regulator: ricoh583: Support for external PWRREQ control
Laxman Dewangan [Sun, 30 Oct 2011 18:07:41 +0000 (23:07 +0530)]
Supporting the different rails control through the external
control signal PWRREQ1 and PWRREQ2.

Reviewed-on: http://git-master/r/61898
(cherry picked from commit fc07ccae30b61a92fa0b77ee6b2b7c8d43176bbe)

Change-Id: Id6322ef251e4b87673d3a647efb1f0d74b8e0815
Reviewed-on: http://git-master/r/62912
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>

Rebase-Id: R687c186e89635a5bd4e3f399709cdf3520936a3f

drivers/mfd/ricoh583.c
drivers/regulator/ricoh583-regulator.c
include/linux/regulator/ricoh583-regulator.h

index 794f6bf..fa11254 100644 (file)
@@ -499,10 +499,12 @@ static void __devinit ricoh583_gpio_init(struct ricoh583 *ricoh583,
                        dev_err(ricoh583->dev, "Gpio %d init "
                                "dir configuration failed: %d\n", i, ret);
 
-               ret = ricoh583_clr_bits(ricoh583->dev, RICOH583_GPIO_PGSEL, 1 << i);
+               ret = ricoh583_clr_bits(ricoh583->dev, RICOH583_GPIO_PGSEL,
+                                       1 << i);
                if (ret < 0)
-                       dev_err(ricoh583->dev, "%s(): The error in writing register "
-                       "0x%02x\n", __func__, RICOH583_GPIO_PGSEL);
+                       dev_err(ricoh583->dev, "%s(): The error in writing "
+                               "register 0x%02x\n", __func__,
+                               RICOH583_GPIO_PGSEL);
        }
 
        ricoh583->gpio.owner            = THIS_MODULE;
@@ -941,6 +943,14 @@ static int ricoh583_i2c_probe(struct i2c_client *i2c,
 
        mutex_init(&ricoh583->io_lock);
 
+       /*  Clear ONOFFSEL register */
+       ret = __ricoh583_write(ricoh583->client, 0x10, 0x0);
+       if (ret < 0) {
+               dev_err(ricoh583->dev, "Error in writing reg 0x10 error: "
+                               "%d\n", ret);
+               goto err_irq_init;
+       }
+
        if (i2c->irq) {
                ret = ricoh583_irq_init(ricoh583, i2c->irq, pdata->irq_base);
                if (ret) {
index 4ea8619..33f1325 100644 (file)
@@ -36,6 +36,8 @@
 #include <linux/mfd/ricoh583.h>
 #include <linux/regulator/ricoh583-regulator.h>
 
+
+#define RICOH_ONOFFSEL_REG     0x10
 struct ricoh583_regulator {
        int             id;
        /* Regulator register address.*/
@@ -47,6 +49,8 @@ struct ricoh583_regulator {
        u8              vout_mask;
        u8              vout_reg_cache;
        u8              deepsleep_reg;
+       u8              sleepseq_reg;
+       u8              sleepseq_shift;
 
        /* chip constraints on regulator behavior */
        int                     min_uV;
@@ -64,6 +68,7 @@ struct ricoh583_regulator {
        struct device           *dev;
 };
 
+
 static inline struct device *to_ricoh583_dev(struct regulator_dev *rdev)
 {
        return rdev_get_dev(rdev)->parent->parent;
@@ -145,6 +150,73 @@ static int __ricoh583_set_ds_voltage(struct device *parent,
        return ret;
 }
 
+static int __ricoh583_set_ext_pwrreq1_control(struct device *parent,
+               struct ricoh583_regulator *ri, unsigned long flags, int slots)
+{
+       int ret;
+       uint8_t sleepseq_val;
+       u8 en_bit;
+       u8 slot_bit;
+
+       if (ri->id == RICOH583_ID_DC0) {
+               if (flags & EXT_PWRREQ1_CONTROL) {
+                       dev_err(ri->dev, "PWRREQ1 is invalid control for "
+                               "rail %d\n", ri->id);
+                       return -EINVAL;
+               }
+               return 0;
+       }
+
+       en_bit = ri->sleepseq_shift;
+       slot_bit = en_bit + 1;
+       ret = ricoh583_read(parent, ri->sleepseq_reg, &sleepseq_val);
+       if (ret < 0) {
+               dev_err(ri->dev, "Error in reading reg 0x%x\n",
+                               ri->sleepseq_reg);
+               return ret;
+       }
+
+       if (flags & EXT_PWRREQ1_CONTROL) {
+               sleepseq_val |= (1 << en_bit);
+               sleepseq_val &= ~(0x7 << slot_bit);
+               sleepseq_val |= ((slots & 0x7) << slot_bit);
+               ret = ricoh583_set_bits(parent, RICOH_ONOFFSEL_REG, (1 << 1));
+               if (ret < 0) {
+                       dev_err(ri->dev, "Error in updating the ONOFFSEL 0x10 register\n");
+                       return ret;
+               }
+       } else {
+               sleepseq_val &= ~(0xF << en_bit);
+       }
+       ret = ricoh583_write(parent, ri->sleepseq_reg, sleepseq_val);
+       if (ret < 0)
+               dev_err(ri->dev, "Error in writing reg 0x%x\n",
+                               ri->sleepseq_reg);
+       return ret;
+}
+
+static int __ricoh583_set_ext_pwrreq2_control(struct device *parent,
+               struct ricoh583_regulator *ri, unsigned long flags)
+{
+       int ret;
+
+       if (ri->id != RICOH583_ID_DC0) {
+               if (flags & EXT_PWRREQ2_CONTROL) {
+                       dev_err(ri->dev, "PWRREQ2 is invalid control for "
+                               "rail %d\n", ri->id);
+                       return -EINVAL;
+               }
+               return 0;
+       }
+       if (flags & EXT_PWRREQ2_CONTROL)
+               ret = ricoh583_set_bits(parent, RICOH_ONOFFSEL_REG, (1 << 2));
+       else
+               ret = ricoh583_clr_bits(parent, RICOH_ONOFFSEL_REG, (1 << 2));
+       if (ret < 0)
+               dev_err(ri->dev, "Error in updating the ONOFFSEL 0x10 register\n");
+       return ret;
+}
+
 static int __ricoh583_set_voltage(struct device *parent,
                struct ricoh583_regulator *ri, int min_uV, int max_uV)
 {
@@ -159,7 +231,8 @@ static int __ricoh583_set_voltage(struct device *parent,
        if (vsel > ri->nsteps)
                return -EDOM;
 
-       vout_val = (ri->vout_reg_cache & ~ri->vout_mask) | (vsel & ri->vout_mask);
+       vout_val = (ri->vout_reg_cache & ~ri->vout_mask) |
+                               (vsel & ri->vout_mask);
        ret = ricoh583_write(parent, ri->vout_reg, vout_val);
        if (ret < 0)
                dev_err(ri->dev, "Error in writing the Voltage register\n");
@@ -187,7 +260,6 @@ static int ricoh583_get_voltage(struct regulator_dev *rdev)
        return ri->min_uV + vsel * ri->step_uV;
 }
 
-
 static struct regulator_ops ricoh583_ops = {
        .list_voltage   = ricoh583_list_voltage,
        .set_voltage    = ricoh583_set_voltage,
@@ -198,10 +270,9 @@ static struct regulator_ops ricoh583_ops = {
        .enable_time    = ricoh583_regulator_enable_time,
 };
 
-
 #define RICOH583_REG(_id, _en_reg, _en_bit, _disc_reg, _disc_bit, _vout_reg, \
-               _vout_mask, _ds_reg, _min_mv, _max_mv, _step_uV, _nsteps, \
-               _ops, _delay)                           \
+               _vout_mask, _ds_reg, _slpseq_reg, _slpseq_shift, _min_mv, \
+               _max_mv, _step_uV, _nsteps, _ops, _delay)               \
 {                                                              \
        .reg_en_reg     = _en_reg,                              \
        .en_bit         = _en_bit,                              \
@@ -210,6 +281,8 @@ static struct regulator_ops ricoh583_ops = {
        .vout_reg       = _vout_reg,                            \
        .vout_mask      = _vout_mask,                           \
        .deepsleep_reg  = _ds_reg,                              \
+       .sleepseq_reg   = _slpseq_reg,                          \
+       .sleepseq_shift = _slpseq_shift,                        \
        .min_uV         = _min_mv * 1000,                       \
        .max_uV         = _max_mv * 1000,                       \
        .step_uV        = _step_uV,                             \
@@ -227,34 +300,34 @@ static struct regulator_ops ricoh583_ops = {
 }
 
 static struct ricoh583_regulator ricoh583_regulator[] = {
-       RICOH583_REG(DC0, 0x30, 0, 0x30, 1, 0x31, 0x7F, 0x60, 700, 1500,
-                       12500, 0x41, ricoh583_ops, 500),
-       RICOH583_REG(DC1, 0x34, 0, 0x34, 1, 0x35, 0x7F, 0x61, 700, 1500,
-                       12500, 0x41, ricoh583_ops, 500),
-       RICOH583_REG(DC2, 0x38, 0, 0x38, 1, 0x39, 0x7F, 0x62, 900, 2400,
-                       12500, 0x79, ricoh583_ops, 500),
-       RICOH583_REG(DC3, 0x3C, 0, 0x3C, 1, 0x3D, 0x7F, 0x63, 900, 2400,
-                       12500, 0x79, ricoh583_ops, 500),
-       RICOH583_REG(LDO0, 0x51, 0, 0x53, 0, 0x54, 0x7F, 0x64, 900, 3400,
-                       25000, 0x65, ricoh583_ops, 500),
-       RICOH583_REG(LDO1, 0x51, 1, 0x53, 1, 0x55, 0x7F, 0x65, 900, 3400,
-                       25000, 0x65, ricoh583_ops, 500),
-       RICOH583_REG(LDO2, 0x51, 2, 0x53, 2, 0x56, 0x7F, 0x66, 900, 3400,
-                       25000, 0x65, ricoh583_ops, 500),
-       RICOH583_REG(LDO3, 0x51, 3, 0x53, 3, 0x57, 0x7F, 0x67, 900, 3400,
-                       25000, 0x65, ricoh583_ops, 500),
-       RICOH583_REG(LDO4, 0x51, 4, 0x53, 4, 0x58, 0x3F, 0x68, 750, 1500,
-                       12500, 0x3D, ricoh583_ops, 500),
-       RICOH583_REG(LDO5, 0x51, 5, 0x53, 5, 0x59, 0x7F, 0x69, 900, 3400,
-                       25000, 0x65, ricoh583_ops, 500),
-       RICOH583_REG(LDO6, 0x51, 6, 0x53, 6, 0x5A, 0x7F, 0x6A, 900, 3400,
-                       25000, 0x65, ricoh583_ops, 500),
-       RICOH583_REG(LDO7, 0x51, 7, 0x53, 7, 0x5B, 0x7F, 0x6B, 900, 3400,
-                       25000, 0x65, ricoh583_ops, 500),
-       RICOH583_REG(LDO8, 0x50, 0, 0x52, 0, 0x5C, 0x7F, 0x6C, 900, 3400,
-                       25000, 0x65, ricoh583_ops, 500),
-       RICOH583_REG(LDO9, 0x50, 1, 0x52, 1, 0x5D, 0x7F, 0x6D, 900, 3400,
-                       25000, 0x65, ricoh583_ops, 500),
+       RICOH583_REG(DC0, 0x30, 0, 0x30, 1, 0x31, 0x7F, 0x60, 0x21, 0,
+                       700, 1500, 12500, 0x41, ricoh583_ops, 500),
+       RICOH583_REG(DC1, 0x34, 0, 0x34, 1, 0x35, 0x7F, 0x61, 0x21, 4,
+                       700, 1500, 12500, 0x41, ricoh583_ops, 500),
+       RICOH583_REG(DC2, 0x38, 0, 0x38, 1, 0x39, 0x7F, 0x62, 0x22, 0,
+                       900, 2400, 12500, 0x79, ricoh583_ops, 500),
+       RICOH583_REG(DC3, 0x3C, 0, 0x3C, 1, 0x3D, 0x7F, 0x63, 0x22, 4,
+                       900, 2400, 12500, 0x79, ricoh583_ops, 500),
+       RICOH583_REG(LDO0, 0x51, 0, 0x53, 0, 0x54, 0x7F, 0x64, 0x23, 0,
+                       900, 3400, 25000, 0x65, ricoh583_ops, 500),
+       RICOH583_REG(LDO1, 0x51, 1, 0x53, 1, 0x55, 0x7F, 0x65, 0x23, 4,
+                       900, 3400, 25000, 0x65, ricoh583_ops, 500),
+       RICOH583_REG(LDO2, 0x51, 2, 0x53, 2, 0x56, 0x7F, 0x66, 0x24, 0,
+                       900, 3400, 25000, 0x65, ricoh583_ops, 500),
+       RICOH583_REG(LDO3, 0x51, 3, 0x53, 3, 0x57, 0x7F, 0x67, 0x24, 4,
+                       900, 3400, 25000, 0x65, ricoh583_ops, 500),
+       RICOH583_REG(LDO4, 0x51, 4, 0x53, 4, 0x58, 0x3F, 0x68, 0x25, 0,
+                       750, 1500, 12500, 0x3D, ricoh583_ops, 500),
+       RICOH583_REG(LDO5, 0x51, 5, 0x53, 5, 0x59, 0x7F, 0x69, 0x25, 4,
+                       900, 3400, 25000, 0x65, ricoh583_ops, 500),
+       RICOH583_REG(LDO6, 0x51, 6, 0x53, 6, 0x5A, 0x7F, 0x6A, 0x26, 0,
+                       900, 3400, 25000, 0x65, ricoh583_ops, 500),
+       RICOH583_REG(LDO7, 0x51, 7, 0x53, 7, 0x5B, 0x7F, 0x6B, 0x26, 4,
+                       900, 3400, 25000, 0x65, ricoh583_ops, 500),
+       RICOH583_REG(LDO8, 0x50, 0, 0x52, 0, 0x5C, 0x7F, 0x6C, 0x27, 0,
+                       900, 3400, 25000, 0x65, ricoh583_ops, 500),
+       RICOH583_REG(LDO9, 0x50, 1, 0x52, 1, 0x5D, 0x7F, 0x6D, 0x27, 4,
+                       900, 3400, 25000, 0x65, ricoh583_ops, 500),
 };
 static inline struct ricoh583_regulator *find_regulator_info(int id)
 {
@@ -275,6 +348,16 @@ static int ricoh583_regulator_preinit(struct device *parent,
 {
        int ret = 0;
 
+       ret = __ricoh583_set_ext_pwrreq1_control(parent, ri,
+                       ricoh583_pdata->flags, ricoh583_pdata->deepsleep_slots);
+       if (ret < 0)
+               return ret;
+
+       ret = __ricoh583_set_ext_pwrreq2_control(parent, ri,
+                       ricoh583_pdata->flags);
+       if (ret < 0)
+               return ret;
+
        if (!ricoh583_pdata->init_apply)
                return 0;
 
index d932f70..71990b8 100644 (file)
@@ -49,12 +49,19 @@ enum regulator_id {
        RICOH583_ID_LDO9,
 };
 
+enum ext_control {
+       EXT_PWRREQ1_CONTROL = 0x1,
+       EXT_PWRREQ2_CONTROL = 0x2,
+};
+
 struct ricoh583_regulator_platform_data {
                struct regulator_init_data regulator;
                int init_uV;
                unsigned init_enable:1;
                unsigned init_apply:1;
                int deepsleep_uV;
+               int deepsleep_slots;
+               unsigned long flags;
 };
 
 #endif