1 /* drivers/input/misc/isl29028.c
3 * Copyright (C) 2010 ROCK-CHIPS, Inc.
4 * Author: eric <linjh@rock-chips.com>
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.
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.
17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/i2c.h>
20 #include <linux/irq.h>
21 #include <linux/gpio.h>
22 #include <linux/input.h>
23 #include <linux/platform_device.h>
25 #include <linux/uaccess.h>
26 #include <linux/miscdevice.h>
27 #include <linux/circ_buf.h>
28 #include <linux/interrupt.h>
31 #ifdef CONFIG_HAS_EARLYSUSPEND
32 #include <linux/earlysuspend.h>
35 #include <linux/delay.h>
36 #include <linux/wait.h>
42 #define D(x...) printk(x)
47 #define ISL_REG_CONFIG (0x01)
48 #define PROX_EN (1 << 7)
49 #define PROX_SLP(x) (x << 4)
50 #define PROX_DR_110 (0 << 3)
51 #define PROX_DR_220 (1 << 3)
52 #define ALS_EN (1 << 2)
53 #define ALS_RANGE_H (1 << 1)
54 #define ALS_RANGE_L (0 << 1)
55 #define ALS_MODE (1 << 0)
57 #define ISL_REG_INT (0x02)
58 #define PROX_FLAG_MASK ~(1 << 7)
59 #define LS_FLAG_MASK ~(1 << 3)
60 #define PROX_PRST(x) (x << 5)
61 #define ALS_PRST(x) (x << 1)
62 #define INT_AND (1 << 0)
63 #define INT_OR (0 << 0)
65 #define ISL_REG_PROX_LT (0x03)
66 #define ISL_REG_PROX_HT (0x04)
67 #define PROX_LT (0x90)
68 #define PROX_HT (0xA0)
70 #define ISL_REG_PROX_DATA (0x08)
71 #define ISL_REG_ALSIR_LDATA (0x09)
72 #define ISL_REG_ALSIR_HDATA (0x0a)
74 struct isl29028_data {
75 struct input_dev *psensor_input_dev;
76 struct input_dev *lsensor_input_dev;
77 struct i2c_client *client;
78 struct delayed_work p_work; //for psensor
79 struct delayed_work l_work; //for light sensor
85 #ifdef CONFIG_HAS_EARLYSUSPEND
86 static struct early_suspend isl29028_early_suspend;
91 static const int luxValues[8] = {
97 static int isl29028_read_reg(struct i2c_client *client, char reg, char *value)
100 struct i2c_msg msg[2];
101 struct i2c_adapter *adap = client->adapter;
103 msg[0].addr = client->addr;
104 msg[0].flags = client->flags;
106 msg[0].buf = (char *)®
107 msg[0].scl_rate = 400 * 1000;
109 msg[1].addr = client->addr;
110 msg[1].flags = client->flags | I2C_M_RD;
112 msg[1].buf = (char *)value;
113 msg[1].scl_rate = 400 * 1000;
115 if ((ret = i2c_transfer(adap, (struct i2c_msg *)&msg, 2)) < 2) {
116 D("%s: read isl29028 register %#x failure\n", __FUNCTION__, reg);
123 static int isl29028_write_reg(struct i2c_client *client, char reg, char value)
128 struct i2c_adapter *adap = client->adapter;
133 msg.addr = client->addr;
134 msg.flags = client->flags;
136 msg.buf = (char *)&buf;
137 msg.scl_rate = 400 * 1000;
140 if ((ret = i2c_transfer(adap, (struct i2c_msg *)&msg, 1)) < 1) {
141 D("%s: read isl29028 register %#x failure\n", __FUNCTION__, reg);
148 static void isl29028_psensor_work_handler(struct work_struct *work)
150 struct isl29028_data *isl = (struct isl29028_data *)container_of(work, struct isl29028_data, p_work.work);
151 char reg, value, int_flag;
153 mutex_lock(&isl->lock);
155 isl29028_read_reg(isl->client, reg, (char *)&int_flag);
157 if (!(int_flag >> 7)) {
158 D("line %d: input_report_abs 1 \n", __LINE__);
159 input_report_abs(isl->psensor_input_dev, ABS_DISTANCE, 1);
160 input_sync(isl->psensor_input_dev);
163 if (int_flag & 0x08) {
164 D("line %d; light sensor interrupt\n", __LINE__);
165 isl29028_write_reg(isl->client, reg, int_flag & 0xf7);
168 reg = ISL_REG_PROX_DATA;
169 isl29028_read_reg(isl->client, reg, (char *)&value);
170 //D("%s: int is %#x\n", __FUNCTION__, int_flag);
171 D("%s: prox_int is %d\n", __FUNCTION__, (int_flag >> 7 ));
172 D("%s: prox_data is %#x\n", __FUNCTION__, value);
173 mutex_unlock(&isl->lock);
175 enable_irq(isl->irq);
178 static irqreturn_t isl29028_psensor_irq_handler(int irq, void *data)
180 struct isl29028_data *isl = (struct isl29028_data *)data;
181 D("line %d, input_report_abs 0 \n", __LINE__);
182 input_report_abs(isl->psensor_input_dev, ABS_DISTANCE, 0);
183 input_sync(isl->psensor_input_dev);
185 disable_irq_nosync(isl->irq);
186 schedule_delayed_work(&isl->p_work, msecs_to_jiffies(420));
191 static int isl29028_psensor_enable(struct i2c_client *client)
195 struct isl29028_data *isl = (struct isl29028_data *)i2c_get_clientdata(client);
197 mutex_lock(&isl->lock);
198 reg = ISL_REG_CONFIG;
199 ret = isl29028_read_reg(client, reg, &value);
201 ret = isl29028_write_reg(client, reg, value);
203 ret = isl29028_read_reg(client, reg, &value);
204 D("%s: configure reg value %#x ...\n", __FUNCTION__, value);
206 mutex_unlock(&isl->lock);
208 //enable_irq(isl->irq);
213 static int isl29028_psensor_disable(struct i2c_client *client)
215 char ret, reg, reg2, value, value2;
216 struct isl29028_data *isl = (struct isl29028_data *)i2c_get_clientdata(client);
218 mutex_lock(&isl->lock);
220 reg = ISL_REG_CONFIG;
221 ret = isl29028_read_reg(client, reg, &value);
223 ret = isl29028_write_reg(client, reg, value);
226 ret = isl29028_read_reg(client, reg2, &value2);
227 value2 &= PROX_FLAG_MASK;
228 ret = isl29028_write_reg(client, reg2, value2);
231 ret = isl29028_read_reg(client, reg, &value);
232 ret = isl29028_read_reg(client, reg2, &value2);
233 D("%s: configure reg value %#x ...\n", __FUNCTION__, value);
234 D("%s: interrupt reg value %#x ...\n", __FUNCTION__, value2);
236 mutex_unlock(&isl->lock);
238 disable_irq(isl->irq);
239 cancel_delayed_work_sync(&isl->p_work);
240 enable_irq(isl->irq);
245 static int isl29028_psensor_open(struct inode *inode, struct file *file);
246 static int isl29028_psensor_release(struct inode *inode, struct file *file);
247 static long isl29028_psensor_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
249 static int misc_ps_opened = 0;
250 static struct file_operations isl29028_psensor_fops = {
251 .owner = THIS_MODULE,
252 .open = isl29028_psensor_open,
253 .release = isl29028_psensor_release,
254 .unlocked_ioctl = isl29028_psensor_ioctl
257 static struct miscdevice isl29028_psensor_misc = {
258 .minor = MISC_DYNAMIC_MINOR,
260 .fops = &isl29028_psensor_fops
263 static int isl29028_psensor_open(struct inode *inode, struct file *file)
265 // struct i2c_client *client =
266 // container_of (isl29028_psensor_misc.parent, struct i2c_client, dev);
272 //return isl29028_psensor_enable(client);
275 static int isl29028_psensor_release(struct inode *inode, struct file *file)
277 // struct i2c_client *client =
278 // container_of (isl29028_psensor_misc.parent, struct i2c_client, dev);
282 //return isl29028_psensor_disable(client);
285 static long isl29028_psensor_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
287 char reg, val, enabled;
288 struct i2c_client *client =
289 container_of (isl29028_psensor_misc.parent, struct i2c_client, dev);
290 struct isl29028_data *isl = (struct isl29028_data *)i2c_get_clientdata(client);
292 D("%s cmd %d\n", __func__, _IOC_NR(cmd));
294 case PSENSOR_IOCTL_ENABLE:
295 if (get_user(val, (unsigned long __user *)arg))
298 return isl29028_psensor_enable(client);
300 return isl29028_psensor_disable(client);
302 case PSENSOR_IOCTL_GET_ENABLED:
303 mutex_lock(&isl->lock);
304 reg = ISL_REG_CONFIG;
305 isl29028_read_reg(client, reg, &val);
306 enabled = (val & (1 << 7)) ? 1 : 0;
307 mutex_unlock(&isl->lock);
308 return put_user(enabled, (unsigned long __user *)arg);
311 pr_err("%s: invalid cmd %d\n", __func__, _IOC_NR(cmd));
316 static int register_psensor_device(struct i2c_client *client, struct isl29028_data *isl)
318 struct input_dev *input_dev;
321 D("%s: allocating input device\n", __func__);
322 input_dev = input_allocate_device();
324 dev_err(&client->dev,"%s: could not allocate input device for psensor\n", __FUNCTION__);
329 isl->psensor_input_dev = input_dev;
330 input_set_drvdata(input_dev, isl);
332 input_dev->name = "proximity";
334 set_bit(EV_ABS, input_dev->evbit);
335 input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);
337 D("%s: registering input device\n", __func__);
338 rc = input_register_device(input_dev);
340 pr_err("%s: could not register input device for psensor\n", __func__);
341 goto err_free_input_device;
344 D("%s: registering misc device for psensor\n", __func__);
345 rc = misc_register(&isl29028_psensor_misc);
347 pr_err("%s: could not register misc device\n", __func__);
348 goto err_unregister_input_device;
351 isl29028_psensor_misc.parent = &client->dev;
352 //misc_deregister(&isl29028_psensor_misc);
354 INIT_DELAYED_WORK(&isl->p_work, isl29028_psensor_work_handler);
356 rc = gpio_request(client->irq, "isl29028 irq");
358 pr_err("%s: request gpio %d failed \n", __func__, client->irq);
359 goto err_unregister_misc;
361 rc = gpio_direction_input(client->irq);
363 pr_err("%s: failed set gpio input\n", __FUNCTION__);
366 gpio_pull_updown(client->irq, GPIOPullUp);
367 isl->irq = gpio_to_irq(client->irq);
369 rc = request_irq(isl->irq, isl29028_psensor_irq_handler,
370 IRQ_TYPE_LEVEL_LOW, client->name, (void *)isl);
372 dev_err(&client->dev,"request_irq failed for gpio %d (%d)\n", client->irq, rc);
379 gpio_free(client->irq);
381 misc_deregister(&isl29028_psensor_misc);
382 err_unregister_input_device:
383 input_unregister_device(input_dev);
384 err_free_input_device:
385 input_free_device(input_dev);
390 static void unregister_psensor_device(struct i2c_client *client, struct isl29028_data *isl)
392 misc_deregister(&isl29028_psensor_misc);
393 input_unregister_device(isl->psensor_input_dev);
394 input_free_device(isl->psensor_input_dev);
397 #define LSENSOR_POLL_PROMESHUTOK 1000
399 static int isl29028_lsensor_enable(struct i2c_client *client)
403 struct isl29028_data *isl = (struct isl29028_data *)i2c_get_clientdata(client);
405 mutex_lock(&isl->lock);
407 reg = ISL_REG_CONFIG;
408 ret = isl29028_read_reg(client, reg, &value);
410 ret = isl29028_write_reg(client, reg, value);
413 ret = isl29028_read_reg(client, reg, &value);
414 D("%s: configure reg value %#x ...\n", __FUNCTION__, value);
417 mutex_unlock(&isl->lock);
419 schedule_delayed_work(&(isl->l_work), msecs_to_jiffies(LSENSOR_POLL_PROMESHUTOK));
424 static int isl29028_lsensor_disable(struct i2c_client *client)
426 char ret, reg, reg2, value, value2;
427 struct isl29028_data *isl = (struct isl29028_data *)i2c_get_clientdata(client);
429 cancel_delayed_work_sync(&(isl->l_work));
431 mutex_lock(&isl->lock);
433 reg = ISL_REG_CONFIG;
434 ret = isl29028_read_reg(client, reg, &value);
436 ret = isl29028_write_reg(client, reg, value);
439 ret = isl29028_read_reg(client, reg2, &value2);
440 value2 &= LS_FLAG_MASK;
441 ret = isl29028_write_reg(client, reg2, value2);
444 ret = isl29028_read_reg(client, reg, &value);
445 ret = isl29028_read_reg(client, reg2, &value2);
446 D("%s: configure reg value %#x ...\n", __FUNCTION__, value);
447 D("%s: interrupt reg value %#x ...\n", __FUNCTION__, value2);
450 mutex_unlock(&isl->lock);
455 static int luxValue_to_level(int value)
458 if (value >= luxValues[7])
460 if (value <= luxValues[0])
463 if (value>=luxValues[i] && value<luxValues[i+1])
468 static void isl29028_lsensor_work_handler(struct work_struct *work)
470 struct isl29028_data *isl = (struct isl29028_data *)container_of(work, struct isl29028_data, l_work.work);
471 char reg, l_value, h_value;
472 unsigned int als_value;
475 mutex_lock(&isl->lock);
476 reg = ISL_REG_ALSIR_LDATA;
477 isl29028_read_reg(isl->client, reg, (char *)&l_value);
479 reg = ISL_REG_ALSIR_HDATA;
480 isl29028_read_reg(isl->client, reg, (char *)&h_value);
482 mutex_unlock(&isl->lock);
485 als_value = (als_value << 8) | l_value;
488 D("%s: ls_data is %#x\n", __FUNCTION__, als_value);
491 level = luxValue_to_level(als_value);
494 D("%s: ls_level is %d\n", __FUNCTION__, level);
497 if (level != g_lightlevel) {
498 g_lightlevel = level;
499 input_report_abs(isl->lsensor_input_dev, ABS_MISC, level);
500 input_sync(isl->lsensor_input_dev);
502 schedule_delayed_work(&(isl->l_work), msecs_to_jiffies(LSENSOR_POLL_PROMESHUTOK));
505 static int isl29028_lsensor_open(struct inode *inode, struct file *file);
506 static int isl29028_lsensor_release(struct inode *inode, struct file *file);
507 static long isl29028_lsensor_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
509 static int misc_ls_opened = 0;
510 static struct file_operations isl29028_lsensor_fops = {
511 .owner = THIS_MODULE,
512 .open = isl29028_lsensor_open,
513 .release = isl29028_lsensor_release,
514 .unlocked_ioctl = isl29028_lsensor_ioctl
517 static struct miscdevice isl29028_lsensor_misc = {
518 .minor = MISC_DYNAMIC_MINOR,
519 .name = "lightsensor",
520 .fops = &isl29028_lsensor_fops
523 static int isl29028_lsensor_open(struct inode *inode, struct file *file)
525 // struct i2c_client *client =
526 // container_of (isl29028_lsensor_misc.parent, struct i2c_client, dev);
532 //return isl29028_lsensor_enable(client);
535 static int isl29028_lsensor_release(struct inode *inode, struct file *file)
538 // struct i2c_client *client =
539 // container_of (isl29028_lsensor_misc.parent, struct i2c_client, dev);
543 //return isl29028_lsensor_disable(client);
546 static long isl29028_lsensor_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
548 char reg, val, enabled;
549 struct i2c_client *client =
550 container_of (isl29028_lsensor_misc.parent, struct i2c_client, dev);
551 struct isl29028_data *isl = (struct isl29028_data *)i2c_get_clientdata(client);
553 D("%s cmd %d\n", __func__, _IOC_NR(cmd));
555 case LIGHTSENSOR_IOCTL_ENABLE:
556 if (get_user(val, (unsigned long __user *)arg))
559 return isl29028_lsensor_enable(client);
561 return isl29028_lsensor_disable(client);
563 case LIGHTSENSOR_IOCTL_GET_ENABLED:
564 mutex_lock(&isl->lock);
565 reg = ISL_REG_CONFIG;
566 isl29028_read_reg(client, reg, &val);
567 mutex_unlock(&isl->lock);
568 enabled = (val & (1 << 2)) ? 1 : 0;
569 return put_user(enabled, (unsigned long __user *)arg);
572 pr_err("%s: invalid cmd %d\n", __func__, _IOC_NR(cmd));
577 static int register_lsensor_device(struct i2c_client *client, struct isl29028_data *isl)
579 struct input_dev *input_dev;
582 D("%s: allocating input device\n", __func__);
583 input_dev = input_allocate_device();
585 dev_err(&client->dev,"%s: could not allocate input device forlsensor\n", __FUNCTION__);
590 isl->lsensor_input_dev = input_dev;
591 input_set_drvdata(input_dev, isl);
593 input_dev->name = "lightsensor-level";
595 set_bit(EV_ABS, input_dev->evbit);
596 input_set_abs_params(input_dev, ABS_MISC, 0, 8, 0, 0);
598 D("%s: registering input device\n", __func__);
599 rc = input_register_device(input_dev);
601 pr_err("%s: could not register input device for lsensor\n", __func__);
602 goto err_free_input_device;
605 D("%s: registering misc device for lsensor\n", __func__);
606 rc = misc_register(&isl29028_lsensor_misc);
608 pr_err("%s: could not register misc device\n", __func__);
609 goto err_unregister_input_device;
612 isl29028_lsensor_misc.parent = &client->dev;
614 INIT_DELAYED_WORK(&isl->l_work, isl29028_lsensor_work_handler);
618 err_unregister_input_device:
619 input_unregister_device(input_dev);
620 err_free_input_device:
621 input_free_device(input_dev);
626 static void unregister_lsensor_device(struct i2c_client *client, struct isl29028_data *isl)
628 misc_deregister(&isl29028_lsensor_misc);
629 input_unregister_device(isl->lsensor_input_dev);
630 input_free_device(isl->lsensor_input_dev);
633 static int isl29028_config(struct i2c_client *client)
637 struct isl29028_data *isl = (struct isl29028_data *)i2c_get_clientdata(client);
639 D("%s: init isl29028 all register\n", __func__);
641 mutex_lock(&isl->lock);
643 /*********************** power on **************************/
646 if ((ret = i2c_master_send(client, buf, 2)) < 2) {
647 printk("%s: config isl29028 register %#x err %d\n", __FUNCTION__, buf[0], ret);
652 if ((ret = i2c_master_send(client, buf, 2)) < 2) {
653 printk("%s: config isl29028 register %#x err %d\n", __FUNCTION__, buf[0], ret);
656 buf[0] = ISL_REG_CONFIG;
658 if ((ret = i2c_master_send(client, buf, 2)) < 2) {
659 printk("%s: config isl29028 register %#x err %d\n", __FUNCTION__, buf[0], ret);
663 mutex_unlock(&isl->lock);
668 /***********************config**************************/
670 buf[0] = ISL_REG_CONFIG;
671 buf[1] = /*PROX_EN | */PROX_SLP(4) | PROX_DR_220 | ALS_RANGE_H /*| ALS_EN */;
672 if ((ret = i2c_master_send(client, buf, 2)) < 2) {
673 printk("%s: config isl29028 register %#x err %d\n", __FUNCTION__, buf[0], ret);
676 isl29028_read_reg(client, 0x01, &value);
677 printk("%s: config isl29028 CONFIGURE(0x01) reg %#x \n", __FUNCTION__, value);
680 buf[0] = ISL_REG_INT;
681 buf[1] = PROX_PRST(1) | ALS_PRST(3);
682 if ((ret = i2c_master_send(client, buf, 2)) < 2) {
683 printk("%s: config isl29028 register %#x err %d\n", __FUNCTION__, buf[0], ret);
686 isl29028_read_reg(client, 0x02, &value);
687 printk("%s: config isl29028 INTERRUPT(0x02) reg %#x \n", __FUNCTION__, value);
690 buf[0] = ISL_REG_PROX_LT;
692 if ((ret = i2c_master_send(client, buf, 2)) < 2) {
693 printk("%s: config isl29028 register %#x err %d\n", __FUNCTION__, buf[0], ret);
696 isl29028_read_reg(client, 0x03, &value);
697 printk("%s: config isl29028 PROX_LT(0x03) reg %#x \n", __FUNCTION__, value);
700 buf[0] = ISL_REG_PROX_HT;
702 if ((ret = i2c_master_send(client, buf, 2)) < 2) {
703 printk("%s: config isl29028 register %#x err %d\n", __FUNCTION__, buf[0], ret);
706 isl29028_read_reg(client, 0x04, &value);
707 printk("%s: config isl29028 PROX_HT(0x04) reg %#x \n", __FUNCTION__, value);
710 mutex_unlock(&isl->lock);
715 #ifdef CONFIG_HAS_EARLYSUSPEND
716 static void isl29028_suspend(struct early_suspend *h)
718 struct i2c_client *client = container_of(isl29028_psensor_misc.parent, struct i2c_client, dev);
719 D("isl29028 early suspend ========================= \n");
721 isl29028_psensor_disable(client);
723 isl29028_lsensor_disable(client);
726 static void isl29028_resume(struct early_suspend *h)
728 struct i2c_client *client = container_of(isl29028_psensor_misc.parent, struct i2c_client, dev);
729 D("isl29028 early resume ======================== \n");
731 isl29028_psensor_enable(client);
733 isl29028_lsensor_enable(client);
736 #define isl29028_suspend NULL
737 #define isl29028_resume NULL
740 static int isl29028_probe(struct i2c_client *client, const struct i2c_device_id *id)
743 struct isl29028_data *isl;
745 D("\n%s: isl29028 i2c client probe\n\n", __func__);
747 isl = kzalloc(sizeof(struct isl29028_data), GFP_KERNEL);
750 dev_err(&client->dev, "failed to allocate driver data\n");
754 isl->client = client;
755 i2c_set_clientdata(client, isl);
758 mutex_init(&isl->lock);
760 rc = register_psensor_device(client, isl);
762 dev_err(&client->dev, "failed to register_psensor_device\n");
766 rc = register_lsensor_device(client, isl);
768 dev_err(&client->dev, "failed to register_lsensor_device\n");
769 goto unregister_device1;
772 rc = isl29028_config(client);
774 dev_err(&client->dev, "failed to isl29028_config\n");
775 goto unregister_device2;
778 #ifdef CONFIG_HAS_EARLYSUSPEND
779 isl29028_early_suspend.suspend = isl29028_suspend;
780 isl29028_early_suspend.resume = isl29028_resume;
781 isl29028_early_suspend.level = 0x02;
782 register_early_suspend(&isl29028_early_suspend);
785 //isl29028_psensor_enable(client);
786 //isl29028_lsensor_enable(client);
791 unregister_lsensor_device(client, isl);
793 unregister_psensor_device(client, isl);
800 static int isl29028_remove(struct i2c_client *client)
802 struct isl29028_data *isl29028 = i2c_get_clientdata(client);
804 unregister_lsensor_device(client, isl29028);
805 unregister_psensor_device(client, isl29028);
807 #ifdef CONFIG_HAS_EARLYSUSPEND
808 unregister_early_suspend(&isl29028_early_suspend);
813 static const struct i2c_device_id isl29028_id[] = {
818 static struct i2c_driver isl29028_driver = {
822 .probe = isl29028_probe,
823 .remove = isl29028_remove,
824 .id_table = isl29028_id,
828 static int __init isl29028_init(void)
831 return i2c_add_driver(&isl29028_driver);
834 static void __exit isl29028_exit(void)
836 return i2c_del_driver(&isl29028_driver);
839 module_init(isl29028_init);
840 module_exit(isl29028_exit);