aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-s3c2440/Kconfig7
-rw-r--r--drivers/input/misc/Kconfig2
-rw-r--r--drivers/input/misc/pcf50633-input.c33
-rw-r--r--drivers/mfd/Kconfig20
-rw-r--r--drivers/mfd/Makefile5
-rw-r--r--drivers/mfd/pcf50633-adc.c27
-rw-r--r--drivers/mfd/pcf50633-core.c24
-rw-r--r--drivers/mfd/pcf50633-gpio.c109
-rw-r--r--drivers/mfd/pcf50633-mbc.c292
-rw-r--r--drivers/misc/neo1973_pm_host.c14
-rw-r--r--drivers/power/Kconfig6
-rw-r--r--drivers/power/Makefile2
-rw-r--r--drivers/regulator/Kconfig7
-rw-r--r--drivers/regulator/pcf50633-regulator.c38
-rw-r--r--drivers/rtc/Kconfig2
-rw-r--r--drivers/rtc/rtc-pcf50633.c28
-rw-r--r--include/linux/mfd/pcf50633/adc.h28
-rw-r--r--include/linux/mfd/pcf50633/core.h14
-rw-r--r--include/linux/mfd/pcf50633/gpio.h30
-rw-r--r--include/linux/mfd/pcf50633/input.h12
-rw-r--r--include/linux/mfd/pcf50633/led.h12
-rw-r--r--include/linux/mfd/pcf50633/mbc.h14
-rw-r--r--include/linux/mfd/pcf50633/rtc.h14
23 files changed, 341 insertions, 399 deletions
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
index 7eedb5a59e2..74c3d8e1d74 100644
--- a/arch/arm/mach-s3c2440/Kconfig
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -88,12 +88,11 @@ config MACH_NEO1973_GTA02
select CPU_S3C2442
select MFD_PCF50633
select INPUT_PCF50633_PMU
- select MFD_PCF50633_ADC
- select MFD_PCF50633_MBC
- select MFD_PCF50633_PMIC
- select MFD_PCF50633_GPIO
+ select PCF50633_ADC
+ select PCF50633_GPIO
select RTC_DRV_PCF50633
select REGULATOR_PCF50633
+ select CHARGER_PCF50633
select POWER_SUPPLY
select GTA02_HDQ
select MACH_NEO1973
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index ffff16dce95..cdf0bfcebc7 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -232,5 +232,7 @@ config INPUT_LIS302DL
config INPUT_PCF50633_PMU
tristate "PCF50633 PMU events"
depends on MFD_PCF50633
+ help
+ Say Y to include support for input events on NXP PCF50633.
endif
diff --git a/drivers/input/misc/pcf50633-input.c b/drivers/input/misc/pcf50633-input.c
index 43451dfa8f0..6fafd2729cb 100644
--- a/drivers/input/misc/pcf50633-input.c
+++ b/drivers/input/misc/pcf50633-input.c
@@ -1,3 +1,28 @@
+/* Philips PCF50633 Input Driver
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * Author: Balaji Rao <balajirrao@openmoko.org>
+ * All rights reserved.
+ *
+ * Broken down from monstrous PCF50633 driver mainly by
+ * Harald Welte and Andy Green
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
#include <linux/input.h>
#include <linux/mfd/pcf50633/core.h>
@@ -9,7 +34,6 @@ pcf50633_input_irq(struct pcf50633 *pcf, int irq, void *data)
struct input_dev *input_dev = pcf->input.input_dev;
int onkey_released;
-
/* We report only one event depending on if the key status */
onkey_released = pcf50633_reg_read(pcf, PCF50633_REG_OOCSTAT) &
PCF50633_OOCSTAT_ONKEY;
@@ -19,12 +43,6 @@ pcf50633_input_irq(struct pcf50633 *pcf, int irq, void *data)
else if (irq == PCF50633_IRQ_ONKEYR && onkey_released)
input_report_key(input_dev, KEY_POWER, 0);
- /* MBC makes sure that only one of USBINS/USBREM will be called */
- if (irq == PCF50633_IRQ_USBINS)
- input_report_key(input_dev, KEY_POWER2, 1);
- else if (irq == PCF50633_IRQ_USBREM)
- input_report_key(input_dev, KEY_POWER2, 0);
-
input_sync(input_dev);
}
@@ -41,7 +59,6 @@ int __init pcf50633_input_probe(struct platform_device *pdev)
return -ENODEV;
input_dev->name = "GTA02 PMU events";
- input_dev->phys = "FIXME";
input_dev->id.bustype = BUS_I2C;
input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_PWR);
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 84920f60757..6509719237d 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -156,18 +156,26 @@ config MFD_WM8350_I2C
config MFD_PCF50633
tristate "Support for NXP PCF50633"
depends on I2C
+ help
+ Say yes here if you have NXP PCF50633 chip on your board.
+ This core driver provides register access and IRQ handling
+ facilities, and registers devices for the various functions
+ so that function-specific drivers can bind to them.
-config MFD_PCF50633_ADC
- tristate "Support for NXP PCF50633 ADC"
- depends on MFD_PCF50633
-config MFD_PCF50633_MBC
- tristate "Support for NXP PCF50633 MBC"
+config PCF50633_ADC
+ tristate "Support for NXP PCF50633 ADC"
depends on MFD_PCF50633
+ help
+ Say yes here if you want to include support for ADC in the
+ NXP PCF50633 chip.
-config MFD_PCF50633_GPIO
+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.
source "drivers/mfd/glamo/Kconfig"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 30f1091072b..c515325b4b2 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -35,6 +35,5 @@ obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o
obj-$(CONFIG_PMIC_DA903X) += da903x.o
obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o
-obj-$(CONFIG_MFD_PCF50633_ADC) += pcf50633-adc.o
-obj-$(CONFIG_MFD_PCF50633_MBC) += pcf50633-mbc.o
-obj-$(CONFIG_MFD_PCF50633_GPIO) += pcf50633-gpio.o
+obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o
+obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o
diff --git a/drivers/mfd/pcf50633-adc.c b/drivers/mfd/pcf50633-adc.c
index 208c1f87e5d..39bdbae67da 100644
--- a/drivers/mfd/pcf50633-adc.c
+++ b/drivers/mfd/pcf50633-adc.c
@@ -1,3 +1,28 @@
+/* Philips PCF50633 ADC Driver
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * Author: Balaji Rao <balajirrao@openmoko.org>
+ * All rights reserved.
+ *
+ * Broken down from monstrous PCF50633 driver mainly by
+ * Harald Welte and Andy Green
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
#include <linux/mfd/pcf50633/core.h>
#include <linux/mfd/pcf50633/adc.h>
@@ -22,7 +47,7 @@ static void adc_read_setup(struct pcf50633 *pcf,
pcf50633_reg_write(pcf, PCF50633_REG_ADCC2, 0x00);
pcf50633_reg_write(pcf, PCF50633_REG_ADCC3, 0x01);
- /* start ADC conversion of selected channel */
+ /* start ADC conversion on selected channel */
pcf50633_reg_write(pcf, PCF50633_REG_ADCC1, channel | avg |
PCF50633_ADCC1_ADCSTART | PCF50633_ADCC1_RES_10BIT);
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 0d44f37df08..6d66b526bc2 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -1,3 +1,25 @@
+/* Philips PCF50633 Power Management Unit (PMU) driver
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
#include <linux/i2c.h>
#include <linux/irq.h>
#include <linux/device.h>
@@ -506,8 +528,6 @@ static int pcf50633_probe(struct i2c_client *client,
&pcf->mbc.pdev);
pcf50633_client_dev_register(pcf, "pcf50633-adc",
&pcf->adc.pdev);
- pcf50633_client_dev_register(pcf, "pcf50633-gpio",
- &pcf->gpio.pdev);
for (i = 0; i < PCF50633_NUM_REGULATORS; i++) {
struct platform_device *pdev;
diff --git a/drivers/mfd/pcf50633-gpio.c b/drivers/mfd/pcf50633-gpio.c
index f71acbd6dbc..a5b978c4e3c 100644
--- a/drivers/mfd/pcf50633-gpio.c
+++ b/drivers/mfd/pcf50633-gpio.c
@@ -1,62 +1,99 @@
+/* Philips PCF50633 GPIO Driver
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * Author: Balaji Rao <balajirrao@openmoko.org>
+ * All rights reserved.
+ *
+ * Broken down from monstrous PCF50633 driver mainly by
+ * Harald Welte and Andy Green
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
#include <linux/mfd/pcf50633/core.h>
#include <linux/mfd/pcf50633/gpio.h>
+#include <linux/mfd/pcf50633/pmic.h>
-void pcf50633_gpio_set(struct pcf50633 *pcf, int gpio, int on)
+void pcf50633_gpio_set(struct pcf50633 *pcf, int gpio, int val)
{
- u8 reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
+ u8 reg;
+
+ reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
- if (on)
- pcf50633_reg_set_bit_mask(pcf, reg, 0x0f, 0x07);
- else
- pcf50633_reg_set_bit_mask(pcf, reg, 0x0f, 0x00);
+ pcf50633_reg_set_bit_mask(pcf, reg, 0x07, val);
}
EXPORT_SYMBOL_GPL(pcf50633_gpio_set);
int pcf50633_gpio_get(struct pcf50633 *pcf, int gpio)
{
- u8 reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
- u8 val = pcf50633_reg_read(pcf, reg) & 0x0f;
+ u8 reg, val;
- if (val == PCF50633_GPOCFG_GPOSEL_1 ||
- val == (PCF50633_GPOCFG_GPOSEL_0|PCF50633_GPOCFG_GPOSEL_INVERSE))
- return 1;
+ reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
+ val = pcf50633_reg_read(pcf, reg);
- return 0;
+ return val;
}
EXPORT_SYMBOL_GPL(pcf50633_gpio_get);
-int __init pcf50633_gpio_probe(struct platform_device *pdev)
+void pcf50633_gpio_invert_set(struct pcf50633 *pcf, int gpio, int invert)
{
- return 0;
+ u8 val, reg;
+
+ reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
+ val = !!invert << 3;
+
+ pcf50633_reg_set_bit_mask(pcf, reg, val, val);
}
+EXPORT_SYMBOL_GPL(pcf50633_gpio_invert_set);
-static int __devexit pcf50633_gpio_remove(struct platform_device *pdev)
+int pcf50633_gpio_invert_get(struct pcf50633 *pcf, int gpio)
{
- return 0;
-}
+ u8 reg, val;
-struct platform_driver pcf50633_gpio_driver = {
- .driver = {
- .name = "pcf50633-gpio",
- },
- .probe = pcf50633_gpio_probe,
- .remove = __devexit_p(pcf50633_gpio_remove),
-};
+ reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
+ val = pcf50633_reg_read(pcf, reg);
-static int __init pcf50633_gpio_init(void)
-{
- return platform_driver_register(&pcf50633_gpio_driver);
+ return val & (1 << 3);
}
-module_init(pcf50633_gpio_init);
+EXPORT_SYMBOL_GPL(pcf50633_gpio_invert_get);
+
+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,
+};
-static void __exit pcf50633_gpio_exit(void)
+void pcf50633_gpio_power_supply_set(struct pcf50633 *pcf,
+ int gpio, int regulator, int on)
{
- platform_driver_unregister(&pcf50633_gpio_driver);
-}
-module_exit(pcf50633_gpio_exit);
+ u8 reg, val;
-MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
-MODULE_DESCRIPTION("PCF50633 gpio driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:pcf50633-gpio");
+ /* the *ENA register is always one after the *OUT register */
+ reg = pcf50633_regulator_registers[regulator] + 1;
+
+ val = (!!on << (gpio - PCF50633_GPIO1));
+ pcf50633_reg_set_bit_mask(pcf, reg, val, val);
+}
+EXPORT_SYMBOL_GPL(pcf50633_gpio_power_supply_set);
diff --git a/drivers/mfd/pcf50633-mbc.c b/drivers/mfd/pcf50633-mbc.c
deleted file mode 100644
index 8e3eb4f7a57..00000000000
--- a/drivers/mfd/pcf50633-mbc.c
+++ /dev/null
@@ -1,292 +0,0 @@
-#include <linux/mfd/pcf50633/core.h>
-#include <linux/mfd/pcf50633/mbc.h>
-
-
-/*
-#if CONFIG_INPUT_PCF50633_PMU =
-extern static void pcf50633_input_irq(struct pcf50633 *, int, void *);
-
-static void pcf50633_input_report(struct pcf50633 *pcf, int key)
-{
- pcf50633_input_irq(pcf, key, NULL);
-}
-#else
-static void pcf50633_input_report(struct pcf50633 *pcf, int key)
-{
-}
-#endif
-*/
-
-void pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
-{
- int ret;
- u8 bits;
-
- if (ma >= 1000)
- bits = PCF50633_MBCC7_USB_1000mA;
- else if (ma >= 500)
- bits = PCF50633_MBCC7_USB_500mA;
- else if (ma >= 100)
- bits = PCF50633_MBCC7_USB_100mA;
- else
- bits = PCF50633_MBCC7_USB_SUSPEND;
-
- ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC7,
- PCF50633_MBCC7_USB_MASK, bits);
- if (ret)
- dev_err(pcf->dev, "error setting usb curlim to %d mA\n", ma);
- else
- dev_info(pcf->dev, "usb curlim to %d mA\n", ma);
-
- power_supply_changed(&pcf->mbc.usb);
-}
-EXPORT_SYMBOL(pcf50633_mbc_usb_curlim_set);
-
-static const char *chgmode_names[] = {
- [PCF50633_MBCS2_MBC_PLAY] = "play-only",
- [PCF50633_MBCS2_MBC_USB_PRE] = "pre",
- [PCF50633_MBCS2_MBC_ADP_PRE] = "pre",
- [PCF50633_MBCS2_MBC_USB_PRE_WAIT] = "pre-wait",
- [PCF50633_MBCS2_MBC_ADP_PRE_WAIT] = "pre-wait",
- [PCF50633_MBCS2_MBC_USB_FAST] = "fast",
- [PCF50633_MBCS2_MBC_ADP_FAST] = "fast",
- [PCF50633_MBCS2_MBC_USB_FAST_WAIT] = "fast-wait",
- [PCF50633_MBCS2_MBC_ADP_FAST_WAIT] = "fast-wait",
- [PCF50633_MBCS2_MBC_BAT_FULL] = "bat-full",
-};
-
-static ssize_t show_chgmode(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct pcf50633 *pcf = dev_get_drvdata(dev);
-
- u8 mbcs2 = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
- u8 chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK);
-
- return sprintf(buf, "%s %d\n", chgmode_names[chgmod], chgmod);
-}
-static DEVICE_ATTR(chgmode, S_IRUGO | S_IWUSR, show_chgmode, NULL);
-
-static ssize_t show_usblim(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct pcf50633 *pcf = dev_get_drvdata(dev);
- u8 usblim = pcf50633_reg_read(pcf, PCF50633_REG_MBCC7) &
- PCF50633_MBCC7_USB_MASK;
- unsigned int ma;
-
- if (usblim == PCF50633_MBCC7_USB_1000mA)
- ma = 1000;
- else if (usblim == PCF50633_MBCC7_USB_500mA)
- ma = 500;
- else if (usblim == PCF50633_MBCC7_USB_100mA)
- ma = 100;
- else
- ma = 0;
-
- return sprintf(buf, "%u\n", ma);
-}
-static DEVICE_ATTR(usb_curlim, S_IRUGO | S_IWUSR, show_usblim, NULL);
-
-static ssize_t force_usb_limit_dangerous(struct device *dev,
- struct device_attribute *attr, const char *buf, size_t count)
-{
- struct pcf50633 *pcf = dev_get_drvdata(dev);
- unsigned long ma;
-
- strict_strtoul(buf, 10, &ma);
-
- pcf50633_mbc_usb_curlim_set(pcf, ma);
-
- return count;
-}
-
-static DEVICE_ATTR(force_usb_limit_dangerous, 0600,
- NULL, force_usb_limit_dangerous);
-
-static struct attribute *mbc_sysfs_entries[] = {
- &dev_attr_chgmode.attr,
- &dev_attr_usb_curlim.attr,
- &dev_attr_force_usb_limit_dangerous.attr,
- NULL,
-};
-
-static struct attribute_group mbc_attr_group = {
- .name = NULL, /* put in device directory */
- .attrs = mbc_sysfs_entries,
-};
-
-static void pcf50633_mbc_irq_handler(struct pcf50633 *pcf, int irq, void *data)
-{
- struct pcf50633_mbc *mbc;
-
- mbc = &pcf->mbc;
-
- /* USB */
- if (irq == PCF50633_IRQ_USBINS)
- mbc->usb_online = 1;
- else if (irq == PCF50633_IRQ_USBREM) {
- mbc->usb_online = 0;
- mbc->usb_active = 0;
- pcf50633_mbc_usb_curlim_set(pcf, 0);
- }
-
- /* Adapter */
- if (irq == PCF50633_IRQ_ADPINS) {
- pcf->mbc.adapter_online = 1;
- pcf->mbc.adapter_active = 1;
- } else if (irq == PCF50633_IRQ_ADPREM) {
- mbc->adapter_online = 0;
- mbc->adapter_active = 0;
- }
-
- if (irq == PCF50633_IRQ_BATFULL) {
- mbc->usb_active = 0;
- mbc->adapter_active = 0;
- }
-
- power_supply_changed(&mbc->usb);
- power_supply_changed(&mbc->adapter);
-
- if (pcf->pdata->mbc_event_callback)
- pcf->pdata->mbc_event_callback(pcf, irq);
-}
-
-static int adapter_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- int ret = 0;
- struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, usb);
-
- switch (psp) {
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = mbc->adapter_online;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
-static int usb_get_property(struct power_supply *psy,
- enum power_supply_property psp,
- union power_supply_propval *val)
-{
- int ret = 0;
- struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, usb);
-
- switch (psp) {
- case POWER_SUPPLY_PROP_ONLINE:
- val->intval = mbc->usb_online;
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
-static enum power_supply_property power_props[] = {
- POWER_SUPPLY_PROP_ONLINE,
-};
-
-int __init pcf50633_mbc_probe(struct platform_device *pdev)
-{
- struct pcf50633 *pcf;
- struct pcf50633_mbc *mbc;
- int ret;
-
- pcf = platform_get_drvdata(pdev);
- mbc = &pcf->mbc;
-
- /* Set up IRQ handlers */
- pcf->irq_handler[PCF50633_IRQ_ADPINS].handler =
- pcf50633_mbc_irq_handler;
- pcf->irq_handler[PCF50633_IRQ_ADPREM].handler =
- pcf50633_mbc_irq_handler;
- pcf->irq_handler[PCF50633_IRQ_USBINS].handler =
- pcf50633_mbc_irq_handler;
- pcf->irq_handler[PCF50633_IRQ_USBREM].handler =
- pcf50633_mbc_irq_handler;
- pcf->irq_handler[PCF50633_IRQ_BATFULL].handler =
- pcf50633_mbc_irq_handler;
- pcf->irq_handler[PCF50633_IRQ_CHGHALT].handler =
- pcf50633_mbc_irq_handler;
- pcf->irq_handler[PCF50633_IRQ_THLIMON].handler =
- pcf50633_mbc_irq_handler;
- pcf->irq_handler[PCF50633_IRQ_THLIMOFF].handler =
- pcf50633_mbc_irq_handler;
- pcf->irq_handler[PCF50633_IRQ_USBLIMON].handler =
- pcf50633_mbc_irq_handler;
- pcf->irq_handler[PCF50633_IRQ_USBLIMOFF].handler =
- pcf50633_mbc_irq_handler;
- pcf->irq_handler[PCF50633_IRQ_LOWSYS].handler =
- pcf50633_mbc_irq_handler;
- pcf->irq_handler[PCF50633_IRQ_LOWBAT].handler =
- pcf50633_mbc_irq_handler;
-
- /* Create power supplies */
-
- mbc->adapter.name = "adapter";
- mbc->adapter.type = POWER_SUPPLY_TYPE_MAINS;
- mbc->adapter.properties = power_props;
- mbc->adapter.num_properties = ARRAY_SIZE(power_props);
- mbc->adapter.get_property = &adapter_get_property;
- mbc->adapter.supplied_to = pcf->pdata->batteries;
- mbc->adapter.num_supplicants = pcf->pdata->num_batteries;
-
- mbc->usb.name = "usb";
- mbc->usb.type = POWER_SUPPLY_TYPE_USB;
- mbc->usb.properties = power_props;
- mbc->usb.num_properties = ARRAY_SIZE(power_props);
- mbc->usb.get_property = usb_get_property;
- mbc->usb.supplied_to = pcf->pdata->batteries;
- mbc->usb.num_supplicants = pcf->pdata->num_batteries;
-
- ret = power_supply_register(&pdev->dev, &mbc->adapter);
- if (ret)
- dev_err(pcf->dev, "failed to register adapter\n");
-
- ret = power_supply_register(&pdev->dev, &mbc->usb);
- if (ret)
- dev_err(pcf->dev, "failed to register usb\n");
-
- return sysfs_create_group(&pdev->dev.kobj, &mbc_attr_group);
-}
-
-static int __devexit pcf50633_mbc_remove(struct platform_device *pdev)
-{
- struct pcf50633 *pcf;
-
- pcf = platform_get_drvdata(pdev);
-
- return 0;
-}
-
-struct platform_driver pcf50633_mbc_driver = {
- .driver = {
- .name = "pcf50633-mbc",
- },
- .probe = pcf50633_mbc_probe,
- .remove = __devexit_p(pcf50633_mbc_remove),
-};
-
-static int __init pcf50633_mbc_init(void)
-{
- return platform_driver_register(&pcf50633_mbc_driver);
-}
-module_init(pcf50633_mbc_init);
-
-static void __exit pcf50633_mbc_exit(void)
-{
- platform_driver_unregister(&pcf50633_mbc_driver);
-}
-module_exit(pcf50633_mbc_exit);
-
-MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
-MODULE_DESCRIPTION("PCF50633 mbc driver");
-MODULE_LICENSE("GPL");
-MODULE_ALIAS("platform:pcf50633-mbc");
-
diff --git a/drivers/misc/neo1973_pm_host.c b/drivers/misc/neo1973_pm_host.c
index caa302eeb91..bc2a82c3b6d 100644
--- a/drivers/misc/neo1973_pm_host.c
+++ b/drivers/misc/neo1973_pm_host.c
@@ -21,21 +21,29 @@
#ifdef CONFIG_MACH_NEO1973_GTA02
#include <mach/gta02.h>
-#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/gpio.h>
static ssize_t pm_host_read(struct device *dev, struct device_attribute *attr,
char *buf)
{
return sprintf(buf, "%d\n",
- pcf50633_gpio_get(gta02_pcf_pdata.pcf, PCF50633_GPO));
+ pcf50633_gpio_get(gta02_pcf_pdata.pcf, PCF50633_GPO)
+ == PCF50633_GPOCFG_GPOSEL_1);
}
static ssize_t pm_host_write(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
unsigned long on = simple_strtoul(buf, NULL, 10);
+ u8 val;
- pcf50633_gpio_set(gta02_pcf_pdata.pcf, PCF50633_GPO, on);
+ if (on)
+ val = PCF50633_GPOCFG_GPOSEL_1;
+ else
+ val = PCF50633_GPOCFG_GPOSEL_0;
+
+
+ pcf50633_gpio_set(gta02_pcf_pdata.pcf, PCF50633_GPO, val);
return count;
}
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 2bf15b1eb2e..64bbd27c197 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -81,5 +81,11 @@ config GTA02_HDQ
on the Neo Freerunner. You probably want to select
at least BATTERY_BQ27000_HDQ as well
+config CHARGER_PCF50633
+ tristate "Support for NXP PCF50633 MBC"
+ depends on MFD_PCF50633
+ help
+ Say Y to include support for NXP PCF50633 Main Battery Charger.
+
endif # POWER_SUPPLY
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 56f3901d7d8..5cee08b40b5 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -27,3 +27,5 @@ obj-$(CONFIG_BATTERY_PALMTX) += palmtx_battery.o
obj-$(CONFIG_BATTERY_BQ27000_HDQ) += bq27000_battery.o
obj-$(CONFIG_GTA02_HDQ) += gta02_hdq.o
+
+obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 865f2756d9c..547d868db68 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -73,9 +73,10 @@ config REGULATOR_DA903X
Say y here to support the BUCKs and LDOs regulators found on
Dialog Semiconductor DA9030/DA9034 PMIC.
-endif
-
config REGULATOR_PCF50633
bool "PCF50633 regulator driver"
depends on MFD_PCF50633
-
+ help
+ Say Y here to support the voltage regulators and convertors
+ on PCF50633
+endif
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
index ef4165ae560..8dee6e03870 100644
--- a/drivers/regulator/pcf50633-regulator.c
+++ b/drivers/regulator/pcf50633-regulator.c
@@ -1,5 +1,26 @@
-/*
- * Regulator driver for pcf50633
+/* Philips PCF50633 PMIC Driver
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * Author: Balaji Rao <balajirrao@openmoko.org>
+ * All rights reserved.
+ *
+ * Broken down from monstrous PCF50633 driver mainly by
+ * Harald Welte and Andy Green
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
*/
#include <linux/regulator/driver.h>
@@ -17,8 +38,7 @@
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}
-
-static const u_int8_t regulator_registers[PCF50633_NUM_REGULATORS] = {
+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,
@@ -104,7 +124,7 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
millivolts = min_uV / 1000;
- regnr = regulator_registers[regulator_id];
+ regnr = pcf50633_regulator_registers[regulator_id];
switch (regulator_id) {
case PCF50633_REGULATOR_AUTO:
@@ -143,7 +163,7 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
if (regulator_id >= PCF50633_NUM_REGULATORS)
return -EINVAL;
- regnr = regulator_registers[regulator_id];
+ regnr = pcf50633_regulator_registers[regulator_id];
volt_bits = pcf50633_reg_read(pcf, regnr);
switch (regulator_id) {
@@ -182,7 +202,7 @@ static int pcf50633_regulator_enable(struct regulator_dev *rdev)
return -EINVAL;
/* the *ENA register is always one after the *OUT register */
- regnr = regulator_registers[regulator_id] + 1;
+ regnr = pcf50633_regulator_registers[regulator_id] + 1;
pcf50633_reg_set_bit_mask(pcf, regnr, PCF50633_REGULATOR_ON,
PCF50633_REGULATOR_ON);
@@ -200,7 +220,7 @@ static int pcf50633_regulator_disable(struct regulator_dev *rdev)
return -EINVAL;
/* the *ENA register is always one after the *OUT register */
- regnr = regulator_registers[regulator_id] + 1;
+ regnr = pcf50633_regulator_registers[regulator_id] + 1;
pcf50633_reg_set_bit_mask(pcf, regnr, PCF50633_REGULATOR_ON, 0);
@@ -217,7 +237,7 @@ static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev)
return -EINVAL;
/* the *ENA register is always one after the *OUT register */
- regnr = regulator_registers[regulator_id] + 1;
+ regnr = pcf50633_regulator_registers[regulator_id] + 1;
val = pcf50633_reg_read(pcf, regnr) & PCF50633_REGULATOR_ON;
return val;
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index e8a1c7c5420..c7108a4d613 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -223,7 +223,7 @@ config RTC_DRV_PCF50633
tristate "Philips PCF50633"
help
If you say yes here you get support for the Philips PCF50633
- PMU's RTC driver.
+ PMU's RTC.
config RTC_DRV_M41T80
tristate "ST M41T65/M41T80/81/82/83/84/85/87"
diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c
index 6b8ef2f4b8a..bd99be1837a 100644
--- a/drivers/rtc/rtc-pcf50633.c
+++ b/drivers/rtc/rtc-pcf50633.c
@@ -1,3 +1,28 @@
+/* Philips PCF50633 RTC Driver
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * Author: Balaji Rao <balajirrao@openmoko.org>
+ * All rights reserved.
+ *
+ * Broken down from monstrous PCF50633 driver mainly by
+ * Harald Welte and Andy Green
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
#include <linux/rtc.h>
#include <linux/platform_device.h>
#include <linux/bcd.h>
@@ -215,6 +240,9 @@ static void pcf50633_rtc_irq(struct pcf50633 *pcf, int irq, void *unused)
case PCF50633_IRQ_ALARM:
rtc_update_irq(pcf->rtc.rtc_dev, 1, RTC_AF | RTC_IRQF);
break;
+ case PCF50633_IRQ_SECOND:
+ rtc_update_irq(pcf->rtc.rtc_dev, 1, RTC_PF | RTC_IRQF);
+ break;
}
}
diff --git a/include/linux/mfd/pcf50633/adc.h b/include/linux/mfd/pcf50633/adc.h
index 54246e72bcc..27eabb21683 100644
--- a/include/linux/mfd/pcf50633/adc.h
+++ b/include/linux/mfd/pcf50633/adc.h
@@ -1,3 +1,15 @@
+/*
+ * adc.h -- Driver for NXP PCF50633 ADC
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * All rights reserved.
+ *
+ * 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.
+ */
+
#ifndef __LINUX_MFD_PCF50633_ADC_H
#define __LINUX_MFD_PCF50633_ADC_H
@@ -66,27 +78,11 @@ struct pcf50633_adc {
struct mutex queue_mutex;
};
-#ifdef CONFIG_MFD_PCF50633_ADC
extern int
pcf50633_adc_async_read(struct pcf50633 *pcf, int mux, int avg,
void (*callback)(struct pcf50633 *, void *, int),
void *callback_param);
extern int
pcf50633_adc_sync_read(struct pcf50633 *pcf, int mux, int avg);
-#else
-int
-pcf50633_adc_async_read(struct pcf50633 *pcf, int mux, int avg,
- void (*callback)(struct pcf50633 *, void *, int),
- void *callback_param)
-{
- return -ENODEV;
-}
-
-int
-pcf50633_adc_sync_read(struct pcf50633 *pcf, int mux, int avg)
-{
- return -ENODEV;
-}
-#endif /* CONFIG_PCF50633_ADC */
#endif /* __LINUX_PCF50633_ADC_H */
diff --git a/include/linux/mfd/pcf50633/core.h b/include/linux/mfd/pcf50633/core.h
index 6c80e1310a5..8c550895a5a 100644
--- a/include/linux/mfd/pcf50633/core.h
+++ b/include/linux/mfd/pcf50633/core.h
@@ -1,3 +1,15 @@
+/*
+ * core.h -- Core driver for NXP PCF50633
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * All rights reserved.
+ *
+ * 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.
+ */
+
#ifndef __LINUX_MFD_PCF50633_CORE_H
#define __LINUX_MFD_PCF50633_CORE_H
@@ -8,7 +20,6 @@
#include <linux/power_supply.h>
#include <linux/mfd/pcf50633/pmic.h>
-#include <linux/mfd/pcf50633/gpio.h>
#include <linux/mfd/pcf50633/input.h>
#include <linux/mfd/pcf50633/mbc.h>
#include <linux/mfd/pcf50633/rtc.h>
@@ -133,7 +144,6 @@ struct pcf50633 {
int onkey1s_held;
struct pcf50633_pmic pmic;
- struct pcf50633_gpio gpio;
struct pcf50633_input input;
struct pcf50633_mbc mbc;
struct pcf50633_rtc rtc;
diff --git a/include/linux/mfd/pcf50633/gpio.h b/include/linux/mfd/pcf50633/gpio.h
index f5038012bae..da74df6d849 100644
--- a/include/linux/mfd/pcf50633/gpio.h
+++ b/include/linux/mfd/pcf50633/gpio.h
@@ -1,12 +1,18 @@
+/*
+ * gpio.h -- GPIO driver for NXP PCF50633
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * All rights reserved.
+ *
+ * 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.
+ */
+
#ifndef __LINUX_MFD_PCF50633_GPIO_H
#define __LINUX_MFD_PCF50633_GPIO_H
-#include <linux/platform_device.h>
-
-struct pcf50633_gpio {
- struct platform_device *pdev;
-};
-
#define PCF50633_GPIO1 1
#define PCF50633_GPIO2 2
#define PCF50633_GPIO3 3
@@ -32,12 +38,14 @@ enum pcf50633_reg_gpocfg {
struct pcf50633;
-extern void
-pcf50633_gpio_set(struct pcf50633 *pcf, int gpio, int on);
+extern void pcf50633_gpio_set(struct pcf50633 *pcf, int gpio, int on);
+extern int pcf50633_gpio_get(struct pcf50633 *pcf, int gpio);
-extern int
-pcf50633_gpio_get(struct pcf50633 *pcf, int gpio);
+extern void pcf50633_gpio_invert_set(struct pcf50633 *, int gpio, int invert);
+extern int pcf50633_gpio_invert_get(struct pcf50633 *pcf, int gpio);
+extern void pcf50633_gpio_power_supply_set(struct pcf50633 *,
+ int gpio, int regulator, int on);
+#endif /* __LINUX_MFD_PCF50633_GPIO_H */
-#endif
diff --git a/include/linux/mfd/pcf50633/input.h b/include/linux/mfd/pcf50633/input.h
index 5f8d78ffea0..fd1030269e2 100644
--- a/include/linux/mfd/pcf50633/input.h
+++ b/include/linux/mfd/pcf50633/input.h
@@ -1,3 +1,15 @@
+/*
+ * input.h -- Input driver for NXP PCF50633
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * All rights reserved.
+ *
+ * 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.
+ */
+
#ifndef __LINUX_MFD_PCF50633_INPUT_H
#define __LINUX_MFD_PCF50633_INPUT_H
diff --git a/include/linux/mfd/pcf50633/led.h b/include/linux/mfd/pcf50633/led.h
index 2f866b208f8..c84a97e0a58 100644
--- a/include/linux/mfd/pcf50633/led.h
+++ b/include/linux/mfd/pcf50633/led.h
@@ -1,3 +1,15 @@
+/*
+ * led.h -- LED driver for NXP PCF50633
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * All rights reserved.
+ *
+ * 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.
+ */
+
#ifndef __LINUX_MFD_PCF50633_LED_H
#define __LINUX_MFD_PCF50633_LED_H
diff --git a/include/linux/mfd/pcf50633/mbc.h b/include/linux/mfd/pcf50633/mbc.h
index d0549c53ddd..a59bd382db4 100644
--- a/include/linux/mfd/pcf50633/mbc.h
+++ b/include/linux/mfd/pcf50633/mbc.h
@@ -1,3 +1,15 @@
+/*
+ * mbc.h -- Driver for NXP PCF50633 Main Battery Charger
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * All rights reserved.
+ *
+ * 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.
+ */
+
#ifndef __LINUX_MFD_PCF50633_MBC_H
#define __LINUX_MFD_PCF50633_MBC_H
@@ -106,6 +118,8 @@ enum pcf50633_reg_mbcs3 {
#define PCF50633_MBCC2_VBATCOND_MASK 0x03
#define PCF50633_MBCC2_VMAX_MASK 0x3c
+struct pcf50633;
+
void pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma);
struct pcf50633_mbc {
diff --git a/include/linux/mfd/pcf50633/rtc.h b/include/linux/mfd/pcf50633/rtc.h
index 0919590dbb9..ce8ad8f5928 100644
--- a/include/linux/mfd/pcf50633/rtc.h
+++ b/include/linux/mfd/pcf50633/rtc.h
@@ -1,3 +1,15 @@
+/*
+ * rtc.h -- RTC driver for NXP PCF50633
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * All rights reserved.
+ *
+ * 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.
+ */
+
#ifndef __LINUX_MFD_PCF50633_RTC_H
#define __LINUX_MFD_PCF50633_RTC_H
@@ -19,8 +31,6 @@
#define PCF50633_REG_RTCMTA 0x65 /* Alarm Month */
#define PCF50633_REG_RTCYRA 0x66 /* Alarm Year */
-#define PCF50633_F_RTC_SECOND (1 << PCF50633_FIDX_RTC_SECOND)
-
struct pcf50633_rtc {
int alarm_enabled;
int second_enabled;