From: Mark Brown <broonie@opensource.wolfsonmicro.com>
To: Balaji Rao <balajirrao@openmoko.org>
Cc: linux-kernel@vger.kernel.org, Andy Green <andy@openmoko.com>,
Liam Girdwood <lrg@slimlogic.co.uk>
Subject: Re: [PATCH V2 7/7] regulator: PCF50633 pmic driver
Date: Thu, 18 Dec 2008 10:08:35 +0000 [thread overview]
Message-ID: <20081218100835.GA27075@rakim.wolfsonmicro.main> (raw)
In-Reply-To: <20081218055817.31696.67376.stgit@cff.thadambail>
On Thu, Dec 18, 2008 at 11:28:17AM +0530, Balaji Rao wrote:
> Changes from V1:
> - Removed support for suspend_enable & suspend_disable functions.
>
> Signed-off-by: Balaji Rao <balajirrao@openmoko.org>
> Cc: Andy Green <andy@openmoko.com>
> Cc: Liam Girdwood <lrg@simlogic.co.uk>
That should be slimlogic with two ls - fixed in the CCs and not cutting
any text for his benefit.
> Cc: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
> ---
> drivers/regulator/Kconfig | 7 +
> drivers/regulator/Makefile | 1
> drivers/regulator/pcf50633-regulator.c | 330 ++++++++++++++++++++++++++++++++
> include/linux/mfd/pcf50633/pmic.h | 68 +++++++
> 4 files changed, 406 insertions(+), 0 deletions(-)
> create mode 100644 drivers/regulator/pcf50633-regulator.c
> create mode 100644 include/linux/mfd/pcf50633/pmic.h
>
> diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
> index 39360e2..e7e0cf1 100644
> --- a/drivers/regulator/Kconfig
> +++ b/drivers/regulator/Kconfig
> @@ -73,4 +73,11 @@ config REGULATOR_DA903X
> Say y here to support the BUCKs and LDOs regulators found on
> Dialog Semiconductor DA9030/DA9034 PMIC.
>
> +config REGULATOR_PCF50633
> + tristate "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/Makefile b/drivers/regulator/Makefile
> index 254d40c..61b30c6 100644
> --- a/drivers/regulator/Makefile
> +++ b/drivers/regulator/Makefile
> @@ -11,5 +11,6 @@ obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
> obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
> obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
> obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
> +obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
>
> ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
> diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
> new file mode 100644
> index 0000000..7a5d732
> --- /dev/null
> +++ b/drivers/regulator/pcf50633-regulator.c
> @@ -0,0 +1,330 @@
> +/* NXP 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 and Werner Almesberger
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + *
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/device.h>
> +#include <linux/err.h>
> +#include <linux/platform_device.h>
> +
> +#include <linux/mfd/pcf50633/core.h>
> +#include <linux/mfd/pcf50633/pmic.h>
> +
> +#define PCF50633_REGULATOR(_name, _id) \
> + { \
> + .name = _name, \
> + .id = _id, \
> + .ops = &pcf50633_regulator_ops, \
> + .type = REGULATOR_VOLTAGE, \
> + .owner = THIS_MODULE, \
> + }
> +
> +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,
> +};
> +
> +/* Bits from voltage value */
> +static u8 auto_voltage_bits(unsigned int millivolts)
> +{
> + if (millivolts < 1800)
> + return 0;
> + if (millivolts > 3800)
> + return 0xff;
> +
> + millivolts -= 625;
> +
> + return millivolts / 25;
> +}
> +
> +static u8 down_voltage_bits(unsigned int millivolts)
> +{
> + if (millivolts < 625)
> + return 0;
> + else if (millivolts > 3000)
> + return 0xff;
> +
> + millivolts -= 625;
> +
> + return millivolts / 25;
> +}
> +
> +static u8 ldo_voltage_bits(unsigned int millivolts)
> +{
> + if (millivolts < 900)
> + return 0;
> + else if (millivolts > 3600)
> + return 0x1f;
> +
> + millivolts -= 900;
> + return millivolts / 100;
> +}
> +
> +/* Obtain voltage value from bits */
> +static unsigned int auto_voltage_value(u8 bits)
> +{
> + if (bits < 0x2f)
> + return 0;
> +
> + return 625 + (bits * 25);
> +}
> +
> +
> +static unsigned int down_voltage_value(u8 bits)
> +{
> + return 625 + (bits * 25);
> +}
> +
> +
> +static unsigned int ldo_voltage_value(u8 bits)
> +{
> + bits &= 0x1f;
> +
> + return 900 + (bits * 100);
> +}
> +
> +static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
> + int min_uV, int max_uV)
> +{
> + struct pcf50633 *pcf;
> + int regulator_id, millivolts;
> + u8 volt_bits, regnr;
> +
> + pcf = rdev_get_drvdata(rdev);
> +
> + regulator_id = rdev_get_id(rdev);
> + if (regulator_id >= PCF50633_NUM_REGULATORS)
> + return -EINVAL;
> +
> + millivolts = min_uV / 1000;
> +
> + regnr = pcf50633_regulator_registers[regulator_id];
> +
> + switch (regulator_id) {
> + case PCF50633_REGULATOR_AUTO:
> + volt_bits = auto_voltage_bits(millivolts);
> + break;
> + case PCF50633_REGULATOR_DOWN1:
> + volt_bits = down_voltage_bits(millivolts);
> + break;
> + case PCF50633_REGULATOR_DOWN2:
> + volt_bits = down_voltage_bits(millivolts);
> + break;
> + case PCF50633_REGULATOR_LDO1:
> + case PCF50633_REGULATOR_LDO2:
> + case PCF50633_REGULATOR_LDO3:
> + case PCF50633_REGULATOR_LDO4:
> + case PCF50633_REGULATOR_LDO5:
> + case PCF50633_REGULATOR_LDO6:
> + case PCF50633_REGULATOR_HCLDO:
> + volt_bits = ldo_voltage_bits(millivolts);
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + return pcf50633_reg_write(pcf, regnr, volt_bits);
> +}
> +
> +static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
> +{
> + struct pcf50633 *pcf;
> + int regulator_id, millivolts, volt_bits;
> + u8 regnr;
> +
> + pcf = rdev_get_drvdata(rdev);;
> +
> + regulator_id = rdev_get_id(rdev);
> + if (regulator_id >= PCF50633_NUM_REGULATORS)
> + return -EINVAL;
> +
> + regnr = pcf50633_regulator_registers[regulator_id];
> +
> + volt_bits = pcf50633_reg_read(pcf, regnr);
> + if (volt_bits < 0)
> + return -1;
> +
> + switch (regulator_id) {
> + case PCF50633_REGULATOR_AUTO:
> + millivolts = auto_voltage_value(volt_bits);
> + break;
> + case PCF50633_REGULATOR_DOWN1:
> + millivolts = down_voltage_value(volt_bits);
> + break;
> + case PCF50633_REGULATOR_DOWN2:
> + millivolts = down_voltage_value(volt_bits);
> + break;
> + case PCF50633_REGULATOR_LDO1:
> + case PCF50633_REGULATOR_LDO2:
> + case PCF50633_REGULATOR_LDO3:
> + case PCF50633_REGULATOR_LDO4:
> + case PCF50633_REGULATOR_LDO5:
> + case PCF50633_REGULATOR_LDO6:
> + case PCF50633_REGULATOR_HCLDO:
> + millivolts = ldo_voltage_value(volt_bits);
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + return millivolts * 1000;
> +}
> +
> +static int pcf50633_regulator_enable(struct regulator_dev *rdev)
> +{
> + struct pcf50633 *pcf = rdev_get_drvdata(rdev);
> + int regulator_id;
> + u8 regnr;
> +
> + regulator_id = rdev_get_id(rdev);
> + if (regulator_id >= PCF50633_NUM_REGULATORS)
> + return -EINVAL;
> +
> + /* The *ENA register is always one after the *OUT register */
> + regnr = pcf50633_regulator_registers[regulator_id] + 1;
> +
> + return pcf50633_reg_set_bit_mask(pcf, regnr, PCF50633_REGULATOR_ON,
> + PCF50633_REGULATOR_ON);
> +
> +}
> +
> +static int pcf50633_regulator_disable(struct regulator_dev *rdev)
> +{
> + struct pcf50633 *pcf = rdev_get_drvdata(rdev);
> + int regulator_id;
> + u8 regnr;
> +
> + regulator_id = rdev_get_id(rdev);
> + if (regulator_id >= PCF50633_NUM_REGULATORS)
> + return -EINVAL;
> +
> + /* the *ENA register is always one after the *OUT register */
> + regnr = pcf50633_regulator_registers[regulator_id] + 1;
> +
> + return pcf50633_reg_set_bit_mask(pcf, regnr,
> + PCF50633_REGULATOR_ON, 0);
> +}
> +
> +static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev)
> +{
> + struct pcf50633 *pcf = rdev_get_drvdata(rdev);
> + int regulator_id = rdev_get_id(rdev);
> + u8 regnr;
> +
> + regulator_id = rdev_get_id(rdev);
> + if (regulator_id >= PCF50633_NUM_REGULATORS)
> + return -EINVAL;
> +
> + /* the *ENA register is always one after the *OUT register */
> + regnr = pcf50633_regulator_registers[regulator_id] + 1;
> +
> + return pcf50633_reg_read(pcf, regnr) & PCF50633_REGULATOR_ON;
> +}
> +
> +static struct regulator_ops pcf50633_regulator_ops = {
> + .set_voltage = pcf50633_regulator_set_voltage,
> + .get_voltage = pcf50633_regulator_get_voltage,
> + .enable = pcf50633_regulator_enable,
> + .disable = pcf50633_regulator_disable,
> + .is_enabled = pcf50633_regulator_is_enabled,
> +};
> +
> +static struct regulator_desc regulators[] = {
> + [PCF50633_REGULATOR_AUTO] =
> + PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO),
> + [PCF50633_REGULATOR_DOWN1] =
> + PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1),
> + [PCF50633_REGULATOR_DOWN2] =
> + PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2),
> + [PCF50633_REGULATOR_LDO1] =
> + PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1),
> + [PCF50633_REGULATOR_LDO2] =
> + PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2),
> + [PCF50633_REGULATOR_LDO3] =
> + PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3),
> + [PCF50633_REGULATOR_LDO4] =
> + PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4),
> + [PCF50633_REGULATOR_LDO5] =
> + PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5),
> + [PCF50633_REGULATOR_LDO6] =
> + PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6),
> + [PCF50633_REGULATOR_HCLDO] =
> + PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO),
> + [PCF50633_REGULATOR_MEMLDO] =
> + PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO),
> +};
> +
> +static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
> +{
> + struct regulator_dev *rdev;
> + struct pcf50633 *pcf;
> +
> + /* Already set by core driver */
> + pcf = platform_get_drvdata(pdev);
> +
> + rdev = regulator_register(®ulators[pdev->id], &pdev->dev, pcf);
> + if (IS_ERR(rdev))
> + return PTR_ERR(rdev);
> +
> + if (pcf->pdata->regulator_registered)
> + pcf->pdata->regulator_registered(pcf, pdev->id);
> +
> + return 0;
> +}
> +
> +static int __devexit pcf50633_regulator_remove(struct platform_device *pdev)
> +{
> + struct regulator_dev *rdev = platform_get_drvdata(pdev);
> +
> + regulator_unregister(rdev);
> +
> + return 0;
> +}
> +
> +static struct platform_driver pcf50633_regulator_driver = {
> + .driver = {
> + .name = "pcf50633-regltr",
> + },
> + .probe = pcf50633_regulator_probe,
> + .remove = __devexit_p(pcf50633_regulator_remove),
> +};
> +
> +static int __init pcf50633_regulator_init(void)
> +{
> + return platform_driver_register(&pcf50633_regulator_driver);
> +}
> +module_init(pcf50633_regulator_init);
> +
> +static void __exit pcf50633_regulator_exit(void)
> +{
> + platform_driver_unregister(&pcf50633_regulator_driver);
> +}
> +module_exit(pcf50633_regulator_exit);
> +
> +MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
> +MODULE_DESCRIPTION("PCF50633 regulator driver");
> +MODULE_LICENSE("GPL");
> +MODULE_ALIAS("platform:pcf50633-regulator");
> diff --git a/include/linux/mfd/pcf50633/pmic.h b/include/linux/mfd/pcf50633/pmic.h
> new file mode 100644
> index 0000000..8c567a1
> --- /dev/null
> +++ b/include/linux/mfd/pcf50633/pmic.h
> @@ -0,0 +1,68 @@
> +#ifndef __LINUX_MFD_PCF50633_PMIC_H
> +#define __LINUX_MFD_PCF50633_PMIC_H
> +
> +#include <linux/mfd/pcf50633/core.h>
> +#include <linux/platform_device.h>
> +
> +#define PCF50633_REG_AUTOOUT 0x1a
> +#define PCF50633_REG_AUTOENA 0x1b
> +#define PCF50633_REG_AUTOCTL 0x1c
> +#define PCF50633_REG_AUTOMXC 0x1d
> +#define PCF50633_REG_DOWN1OUT 0x1e
> +#define PCF50633_REG_DOWN1ENA 0x1f
> +#define PCF50633_REG_DOWN1CTL 0x20
> +#define PCF50633_REG_DOWN1MXC 0x21
> +#define PCF50633_REG_DOWN2OUT 0x22
> +#define PCF50633_REG_DOWN2ENA 0x23
> +#define PCF50633_REG_DOWN2CTL 0x24
> +#define PCF50633_REG_DOWN2MXC 0x25
> +#define PCF50633_REG_MEMLDOOUT 0x26
> +#define PCF50633_REG_MEMLDOENA 0x27
> +#define PCF50633_REG_LDO1OUT 0x2d
> +#define PCF50633_REG_LDO1ENA 0x2e
> +#define PCF50633_REG_LDO2OUT 0x2f
> +#define PCF50633_REG_LDO2ENA 0x30
> +#define PCF50633_REG_LDO3OUT 0x31
> +#define PCF50633_REG_LDO3ENA 0x32
> +#define PCF50633_REG_LDO4OUT 0x33
> +#define PCF50633_REG_LDO4ENA 0x34
> +#define PCF50633_REG_LDO5OUT 0x35
> +#define PCF50633_REG_LDO5ENA 0x36
> +#define PCF50633_REG_LDO6OUT 0x37
> +#define PCF50633_REG_LDO6ENA 0x38
> +#define PCF50633_REG_HCLDOOUT 0x39
> +#define PCF50633_REG_HCLDOENA 0x3a
> +#define PCF50633_REG_HCLDOOVL 0x40
> +
> +enum pcf50633_regulator_enable {
> + PCF50633_REGULATOR_ON = 0x01,
> + PCF50633_REGULATOR_ON_GPIO1 = 0x02,
> + PCF50633_REGULATOR_ON_GPIO2 = 0x04,
> + PCF50633_REGULATOR_ON_GPIO3 = 0x08,
> +};
> +#define PCF50633_REGULATOR_ON_MASK 0x0f
> +
> +enum pcf50633_regulator_phase {
> + PCF50633_REGULATOR_ACTPH1 = 0x00,
> + PCF50633_REGULATOR_ACTPH2 = 0x10,
> + PCF50633_REGULATOR_ACTPH3 = 0x20,
> + PCF50633_REGULATOR_ACTPH4 = 0x30,
> +};
> +#define PCF50633_REGULATOR_ACTPH_MASK 0x30
> +
> +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,
> +};
> +
> +#endif
> +
>
next prev parent reply other threads:[~2008-12-18 10:08 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-12-18 5:56 [PATCH V2 0/7] PCF50633 support Balaji Rao
2008-12-18 5:56 ` [PATCH V2 1/7] mfd: PCF50633 core driver Balaji Rao
2008-12-18 5:56 ` [PATCH V2 2/7] mfd: PCF50633 adc driver Balaji Rao
2008-12-19 11:18 ` Jonathan Cameron
2008-12-19 12:05 ` Mark Brown
2008-12-19 12:47 ` Jonathan Cameron
2008-12-19 12:15 ` Andy Green
2008-12-19 12:51 ` Jonathan Cameron
2008-12-22 16:23 ` Balaji Rao
2008-12-18 5:57 ` [PATCH V2 3/7] mfd: PCF50633 gpio support Balaji Rao
2008-12-18 5:57 ` [PATCH V2 4/7] rtc: PCF50633 rtc driver Balaji Rao
2008-12-18 9:03 ` Alessandro Zummo
2008-12-18 15:11 ` Balaji Rao
2008-12-18 16:52 ` Alessandro Zummo
2008-12-18 5:57 ` [PATCH V2 5/7] power_supply: PCF50633 battery charger driver Balaji Rao
2008-12-18 20:26 ` Balaji Rao
2008-12-25 15:45 ` Anton Vorontsov
2008-12-25 18:50 ` Balaji Rao
2008-12-18 5:58 ` [PATCH V2 6/7] input: PCF50633 input driver Balaji Rao
2008-12-18 5:58 ` [PATCH V2 7/7] regulator: PCF50633 pmic driver Balaji Rao
2008-12-18 10:08 ` Mark Brown [this message]
2008-12-18 15:14 ` Balaji Rao
2008-12-18 20:30 ` Liam Girdwood
2008-12-18 20:47 ` Balaji Rao
2008-12-18 20:54 ` Liam Girdwood
2008-12-22 10:50 ` [PATCH V2 0/7] PCF50633 support Samuel Ortiz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20081218100835.GA27075@rakim.wolfsonmicro.main \
--to=broonie@opensource.wolfsonmicro.com \
--cc=andy@openmoko.com \
--cc=balajirrao@openmoko.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lrg@slimlogic.co.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.