From: marek.vasut@gmail.com (Marek Vasut)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 1/2] ISL6271A voltage regulator support.
Date: Mon, 7 Jun 2010 07:28:25 +0200 [thread overview]
Message-ID: <201006070728.25620.marek.vasut@gmail.com> (raw)
In-Reply-To: <1275887908-22285-1-git-send-email-marek.vasut@gmail.com>
Dne Po 7. ?ervna 2010 07:18:27 Marek Vasut napsal(a):
> This device is very simple, it supports only one LDO. This single LDO is
> programmed over I2C to 16 possible voltages.
>
> Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
I need to test this ... Cyril, will you do me the favour? I'll return that
Zaurus to you, I was unable to compile kernel for it (I dunno what options to
select and I don't feel like trying to figure out).
Also, see the comment below, if it doesn't boot for you, maybe adjust it (try
setting it to 1, 2, 3).
btw. I made modification to 2/2 patch of this series, use the updated patchset.
Thanks!
> ---
> drivers/regulator/Kconfig | 6 +
> drivers/regulator/Makefile | 1 +
> drivers/regulator/isl6271a-regulator.c | 202
> ++++++++++++++++++++++++++++++++ 3 files changed, 209 insertions(+), 0
> deletions(-)
> create mode 100644 drivers/regulator/isl6271a-regulator.c
>
> diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
> index 04f2e08..6772ca7 100644
> --- a/drivers/regulator/Kconfig
> +++ b/drivers/regulator/Kconfig
> @@ -201,5 +201,11 @@ config REGULATOR_88PM8607
> help
> This driver supports 88PM8607 voltage regulator chips.
>
> +config REGULATOR_ISL6271A
> + tristate "Intersil ISL6271A Power regulator"
> + depends on I2C
> + help
> + This driver supports ISL6271A voltage regulator chip.
> +
> endif
>
> diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
> index 4e7feec..e2191bf 100644
> --- a/drivers/regulator/Makefile
> +++ b/drivers/regulator/Makefile
> @@ -31,5 +31,6 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
> obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
> obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
> obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
> +obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
>
> ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
> diff --git a/drivers/regulator/isl6271a-regulator.c
> b/drivers/regulator/isl6271a-regulator.c new file mode 100644
> index 0000000..c6fd20f
> --- /dev/null
> +++ b/drivers/regulator/isl6271a-regulator.c
> @@ -0,0 +1,202 @@
> +/*
> + * isl6271a-regulator.c
> + *
> + * Support for Intersil ISL6271A voltage regulator
> + *
> + * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
> + *
> + * 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 version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
> + * whether express or implied; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
> + * General Public License for more details.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/init.h>
> +#include <linux/err.h>
> +#include <linux/platform_device.h>
> +#include <linux/regulator/driver.h>
> +#include <linux/regulator/machine.h>
> +#include <linux/i2c.h>
> +#include <linux/delay.h>
> +#include <linux/slab.h>
> +
> +/* Supported voltage values for regulators */
> +static const u16 core_buck_table[] = {
> + 850, 900, 950, 1000,
> + 1050, 1100, 1150, 1200,
> + 1250, 1300, 1350, 1400,
> + 1450, 1500, 1550, 1600,
> +};
> +
> +/* PMIC details */
> +struct isl_pmic {
> + struct regulator_desc desc;
> + struct i2c_client *client;
> + struct regulator_dev *rdev;
> + struct mutex mtx;
> +};
> +
> +static int isl6271a_get_voltage(struct regulator_dev *dev)
> +{
> + struct isl_pmic *pmic = rdev_get_drvdata(dev);
> + int idx, data;
> +
> + mutex_lock(&pmic->mtx);
> +
> + idx = i2c_smbus_read_byte_data(pmic->client, 0);
> + if (idx < 0) {
> + dev_err(&pmic->client->dev, "Error getting voltage\n");
> + data = idx;
> + goto out;
> + }
> +
> + data = core_buck_table[idx & 0xf];
> +
> +out:
> + mutex_unlock(&pmic->mtx);
> + return idx;
> +}
> +
> +static int isl6271a_set_voltage(struct regulator_dev *dev, int minuV, int
> maxuV) +{
> + struct isl_pmic *pmic = rdev_get_drvdata(dev);
> + int vsel, err;
> + int pmic_minuV = core_buck_table[0];
> + int pmic_maxuV = core_buck_table[ARRAY_SIZE(core_buck_table) - 1];
> +
> + if (minuV < pmic_minuV || minuV > pmic_maxuV)
> + return -EINVAL;
> + if (maxuV < pmic_minuV || maxuV > pmic_maxuV)
> + return -EINVAL;
> +
> + for (vsel = 0; vsel < ARRAY_SIZE(core_buck_table); vsel++) {
> + int uV = core_buck_table[vsel];
> +
> + if (minuV <= uV && uV <= maxuV)
> + break;
> + }
> +
> + if (vsel == ARRAY_SIZE(core_buck_table))
> + return -EINVAL;
> +
> + mutex_lock(&pmic->mtx);
maybe here we should adjust the vsel with slew-rate (page 9 of the datasheet):
vsel |= slew_rate << 4; // slew_rate is in range 0..3
> +
> + err = i2c_smbus_write_byte_data(pmic->client, 0, vsel);
> + if (err < 0)
> + dev_err(&pmic->client->dev, "Error setting voltage\n");
> +
> + mutex_unlock(&pmic->mtx);
> + return err;
> +}
> +
> +static int isl6271a_list_voltage(struct regulator_dev *dev, unsigned
> selector) +{
> + return core_buck_table[selector];
> +}
> +
> +static struct regulator_ops isl_core_ops = {
> + .get_voltage = isl6271a_get_voltage,
> + .set_voltage = isl6271a_set_voltage,
> + .list_voltage = isl6271a_list_voltage,
> +};
> +
> +static int __devinit isl6271a_probe(struct i2c_client *client,
> + const struct i2c_device_id *id)
> +{
> + struct regulator_init_data *init_data = client->dev.platform_data;
> + struct isl_pmic *pmic;
> + int err;
> +
> + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
> + return -EIO;
> +
> + if (!init_data)
> + return -EIO;
> +
> + pmic = kzalloc(sizeof(struct isl_pmic), GFP_KERNEL);
> + if (!pmic)
> + return -ENOMEM;
> +
> + pmic->client = client;
> +
> + mutex_init(&pmic->mtx);
> +
> + pmic->desc.name = "Core Buck";
> + pmic->desc.id = 0;
> + pmic->desc.n_voltages = ARRAY_SIZE(core_buck_table);
> + pmic->desc.ops = &isl_core_ops;
> + pmic->desc.type = REGULATOR_VOLTAGE;
> + pmic->desc.owner = THIS_MODULE;
> +
> + pmic->rdev = regulator_register(&pmic->desc, &client->dev,
> + init_data, pmic);
> + if (IS_ERR(pmic->rdev)) {
> + dev_err(&client->dev, "failed to register %s\n",
> + id->name);
> + err = PTR_ERR(pmic->rdev);
> + goto error;
> + }
> +
> + i2c_set_clientdata(client, pmic);
> +
> + return 0;
> +
> +error:
> + regulator_unregister(pmic->rdev);
> +
> + kfree(pmic);
> + return err;
> +}
> +
> +static int __devexit isl6271a_remove(struct i2c_client *client)
> +{
> + struct isl_pmic *pmic = i2c_get_clientdata(client);
> +
> + i2c_set_clientdata(client, NULL);
> +
> + regulator_unregister(pmic->rdev);
> +
> + kfree(pmic);
> +
> + return 0;
> +}
> +
> +static const struct i2c_device_id isl6271a_id[] = {
> + {.name = "isl6271a", 0 },
> + { },
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, isl6271a_id);
> +
> +static struct i2c_driver isl6271a_i2c_driver = {
> + .driver = {
> + .name = "isl6271a",
> + .owner = THIS_MODULE,
> + },
> + .probe = isl6271a_probe,
> + .remove = __devexit_p(isl6271a_remove),
> + .id_table = isl6271a_id,
> +};
> +
> +static int __init isl6271a_init(void)
> +{
> + return i2c_add_driver(&isl6271a_i2c_driver);
> +}
> +
> +static void __exit isl6271a_cleanup(void)
> +{
> + i2c_del_driver(&isl6271a_i2c_driver);
> +}
> +
> +subsys_initcall(isl6271a_init);
> +module_exit(isl6271a_cleanup);
> +
> +MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
> +MODULE_DESCRIPTION("Intersil ISL6271A voltage regulator driver");
> +MODULE_LICENSE("GPL v2");
next prev parent reply other threads:[~2010-06-07 5:28 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-07 5:18 [PATCH 1/2] ISL6271A voltage regulator support Marek Vasut
2010-06-07 5:18 ` [PATCH 2/2] pxa/spitz: Add isl6271a voltage regulator Marek Vasut
2010-06-07 5:28 ` Marek Vasut [this message]
2010-06-07 11:48 ` [PATCH 1/2] ISL6271A voltage regulator support Mark Brown
2010-06-07 14:54 ` Marek Vasut
2010-06-13 10:53 ` Eric Miao
-- strict thread matches above, loose matches on Subject: below --
2010-06-07 5:27 Marek Vasut
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=201006070728.25620.marek.vasut@gmail.com \
--to=marek.vasut@gmail.com \
--cc=linux-arm-kernel@lists.infradead.org \
/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.