Merge branches 'ib-mfd-arm-leds-4.10' and 'ib-mfd-gpio-input-regulator-4.10' into ibs-for-mfd-merged

This commit is contained in:
Lee Jones 2016-11-21 12:59:46 +00:00
commit 94662d3075
6 changed files with 157 additions and 131 deletions

View File

@ -1,23 +1,78 @@
TPS65218 family of regulators
Required properties:
For tps65218 regulators/LDOs
- compatible:
- "ti,tps65218-dcdc1" for DCDC1
- "ti,tps65218-dcdc2" for DCDC2
- "ti,tps65218-dcdc3" for DCDC3
- "ti,tps65218-dcdc4" for DCDC4
- "ti,tps65218-dcdc5" for DCDC5
- "ti,tps65218-dcdc6" for DCDC6
- "ti,tps65218-ldo1" for LDO1
- compatible: "ti,tps65218"
- reg: I2C slave address
Optional properties:
- Any optional property defined in bindings/regulator/regulator.txt
- List of regulators provided by this controller, must be named
after their hardware counterparts: dcdc[1-6] and ldo1
- This is the list of child nodes that specify the regulator
initialization data for defined regulators. Not all regulators for the given
device need to be present. The definition for each of these nodes is defined
using the standard binding for regulators found at ./regulator.txt.
The valid names for regulators are:
tps65217: regulator-dcdc1, regulator-dcdc2, regulator-dcdc3, regulator-dcdc4,
regulator-dcdc5, regulator-dcdc6, regulator-ldo1, regulator-ls3.
Each regulator is defined using the standard binding for regulators.
Example:
tps65218: tps65218@24 {
reg = <0x24>;
compatible = "ti,tps65218";
interrupts = <GIC_SPI 7 IRQ_TYPE_NONE>; /* NMIn */
interrupt-controller;
#interrupt-cells = <2>;
xyz: regulator@0 {
compatible = "ti,tps65218-dcdc1";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <3000000>;
dcdc1: regulator-dcdc1 {
regulator-name = "vdd_core";
regulator-min-microvolt = <912000>;
regulator-max-microvolt = <1144000>;
regulator-boot-on;
regulator-always-on;
};
dcdc2: regulator-dcdc2 {
regulator-name = "vdd_mpu";
regulator-min-microvolt = <912000>;
regulator-max-microvolt = <1378000>;
regulator-boot-on;
regulator-always-on;
};
dcdc3: regulator-dcdc3 {
regulator-name = "vdcdc3";
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1500000>;
regulator-boot-on;
regulator-always-on;
};
dcdc5: regulator-dcdc5 {
regulator-name = "v1_0bat";
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <1000000>;
regulator-boot-on;
regulator-always-on;
};
dcdc6: regulator-dcdc6 {
regulator-name = "v1_8bat";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-boot-on;
regulator-always-on;
};
ldo1: regulator-ldo1 {
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-boot-on;
regulator-always-on;
};
ls3: regulator-ls3 {
regulator-min-microvolt = <100000>;
regulator-max-microvolt = <1000000>;
};
};

View File

@ -16,6 +16,7 @@
#include <linux/errno.h>
#include <linux/gpio/driver.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/mfd/tps65218.h>
struct tps65218_gpio {
@ -30,7 +31,7 @@ static int tps65218_gpio_get(struct gpio_chip *gc, unsigned offset)
unsigned int val;
int ret;
ret = tps65218_reg_read(tps65218, TPS65218_REG_ENABLE2, &val);
ret = regmap_read(tps65218->regmap, TPS65218_REG_ENABLE2, &val);
if (ret)
return ret;

View File

@ -150,12 +150,20 @@ static int tps6521x_pb_probe(struct platform_device *pdev)
return 0;
}
static const struct platform_device_id tps6521x_pwrbtn_id_table[] = {
{ "tps65218-pwrbutton", },
{ "tps65217-pwrbutton", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, tps6521x_pwrbtn_id_table);
static struct platform_driver tps6521x_pb_driver = {
.probe = tps6521x_pb_probe,
.driver = {
.name = "tps6521x_pwrbutton",
.of_match_table = of_tps6521x_pb_match,
},
.id_table = tps6521x_pwrbtn_id_table,
};
module_platform_driver(tps6521x_pb_driver);

View File

@ -33,19 +33,17 @@
#define TPS65218_PASSWORD_REGS_UNLOCK 0x7D
/**
* tps65218_reg_read: Read a single tps65218 register.
*
* @tps: Device to read from.
* @reg: Register to read.
* @val: Contians the value
*/
int tps65218_reg_read(struct tps65218 *tps, unsigned int reg,
unsigned int *val)
{
return regmap_read(tps->regmap, reg, val);
}
EXPORT_SYMBOL_GPL(tps65218_reg_read);
static const struct mfd_cell tps65218_cells[] = {
{
.name = "tps65218-pwrbutton",
.of_compatible = "ti,tps65218-pwrbutton",
},
{
.name = "tps65218-gpio",
.of_compatible = "ti,tps65218-gpio",
},
{ .name = "tps65218-regulator", },
};
/**
* tps65218_reg_write: Write a single tps65218 register.
@ -93,7 +91,7 @@ static int tps65218_update_bits(struct tps65218 *tps, unsigned int reg,
int ret;
unsigned int data;
ret = tps65218_reg_read(tps, reg, &data);
ret = regmap_read(tps->regmap, reg, &data);
if (ret) {
dev_err(tps->dev, "Read from reg 0x%x failed\n", reg);
return ret;
@ -251,7 +249,7 @@ static int tps65218_probe(struct i2c_client *client,
if (ret < 0)
return ret;
ret = tps65218_reg_read(tps, TPS65218_REG_CHIPID, &chipid);
ret = regmap_read(tps->regmap, TPS65218_REG_CHIPID, &chipid);
if (ret) {
dev_err(tps->dev, "Failed to read chipid: %d\n", ret);
return ret;
@ -259,8 +257,10 @@ static int tps65218_probe(struct i2c_client *client,
tps->rev = chipid & TPS65218_CHIPID_REV_MASK;
ret = of_platform_populate(client->dev.of_node, NULL, NULL,
&client->dev);
ret = mfd_add_devices(tps->dev, PLATFORM_DEVID_AUTO, tps65218_cells,
ARRAY_SIZE(tps65218_cells), NULL, 0,
regmap_irq_get_domain(tps->irq_data));
if (ret < 0)
goto err_irq;

View File

@ -22,6 +22,7 @@
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
@ -30,10 +31,11 @@
enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4,
DCDC5, DCDC6, LDO1, LS3 };
#define TPS65218_REGULATOR(_name, _id, _type, _ops, _n, _vr, _vm, _er, _em, \
_cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm) \
#define TPS65218_REGULATOR(_name, _of, _id, _type, _ops, _n, _vr, _vm, _er, \
_em, _cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm) \
{ \
.name = _name, \
.of_match = _of, \
.id = _id, \
.ops = &_ops, \
.n_voltages = _n, \
@ -54,14 +56,6 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4,
.bypass_mask = _sm, \
} \
#define TPS65218_INFO(_id, _nm, _min, _max) \
[_id] = { \
.id = _id, \
.name = _nm, \
.min_uV = _min, \
.max_uV = _max, \
}
static const struct regulator_linear_range dcdc1_dcdc2_ranges[] = {
REGULATOR_LINEAR_RANGE(850000, 0x0, 0x32, 10000),
REGULATOR_LINEAR_RANGE(1375000, 0x33, 0x3f, 25000),
@ -77,36 +71,6 @@ static const struct regulator_linear_range dcdc4_ranges[] = {
REGULATOR_LINEAR_RANGE(1600000, 0x10, 0x34, 50000),
};
static struct tps_info tps65218_pmic_regs[] = {
TPS65218_INFO(DCDC1, "DCDC1", 850000, 1675000),
TPS65218_INFO(DCDC2, "DCDC2", 850000, 1675000),
TPS65218_INFO(DCDC3, "DCDC3", 900000, 3400000),
TPS65218_INFO(DCDC4, "DCDC4", 1175000, 3400000),
TPS65218_INFO(DCDC5, "DCDC5", 1000000, 1000000),
TPS65218_INFO(DCDC6, "DCDC6", 1800000, 1800000),
TPS65218_INFO(LDO1, "LDO1", 900000, 3400000),
TPS65218_INFO(LS3, "LS3", -1, -1),
};
#define TPS65218_OF_MATCH(comp, label) \
{ \
.compatible = comp, \
.data = &label, \
}
static const struct of_device_id tps65218_of_match[] = {
TPS65218_OF_MATCH("ti,tps65218-dcdc1", tps65218_pmic_regs[DCDC1]),
TPS65218_OF_MATCH("ti,tps65218-dcdc2", tps65218_pmic_regs[DCDC2]),
TPS65218_OF_MATCH("ti,tps65218-dcdc3", tps65218_pmic_regs[DCDC3]),
TPS65218_OF_MATCH("ti,tps65218-dcdc4", tps65218_pmic_regs[DCDC4]),
TPS65218_OF_MATCH("ti,tps65218-dcdc5", tps65218_pmic_regs[DCDC5]),
TPS65218_OF_MATCH("ti,tps65218-dcdc6", tps65218_pmic_regs[DCDC6]),
TPS65218_OF_MATCH("ti,tps65218-ldo1", tps65218_pmic_regs[LDO1]),
TPS65218_OF_MATCH("ti,tps65218-ls3", tps65218_pmic_regs[LS3]),
{ }
};
MODULE_DEVICE_TABLE(of, tps65218_of_match);
static int tps65218_pmic_set_voltage_sel(struct regulator_dev *dev,
unsigned selector)
{
@ -188,7 +152,7 @@ static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev)
if (rid == TPS65218_DCDC_3 && tps->rev == TPS65218_REV_2_1)
return 0;
if (!tps->info[rid]->strobe) {
if (!tps->strobes[rid]) {
if (rid == TPS65218_DCDC_3)
tps->info[rid]->strobe = 3;
else
@ -197,8 +161,7 @@ static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev)
return tps65218_set_bits(tps, dev->desc->bypass_reg,
dev->desc->bypass_mask,
tps->info[rid]->strobe,
TPS65218_PROTECT_L1);
tps->strobes[rid], TPS65218_PROTECT_L1);
}
/* Operations permitted on DCDC1, DCDC2 */
@ -272,7 +235,7 @@ static int tps65218_pmic_get_current_limit(struct regulator_dev *dev)
unsigned int index;
struct tps65218 *tps = rdev_get_drvdata(dev);
retval = tps65218_reg_read(tps, dev->desc->csel_reg, &index);
retval = regmap_read(tps->regmap, dev->desc->csel_reg, &index);
if (retval < 0)
return retval;
@ -300,104 +263,104 @@ static struct regulator_ops tps65218_dcdc56_pmic_ops = {
};
static const struct regulator_desc regulators[] = {
TPS65218_REGULATOR("DCDC1", TPS65218_DCDC_1, REGULATOR_VOLTAGE,
tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC1,
TPS65218_REGULATOR("DCDC1", "regulator-dcdc1", TPS65218_DCDC_1,
REGULATOR_VOLTAGE, tps65218_dcdc12_ops, 64,
TPS65218_REG_CONTROL_DCDC1,
TPS65218_CONTROL_DCDC1_MASK, TPS65218_REG_ENABLE1,
TPS65218_ENABLE1_DC1_EN, 0, 0, dcdc1_dcdc2_ranges,
2, 4000, 0, TPS65218_REG_SEQ3,
TPS65218_SEQ3_DC1_SEQ_MASK),
TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, REGULATOR_VOLTAGE,
tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC2,
TPS65218_REGULATOR("DCDC2", "regulator-dcdc2", TPS65218_DCDC_2,
REGULATOR_VOLTAGE, tps65218_dcdc12_ops, 64,
TPS65218_REG_CONTROL_DCDC2,
TPS65218_CONTROL_DCDC2_MASK, TPS65218_REG_ENABLE1,
TPS65218_ENABLE1_DC2_EN, 0, 0, dcdc1_dcdc2_ranges,
2, 4000, 0, TPS65218_REG_SEQ3,
TPS65218_SEQ3_DC2_SEQ_MASK),
TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, REGULATOR_VOLTAGE,
tps65218_ldo1_dcdc34_ops, 64,
TPS65218_REGULATOR("DCDC3", "regulator-dcdc3", TPS65218_DCDC_3,
REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64,
TPS65218_REG_CONTROL_DCDC3,
TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1,
TPS65218_ENABLE1_DC3_EN, 0, 0, ldo1_dcdc3_ranges, 2,
0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC3_SEQ_MASK),
TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, REGULATOR_VOLTAGE,
tps65218_ldo1_dcdc34_ops, 53,
TPS65218_REGULATOR("DCDC4", "regulator-dcdc4", TPS65218_DCDC_4,
REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 53,
TPS65218_REG_CONTROL_DCDC4,
TPS65218_CONTROL_DCDC4_MASK, TPS65218_REG_ENABLE1,
TPS65218_ENABLE1_DC4_EN, 0, 0, dcdc4_ranges, 2,
0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC4_SEQ_MASK),
TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, REGULATOR_VOLTAGE,
tps65218_dcdc56_pmic_ops, 1, -1, -1,
TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, 0, 0,
NULL, 0, 0, 1000000, TPS65218_REG_SEQ5,
TPS65218_REGULATOR("DCDC5", "regulator-dcdc5", TPS65218_DCDC_5,
REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1,
-1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, 0,
0, NULL, 0, 0, 1000000, TPS65218_REG_SEQ5,
TPS65218_SEQ5_DC5_SEQ_MASK),
TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, REGULATOR_VOLTAGE,
tps65218_dcdc56_pmic_ops, 1, -1, -1,
TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, 0, 0,
NULL, 0, 0, 1800000, TPS65218_REG_SEQ5,
TPS65218_REGULATOR("DCDC6", "regulator-dcdc6", TPS65218_DCDC_6,
REGULATOR_VOLTAGE, tps65218_dcdc56_pmic_ops, 1, -1,
-1, TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, 0,
0, NULL, 0, 0, 1800000, TPS65218_REG_SEQ5,
TPS65218_SEQ5_DC6_SEQ_MASK),
TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, REGULATOR_VOLTAGE,
tps65218_ldo1_dcdc34_ops, 64,
TPS65218_REGULATOR("LDO1", "regulator-ldo1", TPS65218_LDO_1,
REGULATOR_VOLTAGE, tps65218_ldo1_dcdc34_ops, 64,
TPS65218_REG_CONTROL_LDO1,
TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2,
TPS65218_ENABLE2_LDO1_EN, 0, 0, ldo1_dcdc3_ranges,
2, 0, 0, TPS65218_REG_SEQ6,
TPS65218_SEQ6_LDO1_SEQ_MASK),
TPS65218_REGULATOR("LS3", TPS65218_LS_3, REGULATOR_CURRENT,
tps65218_ls3_ops, 0, 0, 0, TPS65218_REG_ENABLE2,
TPS65218_ENABLE2_LS3_EN, TPS65218_REG_CONFIG2,
TPS65218_CONFIG2_LS3ILIM_MASK, NULL, 0, 0, 0, 0, 0),
TPS65218_REGULATOR("LS3", "regulator-ls3", TPS65218_LS_3,
REGULATOR_CURRENT, tps65218_ls3_ops, 0, 0, 0,
TPS65218_REG_ENABLE2, TPS65218_ENABLE2_LS3_EN,
TPS65218_REG_CONFIG2, TPS65218_CONFIG2_LS3ILIM_MASK,
NULL, 0, 0, 0, 0, 0),
};
static int tps65218_regulator_probe(struct platform_device *pdev)
{
struct tps65218 *tps = dev_get_drvdata(pdev->dev.parent);
struct regulator_init_data *init_data;
const struct tps_info *template;
struct regulator_dev *rdev;
const struct of_device_id *match;
struct regulator_config config = { };
int id, ret;
int i, ret;
unsigned int val;
match = of_match_device(tps65218_of_match, &pdev->dev);
if (!match)
return -ENODEV;
template = match->data;
id = template->id;
init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node,
&regulators[id]);
platform_set_drvdata(pdev, tps);
tps->info[id] = &tps65218_pmic_regs[id];
config.dev = &pdev->dev;
config.init_data = init_data;
config.dev->of_node = tps->dev->of_node;
config.driver_data = tps;
config.regmap = tps->regmap;
config.of_node = pdev->dev.of_node;
rdev = devm_regulator_register(&pdev->dev, &regulators[id], &config);
if (IS_ERR(rdev)) {
dev_err(tps->dev, "failed to register %s regulator\n",
pdev->name);
return PTR_ERR(rdev);
/* Allocate memory for strobes */
tps->strobes = devm_kzalloc(&pdev->dev, sizeof(u8) *
TPS65218_NUM_REGULATOR, GFP_KERNEL);
for (i = 0; i < ARRAY_SIZE(regulators); i++) {
rdev = devm_regulator_register(&pdev->dev, &regulators[i],
&config);
if (IS_ERR(rdev)) {
dev_err(tps->dev, "failed to register %s regulator\n",
pdev->name);
return PTR_ERR(rdev);
}
ret = regmap_read(tps->regmap, regulators[i].bypass_reg, &val);
if (ret)
return ret;
tps->strobes[i] = val & regulators[i].bypass_mask;
}
ret = tps65218_reg_read(tps, regulators[id].bypass_reg, &val);
if (ret)
return ret;
tps->info[id]->strobe = val & regulators[id].bypass_mask;
return 0;
}
static const struct platform_device_id tps65218_regulator_id_table[] = {
{ "tps65218-regulator", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(platform, tps65218_regulator_id_table);
static struct platform_driver tps65218_regulator_driver = {
.driver = {
.name = "tps65218-pmic",
.of_match_table = tps65218_of_match,
},
.probe = tps65218_regulator_probe,
.id_table = tps65218_regulator_id_table,
};
module_platform_driver(tps65218_regulator_driver);

View File

@ -282,10 +282,9 @@ struct tps65218 {
struct regulator_desc desc[TPS65218_NUM_REGULATOR];
struct tps_info *info[TPS65218_NUM_REGULATOR];
struct regmap *regmap;
u8 *strobes;
};
int tps65218_reg_read(struct tps65218 *tps, unsigned int reg,
unsigned int *val);
int tps65218_reg_write(struct tps65218 *tps, unsigned int reg,
unsigned int val, unsigned int level);
int tps65218_set_bits(struct tps65218 *tps, unsigned int reg,