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