aboutsummaryrefslogtreecommitdiff
path: root/drivers/mfd
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mfd')
-rw-r--r--drivers/mfd/Kconfig9
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/pcf50606-adc.c28
-rw-r--r--drivers/mfd/pcf50606-core.c81
-rw-r--r--drivers/mfd/pcf50606-gpo.c119
-rw-r--r--drivers/mfd/pcf50633-core.c11
6 files changed, 64 insertions, 185 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index dfd63bcaee6..aa167dde4b7 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -279,15 +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.
-
-source "drivers/mfd/glamo/Kconfig"
-
endmenu
menu "Multimedia Capabilities Port drivers"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 21d26b3a0ad..25ae87a4f0b 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -48,5 +48,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/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
index 1d5e5212d81..41ac3a52df1 100644
--- a/drivers/mfd/pcf50633-core.c
+++ b/drivers/mfd/pcf50633-core.c
@@ -353,18 +353,18 @@ static void pcf50633_irq_worker(struct work_struct *work)
if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) {
chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
if (chgstat & (0x3 << 4))
- pcf_int[0] &= ~(1 << PCF50633_INT1_USBREM);
+ pcf_int[0] &= ~PCF50633_INT1_USBREM;
else
- pcf_int[0] &= ~(1 << PCF50633_INT1_USBINS);
+ pcf_int[0] &= ~PCF50633_INT1_USBINS;
}
/* Make sure only one of ADPINS or ADPREM is set */
if (pcf_int[0] & (PCF50633_INT1_ADPINS | PCF50633_INT1_ADPREM)) {
chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
if (chgstat & (0x3 << 4))
- pcf_int[0] &= ~(1 << PCF50633_INT1_ADPREM);
+ pcf_int[0] &= ~PCF50633_INT1_ADPREM;
else
- pcf_int[0] &= ~(1 << PCF50633_INT1_ADPINS);
+ pcf_int[0] &= ~PCF50633_INT1_ADPINS;
}
dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x "
@@ -619,6 +619,9 @@ static int __devinit 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-backlight",
+ &pcf->bl_pdev);
+
for (i = 0; i < PCF50633_NUM_REGULATORS; i++) {
struct platform_device *pdev;