xref: /OK3568_Linux_fs/kernel/drivers/input/sensors/lsensor/ls_us5152.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #include <linux/interrupt.h>
3 #include <linux/i2c.h>
4 #include <linux/slab.h>
5 #include <linux/irq.h>
6 #include <linux/miscdevice.h>
7 #include <linux/gpio.h>
8 #include <linux/uaccess.h>
9 #include <asm/atomic.h>
10 #include <linux/delay.h>
11 #include <linux/input.h>
12 #include <linux/workqueue.h>
13 #include <linux/freezer.h>
14 #ifdef CONFIG_HAS_EARLYSUSPEND
15 #include <linux/earlysuspend.h>
16 #endif
17 #include <linux/sensor-dev.h>
18 #include <linux/types.h>
19 
20 
21 #define DRIVER_VERSION		        "1.0"
22 
23 #define PWR_MODE_DOWN_MASK     		0x80
24 #define PWR_MODE_OPERATE_MASK     0x7F
25 
26 
27 /*us5152 Slave Addr*/
28 #define LIGHT_ADDR      0x72
29 
30 /*Interrupt PIN for S3C6410*/
31 #define IRQ_LIGHT_INT IRQ_EINT(6)
32 
33 /*Register Set*/
34 #define REGS_CR0          	0x00
35 #define REGS_CR1          	0x01
36 #define REGS_CR2          	0x02
37 #define REGS_CR3          	0x03
38 //ALS
39 #define REGS_INT_LSB_TH_LO      0x04
40 #define REGS_INT_MSB_TH_LO      0x05
41 #define REGS_INT_LSB_TH_HI      0x06
42 #define REGS_INT_MSB_TH_HI      0x07
43 //ALS data
44 #define REGS_LBS_SENSOR         0x0C
45 #define REGS_MBS_SENSOR         0x0D
46 
47 #define REGS_CR10          	0x10
48 #define REGS_CR11          	0x11
49 #define REGS_VERSION_ID      	0x1F
50 #define REGS_CHIP_ID      	0xB2
51 
52 /*ShutDown_EN*/
53 #define CR0_OPERATION		0x0
54 #define CR0_SHUTDOWN_EN		0x1
55 
56 #define CR0_SHUTDOWN_SHIFT   	(7)
57 #define CR0_SHUTDOWN_MASK    	(0x1 << CR0_SHUTDOWN_SHIFT)
58 
59 /*OneShot_EN*/
60 #define CR0_ONESHOT_EN		0x01
61 
62 #define CR0_ONESHOT_SHIFT   	(6)
63 #define CR0_ONESHOT_MASK    	(0x1 << CR0_ONESHOT_SHIFT)
64 
65 /*Operation Mode*/
66 #define CR0_OPMODE_ALSANDPS	0x0
67 #define CR0_OPMODE_ALSONLY	0x1
68 #define CR0_OPMODE_IRONLY		0x2
69 
70 #define CR0_OPMODE_SHIFT       	(4)
71 #define CR0_OPMODE_MASK        	(0x3 << CR0_OPMODE_SHIFT)
72 
73 /*all int flag (PROX, INT_A, INT_P)*/
74 #define CR0_ALL_INT_CLEAR	0x0
75 
76 #define CR0_ALL_INT_SHIFT       (1)
77 #define CR0_ALL_INT_MASK        (0x7 << CR0_ALL_INT_SHIFT)
78 
79 
80 /*indicator of object proximity detection*/
81 #define CR0_PROX_CLEAR		0x0
82 
83 #define CR0_PROX_SHIFT       	(3)
84 #define CR0_PROX_MASK        	(0x1 << CR0_PROX_SHIFT)
85 
86 /*interrupt status of proximity sensor*/
87 #define CR0_INTP_CLEAR		0x0
88 
89 #define CR0_INTP_SHIFT       	(2)
90 #define CR0_INTP_MASK        	(0x1 << CR0_INTP_SHIFT)
91 
92 /*interrupt status of ambient sensor*/
93 #define CR0_INTA_CLEAR		0x0
94 
95 #define CR0_INTA_SHIFT       	(1)
96 #define CR0_INTA_MASK        	(0x1 << CR0_INTA_SHIFT)
97 
98 /*Word mode enable*/
99 #define CR0_WORD_EN		0x1
100 
101 #define CR0_WORD_SHIFT       	(0)
102 #define CR0_WORD_MASK        	(0x1 << CR0_WORD_SHIFT)
103 
104 
105 /*ALS fault queue depth for interrupt enent output*/
106 #define CR1_ALS_FQ_1		0x0
107 #define CR1_ALS_FQ_4		0x1
108 #define CR1_ALS_FQ_8		0x2
109 #define CR1_ALS_FQ_16		0x3
110 #define CR1_ALS_FQ_24		0x4
111 #define CR1_ALS_FQ_32		0x5
112 #define CR1_ALS_FQ_48		0x6
113 #define CR1_ALS_FQ_63		0x7
114 
115 #define CR1_ALS_FQ_SHIFT       	(5)
116 #define CR1_ALS_FQ_MASK        	(0x7 << CR1_ALS_FQ_SHIFT)
117 
118 /*resolution for ALS*/
119 #define CR1_ALS_RES_12BIT	0x0
120 #define CR1_ALS_RES_14BIT	0x1
121 #define CR1_ALS_RES_16BIT	0x2
122 #define CR1_ALS_RES_16BIT_2	0x3
123 
124 #define CR1_ALS_RES_SHIFT      	(3)
125 #define CR1_ALS_RES_MASK       	(0x3 << CR1_ALS_RES_SHIFT)
126 
127 /*sensing amplifier selection for ALS*/
128 #define CR1_ALS_GAIN_X1		0x0
129 #define CR1_ALS_GAIN_X2		0x1
130 #define CR1_ALS_GAIN_X4		0x2
131 #define CR1_ALS_GAIN_X8		0x3
132 #define CR1_ALS_GAIN_X16	0x4
133 #define CR1_ALS_GAIN_X32	0x5
134 #define CR1_ALS_GAIN_X64	0x6
135 #define CR1_ALS_GAIN_X128	0x7
136 
137 #define CR1_ALS_GAIN_SHIFT      (0)
138 #define CR1_ALS_GAIN_MASK       (0x7 << CR1_ALS_GAIN_SHIFT)
139 
140 
141 /*PS fault queue depth for interrupt event output*/
142 #define CR2_PS_FQ_1		0x0
143 #define CR2_PS_FQ_4		0x1
144 #define CR2_PS_FQ_8		0x2
145 #define CR2_PS_FQ_15		0x3
146 
147 #define CR2_PS_FQ_SHIFT      	(6)
148 #define CR2_PS_FQ_MASK       	(0x3 << CR2_PS_FQ_SHIFT)
149 
150 /*interrupt type setting */
151 /*low active*/
152 #define CR2_INT_LEVEL		0x0
153 /*low pulse*/
154 #define CR2_INT_PULSE		0x1
155 
156 #define CR2_INT_SHIFT      	(5)
157 #define CR2_INT_MASK       	(0x1 << CR2_INT_SHIFT)
158 
159 /*resolution for PS*/
160 #define CR2_PS_RES_12		0x0
161 #define CR2_PS_RES_14		0x1
162 #define CR2_PS_RES_16		0x2
163 #define CR2_PS_RES_16_2		0x3
164 
165 #define CR2_PS_RES_SHIFT      	(3)
166 #define CR2_PS_RES_MASK       	(0x3 << CR2_PS_RES_SHIFT)
167 
168 /*sensing amplifier selection for PS*/
169 #define CR2_PS_GAIN_1		0x0
170 #define CR2_PS_GAIN_2		0x1
171 #define CR2_PS_GAIN_4		0x2
172 #define CR2_PS_GAIN_8		0x3
173 #define CR2_PS_GAIN_16		0x4
174 #define CR2_PS_GAIN_32		0x5
175 #define CR2_PS_GAIN_64		0x6
176 #define CR2_PS_GAIN_128		0x7
177 
178 #define CR2_PS_GAIN_SHIFT      	(0)
179 #define CR2_PS_GAIN_MASK       	(0x7 << CR2_PS_GAIN_SHIFT)
180 
181 /*wait-time slot selection*/
182 #define CR3_WAIT_SEL_0		0x0
183 #define CR3_WAIT_SEL_4		0x1
184 #define CR3_WAIT_SEL_8		0x2
185 #define CR3_WAIT_SEL_16		0x3
186 
187 #define CR3_WAIT_SEL_SHIFT      (6)
188 #define CR3_WAIT_SEL_MASK       (0x3 << CR3_WAIT_SEL_SHIFT)
189 
190 /*IR-LED drive peak current setting*/
191 #define CR3_LEDDR_12_5		0x0
192 #define CR3_LEDDR_25		0x1
193 #define CR3_LEDDR_50		0x2
194 #define CR3_LEDDR_100		0x3
195 
196 #define CR3_LEDDR_SHIFT      	(4)
197 #define CR3_LEDDR_MASK       	(0x3 << CR3_LEDDR_SHIFT)
198 
199 /*INT pin source selection*/
200 #define CR3_INT_SEL_BATH	0x0
201 #define CR3_INT_SEL_ALS		0x1
202 #define CR3_INT_SEL_PS		0x2
203 #define CR3_INT_SEL_PSAPP	0x3
204 
205 #define CR3_INT_SEL_SHIFT      	(2)
206 #define CR3_INT_SEL_MASK       	(0x3 << CR3_INT_SEL_SHIFT)
207 
208 /*software reset for register and core*/
209 #define CR3_SOFTRST_EN		0x1
210 
211 #define CR3_SOFTRST_SHIFT      	(0)
212 #define CR3_SOFTRST_MASK       	(0x1 << CR3_SOFTRST_SHIFT)
213 
214 /*modulation frequency of LED driver*/
215 #define CR10_FREQ_DIV2		0x0
216 #define CR10_FREQ_DIV4		0x1
217 #define CR10_FREQ_DIV8		0x2
218 #define CR10_FREQ_DIV16		0x3
219 
220 #define CR10_FREQ_SHIFT      	(1)
221 #define CR10_FREQ_MASK       	(0x3 << CR10_FREQ_SHIFT)
222 
223 /*50/60 Rejection enable*/
224 #define CR10_REJ_5060_DIS	0x00
225 #define CR10_REJ_5060_EN	0x01
226 
227 #define CR10_REJ_5060_SHIFT     (0)
228 #define CR10_REJ_5060_MASK      (0x1 << CR10_REJ_5060_SHIFT)
229 
230 #define us5152_NUM_CACHABLE_REGS 0x12
231 
232 
sensor_active(struct i2c_client * client,int enable,int rate)233 static int sensor_active(struct i2c_client *client, int enable, int rate)
234 {
235 	//struct sensor_private_data *sensor =
236 	   // (struct sensor_private_data *) i2c_get_clientdata(client);
237 	int result = 0;
238 	char value = 0;
239 	int i = 0;
240 
241 	for(i=0; i<3; i++)
242 		{
243 			if(!enable)
244 			{
245 				value = sensor_read_reg(client, REGS_CR0);
246 				value |= PWR_MODE_DOWN_MASK;	//ShutDown_EN=1
247 				result = sensor_write_reg(client, REGS_CR0, value);
248 				if(result)
249 					return result;
250 			}
251 			else
252 			{
253 				value = sensor_read_reg(client, REGS_CR0);
254 				value &= PWR_MODE_OPERATE_MASK ; //Operation_EN=0
255 				result = sensor_write_reg(client, REGS_CR0, value);
256 				if(result)
257 					return result;
258 			}
259 
260 			if(!result)
261 			break;
262 		}
263 
264 		if(i>1)
265 		printk("%s:set %d times",__func__,i);
266 
267 
268 	//TODO:? function to be added here
269 
270 	return result;
271 
272 }
273 
274 
sensor_init(struct i2c_client * client)275 static int sensor_init(struct i2c_client *client)
276 {
277 	struct sensor_private_data *sensor =
278 	    (struct sensor_private_data *) i2c_get_clientdata(client);
279 	int result = 0;
280 	char value = 0;
281 
282 	result = sensor->ops->active(client,0,0);
283 	if(result)
284 	{
285 		printk("%s:line=%d,error\n",__func__,__LINE__);
286 		return result;
287 	}
288 
289 	sensor->status_cur = SENSOR_OFF;
290 
291 	value = sensor_read_reg(client, REGS_CHIP_ID); //read chip ids
292 	printk("us5152 chip id is %x!\n", value);
293 
294 	value = 0x01;//word accessing
295 
296 	result = sensor_write_reg(client, REGS_CR0, value);
297 	if(result)
298 	{
299 		printk("%s:line=%d,error\n",__func__,__LINE__);
300 		return result;
301 	}
302 
303 	return result;
304 }
305 
306 
us5152_value_report(struct input_dev * input,int data)307 static int us5152_value_report(struct input_dev *input, int data)
308 {
309 	unsigned char index = 0;
310 	if(data <= 10){
311 		index = 0;goto report;
312 	}
313 	else if(data <= 160){
314 		index = 1;goto report;
315 	}
316 	else if(data <= 225){
317 		index = 2;goto report;
318 	}
319 	else if(data <= 320){
320 		index = 3;goto report;
321 	}
322 	else if(data <= 640){
323 		index = 4;goto report;
324 	}
325 	else if(data <= 1280){
326 		index = 5;goto report;
327 	}
328 	else if(data <= 2600){
329 		index = 6;goto report;
330 	}
331 	else{
332 		index = 7;goto report;
333 	}
334 
335 report:
336 	input_report_abs(input, ABS_MISC, index);
337 	input_sync(input);
338 	return index;
339 }
340 
sensor_report_value(struct i2c_client * client)341 static int sensor_report_value(struct i2c_client *client)
342 {
343 	struct sensor_private_data *sensor =
344 	    (struct sensor_private_data *) i2c_get_clientdata(client);
345 	int result = 0;
346 	int value = 0;
347 	char index = 0;
348 	char buffer[2]= { 0 } ;
349 	int ret=0;
350 
351 	if(sensor->pdata->irq_enable)
352 	{
353 		if(sensor->ops->int_status_reg >= 0)
354 		{
355 			value = sensor_read_reg(client, sensor->ops->int_status_reg);
356 		}
357 
358 	}
359 
360 	//value = sensor_read_reg(client, sensor->ops->read_reg);  //TODO:? to be changed
361 	if(sensor->ops->read_len< 2) //12bit
362 	{
363 		printk("us5152 data read para num error ; len = %d\n ",sensor->ops->read_len);
364 		return -1;
365 	}
366 	memset(buffer , 0 , 2);
367 	do
368 	{
369 		*buffer = sensor->ops->read_reg;
370 		ret=sensor_rx_data(client,buffer,sensor->ops->read_len);
371 		if(ret<0)
372 			return ret;
373 	}
374 	while(0);
375 	value=buffer[1];
376 	value =((value << 8) | buffer[0]) & 0xffff;
377 	index = us5152_value_report(sensor->input_dev, value);  //now is 12bit
378 
379 	//printk("%s:%s result=0x%x,index=%d\n",__func__,sensor->ops->name, value,index);
380 	DBG("%s:%s result=%d,index=%d buffer[1]=0x%x , buffer[0]=0x%x \n",__func__,sensor->ops->name, value,index,buffer[1],buffer[0]);
381 
382 	return result;
383 }
384 
385 
386 static struct sensor_operate light_us5152_ops = {
387 	.name				= "ls_us5152",
388 	.type				= SENSOR_TYPE_LIGHT,	//sensor type and it should be correct
389 	.id_i2c				= LIGHT_ID_US5152,	//i2c id number
390 	.read_reg			= REGS_LBS_SENSOR,	//read data
391 	.read_len			= 2,			//data length
392 	.id_reg				= REGS_CHIP_ID,		//read device id from this register
393 	.id_data 			= 0x26,			//device id
394 	.precision			= 12,			//12 bits
395 	.ctrl_reg 			= REGS_CR0,		//enable or disable
396 	.int_status_reg 		= SENSOR_UNKNOW_DATA,	//intterupt status register
397 	.range				= {0,10},		//range
398 	.brightness                     = {10,4095},                          // brightness
399 	.trig				= IRQF_TRIGGER_LOW | IRQF_ONESHOT ,
400 	.active				= sensor_active,
401 	.init				= sensor_init,
402 	.report				= sensor_report_value,
403 };
404 /****************operate according to sensor chip:end************/
light_us5152_probe(struct i2c_client * client,const struct i2c_device_id * devid)405 static int light_us5152_probe(struct i2c_client *client,
406 			      const struct i2c_device_id *devid)
407 {
408 	return sensor_register_device(client, NULL, devid, &light_us5152_ops);
409 }
410 
light_us5152_remove(struct i2c_client * client)411 static int light_us5152_remove(struct i2c_client *client)
412 {
413 	return sensor_unregister_device(client, NULL, &light_us5152_ops);
414 }
415 
416 static const struct i2c_device_id light_us5152_id[] = {
417 	{"ls_us5152", LIGHT_ID_US5152},
418 	{}
419 };
420 
421 static struct i2c_driver light_us5152_driver = {
422 	.probe = light_us5152_probe,
423 	.remove = light_us5152_remove,
424 	.shutdown = sensor_shutdown,
425 	.id_table = light_us5152_id,
426 	.driver = {
427 		.name = "light_us5152",
428 	#ifdef CONFIG_PM
429 		.pm = &sensor_pm_ops,
430 	#endif
431 	},
432 };
433 
434 
435 module_i2c_driver(light_us5152_driver);
436 
437 MODULE_AUTHOR("Finley Huang finley_huang@upi-semi.com");
438 MODULE_DESCRIPTION("us5152 ambient light sensor driver");
439 MODULE_LICENSE("GPL");
440 MODULE_VERSION(DRIVER_VERSION);
441