diff options
author | Lars-Peter Clausen <lars@metafoo.de> | 2009-10-23 22:09:53 +0200 |
---|---|---|
committer | Lars-Peter Clausen <lars@metafoo.de> | 2009-10-23 22:09:53 +0200 |
commit | 8123f88b8de62ce957c0a1e8a68060ceee685a36 (patch) | |
tree | 9ef2f3b3784761999aa27a2494eda8c6cdeee561 | |
parent | ee6baee93c67d4022c756642725e9985fbfd8332 (diff) | |
parent | 4eeac57dd1e056aedbe9d98756d9e5cd211c311b (diff) |
Merge branch 'pcf50606-2.6.31' into om-gta01-2.6.31
-rw-r--r-- | drivers/mfd/Kconfig | 7 | ||||
-rw-r--r-- | drivers/mfd/Makefile | 1 | ||||
-rw-r--r-- | drivers/mfd/pcf50606-adc.c | 28 | ||||
-rw-r--r-- | drivers/mfd/pcf50606-core.c | 81 | ||||
-rw-r--r-- | drivers/mfd/pcf50606-gpo.c | 119 | ||||
-rw-r--r-- | drivers/power/pcf50606-charger.c | 56 | ||||
-rw-r--r-- | drivers/regulator/pcf50606-regulator.c | 126 | ||||
-rw-r--r-- | drivers/rtc/rtc-pcf50606.c | 10 | ||||
-rw-r--r-- | include/linux/mfd/pcf50606/gpo.h | 42 | ||||
-rw-r--r-- | include/linux/mfd/pcf50606/mbc.h | 2 |
10 files changed, 139 insertions, 333 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 4e952cc7a8f..aa167dde4b7 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -279,13 +279,6 @@ config PCF50606_ADC Say yes here if you want to include support for ADC in the NXP PCF50606 chip. -config PCF50606_GPO - tristate "Support for NXP PCF50606 GPO" - depends on MFD_PCF50606 - help - Say yes here if you want to include support GPO for pins on - the PCF50606 chip. - endmenu menu "Multimedia Capabilities Port drivers" diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index ba41b36f2c5..b02f8362ee7 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -47,5 +47,4 @@ obj-$(CONFIG_AB3100_CORE) += ab3100-core.o obj-$(CONFIG_MFD_PCF50606) += pcf50606-core.o obj-$(CONFIG_PCF50606_ADC) += pcf50606-adc.o -obj-$(CONFIG_PCF50606_GPO) += pcf50606-gpo.o diff --git a/drivers/mfd/pcf50606-adc.c b/drivers/mfd/pcf50606-adc.c index 47210a9cce8..f6ffd0b146d 100644 --- a/drivers/mfd/pcf50606-adc.c +++ b/drivers/mfd/pcf50606-adc.c @@ -37,6 +37,7 @@ struct pcf50606_adc_request { }; +/* code expects this to be a power of two */ #define PCF50606_MAX_ADC_FIFO_DEPTH 8 struct pcf50606_adc { @@ -44,12 +45,12 @@ struct pcf50606_adc { /* Private stuff */ struct pcf50606_adc_request *queue[PCF50606_MAX_ADC_FIFO_DEPTH]; - int queue_head; - int queue_tail; + unsigned int queue_head; + unsigned int queue_tail; struct mutex queue_mutex; }; -static inline struct pcf50606_adc *__to_adc(struct pcf50606 *pcf) +static inline struct pcf50606_adc *pcf50606_to_adc(struct pcf50606 *pcf) { return platform_get_drvdata(pcf->adc_pdev); } @@ -66,13 +67,12 @@ static void adc_setup(struct pcf50606 *pcf, int channel) static void trigger_next_adc_job_if_any(struct pcf50606 *pcf) { - struct pcf50606_adc *adc = __to_adc(pcf); - int head, tail; + struct pcf50606_adc *adc = pcf50606_to_adc(pcf); + unsigned int head; mutex_lock(&adc->queue_mutex); head = adc->queue_head; - tail = adc->queue_tail; if (!adc->queue[head]) goto out; @@ -85,11 +85,10 @@ out: static int adc_enqueue_request(struct pcf50606 *pcf, struct pcf50606_adc_request *req) { - struct pcf50606_adc *adc = __to_adc(pcf); - int head, tail; + struct pcf50606_adc *adc = pcf50606_to_adc(pcf); + unsigned int tail; mutex_lock(&adc->queue_mutex); - head = adc->queue_head; tail = adc->queue_tail; if (adc->queue[tail]) { @@ -172,7 +171,7 @@ EXPORT_SYMBOL_GPL(pcf50606_adc_async_read); static int adc_result(struct pcf50606 *pcf) { - u16 ret = (pcf50606_reg_read(pcf, PCF50606_REG_ADCS1) << 2) | + int ret = (pcf50606_reg_read(pcf, PCF50606_REG_ADCS1) << 2) | (pcf50606_reg_read(pcf, PCF50606_REG_ADCS2) & 0x03); dev_dbg(pcf->dev, "adc result = %d\n", ret); @@ -185,7 +184,7 @@ static void pcf50606_adc_irq(int irq, void *data) struct pcf50606_adc *adc = data; struct pcf50606 *pcf = adc->pcf; struct pcf50606_adc_request *req; - int head; + unsigned int head; mutex_lock(&adc->queue_mutex); head = adc->queue_head; @@ -198,8 +197,7 @@ static void pcf50606_adc_irq(int irq, void *data) } adc->queue[head] = NULL; - adc->queue_head = (head + 1) & - (PCF50606_MAX_ADC_FIFO_DEPTH - 1); + adc->queue_head = (head + 1) & (PCF50606_MAX_ADC_FIFO_DEPTH - 1); mutex_unlock(&adc->queue_mutex); @@ -231,7 +229,8 @@ static int __devinit pcf50606_adc_probe(struct platform_device *pdev) static int __devexit pcf50606_adc_remove(struct platform_device *pdev) { struct pcf50606_adc *adc = platform_get_drvdata(pdev); - int i, head; + unsigned int i; + unsigned int head; pcf50606_free_irq(adc->pcf, PCF50606_IRQ_ADCRDY); @@ -254,6 +253,7 @@ static int __devexit pcf50606_adc_remove(struct platform_device *pdev) struct platform_driver pcf50606_adc_driver = { .driver = { .name = "pcf50606-adc", + .owner = THIS_MODULE, }, .probe = pcf50606_adc_probe, .remove = __devexit_p(pcf50606_adc_remove), diff --git a/drivers/mfd/pcf50606-core.c b/drivers/mfd/pcf50606-core.c index 741a432586a..d610ff9346e 100644 --- a/drivers/mfd/pcf50606-core.c +++ b/drivers/mfd/pcf50606-core.c @@ -27,7 +27,7 @@ #include <linux/mfd/pcf50606/core.h> -static int __pcf50606_read(struct pcf50606 *pcf, u8 reg, int num, u8 *data) +static int __pcf50606_read(struct pcf50606 *pcf, uint8_t reg, int num, uint8_t *data) { int ret; @@ -39,7 +39,7 @@ static int __pcf50606_read(struct pcf50606 *pcf, u8 reg, int num, u8 *data) return ret; } -static int __pcf50606_write(struct pcf50606 *pcf, u8 reg, int num, u8 *data) +static int __pcf50606_write(struct pcf50606 *pcf, uint8_t reg, int num, uint8_t *data) { int ret; @@ -53,8 +53,8 @@ static int __pcf50606_write(struct pcf50606 *pcf, u8 reg, int num, u8 *data) } /* Read a block of upto 32 regs */ -int pcf50606_read_block(struct pcf50606 *pcf, u8 reg, - int nr_regs, u8 *data) +int pcf50606_read_block(struct pcf50606 *pcf, uint8_t reg, + int nr_regs, uint8_t *data) { int ret; @@ -67,8 +67,8 @@ int pcf50606_read_block(struct pcf50606 *pcf, u8 reg, EXPORT_SYMBOL_GPL(pcf50606_read_block); /* Write a block of upto 32 regs */ -int pcf50606_write_block(struct pcf50606 *pcf , u8 reg, - int nr_regs, u8 *data) +int pcf50606_write_block(struct pcf50606 *pcf , uint8_t reg, + int nr_regs, uint8_t *data) { int ret; @@ -80,9 +80,9 @@ int pcf50606_write_block(struct pcf50606 *pcf , u8 reg, } EXPORT_SYMBOL_GPL(pcf50606_write_block); -u8 pcf50606_reg_read(struct pcf50606 *pcf, u8 reg) +uint8_t pcf50606_reg_read(struct pcf50606 *pcf, uint8_t reg) { - u8 val; + uint8_t val; mutex_lock(&pcf->lock); __pcf50606_read(pcf, reg, 1, &val); @@ -92,7 +92,7 @@ u8 pcf50606_reg_read(struct pcf50606 *pcf, u8 reg) } EXPORT_SYMBOL_GPL(pcf50606_reg_read); -int pcf50606_reg_write(struct pcf50606 *pcf, u8 reg, u8 val) +int pcf50606_reg_write(struct pcf50606 *pcf, uint8_t reg, uint8_t val) { int ret; @@ -104,10 +104,10 @@ int pcf50606_reg_write(struct pcf50606 *pcf, u8 reg, u8 val) } EXPORT_SYMBOL_GPL(pcf50606_reg_write); -int pcf50606_reg_set_bit_mask(struct pcf50606 *pcf, u8 reg, u8 mask, u8 val) +int pcf50606_reg_set_bit_mask(struct pcf50606 *pcf, uint8_t reg, uint8_t mask, uint8_t val) { int ret; - u8 tmp; + uint8_t tmp; val &= mask; @@ -127,10 +127,10 @@ out: } EXPORT_SYMBOL_GPL(pcf50606_reg_set_bit_mask); -int pcf50606_reg_clear_bits(struct pcf50606 *pcf, u8 reg, u8 val) +int pcf50606_reg_clear_bits(struct pcf50606 *pcf, uint8_t reg, uint8_t val) { int ret; - u8 tmp; + uint8_t tmp; mutex_lock(&pcf->lock); ret = __pcf50606_read(pcf, reg, 1, &tmp); @@ -149,13 +149,13 @@ EXPORT_SYMBOL_GPL(pcf50606_reg_clear_bits); /* sysfs attributes */ static ssize_t show_dump_regs(struct device *dev, struct device_attribute *attr, - char *buf) + char *buf) { struct pcf50606 *pcf = dev_get_drvdata(dev); - u8 dump[16]; + uint8_t dump[16]; int n, n1, idx = 0; char *buf1 = buf; - static u8 address_no_read[] = { /* must be ascending */ + static uint8_t address_no_read[] = { /* must be ascending */ PCF50606_REG_INT1, PCF50606_REG_INT2, PCF50606_REG_INT3, @@ -237,9 +237,9 @@ int pcf50606_free_irq(struct pcf50606 *pcf, int irq) } EXPORT_SYMBOL_GPL(pcf50606_free_irq); -static int __pcf50606_irq_mask_set(struct pcf50606 *pcf, int irq, u8 mask) +static int __pcf50606_irq_mask_set(struct pcf50606 *pcf, int irq, uint8_t mask) { - u8 reg, bits, tmp; + uint8_t reg, bits, tmp; int ret = 0, idx; idx = irq >> 3; @@ -298,7 +298,7 @@ EXPORT_SYMBOL_GPL(pcf50606_irq_unmask); int pcf50606_irq_mask_get(struct pcf50606 *pcf, int irq) { - u8 reg, bits; + uint8_t reg, bits; reg = (irq / 8); bits = (1 << (irq % 8)); @@ -320,9 +320,10 @@ static void pcf50606_irq_call_handler(struct pcf50606 *pcf, static void pcf50606_irq_worker(struct work_struct *work) { + int ret; struct pcf50606 *pcf; - int ret, i, j; - u8 pcf_int[3], chgstat; + uint8_t pcf_int[3], charger_status; + size_t i, j; pcf = container_of(work, struct pcf50606, irq_work); @@ -331,7 +332,7 @@ static void pcf50606_irq_worker(struct work_struct *work) ARRAY_SIZE(pcf_int), pcf_int); if (ret != ARRAY_SIZE(pcf_int)) { dev_err(pcf->dev, "Error reading INT registers\n"); - + /* * If this doesn't ACK the interrupt to the chip, we'll be * called once again as we're level triggered. @@ -340,15 +341,15 @@ static void pcf50606_irq_worker(struct work_struct *work) } /* We immediately read the charger status. We thus make sure - * only of CHGINS/CHGRM interrupt handlers are called */ + * only one of CHGINS/CHGRM interrupt handlers are called */ if (pcf_int[1] & (PCF50606_INT2_CHGINS | PCF50606_INT2_CHGRM)) { - chgstat = pcf50606_reg_read(pcf, PCF50606_REG_MBCS1); - if (chgstat & (0x1 << 4)) - pcf_int[1] &= ~(1 << PCF50606_INT2_CHGRM); + charger_status = pcf50606_reg_read(pcf, PCF50606_REG_MBCS1); + if (charger_status & (0x1 << 4)) + pcf_int[1] &= ~PCF50606_INT2_CHGRM; else - pcf_int[1] &= ~(1 << PCF50606_INT2_CHGINS); + pcf_int[1] &= ~PCF50606_INT2_CHGINS; } - + dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x\n", pcf_int[0], pcf_int[1], pcf_int[2]); @@ -457,9 +458,10 @@ pcf50606_client_dev_register(struct pcf50606 *pcf, const char *name, #ifdef CONFIG_PM static int pcf50606_suspend(struct i2c_client *client, pm_message_t state) { + int ret; struct pcf50606 *pcf; - int ret, i; - u8 res[3]; + size_t i; + uint8_t res[3]; pcf = i2c_get_clientdata(client); @@ -478,7 +480,7 @@ static int pcf50606_suspend(struct i2c_client *client, pm_message_t state) dev_err(pcf->dev, "error saving irq masks\n"); goto out; } - + /* Write wakeup irq masks */ for (i = 0; i < ARRAY_SIZE(res); i++) res[i] = ~pcf->pdata->resumers[i]; @@ -528,10 +530,11 @@ static int pcf50606_resume(struct i2c_client *client) static int pcf50606_probe(struct i2c_client *client, const struct i2c_device_id *ids) { + int ret; struct pcf50606 *pcf; struct pcf50606_platform_data *pdata = client->dev.platform_data; - int i, ret; - int version, variant; + int i; + uint8_t version, variant; if (!client->irq) { dev_err(&client->dev, "Missing IRQ\n"); @@ -555,6 +558,8 @@ static int pcf50606_probe(struct i2c_client *client, version = pcf50606_reg_read(pcf, 0); variant = pcf50606_reg_read(pcf, 1); + + /* This test is always false, FIX it */ if (version < 0 || variant < 0) { dev_err(pcf->dev, "Unable to probe pcf50606\n"); ret = -ENODEV; @@ -595,7 +600,7 @@ static int pcf50606_probe(struct i2c_client *client, dev_err(pcf->dev, "Cannot create regulator %d\n", i); continue; } - + pdev->dev.parent = pcf->dev; platform_device_add_data(pdev, &pdata->reg_init_data[i], sizeof(pdata->reg_init_data[i])); @@ -626,7 +631,7 @@ err: static int pcf50606_remove(struct i2c_client *client) { struct pcf50606 *pcf = i2c_get_clientdata(client); - int i; + unsigned int i; free_irq(pcf->irq, pcf); @@ -638,6 +643,7 @@ static int pcf50606_remove(struct i2c_client *client) for (i = 0; i < PCF50606_NUM_REGULATORS; i++) platform_device_unregister(pcf->regulator_pdev[i]); + i2c_set_clientdata(client, NULL); kfree(pcf); return 0; @@ -662,15 +668,14 @@ static int __init pcf50606_init(void) { return i2c_add_driver(&pcf50606_driver); } +module_init(pcf50606_init); static void pcf50606_exit(void) { i2c_del_driver(&pcf50606_driver); } +module_exit(pcf50606_exit); MODULE_DESCRIPTION("I2C chip driver for NXP PCF50606 PMU"); MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>"); MODULE_LICENSE("GPL"); - -module_init(pcf50606_init); -module_exit(pcf50606_exit); diff --git a/drivers/mfd/pcf50606-gpo.c b/drivers/mfd/pcf50606-gpo.c deleted file mode 100644 index 3510f8b48e9..00000000000 --- a/drivers/mfd/pcf50606-gpo.c +++ /dev/null @@ -1,119 +0,0 @@ -/* Philips PCF50606 GPO Driver - * - * (C) 2006-2008 by Openmoko, Inc. - * Author: Balaji Rao <balajirrao@openmoko.org> - * All rights reserved. - * - * Broken down from monstrous PCF50606 driver mainly by - * Harald Welte, Andy Green Werner Almesberger and Matt Hsu - * - * 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/mfd/pcf50606/core.h> -#include <linux/mfd/pcf50606/gpo.h> - -void pcf50606_gpo_set_active(struct pcf50606 *pcf, int gpo, int val) -{ - u8 reg, value, mask; - - reg = gpo; - value = val; - mask = 0x07; - - if (gpo == PCF50606_GPO2) { - value = val << 4; - mask = 0x07 << 4; - } - pcf50606_reg_set_bit_mask(pcf, reg, mask, value); -} -EXPORT_SYMBOL_GPL(pcf50606_gpo_set_active); - -int pcf50606_gpo_get_active(struct pcf50606 *pcf, int gpo) -{ - u8 reg, value, shift = 0; - - reg = gpo; - if (gpo == PCF50606_GPO2) - shift = 4; - - value = pcf50606_reg_read(pcf, reg); - - return (value >> shift) & 0x07; -} -EXPORT_SYMBOL_GPL(pcf50606_gpo_get_active); - -void pcf50606_gpo_set_standby(struct pcf50606 *pcf, int gpo, int val) -{ - u8 reg; - - if (gpo == PCF50606_GPO1 || gpo == PCF50606_GPO2) { - dev_err(pcf->dev, "Can't set standby settings for GPO[12]n"); - return; - } - - reg = gpo; - - pcf50606_reg_set_bit_mask(pcf, gpo, 0x07 << 3, val); -} -EXPORT_SYMBOL_GPL(pcf50606_gpo_set_standby); - -int pcf50606_gpo_get_standby(struct pcf50606 *pcf, int gpo) -{ - u8 reg, value; - - if (gpo == PCF50606_GPO1 || gpo == PCF50606_GPO2) { - dev_err(pcf->dev, "Can't get standby settings for GPO[12]n"); - return -EINVAL; - } - - reg = gpo; - value = pcf50606_reg_read(pcf, reg); - - return (value >> 3) & 0x07; -} -EXPORT_SYMBOL_GPL(pcf50606_gpo_get_standby); - -void pcf50606_gpo_invert_set(struct pcf50606 *pcf, int gpo, int invert) -{ - u8 reg, value, mask; - - reg = gpo; - value = !!invert << 6; - mask = 0x01 << 6; - - if (gpo == PCF50606_GPO1) { - mask = 0x01 << 4; - value = !!invert << 4; - } - else if (gpo == PCF50606_GPO2) { - mask = 0x01 << 7; - value = !!invert << 7; - } - - pcf50606_reg_set_bit_mask(pcf, reg, mask, value); -} -EXPORT_SYMBOL_GPL(pcf50606_gpo_invert_set); - -int pcf50606_gpo_invert_get(struct pcf50606 *pcf, int gpo) -{ - u8 reg, value, shift; - - reg = gpo; - shift = 6; - - if (gpo == PCF50606_GPO1) - shift = 4; - else if (gpo == PCF50606_GPO2) - shift = 7; - - value = pcf50606_reg_read(pcf, reg); - - return (value >> shift) & 0x01; -} -EXPORT_SYMBOL_GPL(pcf50606_gpo_invert_get); diff --git a/drivers/power/pcf50606-charger.c b/drivers/power/pcf50606-charger.c index f90c5ed25b3..a35b671061b 100644 --- a/drivers/power/pcf50606-charger.c +++ b/drivers/power/pcf50606-charger.c @@ -33,7 +33,7 @@ struct pcf50606_mbc { struct power_supply charger; }; -void pcf50606_charge_fast(struct pcf50606 *pcf, int on) +int pcf50606_charge_fast(struct pcf50606 *pcf, int on) { struct pcf50606_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev); @@ -43,7 +43,7 @@ void pcf50606_charge_fast(struct pcf50606 *pcf, int on) * ready. */ if (!mbc) - return; + return -ENODEV; if (on) { pcf50606_reg_set_bit_mask(pcf, PCF50606_REG_MBCC1, @@ -60,25 +60,27 @@ void pcf50606_charge_fast(struct pcf50606 *pcf, int on) PCF50606_MBCC1_CHGMOD_IDLE); mbc->charger_online = 0; } + + return 0; } EXPORT_SYMBOL_GPL(pcf50606_charge_fast); static ssize_t -show_chgmode(struct device *dev, struct device_attribute *attr, char *buf) +show_charge_mode(struct device *dev, struct device_attribute *attr, char *buf) { struct pcf50606_mbc *mbc = dev_get_drvdata(dev); - u8 mbcc1 = pcf50606_reg_read(mbc->pcf, PCF50606_REG_MBCC1); - u8 chgmod = (mbcc1 & PCF50606_MBCC1_CHGMOD_MASK); + uint8_t charge_mode = pcf50606_reg_read(mbc->pcf, PCF50606_REG_MBCC1); + charge_mode &= PCF50606_MBCC1_CHGMOD_MASK; - return sprintf(buf, "%d\n", chgmod); + return sprintf(buf, "%d\n", charge_mode); } -static ssize_t set_chgmode(struct device *dev, struct device_attribute *attr, +static ssize_t set_charge_mode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct pcf50606_mbc *mbc = dev_get_drvdata(dev); - u_int8_t mbcc1 = pcf50606_reg_read(mbc->pcf, PCF50606_REG_MBCC1); + uint8_t mbcc1 = pcf50606_reg_read(mbc->pcf, PCF50606_REG_MBCC1); mbcc1 &= ~PCF50606_MBCC1_CHGMOD_MASK; @@ -101,18 +103,7 @@ static ssize_t set_chgmode(struct device *dev, struct device_attribute *attr, return count; } -static DEVICE_ATTR(chgmode, S_IRUGO, show_chgmode, set_chgmode); - - -static struct attribute *pcf50606_mbc_sysfs_entries[] = { - &dev_attr_chgmode.attr, - NULL, -}; - -static struct attribute_group mbc_attr_group = { - .name = NULL, /* put in device directory */ - .attrs = pcf50606_mbc_sysfs_entries, -}; +static DEVICE_ATTR(charge_mode, S_IRUGO, show_charge_mode, set_charge_mode); static void pcf50606_mbc_irq_handler(int irq, void *data) @@ -147,7 +138,7 @@ static enum power_supply_property power_props[] = { POWER_SUPPLY_PROP_ONLINE, }; -static const u8 mbc_irq_handlers[] = { +static const uint8_t mbc_irq_handlers[] = { PCF50606_IRQ_CHGINS, PCF50606_IRQ_CHGRM, PCF50606_IRQ_CHGFOK, @@ -160,21 +151,15 @@ static int __devinit pcf50606_mbc_probe(struct platform_device *pdev) { struct pcf50606_mbc *mbc; int ret; - int i; - u8 oocs; + size_t i; + uint8_t oocs; mbc = kzalloc(sizeof(*mbc), GFP_KERNEL); if (!mbc) return -ENOMEM; - platform_set_drvdata(pdev, mbc); mbc->pcf = dev_to_pcf50606(pdev->dev.parent); - /* Set up IRQ handlers */ - for (i = 0; i < ARRAY_SIZE(mbc_irq_handlers); i++) - pcf50606_register_irq(mbc->pcf, mbc_irq_handlers[i], - pcf50606_mbc_irq_handler, mbc); - mbc->charger.name = "charger"; mbc->charger.type = POWER_SUPPLY_TYPE_MAINS; mbc->charger.properties = power_props; @@ -190,7 +175,12 @@ static int __devinit pcf50606_mbc_probe(struct platform_device *pdev) return ret; } - ret = sysfs_create_group(&pdev->dev.kobj, &mbc_attr_group); + /* Set up IRQ handlers */ + for (i = 0; i < ARRAY_SIZE(mbc_irq_handlers); i++) + pcf50606_register_irq(mbc->pcf, mbc_irq_handlers[i], + pcf50606_mbc_irq_handler, mbc); + + ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_charge_mode.attr); if (ret) dev_err(mbc->pcf->dev, "failed to create sysfs entries\n"); @@ -198,13 +188,15 @@ static int __devinit pcf50606_mbc_probe(struct platform_device *pdev) if (oocs & PCF50606_OOCS_CHGOK) pcf50606_mbc_irq_handler(PCF50606_IRQ_CHGINS, mbc); + platform_set_drvdata(pdev, mbc); + return 0; } static int __devexit pcf50606_mbc_remove(struct platform_device *pdev) { struct pcf50606_mbc *mbc = platform_get_drvdata(pdev); - int i; + size_t i; /* Remove IRQ handlers */ for (i = 0; i < ARRAY_SIZE(mbc_irq_handlers); i++) @@ -212,6 +204,7 @@ static int __devexit pcf50606_mbc_remove(struct platform_device *pdev) power_supply_unregister(&mbc->charger); + platform_set_drvdata(pdev, NULL); kfree(mbc); return 0; @@ -220,6 +213,7 @@ static int __devexit pcf50606_mbc_remove(struct platform_device *pdev) static struct platform_driver pcf50606_mbc_driver = { .driver = { .name = "pcf50606-mbc", + .owner = THIS_MODULE, }, .probe = pcf50606_mbc_probe, .remove = __devexit_p(pcf50606_mbc_remove), diff --git a/drivers/regulator/pcf50606-regulator.c b/drivers/regulator/pcf50606-regulator.c index 667614c06f4..ae3193f3104 100644 --- a/drivers/regulator/pcf50606-regulator.c +++ b/drivers/regulator/pcf50606-regulator.c @@ -33,7 +33,7 @@ .owner = THIS_MODULE, \ } -static const u8 pcf50606_regulator_registers[PCF50606_NUM_REGULATORS] = { +static const uint8_t pcf50606_regulator_registers[PCF50606_NUM_REGULATORS] = { [PCF50606_REGULATOR_DCD] = PCF50606_REG_DCDC1, [PCF50606_REGULATOR_DCDE] = PCF50606_REG_DCDEC1, [PCF50606_REGULATOR_DCUD] = PCF50606_REG_DCUDC1, @@ -44,25 +44,21 @@ static const u8 pcf50606_regulator_registers[PCF50606_NUM_REGULATORS] = { [PCF50606_REGULATOR_IOREG] = PCF50606_REG_IOREGC, }; -static u8 dcudc_voltage(unsigned int millivolts) +static uint8_t dcudc_voltage(unsigned int millivolts) { - if (millivolts < 900) + if (millivolts <= 900) return 0; - if (millivolts > 5500) - return 0x1f; - if (millivolts <= 3300) { - millivolts -= 900; - return millivolts/300; - } - if (millivolts < 4000) + else if (millivolts <= 3300) + return (millivolts - 900) / 300; + else if (millivolts < 4000) return 0x0f; - else { - millivolts -= 4000; - return millivolts/100; - } + else if (millivolts <= 5500) + return (millivolts - 4000) / 100; + + return 0x1f; } -static unsigned int dcudc_2voltage(u8 bits) +static unsigned int dcudc_2voltage(uint8_t bits) { bits &= 0x1f; if (bits < 0x08) @@ -70,43 +66,39 @@ static unsigned int dcudc_2voltage(u8 bits) else if (bits < 0x10) return 3300; else - return 4000 + bits * 100; + return 4000 + (bits & 0xf) * 100; } -static u8 dcdec_voltage(unsigned int millivolts) +static uint8_t dcdec_voltage(unsigned int millivolts) { if (millivolts < 900) return 0; else if (millivolts > 3300) return 0x0f; - millivolts -= 900; - return millivolts/300; + return (millivolts - 900) / 300; } -static unsigned int dcdec_2voltage(u8 bits) +static unsigned int dcdec_2voltage(uint8_t bits) { bits &= 0x0f; - return 900 + bits*300; + return 900 + bits * 300; } -static u8 dcdc_voltage(unsigned int millivolts) +static uint8_t dcdc_voltage(unsigned int millivolts) { if (millivolts < 900) return 0; else if (millivolts > 3600) return 0x1f; - if (millivolts < 1500) { - millivolts -= 900; - return millivolts/25; - } else { - millivolts -= 1500; - return 0x18 + millivolts/300; - } + if (millivolts < 1500) + return (millivolts - 900) / 25; + else + return 0x18 + (millivolts - 1500) / 300; } -static unsigned int dcdc_2voltage(u8 bits) +static unsigned int dcdc_2voltage(uint8_t bits) { bits &= 0x1f; if ((bits & 0x18) == 0x18) @@ -115,18 +107,17 @@ static unsigned int dcdc_2voltage(u8 bits) return 900 + (bits * 25); } -static u8 dx_voltage(unsigned int millivolts) +static uint8_t dx_voltage(unsigned int millivolts) { if (millivolts < 900) return 0; else if (millivolts > 3300) return 0x18; - millivolts -= 900; - return millivolts/100; + return (millivolts - 900) / 100; } -static unsigned int dx_2voltage(u8 bits) +static unsigned int dx_2voltage(uint8_t bits) { bits &= 0x1f; return 900 + (bits * 100); @@ -136,85 +127,75 @@ static int pcf50606_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV) { struct pcf50606 *pcf; - int regulator_id, millivolts, rc; - u8 volt_bits, regnr; + int regulator_id, millivolts; + uint8_t volt_bits, regnr; pcf = rdev_get_drvdata(rdev); regulator_id = rdev_get_id(rdev); - if (regulator_id >= PCF50606_NUM_REGULATORS) - return -EINVAL; millivolts = min_uV / 1000; switch (regulator_id) { case PCF50606_REGULATOR_DCD: volt_bits = dcdc_voltage(millivolts); - rc = pcf50606_reg_set_bit_mask(pcf, PCF50606_REG_DCDC1, 0x1f, - volt_bits); + regnr = PCF50606_REG_DCDC1; break; case PCF50606_REGULATOR_DCDE: volt_bits = dcdec_voltage(millivolts); - rc = pcf50606_reg_set_bit_mask(pcf, PCF50606_REG_DCDEC1, 0x0f, - volt_bits); + regnr = PCF50606_REG_DCDEC1; break; case PCF50606_REGULATOR_DCUD: volt_bits = dcudc_voltage(millivolts); - rc = pcf50606_reg_set_bit_mask(pcf, PCF50606_REG_DCUDC1, 0x1f, - volt_bits); + regnr = PCF50606_REG_DCUDC1; break; case PCF50606_REGULATOR_D1REG: case PCF50606_REGULATOR_D2REG: case PCF50606_REGULATOR_D3REG: regnr = PCF50606_REG_D1REGC1 + - (regulator_id - PCF50606_REGULATOR_D1REG); + (regulator_id - PCF50606_REGULATOR_D1REG); volt_bits = dx_voltage(millivolts); - rc = pcf50606_reg_set_bit_mask(pcf, regnr, 0x1f, volt_bits); break; case PCF50606_REGULATOR_LPREG: volt_bits = dx_voltage(millivolts); - rc = pcf50606_reg_set_bit_mask(pcf, PCF50606_REG_LPREGC1, 0x1f, - volt_bits); + regnr = PCF50606_REG_LPREGC1; break; case PCF50606_REGULATOR_IOREG: if (millivolts < 1800) return -EINVAL; volt_bits = dx_voltage(millivolts); - rc = pcf50606_reg_set_bit_mask(pcf, PCF50606_REG_IOREGC, 0x1f, - volt_bits); + regnr = PCF50606_REG_IOREGC; break; default: return -EINVAL; } - return rc; + return pcf50606_reg_set_bit_mask(pcf, regnr, 0x1f, volt_bits); } static int pcf50606_regulator_get_voltage(struct regulator_dev *rdev) { struct pcf50606 *pcf; - u8 volt_bits, regnr; - int rc = 0, regulator_id; - + uint8_t volt_bits, regnr; + int regulator_id; + int voltage; pcf = rdev_get_drvdata(rdev); regulator_id = rdev_get_id(rdev); - if (regulator_id >= PCF50606_NUM_REGULATORS) - return -EINVAL; switch (regulator_id) { case PCF50606_REGULATOR_DCD: volt_bits = pcf50606_reg_read(pcf, PCF50606_REG_DCDC1) & 0x1f; - rc = dcdc_2voltage(volt_bits); + voltage = dcdc_2voltage(volt_bits); break; case PCF50606_REGULATOR_DCDE: volt_bits = pcf50606_reg_read(pcf, PCF50606_REG_DCDEC1) & 0x0f; - rc = dcdec_2voltage(volt_bits); + voltage = dcdec_2voltage(volt_bits); break; case PCF50606_REGULATOR_DCUD: volt_bits = pcf50606_reg_read(pcf, PCF50606_REG_DCUDC1) & 0x1f; - rc = dcudc_2voltage(volt_bits); + voltage = dcudc_2voltage(volt_bits); break; case PCF50606_REGULATOR_D1REG: case PCF50606_REGULATOR_D2REG: @@ -223,38 +204,35 @@ static int pcf50606_regulator_get_voltage(struct regulator_dev *rdev) volt_bits = pcf50606_reg_read(pcf, regnr) & 0x1f; if (volt_bits > 0x18) volt_bits = 0x18; - rc = dx_2voltage(volt_bits); + voltage = dx_2voltage(volt_bits); break; case PCF50606_REGULATOR_LPREG: volt_bits = pcf50606_reg_read(pcf, PCF50606_REG_LPREGC1) & 0x1f; if (volt_bits > 0x18) volt_bits = 0x18; - rc = dx_2voltage(volt_bits); + voltage = dx_2voltage(volt_bits); break; case PCF50606_REGULATOR_IOREG: volt_bits = pcf50606_reg_read(pcf, PCF50606_REG_IOREGC) & 0x1f; if (volt_bits > 0x18) volt_bits = 0x18; - rc = dx_2voltage(volt_bits); + voltage = dx_2voltage(volt_bits); break; default: return -EINVAL; } - return rc * 1000; - + return voltage * 1000; } static int pcf50606_regulator_enable(struct regulator_dev *rdev) { struct pcf50606 *pcf = rdev_get_drvdata(rdev); int regulator_id; - u8 regnr; + uint8_t regnr; regulator_id = rdev_get_id(rdev); - if (regulator_id >= PCF50606_NUM_REGULATORS) - return -EINVAL; - + regnr = pcf50606_regulator_registers[regulator_id]; return pcf50606_reg_set_bit_mask(pcf, regnr, 0xe0, 0xe0); @@ -264,16 +242,14 @@ static int pcf50606_regulator_disable(struct regulator_dev *rdev) { struct pcf50606 *pcf = rdev_get_drvdata(rdev); int regulator_id; - u8 regnr; + uint8_t regnr; regulator_id = rdev_get_id(rdev); - if (regulator_id >= PCF50606_NUM_REGULATORS) - return -EINVAL; /* IOREG cannot be powered off since it powers the PMU I2C */ if (regulator_id == PCF50606_REGULATOR_IOREG) return -EINVAL; - + regnr = pcf50606_regulator_registers[regulator_id]; return pcf50606_reg_set_bit_mask(pcf, regnr, 0xe0, 0); @@ -283,11 +259,9 @@ static int pcf50606_regulator_is_enabled(struct regulator_dev *rdev) { struct pcf50606 *pcf = rdev_get_drvdata(rdev); int regulator_id = rdev_get_id(rdev); - u8 regnr, val; + uint8_t regnr, val; regulator_id = rdev_get_id(rdev); - if (regulator_id >= PCF50606_NUM_REGULATORS) - return -EINVAL; /* the *ENA register is always one after the *OUT register */ regnr = pcf50606_regulator_registers[regulator_id]; @@ -332,7 +306,6 @@ static int __devinit pcf50606_regulator_probe(struct platform_device *pdev) struct regulator_dev *rdev; struct pcf50606 *pcf; - /* Already set by core driver */ pcf = dev_to_pcf50606(pdev->dev.parent); rdev = regulator_register(®ulators[pdev->id], &pdev->dev, @@ -361,6 +334,7 @@ static int __devexit pcf50606_regulator_remove(struct platform_device *pdev) static struct platform_driver pcf50606_regulator_driver = { .driver = { .name = "pcf50606-regltr", + .owner = THIS_MODULE, }, .probe = pcf50606_regulator_probe, .remove = __devexit_p(pcf50606_regulator_remove), diff --git a/drivers/rtc/rtc-pcf50606.c b/drivers/rtc/rtc-pcf50606.c index 01ce1b9e48f..5004987100d 100644 --- a/drivers/rtc/rtc-pcf50606.c +++ b/drivers/rtc/rtc-pcf50606.c @@ -52,7 +52,7 @@ enum pcf50606_time_indexes { }; struct pcf50606_time { - u_int8_t time[PCF50606_TI_EXTENT]; + uint8_t time[PCF50606_TI_EXTENT]; }; struct pcf50606_rtc { @@ -301,12 +301,13 @@ static int __devexit pcf50606_rtc_remove(struct platform_device *pdev) struct pcf50606_rtc *rtc; rtc = platform_get_drvdata(pdev); - + + rtc_device_unregister(rtc->rtc_dev); + pcf50606_free_irq(rtc->pcf, PCF50606_IRQ_ALARM); pcf50606_free_irq(rtc->pcf, PCF50606_IRQ_SECOND); - - rtc_device_unregister(rtc->rtc_dev); + platform_set_drvdata(pdev, NULL); kfree(rtc); return 0; @@ -316,6 +317,7 @@ static int __devexit pcf50606_rtc_remove(struct platform_device *pdev) static struct platform_driver pcf50606_rtc_driver = { .driver = { .name = "pcf50606-rtc", + .owner = THIS_MODULE, }, .probe = pcf50606_rtc_probe, .remove = __devexit_p(pcf50606_rtc_remove), diff --git a/include/linux/mfd/pcf50606/gpo.h b/include/linux/mfd/pcf50606/gpo.h deleted file mode 100644 index 081b127d754..00000000000 --- a/include/linux/mfd/pcf50606/gpo.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * gpo.h -- GPO driver for NXP PCF50606 - * - * (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_PCF50606_GPO_H -#define __LINUX_MFD_PCF50606_GPO_H - -#include <linux/mfd/pcf50633/core.h> - -#define PCF50606_REG_GPOC1 0x38 -#define PCF50606_REG_GPOC2 0x39 -#define PCF50606_REG_GPOC3 0x3a -#define PCF50606_REG_GPOC4 0x3b -#define PCF50606_REG_GPOC5 0x3c - -#define PCF50606_GPO1 PCF50606_REG_GPOC1 -#define PCF50606_GPO2 PCF50606_REG_GPOC1 -#define PCF50606_GPOOD1 PCF50606_REG_GPOC2 -#define PCF50606_GPOOD2 PCF50606_REG_GPOC3 -#define PCF50606_GPOOD3 PCF50606_REG_GPOC4 -#define PCF50606_GPOOD4 PCF50606_REG_GPOC5 - -#define PCF50606_GPOCFG_GPOSEL_MASK 0x07 - -void pcf50606_gpo_set_active(struct pcf50606 *pcf, int gpo, int value); -int pcf50606_gpo_get_active(struct pcf50606 *pcf, int gpo); -void pcf50606_gpo_set_standby(struct pcf50606 *pcf, int gpo, int value); -int pcf50606_gpo_get_standby(struct pcf50606 *pcf, int gpo); - -void pcf50606_gpo_invert_set(struct pcf50606 *, int gpo, int invert); -int pcf50606_gpo_invert_get(struct pcf50606 *pcf, int gpo); - -#endif /* __LINUX_MFD_PCF50606_GPIO_H */ - diff --git a/include/linux/mfd/pcf50606/mbc.h b/include/linux/mfd/pcf50606/mbc.h index b793d703a64..23aeb9e3138 100644 --- a/include/linux/mfd/pcf50606/mbc.h +++ b/include/linux/mfd/pcf50606/mbc.h @@ -46,7 +46,7 @@ #define PCF50606_MBC_CHARGER_ONLINE 0x01 #define PCF50606_MBC_CHARGER_ACTIVE 0x02 -void pcf50606_charge_fast(struct pcf50606 *pcf, int on); +int pcf50606_charge_fast(struct pcf50606 *pcf, int on); #endif |