I2C驅動之 sysfs系統裝置簡寫
阿新 • • 發佈:2018-12-27
#include <linux/kernel.h> #include <linux/init.h> #include <linux/module.h> #include <linux/fs.h> #include <linux/cdev.h> #include <linux/ioctl.h> #include <linux/mm.h> #include <asm/uaccess.h> #include <linux/blkdev.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/kdev_t.h> #include <linux/slab.h> #include <linux/string.h> #include <linux/major.h> #include <linux/errno.h> #include <linux/module.h> #include <linux/seq_file.h> #include <linux/kobject.h> #include <linux/kobj_map.h> #include <linux/cdev.h> #include <linux/mutex.h> #include <linux/backing-dev.h> #include <linux/tty.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/delay.h> #include <linux/hrtimer.h> #include <linux/i2c.h> #include <linux/input.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/platform_device.h> #include <linux/async.h> #include <linux/irq.h> #include <linux/workqueue.h> #include <linux/proc_fs.h> #include <linux/input/mt.h> #include <linux/of_gpio.h> #include <linux/gpio.h> #include <linux/slab.h> #include <linux/device.h> #include <linux/MCP23017.h> static int mcp23017_i2c_write( struct i2c_client* client,uint8_t reg,uint8_t data,int device_addr) { unsigned char buffer[2]; int ret; buffer[0] = reg; buffer[1] = data; mcp_iic_addr = device_addr; struct i2c_msg msgs[] = { { .addr = mcp_iic_addr, .flags = 0, // .len = writelen, .len = sizeof(buffer), .buf = buffer, }, }; client->addr=mcp_iic_addr; ret = i2c_transfer(client->adapter, msgs, 1); if (ret < 0) { dev_err(&client->dev, "%s: i2c write error.\n", __func__); printk("i2c write error\n"); return 0; } return 0; } static int mcp23017_i2c_read( struct i2c_client* client,unsigned char reg,uint8_t *data) { int ret; struct i2c_msg msgs[] = { { .addr = mcp_iic_addr, .flags = 0, // .len = 1, .len = sizeof(reg), .buf = ®,// 暫存器地址 }, { .addr = mcp_iic_addr, // .flags = I2C_M_RD,0x01 .flags = I2C_M_RD, .len = sizeof(data), .buf = data,// 暫存器的值 }, }; ret = i2c_transfer(client->adapter, msgs, 2); if (ret < 0) { printk("i2c read error\n"); } return ret; } static struct kobject *mcp23017_kobj; struct mcp23017_control_attribute { struct attribute attr; ssize_t (*show)(struct kobject *kobj, struct kobj_attribute *attr, char *buf); ssize_t (*store)(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t n); }; static struct mcp23017_control_attribute mcp23017_attribute[] = { // node_name permision show_func store_func //__ATTR(hdmiin_test, S_IRUGO | S_IWUSR, hdmiin_test_show, hdmiin_test_store), __ATTR(leda, 0777, NULL, leda_store), __ATTR(ledb, 0777, NULL, ledb_store), __ATTR(leda1, 0777, NULL, leda1_store), __ATTR(ledb1, 0777, NULL, ledb1_store), }; int k =0; static int mcp23017_probe(struct i2c_client *client, struct i2c_device_id *id) { int i =0; k++; for(i=0; i < 2; i++) { sysfs_create_file(mcp23017_kobj, &mcp23017_attribute[(k-1)*2 + i].attr); } mcp23017_client = client; ... } static const struct i2c_device_id mcp23017_id[] = { {"mcp23017_A", 0}, {"mcp23017_B", 0}, {} }; MODULE_DEVICE_TABLE(i2c, mcp23017_id); static struct i2c_driver mcp23017_drv = { .driver = { .name = "mcp23017", .owner = THIS_MODULE, }, .probe = mcp23017_probe, .id_table = mcp23017_id, }; static int mcp23017_init(void) { mcp23017_kobj = kobject_create_and_add("hello_mcp23017", NULL); i2c_add_driver(&mcp23017_drv); return 0; } static void mcp23017_exit(void) { i2c_del_driver(&mcp23017_drv); k =0; } module_init(mcp23017_init); module_exit(mcp23017_exit); MODULE_LICENSE("GPL");
裝置樹
&i2c2 {
status = "okay";
[email protected]
{
compatible = "mcp23017_A";
reg = <0x24>;
status = "okay";
};
[email protected]
{
compatible = "mcp23017_B";
reg = <0x25>;
status = "okay";
};
}