Commit 64b285ad authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branches 'regulator/topic/max1586',...

Merge remote-tracking branches 'regulator/topic/max1586', 'regulator/topic/max77802' and 'regulator/topic/of' into regulator-next
Maxim MAX1586 voltage regulator
Required properties:
- compatible: must be "maxim,max1586"
- reg: I2C slave address, usually 0x14
- v3-gain: integer specifying the V3 gain as per datasheet
(1 + R24/R25 + R24/185.5kOhm)
- any required generic properties defined in regulator.txt
Example:
i2c_master {
max1586@14 {
compatible = "maxim,max1586";
reg = <0x14>;
v3-gain = <1000000>;
regulators {
vcc_core: v3 {
regulator-name = "vcc_core";
regulator-compatible = "Output_V3";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1705000>;
regulator-always-on;
};
};
};
};
Binding for Maxim MAX77802 regulators
This is a part of device tree bindings of MAX77802 multi-function device.
More information can be found in bindings/mfd/max77802.txt file.
The MAX77802 PMIC has 10 high-efficiency Buck and 32 Low-dropout (LDO)
regulators that can be controlled over I2C.
Following properties should be present in main device node of the MFD chip.
Optional node:
- regulators : The regulators of max77802 have to be instantiated
under subnode named "regulators" using the following format.
regulator-name {
standard regulator constraints....
};
refer Documentation/devicetree/bindings/regulator/regulator.txt
The regulator node name should be initialized with a string to get matched
with their hardware counterparts as follow. The valid names are:
-LDOn : for LDOs, where n can lie in ranges 1-15, 17-21, 23-30
and 32-35.
example: LDO1, LDO2, LDO35.
-BUCKn : for BUCKs, where n can lie in range 1 to 10.
example: BUCK1, BUCK5, BUCK10.
Example:
max77802@09 {
compatible = "maxim,max77802";
interrupt-parent = <&wakeup_eint>;
interrupts = <26 0>;
reg = <0x09>;
#address-cells = <1>;
#size-cells = <0>;
regulators {
ldo11_reg: LDO11 {
regulator-name = "vdd_ldo11";
regulator-min-microvolt = <1900000>;
regulator-max-microvolt = <1900000>;
regulator-always-on;
};
buck1_reg: BUCK1 {
regulator-name = "vdd_mif";
regulator-min-microvolt = <950000>;
regulator-max-microvolt = <1300000>;
regulator-always-on;
regulator-boot-on;
};
};
......@@ -405,6 +405,15 @@ config REGULATOR_MAX77693
and one current regulator 'CHARGER'. This is suitable for
Exynos-4x12 chips.
config REGULATOR_MAX77802
tristate "Maxim 77802 regulator"
depends on MFD_MAX77686
help
This driver controls a Maxim 77802 regulator
via I2C bus. The provided regulator is suitable for
Exynos5420/Exynos5800 SoCs to control various voltages.
It includes support for control of voltage and ramp speed.
config REGULATOR_MC13XXX_CORE
tristate
......
......@@ -54,6 +54,7 @@ obj-$(CONFIG_REGULATOR_MAX8997) += max8997.o
obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
obj-$(CONFIG_REGULATOR_MAX77686) += max77686.o
obj-$(CONFIG_REGULATOR_MAX77693) += max77693.o
obj-$(CONFIG_REGULATOR_MAX77802) += max77802.o
obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o
obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o
obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o
......
......@@ -35,8 +35,18 @@ struct regulator {
struct dentry *debugfs;
};
#ifdef CONFIG_OF
struct regulator_init_data *regulator_of_get_init_data(struct device *dev,
const struct regulator_desc *desc,
struct device_node **node);
#else
static inline struct regulator_init_data *
regulator_of_get_init_data(struct device *dev,
const struct regulator_desc *desc,
struct device_node **node)
{
return NULL;
}
#endif
#endif
......@@ -24,6 +24,8 @@
#include <linux/regulator/driver.h>
#include <linux/slab.h>
#include <linux/regulator/max1586.h>
#include <linux/of_device.h>
#include <linux/regulator/of_regulator.h>
#define MAX1586_V3_MAX_VSEL 31
#define MAX1586_V6_MAX_VSEL 3
......@@ -157,13 +159,87 @@ static struct regulator_desc max1586_reg[] = {
},
};
static int of_get_max1586_platform_data(struct device *dev,
struct max1586_platform_data *pdata)
{
struct max1586_subdev_data *sub;
struct of_regulator_match rmatch[ARRAY_SIZE(max1586_reg)];
struct device_node *np = dev->of_node;
int i, matched;
if (of_property_read_u32(np, "v3-gain",
&pdata->v3_gain) < 0) {
dev_err(dev, "%s has no 'v3-gain' property\n", np->full_name);
return -EINVAL;
}
np = of_get_child_by_name(np, "regulators");
if (!np) {
dev_err(dev, "missing 'regulators' subnode in DT\n");
return -EINVAL;
}
for (i = 0; i < ARRAY_SIZE(rmatch); i++)
rmatch[i].name = max1586_reg[i].name;
matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(rmatch));
of_node_put(np);
/*
* If matched is 0, ie. neither Output_V3 nor Output_V6 have been found,
* return 0, which signals the normal situation where no subregulator is
* available. This is normal because the max1586 doesn't provide any
* readback support, so the subregulators can't report any status
* anyway. If matched < 0, return the error.
*/
if (matched <= 0)
return matched;
pdata->subdevs = devm_kzalloc(dev, sizeof(struct max1586_subdev_data) *
matched, GFP_KERNEL);
if (!pdata->subdevs)
return -ENOMEM;
pdata->num_subdevs = matched;
sub = pdata->subdevs;
for (i = 0; i < matched; i++) {
sub->id = i;
sub->name = rmatch[i].of_node->name;
sub->platform_data = rmatch[i].init_data;
sub++;
}
return 0;
}
static const struct of_device_id max1586_of_match[] = {
{ .compatible = "maxim,max1586", },
{},
};
MODULE_DEVICE_TABLE(of, max1586_of_match);
static int max1586_pmic_probe(struct i2c_client *client,
const struct i2c_device_id *i2c_id)
{
struct max1586_platform_data *pdata = dev_get_platdata(&client->dev);
struct max1586_platform_data *pdata, pdata_of;
struct regulator_config config = { };
struct max1586_data *max1586;
int i, id;
int i, id, ret;
const struct of_device_id *match;
pdata = dev_get_platdata(&client->dev);
if (client->dev.of_node && !pdata) {
match = of_match_device(of_match_ptr(max1586_of_match),
&client->dev);
if (!match) {
dev_err(&client->dev, "Error: No device match found\n");
return -ENODEV;
}
ret = of_get_max1586_platform_data(&client->dev, &pdata_of);
if (ret < 0)
return ret;
pdata = &pdata_of;
}
max1586 = devm_kzalloc(&client->dev, sizeof(struct max1586_data),
GFP_KERNEL);
......@@ -229,6 +305,7 @@ static struct i2c_driver max1586_pmic_driver = {
.driver = {
.name = "max1586",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(max1586_of_match),
},
.id_table = max1586_id,
};
......
/*
* max77802.c - Regulator driver for the Maxim 77802
*
* Copyright (C) 2013-2014 Google, Inc
* Simon Glass <sjg@chromium.org>
*
* Copyright (C) 2012 Samsung Electronics
* Chiwoong Byun <woong.byun@smasung.com>
* Jonghwa Lee <jonghwa3.lee@samsung.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; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* This driver is based on max8997.c
*/
#include <linux/kernel.h>
#include <linux/bug.h>
#include <linux/err.h>
#include <linux/gpio.h>
#include <linux/slab.h>
#include <linux/gpio/consumer.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/of_regulator.h>
#include <linux/mfd/max77686.h>
#include <linux/mfd/max77686-private.h>
/* Default ramp delay in case it is not manually set */
#define MAX77802_RAMP_DELAY 100000 /* uV/us */
#define MAX77802_OPMODE_SHIFT_LDO 6
#define MAX77802_OPMODE_BUCK234_SHIFT 4
#define MAX77802_OPMODE_MASK 0x3
#define MAX77802_VSEL_MASK 0x3F
#define MAX77802_DVS_VSEL_MASK 0xFF
#define MAX77802_RAMP_RATE_MASK_2BIT 0xC0
#define MAX77802_RAMP_RATE_SHIFT_2BIT 6
#define MAX77802_RAMP_RATE_MASK_4BIT 0xF0
#define MAX77802_RAMP_RATE_SHIFT_4BIT 4
/* MAX77802 has two register formats: 2-bit and 4-bit */
static const unsigned int ramp_table_77802_2bit[] = {
12500,
25000,
50000,
100000,
};
static unsigned int ramp_table_77802_4bit[] = {
1000, 2000, 3030, 4000,
5000, 5880, 7140, 8330,
9090, 10000, 11110, 12500,
16670, 25000, 50000, 100000,
};
struct max77802_regulator_prv {
unsigned int opmode[MAX77802_REG_MAX];
};
static int max77802_get_opmode_shift(int id)
{
if (id == MAX77802_BUCK1 || (id >= MAX77802_BUCK5 &&
id <= MAX77802_BUCK10))
return 0;
if (id >= MAX77802_BUCK2 && id <= MAX77802_BUCK4)
return MAX77802_OPMODE_BUCK234_SHIFT;
if (id >= MAX77802_LDO1 && id <= MAX77802_LDO35)
return MAX77802_OPMODE_SHIFT_LDO;
return -EINVAL;
}
/*
* Some BUCKS supports Normal[ON/OFF] mode during suspend
*
* BUCK 1, 6, 2-4, 5, 7-10 (all)
*
* The other mode (0x02) will make PWRREQ switch between normal
* and low power.
*/
static int max77802_buck_set_suspend_disable(struct regulator_dev *rdev)
{
unsigned int val = MAX77802_OPMODE_STANDBY;
struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
int shift = max77802_get_opmode_shift(id);
max77802->opmode[id] = val;
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask, val << shift);
}
/*
* Some LDOs supports LPM-ON/OFF/Normal-ON mode during suspend state
* (Enable Control Logic1 by PWRREQ)
*
* LDOs 2, 4-19, 22-35.
*
*/
static int max77802_ldo_set_suspend_mode_logic1(struct regulator_dev *rdev,
unsigned int mode)
{
struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
unsigned int val;
int shift = max77802_get_opmode_shift(id);
switch (mode) {
case REGULATOR_MODE_IDLE: /* ON in LP Mode */
val = MAX77802_OPMODE_LP;
break;
case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */
val = MAX77802_OPMODE_NORMAL;
break;
case REGULATOR_MODE_STANDBY: /* ON/OFF by PWRREQ */
val = MAX77802_OPMODE_STANDBY;
break;
default:
dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n",
rdev->desc->name, mode);
return -EINVAL;
}
max77802->opmode[id] = val;
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask, val << shift);
}
/*
* Mode 1 (Output[ON/OFF] by PWRREQ) is not supported on some LDOs
* (Enable Control Logic2 by PWRREQ)
*
* LDOs 1, 20, 21, and 3,
*
*/
static int max77802_ldo_set_suspend_mode_logic2(struct regulator_dev *rdev,
unsigned int mode)
{
struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
unsigned int val;
int shift = max77802_get_opmode_shift(id);
switch (mode) {
case REGULATOR_MODE_IDLE: /* ON in LP Mode */
val = MAX77802_OPMODE_LP;
break;
case REGULATOR_MODE_NORMAL: /* ON in Normal Mode */
val = MAX77802_OPMODE_NORMAL;
break;
default:
dev_warn(&rdev->dev, "%s: regulator mode: 0x%x not supported\n",
rdev->desc->name, mode);
return -EINVAL;
}
max77802->opmode[id] = val;
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask, val << shift);
}
static int max77802_enable(struct regulator_dev *rdev)
{
struct max77802_regulator_prv *max77802 = rdev_get_drvdata(rdev);
int id = rdev_get_id(rdev);
int shift = max77802_get_opmode_shift(id);
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
rdev->desc->enable_mask,
max77802->opmode[id] << shift);
}
static int max77802_find_ramp_value(struct regulator_dev *rdev,
const unsigned int limits[], int size,
unsigned int ramp_delay)
{
int i;
for (i = 0; i < size; i++) {
if (ramp_delay <= limits[i])
return i;
}
/* Use maximum value for no ramp control */
dev_warn(&rdev->dev, "%s: ramp_delay: %d not supported, setting 100000\n",
rdev->desc->name, ramp_delay);
return size - 1;
}
/* Used for BUCKs 2-4 */
static int max77802_set_ramp_delay_2bit(struct regulator_dev *rdev,
int ramp_delay)
{
int id = rdev_get_id(rdev);
unsigned int ramp_value;
if (id > MAX77802_BUCK4) {
dev_warn(&rdev->dev,
"%s: regulator: ramp delay not supported\n",
rdev->desc->name);
return -EINVAL;
}
ramp_value = max77802_find_ramp_value(rdev, ramp_table_77802_2bit,
ARRAY_SIZE(ramp_table_77802_2bit), ramp_delay);
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
MAX77802_RAMP_RATE_MASK_2BIT,
ramp_value << MAX77802_RAMP_RATE_SHIFT_2BIT);
}
/* For BUCK1, 6 */
static int max77802_set_ramp_delay_4bit(struct regulator_dev *rdev,
int ramp_delay)
{
unsigned int ramp_value;
ramp_value = max77802_find_ramp_value(rdev, ramp_table_77802_4bit,
ARRAY_SIZE(ramp_table_77802_4bit), ramp_delay);
return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg,
MAX77802_RAMP_RATE_MASK_4BIT,
ramp_value << MAX77802_RAMP_RATE_SHIFT_4BIT);
}
/*
* LDOs 2, 4-19, 22-35
*/
static struct regulator_ops max77802_ldo_ops_logic1 = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.is_enabled = regulator_is_enabled_regmap,
.enable = max77802_enable,
.disable = regulator_disable_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_suspend_mode = max77802_ldo_set_suspend_mode_logic1,
};
/*
* LDOs 1, 20, 21, 3
*/
static struct regulator_ops max77802_ldo_ops_logic2 = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.is_enabled = regulator_is_enabled_regmap,
.enable = max77802_enable,
.disable = regulator_disable_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_suspend_mode = max77802_ldo_set_suspend_mode_logic2,
};
/* BUCKS 1, 6 */
static struct regulator_ops max77802_buck_16_dvs_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.is_enabled = regulator_is_enabled_regmap,
.enable = max77802_enable,
.disable = regulator_disable_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max77802_set_ramp_delay_4bit,
.set_suspend_disable = max77802_buck_set_suspend_disable,
};
/* BUCKs 2-4, 5, 7-10 */
static struct regulator_ops max77802_buck_dvs_ops = {
.list_voltage = regulator_list_voltage_linear,
.map_voltage = regulator_map_voltage_linear,
.is_enabled = regulator_is_enabled_regmap,
.enable = max77802_enable,
.disable = regulator_disable_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.set_voltage_time_sel = regulator_set_voltage_time_sel,
.set_ramp_delay = max77802_set_ramp_delay_2bit,
.set_suspend_disable = max77802_buck_set_suspend_disable,
};
/* LDOs 3-7, 9-14, 18-26, 28, 29, 32-34 */
#define regulator_77802_desc_p_ldo(num, supply, log) { \
.name = "LDO"#num, \
.id = MAX77802_LDO##num, \
.supply_name = "inl"#supply, \
.ops = &max77802_ldo_ops_logic##log, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.min_uV = 800000, \
.uV_step = 50000, \
.ramp_delay = MAX77802_RAMP_DELAY, \
.n_voltages = 1 << 6, \
.vsel_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \
.vsel_mask = MAX77802_VSEL_MASK, \
.enable_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \
.enable_mask = MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \
}
/* LDOs 1, 2, 8, 15, 17, 27, 30, 35 */
#define regulator_77802_desc_n_ldo(num, supply, log) { \
.name = "LDO"#num, \
.id = MAX77802_LDO##num, \
.supply_name = "inl"#supply, \
.ops = &max77802_ldo_ops_logic##log, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.min_uV = 800000, \
.uV_step = 25000, \
.ramp_delay = MAX77802_RAMP_DELAY, \
.n_voltages = 1 << 6, \
.vsel_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \
.vsel_mask = MAX77802_VSEL_MASK, \
.enable_reg = MAX77802_REG_LDO1CTRL1 + num - 1, \
.enable_mask = MAX77802_OPMODE_MASK << MAX77802_OPMODE_SHIFT_LDO, \
}
/* BUCKs 1, 6 */
#define regulator_77802_desc_16_buck(num) { \
.name = "BUCK"#num, \
.id = MAX77802_BUCK##num, \
.supply_name = "inb"#num, \
.ops = &max77802_buck_16_dvs_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.min_uV = 612500, \
.uV_step = 6250, \
.ramp_delay = MAX77802_RAMP_DELAY, \
.n_voltages = 1 << 8, \
.vsel_reg = MAX77802_REG_BUCK ## num ## DVS1, \
.vsel_mask = MAX77802_DVS_VSEL_MASK, \
.enable_reg = MAX77802_REG_BUCK ## num ## CTRL, \
.enable_mask = MAX77802_OPMODE_MASK, \
}
/* BUCKS 2-4 */
#define regulator_77802_desc_234_buck(num) { \
.name = "BUCK"#num, \
.id = MAX77802_BUCK##num, \
.supply_name = "inb"#num, \
.ops = &max77802_buck_dvs_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.min_uV = 600000, \
.uV_step = 6250, \
.ramp_delay = MAX77802_RAMP_DELAY, \
.n_voltages = 0x91, \
.vsel_reg = MAX77802_REG_BUCK ## num ## DVS1, \
.vsel_mask = MAX77802_DVS_VSEL_MASK, \
.enable_reg = MAX77802_REG_BUCK ## num ## CTRL1, \
.enable_mask = MAX77802_OPMODE_MASK << \
MAX77802_OPMODE_BUCK234_SHIFT, \
}
/* BUCK 5 */
#define regulator_77802_desc_buck5(num) { \
.name = "BUCK"#num, \
.id = MAX77802_BUCK##num, \
.supply_name = "inb"#num, \
.ops = &max77802_buck_dvs_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.min_uV = 750000, \
.uV_step = 50000, \
.ramp_delay = MAX77802_RAMP_DELAY, \
.n_voltages = 1 << 6, \
.vsel_reg = MAX77802_REG_BUCK5OUT, \
.vsel_mask = MAX77802_VSEL_MASK, \
.enable_reg = MAX77802_REG_BUCK5CTRL, \
.enable_mask = MAX77802_OPMODE_MASK, \
}
/* BUCKs 7-10 */
#define regulator_77802_desc_buck7_10(num) { \
.name = "BUCK"#num, \
.id = MAX77802_BUCK##num, \
.supply_name = "inb"#num, \
.ops = &max77802_buck_dvs_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.min_uV = 750000, \
.uV_step = 50000, \
.ramp_delay = MAX77802_RAMP_DELAY, \
.n_voltages = 1 << 6, \
.vsel_reg = MAX77802_REG_BUCK7OUT + (num - 7) * 3, \
.vsel_mask = MAX77802_VSEL_MASK, \
.enable_reg = MAX77802_REG_BUCK7CTRL + (num - 7) * 3, \
.enable_mask = MAX77802_OPMODE_MASK, \
}
static struct regulator_desc regulators[] = {
regulator_77802_desc_16_buck(1),
regulator_77802_desc_234_buck(2),
regulator_77802_desc_234_buck(3),
regulator_77802_desc_234_buck(4),
regulator_77802_desc_buck5(5),
regulator_77802_desc_16_buck(6),
regulator_77802_desc_buck7_10(7),
regulator_77802_desc_buck7_10(8),
regulator_77802_desc_buck7_10(9),
regulator_77802_desc_buck7_10(10),
regulator_77802_desc_n_ldo(1, 10, 2),
regulator_77802_desc_n_ldo(2, 10, 1),
regulator_77802_desc_p_ldo(3, 3, 2),
regulator_77802_desc_p_ldo(4, 6, 1),
regulator_77802_desc_p_ldo(5, 3, 1),
regulator_77802_desc_p_ldo(6, 3, 1),
regulator_77802_desc_p_ldo(7, 3, 1),
regulator_77802_desc_n_ldo(8, 1, 1),
regulator_77802_desc_p_ldo(9, 5, 1),
regulator_77802_desc_p_ldo(10, 4, 1),
regulator_77802_desc_p_ldo(11, 4, 1),
regulator_77802_desc_p_ldo(12, 9, 1),
regulator_77802_desc_p_ldo(13, 4, 1),
regulator_77802_desc_p_ldo(14, 4, 1),
regulator_77802_desc_n_ldo(15, 1, 1),
regulator_77802_desc_n_ldo(17, 2, 1),
regulator_77802_desc_p_ldo(18, 7, 1),
regulator_77802_desc_p_ldo(19, 5, 1),
regulator_77802_desc_p_ldo(20, 7, 2),
regulator_77802_desc_p_ldo(21, 6, 2),
regulator_77802_desc_p_ldo(23, 9, 1),
regulator_77802_desc_p_ldo(24, 6, 1),
regulator_77802_desc_p_ldo(25, 9, 1),
regulator_77802_desc_p_ldo(26, 9, 1),
regulator_77802_desc_n_ldo(27, 2, 1),
regulator_77802_desc_p_ldo(28, 7, 1),
regulator_77802_desc_p_ldo(29, 7, 1),
regulator_77802_desc_n_ldo(30, 2, 1),
regulator_77802_desc_p_ldo(32, 9, 1),
regulator_77802_desc_p_ldo(33, 6, 1),
regulator_77802_desc_p_ldo(34, 9, 1),
regulator_77802_desc_n_ldo(35, 2, 1),
};
#ifdef CONFIG_OF
static int max77802_pmic_dt_parse_pdata(struct platform_device *pdev,
struct max77686_platform_data *pdata)
{
struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct device_node *pmic_np, *regulators_np;
struct max77686_regulator_data *rdata;
struct of_regulator_match rmatch;
unsigned int i;
pmic_np = iodev->dev->of_node;
regulators_np = of_get_child_by_name(pmic_np, "regulators");
if (!regulators_np) {
dev_err(&pdev->dev, "could not find regulators sub-node\n");
return -EINVAL;
}
pdata->num_regulators = ARRAY_SIZE(regulators);
rdata = devm_kzalloc(&pdev->dev, sizeof(*rdata) *
pdata->num_regulators, GFP_KERNEL);
if (!rdata) {
of_node_put(regulators_np);
return -ENOMEM;
}
for (i = 0; i < pdata->num_regulators; i++) {
rmatch.name = regulators[i].name;
rmatch.init_data = NULL;
rmatch.of_node = NULL;
if (of_regulator_match(&pdev->dev, regulators_np, &rmatch,
1) != 1) {
dev_warn(&pdev->dev, "No matching regulator for '%s'\n",
rmatch.name);
continue;
}
rdata[i].initdata = rmatch.init_data;
rdata[i].of_node = rmatch.of_node;
rdata[i].id = regulators[i].id;
}
pdata->regulators = rdata;
of_node_put(regulators_np);
return 0;
}
#else
static int max77802_pmic_dt_parse_pdata(struct platform_device *pdev,
struct max77686_platform_data *pdata)
{
return 0;
}
#endif /* CONFIG_OF */
static int max77802_pmic_probe(struct platform_device *pdev)
{
struct max77686_dev *iodev = dev_get_drvdata(pdev->dev.parent);
struct max77686_platform_data *pdata = dev_get_platdata(iodev->dev);
struct max77802_regulator_prv *max77802;
int i, ret = 0, val;
struct regulator_config config = { };
/* This is allocated by the MFD driver */
if (!pdata) {
dev_err(&pdev->dev, "no platform data found for regulator\n");
return -ENODEV;
}
max77802 = devm_kzalloc(&pdev->dev,
sizeof(struct max77802_regulator_prv),
GFP_KERNEL);
if (!max77802)
return -ENOMEM;
if (iodev->dev->of_node) {
ret = max77802_pmic_dt_parse_pdata(pdev, pdata);
if (ret)
return ret;
}
config.dev = iodev->dev;
config.regmap = iodev->regmap;
config.driver_data = max77802;
platform_set_drvdata(pdev, max77802);
for (i = 0; i < MAX77802_REG_MAX; i++) {
struct regulator_dev *rdev;
int id = pdata->regulators[i].id;
int shift = max77802_get_opmode_shift(id);
config.init_data = pdata->regulators[i].initdata;
config.of_node = pdata->regulators[i].of_node;
ret = regmap_read(iodev->regmap, regulators[i].enable_reg, &val);
val = val >> shift & MAX77802_OPMODE_MASK;
/*
* If the regulator is disabled and the system warm rebooted,
* the hardware reports OFF as the regulator operating mode.
* Default to operating mode NORMAL in that case.
*/
if (val == MAX77802_OPMODE_OFF)
max77802->opmode[id] = MAX77802_OPMODE_NORMAL;
else
max77802->opmode[id] = val;
rdev = devm_regulator_register(&pdev->dev,
&regulators[i], &config);
if (IS_ERR(rdev)) {
dev_err(&pdev->dev,
"regulator init failed for %d\n", i);
return PTR_ERR(rdev);
}
}
return 0;
}
static const struct platform_device_id max77802_pmic_id[] = {
{"max77802-pmic", 0},
{ },
};
MODULE_DEVICE_TABLE(platform, max77802_pmic_id);
static struct platform_driver max77802_pmic_driver = {
.driver = {
.name = "max77802-pmic",
.owner = THIS_MODULE,
},
.probe = max77802_pmic_probe,
.id_table = max77802_pmic_id,
};
module_platform_driver(max77802_pmic_driver);
MODULE_DESCRIPTION("MAXIM 77802 Regulator Driver");
MODULE_AUTHOR("Simon Glass <sjg@chromium.org>");
MODULE_LICENSE("GPL");
......@@ -40,7 +40,7 @@
*/
struct max1586_subdev_data {
int id;
char *name;
const char *name;
struct regulator_init_data *platform_data;
};
......
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