1 /*
2     i2c-dev.h - i2c-bus driver, char device interface
3 
4     Copyright (C) 1995-97 Simon G. Vogl
5     Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>
6 
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11 
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15     GNU General Public License for more details.
16 
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20     MA 02110-1301 USA.
21 */
22 
23 /* $Id: i2c-dev.h 5361 2008-10-19 09:47:02Z khali $ */
24 
25 #ifndef LIB_I2CDEV_H
26 #define LIB_I2CDEV_H
27 
28 #include <sys/types.h>
29 #include <sys/ioctl.h>
30 
31 #if defined(__FreeBSD__)
32 typedef int8_t __s8;
33 typedef int16_t __s16;
34 typedef int32_t __s32;
35 typedef uint8_t __u8;
36 typedef uint16_t __u16;
37 typedef uint32_t __u32;
38 #endif
39 
40 /* -- i2c.h -- */
41 
42 
43 /*
44  * I2C Message - used for pure i2c transaction, also from /dev interface
45  */
46 struct i2c_msg {
47 	__u16 addr;	/* slave address			*/
48 	unsigned short flags;
49 #define I2C_M_TEN	0x10	/* we have a ten bit chip address	*/
50 #define I2C_M_RD	0x01
51 #define I2C_M_NOSTART	0x4000
52 #define I2C_M_REV_DIR_ADDR	0x2000
53 #define I2C_M_IGNORE_NAK	0x1000
54 #define I2C_M_NO_RD_ACK		0x0800
55 	short len;		/* msg length				*/
56 	char *buf;		/* pointer to msg data			*/
57 };
58 
59 /* To determine what functionality is present */
60 
61 #define I2C_FUNC_I2C			0x00000001
62 #define I2C_FUNC_10BIT_ADDR		0x00000002
63 #define I2C_FUNC_PROTOCOL_MANGLING	0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */
64 #define I2C_FUNC_SMBUS_PEC		0x00000008
65 #define I2C_FUNC_SMBUS_BLOCK_PROC_CALL	0x00008000 /* SMBus 2.0 */
66 #define I2C_FUNC_SMBUS_QUICK		0x00010000
67 #define I2C_FUNC_SMBUS_READ_BYTE	0x00020000
68 #define I2C_FUNC_SMBUS_WRITE_BYTE	0x00040000
69 #define I2C_FUNC_SMBUS_READ_BYTE_DATA	0x00080000
70 #define I2C_FUNC_SMBUS_WRITE_BYTE_DATA	0x00100000
71 #define I2C_FUNC_SMBUS_READ_WORD_DATA	0x00200000
72 #define I2C_FUNC_SMBUS_WRITE_WORD_DATA	0x00400000
73 #define I2C_FUNC_SMBUS_PROC_CALL	0x00800000
74 #define I2C_FUNC_SMBUS_READ_BLOCK_DATA	0x01000000
75 #define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000
76 #define I2C_FUNC_SMBUS_READ_I2C_BLOCK	0x04000000 /* I2C-like block xfer  */
77 #define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK	0x08000000 /* w/ 1-byte reg. addr. */
78 
79 #define I2C_FUNC_SMBUS_BYTE (I2C_FUNC_SMBUS_READ_BYTE | \
80                              I2C_FUNC_SMBUS_WRITE_BYTE)
81 #define I2C_FUNC_SMBUS_BYTE_DATA (I2C_FUNC_SMBUS_READ_BYTE_DATA | \
82                                   I2C_FUNC_SMBUS_WRITE_BYTE_DATA)
83 #define I2C_FUNC_SMBUS_WORD_DATA (I2C_FUNC_SMBUS_READ_WORD_DATA | \
84                                   I2C_FUNC_SMBUS_WRITE_WORD_DATA)
85 #define I2C_FUNC_SMBUS_BLOCK_DATA (I2C_FUNC_SMBUS_READ_BLOCK_DATA | \
86                                    I2C_FUNC_SMBUS_WRITE_BLOCK_DATA)
87 #define I2C_FUNC_SMBUS_I2C_BLOCK (I2C_FUNC_SMBUS_READ_I2C_BLOCK | \
88                                   I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)
89 
90 /* Old name, for compatibility */
91 #define I2C_FUNC_SMBUS_HWPEC_CALC	I2C_FUNC_SMBUS_PEC
92 
93 /*
94  * Data for SMBus Messages
95  */
96 #define I2C_SMBUS_BLOCK_MAX	32	/* As specified in SMBus standard */
97 #define I2C_SMBUS_I2C_BLOCK_MAX	32	/* Not specified but we use same structure */
98 union i2c_smbus_data {
99 	__u8 byte;
100 	__u16 word;
101 	__u8 block[I2C_SMBUS_BLOCK_MAX + 2]; /* block[0] is used for length */
102 	                                            /* and one more for PEC */
103 };
104 
105 /* smbus_access read or write markers */
106 #define I2C_SMBUS_READ	1
107 #define I2C_SMBUS_WRITE	0
108 
109 /* SMBus transaction types (size parameter in the above functions)
110    Note: these no longer correspond to the (arbitrary) PIIX4 internal codes! */
111 #define I2C_SMBUS_QUICK		    0
112 #define I2C_SMBUS_BYTE		    1
113 #define I2C_SMBUS_BYTE_DATA	    2
114 #define I2C_SMBUS_WORD_DATA	    3
115 #define I2C_SMBUS_PROC_CALL	    4
116 #define I2C_SMBUS_BLOCK_DATA	    5
117 #define I2C_SMBUS_I2C_BLOCK_BROKEN  6
118 #define I2C_SMBUS_BLOCK_PROC_CALL   7		/* SMBus 2.0 */
119 #define I2C_SMBUS_I2C_BLOCK_DATA    8
120 
121 
122 /* ----- commands for the ioctl like i2c_command call:
123  * note that additional calls are defined in the algorithm and hw
124  *	dependent layers - these can be listed here, or see the
125  *	corresponding header files.
126  */
127 				/* -> bit-adapter specific ioctls	*/
128 #define I2C_RETRIES	0x0701	/* number of times a device address      */
129 				/* should be polled when not            */
130                                 /* acknowledging 			*/
131 #define I2C_TIMEOUT	0x0702	/* set timeout - call with int 		*/
132 
133 
134 /* this is for i2c-dev.c	*/
135 #define I2C_SLAVE	0x0703	/* Change slave address			*/
136 				/* Attn.: Slave address is 7 or 10 bits */
137 #define I2C_SLAVE_FORCE	0x0706	/* Change slave address			*/
138 				/* Attn.: Slave address is 7 or 10 bits */
139 				/* This changes the address, even if it */
140 				/* is already taken!			*/
141 #define I2C_TENBIT	0x0704	/* 0 for 7 bit addrs, != 0 for 10 bit	*/
142 
143 #define I2C_FUNCS	0x0705	/* Get the adapter functionality */
144 #define I2C_RDWR	0x0707	/* Combined R/W transfer (one stop only)*/
145 #define I2C_PEC		0x0708	/* != 0 for SMBus PEC                   */
146 
147 #define I2C_SMBUS	0x0720	/* SMBus-level access */
148 
149 /* -- i2c.h -- */
150 
151 
152 /* Note: 10-bit addresses are NOT supported! */
153 
154 /* This is the structure as used in the I2C_SMBUS ioctl call */
155 struct i2c_smbus_ioctl_data {
156 	char read_write;
157 	__u8 command;
158 	int size;
159 	union i2c_smbus_data *data;
160 };
161 
162 /* This is the structure as used in the I2C_RDWR ioctl call */
163 struct i2c_rdwr_ioctl_data {
164 	struct i2c_msg *msgs;	/* pointers to i2c_msgs */
165 	int nmsgs;		/* number of i2c_msgs */
166 };
167 
168 
i2c_smbus_access(int file,char read_write,__u8 command,int size,union i2c_smbus_data * data)169 static inline __s32 i2c_smbus_access(int file, char read_write, __u8 command,
170                                      int size, union i2c_smbus_data *data)
171 {
172 	struct i2c_smbus_ioctl_data args;
173 
174 	args.read_write = read_write;
175 	args.command = command;
176 	args.size = size;
177 	args.data = data;
178 	return ioctl(file,I2C_SMBUS,&args);
179 }
180 
181 
i2c_smbus_write_quick(int file,__u8 value)182 static inline __s32 i2c_smbus_write_quick(int file, __u8 value)
183 {
184 	return i2c_smbus_access(file,value,0,I2C_SMBUS_QUICK,NULL);
185 }
186 
i2c_smbus_read_byte(int file)187 static inline __s32 i2c_smbus_read_byte(int file)
188 {
189 	union i2c_smbus_data data;
190 	if (i2c_smbus_access(file,I2C_SMBUS_READ,0,I2C_SMBUS_BYTE,&data))
191 		return -1;
192 	else
193 		return 0x0FF & data.byte;
194 }
195 
i2c_smbus_write_byte(int file,__u8 value)196 static inline __s32 i2c_smbus_write_byte(int file, __u8 value)
197 {
198 	return i2c_smbus_access(file,I2C_SMBUS_WRITE,value,
199 	                        I2C_SMBUS_BYTE,NULL);
200 }
201 
i2c_smbus_read_byte_data(int file,__u8 command)202 static inline __s32 i2c_smbus_read_byte_data(int file, __u8 command)
203 {
204 	union i2c_smbus_data data;
205 	if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
206 	                     I2C_SMBUS_BYTE_DATA,&data))
207 		return -1;
208 	else
209 		return 0x0FF & data.byte;
210 }
211 
i2c_smbus_write_byte_data(int file,__u8 command,__u8 value)212 static inline __s32 i2c_smbus_write_byte_data(int file, __u8 command,
213                                               __u8 value)
214 {
215 	union i2c_smbus_data data;
216 	data.byte = value;
217 	return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
218 	                        I2C_SMBUS_BYTE_DATA, &data);
219 }
220 
i2c_smbus_read_word_data(int file,__u8 command)221 static inline __s32 i2c_smbus_read_word_data(int file, __u8 command)
222 {
223 	union i2c_smbus_data data;
224 	if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
225 	                     I2C_SMBUS_WORD_DATA,&data))
226 		return -1;
227 	else
228 		return 0x0FFFF & data.word;
229 }
230 
i2c_smbus_write_word_data(int file,__u8 command,__u16 value)231 static inline __s32 i2c_smbus_write_word_data(int file, __u8 command,
232                                               __u16 value)
233 {
234 	union i2c_smbus_data data;
235 	data.word = value;
236 	return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
237 	                        I2C_SMBUS_WORD_DATA, &data);
238 }
239 
i2c_smbus_process_call(int file,__u8 command,__u16 value)240 static inline __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)
241 {
242 	union i2c_smbus_data data;
243 	data.word = value;
244 	if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
245 	                     I2C_SMBUS_PROC_CALL,&data))
246 		return -1;
247 	else
248 		return 0x0FFFF & data.word;
249 }
250 
251 
252 /* Returns the number of read bytes */
i2c_smbus_read_block_data(int file,__u8 command,__u8 * values)253 static inline __s32 i2c_smbus_read_block_data(int file, __u8 command,
254                                               __u8 *values)
255 {
256 	union i2c_smbus_data data;
257 	int i;
258 	if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
259 	                     I2C_SMBUS_BLOCK_DATA,&data))
260 		return -1;
261 	else {
262 		for (i = 1; i <= data.block[0]; i++)
263 			values[i-1] = data.block[i];
264 		return data.block[0];
265 	}
266 }
267 
i2c_smbus_write_block_data(int file,__u8 command,__u8 length,__u8 * values)268 static inline __s32 i2c_smbus_write_block_data(int file, __u8 command,
269                                                __u8 length, __u8 *values)
270 {
271 	union i2c_smbus_data data;
272 	int i;
273 	if (length > 32)
274 		length = 32;
275 	for (i = 1; i <= length; i++)
276 		data.block[i] = values[i-1];
277 	data.block[0] = length;
278 	return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
279 	                        I2C_SMBUS_BLOCK_DATA, &data);
280 }
281 
282 /* Returns the number of read bytes */
283 /* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you
284    ask for less than 32 bytes, your code will only work with kernels
285    2.6.23 and later. */
i2c_smbus_read_i2c_block_data(int file,__u8 command,__u8 length,__u8 * values)286 static inline __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command,
287                                                   __u8 length, __u8 *values)
288 {
289 	union i2c_smbus_data data;
290 	int i;
291 
292 	if (length > 32)
293 		length = 32;
294 	data.block[0] = length;
295 	if (i2c_smbus_access(file,I2C_SMBUS_READ,command,
296 	                     length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :
297 	                      I2C_SMBUS_I2C_BLOCK_DATA,&data))
298 		return -1;
299 	else {
300 		for (i = 1; i <= data.block[0]; i++)
301 			values[i-1] = data.block[i];
302 		return data.block[0];
303 	}
304 }
305 
i2c_smbus_write_i2c_block_data(int file,__u8 command,__u8 length,__u8 * values)306 static inline __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command,
307                                                __u8 length, __u8 *values)
308 {
309 	union i2c_smbus_data data;
310 	int i;
311 	if (length > 32)
312 		length = 32;
313 	for (i = 1; i <= length; i++)
314 		data.block[i] = values[i-1];
315 	data.block[0] = length;
316 	return i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
317 	                        I2C_SMBUS_I2C_BLOCK_BROKEN, &data);
318 }
319 
320 /* Returns the number of read bytes */
i2c_smbus_block_process_call(int file,__u8 command,__u8 length,__u8 * values)321 static inline __s32 i2c_smbus_block_process_call(int file, __u8 command,
322                                                  __u8 length, __u8 *values)
323 {
324 	union i2c_smbus_data data;
325 	int i;
326 	if (length > 32)
327 		length = 32;
328 	for (i = 1; i <= length; i++)
329 		data.block[i] = values[i-1];
330 	data.block[0] = length;
331 	if (i2c_smbus_access(file,I2C_SMBUS_WRITE,command,
332 	                     I2C_SMBUS_BLOCK_PROC_CALL,&data))
333 		return -1;
334 	else {
335 		for (i = 1; i <= data.block[0]; i++)
336 			values[i-1] = data.block[i];
337 		return data.block[0];
338 	}
339 }
340 
341 
342 #endif /* LIB_I2CDEV_H */
343