From b29086188b50e3794533074c2831b4b44507e7e9 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 22 Jan 2010 12:48:41 +0100 Subject: pcf50633: Move pcf50633-gpio driver to the gpio drivers folder --- drivers/gpio/Kconfig | 7 ++ drivers/gpio/Makefile | 1 + drivers/gpio/pcf50633-gpio.c | 228 +++++++++++++++++++++++++++++++++++++++++++ drivers/mfd/Kconfig | 9 +- drivers/mfd/Makefile | 2 +- drivers/mfd/pcf50633-gpio.c | 228 ------------------------------------------- 6 files changed, 239 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 2ad0128c63c..c1a4e822344 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -172,6 +172,13 @@ config GPIO_ADP5520 To compile this driver as a module, choose M here: the module will be called adp5520-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_BT8XX diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 00a532c9a1e..25d66f19fb2 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -19,3 +19,4 @@ obj-$(CONFIG_GPIO_XILINX) += xilinx_gpio.o obj-$(CONFIG_GPIO_BT8XX) += bt8xxgpio.o obj-$(CONFIG_GPIO_VR41XX) += vr41xx_giu.o obj-$(CONFIG_GPIO_WM831X) += wm831x-gpio.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 00000000000..dc49defed23 --- /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 + * Copyright 2010, Lars-Peter Clausen + * 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 +#include + +#include + +#include +#include +#include + +#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) +{ + struct pcf50633 *pcf = dev_to_pcf50633(chip->dev->parent); + return pcf; +} + +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 ? 0x0 : 0x7); +} + +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; + + gpio -= pcf->pdata->gpio_base; + + if (gpio < 3) { + direction = (config == PCF50633_GPIO_CONFIG_INPUT) ? (1 << gpio) : 0; + ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_GPIOCTL, (1 << gpio), + direction); + if (ret) { + return ret; + } + } else if (gpio > 3 || config == PCF50633_GPIO_CONFIG_INPUT) { + return -EINVAL; + } + + if (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 << (gpio - PCF50633_GPIO1); + 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 "); +MODULE_DESCRIPTION("GPIO driver for the PCF50633"); +MODULE_LICENSE("GPL"); diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 570be139f9d..0c2126fe16c 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -268,13 +268,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 AB3100_CORE tristate "ST-Ericsson AB3100 Mixed Signal Circuit core functions" depends on I2C @@ -305,6 +298,8 @@ config EZX_PCAP This enables the PCAP ASIC present on EZX Phones. This is needed for MMC, TouchScreen, Sound, USB, etc.. +source "drivers/mfd/glamo/Kconfig" + endmenu menu "Multimedia Capabilities Port drivers" diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index f3b277b90d4..f30cede74c2 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_MFD_SM501) += sm501.o obj-$(CONFIG_MFD_ASIC3) += asic3.o +obj-$(CONFIG_MFD_GLAMO) += glamo/ obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o @@ -47,6 +48,5 @@ obj-$(CONFIG_PMIC_DA903X) += da903x.o obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o -obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.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 dc49defed23..00000000000 --- 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 - * Copyright 2010, Lars-Peter Clausen - * 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 -#include - -#include - -#include -#include -#include - -#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) -{ - struct pcf50633 *pcf = dev_to_pcf50633(chip->dev->parent); - return pcf; -} - -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 ? 0x0 : 0x7); -} - -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; - - gpio -= pcf->pdata->gpio_base; - - if (gpio < 3) { - direction = (config == PCF50633_GPIO_CONFIG_INPUT) ? (1 << gpio) : 0; - ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_GPIOCTL, (1 << gpio), - direction); - if (ret) { - return ret; - } - } else if (gpio > 3 || config == PCF50633_GPIO_CONFIG_INPUT) { - return -EINVAL; - } - - if (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 << (gpio - PCF50633_GPIO1); - 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 "); -MODULE_DESCRIPTION("GPIO driver for the PCF50633"); -MODULE_LICENSE("GPL"); -- cgit v1.2.3