方式一
前面说了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: rt5651@1a {
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: alc5651@1a{ //新增的内容
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 #
原作者:mfence