Linux设备驱动i2c,linux设备驱动(3)I2C驱动

i2c驱动程序的核心是创建i2c_driver结构体

/*This is the driver that will be inserted*/

static struct i2c_driver at24cxx_driver ={

.driver={

.name= "at24cxx",

},

.id=I2C_DRIVERID_AT24Cxx,

.attach_adapter=at24cxx_attach_adapter,

.detach_client=at24cxx_detach_client,

};

再at24cxx_attach_adapter里面

static int at24cxx_attach_adapter(struct i2c_adapter *adapter)

{return i2c_probe(adapter, &addr_data, at24cxx_detect);

}

当probe到设备后, at24cxx_detect会被调用

这里有两个需要完成的

(1) 配置addr_data

(2)at24cxx_detect

对于addr_data

/** Generic i2c probe

* concerning the addresses: i2c wants 7 bit (without the r/w bit), so ‘>>1‘*/

static unsigned short normal_i2c[] ={0x50, /*7位地址*/I2C_CLIENT_END,

};static unsigned short ignore =I2C_CLIENT_END;static struct i2c_client_address_data addr_data ={

.normal_i2c=normal_i2c,

.probe= &ignore,

.ignore= &ignore,

};

而在 at24cxx_detect中主要有

(1) 设置一个i2c_client 结构体变量

(2) 设置它

(3) 注册

首先创建全局i2c_client变量

static struct i2c_client *at24cxx_client;

static int at24cxx_detect(struct i2c_adapter *adapter, int address, intkind)

{

printk(KERN_INFO"at24cxx_detect \n");int err = 0;/*分配*/at24cxx_client= kzalloc(sizeof(structi2c_client), GFP_KERNEL);/*设置*/at24cxx_client->addr =address;

at24cxx_client->adapter =adapter;

at24cxx_client->driver = &at24cxx_driver;

at24cxx_client->flags = 0;/*Fill in the remaining client fields*/strlcpy(at24cxx_client->name, "at24cxx", I2C_NAME_SIZE);/*Tell the I2C layer a new client has arrived*/

if ((err =i2c_attach_client(at24cxx_client)))gotoexit_kfree;

exit_kfree:

kfree(at24cxx_client);returnerr;

}

i2c设置好了, 数据传输使用i2c_transfer

int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)

因此, 数据传送是需要构造设置msg

与用户程序交互的读:

static int at24cxx_read (struct file *file, char __user *usrbuf, size_t len, loff_t *offset)

{/** buf[0] addr

* buf[1] data*/

intret;

unsignedcharaddress;

unsignedchardata;struct i2c_msg msg[2];if(len != 2)return -EFAULT;if(copy_from_user(&address, usrbuf, 1))

res= -EFAULT;/*i2c 传输*/

/*先发送地址*/msg[0].addr = at24cxx_client->addr; //dest

msg[0].buf = &address; //src

msg[0].flags = 0; //write

msg[0].len = 1; //len

/*再读*/msg[1].addr = at24cxx_client->addr; //dest

msg[2].buf = &data; //src

msg[1].flags = I2C_M_RD; //read

msg[1].len = 1; //len

ret= i2c_transfer(at24cxx_client->adapter, msg, 2);if(ret == 2)

{if(copy_to_user(&usrbuf, &data, 1))

res= -EFAULT;return 1;

}else

return -EIO;return 0;

}

写:

static int at24cxx_write (struct file *file, const char __user *usrbuf, size_t len, loff_t *offset)

{/** buf[0] addr

* buf[1] data*/

intret;

unsignedchar buf[2];struct i2c_msg msg[1];if(len != 2)return -EFAULT;if(copy_from_user(buf, usrbuf, 2))

res= -EFAULT;/*i2c 传输*/msg[0].addr = at24cxx_client->addr; //dest

msg[0].buf = buf; //src

msg[0].flags = 0; //write

msg[0].len = 2; //len

ret = i2c_transfer(at24cxx_client->adapter, msg, 1);if(ret == 1)return 2;else

return -EIO;

}

原文:https://www.cnblogs.com/hulig7/p/9901760.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值