沉默着的莉 2021-03-15 16:52 采纳率: 0%
浏览 304

linux 驱动管理两个相同的I2C设备

 

参照以下网址,在驱动中增加了compatible属性,两个i2C设备完全相同,只有地址不同reg<24>和<21>

编译成功后,无法分别控制这两个设备,请教一下是哪里有部队的地方么?

https://bbs.csdn.net/topics/390847077

驱动编码如下

#define PCA95535_CNT	1
#define NUM_OF_DEVICES 2
#define PCA95535_NAME	"pca95535"

/*
 * two devices pca95535dev[0] and pca95535dev[1]
*/
struct pca95535_dev {
	char name[20];
	dev_t devid;					/* device ID*/
	struct cdev cdev;				/* cdev */
	struct device *device;			/* device */
	int major;						/* major ID */
	void *private_data;				/* private data */
}pca95535dev[NUM_OF_DEVICES];
	
struct class *pca95535_class;			/* class */



static int pca95535_probe(struct i2c_client *client)
{
	
	/* create ID */
	pca95535dev[0].major = 0;
	pca95535dev[1].major = 0;

	int i;
	for(i = 0;i < NUM_OF_DEVICES;i++){
		sprintf(pca95535dev[i].name,"%s%d",PCA95535_NAME,i);

		if(pca95535dev[i].major){
			pca95535dev[i].devid = MKDEV(pca95535dev[i].major, 0);
			register_chrdev_region(pca95535dev[i].devid, PCA95535_CNT,pca95535dev[i].name);
		
		}else{
				alloc_chrdev_region(&pca95535dev[i].devid, 0, PCA95535_CNT,pca95535dev[i].name);
				pca95535dev[i].major = MAJOR(pca95535dev[i].devid);
		}
	}
	
	
	/* creat and register cdev */
	for(i = 0;i<NUM_OF_DEVICES;i++){
		cdev_init(&pca95535dev[i].cdev,&pca95535_ops);
		cdev_add(&pca95535dev[i].cdev,pca95535dev[i].devid,PCA95535_CNT);
	}
	
	/* create class  in /sys/class */
	pca95535_class = class_create(THIS_MODULE,PCA95535_NAME);	
	if(IS_ERR(pca95535_class)){
		return PTR_ERR(pca95535_class);
	}
	
	for(i = 0;i<NUM_OF_DEVICES;i++){

		/* create device */
		pca95535dev[i].device = device_create(pca95535_class,NULL,pca95535dev[i].devid,
										NULL,"%s%d", PCA95535_NAME,i);
		if(IS_ERR(pca95535dev[i].device)){
			return PTR_ERR(pca95535dev[i].device);
		}
		printk("pca95535 driver setup success!\r\n");	
											
		pca95535dev[i].private_data = client;
	}
	return 0;
	
}

/*
 @description	:i2cdriver remove function ,when remove this driver would 
				 be executed
 @input-param	:i2c device
 @return		:0,success;other failed				 
 */
 
static int pca95535_remove(struct i2c_client *client)
{
	/* delete device  */
	int i ;
	for(i = 0;i<NUM_OF_DEVICES;i++){
		cdev_del(&pca95535dev[i].cdev);
		unregister_chrdev_region(pca95535dev[i].devid,PCA95535_CNT);
	
		/* unregister class and device */
		device_destroy(pca95535_class,pca95535dev[i].devid);
	}
	class_destroy(pca95535_class);
	
	return 0;
}
/* tranditional compatible table */
static const struct i2c_device_id pca95535_id[] = {
	{"ti,pca95535",0},
	{"ti,pca95535u39",1},
	{ }
};
/* device-tree compatible list*/
static const struct of_device_id pca95535_of_match[] = {
	{.compatible = "ti,pca95535"},
	{.compatible = "ti,pca95535u39"},
	{}
};

MODULE_DEVICE_TABLE(of, pca95535_of_match);
/* i2c driver struct */
static struct i2c_driver pca95535_driver = {
	.probe = pca95535_probe,
	.remove = pca95535_remove,
	.driver = {
		.owner = THIS_MODULE,
		.name = "pca95535",
		.of_match_table = pca95535_of_match,
	},
	.id_table = pca95535_id,
};



/*
 @description	:driver init function
 @param			:no
 @return		:no
 */
static int __init pca95535_init(void)
{
	int ret;	
	ret = i2c_add_driver(&pca95535_driver);
	if(ret < 0 ){
		printk("i2c device add failed\r\n");
	}
	return ret;
}


/*
 @description	: driver exit function
 */
static void __exit pca95535_exit(void)
{
	printk("pca95535 unregister!\r\n");
	i2c_del_driver(&pca95535_driver);
	
}

module_init(pca95535_init );
module_exit(pca95535_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("shyley");
  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2022-09-07 16:07
    关注
    不知道你这个问题是否已经解决, 如果还没有解决的话:

    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 以帮助更多的人 ^-^
    评论

报告相同问题?

悬赏问题

  • ¥15 请教下, VS QT 环境下, QTOPCUA 的源文件报错,这种情况咋查呢 ?
  • ¥20 UNITY webgl关于文档的上传和下载问题
  • ¥15 安霸cv22 + rtl8211f 千兆,udp传输丢包
  • ¥15 关于区块链和边缘环境搭建的相关问题
  • ¥15 windows远程桌面断卡重连软件卡顿问题
  • ¥30 Unity 实现扫描效果
  • ¥15 HbuilderX检测不到安卓模拟器
  • ¥15 这个main已经在filename.obj中定义是什么错 C语言
  • ¥15 关于#linux#的问题:exsi8.0系统 怎么更改web访问端口,不用80、443
  • ¥15 使用elementor设计样式