驱动模块使用I2C总线范例

来源:互联网 发布:万网解析域名设置 编辑:程序博客网 时间:2024/05/19 16:35

原文http://blog.csdn.net/azloong/article/details/6178657

源码是在linux2.6下写的,为了移值到更高的linux版本,进行了一定的修改。

#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/errno.h>#include <linux/init.h>#include <linux/list.h>#include <linux/i2c.h>#include <linux/hardirq.h>#include <linux/slab.h>   #define I2C_API_FAKE_ADDR   0x7f#define I2C_MINORS          256//#define i2c_version_old     1   int  i2c_api_attach(struct i2c_adapter *adapter);int  i2c_api_detach(struct i2c_adapter *adapter); struct i2c_api {    struct list_head list;    struct i2c_client *client;}; static LIST_HEAD(i2c_api_list);static DEFINE_SPINLOCK(i2c_api_list_lock); static const unsigned short normal_addr[] = { I2C_API_FAKE_ADDR, I2C_CLIENT_END };static const unsigned short ignore[]      = { I2C_CLIENT_END };#ifdef i2c_version_oldstatic struct i2c_client_address_data addr_data =  {    .normal_i2c = normal_addr,    .probe      = ignore,    .ignore     = ignore,    .forces     = NULL,};#endifstatic const struct i2c_device_id id[] = {    {"I2C-API", 0},    {}  };       MODULE_DEVICE_TABLE(i2c, id); static struct i2c_driver i2c_api_driver = {    .id_table       = id,    .attach_adapter = i2c_api_attach, //#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0)    #if 0    .detach_adapter    = i2c_api_detach,#endif        .command        = NULL,    .driver         = {.name  = "I2C-API",.owner = THIS_MODULE,    },#ifdef i2c_version_old        .address_data   = &addr_data,#endif }; static struct i2c_api *get_i2c_api(int bus_id){    struct i2c_api *i2c_api;     spin_lock(&i2c_api_list_lock);    list_for_each_entry(i2c_api, &i2c_api_list, list) {        if (i2c_api->client->adapter->nr == bus_id)            goto found;    }    i2c_api = NULL;    found:    spin_unlock(&i2c_api_list_lock);    return i2c_api;} static struct i2c_api *add_i2c_api(struct i2c_client *client){    struct i2c_api *i2c_api;     if (client->adapter->nr >= I2C_MINORS) {        printk(KERN_ERR "i2c_api: Out of device minors (%d)/n",            client->adapter->nr);        return NULL;    }     i2c_api = kzalloc(sizeof(*i2c_api), GFP_KERNEL);    if (!i2c_api)        return NULL;    i2c_api->client = client;     spin_lock(&i2c_api_list_lock);    list_add_tail(&i2c_api->list, &i2c_api_list);    spin_unlock(&i2c_api_list_lock);    return i2c_api;} static void del_i2c_api(struct i2c_api *i2c_api){    spin_lock(&i2c_api_list_lock);    list_del(&i2c_api->list);    spin_unlock(&i2c_api_list_lock);    kfree(i2c_api);} static int i2c_api_do_xfer(int bus_id, char chip_addr, char sub_addr, int mode,      char *buf, unsigned int size){/** you could define more transfer mode here, implement it following. */#define I2C_API_XFER_MODE_SEND            0x0 /* standard send */#define I2C_API_XFER_MODE_RECV            0x1 /* standard receive */#define I2C_API_XFER_MODE_SEND_NO_SUBADDR 0x2 /* send without sub-address */#define I2C_API_XFER_MODE_RECV_NO_SUBADDR 0x3 /* receive without sub-address */     int ret = 0;    char *tmp;    struct i2c_api *i2c_api = get_i2c_api(bus_id);     if (!i2c_api)        return -ENODEV;        i2c_api->client->addr = chip_addr;    switch (mode) {    case I2C_API_XFER_MODE_SEND:        tmp = kmalloc(size + 1,GFP_KERNEL);        if (tmp == NULL)            return -ENOMEM;        tmp[0] = sub_addr;        memcpy(&tmp[1], buf, size);        ret = i2c_master_send(i2c_api->client, tmp, size + 1);        ret = (ret == size + 1) ? size : ret;        break;            case I2C_API_XFER_MODE_RECV:        ret = i2c_master_send(i2c_api->client, &sub_addr, 1);        if (ret < 0)            return ret;        ret = i2c_master_recv(i2c_api->client, buf, size);        break;        case I2C_API_XFER_MODE_SEND_NO_SUBADDR:        ret = i2c_master_send(i2c_api->client, buf, size);        break;            case I2C_API_XFER_MODE_RECV_NO_SUBADDR:        ret = i2c_master_recv(i2c_api->client, buf, size);        break;                default:        return -EINVAL;    }    return ret;} int i2c_api_do_send(int bus_id, char chip_addr, char sub_addr, char *buf, unsigned int size){    return i2c_api_do_xfer(bus_id, chip_addr, sub_addr, I2C_API_XFER_MODE_SEND, buf, size);} int i2c_api_do_recv(int bus_id, char chip_addr, char sub_addr, char *buf, unsigned int size){    return i2c_api_do_xfer(bus_id, chip_addr, sub_addr, I2C_API_XFER_MODE_RECV, buf, size);} int i2c_api_attach(struct i2c_adapter *adap){    struct i2c_board_info info;    struct i2c_client *client;        memset(&info, 0, sizeof(struct i2c_board_info));        strlcpy(info.type, "i2c_api", I2C_NAME_SIZE);    info.addr = I2C_API_FAKE_ADDR;    client = i2c_new_device(adap, &info);    if (client)        add_i2c_api(client);    printk(KERN_INFO "i2c_api_attach adap[%d]/n", adap->nr);    return 0;} int i2c_api_detach(struct i2c_adapter *adap){        struct i2c_api *i2c_api;     i2c_api = get_i2c_api(adap->nr);    if (i2c_api)        del_i2c_api(i2c_api);    return 0;} static int __init i2c_api_init(void){        int ret = i2c_add_driver(&i2c_api_driver);      if (ret) {        printk(KERN_ERR "[%s] Driver registration failed, module not inserted./n", __func__);        return ret;    }     return 0 ;    } static void __exit i2c_api_exit(void){        i2c_del_driver(&i2c_api_driver);} MODULE_AUTHOR("Loon, <sepnic@gmail.com>");MODULE_DESCRIPTION("I2C i2c_api Driver");MODULE_LICENSE("GPL"); module_init(i2c_api_init);module_exit(i2c_api_exit); EXPORT_SYMBOL_GPL(i2c_api_do_send);EXPORT_SYMBOL_GPL(i2c_api_do_recv);


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 战舰世界航母的飞机恐惧状态怎么办 cad打开图纸不显示轴号怎么办 若背包忘在服务区没拿怎么办 使劲擤鼻涕耳朵耳朵疼了怎么办 用力擤鼻涕一侧的脸肿了怎么办 擦鼻涕太用力耳朵塞住了怎么办 宝宝鼻腔里有鼻涕呼呼响怎么办 黏痰在嗓子眼很干出不来怎么办 宝宝生病好了不久突然又咳嗽怎么办 7个月的宝宝经常生病怎么办 擤鼻涕鼻子周围红肿爆皮怎么办 洗衣机有鼻涕虫洗过的衣服怎么办 手机丢了里边有穿内衣照片怎么办 脸上不知是过敏还是湿疹流水怎么办 一个月的宝宝鼻子不通气怎么办 六个月的宝宝有清水鼻涕怎么办 一岁三个月宝宝流清鼻涕怎么办 宝宝流清水鼻涕怎么办最简单方法 8个月宝宝流清鼻涕怎么办 7个月宝宝流清鼻涕怎么办 9个月宝宝流清鼻涕怎么办 十一个月宝宝流清鼻涕怎么办 18个月宝宝咳嗽有痰怎么办 2个月宝宝鼻子不通气怎么办 两个月的宝宝鼻塞不通气怎么办 两个月大的宝宝鼻子不通气怎么办 宝宝6个月咳嗽有痰怎么办 6个月的宝宝有痰怎么办 小孩流有点咳嗽和脓鼻涕怎么办 6个月的宝宝流鼻涕该怎么办? 小孩鼻塞不流鼻涕总吸鼻子怎么办 四个多月宝宝感冒鼻塞严重怎么办 怀孕6个月严重感冒鼻塞怎么办 16个月的宝宝上火流鼻血怎么办 小狗咳嗽打了针还不好怎么办 孕妇感冒后鼻涕带血口腔发炎怎么办 宝宝出生17天睡眠不安稳怎么办 月子里宝宝睡觉老是睡不安稳怎么办 孕妇晚期咳嗽鼻涕黄咽喉痛怎么办 狗狗流脓鼻涕拉稀没食欲怎么办 孕妇眼睛充血很快就有眼屎怎么办