Commit de4b8941 authored by Linus Walleij's avatar Linus Walleij
Browse files

Merge tag 'ib-mfd-gpio-v4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd into devel

Immutable branch between MFD and GPIO due for the v4.9 merge window
parents 6ea5dcdf c6a05a05
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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:
+120 −47
Original line number Diff line number Diff line
@@ -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)
@@ -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;

@@ -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);

	/*
@@ -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);
@@ -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);
@@ -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)
@@ -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;

@@ -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);
		}
	}

@@ -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,
@@ -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;
@@ -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;
@@ -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]);
	}
}

@@ -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];

@@ -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;
+2 −0
Original line number Diff line number Diff line
@@ -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, },
@@ -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 },
+135 −26
Original line number Diff line number Diff line
@@ -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,
@@ -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[] = {
@@ -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);
}

@@ -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[] = {
@@ -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);
}
@@ -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);
}

@@ -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[] = {
@@ -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);
	}
@@ -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,
};

@@ -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);
}

@@ -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,
@@ -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);
@@ -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);
@@ -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;
@@ -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;
		}
+73 −12
Original line number Diff line number Diff line
@@ -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
 */
@@ -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
@@ -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
@@ -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
 */
@@ -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

@@ -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)

@@ -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