Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e31f9b82 authored by Chris Blair's avatar Chris Blair Committed by Samuel Ortiz
Browse files

mfd: Add support for no-interrupt stmpe config



Adds support for boards which have an STMPE device without the
interrupt pin connected.

Acked-by: default avatarViresh Kumar <viresh.kumar@st.com>
Signed-off-by: default avatarChris Blair <chris.blair@stericsson.com>
Tested-by: default avatarMichel Jaouen <michel.jaouen@stericsson.com>
Reviewed-by: default avatarSrinidhi Kasagar <srinidhi.kasagar@stericsson.com>
Signed-off-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Acked-by: default avatarViresh Kumar <viresh.kumar@st.com>
Signed-off-by: default avatarSamuel Ortiz <sameo@linux.intel.com>
parent 0dc299a3
Loading
Loading
Loading
Loading
+96 −38
Original line number Diff line number Diff line
@@ -298,6 +298,11 @@ static struct mfd_cell stmpe_gpio_cell = {
	.num_resources	= ARRAY_SIZE(stmpe_gpio_resources),
};

static struct mfd_cell stmpe_gpio_cell_noirq = {
	.name		= "stmpe-gpio",
	/* gpio cell resources consist of an irq only so no resources here */
};

/*
 * Keypad (1601, 2401, 2403)
 */
@@ -346,6 +351,13 @@ static struct stmpe_variant_block stmpe801_blocks[] = {
	},
};

static struct stmpe_variant_block stmpe801_blocks_noirq[] = {
	{
		.cell	= &stmpe_gpio_cell_noirq,
		.block	= STMPE_BLOCK_GPIO,
	},
};

static int stmpe801_enable(struct stmpe *stmpe, unsigned int blocks,
			   bool enable)
{
@@ -367,6 +379,17 @@ static struct stmpe_variant_info stmpe801 = {
	.enable		= stmpe801_enable,
};

static struct stmpe_variant_info stmpe801_noirq = {
	.name		= "stmpe801",
	.id_val		= STMPE801_ID,
	.id_mask	= 0xffff,
	.num_gpios	= 8,
	.regs		= stmpe801_regs,
	.blocks		= stmpe801_blocks_noirq,
	.num_blocks	= ARRAY_SIZE(stmpe801_blocks_noirq),
	.enable		= stmpe801_enable,
};

/*
 * Touchscreen (STMPE811 or STMPE610)
 */
@@ -712,7 +735,7 @@ static struct stmpe_variant_info stmpe2403 = {
	.enable_autosleep	= stmpe1601_autosleep, /* same as stmpe1601 */
};

static struct stmpe_variant_info *stmpe_variant_info[] = {
static struct stmpe_variant_info *stmpe_variant_info[STMPE_NBR_PARTS] = {
	[STMPE610]	= &stmpe610,
	[STMPE801]	= &stmpe801,
	[STMPE811]	= &stmpe811,
@@ -721,6 +744,16 @@ static struct stmpe_variant_info *stmpe_variant_info[] = {
	[STMPE2403]	= &stmpe2403,
};

/*
 * These devices can be connected in a 'no-irq' configuration - the irq pin
 * is not used and the device cannot interrupt the CPU. Here we only list
 * devices which support this configuration - the driver will fail probing
 * for any devices not listed here which are configured in this way.
 */
static struct stmpe_variant_info *stmpe_noirq_variant_info[STMPE_NBR_PARTS] = {
	[STMPE801]	= &stmpe801_noirq,
};

static irqreturn_t stmpe_irq(int irq, void *data)
{
	struct stmpe *stmpe = data;
@@ -864,7 +897,7 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe)
	unsigned int irq_trigger = stmpe->pdata->irq_trigger;
	int autosleep_timeout = stmpe->pdata->autosleep_timeout;
	struct stmpe_variant_info *variant = stmpe->variant;
	u8 icr;
	u8 icr = 0;
	unsigned int id;
	u8 data[2];
	int ret;
@@ -887,6 +920,7 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe)
	if (ret)
		return ret;

	if (stmpe->irq >= 0) {
		if (id == STMPE801_ID)
			icr = STMPE801_REG_SYS_CTRL_INT_EN;
		else
@@ -913,6 +947,7 @@ static int __devinit stmpe_chip_init(struct stmpe *stmpe)
			else
				icr ^= STMPE_ICR_LSB_HIGH;
		}
	}

	if (stmpe->pdata->autosleep) {
		ret = stmpe_autosleep(stmpe, autosleep_timeout);
@@ -1001,20 +1036,39 @@ int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum)
		stmpe->irq = ci->irq;
	}

	if (stmpe->irq < 0) {
		/* use alternate variant info for no-irq mode, if supported */
		dev_info(stmpe->dev,
			"%s configured in no-irq mode by platform data\n",
			stmpe->variant->name);
		if (!stmpe_noirq_variant_info[stmpe->partnum]) {
			dev_err(stmpe->dev,
				"%s does not support no-irq mode!\n",
				stmpe->variant->name);
			ret = -ENODEV;
			goto free_gpio;
		}
		stmpe->variant = stmpe_noirq_variant_info[stmpe->partnum];
	}

	ret = stmpe_chip_init(stmpe);
	if (ret)
		goto free_gpio;

	if (stmpe->irq >= 0) {
		ret = stmpe_irq_init(stmpe);
		if (ret)
			goto free_gpio;

		ret = request_threaded_irq(stmpe->irq, NULL, stmpe_irq,
			pdata->irq_trigger | IRQF_ONESHOT, "stmpe", stmpe);
				pdata->irq_trigger | IRQF_ONESHOT,
				"stmpe", stmpe);
		if (ret) {
		dev_err(stmpe->dev, "failed to request IRQ: %d\n", ret);
			dev_err(stmpe->dev, "failed to request IRQ: %d\n",
					ret);
			goto out_removeirq;
		}
	}

	ret = stmpe_devices_init(stmpe);
	if (ret) {
@@ -1026,8 +1080,10 @@ int __devinit stmpe_probe(struct stmpe_client_info *ci, int partnum)

out_removedevs:
	mfd_remove_devices(stmpe->dev);
	if (stmpe->irq >= 0)
		free_irq(stmpe->irq, stmpe);
out_removeirq:
	if (stmpe->irq >= 0)
		stmpe_irq_remove(stmpe);
free_gpio:
	if (pdata->irq_over_gpio)
@@ -1041,8 +1097,10 @@ int stmpe_remove(struct stmpe *stmpe)
{
	mfd_remove_devices(stmpe->dev);

	if (stmpe->irq >= 0) {
		free_irq(stmpe->irq, stmpe);
		stmpe_irq_remove(stmpe);
	}

	if (stmpe->pdata->irq_over_gpio)
		gpio_free(stmpe->pdata->irq_gpio);
@@ -1057,7 +1115,7 @@ static int stmpe_suspend(struct device *dev)
{
	struct stmpe *stmpe = dev_get_drvdata(dev);

	if (device_may_wakeup(dev))
	if (stmpe->irq >= 0 && device_may_wakeup(dev))
		enable_irq_wake(stmpe->irq);

	return 0;
@@ -1067,7 +1125,7 @@ static int stmpe_resume(struct device *dev)
{
	struct stmpe *stmpe = dev_get_drvdata(dev);

	if (device_may_wakeup(dev))
	if (stmpe->irq >= 0 && device_may_wakeup(dev))
		disable_irq_wake(stmpe->irq);

	return 0;
+1 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ enum stmpe_partnum {
	STMPE1601,
	STMPE2401,
	STMPE2403,
	STMPE_NBR_PARTS
};

/*