static irqreturn_t threshold_isr(int irq, void *irq_data) { struct ltr558_chip *chip = (struct ltr558_chip *)irq_data; s32 int_reg; struct i2c_client *client = chip->client; int_reg = i2c_smbus_read_byte_data(client, LTR558_ALS_PS_STATUS); if (int_reg < 0) { dev_err(&client->dev, "Error in reading register %d, error %d\n", LTR558_ALS_PS_STATUS, int_reg); return IRQ_HANDLED; } if (int_reg & STATUS_ALS_INT_TRIGGER) { if (int_reg & STATUS_ALS_NEW_DATA) chip->als_reading = ltr558_als_read(client); } if (int_reg & STATUS_PS_INT_TRIGGER) { if (int_reg & STATUS_PS_NEW_DATA) chip->prox_reading = ltr558_ps_read(client); } return IRQ_HANDLED; }
static int ltr558_suspend(struct i2c_client *client, pm_message_t mesg){ if (ltr558_data->p_enable){ disable_irq(ltr558_data->ltr558_irq); enable_irq_wake(ltr558_data->ltr558_irq); } if(tc4_get_call_flg() && (ltr558_ps_read() >= 0x214)) { ltr558_set_p_range(P_RANGE_2); ltr558_ps_enable(PS_GAINRANGE); } LTRDBG("ltr558 -----flag=%d--------%s\n",ltr558_data->p_enable, __func__); return 0; }
/* Display proxim data */ static ssize_t show_proxim_data(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_to_iio_dev(dev); struct ltr558_chip *chip = iio_priv(indio_dev); int prox_data = 0; ssize_t buf_count = 0; dev_vdbg(dev, "%s()\n", __func__); mutex_lock(&chip->lock); if (chip->is_prox_enable) { prox_data = ltr558_ps_read(chip->client); chip->prox_reading = prox_data; buf_count = sprintf(buf, "%d\n", prox_data); } else buf_count = sprintf(buf, "%d\n", chip->prox_reading); mutex_unlock(&chip->lock); return buf_count; }
static void ltr558_schedwork(struct work_struct *work){ int als_ps_status; int interrupt, newdata; int final_prox_val; int final_lux_val; als_ps_status = ltr558_i2c_read_reg(LTR558_ALS_PS_STATUS); interrupt = als_ps_status & 10; newdata = als_ps_status & 5 ; LTRDBG("interrupt [%d] newdata [%d]\n", interrupt, newdata); switch (interrupt){ case 2: // PS interrupt if ((newdata == 1) | (newdata == 5)){ final_prox_val = ltr558_ps_read(); if(final_prox_val < 0){ LTRERR("read P-sensor data fail\n"); goto out; } LTRDBG("final_prox_val [%d]\n", final_prox_val); if (final_prox_val >= 0x214){ P_L_printk("ltr558 OBJECT_IS_DETECTED\n"); input_report_abs(ltr558_data->ltr558_input, ABS_DISTANCE, OBJECT_IS_DETECTED); if (ltr558_set_p_range(P_RANGE_2)){ LTRERR("set P-sensor to range 2 fail\n"); } }else if (final_prox_val < 0x214){ P_L_printk("ltr558 OBJECT_IS_NOT_DETECTED\n"); input_report_abs(ltr558_data->ltr558_input, ABS_DISTANCE, OBJECT_IS_NOT_DETECTED); if (ltr558_set_p_range(P_RANGE_1)){ LTRERR("set P-sensor to range 1 fail\n"); } } } break; case 8: // ALS interrupt if ((newdata == 4) | (newdata == 5)){ final_lux_val = ltr558_als_read(); if(final_lux_val < 0){ LTRERR("read L-sensor data fail\n"); goto out; } input_report_abs(ltr558_data->ltr558_input, ABS_MISC, final_lux_val); LTRDBG("final_lux_val [%d]\n", final_lux_val); } break; case 10: // Both interrupt if ((newdata == 1) | (newdata == 5)){ final_prox_val = ltr558_ps_read(); if(final_prox_val < 0){ LTRERR("read P-sensor data fail\n"); goto read_als; } LTRDBG("final_prox_val [%d]\n", final_prox_val); if (final_prox_val >= 0x214){ input_report_abs(ltr558_data->ltr558_input, ABS_DISTANCE, OBJECT_IS_DETECTED); if (ltr558_set_p_range(P_RANGE_2)){ LTRERR("set P-sensor to range 2 fail\n"); } }else if (final_prox_val <0x214){ input_report_abs(ltr558_data->ltr558_input, ABS_DISTANCE, OBJECT_IS_NOT_DETECTED); if (ltr558_set_p_range(P_RANGE_1)){ LTRERR("set P-sensor to range 2 fail\n"); } } } read_als: if ((newdata == 4) | (newdata == 5)){ final_lux_val = ltr558_als_read(); if(final_lux_val < 0){ LTRERR("read L-sensor data fail\n"); goto out; } input_report_abs(ltr558_data->ltr558_input, ABS_MISC, final_lux_val); LTRDBG("final_lux_val [%d]\n", final_lux_val); } break; } out: input_sync(ltr558_data->ltr558_input); enable_irq(ltr558_data->ltr558_irq); }
static void ltr558_work_func(struct work_struct *work) { int als_ps_status; int pdata = 0; int cdata = 0; int cdata_high,cdata_low ; int lux = 0; int als_level = 0; int interrupt, newdata; int pthreshold_h=0, pthreshold_l; int temp = 0; int ret ,i; struct ltr558_data *ltr_data = container_of(work, struct ltr558_data, work); als_ps_status = get_ltr_register(ltr_data,LTR558_ALS_PS_STATUS); LTR558_DBG(KERN_ERR "%s: first als_ps_status=0x%x,\n",__func__,als_ps_status); interrupt = als_ps_status & INT_STATE; newdata = als_ps_status & DATA_STATE; LTR558_DBG("get into work func .\n"); if( PS_INIT == (interrupt & PS_INIT) ) { if ( PS_DATA_BIT == (newdata & PS_DATA_BIT)) { pdata = ltr558_ps_read(ltr_data); } LTR558_DBG("pdata = %d \n",pdata); LTR558_DBG("ps_contl = 0x%x \n",get_ltr_register( ltr_data, LTR558_PS_CONTR)); if ((pdata + ltr_558_pwave_value) < min_proximity_value) { LTR558_DBG("readjust the min_proximity_value\n"); min_proximity_value = pdata + ltr_558_pwave_value; temp = min_proximity_value + ltr_558_pwindows_value; ret = set_ltr_register(ltr_data,LTR558_PS_THRES_UP_0, temp & 0xff); ret |= set_ltr_register(ltr_data,LTR558_PS_THRES_UP_1, temp >> 8); if (ret < 0) { printk(KERN_ERR "%s:set LRT558_PILTL_UP register is error(%d)!", __func__, ret); } temp = min_proximity_value; ret = set_ltr_register(ltr_data,LTR558_PS_THRES_LOW_0,temp & 0xff); ret |= set_ltr_register(ltr_data,LTR558_PS_THRES_LOW_1,temp >> 8 ); if (ret < 0) { printk(KERN_ERR "%s:set LRT558_PILTL_LOW register is error(%d)!", __func__, ret); } } /*read the high threhold and the low threhold*/ pthreshold_h = get_ltr_register(ltr_data, LTR558_PS_THRES_UP_1); temp = get_ltr_register(ltr_data, LTR558_PS_THRES_UP_0); pthreshold_h = (pthreshold_h << 8) + temp; pthreshold_l = get_ltr_register(ltr_data, LTR558_PS_THRES_LOW_1); temp = get_ltr_register(ltr_data, LTR558_PS_THRES_LOW_0); pthreshold_l = (pthreshold_l << 8) + temp; LTR558_DBG(KERN_ERR "%s:before pthreshold_h = %d, pthreshold_l = %d\n",__func__,pthreshold_h,pthreshold_l); /* if more than the value of proximity high threshold we set*/ if (pdata >= pthreshold_h) { /* stop the close init */ temp = LTR_558_MAX_PPDATA; ret = set_ltr_register(ltr_data,LTR558_PS_THRES_UP_0, temp & 0xff); ret |= set_ltr_register(ltr_data,LTR558_PS_THRES_UP_1, temp >> 8 ); if (ret <0) { printk(KERN_ERR "%s:set LTR558_PILTL_UP register is error(%d)!", __func__, ret); } temp = min_proximity_value; ret = set_ltr_register(ltr_data,LTR558_PS_THRES_LOW_0,temp & 0xff); ret |= set_ltr_register(ltr_data,LTR558_PS_THRES_LOW_1,temp >> 8 ); if (ret < 0) { printk(KERN_ERR "%s:set LTR558_PILTL_LOW register is error(%d)!", __func__, ret); } input_report_abs(ltr_data->input_dev, ABS_DISTANCE, 0); input_sync(ltr_data->input_dev); }