source: rtems/cpukit/libi2c/libi2c.h @ dbe8e519

4.104.114.84.9
Last change on this file since dbe8e519 was 199e748, checked in by Ralf Corsepius <ralf.corsepius@…>, on Nov 6, 2005 at 9:22:09 AM

Eliminate obsolete types.

  • Property mode set to 100644
File size: 7.9 KB
Line 
1#ifndef RTEMS_LIBI2C_H
2#define RTEMS_LIBI2C_H
3/*$Id$*/
4#include <rtems.h>
5
6#include <rtems/io.h>
7
8#ifdef __cplusplus
9extern "C" {
10#endif
11
12/* Simple I2C driver API */
13
14/* Initialize the libary - may fail if no semaphore or no driver slot is available */
15int rtems_libi2c_initialize ();
16
17/* Bus Driver API
18 *
19 * Bus drivers provide access to low-level i2c functions
20 * such as 'send start', 'send address', 'get bytes' etc.
21 */
22
23/* first field must be a pointer to ops; driver
24 * may add its own fields after this.
25 * the struct that is registered with the library
26 * is not copied; a pointer will we passed
27 * to the callback functions (ops).
28 */
29typedef struct rtems_libi2c_bus_t_
30{
31  struct rtems_libi2c_bus_ops_ *ops;
32  int size;                     /* size of whole structure */
33} rtems_libi2c_bus_t;
34
35/* Access functions a low level driver must provide;
36 *
37 * All of these, except read_bytes and write_bytes
38 * return RTEMS_SUCCESSFUL on success and an error status
39 * otherwise. The read and write ops return the number
40 * of chars read/written or -(status code) on error.
41 */
42typedef struct rtems_libi2c_bus_ops_
43{
44  /* Initialize the bus; might be called again to reset the bus driver */
45  rtems_status_code (*init) (rtems_libi2c_bus_t * bushdl);
46  /* Send start condition */
47  rtems_status_code (*send_start) (rtems_libi2c_bus_t * bushdl);
48  /* Send stop  condition */
49  rtems_status_code (*send_stop) (rtems_libi2c_bus_t * bushdl);
50  /* initiate transfer from (rw!=0) or to a device */
51  rtems_status_code (*send_addr) (rtems_libi2c_bus_t * bushdl,
52                                  uint32_t addr, int rw);
53  /* read a number of bytes */
54  int (*read_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes,
55                     int nbytes);
56  /* write a number of bytes */
57  int (*write_bytes) (rtems_libi2c_bus_t * bushdl, unsigned char *bytes,
58                      int nbytes);
59} rtems_libi2c_bus_ops_t;
60
61
62/*
63 * Register a lowlevel driver
64 *
65 * TODO: better description
66 *
67 * This  allocates a major number identifying *this* driver
68 * (i.e., libi2c) and the minor number encodes a bus# and a i2c address.
69 *
70 * The name will be registered in the filesystem (parent
71 * directories must exist). It may be NULL in which case
72 * the library will pick a default.
73 *
74 * RETURNS: bus # (>=0) or -1 on error (errno set).
75 */
76
77int rtems_libi2c_register_bus (char *name, rtems_libi2c_bus_t * bus);
78
79extern rtems_device_major_number rtems_libi2c_major;
80
81#define RTEMS_LIBI2C_MAKE_MINOR(busno, i2caddr) \
82        ((((busno)&((1<<3)-1))<<10) | ((i2caddr)&((1<<10)-1)))
83
84/* After the library is initialized, a major number is available.
85 * As soon as a low-level bus driver is registered (above routine
86 * returns a 'busno'), a device node can be created in the filesystem
87 * with a major/minor number pair of
88 *
89 *    rtems_libi2c_major / RTEMS_LIBI2C_MAKE_MINOR(busno, i2caddr)
90 *
91 * and a 'raw' hi-level driver is then attached to this device
92 * node.
93 * This 'raw' driver has very simple semantics:
94 *
95 *   'open'         sends a start condition
96 *   'read'/'write' address the device identified by the i2c bus# and address
97 *                  encoded in the minor number and read or write, respectively
98 *                  a stream of bytes from or to the device. Every time the
99 *                  direction is changed, a 're-start' condition followed by
100 *                  an 'address' cycle is generated on the i2c bus.
101 *   'close'        sends a stop condition.
102 *
103 * Hence, using the 'raw' driver, e.g., 100 bytes at offset 0x200 can be
104 * read from an EEPROM by the following pseudo-code:
105 *
106 *   mknod("/dev/i2c-54", mode, MKDEV(rtems_libi2c_major, RTEMS_LIBI2C_MAKE_MINOR(0,0x54)))
107 *
108 *   int fd;
109 *   char off[2]={0x02,0x00};
110 *
111 *   fd = open("/dev/i2c-54",O_RDWR);
112 *   write(fd,off,2);
113 *   read(fd,buf,100);
114 *   close(fd);
115 *
116 */
117
118/* Higher Level Driver API
119 *
120 * Higher level drivers know how to deal with specific i2c
121 * devices (independent of the bus interface chip) and provide
122 * an abstraction, i.e., the usual read/write/ioctl access.
123 *
124 * Using the above example, such a high level driver could
125 * prevent the user from issuing potentially destructive write
126 * operations (the aforementioned EEPROM interprets any 3rd
127 * and following byte written to the device as data, i.e., the
128 * contents could easily be changed!).
129 * The correct 'read-pointer offset' programming could be
130 * implemented in 'open' and 'ioctl' of a high-level driver and
131 * the user would then only have to perform harmless read
132 * operations, e.g.,
133 *
134 *    fd = open("/dev/i2c.eeprom",O_RDONLY) / * opens and sets EEPROM read pointer * /
135 *    ioctl(fd, IOCTL_SEEK, 0x200)                      / * repositions the read pointer       * /
136 *    read(fd, buf, 100)
137 *    close(fd)
138 *
139 */
140
141/* struct provided at driver registration. The driver may store
142 * private data behind the mandatory first fields but the size
143 * must be set to the size of the entire struct, e.g.,
144 *
145 * struct driver_pvt {
146 *      rtems_libi2c_drv_t pub;
147 *      struct {  ...    } pvt;
148 * } my_driver = {
149 *              {  ops: my_ops,
150 *                size: sizeof(my_driver)
151 *              },
152 *              { ...};
153 * };
154 *
155 * A pointer to this struct is passed to the callback ops.
156 */
157
158typedef struct rtems_libi2c_drv_t_
159{
160  rtems_driver_address_table *ops;      /* the driver ops */
161  int size;                     /* size of whole structure (including appended private data) */
162} rtems_libi2c_drv_t;
163
164/*
165 * The high level driver must be registered with a particular
166 * bus number and i2c address.
167 *
168 * The registration procedure also creates a filesystem node,
169 * i.e., the returned minor number is not really needed.
170 *
171 * If the 'name' argument is NULL, no filesystem node is
172 * created (but this can be done 'manually' using rtems_libi2c_major
173 * and the return value of this routine).
174 *
175 * RETURNS minor number (FYI) or -1 on failure
176 */
177int
178rtems_libi2c_register_drv (char *name, rtems_libi2c_drv_t * drvtbl,
179                           unsigned bus, unsigned i2caddr);
180
181/* Operations available to high level drivers */
182
183/* NOTES: The bus a device is attached to is LOCKED from the first send_start
184 *        until send_stop is executed!
185 *
186 *        Bus tenure MUST NOT span multiple system calls - otherwise, a single
187 *        thread could get into the protected sections (or would deadlock if the
188 *                mutex was not nestable).
189 *                E.g., consider what happens if 'open' sends a 'start' and 'close'
190 *                sends a 'stop' (i.e., the bus mutex would be locked in 'open' and
191 *        released in 'close'. A single thread could try to open two devices
192 *        on the same bus and would either deadlock or nest into the bus mutex
193 *        and potentially mess up the i2c messages.
194 *
195 *        The correct way is to *always* relinquish the i2c bus (i.e., send 'stop'
196 *                from any driver routine prior to returning control to the caller.
197 *                Consult the implementation of the generic driver routines (open, close, ...)
198 *                below or the examples in i2c-2b-eeprom.c and i2c-2b-ds1621.c
199 *
200 * Drivers just pass the minor number on to these routines...
201 */
202rtems_status_code rtems_libi2c_send_start (rtems_device_minor_number minor);
203
204rtems_status_code rtems_libi2c_send_stop (rtems_device_minor_number minor);
205
206rtems_status_code
207rtems_libi2c_send_addr (rtems_device_minor_number minor, int rw);
208
209/* the read/write routines return the number of bytes transferred
210 * or -(status_code) on error.
211 */
212int
213rtems_libi2c_read_bytes (rtems_device_minor_number minor,
214                         unsigned char *bytes, int nbytes);
215
216int
217rtems_libi2c_write_bytes (rtems_device_minor_number minor,
218                          unsigned char *bytes, int nbytes);
219
220/* Send start, send address and read bytes */
221int
222rtems_libi2c_start_read_bytes (uint32_t minor, unsigned char *bytes,
223                               int nbytes);
224
225/* Send start, send address and write bytes */
226int
227rtems_libi2c_start_write_bytes (uint32_t minor, unsigned char *bytes,
228                                int nbytes);
229
230#ifdef __cplusplus
231}
232#endif
233
234#endif
Note: See TracBrowser for help on using the repository browser.