1 /*
2 * MCube mc3230 acceleration sensor driver
3 *
4 * Copyright (C) 2011 MCube Inc.,
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17 #include <linux/interrupt.h>
18 #include <linux/i2c.h>
19 #include <linux/slab.h>
20 #include <linux/irq.h>
21 #include <linux/miscdevice.h>
22 #include <linux/gpio.h>
23 #include <linux/uaccess.h>
24 #include <linux/atomic.h>
25 #include <linux/delay.h>
26 #include <linux/input.h>
27 #include <linux/workqueue.h>
28 #include <linux/freezer.h>
29 #include <linux/of_gpio.h>
30 #ifdef CONFIG_HAS_EARLYSUSPEND
31 #include <linux/earlysuspend.h>
32 #endif
33
34 #include <linux/sensor-dev.h>
35 #include <linux/mc3230.h>
36 #include <linux/wakelock.h>
37
38 #define MITECH_SENSOR_DBG
39
40 static int sensor_active(struct i2c_client *client, int enable, int rate);
41 #define MC32X0_XOUT_REG 0x00
42 #define MC32X0_YOUT_REG 0x01
43 #define MC32X0_ZOUT_REG 0x02
44 #define MC32X0_Tilt_Status_REG 0x03
45 #define MC32X0_Sampling_Rate_Status_REG 0x04
46 #define MC32X0_Sleep_Count_REG 0x05
47 #define MC32X0_Interrupt_Enable_REG 0x06
48 #define MC32X0_Mode_Feature_REG 0x07
49 #define MC32X0_Sample_Rate_REG 0x08
50 #define MC32X0_Tap_Detection_Enable_REG 0x09
51 #define MC32X0_TAP_Dwell_Reject_REG 0x0a
52 #define MC32X0_DROP_Control_Register_REG 0x0b
53 #define MC32X0_SHAKE_Debounce_REG 0x0c
54 #define MC32X0_XOUT_EX_L_REG 0x0d
55 #define MC32X0_XOUT_EX_H_REG 0x0e
56 #define MC32X0_YOUT_EX_L_REG 0x0f
57 #define MC32X0_YOUT_EX_H_REG 0x10
58 #define MC32X0_ZOUT_EX_L_REG 0x11
59 #define MC32X0_ZOUT_EX_H_REG 0x12
60 #define MC32X0_CHIP_ID_REG 0x18
61 #define MC32X0_RANGE_Control_REG 0x20
62 #define MC32X0_SHAKE_Threshold_REG 0x2B
63 #define MC32X0_UD_Z_TH_REG 0x2C
64 #define MC32X0_UD_X_TH_REG 0x2D
65 #define MC32X0_RL_Z_TH_REG 0x2E
66 #define MC32X0_RL_Y_TH_REG 0x2F
67 #define MC32X0_FB_Z_TH_REG 0x30
68 #define MC32X0_DROP_Threshold_REG 0x31
69 #define MC32X0_TAP_Threshold_REG 0x32
70 #define MC32X0_MODE_SLEEP 0x00
71 #define MC32X0_MODE_WAKEUP 0x01
72 #define MODE_CHANGE_DELAY_MS 100
73 #define MC3230_MODE_MITECH 0X58
74
75 #define MC3230_MODE_BITS 0x03
76
77 #define MC3230_PRECISION 8
78 #define MC3230_RANGE 1500000
79 #define MC3210_RANGE 8000000
80 #define MC3230_BOUNDARY (0x1 << (MC3230_PRECISION - 1))
81 #define MC3230_GRAVITY_STEPS (MC3230_RANGE/MC3230_BOUNDARY)
82
83 #define MC3236_RANGE 2000000
84 #define MC3236_GRAVITY_STEP (MC3236_RANGE/MC3230_BOUNDARY)
85
86 /* 8bit data */
87 #define MC3210_PRECISION 14
88 #define MC3210_BOUNDARY (0x1 << (MC3210_PRECISION - 1))
89 /* 110 2g full scale range */
90 #define MC3210_GRAVITY_STEP (MC3210_RANGE/MC3210_BOUNDARY)
91
92 /* rate */
93 #define MC3230_RATE_1 0x07
94 #define MC3230_RATE_2 0x06
95 #define MC3230_RATE_4 0x05
96 #define MC3230_RATE_8 0x04
97 #define MC3230_RATE_16 0x03
98 #define MC3230_RATE_32 0x02
99 #define MC3230_RATE_64 0x01
100 #define MC3230_RATE_120 0x00
101
102 #define MC32X0_AXIS_X 0
103 #define MC32X0_AXIS_Y 1
104 #define MC32X0_AXIS_Z 2
105 #define MC32X0_AXES_NUM 3
106 #define MC32X0_DATA_LEN 6
107 #define MC32X0_DEV_NAME "MC32X0"
108 #define GRAVITY_EARTH_1000 9807
109 #define IS_MC3230 1
110 #define IS_MC3210 2
111 #define IS_MC2234 3
112 #define IS_MC3236 4
113 #define IS_MC3413 5
114 #define IS_MC3416 6
115
116 static const char backup_calib_path[] = "/data/misc/mcube-calib.txt";
117 static const char calib_path[] =
118 "/data/data/com.mcube.acc/files/mcube-calib.txt";
119 static char backup_buf[64];
120
121 static GSENSOR_VECTOR3D gsensor_gain;
122
123 static struct file *fd_file;
124 static int load_cali_flg;
125 static bool READ_FROM_BACKUP;
126 static mm_segment_t oldfs;
127 static unsigned char offset_buf[9];
128 static signed int offset_data[3];
129 static s16 G_RAW_DATA[3];
130 static signed int gain_data[3];
131 static signed int enable_RBM_calibration;
132 static unsigned char mc32x0_type;
133 static int g_value;
134
135 #define mcprintkreg(x...)
136 #define mcprintkfunc(x...)
137
138 #define GSE_TAG "[Gsensor] "
139 #define GSE_FUN(f) pr_info(GSE_TAG"%s\n", __func__)
140 #define GSE_ERR(fmt, args...) pr_info(GSE_TAG"%s %d : "fmt, \
141 __func__, __LINE__, ##args)
142 #define GSE_LOG(fmt, args...) pr_info(GSE_TAG fmt, ##args)
143
144 #define MC3230_SPEED (200 * 1000)
145 #define MC3230_DEVID 0x01
146
147 /* Addresses to scan -- protected by sense_data_mutex */
148 static struct i2c_client *this_client;
149
150 #ifdef CONFIG_HAS_EARLYSUSPEND
151 static struct early_suspend mc3230_early_suspend;
152 #endif
153
154 /* status */
155 #define MC3230_OPEN 1
156 #define MC3230_CLOSE 0
157
158 struct hwmsen_convert {
159 s8 sign[3];
160 u8 map[3];
161 };
162
163 struct mc3230_data {
164 struct sensor_private_data *g_sensor_private_data;
165
166 char status;
167 char curr_rate;
168
169 /* +1: for 4-byte alignment */
170 s16 offset[MC32X0_AXES_NUM + 1];
171 s16 data[MC32X0_AXES_NUM + 1];
172 s16 cali_sw[MC32X0_AXES_NUM + 1];
173
174 struct hwmsen_convert cvt;
175 };
176
177 static int MC32X0_WriteCalibration(struct i2c_client *client,
178 int dat[MC32X0_AXES_NUM]);
179
180 static int mc3230_write_reg(struct i2c_client *client, int addr, int value);
181 static int mc3230_read_block(struct i2c_client *client, char reg, char *rxData,
182 int length);
183 static int mc3230_active(struct i2c_client *client, int enable);
184 static void MC32X0_rbm(struct i2c_client *client, int enable);
185 static int init_3230_ctl_data(struct i2c_client *client);
186
openFile(const char * path,int flag,int mode)187 struct file *openFile(const char *path, int flag, int mode)
188 {
189 struct file *fp;
190
191 fp = filp_open(path, flag, mode);
192 if (IS_ERR(fp) || !fp->f_op)
193 return NULL;
194 else
195 return fp;
196 }
197
readFile(struct file * fp,char * buf,int readlen)198 static int readFile(struct file *fp, char *buf, int readlen)
199 {
200 if (fp->f_op && fp->f_op->read)
201 return fp->f_op->read(fp, buf, readlen, &fp->f_pos);
202 else
203 return -1;
204 }
205
writeFile(struct file * fp,char * buf,int writelen)206 static int writeFile(struct file *fp, char *buf, int writelen)
207 {
208 if (fp->f_op && fp->f_op->write)
209 return fp->f_op->write(fp, buf, writelen, &fp->f_pos);
210 else
211 return -1;
212 }
213
closeFile(struct file * fp)214 static int closeFile(struct file *fp)
215 {
216 filp_close(fp, NULL);
217 return 0;
218 }
219
initKernelEnv(void)220 static void initKernelEnv(void)
221 {
222 oldfs = get_fs();
223 set_fs(KERNEL_DS);
224 }
225
226 static struct mc3230_data g_mc3230_data = { 0 };
get_3230_ctl_data(void)227 static struct mc3230_data *get_3230_ctl_data(void)
228 {
229 return &g_mc3230_data;
230 }
231
mcube_read_cali_file(struct i2c_client * client)232 static int mcube_read_cali_file(struct i2c_client *client)
233 {
234 int cali_data[3];
235 int err = 0;
236
237 READ_FROM_BACKUP = false;
238 initKernelEnv();
239
240 fd_file =
241 openFile("/data/data/com.mcube.acc/files/mcube-calib.txt", 0, 0);
242
243 if (!fd_file) {
244 fd_file = openFile(backup_calib_path, O_RDONLY, 0);
245 if (fd_file)
246 READ_FROM_BACKUP = true;
247 }
248
249 if (!fd_file) {
250 cali_data[0] = 0;
251 cali_data[1] = 0;
252 cali_data[2] = 0;
253 return 1;
254 } else {
255 memset(backup_buf, 0, 64);
256 err = readFile(fd_file, backup_buf, 128);
257 if (err > 0)
258 GSE_LOG("buf:%s\n", backup_buf);
259 else
260 GSE_LOG("read file error %d\n", err);
261
262 set_fs(oldfs);
263 closeFile(fd_file);
264
265 sscanf(backup_buf, "%d %d %d", &cali_data[MC32X0_AXIS_X],
266 &cali_data[MC32X0_AXIS_Y], &cali_data[MC32X0_AXIS_Z]);
267 GSE_LOG("cali_data: %d %d %d\n", cali_data[MC32X0_AXIS_X],
268 cali_data[MC32X0_AXIS_Y], cali_data[MC32X0_AXIS_Z]);
269
270 MC32X0_WriteCalibration(client, cali_data);
271 }
272 return 0;
273 }
274
MC32X0_rbm(struct i2c_client * client,int enable)275 static void MC32X0_rbm(struct i2c_client *client, int enable)
276 {
277 int err;
278
279 if (enable == 1) {
280 err = mc3230_write_reg(client, 0x07, 0x43);
281 err = mc3230_write_reg(client, 0x14, 0x02);
282 err = mc3230_write_reg(client, 0x07, 0x41);
283
284 enable_RBM_calibration = 1;
285
286 GSE_LOG("set rbm!!\n");
287
288 msleep(220);
289 } else if (enable == 0) {
290 err = mc3230_write_reg(client, 0x07, 0x43);
291 err = mc3230_write_reg(client, 0x14, 0x00);
292 err = mc3230_write_reg(client, 0x07, 0x41);
293 enable_RBM_calibration = 0;
294
295 GSE_LOG("clear rbm!!\n");
296
297 msleep(220);
298 }
299 }
300
MC32X0_ReadData_RBM(struct i2c_client * client,int data[MC32X0_AXES_NUM])301 static int MC32X0_ReadData_RBM(struct i2c_client *client,
302 int data[MC32X0_AXES_NUM])
303 {
304 u8 addr = 0x0d;
305 u8 rbm_buf[MC32X0_DATA_LEN] = { 0 };
306 int err = 0;
307
308 if (!client) {
309 err = -EINVAL;
310 return err;
311 }
312
313 err = mc3230_read_block(client, addr, rbm_buf, 0x06);
314
315 data[MC32X0_AXIS_X] = (s16)((rbm_buf[0]) | (rbm_buf[1] << 8));
316 data[MC32X0_AXIS_Y] = (s16)((rbm_buf[2]) | (rbm_buf[3] << 8));
317 data[MC32X0_AXIS_Z] = (s16)((rbm_buf[4]) | (rbm_buf[5] << 8));
318
319 GSE_LOG("rbm_buf<<<<<[%02x %02x %02x %02x %02x %02x]\n", rbm_buf[0],
320 rbm_buf[2], rbm_buf[2], rbm_buf[3], rbm_buf[4], rbm_buf[5]);
321 GSE_LOG("RBM<<<<<[%04x %04x %04x]\n", data[MC32X0_AXIS_X],
322 data[MC32X0_AXIS_Y], data[MC32X0_AXIS_Z]);
323 GSE_LOG("RBM<<<<<[%04d %04d %04d]\n", data[MC32X0_AXIS_X],
324 data[MC32X0_AXIS_Y], data[MC32X0_AXIS_Z]);
325 return err;
326 }
327
mc3230_read_block(struct i2c_client * client,char reg,char * rxData,int length)328 static int mc3230_read_block(struct i2c_client *client, char reg, char *rxData,
329 int length)
330 {
331 int ret = 0;
332
333 *rxData = reg;
334 ret = sensor_rx_data(client, rxData, length);
335 return ret;
336 }
337
mc3230_write_reg(struct i2c_client * client,int addr,int value)338 static int mc3230_write_reg(struct i2c_client *client, int addr, int value)
339 {
340 char buffer[3];
341 int ret = 0;
342
343 buffer[0] = addr;
344 buffer[1] = value;
345 ret = sensor_tx_data(client, &buffer[0], 2);
346 return ret;
347 }
348
mc3230_active(struct i2c_client * client,int enable)349 static int mc3230_active(struct i2c_client *client, int enable)
350 {
351 int tmp;
352 int ret = 0;
353
354 if (enable)
355 tmp = 0x01;
356 else
357 tmp = 0x03;
358 mcprintkreg("mc3230_active %s (0x%x)\n", enable ? "active" : "standby",
359 tmp);
360 ret = mc3230_write_reg(client, MC3230_REG_SYSMOD, tmp);
361 return ret;
362 }
363
mc3230_reg_init(struct i2c_client * client)364 static int mc3230_reg_init(struct i2c_client *client)
365 {
366 int ret = 0;
367 int pcode = 0;
368
369 /* 1: awake 0: standby */
370 mc3230_active(client, 0);
371
372 pcode = sensor_read_reg(client, MC3230_REG_PRODUCT_CODE);
373 printk(KERN_INFO "mc3230_reg_init pcode=%x\n", pcode);
374 if ((pcode == 0x19) || (pcode == 0x29)) {
375 mc32x0_type = IS_MC3230;
376 } else if ((pcode == 0x90) || (pcode == 0xA8) || (pcode == 0x88)) {
377 mc32x0_type = IS_MC3210;
378 } else if (pcode == 0x59) {
379 mc32x0_type = IS_MC2234;
380 }
381
382 if ((pcode & 0xF1) == 0x60) {
383 mc32x0_type = IS_MC3236;
384 } else if ((pcode & 0xF1) == 0x10) {
385 mc32x0_type = IS_MC3413;
386 } else if ((pcode & 0xF1) == 0x20) {
387 mc32x0_type = IS_MC3416;
388 }
389
390 GSE_LOG("MC3230 1, MC3210 2, MC2234 3, MC3236 4, MC3416 5, MC3416 6:mc32x0_type=%d\n", mc32x0_type);
391
392 if ((mc32x0_type == IS_MC3230) || (mc32x0_type == IS_MC2234)) {
393 ret = sensor_write_reg(client, 0x20, 0x32);
394 } else if (mc32x0_type == IS_MC3236) {
395 ret = sensor_write_reg(client, 0x20, 0x02);
396 } else if (mc32x0_type == IS_MC3210) {
397 ret = sensor_write_reg(client, 0x20, 0x3F);
398 } else if (mc32x0_type == IS_MC3413) {
399 ret = sensor_write_reg(client, 0x20, 0x25);
400 } else if (mc32x0_type == IS_MC3416) {
401 ret = sensor_write_reg(client, 0x08, 0x05);
402 ret = sensor_write_reg(client, 0x20, 0x29);
403 }
404
405 if ((mc32x0_type == IS_MC3230) || (mc32x0_type == IS_MC2234)) {
406 gsensor_gain.x = gsensor_gain.y = gsensor_gain.z = 86;
407 } else if (mc32x0_type == IS_MC3236) {
408 gsensor_gain.x = gsensor_gain.y = gsensor_gain.z = 64;
409 } else if ((mc32x0_type == IS_MC3210) || (mc32x0_type == IS_MC3413)) {
410 gsensor_gain.x = gsensor_gain.y = gsensor_gain.z = 1024;
411 } else if (mc32x0_type == IS_MC3416) {
412 gsensor_gain.x = gsensor_gain.y = gsensor_gain.z = 4096;
413 }
414
415 return ret;
416 }
init_3230_ctl_data(struct i2c_client * client)417 static int init_3230_ctl_data(struct i2c_client *client)
418 {
419 int err;
420 s16 tmp, x_gain, y_gain, z_gain;
421 s32 x_off, y_off, z_off;
422 struct mc3230_data *mc3230 = get_3230_ctl_data();
423
424 load_cali_flg = 30;
425
426 mcprintkfunc("%s enter\n", __func__);
427
428 this_client = client;
429
430 mc3230->g_sensor_private_data =
431 (struct sensor_private_data *)i2c_get_clientdata(client);
432 mc3230->curr_rate = MC3230_RATE_16;
433 mc3230->status = MC3230_CLOSE;
434 mc3230->cvt.sign[MC32X0_AXIS_X] = 1;
435 mc3230->cvt.sign[MC32X0_AXIS_Y] = 1;
436 mc3230->cvt.sign[MC32X0_AXIS_Z] = 1;
437 mc3230->cvt.map[MC32X0_AXIS_X] = 0;
438 mc3230->cvt.map[MC32X0_AXIS_Y] = 1;
439 mc3230->cvt.map[MC32X0_AXIS_Z] = 2;
440
441 sensor_write_reg(client, 0x1b, 0x6d);
442 sensor_write_reg(client, 0x1b, 0x43);
443 msleep(5);
444
445 sensor_write_reg(client, 0x07, 0x43);
446 sensor_write_reg(client, 0x1C, 0x80);
447 sensor_write_reg(client, 0x17, 0x80);
448 msleep(5);
449 sensor_write_reg(client, 0x1C, 0x00);
450 sensor_write_reg(client, 0x17, 0x00);
451 msleep(5);
452
453 memset(offset_buf, 0, 9);
454 offset_buf[0] = 0x21;
455 err = sensor_rx_data(client, offset_buf, 9);
456 if (err) {
457 GSE_ERR("error: %d\n", err);
458 return err;
459 }
460
461 tmp = ((offset_buf[1] & 0x3f) << 8) + offset_buf[0];
462 if (tmp & 0x2000)
463 tmp |= 0xc000;
464 x_off = tmp;
465
466 tmp = ((offset_buf[3] & 0x3f) << 8) + offset_buf[2];
467 if (tmp & 0x2000)
468 tmp |= 0xc000;
469 y_off = tmp;
470
471 tmp = ((offset_buf[5] & 0x3f) << 8) + offset_buf[4];
472 if (tmp & 0x2000)
473 tmp |= 0xc000;
474 z_off = tmp;
475
476 /* get x,y,z gain */
477 x_gain = ((offset_buf[1] >> 7) << 8) + offset_buf[6];
478 y_gain = ((offset_buf[3] >> 7) << 8) + offset_buf[7];
479 z_gain = ((offset_buf[5] >> 7) << 8) + offset_buf[8];
480
481 /* storege the cerrunt offset data with DOT format */
482 offset_data[0] = x_off;
483 offset_data[1] = y_off;
484 offset_data[2] = z_off;
485
486 /* storege the cerrunt Gain data with GOT format */
487 gain_data[0] = 256 * 8 * 128 / 3 / (40 + x_gain);
488 gain_data[1] = 256 * 8 * 128 / 3 / (40 + y_gain);
489 gain_data[2] = 256 * 8 * 128 / 3 / (40 + z_gain);
490
491 mc3230_reg_init(this_client);
492
493 return 0;
494 }
495
mc3230_start_dev(struct i2c_client * client,char rate)496 static int mc3230_start_dev(struct i2c_client *client, char rate)
497 {
498 int ret = 0;
499 struct mc3230_data *mc3230 = get_3230_ctl_data();
500
501 /* standby */
502 mc3230_active(client, 0);
503 mcprintkreg("mc3230 MC3230_REG_SYSMOD:%x\n",
504 mc3230_read_reg(client, MC3230_REG_SYSMOD));
505
506 /*data rate */
507 ret = mc3230_write_reg(client, MC3230_REG_RATE_SAMP, rate);
508 mc3230->curr_rate = rate;
509 mcprintkreg("mc3230 MC3230_REG_RATE_SAMP:%x rate=%d\n",
510 mc3230_read_reg(client, MC3230_REG_RATE_SAMP), rate);
511 /*wake */
512 mc3230_active(client, 1);
513 mcprintkreg("mc3230 MC3230_REG_SYSMOD:%x\n",
514 mc3230_read_reg(client, MC3230_REG_SYSMOD));
515
516 return ret;
517 }
518
mc3230_start(struct i2c_client * client,char rate)519 static int mc3230_start(struct i2c_client *client, char rate)
520 {
521 struct mc3230_data *mc3230 = get_3230_ctl_data();
522
523 if (mc3230->status == MC3230_OPEN)
524 return 0;
525
526 mc3230->status = MC3230_OPEN;
527 rate = 0;
528 return mc3230_start_dev(client, rate);
529 }
530
mc3230_convert_to_int(s16 value)531 static inline int mc3230_convert_to_int(s16 value)
532 {
533 int result = 0;
534
535 if ((mc32x0_type == IS_MC3230) || (mc32x0_type == IS_MC2234)) {
536 result = value * 192;
537 } else if (mc32x0_type == IS_MC3236) {
538 result = value * 256;
539 } else if ((mc32x0_type == IS_MC3210) || (mc32x0_type == IS_MC3413)) {
540 result = value * 16;
541 } else if (mc32x0_type == IS_MC3416) {
542 result = value * 4;
543 }
544
545 return result;
546 }
547
mc3230_report_value(struct i2c_client * client,struct sensor_axis * axis)548 static void mc3230_report_value(struct i2c_client *client,
549 struct sensor_axis *axis)
550 {
551 struct sensor_private_data *mc3230 = i2c_get_clientdata(client);
552
553 if (mc3230->status_cur == SENSOR_OFF)
554 return;
555
556 if (mc32x0_type == IS_MC2234) {
557 input_report_abs(mc3230->input_dev, ABS_X, (axis->x));
558 input_report_abs(mc3230->input_dev, ABS_Y, -(axis->y));
559 input_report_abs(mc3230->input_dev, ABS_Z, (axis->z));
560 } else if (mc32x0_type == IS_MC3236) {
561 input_report_abs(mc3230->input_dev, ABS_X, -(axis->x));
562 input_report_abs(mc3230->input_dev, ABS_Y, (axis->y));
563 input_report_abs(mc3230->input_dev, ABS_Z, -(axis->z));
564 } else if (mc32x0_type == IS_MC3416) {
565 input_report_abs(mc3230->input_dev, ABS_X, (axis->x));
566 input_report_abs(mc3230->input_dev, ABS_Y, -(axis->y));
567 input_report_abs(mc3230->input_dev, ABS_Z, -(axis->z));
568 } else {
569 input_report_abs(mc3230->input_dev, ABS_X, (axis->y));
570 input_report_abs(mc3230->input_dev, ABS_Y, (axis->x));
571 input_report_abs(mc3230->input_dev, ABS_Z, (axis->z));
572 }
573
574 input_sync(mc3230->input_dev);
575 }
576
577 static int MC32X0_ReadData(struct i2c_client *client,
578 s16 buffer[MC32X0_AXES_NUM]);
579
mc3230_get_data(struct i2c_client * client)580 static int mc3230_get_data(struct i2c_client *client)
581 {
582 struct sensor_private_data *sensor =
583 (struct sensor_private_data *)i2c_get_clientdata(client);
584 struct sensor_platform_data *pdata = sensor->pdata;
585 s16 buffer[6];
586 int ret;
587 int x, y, z;
588 int value = 0;
589 static int flag;
590 struct sensor_axis axis;
591
592 if (load_cali_flg > 0) {
593 ret = mcube_read_cali_file(client);
594 if (ret == 0)
595 load_cali_flg = ret;
596 else
597 load_cali_flg--;
598 }
599 ret = MC32X0_ReadData(client, buffer);
600 if (ret) {
601 GSE_ERR("%s I2C error: ret value=%d", __func__, ret);
602 return -EIO;
603 }
604
605 value = sensor_read_reg(client, 0x20);
606
607 if (value == 0x00) {
608 static int cnt;
609
610 if (cnt++ >= 20) {
611 sensor_active(client, 1, 0xff);
612 cnt = 0;
613 }
614 g_value = 4;
615 } else if (value == 0x01) {
616 g_value = 2;
617 } else
618 g_value = 1;
619
620 x = mc3230_convert_to_int(buffer[0]) * g_value;
621 y = mc3230_convert_to_int(buffer[1]) * g_value;
622 z = mc3230_convert_to_int(buffer[2]) * g_value;
623
624 axis.x =
625 (pdata->orientation[0]) * x + (pdata->orientation[1]) * y +
626 (pdata->orientation[2]) * z;
627 axis.y =
628 (pdata->orientation[3]) * x + (pdata->orientation[4]) * y +
629 (pdata->orientation[5]) * z;
630 axis.z =
631 (pdata->orientation[6]) * x + (pdata->orientation[7]) * y +
632 (pdata->orientation[8]) * z;
633
634 /* input dev will ignore report data if data value is the same with last_value,
635 sample rate will not enough by this way, so just avoid this case */
636 if ((sensor->axis.x == axis.x) && (sensor->axis.y == axis.y) && (sensor->axis.z == axis.z)) {
637 if (flag) {
638 flag = 0;
639 axis.x += 1;
640 axis.y += 1;
641 axis.z += 1;
642 } else {
643 flag = 1;
644 axis.x -= 1;
645 axis.y -= 1;
646 axis.z -= 1;
647 }
648 }
649
650 mc3230_report_value(client, &axis);
651
652 mutex_lock(&sensor->data_mutex);
653 sensor->axis = axis;
654 mutex_unlock(&sensor->data_mutex);
655
656 return 0;
657 }
658
MC32X0_ReadRBMData(struct i2c_client * client,char * buf)659 static int MC32X0_ReadRBMData(struct i2c_client *client, char *buf)
660 {
661 struct mc3230_data *mc3230 =
662 (struct mc3230_data *)i2c_get_clientdata(client);
663 int res = 0;
664 int data[3];
665
666 if (!buf || !client)
667 return -EINVAL;
668
669 if (mc3230->status == MC3230_CLOSE) {
670 res = mc3230_start(client, 0);
671 if (res)
672 GSE_ERR("Power on mc32x0 error %d!\n", res);
673 }
674 res = MC32X0_ReadData_RBM(client, data);
675 if (res) {
676 GSE_ERR("%s I2C error: ret value=%d", __func__, res);
677 return -EIO;
678 } else {
679 sprintf(buf, "%04x %04x %04x", data[MC32X0_AXIS_X],
680 data[MC32X0_AXIS_Y], data[MC32X0_AXIS_Z]);
681 }
682
683 return 0;
684 }
685
MC32X0_ReadOffset(struct i2c_client * client,s16 ofs[MC32X0_AXES_NUM])686 static int MC32X0_ReadOffset(struct i2c_client *client,
687 s16 ofs[MC32X0_AXES_NUM])
688 {
689 int err;
690 u8 off_data[6];
691
692 off_data[0] = MC32X0_XOUT_EX_L_REG;
693 if ((mc32x0_type == IS_MC3210) || (mc32x0_type == IS_MC3413)
694 || (mc32x0_type == IS_MC3416)) {
695 err = sensor_rx_data(client, off_data, MC32X0_DATA_LEN);
696 if (err) {
697 GSE_ERR("error: %d\n", err);
698 return err;
699 }
700 ofs[MC32X0_AXIS_X] =
701 ((s16)(off_data[0])) | ((s16)(off_data[1]) << 8);
702 ofs[MC32X0_AXIS_Y] =
703 ((s16)(off_data[2])) | ((s16)(off_data[3]) << 8);
704 ofs[MC32X0_AXIS_Z] =
705 ((s16)(off_data[4])) | ((s16)(off_data[5]) << 8);
706 } else if ((mc32x0_type == IS_MC3230) || (mc32x0_type == IS_MC2234)) {
707 err = sensor_rx_data(client, off_data, MC32X0_DATA_LEN);
708 if (err) {
709 GSE_ERR("error: %d\n", err);
710 return err;
711 }
712 ofs[MC32X0_AXIS_X] = (s8)off_data[0];
713 ofs[MC32X0_AXIS_Y] = (s8)off_data[1];
714 ofs[MC32X0_AXIS_Z] = (s8)off_data[2];
715 }
716 GSE_LOG("MC32X0_ReadOffset %d %d %d \n", ofs[MC32X0_AXIS_X],
717 ofs[MC32X0_AXIS_Y], ofs[MC32X0_AXIS_Z]);
718
719 return 0;
720 }
721
MC32X0_ResetCalibration(struct i2c_client * client)722 static int MC32X0_ResetCalibration(struct i2c_client *client)
723 {
724 struct mc3230_data *mc3230 = get_3230_ctl_data();
725 s16 tmp, i;
726
727 sensor_write_reg(client, 0x07, 0x43);
728
729 for (i = 0; i < 6; i++) {
730 sensor_write_reg(client, 0x21 + i, offset_buf[i]);
731 msleep(10);
732 }
733
734 sensor_write_reg(client, 0x07, 0x41);
735
736 msleep(20);
737
738 /* add by Liang for set offset_buf as OTP value */
739 tmp = ((offset_buf[1] & 0x3f) << 8) + offset_buf[0];
740 if (tmp & 0x2000)
741 tmp |= 0xc000;
742 offset_data[0] = tmp;
743
744 tmp = ((offset_buf[3] & 0x3f) << 8) + offset_buf[2];
745 if (tmp & 0x2000)
746 tmp |= 0xc000;
747 offset_data[1] = tmp;
748
749 tmp = ((offset_buf[5] & 0x3f) << 8) + offset_buf[4];
750 if (tmp & 0x2000)
751 tmp |= 0xc000;
752 offset_data[2] = tmp;
753
754 memset(mc3230->cali_sw, 0x00, sizeof(mc3230->cali_sw));
755
756 return 0;
757 }
758
MC32X0_ReadCalibration(struct i2c_client * client,int dat[MC32X0_AXES_NUM])759 static int MC32X0_ReadCalibration(struct i2c_client *client,
760 int dat[MC32X0_AXES_NUM])
761 {
762 struct mc3230_data *mc3230 = get_3230_ctl_data();
763 int err;
764
765 err = MC32X0_ReadOffset(client, mc3230->offset);
766 if (err) {
767 GSE_ERR("read offset fail, %d\n", err);
768 return err;
769 }
770
771 dat[MC32X0_AXIS_X] = mc3230->offset[MC32X0_AXIS_X];
772 dat[MC32X0_AXIS_Y] = mc3230->offset[MC32X0_AXIS_Y];
773 dat[MC32X0_AXIS_Z] = mc3230->offset[MC32X0_AXIS_Z];
774
775 return 0;
776 }
777
MC32X0_WriteCalibration(struct i2c_client * client,int dat[MC32X0_AXES_NUM])778 static int MC32X0_WriteCalibration(struct i2c_client *client,
779 int dat[MC32X0_AXES_NUM])
780 {
781 int err;
782 u8 buf[9], i;
783 s16 tmp, x_gain, y_gain, z_gain;
784 s32 x_off, y_off, z_off;
785
786 GSE_LOG("UPDATE dat: (%+3d %+3d %+3d)\n",
787 dat[MC32X0_AXIS_X], dat[MC32X0_AXIS_Y], dat[MC32X0_AXIS_Z]);
788
789 /* read register 0x21~0x28 */
790 buf[0] = 0x21;
791 err = sensor_rx_data(client, &buf[0], 3);
792 buf[3] = 0x24;
793 err = sensor_rx_data(client, &buf[3], 3);
794 buf[6] = 0x27;
795 err = sensor_rx_data(client, &buf[6], 3);
796
797 /* get x,y,z offset */
798 tmp = ((buf[1] & 0x3f) << 8) + buf[0];
799 if (tmp & 0x2000)
800 tmp |= 0xc000;
801 x_off = tmp;
802
803 tmp = ((buf[3] & 0x3f) << 8) + buf[2];
804 if (tmp & 0x2000)
805 tmp |= 0xc000;
806 y_off = tmp;
807
808 tmp = ((buf[5] & 0x3f) << 8) + buf[4];
809 if (tmp & 0x2000)
810 tmp |= 0xc000;
811 z_off = tmp;
812
813 /* get x,y,z gain */
814 x_gain = ((buf[1] >> 7) << 8) + buf[6];
815 y_gain = ((buf[3] >> 7) << 8) + buf[7];
816 z_gain = ((buf[5] >> 7) << 8) + buf[8];
817
818 /* prepare new offset */
819 x_off =
820 x_off +
821 16 * dat[MC32X0_AXIS_X] * 256 * 128 / 3 / gsensor_gain.x / (40 +
822 x_gain);
823 y_off =
824 y_off +
825 16 * dat[MC32X0_AXIS_Y] * 256 * 128 / 3 / gsensor_gain.y / (40 +
826 y_gain);
827 z_off =
828 z_off +
829 16 * dat[MC32X0_AXIS_Z] * 256 * 128 / 3 / gsensor_gain.z / (40 +
830 z_gain);
831
832 /* storege the cerrunt offset data with DOT format */
833 offset_data[0] = x_off;
834 offset_data[1] = y_off;
835 offset_data[2] = z_off;
836
837 /* storege the cerrunt Gain data with GOT format */
838 gain_data[0] = 256 * 8 * 128 / 3 / (40 + x_gain);
839 gain_data[1] = 256 * 8 * 128 / 3 / (40 + y_gain);
840 gain_data[2] = 256 * 8 * 128 / 3 / (40 + z_gain);
841
842 sensor_write_reg(client, 0x07, 0x43);
843
844 buf[0] = x_off & 0xff;
845 buf[1] = ((x_off >> 8) & 0x3f) | (x_gain & 0x0100 ? 0x80 : 0);
846 buf[2] = y_off & 0xff;
847 buf[3] = ((y_off >> 8) & 0x3f) | (y_gain & 0x0100 ? 0x80 : 0);
848 buf[4] = z_off & 0xff;
849 buf[5] = ((z_off >> 8) & 0x3f) | (z_gain & 0x0100 ? 0x80 : 0);
850
851 for (i = 0; i < 6; i++) {
852 sensor_write_reg(client, 0x21 + i, buf[i]);
853 msleep(10);
854 }
855
856 sensor_write_reg(client, 0x07, 0x41);
857
858 return err;
859 }
860
MC32X0_ReadData(struct i2c_client * client,s16 buffer[MC32X0_AXES_NUM])861 static int MC32X0_ReadData(struct i2c_client *client,
862 s16 buffer[MC32X0_AXES_NUM])
863 {
864 s8 buf[3];
865 u8 buf1[6];
866 char rbm_buf[6];
867 int ret;
868 int err = 0;
869
870 int tempX = 0;
871 int tempY = 0;
872 int tempZ = 0;
873
874 if (!client) {
875 err = -EINVAL;
876 return err;
877 }
878 mcprintkfunc("MC32X0_ReadData enable_RBM_calibration = %d\n",
879 enable_RBM_calibration);
880 if (enable_RBM_calibration == 0) {
881 ;
882 } else if (enable_RBM_calibration == 1) {
883 memset(rbm_buf, 0, 3);
884 rbm_buf[0] = MC3230_REG_RBM_DATA;
885 ret = sensor_rx_data(client, &rbm_buf[0], 2);
886 rbm_buf[2] = MC3230_REG_RBM_DATA + 2;
887 ret = sensor_rx_data(client, &rbm_buf[2], 2);
888 rbm_buf[4] = MC3230_REG_RBM_DATA + 4;
889 ret = sensor_rx_data(client, &rbm_buf[4], 2);
890 }
891
892 mcprintkfunc("MC32X0_ReadData %d %d %d %d %d %d\n", rbm_buf[0],
893 rbm_buf[1], rbm_buf[2], rbm_buf[3], rbm_buf[4],
894 rbm_buf[5]);
895 if (enable_RBM_calibration == 0) {
896 do {
897 memset(buf, 0, 3);
898 buf[0] = MC3230_REG_X_OUT;
899 ret = sensor_rx_data(client, &buf[0], 3);
900 if (ret < 0)
901 return ret;
902 } while (0);
903
904 buffer[0] = (s16)buf[0];
905 buffer[1] = (s16)buf[1];
906 buffer[2] = (s16)buf[2];
907
908 if (mc32x0_type == IS_MC2234) {
909 tempX = buffer[MC32X0_AXIS_X];
910 tempY = buffer[MC32X0_AXIS_Y];
911 tempZ = buffer[MC32X0_AXIS_Z];
912
913 buffer[MC32X0_AXIS_Z] =
914 (s8)(gsensor_gain.z - (abs(tempX) + abs(tempY)));
915 }
916
917 else if ((mc32x0_type == IS_MC3210)
918 || (mc32x0_type == IS_MC3413)
919 || (mc32x0_type == IS_MC3416)) {
920 do {
921 memset(buf1, 0, 6);
922 buf[0] = MC32X0_XOUT_EX_L_REG;
923
924 buf1[0] =
925 sensor_read_reg(client,
926 MC32X0_XOUT_EX_L_REG);
927 buf1[1] =
928 sensor_read_reg(client,
929 MC32X0_XOUT_EX_L_REG + 1);
930 buf1[2] =
931 sensor_read_reg(client,
932 MC32X0_XOUT_EX_L_REG + 2);
933 buf1[3] =
934 sensor_read_reg(client,
935 MC32X0_XOUT_EX_L_REG + 3);
936 buf1[4] =
937 sensor_read_reg(client,
938 MC32X0_XOUT_EX_L_REG + 4);
939 buf1[5] =
940 sensor_read_reg(client,
941 MC32X0_XOUT_EX_L_REG + 5);
942 } while (0);
943
944 buffer[0] = (signed short)((buf1[0]) | (buf1[1] << 8));
945 buffer[1] = (signed short)((buf1[2]) | (buf1[3] << 8));
946 buffer[2] = (signed short)((buf1[4]) | (buf1[5] << 8));
947 }
948
949 } else if (enable_RBM_calibration == 1) {
950 buffer[MC32X0_AXIS_X] =
951 (s16)((rbm_buf[0]) | (rbm_buf[1] << 8));
952 buffer[MC32X0_AXIS_Y] =
953 (s16)((rbm_buf[2]) | (rbm_buf[3] << 8));
954 buffer[MC32X0_AXIS_Z] =
955 (s16)((rbm_buf[4]) | (rbm_buf[5] << 8));
956
957 mcprintkfunc("%s RBM<<<<<[%08d %08d %08d]\n", __func__,
958 buffer[MC32X0_AXIS_X], buffer[MC32X0_AXIS_Y],
959 buffer[MC32X0_AXIS_Z]);
960 if (gain_data[0] == 0) {
961 buffer[MC32X0_AXIS_X] = 0;
962 buffer[MC32X0_AXIS_Y] = 0;
963 buffer[MC32X0_AXIS_Z] = 0;
964 return 0;
965 }
966 buffer[MC32X0_AXIS_X] =
967 (buffer[MC32X0_AXIS_X] +
968 offset_data[0] / 2) * gsensor_gain.x / gain_data[0];
969 buffer[MC32X0_AXIS_Y] =
970 (buffer[MC32X0_AXIS_Y] +
971 offset_data[1] / 2) * gsensor_gain.y / gain_data[1];
972 buffer[MC32X0_AXIS_Z] =
973 (buffer[MC32X0_AXIS_Z] +
974 offset_data[2] / 2) * gsensor_gain.z / gain_data[2];
975
976 if (mc32x0_type == IS_MC2234) {
977 tempX = buffer[MC32X0_AXIS_X];
978 tempY = buffer[MC32X0_AXIS_Y];
979 tempZ = buffer[MC32X0_AXIS_Z];
980
981 buffer[MC32X0_AXIS_Z] =
982 (s16)(gsensor_gain.z - (abs(tempX) + abs(tempY)));
983 }
984 }
985
986 return 0;
987 }
988
MC32X0_ReadRawData(struct i2c_client * client,char * buf)989 static int MC32X0_ReadRawData(struct i2c_client *client, char *buf)
990 {
991 struct mc3230_data *obj = get_3230_ctl_data();
992 int res = 0;
993 s16 raw_buf[3];
994
995 if (!buf || !client)
996 return -EINVAL;
997
998 if (obj->status == MC3230_CLOSE) {
999 res = mc3230_start(client, 0);
1000 if (res)
1001 GSE_ERR("Power on mc32x0 error %d!\n", res);
1002 }
1003 res = MC32X0_ReadData(client, &raw_buf[0]);
1004 if (res) {
1005 GSE_LOG("%s %d\n", __func__, __LINE__);
1006 GSE_ERR("I2C error: ret value=%d", res);
1007 return -EIO;
1008 } else {
1009 GSE_LOG("UPDATE dat: (%+3d %+3d %+3d)\n",
1010 raw_buf[MC32X0_AXIS_X], raw_buf[MC32X0_AXIS_Y],
1011 raw_buf[MC32X0_AXIS_Z]);
1012
1013 G_RAW_DATA[MC32X0_AXIS_X] = raw_buf[0];
1014 G_RAW_DATA[MC32X0_AXIS_Y] = raw_buf[1];
1015 G_RAW_DATA[MC32X0_AXIS_Z] = raw_buf[2];
1016 G_RAW_DATA[MC32X0_AXIS_Z] =
1017 G_RAW_DATA[MC32X0_AXIS_Z] + gsensor_gain.z;
1018
1019 sprintf(buf, "%04x %04x %04x", G_RAW_DATA[MC32X0_AXIS_X],
1020 G_RAW_DATA[MC32X0_AXIS_Y], G_RAW_DATA[MC32X0_AXIS_Z]);
1021 GSE_LOG("G_RAW_DATA: (%+3d %+3d %+3d)\n",
1022 G_RAW_DATA[MC32X0_AXIS_X], G_RAW_DATA[MC32X0_AXIS_Y],
1023 G_RAW_DATA[MC32X0_AXIS_Z]);
1024 }
1025
1026 return 0;
1027 }
1028
mcube_copy_file(const char * dstfilepath)1029 static void mcube_copy_file(const char *dstfilepath)
1030 {
1031 int err = 0;
1032
1033 initKernelEnv();
1034 fd_file = openFile(dstfilepath, O_RDWR, 0);
1035 if (!fd_file) {
1036 GSE_LOG("open %s fail\n", dstfilepath);
1037 return;
1038 }
1039
1040 err = writeFile(fd_file, backup_buf, 64);
1041 if (err > 0)
1042 GSE_LOG("buf:%s\n", backup_buf);
1043 else
1044 GSE_LOG("write file error %d\n", err);
1045
1046 set_fs(oldfs);
1047 closeFile(fd_file);
1048 }
1049
mc3230_ioctl(struct file * file,unsigned int cmd,unsigned long arg,struct i2c_client * client)1050 long mc3230_ioctl(struct file *file, unsigned int cmd, unsigned long arg,
1051 struct i2c_client *client)
1052 {
1053 void __user *argp = (void __user *)arg;
1054
1055 char strbuf[256];
1056 void __user *data;
1057 SENSOR_DATA sensor_data;
1058 int err = 0;
1059 int cali[3];
1060
1061 struct mc3230_data *p_mc3230_data = get_3230_ctl_data();
1062 struct sensor_axis sense_data = { 0 };
1063
1064 mcprintkreg("mc3230_ioctl cmd is %d.", cmd);
1065
1066 switch (cmd) {
1067 case GSENSOR_IOCTL_READ_SENSORDATA:
1068 case GSENSOR_IOCTL_READ_RAW_DATA:
1069 GSE_LOG("fwq GSENSOR_IOCTL_READ_RAW_DATA\n");
1070 data = (void __user *)arg;
1071 MC32X0_ReadRawData(client, strbuf);
1072 if (copy_to_user(data, &strbuf, strlen(strbuf) + 1)) {
1073 err = -EFAULT;
1074 break;
1075 }
1076 break;
1077 case GSENSOR_IOCTL_SET_CALI:
1078
1079 GSE_LOG("fwq GSENSOR_IOCTL_SET_CALI!!\n");
1080
1081 break;
1082
1083 case GSENSOR_MCUBE_IOCTL_SET_CALI:
1084 GSE_LOG("fwq GSENSOR_MCUBE_IOCTL_SET_CALI!!\n");
1085 data = (void __user *)arg;
1086 if (!data) {
1087 err = -EINVAL;
1088 break;
1089 }
1090 if (copy_from_user(&sensor_data, data, sizeof(sensor_data))) {
1091 err = -EFAULT;
1092 break;
1093 } else {
1094 cali[MC32X0_AXIS_X] = sensor_data.x;
1095 cali[MC32X0_AXIS_Y] = sensor_data.y;
1096 cali[MC32X0_AXIS_Z] = sensor_data.z;
1097
1098 GSE_LOG
1099 ("MCUBE_IOCTL_SET_CALI %d %d %d %d %d %d!!\n",
1100 cali[MC32X0_AXIS_X], cali[MC32X0_AXIS_Y],
1101 cali[MC32X0_AXIS_Z], sensor_data.x, sensor_data.y,
1102 sensor_data.z);
1103
1104 err = MC32X0_WriteCalibration(client, cali);
1105 }
1106 break;
1107 case GSENSOR_IOCTL_CLR_CALI:
1108 GSE_LOG("fwq GSENSOR_IOCTL_CLR_CALI!!\n");
1109 err = MC32X0_ResetCalibration(client);
1110 break;
1111 case GSENSOR_IOCTL_GET_CALI:
1112 GSE_LOG("fwq mc32x0 GSENSOR_IOCTL_GET_CALI\n");
1113 data = (void __user *)arg;
1114 if (!data) {
1115 err = -EINVAL;
1116 break;
1117 }
1118
1119 err = MC32X0_ReadCalibration(client, cali);
1120 if (err) {
1121 GSE_LOG
1122 ("fwq mc32x0 MC32X0_ReadCalibration error!!!!\n");
1123 break;
1124 }
1125
1126 sensor_data.x = p_mc3230_data->cali_sw[MC32X0_AXIS_X];
1127 sensor_data.y = p_mc3230_data->cali_sw[MC32X0_AXIS_Y];
1128 sensor_data.z = p_mc3230_data->cali_sw[MC32X0_AXIS_Z];
1129 if (copy_to_user(data, &sensor_data, sizeof(sensor_data))) {
1130 err = -EFAULT;
1131 break;
1132 }
1133 break;
1134 case GSENSOR_IOCTL_SET_CALI_MODE:
1135 GSE_LOG("fwq mc32x0 GSENSOR_IOCTL_SET_CALI_MODE\n");
1136 break;
1137 case GSENSOR_MCUBE_IOCTL_READ_RBM_DATA:
1138 GSE_LOG("fwq GSENSOR_MCUBE_IOCTL_READ_RBM_DATA\n");
1139 data = (void __user *)arg;
1140 if (!data) {
1141 err = -EINVAL;
1142 break;
1143 }
1144 MC32X0_ReadRBMData(client, (char *)&strbuf);
1145 if (copy_to_user(data, &strbuf, strlen(strbuf) + 1)) {
1146 err = -EFAULT;
1147 break;
1148 }
1149 break;
1150 case GSENSOR_MCUBE_IOCTL_SET_RBM_MODE:
1151 GSE_LOG("fwq GSENSOR_MCUBE_IOCTL_SET_RBM_MODE\n");
1152 if (READ_FROM_BACKUP == true) {
1153 mcube_copy_file(calib_path);
1154 READ_FROM_BACKUP = false;
1155 }
1156 MC32X0_rbm(client, 1);
1157 break;
1158 case GSENSOR_MCUBE_IOCTL_CLEAR_RBM_MODE:
1159 GSE_LOG("fwq GSENSOR_MCUBE_IOCTL_SET_RBM_MODE\n");
1160
1161 MC32X0_rbm(client, 0);
1162 break;
1163 case GSENSOR_MCUBE_IOCTL_REGISTER_MAP:
1164 GSE_LOG("fwq GSENSOR_MCUBE_IOCTL_REGISTER_MAP\n");
1165 break;
1166 default:
1167 return -ENOTTY;
1168 }
1169
1170 switch (cmd) {
1171 case MC_IOCTL_GETDATA:
1172 if (copy_to_user(argp, &sense_data, sizeof(sense_data))) {
1173 GSE_LOG("failed to copy sense data to user space.");
1174 return -EFAULT;
1175 }
1176 break;
1177 case GSENSOR_IOCTL_READ_RAW_DATA:
1178 case GSENSOR_IOCTL_READ_SENSORDATA:
1179 if (copy_to_user(argp, &strbuf, strlen(strbuf) + 1)) {
1180 GSE_LOG("failed to copy sense data to user space.");
1181 return -EFAULT;
1182 }
1183 break;
1184 default:
1185 break;
1186 }
1187
1188 return 0;
1189 }
1190
1191 /* odr table, hz */
1192 static const int odr_table[8] = {
1193 1, 2, 4, 8, 16, 32, 64, 128
1194 };
1195
mc3230_select_odr(int want)1196 static int mc3230_select_odr(int want)
1197 {
1198 int i;
1199 int max_index = ARRAY_SIZE(odr_table);
1200
1201 for (i = 0; i < max_index; i++) {
1202 if (want <= odr_table[i])
1203 return max_index - i - 1;
1204 }
1205
1206 return 0;
1207 }
sensor_active(struct i2c_client * client,int enable,int rate)1208 static int sensor_active(struct i2c_client *client, int enable, int rate)
1209 {
1210 struct sensor_private_data *sensor =
1211 (struct sensor_private_data *)i2c_get_clientdata(client);
1212 int result = 0;
1213 int mc3230_rate = 0;
1214
1215 if (rate == 0) {
1216 dev_err(&client->dev, "%s: rate == 0!!!\n", __func__);
1217 return -1;
1218 }
1219
1220 mc3230_rate = mc3230_select_odr(1000 / rate);
1221
1222 mc3230_rate = 0xf8 | (0x07 & mc3230_rate);
1223
1224 if (rate != 0xff)
1225 result =
1226 sensor_write_reg(client, MC32X0_Sample_Rate_REG,
1227 mc3230_rate);
1228 if (result) {
1229 pr_info("%s:line=%d,error\n", __func__, __LINE__);
1230 return result;
1231 }
1232
1233 sensor->ops->ctrl_data = sensor_read_reg(client, sensor->ops->ctrl_reg);
1234
1235 if (!enable) {
1236 sensor->ops->ctrl_data &= ~MC3230_MODE_BITS;
1237 sensor->ops->ctrl_data |= MC32X0_MODE_SLEEP;
1238 } else {
1239 sensor->ops->ctrl_data &= ~MC3230_MODE_BITS;
1240 sensor->ops->ctrl_data |= MC32X0_MODE_WAKEUP;
1241 }
1242
1243 result =
1244 sensor_write_reg(client, sensor->ops->ctrl_reg,
1245 sensor->ops->ctrl_data);
1246 if (result)
1247 GSE_LOG("%s:fail to active sensor\n", __func__);
1248
1249 return result;
1250 }
1251
sensor_init(struct i2c_client * client)1252 static int sensor_init(struct i2c_client *client)
1253 {
1254 struct sensor_private_data *sensor =
1255 (struct sensor_private_data *)i2c_get_clientdata(client);
1256 int result = 0;
1257
1258 if (init_3230_ctl_data(client))
1259 return -1;
1260
1261 result = sensor->ops->active(client, 0, sensor->pdata->poll_delay_ms);
1262 if (result) {
1263 GSE_LOG("%s:line=%d,error\n", __func__, __LINE__);
1264 return result;
1265 }
1266
1267 sensor->status_cur = SENSOR_OFF;
1268
1269 result = sensor_write_reg(client, MC32X0_Interrupt_Enable_REG, 0x10);
1270 if (result) {
1271 GSE_LOG("%s:line=%d,error\n", __func__, __LINE__);
1272 return result;
1273 }
1274
1275 result = sensor->ops->active(client, 1, 31);
1276 if (result) {
1277 GSE_LOG("%s:line=%d,error\n", __func__, __LINE__);
1278 return result;
1279 }
1280
1281 return result;
1282 }
1283
sensor_report_value(struct i2c_client * client)1284 static int sensor_report_value(struct i2c_client *client)
1285 {
1286 int ret = 0;
1287
1288 mc3230_get_data(client);
1289
1290 return ret;
1291 }
1292
1293 static struct sensor_operate gsensor_ops = {
1294 .name = "gs_mc3230",
1295 /*sensor type and it should be correct */
1296 .type = SENSOR_TYPE_ACCEL,
1297 /* i2c id number */
1298 .id_i2c = ACCEL_ID_MC3230,
1299 /* read data */
1300 .read_reg = MC32X0_XOUT_REG,
1301 /* data length */
1302 .read_len = 3,
1303 /* read device id from this register, but mc3230 has no id register */
1304 .id_reg = SENSOR_UNKNOW_DATA,
1305 /* device id */
1306 .id_data = SENSOR_UNKNOW_DATA,
1307 /* 6 bits */
1308 .precision = 6,
1309 /* enable or disable */
1310 .ctrl_reg = MC32X0_Mode_Feature_REG,
1311 /* intterupt status register */
1312 .int_status_reg = MC32X0_Interrupt_Enable_REG,
1313 .range = {-32768, 32768},
1314 .trig = (IRQF_TRIGGER_HIGH | IRQF_ONESHOT),
1315 .active = sensor_active,
1316 .init = sensor_init,
1317 .report = sensor_report_value,
1318 };
1319
1320 /****************operate according to sensor chip:end************/
gsensor_mc3230_probe(struct i2c_client * client,const struct i2c_device_id * devid)1321 static int gsensor_mc3230_probe(struct i2c_client *client,
1322 const struct i2c_device_id *devid)
1323 {
1324 return sensor_register_device(client, NULL, devid, &gsensor_ops);
1325 }
1326
gsensor_mc3230_remove(struct i2c_client * client)1327 static int gsensor_mc3230_remove(struct i2c_client *client)
1328 {
1329 return sensor_unregister_device(client, NULL, &gsensor_ops);
1330 }
1331
1332 static const struct i2c_device_id gsensor_mc3230_id[] = {
1333 {"gs_mc3230", ACCEL_ID_MC3230},
1334 {}
1335 };
1336
1337 static struct i2c_driver gsensor_mc3230_driver = {
1338 .probe = gsensor_mc3230_probe,
1339 .remove = gsensor_mc3230_remove,
1340 .shutdown = sensor_shutdown,
1341 .id_table = gsensor_mc3230_id,
1342 .driver = {
1343 .name = "gsensor_mc3230",
1344 #ifdef CONFIG_PM
1345 .pm = &sensor_pm_ops,
1346 #endif
1347 },
1348 };
1349
1350 module_i2c_driver(gsensor_mc3230_driver);
1351
1352 MODULE_LICENSE("GPL");
1353 MODULE_DESCRIPTION("mc3230 3-Axis accelerometer driver");
1354 MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
1355