1 /* drivers/hwmon/sc7a20.c
2 *
3 *allwinner platform
4
5 *
6 * This software is licensed under the terms of the GNU General Public
7 * License version 2, as published by the Free Software Foundation, and
8 * may be copied, distributed, and modified under those terms.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 */
16
17 #include <linux/module.h>
18 #include <linux/init.h>
19 #include <linux/i2c.h>
20 #include <linux/mutex.h>
21 #include <linux/delay.h>
22 #include <linux/interrupt.h>
23 #include <linux/irq.h>
24 #include <linux/hwmon-sysfs.h>
25
26 #include <linux/err.h>
27 #include <linux/hwmon.h>
28 #include <linux/fs.h>
29 #include <linux/input-polldev.h>
30 #include <linux/device.h>
31 #include "../../init-input.h"
32 #include <linux/errno.h>
33 #include <linux/fs.h>
34 #include <linux/miscdevice.h>
35 #include <linux/uaccess.h>
36 #include <linux/kernel.h>
37 #include <linux/module.h>
38 #include <linux/moduleparam.h>
39 #include <linux/device.h>
40 #include <linux/gpio.h>
41 #include <linux/interrupt.h>
42 #include <linux/slab.h>
43 #include <linux/ioctl.h>
44 #include <linux/platform_device.h>
45 #include <linux/regulator/consumer.h>
46
47 #include <linux/hrtimer.h>
48 #include <linux/ktime.h>
49
50 #if IS_ENABLED(CONFIG_PM)
51 #include <linux/pm.h>
52 #endif
53
54 /*
55 * Defines
56 */
57 #define assert(expr) \
58 do {\
59 if (!(expr)) {\
60 printk("Assertion failed! %s,%d,%s,%s\n",\
61 __FILE__, __LINE__, __func__, #expr);\
62 } \
63 } while (0)
64
65 #define sc7a20_DRV_NAME "sc7a20"
66 #define SENSOR_NAME sc7a20_DRV_NAME
67
68 #define POLL_INTERVAL_MAX 1000
69 #define POLL_INTERVAL 50
70 #define INPUT_FUZZ 0
71 #define INPUT_FLAT 2
72 #define TIANJU_FILTER
73
74 #define sc7a20_REG_CTRL 0x20
75 #define sc7a20_REG_CTRL_RANGE 0x23
76 #define sc7a20_REG_DATA 0x00
77
78 #define sc7a20_MEASURING_RANGE 0x30
79 #define sc7a20_MEASURING_RANGE_2G 0x0
80 #define sc7a20_MEASURING_RANGE_4G 0x10
81 #define sc7a20_MEASURING_RANGE_8G 0x20
82 #define sc7a20_MEASURING_RANGE_16G 0x30
83
84 /* sc7a20 control bit */
85 #define sc7a20_CTRL_PWRON 0x47 /* power on */
86 #define sc7a20_CTRL_PWRDN 0x00 /* power donw */
87
88 #define MODE_CHANGE_DELAY_MS 100
89
90 #define CALIBRATION_NUM 40
91 #define AXIS_X_Y_RANGE_LIMIT 200
92 #define AXIS_X_Y_AVG_LIMIT 400
93 #define AXIS_Z_RANGE 200
94 #define AXIS_Z_DFT_G 1000
95 #define GOTO_CALI 100
96 #define FAILTO_CALI 101
97
98 #define SC7A20_ENABLE 1
99 #define SC7A20_XOUT_L 0x28
100 #define SC7A20_XOUT_H 0x29
101 #define SC7A20_YOUT_L 0x2A
102 #define SC7A20_YOUT_H 0x2B
103 #define SC7A20_ZOUT_L 0x2C
104 #define SC7A20_ZOUT_H 0x2D
105 #define SC7A20_MODE 0x20
106 #define SC7A20_MODE1 0x21
107 #define SC7A20_MODE2 0x22
108 #define SC7A20_MODE3 0x23
109 #define SC7A20_BOOT 0x24
110 #define SC7A20_STATUS 0x27
111
112 #define GSENSOR_REG_CALI
113
114 /*
115
116 #ifdef GSENSOR_REG_CALI
117 static int reg[29] = {0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A,
118 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
119 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A};
120 static int reg_data[29] = {0};
121 #endif
122
123 */
124 #define Z_OFF_DEFAULT (8) /* (110) */
125 #define XY_THR_N (-15) /* (-240) */
126 #define XY_THR_P (15) /* (240) */
127 #define Z_THR_MIN_N (-50) /* (-780) */
128 #define Z_THR_MIN_P (50) /* (780) */
129 #define Z_THR_MAX_N (-78) /* (-1200) */
130 #define Z_THR_MAX_P (78) /* (1200) */
131 #define SUM_DOT (50)
132 #define THRESHOLD_VAL (8) /* (40) */
133
134 //static struct device *hwmon_dev;
135 static struct i2c_client *sc7a20_i2c_client;
136 static struct input_dev *sc7a20_idev;
137
138 struct sc7a20_data_s {
139 struct i2c_client *client;
140 struct input_dev *inputDev;
141 struct mutex interval_mutex;
142
143 struct delayed_work dwork;//allen
144 int time_of_cali;
145 atomic_t enable;
146
147 #if IS_ENABLED(CONFIG_PM)
148 volatile int suspend_indator;
149 #endif
150 struct hrtimer hr_timer;
151 struct work_struct wq_hrtimer;
152 ktime_t ktime;
153
154 } sc7a20_data;
155
156 /* Addresses to scan */
157 static const unsigned short normal_i2c[] = {0x19, I2C_CLIENT_END};
158 static __u32 twi_id;
159 static unsigned int delayMs = POLL_INTERVAL;
160
161 static struct sensor_config_info gsensor_info = {
162 .input_type = GSENSOR_TYPE,
163 };
164
165 enum {
166 DEBUG_INIT = 1U << 0,
167 DEBUG_CONTROL_INFO = 1U << 1,
168 DEBUG_DATA_INFO = 1U << 2,
169 DEBUG_SUSPEND = 1U << 3,
170 };
171 static u32 debug_mask;
172 #define dprintk(level_mask, fmt, arg...) \
173 do {\
174 if (unlikely(debug_mask & (level_mask))) \
175 printk(KERN_DEBUG fmt, ## arg); \
176 } while (0)
177
178 module_param_named(debug_mask, debug_mask, int, S_IRUGO);
179
180 static void sc7a20_reset(void);
181
182 #if 0
183 static char Read_Reg(unsigned char reg)
184 {
185 char ret;
186 ret = i2c_smbus_read_byte_data(sc7a20_i2c_client, reg);
187 return ret;
188 }
189 static void Write_Input(char addr, char thedata)
190 {
191 int result;
192 //result = sensor_write_reg(sc7a20_i2c_client, addr, thedata);
193 result = i2c_smbus_write_byte_data(sc7a20_i2c_client, addr, thedata);
194 }
195
196 #endif
197
198
199 /**
200 * gsensor_detect - Device detection callback for automatic device creation
201 * return value:
202 * = 0; success;
203 * < 0; err
204 */
205
sc7a20_gsensor_detect(struct i2c_client * client,struct i2c_board_info * info)206 static int sc7a20_gsensor_detect(struct i2c_client *client, struct i2c_board_info *info)
207 {
208 struct i2c_adapter *adapter = client->adapter;
209 //__s32 ret = 0;
210
211 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
212 return -ENODEV;
213
214 if (twi_id == adapter->nr) {
215 printk("%s: addr= %x\n", __func__, client->addr);
216 /*
217 ret = gsensor_i2c_test(client);
218 if (!ret) {
219 pr_info("%s:I2C connection might be something wrong or maybe the other gsensor equipment! \n",__func__);
220 return -ENODEV;
221 } else
222 */
223 {
224 dprintk(DEBUG_INIT, "%s: I2C connection sucess!\n", __func__);
225 strlcpy(info->type, SENSOR_NAME, I2C_NAME_SIZE);
226 return 0;
227 }
228
229 } else {
230 dprintk(DEBUG_INIT, "%s: I2C connection error!\n", __func__);
231 return -ENODEV;
232 }
233 }
234
sc7a20_delay_show(struct device * dev,struct device_attribute * attr,char * buf)235 static ssize_t sc7a20_delay_show(struct device *dev,
236 struct device_attribute *attr, char *buf)
237 {
238 struct i2c_client *client = sc7a20_i2c_client;
239 struct sc7a20_data_s *sc7a20 = NULL;
240
241 sc7a20 = i2c_get_clientdata(client);
242 return sprintf(buf, "%d\n", delayMs);
243 }
244
sc7a20_delay_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)245 static ssize_t sc7a20_delay_store(struct device *dev,
246 struct device_attribute *attr,
247 const char *buf, size_t count)
248 {
249 unsigned long data;
250 //int error;
251 struct i2c_client *client = sc7a20_i2c_client;
252 struct sc7a20_data_s *sc7a20 = NULL;
253
254 sc7a20 = i2c_get_clientdata(client);
255 dprintk(DEBUG_INIT, "delay store %d\n", __LINE__);
256
257 data = simple_strtoul(buf, NULL, 10);
258 //error = strict_strtoul(buf, 10, &data);
259 //if (error)
260 // return error;
261
262 if (data > POLL_INTERVAL_MAX)
263 data = POLL_INTERVAL_MAX;
264 if (0 >= data)
265 data = 10;
266
267 mutex_lock(&sc7a20->interval_mutex);
268 delayMs = data;
269 mutex_unlock(&sc7a20->interval_mutex);
270 printk(KERN_INFO "%s: sc7a20 delay %d\n", __func__, delayMs);
271
272 if (atomic_read(&sc7a20_data.enable)) {
273 if (delayMs <= 10) {
274 // early 0.5ms
275 sc7a20_data.ktime = ktime_set(0, delayMs* NSEC_PER_MSEC - NSEC_PER_MSEC / 2);
276 } else {
277 sc7a20_data.ktime = ktime_set(0, delayMs* NSEC_PER_MSEC);
278 }
279 hrtimer_start(&sc7a20_data.hr_timer, sc7a20_data.ktime, HRTIMER_MODE_REL);
280 }
281
282 return count;
283 }
284
enable_sensor(int enable)285 static void enable_sensor(int enable)
286 {
287 int error;
288 u32 val = 0;
289
290 if (enable) {
291 printk(KERN_INFO "%s: sc7a20_CTRL_PWRON\n", __func__);
292 error = i2c_smbus_write_byte_data(sc7a20_i2c_client, sc7a20_REG_CTRL, sc7a20_CTRL_PWRON);
293 assert(error == 0);
294
295 // set sensor max range is 4G, because cts test request.
296 val = i2c_smbus_read_byte_data(sc7a20_i2c_client, sc7a20_REG_CTRL_RANGE);
297 val &= ~(sc7a20_MEASURING_RANGE);
298 error = i2c_smbus_write_byte_data(sc7a20_i2c_client, sc7a20_REG_CTRL_RANGE, val | sc7a20_MEASURING_RANGE_4G);
299 assert(error == 0);
300
301 printk(KERN_INFO "%s: sc7a20 delay %d\n", __func__, delayMs);
302 if (delayMs <= 10) {
303 // early 0.5ms
304 sc7a20_data.ktime = ktime_set(0, delayMs * NSEC_PER_MSEC - NSEC_PER_MSEC / 2);
305 } else {
306 sc7a20_data.ktime = ktime_set(0, delayMs * NSEC_PER_MSEC);
307 }
308 hrtimer_start(&sc7a20_data.hr_timer, sc7a20_data.ktime, HRTIMER_MODE_REL);
309 } else {
310 printk(KERN_INFO "%s: sc7a20_CTRL_PWRDN\n", __func__);
311 hrtimer_cancel(&sc7a20_data.hr_timer);
312 error = i2c_smbus_write_byte_data(sc7a20_i2c_client, sc7a20_REG_CTRL, sc7a20_CTRL_PWRDN);
313 assert(error == 0);
314 }
315
316 }
317
sc7a20_enable_show(struct device * dev,struct device_attribute * attr,char * buf)318 static ssize_t sc7a20_enable_show(struct device *dev,
319 struct device_attribute *attr, char *buf)
320 {
321 struct i2c_client *client = sc7a20_i2c_client;
322 struct sc7a20_data_s *sc7a20 = NULL;
323
324 sc7a20 = i2c_get_clientdata(client);
325
326 return sprintf(buf, "%d\n", atomic_read(&sc7a20_data.enable));
327
328 }
329
sc7a20_enable_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)330 static ssize_t sc7a20_enable_store(struct device *dev,
331 struct device_attribute *attr,
332 const char *buf, size_t count)
333 {
334 unsigned long data;
335
336 struct i2c_client *client = sc7a20_i2c_client;
337 struct sc7a20_data_s *sc7a20 = NULL;
338
339 sc7a20 = i2c_get_clientdata(client);
340
341 printk(KERN_INFO "%s: buf=%s\n", __func__, buf);
342 data = simple_strtoul(buf, NULL, 10);
343 //error = strict_strtoul(buf, 10, &data);
344
345 //if (error) {
346 // pr_err("%s strict_strtoul error\n", __FUNCTION__);
347 // goto exit;
348 //}
349
350 atomic_set(&sc7a20_data.enable, data);
351 enable_sensor(data);
352 return count;
353
354 //exit:
355 // return error;
356 }
357
358
359
SC7A20_register_store(struct device * dev,struct device_attribute * attr,const char * buf,size_t count)360 static ssize_t SC7A20_register_store(struct device *dev,
361 struct device_attribute *attr,
362 const char *buf, size_t count)
363 {
364 unsigned int address, value;
365 int result = 0;
366 sscanf(buf, "0x%x=0x%x", &address, &value);
367
368 result = i2c_smbus_write_byte_data(sc7a20_i2c_client, address, value);
369
370 if (result)
371 printk("%s:fail to write sensor_register\n", __func__);
372
373 return count;
374 }
375
SC7A20_register_show(struct device * dev,struct device_attribute * attr,char * buf)376 static ssize_t SC7A20_register_show(struct device *dev,
377 struct device_attribute *attr, char *buf)
378 {
379 size_t count = 0;
380 //u8 reg[0x5b];
381 char i;
382 int buffer[3] = {0};
383 i = 0x0f;
384 *buffer = i;
385 buffer[0] = i2c_smbus_read_byte_data(sc7a20_i2c_client, i);
386 count += sprintf(buf, "0x%x: 0x%x\n", i, buffer[0]);
387 for (i = 0x10; i < 0x5a; i++) {
388 *buffer = i;
389 buffer[0] = i2c_smbus_read_byte_data(sc7a20_i2c_client, i);
390 count += sprintf(&buf[count], "0x%x: 0x%x\n", i, buffer[0]);
391 }
392 return count;
393 }
394 #if 0
395 static DEVICE_ATTR(enable, S_IRUGO,
396 sc7a20_enable_show, sc7a20_enable_store);
397
398 static DEVICE_ATTR(delay, S_IRUGO,
399 sc7a20_delay_show, sc7a20_delay_store);
400
401 static DEVICE_ATTR(reg, S_IRUGO,
402 SC7A20_register_show, SC7A20_register_store);
403
404 static DEVICE_ATTR(reg13_reset, S_IRUGO,
405 SC7A20_reg13_reset, NULL);
406
407 static DEVICE_ATTR(calibration_run, S_IRUGO, //S_IWUSR|S_IWGRP, //calibration_run
408 NULL, SC7A20_3_axis_Calibration);
409 #endif
410 static DEVICE_ATTR(enable, 0644,
411 sc7a20_enable_show, sc7a20_enable_store);
412
413 static DEVICE_ATTR(delay, 0644,
414 sc7a20_delay_show, sc7a20_delay_store);
415
416 static DEVICE_ATTR(reg, 0644,
417 SC7A20_register_show, SC7A20_register_store);
418
419 //static DEVICE_ATTR(reg13_reset, 0644,
420 // SC7A20_reg13_reset, NULL);
421
422 //static DEVICE_ATTR(calibration_run, 0644,//S_IWUSR|S_IWGRP, //calibration_run
423 // NULL, SC7A20_3_axis_Calibration);
424
425 static struct attribute *sc7a20_attributes[] = {
426 // &dev_attr_reg13_reset.attr,
427 &dev_attr_reg.attr,
428 &dev_attr_enable.attr,
429 &dev_attr_delay.attr,
430 // &dev_attr_calibration_run.attr,
431 NULL
432 };
433
434 static struct attribute_group sc7a20_attribute_group = {
435 .attrs = sc7a20_attributes
436 };
437
438 #if 0
439 static int report_abs(void)
440 {
441 s8 xyz[6] = {0, 0, 0};
442 s16 x = 0, y = 0, z = 0;
443 s8 ret = 0;
444 s16 conut = 0;
445 while (1) {
446 ret = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_STATUS);
447 if ((ret & 0x08) != 0) {
448 break;
449 }
450 msleep(1);
451 conut++;
452 if (conut > 40)
453 break;
454 }
455
456 xyz[0] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_XOUT_L);
457 xyz[1] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_XOUT_H);
458
459 xyz[2] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_YOUT_L);
460 xyz[3] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_YOUT_H);
461
462 xyz[4] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_ZOUT_L);
463 xyz[5] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_ZOUT_H);
464
465 //x = ((xyz[1]) << 8) | xyz[0];
466 //y = ((xyz[3]) << 8) | xyz[2];
467 //z = ((xyz[5]) << 8) | xyz[4];
468
469 x = xyz[1];
470 y = xyz[3];
471 z = xyz[5];
472
473
474 input_report_abs(sc7a20_idev->input, ABS_X, x);
475 input_report_abs(sc7a20_idev->input, ABS_Y, y);
476 input_report_abs(sc7a20_idev->input, ABS_Z, z);
477
478 input_sync(sc7a20_idev->input);
479 return 1;
480 }
481
482
483 /*
484 * I2C init/probing/exit functions
485 */
486
487 ////////////////////////////////djq////////////////////////////////////
488 static int sc7a20_acc_get_data(int *xyz)
489 {
490 u8 acc_data[6];
491 /* x,y,z hardware data */
492 int hw_d[3] = { 0 };
493 signed short temp_data[3];
494 int count = 0;
495 u8 buf[3];
496 buf[0] = SC7A20_STATUS;
497 while (1) {
498 buf[0] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_STATUS);
499 if ((buf[0] & 0x08) != 0) {
500 break;
501 }
502 msleep(1);
503 count++;
504 if (count > 40)
505 break;
506 }
507
508 buf[0] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_XOUT_L);
509 acc_data[0] = buf[0];
510 buf[0] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_XOUT_H);
511
512 acc_data[1] = buf[0];
513
514 buf[0] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_YOUT_L);
515 acc_data[2] = buf[0];
516 buf[0] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_YOUT_H);
517 acc_data[3] = buf[0];
518
519 buf[0] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_ZOUT_L);
520 acc_data[4] = buf[0];
521 buf[0] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_ZOUT_H);
522 acc_data[5] = buf[0];
523
524 /* 12-bit */
525 temp_data[0] = (signed short)((acc_data[1] << 8 | acc_data[0]) >> 4);
526 temp_data[1] = (signed short)((acc_data[3] << 8 | acc_data[2]) >> 4);
527 temp_data[2] = (signed short)((acc_data[5] << 8 | acc_data[4]) >> 4);
528
529 hw_d[0] = (temp_data[0] & 0x0800) ? (temp_data[0] | 0xFFFFF800) : (temp_data[0]);
530 hw_d[1] = (temp_data[1] & 0x0800) ? (temp_data[1] | 0xFFFFF800) : (temp_data[1]);
531 hw_d[2] = (temp_data[2] & 0x0800) ? (temp_data[2] | 0xFFFFF800) : (temp_data[2]);
532
533
534
535 xyz[0] = (hw_d[0]) * 1000;
536 xyz[1] = (hw_d[1]) * 1000;
537 xyz[2] = (hw_d[2]) * 1000;
538
539 return 0;
540 }
541
542
543 static int sc7a20_acc_hw_init(void)
544 {
545 char ret;
546 ret = i2c_smbus_write_byte_data(sc7a20_i2c_client, SC7A20_MODE, 0x77);
547 if (ret < 0) {
548 return -1;
549 }
550
551 return 0;
552 }
553
554 #endif
my_hrtimer_callback(struct hrtimer * timer)555 static enum hrtimer_restart my_hrtimer_callback(struct hrtimer *timer)
556 {
557 schedule_work(&sc7a20_data.wq_hrtimer);
558 hrtimer_forward_now(&sc7a20_data.hr_timer, sc7a20_data.ktime);
559 return HRTIMER_RESTART;
560 }
561
find_max_min(s16 * array,int len,s16 * max,s16 * min)562 void find_max_min(s16 *array, int len, s16 *max, s16 *min)
563 {
564 s16 temp_max = *array;
565 s16 temp_min = *array;
566
567 int i = 0;
568 for (i = 0; i < len; i++) {
569 if (*(array + i) > temp_max)
570 temp_max = *(array + i);
571
572 if (*(array + i) < temp_min)
573 temp_min = *(array + i);
574 }
575
576 *max = temp_max;
577 *min = temp_min;
578 }
579
wq_func_hrtimer(struct work_struct * work)580 static void wq_func_hrtimer(struct work_struct *work)
581 {
582 s8 xyz[6] = {0, 0, 0};
583 s16 x = 0, y = 0, z = 0;
584 /*
585 static s16 axis_x_off = 0; //jq 2017-08-07
586 static s16 axis_y_off = 0; //jq 2017-08-07
587 static s16 axis_z_off = Z_OFF_DEFAULT; //jq 2017-08-07
588 static u16 index = 0;
589 static s16 x_value[SUM_DOT] = {0};
590 static s16 y_value[SUM_DOT] = {0};
591 static s16 z_value[SUM_DOT] = {0};
592
593 int flag_x = 0;
594 int flag_y = 0;
595 int flag_z = 0;
596
597 int i = 0;
598
599 s16 x_min = 0;
600 s16 x_max = 0;
601 s16 y_min = 0;
602 s16 y_max = 0;
603 s16 z_min = 0;
604 s16 z_max = 0;
605
606 s32 temp_x_value = 0;
607 s32 temp_y_value = 0;
608 s32 temp_z_value = 0;
609 */
610 xyz[0] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_XOUT_L);
611 xyz[1] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_XOUT_H);
612
613 xyz[2] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_YOUT_L);
614 xyz[3] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_YOUT_H);
615
616 xyz[4] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_ZOUT_L);
617 xyz[5] = i2c_smbus_read_byte_data(sc7a20_i2c_client, SC7A20_ZOUT_H);
618 /*
619 xyz[1] = ((xyz[1]) << 8) >> 8;
620 xyz[3] = ((xyz[3]) << 8) >> 8;
621 xyz[5] = ((xyz[5]) << 8) >> 8;
622
623 if (index < SUM_DOT) {
624 if (xyz[1] > XY_THR_N && xyz[1] < XY_THR_P)
625 flag_x = 1;
626 else
627 flag_x = 0;
628
629 if (xyz[3] > XY_THR_N && xyz[3] < XY_THR_P)
630 flag_y = 1;
631 else
632 flag_y = 0;
633
634 if ((xyz[5] > Z_THR_MAX_N && xyz[5] < Z_THR_MIN_N) || (xyz[5] > Z_THR_MIN_P && xyz[5] < Z_THR_MAX_P))
635 flag_z = 1;
636 else
637 flag_z = 0;
638
639 if (flag_x == 1 && flag_y == 1 && flag_z == 1) {
640 x_value[index] = xyz[1];
641 y_value[index] = xyz[3];
642 z_value[index] = xyz[5];
643 index = index + 1;
644 } else
645 index = 0;
646 }
647
648 if (index == SUM_DOT) {
649 find_max_min(x_value, SUM_DOT, &x_max, &x_min);
650 // printk("aaaaa %s:x_max=%d\n x_min=%d\n ",__func__,x_max,x_min);
651 find_max_min(y_value, SUM_DOT, &y_max, &y_min);
652 // printk("aaaaa %s:y_max=%d\n y_min=%d\n ",__func__,y_max,y_min);
653 find_max_min(z_value, SUM_DOT, &z_max, &z_min);
654 // printk("aaaaa %s:z_max=%d\n z_min=%d\n",__func__,z_max,z_min);
655
656 if (((x_max - x_min) < THRESHOLD_VAL) && ((y_max - y_min) < THRESHOLD_VAL)
657 && ((z_max - z_min) < THRESHOLD_VAL)) {
658 temp_x_value = 0;
659 for (i = 0; i < SUM_DOT; i++) {
660 temp_x_value += x_value[i];
661 }
662 temp_x_value = temp_x_value / SUM_DOT;
663 axis_x_off = 0 - (s16)temp_x_value;
664
665 temp_y_value = 0;
666 for (i = 0; i < SUM_DOT; i++) {
667 temp_y_value += y_value[i];
668 }
669 temp_y_value = temp_y_value / SUM_DOT;
670 axis_y_off = 0 - (s16)temp_y_value;
671
672 temp_z_value = 0;
673 for (i = 0; i < SUM_DOT; i++) {
674 temp_z_value += z_value[i];
675 }
676 temp_z_value = temp_z_value / SUM_DOT;
677
678 if (temp_z_value > Z_THR_MAX_N && temp_z_value < Z_THR_MIN_N)
679 axis_z_off = -64 - (s16)temp_z_value;
680 else
681 axis_z_off = 64 - (s16)temp_z_value;
682 // printk("aaaaa %s:axis_x_off=%d\n axis_y_off=%d\n axis_z_off=%d\n",__func__,axis_x_off,axis_y_off,axis_z_off);
683 }
684 index = 0;
685
686 }
687 //x += axis_x_off;
688 //y += axis_y_off;
689 //z += axis_z_off;
690 xyz[1] += axis_x_off;
691 xyz[3] += axis_y_off;
692 xyz[5] += axis_z_off;
693
694 //x = ((xyz[1]) << 8) >> 8;
695 //y = ((xyz[3]) << 8) >> 8;
696 //z = ((xyz[5]) << 8) >> 8;
697 */
698 x = xyz[1];
699 y = xyz[3];
700 z = xyz[5];
701
702 if (x == 0 && y == 0 && z == 0) {
703 printk("sc7a20 gsensor x y z all 0!!!\n");
704 sc7a20_reset();
705 return;
706 }
707
708 input_report_rel(sc7a20_data.inputDev, REL_X, x);
709 input_report_rel(sc7a20_data.inputDev, REL_Y, y);
710 input_report_rel(sc7a20_data.inputDev, REL_Z, z);
711
712 input_sync(sc7a20_data.inputDev);
713 //printk("chongyuzhao report %d - %d - %d\n", x, y, z);
714 }
715
sc7a20_probe(struct i2c_client * client,const struct i2c_device_id * id)716 static int sc7a20_probe(struct i2c_client *client,
717 const struct i2c_device_id *id)
718 {
719 char reg_cali;
720
721 int result;
722 struct i2c_adapter *adapter;
723 struct sc7a20_data_s *data = &sc7a20_data;
724
725 if (gsensor_info.dev == NULL)
726 gsensor_info.dev = &client->dev;
727
728 printk("sc7a20 probe\n");
729 sc7a20_i2c_client = client;
730 adapter = to_i2c_adapter(client->dev.parent);
731 result = i2c_check_functionality(adapter,
732 I2C_FUNC_SMBUS_BYTE |
733 I2C_FUNC_SMBUS_BYTE_DATA);
734 assert(result);
735 //hwmon_device_register_with_info
736 //hwmon_dev = hwmon_device_register(&client->dev);
737 //assert(!(IS_ERR(hwmon_dev)));
738
739 /*input poll device register */
740 sc7a20_idev = input_allocate_device();
741 if (!sc7a20_idev) {
742 dev_err(&client->dev, "alloc poll device failed!\n");
743 result = -ENOMEM;
744 return result;
745 }
746
747 sc7a20_idev->name = sc7a20_DRV_NAME;
748 sc7a20_idev->id.bustype = BUS_I2C;
749
750 mutex_init(&data->interval_mutex);
751 input_set_capability(sc7a20_idev, EV_REL, REL_X);
752 input_set_capability(sc7a20_idev, EV_REL, REL_Y);
753 input_set_capability(sc7a20_idev, EV_REL, REL_Z);
754 //input_set_abs_params(sc7a20_idev, ABS_X, -512, 512, INPUT_FUZZ, INPUT_FLAT);
755 //input_set_abs_params(sc7a20_idev, ABS_Y, -512, 512, INPUT_FUZZ, INPUT_FLAT);
756 //input_set_abs_params(sc7a20_idev, ABS_Z, -512, 512, INPUT_FUZZ, INPUT_FLAT);
757 input_set_drvdata(sc7a20_idev, &sc7a20_data);
758
759 result = input_register_device(sc7a20_idev);
760 if (result) {
761 dev_err(&client->dev, "registerdevice failed!\n");
762 return result;
763 }
764 result = sysfs_create_group(&sc7a20_idev->dev.kobj, &sc7a20_attribute_group);
765
766 if (result) {
767 dev_err(&client->dev, "create sys failed\n");
768 }
769 kobject_uevent(&sc7a20_idev->dev.kobj, KOBJ_CHANGE);
770
771 data->client = client;
772 data->inputDev = sc7a20_idev;
773 i2c_set_clientdata(client, data);
774
775 //result = i2c_smbus_write_byte_data(sc7a20_i2c_client, sc7a20_REG_CTRL, sc7a20_CTRL_PWRON);
776 //assert(result == 0);
777
778 reg_cali = i2c_smbus_read_byte_data(sc7a20_i2c_client, 0x13);
779 printk("line %d reg_cali = 0x%x \n", __LINE__, reg_cali);
780
781 hrtimer_init(&sc7a20_data.hr_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
782 sc7a20_data.hr_timer.function = my_hrtimer_callback;
783 INIT_WORK(&sc7a20_data.wq_hrtimer, wq_func_hrtimer);
784
785 return result;
786 }
787
sc7a20_remove(struct i2c_client * client)788 static int sc7a20_remove(struct i2c_client *client)
789 {
790 int result;
791 result = i2c_smbus_write_byte_data(sc7a20_i2c_client, sc7a20_REG_CTRL, sc7a20_CTRL_PWRDN);
792 assert(result == 0);
793 //hwmon_device_unregister(hwmon_dev);
794
795 hrtimer_cancel(&sc7a20_data.hr_timer);
796 sysfs_remove_group(&sc7a20_idev->dev.kobj, &sc7a20_attribute_group);
797 input_unregister_device(sc7a20_idev);
798 i2c_set_clientdata(sc7a20_i2c_client, NULL);
799
800 return result;
801 }
802
803 #if IS_ENABLED(CONFIG_PM)
sc7a20_resume(struct device * dev)804 static int sc7a20_resume(struct device *dev)
805 {
806 int enable = atomic_read(&sc7a20_data.enable);
807 input_set_power_enable(&(gsensor_info.input_type), 1);
808 enable_sensor(enable);
809 return 0;
810 }
811
sc7a20_suspend(struct device * dev)812 static int sc7a20_suspend(struct device *dev)
813 {
814 enable_sensor(0);
815 input_set_power_enable(&(gsensor_info.input_type), 0);
816 return 0;
817 }
818 #endif
819
sc7a20_reset(void)820 static void sc7a20_reset(void)
821 {
822 int result;
823 int val_reg;
824 int MTPSETTING, B57H, B1BH, i;
825 printk("sc7a20 reset power down\n");
826 result = i2c_smbus_write_byte_data(sc7a20_i2c_client, sc7a20_REG_CTRL, sc7a20_CTRL_PWRDN);
827 assert(result == 0);
828 msleep(50);
829
830 printk("sc7a20 reset power on\n");
831 val_reg = i2c_smbus_read_byte_data(sc7a20_i2c_client, 0x0f);
832 if (val_reg != 0x11) {
833 for (i = 0; i < 3; i++) {
834 MTPSETTING = 0x07;
835 B57H = 0x00;
836 B1BH = 0x08;
837 sc7a20_i2c_client->addr = 0x18;
838 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x59, MTPSETTING);
839 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1e, 0x05);
840 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1b, B1BH);
841 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x57, B57H);
842 sc7a20_i2c_client->addr = 0x19;
843 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x59, MTPSETTING);
844 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1e, 0x05);
845 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1b, B1BH);
846 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x57, B57H);
847 sc7a20_i2c_client->addr = 0x1a;
848 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x59, MTPSETTING);
849 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1e, 0x05);
850 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1b, B1BH);
851 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x57, B57H);
852 sc7a20_i2c_client->addr = 0x1b;
853 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x59, MTPSETTING);
854 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1e, 0x05);
855 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1b, B1BH);
856 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x57, B57H);
857 sc7a20_i2c_client->addr = 0x1c;
858 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x59, MTPSETTING);
859 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1e, 0x05);
860 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1b, B1BH);
861 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x57, B57H);
862 sc7a20_i2c_client->addr = 0x1d;
863 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x59, MTPSETTING);
864 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1e, 0x05);
865 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1b, B1BH);
866 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x57, B57H);
867 sc7a20_i2c_client->addr = 0x1e;
868 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x59, MTPSETTING);
869 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1e, 0x05);
870 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1b, B1BH);
871 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x57, B57H);
872 sc7a20_i2c_client->addr = 0x1f;
873 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x59, MTPSETTING);
874 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1e, 0x05);
875 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1b, B1BH);
876 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x57, B57H);
877 }
878 sc7a20_i2c_client->addr = 0x1d;
879 msleep(100);
880 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x24, 0x80);
881 i2c_smbus_write_byte_data(sc7a20_i2c_client, 0x1e, 0x05);
882 val_reg = i2c_smbus_read_byte_data(sc7a20_i2c_client, 0x0f);
883 if (val_reg != 0x11)
884 printk("momkey sc7a20 resume fail! regchip_id=0x%x\n", val_reg);
885 }
886
887 result = i2c_smbus_write_byte_data(sc7a20_i2c_client, sc7a20_REG_CTRL, sc7a20_CTRL_PWRON);
888 assert(result == 0);
889 }
890 static const struct of_device_id sc7a20_of_match[] = {
891 {.compatible = "allwinner,sc7a20"},
892 {},
893 };
894
895 static const struct i2c_device_id sc7a20_id[] = {
896 { sc7a20_DRV_NAME, 0 },
897 { }
898 };
899 MODULE_DEVICE_TABLE(i2c, sc7a20_id);
900
901 #if IS_ENABLED(CONFIG_PM)
902 static UNIVERSAL_DEV_PM_OPS(sc7a20_pm_ops, sc7a20_suspend,
903 sc7a20_resume, NULL);
904 #endif
905
906 static struct i2c_driver sc7a20_driver = {
907 .class = I2C_CLASS_HWMON,
908 .driver = {
909 .of_match_table = sc7a20_of_match,
910 .name = sc7a20_DRV_NAME,
911 .owner = THIS_MODULE,
912 #if IS_ENABLED(CONFIG_PM)
913 .pm = &sc7a20_pm_ops,
914 #endif
915 },
916 .probe = sc7a20_probe,
917 .remove = sc7a20_remove,
918 .id_table = sc7a20_id,
919 .address_list = normal_i2c,
920 };
921
startup(void)922 static int startup(void)
923 {
924 int ret = -1;
925
926 printk("function=%s=========LINE=%d. \n", __func__, __LINE__);
927
928 if (input_sensor_startup(&(gsensor_info.input_type))) {
929 printk("%s: err.\n", __func__);
930 return -1;
931 } else
932 ret = input_sensor_init(&(gsensor_info.input_type));
933
934 if (0 != ret) {
935 printk("%s:gsensor.init_platform_resource err. \n", __func__);
936 }
937
938 twi_id = gsensor_info.twi_id;
939 input_set_power_enable(&(gsensor_info.input_type), 1);
940 return 0;
941 }
942
sc7a20_init(void)943 static int __init sc7a20_init(void)
944 {
945 int ret = -1;
946
947 if (startup() != 0)
948 return -1;
949 if (!gsensor_info.isI2CClient)
950 sc7a20_driver.detect = sc7a20_gsensor_detect;
951 ret = i2c_add_driver(&sc7a20_driver);
952 if (ret < 0) {
953 printk("add sc7a20 i2c driver failed\n");
954 return -ENODEV;
955 }
956
957 return 0;
958 }
959
sc7a20_exit(void)960 static void __exit sc7a20_exit(void)
961 {
962 printk("remove sc7a20 i2c driver.\n");
963 input_sensor_free(&(gsensor_info.input_type));
964 input_set_power_enable(&(gsensor_info.input_type), 0);
965 i2c_del_driver(&sc7a20_driver);
966 }
967
968 MODULE_AUTHOR("allwinner");
969 MODULE_DESCRIPTION("sc7a20 Sensor driver");
970 MODULE_LICENSE("GPL");
971 MODULE_VERSION("1.0.3");
972
973 module_init(sc7a20_init);
974 module_exit(sc7a20_exit);
975
976