Loading Documentation/devicetree/bindings/mfd/stmpe.txt +1 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ STMPE is an MFD device which may expose the following inbuilt devices: gpio, keypad, touchscreen, adc, pwm, rotator. Required properties: - compatible : "st,stmpe[610|801|811|1601|2401|2403]" - compatible : "st,stmpe[610|801|811|1600|1601|2401|2403]" - reg : I2C/SPI address of the device Optional properties: Loading drivers/gpio/gpio-stmpe.c +120 −47 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ */ enum { REG_RE, REG_FE, REG_IE }; enum { LSB, CSB, MSB }; #define CACHE_NR_REGS 3 /* No variant has more than 24 GPIOs */ #define CACHE_NR_BANKS (24 / 8) Loading @@ -39,7 +41,7 @@ static int stmpe_gpio_get(struct gpio_chip *chip, unsigned offset) { struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(chip); struct stmpe *stmpe = stmpe_gpio->stmpe; u8 reg = stmpe->regs[STMPE_IDX_GPMR_LSB] - (offset / 8); u8 reg = stmpe->regs[STMPE_IDX_GPMR_LSB + (offset / 8)]; u8 mask = 1 << (offset % 8); int ret; Loading @@ -55,7 +57,7 @@ static void stmpe_gpio_set(struct gpio_chip *chip, unsigned offset, int val) struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(chip); struct stmpe *stmpe = stmpe_gpio->stmpe; int which = val ? STMPE_IDX_GPSR_LSB : STMPE_IDX_GPCR_LSB; u8 reg = stmpe->regs[which] - (offset / 8); u8 reg = stmpe->regs[which + (offset / 8)]; u8 mask = 1 << (offset % 8); /* Loading Loading @@ -89,7 +91,7 @@ static int stmpe_gpio_direction_output(struct gpio_chip *chip, { struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(chip); struct stmpe *stmpe = stmpe_gpio->stmpe; u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB] - (offset / 8); u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB + (offset / 8)]; u8 mask = 1 << (offset % 8); stmpe_gpio_set(chip, offset, val); Loading @@ -102,7 +104,7 @@ static int stmpe_gpio_direction_input(struct gpio_chip *chip, { struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(chip); struct stmpe *stmpe = stmpe_gpio->stmpe; u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB] - (offset / 8); u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB + (offset / 8)]; u8 mask = 1 << (offset % 8); return stmpe_set_bits(stmpe, reg, mask, 0); Loading Loading @@ -142,8 +144,9 @@ static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type) if (type & IRQ_TYPE_LEVEL_LOW || type & IRQ_TYPE_LEVEL_HIGH) return -EINVAL; /* STMPE801 doesn't have RE and FE registers */ if (stmpe_gpio->stmpe->partnum == STMPE801) /* STMPE801 and STMPE 1600 don't have RE and FE registers */ if (stmpe_gpio->stmpe->partnum == STMPE801 || stmpe_gpio->stmpe->partnum == STMPE1600) return 0; if (type & IRQ_TYPE_EDGE_RISING) Loading Loading @@ -173,16 +176,23 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(gc); struct stmpe *stmpe = stmpe_gpio->stmpe; int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8); static const u8 regmap[] = { [REG_RE] = STMPE_IDX_GPRER_LSB, [REG_FE] = STMPE_IDX_GPFER_LSB, [REG_IE] = STMPE_IDX_IEGPIOR_LSB, static const u8 regmap[CACHE_NR_REGS][CACHE_NR_BANKS] = { [REG_RE][LSB] = STMPE_IDX_GPRER_LSB, [REG_RE][CSB] = STMPE_IDX_GPRER_CSB, [REG_RE][MSB] = STMPE_IDX_GPRER_MSB, [REG_FE][LSB] = STMPE_IDX_GPFER_LSB, [REG_FE][CSB] = STMPE_IDX_GPFER_CSB, [REG_FE][MSB] = STMPE_IDX_GPFER_MSB, [REG_IE][LSB] = STMPE_IDX_IEGPIOR_LSB, [REG_IE][CSB] = STMPE_IDX_IEGPIOR_CSB, [REG_IE][MSB] = STMPE_IDX_IEGPIOR_MSB, }; int i, j; for (i = 0; i < CACHE_NR_REGS; i++) { /* STMPE801 doesn't have RE and FE registers */ if ((stmpe->partnum == STMPE801) && /* STMPE801 and STMPE1600 don't have RE and FE registers */ if ((stmpe->partnum == STMPE801 || stmpe->partnum == STMPE1600) && (i != REG_IE)) continue; Loading @@ -194,7 +204,7 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) continue; stmpe_gpio->oldregs[i][j] = new; stmpe_reg_write(stmpe, stmpe->regs[regmap[i]] - j, new); stmpe_reg_write(stmpe, stmpe->regs[regmap[i][j]], new); } } Loading @@ -216,11 +226,21 @@ static void stmpe_gpio_irq_unmask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(gc); struct stmpe *stmpe = stmpe_gpio->stmpe; int offset = d->hwirq; int regoffset = offset / 8; int mask = 1 << (offset % 8); stmpe_gpio->regs[REG_IE][regoffset] |= mask; /* * STMPE1600 workaround: to be able to get IRQ from pins, * a read must be done on GPMR register, or a write in * GPSR or GPCR registers */ if (stmpe->partnum == STMPE1600) stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB + regoffset]); } static void stmpe_dbg_show_one(struct seq_file *s, Loading @@ -230,9 +250,9 @@ static void stmpe_dbg_show_one(struct seq_file *s, struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(gc); struct stmpe *stmpe = stmpe_gpio->stmpe; const char *label = gpiochip_is_requested(gc, offset); int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8); bool val = !!stmpe_gpio_get(gc, offset); u8 dir_reg = stmpe->regs[STMPE_IDX_GPDR_LSB] - (offset / 8); u8 bank = offset / 8; u8 dir_reg = stmpe->regs[STMPE_IDX_GPDR_LSB + bank]; u8 mask = 1 << (offset % 8); int ret; u8 dir; Loading @@ -247,19 +267,42 @@ static void stmpe_dbg_show_one(struct seq_file *s, gpio, label ?: "(none)", val ? "hi" : "lo"); } else { u8 edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_MSB] + num_banks - 1 - (offset / 8); u8 rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB] - (offset / 8); u8 fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB] - (offset / 8); u8 irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB] - (offset / 8); bool edge_det; bool rise; bool fall; u8 edge_det_reg; u8 rise_reg; u8 fall_reg; u8 irqen_reg; char *edge_det_values[] = {"edge-inactive", "edge-asserted", "not-supported"}; char *rise_values[] = {"no-rising-edge-detection", "rising-edge-detection", "not-supported"}; char *fall_values[] = {"no-falling-edge-detection", "falling-edge-detection", "not-supported"}; #define NOT_SUPPORTED_IDX 2 u8 edge_det = NOT_SUPPORTED_IDX; u8 rise = NOT_SUPPORTED_IDX; u8 fall = NOT_SUPPORTED_IDX; bool irqen; switch (stmpe->partnum) { case STMPE610: case STMPE811: case STMPE1601: case STMPE2401: case STMPE2403: edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_LSB + bank]; ret = stmpe_reg_read(stmpe, edge_det_reg); if (ret < 0) return; edge_det = !!(ret & mask); case STMPE1801: rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB + bank]; fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB + bank]; ret = stmpe_reg_read(stmpe, rise_reg); if (ret < 0) return; Loading @@ -268,18 +311,28 @@ static void stmpe_dbg_show_one(struct seq_file *s, if (ret < 0) return; fall = !!(ret & mask); case STMPE801: case STMPE1600: irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB + bank]; break; default: return; } ret = stmpe_reg_read(stmpe, irqen_reg); if (ret < 0) return; irqen = !!(ret & mask); seq_printf(s, " gpio-%-3d (%-20.20s) in %s %s %s%s%s", seq_printf(s, " gpio-%-3d (%-20.20s) in %s %13s %13s %25s %25s", gpio, label ?: "(none)", val ? "hi" : "lo", edge_det ? "edge-asserted" : "edge-inactive", irqen ? "IRQ-enabled" : "", rise ? " rising-edge-detection" : "", fall ? " falling-edge-detection" : ""); edge_det_values[edge_det], irqen ? "IRQ-enabled" : "IRQ-disabled", rise_values[rise], fall_values[fall]); } } Loading Loading @@ -307,18 +360,32 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) { struct stmpe_gpio *stmpe_gpio = dev; struct stmpe *stmpe = stmpe_gpio->stmpe; u8 statmsbreg = stmpe->regs[STMPE_IDX_ISGPIOR_MSB]; u8 statmsbreg; int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8); u8 status[num_banks]; int ret; int i; /* * the stmpe_block_read() call below, imposes to set statmsbreg * with the register located at the lowest address. As STMPE1600 * variant is the only one which respect registers address's order * (LSB regs located at lowest address than MSB ones) whereas all * the others have a registers layout with MSB located before the * LSB regs. */ if (stmpe->partnum == STMPE1600) statmsbreg = stmpe->regs[STMPE_IDX_ISGPIOR_LSB]; else statmsbreg = stmpe->regs[STMPE_IDX_ISGPIOR_MSB]; ret = stmpe_block_read(stmpe, statmsbreg, num_banks, status); if (ret < 0) return IRQ_NONE; for (i = 0; i < num_banks; i++) { int bank = num_banks - i - 1; int bank = (stmpe_gpio->stmpe->partnum == STMPE1600) ? i : num_banks - i - 1; unsigned int enabled = stmpe_gpio->regs[REG_IE][bank]; unsigned int stat = status[i]; Loading @@ -336,12 +403,18 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) stat &= ~(1 << bit); } /* * interrupt status register write has no effect on * 801/1801/1600, bits are cleared when read. * Edge detect register is not present on 801/1600/1801 */ if (stmpe->partnum != STMPE801 || stmpe->partnum != STMPE1600 || stmpe->partnum != STMPE1801) { stmpe_reg_write(stmpe, statmsbreg + i, status[i]); /* Edge detect register is not present on 801 */ if (stmpe->partnum != STMPE801) stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_GPEDR_MSB] + i, status[i]); stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_GPEDR_LSB + i], status[i]); } } return IRQ_HANDLED; Loading drivers/mfd/stmpe-i2c.c +2 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ static const struct of_device_id stmpe_of_match[] = { { .compatible = "st,stmpe610", .data = (void *)STMPE610, }, { .compatible = "st,stmpe801", .data = (void *)STMPE801, }, { .compatible = "st,stmpe811", .data = (void *)STMPE811, }, { .compatible = "st,stmpe1600", .data = (void *)STMPE1600, }, { .compatible = "st,stmpe1601", .data = (void *)STMPE1601, }, { .compatible = "st,stmpe1801", .data = (void *)STMPE1801, }, { .compatible = "st,stmpe2401", .data = (void *)STMPE2401, }, Loading Loading @@ -101,6 +102,7 @@ static const struct i2c_device_id stmpe_i2c_id[] = { { "stmpe610", STMPE610 }, { "stmpe801", STMPE801 }, { "stmpe811", STMPE811 }, { "stmpe1600", STMPE1600 }, { "stmpe1601", STMPE1601 }, { "stmpe1801", STMPE1801 }, { "stmpe2401", STMPE2401 }, Loading drivers/mfd/stmpe.c +135 −26 Original line number Diff line number Diff line Loading @@ -469,6 +469,8 @@ static const struct mfd_cell stmpe_ts_cell = { static const u8 stmpe811_regs[] = { [STMPE_IDX_CHIP_ID] = STMPE811_REG_CHIP_ID, [STMPE_IDX_SYS_CTRL] = STMPE811_REG_SYS_CTRL, [STMPE_IDX_SYS_CTRL2] = STMPE811_REG_SYS_CTRL2, [STMPE_IDX_ICR_LSB] = STMPE811_REG_INT_CTRL, [STMPE_IDX_IER_LSB] = STMPE811_REG_INT_EN, [STMPE_IDX_ISR_MSB] = STMPE811_REG_INT_STA, Loading @@ -481,7 +483,7 @@ static const u8 stmpe811_regs[] = { [STMPE_IDX_GPAFR_U_MSB] = STMPE811_REG_GPIO_AF, [STMPE_IDX_IEGPIOR_LSB] = STMPE811_REG_GPIO_INT_EN, [STMPE_IDX_ISGPIOR_MSB] = STMPE811_REG_GPIO_INT_STA, [STMPE_IDX_GPEDR_MSB] = STMPE811_REG_GPIO_ED, [STMPE_IDX_GPEDR_LSB] = STMPE811_REG_GPIO_ED, }; static struct stmpe_variant_block stmpe811_blocks[] = { Loading Loading @@ -511,7 +513,7 @@ static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks, if (blocks & STMPE_BLOCK_TOUCHSCREEN) mask |= STMPE811_SYS_CTRL2_TSC_OFF; return __stmpe_set_bits(stmpe, STMPE811_REG_SYS_CTRL2, mask, return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], mask, enable ? 0 : mask); } Loading Loading @@ -550,26 +552,90 @@ static struct stmpe_variant_info stmpe610 = { .get_altfunc = stmpe811_get_altfunc, }; /* * STMPE1600 * Compared to all others STMPE variant, LSB and MSB regs are located in this * order : LSB addr * MSB addr + 1 * As there is only 2 * 8bits registers for GPMR/GPSR/IEGPIOPR, CSB index is MSB registers */ static const u8 stmpe1600_regs[] = { [STMPE_IDX_CHIP_ID] = STMPE1600_REG_CHIP_ID, [STMPE_IDX_SYS_CTRL] = STMPE1600_REG_SYS_CTRL, [STMPE_IDX_ICR_LSB] = STMPE1600_REG_SYS_CTRL, [STMPE_IDX_GPMR_LSB] = STMPE1600_REG_GPMR_LSB, [STMPE_IDX_GPMR_CSB] = STMPE1600_REG_GPMR_MSB, [STMPE_IDX_GPSR_LSB] = STMPE1600_REG_GPSR_LSB, [STMPE_IDX_GPSR_CSB] = STMPE1600_REG_GPSR_MSB, [STMPE_IDX_GPDR_LSB] = STMPE1600_REG_GPDR_LSB, [STMPE_IDX_GPDR_CSB] = STMPE1600_REG_GPDR_MSB, [STMPE_IDX_IEGPIOR_LSB] = STMPE1600_REG_IEGPIOR_LSB, [STMPE_IDX_IEGPIOR_CSB] = STMPE1600_REG_IEGPIOR_MSB, [STMPE_IDX_ISGPIOR_LSB] = STMPE1600_REG_ISGPIOR_LSB, }; static struct stmpe_variant_block stmpe1600_blocks[] = { { .cell = &stmpe_gpio_cell, .irq = 0, .block = STMPE_BLOCK_GPIO, }, }; static int stmpe1600_enable(struct stmpe *stmpe, unsigned int blocks, bool enable) { if (blocks & STMPE_BLOCK_GPIO) return 0; else return -EINVAL; } static struct stmpe_variant_info stmpe1600 = { .name = "stmpe1600", .id_val = STMPE1600_ID, .id_mask = 0xffff, .num_gpios = 16, .af_bits = 0, .regs = stmpe1600_regs, .blocks = stmpe1600_blocks, .num_blocks = ARRAY_SIZE(stmpe1600_blocks), .num_irqs = STMPE1600_NR_INTERNAL_IRQS, .enable = stmpe1600_enable, }; /* * STMPE1601 */ static const u8 stmpe1601_regs[] = { [STMPE_IDX_CHIP_ID] = STMPE1601_REG_CHIP_ID, [STMPE_IDX_SYS_CTRL] = STMPE1601_REG_SYS_CTRL, [STMPE_IDX_SYS_CTRL2] = STMPE1601_REG_SYS_CTRL2, [STMPE_IDX_ICR_LSB] = STMPE1601_REG_ICR_LSB, [STMPE_IDX_IER_MSB] = STMPE1601_REG_IER_MSB, [STMPE_IDX_IER_LSB] = STMPE1601_REG_IER_LSB, [STMPE_IDX_ISR_MSB] = STMPE1601_REG_ISR_MSB, [STMPE_IDX_GPMR_LSB] = STMPE1601_REG_GPIO_MP_LSB, [STMPE_IDX_GPMR_CSB] = STMPE1601_REG_GPIO_MP_MSB, [STMPE_IDX_GPSR_LSB] = STMPE1601_REG_GPIO_SET_LSB, [STMPE_IDX_GPSR_CSB] = STMPE1601_REG_GPIO_SET_MSB, [STMPE_IDX_GPCR_LSB] = STMPE1601_REG_GPIO_CLR_LSB, [STMPE_IDX_GPCR_CSB] = STMPE1601_REG_GPIO_CLR_MSB, [STMPE_IDX_GPDR_LSB] = STMPE1601_REG_GPIO_SET_DIR_LSB, [STMPE_IDX_GPDR_CSB] = STMPE1601_REG_GPIO_SET_DIR_MSB, [STMPE_IDX_GPEDR_LSB] = STMPE1601_REG_GPIO_ED_LSB, [STMPE_IDX_GPEDR_CSB] = STMPE1601_REG_GPIO_ED_MSB, [STMPE_IDX_GPRER_LSB] = STMPE1601_REG_GPIO_RE_LSB, [STMPE_IDX_GPRER_CSB] = STMPE1601_REG_GPIO_RE_MSB, [STMPE_IDX_GPFER_LSB] = STMPE1601_REG_GPIO_FE_LSB, [STMPE_IDX_GPFER_CSB] = STMPE1601_REG_GPIO_FE_MSB, [STMPE_IDX_GPPUR_LSB] = STMPE1601_REG_GPIO_PU_LSB, [STMPE_IDX_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB, [STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB, [STMPE_IDX_IEGPIOR_CSB] = STMPE1601_REG_INT_EN_GPIO_MASK_MSB, [STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB, [STMPE_IDX_GPEDR_MSB] = STMPE1601_REG_GPIO_ED_MSB, }; static struct stmpe_variant_block stmpe1601_blocks[] = { Loading Loading @@ -640,13 +706,13 @@ static int stmpe1601_autosleep(struct stmpe *stmpe, return timeout; } ret = __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2, ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], STMPE1601_AUTOSLEEP_TIMEOUT_MASK, timeout); if (ret < 0) return ret; return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2, return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], STPME1601_AUTOSLEEP_ENABLE, STPME1601_AUTOSLEEP_ENABLE); } Loading @@ -671,7 +737,7 @@ static int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks, else mask &= ~STMPE1601_SYS_CTRL_ENABLE_SPWM; return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL, mask, return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask, enable ? mask : 0); } Loading Loading @@ -710,18 +776,33 @@ static struct stmpe_variant_info stmpe1601 = { */ static const u8 stmpe1801_regs[] = { [STMPE_IDX_CHIP_ID] = STMPE1801_REG_CHIP_ID, [STMPE_IDX_SYS_CTRL] = STMPE1801_REG_SYS_CTRL, [STMPE_IDX_ICR_LSB] = STMPE1801_REG_INT_CTRL_LOW, [STMPE_IDX_IER_LSB] = STMPE1801_REG_INT_EN_MASK_LOW, [STMPE_IDX_ISR_LSB] = STMPE1801_REG_INT_STA_LOW, [STMPE_IDX_GPMR_LSB] = STMPE1801_REG_GPIO_MP_LOW, [STMPE_IDX_GPMR_CSB] = STMPE1801_REG_GPIO_MP_MID, [STMPE_IDX_GPMR_MSB] = STMPE1801_REG_GPIO_MP_HIGH, [STMPE_IDX_GPSR_LSB] = STMPE1801_REG_GPIO_SET_LOW, [STMPE_IDX_GPSR_CSB] = STMPE1801_REG_GPIO_SET_MID, [STMPE_IDX_GPSR_MSB] = STMPE1801_REG_GPIO_SET_HIGH, [STMPE_IDX_GPCR_LSB] = STMPE1801_REG_GPIO_CLR_LOW, [STMPE_IDX_GPCR_CSB] = STMPE1801_REG_GPIO_CLR_MID, [STMPE_IDX_GPCR_MSB] = STMPE1801_REG_GPIO_CLR_HIGH, [STMPE_IDX_GPDR_LSB] = STMPE1801_REG_GPIO_SET_DIR_LOW, [STMPE_IDX_GPDR_CSB] = STMPE1801_REG_GPIO_SET_DIR_MID, [STMPE_IDX_GPDR_MSB] = STMPE1801_REG_GPIO_SET_DIR_HIGH, [STMPE_IDX_GPRER_LSB] = STMPE1801_REG_GPIO_RE_LOW, [STMPE_IDX_GPRER_CSB] = STMPE1801_REG_GPIO_RE_MID, [STMPE_IDX_GPRER_MSB] = STMPE1801_REG_GPIO_RE_HIGH, [STMPE_IDX_GPFER_LSB] = STMPE1801_REG_GPIO_FE_LOW, [STMPE_IDX_GPFER_CSB] = STMPE1801_REG_GPIO_FE_MID, [STMPE_IDX_GPFER_MSB] = STMPE1801_REG_GPIO_FE_HIGH, [STMPE_IDX_GPPUR_LSB] = STMPE1801_REG_GPIO_PULL_UP_LOW, [STMPE_IDX_IEGPIOR_LSB] = STMPE1801_REG_INT_EN_GPIO_MASK_LOW, [STMPE_IDX_ISGPIOR_LSB] = STMPE1801_REG_INT_STA_GPIO_LOW, [STMPE_IDX_IEGPIOR_CSB] = STMPE1801_REG_INT_EN_GPIO_MASK_MID, [STMPE_IDX_IEGPIOR_MSB] = STMPE1801_REG_INT_EN_GPIO_MASK_HIGH, [STMPE_IDX_ISGPIOR_MSB] = STMPE1801_REG_INT_STA_GPIO_HIGH, }; static struct stmpe_variant_block stmpe1801_blocks[] = { Loading Loading @@ -751,22 +832,31 @@ static int stmpe1801_enable(struct stmpe *stmpe, unsigned int blocks, enable ? mask : 0); } static int stmpe1801_reset(struct stmpe *stmpe) static int stmpe_reset(struct stmpe *stmpe) { u16 id_val = stmpe->variant->id_val; unsigned long timeout; int ret = 0; u8 reset_bit; ret = __stmpe_set_bits(stmpe, STMPE1801_REG_SYS_CTRL, STMPE1801_MSK_SYS_CTRL_RESET, STMPE1801_MSK_SYS_CTRL_RESET); if (id_val == STMPE811_ID) /* STMPE801 and STMPE610 use bit 1 of SYS_CTRL register */ reset_bit = STMPE811_SYS_CTRL_RESET; else /* all other STMPE variant use bit 7 of SYS_CTRL register */ reset_bit = STMPE_SYS_CTRL_RESET; ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], reset_bit, reset_bit); if (ret < 0) return ret; timeout = jiffies + msecs_to_jiffies(100); while (time_before(jiffies, timeout)) { ret = __stmpe_reg_read(stmpe, STMPE1801_REG_SYS_CTRL); ret = __stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL]); if (ret < 0) return ret; if (!(ret & STMPE1801_MSK_SYS_CTRL_RESET)) if (!(ret & reset_bit)) return 0; usleep_range(100, 200); } Loading Loading @@ -794,20 +884,39 @@ static struct stmpe_variant_info stmpe1801 = { static const u8 stmpe24xx_regs[] = { [STMPE_IDX_CHIP_ID] = STMPE24XX_REG_CHIP_ID, [STMPE_IDX_SYS_CTRL] = STMPE24XX_REG_SYS_CTRL, [STMPE_IDX_SYS_CTRL2] = STMPE24XX_REG_SYS_CTRL2, [STMPE_IDX_ICR_LSB] = STMPE24XX_REG_ICR_LSB, [STMPE_IDX_IER_MSB] = STMPE24XX_REG_IER_MSB, [STMPE_IDX_IER_LSB] = STMPE24XX_REG_IER_LSB, [STMPE_IDX_ISR_MSB] = STMPE24XX_REG_ISR_MSB, [STMPE_IDX_GPMR_LSB] = STMPE24XX_REG_GPMR_LSB, [STMPE_IDX_GPMR_CSB] = STMPE24XX_REG_GPMR_CSB, [STMPE_IDX_GPMR_MSB] = STMPE24XX_REG_GPMR_MSB, [STMPE_IDX_GPSR_LSB] = STMPE24XX_REG_GPSR_LSB, [STMPE_IDX_GPSR_CSB] = STMPE24XX_REG_GPSR_CSB, [STMPE_IDX_GPSR_MSB] = STMPE24XX_REG_GPSR_MSB, [STMPE_IDX_GPCR_LSB] = STMPE24XX_REG_GPCR_LSB, [STMPE_IDX_GPCR_CSB] = STMPE24XX_REG_GPCR_CSB, [STMPE_IDX_GPCR_MSB] = STMPE24XX_REG_GPCR_MSB, [STMPE_IDX_GPDR_LSB] = STMPE24XX_REG_GPDR_LSB, [STMPE_IDX_GPDR_CSB] = STMPE24XX_REG_GPDR_CSB, [STMPE_IDX_GPDR_MSB] = STMPE24XX_REG_GPDR_MSB, [STMPE_IDX_GPRER_LSB] = STMPE24XX_REG_GPRER_LSB, [STMPE_IDX_GPRER_CSB] = STMPE24XX_REG_GPRER_CSB, [STMPE_IDX_GPRER_MSB] = STMPE24XX_REG_GPRER_MSB, [STMPE_IDX_GPFER_LSB] = STMPE24XX_REG_GPFER_LSB, [STMPE_IDX_GPFER_CSB] = STMPE24XX_REG_GPFER_CSB, [STMPE_IDX_GPFER_MSB] = STMPE24XX_REG_GPFER_MSB, [STMPE_IDX_GPPUR_LSB] = STMPE24XX_REG_GPPUR_LSB, [STMPE_IDX_GPPDR_LSB] = STMPE24XX_REG_GPPDR_LSB, [STMPE_IDX_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB, [STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB, [STMPE_IDX_IEGPIOR_CSB] = STMPE24XX_REG_IEGPIOR_CSB, [STMPE_IDX_IEGPIOR_MSB] = STMPE24XX_REG_IEGPIOR_MSB, [STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB, [STMPE_IDX_GPEDR_LSB] = STMPE24XX_REG_GPEDR_LSB, [STMPE_IDX_GPEDR_CSB] = STMPE24XX_REG_GPEDR_CSB, [STMPE_IDX_GPEDR_MSB] = STMPE24XX_REG_GPEDR_MSB, }; Loading Loading @@ -840,7 +949,7 @@ static int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks, if (blocks & STMPE_BLOCK_KEYPAD) mask |= STMPE24XX_SYS_CTRL_ENABLE_KPC; return __stmpe_set_bits(stmpe, STMPE24XX_REG_SYS_CTRL, mask, return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask, enable ? mask : 0); } Loading Loading @@ -893,6 +1002,7 @@ static struct stmpe_variant_info *stmpe_variant_info[STMPE_NBR_PARTS] = { [STMPE610] = &stmpe610, [STMPE801] = &stmpe801, [STMPE811] = &stmpe811, [STMPE1600] = &stmpe1600, [STMPE1601] = &stmpe1601, [STMPE1801] = &stmpe1801, [STMPE2401] = &stmpe2401, Loading @@ -919,7 +1029,8 @@ static irqreturn_t stmpe_irq(int irq, void *data) int ret; int i; if (variant->id_val == STMPE801_ID) { if (variant->id_val == STMPE801_ID || variant->id_val == STMPE1600_ID) { int base = irq_create_mapping(stmpe->domain, 0); handle_nested_irq(base); Loading Loading @@ -982,7 +1093,7 @@ static void stmpe_irq_sync_unlock(struct irq_data *data) continue; stmpe->oldier[i] = new; stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB] - i, new); stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB + i], new); } mutex_unlock(&stmpe->irq_lock); Loading Loading @@ -1088,20 +1199,18 @@ static int stmpe_chip_init(struct stmpe *stmpe) if (ret) return ret; if (id == STMPE1801_ID) { ret = stmpe1801_reset(stmpe); ret = stmpe_reset(stmpe); if (ret < 0) return ret; } if (stmpe->irq >= 0) { if (id == STMPE801_ID) icr = STMPE801_REG_SYS_CTRL_INT_EN; if (id == STMPE801_ID || id == STMPE1600_ID) icr = STMPE_SYS_CTRL_INT_EN; else icr = STMPE_ICR_LSB_GIM; /* STMPE801 doesn't support Edge interrupts */ if (id != STMPE801_ID) { /* STMPE801 and STMPE1600 don't support Edge interrupts */ if (id != STMPE801_ID && id != STMPE1600_ID) { if (irq_trigger == IRQF_TRIGGER_FALLING || irq_trigger == IRQF_TRIGGER_RISING) icr |= STMPE_ICR_LSB_EDGE; Loading @@ -1109,8 +1218,8 @@ static int stmpe_chip_init(struct stmpe *stmpe) if (irq_trigger == IRQF_TRIGGER_RISING || irq_trigger == IRQF_TRIGGER_HIGH) { if (id == STMPE801_ID) icr |= STMPE801_REG_SYS_CTRL_INT_HI; if (id == STMPE801_ID || id == STMPE1600_ID) icr |= STMPE_SYS_CTRL_INT_HI; else icr |= STMPE_ICR_LSB_HIGH; } Loading drivers/mfd/stmpe.h +73 −12 Original line number Diff line number Diff line Loading @@ -104,6 +104,10 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE_ICR_LSB_EDGE (1 << 1) #define STMPE_ICR_LSB_GIM (1 << 0) #define STMPE_SYS_CTRL_RESET (1 << 7) #define STMPE_SYS_CTRL_INT_EN (1 << 2) #define STMPE_SYS_CTRL_INT_HI (1 << 0) /* * STMPE801 */ Loading @@ -119,13 +123,10 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE801_REG_GPIO_SET_PIN 0x11 #define STMPE801_REG_GPIO_DIR 0x12 #define STMPE801_REG_SYS_CTRL_RESET (1 << 7) #define STMPE801_REG_SYS_CTRL_INT_EN (1 << 2) #define STMPE801_REG_SYS_CTRL_INT_HI (1 << 0) /* * STMPE811 */ #define STMPE811_ID 0x0811 #define STMPE811_IRQ_TOUCH_DET 0 #define STMPE811_IRQ_FIFO_TH 1 Loading @@ -138,6 +139,7 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE811_NR_INTERNAL_IRQS 8 #define STMPE811_REG_CHIP_ID 0x00 #define STMPE811_REG_SYS_CTRL 0x03 #define STMPE811_REG_SYS_CTRL2 0x04 #define STMPE811_REG_SPI_CFG 0x08 #define STMPE811_REG_INT_CTRL 0x09 Loading @@ -154,11 +156,34 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE811_REG_GPIO_FE 0x16 #define STMPE811_REG_GPIO_AF 0x17 #define STMPE811_SYS_CTRL_RESET (1 << 1) #define STMPE811_SYS_CTRL2_ADC_OFF (1 << 0) #define STMPE811_SYS_CTRL2_TSC_OFF (1 << 1) #define STMPE811_SYS_CTRL2_GPIO_OFF (1 << 2) #define STMPE811_SYS_CTRL2_TS_OFF (1 << 3) /* * STMPE1600 */ #define STMPE1600_ID 0x0016 #define STMPE1600_NR_INTERNAL_IRQS 16 #define STMPE1600_REG_CHIP_ID 0x00 #define STMPE1600_REG_SYS_CTRL 0x03 #define STMPE1600_REG_IEGPIOR_LSB 0x08 #define STMPE1600_REG_IEGPIOR_MSB 0x09 #define STMPE1600_REG_ISGPIOR_LSB 0x0A #define STMPE1600_REG_ISGPIOR_MSB 0x0B #define STMPE1600_REG_GPMR_LSB 0x10 #define STMPE1600_REG_GPMR_MSB 0x11 #define STMPE1600_REG_GPSR_LSB 0x12 #define STMPE1600_REG_GPSR_MSB 0x13 #define STMPE1600_REG_GPDR_LSB 0x14 #define STMPE1600_REG_GPDR_MSB 0x15 #define STMPE1600_REG_GPPIR_LSB 0x16 #define STMPE1600_REG_GPPIR_MSB 0x17 /* * STMPE1601 */ Loading @@ -175,19 +200,32 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE1601_REG_SYS_CTRL 0x02 #define STMPE1601_REG_SYS_CTRL2 0x03 #define STMPE1601_REG_ICR_MSB 0x10 #define STMPE1601_REG_ICR_LSB 0x11 #define STMPE1601_REG_IER_MSB 0x12 #define STMPE1601_REG_IER_LSB 0x13 #define STMPE1601_REG_ISR_MSB 0x14 #define STMPE1601_REG_CHIP_ID 0x80 #define STMPE1601_REG_ISR_LSB 0x15 #define STMPE1601_REG_INT_EN_GPIO_MASK_MSB 0x16 #define STMPE1601_REG_INT_EN_GPIO_MASK_LSB 0x17 #define STMPE1601_REG_INT_STA_GPIO_MSB 0x18 #define STMPE1601_REG_GPIO_MP_LSB 0x87 #define STMPE1601_REG_INT_STA_GPIO_LSB 0x19 #define STMPE1601_REG_CHIP_ID 0x80 #define STMPE1601_REG_GPIO_SET_MSB 0x82 #define STMPE1601_REG_GPIO_SET_LSB 0x83 #define STMPE1601_REG_GPIO_CLR_MSB 0x84 #define STMPE1601_REG_GPIO_CLR_LSB 0x85 #define STMPE1601_REG_GPIO_MP_MSB 0x86 #define STMPE1601_REG_GPIO_MP_LSB 0x87 #define STMPE1601_REG_GPIO_SET_DIR_MSB 0x88 #define STMPE1601_REG_GPIO_SET_DIR_LSB 0x89 #define STMPE1601_REG_GPIO_ED_MSB 0x8A #define STMPE1601_REG_GPIO_ED_LSB 0x8B #define STMPE1601_REG_GPIO_RE_MSB 0x8C #define STMPE1601_REG_GPIO_RE_LSB 0x8D #define STMPE1601_REG_GPIO_FE_MSB 0x8E #define STMPE1601_REG_GPIO_FE_LSB 0x8F #define STMPE1601_REG_GPIO_PU_MSB 0x90 #define STMPE1601_REG_GPIO_PU_LSB 0x91 #define STMPE1601_REG_GPIO_AF_U_MSB 0x92 Loading Loading @@ -243,8 +281,6 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE1801_REG_GPIO_PULL_UP_MID 0x23 #define STMPE1801_REG_GPIO_PULL_UP_HIGH 0x24 #define STMPE1801_MSK_SYS_CTRL_RESET (1 << 7) #define STMPE1801_MSK_INT_EN_KPC (1 << 1) #define STMPE1801_MSK_INT_EN_GPIO (1 << 3) Loading @@ -264,23 +300,48 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE24XX_NR_INTERNAL_IRQS 9 #define STMPE24XX_REG_SYS_CTRL 0x02 #define STMPE24XX_REG_SYS_CTRL2 0x03 #define STMPE24XX_REG_ICR_MSB 0x10 #define STMPE24XX_REG_ICR_LSB 0x11 #define STMPE24XX_REG_IER_MSB 0x12 #define STMPE24XX_REG_IER_LSB 0x13 #define STMPE24XX_REG_ISR_MSB 0x14 #define STMPE24XX_REG_CHIP_ID 0x80 #define STMPE24XX_REG_ISR_LSB 0x15 #define STMPE24XX_REG_IEGPIOR_MSB 0x16 #define STMPE24XX_REG_IEGPIOR_CSB 0x17 #define STMPE24XX_REG_IEGPIOR_LSB 0x18 #define STMPE24XX_REG_ISGPIOR_MSB 0x19 #define STMPE24XX_REG_GPMR_LSB 0xA4 #define STMPE24XX_REG_ISGPIOR_CSB 0x1A #define STMPE24XX_REG_ISGPIOR_LSB 0x1B #define STMPE24XX_REG_CHIP_ID 0x80 #define STMPE24XX_REG_GPSR_MSB 0x83 #define STMPE24XX_REG_GPSR_CSB 0x84 #define STMPE24XX_REG_GPSR_LSB 0x85 #define STMPE24XX_REG_GPCR_MSB 0x86 #define STMPE24XX_REG_GPCR_CSB 0x87 #define STMPE24XX_REG_GPCR_LSB 0x88 #define STMPE24XX_REG_GPDR_MSB 0x89 #define STMPE24XX_REG_GPDR_CSB 0x8A #define STMPE24XX_REG_GPDR_LSB 0x8B #define STMPE24XX_REG_GPEDR_MSB 0x8C #define STMPE24XX_REG_GPEDR_CSB 0x8D #define STMPE24XX_REG_GPEDR_LSB 0x8E #define STMPE24XX_REG_GPRER_MSB 0x8F #define STMPE24XX_REG_GPRER_CSB 0x90 #define STMPE24XX_REG_GPRER_LSB 0x91 #define STMPE24XX_REG_GPFER_MSB 0x92 #define STMPE24XX_REG_GPFER_CSB 0x93 #define STMPE24XX_REG_GPFER_LSB 0x94 #define STMPE24XX_REG_GPPUR_MSB 0x95 #define STMPE24XX_REG_GPPUR_CSB 0x96 #define STMPE24XX_REG_GPPUR_LSB 0x97 #define STMPE24XX_REG_GPPDR_LSB 0x9a #define STMPE24XX_REG_GPPDR_MSB 0x98 #define STMPE24XX_REG_GPPDR_CSB 0x99 #define STMPE24XX_REG_GPPDR_LSB 0x9A #define STMPE24XX_REG_GPAFR_U_MSB 0x9B #define STMPE24XX_REG_GPMR_MSB 0xA2 #define STMPE24XX_REG_GPMR_CSB 0xA3 #define STMPE24XX_REG_GPMR_LSB 0xA4 #define STMPE24XX_SYS_CTRL_ENABLE_GPIO (1 << 3) #define STMPE24XX_SYSCON_ENABLE_PWM (1 << 2) #define STMPE24XX_SYS_CTRL_ENABLE_KPC (1 << 1) Loading Loading
Documentation/devicetree/bindings/mfd/stmpe.txt +1 −1 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ STMPE is an MFD device which may expose the following inbuilt devices: gpio, keypad, touchscreen, adc, pwm, rotator. Required properties: - compatible : "st,stmpe[610|801|811|1601|2401|2403]" - compatible : "st,stmpe[610|801|811|1600|1601|2401|2403]" - reg : I2C/SPI address of the device Optional properties: Loading
drivers/gpio/gpio-stmpe.c +120 −47 Original line number Diff line number Diff line Loading @@ -20,6 +20,8 @@ */ enum { REG_RE, REG_FE, REG_IE }; enum { LSB, CSB, MSB }; #define CACHE_NR_REGS 3 /* No variant has more than 24 GPIOs */ #define CACHE_NR_BANKS (24 / 8) Loading @@ -39,7 +41,7 @@ static int stmpe_gpio_get(struct gpio_chip *chip, unsigned offset) { struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(chip); struct stmpe *stmpe = stmpe_gpio->stmpe; u8 reg = stmpe->regs[STMPE_IDX_GPMR_LSB] - (offset / 8); u8 reg = stmpe->regs[STMPE_IDX_GPMR_LSB + (offset / 8)]; u8 mask = 1 << (offset % 8); int ret; Loading @@ -55,7 +57,7 @@ static void stmpe_gpio_set(struct gpio_chip *chip, unsigned offset, int val) struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(chip); struct stmpe *stmpe = stmpe_gpio->stmpe; int which = val ? STMPE_IDX_GPSR_LSB : STMPE_IDX_GPCR_LSB; u8 reg = stmpe->regs[which] - (offset / 8); u8 reg = stmpe->regs[which + (offset / 8)]; u8 mask = 1 << (offset % 8); /* Loading Loading @@ -89,7 +91,7 @@ static int stmpe_gpio_direction_output(struct gpio_chip *chip, { struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(chip); struct stmpe *stmpe = stmpe_gpio->stmpe; u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB] - (offset / 8); u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB + (offset / 8)]; u8 mask = 1 << (offset % 8); stmpe_gpio_set(chip, offset, val); Loading @@ -102,7 +104,7 @@ static int stmpe_gpio_direction_input(struct gpio_chip *chip, { struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(chip); struct stmpe *stmpe = stmpe_gpio->stmpe; u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB] - (offset / 8); u8 reg = stmpe->regs[STMPE_IDX_GPDR_LSB + (offset / 8)]; u8 mask = 1 << (offset % 8); return stmpe_set_bits(stmpe, reg, mask, 0); Loading Loading @@ -142,8 +144,9 @@ static int stmpe_gpio_irq_set_type(struct irq_data *d, unsigned int type) if (type & IRQ_TYPE_LEVEL_LOW || type & IRQ_TYPE_LEVEL_HIGH) return -EINVAL; /* STMPE801 doesn't have RE and FE registers */ if (stmpe_gpio->stmpe->partnum == STMPE801) /* STMPE801 and STMPE 1600 don't have RE and FE registers */ if (stmpe_gpio->stmpe->partnum == STMPE801 || stmpe_gpio->stmpe->partnum == STMPE1600) return 0; if (type & IRQ_TYPE_EDGE_RISING) Loading Loading @@ -173,16 +176,23 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(gc); struct stmpe *stmpe = stmpe_gpio->stmpe; int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8); static const u8 regmap[] = { [REG_RE] = STMPE_IDX_GPRER_LSB, [REG_FE] = STMPE_IDX_GPFER_LSB, [REG_IE] = STMPE_IDX_IEGPIOR_LSB, static const u8 regmap[CACHE_NR_REGS][CACHE_NR_BANKS] = { [REG_RE][LSB] = STMPE_IDX_GPRER_LSB, [REG_RE][CSB] = STMPE_IDX_GPRER_CSB, [REG_RE][MSB] = STMPE_IDX_GPRER_MSB, [REG_FE][LSB] = STMPE_IDX_GPFER_LSB, [REG_FE][CSB] = STMPE_IDX_GPFER_CSB, [REG_FE][MSB] = STMPE_IDX_GPFER_MSB, [REG_IE][LSB] = STMPE_IDX_IEGPIOR_LSB, [REG_IE][CSB] = STMPE_IDX_IEGPIOR_CSB, [REG_IE][MSB] = STMPE_IDX_IEGPIOR_MSB, }; int i, j; for (i = 0; i < CACHE_NR_REGS; i++) { /* STMPE801 doesn't have RE and FE registers */ if ((stmpe->partnum == STMPE801) && /* STMPE801 and STMPE1600 don't have RE and FE registers */ if ((stmpe->partnum == STMPE801 || stmpe->partnum == STMPE1600) && (i != REG_IE)) continue; Loading @@ -194,7 +204,7 @@ static void stmpe_gpio_irq_sync_unlock(struct irq_data *d) continue; stmpe_gpio->oldregs[i][j] = new; stmpe_reg_write(stmpe, stmpe->regs[regmap[i]] - j, new); stmpe_reg_write(stmpe, stmpe->regs[regmap[i][j]], new); } } Loading @@ -216,11 +226,21 @@ static void stmpe_gpio_irq_unmask(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(gc); struct stmpe *stmpe = stmpe_gpio->stmpe; int offset = d->hwirq; int regoffset = offset / 8; int mask = 1 << (offset % 8); stmpe_gpio->regs[REG_IE][regoffset] |= mask; /* * STMPE1600 workaround: to be able to get IRQ from pins, * a read must be done on GPMR register, or a write in * GPSR or GPCR registers */ if (stmpe->partnum == STMPE1600) stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB + regoffset]); } static void stmpe_dbg_show_one(struct seq_file *s, Loading @@ -230,9 +250,9 @@ static void stmpe_dbg_show_one(struct seq_file *s, struct stmpe_gpio *stmpe_gpio = gpiochip_get_data(gc); struct stmpe *stmpe = stmpe_gpio->stmpe; const char *label = gpiochip_is_requested(gc, offset); int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8); bool val = !!stmpe_gpio_get(gc, offset); u8 dir_reg = stmpe->regs[STMPE_IDX_GPDR_LSB] - (offset / 8); u8 bank = offset / 8; u8 dir_reg = stmpe->regs[STMPE_IDX_GPDR_LSB + bank]; u8 mask = 1 << (offset % 8); int ret; u8 dir; Loading @@ -247,19 +267,42 @@ static void stmpe_dbg_show_one(struct seq_file *s, gpio, label ?: "(none)", val ? "hi" : "lo"); } else { u8 edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_MSB] + num_banks - 1 - (offset / 8); u8 rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB] - (offset / 8); u8 fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB] - (offset / 8); u8 irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB] - (offset / 8); bool edge_det; bool rise; bool fall; u8 edge_det_reg; u8 rise_reg; u8 fall_reg; u8 irqen_reg; char *edge_det_values[] = {"edge-inactive", "edge-asserted", "not-supported"}; char *rise_values[] = {"no-rising-edge-detection", "rising-edge-detection", "not-supported"}; char *fall_values[] = {"no-falling-edge-detection", "falling-edge-detection", "not-supported"}; #define NOT_SUPPORTED_IDX 2 u8 edge_det = NOT_SUPPORTED_IDX; u8 rise = NOT_SUPPORTED_IDX; u8 fall = NOT_SUPPORTED_IDX; bool irqen; switch (stmpe->partnum) { case STMPE610: case STMPE811: case STMPE1601: case STMPE2401: case STMPE2403: edge_det_reg = stmpe->regs[STMPE_IDX_GPEDR_LSB + bank]; ret = stmpe_reg_read(stmpe, edge_det_reg); if (ret < 0) return; edge_det = !!(ret & mask); case STMPE1801: rise_reg = stmpe->regs[STMPE_IDX_GPRER_LSB + bank]; fall_reg = stmpe->regs[STMPE_IDX_GPFER_LSB + bank]; ret = stmpe_reg_read(stmpe, rise_reg); if (ret < 0) return; Loading @@ -268,18 +311,28 @@ static void stmpe_dbg_show_one(struct seq_file *s, if (ret < 0) return; fall = !!(ret & mask); case STMPE801: case STMPE1600: irqen_reg = stmpe->regs[STMPE_IDX_IEGPIOR_LSB + bank]; break; default: return; } ret = stmpe_reg_read(stmpe, irqen_reg); if (ret < 0) return; irqen = !!(ret & mask); seq_printf(s, " gpio-%-3d (%-20.20s) in %s %s %s%s%s", seq_printf(s, " gpio-%-3d (%-20.20s) in %s %13s %13s %25s %25s", gpio, label ?: "(none)", val ? "hi" : "lo", edge_det ? "edge-asserted" : "edge-inactive", irqen ? "IRQ-enabled" : "", rise ? " rising-edge-detection" : "", fall ? " falling-edge-detection" : ""); edge_det_values[edge_det], irqen ? "IRQ-enabled" : "IRQ-disabled", rise_values[rise], fall_values[fall]); } } Loading Loading @@ -307,18 +360,32 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) { struct stmpe_gpio *stmpe_gpio = dev; struct stmpe *stmpe = stmpe_gpio->stmpe; u8 statmsbreg = stmpe->regs[STMPE_IDX_ISGPIOR_MSB]; u8 statmsbreg; int num_banks = DIV_ROUND_UP(stmpe->num_gpios, 8); u8 status[num_banks]; int ret; int i; /* * the stmpe_block_read() call below, imposes to set statmsbreg * with the register located at the lowest address. As STMPE1600 * variant is the only one which respect registers address's order * (LSB regs located at lowest address than MSB ones) whereas all * the others have a registers layout with MSB located before the * LSB regs. */ if (stmpe->partnum == STMPE1600) statmsbreg = stmpe->regs[STMPE_IDX_ISGPIOR_LSB]; else statmsbreg = stmpe->regs[STMPE_IDX_ISGPIOR_MSB]; ret = stmpe_block_read(stmpe, statmsbreg, num_banks, status); if (ret < 0) return IRQ_NONE; for (i = 0; i < num_banks; i++) { int bank = num_banks - i - 1; int bank = (stmpe_gpio->stmpe->partnum == STMPE1600) ? i : num_banks - i - 1; unsigned int enabled = stmpe_gpio->regs[REG_IE][bank]; unsigned int stat = status[i]; Loading @@ -336,12 +403,18 @@ static irqreturn_t stmpe_gpio_irq(int irq, void *dev) stat &= ~(1 << bit); } /* * interrupt status register write has no effect on * 801/1801/1600, bits are cleared when read. * Edge detect register is not present on 801/1600/1801 */ if (stmpe->partnum != STMPE801 || stmpe->partnum != STMPE1600 || stmpe->partnum != STMPE1801) { stmpe_reg_write(stmpe, statmsbreg + i, status[i]); /* Edge detect register is not present on 801 */ if (stmpe->partnum != STMPE801) stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_GPEDR_MSB] + i, status[i]); stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_GPEDR_LSB + i], status[i]); } } return IRQ_HANDLED; Loading
drivers/mfd/stmpe-i2c.c +2 −0 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ static const struct of_device_id stmpe_of_match[] = { { .compatible = "st,stmpe610", .data = (void *)STMPE610, }, { .compatible = "st,stmpe801", .data = (void *)STMPE801, }, { .compatible = "st,stmpe811", .data = (void *)STMPE811, }, { .compatible = "st,stmpe1600", .data = (void *)STMPE1600, }, { .compatible = "st,stmpe1601", .data = (void *)STMPE1601, }, { .compatible = "st,stmpe1801", .data = (void *)STMPE1801, }, { .compatible = "st,stmpe2401", .data = (void *)STMPE2401, }, Loading Loading @@ -101,6 +102,7 @@ static const struct i2c_device_id stmpe_i2c_id[] = { { "stmpe610", STMPE610 }, { "stmpe801", STMPE801 }, { "stmpe811", STMPE811 }, { "stmpe1600", STMPE1600 }, { "stmpe1601", STMPE1601 }, { "stmpe1801", STMPE1801 }, { "stmpe2401", STMPE2401 }, Loading
drivers/mfd/stmpe.c +135 −26 Original line number Diff line number Diff line Loading @@ -469,6 +469,8 @@ static const struct mfd_cell stmpe_ts_cell = { static const u8 stmpe811_regs[] = { [STMPE_IDX_CHIP_ID] = STMPE811_REG_CHIP_ID, [STMPE_IDX_SYS_CTRL] = STMPE811_REG_SYS_CTRL, [STMPE_IDX_SYS_CTRL2] = STMPE811_REG_SYS_CTRL2, [STMPE_IDX_ICR_LSB] = STMPE811_REG_INT_CTRL, [STMPE_IDX_IER_LSB] = STMPE811_REG_INT_EN, [STMPE_IDX_ISR_MSB] = STMPE811_REG_INT_STA, Loading @@ -481,7 +483,7 @@ static const u8 stmpe811_regs[] = { [STMPE_IDX_GPAFR_U_MSB] = STMPE811_REG_GPIO_AF, [STMPE_IDX_IEGPIOR_LSB] = STMPE811_REG_GPIO_INT_EN, [STMPE_IDX_ISGPIOR_MSB] = STMPE811_REG_GPIO_INT_STA, [STMPE_IDX_GPEDR_MSB] = STMPE811_REG_GPIO_ED, [STMPE_IDX_GPEDR_LSB] = STMPE811_REG_GPIO_ED, }; static struct stmpe_variant_block stmpe811_blocks[] = { Loading Loading @@ -511,7 +513,7 @@ static int stmpe811_enable(struct stmpe *stmpe, unsigned int blocks, if (blocks & STMPE_BLOCK_TOUCHSCREEN) mask |= STMPE811_SYS_CTRL2_TSC_OFF; return __stmpe_set_bits(stmpe, STMPE811_REG_SYS_CTRL2, mask, return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], mask, enable ? 0 : mask); } Loading Loading @@ -550,26 +552,90 @@ static struct stmpe_variant_info stmpe610 = { .get_altfunc = stmpe811_get_altfunc, }; /* * STMPE1600 * Compared to all others STMPE variant, LSB and MSB regs are located in this * order : LSB addr * MSB addr + 1 * As there is only 2 * 8bits registers for GPMR/GPSR/IEGPIOPR, CSB index is MSB registers */ static const u8 stmpe1600_regs[] = { [STMPE_IDX_CHIP_ID] = STMPE1600_REG_CHIP_ID, [STMPE_IDX_SYS_CTRL] = STMPE1600_REG_SYS_CTRL, [STMPE_IDX_ICR_LSB] = STMPE1600_REG_SYS_CTRL, [STMPE_IDX_GPMR_LSB] = STMPE1600_REG_GPMR_LSB, [STMPE_IDX_GPMR_CSB] = STMPE1600_REG_GPMR_MSB, [STMPE_IDX_GPSR_LSB] = STMPE1600_REG_GPSR_LSB, [STMPE_IDX_GPSR_CSB] = STMPE1600_REG_GPSR_MSB, [STMPE_IDX_GPDR_LSB] = STMPE1600_REG_GPDR_LSB, [STMPE_IDX_GPDR_CSB] = STMPE1600_REG_GPDR_MSB, [STMPE_IDX_IEGPIOR_LSB] = STMPE1600_REG_IEGPIOR_LSB, [STMPE_IDX_IEGPIOR_CSB] = STMPE1600_REG_IEGPIOR_MSB, [STMPE_IDX_ISGPIOR_LSB] = STMPE1600_REG_ISGPIOR_LSB, }; static struct stmpe_variant_block stmpe1600_blocks[] = { { .cell = &stmpe_gpio_cell, .irq = 0, .block = STMPE_BLOCK_GPIO, }, }; static int stmpe1600_enable(struct stmpe *stmpe, unsigned int blocks, bool enable) { if (blocks & STMPE_BLOCK_GPIO) return 0; else return -EINVAL; } static struct stmpe_variant_info stmpe1600 = { .name = "stmpe1600", .id_val = STMPE1600_ID, .id_mask = 0xffff, .num_gpios = 16, .af_bits = 0, .regs = stmpe1600_regs, .blocks = stmpe1600_blocks, .num_blocks = ARRAY_SIZE(stmpe1600_blocks), .num_irqs = STMPE1600_NR_INTERNAL_IRQS, .enable = stmpe1600_enable, }; /* * STMPE1601 */ static const u8 stmpe1601_regs[] = { [STMPE_IDX_CHIP_ID] = STMPE1601_REG_CHIP_ID, [STMPE_IDX_SYS_CTRL] = STMPE1601_REG_SYS_CTRL, [STMPE_IDX_SYS_CTRL2] = STMPE1601_REG_SYS_CTRL2, [STMPE_IDX_ICR_LSB] = STMPE1601_REG_ICR_LSB, [STMPE_IDX_IER_MSB] = STMPE1601_REG_IER_MSB, [STMPE_IDX_IER_LSB] = STMPE1601_REG_IER_LSB, [STMPE_IDX_ISR_MSB] = STMPE1601_REG_ISR_MSB, [STMPE_IDX_GPMR_LSB] = STMPE1601_REG_GPIO_MP_LSB, [STMPE_IDX_GPMR_CSB] = STMPE1601_REG_GPIO_MP_MSB, [STMPE_IDX_GPSR_LSB] = STMPE1601_REG_GPIO_SET_LSB, [STMPE_IDX_GPSR_CSB] = STMPE1601_REG_GPIO_SET_MSB, [STMPE_IDX_GPCR_LSB] = STMPE1601_REG_GPIO_CLR_LSB, [STMPE_IDX_GPCR_CSB] = STMPE1601_REG_GPIO_CLR_MSB, [STMPE_IDX_GPDR_LSB] = STMPE1601_REG_GPIO_SET_DIR_LSB, [STMPE_IDX_GPDR_CSB] = STMPE1601_REG_GPIO_SET_DIR_MSB, [STMPE_IDX_GPEDR_LSB] = STMPE1601_REG_GPIO_ED_LSB, [STMPE_IDX_GPEDR_CSB] = STMPE1601_REG_GPIO_ED_MSB, [STMPE_IDX_GPRER_LSB] = STMPE1601_REG_GPIO_RE_LSB, [STMPE_IDX_GPRER_CSB] = STMPE1601_REG_GPIO_RE_MSB, [STMPE_IDX_GPFER_LSB] = STMPE1601_REG_GPIO_FE_LSB, [STMPE_IDX_GPFER_CSB] = STMPE1601_REG_GPIO_FE_MSB, [STMPE_IDX_GPPUR_LSB] = STMPE1601_REG_GPIO_PU_LSB, [STMPE_IDX_GPAFR_U_MSB] = STMPE1601_REG_GPIO_AF_U_MSB, [STMPE_IDX_IEGPIOR_LSB] = STMPE1601_REG_INT_EN_GPIO_MASK_LSB, [STMPE_IDX_IEGPIOR_CSB] = STMPE1601_REG_INT_EN_GPIO_MASK_MSB, [STMPE_IDX_ISGPIOR_MSB] = STMPE1601_REG_INT_STA_GPIO_MSB, [STMPE_IDX_GPEDR_MSB] = STMPE1601_REG_GPIO_ED_MSB, }; static struct stmpe_variant_block stmpe1601_blocks[] = { Loading Loading @@ -640,13 +706,13 @@ static int stmpe1601_autosleep(struct stmpe *stmpe, return timeout; } ret = __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2, ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], STMPE1601_AUTOSLEEP_TIMEOUT_MASK, timeout); if (ret < 0) return ret; return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL2, return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL2], STPME1601_AUTOSLEEP_ENABLE, STPME1601_AUTOSLEEP_ENABLE); } Loading @@ -671,7 +737,7 @@ static int stmpe1601_enable(struct stmpe *stmpe, unsigned int blocks, else mask &= ~STMPE1601_SYS_CTRL_ENABLE_SPWM; return __stmpe_set_bits(stmpe, STMPE1601_REG_SYS_CTRL, mask, return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask, enable ? mask : 0); } Loading Loading @@ -710,18 +776,33 @@ static struct stmpe_variant_info stmpe1601 = { */ static const u8 stmpe1801_regs[] = { [STMPE_IDX_CHIP_ID] = STMPE1801_REG_CHIP_ID, [STMPE_IDX_SYS_CTRL] = STMPE1801_REG_SYS_CTRL, [STMPE_IDX_ICR_LSB] = STMPE1801_REG_INT_CTRL_LOW, [STMPE_IDX_IER_LSB] = STMPE1801_REG_INT_EN_MASK_LOW, [STMPE_IDX_ISR_LSB] = STMPE1801_REG_INT_STA_LOW, [STMPE_IDX_GPMR_LSB] = STMPE1801_REG_GPIO_MP_LOW, [STMPE_IDX_GPMR_CSB] = STMPE1801_REG_GPIO_MP_MID, [STMPE_IDX_GPMR_MSB] = STMPE1801_REG_GPIO_MP_HIGH, [STMPE_IDX_GPSR_LSB] = STMPE1801_REG_GPIO_SET_LOW, [STMPE_IDX_GPSR_CSB] = STMPE1801_REG_GPIO_SET_MID, [STMPE_IDX_GPSR_MSB] = STMPE1801_REG_GPIO_SET_HIGH, [STMPE_IDX_GPCR_LSB] = STMPE1801_REG_GPIO_CLR_LOW, [STMPE_IDX_GPCR_CSB] = STMPE1801_REG_GPIO_CLR_MID, [STMPE_IDX_GPCR_MSB] = STMPE1801_REG_GPIO_CLR_HIGH, [STMPE_IDX_GPDR_LSB] = STMPE1801_REG_GPIO_SET_DIR_LOW, [STMPE_IDX_GPDR_CSB] = STMPE1801_REG_GPIO_SET_DIR_MID, [STMPE_IDX_GPDR_MSB] = STMPE1801_REG_GPIO_SET_DIR_HIGH, [STMPE_IDX_GPRER_LSB] = STMPE1801_REG_GPIO_RE_LOW, [STMPE_IDX_GPRER_CSB] = STMPE1801_REG_GPIO_RE_MID, [STMPE_IDX_GPRER_MSB] = STMPE1801_REG_GPIO_RE_HIGH, [STMPE_IDX_GPFER_LSB] = STMPE1801_REG_GPIO_FE_LOW, [STMPE_IDX_GPFER_CSB] = STMPE1801_REG_GPIO_FE_MID, [STMPE_IDX_GPFER_MSB] = STMPE1801_REG_GPIO_FE_HIGH, [STMPE_IDX_GPPUR_LSB] = STMPE1801_REG_GPIO_PULL_UP_LOW, [STMPE_IDX_IEGPIOR_LSB] = STMPE1801_REG_INT_EN_GPIO_MASK_LOW, [STMPE_IDX_ISGPIOR_LSB] = STMPE1801_REG_INT_STA_GPIO_LOW, [STMPE_IDX_IEGPIOR_CSB] = STMPE1801_REG_INT_EN_GPIO_MASK_MID, [STMPE_IDX_IEGPIOR_MSB] = STMPE1801_REG_INT_EN_GPIO_MASK_HIGH, [STMPE_IDX_ISGPIOR_MSB] = STMPE1801_REG_INT_STA_GPIO_HIGH, }; static struct stmpe_variant_block stmpe1801_blocks[] = { Loading Loading @@ -751,22 +832,31 @@ static int stmpe1801_enable(struct stmpe *stmpe, unsigned int blocks, enable ? mask : 0); } static int stmpe1801_reset(struct stmpe *stmpe) static int stmpe_reset(struct stmpe *stmpe) { u16 id_val = stmpe->variant->id_val; unsigned long timeout; int ret = 0; u8 reset_bit; ret = __stmpe_set_bits(stmpe, STMPE1801_REG_SYS_CTRL, STMPE1801_MSK_SYS_CTRL_RESET, STMPE1801_MSK_SYS_CTRL_RESET); if (id_val == STMPE811_ID) /* STMPE801 and STMPE610 use bit 1 of SYS_CTRL register */ reset_bit = STMPE811_SYS_CTRL_RESET; else /* all other STMPE variant use bit 7 of SYS_CTRL register */ reset_bit = STMPE_SYS_CTRL_RESET; ret = __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], reset_bit, reset_bit); if (ret < 0) return ret; timeout = jiffies + msecs_to_jiffies(100); while (time_before(jiffies, timeout)) { ret = __stmpe_reg_read(stmpe, STMPE1801_REG_SYS_CTRL); ret = __stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL]); if (ret < 0) return ret; if (!(ret & STMPE1801_MSK_SYS_CTRL_RESET)) if (!(ret & reset_bit)) return 0; usleep_range(100, 200); } Loading Loading @@ -794,20 +884,39 @@ static struct stmpe_variant_info stmpe1801 = { static const u8 stmpe24xx_regs[] = { [STMPE_IDX_CHIP_ID] = STMPE24XX_REG_CHIP_ID, [STMPE_IDX_SYS_CTRL] = STMPE24XX_REG_SYS_CTRL, [STMPE_IDX_SYS_CTRL2] = STMPE24XX_REG_SYS_CTRL2, [STMPE_IDX_ICR_LSB] = STMPE24XX_REG_ICR_LSB, [STMPE_IDX_IER_MSB] = STMPE24XX_REG_IER_MSB, [STMPE_IDX_IER_LSB] = STMPE24XX_REG_IER_LSB, [STMPE_IDX_ISR_MSB] = STMPE24XX_REG_ISR_MSB, [STMPE_IDX_GPMR_LSB] = STMPE24XX_REG_GPMR_LSB, [STMPE_IDX_GPMR_CSB] = STMPE24XX_REG_GPMR_CSB, [STMPE_IDX_GPMR_MSB] = STMPE24XX_REG_GPMR_MSB, [STMPE_IDX_GPSR_LSB] = STMPE24XX_REG_GPSR_LSB, [STMPE_IDX_GPSR_CSB] = STMPE24XX_REG_GPSR_CSB, [STMPE_IDX_GPSR_MSB] = STMPE24XX_REG_GPSR_MSB, [STMPE_IDX_GPCR_LSB] = STMPE24XX_REG_GPCR_LSB, [STMPE_IDX_GPCR_CSB] = STMPE24XX_REG_GPCR_CSB, [STMPE_IDX_GPCR_MSB] = STMPE24XX_REG_GPCR_MSB, [STMPE_IDX_GPDR_LSB] = STMPE24XX_REG_GPDR_LSB, [STMPE_IDX_GPDR_CSB] = STMPE24XX_REG_GPDR_CSB, [STMPE_IDX_GPDR_MSB] = STMPE24XX_REG_GPDR_MSB, [STMPE_IDX_GPRER_LSB] = STMPE24XX_REG_GPRER_LSB, [STMPE_IDX_GPRER_CSB] = STMPE24XX_REG_GPRER_CSB, [STMPE_IDX_GPRER_MSB] = STMPE24XX_REG_GPRER_MSB, [STMPE_IDX_GPFER_LSB] = STMPE24XX_REG_GPFER_LSB, [STMPE_IDX_GPFER_CSB] = STMPE24XX_REG_GPFER_CSB, [STMPE_IDX_GPFER_MSB] = STMPE24XX_REG_GPFER_MSB, [STMPE_IDX_GPPUR_LSB] = STMPE24XX_REG_GPPUR_LSB, [STMPE_IDX_GPPDR_LSB] = STMPE24XX_REG_GPPDR_LSB, [STMPE_IDX_GPAFR_U_MSB] = STMPE24XX_REG_GPAFR_U_MSB, [STMPE_IDX_IEGPIOR_LSB] = STMPE24XX_REG_IEGPIOR_LSB, [STMPE_IDX_IEGPIOR_CSB] = STMPE24XX_REG_IEGPIOR_CSB, [STMPE_IDX_IEGPIOR_MSB] = STMPE24XX_REG_IEGPIOR_MSB, [STMPE_IDX_ISGPIOR_MSB] = STMPE24XX_REG_ISGPIOR_MSB, [STMPE_IDX_GPEDR_LSB] = STMPE24XX_REG_GPEDR_LSB, [STMPE_IDX_GPEDR_CSB] = STMPE24XX_REG_GPEDR_CSB, [STMPE_IDX_GPEDR_MSB] = STMPE24XX_REG_GPEDR_MSB, }; Loading Loading @@ -840,7 +949,7 @@ static int stmpe24xx_enable(struct stmpe *stmpe, unsigned int blocks, if (blocks & STMPE_BLOCK_KEYPAD) mask |= STMPE24XX_SYS_CTRL_ENABLE_KPC; return __stmpe_set_bits(stmpe, STMPE24XX_REG_SYS_CTRL, mask, return __stmpe_set_bits(stmpe, stmpe->regs[STMPE_IDX_SYS_CTRL], mask, enable ? mask : 0); } Loading Loading @@ -893,6 +1002,7 @@ static struct stmpe_variant_info *stmpe_variant_info[STMPE_NBR_PARTS] = { [STMPE610] = &stmpe610, [STMPE801] = &stmpe801, [STMPE811] = &stmpe811, [STMPE1600] = &stmpe1600, [STMPE1601] = &stmpe1601, [STMPE1801] = &stmpe1801, [STMPE2401] = &stmpe2401, Loading @@ -919,7 +1029,8 @@ static irqreturn_t stmpe_irq(int irq, void *data) int ret; int i; if (variant->id_val == STMPE801_ID) { if (variant->id_val == STMPE801_ID || variant->id_val == STMPE1600_ID) { int base = irq_create_mapping(stmpe->domain, 0); handle_nested_irq(base); Loading Loading @@ -982,7 +1093,7 @@ static void stmpe_irq_sync_unlock(struct irq_data *data) continue; stmpe->oldier[i] = new; stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB] - i, new); stmpe_reg_write(stmpe, stmpe->regs[STMPE_IDX_IER_LSB + i], new); } mutex_unlock(&stmpe->irq_lock); Loading Loading @@ -1088,20 +1199,18 @@ static int stmpe_chip_init(struct stmpe *stmpe) if (ret) return ret; if (id == STMPE1801_ID) { ret = stmpe1801_reset(stmpe); ret = stmpe_reset(stmpe); if (ret < 0) return ret; } if (stmpe->irq >= 0) { if (id == STMPE801_ID) icr = STMPE801_REG_SYS_CTRL_INT_EN; if (id == STMPE801_ID || id == STMPE1600_ID) icr = STMPE_SYS_CTRL_INT_EN; else icr = STMPE_ICR_LSB_GIM; /* STMPE801 doesn't support Edge interrupts */ if (id != STMPE801_ID) { /* STMPE801 and STMPE1600 don't support Edge interrupts */ if (id != STMPE801_ID && id != STMPE1600_ID) { if (irq_trigger == IRQF_TRIGGER_FALLING || irq_trigger == IRQF_TRIGGER_RISING) icr |= STMPE_ICR_LSB_EDGE; Loading @@ -1109,8 +1218,8 @@ static int stmpe_chip_init(struct stmpe *stmpe) if (irq_trigger == IRQF_TRIGGER_RISING || irq_trigger == IRQF_TRIGGER_HIGH) { if (id == STMPE801_ID) icr |= STMPE801_REG_SYS_CTRL_INT_HI; if (id == STMPE801_ID || id == STMPE1600_ID) icr |= STMPE_SYS_CTRL_INT_HI; else icr |= STMPE_ICR_LSB_HIGH; } Loading
drivers/mfd/stmpe.h +73 −12 Original line number Diff line number Diff line Loading @@ -104,6 +104,10 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE_ICR_LSB_EDGE (1 << 1) #define STMPE_ICR_LSB_GIM (1 << 0) #define STMPE_SYS_CTRL_RESET (1 << 7) #define STMPE_SYS_CTRL_INT_EN (1 << 2) #define STMPE_SYS_CTRL_INT_HI (1 << 0) /* * STMPE801 */ Loading @@ -119,13 +123,10 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE801_REG_GPIO_SET_PIN 0x11 #define STMPE801_REG_GPIO_DIR 0x12 #define STMPE801_REG_SYS_CTRL_RESET (1 << 7) #define STMPE801_REG_SYS_CTRL_INT_EN (1 << 2) #define STMPE801_REG_SYS_CTRL_INT_HI (1 << 0) /* * STMPE811 */ #define STMPE811_ID 0x0811 #define STMPE811_IRQ_TOUCH_DET 0 #define STMPE811_IRQ_FIFO_TH 1 Loading @@ -138,6 +139,7 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE811_NR_INTERNAL_IRQS 8 #define STMPE811_REG_CHIP_ID 0x00 #define STMPE811_REG_SYS_CTRL 0x03 #define STMPE811_REG_SYS_CTRL2 0x04 #define STMPE811_REG_SPI_CFG 0x08 #define STMPE811_REG_INT_CTRL 0x09 Loading @@ -154,11 +156,34 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE811_REG_GPIO_FE 0x16 #define STMPE811_REG_GPIO_AF 0x17 #define STMPE811_SYS_CTRL_RESET (1 << 1) #define STMPE811_SYS_CTRL2_ADC_OFF (1 << 0) #define STMPE811_SYS_CTRL2_TSC_OFF (1 << 1) #define STMPE811_SYS_CTRL2_GPIO_OFF (1 << 2) #define STMPE811_SYS_CTRL2_TS_OFF (1 << 3) /* * STMPE1600 */ #define STMPE1600_ID 0x0016 #define STMPE1600_NR_INTERNAL_IRQS 16 #define STMPE1600_REG_CHIP_ID 0x00 #define STMPE1600_REG_SYS_CTRL 0x03 #define STMPE1600_REG_IEGPIOR_LSB 0x08 #define STMPE1600_REG_IEGPIOR_MSB 0x09 #define STMPE1600_REG_ISGPIOR_LSB 0x0A #define STMPE1600_REG_ISGPIOR_MSB 0x0B #define STMPE1600_REG_GPMR_LSB 0x10 #define STMPE1600_REG_GPMR_MSB 0x11 #define STMPE1600_REG_GPSR_LSB 0x12 #define STMPE1600_REG_GPSR_MSB 0x13 #define STMPE1600_REG_GPDR_LSB 0x14 #define STMPE1600_REG_GPDR_MSB 0x15 #define STMPE1600_REG_GPPIR_LSB 0x16 #define STMPE1600_REG_GPPIR_MSB 0x17 /* * STMPE1601 */ Loading @@ -175,19 +200,32 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE1601_REG_SYS_CTRL 0x02 #define STMPE1601_REG_SYS_CTRL2 0x03 #define STMPE1601_REG_ICR_MSB 0x10 #define STMPE1601_REG_ICR_LSB 0x11 #define STMPE1601_REG_IER_MSB 0x12 #define STMPE1601_REG_IER_LSB 0x13 #define STMPE1601_REG_ISR_MSB 0x14 #define STMPE1601_REG_CHIP_ID 0x80 #define STMPE1601_REG_ISR_LSB 0x15 #define STMPE1601_REG_INT_EN_GPIO_MASK_MSB 0x16 #define STMPE1601_REG_INT_EN_GPIO_MASK_LSB 0x17 #define STMPE1601_REG_INT_STA_GPIO_MSB 0x18 #define STMPE1601_REG_GPIO_MP_LSB 0x87 #define STMPE1601_REG_INT_STA_GPIO_LSB 0x19 #define STMPE1601_REG_CHIP_ID 0x80 #define STMPE1601_REG_GPIO_SET_MSB 0x82 #define STMPE1601_REG_GPIO_SET_LSB 0x83 #define STMPE1601_REG_GPIO_CLR_MSB 0x84 #define STMPE1601_REG_GPIO_CLR_LSB 0x85 #define STMPE1601_REG_GPIO_MP_MSB 0x86 #define STMPE1601_REG_GPIO_MP_LSB 0x87 #define STMPE1601_REG_GPIO_SET_DIR_MSB 0x88 #define STMPE1601_REG_GPIO_SET_DIR_LSB 0x89 #define STMPE1601_REG_GPIO_ED_MSB 0x8A #define STMPE1601_REG_GPIO_ED_LSB 0x8B #define STMPE1601_REG_GPIO_RE_MSB 0x8C #define STMPE1601_REG_GPIO_RE_LSB 0x8D #define STMPE1601_REG_GPIO_FE_MSB 0x8E #define STMPE1601_REG_GPIO_FE_LSB 0x8F #define STMPE1601_REG_GPIO_PU_MSB 0x90 #define STMPE1601_REG_GPIO_PU_LSB 0x91 #define STMPE1601_REG_GPIO_AF_U_MSB 0x92 Loading Loading @@ -243,8 +281,6 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE1801_REG_GPIO_PULL_UP_MID 0x23 #define STMPE1801_REG_GPIO_PULL_UP_HIGH 0x24 #define STMPE1801_MSK_SYS_CTRL_RESET (1 << 7) #define STMPE1801_MSK_INT_EN_KPC (1 << 1) #define STMPE1801_MSK_INT_EN_GPIO (1 << 3) Loading @@ -264,23 +300,48 @@ int stmpe_remove(struct stmpe *stmpe); #define STMPE24XX_NR_INTERNAL_IRQS 9 #define STMPE24XX_REG_SYS_CTRL 0x02 #define STMPE24XX_REG_SYS_CTRL2 0x03 #define STMPE24XX_REG_ICR_MSB 0x10 #define STMPE24XX_REG_ICR_LSB 0x11 #define STMPE24XX_REG_IER_MSB 0x12 #define STMPE24XX_REG_IER_LSB 0x13 #define STMPE24XX_REG_ISR_MSB 0x14 #define STMPE24XX_REG_CHIP_ID 0x80 #define STMPE24XX_REG_ISR_LSB 0x15 #define STMPE24XX_REG_IEGPIOR_MSB 0x16 #define STMPE24XX_REG_IEGPIOR_CSB 0x17 #define STMPE24XX_REG_IEGPIOR_LSB 0x18 #define STMPE24XX_REG_ISGPIOR_MSB 0x19 #define STMPE24XX_REG_GPMR_LSB 0xA4 #define STMPE24XX_REG_ISGPIOR_CSB 0x1A #define STMPE24XX_REG_ISGPIOR_LSB 0x1B #define STMPE24XX_REG_CHIP_ID 0x80 #define STMPE24XX_REG_GPSR_MSB 0x83 #define STMPE24XX_REG_GPSR_CSB 0x84 #define STMPE24XX_REG_GPSR_LSB 0x85 #define STMPE24XX_REG_GPCR_MSB 0x86 #define STMPE24XX_REG_GPCR_CSB 0x87 #define STMPE24XX_REG_GPCR_LSB 0x88 #define STMPE24XX_REG_GPDR_MSB 0x89 #define STMPE24XX_REG_GPDR_CSB 0x8A #define STMPE24XX_REG_GPDR_LSB 0x8B #define STMPE24XX_REG_GPEDR_MSB 0x8C #define STMPE24XX_REG_GPEDR_CSB 0x8D #define STMPE24XX_REG_GPEDR_LSB 0x8E #define STMPE24XX_REG_GPRER_MSB 0x8F #define STMPE24XX_REG_GPRER_CSB 0x90 #define STMPE24XX_REG_GPRER_LSB 0x91 #define STMPE24XX_REG_GPFER_MSB 0x92 #define STMPE24XX_REG_GPFER_CSB 0x93 #define STMPE24XX_REG_GPFER_LSB 0x94 #define STMPE24XX_REG_GPPUR_MSB 0x95 #define STMPE24XX_REG_GPPUR_CSB 0x96 #define STMPE24XX_REG_GPPUR_LSB 0x97 #define STMPE24XX_REG_GPPDR_LSB 0x9a #define STMPE24XX_REG_GPPDR_MSB 0x98 #define STMPE24XX_REG_GPPDR_CSB 0x99 #define STMPE24XX_REG_GPPDR_LSB 0x9A #define STMPE24XX_REG_GPAFR_U_MSB 0x9B #define STMPE24XX_REG_GPMR_MSB 0xA2 #define STMPE24XX_REG_GPMR_CSB 0xA3 #define STMPE24XX_REG_GPMR_LSB 0xA4 #define STMPE24XX_SYS_CTRL_ENABLE_GPIO (1 << 3) #define STMPE24XX_SYSCON_ENABLE_PWM (1 << 2) #define STMPE24XX_SYS_CTRL_ENABLE_KPC (1 << 1) Loading