[PATCH] make mc13783 code generic

Yong Shen yong.shen at linaro.org
Tue Nov 30 04:50:46 EST 2010


Thanks, Alberto. Version 2 will come out soon.

On Tue, Nov 30, 2010 at 5:41 PM, Alberto Panizzo
<maramaopercheseimorto at gmail.com> wrote:
> Hi Yong,
> some comments inline..
>
> On mar, 2010-11-30 at 14:26 +0800, Yong Shen wrote:
>> Hi there,
>>
>> For better code share between mc13783 and mc13892, I did some clean up
>> and move some common code to a separated file. And mc13892 code will
>> come after this patch.
>>
>> Thanks
>> Yong
>>
>> From 98e187834085624c3651587da56da48bec958e05 Mon Sep 17 00:00:00 2001
>> From: Yong Shen <yong.shen at linaro.org>
>> Date: Tue, 30 Nov 2010 14:11:34 +0800
>> Subject: [PATCH] make mc13783 code generic
>>
>> move some common functions and micros to a seperate file,
>> which makes it possible for mc13892 to share code
>>
>> Signed-off-by: Yong Shen <yong.shen at linaro.org>
>> ---
>>  drivers/regulator/Makefile                 |    2 +-
>>  drivers/regulator/mc13783-regulator.c      |  311 +++++-----------------------
>>  drivers/regulator/mc13xxx-regulator-core.c |  241 +++++++++++++++++++++
>>  include/linux/mfd/mc13783.h                |   67 +++---
>>  include/linux/regulator/mc13xxx.h          |  101 +++++++++
>>  5 files changed, 426 insertions(+), 296 deletions(-)
>>  create mode 100644 drivers/regulator/mc13xxx-regulator-core.c
>>  create mode 100644 include/linux/regulator/mc13xxx.h
>>
>> diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
>> index bff8157..4008bf6 100644
>> --- a/drivers/regulator/Makefile
>> +++ b/drivers/regulator/Makefile
>> @@ -29,7 +29,7 @@ obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
>>  obj-$(CONFIG_REGULATOR_DA903X)       += da903x.o
>>  obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
>>  obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
>> -obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
>> +obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o mc13xxx-regulator-core.o
>>  obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
>>
>>  obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
>> diff --git a/drivers/regulator/mc13783-regulator.c
>> b/drivers/regulator/mc13783-regulator.c
>> index 4597d50..fde55f4 100644
>> --- a/drivers/regulator/mc13783-regulator.c
>> +++ b/drivers/regulator/mc13783-regulator.c
>> @@ -1,6 +1,7 @@
>>  /*
>>   * Regulator Driver for Freescale MC13783 PMIC
>>   *
>> + * Copyright 2010 Yong Shen <yong.shen at linaro.org>
>>   * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer at pengutronix.de>
>>   * Copyright 2009 Alberto Panizzo <maramaopercheseimorto at gmail.com>
>>   *
>> @@ -10,6 +11,7 @@
>>   */
>>
>>  #include <linux/mfd/mc13783.h>
>> +#include <linux/regulator/mc13xxx.h>
>>  #include <linux/regulator/machine.h>
>>  #include <linux/regulator/driver.h>
>>  #include <linux/platform_device.h>
>> @@ -89,16 +91,6 @@
>>  #define MC13783_REG_POWERMISC_PWGTSPI_M                      (3 << 15)
>>
>>
>> -struct mc13783_regulator {
>> -     struct regulator_desc desc;
>> -     int reg;
>> -     int enable_bit;
>> -     int vsel_reg;
>> -     int vsel_shift;
>> -     int vsel_mask;
>> -     int const *voltages;
>> -};
>> -
>>  /* Voltage Values */
>>  static const int const mc13783_sw3_val[] = {
>>       5000000, 5000000, 5000000, 5500000,
>> @@ -175,10 +167,9 @@ static const int const mc13783_pwgtdrv_val[] = {
>>       5500000,
>>  };
>>
>> -static struct regulator_ops mc13783_regulator_ops;
>> -static struct regulator_ops mc13783_fixed_regulator_ops;
>>  static struct regulator_ops mc13783_gpo_regulator_ops;
>>
>> +/*
>>  #define MC13783_DEFINE(prefix, _name, _reg, _vsel_reg, _voltages)    \
>>       [MC13783_ ## prefix ## _ ## _name] = {                          \
>>               .desc = {                                               \
>> @@ -196,43 +187,26 @@ static struct regulator_ops mc13783_gpo_regulator_ops;
>>               .vsel_mask = MC13783_REG_ ## _vsel_reg ## _ ## _name ## VSEL_M,\
>>               .voltages =  _voltages,                                 \
>>       }
>> +     */
>
> Is this really meant to be commented?
>
>>
>> -#define MC13783_FIXED_DEFINE(prefix, _name, _reg, _voltages)         \
>> -     [MC13783_ ## prefix ## _ ## _name] = {                          \
>> -             .desc = {                                               \
>> -                     .name = #prefix "_" #_name,                     \
>> -                     .n_voltages = ARRAY_SIZE(_voltages),            \
>> -                     .ops = &mc13783_fixed_regulator_ops,            \
>> -                     .type = REGULATOR_VOLTAGE,                      \
>> -                     .id = MC13783_ ## prefix ## _ ## _name,         \
>> -                     .owner = THIS_MODULE,                           \
>> -             },                                                      \
>> -             .reg = MC13783_REG_ ## _reg,                            \
>> -             .enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN, \
>> -             .voltages =  _voltages,                                 \
>> -     }
>> +#define MC13783_DEFINE(prefix, name, reg, vsel_reg, voltages)        \
>> +     MC13xxx_DEFINE(MC13783_REG_, name, reg, vsel_reg, voltages, \
>> +                     mc13xxx_regulator_ops)
>>
>> -#define MC13783_GPO_DEFINE(prefix, _name, _reg,  _voltages)          \
>> -     [MC13783_ ## prefix ## _ ## _name] = {                          \
>> -             .desc = {                                               \
>> -                     .name = #prefix "_" #_name,                     \
>> -                     .n_voltages = ARRAY_SIZE(_voltages),            \
>> -                     .ops = &mc13783_gpo_regulator_ops,              \
>> -                     .type = REGULATOR_VOLTAGE,                      \
>> -                     .id = MC13783_ ## prefix ## _ ## _name,         \
>> -                     .owner = THIS_MODULE,                           \
>> -             },                                                      \
>> -             .reg = MC13783_REG_ ## _reg,                            \
>> -             .enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN, \
>> -             .voltages =  _voltages,                                 \
>> -     }
>> +#define MC13783_FIXED_DEFINE(prefix, name, reg, voltages)            \
>> +     MC13xxx_FIXED_DEFINE(MC13783_REG_, name, reg, voltages, \
>> +                     mc13xxx_fixed_regulator_ops)
>> +
>> +#define MC13783_GPO_DEFINE(prefix, name, reg, voltages)              \
>> +     MC13xxx_GPO_DEFINE(MC13783_REG_, name, reg, voltages, \
>> +                     mc13783_gpo_regulator_ops)
>>
>>  #define MC13783_DEFINE_SW(_name, _reg, _vsel_reg, _voltages)         \
>>       MC13783_DEFINE(SW, _name, _reg, _vsel_reg, _voltages)
>>  #define MC13783_DEFINE_REGU(_name, _reg, _vsel_reg, _voltages)               \
>>       MC13783_DEFINE(REGU, _name, _reg, _vsel_reg, _voltages)
>>
>> -static struct mc13783_regulator mc13783_regulators[] = {
>> +static struct mc13xxx_regulator mc13783_regulators[] = {
>>       MC13783_DEFINE_SW(SW3, SWITCHERS5, SWITCHERS5, mc13783_sw3_val),
>>
>>       MC13783_FIXED_DEFINE(REGU, VAUDIO, REGULATORMODE0, mc13783_vaudio_val),
>> @@ -274,207 +248,16 @@ static struct mc13783_regulator mc13783_regulators[] = {
>>       MC13783_GPO_DEFINE(REGU, PWGT2SPI, POWERMISC, mc13783_pwgtdrv_val),
>>  };
>>
>> -struct mc13783_regulator_priv {
>> -     struct mc13783 *mc13783;
>> -     u32 powermisc_pwgt_state;
>> -     struct regulator_dev *regulators[];
>> -};
>> -
>> -static int mc13783_regulator_enable(struct regulator_dev *rdev)
>> -{
>> -     struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
>> -     int id = rdev_get_id(rdev);
>> -     int ret;
>> -
>> -     dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
>> -
>> -     mc13783_lock(priv->mc13783);
>> -     ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].reg,
>> -                     mc13783_regulators[id].enable_bit,
>> -                     mc13783_regulators[id].enable_bit);
>> -     mc13783_unlock(priv->mc13783);
>> -
>> -     return ret;
>> -}
>> -
>> -static int mc13783_regulator_disable(struct regulator_dev *rdev)
>> -{
>> -     struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
>> -     int id = rdev_get_id(rdev);
>> -     int ret;
>> -
>> -     dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
>> -
>> -     mc13783_lock(priv->mc13783);
>> -     ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].reg,
>> -                     mc13783_regulators[id].enable_bit, 0);
>> -     mc13783_unlock(priv->mc13783);
>> -
>> -     return ret;
>> -}
>> -
>> -static int mc13783_regulator_is_enabled(struct regulator_dev *rdev)
>> -{
>> -     struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
>> -     int ret, id = rdev_get_id(rdev);
>> -     unsigned int val;
>> -
>> -     mc13783_lock(priv->mc13783);
>> -     ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val);
>> -     mc13783_unlock(priv->mc13783);
>> -
>> -     if (ret)
>> -             return ret;
>> -
>> -     return (val & mc13783_regulators[id].enable_bit) != 0;
>> -}
>> -
>> -static int mc13783_regulator_list_voltage(struct regulator_dev *rdev,
>> -                                             unsigned selector)
>> -{
>> -     int id = rdev_get_id(rdev);
>> -
>> -     if (selector >= mc13783_regulators[id].desc.n_voltages)
>> -             return -EINVAL;
>> -
>> -     return mc13783_regulators[id].voltages[selector];
>> -}
>> -
>> -static int mc13783_get_best_voltage_index(struct regulator_dev *rdev,
>> -                                             int min_uV, int max_uV)
>> -{
>> -     int reg_id = rdev_get_id(rdev);
>> -     int i;
>> -     int bestmatch;
>> -     int bestindex;
>> -
>> -     /*
>> -      * Locate the minimum voltage fitting the criteria on
>> -      * this regulator. The switchable voltages are not
>> -      * in strict falling order so we need to check them
>> -      * all for the best match.
>> -      */
>> -     bestmatch = INT_MAX;
>> -     bestindex = -1;
>> -     for (i = 0; i < mc13783_regulators[reg_id].desc.n_voltages; i++) {
>> -             if (mc13783_regulators[reg_id].voltages[i] >= min_uV &&
>> -                 mc13783_regulators[reg_id].voltages[i] < bestmatch) {
>> -                     bestmatch = mc13783_regulators[reg_id].voltages[i];
>> -                     bestindex = i;
>> -             }
>> -     }
>> -
>> -     if (bestindex < 0 || bestmatch > max_uV) {
>> -             dev_warn(&rdev->dev, "no possible value for %d<=x<=%d uV\n",
>> -                             min_uV, max_uV);
>> -             return -EINVAL;
>> -     }
>> -     return bestindex;
>> -}
>> -
>> -static int mc13783_regulator_set_voltage(struct regulator_dev *rdev,
>> -                                             int min_uV, int max_uV)
>> -{
>> -     struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
>> -     int value, id = rdev_get_id(rdev);
>> -     int ret;
>> -
>> -     dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
>> -             __func__, id, min_uV, max_uV);
>> -
>> -     /* Find the best index */
>> -     value = mc13783_get_best_voltage_index(rdev, min_uV, max_uV);
>> -     dev_dbg(rdev_get_dev(rdev), "%s best value: %d \n", __func__, value);
>> -     if (value < 0)
>> -             return value;
>> -
>> -     mc13783_lock(priv->mc13783);
>> -     ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].vsel_reg,
>> -                     mc13783_regulators[id].vsel_mask,
>> -                     value << mc13783_regulators[id].vsel_shift);
>> -     mc13783_unlock(priv->mc13783);
>> -
>> -     return ret;
>> -}
>> -
>> -static int mc13783_regulator_get_voltage(struct regulator_dev *rdev)
>> -{
>> -     struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
>> -     int ret, id = rdev_get_id(rdev);
>> -     unsigned int val;
>> -
>> -     dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
>> -
>> -     mc13783_lock(priv->mc13783);
>> -     ret = mc13783_reg_read(priv->mc13783,
>> -                             mc13783_regulators[id].vsel_reg, &val);
>> -     mc13783_unlock(priv->mc13783);
>> -
>> -     if (ret)
>> -             return ret;
>> -
>> -     val = (val & mc13783_regulators[id].vsel_mask)
>> -             >> mc13783_regulators[id].vsel_shift;
>> -
>> -     dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val);
>> -
>> -     BUG_ON(val < 0 || val > mc13783_regulators[id].desc.n_voltages);
>> -
>> -     return mc13783_regulators[id].voltages[val];
>> -}
>> -
>> -static struct regulator_ops mc13783_regulator_ops = {
>> -     .enable = mc13783_regulator_enable,
>> -     .disable = mc13783_regulator_disable,
>> -     .is_enabled = mc13783_regulator_is_enabled,
>> -     .list_voltage = mc13783_regulator_list_voltage,
>> -     .set_voltage = mc13783_regulator_set_voltage,
>> -     .get_voltage = mc13783_regulator_get_voltage,
>> -};
>> -
>> -static int mc13783_fixed_regulator_set_voltage(struct regulator_dev *rdev,
>> -                                             int min_uV, int max_uV)
>> -{
>> -     int id = rdev_get_id(rdev);
>> -
>> -     dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
>> -             __func__, id, min_uV, max_uV);
>> -
>> -     if (min_uV >= mc13783_regulators[id].voltages[0] &&
>> -         max_uV <= mc13783_regulators[id].voltages[0])
>> -             return 0;
>> -     else
>> -             return -EINVAL;
>> -}
>> -
>> -static int mc13783_fixed_regulator_get_voltage(struct regulator_dev *rdev)
>> -{
>> -     int id = rdev_get_id(rdev);
>> -
>> -     dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
>> -
>> -     return mc13783_regulators[id].voltages[0];
>> -}
>> -
>> -static struct regulator_ops mc13783_fixed_regulator_ops = {
>> -     .enable = mc13783_regulator_enable,
>> -     .disable = mc13783_regulator_disable,
>> -     .is_enabled = mc13783_regulator_is_enabled,
>> -     .list_voltage = mc13783_regulator_list_voltage,
>> -     .set_voltage = mc13783_fixed_regulator_set_voltage,
>> -     .get_voltage = mc13783_fixed_regulator_get_voltage,
>> -};
>> -
>> -int mc13783_powermisc_rmw(struct mc13783_regulator_priv *priv, u32 mask,
>> +int mc13783_powermisc_rmw(struct mc13xxx_regulator_priv *priv, u32 mask,
>>                                                                       u32 val)
>>  {
>> -     struct mc13783 *mc13783 = priv->mc13783;
>> +     struct mc13xxx *mc13783 = priv->mc13xxx;
>>       int ret;
>>       u32 valread;
>>
>>       BUG_ON(val & ~mask);
>>
>> -     ret = mc13783_reg_read(mc13783, MC13783_REG_POWERMISC, &valread);
>> +     ret = mc13xxx_reg_read(mc13783, MC13783_REG_POWERMISC, &valread);
>>       if (ret)
>>               return ret;
>>
>> @@ -489,34 +272,36 @@ int mc13783_powermisc_rmw(struct
>> mc13783_regulator_priv *priv, u32 mask,
>
> Here git apply get an error...
> Please send a clean patch and then I will get it a try!
>
>>       valread = (valread & ~MC13783_REG_POWERMISC_PWGTSPI_M) |
>>                                               priv->powermisc_pwgt_state;
>>
>> -     return mc13783_reg_write(mc13783, MC13783_REG_POWERMISC, valread);
>> +     return mc13xxx_reg_write(mc13783, MC13783_REG_POWERMISC, valread);
>>  }
>>
>>  static int mc13783_gpo_regulator_enable(struct regulator_dev *rdev)
>>  {
>> -     struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
>> +     struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
>> +     struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
>>       int id = rdev_get_id(rdev);
>>       int ret;
>> -     u32 en_val = mc13783_regulators[id].enable_bit;
>> +     u32 en_val = mc13xxx_regulators[id].enable_bit;
>>
>>       dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
>>
>>       /* Power Gate enable value is 0 */
>> -     if (id == MC13783_REGU_PWGT1SPI ||
>> -         id == MC13783_REGU_PWGT2SPI)
>> +     if (id == MC13783_REG_PWGT1SPI ||
>> +         id == MC13783_REG_PWGT2SPI)
>>               en_val = 0;
>>
>> -     mc13783_lock(priv->mc13783);
>> -     ret = mc13783_powermisc_rmw(priv, mc13783_regulators[id].enable_bit,
>> +     mc13xxx_lock(priv->mc13xxx);
>> +     ret = mc13783_powermisc_rmw(priv, mc13xxx_regulators[id].enable_bit,
>>                                       en_val);
>> -     mc13783_unlock(priv->mc13783);
>> +     mc13xxx_unlock(priv->mc13xxx);
>>
>>       return ret;
>>  }
>>
>>  static int mc13783_gpo_regulator_disable(struct regulator_dev *rdev)
>>  {
>> -     struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
>> +     struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
>> +     struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
>>       int id = rdev_get_id(rdev);
>>       int ret;
>>       u32 dis_val = 0;
>> @@ -524,27 +309,28 @@ static int mc13783_gpo_regulator_disable(struct
>> regulator_dev *rdev)
>>       dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
>>
>>       /* Power Gate disable value is 1 */
>> -     if (id == MC13783_REGU_PWGT1SPI ||
>> -         id == MC13783_REGU_PWGT2SPI)
>> -             dis_val = mc13783_regulators[id].enable_bit;
>> +     if (id == MC13783_REG_PWGT1SPI ||
>> +         id == MC13783_REG_PWGT2SPI)
>> +             dis_val = mc13xxx_regulators[id].enable_bit;
>>
>> -     mc13783_lock(priv->mc13783);
>> -     ret = mc13783_powermisc_rmw(priv, mc13783_regulators[id].enable_bit,
>> +     mc13xxx_lock(priv->mc13xxx);
>> +     ret = mc13783_powermisc_rmw(priv, mc13xxx_regulators[id].enable_bit,
>>                                       dis_val);
>> -     mc13783_unlock(priv->mc13783);
>> +     mc13xxx_unlock(priv->mc13xxx);
>>
>>       return ret;
>>  }
>>
>>  static int mc13783_gpo_regulator_is_enabled(struct regulator_dev *rdev)
>>  {
>> -     struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev);
>> +     struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
>> +     struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
>>       int ret, id = rdev_get_id(rdev);
>>       unsigned int val;
>>
>> -     mc13783_lock(priv->mc13783);
>> -     ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val);
>> -     mc13783_unlock(priv->mc13783);
>> +     mc13xxx_lock(priv->mc13xxx);
>> +     ret = mc13xxx_reg_read(priv->mc13xxx, mc13xxx_regulators[id].reg, &val);
>> +     mc13xxx_unlock(priv->mc13xxx);
>>
>>       if (ret)
>>               return ret;
>> @@ -554,22 +340,22 @@ static int
>> mc13783_gpo_regulator_is_enabled(struct regulator_dev *rdev)
>>       val = (val & ~MC13783_REG_POWERMISC_PWGTSPI_M) |
>>             (priv->powermisc_pwgt_state ^ MC13783_REG_POWERMISC_PWGTSPI_M);
>>
>> -     return (val & mc13783_regulators[id].enable_bit) != 0;
>> +     return (val & mc13xxx_regulators[id].enable_bit) != 0;
>>  }
>>
>>  static struct regulator_ops mc13783_gpo_regulator_ops = {
>>       .enable = mc13783_gpo_regulator_enable,
>>       .disable = mc13783_gpo_regulator_disable,
>>       .is_enabled = mc13783_gpo_regulator_is_enabled,
>> -     .list_voltage = mc13783_regulator_list_voltage,
>> -     .set_voltage = mc13783_fixed_regulator_set_voltage,
>> -     .get_voltage = mc13783_fixed_regulator_get_voltage,
>> +     .list_voltage = mc13xxx_regulator_list_voltage,
>> +     .set_voltage = mc13xxx_fixed_regulator_set_voltage,
>> +     .get_voltage = mc13xxx_fixed_regulator_get_voltage,
>>  };
>>
>>  static int __devinit mc13783_regulator_probe(struct platform_device *pdev)
>>  {
>> -     struct mc13783_regulator_priv *priv;
>> -     struct mc13783 *mc13783 = dev_get_drvdata(pdev->dev.parent);
>> +     struct mc13xxx_regulator_priv *priv;
>> +     struct mc13xxx *mc13783 = dev_get_drvdata(pdev->dev.parent);
>>       struct mc13783_regulator_platform_data *pdata =
>>               dev_get_platdata(&pdev->dev);
>>       struct mc13783_regulator_init_data *init_data;
>> @@ -583,7 +369,8 @@ static int __devinit
>> mc13783_regulator_probe(struct platform_device *pdev)
>>       if (!priv)
>>               return -ENOMEM;
>>
>> -     priv->mc13783 = mc13783;
>> +     priv->mc13xxx_regulators = mc13783_regulators;
>> +     priv->mc13xxx = mc13783;
>>
>>       for (i = 0; i < pdata->num_regulators; i++) {
>>               init_data = &pdata->regulators[i];
>> @@ -613,7 +400,7 @@ err:
>>
>>  static int __devexit mc13783_regulator_remove(struct platform_device *pdev)
>>  {
>> -     struct mc13783_regulator_priv *priv = platform_get_drvdata(pdev);
>> +     struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev);
>>       struct mc13783_regulator_platform_data *pdata =
>>               dev_get_platdata(&pdev->dev);
>>       int i;
>> diff --git a/drivers/regulator/mc13xxx-regulator-core.c
>> b/drivers/regulator/mc13xxx-regulator-core.c
>> new file mode 100644
>> index 0000000..1499615
>> --- /dev/null
>> +++ b/drivers/regulator/mc13xxx-regulator-core.c
>> @@ -0,0 +1,241 @@
>> +/*
>> + * Regulator Driver for Freescale MC13xxx PMIC
>> + *
>> + * Copyright 2010 Yong Shen <yong.shen at linaro.org>
>> + *
>> + * Based on mc13783 regulator driver :
>> + * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer at pengutronix.de>
>> + * Copyright 2009 Alberto Panizzo <maramaopercheseimorto at gmail.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + * Regs infos taken from mc13xxx drivers from freescale and mc13xxx.pdf file
>> + * from freescale
>> + */
>> +
>> +#define DEBUG
>
> And debug enabled by default?
>
> I'll wait for version 2..
>
> Regards,
> Alberto!
>
> PS: ./scripts/get_maintainer.pl said to cc all these guys:
>
> Liam Girdwood <lrg at slimlogic.co.uk>
> Mark Brown <broonie at opensource.wolfsonmicro.com>
> Samuel Ortiz <sameo at linux.intel.com>
> Haojian Zhuang <haojian.zhuang at marvell.com>
> Linus Walleij <linus.walleij at stericsson.com>
> Alberto Panizzo <maramaopercheseimorto at gmail.com>
> "Uwe Kleine-König" <u.kleine-koenig at pengutronix.de>
> Axel Lin <axel.lin at gmail.com>
> Andrew Morton <akpm at linux-foundation.org>
> "Philippe Rétornaz" <philippe.retornaz at epfl.ch>
> linux-kernel at vger.kernel.org
>
> Please, use always this script to decide who have to be cc'ed by default
> sending patches.
>
>> +
>> +#include <linux/mfd/mc13xxx.h>
>> +#include <linux/regulator/mc13xxx.h>
>> +#include <linux/regulator/machine.h>
>> +#include <linux/regulator/driver.h>
>> +#include <linux/platform_device.h>
>> +#include <linux/kernel.h>
>> +#include <linux/slab.h>
>> +#include <linux/init.h>
>> +#include <linux/err.h>
>> +
>> +static int mc13xxx_regulator_enable(struct regulator_dev *rdev)
>> +{
>> +     struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
>> +     struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
>> +     int id = rdev_get_id(rdev);
>> +     int ret;
>> +
>> +     dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
>> +
>> +     mc13xxx_lock(priv->mc13xxx);
>> +     ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg,
>> +                     mc13xxx_regulators[id].enable_bit,
>> +                     mc13xxx_regulators[id].enable_bit);
>> +     mc13xxx_unlock(priv->mc13xxx);
>> +
>> +     return ret;
>> +}
>> +
>> +static int mc13xxx_regulator_disable(struct regulator_dev *rdev)
>> +{
>> +     struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
>> +     struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
>> +     int id = rdev_get_id(rdev);
>> +     int ret;
>> +
>> +     dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
>> +
>> +     mc13xxx_lock(priv->mc13xxx);
>> +     ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg,
>> +                     mc13xxx_regulators[id].enable_bit, 0);
>> +     mc13xxx_unlock(priv->mc13xxx);
>> +
>> +     return ret;
>> +}
>> +
>> +static int mc13xxx_regulator_is_enabled(struct regulator_dev *rdev)
>> +{
>> +     struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
>> +     struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
>> +     int ret, id = rdev_get_id(rdev);
>> +     unsigned int val;
>> +
>> +     mc13xxx_lock(priv->mc13xxx);
>> +     ret = mc13xxx_reg_read(priv->mc13xxx, mc13xxx_regulators[id].reg, &val);
>> +     mc13xxx_unlock(priv->mc13xxx);
>> +
>> +     if (ret)
>> +             return ret;
>> +
>> +     return (val & mc13xxx_regulators[id].enable_bit) != 0;
>> +}
>> +
>> +int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev,
>> +                                             unsigned selector)
>> +{
>> +     int id = rdev_get_id(rdev);
>> +     struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
>> +     struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
>> +
>> +     if (selector >= mc13xxx_regulators[id].desc.n_voltages)
>> +             return -EINVAL;
>> +
>> +     return mc13xxx_regulators[id].voltages[selector];
>> +}
>> +
>> +int mc13xxx_get_best_voltage_index(struct regulator_dev *rdev,
>> +                                             int min_uV, int max_uV)
>> +{
>> +     struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
>> +     struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
>> +     int reg_id = rdev_get_id(rdev);
>> +     int i;
>> +     int bestmatch;
>> +     int bestindex;
>> +
>> +     /*
>> +      * Locate the minimum voltage fitting the criteria on
>> +      * this regulator. The switchable voltages are not
>> +      * in strict falling order so we need to check them
>> +      * all for the best match.
>> +      */
>> +     bestmatch = INT_MAX;
>> +     bestindex = -1;
>> +     for (i = 0; i < mc13xxx_regulators[reg_id].desc.n_voltages; i++) {
>> +             if (mc13xxx_regulators[reg_id].voltages[i] >= min_uV &&
>> +                 mc13xxx_regulators[reg_id].voltages[i] < bestmatch) {
>> +                     bestmatch = mc13xxx_regulators[reg_id].voltages[i];
>> +                     bestindex = i;
>> +             }
>> +     }
>> +
>> +     if (bestindex < 0 || bestmatch > max_uV) {
>> +             dev_warn(&rdev->dev, "no possible value for %d<=x<=%d uV\n",
>> +                             min_uV, max_uV);
>> +             return -EINVAL;
>> +     }
>> +     return bestindex;
>> +}
>> +
>> +static int mc13xxx_regulator_set_voltage(struct regulator_dev *rdev,
>> +                                             int min_uV, int max_uV)
>> +{
>> +     struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
>> +     struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
>> +     int value, id = rdev_get_id(rdev);
>> +     int ret;
>> +
>> +     dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
>> +             __func__, id, min_uV, max_uV);
>> +
>> +     /* Find the best index */
>> +     value = mc13xxx_get_best_voltage_index(rdev, min_uV, max_uV);
>> +     dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value);
>> +     if (value < 0)
>> +             return value;
>> +
>> +     mc13xxx_lock(priv->mc13xxx);
>> +     ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg,
>> +                     mc13xxx_regulators[id].vsel_mask,
>> +                     value << mc13xxx_regulators[id].vsel_shift);
>> +     mc13xxx_unlock(priv->mc13xxx);
>> +
>> +     return ret;
>> +}
>> +
>> +static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev)
>> +{
>> +     struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
>> +     struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
>> +     int ret, id = rdev_get_id(rdev);
>> +     unsigned int val;
>> +
>> +     dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
>> +
>> +     mc13xxx_lock(priv->mc13xxx);
>> +     ret = mc13xxx_reg_read(priv->mc13xxx,
>> +                             mc13xxx_regulators[id].vsel_reg, &val);
>> +     mc13xxx_unlock(priv->mc13xxx);
>> +
>> +     if (ret)
>> +             return ret;
>> +
>> +     val = (val & mc13xxx_regulators[id].vsel_mask)
>> +             >> mc13xxx_regulators[id].vsel_shift;
>> +
>> +     dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val);
>> +
>> +     BUG_ON(val < 0 || val > mc13xxx_regulators[id].desc.n_voltages);
>> +
>> +     return mc13xxx_regulators[id].voltages[val];
>> +}
>> +
>> +struct regulator_ops mc13xxx_regulator_ops = {
>> +     .enable = mc13xxx_regulator_enable,
>> +     .disable = mc13xxx_regulator_disable,
>> +     .is_enabled = mc13xxx_regulator_is_enabled,
>> +     .list_voltage = mc13xxx_regulator_list_voltage,
>> +     .set_voltage = mc13xxx_regulator_set_voltage,
>> +     .get_voltage = mc13xxx_regulator_get_voltage,
>> +};
>> +
>> +int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev,
>> +                                             int min_uV, int max_uV)
>> +{
>> +     struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
>> +     struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
>> +     int id = rdev_get_id(rdev);
>> +
>> +     dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
>> +             __func__, id, min_uV, max_uV);
>> +
>> +     if (min_uV >= mc13xxx_regulators[id].voltages[0] &&
>> +         max_uV <= mc13xxx_regulators[id].voltages[0])
>> +             return 0;
>> +     else
>> +             return -EINVAL;
>> +}
>> +
>> +int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev)
>> +{
>> +     struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
>> +     struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators;
>> +     int id = rdev_get_id(rdev);
>> +
>> +     dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id);
>> +
>> +     return mc13xxx_regulators[id].voltages[0];
>> +}
>> +
>> +struct regulator_ops mc13xxx_fixed_regulator_ops = {
>> +     .enable = mc13xxx_regulator_enable,
>> +     .disable = mc13xxx_regulator_disable,
>> +     .is_enabled = mc13xxx_regulator_is_enabled,
>> +     .list_voltage = mc13xxx_regulator_list_voltage,
>> +     .set_voltage = mc13xxx_fixed_regulator_set_voltage,
>> +     .get_voltage = mc13xxx_fixed_regulator_get_voltage,
>> +};
>> +
>> +int mc13xxx_sw_regulator(struct regulator_dev *rdev)
>> +{
>> +     return 0;
>> +}
>> +
>> +int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev)
>> +{
>> +     return 1;
>> +}
>> +
>> +MODULE_LICENSE("GPL v2");
>> +MODULE_AUTHOR("Yong Shen <yong.shen at linaro.org>");
>> +MODULE_DESCRIPTION("Regulator Driver for Freescale MC13xxx PMIC");
>> +MODULE_ALIAS("platform:mc13xxx-regulator-core");
>> diff --git a/include/linux/mfd/mc13783.h b/include/linux/mfd/mc13783.h
>> index b4c741e..7d0f3d6 100644
>> --- a/include/linux/mfd/mc13783.h
>> +++ b/include/linux/mfd/mc13783.h
>> @@ -1,4 +1,5 @@
>>  /*
>> + * Copyright 2010 Yong Shen <yong.shen at linaro.org>
>>   * Copyright 2009-2010 Pengutronix
>>   * Uwe Kleine-Koenig <u.kleine-koenig at pengutronix.de>
>>   *
>> @@ -122,39 +123,39 @@ int mc13783_adc_do_conversion(struct mc13783
>> *mc13783, unsigned int mode,
>>               unsigned int channel, unsigned int *sample);
>>
>>
>> -#define      MC13783_SW_SW1A         0
>> -#define      MC13783_SW_SW1B         1
>> -#define      MC13783_SW_SW2A         2
>> -#define      MC13783_SW_SW2B         3
>> -#define      MC13783_SW_SW3          4
>> -#define      MC13783_SW_PLL          5
>> -#define      MC13783_REGU_VAUDIO     6
>> -#define      MC13783_REGU_VIOHI      7
>> -#define      MC13783_REGU_VIOLO      8
>> -#define      MC13783_REGU_VDIG       9
>> -#define      MC13783_REGU_VGEN       10
>> -#define      MC13783_REGU_VRFDIG     11
>> -#define      MC13783_REGU_VRFREF     12
>> -#define      MC13783_REGU_VRFCP      13
>> -#define      MC13783_REGU_VSIM       14
>> -#define      MC13783_REGU_VESIM      15
>> -#define      MC13783_REGU_VCAM       16
>> -#define      MC13783_REGU_VRFBG      17
>> -#define      MC13783_REGU_VVIB       18
>> -#define      MC13783_REGU_VRF1       19
>> -#define      MC13783_REGU_VRF2       20
>> -#define      MC13783_REGU_VMMC1      21
>> -#define      MC13783_REGU_VMMC2      22
>> -#define      MC13783_REGU_GPO1       23
>> -#define      MC13783_REGU_GPO2       24
>> -#define      MC13783_REGU_GPO3       25
>> -#define      MC13783_REGU_GPO4       26
>> -#define      MC13783_REGU_V1         27
>> -#define      MC13783_REGU_V2         28
>> -#define      MC13783_REGU_V3         29
>> -#define      MC13783_REGU_V4         30
>> -#define      MC13783_REGU_PWGT1SPI   31
>> -#define      MC13783_REGU_PWGT2SPI   32
>> +#define      MC13783_REG_SW1A                0
>> +#define      MC13783_REG_SW1B                1
>> +#define      MC13783_REG_SW2A                2
>> +#define      MC13783_REG_SW2B                3
>> +#define      MC13783_REG_SW3         4
>> +#define      MC13783_REG_PLL         5
>> +#define      MC13783_REG_VAUDIO      6
>> +#define      MC13783_REG_VIOHI       7
>> +#define      MC13783_REG_VIOLO       8
>> +#define      MC13783_REG_VDIG        9
>> +#define      MC13783_REG_VGEN        10
>> +#define      MC13783_REG_VRFDIG      11
>> +#define      MC13783_REG_VRFREF      12
>> +#define      MC13783_REG_VRFCP       13
>> +#define      MC13783_REG_VSIM        14
>> +#define      MC13783_REG_VESIM       15
>> +#define      MC13783_REG_VCAM        16
>> +#define      MC13783_REG_VRFBG       17
>> +#define      MC13783_REG_VVIB        18
>> +#define      MC13783_REG_VRF1        19
>> +#define      MC13783_REG_VRF2        20
>> +#define      MC13783_REG_VMMC1       21
>> +#define      MC13783_REG_VMMC2       22
>> +#define      MC13783_REG_GPO1        23
>> +#define      MC13783_REG_GPO2        24
>> +#define      MC13783_REG_GPO3        25
>> +#define      MC13783_REG_GPO4        26
>> +#define      MC13783_REG_V1          27
>> +#define      MC13783_REG_V2          28
>> +#define      MC13783_REG_V3          29
>> +#define      MC13783_REG_V4          30
>> +#define      MC13783_REG_PWGT1SPI    31
>> +#define      MC13783_REG_PWGT2SPI    32
>>
>>  #define MC13783_IRQ_ADCDONE  MC13XXX_IRQ_ADCDONE
>>  #define MC13783_IRQ_ADCBISDONE       MC13XXX_IRQ_ADCBISDONE
>> diff --git a/include/linux/regulator/mc13xxx.h
>> b/include/linux/regulator/mc13xxx.h
>> new file mode 100644
>> index 0000000..a60c9be
>> --- /dev/null
>> +++ b/include/linux/regulator/mc13xxx.h
>> @@ -0,0 +1,101 @@
>> +/*
>> + * mc13xxx.h - regulators for the Freescale mc13xxx PMIC
>> + *
>> + *  Copyright (C) 2010 Yong Shen <yong.shen at linaro.org>
>> + *
>> + * 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_REGULATOR_MC13XXX_H
>> +#define __LINUX_REGULATOR_MC13XXX_H
>> +
>> +#include <linux/regulator/driver.h>
>> +
>> +struct mc13xxx_regulator {
>> +     struct regulator_desc desc;
>> +     int reg;
>> +     int enable_bit;
>> +     int vsel_reg;
>> +     int vsel_shift;
>> +     int vsel_mask;
>> +     int hi_bit;
>> +     int const *voltages;
>> +};
>> +
>> +struct mc13xxx_regulator_priv {
>> +     struct mc13xxx *mc13xxx;
>> +     u32 powermisc_pwgt_state;
>> +     struct mc13xxx_regulator *mc13xxx_regulators;
>> +     struct regulator_dev *regulators[];
>> +};
>> +
>> +extern int mc13xxx_sw_regulator(struct regulator_dev *rdev);
>> +extern int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev);
>> +extern int mc13xxx_get_best_voltage_index(struct regulator_dev *rdev,
>> +                                             int min_uV, int max_uV);
>> +extern int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev,
>> +                                             unsigned selector);
>> +extern int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev,
>> +                                             int min_uV, int max_uV);
>> +extern int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev);
>> +
>> +extern struct regulator_ops mc13xxx_regulator_ops;
>> +extern struct regulator_ops mc13xxx_fixed_regulator_ops;
>> +
>> +#define MC13xxx_DEFINE(prefix, _name, _reg, _vsel_reg, _voltages, _ops)      \
>> +     [prefix ## _name] = {                           \
>> +             .desc = {                                               \
>> +                     .name = #prefix "_" #_name,                     \
>> +                     .n_voltages = ARRAY_SIZE(_voltages),            \
>> +                     .ops = &_ops,                   \
>> +                     .type = REGULATOR_VOLTAGE,                      \
>> +                     .id = prefix ## _name,          \
>> +                     .owner = THIS_MODULE,                           \
>> +             },                                                      \
>> +             .reg = prefix ## _reg,                          \
>> +             .enable_bit = prefix ## _reg ## _ ## _name ## EN,       \
>> +             .vsel_reg = prefix ## _vsel_reg,                        \
>> +             .vsel_shift = prefix ## _vsel_reg ## _ ## _name ## VSEL,\
>> +             .vsel_mask = prefix ## _vsel_reg ## _ ## _name ## VSEL_M,\
>> +             .voltages =  _voltages,                                 \
>> +     }
>> +
>> +#define MC13xxx_FIXED_DEFINE(prefix, _name, _reg, _voltages, _ops)   \
>> +     [prefix ## _name] = {                           \
>> +             .desc = {                                               \
>> +                     .name = #prefix "_" #_name,                     \
>> +                     .n_voltages = ARRAY_SIZE(_voltages),            \
>> +                     .ops = &_ops,           \
>> +                     .type = REGULATOR_VOLTAGE,                      \
>> +                     .id = prefix ## _name,          \
>> +                     .owner = THIS_MODULE,                           \
>> +             },                                                      \
>> +             .reg = prefix ## _reg,                          \
>> +             .enable_bit = prefix ## _reg ## _ ## _name ## EN,       \
>> +             .voltages =  _voltages,                                 \
>> +     }
>> +
>> +#define MC13xxx_GPO_DEFINE(prefix, _name, _reg,  _voltages, _ops)    \
>> +     [prefix ## _name] = {                           \
>> +             .desc = {                                               \
>> +                     .name = #prefix "_" #_name,                     \
>> +                     .n_voltages = ARRAY_SIZE(_voltages),            \
>> +                     .ops = &_ops,           \
>> +                     .type = REGULATOR_VOLTAGE,                      \
>> +                     .id = prefix ## _name,          \
>> +                     .owner = THIS_MODULE,                           \
>> +             },                                                      \
>> +             .reg = prefix ## _reg,                          \
>> +             .enable_bit = prefix ## _reg ## _ ## _name ## EN,       \
>> +             .voltages =  _voltages,                                 \
>> +     }
>> +
>> +#define MC13xxx_DEFINE_SW(_name, _reg, _vsel_reg, _voltages, ops)    \
>> +     MC13xxx_DEFINE(SW, _name, _reg, _vsel_reg, _voltages, ops)
>> +#define MC13xxx_DEFINE_REGU(_name, _reg, _vsel_reg, _voltages, ops)  \
>> +     MC13xxx_DEFINE(REGU, _name, _reg, _vsel_reg, _voltages, ops)
>> +
>> +#endif
>
>



More information about the linux-arm-kernel mailing list