summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2011-05-23 17:21:32 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:43:01 -0800
commitfacb5b00caf9ceb034772b8ab5f04799d2daa053 (patch)
treea9b71bd2683e185e774e5bb10897597be5bb4ddb
parenta2941d326b4394ce8aae454c27cb43258f6a58b1 (diff)
mfd: twl-core: Supporting mpu80031 clock 32K generation
The mpu80031 is having the register compatibility with twl6030 and so the mpu80031 driver is based on twl6030 register programming. But mpu80031 has capability of generating 32KHz which is not there in twl6030. Adding subclass for mpu80031 to identify this feature and adding support for 32KHz clock generation. bug 829520 Original-Change-Id: Icac2b0913fb680a472ebbcdc2ec3a54d1df0ebf1 Reviewed-on: http://git-master/r/32595 Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com> Tested-by: Laxman Dewangan <ldewangan@nvidia.com> Rebase-Id: R8069d39f004ea2223b8ccddc8188b263421e0053
-rw-r--r--drivers/mfd/twl-core.c25
-rw-r--r--include/linux/i2c/twl.h2
2 files changed, 25 insertions, 2 deletions
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 712859aa86ac..a455771c1be0 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -221,6 +221,7 @@
#define TWL6030_SMPS_OFFSET 0xB0
#define TWL6030_SMPS_MULT 0xB3
+
/* Few power values */
#define R_CFG_BOOT 0x05
@@ -231,6 +232,9 @@
#define HIGH_PERF_SQ (1 << 3)
#define CK32K_LOWPWR_EN (1 << 7)
+/* MPU80031 specific clock32 generation register */
+#define REG_CLK32KG_CFG_TRANS 0x8D
+#define REG_CLK32KG_CFG_STATE 0x8E
/* chip-specific feature flags, for i2c_device_id.driver_data */
#define TWL4030_VAUX2 BIT(0) /* pre-5030 voltage ranges */
@@ -1154,13 +1158,29 @@ static inline int __init unprotect_pm_master(void)
}
static void clocks_init(struct device *dev,
- struct twl4030_clock_init_data *clock)
+ struct twl4030_clock_init_data *clock,
+ unsigned long features)
{
int e = 0;
struct clk *osc;
u32 rate;
u8 ctrl = HFCLK_FREQ_26_MHZ;
+ if (features & MPU80031_SUBCLASS) {
+ if (clock && clock->clk32_active_state_on) {
+ e = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0x1,
+ REG_CLK32KG_CFG_TRANS);
+ if (!e)
+ e = twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, 0x1,
+ REG_CLK32KG_CFG_STATE);
+ if (e) {
+ dev_err(dev, "Error in initialization"
+ " of 32K output\n");
+ return;
+ }
+ }
+ }
+
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
if (cpu_is_omap2430())
osc = clk_get(dev, "osc_ck");
@@ -1298,7 +1318,7 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id)
}
/* setup clock framework */
- clocks_init(&client->dev, pdata->clock);
+ clocks_init(&client->dev, pdata->clock, id->driver_data);
/* read TWL IDCODE Register */
if (twl_id == TWL4030_CLASS_ID) {
@@ -1366,6 +1386,7 @@ static const struct i2c_device_id twl_ids[] = {
and vibrator. Charger in USB module*/
{ "twl6030", TWL6030_CLASS }, /* "Phoenix power chip" */
{ "twl6025", TWL6030_CLASS | TWL6025_SUBCLASS }, /* "Phoenix lite" */
+ { "mpu80031", TWL6030_CLASS | TWL6025_SUBCLASS | MPU80031_SUBCLASS},
{ /* end of list */ },
};
MODULE_DEVICE_TABLE(i2c, twl_ids);
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index bd126405f10f..bb92f0b13288 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -177,6 +177,7 @@ TWL_CLASS_IS(4030, TWL4030_CLASS_ID)
TWL_CLASS_IS(6030, TWL6030_CLASS_ID)
#define TWL6025_SUBCLASS BIT(4) /* TWL6025 has changed registers */
+#define MPU80031_SUBCLASS BIT(5) /* MPU80031 has changed registers */
/* So we can recover the features in other parts of twl stack */
unsigned int twl_features(void);
@@ -570,6 +571,7 @@ int twl6030_set_usb_in_current(int currentmA);
struct twl4030_clock_init_data {
bool ck32k_lowpwr_enable;
+ bool clk32_active_state_on;
};
struct twl4030_bci_platform_data {