Exemplo n.º 1
0
static int apds990x_init_client(struct i2c_client *client)
{
    struct apds990x_data *data = i2c_get_clientdata(client);
    int err;
    int id;

    data->enable_ps_sensor = 1;
    data->enable_als_sensor = 1;

    err = apds990x_set_enable(client, 0);

    if (err < 0)
        return err;
    
    id = i2c_smbus_read_byte_data(client, CMD_BYTE|APDS990x_ID_REG);
    if (id == 0x20) {
        APDS_DEBUG_LOG("APDS-9901\n");
    }
    else if (id == 0x29) {
        APDS_DEBUG_LOG("APDS-990x\n");
    }
    else {
        APDS_DEBUG_LOG("Neither APDS-9901 nor APDS-9901\n");
        return -EIO;
    }

    apds990x_set_atime(client, 0xC0);
    apds990x_set_ptime(client, 0xFF);
    apds990x_set_wtime(client, 0xE8);

    apds990x_set_ppcount(client, 0x04);
    apds990x_set_config(client, 0);
    apds990x_set_control(client, 0x20);

    apds990x_set_pilt(client, 0);
    apds990x_set_piht(client, guc_nv_proximity_sensor_near[0]);

    data->ps_threshold = guc_nv_proximity_sensor_near[0];
    data->ps_hysteresis_threshold = guc_nv_proximity_sensor_far[0];

    apds990x_set_ailt(client, 0);
    apds990x_set_aiht(client, 0xFFFF);

    apds990x_set_pers(client, 0x22);

    data->enable_ps_sensor = 0;
    data->enable_als_sensor = 0;
    err = apds990x_set_enable(client, 0);


    return 0;
}
Exemplo n.º 2
0
static int apds990x_init_client(struct i2c_client *client)
{
	struct apds990x_data *data = i2c_get_clientdata(client);
	int err;
	int id;

	err = apds990x_set_enable(client, 0);

	if (err < 0)
		return err;
	
	id = i2c_smbus_read_byte_data(client, CMD_BYTE|APDS990x_ID_REG);
	if (id == 0x20) {
		printk("APDS-9901\n");
	}
	else if (id == 0x29) {
		printk("APDS-990x\n");
	}
	else {
		printk("Neither APDS-9901 nor APDS-9901\n");
		return -EIO;
	}

	apds990x_set_atime(client, 0xDB);	// 100.64ms ALS integration time
	apds990x_set_ptime(client, 0xFF);	// 2.72ms Prox integration time
	apds990x_set_wtime(client, 0xFF);	// 2.72ms Wait time

	apds990x_set_ppcount(client, 0x08);	// 8-Pulse for proximity
	apds990x_set_config(client, 0);		// no long wait
	apds990x_set_control(client, 0x60);	// 100mA, IR-diode, 1X PGAIN, 1X AGAIN

	apds990x_set_pilt(client, 0);		// init threshold for proximity
	apds990x_set_piht(client, APDS990x_PS_DETECTION_THRESHOLD);

	data->ps_threshold = APDS990x_PS_DETECTION_THRESHOLD;
	data->ps_hysteresis_threshold = APDS990x_PS_HSYTERESIS_THRESHOLD;

	apds990x_set_ailt(client, 0);		// init threshold for als
	apds990x_set_aiht(client, 0xFFFF);

	apds990x_set_pers(client, 0x22);	// 2 consecutive Interrupt persistence

	// sensor is in disabled mode but all the configurations are preset

	return 0;
}
Exemplo n.º 3
0
static ssize_t apds990x_store_enable_als_sensor(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t count)
{
    struct i2c_client *client = to_i2c_client(dev);
    struct apds990x_data *data = i2c_get_clientdata(client);
    unsigned long val = simple_strtoul(buf, NULL, 10);
    unsigned long flags;
    
    APDS_DEBUG_LOG("%s: enable als sensor ( %ld)\n", __func__, val);
    
    if ((val != 0) && (val != 1))
    {
        APDS_DEBUG_LOG("%s: enable als sensor=%ld\n", __func__, val);
        return count;
    }
    
    if(val == 1) {
        if (data->enable_als_sensor<=0) {

            data->enable_als_sensor = 1;
        
            if (data->enable_ps_sensor<=0) {
                apds990x_set_enable(client,0);
                apds990x_set_atime(client, 0xC0);
                apds990x_set_ptime(client, 0xff);
                apds990x_set_wtime(client, 0xE8);
                apds990x_set_ppcount(client, 0x04);
                apds990x_set_control(client, 0x20);
                apds990x_set_pers(client, 0x22);
                apds990x_set_config(client, 0x00);
                apds990x_set_enable(client, 0x0B);
            }
        
            spin_lock_irqsave(&data->update_lock.wait_lock, flags); 
        
            __cancel_delayed_work(&data->als_dwork);
            schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay));
        
            spin_unlock_irqrestore(&data->update_lock.wait_lock, flags);
        }
        else
        {
            data->enable_als_sensor++;
        }
    }
    else {
        data->enable_als_sensor--;
        if( data->enable_als_sensor > 0)
        {
            ;
        }
        else {
            if (data->enable_ps_sensor<=0) {
                apds990x_set_enable(client, 0);
            }
        
            spin_lock_irqsave(&data->update_lock.wait_lock, flags); 
            
            __cancel_delayed_work(&data->als_dwork);
            
            spin_unlock_irqrestore(&data->update_lock.wait_lock, flags); 
            
            data->als_polling_cnt_reset |= ALS_POLLING_CNT_RESET_DISABLE;
        }
    }
    
    return count;
}
Exemplo n.º 4
0
static ssize_t apds990x_store_enable_ps_sensor(struct device *dev,
                struct device_attribute *attr, const char *buf, size_t count)
{
    struct i2c_client *client = to_i2c_client(dev);
    struct apds990x_data *data = i2c_get_clientdata(client);
    unsigned long val = simple_strtoul(buf, NULL, 10);
    unsigned long flags;
    
    APDS_DEBUG_LOG("%s: enable ps senosr ( %ld)\n", __func__, val);
    
    if ((val != 0) && (val != 1)) {
        APDS_DEBUG_LOG("%s:store unvalid value=%ld\n", __func__, val);
        return count;
    }
    
    if(val == 1) {
        if (data->enable_ps_sensor<=0) {

            data->enable_ps_sensor=1;
        
            if (data->enable_als_sensor<=0) {
                apds990x_set_enable(client,0);
                apds990x_set_atime(client, 0xC0);
                apds990x_set_ptime(client, 0xff);
                apds990x_set_ppcount(client, 0x04);
                apds990x_set_pers(client, 0x22);
                apds990x_set_config(client, 0x00);
            }

            apds990x_set_wtime(client, 0xE5);
            apds990x_set_ailt(client, guc_nv_photo_sensor_dark[0]);
            apds990x_set_aiht(client, 0xffff);
            apds990x_set_pilt(client, 0);
            apds990x_set_piht(client, guc_nv_proximity_sensor_near[0]);
            if( data->als_gain == APDS990X_ALS_GAIN_1X )
            {
                apds990x_set_control(client, 0x20);
            }
            else
            {
                apds990x_set_control(client, 0x20);
                msleep(250);
            }

            data->ps_threshold = guc_nv_proximity_sensor_near[0];
            data->ps_hysteresis_threshold = guc_nv_proximity_sensor_far[0];

            data->ps_detection = 0;

            apds990x_set_enable(client, 0x2F);
            apds990x_enable_ps_irq(data);
        } else
        {
            data->enable_ps_sensor++;
        }
    } 
    else {
        data->enable_ps_sensor--;
        
        if (data->enable_ps_sensor>0) {
            ;
        } else if(data->enable_als_sensor) {
            
            apds990x_disable_ps_irq(data);
            apds990x_set_enable(client, 0x0A);
            i2c_smbus_write_byte(client, CMD_SPECIAL|0x07);
            apds990x_set_wtime(client, 0xE8);
            apds990x_set_enable(client, 0xB);
            
            if( data->ps_detection != 0 )
            {
                data->ps_detection = 0;
                input_report_abs(data->input_dev_ps, ABS_DISTANCE, 0);
                input_sync(data->input_dev_ps);
            }

            spin_lock_irqsave(&data->update_lock.wait_lock, flags); 
            
            __cancel_delayed_work(&data->als_dwork);
            schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay));
            
            spin_unlock_irqrestore(&data->update_lock.wait_lock, flags);    
            
        }
        else {
            apds990x_disable_ps_irq(data);
            i2c_smbus_write_byte_data(client, CMD_BYTE|APDS990x_ENABLE_REG, 0x08);
            i2c_smbus_write_byte(client, CMD_SPECIAL|0x07);
            apds990x_set_wtime(client, 0xE8);
            apds990x_set_enable(client, 0);

            if( data->ps_detection != 0 )
            {
                data->ps_detection = 0;
                input_report_abs(data->input_dev_ps, ABS_DISTANCE, 0);
                input_sync(data->input_dev_ps);
            }
        }
    }
    
    
    return count;
}