【Linux内核驱动】编写I2C外设驱动读取触摸屏固件版本

来源:互联网 发布:ipad能刷windows系统吗 编辑:程序博客网 时间:2024/06/07 11:31

编写I2C外设驱动步骤

  1. 注册I2C设备,一般在板级文件中,定义i2c_board_info
  2. 注册I2C驱动:i2c_register_driver,i2c_del_driver
  3. 利用i2c_client中的addr(设备地址)和adapter(主机驱动)实现I2C数据传输:填充i2c_msg并调用i2c_transfer
#include <linux/kernel.h>#include <linux/module.h>#include <linux/delay.h>#include <linux/i2c.h>#include <linux/gpio.h>#include <plat/gpio-cfg.h>#include <mach/gpio.h>#define DRIVER_NAME "i2c_test"MODULE_LICENSE("Dual BSD/GPL");MODULE_AUTHOR("colorfulshark@hotmail.com");static void i2c_io_init(void);static struct i2c_device_id i2c_test_id_table[] = {    {"i2c_test", 0},    {},};static int i2c_test_probe(struct i2c_client *client, const struct i2c_device_id *id);static int i2c_test_remove(struct i2c_client *client);static struct i2c_driver i2c_test_driver = {    .probe = i2c_test_probe,    .remove = i2c_test_remove,    .id_table = i2c_test_id_table,    .driver = {        .name = DRIVER_NAME,        .owner = THIS_MODULE,    }};/* define i2c_driver callback functions */static int i2c_test_read_fw(struct i2c_client *client);static int i2c_test_probe(struct i2c_client *client, const struct i2c_device_id *id){    printk("i2c test probe\n");    printk("touchscreen io init\n");    i2c_io_init();    i2c_test_read_fw(client);    return 0;}static int i2c_test_remove(struct i2c_client *client){    printk("i2c test remove\n");    return 0;}static int i2c_test_read_reg(struct i2c_client *client, u8 addr, u8 *data){    int error;    u8 buf[4] = {0};    struct i2c_msg msgs[] = {        {            .addr = client->addr,            .flags = 0,            .len = 1,            .buf = buf,        },        {            .addr = client->addr,            .flags = 1,            .len = 1,            .buf = buf,        },    };    buf[0] = addr;    error = i2c_transfer(client->adapter, msgs, 2);    if(error < 0)        goto err_i2c_trans;    *data = buf[0];    return 0;err_i2c_trans:    printk("i2c transfer failed\n");    return error;} static int i2c_test_read_fw(struct i2c_client *client){    int error;    u8 val;    error = i2c_test_read_reg(client, 0xa6, &val);    if(error < 0)        goto err_read_i2c_reg;    printk("fw is %x\n", val);    return 0;err_read_i2c_reg:    printk("read i2c reg failed\n");    return error;}static void i2c_io_init(void){    int ret;    ret = gpio_request(EXYNOS4_GPL0(2), "TP1_EN");    if (ret) {        printk(KERN_ERR "failed to request TP1_EN for "                "I2C control\n");        //return err;    }    gpio_direction_output(EXYNOS4_GPL0(2), 1);    s3c_gpio_cfgpin(EXYNOS4_GPL0(2), S3C_GPIO_OUTPUT);    gpio_free(EXYNOS4_GPL0(2));    mdelay(5);    ret = gpio_request(EXYNOS4_GPX0(3), "GPX0_3");    if (ret) {        gpio_free(EXYNOS4_GPX0(3));        ret = gpio_request(EXYNOS4_GPX0(3), "GPX0_3");        if(ret)        {            printk("ft5xox: Failed to request GPX0_3 \n");        }    }    gpio_direction_output(EXYNOS4_GPX0(3), 0);    mdelay(200);    gpio_direction_output(EXYNOS4_GPX0(3), 1);    s3c_gpio_cfgpin(EXYNOS4_GPX0(3), S3C_GPIO_OUTPUT);    gpio_free(EXYNOS4_GPX0(3));    msleep(300);    }static int i2c_test_init(void){    int error;    printk("i2c test init\n");    printk("i2c register driver\n");    error = i2c_register_driver(THIS_MODULE, &i2c_test_driver);    if(error < 0)        goto err_reg_i2c_dri;    return 0;err_reg_i2c_dri:    printk("fail to register i2c driver\n");    return error;}static void i2c_test_exit(void){    printk("i2c test exit\n");    printk("i2c del driver\n");    i2c_del_driver(&i2c_test_driver);}module_init(i2c_test_init);module_exit(i2c_test_exit);
原创粉丝点击