Project

General

Profile

AKM8976A » History » Version 12

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

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