Exemple #1
0
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));
}
Exemple #2
0
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);
}
Exemple #4
0
/* 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
}