RTEMS  5.1
libi2c.h
Go to the documentation of this file.
1 
9 #ifndef _RTEMS_LIBI2C_H
10 #define _RTEMS_LIBI2C_H
11 
12 /*
13  * Authorship
14  * ----------
15  * This software was created by
16  * Till Straumann <strauman@slac.stanford.edu>, 2005,
17  * Stanford Linear Accelerator Center, Stanford University.
18  *
19  * Acknowledgement of sponsorship
20  * ------------------------------
21  * This software was produced by
22  * the Stanford Linear Accelerator Center, Stanford University,
23  * under Contract DE-AC03-76SFO0515 with the Department of Energy.
24  *
25  * Government disclaimer of liability
26  * ----------------------------------
27  * Neither the United States nor the United States Department of Energy,
28  * nor any of their employees, makes any warranty, express or implied, or
29  * assumes any legal liability or responsibility for the accuracy,
30  * completeness, or usefulness of any data, apparatus, product, or process
31  * disclosed, or represents that its use would not infringe privately owned
32  * rights.
33  *
34  * Stanford disclaimer of liability
35  * --------------------------------
36  * Stanford University makes no representations or warranties, express or
37  * implied, nor assumes any liability for the use of this software.
38  *
39  * Stanford disclaimer of copyright
40  * --------------------------------
41  * Stanford University, owner of the copyright, hereby disclaims its
42  * copyright and all other rights in this software. Hence, anyone may
43  * freely use it for any purpose without restriction.
44  *
45  * Maintenance of notices
46  * ----------------------
47  * In the interest of clarity regarding the origin and status of this
48  * SLAC software, this and all the preceding Stanford University notices
49  * are to remain affixed to any copy or derivative of this software made
50  * or distributed by the recipient and are to be affixed to any copy of
51  * software made or distributed by the recipient that contains a copy or
52  * derivative of this software.
53  *
54  * ------------------ SLAC Software Notices, Set 4 OTT.002a, 2004 FEB 03
55  */
56 
57 #include <rtems.h>
58 
59 #include <rtems/io.h>
60 
61 #ifdef __cplusplus
62 extern "C" {
63 #endif
64 
75 /* Simple I2C driver API */
76 
77 /* Initialize the libary - may fail if no semaphore or no driver slot is available */
78 extern int rtems_libi2c_initialize (void);
79 
80 /* Alternatively to rtems_libi2c_initialize() the library can also be
81  * initialized by means of a traditional driver table entry containing
82  * the following entry points:
83  */
84 extern rtems_status_code
85 rtems_i2c_init (
86  rtems_device_major_number major,
87  rtems_device_minor_number minor,
88  void *arg);
89 
90 extern rtems_status_code
91 rtems_i2c_open (
92  rtems_device_major_number major,
93  rtems_device_minor_number minor,
94  void *arg);
95 
96 extern rtems_status_code
97 rtems_i2c_close (
98  rtems_device_major_number major,
99  rtems_device_minor_number minor,
100  void *arg);
101 
102 extern rtems_status_code
103 rtems_i2c_read (
104  rtems_device_major_number major,
105  rtems_device_minor_number minor,
106  void *arg);
107 
108 extern rtems_status_code
109 rtems_i2c_write (
110  rtems_device_major_number major,
111  rtems_device_minor_number minor,
112  void *arg);
113 
114 extern rtems_status_code
115 rtems_i2c_ioctl (
116  rtems_device_major_number major,
117  rtems_device_minor_number minor,
118  void *arg);
119 
120 extern const rtems_driver_address_table rtems_libi2c_io_ops;
121 
122 /* Unfortunately, if you want to add this driver to
123  * a RTEMS configuration table then you need all the
124  * members explicitly :-( (Device_driver_table should
125  * hold pointers to rtems_driver_address_tables rather
126  * than full structs).
127  *
128  * The difficulty is that adding this driver to the
129  * configuration table is not enough; you still need
130  * to populate the framework with low-level bus-driver(s)
131  * and high-level drivers and/or device-files...
132  *
133  * Currently the preferred way is having the BSP
134  * call 'rtems_libi2c_initialize' followed by
135  * 'rtems_libi2c_register_bus' and
136  * 'rtems_libi2c_register_drv' and/or
137  * 'mknod' (for 'raw' device nodes)
138  * from the 'bsp_predriver_hook'.
139  */
140 #define RTEMS_LIBI2C_DRIVER_TABLE_ENTRY \
141 { \
142  initialization_entry: rtems_i2c_init, \
143  open_entry: rtems_i2c_open, \
144  close_entry: rtems_i2c_close, \
145  read_entry: rtems_i2c_read, \
146  write_entry: rtems_i2c_write, \
147  control_entry: rtems_i2c_ioctl, \
148 }
149 
150 /* Bus Driver API
151  *
152  * Bus drivers provide access to low-level i2c functions
153  * such as 'send start', 'send address', 'get bytes' etc.
154  */
155 
156 /* first field must be a pointer to ops; driver
157  * may add its own fields after this.
158  * the struct that is registered with the library
159  * is not copied; a pointer will we passed
160  * to the callback functions (ops).
161  */
162 typedef struct rtems_libi2c_bus_t_
163 {
164  const struct rtems_libi2c_bus_ops_ *ops;
165  int size; /* size of whole structure */
167 
168 /* Access functions a low level driver must provide;
169  *
170  * All of these, except read_bytes and write_bytes
171  * return RTEMS_SUCCESSFUL on success and an error status
172  * otherwise. The read and write ops return the number
173  * of chars read/written or -(status code) on error.
174  */
175 typedef struct rtems_libi2c_bus_ops_
176 {
177  /* Initialize the bus; might be called again to reset the bus driver */
178  rtems_status_code (*init) (rtems_libi2c_bus_t * bushdl);
179  /* Send start condition */
180  rtems_status_code (*send_start) (rtems_libi2c_bus_t * bushdl);
181  /* Send stop condition */
182  rtems_status_code (*send_stop) (rtems_libi2c_bus_t * bushdl);
183  /* initiate transfer from (rw!=0) or to a device */
184  rtems_status_code (*send_addr) (rtems_libi2c_bus_t * bushdl,
185  uint32_t addr, int rw);
186  /* read a number of bytes */
187  int (*read_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes,
188  int nbytes);
189  /* write a number of bytes */
190  int (*write_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes,
191  int nbytes);
192  /* ioctl misc functions */
193  int (*ioctl) (rtems_libi2c_bus_t * bushdl,
194  int cmd,
195  void *buffer
196  );
198 
199 
200 /*
201  * Register a lowlevel driver
202  *
203  * TODO: better description
204  *
205  * This allocates a major number identifying *this* driver
206  * (i.e., libi2c) and the minor number encodes a bus# and a i2c address.
207  *
208  * The name will be registered in the filesystem (parent
209  * directories must exist, also IMFS filesystem must exist). It may be NULL in
210  * which case the library will pick a default.
211  *
212  * RETURNS: bus # (>=0) or -1 on error (errno set).
213  */
214 
215 extern int rtems_libi2c_register_bus (const char *name, rtems_libi2c_bus_t * bus);
216 
217 extern rtems_device_major_number rtems_libi2c_major;
218 
219 #define RTEMS_LIBI2C_MAKE_MINOR(busno, i2caddr) \
220  ((((busno)&((1<<3)-1))<<10) | ((i2caddr)&((1<<10)-1)))
221 
222 /* After the library is initialized, a major number is available.
223  * As soon as a low-level bus driver is registered (above routine
224  * returns a 'busno'), a device node can be created in the filesystem
225  * with a major/minor number pair of
226  *
227  * rtems_libi2c_major / RTEMS_LIBI2C_MAKE_MINOR(busno, i2caddr)
228  *
229  * and a 'raw' hi-level driver is then attached to this device
230  * node.
231  * This 'raw' driver has very simple semantics:
232  *
233  * 'open' sends a start condition
234  * 'read'/'write' address the device identified by the i2c bus# and address
235  * encoded in the minor number and read or write, respectively
236  * a stream of bytes from or to the device. Every time the
237  * direction is changed, a 're-start' condition followed by
238  * an 'address' cycle is generated on the i2c bus.
239  * 'close' sends a stop condition.
240  *
241  * Hence, using the 'raw' driver, e.g., 100 bytes at offset 0x200 can be
242  * read from an EEPROM by the following pseudo-code:
243  *
244  * mknod("/dev/i2c-54", mode, MKDEV(rtems_libi2c_major, RTEMS_LIBI2C_MAKE_MINOR(0,0x54)))
245  *
246  * int fd;
247  * char off[2]={0x02,0x00};
248  *
249  * fd = open("/dev/i2c-54",O_RDWR);
250  * write(fd,off,2);
251  * read(fd,buf,100);
252  * close(fd);
253  *
254  */
255 
256 /* Higher Level Driver API
257  *
258  * Higher level drivers know how to deal with specific i2c
259  * devices (independent of the bus interface chip) and provide
260  * an abstraction, i.e., the usual read/write/ioctl access.
261  *
262  * Using the above example, such a high level driver could
263  * prevent the user from issuing potentially destructive write
264  * operations (the aforementioned EEPROM interprets any 3rd
265  * and following byte written to the device as data, i.e., the
266  * contents could easily be changed!).
267  * The correct 'read-pointer offset' programming could be
268  * implemented in 'open' and 'ioctl' of a high-level driver and
269  * the user would then only have to perform harmless read
270  * operations, e.g.,
271  *
272  * fd = open("/dev/i2c.eeprom",O_RDONLY) / * opens and sets EEPROM read pointer * /
273  * ioctl(fd, IOCTL_SEEK, 0x200) / * repositions the read pointer * /
274  * read(fd, buf, 100)
275  * close(fd)
276  *
277  */
278 
279 /* struct provided at driver registration. The driver may store
280  * private data behind the mandatory first fields but the size
281  * must be set to the size of the entire struct, e.g.,
282  *
283  * struct driver_pvt {
284  * rtems_libi2c_drv_t pub;
285  * struct { ... } pvt;
286  * } my_driver = {
287  * { ops: my_ops,
288  * size: sizeof(my_driver)
289  * },
290  * { ...};
291  * };
292  *
293  * A pointer to this struct is passed to the callback ops.
294  */
295 
296 typedef struct rtems_libi2c_drv_t_
297 {
298  const rtems_driver_address_table *ops; /* the driver ops */
299  int size; /* size of whole structure (including appended private data) */
301 
302 /*
303  * The high level driver must be registered with a particular
304  * bus number and i2c address.
305  *
306  * The registration procedure also creates a filesystem node,
307  * i.e., the returned minor number is not really needed.
308  *
309  * If the 'name' argument is NULL, no filesystem node is
310  * created (but this can be done 'manually' using rtems_libi2c_major
311  * and the return value of this routine).
312  *
313  * RETURNS minor number (FYI) or -1 on failure
314  */
315 extern int
316 rtems_libi2c_register_drv (const char *name, rtems_libi2c_drv_t * drvtbl,
317  unsigned bus, unsigned i2caddr);
318 
319 /* Operations available to high level drivers */
320 
321 /* NOTES: The bus a device is attached to is LOCKED from the first send_start
322  * until send_stop is executed!
323  *
324  * Bus tenure MUST NOT span multiple system calls - otherwise, a single
325  * thread could get into the protected sections (or would deadlock if the
326  * mutex was not nestable).
327  * E.g., consider what happens if 'open' sends a 'start' and 'close'
328  * sends a 'stop' (i.e., the bus mutex would be locked in 'open' and
329  * released in 'close'. A single thread could try to open two devices
330  * on the same bus and would either deadlock or nest into the bus mutex
331  * and potentially mess up the i2c messages.
332  *
333  * The correct way is to *always* relinquish the i2c bus (i.e., send 'stop'
334  * from any driver routine prior to returning control to the caller.
335  * Consult the implementation of the generic driver routines (open, close, ...)
336  * below or the examples in i2c-2b-eeprom.c and i2c-2b-ds1621.c
337  *
338  * Drivers just pass the minor number on to these routines...
339  */
340 extern rtems_status_code rtems_libi2c_send_start (rtems_device_minor_number minor);
341 
342 extern rtems_status_code rtems_libi2c_send_stop (rtems_device_minor_number minor);
343 
344 extern rtems_status_code
345 rtems_libi2c_send_addr (rtems_device_minor_number minor, int rw);
346 
347 /* the read/write routines return the number of bytes transferred
348  * or -(status_code) on error.
349  */
350 extern int
351 rtems_libi2c_read_bytes (rtems_device_minor_number minor,
352  unsigned char *bytes, int nbytes);
353 
354 extern int
355 rtems_libi2c_write_bytes (rtems_device_minor_number minor,
356  const unsigned char *bytes, int nbytes);
357 
358 /* Send start, send address and read bytes */
359 extern int
360 rtems_libi2c_start_read_bytes (rtems_device_minor_number minor,
361  unsigned char *bytes,
362  int nbytes);
363 
364 /* Send start, send address and write bytes */
365 extern int
366 rtems_libi2c_start_write_bytes (rtems_device_minor_number minor,
367  const unsigned char *bytes,
368  int nbytes);
369 
370 
371 /* call misc iocontrol function */
372 extern int
373 rtems_libi2c_ioctl (rtems_device_minor_number minor,
374  int cmd,
375  ...);
376 /*
377  * NOTE: any low-level driver ioctl returning a negative
378  * result for release the bus (perform a STOP condition)
379  */
380 /*******************************
381  * defined IOCTLs:
382  *******************************/
383 #define RTEMS_LIBI2C_IOCTL_READ_WRITE 1
384 /*
385  * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
386  * RTEMS_LIBI2C_IOCTL_READ_WRITE,
387  * rtems_libi2c_read_write_t *arg);
388  *
389  * This call performs a simultanous read/write transfer,
390  * which is possible (and sometimes needed) for SPI devices
391  *
392  * arg is a pointer to a rd_wr info data structure
393  *
394  * This call is only needed for SPI devices
395  */
396 #define RTEMS_LIBI2C_IOCTL_START_TFM_READ_WRITE 2
397 /*
398  * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
399  * RTEMS_LIBI2C_IOCTL_START_READ_WRITE,
400  * unsigned char *rd_buffer,
401  * const unsigned char *wr_buffer,
402  * int byte_cnt,
403  * const rtems_libi2c_tfr_mode_t *tfr_mode_ptr);
404  *
405  * This call addresses a slave and then:
406  * - sets the proper transfer mode,
407  * - performs a simultanous read/write transfer,
408  * (which is possible and sometimes needed for SPI devices)
409  * NOTE: - if rd_buffer is NULL, receive data will be dropped
410  * - if wr_buffer is NULL, bytes with content 0 will transmitted
411  *
412  * rd_buffer is a pointer to a receive buffer (or NULL)
413  * wr_buffer is a pointer to the data to be sent (or NULL)
414  *
415  * This call is only needed for SPI devices
416  */
417 
418 #define RTEMS_LIBI2C_IOCTL_SET_TFRMODE 3
419 /*
420  * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
421  * RTEMS_LIBI2C_IOCTL_SET_TFRMODE,
422  * const rtems_libi2c_tfr_mode_t *tfr_mode_ptr);
423  *
424  * This call sets an SPI device to the transfer mode needed (baudrate etc.)
425  *
426  * tfr_mode is a pointer to a structure defining the SPI transfer mode needed
427  * (see below).
428  *
429  * This call is only needed for SPI devices
430  */
431 
432 #define RTEMS_LIBI2C_IOCTL_GET_DRV_T 4
433 
434 /*
435  * retval = rtems_libi2c_ioctl(rtems_device_minor_number minor,
436  * RTEMS_LIBI2C_IOCTL_GET_DRV_T,
437  * const rtems_libi2c_drv_t *drv_t_ptr);
438  *
439  * This call allows the a high-level driver to query its driver table entry,
440  * including its private data appended to it during creation of the entry
441  *
442  */
443 
451 #define RTEMS_LIBI2C_IOCTL_READ_WRITE_ASYNC 5
452 
453 /*
454  * argument data structures for IOCTLs defined above
455  */
456 typedef struct {
457  unsigned char *rd_buf;
458  const unsigned char *wr_buf;
459  int byte_cnt;
461 
462 typedef struct {
463  uint32_t baudrate; /* maximum bits per second */
464  /* only valid for SPI drivers: */
465  uint8_t bits_per_char; /* how many bits per byte/word/longword? */
466  bool lsb_first; /* true: send LSB first */
467  bool clock_inv; /* true: inverted clock (high active) */
468  bool clock_phs; /* true: clock starts toggling at start of data tfr */
469  uint32_t idle_char; /* This character will be continuously transmitted in read only functions */
471 
472 typedef struct {
473  rtems_libi2c_tfr_mode_t tfr_mode;
476 
485 typedef void (*rtems_libi2c_read_write_done_t) \
486  ( int /* return value */, int /* nbytes */, void * /* arg */);
487 
496 typedef struct {
497  unsigned char *rd_buf;
498  const unsigned char *wr_buf;
499  int byte_cnt;
501  void *arg;
503 
506 #ifdef __cplusplus
507 }
508 #endif
509 
510 #endif
IO command data for asynchronous read and write.
Definition: libi2c.h:496
Definition: libi2c.h:162
Definition: libi2c.h:472
Definition: io.h:48
void(* rtems_libi2c_read_write_done_t)(int, int, void *)
Notification function type for asynchronous read and write.
Definition: libi2c.h:486
rtems_status_code
Classic API Status.
Definition: status.h:43
Classic Input/Output Manager API.
Definition: libi2c.h:462
Definition: libi2c.h:175
Definition: libi2c.h:296
unsigned size
Definition: tte.h:74
Definition: libi2c.h:456