2 * This file implements support for i2c on the BeagleBone and BeagleBoard-xM
6 #include <minix/chardriver.h>
7 #include <minix/clkconf.h>
8 #include <minix/drivers.h>
10 #include <minix/log.h>
11 #include <minix/mmio.h>
12 #include <minix/padconf.h>
13 #include <minix/sysutil.h>
14 #include <minix/type.h>
15 #include <minix/board.h>
16 #include <minix/spin.h>
19 #include <minix/i2c.h>
22 #include <sys/ioctl.h>
24 #include <sys/types.h>
35 * defines the set of register
37 * Warning: always use the 16-bit variants of read/write/set from mmio.h
38 * to access these registers. The DM37XX TRM Section 17.6 warns that 32-bit
39 * accesses can corrupt the register contents.
41 typedef struct omap_i2c_registers
43 vir_bytes I2C_REVNB_LO
; /* AM335X Only */
44 vir_bytes I2C_REVNB_HI
; /* AM335X Only */
45 vir_bytes I2C_REV
; /* DM37XX Only */
46 vir_bytes I2C_IE
; /* DM37XX Only */
47 vir_bytes I2C_STAT
; /* DM37XX Only */
49 vir_bytes I2C_IRQSTATUS_RAW
; /* AM335X Only */
50 vir_bytes I2C_IRQSTATUS
; /* AM335X Only */
51 vir_bytes I2C_IRQENABLE_SET
; /* AM335X Only */
52 vir_bytes I2C_IRQENABLE_CLR
; /* AM335X Only */
54 vir_bytes I2C_DMARXENABLE_SET
; /* AM335X Only */
55 vir_bytes I2C_DMATXENABLE_SET
; /* AM335X Only */
56 vir_bytes I2C_DMARXENABLE_CLR
; /* AM335X Only */
57 vir_bytes I2C_DMATXENABLE_CLR
; /* AM335X Only */
58 vir_bytes I2C_DMARXWAKE_EN
; /* AM335X Only */
59 vir_bytes I2C_DMATXWAKE_EN
; /* AM335X Only */
65 vir_bytes I2C_OA
; /* AM335X Only */
66 vir_bytes I2C_OA0
; /* DM37XX Only */
71 vir_bytes I2C_SYSTEST
;
72 vir_bytes I2C_BUFSTAT
;
80 /* generic definition an i2c bus */
82 typedef struct omap_i2c_bus
85 { AM335X_I2C_BUS
, DM37XX_I2C_BUS
} bus_type
;
88 vir_bytes mapped_addr
;
89 omap_i2c_regs_t
*regs
;
90 uint32_t functional_clock
;
91 uint32_t module_clock
;
97 int irq_hook_kernel_id
;
100 /* Define the registers for each chip */
102 static omap_i2c_regs_t am335x_i2c_regs
= {
103 .I2C_REVNB_LO
= AM335X_I2C_REVNB_LO
,
104 .I2C_REVNB_HI
= AM335X_I2C_REVNB_HI
,
105 .I2C_SYSC
= AM335X_I2C_SYSC
,
106 .I2C_IRQSTATUS_RAW
= AM335X_I2C_IRQSTATUS_RAW
,
107 .I2C_IRQSTATUS
= AM335X_I2C_IRQSTATUS
,
108 .I2C_IRQENABLE_SET
= AM335X_I2C_IRQENABLE_SET
,
109 .I2C_IRQENABLE_CLR
= AM335X_I2C_IRQENABLE_CLR
,
110 .I2C_WE
= AM335X_I2C_WE
,
111 .I2C_DMARXENABLE_SET
= AM335X_I2C_DMARXENABLE_SET
,
112 .I2C_DMATXENABLE_SET
= AM335X_I2C_DMATXENABLE_SET
,
113 .I2C_DMARXENABLE_CLR
= AM335X_I2C_DMARXENABLE_CLR
,
114 .I2C_DMATXENABLE_CLR
= AM335X_I2C_DMATXENABLE_CLR
,
115 .I2C_DMARXWAKE_EN
= AM335X_I2C_DMARXWAKE_EN
,
116 .I2C_DMATXWAKE_EN
= AM335X_I2C_DMATXWAKE_EN
,
117 .I2C_SYSS
= AM335X_I2C_SYSS
,
118 .I2C_BUF
= AM335X_I2C_BUF
,
119 .I2C_CNT
= AM335X_I2C_CNT
,
120 .I2C_DATA
= AM335X_I2C_DATA
,
121 .I2C_CON
= AM335X_I2C_CON
,
122 .I2C_OA
= AM335X_I2C_OA
,
123 .I2C_SA
= AM335X_I2C_SA
,
124 .I2C_PSC
= AM335X_I2C_PSC
,
125 .I2C_SCLL
= AM335X_I2C_SCLL
,
126 .I2C_SCLH
= AM335X_I2C_SCLH
,
127 .I2C_SYSTEST
= AM335X_I2C_SYSTEST
,
128 .I2C_BUFSTAT
= AM335X_I2C_BUFSTAT
,
129 .I2C_OA1
= AM335X_I2C_OA1
,
130 .I2C_OA2
= AM335X_I2C_OA2
,
131 .I2C_OA3
= AM335X_I2C_OA3
,
132 .I2C_ACTOA
= AM335X_I2C_ACTOA
,
133 .I2C_SBLOCK
= AM335X_I2C_SBLOCK
136 static omap_i2c_regs_t dm37xx_i2c_regs
= {
137 .I2C_REV
= DM37XX_I2C_REV
,
138 .I2C_IE
= DM37XX_I2C_IE
,
139 .I2C_STAT
= DM37XX_I2C_STAT
,
140 .I2C_WE
= DM37XX_I2C_WE
,
141 .I2C_SYSS
= DM37XX_I2C_SYSS
,
142 .I2C_BUF
= DM37XX_I2C_BUF
,
143 .I2C_CNT
= DM37XX_I2C_CNT
,
144 .I2C_DATA
= DM37XX_I2C_DATA
,
145 .I2C_SYSC
= DM37XX_I2C_SYSC
,
146 .I2C_CON
= DM37XX_I2C_CON
,
147 .I2C_OA0
= DM37XX_I2C_OA0
,
148 .I2C_SA
= DM37XX_I2C_SA
,
149 .I2C_PSC
= DM37XX_I2C_PSC
,
150 .I2C_SCLL
= DM37XX_I2C_SCLL
,
151 .I2C_SCLH
= DM37XX_I2C_SCLH
,
152 .I2C_SYSTEST
= DM37XX_I2C_SYSTEST
,
153 .I2C_BUFSTAT
= DM37XX_I2C_BUFSTAT
,
154 .I2C_OA1
= DM37XX_I2C_OA1
,
155 .I2C_OA2
= DM37XX_I2C_OA2
,
156 .I2C_OA3
= DM37XX_I2C_OA3
,
157 .I2C_ACTOA
= DM37XX_I2C_ACTOA
,
158 .I2C_SBLOCK
= DM37XX_I2C_SBLOCK
161 /* Define the buses available on each chip */
163 static omap_i2c_bus_t am335x_i2c_buses
[] = {
164 {AM335X_I2C_BUS
, AM335X_I2C0_BASE
, AM335X_I2C0_SIZE
, 0, &am335x_i2c_regs
,
165 AM335X_FUNCTIONAL_CLOCK
, AM335X_MODULE_CLOCK
,
166 BUS_SPEED_400KHz
, AM335X_REV_MAJOR
, AM335X_REV_MINOR
,
167 AM335X_I2C0_IRQ
, 1, 1},
168 {AM335X_I2C_BUS
, AM335X_I2C1_BASE
, AM335X_I2C1_SIZE
, 0, &am335x_i2c_regs
,
169 AM335X_FUNCTIONAL_CLOCK
, AM335X_MODULE_CLOCK
,
170 BUS_SPEED_100KHz
, AM335X_REV_MAJOR
, AM335X_REV_MINOR
,
171 AM335X_I2C1_IRQ
, 2, 3},
172 {AM335X_I2C_BUS
, AM335X_I2C2_BASE
, AM335X_I2C2_SIZE
, 0, &am335x_i2c_regs
,
173 AM335X_FUNCTIONAL_CLOCK
, AM335X_MODULE_CLOCK
,
174 BUS_SPEED_100KHz
, AM335X_REV_MAJOR
, AM335X_REV_MINOR
,
175 AM335X_I2C2_IRQ
, 3, 3}
178 #define AM335X_OMAP_NBUSES (sizeof(am335x_i2c_buses) / sizeof(omap_i2c_bus_t))
180 static omap_i2c_bus_t dm37xx_i2c_buses
[] = {
181 {DM37XX_I2C_BUS
, DM37XX_I2C0_BASE
, DM37XX_I2C0_SIZE
, 0, &dm37xx_i2c_regs
,
182 DM37XX_FUNCTIONAL_CLOCK
, DM37XX_MODULE_CLOCK
,
183 BUS_SPEED_100KHz
, DM37XX_REV_MAJOR
, DM37XX_REV_MINOR
,
184 DM37XX_I2C0_IRQ
, 1, 1},
185 {DM37XX_I2C_BUS
, DM37XX_I2C1_BASE
, DM37XX_I2C1_SIZE
, 0, &dm37xx_i2c_regs
,
186 DM37XX_FUNCTIONAL_CLOCK
, DM37XX_MODULE_CLOCK
,
187 BUS_SPEED_100KHz
, DM37XX_REV_MAJOR
, DM37XX_REV_MINOR
,
188 DM37XX_I2C1_IRQ
, 2, 2},
189 {DM37XX_I2C_BUS
, DM37XX_I2C2_BASE
, DM37XX_I2C2_SIZE
, 0, &dm37xx_i2c_regs
,
190 DM37XX_FUNCTIONAL_CLOCK
, DM37XX_MODULE_CLOCK
,
191 BUS_SPEED_100KHz
, DM37XX_REV_MAJOR
, DM37XX_REV_MINOR
,
192 DM37XX_I2C2_IRQ
, 3, 3}
195 #define DM37XX_OMAP_NBUSES (sizeof(dm37xx_i2c_buses) / sizeof(omap_i2c_bus_t))
199 static omap_i2c_bus_t
*omap_i2c_buses
; /* all available buses for this SoC */
200 static omap_i2c_bus_t
*omap_i2c_bus
; /* the bus selected at start-up */
201 static int omap_i2c_nbuses
; /* number of buses supported by SoC */
203 /* logging - use with log_warn(), log_info(), log_debug(), log_trace() */
204 static struct log log
= {
206 .log_level
= LEVEL_INFO
,
207 .log_func
= default_log
210 /* Local Function Prototypes */
212 /* Implementation of Generic I2C Interface using Bus Specific Code */
213 static int omap_i2c_process(minix_i2c_ioctl_exec_t
* m
);
215 /* Bus Specific Code */
216 static void omap_i2c_flush(void);
217 static uint16_t omap_i2c_poll(uint16_t mask
);
218 static int omap_i2c_bus_is_free(void);
219 static int omap_i2c_soft_reset(void);
220 static void omap_i2c_bus_init(void);
221 static void omap_i2c_padconf(int i2c_bus_id
);
222 static void omap_i2c_clkconf(int i2c_bus_id
);
223 static void omap_i2c_intr_enable(void);
224 static uint16_t omap_i2c_read_status(void);
225 static void omap_i2c_write_status(uint16_t mask
);
226 static int omap_i2c_read(i2c_addr_t addr
, uint8_t * buf
, size_t buflen
,
228 static int omap_i2c_write(i2c_addr_t addr
, const uint8_t * buf
, size_t buflen
,
232 * Performs the action in minix_i2c_ioctl_exec_t.
235 omap_i2c_process(minix_i2c_ioctl_exec_t
* ioctl_exec
)
240 * Zero data bytes transfers are not allowed. The controller treats
241 * I2C_CNT register value of 0x0 as 65536. This is true for both the
242 * am335x and dm37xx. Full details in the TRM on the I2C_CNT page.
244 if (ioctl_exec
->iie_buflen
== 0) {
248 omap_i2c_flush(); /* clear any garbage in the fifo */
250 /* Check bus busy flag before using the bus */
251 r
= omap_i2c_bus_is_free();
253 log_warn(&log
, "Bus is busy\n");
257 if (ioctl_exec
->iie_cmdlen
> 0) {
258 r
= omap_i2c_write(ioctl_exec
->iie_addr
, ioctl_exec
->iie_cmd
,
259 ioctl_exec
->iie_cmdlen
,
260 !(I2C_OP_READ_P(ioctl_exec
->iie_op
)));
262 omap_i2c_soft_reset();
268 if (I2C_OP_READ_P(ioctl_exec
->iie_op
)) {
269 r
= omap_i2c_read(ioctl_exec
->iie_addr
, ioctl_exec
->iie_buf
,
270 ioctl_exec
->iie_buflen
, I2C_OP_STOP_P(ioctl_exec
->iie_op
));
272 r
= omap_i2c_write(ioctl_exec
->iie_addr
, ioctl_exec
->iie_buf
,
273 ioctl_exec
->iie_buflen
, I2C_OP_STOP_P(ioctl_exec
->iie_op
));
277 omap_i2c_soft_reset();
286 * Drain the incoming FIFO.
288 * Usually called to clear any garbage that may be in the buffer before
297 for (tries
= 0; tries
< 1000; tries
++) {
298 status
= omap_i2c_poll(1 << RRDY
);
299 if ((status
& (1 << RRDY
)) != 0) { /* bytes available for reading */
301 /* consume the byte and throw it away */
302 (void) read16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_DATA
);
304 /* clear the read ready flag */
305 omap_i2c_write_status(1 << RRDY
);
308 break; /* buffer drained */
314 * Poll the status register checking the bits set in 'mask'.
315 * Returns the status if any bits set or 0x0000 when the timeout is reached.
318 omap_i2c_poll(uint16_t mask
)
323 /* poll for up to 1 s */
324 spin_init(&spin
, 1000000);
326 status
= omap_i2c_read_status();
327 if ((status
& mask
) != 0) { /* any bits in mask set */
331 } while (spin_check(&spin
));
333 return status
; /* timeout reached, abort */
337 * Poll Bus Busy Flag until the bus becomes free (return 1) or the timeout
338 * expires (return 0).
341 omap_i2c_bus_is_free(void)
346 /* wait for up to 1 second for the bus to become free */
347 spin_init(&spin
, 1000000);
350 status
= omap_i2c_read_status();
351 if ((status
& (1 << BB
)) == 0) {
352 return 1; /* bus is free */
355 } while (spin_check(&spin
));
357 return 0; /* timeout expired */
361 omap_i2c_clkconf(int i2c_bus_id
)
365 if (omap_i2c_bus
->bus_type
== DM37XX_I2C_BUS
) {
367 clkconf_set(CM_ICLKEN1_CORE
, BIT((15 + i2c_bus_id
)),
369 clkconf_set(CM_FCLKEN1_CORE
, BIT((15 + i2c_bus_id
)),
372 } else if (omap_i2c_bus
->bus_type
== AM335X_I2C_BUS
) {
374 switch (i2c_bus_id
) {
376 clkconf_set(CM_WKUP_I2C0_CLKCTRL
, BIT(1), 0xffffffff);
379 clkconf_set(CM_PER_I2C1_CLKCTRL
, BIT(1), 0xffffffff);
382 clkconf_set(CM_PER_I2C2_CLKCTRL
, BIT(1), 0xffffffff);
385 log_warn(&log
, "Invalid i2c_bus_id\n");
394 omap_i2c_padconf(int i2c_bus_id
)
399 if (omap_i2c_bus
->bus_type
== AM335X_I2C_BUS
) {
401 /* use the options suggested in starterware driver */
403 CONTROL_CONF_SLEWCTRL
| CONTROL_CONF_RXACTIVE
|
404 CONTROL_CONF_PUTYPESEL
;
406 switch (i2c_bus_id
) {
408 pinopts
|= CONTROL_CONF_MUXMODE(0);
410 r
= sys_padconf(CONTROL_CONF_I2C0_SDA
, 0xffffffff,
413 log_warn(&log
, "padconf failed (r=%d)\n", r
);
416 r
= sys_padconf(CONTROL_CONF_I2C0_SCL
, 0xffffffff,
419 log_warn(&log
, "padconf failed (r=%d)\n", r
);
422 log_debug(&log
, "pinopts=0x%x\n", pinopts
);
426 pinopts
|= CONTROL_CONF_MUXMODE(2);
428 r
= sys_padconf(CONTROL_CONF_SPI0_CS0
, 0xffffffff,
431 log_warn(&log
, "padconf failed (r=%d)\n", r
);
434 r
= sys_padconf(CONTROL_CONF_SPI0_D1
, 0xffffffff,
437 log_warn(&log
, "padconf failed (r=%d)\n", r
);
439 log_debug(&log
, "pinopts=0x%x\n", pinopts
);
443 pinopts
|= CONTROL_CONF_MUXMODE(3);
445 r
= sys_padconf(CONTROL_CONF_UART1_CTSN
, 0xffffffff,
448 log_warn(&log
, "padconf failed (r=%d)\n", r
);
451 r
= sys_padconf(CONTROL_CONF_UART1_RTSN
,
452 0xffffffff, pinopts
);
454 log_warn(&log
, "padconf failed (r=%d)\n", r
);
457 log_debug(&log
, "pinopts=0x%x\n", pinopts
);
461 log_warn(&log
, "Invalid i2c_bus_id\n");
466 /* nothing to do for the DM37XX */
470 omap_i2c_soft_reset(void)
474 /* Disable to do soft reset */
475 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_CON
, 0);
478 /* Do a soft reset */
479 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_SYSC
, (1 << SRST
));
481 /* Have to temporarily enable I2C to read RDONE */
482 set16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_CON
, (1<<I2C_EN
), (1<<I2C_EN
));
485 /* wait up to 3 seconds for reset to complete */
486 spin_init(&spin
, 3000000);
488 if (read16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_SYSS
) & (1 << RDONE
)) {
492 } while (spin_check(&spin
));
494 log_warn(&log
, "Tried soft reset, but bus never came back.\n");
499 omap_i2c_intr_enable(void)
503 static int policy_set
= 0;
504 static int enabled
= 0;
507 r
= sys_irqsetpolicy(omap_i2c_bus
->irq
, 0,
508 &omap_i2c_bus
->irq_hook_kernel_id
);
512 log_warn(&log
, "Couldn't set irq policy\n");
516 if (policy_set
&& !enabled
) {
517 r
= sys_irqenable(&omap_i2c_bus
->irq_hook_kernel_id
);
521 log_warn(&log
, "Couldn't enable irq %d (hooked)\n",
526 /* According to NetBSD driver and u-boot, these are needed even
527 * if just using polling (i.e. non-interrupt driver programming).
530 intmask
|= (1 << ROVR
);
531 intmask
|= (1 << AERR
);
532 intmask
|= (1 << XRDY
);
533 intmask
|= (1 << RRDY
);
534 intmask
|= (1 << ARDY
);
535 intmask
|= (1 << NACK
);
536 intmask
|= (1 << AL
);
538 if (omap_i2c_bus
->bus_type
== AM335X_I2C_BUS
) {
539 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_IRQENABLE_SET
, intmask
);
540 } else if (omap_i2c_bus
->bus_type
== DM37XX_I2C_BUS
) {
541 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_IE
, intmask
);
543 log_warn(&log
, "Don't know how to enable interrupts.\n");
548 omap_i2c_bus_init(void)
551 /* Ensure i2c module is disabled before setting prescalar & bus speed */
552 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_CON
, 0);
555 /* Disable autoidle */
556 set16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_SYSC
, (1<<AUTOIDLE
), (0<<AUTOIDLE
));
558 /* Set prescalar to obtain 12 MHz i2c module clock */
559 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_PSC
,
560 ((omap_i2c_bus
->functional_clock
/ omap_i2c_bus
->module_clock
) -
563 /* Set the bus speed */
564 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_SCLL
,
565 ((omap_i2c_bus
->module_clock
/ (2 * omap_i2c_bus
->bus_speed
)) -
567 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_SCLH
,
568 ((omap_i2c_bus
->module_clock
/ (2 * omap_i2c_bus
->bus_speed
)) -
571 /* Set own I2C address */
572 if (omap_i2c_bus
->bus_type
== AM335X_I2C_BUS
) {
573 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_OA
, I2C_OWN_ADDRESS
);
574 } else if (omap_i2c_bus
->bus_type
== DM37XX_I2C_BUS
) {
575 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_OA0
, I2C_OWN_ADDRESS
);
577 log_warn(&log
, "Don't know how to set own address.\n");
580 /* Set TX/RX Threshold to 1 and disable I2C DMA */
581 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_BUF
, 0x0000);
583 /* Bring the i2c module out of reset */
584 set16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_CON
, (1<<I2C_EN
), (1<<I2C_EN
));
590 omap_i2c_intr_enable();
594 omap_i2c_read_status(void)
596 uint16_t status
= 0x0000;
598 if (omap_i2c_bus
->bus_type
== AM335X_I2C_BUS
) {
599 /* TRM says to use RAW for polling for events */
600 status
= read16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_IRQSTATUS_RAW
);
601 } else if (omap_i2c_bus
->bus_type
== DM37XX_I2C_BUS
) {
602 status
= read16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_STAT
);
604 log_warn(&log
, "Don't know how to read i2c bus status.\n");
611 omap_i2c_write_status(uint16_t mask
)
613 if (omap_i2c_bus
->bus_type
== AM335X_I2C_BUS
) {
614 /* write 1's to IRQSTATUS (not RAW) to clear the bits */
615 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_IRQSTATUS
, mask
);
616 } else if (omap_i2c_bus
->bus_type
== DM37XX_I2C_BUS
) {
617 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_STAT
, mask
);
619 log_warn(&log
, "Don't know how to clear i2c bus status.\n");
624 omap_i2c_read(i2c_addr_t addr
, uint8_t * buf
, size_t buflen
, int dostop
)
631 /* Set address of slave device */
633 addr
&= MAX_I2C_SA_MASK
; /* sanitize address (10-bit max) */
635 /* 10-bit extended address in use, need to set XSA */
636 conopts
|= (1 << XSA
);
640 errmask
|= (1 << ROVR
);
641 errmask
|= (1 << AERR
);
642 errmask
|= (1 << NACK
);
643 errmask
|= (1 << AL
);
646 pollmask
|= (1 << RRDY
);
648 /* Set bytes to read and slave address */
649 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_CNT
, buflen
);
650 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_SA
, addr
);
652 /* Set control register */
653 conopts
|= (1 << I2C_EN
); /* enabled */
654 conopts
|= (1 << MST
); /* master mode */
655 conopts
|= (1 << STT
); /* start condition */
658 conopts
|= (1 << STP
); /* stop condition */
661 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_CON
, conopts
);
663 for (i
= 0; i
< buflen
; i
++) {
665 r
= omap_i2c_poll(pollmask
| errmask
);
666 if ((r
& errmask
) != 0) {
667 /* only debug log level because i2cscan trigers this */
668 log_debug(&log
, "Read Error! Status=%x\n", r
);
670 } else if ((r
& pollmask
) == 0) {
671 log_warn(&log
, "No RRDY Interrupt. Status=%x\n", r
);
673 "Likely cause: bad pinmux or no devices on bus\n");
678 buf
[i
] = read16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_DATA
) & 0xff;
680 /* clear the read ready flag */
681 omap_i2c_write_status(pollmask
);
684 r
= omap_i2c_read_status();
685 if ((r
& (1 << NACK
)) != 0) {
686 log_warn(&log
, "NACK\n");
690 /* Wait for operation to complete */
691 pollmask
= (1<<ARDY
); /* poll access ready bit */
692 r
= omap_i2c_poll(pollmask
);
693 if ((r
& pollmask
) == 0) {
694 log_warn(&log
, "Read operation never finished.\n");
697 omap_i2c_write_status(0x7fff);
703 omap_i2c_write(i2c_addr_t addr
, const uint8_t * buf
, size_t buflen
, int dostop
)
710 /* Set address of slave device */
712 addr
&= MAX_I2C_SA_MASK
; /* sanitize address (10-bit max) */
714 /* 10-bit extended address in use, need to set XSA */
715 conopts
|= (1 << XSA
);
719 pollmask
|= (1 << XRDY
);
722 errmask
|= (1 << ROVR
);
723 errmask
|= (1 << AERR
);
724 errmask
|= (1 << NACK
);
725 errmask
|= (1 << AL
);
727 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_CNT
, buflen
);
728 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_SA
, addr
);
730 /* Set control register */
731 conopts
|= (1 << I2C_EN
); /* enabled */
732 conopts
|= (1 << MST
); /* master mode */
733 conopts
|= (1 << TRX
); /* TRX mode */
734 conopts
|= (1 << STT
); /* start condition */
737 conopts
|= (1 << STP
); /* stop condition */
740 omap_i2c_write_status(0x7fff);
741 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_CON
, conopts
);
743 for (i
= 0; i
< buflen
; i
++) {
745 /* Ready to write? */
746 r
= omap_i2c_poll(pollmask
| errmask
);
747 if ((r
& errmask
) != 0) {
748 log_warn(&log
, "Write Error! Status=%x\n", r
);
750 } else if ((r
& pollmask
) == 0) {
751 log_warn(&log
, "Not ready for write? Status=%x\n", r
);
755 write16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_DATA
, buf
[i
]);
757 /* clear the write ready flag */
758 omap_i2c_write_status(pollmask
);
761 r
= omap_i2c_read_status();
762 if ((r
& (1 << NACK
)) != 0) {
763 log_warn(&log
, "NACK\n");
767 /* Wait for operation to complete */
768 pollmask
= (1<<ARDY
); /* poll access ready bit */
769 r
= omap_i2c_poll(pollmask
);
770 if ((r
& pollmask
) == 0) {
771 log_warn(&log
, "Write operation never finished.\n");
774 omap_i2c_write_status(0x7fff);
780 omap_interface_setup(int (**process
) (minix_i2c_ioctl_exec_t
* ioctl_exec
),
784 int i2c_rev
, major
, minor
;
785 struct minix_mem_range mr
;
786 struct machine machine
;
787 sys_getmachine(&machine
);
789 /* Fill in the function pointer */
791 *process
= omap_i2c_process
;
793 /* Select the correct i2c definition for this SoC */
795 if (BOARD_IS_BBXM(machine
.board_id
)){
796 omap_i2c_buses
= dm37xx_i2c_buses
;
797 omap_i2c_nbuses
= DM37XX_OMAP_NBUSES
;
798 } else if (BOARD_IS_BB(machine
.board_id
)){
799 omap_i2c_buses
= am335x_i2c_buses
;
800 omap_i2c_nbuses
= AM335X_OMAP_NBUSES
;
805 if (i2c_bus_id
< 0 || i2c_bus_id
>= omap_i2c_nbuses
) {
809 /* select the bus to operate on */
810 omap_i2c_bus
= &omap_i2c_buses
[i2c_bus_id
];
813 omap_i2c_padconf(i2c_bus_id
);
819 /* Configure memory access */
820 mr
.mr_base
= omap_i2c_bus
->mr_base
; /* start addr */
821 mr
.mr_limit
= mr
.mr_base
+ omap_i2c_bus
->mr_size
; /* end addr */
823 /* ask for privileges to access the I2C memory range */
824 if (sys_privctl(SELF
, SYS_PRIV_ADD_MEM
, &mr
) != OK
) {
825 panic("Unable to obtain i2c memory range privileges");
828 /* map the memory into this process */
829 omap_i2c_bus
->mapped_addr
= (vir_bytes
) vm_map_phys(SELF
,
830 (void *) omap_i2c_bus
->mr_base
, omap_i2c_bus
->mr_size
);
832 if (omap_i2c_bus
->mapped_addr
== (vir_bytes
) MAP_FAILED
) {
833 panic("Unable to map i2c registers");
837 omap_i2c_clkconf(i2c_bus_id
);
839 /* Perform a soft reset of the I2C module to ensure a fresh start */
840 r
= omap_i2c_soft_reset();
842 /* module didn't come back up :( */
846 /* Bring up I2C module */
849 /* Get I2C Revision */
850 if (omap_i2c_bus
->bus_type
== AM335X_I2C_BUS
) {
851 /* I2C_REVLO revision: major (bits 10-8), minor (bits 5-0) */
852 i2c_rev
= read16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_REVNB_LO
);
853 major
= (i2c_rev
>> 8) & 0x07;
854 minor
= i2c_rev
& 0x3f;
856 } else if (omap_i2c_bus
->bus_type
== DM37XX_I2C_BUS
) {
857 /* I2C_REV revision: major (bits 7-4), minor (bits 3-0) */
858 i2c_rev
= read16(omap_i2c_bus
->mapped_addr
+ omap_i2c_bus
->regs
->I2C_REV
);
859 major
= (i2c_rev
>> 4) & 0x0f;
860 minor
= i2c_rev
& 0x0f;
862 panic("Don't know how to read i2c revision.");
865 if (major
!= omap_i2c_bus
->major
|| minor
!= omap_i2c_bus
->minor
) {
866 log_warn(&log
, "Unrecognized value in I2C_REV register.\n");
867 log_warn(&log
, "Read: 0x%x.0x%x | Expected: 0x%x.0x%x\n",
868 major
, minor
, omap_i2c_bus
->major
, omap_i2c_bus
->minor
);
871 /* display i2c revision information for debugging purposes */
872 log_debug(&log
, "i2c_%d: I2C rev 0x%x.0x%x\n", (i2c_bus_id
+ 1),