rk3399下iic驅動方式二-----裝置樹
阿新 • • 發佈:2018-11-09
前面說了iic在新核心下的一種方式,下面是第二種方式,這種方式在fireflyWiki教程裡面有說明
程式碼如下
#include <linux/kernel.h> #include <linux/module.h> #include <linux/platform_device.h> #include <linux/i2c.h> #include <linux/err.h> #include <linux/regmap.h> #include <linux/slab.h> #include <linux/fs.h> #include <asm/uaccess.h> static int major; static struct class *class; static struct i2c_client *iic_client; static int read_reg(const struct i2c_client *client, unsigned int *buf , unsigned char address) { struct i2c_msg msg[2]; int ret; unsigned char date1[2]; msg[0].addr = client->addr; msg[0].buf = &address; msg[0].len = 1; msg[0].flags = 0; msg[1].addr = client->addr; msg[1].buf = date1; msg[1].len = 2; msg[1].flags = I2C_M_RD; ret = i2c_transfer(client->adapter, msg, 2); if (ret > 0) { printk(KERN_INFO "date1 : %d date1 :%d\n",date1[0],date1[1]); *buf = (date1[0] << 8) | (date1[1]); return 1; } else return -EIO; } static struct file_operations iic_fops = { .owner = THIS_MODULE, }; static int iic_probe(struct i2c_client *client,const struct i2c_device_id *id) { int ret; unsigned int data = 0; iic_client = client; printk(KERN_INFO "%s %s %d\n", __FILE__, __FUNCTION__, __LINE__); major = register_chrdev(0, "iic", &iic_fops); class = class_create(THIS_MODULE, "iic"); device_create(class, NULL, MKDEV(major, 0), NULL, "iic"); ret = read_reg(iic_client,&data,0xff); printk(KERN_INFO "Device ID 0x%x\n",data); return 0; } static int iic_remove(struct i2c_client *client) { printk(KERN_INFO "%s %s %d\n", __FILE__, __FUNCTION__, __LINE__); device_destroy(class, MKDEV(major, 0)); class_destroy(class); unregister_chrdev(major, "iic"); return 0; } static const struct i2c_device_id iic_id_table[] = { { "iic_test", 0 }, {} }; static const struct of_device_id of_alc_match[] = { { .compatible = "alc5651" }, { } }; static struct i2c_driver iic_driver = { .driver = { .name = "rt5651_iic", .owner = THIS_MODULE, .of_match_table = of_alc_match, }, .probe = iic_probe, .remove = iic_remove, .id_table = iic_id_table, }; static int iic_drv_init(void) { printk(KERN_INFO "%s %s %d\n", __FILE__, __FUNCTION__, __LINE__); i2c_add_driver(&iic_driver); return 0; } static void iic_drv_exit(void) { i2c_del_driver(&iic_driver); } module_init(iic_drv_init); module_exit(iic_drv_exit); MODULE_LICENSE("GPL");
makefile檔案就不貼了,前一篇文章有說
dts檔案中新增內容:
&i2c1 {
status = "okay";
i2c-scl-rising-time-ns = <300>;
i2c-scl-falling-time-ns = <15>;
rt5651: [email protected] {
#sound-dai-cells = <0>;
compatible = "realtek,rt5651";
reg = <0x1a>;
clocks = <&cru SCLK_I2S_8CH_OUT>;
clock-names = "mclk";
pinctrl-names = "default";
pinctrl-0 = <&i2s_8ch_mclk>;
spk-con-gpio = <&gpio0 11 GPIO_ACTIVE_HIGH>;
};
alc5651: [email protected]{ //新增的內容
status = "okay";
compatible = "alc5651";
reg = <0x1a>;//iic裝置地址,不可忽略,必須寫對
};
};
一樣,還是貼一下結果,注意,這裡的模組裡面沒有iic_dev.ko,只有iic_dts.ko這個模組被載入
g3399:/storage/0000-0000 # ls LOST.DIR cmd_test iic_dev.ko test.ko System Volume Information iic.ko iic_dts.ko test_char.ko g3399:/storage/0000-0000 # insmod iic_dts.ko [ 449.444537] /rk3399/source/g3399-v7-1-2-20180529/test_code/iic/iic_dts.c iic_drv_init 96 [ 449.452793] /rk3399/source/g3399-v7-1-2-20180529/test_code/iic/iic_dts.c iic_probe 55 [ 449.456078] dag3399:/storage/0000-0000 # te1 : 98 date1 :129 [ 449.456099] Device ID 0x6281 g3399:/storage/0000-0000 # g3399:/storage/0000-0000 # g3399:/storage/0000-0000 # g3399:/storage/0000-0000 # lsmod Module Size Used by iic_dts 4050 0 g3399:/storage/0000-0000 #