Commit 9909f798 authored by Mark Brown's avatar Mark Brown

Merge branch 'regulator-5.6' into regulator-next

parents f7abb7e3 53ba2f1a
Monolithic Power Systems MP8859 voltage regulator
Required properties:
- compatible: "mps,mp8859";
- reg: I2C slave address.
Optional subnode for regulator: "mp8859_dcdc", using common regulator
bindings given in <Documentation/devicetree/bindings/regulator/regulator.txt>.
Example:
mp8859: regulator@66 {
compatible = "mps,mp8859";
reg = <0x66>;
dc_12v: mp8859_dcdc {
regulator-name = "dc_12v";
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
regulator-boot-on;
regulator-always-on;
};
};
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/rohm,bd71828-regulator.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: ROHM BD71828 Power Management Integrated Circuit regulators
maintainers:
- Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
description: |
This module is part of the ROHM BD71828 MFD device. For more details
see Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml.
The regulator controller is represented as a sub-node of the PMIC node
on the device tree.
Regulator nodes should be named to BUCK_<number> and LDO_<number>.
The valid names for BD71828 regulator nodes are
BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, BUCK7
LDO1, LDO2, LDO3, LDO4, LDO5, LDO6, LDO7
patternProperties:
"^LDO[1-7]$":
type: object
allOf:
- $ref: regulator.yaml#
description:
Properties for single LDO regulator.
properties:
regulator-name:
pattern: "^ldo[1-7]$"
description:
should be "ldo1", ..., "ldo7"
"^BUCK[1-7]$":
type: object
allOf:
- $ref: regulator.yaml#
description:
Properties for single BUCK regulator.
properties:
regulator-name:
pattern: "^buck[1-7]$"
description:
should be "buck1", ..., "buck7"
rohm,dvs-run-voltage:
allOf:
- $ref: "/schemas/types.yaml#/definitions/uint32"
- minimum: 0
maximum: 3300000
description:
PMIC default "RUN" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
rohm,dvs-idle-voltage:
allOf:
- $ref: "/schemas/types.yaml#/definitions/uint32"
- minimum: 0
maximum: 3300000
description:
PMIC default "IDLE" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
rohm,dvs-suspend-voltage:
allOf:
- $ref: "/schemas/types.yaml#/definitions/uint32"
- minimum: 0
maximum: 3300000
description:
PMIC default "SUSPEND" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
rohm,dvs-lpsr-voltage:
allOf:
- $ref: "/schemas/types.yaml#/definitions/uint32"
- minimum: 0
maximum: 3300000
description:
PMIC default "LPSR" state voltage in uV. See below table for
bucks which support this. 0 means disabled.
# Supported default DVS states:
# buck | run | idle | suspend | lpsr
#--------------------------------------------------------------
# 1, 2, 6, and 7 | supported | supported | supported (*)
#--------------------------------------------------------------
# 3, 4, and 5 | supported (**)
#--------------------------------------------------------------
#
#(*) LPSR and SUSPEND states use same voltage but both states have own
# enable /
# disable settings. Voltage 0 can be specified for a state to make
# regulator disabled on that state.
#
#(**) All states use same voltage but have own enable / disable
# settings. Voltage 0 can be specified for a state to make
# regulator disabled on that state.
required:
- regulator-name
additionalProperties: false
additionalProperties: false
STM32 BOOSTER - Booster for ADC analog input switches
Some STM32 devices embed a 3.3V booster supplied by Vdda, that can be used
to supply ADC analog input switches.
Required properties:
- compatible: Should be one of:
"st,stm32h7-booster"
"st,stm32mp1-booster"
- st,syscfg: Phandle to system configuration controller.
- vdda-supply: Phandle to the vdda input analog voltage.
Example:
booster: regulator-booster {
compatible = "st,stm32mp1-booster";
st,syscfg = <&syscfg>;
vdda-supply = <&vdda>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/st,stm32-booster.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: STMicroelectronics STM32 booster for ADC analog input switches bindings
maintainers:
- Fabrice Gasnier <fabrice.gasnier@st.com>
description: |
Some STM32 devices embed a 3.3V booster supplied by Vdda, that can be used
to supply ADC analog input switches.
allOf:
- $ref: "regulator.yaml#"
properties:
compatible:
enum:
- st,stm32h7-booster
- st,stm32mp1-booster
st,syscfg:
allOf:
- $ref: "/schemas/types.yaml#/definitions/phandle-array"
description: phandle to system configuration controller.
vdda-supply:
description: phandle to the vdda input analog voltage.
required:
- compatible
- st,syscfg
- vdda-supply
examples:
- |
regulator-booster {
compatible = "st,stm32mp1-booster";
st,syscfg = <&syscfg>;
vdda-supply = <&vdda>;
};
...
STM32 VREFBUF - Voltage reference buffer
Some STM32 devices embed a voltage reference buffer which can be used as
voltage reference for ADCs, DACs and also as voltage reference for external
components through the dedicated VREF+ pin.
Required properties:
- compatible: Must be "st,stm32-vrefbuf".
- reg: Offset and length of VREFBUF register set.
- clocks: Must contain an entry for peripheral clock.
Example:
vrefbuf: regulator@58003c00 {
compatible = "st,stm32-vrefbuf";
reg = <0x58003C00 0x8>;
clocks = <&rcc VREF_CK>;
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <2500000>;
vdda-supply = <&vdda>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/st,stm32-vrefbuf.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: STMicroelectronics STM32 Voltage reference buffer bindings
description: |
Some STM32 devices embed a voltage reference buffer which can be used as
voltage reference for ADCs, DACs and also as voltage reference for external
components through the dedicated VREF+ pin.
maintainers:
- Fabrice Gasnier <fabrice.gasnier@st.com>
allOf:
- $ref: "regulator.yaml#"
properties:
compatible:
const: st,stm32-vrefbuf
reg:
maxItems: 1
clocks:
maxItems: 1
vdda-supply:
description: phandle to the vdda input analog voltage.
required:
- compatible
- reg
- clocks
- vdda-supply
examples:
- |
#include <dt-bindings/clock/stm32mp1-clks.h>
vrefbuf@50025000 {
compatible = "st,stm32-vrefbuf";
reg = <0x50025000 0x8>;
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <2500000>;
clocks = <&rcc VREF>;
vdda-supply = <&vdda>;
};
...
STM32MP1 PWR Regulators
-----------------------
Available Regulators in STM32MP1 PWR block are:
- reg11 for regulator 1V1
- reg18 for regulator 1V8
- usb33 for the swtich USB3V3
Required properties:
- compatible: Must be "st,stm32mp1,pwr-reg"
- list of child nodes that specify the regulator reg11, reg18 or usb33
initialization data for defined regulators. The definition for each of
these nodes is defined using the standard binding for regulators found at
Documentation/devicetree/bindings/regulator/regulator.txt.
- vdd-supply: phandle to the parent supply/regulator node for vdd input
- vdd_3v3_usbfs-supply: phandle to the parent supply/regulator node for usb33
Example:
pwr_regulators: pwr@50001000 {
compatible = "st,stm32mp1,pwr-reg";
reg = <0x50001000 0x10>;
vdd-supply = <&vdd>;
vdd_3v3_usbfs-supply = <&vdd_usb>;
reg11: reg11 {
regulator-name = "reg11";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
};
reg18: reg18 {
regulator-name = "reg18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
usb33: usb33 {
regulator-name = "usb33";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/regulator/st,stm32mp1-pwr-reg.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: STM32MP1 PWR voltage regulators
maintainers:
- Pascal Paillet <p.paillet@st.com>
properties:
compatible:
const: st,stm32mp1,pwr-reg
reg:
maxItems: 1
vdd-supply:
description: Input supply phandle(s) for vdd input
vdd_3v3_usbfs-supply:
description: Input supply phandle(s) for vdd_3v3_usbfs input
patternProperties:
"^(reg11|reg18|usb33)$":
type: object
allOf:
- $ref: "regulator.yaml#"
required:
- compatible
- reg
additionalProperties: false
examples:
- |
pwr@50001000 {
compatible = "st,stm32mp1,pwr-reg";
reg = <0x50001000 0x10>;
vdd-supply = <&vdd>;
vdd_3v3_usbfs-supply = <&vdd_usb>;
reg11 {
regulator-name = "reg11";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1100000>;
};
reg18 {
regulator-name = "reg18";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
};
usb33 {
regulator-name = "usb33";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
};
...
......@@ -11143,6 +11143,13 @@ S: Maintained
F: Documentation/driver-api/serial/moxa-smartio.rst
F: drivers/tty/mxser.*
MONOLITHIC POWER SYSTEM PMIC DRIVER
M: Saravanan Sekar <sravanhome@gmail.com>
S: Maintained
F: Documentation/devicetree/bindings/regulator/mpq7920.yaml
F: drivers/regulator/mpq7920.c
F: drivers/regulator/mpq7920.h
MR800 AVERMEDIA USB FM RADIO DRIVER
M: Alexey Klimov <klimov.linux@gmail.com>
L: linux-media@vger.kernel.org
......
......@@ -194,6 +194,18 @@ config REGULATOR_BD70528
This driver can also be built as a module. If so, the module
will be called bd70528-regulator.
config REGULATOR_BD71828
tristate "ROHM BD71828 Power Regulator"
depends on MFD_ROHM_BD71828
select REGULATOR_ROHM
help
This driver supports voltage regulators on ROHM BD71828 PMIC.
This will enable support for the software controllable buck
and LDO regulators.
This driver can also be built as a module. If so, the module
will be called bd71828-regulator.
config REGULATOR_BD718XX
tristate "ROHM BD71837 Power Regulator"
depends on MFD_ROHM_BD718XX
......@@ -600,6 +612,27 @@ config REGULATOR_MCP16502
through the regulator interface. In addition it enables
suspend-to-ram/standby transition.
config REGULATOR_MP8859
tristate "MPS MP8859 regulator driver"
depends on I2C
select REGMAP_I2C
help
Say y here to support the MP8859 voltage regulator. This driver
supports basic operations (get/set voltage) through the regulator
interface.
Say M here if you want to include support for the regulator as a
module. The module will be named "mp8859".
config REGULATOR_MPQ7920
tristate "Monolithic MPQ7920 PMIC"
depends on I2C && OF
select REGMAP_I2C
help
Say y here to support the MPQ7920 PMIC. This will enable supports
the software controllable 4 buck and 5 LDO regulators.
This driver supports the control of different power rails of device
through regulator interface.
config REGULATOR_MT6311
tristate "MediaTek MT6311 PMIC"
depends on I2C
......@@ -1077,6 +1110,13 @@ config REGULATOR_VEXPRESS
This driver provides support for voltage regulators available
on the ARM Ltd's Versatile Express platform.
config REGULATOR_VQMMC_IPQ4019
tristate "IPQ4019 VQMMC SD LDO regulator support"
depends on ARCH_QCOM
help
This driver provides support for the VQMMC LDO I/0
voltage regulator of the IPQ4019 SD/EMMC controller.
config REGULATOR_WM831X
tristate "Wolfson Microelectronics WM831x PMIC regulators"
depends on MFD_WM831X
......
......@@ -28,6 +28,7 @@ obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
obj-$(CONFIG_REGULATOR_BD70528) += bd70528-regulator.o
obj-$(CONFIG_REGULATOR_BD71828) += bd71828-regulator.o
obj-$(CONFIG_REGULATOR_BD718XX) += bd718x7-regulator.o
obj-$(CONFIG_REGULATOR_BD9571MWV) += bd9571mwv-regulator.o
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
......@@ -77,6 +78,8 @@ obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
obj-$(CONFIG_REGULATOR_MCP16502) += mcp16502.o
obj-$(CONFIG_REGULATOR_MP8859) += mp8859.o
obj-$(CONFIG_REGULATOR_MPQ7920) += mpq7920.o
obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o
obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o
obj-$(CONFIG_REGULATOR_MT6358) += mt6358-regulator.o
......@@ -132,6 +135,7 @@ obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o
obj-$(CONFIG_REGULATOR_UNIPHIER) += uniphier-regulator.o
obj-$(CONFIG_REGULATOR_VCTRL) += vctrl-regulator.o
obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress-regulator.o
obj-$(CONFIG_REGULATOR_VQMMC_IPQ4019) += vqmmc-ipq4019-regulator.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
......
This diff is collapsed.
......@@ -1142,28 +1142,14 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
},
};
struct bd718xx_pmic_inits {
const struct bd718xx_regulator_data *r_datas;
unsigned int r_amount;
};
static int bd718xx_probe(struct platform_device *pdev)
{
struct bd718xx *mfd;
struct regulator_config config = { 0 };
struct bd718xx_pmic_inits pmic_regulators[ROHM_CHIP_TYPE_AMOUNT] = {
[ROHM_CHIP_TYPE_BD71837] = {
.r_datas = bd71837_regulators,
.r_amount = ARRAY_SIZE(bd71837_regulators),
},
[ROHM_CHIP_TYPE_BD71847] = {
.r_datas = bd71847_regulators,
.r_amount = ARRAY_SIZE(bd71847_regulators),
},
};
int i, j, err;
bool use_snvs;
const struct bd718xx_regulator_data *reg_data;
unsigned int num_reg_data;
mfd = dev_get_drvdata(pdev->dev.parent);
if (!mfd) {
......@@ -1172,8 +1158,16 @@ static int bd718xx_probe(struct platform_device *pdev)
goto err;
}
if (mfd->chip.chip_type >= ROHM_CHIP_TYPE_AMOUNT ||
!pmic_regulators[mfd->chip.chip_type].r_datas) {
switch (mfd->chip.chip_type) {
case ROHM_CHIP_TYPE_BD71837:
reg_data = bd71837_regulators;
num_reg_data = ARRAY_SIZE(bd71837_regulators);
break;
case ROHM_CHIP_TYPE_BD71847:
reg_data = bd71847_regulators;
num_reg_data = ARRAY_SIZE(bd71847_regulators);
break;
default:
dev_err(&pdev->dev, "Unsupported chip type\n");
err = -EINVAL;
goto err;
......@@ -1215,13 +1209,13 @@ static int bd718xx_probe(struct platform_device *pdev)
}
}
for (i = 0; i < pmic_regulators[mfd->chip.chip_type].r_amount; i++) {
for (i = 0; i < num_reg_data; i++) {
const struct regulator_desc *desc;
struct regulator_dev *rdev;
const struct bd718xx_regulator_data *r;
r = &pmic_regulators[mfd->chip.chip_type].r_datas[i];
r = &reg_data[i];
desc = &r->desc;
config.dev = pdev->dev.parent;
......
......@@ -131,8 +131,7 @@ static const struct of_device_id da9210_dt_ids[] = {
};
MODULE_DEVICE_TABLE(of, da9210_dt_ids);
static int da9210_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int da9210_i2c_probe(struct i2c_client *i2c)
{
struct da9210 *chip;
struct device *dev = &i2c->dev;
......@@ -228,7 +227,7 @@ static struct i2c_driver da9210_regulator_driver = {
.name = "da9210",
.of_match_table = of_match_ptr(da9210_dt_ids),
},
.probe = da9210_i2c_probe,
.probe_new = da9210_i2c_probe,
.id_table = da9210_i2c_id,
};
......
......@@ -416,8 +416,7 @@ static int da9211_regulator_init(struct da9211 *chip)
/*
* I2C driver interface functions
*/
static int da9211_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int da9211_i2c_probe(struct i2c_client *i2c)
{
struct da9211 *chip;
int error, ret;
......@@ -526,7 +525,7 @@ static struct i2c_driver da9211_regulator_driver = {
.name = "da9211",
.of_match_table = of_match_ptr(da9211_dt_ids),
},
.probe = da9211_i2c_probe,
.probe_new = da9211_i2c_probe,
.id_table = da9211_i2c_id,
};
......
......@@ -137,8 +137,7 @@ static const struct regmap_config isl9305_regmap = {
.cache_type = REGCACHE_RBTREE,
};
static int isl9305_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int isl9305_i2c_probe(struct i2c_client *i2c)
{
struct regulator_config config = { };
struct isl9305_pdata *pdata = i2c->dev.platform_data;
......@@ -198,7 +197,7 @@ static struct i2c_driver isl9305_regulator_driver = {
.name = "isl9305",
.of_match_table = of_match_ptr(isl9305_dt_ids),
},
.probe = isl9305_i2c_probe,
.probe_new = isl9305_i2c_probe,
.id_table = isl9305_i2c_id,
};
......
......@@ -400,8 +400,7 @@ static int setup_regulators(struct lp3971 *lp3971,
return 0;
}
static int lp3971_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int lp3971_i2c_probe(struct i2c_client *i2c)
{
struct lp3971 *lp3971;
struct lp3971_platform_data *pdata = dev_get_platdata(&i2c->dev);
......@@ -449,7 +448,7 @@ static struct i2c_driver lp3971_i2c_driver = {
.driver = {
.name = "LP3971",
},
.probe = lp3971_i2c_probe,
.probe_new = lp3971_i2c_probe,
.id_table = lp3971_i2c_id,
};
......
......@@ -301,8 +301,7 @@ static irqreturn_t ltc3676_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
static int ltc3676_regulator_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int ltc3676_regulator_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct regulator_init_data *init_data = dev_get_platdata(dev);
......@@ -380,7 +379,7 @@ static struct i2c_driver ltc3676_driver = {
.name = DRIVER_NAME,
.of_match_table = of_match_ptr(ltc3676_of_match),
},
.probe = ltc3676_regulator_probe,
.probe_new = ltc3676_regulator_probe,
.id_table = ltc3676_i2c_id,
};
module_i2c_driver(ltc3676_driver);
......
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2019 five technologies GmbH
// Author: Markus Reichl <m.reichl@fivetechno.de>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/of.h>
#include <linux/regulator/driver.h>
#include <linux/regmap.h>
#define VOL_MIN_IDX 0x00
#define VOL_MAX_IDX 0x7ff
/* Register definitions */
#define MP8859_VOUT_L_REG 0 //3 lo Bits
#define MP8859_VOUT_H_REG 1 //8 hi Bits
#define MP8859_VOUT_GO_REG 2
#define MP8859_IOUT_LIM_REG 3
#define MP8859_CTL1_REG 4
#define MP8859_CTL2_REG 5
#define MP8859_RESERVED1_REG 6
#define MP8859_RESERVED2_REG 7
#define MP8859_RESERVED3_REG 8
#define MP8859_STATUS_REG 9
#define MP8859_INTERRUPT_REG 0x0A
#define MP8859_MASK_REG 0x0B
#define MP8859_ID1_REG 0x0C
#define MP8859_MFR_ID_REG 0x27
#define MP8859_DEV_ID_REG 0x28
#define MP8859_IC_REV_REG 0x29
#define MP8859_MAX_REG 0x29
#define MP8859_GO_BIT 0x01
static int mp8859_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel)
{
int ret;
ret = regmap_write(rdev->regmap, MP8859_VOUT_L_REG, sel & 0x7);
if (ret)
return ret;
ret = regmap_write(rdev->regmap, MP8859_VOUT_H_REG, sel >> 3);
if (ret)
return ret;
ret = regmap_update_bits(rdev->regmap, MP8859_VOUT_GO_REG,
MP8859_GO_BIT, 1);
return ret;
}
static int mp8859_get_voltage_sel(struct regulator_dev *rdev)
{
unsigned int val_tmp;
unsigned int val;
int ret;
ret = regmap_read(rdev->regmap, MP8859_VOUT_H_REG, &val_tmp);
if (ret)
return ret;
val = val_tmp << 3;
ret = regmap_read(rdev->regmap, MP8859_VOUT_L_REG, &val_tmp);
if (ret)
return ret;
val |= val_tmp & 0x07;
return val;
}
static const struct regulator_linear_range mp8859_dcdc_ranges[] = {
REGULATOR_LINEAR_RANGE(0, VOL_MIN_IDX, VOL_MAX_IDX, 10000),
};
static const struct regmap_config mp8859_regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = MP8859_MAX_REG,
.cache_type = REGCACHE_RBTREE,
};
static const struct regulator_ops mp8859_ops = {
.set_voltage_sel = mp8859_set_voltage_sel,
.get_voltage_sel = mp8859_get_voltage_sel,
.list_voltage = regulator_list_voltage_linear_range,
};
static const struct regulator_desc mp8859_regulators[] = {
{
.id = 0,
.type = REGULATOR_VOLTAGE,
.name = "mp8859_dcdc",
.of_match = of_match_ptr("mp8859_dcdc"),
.n_voltages = VOL_MAX_IDX + 1,
.linear_ranges = mp8859_dcdc_ranges,
.n_linear_ranges = 1,
.ops = &mp8859_ops,
.owner = THIS_MODULE,
},
};
static int mp8859_i2c_probe(struct i2c_client *i2c)
{
int ret;
struct regulator_config config = {.dev = &i2c->dev};
struct regmap *regmap = devm_regmap_init_i2c(i2c, &mp8859_regmap);
struct regulator_dev *rdev;
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
return ret;
}
rdev = devm_regulator_register(&i2c->dev, &mp8859_regulators[0],
&config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&i2c->dev, "failed to register %s: %d\n",
mp8859_regulators[0].name, ret);
return ret;
}
return 0;
}
static const struct of_device_id mp8859_dt_id[] = {
{.compatible = "mps,mp8859"},
{},
};
MODULE_DEVICE_TABLE(of, mp8859_dt_id);
static const struct i2c_device_id mp8859_i2c_id[] = {
{ "mp8859", },
{ },
};
MODULE_DEVICE_TABLE(i2c, mp8859_i2c_id);
static struct i2c_driver mp8859_regulator_driver = {
.driver = {
.name = "mp8859",
.of_match_table = of_match_ptr(mp8859_dt_id),
},
.probe_new = mp8859_i2c_probe,
.id_table = mp8859_i2c_id,
};
module_i2c_driver(mp8859_regulator_driver);
MODULE_DESCRIPTION("Monolithic Power Systems MP8859 voltage regulator driver");
MODULE_AUTHOR("Markus Reichl <m.reichl@fivetechno.de>");
MODULE_LICENSE("GPL v2");
// SPDX-License-Identifier: GPL-2.0+
//
// mpq7920.c - regulator driver for mps mpq7920
//
// Copyright 2019 Monolithic Power Systems, Inc
//
// Author: Saravanan Sekar <sravanhome@gmail.com>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/of_regulator.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include "mpq7920.h"
#define MPQ7920_BUCK_VOLT_RANGE \
((MPQ7920_VOLT_MAX - MPQ7920_BUCK_VOLT_MIN)/MPQ7920_VOLT_STEP + 1)
#define MPQ7920_LDO_VOLT_RANGE \
((MPQ7920_VOLT_MAX - MPQ7920_LDO_VOLT_MIN)/MPQ7920_VOLT_STEP + 1)
#define MPQ7920BUCK(_name, _id, _ilim) \
[MPQ7920_BUCK ## _id] = { \
.id = MPQ7920_BUCK ## _id, \
.name = _name, \
.of_match = _name, \
.regulators_node = "regulators", \
.of_parse_cb = mpq7920_parse_cb, \
.ops = &mpq7920_buck_ops, \
.min_uV = MPQ7920_BUCK_VOLT_MIN, \
.uV_step = MPQ7920_VOLT_STEP, \
.n_voltages = MPQ7920_BUCK_VOLT_RANGE, \
.curr_table = _ilim, \
.n_current_limits = ARRAY_SIZE(_ilim), \
.csel_reg = MPQ7920_BUCK ##_id## _REG_C, \
.csel_mask = MPQ7920_MASK_BUCK_ILIM, \
.enable_reg = MPQ7920_REG_REGULATOR_EN, \
.enable_mask = BIT(MPQ7920_REGULATOR_EN_OFFSET - \
MPQ7920_BUCK ## _id), \
.vsel_reg = MPQ7920_BUCK ##_id## _REG_A, \
.vsel_mask = MPQ7920_MASK_VREF, \
.active_discharge_on = MPQ7920_DISCHARGE_ON, \
.active_discharge_reg = MPQ7920_BUCK ##_id## _REG_B, \
.active_discharge_mask = MPQ7920_MASK_DISCHARGE, \
.soft_start_reg = MPQ7920_BUCK ##_id## _REG_C, \
.soft_start_mask = MPQ7920_MASK_SOFTSTART, \
.owner = THIS_MODULE, \
}
#define MPQ7920LDO(_name, _id, _ops, _ilim, _ilim_sz, _creg, _cmask) \
[MPQ7920_LDO ## _id] = { \
.id = MPQ7920_LDO ## _id, \
.name = _name, \
.of_match = _name, \
.regulators_node = "regulators", \
.ops = _ops, \
.min_uV = MPQ7920_LDO_VOLT_MIN, \
.uV_step = MPQ7920_VOLT_STEP, \
.n_voltages = MPQ7920_LDO_VOLT_RANGE, \
.vsel_reg = MPQ7920_LDO ##_id## _REG_A, \
.vsel_mask = MPQ7920_MASK_VREF, \
.curr_table = _ilim, \
.n_current_limits = _ilim_sz, \
.csel_reg = _creg, \
.csel_mask = _cmask, \
.enable_reg = (_id == 1) ? 0 : MPQ7920_REG_REGULATOR_EN,\
.enable_mask = BIT(MPQ7920_REGULATOR_EN_OFFSET - \
MPQ7920_LDO ##_id + 1), \
.active_discharge_on = MPQ7920_DISCHARGE_ON, \
.active_discharge_mask = MPQ7920_MASK_DISCHARGE, \
.active_discharge_reg = MPQ7920_LDO ##_id## _REG_B, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}
enum mpq7920_regulators {
MPQ7920_BUCK1,
MPQ7920_BUCK2,
MPQ7920_BUCK3,
MPQ7920_BUCK4,
MPQ7920_LDO1, /* LDORTC */
MPQ7920_LDO2,
MPQ7920_LDO3,
MPQ7920_LDO4,
MPQ7920_LDO5,
MPQ7920_MAX_REGULATORS,
};
struct mpq7920_regulator_info {
struct regmap *regmap;
struct regulator_desc *rdesc;
};
static const struct regmap_config mpq7920_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = 0x25,
};
/* Current limits array (in uA)
* ILIM1 & ILIM3
*/
static const unsigned int mpq7920_I_limits1[] = {
4600000, 6600000, 7600000, 9300000
};
/* ILIM2 & ILIM4 */
static const unsigned int mpq7920_I_limits2[] = {
2700000, 3900000, 5100000, 6100000
};
/* LDO4 & LDO5 */
static const unsigned int mpq7920_I_limits3[] = {
300000, 700000
};
static int mpq7920_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay);
static int mpq7920_parse_cb(struct device_node *np,
const struct regulator_desc *rdesc,
struct regulator_config *config);
/* RTCLDO not controllable, always ON */
static const struct regulator_ops mpq7920_ldortc_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
};
static const struct regulator_ops mpq7920_ldo_wo_current_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_active_discharge = regulator_set_active_discharge_regmap,
};
static const struct regulator_ops mpq7920_ldo_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_active_discharge = regulator_set_active_discharge_regmap,
.get_current_limit = regulator_get_current_limit_regmap,
.set_current_limit = regulator_set_current_limit_regmap,
};
static const struct regulator_ops mpq7920_buck_ops = {
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_active_discharge = regulator_set_active_discharge_regmap,
.set_soft_start = regulator_set_soft_start_regmap,
.set_ramp_delay = mpq7920_set_ramp_delay,
};
static struct regulator_desc mpq7920_regulators_desc[MPQ7920_MAX_REGULATORS] = {
MPQ7920BUCK("buck1", 1, mpq7920_I_limits1),
MPQ7920BUCK("buck2", 2, mpq7920_I_limits2),
MPQ7920BUCK("buck3", 3, mpq7920_I_limits1),
MPQ7920BUCK("buck4", 4, mpq7920_I_limits2),
MPQ7920LDO("ldortc", 1, &mpq7920_ldortc_ops, NULL, 0, 0, 0),
MPQ7920LDO("ldo2", 2, &mpq7920_ldo_wo_current_ops, NULL, 0, 0, 0),
MPQ7920LDO("ldo3", 3, &mpq7920_ldo_wo_current_ops, NULL, 0, 0, 0),
MPQ7920LDO("ldo4", 4, &mpq7920_ldo_ops, mpq7920_I_limits3,
ARRAY_SIZE(mpq7920_I_limits3), MPQ7920_LDO4_REG_B,
MPQ7920_MASK_LDO_ILIM),
MPQ7920LDO("ldo5", 5, &mpq7920_ldo_ops, mpq7920_I_limits3,
ARRAY_SIZE(mpq7920_I_limits3), MPQ7920_LDO5_REG_B,
MPQ7920_MASK_LDO_ILIM),
};
/*
* DVS ramp rate BUCK1 to BUCK4
* 00-01: Reserved
* 10: 8mV/us
* 11: 4mV/us
*/
static int mpq7920_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
{
unsigned int ramp_val;
if (ramp_delay > 8000 || ramp_delay < 0)
return -EINVAL;
if (ramp_delay <= 4000)
ramp_val = 3;
else
ramp_val = 2;
return regmap_update_bits(rdev->regmap, MPQ7920_REG_CTL0,
MPQ7920_MASK_DVS_SLEWRATE, ramp_val << 6);
}
static int mpq7920_parse_cb(struct device_node *np,
const struct regulator_desc *desc,
struct regulator_config *config)
{
uint8_t val;
int ret;
struct mpq7920_regulator_info *info = config->driver_data;
struct regulator_desc *rdesc = &info->rdesc[desc->id];
if (of_property_read_bool(np, "mps,buck-ovp-disable")) {
regmap_update_bits(config->regmap,
MPQ7920_BUCK1_REG_B + (rdesc->id * 4),
MPQ7920_MASK_OVP, MPQ7920_OVP_DISABLE);
}
ret = of_property_read_u8(np, "mps,buck-phase-delay", &val);
if (!ret) {
regmap_update_bits(config->regmap,
MPQ7920_BUCK1_REG_C + (rdesc->id * 4),
MPQ7920_MASK_BUCK_PHASE_DEALY,
(val & 3) << 4);
}
ret = of_property_read_u8(np, "mps,buck-softstart", &val);
if (!ret)
rdesc->soft_start_val_on = (val & 3) << 2;
return 0;
}
static void mpq7920_parse_dt(struct device *dev,
struct mpq7920_regulator_info *info)
{
int ret;
struct device_node *np = dev->of_node;
uint8_t freq;
np = of_get_child_by_name(np, "regulators");
if (!np) {
dev_err(dev, "missing 'regulators' subnode in DT\n");
return;
}
ret = of_property_read_u8(np, "mps,switch-freq", &freq);
if (!ret) {
regmap_update_bits(info->regmap, MPQ7920_REG_CTL0,
MPQ7920_MASK_SWITCH_FREQ,
(freq & 3) << 4);
}
of_node_put(np);
}
static int mpq7920_i2c_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct mpq7920_regulator_info *info;
struct regulator_config config = { NULL, };
struct regulator_dev *rdev;
struct regmap *regmap;
int i;
info = devm_kzalloc(dev, sizeof(struct mpq7920_regulator_info),
GFP_KERNEL);
if (!info)
return -ENOMEM;
info->rdesc = mpq7920_regulators_desc;
regmap = devm_regmap_init_i2c(client, &mpq7920_regmap_config);
if (IS_ERR(regmap)) {
dev_err(dev, "Failed to allocate regmap!\n");
return PTR_ERR(regmap);
}
i2c_set_clientdata(client, info);
info->regmap = regmap;
if (client->dev.of_node)
mpq7920_parse_dt(&client->dev, info);
config.dev = dev;
config.regmap = regmap;
config.driver_data = info;
for (i = 0; i < MPQ7920_MAX_REGULATORS; i++) {
rdev = devm_regulator_register(dev,
&mpq7920_regulators_desc[i],
&config);
if (IS_ERR(rdev)) {
dev_err(dev, "Failed to register regulator!\n");
return PTR_ERR(rdev);
}
}
return 0;
}
static const struct of_device_id mpq7920_of_match[] = {
{ .compatible = "mps,mpq7920"},
{},
};
MODULE_DEVICE_TABLE(of, mpq7920_of_match);
static const struct i2c_device_id mpq7920_id[] = {
{ "mpq7920", },
{ },
};
MODULE_DEVICE_TABLE(i2c, mpq7920_id);
static struct i2c_driver mpq7920_regulator_driver = {
.driver = {
.name = "mpq7920",
.of_match_table = of_match_ptr(mpq7920_of_match),
},
.probe_new = mpq7920_i2c_probe,
.id_table = mpq7920_id,
};
module_i2c_driver(mpq7920_regulator_driver);
MODULE_AUTHOR("Saravanan Sekar <sravanhome@gmail.com>");
MODULE_DESCRIPTION("MPQ7920 PMIC regulator driver");
MODULE_LICENSE("GPL");
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* mpq7920.h - Regulator definitions for mpq7920
*
* Copyright 2019 Monolithic Power Systems, Inc
*
*/
#ifndef __MPQ7920_H__
#define __MPQ7920_H__
#define MPQ7920_REG_CTL0 0x00
#define MPQ7920_REG_CTL1 0x01
#define MPQ7920_REG_CTL2 0x02
#define MPQ7920_BUCK1_REG_A 0x03
#define MPQ7920_BUCK1_REG_B 0x04
#define MPQ7920_BUCK1_REG_C 0x05
#define MPQ7920_BUCK1_REG_D 0x06
#define MPQ7920_BUCK2_REG_A 0x07
#define MPQ7920_BUCK2_REG_B 0x08
#define MPQ7920_BUCK2_REG_C 0x09
#define MPQ7920_BUCK2_REG_D 0x0a
#define MPQ7920_BUCK3_REG_A 0x0b
#define MPQ7920_BUCK3_REG_B 0x0c
#define MPQ7920_BUCK3_REG_C 0x0d
#define MPQ7920_BUCK3_REG_D 0x0e
#define MPQ7920_BUCK4_REG_A 0x0f
#define MPQ7920_BUCK4_REG_B 0x10
#define MPQ7920_BUCK4_REG_C 0x11
#define MPQ7920_BUCK4_REG_D 0x12
#define MPQ7920_LDO1_REG_A 0x13
#define MPQ7920_LDO1_REG_B 0x0
#define MPQ7920_LDO2_REG_A 0x14
#define MPQ7920_LDO2_REG_B 0x15
#define MPQ7920_LDO2_REG_C 0x16
#define MPQ7920_LDO3_REG_A 0x17
#define MPQ7920_LDO3_REG_B 0x18
#define MPQ7920_LDO3_REG_C 0x19
#define MPQ7920_LDO4_REG_A 0x1a
#define MPQ7920_LDO4_REG_B 0x1b
#define MPQ7920_LDO4_REG_C 0x1c
#define MPQ7920_LDO5_REG_A 0x1d
#define MPQ7920_LDO5_REG_B 0x1e
#define MPQ7920_LDO5_REG_C 0x1f
#define MPQ7920_REG_MODE 0x20
#define MPQ7920_REG_REGULATOR_EN 0x22
#define MPQ7920_MASK_VREF 0x7f
#define MPQ7920_MASK_BUCK_ILIM 0xc0
#define MPQ7920_MASK_LDO_ILIM BIT(6)
#define MPQ7920_MASK_DISCHARGE BIT(5)
#define MPQ7920_MASK_MODE 0xc0
#define MPQ7920_MASK_SOFTSTART 0x0c
#define MPQ7920_MASK_SWITCH_FREQ 0x30
#define MPQ7920_MASK_BUCK_PHASE_DEALY 0x30
#define MPQ7920_MASK_DVS_SLEWRATE 0xc0
#define MPQ7920_MASK_OVP 0x40
#define MPQ7920_OVP_DISABLE ~(0x40)
#define MPQ7920_DISCHARGE_ON BIT(5)
#define MPQ7920_REGULATOR_EN_OFFSET 7
/* values in mV */
#define MPQ7920_BUCK_VOLT_MIN 400000
#define MPQ7920_LDO_VOLT_MIN 650000
#define MPQ7920_VOLT_MAX 3587500
#define MPQ7920_VOLT_STEP 12500
#endif /* __MPQ7920_H__ */
......@@ -85,8 +85,7 @@ static const struct regulator_desc mt6311_regulators[] = {
/*
* I2C driver interface functions
*/
static int mt6311_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int mt6311_i2c_probe(struct i2c_client *i2c)
{
struct regulator_config config = { };
struct regulator_dev *rdev;
......@@ -154,7 +153,7 @@ static struct i2c_driver mt6311_regulator_driver = {
.name = "mt6311",
.of_match_table = of_match_ptr(mt6311_dt_ids),
},
.probe = mt6311_i2c_probe,
.probe_new = mt6311_i2c_probe,
.id_table = mt6311_i2c_id,
};
......
......@@ -279,8 +279,7 @@ static irqreturn_t pv88060_irq_handler(int irq, void *data)
/*
* I2C driver interface functions
*/
static int pv88060_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int pv88060_i2c_probe(struct i2c_client *i2c)
{
struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
struct pv88060 *chip;
......@@ -385,7 +384,7 @@ static struct i2c_driver pv88060_regulator_driver = {
.name = "pv88060",
.of_match_table = of_match_ptr(pv88060_dt_ids),
},
.probe = pv88060_i2c_probe,
.probe_new = pv88060_i2c_probe,
.id_table = pv88060_i2c_id,
};
......
......@@ -272,8 +272,7 @@ static irqreturn_t pv88090_irq_handler(int irq, void *data)
/*
* I2C driver interface functions
*/
static int pv88090_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int pv88090_i2c_probe(struct i2c_client *i2c)
{
struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
struct pv88090 *chip;
......@@ -406,7 +405,7 @@ static struct i2c_driver pv88090_regulator_driver = {
.name = "pv88090",
.of_match_table = of_match_ptr(pv88090_dt_ids),
},
.probe = pv88090_i2c_probe,
.probe_new = pv88090_i2c_probe,
.id_table = pv88090_i2c_id,
};
......
......@@ -1282,7 +1282,7 @@ static int rk808_regulator_dt_parse_pdata(struct device *dev,
}
if (!pdata->dvs_gpio[i]) {
dev_warn(dev, "there is no dvs%d gpio\n", i);
dev_info(dev, "there is no dvs%d gpio\n", i);
continue;
}
......
......@@ -390,5 +390,5 @@ module_platform_driver(s2mpa01_pmic_driver);
/* Module information */
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
MODULE_AUTHOR("Sachin Kamat <sachin.kamat@samsung.com>");
MODULE_DESCRIPTION("SAMSUNG S2MPA01 Regulator Driver");
MODULE_DESCRIPTION("Samsung S2MPA01 Regulator Driver");
MODULE_LICENSE("GPL");
......@@ -1265,5 +1265,5 @@ module_platform_driver(s2mps11_pmic_driver);
/* Module information */
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
MODULE_DESCRIPTION("SAMSUNG S2MPS11/S2MPS14/S2MPS15/S2MPU02 Regulator Driver");
MODULE_DESCRIPTION("Samsung S2MPS11/S2MPS14/S2MPS15/S2MPU02 Regulator Driver");
MODULE_LICENSE("GPL");
......@@ -1015,5 +1015,5 @@ module_exit(s5m8767_pmic_exit);
/* Module information */
MODULE_AUTHOR("Sangbeom Kim <sbkim73@samsung.com>");
MODULE_DESCRIPTION("SAMSUNG S5M8767 Regulator Driver");
MODULE_DESCRIPTION("Samsung S5M8767 Regulator Driver");
MODULE_LICENSE("GPL");
......@@ -439,8 +439,7 @@ static void slg51000_clear_fault_log(struct slg51000 *chip)
dev_dbg(chip->dev, "Fault log: FLT_POR\n");
}
static int slg51000_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int slg51000_i2c_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct slg51000 *chip;
......@@ -509,7 +508,7 @@ static struct i2c_driver slg51000_regulator_driver = {
.driver = {
.name = "slg51000-regulator",
},
.probe = slg51000_i2c_probe,
.probe_new = slg51000_i2c_probe,
.id_table = slg51000_i2c_id,
};
......
......@@ -61,8 +61,7 @@ static const struct regulator_desc sy8106a_reg = {
/*
* I2C driver interface functions
*/
static int sy8106a_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
static int sy8106a_i2c_probe(struct i2c_client *i2c)
{
struct device *dev = &i2c->dev;
struct regulator_dev *rdev;
......@@ -141,7 +140,7 @@ static struct i2c_driver sy8106a_regulator_driver = {
.name = "sy8106a",
.of_match_table = of_match_ptr(sy8106a_i2c_of_match),
},
.probe = sy8106a_i2c_probe,
.probe_new = sy8106a_i2c_probe,
.id_table = sy8106a_i2c_id,
};
......
......@@ -112,8 +112,7 @@ static const struct regmap_config sy8824_regmap_config = {
.val_bits = 8,
};
static int sy8824_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
static int sy8824_i2c_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct device_node *np = dev->of_node;
......@@ -222,7 +221,7 @@ static struct i2c_driver sy8824_regulator_driver = {
.name = "sy8824-regulator",
.of_match_table = of_match_ptr(sy8824_dt_ids),
},
.probe = sy8824_i2c_probe,
.probe_new = sy8824_i2c_probe,
.id_table = sy8824_id,
};
module_i2c_driver(sy8824_regulator_driver);
......
......@@ -220,8 +220,7 @@ static const struct regmap_config tps65132_regmap_config = {
.wr_table = &tps65132_no_reg_table,
};
static int tps65132_probe(struct i2c_client *client,
const struct i2c_device_id *client_id)
static int tps65132_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct tps65132_regulator *tps;
......@@ -272,7 +271,7 @@ static struct i2c_driver tps65132_i2c_driver = {
.driver = {
.name = "tps65132",
},
.probe = tps65132_probe,
.probe_new = tps65132_probe,
.id_table = tps65132_id,
};
......
// SPDX-License-Identifier: GPL-2.0+
//
// Copyright (c) 2019 Mantas Pucka <mantas@8devices.com>
// Copyright (c) 2019 Robert Marko <robert.marko@sartura.hr>
//
// Driver for IPQ4019 SD/MMC controller's I/O LDO voltage regulator
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
static const unsigned int ipq4019_vmmc_voltages[] = {
1500000, 1800000, 2500000, 3000000,
};
static const struct regulator_ops ipq4019_regulator_voltage_ops = {
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_ascend,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
};
static const struct regulator_desc vmmc_regulator = {
.name = "vmmcq",
.ops = &ipq4019_regulator_voltage_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.volt_table = ipq4019_vmmc_voltages,
.n_voltages = ARRAY_SIZE(ipq4019_vmmc_voltages),
.vsel_reg = 0,
.vsel_mask = 0x3,
};
static const struct regmap_config ipq4019_vmmcq_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
};
static int ipq4019_regulator_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct regulator_init_data *init_data;
struct regulator_config cfg = {};
struct regulator_dev *rdev;
struct resource *res;
struct regmap *rmap;
void __iomem *base;
init_data = of_get_regulator_init_data(dev, dev->of_node,
&vmmc_regulator);
if (!init_data)
return -EINVAL;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
rmap = devm_regmap_init_mmio(dev, base, &ipq4019_vmmcq_regmap_config);
if (IS_ERR(rmap))
return PTR_ERR(rmap);
cfg.dev = dev;
cfg.init_data = init_data;
cfg.of_node = dev->of_node;
cfg.regmap = rmap;
rdev = devm_regulator_register(dev, &vmmc_regulator, &cfg);
if (IS_ERR(rdev)) {
dev_err(dev, "Failed to register regulator: %ld\n",
PTR_ERR(rdev));
return PTR_ERR(rdev);
}
platform_set_drvdata(pdev, rdev);
return 0;
}
static const struct of_device_id regulator_ipq4019_of_match[] = {
{ .compatible = "qcom,vqmmc-ipq4019-regulator", },
{},
};
static struct platform_driver ipq4019_regulator_driver = {
.probe = ipq4019_regulator_probe,
.driver = {
.name = "vqmmc-ipq4019-regulator",
.of_match_table = of_match_ptr(regulator_ipq4019_of_match),
},
};
module_platform_driver(ipq4019_regulator_driver);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Mantas Pucka <mantas@8devices.com>");
MODULE_DESCRIPTION("IPQ4019 VQMMC voltage regulator");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment