/* * These registers are modified under the irq bus lock and cached to avoid * unnecessary writes in bus_sync_unlock.
*/ 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)
struct stmpe_gpio { struct gpio_chip chip; struct stmpe *stmpe; struct mutex irq_lock;
u32 norequest_mask; /* Caches of interrupt control registers for bus_lock */
u8 regs[CACHE_NR_REGS][CACHE_NR_BANKS];
u8 oldregs[CACHE_NR_REGS][CACHE_NR_BANKS];
};
/* * Some variants have single register for gpio set/clear functionality. * For them we need to write 0 to clear and 1 to set.
*/ if (stmpe->regs[STMPE_IDX_GPSR_LSB] == stmpe->regs[STMPE_IDX_GPCR_LSB]) return stmpe_set_bits(stmpe, reg, mask, val ? mask : 0);
if (type & IRQ_TYPE_LEVEL_LOW || type & IRQ_TYPE_LEVEL_HIGH) return -EINVAL;
/* STMPE801 and STMPE 1600 don't have RE and FE registers */ if (stmpe_gpio->stmpe->partnum == STMPE801 ||
stmpe_gpio->stmpe->partnum == STMPE1600) return 0;
/* * STMPE1600: 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) {
ret = stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_LSB]); if (ret < 0) {
dev_err(stmpe->dev, "Failed to read GPMR_LSB: %d\n", ret); goto err;
}
ret = stmpe_reg_read(stmpe, stmpe->regs[STMPE_IDX_GPMR_CSB]); if (ret < 0) {
dev_err(stmpe->dev, "Failed to read GPMR_CSB: %d\n", ret); goto err;
}
}
for (i = 0; i < CACHE_NR_REGS; i++) { /* STMPE801 and STMPE1600 don't have RE and FE registers */ if ((stmpe->partnum == STMPE801 ||
stmpe->partnum == STMPE1600) &&
(i != REG_IE)) continue;
for (j = 0; j < num_banks; j++) {
u8 old = stmpe_gpio->oldregs[i][j];
u8 new = stmpe_gpio->regs[i][j];
/* * 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 = (stmpe_gpio->stmpe->partnum == STMPE1600) ? i :
num_banks - i - 1; unsignedint enabled = stmpe_gpio->regs[REG_IE][bank]; unsignedint stat = status[i];
stat &= enabled; if (!stat) continue;
while (stat) { int bit = __ffs(stat); int line = bank * 8 + bit; int child_irq = irq_find_mapping(stmpe_gpio->chip.irq.domain,
line);
handle_nested_irq(child_irq);
stat &= ~BIT(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]);
stmpe_reg_write(stmpe,
stmpe->regs[STMPE_IDX_GPEDR_MSB] + i,
status[i]);
}
}
/* Forbid unused lines to be mapped as IRQs */ for (i = 0; i < sizeof(u32); i++) { if (stmpe_gpio->norequest_mask & BIT(i))
clear_bit(i, valid_mask);
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.