1 /*
2  * Copyright (C) 2015-2018 Alibaba Group Holding Limited
3  *
4  *
5  */
6 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include "aos/kernel.h"
11 #include "sensor_drv_api.h"
12 #include "sensor_hal.h"
13 
14 
15 #define BMM150_I2C_ADDR1                            (0x10<<1)
16 #define BMM150_I2C_ADDR2                            (0x11 << 1)
17 #define BMM150_I2C_ADDR3                            (0x12 << 1)
18 #define BMM150_I2C_ADDR4                            (0x13 << 1)
19 
20 #define BMM150_CHIP_ID_ADDR                         (0X40)
21 #define BMM150_CHIP_ID_VALUE                        (0X32)
22 
23 #define BMM150_OP_MODE_ADDR                         (0x4C)
24 #define BMM150_DATA_X_LSB                           (0x42)
25 
26 #define BMM150_ODR_ADDR_POS                         (3)
27 #define BMM150_ODR_ADDR_LEN                         (3)
28 #define BMM150_ODR_ADDR_MSK                         (0x31)
29 #define BMM150_ODR_ADDR_REG                         (BMM150_OP_MODE_ADDR)
30 
31 #define BMM150_POWER_MODE_POS                       (1)
32 #define BMM150_POWER_MODE_LEN                       (2)
33 #define BMM150_POWER_MODE_MSK                       (0xf9)
34 #define BMM150_POWER_MODE_REG                       (BMM150_OP_MODE_ADDR)
35 
36 #define BMM150_POWER_MODE_NORMAL (0X0)
37 #define BMM150_POWER_MODE_SLEEP                     (0X3)
38 #define BMM150_POWER_MODE_OFF                       (0X3)
39 
40 #define BMM150_ODR_2                        (2)
41 #define BMM150_ODR_6                        (6)
42 #define BMM150_ODR_8                        (8)
43 #define BMM150_ODR_10                       (10)
44 #define BMM150_ODR_15                       (15)
45 #define BMM150_ODR_20                       (20)
46 #define BMM150_ODR_25                       (25)
47 #define BMM150_ODR_30                       (30)
48 
49 
50 #define BMM150_ODR_2_REG                    (0x1)
51 #define BMM150_ODR_6_REG                    (0x2)
52 #define BMM150_ODR_8_REG                    (0x3)
53 #define BMM150_ODR_10_REG                   (0x0)
54 #define BMM150_ODR_15_REG                   (0x4)
55 #define BMM150_ODR_20_REG                   (0x5)
56 #define BMM150_ODR_25_REG                   (0x6)
57 #define BMM150_ODR_30_REG                   (0x7)
58 
59 #define BMM150_DIG_X1                       (0x5D)
60 #define BMM150_DIG_Y1                       (0x5E)
61 #define BMM150_DIG_Z4_LSB                   (0x62)
62 #define BMM150_DIG_Z4_MSB                   (0x63)
63 #define BMM150_DIG_X2                       (0x64)
64 #define BMM150_DIG_Y2                       (0x65)
65 #define BMM150_DIG_Z2_LSB                   (0x68)
66 #define BMM150_DIG_Z2_MSB                   (0x69)
67 #define BMM150_DIG_Z1_LSB                   (0x6A)
68 #define BMM150_DIG_Z1_MSB                   (0x6B)
69 #define BMM150_DIG_XYZ1_LSB                 (0x6C)
70 #define BMM150_DIG_XYZ1_MSB                 (0x6D)
71 #define BMM150_DIG_Z3_LSB                   (0x6E)
72 #define BMM150_DIG_Z3_MSB                   (0x6F)
73 #define BMM150_DIG_XY2                      (0x70)
74 #define BMM150_DIG_XY1                      (0x71)
75 
76 
77 #define BMM150_DATA_X_MSK                       (0xF8)
78 #define BMM150_DATA_X_POS                       (0x03)
79 
80 #define BMM150_DATA_Y_MSK                       (0xF8)
81 #define BMM150_DATA_Y_POS                       (0x03)
82 
83 #define BMM150_DATA_Z_MSK                       (0xFE)
84 #define BMM150_DATA_Z_POS                       (0x01)
85 
86 #define BMM150_DATA_RHALL_MSK                   (0xFC)
87 #define BMM150_DATA_RHALL_POS                   (0x02)
88 
89 #define BMM150_DATA_UT_2_MG                     (10)
90 
91 
92 #define BMM150_OVERFLOW_OUTPUT                                      (-32768)
93 #define BMM150_NEGATIVE_SATURATION_Z                                (-32767)
94 #define BMM150_POSITIVE_SATURATION_Z                                (32767)
95 
96 #define BMM150_XYAXES_FLIP_OVERFLOW_ADCVAL                          (-4096)
97 #define BMM150_ZAXIS_HALL_OVERFLOW_ADCVAL                           (-16384)
98 
99 #define BMM150_GET_BITSLICE(regvar, bitname) \
100     ((regvar & bitname##_MSK) >> bitname##_POS)
101 #define BMM150_SET_BITSLICE(regvar, bitname, val) \
102     ((regvar & (~bitname##_MSK)) | ((val << bitname##_POS) & bitname##_MSK))
103 
104 typedef struct bmm150_trim_registers {
105     int8_t dig_x1;
106     int8_t dig_y1;
107     int8_t dig_x2;
108     int8_t dig_y2;
109     uint16_t dig_z1;
110     int16_t dig_z2;
111     int16_t dig_z3;
112     int16_t dig_z4;
113     uint8_t dig_xy1;
114     int8_t dig_xy2;
115     uint16_t dig_xyz1;
116 }bmm150_trim_reg_st;
117 
118 bmm150_trim_reg_st      g_bmm150_trim_reg = {0};
119 
120 i2c_dev_t bmm150_ctx = {
121     .port                 = 3,
122     .config.address_width = 8,
123     .config.freq          = 400000,
124     .config.dev_addr      = BMM150_I2C_ADDR1,
125 };
126 
drv_mag_bosch_bmm150_validate_id(i2c_dev_t * drv,uint8_t id_value)127 int drv_mag_bosch_bmm150_validate_id(i2c_dev_t *drv, uint8_t id_value)
128 {
129     uint8_t value = 0x00;
130     int     ret   = 0;
131 
132     if (drv == NULL) {
133         return -1;
134     }
135 
136     ret = sensor_i2c_read(drv, BMM150_CHIP_ID_ADDR, &value, I2C_DATA_LEN,
137                           I2C_OP_RETRIES);
138     if (unlikely(ret)) {
139         return ret;
140     }
141 
142     if (id_value != value) {
143         return -1;
144     }
145 
146     return 0;
147 }
148 
drv_mag_bosch_bmm150_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)149 int drv_mag_bosch_bmm150_set_power_mode(i2c_dev_t *      drv,
150                                                 dev_power_mode_e mode)
151 {
152     uint8_t value = 0x00;
153 
154     uint8_t value1 = 0x00;
155     int     ret = 0;
156 
157     ret = sensor_i2c_read(drv, BMM150_POWER_MODE_REG, &value, I2C_DATA_LEN,
158                           I2C_OP_RETRIES);
159     if (unlikely(ret)) {
160         return ret;
161     }
162     switch (mode) {
163         case DEV_POWER_ON: {
164             ret = sensor_i2c_read(drv, 0x4b, &value1, I2C_DATA_LEN,
165                           I2C_OP_RETRIES);
166             value1 |= 1;
167 
168             ret = sensor_i2c_write(drv, 0x4b, &value1,
169                            I2C_DATA_LEN, I2C_OP_RETRIES);
170 
171                            aos_msleep(1);
172             value = BMM150_SET_BITSLICE(value,BMM150_POWER_MODE,BMM150_POWER_MODE_NORMAL);
173         } break;
174 
175         case DEV_POWER_OFF: {
176             value = BMM150_SET_BITSLICE(value,BMM150_POWER_MODE,BMM150_POWER_MODE_OFF);
177 
178         } break;
179 
180         case DEV_SLEEP: {
181             value = BMM150_SET_BITSLICE(value,BMM150_POWER_MODE,BMM150_POWER_MODE_OFF);
182         } break;
183 
184         default:
185             return -1;
186     }
187 
188     ret = sensor_i2c_write(drv, BMM150_POWER_MODE_REG, &value,
189                            I2C_DATA_LEN, I2C_OP_RETRIES);
190     if (unlikely(ret)) {
191         return ret;
192     }
193 
194     return 0;
195 }
196 
drv_mag_bosch_bmm150_set_odr(i2c_dev_t * drv,uint32_t odr)197 int drv_mag_bosch_bmm150_set_odr(i2c_dev_t *drv, uint32_t odr)
198 {
199     int     ret   = 0;
200     uint8_t value = 0x00;
201 
202     ret = sensor_i2c_read(drv, BMM150_ODR_ADDR_REG, &value, I2C_DATA_LEN,
203                           I2C_OP_RETRIES);
204     if (unlikely(ret)) {
205         return ret;
206     }
207 
208     if (odr >= BMM150_ODR_30) {
209         value = BMM150_SET_BITSLICE(value,BMM150_ODR_ADDR,BMM150_ODR_30_REG);
210     } else if (odr >= BMM150_ODR_25) {
211         value = BMM150_SET_BITSLICE(value,BMM150_ODR_ADDR,BMM150_ODR_25_REG);
212     } else if (odr >= BMM150_ODR_20) {
213         value = BMM150_SET_BITSLICE(value,BMM150_ODR_ADDR,BMM150_ODR_20_REG);
214     } else if (odr >= BMM150_ODR_15) {
215         value = BMM150_SET_BITSLICE(value,BMM150_ODR_ADDR,BMM150_ODR_15_REG);
216     } else if (odr >= BMM150_ODR_10) {
217         value = BMM150_SET_BITSLICE(value,BMM150_ODR_ADDR,BMM150_ODR_10_REG);
218     } else if (odr >= BMM150_ODR_8) {
219         value = BMM150_SET_BITSLICE(value,BMM150_ODR_ADDR,BMM150_ODR_8_REG);
220     } else if (odr >= BMM150_ODR_6) {
221         value = BMM150_SET_BITSLICE(value,BMM150_ODR_ADDR,BMM150_ODR_6_REG);
222     } else {
223         value = BMM150_SET_BITSLICE(value,BMM150_ODR_ADDR,BMM150_ODR_2_REG);
224     }
225 
226     ret = sensor_i2c_write(drv, BMM150_ODR_ADDR_REG, &value, I2C_DATA_LEN,
227                            I2C_OP_RETRIES);
228     if (unlikely(ret)) {
229         return ret;
230     }
231     return 0;
232 }
233 
drv_mag_bosch_bmm150_irq_handle(void)234 void drv_mag_bosch_bmm150_irq_handle(void)
235 {
236     /* no handle so far */
237 }
238 
drv_mag_bosch_bmm150_open(void)239 int drv_mag_bosch_bmm150_open(void)
240 {
241     int ret = 0;
242     ret     = drv_mag_bosch_bmm150_set_power_mode(&bmm150_ctx, DEV_POWER_ON);
243     if (unlikely(ret)) {
244         return -1;
245     }
246 
247     LOG("%s %s successfully \n", SENSOR_STR, __func__);
248     return 0;
249 }
250 
drv_mag_bosch_bmm150_close(void)251 int drv_mag_bosch_bmm150_close(void)
252 {
253     int ret = 0;
254     ret     = drv_mag_bosch_bmm150_set_power_mode(&bmm150_ctx, DEV_POWER_OFF);
255     if (unlikely(ret)) {
256         return -1;
257     }
258     return 0;
259 }
260 
261 
262 
drv_mag_bosch_bmm150_compensate_x(int16_t mag_data_x,uint16_t data_rhall)263 static int16_t drv_mag_bosch_bmm150_compensate_x(int16_t mag_data_x, uint16_t data_rhall)
264 {
265     int16_t retval;
266     uint16_t process_comp_x0 = 0;
267     int32_t process_comp_x1;
268     uint16_t process_comp_x2;
269     int32_t process_comp_x3;
270     int32_t process_comp_x4;
271     int32_t process_comp_x5;
272     int32_t process_comp_x6;
273     int32_t process_comp_x7;
274     int32_t process_comp_x8;
275     int32_t process_comp_x9;
276     int32_t process_comp_x10;
277 
278 	/* Overflow condition check */
279 	if (mag_data_x != BMM150_XYAXES_FLIP_OVERFLOW_ADCVAL) {
280         if (data_rhall != 0) {
281             process_comp_x0 = data_rhall;
282         } else if (g_bmm150_trim_reg.dig_xyz1 != 0) {
283             process_comp_x0 = g_bmm150_trim_reg.dig_xyz1;
284         } else {
285             process_comp_x0 = 0;
286         }
287         if (process_comp_x0 != 0) {
288             process_comp_x1 = ((int32_t)g_bmm150_trim_reg.dig_xyz1) * 16384;
289             process_comp_x2 = ((uint16_t)(process_comp_x1 / process_comp_x0)) - ((uint16_t)0x4000);
290             retval = ((int16_t)process_comp_x2);
291             process_comp_x3 = (((int32_t)retval) * ((int32_t)retval));
292             process_comp_x4 = (((int32_t)g_bmm150_trim_reg.dig_xy2) * (process_comp_x3 / 128));
293             process_comp_x5 = (int32_t)(((int16_t)g_bmm150_trim_reg.dig_xy1) * 128);
294             process_comp_x6 = ((int32_t)retval) * process_comp_x5;
295             process_comp_x7 = (((process_comp_x4 + process_comp_x6) / 512) + ((int32_t)0x100000));
296             process_comp_x8 = ((int32_t)(((int16_t)g_bmm150_trim_reg.dig_x2) + ((int16_t)0xA0)));
297             process_comp_x9 = ((process_comp_x7 * process_comp_x8) / 4096);
298             process_comp_x10 = ((int32_t)mag_data_x) * process_comp_x9;
299             retval = ((int16_t)(process_comp_x10 / 8192));
300             retval = (retval + (((int16_t)g_bmm150_trim_reg.dig_x1) * 8)) / 16;
301         } else {
302             retval = BMM150_OVERFLOW_OUTPUT;
303         }
304     } else {
305         retval = BMM150_OVERFLOW_OUTPUT;
306     }
307 
308     return retval;
309 }
310 
311 
drv_mag_bosch_bmm150_compensate_y(int16_t mag_data_y,uint16_t data_rhall)312 static int16_t drv_mag_bosch_bmm150_compensate_y(int16_t mag_data_y, uint16_t data_rhall)
313 {
314     int16_t retval;
315     uint16_t process_comp_y0 = 0;
316     int32_t process_comp_y1;
317     uint16_t process_comp_y2;
318     int32_t process_comp_y3;
319     int32_t process_comp_y4;
320     int32_t process_comp_y5;
321     int32_t process_comp_y6;
322     int32_t process_comp_y7;
323     int32_t process_comp_y8;
324     int32_t process_comp_y9;
325 
326 
327     if (mag_data_y != BMM150_XYAXES_FLIP_OVERFLOW_ADCVAL) {
328         if (data_rhall != 0) {
329             process_comp_y0 = data_rhall;
330         } else if (g_bmm150_trim_reg.dig_xyz1 != 0) {
331             process_comp_y0 = g_bmm150_trim_reg.dig_xyz1;
332         } else {
333             process_comp_y0 = 0;
334         }
335         if (process_comp_y0 != 0) {
336             process_comp_y1 = (((int32_t)g_bmm150_trim_reg.dig_xyz1) * 16384) / process_comp_y0;
337             process_comp_y2 = ((uint16_t)process_comp_y1) - ((uint16_t)0x4000);
338             retval = ((int16_t)process_comp_y2);
339             process_comp_y3 = ((int32_t) retval) * ((int32_t)retval);
340             process_comp_y4 = ((int32_t)g_bmm150_trim_reg.dig_xy2) * (process_comp_y3 / 128);
341             process_comp_y5 = ((int32_t)(((int16_t)g_bmm150_trim_reg.dig_xy1) * 128));
342             process_comp_y6 = ((process_comp_y4 + (((int32_t)retval) * process_comp_y5)) / 512);
343             process_comp_y7 = ((int32_t)(((int16_t)g_bmm150_trim_reg.dig_y2) + ((int16_t)0xA0)));
344             process_comp_y8 = (((process_comp_y6 + ((int32_t)0x100000)) * process_comp_y7) / 4096);
345             process_comp_y9 = (((int32_t)mag_data_y) * process_comp_y8);
346             retval = (int16_t)(process_comp_y9 / 8192);
347             retval = (retval + (((int16_t)g_bmm150_trim_reg.dig_y1) * 8)) / 16;
348         } else {
349             retval = BMM150_OVERFLOW_OUTPUT;
350         }
351     } else {
352 
353         retval = BMM150_OVERFLOW_OUTPUT;
354     }
355 
356     return retval;
357 }
358 
359 /*!
360  * @brief This internal API is used to obtain the compensated
361  * magnetometer Z axis data(micro-tesla) in int16_t.
362  */
drv_mag_bosch_bmm150_compensate_z(int16_t mag_data_z,uint16_t data_rhall)363 static int16_t drv_mag_bosch_bmm150_compensate_z(int16_t mag_data_z, uint16_t data_rhall)
364 {
365 	int32_t retval;
366 	int16_t process_comp_z0;
367 	int32_t process_comp_z1;
368 	int32_t process_comp_z2;
369 	int32_t process_comp_z3;
370 	int16_t process_comp_z4;
371 
372 	if (mag_data_z != BMM150_ZAXIS_HALL_OVERFLOW_ADCVAL) {
373 		if ((g_bmm150_trim_reg.dig_z2 != 0) && (g_bmm150_trim_reg.dig_z1 != 0)
374 		&& (data_rhall != 0) && (g_bmm150_trim_reg.dig_xyz1 != 0)) {
375 			/*Processing compensation equations*/
376 			process_comp_z0 = ((int16_t)data_rhall) - ((int16_t) g_bmm150_trim_reg.dig_xyz1);
377 			process_comp_z1 = (((int32_t)g_bmm150_trim_reg.dig_z3) * ((int32_t)(process_comp_z0))) / 4;
378 			process_comp_z2 = (((int32_t)(mag_data_z - g_bmm150_trim_reg.dig_z4)) * 32768);
379 			process_comp_z3 = ((int32_t)g_bmm150_trim_reg.dig_z1) * (((int16_t)data_rhall) * 2);
380 			process_comp_z4 = (int16_t)((process_comp_z3 + (32768)) / 65536);
381 			retval = ((process_comp_z2 - process_comp_z1) / (g_bmm150_trim_reg.dig_z2 + process_comp_z4));
382 
383 			/* saturate result to +/- 2 micro-tesla */
384 			if (retval > BMM150_POSITIVE_SATURATION_Z) {
385 				retval =  BMM150_POSITIVE_SATURATION_Z;
386 			} else {
387 				if (retval < BMM150_NEGATIVE_SATURATION_Z)
388 					retval = BMM150_NEGATIVE_SATURATION_Z;
389 			}
390 			/* Conversion of LSB to micro-tesla*/
391 			retval = retval / 16;
392 		} else {
393 			retval = BMM150_OVERFLOW_OUTPUT;
394 
395 		}
396 	} else {
397 		/* Overflow condition*/
398 		retval = BMM150_OVERFLOW_OUTPUT;
399 	}
400 
401 	return (int16_t)retval;
402 }
403 
404 
405 
drv_mag_bosch_bmm150_read_calib_reg(i2c_dev_t * drv)406 static int8_t drv_mag_bosch_bmm150_read_calib_reg(i2c_dev_t *drv)
407 {
408     int8_t ret;
409     uint8_t trim_x1y1[2] = {0};
410     uint8_t trim_xyz_data[4] = {0};
411     uint8_t trim_xy1xy2[10] = {0};
412     uint16_t temp_msb = 0;
413 
414     ret = sensor_i2c_read(drv, BMM150_DIG_X1, trim_x1y1, 2,
415                           I2C_OP_RETRIES);
416     if (unlikely(ret)) {
417         return -1;
418     }
419 
420     ret = sensor_i2c_read(drv, BMM150_DIG_Z4_LSB, trim_xyz_data, 4,
421                   I2C_OP_RETRIES);
422     if (unlikely(ret)) {
423         return -1;
424     }
425 
426     ret = sensor_i2c_read(drv, BMM150_DIG_Z2_LSB, trim_xy1xy2, 10,
427       I2C_OP_RETRIES);
428 
429     if (unlikely(ret)) {
430         return -1;
431     }
432 
433     g_bmm150_trim_reg.dig_x1 = (int8_t)trim_x1y1[0];
434     g_bmm150_trim_reg.dig_y1 = (int8_t)trim_x1y1[1];
435     g_bmm150_trim_reg.dig_x2 = (int8_t)trim_xyz_data[2];
436     g_bmm150_trim_reg.dig_y2 = (int8_t)trim_xyz_data[3];
437     temp_msb = ((uint16_t)trim_xy1xy2[3]) << 8;
438     g_bmm150_trim_reg.dig_z1 = (uint16_t)(temp_msb | trim_xy1xy2[2]);
439     temp_msb = ((uint16_t)trim_xy1xy2[1]) << 8;
440     g_bmm150_trim_reg.dig_z2 = (int16_t)(temp_msb | trim_xy1xy2[0]);
441     temp_msb = ((uint16_t)trim_xy1xy2[7]) << 8;
442     g_bmm150_trim_reg.dig_z3 = (int16_t)(temp_msb | trim_xy1xy2[6]);
443     temp_msb = ((uint16_t)trim_xyz_data[1]) << 8;
444     g_bmm150_trim_reg.dig_z4 = (int16_t)(temp_msb | trim_xyz_data[0]);
445     g_bmm150_trim_reg.dig_xy1 = trim_xy1xy2[9];
446     g_bmm150_trim_reg.dig_xy2 = (int8_t)trim_xy1xy2[8];
447     temp_msb = ((uint16_t)(trim_xy1xy2[5] & 0x7F)) << 8;
448     g_bmm150_trim_reg.dig_xyz1 = (uint16_t)(temp_msb | trim_xy1xy2[4]);
449 
450     return ret;
451 }
452 
453 
drv_mag_bosch_bmm150_read(void * buf,size_t len)454 int drv_mag_bosch_bmm150_read(void *buf, size_t len)
455 {
456     int          ret  = 0;
457     size_t       size = 0;
458     uint8_t      reg[8];
459     int16_t     msb_data;
460     int16_t     raw_datax;
461     int16_t     raw_datay;
462     int16_t     raw_dataz;
463     uint16_t    raw_data_r;
464     mag_data_t *mag = (mag_data_t *)buf;
465     if (mag == NULL) {
466         return -1;
467     }
468 
469     size = sizeof(mag_data_t);
470     if (len < size) {
471         return -1;
472     }
473 
474     ret = sensor_i2c_read(&bmm150_ctx, BMM150_DATA_X_LSB, &reg[0],
475                           8, I2C_OP_RETRIES);
476 
477     if (unlikely(ret)) {
478         return -1;
479     }
480 
481     reg[0] = BMM150_GET_BITSLICE(reg[0], BMM150_DATA_X);
482     msb_data = ((int16_t)((int8_t)reg[1])) * 32;
483     raw_datax = (int16_t)(msb_data | reg[0]);
484 
485     reg[2] = BMM150_GET_BITSLICE(reg[2], BMM150_DATA_Y);
486     msb_data = ((int16_t)((int8_t)reg[3])) * 32;
487     raw_datay = (int16_t)(msb_data | reg[2]);
488 
489     reg[4] = BMM150_GET_BITSLICE(reg[4], BMM150_DATA_Z);
490     msb_data = ((int16_t)((int8_t)reg[5])) * 128;
491     raw_dataz = (int16_t)(msb_data | reg[4]);
492 
493     reg[6] = BMM150_GET_BITSLICE(reg[6], BMM150_DATA_RHALL);
494     raw_data_r = (uint16_t)(((uint16_t)reg[7] << 6) | reg[6]);
495 
496     mag->data[0] = (int32_t)drv_mag_bosch_bmm150_compensate_x(raw_datax, raw_data_r);
497 
498     mag->data[1] = (int32_t)drv_mag_bosch_bmm150_compensate_y(raw_datay, raw_data_r);
499 
500     mag->data[2] = (int32_t)drv_mag_bosch_bmm150_compensate_z(raw_dataz, raw_data_r);
501 
502     mag->data[0] = mag->data[0] * BMM150_DATA_UT_2_MG;
503     mag->data[1] = mag->data[1] * BMM150_DATA_UT_2_MG;
504     mag->data[2] = mag->data[2] * BMM150_DATA_UT_2_MG;
505 
506     mag->timestamp = aos_now_ms();
507     return (int)size;
508 }
509 
drv_mag_bosch_bmm150_ioctl(int cmd,unsigned long arg)510 static int drv_mag_bosch_bmm150_ioctl(int cmd, unsigned long arg)
511 {
512     int ret = 0;
513 
514     switch (cmd) {
515         case SENSOR_IOCTL_ODR_SET: {
516             ret = drv_mag_bosch_bmm150_set_odr(&bmm150_ctx, arg);
517             if (unlikely(ret)) {
518                 return -1;
519             }
520         } break;
521         case SENSOR_IOCTL_RANGE_SET: {
522 
523         } break;
524         case SENSOR_IOCTL_SET_POWER: {
525             ret = drv_mag_bosch_bmm150_set_power_mode(&bmm150_ctx, arg);
526             if (unlikely(ret)) {
527                 return -1;
528             }
529         } break;
530         case SENSOR_IOCTL_GET_INFO: {
531             /* fill the dev info here */
532             dev_sensor_info_t *info = (dev_sensor_info_t *)arg;
533             info->model             = "BMM150";
534             info->range_max         = 2500;
535             info->range_min         = 2500;
536             info->unit              = udps;
537         } break;
538 
539         default:
540             break;
541     }
542 
543     return 0;
544 }
545 
drv_mag_bosch_bmm150_init(void)546 int drv_mag_bosch_bmm150_init(void)
547 {
548     int          ret = 0;
549     sensor_obj_t sensor;
550     memset(&sensor, 0, sizeof(sensor));
551     /* fill the sensor obj parameters here */
552     sensor.io_port    = I2C_PORT;
553     sensor.tag        = TAG_DEV_MAG;
554     sensor.path       = dev_mag_path;
555     sensor.open       = drv_mag_bosch_bmm150_open;
556     sensor.close      = drv_mag_bosch_bmm150_close;
557     sensor.read       = drv_mag_bosch_bmm150_read;
558     sensor.write      = NULL;
559     sensor.ioctl      = drv_mag_bosch_bmm150_ioctl;
560     sensor.irq_handle = drv_mag_bosch_bmm150_irq_handle;
561 
562     ret = sensor_create_obj(&sensor);
563     if (unlikely(ret)) {
564         return -1;
565     }
566 
567     ret = drv_mag_bosch_bmm150_set_power_mode(&bmm150_ctx, DEV_POWER_ON);
568     if (unlikely(ret)) {
569         return -1;
570     }
571     aos_msleep(10);
572     ret = drv_mag_bosch_bmm150_validate_id(&bmm150_ctx, BMM150_CHIP_ID_VALUE);
573     if (unlikely(ret)) {
574         return -1;
575     }
576 
577     ret = drv_mag_bosch_bmm150_set_odr(&bmm150_ctx, 2);
578     if (unlikely(ret)) {
579         return -1;
580     }
581 
582     memset(&g_bmm150_trim_reg, 0, sizeof(g_bmm150_trim_reg));
583     ret = drv_mag_bosch_bmm150_read_calib_reg(&bmm150_ctx);
584     if (unlikely(ret)) {
585         return -1;
586     }
587 
588     /* update the phy sensor info to sensor hal */
589     LOG("%s %s successfully \n", SENSOR_STR, __func__);
590     return 0;
591 }
592 
593 SENSOR_DRV_ADD(drv_mag_bosch_bmm150_init);