summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/mfd/ricoh583.c16
-rw-r--r--drivers/regulator/ricoh583-regulator.c149
-rw-r--r--include/linux/regulator/ricoh583-regulator.h7
3 files changed, 136 insertions, 36 deletions
diff --git a/drivers/mfd/ricoh583.c b/drivers/mfd/ricoh583.c
index 794f6bf48dea..fa11254806b1 100644
--- a/drivers/mfd/ricoh583.c
+++ b/drivers/mfd/ricoh583.c
@@ -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) {
diff --git a/drivers/regulator/ricoh583-regulator.c b/drivers/regulator/ricoh583-regulator.c
index 4ea861969b89..33f13252cfa7 100644
--- a/drivers/regulator/ricoh583-regulator.c
+++ b/drivers/regulator/ricoh583-regulator.c
@@ -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;
diff --git a/include/linux/regulator/ricoh583-regulator.h b/include/linux/regulator/ricoh583-regulator.h
index d932f7094459..71990b86a2b6 100644
--- a/include/linux/regulator/ricoh583-regulator.h
+++ b/include/linux/regulator/ricoh583-regulator.h
@@ -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