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