Project

General

Profile

AKM8976A » History » Version 11

Paul Kocialkowski, 07/04/2011 09:16 PM

1 1 Paul Kocialkowski
=  AKM8976A =
2
3
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). 
4
This page is to coordinate the work around this goal.
5
6
== Current status ==
7
8 2 Paul Kocialkowski
=== Global tasks achievement ===
9 1 Paul Kocialkowski
10 2 Paul Kocialkowski
|| Task || Achievement ||
11
|| Modifying the kernel driver to print the requests akmd makes (ioctl, etc) || [[span(Done , style=background: green; color: white; display: inline-block; width: 100%;)]] ||
12
|| Get an idea of how it works (what akmd does after what) || [[span(Done , style=background: green; color: white; display: inline-block; width: 100%;)]] ||
13
|| Define the exact steps that akmd follows || [[span(Done , style=background: green; color: white; display: inline-block; width: 100%;)]] ||
14
|| Implement AKM8976A in akmd-free without any data treatment yet || [[span(Done , style=background: green; color: white; display: inline-block; width: 100%;)]] ||
15
|| Understand how the data is treated (algorithms, etc) || [[span(Work in progress , style=background: orange; color: white; display: inline-block; width: 100%;)]] ||
16
|| Reproduce the data treatment with standard C code || [[span(Work in progress , style=background: orange; color: white; display: inline-block; width: 100%;)]] ||
17 8 Paul Kocialkowski
|| Include the data treatment code in akmd-free || [[span(TODO , style=background: red; color: white; display: inline-block; width: 100%;)]] ||
18
|| Check that everything is OK on different devices || [[span(TODO , style=background: red; color: white; display: inline-block; width: 100%;)]] ||
19 1 Paul Kocialkowski
20 3 Paul Kocialkowski
=== Specific tasks achievement ===
21
22 5 Paul Kocialkowski
==== Initialization/calibration sequence ====
23 3 Paul Kocialkowski
24
|| Task || Global achievement || Understood || Reproduced || Implemented ||
25 8 Paul Kocialkowski
|| Before the first ECS_IOCTL_GETDATA || [[span(Mostly done , style=background: orange; color: white; display: inline-block; width: 100%;)]] || [[span(Done , style=background: green; color: white; display: inline-block; width: 100%;)]] || [[span(Done , style=background: green; color: white; display: inline-block; width: 100%;)]] || [[span(TODO , style=background: red; color: white; display: inline-block; width: 100%;)]]
26 1 Paul Kocialkowski
27
== Getting started ==
28
29 5 Paul Kocialkowski
Note that before everything, coming on our IRC channel [https://www.jappix.com/?r=replicant%25irc.freenode.net@irc.jappix.com #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. 
30
31
If you plan to join the effort to achieve this goal, here are the steps: 
32
33 6 Paul Kocialkowski
 * Downloading and setting up the akm8976a-dev branch for kernel-msm (which contains a modified version of ''drivers/misc/akm8976.c'')
34
 * Downloading some scripts that are useful to debug fast
35
 * Download and build the re_set_data tool (to inject some data to the kernel)
36 7 Paul Kocialkowski
 * Generate the file containing the "phone" button pressed sequence. 
37
 * Get the non-free akmd. 
38 5 Paul Kocialkowski
39
== Using the scripts/tools ==
40 1 Paul Kocialkowski
41
First of all, you need to know that the kernel-side driver that is used for AKM8976A is located at ''drivers/misc/akm8976.c''.
42
This file has been modified in order to:
43 6 Paul Kocialkowski
 * make it trace (print) all the ioctl
44
 * make it possible to inject data 
45
46
Note that before you run any of the scripts, you need to start adb server as root:
47
{{{ # adb start-server }}}
48
49 1 Paul Kocialkowski
Here is a list of the scripts, what they do and how to use them:
50
 * '''replicant_kern_debug.sh''': this one is to get the debug messages from the kernel. It requires no special parameter, nor any specific location to be lunched in. 
51
 * '''replicant_calib_kern.sh''': this script should be used while working on the calibration part. The 2 remaining initialisation sequences we miss start with { 4, 235 } and { 4, 241 } and this script is to print the calibration values for these sequences (when the kernel printk the values, so when akmd sends them). To use it, pass 235 or 241 as first argument to the script, for the first or 2nd initialisation sequence we miss. 
52 8 Paul Kocialkowski
 * '''replicant_calib_adb.sh''': this script should be used while working on the calibration part. This script has to be ran in the directory containing ''akmd_set_dev.txt'' and ''re_set_data.txt''. You can also pass the directory containing these files as first argument to the script. In the correct order, this script: 
53
  * copies the ''akmd_set_dev.txt'' file to ''/data/misc/akmd_set.txt'' (akmd calibration file)
54
  * copies the ''re_set_data.txt'' file to ''/data/re_set_data.txt'' (retro engineering file, which contains the values to force as ECS_IOCTL_GETDATA returning values)
55
  * lunches ''/data/re_set_data load'' to inject the values from ''/data/re_set_data.txt'' to the kernel
56
  * lunches ''akmd'', which won't do anything if the phone is in sleep mode (black screen).
57
  * inject ''/data/suspend_wake'' to ''/dev/input/event4'' (the buttons event node) to wakeup the phone
58
  * wait for akmd to perform the initialisation sequence, that you should see with '''replicant_calib_kern.sh'''.
59
  * kill akmd
60
  * inject ''/data/suspend_wake'' to ''/dev/input/event4'' (the buttons event node) to put the phone in sleep mode
61
62
You can also avoid the use of the scripts and directly run the needed commands:
63
 * '''adb push akmd_set_dev.txt /data/misc/akmd_set.txt''': this is to copy ''akmd_set_dev.txt'' (akmd calibration file) to its correct location on the device. You need to run that in the directory where ''akmd_set_dev.txt'' is.
64
 * '''adb push re_set_data.txt /data/re_set_data.txt''': this is to copy ''re_set_data.txt'' (retro engineering file, which contains the values to force as ECS_IOCTL_GETDATA returning values)to its correct location on the device. You need to run that in the directory where ''re_set_data.txt'' is.
65 9 Paul Kocialkowski
 * '''adb shell "/data/re_set_data load"''': this is to inject the values from ''/data/re_set_data.txt'' to the kernel driver.
66
 * '''adb shell /data/akmd''': this is to start the non-free akmd daemon.
67
 * '''adb shell "cat /data/suspend_wake  > /dev/input/event4"''': this is to inject the "phone" button pressed event, so it will either wakeup the phone or set it in sleep mode. 
68
 * '''adb shell "killall akmd"''': this is to kill the non-free akmd daemon.
69
 * '''adb shell "echo 8 > /proc/sys/kernel/printk && cat /proc/kmsg"''': this is to set the verbosity level of the kernel messages to high and print the messages.
70 10 Paul Kocialkowski
71
== Conclusions on how it works ==
72
73
To begin with, here is the trace of the requests akmd does to the kernel driver (using the ioctl system call):
74
75 11 Paul Kocialkowski
76 10 Paul Kocialkowski
{{{
77
<6>[ 2066.362670] --> ECS_IOCTL_SET_MODE #1
78
<6>[ 2066.363220] --> ECS_IOCTL_SET_MODE
79
<6>[ 2066.364074]  --> AKECS_MODE_E2P_READ
80
<6>[ 2066.381042] --> ECS_IOCTL_READ #1
81
<6>[ 2066.381317] what is in rwbuf?
82
<6>[ 2066.381744] --------------------
83
<6>[ 2066.382019] |	index	|	hdata	|	ddata	|
84
<6>[ 2066.382263] |	0	|	0x1	|	1	|
85
<6>[ 2066.382507] |	1	|	0x42	|	66	|
86
<6>[ 2066.382934] |	2	|	0x0	|	0	|
87
<6>[ 2066.383178] |	3	|	0x0	|	0	|
88
<6>[ 2066.383392] |	4	|	0x0	|	0	|
89
<6>[ 2066.383636] ----------
90
<6>[ 2066.384063] --> ECS_IOCTL_READ
91
<6>[ 2066.384979] --> ECS_IOCTL_READ #3
92
<6>[ 2066.385253] --------------------
93
<6>[ 2066.385498] |	index	|	hdata	|	ddata	|
94
<6>[ 2066.385925] |	0	|	0x1	|	1	|
95
<6>[ 2066.386169] |	1	|	0x66	|	102	|
96
<6>[ 2066.386383] |	2	|	0x0	|	0	|
97
<6>[ 2066.386627] |	3	|	0x0	|	0	|
98
<6>[ 2066.387054] |	4	|	0x0	|	0	|
99
<6>[ 2066.387268] ----------
100
<6>[ 2066.387542] --> ECS_IOCTL_SET_MODE #1
101
<6>[ 2066.387786] --> ECS_IOCTL_SET_MODE
102
<6>[ 2066.388214]  --> AKECS_MODE_POWERDOWN
103
<6>[ 2066.401031] --> ECS_IOCTL_GET_OPEN_STATUS
104
<6>[ 2066.401306] --> ECS_IOCTL_GET_OPEN_STATUS #3
105
<6>[ 2066.407135] --> ECS_IOCTL_INIT
106
<6>[ 2066.408020] --> ECS_IOCTL_SET_MODE #1
107
<6>[ 2066.408294] --> ECS_IOCTL_SET_MODE
108
<6>[ 2066.408721]  --> AKECS_MODE_E2P_READ
109
<6>[ 2066.421234] --> ECS_IOCTL_READ #1
110
<6>[ 2066.421630] what is in rwbuf?
111
<6>[ 2066.422302] --------------------
112
<6>[ 2066.422637] |	index	|	hdata	|	ddata	|
113
<6>[ 2066.423004] |	0	|	0x3	|	3	|
114
<6>[ 2066.423339] |	1	|	0x46	|	70	|
115
<6>[ 2066.423950] |	2	|	0x0	|	0	|
116
<6>[ 2066.424285] |	3	|	0x0	|	0	|
117
<6>[ 2066.424621] |	4	|	0x0	|	0	|
118
<6>[ 2066.424957] ----------
119
<6>[ 2066.425567] --> ECS_IOCTL_READ
120
<6>[ 2066.426696] --> ECS_IOCTL_READ #3
121
<6>[ 2066.427062] --------------------
122
<6>[ 2066.427398] |	index	|	hdata	|	ddata	|
123
<6>[ 2066.428039] |	0	|	0x3	|	3	|
124
<6>[ 2066.428375] |	1	|	0x97	|	151	|
125
<6>[ 2066.428710] |	2	|	0x87	|	135	|
126
<6>[ 2066.429321] |	3	|	0x19	|	25	|
127
<6>[ 2066.429656] |	4	|	0x0	|	0	|
128
<6>[ 2066.429992] ----------
129
<6>[ 2066.431243] --> ECS_IOCTL_SET_MODE #1
130
<6>[ 2066.431915] --> ECS_IOCTL_SET_MODE
131
<6>[ 2066.432250]  --> AKECS_MODE_POWERDOWN
132
<6>[ 2066.450866] --> ECS_IOCTL_WRITE #1
133
<6>[ 2066.451385] what is in rwbuf?
134
<6>[ 2066.452239] --------------------
135
<6>[ 2066.452697] |	index	|	hdata	|	ddata	|
136
<6>[ 2066.453186] |	0	|	0x4	|	4	|
137
<6>[ 2066.454040] |	1	|	0xe8	|	232	|
138
<6>[ 2066.454498] |	2	|	0x7	|	7	|
139
<6>[ 2066.454956] |	3	|	0x7	|	7	|
140
<6>[ 2066.455413] |	4	|	0x9	|	9	|
141
<6>[ 2066.456268] ----------
142
<6>[ 2066.456726] --> ECS_IOCTL_WRITE
143
<6>[ 2066.457916] --> ECS_IOCTL_WRITE #1
144
<6>[ 2066.458374] what is in rwbuf?
145
<6>[ 2066.459228] --------------------
146
<6>[ 2066.459686] |	index	|	hdata	|	ddata	|
147
<6>[ 2066.460174] |	0	|	0x4	|	4	|
148
<6>[ 2066.460784] |	1	|	0xe5	|	229	|
149
<6>[ 2066.461669] |	2	|	0x89	|	137	|
150
<6>[ 2066.462127] |	3	|	0x0	|	0	|
151
<6>[ 2066.462615] |	4	|	0x89	|	137	|
152
<6>[ 2066.463073] ----------
153
<6>[ 2066.463928] --> ECS_IOCTL_WRITE
154
<6>[ 2066.465698] --> ECS_IOCTL_SET_MODE #1
155
<6>[ 2066.466186] --> ECS_IOCTL_SET_MODE
156
<6>[ 2066.467071]  --> AKECS_MODE_MEASURE_SNG
157
<6>[ 2066.480468] --> ECS_IOCTL_GETDATA
158
<6>[ 2066.480987] --> ECS_IOCTL_GETDATA #3
159
<6>[ 2066.481445] --------------------
160
<6>[ 2066.482299] |	index	|	hdata	|	ddata	|
161
<6>[ 2066.482788] gflag1|	0	|	0x70	|	112	|
162
<6>[ 2066.483245] gflag1|	1	|	0x7f	|	127	|
163
<6>[ 2066.484100] gflag1|	2	|	0xa5	|	165	|
164
<6>[ 2066.484588] gflag1|	3	|	0x5c	|	92	|
165
<6>[ 2066.485046] gflag1|	4	|	0x66	|	102	|
166
<6>[ 2066.485900] gflag1|	5	|	0x85	|	133	|
167
<6>[ 2066.486450] gflag1|	6	|	0x5c	|	92	|
168
<6>[ 2066.486938] gflag1|	7	|	0x85	|	133	|
169
<6>[ 2066.487792] gflag1|	8	|	0x0	|	0	|
170
<6>[ 2066.488250] gflag1|	9	|	0x0	|	0	|
171
<6>[ 2066.488708] gflag1|	10	|	0x0	|	0	|
172
<6>[ 2066.489196] gflag1|	11	|	0x0	|	0	|
173
<6>[ 2066.490051] gflag1|	12	|	0x0	|	0	|
174
<6>[ 2066.490631] gflag1|	13	|	0x0	|	0	|
175
<6>[ 2066.491119] gflag1|	14	|	0x0	|	0	|
176
<6>[ 2066.491973] gflag1|	15	|	0x0	|	0	|
177
<6>[ 2066.492431] gflag1|	16	|	0x0	|	0	|
178
<6>[ 2066.492919] gflag1|	17	|	0xa5	|	165	|
179
<6>[ 2066.493774] gflag1|	18	|	0x5c	|	92	|
180
<6>[ 2066.494262] gflag1|	19	|	0x66	|	102	|
181
<6>[ 2066.494720] gflag1|	20	|	0x85	|	133	|
182
<6>[ 2066.495574] gflag1|	21	|	0x5c	|	92	|
183
<6>[ 2066.496032] gflag1|	22	|	0x85	|	133	|
184
<6>[ 2066.496520] gflag1|	23	|	0x0	|	0	|
185
<6>[ 2066.496978] gflag1|	24	|	0x0	|	0	|
186
<6>[ 2066.497833] gflag1|	25	|	0x0	|	0	|
187
<6>[ 2066.498291] gflag1|	26	|	0x0	|	0	|
188
<6>[ 2066.498779] gflag1|	27	|	0x0	|	0	|
189
<6>[ 2066.499633] gflag1|	28	|	0x0	|	0	|
190
<6>[ 2066.500122] gflag1|	29	|	0x0	|	0	|
191
<6>[ 2066.500671] gflag1|	30	|	0x0	|	0	|
192
<6>[ 2066.501525] gflag1|	31	|	0x0	|	0	|
193
<6>[ 2066.501983] ----------
194
<6>[ 2066.509826] --> ECS_IOCTL_GET_NUMFRQ
195
<6>[ 2066.510559] --> ECS_IOCTL_GET_NUMFRQ #3
196
<6>[ 2066.511444] --------------------
197
<6>[ 2066.511901] |	index	|	hdata	|	ddata	|
198
<6>[ 2066.512390] |	0	|	0x1	|	1	|
199
<6>[ 2066.513244] |	1	|	0x0	|	0	|
200
<6>[ 2066.513702] ----------
201
<6>[ 2066.515655] --> ECS_IOCTL_WRITE #1
202
<6>[ 2066.516174] what is in rwbuf?
203
<6>[ 2066.517120] --------------------
204
<6>[ 2066.517578] |	index	|	hdata	|	ddata	|
205
<6>[ 2066.518066] |	0	|	0x4	|	4	|
206
<6>[ 2066.518524] |	1	|	0xee	|	238	|
207
<6>[ 2066.519378] |	2	|	0x10	|	16	|
208
<6>[ 2066.519836] |	3	|	0x10	|	16	|
209
<6>[ 2066.520324] |	4	|	0x10	|	16	|
210
<6>[ 2066.520904] ----------
211
<6>[ 2066.521789] --> ECS_IOCTL_WRITE
212
<6>[ 2066.524230] --> ECS_IOCTL_WRITE #1
213
<6>[ 2066.524749] what is in rwbuf?
214
<6>[ 2066.525299] --------------------
215
<6>[ 2066.526153] |	index	|	hdata	|	ddata	|
216
<6>[ 2066.526641] |	0	|	0x4	|	4	|
217
<6>[ 2066.527099] |	1	|	0xeb	|	235	|
218
<6>[ 2066.527954] |	2	|	0x3	|	3	|
219
<6>[ 2066.528411] |	3	|	0x7	|	7	|
220
<6>[ 2066.528869] |	4	|	0x8a	|	138	|
221
<6>[ 2066.529357] ----------
222
<6>[ 2066.529815] --> ECS_IOCTL_WRITE
223
<6>[ 2066.532836] --> ECS_IOCTL_WRITE #1
224
<6>[ 2066.533355] what is in rwbuf?
225
<6>[ 2066.533874] --------------------
226
<6>[ 2066.534729] |	index	|	hdata	|	ddata	|
227
<6>[ 2066.535186] |	0	|	0x2	|	2	|
228
<6>[ 2066.535675] |	1	|	0xf4	|	244	|
229
<6>[ 2066.536132] |	2	|	0x55	|	85	|
230
<6>[ 2066.537017] |	3	|	0x0	|	0	|
231
<6>[ 2066.537475] |	4	|	0x0	|	0	|
232
<6>[ 2066.537933] ----------
233
<6>[ 2066.538391] --> ECS_IOCTL_WRITE
234
<6>[ 2066.539947] --> ECS_IOCTL_WRITE #1
235
<6>[ 2066.540618] what is in rwbuf?
236
<6>[ 2066.541107] --------------------
237
<6>[ 2066.541534] |	index	|	hdata	|	ddata	|
238
<6>[ 2066.542388] |	0	|	0x2	|	2	|
239
<6>[ 2066.542877] |	1	|	0xf5	|	245	|
240
<6>[ 2066.543334] |	2	|	0x1b	|	27	|
241
<6>[ 2066.544219] |	3	|	0x0	|	0	|
242
<6>[ 2066.544677] |	4	|	0x0	|	0	|
243
<6>[ 2066.545135] ----------
244
<6>[ 2066.545623] --> ECS_IOCTL_WRITE
245
<6>[ 2066.548126] --> ECS_IOCTL_WRITE #1
246
<6>[ 2066.548370] what is in rwbuf?
247
<6>[ 2066.548614] --------------------
248
<6>[ 2066.548858] |	index	|	hdata	|	ddata	|
249
<6>[ 2066.549285] |	0	|	0x2	|	2	|
250
<6>[ 2066.549530] |	1	|	0xf6	|	246	|
251
<6>[ 2066.549743] |	2	|	0x8	|	8	|
252
<6>[ 2066.549987] |	3	|	0x0	|	0	|
253
<6>[ 2066.550537] |	4	|	0x0	|	0	|
254
<6>[ 2066.550781] ----------
255
<6>[ 2066.551025] --> ECS_IOCTL_WRITE
256
<6>[ 2066.552398] --> ECS_IOCTL_WRITE #1
257
<6>[ 2066.552856] what is in rwbuf?
258
<6>[ 2066.553131] --------------------
259
<6>[ 2066.553375] |	index	|	hdata	|	ddata	|
260
<6>[ 2066.553802] |	0	|	0x4	|	4	|
261
<6>[ 2066.554046] |	1	|	0xf1	|	241	|
262
<6>[ 2066.554260] |	2	|	0x84	|	132	|
263
<6>[ 2066.554504] |	3	|	0x87	|	135	|
264
<6>[ 2066.554931] |	4	|	0x83	|	131	|
265
<6>[ 2066.555145] ----------
266
<6>[ 2066.555389] --> ECS_IOCTL_WRITE
267
<6>[ 2066.557525] --> ECS_IOCTL_GET_CLOSE_STATUS
268
<6>[ 2066.558074] --> ECS_IOCTL_GET_DELAY
269
<6>[ 2066.558319] --> ECS_IOCTL_GET_DELAY #3
270
<6>[ 2066.761016] --> ECS_IOCTL_SET_MODE #1
271
<6>[ 2066.761932] --> ECS_IOCTL_SET_MODE
272
<6>[ 2066.762420]  --> AKECS_MODE_MEASURE_SNG
273
<6>[ 2066.781555] --> ECS_IOCTL_GETDATA
274
<6>[ 2066.782531] --> ECS_IOCTL_GETDATA #3
275
<6>[ 2066.783020] --------------------
276
<6>[ 2066.783477] |	index	|	hdata	|	ddata	|
277
<6>[ 2066.783935] gflag1|	0	|	0x70	|	112	|
278
<6>[ 2066.784820] gflag1|	1	|	0x7f	|	127	|
279
<6>[ 2066.785278] gflag1|	2	|	0xa3	|	163	|
280
<6>[ 2066.785766] gflag1|	3	|	0x5d	|	93	|
281
<6>[ 2066.786621] gflag1|	4	|	0x68	|	104	|
282
<6>[ 2066.787078] gflag1|	5	|	0x86	|	134	|
283
<6>[ 2066.787567] gflag1|	6	|	0x5c	|	92	|
284
<6>[ 2066.788421] gflag1|	7	|	0x85	|	133	|
285
<6>[ 2066.788879] gflag1|	8	|	0x0	|	0	|
286
<6>[ 2066.789367] gflag1|	9	|	0x0	|	0	|
287
<6>[ 2066.790222] gflag1|	10	|	0x0	|	0	|
288
<6>[ 2066.790832] gflag1|	11	|	0x0	|	0	|
289
<6>[ 2066.791320] gflag1|	12	|	0x0	|	0	|
290
<6>[ 2066.791778] gflag1|	13	|	0x0	|	0	|
291
<6>[ 2066.792663] gflag1|	14	|	0x0	|	0	|
292
<6>[ 2066.793121] gflag1|	15	|	0x0	|	0	|
293
<6>[ 2066.793579] gflag1|	16	|	0x0	|	0	|
294
<6>[ 2066.794464] gflag1|	17	|	0xa3	|	163	|
295
<6>[ 2066.794921] gflag1|	18	|	0x5d	|	93	|
296
<6>[ 2066.795379] gflag1|	19	|	0x68	|	104	|
297
<6>[ 2066.796264] gflag1|	20	|	0x86	|	134	|
298
<6>[ 2066.796722] gflag1|	21	|	0x5c	|	92	|
299
<6>[ 2066.797210] gflag1|	22	|	0x85	|	133	|
300
<6>[ 2066.798065] gflag1|	23	|	0x0	|	0	|
301
<6>[ 2066.798553] gflag1|	24	|	0x0	|	0	|
302
<6>[ 2066.799041] gflag1|	25	|	0x0	|	0	|
303
<6>[ 2066.799499] gflag1|	26	|	0x0	|	0	|
304
<6>[ 2066.800354] gflag1|	27	|	0x0	|	0	|
305
<6>[ 2066.800903] gflag1|	28	|	0x0	|	0	|
306
<6>[ 2066.801391] gflag1|	29	|	0x0	|	0	|
307
<6>[ 2066.802246] gflag1|	30	|	0x0	|	0	|
308
<6>[ 2066.802703] gflag1|	31	|	0x0	|	0	|
309
<6>[ 2066.803161] ----------
310
<6>[ 2066.807067] --> ECS_IOCTL_GET_NUMFRQ
311
<6>[ 2066.808044] --> ECS_IOCTL_GET_NUMFRQ #3
312
<6>[ 2066.808502] --------------------
313
<6>[ 2066.808959] |	index	|	hdata	|	ddata	|
314
<6>[ 2066.809814] |	0	|	0x1	|	1	|
315
<6>[ 2066.810302] |	1	|	0x0	|	0	|
316
<6>[ 2066.810943] ----------
317
<6>[ 2066.813629] --> ECS_IOCTL_SET_YPR #1
318
<6>[ 2066.814636] --------------------
319
<6>[ 2066.815093] |	index	|	hdata	|	ddata	|
320
<6>[ 2066.815582] gflag2|	0	|	0x55	|	85	|
321
<6>[ 2066.816467] gflag2|	1	|	0xffffffff	|	-1	|
322
<6>[ 2066.816925] gflag2|	2	|	0x2	|	2	|
323
<6>[ 2066.817382] gflag2|	3	|	0x1e	|	30	|
324
<6>[ 2066.817840] gflag2|	4	|	0x1	|	1	|
325
<6>[ 2066.818328] gflag2|	5	|	0x0	|	0	|
326
<6>[ 2066.818786] gflag2|	6	|	0x14	|	20	|
327
<6>[ 2066.819244] gflag2|	7	|	0xfffffd3b	|	-709	|
328
<6>[ 2066.820129] gflag2|	8	|	0x11	|	17	|
329
<6>[ 2066.820770] gflag2|	9	|	0x185	|	389	|
330
<6>[ 2066.821258] gflag2|	10	|	0xffffffe7	|	-25	|
331
<6>[ 2066.822113] gflag2|	11	|	0xfffffe20	|	-480	|
332
<6>[ 2066.822570] ----------
333
<6>[ 2066.823028] --> ECS_IOCTL_SET_YPR
334
<6>[ 2066.823913] AKECS_Report_Value: yaw = 85, pitch = -1, roll = 2
335
<6>[ 2066.824401]                     tmp = 30, m_stat= 1, g_stat=0
336
<6>[ 2066.825286]           G_Sensor:   x = 20 LSB, y = -709 LSB, z = 17 LSB
337
<6>[ 2066.825744]                MAG:   MAGV_X = 389, MAGV_Y = -25, MAGV_Z = -480
338
<6>[ 2066.829833] --> ECS_IOCTL_GET_DELAY
339
<6>[ 2066.830352] --> ECS_IOCTL_GET_DELAY #3
340
<6>[ 2067.034759] --> ECS_IOCTL_SET_MODE #1
341
<6>[ 2067.035705] --> ECS_IOCTL_SET_MODE
342
<6>[ 2067.036163]  --> AKECS_MODE_MEASURE_SNG
343
<6>[ 2067.051818] --> ECS_IOCTL_GETDATA
344
<6>[ 2067.052764] --> ECS_IOCTL_GETDATA #3
345
<6>[ 2067.053253] --------------------
346
<6>[ 2067.053741] |	index	|	hdata	|	ddata	|
347
<6>[ 2067.054595] gflag1|	0	|	0x70	|	112	|
348
<6>[ 2067.055084] gflag1|	1	|	0x7f	|	127	|
349
<6>[ 2067.055572] gflag1|	2	|	0xa2	|	162	|
350
<6>[ 2067.056427] gflag1|	3	|	0x5d	|	93	|
351
<6>[ 2067.056915] gflag1|	4	|	0x65	|	101	|
352
<6>[ 2067.057373] gflag1|	5	|	0x86	|	134	|
353
<6>[ 2067.057861] gflag1|	6	|	0x5b	|	91	|
354
<6>[ 2067.058715] gflag1|	7	|	0x85	|	133	|
355
<6>[ 2067.059173] gflag1|	8	|	0x0	|	0	|
356
<6>[ 2067.059661] gflag1|	9	|	0x0	|	0	|
357
<6>[ 2067.060577] gflag1|	10	|	0x0	|	0	|
358
<6>[ 2067.061157] gflag1|	11	|	0x0	|	0	|
359
<6>[ 2067.061645] gflag1|	12	|	0x0	|	0	|
360
<6>[ 2067.062500] gflag1|	13	|	0x0	|	0	|
361
<6>[ 2067.062957] gflag1|	14	|	0x0	|	0	|
362
<6>[ 2067.063415] gflag1|	15	|	0x0	|	0	|
363
<6>[ 2067.063873] gflag1|	16	|	0x0	|	0	|
364
<6>[ 2067.064727] gflag1|	17	|	0xa2	|	162	|
365
<6>[ 2067.065185] gflag1|	18	|	0x5d	|	93	|
366
<6>[ 2067.065673] gflag1|	19	|	0x65	|	101	|
367
<6>[ 2067.066528] gflag1|	20	|	0x86	|	134	|
368
<6>[ 2067.067016] gflag1|	21	|	0x5b	|	91	|
369
<6>[ 2067.067474] gflag1|	22	|	0x85	|	133	|
370
<6>[ 2067.068328] gflag1|	23	|	0x0	|	0	|
371
<6>[ 2067.068817] gflag1|	24	|	0x0	|	0	|
372
<6>[ 2067.069274] gflag1|	25	|	0x0	|	0	|
373
<6>[ 2067.070129] gflag1|	26	|	0x0	|	0	|
374
<6>[ 2067.070587] gflag1|	27	|	0x0	|	0	|
375
<6>[ 2067.071136] gflag1|	28	|	0x0	|	0	|
376
<6>[ 2067.071624] gflag1|	29	|	0x0	|	0	|
377
<6>[ 2067.072479] gflag1|	30	|	0x0	|	0	|
378
<6>[ 2067.072937] gflag1|	31	|	0x0	|	0	|
379
<6>[ 2067.073394] ----------
380
<6>[ 2067.077880] --> ECS_IOCTL_GET_NUMFRQ
381
<6>[ 2067.078399] --> ECS_IOCTL_GET_NUMFRQ #3
382
<6>[ 2067.078857] --------------------
383
<6>[ 2067.079315] |	index	|	hdata	|	ddata	|
384
<6>[ 2067.080169] |	0	|	0x1	|	1	|
385
<6>[ 2067.080657] |	1	|	0x0	|	0	|
386
<6>[ 2067.081298] ----------
387
<6>[ 2067.083892] --> ECS_IOCTL_SET_YPR #1
388
<6>[ 2067.084869] --------------------
389
<6>[ 2067.085327] |	index	|	hdata	|	ddata	|
390
<6>[ 2067.085815] gflag2|	0	|	0x54	|	84	|
391
<6>[ 2067.086700] gflag2|	1	|	0xffffffff	|	-1	|
392
<6>[ 2067.087158] gflag2|	2	|	0x2	|	2	|
393
<6>[ 2067.087615] gflag2|	3	|	0x1e	|	30	|
394
<6>[ 2067.088470] gflag2|	4	|	0x1	|	1	|
395
<6>[ 2067.088928] gflag2|	5	|	0x0	|	0	|
396
<6>[ 2067.089416] gflag2|	6	|	0x14	|	20	|
397
<6>[ 2067.090270] gflag2|	7	|	0xfffffd2b	|	-725	|
398
<6>[ 2067.090728] gflag2|	8	|	0x11	|	17	|
399
<6>[ 2067.091400] gflag2|	9	|	0x175	|	373	|
400
<6>[ 2067.092254] gflag2|	10	|	0xffffffe7	|	-25	|
401
<6>[ 2067.092742] gflag2|	11	|	0xfffffdef	|	-529	|
402
<6>[ 2067.093231] ----------
403
<6>[ 2067.093688] --> ECS_IOCTL_SET_YPR
404
<6>[ 2067.094543] AKECS_Report_Value: yaw = 84, pitch = -1, roll = 2
405
<6>[ 2067.095031]                     tmp = 30, m_stat= 1, g_stat=0
406
<6>[ 2067.095916]           G_Sensor:   x = 20 LSB, y = -725 LSB, z = 17 LSB
407
<6>[ 2067.096405]                MAG:   MAGV_X = 373, MAGV_Y = -25, MAGV_Z = -529
408
}}}
409
410
=== Index of the things to know about the different ioctl commands ===
411
412
 * '''ECS_IOCTL_SET_MODE''': value is a short, must be one of the following values, as defined in akm8976.h:
413
{{{
414
#define AKECS_MODE_MEASURE	0x00	/* Starts measurement. Please use AKECS_MODE_MEASURE_SNG */
415
					/* or AKECS_MODE_MEASURE_SEQ instead of this. */
416
#define AKECS_MODE_PFFD		0x01	/* Start pedometer and free fall detect. */
417
#define AKECS_MODE_E2P_READ	0x02	/* E2P access mode (read). */
418
#define AKECS_MODE_POWERDOWN	0x03	/* Power down mode */
419
420
#define AKECS_MODE_MEASURE_SNG	0x10	/* Starts single measurement */
421
#define AKECS_MODE_MEASURE_SEQ	0x11	/* Starts sequential measurement */
422
}}}
423
 * '''ECS_IOCTL_READ'''/'''ECS_IOCTL_WRITE''': value is a char table (called rwbuf on the kernel driver). rwbuf[0] is the length of the data and the data itself starts at rwbuf[1]. '''ECS_IOCTL_READ''' will give an answer to the request (on the same format) while '''ECS_IOCTL_WRITE''' won't. rwbuf is sent to the chip using I2C from the kernel driver.
424
425
=== Index of the files that are used by akmd or the kernel ===
426
427
 * '''/data/misc/akmd_set.txt''': it's the file containing the calibration values that akmd loads when it starts. If this file does not exist, akmd will re-create from the data it gets doing an ioctl system call to the kernel driver with ECS_IOCTL_GET_CALI_DATA. 
428
429
=== The initialization part ===
430
431
Let's take a look closer at the initialization part: this concerns everything before akmd starts reporting treated values.
432
433
So first of all, we have:
434
435
{{{
436
<6>[ 2066.362670] --> ECS_IOCTL_SET_MODE #1
437
<6>[ 2066.363220] --> ECS_IOCTL_SET_MODE
438
<6>[ 2066.364074]  --> AKECS_MODE_E2P_READ
439
440
}}}
441
442
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.
443
444
{{{
445
<6>[ 2066.381042] --> ECS_IOCTL_READ #1
446
<6>[ 2066.381317] what is in rwbuf?
447
<6>[ 2066.381744] --------------------
448
<6>[ 2066.382019] |	index	|	hdata	|	ddata	|
449
<6>[ 2066.382263] |	0	|	0x1	|	1	|
450
<6>[ 2066.382507] |	1	|	0x42	|	66	|
451
<6>[ 2066.382934] |	2	|	0x0	|	0	|
452
<6>[ 2066.383178] |	3	|	0x0	|	0	|
453
<6>[ 2066.383392] |	4	|	0x0	|	0	|
454
<6>[ 2066.383636] ----------
455
<6>[ 2066.384063] --> ECS_IOCTL_READ
456
<6>[ 2066.384979] --> ECS_IOCTL_READ #3
457
<6>[ 2066.385253] --------------------
458
<6>[ 2066.385498] |	index	|	hdata	|	ddata	|
459
<6>[ 2066.385925] |	0	|	0x1	|	1	|
460
<6>[ 2066.386169] |	1	|	0x66	|	102	|
461
<6>[ 2066.386383] |	2	|	0x0	|	0	|
462
<6>[ 2066.386627] |	3	|	0x0	|	0	|
463
<6>[ 2066.387054] |	4	|	0x0	|	0	|
464
}}}
465
466
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. 
467
For this, the request is always { 1, 66 } but the answer may not be the same on different devices. 
468
469
Though, this value seems not to be used used for any of the next requests, but it may still be the case. 
470
471
{{{
472
<6>[ 2066.387542] --> ECS_IOCTL_SET_MODE #1
473
<6>[ 2066.387786] --> ECS_IOCTL_SET_MODE
474
<6>[ 2066.388214]  --> AKECS_MODE_POWERDOWN
475
<6>[ 2066.401031] --> ECS_IOCTL_GET_OPEN_STATUS
476
<6>[ 2066.401306] --> ECS_IOCTL_GET_OPEN_STATUS #3
477
<6>[ 2066.407135] --> ECS_IOCTL_INIT
478
<6>[ 2066.408020] --> ECS_IOCTL_SET_MODE #1
479
<6>[ 2066.408294] --> ECS_IOCTL_SET_MODE
480
<6>[ 2066.408721]  --> AKECS_MODE_E2P_READ
481
}}}
482
483
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
484
 will block until the chip is requested. This also append when the phone is in "sleep" mode. 
485
486
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.
487
488
All this is already implemented in akmd-free.
489
490
{{{
491
<6>[ 2066.421234] --> ECS_IOCTL_READ #1
492
<6>[ 2066.421630] what is in rwbuf?
493
<6>[ 2066.422302] --------------------
494
<6>[ 2066.422637] |	index	|	hdata	|	ddata	|
495
<6>[ 2066.423004] |	0	|	0x3	|	3	|
496
<6>[ 2066.423339] |	1	|	0x46	|	70	|
497
<6>[ 2066.423950] |	2	|	0x0	|	0	|
498
<6>[ 2066.424285] |	3	|	0x0	|	0	|
499
<6>[ 2066.424621] |	4	|	0x0	|	0	|
500
<6>[ 2066.424957] ----------
501
<6>[ 2066.425567] --> ECS_IOCTL_READ
502
<6>[ 2066.426696] --> ECS_IOCTL_READ #3
503
<6>[ 2066.427062] --------------------
504
<6>[ 2066.427398] |	index	|	hdata	|	ddata	|
505
<6>[ 2066.428039] |	0	|	0x3	|	3	|
506
<6>[ 2066.428375] |	1	|	0x97	|	151	|
507
<6>[ 2066.428710] |	2	|	0x87	|	135	|
508
<6>[ 2066.429321] |	3	|	0x19	|	25	|
509
<6>[ 2066.429656] |	4	|	0x0	|	0	|
510
<6>[ 2066.429992] ----------
511
}}}
512
513
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.
514
515
{{{
516
<6>[ 2066.431243] --> ECS_IOCTL_SET_MODE #1
517
<6>[ 2066.431915] --> ECS_IOCTL_SET_MODE
518
<6>[ 2066.432250]  --> AKECS_MODE_POWERDOWN
519
<6>[ 2066.450866] --> ECS_IOCTL_WRITE #1
520
<6>[ 2066.451385] what is in rwbuf?
521
<6>[ 2066.452239] --------------------
522
<6>[ 2066.452697] |	index	|	hdata	|	ddata	|
523
<6>[ 2066.453186] |	0	|	0x4	|	4	|
524
<6>[ 2066.454040] |	1	|	0xe8	|	232	|
525
<6>[ 2066.454498] |	2	|	0x7	|	7	|
526
<6>[ 2066.454956] |	3	|	0x7	|	7	|
527
<6>[ 2066.455413] |	4	|	0x9	|	9	|
528
<6>[ 2066.456268] ----------
529
<6>[ 2066.456726] --> ECS_IOCTL_WRITE
530
}}}
531
532
Here akmd sets the mode to AKECS_MODE_POWERDOWN and writes 4 numbers { 4, 232, x, y, z } to the kernel driver. rwbuf[1] 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:
533
x = (READ ASW #2's x) % 16
534
y = (READ ASW #2's y) % 16
535
z = (READ ASW #2's y) % 16
536
537
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. 
538
539
{{{
540
<6>[ 2066.457916] --> ECS_IOCTL_WRITE #1
541
<6>[ 2066.458374] what is in rwbuf?
542
<6>[ 2066.459228] --------------------
543
<6>[ 2066.459686] |	index	|	hdata	|	ddata	|
544
<6>[ 2066.460174] |	0	|	0x4	|	4	|
545
<6>[ 2066.460784] |	1	|	0xe5	|	229	|
546
<6>[ 2066.461669] |	2	|	0x89	|	137	|
547
<6>[ 2066.462127] |	3	|	0x0	|	0	|
548
<6>[ 2066.462615] |	4	|	0x89	|	137	|
549
<6>[ 2066.463073] ----------
550
<6>[ 2066.463928] --> ECS_IOCTL_WRITE
551
<6>[ 2066.465698] --> ECS_IOCTL_SET_MODE #1
552
<6>[ 2066.466186] --> ECS_IOCTL_SET_MODE
553
<6>[ 2066.467071]  --> AKECS_MODE_MEASURE_SNG
554
}}}
555
556
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''.
557
558
Anyway, setting x, y and z to 0 doesn't prevent anything to work. 
559
560
Then akmd also sets the mode to AKECS_MODE_MEASURE_SNG.