mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 0/3] pcf50633: Replace custom gpio api with gpiolib
@ 2010-05-12  1:31 Lars-Peter Clausen
  2010-05-12  1:31 ` [PATCH 1/3] gta02: Remove usage of pcf50633 gpio api Lars-Peter Clausen
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Lars-Peter Clausen @ 2010-05-12  1:31 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, Lars-Peter Clausen

Hi

This patch series replaces the custom api in the pcf50633 gpio driver with
gpiolib. There is only one user of the custom api which can be safely removed.

Lars-Peter Clausen (3):
  gta02: Remove usage of pcf50633 gpio api
  MFD: pcf50633-gpio: Add gpiolib support
  MFD: pcf50633: Move pcf50633-gpio driver to the gpio drivers folder

 arch/arm/mach-s3c2440/Kconfig      |    1 -
 arch/arm/mach-s3c2440/mach-gta02.c |   12 +--
 drivers/gpio/Kconfig               |    7 +
 drivers/gpio/Makefile              |    1 +
 drivers/gpio/pcf50633-gpio.c       |  228 ++++++++++++++++++++++++++++++++++++
 drivers/mfd/Kconfig                |    7 -
 drivers/mfd/Makefile               |    1 -
 drivers/mfd/pcf50633-core.c        |    4 +-
 drivers/mfd/pcf50633-gpio.c        |  121 -------------------
 include/linux/mfd/pcf50633/core.h  |    4 +
 include/linux/mfd/pcf50633/gpio.h  |   61 +++++-----
 11 files changed, 277 insertions(+), 170 deletions(-)
 create mode 100644 drivers/gpio/pcf50633-gpio.c
 delete mode 100644 drivers/mfd/pcf50633-gpio.c


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] gta02: Remove usage of pcf50633 gpio api
  2010-05-12  1:31 [PATCH 0/3] pcf50633: Replace custom gpio api with gpiolib Lars-Peter Clausen
@ 2010-05-12  1:31 ` Lars-Peter Clausen
  2010-05-12  1:31 ` [PATCH 2/3] MFD: pcf50633-gpio: Add gpiolib support Lars-Peter Clausen
  2010-05-12  1:31 ` [PATCH 3/3] MFD: pcf50633: Move pcf50633-gpio driver to the gpio drivers folder Lars-Peter Clausen
  2 siblings, 0 replies; 4+ messages in thread
From: Lars-Peter Clausen @ 2010-05-12  1:31 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, Lars-Peter Clausen, Ben Dooks

This is the only user of the pcf50633 gpio api. Since the custom interface is
going to be replaced with gpiolib all users need to be removed or replaced.
It is safe to remove it in this case since it is used to turn a gpio off for
which there is no matching enable function call.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Cc: Ben Dooks <ben-linux@fluff.org>

---
 arch/arm/mach-s3c2440/Kconfig      |    1 -
 arch/arm/mach-s3c2440/mach-gta02.c |   12 ++----------
 2 files changed, 2 insertions(+), 11 deletions(-)

diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index 9d102b9..16e7066 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -95,7 +95,6 @@ config MACH_NEO1973_GTA02
 	bool "Openmoko GTA02 / Freerunner phone"
 	select CPU_S3C2442
 	select MFD_PCF50633
-	select PCF50633_GPIO
 	select I2C
 	select POWER_SUPPLY
 	select MACH_NEO1973
diff --git a/arch/arm/mach-s3c2440/mach-gta02.c b/arch/arm/mach-s3c2440/mach-gta02.c
index 120a26f..1c7d36d 100644
--- a/arch/arm/mach-s3c2440/mach-gta02.c
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
@@ -54,7 +54,6 @@
 #include <linux/mfd/pcf50633/core.h>
 #include <linux/mfd/pcf50633/mbc.h>
 #include <linux/mfd/pcf50633/adc.h>
-#include <linux/mfd/pcf50633/gpio.h>
 #include <linux/mfd/pcf50633/pmic.h>
 #include <linux/mfd/pcf50633/backlight.h>
 
@@ -167,16 +166,9 @@ gta02_configure_pmu_for_charger(struct pcf50633 *pcf, void *unused, int res)
 	int  ma;
 
 	/* Interpret charger type */
-	if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2)) {
-
-		/*
-		 * Sanity - stop GPO driving out now that we have a 1A charger
-		 * GPO controls USB Host power generation on GTA02
-		 */
-		pcf50633_gpio_set(pcf, PCF50633_GPO, 0);
-
+	if (res < ((ADC_NOM_CHG_DETECT_USB + ADC_NOM_CHG_DETECT_1A) / 2))
 		ma = 1000;
-	} else
+	else
 		ma = 100;
 
 	pcf50633_mbc_usb_curlim_set(pcf, ma);
-- 
1.5.6.5


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2/3] MFD: pcf50633-gpio: Add gpiolib support
  2010-05-12  1:31 [PATCH 0/3] pcf50633: Replace custom gpio api with gpiolib Lars-Peter Clausen
  2010-05-12  1:31 ` [PATCH 1/3] gta02: Remove usage of pcf50633 gpio api Lars-Peter Clausen
@ 2010-05-12  1:31 ` Lars-Peter Clausen
  2010-05-12  1:31 ` [PATCH 3/3] MFD: pcf50633: Move pcf50633-gpio driver to the gpio drivers folder Lars-Peter Clausen
  2 siblings, 0 replies; 4+ messages in thread
From: Lars-Peter Clausen @ 2010-05-12  1:31 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, Lars-Peter Clausen

This patch replaces the custom gpio interface of the pcf50633 gpio driver with
gpiolib. Although the pcf50633 offers more functionality then what can be
exposed through the gpiolib api this functionality is seldomly used. Furthermore
functions providing the additional functionality can be modeld on top of
gpiolib.
By using gpiolib it is possible to use generic drivers for devices connected to
one of the pcf50633 gpios.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 drivers/mfd/pcf50633-core.c       |    4 +-
 drivers/mfd/pcf50633-gpio.c       |  159 +++++++++++++++++++++++++++++++------
 include/linux/mfd/pcf50633/core.h |    4 +
 include/linux/mfd/pcf50633/gpio.h |   61 ++++++++-------
 4 files changed, 172 insertions(+), 56 deletions(-)

diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 704736e..87682c8 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -307,7 +307,8 @@ static int __devinit pcf50633_probe(struct i2c_client *client,
 						&pcf->adc_pdev);
 	pcf50633_client_dev_register(pcf, "pcf50633-backlight",
 						&pcf->bl_pdev);
-
+	pcf50633_client_dev_register(pcf, "pcf50633-gpio",
+						&pcf->gpio_pdev);
 
 	for (i = 0; i < PCF50633_NUM_REGULATORS; i++) {
 		struct platform_device *pdev;
@@ -349,6 +350,7 @@ static int __devexit pcf50633_remove(struct i2c_client *client)
 
 	pcf50633_irq_free(pcf);
 
+	platform_device_unregister(pcf->gpio_pdev);
 	platform_device_unregister(pcf->input_pdev);
 	platform_device_unregister(pcf->rtc_pdev);
 	platform_device_unregister(pcf->mbc_pdev);
diff --git a/drivers/mfd/pcf50633-gpio.c b/drivers/mfd/pcf50633-gpio.c
index 9ab19a8..237f53f 100644
--- a/drivers/mfd/pcf50633-gpio.c
+++ b/drivers/mfd/pcf50633-gpio.c
@@ -2,6 +2,7 @@
  *
  * (C) 2006-2008 by Openmoko, Inc.
  * Author: Balaji Rao <balajirrao@openmoko.org>
+ * Copyright 2010, Lars-Peter Clausen <lars@metafoo.de>
  * All rights reserved.
  *
  * Broken down from monstrous PCF50633 driver mainly by
@@ -16,9 +17,15 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
 
 #include <linux/mfd/pcf50633/core.h>
 #include <linux/mfd/pcf50633/gpio.h>
+#include <linux/gpio.h>
+
+#define PCF50633_REG_GPIOCTL	0x13
+#define PCF50633_REG_GPIOCFG(x) (0x14 + (x))
 
 enum pcf50633_regulator_id {
 	PCF50633_REGULATOR_AUTO,
@@ -60,62 +67,162 @@ static const u8 pcf50633_regulator_registers[PCF50633_NUM_REGULATORS] = {
 	[PCF50633_REGULATOR_HCLDO]	= PCF50633_REG_HCLDOOUT,
 };
 
-int pcf50633_gpio_set(struct pcf50633 *pcf, int gpio, u8 val)
+struct pcf50633_gpio {
+	struct pcf50633 *pcf;
+	struct gpio_chip chip;
+};
+
+static inline struct pcf50633 *gpio_chip_to_pcf50633(struct gpio_chip *chip)
+{
+	return dev_to_pcf50633(chip->dev->parent);
+}
+
+static void pcf50633_gpio_set_value(struct gpio_chip *chip, unsigned gpio,
+	int value)
 {
+	struct pcf50633 *pcf = gpio_chip_to_pcf50633(chip);
 	u8 reg;
 
-	reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
+	reg = PCF50633_REG_GPIOCFG(gpio);
 
-	return pcf50633_reg_set_bit_mask(pcf, reg, 0x07, val);
+	pcf50633_reg_set_bit_mask(pcf, reg, 0x07, value ? 0x7 : 0x0);
 }
-EXPORT_SYMBOL_GPL(pcf50633_gpio_set);
 
-u8 pcf50633_gpio_get(struct pcf50633 *pcf, int gpio)
+static int pcf50633_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
 {
-	u8 reg, val;
-
-	reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
-	val = pcf50633_reg_read(pcf, reg) & 0x07;
-
-	return val;
+	struct pcf50633 *pcf = gpio_chip_to_pcf50633(chip);
+	return pcf50633_reg_read(pcf, PCF50633_REG_GPIOCFG(gpio)) >> 3;
 }
-EXPORT_SYMBOL_GPL(pcf50633_gpio_get);
 
-int pcf50633_gpio_invert_set(struct pcf50633 *pcf, int gpio, int invert)
+
+static int pcf50633_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
+	int value)
 {
-	u8 val, reg;
+	struct pcf50633 *pcf = gpio_chip_to_pcf50633(chip);
+	int ret;
 
-	reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
-	val = !!invert << 3;
+	ret = pcf50633_gpio_set_config(pcf, pcf->pdata->gpio_base + gpio,
+		PCF50633_GPIO_CONFIG_OUTPUT);
+	if (!ret)
+		pcf50633_gpio_set_value(chip, gpio, value);
 
-	return pcf50633_reg_set_bit_mask(pcf, reg, 1 << 3, val);
+	return ret;
 }
-EXPORT_SYMBOL_GPL(pcf50633_gpio_invert_set);
 
-int pcf50633_gpio_invert_get(struct pcf50633 *pcf, int gpio)
+static int pcf50633_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
 {
-	u8 reg, val;
-
-	reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
-	val = pcf50633_reg_read(pcf, reg);
+	return -ENOSYS;
+}
 
-	return val & (1 << 3);
+int pcf50633_gpio_set_config(struct pcf50633 *pcf, unsigned gpio,
+	enum pcf50633_gpio_config config)
+{
+	u8 reg;
+	u8 direction;
+	int ret = 0;
+
+	gpio -= pcf->pdata->gpio_base;
+
+	if (gpio < 3) {
+		if (config == PCF50633_GPIO_CONFIG_INPUT)
+			direction = (1 << gpio);
+		else
+			direction = 0;
+		ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_GPIOCTL,
+			(1 << gpio), direction);
+	} else if (gpio > 3 || config == PCF50633_GPIO_CONFIG_INPUT) {
+		ret = -EINVAL;
+	}
+
+	if (!ret && config != PCF50633_GPIO_CONFIG_INPUT) {
+		reg = PCF50633_REG_GPIOCFG(gpio);
+		ret = pcf50633_reg_set_bit_mask(pcf, reg, 0x0f, config);
+	}
+
+	return ret;
 }
-EXPORT_SYMBOL_GPL(pcf50633_gpio_invert_get);
+EXPORT_SYMBOL_GPL(pcf50633_gpio_set_config);
 
 int pcf50633_gpio_power_supply_set(struct pcf50633 *pcf,
 					int gpio, int regulator, int on)
 {
 	u8 reg, val, mask;
 
+	gpio -= pcf->pdata->gpio_base;
+
 	/* the *ENA register is always one after the *OUT register */
 	reg = pcf50633_regulator_registers[regulator] + 1;
 
-	val = !!on << (gpio - PCF50633_GPIO1);
+	val = on ? (1 << (gpio - PCF50633_GPIO1)) : 0;
 	mask = 1 << (gpio - PCF50633_GPIO1);
 
 	return pcf50633_reg_set_bit_mask(pcf, reg, mask, val);
 }
 EXPORT_SYMBOL_GPL(pcf50633_gpio_power_supply_set);
 
+
+static int __devinit pcf50633_gpio_probe(struct platform_device *pdev)
+{
+	struct pcf50633 *pcf = dev_to_pcf50633(pdev->dev.parent);
+	struct pcf50633_gpio *pcf_gpio;
+
+	pcf_gpio = kzalloc(sizeof(*pcf_gpio), GFP_KERNEL);
+
+	if (!pcf_gpio)
+		return -ENOMEM;
+
+	pcf_gpio->pcf = pcf;
+
+	pcf_gpio->chip.direction_input = pcf50633_gpio_direction_input;
+	pcf_gpio->chip.direction_output = pcf50633_gpio_direction_output;
+	pcf_gpio->chip.get = pcf50633_gpio_get_value;
+	pcf_gpio->chip.set = pcf50633_gpio_set_value;
+
+	pcf_gpio->chip.base = pcf->pdata->gpio_base;
+	pcf_gpio->chip.ngpio = 4;
+	pcf_gpio->chip.label = dev_name(pcf->dev);
+	pcf_gpio->chip.can_sleep = 1;
+	pcf_gpio->chip.owner = THIS_MODULE;
+	pcf_gpio->chip.dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, pcf_gpio);
+
+	return gpiochip_add(&pcf_gpio->chip);
+}
+
+static int __devexit pcf50633_gpio_remove(struct platform_device *pdev)
+{
+	struct pcf50633_gpio *pcf_gpio = platform_get_drvdata(pdev);
+
+	gpiochip_remove(&pcf_gpio->chip);
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(pcf_gpio);
+
+	return 0;
+}
+
+static struct platform_driver pcf50633_gpio_driver = {
+	.probe = pcf50633_gpio_probe,
+	.remove = __devexit_p(pcf50633_gpio_remove),
+	.driver = {
+		.name = "pcf50633-gpio",
+		.owner = THIS_MODULE,
+	},
+};
+
+int __init pcf50633_gpio_init(void)
+{
+	return platform_driver_register(&pcf50633_gpio_driver);
+}
+module_init(pcf50633_gpio_init);
+
+void __exit pcf50633_gpio_exit(void)
+{
+	platform_driver_unregister(&pcf50633_gpio_driver);
+}
+module_exit(pcf50633_gpio_exit);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("GPIO driver for the PCF50633");
 MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/pcf50633/core.h b/include/linux/mfd/pcf50633/core.h
index ad411a7..9953fa1 100644
--- a/include/linux/mfd/pcf50633/core.h
+++ b/include/linux/mfd/pcf50633/core.h
@@ -19,6 +19,7 @@
 #include <linux/regulator/machine.h>
 #include <linux/power_supply.h>
 #include <linux/mfd/pcf50633/backlight.h>
+#include <linux/gpio.h>
 
 struct pcf50633;
 
@@ -46,6 +47,8 @@ struct pcf50633_platform_data {
 	u8 resumers[5];
 
 	struct pcf50633_bl_platform_data *backlight_data;
+
+	int gpio_base;
 };
 
 struct pcf50633_irq {
@@ -151,6 +154,7 @@ struct pcf50633 {
 
 	int onkey1s_held;
 
+	struct platform_device *gpio_pdev;
 	struct platform_device *rtc_pdev;
 	struct platform_device *mbc_pdev;
 	struct platform_device *adc_pdev;
diff --git a/include/linux/mfd/pcf50633/gpio.h b/include/linux/mfd/pcf50633/gpio.h
index a42b845..e430e68 100644
--- a/include/linux/mfd/pcf50633/gpio.h
+++ b/include/linux/mfd/pcf50633/gpio.h
@@ -15,38 +15,41 @@
 
 #include <linux/mfd/pcf50633/core.h>
 
-#define PCF50633_GPIO1		1
-#define PCF50633_GPIO2		2
-#define PCF50633_GPIO3		3
-#define PCF50633_GPO		4
-
-#define PCF50633_REG_GPIO1CFG	0x14
-#define PCF50633_REG_GPIO2CFG	0x15
-#define PCF50633_REG_GPIO3CFG	0x16
-#define PCF50633_REG_GPOCFG 	0x17
-
-#define PCF50633_GPOCFG_GPOSEL_MASK	0x07
-
-enum pcf50633_reg_gpocfg {
-	PCF50633_GPOCFG_GPOSEL_0	= 0x00,
-	PCF50633_GPOCFG_GPOSEL_LED_NFET	= 0x01,
-	PCF50633_GPOCFG_GPOSEL_SYSxOK	= 0x02,
-	PCF50633_GPOCFG_GPOSEL_CLK32K	= 0x03,
-	PCF50633_GPOCFG_GPOSEL_ADAPUSB	= 0x04,
-	PCF50633_GPOCFG_GPOSEL_USBxOK	= 0x05,
-	PCF50633_GPOCFG_GPOSEL_ACTPH4	= 0x06,
-	PCF50633_GPOCFG_GPOSEL_1	= 0x07,
-	PCF50633_GPOCFG_GPOSEL_INVERSE	= 0x08,
+#define PCF50633_GPIO1		0
+#define PCF50633_GPIO2		1
+#define PCF50633_GPIO3		2
+#define PCF50633_GPO		3
+
+#define PCF50633_REG_GPIOCFG(x) (0x14 + (x))
+
+enum pcf50633_gpio_config {
+	PCF50633_GPIO_CONFIG_OUTPUT	= 0x0,
+	PCF50633_GPIO_CONFIG_SYSxOK	= 0x2,
+	PCF50633_GPIO_CONFIG_CHARGING	= 0x3,
+	PCF50633_GPIO_CONFIG_MOBILE_MODE = 0x4,
+	PCF50633_GPIO_CONFIG_USBxOK	= 0x5,
+	PCF50633_GPIO_CONFIG_ACTPH	= 0x6,
+	PCF50633_GPIO_CONFIG_INPUT	= 0x7,
+
+	PCF50633_GPIO_CONFIG_INVERT	= 0x8,
+
+	PCF50633_GPO_CONFIG_OUTPUT	= 0x0,
+	PCF50633_GPO_CONFIG_LED_NFET	= 0x1,
+	PCF50633_GPO_CONFIG_SYSxOK	= 0x2,
+	PCF50633_GPO_CONFIG_CLK32K	= 0x3,
+	PCF50633_GPO_CONFIG_MOBILE_MODE = 0x4,
+	PCF50633_GPO_CONFIG_USBxOK	= 0x5,
+	PCF50633_GPO_CONFIG_ACTPH	= 0x6,
+	PCF50633_GPO_CONFIG_INPUT	= 0x7,
+
+	PCF50633_GPO_CONFIG_INVERT	= 0x8,
 };
 
-int pcf50633_gpio_set(struct pcf50633 *pcf, int gpio, u8 val);
-u8 pcf50633_gpio_get(struct pcf50633 *pcf, int gpio);
+int pcf50633_gpio_set_config(struct pcf50633 *pcf, unsigned gpio,
+	enum pcf50633_gpio_config config);
 
-int pcf50633_gpio_invert_set(struct pcf50633 *, int gpio, int invert);
-int pcf50633_gpio_invert_get(struct pcf50633 *pcf, int gpio);
-
-int pcf50633_gpio_power_supply_set(struct pcf50633 *,
-					int gpio, int regulator, int on);
+int pcf50633_gpio_power_supply_set(struct pcf50633 *pcf,
+	int gpio, int regulator, int on);
 #endif /* __LINUX_MFD_PCF50633_GPIO_H */
 
 
-- 
1.5.6.5


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 3/3] MFD: pcf50633: Move pcf50633-gpio driver to the gpio drivers folder
  2010-05-12  1:31 [PATCH 0/3] pcf50633: Replace custom gpio api with gpiolib Lars-Peter Clausen
  2010-05-12  1:31 ` [PATCH 1/3] gta02: Remove usage of pcf50633 gpio api Lars-Peter Clausen
  2010-05-12  1:31 ` [PATCH 2/3] MFD: pcf50633-gpio: Add gpiolib support Lars-Peter Clausen
@ 2010-05-12  1:31 ` Lars-Peter Clausen
  2 siblings, 0 replies; 4+ messages in thread
From: Lars-Peter Clausen @ 2010-05-12  1:31 UTC (permalink / raw)
  To: sameo; +Cc: linux-kernel, Lars-Peter Clausen

Now that the driver is implemented using gpiolib it should be moved to the gpio
drivers folder.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 drivers/gpio/Kconfig         |    7 ++
 drivers/gpio/Makefile        |    1 +
 drivers/gpio/pcf50633-gpio.c |  228 ++++++++++++++++++++++++++++++++++++++++++
 drivers/mfd/Kconfig          |    7 --
 drivers/mfd/Makefile         |    1 -
 drivers/mfd/pcf50633-gpio.c  |  228 ------------------------------------------
 6 files changed, 236 insertions(+), 236 deletions(-)
 create mode 100644 drivers/gpio/pcf50633-gpio.c
 delete mode 100644 drivers/mfd/pcf50633-gpio.c

diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index bde1bad..905fea4 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -242,6 +242,13 @@ config GPIO_ADP5588
 	  To compile this driver as a module, choose M here: the module will be
 	  called adp5588-gpio.
 
+config GPIO_PCF50633
+	tristate "GPIO support for NXP PCF50633"
+	depends on MFD_PCF50633
+	help
+	 Say yes here if you want to include support GPIO for pins on
+	 the PCF50633 chip.
+
 comment "PCI GPIO expanders:"
 
 config GPIO_CS5535
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 51c3cdd..928aede 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -31,3 +31,4 @@ obj-$(CONFIG_GPIO_WM8994)	+= wm8994-gpio.o
 obj-$(CONFIG_GPIO_SCH)		+= sch_gpio.o
 obj-$(CONFIG_GPIO_RDC321X)	+= rdc321x-gpio.o
 obj-$(CONFIG_GPIO_JANZ_TTL)	+= janz-ttl.o
+obj-$(CONFIG_GPIO_PCF50633)	+= pcf50633-gpio.o
diff --git a/drivers/gpio/pcf50633-gpio.c b/drivers/gpio/pcf50633-gpio.c
new file mode 100644
index 0000000..237f53f
--- /dev/null
+++ b/drivers/gpio/pcf50633-gpio.c
@@ -0,0 +1,228 @@
+/* NXP PCF50633 GPIO Driver
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * Author: Balaji Rao <balajirrao@openmoko.org>
+ * Copyright 2010, Lars-Peter Clausen <lars@metafoo.de>
+ * All rights reserved.
+ *
+ * Broken down from monstrous PCF50633 driver mainly by
+ * Harald Welte, Andy Green and Werner Almesberger
+ *
+ *  This program is free software; you can redistribute  it and/or modify it
+ *  under  the terms of  the GNU General  Public License as published by the
+ *  Free Software Foundation;  either version 2 of the  License, or (at your
+ *  option) any later version.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/gpio.h>
+#include <linux/gpio.h>
+
+#define PCF50633_REG_GPIOCTL	0x13
+#define PCF50633_REG_GPIOCFG(x) (0x14 + (x))
+
+enum pcf50633_regulator_id {
+	PCF50633_REGULATOR_AUTO,
+	PCF50633_REGULATOR_DOWN1,
+	PCF50633_REGULATOR_DOWN2,
+	PCF50633_REGULATOR_LDO1,
+	PCF50633_REGULATOR_LDO2,
+	PCF50633_REGULATOR_LDO3,
+	PCF50633_REGULATOR_LDO4,
+	PCF50633_REGULATOR_LDO5,
+	PCF50633_REGULATOR_LDO6,
+	PCF50633_REGULATOR_HCLDO,
+	PCF50633_REGULATOR_MEMLDO,
+};
+
+#define PCF50633_REG_AUTOOUT	0x1a
+#define PCF50633_REG_DOWN1OUT	0x1e
+#define PCF50633_REG_DOWN2OUT	0x22
+#define PCF50633_REG_MEMLDOOUT	0x26
+#define PCF50633_REG_LDO1OUT	0x2d
+#define PCF50633_REG_LDO2OUT	0x2f
+#define PCF50633_REG_LDO3OUT	0x31
+#define PCF50633_REG_LDO4OUT	0x33
+#define PCF50633_REG_LDO5OUT	0x35
+#define PCF50633_REG_LDO6OUT	0x37
+#define PCF50633_REG_HCLDOOUT	0x39
+
+static const u8 pcf50633_regulator_registers[PCF50633_NUM_REGULATORS] = {
+	[PCF50633_REGULATOR_AUTO]	= PCF50633_REG_AUTOOUT,
+	[PCF50633_REGULATOR_DOWN1]	= PCF50633_REG_DOWN1OUT,
+	[PCF50633_REGULATOR_DOWN2]	= PCF50633_REG_DOWN2OUT,
+	[PCF50633_REGULATOR_MEMLDO]	= PCF50633_REG_MEMLDOOUT,
+	[PCF50633_REGULATOR_LDO1]	= PCF50633_REG_LDO1OUT,
+	[PCF50633_REGULATOR_LDO2]	= PCF50633_REG_LDO2OUT,
+	[PCF50633_REGULATOR_LDO3]	= PCF50633_REG_LDO3OUT,
+	[PCF50633_REGULATOR_LDO4]	= PCF50633_REG_LDO4OUT,
+	[PCF50633_REGULATOR_LDO5]	= PCF50633_REG_LDO5OUT,
+	[PCF50633_REGULATOR_LDO6]	= PCF50633_REG_LDO6OUT,
+	[PCF50633_REGULATOR_HCLDO]	= PCF50633_REG_HCLDOOUT,
+};
+
+struct pcf50633_gpio {
+	struct pcf50633 *pcf;
+	struct gpio_chip chip;
+};
+
+static inline struct pcf50633 *gpio_chip_to_pcf50633(struct gpio_chip *chip)
+{
+	return dev_to_pcf50633(chip->dev->parent);
+}
+
+static void pcf50633_gpio_set_value(struct gpio_chip *chip, unsigned gpio,
+	int value)
+{
+	struct pcf50633 *pcf = gpio_chip_to_pcf50633(chip);
+	u8 reg;
+
+	reg = PCF50633_REG_GPIOCFG(gpio);
+
+	pcf50633_reg_set_bit_mask(pcf, reg, 0x07, value ? 0x7 : 0x0);
+}
+
+static int pcf50633_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+	struct pcf50633 *pcf = gpio_chip_to_pcf50633(chip);
+	return pcf50633_reg_read(pcf, PCF50633_REG_GPIOCFG(gpio)) >> 3;
+}
+
+
+static int pcf50633_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
+	int value)
+{
+	struct pcf50633 *pcf = gpio_chip_to_pcf50633(chip);
+	int ret;
+
+	ret = pcf50633_gpio_set_config(pcf, pcf->pdata->gpio_base + gpio,
+		PCF50633_GPIO_CONFIG_OUTPUT);
+	if (!ret)
+		pcf50633_gpio_set_value(chip, gpio, value);
+
+	return ret;
+}
+
+static int pcf50633_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
+{
+	return -ENOSYS;
+}
+
+int pcf50633_gpio_set_config(struct pcf50633 *pcf, unsigned gpio,
+	enum pcf50633_gpio_config config)
+{
+	u8 reg;
+	u8 direction;
+	int ret = 0;
+
+	gpio -= pcf->pdata->gpio_base;
+
+	if (gpio < 3) {
+		if (config == PCF50633_GPIO_CONFIG_INPUT)
+			direction = (1 << gpio);
+		else
+			direction = 0;
+		ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_GPIOCTL,
+			(1 << gpio), direction);
+	} else if (gpio > 3 || config == PCF50633_GPIO_CONFIG_INPUT) {
+		ret = -EINVAL;
+	}
+
+	if (!ret && config != PCF50633_GPIO_CONFIG_INPUT) {
+		reg = PCF50633_REG_GPIOCFG(gpio);
+		ret = pcf50633_reg_set_bit_mask(pcf, reg, 0x0f, config);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(pcf50633_gpio_set_config);
+
+int pcf50633_gpio_power_supply_set(struct pcf50633 *pcf,
+					int gpio, int regulator, int on)
+{
+	u8 reg, val, mask;
+
+	gpio -= pcf->pdata->gpio_base;
+
+	/* the *ENA register is always one after the *OUT register */
+	reg = pcf50633_regulator_registers[regulator] + 1;
+
+	val = on ? (1 << (gpio - PCF50633_GPIO1)) : 0;
+	mask = 1 << (gpio - PCF50633_GPIO1);
+
+	return pcf50633_reg_set_bit_mask(pcf, reg, mask, val);
+}
+EXPORT_SYMBOL_GPL(pcf50633_gpio_power_supply_set);
+
+
+static int __devinit pcf50633_gpio_probe(struct platform_device *pdev)
+{
+	struct pcf50633 *pcf = dev_to_pcf50633(pdev->dev.parent);
+	struct pcf50633_gpio *pcf_gpio;
+
+	pcf_gpio = kzalloc(sizeof(*pcf_gpio), GFP_KERNEL);
+
+	if (!pcf_gpio)
+		return -ENOMEM;
+
+	pcf_gpio->pcf = pcf;
+
+	pcf_gpio->chip.direction_input = pcf50633_gpio_direction_input;
+	pcf_gpio->chip.direction_output = pcf50633_gpio_direction_output;
+	pcf_gpio->chip.get = pcf50633_gpio_get_value;
+	pcf_gpio->chip.set = pcf50633_gpio_set_value;
+
+	pcf_gpio->chip.base = pcf->pdata->gpio_base;
+	pcf_gpio->chip.ngpio = 4;
+	pcf_gpio->chip.label = dev_name(pcf->dev);
+	pcf_gpio->chip.can_sleep = 1;
+	pcf_gpio->chip.owner = THIS_MODULE;
+	pcf_gpio->chip.dev = &pdev->dev;
+
+	platform_set_drvdata(pdev, pcf_gpio);
+
+	return gpiochip_add(&pcf_gpio->chip);
+}
+
+static int __devexit pcf50633_gpio_remove(struct platform_device *pdev)
+{
+	struct pcf50633_gpio *pcf_gpio = platform_get_drvdata(pdev);
+
+	gpiochip_remove(&pcf_gpio->chip);
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(pcf_gpio);
+
+	return 0;
+}
+
+static struct platform_driver pcf50633_gpio_driver = {
+	.probe = pcf50633_gpio_probe,
+	.remove = __devexit_p(pcf50633_gpio_remove),
+	.driver = {
+		.name = "pcf50633-gpio",
+		.owner = THIS_MODULE,
+	},
+};
+
+int __init pcf50633_gpio_init(void)
+{
+	return platform_driver_register(&pcf50633_gpio_driver);
+}
+module_init(pcf50633_gpio_init);
+
+void __exit pcf50633_gpio_exit(void)
+{
+	platform_driver_unregister(&pcf50633_gpio_driver);
+}
+module_exit(pcf50633_gpio_exit);
+
+MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
+MODULE_DESCRIPTION("GPIO driver for the PCF50633");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index fea62a9..440118e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -367,13 +367,6 @@ config PCF50633_ADC
 	 Say yes here if you want to include support for ADC in the
 	 NXP PCF50633 chip.
 
-config PCF50633_GPIO
-	tristate "Support for NXP PCF50633 GPIO"
-	depends on MFD_PCF50633
-	help
-	 Say yes here if you want to include support GPIO for pins on
-	 the PCF50633 chip.
-
 config ABX500_CORE
 	bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions"
 	default y if ARCH_U300
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index ca1517e..10fed9d 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -60,7 +60,6 @@ obj-$(CONFIG_MFD_MAX8925)	+= max8925.o
 pcf50633-objs			:= pcf50633-core.o pcf50633-irq.o
 obj-$(CONFIG_MFD_PCF50633)	+= pcf50633.o
 obj-$(CONFIG_PCF50633_ADC)	+= pcf50633-adc.o
-obj-$(CONFIG_PCF50633_GPIO)	+= pcf50633-gpio.o
 obj-$(CONFIG_ABX500_CORE)	+= abx500-core.o
 obj-$(CONFIG_AB3100_CORE)	+= ab3100-core.o
 obj-$(CONFIG_AB3100_OTP)	+= ab3100-otp.o
diff --git a/drivers/mfd/pcf50633-gpio.c b/drivers/mfd/pcf50633-gpio.c
deleted file mode 100644
index 237f53f..0000000
--- a/drivers/mfd/pcf50633-gpio.c
+++ /dev/null
@@ -1,228 +0,0 @@
-/* NXP PCF50633 GPIO Driver
- *
- * (C) 2006-2008 by Openmoko, Inc.
- * Author: Balaji Rao <balajirrao@openmoko.org>
- * Copyright 2010, Lars-Peter Clausen <lars@metafoo.de>
- * All rights reserved.
- *
- * Broken down from monstrous PCF50633 driver mainly by
- * Harald Welte, Andy Green and Werner Almesberger
- *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/platform_device.h>
-
-#include <linux/mfd/pcf50633/core.h>
-#include <linux/mfd/pcf50633/gpio.h>
-#include <linux/gpio.h>
-
-#define PCF50633_REG_GPIOCTL	0x13
-#define PCF50633_REG_GPIOCFG(x) (0x14 + (x))
-
-enum pcf50633_regulator_id {
-	PCF50633_REGULATOR_AUTO,
-	PCF50633_REGULATOR_DOWN1,
-	PCF50633_REGULATOR_DOWN2,
-	PCF50633_REGULATOR_LDO1,
-	PCF50633_REGULATOR_LDO2,
-	PCF50633_REGULATOR_LDO3,
-	PCF50633_REGULATOR_LDO4,
-	PCF50633_REGULATOR_LDO5,
-	PCF50633_REGULATOR_LDO6,
-	PCF50633_REGULATOR_HCLDO,
-	PCF50633_REGULATOR_MEMLDO,
-};
-
-#define PCF50633_REG_AUTOOUT	0x1a
-#define PCF50633_REG_DOWN1OUT	0x1e
-#define PCF50633_REG_DOWN2OUT	0x22
-#define PCF50633_REG_MEMLDOOUT	0x26
-#define PCF50633_REG_LDO1OUT	0x2d
-#define PCF50633_REG_LDO2OUT	0x2f
-#define PCF50633_REG_LDO3OUT	0x31
-#define PCF50633_REG_LDO4OUT	0x33
-#define PCF50633_REG_LDO5OUT	0x35
-#define PCF50633_REG_LDO6OUT	0x37
-#define PCF50633_REG_HCLDOOUT	0x39
-
-static const u8 pcf50633_regulator_registers[PCF50633_NUM_REGULATORS] = {
-	[PCF50633_REGULATOR_AUTO]	= PCF50633_REG_AUTOOUT,
-	[PCF50633_REGULATOR_DOWN1]	= PCF50633_REG_DOWN1OUT,
-	[PCF50633_REGULATOR_DOWN2]	= PCF50633_REG_DOWN2OUT,
-	[PCF50633_REGULATOR_MEMLDO]	= PCF50633_REG_MEMLDOOUT,
-	[PCF50633_REGULATOR_LDO1]	= PCF50633_REG_LDO1OUT,
-	[PCF50633_REGULATOR_LDO2]	= PCF50633_REG_LDO2OUT,
-	[PCF50633_REGULATOR_LDO3]	= PCF50633_REG_LDO3OUT,
-	[PCF50633_REGULATOR_LDO4]	= PCF50633_REG_LDO4OUT,
-	[PCF50633_REGULATOR_LDO5]	= PCF50633_REG_LDO5OUT,
-	[PCF50633_REGULATOR_LDO6]	= PCF50633_REG_LDO6OUT,
-	[PCF50633_REGULATOR_HCLDO]	= PCF50633_REG_HCLDOOUT,
-};
-
-struct pcf50633_gpio {
-	struct pcf50633 *pcf;
-	struct gpio_chip chip;
-};
-
-static inline struct pcf50633 *gpio_chip_to_pcf50633(struct gpio_chip *chip)
-{
-	return dev_to_pcf50633(chip->dev->parent);
-}
-
-static void pcf50633_gpio_set_value(struct gpio_chip *chip, unsigned gpio,
-	int value)
-{
-	struct pcf50633 *pcf = gpio_chip_to_pcf50633(chip);
-	u8 reg;
-
-	reg = PCF50633_REG_GPIOCFG(gpio);
-
-	pcf50633_reg_set_bit_mask(pcf, reg, 0x07, value ? 0x7 : 0x0);
-}
-
-static int pcf50633_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
-{
-	struct pcf50633 *pcf = gpio_chip_to_pcf50633(chip);
-	return pcf50633_reg_read(pcf, PCF50633_REG_GPIOCFG(gpio)) >> 3;
-}
-
-
-static int pcf50633_gpio_direction_output(struct gpio_chip *chip, unsigned gpio,
-	int value)
-{
-	struct pcf50633 *pcf = gpio_chip_to_pcf50633(chip);
-	int ret;
-
-	ret = pcf50633_gpio_set_config(pcf, pcf->pdata->gpio_base + gpio,
-		PCF50633_GPIO_CONFIG_OUTPUT);
-	if (!ret)
-		pcf50633_gpio_set_value(chip, gpio, value);
-
-	return ret;
-}
-
-static int pcf50633_gpio_direction_input(struct gpio_chip *chip, unsigned gpio)
-{
-	return -ENOSYS;
-}
-
-int pcf50633_gpio_set_config(struct pcf50633 *pcf, unsigned gpio,
-	enum pcf50633_gpio_config config)
-{
-	u8 reg;
-	u8 direction;
-	int ret = 0;
-
-	gpio -= pcf->pdata->gpio_base;
-
-	if (gpio < 3) {
-		if (config == PCF50633_GPIO_CONFIG_INPUT)
-			direction = (1 << gpio);
-		else
-			direction = 0;
-		ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_GPIOCTL,
-			(1 << gpio), direction);
-	} else if (gpio > 3 || config == PCF50633_GPIO_CONFIG_INPUT) {
-		ret = -EINVAL;
-	}
-
-	if (!ret && config != PCF50633_GPIO_CONFIG_INPUT) {
-		reg = PCF50633_REG_GPIOCFG(gpio);
-		ret = pcf50633_reg_set_bit_mask(pcf, reg, 0x0f, config);
-	}
-
-	return ret;
-}
-EXPORT_SYMBOL_GPL(pcf50633_gpio_set_config);
-
-int pcf50633_gpio_power_supply_set(struct pcf50633 *pcf,
-					int gpio, int regulator, int on)
-{
-	u8 reg, val, mask;
-
-	gpio -= pcf->pdata->gpio_base;
-
-	/* the *ENA register is always one after the *OUT register */
-	reg = pcf50633_regulator_registers[regulator] + 1;
-
-	val = on ? (1 << (gpio - PCF50633_GPIO1)) : 0;
-	mask = 1 << (gpio - PCF50633_GPIO1);
-
-	return pcf50633_reg_set_bit_mask(pcf, reg, mask, val);
-}
-EXPORT_SYMBOL_GPL(pcf50633_gpio_power_supply_set);
-
-
-static int __devinit pcf50633_gpio_probe(struct platform_device *pdev)
-{
-	struct pcf50633 *pcf = dev_to_pcf50633(pdev->dev.parent);
-	struct pcf50633_gpio *pcf_gpio;
-
-	pcf_gpio = kzalloc(sizeof(*pcf_gpio), GFP_KERNEL);
-
-	if (!pcf_gpio)
-		return -ENOMEM;
-
-	pcf_gpio->pcf = pcf;
-
-	pcf_gpio->chip.direction_input = pcf50633_gpio_direction_input;
-	pcf_gpio->chip.direction_output = pcf50633_gpio_direction_output;
-	pcf_gpio->chip.get = pcf50633_gpio_get_value;
-	pcf_gpio->chip.set = pcf50633_gpio_set_value;
-
-	pcf_gpio->chip.base = pcf->pdata->gpio_base;
-	pcf_gpio->chip.ngpio = 4;
-	pcf_gpio->chip.label = dev_name(pcf->dev);
-	pcf_gpio->chip.can_sleep = 1;
-	pcf_gpio->chip.owner = THIS_MODULE;
-	pcf_gpio->chip.dev = &pdev->dev;
-
-	platform_set_drvdata(pdev, pcf_gpio);
-
-	return gpiochip_add(&pcf_gpio->chip);
-}
-
-static int __devexit pcf50633_gpio_remove(struct platform_device *pdev)
-{
-	struct pcf50633_gpio *pcf_gpio = platform_get_drvdata(pdev);
-
-	gpiochip_remove(&pcf_gpio->chip);
-
-	platform_set_drvdata(pdev, NULL);
-	kfree(pcf_gpio);
-
-	return 0;
-}
-
-static struct platform_driver pcf50633_gpio_driver = {
-	.probe = pcf50633_gpio_probe,
-	.remove = __devexit_p(pcf50633_gpio_remove),
-	.driver = {
-		.name = "pcf50633-gpio",
-		.owner = THIS_MODULE,
-	},
-};
-
-int __init pcf50633_gpio_init(void)
-{
-	return platform_driver_register(&pcf50633_gpio_driver);
-}
-module_init(pcf50633_gpio_init);
-
-void __exit pcf50633_gpio_exit(void)
-{
-	platform_driver_unregister(&pcf50633_gpio_driver);
-}
-module_exit(pcf50633_gpio_exit);
-
-MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
-MODULE_DESCRIPTION("GPIO driver for the PCF50633");
-MODULE_LICENSE("GPL");
-- 
1.5.6.5


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2010-05-12  1:38 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-12  1:31 [PATCH 0/3] pcf50633: Replace custom gpio api with gpiolib Lars-Peter Clausen
2010-05-12  1:31 ` [PATCH 1/3] gta02: Remove usage of pcf50633 gpio api Lars-Peter Clausen
2010-05-12  1:31 ` [PATCH 2/3] MFD: pcf50633-gpio: Add gpiolib support Lars-Peter Clausen
2010-05-12  1:31 ` [PATCH 3/3] MFD: pcf50633: Move pcf50633-gpio driver to the gpio drivers folder Lars-Peter Clausen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®