1 /* bmm150.c - bmm150 compass driver
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
7 * (C) Copyright 2011 Bosch Sensortec GmbH
11 * History: V1.0 --- Driver creation
12 * V1.1 --- Add share I2C address solution
13 * V1.2 --- Fix bug that daemon can't get
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>
34 #include <mach/mt_typedefs.h>
35 #include <mach/mt_gpio.h>
36 #include <mach/mt_pm_ldo.h>
38 #define POWER_NONE_MACRO MT65XX_POWER_NONE
42 #include <linux/hwmsen_helper.h>
43 #include <linux/hwmsensor.h>
44 #include <linux/hwmsen_dev.h>
45 #include <linux/sensors_io.h>
48 /*----------------------------------------------------------------------------*/
50 * Enable the driver to block e-compass daemon on suspend
52 #define BMC150_BLOCK_DAEMON_ON_SUSPEND
53 //#undef BMC150_BLOCK_DAEMON_ON_SUSPEND
55 * Enable gyroscope feature with BMC150
60 * Enable rotation vecter feature with BMC150
66 * Enable virtual linear accelerometer feature with BMC150
72 * Enable virtual gravity feature with BMC150
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)
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)
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)
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)
102 /*----------------------------------------------------------------------------*/
103 /* BMM150 API Section */
104 /*----------------------------------------------------------------------------*/
106 #define BMM150_U16 unsigned short
107 #define BMM150_S16 signed short
108 #define BMM150_S32 signed int
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)
120 #define BMM150_BUS_RD_RETURN_TYPE char
122 #define BMM150_BUS_RD_PARAM_TYPES\
123 unsigned char, unsigned char, unsigned char *, unsigned char
125 #define BMM150_BUS_RD_PARAM_ORDER (device_addr, register_addr, register_data)
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)
131 #define BMM150_DELAY_RETURN_TYPE void
133 #define BMM150_DELAY_PARAM_TYPES unsigned int
135 #define BMM150_DELAY_FUNC(delay_in_msec)\
136 delay_func(delay_in_msec)
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
149 #define BMM150_RETURN_FUNCTION_TYPE char
150 #define BMM150_I2C_ADDRESS 0x10
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
159 /* Fixed Data Registers */
160 #define BMM150_CHIP_ID 0x40
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
172 /* Status Registers */
173 #define BMM150_INT_STAT 0x4A
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
420 #define BMM150_X_AXIS 0
421 #define BMM150_Y_AXIS 1
422 #define BMM150_Z_AXIS 2
423 #define BMM150_RESISTANCE 3
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
440 #define BMM150_NORMAL_MODE 0x00
441 #define BMM150_FORCED_MODE 0x01
442 #define BMM150_SUSPEND_MODE 0x02
443 #define BMM150_SLEEP_MODE 0x03
445 #define BMM150_ADVANCED_SELFTEST_OFF 0
446 #define BMM150_ADVANCED_SELFTEST_NEGATIVE 2
447 #define BMM150_ADVANCED_SELFTEST_POSITIVE 3
449 #define BMM150_NEGATIVE_SATURATION_Z -32767
450 #define BMM150_POSITIVE_SATURATION_Z 32767
452 #define BMM150_SPI_RD_MASK 0x80
453 #define BMM150_READ_SET 0x01
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
460 #define BMM150_WR_FUNC_PTR\
461 char (*bus_write)(unsigned char, unsigned char,\
462 unsigned char *, unsigned char)
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
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
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
488 /* Conversion factors*/
489 #define BMM150_CONVFACTOR_LSB_UT 6
492 #define BMM150_GET_BITSLICE(regvar, bitname)\
493 ((regvar & bitname##__MSK) >> bitname##__POS)
496 #define BMM150_SET_BITSLICE(regvar, bitname, val)\
497 ((regvar & ~bitname##__MSK) | ((val<<bitname##__POS)&bitname##__MSK))
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
507 #define BMM150_PRESETMODE_LOWPOWER 1
508 #define BMM150_PRESETMODE_REGULAR 2
509 #define BMM150_PRESETMODE_HIGHACCURACY 3
510 #define BMM150_PRESETMODE_ENHANCED 4
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
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
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
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
541 /*user defined Structures*/
542 struct bmm150api_mdata
{
546 BMM150_U16 resistance
;
548 struct bmm150api_mdata_s32
{
552 BMM150_U16 resistance
;
554 struct bmm150api_mdata_float
{
558 BMM150_U16 resistance
;
562 unsigned char company_id
;
563 unsigned char dev_addr
;
567 void(*delay_msec
)(BMM150_MDELAY_DATA_TYPE
);
580 unsigned char dig_xy1
;
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
);
593 BMM150_RETURN_FUNCTION_TYPE
bmm150api_read_mdataXYZ_float(
594 struct bmm150api_mdata_float
*mdata
);
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
);
607 float bmm150api_compensate_X_float(
608 BMM150_S16 mdata_x
, BMM150_U16 data_R
);
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
);
615 float bmm150api_compensate_Y_float(
616 BMM150_S16 mdata_y
, BMM150_U16 data_R
);
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
);
623 float bmm150api_compensate_Z_float(
624 BMM150_S16 mdata_z
, BMM150_U16 data_R
);
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(
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(
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);
669 static struct bmm150api
*p_bmm150
;
671 BMM150_RETURN_FUNCTION_TYPE
bmm150api_init(struct bmm150api
*bmm150
)
673 BMM150_RETURN_FUNCTION_TYPE comres
= 0;
674 unsigned char a_data_u8r
[2];
677 p_bmm150
->dev_addr
= BMM150_I2C_ADDRESS
;
679 /* set device from suspend into sleep mode */
680 bmm150api_set_powermode(BMM150_ON
);
682 /* wait two millisecond for bmc to settle */
683 p_bmm150
->delay_msec(BMM150_DELAY_SETTLING_TIME
);
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];
690 /* Function to initialise trim values */
691 bmm150api_init_trim_registers();
692 bmm150api_set_presetmode(BMM150_PRESETMODE_REGULAR
);
696 BMM150_RETURN_FUNCTION_TYPE
bmm150api_set_presetmode(unsigned char mode
)
698 BMM150_RETURN_FUNCTION_TYPE comres
= 0;
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
);
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
);
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
);
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
);
733 comres
= E_BMM150_OUT_OF_RANGE
;
739 BMM150_RETURN_FUNCTION_TYPE
bmm150api_set_functional_state(
740 unsigned char functional_state
)
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
;
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
);
756 comres
|= p_bmm150
->BMM150_BUS_READ_FUNC(
758 BMM150_CNTL_OPMODE__REG
,
760 v_data1_u8r
= BMM150_SET_BITSLICE(
764 comres
|= p_bmm150
->BMM150_BUS_WRITE_FUNC(
766 BMM150_CNTL_OPMODE__REG
,
770 case BMM150_SUSPEND_MODE
:
771 comres
= bmm150api_set_powermode(BMM150_OFF
);
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
);
780 comres
|= p_bmm150
->BMM150_BUS_READ_FUNC(
782 BMM150_CNTL_OPMODE__REG
,
784 v_data1_u8r
= BMM150_SET_BITSLICE(
786 BMM150_CNTL_OPMODE
, BMM150_ON
);
787 comres
|= p_bmm150
->BMM150_BUS_WRITE_FUNC(
789 BMM150_CNTL_OPMODE__REG
,
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
);
799 comres
|= p_bmm150
->BMM150_BUS_READ_FUNC(
801 BMM150_CNTL_OPMODE__REG
,
803 v_data1_u8r
= BMM150_SET_BITSLICE(
807 comres
|= p_bmm150
->BMM150_BUS_WRITE_FUNC(
809 BMM150_CNTL_OPMODE__REG
,
813 comres
= E_BMM150_OUT_OF_RANGE
;
820 BMM150_RETURN_FUNCTION_TYPE
bmm150api_get_functional_state(
821 unsigned char *functional_state
)
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
;
828 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(
830 BMM150_CNTL_OPMODE__REG
,
832 *functional_state
= BMM150_GET_BITSLICE(
833 v_data_u8r
, BMM150_CNTL_OPMODE
);
838 BMM150_RETURN_FUNCTION_TYPE
bmm150api_read_mdataXYZ(struct bmm150api_mdata
*mdata
)
840 BMM150_RETURN_FUNCTION_TYPE comres
;
842 unsigned char a_data_u8r
[8];
845 BMM150_S16 raw_dataX
;
846 BMM150_S16 raw_dataY
;
847 BMM150_S16 raw_dataZ
;
848 BMM150_U16 raw_dataR
;
851 if (p_bmm150
== BMM150_NULL
) {
852 comres
= E_BMM150_NULL_PTR
;
854 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(p_bmm150
->dev_addr
,
855 BMM150_DATAX_LSB
, a_data_u8r
, 8);
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]);
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]);
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]);
878 /* Reading data for Resistance*/
879 a_data_u8r
[6] = BMM150_GET_BITSLICE(a_data_u8r
[6],
881 raw_dataXYZ
.raw_dataR
= (BMM150_U16
)((((BMM150_U16
)
883 SHIFT_LEFT_6_POSITION
) | a_data_u8r
[6]);
885 /* Compensation for X axis */
886 mdata
->datax
= bmm150api_compensate_X(raw_dataXYZ
.raw_dataX
,
887 raw_dataXYZ
.raw_dataR
);
889 /* Compensation for Y axis */
890 mdata
->datay
= bmm150api_compensate_Y(raw_dataXYZ
.raw_dataY
,
891 raw_dataXYZ
.raw_dataR
);
893 /* Compensation for Z axis */
894 mdata
->dataz
= bmm150api_compensate_Z(raw_dataXYZ
.raw_dataZ
,
895 raw_dataXYZ
.raw_dataR
);
897 /* Output raw resistance value */
898 mdata
->resistance
= raw_dataXYZ
.raw_dataR
;
903 BMM150_RETURN_FUNCTION_TYPE
bmm150api_read_mdataXYZ_s32(
904 struct bmm150api_mdata_s32
*mdata
)
906 BMM150_RETURN_FUNCTION_TYPE comres
;
908 unsigned char a_data_u8r
[8];
911 BMM150_S16 raw_dataX
;
912 BMM150_S16 raw_dataY
;
913 BMM150_S16 raw_dataZ
;
914 BMM150_U16 raw_dataR
;
917 if (p_bmm150
== BMM150_NULL
) {
918 comres
= E_BMM150_NULL_PTR
;
920 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(p_bmm150
->dev_addr
,
921 BMM150_DATAX_LSB
, a_data_u8r
, 8);
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]);
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]);
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]);
944 /* Reading data for Resistance*/
945 a_data_u8r
[6] = BMM150_GET_BITSLICE(a_data_u8r
[6],
947 raw_dataXYZ
.raw_dataR
= (BMM150_U16
)((((BMM150_U16
)
949 SHIFT_LEFT_6_POSITION
) | a_data_u8r
[6]);
951 /* Compensation for X axis */
952 mdata
->datax
= bmm150api_compensate_X_s32(raw_dataXYZ
.raw_dataX
,
953 raw_dataXYZ
.raw_dataR
);
955 /* Compensation for Y axis */
956 mdata
->datay
= bmm150api_compensate_Y_s32(raw_dataXYZ
.raw_dataY
,
957 raw_dataXYZ
.raw_dataR
);
959 /* Compensation for Z axis */
960 mdata
->dataz
= bmm150api_compensate_Z_s32(raw_dataXYZ
.raw_dataZ
,
961 raw_dataXYZ
.raw_dataR
);
963 /* Output raw resistance value */
964 mdata
->resistance
= raw_dataXYZ
.raw_dataR
;
970 BMM150_RETURN_FUNCTION_TYPE
bmm150api_read_mdataXYZ_float(
971 struct bmm150api_mdata_float
*mdata
)
973 BMM150_RETURN_FUNCTION_TYPE comres
;
975 unsigned char a_data_u8r
[8];
978 BMM150_S16 raw_dataX
;
979 BMM150_S16 raw_dataY
;
980 BMM150_S16 raw_dataZ
;
981 BMM150_U16 raw_dataR
;
984 if (p_bmm150
== BMM150_NULL
) {
985 comres
= E_BMM150_NULL_PTR
;
987 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(p_bmm150
->dev_addr
,
988 BMM150_DATAX_LSB
, a_data_u8r
, 8);
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]);
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]);
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]);
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
)
1016 SHIFT_LEFT_6_POSITION
) | a_data_u8r
[6]);
1018 /* Compensation for X axis */
1019 mdata
->datax
= bmm150api_compensate_X_float(raw_dataXYZ
.raw_dataX
,
1020 raw_dataXYZ
.raw_dataR
);
1022 /* Compensation for Y axis */
1023 mdata
->datay
= bmm150api_compensate_Y_float(raw_dataXYZ
.raw_dataY
,
1024 raw_dataXYZ
.raw_dataR
);
1026 /* Compensation for Z axis */
1027 mdata
->dataz
= bmm150api_compensate_Z_float(raw_dataXYZ
.raw_dataZ
,
1028 raw_dataXYZ
.raw_dataR
);
1030 /* Output raw resistance value */
1031 mdata
->resistance
= raw_dataXYZ
.raw_dataR
;
1037 BMM150_RETURN_FUNCTION_TYPE
bmm150api_read_register(unsigned char addr
,
1038 unsigned char *data
, unsigned char len
)
1040 BMM150_RETURN_FUNCTION_TYPE comres
;
1041 if (p_bmm150
== BMM150_NULL
) {
1042 comres
= E_BMM150_NULL_PTR
;
1044 comres
+= p_bmm150
->BMM150_BUS_READ_FUNC(p_bmm150
->dev_addr
,
1050 BMM150_RETURN_FUNCTION_TYPE
bmm150api_write_register(unsigned char addr
,
1051 unsigned char *data
, unsigned char len
)
1053 BMM150_RETURN_FUNCTION_TYPE comres
= 0;
1054 if (p_bmm150
== BMM150_NULL
) {
1055 comres
= E_BMM150_NULL_PTR
;
1057 comres
= p_bmm150
->BMM150_BUS_WRITE_FUNC(p_bmm150
->dev_addr
,
1063 BMM150_RETURN_FUNCTION_TYPE
bmm150api_set_selftest(unsigned char selftest
)
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
;
1070 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(
1071 p_bmm150
->dev_addr
, BMM150_CNTL_S_TEST__REG
,
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
,
1082 BMM150_RETURN_FUNCTION_TYPE
bmm150api_get_self_test_XYZ(
1083 unsigned char *self_testxyz
)
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
;
1090 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(
1091 p_bmm150
->dev_addr
, BMM150_DATAX_LSB_TESTX__REG
,
1094 v_result_u8r
= BMM150_GET_BITSLICE(a_data_u8r
[4],
1095 BMM150_DATAZ_LSB_TESTZ
);
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
));
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
));
1105 *self_testxyz
= v_result_u8r
;
1110 BMM150_RETURN_FUNCTION_TYPE
bmm150api_set_spi3(unsigned char value
)
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
;
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);
1127 BMM150_RETURN_FUNCTION_TYPE
bmm150api_set_datarate(unsigned char data_rate
)
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
;
1134 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(
1136 BMM150_CNTL_DR__REG
,
1138 v_data1_u8r
= BMM150_SET_BITSLICE(v_data1_u8r
,
1139 BMM150_CNTL_DR
, data_rate
);
1140 comres
|= p_bmm150
->BMM150_BUS_WRITE_FUNC(
1142 BMM150_CNTL_DR__REG
,
1148 BMM150_RETURN_FUNCTION_TYPE
bmm150api_get_datarate(unsigned char *data_rate
)
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
;
1155 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(
1157 BMM150_CNTL_DR__REG
,
1159 *data_rate
= BMM150_GET_BITSLICE(v_data_u8r
,
1165 BMM150_RETURN_FUNCTION_TYPE
bmm150api_perform_advanced_selftest(
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
;
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
);
1179 /* set normal accuracy mode */
1180 comres
|= bmm150api_set_repetitions_Z(BMM150_LOWPOWER_REPZ
);
1181 /* 14 repetitions Z in normal accuracy mode */
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
);
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);
1197 /* read result from positive field measurement */
1198 comres
|= bmm150api_read_mdataXYZ_s32(&mdata
);
1199 result_positive
= mdata
.dataz
;
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 */
1208 /* read result from negative field measurement */
1209 comres
|= bmm150api_read_mdataXYZ_s32(&mdata
);
1210 result_negative
= mdata
.dataz
;
1212 /* turn off self test current */
1213 comres
|= bmm150api_set_adv_selftest(
1214 BMM150_ADVANCED_SELFTEST_OFF
);
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
);
1222 /* write out difference in positive and negative field.
1223 * This should be ~ 200 mT = 3200 LSB */
1224 *diff_z
= (result_positive
- result_negative
);
1229 BMM150_RETURN_FUNCTION_TYPE
bmm150api_init_trim_registers(void)
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);
1246 /* shorts can not be recasted into (unsigned char*)
1247 * due to possible mixup between trim data
1248 * arrangement and memory arrangement */
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)
1254 SHIFT_LEFT_8_POSITION
) | a_data_u8r
[0]);
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]);
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]);
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]);
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]);
1283 BMM150_RETURN_FUNCTION_TYPE
bmm150api_set_adv_selftest(unsigned char adv_selftest
)
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
;
1290 switch (adv_selftest
) {
1291 case BMM150_ADVANCED_SELFTEST_OFF
:
1292 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(
1294 BMM150_CNTL_ADV_ST__REG
,
1296 v_data1_u8r
= BMM150_SET_BITSLICE(
1299 BMM150_ADVANCED_SELFTEST_OFF
);
1300 comres
|= p_bmm150
->BMM150_BUS_WRITE_FUNC(
1302 BMM150_CNTL_ADV_ST__REG
,
1305 case BMM150_ADVANCED_SELFTEST_POSITIVE
:
1306 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(
1308 BMM150_CNTL_ADV_ST__REG
,
1310 v_data1_u8r
= BMM150_SET_BITSLICE(
1313 BMM150_ADVANCED_SELFTEST_POSITIVE
);
1314 comres
|= p_bmm150
->BMM150_BUS_WRITE_FUNC(
1316 BMM150_CNTL_ADV_ST__REG
,
1319 case BMM150_ADVANCED_SELFTEST_NEGATIVE
:
1320 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(
1322 BMM150_CNTL_ADV_ST__REG
,
1324 v_data1_u8r
= BMM150_SET_BITSLICE(
1327 BMM150_ADVANCED_SELFTEST_NEGATIVE
);
1328 comres
|= p_bmm150
->BMM150_BUS_WRITE_FUNC(
1330 BMM150_CNTL_ADV_ST__REG
,
1340 BMM150_RETURN_FUNCTION_TYPE
bmm150api_get_adv_selftest(unsigned char *adv_selftest
)
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
;
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
);
1355 BMM150_RETURN_FUNCTION_TYPE
bmm150api_get_presetmode(
1356 unsigned char *mode
)
1358 BMM150_RETURN_FUNCTION_TYPE comres
= 0;
1359 unsigned char data_rate
= 0;
1360 unsigned char repetitionsxy
= 0;
1361 unsigned char repetitionsz
= 0;
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
;
1374 if ((data_rate
== BMM150_REGULAR_DR
) && (
1375 repetitionsxy
== BMM150_REGULAR_REPXY
) && (
1376 repetitionsz
== BMM150_REGULAR_REPZ
)) {
1377 *mode
= BMM150_PRESETMODE_REGULAR
;
1379 if ((data_rate
== BMM150_HIGHACCURACY_DR
) && (
1380 repetitionsxy
== BMM150_HIGHACCURACY_REPXY
) && (
1381 repetitionsz
== BMM150_HIGHACCURACY_REPZ
)) {
1382 *mode
= BMM150_PRESETMODE_HIGHACCURACY
;
1384 if ((data_rate
== BMM150_ENHANCED_DR
) && (
1385 repetitionsxy
== BMM150_ENHANCED_REPXY
) && (
1386 repetitionsz
== BMM150_ENHANCED_REPZ
)) {
1387 *mode
= BMM150_PRESETMODE_ENHANCED
;
1389 *mode
= E_BMM150_UNDEFINED_MODE
;
1397 BMM150_RETURN_FUNCTION_TYPE
bmm150api_get_powermode(unsigned char *mode
)
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
;
1404 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(
1406 BMM150_POWER_CNTL_PCB__REG
,
1408 *mode
= BMM150_GET_BITSLICE(v_data_u8r
,
1409 BMM150_POWER_CNTL_PCB
);
1414 BMM150_RETURN_FUNCTION_TYPE
bmm150api_set_powermode(unsigned char mode
)
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
;
1421 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(
1423 BMM150_POWER_CNTL_PCB__REG
,
1425 v_data_u8r
= BMM150_SET_BITSLICE(v_data_u8r
,
1426 BMM150_POWER_CNTL_PCB
, mode
);
1427 comres
|= p_bmm150
->BMM150_BUS_WRITE_FUNC(
1429 BMM150_POWER_CNTL_PCB__REG
,
1435 BMM150_RETURN_FUNCTION_TYPE
bmm150api_get_repetitions_XY(
1436 unsigned char *no_repetitions_xy
)
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
;
1443 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(
1445 BMM150_NO_REPETITIONS_XY
,
1447 *no_repetitions_xy
= v_data_u8r
;
1452 BMM150_RETURN_FUNCTION_TYPE
bmm150api_set_repetitions_XY(
1453 unsigned char no_repetitions_xy
)
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
;
1460 v_data_u8r
= no_repetitions_xy
;
1461 comres
= p_bmm150
->BMM150_BUS_WRITE_FUNC(
1463 BMM150_NO_REPETITIONS_XY
,
1469 BMM150_RETURN_FUNCTION_TYPE
bmm150api_get_repetitions_Z(
1470 unsigned char *no_repetitions_z
)
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
;
1477 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(
1479 BMM150_NO_REPETITIONS_Z
,
1481 *no_repetitions_z
= v_data_u8r
;
1486 BMM150_RETURN_FUNCTION_TYPE
bmm150api_set_repetitions_Z(
1487 unsigned char no_repetitions_z
)
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
;
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);
1501 BMM150_S16
bmm150api_compensate_X(BMM150_S16 mdata_x
, BMM150_U16 data_R
)
1503 BMM150_S16 inter_retval
;
1504 if (mdata_x
!= BMM150_FLIP_OVERFLOW_ADCVAL
/* no overflow */
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
)
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);
1523 inter_retval
= BMM150_OVERFLOW_OUTPUT
;
1525 return inter_retval
;
1528 BMM150_S32
bmm150api_compensate_X_s32 (BMM150_S16 mdata_x
, BMM150_U16 data_R
)
1532 retval
= bmm150api_compensate_X(mdata_x
, data_R
);
1533 if (retval
== (BMM150_S32
)BMM150_OVERFLOW_OUTPUT
)
1534 retval
= BMM150_OVERFLOW_OUTPUT_S32
;
1539 float bmm150api_compensate_X_float (BMM150_S16 mdata_x
, BMM150_U16 data_R
)
1542 if (mdata_x
!= BMM150_FLIP_OVERFLOW_ADCVAL
/* no overflow */
1545 inter_retval
= ((((float)p_bmm150
->dig_xyz1
)*16384.0f
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
;
1556 inter_retval
= BMM150_OVERFLOW_OUTPUT_FLOAT
;
1558 return inter_retval
;
1562 BMM150_S16
bmm150api_compensate_Y(BMM150_S16 mdata_y
, BMM150_U16 data_R
)
1564 BMM150_S16 inter_retval
;
1565 if (mdata_y
!= BMM150_FLIP_OVERFLOW_ADCVAL
/* no overflow */
1567 inter_retval
= ((BMM150_S16
)(((BMM150_U16
)(((
1568 (BMM150_S32
)p_bmm150
->dig_xyz1
) << 14) /
1570 data_R
: p_bmm150
->dig_xyz1
))) -
1571 ((BMM150_U16
)0x4000)));
1572 inter_retval
= ((BMM150_S16
)((((BMM150_S32
)mdata_y
) *
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))))
1584 (((BMM150_S16
)p_bmm150
->dig_y1
) << 3);
1587 inter_retval
= BMM150_OVERFLOW_OUTPUT
;
1589 return inter_retval
;
1592 BMM150_S32
bmm150api_compensate_Y_s32 (BMM150_S16 mdata_y
, BMM150_U16 data_R
)
1596 retval
= bmm150api_compensate_Y(mdata_y
, data_R
);
1597 if (retval
== BMM150_OVERFLOW_OUTPUT
)
1598 retval
= BMM150_OVERFLOW_OUTPUT_S32
;
1603 float bmm150api_compensate_Y_float(BMM150_S16 mdata_y
, BMM150_U16 data_R
)
1606 if (mdata_y
!= BMM150_FLIP_OVERFLOW_ADCVAL
/* no overflow */
1609 inter_retval
= ((((float)p_bmm150
->dig_xyz1
)*16384.0f
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
;
1620 /* overflow, set output to 0.0f */
1621 inter_retval
= BMM150_OVERFLOW_OUTPUT_FLOAT
;
1623 return inter_retval
;
1627 BMM150_S16
bmm150api_compensate_Z(BMM150_S16 mdata_z
, BMM150_U16 data_R
)
1630 if ((mdata_z
!= BMM150_HALL_OVERFLOW_ADCVAL
) /* no overflow */
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
) -
1636 p_bmm150
->dig_xyz1
))))>>2)) /
1638 ((BMM150_S16
)(((((BMM150_S32
)
1640 ((((BMM150_S16
)data_R
) << 1)))+
1642 /* saturate result to +/- 2 mT */
1643 if (retval
> BMM150_POSITIVE_SATURATION_Z
) {
1644 retval
= BMM150_POSITIVE_SATURATION_Z
;
1646 if (retval
< BMM150_NEGATIVE_SATURATION_Z
)
1647 retval
= BMM150_NEGATIVE_SATURATION_Z
;
1651 retval
= BMM150_OVERFLOW_OUTPUT
;
1653 return (BMM150_S16
)retval
;
1656 BMM150_S32
bmm150api_compensate_Z_s32(BMM150_S16 mdata_z
, BMM150_U16 data_R
)
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)) /
1665 ((BMM150_S16
)(((((BMM150_S32
)p_bmm150
->dig_z1
) *
1666 ((((BMM150_S16
)data_R
) << 1)))+(1<<15))>>16))));
1668 retval
= BMM150_OVERFLOW_OUTPUT_S32
;
1674 float bmm150api_compensate_Z_float (BMM150_S16 mdata_z
, BMM150_U16 data_R
)
1677 if (mdata_z
!= BMM150_HALL_OVERFLOW_ADCVAL
/* no overflow */
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;
1684 /* overflow, set output to 0.0f */
1685 inter_retval
= BMM150_OVERFLOW_OUTPUT_FLOAT
;
1687 return inter_retval
;
1691 BMM150_RETURN_FUNCTION_TYPE
bmm150api_set_control_measurement_x(
1692 unsigned char enable_disable
)
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
;
1699 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(
1701 BMM150_SENS_CNTL_CHANNELX__REG
,
1703 v_data1_u8r
= BMM150_SET_BITSLICE(v_data1_u8r
,
1704 BMM150_SENS_CNTL_CHANNELX
,
1706 comres
|= p_bmm150
->BMM150_BUS_WRITE_FUNC(
1708 BMM150_SENS_CNTL_CHANNELX__REG
,
1714 BMM150_RETURN_FUNCTION_TYPE
bmm150api_set_control_measurement_y(
1715 unsigned char enable_disable
)
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
;
1722 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(
1724 BMM150_SENS_CNTL_CHANNELY__REG
,
1726 v_data1_u8r
= BMM150_SET_BITSLICE(
1728 BMM150_SENS_CNTL_CHANNELY
,
1730 comres
|= p_bmm150
->BMM150_BUS_WRITE_FUNC(
1732 BMM150_SENS_CNTL_CHANNELY__REG
,
1738 BMM150_RETURN_FUNCTION_TYPE
bmm150api_soft_reset(void)
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
;
1745 v_data_u8r
= BMM150_ON
;
1747 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(
1749 BMM150_POWER_CNTL_SRST7__REG
,
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(
1756 BMM150_POWER_CNTL_SRST7__REG
, &v_data_u8r
, 1);
1758 comres
|= p_bmm150
->BMM150_BUS_READ_FUNC(
1760 BMM150_POWER_CNTL_SRST1__REG
,
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(
1767 BMM150_POWER_CNTL_SRST1__REG
,
1770 p_bmm150
->delay_msec(BMM150_DELAY_SOFTRESET
);
1775 BMM150_RETURN_FUNCTION_TYPE
bmm150api_get_raw_xyz(struct bmm150api_mdata
*mdata
)
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
;
1782 comres
= p_bmm150
->BMM150_BUS_READ_FUNC(p_bmm150
->dev_addr
,
1783 BMM150_DATAX_LSB
, a_data_u8r
, 6);
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
)
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
)
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
)
1809 /*----------------------------------------------------------------------------*/
1810 /* End of API Section */
1811 /*----------------------------------------------------------------------------*/
1813 /*----------------------------------------------------------------------------*/
1815 #define BMM150_DEV_NAME "bmm150"
1816 /*----------------------------------------------------------------------------*/
1818 #define SENSOR_CHIP_ID_BMM (0x32)
1820 #define BMM150_DEFAULT_DELAY 100
1821 #define BMM150_BUFSIZE 0x20
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)
1828 static struct i2c_client
*this_client
= NULL
;
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
];
1839 #if defined(BMC150_VG)
1840 static int vg_data
[CALIBRATION_DATA_SIZE
];
1843 static struct mutex sensor_data_mutex
;
1844 static DECLARE_WAIT_QUEUE_HEAD(uplink_event_flag_wq
);
1846 static int bmm150d_delay
= BMM150_DEFAULT_DELAY
;
1848 static int m4g_delay
= BMM150_DEFAULT_DELAY
;
1851 static int vrv_delay
= BMM150_DEFAULT_DELAY
;
1854 static int vla_delay
= BMM150_DEFAULT_DELAY
;
1858 static int vg_delay
= BMM150_DEFAULT_DELAY
;
1861 static atomic_t m_flag
= ATOMIC_INIT(0);
1862 static atomic_t o_flag
= ATOMIC_INIT(0);
1864 static atomic_t g_flag
= ATOMIC_INIT(0);
1867 static atomic_t vrv_flag
= ATOMIC_INIT(0);
1870 static atomic_t vla_flag
= ATOMIC_INIT(0);
1873 static atomic_t vg_flag
= ATOMIC_INIT(0);
1876 #ifdef BMC150_BLOCK_DAEMON_ON_SUSPEND
1877 static atomic_t driver_suspend_flag
= ATOMIC_INIT(0);
1878 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
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 */
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 */
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,
1904 BMMDRV_ULEVT_FLAG_ALL
= 0xffff
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
)};
1912 /*----------------------------------------------------------------------------*/
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,
1922 /*----------------------------------------------------------------------------*/
1923 struct bmm150_i2c_data
{
1924 struct i2c_client
*client
;
1928 struct hwmsen_convert cvt
;
1930 struct bmm150api device
;
1938 #if defined(CONFIG_HAS_EARLYSUSPEND)
1939 struct early_suspend early_drv
;
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
)
1949 static unsigned int power_on
= 0;
1951 if(hw
->power_id
!= POWER_NONE_MACRO
)
1953 MSE_LOG("power %s\n", on
? "on" : "off");
1956 MSE_LOG("ignore power control: %d\n", on
);
1960 if(!hwPowerOn(hw
->power_id
, hw
->power_vol
, "bmm150"))
1962 MSE_ERR( "power on fails!!\n");
1967 if(!hwPowerDown(hw
->power_id
, "bmm150"))
1969 MSE_ERR( "power off fail!!\n");
1976 // Daemon application save the data
1977 static int ECS_SaveData(int buf
[CALIBRATION_DATA_SIZE
])
1980 struct bmm150_i2c_data
*data
= i2c_get_clientdata(this_client
);
1983 mutex_lock(&sensor_data_mutex
);
1986 case 2: /* SENSOR_HANDLE_MAGNETIC_FIELD */
1987 memcpy(sensor_data
+4, buf
+1, 4*sizeof(int));
1989 case 3: /* SENSOR_HANDLE_ORIENTATION */
1990 memcpy(sensor_data
+8, buf
+1, 4*sizeof(int));
1993 case 4: /* SENSOR_HANDLE_GYROSCOPE */
1994 memcpy(m4g_data
, buf
+1, 4*sizeof(int));
1998 case 11: /* SENSOR_HANDLE_ROTATION_VECTOR */
1999 memcpy(m4g_data
+4, buf
+1, 4*sizeof(int));
2003 case 10: /* SENSOR_HANDLE_LINEAR_ACCELERATION */
2004 memcpy(vla_data
, buf
+1, 4*sizeof(int));
2008 case 9: /* SENSOR_HANDLE_GRAVITY */
2009 memcpy(vg_data
, buf
+1, 4*sizeof(int));
2015 mutex_unlock(&sensor_data_mutex
);
2018 if(atomic_read(&data
->trace
) & MMC_HWM_DEBUG
)
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]);
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]);
2048 /*----------------------------------------------------------------------------*/
2049 static int ECS_GetRawData(int data
[3])
2051 struct bmm150api_mdata_s32 mdata
;
2052 struct bmm150_i2c_data
*obj
= i2c_get_clientdata(this_client
);
2054 u8 databuf
[2] = {BMM150_CONTROL
, 0x02};
2056 bmm150api_read_mdataXYZ_s32(&mdata
);
2058 data
[0] = mdata
.datax
/16;
2059 data
[1] = mdata
.datay
/16;
2060 data
[2] = mdata
.dataz
/16;
2062 /* measure magnetic field for next sample */
2063 if (obj
->op_mode
== BMM150_SUSPEND_MODE
)
2065 /* power on firstly */
2066 bmm150api_set_powermode(BMM150_ON
);
2068 /* special treat of forced mode
2069 * for optimization */
2070 i2c_master_send(this_client
, databuf
, 2);
2071 obj
->op_mode
= BMM150_SLEEP_MODE
;
2075 /*----------------------------------------------------------------------------*/
2076 static int bmm150_ReadChipInfo(char *buf
, int bufsize
)
2078 if((!buf
)||(bufsize
<= BMM150_BUFSIZE
-1))
2088 sprintf(buf
, "BMM150 Chip");
2091 /*----------------------------------------------------------------------------*/
2092 static void bmm150_SetPowerMode(struct i2c_client
*client
, bool enable
)
2094 struct bmm150_i2c_data
*obj
= i2c_get_clientdata(client
);
2098 if (enable
== FALSE
)
2100 if (bmm150api_set_functional_state(BMM150_SUSPEND_MODE
) != 0)
2102 MSE_ERR("fail to suspend sensor");
2105 obj
->op_mode
= BMM150_SUSPEND_MODE
;
2109 if (obj
->op_mode
== BMM150_SUSPEND_MODE
)
2111 obj
->op_mode
= BMM150_SLEEP_MODE
;
2113 bmm150_restore_hw_cfg(client
);
2117 /*----------------------------------------------------------------------------*/
2118 /* Driver Attributes Functions Section */
2119 /*----------------------------------------------------------------------------*/
2120 static ssize_t
show_chipinfo_value(struct device_driver
*ddri
, char *buf
)
2122 char strbuf
[BMM150_BUFSIZE
];
2123 bmm150_ReadChipInfo(strbuf
, BMM150_BUFSIZE
);
2124 return sprintf(buf
, "%s\n", strbuf
);
2126 /*----------------------------------------------------------------------------*/
2127 static ssize_t
show_sensordata_value(struct device_driver
*ddri
, char *buf
)
2130 char strbuf
[BMM150_BUFSIZE
];
2132 ECS_GetRawData(sensordata
);
2133 sprintf(strbuf
, "%d %d %d\n", sensordata
[0],sensordata
[1],sensordata
[2]);
2134 return sprintf(buf
, "%s\n", strbuf
);
2136 /*----------------------------------------------------------------------------*/
2137 static ssize_t
show_posturedata_value(struct device_driver
*ddri
, char *buf
)
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]);
2146 return sprintf(buf
, "%s\n", strbuf
);;
2149 /*----------------------------------------------------------------------------*/
2150 static ssize_t
show_layout_value(struct device_driver
*ddri
, char *buf
)
2152 struct bmm150_i2c_data
*data
= i2c_get_clientdata(this_client
);
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]);
2158 /*----------------------------------------------------------------------------*/
2159 static ssize_t
store_layout_value(struct device_driver
*ddri
, char *buf
, size_t count
)
2161 struct i2c_client
*client
= this_client
;
2162 struct bmm150_i2c_data
*data
= i2c_get_clientdata(this_client
);
2166 if(1 == sscanf(buf
, "%d", &layout
))
2168 atomic_set(&data
->layout
, layout
);
2169 if(!hwmsen_get_convert(layout
, &data
->cvt
))
2171 MSE_ERR( "HWMSEN_GET_CONVERT function error!\r\n");
2173 else if(!hwmsen_get_convert(data
->hw
->direction
, &data
->cvt
))
2175 MSE_ERR( "invalid layout: %d, restore to %d\n", layout
, data
->hw
->direction
);
2179 MSE_ERR( "invalid layout: (%d, %d)\n", layout
, data
->hw
->direction
);
2180 hwmsen_get_convert(0, &data
->cvt
);
2185 MSE_ERR( "invalid format = '%s'\n", buf
);
2190 /*----------------------------------------------------------------------------*/
2191 static ssize_t
show_status_value(struct device_driver
*ddri
, char *buf
)
2193 struct bmm150_i2c_data
*data
= i2c_get_clientdata(this_client
);
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
);
2204 len
+= snprintf(buf
+len
, PAGE_SIZE
-len
, "CUST: NULL\n");
2209 /*----------------------------------------------------------------------------*/
2210 static ssize_t
show_trace_value(struct device_driver
*ddri
, char *buf
)
2213 struct bmm150_i2c_data
*obj
= i2c_get_clientdata(this_client
);
2217 MSE_ERR( "bmm150_i2c_data is null!!\n");
2221 res
= snprintf(buf
, PAGE_SIZE
, "0x%04X\n", atomic_read(&obj
->trace
));
2224 /*----------------------------------------------------------------------------*/
2225 static ssize_t
store_trace_value(struct device_driver
*ddri
, char *buf
, size_t count
)
2227 struct bmm150_i2c_data
*obj
= i2c_get_clientdata(this_client
);
2232 MSE_ERR( "bmm150_i2c_data is null!!\n");
2236 if(1 == sscanf(buf
, "0x%x", &trace
))
2238 atomic_set(&obj
->trace
, trace
);
2242 MSE_ERR( "invalid content: '%s', length = %d\n", buf
, count
);
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
)
2253 struct bmm150_i2c_data
*obj
= i2c_get_clientdata(this_client
);
2255 struct bmm150api_mdata_s32 mdata
;
2258 bmm150api_read_mdataXYZ_s32(&mdata
);
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
;
2265 return sprintf(buf
, "%d %d %d\n", mag
[BMM150_AXIS_X
], mag
[BMM150_AXIS_Y
], mag
[BMM150_AXIS_Z
]);
2267 /*----------------------------------------------------------------------------*/
2268 static ssize_t
show_cpsopmode_value(struct device_driver
*ddri
, char *buf
)
2270 struct bmm150_i2c_data
*obj
= i2c_get_clientdata(this_client
);
2275 bmm150api_get_powermode(&power_mode
);
2278 bmm150api_get_functional_state(&op_mode
);
2282 op_mode
= BMM150_SUSPEND_MODE
;
2285 MSE_LOG("op_mode: %d", op_mode
);
2287 return sprintf(buf
, "%d\n", op_mode
);
2290 /*----------------------------------------------------------------------------*/
2291 static ssize_t
store_cpsopmode_value(struct device_driver
*ddri
, char *buf
, size_t count
)
2293 struct bmm150_i2c_data
*obj
= i2c_get_clientdata(this_client
);
2296 strict_strtoul(buf
, 10, &op_mode
);
2297 if ((unsigned char)op_mode
> 3)
2301 if (op_mode
== obj
->op_mode
)
2303 /* don't return error here */
2307 if (BMM150_FORCED_MODE
== op_mode
)
2309 u8 databuf
[2] = {BMM150_CONTROL
, 0x02};
2311 if (obj
->op_mode
== BMM150_SUSPEND_MODE
)
2313 /* power on firstly */
2314 bmm150api_set_powermode(BMM150_ON
);
2316 /* special treat of forced mode
2317 * for optimization */
2318 i2c_master_send(this_client
, databuf
, 2);
2319 obj
->op_mode
= BMM150_SLEEP_MODE
;
2323 bmm150api_set_functional_state((unsigned char)op_mode
);
2324 obj
->op_mode
= op_mode
;
2329 /*----------------------------------------------------------------------------*/
2330 static ssize_t
show_cpsreptxy_value(struct device_driver
*ddri
, char *buf
)
2332 unsigned char data
= 0;
2336 bmm150api_get_powermode(&power_mode
);
2339 err
= bmm150api_get_repetitions_XY(&data
);
2349 return sprintf(buf
, "%d\n", data
);
2351 /*----------------------------------------------------------------------------*/
2352 static ssize_t
store_cpsreptxy_value(struct device_driver
*ddri
, char *buf
, size_t count
)
2354 struct bmm150_i2c_data
*obj
= i2c_get_clientdata(this_client
);
2356 unsigned long tmp
= 0;
2361 err
= strict_strtoul(buf
, 10, &tmp
);
2368 data
= (unsigned char)tmp
;
2370 bmm150api_get_powermode(&power_mode
);
2373 err
= bmm150api_set_repetitions_XY(data
);
2376 //mdelay(BMM_I2C_WRITE_DELAY_TIME);
2377 obj
->rept_xy
= data
;
2390 /*----------------------------------------------------------------------------*/
2391 static ssize_t
show_cpsreptz_value(struct device_driver
*ddri
, char *buf
)
2393 unsigned char data
= 0;
2397 bmm150api_get_powermode(&power_mode
);
2400 err
= bmm150api_get_repetitions_Z(&data
);
2410 return sprintf(buf
, "%d\n", data
);
2412 /*----------------------------------------------------------------------------*/
2413 static ssize_t
store_cpsreptz_value(struct device_driver
*ddri
, char *buf
, size_t count
)
2415 struct bmm150_i2c_data
*obj
= i2c_get_clientdata(this_client
);
2416 unsigned long tmp
= 0;
2421 err
= strict_strtoul(buf
, 10, &tmp
);
2428 data
= (unsigned char)tmp
;
2430 bmm150api_get_powermode(&power_mode
);
2433 err
= bmm150api_set_repetitions_Z(data
);
2436 //mdelay(BMM_I2C_WRITE_DELAY_TIME);
2451 static ssize_t
show_test_value(struct device_driver
*ddri
, char *buf
)
2453 struct bmm150_i2c_data
*client_data
= i2c_get_clientdata(this_client
);
2456 err
= sprintf(buf
, "%d\n", client_data
->result_test
);
2460 static ssize_t
store_test_value(struct device_driver
*ddri
, char *buf
, size_t count
)
2464 struct bmm150_i2c_data
*client_data
= i2c_get_clientdata(this_client
);
2467 err
= strict_strtoul(buf
, 10, &data
);
2471 /* the following code assumes the work thread is not running */
2474 err
= bmm150api_set_functional_state(BMM150_SLEEP_MODE
);
2476 err
= bmm150api_set_selftest(1);
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
);
2488 bmm150api_soft_reset();
2490 bmm150_restore_hw_cfg(this_client
);
2499 /*----------------------------------------------------------------------------*/
2500 static ssize_t
show_daemon_name(struct device_driver
*ddri
, char *buf
)
2503 sprintf(strbuf
, "bmc150d");
2504 return sprintf(buf
, "%s", strbuf
);
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
,
2529 &driver_attr_cpsdata
,
2530 &driver_attr_cpsopmode
,
2531 &driver_attr_cpsreptxy
,
2532 &driver_attr_cpsreptz
,
2535 /*----------------------------------------------------------------------------*/
2536 static int bmm150_create_attr(struct device_driver
*driver
)
2539 int num
= (int)(sizeof(bmm150_attr_list
)/sizeof(bmm150_attr_list
[0]));
2545 for(idx
= 0; idx
< num
; idx
++)
2547 if(err
= driver_create_file(driver
, bmm150_attr_list
[idx
]))
2549 MSE_ERR( "driver_create_file (%s) = %d\n", bmm150_attr_list
[idx
]->attr
.name
, err
);
2556 /*----------------------------------------------------------------------------*/
2557 static int bmm150_delete_attr(struct device_driver
*driver
)
2560 int num
= (int)(sizeof(bmm150_attr_list
)/sizeof(bmm150_attr_list
[0]));
2567 for(idx
= 0; idx
< num
; idx
++)
2569 driver_remove_file(driver
, bmm150_attr_list
[idx
]);
2575 /*----------------------------------------------------------------------------*/
2576 static int bmm150_open(struct inode
*inode
, struct file
*file
)
2578 struct bmm150_i2c_data
*obj
= i2c_get_clientdata(this_client
);
2581 if(atomic_read(&obj
->trace
) & MMC_CTR_DEBUG
)
2583 MSE_LOG("Open device node:bmm150\n");
2585 ret
= nonseekable_open(inode
, file
);
2589 /*----------------------------------------------------------------------------*/
2590 static int bmm150_release(struct inode
*inode
, struct file
*file
)
2592 struct bmm150_i2c_data
*obj
= i2c_get_clientdata(this_client
);
2594 if(atomic_read(&obj
->trace
) & MMC_CTR_DEBUG
)
2596 MSE_LOG("Release device node:bmm150\n");
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
2604 static long bmm150_unlocked_ioctl(struct file
*file
, unsigned int cmd
,unsigned long arg
)
2606 void __user
*argp
= (void __user
*)arg
;
2608 /* NOTE: In this function the size of "char" should be 1-byte. */
2609 char buff
[BMM150_BUFSIZE
]; /* for chip information */
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 */
2615 struct bmm150_i2c_data
*clientdata
= i2c_get_clientdata(this_client
);
2616 hwm_sensor_data
* osensor_data
;
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
)))
2629 MSE_ERR("copy_to_user failed.");
2634 case ECOMPASS_IOC_GET_DELAY
: //used by daemon
2635 if(copy_to_user(argp
, &bmm150d_delay
, sizeof(bmm150d_delay
)))
2637 MSE_ERR("copy_to_user failed.");
2640 /* clear the flag */
2641 mutex_lock(&uplink_event_flag_mutex
);
2642 if ((uplink_event_flag
& BMMDRV_ULEVT_FLAG_M_DELAY
) != 0)
2644 uplink_event_flag
&= ~BMMDRV_ULEVT_FLAG_M_DELAY
;
2646 else if ((uplink_event_flag
& BMMDRV_ULEVT_FLAG_O_DELAY
) != 0)
2648 uplink_event_flag
&= ~BMMDRV_ULEVT_FLAG_O_DELAY
;
2650 mutex_unlock(&uplink_event_flag_mutex
);
2651 /* wake up the wait queue */
2652 wake_up(&uplink_event_flag_wq
);
2655 case ECOMPASS_IOC_SET_YPR
: //used by daemon
2658 MSE_ERR("invalid argument.");
2661 if(copy_from_user(value
, argp
, sizeof(value
)))
2663 MSE_ERR("copy_from_user failed.");
2666 ECS_SaveData(value
);
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))
2674 /* de-active m-channel when driver suspend regardless of m_flag*/
2677 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
2678 if(copy_to_user(argp
, &sensor_status
, sizeof(sensor_status
)))
2680 MSE_ERR("copy_to_user failed.");
2683 /* clear the flag */
2684 mutex_lock(&uplink_event_flag_mutex
);
2685 if ((uplink_event_flag
& BMMDRV_ULEVT_FLAG_M_ACTIVE
) != 0)
2687 uplink_event_flag
&= ~BMMDRV_ULEVT_FLAG_M_ACTIVE
;
2689 mutex_unlock(&uplink_event_flag_mutex
);
2690 /* wake up the wait queue */
2691 wake_up(&uplink_event_flag_wq
);
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))
2699 /* de-active m-channel when driver suspend regardless of m_flag*/
2702 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
2703 if(copy_to_user(argp
, &sensor_status
, sizeof(sensor_status
)))
2705 MSE_ERR("copy_to_user failed.");
2708 /* clear the flag */
2709 mutex_lock(&uplink_event_flag_mutex
);
2710 if ((uplink_event_flag
& BMMDRV_ULEVT_FLAG_O_ACTIVE
) != 0)
2712 uplink_event_flag
&= ~BMMDRV_ULEVT_FLAG_O_ACTIVE
;
2714 mutex_unlock(&uplink_event_flag_mutex
);
2715 /* wake up the wait queue */
2716 wake_up(&uplink_event_flag_wq
);
2720 case ECOMPASS_IOC_GET_GDELAY
: //used by daemon
2721 if(copy_to_user(argp
, &m4g_delay
, sizeof(m4g_delay
)))
2723 MSE_ERR("copy_to_user failed.");
2726 /* clear the flag */
2727 mutex_lock(&uplink_event_flag_mutex
);
2728 if ((uplink_event_flag
& BMMDRV_ULEVT_FLAG_G_DELAY
) != 0)
2730 uplink_event_flag
&= ~BMMDRV_ULEVT_FLAG_G_DELAY
;
2732 mutex_unlock(&uplink_event_flag_mutex
);
2733 /* wake up the wait queue */
2734 wake_up(&uplink_event_flag_wq
);
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))
2742 /* de-active g-channel when driver suspend regardless of g_flag*/
2745 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
2746 if(copy_to_user(argp
, &sensor_status
, sizeof(sensor_status
)))
2748 MSE_ERR("copy_to_user failed.");
2751 /* clear the flag */
2752 mutex_lock(&uplink_event_flag_mutex
);
2753 if ((uplink_event_flag
& BMMDRV_ULEVT_FLAG_G_ACTIVE
) != 0)
2755 uplink_event_flag
&= ~BMMDRV_ULEVT_FLAG_G_ACTIVE
;
2757 mutex_unlock(&uplink_event_flag_mutex
);
2758 /* wake up the wait queue */
2759 wake_up(&uplink_event_flag_wq
);
2764 case ECOMPASS_IOC_GET_VRVDELAY
: //used by daemon
2765 if(copy_to_user(argp
, &vrv_delay
, sizeof(vrv_delay
)))
2767 MSE_ERR("copy_to_user failed.");
2770 /* clear the flag */
2771 mutex_lock(&uplink_event_flag_mutex
);
2772 if ((uplink_event_flag
& BMMDRV_ULEVT_FLAG_VRV_DELAY
) != 0)
2774 uplink_event_flag
&= ~BMMDRV_ULEVT_FLAG_VRV_DELAY
;
2776 mutex_unlock(&uplink_event_flag_mutex
);
2777 /* wake up the wait queue */
2778 wake_up(&uplink_event_flag_wq
);
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))
2786 /* de-active vrv-channel when driver suspend regardless of vrv_flag*/
2789 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
2790 if(copy_to_user(argp
, &sensor_status
, sizeof(sensor_status
)))
2792 MSE_ERR("copy_to_user failed.");
2795 /* clear the flag */
2796 mutex_lock(&uplink_event_flag_mutex
);
2797 if ((uplink_event_flag
& BMMDRV_ULEVT_FLAG_VRV_ACTIVE
) != 0)
2799 uplink_event_flag
&= ~BMMDRV_ULEVT_FLAG_VRV_ACTIVE
;
2801 mutex_unlock(&uplink_event_flag_mutex
);
2802 /* wake up the wait queue */
2803 wake_up(&uplink_event_flag_wq
);
2808 case ECOMPASS_IOC_GET_VLADELAY
: //used by daemon
2809 if(copy_to_user(argp
, &vla_delay
, sizeof(vla_delay
)))
2811 MSE_ERR("copy_to_user failed.");
2814 /* clear the flag */
2815 mutex_lock(&uplink_event_flag_mutex
);
2816 if ((uplink_event_flag
& BMMDRV_ULEVT_FLAG_VLA_DELAY
) != 0)
2818 uplink_event_flag
&= ~BMMDRV_ULEVT_FLAG_VLA_DELAY
;
2820 mutex_unlock(&uplink_event_flag_mutex
);
2821 /* wake up the wait queue */
2822 wake_up(&uplink_event_flag_wq
);
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))
2830 /* de-active vla-channel when driver suspend regardless of vla_flag*/
2833 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
2834 if(copy_to_user(argp
, &sensor_status
, sizeof(sensor_status
)))
2836 MSE_ERR("copy_to_user failed.");
2839 /* clear the flag */
2840 mutex_lock(&uplink_event_flag_mutex
);
2841 if ((uplink_event_flag
& BMMDRV_ULEVT_FLAG_VLA_ACTIVE
) != 0)
2843 uplink_event_flag
&= ~BMMDRV_ULEVT_FLAG_VLA_ACTIVE
;
2845 mutex_unlock(&uplink_event_flag_mutex
);
2846 /* wake up the wait queue */
2847 wake_up(&uplink_event_flag_wq
);
2852 case ECOMPASS_IOC_GET_VGDELAY
: //used by daemon
2853 if(copy_to_user(argp
, &vg_delay
, sizeof(vg_delay
)))
2855 MSE_ERR("copy_to_user failed.");
2858 /* clear the flag */
2859 mutex_lock(&uplink_event_flag_mutex
);
2860 if ((uplink_event_flag
& BMMDRV_ULEVT_FLAG_VG_DELAY
) != 0)
2862 uplink_event_flag
&= ~BMMDRV_ULEVT_FLAG_VG_DELAY
;
2864 mutex_unlock(&uplink_event_flag_mutex
);
2865 /* wake up the wait queue */
2866 wake_up(&uplink_event_flag_wq
);
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))
2874 /* de-active vla-channel when driver suspend regardless of vla_flag*/
2877 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
2878 if(copy_to_user(argp
, &sensor_status
, sizeof(sensor_status
)))
2880 MSE_ERR("copy_to_user failed.");
2883 /* clear the flag */
2884 mutex_lock(&uplink_event_flag_mutex
);
2885 if ((uplink_event_flag
& BMMDRV_ULEVT_FLAG_VG_ACTIVE
) != 0)
2887 uplink_event_flag
&= ~BMMDRV_ULEVT_FLAG_VG_ACTIVE
;
2889 mutex_unlock(&uplink_event_flag_mutex
);
2890 /* wake up the wait queue */
2891 wake_up(&uplink_event_flag_wq
);
2894 case MSENSOR_IOCTL_READ_CHIPINFO
: //reserved
2897 MSE_ERR( "IO parameter pointer is NULL!\r\n");
2901 bmm150_ReadChipInfo(buff
, BMM150_BUFSIZE
);
2902 if(copy_to_user(argp
, buff
, strlen(buff
)+1))
2908 case MSENSOR_IOCTL_READ_SENSORDATA
: //used by MTK ftm or engineering mode
2911 MSE_ERR( "IO parameter pointer is NULL!\r\n");
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))
2922 case ECOMPASS_IOC_GET_LAYOUT
: //used by daemon
2923 status
= atomic_read(&clientdata
->layout
);
2924 if(copy_to_user(argp
, &status
, sizeof(status
)))
2926 MSE_ERR("copy_to_user failed.");
2931 case MSENSOR_IOCTL_SENSOR_ENABLE
: //used by MTK ftm
2934 MSE_ERR( "IO parameter pointer is NULL!\r\n");
2937 if(copy_from_user(&enable
, argp
, sizeof(enable
)))
2939 MSE_ERR("copy_from_user failed.");
2944 MSE_LOG("MSENSOR_IOCTL_SENSOR_ENABLE enable=%d!\r\n",enable
);
2947 atomic_set(&o_flag
, 1);
2951 atomic_set(&o_flag
, 0);
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
);
2963 case MSENSOR_IOCTL_READ_FACTORY_SENSORDATA
: //used by MTK ftm
2966 MSE_ERR( "IO parameter pointer is NULL!\r\n");
2970 osensor_data
= (hwm_sensor_data
*)buff
;
2971 mutex_lock(&sensor_data_mutex
);
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
;
2979 mutex_unlock(&sensor_data_mutex
);
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))
2990 MSE_ERR( "%s not supported = 0x%04x", __FUNCTION__
, cmd
);
2991 return -ENOIOCTLCMD
;
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
,
3004 /*----------------------------------------------------------------------------*/
3005 static struct miscdevice bmm150_device
= {
3006 .minor
= MISC_DYNAMIC_MINOR
,
3008 .fops
= &bmm150_fops
,
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
)
3016 hwm_sensor_data
* msensor_data
;
3019 struct i2c_client
*client
= this_client
;
3020 struct bmm150_i2c_data
*data
= i2c_get_clientdata(this_client
);
3024 if(atomic_read(&data
->trace
) & MMC_FUN_DEBUG
)
3032 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
3034 MSE_ERR( "Set delay parameter error!\n");
3039 value
= *(int *)buff_in
;
3041 bmm150d_delay
= value
;
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
);
3052 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
3054 MSE_ERR( "Enable sensor parameter error!\n");
3060 value
= *(int *)buff_in
;
3064 atomic_set(&m_flag
, 1);
3068 atomic_set(&m_flag
, 0);
3071 bmm150_SetPowerMode(this_client
, (value
== 1));
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
);
3082 case SENSOR_GET_DATA
:
3083 if((buff_out
== NULL
) || (size_out
< sizeof(hwm_sensor_data
)))
3085 MSE_ERR( "get sensor data parameter error!\n");
3090 msensor_data
= (hwm_sensor_data
*)buff_out
;
3091 mutex_lock(&sensor_data_mutex
);
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
;
3099 mutex_unlock(&sensor_data_mutex
);
3101 if(atomic_read(&data
->trace
) & MMC_HWM_DEBUG
)
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
);
3111 MSE_ERR( "msensor operate function no this parameter %d!\n", command
);
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
)
3125 hwm_sensor_data
* osensor_data
;
3127 struct i2c_client
*client
= this_client
;
3128 struct bmm150_i2c_data
*data
= i2c_get_clientdata(this_client
);
3132 if(atomic_read(&data
->trace
) & MMC_FUN_DEBUG
)
3141 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
3143 MSE_ERR( "Set delay parameter error!\n");
3148 value
= *(int *)buff_in
;
3149 bmm150d_delay
= value
;
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
);
3160 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
3162 MSE_ERR( "Enable sensor parameter error!\n");
3168 value
= *(int *)buff_in
;
3172 atomic_set(&o_flag
, 1);
3176 atomic_set(&o_flag
, 0);
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
);
3188 case SENSOR_GET_DATA
:
3189 if((buff_out
== NULL
) || (size_out
< sizeof(hwm_sensor_data
)))
3191 MSE_ERR( "get sensor data parameter error!\n");
3196 osensor_data
= (hwm_sensor_data
*)buff_out
;
3197 mutex_lock(&sensor_data_mutex
);
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
;
3205 mutex_unlock(&sensor_data_mutex
);
3207 if(atomic_read(&data
->trace
) & MMC_HWM_DEBUG
)
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
);
3217 MSE_ERR( "osensor operate function no this parameter %d!\n", command
);
3224 /*----------------------------------------------------------------------------*/
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
)
3231 hwm_sensor_data
* g_data
;
3233 struct i2c_client
*client
= this_client
;
3234 struct bmm150_i2c_data
*data
= i2c_get_clientdata(this_client
);
3238 if(atomic_read(&data
->trace
) & MMC_FUN_DEBUG
)
3247 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
3249 MSE_ERR( "Set delay parameter error!\n");
3254 value
= *(int *)buff_in
;
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
);
3266 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
3268 MSE_ERR( "Enable sensor parameter error!\n");
3274 value
= *(int *)buff_in
;
3278 atomic_set(&g_flag
, 1);
3282 atomic_set(&g_flag
, 0);
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
);
3294 case SENSOR_GET_DATA
:
3295 if((buff_out
== NULL
) || (size_out
< sizeof(hwm_sensor_data
)))
3297 MSE_ERR( "get sensor data parameter error!\n");
3302 g_data
= (hwm_sensor_data
*)buff_out
;
3303 mutex_lock(&sensor_data_mutex
);
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
;
3311 mutex_unlock(&sensor_data_mutex
);
3313 if(atomic_read(&data
->trace
) & MMC_HWM_DEBUG
)
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
);
3323 MSE_ERR( "m4g operate function no this parameter %d!\n", command
);
3331 /*----------------------------------------------------------------------------*/
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
)
3338 hwm_sensor_data
* vrv_data
;
3340 struct i2c_client
*client
= this_client
;
3341 struct bmm150_i2c_data
*data
= i2c_get_clientdata(this_client
);
3345 if(atomic_read(&data
->trace
) & MMC_FUN_DEBUG
)
3354 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
3356 MSE_ERR( "Set delay parameter error!\n");
3361 value
= *(int *)buff_in
;
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
);
3373 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
3375 MSE_ERR( "Enable sensor parameter error!\n");
3381 value
= *(int *)buff_in
;
3385 atomic_set(&vrv_flag
, 1);
3389 atomic_set(&vrv_flag
, 0);
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
);
3401 case SENSOR_GET_DATA
:
3402 if((buff_out
== NULL
) || (size_out
< sizeof(hwm_sensor_data
)))
3404 MSE_ERR( "get sensor data parameter error!\n");
3409 vrv_data
= (hwm_sensor_data
*)buff_out
;
3410 mutex_lock(&sensor_data_mutex
);
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
;
3418 mutex_unlock(&sensor_data_mutex
);
3420 if(atomic_read(&data
->trace
) & MMC_HWM_DEBUG
)
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
);
3430 MSE_ERR( "rotation vector operate function no this parameter %d!\n", command
);
3438 /*----------------------------------------------------------------------------*/
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
)
3445 hwm_sensor_data
* vla_value
;
3447 struct i2c_client
*client
= this_client
;
3448 struct bmm150_i2c_data
*data
= i2c_get_clientdata(this_client
);
3452 if(atomic_read(&data
->trace
) & MMC_FUN_DEBUG
)
3461 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
3463 MSE_ERR( "Set delay parameter error!\n");
3468 value
= *(int *)buff_in
;
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
);
3480 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
3482 MSE_ERR( "Enable sensor parameter error!\n");
3488 value
= *(int *)buff_in
;
3492 atomic_set(&vla_flag
, 1);
3496 atomic_set(&vla_flag
, 0);
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
);
3508 case SENSOR_GET_DATA
:
3509 if((buff_out
== NULL
) || (size_out
< sizeof(hwm_sensor_data
)))
3511 MSE_ERR( "get sensor data parameter error!\n");
3516 vla_value
= (hwm_sensor_data
*)buff_out
;
3517 mutex_lock(&sensor_data_mutex
);
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
;
3525 mutex_unlock(&sensor_data_mutex
);
3527 if(atomic_read(&data
->trace
) & MMC_HWM_DEBUG
)
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
);
3537 MSE_ERR( "virtual linear accelerometer operate function no this parameter %d!\n", command
);
3545 /*----------------------------------------------------------------------------*/
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
)
3552 hwm_sensor_data
* vg_value
;
3554 struct i2c_client
*client
= this_client
;
3555 struct bmm150_i2c_data
*data
= i2c_get_clientdata(this_client
);
3559 if(atomic_read(&data
->trace
) & MMC_FUN_DEBUG
)
3568 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
3570 MSE_ERR( "Set delay parameter error!\n");
3575 value
= *(int *)buff_in
;
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
);
3587 if((buff_in
== NULL
) || (size_in
< sizeof(int)))
3589 MSE_ERR( "Enable sensor parameter error!\n");
3595 value
= *(int *)buff_in
;
3599 atomic_set(&vg_flag
, 1);
3603 atomic_set(&vg_flag
, 0);
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
);
3615 case SENSOR_GET_DATA
:
3616 if((buff_out
== NULL
) || (size_out
< sizeof(hwm_sensor_data
)))
3618 MSE_ERR( "get sensor data parameter error!\n");
3623 vg_value
= (hwm_sensor_data
*)buff_out
;
3624 mutex_lock(&sensor_data_mutex
);
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
;
3632 mutex_unlock(&sensor_data_mutex
);
3634 if(atomic_read(&data
->trace
) & MMC_HWM_DEBUG
)
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
);
3644 MSE_ERR( "virtual gravity operate function no this parameter %d!\n", command
);
3652 /*----------------------------------------------------------------------------*/
3653 static void bmm150_restore_hw_cfg(struct i2c_client
*client
)
3655 struct bmm150_i2c_data
*obj
= i2c_get_clientdata(client
);
3657 if (obj
->op_mode
> 3)
3659 obj
->op_mode
= BMM150_SLEEP_MODE
;
3661 bmm150api_set_functional_state(obj
->op_mode
);
3663 bmm150api_set_datarate(obj
->odr
);
3664 //mdelay(BMM_I2C_WRITE_DELAY_TIME);
3666 bmm150api_set_repetitions_XY(obj
->rept_xy
);
3667 //mdelay(BMM_I2C_WRITE_DELAY_TIME);
3669 bmm150api_set_repetitions_Z(obj
->rept_z
);
3670 //mdelay(BMM_I2C_WRITE_DELAY_TIME);
3673 /*----------------------------------------------------------------------------*/
3674 #ifndef CONFIG_HAS_EARLYSUSPEND
3675 /*----------------------------------------------------------------------------*/
3676 static int bmm150_suspend(struct i2c_client
*client
, pm_message_t msg
)
3678 struct bmm150_i2c_data
*data
= i2c_get_clientdata(client
);
3680 if(msg
.event
== PM_EVENT_SUSPEND
)
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)
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
);
3692 if (atomic_read(&o_flag
) == 1)
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
);
3700 if (atomic_read(&g_flag
) == 1)
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
);
3709 if (atomic_read(&vrv_flag
) == 1)
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
);
3718 if (atomic_read(&vla_flag
) == 1)
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
);
3727 if (atomic_read(&vg_flag
) == 1)
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
);
3736 /* wake up the wait queue */
3737 wake_up(&uplink_event_flag_wq
);
3738 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
3740 bmm150_SetPowerMode(obj
->client
, FALSE
);
3741 bmm150_power(obj
->hw
, 0);
3745 /*----------------------------------------------------------------------------*/
3746 static int bmm150_resume(struct i2c_client
*client
)
3748 struct bmm150_i2c_data
*data
= i2c_get_clientdata(client
);
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)
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
);
3762 if (atomic_read(&o_flag
) == 1)
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
);
3770 if (atomic_read(&g_flag
) == 1)
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
);
3779 if (atomic_read(&vrv_flag
) == 1)
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
);
3788 if (atomic_read(&vg_flag
) == 1)
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
);
3797 /* wake up the wait queue */
3798 wake_up(&uplink_event_flag_wq
);
3799 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
3802 /*----------------------------------------------------------------------------*/
3803 #else /*CONFIG_HAS_EARLY_SUSPEND is defined*/
3804 /*----------------------------------------------------------------------------*/
3805 static void bmm150_early_suspend(struct early_suspend
*h
)
3807 struct bmm150_i2c_data
*obj
= container_of(h
, struct bmm150_i2c_data
, early_drv
);
3813 MSE_ERR( "null pointer!!\n");
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)
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
);
3827 if (atomic_read(&o_flag
) == 1)
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
);
3835 if (atomic_read(&g_flag
) == 1)
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
);
3844 if (atomic_read(&vrv_flag
) == 1)
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
);
3853 if (atomic_read(&vla_flag
) == 1)
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
);
3862 if (atomic_read(&vg_flag
) == 1)
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
);
3871 /* wake up the wait queue */
3872 wake_up(&uplink_event_flag_wq
);
3873 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
3875 bmm150_SetPowerMode(obj
->client
, FALSE
);
3876 bmm150_power(obj
->hw
, 0);
3878 /*----------------------------------------------------------------------------*/
3879 static void bmm150_late_resume(struct early_suspend
*h
)
3881 struct bmm150_i2c_data
*obj
= container_of(h
, struct bmm150_i2c_data
, early_drv
);
3885 MSE_ERR( "null pointer!!\n");
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)
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
);
3901 if (atomic_read(&o_flag
) == 1)
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
);
3909 if (atomic_read(&g_flag
) == 1)
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
);
3918 if (atomic_read(&vrv_flag
) == 1)
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
);
3927 if (atomic_read(&vla_flag
) == 1)
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
);
3936 if (atomic_read(&vg_flag
) == 1)
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
);
3945 /* wake up the wait queue */
3946 wake_up(&uplink_event_flag_wq
);
3947 #endif //BMC150_BLOCK_DAEMON_ON_SUSPEND
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
)
3956 int try_times
= BMM_MAX_RETRY_WAKEUP
;
3957 u8 data
[2] = {BMM150_POWER_CNTL
, 0x01};
3960 MSE_LOG("waking up the chip...");
3963 err
= i2c_master_send(client
, data
, 2);
3964 mdelay(BMM_I2C_WRITE_DELAY_TIME
);
3966 err
= hwmsen_read_block(client
, BMM150_POWER_CNTL
, &dummy
, 1);
3967 if (data
[1] == dummy
)
3974 MSE_LOG("wake up result: %s, tried times: %d",
3975 (try_times
> 0) ? "succeed" : "fail",
3976 BMM_MAX_RETRY_WAKEUP
- try_times
+ 1);
3978 err
= (try_times
> 0) ? 0 : -1;
3982 /*----------------------------------------------------------------------------*/
3983 static int bmm150_checkchipid(struct i2c_client
*client
)
3988 hwmsen_read_block(client
, BMM150_CHIP_ID
, &chip_id
, 1);
3989 MSE_LOG("read chip id result: %#x", chip_id
);
3991 if ((chip_id
& 0xff) != SENSOR_CHIP_ID_BMM
)
4000 /*----------------------------------------------------------------------------*/
4001 static char bmm150_i2c_read_wrapper(u8 dev_addr
, u8 reg_addr
, u8
*data
, u8 len
)
4003 return hwmsen_read_block(this_client
, reg_addr
, data
, len
);
4005 /*----------------------------------------------------------------------------*/
4006 static char bmm150_i2c_write_wrapper(u8 dev_addr
, u8 reg_addr
, u8
*data
, u8 len
)
4008 u8 buff
[BMM150_BUFSIZE
+ 1];
4010 if (len
> BMM150_BUFSIZE
)
4016 memcpy(buff
+1, data
, len
);
4017 if (i2c_master_send(this_client
, buff
, len
+1) != (len
+1))
4019 /* I2C transfer error */
4027 /*----------------------------------------------------------------------------*/
4028 static void bmm150_delay(u32 msec
)
4032 /*----------------------------------------------------------------------------*/
4033 static int bmm150_init_client(struct i2c_client
*client
)
4035 struct bmm150_i2c_data
*obj
= i2c_get_clientdata(client
);
4038 res
= bmm150_wakeup(client
);
4043 res
= bmm150_checkchipid(client
);
4048 MSE_LOG("check chip ID ok");
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
);
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
;
4062 res
= bmm150api_set_functional_state(BMM150_SUSPEND_MODE
);
4070 /*----------------------------------------------------------------------------*/
4072 static struct platform_driver bmm150_sensor_driver
= {
4073 .probe
= bmm150_probe
,
4074 .remove
= bmm150_remove
,
4077 //.owner = THIS_MODULE,
4083 static const struct of_device_id bmm150_of_match
[] = {
4084 { .compatible
= "mediatek,msensor", },
4089 static struct platform_driver bmm150_sensor_driver
=
4091 .probe
= bmm150_probe
,
4092 .remove
= bmm150_remove
,
4097 .of_match_table
= bmm150_of_match
,
4102 /*----------------------------------------------------------------------------*/
4103 static int bmm150_i2c_probe(struct i2c_client
*client
, const struct i2c_device_id
*id
)
4105 struct i2c_client
*new_client
;
4106 struct bmm150_i2c_data
*data
;
4108 struct hwmsen_object sobj_m
, sobj_o
;
4110 struct hwmsen_object sobj_g
;
4113 struct hwmsen_object sobj_vrv
;
4116 struct hwmsen_object sobj_vla
;
4119 struct hwmsen_object sobj_vg
;
4122 if(!(data
= kmalloc(sizeof(struct bmm150_i2c_data
), GFP_KERNEL
)))
4127 memset(data
, 0, sizeof(struct bmm150_i2c_data
));
4129 data
->hw
= get_cust_mag_hw();
4130 if(err
= hwmsen_get_convert(data
->hw
->direction
, &data
->cvt
))
4132 MSE_ERR("invalid direction: %d\n", data
->hw
->direction
);
4135 atomic_set(&data
->layout
, data
->hw
->direction
);
4136 atomic_set(&data
->trace
, 0);
4138 mutex_init(&sensor_data_mutex
);
4139 mutex_init(&uplink_event_flag_mutex
);
4141 init_waitqueue_head(&uplink_event_flag_wq
);
4143 data
->client
= client
;
4144 new_client
= data
->client
;
4145 i2c_set_clientdata(new_client
, data
);
4147 this_client
= new_client
;
4150 if (err
= bmm150_init_client(this_client
))
4152 MSE_ERR("fail to initialize client");
4153 goto exit_client_failed
;
4156 /* Register sysfs attribute */
4157 if(err
= bmm150_create_attr(&bmm150_sensor_driver
.driver
))
4159 MSE_ERR("create attribute err = %d\n", err
);
4160 goto exit_sysfs_create_group_failed
;
4163 if(err
= misc_register(&bmm150_device
))
4165 MSE_ERR("bmm150_device register failed\n");
4166 goto exit_misc_device_register_failed
;
4171 sobj_m
.sensor_operate
= bmm150_operate
;
4172 if(err
= hwmsen_attach(ID_MAGNETIC
, &sobj_m
))
4174 MSE_ERR( "attach fail = %d\n", err
);
4180 sobj_o
.sensor_operate
= bmm150_orientation_operate
;
4181 if(err
= hwmsen_attach(ID_ORIENTATION
, &sobj_o
))
4183 MSE_ERR( "attach fail = %d\n", err
);
4190 sobj_g
.sensor_operate
= bmm150_m4g_operate
;
4191 if(err
= hwmsen_attach(ID_GYROSCOPE
, &sobj_g
))
4193 MSE_ERR( "attach fail = %d\n", err
);
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
))
4204 MSE_ERR( "attach fail = %d\n", err
);
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
))
4215 MSE_ERR( "attach fail = %d\n", err
);
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
))
4226 MSE_ERR( "attach fail = %d\n", err
);
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
);
4238 MSE_LOG("%s: OK\n", __func__
);
4242 exit_sysfs_create_group_failed
:
4243 exit_misc_device_register_failed
:
4247 MSE_ERR( "%s: err = %d\n", __func__
, err
);
4250 /*----------------------------------------------------------------------------*/
4251 static int bmm150_i2c_remove(struct i2c_client
*client
)
4253 struct bmm150_i2c_data
*obj
= i2c_get_clientdata(client
);
4255 if(bmm150_delete_attr(&bmm150_sensor_driver
.driver
))
4257 MSE_ERR( "bmm150_delete_attr fail");
4260 #ifdef CONFIG_HAS_EARLYSUSPEND
4261 unregister_early_suspend(&obj
->early_drv
);
4263 bmm150api_set_functional_state(BMM150_SUSPEND_MODE
);
4265 i2c_unregister_device(client
);
4268 misc_deregister(&bmm150_device
);
4271 /*----------------------------------------------------------------------------*/
4273 static struct i2c_driver bmm150_i2c_driver
= {
4275 .name
= BMM150_DEV_NAME
,
4277 .probe
= bmm150_i2c_probe
,
4278 .remove
= bmm150_i2c_remove
,
4279 #if !defined(CONFIG_HAS_EARLYSUSPEND)
4280 .suspend
= bmm150_suspend
,
4281 .resume
= bmm150_resume
,
4283 .id_table
= bmm150_i2c_id
,
4286 /*----------------------------------------------------------------------------*/
4287 static int bmm150_probe(struct platform_device
*pdev
)
4289 struct mag_hw
*hw
= get_cust_mag_hw();
4291 bmm150_power(hw
, 1);
4292 if(i2c_add_driver(&bmm150_i2c_driver
))
4294 MSE_ERR("add driver error\n");
4300 /*----------------------------------------------------------------------------*/
4301 static int bmm150_remove(struct platform_device
*pdev
)
4303 struct mag_hw
*hw
= get_cust_mag_hw();
4305 i2c_del_driver(&bmm150_i2c_driver
);
4306 bmm150_power(hw
, 0);
4309 /*----------------------------------------------------------------------------*/
4310 static int __init
bmm150_init(void)
4312 struct mag_hw
*hw
= get_cust_mag_hw();
4314 i2c_register_board_info(hw
->i2c_num
, &bmm150_i2c_info
, 1);
4315 if(platform_driver_register(&bmm150_sensor_driver
))
4317 MSE_ERR("failed to register driver");
4322 /*----------------------------------------------------------------------------*/
4323 static void __exit
bmm150_exit(void)
4325 platform_driver_unregister(&bmm150_sensor_driver
);
4327 /*----------------------------------------------------------------------------*/
4328 module_init(bmm150_init
);
4329 module_exit(bmm150_exit
);
4331 MODULE_AUTHOR("hongji.zhou@bosch-sensortec.com");
4332 MODULE_DESCRIPTION("bmm150 compass driver");
4333 MODULE_LICENSE("GPLv2");