Skip to contentSkip to conversation

mfd: add TI TPS80031 mfd core driver

PATCH In review Laxman Dewangan 3 participants 6 messages Nov 14, 2012 – Nov 21, 2012

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH v4 1/2 mfd: add TI TPS80031 mfd core driver

TPS80031/ TPS80032 Fully Integrated Power Management with Power Path and Battery Charger. The device provides five configurable step-down converters, 11 general purpose LDOs, USB OTG Module, ADC, RTC, 2 PWM, System Voltage Regulator/Battery Charger with Power Path from USB, 32K clock generator.

Add the mfd core driver for TPS80031/TPS80032.

---
Changes from V1:
- remove the volatle api.
- add regmap irq regardless of client->irq.
- Correct the irq cleanups.
- remove usage of irq_base.
- remove suspend/resume
- Correct acroym and ES nomenclature.

Changes from V2:
- Merged regulator specific header file change on this patch.

Changes from V3:
- Remove he twake_base initialzation to get the wakeup support but this is not correct way of doing this.
- Rename some of public definition to have prefix as TPS80031.
- Some more code cleanups as suggested by Guennadi.
- Add the description about MASK_LINE and MASK_STS registers.

 drivers/mfd/Kconfig          |   14 +
 drivers/mfd/Makefile         |    1 +
 drivers/mfd/tps80031.c       |  573 +++++++++++++++++++++++++++++++++++++
 include/linux/mfd/tps80031.h |  637 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 1225 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mfd/tps80031.c
 create mode 100644 include/linux/mfd/tps80031.h
drivers/mfd/Kconfig +14 -0
index 3dcbf06..ffb88dd 100644
@@ -265,6 +265,20 @@ config MFD_TPS65912_SPI
 	  If you say yes here you get support for the TPS65912 series of
 	  PM chips with SPI interface.
 
+config MFD_TPS80031
+	bool "TI TPS80031/TPS80032 Power Management chips"
+	depends on I2C && GENERIC_HARDIRQS
+	select MFD_CORE
+	select REGMAP_I2C
+	select IRQ_DOMAIN
+	help
+	  If you say yes here you get support for the Texas Instruments
+	  TPS80031/ TPS80032 Fully Integrated Power Management with Power
+	  Path and Battery Charger. The device provides five configurable
+	  step-down converters, 11 general purpose LDOs, USB OTG Module,
+	  ADC, RTC, 2 PWM, System Voltage Regulator/Battery Charger with
+	  Power Path from USB, 32K clock generator.
+
 config MENELAUS
 	bool "Texas Instruments TWL92330/Menelaus PM chip"
 	depends on I2C=y && ARCH_OMAP2
drivers/mfd/Makefile +1 -0
index 7d99e8d..c3481f8 100644
@@ -61,6 +61,7 @@ tps65912-objs                   := tps65912-core.o tps65912-irq.o
 obj-$(CONFIG_MFD_TPS65912)	+= tps65912.o
 obj-$(CONFIG_MFD_TPS65912_I2C)	+= tps65912-i2c.o
 obj-$(CONFIG_MFD_TPS65912_SPI)  += tps65912-spi.o
+obj-$(CONFIG_MFD_TPS80031)	+= tps80031.o
 obj-$(CONFIG_MENELAUS)		+= menelaus.o
 
 obj-$(CONFIG_TWL4030_CORE)	+= twl-core.o twl4030-irq.o twl6030-irq.o
drivers/mfd/tps80031.c new file +573 -0

573 lines not on this page · raw message

include/linux/mfd/tps80031.h new file +637 -0

637 lines not on this page · raw message

Signature · 1 line
1.7.1.1
#1 lore raw

PATCH 2/2 regulator: tps80031: add prefix TPS80031 on common defines.

Pefix "TPS80031" is added on all defines of tps80031 header to avoid conflict with other header definitions. Update the regualtor driver of tps80031 to use the same name.

---
Guennadi suggested to have the names of register and its field prefix by TPS80031 to avoid the conflict with name on other driver's header. By doing this, it also need to update the regulator driver to use new names. Just updating the driver on top of applied patch.

 drivers/regulator/tps80031-regulator.c |   80 +++++++++++++++++---------------
 1 files changed, 42 insertions(+), 38 deletions(-)
drivers/regulator/tps80031-regulator.c +42 -38
index 0484478..a37ede8 100644
@@ -105,16 +105,17 @@ static int tps80031_reg_is_enabled(struct regulator_dev *rdev)
 	u8 reg_val;
 	int ret;
 
-	if (ri->ext_ctrl_flag & EXT_PWR_REQ)
+	if (ri->ext_ctrl_flag & TPS80031_EXT_PWR_REQ)
 		return true;
 
-	ret = tps80031_read(parent, SLAVE_ID1, ri->rinfo->state_reg, &reg_val);
+	ret = tps80031_read(parent, TPS80031_SLAVE_ID1, ri->rinfo->state_reg,
+				&reg_val);
 	if (ret < 0) {
 		dev_err(&rdev->dev, "Reg 0x%02x read failed, err = %d\n",
 			ri->rinfo->state_reg, ret);
 		return ret;
 	}
-	return ((reg_val & STATE_MASK) == STATE_ON);
+	return ((reg_val & TPS80031_STATE_MASK) == TPS80031_STATE_ON);
 }
 
 static int tps80031_reg_enable(struct regulator_dev *rdev)
@@ -123,11 +124,11 @@ static int tps80031_reg_enable(struct regulator_dev *rdev)
 	struct device *parent = to_tps80031_dev(rdev);
 	int ret;
 
-	if (ri->ext_ctrl_flag & EXT_PWR_REQ)
+	if (ri->ext_ctrl_flag & TPS80031_EXT_PWR_REQ)
 		return 0;
 
-	ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->state_reg,
-			STATE_ON, STATE_MASK);
+	ret = tps80031_update(parent, TPS80031_SLAVE_ID1, ri->rinfo->state_reg,
+			TPS80031_STATE_ON, TPS80031_STATE_MASK);
 	if (ret < 0) {
 		dev_err(&rdev->dev, "Reg 0x%02x update failed, err = %d\n",
 			ri->rinfo->state_reg, ret);
@@ -142,11 +143,11 @@ static int tps80031_reg_disable(struct regulator_dev *rdev)
 	struct device *parent = to_tps80031_dev(rdev);
 	int ret;
 
-	if (ri->ext_ctrl_flag & EXT_PWR_REQ)
+	if (ri->ext_ctrl_flag & TPS80031_EXT_PWR_REQ)
 		return 0;
 
-	ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->state_reg,
-			STATE_OFF, STATE_MASK);
+	ret = tps80031_update(parent, TPS80031_SLAVE_ID1, ri->rinfo->state_reg,
+			TPS80031_STATE_OFF, TPS80031_STATE_MASK);
 	if (ret < 0)
 		dev_err(&rdev->dev, "Reg 0x%02x update failed, err = %d\n",
 			ri->rinfo->state_reg, ret);
@@ -299,14 +300,14 @@ static int tps80031_vbus_is_enabled(struct regulator_dev *rdev)
 	uint8_t ctrl1 = 0;
 	uint8_t ctrl3 = 0;
 
-	ret = tps80031_read(parent, SLAVE_ID2,
+	ret = tps80031_read(parent, TPS80031_SLAVE_ID2,
 			TPS80031_CHARGERUSB_CTRL1, &ctrl1);
 	if (ret < 0) {
 		dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n",
 			TPS80031_CHARGERUSB_CTRL1, ret);
 		return ret;
 	}
-	ret = tps80031_read(parent, SLAVE_ID2,
+	ret = tps80031_read(parent, TPS80031_SLAVE_ID2,
 				TPS80031_CHARGERUSB_CTRL3, &ctrl3);
 	if (ret < 0) {
 		dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n",
@@ -324,7 +325,7 @@ static int tps80031_vbus_enable(struct regulator_dev *rdev)
 	struct device *parent = to_tps80031_dev(rdev);
 	int ret;
 
-	ret = tps80031_set_bits(parent, SLAVE_ID2,
+	ret = tps80031_set_bits(parent, TPS80031_SLAVE_ID2,
 				TPS80031_CHARGERUSB_CTRL1, OPA_MODE_EN);
 	if (ret < 0) {
 		dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n",
@@ -332,7 +333,7 @@ static int tps80031_vbus_enable(struct regulator_dev *rdev)
 		return ret;
 	}
 
-	ret = tps80031_set_bits(parent, SLAVE_ID2,
+	ret = tps80031_set_bits(parent, TPS80031_SLAVE_ID2,
 				TPS80031_CHARGERUSB_CTRL3, BOOST_HW_PWR_EN);
 	if (ret < 0) {
 		dev_err(ri->dev, "reg 0x%02x read failed, e = %d\n",
@@ -348,8 +349,8 @@ static int tps80031_vbus_disable(struct regulator_dev *rdev)
 	struct device *parent = to_tps80031_dev(rdev);
 	int ret = 0;
 
-	if (ri->config_flags & VBUS_DISCHRG_EN_PDN) {
-		ret = tps80031_write(parent, SLAVE_ID2,
+	if (ri->config_flags & TPS80031_VBUS_DISCHRG_EN_PDN) {
+		ret = tps80031_write(parent, TPS80031_SLAVE_ID2,
 			USB_VBUS_CTRL_SET, VBUS_DISCHRG);
 		if (ret < 0) {
 			dev_err(ri->dev, "reg 0x%02x write failed, e = %d\n",
@@ -358,7 +359,7 @@ static int tps80031_vbus_disable(struct regulator_dev *rdev)
 		}
 	}
 
-	ret = tps80031_clr_bits(parent, SLAVE_ID2,
+	ret = tps80031_clr_bits(parent, TPS80031_SLAVE_ID2,
 			TPS80031_CHARGERUSB_CTRL1,  OPA_MODE_EN);
 	if (ret < 0) {
 		dev_err(ri->dev, "reg 0x%02x clearbit failed, e = %d\n",
@@ -366,7 +367,7 @@ static int tps80031_vbus_disable(struct regulator_dev *rdev)
 		return ret;
 	}
 
-	ret = tps80031_clr_bits(parent, SLAVE_ID2,
+	ret = tps80031_clr_bits(parent, TPS80031_SLAVE_ID2,
 				TPS80031_CHARGERUSB_CTRL3, BOOST_HW_PWR_EN);
 	if (ret < 0) {
 		dev_err(ri->dev, "reg 0x%02x clearbit failed, e = %d\n",
@@ -375,8 +376,8 @@ static int tps80031_vbus_disable(struct regulator_dev *rdev)
 	}
 
 	mdelay(DIV_ROUND_UP(ri->rinfo->desc.enable_time, 1000));
-	if (ri->config_flags & VBUS_DISCHRG_EN_PDN) {
-		ret = tps80031_write(parent, SLAVE_ID2,
+	if (ri->config_flags & TPS80031_VBUS_DISCHRG_EN_PDN) {
+		ret = tps80031_write(parent, TPS80031_SLAVE_ID2,
 			USB_VBUS_CTRL_CLR, VBUS_DISCHRG);
 		if (ret < 0) {
 			dev_err(ri->dev, "reg 0x%02x write failed, e = %d\n",
@@ -433,7 +434,7 @@ static struct regulator_ops tps80031_ext_reg_ops = {
 	.state_reg = TPS80031_##_id##_CFG_STATE,		\
 	.force_reg = TPS80031_##_id##_CFG_FORCE,		\
 	.volt_reg = TPS80031_##_id##_CFG_VOLTAGE,		\
-	.volt_id = SLAVE_##_volt_id,				\
+	.volt_id = TPS80031_SLAVE_##_volt_id,			\
 	.preq_bit = _pbit,					\
 	.desc = {						\
 		.name = "tps80031_"#_id,			\
@@ -451,7 +452,7 @@ static struct regulator_ops tps80031_ext_reg_ops = {
 	.trans_reg = TPS80031_##_id##_CFG_TRANS,		\
 	.state_reg = TPS80031_##_id##_CFG_STATE,		\
 	.volt_reg = TPS80031_##_id##_CFG_VOLTAGE,		\
-	.volt_id = SLAVE_ID1,					\
+	.volt_id = TPS80031_SLAVE_ID1,				\
 	.preq_bit = _preq_bit,					\
 	.desc = {						\
 		.owner = THIS_MODULE,				\
@@ -471,7 +472,7 @@ static struct regulator_ops tps80031_ext_reg_ops = {
 {								\
 	.trans_reg = TPS80031_##_id##_CFG_TRANS,		\
 	.state_reg = TPS80031_##_id##_CFG_STATE,		\
-	.volt_id = SLAVE_ID1,					\
+	.volt_id = TPS80031_SLAVE_ID1,				\
 	.preq_bit = _pbit,					\
 	.desc = {						\
 		.name = "tps80031_"#_id,			\
@@ -524,9 +525,10 @@ static int tps80031_power_req_config(struct device *parent,
 	}
 
 skip_pwr_req_config:
-	if (tps80031_pdata->ext_ctrl_flag & PWR_ON_ON_SLEEP) {
-		ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->trans_reg,
-				TRANS_SLEEP_ON, TRANS_SLEEP_MASK);
+	if (tps80031_pdata->ext_ctrl_flag & TPS80031_PWR_ON_ON_SLEEP) {
+		ret = tps80031_update(parent, TPS80031_SLAVE_ID1,
+				ri->rinfo->trans_reg, TPS80031_TRANS_SLEEP_ON,
+				TPS80031_TRANS_SLEEP_MASK);
 		if (ret < 0) {
 			dev_err(ri->dev, "Reg 0x%02x update failed, e %d\n",
 					ri->rinfo->trans_reg, ret);
@@ -544,16 +546,17 @@ static int tps80031_regulator_config(struct device *parent,
 
 	switch (ri->rinfo->desc.id) {
 	case TPS80031_REGULATOR_LDOUSB:
-		if (ri->config_flags &
-			(USBLDO_INPUT_VSYS | USBLDO_INPUT_PMID)) {
+		if (ri->config_flags & (TPS80031_USBLDO_INPUT_VSYS |
+			TPS80031_USBLDO_INPUT_PMID)) {
 			unsigned val = 0;
-			if (ri->config_flags & USBLDO_INPUT_VSYS)
+			if (ri->config_flags & TPS80031_USBLDO_INPUT_VSYS)
 				val = MISC2_LDOUSB_IN_VSYS;
 			else
 				val = MISC2_LDOUSB_IN_PMID;
 
-			ret = tps80031_update(parent, SLAVE_ID1,
-				TPS80031_MISC2, val, MISC2_LDOUSB_IN_MASK);
+			ret = tps80031_update(parent, TPS80031_SLAVE_ID1,
+				TPS80031_MISC2, val,
+				MISC2_LDOUSB_IN_MASK);
 			if (ret < 0) {
 				dev_err(ri->dev,
 					"LDOUSB config failed, e= %d\n", ret);
@@ -563,8 +566,8 @@ static int tps80031_regulator_config(struct device *parent,
 		break;
 
 	case TPS80031_REGULATOR_LDO3:
-		if (ri->config_flags & LDO3_OUTPUT_VIB) {
-			ret = tps80031_update(parent, SLAVE_ID1,
+		if (ri->config_flags & TPS80031_LDO3_OUTPUT_VIB) {
+			ret = tps80031_update(parent, TPS80031_SLAVE_ID1,
 				TPS80031_MISC2, MISC2_LDO3_SEL_VIB_VAL,
 				MISC2_LDO3_SEL_VIB_MASK);
 			if (ret < 0) {
@@ -577,7 +580,7 @@ static int tps80031_regulator_config(struct device *parent,
 
 	case TPS80031_REGULATOR_VBUS:
 		/* Provide SW control Ops if VBUS is SW control */
-		if (!(ri->config_flags & VBUS_SW_ONLY))
+		if (!(ri->config_flags & TPS80031_VBUS_SW_ONLY))
 			ri->rinfo->desc.ops = &tps80031_vbus_sw_ops;
 		break;
 	default:
@@ -585,9 +588,10 @@ static int tps80031_regulator_config(struct device *parent,
 	}
 
 	/* Configure Active state to ON, SLEEP to OFF and OFF_state to OFF */
-	ret = tps80031_update(parent, SLAVE_ID1, ri->rinfo->trans_reg,
-		TRANS_ACTIVE_ON | TRANS_SLEEP_OFF | TRANS_OFF_OFF,
-		TRANS_ACTIVE_MASK | TRANS_SLEEP_MASK | TRANS_OFF_MASK);
+	ret = tps80031_update(parent, TPS80031_SLAVE_ID1, ri->rinfo->trans_reg,
+		TPS80031_TRANS_ACTIVE_ON | TPS80031_TRANS_SLEEP_OFF |
+		TPS80031_TRANS_OFF_OFF, TPS80031_TRANS_ACTIVE_MASK |
+		TPS80031_TRANS_SLEEP_MASK | TPS80031_TRANS_OFF_MASK);
 	if (ret < 0) {
 		dev_err(ri->dev, "trans reg update failed, e %d\n", ret);
 		return ret;
@@ -604,14 +608,14 @@ static int check_smps_mode_mult(struct device *parent,
 	u8 smps_offset;
 	u8 smps_mult;
 
-	ret = tps80031_read(parent, SLAVE_ID1,
+	ret = tps80031_read(parent, TPS80031_SLAVE_ID1,
 			TPS80031_SMPS_OFFSET, &smps_offset);
 	if (ret < 0) {
 		dev_err(parent, "Error in reading smps offset register\n");
 		return ret;
 	}
 
-	ret = tps80031_read(parent, SLAVE_ID1,
+	ret = tps80031_read(parent, TPS80031_SLAVE_ID1,
 			TPS80031_SMPS_MULT, &smps_mult);
 	if (ret < 0) {
 		dev_err(parent, "Error in reading smps mult register\n");
Signature · 1 line
1.7.1.1
#2 lore raw

Re: [PATCH 2/2] regulator: tps80031: add prefix TPS80031 on common defines.

Quoted 3 lines · Laxman Dewangan

Pefix "TPS80031" is added on all defines of tps80031 header to avoid conflict with other header definitions. Update the regualtor driver of tps80031 to use the same name.

Appiled, thanks.

#3 lore raw
In reply to Laxman Dewangan
Quoted 5 lines · Laxman Dewangan

TPS80031/ TPS80032 Fully Integrated Power Management with Power Path and Battery Charger. The device provides five configurable step-down converters, 11 general purpose LDOs, USB OTG Module, ADC, RTC, 2 PWM, System Voltage Regulator/Battery Charger with Power Path from USB, 32K clock generator.

#4 lore raw
Quoted 9 lines · Mark Brown

* PGP Signed by an unknown key

Quoted 5 lines · Laxman Dewangan

TPS80031/ TPS80032 Fully Integrated Power Management with Power Path and Battery Charger. The device provides five configurable step-down converters, 11 general purpose LDOs, USB OTG Module, ADC, RTC, 2 PWM, System Voltage Regulator/Battery Charger with Power Path from USB, 32K clock generator.

This patch use the function regmap_irq_get_domain() which is not in mfd subsystem. So either it need to go to regmap branch or Samuel need to pull this change. It is good that it will apply on the same way as discussed in patch
[PATCH V3 RESEND 0/4] mfd: tps65910: use regmap irq framework for interrupt

#5 lore raw
In reply to Laxman Dewangan

Hi Laxman,

Quoted 7 lines · Laxman Dewangan

TPS80031/ TPS80032 Fully Integrated Power Management with Power Path and Battery Charger. The device provides five configurable step-down converters, 11 general purpose LDOs, USB OTG Module, ADC, RTC, 2 PWM, System Voltage Regulator/Battery Charger with Power Path from USB, 32K clock generator.

Add the mfd core driver for TPS80031/TPS80032.

Patch applied, thanks.

Cheers,
Samuel.

Signature · 2 lines
Intel Open Source Technology Centre
http://oss.intel.com/