Linux i2c驱动(eeprom 读写)

转载地址:http://blog.csdn.net/tchonggang77/article/details/7366027

一、M24256简介

1、256 Kbit Serial I²C Bus EEPROM

2、Compatible with I2C Extended Addressing
3、Two Wire I2C Serial Interface
4、Supports 400 kHz Protocol
5、 Hardware Write Control
6、 BYTE and PAGE WRITE (up to 64 Bytes)
7、 RANDOM and SEQUENTIAL READ Modes
8、 Automatic Address Incrementing

9、管脚定义

 

 

二、M24256读写时序

1、写page时序

2、读page时序

 

三、i2c驱动

[cpp] view plain copy
  1. #include   
  2. #include   
  3. #include   
  4. #include   
  5. #include   
  6. #include   
  7. #include   
  8. #include   
  9. #include   
  10. #include   
  11. #include   
  12. #include   
  13. #include   
  14.   
  15.   
  16. #define EEPROM_MAJOR      247  
  17. #define EEPROM_I2C_MINORS 1  
  18. #define EEPROM_NAME       "eeprom"  
  19. #define I2C_EEPROM_ADDR   (0x54 << 1)  
  20. #define I2C_EEPROM_ID     777  
  21. #define EEPROM_BANK_SIZE  64  
  22. #define I2C_NAME(x)       (x)->name  
  23. #define SET_EEPROM_PAGE_ADDR 1  
  24. #define EEPROM_MAX_ADDR   0x7fff  /* 256Kbit = 32Kbyte */  
  25.   
  26. static DEFINE_SPINLOCK(i2c_dev_array_lock);  
  27. static struct i2c_driver eeprom_driver;  
  28. static struct i2c_dev *i2c_dev_array[EEPROM_I2C_MINORS]= {NULL};  
  29.   
  30. struct i2c_dev  
  31. {  
  32.     int minor;  
  33.     struct i2c_adapter *adap;  
  34.     struct i2c_client *client;  
  35.     atomic_t busy;  
  36.     unsigned short page_address;  
  37. };  
  38.   
  39. static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap)  
  40. {  
  41.     struct i2c_dev *i2c_dev = NULL;  
  42.   
  43.     if(adap == NULL)  
  44.     {  
  45.         printk("invalid parameter,adap == NULL\n");  
  46.         return NULL;  
  47.     }  
  48.   
  49.     if( adap->nr >= EEPROM_I2C_MINORS)  
  50.     {  
  51.         printk("invalid parameter,adap->nr = %d\n",adap->nr);  
  52.         return NULL;  
  53.     }  
  54.   
  55.     i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL);  
  56.     if(i2c_dev == NULL)  
  57.     {  
  58.         printk("kzalloc i2c_dev error \n");  
  59.         return NULL;  
  60.     }  
  61.   
  62.     spin_lock(&i2c_dev_array_lock);  
  63.     if (i2c_dev_array[adap->nr] != NULL)  
  64.     {  
  65.         spin_unlock(&i2c_dev_array_lock);  
  66.         printk("eeprom already has a device assigned to this adapter\n");  
  67.         goto exit;  
  68.     }  
  69.   
  70.     i2c_dev->minor = adap->nr;  
  71.     i2c_dev_array[adap->nr] = i2c_dev;  
  72.     spin_unlock(&i2c_dev_array_lock);  
  73.   
  74.     return i2c_dev;  
  75. exit:  
  76.     kfree(i2c_dev);  
  77.     return NULL;  
  78. }  
  79.   
  80. static int eeprom_detect_client(struct i2c_adapter *adapter, int address,int kind)  
  81. {  
  82.     struct i2c_client *client = NULL;  
  83.     struct i2c_dev *i2c_dev = NULL;  
  84.     char *dname = NULL;  
  85.     int ret = -1;  
  86.   
  87.     printk("detecte eeprom client on address 0x%x\n",address << 1);  
  88.   
  89.     if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))  
  90.     {  
  91.         printk("i2c check functionality failed\n");  
  92.         return -1;  
  93.     }  
  94.   
  95.     client =  kzalloc(sizeof(struct i2c_client), GFP_KERNEL);  
  96.     if (client == 0)  
  97.     {  
  98.         return -ENOMEM;  
  99.     }  
  100.   
  101.     client->addr    = address;  
  102.     client->adapter = adapter;  
  103.     client->driver  = &eeprom_driver;  
  104.     client->flags   = 0;  
  105.   
  106.     if (client->addr == (I2C_EEPROM_ADDR >> 1))  
  107.     {  
  108.         dname = EEPROM_NAME;  
  109.     }  
  110.     else  
  111.     {  
  112.         printk(" detect client: i2c addr error addr = 0x%X \n",client->addr);  
  113.         kfree(client);  
  114.         return -1;  
  115.     }  
  116.   
  117.     strlcpy(I2C_NAME(client), dname, sizeof(I2C_NAME(client)));  
  118.   
  119.     ret = i2c_attach_client(client);  
  120.     if (ret != 0)  
  121.     {  
  122.         printk(" detect client: i2c_attach_client(),ret = %d \n",ret);  
  123.         kfree(client);  
  124.         return ret;  
  125.     }  
  126.   
  127.     i2c_dev = get_free_i2c_dev(adapter);  
  128.     if (i2c_dev == NULL)  
  129.     {  
  130.         kfree(client);  
  131.         return -1;  
  132.     }  
  133.   
  134.     printk("eeprom adapter [%s] registered as minor %d\n",adapter->name, i2c_dev->minor);  
  135.   
  136.     i2c_dev->adap = adapter;  
  137.     i2c_dev->client = client;  
  138.     atomic_set(&(i2c_dev->busy),1);  
  139.   
  140.     return 0;  
  141. }  
  142.   
  143. static unsigned short normal_i2c[] = {I2C_EEPROM_ADDR >> 1,  I2C_CLIENT_END};  
  144. static unsigned short ignore = I2C_CLIENT_END;  
  145. static struct i2c_client_address_data addr_data =  
  146. {  
  147.     .normal_i2c  = normal_i2c,  
  148.     .probe       = &ignore,  
  149.     .ignore      = &ignore,  
  150. };  
  151.   
  152. static int return_i2c_dev(struct i2c_dev *i2c_dev)  
  153. {  
  154.     if(i2c_dev == NULL)  
  155.     {  
  156.         printk("invalid parameter,i2c_dev == NULL\n");  
  157.         return -1;  
  158.     }  
  159.   
  160.     if(i2c_dev->minor >= EEPROM_I2C_MINORS)  
  161.     {  
  162.         printk("invalid parameter,i2c_dev->minor = %d\n",i2c_dev->minor);  
  163.         return -1;  
  164.     }  
  165.     spin_lock(&i2c_dev_array_lock);  
  166.     i2c_dev_array[i2c_dev->minor] = NULL;  
  167.     spin_unlock(&i2c_dev_array_lock);  
  168.     kfree(i2c_dev);  
  169.   
  170.     return 0;  
  171. }  
  172.   
  173. static struct i2c_dev *i2c_dev_get_by_adapter(struct i2c_adapter *adap)  
  174. {  
  175.     struct i2c_dev *i2c_dev = NULL;  
  176.   
  177.     if(adap == NULL)  
  178.     {  
  179.         printk("invalid parameter,adap == NULL\n");  
  180.         return NULL;  
  181.     }  
  182.     if(adap->nr >= EEPROM_I2C_MINORS)  
  183.     {  
  184.         printk("invalid parameter,adap->nr = %d\n",adap->nr);  
  185.         return NULL;  
  186.     }  
  187.   
  188.     spin_lock(&i2c_dev_array_lock);  
  189.     if ((i2c_dev_array[adap->nr] != NULL) && (i2c_dev_array[adap->nr]->adap == adap))  
  190.     {  
  191.         i2c_dev = i2c_dev_array[adap->nr];  
  192.     }  
  193.     spin_unlock(&i2c_dev_array_lock);  
  194.   
  195.     return i2c_dev;  
  196. }  
  197.   
  198. static int eeprom_attach_adapter(struct i2c_adapter *adap)  
  199. {  
  200.     printk("start probe for adapter %s (0x%x)\n",I2C_NAME(adap), adap->nr);  
  201.     return i2c_probe(adap, &addr_data, &eeprom_detect_client);  
  202. }  
  203.   
  204. static int eeprom_detach_client(struct i2c_client *client)  
  205. {  
  206.     struct i2c_dev *i2c_dev = NULL;  
  207.     int ret = -1;  
  208.   
  209.     if(client == NULL)  
  210.     {  
  211.         printk("invalid parameter,client == NULL\n");  
  212.         return -1;  
  213.     }  
  214.   
  215.     i2c_dev = i2c_dev_get_by_adapter(client->adapter);  
  216.     if(i2c_dev == NULL)  
  217.     {  
  218.         printk("invalid parameter,i2c_dev == NULL\n");  
  219.         return -1;  
  220.     }  
  221.   
  222.     return_i2c_dev(i2c_dev);  
  223.     ret = i2c_detach_client(client);  
  224.     if (ret != 0)  
  225.     {  
  226.         printk("i2c_detach_client() error,ret == %d\n",ret);  
  227.         return ret;  
  228.     }  
  229.     kfree(client);  
  230.     printk("eeprom detach client success\n");  
  231.   
  232.     return 0;  
  233. }  
  234.   
  235. static struct i2c_driver eeprom_driver =  
  236. {  
  237.     .driver =  
  238.     {  
  239.         .name       = "eeprom_driver",  
  240.     },  
  241.     .id             = I2C_EEPROM_ID,  
  242.     .attach_adapter = eeprom_attach_adapter,  
  243.     .detach_client  = eeprom_detach_client,  
  244. };  
  245.   
  246. static struct i2c_dev *i2c_dev_get_by_minor(unsigned index)  
  247. {  
  248.     struct i2c_dev *i2c_dev = NULL;  
  249.   
  250.     if(index >= EEPROM_I2C_MINORS)  
  251.     {  
  252.         printk("invalid parameter,index = %d\n",index);  
  253.         return NULL;  
  254.     }  
  255.   
  256.     spin_lock(&i2c_dev_array_lock);  
  257.     i2c_dev = i2c_dev_array[index];  
  258.     spin_unlock(&i2c_dev_array_lock);  
  259.   
  260.     return i2c_dev;  
  261. }  
  262.   
  263. static inline int eeprom_read_byte(struct i2c_client *client, u8 reg)  
  264. {  
  265.     if (client == NULL)  
  266.     {  
  267.         printk("invalid parameter,client == NULL\n");  
  268.         return -1;  
  269.     }  
  270.     return i2c_smbus_read_byte_data(client, reg);  
  271. }  
  272.   
  273. static inline int eeprom_write_byte(struct i2c_client *client, u8 reg, u8 value)  
  274. {  
  275.     int ret = -1;  
  276.   
  277.     if (client == NULL)  
  278.     {  
  279.         printk("invalid parameter,client == NULL\n");  
  280.         return -1;  
  281.     }  
  282.   
  283.     ret = i2c_smbus_write_byte_data(client, reg, value);  
  284.     if(ret != 0)  
  285.     {  
  286.         printk("eeprom write addr:0x%x,name:%s,reg:0x%x,value0x%x\n",client->addr,client->name,reg,value);  
  287.     }  
  288.   
  289.     return ret;  
  290. }  
  291.   
  292. static int eeprom_open(struct inode *node,struct file *file)  
  293. {  
  294.     unsigned int minor = iminor(node);  
  295.     struct i2c_dev *i2c_dev = NULL;  
  296.   
  297.     printk("eeprom open\n");  
  298.   
  299.     i2c_dev = i2c_dev_get_by_minor(minor);  
  300.     i2c_dev->page_address = 0;  
  301.     set_wc_bit_high(); /* 写保护信号拉高 */  
  302.     file->private_data = i2c_dev;  
  303.   
  304.     if (atomic_dec_and_test(&i2c_dev->busy) == 0)  
  305.     {  
  306.         atomic_inc(&i2c_dev->busy);  
  307.         return -EBUSY; /* already open */  
  308.     }  
  309.   
  310.     return 0;  
  311. }  
  312.   
  313. static int eeprom_release(struct inode *node,struct file *file)  
  314. {  
  315.     struct i2c_dev * i2c_dev = (struct i2c_dev *)file->private_data;  
  316.   
  317.     if(i2c_dev == NULL)  
  318.     {  
  319.         printk("invalid parameter,i2c_dev == NULL\n");  
  320.         return -1;  
  321.     }  
  322.   
  323.     atomic_inc(&i2c_dev->busy);  
  324.     file->private_data = NULL;  
  325.     printk("eeprom release\n");  
  326.   
  327.     return 0;  
  328. }  
  329.   
  330. static ssize_t eeprom_read(struct file *filp,char *buf, size_t count, loff_t *offset)  
  331. {  
  332.     struct i2c_dev *i2c_dev = (struct i2c_dev *)filp->private_data;  
  333.     struct i2c_client *client = i2c_dev->client;  
  334.     int ret = -1;  
  335.     char my_buf[EEPROM_BANK_SIZE] = {0,};  
  336.     char message[2] = {0,};  
  337.   
  338.     if(i2c_dev->page_address + count > EEPROM_MAX_ADDR)  
  339.     {  
  340.         printk("eeprom read address range beyond\n");  
  341.         i2c_dev->page_address = 0;  
  342.         return -1;  
  343.     }  
  344.   
  345.     set_wc_bit_low(); /* 写保护信号拉低 */  
  346.     mdelay(1);  
  347.   
  348.     message[0] = (u8)(i2c_dev->page_address >> 8);  
  349.     message[1] = (u8)(i2c_dev->page_address);  
  350.     i2c_master_send(client, message, 2);  
  351.     i2c_master_recv(client, my_buf, count);  
  352.   
  353.     set_wc_bit_high(); /* 写保护信号拉高 */  
  354.     copy_to_user(buf, (void *)my_buf, count);  
  355.   
  356.     return count;  
  357. }  
  358.   
  359. static ssize_t eeprom_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)  
  360. {  
  361.     struct i2c_dev *i2c_dev = (struct i2c_dev *)file->private_data;  
  362.     struct i2c_client *client = i2c_dev->client;  
  363.     int ret = -1;  
  364.     char message[EEPROM_BANK_SIZE + 2] = {0,};  
  365.   
  366.     if(i2c_dev->page_address + count > EEPROM_MAX_ADDR)  
  367.     {  
  368.         printk("eeprom write address range beyond\n");  
  369.         i2c_dev->page_address = 0;  
  370.         return -1;  
  371.     }  
  372.   
  373.     if(count > EEPROM_BANK_SIZE)  
  374.     {  
  375.         count = EEPROM_BANK_SIZE;  
  376.     }  
  377.   
  378.     message[0] = (u8)(i2c_dev->page_address >> 8);  
  379.     message[1] = (u8)(i2c_dev->page_address);  
  380.   
  381.     ret = copy_from_user(&message[2], (void *)buf, count);  
  382.     if(ret != 0)  
  383.     {  
  384.         printk("eeprom write copy_from_user failed\n");  
  385.         return -1;  
  386.     }  
  387.   
  388.     set_wc_bit_high(); /* 写保护信号拉低 */  
  389.     mdelay(1);  
  390.   
  391.     i2c_master_send(client, message, count + 2);  
  392.   
  393.     mdelay(1);  
  394.     set_wc_bit_high(); /* 写保护信号拉高 */  
  395.   
  396.     return count;  
  397. }  
  398.   
  399. static int eeprom_ioctl(struct inode *inode, struct file *file,unsigned int cmd, unsigned long arg)  
  400. {  
  401.     struct i2c_dev * i2c_dev = (struct i2c_dev *)file->private_data;  
  402.   
  403.     if(i2c_dev == NULL)  
  404.     {  
  405.         printk("invalid parameter,i2c_dev == NULL\n");  
  406.         return -1;  
  407.     }  
  408.   
  409.     switch(cmd)  
  410.     {  
  411.         case SET_EEPROM_PAGE_ADDR:  
  412.             if(arg > EEPROM_MAX_ADDR)  
  413.             {  
  414.                 printk("eeprom address range beyond\n");  
  415.                 i2c_dev->page_address = 0;  
  416.                 return -1;  
  417.             }  
  418.             else  
  419.             {  
  420.                 i2c_dev->page_address = (unsigned short)arg;  
  421.             }  
  422.             break;  
  423.         default:  
  424.             printk("eeprom cmd error!\n");  
  425.             return -1;  
  426.     }  
  427.   
  428.     return 0;  
  429. }  
  430.   
  431. static struct file_operations eeprom_fops =  
  432. {  
  433.     .owner   = THIS_MODULE,  
  434.     .open    = eeprom_open,  
  435.     .release = eeprom_release,  
  436.     .read    = eeprom_read,  
  437.     .write   = eeprom_write,  
  438.     .ioctl   = eeprom_ioctl,  
  439. };  
  440.   
  441. static int __init eeprom_init(void)  
  442. {  
  443.     int ret = -1;  
  444.   
  445.     ret = register_chrdev(EEPROM_MAJOR, EEPROM_NAME, &eeprom_fops);  
  446.     if (ret != 0)  
  447.     {  
  448.         printk("%s: can't get major %d", EEPROM_NAME, EEPROM_MAJOR);  
  449.         goto exit;  
  450.     }  
  451.   
  452.     memset(i2c_dev_array, 0 ,sizeof(i2c_dev_array));  
  453.   
  454.     ret = i2c_add_driver(&eeprom_driver);  
  455.     if (ret != 0)  
  456.     {  
  457.         printk("i2c add eeprom_driver error!\n");  
  458.         goto unregister_chrdev;  
  459.     }  
  460.     return 0;  
  461.   
  462. unregister_chrdev:  
  463.     unregister_chrdev(EEPROM_MAJOR, EEPROM_NAME);  
  464. exit:  
  465.     return ret;  
  466. }  
  467.   
  468. static void __exit eeprom_exit(void)  
  469. {  
  470.     i2c_del_driver(&eeprom_driver);  
  471.     unregister_chrdev(EEPROM_MAJOR, EEPROM_NAME);  
  472. }  
  473.   
  474. MODULE_DESCRIPTION("eeprom driver");  
  475. MODULE_LICENSE("GPL");  
  476.   
  477. module_init(eeprom_init);  
  478. module_exit(eeprom_exit); 

你可能感兴趣的:(Linux i2c驱动(eeprom 读写))