import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / magnetometer / bmm150 / bmm150.c
1 /* bmm150.c - bmm150 compass driver
2 *
3 *
4 * This software program is licensed subject to the GNU General Public License
5 * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
6
7 * (C) Copyright 2011 Bosch Sensortec GmbH
8 * All Rights Reserved
9 *
10 * VERSION: V1.2
11 * History: V1.0 --- Driver creation
12 * V1.1 --- Add share I2C address solution
13 * V1.2 --- Fix bug that daemon can't get
14 * delay command.
15 */
16
17 #include <linux/interrupt.h>
18 #include <linux/i2c.h>
19 #include <linux/slab.h>
20 #include <linux/irq.h>
21 #include <linux/miscdevice.h>
22 #include <asm/uaccess.h>
23 #include <asm/atomic.h>
24 #include <linux/delay.h>
25 #include <linux/input.h>
26 #include <linux/workqueue.h>
27 #include <linux/kobject.h>
28 #include <linux/platform_device.h>
29 #include <linux/earlysuspend.h>
30 #include <linux/time.h>
31 #include <linux/hrtimer.h>
32 #include <linux/module.h>
33
34 #include <mach/mt_typedefs.h>
35 #include <mach/mt_gpio.h>
36 #include <mach/mt_pm_ldo.h>
37
38 #define POWER_NONE_MACRO MT65XX_POWER_NONE
39
40
41 #include <cust_mag.h>
42 #include <linux/hwmsen_helper.h>
43 #include <linux/hwmsensor.h>
44 #include <linux/hwmsen_dev.h>
45 #include <linux/sensors_io.h>
46 #include "bmm150.h"
47
48 /*----------------------------------------------------------------------------*/
49 /*
50 * Enable the driver to block e-compass daemon on suspend
51 */
52 #define BMC150_BLOCK_DAEMON_ON_SUSPEND
53 //#undef BMC150_BLOCK_DAEMON_ON_SUSPEND
54 /*
55 * Enable gyroscope feature with BMC150
56 */
57 #define BMC150_M4G
58 #undef BMC150_M4G
59 /*
60 * Enable rotation vecter feature with BMC150
61 */
62 #define BMC150_VRV
63 #undef BMC150_VRV
64
65 /*
66 * Enable virtual linear accelerometer feature with BMC150
67 */
68 #define BMC150_VLA
69 #undef BMC150_VLA
70
71 /*
72 * Enable virtual gravity feature with BMC150
73 */
74 #define BMC150_VG
75 #undef BMC150_VG
76
77 #ifdef BMC150_M4G
78 /* !!! add a new definition in linux/sensors_io.h if possible !!! */
79 #define ECOMPASS_IOC_GET_GFLAG _IOR(MSENSOR, 0x30, short)
80 /* !!! add a new definition in linux/sensors_io.h if possible !!! */
81 #define ECOMPASS_IOC_GET_GDELAY _IOR(MSENSOR, 0x31, int)
82 #endif //BMC150_M4G
83 #ifdef BMC150_VRV
84 /* !!! add a new definition in linux/sensors_io.h if possible !!! */
85 #define ECOMPASS_IOC_GET_VRVFLAG _IOR(MSENSOR, 0x32, short)
86 /* !!! add a new definition in linux/sensors_io.h if possible !!! */
87 #define ECOMPASS_IOC_GET_VRVDELAY _IOR(MSENSOR, 0x33, int)
88 #endif //BMC150_VRV
89 #ifdef BMC150_VLA
90 /* !!! add a new definition in linux/sensors_io.h if possible !!! */
91 #define ECOMPASS_IOC_GET_VLAFLAG _IOR(MSENSOR, 0x34, short)
92 /* !!! add a new definition in linux/sensors_io.h if possible !!! */
93 #define ECOMPASS_IOC_GET_VLADELAY _IOR(MSENSOR, 0x35, int)
94 #endif //BMC150_VLA
95 #ifdef BMC150_VG
96 /* !!! add a new definition in linux/sensors_io.h if possible !!! */
97 #define ECOMPASS_IOC_GET_VGFLAG _IOR(MSENSOR, 0x36, short)
98 /* !!! add a new definition in linux/sensors_io.h if possible !!! */
99 #define ECOMPASS_IOC_GET_VGDELAY _IOR(MSENSOR, 0x37, int)
100 #endif //BMC150_VG
101
102 /*----------------------------------------------------------------------------*/
103 /* BMM150 API Section */
104 /*----------------------------------------------------------------------------*/
105
106 #define BMM150_U16 unsigned short
107 #define BMM150_S16 signed short
108 #define BMM150_S32 signed int
109
110
111 #define BMM150_BUS_WR_RETURN_TYPE char
112 #define BMM150_BUS_WR_PARAM_TYPES\
113 unsigned char, unsigned char, unsigned char *, unsigned char
114 #define BMM150_BUS_WR_PARAM_ORDER\
115 (device_addr, register_addr, register_data, wr_len)
116 #define BMM150_BUS_WRITE_FUNC(\
117 device_addr, register_addr, register_data, wr_len)\
118 bus_write(device_addr, register_addr, register_data, wr_len)
119
120 #define BMM150_BUS_RD_RETURN_TYPE char
121
122 #define BMM150_BUS_RD_PARAM_TYPES\
123 unsigned char, unsigned char, unsigned char *, unsigned char
124
125 #define BMM150_BUS_RD_PARAM_ORDER (device_addr, register_addr, register_data)
126
127 #define BMM150_BUS_READ_FUNC(device_addr, register_addr, register_data, rd_len)\
128 bus_read(device_addr, register_addr, register_data, rd_len)
129
130
131 #define BMM150_DELAY_RETURN_TYPE void
132
133 #define BMM150_DELAY_PARAM_TYPES unsigned int
134
135 #define BMM150_DELAY_FUNC(delay_in_msec)\
136 delay_func(delay_in_msec)
137
138 #define BMM150_DELAY_POWEROFF_SUSPEND 1
139 #define BMM150_DELAY_SUSPEND_SLEEP 2
140 #define BMM150_DELAY_SLEEP_ACTIVE 1
141 #define BMM150_DELAY_ACTIVE_SLEEP 1
142 #define BMM150_DELAY_SLEEP_SUSPEND 1
143 #define BMM150_DELAY_ACTIVE_SUSPEND 1
144 #define BMM150_DELAY_SLEEP_POWEROFF 1
145 #define BMM150_DELAY_ACTIVE_POWEROFF 1
146 #define BMM150_DELAY_SETTLING_TIME 2
147
148
149 #define BMM150_RETURN_FUNCTION_TYPE char
150 #define BMM150_I2C_ADDRESS 0x10
151
152 /*General Info datas*/
153 #define BMM150_SOFT_RESET7_ON 1
154 #define BMM150_SOFT_RESET1_ON 1
155 #define BMM150_SOFT_RESET7_OFF 0
156 #define BMM150_SOFT_RESET1_OFF 0
157 #define BMM150_DELAY_SOFTRESET 1
158
159 /* Fixed Data Registers */
160 #define BMM150_CHIP_ID 0x40
161
162 /* Data Registers */
163 #define BMM150_DATAX_LSB 0x42
164 #define BMM150_DATAX_MSB 0x43
165 #define BMM150_DATAY_LSB 0x44
166 #define BMM150_DATAY_MSB 0x45
167 #define BMM150_DATAZ_LSB 0x46
168 #define BMM150_DATAZ_MSB 0x47
169 #define BMM150_R_LSB 0x48
170 #define BMM150_R_MSB 0x49
171
172 /* Status Registers */
173 #define BMM150_INT_STAT 0x4A
174
175 /* Control Registers */
176 #define BMM150_POWER_CNTL 0x4B
177 #define BMM150_CONTROL 0x4C
178 #define BMM150_INT_CNTL 0x4D
179 #define BMM150_SENS_CNTL 0x4E
180 #define BMM150_LOW_THRES 0x4F
181 #define BMM150_HIGH_THRES 0x50
182 #define BMM150_NO_REPETITIONS_XY 0x51
183 #define BMM150_NO_REPETITIONS_Z 0x52
184
185 /* Trim Extended Registers */
186 #define BMM150_DIG_X1 0x5D
187 #define BMM150_DIG_Y1 0x5E
188 #define BMM150_DIG_Z4_LSB 0x62
189 #define BMM150_DIG_Z4_MSB 0x63
190 #define BMM150_DIG_X2 0x64
191 #define BMM150_DIG_Y2 0x65
192 #define BMM150_DIG_Z2_LSB 0x68
193 #define BMM150_DIG_Z2_MSB 0x69
194 #define BMM150_DIG_Z1_LSB 0x6A
195 #define BMM150_DIG_Z1_MSB 0x6B
196 #define BMM150_DIG_XYZ1_LSB 0x6C
197 #define BMM150_DIG_XYZ1_MSB 0x6D
198 #define BMM150_DIG_Z3_LSB 0x6E
199 #define BMM150_DIG_Z3_MSB 0x6F
200 #define BMM150_DIG_XY2 0x70
201 #define BMM150_DIG_XY1 0x71
202
203
204 /* Data X LSB Regsiter */
205 #define BMM150_DATAX_LSB_VALUEX__POS 3
206 #define BMM150_DATAX_LSB_VALUEX__LEN 5
207 #define BMM150_DATAX_LSB_VALUEX__MSK 0xF8
208 #define BMM150_DATAX_LSB_VALUEX__REG BMM150_DATAX_LSB
209
210 #define BMM150_DATAX_LSB_TESTX__POS 0
211 #define BMM150_DATAX_LSB_TESTX__LEN 1
212 #define BMM150_DATAX_LSB_TESTX__MSK 0x01
213 #define BMM150_DATAX_LSB_TESTX__REG BMM150_DATAX_LSB
214
215 /* Data Y LSB Regsiter */
216 #define BMM150_DATAY_LSB_VALUEY__POS 3
217 #define BMM150_DATAY_LSB_VALUEY__LEN 5
218 #define BMM150_DATAY_LSB_VALUEY__MSK 0xF8
219 #define BMM150_DATAY_LSB_VALUEY__REG BMM150_DATAY_LSB
220
221 #define BMM150_DATAY_LSB_TESTY__POS 0
222 #define BMM150_DATAY_LSB_TESTY__LEN 1
223 #define BMM150_DATAY_LSB_TESTY__MSK 0x01
224 #define BMM150_DATAY_LSB_TESTY__REG BMM150_DATAY_LSB
225
226 /* Data Z LSB Regsiter */
227 #define BMM150_DATAZ_LSB_VALUEZ__POS 1
228 #define BMM150_DATAZ_LSB_VALUEZ__LEN 7
229 #define BMM150_DATAZ_LSB_VALUEZ__MSK 0xFE
230 #define BMM150_DATAZ_LSB_VALUEZ__REG BMM150_DATAZ_LSB
231
232 #define BMM150_DATAZ_LSB_TESTZ__POS 0
233 #define BMM150_DATAZ_LSB_TESTZ__LEN 1
234 #define BMM150_DATAZ_LSB_TESTZ__MSK 0x01
235 #define BMM150_DATAZ_LSB_TESTZ__REG BMM150_DATAZ_LSB
236
237 /* Hall Resistance LSB Regsiter */
238 #define BMM150_R_LSB_VALUE__POS 2
239 #define BMM150_R_LSB_VALUE__LEN 6
240 #define BMM150_R_LSB_VALUE__MSK 0xFC
241 #define BMM150_R_LSB_VALUE__REG BMM150_R_LSB
242
243 #define BMM150_DATA_RDYSTAT__POS 0
244 #define BMM150_DATA_RDYSTAT__LEN 1
245 #define BMM150_DATA_RDYSTAT__MSK 0x01
246 #define BMM150_DATA_RDYSTAT__REG BMM150_R_LSB
247
248 /* Interupt Status Register */
249 #define BMM150_INT_STAT_DOR__POS 7
250 #define BMM150_INT_STAT_DOR__LEN 1
251 #define BMM150_INT_STAT_DOR__MSK 0x80
252 #define BMM150_INT_STAT_DOR__REG BMM150_INT_STAT
253
254 #define BMM150_INT_STAT_OVRFLOW__POS 6
255 #define BMM150_INT_STAT_OVRFLOW__LEN 1
256 #define BMM150_INT_STAT_OVRFLOW__MSK 0x40
257 #define BMM150_INT_STAT_OVRFLOW__REG BMM150_INT_STAT
258
259 #define BMM150_INT_STAT_HIGH_THZ__POS 5
260 #define BMM150_INT_STAT_HIGH_THZ__LEN 1
261 #define BMM150_INT_STAT_HIGH_THZ__MSK 0x20
262 #define BMM150_INT_STAT_HIGH_THZ__REG BMM150_INT_STAT
263
264 #define BMM150_INT_STAT_HIGH_THY__POS 4
265 #define BMM150_INT_STAT_HIGH_THY__LEN 1
266 #define BMM150_INT_STAT_HIGH_THY__MSK 0x10
267 #define BMM150_INT_STAT_HIGH_THY__REG BMM150_INT_STAT
268
269 #define BMM150_INT_STAT_HIGH_THX__POS 3
270 #define BMM150_INT_STAT_HIGH_THX__LEN 1
271 #define BMM150_INT_STAT_HIGH_THX__MSK 0x08
272 #define BMM150_INT_STAT_HIGH_THX__REG BMM150_INT_STAT
273
274 #define BMM150_INT_STAT_LOW_THZ__POS 2
275 #define BMM150_INT_STAT_LOW_THZ__LEN 1
276 #define BMM150_INT_STAT_LOW_THZ__MSK 0x04
277 #define BMM150_INT_STAT_LOW_THZ__REG BMM150_INT_STAT
278
279 #define BMM150_INT_STAT_LOW_THY__POS 1
280 #define BMM150_INT_STAT_LOW_THY__LEN 1
281 #define BMM150_INT_STAT_LOW_THY__MSK 0x02
282 #define BMM150_INT_STAT_LOW_THY__REG BMM150_INT_STAT
283
284 #define BMM150_INT_STAT_LOW_THX__POS 0
285 #define BMM150_INT_STAT_LOW_THX__LEN 1
286 #define BMM150_INT_STAT_LOW_THX__MSK 0x01
287 #define BMM150_INT_STAT_LOW_THX__REG BMM150_INT_STAT
288
289 /* Power Control Register */
290 #define BMM150_POWER_CNTL_SRST7__POS 7
291 #define BMM150_POWER_CNTL_SRST7__LEN 1
292 #define BMM150_POWER_CNTL_SRST7__MSK 0x80
293 #define BMM150_POWER_CNTL_SRST7__REG BMM150_POWER_CNTL
294
295 #define BMM150_POWER_CNTL_SPI3_EN__POS 2
296 #define BMM150_POWER_CNTL_SPI3_EN__LEN 1
297 #define BMM150_POWER_CNTL_SPI3_EN__MSK 0x04
298 #define BMM150_POWER_CNTL_SPI3_EN__REG BMM150_POWER_CNTL
299
300 #define BMM150_POWER_CNTL_SRST1__POS 1
301 #define BMM150_POWER_CNTL_SRST1__LEN 1
302 #define BMM150_POWER_CNTL_SRST1__MSK 0x02
303 #define BMM150_POWER_CNTL_SRST1__REG BMM150_POWER_CNTL
304
305 #define BMM150_POWER_CNTL_PCB__POS 0
306 #define BMM150_POWER_CNTL_PCB__LEN 1
307 #define BMM150_POWER_CNTL_PCB__MSK 0x01
308 #define BMM150_POWER_CNTL_PCB__REG BMM150_POWER_CNTL
309
310 /* Control Register */
311 #define BMM150_CNTL_ADV_ST__POS 6
312 #define BMM150_CNTL_ADV_ST__LEN 2
313 #define BMM150_CNTL_ADV_ST__MSK 0xC0
314 #define BMM150_CNTL_ADV_ST__REG BMM150_CONTROL
315
316 #define BMM150_CNTL_DR__POS 3
317 #define BMM150_CNTL_DR__LEN 3
318 #define BMM150_CNTL_DR__MSK 0x38
319 #define BMM150_CNTL_DR__REG BMM150_CONTROL
320
321 #define BMM150_CNTL_OPMODE__POS 1
322 #define BMM150_CNTL_OPMODE__LEN 2
323 #define BMM150_CNTL_OPMODE__MSK 0x06
324 #define BMM150_CNTL_OPMODE__REG BMM150_CONTROL
325
326 #define BMM150_CNTL_S_TEST__POS 0
327 #define BMM150_CNTL_S_TEST__LEN 1
328 #define BMM150_CNTL_S_TEST__MSK 0x01
329 #define BMM150_CNTL_S_TEST__REG BMM150_CONTROL
330
331 /* Interupt Control Register */
332 #define BMM150_INT_CNTL_DOR_EN__POS 7
333 #define BMM150_INT_CNTL_DOR_EN__LEN 1
334 #define BMM150_INT_CNTL_DOR_EN__MSK 0x80
335 #define BMM150_INT_CNTL_DOR_EN__REG BMM150_INT_CNTL
336
337 #define BMM150_INT_CNTL_OVRFLOW_EN__POS 6
338 #define BMM150_INT_CNTL_OVRFLOW_EN__LEN 1
339 #define BMM150_INT_CNTL_OVRFLOW_EN__MSK 0x40
340 #define BMM150_INT_CNTL_OVRFLOW_EN__REG BMM150_INT_CNTL
341
342 #define BMM150_INT_CNTL_HIGH_THZ_EN__POS 5
343 #define BMM150_INT_CNTL_HIGH_THZ_EN__LEN 1
344 #define BMM150_INT_CNTL_HIGH_THZ_EN__MSK 0x20
345 #define BMM150_INT_CNTL_HIGH_THZ_EN__REG BMM150_INT_CNTL
346
347 #define BMM150_INT_CNTL_HIGH_THY_EN__POS 4
348 #define BMM150_INT_CNTL_HIGH_THY_EN__LEN 1
349 #define BMM150_INT_CNTL_HIGH_THY_EN__MSK 0x10
350 #define BMM150_INT_CNTL_HIGH_THY_EN__REG BMM150_INT_CNTL
351
352 #define BMM150_INT_CNTL_HIGH_THX_EN__POS 3
353 #define BMM150_INT_CNTL_HIGH_THX_EN__LEN 1
354 #define BMM150_INT_CNTL_HIGH_THX_EN__MSK 0x08
355 #define BMM150_INT_CNTL_HIGH_THX_EN__REG BMM150_INT_CNTL
356
357 #define BMM150_INT_CNTL_LOW_THZ_EN__POS 2
358 #define BMM150_INT_CNTL_LOW_THZ_EN__LEN 1
359 #define BMM150_INT_CNTL_LOW_THZ_EN__MSK 0x04
360 #define BMM150_INT_CNTL_LOW_THZ_EN__REG BMM150_INT_CNTL
361
362 #define BMM150_INT_CNTL_LOW_THY_EN__POS 1
363 #define BMM150_INT_CNTL_LOW_THY_EN__LEN 1
364 #define BMM150_INT_CNTL_LOW_THY_EN__MSK 0x02
365 #define BMM150_INT_CNTL_LOW_THY_EN__REG BMM150_INT_CNTL
366
367 #define BMM150_INT_CNTL_LOW_THX_EN__POS 0
368 #define BMM150_INT_CNTL_LOW_THX_EN__LEN 1
369 #define BMM150_INT_CNTL_LOW_THX_EN__MSK 0x01
370 #define BMM150_INT_CNTL_LOW_THX_EN__REG BMM150_INT_CNTL
371
372 /* Sensor Control Register */
373 #define BMM150_SENS_CNTL_DRDY_EN__POS 7
374 #define BMM150_SENS_CNTL_DRDY_EN__LEN 1
375 #define BMM150_SENS_CNTL_DRDY_EN__MSK 0x80
376 #define BMM150_SENS_CNTL_DRDY_EN__REG BMM150_SENS_CNTL
377
378 #define BMM150_SENS_CNTL_IE__POS 6
379 #define BMM150_SENS_CNTL_IE__LEN 1
380 #define BMM150_SENS_CNTL_IE__MSK 0x40
381 #define BMM150_SENS_CNTL_IE__REG BMM150_SENS_CNTL
382
383 #define BMM150_SENS_CNTL_CHANNELZ__POS 5
384 #define BMM150_SENS_CNTL_CHANNELZ__LEN 1
385 #define BMM150_SENS_CNTL_CHANNELZ__MSK 0x20
386 #define BMM150_SENS_CNTL_CHANNELZ__REG BMM150_SENS_CNTL
387
388 #define BMM150_SENS_CNTL_CHANNELY__POS 4
389 #define BMM150_SENS_CNTL_CHANNELY__LEN 1
390 #define BMM150_SENS_CNTL_CHANNELY__MSK 0x10
391 #define BMM150_SENS_CNTL_CHANNELY__REG BMM150_SENS_CNTL
392
393 #define BMM150_SENS_CNTL_CHANNELX__POS 3
394 #define BMM150_SENS_CNTL_CHANNELX__LEN 1
395 #define BMM150_SENS_CNTL_CHANNELX__MSK 0x08
396 #define BMM150_SENS_CNTL_CHANNELX__REG BMM150_SENS_CNTL
397
398 #define BMM150_SENS_CNTL_DR_POLARITY__POS 2
399 #define BMM150_SENS_CNTL_DR_POLARITY__LEN 1
400 #define BMM150_SENS_CNTL_DR_POLARITY__MSK 0x04
401 #define BMM150_SENS_CNTL_DR_POLARITY__REG BMM150_SENS_CNTL
402
403 #define BMM150_SENS_CNTL_INTERRUPT_LATCH__POS 1
404 #define BMM150_SENS_CNTL_INTERRUPT_LATCH__LEN 1
405 #define BMM150_SENS_CNTL_INTERRUPT_LATCH__MSK 0x02
406 #define BMM150_SENS_CNTL_INTERRUPT_LATCH__REG BMM150_SENS_CNTL
407
408 #define BMM150_SENS_CNTL_INTERRUPT_POLARITY__POS 0
409 #define BMM150_SENS_CNTL_INTERRUPT_POLARITY__LEN 1
410 #define BMM150_SENS_CNTL_INTERRUPT_POLARITY__MSK 0x01
411 #define BMM150_SENS_CNTL_INTERRUPT_POLARITY__REG BMM150_SENS_CNTL
412
413 /* Register 6D */
414 #define BMM150_DIG_XYZ1_MSB__POS 0
415 #define BMM150_DIG_XYZ1_MSB__LEN 7
416 #define BMM150_DIG_XYZ1_MSB__MSK 0x7F
417 #define BMM150_DIG_XYZ1_MSB__REG BMM150_DIG_XYZ1_MSB
418
419
420 #define BMM150_X_AXIS 0
421 #define BMM150_Y_AXIS 1
422 #define BMM150_Z_AXIS 2
423 #define BMM150_RESISTANCE 3
424 #define BMM150_X 1
425 #define BMM150_Y 2
426 #define BMM150_Z 4
427 #define BMM150_XYZ 7
428
429 /* Constants */
430 #define BMM150_NULL 0
431 #define BMM150_DISABLE 0
432 #define BMM150_ENABLE 1
433 #define BMM150_CHANNEL_DISABLE 1
434 #define BMM150_CHANNEL_ENABLE 0
435 #define BMM150_INTPIN_LATCH_ENABLE 1
436 #define BMM150_INTPIN_LATCH_DISABLE 0
437 #define BMM150_OFF 0
438 #define BMM150_ON 1
439
440 #define BMM150_NORMAL_MODE 0x00
441 #define BMM150_FORCED_MODE 0x01
442 #define BMM150_SUSPEND_MODE 0x02
443 #define BMM150_SLEEP_MODE 0x03
444
445 #define BMM150_ADVANCED_SELFTEST_OFF 0
446 #define BMM150_ADVANCED_SELFTEST_NEGATIVE 2
447 #define BMM150_ADVANCED_SELFTEST_POSITIVE 3
448
449 #define BMM150_NEGATIVE_SATURATION_Z -32767
450 #define BMM150_POSITIVE_SATURATION_Z 32767
451
452 #define BMM150_SPI_RD_MASK 0x80
453 #define BMM150_READ_SET 0x01
454
455 #define E_BMM150_NULL_PTR ((char)-127)
456 #define E_BMM150_COMM_RES ((char)-1)
457 #define E_BMM150_OUT_OF_RANGE ((char)-2)
458 #define E_BMM150_UNDEFINED_MODE 0
459
460 #define BMM150_WR_FUNC_PTR\
461 char (*bus_write)(unsigned char, unsigned char,\
462 unsigned char *, unsigned char)
463
464 #define BMM150_RD_FUNC_PTR\
465 char (*bus_read)(unsigned char, unsigned char,\
466 unsigned char *, unsigned char)
467 #define BMM150_MDELAY_DATA_TYPE unsigned int
468
469 /*Shifting Constants*/
470 #define SHIFT_RIGHT_1_POSITION 1
471 #define SHIFT_RIGHT_2_POSITION 2
472 #define SHIFT_RIGHT_3_POSITION 3
473 #define SHIFT_RIGHT_4_POSITION 4
474 #define SHIFT_RIGHT_5_POSITION 5
475 #define SHIFT_RIGHT_6_POSITION 6
476 #define SHIFT_RIGHT_7_POSITION 7
477 #define SHIFT_RIGHT_8_POSITION 8
478
479 #define SHIFT_LEFT_1_POSITION 1
480 #define SHIFT_LEFT_2_POSITION 2
481 #define SHIFT_LEFT_3_POSITION 3
482 #define SHIFT_LEFT_4_POSITION 4
483 #define SHIFT_LEFT_5_POSITION 5
484 #define SHIFT_LEFT_6_POSITION 6
485 #define SHIFT_LEFT_7_POSITION 7
486 #define SHIFT_LEFT_8_POSITION 8
487
488 /* Conversion factors*/
489 #define BMM150_CONVFACTOR_LSB_UT 6
490
491 /* get bit slice */
492 #define BMM150_GET_BITSLICE(regvar, bitname)\
493 ((regvar & bitname##__MSK) >> bitname##__POS)
494
495 /* Set bit slice */
496 #define BMM150_SET_BITSLICE(regvar, bitname, val)\
497 ((regvar & ~bitname##__MSK) | ((val<<bitname##__POS)&bitname##__MSK))
498
499 /* compensated output value returned if sensor had overflow */
500 #define BMM150_OVERFLOW_OUTPUT -32768
501 #define BMM150_OVERFLOW_OUTPUT_S32 ((BMM150_S32)(-2147483647-1))
502 #define BMM150_OVERFLOW_OUTPUT_FLOAT 0.0f
503 #define BMM150_FLIP_OVERFLOW_ADCVAL -4096
504 #define BMM150_HALL_OVERFLOW_ADCVAL -16384
505
506
507 #define BMM150_PRESETMODE_LOWPOWER 1
508 #define BMM150_PRESETMODE_REGULAR 2
509 #define BMM150_PRESETMODE_HIGHACCURACY 3
510 #define BMM150_PRESETMODE_ENHANCED 4
511
512 /* PRESET MODES - DATA RATES */
513 #define BMM150_LOWPOWER_DR BMM150_DR_10HZ
514 #define BMM150_REGULAR_DR BMM150_DR_10HZ
515 #define BMM150_HIGHACCURACY_DR BMM150_DR_20HZ
516 #define BMM150_ENHANCED_DR BMM150_DR_10HZ
517
518 /* PRESET MODES - REPETITIONS-XY RATES */
519 #define BMM150_LOWPOWER_REPXY 1
520 #define BMM150_REGULAR_REPXY 4
521 #define BMM150_HIGHACCURACY_REPXY 23
522 #define BMM150_ENHANCED_REPXY 7
523
524 /* PRESET MODES - REPETITIONS-Z RATES */
525 #define BMM150_LOWPOWER_REPZ 2
526 #define BMM150_REGULAR_REPZ 15
527 #define BMM150_HIGHACCURACY_REPZ 82
528 #define BMM150_ENHANCED_REPZ 26
529
530 /* Data Rates */
531
532 #define BMM150_DR_10HZ 0
533 #define BMM150_DR_02HZ 1
534 #define BMM150_DR_06HZ 2
535 #define BMM150_DR_08HZ 3
536 #define BMM150_DR_15HZ 4
537 #define BMM150_DR_20HZ 5
538 #define BMM150_DR_25HZ 6
539 #define BMM150_DR_30HZ 7
540
541 /*user defined Structures*/
542 struct bmm150api_mdata {
543 BMM150_S16 datax;
544 BMM150_S16 datay;
545 BMM150_S16 dataz;
546 BMM150_U16 resistance;
547 };
548 struct bmm150api_mdata_s32 {
549 BMM150_S32 datax;
550 BMM150_S32 datay;
551 BMM150_S32 dataz;
552 BMM150_U16 resistance;
553 };
554 struct bmm150api_mdata_float {
555 float datax;
556 float datay;
557 float dataz;
558 BMM150_U16 resistance;
559 };
560
561 struct bmm150api {
562 unsigned char company_id;
563 unsigned char dev_addr;
564
565 BMM150_WR_FUNC_PTR;
566 BMM150_RD_FUNC_PTR;
567 void(*delay_msec)(BMM150_MDELAY_DATA_TYPE);
568
569 signed char dig_x1;
570 signed char dig_y1;
571
572 signed char dig_x2;
573 signed char dig_y2;
574
575 BMM150_U16 dig_z1;
576 BMM150_S16 dig_z2;
577 BMM150_S16 dig_z3;
578 BMM150_S16 dig_z4;
579
580 unsigned char dig_xy1;
581 signed char dig_xy2;
582
583 BMM150_U16 dig_xyz1;
584 };
585
586
587 BMM150_RETURN_FUNCTION_TYPE bmm150api_init(struct bmm150api *p_bmm150);
588 BMM150_RETURN_FUNCTION_TYPE bmm150api_read_mdataXYZ(
589 struct bmm150api_mdata *mdata);
590 BMM150_RETURN_FUNCTION_TYPE bmm150api_read_mdataXYZ_s32(
591 struct bmm150api_mdata_s32 *mdata);
592 #ifdef ENABLE_FLOAT
593 BMM150_RETURN_FUNCTION_TYPE bmm150api_read_mdataXYZ_float(
594 struct bmm150api_mdata_float *mdata);
595 #endif
596 BMM150_RETURN_FUNCTION_TYPE bmm150api_read_register(
597 unsigned char addr, unsigned char *data, unsigned char len);
598 BMM150_RETURN_FUNCTION_TYPE bmm150api_write_register(
599 unsigned char addr, unsigned char *data, unsigned char len);
600 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_self_test_XYZ(
601 unsigned char *self_testxyz);
602 BMM150_S16 bmm150api_compensate_X(
603 BMM150_S16 mdata_x, BMM150_U16 data_R);
604 BMM150_S32 bmm150api_compensate_X_s32(
605 BMM150_S16 mdata_x, BMM150_U16 data_R);
606 #ifdef ENABLE_FLOAT
607 float bmm150api_compensate_X_float(
608 BMM150_S16 mdata_x, BMM150_U16 data_R);
609 #endif
610 BMM150_S16 bmm150api_compensate_Y(
611 BMM150_S16 mdata_y, BMM150_U16 data_R);
612 BMM150_S32 bmm150api_compensate_Y_s32(
613 BMM150_S16 mdata_y, BMM150_U16 data_R);
614 #ifdef ENABLE_FLOAT
615 float bmm150api_compensate_Y_float(
616 BMM150_S16 mdata_y, BMM150_U16 data_R);
617 #endif
618 BMM150_S16 bmm150api_compensate_Z(
619 BMM150_S16 mdata_z, BMM150_U16 data_R);
620 BMM150_S32 bmm150api_compensate_Z_s32(
621 BMM150_S16 mdata_z, BMM150_U16 data_R);
622 #ifdef ENABLE_FLOAT
623 float bmm150api_compensate_Z_float(
624 BMM150_S16 mdata_z, BMM150_U16 data_R);
625 #endif
626 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_raw_xyz(
627 struct bmm150api_mdata *mdata);
628 BMM150_RETURN_FUNCTION_TYPE bmm150api_init_trim_registers(void);
629 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_spi3(
630 unsigned char value);
631 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_powermode(
632 unsigned char *mode);
633 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_powermode(
634 unsigned char mode);
635 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_adv_selftest(
636 unsigned char adv_selftest);
637 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_adv_selftest(
638 unsigned char *adv_selftest);
639 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_datarate(
640 unsigned char data_rate);
641 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_datarate(
642 unsigned char *data_rate);
643 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_functional_state(
644 unsigned char functional_state);
645 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_functional_state(
646 unsigned char *functional_state);
647 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_selftest(
648 unsigned char selftest);
649 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_selftest(
650 unsigned char *selftest);
651 BMM150_RETURN_FUNCTION_TYPE bmm150api_perform_advanced_selftest(
652 BMM150_S16 *diff_z);
653 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_repetitions_XY(
654 unsigned char *no_repetitions_xy);
655 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_repetitions_XY(
656 unsigned char no_repetitions_xy);
657 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_repetitions_Z(
658 unsigned char *no_repetitions_z);
659 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_repetitions_Z(
660 unsigned char no_repetitions_z);
661 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_presetmode(unsigned char *mode);
662 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_presetmode(unsigned char mode);
663 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_control_measurement_x(
664 unsigned char enable_disable);
665 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_control_measurement_y(
666 unsigned char enable_disable);
667 BMM150_RETURN_FUNCTION_TYPE bmm150api_soft_reset(void);
668
669 static struct bmm150api *p_bmm150;
670
671 BMM150_RETURN_FUNCTION_TYPE bmm150api_init(struct bmm150api *bmm150)
672 {
673 BMM150_RETURN_FUNCTION_TYPE comres = 0;
674 unsigned char a_data_u8r[2];
675 p_bmm150 = bmm150;
676
677 p_bmm150->dev_addr = BMM150_I2C_ADDRESS;
678
679 /* set device from suspend into sleep mode */
680 bmm150api_set_powermode(BMM150_ON);
681
682 /* wait two millisecond for bmc to settle */
683 p_bmm150->delay_msec(BMM150_DELAY_SETTLING_TIME);
684
685 /*Read CHIP_ID and REv. info */
686 comres = p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
687 BMM150_CHIP_ID, a_data_u8r, 1);
688 p_bmm150->company_id = a_data_u8r[0];
689
690 /* Function to initialise trim values */
691 bmm150api_init_trim_registers();
692 bmm150api_set_presetmode(BMM150_PRESETMODE_REGULAR);
693 return comres;
694 }
695
696 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_presetmode(unsigned char mode)
697 {
698 BMM150_RETURN_FUNCTION_TYPE comres = 0;
699 switch (mode) {
700 case BMM150_PRESETMODE_LOWPOWER:
701 /* Set the data rate for Low Power mode */
702 comres = bmm150api_set_datarate(BMM150_LOWPOWER_DR);
703 /* Set the XY-repetitions number for Low Power mode */
704 comres |= bmm150api_set_repetitions_XY(BMM150_LOWPOWER_REPXY);
705 /* Set the Z-repetitions number for Low Power mode */
706 comres |= bmm150api_set_repetitions_Z(BMM150_LOWPOWER_REPZ);
707 break;
708 case BMM150_PRESETMODE_REGULAR:
709 /* Set the data rate for Regular mode */
710 comres = bmm150api_set_datarate(BMM150_REGULAR_DR);
711 /* Set the XY-repetitions number for Regular mode */
712 comres |= bmm150api_set_repetitions_XY(BMM150_REGULAR_REPXY);
713 /* Set the Z-repetitions number for Regular mode */
714 comres |= bmm150api_set_repetitions_Z(BMM150_REGULAR_REPZ);
715 break;
716 case BMM150_PRESETMODE_HIGHACCURACY:
717 /* Set the data rate for High Accuracy mode */
718 comres = bmm150api_set_datarate(BMM150_HIGHACCURACY_DR);
719 /* Set the XY-repetitions number for High Accuracy mode */
720 comres |= bmm150api_set_repetitions_XY(BMM150_HIGHACCURACY_REPXY);
721 /* Set the Z-repetitions number for High Accuracyr mode */
722 comres |= bmm150api_set_repetitions_Z(BMM150_HIGHACCURACY_REPZ);
723 break;
724 case BMM150_PRESETMODE_ENHANCED:
725 /* Set the data rate for Enhanced Accuracy mode */
726 comres = bmm150api_set_datarate(BMM150_ENHANCED_DR);
727 /* Set the XY-repetitions number for High Enhanced mode */
728 comres |= bmm150api_set_repetitions_XY(BMM150_ENHANCED_REPXY);
729 /* Set the Z-repetitions number for High Enhanced mode */
730 comres |= bmm150api_set_repetitions_Z(BMM150_ENHANCED_REPZ);
731 break;
732 default:
733 comres = E_BMM150_OUT_OF_RANGE;
734 break;
735 }
736 return comres;
737 }
738
739 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_functional_state(
740 unsigned char functional_state)
741 {
742 BMM150_RETURN_FUNCTION_TYPE comres = 0;
743 unsigned char v_data1_u8r;
744 if (p_bmm150 == BMM150_NULL) {
745 comres = E_BMM150_NULL_PTR;
746 } else {
747 switch (functional_state) {
748 case BMM150_NORMAL_MODE:
749 comres = bmm150api_get_powermode(&v_data1_u8r);
750 if (v_data1_u8r == BMM150_OFF) {
751 comres |= bmm150api_set_powermode(BMM150_ON);
752 p_bmm150->delay_msec(
753 BMM150_DELAY_SUSPEND_SLEEP);
754 }
755 {
756 comres |= p_bmm150->BMM150_BUS_READ_FUNC(
757 p_bmm150->dev_addr,
758 BMM150_CNTL_OPMODE__REG,
759 &v_data1_u8r, 1);
760 v_data1_u8r = BMM150_SET_BITSLICE(
761 v_data1_u8r,
762 BMM150_CNTL_OPMODE,
763 BMM150_NORMAL_MODE);
764 comres |= p_bmm150->BMM150_BUS_WRITE_FUNC(
765 p_bmm150->dev_addr,
766 BMM150_CNTL_OPMODE__REG,
767 &v_data1_u8r, 1);
768 }
769 break;
770 case BMM150_SUSPEND_MODE:
771 comres = bmm150api_set_powermode(BMM150_OFF);
772 break;
773 case BMM150_FORCED_MODE:
774 comres = bmm150api_get_powermode(&v_data1_u8r);
775 if (v_data1_u8r == BMM150_OFF) {
776 comres = bmm150api_set_powermode(BMM150_ON);
777 p_bmm150->delay_msec(
778 BMM150_DELAY_SUSPEND_SLEEP);
779 }
780 comres |= p_bmm150->BMM150_BUS_READ_FUNC(
781 p_bmm150->dev_addr,
782 BMM150_CNTL_OPMODE__REG,
783 &v_data1_u8r, 1);
784 v_data1_u8r = BMM150_SET_BITSLICE(
785 v_data1_u8r,
786 BMM150_CNTL_OPMODE, BMM150_ON);
787 comres |= p_bmm150->BMM150_BUS_WRITE_FUNC(
788 p_bmm150->dev_addr,
789 BMM150_CNTL_OPMODE__REG,
790 &v_data1_u8r, 1);
791 break;
792 case BMM150_SLEEP_MODE:
793 bmm150api_get_powermode(&v_data1_u8r);
794 if (v_data1_u8r == BMM150_OFF) {
795 comres = bmm150api_set_powermode(BMM150_ON);
796 p_bmm150->delay_msec(
797 BMM150_DELAY_SUSPEND_SLEEP);
798 }
799 comres |= p_bmm150->BMM150_BUS_READ_FUNC(
800 p_bmm150->dev_addr,
801 BMM150_CNTL_OPMODE__REG,
802 &v_data1_u8r, 1);
803 v_data1_u8r = BMM150_SET_BITSLICE(
804 v_data1_u8r,
805 BMM150_CNTL_OPMODE,
806 BMM150_SLEEP_MODE);
807 comres |= p_bmm150->BMM150_BUS_WRITE_FUNC(
808 p_bmm150->dev_addr,
809 BMM150_CNTL_OPMODE__REG,
810 &v_data1_u8r, 1);
811 break;
812 default:
813 comres = E_BMM150_OUT_OF_RANGE;
814 break;
815 }
816 }
817 return comres;
818 }
819
820 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_functional_state(
821 unsigned char *functional_state)
822 {
823 BMM150_RETURN_FUNCTION_TYPE comres = 0;
824 unsigned char v_data_u8r;
825 if (p_bmm150 == BMM150_NULL) {
826 comres = E_BMM150_NULL_PTR;
827 } else {
828 comres = p_bmm150->BMM150_BUS_READ_FUNC(
829 p_bmm150->dev_addr,
830 BMM150_CNTL_OPMODE__REG,
831 &v_data_u8r, 1);
832 *functional_state = BMM150_GET_BITSLICE(
833 v_data_u8r, BMM150_CNTL_OPMODE);
834 }
835 return comres;
836 }
837
838 BMM150_RETURN_FUNCTION_TYPE bmm150api_read_mdataXYZ(struct bmm150api_mdata *mdata)
839 {
840 BMM150_RETURN_FUNCTION_TYPE comres;
841
842 unsigned char a_data_u8r[8];
843
844 struct {
845 BMM150_S16 raw_dataX;
846 BMM150_S16 raw_dataY;
847 BMM150_S16 raw_dataZ;
848 BMM150_U16 raw_dataR;
849 } raw_dataXYZ;
850
851 if (p_bmm150 == BMM150_NULL) {
852 comres = E_BMM150_NULL_PTR;
853 } else {
854 comres = p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
855 BMM150_DATAX_LSB, a_data_u8r, 8);
856
857 /* Reading data for X axis */
858 a_data_u8r[0] = BMM150_GET_BITSLICE(a_data_u8r[0],
859 BMM150_DATAX_LSB_VALUEX);
860 raw_dataXYZ.raw_dataX = (BMM150_S16)((((BMM150_S16)
861 ((signed char)a_data_u8r[1])) <<
862 SHIFT_LEFT_5_POSITION) | a_data_u8r[0]);
863
864 /* Reading data for Y axis */
865 a_data_u8r[2] = BMM150_GET_BITSLICE(a_data_u8r[2],
866 BMM150_DATAY_LSB_VALUEY);
867 raw_dataXYZ.raw_dataY = (BMM150_S16)((((BMM150_S16)
868 ((signed char)a_data_u8r[3])) <<
869 SHIFT_LEFT_5_POSITION) | a_data_u8r[2]);
870
871 /* Reading data for Z axis */
872 a_data_u8r[4] = BMM150_GET_BITSLICE(a_data_u8r[4],
873 BMM150_DATAZ_LSB_VALUEZ);
874 raw_dataXYZ.raw_dataZ = (BMM150_S16)((((BMM150_S16)
875 ((signed char)a_data_u8r[5])) <<
876 SHIFT_LEFT_7_POSITION) | a_data_u8r[4]);
877
878 /* Reading data for Resistance*/
879 a_data_u8r[6] = BMM150_GET_BITSLICE(a_data_u8r[6],
880 BMM150_R_LSB_VALUE);
881 raw_dataXYZ.raw_dataR = (BMM150_U16)((((BMM150_U16)
882 a_data_u8r[7]) <<
883 SHIFT_LEFT_6_POSITION) | a_data_u8r[6]);
884
885 /* Compensation for X axis */
886 mdata->datax = bmm150api_compensate_X(raw_dataXYZ.raw_dataX,
887 raw_dataXYZ.raw_dataR);
888
889 /* Compensation for Y axis */
890 mdata->datay = bmm150api_compensate_Y(raw_dataXYZ.raw_dataY,
891 raw_dataXYZ.raw_dataR);
892
893 /* Compensation for Z axis */
894 mdata->dataz = bmm150api_compensate_Z(raw_dataXYZ.raw_dataZ,
895 raw_dataXYZ.raw_dataR);
896
897 /* Output raw resistance value */
898 mdata->resistance = raw_dataXYZ.raw_dataR;
899 }
900 return comres;
901 }
902
903 BMM150_RETURN_FUNCTION_TYPE bmm150api_read_mdataXYZ_s32(
904 struct bmm150api_mdata_s32 *mdata)
905 {
906 BMM150_RETURN_FUNCTION_TYPE comres;
907
908 unsigned char a_data_u8r[8];
909
910 struct {
911 BMM150_S16 raw_dataX;
912 BMM150_S16 raw_dataY;
913 BMM150_S16 raw_dataZ;
914 BMM150_U16 raw_dataR;
915 } raw_dataXYZ;
916
917 if (p_bmm150 == BMM150_NULL) {
918 comres = E_BMM150_NULL_PTR;
919 } else {
920 comres = p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
921 BMM150_DATAX_LSB, a_data_u8r, 8);
922
923 /* Reading data for X axis */
924 a_data_u8r[0] = BMM150_GET_BITSLICE(a_data_u8r[0],
925 BMM150_DATAX_LSB_VALUEX);
926 raw_dataXYZ.raw_dataX = (BMM150_S16)((((BMM150_S16)
927 ((signed char)a_data_u8r[1])) <<
928 SHIFT_LEFT_5_POSITION) | a_data_u8r[0]);
929
930 /* Reading data for Y axis */
931 a_data_u8r[2] = BMM150_GET_BITSLICE(a_data_u8r[2],
932 BMM150_DATAY_LSB_VALUEY);
933 raw_dataXYZ.raw_dataY = (BMM150_S16)((((BMM150_S16)
934 ((signed char)a_data_u8r[3])) <<
935 SHIFT_LEFT_5_POSITION) | a_data_u8r[2]);
936
937 /* Reading data for Z axis */
938 a_data_u8r[4] = BMM150_GET_BITSLICE(a_data_u8r[4],
939 BMM150_DATAZ_LSB_VALUEZ);
940 raw_dataXYZ.raw_dataZ = (BMM150_S16)((((BMM150_S16)
941 ((signed char)a_data_u8r[5])) <<
942 SHIFT_LEFT_7_POSITION) | a_data_u8r[4]);
943
944 /* Reading data for Resistance*/
945 a_data_u8r[6] = BMM150_GET_BITSLICE(a_data_u8r[6],
946 BMM150_R_LSB_VALUE);
947 raw_dataXYZ.raw_dataR = (BMM150_U16)((((BMM150_U16)
948 a_data_u8r[7]) <<
949 SHIFT_LEFT_6_POSITION) | a_data_u8r[6]);
950
951 /* Compensation for X axis */
952 mdata->datax = bmm150api_compensate_X_s32(raw_dataXYZ.raw_dataX,
953 raw_dataXYZ.raw_dataR);
954
955 /* Compensation for Y axis */
956 mdata->datay = bmm150api_compensate_Y_s32(raw_dataXYZ.raw_dataY,
957 raw_dataXYZ.raw_dataR);
958
959 /* Compensation for Z axis */
960 mdata->dataz = bmm150api_compensate_Z_s32(raw_dataXYZ.raw_dataZ,
961 raw_dataXYZ.raw_dataR);
962
963 /* Output raw resistance value */
964 mdata->resistance = raw_dataXYZ.raw_dataR;
965 }
966 return comres;
967 }
968
969 #ifdef ENABLE_FLOAT
970 BMM150_RETURN_FUNCTION_TYPE bmm150api_read_mdataXYZ_float(
971 struct bmm150api_mdata_float *mdata)
972 {
973 BMM150_RETURN_FUNCTION_TYPE comres;
974
975 unsigned char a_data_u8r[8];
976
977 struct {
978 BMM150_S16 raw_dataX;
979 BMM150_S16 raw_dataY;
980 BMM150_S16 raw_dataZ;
981 BMM150_U16 raw_dataR;
982 } raw_dataXYZ;
983
984 if (p_bmm150 == BMM150_NULL) {
985 comres = E_BMM150_NULL_PTR;
986 } else {
987 comres = p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
988 BMM150_DATAX_LSB, a_data_u8r, 8);
989
990 /* Reading data for X axis */
991 a_data_u8r[0] = BMM150_GET_BITSLICE(a_data_u8r[0],
992 BMM150_DATAX_LSB_VALUEX);
993 raw_dataXYZ.raw_dataX = (BMM150_S16)((((BMM150_S16)
994 ((signed char)a_data_u8r[1])) <<
995 SHIFT_LEFT_5_POSITION) | a_data_u8r[0]);
996
997 /* Reading data for Y axis */
998 a_data_u8r[2] = BMM150_GET_BITSLICE(a_data_u8r[2],
999 BMM150_DATAY_LSB_VALUEY);
1000 raw_dataXYZ.raw_dataY = (BMM150_S16)((((BMM150_S16)
1001 ((signed char)a_data_u8r[3])) <<
1002 SHIFT_LEFT_5_POSITION) | a_data_u8r[2]);
1003
1004 /* Reading data for Z axis */
1005 a_data_u8r[4] = BMM150_GET_BITSLICE(a_data_u8r[4],
1006 BMM150_DATAZ_LSB_VALUEZ);
1007 raw_dataXYZ.raw_dataZ = (BMM150_S16)((((BMM150_S16)
1008 ((signed char)a_data_u8r[5])) <<
1009 SHIFT_LEFT_7_POSITION) | a_data_u8r[4]);
1010
1011 /* Reading data for Resistance*/
1012 a_data_u8r[6] = BMM150_GET_BITSLICE(a_data_u8r[6],
1013 BMM150_R_LSB_VALUE);
1014 raw_dataXYZ.raw_dataR = (BMM150_U16)((((BMM150_U16)
1015 a_data_u8r[7]) <<
1016 SHIFT_LEFT_6_POSITION) | a_data_u8r[6]);
1017
1018 /* Compensation for X axis */
1019 mdata->datax = bmm150api_compensate_X_float(raw_dataXYZ.raw_dataX,
1020 raw_dataXYZ.raw_dataR);
1021
1022 /* Compensation for Y axis */
1023 mdata->datay = bmm150api_compensate_Y_float(raw_dataXYZ.raw_dataY,
1024 raw_dataXYZ.raw_dataR);
1025
1026 /* Compensation for Z axis */
1027 mdata->dataz = bmm150api_compensate_Z_float(raw_dataXYZ.raw_dataZ,
1028 raw_dataXYZ.raw_dataR);
1029
1030 /* Output raw resistance value */
1031 mdata->resistance = raw_dataXYZ.raw_dataR;
1032 }
1033 return comres;
1034 }
1035 #endif
1036
1037 BMM150_RETURN_FUNCTION_TYPE bmm150api_read_register(unsigned char addr,
1038 unsigned char *data, unsigned char len)
1039 {
1040 BMM150_RETURN_FUNCTION_TYPE comres;
1041 if (p_bmm150 == BMM150_NULL) {
1042 comres = E_BMM150_NULL_PTR;
1043 } else {
1044 comres += p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
1045 addr, data, len);
1046 }
1047 return comres;
1048 }
1049
1050 BMM150_RETURN_FUNCTION_TYPE bmm150api_write_register(unsigned char addr,
1051 unsigned char *data, unsigned char len)
1052 {
1053 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1054 if (p_bmm150 == BMM150_NULL) {
1055 comres = E_BMM150_NULL_PTR;
1056 } else {
1057 comres = p_bmm150->BMM150_BUS_WRITE_FUNC(p_bmm150->dev_addr,
1058 addr, data, len);
1059 }
1060 return comres;
1061 }
1062
1063 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_selftest(unsigned char selftest)
1064 {
1065 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1066 unsigned char v_data1_u8r;
1067 if (p_bmm150 == BMM150_NULL) {
1068 comres = E_BMM150_NULL_PTR;
1069 } else {
1070 comres = p_bmm150->BMM150_BUS_READ_FUNC(
1071 p_bmm150->dev_addr, BMM150_CNTL_S_TEST__REG,
1072 &v_data1_u8r, 1);
1073 v_data1_u8r = BMM150_SET_BITSLICE(
1074 v_data1_u8r, BMM150_CNTL_S_TEST, selftest);
1075 comres |= p_bmm150->BMM150_BUS_WRITE_FUNC(
1076 p_bmm150->dev_addr, BMM150_CNTL_S_TEST__REG,
1077 &v_data1_u8r, 1);
1078 }
1079 return comres;
1080 }
1081
1082 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_self_test_XYZ(
1083 unsigned char *self_testxyz)
1084 {
1085 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1086 unsigned char a_data_u8r[5], v_result_u8r = 0x00;
1087 if (p_bmm150 == BMM150_NULL) {
1088 comres = E_BMM150_NULL_PTR;
1089 } else {
1090 comres = p_bmm150->BMM150_BUS_READ_FUNC(
1091 p_bmm150->dev_addr, BMM150_DATAX_LSB_TESTX__REG,
1092 a_data_u8r, 5);
1093
1094 v_result_u8r = BMM150_GET_BITSLICE(a_data_u8r[4],
1095 BMM150_DATAZ_LSB_TESTZ);
1096
1097 v_result_u8r = (v_result_u8r << 1);
1098 v_result_u8r = (v_result_u8r | BMM150_GET_BITSLICE(
1099 a_data_u8r[2], BMM150_DATAY_LSB_TESTY));
1100
1101 v_result_u8r = (v_result_u8r << 1);
1102 v_result_u8r = (v_result_u8r | BMM150_GET_BITSLICE(
1103 a_data_u8r[0], BMM150_DATAX_LSB_TESTX));
1104
1105 *self_testxyz = v_result_u8r;
1106 }
1107 return comres;
1108 }
1109
1110 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_spi3(unsigned char value)
1111 {
1112 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1113 unsigned char v_data1_u8r;
1114 if (p_bmm150 == BMM150_NULL) {
1115 comres = E_BMM150_NULL_PTR;
1116 } else {
1117 comres = p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
1118 BMM150_POWER_CNTL_SPI3_EN__REG, &v_data1_u8r, 1);
1119 v_data1_u8r = BMM150_SET_BITSLICE(v_data1_u8r,
1120 BMM150_POWER_CNTL_SPI3_EN, value);
1121 comres |= p_bmm150->BMM150_BUS_WRITE_FUNC(p_bmm150->dev_addr,
1122 BMM150_POWER_CNTL_SPI3_EN__REG, &v_data1_u8r, 1);
1123 }
1124 return comres;
1125 }
1126
1127 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_datarate(unsigned char data_rate)
1128 {
1129 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1130 unsigned char v_data1_u8r;
1131 if (p_bmm150 == BMM150_NULL) {
1132 comres = E_BMM150_NULL_PTR;
1133 } else {
1134 comres = p_bmm150->BMM150_BUS_READ_FUNC(
1135 p_bmm150->dev_addr,
1136 BMM150_CNTL_DR__REG,
1137 &v_data1_u8r, 1);
1138 v_data1_u8r = BMM150_SET_BITSLICE(v_data1_u8r,
1139 BMM150_CNTL_DR, data_rate);
1140 comres |= p_bmm150->BMM150_BUS_WRITE_FUNC(
1141 p_bmm150->dev_addr,
1142 BMM150_CNTL_DR__REG,
1143 &v_data1_u8r, 1);
1144 }
1145 return comres;
1146 }
1147
1148 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_datarate(unsigned char *data_rate)
1149 {
1150 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1151 unsigned char v_data_u8r;
1152 if (p_bmm150 == BMM150_NULL) {
1153 comres = E_BMM150_NULL_PTR;
1154 } else {
1155 comres = p_bmm150->BMM150_BUS_READ_FUNC(
1156 p_bmm150->dev_addr,
1157 BMM150_CNTL_DR__REG,
1158 &v_data_u8r, 1);
1159 *data_rate = BMM150_GET_BITSLICE(v_data_u8r,
1160 BMM150_CNTL_DR);
1161 }
1162 return comres;
1163 }
1164
1165 BMM150_RETURN_FUNCTION_TYPE bmm150api_perform_advanced_selftest(
1166 BMM150_S16 *diff_z)
1167 {
1168 BMM150_RETURN_FUNCTION_TYPE comres;
1169 BMM150_S16 result_positive, result_negative;
1170 struct bmm150api_mdata_s32 mdata;
1171 if (p_bmm150 == BMM150_NULL) {
1172 comres = E_BMM150_NULL_PTR;
1173 } else {
1174 /* set sleep mode to prepare for forced measurement.
1175 * If sensor is off, this will turn it on
1176 * and respect needed delays. */
1177 comres = bmm150api_set_functional_state(BMM150_SLEEP_MODE);
1178
1179 /* set normal accuracy mode */
1180 comres |= bmm150api_set_repetitions_Z(BMM150_LOWPOWER_REPZ);
1181 /* 14 repetitions Z in normal accuracy mode */
1182
1183 /* disable X, Y channel */
1184 comres |= bmm150api_set_control_measurement_x(
1185 BMM150_CHANNEL_DISABLE);
1186 comres |= bmm150api_set_control_measurement_y(
1187 BMM150_CHANNEL_DISABLE);
1188
1189 /* enable positive current and force a
1190 * measurement with positive field */
1191 comres |= bmm150api_set_adv_selftest(
1192 BMM150_ADVANCED_SELFTEST_POSITIVE);
1193 comres |= bmm150api_set_functional_state(BMM150_FORCED_MODE);
1194 /* wait for measurement to complete */
1195 p_bmm150->delay_msec(4);
1196
1197 /* read result from positive field measurement */
1198 comres |= bmm150api_read_mdataXYZ_s32(&mdata);
1199 result_positive = mdata.dataz;
1200
1201 /* enable negative current and force a
1202 * measurement with negative field */
1203 comres |= bmm150api_set_adv_selftest(
1204 BMM150_ADVANCED_SELFTEST_NEGATIVE);
1205 comres |= bmm150api_set_functional_state(BMM150_FORCED_MODE);
1206 p_bmm150->delay_msec(4); /* wait for measurement to complete */
1207
1208 /* read result from negative field measurement */
1209 comres |= bmm150api_read_mdataXYZ_s32(&mdata);
1210 result_negative = mdata.dataz;
1211
1212 /* turn off self test current */
1213 comres |= bmm150api_set_adv_selftest(
1214 BMM150_ADVANCED_SELFTEST_OFF);
1215
1216 /* enable X, Y channel */
1217 comres |= bmm150api_set_control_measurement_x(
1218 BMM150_CHANNEL_ENABLE);
1219 comres |= bmm150api_set_control_measurement_y(
1220 BMM150_CHANNEL_ENABLE);
1221
1222 /* write out difference in positive and negative field.
1223 * This should be ~ 200 mT = 3200 LSB */
1224 *diff_z = (result_positive - result_negative);
1225 }
1226 return comres;
1227 }
1228
1229 BMM150_RETURN_FUNCTION_TYPE bmm150api_init_trim_registers(void)
1230 {
1231 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1232 unsigned char a_data_u8r[2];
1233 comres = p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
1234 BMM150_DIG_X1, (unsigned char *)&p_bmm150->dig_x1, 1);
1235 comres |= p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
1236 BMM150_DIG_Y1, (unsigned char *)&p_bmm150->dig_y1, 1);
1237 comres |= p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
1238 BMM150_DIG_X2, (unsigned char *)&p_bmm150->dig_x2, 1);
1239 comres |= p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
1240 BMM150_DIG_Y2, (unsigned char *)&p_bmm150->dig_y2, 1);
1241 comres |= p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
1242 BMM150_DIG_XY1, (unsigned char *)&p_bmm150->dig_xy1, 1);
1243 comres |= p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
1244 BMM150_DIG_XY2, (unsigned char *)&p_bmm150->dig_xy2, 1);
1245
1246 /* shorts can not be recasted into (unsigned char*)
1247 * due to possible mixup between trim data
1248 * arrangement and memory arrangement */
1249
1250 comres |= p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
1251 BMM150_DIG_Z1_LSB, a_data_u8r, 2);
1252 p_bmm150->dig_z1 = (BMM150_U16)((((BMM150_U16)((unsigned char)
1253 a_data_u8r[1])) <<
1254 SHIFT_LEFT_8_POSITION) | a_data_u8r[0]);
1255
1256 comres |= p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
1257 BMM150_DIG_Z2_LSB, a_data_u8r, 2);
1258 p_bmm150->dig_z2 = (BMM150_S16)((((BMM150_S16)(
1259 (signed char)a_data_u8r[1])) <<
1260 SHIFT_LEFT_8_POSITION) | a_data_u8r[0]);
1261
1262 comres |= p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
1263 BMM150_DIG_Z3_LSB, a_data_u8r, 2);
1264 p_bmm150->dig_z3 = (BMM150_S16)((((BMM150_S16)(
1265 (signed char)a_data_u8r[1])) <<
1266 SHIFT_LEFT_8_POSITION) | a_data_u8r[0]);
1267
1268 comres |= p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
1269 BMM150_DIG_Z4_LSB, a_data_u8r, 2);
1270 p_bmm150->dig_z4 = (BMM150_S16)((((BMM150_S16)(
1271 (signed char)a_data_u8r[1])) <<
1272 SHIFT_LEFT_8_POSITION) | a_data_u8r[0]);
1273
1274 comres |= p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
1275 BMM150_DIG_XYZ1_LSB, a_data_u8r, 2);
1276 a_data_u8r[1] = BMM150_GET_BITSLICE(a_data_u8r[1], BMM150_DIG_XYZ1_MSB);
1277 p_bmm150->dig_xyz1 = (BMM150_U16)((((BMM150_U16)
1278 ((unsigned char)a_data_u8r[1])) <<
1279 SHIFT_LEFT_8_POSITION) | a_data_u8r[0]);
1280 return comres;
1281 }
1282
1283 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_adv_selftest(unsigned char adv_selftest)
1284 {
1285 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1286 unsigned char v_data1_u8r;
1287 if (p_bmm150 == BMM150_NULL) {
1288 comres = E_BMM150_NULL_PTR;
1289 } else {
1290 switch (adv_selftest) {
1291 case BMM150_ADVANCED_SELFTEST_OFF:
1292 comres = p_bmm150->BMM150_BUS_READ_FUNC(
1293 p_bmm150->dev_addr,
1294 BMM150_CNTL_ADV_ST__REG,
1295 &v_data1_u8r, 1);
1296 v_data1_u8r = BMM150_SET_BITSLICE(
1297 v_data1_u8r,
1298 BMM150_CNTL_ADV_ST,
1299 BMM150_ADVANCED_SELFTEST_OFF);
1300 comres |= p_bmm150->BMM150_BUS_WRITE_FUNC(
1301 p_bmm150->dev_addr,
1302 BMM150_CNTL_ADV_ST__REG,
1303 &v_data1_u8r, 1);
1304 break;
1305 case BMM150_ADVANCED_SELFTEST_POSITIVE:
1306 comres = p_bmm150->BMM150_BUS_READ_FUNC(
1307 p_bmm150->dev_addr,
1308 BMM150_CNTL_ADV_ST__REG,
1309 &v_data1_u8r, 1);
1310 v_data1_u8r = BMM150_SET_BITSLICE(
1311 v_data1_u8r,
1312 BMM150_CNTL_ADV_ST,
1313 BMM150_ADVANCED_SELFTEST_POSITIVE);
1314 comres |= p_bmm150->BMM150_BUS_WRITE_FUNC(
1315 p_bmm150->dev_addr,
1316 BMM150_CNTL_ADV_ST__REG,
1317 &v_data1_u8r, 1);
1318 break;
1319 case BMM150_ADVANCED_SELFTEST_NEGATIVE:
1320 comres = p_bmm150->BMM150_BUS_READ_FUNC(
1321 p_bmm150->dev_addr,
1322 BMM150_CNTL_ADV_ST__REG,
1323 &v_data1_u8r, 1);
1324 v_data1_u8r = BMM150_SET_BITSLICE(
1325 v_data1_u8r,
1326 BMM150_CNTL_ADV_ST,
1327 BMM150_ADVANCED_SELFTEST_NEGATIVE);
1328 comres |= p_bmm150->BMM150_BUS_WRITE_FUNC(
1329 p_bmm150->dev_addr,
1330 BMM150_CNTL_ADV_ST__REG,
1331 &v_data1_u8r, 1);
1332 break;
1333 default:
1334 break;
1335 }
1336 }
1337 return comres;
1338 }
1339
1340 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_adv_selftest(unsigned char *adv_selftest)
1341 {
1342 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1343 unsigned char v_data_u8r;
1344 if (p_bmm150 == BMM150_NULL) {
1345 comres = E_BMM150_NULL_PTR;
1346 } else {
1347 comres = p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
1348 BMM150_CNTL_ADV_ST__REG, &v_data_u8r, 1);
1349 *adv_selftest = BMM150_GET_BITSLICE(v_data_u8r,
1350 BMM150_CNTL_ADV_ST);
1351 }
1352 return comres;
1353 }
1354
1355 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_presetmode(
1356 unsigned char *mode)
1357 {
1358 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1359 unsigned char data_rate = 0;
1360 unsigned char repetitionsxy = 0;
1361 unsigned char repetitionsz = 0;
1362
1363 /* Get the current data rate */
1364 comres = bmm150api_get_datarate(&data_rate);
1365 /* Get the preset number of XY Repetitions */
1366 comres |= bmm150api_get_repetitions_XY(&repetitionsxy);
1367 /* Get the preset number of Z Repetitions */
1368 comres |= bmm150api_get_repetitions_Z(&repetitionsz);
1369 if ((data_rate == BMM150_LOWPOWER_DR) && (
1370 repetitionsxy == BMM150_LOWPOWER_REPXY) && (
1371 repetitionsz == BMM150_LOWPOWER_REPZ)) {
1372 *mode = BMM150_PRESETMODE_LOWPOWER;
1373 } else {
1374 if ((data_rate == BMM150_REGULAR_DR) && (
1375 repetitionsxy == BMM150_REGULAR_REPXY) && (
1376 repetitionsz == BMM150_REGULAR_REPZ)) {
1377 *mode = BMM150_PRESETMODE_REGULAR;
1378 } else {
1379 if ((data_rate == BMM150_HIGHACCURACY_DR) && (
1380 repetitionsxy == BMM150_HIGHACCURACY_REPXY) && (
1381 repetitionsz == BMM150_HIGHACCURACY_REPZ)) {
1382 *mode = BMM150_PRESETMODE_HIGHACCURACY;
1383 } else {
1384 if ((data_rate == BMM150_ENHANCED_DR) && (
1385 repetitionsxy == BMM150_ENHANCED_REPXY) && (
1386 repetitionsz == BMM150_ENHANCED_REPZ)) {
1387 *mode = BMM150_PRESETMODE_ENHANCED;
1388 } else {
1389 *mode = E_BMM150_UNDEFINED_MODE;
1390 }
1391 }
1392 }
1393 }
1394 return comres;
1395 }
1396
1397 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_powermode(unsigned char *mode)
1398 {
1399 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1400 unsigned char v_data_u8r;
1401 if (p_bmm150 == BMM150_NULL) {
1402 comres = E_BMM150_NULL_PTR;
1403 } else {
1404 comres = p_bmm150->BMM150_BUS_READ_FUNC(
1405 p_bmm150->dev_addr,
1406 BMM150_POWER_CNTL_PCB__REG,
1407 &v_data_u8r, 1);
1408 *mode = BMM150_GET_BITSLICE(v_data_u8r,
1409 BMM150_POWER_CNTL_PCB);
1410 }
1411 return comres;
1412 }
1413
1414 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_powermode(unsigned char mode)
1415 {
1416 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1417 unsigned char v_data_u8r;
1418 if (p_bmm150 == BMM150_NULL) {
1419 comres = E_BMM150_NULL_PTR;
1420 } else {
1421 comres = p_bmm150->BMM150_BUS_READ_FUNC(
1422 p_bmm150->dev_addr,
1423 BMM150_POWER_CNTL_PCB__REG,
1424 &v_data_u8r, 1);
1425 v_data_u8r = BMM150_SET_BITSLICE(v_data_u8r,
1426 BMM150_POWER_CNTL_PCB, mode);
1427 comres |= p_bmm150->BMM150_BUS_WRITE_FUNC(
1428 p_bmm150->dev_addr,
1429 BMM150_POWER_CNTL_PCB__REG,
1430 &v_data_u8r, 1);
1431 }
1432 return comres;
1433 }
1434
1435 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_repetitions_XY(
1436 unsigned char *no_repetitions_xy)
1437 {
1438 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1439 unsigned char v_data_u8r;
1440 if (p_bmm150 == BMM150_NULL) {
1441 comres = E_BMM150_NULL_PTR;
1442 } else {
1443 comres = p_bmm150->BMM150_BUS_READ_FUNC(
1444 p_bmm150->dev_addr,
1445 BMM150_NO_REPETITIONS_XY,
1446 &v_data_u8r, 1);
1447 *no_repetitions_xy = v_data_u8r;
1448 }
1449 return comres;
1450 }
1451
1452 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_repetitions_XY(
1453 unsigned char no_repetitions_xy)
1454 {
1455 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1456 unsigned char v_data_u8r;
1457 if (p_bmm150 == BMM150_NULL) {
1458 comres = E_BMM150_NULL_PTR;
1459 } else {
1460 v_data_u8r = no_repetitions_xy;
1461 comres = p_bmm150->BMM150_BUS_WRITE_FUNC(
1462 p_bmm150->dev_addr,
1463 BMM150_NO_REPETITIONS_XY,
1464 &v_data_u8r, 1);
1465 }
1466 return comres;
1467 }
1468
1469 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_repetitions_Z(
1470 unsigned char *no_repetitions_z)
1471 {
1472 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1473 unsigned char v_data_u8r;
1474 if (p_bmm150 == BMM150_NULL) {
1475 comres = E_BMM150_NULL_PTR;
1476 } else {
1477 comres = p_bmm150->BMM150_BUS_READ_FUNC(
1478 p_bmm150->dev_addr,
1479 BMM150_NO_REPETITIONS_Z,
1480 &v_data_u8r, 1);
1481 *no_repetitions_z = v_data_u8r;
1482 }
1483 return comres;
1484 }
1485
1486 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_repetitions_Z(
1487 unsigned char no_repetitions_z)
1488 {
1489 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1490 unsigned char v_data_u8r;
1491 if (p_bmm150 == BMM150_NULL) {
1492 comres = E_BMM150_NULL_PTR;
1493 } else {
1494 v_data_u8r = no_repetitions_z;
1495 comres = p_bmm150->BMM150_BUS_WRITE_FUNC(p_bmm150->dev_addr,
1496 BMM150_NO_REPETITIONS_Z, &v_data_u8r, 1);
1497 }
1498 return comres;
1499 }
1500
1501 BMM150_S16 bmm150api_compensate_X(BMM150_S16 mdata_x, BMM150_U16 data_R)
1502 {
1503 BMM150_S16 inter_retval;
1504 if (mdata_x != BMM150_FLIP_OVERFLOW_ADCVAL /* no overflow */
1505 ) {
1506 inter_retval = ((BMM150_S16)(((BMM150_U16)
1507 ((((BMM150_S32)p_bmm150->dig_xyz1) << 14) /
1508 (data_R != 0 ? data_R : p_bmm150->dig_xyz1))) -
1509 ((BMM150_U16)0x4000)));
1510 inter_retval = ((BMM150_S16)((((BMM150_S32)mdata_x) *
1511 ((((((((BMM150_S32)p_bmm150->dig_xy2) *
1512 ((((BMM150_S32)inter_retval) *
1513 ((BMM150_S32)inter_retval)) >> 7)) +
1514 (((BMM150_S32)inter_retval) *
1515 ((BMM150_S32)(((BMM150_S16)p_bmm150->dig_xy1)
1516 << 7)))) >> 9) +
1517 ((BMM150_S32)0x100000)) *
1518 ((BMM150_S32)(((BMM150_S16)p_bmm150->dig_x2) +
1519 ((BMM150_S16)0xA0)))) >> 12)) >> 13)) +
1520 (((BMM150_S16)p_bmm150->dig_x1) << 3);
1521 } else {
1522 /* overflow */
1523 inter_retval = BMM150_OVERFLOW_OUTPUT;
1524 }
1525 return inter_retval;
1526 }
1527
1528 BMM150_S32 bmm150api_compensate_X_s32 (BMM150_S16 mdata_x, BMM150_U16 data_R)
1529 {
1530 BMM150_S32 retval;
1531
1532 retval = bmm150api_compensate_X(mdata_x, data_R);
1533 if (retval == (BMM150_S32)BMM150_OVERFLOW_OUTPUT)
1534 retval = BMM150_OVERFLOW_OUTPUT_S32;
1535 return retval;
1536 }
1537
1538 #ifdef ENABLE_FLOAT
1539 float bmm150api_compensate_X_float (BMM150_S16 mdata_x, BMM150_U16 data_R)
1540 {
1541 float inter_retval;
1542 if (mdata_x != BMM150_FLIP_OVERFLOW_ADCVAL /* no overflow */
1543 ) {
1544 if (data_R != 0) {
1545 inter_retval = ((((float)p_bmm150->dig_xyz1)*16384.0f
1546 /data_R)-16384.0f);
1547 } else {
1548 inter_retval = 0;
1549 }
1550 inter_retval = (((mdata_x * ((((((float)p_bmm150->dig_xy2) *
1551 (inter_retval*inter_retval / 268435456.0f) +
1552 inter_retval*((float)p_bmm150->dig_xy1)/16384.0f))
1553 + 256.0f) * (((float)p_bmm150->dig_x2) + 160.0f)))
1554 / 8192.0f) + (((float)p_bmm150->dig_x1) * 8.0f))/16.0f;
1555 } else {
1556 inter_retval = BMM150_OVERFLOW_OUTPUT_FLOAT;
1557 }
1558 return inter_retval;
1559 }
1560 #endif
1561
1562 BMM150_S16 bmm150api_compensate_Y(BMM150_S16 mdata_y, BMM150_U16 data_R)
1563 {
1564 BMM150_S16 inter_retval;
1565 if (mdata_y != BMM150_FLIP_OVERFLOW_ADCVAL /* no overflow */
1566 ) {
1567 inter_retval = ((BMM150_S16)(((BMM150_U16)(((
1568 (BMM150_S32)p_bmm150->dig_xyz1) << 14) /
1569 (data_R != 0 ?
1570 data_R : p_bmm150->dig_xyz1))) -
1571 ((BMM150_U16)0x4000)));
1572 inter_retval = ((BMM150_S16)((((BMM150_S32)mdata_y) *
1573 ((((((((BMM150_S32)
1574 p_bmm150->dig_xy2) *
1575 ((((BMM150_S32) inter_retval) *
1576 ((BMM150_S32)inter_retval)) >> 7)) +
1577 (((BMM150_S32)inter_retval) *
1578 ((BMM150_S32)(((BMM150_S16)
1579 p_bmm150->dig_xy1) << 7)))) >> 9) +
1580 ((BMM150_S32)0x100000)) *
1581 ((BMM150_S32)(((BMM150_S16)p_bmm150->dig_y2)
1582 + ((BMM150_S16)0xA0))))
1583 >> 12)) >> 13)) +
1584 (((BMM150_S16)p_bmm150->dig_y1) << 3);
1585 } else {
1586 /* overflow */
1587 inter_retval = BMM150_OVERFLOW_OUTPUT;
1588 }
1589 return inter_retval;
1590 }
1591
1592 BMM150_S32 bmm150api_compensate_Y_s32 (BMM150_S16 mdata_y, BMM150_U16 data_R)
1593 {
1594 BMM150_S32 retval;
1595
1596 retval = bmm150api_compensate_Y(mdata_y, data_R);
1597 if (retval == BMM150_OVERFLOW_OUTPUT)
1598 retval = BMM150_OVERFLOW_OUTPUT_S32;
1599 return retval;
1600 }
1601
1602 #ifdef ENABLE_FLOAT
1603 float bmm150api_compensate_Y_float(BMM150_S16 mdata_y, BMM150_U16 data_R)
1604 {
1605 float inter_retval;
1606 if (mdata_y != BMM150_FLIP_OVERFLOW_ADCVAL /* no overflow */
1607 ) {
1608 if (data_R != 0) {
1609 inter_retval = ((((float)p_bmm150->dig_xyz1)*16384.0f
1610 /data_R)-16384.0f);
1611 } else {
1612 inter_retval = 0;
1613 }
1614 inter_retval = (((mdata_y * ((((((float)p_bmm150->dig_xy2) *
1615 (inter_retval*inter_retval / 268435456.0f) +
1616 inter_retval * ((float)p_bmm150->dig_xy1)/16384.0f)) +
1617 256.0f) * (((float)p_bmm150->dig_y2) + 160.0f)))
1618 / 8192.0f) + (((float)p_bmm150->dig_y1) * 8.0f))/16.0f;
1619 } else {
1620 /* overflow, set output to 0.0f */
1621 inter_retval = BMM150_OVERFLOW_OUTPUT_FLOAT;
1622 }
1623 return inter_retval;
1624 }
1625 #endif
1626
1627 BMM150_S16 bmm150api_compensate_Z(BMM150_S16 mdata_z, BMM150_U16 data_R)
1628 {
1629 BMM150_S32 retval;
1630 if ((mdata_z != BMM150_HALL_OVERFLOW_ADCVAL) /* no overflow */
1631 ) {
1632 retval = (((((BMM150_S32)(mdata_z - p_bmm150->dig_z4)) << 15) -
1633 ((((BMM150_S32)p_bmm150->dig_z3) *
1634 ((BMM150_S32)(((BMM150_S16)data_R) -
1635 ((BMM150_S16)
1636 p_bmm150->dig_xyz1))))>>2)) /
1637 (p_bmm150->dig_z2 +
1638 ((BMM150_S16)(((((BMM150_S32)
1639 p_bmm150->dig_z1) *
1640 ((((BMM150_S16)data_R) << 1)))+
1641 (1<<15))>>16))));
1642 /* saturate result to +/- 2 mT */
1643 if (retval > BMM150_POSITIVE_SATURATION_Z) {
1644 retval = BMM150_POSITIVE_SATURATION_Z;
1645 } else {
1646 if (retval < BMM150_NEGATIVE_SATURATION_Z)
1647 retval = BMM150_NEGATIVE_SATURATION_Z;
1648 }
1649 } else {
1650 /* overflow */
1651 retval = BMM150_OVERFLOW_OUTPUT;
1652 }
1653 return (BMM150_S16)retval;
1654 }
1655
1656 BMM150_S32 bmm150api_compensate_Z_s32(BMM150_S16 mdata_z, BMM150_U16 data_R)
1657 {
1658 BMM150_S32 retval;
1659 if (mdata_z != BMM150_HALL_OVERFLOW_ADCVAL) {
1660 retval = (((((BMM150_S32)(mdata_z - p_bmm150->dig_z4)) << 15) -
1661 ((((BMM150_S32)p_bmm150->dig_z3) *
1662 ((BMM150_S32)(((BMM150_S16)data_R) -
1663 ((BMM150_S16)p_bmm150->dig_xyz1))))>>2)) /
1664 (p_bmm150->dig_z2 +
1665 ((BMM150_S16)(((((BMM150_S32)p_bmm150->dig_z1) *
1666 ((((BMM150_S16)data_R) << 1)))+(1<<15))>>16))));
1667 } else {
1668 retval = BMM150_OVERFLOW_OUTPUT_S32;
1669 }
1670 return retval;
1671 }
1672
1673 #ifdef ENABLE_FLOAT
1674 float bmm150api_compensate_Z_float (BMM150_S16 mdata_z, BMM150_U16 data_R)
1675 {
1676 float inter_retval;
1677 if (mdata_z != BMM150_HALL_OVERFLOW_ADCVAL /* no overflow */
1678 ) {
1679 inter_retval = ((((((float)mdata_z)-((float)p_bmm150->dig_z4))*
1680 131072.0f)-(((float)p_bmm150->dig_z3)*(((float)data_R)-
1681 ((float)p_bmm150->dig_xyz1))))/((((float)p_bmm150->dig_z2)+
1682 ((float)p_bmm150->dig_z1)*((float)data_R)/32768.0)*4.0))/16.0;
1683 } else {
1684 /* overflow, set output to 0.0f */
1685 inter_retval = BMM150_OVERFLOW_OUTPUT_FLOAT;
1686 }
1687 return inter_retval;
1688 }
1689 #endif
1690
1691 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_control_measurement_x(
1692 unsigned char enable_disable)
1693 {
1694 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1695 unsigned char v_data1_u8r;
1696 if (p_bmm150 == BMM150_NULL) {
1697 comres = E_BMM150_NULL_PTR;
1698 } else {
1699 comres = p_bmm150->BMM150_BUS_READ_FUNC(
1700 p_bmm150->dev_addr,
1701 BMM150_SENS_CNTL_CHANNELX__REG,
1702 &v_data1_u8r, 1);
1703 v_data1_u8r = BMM150_SET_BITSLICE(v_data1_u8r,
1704 BMM150_SENS_CNTL_CHANNELX,
1705 enable_disable);
1706 comres |= p_bmm150->BMM150_BUS_WRITE_FUNC(
1707 p_bmm150->dev_addr,
1708 BMM150_SENS_CNTL_CHANNELX__REG,
1709 &v_data1_u8r, 1);
1710 }
1711 return comres;
1712 }
1713
1714 BMM150_RETURN_FUNCTION_TYPE bmm150api_set_control_measurement_y(
1715 unsigned char enable_disable)
1716 {
1717 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1718 unsigned char v_data1_u8r;
1719 if (p_bmm150 == BMM150_NULL) {
1720 comres = E_BMM150_NULL_PTR;
1721 } else {
1722 comres = p_bmm150->BMM150_BUS_READ_FUNC(
1723 p_bmm150->dev_addr,
1724 BMM150_SENS_CNTL_CHANNELY__REG,
1725 &v_data1_u8r, 1);
1726 v_data1_u8r = BMM150_SET_BITSLICE(
1727 v_data1_u8r,
1728 BMM150_SENS_CNTL_CHANNELY,
1729 enable_disable);
1730 comres |= p_bmm150->BMM150_BUS_WRITE_FUNC(
1731 p_bmm150->dev_addr,
1732 BMM150_SENS_CNTL_CHANNELY__REG,
1733 &v_data1_u8r, 1);
1734 }
1735 return comres;
1736 }
1737
1738 BMM150_RETURN_FUNCTION_TYPE bmm150api_soft_reset(void)
1739 {
1740 BMM150_RETURN_FUNCTION_TYPE comres = 0;
1741 unsigned char v_data_u8r;
1742 if (p_bmm150 == BMM150_NULL) {
1743 comres = E_BMM150_NULL_PTR;
1744 } else {
1745 v_data_u8r = BMM150_ON;
1746
1747 comres = p_bmm150->BMM150_BUS_READ_FUNC(
1748 p_bmm150->dev_addr,
1749 BMM150_POWER_CNTL_SRST7__REG,
1750 &v_data_u8r, 1);
1751 v_data_u8r = BMM150_SET_BITSLICE(v_data_u8r,
1752 BMM150_POWER_CNTL_SRST7,
1753 BMM150_SOFT_RESET7_ON);
1754 comres |= p_bmm150->BMM150_BUS_WRITE_FUNC(
1755 p_bmm150->dev_addr,
1756 BMM150_POWER_CNTL_SRST7__REG, &v_data_u8r, 1);
1757
1758 comres |= p_bmm150->BMM150_BUS_READ_FUNC(
1759 p_bmm150->dev_addr,
1760 BMM150_POWER_CNTL_SRST1__REG,
1761 &v_data_u8r, 1);
1762 v_data_u8r = BMM150_SET_BITSLICE(v_data_u8r,
1763 BMM150_POWER_CNTL_SRST1,
1764 BMM150_SOFT_RESET1_ON);
1765 comres |= p_bmm150->BMM150_BUS_WRITE_FUNC(
1766 p_bmm150->dev_addr,
1767 BMM150_POWER_CNTL_SRST1__REG,
1768 &v_data_u8r, 1);
1769
1770 p_bmm150->delay_msec(BMM150_DELAY_SOFTRESET);
1771 }
1772 return comres;
1773 }
1774
1775 BMM150_RETURN_FUNCTION_TYPE bmm150api_get_raw_xyz(struct bmm150api_mdata *mdata)
1776 {
1777 BMM150_RETURN_FUNCTION_TYPE comres;
1778 unsigned char a_data_u8r[6];
1779 if (p_bmm150 == BMM150_NULL) {
1780 comres = E_BMM150_NULL_PTR;
1781 } else {
1782 comres = p_bmm150->BMM150_BUS_READ_FUNC(p_bmm150->dev_addr,
1783 BMM150_DATAX_LSB, a_data_u8r, 6);
1784
1785 a_data_u8r[0] = BMM150_GET_BITSLICE(a_data_u8r[0],
1786 BMM150_DATAX_LSB_VALUEX);
1787 mdata->datax = (BMM150_S16)((((BMM150_S16)
1788 ((signed char)a_data_u8r[1]))
1789 << SHIFT_LEFT_5_POSITION)
1790 | a_data_u8r[0]);
1791
1792 a_data_u8r[2] = BMM150_GET_BITSLICE(a_data_u8r[2],
1793 BMM150_DATAY_LSB_VALUEY);
1794 mdata->datay = (BMM150_S16)((((BMM150_S16)
1795 ((signed char)a_data_u8r[3]))
1796 << SHIFT_LEFT_5_POSITION)
1797 | a_data_u8r[2]);
1798
1799 a_data_u8r[4] = BMM150_GET_BITSLICE(a_data_u8r[4],
1800 BMM150_DATAZ_LSB_VALUEZ);
1801 mdata->dataz = (BMM150_S16)((((BMM150_S16)
1802 ((signed char)a_data_u8r[5]))
1803 << SHIFT_LEFT_7_POSITION)
1804 | a_data_u8r[4]);
1805 }
1806 return comres;
1807 }
1808
1809 /*----------------------------------------------------------------------------*/
1810 /* End of API Section */
1811 /*----------------------------------------------------------------------------*/
1812
1813 /*----------------------------------------------------------------------------*/
1814 #define DEBUG 1
1815 #define BMM150_DEV_NAME "bmm150"
1816 /*----------------------------------------------------------------------------*/
1817
1818 #define SENSOR_CHIP_ID_BMM (0x32)
1819
1820 #define BMM150_DEFAULT_DELAY 100
1821 #define BMM150_BUFSIZE 0x20
1822
1823 #define MSE_TAG "[Msensor] "
1824 #define MSE_FUN(f) printk(KERN_INFO MSE_TAG"%s\n", __FUNCTION__)
1825 #define MSE_ERR(fmt, args...) printk(KERN_ERR MSE_TAG"%s %d : "fmt, __FUNCTION__, __LINE__, ##args)
1826 #define MSE_LOG(fmt, args...) printk(KERN_INFO MSE_TAG fmt, ##args)
1827
1828 static struct i2c_client *this_client = NULL;
1829
1830 // calibration msensor and orientation data
1831 static int sensor_data[CALIBRATION_DATA_SIZE];
1832 #if defined(BMC150_M4G) || defined(BMC150_VRV)
1833 static int m4g_data[CALIBRATION_DATA_SIZE];
1834 #endif //BMC150_M4G || BMC150_VRV
1835 #if defined(BMC150_VLA)
1836 static int vla_data[CALIBRATION_DATA_SIZE];
1837 #endif //BMC150_VLA
1838
1839 #if defined(BMC150_VG)
1840 static int vg_data[CALIBRATION_DATA_SIZE];
1841 #endif //BMC150_VG
1842
1843 static struct mutex sensor_data_mutex;
1844 static DECLARE_WAIT_QUEUE_HEAD(uplink_event_flag_wq);
1845
1846 static int bmm150d_delay = BMM150_DEFAULT_DELAY;
1847 #ifdef BMC150_M4G
1848 static int m4g_delay = BMM150_DEFAULT_DELAY;
1849 #endif //BMC150_M4G
1850 #ifdef BMC150_VRV
1851 static int vrv_delay = BMM150_DEFAULT_DELAY;
1852 #endif //BMC150_VRV
1853 #ifdef BMC150_VLA
1854 static int vla_delay = BMM150_DEFAULT_DELAY;
1855 #endif //BMC150_VRV
1856
1857 #ifdef BMC150_VG
1858 static int vg_delay = BMM150_DEFAULT_DELAY;
1859 #endif //BMC150_VG
1860
1861 static atomic_t m_flag = ATOMIC_INIT(0);
1862 static atomic_t o_flag = ATOMIC_INIT(0);
1863 #ifdef BMC150_M4G
1864 static atomic_t g_flag = ATOMIC_INIT(0);
1865 #endif //BMC150_M4G
1866 #ifdef BMC150_VRV
1867 static atomic_t vrv_flag = ATOMIC_INIT(0);
1868 #endif //BMC150_VRV
1869 #ifdef BMC150_VLA
1870 static atomic_t vla_flag = ATOMIC_INIT(0);
1871 #endif //BMC150_VLA
1872 #ifdef BMC150_VG
1873 static atomic_t vg_flag = ATOMIC_INIT(0);
1874 #endif //BMC150_VG
1875
1876 #ifdef BMC150_BLOCK_DAEMON_ON_SUSPEND
1877 static atomic_t driver_suspend_flag = ATOMIC_INIT(0);
1878 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
1879
1880 static struct mutex uplink_event_flag_mutex;
1881 /* uplink event flag */
1882 static volatile u32 uplink_event_flag = 0;
1883 /* uplink event flag bitmap */
1884 enum {
1885 /* active */
1886 BMMDRV_ULEVT_FLAG_O_ACTIVE = 0x0001,
1887 BMMDRV_ULEVT_FLAG_M_ACTIVE = 0x0002,
1888 BMMDRV_ULEVT_FLAG_G_ACTIVE = 0x0004,
1889 BMMDRV_ULEVT_FLAG_VRV_ACTIVE = 0x0008,/* Virtual Rotation Vector */
1890 BMMDRV_ULEVT_FLAG_FLIP_ACTIVE = 0x0010,
1891 BMMDRV_ULEVT_FLAG_VLA_ACTIVE = 0x0020,/* Virtual Linear Accelerometer */
1892 BMMDRV_ULEVT_FLAG_VG_ACTIVE = 0x0040,/* Virtual Gravity */
1893
1894 /* delay */
1895 BMMDRV_ULEVT_FLAG_O_DELAY = 0x0100,
1896 BMMDRV_ULEVT_FLAG_M_DELAY = 0x0200,
1897 BMMDRV_ULEVT_FLAG_G_DELAY = 0x0400,
1898 BMMDRV_ULEVT_FLAG_VRV_DELAY = 0x0800,
1899 BMMDRV_ULEVT_FLAG_FLIP_DELAY = 0x1000,
1900 BMMDRV_ULEVT_FLAG_VLA_DELAY = 0x2000,
1901 BMMDRV_ULEVT_FLAG_VG_DELAY = 0x4000,
1902
1903 /* all */
1904 BMMDRV_ULEVT_FLAG_ALL = 0xffff
1905 };
1906
1907 /*----------------------------------------------------------------------------*/
1908 /*----------------------------------------------------------------------------*/
1909 static const struct i2c_device_id bmm150_i2c_id[] = {{BMM150_DEV_NAME,0},{}};
1910 static struct i2c_board_info __initdata bmm150_i2c_info = {I2C_BOARD_INFO(BMM150_DEV_NAME, BMM150_I2C_ADDR)};
1911
1912 /*----------------------------------------------------------------------------*/
1913
1914 typedef enum {
1915 MMC_FUN_DEBUG = 0x01,
1916 MMC_DATA_DEBUG = 0X02,
1917 MMC_HWM_DEBUG = 0X04,
1918 MMC_CTR_DEBUG = 0X08,
1919 MMC_I2C_DEBUG = 0x10,
1920 } MMC_TRC;
1921
1922 /*----------------------------------------------------------------------------*/
1923 struct bmm150_i2c_data {
1924 struct i2c_client *client;
1925 struct mag_hw *hw;
1926 atomic_t layout;
1927 atomic_t trace;
1928 struct hwmsen_convert cvt;
1929
1930 struct bmm150api device;
1931
1932 u8 op_mode;
1933 u8 odr;
1934 u8 rept_xy;
1935 u8 rept_z;
1936 s16 result_test;
1937
1938 #if defined(CONFIG_HAS_EARLYSUSPEND)
1939 struct early_suspend early_drv;
1940 #endif
1941 };
1942 /*----------------------------------------------------------------------------*/
1943 static void bmm150_restore_hw_cfg(struct i2c_client *client);
1944 static int bmm150_probe(struct platform_device *pdev);
1945 static int bmm150_remove(struct platform_device *pdev);
1946 /*----------------------------------------------------------------------------*/
1947 static void bmm150_power(struct mag_hw *hw, unsigned int on)
1948 {
1949 static unsigned int power_on = 0;
1950
1951 if(hw->power_id != POWER_NONE_MACRO)
1952 {
1953 MSE_LOG("power %s\n", on ? "on" : "off");
1954 if(power_on == on)
1955 {
1956 MSE_LOG("ignore power control: %d\n", on);
1957 }
1958 else if(on)
1959 {
1960 if(!hwPowerOn(hw->power_id, hw->power_vol, "bmm150"))
1961 {
1962 MSE_ERR( "power on fails!!\n");
1963 }
1964 }
1965 else
1966 {
1967 if(!hwPowerDown(hw->power_id, "bmm150"))
1968 {
1969 MSE_ERR( "power off fail!!\n");
1970 }
1971 }
1972 }
1973 power_on = on;
1974 }
1975
1976 // Daemon application save the data
1977 static int ECS_SaveData(int buf[CALIBRATION_DATA_SIZE])
1978 {
1979 #if DEBUG
1980 struct bmm150_i2c_data *data = i2c_get_clientdata(this_client);
1981 #endif
1982
1983 mutex_lock(&sensor_data_mutex);
1984 switch (buf[0])
1985 {
1986 case 2: /* SENSOR_HANDLE_MAGNETIC_FIELD */
1987 memcpy(sensor_data+4, buf+1, 4*sizeof(int));
1988 break;
1989 case 3: /* SENSOR_HANDLE_ORIENTATION */
1990 memcpy(sensor_data+8, buf+1, 4*sizeof(int));
1991 break;
1992 #ifdef BMC150_M4G
1993 case 4: /* SENSOR_HANDLE_GYROSCOPE */
1994 memcpy(m4g_data, buf+1, 4*sizeof(int));
1995 break;
1996 #endif //BMC150_M4G
1997 #ifdef BMC150_VRV
1998 case 11: /* SENSOR_HANDLE_ROTATION_VECTOR */
1999 memcpy(m4g_data+4, buf+1, 4*sizeof(int));
2000 break;
2001 #endif //BMC150_VRV
2002 #ifdef BMC150_VLA
2003 case 10: /* SENSOR_HANDLE_LINEAR_ACCELERATION */
2004 memcpy(vla_data, buf+1, 4*sizeof(int));
2005 break;
2006 #endif //BMC150_VLA
2007 #ifdef BMC150_VG
2008 case 9: /* SENSOR_HANDLE_GRAVITY */
2009 memcpy(vg_data, buf+1, 4*sizeof(int));
2010 break;
2011 #endif //BMC150_VG
2012 default:
2013 break;
2014 }
2015 mutex_unlock(&sensor_data_mutex);
2016
2017 #if DEBUG
2018 if(atomic_read(&data->trace) & MMC_HWM_DEBUG)
2019 {
2020 MSE_LOG("Get daemon data: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d!\n",
2021 sensor_data[0],sensor_data[1],sensor_data[2],sensor_data[3],
2022 sensor_data[4],sensor_data[5],sensor_data[6],sensor_data[7],
2023 sensor_data[8],sensor_data[9],sensor_data[10],sensor_data[11]);
2024 #if defined(BMC150_M4G) || defined(BMC150_VRV)
2025 MSE_LOG("Get m4g data: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d!\n",
2026 m4g_data[0],m4g_data[1],m4g_data[2],m4g_data[3],
2027 m4g_data[4],m4g_data[5],m4g_data[6],m4g_data[7],
2028 m4g_data[8],m4g_data[9],m4g_data[10],m4g_data[11]);
2029 #endif //BMC150_M4G || BMC150_VRV
2030 #if defined(BMC150_VLA)
2031 MSE_LOG("Get vla data: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d!\n",
2032 vla_data[0],vla_data[1],vla_data[2],vla_data[3],
2033 vla_data[4],vla_data[5],vla_data[6],vla_data[7],
2034 vla_data[8],vla_data[9],vla_data[10],vla_data[11]);
2035 #endif //BMC150_VLA
2036
2037 #if defined(BMC150_VG)
2038 MSE_LOG("Get vg data: %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d!\n",
2039 vg_data[0],vg_data[1],vg_data[2],vg_data[3],
2040 vg_data[4],vg_data[5],vg_data[6],vg_data[7],
2041 vg_data[8],vg_data[9],vg_data[10],vg_data[11]);
2042 #endif //BMC150_VG
2043 }
2044 #endif
2045
2046 return 0;
2047 }
2048 /*----------------------------------------------------------------------------*/
2049 static int ECS_GetRawData(int data[3])
2050 {
2051 struct bmm150api_mdata_s32 mdata;
2052 struct bmm150_i2c_data *obj = i2c_get_clientdata(this_client);
2053
2054 u8 databuf[2] = {BMM150_CONTROL, 0x02};
2055
2056 bmm150api_read_mdataXYZ_s32(&mdata);
2057 //data in uT
2058 data[0] = mdata.datax/16;
2059 data[1] = mdata.datay/16;
2060 data[2] = mdata.dataz/16;
2061
2062 /* measure magnetic field for next sample */
2063 if (obj->op_mode == BMM150_SUSPEND_MODE)
2064 {
2065 /* power on firstly */
2066 bmm150api_set_powermode(BMM150_ON);
2067 }
2068 /* special treat of forced mode
2069 * for optimization */
2070 i2c_master_send(this_client, databuf, 2);
2071 obj->op_mode = BMM150_SLEEP_MODE;
2072
2073 return 0;
2074 }
2075 /*----------------------------------------------------------------------------*/
2076 static int bmm150_ReadChipInfo(char *buf, int bufsize)
2077 {
2078 if((!buf)||(bufsize <= BMM150_BUFSIZE -1))
2079 {
2080 return -1;
2081 }
2082 if(!this_client)
2083 {
2084 *buf = 0;
2085 return -2;
2086 }
2087
2088 sprintf(buf, "BMM150 Chip");
2089 return 0;
2090 }
2091 /*----------------------------------------------------------------------------*/
2092 static void bmm150_SetPowerMode(struct i2c_client *client, bool enable)
2093 {
2094 struct bmm150_i2c_data *obj = i2c_get_clientdata(client);
2095
2096 u8 power_mode;
2097
2098 if (enable == FALSE)
2099 {
2100 if (bmm150api_set_functional_state(BMM150_SUSPEND_MODE) != 0)
2101 {
2102 MSE_ERR("fail to suspend sensor");
2103 return;
2104 }
2105 obj->op_mode = BMM150_SUSPEND_MODE;
2106 }
2107 else
2108 {
2109 if (obj->op_mode == BMM150_SUSPEND_MODE)
2110 {
2111 obj->op_mode = BMM150_SLEEP_MODE;
2112 }
2113 bmm150_restore_hw_cfg(client);
2114 }
2115 }
2116
2117 /*----------------------------------------------------------------------------*/
2118 /* Driver Attributes Functions Section */
2119 /*----------------------------------------------------------------------------*/
2120 static ssize_t show_chipinfo_value(struct device_driver *ddri, char *buf)
2121 {
2122 char strbuf[BMM150_BUFSIZE];
2123 bmm150_ReadChipInfo(strbuf, BMM150_BUFSIZE);
2124 return sprintf(buf, "%s\n", strbuf);
2125 }
2126 /*----------------------------------------------------------------------------*/
2127 static ssize_t show_sensordata_value(struct device_driver *ddri, char *buf)
2128 {
2129 int sensordata[3];
2130 char strbuf[BMM150_BUFSIZE];
2131
2132 ECS_GetRawData(sensordata);
2133 sprintf(strbuf, "%d %d %d\n", sensordata[0],sensordata[1],sensordata[2]);
2134 return sprintf(buf, "%s\n", strbuf);
2135 }
2136 /*----------------------------------------------------------------------------*/
2137 static ssize_t show_posturedata_value(struct device_driver *ddri, char *buf)
2138 {
2139 int tmp[3];
2140 char strbuf[BMM150_BUFSIZE];
2141 tmp[0] = sensor_data[0] * CONVERT_O / CONVERT_O_DIV;
2142 tmp[1] = sensor_data[1] * CONVERT_O / CONVERT_O_DIV;
2143 tmp[2] = sensor_data[2] * CONVERT_O / CONVERT_O_DIV;
2144 sprintf(strbuf, "%d, %d, %d\n", tmp[0],tmp[1], tmp[2]);
2145
2146 return sprintf(buf, "%s\n", strbuf);;
2147 }
2148
2149 /*----------------------------------------------------------------------------*/
2150 static ssize_t show_layout_value(struct device_driver *ddri, char *buf)
2151 {
2152 struct bmm150_i2c_data *data = i2c_get_clientdata(this_client);
2153
2154 return sprintf(buf, "(%d, %d)\n[%+2d %+2d %+2d]\n[%+2d %+2d %+2d]\n",
2155 data->hw->direction,atomic_read(&data->layout), data->cvt.sign[0], data->cvt.sign[1],
2156 data->cvt.sign[2],data->cvt.map[0], data->cvt.map[1], data->cvt.map[2]);
2157 }
2158 /*----------------------------------------------------------------------------*/
2159 static ssize_t store_layout_value(struct device_driver *ddri, char *buf, size_t count)
2160 {
2161 struct i2c_client *client = this_client;
2162 struct bmm150_i2c_data *data = i2c_get_clientdata(this_client);
2163
2164 int layout = 0;
2165
2166 if(1 == sscanf(buf, "%d", &layout))
2167 {
2168 atomic_set(&data->layout, layout);
2169 if(!hwmsen_get_convert(layout, &data->cvt))
2170 {
2171 MSE_ERR( "HWMSEN_GET_CONVERT function error!\r\n");
2172 }
2173 else if(!hwmsen_get_convert(data->hw->direction, &data->cvt))
2174 {
2175 MSE_ERR( "invalid layout: %d, restore to %d\n", layout, data->hw->direction);
2176 }
2177 else
2178 {
2179 MSE_ERR( "invalid layout: (%d, %d)\n", layout, data->hw->direction);
2180 hwmsen_get_convert(0, &data->cvt);
2181 }
2182 }
2183 else
2184 {
2185 MSE_ERR( "invalid format = '%s'\n", buf);
2186 }
2187
2188 return count;
2189 }
2190 /*----------------------------------------------------------------------------*/
2191 static ssize_t show_status_value(struct device_driver *ddri, char *buf)
2192 {
2193 struct bmm150_i2c_data *data = i2c_get_clientdata(this_client);
2194
2195 ssize_t len = 0;
2196
2197 if(data->hw)
2198 {
2199 len += snprintf(buf+len, PAGE_SIZE-len, "CUST: %d %d (%d %d)\n",
2200 data->hw->i2c_num, data->hw->direction, data->hw->power_id, data->hw->power_vol);
2201 }
2202 else
2203 {
2204 len += snprintf(buf+len, PAGE_SIZE-len, "CUST: NULL\n");
2205 }
2206
2207 return len;
2208 }
2209 /*----------------------------------------------------------------------------*/
2210 static ssize_t show_trace_value(struct device_driver *ddri, char *buf)
2211 {
2212 ssize_t res;
2213 struct bmm150_i2c_data *obj = i2c_get_clientdata(this_client);
2214
2215 if(NULL == obj)
2216 {
2217 MSE_ERR( "bmm150_i2c_data is null!!\n");
2218 return 0;
2219 }
2220
2221 res = snprintf(buf, PAGE_SIZE, "0x%04X\n", atomic_read(&obj->trace));
2222 return res;
2223 }
2224 /*----------------------------------------------------------------------------*/
2225 static ssize_t store_trace_value(struct device_driver *ddri, char *buf, size_t count)
2226 {
2227 struct bmm150_i2c_data *obj = i2c_get_clientdata(this_client);
2228
2229 int trace;
2230 if(NULL == obj)
2231 {
2232 MSE_ERR( "bmm150_i2c_data is null!!\n");
2233 return 0;
2234 }
2235
2236 if(1 == sscanf(buf, "0x%x", &trace))
2237 {
2238 atomic_set(&obj->trace, trace);
2239 }
2240 else
2241 {
2242 MSE_ERR( "invalid content: '%s', length = %d\n", buf, count);
2243 }
2244
2245 return count;
2246 }
2247 /*----------------------------------------------------------------------------*/
2248 #define BMM150_AXIS_X 0
2249 #define BMM150_AXIS_Y 1
2250 #define BMM150_AXIS_Z 2
2251 static ssize_t show_cpsdata_value(struct device_driver *ddri, char *buf)
2252 {
2253 struct bmm150_i2c_data *obj = i2c_get_clientdata(this_client);
2254
2255 struct bmm150api_mdata_s32 mdata;
2256 s32 mag[3];
2257
2258 bmm150api_read_mdataXYZ_s32(&mdata);
2259
2260 /*remap coordinate*/
2261 mag[obj->cvt.map[BMM150_AXIS_X]] = obj->cvt.sign[BMM150_AXIS_X]*mdata.datax;
2262 mag[obj->cvt.map[BMM150_AXIS_Y]] = obj->cvt.sign[BMM150_AXIS_Y]*mdata.datay;
2263 mag[obj->cvt.map[BMM150_AXIS_Z]] = obj->cvt.sign[BMM150_AXIS_Z]*mdata.dataz;
2264
2265 return sprintf(buf, "%d %d %d\n", mag[BMM150_AXIS_X], mag[BMM150_AXIS_Y], mag[BMM150_AXIS_Z]);
2266 }
2267 /*----------------------------------------------------------------------------*/
2268 static ssize_t show_cpsopmode_value(struct device_driver *ddri, char *buf)
2269 {
2270 struct bmm150_i2c_data *obj = i2c_get_clientdata(this_client);
2271
2272 u8 op_mode = 0xff;
2273 u8 power_mode;
2274
2275 bmm150api_get_powermode(&power_mode);
2276 if (power_mode)
2277 {
2278 bmm150api_get_functional_state(&op_mode);
2279 }
2280 else
2281 {
2282 op_mode = BMM150_SUSPEND_MODE;
2283 }
2284
2285 MSE_LOG("op_mode: %d", op_mode);
2286
2287 return sprintf(buf, "%d\n", op_mode);
2288 }
2289
2290 /*----------------------------------------------------------------------------*/
2291 static ssize_t store_cpsopmode_value(struct device_driver *ddri, char *buf, size_t count)
2292 {
2293 struct bmm150_i2c_data *obj = i2c_get_clientdata(this_client);
2294 long op_mode = -1;
2295
2296 strict_strtoul(buf, 10, &op_mode);
2297 if ((unsigned char)op_mode > 3)
2298 {
2299 return -EINVAL;
2300 }
2301 if (op_mode == obj->op_mode)
2302 {
2303 /* don't return error here */
2304 return count;
2305 }
2306
2307 if (BMM150_FORCED_MODE == op_mode)
2308 {
2309 u8 databuf[2] = {BMM150_CONTROL, 0x02};
2310
2311 if (obj->op_mode == BMM150_SUSPEND_MODE)
2312 {
2313 /* power on firstly */
2314 bmm150api_set_powermode(BMM150_ON);
2315 }
2316 /* special treat of forced mode
2317 * for optimization */
2318 i2c_master_send(this_client, databuf, 2);
2319 obj->op_mode = BMM150_SLEEP_MODE;
2320 }
2321 else
2322 {
2323 bmm150api_set_functional_state((unsigned char)op_mode);
2324 obj->op_mode = op_mode;
2325 }
2326
2327 return count;
2328 }
2329 /*----------------------------------------------------------------------------*/
2330 static ssize_t show_cpsreptxy_value(struct device_driver *ddri, char *buf)
2331 {
2332 unsigned char data = 0;
2333 u8 power_mode;
2334 int err;
2335
2336 bmm150api_get_powermode(&power_mode);
2337 if (power_mode)
2338 {
2339 err = bmm150api_get_repetitions_XY(&data);
2340 }
2341 else
2342 {
2343 err = -EIO;
2344 }
2345
2346 if (err)
2347 return err;
2348
2349 return sprintf(buf, "%d\n", data);
2350 }
2351 /*----------------------------------------------------------------------------*/
2352 static ssize_t store_cpsreptxy_value(struct device_driver *ddri, char *buf, size_t count)
2353 {
2354 struct bmm150_i2c_data *obj = i2c_get_clientdata(this_client);
2355
2356 unsigned long tmp = 0;
2357 int err;
2358 u8 data;
2359 u8 power_mode;
2360
2361 err = strict_strtoul(buf, 10, &tmp);
2362 if (err)
2363 return err;
2364
2365 if (tmp > 255)
2366 return -EINVAL;
2367
2368 data = (unsigned char)tmp;
2369
2370 bmm150api_get_powermode(&power_mode);
2371 if (power_mode)
2372 {
2373 err = bmm150api_set_repetitions_XY(data);
2374 if (!err)
2375 {
2376 //mdelay(BMM_I2C_WRITE_DELAY_TIME);
2377 obj->rept_xy = data;
2378 }
2379 }
2380 else
2381 {
2382 err = -EIO;
2383 }
2384
2385 if (err)
2386 return err;
2387
2388 return count;
2389 }
2390 /*----------------------------------------------------------------------------*/
2391 static ssize_t show_cpsreptz_value(struct device_driver *ddri, char *buf)
2392 {
2393 unsigned char data = 0;
2394 u8 power_mode;
2395 int err;
2396
2397 bmm150api_get_powermode(&power_mode);
2398 if (power_mode)
2399 {
2400 err = bmm150api_get_repetitions_Z(&data);
2401 }
2402 else
2403 {
2404 err = -EIO;
2405 }
2406
2407 if (err)
2408 return err;
2409
2410 return sprintf(buf, "%d\n", data);
2411 }
2412 /*----------------------------------------------------------------------------*/
2413 static ssize_t store_cpsreptz_value(struct device_driver *ddri, char *buf, size_t count)
2414 {
2415 struct bmm150_i2c_data *obj = i2c_get_clientdata(this_client);
2416 unsigned long tmp = 0;
2417 int err;
2418 u8 data;
2419 u8 power_mode;
2420
2421 err = strict_strtoul(buf, 10, &tmp);
2422 if (err)
2423 return err;
2424
2425 if (tmp > 255)
2426 return -EINVAL;
2427
2428 data = (unsigned char)tmp;
2429
2430 bmm150api_get_powermode(&power_mode);
2431 if (power_mode)
2432 {
2433 err = bmm150api_set_repetitions_Z(data);
2434 if (!err)
2435 {
2436 //mdelay(BMM_I2C_WRITE_DELAY_TIME);
2437 obj->rept_z = data;
2438 }
2439 }
2440 else
2441 {
2442 err = -EIO;
2443 }
2444
2445 if (err)
2446 return err;
2447
2448 return count;
2449 }
2450
2451 static ssize_t show_test_value(struct device_driver *ddri, char *buf)
2452 {
2453 struct bmm150_i2c_data *client_data = i2c_get_clientdata(this_client);
2454 int err;
2455
2456 err = sprintf(buf, "%d\n", client_data->result_test);
2457 return err;
2458 }
2459
2460 static ssize_t store_test_value(struct device_driver *ddri, char *buf, size_t count)
2461 {
2462 unsigned long data;
2463 int err;
2464 struct bmm150_i2c_data *client_data = i2c_get_clientdata(this_client);
2465 u8 dummy;
2466
2467 err = strict_strtoul(buf, 10, &data);
2468 if (err)
2469 return err;
2470
2471 /* the following code assumes the work thread is not running */
2472 if (1 == data) {
2473 /* self test */
2474 err = bmm150api_set_functional_state(BMM150_SLEEP_MODE);
2475 mdelay(3);
2476 err = bmm150api_set_selftest(1);
2477 mdelay(3);
2478 err = bmm150api_get_self_test_XYZ(&dummy);
2479 client_data->result_test = dummy;
2480 } else if (2 == data) {
2481 /* advanced self test */
2482 err = bmm150api_perform_advanced_selftest(&client_data->result_test);
2483 } else {
2484 err = -EINVAL;
2485 }
2486
2487 if (!err) {
2488 bmm150api_soft_reset();
2489 mdelay(1);
2490 bmm150_restore_hw_cfg(this_client);
2491 }
2492
2493 if (err)
2494 count = -1;
2495
2496 return count;
2497 }
2498
2499 /*----------------------------------------------------------------------------*/
2500 static ssize_t show_daemon_name(struct device_driver *ddri, char *buf)
2501 {
2502 char strbuf[256];
2503 sprintf(strbuf, "bmc150d");
2504 return sprintf(buf, "%s", strbuf);
2505 }
2506
2507 /*----------------------------------------------------------------------------*/
2508 static DRIVER_ATTR(daemon, S_IRUGO, show_daemon_name, NULL);
2509 static DRIVER_ATTR(chipinfo, S_IRUGO, show_chipinfo_value, NULL);
2510 static DRIVER_ATTR(sensordata, S_IRUGO, show_sensordata_value, NULL);
2511 static DRIVER_ATTR(posturedata, S_IRUGO, show_posturedata_value, NULL);
2512 static DRIVER_ATTR(layout, S_IRUGO | S_IWUSR, show_layout_value, store_layout_value);
2513 static DRIVER_ATTR(status, S_IRUGO, show_status_value, NULL);
2514 static DRIVER_ATTR(trace, S_IRUGO | S_IWUSR, show_trace_value, store_trace_value);
2515 static DRIVER_ATTR(cpsdata, S_IWUSR | S_IRUGO, show_cpsdata_value, NULL);
2516 static DRIVER_ATTR(cpsopmode, S_IRUGO | S_IWUSR, show_cpsopmode_value, store_cpsopmode_value);
2517 static DRIVER_ATTR(cpsreptxy, S_IRUGO | S_IWUSR, show_cpsreptxy_value, store_cpsreptxy_value);
2518 static DRIVER_ATTR(cpsreptz, S_IRUGO | S_IWUSR, show_cpsreptz_value, store_cpsreptz_value);
2519 static DRIVER_ATTR(test, S_IRUGO | S_IWUSR, show_test_value, store_test_value);
2520 /*----------------------------------------------------------------------------*/
2521 static struct driver_attribute *bmm150_attr_list[] = {
2522 &driver_attr_daemon,
2523 &driver_attr_chipinfo,
2524 &driver_attr_sensordata,
2525 &driver_attr_posturedata,
2526 &driver_attr_layout,
2527 &driver_attr_status,
2528 &driver_attr_trace,
2529 &driver_attr_cpsdata,
2530 &driver_attr_cpsopmode,
2531 &driver_attr_cpsreptxy,
2532 &driver_attr_cpsreptz,
2533 &driver_attr_test,
2534 };
2535 /*----------------------------------------------------------------------------*/
2536 static int bmm150_create_attr(struct device_driver *driver)
2537 {
2538 int idx, err = 0;
2539 int num = (int)(sizeof(bmm150_attr_list)/sizeof(bmm150_attr_list[0]));
2540 if (driver == NULL)
2541 {
2542 return -EINVAL;
2543 }
2544
2545 for(idx = 0; idx < num; idx++)
2546 {
2547 if(err = driver_create_file(driver, bmm150_attr_list[idx]))
2548 {
2549 MSE_ERR( "driver_create_file (%s) = %d\n", bmm150_attr_list[idx]->attr.name, err);
2550 break;
2551 }
2552 }
2553
2554 return err;
2555 }
2556 /*----------------------------------------------------------------------------*/
2557 static int bmm150_delete_attr(struct device_driver *driver)
2558 {
2559 int idx;
2560 int num = (int)(sizeof(bmm150_attr_list)/sizeof(bmm150_attr_list[0]));
2561
2562 if(driver == NULL)
2563 {
2564 return -EINVAL;
2565 }
2566
2567 for(idx = 0; idx < num; idx++)
2568 {
2569 driver_remove_file(driver, bmm150_attr_list[idx]);
2570 }
2571
2572 return 0;
2573 }
2574
2575 /*----------------------------------------------------------------------------*/
2576 static int bmm150_open(struct inode *inode, struct file *file)
2577 {
2578 struct bmm150_i2c_data *obj = i2c_get_clientdata(this_client);
2579 int ret = -1;
2580
2581 if(atomic_read(&obj->trace) & MMC_CTR_DEBUG)
2582 {
2583 MSE_LOG("Open device node:bmm150\n");
2584 }
2585 ret = nonseekable_open(inode, file);
2586
2587 return ret;
2588 }
2589 /*----------------------------------------------------------------------------*/
2590 static int bmm150_release(struct inode *inode, struct file *file)
2591 {
2592 struct bmm150_i2c_data *obj = i2c_get_clientdata(this_client);
2593
2594 if(atomic_read(&obj->trace) & MMC_CTR_DEBUG)
2595 {
2596 MSE_LOG("Release device node:bmm150\n");
2597 }
2598 return 0;
2599 }
2600 /*----------------------------------------------------------------------------*/
2601 /* !!! add a new definition in linux/sensors_io.h if possible !!! */
2602 #define BMM_IOC_GET_EVENT_FLAG ECOMPASS_IOC_GET_OPEN_STATUS
2603
2604 static long bmm150_unlocked_ioctl(struct file *file, unsigned int cmd,unsigned long arg)
2605 {
2606 void __user *argp = (void __user *)arg;
2607
2608 /* NOTE: In this function the size of "char" should be 1-byte. */
2609 char buff[BMM150_BUFSIZE]; /* for chip information */
2610
2611 int value[CALIBRATION_DATA_SIZE]; /* for SET_YPR */
2612 int status; /* for OPEN/CLOSE_STATUS */
2613 short sensor_status; /* for Orientation and Msensor status */
2614 int vec[3] = {0};
2615 struct bmm150_i2c_data *clientdata = i2c_get_clientdata(this_client);
2616 hwm_sensor_data* osensor_data;
2617 uint32_t enable;
2618
2619 switch (cmd)
2620 {
2621 case BMM_IOC_GET_EVENT_FLAG: // used by daemon only
2622 /* block if no event updated */
2623 wait_event_interruptible(uplink_event_flag_wq, (uplink_event_flag != 0));
2624 mutex_lock(&uplink_event_flag_mutex);
2625 status = uplink_event_flag;
2626 mutex_unlock(&uplink_event_flag_mutex);
2627 if(copy_to_user(argp, &status, sizeof(status)))
2628 {
2629 MSE_ERR("copy_to_user failed.");
2630 return -EFAULT;
2631 }
2632 break;
2633
2634 case ECOMPASS_IOC_GET_DELAY: //used by daemon
2635 if(copy_to_user(argp, &bmm150d_delay, sizeof(bmm150d_delay)))
2636 {
2637 MSE_ERR("copy_to_user failed.");
2638 return -EFAULT;
2639 }
2640 /* clear the flag */
2641 mutex_lock(&uplink_event_flag_mutex);
2642 if ((uplink_event_flag & BMMDRV_ULEVT_FLAG_M_DELAY) != 0)
2643 {
2644 uplink_event_flag &= ~BMMDRV_ULEVT_FLAG_M_DELAY;
2645 }
2646 else if ((uplink_event_flag & BMMDRV_ULEVT_FLAG_O_DELAY) != 0)
2647 {
2648 uplink_event_flag &= ~BMMDRV_ULEVT_FLAG_O_DELAY;
2649 }
2650 mutex_unlock(&uplink_event_flag_mutex);
2651 /* wake up the wait queue */
2652 wake_up(&uplink_event_flag_wq);
2653 break;
2654
2655 case ECOMPASS_IOC_SET_YPR: //used by daemon
2656 if(argp == NULL)
2657 {
2658 MSE_ERR("invalid argument.");
2659 return -EINVAL;
2660 }
2661 if(copy_from_user(value, argp, sizeof(value)))
2662 {
2663 MSE_ERR("copy_from_user failed.");
2664 return -EFAULT;
2665 }
2666 ECS_SaveData(value);
2667 break;
2668
2669 case ECOMPASS_IOC_GET_MFLAG: //used by daemon
2670 sensor_status = atomic_read(&m_flag);
2671 #ifdef BMC150_BLOCK_DAEMON_ON_SUSPEND
2672 if ((sensor_status == 1) && (atomic_read(&driver_suspend_flag) == 1))
2673 {
2674 /* de-active m-channel when driver suspend regardless of m_flag*/
2675 sensor_status = 0;
2676 }
2677 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
2678 if(copy_to_user(argp, &sensor_status, sizeof(sensor_status)))
2679 {
2680 MSE_ERR("copy_to_user failed.");
2681 return -EFAULT;
2682 }
2683 /* clear the flag */
2684 mutex_lock(&uplink_event_flag_mutex);
2685 if ((uplink_event_flag & BMMDRV_ULEVT_FLAG_M_ACTIVE) != 0)
2686 {
2687 uplink_event_flag &= ~BMMDRV_ULEVT_FLAG_M_ACTIVE;
2688 }
2689 mutex_unlock(&uplink_event_flag_mutex);
2690 /* wake up the wait queue */
2691 wake_up(&uplink_event_flag_wq);
2692 break;
2693
2694 case ECOMPASS_IOC_GET_OFLAG: //used by daemon
2695 sensor_status = atomic_read(&o_flag);
2696 #ifdef BMC150_BLOCK_DAEMON_ON_SUSPEND
2697 if ((sensor_status == 1) && (atomic_read(&driver_suspend_flag) == 1))
2698 {
2699 /* de-active m-channel when driver suspend regardless of m_flag*/
2700 sensor_status = 0;
2701 }
2702 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
2703 if(copy_to_user(argp, &sensor_status, sizeof(sensor_status)))
2704 {
2705 MSE_ERR("copy_to_user failed.");
2706 return -EFAULT;
2707 }
2708 /* clear the flag */
2709 mutex_lock(&uplink_event_flag_mutex);
2710 if ((uplink_event_flag & BMMDRV_ULEVT_FLAG_O_ACTIVE) != 0)
2711 {
2712 uplink_event_flag &= ~BMMDRV_ULEVT_FLAG_O_ACTIVE;
2713 }
2714 mutex_unlock(&uplink_event_flag_mutex);
2715 /* wake up the wait queue */
2716 wake_up(&uplink_event_flag_wq);
2717 break;
2718
2719 #ifdef BMC150_M4G
2720 case ECOMPASS_IOC_GET_GDELAY: //used by daemon
2721 if(copy_to_user(argp, &m4g_delay, sizeof(m4g_delay)))
2722 {
2723 MSE_ERR("copy_to_user failed.");
2724 return -EFAULT;
2725 }
2726 /* clear the flag */
2727 mutex_lock(&uplink_event_flag_mutex);
2728 if ((uplink_event_flag & BMMDRV_ULEVT_FLAG_G_DELAY) != 0)
2729 {
2730 uplink_event_flag &= ~BMMDRV_ULEVT_FLAG_G_DELAY;
2731 }
2732 mutex_unlock(&uplink_event_flag_mutex);
2733 /* wake up the wait queue */
2734 wake_up(&uplink_event_flag_wq);
2735 break;
2736
2737 case ECOMPASS_IOC_GET_GFLAG: //used by daemon
2738 sensor_status = atomic_read(&g_flag);
2739 #ifdef BMC150_BLOCK_DAEMON_ON_SUSPEND
2740 if ((sensor_status == 1) && (atomic_read(&driver_suspend_flag) == 1))
2741 {
2742 /* de-active g-channel when driver suspend regardless of g_flag*/
2743 sensor_status = 0;
2744 }
2745 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
2746 if(copy_to_user(argp, &sensor_status, sizeof(sensor_status)))
2747 {
2748 MSE_ERR("copy_to_user failed.");
2749 return -EFAULT;
2750 }
2751 /* clear the flag */
2752 mutex_lock(&uplink_event_flag_mutex);
2753 if ((uplink_event_flag & BMMDRV_ULEVT_FLAG_G_ACTIVE) != 0)
2754 {
2755 uplink_event_flag &= ~BMMDRV_ULEVT_FLAG_G_ACTIVE;
2756 }
2757 mutex_unlock(&uplink_event_flag_mutex);
2758 /* wake up the wait queue */
2759 wake_up(&uplink_event_flag_wq);
2760 break;
2761 #endif //BMC150_M4G
2762
2763 #ifdef BMC150_VRV
2764 case ECOMPASS_IOC_GET_VRVDELAY: //used by daemon
2765 if(copy_to_user(argp, &vrv_delay, sizeof(vrv_delay)))
2766 {
2767 MSE_ERR("copy_to_user failed.");
2768 return -EFAULT;
2769 }
2770 /* clear the flag */
2771 mutex_lock(&uplink_event_flag_mutex);
2772 if ((uplink_event_flag & BMMDRV_ULEVT_FLAG_VRV_DELAY) != 0)
2773 {
2774 uplink_event_flag &= ~BMMDRV_ULEVT_FLAG_VRV_DELAY;
2775 }
2776 mutex_unlock(&uplink_event_flag_mutex);
2777 /* wake up the wait queue */
2778 wake_up(&uplink_event_flag_wq);
2779 break;
2780
2781 case ECOMPASS_IOC_GET_VRVFLAG: //used by daemon
2782 sensor_status = atomic_read(&vrv_flag);
2783 #ifdef BMC150_BLOCK_DAEMON_ON_SUSPEND
2784 if ((sensor_status == 1) && (atomic_read(&driver_suspend_flag) == 1))
2785 {
2786 /* de-active vrv-channel when driver suspend regardless of vrv_flag*/
2787 sensor_status = 0;
2788 }
2789 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
2790 if(copy_to_user(argp, &sensor_status, sizeof(sensor_status)))
2791 {
2792 MSE_ERR("copy_to_user failed.");
2793 return -EFAULT;
2794 }
2795 /* clear the flag */
2796 mutex_lock(&uplink_event_flag_mutex);
2797 if ((uplink_event_flag & BMMDRV_ULEVT_FLAG_VRV_ACTIVE) != 0)
2798 {
2799 uplink_event_flag &= ~BMMDRV_ULEVT_FLAG_VRV_ACTIVE;
2800 }
2801 mutex_unlock(&uplink_event_flag_mutex);
2802 /* wake up the wait queue */
2803 wake_up(&uplink_event_flag_wq);
2804 break;
2805 #endif //BMC150_VRV
2806
2807 #ifdef BMC150_VLA
2808 case ECOMPASS_IOC_GET_VLADELAY: //used by daemon
2809 if(copy_to_user(argp, &vla_delay, sizeof(vla_delay)))
2810 {
2811 MSE_ERR("copy_to_user failed.");
2812 return -EFAULT;
2813 }
2814 /* clear the flag */
2815 mutex_lock(&uplink_event_flag_mutex);
2816 if ((uplink_event_flag & BMMDRV_ULEVT_FLAG_VLA_DELAY) != 0)
2817 {
2818 uplink_event_flag &= ~BMMDRV_ULEVT_FLAG_VLA_DELAY;
2819 }
2820 mutex_unlock(&uplink_event_flag_mutex);
2821 /* wake up the wait queue */
2822 wake_up(&uplink_event_flag_wq);
2823 break;
2824
2825 case ECOMPASS_IOC_GET_VLAFLAG: //used by daemon
2826 sensor_status = atomic_read(&vla_flag);
2827 #ifdef BMC150_BLOCK_DAEMON_ON_SUSPEND
2828 if ((sensor_status == 1) && (atomic_read(&driver_suspend_flag) == 1))
2829 {
2830 /* de-active vla-channel when driver suspend regardless of vla_flag*/
2831 sensor_status = 0;
2832 }
2833 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
2834 if(copy_to_user(argp, &sensor_status, sizeof(sensor_status)))
2835 {
2836 MSE_ERR("copy_to_user failed.");
2837 return -EFAULT;
2838 }
2839 /* clear the flag */
2840 mutex_lock(&uplink_event_flag_mutex);
2841 if ((uplink_event_flag & BMMDRV_ULEVT_FLAG_VLA_ACTIVE) != 0)
2842 {
2843 uplink_event_flag &= ~BMMDRV_ULEVT_FLAG_VLA_ACTIVE;
2844 }
2845 mutex_unlock(&uplink_event_flag_mutex);
2846 /* wake up the wait queue */
2847 wake_up(&uplink_event_flag_wq);
2848 break;
2849 #endif //BMC150_VLA
2850
2851 #ifdef BMC150_VG
2852 case ECOMPASS_IOC_GET_VGDELAY: //used by daemon
2853 if(copy_to_user(argp, &vg_delay, sizeof(vg_delay)))
2854 {
2855 MSE_ERR("copy_to_user failed.");
2856 return -EFAULT;
2857 }
2858 /* clear the flag */
2859 mutex_lock(&uplink_event_flag_mutex);
2860 if ((uplink_event_flag & BMMDRV_ULEVT_FLAG_VG_DELAY) != 0)
2861 {
2862 uplink_event_flag &= ~BMMDRV_ULEVT_FLAG_VG_DELAY;
2863 }
2864 mutex_unlock(&uplink_event_flag_mutex);
2865 /* wake up the wait queue */
2866 wake_up(&uplink_event_flag_wq);
2867 break;
2868
2869 case ECOMPASS_IOC_GET_VGFLAG: //used by daemon
2870 sensor_status = atomic_read(&vg_flag);
2871 #ifdef BMC150_BLOCK_DAEMON_ON_SUSPEND
2872 if ((sensor_status == 1) && (atomic_read(&driver_suspend_flag) == 1))
2873 {
2874 /* de-active vla-channel when driver suspend regardless of vla_flag*/
2875 sensor_status = 0;
2876 }
2877 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
2878 if(copy_to_user(argp, &sensor_status, sizeof(sensor_status)))
2879 {
2880 MSE_ERR("copy_to_user failed.");
2881 return -EFAULT;
2882 }
2883 /* clear the flag */
2884 mutex_lock(&uplink_event_flag_mutex);
2885 if ((uplink_event_flag & BMMDRV_ULEVT_FLAG_VG_ACTIVE) != 0)
2886 {
2887 uplink_event_flag &= ~BMMDRV_ULEVT_FLAG_VG_ACTIVE;
2888 }
2889 mutex_unlock(&uplink_event_flag_mutex);
2890 /* wake up the wait queue */
2891 wake_up(&uplink_event_flag_wq);
2892 break;
2893 #endif //BMC150_VG
2894 case MSENSOR_IOCTL_READ_CHIPINFO: //reserved
2895 if(argp == NULL)
2896 {
2897 MSE_ERR( "IO parameter pointer is NULL!\r\n");
2898 break;
2899 }
2900
2901 bmm150_ReadChipInfo(buff, BMM150_BUFSIZE);
2902 if(copy_to_user(argp, buff, strlen(buff)+1))
2903 {
2904 return -EFAULT;
2905 }
2906 break;
2907
2908 case MSENSOR_IOCTL_READ_SENSORDATA: //used by MTK ftm or engineering mode
2909 if(argp == NULL)
2910 {
2911 MSE_ERR( "IO parameter pointer is NULL!\r\n");
2912 break;
2913 }
2914 ECS_GetRawData(vec);
2915 sprintf(buff, "%x %x %x", vec[0], vec[1], vec[2]);
2916 if(copy_to_user(argp, buff, strlen(buff)+1))
2917 {
2918 return -EFAULT;
2919 }
2920 break;
2921
2922 case ECOMPASS_IOC_GET_LAYOUT: //used by daemon
2923 status = atomic_read(&clientdata->layout);
2924 if(copy_to_user(argp, &status, sizeof(status)))
2925 {
2926 MSE_ERR("copy_to_user failed.");
2927 return -EFAULT;
2928 }
2929 break;
2930
2931 case MSENSOR_IOCTL_SENSOR_ENABLE: //used by MTK ftm
2932 if(argp == NULL)
2933 {
2934 MSE_ERR( "IO parameter pointer is NULL!\r\n");
2935 break;
2936 }
2937 if(copy_from_user(&enable, argp, sizeof(enable)))
2938 {
2939 MSE_ERR("copy_from_user failed.");
2940 return -EFAULT;
2941 }
2942 else
2943 {
2944 MSE_LOG("MSENSOR_IOCTL_SENSOR_ENABLE enable=%d!\r\n",enable);
2945 if(1 == enable)
2946 {
2947 atomic_set(&o_flag, 1);
2948 }
2949 else
2950 {
2951 atomic_set(&o_flag, 0);
2952 }
2953
2954 /* set the flag */
2955 mutex_lock(&uplink_event_flag_mutex);
2956 uplink_event_flag |= BMMDRV_ULEVT_FLAG_O_ACTIVE;
2957 mutex_unlock(&uplink_event_flag_mutex);
2958 /* wake up the wait queue */
2959 wake_up(&uplink_event_flag_wq);
2960 }
2961 break;
2962
2963 case MSENSOR_IOCTL_READ_FACTORY_SENSORDATA: //used by MTK ftm
2964 if(argp == NULL)
2965 {
2966 MSE_ERR( "IO parameter pointer is NULL!\r\n");
2967 break;
2968 }
2969
2970 osensor_data = (hwm_sensor_data *)buff;
2971 mutex_lock(&sensor_data_mutex);
2972
2973 osensor_data->values[0] = sensor_data[8];
2974 osensor_data->values[1] = sensor_data[9];
2975 osensor_data->values[2] = sensor_data[10];
2976 osensor_data->status = sensor_data[11];
2977 osensor_data->value_divide = CONVERT_O_DIV;
2978
2979 mutex_unlock(&sensor_data_mutex);
2980
2981 sprintf(buff, "%x %x %x %x %x", osensor_data->values[0], osensor_data->values[1],
2982 osensor_data->values[2],osensor_data->status,osensor_data->value_divide);
2983 if(copy_to_user(argp, buff, strlen(buff)+1))
2984 {
2985 return -EFAULT;
2986 }
2987 break;
2988
2989 default:
2990 MSE_ERR( "%s not supported = 0x%04x", __FUNCTION__, cmd);
2991 return -ENOIOCTLCMD;
2992 break;
2993 }
2994
2995 return 0;
2996 }
2997 /*----------------------------------------------------------------------------*/
2998 static struct file_operations bmm150_fops = {
2999 .owner = THIS_MODULE,
3000 .open = bmm150_open,
3001 .release = bmm150_release,
3002 .unlocked_ioctl = bmm150_unlocked_ioctl,
3003 };
3004 /*----------------------------------------------------------------------------*/
3005 static struct miscdevice bmm150_device = {
3006 .minor = MISC_DYNAMIC_MINOR,
3007 .name = "msensor",
3008 .fops = &bmm150_fops,
3009 };
3010 /*----------------------------------------------------------------------------*/
3011 static int bmm150_operate(void* self, uint32_t command, void* buff_in, int size_in,
3012 void* buff_out, int size_out, int* actualout)
3013 {
3014 int err = 0;
3015 int value;
3016 hwm_sensor_data* msensor_data;
3017
3018 #if DEBUG
3019 struct i2c_client *client = this_client;
3020 struct bmm150_i2c_data *data = i2c_get_clientdata(this_client);
3021 #endif
3022
3023 #if DEBUG
3024 if(atomic_read(&data->trace) & MMC_FUN_DEBUG)
3025 {
3026 MSE_FUN();
3027 }
3028 #endif
3029 switch (command)
3030 {
3031 case SENSOR_DELAY:
3032 if((buff_in == NULL) || (size_in < sizeof(int)))
3033 {
3034 MSE_ERR( "Set delay parameter error!\n");
3035 err = -EINVAL;
3036 }
3037 else
3038 {
3039 value = *(int *)buff_in;
3040
3041 bmm150d_delay = value;
3042 /* set the flag */
3043 mutex_lock(&uplink_event_flag_mutex);
3044 uplink_event_flag |= BMMDRV_ULEVT_FLAG_M_DELAY;
3045 mutex_unlock(&uplink_event_flag_mutex);
3046 /* wake up the wait queue */
3047 wake_up(&uplink_event_flag_wq);
3048 }
3049 break;
3050
3051 case SENSOR_ENABLE:
3052 if((buff_in == NULL) || (size_in < sizeof(int)))
3053 {
3054 MSE_ERR( "Enable sensor parameter error!\n");
3055 err = -EINVAL;
3056 }
3057 else
3058 {
3059
3060 value = *(int *)buff_in;
3061
3062 if(value == 1)
3063 {
3064 atomic_set(&m_flag, 1);
3065 }
3066 else
3067 {
3068 atomic_set(&m_flag, 0);
3069 }
3070
3071 bmm150_SetPowerMode(this_client, (value == 1));
3072
3073 /* set the flag */
3074 mutex_lock(&uplink_event_flag_mutex);
3075 uplink_event_flag |= BMMDRV_ULEVT_FLAG_M_ACTIVE;
3076 mutex_unlock(&uplink_event_flag_mutex);
3077 /* wake up the wait queue */
3078 wake_up(&uplink_event_flag_wq);
3079 }
3080 break;
3081
3082 case SENSOR_GET_DATA:
3083 if((buff_out == NULL) || (size_out< sizeof(hwm_sensor_data)))
3084 {
3085 MSE_ERR( "get sensor data parameter error!\n");
3086 err = -EINVAL;
3087 }
3088 else
3089 {
3090 msensor_data = (hwm_sensor_data *)buff_out;
3091 mutex_lock(&sensor_data_mutex);
3092
3093 msensor_data->values[0] = sensor_data[4];
3094 msensor_data->values[1] = sensor_data[5];
3095 msensor_data->values[2] = sensor_data[6];
3096 msensor_data->status = sensor_data[7];
3097 msensor_data->value_divide = CONVERT_M_DIV;
3098
3099 mutex_unlock(&sensor_data_mutex);
3100 #if DEBUG
3101 if(atomic_read(&data->trace) & MMC_HWM_DEBUG)
3102 {
3103 MSE_LOG("Hwm get m-sensor data: %d, %d, %d. divide %d, status %d!\n",
3104 msensor_data->values[0],msensor_data->values[1],msensor_data->values[2],
3105 msensor_data->value_divide,msensor_data->status);
3106 }
3107 #endif
3108 }
3109 break;
3110 default:
3111 MSE_ERR( "msensor operate function no this parameter %d!\n", command);
3112 err = -1;
3113 break;
3114 }
3115
3116 return err;
3117 }
3118
3119 /*----------------------------------------------------------------------------*/
3120 int bmm150_orientation_operate(void* self, uint32_t command, void* buff_in, int size_in,
3121 void* buff_out, int size_out, int* actualout)
3122 {
3123 int err = 0;
3124 int value;
3125 hwm_sensor_data* osensor_data;
3126 #if DEBUG
3127 struct i2c_client *client = this_client;
3128 struct bmm150_i2c_data *data = i2c_get_clientdata(this_client);
3129 #endif
3130
3131 #if DEBUG
3132 if(atomic_read(&data->trace) & MMC_FUN_DEBUG)
3133 {
3134 MSE_FUN();
3135 }
3136 #endif
3137
3138 switch (command)
3139 {
3140 case SENSOR_DELAY:
3141 if((buff_in == NULL) || (size_in < sizeof(int)))
3142 {
3143 MSE_ERR( "Set delay parameter error!\n");
3144 err = -EINVAL;
3145 }
3146 else
3147 {
3148 value = *(int *)buff_in;
3149 bmm150d_delay = value;
3150 /* set the flag */
3151 mutex_lock(&uplink_event_flag_mutex);
3152 uplink_event_flag |= BMMDRV_ULEVT_FLAG_O_DELAY;
3153 mutex_unlock(&uplink_event_flag_mutex);
3154 /* wake up the wait queue */
3155 wake_up(&uplink_event_flag_wq);
3156 }
3157 break;
3158
3159 case SENSOR_ENABLE:
3160 if((buff_in == NULL) || (size_in < sizeof(int)))
3161 {
3162 MSE_ERR( "Enable sensor parameter error!\n");
3163 err = -EINVAL;
3164 }
3165 else
3166 {
3167
3168 value = *(int *)buff_in;
3169
3170 if(value == 1)
3171 {
3172 atomic_set(&o_flag, 1);
3173 }
3174 else
3175 {
3176 atomic_set(&o_flag, 0);
3177 }
3178
3179 /* set the flag */
3180 mutex_lock(&uplink_event_flag_mutex);
3181 uplink_event_flag |= BMMDRV_ULEVT_FLAG_O_ACTIVE;
3182 mutex_unlock(&uplink_event_flag_mutex);
3183 /* wake up the wait queue */
3184 wake_up(&uplink_event_flag_wq);
3185 }
3186 break;
3187
3188 case SENSOR_GET_DATA:
3189 if((buff_out == NULL) || (size_out< sizeof(hwm_sensor_data)))
3190 {
3191 MSE_ERR( "get sensor data parameter error!\n");
3192 err = -EINVAL;
3193 }
3194 else
3195 {
3196 osensor_data = (hwm_sensor_data *)buff_out;
3197 mutex_lock(&sensor_data_mutex);
3198
3199 osensor_data->values[0] = sensor_data[8];
3200 osensor_data->values[1] = sensor_data[9];
3201 osensor_data->values[2] = sensor_data[10];
3202 osensor_data->status = sensor_data[11];
3203 osensor_data->value_divide = CONVERT_O_DIV;
3204
3205 mutex_unlock(&sensor_data_mutex);
3206 #if DEBUG
3207 if(atomic_read(&data->trace) & MMC_HWM_DEBUG)
3208 {
3209 MSE_LOG("Hwm get o-sensor data: %d, %d, %d. divide %d, status %d!\n",
3210 osensor_data->values[0],osensor_data->values[1],osensor_data->values[2],
3211 osensor_data->value_divide,osensor_data->status);
3212 }
3213 #endif
3214 }
3215 break;
3216 default:
3217 MSE_ERR( "osensor operate function no this parameter %d!\n", command);
3218 err = -1;
3219 break;
3220 }
3221
3222 return err;
3223 }
3224 /*----------------------------------------------------------------------------*/
3225 #ifdef BMC150_M4G
3226 int bmm150_m4g_operate(void* self, uint32_t command, void* buff_in, int size_in,
3227 void* buff_out, int size_out, int* actualout)
3228 {
3229 int err = 0;
3230 int value;
3231 hwm_sensor_data* g_data;
3232 #if DEBUG
3233 struct i2c_client *client = this_client;
3234 struct bmm150_i2c_data *data = i2c_get_clientdata(this_client);
3235 #endif
3236
3237 #if DEBUG
3238 if(atomic_read(&data->trace) & MMC_FUN_DEBUG)
3239 {
3240 MSE_FUN();
3241 }
3242 #endif
3243
3244 switch (command)
3245 {
3246 case SENSOR_DELAY:
3247 if((buff_in == NULL) || (size_in < sizeof(int)))
3248 {
3249 MSE_ERR( "Set delay parameter error!\n");
3250 err = -EINVAL;
3251 }
3252 else
3253 {
3254 value = *(int *)buff_in;
3255 m4g_delay = value;
3256 /* set the flag */
3257 mutex_lock(&uplink_event_flag_mutex);
3258 uplink_event_flag |= BMMDRV_ULEVT_FLAG_G_DELAY;
3259 mutex_unlock(&uplink_event_flag_mutex);
3260 /* wake up the wait queue */
3261 wake_up(&uplink_event_flag_wq);
3262 }
3263 break;
3264
3265 case SENSOR_ENABLE:
3266 if((buff_in == NULL) || (size_in < sizeof(int)))
3267 {
3268 MSE_ERR( "Enable sensor parameter error!\n");
3269 err = -EINVAL;
3270 }
3271 else
3272 {
3273
3274 value = *(int *)buff_in;
3275
3276 if(value == 1)
3277 {
3278 atomic_set(&g_flag, 1);
3279 }
3280 else
3281 {
3282 atomic_set(&g_flag, 0);
3283 }
3284
3285 /* set the flag */
3286 mutex_lock(&uplink_event_flag_mutex);
3287 uplink_event_flag |= BMMDRV_ULEVT_FLAG_G_ACTIVE;
3288 mutex_unlock(&uplink_event_flag_mutex);
3289 /* wake up the wait queue */
3290 wake_up(&uplink_event_flag_wq);
3291 }
3292 break;
3293
3294 case SENSOR_GET_DATA:
3295 if((buff_out == NULL) || (size_out< sizeof(hwm_sensor_data)))
3296 {
3297 MSE_ERR( "get sensor data parameter error!\n");
3298 err = -EINVAL;
3299 }
3300 else
3301 {
3302 g_data = (hwm_sensor_data *)buff_out;
3303 mutex_lock(&sensor_data_mutex);
3304
3305 g_data->values[0] = m4g_data[0];
3306 g_data->values[1] = m4g_data[1];
3307 g_data->values[2] = m4g_data[2];
3308 g_data->status = m4g_data[3];
3309 g_data->value_divide = CONVERT_G_DIV;
3310
3311 mutex_unlock(&sensor_data_mutex);
3312 #if DEBUG
3313 if(atomic_read(&data->trace) & MMC_HWM_DEBUG)
3314 {
3315 MSE_LOG("Hwm get m4g data: %d, %d, %d. divide %d, status %d!\n",
3316 g_data->values[0],g_data->values[1],g_data->values[2],
3317 g_data->value_divide,g_data->status);
3318 }
3319 #endif
3320 }
3321 break;
3322 default:
3323 MSE_ERR( "m4g operate function no this parameter %d!\n", command);
3324 err = -1;
3325 break;
3326 }
3327
3328 return err;
3329 }
3330 #endif //BMC150_M4G
3331 /*----------------------------------------------------------------------------*/
3332 #ifdef BMC150_VRV
3333 int bmm150_vrv_operate(void* self, uint32_t command, void* buff_in, int size_in,
3334 void* buff_out, int size_out, int* actualout)
3335 {
3336 int err = 0;
3337 int value;
3338 hwm_sensor_data* vrv_data;
3339 #if DEBUG
3340 struct i2c_client *client = this_client;
3341 struct bmm150_i2c_data *data = i2c_get_clientdata(this_client);
3342 #endif
3343
3344 #if DEBUG
3345 if(atomic_read(&data->trace) & MMC_FUN_DEBUG)
3346 {
3347 MSE_FUN();
3348 }
3349 #endif
3350
3351 switch (command)
3352 {
3353 case SENSOR_DELAY:
3354 if((buff_in == NULL) || (size_in < sizeof(int)))
3355 {
3356 MSE_ERR( "Set delay parameter error!\n");
3357 err = -EINVAL;
3358 }
3359 else
3360 {
3361 value = *(int *)buff_in;
3362 vrv_delay = value;
3363 /* set the flag */
3364 mutex_lock(&uplink_event_flag_mutex);
3365 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VRV_DELAY;
3366 mutex_unlock(&uplink_event_flag_mutex);
3367 /* wake up the wait queue */
3368 wake_up(&uplink_event_flag_wq);
3369 }
3370 break;
3371
3372 case SENSOR_ENABLE:
3373 if((buff_in == NULL) || (size_in < sizeof(int)))
3374 {
3375 MSE_ERR( "Enable sensor parameter error!\n");
3376 err = -EINVAL;
3377 }
3378 else
3379 {
3380
3381 value = *(int *)buff_in;
3382
3383 if(value == 1)
3384 {
3385 atomic_set(&vrv_flag, 1);
3386 }
3387 else
3388 {
3389 atomic_set(&vrv_flag, 0);
3390 }
3391
3392 /* set the flag */
3393 mutex_lock(&uplink_event_flag_mutex);
3394 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VRV_ACTIVE;
3395 mutex_unlock(&uplink_event_flag_mutex);
3396 /* wake up the wait queue */
3397 wake_up(&uplink_event_flag_wq);
3398 }
3399 break;
3400
3401 case SENSOR_GET_DATA:
3402 if((buff_out == NULL) || (size_out< sizeof(hwm_sensor_data)))
3403 {
3404 MSE_ERR( "get sensor data parameter error!\n");
3405 err = -EINVAL;
3406 }
3407 else
3408 {
3409 vrv_data = (hwm_sensor_data *)buff_out;
3410 mutex_lock(&sensor_data_mutex);
3411
3412 vrv_data->values[0] = m4g_data[4];
3413 vrv_data->values[1] = m4g_data[5];
3414 vrv_data->values[2] = m4g_data[6];
3415 vrv_data->status = m4g_data[7];
3416 vrv_data->value_divide = CONVERT_VRV_DIV;
3417
3418 mutex_unlock(&sensor_data_mutex);
3419 #if DEBUG
3420 if(atomic_read(&data->trace) & MMC_HWM_DEBUG)
3421 {
3422 MSE_LOG("Hwm get rotation vector data: %d, %d, %d. divide %d, status %d!\n",
3423 vrv_data->values[0],vrv_data->values[1],vrv_data->values[2],
3424 vrv_data->value_divide,vrv_data->status);
3425 }
3426 #endif
3427 }
3428 break;
3429 default:
3430 MSE_ERR( "rotation vector operate function no this parameter %d!\n", command);
3431 err = -1;
3432 break;
3433 }
3434
3435 return err;
3436 }
3437 #endif //BMC150_VRV
3438 /*----------------------------------------------------------------------------*/
3439 #ifdef BMC150_VLA
3440 int bmm150_vla_operate(void* self, uint32_t command, void* buff_in, int size_in,
3441 void* buff_out, int size_out, int* actualout)
3442 {
3443 int err = 0;
3444 int value;
3445 hwm_sensor_data* vla_value;
3446 #if DEBUG
3447 struct i2c_client *client = this_client;
3448 struct bmm150_i2c_data *data = i2c_get_clientdata(this_client);
3449 #endif
3450
3451 #if DEBUG
3452 if(atomic_read(&data->trace) & MMC_FUN_DEBUG)
3453 {
3454 MSE_FUN();
3455 }
3456 #endif
3457
3458 switch (command)
3459 {
3460 case SENSOR_DELAY:
3461 if((buff_in == NULL) || (size_in < sizeof(int)))
3462 {
3463 MSE_ERR( "Set delay parameter error!\n");
3464 err = -EINVAL;
3465 }
3466 else
3467 {
3468 value = *(int *)buff_in;
3469 vla_delay = value;
3470 /* set the flag */
3471 mutex_lock(&uplink_event_flag_mutex);
3472 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VLA_DELAY;
3473 mutex_unlock(&uplink_event_flag_mutex);
3474 /* wake up the wait queue */
3475 wake_up(&uplink_event_flag_wq);
3476 }
3477 break;
3478
3479 case SENSOR_ENABLE:
3480 if((buff_in == NULL) || (size_in < sizeof(int)))
3481 {
3482 MSE_ERR( "Enable sensor parameter error!\n");
3483 err = -EINVAL;
3484 }
3485 else
3486 {
3487
3488 value = *(int *)buff_in;
3489
3490 if(value == 1)
3491 {
3492 atomic_set(&vla_flag, 1);
3493 }
3494 else
3495 {
3496 atomic_set(&vla_flag, 0);
3497 }
3498
3499 /* set the flag */
3500 mutex_lock(&uplink_event_flag_mutex);
3501 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VLA_ACTIVE;
3502 mutex_unlock(&uplink_event_flag_mutex);
3503 /* wake up the wait queue */
3504 wake_up(&uplink_event_flag_wq);
3505 }
3506 break;
3507
3508 case SENSOR_GET_DATA:
3509 if((buff_out == NULL) || (size_out< sizeof(hwm_sensor_data)))
3510 {
3511 MSE_ERR( "get sensor data parameter error!\n");
3512 err = -EINVAL;
3513 }
3514 else
3515 {
3516 vla_value = (hwm_sensor_data *)buff_out;
3517 mutex_lock(&sensor_data_mutex);
3518
3519 vla_value->values[0] = vla_data[0];
3520 vla_value->values[1] = vla_data[1];
3521 vla_value->values[2] = vla_data[2];
3522 vla_value->status = vla_data[3];
3523 vla_value->value_divide = CONVERT_VLA_DIV;
3524
3525 mutex_unlock(&sensor_data_mutex);
3526 #if DEBUG
3527 if(atomic_read(&data->trace) & MMC_HWM_DEBUG)
3528 {
3529 MSE_LOG("Hwm get virtual linear accelerometer data: %d, %d, %d. divide %d, status %d!\n",
3530 vla_value->values[0],vla_value->values[1],vla_value->values[2],
3531 vla_value->value_divide,vla_value->status);
3532 }
3533 #endif
3534 }
3535 break;
3536 default:
3537 MSE_ERR( "virtual linear accelerometer operate function no this parameter %d!\n", command);
3538 err = -1;
3539 break;
3540 }
3541
3542 return err;
3543 }
3544 #endif //BMC150_VLA
3545 /*----------------------------------------------------------------------------*/
3546 #ifdef BMC150_VG
3547 int bmm150_vg_operate(void* self, uint32_t command, void* buff_in, int size_in,
3548 void* buff_out, int size_out, int* actualout)
3549 {
3550 int err = 0;
3551 int value;
3552 hwm_sensor_data* vg_value;
3553 #if DEBUG
3554 struct i2c_client *client = this_client;
3555 struct bmm150_i2c_data *data = i2c_get_clientdata(this_client);
3556 #endif
3557
3558 #if DEBUG
3559 if(atomic_read(&data->trace) & MMC_FUN_DEBUG)
3560 {
3561 MSE_FUN();
3562 }
3563 #endif
3564
3565 switch (command)
3566 {
3567 case SENSOR_DELAY:
3568 if((buff_in == NULL) || (size_in < sizeof(int)))
3569 {
3570 MSE_ERR( "Set delay parameter error!\n");
3571 err = -EINVAL;
3572 }
3573 else
3574 {
3575 value = *(int *)buff_in;
3576 vg_delay = value;
3577 /* set the flag */
3578 mutex_lock(&uplink_event_flag_mutex);
3579 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VG_DELAY;
3580 mutex_unlock(&uplink_event_flag_mutex);
3581 /* wake up the wait queue */
3582 wake_up(&uplink_event_flag_wq);
3583 }
3584 break;
3585
3586 case SENSOR_ENABLE:
3587 if((buff_in == NULL) || (size_in < sizeof(int)))
3588 {
3589 MSE_ERR( "Enable sensor parameter error!\n");
3590 err = -EINVAL;
3591 }
3592 else
3593 {
3594
3595 value = *(int *)buff_in;
3596
3597 if(value == 1)
3598 {
3599 atomic_set(&vg_flag, 1);
3600 }
3601 else
3602 {
3603 atomic_set(&vg_flag, 0);
3604 }
3605
3606 /* set the flag */
3607 mutex_lock(&uplink_event_flag_mutex);
3608 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VG_ACTIVE;
3609 mutex_unlock(&uplink_event_flag_mutex);
3610 /* wake up the wait queue */
3611 wake_up(&uplink_event_flag_wq);
3612 }
3613 break;
3614
3615 case SENSOR_GET_DATA:
3616 if((buff_out == NULL) || (size_out< sizeof(hwm_sensor_data)))
3617 {
3618 MSE_ERR( "get sensor data parameter error!\n");
3619 err = -EINVAL;
3620 }
3621 else
3622 {
3623 vg_value = (hwm_sensor_data *)buff_out;
3624 mutex_lock(&sensor_data_mutex);
3625
3626 vg_value->values[0] = vg_data[0];
3627 vg_value->values[1] = vg_data[1];
3628 vg_value->values[2] = vg_data[2];
3629 vg_value->status = vg_data[3];
3630 vg_value->value_divide = CONVERT_VG_DIV;
3631
3632 mutex_unlock(&sensor_data_mutex);
3633 #if DEBUG
3634 if(atomic_read(&data->trace) & MMC_HWM_DEBUG)
3635 {
3636 MSE_LOG("Hwm get virtual gravity data: %d, %d, %d. divide %d, status %d!\n",
3637 vg_value->values[0],vg_value->values[1],vg_value->values[2],
3638 vg_value->value_divide,vg_value->status);
3639 }
3640 #endif
3641 }
3642 break;
3643 default:
3644 MSE_ERR( "virtual gravity operate function no this parameter %d!\n", command);
3645 err = -1;
3646 break;
3647 }
3648
3649 return err;
3650 }
3651 #endif //BMC150_VG
3652 /*----------------------------------------------------------------------------*/
3653 static void bmm150_restore_hw_cfg(struct i2c_client *client)
3654 {
3655 struct bmm150_i2c_data *obj = i2c_get_clientdata(client);
3656
3657 if (obj->op_mode > 3)
3658 {
3659 obj->op_mode = BMM150_SLEEP_MODE;
3660 }
3661 bmm150api_set_functional_state(obj->op_mode);
3662
3663 bmm150api_set_datarate(obj->odr);
3664 //mdelay(BMM_I2C_WRITE_DELAY_TIME);
3665
3666 bmm150api_set_repetitions_XY(obj->rept_xy);
3667 //mdelay(BMM_I2C_WRITE_DELAY_TIME);
3668
3669 bmm150api_set_repetitions_Z(obj->rept_z);
3670 //mdelay(BMM_I2C_WRITE_DELAY_TIME);
3671 }
3672
3673 /*----------------------------------------------------------------------------*/
3674 #ifndef CONFIG_HAS_EARLYSUSPEND
3675 /*----------------------------------------------------------------------------*/
3676 static int bmm150_suspend(struct i2c_client *client, pm_message_t msg)
3677 {
3678 struct bmm150_i2c_data *data = i2c_get_clientdata(client);
3679
3680 if(msg.event == PM_EVENT_SUSPEND)
3681 {
3682 #ifdef BMC150_BLOCK_DAEMON_ON_SUSPEND
3683 /* set driver suspend flag */
3684 atomic_set(&driver_suspend_flag, 1);
3685 if (atomic_read(&m_flag) == 1)
3686 {
3687 /* set the flag to block e-compass daemon*/
3688 mutex_lock(&uplink_event_flag_mutex);
3689 uplink_event_flag |= BMMDRV_ULEVT_FLAG_M_ACTIVE;
3690 mutex_unlock(&uplink_event_flag_mutex);
3691 }
3692 if (atomic_read(&o_flag) == 1)
3693 {
3694 /* set the flag to block e-compass daemon*/
3695 mutex_lock(&uplink_event_flag_mutex);
3696 uplink_event_flag |= BMMDRV_ULEVT_FLAG_O_ACTIVE;
3697 mutex_unlock(&uplink_event_flag_mutex);
3698 }
3699 #ifdef BMC150_M4G
3700 if (atomic_read(&g_flag) == 1)
3701 {
3702 /* set the flag to block e-compass daemon*/
3703 mutex_lock(&uplink_event_flag_mutex);
3704 uplink_event_flag |= BMMDRV_ULEVT_FLAG_G_ACTIVE;
3705 mutex_unlock(&uplink_event_flag_mutex);
3706 }
3707 #endif //BMC150_M4G
3708 #ifdef BMC150_VRV
3709 if (atomic_read(&vrv_flag) == 1)
3710 {
3711 /* set the flag to block e-compass daemon*/
3712 mutex_lock(&uplink_event_flag_mutex);
3713 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VRV_ACTIVE;
3714 mutex_unlock(&uplink_event_flag_mutex);
3715 }
3716 #endif //BMC150_VRV
3717 #ifdef BMC150_VLA
3718 if (atomic_read(&vla_flag) == 1)
3719 {
3720 /* set the flag to block e-compass daemon*/
3721 mutex_lock(&uplink_event_flag_mutex);
3722 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VLA_ACTIVE;
3723 mutex_unlock(&uplink_event_flag_mutex);
3724 }
3725 #endif //BMC150_VLA
3726 #ifdef BMC150_VG
3727 if (atomic_read(&vg_flag) == 1)
3728 {
3729 /* set the flag to block e-compass daemon*/
3730 mutex_lock(&uplink_event_flag_mutex);
3731 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VG_ACTIVE;
3732 mutex_unlock(&uplink_event_flag_mutex);
3733 }
3734 #endif //BMC150_VG
3735
3736 /* wake up the wait queue */
3737 wake_up(&uplink_event_flag_wq);
3738 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
3739
3740 bmm150_SetPowerMode(obj->client, FALSE);
3741 bmm150_power(obj->hw, 0);
3742 }
3743 return 0;
3744 }
3745 /*----------------------------------------------------------------------------*/
3746 static int bmm150_resume(struct i2c_client *client)
3747 {
3748 struct bmm150_i2c_data *data = i2c_get_clientdata(client);
3749
3750 bmm150_power(obj->hw, 1);
3751 bmm150_SetPowerMode(obj->client, TRUE);
3752 #ifdef BMC150_BLOCK_DAEMON_ON_SUSPEND
3753 /* clear driver suspend flag */
3754 atomic_set(&driver_suspend_flag, 0);
3755 if (atomic_read(&m_flag) == 1)
3756 {
3757 /* set the flag to unblock e-compass daemon*/
3758 mutex_lock(&uplink_event_flag_mutex);
3759 uplink_event_flag |= BMMDRV_ULEVT_FLAG_M_ACTIVE;
3760 mutex_unlock(&uplink_event_flag_mutex);
3761 }
3762 if (atomic_read(&o_flag) == 1)
3763 {
3764 /* set the flag to unblock e-compass daemon*/
3765 mutex_lock(&uplink_event_flag_mutex);
3766 uplink_event_flag |= BMMDRV_ULEVT_FLAG_O_ACTIVE;
3767 mutex_unlock(&uplink_event_flag_mutex);
3768 }
3769 #ifdef BMC150_M4G
3770 if (atomic_read(&g_flag) == 1)
3771 {
3772 /* set the flag to unblock e-compass daemon*/
3773 mutex_lock(&uplink_event_flag_mutex);
3774 uplink_event_flag |= BMMDRV_ULEVT_FLAG_G_ACTIVE;
3775 mutex_unlock(&uplink_event_flag_mutex);
3776 }
3777 #endif //BMC150_M4G
3778 #ifdef BMC150_VRV
3779 if (atomic_read(&vrv_flag) == 1)
3780 {
3781 /* set the flag to unblock e-compass daemon*/
3782 mutex_lock(&uplink_event_flag_mutex);
3783 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VRV_ACTIVE;
3784 mutex_unlock(&uplink_event_flag_mutex);
3785 }
3786 #endif //BMC150_VRV
3787 #ifdef BMC150_VG
3788 if (atomic_read(&vg_flag) == 1)
3789 {
3790 /* set the flag to unblock e-compass daemon*/
3791 mutex_lock(&uplink_event_flag_mutex);
3792 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VG_ACTIVE;
3793 mutex_unlock(&uplink_event_flag_mutex);
3794 }
3795 #endif //BMC150_VG
3796
3797 /* wake up the wait queue */
3798 wake_up(&uplink_event_flag_wq);
3799 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
3800 return 0;
3801 }
3802 /*----------------------------------------------------------------------------*/
3803 #else /*CONFIG_HAS_EARLY_SUSPEND is defined*/
3804 /*----------------------------------------------------------------------------*/
3805 static void bmm150_early_suspend(struct early_suspend *h)
3806 {
3807 struct bmm150_i2c_data *obj = container_of(h, struct bmm150_i2c_data, early_drv);
3808 u8 power_mode;
3809 int err = 0;
3810
3811 if(NULL == obj)
3812 {
3813 MSE_ERR( "null pointer!!\n");
3814 return;
3815 }
3816
3817 #ifdef BMC150_BLOCK_DAEMON_ON_SUSPEND
3818 /* set driver suspend flag */
3819 atomic_set(&driver_suspend_flag, 1);
3820 if (atomic_read(&m_flag) == 1)
3821 {
3822 /* set the flag to block e-compass daemon*/
3823 mutex_lock(&uplink_event_flag_mutex);
3824 uplink_event_flag |= BMMDRV_ULEVT_FLAG_M_ACTIVE;
3825 mutex_unlock(&uplink_event_flag_mutex);
3826 }
3827 if (atomic_read(&o_flag) == 1)
3828 {
3829 /* set the flag to block e-compass daemon*/
3830 mutex_lock(&uplink_event_flag_mutex);
3831 uplink_event_flag |= BMMDRV_ULEVT_FLAG_O_ACTIVE;
3832 mutex_unlock(&uplink_event_flag_mutex);
3833 }
3834 #ifdef BMC150_M4G
3835 if (atomic_read(&g_flag) == 1)
3836 {
3837 /* set the flag to block e-compass daemon*/
3838 mutex_lock(&uplink_event_flag_mutex);
3839 uplink_event_flag |= BMMDRV_ULEVT_FLAG_G_ACTIVE;
3840 mutex_unlock(&uplink_event_flag_mutex);
3841 }
3842 #endif //BMC150_M4G
3843 #ifdef BMC150_VRV
3844 if (atomic_read(&vrv_flag) == 1)
3845 {
3846 /* set the flag to block e-compass daemon*/
3847 mutex_lock(&uplink_event_flag_mutex);
3848 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VRV_ACTIVE;
3849 mutex_unlock(&uplink_event_flag_mutex);
3850 }
3851 #endif //BMC150_VRV
3852 #ifdef BMC150_VLA
3853 if (atomic_read(&vla_flag) == 1)
3854 {
3855 /* set the flag to block e-compass daemon*/
3856 mutex_lock(&uplink_event_flag_mutex);
3857 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VLA_ACTIVE;
3858 mutex_unlock(&uplink_event_flag_mutex);
3859 }
3860 #endif //BMC150_VLA
3861 #ifdef BMC150_VRV
3862 if (atomic_read(&vg_flag) == 1)
3863 {
3864 /* set the flag to block e-compass daemon*/
3865 mutex_lock(&uplink_event_flag_mutex);
3866 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VG_ACTIVE;
3867 mutex_unlock(&uplink_event_flag_mutex);
3868 }
3869 #endif //BMC150_VG
3870
3871 /* wake up the wait queue */
3872 wake_up(&uplink_event_flag_wq);
3873 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
3874
3875 bmm150_SetPowerMode(obj->client, FALSE);
3876 bmm150_power(obj->hw, 0);
3877 }
3878 /*----------------------------------------------------------------------------*/
3879 static void bmm150_late_resume(struct early_suspend *h)
3880 {
3881 struct bmm150_i2c_data *obj = container_of(h, struct bmm150_i2c_data, early_drv);
3882
3883 if(NULL == obj)
3884 {
3885 MSE_ERR( "null pointer!!\n");
3886 return;
3887 }
3888
3889 bmm150_power(obj->hw, 1);
3890 bmm150_SetPowerMode(obj->client, TRUE);
3891 #ifdef BMC150_BLOCK_DAEMON_ON_SUSPEND
3892 /* clear driver suspend flag */
3893 atomic_set(&driver_suspend_flag, 0);
3894 if (atomic_read(&m_flag) == 1)
3895 {
3896 /* set the flag to unblock e-compass daemon*/
3897 mutex_lock(&uplink_event_flag_mutex);
3898 uplink_event_flag |= BMMDRV_ULEVT_FLAG_M_ACTIVE;
3899 mutex_unlock(&uplink_event_flag_mutex);
3900 }
3901 if (atomic_read(&o_flag) == 1)
3902 {
3903 /* set the flag to unblock e-compass daemon*/
3904 mutex_lock(&uplink_event_flag_mutex);
3905 uplink_event_flag |= BMMDRV_ULEVT_FLAG_O_ACTIVE;
3906 mutex_unlock(&uplink_event_flag_mutex);
3907 }
3908 #ifdef BMC150_M4G
3909 if (atomic_read(&g_flag) == 1)
3910 {
3911 /* set the flag to unblock e-compass daemon*/
3912 mutex_lock(&uplink_event_flag_mutex);
3913 uplink_event_flag |= BMMDRV_ULEVT_FLAG_G_ACTIVE;
3914 mutex_unlock(&uplink_event_flag_mutex);
3915 }
3916 #endif //BMC150_M4G
3917 #ifdef BMC150_VRV
3918 if (atomic_read(&vrv_flag) == 1)
3919 {
3920 /* set the flag to unblock e-compass daemon*/
3921 mutex_lock(&uplink_event_flag_mutex);
3922 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VRV_ACTIVE;
3923 mutex_unlock(&uplink_event_flag_mutex);
3924 }
3925 #endif //BMC150_VRV
3926 #ifdef BMC150_VLA
3927 if (atomic_read(&vla_flag) == 1)
3928 {
3929 /* set the flag to unblock e-compass daemon*/
3930 mutex_lock(&uplink_event_flag_mutex);
3931 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VLA_ACTIVE;
3932 mutex_unlock(&uplink_event_flag_mutex);
3933 }
3934 #endif //BMC150_VLA
3935 #ifdef BMC150_VG
3936 if (atomic_read(&vg_flag) == 1)
3937 {
3938 /* set the flag to unblock e-compass daemon*/
3939 mutex_lock(&uplink_event_flag_mutex);
3940 uplink_event_flag |= BMMDRV_ULEVT_FLAG_VG_ACTIVE;
3941 mutex_unlock(&uplink_event_flag_mutex);
3942 }
3943 #endif //BMC150_VG
3944
3945 /* wake up the wait queue */
3946 wake_up(&uplink_event_flag_wq);
3947 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
3948 }
3949 #endif /*CONFIG_HAS_EARLYSUSPEND*/
3950 /*----------------------------------------------------------------------------*/
3951 #define BMM_MAX_RETRY_WAKEUP (5)
3952 #define BMM_I2C_WRITE_DELAY_TIME (1)
3953 static int bmm150_wakeup(struct i2c_client *client)
3954 {
3955 int err = 0;
3956 int try_times = BMM_MAX_RETRY_WAKEUP;
3957 u8 data[2] = {BMM150_POWER_CNTL, 0x01};
3958 u8 dummy;
3959
3960 MSE_LOG("waking up the chip...");
3961
3962 while (try_times) {
3963 err = i2c_master_send(client, data, 2);
3964 mdelay(BMM_I2C_WRITE_DELAY_TIME);
3965 dummy = 0;
3966 err = hwmsen_read_block(client, BMM150_POWER_CNTL, &dummy, 1);
3967 if (data[1] == dummy)
3968 {
3969 break;
3970 }
3971 try_times--;
3972 }
3973
3974 MSE_LOG("wake up result: %s, tried times: %d",
3975 (try_times > 0) ? "succeed" : "fail",
3976 BMM_MAX_RETRY_WAKEUP - try_times + 1);
3977
3978 err = (try_times > 0) ? 0 : -1;
3979
3980 return err;
3981 }
3982 /*----------------------------------------------------------------------------*/
3983 static int bmm150_checkchipid(struct i2c_client *client)
3984 {
3985 int err = 0;
3986 u8 chip_id = 0;
3987
3988 hwmsen_read_block(client, BMM150_CHIP_ID, &chip_id, 1);
3989 MSE_LOG("read chip id result: %#x", chip_id);
3990
3991 if ((chip_id & 0xff) != SENSOR_CHIP_ID_BMM)
3992 {
3993 return -1;
3994 }
3995 else
3996 {
3997 return 0;
3998 }
3999 }
4000 /*----------------------------------------------------------------------------*/
4001 static char bmm150_i2c_read_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
4002 {
4003 return hwmsen_read_block(this_client, reg_addr, data, len);
4004 }
4005 /*----------------------------------------------------------------------------*/
4006 static char bmm150_i2c_write_wrapper(u8 dev_addr, u8 reg_addr, u8 *data, u8 len)
4007 {
4008 u8 buff[BMM150_BUFSIZE + 1];
4009
4010 if (len > BMM150_BUFSIZE)
4011 {
4012 return -1;
4013 }
4014
4015 buff[0] = reg_addr;
4016 memcpy(buff+1, data, len);
4017 if (i2c_master_send(this_client, buff, len+1) != (len+1))
4018 {
4019 /* I2C transfer error */
4020 return -EIO;
4021 }
4022 else
4023 {
4024 return 0;
4025 }
4026 }
4027 /*----------------------------------------------------------------------------*/
4028 static void bmm150_delay(u32 msec)
4029 {
4030 mdelay(msec);
4031 }
4032 /*----------------------------------------------------------------------------*/
4033 static int bmm150_init_client(struct i2c_client *client)
4034 {
4035 struct bmm150_i2c_data *obj = i2c_get_clientdata(client);
4036 int res = 0;
4037
4038 res = bmm150_wakeup(client);
4039 if (res < 0)
4040 {
4041 return res;
4042 }
4043 res = bmm150_checkchipid(client);
4044 if(res < 0)
4045 {
4046 return res;
4047 }
4048 MSE_LOG("check chip ID ok");
4049
4050 //bmm150 api init
4051 obj->device.bus_read = bmm150_i2c_read_wrapper;
4052 obj->device.bus_write = bmm150_i2c_write_wrapper;
4053 obj->device.delay_msec = bmm150_delay;
4054 bmm150api_init(&obj->device);
4055
4056 /* now it's power on which is considered as resuming from suspend */
4057 obj->op_mode = BMM150_SUSPEND_MODE;
4058 obj->odr = BMM150_REGULAR_DR;
4059 obj->rept_xy = BMM150_REGULAR_REPXY;
4060 obj->rept_z = BMM150_REGULAR_REPZ;
4061
4062 res = bmm150api_set_functional_state(BMM150_SUSPEND_MODE);
4063 if (res)
4064 {
4065 return -EIO;
4066 }
4067
4068 return 0;
4069 }
4070 /*----------------------------------------------------------------------------*/
4071 #if 0
4072 static struct platform_driver bmm150_sensor_driver = {
4073 .probe = bmm150_probe,
4074 .remove = bmm150_remove,
4075 .driver = {
4076 .name = "msensor",
4077 //.owner = THIS_MODULE,
4078 }
4079 };
4080 #endif
4081
4082 #ifdef CONFIG_OF
4083 static const struct of_device_id bmm150_of_match[] = {
4084 { .compatible = "mediatek,msensor", },
4085 {},
4086 };
4087 #endif
4088
4089 static struct platform_driver bmm150_sensor_driver =
4090 {
4091 .probe = bmm150_probe,
4092 .remove = bmm150_remove,
4093 .driver =
4094 {
4095 .name = "msensor",
4096 #ifdef CONFIG_OF
4097 .of_match_table = bmm150_of_match,
4098 #endif
4099 }
4100 };
4101
4102 /*----------------------------------------------------------------------------*/
4103 static int bmm150_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
4104 {
4105 struct i2c_client *new_client;
4106 struct bmm150_i2c_data *data;
4107 int err = 0;
4108 struct hwmsen_object sobj_m, sobj_o;
4109 #ifdef BMC150_M4G
4110 struct hwmsen_object sobj_g;
4111 #endif //BMC150_M4G
4112 #ifdef BMC150_VRV
4113 struct hwmsen_object sobj_vrv;
4114 #endif //BMC150_VRV
4115 #ifdef BMC150_VLA
4116 struct hwmsen_object sobj_vla;
4117 #endif //BMC150_VLA
4118 #ifdef BMC150_VG
4119 struct hwmsen_object sobj_vg;
4120 #endif //BMC150_VG
4121
4122 if(!(data = kmalloc(sizeof(struct bmm150_i2c_data), GFP_KERNEL)))
4123 {
4124 err = -ENOMEM;
4125 goto exit;
4126 }
4127 memset(data, 0, sizeof(struct bmm150_i2c_data));
4128
4129 data->hw = get_cust_mag_hw();
4130 if(err = hwmsen_get_convert(data->hw->direction, &data->cvt))
4131 {
4132 MSE_ERR("invalid direction: %d\n", data->hw->direction);
4133 goto exit;
4134 }
4135 atomic_set(&data->layout, data->hw->direction);
4136 atomic_set(&data->trace, 0);
4137
4138 mutex_init(&sensor_data_mutex);
4139 mutex_init(&uplink_event_flag_mutex);
4140
4141 init_waitqueue_head(&uplink_event_flag_wq);
4142
4143 data->client = client;
4144 new_client = data->client;
4145 i2c_set_clientdata(new_client, data);
4146
4147 this_client = new_client;
4148
4149 //initial client
4150 if (err = bmm150_init_client(this_client))
4151 {
4152 MSE_ERR("fail to initialize client");
4153 goto exit_client_failed;
4154 }
4155
4156 /* Register sysfs attribute */
4157 if(err = bmm150_create_attr(&bmm150_sensor_driver.driver))
4158 {
4159 MSE_ERR("create attribute err = %d\n", err);
4160 goto exit_sysfs_create_group_failed;
4161 }
4162
4163 if(err = misc_register(&bmm150_device))
4164 {
4165 MSE_ERR("bmm150_device register failed\n");
4166 goto exit_misc_device_register_failed;
4167 }
4168
4169 sobj_m.self = data;
4170 sobj_m.polling = 1;
4171 sobj_m.sensor_operate = bmm150_operate;
4172 if(err = hwmsen_attach(ID_MAGNETIC, &sobj_m))
4173 {
4174 MSE_ERR( "attach fail = %d\n", err);
4175 goto exit_kfree;
4176 }
4177
4178 sobj_o.self = data;
4179 sobj_o.polling = 1;
4180 sobj_o.sensor_operate = bmm150_orientation_operate;
4181 if(err = hwmsen_attach(ID_ORIENTATION, &sobj_o))
4182 {
4183 MSE_ERR( "attach fail = %d\n", err);
4184 goto exit_kfree;
4185 }
4186
4187 #ifdef BMC150_M4G
4188 sobj_g.self = data;
4189 sobj_g.polling = 1;
4190 sobj_g.sensor_operate = bmm150_m4g_operate;
4191 if(err = hwmsen_attach(ID_GYROSCOPE, &sobj_g))
4192 {
4193 MSE_ERR( "attach fail = %d\n", err);
4194 goto exit_kfree;
4195 }
4196 #endif //BMC150_M4G
4197
4198 #ifdef BMC150_VRV
4199 sobj_vrv.self = data;
4200 sobj_vrv.polling = 1;
4201 sobj_vrv.sensor_operate = bmm150_vrv_operate;
4202 if(err = hwmsen_attach(ID_ROTATION_VECTOR, &sobj_vrv))
4203 {
4204 MSE_ERR( "attach fail = %d\n", err);
4205 goto exit_kfree;
4206 }
4207 #endif //BMC150_VRV
4208
4209 #ifdef BMC150_VLA
4210 sobj_vla.self = data;
4211 sobj_vla.polling = 1;
4212 sobj_vla.sensor_operate = bmm150_vla_operate;
4213 if(err = hwmsen_attach(ID_LINEAR_ACCELERATION, &sobj_vla))
4214 {
4215 MSE_ERR( "attach fail = %d\n", err);
4216 goto exit_kfree;
4217 }
4218 #endif //BMC150_VLA
4219
4220 #ifdef BMC150_VG
4221 sobj_vg.self = data;
4222 sobj_vg.polling = 1;
4223 sobj_vg.sensor_operate = bmm150_vg_operate;
4224 if(err = hwmsen_attach(ID_GRAVITY, &sobj_vg))
4225 {
4226 MSE_ERR( "attach fail = %d\n", err);
4227 goto exit_kfree;
4228 }
4229 #endif //BMC150_VG
4230
4231 #if CONFIG_HAS_EARLYSUSPEND
4232 data->early_drv.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 1,
4233 data->early_drv.suspend = bmm150_early_suspend,
4234 data->early_drv.resume = bmm150_late_resume,
4235 register_early_suspend(&data->early_drv);
4236 #endif
4237
4238 MSE_LOG("%s: OK\n", __func__);
4239 return 0;
4240
4241 exit_client_failed:
4242 exit_sysfs_create_group_failed:
4243 exit_misc_device_register_failed:
4244 exit_kfree:
4245 kfree(data);
4246 exit:
4247 MSE_ERR( "%s: err = %d\n", __func__, err);
4248 return err;
4249 }
4250 /*----------------------------------------------------------------------------*/
4251 static int bmm150_i2c_remove(struct i2c_client *client)
4252 {
4253 struct bmm150_i2c_data *obj = i2c_get_clientdata(client);
4254
4255 if(bmm150_delete_attr(&bmm150_sensor_driver.driver))
4256 {
4257 MSE_ERR( "bmm150_delete_attr fail");
4258 }
4259
4260 #ifdef CONFIG_HAS_EARLYSUSPEND
4261 unregister_early_suspend(&obj->early_drv);
4262 #endif
4263 bmm150api_set_functional_state(BMM150_SUSPEND_MODE);
4264 this_client = NULL;
4265 i2c_unregister_device(client);
4266
4267 kfree(obj);
4268 misc_deregister(&bmm150_device);
4269 return 0;
4270 }
4271 /*----------------------------------------------------------------------------*/
4272
4273 static struct i2c_driver bmm150_i2c_driver = {
4274 .driver = {
4275 .name = BMM150_DEV_NAME,
4276 },
4277 .probe = bmm150_i2c_probe,
4278 .remove = bmm150_i2c_remove,
4279 #if !defined(CONFIG_HAS_EARLYSUSPEND)
4280 .suspend = bmm150_suspend,
4281 .resume = bmm150_resume,
4282 #endif
4283 .id_table = bmm150_i2c_id,
4284 };
4285
4286 /*----------------------------------------------------------------------------*/
4287 static int bmm150_probe(struct platform_device *pdev)
4288 {
4289 struct mag_hw *hw = get_cust_mag_hw();
4290
4291 bmm150_power(hw, 1);
4292 if(i2c_add_driver(&bmm150_i2c_driver))
4293 {
4294 MSE_ERR("add driver error\n");
4295 return -1;
4296 }
4297
4298 return 0;
4299 }
4300 /*----------------------------------------------------------------------------*/
4301 static int bmm150_remove(struct platform_device *pdev)
4302 {
4303 struct mag_hw *hw = get_cust_mag_hw();
4304
4305 i2c_del_driver(&bmm150_i2c_driver);
4306 bmm150_power(hw, 0);
4307 return 0;
4308 }
4309 /*----------------------------------------------------------------------------*/
4310 static int __init bmm150_init(void)
4311 {
4312 struct mag_hw *hw = get_cust_mag_hw();
4313
4314 i2c_register_board_info(hw->i2c_num, &bmm150_i2c_info, 1);
4315 if(platform_driver_register(&bmm150_sensor_driver))
4316 {
4317 MSE_ERR("failed to register driver");
4318 return -ENODEV;
4319 }
4320 return 0;
4321 }
4322 /*----------------------------------------------------------------------------*/
4323 static void __exit bmm150_exit(void)
4324 {
4325 platform_driver_unregister(&bmm150_sensor_driver);
4326 }
4327 /*----------------------------------------------------------------------------*/
4328 module_init(bmm150_init);
4329 module_exit(bmm150_exit);
4330
4331 MODULE_AUTHOR("hongji.zhou@bosch-sensortec.com");
4332 MODULE_DESCRIPTION("bmm150 compass driver");
4333 MODULE_LICENSE("GPLv2");
4334