1. 程式人生 > >rk3399下iic驅動方式二-----裝置樹

rk3399下iic驅動方式二-----裝置樹

方式一

前面說了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 #