您的位置:首页 > 运维架构 > Linux

IIC Device(At24c02) Driver for Linux2.6.xx+ARM9

2013-02-02 19:09 519 查看
/* iic-dev: at24c02 256bytes(2k bits)

  * From 2013-01-31 To 2013-02-02

  */

----------------------------------------------------------driver---------------------------------------------------------------

#include <linux/kernel.h>

#include <linux/init.h>

#include <linux/module.h>

#include <linux/slab.h>

#include <linux/jiffies.h>

#include <linux/i2c.h>

#include <linux/mutex.h>

//begin

#include <linux/fs.h>

//error: variable `at24c02_operations' has initializer but incomplete type

//end

//begin

//czat24c02_iicdev: Unknown symbol copy_from_user

#include <asm/uaccess.h>

//end

static unsigned short ignore[] = { I2C_CLIENT_END };

static unsigned short normal_addr[] = { 0x50, I2C_CLIENT_END };

static int major;

static struct class *at24c02_cls;

static struct class_device *at24c02_cls_dev;

static struct i2c_client *new_client;

static struct i2c_client_address_data addr_data = {

 .normal_i2c = normal_addr,

 .probe = ignore,

 .ignore = ignore,

};

static struct bin_attribute at24c02_attr = {

 .attr = {

  .name = "at24c02",

  .mode = S_IRUGO,

  .owner = THIS_MODULE,

 },

 //.size = EEPROM_SIZE,

 //.read = eeprom_read,

};

static int czat24c02_attach_adapter(struct i2c_adapter *adapter);

static int czat24c02_detach_client(struct i2c_client *client);

static struct i2c_driver at24c02_driver = {

 .driver = {

  .name = "at24c02",

 },

 //.id  = I2C_DRIVERID_EEPROM,

 .attach_adapter = czat24c02_attach_adapter,

 .detach_client = czat24c02_detach_client,

};

static ssize_t czat24c02_read (struct file *file, char __user *buffer, size_t size, loff_t *ppos)

{

 printk("driver: czat24c02_read in ok\n");

 if (size != 1)

       printk("driver: czat24c02_read size != 1\n");

 struct i2c_msg msg[2];

 unsigned char val; //val[1]:addr for reading

 unsigned char data;

 

 copy_from_user(&val, buffer, 1);//get the addr for reading

 printk("driver: czat24c02_read copy_from_user ok\n");

 msg[0].addr = 0x50; //at24c02 address

 msg[0].buf = &val;

 msg[0].len = 1;

 msg[0].flags = 0; //write addr

 msg[1].addr = 0x50; //at24c02 address

 msg[1].buf = &data;//get the data

 msg[1].len = 1;

 msg[1].flags = I2C_M_RD; //read addr

 if((i2c_transfer(new_client->adapter, msg, 2))==2)

  {

   printk("driver: czat24c02_read i2c_transfer=2 ok\n");

   copy_to_user(buffer,&data,1);//tell app what we got

   printk("driver: czat24c02_read copy_to_user ok\n");

   return 0;

  }

 printk("driver: czat24c02_read i2c_transfer !!!!=2\n");

 return -EIO;

}

static int czat24c02_write (struct file *file, const char __user *buffer, size_t size, loff_t *ppos)

{

 printk("driver: czat24c02_write in ok\n");

 struct i2c_msg msg[1];

 unsigned char val[2]; //val[1]:addr for writing, val[2]:data for writing

 

 copy_from_user(val, buffer, 2);

 printk("driver: czat24c02_write addr:%d, data:%d\n",val[0],val[1]);

 msg[0].addr = 0x50; //at24c02 address

 msg[0].buf = val;

 msg[0].len = 2;

 msg[0].flags = 0; //write msg

 

 i2c_transfer(new_client->adapter, msg, 1);

 

 return 0;

}

static int czat24c02_open(struct inode *inode, struct file *file)

{

 printk("driver: czat24c02_open in ok\n");

 return 0;

}

static struct file_operations at24c02_operations = {

 .owner = THIS_MODULE,

 .open = czat24c02_open,

 .read   = czat24c02_read,

 .write  = czat24c02_write,

};

static int czat24c02_detect(struct i2c_adapter *adapter, int address, int kind)

{

 printk("driver: czat24c02_detect in ok\n");

 i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE_DATA

       | I2C_FUNC_SMBUS_BYTE);

 new_client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);

 new_client->addr = address;

 new_client->adapter = adapter;

 new_client->driver = &at24c02_driver;

 new_client->flags = 0;

 

 strlcpy(new_client->name, "at24c02", I2C_NAME_SIZE);

 i2c_attach_client(new_client);

 sysfs_create_bin_file(&new_client->dev.kobj, &at24c02_attr);

 major = register_chrdev(0, "at24c02", &at24c02_operations);

 at24c02_cls = class_create(THIS_MODULE, "at24c02_cls");

 at24c02_cls_dev = class_device_create(at24c02_cls, NULL, MKDEV(major,0), NULL, "at24c02_cls_dev");

 return 0;

}

static int czat24c02_detach_client(struct i2c_client *client)

{

 printk("driver: czat24c02_detach_client in ok\n");

 int err;

 sysfs_remove_bin_file(&client->dev.kobj, &at24c02_attr);

 err = i2c_detach_client(client);

 if (err)

  return err;

 kfree(i2c_get_clientdata(client));

 

 class_device_destroy(at24c02_cls, MKDEV(major,0));

 class_destroy(at24c02_cls);

 unregister_chrdev(major, "at24c02");

 return 0;

}

static int czat24c02_attach_adapter(struct i2c_adapter *adapter)

{

 printk("driver: czat24c02_attach_adapter in ok\n");

 return i2c_probe(adapter, &addr_data, czat24c02_detect);

}

static int __init czat24c02_init(void)

{

 printk("driver: czat24c02_init in ok\n");

 i2c_add_driver(&at24c02_driver);

 return 0;

}

static void __exit czat24c02_exit(void)

{

 printk("driver: czat24c02_exit in ok\n");

 i2c_del_driver(&at24c02_driver);

}

module_init(czat24c02_init);

module_exit(czat24c02_exit);

MODULE_AUTHOR("chaozang(cz) <zangchao.cn@gmail.com>,copy frm my teacher:weidongshan,thanks so much!");

MODULE_LICENSE("GPL");

----------------------------------------------------test app----------------------------------------------------------

/*

  *  read: at24c02 addr

  * write: at24c02 addr data

 */

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <stdio.h>

void print_usage(char *file)

{

 printf(" read: %s addr\n",file);

 printf("write: %s addr data\n",file);

}

//char *argv[ ] == char **argv

int main(int argc, char **argv)

{

 int fd;

 unsigned char buffer[2];

 

 if((argc != 2)&&(argc != 3))

  print_usage(argv[0]);

 fd = open("/dev/at24c02_cls_dev",O_RDWR);

 if (fd < 0)

 {

  printf("can't open /dev/at24c02_cls_dev\n");

  return -1;

 }

 

 //if (strcmp(argv[1], "r") == 0)

 if(argc == 2)

  {

      printf("app: argc == 2\n");

   buffer[0] = strtoul(argv[1], NULL, 0);

   printf("app: buffer[0] is %d\n",buffer[0]);

   read(fd, buffer, 1);

   printf("app: read result is:%d\n",buffer[0]);

   //begin

   //printf("app: read result is:%s\n",buffer[0]);

   //Segmentation fault

   //end

   

  }

 else if(argc == 3)

  {

   buffer[0] = strtoul(argv[1], NULL, 0);

   buffer[1] = strtoul(argv[2], NULL, 0);

   write(fd, buffer, 2);

  }

 else

  {

   print_usage(argv[0]);

   return -1;

  }

 

 return 0;

}

-----------------------------------------------------------

Contact: zangchao.cn@gmail.com
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: