一。应用平台:MICRO2440
二。操作系统:UBUNTU10.04
三。内核版本:2.6.32.2
四。GCC编译器版本:4.4.3
五。底层驱动:
/*********************************
** at24LC04驱动程序 **
*********************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEVICE_NAME "at24lc04"
struct at24lc04_dev{
struct i2c_client *client;
char name[30];
unsigned short current_pointer;
//struct cdev cdev;
};
struct at24lc04_dev *at24lc04_devp;
static int lc04_open(struct inode *inode,struct file *file)
{
file->private_data=at24lc04_devp;
return 0;
}
static ssize_t lc04_read(struct file *file,char *buf,size_t count,loff_t *ppos)
{
int i=0;
int transferred=0;
int ret,my_buf[512];
struct at24lc04_dev *dev=(struct at24lc04_dev *)file->private_data;
dev->current_pointer=*ppos;
if(i2c_check_functionality(dev->client->adapter,I2C_FUNC_SMBUS_READ_BYTE_DATA))
{
while(transferred {
ret=i2c_smbus_read_byte_data(dev->client,dev->current_pointer+i);
my_buf[i++]=(unsigned short)ret;
transferred+=1;
}
copy_to_user(buf,(void *)my_buf,transferred);
dev->current_pointer+=transferred;
}
return transferred;
}
static ssize_t lc04_write(struct file *file,char *buf,size_t count,loff_t *ppos)
{
int i=0;
int transferred=0;
int ret,my_buf[512];
struct at24lc04_dev *dev=(struct at24lc04_dev *)file->private_data;
dev->current_pointer=*ppos;
if(i2c_check_functionality(dev->client->adapter,I2C_FUNC_SMBUS_READ_BYTE_DATA))
{copy_from_user(my_buf,buf,count);
while(transferred {
ret=i2c_smbus_write_byte_data(dev->client,dev->current_pointer+i,my_buf[i]);
i=i+1;
transferred+=1;
}
dev->current_pointer+=transferred;
}
return transferred;
}
static int lc04_close(struct inode *inodep,struct file *file)
{
file->private_data=NULL;
return 0;
}
static int __devexit at24lc04_remove(struct i2c_client *client)
{
kfree(at24lc04_devp);
return 0;
}
static int __devinit at24lc04_probe(struct i2c_client *client,const struct i2c_device_id *id)
{
printk(KERN_NOTICE"at24lc04 probe is start\n");
int ret;
at24lc04_devp=kmalloc(sizeof(struct at24lc04_dev),GFP_KERNEL);
if(!at24lc04_devp)
{
ret=-ENOMEM;
goto fail_malloc;
}
memset(at24lc04_devp,0,sizeof(struct at24lc04_dev));
at24lc04_devp->client=client;
return 0;
fail_malloc:
return ret;
}
static const struct i2c_device_id at24lc04_id[]={
{"at24lc04",0},
{}
};
MODULE_DEVICE_TABLE(i2c,at24lc04_id);
static struct i2c_driver at24lc04_driver={
.driver={
.name="at24lc04",
.owner=THIS_MODULE,
},
.probe=at24lc04_probe,
.remove=__devexit_p(at24lc04_remove),
.id_table=at24lc04_id,
};
static struct file_operations dev_fops={
.owner=THIS_MODULE,
.open=lc04_open,
.release=lc04_close,
//.ioctl=lc04_ioctl,
.read=lc04_read,
.write=lc04_write,
};
static struct miscdevice misc={
.name=DEVICE_NAME,
.minor=MISC_DYNAMIC_MINOR,
.fops=&dev_fops,
};
static int __init at24lc04_init(void)
{
misc_register(&misc);
return i2c_add_driver(&at24lc04_driver);
}
void __exit at24lc04_exit(void)
{
i2c_del_driver(&at24lc04_driver);
misc_deregister(&misc);
}
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("xubin");
module_init(at24lc04_init);
module_exit(at24lc04_exit);
六。应用程序:
#include
#include
#include
#include
#include
#include
int main(int argc,char **argv)
{
int i;
unsigned int value[512];
int fd;
value[0]=0x01;
fd=open("/dev/at24lc04",O_RDWR);
if(fd<0)
{
printf("error\n");
exit(1);
}
while(1)
{
write(fd,value,1);
printf("write reg[0]data:%x to at24lc04\n",value[0]);
sleep(1);
value[0]=0;
read(fd,value,1);
printf("read reg[0]data:%x to at24lc04\n",value[0]);
value[0]+=1;
}
return 0;
}
除了驱动程序以及应用程序外还需要对mach-mini2440.c文件进行添加更改,具体内容在稍后程序分析以及IIC知识点分析的blog上完成。
阅读(2433) | 评论(0) | 转发(0) |