root/i2c-tools/trunk/eepromer/24cXX.c

Revision 4230, 4.7 kB (checked in by khali, 2 years ago)

The I2C_FUNCS ioctl expects an unsigned long.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /***************************************************************************
2     copyright            : (C) by 2002-2003 Stefano Barbato
3     email                : stefano@codesink.org
4
5     $Id$
6  ***************************************************************************/
7
8 /***************************************************************************
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  ***************************************************************************/
16 #include <stdio.h>
17 #include <fcntl.h>
18 #include <unistd.h>
19 #include <stdlib.h>
20 #include <linux/fs.h>
21 #include <sys/types.h>
22 #include <sys/ioctl.h>
23 #include <errno.h>
24 #include <assert.h>
25 #include <string.h>
26 #include "24cXX.h"
27
28 static int i2c_write_1b(struct eeprom *e, __u8 buf)
29 {
30         int r;
31         // we must simulate a plain I2C byte write with SMBus functions
32         r = i2c_smbus_write_byte(e->fd, buf);
33         if(r < 0)
34                 fprintf(stderr, "Error i2c_write_1b: %s\n", strerror(errno));
35         usleep(10);
36         return r;
37 }
38
39 static int i2c_write_2b(struct eeprom *e, __u8 buf[2])
40 {
41         int r;
42         // we must simulate a plain I2C byte write with SMBus functions
43         r = i2c_smbus_write_byte_data(e->fd, buf[0], buf[1]);
44         if(r < 0)
45                 fprintf(stderr, "Error i2c_write_2b: %s\n", strerror(errno));
46         usleep(10);
47         return r;
48 }
49
50 static int i2c_write_3b(struct eeprom *e, __u8 buf[3])
51 {
52         int r;
53         // we must simulate a plain I2C byte write with SMBus functions
54         // the __u16 data field will be byte swapped by the SMBus protocol
55         r = i2c_smbus_write_word_data(e->fd, buf[0], buf[2] << 8 | buf[1]);
56         if(r < 0)
57                 fprintf(stderr, "Error i2c_write_3b: %s\n", strerror(errno));
58         usleep(10);
59         return r;
60 }
61
62
63 #define CHECK_I2C_FUNC( var, label ) \
64         do {    if(0 == (var & label)) { \
65                 fprintf(stderr, "\nError: " \
66                         #label " function is required. Program halted.\n\n"); \
67                 exit(1); } \
68         } while(0);
69
70 int eeprom_open(char *dev_fqn, int addr, int type, struct eeprom* e)
71 {
72         int fd, r;
73         unsigned long funcs;
74         e->fd = e->addr = 0;
75         e->dev = 0;
76        
77         fd = open(dev_fqn, O_RDWR);
78         if(fd <= 0)
79                 return -1;
80
81         // get funcs list
82         if((r = ioctl(fd, I2C_FUNCS, &funcs) < 0))
83                 return r;
84
85        
86         // check for req funcs
87         CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE );
88         CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE );
89         CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_BYTE_DATA );
90         CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_BYTE_DATA );
91         CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_READ_WORD_DATA );
92         CHECK_I2C_FUNC( funcs, I2C_FUNC_SMBUS_WRITE_WORD_DATA );
93
94         // set working device
95         if( ( r = ioctl(fd, I2C_SLAVE, addr)) < 0)
96                 return r;
97         e->fd = fd;
98         e->addr = addr;
99         e->dev = dev_fqn;
100         e->type = type;
101         return 0;
102 }
103
104 int eeprom_close(struct eeprom *e)
105 {
106         close(e->fd);
107         e->fd = -1;
108         e->dev = 0;
109         e->type = EEPROM_TYPE_UNKNOWN;
110         return 0;
111 }
112
113 #if 0
114 int eeprom_24c32_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data)
115 {
116         __u8 buf[3] = { (mem_addr >> 8) & 0x00ff, mem_addr & 0x00ff, data };
117         return i2c_write_3b(e, buf);
118 }
119
120
121 int eeprom_24c32_read_current_byte(struct eeprom* e)
122 {
123         ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer
124         return i2c_smbus_read_byte(e->fd);
125 }
126
127 int eeprom_24c32_read_byte(struct eeprom* e, __u16 mem_addr)
128 {
129         int r;
130         ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer
131         __u8 buf[2] = { (mem_addr >> 8) & 0x0ff, mem_addr & 0x0ff };
132         r = i2c_write_2b(e, buf);
133         if (r < 0)
134                 return r;
135         r = i2c_smbus_read_byte(e->fd);
136         return r;
137 }
138 #endif
139
140
141 int eeprom_read_current_byte(struct eeprom* e)
142 {
143         ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer
144         return i2c_smbus_read_byte(e->fd);
145 }
146
147 int eeprom_read_byte(struct eeprom* e, __u16 mem_addr)
148 {
149         int r;
150         ioctl(e->fd, BLKFLSBUF); // clear kernel read buffer
151         if(e->type == EEPROM_TYPE_8BIT_ADDR)
152         {
153                 __u8 buf =  mem_addr & 0x0ff;
154                 r = i2c_write_1b(e, buf);
155         } else if(e->type == EEPROM_TYPE_16BIT_ADDR) {
156                 __u8 buf[2] = { (mem_addr >> 8) & 0x0ff, mem_addr & 0x0ff };
157                 r = i2c_write_2b(e, buf);
158         } else {
159                 fprintf(stderr, "ERR: unknown eeprom type\n");
160                 return -1;
161         }
162         if (r < 0)
163                 return r;
164         r = i2c_smbus_read_byte(e->fd);
165         return r;
166 }
167
168 int eeprom_write_byte(struct eeprom *e, __u16 mem_addr, __u8 data)
169 {
170         if(e->type == EEPROM_TYPE_8BIT_ADDR) {
171                 __u8 buf[2] = { mem_addr & 0x00ff, data };
172                 return i2c_write_2b(e, buf);
173         } else if(e->type == EEPROM_TYPE_16BIT_ADDR) {
174                 __u8 buf[3] =
175                         { (mem_addr >> 8) & 0x00ff, mem_addr & 0x00ff, data };
176                 return i2c_write_3b(e, buf);
177         } else {
178                 fprintf(stderr, "ERR: unknown eeprom type\n");
179                 return -1;
180         }
181 }
182
Note: See TracBrowser for help on using the browser.