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; }
/* Display als data */ static ssize_t show_als_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); ssize_t buf_count = 0; int als_data = 0; dev_vdbg(dev, "%s()\n", __func__); mutex_lock(&chip->lock); if (chip->is_als_enable) { als_data = ltr558_als_read(chip->client); buf_count = sprintf(buf, "%d\n", als_data); chip->als_reading = als_data; } else buf_count = sprintf(buf, "%d\n", chip->als_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); }