x86: Streamline MMIO accesses in GPIO and I2C drivers
This patch refactors the MMIO routines in the GPIO and I2C drivers to eliminate the base_addr parameter that specifies the MMIO base address. Instead, just the MMIO routines themselves retrieve the base address from the driver structure.
This commit is contained in:
parent
f85654a82f
commit
e297177a69
|
@ -60,29 +60,31 @@ struct gpio_internal_data {
|
||||||
static struct gpio_internal_data data;
|
static struct gpio_internal_data data;
|
||||||
|
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
read(uint32_t base_addr, uint32_t offset)
|
read(uint32_t offset)
|
||||||
{
|
{
|
||||||
return *(uint32_t*)(base_addr + offset);
|
uint32_t res;
|
||||||
|
PCI_MMIO_READL(data.pci, res, offset);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
write(uint32_t base_addr, uint32_t offset, uint32_t val)
|
write(uint32_t offset, uint32_t val)
|
||||||
{
|
{
|
||||||
*(uint32_t*)(base_addr + offset) = val;
|
PCI_MMIO_WRITEL(data.pci, offset, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* value must be 0x0 or 0x1 */
|
/* value must be 0x0 or 0x1 */
|
||||||
static void
|
static void
|
||||||
set_bit(uint32_t base_addr, uint32_t offset, uint32_t bit, uint32_t value)
|
set_bit(uint32_t offset, uint32_t bit, uint32_t value)
|
||||||
{
|
{
|
||||||
uint32_t reg;
|
uint32_t reg;
|
||||||
|
|
||||||
reg = read(base_addr, offset);
|
reg = read(offset);
|
||||||
|
|
||||||
reg &= ~BIT(bit);
|
reg &= ~BIT(bit);
|
||||||
reg |= value << bit;
|
reg |= value << bit;
|
||||||
|
|
||||||
write(base_addr, offset, reg);
|
write(offset, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -90,37 +92,37 @@ gpio_isr(void)
|
||||||
{
|
{
|
||||||
uint32_t int_status;
|
uint32_t int_status;
|
||||||
|
|
||||||
int_status = read(data.pci.mmio, INTSTATUS);
|
int_status = read(INTSTATUS);
|
||||||
|
|
||||||
if (data.callback)
|
if (data.callback)
|
||||||
data.callback(int_status);
|
data.callback(int_status);
|
||||||
|
|
||||||
write(data.pci.mmio, PORTA_EOI, -1);
|
write(PORTA_EOI, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gpio_interrupt_config(uint8_t pin, int flags)
|
gpio_interrupt_config(uint8_t pin, int flags)
|
||||||
{
|
{
|
||||||
/* set as input */
|
/* set as input */
|
||||||
set_bit(data.pci.mmio, SWPORTA_DDR, pin, 0);
|
set_bit(SWPORTA_DDR, pin, 0);
|
||||||
|
|
||||||
/* set interrupt enabled */
|
/* set interrupt enabled */
|
||||||
set_bit(data.pci.mmio, INTEN, pin, 1);
|
set_bit(INTEN, pin, 1);
|
||||||
|
|
||||||
/* unmask interrupt */
|
/* unmask interrupt */
|
||||||
set_bit(data.pci.mmio, INTMASK, pin, 0);
|
set_bit(INTMASK, pin, 0);
|
||||||
|
|
||||||
/* set active high/low */
|
/* set active high/low */
|
||||||
set_bit(data.pci.mmio, INT_POLARITY, pin, !!(flags & QUARKX1000_GPIO_ACTIVE_HIGH));
|
set_bit(INT_POLARITY, pin, !!(flags & QUARKX1000_GPIO_ACTIVE_HIGH));
|
||||||
|
|
||||||
/* set level/edge */
|
/* set level/edge */
|
||||||
set_bit(data.pci.mmio, INTTYPE_LEVEL, pin, !!(flags & QUARKX1000_GPIO_EDGE));
|
set_bit(INTTYPE_LEVEL, pin, !!(flags & QUARKX1000_GPIO_EDGE));
|
||||||
|
|
||||||
/* set debounce */
|
/* set debounce */
|
||||||
set_bit(data.pci.mmio, DEBOUNCE, pin, !!(flags & QUARKX1000_GPIO_DEBOUNCE));
|
set_bit(DEBOUNCE, pin, !!(flags & QUARKX1000_GPIO_DEBOUNCE));
|
||||||
|
|
||||||
/* set clock synchronous */
|
/* set clock synchronous */
|
||||||
set_bit(data.pci.mmio, LS_SYNC, 0, !!(flags & QUARKX1000_GPIO_CLOCK_SYNC));
|
set_bit(LS_SYNC, 0, !!(flags & QUARKX1000_GPIO_CLOCK_SYNC));
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -135,10 +137,10 @@ quarkX1000_gpio_config(uint8_t pin, int flags)
|
||||||
gpio_interrupt_config(pin, flags);
|
gpio_interrupt_config(pin, flags);
|
||||||
} else {
|
} else {
|
||||||
/* set direction */
|
/* set direction */
|
||||||
set_bit(data.pci.mmio, SWPORTA_DDR, pin, !!(flags & QUARKX1000_GPIO_OUT));
|
set_bit(SWPORTA_DDR, pin, !!(flags & QUARKX1000_GPIO_OUT));
|
||||||
|
|
||||||
/* set interrupt disabled */
|
/* set interrupt disabled */
|
||||||
set_bit(data.pci.mmio, INTEN, pin, 0);
|
set_bit(INTEN, pin, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -161,7 +163,7 @@ quarkX1000_gpio_config_port(int flags)
|
||||||
int
|
int
|
||||||
quarkX1000_gpio_read(uint8_t pin, uint8_t *value)
|
quarkX1000_gpio_read(uint8_t pin, uint8_t *value)
|
||||||
{
|
{
|
||||||
uint32_t value32 = read(data.pci.mmio, EXT_PORTA);
|
uint32_t value32 = read(EXT_PORTA);
|
||||||
*value = !!(value32 & BIT(pin));
|
*value = !!(value32 & BIT(pin));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -170,14 +172,14 @@ quarkX1000_gpio_read(uint8_t pin, uint8_t *value)
|
||||||
int
|
int
|
||||||
quarkX1000_gpio_write(uint8_t pin, uint8_t value)
|
quarkX1000_gpio_write(uint8_t pin, uint8_t value)
|
||||||
{
|
{
|
||||||
set_bit(data.pci.mmio, SWPORTA_DR, pin, !!value);
|
set_bit(SWPORTA_DR, pin, !!value);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
quarkX1000_gpio_read_port(uint8_t *value)
|
quarkX1000_gpio_read_port(uint8_t *value)
|
||||||
{
|
{
|
||||||
uint32_t value32 = read(data.pci.mmio, EXT_PORTA);
|
uint32_t value32 = read(EXT_PORTA);
|
||||||
*value = value32 & ~0xFFFFFF00;
|
*value = value32 & ~0xFFFFFF00;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -186,7 +188,7 @@ quarkX1000_gpio_read_port(uint8_t *value)
|
||||||
int
|
int
|
||||||
quarkX1000_gpio_write_port(uint8_t value)
|
quarkX1000_gpio_write_port(uint8_t value)
|
||||||
{
|
{
|
||||||
write(data.pci.mmio, SWPORTA_DR, value);
|
write(SWPORTA_DR, value);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,13 +202,13 @@ quarkX1000_gpio_set_callback(quarkX1000_gpio_callback callback)
|
||||||
void
|
void
|
||||||
quarkX1000_gpio_clock_enable(void)
|
quarkX1000_gpio_clock_enable(void)
|
||||||
{
|
{
|
||||||
set_bit(data.pci.mmio, LS_SYNC, 0, 1);
|
set_bit(LS_SYNC, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
quarkX1000_gpio_clock_disable(void)
|
quarkX1000_gpio_clock_disable(void)
|
||||||
{
|
{
|
||||||
set_bit(data.pci.mmio, LS_SYNC, 0, 0);
|
set_bit(LS_SYNC, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -244,9 +246,9 @@ quarkX1000_gpio_init(void)
|
||||||
quarkX1000_gpio_clock_enable();
|
quarkX1000_gpio_clock_enable();
|
||||||
|
|
||||||
/* clear registers */
|
/* clear registers */
|
||||||
write(data.pci.mmio, INTEN, 0);
|
write(INTEN, 0);
|
||||||
write(data.pci.mmio, INTMASK, 0);
|
write(INTMASK, 0);
|
||||||
write(data.pci.mmio, PORTA_EOI, 0);
|
write(PORTA_EOI, 0);
|
||||||
|
|
||||||
pic_unmask_irq(GPIO_IRQ);
|
pic_unmask_irq(GPIO_IRQ);
|
||||||
|
|
||||||
|
|
|
@ -75,21 +75,23 @@ struct i2c_internal_data {
|
||||||
static struct i2c_internal_data device;
|
static struct i2c_internal_data device;
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
read(uint32_t base_addr, uint32_t offset)
|
read(uint32_t offset)
|
||||||
{
|
{
|
||||||
return *(uint32_t*)(base_addr + offset);
|
uint32_t res;
|
||||||
|
PCI_MMIO_READL(device.pci, res, offset);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
write(uint32_t base_addr, uint32_t offset, uint32_t val)
|
write(uint32_t offset, uint32_t val)
|
||||||
{
|
{
|
||||||
*(uint32_t*)(base_addr + offset) = val;
|
PCI_MMIO_WRITEL(device.pci, offset, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
get_value(uint32_t base_addr, uint32_t offset, uint32_t mask, uint32_t shift)
|
get_value(uint32_t offset, uint32_t mask, uint32_t shift)
|
||||||
{
|
{
|
||||||
uint32_t register_value = *(uint32_t*)(base_addr + offset);
|
uint32_t register_value = read(offset);
|
||||||
|
|
||||||
register_value &= ~(0xFFFFFFFF - mask);
|
register_value &= ~(0xFFFFFFFF - mask);
|
||||||
|
|
||||||
|
@ -97,12 +99,14 @@ get_value(uint32_t base_addr, uint32_t offset, uint32_t mask, uint32_t shift)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_value(uint32_t base_addr, uint32_t offset, uint32_t mask, uint32_t shift, uint32_t value)
|
set_value(uint32_t offset, uint32_t mask, uint32_t shift, uint32_t value)
|
||||||
{
|
{
|
||||||
volatile uint32_t *register_value = (volatile uint32_t*)(base_addr + offset);
|
uint32_t register_value = read(offset);
|
||||||
|
|
||||||
*register_value &= ~mask;
|
register_value &= ~mask;
|
||||||
*register_value |= value << shift;
|
register_value |= value << shift;
|
||||||
|
|
||||||
|
write(offset, register_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -113,14 +117,14 @@ i2c_data_read(void)
|
||||||
if (device.rx_len == 0)
|
if (device.rx_len == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rx_cnt = get_value(device.pci.mmio, QUARKX1000_IC_RXFLR,
|
rx_cnt = get_value(QUARKX1000_IC_RXFLR,
|
||||||
QUARKX1000_IC_RXFLR_MASK, QUARKX1000_IC_RXFLR_SHIFT);
|
QUARKX1000_IC_RXFLR_MASK, QUARKX1000_IC_RXFLR_SHIFT);
|
||||||
|
|
||||||
if (rx_cnt > device.rx_len)
|
if (rx_cnt > device.rx_len)
|
||||||
rx_cnt = device.rx_len;
|
rx_cnt = device.rx_len;
|
||||||
|
|
||||||
for (i = 0; i < rx_cnt; i++) {
|
for (i = 0; i < rx_cnt; i++) {
|
||||||
device.rx_buffer[i] = get_value(device.pci.mmio, QUARKX1000_IC_DATA_CMD,
|
device.rx_buffer[i] = get_value(QUARKX1000_IC_DATA_CMD,
|
||||||
QUARKX1000_IC_DATA_CMD_DAT_MASK, QUARKX1000_IC_DATA_CMD_DAT_SHIFT);
|
QUARKX1000_IC_DATA_CMD_DAT_MASK, QUARKX1000_IC_DATA_CMD_DAT_SHIFT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +141,7 @@ i2c_data_send(void)
|
||||||
if (device.rx_tx_len == 0)
|
if (device.rx_tx_len == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tx_cnt = I2C_FIFO_DEPTH - get_value(device.pci.mmio, QUARKX1000_IC_TXFLR,
|
tx_cnt = I2C_FIFO_DEPTH - get_value(QUARKX1000_IC_TXFLR,
|
||||||
QUARKX1000_IC_TXFLR_MASK, QUARKX1000_IC_TXFLR_SHIFT);
|
QUARKX1000_IC_TXFLR_MASK, QUARKX1000_IC_TXFLR_SHIFT);
|
||||||
|
|
||||||
if (tx_cnt > device.rx_tx_len)
|
if (tx_cnt > device.rx_tx_len)
|
||||||
|
@ -158,7 +162,7 @@ i2c_data_send(void)
|
||||||
data |= QUARKX1000_IC_DATA_CMD_STOP_MASK;
|
data |= QUARKX1000_IC_DATA_CMD_STOP_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
write(device.pci.mmio, QUARKX1000_IC_DATA_CMD, data);
|
write(QUARKX1000_IC_DATA_CMD, data);
|
||||||
device.rx_tx_len -= 1;
|
device.rx_tx_len -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,11 +172,11 @@ i2c_data_send(void)
|
||||||
static void
|
static void
|
||||||
i2c_isr(void)
|
i2c_isr(void)
|
||||||
{
|
{
|
||||||
if (read(device.pci.mmio, QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_STOP_DET_MASK) {
|
if (read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_STOP_DET_MASK) {
|
||||||
i2c_data_read();
|
i2c_data_read();
|
||||||
|
|
||||||
write(device.pci.mmio, QUARKX1000_IC_INTR_MASK, 0);
|
write(QUARKX1000_IC_INTR_MASK, 0);
|
||||||
read(device.pci.mmio, QUARKX1000_IC_CLR_INTR);
|
read(QUARKX1000_IC_CLR_INTR);
|
||||||
|
|
||||||
if (device.direction == I2C_DIRECTION_WRITE) {
|
if (device.direction == I2C_DIRECTION_WRITE) {
|
||||||
if (device.config.cb_tx)
|
if (device.config.cb_tx)
|
||||||
|
@ -183,24 +187,24 @@ i2c_isr(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read(device.pci.mmio, QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK) {
|
if (read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK) {
|
||||||
i2c_data_send();
|
i2c_data_send();
|
||||||
if (device.rx_tx_len <= 0) {
|
if (device.rx_tx_len <= 0) {
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_INTR_MASK,
|
set_value(QUARKX1000_IC_INTR_MASK,
|
||||||
QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK, QUARKX1000_IC_INTR_STAT_TX_EMPTY_SHIFT, 0);
|
QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK, QUARKX1000_IC_INTR_STAT_TX_EMPTY_SHIFT, 0);
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_INTR_MASK,
|
set_value(QUARKX1000_IC_INTR_MASK,
|
||||||
QUARKX1000_IC_INTR_STAT_STOP_DET_MASK, QUARKX1000_IC_INTR_STAT_STOP_DET_SHIFT, 1);
|
QUARKX1000_IC_INTR_STAT_STOP_DET_MASK, QUARKX1000_IC_INTR_STAT_STOP_DET_SHIFT, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (read(device.pci.mmio, QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_RX_FULL_MASK)
|
if (read(QUARKX1000_IC_INTR_STAT) & QUARKX1000_IC_INTR_STAT_RX_FULL_MASK)
|
||||||
i2c_data_read();
|
i2c_data_read();
|
||||||
|
|
||||||
if (read(device.pci.mmio, QUARKX1000_IC_INTR_STAT) & (QUARKX1000_IC_INTR_STAT_TX_ABRT_MASK
|
if (read(QUARKX1000_IC_INTR_STAT) & (QUARKX1000_IC_INTR_STAT_TX_ABRT_MASK
|
||||||
| QUARKX1000_IC_INTR_STAT_TX_OVER_MASK | QUARKX1000_IC_INTR_STAT_RX_OVER_MASK
|
| QUARKX1000_IC_INTR_STAT_TX_OVER_MASK | QUARKX1000_IC_INTR_STAT_RX_OVER_MASK
|
||||||
| QUARKX1000_IC_INTR_STAT_RX_UNDER_MASK)) {
|
| QUARKX1000_IC_INTR_STAT_RX_UNDER_MASK)) {
|
||||||
write(device.pci.mmio, QUARKX1000_IC_INTR_MASK, 0);
|
write(QUARKX1000_IC_INTR_MASK, 0);
|
||||||
read(device.pci.mmio, QUARKX1000_IC_CLR_INTR);
|
read(QUARKX1000_IC_CLR_INTR);
|
||||||
|
|
||||||
if (device.config.cb_err)
|
if (device.config.cb_err)
|
||||||
device.config.cb_err();
|
device.config.cb_err();
|
||||||
|
@ -227,7 +231,7 @@ quarkX1000_i2c_configure(struct quarkX1000_i2c_config *config)
|
||||||
hcnt = I2C_FS_HCNT;
|
hcnt = I2C_FS_HCNT;
|
||||||
}
|
}
|
||||||
|
|
||||||
ic_fs_spklen = get_value(device.pci.mmio, QUARKX1000_IC_FS_SPKLEN,
|
ic_fs_spklen = get_value(QUARKX1000_IC_FS_SPKLEN,
|
||||||
QUARKX1000_IC_FS_SPKLEN_MASK, QUARKX1000_IC_FS_SPKLEN_SHIFT);
|
QUARKX1000_IC_FS_SPKLEN_MASK, QUARKX1000_IC_FS_SPKLEN_SHIFT);
|
||||||
|
|
||||||
/* We adjust the Low Count and High Count based on the Spike Suppression Limit */
|
/* We adjust the Low Count and High Count based on the Spike Suppression Limit */
|
||||||
|
@ -235,7 +239,7 @@ quarkX1000_i2c_configure(struct quarkX1000_i2c_config *config)
|
||||||
device.hcnt = (hcnt < (ic_fs_spklen + I2C_FS_SPKLEN_HCNT_OFFSET)) ? ic_fs_spklen + I2C_FS_SPKLEN_HCNT_OFFSET : hcnt;
|
device.hcnt = (hcnt < (ic_fs_spklen + I2C_FS_SPKLEN_HCNT_OFFSET)) ? ic_fs_spklen + I2C_FS_SPKLEN_HCNT_OFFSET : hcnt;
|
||||||
|
|
||||||
/* Clear interrupts. */
|
/* Clear interrupts. */
|
||||||
read(device.pci.mmio, QUARKX1000_IC_CLR_INTR);
|
read(QUARKX1000_IC_CLR_INTR);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -244,38 +248,38 @@ static int
|
||||||
i2c_setup(void)
|
i2c_setup(void)
|
||||||
{
|
{
|
||||||
/* Clear all values */
|
/* Clear all values */
|
||||||
write(device.pci.mmio, QUARKX1000_IC_CON, 0);
|
write(QUARKX1000_IC_CON, 0);
|
||||||
|
|
||||||
/* Clear interrupts */
|
/* Clear interrupts */
|
||||||
read(device.pci.mmio, QUARKX1000_IC_CLR_INTR);
|
read(QUARKX1000_IC_CLR_INTR);
|
||||||
|
|
||||||
/* Quark X1000 SoC I2C only supports master mode. */
|
/* Quark X1000 SoC I2C only supports master mode. */
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_CON,
|
set_value(QUARKX1000_IC_CON,
|
||||||
QUARKX1000_IC_CON_MASTER_MODE_MASK, QUARKX1000_IC_CON_MASTER_MODE_SHIFT, 1);
|
QUARKX1000_IC_CON_MASTER_MODE_MASK, QUARKX1000_IC_CON_MASTER_MODE_SHIFT, 1);
|
||||||
|
|
||||||
/* Set restart enable */
|
/* Set restart enable */
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_CON,
|
set_value(QUARKX1000_IC_CON,
|
||||||
QUARKX1000_IC_CON_RESTART_EN_MASK, QUARKX1000_IC_CON_RESTART_EN_SHIFT, 1);
|
QUARKX1000_IC_CON_RESTART_EN_MASK, QUARKX1000_IC_CON_RESTART_EN_SHIFT, 1);
|
||||||
|
|
||||||
/* Set addressing mode */
|
/* Set addressing mode */
|
||||||
if (device.config.addressing_mode == QUARKX1000_I2C_ADDR_MODE_10BIT) {
|
if (device.config.addressing_mode == QUARKX1000_I2C_ADDR_MODE_10BIT) {
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_CON,
|
set_value(QUARKX1000_IC_CON,
|
||||||
QUARKX1000_IC_CON_10BITADDR_MASTER_MASK, QUARKX1000_IC_CON_10BITADDR_MASTER_SHIFT, 1);
|
QUARKX1000_IC_CON_10BITADDR_MASTER_MASK, QUARKX1000_IC_CON_10BITADDR_MASTER_SHIFT, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (device.config.speed == QUARKX1000_I2C_SPEED_STANDARD) {
|
if (device.config.speed == QUARKX1000_I2C_SPEED_STANDARD) {
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_SS_SCL_LCNT,
|
set_value(QUARKX1000_IC_SS_SCL_LCNT,
|
||||||
QUARKX1000_IC_SS_SCL_LCNT_MASK, QUARKX1000_IC_SS_SCL_LCNT_SHIFT, device.lcnt);
|
QUARKX1000_IC_SS_SCL_LCNT_MASK, QUARKX1000_IC_SS_SCL_LCNT_SHIFT, device.lcnt);
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_SS_SCL_HCNT,
|
set_value(QUARKX1000_IC_SS_SCL_HCNT,
|
||||||
QUARKX1000_IC_SS_SCL_HCNT_MASK, QUARKX1000_IC_SS_SCL_HCNT_SHIFT, device.hcnt);
|
QUARKX1000_IC_SS_SCL_HCNT_MASK, QUARKX1000_IC_SS_SCL_HCNT_SHIFT, device.hcnt);
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_CON,
|
set_value(QUARKX1000_IC_CON,
|
||||||
QUARKX1000_IC_CON_SPEED_MASK, QUARKX1000_IC_CON_SPEED_SHIFT, 0x1);
|
QUARKX1000_IC_CON_SPEED_MASK, QUARKX1000_IC_CON_SPEED_SHIFT, 0x1);
|
||||||
} else {
|
} else {
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_FS_SCL_LCNT,
|
set_value(QUARKX1000_IC_FS_SCL_LCNT,
|
||||||
QUARKX1000_IC_FS_SCL_LCNT_MASK, QUARKX1000_IC_FS_SCL_LCNT_SHIFT, device.lcnt);
|
QUARKX1000_IC_FS_SCL_LCNT_MASK, QUARKX1000_IC_FS_SCL_LCNT_SHIFT, device.lcnt);
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_FS_SCL_HCNT,
|
set_value(QUARKX1000_IC_FS_SCL_HCNT,
|
||||||
QUARKX1000_IC_FS_SCL_HCNT_MASK, QUARKX1000_IC_FS_SCL_HCNT_SHIFT, device.hcnt);
|
QUARKX1000_IC_FS_SCL_HCNT_MASK, QUARKX1000_IC_FS_SCL_HCNT_SHIFT, device.hcnt);
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_CON,
|
set_value(QUARKX1000_IC_CON,
|
||||||
QUARKX1000_IC_CON_SPEED_MASK, QUARKX1000_IC_CON_SPEED_SHIFT, 0x2);
|
QUARKX1000_IC_CON_SPEED_MASK, QUARKX1000_IC_CON_SPEED_SHIFT, 0x2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,19 +297,19 @@ i2c_operation_setup(uint8_t *write_buf, uint8_t write_len,
|
||||||
device.rx_tx_len = device.rx_len + device.tx_len;
|
device.rx_tx_len = device.rx_len + device.tx_len;
|
||||||
|
|
||||||
/* Disable controller */
|
/* Disable controller */
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_ENABLE,
|
set_value(QUARKX1000_IC_ENABLE,
|
||||||
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
|
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
|
||||||
|
|
||||||
i2c_setup();
|
i2c_setup();
|
||||||
|
|
||||||
/* Disable interrupts */
|
/* Disable interrupts */
|
||||||
write(device.pci.mmio, QUARKX1000_IC_INTR_MASK, 0);
|
write(QUARKX1000_IC_INTR_MASK, 0);
|
||||||
|
|
||||||
/* Clear interrupts */
|
/* Clear interrupts */
|
||||||
read(device.pci.mmio, QUARKX1000_IC_CLR_INTR);
|
read(QUARKX1000_IC_CLR_INTR);
|
||||||
|
|
||||||
/* Set address of target slave */
|
/* Set address of target slave */
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_TAR,
|
set_value(QUARKX1000_IC_TAR,
|
||||||
QUARKX1000_IC_TAR_MASK, QUARKX1000_IC_TAR_SHIFT, addr);
|
QUARKX1000_IC_TAR_MASK, QUARKX1000_IC_TAR_SHIFT, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,29 +318,29 @@ static int
|
||||||
i2c_operation(uint8_t *write_buf, uint8_t write_len,
|
i2c_operation(uint8_t *write_buf, uint8_t write_len,
|
||||||
uint8_t *read_buf, uint8_t read_len, uint16_t addr)
|
uint8_t *read_buf, uint8_t read_len, uint16_t addr)
|
||||||
{
|
{
|
||||||
if (read(device.pci.mmio, QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_ACTIVITY_MASK)
|
if (read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_ACTIVITY_MASK)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
i2c_operation_setup(write_buf, write_len, read_buf, read_len, addr);
|
i2c_operation_setup(write_buf, write_len, read_buf, read_len, addr);
|
||||||
|
|
||||||
/* Enable master TX and RX interrupts */
|
/* Enable master TX and RX interrupts */
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_INTR_MASK,
|
set_value(QUARKX1000_IC_INTR_MASK,
|
||||||
QUARKX1000_IC_INTR_STAT_TX_OVER_MASK, QUARKX1000_IC_INTR_STAT_TX_OVER_SHIFT, 1);
|
QUARKX1000_IC_INTR_STAT_TX_OVER_MASK, QUARKX1000_IC_INTR_STAT_TX_OVER_SHIFT, 1);
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_INTR_MASK,
|
set_value(QUARKX1000_IC_INTR_MASK,
|
||||||
QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK, QUARKX1000_IC_INTR_STAT_TX_EMPTY_SHIFT, 1);
|
QUARKX1000_IC_INTR_STAT_TX_EMPTY_MASK, QUARKX1000_IC_INTR_STAT_TX_EMPTY_SHIFT, 1);
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_INTR_MASK,
|
set_value(QUARKX1000_IC_INTR_MASK,
|
||||||
QUARKX1000_IC_INTR_STAT_TX_ABRT_MASK, QUARKX1000_IC_INTR_STAT_TX_ABRT_SHIFT, 1);
|
QUARKX1000_IC_INTR_STAT_TX_ABRT_MASK, QUARKX1000_IC_INTR_STAT_TX_ABRT_SHIFT, 1);
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_INTR_MASK,
|
set_value(QUARKX1000_IC_INTR_MASK,
|
||||||
QUARKX1000_IC_INTR_STAT_RX_UNDER_MASK, QUARKX1000_IC_INTR_STAT_RX_UNDER_SHIFT, 1);
|
QUARKX1000_IC_INTR_STAT_RX_UNDER_MASK, QUARKX1000_IC_INTR_STAT_RX_UNDER_SHIFT, 1);
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_INTR_MASK,
|
set_value(QUARKX1000_IC_INTR_MASK,
|
||||||
QUARKX1000_IC_INTR_STAT_RX_OVER_MASK, QUARKX1000_IC_INTR_STAT_RX_OVER_SHIFT, 1);
|
QUARKX1000_IC_INTR_STAT_RX_OVER_MASK, QUARKX1000_IC_INTR_STAT_RX_OVER_SHIFT, 1);
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_INTR_MASK,
|
set_value(QUARKX1000_IC_INTR_MASK,
|
||||||
QUARKX1000_IC_INTR_STAT_RX_FULL_MASK, QUARKX1000_IC_INTR_STAT_RX_FULL_SHIFT, 1);
|
QUARKX1000_IC_INTR_STAT_RX_FULL_MASK, QUARKX1000_IC_INTR_STAT_RX_FULL_SHIFT, 1);
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_INTR_MASK,
|
set_value(QUARKX1000_IC_INTR_MASK,
|
||||||
QUARKX1000_IC_INTR_STAT_STOP_DET_MASK, QUARKX1000_IC_INTR_STAT_STOP_DET_SHIFT, 1);
|
QUARKX1000_IC_INTR_STAT_STOP_DET_MASK, QUARKX1000_IC_INTR_STAT_STOP_DET_SHIFT, 1);
|
||||||
|
|
||||||
/* Enable controller */
|
/* Enable controller */
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_ENABLE,
|
set_value(QUARKX1000_IC_ENABLE,
|
||||||
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 1);
|
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 1);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -364,33 +368,33 @@ i2c_polling_operation(uint8_t *write_buf, uint8_t write_len,
|
||||||
{
|
{
|
||||||
uint32_t start_time, intr_mask_stat;
|
uint32_t start_time, intr_mask_stat;
|
||||||
|
|
||||||
if (!(read(device.pci.mmio, QUARKX1000_IC_CON) & QUARKX1000_IC_CON_MASTER_MODE_MASK))
|
if (!(read(QUARKX1000_IC_CON) & QUARKX1000_IC_CON_MASTER_MODE_MASK))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Wait i2c idle */
|
/* Wait i2c idle */
|
||||||
start_time = clock_seconds();
|
start_time = clock_seconds();
|
||||||
while (read(device.pci.mmio, QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_ACTIVITY_MASK) {
|
while (read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_ACTIVITY_MASK) {
|
||||||
if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
|
if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get interrupt mask to restore in the end of polling operation */
|
/* Get interrupt mask to restore in the end of polling operation */
|
||||||
intr_mask_stat = read(device.pci.mmio, QUARKX1000_IC_INTR_MASK);
|
intr_mask_stat = read(QUARKX1000_IC_INTR_MASK);
|
||||||
|
|
||||||
i2c_operation_setup(write_buf, write_len, read_buf, read_len, addr);
|
i2c_operation_setup(write_buf, write_len, read_buf, read_len, addr);
|
||||||
|
|
||||||
/* Enable controller */
|
/* Enable controller */
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_ENABLE,
|
set_value(QUARKX1000_IC_ENABLE,
|
||||||
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 1);
|
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 1);
|
||||||
|
|
||||||
/* Transmit */
|
/* Transmit */
|
||||||
if (device.tx_len != 0) {
|
if (device.tx_len != 0) {
|
||||||
while (device.tx_len > 0) {
|
while (device.tx_len > 0) {
|
||||||
start_time = clock_seconds();
|
start_time = clock_seconds();
|
||||||
while (!(read(device.pci.mmio, QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_TFNF_MASK)) {
|
while (!(read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_TFNF_MASK)) {
|
||||||
if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
|
if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_ENABLE,
|
set_value(QUARKX1000_IC_ENABLE,
|
||||||
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
|
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -399,9 +403,9 @@ i2c_polling_operation(uint8_t *write_buf, uint8_t write_len,
|
||||||
}
|
}
|
||||||
|
|
||||||
start_time = clock_seconds();
|
start_time = clock_seconds();
|
||||||
while (!(read(device.pci.mmio, QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_TFE_MASK)) {
|
while (!(read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_TFE_MASK)) {
|
||||||
if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
|
if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_ENABLE,
|
set_value(QUARKX1000_IC_ENABLE,
|
||||||
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
|
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -414,9 +418,9 @@ i2c_polling_operation(uint8_t *write_buf, uint8_t write_len,
|
||||||
if (device.rx_len != 0) {
|
if (device.rx_len != 0) {
|
||||||
while (device.rx_len > 0) {
|
while (device.rx_len > 0) {
|
||||||
start_time = clock_seconds();
|
start_time = clock_seconds();
|
||||||
while (!(read(device.pci.mmio, QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_RFNE_MASK)) {
|
while (!(read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_RFNE_MASK)) {
|
||||||
if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
|
if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_ENABLE,
|
set_value(QUARKX1000_IC_ENABLE,
|
||||||
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
|
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -427,31 +431,31 @@ i2c_polling_operation(uint8_t *write_buf, uint8_t write_len,
|
||||||
|
|
||||||
/* Stop Det */
|
/* Stop Det */
|
||||||
start_time = clock_seconds();
|
start_time = clock_seconds();
|
||||||
while (!(read(device.pci.mmio, QUARKX1000_IC_RAW_INTR_STAT) & QUARKX1000_IC_INTR_STAT_STOP_DET_MASK)) {
|
while (!(read(QUARKX1000_IC_RAW_INTR_STAT) & QUARKX1000_IC_INTR_STAT_STOP_DET_MASK)) {
|
||||||
if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
|
if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_ENABLE,
|
set_value(QUARKX1000_IC_ENABLE,
|
||||||
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
|
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
read(device.pci.mmio, QUARKX1000_IC_CLR_STOP_DET);
|
read(QUARKX1000_IC_CLR_STOP_DET);
|
||||||
|
|
||||||
/* Wait i2c idle */
|
/* Wait i2c idle */
|
||||||
start_time = clock_seconds();
|
start_time = clock_seconds();
|
||||||
while (read(device.pci.mmio, QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_ACTIVITY_MASK) {
|
while (read(QUARKX1000_IC_STATUS) & QUARKX1000_IC_STATUS_ACTIVITY_MASK) {
|
||||||
if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
|
if ((clock_seconds() - start_time) > I2C_POLLING_TIMEOUT) {
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_ENABLE,
|
set_value(QUARKX1000_IC_ENABLE,
|
||||||
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
|
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable controller */
|
/* Disable controller */
|
||||||
set_value(device.pci.mmio, QUARKX1000_IC_ENABLE,
|
set_value(QUARKX1000_IC_ENABLE,
|
||||||
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
|
QUARKX1000_IC_ENABLE_MASK, QUARKX1000_IC_ENABLE_SHIFT, 0);
|
||||||
|
|
||||||
/* Restore interrupt mask */
|
/* Restore interrupt mask */
|
||||||
write(device.pci.mmio, QUARKX1000_IC_INTR_MASK, intr_mask_stat);
|
write(QUARKX1000_IC_INTR_MASK, intr_mask_stat);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue