Chinaunix首页 | 论坛 | 博客
  • 博客访问: 119404
  • 博文数量: 24
  • 博客积分: 616
  • 博客等级: 中士
  • 技术积分: 375
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-01 10:54
文章分类
文章存档

2012年(24)

我的朋友

分类: LINUX

2012-07-13 13:01:20

一。应用平台: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) |
给主人留下些什么吧!~~