diff --git a/etc/system.conf b/etc/system.conf index 44e926a8e..8290eea07 100644 --- a/etc/system.conf +++ b/etc/system.conf @@ -465,7 +465,7 @@ service fb PRIVCTL # 4 ; ipc - SYSTEM pm rs ds vm vfs cat24c256 tda19988 + SYSTEM pm rs ds vm vfs cat24c256 tda19988 ; }; @@ -563,3 +563,26 @@ service mailbox ; ipc ALL }; + +service i2c +{ + system + PRIVCTL # 4 + IRQCTL # 19 + PADCONF # 57 + ; + irq + # DM37XX (BeagleBoard-xM) + 56 # I2C module 1 + 57 # I2C module 2 + 61 # I2C module 3 + # AM335X (BeagleBone) + 70 # I2C module 1 + 71 # I2C module 2 + 30 # I2C module 3 + # BCM283X (RaspberryPi 2,3) + 47 + ; + ipc SYSTEM rs ds vm + ; +}; diff --git a/minix/drivers/bus/i2c/Makefile b/minix/drivers/bus/i2c/Makefile index 400df49b5..6d74b03f5 100644 --- a/minix/drivers/bus/i2c/Makefile +++ b/minix/drivers/bus/i2c/Makefile @@ -2,24 +2,25 @@ PROG= i2c SRCS+= i2c.c -FILESNAME=i2c -FILES=i2c.conf + +FILES=${PROG}.conf +FILESNAME=${PROG} +FILESDIR= /etc/system.conf.d + +.include .if ${MACHINE_ARCH} == "earm" .for pl in rpi omap .PATH: ${.CURDIR}/arch/earm/${pl} -SRCS+= ${pl}_i2c.c ${pl}_i2c.h ${pl}_i2c_registers.h +SRCS+= ${pl}_i2c.c .endfor .else .PATH: ${.CURDIR}/arch/${MACHINE_ARCH} -SRCS+= pci_i2c.c pci_i2c.h pci_i2c_register.h +SRCS+= pci_i2c.c .endif -FILESDIR= /etc/system.conf.d CPPFLAGS+= -I${.CURDIR} -I${.CURDIR}/arch/earm/rpi -I${.CURDIR}/arch/earm/omap DPADD+= ${LIBCHARDRIVER} ${LIBSYS} ${LIBTIMERS} ${LIBCLKCONF} LDADD+= -lchardriver -lsys -ltimers -lclkconf -MKMAN:= no - .include \ No newline at end of file diff --git a/minix/drivers/bus/i2c/README.txt b/minix/drivers/bus/i2c/README.txt index a1ab83777..f990aee6c 100644 --- a/minix/drivers/bus/i2c/README.txt +++ b/minix/drivers/bus/i2c/README.txt @@ -14,11 +14,17 @@ Organization and Layout ----------------------- i2c.c generic i2c bus driver +i2c.conf configuration for the i2c driver arch/ arch specific code earm/ earm specific code - omap_i2c.c AM335X/DM37XX i2c bus driver - omap_i2c.h AM335X/DM37XX function prototypes - omap_i2c_registers.h AM335X/DM37XX register offsets, etc. + omap/ + omap_i2c.c AM335X/DM37XX i2c bus driver + omap_i2c.h AM335X/DM37XX function prototypes + omap_i2c_registers.h AM335X/DM37XX register offsets, etc. + rpi/ + rpi_i2c.c BCM283X i2c bus driver + rpi_i2c.h BCM283X function prototypes + rpi_i2c_registers.h BCM283X register offsets, etc. Testing the Code ---------------- @@ -62,3 +68,17 @@ Minix i2c device drivers. It shows how to use the i2cdriver library and how to use the bus for reads and writes. commands/eepromread is another place to look if you're interested in accessing devices through the /dev interface. + +Developing I2C Drivers For The New Arm Platform +------------------------------------------- + +1) Create the directory "your_platform" in the arch/earm +2) Your driver has to implement "int your_platform_interface_setup +(int (**process)(minix_i2c_ioctl_exec_t *ioctl_exec), int i2c_bus_id);", +which is called by the general i2c driver for control platform dependent +functions. See previous realizations for more examples. +3) Your files have to named your_platform_i2c.c your_platform_i2c.h +your_platform_i2c_registers.h +4) Add your platform name in the Makefile directories list. +5) Include "your_platform_i2c.h" in the i2c.c. +6) Add else/if section in the i2c.c in the sef_cb_init function. diff --git a/minix/drivers/bus/i2c/arch/earm/rpi/rpi_i2c.c b/minix/drivers/bus/i2c/arch/earm/rpi/rpi_i2c.c index f12dd7307..f023fcfa2 100644 --- a/minix/drivers/bus/i2c/arch/earm/rpi/rpi_i2c.c +++ b/minix/drivers/bus/i2c/arch/earm/rpi/rpi_i2c.c @@ -4,13 +4,13 @@ /* kernel headers */ #include -#include #include #include #include #include #include #include +#include #include #include #include @@ -84,10 +84,10 @@ static rpi_i2c_regs_t bcm283x_i2c_regs = { static rpi_i2c_bus_t bcm283x_i2c_buses[] = { {BCM283X_I2C0_BASE, BCM283X_I2C0_SIZE, 0, &bcm283x_i2c_regs, BCM283X_FUNCTIONAL_CLOCK, BCM283X_MODULE_CLOCK, - BUS_SPEED_400KHz, BCM283X_I2C0_IRQ, 1, 1}, + BUS_SPEED_100KHz, BCM283X_I2C0_IRQ, 1, 1}, {BCM283X_I2C1_BASE, BCM283X_I2C1_SIZE, 0, &bcm283x_i2c_regs, BCM283X_FUNCTIONAL_CLOCK, BCM283X_MODULE_CLOCK, - BUS_SPEED_400KHz, BCM283X_I2C0_IRQ, 2, 3} + BUS_SPEED_100KHz, BCM283X_I2C0_IRQ, 2, 3} }; #define BCM283X_rpi_NBUSES (sizeof(bcm283x_i2c_buses) / sizeof(rpi_i2c_bus_t)) @@ -101,7 +101,7 @@ static int rpi_i2c_nbuses; /* number of buses supported by SoC */ /* logging - use with log_warn(), log_info(), log_debug(), log_trace() */ static struct log log = { .name = "i2c", - .log_level = LEVEL_INFO, + .log_level = LEVEL_TRACE, .log_func = default_log }; @@ -117,7 +117,6 @@ static int rpi_i2c_bus_is_free(void); static int rpi_i2c_soft_reset(void); static void rpi_i2c_bus_init(void); static void rpi_i2c_padconf(int i2c_bus_id); -static void rpi_i2c_clkconf(int i2c_bus_id); static void rpi_i2c_intr_enable(void); static uint32_t rpi_i2c_read_status(void); static void rpi_i2c_write_status(uint32_t mask); @@ -144,6 +143,7 @@ rpi_i2c_process(minix_i2c_ioctl_exec_t * ioctl_exec) } rpi_i2c_flush(); /* clear any garbage in the fifo */ + log_debug(&log, "buflen %d, cmdlen %d, addr 0x%x\n", ioctl_exec->iie_buflen, ioctl_exec->iie_cmdlen, ioctl_exec->iie_addr); /* Check bus busy flag before using the bus */ r = rpi_i2c_bus_is_free(); @@ -151,7 +151,6 @@ rpi_i2c_process(minix_i2c_ioctl_exec_t * ioctl_exec) log_warn(&log, "Bus is busy\n"); return EBUSY; } - if (ioctl_exec->iie_cmdlen > 0) { r = rpi_i2c_write(ioctl_exec->iie_addr, ioctl_exec->iie_cmd, ioctl_exec->iie_cmdlen, @@ -195,14 +194,19 @@ rpi_i2c_flush(void) for (tries = 0; tries < 1000; tries++) { status = rpi_i2c_poll(BCM283X_STATUS_RXD); if ((status & BCM283X_STATUS_RXD) != 0) { /* bytes available for reading */ - /* consume the byte and throw it away */ - (void) read32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->FIFO); + read32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->FIFO); + + set32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL, + BCM283X_CTRL_CFIFO, BCM283X_CTRL_CFIFO); + set32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->ST, + BCM283X_STATUS_DONE, BCM283X_STATUS_DONE); } else { break; /* buffer drained */ } } + log_debug(&log, "bytes available 0x%x\n", status); } /* @@ -222,7 +226,6 @@ rpi_i2c_poll(uint32_t mask) if ((status & mask) != 0) { /* any bits in mask set */ return status; } - } while (spin_check(&spin)); return status; /* timeout reached, abort */ @@ -246,53 +249,22 @@ rpi_i2c_bus_is_free(void) if ((status & BCM283X_STATUS_TA) == 0) { return 1; /* bus is free */ } - } while (spin_check(&spin)); return 0; /* timeout expired */ } -static void -rpi_i2c_clkconf(int i2c_bus_id) -{ - clkconf_init(); - - switch (i2c_bus_id) { - case 0: - clkconf_set(CM_WKUP_I2C0_CLKCTRL, BIT(1), 0xffffffff); - break; - case 1: - clkconf_set(CM_PER_I2C1_CLKCTRL, BIT(1), 0xffffffff); - break; - default: - log_warn(&log, "Invalid i2c_bus_id\n"); - break; - } - - clkconf_release(); -} - static void rpi_i2c_padconf(int i2c_bus_id) { int r; u32_t pinopts; - /* use the options suggested in starterware driver */ - pinopts = - CONTROL_CONF_SLEWCTRL | CONTROL_CONF_RXACTIVE | - CONTROL_CONF_PUTYPESEL; switch (i2c_bus_id) { case 0: - pinopts |= CONTROL_CONF_MUXMODE(0); + pinopts |= CONTROL_BCM_CONF_I2C0_SDA | CONTROL_BCM_CONF_I2C0_SCL; - r = sys_padconf(CONTROL_CONF_I2C0_SDA, 0xffffffff, - pinopts); - if (r != OK) { - log_warn(&log, "padconf failed (r=%d)\n", r); - } - - r = sys_padconf(CONTROL_CONF_I2C0_SCL, 0xffffffff, + r = sys_padconf(GPFSEL09, 0xffffffff, pinopts); if (r != OK) { log_warn(&log, "padconf failed (r=%d)\n", r); @@ -302,15 +274,9 @@ rpi_i2c_padconf(int i2c_bus_id) break; case 1: - pinopts |= CONTROL_CONF_MUXMODE(2); + pinopts |= CONTROL_BCM_CONF_I2C1_SDA | CONTROL_BCM_CONF_I2C1_SCL; - r = sys_padconf(CONTROL_CONF_SPI0_CS0, 0xffffffff, - pinopts); - if (r != OK) { - log_warn(&log, "padconf failed (r=%d)\n", r); - } - - r = sys_padconf(CONTROL_CONF_SPI0_D1, 0xffffffff, + r = sys_padconf(GPFSEL09, 0xffffffff, pinopts); if (r != OK) { log_warn(&log, "padconf failed (r=%d)\n", r); @@ -382,13 +348,13 @@ rpi_i2c_intr_enable(void) static void rpi_i2c_bus_init(void) { - /* Ensure i2c module is disabled before setting prescalar & bus speed */ write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL, 0); micro_delay(50000); /* Set prescalar to obtain 12 MHz i2c module clock */ - uint32_t divider = (rpi_i2c_bus->functional_clock / rpi_i2c_bus->module_clock) - 1; + uint32_t divider = (sys_hz() * 10000 + rpi_i2c_bus->bus_speed - 1) / rpi_i2c_bus->bus_speed; + log_debug(&log, "divider %lu sys_hz %lu\n", (uint32_t)divider, sys_hz()); if (divider > BCM283X_I2C_CDIV_MAX || divider < BCM283X_I2C_CDIV_MIN) { log_warn(&log, "Incorrect divider\n"); @@ -397,7 +363,7 @@ rpi_i2c_bus_init(void) if (divider & 0x01) divider++; - write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->DIV, divider); + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->DIV, 1500); /* Set own I2C address */ write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->SL_ADDR, I2C_OWN_ADDRESS); @@ -410,6 +376,8 @@ rpi_i2c_bus_init(void) * Enable interrupts */ rpi_i2c_intr_enable(); + + log_debug(&log, "interrupts enabled\n"); } static uint32_t @@ -435,53 +403,61 @@ rpi_i2c_read(i2c_addr_t addr, uint8_t * buf, size_t buflen, int dostop) /* Set address of slave device */ addr &= MAX_I2C_SA_MASK; /* sanitize address (10-bit max) */ + if (addr > 0xff) { + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->DLEN, 1); - write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->DLEN, 1); - - write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->FIFO, addr & 0xff); - - write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->SL_ADDR, (addr >> XSA) | SL_ADDR_MASK); - - ctrl = read32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL); - ctrl |= BCM283X_CTRL_ST; - ctrl &= (~BCM283X_CTRL_READ); - write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL, ctrl); - - pollmask |= BCM283X_STATUS_DONE; - errmask |= BCM283X_STATUS_CLKT; - errmask |= BCM283X_STATUS_ERR; - - r = rpi_i2c_poll(pollmask | errmask); - if ((r & errmask) != 0) { - /* only debug log level because i2cscan trigers this */ - log_debug(&log, "Read Error! Status=%x\n", r); - return EIO; - } else if ((r & pollmask) == 0) { - log_warn(&log, "No RRDY Interrupt. Status=%x\n", r); - log_warn(&log, - "Likely cause: bad pinmux or no devices on bus\n"); - return EBUSY; - } + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->SL_ADDR, (addr >> XSA) | SL_ADDR_MASK); - write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->DLEN, buflen); + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->FIFO, addr & 0xff); + + ctrl = read32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL); + ctrl |= BCM283X_CTRL_ST; + ctrl &= (~BCM283X_CTRL_READ); + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL, ctrl); + + pollmask |= BCM283X_STATUS_TA; + pollmask |= BCM283X_STATUS_DONE; + errmask |= BCM283X_STATUS_CLKT; + errmask |= BCM283X_STATUS_ERR; + + r = rpi_i2c_poll(pollmask | errmask); + if ((r & errmask) != 0) { + /* only debug log level because i2cscan trigers this */ + log_debug(&log, "Write addrress Error! On %d byte, Status=%x\n", i, r); + return EIO; + } else if ((r & pollmask) == 0) { + log_warn(&log, "No TA Interrupt. Status=%x\n", r); + log_warn(&log, + "Likely cause: bad pinmux or no devices on bus\n"); + return EBUSY; + } + } else { + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->SL_ADDR, addr); + } ctrl = read32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL); ctrl |= BCM283X_CTRL_ST; ctrl |= BCM283X_CTRL_READ; write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL, ctrl); - pollmask |= BCM283X_STATUS_RXD; + errmask |= BCM283X_STATUS_CLKT; + errmask |= BCM283X_STATUS_ERR; + pollmask = BCM283X_STATUS_RXD; + pollmask |= BCM283X_STATUS_RXR; pollmask |= BCM283X_STATUS_RXF; + pollmask |= BCM283X_STATUS_DONE; + + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->DLEN, buflen); for (i = 0; i < buflen; i++) { /* Data to read? */ r = rpi_i2c_poll(pollmask | errmask); if ((r & errmask) != 0) { /* only debug log level because i2cscan trigers this */ - log_debug(&log, "Read Error! Status=%x\n", r); + log_debug(&log, "Read Error! On %d byte, Status=%x\n", i, r); return EIO; } else if ((r & pollmask) == 0) { - log_warn(&log, "No RRDY Interrupt. Status=%x\n", r); + log_warn(&log, "No RXD Interrupt. Status=%x\n", r); log_warn(&log, "Likely cause: bad pinmux or no devices on bus\n"); return EBUSY; @@ -489,14 +465,28 @@ rpi_i2c_read(i2c_addr_t addr, uint8_t * buf, size_t buflen, int dostop) /* read a byte */ buf[i] = read32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->FIFO) & 0xff; - - /* clear the read ready flag */ - rpi_i2c_write_status(BCM283X_STATUS_DONE | errmask); } - set32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL, BCM283X_CTRL_CFIFO, BCM283X_CTRL_CFIFO); + if (rpi_i2c_read_status() & BCM283X_STATUS_ERR) { + log_warn(&log, "can't wait ack\n"); + return EIO; + } - return 0; + pollmask = BCM283X_STATUS_DONE; /* poll access ready bit */ + r = rpi_i2c_poll(pollmask); + if ((r & pollmask) == 0) { + log_warn(&log, "Read operation never finished.\n"); + return EBUSY; + } + + ctrl = read32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL); + ctrl |= BCM283X_CTRL_CFIFO; + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL, ctrl); + + /* clear the read ready flag */ + rpi_i2c_write_status(BCM283X_STATUS_DONE | errmask); + + return OK; } static int @@ -506,17 +496,23 @@ rpi_i2c_write(i2c_addr_t addr, const uint8_t * buf, size_t buflen, int dostop) uint32_t pollmask; uint32_t errmask; uint32_t ctrl; - /* Set address of slave device */ addr &= MAX_I2C_SA_MASK; /* sanitize address (10-bit max) */ - write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->DLEN, buflen + 1); + if (addr > 0xff) { + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->DLEN, buflen + 1); - write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->FIFO, addr & 0xff); + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->SL_ADDR, (addr >> XSA) | SL_ADDR_MASK); + + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->FIFO, addr & 0xff); + } else { + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->DLEN, buflen); + + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->SL_ADDR, addr); + } - pollmask |= BCM283X_STATUS_DONE; - pollmask |= BCM283X_STATUS_TXE; pollmask |= BCM283X_STATUS_TXD; + pollmask |= BCM283X_STATUS_DONE; errmask |= BCM283X_STATUS_CLKT; errmask |= BCM283X_STATUS_ERR; @@ -525,27 +521,41 @@ rpi_i2c_write(i2c_addr_t addr, const uint8_t * buf, size_t buflen, int dostop) ctrl &= (~BCM283X_CTRL_READ); write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL, ctrl); - for (i = 0; i < buflen; i++) { + log_debug(&log, "buflen %d data 0x%x\n", buflen, buf[0]); + for (i = 0; i < buflen; i++) { + log_debug(&log, "write\n"); /* Ready to write? */ r = rpi_i2c_poll(pollmask | errmask); if ((r & errmask) != 0) { - log_warn(&log, "Write Error! Status=%x\n", r); + log_warn(&log, "Write Error! On %d byte, Status=%x\n", i, r); return EIO; } else if ((r & pollmask) == 0) { log_warn(&log, "Not ready for write? Status=%x\n", r); return EBUSY; } - write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->FIFO, buf[i]); - - /* clear the write ready flag */ - rpi_i2c_write_status(BCM283X_STATUS_DONE | errmask); + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->FIFO, buf[i]); + } + + if (rpi_i2c_read_status() & BCM283X_STATUS_ERR) { + log_warn(&log, "can't wait ack\n"); + return EIO; } - set32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL, BCM283X_CTRL_CFIFO, BCM283X_CTRL_CFIFO); + r = rpi_i2c_poll(pollmask); + if ((r & pollmask) == 0) { + log_warn(&log, "Write operation never finished.\n"); + return EBUSY; + } - return 0; + ctrl = read32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL); + ctrl |= BCM283X_CTRL_CFIFO; + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL, ctrl); + /* clear the write ready flag */ + rpi_i2c_write_status(BCM283X_STATUS_DONE | errmask); + + return OK; } int @@ -558,6 +568,7 @@ rpi_interface_setup(int (**process) (minix_i2c_ioctl_exec_t * ioctl_exec), struct machine machine; sys_getmachine(&machine); + log_info(&log, "setup start\n"); /* Fill in the function pointer */ *process = rpi_i2c_process; @@ -571,6 +582,8 @@ rpi_interface_setup(int (**process) (minix_i2c_ioctl_exec_t * ioctl_exec), return EINVAL; } + log_debug(&log, "cont\n"); + if (i2c_bus_id < 0 || i2c_bus_id >= rpi_i2c_nbuses) { return EINVAL; } @@ -602,12 +615,10 @@ rpi_interface_setup(int (**process) (minix_i2c_ioctl_exec_t * ioctl_exec), panic("Unable to map i2c registers"); } - /* Enable Clocks */ - rpi_i2c_clkconf(i2c_bus_id); - /* Perform a soft reset of the I2C module to ensure a fresh start */ r = rpi_i2c_soft_reset(); if (r != OK) { + log_warn(&log, "can't do soft reset\n"); /* module didn't come back up :( */ return r; } diff --git a/minix/drivers/bus/i2c/arch/earm/rpi/rpi_i2c_registers.h b/minix/drivers/bus/i2c/arch/earm/rpi/rpi_i2c_registers.h index 4cea16bcc..803d45fab 100644 --- a/minix/drivers/bus/i2c/arch/earm/rpi/rpi_i2c_registers.h +++ b/minix/drivers/bus/i2c/arch/earm/rpi/rpi_i2c_registers.h @@ -64,8 +64,10 @@ #define RXFIFO_CLR 14 #define TXFIFO_CLR 6 -#define BCM283X_STATUS_TA 0x00 -#define BCM283X_STATUS_DONE 0x01 +#define BCM283X_STATUS_TA 0x01 +#define BCM283X_STATUS_DONE 0x02 +#define BCM283X_STATUS_TXW 0x04 +#define BCM283X_STATUS_RXR 0x08 #define BCM283X_STATUS_TXD 0x10 #define BCM283X_STATUS_RXD 0x20 #define BCM283X_STATUS_TXE 0x40 @@ -73,8 +75,8 @@ #define BCM283X_STATUS_ERR 0x100 #define BCM283X_STATUS_CLKT 0x200 -#define BCM283X_CTRL_READ 0x00 -#define BCM283X_CTRL_ST 0x20 +#define BCM283X_CTRL_READ 0x01 +#define BCM283X_CTRL_ST 0x80 #define BCM283X_CTRL_CFIFO 0x30 #define BCM283X_CTRL_INTD 0x100 #define BCM283X_CTRL_INTT 0x200 diff --git a/minix/drivers/bus/i2c/i2c.conf b/minix/drivers/bus/i2c/i2c.conf index 99dc1f925..ab6e1b3fb 100644 --- a/minix/drivers/bus/i2c/i2c.conf +++ b/minix/drivers/bus/i2c/i2c.conf @@ -17,5 +17,5 @@ service i2c # BCM283X (RaspberryPi 2,3) 47 ; - ipc SYSTEM RS DS; + ipc SYSTEM rs ds; }; diff --git a/minix/include/minix/padconf.h b/minix/include/minix/padconf.h index 5192a0296..36711405a 100644 --- a/minix/include/minix/padconf.h +++ b/minix/include/minix/padconf.h @@ -324,4 +324,16 @@ #define PADCONF_RPI2_REGISTERS_OFFSET 0x0000 #define PADCONF_RPI2_REGISTERS_SIZE 0x1000 +#define GPFSEL09 (0x00000000) +#define GPFSEL1019 (0x00000004) +#define GPFSEL2029 (0x00000008) +#define GPFSEL3039 (0x0000000C) +#define GPFSEL4049 (0x00000010) +#define GPFSEL5053 (0x00000014) + +#define CONTROL_BCM_CONF_I2C0_SDA (0x00E00000) +#define CONTROL_BCM_CONF_I2C0_SCL (0x07000000) +#define CONTROL_BCM_CONF_I2C1_SDA (0x00000100) +#define CONTROL_BCM_CONF_I2C1_SCL (0x00000800) + #endif /* __MINIX_PADCONF_H */