1 /* BMA150 motion sensor driver
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
16 #include <linux/interrupt.h>
17 #include <linux/i2c.h>
18 #include <linux/slab.h>
19 #include <linux/irq.h>
20 #include <linux/miscdevice.h>
21 #include <asm/uaccess.h>
22 #include <linux/delay.h>
23 #include <linux/input.h>
24 #include <linux/workqueue.h>
25 #include <linux/kobject.h>
26 #include <linux/earlysuspend.h>
27 #include <linux/platform_device.h>
28 #include <asm/atomic.h>
30 #include <mach/mt_typedefs.h>
31 #include <mach/mt_gpio.h>
32 #include <mach/mt_pm_ldo.h>
34 #define POWER_NONE_MACRO MT65XX_POWER_NONE
37 #include <linux/hwmsensor.h>
38 #include <linux/hwmsen_dev.h>
39 #include <linux/sensors_io.h>
41 #include <linux/hwmsen_helper.h>
44 #include <linux/batch.h>
45 #ifdef CUSTOM_KERNEL_SENSORHUB
46 #include <SCP_sensorHub.h>
47 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
49 /*----------------------------------------------------------------------------*/
50 #define I2C_DRIVERID_BMA222 222
51 /*----------------------------------------------------------------------------*/
53 /*----------------------------------------------------------------------------*/
55 #define SW_CALIBRATION
57 /*----------------------------------------------------------------------------*/
58 #define BMA222_AXIS_X 0
59 #define BMA222_AXIS_Y 1
60 #define BMA222_AXIS_Z 2
61 #define BMA222_DATA_LEN 6
62 #define BMA222_DEV_NAME "BMA222"
63 /*----------------------------------------------------------------------------*/
66 /*----------------------------------------------------------------------------*/
67 static const struct i2c_device_id bma222_i2c_id
[] = {{BMA222_DEV_NAME
,0},{}};
68 static struct i2c_board_info __initdata i2c_BMA222
={ I2C_BOARD_INFO(BMA222_DEV_NAME
, 0x18)};
71 /*----------------------------------------------------------------------------*/
72 static int bma222_i2c_probe(struct i2c_client
*client
, const struct i2c_device_id
*id
);
73 static int bma222_i2c_remove(struct i2c_client
*client
);
74 #if !defined(CONFIG_HAS_EARLYSUSPEND) || !defined(USE_EARLY_SUSPEND)
75 static int bma222_suspend(struct i2c_client
*client
, pm_message_t msg
);
76 static int bma222_resume(struct i2c_client
*client
);
79 static int gsensor_local_init(void);
80 static int gsensor_remove(void);
81 #ifdef CUSTOM_KERNEL_SENSORHUB
82 static int gsensor_setup_irq(void);
83 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
84 static int gsensor_set_delay(u64 ns
);
85 /*----------------------------------------------------------------------------*/
87 ADX_TRC_FILTER
= 0x01,
88 ADX_TRC_RAWDATA
= 0x02,
93 /*----------------------------------------------------------------------------*/
98 /*----------------------------------------------------------------------------*/
99 struct data_resolution
{
100 struct scale_factor scalefactor
;
103 /*----------------------------------------------------------------------------*/
104 #define C_MAX_FIR_LENGTH (32)
105 /*----------------------------------------------------------------------------*/
107 s16 raw
[C_MAX_FIR_LENGTH
][BMA222_AXES_NUM
];
108 int sum
[BMA222_AXES_NUM
];
112 /*----------------------------------------------------------------------------*/
113 struct bma222_i2c_data
{
114 struct i2c_client
*client
;
116 struct hwmsen_convert cvt
;
117 #ifdef CUSTOM_KERNEL_SENSORHUB
118 struct work_struct irq_work
;
119 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
122 struct data_resolution
*reso
;
127 s16 cali_sw
[BMA222_AXES_NUM
+1];
130 s8 offset
[BMA222_AXES_NUM
+1]; /*+1: for 4-byte alignment*/
131 s16 data
[BMA222_AXES_NUM
+1];
133 #ifdef CUSTOM_KERNEL_SENSORHUB
135 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
138 #if defined(CONFIG_BMA222_LOWPASS)
141 struct data_filter fir
;
144 #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(USE_EARLY_SUSPEND)
145 struct early_suspend early_drv
;
149 /*----------------------------------------------------------------------------*/
150 static struct i2c_driver bma222_i2c_driver
= {
152 // .owner = THIS_MODULE,
153 .name
= BMA222_DEV_NAME
,
155 .probe
= bma222_i2c_probe
,
156 .remove
= bma222_i2c_remove
,
157 #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(USE_EARLY_SUSPEND)
158 .suspend
= bma222_suspend
,
159 .resume
= bma222_resume
,
161 .id_table
= bma222_i2c_id
,
162 // .address_data = &bma222_addr_data,
165 /*----------------------------------------------------------------------------*/
166 static struct i2c_client
*bma222_i2c_client
= NULL
;
167 static struct bma222_i2c_data
*obj_i2c_data
= NULL
;
168 static bool sensor_power
= true;
169 static int sensor_suspend
= 0;
170 static GSENSOR_VECTOR3D gsensor_gain
;
171 //static char selftestRes[8]= {0};
172 static DEFINE_MUTEX(gsensor_mutex
);
173 static DEFINE_MUTEX(gsensor_scp_en_mutex
);
176 static bool enable_status
= false;
178 static int gsensor_init_flag
=-1; // 0<==>OK -1 <==> fail
179 static struct acc_init_info bma222_init_info
= {
180 .name
= BMA222_DEV_NAME
,
181 .init
= gsensor_local_init
,
182 .uninit
= gsensor_remove
,
185 /*----------------------------------------------------------------------------*/
187 #define GSE_TAG "[Gsensor] "
188 #define GSE_FUN(f) printk(GSE_TAG"%s\n", __FUNCTION__)
189 #define GSE_ERR(fmt, args...) printk(GSE_TAG"%s %d : "fmt, __FUNCTION__, __LINE__, ##args)
190 #define GSE_LOG(fmt, args...) printk(GSE_TAG fmt, ##args)
194 #define GSE_ERR(fmt, args...)
195 #define GSE_LOG(fmt, args...)
198 /*----------------------------------------------------------------------------*/
199 static struct data_resolution bma222_data_resolution
[1] = {
200 /* combination by {FULL_RES,RANGE}*/
201 {{ 15, 6}, 64}, // dataformat +/-2g in 8-bit resolution; { 15, 6} = 15.6= (2*2*1000)/(2^8); 64 = (2^8)/(2*2)
203 /*----------------------------------------------------------------------------*/
204 static struct data_resolution bma222_offset_resolution
= {{15, 6}, 64};
206 /*----------------------------------------------------------------------------*/
207 static int bma_i2c_read_block(struct i2c_client
*client
, u8 addr
, u8
*data
, u8 len
)
211 struct i2c_msg msgs
[2]={{0},{0}};
213 mutex_lock(&gsensor_mutex
);
215 msgs
[0].addr
= client
->addr
;
220 msgs
[1].addr
= client
->addr
;
221 msgs
[1].flags
= I2C_M_RD
;
227 mutex_unlock(&gsensor_mutex
);
230 else if (len
> C_I2C_FIFO_SIZE
)
232 GSE_ERR(" length %d exceeds %d\n", len
, C_I2C_FIFO_SIZE
);
233 mutex_unlock(&gsensor_mutex
);
236 err
= i2c_transfer(client
->adapter
, msgs
, sizeof(msgs
)/sizeof(msgs
[0]));
239 GSE_ERR("i2c_transfer error: (%d %p %d) %d\n",addr
, data
, len
, err
);
246 mutex_unlock(&gsensor_mutex
);
250 EXPORT_SYMBOL(bma_i2c_read_block
);
251 static int bma_i2c_write_block(struct i2c_client
*client
, u8 addr
, u8
*data
, u8 len
)
252 { /*because address also occupies one byte, the maximum length for write is 7 bytes*/
254 char buf
[C_I2C_FIFO_SIZE
];
256 mutex_lock(&gsensor_mutex
);
259 mutex_unlock(&gsensor_mutex
);
262 else if (len
>= C_I2C_FIFO_SIZE
)
264 GSE_ERR(" length %d exceeds %d\n", len
, C_I2C_FIFO_SIZE
);
265 mutex_unlock(&gsensor_mutex
);
271 for (idx
= 0; idx
< len
; idx
++)
273 buf
[num
++] = data
[idx
];
276 err
= i2c_master_send(client
, buf
, num
);
279 GSE_ERR("send command error!!\n");
280 mutex_unlock(&gsensor_mutex
);
283 mutex_unlock(&gsensor_mutex
);
286 EXPORT_SYMBOL(bma_i2c_write_block
);
288 /*----------------------------------------------------------------------------*/
289 /*--------------------Add by Susan----------------------------------*/
290 #ifdef CUSTOM_KERNEL_SENSORHUB
291 int BMA222_SCP_SetPowerMode(bool enable
, int sensorType
)
293 static bool gsensor_scp_en_status
= false;
294 static unsigned int gsensor_scp_en_map
= 0;
295 SCP_SENSOR_HUB_DATA req
;
299 mutex_lock(&gsensor_scp_en_mutex
);
301 if (sensorType
>= 32)
303 GSE_ERR("Out of index!\n");
309 gsensor_scp_en_map
|= (1<<sensorType
);
313 gsensor_scp_en_map
&= ~(1<<sensorType
);
316 if (0 == gsensor_scp_en_map
)
321 if (gsensor_scp_en_status
!= enable
)
323 gsensor_scp_en_status
= enable
;
325 req
.activate_req
.sensorType
= ID_ACCELEROMETER
;
326 req
.activate_req
.action
= SENSOR_HUB_ACTIVATE
;
327 req
.activate_req
.enable
= enable
;
328 len
= sizeof(req
.activate_req
);
329 err
= SCP_sensorHub_req_send(&req
, &len
, 1);
332 GSE_ERR("SCP_sensorHub_req_send fail\n");
336 mutex_unlock(&gsensor_scp_en_mutex
);
340 EXPORT_SYMBOL(BMA222_SCP_SetPowerMode
);
342 /*----------------------------------------------------------------------------*/
343 /*--------------------BMA222 power control function----------------------------------*/
344 static void BMA222_power(struct acc_hw
*hw
, unsigned int on
)
346 #ifndef FPGA_EARLY_PORTING
347 static unsigned int power_on
= 0;
349 if(hw
->power_id
!= POWER_NONE_MACRO
) // have externel LDO
351 GSE_LOG("power %s\n", on
? "on" : "off");
352 if(power_on
== on
) // power status not change
354 GSE_LOG("ignore power control: %d\n", on
);
356 else if(on
) // power on
358 if(!hwPowerOn(hw
->power_id
, hw
->power_vol
, "BMA222"))
360 GSE_ERR("power on fails!!\n");
365 if (!hwPowerDown(hw
->power_id
, "BMA222"))
367 GSE_ERR("power off fail!!\n");
372 #endif //#ifndef FPGA_EARLY_PORTING
374 /*----------------------------------------------------------------------------*/
376 /*----------------------------------------------------------------------------*/
377 static int BMA222_SetDataResolution(struct bma222_i2c_data
*obj
)
380 /*set g sensor dataresolution here*/
382 /*BMA222 only can set to 10-bit dataresolution, so do nothing in bma222 driver here*/
384 /*end of set dataresolution*/
388 /*we set measure range from -2g to +2g in BMA150_SetDataFormat(client, BMA150_RANGE_2G),
389 and set 10-bit dataresolution BMA150_SetDataResolution()*/
391 /*so bma222_data_resolution[0] set value as {{ 3, 9}, 256} when declaration, and assign the value to obj->reso here*/
393 obj
->reso
= &bma222_data_resolution
[0];
396 /*if you changed the measure range, for example call: BMA222_SetDataFormat(client, BMA150_RANGE_4G),
397 you must set the right value to bma222_data_resolution*/
400 /*----------------------------------------------------------------------------*/
401 static int BMA222_ReadData(struct i2c_client
*client
, s16 data
[BMA222_AXES_NUM
])
403 struct bma222_i2c_data
*priv
= i2c_get_clientdata(client
);
405 #if 0 //CUSTOM_KERNEL_SENSORHUB
406 SCP_SENSOR_HUB_DATA req
;
408 #else //#ifdef CUSTOM_KERNEL_SENSORHUB
409 u8 addr
= BMA222_REG_DATAXLOW
;
410 u8 buf
[BMA222_DATA_LEN
] = {0};
411 #endif //#ifdef CUSTOM_KERNEL_SENSORHUB
413 #if 0 // CUSTOM_KERNEL_SENSORHUB
414 req
.get_data_req
.sensorType
= ID_ACCELEROMETER
;
415 req
.get_data_req
.action
= SENSOR_HUB_GET_DATA
;
416 len
= sizeof(req
.get_data_req
);
417 err
= SCP_sensorHub_req_send(&req
, &len
, 1);
420 GSE_ERR("SCP_sensorHub_req_send!\n");
424 if (ID_ACCELEROMETER
!= req
.get_data_rsp
.sensorType
||
425 SENSOR_HUB_GET_DATA
!= req
.get_data_rsp
.action
||
426 0 != req
.get_data_rsp
.errCode
)
428 GSE_ERR("error : %d\n", req
.get_data_rsp
.errCode
);
429 return req
.get_data_rsp
.errCode
;
432 len
-= offsetof(SCP_SENSOR_HUB_GET_DATA_RSP
, int8_Data
);
436 data
[BMA222_AXIS_X
] = req
.get_data_rsp
.int16_Data
[0];
437 data
[BMA222_AXIS_Y
] = req
.get_data_rsp
.int16_Data
[1];
438 data
[BMA222_AXIS_Z
] = req
.get_data_rsp
.int16_Data
[2];
442 GSE_ERR("data length fail : %d\n", len
);
445 if(atomic_read(&priv
->trace
) & ADX_TRC_RAWDATA
)
449 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
454 else if((err
= bma_i2c_read_block(client
, addr
, buf
, 0x05))!=0)
456 GSE_ERR("error: %d\n", err
);
460 data
[BMA222_AXIS_X
] = (s16
)buf
[BMA222_AXIS_X
*2] ;
461 data
[BMA222_AXIS_Y
] = (s16
)buf
[BMA222_AXIS_Y
*2];
462 data
[BMA222_AXIS_Z
] = (s16
)buf
[BMA222_AXIS_Z
*2] ;
463 if(atomic_read(&priv
->trace
) & ADX_TRC_RAWDATA
)
465 GSE_LOG("[%08X %08X %08X] => [%5d %5d %5d] before\n", data
[BMA222_AXIS_X
], data
[BMA222_AXIS_Y
], data
[BMA222_AXIS_Z
],
466 data
[BMA222_AXIS_X
], data
[BMA222_AXIS_Y
], data
[BMA222_AXIS_Z
]);
469 if(data
[BMA222_AXIS_X
]&0x80)
471 data
[BMA222_AXIS_X
] = ~data
[BMA222_AXIS_X
];
472 data
[BMA222_AXIS_X
] &= 0xff;
473 data
[BMA222_AXIS_X
]+=1;
474 data
[BMA222_AXIS_X
] = -data
[BMA222_AXIS_X
];
476 if(data
[BMA222_AXIS_Y
]&0x80)
478 data
[BMA222_AXIS_Y
] = ~data
[BMA222_AXIS_Y
];
479 data
[BMA222_AXIS_Y
] &= 0xff;
480 data
[BMA222_AXIS_Y
]+=1;
481 data
[BMA222_AXIS_Y
] = -data
[BMA222_AXIS_Y
];
483 if(data
[BMA222_AXIS_Z
]&0x80)
485 data
[BMA222_AXIS_Z
] = ~data
[BMA222_AXIS_Z
];
486 data
[BMA222_AXIS_Z
] &= 0xff;
487 data
[BMA222_AXIS_Z
]+=1;
488 data
[BMA222_AXIS_Z
] = -data
[BMA222_AXIS_Z
];
491 if(atomic_read(&priv
->trace
) & ADX_TRC_RAWDATA
)
493 GSE_LOG("[%08X %08X %08X] => [%5d %5d %5d] after\n", data
[BMA222_AXIS_X
], data
[BMA222_AXIS_Y
], data
[BMA222_AXIS_Z
],
494 data
[BMA222_AXIS_X
], data
[BMA222_AXIS_Y
], data
[BMA222_AXIS_Z
]);
496 #ifdef CONFIG_BMA222_LOWPASS
497 if(atomic_read(&priv
->filter
))
499 if(atomic_read(&priv
->fir_en
) && !atomic_read(&priv
->suspend
))
501 int idx
, firlen
= atomic_read(&priv
->firlen
);
502 if(priv
->fir
.num
< firlen
)
504 priv
->fir
.raw
[priv
->fir
.num
][BMA222_AXIS_X
] = data
[BMA222_AXIS_X
];
505 priv
->fir
.raw
[priv
->fir
.num
][BMA222_AXIS_Y
] = data
[BMA222_AXIS_Y
];
506 priv
->fir
.raw
[priv
->fir
.num
][BMA222_AXIS_Z
] = data
[BMA222_AXIS_Z
];
507 priv
->fir
.sum
[BMA222_AXIS_X
] += data
[BMA222_AXIS_X
];
508 priv
->fir
.sum
[BMA222_AXIS_Y
] += data
[BMA222_AXIS_Y
];
509 priv
->fir
.sum
[BMA222_AXIS_Z
] += data
[BMA222_AXIS_Z
];
510 if(atomic_read(&priv
->trace
) & ADX_TRC_FILTER
)
512 GSE_LOG("add [%2d] [%5d %5d %5d] => [%5d %5d %5d]\n", priv
->fir
.num
,
513 priv
->fir
.raw
[priv
->fir
.num
][BMA222_AXIS_X
], priv
->fir
.raw
[priv
->fir
.num
][BMA222_AXIS_Y
], priv
->fir
.raw
[priv
->fir
.num
][BMA222_AXIS_Z
],
514 priv
->fir
.sum
[BMA222_AXIS_X
], priv
->fir
.sum
[BMA222_AXIS_Y
], priv
->fir
.sum
[BMA222_AXIS_Z
]);
521 idx
= priv
->fir
.idx
% firlen
;
522 priv
->fir
.sum
[BMA222_AXIS_X
] -= priv
->fir
.raw
[idx
][BMA222_AXIS_X
];
523 priv
->fir
.sum
[BMA222_AXIS_Y
] -= priv
->fir
.raw
[idx
][BMA222_AXIS_Y
];
524 priv
->fir
.sum
[BMA222_AXIS_Z
] -= priv
->fir
.raw
[idx
][BMA222_AXIS_Z
];
525 priv
->fir
.raw
[idx
][BMA222_AXIS_X
] = data
[BMA222_AXIS_X
];
526 priv
->fir
.raw
[idx
][BMA222_AXIS_Y
] = data
[BMA222_AXIS_Y
];
527 priv
->fir
.raw
[idx
][BMA222_AXIS_Z
] = data
[BMA222_AXIS_Z
];
528 priv
->fir
.sum
[BMA222_AXIS_X
] += data
[BMA222_AXIS_X
];
529 priv
->fir
.sum
[BMA222_AXIS_Y
] += data
[BMA222_AXIS_Y
];
530 priv
->fir
.sum
[BMA222_AXIS_Z
] += data
[BMA222_AXIS_Z
];
532 data
[BMA222_AXIS_X
] = priv
->fir
.sum
[BMA222_AXIS_X
]/firlen
;
533 data
[BMA222_AXIS_Y
] = priv
->fir
.sum
[BMA222_AXIS_Y
]/firlen
;
534 data
[BMA222_AXIS_Z
] = priv
->fir
.sum
[BMA222_AXIS_Z
]/firlen
;
535 if(atomic_read(&priv
->trace
) & ADX_TRC_FILTER
)
537 GSE_LOG("add [%2d] [%5d %5d %5d] => [%5d %5d %5d] : [%5d %5d %5d]\n", idx
,
538 priv
->fir
.raw
[idx
][BMA222_AXIS_X
], priv
->fir
.raw
[idx
][BMA222_AXIS_Y
], priv
->fir
.raw
[idx
][BMA222_AXIS_Z
],
539 priv
->fir
.sum
[BMA222_AXIS_X
], priv
->fir
.sum
[BMA222_AXIS_Y
], priv
->fir
.sum
[BMA222_AXIS_Z
],
540 data
[BMA222_AXIS_X
], data
[BMA222_AXIS_Y
], data
[BMA222_AXIS_Z
]);
550 /*----------------------------------------------------------------------------*/
552 static int BMA222_ReadOffset(struct i2c_client
*client
, s8 ofs
[BMA222_AXES_NUM
])
558 #ifdef SW_CALIBRATION
559 ofs
[0]=ofs
[1]=ofs
[2]=0x0;
561 if((err
= bma_i2c_read_block(client
, BMA222_REG_OFSX
, ofs
, BMA222_AXES_NUM
)))
563 GSE_ERR("error: %d\n", err
);
566 //printk("offesx=%x, y=%x, z=%x",ofs[0],ofs[1],ofs[2]);
571 /*----------------------------------------------------------------------------*/
572 static int BMA222_ResetCalibration(struct i2c_client
*client
)
574 struct bma222_i2c_data
*obj
= i2c_get_clientdata(client
);
575 //u8 ofs[4]={0,0,0,0};
577 #ifdef CUSTOM_KERNEL_SENSORHUB
578 SCP_SENSOR_HUB_DATA data
;
579 BMA222_CUST_DATA
*pCustData
;
587 #ifdef CUSTOM_KERNEL_SENSORHUB
588 if (0 != obj
->SCP_init_done
)
590 pCustData
= (BMA222_CUST_DATA
*)&data
.set_cust_req
.custData
;
592 data
.set_cust_req
.sensorType
= ID_ACCELEROMETER
;
593 data
.set_cust_req
.action
= SENSOR_HUB_SET_CUST
;
594 pCustData
->resetCali
.action
= BMA222_CUST_ACTION_RESET_CALI
;
595 len
= offsetof(SCP_SENSOR_HUB_SET_CUST_REQ
, custData
) + sizeof(pCustData
->resetCali
);
596 SCP_sensorHub_req_send(&data
, &len
, 1);
600 memset(obj
->cali_sw
, 0x00, sizeof(obj
->cali_sw
));
601 memset(obj
->offset
, 0x00, sizeof(obj
->offset
));
604 /*----------------------------------------------------------------------------*/
605 static int BMA222_ReadCalibration(struct i2c_client
*client
, int dat
[BMA222_AXES_NUM
])
607 struct bma222_i2c_data
*obj
= i2c_get_clientdata(client
);
612 #ifdef SW_CALIBRATION
613 mul
= 0;//only SW Calibration, disable HW Calibration
615 if ((err
= BMA222_ReadOffset(client
, obj
->offset
))) {
616 GSE_ERR("read offset fail, %d\n", err
);
619 mul
= obj
->reso
->sensitivity
/bma222_offset_resolution
.sensitivity
;
622 dat
[obj
->cvt
.map
[BMA222_AXIS_X
]] = obj
->cvt
.sign
[BMA222_AXIS_X
]*(obj
->offset
[BMA222_AXIS_X
]*mul
+ obj
->cali_sw
[BMA222_AXIS_X
]);
623 dat
[obj
->cvt
.map
[BMA222_AXIS_Y
]] = obj
->cvt
.sign
[BMA222_AXIS_Y
]*(obj
->offset
[BMA222_AXIS_Y
]*mul
+ obj
->cali_sw
[BMA222_AXIS_Y
]);
624 dat
[obj
->cvt
.map
[BMA222_AXIS_Z
]] = obj
->cvt
.sign
[BMA222_AXIS_Z
]*(obj
->offset
[BMA222_AXIS_Z
]*mul
+ obj
->cali_sw
[BMA222_AXIS_Z
]);
628 /*----------------------------------------------------------------------------*/
629 static int BMA222_ReadCalibrationEx(struct i2c_client
*client
, int act
[BMA222_AXES_NUM
], int raw
[BMA222_AXES_NUM
])
631 /*raw: the raw calibration data; act: the actual calibration data*/
632 struct bma222_i2c_data
*obj
= i2c_get_clientdata(client
);
638 #ifdef SW_CALIBRATION
639 mul
= 0;//only SW Calibration, disable HW Calibration
641 if((err
= BMA222_ReadOffset(client
, obj
->offset
)))
643 GSE_ERR("read offset fail, %d\n", err
);
646 mul
= obj
->reso
->sensitivity
/bma222_offset_resolution
.sensitivity
;
649 raw
[BMA222_AXIS_X
] = obj
->offset
[BMA222_AXIS_X
]*mul
+ obj
->cali_sw
[BMA222_AXIS_X
];
650 raw
[BMA222_AXIS_Y
] = obj
->offset
[BMA222_AXIS_Y
]*mul
+ obj
->cali_sw
[BMA222_AXIS_Y
];
651 raw
[BMA222_AXIS_Z
] = obj
->offset
[BMA222_AXIS_Z
]*mul
+ obj
->cali_sw
[BMA222_AXIS_Z
];
653 act
[obj
->cvt
.map
[BMA222_AXIS_X
]] = obj
->cvt
.sign
[BMA222_AXIS_X
]*raw
[BMA222_AXIS_X
];
654 act
[obj
->cvt
.map
[BMA222_AXIS_Y
]] = obj
->cvt
.sign
[BMA222_AXIS_Y
]*raw
[BMA222_AXIS_Y
];
655 act
[obj
->cvt
.map
[BMA222_AXIS_Z
]] = obj
->cvt
.sign
[BMA222_AXIS_Z
]*raw
[BMA222_AXIS_Z
];
659 /*----------------------------------------------------------------------------*/
660 static int BMA222_WriteCalibration(struct i2c_client
*client
, int dat
[BMA222_AXES_NUM
])
662 struct bma222_i2c_data
*obj
= i2c_get_clientdata(client
);
664 int cali
[BMA222_AXES_NUM
], raw
[BMA222_AXES_NUM
];
665 #ifdef CUSTOM_KERNEL_SENSORHUB
666 SCP_SENSOR_HUB_DATA data
;
667 BMA222_CUST_DATA
*pCustData
;
672 if(0 != (err
= BMA222_ReadCalibrationEx(client
, cali
, raw
))) /*offset will be updated in obj->offset*/
674 GSE_ERR("read offset fail, %d\n", err
);
678 GSE_LOG("OLDOFF: (%+3d %+3d %+3d): (%+3d %+3d %+3d) / (%+3d %+3d %+3d)\n",
679 raw
[BMA222_AXIS_X
], raw
[BMA222_AXIS_Y
], raw
[BMA222_AXIS_Z
],
680 obj
->offset
[BMA222_AXIS_X
], obj
->offset
[BMA222_AXIS_Y
], obj
->offset
[BMA222_AXIS_Z
],
681 obj
->cali_sw
[BMA222_AXIS_X
], obj
->cali_sw
[BMA222_AXIS_Y
], obj
->cali_sw
[BMA222_AXIS_Z
]);
683 #ifdef CUSTOM_KERNEL_SENSORHUB
684 pCustData
= (BMA222_CUST_DATA
*)data
.set_cust_req
.custData
;
685 data
.set_cust_req
.sensorType
= ID_ACCELEROMETER
;
686 data
.set_cust_req
.action
= SENSOR_HUB_SET_CUST
;
687 pCustData
->setCali
.action
= BMA222_CUST_ACTION_SET_CALI
;
688 pCustData
->setCali
.data
[BMA222_AXIS_X
] = dat
[BMA222_AXIS_X
];
689 pCustData
->setCali
.data
[BMA222_AXIS_Y
] = dat
[BMA222_AXIS_Y
];
690 pCustData
->setCali
.data
[BMA222_AXIS_Z
] = dat
[BMA222_AXIS_Z
];
691 len
= offsetof(SCP_SENSOR_HUB_SET_CUST_REQ
, custData
) + sizeof(pCustData
->setCali
);
692 SCP_sensorHub_req_send(&data
, &len
, 1);
695 /*calculate the real offset expected by caller*/
696 cali
[BMA222_AXIS_X
] += dat
[BMA222_AXIS_X
];
697 cali
[BMA222_AXIS_Y
] += dat
[BMA222_AXIS_Y
];
698 cali
[BMA222_AXIS_Z
] += dat
[BMA222_AXIS_Z
];
700 GSE_LOG("UPDATE: (%+3d %+3d %+3d)\n",
701 dat
[BMA222_AXIS_X
], dat
[BMA222_AXIS_Y
], dat
[BMA222_AXIS_Z
]);
703 #ifdef SW_CALIBRATION
704 obj
->cali_sw
[BMA222_AXIS_X
] = obj
->cvt
.sign
[BMA222_AXIS_X
]*(cali
[obj
->cvt
.map
[BMA222_AXIS_X
]]);
705 obj
->cali_sw
[BMA222_AXIS_Y
] = obj
->cvt
.sign
[BMA222_AXIS_Y
]*(cali
[obj
->cvt
.map
[BMA222_AXIS_Y
]]);
706 obj
->cali_sw
[BMA222_AXIS_Z
] = obj
->cvt
.sign
[BMA222_AXIS_Z
]*(cali
[obj
->cvt
.map
[BMA222_AXIS_Z
]]);
708 int divisor
= obj
->reso
->sensitivity
/lsb
;//modified
709 obj
->offset
[BMA222_AXIS_X
] = (s8
)(obj
->cvt
.sign
[BMA222_AXIS_X
]*(cali
[obj
->cvt
.map
[BMA222_AXIS_X
]])/(divisor
));
710 obj
->offset
[BMA222_AXIS_Y
] = (s8
)(obj
->cvt
.sign
[BMA222_AXIS_Y
]*(cali
[obj
->cvt
.map
[BMA222_AXIS_Y
]])/(divisor
));
711 obj
->offset
[BMA222_AXIS_Z
] = (s8
)(obj
->cvt
.sign
[BMA222_AXIS_Z
]*(cali
[obj
->cvt
.map
[BMA222_AXIS_Z
]])/(divisor
));
713 /*convert software calibration using standard calibration*/
714 obj
->cali_sw
[BMA222_AXIS_X
] = obj
->cvt
.sign
[BMA222_AXIS_X
]*(cali
[obj
->cvt
.map
[BMA222_AXIS_X
]])%(divisor
);
715 obj
->cali_sw
[BMA222_AXIS_Y
] = obj
->cvt
.sign
[BMA222_AXIS_Y
]*(cali
[obj
->cvt
.map
[BMA222_AXIS_Y
]])%(divisor
);
716 obj
->cali_sw
[BMA222_AXIS_Z
] = obj
->cvt
.sign
[BMA222_AXIS_Z
]*(cali
[obj
->cvt
.map
[BMA222_AXIS_Z
]])%(divisor
);
718 GSE_LOG("NEWOFF: (%+3d %+3d %+3d): (%+3d %+3d %+3d) / (%+3d %+3d %+3d)\n",
719 obj
->offset
[BMA222_AXIS_X
]*divisor
+ obj
->cali_sw
[BMA222_AXIS_X
],
720 obj
->offset
[BMA222_AXIS_Y
]*divisor
+ obj
->cali_sw
[BMA222_AXIS_Y
],
721 obj
->offset
[BMA222_AXIS_Z
]*divisor
+ obj
->cali_sw
[BMA222_AXIS_Z
],
722 obj
->offset
[BMA222_AXIS_X
], obj
->offset
[BMA222_AXIS_Y
], obj
->offset
[BMA222_AXIS_Z
],
723 obj
->cali_sw
[BMA222_AXIS_X
], obj
->cali_sw
[BMA222_AXIS_Y
], obj
->cali_sw
[BMA222_AXIS_Z
]);
725 if((err
= hwmsen_write_block(obj
->client
, BMA222_REG_OFSX
, obj
->offset
, BMA222_AXES_NUM
)))
727 GSE_ERR("write offset fail: %d\n", err
);
734 /*----------------------------------------------------------------------------*/
735 static int BMA222_CheckDeviceID(struct i2c_client
*client
)
741 res
= bma_i2c_read_block(client
,BMA222_REG_DEVID
,databuf
,0x1);
744 goto exit_BMA222_CheckDeviceID
;
748 GSE_LOG("BMA222_CheckDeviceID %d done!\n ", databuf
[0]);
750 exit_BMA222_CheckDeviceID
:
753 GSE_ERR("BMA222_CheckDeviceID %d failt!\n ", BMA222_ERR_I2C
);
754 return BMA222_ERR_I2C
;
757 return BMA222_SUCCESS
;
759 /*----------------------------------------------------------------------------*/
760 static int BMA222_SetPowerMode(struct i2c_client
*client
, bool enable
)
762 struct bma222_i2c_data
*obj
= i2c_get_clientdata(client
);
766 u8 addr
= BMA222_REG_POWER_CTL
;
768 if(enable
== sensor_power
)
770 GSE_LOG("Sensor power status is newest!\n");
771 return BMA222_SUCCESS
;
774 if(bma_i2c_read_block(client
, addr
, databuf
, 0x01))
776 GSE_ERR("read power ctl register err!\n");
777 return BMA222_ERR_I2C
;
779 GSE_LOG("set power mode value = 0x%x!\n",databuf
[0]);
783 databuf
[0] &= ~BMA222_MEASURE_MODE
;
787 databuf
[0] |= BMA222_MEASURE_MODE
;
790 res
= bma_i2c_write_block(client
,BMA222_REG_POWER_CTL
,databuf
,0x1);
793 GSE_LOG("set power mode failed!\n");
794 return BMA222_ERR_I2C
;
796 else if(atomic_read(&obj
->trace
) & ADX_TRC_INFO
)
798 GSE_LOG("set power mode ok %d!\n", databuf
[1]);
802 sensor_power
= enable
;
804 //GSE_LOG("leave Sensor power status is sensor_power = %d\n",sensor_power);
805 return BMA222_SUCCESS
;
807 /*----------------------------------------------------------------------------*/
808 static int BMA222_SetDataFormat(struct i2c_client
*client
, u8 dataformat
)
810 struct bma222_i2c_data
*obj
= i2c_get_clientdata(client
);
814 if(bma_i2c_read_block(client
, BMA222_REG_DATA_FORMAT
, databuf
, 0x01))
816 printk("bma222 read Dataformat failt \n");
817 return BMA222_ERR_I2C
;
820 databuf
[0] &= ~BMA222_RANGE_MASK
;
821 databuf
[0] |= dataformat
;
823 res
= bma_i2c_write_block(client
,BMA222_REG_DATA_FORMAT
,databuf
,0x1);
826 return BMA222_ERR_I2C
;
829 //printk("BMA222_SetDataFormat OK! \n");
831 return BMA222_SetDataResolution(obj
);
833 /*----------------------------------------------------------------------------*/
834 static int BMA222_SetBWRate(struct i2c_client
*client
, u8 bwrate
)
839 if(bma_i2c_read_block(client
, BMA222_REG_BW_RATE
, databuf
, 0x01))
841 printk("bma222 read rate failt \n");
842 return BMA222_ERR_I2C
;
845 databuf
[0] &= ~BMA222_BW_MASK
;
846 databuf
[0] |= bwrate
;
849 res
= bma_i2c_write_block(client
,BMA222_REG_BW_RATE
,databuf
,0x1);
852 return BMA222_ERR_I2C
;
855 //printk("BMA222_SetBWRate OK! \n");
857 return BMA222_SUCCESS
;
859 /*----------------------------------------------------------------------------*/
860 static int BMA222_SetIntEnable(struct i2c_client
*client
, u8 intenable
)
865 res
= hwmsen_write_byte(client
, BMA222_INT_REG_1
, 0x00);
866 if(res
!= BMA222_SUCCESS
)
871 res
= hwmsen_write_byte(client
, BMA222_INT_REG_2
, 0x00);
872 if(res
!= BMA222_SUCCESS
)
876 //printk("BMA222 disable interrupt ...\n");
878 /*for disable interrupt function*/
880 return BMA222_SUCCESS
;
883 /*----------------------------------------------------------------------------*/
884 static int bma222_init_client(struct i2c_client
*client
, int reset_cali
)
886 struct bma222_i2c_data
*obj
= i2c_get_clientdata(client
);
892 res
= BMA222_CheckDeviceID(client
);
893 if(res
!= BMA222_SUCCESS
)
897 //printk("BMA222_CheckDeviceID ok \n");
899 res
= BMA222_SetBWRate(client
, BMA222_BW_100HZ
);
900 if(res
!= BMA222_SUCCESS
)
904 //printk("BMA222_SetBWRate OK!\n");
906 res
= BMA222_SetDataFormat(client
, BMA222_RANGE_2G
);
907 if(res
!= BMA222_SUCCESS
)
911 //printk("BMA222_SetDataFormat OK!\n");
913 gsensor_gain
.x
= gsensor_gain
.y
= gsensor_gain
.z
= obj
->reso
->sensitivity
;
915 #ifdef CUSTOM_KERNEL_SENSORHUB
916 res
= gsensor_setup_irq();
917 if(res
!= BMA222_SUCCESS
)
921 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
923 res
= BMA222_SetIntEnable(client
, 0x00);
924 if(res
!= BMA222_SUCCESS
)
928 //printk("BMA222 disable interrupt function!\n");
930 res
= BMA222_SetPowerMode(client
, enable_status
);//false);//
931 if(res
!= BMA222_SUCCESS
)
935 //printk("BMA222_SetPowerMode OK!\n");
940 /*reset calibration only in power on*/
941 res
= BMA222_ResetCalibration(client
);
942 if(res
!= BMA222_SUCCESS
)
947 GSE_LOG("bma222_init_client OK!\n");
948 #ifdef CONFIG_BMA222_LOWPASS
949 memset(&obj
->fir
, 0x00, sizeof(obj
->fir
));
951 return BMA222_SUCCESS
;
953 /*----------------------------------------------------------------------------*/
954 static int BMA222_ReadChipInfo(struct i2c_client
*client
, char *buf
, int bufsize
)
958 memset(databuf
, 0, sizeof(u8
)*10);
960 if((NULL
== buf
)||(bufsize
<=30))
971 sprintf(buf
, "BMA222 Chip");
974 /*----------------------------------------------------------------------------*/
975 static int BMA222_ReadSensorData(struct i2c_client
*client
, char *buf
, int bufsize
)
977 struct bma222_i2c_data
*obj
= (struct bma222_i2c_data
*)i2c_get_clientdata(client
);
979 int acc
[BMA222_AXES_NUM
];
981 memset(databuf
, 0, sizeof(u8
)*10);
993 if(sensor_suspend
== 1)
995 //GSE_LOG("sensor in suspend read not data!\n");
999 if((res
= BMA222_ReadData(client
, obj
->data
))!=0)
1001 GSE_ERR("I2C error: ret value=%d", res
);
1006 #if 0 // CUSTOM_KERNEL_SENSORHUB
1007 acc
[BMA222_AXIS_X
] = obj
->data
[BMA222_AXIS_X
];
1008 acc
[BMA222_AXIS_Y
] = obj
->data
[BMA222_AXIS_Y
];
1009 acc
[BMA222_AXIS_Z
] = obj
->data
[BMA222_AXIS_Z
];
1010 //data has been calibrated in SCP side.
1011 #else //#ifdef CUSTOM_KERNEL_SENSORHUB
1012 //GSE_LOG("raw data x=%d, y=%d, z=%d \n",obj->data[BMA222_AXIS_X],obj->data[BMA222_AXIS_Y],obj->data[BMA222_AXIS_Z]);
1013 obj
->data
[BMA222_AXIS_X
] += obj
->cali_sw
[BMA222_AXIS_X
];
1014 obj
->data
[BMA222_AXIS_Y
] += obj
->cali_sw
[BMA222_AXIS_Y
];
1015 obj
->data
[BMA222_AXIS_Z
] += obj
->cali_sw
[BMA222_AXIS_Z
];
1017 //printk("cali_sw x=%d, y=%d, z=%d \n",obj->cali_sw[BMA150_AXIS_X],obj->cali_sw[BMA150_AXIS_Y],obj->cali_sw[BMA150_AXIS_Z]);
1019 /*remap coordinate*/
1020 acc
[obj
->cvt
.map
[BMA222_AXIS_X
]] = obj
->cvt
.sign
[BMA222_AXIS_X
]*obj
->data
[BMA222_AXIS_X
];
1021 acc
[obj
->cvt
.map
[BMA222_AXIS_Y
]] = obj
->cvt
.sign
[BMA222_AXIS_Y
]*obj
->data
[BMA222_AXIS_Y
];
1022 acc
[obj
->cvt
.map
[BMA222_AXIS_Z
]] = obj
->cvt
.sign
[BMA222_AXIS_Z
]*obj
->data
[BMA222_AXIS_Z
];
1023 //printk("cvt x=%d, y=%d, z=%d \n",obj->cvt.sign[BMA150_AXIS_X],obj->cvt.sign[BMA150_AXIS_Y],obj->cvt.sign[BMA150_AXIS_Z]);
1026 //GSE_LOG("Mapped gsensor data: %d, %d, %d!\n", acc[BMA150_AXIS_X], acc[BMA150_AXIS_Y], acc[BMA150_AXIS_Z]);
1029 //printk("mg acc=%d, GRAVITY=%d, sensityvity=%d \n",acc[BMA150_AXIS_X],GRAVITY_EARTH_1000,obj->reso->sensitivity);
1030 acc
[BMA222_AXIS_X
] = acc
[BMA222_AXIS_X
] * GRAVITY_EARTH_1000
/ obj
->reso
->sensitivity
;
1031 acc
[BMA222_AXIS_Y
] = acc
[BMA222_AXIS_Y
] * GRAVITY_EARTH_1000
/ obj
->reso
->sensitivity
;
1032 acc
[BMA222_AXIS_Z
] = acc
[BMA222_AXIS_Z
] * GRAVITY_EARTH_1000
/ obj
->reso
->sensitivity
;
1033 #endif //#ifdef CUSTOM_KERNEL_SENSORHUB
1036 sprintf(buf
, "%04x %04x %04x", acc
[BMA222_AXIS_X
], acc
[BMA222_AXIS_Y
], acc
[BMA222_AXIS_Z
]);
1037 if(atomic_read(&obj
->trace
) & ADX_TRC_IOCTL
)
1039 GSE_LOG("gsensor data: %s!\n", buf
);
1045 /*----------------------------------------------------------------------------*/
1046 static int BMA222_ReadRawData(struct i2c_client
*client
, char *buf
)
1048 struct bma222_i2c_data
*obj
= (struct bma222_i2c_data
*)i2c_get_clientdata(client
);
1051 if (!buf
|| !client
)
1056 if(0 != (res
= BMA222_ReadData(client
, obj
->data
)))
1058 GSE_ERR("I2C error: ret value=%d", res
);
1063 sprintf(buf
, "BMA222_ReadRawData %04x %04x %04x", obj
->data
[BMA222_AXIS_X
],
1064 obj
->data
[BMA222_AXIS_Y
], obj
->data
[BMA222_AXIS_Z
]);
1070 /*----------------------------------------------------------------------------*/
1071 static ssize_t
show_chipinfo_value(struct device_driver
*ddri
, char *buf
)
1073 struct i2c_client
*client
= bma222_i2c_client
;
1074 char strbuf
[BMA222_BUFSIZE
];
1077 GSE_ERR("i2c client is null!!\n");
1081 BMA222_ReadChipInfo(client
, strbuf
, BMA222_BUFSIZE
);
1082 return snprintf(buf
, PAGE_SIZE
, "%s\n", strbuf
);
1086 static ssize_t
gsensor_init(struct device_driver
*ddri
, char *buf
, size_t count
)
1088 struct i2c_client
*client
= bma222_i2c_client
;
1089 char strbuf
[BMA222_BUFSIZE
];
1093 GSE_ERR("i2c client is null!!\n");
1096 bma222_init_client(client
, 1);
1097 return snprintf(buf
, PAGE_SIZE
, "%s\n", strbuf
);
1102 /*----------------------------------------------------------------------------*/
1103 static ssize_t
show_sensordata_value(struct device_driver
*ddri
, char *buf
)
1105 struct i2c_client
*client
= bma222_i2c_client
;
1106 char strbuf
[BMA222_BUFSIZE
];
1110 GSE_ERR("i2c client is null!!\n");
1113 BMA222_ReadSensorData(client
, strbuf
, BMA222_BUFSIZE
);
1114 //BMA150_ReadRawData(client, strbuf);
1115 return snprintf(buf
, PAGE_SIZE
, "%s\n", strbuf
);
1119 static ssize_t
show_sensorrawdata_value(struct device_driver
*ddri
, char *buf
, size_t count
)
1121 struct i2c_client
*client
= bma222_i2c_client
;
1122 char strbuf
[BMA222_BUFSIZE
];
1126 GSE_ERR("i2c client is null!!\n");
1129 //BMA150_ReadSensorData(client, strbuf, BMA150_BUFSIZE);
1130 BMA222_ReadRawData(client
, strbuf
);
1131 return snprintf(buf
, PAGE_SIZE
, "%s\n", strbuf
);
1135 /*----------------------------------------------------------------------------*/
1137 static ssize_t
show_cali_value(struct device_driver
*ddri
, char *buf
)
1139 struct i2c_client
*client
= bma222_i2c_client
;
1140 struct bma222_i2c_data
*obj
;
1141 int err
, len
= 0, mul
;
1142 int tmp
[BMA222_AXES_NUM
];
1146 GSE_ERR("i2c client is null!!\n");
1150 obj
= i2c_get_clientdata(client
);
1154 if(0 != (err
= BMA222_ReadOffset(client
, obj
->offset
)))
1158 else if(0 != (err
= BMA222_ReadCalibration(client
, tmp
)))
1164 mul
= obj
->reso
->sensitivity
/bma222_offset_resolution
.sensitivity
;
1165 len
+= snprintf(buf
+len
, PAGE_SIZE
-len
, "[HW ][%d] (%+3d, %+3d, %+3d) : (0x%02X, 0x%02X, 0x%02X)\n", mul
,
1166 obj
->offset
[BMA222_AXIS_X
], obj
->offset
[BMA222_AXIS_Y
], obj
->offset
[BMA222_AXIS_Z
],
1167 obj
->offset
[BMA222_AXIS_X
], obj
->offset
[BMA222_AXIS_Y
], obj
->offset
[BMA222_AXIS_Z
]);
1168 len
+= snprintf(buf
+len
, PAGE_SIZE
-len
, "[SW ][%d] (%+3d, %+3d, %+3d)\n", 1,
1169 obj
->cali_sw
[BMA222_AXIS_X
], obj
->cali_sw
[BMA222_AXIS_Y
], obj
->cali_sw
[BMA222_AXIS_Z
]);
1171 len
+= snprintf(buf
+len
, PAGE_SIZE
-len
, "[ALL] (%+3d, %+3d, %+3d) : (%+3d, %+3d, %+3d)\n",
1172 obj
->offset
[BMA222_AXIS_X
]*mul
+ obj
->cali_sw
[BMA222_AXIS_X
],
1173 obj
->offset
[BMA222_AXIS_Y
]*mul
+ obj
->cali_sw
[BMA222_AXIS_Y
],
1174 obj
->offset
[BMA222_AXIS_Z
]*mul
+ obj
->cali_sw
[BMA222_AXIS_Z
],
1175 tmp
[BMA222_AXIS_X
], tmp
[BMA222_AXIS_Y
], tmp
[BMA222_AXIS_Z
]);
1180 /*----------------------------------------------------------------------------*/
1181 static ssize_t
store_cali_value(struct device_driver
*ddri
, const char *buf
, size_t count
)
1183 struct i2c_client
*client
= bma222_i2c_client
;
1185 int dat
[BMA222_AXES_NUM
];
1187 if(!strncmp(buf
, "rst", 3))
1189 if(0 != (err
= BMA222_ResetCalibration(client
)))
1191 GSE_ERR("reset offset err = %d\n", err
);
1194 else if(3 == sscanf(buf
, "0x%02X 0x%02X 0x%02X", &x
, &y
, &z
))
1196 dat
[BMA222_AXIS_X
] = x
;
1197 dat
[BMA222_AXIS_Y
] = y
;
1198 dat
[BMA222_AXIS_Z
] = z
;
1199 if(0 != (err
= BMA222_WriteCalibration(client
, dat
)))
1201 GSE_ERR("write calibration err = %d\n", err
);
1206 GSE_ERR("invalid format\n");
1213 /*----------------------------------------------------------------------------*/
1214 static ssize_t
show_firlen_value(struct device_driver
*ddri
, char *buf
)
1216 #ifdef CONFIG_BMA222_LOWPASS
1217 struct i2c_client
*client
= bma222_i2c_client
;
1218 struct bma222_i2c_data
*obj
= i2c_get_clientdata(client
);
1219 if(atomic_read(&obj
->firlen
))
1221 int idx
, len
= atomic_read(&obj
->firlen
);
1222 GSE_LOG("len = %2d, idx = %2d\n", obj
->fir
.num
, obj
->fir
.idx
);
1224 for(idx
= 0; idx
< len
; idx
++)
1226 GSE_LOG("[%5d %5d %5d]\n", obj
->fir
.raw
[idx
][BMA222_AXIS_X
], obj
->fir
.raw
[idx
][BMA222_AXIS_Y
], obj
->fir
.raw
[idx
][BMA222_AXIS_Z
]);
1229 GSE_LOG("sum = [%5d %5d %5d]\n", obj
->fir
.sum
[BMA222_AXIS_X
], obj
->fir
.sum
[BMA222_AXIS_Y
], obj
->fir
.sum
[BMA222_AXIS_Z
]);
1230 GSE_LOG("avg = [%5d %5d %5d]\n", obj
->fir
.sum
[BMA222_AXIS_X
]/len
, obj
->fir
.sum
[BMA222_AXIS_Y
]/len
, obj
->fir
.sum
[BMA222_AXIS_Z
]/len
);
1232 return snprintf(buf
, PAGE_SIZE
, "%d\n", atomic_read(&obj
->firlen
));
1234 return snprintf(buf
, PAGE_SIZE
, "not support\n");
1237 /*----------------------------------------------------------------------------*/
1238 static ssize_t
store_firlen_value(struct device_driver
*ddri
, const char *buf
, size_t count
)
1240 #ifdef CONFIG_BMA222_LOWPASS
1241 struct i2c_client
*client
= bma222_i2c_client
;
1242 struct bma222_i2c_data
*obj
= i2c_get_clientdata(client
);
1245 if(1 != sscanf(buf
, "%d", &firlen
))
1247 GSE_ERR("invallid format\n");
1249 else if(firlen
> C_MAX_FIR_LENGTH
)
1251 GSE_ERR("exceeds maximum filter length\n");
1255 atomic_set(&obj
->firlen
, firlen
);
1258 atomic_set(&obj
->fir_en
, 0);
1262 memset(&obj
->fir
, 0x00, sizeof(obj
->fir
));
1263 atomic_set(&obj
->fir_en
, 1);
1269 /*----------------------------------------------------------------------------*/
1270 static ssize_t
show_trace_value(struct device_driver
*ddri
, char *buf
)
1273 struct bma222_i2c_data
*obj
= obj_i2c_data
;
1276 GSE_ERR("i2c_data obj is null!!\n");
1280 res
= snprintf(buf
, PAGE_SIZE
, "0x%04X\n", atomic_read(&obj
->trace
));
1283 /*----------------------------------------------------------------------------*/
1284 static ssize_t
store_trace_value(struct device_driver
*ddri
, const char *buf
, size_t count
)
1286 struct bma222_i2c_data
*obj
= obj_i2c_data
;
1290 GSE_ERR("i2c_data obj is null!!\n");
1294 if(1 == sscanf(buf
, "0x%x", &trace
))
1296 atomic_set(&obj
->trace
, trace
);
1300 GSE_ERR("invalid content: '%s', length = %d\n", buf
, (int)count
);
1305 /*----------------------------------------------------------------------------*/
1306 static ssize_t
show_status_value(struct device_driver
*ddri
, char *buf
)
1309 struct bma222_i2c_data
*obj
= obj_i2c_data
;
1312 GSE_ERR("i2c_data obj is null!!\n");
1318 len
+= snprintf(buf
+len
, PAGE_SIZE
-len
, "CUST: %d %d (%d %d)\n",
1319 obj
->hw
->i2c_num
, obj
->hw
->direction
, obj
->hw
->power_id
, obj
->hw
->power_vol
);
1323 len
+= snprintf(buf
+len
, PAGE_SIZE
-len
, "CUST: NULL\n");
1327 /*----------------------------------------------------------------------------*/
1328 static ssize_t
show_power_status_value(struct device_driver
*ddri
, char *buf
)
1333 u8 addr
= BMA222_REG_POWER_CTL
;
1334 struct bma222_i2c_data
*obj
= obj_i2c_data
;
1335 if(bma_i2c_read_block(obj
->client
, addr
, databuf
, 0x01))
1337 GSE_ERR("read power ctl register err!\n");
1342 GSE_LOG("G sensor is in work mode, sensor_power = %d\n", sensor_power
);
1344 GSE_LOG("G sensor is in standby mode, sensor_power = %d\n", sensor_power
);
1346 return snprintf(buf
, PAGE_SIZE
, "%x\n", databuf
[0]);
1348 /*----------------------------------------------------------------------------*/
1349 static DRIVER_ATTR(chipinfo
, S_IWUSR
| S_IRUGO
, show_chipinfo_value
, NULL
);
1350 static DRIVER_ATTR(sensordata
, S_IWUSR
| S_IRUGO
, show_sensordata_value
, NULL
);
1351 static DRIVER_ATTR(cali
, S_IWUSR
| S_IRUGO
, show_cali_value
, store_cali_value
);
1352 static DRIVER_ATTR(firlen
, S_IWUSR
| S_IRUGO
, show_firlen_value
, store_firlen_value
);
1353 static DRIVER_ATTR(trace
, S_IWUSR
| S_IRUGO
, show_trace_value
, store_trace_value
);
1354 static DRIVER_ATTR(status
, S_IRUGO
, show_status_value
, NULL
);
1355 static DRIVER_ATTR(powerstatus
, S_IRUGO
, show_power_status_value
, NULL
);
1357 /*----------------------------------------------------------------------------*/
1358 static struct driver_attribute
*bma222_attr_list
[] = {
1359 &driver_attr_chipinfo
, /*chip information*/
1360 &driver_attr_sensordata
, /*dump sensor data*/
1361 &driver_attr_cali
, /*show calibration data*/
1362 &driver_attr_firlen
, /*filter length: 0: disable, others: enable*/
1363 &driver_attr_trace
, /*trace log*/
1364 &driver_attr_status
,
1365 &driver_attr_powerstatus
,
1367 /*----------------------------------------------------------------------------*/
1368 static int bma222_create_attr(struct device_driver
*driver
)
1371 int num
= (int)(sizeof(bma222_attr_list
)/sizeof(bma222_attr_list
[0]));
1377 for(idx
= 0; idx
< num
; idx
++)
1379 if(0 != (err
= driver_create_file(driver
, bma222_attr_list
[idx
])))
1381 GSE_ERR("driver_create_file (%s) = %d\n", bma222_attr_list
[idx
]->attr
.name
, err
);
1387 /*----------------------------------------------------------------------------*/
1388 static int bma222_delete_attr(struct device_driver
*driver
)
1391 int num
= (int)(sizeof(bma222_attr_list
)/sizeof(bma222_attr_list
[0]));
1399 for(idx
= 0; idx
< num
; idx
++)
1401 driver_remove_file(driver
, bma222_attr_list
[idx
]);
1408 /*----------------------------------------------------------------------------*/
1409 #ifdef CUSTOM_KERNEL_SENSORHUB
1410 static void gsensor_irq_work(struct work_struct
*work
)
1412 struct bma222_i2c_data
*obj
= obj_i2c_data
;
1413 BMA222_CUST_DATA
*p_cust_data
;
1414 SCP_SENSOR_HUB_DATA data
;
1415 int max_cust_data_size_per_packet
;
1417 uint sizeOfCustData
;
1419 char *p
= (char *)obj
->hw
;
1422 p_cust_data
= (BMA222_CUST_DATA
*)data
.set_cust_req
.custData
;
1424 data
.set_cust_req
.sensorType
= ID_ACCELEROMETER
;
1425 data
.set_cust_req
.action
= SENSOR_HUB_SET_CUST
;
1426 sizeOfCustData
= sizeof(*(obj
->hw
));
1427 p_cust_data
->setCust
.action
= BMA222_CUST_ACTION_SET_CUST
;
1428 max_cust_data_size_per_packet
= sizeof(data
.set_cust_req
.custData
) - offsetof(BMA222_SET_CUST
, data
);
1430 GSE_ERR("sizeOfCustData = %d, max_cust_data_size_per_packet = %d\n", sizeOfCustData
, max_cust_data_size_per_packet
);
1431 GSE_ERR("offset %d\n", offsetof(BMA222_SET_CUST
, data
));
1433 for (i
=0;sizeOfCustData
>0;i
++)
1435 p_cust_data
->setCust
.part
= i
;
1436 if (sizeOfCustData
> max_cust_data_size_per_packet
)
1438 len
= max_cust_data_size_per_packet
;
1442 len
= sizeOfCustData
;
1445 memcpy(p_cust_data
->setCust
.data
, p
, len
);
1446 sizeOfCustData
-= len
;
1449 GSE_ERR("i= %d, sizeOfCustData = %d, len = %d \n", i
, sizeOfCustData
, len
);
1450 len
+= offsetof(SCP_SENSOR_HUB_SET_CUST_REQ
, custData
) + offsetof(BMA222_SET_CUST
, data
);
1451 GSE_ERR("data.set_cust_req.sensorType= %d \n", data
.set_cust_req
.sensorType
);
1452 SCP_sensorHub_req_send(&data
, &len
, 1);
1455 p_cust_data
= (BMA222_CUST_DATA
*)&data
.set_cust_req
.custData
;
1456 data
.set_cust_req
.sensorType
= ID_ACCELEROMETER
;
1457 data
.set_cust_req
.action
= SENSOR_HUB_SET_CUST
;
1458 p_cust_data
->resetCali
.action
= BMA222_CUST_ACTION_RESET_CALI
;
1459 len
= offsetof(SCP_SENSOR_HUB_SET_CUST_REQ
, custData
) + sizeof(p_cust_data
->resetCali
);
1460 SCP_sensorHub_req_send(&data
, &len
, 1);
1461 obj
->SCP_init_done
= 1;
1463 /*----------------------------------------------------------------------------*/
1464 static int gsensor_irq_handler(void* data
, uint len
)
1466 struct bma222_i2c_data
*obj
= obj_i2c_data
;
1467 SCP_SENSOR_HUB_DATA_P rsp
= (SCP_SENSOR_HUB_DATA_P
)data
;
1469 GSE_ERR("gsensor_irq_handler len = %d, type = %d, action = %d, errCode = %d\n", len
, rsp
->rsp
.sensorType
, rsp
->rsp
.action
, rsp
->rsp
.errCode
);
1475 switch(rsp
->rsp
.action
)
1477 case SENSOR_HUB_NOTIFY
:
1478 switch(rsp
->notify_rsp
.event
)
1481 schedule_work(&obj
->irq_work
);
1482 GSE_ERR("OK sensor hub notify\n");
1485 GSE_ERR("Error sensor hub notify\n");
1490 GSE_ERR("Error sensor hub action\n");
1497 static int gsensor_setup_irq()
1503 err
= SCP_sensorHub_rsp_registration(ID_ACCELEROMETER
, gsensor_irq_handler
);
1507 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
1508 /******************************************************************************
1509 * Function Configuration
1510 ******************************************************************************/
1511 static int bma222_open(struct inode
*inode
, struct file
*file
)
1513 file
->private_data
= bma222_i2c_client
;
1515 if(file
->private_data
== NULL
)
1517 GSE_ERR("null pointer!!\n");
1520 return nonseekable_open(inode
, file
);
1522 /*----------------------------------------------------------------------------*/
1523 static int bma222_release(struct inode
*inode
, struct file
*file
)
1525 file
->private_data
= NULL
;
1528 /*----------------------------------------------------------------------------*/
1529 //static int bma222_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
1530 // unsigned long arg)
1531 static long bma222_unlocked_ioctl(struct file
*file
, unsigned int cmd
,
1535 struct i2c_client
*client
= (struct i2c_client
*)file
->private_data
;
1536 struct bma222_i2c_data
*obj
= (struct bma222_i2c_data
*)i2c_get_clientdata(client
);
1537 char strbuf
[BMA222_BUFSIZE
];
1539 SENSOR_DATA sensor_data
;
1544 if(_IOC_DIR(cmd
) & _IOC_READ
)
1546 err
= !access_ok(VERIFY_WRITE
, (void __user
*)arg
, _IOC_SIZE(cmd
));
1548 else if(_IOC_DIR(cmd
) & _IOC_WRITE
)
1550 err
= !access_ok(VERIFY_READ
, (void __user
*)arg
, _IOC_SIZE(cmd
));
1555 GSE_ERR("access error: %08X, (%2d, %2d)\n", cmd
, _IOC_DIR(cmd
), _IOC_SIZE(cmd
));
1561 case GSENSOR_IOCTL_INIT
:
1562 bma222_init_client(client
, 0);
1565 case GSENSOR_IOCTL_READ_CHIPINFO
:
1566 data
= (void __user
*) arg
;
1573 BMA222_ReadChipInfo(client
, strbuf
, BMA222_BUFSIZE
);
1574 if(copy_to_user(data
, strbuf
, strlen(strbuf
)+1))
1581 case GSENSOR_IOCTL_READ_SENSORDATA
:
1582 data
= (void __user
*) arg
;
1588 BMA222_SetPowerMode(client
,true);
1589 BMA222_ReadSensorData(client
, strbuf
, BMA222_BUFSIZE
);
1590 if(copy_to_user(data
, strbuf
, strlen(strbuf
)+1))
1597 case GSENSOR_IOCTL_READ_GAIN
:
1598 data
= (void __user
*) arg
;
1605 if(copy_to_user(data
, &gsensor_gain
, sizeof(GSENSOR_VECTOR3D
)))
1612 case GSENSOR_IOCTL_READ_RAW_DATA
:
1613 data
= (void __user
*) arg
;
1619 BMA222_ReadRawData(client
, strbuf
);
1620 if(copy_to_user(data
, &strbuf
, strlen(strbuf
)+1))
1627 case GSENSOR_IOCTL_SET_CALI
:
1628 data
= (void __user
*)arg
;
1634 if(copy_from_user(&sensor_data
, data
, sizeof(sensor_data
)))
1639 if(atomic_read(&obj
->suspend
))
1641 GSE_ERR("Perform calibration in suspend state!!\n");
1646 cali
[BMA222_AXIS_X
] = sensor_data
.x
* obj
->reso
->sensitivity
/ GRAVITY_EARTH_1000
;
1647 cali
[BMA222_AXIS_Y
] = sensor_data
.y
* obj
->reso
->sensitivity
/ GRAVITY_EARTH_1000
;
1648 cali
[BMA222_AXIS_Z
] = sensor_data
.z
* obj
->reso
->sensitivity
/ GRAVITY_EARTH_1000
;
1649 err
= BMA222_WriteCalibration(client
, cali
);
1653 case GSENSOR_IOCTL_CLR_CALI
:
1654 err
= BMA222_ResetCalibration(client
);
1657 case GSENSOR_IOCTL_GET_CALI
:
1658 data
= (void __user
*)arg
;
1664 if(0 != (err
= BMA222_ReadCalibration(client
, cali
)))
1669 sensor_data
.x
= cali
[BMA222_AXIS_X
] * GRAVITY_EARTH_1000
/ obj
->reso
->sensitivity
;
1670 sensor_data
.y
= cali
[BMA222_AXIS_Y
] * GRAVITY_EARTH_1000
/ obj
->reso
->sensitivity
;
1671 sensor_data
.z
= cali
[BMA222_AXIS_Z
] * GRAVITY_EARTH_1000
/ obj
->reso
->sensitivity
;
1672 if(copy_to_user(data
, &sensor_data
, sizeof(sensor_data
)))
1681 GSE_ERR("unknown IOCTL: 0x%08x\n", cmd
);
1691 /*----------------------------------------------------------------------------*/
1692 static struct file_operations bma222_fops
= {
1693 .owner
= THIS_MODULE
,
1694 .open
= bma222_open
,
1695 .release
= bma222_release
,
1696 .unlocked_ioctl
= bma222_unlocked_ioctl
,
1698 /*----------------------------------------------------------------------------*/
1699 static struct miscdevice bma222_device
= {
1700 .minor
= MISC_DYNAMIC_MINOR
,
1702 .fops
= &bma222_fops
,
1704 /*----------------------------------------------------------------------------*/
1705 #ifndef USE_EARLY_SUSPEND
1706 /*----------------------------------------------------------------------------*/
1707 static int bma222_suspend(struct i2c_client
*client
, pm_message_t msg
)
1709 struct bma222_i2c_data
*obj
= i2c_get_clientdata(client
);
1711 mutex_lock(&gsensor_scp_en_mutex
);
1712 if(msg
.event
== PM_EVENT_SUSPEND
)
1716 GSE_ERR("null pointer!!\n");
1717 mutex_unlock(&gsensor_scp_en_mutex
);
1720 atomic_set(&obj
->suspend
, 1);
1721 #ifdef CUSTOM_KERNEL_SENSORHUB
1722 if(0 != (err
= BMA222_SCP_SetPowerMode(false, ID_ACCELEROMETER
)))
1724 if(0 != (err
= BMA222_SetPowerMode(obj
->client
, false)))
1727 GSE_ERR("write power control fail!!\n");
1728 mutex_unlock(&gsensor_scp_en_mutex
);
1731 #ifndef CUSTOM_KERNEL_SENSORHUB
1732 BMA222_power(obj
->hw
, 0);
1735 mutex_unlock(&gsensor_scp_en_mutex
);
1738 /*----------------------------------------------------------------------------*/
1739 static int bma222_resume(struct i2c_client
*client
)
1741 struct bma222_i2c_data
*obj
= i2c_get_clientdata(client
);
1746 GSE_ERR("null pointer!!\n");
1750 #ifndef CUSTOM_KERNEL_SENSORHUB
1751 BMA222_power(obj
->hw
, 1);
1754 #ifndef CUSTOM_KERNEL_SENSORHUB
1755 if(0 != (err
= bma222_init_client(client
, 0)))
1757 if(0 != (err
= BMA222_SCP_SetPowerMode(enable_status
, ID_ACCELEROMETER
)))
1760 GSE_ERR("initialize client fail!!\n");
1764 atomic_set(&obj
->suspend
, 0);
1769 /*----------------------------------------------------------------------------*/
1770 #else /*CONFIG_HAS_EARLY_SUSPEND is defined*/
1771 /*----------------------------------------------------------------------------*/
1772 static void bma222_early_suspend(struct early_suspend
*h
)
1774 struct bma222_i2c_data
*obj
= container_of(h
, struct bma222_i2c_data
, early_drv
);
1779 GSE_ERR("null pointer!!\n");
1782 atomic_set(&obj
->suspend
, 1);
1785 u8 databuf
[2]; //for debug read power control register to see the value is OK
1786 if(bma_i2c_read_block(obj
->client
, BMA222_REG_POWER_CTL
, databuf
, 0x01))
1788 GSE_ERR("read power ctl register err!\n");
1789 return BMA222_ERR_I2C
;
1791 if(databuf
[0]==0xff)//if the value is ff the gsensor will not work anymore, any i2c operations won't be vaild
1792 GSE_LOG("before BMA222_SetPowerMode in suspend databuf = 0x%x\n",databuf
[0]);
1793 #ifndef CUSTOM_KERNEL_SENSORHUB
1794 if((err
= BMA222_SetPowerMode(obj
->client
, false)))
1796 if((err
= BMA222_SCP_SetPowerMode(false, ID_ACCELEROMETER
)))
1799 GSE_ERR("write power control fail!!\n");
1803 if(bma_i2c_read_block(obj
->client
, BMA222_REG_POWER_CTL
, databuf
, 0x01)) //for debug read power control register to see the value is OK
1805 GSE_ERR("read power ctl register err!\n");
1807 return BMA222_ERR_I2C
;
1809 if(databuf
[0]==0xff)//if the value is ff the gsensor will not work anymore, any i2c operations won't be vaild
1810 GSE_LOG("after BMA222_SetPowerMode suspend err databuf = 0x%x\n",databuf
[0]);
1813 #ifndef CUSTOM_KERNEL_SENSORHUB
1814 BMA222_power(obj
->hw
, 0);
1818 /*----------------------------------------------------------------------------*/
1819 static void bma222_late_resume(struct early_suspend
*h
)
1821 struct bma222_i2c_data
*obj
= container_of(h
, struct bma222_i2c_data
, early_drv
);
1826 GSE_ERR("null pointer!!\n");
1830 #ifndef CUSTOM_KERNEL_SENSORHUB
1831 BMA222_power(obj
->hw
, 1);
1837 u8 databuf
[2];//for debug read power control register to see the value is OK
1838 if(bma_i2c_read_block(obj
->client
, BMA222_REG_POWER_CTL
, databuf
, 0x01))
1840 GSE_ERR("read power ctl register err!\n");
1842 return BMA222_ERR_I2C
;
1845 if(databuf
[0]==0xff)//if the value is ff the gsensor will not work anymore, any i2c operations won't be vaild
1847 GSE_LOG("before bma222_init_client databuf = 0x%x\n",databuf
[0]);
1848 #ifndef CUSTOM_KERNEL_SENSORHUB
1849 if((err
= bma222_init_client(obj
->client
, 0)))
1851 if((err
= BMA222_SCP_SetPowerMode(enable_status
, ID_ACCELEROMETER
)))
1854 GSE_ERR("initialize client fail!!\n");
1859 if(bma_i2c_read_block(obj
->client
, BMA222_REG_POWER_CTL
, databuf
, 0x01)) //for debug read power control register to see the value is OK
1861 GSE_ERR("read power ctl register err!\n");
1863 return BMA222_ERR_I2C
;
1866 if(databuf
[0]==0xff)//if the value is ff the gsensor will not work anymore, any i2c operations won't be vaild
1867 GSE_LOG("after bma222_init_client databuf = 0x%x\n",databuf
[0]);
1870 atomic_set(&obj
->suspend
, 0);
1872 /*----------------------------------------------------------------------------*/
1873 #endif /*USE_EARLY_SUSPEND*/
1874 /*----------------------------------------------------------------------------*/
1875 // if use this typ of enable , Gsensor should report inputEvent(x, y, z ,stats, div) to HAL
1876 static int gsensor_open_report_data(int open
)
1878 //should queuq work to report event if is_report_input_direct=true
1881 /*----------------------------------------------------------------------------*/
1882 // if use this typ of enable , Gsensor only enabled but not report inputEvent to HAL
1883 static int gsensor_enable_nodata(int en
)
1889 if(((en
== 0) && (sensor_power
== false)) ||((en
== 1) && (sensor_power
== true)))
1891 enable_status
= sensor_power
;
1892 GSE_LOG("Gsensor device have updated!\n");
1896 enable_status
= !sensor_power
;
1897 if (atomic_read(&obj_i2c_data
->suspend
) == 0)
1899 #ifdef CUSTOM_KERNEL_SENSORHUB
1900 err
= BMA222_SCP_SetPowerMode(enable_status
, ID_ACCELEROMETER
);
1903 sensor_power
= enable_status
;
1906 err
= BMA222_SetPowerMode(obj_i2c_data
->client
, enable_status
);
1908 GSE_LOG("Gsensor not in suspend BMA222_SetPowerMode!, enable_status = %d\n",enable_status
);
1912 GSE_LOG("Gsensor in suspend and can not enable or disable!enable_status = %d\n",enable_status
);
1917 if(err
!= BMA222_SUCCESS
)
1919 GSE_ERR("gsensor_enable_nodata fail!\n");
1923 GSE_ERR("gsensor_enable_nodata OK!\n");
1926 /*----------------------------------------------------------------------------*/
1927 static int gsensor_set_delay(u64 ns
)
1931 #ifdef CUSTOM_KERNEL_SENSORHUB
1932 SCP_SENSOR_HUB_DATA req
;
1934 #else//#ifdef CUSTOM_KERNEL_SENSORHUB
1936 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
1938 value
= (int)ns
/1000/1000;
1940 #ifdef CUSTOM_KERNEL_SENSORHUB
1941 req
.set_delay_req
.sensorType
= ID_ACCELEROMETER
;
1942 req
.set_delay_req
.action
= SENSOR_HUB_SET_DELAY
;
1943 req
.set_delay_req
.delay
= value
;
1944 len
= sizeof(req
.activate_req
);
1945 err
= SCP_sensorHub_req_send(&req
, &len
, 1);
1948 GSE_ERR("SCP_sensorHub_req_send!\n");
1951 #else//#ifdef CUSTOM_KERNEL_SENSORHUB
1954 sample_delay
= BMA222_BW_200HZ
;
1956 else if(value
<= 10)
1958 sample_delay
= BMA222_BW_100HZ
;
1962 sample_delay
= BMA222_BW_100HZ
;
1965 mutex_lock(&gsensor_scp_en_mutex
);
1966 err
= BMA222_SetBWRate(obj_i2c_data
->client
, sample_delay
);
1967 mutex_unlock(&gsensor_scp_en_mutex
);
1968 if(err
!= BMA222_SUCCESS
) //0x2C->BW=100Hz
1970 GSE_ERR("Set delay parameter error!\n");
1976 atomic_set(&obj_i2c_data
->filter
, 0);
1980 #if defined(CONFIG_BMA222_LOWPASS)
1983 priv
->fir
.sum
[BMA222_AXIS_X
] = 0;
1984 priv
->fir
.sum
[BMA222_AXIS_Y
] = 0;
1985 priv
->fir
.sum
[BMA222_AXIS_Z
] = 0;
1986 atomic_set(&priv
->filter
, 1);
1989 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
1991 GSE_LOG("gsensor_set_delay (%d)\n",value
);
1995 /*----------------------------------------------------------------------------*/
1996 /*----------------------------------------------------------------------------*/
1997 static int gsensor_get_data(int* x
,int* y
,int* z
, int* status
)
1999 #ifdef CUSTOM_KERNEL_SENSORHUB
2000 SCP_SENSOR_HUB_DATA req
;
2004 char buff
[BMA222_BUFSIZE
];
2007 #ifdef CUSTOM_KERNEL_SENSORHUB
2008 req
.get_data_req
.sensorType
= ID_ACCELEROMETER
;
2009 req
.get_data_req
.action
= SENSOR_HUB_GET_DATA
;
2010 len
= sizeof(req
.get_data_req
);
2011 err
= SCP_sensorHub_req_send(&req
, &len
, 1);
2014 GSE_ERR("SCP_sensorHub_req_send!\n");
2018 if (ID_ACCELEROMETER
!= req
.get_data_rsp
.sensorType
||
2019 SENSOR_HUB_GET_DATA
!= req
.get_data_rsp
.action
||
2020 0 != req
.get_data_rsp
.errCode
)
2022 GSE_ERR("error : %d\n", req
.get_data_rsp
.errCode
);
2023 return req
.get_data_rsp
.errCode
;
2026 *x
= req
.get_data_rsp
.int16_Data
[0];
2027 *y
= req
.get_data_rsp
.int16_Data
[1];
2028 *z
= req
.get_data_rsp
.int16_Data
[2];
2029 GSE_ERR("x = %d, y = %d, z = %d\n", *x
, *y
, *z
);
2031 *status
= SENSOR_STATUS_ACCURACY_MEDIUM
;
2033 mutex_lock(&gsensor_scp_en_mutex
);
2034 BMA222_ReadSensorData(obj_i2c_data
->client
, buff
, BMA222_BUFSIZE
);
2035 mutex_unlock(&gsensor_scp_en_mutex
);
2036 sscanf(buff
, "%x %x %x", x
, y
, z
);
2037 *status
= SENSOR_STATUS_ACCURACY_MEDIUM
;
2041 /*----------------------------------------------------------------------------*/
2042 static int bma222_i2c_probe(struct i2c_client
*client
, const struct i2c_device_id
*id
)
2044 struct i2c_client
*new_client
;
2045 struct bma222_i2c_data
*obj
;
2046 struct acc_control_path ctl
={0};
2047 struct acc_data_path data
={0};
2052 if(!(obj
= kzalloc(sizeof(*obj
), GFP_KERNEL
)))
2058 memset(obj
, 0, sizeof(struct bma222_i2c_data
));
2060 obj
->hw
= get_cust_acc_hw();
2062 if(0 != (err
= hwmsen_get_convert(obj
->hw
->direction
, &obj
->cvt
)))
2064 GSE_ERR("invalid direction: %d\n", obj
->hw
->direction
);
2068 #ifdef CUSTOM_KERNEL_SENSORHUB
2069 INIT_WORK(&obj
->irq_work
, gsensor_irq_work
);
2070 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
2073 obj
->client
= client
;
2074 #ifdef FPGA_EARLY_PORTING
2075 obj
->client
->timing
= 100;
2077 obj
->client
->timing
= 400;
2079 new_client
= obj
->client
;
2080 i2c_set_clientdata(new_client
,obj
);
2082 atomic_set(&obj
->trace
, 0);
2083 atomic_set(&obj
->suspend
, 0);
2085 #ifdef CONFIG_BMA222_LOWPASS
2086 if(obj
->hw
->firlen
> C_MAX_FIR_LENGTH
)
2088 atomic_set(&obj
->firlen
, C_MAX_FIR_LENGTH
);
2092 atomic_set(&obj
->firlen
, obj
->hw
->firlen
);
2095 if(atomic_read(&obj
->firlen
) > 0)
2097 atomic_set(&obj
->fir_en
, 1);
2102 bma222_i2c_client
= new_client
;
2104 for(retry
= 0; retry
< 3; retry
++){
2105 if(0 != (err
= bma222_init_client(new_client
, 1)))
2107 GSE_ERR("bma222_device init cilent fail time: %d\n", retry
);
2112 goto exit_init_failed
;
2115 if(0 != (err
= misc_register(&bma222_device
)))
2117 GSE_ERR("bma222_device register failed\n");
2118 goto exit_misc_device_register_failed
;
2121 if(0 != (err
= bma222_create_attr(&bma222_init_info
.platform_diver_addr
->driver
)))
2123 GSE_ERR("create attribute err = %d\n", err
);
2124 goto exit_create_attr_failed
;
2127 ctl
.open_report_data
= gsensor_open_report_data
;
2128 ctl
.enable_nodata
= gsensor_enable_nodata
;
2129 ctl
.set_delay
= gsensor_set_delay
;
2130 //ctl.batch = gsensor_set_batch;
2131 ctl
.is_report_input_direct
= false;
2133 #ifdef CUSTOM_KERNEL_SENSORHUB
2134 ctl
.is_support_batch
= obj
->hw
->is_batch_supported
;
2136 ctl
.is_support_batch
= false;
2139 err
= acc_register_control_path(&ctl
);
2142 GSE_ERR("register acc control path err\n");
2146 data
.get_data
= gsensor_get_data
;
2147 data
.vender_div
= 1000;
2148 err
= acc_register_data_path(&data
);
2151 GSE_ERR("register acc data path err\n");
2155 err
= batch_register_support_info(ID_ACCELEROMETER
,ctl
.is_support_batch
, 1000, 0);
2158 GSE_ERR("register gsensor batch support err = %d\n", err
);
2159 goto exit_create_attr_failed
;
2162 #ifdef USE_EARLY_SUSPEND
2163 obj
->early_drv
.level
= EARLY_SUSPEND_LEVEL_STOP_DRAWING
- 2,
2164 obj
->early_drv
.suspend
= bma222_early_suspend
,
2165 obj
->early_drv
.resume
= bma222_late_resume
,
2166 register_early_suspend(&obj
->early_drv
);
2169 gsensor_init_flag
=0;
2170 GSE_LOG("%s: OK\n", __func__
);
2173 exit_create_attr_failed
:
2174 misc_deregister(&bma222_device
);
2175 exit_misc_device_register_failed
:
2177 //i2c_detach_client(new_client);
2181 GSE_ERR("%s: err = %d\n", __func__
, err
);
2182 gsensor_init_flag
= -1;
2186 /*----------------------------------------------------------------------------*/
2187 static int bma222_i2c_remove(struct i2c_client
*client
)
2191 if(0 != (err
= bma222_delete_attr(&bma222_init_info
.platform_diver_addr
->driver
)))
2193 GSE_ERR("bma150_delete_attr fail: %d\n", err
);
2196 if(0 != (err
= misc_deregister(&bma222_device
)))
2198 GSE_ERR("misc_deregister fail: %d\n", err
);
2201 bma222_i2c_client
= NULL
;
2202 i2c_unregister_device(client
);
2203 kfree(i2c_get_clientdata(client
));
2206 /*----------------------------------------------------------------------------*/
2207 static int gsensor_local_init(void)
2209 struct acc_hw
*hw
= get_cust_acc_hw();
2213 BMA222_power(hw
, 1);
2214 if(i2c_add_driver(&bma222_i2c_driver
))
2216 GSE_ERR("add driver error\n");
2219 if(-1 == gsensor_init_flag
)
2223 //printk("fwq loccal init---\n");
2226 /*----------------------------------------------------------------------------*/
2227 static int gsensor_remove()
2229 struct acc_hw
*hw
= get_cust_acc_hw();
2232 BMA222_power(hw
, 0);
2233 i2c_del_driver(&bma222_i2c_driver
);
2236 /*----------------------------------------------------------------------------*/
2237 static int __init
bma222_init(void)
2240 struct acc_hw
*hw
= get_cust_acc_hw();
2241 GSE_LOG("%s: i2c_number=%d\n", __func__
,hw
->i2c_num
);
2242 i2c_register_board_info(hw
->i2c_num
, &i2c_BMA222
, 1);
2243 acc_driver_add(&bma222_init_info
);
2246 /*----------------------------------------------------------------------------*/
2247 static void __exit
bma222_exit(void)
2251 /*----------------------------------------------------------------------------*/
2252 module_init(bma222_init
);
2253 module_exit(bma222_exit
);
2254 /*----------------------------------------------------------------------------*/
2255 MODULE_LICENSE("GPL");
2256 MODULE_DESCRIPTION("BMA222 I2C driver");
2257 MODULE_AUTHOR("Xiaoli.li@mediatek.com");