diff options
author | Tom Cherry <tcherry@nvidia.com> | 2012-03-23 13:55:52 -0700 |
---|---|---|
committer | Rohan Somvanshi <rsomvanshi@nvidia.com> | 2012-04-05 08:54:59 -0700 |
commit | 40aa4fb7ef812eb700cbce8ab94cf25f6ab9330c (patch) | |
tree | 652578b1629dcc6c863bda80bfcd2984f481996e | |
parent | 1edb224e180de5780baf25da3ac24e5e5a78db9b (diff) |
mfd: tps80031: add option to enable internal pullup or pulldown
Bug 958089
(cherry-picked from commit 7f4c6d6b9dd2b06984b59dcd60d92026cab4c87c)
Reviewed-on: http://git-master/r/92053
Change-Id: I0f2bdb5482fdcb508808d2d58771d74a05b5597f
Signed-off-by: Tom Cherry <tcherry@nvidia.com>
Reviewed-on: http://git-master/r/94117
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
-rw-r--r-- | drivers/mfd/tps80031.c | 62 | ||||
-rw-r--r-- | include/linux/mfd/tps80031.h | 31 |
2 files changed, 93 insertions, 0 deletions
diff --git a/drivers/mfd/tps80031.c b/drivers/mfd/tps80031.c index fb6ff3bf4d60..e8ea75c424c6 100644 --- a/drivers/mfd/tps80031.c +++ b/drivers/mfd/tps80031.c @@ -100,6 +100,16 @@ #define TPS80031_PREQ3_RES_ASS_A 0xDD #define TPS80031_PHOENIX_MSK_TRANSITION 0x20 +#define TPS80031_CFG_INPUT_PUPD1 0xF0 +#define TPS80031_CFG_INPUT_PUPD2 0xF1 +#define TPS80031_CFG_INPUT_PUPD3 0xF2 +#define TPS80031_CFG_INPUT_PUPD4 0xF3 + +struct tps80031_pupd_data { + u8 reg; + u8 pullup_bit; + u8 pulldown_bit; +}; static u8 pmc_ext_control_base[] = { REGEN1_BASE_ADD, @@ -183,6 +193,31 @@ static const struct tps80031_irq_data tps80031_irqs[] = { MLINCH_GATED, LINCH_GATED), }; +#define PUPD_DATA(_reg, _pulldown_bit, _pullup_bit) \ + { \ + .reg = TPS80031_CFG_INPUT_PUPD##_reg, \ + .pulldown_bit = _pulldown_bit, \ + .pullup_bit = _pullup_bit, \ + } + +static const struct tps80031_pupd_data tps80031_pupds[] = { + [TPS80031_PREQ1] = PUPD_DATA(1, 1 << 0, 1 << 1 ), + [TPS80031_PREQ2A] = PUPD_DATA(1, 1 << 2, 1 << 3 ), + [TPS80031_PREQ2B] = PUPD_DATA(1, 1 << 4, 1 << 5 ), + [TPS80031_PREQ2C] = PUPD_DATA(1, 1 << 6, 1 << 7 ), + [TPS80031_PREQ3] = PUPD_DATA(2, 1 << 0, 1 << 1 ), + [TPS80031_NRES_WARM] = PUPD_DATA(2, 0, 1 << 2 ), + [TPS80031_PWM_FORCE] = PUPD_DATA(2, 1 << 5, 0 ), + [TPS80031_CHRG_EXT_CHRG_STATZ] = PUPD_DATA(2, 0, 1 << 6 ), + [TPS80031_SIM] = PUPD_DATA(3, 1 << 0, 1 << 1 ), + [TPS80031_MMC] = PUPD_DATA(3, 1 << 2, 1 << 3 ), + [TPS80031_GPADC_START] = PUPD_DATA(3, 1 << 4, 0 ), + [TPS80031_DVSI2C_SCL] = PUPD_DATA(4, 0, 1 << 0 ), + [TPS80031_DVSI2C_SDA] = PUPD_DATA(4, 0, 1 << 1 ), + [TPS80031_CTLI2C_SCL] = PUPD_DATA(4, 0, 1 << 2 ), + [TPS80031_CTLI2C_SDA] = PUPD_DATA(4, 0, 1 << 3 ), +}; + static const int controller_stat1_irq_nr[] = { TPS80031_INT_BAT_TEMP_OVRANGE, TPS80031_INT_BAT_REMOVED, @@ -509,6 +544,30 @@ static void tps80031_power_off(void) __tps80031_write(tps->client, TPS80031_PHOENIX_DEV_ON, DEVOFF); } +static void tps80031_pupd_init(struct tps80031 *tps80031, + struct tps80031_platform_data *pdata) +{ + struct tps80031_pupd_init_data *pupd_init_data = pdata->pupd_init_data; + int data_size = pdata->pupd_init_data_size; + int i; + + for (i = 0; i < data_size; ++i) { + struct tps80031_pupd_init_data *pupd_init = &pupd_init_data[i]; + const struct tps80031_pupd_data *pupd = + &tps80031_pupds[pupd_init->input_pin]; + u8 update_value = 0; + u8 update_mask = pupd->pulldown_bit | pupd->pullup_bit; + + if (pupd_init->setting == TPS80031_PUPD_PULLDOWN) + update_value = pupd->pulldown_bit; + else if (pupd_init->setting == TPS80031_PUPD_PULLUP) + update_value = pupd->pullup_bit; + + tps80031_update(tps80031->dev, SLAVE_ID1, pupd->reg, + update_value, update_mask); + } +} + static void tps80031_init_ext_control(struct tps80031 *tps80031, struct tps80031_platform_data *pdata) { int ret; @@ -1197,6 +1256,9 @@ static int __devinit tps80031_i2c_probe(struct i2c_client *client, goto fail; } } + + tps80031_pupd_init(tps80031, pdata); + tps80031_init_ext_control(tps80031, pdata); ret = tps80031_add_subdevs(tps80031, pdata); diff --git a/include/linux/mfd/tps80031.h b/include/linux/mfd/tps80031.h index 1802dfefef05..9623a873d311 100644 --- a/include/linux/mfd/tps80031.h +++ b/include/linux/mfd/tps80031.h @@ -132,6 +132,30 @@ enum tps80031_ext_control { PWR_ON_ON_SLEEP = 0x00000010, }; +enum tps80031_pupd_pins { + TPS80031_PREQ1 = 0, + TPS80031_PREQ2A, + TPS80031_PREQ2B, + TPS80031_PREQ2C, + TPS80031_PREQ3, + TPS80031_NRES_WARM, + TPS80031_PWM_FORCE, + TPS80031_CHRG_EXT_CHRG_STATZ, + TPS80031_SIM, + TPS80031_MMC, + TPS80031_GPADC_START, + TPS80031_DVSI2C_SCL, + TPS80031_DVSI2C_SDA, + TPS80031_CTLI2C_SCL, + TPS80031_CTLI2C_SDA, +}; + +enum tps80031_pupd_settings { + TPS80031_PUPD_NORMAL, + TPS80031_PUPD_PULLDOWN, + TPS80031_PUPD_PULLUP, +}; + struct tps80031_subdev_info { int id; const char *name; @@ -154,6 +178,11 @@ struct tps80031_gpio_init_data { unsigned long ext_ctrl_flag; }; +struct tps80031_pupd_init_data { + int input_pin; + int setting; +}; + struct tps80031_platform_data { int num_subdevs; struct tps80031_subdev_info *subdevs; @@ -165,6 +194,8 @@ struct tps80031_platform_data { struct tps80031_clk32k_init_data *clk32k_init_data; int clk32k_init_data_size; bool use_power_off; + struct tps80031_pupd_init_data *pupd_init_data; + int pupd_init_data_size; }; struct tps80031_bg_platform_data { |