mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2026-01-10 17:41:54 +00:00
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>
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
/* Disable the SMBus host interface */
|
||||
IT83XX_SMB_HOCTL2(p) = 0x00;
|
||||
if (p < I2C_STANDARD_PORT_COUNT) {
|
||||
/* bit1, kill current transaction. */
|
||||
IT83XX_SMB_HOCTL(p) |= 0x02;
|
||||
IT83XX_SMB_HOCTL(p) &= ~0x02;
|
||||
|
||||
/* clk pin output high */
|
||||
*i2c_pin_regs[p].pin_clk = 0x40;
|
||||
*i2c_pin_regs[p].pin_clk_ctrl |= i2c_pin_regs[p].clk_mask;
|
||||
/* Disable the SMBus host interface */
|
||||
IT83XX_SMB_HOCTL2(p) = 0x00;
|
||||
|
||||
udelay(16);
|
||||
/* clk pin output high */
|
||||
*i2c_pin_regs[p].pin_clk = 0x40;
|
||||
*i2c_pin_regs[p].pin_clk_ctrl |= i2c_pin_regs[p].clk_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(16);
|
||||
|
||||
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);
|
||||
/* data pin output high */
|
||||
*i2c_pin_regs[p].pin_data = 0x40;
|
||||
*i2c_pin_regs[p].pin_data_ctrl |= i2c_pin_regs[p].data_mask;
|
||||
|
||||
/* I2C function */
|
||||
*i2c_pin_regs[p].pin_clk = 0x00;
|
||||
*i2c_pin_regs[p].pin_data = 0x00;
|
||||
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);
|
||||
|
||||
/* Enable the SMBus host interface */
|
||||
IT83XX_SMB_HOCTL2(p) = 0x11;
|
||||
/* I2C function */
|
||||
*i2c_pin_regs[p].pin_clk = 0x00;
|
||||
*i2c_pin_regs[p].pin_data = 0x00;
|
||||
|
||||
/* W/C host status register */
|
||||
IT83XX_SMB_HOSTA(p) = HOSTA_ALL_WC_BIT;
|
||||
/* Enable the SMBus host interface */
|
||||
IT83XX_SMB_HOCTL2(p) = 0x11;
|
||||
|
||||
CPRINTS("I2C ch%d reset cause %d", p, cause);
|
||||
/* 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);
|
||||
|
||||
/* State reset and hardware reset */
|
||||
IT83XX_I2C_CTR(p_ch) = 0x11;
|
||||
IT83XX_I2C_CTR(p_ch) = 0x00;
|
||||
|
||||
/* Set i2c frequency */
|
||||
IT83XX_I2C_PSR(p_ch) = pdata[p].freq;
|
||||
IT83XX_I2C_HSPR(p_ch) = pdata[p].freq;
|
||||
|
||||
/* 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 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);
|
||||
|
||||
/* Send ID */
|
||||
i2c_pio_trans_data(p, TX_DIRECT, pd->addr, 1);
|
||||
} else {
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/* any error */
|
||||
if (IT83XX_SMB_HOSTA(p) & HOSTA_ANY_ERROR) {
|
||||
pd->err = (IT83XX_SMB_HOSTA(p) & HOSTA_ANY_ERROR);
|
||||
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 {
|
||||
/* 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;
|
||||
/* 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;
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user