diff options
Diffstat (limited to 'chip/stm32/i2c-stm32f4.c')
-rw-r--r-- | chip/stm32/i2c-stm32f4.c | 182 |
1 files changed, 91 insertions, 91 deletions
diff --git a/chip/stm32/i2c-stm32f4.c b/chip/stm32/i2c-stm32f4.c index bce81b14c9..9f4d799912 100644 --- a/chip/stm32/i2c-stm32f4.c +++ b/chip/stm32/i2c-stm32f4.c @@ -1,9 +1,10 @@ -/* Copyright 2016 The Chromium OS Authors. All rights reserved. +/* Copyright 2016 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +#include "builtin/assert.h" #include "chipset.h" #include "clock.h" #include "common.h" @@ -20,12 +21,12 @@ /* Console output macros */ #define CPUTS(outstr) cputs(CC_I2C, outstr) -#define CPRINTS(format, args...) cprints(CC_I2C, format, ## args) +#define CPRINTS(format, args...) cprints(CC_I2C, format, ##args) #define I2C_ERROR_FAILED_START EC_ERROR_INTERNAL_FIRST /* Transmit timeout in microseconds */ -#define I2C_TX_TIMEOUT_CONTROLLER (10 * MSEC) +#define I2C_TX_TIMEOUT_CONTROLLER (10 * MSEC) #ifdef CONFIG_HOSTCMD_I2C_ADDR_FLAGS #if (I2C_PORT_EC == STM32_I2C1_PORT) @@ -43,36 +44,36 @@ * two sets of functions to handle this for stm32f4. In stm32f446, we * only have one FMP block so we'll hardcode its port number. */ -#define STM32F4_FMPI2C_PORT 3 +#define STM32F4_FMPI2C_PORT 3 static const __unused struct dma_option dma_tx_option[I2C_PORT_COUNT] = { - {STM32_DMAC_I2C1_TX, (void *)&STM32_I2C_DR(STM32_I2C1_PORT), - STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | - STM32_DMA_CCR_CHANNEL(STM32_I2C1_TX_REQ_CH)}, - {STM32_DMAC_I2C2_TX, (void *)&STM32_I2C_DR(STM32_I2C2_PORT), - STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | - STM32_DMA_CCR_CHANNEL(STM32_I2C2_TX_REQ_CH)}, - {STM32_DMAC_I2C3_TX, (void *)&STM32_I2C_DR(STM32_I2C3_PORT), - STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | - STM32_DMA_CCR_CHANNEL(STM32_I2C3_TX_REQ_CH)}, - {STM32_DMAC_FMPI2C4_TX, (void *)&STM32_FMPI2C_TXDR(STM32_FMPI2C4_PORT), - STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | - STM32_DMA_CCR_CHANNEL(STM32_FMPI2C4_TX_REQ_CH)}, + { STM32_DMAC_I2C1_TX, (void *)&STM32_I2C_DR(STM32_I2C1_PORT), + STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | + STM32_DMA_CCR_CHANNEL(STM32_I2C1_TX_REQ_CH) }, + { STM32_DMAC_I2C2_TX, (void *)&STM32_I2C_DR(STM32_I2C2_PORT), + STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | + STM32_DMA_CCR_CHANNEL(STM32_I2C2_TX_REQ_CH) }, + { STM32_DMAC_I2C3_TX, (void *)&STM32_I2C_DR(STM32_I2C3_PORT), + STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | + STM32_DMA_CCR_CHANNEL(STM32_I2C3_TX_REQ_CH) }, + { STM32_DMAC_FMPI2C4_TX, (void *)&STM32_FMPI2C_TXDR(STM32_FMPI2C4_PORT), + STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | + STM32_DMA_CCR_CHANNEL(STM32_FMPI2C4_TX_REQ_CH) }, }; static const struct dma_option dma_rx_option[I2C_PORT_COUNT] = { - {STM32_DMAC_I2C1_RX, (void *)&STM32_I2C_DR(STM32_I2C1_PORT), - STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | - STM32_DMA_CCR_CHANNEL(STM32_I2C1_RX_REQ_CH)}, - {STM32_DMAC_I2C2_RX, (void *)&STM32_I2C_DR(STM32_I2C2_PORT), - STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | - STM32_DMA_CCR_CHANNEL(STM32_I2C2_RX_REQ_CH)}, - {STM32_DMAC_I2C3_RX, (void *)&STM32_I2C_DR(STM32_I2C3_PORT), - STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | - STM32_DMA_CCR_CHANNEL(STM32_I2C3_RX_REQ_CH)}, - {STM32_DMAC_FMPI2C4_RX, (void *)&STM32_FMPI2C_RXDR(STM32_FMPI2C4_PORT), - STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | - STM32_DMA_CCR_CHANNEL(STM32_FMPI2C4_RX_REQ_CH)}, + { STM32_DMAC_I2C1_RX, (void *)&STM32_I2C_DR(STM32_I2C1_PORT), + STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | + STM32_DMA_CCR_CHANNEL(STM32_I2C1_RX_REQ_CH) }, + { STM32_DMAC_I2C2_RX, (void *)&STM32_I2C_DR(STM32_I2C2_PORT), + STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | + STM32_DMA_CCR_CHANNEL(STM32_I2C2_RX_REQ_CH) }, + { STM32_DMAC_I2C3_RX, (void *)&STM32_I2C_DR(STM32_I2C3_PORT), + STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | + STM32_DMA_CCR_CHANNEL(STM32_I2C3_RX_REQ_CH) }, + { STM32_DMAC_FMPI2C4_RX, (void *)&STM32_FMPI2C_RXDR(STM32_FMPI2C4_PORT), + STM32_DMA_CCR_MSIZE_8_BIT | STM32_DMA_CCR_PSIZE_8_BIT | + STM32_DMA_CCR_CHANNEL(STM32_FMPI2C4_RX_REQ_CH) }, }; /* Callback for ISR to wake task on DMA complete. */ @@ -164,7 +165,6 @@ static int wait_sr1(int port, int mask) return wait_sr1_poll(port, mask, SET, 100); } - /** * Send a start condition and peripheral address on the specified port. * @@ -232,8 +232,8 @@ static int wait_fmpi2c_isr_poll(int port, int mask, int val, int poll) int isr = STM32_FMPI2C_ISR(port); /* Check for errors */ - if (isr & (FMPI2C_ISR_ARLO | FMPI2C_ISR_BERR | - FMPI2C_ISR_NACKF)) { + if (isr & + (FMPI2C_ISR_ARLO | FMPI2C_ISR_BERR | FMPI2C_ISR_NACKF)) { return EC_ERROR_UNKNOWN; } @@ -265,19 +265,18 @@ static int wait_fmpi2c_isr(int port, int mask) * * @return Non-zero if error. */ -static int send_fmpi2c_start(const int port, const uint16_t addr_8bit, - int size, int is_read) +static int send_fmpi2c_start(const int port, const uint16_t addr_8bit, int size, + int is_read) { uint32_t reg; /* Send start bit */ reg = STM32_FMPI2C_CR2(port); reg &= ~(FMPI2C_CR2_SADD_MASK | FMPI2C_CR2_SIZE_MASK | - FMPI2C_CR2_RELOAD | FMPI2C_CR2_AUTOEND | - FMPI2C_CR2_RD_WRN | FMPI2C_CR2_START | FMPI2C_CR2_STOP); - reg |= FMPI2C_CR2_START | FMPI2C_CR2_AUTOEND | - addr_8bit | FMPI2C_CR2_SIZE(size) | - (is_read ? FMPI2C_CR2_RD_WRN : 0); + FMPI2C_CR2_RELOAD | FMPI2C_CR2_AUTOEND | FMPI2C_CR2_RD_WRN | + FMPI2C_CR2_START | FMPI2C_CR2_STOP); + reg |= FMPI2C_CR2_START | FMPI2C_CR2_AUTOEND | addr_8bit | + FMPI2C_CR2_SIZE(size) | (is_read ? FMPI2C_CR2_RD_WRN : 0); STM32_FMPI2C_CR2(port) = reg; return EC_SUCCESS; @@ -300,17 +299,17 @@ static void i2c_set_freq_port(const struct i2c_port_t *p) /* FMP I2C clock set. */ STM32_FMPI2C_CR1(port) &= ~FMPI2C_CR1_PE; - prescalar = (freq / (p->kbps * 1000 * - (0x12 + 1 + 0xe + 1 + 1))) - 1; + prescalar = + (freq / (p->kbps * 1000 * (0x12 + 1 + 0xe + 1 + 1))) - + 1; actual = freq / ((prescalar + 1) * (0x12 + 1 + 0xe + 1 + 1)); - reg = FMPI2C_TIMINGR_SCLL(0x12) | - FMPI2C_TIMINGR_SCLH(0xe) | - FMPI2C_TIMINGR_PRESC(prescalar); + reg = FMPI2C_TIMINGR_SCLL(0x12) | FMPI2C_TIMINGR_SCLH(0xe) | + FMPI2C_TIMINGR_PRESC(prescalar); STM32_FMPI2C_TIMINGR(port) = reg; - CPRINTS("port %d target %d, pre %d, act %d, reg 0x%08x", - port, p->kbps, prescalar, actual, reg); + CPRINTS("port %d target %d, pre %d, act %d, reg 0x%08x", port, + p->kbps, prescalar, actual, reg); STM32_FMPI2C_CR1(port) |= FMPI2C_CR1_PE; udelay(10); @@ -323,9 +322,9 @@ static void i2c_set_freq_port(const struct i2c_port_t *p) if (p->kbps > 100) { STM32_I2C_CCR(port) = freq / (2 * MSEC * p->kbps); } else { - STM32_I2C_CCR(port) = STM32_I2C_CCR_FM - | STM32_I2C_CCR_DUTY - | (freq / (16 + 9 * MSEC * p->kbps)); + STM32_I2C_CCR(port) = + STM32_I2C_CCR_FM | STM32_I2C_CCR_DUTY | + (freq / (16 + 9 * MSEC * p->kbps)); } STM32_I2C_CR2(port) = freq / SECOND; STM32_I2C_TRISE(port) = freq / SECOND + 1; @@ -384,10 +383,10 @@ static void fmpi2c_clear_regs(int port) STM32_FMPI2C_ICR(port) = 0xffffffff; /* Clear start, stop, NACK, etc. bits to get us in a known state */ - STM32_FMPI2C_CR2(port) &= ~(FMPI2C_CR2_START | FMPI2C_CR2_STOP | - FMPI2C_CR2_RD_WRN | FMPI2C_CR2_NACK | - FMPI2C_CR2_AUTOEND | - FMPI2C_CR2_SADD_MASK | FMPI2C_CR2_SIZE_MASK); + STM32_FMPI2C_CR2(port) &= + ~(FMPI2C_CR2_START | FMPI2C_CR2_STOP | FMPI2C_CR2_RD_WRN | + FMPI2C_CR2_NACK | FMPI2C_CR2_AUTOEND | FMPI2C_CR2_SADD_MASK | + FMPI2C_CR2_SIZE_MASK); } /** @@ -404,8 +403,8 @@ static void fmpi2c_clear_regs(int port) * @return EC_SUCCESS on success. */ static int chip_fmpi2c_xfer(const int port, const uint16_t addr_8bit, - const uint8_t *out, int out_bytes, - uint8_t *in, int in_bytes, int flags) + const uint8_t *out, int out_bytes, uint8_t *in, + int in_bytes, int flags) { int started = (flags & I2C_XFER_START) ? 0 : 1; int rv = EC_SUCCESS; @@ -424,8 +423,8 @@ static int chip_fmpi2c_xfer(const int port, const uint16_t addr_8bit, /* No out bytes and no in bytes means just check for active */ if (out_bytes || !in_bytes) { - rv = send_fmpi2c_start( - port, addr_8bit, out_bytes, FMPI2C_WRITE); + rv = send_fmpi2c_start(port, addr_8bit, out_bytes, + FMPI2C_WRITE); if (rv) goto xfer_exit; @@ -450,8 +449,8 @@ static int chip_fmpi2c_xfer(const int port, const uint16_t addr_8bit, dma_start_rx(dma, in_bytes, in); i2c_dma_enable_tc_interrupt(dma->channel, port); - rv_start = send_fmpi2c_start( - port, addr_8bit, in_bytes, FMPI2C_READ); + rv_start = send_fmpi2c_start(port, addr_8bit, in_bytes, + FMPI2C_READ); if (rv_start) goto xfer_exit; @@ -460,9 +459,8 @@ static int chip_fmpi2c_xfer(const int port, const uint16_t addr_8bit, goto xfer_exit; STM32_FMPI2C_CR1(port) |= FMPI2C_CR1_RXDMAEN; - rv = task_wait_event_mask( - TASK_EVENT_I2C_COMPLETION(port), - DMA_TRANSFER_TIMEOUT_US); + rv = task_wait_event_mask(TASK_EVENT_I2C_COMPLETION(port), + DMA_TRANSFER_TIMEOUT_US); if (rv & TASK_EVENT_I2C_COMPLETION(port)) rv = EC_SUCCESS; else @@ -478,7 +476,7 @@ static int chip_fmpi2c_xfer(const int port, const uint16_t addr_8bit, STM32_FMPI2C_CR1(port) &= ~FMPI2C_CR1_RXDMAEN; } - xfer_exit: +xfer_exit: /* On error, queue a stop condition */ if (rv) { flags |= I2C_XFER_STOP; @@ -492,7 +490,8 @@ static int chip_fmpi2c_xfer(const int port, const uint16_t addr_8bit, const struct i2c_port_t *p; CPRINTS("chip_fmpi2c_xfer start error; " - "unwedging and resetting i2c %d", port); + "unwedging and resetting i2c %d", + port); p = find_port(port); i2c_unwedge(port); @@ -522,7 +521,6 @@ static int chip_fmpi2c_xfer(const int port, const uint16_t addr_8bit, return rv; } - /** * Clear status regs on the specified I2C port. * @@ -539,10 +537,8 @@ static void i2c_clear_regs(int port) STM32_I2C_SR1(port) = 0; /* Clear start, stop, POS, ACK bits to get us in a known state */ - STM32_I2C_CR1(port) &= ~(STM32_I2C_CR1_START | - STM32_I2C_CR1_STOP | - STM32_I2C_CR1_POS | - STM32_I2C_CR1_ACK); + STM32_I2C_CR1(port) &= ~(STM32_I2C_CR1_START | STM32_I2C_CR1_STOP | + STM32_I2C_CR1_POS | STM32_I2C_CR1_ACK); } /***************************************************************************** @@ -550,9 +546,8 @@ static void i2c_clear_regs(int port) */ /* Perform an i2c transaction. */ -int chip_i2c_xfer(const int port, const uint16_t addr_flags, - const uint8_t *out, int out_bytes, - uint8_t *in, int in_bytes, int flags) +int chip_i2c_xfer(const int port, const uint16_t addr_flags, const uint8_t *out, + int out_bytes, uint8_t *in, int in_bytes, int flags) { int addr_8bit = I2C_STRIP_FLAGS(addr_flags) << 1; int started = (flags & I2C_XFER_START) ? 0 : 1; @@ -565,9 +560,8 @@ int chip_i2c_xfer(const int port, const uint16_t addr_flags, ASSERT(!started); if (p->port == STM32F4_FMPI2C_PORT) { - return chip_fmpi2c_xfer(port, addr_8bit, - out, out_bytes, - in, in_bytes, flags); + return chip_fmpi2c_xfer(port, addr_8bit, out, out_bytes, in, + in_bytes, flags); } i2c_clear_regs(port); @@ -644,7 +638,7 @@ int chip_i2c_xfer(const int port, const uint16_t addr_flags, STM32_I2C_CR2(port) &= ~STM32_I2C_CR2_DMAEN; } - xfer_exit: +xfer_exit: /* On error, queue a stop condition */ if (rv) { flags |= I2C_XFER_STOP; @@ -658,7 +652,8 @@ int chip_i2c_xfer(const int port, const uint16_t addr_flags, const struct i2c_port_t *p; CPRINTS("chip_i2c_xfer start error; " - "unwedging and resetting i2c %d", port); + "unwedging and resetting i2c %d", + port); p = find_port(port); i2c_unwedge(port); @@ -711,7 +706,7 @@ int i2c_raw_get_sda(int port) int i2c_get_line_levels(int port) { return (i2c_raw_get_sda(port) ? I2C_LINE_SDA_HIGH : 0) | - (i2c_raw_get_scl(port) ? I2C_LINE_SCL_HIGH : 0); + (i2c_raw_get_scl(port) ? I2C_LINE_SCL_HIGH : 0); } /*****************************************************************************/ @@ -766,7 +761,7 @@ DECLARE_HOOK(HOOK_FREQ_CHANGE, i2c_freq_change_hook, HOOK_PRIO_DEFAULT); */ static uint8_t host_buffer_padded[I2C_MAX_HOST_PACKET_SIZE + 4 + CONFIG_I2C_EXTRA_PACKET_SIZE] __aligned(4); -static uint8_t * const host_buffer = host_buffer_padded + 2; +static uint8_t *const host_buffer = host_buffer_padded + 2; static uint8_t params_copy[I2C_MAX_HOST_PACKET_SIZE] __aligned(4); static int host_i2c_resp_port; static int tx_pending; @@ -879,14 +874,16 @@ static void i2c_event_handler(int port) /* Disable buffer interrupt */ STM32_I2C_CR2(port) &= ~STM32_I2C_CR2_ITBUFEN; /* Clear error status bits */ - STM32_I2C_SR1(port) &= ~(STM32_I2C_SR1_ARLO | - STM32_I2C_SR1_BERR); + STM32_I2C_SR1(port) &= + ~(STM32_I2C_SR1_ARLO | STM32_I2C_SR1_BERR); } /* Transfer matched our peripheral address */ if (i2c_sr1 & STM32_I2C_SR1_ADDR) { addr_8bit = ((i2c_sr2 & STM32_I2C_SR2_DUALF) ? - STM32_I2C_OAR2(port) : STM32_I2C_OAR1(port)) & 0xfe; + STM32_I2C_OAR2(port) : + STM32_I2C_OAR1(port)) & + 0xfe; if (i2c_sr2 & STM32_I2C_SR2_TRA) { /* Transmitter peripheral */ i2c_sr1 |= STM32_I2C_SR1_TXE; @@ -957,7 +954,7 @@ static void i2c_event_handler(int port) #ifdef CONFIG_BOARD_I2C_ADDR_FLAGS if (rx_pending && (addr_8b >> 1) == - I2C_STRIP_FLAGS(CONFIG_BOARD_I2C_ADDR_FLAGS)) + I2C_STRIP_FLAGS(CONFIG_BOARD_I2C_ADDR_FLAGS)) i2c_process_board_command(0, addr_8bit, buf_idx); #endif rx_pending = 0; @@ -977,12 +974,14 @@ static void i2c_event_handler(int port) if (!(i2c_cr1 & STM32_I2C_CR1_PE)) STM32_I2C_CR1(port) |= STM32_I2C_CR1_PE; } -static void i2c_event_interrupt(void) { i2c_event_handler(I2C_PORT_EC); } +static void i2c_event_interrupt(void) +{ + i2c_event_handler(I2C_PORT_EC); +} DECLARE_IRQ(IRQ_PERIPHERAL_EV, i2c_event_interrupt, 2); DECLARE_IRQ(IRQ_PERIPHERAL_ER, i2c_event_interrupt, 2); #endif - /* Init all available i2c ports */ void i2c_init(void) { @@ -992,19 +991,20 @@ void i2c_init(void) for (i = 0; i < i2c_ports_used; i++, p++) i2c_init_port(p); - #ifdef CONFIG_HOSTCMD_I2C_ADDR_FLAGS /* Enable ACK */ STM32_I2C_CR1(I2C_PORT_EC) |= STM32_I2C_CR1_ACK; /* Enable interrupts */ - STM32_I2C_CR2(I2C_PORT_EC) |= STM32_I2C_CR2_ITEVTEN - | STM32_I2C_CR2_ITERREN; + STM32_I2C_CR2(I2C_PORT_EC) |= STM32_I2C_CR2_ITEVTEN | + STM32_I2C_CR2_ITERREN; /* Setup host command peripheral */ - STM32_I2C_OAR1(I2C_PORT_EC) = STM32_I2C_OAR1_B14 - | (I2C_STRIP_ADDR(CONFIG_HOSTCMD_I2C_ADDR_FLAGS) << 1); + STM32_I2C_OAR1(I2C_PORT_EC) = + STM32_I2C_OAR1_B14 | + (I2C_STRIP_ADDR(CONFIG_HOSTCMD_I2C_ADDR_FLAGS) << 1); #ifdef CONFIG_BOARD_I2C_ADDR_FLAGS - STM32_I2C_OAR2(I2C_PORT_EC) = STM32_I2C_OAR2_ENDUAL - | (I2C_STRIP_FLAGS(CONFIG_BOARD_I2C_ADDR_FLAGS) << 1); + STM32_I2C_OAR2(I2C_PORT_EC) = + STM32_I2C_OAR2_ENDUAL | + (I2C_STRIP_FLAGS(CONFIG_BOARD_I2C_ADDR_FLAGS) << 1); #endif task_enable_irq(IRQ_PERIPHERAL_EV); task_enable_irq(IRQ_PERIPHERAL_ER); |