diff --git a/distrib/sets/lists/minix-base/md.evbarm b/distrib/sets/lists/minix-base/md.evbarm index b01b7608a..1ccc1c681 100644 --- a/distrib/sets/lists/minix-base/md.evbarm +++ b/distrib/sets/lists/minix-base/md.evbarm @@ -9,6 +9,7 @@ ./etc/rc.capes/BB-BONE-WTHR-01 minix-base ./etc/system.conf.d/bmp085 minix-base ./etc/system.conf.d/gpio minix-base +./etc/system.conf.d/i2c minix-base ./etc/system.conf.d/lan8710a minix-base ./etc/system.conf.d/sht21 minix-base ./etc/system.conf.d/tsl2550 minix-base @@ -17,12 +18,11 @@ ./service/cat24c256 minix-base ./service/fb minix-base ./service/gpio minix-base +./service/i2c minix-base ./service/lan8710a minix-base ./service/mailbox minix-base ./service/omap_emmc minix-base -./service/i2c_omap minix-base ./service/omap_mmc minix-base -./service/i2c_rpi minix-base ./service/rpi_mmc minix-base ./service/random minix-base ./service/sht21 minix-base diff --git a/minix/drivers/bus/i2c/Makefile b/minix/drivers/bus/i2c/Makefile index 4f9302479..400df49b5 100644 --- a/minix/drivers/bus/i2c/Makefile +++ b/minix/drivers/bus/i2c/Makefile @@ -1,16 +1,18 @@ # Makefile for I2C support +PROG= i2c +SRCS+= i2c.c +FILESNAME=i2c +FILES=i2c.conf + .if ${MACHINE_ARCH} == "earm" .for pl in rpi omap .PATH: ${.CURDIR}/arch/earm/${pl} -PROGS+= i2c_${pl} -SRCS.i2c_${pl}+= i2c.c ${pl}_i2c.c ${pl}_i2c.h ${pl}_i2c_registers.h -FILES.i2c_${pl}=i2c_${pl}.conf -FILESNAME=i2c_${pl} +SRCS+= ${pl}_i2c.c ${pl}_i2c.h ${pl}_i2c_registers.h .endfor .else .PATH: ${.CURDIR}/arch/${MACHINE_ARCH} -SRCS.i2c += pci_i2c.c pci_i2c.h pci_i2c_register.h +SRCS+= pci_i2c.c pci_i2c.h pci_i2c_register.h .endif FILESDIR= /etc/system.conf.d diff --git a/minix/drivers/bus/i2c/arch/earm/omap/i2c.conf b/minix/drivers/bus/i2c/arch/earm/omap/i2c.conf deleted file mode 100644 index 6112f91c7..000000000 --- a/minix/drivers/bus/i2c/arch/earm/omap/i2c.conf +++ /dev/null @@ -1,20 +0,0 @@ -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 - ; - ipc SYSTEM RS DS; -}; - diff --git a/minix/drivers/bus/i2c/arch/earm/rpi/i2c.conf b/minix/drivers/bus/i2c/arch/earm/rpi/i2c.conf deleted file mode 100644 index 441ed4443..000000000 --- a/minix/drivers/bus/i2c/arch/earm/rpi/i2c.conf +++ /dev/null @@ -1,12 +0,0 @@ -service rpi_i2c -{ - system - PRIVCTL # 4 - IRQCTL # 19 - PADCONF # 57 - ; - irq - ; - ipc SYSTEM RS DS; -}; - 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 a67cabe89..f12dd7307 100644 --- a/minix/drivers/bus/i2c/arch/earm/rpi/rpi_i2c.c +++ b/minix/drivers/bus/i2c/arch/earm/rpi/rpi_i2c.c @@ -38,167 +38,65 @@ * to access these registers. The DM37XX TRM Section 17.6 warns that 32-bit * accesses can corrupt the register contents. */ -typedef struct omap_i2c_registers +typedef struct { - vir_bytes I2C_REVNB_LO; /* AM335X Only */ - vir_bytes I2C_REVNB_HI; /* AM335X Only */ - vir_bytes I2C_REV; /* DM37XX Only */ - vir_bytes I2C_IE; /* DM37XX Only */ - vir_bytes I2C_STAT; /* DM37XX Only */ - vir_bytes I2C_SYSC; - vir_bytes I2C_IRQSTATUS_RAW; /* AM335X Only */ - vir_bytes I2C_IRQSTATUS; /* AM335X Only */ - vir_bytes I2C_IRQENABLE_SET; /* AM335X Only */ - vir_bytes I2C_IRQENABLE_CLR; /* AM335X Only */ - vir_bytes I2C_WE; - vir_bytes I2C_DMARXENABLE_SET; /* AM335X Only */ - vir_bytes I2C_DMATXENABLE_SET; /* AM335X Only */ - vir_bytes I2C_DMARXENABLE_CLR; /* AM335X Only */ - vir_bytes I2C_DMATXENABLE_CLR; /* AM335X Only */ - vir_bytes I2C_DMARXWAKE_EN; /* AM335X Only */ - vir_bytes I2C_DMATXWAKE_EN; /* AM335X Only */ - vir_bytes I2C_SYSS; - vir_bytes I2C_BUF; - vir_bytes I2C_CNT; - vir_bytes I2C_DATA; - vir_bytes I2C_CON; - vir_bytes I2C_OA; /* AM335X Only */ - vir_bytes I2C_OA0; /* DM37XX Only */ - vir_bytes I2C_SA; - vir_bytes I2C_PSC; - vir_bytes I2C_SCLL; - vir_bytes I2C_SCLH; - vir_bytes I2C_SYSTEST; - vir_bytes I2C_BUFSTAT; - vir_bytes I2C_OA1; - vir_bytes I2C_OA2; - vir_bytes I2C_OA3; - vir_bytes I2C_ACTOA; - vir_bytes I2C_SBLOCK; -} omap_i2c_regs_t; + vir_bytes CTRL; + vir_bytes ST; + vir_bytes DLEN; + vir_bytes SL_ADDR; + vir_bytes FIFO; + vir_bytes DIV; + vir_bytes DEL; + vir_bytes CLKT; +} rpi_i2c_regs_t; /* generic definition an i2c bus */ -typedef struct omap_i2c_bus +typedef struct rpi_i2c_bus { - enum bus_types - { AM335X_I2C_BUS, DM37XX_I2C_BUS} bus_type; phys_bytes mr_base; phys_bytes mr_size; vir_bytes mapped_addr; - omap_i2c_regs_t *regs; + rpi_i2c_regs_t *regs; uint32_t functional_clock; uint32_t module_clock; uint32_t bus_speed; - uint16_t major; - uint16_t minor; int irq; int irq_hook_id; int irq_hook_kernel_id; -} omap_i2c_bus_t; +} rpi_i2c_bus_t; /* Define the registers for each chip */ -static omap_i2c_regs_t am335x_i2c_regs = { - .I2C_REVNB_LO = AM335X_I2C_REVNB_LO, - .I2C_REVNB_HI = AM335X_I2C_REVNB_HI, - .I2C_SYSC = AM335X_I2C_SYSC, - .I2C_IRQSTATUS_RAW = AM335X_I2C_IRQSTATUS_RAW, - .I2C_IRQSTATUS = AM335X_I2C_IRQSTATUS, - .I2C_IRQENABLE_SET = AM335X_I2C_IRQENABLE_SET, - .I2C_IRQENABLE_CLR = AM335X_I2C_IRQENABLE_CLR, - .I2C_WE = AM335X_I2C_WE, - .I2C_DMARXENABLE_SET = AM335X_I2C_DMARXENABLE_SET, - .I2C_DMATXENABLE_SET = AM335X_I2C_DMATXENABLE_SET, - .I2C_DMARXENABLE_CLR = AM335X_I2C_DMARXENABLE_CLR, - .I2C_DMATXENABLE_CLR = AM335X_I2C_DMATXENABLE_CLR, - .I2C_DMARXWAKE_EN = AM335X_I2C_DMARXWAKE_EN, - .I2C_DMATXWAKE_EN = AM335X_I2C_DMATXWAKE_EN, - .I2C_SYSS = AM335X_I2C_SYSS, - .I2C_BUF = AM335X_I2C_BUF, - .I2C_CNT = AM335X_I2C_CNT, - .I2C_DATA = AM335X_I2C_DATA, - .I2C_CON = AM335X_I2C_CON, - .I2C_OA = AM335X_I2C_OA, - .I2C_SA = AM335X_I2C_SA, - .I2C_PSC = AM335X_I2C_PSC, - .I2C_SCLL = AM335X_I2C_SCLL, - .I2C_SCLH = AM335X_I2C_SCLH, - .I2C_SYSTEST = AM335X_I2C_SYSTEST, - .I2C_BUFSTAT = AM335X_I2C_BUFSTAT, - .I2C_OA1 = AM335X_I2C_OA1, - .I2C_OA2 = AM335X_I2C_OA2, - .I2C_OA3 = AM335X_I2C_OA3, - .I2C_ACTOA = AM335X_I2C_ACTOA, - .I2C_SBLOCK = AM335X_I2C_SBLOCK -}; - -static omap_i2c_regs_t dm37xx_i2c_regs = { - .I2C_REV = DM37XX_I2C_REV, - .I2C_IE = DM37XX_I2C_IE, - .I2C_STAT = DM37XX_I2C_STAT, - .I2C_WE = DM37XX_I2C_WE, - .I2C_SYSS = DM37XX_I2C_SYSS, - .I2C_BUF = DM37XX_I2C_BUF, - .I2C_CNT = DM37XX_I2C_CNT, - .I2C_DATA = DM37XX_I2C_DATA, - .I2C_SYSC = DM37XX_I2C_SYSC, - .I2C_CON = DM37XX_I2C_CON, - .I2C_OA0 = DM37XX_I2C_OA0, - .I2C_SA = DM37XX_I2C_SA, - .I2C_PSC = DM37XX_I2C_PSC, - .I2C_SCLL = DM37XX_I2C_SCLL, - .I2C_SCLH = DM37XX_I2C_SCLH, - .I2C_SYSTEST = DM37XX_I2C_SYSTEST, - .I2C_BUFSTAT = DM37XX_I2C_BUFSTAT, - .I2C_OA1 = DM37XX_I2C_OA1, - .I2C_OA2 = DM37XX_I2C_OA2, - .I2C_OA3 = DM37XX_I2C_OA3, - .I2C_ACTOA = DM37XX_I2C_ACTOA, - .I2C_SBLOCK = DM37XX_I2C_SBLOCK +static rpi_i2c_regs_t bcm283x_i2c_regs = { + .CTRL = BCM283X_CTRL, + .ST = BCM283X_STATUS, + .DLEN = BCM283X_DLEN, + .SL_ADDR = BCM283X_SL_ADDR, + .FIFO = BCM283X_FIFO, + .DIV = BCM283X_DIV, + .DEL = BCM283X_DEL, + .CLKT = BCM283X_CLKT, }; /* Define the buses available on each chip */ -static omap_i2c_bus_t am335x_i2c_buses[] = { - {AM335X_I2C_BUS, AM335X_I2C0_BASE, AM335X_I2C0_SIZE, 0, &am335x_i2c_regs, - AM335X_FUNCTIONAL_CLOCK, AM335X_MODULE_CLOCK, - BUS_SPEED_400KHz, AM335X_REV_MAJOR, AM335X_REV_MINOR, - AM335X_I2C0_IRQ, 1, 1}, - {AM335X_I2C_BUS, AM335X_I2C1_BASE, AM335X_I2C1_SIZE, 0, &am335x_i2c_regs, - AM335X_FUNCTIONAL_CLOCK, AM335X_MODULE_CLOCK, - BUS_SPEED_100KHz, AM335X_REV_MAJOR, AM335X_REV_MINOR, - AM335X_I2C1_IRQ, 2, 3}, - {AM335X_I2C_BUS, AM335X_I2C2_BASE, AM335X_I2C2_SIZE, 0, &am335x_i2c_regs, - AM335X_FUNCTIONAL_CLOCK, AM335X_MODULE_CLOCK, - BUS_SPEED_100KHz, AM335X_REV_MAJOR, AM335X_REV_MINOR, - AM335X_I2C2_IRQ, 3, 3} -}; +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}, + {BCM283X_I2C1_BASE, BCM283X_I2C1_SIZE, 0, &bcm283x_i2c_regs, + BCM283X_FUNCTIONAL_CLOCK, BCM283X_MODULE_CLOCK, + BUS_SPEED_400KHz, BCM283X_I2C0_IRQ, 2, 3} + }; -#define AM335X_OMAP_NBUSES (sizeof(am335x_i2c_buses) / sizeof(omap_i2c_bus_t)) - -static omap_i2c_bus_t dm37xx_i2c_buses[] = { - {DM37XX_I2C_BUS, DM37XX_I2C0_BASE, DM37XX_I2C0_SIZE, 0, &dm37xx_i2c_regs, - DM37XX_FUNCTIONAL_CLOCK, DM37XX_MODULE_CLOCK, - BUS_SPEED_100KHz, DM37XX_REV_MAJOR, DM37XX_REV_MINOR, - DM37XX_I2C0_IRQ, 1, 1}, - {DM37XX_I2C_BUS, DM37XX_I2C1_BASE, DM37XX_I2C1_SIZE, 0, &dm37xx_i2c_regs, - DM37XX_FUNCTIONAL_CLOCK, DM37XX_MODULE_CLOCK, - BUS_SPEED_100KHz, DM37XX_REV_MAJOR, DM37XX_REV_MINOR, - DM37XX_I2C1_IRQ, 2, 2}, - {DM37XX_I2C_BUS, DM37XX_I2C2_BASE, DM37XX_I2C2_SIZE, 0, &dm37xx_i2c_regs, - DM37XX_FUNCTIONAL_CLOCK, DM37XX_MODULE_CLOCK, - BUS_SPEED_100KHz, DM37XX_REV_MAJOR, DM37XX_REV_MINOR, - DM37XX_I2C2_IRQ, 3, 3} -}; - -#define DM37XX_OMAP_NBUSES (sizeof(dm37xx_i2c_buses) / sizeof(omap_i2c_bus_t)) +#define BCM283X_rpi_NBUSES (sizeof(bcm283x_i2c_buses) / sizeof(rpi_i2c_bus_t)) /* Globals */ -static omap_i2c_bus_t *omap_i2c_buses; /* all available buses for this SoC */ -static omap_i2c_bus_t *omap_i2c_bus; /* the bus selected at start-up */ -static int omap_i2c_nbuses; /* number of buses supported by SoC */ +static rpi_i2c_bus_t *rpi_i2c_buses; /* all available buses for this SoC */ +static rpi_i2c_bus_t *rpi_i2c_bus; /* the bus selected at start-up */ +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 = { @@ -210,29 +108,29 @@ static struct log log = { /* Local Function Prototypes */ /* Implementation of Generic I2C Interface using Bus Specific Code */ -static int omap_i2c_process(minix_i2c_ioctl_exec_t * m); +static int rpi_i2c_process(minix_i2c_ioctl_exec_t * m); /* Bus Specific Code */ -static void omap_i2c_flush(void); -static uint16_t omap_i2c_poll(uint16_t mask); -static int omap_i2c_bus_is_free(void); -static int omap_i2c_soft_reset(void); -static void omap_i2c_bus_init(void); -static void omap_i2c_padconf(int i2c_bus_id); -static void omap_i2c_clkconf(int i2c_bus_id); -static void omap_i2c_intr_enable(void); -static uint16_t omap_i2c_read_status(void); -static void omap_i2c_write_status(uint16_t mask); -static int omap_i2c_read(i2c_addr_t addr, uint8_t * buf, size_t buflen, +static void rpi_i2c_flush(void); +static uint32_t rpi_i2c_poll(uint32_t mask); +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); +static int rpi_i2c_read(i2c_addr_t addr, uint8_t * buf, size_t buflen, int dostop); -static int omap_i2c_write(i2c_addr_t addr, const uint8_t * buf, size_t buflen, +static int rpi_i2c_write(i2c_addr_t addr, const uint8_t * buf, size_t buflen, int dostop); /* * Performs the action in minix_i2c_ioctl_exec_t. */ static int -omap_i2c_process(minix_i2c_ioctl_exec_t * ioctl_exec) +rpi_i2c_process(minix_i2c_ioctl_exec_t * ioctl_exec) { int r; @@ -245,37 +143,37 @@ omap_i2c_process(minix_i2c_ioctl_exec_t * ioctl_exec) return EINVAL; } - omap_i2c_flush(); /* clear any garbage in the fifo */ + rpi_i2c_flush(); /* clear any garbage in the fifo */ /* Check bus busy flag before using the bus */ - r = omap_i2c_bus_is_free(); + r = rpi_i2c_bus_is_free(); if (r == 0) { log_warn(&log, "Bus is busy\n"); return EBUSY; } if (ioctl_exec->iie_cmdlen > 0) { - r = omap_i2c_write(ioctl_exec->iie_addr, ioctl_exec->iie_cmd, + r = rpi_i2c_write(ioctl_exec->iie_addr, ioctl_exec->iie_cmd, ioctl_exec->iie_cmdlen, !(I2C_OP_READ_P(ioctl_exec->iie_op))); if (r != OK) { - omap_i2c_soft_reset(); - omap_i2c_bus_init(); + rpi_i2c_soft_reset(); + rpi_i2c_bus_init(); return r; } } if (I2C_OP_READ_P(ioctl_exec->iie_op)) { - r = omap_i2c_read(ioctl_exec->iie_addr, ioctl_exec->iie_buf, + r = rpi_i2c_read(ioctl_exec->iie_addr, ioctl_exec->iie_buf, ioctl_exec->iie_buflen, I2C_OP_STOP_P(ioctl_exec->iie_op)); } else { - r = omap_i2c_write(ioctl_exec->iie_addr, ioctl_exec->iie_buf, + r = rpi_i2c_write(ioctl_exec->iie_addr, ioctl_exec->iie_buf, ioctl_exec->iie_buflen, I2C_OP_STOP_P(ioctl_exec->iie_op)); } if (r != OK) { - omap_i2c_soft_reset(); - omap_i2c_bus_init(); + rpi_i2c_soft_reset(); + rpi_i2c_bus_init(); return r; } @@ -289,20 +187,17 @@ omap_i2c_process(minix_i2c_ioctl_exec_t * ioctl_exec) * doing a read. */ static void -omap_i2c_flush(void) +rpi_i2c_flush(void) { int tries; int status; for (tries = 0; tries < 1000; tries++) { - status = omap_i2c_poll(1 << RRDY); - if ((status & (1 << RRDY)) != 0) { /* bytes available for reading */ + 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) read16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_DATA); - - /* clear the read ready flag */ - omap_i2c_write_status(1 << RRDY); + (void) read32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->FIFO); } else { break; /* buffer drained */ @@ -314,16 +209,16 @@ omap_i2c_flush(void) * Poll the status register checking the bits set in 'mask'. * Returns the status if any bits set or 0x0000 when the timeout is reached. */ -static uint16_t -omap_i2c_poll(uint16_t mask) +static uint32_t +rpi_i2c_poll(uint32_t mask) { spin_t spin; - uint16_t status; + uint32_t status; /* poll for up to 1 s */ spin_init(&spin, 1000000); do { - status = omap_i2c_read_status(); + status = rpi_i2c_read_status(); if ((status & mask) != 0) { /* any bits in mask set */ return status; } @@ -338,7 +233,7 @@ omap_i2c_poll(uint16_t mask) * expires (return 0). */ static int -omap_i2c_bus_is_free(void) +rpi_i2c_bus_is_free(void) { spin_t spin; uint16_t status; @@ -347,8 +242,8 @@ omap_i2c_bus_is_free(void) spin_init(&spin, 1000000); do { - status = omap_i2c_read_status(); - if ((status & (1 << BB)) == 0) { + status = rpi_i2c_read_status(); + if ((status & BCM283X_STATUS_TA) == 0) { return 1; /* bus is free */ } @@ -358,145 +253,95 @@ omap_i2c_bus_is_free(void) } static void -omap_i2c_clkconf(int i2c_bus_id) +rpi_i2c_clkconf(int i2c_bus_id) { clkconf_init(); - if (omap_i2c_bus->bus_type == DM37XX_I2C_BUS) { - - clkconf_set(CM_ICLKEN1_CORE, BIT((15 + i2c_bus_id)), - 0xffffffff); - clkconf_set(CM_FCLKEN1_CORE, BIT((15 + i2c_bus_id)), - 0xffffffff); - - } else if (omap_i2c_bus->bus_type == AM335X_I2C_BUS) { - - 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; - case 2: - clkconf_set(CM_PER_I2C2_CLKCTRL, BIT(1), 0xffffffff); - break; - default: - log_warn(&log, "Invalid i2c_bus_id\n"); - break; - } + 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 -omap_i2c_padconf(int i2c_bus_id) +rpi_i2c_padconf(int i2c_bus_id) { int r; u32_t pinopts; - if (omap_i2c_bus->bus_type == AM335X_I2C_BUS) { - - /* 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); - - 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, - pinopts); - if (r != OK) { - log_warn(&log, "padconf failed (r=%d)\n", r); - } - - log_debug(&log, "pinopts=0x%x\n", pinopts); - break; - - case 1: - pinopts |= CONTROL_CONF_MUXMODE(2); - - 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, - pinopts); - if (r != OK) { - log_warn(&log, "padconf failed (r=%d)\n", r); - } - log_debug(&log, "pinopts=0x%x\n", pinopts); - break; - - case 2: - pinopts |= CONTROL_CONF_MUXMODE(3); - - r = sys_padconf(CONTROL_CONF_UART1_CTSN, 0xffffffff, - pinopts); - if (r != OK) { - log_warn(&log, "padconf failed (r=%d)\n", r); - } - - r = sys_padconf(CONTROL_CONF_UART1_RTSN, - 0xffffffff, pinopts); - if (r != OK) { - log_warn(&log, "padconf failed (r=%d)\n", r); - } - - log_debug(&log, "pinopts=0x%x\n", pinopts); - break; - - default: - log_warn(&log, "Invalid i2c_bus_id\n"); - break; + /* 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); + + 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, + pinopts); + if (r != OK) { + log_warn(&log, "padconf failed (r=%d)\n", r); + } + + log_debug(&log, "pinopts=0x%x\n", pinopts); + break; + + case 1: + pinopts |= CONTROL_CONF_MUXMODE(2); + + 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, + pinopts); + if (r != OK) { + log_warn(&log, "padconf failed (r=%d)\n", r); + } + + log_debug(&log, "pinopts=0x%x\n", pinopts); + break; + + default: + log_warn(&log, "Invalid i2c_bus_id\n"); + break; } - - /* nothing to do for the DM37XX */ } static int -omap_i2c_soft_reset(void) +rpi_i2c_soft_reset(void) { - spin_t spin; - /* Disable to do soft reset */ - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_CON, 0); + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL, 0); micro_delay(50000); - /* Do a soft reset */ - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_SYSC, (1 << SRST)); - /* Have to temporarily enable I2C to read RDONE */ - set16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_CON, (1<mapped_addr + rpi_i2c_bus->regs->CTRL, BCM283X_CTRL_I2C_EN | BCM283X_CTRL_CFIFO, + BCM283X_CTRL_I2C_EN | BCM283X_CTRL_CFIFO); micro_delay(50000); - /* wait up to 3 seconds for reset to complete */ - spin_init(&spin, 3000000); - do { - if (read16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_SYSS) & (1 << RDONE)) { - return OK; - } - - } while (spin_check(&spin)); - - log_warn(&log, "Tried soft reset, but bus never came back.\n"); - return EIO; + return OK; } static void -omap_i2c_intr_enable(void) +rpi_i2c_intr_enable(void) { int r; uint16_t intmask; @@ -504,8 +349,8 @@ omap_i2c_intr_enable(void) static int enabled = 0; if (!policy_set) { - r = sys_irqsetpolicy(omap_i2c_bus->irq, 0, - &omap_i2c_bus->irq_hook_kernel_id); + r = sys_irqsetpolicy(rpi_i2c_bus->irq, 0, + &rpi_i2c_bus->irq_hook_kernel_id); if (r == OK) { policy_set = 1; } else { @@ -514,12 +359,12 @@ omap_i2c_intr_enable(void) } if (policy_set && !enabled) { - r = sys_irqenable(&omap_i2c_bus->irq_hook_kernel_id); + r = sys_irqenable(&rpi_i2c_bus->irq_hook_kernel_id); if (r == OK) { enabled = 1; } else { log_warn(&log, "Couldn't enable irq %d (hooked)\n", - omap_i2c_bus->irq); + rpi_i2c_bus->irq); } } @@ -527,142 +372,110 @@ omap_i2c_intr_enable(void) * if just using polling (i.e. non-interrupt driver programming). */ intmask = 0; - intmask |= (1 << ROVR); - intmask |= (1 << AERR); - intmask |= (1 << XRDY); - intmask |= (1 << RRDY); - intmask |= (1 << ARDY); - intmask |= (1 << NACK); - intmask |= (1 << AL); + intmask |= BCM283X_CTRL_INTR; + intmask |= BCM283X_CTRL_INTT; + intmask |= BCM283X_CTRL_INTD; - if (omap_i2c_bus->bus_type == AM335X_I2C_BUS) { - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_IRQENABLE_SET, intmask); - } else if (omap_i2c_bus->bus_type == DM37XX_I2C_BUS) { - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_IE, intmask); - } else { - log_warn(&log, "Don't know how to enable interrupts.\n"); - } + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL, intmask); } static void -omap_i2c_bus_init(void) +rpi_i2c_bus_init(void) { /* Ensure i2c module is disabled before setting prescalar & bus speed */ - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_CON, 0); + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->CTRL, 0); micro_delay(50000); - /* Disable autoidle */ - set16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_SYSC, (1<mapped_addr + omap_i2c_bus->regs->I2C_PSC, - ((omap_i2c_bus->functional_clock / omap_i2c_bus->module_clock) - - 1)); - - /* Set the bus speed */ - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_SCLL, - ((omap_i2c_bus->module_clock / (2 * omap_i2c_bus->bus_speed)) - - 7)); - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_SCLH, - ((omap_i2c_bus->module_clock / (2 * omap_i2c_bus->bus_speed)) - - 5)); - - /* Set own I2C address */ - if (omap_i2c_bus->bus_type == AM335X_I2C_BUS) { - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_OA, I2C_OWN_ADDRESS); - } else if (omap_i2c_bus->bus_type == DM37XX_I2C_BUS) { - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_OA0, I2C_OWN_ADDRESS); - } else { - log_warn(&log, "Don't know how to set own address.\n"); + uint32_t divider = (rpi_i2c_bus->functional_clock / rpi_i2c_bus->module_clock) - 1; + if (divider > BCM283X_I2C_CDIV_MAX || + divider < BCM283X_I2C_CDIV_MIN) { + log_warn(&log, "Incorrect divider\n"); } - /* Set TX/RX Threshold to 1 and disable I2C DMA */ - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_BUF, 0x0000); + if (divider & 0x01) + divider++; + + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->DIV, divider); + + /* Set own I2C address */ + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->SL_ADDR, I2C_OWN_ADDRESS); /* Bring the i2c module out of reset */ - set16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_CON, (1<mapped_addr + rpi_i2c_bus->regs->CTRL, BCM283X_CTRL_I2C_EN, BCM283X_CTRL_I2C_EN); micro_delay(50000); /* * Enable interrupts */ - omap_i2c_intr_enable(); + rpi_i2c_intr_enable(); } -static uint16_t -omap_i2c_read_status(void) +static uint32_t +rpi_i2c_read_status(void) { - uint16_t status = 0x0000; - - if (omap_i2c_bus->bus_type == AM335X_I2C_BUS) { - /* TRM says to use RAW for polling for events */ - status = read16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_IRQSTATUS_RAW); - } else if (omap_i2c_bus->bus_type == DM37XX_I2C_BUS) { - status = read16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_STAT); - } else { - log_warn(&log, "Don't know how to read i2c bus status.\n"); - } - + uint16_t status = read32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->ST); return status; } static void -omap_i2c_write_status(uint16_t mask) +rpi_i2c_write_status(uint32_t mask) { - if (omap_i2c_bus->bus_type == AM335X_I2C_BUS) { - /* write 1's to IRQSTATUS (not RAW) to clear the bits */ - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_IRQSTATUS, mask); - } else if (omap_i2c_bus->bus_type == DM37XX_I2C_BUS) { - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_STAT, mask); - } else { - log_warn(&log, "Don't know how to clear i2c bus status.\n"); - } + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->ST, mask); } static int -omap_i2c_read(i2c_addr_t addr, uint8_t * buf, size_t buflen, int dostop) +rpi_i2c_read(i2c_addr_t addr, uint8_t * buf, size_t buflen, int dostop) { int r, i; - uint16_t conopts; - uint16_t pollmask; - uint16_t errmask; + uint32_t ctrl; + uint32_t pollmask; + uint32_t errmask; /* Set address of slave device */ - conopts = 0; addr &= MAX_I2C_SA_MASK; /* sanitize address (10-bit max) */ - if (addr > 0x7f) { - /* 10-bit extended address in use, need to set XSA */ - conopts |= (1 << XSA); + + 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->DLEN, buflen); - errmask = 0; - errmask |= (1 << ROVR); - errmask |= (1 << AERR); - errmask |= (1 << NACK); - errmask |= (1 << AL); + 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 = 0; - pollmask |= (1 << RRDY); - - /* Set bytes to read and slave address */ - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_CNT, buflen); - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_SA, addr); - - /* Set control register */ - conopts |= (1 << I2C_EN); /* enabled */ - conopts |= (1 << MST); /* master mode */ - conopts |= (1 << STT); /* start condition */ - - if (dostop != 0) { - conopts |= (1 << STP); /* stop condition */ - } - - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_CON, conopts); + pollmask |= BCM283X_STATUS_RXD; + pollmask |= BCM283X_STATUS_RXF; for (i = 0; i < buflen; i++) { /* Data to read? */ - r = omap_i2c_poll(pollmask | errmask); + 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); @@ -675,75 +488,47 @@ omap_i2c_read(i2c_addr_t addr, uint8_t * buf, size_t buflen, int dostop) } /* read a byte */ - buf[i] = read16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_DATA) & 0xff; + buf[i] = read32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->FIFO) & 0xff; /* clear the read ready flag */ - omap_i2c_write_status(pollmask); + rpi_i2c_write_status(BCM283X_STATUS_DONE | errmask); } - r = omap_i2c_read_status(); - if ((r & (1 << NACK)) != 0) { - log_warn(&log, "NACK\n"); - return EIO; - } - - /* Wait for operation to complete */ - pollmask = (1<mapped_addr + rpi_i2c_bus->regs->CTRL, BCM283X_CTRL_CFIFO, BCM283X_CTRL_CFIFO); return 0; } static int -omap_i2c_write(i2c_addr_t addr, const uint8_t * buf, size_t buflen, int dostop) +rpi_i2c_write(i2c_addr_t addr, const uint8_t * buf, size_t buflen, int dostop) { int r, i; - uint16_t conopts; - uint16_t pollmask; - uint16_t errmask; + uint32_t pollmask; + uint32_t errmask; + uint32_t ctrl; /* Set address of slave device */ - conopts = 0; addr &= MAX_I2C_SA_MASK; /* sanitize address (10-bit max) */ - if (addr > 0x7f) { - /* 10-bit extended address in use, need to set XSA */ - conopts |= (1 << XSA); - } - pollmask = 0; - pollmask |= (1 << XRDY); + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->DLEN, buflen + 1); - errmask = 0; - errmask |= (1 << ROVR); - errmask |= (1 << AERR); - errmask |= (1 << NACK); - errmask |= (1 << AL); + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->FIFO, addr & 0xff); - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_CNT, buflen); - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_SA, addr); + pollmask |= BCM283X_STATUS_DONE; + pollmask |= BCM283X_STATUS_TXE; + pollmask |= BCM283X_STATUS_TXD; + errmask |= BCM283X_STATUS_CLKT; + errmask |= BCM283X_STATUS_ERR; - /* Set control register */ - conopts |= (1 << I2C_EN); /* enabled */ - conopts |= (1 << MST); /* master mode */ - conopts |= (1 << TRX); /* TRX mode */ - conopts |= (1 << STT); /* start condition */ - - if (dostop != 0) { - conopts |= (1 << STP); /* stop condition */ - } - - omap_i2c_write_status(0x7fff); - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_CON, conopts); + 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); for (i = 0; i < buflen; i++) { /* Ready to write? */ - r = omap_i2c_poll(pollmask | errmask); + r = rpi_i2c_poll(pollmask | errmask); if ((r & errmask) != 0) { log_warn(&log, "Write Error! Status=%x\n", r); return EIO; @@ -752,32 +537,19 @@ omap_i2c_write(i2c_addr_t addr, const uint8_t * buf, size_t buflen, int dostop) return EBUSY; } - write16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_DATA, buf[i]); + write32(rpi_i2c_bus->mapped_addr + rpi_i2c_bus->regs->FIFO, buf[i]); /* clear the write ready flag */ - omap_i2c_write_status(pollmask); + rpi_i2c_write_status(BCM283X_STATUS_DONE | errmask); } - r = omap_i2c_read_status(); - if ((r & (1 << NACK)) != 0) { - log_warn(&log, "NACK\n"); - return EIO; - } - - /* Wait for operation to complete */ - pollmask = (1<mapped_addr + rpi_i2c_bus->regs->CTRL, BCM283X_CTRL_CFIFO, BCM283X_CTRL_CFIFO); return 0; } int -omap_interface_setup(int (**process) (minix_i2c_ioctl_exec_t * ioctl_exec), +rpi_interface_setup(int (**process) (minix_i2c_ioctl_exec_t * ioctl_exec), int i2c_bus_id) { int r; @@ -788,37 +560,34 @@ omap_interface_setup(int (**process) (minix_i2c_ioctl_exec_t * ioctl_exec), /* Fill in the function pointer */ - *process = omap_i2c_process; + *process = rpi_i2c_process; /* Select the correct i2c definition for this SoC */ - if (BOARD_IS_BBXM(machine.board_id)){ - omap_i2c_buses = dm37xx_i2c_buses; - omap_i2c_nbuses = DM37XX_OMAP_NBUSES; - } else if (BOARD_IS_BB(machine.board_id)){ - omap_i2c_buses = am335x_i2c_buses; - omap_i2c_nbuses = AM335X_OMAP_NBUSES; + if (BOARD_IS_RPI_2_B(machine.board_id) || BOARD_IS_RPI_3_B(machine.board_id)){ + rpi_i2c_buses = bcm283x_i2c_buses; + rpi_i2c_nbuses = BCM283X_rpi_NBUSES; } else { return EINVAL; } - if (i2c_bus_id < 0 || i2c_bus_id >= omap_i2c_nbuses) { + if (i2c_bus_id < 0 || i2c_bus_id >= rpi_i2c_nbuses) { return EINVAL; } /* select the bus to operate on */ - omap_i2c_bus = &omap_i2c_buses[i2c_bus_id]; + rpi_i2c_bus = &rpi_i2c_buses[i2c_bus_id]; /* Configure Pins */ - omap_i2c_padconf(i2c_bus_id); + rpi_i2c_padconf(i2c_bus_id); /* * Map I2C Registers */ /* Configure memory access */ - mr.mr_base = omap_i2c_bus->mr_base; /* start addr */ - mr.mr_limit = mr.mr_base + omap_i2c_bus->mr_size; /* end addr */ + mr.mr_base = rpi_i2c_bus->mr_base; /* start addr */ + mr.mr_limit = mr.mr_base + rpi_i2c_bus->mr_size; /* end addr */ /* ask for privileges to access the I2C memory range */ if (sys_privctl(SELF, SYS_PRIV_ADD_MEM, &mr) != OK) { @@ -826,51 +595,25 @@ omap_interface_setup(int (**process) (minix_i2c_ioctl_exec_t * ioctl_exec), } /* map the memory into this process */ - omap_i2c_bus->mapped_addr = (vir_bytes) vm_map_phys(SELF, - (void *) omap_i2c_bus->mr_base, omap_i2c_bus->mr_size); + rpi_i2c_bus->mapped_addr = (vir_bytes) vm_map_phys(SELF, + (void *) rpi_i2c_bus->mr_base, rpi_i2c_bus->mr_size); - if (omap_i2c_bus->mapped_addr == (vir_bytes) MAP_FAILED) { + if (rpi_i2c_bus->mapped_addr == (vir_bytes) MAP_FAILED) { panic("Unable to map i2c registers"); } /* Enable Clocks */ - omap_i2c_clkconf(i2c_bus_id); + rpi_i2c_clkconf(i2c_bus_id); /* Perform a soft reset of the I2C module to ensure a fresh start */ - r = omap_i2c_soft_reset(); + r = rpi_i2c_soft_reset(); if (r != OK) { /* module didn't come back up :( */ return r; } /* Bring up I2C module */ - omap_i2c_bus_init(); - - /* Get I2C Revision */ - if (omap_i2c_bus->bus_type == AM335X_I2C_BUS) { - /* I2C_REVLO revision: major (bits 10-8), minor (bits 5-0) */ - i2c_rev = read16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_REVNB_LO); - major = (i2c_rev >> 8) & 0x07; - minor = i2c_rev & 0x3f; - - } else if (omap_i2c_bus->bus_type == DM37XX_I2C_BUS) { - /* I2C_REV revision: major (bits 7-4), minor (bits 3-0) */ - i2c_rev = read16(omap_i2c_bus->mapped_addr + omap_i2c_bus->regs->I2C_REV); - major = (i2c_rev >> 4) & 0x0f; - minor = i2c_rev & 0x0f; - } else { - panic("Don't know how to read i2c revision."); - } - - if (major != omap_i2c_bus->major || minor != omap_i2c_bus->minor) { - log_warn(&log, "Unrecognized value in I2C_REV register.\n"); - log_warn(&log, "Read: 0x%x.0x%x | Expected: 0x%x.0x%x\n", - major, minor, omap_i2c_bus->major, omap_i2c_bus->minor); - } - - /* display i2c revision information for debugging purposes */ - log_debug(&log, "i2c_%d: I2C rev 0x%x.0x%x\n", (i2c_bus_id + 1), - major, minor); + rpi_i2c_bus_init(); return OK; } diff --git a/minix/drivers/bus/i2c/arch/earm/rpi/rpi_i2c.h b/minix/drivers/bus/i2c/arch/earm/rpi/rpi_i2c.h index 70e56b432..7052e3935 100644 --- a/minix/drivers/bus/i2c/arch/earm/rpi/rpi_i2c.h +++ b/minix/drivers/bus/i2c/arch/earm/rpi/rpi_i2c.h @@ -5,6 +5,6 @@ #include #include "rpi_i2c_registers.h" -int omap_interface_setup(int (**process)(minix_i2c_ioctl_exec_t *ioctl_exec), int i2c_bus_id); +int rpi_interface_setup(int (**process)(minix_i2c_ioctl_exec_t *ioctl_exec), int i2c_bus_id); #endif /* _RPI_I2C_H */ 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 fa4be6f16..4cea16bcc 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 @@ -1,152 +1,84 @@ #ifndef _RPI_I2C_REGISTERS_H #define _RPI_I2C_REGISTERS_H -/* I2C Addresses for am335x (BeagleBone White / BeagleBone Black) */ +/* I2C Addresses for bcm2835 */ /* IRQ Numbers */ -#define AM335X_I2C0_IRQ 70 -#define AM335X_I2C1_IRQ 71 -#define AM335X_I2C2_IRQ 30 +#define BCM283X_I2C0_IRQ 47 /* Base Addresses */ -#define AM335X_I2C0_BASE 0x44e0b000 -#define AM335X_I2C1_BASE 0x4802a000 -#define AM335X_I2C2_BASE 0x4819c000 +#define BCM283X_I2C0_BASE 0x3f205000 +#define BCM283X_I2C1_BASE 0x3f804000 /* Size of I2C Register Address Range */ -#define AM335X_I2C0_SIZE 0x1000 -#define AM335X_I2C1_SIZE 0x1000 -#define AM335X_I2C2_SIZE 0x1000 +#define BCM283X_I2C0_SIZE 0x1000 +#define BCM283X_I2C1_SIZE 0x1000 /* Register Offsets */ -#define AM335X_I2C_REVNB_LO 0x00 -#define AM335X_I2C_REVNB_HI 0x04 -#define AM335X_I2C_SYSC 0x10 -#define AM335X_I2C_IRQSTATUS_RAW 0x24 -#define AM335X_I2C_IRQSTATUS 0x28 -#define AM335X_I2C_IRQENABLE_SET 0x2c -#define AM335X_I2C_IRQENABLE_CLR 0x30 -#define AM335X_I2C_WE 0x34 -#define AM335X_I2C_DMARXENABLE_SET 0x38 -#define AM335X_I2C_DMATXENABLE_SET 0x3c -#define AM335X_I2C_DMARXENABLE_CLR 0x40 -#define AM335X_I2C_DMATXENABLE_CLR 0x44 -#define AM335X_I2C_DMARXWAKE_EN 0x48 -#define AM335X_I2C_DMATXWAKE_EN 0x4c -#define AM335X_I2C_SYSS 0x90 -#define AM335X_I2C_BUF 0x94 -#define AM335X_I2C_CNT 0x98 -#define AM335X_I2C_DATA 0x9c -#define AM335X_I2C_CON 0xa4 -#define AM335X_I2C_OA 0xa8 -#define AM335X_I2C_SA 0xac -#define AM335X_I2C_PSC 0xb0 -#define AM335X_I2C_SCLL 0xb4 -#define AM335X_I2C_SCLH 0xb8 -#define AM335X_I2C_SYSTEST 0xbc -#define AM335X_I2C_BUFSTAT 0xc0 -#define AM335X_I2C_OA1 0xc4 -#define AM335X_I2C_OA2 0xc8 -#define AM335X_I2C_OA3 0xcc -#define AM335X_I2C_ACTOA 0xd0 -#define AM335X_I2C_SBLOCK 0xd4 +#define BCM283X_CTRL 0x00 +#define BCM283X_STATUS 0x04 +#define BCM283X_DLEN 0x08 +#define BCM283X_SL_ADDR 0x0C +#define BCM283X_FIFO 0x10 +#define BCM283X_DIV 0x14 +#define BCM283X_DEL 0x18 +#define BCM283X_CLKT 0x1c /* Constants */ -#define AM335X_FUNCTIONAL_CLOCK 96000000 /* 96 MHz */ -#define AM335X_MODULE_CLOCK 12000000 /* 12 MHz */ +#define BCM283X_FUNCTIONAL_CLOCK 96000000 /* 96 MHz */ +#define BCM283X_MODULE_CLOCK 12000000 /* 12 MHz */ -/* I2C_REV value found on the BeagleBone / BeagleBone Black */ -#define AM335X_REV_MAJOR 0x00 -#define AM335X_REV_MINOR 0x0b - -/* I2C Addresses for dm37xx (BeagleBoard-xM) */ - -/* IRQ Numbers */ -#define DM37XX_I2C0_IRQ 56 -#define DM37XX_I2C1_IRQ 57 -#define DM37XX_I2C2_IRQ 61 - -/* Base Addresses */ -#define DM37XX_I2C0_BASE 0x48070000 -#define DM37XX_I2C1_BASE 0x48072000 -#define DM37XX_I2C2_BASE 0x48060000 - -/* Size of I2C Register Address Range */ -#define DM37XX_I2C0_SIZE 0x1000 -#define DM37XX_I2C1_SIZE 0x1000 -#define DM37XX_I2C2_SIZE 0x1000 - -/* Register Offsets */ -#define DM37XX_I2C_REV 0x00 -#define DM37XX_I2C_IE 0x04 -#define DM37XX_I2C_STAT 0x08 -#define DM37XX_I2C_WE 0x0C -#define DM37XX_I2C_SYSS 0x10 -#define DM37XX_I2C_BUF 0x14 -#define DM37XX_I2C_CNT 0x18 -#define DM37XX_I2C_DATA 0x1c -#define DM37XX_I2C_SYSC 0x20 -#define DM37XX_I2C_CON 0x24 -#define DM37XX_I2C_OA0 0x28 -#define DM37XX_I2C_SA 0x2c -#define DM37XX_I2C_PSC 0x30 -#define DM37XX_I2C_SCLL 0x34 -#define DM37XX_I2C_SCLH 0x38 -#define DM37XX_I2C_SYSTEST 0x3c -#define DM37XX_I2C_BUFSTAT 0x40 -#define DM37XX_I2C_OA1 0x44 -#define DM37XX_I2C_OA2 0x48 -#define DM37XX_I2C_OA3 0x4c -#define DM37XX_I2C_ACTOA 0x50 -#define DM37XX_I2C_SBLOCK 0x54 - -/* Constants */ -#define DM37XX_FUNCTIONAL_CLOCK 96000000 /* 96 MHz */ -#define DM37XX_MODULE_CLOCK 19200000 /* 19.2 MHz */ - -#define DM37XX_REV_MAJOR 0x04 -#define DM37XX_REV_MINOR 0x00 +#define BCM283X_I2C_CDIV_MIN 0x0002 +#define BCM283X_I2C_CDIV_MAX 0xFFFE /* Shared Values */ -#define BUS_SPEED_100KHz 100000 /* 100 KHz */ -#define BUS_SPEED_400KHz 400000 /* 400 KHz */ -#define I2C_OWN_ADDRESS 0x01 +#define BUS_SPEED_100KHz 100000 /* 100 KHz */ +#define BUS_SPEED_400KHz 400000 /* 400 KHz */ +#define I2C_OWN_ADDRESS 0x01 /* Masks */ #define MAX_I2C_SA_MASK (0x3ff) /* Highest 10 bit address -- 9..0 */ +#define SL_ADDR_MASK (0x78) /* Mask for slave address (the last two bits + are the most significant of the addr)*/ /* Bit Offsets within Registers (only those used are listed) */ -/* Same offsets for both dm37xx and am335x */ +#define I2C_EN 15 +#define MST 10 +#define TRX 9 +#define XSA 8 +#define STP 1 +#define STT 0 -#define I2C_EN 15 /* I2C_CON */ -#define MST 10 /* I2C_CON */ -#define TRX 9 /* I2C_CON */ -#define XSA 8 /* I2C_CON */ -#define STP 1 /* I2C_CON */ -#define STT 0 /* I2C_CON */ +#define CLKACTIVITY_S 9 +#define CLKACTIVITY_I 8 +#define SMART_WAKE_UP 4 +#define NO_IDLE_MODE 3 +#define SRST 1 +#define AUTOIDLE 0 -#define CLKACTIVITY_S 9 /* I2C_SYSC */ -#define CLKACTIVITY_I 8 /* I2C_SYSC */ -#define SMART_WAKE_UP 4 /* I2C_SYSC */ -#define NO_IDLE_MODE 3 /* I2C_SYSC */ -#define SRST 1 /* I2C_SYSC */ -#define AUTOIDLE 0 /* I2C_SYSC */ +#define RDONE 0 -#define RDONE 0 /* I2C_SYSS */ +#define RXFIFO_CLR 14 +#define TXFIFO_CLR 6 -#define RXFIFO_CLR 14 /* I2C_BUF */ -#define TXFIFO_CLR 6 /* I2C_BUF */ +#define BCM283X_STATUS_TA 0x00 +#define BCM283X_STATUS_DONE 0x01 +#define BCM283X_STATUS_TXD 0x10 +#define BCM283X_STATUS_RXD 0x20 +#define BCM283X_STATUS_TXE 0x40 +#define BCM283X_STATUS_RXF 0x80 +#define BCM283X_STATUS_ERR 0x100 +#define BCM283X_STATUS_CLKT 0x200 -#define BB 12 /* I2C_IRQSTATUS / I2C_STAT / I2C_IRQENABLE_SET / I2C_IE */ -#define ROVR 11 /* I2C_IRQSTATUS / I2C_STAT / I2C_IRQENABLE_SET / I2C_IE */ -#define AERR 7 /* I2C_IRQSTATUS / I2C_STAT / I2C_IRQENABLE_SET / I2C_IE */ -#define XRDY 4 /* I2C_IRQSTATUS / I2C_STAT / I2C_IRQENABLE_SET / I2C_IE */ -#define RRDY 3 /* I2C_IRQSTATUS / I2C_STAT / I2C_IRQENABLE_SET / I2C_IE */ -#define ARDY 2 /* I2C_IRQSTATUS / I2C_STAT / I2C_IRQENABLE_SET / I2C_IE */ -#define NACK 1 /* I2C_IRQSTATUS / I2C_STAT / I2C_IRQENABLE_SET / I2C_IE */ -#define AL 0 /* I2C_IRQSTATUS / I2C_STAT / I2C_IRQENABLE_SET / I2C_IE */ +#define BCM283X_CTRL_READ 0x00 +#define BCM283X_CTRL_ST 0x20 +#define BCM283X_CTRL_CFIFO 0x30 +#define BCM283X_CTRL_INTD 0x100 +#define BCM283X_CTRL_INTT 0x200 +#define BCM283X_CTRL_INTR 0x400 +#define BCM283X_CTRL_I2C_EN 0x8000 #endif /* _RPI_I2C_REGISTERS_H */ diff --git a/minix/drivers/bus/i2c/i2c.c b/minix/drivers/bus/i2c/i2c.c index 58371c7b1..d28c70d6c 100644 --- a/minix/drivers/bus/i2c/i2c.c +++ b/minix/drivers/bus/i2c/i2c.c @@ -438,6 +438,12 @@ sef_cb_init(int type, sef_init_info_t * UNUSED(info)) if (r != OK) { return r; } + } else if (BOARD_IS_RPI_2_B(machine.board_id) || BOARD_IS_RPI_3_B(machine.board_id)){ + /* Set callback and initialize the bus */ + r = rpi_interface_setup(&process, i2c_bus_id); + if (r != OK) { + return r; + } } else { return ENODEV; } diff --git a/minix/drivers/bus/i2c/i2c.conf b/minix/drivers/bus/i2c/i2c.conf new file mode 100644 index 000000000..99dc1f925 --- /dev/null +++ b/minix/drivers/bus/i2c/i2c.conf @@ -0,0 +1,21 @@ +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; +}; diff --git a/releasetools/arm_sdimage_rpi.sh b/releasetools/arm_sdimage_rpi.sh index d05a2d580..93283f43e 100755 --- a/releasetools/arm_sdimage_rpi.sh +++ b/releasetools/arm_sdimage_rpi.sh @@ -121,6 +121,8 @@ device_tree=bcm2709-rpi-2-b.dtb [all] device_tree_address=0x100 kernel=minix_rpi.bin + +dtparam=i2c_arm=on EOF ${CROSS_TOOLS}/nbmakefs -t msdos -s $FAT_SIZE -O $FAT_START -o "F=32,c=1" ${IMG} ${ROOT_DIR} >/dev/null