AKM8976A

The goal here is to add support for AKM8976A to akmd-free (a free rewrite of akmd, the daemon that deals with the accelerometer/magnetometer data for a few chips, including AKM ones).
This page is to coordinate the work around this goal.

Current status

Global tasks achievement

Task Achievement
Modifying the kernel driver to print the requests akmd makes (ioctl, etc) Done
Get an idea of how it works (what akmd does after what) Done
Define the exact steps that akmd follows Done
Implement AKM8976A in akmd-free without any data treatment yet Done
Understand how the data is treated (algorithms, etc) Work in progress
Reproduce the data treatment with standard C code Work in progress
Include the data treatment code in akmd-free TODO
Check that everything is OK on different devices TODO

Specific tasks achievement

Initialization/calibration sequence

Task Global achievement Understood Reproduced Implemented
Before the first ECS_IOCTL_GETDATA Mostly done Done Done TODO

Getting started

Note that before everything, coming on our IRC channel #replicant on irc.freenode.net and introducing yourself is essential: you'll be able to get help there and, of course, if you want to join the effort, communication is fundamental.

If you plan to join the effort to achieve this goal, here are the steps:

Using the scripts/tools

First of all, you need to know that the kernel-side driver that is used for AKM8976A is located at drivers/misc/akm8976.c.
This file has been modified in order to:

Note that before you run any of the scripts, you need to start adb server as root:

Here is a list of the scripts, what they do and how to use them: You can also avoid the use of the scripts and directly run the needed commands:

Conclusions on how it works

To begin with, here is the trace of the requests akmd does to the kernel driver (using the ioctl system call):

<6>[ 2066.362670] --> ECS_IOCTL_SET_MODE #1
<6>[ 2066.363220] --> ECS_IOCTL_SET_MODE
<6>[ 2066.364074]  --> AKECS_MODE_E2P_READ
<6>[ 2066.381042] --> ECS_IOCTL_READ #1
<6>[ 2066.381317] what is in rwbuf?
<6>[ 2066.381744] --------------------
<6>[ 2066.382019] |    index    |    hdata    |    ddata    |
<6>[ 2066.382263] |    0    |    0x1    |    1    |
<6>[ 2066.382507] |    1    |    0x42    |    66    |
<6>[ 2066.382934] |    2    |    0x0    |    0    |
<6>[ 2066.383178] |    3    |    0x0    |    0    |
<6>[ 2066.383392] |    4    |    0x0    |    0    |
<6>[ 2066.383636] ----------
<6>[ 2066.384063] --> ECS_IOCTL_READ
<6>[ 2066.384979] --> ECS_IOCTL_READ #3
<6>[ 2066.385253] --------------------
<6>[ 2066.385498] |    index    |    hdata    |    ddata    |
<6>[ 2066.385925] |    0    |    0x1    |    1    |
<6>[ 2066.386169] |    1    |    0x66    |    102    |
<6>[ 2066.386383] |    2    |    0x0    |    0    |
<6>[ 2066.386627] |    3    |    0x0    |    0    |
<6>[ 2066.387054] |    4    |    0x0    |    0    |
<6>[ 2066.387268] ----------
<6>[ 2066.387542] --> ECS_IOCTL_SET_MODE #1
<6>[ 2066.387786] --> ECS_IOCTL_SET_MODE
<6>[ 2066.388214]  --> AKECS_MODE_POWERDOWN
<6>[ 2066.401031] --> ECS_IOCTL_GET_OPEN_STATUS
<6>[ 2066.401306] --> ECS_IOCTL_GET_OPEN_STATUS #3
<6>[ 2066.407135] --> ECS_IOCTL_INIT
<6>[ 2066.408020] --> ECS_IOCTL_SET_MODE #1
<6>[ 2066.408294] --> ECS_IOCTL_SET_MODE
<6>[ 2066.408721]  --> AKECS_MODE_E2P_READ
<6>[ 2066.421234] --> ECS_IOCTL_READ #1
<6>[ 2066.421630] what is in rwbuf?
<6>[ 2066.422302] --------------------
<6>[ 2066.422637] |    index    |    hdata    |    ddata    |
<6>[ 2066.423004] |    0    |    0x3    |    3    |
<6>[ 2066.423339] |    1    |    0x46    |    70    |
<6>[ 2066.423950] |    2    |    0x0    |    0    |
<6>[ 2066.424285] |    3    |    0x0    |    0    |
<6>[ 2066.424621] |    4    |    0x0    |    0    |
<6>[ 2066.424957] ----------
<6>[ 2066.425567] --> ECS_IOCTL_READ
<6>[ 2066.426696] --> ECS_IOCTL_READ #3
<6>[ 2066.427062] --------------------
<6>[ 2066.427398] |    index    |    hdata    |    ddata    |
<6>[ 2066.428039] |    0    |    0x3    |    3    |
<6>[ 2066.428375] |    1    |    0x97    |    151    |
<6>[ 2066.428710] |    2    |    0x87    |    135    |
<6>[ 2066.429321] |    3    |    0x19    |    25    |
<6>[ 2066.429656] |    4    |    0x0    |    0    |
<6>[ 2066.429992] ----------
<6>[ 2066.431243] --> ECS_IOCTL_SET_MODE #1
<6>[ 2066.431915] --> ECS_IOCTL_SET_MODE
<6>[ 2066.432250]  --> AKECS_MODE_POWERDOWN
<6>[ 2066.450866] --> ECS_IOCTL_WRITE #1
<6>[ 2066.451385] what is in rwbuf?
<6>[ 2066.452239] --------------------
<6>[ 2066.452697] |    index    |    hdata    |    ddata    |
<6>[ 2066.453186] |    0    |    0x4    |    4    |
<6>[ 2066.454040] |    1    |    0xe8    |    232    |
<6>[ 2066.454498] |    2    |    0x7    |    7    |
<6>[ 2066.454956] |    3    |    0x7    |    7    |
<6>[ 2066.455413] |    4    |    0x9    |    9    |
<6>[ 2066.456268] ----------
<6>[ 2066.456726] --> ECS_IOCTL_WRITE
<6>[ 2066.457916] --> ECS_IOCTL_WRITE #1
<6>[ 2066.458374] what is in rwbuf?
<6>[ 2066.459228] --------------------
<6>[ 2066.459686] |    index    |    hdata    |    ddata    |
<6>[ 2066.460174] |    0    |    0x4    |    4    |
<6>[ 2066.460784] |    1    |    0xe5    |    229    |
<6>[ 2066.461669] |    2    |    0x89    |    137    |
<6>[ 2066.462127] |    3    |    0x0    |    0    |
<6>[ 2066.462615] |    4    |    0x89    |    137    |
<6>[ 2066.463073] ----------
<6>[ 2066.463928] --> ECS_IOCTL_WRITE
<6>[ 2066.465698] --> ECS_IOCTL_SET_MODE #1
<6>[ 2066.466186] --> ECS_IOCTL_SET_MODE
<6>[ 2066.467071]  --> AKECS_MODE_MEASURE_SNG
<6>[ 2066.480468] --> ECS_IOCTL_GETDATA
<6>[ 2066.480987] --> ECS_IOCTL_GETDATA #3
<6>[ 2066.481445] --------------------
<6>[ 2066.482299] |    index    |    hdata    |    ddata    |
<6>[ 2066.482788] gflag1|    0    |    0x70    |    112    |
<6>[ 2066.483245] gflag1|    1    |    0x7f    |    127    |
<6>[ 2066.484100] gflag1|    2    |    0xa5    |    165    |
<6>[ 2066.484588] gflag1|    3    |    0x5c    |    92    |
<6>[ 2066.485046] gflag1|    4    |    0x66    |    102    |
<6>[ 2066.485900] gflag1|    5    |    0x85    |    133    |
<6>[ 2066.486450] gflag1|    6    |    0x5c    |    92    |
<6>[ 2066.486938] gflag1|    7    |    0x85    |    133    |
<6>[ 2066.487792] gflag1|    8    |    0x0    |    0    |
<6>[ 2066.488250] gflag1|    9    |    0x0    |    0    |
<6>[ 2066.488708] gflag1|    10    |    0x0    |    0    |
<6>[ 2066.489196] gflag1|    11    |    0x0    |    0    |
<6>[ 2066.490051] gflag1|    12    |    0x0    |    0    |
<6>[ 2066.490631] gflag1|    13    |    0x0    |    0    |
<6>[ 2066.491119] gflag1|    14    |    0x0    |    0    |
<6>[ 2066.491973] gflag1|    15    |    0x0    |    0    |
<6>[ 2066.492431] gflag1|    16    |    0x0    |    0    |
<6>[ 2066.492919] gflag1|    17    |    0xa5    |    165    |
<6>[ 2066.493774] gflag1|    18    |    0x5c    |    92    |
<6>[ 2066.494262] gflag1|    19    |    0x66    |    102    |
<6>[ 2066.494720] gflag1|    20    |    0x85    |    133    |
<6>[ 2066.495574] gflag1|    21    |    0x5c    |    92    |
<6>[ 2066.496032] gflag1|    22    |    0x85    |    133    |
<6>[ 2066.496520] gflag1|    23    |    0x0    |    0    |
<6>[ 2066.496978] gflag1|    24    |    0x0    |    0    |
<6>[ 2066.497833] gflag1|    25    |    0x0    |    0    |
<6>[ 2066.498291] gflag1|    26    |    0x0    |    0    |
<6>[ 2066.498779] gflag1|    27    |    0x0    |    0    |
<6>[ 2066.499633] gflag1|    28    |    0x0    |    0    |
<6>[ 2066.500122] gflag1|    29    |    0x0    |    0    |
<6>[ 2066.500671] gflag1|    30    |    0x0    |    0    |
<6>[ 2066.501525] gflag1|    31    |    0x0    |    0    |
<6>[ 2066.501983] ----------
<6>[ 2066.509826] --> ECS_IOCTL_GET_NUMFRQ
<6>[ 2066.510559] --> ECS_IOCTL_GET_NUMFRQ #3
<6>[ 2066.511444] --------------------
<6>[ 2066.511901] |    index    |    hdata    |    ddata    |
<6>[ 2066.512390] |    0    |    0x1    |    1    |
<6>[ 2066.513244] |    1    |    0x0    |    0    |
<6>[ 2066.513702] ----------
<6>[ 2066.515655] --> ECS_IOCTL_WRITE #1
<6>[ 2066.516174] what is in rwbuf?
<6>[ 2066.517120] --------------------
<6>[ 2066.517578] |    index    |    hdata    |    ddata    |
<6>[ 2066.518066] |    0    |    0x4    |    4    |
<6>[ 2066.518524] |    1    |    0xee    |    238    |
<6>[ 2066.519378] |    2    |    0x10    |    16    |
<6>[ 2066.519836] |    3    |    0x10    |    16    |
<6>[ 2066.520324] |    4    |    0x10    |    16    |
<6>[ 2066.520904] ----------
<6>[ 2066.521789] --> ECS_IOCTL_WRITE
<6>[ 2066.524230] --> ECS_IOCTL_WRITE #1
<6>[ 2066.524749] what is in rwbuf?
<6>[ 2066.525299] --------------------
<6>[ 2066.526153] |    index    |    hdata    |    ddata    |
<6>[ 2066.526641] |    0    |    0x4    |    4    |
<6>[ 2066.527099] |    1    |    0xeb    |    235    |
<6>[ 2066.527954] |    2    |    0x3    |    3    |
<6>[ 2066.528411] |    3    |    0x7    |    7    |
<6>[ 2066.528869] |    4    |    0x8a    |    138    |
<6>[ 2066.529357] ----------
<6>[ 2066.529815] --> ECS_IOCTL_WRITE
<6>[ 2066.532836] --> ECS_IOCTL_WRITE #1
<6>[ 2066.533355] what is in rwbuf?
<6>[ 2066.533874] --------------------
<6>[ 2066.534729] |    index    |    hdata    |    ddata    |
<6>[ 2066.535186] |    0    |    0x2    |    2    |
<6>[ 2066.535675] |    1    |    0xf4    |    244    |
<6>[ 2066.536132] |    2    |    0x55    |    85    |
<6>[ 2066.537017] |    3    |    0x0    |    0    |
<6>[ 2066.537475] |    4    |    0x0    |    0    |
<6>[ 2066.537933] ----------
<6>[ 2066.538391] --> ECS_IOCTL_WRITE
<6>[ 2066.539947] --> ECS_IOCTL_WRITE #1
<6>[ 2066.540618] what is in rwbuf?
<6>[ 2066.541107] --------------------
<6>[ 2066.541534] |    index    |    hdata    |    ddata    |
<6>[ 2066.542388] |    0    |    0x2    |    2    |
<6>[ 2066.542877] |    1    |    0xf5    |    245    |
<6>[ 2066.543334] |    2    |    0x1b    |    27    |
<6>[ 2066.544219] |    3    |    0x0    |    0    |
<6>[ 2066.544677] |    4    |    0x0    |    0    |
<6>[ 2066.545135] ----------
<6>[ 2066.545623] --> ECS_IOCTL_WRITE
<6>[ 2066.548126] --> ECS_IOCTL_WRITE #1
<6>[ 2066.548370] what is in rwbuf?
<6>[ 2066.548614] --------------------
<6>[ 2066.548858] |    index    |    hdata    |    ddata    |
<6>[ 2066.549285] |    0    |    0x2    |    2    |
<6>[ 2066.549530] |    1    |    0xf6    |    246    |
<6>[ 2066.549743] |    2    |    0x8    |    8    |
<6>[ 2066.549987] |    3    |    0x0    |    0    |
<6>[ 2066.550537] |    4    |    0x0    |    0    |
<6>[ 2066.550781] ----------
<6>[ 2066.551025] --> ECS_IOCTL_WRITE
<6>[ 2066.552398] --> ECS_IOCTL_WRITE #1
<6>[ 2066.552856] what is in rwbuf?
<6>[ 2066.553131] --------------------
<6>[ 2066.553375] |    index    |    hdata    |    ddata    |
<6>[ 2066.553802] |    0    |    0x4    |    4    |
<6>[ 2066.554046] |    1    |    0xf1    |    241    |
<6>[ 2066.554260] |    2    |    0x84    |    132    |
<6>[ 2066.554504] |    3    |    0x87    |    135    |
<6>[ 2066.554931] |    4    |    0x83    |    131    |
<6>[ 2066.555145] ----------
<6>[ 2066.555389] --> ECS_IOCTL_WRITE
<6>[ 2066.557525] --> ECS_IOCTL_GET_CLOSE_STATUS
<6>[ 2066.558074] --> ECS_IOCTL_GET_DELAY
<6>[ 2066.558319] --> ECS_IOCTL_GET_DELAY #3
<6>[ 2066.761016] --> ECS_IOCTL_SET_MODE #1
<6>[ 2066.761932] --> ECS_IOCTL_SET_MODE
<6>[ 2066.762420]  --> AKECS_MODE_MEASURE_SNG
<6>[ 2066.781555] --> ECS_IOCTL_GETDATA
<6>[ 2066.782531] --> ECS_IOCTL_GETDATA #3
<6>[ 2066.783020] --------------------
<6>[ 2066.783477] |    index    |    hdata    |    ddata    |
<6>[ 2066.783935] gflag1|    0    |    0x70    |    112    |
<6>[ 2066.784820] gflag1|    1    |    0x7f    |    127    |
<6>[ 2066.785278] gflag1|    2    |    0xa3    |    163    |
<6>[ 2066.785766] gflag1|    3    |    0x5d    |    93    |
<6>[ 2066.786621] gflag1|    4    |    0x68    |    104    |
<6>[ 2066.787078] gflag1|    5    |    0x86    |    134    |
<6>[ 2066.787567] gflag1|    6    |    0x5c    |    92    |
<6>[ 2066.788421] gflag1|    7    |    0x85    |    133    |
<6>[ 2066.788879] gflag1|    8    |    0x0    |    0    |
<6>[ 2066.789367] gflag1|    9    |    0x0    |    0    |
<6>[ 2066.790222] gflag1|    10    |    0x0    |    0    |
<6>[ 2066.790832] gflag1|    11    |    0x0    |    0    |
<6>[ 2066.791320] gflag1|    12    |    0x0    |    0    |
<6>[ 2066.791778] gflag1|    13    |    0x0    |    0    |
<6>[ 2066.792663] gflag1|    14    |    0x0    |    0    |
<6>[ 2066.793121] gflag1|    15    |    0x0    |    0    |
<6>[ 2066.793579] gflag1|    16    |    0x0    |    0    |
<6>[ 2066.794464] gflag1|    17    |    0xa3    |    163    |
<6>[ 2066.794921] gflag1|    18    |    0x5d    |    93    |
<6>[ 2066.795379] gflag1|    19    |    0x68    |    104    |
<6>[ 2066.796264] gflag1|    20    |    0x86    |    134    |
<6>[ 2066.796722] gflag1|    21    |    0x5c    |    92    |
<6>[ 2066.797210] gflag1|    22    |    0x85    |    133    |
<6>[ 2066.798065] gflag1|    23    |    0x0    |    0    |
<6>[ 2066.798553] gflag1|    24    |    0x0    |    0    |
<6>[ 2066.799041] gflag1|    25    |    0x0    |    0    |
<6>[ 2066.799499] gflag1|    26    |    0x0    |    0    |
<6>[ 2066.800354] gflag1|    27    |    0x0    |    0    |
<6>[ 2066.800903] gflag1|    28    |    0x0    |    0    |
<6>[ 2066.801391] gflag1|    29    |    0x0    |    0    |
<6>[ 2066.802246] gflag1|    30    |    0x0    |    0    |
<6>[ 2066.802703] gflag1|    31    |    0x0    |    0    |
<6>[ 2066.803161] ----------
<6>[ 2066.807067] --> ECS_IOCTL_GET_NUMFRQ
<6>[ 2066.808044] --> ECS_IOCTL_GET_NUMFRQ #3
<6>[ 2066.808502] --------------------
<6>[ 2066.808959] |    index    |    hdata    |    ddata    |
<6>[ 2066.809814] |    0    |    0x1    |    1    |
<6>[ 2066.810302] |    1    |    0x0    |    0    |
<6>[ 2066.810943] ----------
<6>[ 2066.813629] --> ECS_IOCTL_SET_YPR #1
<6>[ 2066.814636] --------------------
<6>[ 2066.815093] |    index    |    hdata    |    ddata    |
<6>[ 2066.815582] gflag2|    0    |    0x55    |    85    |
<6>[ 2066.816467] gflag2|    1    |    0xffffffff    |    -1    |
<6>[ 2066.816925] gflag2|    2    |    0x2    |    2    |
<6>[ 2066.817382] gflag2|    3    |    0x1e    |    30    |
<6>[ 2066.817840] gflag2|    4    |    0x1    |    1    |
<6>[ 2066.818328] gflag2|    5    |    0x0    |    0    |
<6>[ 2066.818786] gflag2|    6    |    0x14    |    20    |
<6>[ 2066.819244] gflag2|    7    |    0xfffffd3b    |    -709    |
<6>[ 2066.820129] gflag2|    8    |    0x11    |    17    |
<6>[ 2066.820770] gflag2|    9    |    0x185    |    389    |
<6>[ 2066.821258] gflag2|    10    |    0xffffffe7    |    -25    |
<6>[ 2066.822113] gflag2|    11    |    0xfffffe20    |    -480    |
<6>[ 2066.822570] ----------
<6>[ 2066.823028] --> ECS_IOCTL_SET_YPR
<6>[ 2066.823913] AKECS_Report_Value: yaw = 85, pitch = -1, roll = 2
<6>[ 2066.824401]                     tmp = 30, m_stat= 1, g_stat=0
<6>[ 2066.825286]           G_Sensor:   x = 20 LSB, y = -709 LSB, z = 17 LSB
<6>[ 2066.825744]                MAG:   MAGV_X = 389, MAGV_Y = -25, MAGV_Z = -480
<6>[ 2066.829833] --> ECS_IOCTL_GET_DELAY
<6>[ 2066.830352] --> ECS_IOCTL_GET_DELAY #3
<6>[ 2067.034759] --> ECS_IOCTL_SET_MODE #1
<6>[ 2067.035705] --> ECS_IOCTL_SET_MODE
<6>[ 2067.036163]  --> AKECS_MODE_MEASURE_SNG
<6>[ 2067.051818] --> ECS_IOCTL_GETDATA
<6>[ 2067.052764] --> ECS_IOCTL_GETDATA #3
<6>[ 2067.053253] --------------------
<6>[ 2067.053741] |    index    |    hdata    |    ddata    |
<6>[ 2067.054595] gflag1|    0    |    0x70    |    112    |
<6>[ 2067.055084] gflag1|    1    |    0x7f    |    127    |
<6>[ 2067.055572] gflag1|    2    |    0xa2    |    162    |
<6>[ 2067.056427] gflag1|    3    |    0x5d    |    93    |
<6>[ 2067.056915] gflag1|    4    |    0x65    |    101    |
<6>[ 2067.057373] gflag1|    5    |    0x86    |    134    |
<6>[ 2067.057861] gflag1|    6    |    0x5b    |    91    |
<6>[ 2067.058715] gflag1|    7    |    0x85    |    133    |
<6>[ 2067.059173] gflag1|    8    |    0x0    |    0    |
<6>[ 2067.059661] gflag1|    9    |    0x0    |    0    |
<6>[ 2067.060577] gflag1|    10    |    0x0    |    0    |
<6>[ 2067.061157] gflag1|    11    |    0x0    |    0    |
<6>[ 2067.061645] gflag1|    12    |    0x0    |    0    |
<6>[ 2067.062500] gflag1|    13    |    0x0    |    0    |
<6>[ 2067.062957] gflag1|    14    |    0x0    |    0    |
<6>[ 2067.063415] gflag1|    15    |    0x0    |    0    |
<6>[ 2067.063873] gflag1|    16    |    0x0    |    0    |
<6>[ 2067.064727] gflag1|    17    |    0xa2    |    162    |
<6>[ 2067.065185] gflag1|    18    |    0x5d    |    93    |
<6>[ 2067.065673] gflag1|    19    |    0x65    |    101    |
<6>[ 2067.066528] gflag1|    20    |    0x86    |    134    |
<6>[ 2067.067016] gflag1|    21    |    0x5b    |    91    |
<6>[ 2067.067474] gflag1|    22    |    0x85    |    133    |
<6>[ 2067.068328] gflag1|    23    |    0x0    |    0    |
<6>[ 2067.068817] gflag1|    24    |    0x0    |    0    |
<6>[ 2067.069274] gflag1|    25    |    0x0    |    0    |
<6>[ 2067.070129] gflag1|    26    |    0x0    |    0    |
<6>[ 2067.070587] gflag1|    27    |    0x0    |    0    |
<6>[ 2067.071136] gflag1|    28    |    0x0    |    0    |
<6>[ 2067.071624] gflag1|    29    |    0x0    |    0    |
<6>[ 2067.072479] gflag1|    30    |    0x0    |    0    |
<6>[ 2067.072937] gflag1|    31    |    0x0    |    0    |
<6>[ 2067.073394] ----------
<6>[ 2067.077880] --> ECS_IOCTL_GET_NUMFRQ
<6>[ 2067.078399] --> ECS_IOCTL_GET_NUMFRQ #3
<6>[ 2067.078857] --------------------
<6>[ 2067.079315] |    index    |    hdata    |    ddata    |
<6>[ 2067.080169] |    0    |    0x1    |    1    |
<6>[ 2067.080657] |    1    |    0x0    |    0    |
<6>[ 2067.081298] ----------
<6>[ 2067.083892] --> ECS_IOCTL_SET_YPR #1
<6>[ 2067.084869] --------------------
<6>[ 2067.085327] |    index    |    hdata    |    ddata    |
<6>[ 2067.085815] gflag2|    0    |    0x54    |    84    |
<6>[ 2067.086700] gflag2|    1    |    0xffffffff    |    -1    |
<6>[ 2067.087158] gflag2|    2    |    0x2    |    2    |
<6>[ 2067.087615] gflag2|    3    |    0x1e    |    30    |
<6>[ 2067.088470] gflag2|    4    |    0x1    |    1    |
<6>[ 2067.088928] gflag2|    5    |    0x0    |    0    |
<6>[ 2067.089416] gflag2|    6    |    0x14    |    20    |
<6>[ 2067.090270] gflag2|    7    |    0xfffffd2b    |    -725    |
<6>[ 2067.090728] gflag2|    8    |    0x11    |    17    |
<6>[ 2067.091400] gflag2|    9    |    0x175    |    373    |
<6>[ 2067.092254] gflag2|    10    |    0xffffffe7    |    -25    |
<6>[ 2067.092742] gflag2|    11    |    0xfffffdef    |    -529    |
<6>[ 2067.093231] ----------
<6>[ 2067.093688] --> ECS_IOCTL_SET_YPR
<6>[ 2067.094543] AKECS_Report_Value: yaw = 84, pitch = -1, roll = 2
<6>[ 2067.095031]                     tmp = 30, m_stat= 1, g_stat=0
<6>[ 2067.095916]           G_Sensor:   x = 20 LSB, y = -725 LSB, z = 17 LSB
<6>[ 2067.096405]                MAG:   MAGV_X = 373, MAGV_Y = -25, MAGV_Z = -529

Index of the things to know about the different ioctl commands

Index of the files that are used by akmd or the kernel

The initialization part

Let's take a look closer at the initialization part: this concerns everything before akmd starts reporting treated values.

So first of all, we have:

<6>[ 2066.362670] --> ECS_IOCTL_SET_MODE #1
<6>[ 2066.363220] --> ECS_IOCTL_SET_MODE
<6>[ 2066.364074]  --> AKECS_MODE_E2P_READ

akmd sets the driver mode to AKECS_MODE_E2P_READ. It's not clear about why it's really necessary but it's there anyway, and it's quite easy to reproduce since there is no data treatment on that and that it's now clear that this call does not change depending of external values.

<6>[ 2066.381042] --> ECS_IOCTL_READ #1
<6>[ 2066.381317] what is in rwbuf?
<6>[ 2066.381744] --------------------
<6>[ 2066.382019] |    index    |    hdata    |    ddata    |
<6>[ 2066.382263] |    0    |    0x1    |    1    |
<6>[ 2066.382507] |    1    |    0x42    |    66    |
<6>[ 2066.382934] |    2    |    0x0    |    0    |
<6>[ 2066.383178] |    3    |    0x0    |    0    |
<6>[ 2066.383392] |    4    |    0x0    |    0    |
<6>[ 2066.383636] ----------
<6>[ 2066.384063] --> ECS_IOCTL_READ
<6>[ 2066.384979] --> ECS_IOCTL_READ #3
<6>[ 2066.385253] --------------------
<6>[ 2066.385498] |    index    |    hdata    |    ddata    |
<6>[ 2066.385925] |    0    |    0x1    |    1    |
<6>[ 2066.386169] |    1    |    0x66    |    102    |
<6>[ 2066.386383] |    2    |    0x0    |    0    |
<6>[ 2066.386627] |    3    |    0x0    |    0    |
<6>[ 2066.387054] |    4    |    0x0    |    0    |

This first part (ECS_IOCTL_READ #1) is the request (READ REQ #1) that akmd sends to the kernel and the second part (ECS_IOCTL_READ #3) is the answer (READ ASW #1) it gets. Its length is 1, so all the 0 values are not to be taken in count.
For this, the request is always { 1, 66 } but the answer may not be the same on different devices.

Though, this value seems not to be used used for any of the next requests, but it may still be the case.

<6>[ 2066.387542] --> ECS_IOCTL_SET_MODE #1
<6>[ 2066.387786] --> ECS_IOCTL_SET_MODE
<6>[ 2066.388214]  --> AKECS_MODE_POWERDOWN
<6>[ 2066.401031] --> ECS_IOCTL_GET_OPEN_STATUS
<6>[ 2066.401306] --> ECS_IOCTL_GET_OPEN_STATUS #3
<6>[ 2066.407135] --> ECS_IOCTL_INIT
<6>[ 2066.408020] --> ECS_IOCTL_SET_MODE #1
<6>[ 2066.408294] --> ECS_IOCTL_SET_MODE
<6>[ 2066.408721]  --> AKECS_MODE_E2P_READ

akmd sets the mode to AKECS_MODE_POWERDOWN, then waits for the kernel to have "open" status. This appears when the accelerometer/magnetometer is requested by the system, so if nothing requests the chip, ECS_IOCTL_GET_OPEN_STATUS
will block until the chip is requested. This also append when the phone is in "sleep" mode.

When ECS_IOCTL_GET_OPEN_STATUS is not blocking (the chip is requested by the system), akmd asks the driver to init the chip, with ECS_IOCTL_INIT. Then, akmd sets the mode to AKECS_MODE_E2P_READ. The reason of that is still unclear.

All this is already implemented in akmd-free.

<6>[ 2066.421234] --> ECS_IOCTL_READ #1
<6>[ 2066.421630] what is in rwbuf?
<6>[ 2066.422302] --------------------
<6>[ 2066.422637] |    index    |    hdata    |    ddata    |
<6>[ 2066.423004] |    0    |    0x3    |    3    |
<6>[ 2066.423339] |    1    |    0x46    |    70    |
<6>[ 2066.423950] |    2    |    0x0    |    0    |
<6>[ 2066.424285] |    3    |    0x0    |    0    |
<6>[ 2066.424621] |    4    |    0x0    |    0    |
<6>[ 2066.424957] ----------
<6>[ 2066.425567] --> ECS_IOCTL_READ
<6>[ 2066.426696] --> ECS_IOCTL_READ #3
<6>[ 2066.427062] --------------------
<6>[ 2066.427398] |    index    |    hdata    |    ddata    |
<6>[ 2066.428039] |    0    |    0x3    |    3    |
<6>[ 2066.428375] |    1    |    0x97    |    151    |
<6>[ 2066.428710] |    2    |    0x87    |    135    |
<6>[ 2066.429321] |    3    |    0x19    |    25    |
<6>[ 2066.429656] |    4    |    0x0    |    0    |
<6>[ 2066.429992] ----------

Here we have a read request, with { 3, 70 } (READ REQ #2) that returns { 3, x, y, z } (READ ASW #2). The answer elements are called x, y, z since these are not constant and my change between devices. We'll refer to these values under the names: READ ASW #2's x, READ ASW #2's y and READ ASW #2's z.

<6>[ 2066.431243] --> ECS_IOCTL_SET_MODE #1
<6>[ 2066.431915] --> ECS_IOCTL_SET_MODE
<6>[ 2066.432250]  --> AKECS_MODE_POWERDOWN
<6>[ 2066.450866] --> ECS_IOCTL_WRITE #1
<6>[ 2066.451385] what is in rwbuf?
<6>[ 2066.452239] --------------------
<6>[ 2066.452697] |    index    |    hdata    |    ddata    |
<6>[ 2066.453186] |    0    |    0x4    |    4    |
<6>[ 2066.454040] |    1    |    0xe8    |    232    |
<6>[ 2066.454498] |    2    |    0x7    |    7    |
<6>[ 2066.454956] |    3    |    0x7    |    7    |
<6>[ 2066.455413] |    4    |    0x9    |    9    |
<6>[ 2066.456268] ----------
<6>[ 2066.456726] --> ECS_IOCTL_WRITE

Here akmd sets the mode to AKECS_MODE_POWERDOWN and writes 4 numbers { 4, 232, x, y, z } to the kernel driver. rwbufr1 is always 232 but the other numbers are changing depending on READ ASW #2's values. The formula to get x, y and z from READ ASW #2's values is:
x = (READ ASW #2's x) % 16
y = (READ ASW #2's y) % 16
z = (READ ASW #2's y) % 16

The way to discover that was to determine what makes these values change and how they change depending on READ ASW #2's values. This was easy since the values are also printed in hex format, so (READ ASW #2's x) % 16 is the last number of the hex representation of READ ASW #2's x.

<6>[ 2066.457916] --> ECS_IOCTL_WRITE #1
<6>[ 2066.458374] what is in rwbuf?
<6>[ 2066.459228] --------------------
<6>[ 2066.459686] |    index    |    hdata    |    ddata    |
<6>[ 2066.460174] |    0    |    0x4    |    4    |
<6>[ 2066.460784] |    1    |    0xe5    |    229    |
<6>[ 2066.461669] |    2    |    0x89    |    137    |
<6>[ 2066.462127] |    3    |    0x0    |    0    |
<6>[ 2066.462615] |    4    |    0x89    |    137    |
<6>[ 2066.463073] ----------
<6>[ 2066.463928] --> ECS_IOCTL_WRITE
<6>[ 2066.465698] --> ECS_IOCTL_SET_MODE #1
<6>[ 2066.466186] --> ECS_IOCTL_SET_MODE
<6>[ 2066.467071]  --> AKECS_MODE_MEASURE_SNG

Here is a write request of the type { 4, 229, x, y, z }. x, y and z values seem to be written to akmd_set_values.txt when akmd quits (this should be confirmed), so on the first start of akmd, x, y and z are 0 since there was no previous session to write the numbers on akmd_set_values.txt.

Anyway, setting x, y and z to 0 doesn't prevent anything to work.

Then akmd also sets the mode to AKECS_MODE_MEASURE_SNG.