diff options
author | nagesh Penumarty <vpenumarty@nvidia.com> | 2011-04-11 14:59:28 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:43:01 -0800 |
commit | f501c93f859761f4f884a374b72179f164b2742c (patch) | |
tree | 1c9fd55d4dd5db86b2d450fa3a264d530066ea54 | |
parent | f8c8e059b8fe4c6886b00fc38b634f880249eb6d (diff) |
drivers: regulator: Adding the regulator driver
Adding the TI 6025 PMU regulator driver.
Original-Change-Id: I8ad675711bbe2ae942bcc0e32b711883eae215b4
Reviewed-on: http://git-master/r/27342
Tested-by: Venkata Nageswara Penumarty <vpenumarty@nvidia.com>
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Original-Change-Id: Ib91f033c557bb7f4c87522ae4f5c7922a62f71f8
Rebase-Id: R690581a1fd604a9232474fc47982050691051f11
-rw-r--r-- | drivers/mfd/twl-core.c | 85 | ||||
-rw-r--r-- | include/linux/i2c/twl.h | 56 | ||||
-rw-r--r-- | include/linux/mfd/tps80031x.h | 106 |
3 files changed, 243 insertions, 4 deletions
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index b8eef462737a..712859aa86ac 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -58,6 +58,14 @@ #define DRIVER_NAME "twl" +#if defined(CONFIG_TWL4030_BCI_BATTERY) || \ + defined(CONFIG_TWL4030_BCI_BATTERY_MODULE) || \ + defined(CONFIG_TWL6030_BCI_BATTERY) || \ + defined(CONFIG_TWL6030_BCI_BATTERY_MODULE) +#define twl_has_bci() true +#else +#define twl_has_bci() false +#endif #if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE) #define twl_has_keypad() true #else @@ -77,7 +85,8 @@ #define twl_has_regulator() false #endif -#if defined(CONFIG_TWL4030_MADC) || defined(CONFIG_TWL4030_MADC_MODULE) +#if defined(CONFIG_TWL4030_MADC) || defined(CONFIG_TWL4030_MADC_MODULE) ||\ + defined(CONFIG_TWL6030_GPADC) || defined(CONFIG_TWL6030_GPADC_MODULE) #define twl_has_madc() true #else #define twl_has_madc() false @@ -125,7 +134,7 @@ /* Triton Core internal information (BEGIN) */ /* Last - for index max*/ -#define TWL4030_MODULE_LAST TWL4030_MODULE_SECURED_REG +#define TWL4030_MODULE_LAST TWL6025_MODULE_CHARGER #define TWL_NUM_SLAVES 4 @@ -208,6 +217,10 @@ #define TWL6030_BASEADD_RSV 0x0000 #define TWL6030_BASEADD_ZERO 0x0000 +/* twl6030 SMPS EPROM values */ +#define TWL6030_SMPS_OFFSET 0xB0 +#define TWL6030_SMPS_MULT 0xB3 + /* Few power values */ #define R_CFG_BOOT 0x05 @@ -240,6 +253,33 @@ unsigned int twl_rev(void) } EXPORT_SYMBOL(twl_rev); +static unsigned int twl_feat; +unsigned int twl_features(void) +{ + return twl_feat; +} +EXPORT_SYMBOL(twl_features); + +u8 twl_get_smps_offset(void) +{ + u8 value; + + twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value, + TWL6030_SMPS_OFFSET); + return value; +} +EXPORT_SYMBOL(twl_get_smps_offset); + +u8 twl_get_smps_mult(void) +{ + u8 value; + + twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value, + TWL6030_SMPS_MULT); + return value; +} +EXPORT_SYMBOL(twl_get_smps_mult); + /* Structure for each TWL4030/TWL6030 Slave */ struct twl_client { struct i2c_client *client; @@ -490,6 +530,19 @@ int twl_i2c_read_u8(u8 mod_no, u8 *value, u8 reg) } EXPORT_SYMBOL(twl_i2c_read_u8); + +void twl_reg_dump(int module, int start, int end) +{ + int i; + u8 val; + + for (i = start; i < end; i++) { + twl_i2c_read_u8(module, &val, i); + printk(KERN_ERR "reg 0x%2x val 0x%2x\n", i, val); + } +} +EXPORT_SYMBOL(twl_reg_dump); + /*----------------------------------------------------------------------*/ /** @@ -660,8 +713,16 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) if (IS_ERR(child)) return PTR_ERR(child); } + if (twl_has_bci() && pdata->bci && + (features & TWL6030_CLASS)) { + child = add_child(1, "twl6030_bci", + pdata->bci, sizeof(*pdata->bci), + false, + pdata->irq_base + CHARGER_INTR_OFFSET, + pdata->irq_base + CHARGERFAULT_INTR_OFFSET); + } - if (twl_has_madc() && pdata->madc) { + if (twl_has_madc() && pdata->madc && twl_class_is_4030()) { child = add_child(2, "twl4030_madc", pdata->madc, sizeof(*pdata->madc), true, pdata->irq_base + MADC_INTR_OFFSET, 0); @@ -669,6 +730,15 @@ add_children(struct twl4030_platform_data *pdata, unsigned long features) return PTR_ERR(child); } + if (twl_has_madc() && pdata->madc && twl_class_is_6030()) { + child = add_child(1, "twl6030_gpadc", + pdata->madc, sizeof(*pdata->madc), + true, pdata->irq_base + MADC_INTR_OFFSET, + pdata->irq_base + GPADCSW_INTR_OFFSET); + if (IS_ERR(child)) + return PTR_ERR(child); + } + if (twl_has_rtc()) { /* * REVISIT platform_data here currently might expose the @@ -1269,7 +1339,16 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1); } + twl_feat = id->driver_data; + status = add_children(pdata, id->driver_data); + if (status < 0 ) + goto fail; + + /* Board Specific Init Callback */ + if(pdata->init) + status = pdata->init(); + fail: if (status < 0) twl_remove(client); diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h index 114c0f6fc63d..bd126405f10f 100644 --- a/include/linux/i2c/twl.h +++ b/include/linux/i2c/twl.h @@ -82,6 +82,10 @@ #define TWL_MODULE_RTC TWL4030_MODULE_RTC #define TWL_MODULE_PWM TWL4030_MODULE_PWM0 +#define TWL6030_MODULE_CHARGER TWL4030_MODULE_MAIN_CHARGE +#define TWL6025_MODULE_CHARGER 0x18 + +#define TWL6030_MODULE_GASGAUGE 0x0B #define TWL6030_MODULE_ID0 0x0D #define TWL6030_MODULE_ID1 0x0E #define TWL6030_MODULE_ID2 0x0F @@ -108,6 +112,7 @@ #define GASGAUGE_INTR_OFFSET 17 #define USBOTG_INTR_OFFSET 4 #define CHARGER_INTR_OFFSET 2 +#define GPADCSW_INTR_OFFSET 1 #define RSV_INTR_OFFSET 0 /* INT register offsets */ @@ -173,12 +178,21 @@ TWL_CLASS_IS(6030, TWL6030_CLASS_ID) #define TWL6025_SUBCLASS BIT(4) /* TWL6025 has changed registers */ +/* So we can recover the features in other parts of twl stack */ +unsigned int twl_features(void); + +/* so we can get at the EPROM SMPS OFFSET/MULT stuff */ +u8 twl_get_smps_offset(void); +u8 twl_get_smps_mult(void); + /* * Read and write single 8-bit registers */ int twl_i2c_write_u8(u8 mod_no, u8 val, u8 reg); int twl_i2c_read_u8(u8 mod_no, u8 *val, u8 reg); +void twl_reg_dump(int module, int start, int end); + /* * Read and write several 8-bit registers at once. * @@ -215,6 +229,10 @@ static inline int twl6030_mmc_card_detect(struct device *dev, int slot) return -EIO; } #endif + +int twl6030_set_usb_charge_enable(int enable); +int twl6030_set_usb_in_current(int currentmA); + /*----------------------------------------------------------------------*/ /* @@ -556,7 +574,22 @@ struct twl4030_clock_init_data { struct twl4030_bci_platform_data { int *battery_tmp_tbl; - unsigned int tblsize; + unsigned int battery_tmp_tblsize; + int *battery_volt_tbl; + unsigned int battery_volt_tblsize; + unsigned int monitoring_interval; + + unsigned int max_charger_currentmA; + unsigned int max_charger_voltagemV; + unsigned int termination_currentmA; + + unsigned int max_bat_voltagemV; + unsigned int low_bat_voltagemV; + + /* twl6025 */ + unsigned int use_hw_charger; + unsigned int use_eeprom_config; + unsigned int power_path; }; /* TWL4030_GPIO_MAX (18) GPIOs, with interrupts */ @@ -621,6 +654,7 @@ struct twl4030_usb_data { int (*phy_set_clock)(struct device *dev, int on); /* suspend/resume of phy */ int (*phy_suspend)(struct device *dev, int suspend); + int (*board_control_power)(struct device *dev, int on); }; struct twl4030_ins { @@ -696,6 +730,10 @@ struct twl4030_audio_data { struct twl4030_platform_data { unsigned irq_base, irq_end; + + /* Callback for boar regulator initialisation */ + int (*init)(void); + struct twl4030_clock_init_data *clock; struct twl4030_bci_platform_data *bci; struct twl4030_gpio_platform_data *gpio; @@ -822,6 +860,22 @@ static inline int twl4030charger_usb_en(int enable) { return 0; } #define TWL6030_REG_VDAC 45 #define TWL6030_REG_VUSB 46 +/* These are renamed in 6025 but same registers */ +#define TWL6025_REG_LDO2 48 +#define TWL6025_REG_LDO4 49 +#define TWL6025_REG_LDO3 50 +#define TWL6025_REG_LDO5 51 +#define TWL6025_REG_LDO1 52 +#define TWL6025_REG_LDO7 53 +#define TWL6025_REG_LDO6 54 +#define TWL6025_REG_LDOLN 55 +#define TWL6025_REG_LDOUSB 56 + +/* 6025 DCDC supplies */ +#define TWL6025_REG_SMPS3 57 +#define TWL6025_REG_SMPS4 58 +#define TWL6025_REG_VIO 59 + /* INTERNAL LDOs */ #define TWL6030_REG_VRTC 47 #define TWL6030_REG_CLK32KG 48 diff --git a/include/linux/mfd/tps80031x.h b/include/linux/mfd/tps80031x.h new file mode 100644 index 000000000000..8f74cbe7406e --- /dev/null +++ b/include/linux/mfd/tps80031x.h @@ -0,0 +1,106 @@ +/* + * include/linux/mfd/tps80031x.c + * Core driver interface for TI TPS80031x PMIC family + * + * Copyright (C) 2011 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef __LINUX_MFD_TPS80031X_H +#define __LINUX_MFD_TPS80031X_H + +#define tps80031x_rails(_name) "tps80031x_"#_name + +enum { + TPS80031X_ID_SMPS4, + TPS80031X_ID_VIO, + TPS80031X_ID_SMPS1, + TPS80031X_ID_SMPS2, + TPS80031X_ID_SMPS3, + TPS80031X_ID_VANA, + TPS80031X_ID_LDO_2, + TPS80031X_ID_LDO_4, + TPS80031X_ID_LDO_3, + TPS80031X_ID_LDO_6, + TPS80031X_ID_LDO_LN, + TPS80031X_ID_LDO_5, + TPS80031X_ID_LDO_1, + TPS80031X_ID_LDO_USB, + TPS80031X_ID_LDO_7, + TPS80031X_ID_LDO_VRTC, +}; + +enum { + TPS80031X_INT_PWRHOLD_F, + TPS80031X_INT_VMBHI, + TPS80031X_INT_PWRON, + TPS80031X_INT_PWRON_LP, + TPS80031X_INT_PWRHOLD_R, + TPS80031X_INT_HOTDIE, + TPS80031X_INT_RTC_ALARM, + TPS80031X_INT_RTC_PERIOD, + TPS80031X_INT_GPIO0_R, + TPS80031X_INT_GPIO0_F, + TPS80031X_INT_GPIO1_R, + TPS80031X_INT_GPIO1_F, + TPS80031X_INT_GPIO2_R, + TPS80031X_INT_GPIO2_F, + TPS80031X_INT_GPIO3_R, + TPS80031X_INT_GPIO3_F, + TPS80031X_INT_GPIO4_R, + TPS80031X_INT_GPIO4_F, + TPS80031X_INT_GPIO5_R, + TPS80031X_INT_GPIO5_F, + TPS80031X_INT_WTCHDG, + TPS80031X_INT_VMBCH2_H, + TPS80031X_INT_VMBCH2_L, + TPS80031X_INT_PWRDN, +}; + +struct tps80031x_subdev_info { + int id; + const char *name; + void *platform_data; +}; + +struct tps80031x_rtc_platform_data { + int irq; +}; + +struct tps80031x_platform_data { + int num_subdevs; + struct tps80031x_subdev_info *subdevs; + + int gpio_base; + int irq_base; +}; + +/* + * NOTE: the functions below are not intended for use outside + * of the TPS80031X sub-device drivers + */ +extern int tps80031x_write(struct device *dev, int reg, uint8_t val); +extern int tps80031x_writes(struct device *dev, int reg, int len, uint8_t *val); +extern int tps80031x_read(struct device *dev, int reg, uint8_t *val); +extern int tps80031x_reads(struct device *dev, int reg, int len, uint8_t *val); +extern int tps80031x_set_bits(struct device *dev, int reg, uint8_t bit_mask); +extern int tps80031x_clr_bits(struct device *dev, int reg, uint8_t bit_mask); +extern int tps80031x_update(struct device *dev, int reg, uint8_t val, + uint8_t mask); +extern int tps80031x_power_off(void); + +#endif /*__LINUX_MFD_TPS80031X_H */ |