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