1. 程式人生 > >I2C驅動之 sysfs系統裝置簡寫

I2C驅動之 sysfs系統裝置簡寫

#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 = &reg,// 暫存器地址
			 },
			{
				 .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"; }; }