static void apds990x_als_polling_work_handler(struct work_struct *work) { struct apds990x_data *data = container_of(work, struct apds990x_data, als_dwork.work); struct i2c_client *client=data->client; int luxValue=0; data->cdata = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_CDATAL_REG); data->irdata = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_IRDATAL_REG); data->pdata = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_PDATAL_REG); luxValue = LuxCalculation(client, data->cdata, data->irdata); luxValue = luxValue>0 ? luxValue : 0; luxValue = luxValue<APDS990X_LUXVALUE_MAX ? luxValue : APDS990X_LUXVALUE_MAX; if(data->enable_ps_sensor>0) { if( (data->cdata >= 0xFFFF) || (data->irdata >= 0xFFFF) ) { luxValue = APDS990X_LUXVALUE_MAX; data->als_polling_cnt_reset |= ALS_POLLING_CNT_RESET_MAX_DATA; } } else if(data->als_gain == APDS990X_ALS_GAIN_1X) { if( (data->cdata >= 0xFFFF) || (data->irdata >= 0xFFFF) ) { luxValue = APDS990X_LUXVALUE_MAX; data->als_polling_cnt_reset |= ALS_POLLING_CNT_RESET_MAX_DATA; } else if( (data->cdata < 0x0900) && (data->irdata < 0x0900) ) { apds990x_change_als_gain(client, APDS990X_ALS_GAIN_8X); } else { /* nop */ } } else { if( (data->cdata >= 0x5D00) || (data->irdata >= 0x5D00) ) { apds990x_change_als_gain(client, APDS990X_ALS_GAIN_1X); if( (data->cdata >= 0xFFFF) || (data->irdata >= 0xFFFF) ) { schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay)); return; } } } apds990x_put_luxValue( data, (uint32_t)luxValue ); APDS_DEBUG_LOG("%s: lux = %d lux_mean = %d cdata = %x irdata = %x pdata = %x \n", __func__, luxValue, data->als_lux_ave, data->cdata, data->irdata, data->pdata); schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay)); }
static void apds990x_change_als_threshold(struct i2c_client *client) { struct apds990x_data *data = i2c_get_clientdata(client); int cdata, irdata; int luxValue=0; cdata = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_CDATAL_REG); irdata = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_IRDATAL_REG); luxValue = LuxCalculation(client, cdata, irdata); luxValue = luxValue>0 ? luxValue : 0; luxValue = luxValue<10000 ? luxValue : 10000; // check PS under sunlight if ( (data->ps_detection == 1) && (cdata > (75*(1024*(256-data->atime)))/100)) // PS was previously in far-to-near condition { // need to inform input event as there will be no interrupt from the PS input_report_abs(data->input_dev_ps, ABS_DISTANCE, 0);/* NEAR-to-FAR detection */ input_sync(data->input_dev_ps); i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_PILTL_REG, 0); i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_PIHTL_REG, data->ps_threshold); data->pilt = 0; data->piht = data->ps_threshold; data->ps_detection = 0; /* near-to-far detected */ printk("apds_990x_proximity_handler = FAR\n"); } input_report_abs(data->input_dev_als, ABS_MISC, luxValue); // report the lux level input_sync(data->input_dev_als); data->als_data = cdata; data->als_threshold_l = (data->als_data * (100-APDS990x_ALS_THRESHOLD_HSYTERESIS) ) /100; data->als_threshold_h = (data->als_data * (100+APDS990x_ALS_THRESHOLD_HSYTERESIS) ) /100; if (data->als_threshold_h >= 65535) data->als_threshold_h = 65535; i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_AILTL_REG, data->als_threshold_l); i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_AIHTL_REG, data->als_threshold_h); }
/* ALS polling routine */ static void tmd2771x_als_polling_work_handler(struct work_struct *work) { struct i2c_client *client=data->client; int cdata, irdata, pdata; int luxValue=0; //1. work queue is reentrant in SMP. //2. serveral function here calls need mutex. mutex_lock(&data->update_lock); cdata = i2c_smbus_read_word_data(client, CMD_WORD|TMD2771X_CDATAL_REG); irdata = i2c_smbus_read_word_data(client, CMD_WORD|TMD2771X_IRDATAL_REG); pdata = i2c_smbus_read_word_data(client, CMD_WORD|TMD2771X_PDATAL_REG); if ((cdata < 0) || (irdata < 0) || (pdata < 0)) { mutex_unlock(&data->update_lock); return; } luxValue = LuxCalculation(client, cdata, irdata); luxValue = luxValue>0 ? luxValue : 0; luxValue = luxValue<10000 ? luxValue : 10000; light_data = luxValue; //printk("%s: lux = %d cdata = %x irdata = %x pdata = %x \n", __func__, luxValue, cdata, irdata, pdata); // check PS under sunlight if ( (data->ps_detection == 1) && (cdata > (75*(1024*(256-data->atime)))/100)) // PS was previously in far-to-near condition { // need to inform input event as there will be no interrupt from the PS input_report_abs(data->input_dev_ps, ABS_DISTANCE, 1);/* NEAR-to-FAR detection */ input_sync(data->input_dev_ps); i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X_PILTL_REG, 0); i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X_PIHTL_REG, data->ps_threshold); data->pilt = 0; data->piht = data->ps_threshold; data->ps_detection = 0; /* near-to-far detected */ printk("tmd2771x_proximity_handler = FAR\n"); } input_report_abs(data->input_dev_als, ABS_MISC, luxValue); // report the lux level input_sync(data->input_dev_als); schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay)); // restart timer mutex_unlock(&data->update_lock); }
/* ALS polling routine */ static void apds990x_als_polling_work_handler(struct work_struct *work) { struct apds990x_data *data = container_of(work, struct apds990x_data, als_dwork.work); struct i2c_client *client=data->client; int cdata, irdata, pdata; int luxValue=0; cdata = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_CDATAL_REG); irdata = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_IRDATAL_REG); pdata = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_PDATAL_REG); luxValue = LuxCalculation(client, cdata, irdata); luxValue = luxValue>0 ? luxValue : 0; luxValue = luxValue<10000 ? luxValue : 10000; APDSDBG("%s: lux = %d cdata = %x irdata = %x pdata = %x \n", __func__, luxValue, cdata, irdata, pdata); testmode_prox = pdata; testmode_lux = luxValue; // check PS under sunlight if ( (data->ps_detection == 1) && (cdata > (75*(1024*(256-data->atime)))/100)) // PS was previously in far-to-near condition { // need to inform input event as there will be no interrupt from the PS input_report_abs(data->input_dev_ps, ABS_DISTANCE, 0);/* NEAR-to-FAR detection */ input_sync(data->input_dev_ps); i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_PILTL_REG, 0); i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_PIHTL_REG, data->ps_threshold); data->pilt = 0; data->piht = data->ps_threshold; data->ps_detection = 0; /* near-to-far detected */ printk("apds_990x_proximity_handler = FAR\n"); } input_report_abs(data->input_dev_als, ABS_MISC, luxValue); // report the lux level data->input_dev_als->absinfo[ABS_MISC].value = -1; input_sync(data->input_dev_als); schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay)); // restart timer }