Пример #1
0
/* PS interrupt routine */
static void apds9130_work_handler(struct work_struct *work)
{
	struct apds9130_data *data = container_of(work, struct apds9130_data, dwork.work);
	struct i2c_client *client=data->client;
	int status;
	int enable;


	if(wake_lock_active(&data->ps_wlock))
		wake_unlock(&data->ps_wlock);
	wake_lock_timeout(&data->ps_wlock, 2 * HZ);


	status = i2c_smbus_read_byte_data(client, CMD_BYTE|APDS9130_STATUS_REG);
	enable = i2c_smbus_read_byte_data(client, CMD_BYTE|APDS9130_ENABLE_REG);

	i2c_smbus_write_byte_data(client, CMD_BYTE|APDS9130_ENABLE_REG, 1);	/* disable 9130 first */

	printk(KERN_INFO"status = %x\n", status);

	if ((status & enable & 0x30) == 0x30) {
		/* both PS and ALS are interrupted - never happened*/

		if ( (status&0x40) != 0x40 ) // no PSAT bit set
			apds9130_change_ps_threshold(client);
		else {
			if (data->ps_detection == 1) {
				apds9130_change_ps_threshold(client);
			}
			else {
				printk(KERN_INFO"Triggered by background ambient noise\n");
			}
		}

		apds9130_set_command(client, 2);	/* 2 = CMD_CLR_PS_ALS_INT */
	}
	else if ((status & enable & 0x20) == 0x20) {
		/* only PS is interrupted */

		if ( (status&0x40) != 0x40 ) // no PSAT bit set
			apds9130_change_ps_threshold(client);	// far-to-near
		else {
			if (data->ps_detection == 1) {
				apds9130_change_ps_threshold(client); // near-to-far
			}
			else {
				printk(KERN_INFO"Triggered by background ambient noise\n");
			}
		}

		apds9130_set_command(client, 0);	/* 0 = CMD_CLR_PS_INT */
	}
	else if ((status & enable & 0x10) == 0x10) {
		/* only ALS is interrupted - will never happened*/

		apds9130_set_command(client, 1);	/* 1 = CMD_CLR_ALS_INT */
	}

	i2c_smbus_write_byte_data(client, CMD_BYTE|APDS9130_ENABLE_REG, data->enable);
}
/* PS interrupt routine */
static void apds9130_work_handler(struct work_struct *work)
{
	struct apds9130_data *data = container_of(work, struct apds9130_data, dwork.work);
	struct i2c_client *client=data->client;
	int status;
	int enable;
    int err = 0;

	status = i2c_smbus_read_byte_data(client, CMD_BYTE|APDS9130_STATUS_REG);
	enable = i2c_smbus_read_byte_data(client, CMD_BYTE|APDS9130_ENABLE_REG);

	err = i2c_smbus_write_byte_data(client, CMD_BYTE|APDS9130_ENABLE_REG, 1);
    if(err) {
        printk("[ProximitySensor_E] %s : i2c_write fail(%d) at (%d)\n", __func__, err, __LINE__);
        return;
    }

	printk("[ProximitySensor] %s : [status:0x%02x][enable:0x%02x]\n", __func__, status, enable);
	if ((status & enable & 0x30) == 0x30) {
		/* both PS and ALS are interrupted - never happened*/

		if ( (status&0x40) != 0x40 ) // no PSAT bit set
			apds9130_change_ps_threshold(client);
		else {
			if (data->ps_detection == 1) {
				apds9130_change_ps_threshold(client);
			}
			else {
				printk("* Triggered by background ambient noise\n");
			}
		}

		err = apds9130_set_command(client, 2);	/* 2 = CMD_CLR_PS_ALS_INT */
	}
	else if ((status & enable & 0x20) == 0x20) {
		/* only PS is interrupted */
		
		if ( (status&0x40) != 0x40 ) // no PSAT bit set
			apds9130_change_ps_threshold(client);	// far-to-near
		else {
			if (data->ps_detection == 1) {
				apds9130_change_ps_threshold(client); // near-to-far
			}
			else {
				printk("* Triggered by background ambient noise\n");
			}
		}

		err = apds9130_set_command(client, 0);	/* 0 = CMD_CLR_PS_INT */
	}
	else if ((status & enable & 0x10) == 0x10) {
		/* only ALS is interrupted - will never happened*/	

		err = apds9130_set_command(client, 1);	/* 1 = CMD_CLR_ALS_INT */
	}

    if(err) {
        printk("[ProximitySensor_E] %s : i2c_write fail(%d) at (%d)\n", __func__, err, __LINE__);
        return;
    }

	err = i2c_smbus_write_byte_data(client, CMD_BYTE|APDS9130_ENABLE_REG, data->enable);
    if(err) {
        printk("[ProximitySensor_E] %s : i2c_write fail(%d) at (%d)\n", __func__, err, __LINE__);
        return;
    }
}