#include <linux/circ_buf.h>
#include <linux/interrupt.h>
#include "isl29028.h"
+#include <linux/slab.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#define ISL_REG_ALSIR_LDATA (0x09)
#define ISL_REG_ALSIR_HDATA (0x0a)
+
+#define ISL_REG_ALSIR_TH1 (0x05)
+#define ISL_REG_ALSIR_TH2 (0x06)
+#define ISL_REG_ALSIR_TH3 (0x07)
+
struct isl29028_data {
struct input_dev *psensor_input_dev;
struct input_dev *lsensor_input_dev;
static struct early_suspend isl29028_early_suspend;
#endif
+static irqreturn_t isl29028_psensor_irq_handler(int irq, void *data);
+
+
int g_lightlevel = 8;
static const int luxValues[8] = {
static void isl29028_psensor_work_handler(struct work_struct *work)
{
+#if 1
+ struct isl29028_data *isl = (struct isl29028_data *)container_of(work, struct isl29028_data, p_work.work);
+ int rc;
+
+ if (gpio_get_value(isl->client->irq)) {
+ D("line %d, input_report_abs 0 \n", __LINE__);
+ input_report_abs(isl->psensor_input_dev, ABS_DISTANCE, 1);
+ input_sync(isl->psensor_input_dev);
+ free_irq(isl->irq, (void *)isl);
+ rc = request_irq(isl->irq, isl29028_psensor_irq_handler,
+ IRQ_TYPE_EDGE_FALLING, isl->client->name, (void *)isl);
+ if (rc < 0) {
+ dev_err(&(isl->client->dev),"request_irq failed for gpio %d (%d)\n", isl->client->irq, rc);
+ }
+ }
+ else {
+ D("line %d, input_report_abs 0 \n", __LINE__);
+ input_report_abs(isl->psensor_input_dev, ABS_DISTANCE, 0);
+ input_sync(isl->psensor_input_dev);
+ free_irq(isl->irq, (void *)isl);
+ rc = request_irq(isl->irq, isl29028_psensor_irq_handler,
+ IRQ_TYPE_EDGE_RISING, isl->client->name, (void *)isl);
+ if (rc < 0) {
+ dev_err(&(isl->client->dev),"request_irq failed for gpio %d (%d)\n", isl->client->irq, rc);
+ }
+ }
+
+ return ;
+#else
struct isl29028_data *isl = (struct isl29028_data *)container_of(work, struct isl29028_data, p_work.work);
char reg, value, int_flag;
mutex_unlock(&isl->lock);
enable_irq(isl->irq);
+
+#endif
}
static irqreturn_t isl29028_psensor_irq_handler(int irq, void *data)
{
+#if 1
+ struct isl29028_data *isl = (struct isl29028_data *)data;
+ //disable_irq_nosync(isl->irq);
+ schedule_delayed_work(&isl->p_work, msecs_to_jiffies(420));
+ return IRQ_HANDLED;
+#else
struct isl29028_data *isl = (struct isl29028_data *)data;
D("line %d, input_report_abs 0 \n", __LINE__);
input_report_abs(isl->psensor_input_dev, ABS_DISTANCE, 0);
schedule_delayed_work(&isl->p_work, msecs_to_jiffies(420));
return IRQ_HANDLED;
+#endif
}
static int isl29028_psensor_enable(struct i2c_client *client)
{
- char reg, value;
+ char reg, value, int_flag;
int ret;
struct isl29028_data *isl = (struct isl29028_data *)i2c_get_clientdata(client);
+ printk("line %d: enter func %s\n", __LINE__, __FUNCTION__);
+
mutex_lock(&isl->lock);
reg = ISL_REG_CONFIG;
ret = isl29028_read_reg(client, reg, &value);
ret = isl29028_read_reg(client, reg, &value);
D("%s: configure reg value %#x ...\n", __FUNCTION__, value);
#endif
+
+ reg = ISL_REG_INT;
+ isl29028_read_reg(isl->client, reg, (char *)&int_flag);
+ if (!(int_flag >> 7)) {
+ printk("line %d: input_report_abs 1 \n", __LINE__);
+ input_report_abs(isl->psensor_input_dev, ABS_DISTANCE, 1);
+ input_sync(isl->psensor_input_dev);
+ }
mutex_unlock(&isl->lock);
//enable_irq(isl->irq);
{
char ret, reg, reg2, value, value2;
struct isl29028_data *isl = (struct isl29028_data *)i2c_get_clientdata(client);
+ printk("line %d: enter func %s\n", __LINE__, __FUNCTION__);
+
+ //disable_irq_nosync(isl->irq);
mutex_lock(&isl->lock);
#endif
mutex_unlock(&isl->lock);
- disable_irq(isl->irq);
+ //disable_irq(isl->irq);
cancel_delayed_work_sync(&isl->p_work);
- enable_irq(isl->irq);
+ //enable_irq(isl->irq);
return ret;
}
isl->irq = gpio_to_irq(client->irq);
//mdelay(1);
rc = request_irq(isl->irq, isl29028_psensor_irq_handler,
- IRQ_TYPE_LEVEL_LOW, client->name, (void *)isl);
+ IRQ_TYPE_EDGE_FALLING, client->name, (void *)isl);
if (rc < 0) {
dev_err(&client->dev,"request_irq failed for gpio %d (%d)\n", client->irq, rc);
goto err_free_gpio;
}
+
+ //disable_irq_nosync(isl->irq);
return 0;
printk("%s: config isl29028 PROX_HT(0x04) reg %#x \n", __FUNCTION__, value);
#endif
+ buf[0] = ISL_REG_ALSIR_TH1;
+ buf[1] = 0x0;
+ if ((ret = i2c_master_send(client, buf, 2)) < 2) {
+ printk("%s: config isl29028 register %#x err %d\n", __FUNCTION__, buf[0], ret);
+ }
+
+ buf[0] = ISL_REG_ALSIR_TH2;
+ buf[1] = 0xF0;
+ if ((ret = i2c_master_send(client, buf, 2)) < 2) {
+ printk("%s: config isl29028 register %#x err %d\n", __FUNCTION__, buf[0], ret);
+ }
+
+ buf[0] = ISL_REG_ALSIR_TH3;
+ buf[1] = 0xFF;
+ if ((ret = i2c_master_send(client, buf, 2)) < 2) {
+ printk("%s: config isl29028 register %#x err %d\n", __FUNCTION__, buf[0], ret);
+ }
+
mutex_unlock(&isl->lock);
return 0;
static void isl29028_suspend(struct early_suspend *h)
{
struct i2c_client *client = container_of(isl29028_psensor_misc.parent, struct i2c_client, dev);
+ struct isl29028_data *isl = (struct isl29028_data *)i2c_get_clientdata(client);
+
D("isl29028 early suspend ========================= \n");
if (misc_ps_opened)
- isl29028_psensor_disable(client);
+ enable_irq_wake(isl->irq);
+// isl29028_psensor_disable(client);
if (misc_ls_opened)
isl29028_lsensor_disable(client);
}
static void isl29028_resume(struct early_suspend *h)
{
struct i2c_client *client = container_of(isl29028_psensor_misc.parent, struct i2c_client, dev);
+ struct isl29028_data *isl = (struct isl29028_data *)i2c_get_clientdata(client);
+
D("isl29028 early resume ======================== \n");
if (misc_ps_opened)
- isl29028_psensor_enable(client);
+ disable_irq_wake(isl->irq);
+// isl29028_psensor_enable(client);
if (misc_ls_opened)
isl29028_lsensor_enable(client);
}