import PULS_20160108
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / misc / mediatek / accelerometer / bma222E-new / bma222E.c
1 /* BMA150 motion sensor driver
2 *
3 *
4 *
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.
8 *
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.
13 *
14 */
15
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>
29
30 #include <mach/mt_typedefs.h>
31 #include <mach/mt_gpio.h>
32 #include <mach/mt_pm_ldo.h>
33
34 #define POWER_NONE_MACRO MT65XX_POWER_NONE
35
36 #include <cust_acc.h>
37 #include <linux/hwmsensor.h>
38 #include <linux/hwmsen_dev.h>
39 #include <linux/sensors_io.h>
40 #include "bma222E.h"
41 #include <linux/hwmsen_helper.h>
42
43 #include <accel.h>
44 #include <linux/batch.h>
45 #ifdef CUSTOM_KERNEL_SENSORHUB
46 #include <SCP_sensorHub.h>
47 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
48
49 /*----------------------------------------------------------------------------*/
50 #define I2C_DRIVERID_BMA222 222
51 /*----------------------------------------------------------------------------*/
52 #define DEBUG 1
53 /*----------------------------------------------------------------------------*/
54
55 #define SW_CALIBRATION
56
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 /*----------------------------------------------------------------------------*/
64
65 /*********/
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)};
69
70
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);
77 #endif
78
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 /*----------------------------------------------------------------------------*/
86 typedef enum {
87 ADX_TRC_FILTER = 0x01,
88 ADX_TRC_RAWDATA = 0x02,
89 ADX_TRC_IOCTL = 0x04,
90 ADX_TRC_CALI = 0X08,
91 ADX_TRC_INFO = 0X10,
92 } ADX_TRC;
93 /*----------------------------------------------------------------------------*/
94 struct scale_factor{
95 u8 whole;
96 u8 fraction;
97 };
98 /*----------------------------------------------------------------------------*/
99 struct data_resolution {
100 struct scale_factor scalefactor;
101 int sensitivity;
102 };
103 /*----------------------------------------------------------------------------*/
104 #define C_MAX_FIR_LENGTH (32)
105 /*----------------------------------------------------------------------------*/
106 struct data_filter {
107 s16 raw[C_MAX_FIR_LENGTH][BMA222_AXES_NUM];
108 int sum[BMA222_AXES_NUM];
109 int num;
110 int idx;
111 };
112 /*----------------------------------------------------------------------------*/
113 struct bma222_i2c_data {
114 struct i2c_client *client;
115 struct acc_hw *hw;
116 struct hwmsen_convert cvt;
117 #ifdef CUSTOM_KERNEL_SENSORHUB
118 struct work_struct irq_work;
119 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
120
121 /*misc*/
122 struct data_resolution *reso;
123 atomic_t trace;
124 atomic_t suspend;
125 atomic_t selftest;
126 atomic_t filter;
127 s16 cali_sw[BMA222_AXES_NUM+1];
128
129 /*data*/
130 s8 offset[BMA222_AXES_NUM+1]; /*+1: for 4-byte alignment*/
131 s16 data[BMA222_AXES_NUM+1];
132
133 #ifdef CUSTOM_KERNEL_SENSORHUB
134 int SCP_init_done;
135 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
136
137
138 #if defined(CONFIG_BMA222_LOWPASS)
139 atomic_t firlen;
140 atomic_t fir_en;
141 struct data_filter fir;
142 #endif
143 /*early suspend*/
144 #if defined(CONFIG_HAS_EARLYSUSPEND) && defined(USE_EARLY_SUSPEND)
145 struct early_suspend early_drv;
146 #endif
147 u8 bandwidth;
148 };
149 /*----------------------------------------------------------------------------*/
150 static struct i2c_driver bma222_i2c_driver = {
151 .driver = {
152 // .owner = THIS_MODULE,
153 .name = BMA222_DEV_NAME,
154 },
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,
160 #endif
161 .id_table = bma222_i2c_id,
162 // .address_data = &bma222_addr_data,
163 };
164
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);
174
175
176 static bool enable_status = false;
177
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,
183 };
184
185 /*----------------------------------------------------------------------------*/
186 #ifdef GSE_DUBUG
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)
191 #else
192 #define GSE_TAG
193 #define GSE_FUN(f)
194 #define GSE_ERR(fmt, args...)
195 #define GSE_LOG(fmt, args...)
196 #endif
197
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)
202 };
203 /*----------------------------------------------------------------------------*/
204 static struct data_resolution bma222_offset_resolution = {{15, 6}, 64};
205
206 /*----------------------------------------------------------------------------*/
207 static int bma_i2c_read_block(struct i2c_client *client, u8 addr, u8 *data, u8 len)
208 {
209 u8 beg = addr;
210 int err;
211 struct i2c_msg msgs[2]={{0},{0}};
212
213 mutex_lock(&gsensor_mutex);
214
215 msgs[0].addr = client->addr;
216 msgs[0].flags = 0;
217 msgs[0].len =1;
218 msgs[0].buf = &beg;
219
220 msgs[1].addr = client->addr;
221 msgs[1].flags = I2C_M_RD;
222 msgs[1].len =len;
223 msgs[1].buf = data;
224
225 if (!client)
226 {
227 mutex_unlock(&gsensor_mutex);
228 return -EINVAL;
229 }
230 else if (len > C_I2C_FIFO_SIZE)
231 {
232 GSE_ERR(" length %d exceeds %d\n", len, C_I2C_FIFO_SIZE);
233 mutex_unlock(&gsensor_mutex);
234 return -EINVAL;
235 }
236 err = i2c_transfer(client->adapter, msgs, sizeof(msgs)/sizeof(msgs[0]));
237 if (err != 2)
238 {
239 GSE_ERR("i2c_transfer error: (%d %p %d) %d\n",addr, data, len, err);
240 err = -EIO;
241 }
242 else
243 {
244 err = 0;
245 }
246 mutex_unlock(&gsensor_mutex);
247 return err;
248
249 }
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*/
253 int err, idx, num;
254 char buf[C_I2C_FIFO_SIZE];
255 err =0;
256 mutex_lock(&gsensor_mutex);
257 if (!client)
258 {
259 mutex_unlock(&gsensor_mutex);
260 return -EINVAL;
261 }
262 else if (len >= C_I2C_FIFO_SIZE)
263 {
264 GSE_ERR(" length %d exceeds %d\n", len, C_I2C_FIFO_SIZE);
265 mutex_unlock(&gsensor_mutex);
266 return -EINVAL;
267 }
268
269 num = 0;
270 buf[num++] = addr;
271 for (idx = 0; idx < len; idx++)
272 {
273 buf[num++] = data[idx];
274 }
275
276 err = i2c_master_send(client, buf, num);
277 if (err < 0)
278 {
279 GSE_ERR("send command error!!\n");
280 mutex_unlock(&gsensor_mutex);
281 return -EFAULT;
282 }
283 mutex_unlock(&gsensor_mutex);
284 return err;
285 }
286 EXPORT_SYMBOL(bma_i2c_write_block);
287
288 /*----------------------------------------------------------------------------*/
289 /*--------------------Add by Susan----------------------------------*/
290 #ifdef CUSTOM_KERNEL_SENSORHUB
291 int BMA222_SCP_SetPowerMode(bool enable, int sensorType)
292 {
293 static bool gsensor_scp_en_status = false;
294 static unsigned int gsensor_scp_en_map = 0;
295 SCP_SENSOR_HUB_DATA req;
296 int len;
297 int err = 0;
298
299 mutex_lock(&gsensor_scp_en_mutex);
300
301 if (sensorType >= 32)
302 {
303 GSE_ERR("Out of index!\n");
304 return -1;
305 }
306
307 if (true == enable)
308 {
309 gsensor_scp_en_map |= (1<<sensorType);
310 }
311 else
312 {
313 gsensor_scp_en_map &= ~(1<<sensorType);
314 }
315
316 if (0 == gsensor_scp_en_map)
317 enable = false;
318 else
319 enable = true;
320
321 if (gsensor_scp_en_status != enable)
322 {
323 gsensor_scp_en_status = enable;
324
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);
330 if (err)
331 {
332 GSE_ERR("SCP_sensorHub_req_send fail\n");
333 }
334 }
335
336 mutex_unlock(&gsensor_scp_en_mutex);
337
338 return err;
339 }
340 EXPORT_SYMBOL(BMA222_SCP_SetPowerMode);
341 #endif
342 /*----------------------------------------------------------------------------*/
343 /*--------------------BMA222 power control function----------------------------------*/
344 static void BMA222_power(struct acc_hw *hw, unsigned int on)
345 {
346 #ifndef FPGA_EARLY_PORTING
347 static unsigned int power_on = 0;
348
349 if(hw->power_id != POWER_NONE_MACRO) // have externel LDO
350 {
351 GSE_LOG("power %s\n", on ? "on" : "off");
352 if(power_on == on) // power status not change
353 {
354 GSE_LOG("ignore power control: %d\n", on);
355 }
356 else if(on) // power on
357 {
358 if(!hwPowerOn(hw->power_id, hw->power_vol, "BMA222"))
359 {
360 GSE_ERR("power on fails!!\n");
361 }
362 }
363 else // power off
364 {
365 if (!hwPowerDown(hw->power_id, "BMA222"))
366 {
367 GSE_ERR("power off fail!!\n");
368 }
369 }
370 }
371 power_on = on;
372 #endif //#ifndef FPGA_EARLY_PORTING
373 }
374 /*----------------------------------------------------------------------------*/
375
376 /*----------------------------------------------------------------------------*/
377 static int BMA222_SetDataResolution(struct bma222_i2c_data *obj)
378 {
379
380 /*set g sensor dataresolution here*/
381
382 /*BMA222 only can set to 10-bit dataresolution, so do nothing in bma222 driver here*/
383
384 /*end of set dataresolution*/
385
386
387
388 /*we set measure range from -2g to +2g in BMA150_SetDataFormat(client, BMA150_RANGE_2G),
389 and set 10-bit dataresolution BMA150_SetDataResolution()*/
390
391 /*so bma222_data_resolution[0] set value as {{ 3, 9}, 256} when declaration, and assign the value to obj->reso here*/
392
393 obj->reso = &bma222_data_resolution[0];
394 return 0;
395
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*/
398
399 }
400 /*----------------------------------------------------------------------------*/
401 static int BMA222_ReadData(struct i2c_client *client, s16 data[BMA222_AXES_NUM])
402 {
403 struct bma222_i2c_data *priv = i2c_get_clientdata(client);
404 int err = 0;
405 #if 0 //CUSTOM_KERNEL_SENSORHUB
406 SCP_SENSOR_HUB_DATA req;
407 int len;
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
412
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);
418 if (err)
419 {
420 GSE_ERR("SCP_sensorHub_req_send!\n");
421 return err;
422 }
423
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)
427 {
428 GSE_ERR("error : %d\n", req.get_data_rsp.errCode);
429 return req.get_data_rsp.errCode;
430 }
431
432 len -= offsetof(SCP_SENSOR_HUB_GET_DATA_RSP, int8_Data);
433
434 if (6 == len)
435 {
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];
439 }
440 else
441 {
442 GSE_ERR("data length fail : %d\n", len);
443 }
444
445 if(atomic_read(&priv->trace) & ADX_TRC_RAWDATA)
446 {
447 //show data
448 }
449 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
450 if(NULL == client)
451 {
452 err = -EINVAL;
453 }
454 else if((err = bma_i2c_read_block(client, addr, buf, 0x05))!=0)
455 {
456 GSE_ERR("error: %d\n", err);
457 }
458 else
459 {
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)
464 {
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]);
467 }
468
469 if(data[BMA222_AXIS_X]&0x80)
470 {
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];
475 }
476 if(data[BMA222_AXIS_Y]&0x80)
477 {
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];
482 }
483 if(data[BMA222_AXIS_Z]&0x80)
484 {
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];
489 }
490
491 if(atomic_read(&priv->trace) & ADX_TRC_RAWDATA)
492 {
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]);
495 }
496 #ifdef CONFIG_BMA222_LOWPASS
497 if(atomic_read(&priv->filter))
498 {
499 if(atomic_read(&priv->fir_en) && !atomic_read(&priv->suspend))
500 {
501 int idx, firlen = atomic_read(&priv->firlen);
502 if(priv->fir.num < firlen)
503 {
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)
511 {
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]);
515 }
516 priv->fir.num++;
517 priv->fir.idx++;
518 }
519 else
520 {
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];
531 priv->fir.idx++;
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)
536 {
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]);
541 }
542 }
543 }
544 }
545 #endif
546 }
547
548 return err;
549 }
550 /*----------------------------------------------------------------------------*/
551
552 static int BMA222_ReadOffset(struct i2c_client *client, s8 ofs[BMA222_AXES_NUM])
553 {
554 int err;
555 err = 0;
556
557
558 #ifdef SW_CALIBRATION
559 ofs[0]=ofs[1]=ofs[2]=0x0;
560 #else
561 if((err = bma_i2c_read_block(client, BMA222_REG_OFSX, ofs, BMA222_AXES_NUM)))
562 {
563 GSE_ERR("error: %d\n", err);
564 }
565 #endif
566 //printk("offesx=%x, y=%x, z=%x",ofs[0],ofs[1],ofs[2]);
567
568 return err;
569 }
570
571 /*----------------------------------------------------------------------------*/
572 static int BMA222_ResetCalibration(struct i2c_client *client)
573 {
574 struct bma222_i2c_data *obj = i2c_get_clientdata(client);
575 //u8 ofs[4]={0,0,0,0};
576 int err = 0;
577 #ifdef CUSTOM_KERNEL_SENSORHUB
578 SCP_SENSOR_HUB_DATA data;
579 BMA222_CUST_DATA *pCustData;
580 unsigned int len;
581 #endif
582
583 #ifdef GSENSOR_UT
584 GSE_FUN();
585 #endif
586
587 #ifdef CUSTOM_KERNEL_SENSORHUB
588 if (0 != obj->SCP_init_done)
589 {
590 pCustData = (BMA222_CUST_DATA *)&data.set_cust_req.custData;
591
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);
597 }
598 #endif
599
600 memset(obj->cali_sw, 0x00, sizeof(obj->cali_sw));
601 memset(obj->offset, 0x00, sizeof(obj->offset));
602 return err;
603 }
604 /*----------------------------------------------------------------------------*/
605 static int BMA222_ReadCalibration(struct i2c_client *client, int dat[BMA222_AXES_NUM])
606 {
607 struct bma222_i2c_data *obj = i2c_get_clientdata(client);
608 int err = 0;
609 int mul;
610
611 GSE_FUN();
612 #ifdef SW_CALIBRATION
613 mul = 0;//only SW Calibration, disable HW Calibration
614 #else
615 if ((err = BMA222_ReadOffset(client, obj->offset))) {
616 GSE_ERR("read offset fail, %d\n", err);
617 return err;
618 }
619 mul = obj->reso->sensitivity/bma222_offset_resolution.sensitivity;
620 #endif
621
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]);
625
626 return err;
627 }
628 /*----------------------------------------------------------------------------*/
629 static int BMA222_ReadCalibrationEx(struct i2c_client *client, int act[BMA222_AXES_NUM], int raw[BMA222_AXES_NUM])
630 {
631 /*raw: the raw calibration data; act: the actual calibration data*/
632 struct bma222_i2c_data *obj = i2c_get_clientdata(client);
633 int err;
634 int mul;
635 err = 0;
636
637
638 #ifdef SW_CALIBRATION
639 mul = 0;//only SW Calibration, disable HW Calibration
640 #else
641 if((err = BMA222_ReadOffset(client, obj->offset)))
642 {
643 GSE_ERR("read offset fail, %d\n", err);
644 return err;
645 }
646 mul = obj->reso->sensitivity/bma222_offset_resolution.sensitivity;
647 #endif
648
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];
652
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];
656
657 return 0;
658 }
659 /*----------------------------------------------------------------------------*/
660 static int BMA222_WriteCalibration(struct i2c_client *client, int dat[BMA222_AXES_NUM])
661 {
662 struct bma222_i2c_data *obj = i2c_get_clientdata(client);
663 int err = 0;
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;
668 unsigned int len;
669 #endif
670
671
672 if(0 != (err = BMA222_ReadCalibrationEx(client, cali, raw))) /*offset will be updated in obj->offset*/
673 {
674 GSE_ERR("read offset fail, %d\n", err);
675 return err;
676 }
677
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]);
682
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);
693 #endif
694
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];
699
700 GSE_LOG("UPDATE: (%+3d %+3d %+3d)\n",
701 dat[BMA222_AXIS_X], dat[BMA222_AXIS_Y], dat[BMA222_AXIS_Z]);
702
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]]);
707 #else
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));
712
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);
717
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]);
724
725 if((err = hwmsen_write_block(obj->client, BMA222_REG_OFSX, obj->offset, BMA222_AXES_NUM)))
726 {
727 GSE_ERR("write offset fail: %d\n", err);
728 return err;
729 }
730 #endif
731 mdelay(1);
732 return err;
733 }
734 /*----------------------------------------------------------------------------*/
735 static int BMA222_CheckDeviceID(struct i2c_client *client)
736 {
737 u8 databuf[2]={0};
738 int res = 0;
739
740
741 res = bma_i2c_read_block(client,BMA222_REG_DEVID,databuf,0x1);
742 if(res < 0)
743 {
744 goto exit_BMA222_CheckDeviceID;
745 }
746
747
748 GSE_LOG("BMA222_CheckDeviceID %d done!\n ", databuf[0]);
749
750 exit_BMA222_CheckDeviceID:
751 if (res < 0)
752 {
753 GSE_ERR("BMA222_CheckDeviceID %d failt!\n ", BMA222_ERR_I2C);
754 return BMA222_ERR_I2C;
755 }
756 mdelay(1);
757 return BMA222_SUCCESS;
758 }
759 /*----------------------------------------------------------------------------*/
760 static int BMA222_SetPowerMode(struct i2c_client *client, bool enable)
761 {
762 struct bma222_i2c_data *obj = i2c_get_clientdata(client);
763 int res = 0;
764
765 u8 databuf[2];
766 u8 addr = BMA222_REG_POWER_CTL;
767
768 if(enable == sensor_power )
769 {
770 GSE_LOG("Sensor power status is newest!\n");
771 return BMA222_SUCCESS;
772 }
773
774 if(bma_i2c_read_block(client, addr, databuf, 0x01))
775 {
776 GSE_ERR("read power ctl register err!\n");
777 return BMA222_ERR_I2C;
778 }
779 GSE_LOG("set power mode value = 0x%x!\n",databuf[0]);
780 mdelay(1);
781 if(enable == TRUE)
782 {
783 databuf[0] &= ~BMA222_MEASURE_MODE;
784 }
785 else
786 {
787 databuf[0] |= BMA222_MEASURE_MODE;
788 }
789
790 res = bma_i2c_write_block(client,BMA222_REG_POWER_CTL,databuf,0x1);
791 if(res < 0)
792 {
793 GSE_LOG("set power mode failed!\n");
794 return BMA222_ERR_I2C;
795 }
796 else if(atomic_read(&obj->trace) & ADX_TRC_INFO)
797 {
798 GSE_LOG("set power mode ok %d!\n", databuf[1]);
799 }
800
801
802 sensor_power = enable;
803 mdelay(1);
804 //GSE_LOG("leave Sensor power status is sensor_power = %d\n",sensor_power);
805 return BMA222_SUCCESS;
806 }
807 /*----------------------------------------------------------------------------*/
808 static int BMA222_SetDataFormat(struct i2c_client *client, u8 dataformat)
809 {
810 struct bma222_i2c_data *obj = i2c_get_clientdata(client);
811 u8 databuf[10]={0};
812 int res = 0;
813
814 if(bma_i2c_read_block(client, BMA222_REG_DATA_FORMAT, databuf, 0x01))
815 {
816 printk("bma222 read Dataformat failt \n");
817 return BMA222_ERR_I2C;
818 }
819 mdelay(1);
820 databuf[0] &= ~BMA222_RANGE_MASK;
821 databuf[0] |= dataformat;
822
823 res = bma_i2c_write_block(client,BMA222_REG_DATA_FORMAT,databuf,0x1);
824 if(res < 0)
825 {
826 return BMA222_ERR_I2C;
827 }
828
829 //printk("BMA222_SetDataFormat OK! \n");
830 mdelay(1);
831 return BMA222_SetDataResolution(obj);
832 }
833 /*----------------------------------------------------------------------------*/
834 static int BMA222_SetBWRate(struct i2c_client *client, u8 bwrate)
835 {
836 u8 databuf[10]={0};
837 int res = 0;
838
839 if(bma_i2c_read_block(client, BMA222_REG_BW_RATE, databuf, 0x01))
840 {
841 printk("bma222 read rate failt \n");
842 return BMA222_ERR_I2C;
843 }
844 mdelay(1);
845 databuf[0] &= ~BMA222_BW_MASK;
846 databuf[0] |= bwrate;
847
848
849 res = bma_i2c_write_block(client,BMA222_REG_BW_RATE,databuf,0x1);
850 if(res < 0)
851 {
852 return BMA222_ERR_I2C;
853 }
854 mdelay(1);
855 //printk("BMA222_SetBWRate OK! \n");
856
857 return BMA222_SUCCESS;
858 }
859 /*----------------------------------------------------------------------------*/
860 static int BMA222_SetIntEnable(struct i2c_client *client, u8 intenable)
861 {
862 //u8 databuf[10];
863 int res = 0;
864
865 res = hwmsen_write_byte(client, BMA222_INT_REG_1, 0x00);
866 if(res != BMA222_SUCCESS)
867 {
868 return res;
869 }
870 mdelay(1);
871 res = hwmsen_write_byte(client, BMA222_INT_REG_2, 0x00);
872 if(res != BMA222_SUCCESS)
873 {
874 return res;
875 }
876 //printk("BMA222 disable interrupt ...\n");
877
878 /*for disable interrupt function*/
879 mdelay(1);
880 return BMA222_SUCCESS;
881 }
882
883 /*----------------------------------------------------------------------------*/
884 static int bma222_init_client(struct i2c_client *client, int reset_cali)
885 {
886 struct bma222_i2c_data *obj = i2c_get_clientdata(client);
887 int res = 0;
888
889 GSE_FUN();
890
891
892 res = BMA222_CheckDeviceID(client);
893 if(res != BMA222_SUCCESS)
894 {
895 return res;
896 }
897 //printk("BMA222_CheckDeviceID ok \n");
898
899 res = BMA222_SetBWRate(client, BMA222_BW_100HZ);
900 if(res != BMA222_SUCCESS )
901 {
902 return res;
903 }
904 //printk("BMA222_SetBWRate OK!\n");
905
906 res = BMA222_SetDataFormat(client, BMA222_RANGE_2G);
907 if(res != BMA222_SUCCESS)
908 {
909 return res;
910 }
911 //printk("BMA222_SetDataFormat OK!\n");
912
913 gsensor_gain.x = gsensor_gain.y = gsensor_gain.z = obj->reso->sensitivity;
914
915 #ifdef CUSTOM_KERNEL_SENSORHUB
916 res = gsensor_setup_irq();
917 if(res != BMA222_SUCCESS)
918 {
919 return res;
920 }
921 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
922
923 res = BMA222_SetIntEnable(client, 0x00);
924 if(res != BMA222_SUCCESS)
925 {
926 return res;
927 }
928 //printk("BMA222 disable interrupt function!\n");
929
930 res = BMA222_SetPowerMode(client, enable_status);//false);//
931 if(res != BMA222_SUCCESS)
932 {
933 return res;
934 }
935 //printk("BMA222_SetPowerMode OK!\n");
936
937
938 if(0 != reset_cali)
939 {
940 /*reset calibration only in power on*/
941 res = BMA222_ResetCalibration(client);
942 if(res != BMA222_SUCCESS)
943 {
944 return res;
945 }
946 }
947 GSE_LOG("bma222_init_client OK!\n");
948 #ifdef CONFIG_BMA222_LOWPASS
949 memset(&obj->fir, 0x00, sizeof(obj->fir));
950 #endif
951 return BMA222_SUCCESS;
952 }
953 /*----------------------------------------------------------------------------*/
954 static int BMA222_ReadChipInfo(struct i2c_client *client, char *buf, int bufsize)
955 {
956 u8 databuf[10];
957
958 memset(databuf, 0, sizeof(u8)*10);
959
960 if((NULL == buf)||(bufsize<=30))
961 {
962 return -1;
963 }
964
965 if(NULL == client)
966 {
967 *buf = 0;
968 return -2;
969 }
970
971 sprintf(buf, "BMA222 Chip");
972 return 0;
973 }
974 /*----------------------------------------------------------------------------*/
975 static int BMA222_ReadSensorData(struct i2c_client *client, char *buf, int bufsize)
976 {
977 struct bma222_i2c_data *obj = (struct bma222_i2c_data*)i2c_get_clientdata(client);
978 u8 databuf[20];
979 int acc[BMA222_AXES_NUM];
980 int res = 0;
981 memset(databuf, 0, sizeof(u8)*10);
982
983 if(NULL == buf)
984 {
985 return -1;
986 }
987 if(NULL == client)
988 {
989 *buf = 0;
990 return -2;
991 }
992
993 if(sensor_suspend == 1)
994 {
995 //GSE_LOG("sensor in suspend read not data!\n");
996 return 0;
997 }
998
999 if((res = BMA222_ReadData(client, obj->data))!=0)
1000 {
1001 GSE_ERR("I2C error: ret value=%d", res);
1002 return -3;
1003 }
1004 else
1005 {
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];
1016
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]);
1018
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]);
1024
1025
1026 //GSE_LOG("Mapped gsensor data: %d, %d, %d!\n", acc[BMA150_AXIS_X], acc[BMA150_AXIS_Y], acc[BMA150_AXIS_Z]);
1027
1028 //Out put the mg
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
1034
1035
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)
1038 {
1039 GSE_LOG("gsensor data: %s!\n", buf);
1040 }
1041 }
1042
1043 return 0;
1044 }
1045 /*----------------------------------------------------------------------------*/
1046 static int BMA222_ReadRawData(struct i2c_client *client, char *buf)
1047 {
1048 struct bma222_i2c_data *obj = (struct bma222_i2c_data*)i2c_get_clientdata(client);
1049 int res = 0;
1050
1051 if (!buf || !client)
1052 {
1053 return EINVAL;
1054 }
1055
1056 if(0 != (res = BMA222_ReadData(client, obj->data)))
1057 {
1058 GSE_ERR("I2C error: ret value=%d", res);
1059 return EIO;
1060 }
1061 else
1062 {
1063 sprintf(buf, "BMA222_ReadRawData %04x %04x %04x", obj->data[BMA222_AXIS_X],
1064 obj->data[BMA222_AXIS_Y], obj->data[BMA222_AXIS_Z]);
1065
1066 }
1067
1068 return 0;
1069 }
1070 /*----------------------------------------------------------------------------*/
1071 static ssize_t show_chipinfo_value(struct device_driver *ddri, char *buf)
1072 {
1073 struct i2c_client *client = bma222_i2c_client;
1074 char strbuf[BMA222_BUFSIZE];
1075 if(NULL == client)
1076 {
1077 GSE_ERR("i2c client is null!!\n");
1078 return 0;
1079 }
1080
1081 BMA222_ReadChipInfo(client, strbuf, BMA222_BUFSIZE);
1082 return snprintf(buf, PAGE_SIZE, "%s\n", strbuf);
1083 }
1084
1085 #if 0
1086 static ssize_t gsensor_init(struct device_driver *ddri, char *buf, size_t count)
1087 {
1088 struct i2c_client *client = bma222_i2c_client;
1089 char strbuf[BMA222_BUFSIZE];
1090
1091 if(NULL == client)
1092 {
1093 GSE_ERR("i2c client is null!!\n");
1094 return 0;
1095 }
1096 bma222_init_client(client, 1);
1097 return snprintf(buf, PAGE_SIZE, "%s\n", strbuf);
1098 }
1099 #endif
1100
1101
1102 /*----------------------------------------------------------------------------*/
1103 static ssize_t show_sensordata_value(struct device_driver *ddri, char *buf)
1104 {
1105 struct i2c_client *client = bma222_i2c_client;
1106 char strbuf[BMA222_BUFSIZE];
1107
1108 if(NULL == client)
1109 {
1110 GSE_ERR("i2c client is null!!\n");
1111 return 0;
1112 }
1113 BMA222_ReadSensorData(client, strbuf, BMA222_BUFSIZE);
1114 //BMA150_ReadRawData(client, strbuf);
1115 return snprintf(buf, PAGE_SIZE, "%s\n", strbuf);
1116 }
1117
1118 #if 0
1119 static ssize_t show_sensorrawdata_value(struct device_driver *ddri, char *buf, size_t count)
1120 {
1121 struct i2c_client *client = bma222_i2c_client;
1122 char strbuf[BMA222_BUFSIZE];
1123
1124 if(NULL == client)
1125 {
1126 GSE_ERR("i2c client is null!!\n");
1127 return 0;
1128 }
1129 //BMA150_ReadSensorData(client, strbuf, BMA150_BUFSIZE);
1130 BMA222_ReadRawData(client, strbuf);
1131 return snprintf(buf, PAGE_SIZE, "%s\n", strbuf);
1132 }
1133 #endif
1134
1135 /*----------------------------------------------------------------------------*/
1136 #if 1
1137 static ssize_t show_cali_value(struct device_driver *ddri, char *buf)
1138 {
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];
1143
1144 if(NULL == client)
1145 {
1146 GSE_ERR("i2c client is null!!\n");
1147 return 0;
1148 }
1149
1150 obj = i2c_get_clientdata(client);
1151
1152
1153
1154 if(0 != (err = BMA222_ReadOffset(client, obj->offset)))
1155 {
1156 return -EINVAL;
1157 }
1158 else if(0 != (err = BMA222_ReadCalibration(client, tmp)))
1159 {
1160 return -EINVAL;
1161 }
1162 else
1163 {
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]);
1170
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]);
1176
1177 return len;
1178 }
1179 }
1180 /*----------------------------------------------------------------------------*/
1181 static ssize_t store_cali_value(struct device_driver *ddri, const char *buf, size_t count)
1182 {
1183 struct i2c_client *client = bma222_i2c_client;
1184 int err, x, y, z;
1185 int dat[BMA222_AXES_NUM];
1186
1187 if(!strncmp(buf, "rst", 3))
1188 {
1189 if(0 != (err = BMA222_ResetCalibration(client)))
1190 {
1191 GSE_ERR("reset offset err = %d\n", err);
1192 }
1193 }
1194 else if(3 == sscanf(buf, "0x%02X 0x%02X 0x%02X", &x, &y, &z))
1195 {
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)))
1200 {
1201 GSE_ERR("write calibration err = %d\n", err);
1202 }
1203 }
1204 else
1205 {
1206 GSE_ERR("invalid format\n");
1207 }
1208
1209 return count;
1210 }
1211 #endif
1212
1213 /*----------------------------------------------------------------------------*/
1214 static ssize_t show_firlen_value(struct device_driver *ddri, char *buf)
1215 {
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))
1220 {
1221 int idx, len = atomic_read(&obj->firlen);
1222 GSE_LOG("len = %2d, idx = %2d\n", obj->fir.num, obj->fir.idx);
1223
1224 for(idx = 0; idx < len; idx++)
1225 {
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]);
1227 }
1228
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);
1231 }
1232 return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&obj->firlen));
1233 #else
1234 return snprintf(buf, PAGE_SIZE, "not support\n");
1235 #endif
1236 }
1237 /*----------------------------------------------------------------------------*/
1238 static ssize_t store_firlen_value(struct device_driver *ddri, const char *buf, size_t count)
1239 {
1240 #ifdef CONFIG_BMA222_LOWPASS
1241 struct i2c_client *client = bma222_i2c_client;
1242 struct bma222_i2c_data *obj = i2c_get_clientdata(client);
1243 int firlen;
1244
1245 if(1 != sscanf(buf, "%d", &firlen))
1246 {
1247 GSE_ERR("invallid format\n");
1248 }
1249 else if(firlen > C_MAX_FIR_LENGTH)
1250 {
1251 GSE_ERR("exceeds maximum filter length\n");
1252 }
1253 else
1254 {
1255 atomic_set(&obj->firlen, firlen);
1256 if(NULL == firlen)
1257 {
1258 atomic_set(&obj->fir_en, 0);
1259 }
1260 else
1261 {
1262 memset(&obj->fir, 0x00, sizeof(obj->fir));
1263 atomic_set(&obj->fir_en, 1);
1264 }
1265 }
1266 #endif
1267 return count;
1268 }
1269 /*----------------------------------------------------------------------------*/
1270 static ssize_t show_trace_value(struct device_driver *ddri, char *buf)
1271 {
1272 ssize_t res;
1273 struct bma222_i2c_data *obj = obj_i2c_data;
1274 if (obj == NULL)
1275 {
1276 GSE_ERR("i2c_data obj is null!!\n");
1277 return 0;
1278 }
1279
1280 res = snprintf(buf, PAGE_SIZE, "0x%04X\n", atomic_read(&obj->trace));
1281 return res;
1282 }
1283 /*----------------------------------------------------------------------------*/
1284 static ssize_t store_trace_value(struct device_driver *ddri, const char *buf, size_t count)
1285 {
1286 struct bma222_i2c_data *obj = obj_i2c_data;
1287 int trace;
1288 if (obj == NULL)
1289 {
1290 GSE_ERR("i2c_data obj is null!!\n");
1291 return 0;
1292 }
1293
1294 if(1 == sscanf(buf, "0x%x", &trace))
1295 {
1296 atomic_set(&obj->trace, trace);
1297 }
1298 else
1299 {
1300 GSE_ERR("invalid content: '%s', length = %d\n", buf, (int)count);
1301 }
1302
1303 return count;
1304 }
1305 /*----------------------------------------------------------------------------*/
1306 static ssize_t show_status_value(struct device_driver *ddri, char *buf)
1307 {
1308 ssize_t len = 0;
1309 struct bma222_i2c_data *obj = obj_i2c_data;
1310 if (obj == NULL)
1311 {
1312 GSE_ERR("i2c_data obj is null!!\n");
1313 return 0;
1314 }
1315
1316 if(obj->hw)
1317 {
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);
1320 }
1321 else
1322 {
1323 len += snprintf(buf+len, PAGE_SIZE-len, "CUST: NULL\n");
1324 }
1325 return len;
1326 }
1327 /*----------------------------------------------------------------------------*/
1328 static ssize_t show_power_status_value(struct device_driver *ddri, char *buf)
1329 {
1330
1331 u8 databuf[2];
1332 //int res = 0;
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))
1336 {
1337 GSE_ERR("read power ctl register err!\n");
1338 return 1;
1339 }
1340
1341 if(sensor_power)
1342 GSE_LOG("G sensor is in work mode, sensor_power = %d\n", sensor_power);
1343 else
1344 GSE_LOG("G sensor is in standby mode, sensor_power = %d\n", sensor_power);
1345
1346 return snprintf(buf, PAGE_SIZE, "%x\n", databuf[0]);
1347 }
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);
1356
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,
1366 };
1367 /*----------------------------------------------------------------------------*/
1368 static int bma222_create_attr(struct device_driver *driver)
1369 {
1370 int idx, err = 0;
1371 int num = (int)(sizeof(bma222_attr_list)/sizeof(bma222_attr_list[0]));
1372 if (driver == NULL)
1373 {
1374 return -EINVAL;
1375 }
1376
1377 for(idx = 0; idx < num; idx++)
1378 {
1379 if(0 != (err = driver_create_file(driver, bma222_attr_list[idx])))
1380 {
1381 GSE_ERR("driver_create_file (%s) = %d\n", bma222_attr_list[idx]->attr.name, err);
1382 break;
1383 }
1384 }
1385 return err;
1386 }
1387 /*----------------------------------------------------------------------------*/
1388 static int bma222_delete_attr(struct device_driver *driver)
1389 {
1390 int idx ,err = 0;
1391 int num = (int)(sizeof(bma222_attr_list)/sizeof(bma222_attr_list[0]));
1392
1393 if(driver == NULL)
1394 {
1395 return -EINVAL;
1396 }
1397
1398
1399 for(idx = 0; idx < num; idx++)
1400 {
1401 driver_remove_file(driver, bma222_attr_list[idx]);
1402 }
1403
1404
1405 return err;
1406 }
1407
1408 /*----------------------------------------------------------------------------*/
1409 #ifdef CUSTOM_KERNEL_SENSORHUB
1410 static void gsensor_irq_work(struct work_struct *work)
1411 {
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;
1416 int i;
1417 uint sizeOfCustData;
1418 uint len;
1419 char *p = (char *)obj->hw;
1420
1421 GSE_FUN();
1422 p_cust_data = (BMA222_CUST_DATA *)data.set_cust_req.custData;
1423
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);
1429
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));
1432
1433 for (i=0;sizeOfCustData>0;i++)
1434 {
1435 p_cust_data->setCust.part = i;
1436 if (sizeOfCustData > max_cust_data_size_per_packet)
1437 {
1438 len = max_cust_data_size_per_packet;
1439 }
1440 else
1441 {
1442 len = sizeOfCustData;
1443 }
1444
1445 memcpy(p_cust_data->setCust.data, p, len);
1446 sizeOfCustData -= len;
1447 p += len;
1448
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);
1453
1454 }
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;
1462 }
1463 /*----------------------------------------------------------------------------*/
1464 static int gsensor_irq_handler(void* data, uint len)
1465 {
1466 struct bma222_i2c_data *obj = obj_i2c_data;
1467 SCP_SENSOR_HUB_DATA_P rsp = (SCP_SENSOR_HUB_DATA_P)data;
1468
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);
1470 if(!obj)
1471 {
1472 return -1;
1473 }
1474
1475 switch(rsp->rsp.action)
1476 {
1477 case SENSOR_HUB_NOTIFY:
1478 switch(rsp->notify_rsp.event)
1479 {
1480 case SCP_INIT_DONE:
1481 schedule_work(&obj->irq_work);
1482 GSE_ERR("OK sensor hub notify\n");
1483 break;
1484 default:
1485 GSE_ERR("Error sensor hub notify\n");
1486 break;
1487 }
1488 break;
1489 default:
1490 GSE_ERR("Error sensor hub action\n");
1491 break;
1492 }
1493
1494 return 0;
1495 }
1496
1497 static int gsensor_setup_irq()
1498 {
1499 int err = 0;
1500
1501
1502
1503 err = SCP_sensorHub_rsp_registration(ID_ACCELEROMETER, gsensor_irq_handler);
1504
1505 return err;
1506 }
1507 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
1508 /******************************************************************************
1509 * Function Configuration
1510 ******************************************************************************/
1511 static int bma222_open(struct inode *inode, struct file *file)
1512 {
1513 file->private_data = bma222_i2c_client;
1514
1515 if(file->private_data == NULL)
1516 {
1517 GSE_ERR("null pointer!!\n");
1518 return -EINVAL;
1519 }
1520 return nonseekable_open(inode, file);
1521 }
1522 /*----------------------------------------------------------------------------*/
1523 static int bma222_release(struct inode *inode, struct file *file)
1524 {
1525 file->private_data = NULL;
1526 return 0;
1527 }
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,
1532 unsigned long arg)
1533
1534 {
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];
1538 void __user *data;
1539 SENSOR_DATA sensor_data;
1540 long err = 0;
1541 int cali[3];
1542
1543 //GSE_FUN(f);
1544 if(_IOC_DIR(cmd) & _IOC_READ)
1545 {
1546 err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
1547 }
1548 else if(_IOC_DIR(cmd) & _IOC_WRITE)
1549 {
1550 err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
1551 }
1552
1553 if(err)
1554 {
1555 GSE_ERR("access error: %08X, (%2d, %2d)\n", cmd, _IOC_DIR(cmd), _IOC_SIZE(cmd));
1556 return -EFAULT;
1557 }
1558
1559 switch(cmd)
1560 {
1561 case GSENSOR_IOCTL_INIT:
1562 bma222_init_client(client, 0);
1563 break;
1564
1565 case GSENSOR_IOCTL_READ_CHIPINFO:
1566 data = (void __user *) arg;
1567 if(data == NULL)
1568 {
1569 err = -EINVAL;
1570 break;
1571 }
1572
1573 BMA222_ReadChipInfo(client, strbuf, BMA222_BUFSIZE);
1574 if(copy_to_user(data, strbuf, strlen(strbuf)+1))
1575 {
1576 err = -EFAULT;
1577 break;
1578 }
1579 break;
1580
1581 case GSENSOR_IOCTL_READ_SENSORDATA:
1582 data = (void __user *) arg;
1583 if(data == NULL)
1584 {
1585 err = -EINVAL;
1586 break;
1587 }
1588 BMA222_SetPowerMode(client,true);
1589 BMA222_ReadSensorData(client, strbuf, BMA222_BUFSIZE);
1590 if(copy_to_user(data, strbuf, strlen(strbuf)+1))
1591 {
1592 err = -EFAULT;
1593 break;
1594 }
1595 break;
1596
1597 case GSENSOR_IOCTL_READ_GAIN:
1598 data = (void __user *) arg;
1599 if(data == NULL)
1600 {
1601 err = -EINVAL;
1602 break;
1603 }
1604
1605 if(copy_to_user(data, &gsensor_gain, sizeof(GSENSOR_VECTOR3D)))
1606 {
1607 err = -EFAULT;
1608 break;
1609 }
1610 break;
1611
1612 case GSENSOR_IOCTL_READ_RAW_DATA:
1613 data = (void __user *) arg;
1614 if(data == NULL)
1615 {
1616 err = -EINVAL;
1617 break;
1618 }
1619 BMA222_ReadRawData(client, strbuf);
1620 if(copy_to_user(data, &strbuf, strlen(strbuf)+1))
1621 {
1622 err = -EFAULT;
1623 break;
1624 }
1625 break;
1626
1627 case GSENSOR_IOCTL_SET_CALI:
1628 data = (void __user*)arg;
1629 if(data == NULL)
1630 {
1631 err = -EINVAL;
1632 break;
1633 }
1634 if(copy_from_user(&sensor_data, data, sizeof(sensor_data)))
1635 {
1636 err = -EFAULT;
1637 break;
1638 }
1639 if(atomic_read(&obj->suspend))
1640 {
1641 GSE_ERR("Perform calibration in suspend state!!\n");
1642 err = -EINVAL;
1643 }
1644 else
1645 {
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);
1650 }
1651 break;
1652
1653 case GSENSOR_IOCTL_CLR_CALI:
1654 err = BMA222_ResetCalibration(client);
1655 break;
1656
1657 case GSENSOR_IOCTL_GET_CALI:
1658 data = (void __user*)arg;
1659 if(data == NULL)
1660 {
1661 err = -EINVAL;
1662 break;
1663 }
1664 if(0 != (err = BMA222_ReadCalibration(client, cali)))
1665 {
1666 break;
1667 }
1668
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)))
1673 {
1674 err = -EFAULT;
1675 break;
1676 }
1677 break;
1678
1679
1680 default:
1681 GSE_ERR("unknown IOCTL: 0x%08x\n", cmd);
1682 err = -ENOIOCTLCMD;
1683 break;
1684
1685 }
1686
1687 return err;
1688 }
1689
1690
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,
1697 };
1698 /*----------------------------------------------------------------------------*/
1699 static struct miscdevice bma222_device = {
1700 .minor = MISC_DYNAMIC_MINOR,
1701 .name = "gsensor",
1702 .fops = &bma222_fops,
1703 };
1704 /*----------------------------------------------------------------------------*/
1705 #ifndef USE_EARLY_SUSPEND
1706 /*----------------------------------------------------------------------------*/
1707 static int bma222_suspend(struct i2c_client *client, pm_message_t msg)
1708 {
1709 struct bma222_i2c_data *obj = i2c_get_clientdata(client);
1710 int err = 0;
1711 mutex_lock(&gsensor_scp_en_mutex);
1712 if(msg.event == PM_EVENT_SUSPEND)
1713 {
1714 if(obj == NULL)
1715 {
1716 GSE_ERR("null pointer!!\n");
1717 mutex_unlock(&gsensor_scp_en_mutex);
1718 return -EINVAL;
1719 }
1720 atomic_set(&obj->suspend, 1);
1721 #ifdef CUSTOM_KERNEL_SENSORHUB
1722 if(0 != (err = BMA222_SCP_SetPowerMode(false, ID_ACCELEROMETER)))
1723 #else
1724 if(0 != (err = BMA222_SetPowerMode(obj->client, false)))
1725 #endif
1726 {
1727 GSE_ERR("write power control fail!!\n");
1728 mutex_unlock(&gsensor_scp_en_mutex);
1729 return -EINVAL;
1730 }
1731 #ifndef CUSTOM_KERNEL_SENSORHUB
1732 BMA222_power(obj->hw, 0);
1733 #endif
1734 }
1735 mutex_unlock(&gsensor_scp_en_mutex);
1736 return err;
1737 }
1738 /*----------------------------------------------------------------------------*/
1739 static int bma222_resume(struct i2c_client *client)
1740 {
1741 struct bma222_i2c_data *obj = i2c_get_clientdata(client);
1742 int err;
1743
1744 if(obj == NULL)
1745 {
1746 GSE_ERR("null pointer!!\n");
1747 return -EINVAL;
1748 }
1749
1750 #ifndef CUSTOM_KERNEL_SENSORHUB
1751 BMA222_power(obj->hw, 1);
1752 #endif
1753
1754 #ifndef CUSTOM_KERNEL_SENSORHUB
1755 if(0 != (err = bma222_init_client(client, 0)))
1756 #else
1757 if(0 != (err = BMA222_SCP_SetPowerMode(enable_status, ID_ACCELEROMETER)))
1758 #endif
1759 {
1760 GSE_ERR("initialize client fail!!\n");
1761
1762 return err;
1763 }
1764 atomic_set(&obj->suspend, 0);
1765
1766
1767 return 0;
1768 }
1769 /*----------------------------------------------------------------------------*/
1770 #else /*CONFIG_HAS_EARLY_SUSPEND is defined*/
1771 /*----------------------------------------------------------------------------*/
1772 static void bma222_early_suspend(struct early_suspend *h)
1773 {
1774 struct bma222_i2c_data *obj = container_of(h, struct bma222_i2c_data, early_drv);
1775 int err;
1776
1777 if(obj == NULL)
1778 {
1779 GSE_ERR("null pointer!!\n");
1780 return;
1781 }
1782 atomic_set(&obj->suspend, 1);
1783
1784 GSE_FUN();
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))
1787 {
1788 GSE_ERR("read power ctl register err!\n");
1789 return BMA222_ERR_I2C;
1790 }
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)))
1795 #else
1796 if((err = BMA222_SCP_SetPowerMode(false, ID_ACCELEROMETER)))
1797 #endif
1798 {
1799 GSE_ERR("write power control fail!!\n");
1800
1801 return;
1802 }
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
1804 {
1805 GSE_ERR("read power ctl register err!\n");
1806
1807 return BMA222_ERR_I2C;
1808 }
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]);
1811 sensor_suspend = 1;
1812
1813 #ifndef CUSTOM_KERNEL_SENSORHUB
1814 BMA222_power(obj->hw, 0);
1815 #endif
1816
1817 }
1818 /*----------------------------------------------------------------------------*/
1819 static void bma222_late_resume(struct early_suspend *h)
1820 {
1821 struct bma222_i2c_data *obj = container_of(h, struct bma222_i2c_data, early_drv);
1822 int err;
1823
1824 if(obj == NULL)
1825 {
1826 GSE_ERR("null pointer!!\n");
1827 return;
1828 }
1829
1830 #ifndef CUSTOM_KERNEL_SENSORHUB
1831 BMA222_power(obj->hw, 1);
1832
1833 #endif
1834
1835
1836
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))
1839 {
1840 GSE_ERR("read power ctl register err!\n");
1841
1842 return BMA222_ERR_I2C;
1843
1844 }
1845 if(databuf[0]==0xff)//if the value is ff the gsensor will not work anymore, any i2c operations won't be vaild
1846
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)))
1850 #else
1851 if((err = BMA222_SCP_SetPowerMode(enable_status, ID_ACCELEROMETER)))
1852 #endif
1853 {
1854 GSE_ERR("initialize client fail!!\n");
1855
1856 return;
1857 }
1858
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
1860 {
1861 GSE_ERR("read power ctl register err!\n");
1862
1863 return BMA222_ERR_I2C;
1864 }
1865
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]);
1868 sensor_suspend = 0;
1869
1870 atomic_set(&obj->suspend, 0);
1871 }
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)
1877 {
1878 //should queuq work to report event if is_report_input_direct=true
1879 return 0;
1880 }
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)
1884 {
1885 int err = 0;
1886
1887
1888
1889 if(((en == 0) && (sensor_power == false)) ||((en == 1) && (sensor_power == true)))
1890 {
1891 enable_status = sensor_power;
1892 GSE_LOG("Gsensor device have updated!\n");
1893 }
1894 else
1895 {
1896 enable_status = !sensor_power;
1897 if (atomic_read(&obj_i2c_data->suspend) == 0)
1898 {
1899 #ifdef CUSTOM_KERNEL_SENSORHUB
1900 err = BMA222_SCP_SetPowerMode(enable_status, ID_ACCELEROMETER);
1901 if (0 == err)
1902 {
1903 sensor_power = enable_status;
1904 }
1905 #else
1906 err = BMA222_SetPowerMode(obj_i2c_data->client, enable_status);
1907 #endif
1908 GSE_LOG("Gsensor not in suspend BMA222_SetPowerMode!, enable_status = %d\n",enable_status);
1909 }
1910 else
1911 {
1912 GSE_LOG("Gsensor in suspend and can not enable or disable!enable_status = %d\n",enable_status);
1913 }
1914 }
1915
1916
1917 if(err != BMA222_SUCCESS)
1918 {
1919 GSE_ERR("gsensor_enable_nodata fail!\n");
1920 return -1;
1921 }
1922
1923 GSE_ERR("gsensor_enable_nodata OK!\n");
1924 return 0;
1925 }
1926 /*----------------------------------------------------------------------------*/
1927 static int gsensor_set_delay(u64 ns)
1928 {
1929 int err = 0;
1930 int value;
1931 #ifdef CUSTOM_KERNEL_SENSORHUB
1932 SCP_SENSOR_HUB_DATA req;
1933 int len;
1934 #else//#ifdef CUSTOM_KERNEL_SENSORHUB
1935 int sample_delay;
1936 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
1937
1938 value = (int)ns/1000/1000;
1939
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);
1946 if (err)
1947 {
1948 GSE_ERR("SCP_sensorHub_req_send!\n");
1949 return err;
1950 }
1951 #else//#ifdef CUSTOM_KERNEL_SENSORHUB
1952 if(value <= 5)
1953 {
1954 sample_delay = BMA222_BW_200HZ;
1955 }
1956 else if(value <= 10)
1957 {
1958 sample_delay = BMA222_BW_100HZ;
1959 }
1960 else
1961 {
1962 sample_delay = BMA222_BW_100HZ;
1963 }
1964
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
1969 {
1970 GSE_ERR("Set delay parameter error!\n");
1971 return -1;
1972 }
1973
1974 if(value >= 50)
1975 {
1976 atomic_set(&obj_i2c_data->filter, 0);
1977 }
1978 else
1979 {
1980 #if defined(CONFIG_BMA222_LOWPASS)
1981 priv->fir.num = 0;
1982 priv->fir.idx = 0;
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);
1987 #endif
1988 }
1989 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
1990
1991 GSE_LOG("gsensor_set_delay (%d)\n",value);
1992
1993 return 0;
1994 }
1995 /*----------------------------------------------------------------------------*/
1996 /*----------------------------------------------------------------------------*/
1997 static int gsensor_get_data(int* x ,int* y,int* z, int* status)
1998 {
1999 #ifdef CUSTOM_KERNEL_SENSORHUB
2000 SCP_SENSOR_HUB_DATA req;
2001 int len;
2002 int err = 0;
2003 #else
2004 char buff[BMA222_BUFSIZE];
2005 #endif
2006
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);
2012 if (err)
2013 {
2014 GSE_ERR("SCP_sensorHub_req_send!\n");
2015 return err;
2016 }
2017
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)
2021 {
2022 GSE_ERR("error : %d\n", req.get_data_rsp.errCode);
2023 return req.get_data_rsp.errCode;
2024 }
2025
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);
2030
2031 *status = SENSOR_STATUS_ACCURACY_MEDIUM;
2032 #else
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;
2038 #endif
2039 return 0;
2040 }
2041 /*----------------------------------------------------------------------------*/
2042 static int bma222_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
2043 {
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};
2048 int err = 0;
2049 int retry = 0;
2050 GSE_FUN();
2051
2052 if(!(obj = kzalloc(sizeof(*obj), GFP_KERNEL)))
2053 {
2054 err = -ENOMEM;
2055 goto exit;
2056 }
2057
2058 memset(obj, 0, sizeof(struct bma222_i2c_data));
2059
2060 obj->hw = get_cust_acc_hw();
2061
2062 if(0 != (err = hwmsen_get_convert(obj->hw->direction, &obj->cvt)))
2063 {
2064 GSE_ERR("invalid direction: %d\n", obj->hw->direction);
2065 goto exit;
2066 }
2067
2068 #ifdef CUSTOM_KERNEL_SENSORHUB
2069 INIT_WORK(&obj->irq_work, gsensor_irq_work);
2070 #endif//#ifdef CUSTOM_KERNEL_SENSORHUB
2071
2072 obj_i2c_data = obj;
2073 obj->client = client;
2074 #ifdef FPGA_EARLY_PORTING
2075 obj->client->timing = 100;
2076 #else
2077 obj->client->timing = 400;
2078 #endif
2079 new_client = obj->client;
2080 i2c_set_clientdata(new_client,obj);
2081
2082 atomic_set(&obj->trace, 0);
2083 atomic_set(&obj->suspend, 0);
2084
2085 #ifdef CONFIG_BMA222_LOWPASS
2086 if(obj->hw->firlen > C_MAX_FIR_LENGTH)
2087 {
2088 atomic_set(&obj->firlen, C_MAX_FIR_LENGTH);
2089 }
2090 else
2091 {
2092 atomic_set(&obj->firlen, obj->hw->firlen);
2093 }
2094
2095 if(atomic_read(&obj->firlen) > 0)
2096 {
2097 atomic_set(&obj->fir_en, 1);
2098 }
2099
2100 #endif
2101
2102 bma222_i2c_client = new_client;
2103
2104 for(retry = 0; retry < 3; retry++){
2105 if(0 != (err = bma222_init_client(new_client, 1)))
2106 {
2107 GSE_ERR("bma222_device init cilent fail time: %d\n", retry);
2108 continue;
2109 }
2110 }
2111 if(err != 0)
2112 goto exit_init_failed;
2113
2114
2115 if(0 != (err = misc_register(&bma222_device)))
2116 {
2117 GSE_ERR("bma222_device register failed\n");
2118 goto exit_misc_device_register_failed;
2119 }
2120
2121 if(0 != (err = bma222_create_attr(&bma222_init_info.platform_diver_addr->driver)))
2122 {
2123 GSE_ERR("create attribute err = %d\n", err);
2124 goto exit_create_attr_failed;
2125 }
2126
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;
2132
2133 #ifdef CUSTOM_KERNEL_SENSORHUB
2134 ctl.is_support_batch = obj->hw->is_batch_supported;
2135 #else
2136 ctl.is_support_batch = false;
2137 #endif
2138
2139 err = acc_register_control_path(&ctl);
2140 if(err)
2141 {
2142 GSE_ERR("register acc control path err\n");
2143 goto exit_kfree;
2144 }
2145
2146 data.get_data = gsensor_get_data;
2147 data.vender_div = 1000;
2148 err = acc_register_data_path(&data);
2149 if(err)
2150 {
2151 GSE_ERR("register acc data path err\n");
2152 goto exit_kfree;
2153 }
2154
2155 err = batch_register_support_info(ID_ACCELEROMETER,ctl.is_support_batch, 1000, 0);
2156 if(err)
2157 {
2158 GSE_ERR("register gsensor batch support err = %d\n", err);
2159 goto exit_create_attr_failed;
2160 }
2161
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);
2167 #endif
2168
2169 gsensor_init_flag =0;
2170 GSE_LOG("%s: OK\n", __func__);
2171 return 0;
2172
2173 exit_create_attr_failed:
2174 misc_deregister(&bma222_device);
2175 exit_misc_device_register_failed:
2176 exit_init_failed:
2177 //i2c_detach_client(new_client);
2178 exit_kfree:
2179 kfree(obj);
2180 exit:
2181 GSE_ERR("%s: err = %d\n", __func__, err);
2182 gsensor_init_flag = -1;
2183 return err;
2184 }
2185
2186 /*----------------------------------------------------------------------------*/
2187 static int bma222_i2c_remove(struct i2c_client *client)
2188 {
2189 int err = 0;
2190
2191 if(0 != (err = bma222_delete_attr(&bma222_init_info.platform_diver_addr->driver)))
2192 {
2193 GSE_ERR("bma150_delete_attr fail: %d\n", err);
2194 }
2195
2196 if(0 != (err = misc_deregister(&bma222_device)))
2197 {
2198 GSE_ERR("misc_deregister fail: %d\n", err);
2199 }
2200
2201 bma222_i2c_client = NULL;
2202 i2c_unregister_device(client);
2203 kfree(i2c_get_clientdata(client));
2204 return 0;
2205 }
2206 /*----------------------------------------------------------------------------*/
2207 static int gsensor_local_init(void)
2208 {
2209 struct acc_hw *hw = get_cust_acc_hw();
2210
2211 GSE_FUN();
2212
2213 BMA222_power(hw, 1);
2214 if(i2c_add_driver(&bma222_i2c_driver))
2215 {
2216 GSE_ERR("add driver error\n");
2217 return -1;
2218 }
2219 if(-1 == gsensor_init_flag)
2220 {
2221 return -1;
2222 }
2223 //printk("fwq loccal init---\n");
2224 return 0;
2225 }
2226 /*----------------------------------------------------------------------------*/
2227 static int gsensor_remove()
2228 {
2229 struct acc_hw *hw = get_cust_acc_hw();
2230
2231 GSE_FUN();
2232 BMA222_power(hw, 0);
2233 i2c_del_driver(&bma222_i2c_driver);
2234 return 0;
2235 }
2236 /*----------------------------------------------------------------------------*/
2237 static int __init bma222_init(void)
2238 {
2239 GSE_FUN();
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);
2244 return 0;
2245 }
2246 /*----------------------------------------------------------------------------*/
2247 static void __exit bma222_exit(void)
2248 {
2249 GSE_FUN();
2250 }
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");