Merge branch 'develop' of 10.10.10.29:/home/rockchip/kernel into develop
[firefly-linux-kernel-4.4.55.git] / drivers / input / lightsensor / rk29_lightsensor.c
1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/init.h>
4 #include <linux/fs.h>
5 #include <linux/interrupt.h>
6 #include <linux/sched.h>
7 #include <linux/pm.h>
8 #include <linux/sysctl.h>
9 #include <linux/proc_fs.h>
10 #include <linux/platform_device.h>
11 #include <linux/miscdevice.h>
12 #include <linux/slab.h>
13 #include <asm/gpio.h>
14 #include <asm/uaccess.h>
15 #include <linux/timer.h>
16 #include <linux/input.h>
17 #include <linux/adc.h>
18 #include <linux/delay.h>
19 #include <linux/string.h>
20
21
22 #include <mach/rk29_lightsensor.h>
23
24 struct rk29_lsr_platform_data *lightsensor;
25 static void lsr_report_value(struct input_dev *input_dev, int value)
26 {
27     input_report_abs(input_dev, ABS_X, value);
28     //input_sync(input_dev);
29 }
30
31
32 static inline void timer_callback(unsigned long data)
33 {
34         int ret;
35         unsigned int rate;
36         adc_async_read(lightsensor->client);
37         mutex_lock(&lightsensor->lsr_mutex);
38         rate = lightsensor->rate;
39         mutex_unlock(&lightsensor->lsr_mutex);
40         if(lightsensor->client->result != lightsensor->oldresult)
41                 {
42                         lsr_report_value(lightsensor->input_dev, lightsensor->client->result);
43                         lightsensor->oldresult = lightsensor->client->result;
44                 }
45         ret = mod_timer( &lightsensor->timer, jiffies + msecs_to_jiffies(RATE(rate)));
46         if(ret)
47                 printk("Error in mod_timer\n");
48 }
49 static inline void set_lsr_value(bool state)
50 {
51         if(state)
52                 lightsensor->lsr_state = 1;
53         else
54                 lightsensor->lsr_state = 0;
55         gpio_direction_output(LSR_GPIO, lightsensor->lsr_state);
56         gpio_set_value(LSR_GPIO, lightsensor->lsr_state);       
57 }
58
59 static inline unsigned int get_lsr_value(void)
60 {
61         if(0 == lightsensor->lsr_state)
62                 return 0;
63         else
64                 return 1;
65 }
66
67 static inline unsigned int get_adc_value(void)
68 {
69
70         return lightsensor->client->result;
71 }
72
73 static inline unsigned int set_lsr_rate(unsigned int value)
74 {
75         mutex_lock(&lightsensor->lsr_mutex);
76         if(value <= 0)
77                 value = 1;
78         if(value >= 100)
79                 value = 100;
80         lightsensor->rate = value;
81         mutex_unlock(&lightsensor->lsr_mutex);
82         return 0;
83 }
84 static inline unsigned int set_lsr_timer(unsigned int value)
85 {
86         if(value > 0)
87                 {
88                         if(1 != lightsensor->timer_on)
89                                 {
90                                         add_timer(&lightsensor->timer);
91                                         lightsensor->timer_on = 1;
92                                 }
93                                 
94                 }
95         if(value == 0)
96                 {
97                         if(0 != lightsensor->timer_on)
98                                 {
99                                         del_timer(&lightsensor->timer);
100                                         lightsensor->timer_on = 0;
101                                 }
102                                 
103                 }               
104         return 0;
105 }
106
107
108
109 static ssize_t lsr_store_value(struct device *dev,
110                                           struct device_attribute *attr,
111                                           const char *buf, size_t count)
112 {
113         unsigned long val;
114         if(0 == count)
115                 return count;
116         if (strict_strtoul(buf, 10, &val) < 0)
117                 return -EINVAL;
118         if(val)
119                 set_lsr_value(true);
120         else
121                 set_lsr_value(false);
122         return count;
123 }
124
125 static ssize_t lsr_show_value(struct device *dev,
126                                  struct device_attribute *attr, char *buf)
127 {
128         return sprintf(buf, "lsr value:%d\nadc value:%d\n", get_lsr_value(),get_adc_value());   
129 }
130
131 static DEVICE_ATTR(value, S_IWUSR|S_IRUGO, lsr_show_value, lsr_store_value );
132
133 static struct attribute *lsr_attributes[] = {
134         &dev_attr_value.attr,
135         NULL
136 };
137
138 static const struct attribute_group lsr_attr_group = {
139         .attrs = lsr_attributes,
140 };
141 static int rk29_lsr_io_init(struct platform_device *dev)
142 {
143         int err;
144         struct platform_device *pdev = dev;
145         struct rk29_lsr_platform_data *pdata = pdev->dev.platform_data;
146
147         err = gpio_request(pdata->gpio, pdata->desc ?: "rk29-lsr");
148         if (err) {
149                 gpio_free(pdata->gpio);
150                 printk("-------request RK29_PIN6_PB1 fail--------\n");
151                 return -1;
152         }
153
154         gpio_direction_output(pdata->gpio, pdata->active_low);
155         gpio_set_value(pdata->gpio, pdata->active_low);
156         set_lsr_value(STARTUP_LEV_LOW);
157         err = sysfs_create_group(&pdev->dev.kobj, &lsr_attr_group);
158         return 0;
159 }
160 static int rk29_lsr_io_deinit(struct platform_device *dev)
161 {
162         struct platform_device *pdev = dev;
163         struct rk29_lsr_platform_data *pdata = pdev->dev.platform_data;
164
165         gpio_direction_output(pdata->gpio, pdata->active_low);
166         gpio_set_value(pdata->gpio, pdata->active_low);
167
168         gpio_free(pdata->gpio);
169         sysfs_remove_group(&pdev->dev.kobj, &lsr_attr_group);
170         return 0;
171 }
172 static void callback(struct adc_client *client, void *callback_param, int result)
173 {
174         client->result = result;
175 }
176 static int rk29_lsr_adc_init(struct platform_device *dev)
177 {
178         struct rk29_lsr_platform_data *pdata = dev->dev.platform_data;
179         pdata->client = adc_register(pdata->adc_chn, callback, "lsr_adc");
180         if(!pdata->client)
181                 return -EINVAL;
182         mutex_init(&pdata->lsr_mutex);
183         return 0;
184 }
185 static void rk29_lsr_adc_deinit(struct platform_device *dev)
186 {
187         struct rk29_lsr_platform_data *pdata = dev->dev.platform_data;
188         adc_unregister(pdata->client);
189         mutex_destroy(&pdata->lsr_mutex);
190 }
191
192 static void rk29_lsr_timer_init(struct platform_device *dev)
193 {
194         int ret;
195         struct rk29_lsr_platform_data *pdata = dev->dev.platform_data;
196         setup_timer(&pdata->timer, timer_callback, 0);
197         lightsensor->timer_on = 1;
198         ret = mod_timer( &pdata->timer, jiffies + msecs_to_jiffies(pdata->delay_time) );
199         if(ret)
200                 printk("Error in mod_timer\n");
201         return ;
202 }
203 static void rk29_lsr_timer_deinit(struct platform_device *dev)
204 {
205         struct rk29_lsr_platform_data *pdata = dev->dev.platform_data;
206         del_timer(&pdata->timer);
207         lightsensor->timer_on = 0;
208 }
209
210 static void rk29_lsr_input_init(struct platform_device *dev)
211 {
212         int ret;
213         struct rk29_lsr_platform_data *pdata = dev->dev.platform_data;
214         pdata->input_dev = input_allocate_device();
215         if (!pdata->input_dev) {
216                 printk(KERN_ERR"rk29_lsr_input_init: Failed to allocate input device\n");
217                 goto init_input_register_device_failed;
218         }
219         pdata->input_dev->name = "lsensor";
220         pdata->input_dev->dev.parent = &dev->dev;
221         pdata->input_dev->evbit[0] = BIT(EV_ABS);
222         input_set_abs_params(pdata->input_dev,ABS_X,0,0x3ff,0,0);
223         ret = input_register_device(pdata->input_dev);
224         return ;
225 init_input_register_device_failed:
226 input_free_device(pdata->input_dev);
227 }
228
229 static void rk29_lsr_input_deinit(struct platform_device *dev)
230 {
231         struct rk29_lsr_platform_data *pdata = dev->dev.platform_data;
232         input_unregister_device(pdata->input_dev);
233     input_free_device(pdata->input_dev);
234 }
235
236 static int __devinit lsr_probe(struct platform_device *pdev)
237 {
238         lightsensor = kzalloc(sizeof(struct rk29_lsr_platform_data), GFP_KERNEL);
239         if(!lightsensor)
240         {
241         dev_err(&pdev->dev, "no memory for state\n");
242         goto err_kzalloc_lightsensor;
243     }
244         lightsensor->gpio               = LSR_GPIO;
245         lightsensor->desc               = "rk29-lsr";
246         lightsensor->adc_chn    = 1;
247         lightsensor->delay_time = 1000;
248         lightsensor->rate               = 100;
249         lightsensor->oldresult  = 0;
250         lightsensor->active_low = STARTUP_LEV_LOW;
251         pdev->dev.platform_data = lightsensor; 
252         rk29_lsr_io_init(pdev);
253         rk29_lsr_adc_init(pdev);
254         rk29_lsr_timer_init(pdev);
255         rk29_lsr_input_init(pdev);
256         return 0;
257
258 err_kzalloc_lightsensor:
259         kfree(lightsensor);
260         return 0; 
261
262 }
263
264 static int __devexit lsr_remove(struct platform_device *pdev)
265 {
266         rk29_lsr_io_deinit(pdev);
267         rk29_lsr_adc_deinit(pdev);
268         rk29_lsr_timer_deinit(pdev);
269         rk29_lsr_input_deinit(pdev);
270         kfree(lightsensor);
271         return 0;
272 }
273
274 static int lsr_suspend(struct platform_device *pdev, pm_message_t state)
275 {
276         set_lsr_timer(0);
277         set_lsr_value(LSR_OFF);
278         return 0;
279 }
280
281 static int lsr_resume(struct platform_device *pdev)
282 {
283         set_lsr_timer(1);
284         set_lsr_value(LSR_ON);
285         return 0; 
286 }
287
288
289
290 static struct platform_driver lsr_device_driver = {
291         .probe          = lsr_probe,
292         .remove         = __devexit_p(lsr_remove),
293         .suspend        = lsr_suspend,
294         .resume         = lsr_resume,
295         .driver         = {
296                 .name   = LSR_NAME,
297                 .owner  = THIS_MODULE,
298         }
299 };
300
301 static int lsr_adc_open(struct inode * inode, struct file * file)
302 {
303         set_lsr_value(LSR_ON);
304         return 0;
305 }
306
307 static int lsr_adc_ioctl(struct tty_struct * tty,struct file * file,unsigned int cmd, unsigned long arg)
308 {
309         int ret = 0;
310         switch(cmd)
311                 {
312                         case LSR_IOCTL_ENABLE:
313                                 set_lsr_value(arg);
314                                 break;
315                         case LSR_IOCTL_SETRATE:
316                                 set_lsr_rate(arg);
317                                 break;
318                         case LSR_IOCTL_DEVNAME:
319                                 ret = copy_to_user((void __user *)arg,lightsensor->input_dev->name,strlen(lightsensor->input_dev->name)+1);
320                                 break;
321                         case LSR_IOCTL_SWICTH:
322                                 set_lsr_timer(arg);
323                                 break;
324                         default:
325                                 break;
326                 }
327         return ret;
328 }
329
330 static ssize_t lsr_adc_read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
331 {
332         int ret;
333         ret = copy_to_user(userbuf,&lightsensor->client->result,bytes);
334         return ret;
335 }
336
337 static struct file_operations lsr_adc_fops = {
338         .owner          = THIS_MODULE,
339         .open           = lsr_adc_open,
340         .read           = lsr_adc_read,
341         .ioctl          = lsr_adc_ioctl,
342 };
343
344 static struct miscdevice misc_lsr_adc_device = {
345         .minor  = MISC_DYNAMIC_MINOR,
346         .name   = LSR_NAME,
347         .fops   = &lsr_adc_fops,
348 };
349
350 static int __init lsr_init(void)
351 {
352         platform_driver_register(&lsr_device_driver);
353         misc_register(&misc_lsr_adc_device);
354         return 0;
355 }
356
357 static void __exit lsr_exit(void)
358 {
359         platform_driver_unregister(&lsr_device_driver);
360         misc_deregister(&misc_lsr_adc_device);
361 }
362
363 module_init(lsr_init);
364 module_exit(lsr_exit);
365
366 MODULE_LICENSE("GPL");
367 MODULE_AUTHOR("Seven Huang <sevenxuemin@sina.com>");
368 MODULE_DESCRIPTION("Light sensor for Backlight");
369 MODULE_ALIAS("platform:gpio-lightsensor");