内核:Linux3.6;
平台:IMX6Q;
io口下降沿中断触发,调用线程函数,线程读取光感值,并更新在input的节点下。
1、 kernel_imx\arch\arm\mach-mx6: Board-mx6q_sabresd.c
static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
...
{
I2C_BOARD_INFO("LTR_558ALS", 0x23),
.irq = gpio_to_irq(ALS_LIGHT_SENSOR_INT),
},
...
};
2、 kernel_imx\drivers\input\misc:Ltr558.c
static int __init ltr558_driverinit(void)
{
return i2c_add_driver(<r558_driver);
}
static int ltr558_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ltr558_chip *chip = NULL;
struct input_dev *pinput_dev = NULL;
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
int ret = 0;
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
return -EIO;
printk("ltr558_probe start ...%s\n",id->name);
chip = kzalloc(sizeof(struct ltr558_chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
dev_dbg(&client->dev, "%s() called\n", __func__);
i2c_set_clientdata(client, chip);
chip->client = client;
/*
if (chip->irq > 0) {
ret = request_threaded_irq(chip->irq, NULL, threshold_isr,
IRQF_SHARED, "LTR558_ALS", chip);
if (ret) {
dev_err(&client->dev, "Unable to register irq %d; "
"ret %d\n", chip->irq, ret);
goto exit_free;
}
}
*/
mutex_init(&chip->lock);
/*
ret = ltr558_chip_init(client);
if (ret)
goto exit_irq;
*/
pinput_dev = input_allocate_device();
if (!pinput_dev) {
ret = -ENOMEM;
goto exit_irq;
}
chip->input = pinput_dev;
pinput_dev->name = "isl29023 light sensor";
pinput_dev->id.bustype = BUS_I2C;
pinput_dev->phys = chip->phys;
__set_bit(EV_ABS, pinput_dev->evbit);
input_set_abs_params(pinput_dev, ABS_MISC, 0,65535, 0, 0);
ret = input_register_device(pinput_dev);
if (ret)
goto exit_irq;
/* register sysfs hooks */
ret = sysfs_create_group(&client->dev.kobj, <r558_group);
if (ret)
goto exit_irq;
chip->irq = client->irq;
/* set irq type to edge falling */
if (chip->irq > 0){
printk("irq start ...\n");
irq_set_irq_type(client->irq, IRQF_TRIGGER_FALLING);
ret = request_irq(client->irq, ltr558_irq_handler, 0,
client->dev.driver->name, chip);
if (ret < 0) {
dev_err(&client->dev, "failed to register irq %d!\n",
client->irq);
goto exit_irq;
}
}
chip->workqueue = create_singlethread_workqueue("isl29023");
INIT_WORK(&chip->work, ltr558_work);
if (chip->workqueue == NULL) {
dev_err(&client->dev, "couldn't create workqueue\n");
ret = -ENOMEM;
goto exit_irq;
}
ret = ltr558_chip_init(client);
if (ret)
goto exit_irq;
printk("success of init ltr558_probe\n");
return 0;
exit_irq:
if (chip->irq > 0)
free_irq(chip->irq, chip);
if(pinput_dev)
input_free_device(pinput_dev);
return ret;
}