Skip to contentSkip to conversation

i2c-htcpld: Add the HTCPLD driver

PATCH Superseded Cory Maccarrone 2 participants 3 messages Dec 12, 2009 – Dec 14, 2009 2 messages not in the archive

Subsystems (2)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 i2c-htcpld: Add the HTCPLD driver

This change introduces a driver for the HTC PLD chip found on some smartphones, such as the HTC Wizard and HTC Herald. It works through the I2C bus and acts as a GPIO extender. Specifically:

* it can have several sub-devices, each with its own I2C address
* Each sub-device provides 8 output and 8 input pins
* The chip attaches to one GPIO to signal when any of the input GPIOs change -- at which point all chips must be scanned for changes

This driver implements the GPIOs throught the kernel's GPIO and IRQ framework. This allows any GPIO-servicing drivers to operate on htcpld pins, such as the gpio-keys and gpio-leds drivers.

---
 drivers/mfd/Kconfig      |    9 +
 drivers/mfd/Makefile     |    1 +
 drivers/mfd/htc-i2cpld.c |  608 ++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/htcpld.h   |   24 ++
 4 files changed, 642 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mfd/htc-i2cpld.c
 create mode 100644 include/linux/htcpld.h
drivers/mfd/Kconfig +9 -0
index 08f2d07..f8283cf 100644
@@ -60,6 +60,15 @@ config HTC_PASIC3
 	  HTC Magician devices, respectively. Actual functionality is
 	  handled by the leds-pasic3 and ds1wm drivers.
 
+config HTC_I2CPLD
+	bool "HTC I2C PLD chip support"
+	depends on I2C
+	help
+	  If you say yes here you get support for the supposed CPLD
+	  found on omap850 HTC devices like the HTC Wizard and HTC Herald.
+	  This device provides input and output GPIOs through an I2C
+	  interface to one or more sub-chips.
+
 config UCB1400_CORE
 	tristate "Philips UCB1400 Core driver"
 	depends on AC97_BUS
drivers/mfd/Makefile +1 -0
index af0fc90..a374457 100644
@@ -7,6 +7,7 @@ obj-$(CONFIG_MFD_ASIC3)		+= asic3.o
 
 obj-$(CONFIG_HTC_EGPIO)		+= htc-egpio.o
 obj-$(CONFIG_HTC_PASIC3)	+= htc-pasic3.o
+obj-$(CONFIG_HTC_I2CPLD)	+= htc-i2cpld.o
 
 obj-$(CONFIG_MFD_DM355EVM_MSP)	+= dm355evm_msp.o
 
drivers/mfd/htc-i2cpld.c new file +608 -0

608 lines not on this page · raw message

include/linux/htcpld.h new file +24 -0
new file mode 100644
index 0000000..ab3f6cb
@@ -0,0 +1,24 @@
+#ifndef __LINUX_HTCPLD_H
+#define __LINUX_HTCPLD_H
+
+struct htcpld_chip_platform_data {
+	unsigned int addr;
+	unsigned int reset;
+	unsigned int num_gpios;
+	unsigned int gpio_out_base;
+	unsigned int gpio_in_base;
+	unsigned int irq_base;
+	unsigned int num_irqs;
+};
+
+struct htcpld_core_platform_data {
+	unsigned int                      int_reset_gpio_hi;
+	unsigned int                      int_reset_gpio_lo;
+	unsigned int                      i2c_adapter_id;
+
+	struct htcpld_chip_platform_data  *chip;
+	unsigned int                      num_chip;
+};
+
+#endif /* __LINUX_HTCPLD_H */
+
Signature · 1 line
1.6.3.3

A message that is not in the archive (sent off-list or not yet received): 1260653372-29299-1-git-send-email-darkstar6262-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org

#2 lore raw
Quoted 3 lines · Cory Maccarrone
drivers/mfd/htc-i2cpld.c new file +3 -0
+static irqreturn_t htcpld_handler(int irq, void *dev)
+{
+	struct htcpld_data *htcpld = dev;

...

drivers/mfd/htc-i2cpld.c line 144

Quoted 7 lines
drivers/mfd/htc-i2cpld.c new file +7 -0
+	/* To properly dispatch IRQ events, we need to read from the
+	 * chip.  This is an I2C action that could possibly sleep
+	 * (which is bad here, since we're in interrupt context).
+	 * As such, the rest of this is implemented in a process-context
+	 * workload that will take care of the actual dispatch.
+	 */
+	schedule_delayed_work(&(htcpld->interrupt_work), 0);

request_threaded_irq() probably does what you want here and is more friendly to things like lockdep. There's an example of handling this sort of chip with the genirq infrastructure in the WM831x driver.

drivers/mfd/htc-i2cpld.c line 357

Quoted 13 lines
drivers/mfd/htc-i2cpld.c new file +13 -0
+static int __devinit htcpld_core_probe(struct platform_device *pdev)
+{
+	struct htcpld_data *htcpld;
+	struct device *dev = &pdev->dev;
+	struct htcpld_core_platform_data *pdata;
+	struct resource *res;
+	int i, ret = 0;
+	unsigned int irq, irq_end;
+
+	if (!dev)
+		return -ENODEV;
+
+	pdata = (struct htcpld_core_platform_data *)dev->platform_data;

You don't need to cast awat from void.

A message that is not in the archive (sent off-list or not yet received): [email protected]

#4 lore raw
Quoted 5 lines · Mark Brown

request_threaded_irq() probably does what you want here and is more friendly to things like lockdep.  There's an example of handling this sort of chip with the genirq infrastructure in the WM831x driver.

Ah, cool, I didn't know about that. That looks to be exactly what I want.

Quoted 3 lines

You don't need to cast awat from void.

Easy enough.

I'll make the changes and resubmit. Thanks for the feedback!

- Cory