diff options
author | Eli Hsu <eli.hsu@ite.com.tw> | 2016-04-14 16:33:33 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-04-14 21:08:00 -0700 |
commit | b72c096f20a0520ff794cc871073677bdb0cdec7 (patch) | |
tree | 1c383686906a5daa1f45093310d0647d39fc3409 | |
parent | a1b00c1797d3695c1a55dff2cc161ce2fbc8ada5 (diff) | |
download | chrome-ec-b72c096f20a0520ff794cc871073677bdb0cdec7.tar.gz |
chip: it83xx: Add i2c channel d/e/f function
[board]
1. Add i2c channel d/e/f setting.
2. Add i2c channel d/e/f pin definition.
[chip]
3. change i2c port number.
4. Add i2c channel d/e/f function.
5. Add i2c channel d/e/f interrupt.
6. Add i2c channel d/e/f registers.
Signed-off-by: Eli Hsu <eli.hsu@ite.com.tw>
BRANCH=none
BUG=none
TEST=Test by console command "i2cscan","i2cxfer" and "battery"
Change-Id: I928f333ec129924795c3b594ad6a2bfdd0b3d220
Reviewed-on: https://chromium-review.googlesource.com/336560
Commit-Ready: Eli Hsu <eli.hsu@ite.com.tw>
Tested-by: Eli Hsu <eli.hsu@ite.com.tw>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | board/it8380dev/board.c | 21 | ||||
-rw-r--r-- | board/it8380dev/board.h | 6 | ||||
-rw-r--r-- | board/it8380dev/gpio.inc | 9 | ||||
-rw-r--r-- | chip/it83xx/config_chip.h | 8 | ||||
-rw-r--r-- | chip/it83xx/i2c.c | 614 | ||||
-rw-r--r-- | chip/it83xx/intc.c | 18 | ||||
-rw-r--r-- | chip/it83xx/registers.h | 92 |
7 files changed, 668 insertions, 100 deletions
diff --git a/board/it8380dev/board.c b/board/it8380dev/board.c index d7bf4388ab..b63f6b9dcb 100644 --- a/board/it8380dev/board.c +++ b/board/it8380dev/board.c @@ -213,13 +213,28 @@ struct keyboard_scan_config keyscan_config = { * In order to set frequency independently for each channels, * We use timing registers 09h~0Bh, and the supported frequency will be: * 50KHz, 100KHz, 400KHz, or 1MHz. + * I2C channels (D, E and F) can be set different frequency on different ports. + * The I2C(D/E/F) frequency depend on the frequency of SMBus Module and + * the individual prescale register. + * The frequency of SMBus module is 24MHz on default. + * The allowed range of I2C(D/E/F) frequency is as following setting. + * SMBus Module Freq = PLL_CLOCK / ((IT83XX_ECPM_SCDCR2 & 0x0F) + 1) + * (SMBus Module Freq / 510) <= I2C Freq <= (SMBus Module Freq / 8) + * Channel D has multi-function and can be used as UART interface. + * Channel F is reserved for EC debug. */ + /* I2C ports */ const struct i2c_port_t i2c_ports[] = { - {"battery", 2, 100, GPIO_I2C_C_SCL, GPIO_I2C_C_SDA}, - {"evb-1", 0, 100, GPIO_I2C_A_SCL, GPIO_I2C_A_SDA}, - {"evb-2", 1, 100, GPIO_I2C_B_SCL, GPIO_I2C_B_SDA}, + {"battery", IT83XX_I2C_CH_C, 100, GPIO_I2C_C_SCL, GPIO_I2C_C_SDA}, + {"evb-1", IT83XX_I2C_CH_A, 100, GPIO_I2C_A_SCL, GPIO_I2C_A_SDA}, + {"evb-2", IT83XX_I2C_CH_B, 100, GPIO_I2C_B_SCL, GPIO_I2C_B_SDA}, +#ifndef CONFIG_UART_HOST + {"opt-3", IT83XX_I2C_CH_D, 100, GPIO_I2C_D_SCL, GPIO_I2C_D_SDA}, +#endif + {"opt-4", IT83XX_I2C_CH_E, 100, GPIO_I2C_E_SCL, GPIO_I2C_E_SDA}, }; + const unsigned int i2c_ports_used = ARRAY_SIZE(i2c_ports); /* SPI devices */ diff --git a/board/it8380dev/board.h b/board/it8380dev/board.h index 2655c8ec74..b2cf093968 100644 --- a/board/it8380dev/board.h +++ b/board/it8380dev/board.h @@ -39,8 +39,10 @@ #ifndef __ASSEMBLER__ -#define I2C_PORT_CHARGER 2 -#define I2C_PORT_BATTERY 2 +#include "registers.h" + +#define I2C_PORT_CHARGER IT83XX_I2C_CH_C +#define I2C_PORT_BATTERY IT83XX_I2C_CH_C #include "gpio_signal.h" diff --git a/board/it8380dev/gpio.inc b/board/it8380dev/gpio.inc index a76527e0c3..51c9167b92 100644 --- a/board/it8380dev/gpio.inc +++ b/board/it8380dev/gpio.inc @@ -36,9 +36,15 @@ GPIO(I2C_C_SCL, PIN(F, 6), GPIO_INPUT) #endif GPIO(I2C_C_SDA, PIN(F, 7), GPIO_INPUT) +GPIO(I2C_E_SCL, PIN(E, 0), GPIO_INPUT) +GPIO(I2C_E_SDA, PIN(E, 7), GPIO_INPUT) + #ifdef CONFIG_UART_HOST GPIO(UART2_SIN1, PIN(H, 1), GPIO_INPUT) GPIO(UART2_SOUT1, PIN(H, 2), GPIO_INPUT) +#else +GPIO(I2C_D_SCL, PIN(H, 1), GPIO_INPUT) +GPIO(I2C_D_SDA, PIN(H, 2), GPIO_INPUT) #endif /* KSO/KSI pins can be used as GPIO input. */ @@ -52,6 +58,8 @@ UNIMPLEMENTED(ENTERING_RW) ALTERNATE(PIN_MASK(B, 0x03), 1, MODULE_UART, GPIO_PULL_UP) /* UART1 */ #ifdef CONFIG_UART_HOST ALTERNATE(PIN_MASK(H, 0x06), 1, MODULE_UART, 0) /* UART2 */ +#else +ALTERNATE(PIN_MASK(H, 0x06), 1, MODULE_I2C, 0) /* I2C D SCL/SDA H1/H2 */ #endif ALTERNATE(PIN_MASK(A, 0x40), 3, MODULE_SPI, 0) /* SSCK of SPI */ ALTERNATE(PIN_MASK(C, 0x28), 3, MODULE_SPI, 0) /* SMOSI/SMISO of SPI */ @@ -67,3 +75,4 @@ ALTERNATE(PIN_MASK(F, 0x80), 1, MODULE_I2C, 0) /* I2C C SDA */ ALTERNATE(PIN_MASK(C, 0x06), 1, MODULE_I2C, 0) /* I2C B SCL/SDA */ ALTERNATE(PIN_MASK(F, 0xC0), 1, MODULE_I2C, 0) /* I2C C SCL/SDA */ #endif +ALTERNATE(PIN_MASK(E, 0x81), 1, MODULE_I2C, 0) /* I2C E SCL/SDA E0/E7 */ diff --git a/chip/it83xx/config_chip.h b/chip/it83xx/config_chip.h index c71fc5f925..e66ee01181 100644 --- a/chip/it83xx/config_chip.h +++ b/chip/it83xx/config_chip.h @@ -23,7 +23,13 @@ #define PLL_CLOCK 48000000 /* Number of I2C ports */ -#define I2C_PORT_COUNT 3 +#define I2C_PORT_COUNT 6 + +/* I2C ports on chip + * IT83xx - There are three i2c standard ports. + * There are three i2c enhanced ports. + */ +#define I2C_STANDARD_PORT_COUNT 3 /****************************************************************************/ /* Memory mapping */ diff --git a/chip/it83xx/i2c.c b/chip/it83xx/i2c.c index fe516bb41f..2f5dd31fff 100644 --- a/chip/it83xx/i2c.c +++ b/chip/it83xx/i2c.c @@ -27,6 +27,11 @@ /* Default maximum time we allow for an I2C transfer */ #define I2C_TIMEOUT_DEFAULT_US (100 * MSEC) +enum enhanced_i2c_transfer_direct { + TX_DIRECT, + RX_DIRECT, +}; + enum i2c_host_status { /* Host busy */ HOSTA_HOBY = 0x01, @@ -48,6 +53,46 @@ enum i2c_host_status { HOSTA_NO_FINISH = 0xFF, }; +enum enhanced_i2c_host_status { + /* ACK receive */ + E_HOSTA_ACK = 0x01, + /* Interrupt pending */ + E_HOSTA_INTP = 0x02, + /* Read/Write */ + E_HOSTA_RW = 0x04, + /* Time out error */ + E_HOSTA_TMOE = 0x08, + /* Arbitration lost */ + E_HOSTA_ARB = 0x10, + /* Bus busy */ + E_HOSTA_BB = 0x20, + /* Address match */ + E_HOSTA_AM = 0x40, + /* Byte done status */ + E_HOSTA_BDS = 0x80, + + E_HOSTA_NO_FINISH = 0xFF, +}; + +enum enhanced_i2c_ctl { + /* Hardware reset */ + E_HW_RST = 0x01, + /* Stop */ + E_STOP = 0x02, + /* Start & Repeat start */ + E_START = 0x04, + /* Acknowledge */ + E_ACK = 0x08, + /* State reset */ + E_STS_RST = 0x10, + /* Mode select */ + E_MODE_SEL = 0x20, + /* I2C interrupt enable */ + E_INT_EN = 0x40, + /* 0 : Standard mode , 1 : Receive mode */ + E_RX_MODE = 0x80, +}; + enum i2c_host_status_mask { HOSTA_ANY_ERROR = (HOSTA_DVER | HOSTA_BSER | HOSTA_FAIL | HOSTA_NACK | HOSTA_TMOE), @@ -55,6 +100,11 @@ enum i2c_host_status_mask { HOSTA_ALL_WC_BIT = (HOSTA_FINTR | HOSTA_ANY_ERROR | HOSTA_BDS), }; +enum enhanced_i2c_host_status_mask { + E_HOSTA_ANY_ERROR = (E_HOSTA_TMOE | E_HOSTA_ARB), + E_HOSTA_NEXT_BYTE = E_HOSTA_BDS, +}; + enum i2c_reset_cause { I2C_RC_NO_IDLE_FOR_START = 1, I2C_RC_TIMEOUT, @@ -103,23 +153,40 @@ static const struct i2c_pin i2c_pin_regs[] = { &IT83XX_GPIO_GPDMRF, &IT83XX_GPIO_GPDMRF, 0x40, 0x80}, #endif + { &IT83XX_GPIO_GPCRH1, &IT83XX_GPIO_GPCRH2, + &IT83XX_GPIO_GPDRH, &IT83XX_GPIO_GPDRH, + &IT83XX_GPIO_GPDMRH, &IT83XX_GPIO_GPDMRH, + 0x02, 0x04}, + { &IT83XX_GPIO_GPCRE0, &IT83XX_GPIO_GPCRE7, + &IT83XX_GPIO_GPDRE, &IT83XX_GPIO_GPDRE, + &IT83XX_GPIO_GPDMRE, &IT83XX_GPIO_GPDMRE, + 0x01, 0x80}, + { &IT83XX_GPIO_GPCRA4, &IT83XX_GPIO_GPCRA5, + &IT83XX_GPIO_GPDRA, &IT83XX_GPIO_GPDRA, + &IT83XX_GPIO_GPDMRA, &IT83XX_GPIO_GPDMRA, + 0x10, 0x20}, }; struct i2c_ctrl_t { uint8_t irq; enum clock_gate_offsets clock_gate; + int reg_shift; }; const struct i2c_ctrl_t i2c_ctrl_regs[] = { - {IT83XX_IRQ_SMB_A, CGC_OFFSET_SMBA}, - {IT83XX_IRQ_SMB_B, CGC_OFFSET_SMBB}, - {IT83XX_IRQ_SMB_C, CGC_OFFSET_SMBC}, + {IT83XX_IRQ_SMB_A, CGC_OFFSET_SMBA, -1}, + {IT83XX_IRQ_SMB_B, CGC_OFFSET_SMBB, -1}, + {IT83XX_IRQ_SMB_C, CGC_OFFSET_SMBC, -1}, + {IT83XX_IRQ_SMB_D, CGC_OFFSET_SMBD, 3}, + {IT83XX_IRQ_SMB_E, CGC_OFFSET_SMBE, 0}, + {IT83XX_IRQ_SMB_F, CGC_OFFSET_SMBF, 1}, }; enum i2c_ch_status { I2C_CH_NORMAL = 0, I2C_CH_W2R, I2C_CH_WAIT_READ, + I2C_CH_DIRECT_W2R = 4, }; /* I2C port state data */ @@ -134,6 +201,7 @@ struct i2c_port_data { int err; /* Error code, if any */ uint8_t addr; /* address of device */ uint32_t timeout_us; /* Transaction timeout, or 0 to use default */ + uint8_t freq; /* Freqency setting */ enum i2c_ch_status i2ccs; /* Task waiting on port, or TASK_ID_INVALID if none. */ @@ -141,44 +209,90 @@ struct i2c_port_data { }; static struct i2c_port_data pdata[I2C_PORT_COUNT]; +static int i2c_ch_reg_shift(int p) +{ + /* + * only enhanced port needs to be changed the parameter of registers + */ + ASSERT(p >= I2C_STANDARD_PORT_COUNT && p < I2C_PORT_COUNT); + + /* + * The registers of i2c enhanced ports are not sequential. + * This routine transfers the i2c port number to related + * parameter of registers. + * + * IT83xx chip : i2c enhanced ports - channel D,E,F + * channel D registers : 0x3680 ~ 0x36FF + * channel E registers : 0x3500 ~ 0x357F + * channel F registers : 0x3580 ~ 0x35FF + */ + return i2c_ctrl_regs[p].reg_shift; +} + static void i2c_reset(int p, int cause) { - /* bit1, kill current transaction. */ - IT83XX_SMB_HOCTL(p) |= 0x02; - IT83XX_SMB_HOCTL(p) &= ~0x02; + int p_ch; + + if (p < I2C_STANDARD_PORT_COUNT) { + /* bit1, kill current transaction. */ + IT83XX_SMB_HOCTL(p) |= 0x02; + IT83XX_SMB_HOCTL(p) &= ~0x02; - /* Disable the SMBus host interface */ - IT83XX_SMB_HOCTL2(p) = 0x00; + /* Disable the SMBus host interface */ + IT83XX_SMB_HOCTL2(p) = 0x00; - /* clk pin output high */ - *i2c_pin_regs[p].pin_clk = 0x40; - *i2c_pin_regs[p].pin_clk_ctrl |= i2c_pin_regs[p].clk_mask; + /* clk pin output high */ + *i2c_pin_regs[p].pin_clk = 0x40; + *i2c_pin_regs[p].pin_clk_ctrl |= i2c_pin_regs[p].clk_mask; - udelay(16); + udelay(16); - /* data pin output high */ - *i2c_pin_regs[p].pin_data = 0x40; - *i2c_pin_regs[p].pin_data_ctrl |= i2c_pin_regs[p].data_mask; + /* data pin output high */ + *i2c_pin_regs[p].pin_data = 0x40; + *i2c_pin_regs[p].pin_data_ctrl |= i2c_pin_regs[p].data_mask; - udelay(500); - /* start condition */ - *i2c_pin_regs[p].pin_data_ctrl &= ~i2c_pin_regs[p].data_mask; - udelay(1000); - /* stop condition */ - *i2c_pin_regs[p].pin_data_ctrl |= i2c_pin_regs[p].data_mask; - udelay(500); + udelay(500); + /* start condition */ + *i2c_pin_regs[p].pin_data_ctrl &= ~i2c_pin_regs[p].data_mask; + udelay(1000); + /* stop condition */ + *i2c_pin_regs[p].pin_data_ctrl |= i2c_pin_regs[p].data_mask; + udelay(500); - /* I2C function */ - *i2c_pin_regs[p].pin_clk = 0x00; - *i2c_pin_regs[p].pin_data = 0x00; + /* I2C function */ + *i2c_pin_regs[p].pin_clk = 0x00; + *i2c_pin_regs[p].pin_data = 0x00; + + /* Enable the SMBus host interface */ + IT83XX_SMB_HOCTL2(p) = 0x11; + + /* W/C host status register */ + IT83XX_SMB_HOSTA(p) = HOSTA_ALL_WC_BIT; + CPRINTS("I2C ch%d reset cause %d", p, cause); + } else { + /* Shift register */ + p_ch = i2c_ch_reg_shift(p); - /* Enable the SMBus host interface */ - IT83XX_SMB_HOCTL2(p) = 0x11; + /* State reset and hardware reset */ + IT83XX_I2C_CTR(p_ch) = 0x11; + IT83XX_I2C_CTR(p_ch) = 0x00; - /* W/C host status register */ - IT83XX_SMB_HOSTA(p) = HOSTA_ALL_WC_BIT; + /* Set i2c frequency */ + IT83XX_I2C_PSR(p_ch) = pdata[p].freq; + IT83XX_I2C_HSPR(p_ch) = pdata[p].freq; - CPRINTS("I2C ch%d reset cause %d", p, cause); + /* Set time out register */ + IT83XX_I2C_TOR(p_ch) = 0xFF; + + /* Time buffer from STOP signal to next START signal */ + IT83XX_I2C_T_BUF(p_ch) = 0x3F; + + /* Enable interrupt, Master mode, Ack needed */ + IT83XX_I2C_CTR(p_ch) = 0x68; + + /* Enable i2c d/e/f module */ + IT83XX_I2C_CTR1(p_ch) = 0x32; + } } static void i2c_r_last_byte(int p) @@ -211,6 +325,50 @@ static void i2c_w2r_change_direction(int p) } } +static void i2c_pio_trans_data(int p, enum enhanced_i2c_transfer_direct direct, + uint8_t data, int first_byte) +{ + struct i2c_port_data *pd = pdata + p; + int p_ch; + + /* Shift register */ + p_ch = i2c_ch_reg_shift(p); + + if (first_byte) { + /* First byte must be slave address, transmit data */ + IT83XX_I2C_DTR(p_ch) = data; + } else { + if (direct == TX_DIRECT) + /* Transmit data*/ + IT83XX_I2C_DTR(p_ch) = data; + else { + /* Receive data, master need to ack */ + IT83XX_I2C_CTR(p_ch) |= E_ACK; + + /* Last byte should be NACK in the end of read cycle */ + if (((pd->ridx + 1) == pd->in_size) && + (pd->flags & I2C_XFER_STOP)) + /* Clear ack bit */ + IT83XX_I2C_CTR(p_ch) &= ~E_ACK; + } + } + + if (first_byte) { + /* + * Need start or repeat start signal + * Set hardware reset to start next transmission + */ + IT83XX_I2C_CTR(p_ch) |= (E_START | E_HW_RST); + } else { + /* + * Needn't start or repeat start signal + * Set hardware reset to start next transmission + */ + IT83XX_I2C_CTR(p_ch) &= ~(E_START); + IT83XX_I2C_CTR(p_ch) |= E_HW_RST; + } +} + static int i2c_tran_write(int p) { struct i2c_port_data *pd = pdata + p; @@ -334,35 +492,221 @@ static int i2c_tran_read(int p) return 1; } -static int i2c_transaction(int p) +static int enhanced_i2c_tran_write(int p) { struct i2c_port_data *pd = pdata + p; + uint8_t out_data; + int p_ch; + + /* Shift register */ + p_ch = i2c_ch_reg_shift(p); + + if (pd->flags & I2C_XFER_START) { + /* Clear start bit */ + pd->flags &= ~I2C_XFER_START; + + /* Reset channel */ + i2c_reset(p, 0); - /* any error */ - if (IT83XX_SMB_HOSTA(p) & HOSTA_ANY_ERROR) { - pd->err = (IT83XX_SMB_HOSTA(p) & HOSTA_ANY_ERROR); + /* Send ID */ + i2c_pio_trans_data(p, TX_DIRECT, pd->addr, 1); } else { - /* i2c write */ - if (pd->out_size) - return i2c_tran_write(p); - /* i2c read */ - else if (pd->in_size) - return i2c_tran_read(p); - /* wait finish */ - if (!(IT83XX_SMB_HOSTA(p) & HOSTA_FINTR)) + /* + * If device doesn't response ack, reset + * the channel and abort the transaction. + */ + if (!(IT83XX_I2C_STR(p_ch) & E_HOSTA_ACK)) { + pd->i2ccs = I2C_CH_NORMAL; + pd->err = E_HOSTA_ACK; + i2c_reset(p, 0); + /* Disable i2c module */ + IT83XX_I2C_CTR1(p_ch) = 0x00; + return 0; + } + + /* Wait for byte done */ + if (!(IT83XX_I2C_STR(p_ch) & E_HOSTA_BDS)) return 1; + + /* Host has completed the transmission of a byte */ + if (pd->widx < pd->out_size) { + out_data = *(pd->out++); + pd->widx++; + + /* Send Byte */ + i2c_pio_trans_data(p, TX_DIRECT, out_data, 0); + } else { + /* done */ + pd->out_size = 0; + if (pd->in_size > 0) { + /* Write to read protocol */ + pd->i2ccs = I2C_CH_W2R; + /* Repeat Start */ + i2c_pio_trans_data(p, RX_DIRECT, + (pd->addr + 1), 1); + } else { + if (pd->flags & I2C_XFER_STOP) { + /* Stop and finish */ + IT83XX_I2C_CTR(p) = + (E_STOP | E_HW_RST); + i2c_reset(p, 0); + /* Disable i2c module */ + IT83XX_I2C_CTR1(p_ch) = 0x00; + return 0; + } + /* Direct write with direct read */ + pd->i2ccs = I2C_CH_DIRECT_W2R; + return 0; + } + } + } + return 1; +} + +static int enhanced_i2c_tran_read(int p) +{ + struct i2c_port_data *pd = pdata + p; + uint8_t in_data = 0; + int p_ch; + + /* Shift register */ + p_ch = i2c_ch_reg_shift(p); + + if (pd->flags & I2C_XFER_START) { + /* clear start flag */ + pd->flags &= ~I2C_XFER_START; + + /* reset channel */ + i2c_reset(p, 0); + + /* Direct read */ + pd->i2ccs = I2C_CH_WAIT_READ; + + /* Send ID */ + i2c_pio_trans_data(p, RX_DIRECT, (pd->addr + 1), 1); + } else { + if (pd->i2ccs) { + if (pd->i2ccs == I2C_CH_W2R) { + pd->i2ccs = I2C_CH_NORMAL; + /* Receive data */ + i2c_pio_trans_data(p, RX_DIRECT, in_data, 0); + } else if (pd->i2ccs == I2C_CH_WAIT_READ) { + pd->i2ccs = I2C_CH_NORMAL; + /* + * If device doesn't response ack, reset + * the channel and abort the transaction. + */ + if (!(IT83XX_I2C_STR(p_ch) & E_HOSTA_ACK)) { + pd->err = E_HOSTA_ACK; + i2c_reset(p, 0); + /* Disable i2c module */ + IT83XX_I2C_CTR1(p_ch) = 0x00; + return 0; + } + /* Receive data */ + i2c_pio_trans_data(p, RX_DIRECT, in_data, 0); + /* Direct write with direct read protocol */ + task_clear_pending_irq(i2c_ctrl_regs[p].irq); + /* Turn on irq before next direct read */ + task_enable_irq(i2c_ctrl_regs[p].irq); + } else { + /* Write to read */ + pd->i2ccs = I2C_CH_WAIT_READ; + /* Send ID */ + i2c_pio_trans_data(p, RX_DIRECT, + (pd->addr + 1), 1); + /* Direct write with direct read protocol */ + task_clear_pending_irq(i2c_ctrl_regs[p].irq); + /* Turn on irq before next direct read */ + task_enable_irq(i2c_ctrl_regs[p].irq); + } + } else { + /* Wait for byte done */ + if (!(IT83XX_I2C_STR(p_ch) & E_HOSTA_BDS)) + return 1; + + if (pd->ridx < pd->in_size) { + /* read data */ + *(pd->in++) = IT83XX_I2C_DRR(p_ch); + pd->ridx++; + + /* done */ + if (pd->ridx == pd->in_size) { + pd->in_size = 0; + if (pd->flags & I2C_XFER_STOP) { + pd->i2ccs = I2C_CH_NORMAL; + /* Stop and finish */ + IT83XX_I2C_CTR(p_ch) = + (E_STOP | E_HW_RST); + /* Disable i2c module */ + IT83XX_I2C_CTR1(p_ch) = 0x00; + return 0; + } + /* End the transaction */ + pd->i2ccs = I2C_CH_WAIT_READ; + return 0; + } + /* read next byte */ + i2c_pio_trans_data(p, RX_DIRECT, in_data, 0); + } + } + } + return 1; +} + +static int i2c_transaction(int p) +{ + struct i2c_port_data *pd = pdata + p; + int p_ch; + + if (p < I2C_STANDARD_PORT_COUNT) { + /* any error */ + if (IT83XX_SMB_HOSTA(p) & HOSTA_ANY_ERROR) { + pd->err = (IT83XX_SMB_HOSTA(p) & HOSTA_ANY_ERROR); + } else { + /* i2c write */ + if (pd->out_size) + return i2c_tran_write(p); + /* i2c read */ + else if (pd->in_size) + return i2c_tran_read(p); + /* wait finish */ + if (!(IT83XX_SMB_HOSTA(p) & HOSTA_FINTR)) + return 1; + } + /* W/C */ + IT83XX_SMB_HOSTA(p) = HOSTA_ALL_WC_BIT; + /* disable the SMBus host interface */ + IT83XX_SMB_HOCTL2(p) = 0x00; + } else { + /* Shift register */ + p_ch = i2c_ch_reg_shift(p); + + /* check error */ + if (IT83XX_I2C_STR(p_ch) & E_HOSTA_ANY_ERROR) + pd->err = (IT83XX_I2C_STR(p_ch) & E_HOSTA_ANY_ERROR); + else { + /* i2c write */ + if (pd->out_size) + return enhanced_i2c_tran_write(p); + /* i2c read */ + else if (pd->in_size) + return enhanced_i2c_tran_read(p); + } } - /* W/C */ - IT83XX_SMB_HOSTA(p) = HOSTA_ALL_WC_BIT; - /* disable the SMBus host interface */ - IT83XX_SMB_HOCTL2(p) = 0x00; /* done doing work */ return 0; } int i2c_is_busy(int port) { - return IT83XX_SMB_HOSTA(port) & HOSTA_HOBY; + int p_ch; + + if (port < I2C_STANDARD_PORT_COUNT) + return (IT83XX_SMB_HOSTA(port) & HOSTA_HOBY); + + p_ch = i2c_ch_reg_shift(port); + return (IT83XX_I2C_STR(p_ch) & E_HOSTA_BB); } int chip_i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size, @@ -374,7 +718,9 @@ int chip_i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size, if (out_size == 0 && in_size == 0) return EC_SUCCESS; - if ((pd->i2ccs == I2C_CH_W2R) || (pd->i2ccs == I2C_CH_WAIT_READ)) { + if ((pd->i2ccs == I2C_CH_W2R) || + (pd->i2ccs == I2C_CH_WAIT_READ) || + (pd->i2ccs & I2C_CH_DIRECT_W2R)) { if ((flags & I2C_XFER_SINGLE) == I2C_XFER_SINGLE) flags &= ~I2C_XFER_START; } @@ -390,15 +736,26 @@ int chip_i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size, pd->err = 0; pd->addr = slave_addr; - /* Make sure we're in a good state to start */ - if ((flags & I2C_XFER_START) && (i2c_is_busy(port) + if (port < I2C_STANDARD_PORT_COUNT) { + /* Make sure we're in a good state to start */ + if ((flags & I2C_XFER_START) && (i2c_is_busy(port) || (IT83XX_SMB_HOSTA(port) & HOSTA_ALL_WC_BIT) || (i2c_get_line_levels(port) != I2C_LINE_IDLE))) { - /* Attempt to unwedge the port. */ - i2c_unwedge(port); - /* reset i2c port */ - i2c_reset(port, I2C_RC_NO_IDLE_FOR_START); + /* Attempt to unwedge the port. */ + i2c_unwedge(port); + /* reset i2c port */ + i2c_reset(port, I2C_RC_NO_IDLE_FOR_START); + } + } else { + /* Make sure we're in a good state to start */ + if ((flags & I2C_XFER_START) && (i2c_is_busy(port) + || (i2c_get_line_levels(port) != I2C_LINE_IDLE))) { + /* Attempt to unwedge the port. */ + i2c_unwedge(port); + /* reset i2c port */ + i2c_reset(port, I2C_RC_NO_IDLE_FOR_START); + } } pd->task_waiting = task_get_current(); @@ -452,7 +809,17 @@ int i2c_raw_get_sda(int port) int i2c_get_line_levels(int port) { - return IT83XX_SMB_SMBPCTL(port) & 0x03; + int pin_sts = 0; + + if (port < I2C_STANDARD_PORT_COUNT) + return IT83XX_SMB_SMBPCTL(port) & 0x03; + + if (*i2c_pin_regs[port].mirror_clk & i2c_pin_regs[port].clk_mask) + pin_sts |= I2C_LINE_SCL_HIGH; + if (*i2c_pin_regs[port].mirror_data & i2c_pin_regs[port].data_mask) + pin_sts |= I2C_LINE_SDA_HIGH; + + return pin_sts; } void i2c_set_timeout(int port, uint32_t timeout) @@ -480,18 +847,56 @@ void i2c_interrupt(int port) static void i2c_freq_changed(void) { - int i, f; + int i, f, clk_div, psr, freq; + int p_ch; + /* + * Standard I2C Channels + */ for (i = 0; i < i2c_ports_used; i++) { - for (f = ARRAY_SIZE(i2c_freq_select) - 1; f >= 0; f--) { - if (i2c_ports[i].kbps >= i2c_freq_select[f].kpbs) { - IT83XX_SMB_SCLKTS(i2c_ports[i].port) = - i2c_freq_select[f].freq_set; - break; + freq = i2c_ports[i].kbps; + if (i2c_ports[i].port < I2C_STANDARD_PORT_COUNT) { + for (f = ARRAY_SIZE(i2c_freq_select) - 1; f >= 0; f--) { + if (freq >= i2c_freq_select[f].kpbs) { + IT83XX_SMB_SCLKTS(i2c_ports[i].port) = + i2c_freq_select[f].freq_set; + break; + } + } + } else { + p_ch = i2c_ch_reg_shift(i2c_ports[i].port); + /* + * Let psr(Prescale) = IT83XX_I2C_PSR(p_ch) + * Then, 1 SCL cycle = 2 x (psr + 2) x SMBus clock cycle + * SMBus clock = PLL_CLOCK / clk_div + * SMBus clock cycle = 1 / SMBus clock + * 1 SCL cycle = 1 / (1000 x freq) + * 1 / (1000 x freq) = + * 2 x (psr + 2) x (1 / (PLL_CLOCK / clk_div)) + * psr = ((PLL_CLOCK / clk_div) x + * (1 / (1000 x freq)) x (1 / 2)) - 2 + */ + if (freq) { + /* Get SMBus clock devide value */ + clk_div = (IT83XX_ECPM_SCDCR2 & 0x0F) + 1; + /* Calculate PSR value */ + psr = (PLL_CLOCK / + (clk_div * (2 * 1000 * freq))) - 2; + /* Set psr value under 0xFD */ + if (psr > 0xFD) + psr = 0xFD; + + /* Set I2C Speed */ + IT83XX_I2C_PSR(p_ch) = (psr & 0xFF); + IT83XX_I2C_HSPR(p_ch) = (psr & 0xFF); + + /* Backup */ + pdata[i2c_ports[i].port].freq = (psr & 0xFF); } + /* I2C D/E/F clock/data low timeout. */ + IT83XX_I2C_TOR(p_ch) = I2C_CLK_LOW_TIMEOUT; } } - /* This field defines the SMCLK0/1/2 clock/data low timeout. */ IT83XX_SMB_25MS = I2C_CLK_LOW_TIMEOUT; } @@ -499,7 +904,7 @@ DECLARE_HOOK(HOOK_FREQ_CHANGE, i2c_freq_changed, HOOK_PRIO_DEFAULT); static void i2c_init(void) { - int i, p; + int i, p, p_ch; /* Configure GPIOs */ gpio_config_module(MODULE_I2C, 1); @@ -513,33 +918,78 @@ static void i2c_init(void) for (i = 0; i < i2c_ports_used; i++) { /* I2c port mapping. */ p = i2c_ports[i].port; - clock_enable_peripheral(i2c_ctrl_regs[p].clock_gate, 0, 0); - /* - * bit0, The SMBus host interface is enabled. - * bit1, Enable to communicate with I2C device and - * support I2C-compatible cycles. - * bit4, This bit controls the reset mechanism of SMBus master - * to handle the SMDAT line low if 25ms reg timeout. - */ - IT83XX_SMB_HOCTL2(p) = 0x11; - /* - * bit1, Kill SMBus host transaction. - * bit0, Enable the interrupt for the master interface. - */ - IT83XX_SMB_HOCTL(p) = 0x03; - IT83XX_SMB_HOCTL(p) = 0x01; - /* W/C host status register */ - IT83XX_SMB_HOSTA(p) = HOSTA_ALL_WC_BIT; - IT83XX_SMB_HOCTL2(p) = 0x00; + clock_enable_peripheral(i2c_ctrl_regs[p].clock_gate, 0, 0); + if (p < I2C_STANDARD_PORT_COUNT) { + /* + * bit0, The SMBus host interface is enabled. + * bit1, Enable to communicate with I2C device + * and support I2C-compatible cycles. + * bit4, This bit controls the reset mechanism + * of SMBus master to handle the SMDAT + * line low if 25ms reg timeout. + */ + IT83XX_SMB_HOCTL2(p) = 0x11; + /* + * bit1, Kill SMBus host transaction. + * bit0, Enable the interrupt for the master interface. + */ + IT83XX_SMB_HOCTL(p) = 0x03; + IT83XX_SMB_HOCTL(p) = 0x01; + /* W/C host status register */ + IT83XX_SMB_HOSTA(p) = HOSTA_ALL_WC_BIT; + IT83XX_SMB_HOCTL2(p) = 0x00; + } else { + /* Shift register */ + p_ch = i2c_ch_reg_shift(p); + switch (p) { + case IT83XX_I2C_CH_D: + #ifndef CONFIG_UART_HOST + /* Enable SMBus D channel */ + IT83XX_GPIO_GRC2 |= 0x20; + #endif + break; + case IT83XX_I2C_CH_E: + /* Enable SMBus E channel */ + IT83XX_GCTRL_PMER1 |= 0x01; + break; + case IT83XX_I2C_CH_F: + /* Enable SMBus F channel */ + IT83XX_GCTRL_PMER1 |= 0x02; + break; + } + /* Software reset */ + IT83XX_I2C_DHTR(p_ch) |= 0x80; + IT83XX_I2C_DHTR(p_ch) &= 0x7F; + + /* State reset and hardware reset */ + IT83XX_I2C_CTR(p_ch) = 0x11; + IT83XX_I2C_CTR(p_ch) = 0x00; + + /* Set time out condition */ + IT83XX_I2C_TOR(p_ch) = 0xFF; + IT83XX_I2C_T_BUF(p_ch) = 0x3F; + + /* + * bit3, Acknowledge + * bit5, Master mode + * bit6, Interrupt enable + */ + IT83XX_I2C_CTR(p_ch) = 0x68; + + /* + * bit1, Module enable + * bit4-6 Support number of devices + */ + IT83XX_I2C_CTR1(p_ch) = 0x00; + } pdata[i].task_waiting = TASK_ID_INVALID; } i2c_freq_changed(); for (i = 0; i < I2C_PORT_COUNT; i++) { - /* Use default timeout */ i2c_set_timeout(i, 0); } diff --git a/chip/it83xx/intc.c b/chip/it83xx/intc.c index 432eb7b34d..9b51b74fc3 100644 --- a/chip/it83xx/intc.c +++ b/chip/it83xx/intc.c @@ -88,15 +88,27 @@ void intc_cpu_int_group_6(void) switch (intc_group_6) { case IT83XX_IRQ_SMB_A: - i2c_interrupt(0); + i2c_interrupt(IT83XX_I2C_CH_A); break; case IT83XX_IRQ_SMB_B: - i2c_interrupt(1); + i2c_interrupt(IT83XX_I2C_CH_B); break; case IT83XX_IRQ_SMB_C: - i2c_interrupt(2); + i2c_interrupt(IT83XX_I2C_CH_C); + break; + + case IT83XX_IRQ_SMB_D: + i2c_interrupt(IT83XX_I2C_CH_D); + break; + + case IT83XX_IRQ_SMB_E: + i2c_interrupt(IT83XX_I2C_CH_E); + break; + + case IT83XX_IRQ_SMB_F: + i2c_interrupt(IT83XX_I2C_CH_F); break; default: diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h index efd5083edb..759bdc84eb 100644 --- a/chip/it83xx/registers.h +++ b/chip/it83xx/registers.h @@ -475,9 +475,12 @@ #define IT83XX_GPIO_GCR REG8(IT83XX_GPIO_BASE+0x00) +#define IT83XX_GPIO_GPDRA REG8(IT83XX_GPIO_BASE+0x01) #define IT83XX_GPIO_GPDRB REG8(IT83XX_GPIO_BASE+0x02) #define IT83XX_GPIO_GPDRC REG8(IT83XX_GPIO_BASE+0x03) +#define IT83XX_GPIO_GPDRE REG8(IT83XX_GPIO_BASE+0x05) #define IT83XX_GPIO_GPDRF REG8(IT83XX_GPIO_BASE+0x06) +#define IT83XX_GPIO_GPDRH REG8(IT83XX_GPIO_BASE+0x08) #define IT83XX_GPIO_GPCRA0 REG8(IT83XX_GPIO_BASE+0x10) #define IT83XX_GPIO_GPCRA1 REG8(IT83XX_GPIO_BASE+0x11) @@ -506,14 +509,14 @@ #define IT83XX_GPIO_GPCRC6 REG8(IT83XX_GPIO_BASE+0x26) #define IT83XX_GPIO_GPCRC7 REG8(IT83XX_GPIO_BASE+0x27) -#define IT83XX_GPIO_GPCRF0 REG8(IT83XX_GPIO_BASE+0x38) -#define IT83XX_GPIO_GPCRF1 REG8(IT83XX_GPIO_BASE+0x39) -#define IT83XX_GPIO_GPCRF2 REG8(IT83XX_GPIO_BASE+0x3A) -#define IT83XX_GPIO_GPCRF3 REG8(IT83XX_GPIO_BASE+0x3B) -#define IT83XX_GPIO_GPCRF4 REG8(IT83XX_GPIO_BASE+0x3C) -#define IT83XX_GPIO_GPCRF5 REG8(IT83XX_GPIO_BASE+0x3D) -#define IT83XX_GPIO_GPCRF6 REG8(IT83XX_GPIO_BASE+0x3E) -#define IT83XX_GPIO_GPCRF7 REG8(IT83XX_GPIO_BASE+0x3F) +#define IT83XX_GPIO_GPCRE0 REG8(IT83XX_GPIO_BASE+0x30) +#define IT83XX_GPIO_GPCRE1 REG8(IT83XX_GPIO_BASE+0x31) +#define IT83XX_GPIO_GPCRE2 REG8(IT83XX_GPIO_BASE+0x32) +#define IT83XX_GPIO_GPCRE3 REG8(IT83XX_GPIO_BASE+0x33) +#define IT83XX_GPIO_GPCRE4 REG8(IT83XX_GPIO_BASE+0x34) +#define IT83XX_GPIO_GPCRE5 REG8(IT83XX_GPIO_BASE+0x35) +#define IT83XX_GPIO_GPCRE6 REG8(IT83XX_GPIO_BASE+0x36) +#define IT83XX_GPIO_GPCRE7 REG8(IT83XX_GPIO_BASE+0x37) #define IT83XX_GPIO_GPCRF0 REG8(IT83XX_GPIO_BASE+0x38) #define IT83XX_GPIO_GPCRF1 REG8(IT83XX_GPIO_BASE+0x39) @@ -524,6 +527,15 @@ #define IT83XX_GPIO_GPCRF6 REG8(IT83XX_GPIO_BASE+0x3E) #define IT83XX_GPIO_GPCRF7 REG8(IT83XX_GPIO_BASE+0x3F) +#define IT83XX_GPIO_GPCRH0 REG8(IT83XX_GPIO_BASE+0x48) +#define IT83XX_GPIO_GPCRH1 REG8(IT83XX_GPIO_BASE+0x49) +#define IT83XX_GPIO_GPCRH2 REG8(IT83XX_GPIO_BASE+0x4A) +#define IT83XX_GPIO_GPCRH3 REG8(IT83XX_GPIO_BASE+0x4B) +#define IT83XX_GPIO_GPCRH4 REG8(IT83XX_GPIO_BASE+0x4C) +#define IT83XX_GPIO_GPCRH5 REG8(IT83XX_GPIO_BASE+0x4D) +#define IT83XX_GPIO_GPCRH6 REG8(IT83XX_GPIO_BASE+0x4E) +#define IT83XX_GPIO_GPCRH7 REG8(IT83XX_GPIO_BASE+0x4F) + #define IT83XX_GPIO_GPCRI0 REG8(IT83XX_GPIO_BASE+0x50) #define IT83XX_GPIO_GPCRI1 REG8(IT83XX_GPIO_BASE+0x51) #define IT83XX_GPIO_GPCRI2 REG8(IT83XX_GPIO_BASE+0x52) @@ -533,9 +545,12 @@ #define IT83XX_GPIO_GPCRI6 REG8(IT83XX_GPIO_BASE+0x56) #define IT83XX_GPIO_GPCRI7 REG8(IT83XX_GPIO_BASE+0x57) +#define IT83XX_GPIO_GPDMRA REG8(IT83XX_GPIO_BASE+0x61) #define IT83XX_GPIO_GPDMRB REG8(IT83XX_GPIO_BASE+0x62) #define IT83XX_GPIO_GPDMRC REG8(IT83XX_GPIO_BASE+0x63) +#define IT83XX_GPIO_GPDMRE REG8(IT83XX_GPIO_BASE+0x65) #define IT83XX_GPIO_GPDMRF REG8(IT83XX_GPIO_BASE+0x66) +#define IT83XX_GPIO_GPDMRH REG8(IT83XX_GPIO_BASE+0x68) #define IT83XX_GPIO_GRC1 REG8(IT83XX_GPIO_BASE+0xF0) #define IT83XX_GPIO_GRC2 REG8(IT83XX_GPIO_BASE+0xF1) @@ -678,6 +693,7 @@ enum clock_gate_offsets { #define IT83XX_GCTRL_RSTC4 REG8(IT83XX_GCTRL_BASE+0x11) #define IT83XX_GCTRL_SPCTRL4 REG8(IT83XX_GCTRL_BASE+0x1C) #define IT83XX_GCTRL_MCCR REG8(IT83XX_GCTRL_BASE+0x30) +#define IT83XX_GCTRL_PMER1 REG8(IT83XX_GCTRL_BASE+0x32) #define IT83XX_GCTRL_PMER2 REG8(IT83XX_GCTRL_BASE+0x33) #define IT83XX_GCTRL_EPLR REG8(IT83XX_GCTRL_BASE+0x37) #define IT83XX_GCTRL_IVTBAR REG8(IT83XX_GCTRL_BASE+0x41) @@ -964,6 +980,9 @@ REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 5 : 8) + (ch << 4)) #define IT83XX_SMB_4P7A4P0H REG8(IT83XX_SMB_BASE+0x07) #define IT83XX_SMB_SLVISELR REG8(IT83XX_SMB_BASE+0x08) #define IT83XX_SMB_SCLKTS(ch) REG8(IT83XX_SMB_BASE+0x09+ch) +#define IT83XX_SMB_CHSEF REG8(IT83XX_SMB_BASE+0x11) +#define IT83XX_SMB_CHSAB REG8(IT83XX_SMB_BASE+0x20) +#define IT83XX_SMB_CHSCD REG8(IT83XX_SMB_BASE+0x21) #define IT83XX_SMB_HOSTA(ch) REG8(IT83XX_SMB_BASE+0x40+(ch << 6)) #define IT83XX_SMB_HOCTL(ch) REG8(IT83XX_SMB_BASE+0x41+(ch << 6)) #define IT83XX_SMB_HOCMD(ch) REG8(IT83XX_SMB_BASE+0x42+(ch << 6)) @@ -1012,6 +1031,62 @@ enum bram_indices { #define IT83XX_BRAM_BANK1(i) REG8(IT83XX_BRAM_BASE + 0x80 + i) +/* + * Enhanced SMBus/I2C Interface + * Ch_D: 0x00F03680 , Ch_E: 0x00F03500 , Ch_F: 0x00F03580 + * Ch_D: ch = 0x03 , Ch_E: ch = 0x00 , Ch_F: ch = 0x01 + */ +#define IT83XX_I2C_BASE 0x00F03500 + +#define IT83XX_I2C_DRR(ch) REG8(IT83XX_I2C_BASE+0x00+(ch << 7)) +#define IT83XX_I2C_PSR(ch) REG8(IT83XX_I2C_BASE+0x01+(ch << 7)) +#define IT83XX_I2C_HSPR(ch) REG8(IT83XX_I2C_BASE+0x02+(ch << 7)) +#define IT83XX_I2C_STR(ch) REG8(IT83XX_I2C_BASE+0x03+(ch << 7)) +#define IT83XX_I2C_DHTR(ch) REG8(IT83XX_I2C_BASE+0x04+(ch << 7)) +#define IT83XX_I2C_TOR(ch) REG8(IT83XX_I2C_BASE+0x05+(ch << 7)) +#define IT83XX_I2C_IDR(ch) REG8(IT83XX_I2C_BASE+0x06+(ch << 7)) +#define IT83XX_I2C_TOS(ch) REG8(IT83XX_I2C_BASE+0x07+(ch << 7)) +#define IT83XX_I2C_DTR(ch) REG8(IT83XX_I2C_BASE+0x08+(ch << 7)) +#define IT83XX_I2C_CTR(ch) REG8(IT83XX_I2C_BASE+0x09+(ch << 7)) +#define IT83XX_I2C_CTR1(ch) REG8(IT83XX_I2C_BASE+0x0A+(ch << 7)) +#define IT83XX_I2C_BYTE_CNT_H(ch) REG8(IT83XX_I2C_BASE+0x0B+(ch << 7)) +#define IT83XX_I2C_BYTE_CNT_L(ch) REG8(IT83XX_I2C_BASE+0x0C+(ch << 7)) +#define IT83XX_I2C_IRQ_ST(ch) REG8(IT83XX_I2C_BASE+0x0D+(ch << 7)) +#define IT83XX_I2C_SLV_NUM_H(ch) REG8(IT83XX_I2C_BASE+0x10+(ch << 7)) +#define IT83XX_I2C_SLV_NUM_L(ch) REG8(IT83XX_I2C_BASE+0x11+(ch << 7)) +#define IT83XX_I2C_STR2(ch) REG8(IT83XX_I2C_BASE+0x12+(ch << 7)) +#define IT83XX_I2C_NST(ch) REG8(IT83XX_I2C_BASE+0x13+(ch << 7)) +#define IT83XX_I2C_T_BUF(ch) REG8(IT83XX_I2C_BASE+0x14+(ch << 7)) +#define IT83XX_I2C_TH_ST(ch) REG8(IT83XX_I2C_BASE+0x16+(ch << 7)) +#define IT83XX_I2C_TO_ARB_ST(ch) REG8(IT83XX_I2C_BASE+0x18+(ch << 7)) +#define IT83XX_I2C_ERR_ST(ch) REG8(IT83XX_I2C_BASE+0x19+(ch << 7)) +#define IT83XX_I2C_EN_TRIG(ch) REG8(IT83XX_I2C_BASE+0x1A+(ch << 7)) +#define IT83XX_I2C_FST(ch) REG8(IT83XX_I2C_BASE+0x1B+(ch << 7)) +#define IT83XX_I2C_EM(ch) REG8(IT83XX_I2C_BASE+0x1C+(ch << 7)) +#define IT83XX_I2C_MODE_SEL(ch) REG8(IT83XX_I2C_BASE+0x1D+(ch << 7)) +#define IT83XX_I2C_CSR(ch) REG8(IT83XX_I2C_BASE+0x1F+(ch << 7)) +#define IT83XX_I2C_CTR2(ch) REG8(IT83XX_I2C_BASE+0x20+(ch << 7)) +#define IT83XX_I2C_CMD_IDX_2(ch) REG8(IT83XX_I2C_BASE+0x21+(ch << 7)) +#define IT83XX_I2C_WCSR_i(ch) REG8(IT83XX_I2C_BASE+0x22+(ch << 7)) +#define IT83XX_I2C_RAMHA_i(ch) REG8(IT83XX_I2C_BASE+0x23+(ch << 7)) +#define IT83XX_I2C_RAMLA_i(ch) REG8(IT83XX_I2C_BASE+0x24+(ch << 7)) +#define IT83XX_I2C_CMD_ADDH_i(ch) REG8(IT83XX_I2C_BASE+0x25+(ch << 7)) +#define IT83XX_I2C_CMD_ADDL_i(ch) REG8(IT83XX_I2C_BASE+0x26+(ch << 7)) +#define IT83XX_I2C_LNGRH_i(ch) REG8(IT83XX_I2C_BASE+0x27+(ch << 7)) +#define IT83XX_I2C_LNGRL_i(ch) REG8(IT83XX_I2C_BASE+0x28+(ch << 7)) +#define IT83XX_I2C_LNGSTH_i(ch) REG8(IT83XX_I2C_BASE+0x29+(ch << 7)) +#define IT83XX_I2C_TH_CTR(ch) REG8(IT83XX_I2C_BASE+0x2A+(ch << 7)) + +enum i2c_channels { + IT83XX_I2C_CH_A, /* GPIO.B3/B4 */ + IT83XX_I2C_CH_B, /* GPIO.C1/C2 */ + IT83XX_I2C_CH_C, /* GPIO.F6/F7 or GPIO.C7/F7 */ + IT83XX_I2C_CH_D, /* GPIO.H1/H2 */ + IT83XX_I2C_CH_E, /* GPIO.E0/E7 */ + IT83XX_I2C_CH_F, /* GPIO.A4/A5 (for util/iteflash) */ + IT83XX_I2C_PORT_COUNT, +}; + /* --- MISC (not implemented yet) --- */ #define IT83XX_PS2_BASE 0x00F01700 @@ -1020,7 +1095,6 @@ enum bram_indices { #define IT83XX_CIR_BASE 0x00F02300 #define IT83XX_DBGR_BASE 0x00F02500 #define IT83XX_OW_BASE 0x00F02A00 -#define IT83XX_I2C_BASE 0x00F02D00 #define IT83XX_CEC_BASE 0x00F02E00 #define IT83XX_USB_BASE 0x00F02F00 |