* [PATCH v2 0/3] mfd: lp873x: Add lp873x PMIC support @ 2016-05-10 4:04 Keerthy 2016-05-10 4:04 ` [PATCH v2 1/3] Documentation: mfd: LP873X: Add information for the mfd and regulator drivers Keerthy ` (2 more replies) 0 siblings, 3 replies; 13+ messages in thread From: Keerthy @ 2016-05-10 4:04 UTC (permalink / raw) To: broonie, lgirdwood, lee.jones Cc: linux-kernel, linux-omap, devicetree, robh+dt, mark.rutland, j-keerthy The LP873X chip is a power management IC for Portable Navigation Systems and Tablet Computing devices. It contains the following components: - Regulators. - Configurable General Purpose Output Signals(GPO). PMIC interacts with the main processor through i2c. PMIC has couple of LDOs(Linear Regulators), couple of BUCKs (Step-Down DC-DC Converter Cores) and GPOs(General Purpose Output Signals). At this time only the regulator functionality is made available. Keerthy (3): Documentation: mfd: LP873X: Add information for the mfd and regulator drivers mfd: lp873x: Add lp873x PMIC support regulator: lp873x: Add support for lp873x PMIC regulators Documentation/devicetree/bindings/mfd/lp873x.txt | 55 +++++ drivers/mfd/Kconfig | 15 ++ drivers/mfd/Makefile | 2 + drivers/mfd/lp873x.c | 98 +++++++++ drivers/regulator/Kconfig | 9 + drivers/regulator/Makefile | 1 + drivers/regulator/lp873x-regulator.c | 241 +++++++++++++++++++++ include/linux/mfd/lp873x.h | 265 +++++++++++++++++++++++ 8 files changed, 686 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/lp873x.txt create mode 100644 drivers/mfd/lp873x.c create mode 100644 drivers/regulator/lp873x-regulator.c create mode 100644 include/linux/mfd/lp873x.h -- 1.9.1 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 1/3] Documentation: mfd: LP873X: Add information for the mfd and regulator drivers 2016-05-10 4:04 [PATCH v2 0/3] mfd: lp873x: Add lp873x PMIC support Keerthy @ 2016-05-10 4:04 ` Keerthy 2016-05-11 14:35 ` Rob Herring 2016-05-12 13:21 ` Lee Jones 2016-05-10 4:04 ` [PATCH v2 2/3] mfd: lp873x: Add lp873x PMIC support Keerthy 2016-05-10 4:04 ` [PATCH v2 3/3] regulator: lp873x: Add support for lp873x PMIC regulators Keerthy 2 siblings, 2 replies; 13+ messages in thread From: Keerthy @ 2016-05-10 4:04 UTC (permalink / raw) To: broonie, lgirdwood, lee.jones Cc: linux-kernel, linux-omap, devicetree, robh+dt, mark.rutland, j-keerthy Add information for the mfd and regulator drivers. Signed-off-by: Keerthy <j-keerthy@ti.com> --- Documentation/devicetree/bindings/mfd/lp873x.txt | 55 ++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/lp873x.txt diff --git a/Documentation/devicetree/bindings/mfd/lp873x.txt b/Documentation/devicetree/bindings/mfd/lp873x.txt new file mode 100644 index 0000000..3ef5ea0 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/lp873x.txt @@ -0,0 +1,55 @@ +TI LP3943 MFD driver + +Required properties: + - compatible: "ti,lp8732", "ti,lp8733" + - reg: I2C slave address. + +For the lp873x regulator properties please refer to: +Documentation/devicetree/bindings/regulator/lp873x.txt + +Example: + +lp8733: lp8733@60 { + compatible = "ti,lp8733"; + reg = <0x60>; + + regulators { + lp8733_buck0: buck0 { + regulator-name = "lp8733-buck0"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + regulator-min-microamp = <1500000>; + regulator-max-microamp = <4000000>; + regulator-ramp-delay = <10000>; + regulator-always-on; + regulator-boot-on; + }; + + lp8733_buck1: buck1 { + regulator-name = "lp8733-buck1"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1400000>; + regulator-min-microamp = <1500000>; + regulator-max-microamp = <4000000>; + regulator-ramp-delay = <10000>; + regulator-boot-on; + regulator-always-on; + }; + + lp8733_ldo0: ldo0 { + regulator-name = "lp8733-ldo0"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + regulator-always-on; + }; + + lp8733_ldo1: ldo1 { + regulator-name = "lp8733-ldo1"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3000000>; + regulator-always-on; + regulator-boot-on; + }; + }; +}; -- 1.9.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/3] Documentation: mfd: LP873X: Add information for the mfd and regulator drivers 2016-05-10 4:04 ` [PATCH v2 1/3] Documentation: mfd: LP873X: Add information for the mfd and regulator drivers Keerthy @ 2016-05-11 14:35 ` Rob Herring 2016-05-12 13:21 ` Lee Jones 1 sibling, 0 replies; 13+ messages in thread From: Rob Herring @ 2016-05-11 14:35 UTC (permalink / raw) To: Keerthy Cc: broonie, lgirdwood, lee.jones, linux-kernel, linux-omap, devicetree, mark.rutland On Tue, May 10, 2016 at 09:34:37AM +0530, Keerthy wrote: > Add information for the mfd and regulator drivers. > > Signed-off-by: Keerthy <j-keerthy@ti.com> > --- > Documentation/devicetree/bindings/mfd/lp873x.txt | 55 ++++++++++++++++++++++++ > 1 file changed, 55 insertions(+) > create mode 100644 Documentation/devicetree/bindings/mfd/lp873x.txt Acked-by: Rob Herring <robh@kernel.org> ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/3] Documentation: mfd: LP873X: Add information for the mfd and regulator drivers 2016-05-10 4:04 ` [PATCH v2 1/3] Documentation: mfd: LP873X: Add information for the mfd and regulator drivers Keerthy 2016-05-11 14:35 ` Rob Herring @ 2016-05-12 13:21 ` Lee Jones 2016-05-12 23:21 ` Keerthy 1 sibling, 1 reply; 13+ messages in thread From: Lee Jones @ 2016-05-12 13:21 UTC (permalink / raw) To: Keerthy Cc: broonie, lgirdwood, linux-kernel, linux-omap, devicetree, robh+dt, mark.rutland On Tue, 10 May 2016, Keerthy wrote: > Add information for the mfd and regulator drivers. > > Signed-off-by: Keerthy <j-keerthy@ti.com> > --- > Documentation/devicetree/bindings/mfd/lp873x.txt | 55 ++++++++++++++++++++++++ > 1 file changed, 55 insertions(+) > create mode 100644 Documentation/devicetree/bindings/mfd/lp873x.txt > > diff --git a/Documentation/devicetree/bindings/mfd/lp873x.txt b/Documentation/devicetree/bindings/mfd/lp873x.txt > new file mode 100644 > index 0000000..3ef5ea0 > --- /dev/null > +++ b/Documentation/devicetree/bindings/mfd/lp873x.txt > @@ -0,0 +1,55 @@ > +TI LP3943 MFD driver > + > +Required properties: > + - compatible: "ti,lp8732", "ti,lp8733" > + - reg: I2C slave address. > + > +For the lp873x regulator properties please refer to: > +Documentation/devicetree/bindings/regulator/lp873x.txt This is a Linuxism. Use ../bindings/.. instead. > +Example: > + > +lp8733: lp8733@60 { lp8733 is not a device 'type'. What does it do? Looks like a 'pmic' to me. > + compatible = "ti,lp8733"; > + reg = <0x60>; > + > + regulators { > + lp8733_buck0: buck0 { > + regulator-name = "lp8733-buck0"; > + regulator-min-microvolt = <800000>; > + regulator-max-microvolt = <1400000>; > + regulator-min-microamp = <1500000>; > + regulator-max-microamp = <4000000>; > + regulator-ramp-delay = <10000>; > + regulator-always-on; > + regulator-boot-on; > + }; > + > + lp8733_buck1: buck1 { > + regulator-name = "lp8733-buck1"; > + regulator-min-microvolt = <800000>; > + regulator-max-microvolt = <1400000>; > + regulator-min-microamp = <1500000>; > + regulator-max-microamp = <4000000>; > + regulator-ramp-delay = <10000>; > + regulator-boot-on; > + regulator-always-on; > + }; > + > + lp8733_ldo0: ldo0 { > + regulator-name = "lp8733-ldo0"; > + regulator-min-microvolt = <800000>; > + regulator-max-microvolt = <3000000>; > + regulator-boot-on; > + regulator-always-on; > + }; > + > + lp8733_ldo1: ldo1 { > + regulator-name = "lp8733-ldo1"; > + regulator-min-microvolt = <800000>; > + regulator-max-microvolt = <3000000>; > + regulator-always-on; > + regulator-boot-on; > + }; > + }; > +}; I'm failing to see how this is an MFD? -- Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 1/3] Documentation: mfd: LP873X: Add information for the mfd and regulator drivers 2016-05-12 13:21 ` Lee Jones @ 2016-05-12 23:21 ` Keerthy 0 siblings, 0 replies; 13+ messages in thread From: Keerthy @ 2016-05-12 23:21 UTC (permalink / raw) To: Lee Jones, Keerthy Cc: broonie, lgirdwood, linux-kernel, linux-omap, devicetree, robh+dt, mark.rutland On Thursday 12 May 2016 06:51 PM, Lee Jones wrote: > On Tue, 10 May 2016, Keerthy wrote: > >> Add information for the mfd and regulator drivers. >> >> Signed-off-by: Keerthy <j-keerthy@ti.com> >> --- >> Documentation/devicetree/bindings/mfd/lp873x.txt | 55 ++++++++++++++++++++++++ >> 1 file changed, 55 insertions(+) >> create mode 100644 Documentation/devicetree/bindings/mfd/lp873x.txt >> >> diff --git a/Documentation/devicetree/bindings/mfd/lp873x.txt b/Documentation/devicetree/bindings/mfd/lp873x.txt >> new file mode 100644 >> index 0000000..3ef5ea0 >> --- /dev/null >> +++ b/Documentation/devicetree/bindings/mfd/lp873x.txt >> @@ -0,0 +1,55 @@ >> +TI LP3943 MFD driver >> + >> +Required properties: >> + - compatible: "ti,lp8732", "ti,lp8733" >> + - reg: I2C slave address. >> + >> +For the lp873x regulator properties please refer to: >> +Documentation/devicetree/bindings/regulator/lp873x.txt > > This is a Linuxism. Use ../bindings/.. instead. Okay. > >> +Example: >> + >> +lp8733: lp8733@60 { > > lp8733 is not a device 'type'. What does it do? > > Looks like a 'pmic' to me. > >> + compatible = "ti,lp8733"; >> + reg = <0x60>; >> + >> + regulators { >> + lp8733_buck0: buck0 { >> + regulator-name = "lp8733-buck0"; >> + regulator-min-microvolt = <800000>; >> + regulator-max-microvolt = <1400000>; >> + regulator-min-microamp = <1500000>; >> + regulator-max-microamp = <4000000>; >> + regulator-ramp-delay = <10000>; >> + regulator-always-on; >> + regulator-boot-on; >> + }; >> + >> + lp8733_buck1: buck1 { >> + regulator-name = "lp8733-buck1"; >> + regulator-min-microvolt = <800000>; >> + regulator-max-microvolt = <1400000>; >> + regulator-min-microamp = <1500000>; >> + regulator-max-microamp = <4000000>; >> + regulator-ramp-delay = <10000>; >> + regulator-boot-on; >> + regulator-always-on; >> + }; >> + >> + lp8733_ldo0: ldo0 { >> + regulator-name = "lp8733-ldo0"; >> + regulator-min-microvolt = <800000>; >> + regulator-max-microvolt = <3000000>; >> + regulator-boot-on; >> + regulator-always-on; >> + }; >> + >> + lp8733_ldo1: ldo1 { >> + regulator-name = "lp8733-ldo1"; >> + regulator-min-microvolt = <800000>; >> + regulator-max-microvolt = <3000000>; >> + regulator-always-on; >> + regulator-boot-on; >> + }; >> + }; >> +}; > > I'm failing to see how this is an MFD? As of now, only regulators part is supported, there are Configurable General Purpose Output Signals (GPO), Over-Temperature Warning and Protection apart from regulators. > ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 2/3] mfd: lp873x: Add lp873x PMIC support 2016-05-10 4:04 [PATCH v2 0/3] mfd: lp873x: Add lp873x PMIC support Keerthy 2016-05-10 4:04 ` [PATCH v2 1/3] Documentation: mfd: LP873X: Add information for the mfd and regulator drivers Keerthy @ 2016-05-10 4:04 ` Keerthy 2016-05-12 13:18 ` Lee Jones 2016-05-10 4:04 ` [PATCH v2 3/3] regulator: lp873x: Add support for lp873x PMIC regulators Keerthy 2 siblings, 1 reply; 13+ messages in thread From: Keerthy @ 2016-05-10 4:04 UTC (permalink / raw) To: broonie, lgirdwood, lee.jones Cc: linux-kernel, linux-omap, devicetree, robh+dt, mark.rutland, j-keerthy The LP873X chip is a power management IC for Portable Navigation Systems and Tablet Computing devices. It contains the following components: - Regulators. - Configurable General Purpose Output Signals(GPO). PMIC interacts with the main processor through i2c. PMIC has couple of LDOs(Linear Regulators), couple of BUCKs (Step-Down DC-DC Converter Cores) and GPOs(General Purpose Output Signals). At this time only the regulator functionality is made available. Signed-off-by: Keerthy <j-keerthy@ti.com> --- Changes in v2: * Used mfd_add_devices instead of of_pltaform_populate. drivers/mfd/Kconfig | 15 +++ drivers/mfd/Makefile | 2 + drivers/mfd/lp873x.c | 98 +++++++++++++++++ include/linux/mfd/lp873x.h | 265 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 380 insertions(+) create mode 100644 drivers/mfd/lp873x.c create mode 100644 include/linux/mfd/lp873x.h diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index eea61e3..1d85f10 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1185,6 +1185,21 @@ config MFD_TPS65217 This driver can also be built as a module. If so, the module will be called tps65217. +config MFD_LP873X + tristate "TI LP873X Power Management IC" + depends on I2C + select MFD_CORE + select REGMAP_I2C + help + If you say yes here you get support for the LP873X series of + Power Management Integrated Circuits. + These include voltage regulators, Thermal protection, Configurable + general pirpose outputs and other features that are often used in + portable devices. + + This driver can also be built as a module. If so, the module + will be called lp873x. + config MFD_TPS65218 tristate "TI TPS65218 Power Management chips" depends on I2C diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 5eaa6465d..617c688 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -22,6 +22,8 @@ obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o +obj-$(CONFIG_MFD_LP873X) += lp873x.o + obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o obj-$(CONFIG_MFD_TI_AM335X_TSCADC) += ti_am335x_tscadc.o diff --git a/drivers/mfd/lp873x.c b/drivers/mfd/lp873x.c new file mode 100644 index 0000000..6046adf --- /dev/null +++ b/drivers/mfd/lp873x.c @@ -0,0 +1,98 @@ +/* + * LP873X chip family multi-function driver + * + * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ + * + * 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 version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/mfd/core.h> +#include <linux/regmap.h> +#include <linux/of_device.h> +#include <linux/mfd/lp873x.h> + +static const struct regmap_config lp873x_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = LP873X_REG_MAX, +}; + +static const struct mfd_cell lp873x_cells[] = { + { .name = "lp873x-regulator", }, +}; + +static const struct of_device_id of_lp873x_match_table[] = { + { .compatible = "ti,lp8733", }, + { .compatible = "ti,lp8732", }, + {} +}; +MODULE_DEVICE_TABLE(of, of_lp873x_match_table); + +static const struct i2c_device_id lp873x_id_table[] = { + { "lp873x", LP873X }, + { "lp8732", LP873X }, + { "lp8733", LP873X }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, lp873x_id_table); + +static int lp873x_probe(struct i2c_client *client, + const struct i2c_device_id *ids) +{ + struct lp873x *lp873; + int ret; + unsigned int otpid; + + lp873 = devm_kzalloc(&client->dev, sizeof(*lp873), GFP_KERNEL); + if (!lp873) + return -ENOMEM; + + i2c_set_clientdata(client, lp873); + lp873->dev = &client->dev; + lp873->regmap = devm_regmap_init_i2c(client, &lp873x_regmap_config); + if (IS_ERR(lp873->regmap)) { + ret = PTR_ERR(lp873->regmap); + dev_err(lp873->dev, "Failed to initialize register map: %d\n", + ret); + return ret; + } + + mutex_init(&lp873->lp873_lock); + + ret = regmap_read(lp873->regmap, LP873X_REG_OTP_REV, &otpid); + + if (ret) { + dev_err(lp873->dev, "Failed to read otpid\n"); + return ret; + } + + lp873->rev = otpid & LP873X_OTP_REV_OTP_ID; + + ret = mfd_add_devices(lp873->dev, PLATFORM_DEVID_AUTO, lp873x_cells, + ARRAY_SIZE(lp873x_cells), NULL, 0, NULL); + + return ret; +} + +static struct i2c_driver lp873x_driver = { + .driver = { + .name = "lp873x", + .of_match_table = of_lp873x_match_table, + }, + .probe = lp873x_probe, + .id_table = lp873x_id_table, +}; +module_i2c_driver(lp873x_driver); + +MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>"); +MODULE_DESCRIPTION("LP873X chip family multi-function driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/mfd/lp873x.h b/include/linux/mfd/lp873x.h new file mode 100644 index 0000000..72f6ee9 --- /dev/null +++ b/include/linux/mfd/lp873x.h @@ -0,0 +1,265 @@ +/* + * Functions to access LP873X power management chip. + * + * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ + * + * 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 version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __LINUX_MFD_LP873X_H +#define __LINUX_MFD_LP873X_H + +#include <linux/i2c.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/machine.h> + +/* LP873x chip id list */ +#define LP873X 0x00 + +/* All register addresses */ +#define LP873X_REG_DEV_REV 0X00 +#define LP873X_REG_OTP_REV 0X01 +#define LP873X_REG_BUCK0_CTRL_1 0X02 +#define LP873X_REG_BUCK0_CTRL_2 0X03 +#define LP873X_REG_BUCK1_CTRL_1 0X04 +#define LP873X_REG_BUCK1_CTRL_2 0X05 +#define LP873X_REG_BUCK0_VOUT 0X06 +#define LP873X_REG_BUCK1_VOUT 0X07 +#define LP873X_REG_LDO0_CTRL 0X08 +#define LP873X_REG_LDO1_CTRL 0X09 +#define LP873X_REG_LDO0_VOUT 0X0A +#define LP873X_REG_LDO1_VOUT 0X0B +#define LP873X_REG_BUCK0_DELAY 0X0C +#define LP873X_REG_BUCK1_DELAY 0X0D +#define LP873X_REG_LDO0_DELAY 0X0E +#define LP873X_REG_LDO1_DELAY 0X0F +#define LP873X_REG_GPO_DELAY 0X10 +#define LP873X_REG_GPO2_DELAY 0X11 +#define LP873X_REG_GPO_CTRL 0X12 +#define LP873X_REG_CONFIG 0X13 +#define LP873X_REG_PLL_CTRL 0X14 +#define LP873X_REG_PGOOD_CTRL1 0X15 +#define LP873X_REG_PGOOD_CTRL2 0X16 +#define LP873X_REG_PG_FAULT 0X17 +#define LP873X_REG_RESET 0X18 +#define LP873X_REG_INT_TOP_1 0X19 +#define LP873X_REG_INT_TOP_2 0X1A +#define LP873X_REG_INT_BUCK 0X1B +#define LP873X_REG_INT_LDO 0X1C +#define LP873X_REG_TOP_STAT 0X1D +#define LP873X_REG_BUCK_STAT 0X1E +#define LP873X_REG_LDO_STAT 0x1F +#define LP873X_REG_TOP_MASK_1 0x20 +#define LP873X_REG_TOP_MASK_2 0x21 +#define LP873X_REG_BUCK_MASK 0x22 +#define LP873X_REG_LDO_MASK 0x23 +#define LP873X_REG_SEL_I_LOAD 0x24 +#define LP873X_REG_I_LOAD_2 0x25 +#define LP873X_REG_I_LOAD_1 0x26 + +#define LP873X_REG_MAX LP873X_REG_I_LOAD_1 + +/* Register field definitions */ +#define LP873X_DEV_REV_DEV_ID 0xC0 +#define LP873X_DEV_REV_ALL_LAYER 0x30 +#define LP873X_DEV_REV_METAL_LAYER 0x0F + +#define LP873X_OTP_REV_OTP_ID 0xFF + +#define LP873X_BUCK0_CTRL_1_BUCK0_FPWM BIT(3) +#define LP873X_BUCK0_CTRL_1_BUCK0_RDIS_EN BIT(2) +#define LP873X_BUCK0_CTRL_1_BUCK0_EN_PIN_CTRL BIT(1) +#define LP873X_BUCK0_CTRL_1_BUCK0_EN BIT(0) + +#define LP873X_BUCK0_CTRL_2_BUCK0_ILIM 0x38 +#define LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE 0x07 + +#define LP873X_BUCK1_CTRL_1_BUCK1_FPWM BIT(3) +#define LP873X_BUCK1_CTRL_1_BUCK1_RDIS_EN BIT(2) +#define LP873X_BUCK1_CTRL_1_BUCK1_EN_PIN_CTRL BIT(1) +#define LP873X_BUCK1_CTRL_1_BUCK1_EN BIT(0) + +#define LP873X_BUCK1_CTRL_2_BUCK1_ILIM 0x38 +#define LP873X_BUCK1_CTRL_2_BUCK1_SLEW_RATE 0x07 + +#define LP873X_BUCK0_VOUT_BUCK0_VSET 0xFF + +#define LP873X_BUCK1_VOUT_BUCK1_VSET 0xFF + +#define LP873X_LDO0_CTRL_LDO0_RDIS_EN BIT(2) +#define LP873X_LDO0_CTRL_LDO0_EN_PIN_CTRL BIT(1) +#define LP873X_LDO0_CTRL_LDO0_EN BIT(0) + +#define LP873X_LDO1_CTRL_LDO1_RDIS_EN BIT(2) +#define LP873X_LDO1_CTRL_LDO1_EN_PIN_CTRL BIT(1) +#define LP873X_LDO1_CTRL_LDO1_EN BIT(0) + +#define LP873X_LDO0_VOUT_LDO0_VSET 0x1F + +#define LP873X_LDO1_VOUT_LDO1_VSET 0x1F + +#define LP873X_BUCK0_DELAY_BUCK0_SD_DELAY 0xF0 +#define LP873X_BUCK0_DELAY_BUCK0_SU_DELAY 0x0F + +#define LP873X_BUCK1_DELAY_BUCK1_SD_DELAY 0xF0 +#define LP873X_BUCK1_DELAY_BUCK1_SU_DELAY 0x0F + +#define LP873X_LDO0_DELAY_LDO0_SD_DELAY 0xF0 +#define LP873X_LDO0_DELAY_LDO0_SU_DELAY 0x0F + +#define LP873X_LDO1_DELAY_LDO1_SD_DELAY 0xF0 +#define LP873X_LDO1_DELAY_LDO1_SU_DELAY 0x0F + +#define LP873X_GPO_DELAY_GPO_SD_DELAY 0xF0 +#define LP873X_GPO_DELAY_GPO_SU_DELAY 0x0F + +#define LP873X_GPO2_DELAY_GPO2_SD_DELAY 0xF0 +#define LP873X_GPO2_DELAY_GPO2_SU_DELAY 0x0F + +#define LP873X_GPO_CTRL_GPO2_OD BIT(6) +#define LP873X_GPO_CTRL_GPO2_EN_PIN_CTRL BIT(5) +#define LP873X_GPO_CTRL_GPO2_EN BIT(4) +#define LP873X_GPO_CTRL_GPO_OD BIT(2) +#define LP873X_GPO_CTRL_GPO_EN_PIN_CTRL BIT(1) +#define LP873X_GPO_CTRL_GPO_EN BIT(0) + +#define LP873X_CONFIG_SU_DELAY_SEL BIT(6) +#define LP873X_CONFIG_SD_DELAY_SEL BIT(5) +#define LP873X_CONFIG_CLKIN_PIN_SEL BIT(4) +#define LP873X_CONFIG_CLKIN_PD BIT(3) +#define LP873X_CONFIG_EN_PD BIT(2) +#define LP873X_CONFIG_TDIE_WARN_LEVEL BIT(1) +#define LP873X_EN_SPREAD_SPEC BIT(0) + +#define LP873X_PLL_CTRL_EN_PLL BIT(6) +#define LP873X_EXT_CLK_FREQ 0x1F + +#define LP873X_PGOOD_CTRL1_PGOOD_POL BIT(7) +#define LP873X_PGOOD_CTRL1_PGOOD_OD BIT(6) +#define LP873X_PGOOD_CTRL1_PGOOD_WINDOW_LDO BIT(5) +#define LP873X_PGOOD_CTRL1_PGOOD_WINDOWN_BUCK BIT(4) +#define LP873X_PGOOD_CTRL1_PGOOD_EN_PGOOD_LDO1 BIT(3) +#define LP873X_PGOOD_CTRL1_PGOOD_EN_PGOOD_LDO0 BIT(2) +#define LP873X_PGOOD_CTRL1_PGOOD_EN_PGOOD_BUCK1 BIT(1) +#define LP873X_PGOOD_CTRL1_PGOOD_EN_PGOOD_BUCK0 BIT(0) + +#define LP873X_PGOOD_CTRL2_EN_PGOOD_TWARN BIT(2) +#define LP873X_PGOOD_CTRL2_EN_PG_FAULT_GATE BIT(1) +#define LP873X_PGOOD_CTRL2_PGOOD_MODE BIT(0) + +#define LP873X_PG_FAULT_PG_FAULT_LDO1 BIT(3) +#define LP873X_PG_FAULT_PG_FAULT_LDO0 BIT(2) +#define LP873X_PG_FAULT_PG_FAULT_BUCK1 BIT(1) +#define LP873X_PG_FAULT_PG_FAULT_BUCK0 BIT(0) + +#define LP873X_RESET_SW_RESET BIT(0) + +#define LP873X_INT_TOP_1_PGOOD_INT BIT(7) +#define LP873X_INT_TOP_1_LDO_INT BIT(6) +#define LP873X_INT_TOP_1_BUCK_INT BIT(5) +#define LP873X_INT_TOP_1_SYNC_CLK_INT BIT(4) +#define LP873X_INT_TOP_1_TDIE_SD_INT BIT(3) +#define LP873X_INT_TOP_1_TDIE_WARN_INT BIT(2) +#define LP873X_INT_TOP_1_OVP_INT BIT(1) +#define LP873X_INT_TOP_1_I_MEAS_INT BIT(0) + +#define LP873X_INT_TOP_2_RESET_REG_INT BIT(0) + +#define LP873X_INT_BUCK_BUCK1_PG_INT BIT(6) +#define LP873X_INT_BUCK_BUCK1_SC_INT BIT(5) +#define LP873X_INT_BUCK_BUCK1_ILIM_INT BIT(4) +#define LP873X_INT_BUCK_BUCK0_PG_INT BIT(2) +#define LP873X_INT_BUCK_BUCK0_SC_INT BIT(1) +#define LP873X_INT_BUCK_BUCK0_ILIM_INT BIT(0) + +#define LP873X_INT_LDO_LDO1_PG_INT BIT(6) +#define LP873X_INT_LDO_LDO1_SC_INT BIT(5) +#define LP873X_INT_LDO_LDO1_ILIM_INT BIT(4) +#define LP873X_INT_LDO_LDO0_PG_INT BIT(2) +#define LP873X_INT_LDO_LDO0_SC_INT BIT(1) +#define LP873X_INT_LDO_LDO0_ILIM_INT BIT(0) + +#define LP873X_TOP_STAT_PGOOD_STAT BIT(7) +#define LP873X_TOP_STAT_SYNC_CLK_STAT BIT(4) +#define LP873X_TOP_STAT_TDIE_SD_STAT BIT(3) +#define LP873X_TOP_STAT_TDIE_WARN_STAT BIT(2) +#define LP873X_TOP_STAT_OVP_STAT BIT(1) + +#define LP873X_BUCK_STAT_BUCK1_STAT BIT(7) +#define LP873X_BUCK_STAT_BUCK1_PG_STAT BIT(6) +#define LP873X_BUCK_STAT_BUCK1_ILIM_STAT BIT(4) +#define LP873X_BUCK_STAT_BUCK0_STAT BIT(3) +#define LP873X_BUCK_STAT_BUCK0_PG_STAT BIT(2) +#define LP873X_BUCK_STAT_BUCK0_ILIM_STAT BIT(0) + +#define LP873X_LDO_STAT_LDO1_STAT BIT(7) +#define LP873X_LDO_STAT_LDO1_PG_STAT BIT(6) +#define LP873X_LDO_STAT_LDO1_ILIM_STAT BIT(4) +#define LP873X_LDO_STAT_LDO0_STAT BIT(3) +#define LP873X_LDO_STAT_LDO0_PG_STAT BIT(2) +#define LP873X_LDO_STAT_LDO0_ILIM_STAT BIT(0) + +#define LP873X_TOP_MASK_1_PGOOD_INT_MASK BIT(7) +#define LP873X_TOP_MASK_1_SYNC_CLK_MASK BIT(4) +#define LP873X_TOP_MASK_1_TDIE_WARN_MASK BIT(2) +#define LP873X_TOP_MASK_1_I_MEAS_MASK BIT(0) + +#define LP873X_TOP_MASK_2_RESET_REG_MASK BIT(0) + +#define LP873X_BUCK_MASK_BUCK1_PGF_MASK BIT(7) +#define LP873X_BUCK_MASK_BUCK1_PGR_MASK BIT(6) +#define LP873X_BUCK_MASK_BUCK1_ILIM_MASK BIT(4) +#define LP873X_BUCK_MASK_BUCK0_PGF_MASK BIT(3) +#define LP873X_BUCK_MASK_BUCK0_PGR_MASK BIT(2) +#define LP873X_BUCK_MASK_BUCK0_ILIM_MASK BIT(0) + +#define LP873X_LDO_MASK_LDO1_PGF_MASK BIT(7) +#define LP873X_LDO_MASK_LDO1_PGR_MASK BIT(6) +#define LP873X_LDO_MASK_LDO1_ILIM_MASK BIT(4) +#define LP873X_LDO_MASK_LDO0_PGF_MASK BIT(3) +#define LP873X_LDO_MASK_LDO0_PGR_MASK BIT(2) +#define LP873X_LDO_MASK_LDO0_ILIM_MASK BIT(0) + +#define LP873X_SEL_I_LOAD_CURRENT_BUCK_SELECT BIT(0) + +#define LP873X_I_LOAD_2_BUCK_LOAD_CURRENT BIT(0) + +#define LP873X_I_LOAD_1_BUCK_LOAD_CURRENT 0xFF + +#define LP873X_MAX_REG_ID LP873X_LDO_1 + +/* Number of step-down converters available */ +#define LP873X_NUM_BUCK 2 +/* Number of LDO voltage regulators available */ +#define LP873X_NUM_LDO 2 +/* Number of total regulators available */ +#define LP873X_NUM_REGULATOR (LP873X_NUM_BUCK + LP873X_NUM_LDO) + +enum lp873x_regulator_id { + /* BUCK's */ + LP873X_BUCK_0, + LP873X_BUCK_1, + /* LDOs */ + LP873X_LDO_0, + LP873X_LDO_1, +}; + +/** + * struct lp873x - state holder for the lp873x driver + * Device data may be used to access the LP873X chip + */ +struct lp873x { + struct device *dev; + unsigned long id; + u8 rev; + struct mutex lp873_lock; /* lock guarding the data structure */ + struct regmap *regmap; +}; +#endif /* __LINUX_MFD_LP873X_H */ -- 1.9.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/3] mfd: lp873x: Add lp873x PMIC support 2016-05-10 4:04 ` [PATCH v2 2/3] mfd: lp873x: Add lp873x PMIC support Keerthy @ 2016-05-12 13:18 ` Lee Jones 2016-05-12 23:13 ` Keerthy 0 siblings, 1 reply; 13+ messages in thread From: Lee Jones @ 2016-05-12 13:18 UTC (permalink / raw) To: Keerthy Cc: broonie, lgirdwood, linux-kernel, linux-omap, devicetree, robh+dt, mark.rutland On Tue, 10 May 2016, Keerthy wrote: > The LP873X chip is a power management IC for Portable Navigation Systems > and Tablet Computing devices. It contains the following components: > > - Regulators. > - Configurable General Purpose Output Signals(GPO). > > PMIC interacts with the main processor through i2c. PMIC has > couple of LDOs(Linear Regulators), couple of BUCKs (Step-Down DC-DC > Converter Cores) and GPOs(General Purpose Output Signals). At this > time only the regulator functionality is made available. > > Signed-off-by: Keerthy <j-keerthy@ti.com> > --- > > Changes in v2: > > * Used mfd_add_devices instead of of_pltaform_populate. Didn't see this conversation, but of_platform_populate () is usually okay? > drivers/mfd/Kconfig | 15 +++ > drivers/mfd/Makefile | 2 + > drivers/mfd/lp873x.c | 98 +++++++++++++++++ > include/linux/mfd/lp873x.h | 265 +++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 380 insertions(+) > create mode 100644 drivers/mfd/lp873x.c > create mode 100644 include/linux/mfd/lp873x.h > > diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig > index eea61e3..1d85f10 100644 > --- a/drivers/mfd/Kconfig > +++ b/drivers/mfd/Kconfig > @@ -1185,6 +1185,21 @@ config MFD_TPS65217 > This driver can also be built as a module. If so, the module > will be called tps65217. > > +config MFD_LP873X > + tristate "TI LP873X Power Management IC" > + depends on I2C > + select MFD_CORE > + select REGMAP_I2C > + help > + If you say yes here you get support for the LP873X series of > + Power Management Integrated Circuits. > + These include voltage regulators, Thermal protection, Configurable > + general pirpose outputs and other features that are often used in > + portable devices. Please proof read this, including spell check and fix any grammatical errors. "other features" is too vague. Either specify what they are, or don't mention them at all. > + This driver can also be built as a module. If so, the module > + will be called lp873x. > + > config MFD_TPS65218 > tristate "TI TPS65218 Power Management chips" > depends on I2C > diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile > index 5eaa6465d..617c688 100644 > --- a/drivers/mfd/Makefile > +++ b/drivers/mfd/Makefile > @@ -22,6 +22,8 @@ obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o > obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o > obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o > > +obj-$(CONFIG_MFD_LP873X) += lp873x.o > + > obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o > obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o > obj-$(CONFIG_MFD_TI_AM335X_TSCADC) += ti_am335x_tscadc.o > diff --git a/drivers/mfd/lp873x.c b/drivers/mfd/lp873x.c > new file mode 100644 > index 0000000..6046adf > --- /dev/null > +++ b/drivers/mfd/lp873x.c > @@ -0,0 +1,98 @@ > +/* > + * LP873X chip family multi-function driver No need to mention that it's an MFD, it's in drivers/mfd/ so we know that. > + * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ > + * > + * 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 version 2. > + * > + * This program is distributed "as is" WITHOUT ANY WARRANTY of any > + * kind, whether express or implied; without even the implied warranty > + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include <linux/module.h> > +#include <linux/interrupt.h> > +#include <linux/mfd/core.h> > +#include <linux/regmap.h> > +#include <linux/of_device.h> > +#include <linux/mfd/lp873x.h> Alphabetical. > +static const struct regmap_config lp873x_regmap_config = { > + .reg_bits = 8, > + .val_bits = 8, > + .max_register = LP873X_REG_MAX, > +}; > + > +static const struct mfd_cell lp873x_cells[] = { > + { .name = "lp873x-regulator", }, > +}; > + > +static const struct of_device_id of_lp873x_match_table[] = { > + { .compatible = "ti,lp8733", }, > + { .compatible = "ti,lp8732", }, > + {} > +}; > +MODULE_DEVICE_TABLE(of, of_lp873x_match_table); Put this just above where you first make use of it. > +static const struct i2c_device_id lp873x_id_table[] = { > + { "lp873x", LP873X }, > + { "lp8732", LP873X }, > + { "lp8733", LP873X }, > + { }, > +}; > +MODULE_DEVICE_TABLE(i2c, lp873x_id_table); As above. > +static int lp873x_probe(struct i2c_client *client, > + const struct i2c_device_id *ids) > +{ > + struct lp873x *lp873; > + int ret; > + unsigned int otpid; > + > + lp873 = devm_kzalloc(&client->dev, sizeof(*lp873), GFP_KERNEL); > + if (!lp873) > + return -ENOMEM; > + > + i2c_set_clientdata(client, lp873); Move this until just before mfd_add_devices() > + lp873->dev = &client->dev; '\n' here. > + lp873->regmap = devm_regmap_init_i2c(client, &lp873x_regmap_config); > + if (IS_ERR(lp873->regmap)) { > + ret = PTR_ERR(lp873->regmap); > + dev_err(lp873->dev, "Failed to initialize register map: %d\n", > + ret); > + return ret; > + } > + > + mutex_init(&lp873->lp873_lock); > + > + ret = regmap_read(lp873->regmap, LP873X_REG_OTP_REV, &otpid); > + Remove this line. > + if (ret) { > + dev_err(lp873->dev, "Failed to read otpid\n"); "OTP ID" > + return ret; > + } > + > + lp873->rev = otpid & LP873X_OTP_REV_OTP_ID; > + > + ret = mfd_add_devices(lp873->dev, PLATFORM_DEVID_AUTO, lp873x_cells, > + ARRAY_SIZE(lp873x_cells), NULL, 0, NULL); > + > + return ret; > +} > + > +static struct i2c_driver lp873x_driver = { > + .driver = { > + .name = "lp873x", > + .of_match_table = of_lp873x_match_table, > + }, > + .probe = lp873x_probe, > + .id_table = lp873x_id_table, > +}; > +module_i2c_driver(lp873x_driver); > + > +MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>"); > +MODULE_DESCRIPTION("LP873X chip family multi-function driver"); > +MODULE_LICENSE("GPL v2"); > diff --git a/include/linux/mfd/lp873x.h b/include/linux/mfd/lp873x.h > new file mode 100644 > index 0000000..72f6ee9 > --- /dev/null > +++ b/include/linux/mfd/lp873x.h > @@ -0,0 +1,265 @@ > +/* > + * Functions to access LP873X power management chip. > + * > + * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ > + * > + * 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 version 2. > + * > + * This program is distributed "as is" WITHOUT ANY WARRANTY of any > + * kind, whether express or implied; without even the implied warranty > + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#ifndef __LINUX_MFD_LP873X_H > +#define __LINUX_MFD_LP873X_H > + > +#include <linux/i2c.h> > +#include <linux/regulator/driver.h> > +#include <linux/regulator/machine.h> > + > +/* LP873x chip id list */ > +#define LP873X 0x00 > + > +/* All register addresses */ > +#define LP873X_REG_DEV_REV 0X00 > +#define LP873X_REG_OTP_REV 0X01 > +#define LP873X_REG_BUCK0_CTRL_1 0X02 > +#define LP873X_REG_BUCK0_CTRL_2 0X03 > +#define LP873X_REG_BUCK1_CTRL_1 0X04 > +#define LP873X_REG_BUCK1_CTRL_2 0X05 > +#define LP873X_REG_BUCK0_VOUT 0X06 > +#define LP873X_REG_BUCK1_VOUT 0X07 > +#define LP873X_REG_LDO0_CTRL 0X08 > +#define LP873X_REG_LDO1_CTRL 0X09 > +#define LP873X_REG_LDO0_VOUT 0X0A > +#define LP873X_REG_LDO1_VOUT 0X0B > +#define LP873X_REG_BUCK0_DELAY 0X0C > +#define LP873X_REG_BUCK1_DELAY 0X0D > +#define LP873X_REG_LDO0_DELAY 0X0E > +#define LP873X_REG_LDO1_DELAY 0X0F > +#define LP873X_REG_GPO_DELAY 0X10 > +#define LP873X_REG_GPO2_DELAY 0X11 > +#define LP873X_REG_GPO_CTRL 0X12 > +#define LP873X_REG_CONFIG 0X13 > +#define LP873X_REG_PLL_CTRL 0X14 > +#define LP873X_REG_PGOOD_CTRL1 0X15 > +#define LP873X_REG_PGOOD_CTRL2 0X16 > +#define LP873X_REG_PG_FAULT 0X17 > +#define LP873X_REG_RESET 0X18 > +#define LP873X_REG_INT_TOP_1 0X19 > +#define LP873X_REG_INT_TOP_2 0X1A > +#define LP873X_REG_INT_BUCK 0X1B > +#define LP873X_REG_INT_LDO 0X1C > +#define LP873X_REG_TOP_STAT 0X1D > +#define LP873X_REG_BUCK_STAT 0X1E > +#define LP873X_REG_LDO_STAT 0x1F > +#define LP873X_REG_TOP_MASK_1 0x20 > +#define LP873X_REG_TOP_MASK_2 0x21 > +#define LP873X_REG_BUCK_MASK 0x22 > +#define LP873X_REG_LDO_MASK 0x23 > +#define LP873X_REG_SEL_I_LOAD 0x24 > +#define LP873X_REG_I_LOAD_2 0x25 > +#define LP873X_REG_I_LOAD_1 0x26 > + > +#define LP873X_REG_MAX LP873X_REG_I_LOAD_1 > + > +/* Register field definitions */ > +#define LP873X_DEV_REV_DEV_ID 0xC0 > +#define LP873X_DEV_REV_ALL_LAYER 0x30 > +#define LP873X_DEV_REV_METAL_LAYER 0x0F > + > +#define LP873X_OTP_REV_OTP_ID 0xFF > + > +#define LP873X_BUCK0_CTRL_1_BUCK0_FPWM BIT(3) > +#define LP873X_BUCK0_CTRL_1_BUCK0_RDIS_EN BIT(2) > +#define LP873X_BUCK0_CTRL_1_BUCK0_EN_PIN_CTRL BIT(1) > +#define LP873X_BUCK0_CTRL_1_BUCK0_EN BIT(0) > + > +#define LP873X_BUCK0_CTRL_2_BUCK0_ILIM 0x38 > +#define LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE 0x07 > + > +#define LP873X_BUCK1_CTRL_1_BUCK1_FPWM BIT(3) > +#define LP873X_BUCK1_CTRL_1_BUCK1_RDIS_EN BIT(2) > +#define LP873X_BUCK1_CTRL_1_BUCK1_EN_PIN_CTRL BIT(1) > +#define LP873X_BUCK1_CTRL_1_BUCK1_EN BIT(0) > + > +#define LP873X_BUCK1_CTRL_2_BUCK1_ILIM 0x38 > +#define LP873X_BUCK1_CTRL_2_BUCK1_SLEW_RATE 0x07 > + > +#define LP873X_BUCK0_VOUT_BUCK0_VSET 0xFF > + > +#define LP873X_BUCK1_VOUT_BUCK1_VSET 0xFF > + > +#define LP873X_LDO0_CTRL_LDO0_RDIS_EN BIT(2) > +#define LP873X_LDO0_CTRL_LDO0_EN_PIN_CTRL BIT(1) > +#define LP873X_LDO0_CTRL_LDO0_EN BIT(0) > + > +#define LP873X_LDO1_CTRL_LDO1_RDIS_EN BIT(2) > +#define LP873X_LDO1_CTRL_LDO1_EN_PIN_CTRL BIT(1) > +#define LP873X_LDO1_CTRL_LDO1_EN BIT(0) > + > +#define LP873X_LDO0_VOUT_LDO0_VSET 0x1F > + > +#define LP873X_LDO1_VOUT_LDO1_VSET 0x1F > + > +#define LP873X_BUCK0_DELAY_BUCK0_SD_DELAY 0xF0 > +#define LP873X_BUCK0_DELAY_BUCK0_SU_DELAY 0x0F > + > +#define LP873X_BUCK1_DELAY_BUCK1_SD_DELAY 0xF0 > +#define LP873X_BUCK1_DELAY_BUCK1_SU_DELAY 0x0F > + > +#define LP873X_LDO0_DELAY_LDO0_SD_DELAY 0xF0 > +#define LP873X_LDO0_DELAY_LDO0_SU_DELAY 0x0F > + > +#define LP873X_LDO1_DELAY_LDO1_SD_DELAY 0xF0 > +#define LP873X_LDO1_DELAY_LDO1_SU_DELAY 0x0F > + > +#define LP873X_GPO_DELAY_GPO_SD_DELAY 0xF0 > +#define LP873X_GPO_DELAY_GPO_SU_DELAY 0x0F > + > +#define LP873X_GPO2_DELAY_GPO2_SD_DELAY 0xF0 > +#define LP873X_GPO2_DELAY_GPO2_SU_DELAY 0x0F > + > +#define LP873X_GPO_CTRL_GPO2_OD BIT(6) > +#define LP873X_GPO_CTRL_GPO2_EN_PIN_CTRL BIT(5) > +#define LP873X_GPO_CTRL_GPO2_EN BIT(4) > +#define LP873X_GPO_CTRL_GPO_OD BIT(2) > +#define LP873X_GPO_CTRL_GPO_EN_PIN_CTRL BIT(1) > +#define LP873X_GPO_CTRL_GPO_EN BIT(0) > + > +#define LP873X_CONFIG_SU_DELAY_SEL BIT(6) > +#define LP873X_CONFIG_SD_DELAY_SEL BIT(5) > +#define LP873X_CONFIG_CLKIN_PIN_SEL BIT(4) > +#define LP873X_CONFIG_CLKIN_PD BIT(3) > +#define LP873X_CONFIG_EN_PD BIT(2) > +#define LP873X_CONFIG_TDIE_WARN_LEVEL BIT(1) > +#define LP873X_EN_SPREAD_SPEC BIT(0) > + > +#define LP873X_PLL_CTRL_EN_PLL BIT(6) > +#define LP873X_EXT_CLK_FREQ 0x1F > + > +#define LP873X_PGOOD_CTRL1_PGOOD_POL BIT(7) > +#define LP873X_PGOOD_CTRL1_PGOOD_OD BIT(6) > +#define LP873X_PGOOD_CTRL1_PGOOD_WINDOW_LDO BIT(5) > +#define LP873X_PGOOD_CTRL1_PGOOD_WINDOWN_BUCK BIT(4) > +#define LP873X_PGOOD_CTRL1_PGOOD_EN_PGOOD_LDO1 BIT(3) > +#define LP873X_PGOOD_CTRL1_PGOOD_EN_PGOOD_LDO0 BIT(2) > +#define LP873X_PGOOD_CTRL1_PGOOD_EN_PGOOD_BUCK1 BIT(1) > +#define LP873X_PGOOD_CTRL1_PGOOD_EN_PGOOD_BUCK0 BIT(0) > + > +#define LP873X_PGOOD_CTRL2_EN_PGOOD_TWARN BIT(2) > +#define LP873X_PGOOD_CTRL2_EN_PG_FAULT_GATE BIT(1) > +#define LP873X_PGOOD_CTRL2_PGOOD_MODE BIT(0) > + > +#define LP873X_PG_FAULT_PG_FAULT_LDO1 BIT(3) > +#define LP873X_PG_FAULT_PG_FAULT_LDO0 BIT(2) > +#define LP873X_PG_FAULT_PG_FAULT_BUCK1 BIT(1) > +#define LP873X_PG_FAULT_PG_FAULT_BUCK0 BIT(0) > + > +#define LP873X_RESET_SW_RESET BIT(0) > + > +#define LP873X_INT_TOP_1_PGOOD_INT BIT(7) > +#define LP873X_INT_TOP_1_LDO_INT BIT(6) > +#define LP873X_INT_TOP_1_BUCK_INT BIT(5) > +#define LP873X_INT_TOP_1_SYNC_CLK_INT BIT(4) > +#define LP873X_INT_TOP_1_TDIE_SD_INT BIT(3) > +#define LP873X_INT_TOP_1_TDIE_WARN_INT BIT(2) > +#define LP873X_INT_TOP_1_OVP_INT BIT(1) > +#define LP873X_INT_TOP_1_I_MEAS_INT BIT(0) > + > +#define LP873X_INT_TOP_2_RESET_REG_INT BIT(0) > + > +#define LP873X_INT_BUCK_BUCK1_PG_INT BIT(6) > +#define LP873X_INT_BUCK_BUCK1_SC_INT BIT(5) > +#define LP873X_INT_BUCK_BUCK1_ILIM_INT BIT(4) > +#define LP873X_INT_BUCK_BUCK0_PG_INT BIT(2) > +#define LP873X_INT_BUCK_BUCK0_SC_INT BIT(1) > +#define LP873X_INT_BUCK_BUCK0_ILIM_INT BIT(0) > + > +#define LP873X_INT_LDO_LDO1_PG_INT BIT(6) > +#define LP873X_INT_LDO_LDO1_SC_INT BIT(5) > +#define LP873X_INT_LDO_LDO1_ILIM_INT BIT(4) > +#define LP873X_INT_LDO_LDO0_PG_INT BIT(2) > +#define LP873X_INT_LDO_LDO0_SC_INT BIT(1) > +#define LP873X_INT_LDO_LDO0_ILIM_INT BIT(0) > + > +#define LP873X_TOP_STAT_PGOOD_STAT BIT(7) > +#define LP873X_TOP_STAT_SYNC_CLK_STAT BIT(4) > +#define LP873X_TOP_STAT_TDIE_SD_STAT BIT(3) > +#define LP873X_TOP_STAT_TDIE_WARN_STAT BIT(2) > +#define LP873X_TOP_STAT_OVP_STAT BIT(1) > + > +#define LP873X_BUCK_STAT_BUCK1_STAT BIT(7) > +#define LP873X_BUCK_STAT_BUCK1_PG_STAT BIT(6) > +#define LP873X_BUCK_STAT_BUCK1_ILIM_STAT BIT(4) > +#define LP873X_BUCK_STAT_BUCK0_STAT BIT(3) > +#define LP873X_BUCK_STAT_BUCK0_PG_STAT BIT(2) > +#define LP873X_BUCK_STAT_BUCK0_ILIM_STAT BIT(0) > + > +#define LP873X_LDO_STAT_LDO1_STAT BIT(7) > +#define LP873X_LDO_STAT_LDO1_PG_STAT BIT(6) > +#define LP873X_LDO_STAT_LDO1_ILIM_STAT BIT(4) > +#define LP873X_LDO_STAT_LDO0_STAT BIT(3) > +#define LP873X_LDO_STAT_LDO0_PG_STAT BIT(2) > +#define LP873X_LDO_STAT_LDO0_ILIM_STAT BIT(0) > + > +#define LP873X_TOP_MASK_1_PGOOD_INT_MASK BIT(7) > +#define LP873X_TOP_MASK_1_SYNC_CLK_MASK BIT(4) > +#define LP873X_TOP_MASK_1_TDIE_WARN_MASK BIT(2) > +#define LP873X_TOP_MASK_1_I_MEAS_MASK BIT(0) > + > +#define LP873X_TOP_MASK_2_RESET_REG_MASK BIT(0) > + > +#define LP873X_BUCK_MASK_BUCK1_PGF_MASK BIT(7) > +#define LP873X_BUCK_MASK_BUCK1_PGR_MASK BIT(6) > +#define LP873X_BUCK_MASK_BUCK1_ILIM_MASK BIT(4) > +#define LP873X_BUCK_MASK_BUCK0_PGF_MASK BIT(3) > +#define LP873X_BUCK_MASK_BUCK0_PGR_MASK BIT(2) > +#define LP873X_BUCK_MASK_BUCK0_ILIM_MASK BIT(0) > + > +#define LP873X_LDO_MASK_LDO1_PGF_MASK BIT(7) > +#define LP873X_LDO_MASK_LDO1_PGR_MASK BIT(6) > +#define LP873X_LDO_MASK_LDO1_ILIM_MASK BIT(4) > +#define LP873X_LDO_MASK_LDO0_PGF_MASK BIT(3) > +#define LP873X_LDO_MASK_LDO0_PGR_MASK BIT(2) > +#define LP873X_LDO_MASK_LDO0_ILIM_MASK BIT(0) > + > +#define LP873X_SEL_I_LOAD_CURRENT_BUCK_SELECT BIT(0) > + > +#define LP873X_I_LOAD_2_BUCK_LOAD_CURRENT BIT(0) > + > +#define LP873X_I_LOAD_1_BUCK_LOAD_CURRENT 0xFF > + > +#define LP873X_MAX_REG_ID LP873X_LDO_1 > + > +/* Number of step-down converters available */ > +#define LP873X_NUM_BUCK 2 > +/* Number of LDO voltage regulators available */ > +#define LP873X_NUM_LDO 2 > +/* Number of total regulators available */ > +#define LP873X_NUM_REGULATOR (LP873X_NUM_BUCK + LP873X_NUM_LDO) > + > +enum lp873x_regulator_id { > + /* BUCK's */ > + LP873X_BUCK_0, > + LP873X_BUCK_1, > + /* LDOs */ > + LP873X_LDO_0, > + LP873X_LDO_1, > +}; > + > +/** > + * struct lp873x - state holder for the lp873x driver > + * Device data may be used to access the LP873X chip > + */ > +struct lp873x { > + struct device *dev; > + unsigned long id; > + u8 rev; > + struct mutex lp873_lock; /* lock guarding the data structure */ > + struct regmap *regmap; Are all of these used in >1 driver? > +}; > +#endif /* __LINUX_MFD_LP873X_H */ -- Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/3] mfd: lp873x: Add lp873x PMIC support 2016-05-12 13:18 ` Lee Jones @ 2016-05-12 23:13 ` Keerthy 2016-05-17 8:01 ` Lee Jones 0 siblings, 1 reply; 13+ messages in thread From: Keerthy @ 2016-05-12 23:13 UTC (permalink / raw) To: Lee Jones, Keerthy Cc: broonie, lgirdwood, linux-kernel, linux-omap, devicetree, robh+dt, mark.rutland Hi Lee Jones, On Thursday 12 May 2016 06:48 PM, Lee Jones wrote: > On Tue, 10 May 2016, Keerthy wrote: > >> The LP873X chip is a power management IC for Portable Navigation Systems >> and Tablet Computing devices. It contains the following components: >> >> - Regulators. >> - Configurable General Purpose Output Signals(GPO). >> >> PMIC interacts with the main processor through i2c. PMIC has >> couple of LDOs(Linear Regulators), couple of BUCKs (Step-Down DC-DC >> Converter Cores) and GPOs(General Purpose Output Signals). At this >> time only the regulator functionality is made available. >> >> Signed-off-by: Keerthy <j-keerthy@ti.com> >> --- >> >> Changes in v2: >> >> * Used mfd_add_devices instead of of_pltaform_populate. > > Didn't see this conversation, but of_platform_populate () is usually > okay? https://lkml.org/lkml/2016/5/6/244. > >> drivers/mfd/Kconfig | 15 +++ >> drivers/mfd/Makefile | 2 + >> drivers/mfd/lp873x.c | 98 +++++++++++++++++ >> include/linux/mfd/lp873x.h | 265 +++++++++++++++++++++++++++++++++++++++++++++ >> 4 files changed, 380 insertions(+) >> create mode 100644 drivers/mfd/lp873x.c >> create mode 100644 include/linux/mfd/lp873x.h >> >> diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig >> index eea61e3..1d85f10 100644 >> --- a/drivers/mfd/Kconfig >> +++ b/drivers/mfd/Kconfig >> @@ -1185,6 +1185,21 @@ config MFD_TPS65217 >> This driver can also be built as a module. If so, the module >> will be called tps65217. >> >> +config MFD_LP873X >> + tristate "TI LP873X Power Management IC" >> + depends on I2C >> + select MFD_CORE >> + select REGMAP_I2C >> + help >> + If you say yes here you get support for the LP873X series of >> + Power Management Integrated Circuits. >> + These include voltage regulators, Thermal protection, Configurable >> + general pirpose outputs and other features that are often used in >> + portable devices. > > Please proof read this, including spell check and fix any grammatical > errors. > > "other features" is too vague. Either specify what they are, or > don't mention them at all. Sure. > >> + This driver can also be built as a module. If so, the module >> + will be called lp873x. >> + >> config MFD_TPS65218 >> tristate "TI TPS65218 Power Management chips" >> depends on I2C >> diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile >> index 5eaa6465d..617c688 100644 >> --- a/drivers/mfd/Makefile >> +++ b/drivers/mfd/Makefile >> @@ -22,6 +22,8 @@ obj-$(CONFIG_HTC_EGPIO) += htc-egpio.o >> obj-$(CONFIG_HTC_PASIC3) += htc-pasic3.o >> obj-$(CONFIG_HTC_I2CPLD) += htc-i2cpld.o >> >> +obj-$(CONFIG_MFD_LP873X) += lp873x.o >> + >> obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o >> obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o >> obj-$(CONFIG_MFD_TI_AM335X_TSCADC) += ti_am335x_tscadc.o >> diff --git a/drivers/mfd/lp873x.c b/drivers/mfd/lp873x.c >> new file mode 100644 >> index 0000000..6046adf >> --- /dev/null >> +++ b/drivers/mfd/lp873x.c >> @@ -0,0 +1,98 @@ >> +/* >> + * LP873X chip family multi-function driver > > No need to mention that it's an MFD, it's in drivers/mfd/ so we know > that. Okay. > >> + * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ >> + * >> + * 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 version 2. >> + * >> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any >> + * kind, whether express or implied; without even the implied warranty >> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + */ >> + >> +#include <linux/module.h> >> +#include <linux/interrupt.h> >> +#include <linux/mfd/core.h> >> +#include <linux/regmap.h> >> +#include <linux/of_device.h> >> +#include <linux/mfd/lp873x.h> > > Alphabetical. Okay. > >> +static const struct regmap_config lp873x_regmap_config = { >> + .reg_bits = 8, >> + .val_bits = 8, >> + .max_register = LP873X_REG_MAX, >> +}; >> + >> +static const struct mfd_cell lp873x_cells[] = { >> + { .name = "lp873x-regulator", }, >> +}; >> + >> +static const struct of_device_id of_lp873x_match_table[] = { >> + { .compatible = "ti,lp8733", }, >> + { .compatible = "ti,lp8732", }, >> + {} >> +}; >> +MODULE_DEVICE_TABLE(of, of_lp873x_match_table); > > Put this just above where you first make use of it. > >> +static const struct i2c_device_id lp873x_id_table[] = { >> + { "lp873x", LP873X }, >> + { "lp8732", LP873X }, >> + { "lp8733", LP873X }, >> + { }, >> +}; >> +MODULE_DEVICE_TABLE(i2c, lp873x_id_table); > > As above. Okay. > >> +static int lp873x_probe(struct i2c_client *client, >> + const struct i2c_device_id *ids) >> +{ >> + struct lp873x *lp873; >> + int ret; >> + unsigned int otpid; >> + >> + lp873 = devm_kzalloc(&client->dev, sizeof(*lp873), GFP_KERNEL); >> + if (!lp873) >> + return -ENOMEM; >> + >> + i2c_set_clientdata(client, lp873); > > Move this until just before mfd_add_devices() Okay. > >> + lp873->dev = &client->dev; > > '\n' here. > >> + lp873->regmap = devm_regmap_init_i2c(client, &lp873x_regmap_config); >> + if (IS_ERR(lp873->regmap)) { >> + ret = PTR_ERR(lp873->regmap); >> + dev_err(lp873->dev, "Failed to initialize register map: %d\n", >> + ret); >> + return ret; >> + } >> + >> + mutex_init(&lp873->lp873_lock); >> + >> + ret = regmap_read(lp873->regmap, LP873X_REG_OTP_REV, &otpid); >> + > > Remove this line. Okay > >> + if (ret) { >> + dev_err(lp873->dev, "Failed to read otpid\n"); > > "OTP ID" > >> + return ret; >> + } >> + >> + lp873->rev = otpid & LP873X_OTP_REV_OTP_ID; >> + >> + ret = mfd_add_devices(lp873->dev, PLATFORM_DEVID_AUTO, lp873x_cells, >> + ARRAY_SIZE(lp873x_cells), NULL, 0, NULL); >> + >> + return ret; >> +} >> + >> +static struct i2c_driver lp873x_driver = { >> + .driver = { >> + .name = "lp873x", >> + .of_match_table = of_lp873x_match_table, >> + }, >> + .probe = lp873x_probe, >> + .id_table = lp873x_id_table, >> +}; >> +module_i2c_driver(lp873x_driver); >> + >> +MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>"); >> +MODULE_DESCRIPTION("LP873X chip family multi-function driver"); >> +MODULE_LICENSE("GPL v2"); >> diff --git a/include/linux/mfd/lp873x.h b/include/linux/mfd/lp873x.h >> new file mode 100644 >> index 0000000..72f6ee9 >> --- /dev/null >> +++ b/include/linux/mfd/lp873x.h >> @@ -0,0 +1,265 @@ >> +/* >> + * Functions to access LP873X power management chip. >> + * >> + * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ >> + * >> + * 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 version 2. >> + * >> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any >> + * kind, whether express or implied; without even the implied warranty >> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + */ >> + >> +#ifndef __LINUX_MFD_LP873X_H >> +#define __LINUX_MFD_LP873X_H >> + >> +#include <linux/i2c.h> >> +#include <linux/regulator/driver.h> >> +#include <linux/regulator/machine.h> >> + >> +/* LP873x chip id list */ >> +#define LP873X 0x00 >> + >> +/* All register addresses */ >> +#define LP873X_REG_DEV_REV 0X00 >> +#define LP873X_REG_OTP_REV 0X01 >> +#define LP873X_REG_BUCK0_CTRL_1 0X02 >> +#define LP873X_REG_BUCK0_CTRL_2 0X03 >> +#define LP873X_REG_BUCK1_CTRL_1 0X04 >> +#define LP873X_REG_BUCK1_CTRL_2 0X05 >> +#define LP873X_REG_BUCK0_VOUT 0X06 >> +#define LP873X_REG_BUCK1_VOUT 0X07 >> +#define LP873X_REG_LDO0_CTRL 0X08 >> +#define LP873X_REG_LDO1_CTRL 0X09 >> +#define LP873X_REG_LDO0_VOUT 0X0A >> +#define LP873X_REG_LDO1_VOUT 0X0B >> +#define LP873X_REG_BUCK0_DELAY 0X0C >> +#define LP873X_REG_BUCK1_DELAY 0X0D >> +#define LP873X_REG_LDO0_DELAY 0X0E >> +#define LP873X_REG_LDO1_DELAY 0X0F >> +#define LP873X_REG_GPO_DELAY 0X10 >> +#define LP873X_REG_GPO2_DELAY 0X11 >> +#define LP873X_REG_GPO_CTRL 0X12 >> +#define LP873X_REG_CONFIG 0X13 >> +#define LP873X_REG_PLL_CTRL 0X14 >> +#define LP873X_REG_PGOOD_CTRL1 0X15 >> +#define LP873X_REG_PGOOD_CTRL2 0X16 >> +#define LP873X_REG_PG_FAULT 0X17 >> +#define LP873X_REG_RESET 0X18 >> +#define LP873X_REG_INT_TOP_1 0X19 >> +#define LP873X_REG_INT_TOP_2 0X1A >> +#define LP873X_REG_INT_BUCK 0X1B >> +#define LP873X_REG_INT_LDO 0X1C >> +#define LP873X_REG_TOP_STAT 0X1D >> +#define LP873X_REG_BUCK_STAT 0X1E >> +#define LP873X_REG_LDO_STAT 0x1F >> +#define LP873X_REG_TOP_MASK_1 0x20 >> +#define LP873X_REG_TOP_MASK_2 0x21 >> +#define LP873X_REG_BUCK_MASK 0x22 >> +#define LP873X_REG_LDO_MASK 0x23 >> +#define LP873X_REG_SEL_I_LOAD 0x24 >> +#define LP873X_REG_I_LOAD_2 0x25 >> +#define LP873X_REG_I_LOAD_1 0x26 >> + >> +#define LP873X_REG_MAX LP873X_REG_I_LOAD_1 >> + >> +/* Register field definitions */ >> +#define LP873X_DEV_REV_DEV_ID 0xC0 >> +#define LP873X_DEV_REV_ALL_LAYER 0x30 >> +#define LP873X_DEV_REV_METAL_LAYER 0x0F >> + >> +#define LP873X_OTP_REV_OTP_ID 0xFF >> + >> +#define LP873X_BUCK0_CTRL_1_BUCK0_FPWM BIT(3) >> +#define LP873X_BUCK0_CTRL_1_BUCK0_RDIS_EN BIT(2) >> +#define LP873X_BUCK0_CTRL_1_BUCK0_EN_PIN_CTRL BIT(1) >> +#define LP873X_BUCK0_CTRL_1_BUCK0_EN BIT(0) >> + >> +#define LP873X_BUCK0_CTRL_2_BUCK0_ILIM 0x38 >> +#define LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE 0x07 >> + >> +#define LP873X_BUCK1_CTRL_1_BUCK1_FPWM BIT(3) >> +#define LP873X_BUCK1_CTRL_1_BUCK1_RDIS_EN BIT(2) >> +#define LP873X_BUCK1_CTRL_1_BUCK1_EN_PIN_CTRL BIT(1) >> +#define LP873X_BUCK1_CTRL_1_BUCK1_EN BIT(0) >> + >> +#define LP873X_BUCK1_CTRL_2_BUCK1_ILIM 0x38 >> +#define LP873X_BUCK1_CTRL_2_BUCK1_SLEW_RATE 0x07 >> + >> +#define LP873X_BUCK0_VOUT_BUCK0_VSET 0xFF >> + >> +#define LP873X_BUCK1_VOUT_BUCK1_VSET 0xFF >> + >> +#define LP873X_LDO0_CTRL_LDO0_RDIS_EN BIT(2) >> +#define LP873X_LDO0_CTRL_LDO0_EN_PIN_CTRL BIT(1) >> +#define LP873X_LDO0_CTRL_LDO0_EN BIT(0) >> + >> +#define LP873X_LDO1_CTRL_LDO1_RDIS_EN BIT(2) >> +#define LP873X_LDO1_CTRL_LDO1_EN_PIN_CTRL BIT(1) >> +#define LP873X_LDO1_CTRL_LDO1_EN BIT(0) >> + >> +#define LP873X_LDO0_VOUT_LDO0_VSET 0x1F >> + >> +#define LP873X_LDO1_VOUT_LDO1_VSET 0x1F >> + >> +#define LP873X_BUCK0_DELAY_BUCK0_SD_DELAY 0xF0 >> +#define LP873X_BUCK0_DELAY_BUCK0_SU_DELAY 0x0F >> + >> +#define LP873X_BUCK1_DELAY_BUCK1_SD_DELAY 0xF0 >> +#define LP873X_BUCK1_DELAY_BUCK1_SU_DELAY 0x0F >> + >> +#define LP873X_LDO0_DELAY_LDO0_SD_DELAY 0xF0 >> +#define LP873X_LDO0_DELAY_LDO0_SU_DELAY 0x0F >> + >> +#define LP873X_LDO1_DELAY_LDO1_SD_DELAY 0xF0 >> +#define LP873X_LDO1_DELAY_LDO1_SU_DELAY 0x0F >> + >> +#define LP873X_GPO_DELAY_GPO_SD_DELAY 0xF0 >> +#define LP873X_GPO_DELAY_GPO_SU_DELAY 0x0F >> + >> +#define LP873X_GPO2_DELAY_GPO2_SD_DELAY 0xF0 >> +#define LP873X_GPO2_DELAY_GPO2_SU_DELAY 0x0F >> + >> +#define LP873X_GPO_CTRL_GPO2_OD BIT(6) >> +#define LP873X_GPO_CTRL_GPO2_EN_PIN_CTRL BIT(5) >> +#define LP873X_GPO_CTRL_GPO2_EN BIT(4) >> +#define LP873X_GPO_CTRL_GPO_OD BIT(2) >> +#define LP873X_GPO_CTRL_GPO_EN_PIN_CTRL BIT(1) >> +#define LP873X_GPO_CTRL_GPO_EN BIT(0) >> + >> +#define LP873X_CONFIG_SU_DELAY_SEL BIT(6) >> +#define LP873X_CONFIG_SD_DELAY_SEL BIT(5) >> +#define LP873X_CONFIG_CLKIN_PIN_SEL BIT(4) >> +#define LP873X_CONFIG_CLKIN_PD BIT(3) >> +#define LP873X_CONFIG_EN_PD BIT(2) >> +#define LP873X_CONFIG_TDIE_WARN_LEVEL BIT(1) >> +#define LP873X_EN_SPREAD_SPEC BIT(0) >> + >> +#define LP873X_PLL_CTRL_EN_PLL BIT(6) >> +#define LP873X_EXT_CLK_FREQ 0x1F >> + >> +#define LP873X_PGOOD_CTRL1_PGOOD_POL BIT(7) >> +#define LP873X_PGOOD_CTRL1_PGOOD_OD BIT(6) >> +#define LP873X_PGOOD_CTRL1_PGOOD_WINDOW_LDO BIT(5) >> +#define LP873X_PGOOD_CTRL1_PGOOD_WINDOWN_BUCK BIT(4) >> +#define LP873X_PGOOD_CTRL1_PGOOD_EN_PGOOD_LDO1 BIT(3) >> +#define LP873X_PGOOD_CTRL1_PGOOD_EN_PGOOD_LDO0 BIT(2) >> +#define LP873X_PGOOD_CTRL1_PGOOD_EN_PGOOD_BUCK1 BIT(1) >> +#define LP873X_PGOOD_CTRL1_PGOOD_EN_PGOOD_BUCK0 BIT(0) >> + >> +#define LP873X_PGOOD_CTRL2_EN_PGOOD_TWARN BIT(2) >> +#define LP873X_PGOOD_CTRL2_EN_PG_FAULT_GATE BIT(1) >> +#define LP873X_PGOOD_CTRL2_PGOOD_MODE BIT(0) >> + >> +#define LP873X_PG_FAULT_PG_FAULT_LDO1 BIT(3) >> +#define LP873X_PG_FAULT_PG_FAULT_LDO0 BIT(2) >> +#define LP873X_PG_FAULT_PG_FAULT_BUCK1 BIT(1) >> +#define LP873X_PG_FAULT_PG_FAULT_BUCK0 BIT(0) >> + >> +#define LP873X_RESET_SW_RESET BIT(0) >> + >> +#define LP873X_INT_TOP_1_PGOOD_INT BIT(7) >> +#define LP873X_INT_TOP_1_LDO_INT BIT(6) >> +#define LP873X_INT_TOP_1_BUCK_INT BIT(5) >> +#define LP873X_INT_TOP_1_SYNC_CLK_INT BIT(4) >> +#define LP873X_INT_TOP_1_TDIE_SD_INT BIT(3) >> +#define LP873X_INT_TOP_1_TDIE_WARN_INT BIT(2) >> +#define LP873X_INT_TOP_1_OVP_INT BIT(1) >> +#define LP873X_INT_TOP_1_I_MEAS_INT BIT(0) >> + >> +#define LP873X_INT_TOP_2_RESET_REG_INT BIT(0) >> + >> +#define LP873X_INT_BUCK_BUCK1_PG_INT BIT(6) >> +#define LP873X_INT_BUCK_BUCK1_SC_INT BIT(5) >> +#define LP873X_INT_BUCK_BUCK1_ILIM_INT BIT(4) >> +#define LP873X_INT_BUCK_BUCK0_PG_INT BIT(2) >> +#define LP873X_INT_BUCK_BUCK0_SC_INT BIT(1) >> +#define LP873X_INT_BUCK_BUCK0_ILIM_INT BIT(0) >> + >> +#define LP873X_INT_LDO_LDO1_PG_INT BIT(6) >> +#define LP873X_INT_LDO_LDO1_SC_INT BIT(5) >> +#define LP873X_INT_LDO_LDO1_ILIM_INT BIT(4) >> +#define LP873X_INT_LDO_LDO0_PG_INT BIT(2) >> +#define LP873X_INT_LDO_LDO0_SC_INT BIT(1) >> +#define LP873X_INT_LDO_LDO0_ILIM_INT BIT(0) >> + >> +#define LP873X_TOP_STAT_PGOOD_STAT BIT(7) >> +#define LP873X_TOP_STAT_SYNC_CLK_STAT BIT(4) >> +#define LP873X_TOP_STAT_TDIE_SD_STAT BIT(3) >> +#define LP873X_TOP_STAT_TDIE_WARN_STAT BIT(2) >> +#define LP873X_TOP_STAT_OVP_STAT BIT(1) >> + >> +#define LP873X_BUCK_STAT_BUCK1_STAT BIT(7) >> +#define LP873X_BUCK_STAT_BUCK1_PG_STAT BIT(6) >> +#define LP873X_BUCK_STAT_BUCK1_ILIM_STAT BIT(4) >> +#define LP873X_BUCK_STAT_BUCK0_STAT BIT(3) >> +#define LP873X_BUCK_STAT_BUCK0_PG_STAT BIT(2) >> +#define LP873X_BUCK_STAT_BUCK0_ILIM_STAT BIT(0) >> + >> +#define LP873X_LDO_STAT_LDO1_STAT BIT(7) >> +#define LP873X_LDO_STAT_LDO1_PG_STAT BIT(6) >> +#define LP873X_LDO_STAT_LDO1_ILIM_STAT BIT(4) >> +#define LP873X_LDO_STAT_LDO0_STAT BIT(3) >> +#define LP873X_LDO_STAT_LDO0_PG_STAT BIT(2) >> +#define LP873X_LDO_STAT_LDO0_ILIM_STAT BIT(0) >> + >> +#define LP873X_TOP_MASK_1_PGOOD_INT_MASK BIT(7) >> +#define LP873X_TOP_MASK_1_SYNC_CLK_MASK BIT(4) >> +#define LP873X_TOP_MASK_1_TDIE_WARN_MASK BIT(2) >> +#define LP873X_TOP_MASK_1_I_MEAS_MASK BIT(0) >> + >> +#define LP873X_TOP_MASK_2_RESET_REG_MASK BIT(0) >> + >> +#define LP873X_BUCK_MASK_BUCK1_PGF_MASK BIT(7) >> +#define LP873X_BUCK_MASK_BUCK1_PGR_MASK BIT(6) >> +#define LP873X_BUCK_MASK_BUCK1_ILIM_MASK BIT(4) >> +#define LP873X_BUCK_MASK_BUCK0_PGF_MASK BIT(3) >> +#define LP873X_BUCK_MASK_BUCK0_PGR_MASK BIT(2) >> +#define LP873X_BUCK_MASK_BUCK0_ILIM_MASK BIT(0) >> + >> +#define LP873X_LDO_MASK_LDO1_PGF_MASK BIT(7) >> +#define LP873X_LDO_MASK_LDO1_PGR_MASK BIT(6) >> +#define LP873X_LDO_MASK_LDO1_ILIM_MASK BIT(4) >> +#define LP873X_LDO_MASK_LDO0_PGF_MASK BIT(3) >> +#define LP873X_LDO_MASK_LDO0_PGR_MASK BIT(2) >> +#define LP873X_LDO_MASK_LDO0_ILIM_MASK BIT(0) >> + >> +#define LP873X_SEL_I_LOAD_CURRENT_BUCK_SELECT BIT(0) >> + >> +#define LP873X_I_LOAD_2_BUCK_LOAD_CURRENT BIT(0) >> + >> +#define LP873X_I_LOAD_1_BUCK_LOAD_CURRENT 0xFF >> + >> +#define LP873X_MAX_REG_ID LP873X_LDO_1 >> + >> +/* Number of step-down converters available */ >> +#define LP873X_NUM_BUCK 2 >> +/* Number of LDO voltage regulators available */ >> +#define LP873X_NUM_LDO 2 >> +/* Number of total regulators available */ >> +#define LP873X_NUM_REGULATOR (LP873X_NUM_BUCK + LP873X_NUM_LDO) >> + >> +enum lp873x_regulator_id { >> + /* BUCK's */ >> + LP873X_BUCK_0, >> + LP873X_BUCK_1, >> + /* LDOs */ >> + LP873X_LDO_0, >> + LP873X_LDO_1, >> +}; >> + >> +/** >> + * struct lp873x - state holder for the lp873x driver >> + * Device data may be used to access the LP873X chip >> + */ >> +struct lp873x { >> + struct device *dev; >> + unsigned long id; >> + u8 rev; >> + struct mutex lp873_lock; /* lock guarding the data structure */ >> + struct regmap *regmap; > > Are all of these used in >1 driver? Apart from id and rev all are used. > >> +}; >> +#endif /* __LINUX_MFD_LP873X_H */ > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/3] mfd: lp873x: Add lp873x PMIC support 2016-05-12 23:13 ` Keerthy @ 2016-05-17 8:01 ` Lee Jones 2016-05-17 8:04 ` Keerthy 0 siblings, 1 reply; 13+ messages in thread From: Lee Jones @ 2016-05-17 8:01 UTC (permalink / raw) To: Keerthy Cc: Keerthy, broonie, lgirdwood, linux-kernel, linux-omap, devicetree, robh+dt, mark.rutland On Fri, 13 May 2016, Keerthy wrote: > On Thursday 12 May 2016 06:48 PM, Lee Jones wrote: > >On Tue, 10 May 2016, Keerthy wrote: > > > >>The LP873X chip is a power management IC for Portable Navigation Systems > >> and Tablet Computing devices. It contains the following components: > >> > >> - Regulators. > >> - Configurable General Purpose Output Signals(GPO). > >> > >>PMIC interacts with the main processor through i2c. PMIC has > >>couple of LDOs(Linear Regulators), couple of BUCKs (Step-Down DC-DC > >>Converter Cores) and GPOs(General Purpose Output Signals). At this > >>time only the regulator functionality is made available. > >> > >>Signed-off-by: Keerthy <j-keerthy@ti.com> > >>--- > >> > >>Changes in v2: > >> > >> * Used mfd_add_devices instead of of_pltaform_populate. > > > >Didn't see this conversation, but of_platform_populate () is usually > >okay? > > https://lkml.org/lkml/2016/5/6/244. Did Mark tell you why you shouldn't be using it? > >> drivers/mfd/Kconfig | 15 +++ > >> drivers/mfd/Makefile | 2 + > >> drivers/mfd/lp873x.c | 98 +++++++++++++++++ > >> include/linux/mfd/lp873x.h | 265 +++++++++++++++++++++++++++++++++++++++++++++ > >> 4 files changed, 380 insertions(+) > >> create mode 100644 drivers/mfd/lp873x.c > >> create mode 100644 include/linux/mfd/lp873x.h [...] > >>+/** > >>+ * struct lp873x - state holder for the lp873x driver > >>+ * Device data may be used to access the LP873X chip > >>+ */ > >>+struct lp873x { > >>+ struct device *dev; > >>+ unsigned long id; > >>+ u8 rev; > >>+ struct mutex lp873_lock; /* lock guarding the data structure */ > >>+ struct regmap *regmap; > > > >Are all of these used in >1 driver? > > Apart from id and rev all are used. Then why are id and rev in there? -- Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/3] mfd: lp873x: Add lp873x PMIC support 2016-05-17 8:01 ` Lee Jones @ 2016-05-17 8:04 ` Keerthy 2016-05-17 8:07 ` Keerthy 0 siblings, 1 reply; 13+ messages in thread From: Keerthy @ 2016-05-17 8:04 UTC (permalink / raw) To: Lee Jones Cc: Keerthy, broonie, lgirdwood, linux-kernel, linux-omap, devicetree, robh+dt, mark.rutland On Tuesday 17 May 2016 01:31 PM, Lee Jones wrote: > On Fri, 13 May 2016, Keerthy wrote: >> On Thursday 12 May 2016 06:48 PM, Lee Jones wrote: >>> On Tue, 10 May 2016, Keerthy wrote: >>> >>>> The LP873X chip is a power management IC for Portable Navigation Systems >>>> and Tablet Computing devices. It contains the following components: >>>> >>>> - Regulators. >>>> - Configurable General Purpose Output Signals(GPO). >>>> >>>> PMIC interacts with the main processor through i2c. PMIC has >>>> couple of LDOs(Linear Regulators), couple of BUCKs (Step-Down DC-DC >>>> Converter Cores) and GPOs(General Purpose Output Signals). At this >>>> time only the regulator functionality is made available. >>>> >>>> Signed-off-by: Keerthy <j-keerthy@ti.com> >>>> --- >>>> >>>> Changes in v2: >>>> >>>> * Used mfd_add_devices instead of of_pltaform_populate. >>> >>> Didn't see this conversation, but of_platform_populate () is usually >>> okay? >> >> https://lkml.org/lkml/2016/5/6/244. > > Did Mark tell you why you shouldn't be using it? "You shouldn't be using that, you should just have a table of subdevices in the MFD" I inferred not to use of_platform_populate and make use of mfd_add_devices instead. Please correct me if am wrong. > >>>> drivers/mfd/Kconfig | 15 +++ >>>> drivers/mfd/Makefile | 2 + >>>> drivers/mfd/lp873x.c | 98 +++++++++++++++++ >>>> include/linux/mfd/lp873x.h | 265 +++++++++++++++++++++++++++++++++++++++++++++ >>>> 4 files changed, 380 insertions(+) >>>> create mode 100644 drivers/mfd/lp873x.c >>>> create mode 100644 include/linux/mfd/lp873x.h > > [...] > >>>> +/** >>>> + * struct lp873x - state holder for the lp873x driver >>>> + * Device data may be used to access the LP873X chip >>>> + */ >>>> +struct lp873x { >>>> + struct device *dev; >>>> + unsigned long id; >>>> + u8 rev; >>>> + struct mutex lp873_lock; /* lock guarding the data structure */ >>>> + struct regmap *regmap; >>> >>> Are all of these used in >1 driver? >> >> Apart from id and rev all are used. > > Then why are id and rev in there? > ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v2 2/3] mfd: lp873x: Add lp873x PMIC support 2016-05-17 8:04 ` Keerthy @ 2016-05-17 8:07 ` Keerthy 0 siblings, 0 replies; 13+ messages in thread From: Keerthy @ 2016-05-17 8:07 UTC (permalink / raw) To: Lee Jones Cc: Keerthy, broonie, lgirdwood, linux-kernel, linux-omap, devicetree, robh+dt, mark.rutland On Tuesday 17 May 2016 01:34 PM, Keerthy wrote: > > > On Tuesday 17 May 2016 01:31 PM, Lee Jones wrote: >> On Fri, 13 May 2016, Keerthy wrote: >>> On Thursday 12 May 2016 06:48 PM, Lee Jones wrote: >>>> On Tue, 10 May 2016, Keerthy wrote: >>>> >>>>> The LP873X chip is a power management IC for Portable Navigation >>>>> Systems >>>>> and Tablet Computing devices. It contains the following >>>>> components: >>>>> >>>>> - Regulators. >>>>> - Configurable General Purpose Output Signals(GPO). >>>>> >>>>> PMIC interacts with the main processor through i2c. PMIC has >>>>> couple of LDOs(Linear Regulators), couple of BUCKs (Step-Down DC-DC >>>>> Converter Cores) and GPOs(General Purpose Output Signals). At this >>>>> time only the regulator functionality is made available. >>>>> >>>>> Signed-off-by: Keerthy <j-keerthy@ti.com> >>>>> --- >>>>> >>>>> Changes in v2: >>>>> >>>>> * Used mfd_add_devices instead of of_pltaform_populate. >>>> >>>> Didn't see this conversation, but of_platform_populate () is usually >>>> okay? >>> >>> https://lkml.org/lkml/2016/5/6/244. >> >> Did Mark tell you why you shouldn't be using it? > > "You shouldn't be using that, you should just have a table of subdevices > in the MFD" > > I inferred not to use of_platform_populate and make use of > mfd_add_devices instead. > > Please correct me if am wrong. To answer why, Here is what Mark told: https://lkml.org/lkml/2016/5/6/7 > >> >>>>> drivers/mfd/Kconfig | 15 +++ >>>>> drivers/mfd/Makefile | 2 + >>>>> drivers/mfd/lp873x.c | 98 +++++++++++++++++ >>>>> include/linux/mfd/lp873x.h | 265 >>>>> +++++++++++++++++++++++++++++++++++++++++++++ >>>>> 4 files changed, 380 insertions(+) >>>>> create mode 100644 drivers/mfd/lp873x.c >>>>> create mode 100644 include/linux/mfd/lp873x.h >> >> [...] >> >>>>> +/** >>>>> + * struct lp873x - state holder for the lp873x driver >>>>> + * Device data may be used to access the LP873X chip >>>>> + */ >>>>> +struct lp873x { >>>>> + struct device *dev; >>>>> + unsigned long id; >>>>> + u8 rev; >>>>> + struct mutex lp873_lock; /* lock guarding the data >>>>> structure */ >>>>> + struct regmap *regmap; >>>> >>>> Are all of these used in >1 driver? >>> >>> Apart from id and rev all are used. >> >> Then why are id and rev in there? >> ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v2 3/3] regulator: lp873x: Add support for lp873x PMIC regulators 2016-05-10 4:04 [PATCH v2 0/3] mfd: lp873x: Add lp873x PMIC support Keerthy 2016-05-10 4:04 ` [PATCH v2 1/3] Documentation: mfd: LP873X: Add information for the mfd and regulator drivers Keerthy 2016-05-10 4:04 ` [PATCH v2 2/3] mfd: lp873x: Add lp873x PMIC support Keerthy @ 2016-05-10 4:04 ` Keerthy 2016-05-11 17:27 ` Applied "regulator: lp873x: Add support for lp873x PMIC regulators" to the regulator tree Mark Brown 2 siblings, 1 reply; 13+ messages in thread From: Keerthy @ 2016-05-10 4:04 UTC (permalink / raw) To: broonie, lgirdwood, lee.jones Cc: linux-kernel, linux-omap, devicetree, robh+dt, mark.rutland, j-keerthy The regulators set consists of 2 BUCKs and 2 LDOs. The output voltages are configurable and are meant to supply power to the main processor and other components. The ramp delay is configurable for both BUCKs. Signed-off-by: Keerthy <j-keerthy@ti.com> --- Changes in v2: * Removed all compatibles and introduced an id_table. drivers/regulator/Kconfig | 9 ++ drivers/regulator/Makefile | 1 + drivers/regulator/lp873x-regulator.c | 241 +++++++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+) create mode 100644 drivers/regulator/lp873x-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index c77dc08..4d2d737 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -321,6 +321,15 @@ config REGULATOR_LP872X help This driver supports LP8720/LP8725 PMIC +config REGULATOR_LP873X + tristate "TI LP873X Power regulators" + depends on MFD_LP873X && OF + help + This driver supports LP873X voltage regulator chips. LP873X + provides two step-down converters and two general-purpose LDO + voltage regulators. It supports software based voltage control + for different voltage domains + config REGULATOR_LP8755 tristate "TI LP8755 High Performance PMU driver" depends on I2C diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 61bfbb9..7182b5f 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_REGULATOR_LM363X) += lm363x-regulator.o obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o +obj-$(CONFIG_REGULATOR_LP873X) += lp873x-regulator.o obj-$(CONFIG_REGULATOR_LP8788) += lp8788-buck.o obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o diff --git a/drivers/regulator/lp873x-regulator.c b/drivers/regulator/lp873x-regulator.c new file mode 100644 index 0000000..b4ffd11 --- /dev/null +++ b/drivers/regulator/lp873x-regulator.c @@ -0,0 +1,241 @@ +/* + * Regulator driver for LP873X PMIC + * + * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether expressed or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License version 2 for more details. + */ + +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <linux/mfd/lp873x.h> + +#define LP873X_REGULATOR(_name, _id, _of, _ops, _n, _vr, _vm, _er, _em, \ + _delay, _lr, _nlr, _cr) \ + [_id] = { \ + .desc = { \ + .name = _name, \ + .id = _id, \ + .of_match = of_match_ptr(_of), \ + .regulators_node = of_match_ptr("regulators"),\ + .ops = &_ops, \ + .n_voltages = _n, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .vsel_reg = _vr, \ + .vsel_mask = _vm, \ + .enable_reg = _er, \ + .enable_mask = _em, \ + .ramp_delay = _delay, \ + .linear_ranges = _lr, \ + .n_linear_ranges = _nlr, \ + }, \ + .ctrl2_reg = _cr, \ + } + +struct lp873x_regulator { + struct regulator_desc desc; + unsigned int ctrl2_reg; +}; + +static const struct lp873x_regulator regulators[]; + +static const struct regulator_linear_range buck0_buck1_ranges[] = { + REGULATOR_LINEAR_RANGE(0, 0x0, 0x13, 0), + REGULATOR_LINEAR_RANGE(700000, 0x14, 0x17, 10000), + REGULATOR_LINEAR_RANGE(735000, 0x18, 0x9d, 5000), + REGULATOR_LINEAR_RANGE(1420000, 0x9e, 0xff, 20000), +}; + +static const struct regulator_linear_range ldo0_ldo1_ranges[] = { + REGULATOR_LINEAR_RANGE(800000, 0x0, 0x19, 100000), +}; + +static unsigned int lp873x_buck_ramp_delay[] = { + 30000, 15000, 10000, 7500, 3800, 1900, 940, 470 +}; + +/* LP873X BUCK current limit */ +static const unsigned int lp873x_buck_uA[] = { + 1500000, 2000000, 2500000, 3000000, 3500000, 4000000, +}; + +static int lp873x_buck_set_ramp_delay(struct regulator_dev *rdev, + int ramp_delay) +{ + int id = rdev_get_id(rdev); + struct lp873x *lp873 = rdev_get_drvdata(rdev); + unsigned int reg; + int ret; + + if (ramp_delay <= 470) + reg = 7; + else if (ramp_delay <= 940) + reg = 6; + else if (ramp_delay <= 1900) + reg = 5; + else if (ramp_delay <= 3800) + reg = 4; + else if (ramp_delay <= 7500) + reg = 3; + else if (ramp_delay <= 10000) + reg = 2; + else if (ramp_delay <= 15000) + reg = 1; + else + reg = 0; + + ret = regmap_update_bits(lp873->regmap, regulators[id].ctrl2_reg, + LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE, + reg << __ffs(LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE)); + if (ret) { + dev_err(lp873->dev, "SLEW RATE write failed: %d\n", ret); + return ret; + } + + rdev->constraints->ramp_delay = lp873x_buck_ramp_delay[reg]; + + return 0; +} + +static int lp873x_buck_set_current_limit(struct regulator_dev *rdev, + int min_uA, int max_uA) +{ + int id = rdev_get_id(rdev); + struct lp873x *lp873 = rdev_get_drvdata(rdev); + int i; + + for (i = ARRAY_SIZE(lp873x_buck_uA) - 1; i >= 0; i--) { + if (lp873x_buck_uA[i] >= min_uA && + lp873x_buck_uA[i] <= max_uA) + return regmap_update_bits(lp873->regmap, + regulators[id].ctrl2_reg, + LP873X_BUCK0_CTRL_2_BUCK0_ILIM, + i << __ffs(LP873X_BUCK0_CTRL_2_BUCK0_ILIM)); + } + + return -EINVAL; +} + +static int lp873x_buck_get_current_limit(struct regulator_dev *rdev) +{ + int id = rdev_get_id(rdev); + struct lp873x *lp873 = rdev_get_drvdata(rdev); + int ret; + unsigned int val; + + ret = regmap_read(lp873->regmap, regulators[id].ctrl2_reg, &val); + if (ret) + return ret; + + val = (val & LP873X_BUCK0_CTRL_2_BUCK0_ILIM) >> + __ffs(LP873X_BUCK0_CTRL_2_BUCK0_ILIM); + + return (val < ARRAY_SIZE(lp873x_buck_uA)) ? + lp873x_buck_uA[val] : -EINVAL; +} + +/* Operations permitted on BUCK0, BUCK1 */ +static struct regulator_ops lp873x_buck01_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_ramp_delay = lp873x_buck_set_ramp_delay, + .set_current_limit = lp873x_buck_set_current_limit, + .get_current_limit = lp873x_buck_get_current_limit, +}; + +/* Operations permitted on LDO0 and LDO1 */ +static struct regulator_ops lp873x_ldo01_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, +}; + +static const struct lp873x_regulator regulators[] = { + LP873X_REGULATOR("BUCK0", LP873X_BUCK_0, "buck0", lp873x_buck01_ops, + 256, LP873X_REG_BUCK0_VOUT, + LP873X_BUCK0_VOUT_BUCK0_VSET, LP873X_REG_BUCK0_CTRL_1, + LP873X_BUCK0_CTRL_1_BUCK0_EN, 10000, + buck0_buck1_ranges, 4, LP873X_REG_BUCK0_CTRL_2), + LP873X_REGULATOR("BUCK1", LP873X_BUCK_1, "buck1", lp873x_buck01_ops, + 256, LP873X_REG_BUCK1_VOUT, + LP873X_BUCK1_VOUT_BUCK1_VSET, LP873X_REG_BUCK1_CTRL_1, + LP873X_BUCK1_CTRL_1_BUCK1_EN, 10000, + buck0_buck1_ranges, 4, LP873X_REG_BUCK1_CTRL_2), + LP873X_REGULATOR("LDO0", LP873X_LDO_0, "ldo0", lp873x_ldo01_ops, 26, + LP873X_REG_LDO0_VOUT, LP873X_LDO0_VOUT_LDO0_VSET, + LP873X_REG_LDO0_CTRL, + LP873X_LDO0_CTRL_LDO0_EN, 0, ldo0_ldo1_ranges, 1, + 0xFF), + LP873X_REGULATOR("LDO1", LP873X_LDO_1, "ldo1", lp873x_ldo01_ops, 26, + LP873X_REG_LDO1_VOUT, LP873X_LDO1_VOUT_LDO1_VSET, + LP873X_REG_LDO1_CTRL, + LP873X_LDO1_CTRL_LDO1_EN, 0, ldo0_ldo1_ranges, 1, + 0xFF), +}; + +static int lp873x_regulator_probe(struct platform_device *pdev) +{ + struct lp873x *lp873 = dev_get_drvdata(pdev->dev.parent); + struct regulator_config config = { }; + struct regulator_dev *rdev; + int i; + + platform_set_drvdata(pdev, lp873); + + config.dev = &pdev->dev; + config.dev->of_node = lp873->dev->of_node; + config.driver_data = lp873; + config.regmap = lp873->regmap; + + for (i = 0; i < ARRAY_SIZE(regulators); i++) { + rdev = devm_regulator_register(&pdev->dev, ®ulators[i].desc, + &config); + if (IS_ERR(rdev)) { + dev_err(lp873->dev, "failed to register %s regulator\n", + pdev->name); + return PTR_ERR(rdev); + } + } + + return 0; +} + +static const struct platform_device_id lp873x_regulator_id_table[] = { + { "lp873x-regulator", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, lp873x_regulator_id_table); + +static struct platform_driver lp873x_regulator_driver = { + .driver = { + .name = "lp873x-pmic", + }, + .probe = lp873x_regulator_probe, + .id_table = lp873x_regulator_id_table, +}; +module_platform_driver(lp873x_regulator_driver); + +MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>"); +MODULE_DESCRIPTION("LP873X voltage regulator driver"); +MODULE_ALIAS("platform:lp873x-pmic"); +MODULE_LICENSE("GPL v2"); -- 1.9.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Applied "regulator: lp873x: Add support for lp873x PMIC regulators" to the regulator tree 2016-05-10 4:04 ` [PATCH v2 3/3] regulator: lp873x: Add support for lp873x PMIC regulators Keerthy @ 2016-05-11 17:27 ` Mark Brown 0 siblings, 0 replies; 13+ messages in thread From: Mark Brown @ 2016-05-11 17:27 UTC (permalink / raw) To: Keerthy Cc: Mark Brown, broonie, lgirdwood, lee.jones, linux-kernel, linux-omap, devicetree, robh+dt, mark.rutland, j-keerthy The patch regulator: lp873x: Add support for lp873x PMIC regulators has been applied to the regulator tree at git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted. You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed. If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced. Please add any relevant lists and maintainers to the CCs when replying to this mail. Thanks, Mark >From 994aae32b13e373dcbe001af33d5b01379483463 Mon Sep 17 00:00:00 2001 From: Keerthy <j-keerthy@ti.com> Date: Tue, 10 May 2016 09:34:39 +0530 Subject: [PATCH] regulator: lp873x: Add support for lp873x PMIC regulators The regulators set consists of 2 BUCKs and 2 LDOs. The output voltages are configurable and are meant to supply power to the main processor and other components. The ramp delay is configurable for both BUCKs. Signed-off-by: Keerthy <j-keerthy@ti.com> Signed-off-by: Mark Brown <broonie@kernel.org> --- drivers/regulator/Kconfig | 9 ++ drivers/regulator/Makefile | 1 + drivers/regulator/lp873x-regulator.c | 241 +++++++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+) create mode 100644 drivers/regulator/lp873x-regulator.c diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index c77dc08b1202..4d2d737f8c7e 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -321,6 +321,15 @@ config REGULATOR_LP872X help This driver supports LP8720/LP8725 PMIC +config REGULATOR_LP873X + tristate "TI LP873X Power regulators" + depends on MFD_LP873X && OF + help + This driver supports LP873X voltage regulator chips. LP873X + provides two step-down converters and two general-purpose LDO + voltage regulators. It supports software based voltage control + for different voltage domains + config REGULATOR_LP8755 tristate "TI LP8755 High Performance PMU driver" depends on I2C diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 61bfbb9d4a0c..7182b5f7c3e7 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_REGULATOR_LM363X) += lm363x-regulator.o obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o obj-$(CONFIG_REGULATOR_LP3972) += lp3972.o obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o +obj-$(CONFIG_REGULATOR_LP873X) += lp873x-regulator.o obj-$(CONFIG_REGULATOR_LP8788) += lp8788-buck.o obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o diff --git a/drivers/regulator/lp873x-regulator.c b/drivers/regulator/lp873x-regulator.c new file mode 100644 index 000000000000..b4ffd113ba21 --- /dev/null +++ b/drivers/regulator/lp873x-regulator.c @@ -0,0 +1,241 @@ +/* + * Regulator driver for LP873X PMIC + * + * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/ + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether expressed or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License version 2 for more details. + */ + +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#include <linux/mfd/lp873x.h> + +#define LP873X_REGULATOR(_name, _id, _of, _ops, _n, _vr, _vm, _er, _em, \ + _delay, _lr, _nlr, _cr) \ + [_id] = { \ + .desc = { \ + .name = _name, \ + .id = _id, \ + .of_match = of_match_ptr(_of), \ + .regulators_node = of_match_ptr("regulators"),\ + .ops = &_ops, \ + .n_voltages = _n, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .vsel_reg = _vr, \ + .vsel_mask = _vm, \ + .enable_reg = _er, \ + .enable_mask = _em, \ + .ramp_delay = _delay, \ + .linear_ranges = _lr, \ + .n_linear_ranges = _nlr, \ + }, \ + .ctrl2_reg = _cr, \ + } + +struct lp873x_regulator { + struct regulator_desc desc; + unsigned int ctrl2_reg; +}; + +static const struct lp873x_regulator regulators[]; + +static const struct regulator_linear_range buck0_buck1_ranges[] = { + REGULATOR_LINEAR_RANGE(0, 0x0, 0x13, 0), + REGULATOR_LINEAR_RANGE(700000, 0x14, 0x17, 10000), + REGULATOR_LINEAR_RANGE(735000, 0x18, 0x9d, 5000), + REGULATOR_LINEAR_RANGE(1420000, 0x9e, 0xff, 20000), +}; + +static const struct regulator_linear_range ldo0_ldo1_ranges[] = { + REGULATOR_LINEAR_RANGE(800000, 0x0, 0x19, 100000), +}; + +static unsigned int lp873x_buck_ramp_delay[] = { + 30000, 15000, 10000, 7500, 3800, 1900, 940, 470 +}; + +/* LP873X BUCK current limit */ +static const unsigned int lp873x_buck_uA[] = { + 1500000, 2000000, 2500000, 3000000, 3500000, 4000000, +}; + +static int lp873x_buck_set_ramp_delay(struct regulator_dev *rdev, + int ramp_delay) +{ + int id = rdev_get_id(rdev); + struct lp873x *lp873 = rdev_get_drvdata(rdev); + unsigned int reg; + int ret; + + if (ramp_delay <= 470) + reg = 7; + else if (ramp_delay <= 940) + reg = 6; + else if (ramp_delay <= 1900) + reg = 5; + else if (ramp_delay <= 3800) + reg = 4; + else if (ramp_delay <= 7500) + reg = 3; + else if (ramp_delay <= 10000) + reg = 2; + else if (ramp_delay <= 15000) + reg = 1; + else + reg = 0; + + ret = regmap_update_bits(lp873->regmap, regulators[id].ctrl2_reg, + LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE, + reg << __ffs(LP873X_BUCK0_CTRL_2_BUCK0_SLEW_RATE)); + if (ret) { + dev_err(lp873->dev, "SLEW RATE write failed: %d\n", ret); + return ret; + } + + rdev->constraints->ramp_delay = lp873x_buck_ramp_delay[reg]; + + return 0; +} + +static int lp873x_buck_set_current_limit(struct regulator_dev *rdev, + int min_uA, int max_uA) +{ + int id = rdev_get_id(rdev); + struct lp873x *lp873 = rdev_get_drvdata(rdev); + int i; + + for (i = ARRAY_SIZE(lp873x_buck_uA) - 1; i >= 0; i--) { + if (lp873x_buck_uA[i] >= min_uA && + lp873x_buck_uA[i] <= max_uA) + return regmap_update_bits(lp873->regmap, + regulators[id].ctrl2_reg, + LP873X_BUCK0_CTRL_2_BUCK0_ILIM, + i << __ffs(LP873X_BUCK0_CTRL_2_BUCK0_ILIM)); + } + + return -EINVAL; +} + +static int lp873x_buck_get_current_limit(struct regulator_dev *rdev) +{ + int id = rdev_get_id(rdev); + struct lp873x *lp873 = rdev_get_drvdata(rdev); + int ret; + unsigned int val; + + ret = regmap_read(lp873->regmap, regulators[id].ctrl2_reg, &val); + if (ret) + return ret; + + val = (val & LP873X_BUCK0_CTRL_2_BUCK0_ILIM) >> + __ffs(LP873X_BUCK0_CTRL_2_BUCK0_ILIM); + + return (val < ARRAY_SIZE(lp873x_buck_uA)) ? + lp873x_buck_uA[val] : -EINVAL; +} + +/* Operations permitted on BUCK0, BUCK1 */ +static struct regulator_ops lp873x_buck01_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, + .set_voltage_time_sel = regulator_set_voltage_time_sel, + .set_ramp_delay = lp873x_buck_set_ramp_delay, + .set_current_limit = lp873x_buck_set_current_limit, + .get_current_limit = lp873x_buck_get_current_limit, +}; + +/* Operations permitted on LDO0 and LDO1 */ +static struct regulator_ops lp873x_ldo01_ops = { + .is_enabled = regulator_is_enabled_regmap, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, +}; + +static const struct lp873x_regulator regulators[] = { + LP873X_REGULATOR("BUCK0", LP873X_BUCK_0, "buck0", lp873x_buck01_ops, + 256, LP873X_REG_BUCK0_VOUT, + LP873X_BUCK0_VOUT_BUCK0_VSET, LP873X_REG_BUCK0_CTRL_1, + LP873X_BUCK0_CTRL_1_BUCK0_EN, 10000, + buck0_buck1_ranges, 4, LP873X_REG_BUCK0_CTRL_2), + LP873X_REGULATOR("BUCK1", LP873X_BUCK_1, "buck1", lp873x_buck01_ops, + 256, LP873X_REG_BUCK1_VOUT, + LP873X_BUCK1_VOUT_BUCK1_VSET, LP873X_REG_BUCK1_CTRL_1, + LP873X_BUCK1_CTRL_1_BUCK1_EN, 10000, + buck0_buck1_ranges, 4, LP873X_REG_BUCK1_CTRL_2), + LP873X_REGULATOR("LDO0", LP873X_LDO_0, "ldo0", lp873x_ldo01_ops, 26, + LP873X_REG_LDO0_VOUT, LP873X_LDO0_VOUT_LDO0_VSET, + LP873X_REG_LDO0_CTRL, + LP873X_LDO0_CTRL_LDO0_EN, 0, ldo0_ldo1_ranges, 1, + 0xFF), + LP873X_REGULATOR("LDO1", LP873X_LDO_1, "ldo1", lp873x_ldo01_ops, 26, + LP873X_REG_LDO1_VOUT, LP873X_LDO1_VOUT_LDO1_VSET, + LP873X_REG_LDO1_CTRL, + LP873X_LDO1_CTRL_LDO1_EN, 0, ldo0_ldo1_ranges, 1, + 0xFF), +}; + +static int lp873x_regulator_probe(struct platform_device *pdev) +{ + struct lp873x *lp873 = dev_get_drvdata(pdev->dev.parent); + struct regulator_config config = { }; + struct regulator_dev *rdev; + int i; + + platform_set_drvdata(pdev, lp873); + + config.dev = &pdev->dev; + config.dev->of_node = lp873->dev->of_node; + config.driver_data = lp873; + config.regmap = lp873->regmap; + + for (i = 0; i < ARRAY_SIZE(regulators); i++) { + rdev = devm_regulator_register(&pdev->dev, ®ulators[i].desc, + &config); + if (IS_ERR(rdev)) { + dev_err(lp873->dev, "failed to register %s regulator\n", + pdev->name); + return PTR_ERR(rdev); + } + } + + return 0; +} + +static const struct platform_device_id lp873x_regulator_id_table[] = { + { "lp873x-regulator", }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(platform, lp873x_regulator_id_table); + +static struct platform_driver lp873x_regulator_driver = { + .driver = { + .name = "lp873x-pmic", + }, + .probe = lp873x_regulator_probe, + .id_table = lp873x_regulator_id_table, +}; +module_platform_driver(lp873x_regulator_driver); + +MODULE_AUTHOR("J Keerthy <j-keerthy@ti.com>"); +MODULE_DESCRIPTION("LP873X voltage regulator driver"); +MODULE_ALIAS("platform:lp873x-pmic"); +MODULE_LICENSE("GPL v2"); -- 2.8.1 ^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2016-05-17 8:08 UTC | newest] Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2016-05-10 4:04 [PATCH v2 0/3] mfd: lp873x: Add lp873x PMIC support Keerthy 2016-05-10 4:04 ` [PATCH v2 1/3] Documentation: mfd: LP873X: Add information for the mfd and regulator drivers Keerthy 2016-05-11 14:35 ` Rob Herring 2016-05-12 13:21 ` Lee Jones 2016-05-12 23:21 ` Keerthy 2016-05-10 4:04 ` [PATCH v2 2/3] mfd: lp873x: Add lp873x PMIC support Keerthy 2016-05-12 13:18 ` Lee Jones 2016-05-12 23:13 ` Keerthy 2016-05-17 8:01 ` Lee Jones 2016-05-17 8:04 ` Keerthy 2016-05-17 8:07 ` Keerthy 2016-05-10 4:04 ` [PATCH v2 3/3] regulator: lp873x: Add support for lp873x PMIC regulators Keerthy 2016-05-11 17:27 ` Applied "regulator: lp873x: Add support for lp873x PMIC regulators" to the regulator tree Mark Brown
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).