1 #include <linux/kernel.h>
2 #include <linux/module.h>
3 #include <linux/init.h>
4 #include <linux/device.h>
8 #include <linux/delay.h>
10 #include <linux/sched.h>
12 #include <linux/sysctl.h>
13 #include <linux/miscdevice.h>
14 #include <linux/slab.h>
16 #include <asm/uaccess.h>
17 #include <linux/timer.h>
18 #include <linux/input.h>
19 #include <linux/ioctl.h>
20 //#include <mach/rk29_sdk_io.h>
21 #include <mach/board.h>
22 #include <linux/platform_device.h>
23 #ifdef CONFIG_HAS_EARLYSUSPEND
24 #include <linux/earlysuspend.h>
30 #define DBG(X...) printk(KERN_NOTICE X)
35 //#define CM3202_SD_IOPIN LIGHT_INT_IOPIN//light sensor int Pin <level=Low "ON"> <level=Hight "OFF">
36 //#define DATA_ADC_CHN 2 //SARADC_AIN[3]
39 #define LIGHTSENSOR_IOCTL_MAGIC 'l'
40 #define LIGHTSENSOR_IOCTL_GET_ENABLED _IOR(LIGHTSENSOR_IOCTL_MAGIC, 1, int *)
41 #define LIGHTSENSOR_IOCTL_ENABLE _IOW(LIGHTSENSOR_IOCTL_MAGIC, 2, int *)
42 #define LIGHTSENSOR_IOCTL_DISABLE _IOW(LIGHTSENSOR_IOCTL_MAGIC, 3, int *)
45 struct adc_client *client;
46 struct timer_list timer;
47 struct work_struct timer_work;
48 struct input_dev *input;
52 #ifdef CONFIG_HAS_EARLYSUSPEND
53 static struct early_suspend cm3202_early_suspend;
55 static struct cm3202_data *light;
57 static int cm3202_start(struct cm3202_data *data)
59 struct cm3202_data *cm3202 = data;
62 gpio_direction_output(cm3202->CM3202_SD,0);//level = 0 Sensor ON
63 cm3202->statue = SENSOR_ON;
64 cm3202->timer.expires = jiffies + 1*HZ;
65 add_timer(&cm3202->timer);
66 printk("========== cm3202 light sensor start ==========\n");
70 static int cm3202_stop(struct cm3202_data *data)
72 struct cm3202_data *cm3202 = data;
73 if(cm3202->statue == 0)
75 gpio_direction_output(cm3202->CM3202_SD,1);//level = 1 Sensor OFF
76 cm3202->statue = SENSOR_OFF;
77 del_timer(&cm3202->timer);
78 printk("========== cm3202 light sensor stop ==========\n");
82 #ifdef CONFIG_HAS_EARLYSUSPEND
83 static void cm3202_suspend(struct early_suspend *h)
85 struct cm3202_data *cm3202 = light;
87 printk("Light Sensor cm3202 enter suspend cm3202->status %d\n",cm3202->statue);
90 static void cm3202_resume(struct early_suspend *h)
92 struct cm3202_data *cm3202 = light;
94 printk("Light Sensor cm3202 enter resume cm3202->status %d\n",cm3202->statue);
97 static int cm3202_open(struct inode *indoe, struct file *file)
102 static int cm3202_release(struct inode *inode, struct file *file)
107 static int cm3202_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
109 unsigned long *argp = (unsigned char *)arg;
111 case LIGHTSENSOR_IOCTL_GET_ENABLED:
112 *argp = light->statue;
114 case LIGHTSENSOR_IOCTL_ENABLE:
125 static void cm3202_value_report(struct input_dev *input, int data)
127 unsigned char index = 0;
129 index = 0;goto report;
131 else if(data <= 160){
132 index = 1;goto report;
134 else if(data <= 225){
135 index = 2;goto report;
137 else if(data <= 320){
138 index = 3;goto report;
140 else if(data <= 640){
141 index = 4;goto report;
143 else if(data <= 1280){
144 index = 5;goto report;
146 else if(data <= 2600){
147 index = 6;goto report;
150 index = 7;goto report;
153 DBG("cm3202 report index = %d\n",index);
154 input_report_abs(input, ABS_MISC, index);
158 static void callback(struct adc_client *client, void *param, int result)
160 DBG("[chn%d] cm3202 report value: %d\n", client->chn, result);
163 static void adc_timer(unsigned long data)
165 struct cm3202_data *cm3202=(struct cm3202_data *)data;
166 schedule_work(&cm3202->timer_work);
168 static void adc_timer_work(struct work_struct *work)
171 struct cm3202_data *cm3202 = container_of(work, struct cm3202_data,timer_work);
172 adc_async_read(cm3202->client);
173 sync_read = adc_sync_read(cm3202->client);
174 cm3202_value_report(cm3202->input, sync_read);
176 cm3202->timer.expires = jiffies + 3*HZ;
177 add_timer(&cm3202->timer);
181 static struct file_operations cm3202_fops = {
182 .owner = THIS_MODULE,
183 .ioctl = cm3202_ioctl,
185 .release = cm3202_release,
188 static struct miscdevice cm3202_device = {
189 .minor = MISC_DYNAMIC_MINOR,
190 .name = "lightsensor",
191 .fops = &cm3202_fops,
194 static int cm3202_probe(struct platform_device *pdev)
196 struct cm3202_data *cm3202;
197 struct cm3202_platform_data *pdata = pdata = pdev->dev.platform_data;
199 DBG("============= cm3202 probe enter ==============\n");
200 cm3202 = kmalloc(sizeof(struct cm3202_data), GFP_KERNEL);
202 printk("cm3202 alloc memory err !!!\n");
204 goto alloc_memory_fail;
206 if(pdata->init_platform_hw)
207 pdata->init_platform_hw();
209 cm3202->CM3202_SD = pdata->CM3202_SD_IOPIN;
210 DBG("===============================cm3202==========================\ncm3202_ADC_CHN = %d",pdata->DATA_ADC_CHN);
212 cm3202->client = adc_register(pdata->DATA_ADC_CHN, callback, NULL);
213 cm3202->statue = SENSOR_OFF;
214 cm3202->input = input_allocate_device();
215 if (!cm3202->input) {
217 printk(KERN_ERR"cm3202: Failed to allocate input device\n");
218 goto exit_input_allocate_device_failed;
220 set_bit(EV_ABS, cm3202->input->evbit);
221 /* light sensor data */
222 input_set_abs_params(cm3202->input, ABS_MISC, 0, 0x3ff, 0, 0);
223 cm3202->input->name = "lightsensor";
225 err = input_register_device(cm3202->input);
227 printk(KERN_ERR"cm3202: Unable to register input device: %s\n",cm3202->input->name);
228 goto exit_input_register_device_failed;
231 ret = gpio_request(CM3202_SD_IOPIN, "cm3202_sd");
233 printk( "failed to request cm3202 SD GPIO%d\n",CM3202_SD_IOPIN);
234 goto exit_gpio_request_fail;
236 DBG("cm3202 request INT inpin ok !!!");
237 gpio_pull_updown(CM3202_SD_IOPIN,GPIOPullDown); */
238 INIT_WORK(&cm3202->timer_work, adc_timer_work);
239 setup_timer(&cm3202->timer, adc_timer, (unsigned long)cm3202);
240 err = misc_register(&cm3202_device);
242 printk(KERN_ERR"cm3202_probe: lightsensor_device register failed\n");
243 goto exit_misc_register_fail;
245 printk("lightsensor cm3202 driver created !\n");
246 //cm3202_start(light);
247 #ifdef CONFIG_HAS_EARLYSUSPEND
248 cm3202_early_suspend.suspend = cm3202_suspend;
249 cm3202_early_suspend.resume = cm3202_resume;
250 cm3202_early_suspend.level = 0x2;
251 register_early_suspend(&cm3202_early_suspend);
254 exit_misc_register_fail:
255 gpio_free(pdata->CM3202_SD_IOPIN);
256 input_unregister_device(cm3202->input);
257 exit_input_register_device_failed:
258 input_free_device(cm3202->input);
259 exit_input_allocate_device_failed:
262 printk("%s error\n",__FUNCTION__);
266 static int cm3202_remove(struct platform_device *pdev)
268 struct cm3202_data *cm3202 = light;
270 input_free_device(cm3202->input);
271 input_unregister_device(cm3202->input);
272 misc_deregister(&cm3202_device);
276 static struct platform_driver cm3202_driver = {
277 .probe = cm3202_probe,
278 .remove = cm3202_remove,
280 .owner = THIS_MODULE,
281 .name = "lightsensor",
285 static int __init cm3202_init(void)
287 return platform_driver_register(&cm3202_driver);
290 static void __exit cm3202_exit(void)
292 platform_driver_unregister(&cm3202_driver);
295 module_init(cm3202_init);
296 module_exit(cm3202_exit);