drivers: gpio: it8xxx2: add support for GPIO_VOLTAGE_ flags

Support GPIO_VOLTAGE_1P8, GPIO_VOLTAGE_3P3 flags on IT8xxx2 chips.

Signed-off-by: Dino Li <Dino.Li@ite.com.tw>
This commit is contained in:
Dino Li 2021-05-04 15:10:50 +08:00 committed by Kumar Gala
commit b316d18cb0
2 changed files with 161 additions and 5 deletions

View file

@ -31,6 +31,8 @@ struct gpio_ite_cfg {
uintptr_t reg_gpdmr;
/* gpio port output type register (bit mapping to pin) */
uintptr_t reg_gpotr;
/* Index in gpio_1p8v for voltage level control register element. */
uint8_t index;
/* gpio's irq */
uint8_t gpio_irq[8];
};
@ -222,6 +224,122 @@ static const struct {
};
BUILD_ASSERT(ARRAY_SIZE(gpio_irqs) == IT8XXX2_IRQ_COUNT + 1);
/* 1.8v gpio group a, b, c, d, e, f, g, h, i, j, k, l, and m */
#define GPIO_GROUP_COUNT 13
#define GPIO_GROUP_INDEX(label) \
(uint8_t)(DT_REG_ADDR(DT_NODELABEL(label)) - \
DT_REG_ADDR(DT_NODELABEL(gpioa)))
/* general control registers for selecting 1.8V/3.3V */
static const struct {
uint8_t offset;
uint8_t mask_1p8v;
} gpio_1p8v[GPIO_GROUP_COUNT][8] = {
[GPIO_GROUP_INDEX(gpioa)] = {
[4] = {IT8XXX2_GPIO_GCR24_OFFSET, BIT(0)},
[5] = {IT8XXX2_GPIO_GCR24_OFFSET, BIT(1)},
[6] = {IT8XXX2_GPIO_GCR24_OFFSET, BIT(5)},
[7] = {IT8XXX2_GPIO_GCR24_OFFSET, BIT(6)} },
[GPIO_GROUP_INDEX(gpiob)] = {
[3] = {IT8XXX2_GPIO_GCR22_OFFSET, BIT(1)},
[4] = {IT8XXX2_GPIO_GCR22_OFFSET, BIT(0)},
[5] = {IT8XXX2_GPIO_GCR19_OFFSET, BIT(7)},
[6] = {IT8XXX2_GPIO_GCR19_OFFSET, BIT(6)},
[7] = {IT8XXX2_GPIO_GCR24_OFFSET, BIT(4)} },
[GPIO_GROUP_INDEX(gpioc)] = {
[0] = {IT8XXX2_GPIO_GCR22_OFFSET, BIT(7)},
[1] = {IT8XXX2_GPIO_GCR19_OFFSET, BIT(5)},
[2] = {IT8XXX2_GPIO_GCR19_OFFSET, BIT(4)},
[4] = {IT8XXX2_GPIO_GCR24_OFFSET, BIT(2)},
[6] = {IT8XXX2_GPIO_GCR24_OFFSET, BIT(3)},
[7] = {IT8XXX2_GPIO_GCR19_OFFSET, BIT(3)} },
[GPIO_GROUP_INDEX(gpiod)] = {
[0] = {IT8XXX2_GPIO_GCR19_OFFSET, BIT(2)},
[1] = {IT8XXX2_GPIO_GCR19_OFFSET, BIT(1)},
[2] = {IT8XXX2_GPIO_GCR19_OFFSET, BIT(0)},
[3] = {IT8XXX2_GPIO_GCR20_OFFSET, BIT(7)},
[4] = {IT8XXX2_GPIO_GCR20_OFFSET, BIT(6)},
[5] = {IT8XXX2_GPIO_GCR22_OFFSET, BIT(4)},
[6] = {IT8XXX2_GPIO_GCR22_OFFSET, BIT(5)},
[7] = {IT8XXX2_GPIO_GCR22_OFFSET, BIT(6)} },
[GPIO_GROUP_INDEX(gpioe)] = {
[0] = {IT8XXX2_GPIO_GCR20_OFFSET, BIT(5)},
[1] = {IT8XXX2_GPIO_GCR28_OFFSET, BIT(6)},
[2] = {IT8XXX2_GPIO_GCR28_OFFSET, BIT(7)},
[4] = {IT8XXX2_GPIO_GCR22_OFFSET, BIT(2)},
[5] = {IT8XXX2_GPIO_GCR22_OFFSET, BIT(3)},
[6] = {IT8XXX2_GPIO_GCR20_OFFSET, BIT(4)},
[7] = {IT8XXX2_GPIO_GCR20_OFFSET, BIT(3)} },
[GPIO_GROUP_INDEX(gpiof)] = {
[0] = {IT8XXX2_GPIO_GCR28_OFFSET, BIT(4)},
[1] = {IT8XXX2_GPIO_GCR28_OFFSET, BIT(5)},
[2] = {IT8XXX2_GPIO_GCR20_OFFSET, BIT(2)},
[3] = {IT8XXX2_GPIO_GCR20_OFFSET, BIT(1)},
[4] = {IT8XXX2_GPIO_GCR20_OFFSET, BIT(0)},
[5] = {IT8XXX2_GPIO_GCR21_OFFSET, BIT(7)},
[6] = {IT8XXX2_GPIO_GCR21_OFFSET, BIT(6)},
[7] = {IT8XXX2_GPIO_GCR21_OFFSET, BIT(5)} },
[GPIO_GROUP_INDEX(gpiog)] = {
[0] = {IT8XXX2_GPIO_GCR28_OFFSET, BIT(2)},
[1] = {IT8XXX2_GPIO_GCR21_OFFSET, BIT(4)},
[2] = {IT8XXX2_GPIO_GCR28_OFFSET, BIT(3)},
[6] = {IT8XXX2_GPIO_GCR21_OFFSET, BIT(3)} },
[GPIO_GROUP_INDEX(gpioh)] = {
[0] = {IT8XXX2_GPIO_GCR21_OFFSET, BIT(2)},
[1] = {IT8XXX2_GPIO_GCR21_OFFSET, BIT(1)},
[2] = {IT8XXX2_GPIO_GCR21_OFFSET, BIT(0)},
[5] = {IT8XXX2_GPIO_GCR27_OFFSET, BIT(7)},
[6] = {IT8XXX2_GPIO_GCR28_OFFSET, BIT(0)} },
[GPIO_GROUP_INDEX(gpioi)] = {
[0] = {IT8XXX2_GPIO_GCR27_OFFSET, BIT(3)},
[1] = {IT8XXX2_GPIO_GCR23_OFFSET, BIT(4)},
[2] = {IT8XXX2_GPIO_GCR23_OFFSET, BIT(5)},
[3] = {IT8XXX2_GPIO_GCR23_OFFSET, BIT(6)},
[4] = {IT8XXX2_GPIO_GCR23_OFFSET, BIT(7)},
[5] = {IT8XXX2_GPIO_GCR27_OFFSET, BIT(4)},
[6] = {IT8XXX2_GPIO_GCR27_OFFSET, BIT(5)},
[7] = {IT8XXX2_GPIO_GCR27_OFFSET, BIT(6)} },
[GPIO_GROUP_INDEX(gpioj)] = {
[0] = {IT8XXX2_GPIO_GCR23_OFFSET, BIT(0)},
[1] = {IT8XXX2_GPIO_GCR23_OFFSET, BIT(1)},
[2] = {IT8XXX2_GPIO_GCR23_OFFSET, BIT(2)},
[3] = {IT8XXX2_GPIO_GCR23_OFFSET, BIT(3)},
[4] = {IT8XXX2_GPIO_GCR27_OFFSET, BIT(0)},
[5] = {IT8XXX2_GPIO_GCR27_OFFSET, BIT(1)},
[6] = {IT8XXX2_GPIO_GCR27_OFFSET, BIT(2)},
[7] = {IT8XXX2_GPIO_GCR33_OFFSET, BIT(2)} },
[GPIO_GROUP_INDEX(gpiok)] = {
[0] = {IT8XXX2_GPIO_GCR26_OFFSET, BIT(0)},
[1] = {IT8XXX2_GPIO_GCR26_OFFSET, BIT(1)},
[2] = {IT8XXX2_GPIO_GCR26_OFFSET, BIT(2)},
[3] = {IT8XXX2_GPIO_GCR26_OFFSET, BIT(3)},
[4] = {IT8XXX2_GPIO_GCR26_OFFSET, BIT(4)},
[5] = {IT8XXX2_GPIO_GCR26_OFFSET, BIT(5)},
[6] = {IT8XXX2_GPIO_GCR26_OFFSET, BIT(6)},
[7] = {IT8XXX2_GPIO_GCR26_OFFSET, BIT(7)} },
[GPIO_GROUP_INDEX(gpiol)] = {
[0] = {IT8XXX2_GPIO_GCR25_OFFSET, BIT(0)},
[1] = {IT8XXX2_GPIO_GCR25_OFFSET, BIT(1)},
[2] = {IT8XXX2_GPIO_GCR25_OFFSET, BIT(2)},
[3] = {IT8XXX2_GPIO_GCR25_OFFSET, BIT(3)},
[4] = {IT8XXX2_GPIO_GCR25_OFFSET, BIT(4)},
[5] = {IT8XXX2_GPIO_GCR25_OFFSET, BIT(5)},
[6] = {IT8XXX2_GPIO_GCR25_OFFSET, BIT(6)},
[7] = {IT8XXX2_GPIO_GCR25_OFFSET, BIT(7)} },
/*
* M group's voltage level is according to chip's VCC is connected
* to 1.8V or 3.3V.
*/
[GPIO_GROUP_INDEX(gpiom)] = {
[0] = {IT8XXX2_GPIO_GCR30_OFFSET, BIT(4)},
[1] = {IT8XXX2_GPIO_GCR30_OFFSET, BIT(4)},
[2] = {IT8XXX2_GPIO_GCR30_OFFSET, BIT(4)},
[3] = {IT8XXX2_GPIO_GCR30_OFFSET, BIT(4)},
[4] = {IT8XXX2_GPIO_GCR30_OFFSET, BIT(4)},
[5] = {IT8XXX2_GPIO_GCR30_OFFSET, BIT(4)},
[6] = {IT8XXX2_GPIO_GCR30_OFFSET, BIT(4)} },
};
/**
* Driver functions
*/
@ -234,8 +352,13 @@ static int gpio_ite_configure(const struct device *dev,
volatile uint8_t *reg_gpdr = (uint8_t *)gpio_config->reg_gpdr;
volatile uint8_t *reg_gpcr = (uint8_t *)(gpio_config->reg_gpcr + pin);
volatile uint8_t *reg_gpotr = (uint8_t *)gpio_config->reg_gpotr;
volatile uint8_t *reg_1p8v;
volatile uint8_t mask_1p8v;
uint8_t mask = BIT(pin);
__ASSERT(gpio_config->index < GPIO_GROUP_COUNT,
"Invalid GPIO group index");
/*
* Select open drain first, so that we don't glitch the signal
* when changing the line to an output.
@ -245,6 +368,25 @@ static int gpio_ite_configure(const struct device *dev,
else
*reg_gpotr &= ~mask;
/* 1.8V or 3.3V */
reg_1p8v = &IT8XXX2_GPIO_GCRX(
gpio_1p8v[gpio_config->index][pin].offset);
mask_1p8v = gpio_1p8v[gpio_config->index][pin].mask_1p8v;
if (reg_1p8v != &IT8XXX2_GPIO_GCRX(0)) {
gpio_flags_t volt = flags & GPIO_VOLTAGE_MASK;
if (volt == GPIO_VOLTAGE_1P8) {
__ASSERT(!(flags & GPIO_PULL_UP),
"Don't enable internal pullup if 1.8V voltage is used");
*reg_1p8v |= mask_1p8v;
} else if (volt == GPIO_VOLTAGE_3P3 ||
volt == GPIO_VOLTAGE_DEFAULT) {
*reg_1p8v &= ~mask_1p8v;
} else {
return -EINVAL;
}
}
/* If output, set level before changing type to an output. */
if (flags & GPIO_OUTPUT) {
if (flags & GPIO_OUTPUT_INIT_HIGH)
@ -274,11 +416,6 @@ static int gpio_ite_configure(const struct device *dev,
GPCR_PORT_PIN_MODE_PULLDOWN);
}
/*
* TODO: There are some gpios are 1.8v input at default.
* Is there a configuration flag for 1.8/3.3v selection.
*/
return 0;
}
@ -440,6 +577,8 @@ static const struct gpio_ite_cfg gpio_ite_cfg_##inst = { \
.reg_gpcr = DT_INST_REG_ADDR_BY_IDX(inst, 1), \
.reg_gpdmr = DT_INST_REG_ADDR_BY_IDX(inst, 2), \
.reg_gpotr = DT_INST_REG_ADDR_BY_IDX(inst, 3), \
.index = (uint8_t)(DT_INST_REG_ADDR(inst) - \
DT_REG_ADDR(DT_NODELABEL(gpioa))), \
.gpio_irq[0] = DT_INST_IRQ_BY_IDX(inst, 0, irq), \
.gpio_irq[1] = DT_INST_IRQ_BY_IDX(inst, 1, irq), \
.gpio_irq[2] = DT_INST_IRQ_BY_IDX(inst, 2, irq), \

View file

@ -1719,6 +1719,23 @@ struct flash_it8xxx2_regs {
#define IT8XXX2_GPIO_GCR ECREG(IT8XXX2_GPIO_BASE + 0x00)
#define IT8XXX2_GPIO_GCRX(offset) ECREG(IT8XXX2_GPIO_BASE + (offset))
#define IT8XXX2_GPIO_GCR25_OFFSET 0xd1
#define IT8XXX2_GPIO_GCR26_OFFSET 0xd2
#define IT8XXX2_GPIO_GCR27_OFFSET 0xd3
#define IT8XXX2_GPIO_GCR28_OFFSET 0xd4
#define IT8XXX2_GPIO_GCR31_OFFSET 0xd5
#define IT8XXX2_GPIO_GCR32_OFFSET 0xd6
#define IT8XXX2_GPIO_GCR33_OFFSET 0xd7
#define IT8XXX2_GPIO_GCR19_OFFSET 0xe4
#define IT8XXX2_GPIO_GCR20_OFFSET 0xe5
#define IT8XXX2_GPIO_GCR21_OFFSET 0xe6
#define IT8XXX2_GPIO_GCR22_OFFSET 0xe7
#define IT8XXX2_GPIO_GCR23_OFFSET 0xe8
#define IT8XXX2_GPIO_GCR24_OFFSET 0xe9
#define IT8XXX2_GPIO_GCR30_OFFSET 0xed
#define IT8XXX2_GPIO_GCR29_OFFSET 0xee
/* TODO: correct GRCx to GCRx */
#define IT8XXX2_GPIO_GRC1 ECREG(IT8XXX2_GPIO_BASE + 0xF0)
#define IT8XXX2_GPIO_GRC21 ECREG(IT8XXX2_GPIO_BASE + 0xE6)