linux-I2C驱动(4)--编写驱动代码

开发板:讯为电子itop4412开发板,实测可行。

示例代码:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/platform_device.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/regulator/consumer.h>
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <asm/uaccess.h> 
#include <linux/miscdevice.h>
#include <linux/i2c.h>


#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>


static struct i2c_client *pocky_client;

ssize_t pocky_read(struct file *file, char __user *buffer, size_t num, loff_t *loff_t)
{
	int ret;
	struct i2c_msg msg[2];
	char buf[2];
	ret = copy_from_user(&buf,buffer,num);
	msg[0].addr  = pocky_client->addr;
	msg[0].buf	 = buf;
	msg[0].flags = 0;
	msg[0].len	 = 1;
	msg[1].addr  = pocky_client->addr;
	msg[1].buf	 = buf;
	msg[1].flags = I2C_M_RD;
	msg[1].len	 = 1;
	ret = i2c_transfer(pocky_client->adapter, msg, 2);
	if(ret < 0)
	{
		printk("read error!\n");
	}
	ret = copy_to_user(buffer,buf,num);
	
	return ret;
}
ssize_t pocky_write(struct file *file, const char __user *buffer, size_t num, loff_t *loff_t)
{
	int ret;
	struct i2c_msg msg[1];
	char buf[2];
	ret = copy_from_user(&buf,buffer,num);
	msg[0].addr  = pocky_client->addr;
	msg[0].buf	 = buf;
	msg[0].flags = 0;
	msg[0].len	 = num;
	ret = i2c_transfer(pocky_client->adapter,msg,1);
	if(ret < 0)
	{
		printk("write reg 0x%02x error!\n",buf[0]);
	}
	ret = copy_to_user(buffer,buf,num);
	return ret;
}

int pocky_open(struct inode *inode, struct file *file)
{
	printk("pocky_open open \n");
	return 0;
}

int pocky_release (struct inode *inode, struct file *file)
{
	printk("pocky_release release \n");
	return 0;
}



static struct file_operations pocky_fop = {
	.owner = THIS_MODULE,
	.open = pocky_open,
	.release = pocky_release,
	.write = pocky_write,
	.read = pocky_read,
};



static struct miscdevice i2c_dev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "my_i2c_test",
	.fops = &pocky_fop,
};


int pocky_i2c_probe(struct i2c_client *client, const struct i2c_device_id * id)
{
	printk("%S %s %d \n",__FILE__,__FUNCTION__,__LINE__);
	pocky_client = client;
	misc_register(&i2c_dev);
	return 0;
}

int pocky_i2c_remove(struct i2c_client *client)
{
	printk("%S %s %d \n",__FILE__,__FUNCTION__,__LINE__);
	misc_deregister(&i2c_dev);
	return 0;
}

int pocky_i2c_detect(struct i2c_client *client, struct i2c_board_info *info)
{
	/* 应该去访问硬件,确定设备确实存在 */
	printk("at24cxx_detect : addr = 0x%x\n",client->addr);
	if(client->addr == 0x38)
	{
		strlcpy(info->type,"i2c_pocky",I2C_NAME_SIZE);
		return 0;
	}
	else
		return -ENODEV;
}

static const unsigned short addr_list[] = {0x38,0x50,I2C_CLIENT_END};

static const struct i2c_device_id pocky_i2c_id[] = {
	{ "i2c_pocky", 0 },
	{ }
};

struct i2c_driver pocky_i2c_driver = {
	.class = I2C_CLASS_HWMON, /* 表示去那些适配器上找设备*/
	.driver = {
		   .name = "pocky",
		   .owner = THIS_MODULE,
		   },
	.probe = pocky_i2c_probe,
	.remove = pocky_i2c_remove,
	.id_table = pocky_i2c_id,
	.detect = pocky_i2c_detect,
	.address_list = addr_list,

};

static void i2c_io_init(void)
{
	int ret;
	ret = gpio_request(EXYNOS4_GPL0(2), "TP1_EN");
	if (ret) {
		printk(KERN_ERR "failed to request TP1_EN for "
				"I2C control\n");
		//return err;
	}
	gpio_direction_output(EXYNOS4_GPL0(2), 1);
	s3c_gpio_cfgpin(EXYNOS4_GPL0(2), S3C_GPIO_OUTPUT);
	gpio_free(EXYNOS4_GPL0(2));
	mdelay(5);
	
	ret = gpio_request(EXYNOS4_GPX0(3), "GPX0_3");
	if (ret) {
		gpio_free(EXYNOS4_GPX0(3));
		ret = gpio_request(EXYNOS4_GPX0(3), "GPX0_3");
	if(ret)
	{
		printk("ft5xox: Failed to request GPX0_3 \n");
	}
	}
	gpio_direction_output(EXYNOS4_GPX0(3), 0);
	mdelay(200);
	gpio_direction_output(EXYNOS4_GPX0(3), 1);
	s3c_gpio_cfgpin(EXYNOS4_GPX0(3), S3C_GPIO_OUTPUT);
	gpio_free(EXYNOS4_GPX0(3));
	msleep(300);	
}

static int pocky_init(void)
{
	i2c_io_init();
	i2c_add_driver(&pocky_i2c_driver);
	return 0;
}

static void pocky_exit(void)
{
	i2c_del_driver(&pocky_i2c_driver);
}
module_init(pocky_init);
module_exit(pocky_exit);

MODULE_LICENSE("GPL");

app:

#include <stdio.h>
#include <stdlib.h>


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>

int main(int argc,char **argv)
{
	int fd,ret;
	int data_input;
	char *i2c_device = "/dev/my_i2c_test";
	unsigned char buffer[2];
	data_input = atoi(argv[1]);
	
	printf("open %s!\n",i2c_device);
	if((fd = open(i2c_device,O_RDWR|O_NDELAY))<0)
		printf("APP open %s failed",i2c_device);
	else{
		printf("APP open %s success!\n",i2c_device);
	}
	
//读一个数据0xa6
	buffer[0] = 0xa6;
	ret = read(fd,buffer,1);
	if(ret<0)
		printf("i2c read failed!\n");
	else{
		printf("i2c read reg 0xa6 data is 0x%02x!\n",buffer[0]);
	}
	
//01先从0x00读出一个数据,02写一个数据到0x00,03再读出来对比
	//01
	buffer[0] = 0x00;
	read(fd,buffer,1);
	printf("i2c read reg 0x00 data is 0x%02x!\n",buffer[0]);
	//02
	buffer[0] = 0x00;
	buffer[1] = data_input;
	ret = write(fd,buffer,2);
	if(ret<0){
		printf("i2c write failed!\n");
		goto exit;
	}
	//03
	buffer[0] = 0x00;
	read(fd,buffer,1);
	printf("i2c read reg 0x00 data is 0x%02x!\n",buffer[0]);
	
	close(fd);
	
exit:
	close(fd);
	return -1;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值