summaryrefslogtreecommitdiff
path: root/chip/it83xx/i2c_peripheral.c
diff options
context:
space:
mode:
Diffstat (limited to 'chip/it83xx/i2c_peripheral.c')
-rw-r--r--chip/it83xx/i2c_peripheral.c344
1 files changed, 0 insertions, 344 deletions
diff --git a/chip/it83xx/i2c_peripheral.c b/chip/it83xx/i2c_peripheral.c
deleted file mode 100644
index 91eb2c1dfb..0000000000
--- a/chip/it83xx/i2c_peripheral.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/* Copyright 2019 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-/* I2C module for Chrome EC */
-#include "clock.h"
-#include "compile_time_macros.h"
-#include "console.h"
-#include "gpio.h"
-#include "hooks.h"
-#include "i2c_peripheral.h"
-#include "registers.h"
-#include <stddef.h>
-#include <string.h>
-#include "task.h"
-
-/* Console output macros */
-#define CPRINTS(format, args...) cprints(CC_I2C, format, ## args)
-
-/* The size must be a power of 2 */
-#define I2C_MAX_BUFFER_SIZE 0x100
-#define I2C_SIZE_MASK (I2C_MAX_BUFFER_SIZE - 1)
-
-#define I2C_READ_MAXFIFO_DATA 16
-#define I2C_ENHANCED_CH_INTERVAL 0x80
-
-/* Store controller to peripheral data of channel D, E, F by DMA */
-static uint8_t in_data[I2C_ENHANCED_PORT_COUNT][I2C_MAX_BUFFER_SIZE]
- __attribute__((section(".h2ram.pool.i2cslv")));
-/* Store peripheral to controller data of channel D, E, F by DMA */
-static uint8_t out_data[I2C_ENHANCED_PORT_COUNT][I2C_MAX_BUFFER_SIZE]
- __attribute__((section(".h2ram.pool.i2cslv")));
-/* Store read and write data of channel A by FIFO mode */
-static uint8_t pbuffer[I2C_MAX_BUFFER_SIZE];
-
-static uint32_t w_index;
-static uint32_t r_index;
-static int wr_done[I2C_ENHANCED_PORT_COUNT];
-
-void buffer_index_reset(void)
-{
- /* Reset write buffer index */
- w_index = 0;
- /* Reset read buffer index */
- r_index = 0;
-}
-
-/* Data structure to define I2C peripheral control configuration. */
-struct i2c_periph_ctrl_t {
- int irq; /* peripheral irq */
- /* offset from base 0x00F03500 register; -1 means unused. */
- int offset;
- enum clock_gate_offsets clock_gate;
- int dma_index;
-};
-
-/* I2C peripheral control */
-const struct i2c_periph_ctrl_t i2c_periph_ctrl[] = {
- [IT83XX_I2C_CH_A] = {.irq = IT83XX_IRQ_SMB_A, .offset = -1,
- .clock_gate = CGC_OFFSET_SMBA, .dma_index = -1},
- [IT83XX_I2C_CH_D] = {.irq = IT83XX_IRQ_SMB_D, .offset = 0x180,
- .clock_gate = CGC_OFFSET_SMBD, .dma_index = 0},
- [IT83XX_I2C_CH_E] = {.irq = IT83XX_IRQ_SMB_E, .offset = 0x0,
- .clock_gate = CGC_OFFSET_SMBE, .dma_index = 1},
- [IT83XX_I2C_CH_F] = {.irq = IT83XX_IRQ_SMB_F, .offset = 0x80,
- .clock_gate = CGC_OFFSET_SMBF, .dma_index = 2},
-};
-
-void i2c_peripheral_read_write_data(int port)
-{
- int periph_status, i;
-
- /* I2C peripheral channel A FIFO mode */
- if (port < I2C_STANDARD_PORT_COUNT) {
- int count;
-
- periph_status = IT83XX_SMB_SLSTA;
-
- /* bit0-4 : FIFO byte count */
- count = IT83XX_SMB_SFFSTA & 0x1F;
-
- /* Peripheral data register is waiting for read or write. */
- if (periph_status & IT83XX_SMB_SDS) {
- /* Controller to read data */
- if (periph_status & IT83XX_SMB_RCS) {
- for (i = 0; i < I2C_READ_MAXFIFO_DATA; i++)
- /* Return buffer data to controller */
- IT83XX_SMB_SLDA =
- pbuffer[(i + r_index) & I2C_SIZE_MASK];
-
- /* Index to next 16 bytes of read buffer */
- r_index += I2C_READ_MAXFIFO_DATA;
- }
- /* Controller to write data */
- else {
- /* FIFO Full */
- if (IT83XX_SMB_SFFSTA & IT83XX_SMB_SFFFULL) {
- for (i = 0; i < count; i++)
- /* Get data from controller to buffer */
- pbuffer[(w_index + i) &
- I2C_SIZE_MASK] = IT83XX_SMB_SLDA;
- }
-
- /* Index to next byte of write buffer */
- w_index += count;
- }
- }
- /* Stop condition, indicate stop condition detected. */
- if (periph_status & IT83XX_SMB_SPDS) {
- /* Read data less 16 bytes status */
- if (periph_status & IT83XX_SMB_RCS) {
- /* Disable FIFO mode to clear left count */
- IT83XX_SMB_SFFCTL &= ~IT83XX_SMB_SAFE;
-
- /* Peripheral A FIFO Enable */
- IT83XX_SMB_SFFCTL |= IT83XX_SMB_SAFE;
- }
- /* Controller to write data */
- else {
- for (i = 0; i < count; i++)
- /* Get data from controller to buffer */
- pbuffer[(i + w_index) &
- I2C_SIZE_MASK] = IT83XX_SMB_SLDA;
- }
-
- /* Reset read and write buffer index */
- buffer_index_reset();
- }
- /* Peripheral time status, timeout status occurs. */
- if (periph_status & IT83XX_SMB_STS) {
- /* Reset read and write buffer index */
- buffer_index_reset();
- }
-
- /* Write clear the peripheral status */
- IT83XX_SMB_SLSTA = periph_status;
- }
- /* Enhanced I2C peripheral channel D, E, F DMA mode */
- else {
- int ch, idx;
-
- /* Get enhanced i2c channel */
- ch = i2c_periph_ctrl[port].offset / I2C_ENHANCED_CH_INTERVAL;
-
- idx = i2c_periph_ctrl[port].dma_index;
-
- /* Interrupt pending */
- if (IT83XX_I2C_STR(ch) & IT83XX_I2C_INTPEND) {
-
- periph_status = IT83XX_I2C_IRQ_ST(ch);
-
- /* Controller to read data */
- if (periph_status & IT83XX_I2C_IDR_CLR) {
- /*
- * TODO(b:129360157): Return buffer data by
- * "out_data" array.
- * Ex: Write data to buffer from 0x00 to 0xFF
- */
- for (i = 0; i < I2C_MAX_BUFFER_SIZE; i++)
- out_data[idx][i] = i;
- }
- /* Controller to write data */
- if (periph_status & IT83XX_I2C_IDW_CLR) {
- /* Controller to write data finish flag */
- wr_done[idx] = 1;
- }
- /* Peripheral finish */
- if (periph_status & IT83XX_I2C_P_CLR) {
- if (wr_done[idx]) {
- /*
- * TODO(b:129360157): Handle controller write
- * data by "in_data" array.
- */
- CPRINTS("WData: %ph",
- HEX_BUF(in_data[idx],
- I2C_MAX_BUFFER_SIZE));
- wr_done[idx] = 0;
- }
- }
-
- /* Write clear the peripheral status */
- IT83XX_I2C_IRQ_ST(ch) = periph_status;
- }
-
- /* Hardware reset */
- IT83XX_I2C_CTR(ch) |= IT83XX_I2C_HALT;
- }
-}
-
-void i2c_periph_interrupt(int port)
-{
- /* Peripheral to read and write fifo data */
- i2c_peripheral_read_write_data(port);
-
- /* Clear the interrupt status */
- task_clear_pending_irq(i2c_periph_ctrl[port].irq);
-}
-
-void i2c_peripheral_enable(int port, uint8_t periph_addr)
-{
-
- clock_enable_peripheral(i2c_periph_ctrl[port].clock_gate, 0, 0);
-
- /* I2C peripheral channel A FIFO mode */
- if (port < I2C_STANDARD_PORT_COUNT) {
-
- /* This field defines the SMCLK0/1/2 clock/data low timeout. */
- IT83XX_SMB_25MS = I2C_CLK_LOW_TIMEOUT;
-
- /* bit0 : Peripheral A FIFO Enable */
- IT83XX_SMB_SFFCTL |= IT83XX_SMB_SAFE;
-
- /*
- * bit1 : Peripheral interrupt enable.
- * bit2 : SMCLK/SMDAT will be released if timeout.
- * bit3 : Peripheral detect STOP condition interrupt enable.
- */
- IT83XX_SMB_SICR = 0x0E;
-
- /* Peripheral address 1 */
- IT83XX_SMB_RESLADR = periph_addr;
-
- /* Write clear all peripheral status */
- IT83XX_SMB_SLSTA = 0xE7;
-
- /* bit5 : Enable the SMBus peripheral device */
- IT83XX_SMB_HOCTL2(port) |= IT83XX_SMB_SLVEN;
- }
- /* Enhanced I2C peripheral channel D, E, F DMA mode */
- else {
- int ch, idx;
- uint32_t in_data_addr, out_data_addr;
-
- /* Get enhanced i2c channel */
- ch = i2c_periph_ctrl[port].offset / I2C_ENHANCED_CH_INTERVAL;
-
- idx = i2c_periph_ctrl[port].dma_index;
-
- switch (port) {
- case IT83XX_I2C_CH_D:
- /* Enable I2C D channel */
- IT83XX_GPIO_GRC2 |= (1 << 5);
- break;
- case IT83XX_I2C_CH_E:
- /* Enable I2C E channel */
- IT83XX_GCTRL_PMER1 |= (1 << 0);
- break;
- case IT83XX_I2C_CH_F:
- /* Enable I2C F channel */
- IT83XX_GCTRL_PMER1 |= (1 << 1);
- break;
- }
-
- /* Software reset */
- IT83XX_I2C_DHTR(ch) |= (1 << 7);
- IT83XX_I2C_DHTR(ch) &= ~(1 << 7);
-
- /* This field defines the SMCLK3/4/5 clock/data low timeout. */
- IT83XX_I2C_TOR(ch) = I2C_CLK_LOW_TIMEOUT;
-
- /* Bit stretching */
- IT83XX_I2C_TOS(ch) |= IT83XX_I2C_CLK_STR;
-
- /* Peripheral address(8-bit)*/
- IT83XX_I2C_IDR(ch) = periph_addr << 1;
-
- /* I2C interrupt enable and set acknowledge */
- IT83XX_I2C_CTR(ch) = IT83XX_I2C_HALT |
- IT83XX_I2C_INTEN | IT83XX_I2C_ACK;
-
- /*
- * bit3 : Peripheral ID write flag
- * bit2 : Peripheral ID read flag
- * bit1 : Peripheral received data flag
- * bit0 : Peripheral finish
- */
- IT83XX_I2C_IRQ_ST(ch) = 0xFF;
-
- /* Clear read and write data buffer of DMA */
- memset(in_data[idx], 0, I2C_MAX_BUFFER_SIZE);
- memset(out_data[idx], 0, I2C_MAX_BUFFER_SIZE);
-
- if (IS_ENABLED(CHIP_ILM_DLM_ORDER)) {
- in_data_addr = (uint32_t)in_data[idx] & 0xffffff;
- out_data_addr = (uint32_t)out_data[idx] & 0xffffff;
- } else {
- in_data_addr = (uint32_t)in_data[idx] & 0xfff;
- out_data_addr = (uint32_t)out_data[idx] & 0xfff;
- }
-
- /* DMA write target address register */
- IT83XX_I2C_RAMHA(ch) = in_data_addr >> 8;
- IT83XX_I2C_RAMLA(ch) = in_data_addr;
-
- if (IS_ENABLED(CHIP_ILM_DLM_ORDER)) {
- /*
- * DMA write target address register
- * for high order byte
- */
- IT83XX_I2C_RAMH2A(ch) = in_data_addr >> 16;
- /*
- * DMA read target address register
- * for high order byte
- */
- IT83XX_I2C_CMD_ADDH2(ch) = out_data_addr >> 16;
- IT83XX_I2C_CMD_ADDH(ch) = out_data_addr >> 8;
- IT83XX_I2C_CMD_ADDL(ch) = out_data_addr;
- } else {
- /* DMA read target address register */
- IT83XX_I2C_RAMHA2(ch) = out_data_addr >> 8;
- IT83XX_I2C_RAMLA2(ch) = out_data_addr;
- }
-
- /* I2C module enable and command queue mode */
- IT83XX_I2C_CTR1(ch) = IT83XX_I2C_COMQ_EN |
- IT83XX_I2C_MDL_EN;
- }
-}
-
-static void i2c_peripheral_init(void)
-{
- int i, p;
-
- /* DLM 52k~56k size select enable */
- IT83XX_GCTRL_MCCR2 |= (1 << 4);
-
- /* Enable I2C Peripheral function */
- for (i = 0; i < i2c_periphs_used; i++) {
-
- /* I2c peripheral port mapping. */
- p = i2c_periph_ports[i].port;
-
- /* To enable peripheral ch[x] */
- i2c_peripheral_enable(p, i2c_periph_ports[i].addr);
-
- /* Clear the interrupt status */
- task_clear_pending_irq(i2c_periph_ctrl[p].irq);
-
- /* enable i2c interrupt */
- task_enable_irq(i2c_periph_ctrl[p].irq);
- }
-}
-DECLARE_HOOK(HOOK_INIT, i2c_peripheral_init, HOOK_PRIO_INIT_I2C + 1);