• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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