summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2011-11-07 11:26:26 +0530
committerLokesh Pathak <lpathak@nvidia.com>2011-11-09 07:32:51 -0800
commit7c2817b42785302c3d9a779c817f70163fabee71 (patch)
tree72898c643c27a3fb66c341f15ee1dff23d27999a
parenta49db43178ed94f0f7081b18ba89bbeb7e6188b6 (diff)
mfd: ricoh583: Move sleep configuration to core driver
Moving the sleep sequence configuration for the pmu from regulator driver to core driver so that other than power rails, gpio can also use these APIs. Reviewed-on: http://git-master/r/62652 (cherry picked from commit eeb7d4a5fabe803e9c76900ff1aa1d71e8111c75) Change-Id: I2bcb751d25e59939e2c7119dc131df11d10fdfa9 Reviewed-on: http://git-master/r/62901 Tested-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
-rw-r--r--drivers/mfd/ricoh583.c150
-rw-r--r--drivers/regulator/ricoh583-regulator.c123
-rw-r--r--include/linux/mfd/ricoh583.h34
-rw-r--r--include/linux/regulator/ricoh583-regulator.h6
4 files changed, 204 insertions, 109 deletions
diff --git a/drivers/mfd/ricoh583.c b/drivers/mfd/ricoh583.c
index fa11254806b1..52aafe65ee57 100644
--- a/drivers/mfd/ricoh583.c
+++ b/drivers/mfd/ricoh583.c
@@ -35,6 +35,8 @@
#include <linux/mfd/core.h>
#include <linux/mfd/ricoh583.h>
+#define RICOH_ONOFFSEL_REG 0x10
+
/* Interrupt enable register */
#define RICOH583_INT_EN_SYS1 0x19
#define RICOH583_INT_EN_SYS2 0x1D
@@ -97,6 +99,11 @@ struct ricoh583_irq_data {
int grp_index;
};
+struct deepsleep_control_data {
+ u8 reg_add;
+ u8 ds_pos_bit;
+};
+
#define RICOH583_IRQ(_int_type, _master_bit, _grp_index, _int_bit, _mask_ind) \
{ \
.int_type = _int_type, \
@@ -153,8 +160,37 @@ static const struct ricoh583_irq_data ricoh583_irqs[] = {
[RICOH583_NR_IRQS] = RICOH583_IRQ(GPIO_INT, 4, 8, 8, 7),
};
+#define DEEPSLEEP_INIT(_id, _reg, _pos) \
+ [RICOH583_DS_##_id] = {.reg_add = _reg, .ds_pos_bit = _pos}
+
+static struct deepsleep_control_data deepsleep_data[] = {
+ DEEPSLEEP_INIT(DC1, 0x21, 4),
+ DEEPSLEEP_INIT(DC2, 0x22, 0),
+ DEEPSLEEP_INIT(DC3, 0x22, 4),
+ DEEPSLEEP_INIT(LDO0, 0x23, 0),
+ DEEPSLEEP_INIT(LDO1, 0x23, 4),
+ DEEPSLEEP_INIT(LDO2, 0x24, 0),
+ DEEPSLEEP_INIT(LDO3, 0x24, 4),
+ DEEPSLEEP_INIT(LDO4, 0x25, 0),
+ DEEPSLEEP_INIT(LDO5, 0x25, 4),
+ DEEPSLEEP_INIT(LDO6, 0x26, 0),
+ DEEPSLEEP_INIT(LDO7, 0x26, 4),
+ DEEPSLEEP_INIT(LDO8, 0x27, 0),
+ DEEPSLEEP_INIT(LDO9, 0x27, 4),
+ DEEPSLEEP_INIT(PSO0, 0x28, 0),
+ DEEPSLEEP_INIT(PSO1, 0x28, 4),
+ DEEPSLEEP_INIT(PSO2, 0x29, 0),
+ DEEPSLEEP_INIT(PSO3, 0x29, 4),
+ DEEPSLEEP_INIT(PSO4, 0x2A, 0),
+ DEEPSLEEP_INIT(PSO5, 0x2A, 4),
+ DEEPSLEEP_INIT(PSO6, 0x2B, 0),
+ DEEPSLEEP_INIT(PSO7, 0x2B, 4),
+};
+
#define MAX_INTERRUPT_MASKS 8
#define MAX_MAIN_INTERRUPT 5
+#define EXT_PWR_REQ \
+ (RICOH583_EXT_PWRREQ1_CONTROL | RICOH583_EXT_PWRREQ2_CONTROL)
struct ricoh583 {
struct device *dev;
@@ -363,6 +399,112 @@ out:
}
EXPORT_SYMBOL_GPL(ricoh583_update);
+static int __ricoh583_set_ext_pwrreq1_control(struct device *dev,
+ enum ricoh583_deepsleep_control_id id,
+ enum ricoh583_ext_pwrreq_control ext_pwr, int slots)
+{
+ int ret;
+ uint8_t sleepseq_val;
+ u8 en_bit;
+ u8 slot_bit;
+
+ if (!(ext_pwr & RICOH583_EXT_PWRREQ1_CONTROL))
+ return 0;
+
+ if (id == RICOH583_DS_DC0) {
+ dev_err(dev, "PWRREQ1 is invalid control for rail %d\n", id);
+ return -EINVAL;
+ }
+
+ en_bit = deepsleep_data[id].ds_pos_bit;
+ slot_bit = en_bit + 1;
+ ret = ricoh583_read(dev, deepsleep_data[id].reg_add, &sleepseq_val);
+ if (ret < 0) {
+ dev_err(dev, "Error in reading reg 0x%x\n",
+ deepsleep_data[id].reg_add);
+ return ret;
+ }
+
+ sleepseq_val &= ~(0xF << en_bit);
+ sleepseq_val |= (1 << en_bit);
+ sleepseq_val |= ((slots & 0x7) << slot_bit);
+ ret = ricoh583_set_bits(dev, RICOH_ONOFFSEL_REG, (1 << 1));
+ if (ret < 0) {
+ dev_err(dev, "Error in updating the 0x%02x register\n",
+ RICOH_ONOFFSEL_REG);
+ return ret;
+ }
+
+ ret = ricoh583_write(dev, deepsleep_data[id].reg_add, sleepseq_val);
+ if (ret < 0)
+ dev_err(dev, "Error in writing reg 0x%x\n",
+ deepsleep_data[id].reg_add);
+ return ret;
+}
+
+static int __ricoh583_set_ext_pwrreq2_control(struct device *dev,
+ enum ricoh583_deepsleep_control_id id,
+ enum ricoh583_ext_pwrreq_control ext_pwr)
+{
+ int ret;
+
+ if (!(ext_pwr & RICOH583_EXT_PWRREQ2_CONTROL))
+ return 0;
+
+ if (id != RICOH583_DS_DC0) {
+ dev_err(dev, "PWRREQ2 is invalid control for rail %d\n", id);
+ return -EINVAL;
+ }
+
+ ret = ricoh583_set_bits(dev, RICOH_ONOFFSEL_REG, (1 << 2));
+ if (ret < 0)
+ dev_err(dev, "Error in updating the ONOFFSEL 0x10 register\n");
+ return ret;
+}
+
+int ricoh583_ext_power_req_config(struct device *dev,
+ enum ricoh583_deepsleep_control_id id,
+ enum ricoh583_ext_pwrreq_control ext_pwr_req,
+ int deepsleep_slot_nr)
+{
+ if ((ext_pwr_req & EXT_PWR_REQ) == EXT_PWR_REQ)
+ return -EINVAL;
+
+ if (ext_pwr_req & RICOH583_EXT_PWRREQ1_CONTROL)
+ return __ricoh583_set_ext_pwrreq1_control(dev, id,
+ ext_pwr_req, deepsleep_slot_nr);
+
+ if (ext_pwr_req & RICOH583_EXT_PWRREQ2_CONTROL)
+ return __ricoh583_set_ext_pwrreq2_control(dev,
+ id, ext_pwr_req);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(ricoh583_ext_power_req_config);
+
+static int __devinit ricoh583_ext_power_init(struct ricoh583 *ricoh583,
+ struct ricoh583_platform_data *pdata)
+{
+ int ret;
+ int i;
+
+ /* Clear ONOFFSEL register */
+ mutex_lock(&ricoh583->io_lock);
+ ret = __ricoh583_write(ricoh583->client, RICOH_ONOFFSEL_REG, 0x0);
+ if (ret < 0)
+ dev_err(ricoh583->dev, "Error in writing reg %d error: "
+ "%d\n", RICOH_ONOFFSEL_REG, ret);
+
+ /* Clear sleepseq register */
+ for (i = 0x21; i < 0x2B; ++i) {
+ ret = __ricoh583_write(ricoh583->client, i, 0x0);
+ if (ret < 0)
+ dev_err(ricoh583->dev, "Error in writing reg 0x%02x "
+ "error: %d\n", i, ret);
+ }
+ mutex_unlock(&ricoh583->io_lock);
+ return 0;
+}
+
static struct i2c_client *ricoh583_i2c_client;
int ricoh583_power_off(void)
{
@@ -943,13 +1085,9 @@ 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);
+ ret = ricoh583_ext_power_init(ricoh583, pdata);
+ if (ret < 0)
goto err_irq_init;
- }
if (i2c->irq) {
ret = ricoh583_irq_init(ricoh583, i2c->irq, pdata->irq_base);
diff --git a/drivers/regulator/ricoh583-regulator.c b/drivers/regulator/ricoh583-regulator.c
index 33f13252cfa7..2f3ef87ecda7 100644
--- a/drivers/regulator/ricoh583-regulator.c
+++ b/drivers/regulator/ricoh583-regulator.c
@@ -36,10 +36,9 @@
#include <linux/mfd/ricoh583.h>
#include <linux/regulator/ricoh583-regulator.h>
-
-#define RICOH_ONOFFSEL_REG 0x10
struct ricoh583_regulator {
int id;
+ int deepsleep_id;
/* Regulator register address.*/
u8 reg_en_reg;
u8 en_bit;
@@ -49,8 +48,6 @@ 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;
@@ -150,73 +147,6 @@ 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)
{
@@ -271,8 +201,8 @@ static struct regulator_ops ricoh583_ops = {
};
#define RICOH583_REG(_id, _en_reg, _en_bit, _disc_reg, _disc_bit, _vout_reg, \
- _vout_mask, _ds_reg, _slpseq_reg, _slpseq_shift, _min_mv, \
- _max_mv, _step_uV, _nsteps, _ops, _delay) \
+ _vout_mask, _ds_reg, _min_mv, _max_mv, _step_uV, _nsteps, \
+ _ops, _delay) \
{ \
.reg_en_reg = _en_reg, \
.en_bit = _en_bit, \
@@ -281,14 +211,13 @@ 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, \
.nsteps = _nsteps, \
.delay = _delay, \
.id = RICOH583_ID_##_id, \
+ .deepsleep_id = RICOH583_DS_##_id, \
.desc = { \
.name = ricoh583_rails(_id), \
.id = RICOH583_ID_##_id, \
@@ -300,33 +229,33 @@ static struct regulator_ops ricoh583_ops = {
}
static struct ricoh583_regulator ricoh583_regulator[] = {
- RICOH583_REG(DC0, 0x30, 0, 0x30, 1, 0x31, 0x7F, 0x60, 0x21, 0,
+ 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, 0x21, 4,
+ 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, 0x22, 0,
+ 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, 0x22, 4,
+ 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, 0x23, 0,
+ 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, 0x23, 4,
+ 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, 0x24, 0,
+ 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, 0x24, 4,
+ 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, 0x25, 0,
+ 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, 0x25, 4,
+ 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, 0x26, 0,
+ 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, 0x26, 4,
+ 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, 0x27, 0,
+ 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, 0x27, 4,
+ RICOH583_REG(LDO9, 0x50, 1, 0x52, 1, 0x5D, 0x7F, 0x6D,
900, 3400, 25000, 0x65, ricoh583_ops, 500),
};
static inline struct ricoh583_regulator *find_regulator_info(int id)
@@ -348,15 +277,13 @@ 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 (ri->deepsleep_id != RICOH583_DS_NONE) {
+ ret = ricoh583_ext_power_req_config(parent, ri->deepsleep_id,
+ ricoh583_pdata->ext_pwr_req,
+ ricoh583_pdata->deepsleep_slots);
+ if (ret < 0)
+ return ret;
+ }
if (!ricoh583_pdata->init_apply)
return 0;
diff --git a/include/linux/mfd/ricoh583.h b/include/linux/mfd/ricoh583.h
index e420bc9a57cd..db1099e4cf57 100644
--- a/include/linux/mfd/ricoh583.h
+++ b/include/linux/mfd/ricoh583.h
@@ -85,6 +85,36 @@ enum {
RICOH583_NR_GPIO,
};
+enum ricoh583_deepsleep_control_id {
+ RICOH583_DS_NONE,
+ RICOH583_DS_DC0,
+ RICOH583_DS_DC1,
+ RICOH583_DS_DC2,
+ RICOH583_DS_DC3,
+ RICOH583_DS_LDO0,
+ RICOH583_DS_LDO1,
+ RICOH583_DS_LDO2,
+ RICOH583_DS_LDO3,
+ RICOH583_DS_LDO4,
+ RICOH583_DS_LDO5,
+ RICOH583_DS_LDO6,
+ RICOH583_DS_LDO7,
+ RICOH583_DS_LDO8,
+ RICOH583_DS_LDO9,
+ RICOH583_DS_PSO0,
+ RICOH583_DS_PSO1,
+ RICOH583_DS_PSO2,
+ RICOH583_DS_PSO3,
+ RICOH583_DS_PSO4,
+ RICOH583_DS_PSO5,
+ RICOH583_DS_PSO6,
+ RICOH583_DS_PSO7,
+};
+enum ricoh583_ext_pwrreq_control {
+ RICOH583_EXT_PWRREQ1_CONTROL = 0x1,
+ RICOH583_EXT_PWRREQ2_CONTROL = 0x2,
+};
+
struct ricoh583_subdev_info {
int id;
const char *name;
@@ -122,6 +152,10 @@ extern int ricoh583_set_bits(struct device *dev, u8 reg, uint8_t bit_mask);
extern int ricoh583_clr_bits(struct device *dev, u8 reg, uint8_t bit_mask);
extern int ricoh583_update(struct device *dev, u8 reg, uint8_t val,
uint8_t mask);
+extern int ricoh583_ext_power_req_config(struct device *dev,
+ enum ricoh583_deepsleep_control_id control_id,
+ enum ricoh583_ext_pwrreq_control ext_pwr_req,
+ int deepsleep_slot_nr);
extern int ricoh583_power_off(void);
#endif
diff --git a/include/linux/regulator/ricoh583-regulator.h b/include/linux/regulator/ricoh583-regulator.h
index 71990b86a2b6..39fdb9e56e05 100644
--- a/include/linux/regulator/ricoh583-regulator.h
+++ b/include/linux/regulator/ricoh583-regulator.h
@@ -49,11 +49,6 @@ 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;
@@ -61,6 +56,7 @@ struct ricoh583_regulator_platform_data {
unsigned init_apply:1;
int deepsleep_uV;
int deepsleep_slots;
+ unsigned long ext_pwr_req;
unsigned long flags;
};