i2c-htcpld: Add the HTCPLD driver
Subsystems (2)
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
@@ -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
@@ -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
@@ -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
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]
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