regulator: Updates for v3.14

A respin of the merges in the previous pull request with one extra fix.
 A quiet release for the regulator API, quite a large number of small
 improvements all over but other than the addition of new drivers for the
 AS3722 and MAX14577 there is nothing of substantial non-local impact.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJS4QTYAAoJELSic+t+oim92bMP/09kMG+4zS6TGM+ljselfYLQ
 XmqEAfLpND+07HmxlCRMHIRdrzMm7QrrW076UT3u6Q/RUi6L7LjXWdFNhm9d7k4V
 l45lvpo8C+bJkmX9Y9+dBPKbY5qnz9Kttpr/8wn0uAz1zhqhCCG2GYp0eV7Qcz7L
 XrBfiWmmeu11ArFtQcVPheGMdjiG2hpxbHqJ4e5nZ8kJ3C31RgfTR2r8xA8xr99H
 LhzuwoKjlsjzIuXUgd2F/i4TqtOkpg69wQocRnOYyyEpd4TnI+q4pk4GiMx4EuH1
 GMZ/XGmd1GuiAa7hXIWOyz7vNe54RPoLTWN8QEaYGXf8m/AUUVbje33BTtWbwEeU
 VXWbKpNEWWzykE6lPtxY9I0KMYbqAUvcflIL7kLYbxLS6RE5U4+dwYVEF0gwAWor
 svwgwXhjzNCJhb+DQlzKQa2zcWwJr0uT+DllPXEXJE5yIIn7cHEraYcS4cPfLNL5
 MLnB9BGX5zJQDJVsex/8jnCafI7M/CefIB06CbLK4klR1OtyTJc3yEhGCgWlJU4C
 NKdUbUhirCkPqY2v4RwWwOaxGs0WFWsyd5gYhCy3gL7O22pGW5yGO3MG524mRWrU
 ccU9lbpXgtHTTcb+RKBEwr9fWEcsCIt5gImcRoMxqfkjY0CsQJD8tVdl4Md7OYYv
 BjJexZZulWce7R3F7+Kf
 =1NsR
 -----END PGP SIGNATURE-----

Merge tag 'regulator-v3.14-2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator

Pull regulator updates from Mark Brown:
 "A respin of the merges in the previous pull request with one extra
  fix.

  A quiet release for the regulator API, quite a large number of small
  improvements all over but other than the addition of new drivers for
  the AS3722 and MAX14577 there is nothing of substantial non-local
  impact"

* tag 'regulator-v3.14-2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (47 commits)
  regulator: pfuze100-regulator: Improve dev_info() message
  regulator: pfuze100-regulator: Fix some checkpatch complaints
  regulator: twl: Fix checkpatch issue
  regulator: core: Fix checkpatch issue
  regulator: anatop-regulator: Remove unneeded memset()
  regulator: s5m8767: Update LDO index in s5m8767-regulator.txt
  regulator: as3722: set enable time for SD0/1/6
  regulator: as3722: detect SD0 low-voltage mode
  regulator: tps62360: Fix up a pointer-integer size mismatch warning
  regulator: anatop-regulator: Remove unneeded kstrdup()
  regulator: act8865: Fix build error when !OF
  regulator: act8865: register all regulators regardless of how many are used
  regulator: wm831x-dcdc: Remove unneeded 'err' label
  regulator: anatop-regulator: Add MODULE_ALIAS()
  regulator: act8865: fix incorrect devm_kzalloc for act8865
  regulator: act8865: Remove set_suspend_[en|dis]able implementation
  regulator: act8865: Remove unneeded regulator_unregister() calls
  regulator: s2mps11: Clean up redundant code
  regulator: tps65910: Simplify setting enable_mask for regulators
  regulator: act8865: add device tree binding doc
  ...
This commit is contained in:
Linus Torvalds 2014-01-25 13:19:10 -08:00
commit 15333539a9
36 changed files with 1017 additions and 460 deletions

View file

@ -21,7 +21,7 @@ Required properties:
The valid regulator-compatible values are: The valid regulator-compatible values are:
tps65910: vrtc, vio, vdd1, vdd2, vdd3, vdig1, vdig2, vpll, vdac, vaux1, tps65910: vrtc, vio, vdd1, vdd2, vdd3, vdig1, vdig2, vpll, vdac, vaux1,
vaux2, vaux33, vmmc vaux2, vaux33, vmmc, vbb
tps65911: vrtc, vio, vdd1, vdd3, vddctrl, ldo1, ldo2, ldo3, ldo4, ldo5, tps65911: vrtc, vio, vdd1, vdd3, vddctrl, ldo1, ldo2, ldo3, ldo4, ldo5,
ldo6, ldo7, ldo8 ldo6, ldo7, ldo8
@ -38,7 +38,7 @@ Required properties:
vcc4-supply: VAUX1 and VAUX2 input. vcc4-supply: VAUX1 and VAUX2 input.
vcc5-supply: VPLL and VDAC input. vcc5-supply: VPLL and VDAC input.
vcc6-supply: VDIG1 and VDIG2 input. vcc6-supply: VDIG1 and VDIG2 input.
vcc7-supply: VRTC input. vcc7-supply: VRTC and VBB input.
vccio-supply: VIO input. vccio-supply: VIO input.
tps65911: tps65911:
vcc1-supply: VDD1 input. vcc1-supply: VDD1 input.

View file

@ -0,0 +1,60 @@
ACT8865 regulator
-------------------
Required properties:
- compatible: "active-semi,act8865"
- reg: I2C slave address
Any standard regulator properties can be used to configure the single regulator.
The valid names for regulators are:
DCDC_REG1, DCDC_REG2, DCDC_REG3, LDO_REG1, LDO_REG2, LDO_REG3, LDO_REG4.
Example:
--------
i2c1: i2c@f0018000 {
pmic: act8865@5b {
compatible = "active-semi,act8865";
reg = <0x5b>;
status = "disabled";
regulators {
vcc_1v8_reg: DCDC_REG1 {
regulator-name = "VCC_1V8";
regulator-min-microvolt = <1800000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
};
vcc_1v2_reg: DCDC_REG2 {
regulator-name = "VCC_1V2";
regulator-min-microvolt = <1100000>;
regulator-max-microvolt = <1300000>;
regulator-suspend-mem-microvolt = <1150000>;
regulator-suspend-standby-microvolt = <1150000>;
regulator-always-on;
};
vcc_3v3_reg: DCDC_REG3 {
regulator-name = "VCC_3V3";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
vddana_reg: LDO_REG1 {
regulator-name = "VDDANA";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
};
vddfuse_reg: LDO_REG2 {
regulator-name = "FUSE_2V5";
regulator-min-microvolt = <2500000>;
regulator-max-microvolt = <2500000>;
};
};
};
};

View file

@ -83,7 +83,7 @@ as per the datasheet of s5m8767.
- LDOn - LDOn
- valid values for n are 1 to 28 - valid values for n are 1 to 28
- Example: LDO0, LD01, LDO28 - Example: LDO1, LD02, LDO28
- BUCKn - BUCKn
- valid values for n are 1 to 9. - valid values for n are 1 to 9.
- Example: BUCK1, BUCK2, BUCK9 - Example: BUCK1, BUCK2, BUCK9

View file

@ -3,6 +3,7 @@ Device tree binding vendor prefix registry. Keep list in alphabetical order.
This isn't an exhaustive list, but you should add new prefixes to it before This isn't an exhaustive list, but you should add new prefixes to it before
using them to avoid name-space collisions. using them to avoid name-space collisions.
active-semi Active-Semi International Inc
ad Avionic Design GmbH ad Avionic Design GmbH
adi Analog Devices, Inc. adi Analog Devices, Inc.
aeroflexgaisler Aeroflex Gaisler AB aeroflexgaisler Aeroflex Gaisler AB

View file

@ -245,7 +245,7 @@ static int pcf50633_probe(struct i2c_client *client,
for (i = 0; i < PCF50633_NUM_REGULATORS; i++) { for (i = 0; i < PCF50633_NUM_REGULATORS; i++) {
struct platform_device *pdev; struct platform_device *pdev;
pdev = platform_device_alloc("pcf50633-regltr", i); pdev = platform_device_alloc("pcf50633-regulator", i);
if (!pdev) { if (!pdev) {
dev_err(pcf->dev, "Cannot create regulator %d\n", i); dev_err(pcf->dev, "Cannot create regulator %d\n", i);
continue; continue;

View file

@ -81,36 +81,6 @@ static struct of_device_id sec_dt_match[] = {
}; };
#endif #endif
int sec_reg_read(struct sec_pmic_dev *sec_pmic, u8 reg, void *dest)
{
return regmap_read(sec_pmic->regmap_pmic, reg, dest);
}
EXPORT_SYMBOL_GPL(sec_reg_read);
int sec_bulk_read(struct sec_pmic_dev *sec_pmic, u8 reg, int count, u8 *buf)
{
return regmap_bulk_read(sec_pmic->regmap_pmic, reg, buf, count);
}
EXPORT_SYMBOL_GPL(sec_bulk_read);
int sec_reg_write(struct sec_pmic_dev *sec_pmic, u8 reg, u8 value)
{
return regmap_write(sec_pmic->regmap_pmic, reg, value);
}
EXPORT_SYMBOL_GPL(sec_reg_write);
int sec_bulk_write(struct sec_pmic_dev *sec_pmic, u8 reg, int count, u8 *buf)
{
return regmap_raw_write(sec_pmic->regmap_pmic, reg, buf, count);
}
EXPORT_SYMBOL_GPL(sec_bulk_write);
int sec_reg_update(struct sec_pmic_dev *sec_pmic, u8 reg, u8 val, u8 mask)
{
return regmap_update_bits(sec_pmic->regmap_pmic, reg, mask, val);
}
EXPORT_SYMBOL_GPL(sec_reg_update);
static bool s2mps11_volatile(struct device *dev, unsigned int reg) static bool s2mps11_volatile(struct device *dev, unsigned int reg)
{ {
switch (reg) { switch (reg) {

View file

@ -70,6 +70,14 @@ config REGULATOR_88PM8607
help help
This driver supports 88PM8607 voltage regulator chips. This driver supports 88PM8607 voltage regulator chips.
config REGULATOR_ACT8865
tristate "Active-semi act8865 voltage regulator"
depends on I2C
select REGMAP_I2C
help
This driver controls a active-semi act8865 voltage output
regulator via I2C bus.
config REGULATOR_AD5398 config REGULATOR_AD5398
tristate "Analog Devices AD5398/AD5821 regulators" tristate "Analog Devices AD5398/AD5821 regulators"
depends on I2C depends on I2C
@ -249,6 +257,13 @@ config REGULATOR_LP8788
help help
This driver supports LP8788 voltage regulator chip. This driver supports LP8788 voltage regulator chip.
config REGULATOR_MAX14577
tristate "Maxim 14577 regulator"
depends on MFD_MAX14577
help
This driver controls a Maxim 14577 regulator via I2C bus.
The regulators include safeout LDO and current regulator 'CHARGER'.
config REGULATOR_MAX1586 config REGULATOR_MAX1586
tristate "Maxim 1586/1587 voltage regulator" tristate "Maxim 1586/1587 voltage regulator"
depends on I2C depends on I2C
@ -384,7 +399,7 @@ config REGULATOR_PCF50633
on PCF50633 on PCF50633
config REGULATOR_PFUZE100 config REGULATOR_PFUZE100
tristate "Support regulators on Freescale PFUZE100 PMIC" tristate "Freescale PFUZE100 regulator driver"
depends on I2C depends on I2C
select REGMAP_I2C select REGMAP_I2C
help help

View file

@ -14,6 +14,7 @@ obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o obj-$(CONFIG_REGULATOR_AAT2870) += aat2870-regulator.o
obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
obj-$(CONFIG_REGULATOR_AB8500) += ab8500-ext.o ab8500.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500-ext.o ab8500.o
obj-$(CONFIG_REGULATOR_ACT8865) += act8865-regulator.o
obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o
obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o
obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o
@ -35,6 +36,7 @@ obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o
obj-$(CONFIG_REGULATOR_LP8788) += lp8788-buck.o obj-$(CONFIG_REGULATOR_LP8788) += lp8788-buck.o
obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o
obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o
obj-$(CONFIG_REGULATOR_MAX14577) += max14577.o
obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o

View file

@ -2998,37 +2998,6 @@ static void abx500_get_regulator_info(struct ab8500 *ab8500)
} }
} }
static int ab8500_regulator_init_registers(struct platform_device *pdev,
int id, int mask, int value)
{
struct ab8500_reg_init *reg_init = abx500_regulator.init;
int err;
BUG_ON(value & ~mask);
BUG_ON(mask & ~reg_init[id].mask);
/* initialize register */
err = abx500_mask_and_set_register_interruptible(
&pdev->dev,
reg_init[id].bank,
reg_init[id].addr,
mask, value);
if (err < 0) {
dev_err(&pdev->dev,
"Failed to initialize 0x%02x, 0x%02x.\n",
reg_init[id].bank,
reg_init[id].addr);
return err;
}
dev_vdbg(&pdev->dev,
" init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
reg_init[id].bank,
reg_init[id].addr,
mask, value);
return 0;
}
static int ab8500_regulator_register(struct platform_device *pdev, static int ab8500_regulator_register(struct platform_device *pdev,
struct regulator_init_data *init_data, struct regulator_init_data *init_data,
int id, struct device_node *np) int id, struct device_node *np)
@ -3036,7 +3005,6 @@ static int ab8500_regulator_register(struct platform_device *pdev,
struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
struct ab8500_regulator_info *info = NULL; struct ab8500_regulator_info *info = NULL;
struct regulator_config config = { }; struct regulator_config config = { };
int err;
/* assign per-regulator data */ /* assign per-regulator data */
info = &abx500_regulator.info[id]; info = &abx500_regulator.info[id];
@ -3058,17 +3026,12 @@ static int ab8500_regulator_register(struct platform_device *pdev,
} }
/* register regulator with framework */ /* register regulator with framework */
info->regulator = regulator_register(&info->desc, &config); info->regulator = devm_regulator_register(&pdev->dev, &info->desc,
&config);
if (IS_ERR(info->regulator)) { if (IS_ERR(info->regulator)) {
err = PTR_ERR(info->regulator);
dev_err(&pdev->dev, "failed to register regulator %s\n", dev_err(&pdev->dev, "failed to register regulator %s\n",
info->desc.name); info->desc.name);
/* when we fail, un-register all earlier regulators */ return PTR_ERR(info->regulator);
while (--id >= 0) {
info = &abx500_regulator.info[id];
regulator_unregister(info->regulator);
}
return err;
} }
return 0; return 0;
@ -3095,9 +3058,7 @@ static int ab8500_regulator_probe(struct platform_device *pdev)
{ {
struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
struct device_node *np = pdev->dev.of_node; struct device_node *np = pdev->dev.of_node;
struct ab8500_platform_data *ppdata; int err;
struct ab8500_regulator_platform_data *pdata;
int i, err;
if (!ab8500) { if (!ab8500) {
dev_err(&pdev->dev, "null mfd parent\n"); dev_err(&pdev->dev, "null mfd parent\n");
@ -3106,83 +3067,20 @@ static int ab8500_regulator_probe(struct platform_device *pdev)
abx500_get_regulator_info(ab8500); abx500_get_regulator_info(ab8500);
if (np) { err = of_regulator_match(&pdev->dev, np,
err = of_regulator_match(&pdev->dev, np, abx500_regulator.match,
abx500_regulator.match, abx500_regulator.match_size);
abx500_regulator.match_size); if (err < 0) {
if (err < 0) { dev_err(&pdev->dev,
dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", err);
"Error parsing regulator init data: %d\n", err);
return err;
}
err = ab8500_regulator_of_probe(pdev, np);
return err; return err;
} }
return ab8500_regulator_of_probe(pdev, np);
ppdata = dev_get_platdata(ab8500->dev);
if (!ppdata) {
dev_err(&pdev->dev, "null parent pdata\n");
return -EINVAL;
}
pdata = ppdata->regulator;
if (!pdata) {
dev_err(&pdev->dev, "null pdata\n");
return -EINVAL;
}
/* make sure the platform data has the correct size */
if (pdata->num_regulator != abx500_regulator.info_size) {
dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
return -EINVAL;
}
/* initialize debug (initial state is recorded with this call) */
err = ab8500_regulator_debug_init(pdev);
if (err)
return err;
/* initialize registers */
for (i = 0; i < pdata->num_reg_init; i++) {
int id, mask, value;
id = pdata->reg_init[i].id;
mask = pdata->reg_init[i].mask;
value = pdata->reg_init[i].value;
/* check for configuration errors */
BUG_ON(id >= abx500_regulator.init_size);
err = ab8500_regulator_init_registers(pdev, id, mask, value);
if (err < 0)
return err;
}
/* register all regulators */
for (i = 0; i < abx500_regulator.info_size; i++) {
err = ab8500_regulator_register(pdev, &pdata->regulator[i],
i, NULL);
if (err < 0)
return err;
}
return 0;
} }
static int ab8500_regulator_remove(struct platform_device *pdev) static int ab8500_regulator_remove(struct platform_device *pdev)
{ {
int i, err; int err;
for (i = 0; i < abx500_regulator.info_size; i++) {
struct ab8500_regulator_info *info = NULL;
info = &abx500_regulator.info[i];
dev_vdbg(rdev_get_dev(info->regulator),
"%s-remove\n", info->desc.name);
regulator_unregister(info->regulator);
}
/* remove regulator debug */ /* remove regulator debug */
err = ab8500_regulator_debug_exit(pdev); err = ab8500_regulator_debug_exit(pdev);

View file

@ -0,0 +1,349 @@
/*
* act8865-regulator.c - Voltage regulation for the active-semi ACT8865
* http://www.active-semi.com/sheets/ACT8865_Datasheet.pdf
*
* Copyright (C) 2013 Atmel Corporation
*
* 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.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/act8865.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/regulator/of_regulator.h>
#include <linux/regmap.h>
/*
* ACT8865 Global Register Map.
*/
#define ACT8865_SYS_MODE 0x00
#define ACT8865_SYS_CTRL 0x01
#define ACT8865_DCDC1_VSET1 0x20
#define ACT8865_DCDC1_VSET2 0x21
#define ACT8865_DCDC1_CTRL 0x22
#define ACT8865_DCDC2_VSET1 0x30
#define ACT8865_DCDC2_VSET2 0x31
#define ACT8865_DCDC2_CTRL 0x32
#define ACT8865_DCDC3_VSET1 0x40
#define ACT8865_DCDC3_VSET2 0x41
#define ACT8865_DCDC3_CTRL 0x42
#define ACT8865_LDO1_VSET 0x50
#define ACT8865_LDO1_CTRL 0x51
#define ACT8865_LDO2_VSET 0x54
#define ACT8865_LDO2_CTRL 0x55
#define ACT8865_LDO3_VSET 0x60
#define ACT8865_LDO3_CTRL 0x61
#define ACT8865_LDO4_VSET 0x64
#define ACT8865_LDO4_CTRL 0x65
/*
* Field Definitions.
*/
#define ACT8865_ENA 0x80 /* ON - [7] */
#define ACT8865_VSEL_MASK 0x3F /* VSET - [5:0] */
/*
* ACT8865 voltage number
*/
#define ACT8865_VOLTAGE_NUM 64
struct act8865 {
struct regulator_dev *rdev[ACT8865_REG_NUM];
struct regmap *regmap;
};
static const struct regmap_config act8865_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
};
static const struct regulator_linear_range act8865_volatge_ranges[] = {
REGULATOR_LINEAR_RANGE(600000, 0, 23, 25000),
REGULATOR_LINEAR_RANGE(1200000, 24, 47, 50000),
REGULATOR_LINEAR_RANGE(2400000, 48, 63, 100000),
};
static struct regulator_ops act8865_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
static const struct regulator_desc act8865_reg[] = {
{
.name = "DCDC_REG1",
.id = ACT8865_ID_DCDC1,
.ops = &act8865_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = ACT8865_VOLTAGE_NUM,
.linear_ranges = act8865_volatge_ranges,
.n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
.vsel_reg = ACT8865_DCDC1_VSET1,
.vsel_mask = ACT8865_VSEL_MASK,
.enable_reg = ACT8865_DCDC1_CTRL,
.enable_mask = ACT8865_ENA,
.owner = THIS_MODULE,
},
{
.name = "DCDC_REG2",
.id = ACT8865_ID_DCDC2,
.ops = &act8865_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = ACT8865_VOLTAGE_NUM,
.linear_ranges = act8865_volatge_ranges,
.n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
.vsel_reg = ACT8865_DCDC2_VSET1,
.vsel_mask = ACT8865_VSEL_MASK,
.enable_reg = ACT8865_DCDC2_CTRL,
.enable_mask = ACT8865_ENA,
.owner = THIS_MODULE,
},
{
.name = "DCDC_REG3",
.id = ACT8865_ID_DCDC3,
.ops = &act8865_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = ACT8865_VOLTAGE_NUM,
.linear_ranges = act8865_volatge_ranges,
.n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
.vsel_reg = ACT8865_DCDC3_VSET1,
.vsel_mask = ACT8865_VSEL_MASK,
.enable_reg = ACT8865_DCDC3_CTRL,
.enable_mask = ACT8865_ENA,
.owner = THIS_MODULE,
},
{
.name = "LDO_REG1",
.id = ACT8865_ID_LDO1,
.ops = &act8865_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = ACT8865_VOLTAGE_NUM,
.linear_ranges = act8865_volatge_ranges,
.n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
.vsel_reg = ACT8865_LDO1_VSET,
.vsel_mask = ACT8865_VSEL_MASK,
.enable_reg = ACT8865_LDO1_CTRL,
.enable_mask = ACT8865_ENA,
.owner = THIS_MODULE,
},
{
.name = "LDO_REG2",
.id = ACT8865_ID_LDO2,
.ops = &act8865_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = ACT8865_VOLTAGE_NUM,
.linear_ranges = act8865_volatge_ranges,
.n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
.vsel_reg = ACT8865_LDO2_VSET,
.vsel_mask = ACT8865_VSEL_MASK,
.enable_reg = ACT8865_LDO2_CTRL,
.enable_mask = ACT8865_ENA,
.owner = THIS_MODULE,
},
{
.name = "LDO_REG3",
.id = ACT8865_ID_LDO3,
.ops = &act8865_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = ACT8865_VOLTAGE_NUM,
.linear_ranges = act8865_volatge_ranges,
.n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
.vsel_reg = ACT8865_LDO3_VSET,
.vsel_mask = ACT8865_VSEL_MASK,
.enable_reg = ACT8865_LDO3_CTRL,
.enable_mask = ACT8865_ENA,
.owner = THIS_MODULE,
},
{
.name = "LDO_REG4",
.id = ACT8865_ID_LDO4,
.ops = &act8865_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = ACT8865_VOLTAGE_NUM,
.linear_ranges = act8865_volatge_ranges,
.n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
.vsel_reg = ACT8865_LDO4_VSET,
.vsel_mask = ACT8865_VSEL_MASK,
.enable_reg = ACT8865_LDO4_CTRL,
.enable_mask = ACT8865_ENA,
.owner = THIS_MODULE,
},
};
#ifdef CONFIG_OF
static const struct of_device_id act8865_dt_ids[] = {
{ .compatible = "active-semi,act8865" },
{ }
};
MODULE_DEVICE_TABLE(of, act8865_dt_ids);
static struct of_regulator_match act8865_matches[] = {
[ACT8865_ID_DCDC1] = { .name = "DCDC_REG1"},
[ACT8865_ID_DCDC2] = { .name = "DCDC_REG2"},
[ACT8865_ID_DCDC3] = { .name = "DCDC_REG3"},
[ACT8865_ID_LDO1] = { .name = "LDO_REG1"},
[ACT8865_ID_LDO2] = { .name = "LDO_REG2"},
[ACT8865_ID_LDO3] = { .name = "LDO_REG3"},
[ACT8865_ID_LDO4] = { .name = "LDO_REG4"},
};
static int act8865_pdata_from_dt(struct device *dev,
struct device_node **of_node,
struct act8865_platform_data *pdata)
{
int matched, i;
struct device_node *np;
struct act8865_regulator_data *regulator;
np = of_find_node_by_name(dev->of_node, "regulators");
if (!np) {
dev_err(dev, "missing 'regulators' subnode in DT\n");
return -EINVAL;
}
matched = of_regulator_match(dev, np,
act8865_matches, ARRAY_SIZE(act8865_matches));
if (matched <= 0)
return matched;
pdata->regulators = devm_kzalloc(dev,
sizeof(struct act8865_regulator_data) *
ARRAY_SIZE(act8865_matches), GFP_KERNEL);
if (!pdata->regulators) {
dev_err(dev, "%s: failed to allocate act8865 registor\n",
__func__);
return -ENOMEM;
}
pdata->num_regulators = matched;
regulator = pdata->regulators;
for (i = 0; i < ARRAY_SIZE(act8865_matches); i++) {
regulator->id = i;
regulator->name = act8865_matches[i].name;
regulator->platform_data = act8865_matches[i].init_data;
of_node[i] = act8865_matches[i].of_node;
regulator++;
}
return 0;
}
#else
static inline int act8865_pdata_from_dt(struct device *dev,
struct device_node **of_node,
struct act8865_platform_data *pdata)
{
return 0;
}
#endif
static int act8865_pmic_probe(struct i2c_client *client,
const struct i2c_device_id *i2c_id)
{
struct regulator_dev **rdev;
struct device *dev = &client->dev;
struct act8865_platform_data *pdata = dev_get_platdata(dev);
struct regulator_config config = { };
struct act8865 *act8865;
struct device_node *of_node[ACT8865_REG_NUM];
int i, id;
int ret = -EINVAL;
int error;
if (dev->of_node && !pdata) {
const struct of_device_id *id;
struct act8865_platform_data pdata_of;
id = of_match_device(of_match_ptr(act8865_dt_ids), dev);
if (!id)
return -ENODEV;
ret = act8865_pdata_from_dt(dev, of_node, &pdata_of);
if (ret < 0)
return ret;
pdata = &pdata_of;
}
if (pdata->num_regulators > ACT8865_REG_NUM) {
dev_err(dev, "Too many regulators found!\n");
return -EINVAL;
}
act8865 = devm_kzalloc(dev, sizeof(struct act8865), GFP_KERNEL);
if (!act8865)
return -ENOMEM;
rdev = act8865->rdev;
act8865->regmap = devm_regmap_init_i2c(client, &act8865_regmap_config);
if (IS_ERR(act8865->regmap)) {
error = PTR_ERR(act8865->regmap);
dev_err(&client->dev, "Failed to allocate register map: %d\n",
error);
return error;
}
/* Finally register devices */
for (i = 0; i < ACT8865_REG_NUM; i++) {
id = pdata->regulators[i].id;
config.dev = dev;
config.init_data = pdata->regulators[i].platform_data;
config.of_node = of_node[i];
config.driver_data = act8865;
config.regmap = act8865->regmap;
rdev[i] = devm_regulator_register(&client->dev,
&act8865_reg[i], &config);
if (IS_ERR(rdev[i])) {
dev_err(dev, "failed to register %s\n",
act8865_reg[id].name);
return PTR_ERR(rdev[i]);
}
}
i2c_set_clientdata(client, act8865);
return 0;
}
static const struct i2c_device_id act8865_ids[] = {
{ "act8865", 0 },
{ },
};
MODULE_DEVICE_TABLE(i2c, act8865_ids);
static struct i2c_driver act8865_pmic_driver = {
.driver = {
.name = "act8865",
.owner = THIS_MODULE,
},
.probe = act8865_pmic_probe,
.id_table = act8865_ids,
};
module_i2c_driver(act8865_pmic_driver);
MODULE_DESCRIPTION("active-semi act8865 voltage regulator driver");
MODULE_AUTHOR("Wenyou Yang <wenyou.yang@atmel.com>");
MODULE_LICENSE("GPL v2");

View file

@ -122,10 +122,8 @@ static int anatop_regulator_probe(struct platform_device *pdev)
if (!sreg) if (!sreg)
return -ENOMEM; return -ENOMEM;
sreg->initdata = initdata; sreg->initdata = initdata;
sreg->name = kstrdup(of_get_property(np, "regulator-name", NULL), sreg->name = of_get_property(np, "regulator-name", NULL);
GFP_KERNEL);
rdesc = &sreg->rdesc; rdesc = &sreg->rdesc;
memset(rdesc, 0, sizeof(*rdesc));
rdesc->name = sreg->name; rdesc->name = sreg->name;
rdesc->ops = &anatop_rops; rdesc->ops = &anatop_rops;
rdesc->type = REGULATOR_VOLTAGE; rdesc->type = REGULATOR_VOLTAGE;
@ -143,37 +141,37 @@ static int anatop_regulator_probe(struct platform_device *pdev)
&sreg->control_reg); &sreg->control_reg);
if (ret) { if (ret) {
dev_err(dev, "no anatop-reg-offset property set\n"); dev_err(dev, "no anatop-reg-offset property set\n");
goto anatop_probe_end; return ret;
} }
ret = of_property_read_u32(np, "anatop-vol-bit-width", ret = of_property_read_u32(np, "anatop-vol-bit-width",
&sreg->vol_bit_width); &sreg->vol_bit_width);
if (ret) { if (ret) {
dev_err(dev, "no anatop-vol-bit-width property set\n"); dev_err(dev, "no anatop-vol-bit-width property set\n");
goto anatop_probe_end; return ret;
} }
ret = of_property_read_u32(np, "anatop-vol-bit-shift", ret = of_property_read_u32(np, "anatop-vol-bit-shift",
&sreg->vol_bit_shift); &sreg->vol_bit_shift);
if (ret) { if (ret) {
dev_err(dev, "no anatop-vol-bit-shift property set\n"); dev_err(dev, "no anatop-vol-bit-shift property set\n");
goto anatop_probe_end; return ret;
} }
ret = of_property_read_u32(np, "anatop-min-bit-val", ret = of_property_read_u32(np, "anatop-min-bit-val",
&sreg->min_bit_val); &sreg->min_bit_val);
if (ret) { if (ret) {
dev_err(dev, "no anatop-min-bit-val property set\n"); dev_err(dev, "no anatop-min-bit-val property set\n");
goto anatop_probe_end; return ret;
} }
ret = of_property_read_u32(np, "anatop-min-voltage", ret = of_property_read_u32(np, "anatop-min-voltage",
&sreg->min_voltage); &sreg->min_voltage);
if (ret) { if (ret) {
dev_err(dev, "no anatop-min-voltage property set\n"); dev_err(dev, "no anatop-min-voltage property set\n");
goto anatop_probe_end; return ret;
} }
ret = of_property_read_u32(np, "anatop-max-voltage", ret = of_property_read_u32(np, "anatop-max-voltage",
&sreg->max_voltage); &sreg->max_voltage);
if (ret) { if (ret) {
dev_err(dev, "no anatop-max-voltage property set\n"); dev_err(dev, "no anatop-max-voltage property set\n");
goto anatop_probe_end; return ret;
} }
/* read LDO ramp up setting, only for core reg */ /* read LDO ramp up setting, only for core reg */
@ -204,27 +202,11 @@ static int anatop_regulator_probe(struct platform_device *pdev)
if (IS_ERR(rdev)) { if (IS_ERR(rdev)) {
dev_err(dev, "failed to register %s\n", dev_err(dev, "failed to register %s\n",
rdesc->name); rdesc->name);
ret = PTR_ERR(rdev); return PTR_ERR(rdev);
goto anatop_probe_end;
} }
platform_set_drvdata(pdev, rdev); platform_set_drvdata(pdev, rdev);
anatop_probe_end:
if (ret)
kfree(sreg->name);
return ret;
}
static int anatop_regulator_remove(struct platform_device *pdev)
{
struct regulator_dev *rdev = platform_get_drvdata(pdev);
struct anatop_regulator *sreg = rdev_get_drvdata(rdev);
const char *name = sreg->name;
kfree(name);
return 0; return 0;
} }
@ -240,7 +222,6 @@ static struct platform_driver anatop_regulator_driver = {
.of_match_table = of_anatop_regulator_match_tbl, .of_match_table = of_anatop_regulator_match_tbl,
}, },
.probe = anatop_regulator_probe, .probe = anatop_regulator_probe,
.remove = anatop_regulator_remove,
}; };
static int __init anatop_regulator_init(void) static int __init anatop_regulator_init(void)
@ -259,3 +240,4 @@ MODULE_AUTHOR("Nancy Chen <Nancy.Chen@freescale.com>");
MODULE_AUTHOR("Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>"); MODULE_AUTHOR("Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>");
MODULE_DESCRIPTION("ANATOP Regulator driver"); MODULE_DESCRIPTION("ANATOP Regulator driver");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:anatop_regulator");

View file

@ -28,8 +28,6 @@
#include <linux/mfd/arizona/pdata.h> #include <linux/mfd/arizona/pdata.h>
#include <linux/mfd/arizona/registers.h> #include <linux/mfd/arizona/registers.h>
#define ARIZONA_MICSUPP_MAX_SELECTOR 0x1f
struct arizona_micsupp { struct arizona_micsupp {
struct regulator_dev *regulator; struct regulator_dev *regulator;
struct arizona *arizona; struct arizona *arizona;
@ -40,42 +38,6 @@ struct arizona_micsupp {
struct work_struct check_cp_work; struct work_struct check_cp_work;
}; };
static int arizona_micsupp_list_voltage(struct regulator_dev *rdev,
unsigned int selector)
{
if (selector > ARIZONA_MICSUPP_MAX_SELECTOR)
return -EINVAL;
if (selector == ARIZONA_MICSUPP_MAX_SELECTOR)
return 3300000;
else
return (selector * 50000) + 1700000;
}
static int arizona_micsupp_map_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV)
{
unsigned int voltage;
int selector;
if (min_uV < 1700000)
min_uV = 1700000;
if (min_uV > 3200000)
selector = ARIZONA_MICSUPP_MAX_SELECTOR;
else
selector = DIV_ROUND_UP(min_uV - 1700000, 50000);
if (selector < 0)
return -EINVAL;
voltage = arizona_micsupp_list_voltage(rdev, selector);
if (voltage < min_uV || voltage > max_uV)
return -EINVAL;
return selector;
}
static void arizona_micsupp_check_cp(struct work_struct *work) static void arizona_micsupp_check_cp(struct work_struct *work)
{ {
struct arizona_micsupp *micsupp = struct arizona_micsupp *micsupp =
@ -145,8 +107,8 @@ static struct regulator_ops arizona_micsupp_ops = {
.disable = arizona_micsupp_disable, .disable = arizona_micsupp_disable,
.is_enabled = regulator_is_enabled_regmap, .is_enabled = regulator_is_enabled_regmap,
.list_voltage = arizona_micsupp_list_voltage, .list_voltage = regulator_list_voltage_linear_range,
.map_voltage = arizona_micsupp_map_voltage, .map_voltage = regulator_map_voltage_linear_range,
.get_voltage_sel = regulator_get_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap, .set_voltage_sel = regulator_set_voltage_sel_regmap,
@ -155,11 +117,16 @@ static struct regulator_ops arizona_micsupp_ops = {
.set_bypass = arizona_micsupp_set_bypass, .set_bypass = arizona_micsupp_set_bypass,
}; };
static const struct regulator_linear_range arizona_micsupp_ranges[] = {
REGULATOR_LINEAR_RANGE(1700000, 0, 0x1e, 50000),
REGULATOR_LINEAR_RANGE(3300000, 0x1f, 0x1f, 0),
};
static const struct regulator_desc arizona_micsupp = { static const struct regulator_desc arizona_micsupp = {
.name = "MICVDD", .name = "MICVDD",
.supply_name = "CPVDD", .supply_name = "CPVDD",
.type = REGULATOR_VOLTAGE, .type = REGULATOR_VOLTAGE,
.n_voltages = ARIZONA_MICSUPP_MAX_SELECTOR + 1, .n_voltages = 32,
.ops = &arizona_micsupp_ops, .ops = &arizona_micsupp_ops,
.vsel_reg = ARIZONA_LDO2_CONTROL_1, .vsel_reg = ARIZONA_LDO2_CONTROL_1,
@ -169,6 +136,9 @@ static const struct regulator_desc arizona_micsupp = {
.bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1, .bypass_reg = ARIZONA_MIC_CHARGE_PUMP_1,
.bypass_mask = ARIZONA_CPMIC_BYPASS, .bypass_mask = ARIZONA_CPMIC_BYPASS,
.linear_ranges = arizona_micsupp_ranges,
.n_linear_ranges = ARRAY_SIZE(arizona_micsupp_ranges),
.enable_time = 3000, .enable_time = 3000,
.owner = THIS_MODULE, .owner = THIS_MODULE,

View file

@ -99,7 +99,6 @@ static const struct as3722_register_mapping as3722_reg_lookup[] = {
.sleep_ctrl_mask = AS3722_SD0_EXT_ENABLE_MASK, .sleep_ctrl_mask = AS3722_SD0_EXT_ENABLE_MASK,
.control_reg = AS3722_SD0_CONTROL_REG, .control_reg = AS3722_SD0_CONTROL_REG,
.mode_mask = AS3722_SD0_MODE_FAST, .mode_mask = AS3722_SD0_MODE_FAST,
.n_voltages = AS3722_SD0_VSEL_MAX + 1,
}, },
{ {
.regulator_id = AS3722_REGULATOR_ID_SD1, .regulator_id = AS3722_REGULATOR_ID_SD1,
@ -112,7 +111,6 @@ static const struct as3722_register_mapping as3722_reg_lookup[] = {
.sleep_ctrl_mask = AS3722_SD1_EXT_ENABLE_MASK, .sleep_ctrl_mask = AS3722_SD1_EXT_ENABLE_MASK,
.control_reg = AS3722_SD1_CONTROL_REG, .control_reg = AS3722_SD1_CONTROL_REG,
.mode_mask = AS3722_SD1_MODE_FAST, .mode_mask = AS3722_SD1_MODE_FAST,
.n_voltages = AS3722_SD0_VSEL_MAX + 1,
}, },
{ {
.regulator_id = AS3722_REGULATOR_ID_SD2, .regulator_id = AS3722_REGULATOR_ID_SD2,
@ -181,7 +179,6 @@ static const struct as3722_register_mapping as3722_reg_lookup[] = {
.sleep_ctrl_mask = AS3722_SD6_EXT_ENABLE_MASK, .sleep_ctrl_mask = AS3722_SD6_EXT_ENABLE_MASK,
.control_reg = AS3722_SD6_CONTROL_REG, .control_reg = AS3722_SD6_CONTROL_REG,
.mode_mask = AS3722_SD6_MODE_FAST, .mode_mask = AS3722_SD6_MODE_FAST,
.n_voltages = AS3722_SD0_VSEL_MAX + 1,
}, },
{ {
.regulator_id = AS3722_REGULATOR_ID_LDO0, .regulator_id = AS3722_REGULATOR_ID_LDO0,
@ -595,6 +592,22 @@ static int as3722_sd016_set_current_limit(struct regulator_dev *rdev,
return as3722_update_bits(as3722, reg, mask, val); return as3722_update_bits(as3722, reg, mask, val);
} }
static bool as3722_sd0_is_low_voltage(struct as3722_regulators *as3722_regs)
{
int err;
unsigned val;
err = as3722_read(as3722_regs->as3722, AS3722_FUSE7_REG, &val);
if (err < 0) {
dev_err(as3722_regs->dev, "Reg 0x%02x read failed: %d\n",
AS3722_FUSE7_REG, err);
return false;
}
if (val & AS3722_FUSE7_SD0_LOW_VOLTAGE)
return true;
return false;
}
static const struct regulator_linear_range as3722_sd2345_ranges[] = { static const struct regulator_linear_range as3722_sd2345_ranges[] = {
REGULATOR_LINEAR_RANGE(612500, 0x01, 0x40, 12500), REGULATOR_LINEAR_RANGE(612500, 0x01, 0x40, 12500),
REGULATOR_LINEAR_RANGE(1425000, 0x41, 0x70, 25000), REGULATOR_LINEAR_RANGE(1425000, 0x41, 0x70, 25000),
@ -820,9 +833,19 @@ static int as3722_regulator_probe(struct platform_device *pdev)
ops = &as3722_sd016_extcntrl_ops; ops = &as3722_sd016_extcntrl_ops;
else else
ops = &as3722_sd016_ops; ops = &as3722_sd016_ops;
as3722_regs->desc[id].min_uV = 610000; if (id == AS3722_REGULATOR_ID_SD0 &&
as3722_sd0_is_low_voltage(as3722_regs)) {
as3722_regs->desc[id].n_voltages =
AS3722_SD0_VSEL_LOW_VOL_MAX + 1;
as3722_regs->desc[id].min_uV = 410000;
} else {
as3722_regs->desc[id].n_voltages =
AS3722_SD0_VSEL_MAX + 1,
as3722_regs->desc[id].min_uV = 610000;
}
as3722_regs->desc[id].uV_step = 10000; as3722_regs->desc[id].uV_step = 10000;
as3722_regs->desc[id].linear_min_sel = 1; as3722_regs->desc[id].linear_min_sel = 1;
as3722_regs->desc[id].enable_time = 600;
break; break;
case AS3722_REGULATOR_ID_SD2: case AS3722_REGULATOR_ID_SD2:
case AS3722_REGULATOR_ID_SD3: case AS3722_REGULATOR_ID_SD3:
@ -842,9 +865,6 @@ static int as3722_regulator_probe(struct platform_device *pdev)
ops = &as3722_ldo_extcntrl_ops; ops = &as3722_ldo_extcntrl_ops;
else else
ops = &as3722_ldo_ops; ops = &as3722_ldo_ops;
as3722_regs->desc[id].min_uV = 825000;
as3722_regs->desc[id].uV_step = 25000;
as3722_regs->desc[id].linear_min_sel = 1;
as3722_regs->desc[id].enable_time = 500; as3722_regs->desc[id].enable_time = 500;
as3722_regs->desc[id].linear_ranges = as3722_ldo_ranges; as3722_regs->desc[id].linear_ranges = as3722_ldo_ranges;
as3722_regs->desc[id].n_linear_ranges = as3722_regs->desc[id].n_linear_ranges =

View file

@ -1334,9 +1334,8 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
* If we have return value from dev_lookup fail, we do not expect to * If we have return value from dev_lookup fail, we do not expect to
* succeed, so, quit with appropriate error value * succeed, so, quit with appropriate error value
*/ */
if (ret && ret != -ENODEV) { if (ret && ret != -ENODEV)
goto out; goto out;
}
if (!devname) if (!devname)
devname = "deviceless"; devname = "deviceless";
@ -1351,7 +1350,8 @@ static struct regulator *_regulator_get(struct device *dev, const char *id,
rdev = dummy_regulator_rdev; rdev = dummy_regulator_rdev;
goto found; goto found;
} else { /* Don't log an error when called from regulator_get_optional() */
} else if (!have_full_constraints() || exclusive) {
dev_err(dev, "dummy supplies not allowed\n"); dev_err(dev, "dummy supplies not allowed\n");
} }
@ -2244,7 +2244,7 @@ int regulator_is_supported_voltage(struct regulator *regulator,
if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) { if (!(rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_VOLTAGE)) {
ret = regulator_get_voltage(regulator); ret = regulator_get_voltage(regulator);
if (ret >= 0) if (ret >= 0)
return (min_uV <= ret && ret <= max_uV); return min_uV <= ret && ret <= max_uV;
else else
return ret; return ret;
} }
@ -3835,9 +3835,8 @@ static int __init regulator_init_complete(void)
* goes wrong. */ * goes wrong. */
rdev_info(rdev, "disabling\n"); rdev_info(rdev, "disabling\n");
ret = ops->disable(rdev); ret = ops->disable(rdev);
if (ret != 0) { if (ret != 0)
rdev_err(rdev, "couldn't disable: %d\n", ret); rdev_err(rdev, "couldn't disable: %d\n", ret);
}
} else { } else {
/* The intention is that in future we will /* The intention is that in future we will
* assume that full constraints are provided * assume that full constraints are provided

View file

@ -431,17 +431,11 @@ static int db8500_regulator_register(struct platform_device *pdev,
config.of_node = np; config.of_node = np;
/* register with the regulator framework */ /* register with the regulator framework */
info->rdev = regulator_register(&info->desc, &config); info->rdev = devm_regulator_register(&pdev->dev, &info->desc, &config);
if (IS_ERR(info->rdev)) { if (IS_ERR(info->rdev)) {
err = PTR_ERR(info->rdev); err = PTR_ERR(info->rdev);
dev_err(&pdev->dev, "failed to register %s: err %i\n", dev_err(&pdev->dev, "failed to register %s: err %i\n",
info->desc.name, err); info->desc.name, err);
/* if failing, unregister all earlier regulators */
while (--id >= 0) {
info = &dbx500_regulator_info[id];
regulator_unregister(info->rdev);
}
return err; return err;
} }
@ -530,20 +524,8 @@ static int db8500_regulator_probe(struct platform_device *pdev)
static int db8500_regulator_remove(struct platform_device *pdev) static int db8500_regulator_remove(struct platform_device *pdev)
{ {
int i;
ux500_regulator_debug_exit(); ux500_regulator_debug_exit();
for (i = 0; i < ARRAY_SIZE(dbx500_regulator_info); i++) {
struct dbx500_regulator_info *info;
info = &dbx500_regulator_info[i];
dev_vdbg(rdev_get_dev(info->rdev),
"regulator-%s-remove\n", info->desc.name);
regulator_unregister(info->rdev);
}
return 0; return 0;
} }

View file

@ -203,17 +203,18 @@ of_get_gpio_regulator_config(struct device *dev, struct device_node *np)
} }
config->nr_states = i; config->nr_states = i;
config->type = REGULATOR_VOLTAGE;
ret = of_property_read_string(np, "regulator-type", &regtype); ret = of_property_read_string(np, "regulator-type", &regtype);
if (ret < 0) { if (ret >= 0) {
dev_err(dev, "Missing 'regulator-type' property\n"); if (!strncmp("voltage", regtype, 7))
return ERR_PTR(-EINVAL); config->type = REGULATOR_VOLTAGE;
else if (!strncmp("current", regtype, 7))
config->type = REGULATOR_CURRENT;
else
dev_warn(dev, "Unknown regulator-type '%s'\n",
regtype);
} }
if (!strncmp("voltage", regtype, 7))
config->type = REGULATOR_VOLTAGE;
else if (!strncmp("current", regtype, 7))
config->type = REGULATOR_CURRENT;
return config; return config;
} }

View file

@ -25,8 +25,6 @@ struct lp3971 {
struct device *dev; struct device *dev;
struct mutex io_lock; struct mutex io_lock;
struct i2c_client *i2c; struct i2c_client *i2c;
int num_regulators;
struct regulator_dev **rdev;
}; };
static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg); static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg);
@ -383,42 +381,27 @@ static int setup_regulators(struct lp3971 *lp3971,
{ {
int i, err; int i, err;
lp3971->num_regulators = pdata->num_regulators;
lp3971->rdev = kcalloc(pdata->num_regulators,
sizeof(struct regulator_dev *), GFP_KERNEL);
if (!lp3971->rdev) {
err = -ENOMEM;
goto err_nomem;
}
/* Instantiate the regulators */ /* Instantiate the regulators */
for (i = 0; i < pdata->num_regulators; i++) { for (i = 0; i < pdata->num_regulators; i++) {
struct regulator_config config = { }; struct regulator_config config = { };
struct lp3971_regulator_subdev *reg = &pdata->regulators[i]; struct lp3971_regulator_subdev *reg = &pdata->regulators[i];
struct regulator_dev *rdev;
config.dev = lp3971->dev; config.dev = lp3971->dev;
config.init_data = reg->initdata; config.init_data = reg->initdata;
config.driver_data = lp3971; config.driver_data = lp3971;
lp3971->rdev[i] = regulator_register(&regulators[reg->id], rdev = devm_regulator_register(lp3971->dev,
&config); &regulators[reg->id], &config);
if (IS_ERR(lp3971->rdev[i])) { if (IS_ERR(rdev)) {
err = PTR_ERR(lp3971->rdev[i]); err = PTR_ERR(rdev);
dev_err(lp3971->dev, "regulator init failed: %d\n", dev_err(lp3971->dev, "regulator init failed: %d\n",
err); err);
goto error; return err;
} }
} }
return 0; return 0;
error:
while (--i >= 0)
regulator_unregister(lp3971->rdev[i]);
kfree(lp3971->rdev);
lp3971->rdev = NULL;
err_nomem:
return err;
} }
static int lp3971_i2c_probe(struct i2c_client *i2c, static int lp3971_i2c_probe(struct i2c_client *i2c,
@ -460,19 +443,6 @@ static int lp3971_i2c_probe(struct i2c_client *i2c,
return 0; return 0;
} }
static int lp3971_i2c_remove(struct i2c_client *i2c)
{
struct lp3971 *lp3971 = i2c_get_clientdata(i2c);
int i;
for (i = 0; i < lp3971->num_regulators; i++)
regulator_unregister(lp3971->rdev[i]);
kfree(lp3971->rdev);
return 0;
}
static const struct i2c_device_id lp3971_i2c_id[] = { static const struct i2c_device_id lp3971_i2c_id[] = {
{ "lp3971", 0 }, { "lp3971", 0 },
{ } { }
@ -485,7 +455,6 @@ static struct i2c_driver lp3971_i2c_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = lp3971_i2c_probe, .probe = lp3971_i2c_probe,
.remove = lp3971_i2c_remove,
.id_table = lp3971_i2c_id, .id_table = lp3971_i2c_id,
}; };

View file

@ -22,8 +22,6 @@ struct lp3972 {
struct device *dev; struct device *dev;
struct mutex io_lock; struct mutex io_lock;
struct i2c_client *i2c; struct i2c_client *i2c;
int num_regulators;
struct regulator_dev **rdev;
}; };
/* LP3972 Control Registers */ /* LP3972 Control Registers */
@ -478,41 +476,27 @@ static int setup_regulators(struct lp3972 *lp3972,
{ {
int i, err; int i, err;
lp3972->num_regulators = pdata->num_regulators;
lp3972->rdev = kcalloc(pdata->num_regulators,
sizeof(struct regulator_dev *), GFP_KERNEL);
if (!lp3972->rdev) {
err = -ENOMEM;
goto err_nomem;
}
/* Instantiate the regulators */ /* Instantiate the regulators */
for (i = 0; i < pdata->num_regulators; i++) { for (i = 0; i < pdata->num_regulators; i++) {
struct lp3972_regulator_subdev *reg = &pdata->regulators[i]; struct lp3972_regulator_subdev *reg = &pdata->regulators[i];
struct regulator_config config = { }; struct regulator_config config = { };
struct regulator_dev *rdev;
config.dev = lp3972->dev; config.dev = lp3972->dev;
config.init_data = reg->initdata; config.init_data = reg->initdata;
config.driver_data = lp3972; config.driver_data = lp3972;
lp3972->rdev[i] = regulator_register(&regulators[reg->id], rdev = devm_regulator_register(lp3972->dev,
&config); &regulators[reg->id], &config);
if (IS_ERR(lp3972->rdev[i])) { if (IS_ERR(rdev)) {
err = PTR_ERR(lp3972->rdev[i]); err = PTR_ERR(rdev);
dev_err(lp3972->dev, "regulator init failed: %d\n", dev_err(lp3972->dev, "regulator init failed: %d\n",
err); err);
goto error; return err;
} }
} }
return 0; return 0;
error:
while (--i >= 0)
regulator_unregister(lp3972->rdev[i]);
kfree(lp3972->rdev);
lp3972->rdev = NULL;
err_nomem:
return err;
} }
static int lp3972_i2c_probe(struct i2c_client *i2c, static int lp3972_i2c_probe(struct i2c_client *i2c,
@ -557,18 +541,6 @@ static int lp3972_i2c_probe(struct i2c_client *i2c,
return 0; return 0;
} }
static int lp3972_i2c_remove(struct i2c_client *i2c)
{
struct lp3972 *lp3972 = i2c_get_clientdata(i2c);
int i;
for (i = 0; i < lp3972->num_regulators; i++)
regulator_unregister(lp3972->rdev[i]);
kfree(lp3972->rdev);
return 0;
}
static const struct i2c_device_id lp3972_i2c_id[] = { static const struct i2c_device_id lp3972_i2c_id[] = {
{ "lp3972", 0 }, { "lp3972", 0 },
{ } { }
@ -581,7 +553,6 @@ static struct i2c_driver lp3972_i2c_driver = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = lp3972_i2c_probe, .probe = lp3972_i2c_probe,
.remove = lp3972_i2c_remove,
.id_table = lp3972_i2c_id, .id_table = lp3972_i2c_id,
}; };

View file

@ -0,0 +1,273 @@
/*
* max14577.c - Regulator driver for the Maxim 14577
*
* Copyright (C) 2013 Samsung Electronics
* Krzysztof Kozlowski <k.kozlowski@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.
*/
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/mfd/max14577.h>
#include <linux/mfd/max14577-private.h>
#include <linux/regulator/of_regulator.h>
struct max14577_regulator {
struct device *dev;
struct max14577 *max14577;
struct regulator_dev **regulators;
};
static int max14577_reg_is_enabled(struct regulator_dev *rdev)
{
int rid = rdev_get_id(rdev);
struct regmap *rmap = rdev->regmap;
u8 reg_data;
switch (rid) {
case MAX14577_CHARGER:
max14577_read_reg(rmap, MAX14577_CHG_REG_CHG_CTRL2, &reg_data);
if ((reg_data & CHGCTRL2_MBCHOSTEN_MASK) == 0)
return 0;
max14577_read_reg(rmap, MAX14577_CHG_REG_STATUS3, &reg_data);
if ((reg_data & STATUS3_CGMBC_MASK) == 0)
return 0;
/* MBCHOSTEN and CGMBC are on */
return 1;
default:
return -EINVAL;
}
}
static int max14577_reg_get_current_limit(struct regulator_dev *rdev)
{
u8 reg_data;
struct regmap *rmap = rdev->regmap;
if (rdev_get_id(rdev) != MAX14577_CHARGER)
return -EINVAL;
max14577_read_reg(rmap, MAX14577_CHG_REG_CHG_CTRL4, &reg_data);
if ((reg_data & CHGCTRL4_MBCICHWRCL_MASK) == 0)
return MAX14577_REGULATOR_CURRENT_LIMIT_MIN;
reg_data = ((reg_data & CHGCTRL4_MBCICHWRCH_MASK) >>
CHGCTRL4_MBCICHWRCH_SHIFT);
return MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_START +
reg_data * MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_STEP;
}
static int max14577_reg_set_current_limit(struct regulator_dev *rdev,
int min_uA, int max_uA)
{
int i, current_bits = 0xf;
u8 reg_data;
if (rdev_get_id(rdev) != MAX14577_CHARGER)
return -EINVAL;
if (min_uA > MAX14577_REGULATOR_CURRENT_LIMIT_MAX ||
max_uA < MAX14577_REGULATOR_CURRENT_LIMIT_MIN)
return -EINVAL;
if (max_uA < MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_START) {
/* Less than 200 mA, so set 90mA (turn only Low Bit off) */
u8 reg_data = 0x0 << CHGCTRL4_MBCICHWRCL_SHIFT;
return max14577_update_reg(rdev->regmap,
MAX14577_CHG_REG_CHG_CTRL4,
CHGCTRL4_MBCICHWRCL_MASK, reg_data);
}
/* max_uA is in range: <LIMIT_HIGH_START, inifinite>, so search for
* valid current starting from LIMIT_MAX. */
for (i = MAX14577_REGULATOR_CURRENT_LIMIT_MAX;
i >= MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_START;
i -= MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_STEP) {
if (i <= max_uA)
break;
current_bits--;
}
BUG_ON(current_bits < 0); /* Cannot happen */
/* Turn Low Bit on (use range 200mA-950 mA) */
reg_data = 0x1 << CHGCTRL4_MBCICHWRCL_SHIFT;
/* and set proper High Bits */
reg_data |= current_bits << CHGCTRL4_MBCICHWRCH_SHIFT;
return max14577_update_reg(rdev->regmap, MAX14577_CHG_REG_CHG_CTRL4,
CHGCTRL4_MBCICHWRCL_MASK | CHGCTRL4_MBCICHWRCH_MASK,
reg_data);
}
static struct regulator_ops max14577_safeout_ops = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.list_voltage = regulator_list_voltage_linear,
};
static struct regulator_ops max14577_charger_ops = {
.is_enabled = max14577_reg_is_enabled,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.get_current_limit = max14577_reg_get_current_limit,
.set_current_limit = max14577_reg_set_current_limit,
};
static const struct regulator_desc supported_regulators[] = {
[MAX14577_SAFEOUT] = {
.name = "SAFEOUT",
.id = MAX14577_SAFEOUT,
.ops = &max14577_safeout_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.n_voltages = 1,
.min_uV = MAX14577_REGULATOR_SAFEOUT_VOLTAGE,
.enable_reg = MAX14577_REG_CONTROL2,
.enable_mask = CTRL2_SFOUTORD_MASK,
},
[MAX14577_CHARGER] = {
.name = "CHARGER",
.id = MAX14577_CHARGER,
.ops = &max14577_charger_ops,
.type = REGULATOR_CURRENT,
.owner = THIS_MODULE,
.enable_reg = MAX14577_CHG_REG_CHG_CTRL2,
.enable_mask = CHGCTRL2_MBCHOSTEN_MASK,
},
};
#ifdef CONFIG_OF
static struct of_regulator_match max14577_regulator_matches[] = {
{ .name = "SAFEOUT", },
{ .name = "CHARGER", },
};
static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev)
{
int ret;
struct device_node *np;
np = of_get_child_by_name(pdev->dev.parent->of_node, "regulators");
if (!np) {
dev_err(&pdev->dev, "Failed to get child OF node for regulators\n");
return -EINVAL;
}
ret = of_regulator_match(&pdev->dev, np, max14577_regulator_matches,
MAX14577_REG_MAX);
if (ret < 0) {
dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret);
return ret;
}
return 0;
}
static inline struct regulator_init_data *match_init_data(int index)
{
return max14577_regulator_matches[index].init_data;
}
static inline struct device_node *match_of_node(int index)
{
return max14577_regulator_matches[index].of_node;
}
#else /* CONFIG_OF */
static int max14577_regulator_dt_parse_pdata(struct platform_device *pdev)
{
return 0;
}
static inline struct regulator_init_data *match_init_data(int index)
{
return NULL;
}
static inline struct device_node *match_of_node(int index)
{
return NULL;
}
#endif /* CONFIG_OF */
static int max14577_regulator_probe(struct platform_device *pdev)
{
struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent);
struct max14577_platform_data *pdata = dev_get_platdata(max14577->dev);
int i, ret;
struct regulator_config config = {};
ret = max14577_regulator_dt_parse_pdata(pdev);
if (ret)
return ret;
config.dev = &pdev->dev;
config.regmap = max14577->regmap;
for (i = 0; i < ARRAY_SIZE(supported_regulators); i++) {
struct regulator_dev *regulator;
/*
* Index of supported_regulators[] is also the id and must
* match index of pdata->regulators[].
*/
if (pdata && pdata->regulators) {
config.init_data = pdata->regulators[i].initdata;
config.of_node = pdata->regulators[i].of_node;
} else {
config.init_data = match_init_data(i);
config.of_node = match_of_node(i);
}
regulator = devm_regulator_register(&pdev->dev,
&supported_regulators[i], &config);
if (IS_ERR(regulator)) {
ret = PTR_ERR(regulator);
dev_err(&pdev->dev,
"Regulator init failed for ID %d with error: %d\n",
i, ret);
return ret;
}
}
return ret;
}
static struct platform_driver max14577_regulator_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "max14577-regulator",
},
.probe = max14577_regulator_probe,
};
static int __init max14577_regulator_init(void)
{
BUILD_BUG_ON(MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_START +
MAX14577_REGULATOR_CURRENT_LIMIT_HIGH_STEP * 0xf !=
MAX14577_REGULATOR_CURRENT_LIMIT_MAX);
BUILD_BUG_ON(ARRAY_SIZE(supported_regulators) != MAX14577_REG_MAX);
return platform_driver_register(&max14577_regulator_driver);
}
subsys_initcall(max14577_regulator_init);
static void __exit max14577_regulator_exit(void)
{
platform_driver_unregister(&max14577_regulator_driver);
}
module_exit(max14577_regulator_exit);
MODULE_AUTHOR("Krzysztof Kozlowski <k.kozlowski@samsung.com>");
MODULE_DESCRIPTION("MAXIM 14577 regulator driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:max14577-regulator");

View file

@ -138,6 +138,7 @@ static struct regulator_ops max77693_charger_ops = {
.n_voltages = 4, \ .n_voltages = 4, \
.ops = &max77693_safeout_ops, \ .ops = &max77693_safeout_ops, \
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.volt_table = max77693_safeout_table, \ .volt_table = max77693_safeout_table, \
.vsel_reg = MAX77693_CHG_REG_SAFEOUT_CTRL, \ .vsel_reg = MAX77693_CHG_REG_SAFEOUT_CTRL, \
.vsel_mask = SAFEOUT_CTRL_SAFEOUT##_num##_MASK, \ .vsel_mask = SAFEOUT_CTRL_SAFEOUT##_num##_MASK, \

View file

@ -274,25 +274,25 @@ static struct mc13xxx_regulator mc13892_regulators[] = {
MC13892_SW_DEFINE(SW4, SWITCHERS3, SWITCHERS3, mc13892_sw), MC13892_SW_DEFINE(SW4, SWITCHERS3, SWITCHERS3, mc13892_sw),
MC13892_FIXED_DEFINE(SWBST, SWITCHERS5, mc13892_swbst), MC13892_FIXED_DEFINE(SWBST, SWITCHERS5, mc13892_swbst),
MC13892_FIXED_DEFINE(VIOHI, REGULATORMODE0, mc13892_viohi), MC13892_FIXED_DEFINE(VIOHI, REGULATORMODE0, mc13892_viohi),
MC13892_DEFINE_REGU(VPLL, REGULATORMODE0, REGULATORSETTING0, \ MC13892_DEFINE_REGU(VPLL, REGULATORMODE0, REGULATORSETTING0,
mc13892_vpll), mc13892_vpll),
MC13892_DEFINE_REGU(VDIG, REGULATORMODE0, REGULATORSETTING0, \ MC13892_DEFINE_REGU(VDIG, REGULATORMODE0, REGULATORSETTING0,
mc13892_vdig), mc13892_vdig),
MC13892_DEFINE_REGU(VSD, REGULATORMODE1, REGULATORSETTING1, \ MC13892_DEFINE_REGU(VSD, REGULATORMODE1, REGULATORSETTING1,
mc13892_vsd), mc13892_vsd),
MC13892_DEFINE_REGU(VUSB2, REGULATORMODE0, REGULATORSETTING0, \ MC13892_DEFINE_REGU(VUSB2, REGULATORMODE0, REGULATORSETTING0,
mc13892_vusb2), mc13892_vusb2),
MC13892_DEFINE_REGU(VVIDEO, REGULATORMODE1, REGULATORSETTING1, \ MC13892_DEFINE_REGU(VVIDEO, REGULATORMODE1, REGULATORSETTING1,
mc13892_vvideo), mc13892_vvideo),
MC13892_DEFINE_REGU(VAUDIO, REGULATORMODE1, REGULATORSETTING1, \ MC13892_DEFINE_REGU(VAUDIO, REGULATORMODE1, REGULATORSETTING1,
mc13892_vaudio), mc13892_vaudio),
MC13892_DEFINE_REGU(VCAM, REGULATORMODE1, REGULATORSETTING0, \ MC13892_DEFINE_REGU(VCAM, REGULATORMODE1, REGULATORSETTING0,
mc13892_vcam), mc13892_vcam),
MC13892_DEFINE_REGU(VGEN1, REGULATORMODE0, REGULATORSETTING0, \ MC13892_DEFINE_REGU(VGEN1, REGULATORMODE0, REGULATORSETTING0,
mc13892_vgen1), mc13892_vgen1),
MC13892_DEFINE_REGU(VGEN2, REGULATORMODE0, REGULATORSETTING0, \ MC13892_DEFINE_REGU(VGEN2, REGULATORMODE0, REGULATORSETTING0,
mc13892_vgen2), mc13892_vgen2),
MC13892_DEFINE_REGU(VGEN3, REGULATORMODE1, REGULATORSETTING0, \ MC13892_DEFINE_REGU(VGEN3, REGULATORMODE1, REGULATORSETTING0,
mc13892_vgen3), mc13892_vgen3),
MC13892_FIXED_DEFINE(VUSB, USB1, mc13892_vusb), MC13892_FIXED_DEFINE(VUSB, USB1, mc13892_vusb),
MC13892_GPO_DEFINE(GPO1, POWERMISC, mc13892_gpo), MC13892_GPO_DEFINE(GPO1, POWERMISC, mc13892_gpo),
@ -476,8 +476,8 @@ static int mc13892_sw_regulator_set_voltage_sel(struct regulator_dev *rdev,
} }
mc13xxx_lock(priv->mc13xxx); mc13xxx_lock(priv->mc13xxx);
ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].vsel_reg, mask, ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].vsel_reg,
reg_value); mask, reg_value);
mc13xxx_unlock(priv->mc13xxx); mc13xxx_unlock(priv->mc13xxx);
return ret; return ret;

View file

@ -105,7 +105,7 @@ static int pcf50633_regulator_probe(struct platform_device *pdev)
static struct platform_driver pcf50633_regulator_driver = { static struct platform_driver pcf50633_regulator_driver = {
.driver = { .driver = {
.name = "pcf50633-regltr", .name = "pcf50633-regulator",
}, },
.probe = pcf50633_regulator_probe, .probe = pcf50633_regulator_probe,
}; };

View file

@ -309,21 +309,24 @@ static int pfuze_identify(struct pfuze_chip *pfuze_chip)
return ret; return ret;
switch (value & 0x0f) { switch (value & 0x0f) {
/* Freescale misprogrammed 1-3% of parts prior to week 8 of 2013 as ID=8 */ /*
case 0x8: * Freescale misprogrammed 1-3% of parts prior to week 8 of 2013
dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8"); * as ID=8
case 0x0: */
break; case 0x8:
default: dev_info(pfuze_chip->dev, "Assuming misprogrammed ID=0x8");
dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value); case 0x0:
return -ENODEV; break;
default:
dev_warn(pfuze_chip->dev, "Illegal ID: %x\n", value);
return -ENODEV;
} }
ret = regmap_read(pfuze_chip->regmap, PFUZE100_REVID, &value); ret = regmap_read(pfuze_chip->regmap, PFUZE100_REVID, &value);
if (ret) if (ret)
return ret; return ret;
dev_info(pfuze_chip->dev, dev_info(pfuze_chip->dev,
"Full lay: %x, Metal lay: %x\n", "Full layer: %x, Metal layer: %x\n",
(value & 0xf0) >> 4, value & 0x0f); (value & 0xf0) >> 4, value & 0x0f);
ret = regmap_read(pfuze_chip->regmap, PFUZE100_FABID, &value); ret = regmap_read(pfuze_chip->regmap, PFUZE100_FABID, &value);
@ -408,31 +411,18 @@ static int pfuze100_regulator_probe(struct i2c_client *client,
config.driver_data = pfuze_chip; config.driver_data = pfuze_chip;
config.of_node = match_of_node(i); config.of_node = match_of_node(i);
pfuze_chip->regulators[i] = regulator_register(desc, &config); pfuze_chip->regulators[i] =
devm_regulator_register(&client->dev, desc, &config);
if (IS_ERR(pfuze_chip->regulators[i])) { if (IS_ERR(pfuze_chip->regulators[i])) {
dev_err(&client->dev, "register regulator%s failed\n", dev_err(&client->dev, "register regulator%s failed\n",
pfuze100_regulators[i].desc.name); pfuze100_regulators[i].desc.name);
ret = PTR_ERR(pfuze_chip->regulators[i]); return PTR_ERR(pfuze_chip->regulators[i]);
while (--i >= 0)
regulator_unregister(pfuze_chip->regulators[i]);
return ret;
} }
} }
return 0; return 0;
} }
static int pfuze100_regulator_remove(struct i2c_client *client)
{
int i;
struct pfuze_chip *pfuze_chip = i2c_get_clientdata(client);
for (i = 0; i < PFUZE100_MAX_REGULATOR; i++)
regulator_unregister(pfuze_chip->regulators[i]);
return 0;
}
static struct i2c_driver pfuze_driver = { static struct i2c_driver pfuze_driver = {
.id_table = pfuze_device_id, .id_table = pfuze_device_id,
.driver = { .driver = {
@ -441,7 +431,6 @@ static struct i2c_driver pfuze_driver = {
.of_match_table = pfuze_dt_ids, .of_match_table = pfuze_dt_ids,
}, },
.probe = pfuze100_regulator_probe, .probe = pfuze100_regulator_probe,
.remove = pfuze100_regulator_remove,
}; };
module_i2c_driver(pfuze_driver); module_i2c_driver(pfuze_driver);

View file

@ -70,8 +70,6 @@ static int s2mps11_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
ramp_delay = s2mps11->ramp_delay2; ramp_delay = s2mps11->ramp_delay2;
break; break;
case S2MPS11_BUCK3: case S2MPS11_BUCK3:
ramp_delay = s2mps11->ramp_delay34;
break;
case S2MPS11_BUCK4: case S2MPS11_BUCK4:
ramp_delay = s2mps11->ramp_delay34; ramp_delay = s2mps11->ramp_delay34;
break; break;

View file

@ -23,6 +23,7 @@
#include <linux/mfd/samsung/core.h> #include <linux/mfd/samsung/core.h>
#include <linux/mfd/samsung/s5m8767.h> #include <linux/mfd/samsung/s5m8767.h>
#include <linux/regulator/of_regulator.h> #include <linux/regulator/of_regulator.h>
#include <linux/regmap.h>
#define S5M8767_OPMODE_NORMAL_MODE 0x1 #define S5M8767_OPMODE_NORMAL_MODE 0x1
@ -120,8 +121,8 @@ static const struct sec_voltage_desc *reg_voltage_map[] = {
[S5M8767_BUCK4] = &buck_voltage_val2, [S5M8767_BUCK4] = &buck_voltage_val2,
[S5M8767_BUCK5] = &buck_voltage_val1, [S5M8767_BUCK5] = &buck_voltage_val1,
[S5M8767_BUCK6] = &buck_voltage_val1, [S5M8767_BUCK6] = &buck_voltage_val1,
[S5M8767_BUCK7] = NULL, [S5M8767_BUCK7] = &buck_voltage_val3,
[S5M8767_BUCK8] = NULL, [S5M8767_BUCK8] = &buck_voltage_val3,
[S5M8767_BUCK9] = &buck_voltage_val3, [S5M8767_BUCK9] = &buck_voltage_val3,
}; };
@ -217,7 +218,7 @@ static int s5m8767_reg_is_enabled(struct regulator_dev *rdev)
{ {
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
int ret, reg; int ret, reg;
int mask = 0xc0, enable_ctrl; int enable_ctrl;
unsigned int val; unsigned int val;
ret = s5m8767_get_register(rdev, &reg, &enable_ctrl); ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
@ -226,37 +227,38 @@ static int s5m8767_reg_is_enabled(struct regulator_dev *rdev)
else if (ret) else if (ret)
return ret; return ret;
ret = sec_reg_read(s5m8767->iodev, reg, &val); ret = regmap_read(s5m8767->iodev->regmap_pmic, reg, &val);
if (ret) if (ret)
return ret; return ret;
return (val & mask) == enable_ctrl; return (val & S5M8767_ENCTRL_MASK) == enable_ctrl;
} }
static int s5m8767_reg_enable(struct regulator_dev *rdev) static int s5m8767_reg_enable(struct regulator_dev *rdev)
{ {
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
int ret, reg; int ret, reg;
int mask = 0xc0, enable_ctrl; int enable_ctrl;
ret = s5m8767_get_register(rdev, &reg, &enable_ctrl); ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
if (ret) if (ret)
return ret; return ret;
return sec_reg_update(s5m8767->iodev, reg, enable_ctrl, mask); return regmap_update_bits(s5m8767->iodev->regmap_pmic, reg,
S5M8767_ENCTRL_MASK, enable_ctrl);
} }
static int s5m8767_reg_disable(struct regulator_dev *rdev) static int s5m8767_reg_disable(struct regulator_dev *rdev)
{ {
struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev); struct s5m8767_info *s5m8767 = rdev_get_drvdata(rdev);
int ret, reg; int ret, reg, enable_ctrl;
int mask = 0xc0, enable_ctrl;
ret = s5m8767_get_register(rdev, &reg, &enable_ctrl); ret = s5m8767_get_register(rdev, &reg, &enable_ctrl);
if (ret) if (ret)
return ret; return ret;
return sec_reg_update(s5m8767->iodev, reg, ~mask, mask); return regmap_update_bits(s5m8767->iodev->regmap_pmic, reg,
S5M8767_ENCTRL_MASK, ~S5M8767_ENCTRL_MASK);
} }
static int s5m8767_get_vsel_reg(int reg_id, struct s5m8767_info *s5m8767) static int s5m8767_get_vsel_reg(int reg_id, struct s5m8767_info *s5m8767)
@ -417,9 +419,12 @@ static struct regulator_ops s5m8767_ops = {
}; };
static struct regulator_ops s5m8767_buck78_ops = { static struct regulator_ops s5m8767_buck78_ops = {
.list_voltage = regulator_list_voltage_linear,
.is_enabled = s5m8767_reg_is_enabled, .is_enabled = s5m8767_reg_is_enabled,
.enable = s5m8767_reg_enable, .enable = s5m8767_reg_enable,
.disable = s5m8767_reg_disable, .disable = s5m8767_reg_disable,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
}; };
#define s5m8767_regulator_desc(_name) { \ #define s5m8767_regulator_desc(_name) { \
@ -745,17 +750,20 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2, buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2,
pdata->buck2_init); pdata->buck2_init);
sec_reg_write(s5m8767->iodev, S5M8767_REG_BUCK2DVS2, buck_init); regmap_write(s5m8767->iodev->regmap_pmic, S5M8767_REG_BUCK2DVS2,
buck_init);
buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2, buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2,
pdata->buck3_init); pdata->buck3_init);
sec_reg_write(s5m8767->iodev, S5M8767_REG_BUCK3DVS2, buck_init); regmap_write(s5m8767->iodev->regmap_pmic, S5M8767_REG_BUCK3DVS2,
buck_init);
buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2, buck_init = s5m8767_convert_voltage_to_sel(&buck_voltage_val2,
pdata->buck4_init); pdata->buck4_init);
sec_reg_write(s5m8767->iodev, S5M8767_REG_BUCK4DVS2, buck_init); regmap_write(s5m8767->iodev->regmap_pmic, S5M8767_REG_BUCK4DVS2,
buck_init);
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (s5m8767->buck2_gpiodvs) { if (s5m8767->buck2_gpiodvs) {
@ -837,71 +845,76 @@ static int s5m8767_pmic_probe(struct platform_device *pdev)
if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs || if (pdata->buck2_gpiodvs || pdata->buck3_gpiodvs ||
pdata->buck4_gpiodvs) { pdata->buck4_gpiodvs) {
sec_reg_update(s5m8767->iodev, S5M8767_REG_BUCK2CTRL, regmap_update_bits(s5m8767->iodev->regmap_pmic,
(pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1), S5M8767_REG_BUCK2CTRL, 1 << 1,
1 << 1); (pdata->buck2_gpiodvs) ? (1 << 1) : (0 << 1));
sec_reg_update(s5m8767->iodev, S5M8767_REG_BUCK3CTRL, regmap_update_bits(s5m8767->iodev->regmap_pmic,
(pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1), S5M8767_REG_BUCK3CTRL, 1 << 1,
1 << 1); (pdata->buck3_gpiodvs) ? (1 << 1) : (0 << 1));
sec_reg_update(s5m8767->iodev, S5M8767_REG_BUCK4CTRL, regmap_update_bits(s5m8767->iodev->regmap_pmic,
(pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1), S5M8767_REG_BUCK4CTRL, 1 << 1,
1 << 1); (pdata->buck4_gpiodvs) ? (1 << 1) : (0 << 1));
} }
/* Initialize GPIO DVS registers */ /* Initialize GPIO DVS registers */
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
if (s5m8767->buck2_gpiodvs) { if (s5m8767->buck2_gpiodvs) {
sec_reg_write(s5m8767->iodev, S5M8767_REG_BUCK2DVS1 + i, regmap_write(s5m8767->iodev->regmap_pmic,
s5m8767->buck2_vol[i]); S5M8767_REG_BUCK2DVS1 + i,
s5m8767->buck2_vol[i]);
} }
if (s5m8767->buck3_gpiodvs) { if (s5m8767->buck3_gpiodvs) {
sec_reg_write(s5m8767->iodev, S5M8767_REG_BUCK3DVS1 + i, regmap_write(s5m8767->iodev->regmap_pmic,
s5m8767->buck3_vol[i]); S5M8767_REG_BUCK3DVS1 + i,
s5m8767->buck3_vol[i]);
} }
if (s5m8767->buck4_gpiodvs) { if (s5m8767->buck4_gpiodvs) {
sec_reg_write(s5m8767->iodev, S5M8767_REG_BUCK4DVS1 + i, regmap_write(s5m8767->iodev->regmap_pmic,
s5m8767->buck4_vol[i]); S5M8767_REG_BUCK4DVS1 + i,
s5m8767->buck4_vol[i]);
} }
} }
if (s5m8767->buck2_ramp) if (s5m8767->buck2_ramp)
sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x08, 0x08); regmap_update_bits(s5m8767->iodev->regmap_pmic,
S5M8767_REG_DVSRAMP, 0x08, 0x08);
if (s5m8767->buck3_ramp) if (s5m8767->buck3_ramp)
sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x04, 0x04); regmap_update_bits(s5m8767->iodev->regmap_pmic,
S5M8767_REG_DVSRAMP, 0x04, 0x04);
if (s5m8767->buck4_ramp) if (s5m8767->buck4_ramp)
sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, 0x02, 0x02); regmap_update_bits(s5m8767->iodev->regmap_pmic,
S5M8767_REG_DVSRAMP, 0x02, 0x02);
if (s5m8767->buck2_ramp || s5m8767->buck3_ramp if (s5m8767->buck2_ramp || s5m8767->buck3_ramp
|| s5m8767->buck4_ramp) { || s5m8767->buck4_ramp) {
unsigned int val;
switch (s5m8767->ramp_delay) { switch (s5m8767->ramp_delay) {
case 5: case 5:
sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, val = S5M8767_DVS_BUCK_RAMP_5;
0x40, 0xf0);
break; break;
case 10: case 10:
sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, val = S5M8767_DVS_BUCK_RAMP_10;
0x90, 0xf0);
break; break;
case 25: case 25:
sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, val = S5M8767_DVS_BUCK_RAMP_25;
0xd0, 0xf0);
break; break;
case 50: case 50:
sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, val = S5M8767_DVS_BUCK_RAMP_50;
0xe0, 0xf0);
break; break;
case 100: case 100:
sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, val = S5M8767_DVS_BUCK_RAMP_100;
0xf0, 0xf0);
break; break;
default: default:
sec_reg_update(s5m8767->iodev, S5M8767_REG_DVSRAMP, val = S5M8767_DVS_BUCK_RAMP_10;
0x90, 0xf0);
} }
regmap_update_bits(s5m8767->iodev->regmap_pmic,
S5M8767_REG_DVSRAMP,
S5M8767_DVS_BUCK_RAMP_MASK,
val << S5M8767_DVS_BUCK_RAMP_SHIFT);
} }
for (i = 0; i < pdata->num_regulators; i++) { for (i = 0; i < pdata->num_regulators; i++) {

View file

@ -74,7 +74,8 @@ static int stw481x_vmmc_regulator_probe(struct platform_device *pdev)
config.init_data = of_get_regulator_init_data(&pdev->dev, config.init_data = of_get_regulator_init_data(&pdev->dev,
pdev->dev.of_node); pdev->dev.of_node);
stw481x->vmmc_regulator = regulator_register(&vmmc_regulator, &config); stw481x->vmmc_regulator = devm_regulator_register(&pdev->dev,
&vmmc_regulator, &config);
if (IS_ERR(stw481x->vmmc_regulator)) { if (IS_ERR(stw481x->vmmc_regulator)) {
dev_err(&pdev->dev, dev_err(&pdev->dev,
"error initializing STw481x VMMC regulator\n"); "error initializing STw481x VMMC regulator\n");
@ -85,14 +86,6 @@ static int stw481x_vmmc_regulator_probe(struct platform_device *pdev)
return 0; return 0;
} }
static int stw481x_vmmc_regulator_remove(struct platform_device *pdev)
{
struct stw481x *stw481x = dev_get_platdata(&pdev->dev);
regulator_unregister(stw481x->vmmc_regulator);
return 0;
}
static const struct of_device_id stw481x_vmmc_match[] = { static const struct of_device_id stw481x_vmmc_match[] = {
{ .compatible = "st,stw481x-vmmc", }, { .compatible = "st,stw481x-vmmc", },
{}, {},
@ -105,7 +98,6 @@ static struct platform_driver stw481x_vmmc_regulator_driver = {
.of_match_table = stw481x_vmmc_match, .of_match_table = stw481x_vmmc_match,
}, },
.probe = stw481x_vmmc_regulator_probe, .probe = stw481x_vmmc_regulator_probe,
.remove = stw481x_vmmc_regulator_remove,
}; };
module_platform_driver(stw481x_vmmc_regulator_driver); module_platform_driver(stw481x_vmmc_regulator_driver);

View file

@ -70,16 +70,16 @@
#define TPS51632_POWER_STATE_SINGLE_PHASE_CCM 0x1 #define TPS51632_POWER_STATE_SINGLE_PHASE_CCM 0x1
#define TPS51632_POWER_STATE_SINGLE_PHASE_DCM 0x2 #define TPS51632_POWER_STATE_SINGLE_PHASE_DCM 0x2
#define TPS51632_MIN_VOLATGE 500000 #define TPS51632_MIN_VOLTAGE 500000
#define TPS51632_MAX_VOLATGE 1520000 #define TPS51632_MAX_VOLTAGE 1520000
#define TPS51632_VOLATGE_STEP_10mV 10000 #define TPS51632_VOLTAGE_STEP_10mV 10000
#define TPS51632_VOLATGE_STEP_20mV 20000 #define TPS51632_VOLTAGE_STEP_20mV 20000
#define TPS51632_MAX_VSEL 0x7F #define TPS51632_MAX_VSEL 0x7F
#define TPS51632_MIN_VSEL 0x19 #define TPS51632_MIN_VSEL 0x19
#define TPS51632_DEFAULT_RAMP_DELAY 6000 #define TPS51632_DEFAULT_RAMP_DELAY 6000
#define TPS51632_VOLT_VSEL(uV) \ #define TPS51632_VOLT_VSEL(uV) \
(DIV_ROUND_UP(uV - TPS51632_MIN_VOLATGE, \ (DIV_ROUND_UP(uV - TPS51632_MIN_VOLTAGE, \
TPS51632_VOLATGE_STEP_10mV) + \ TPS51632_VOLTAGE_STEP_10mV) + \
TPS51632_MIN_VSEL) TPS51632_MIN_VSEL)
/* TPS51632 chip information */ /* TPS51632 chip information */
@ -243,9 +243,9 @@ static struct tps51632_regulator_platform_data *
pdata->dvfs_step_20mV = of_property_read_bool(np, "ti,dvfs-step-20mV"); pdata->dvfs_step_20mV = of_property_read_bool(np, "ti,dvfs-step-20mV");
pdata->base_voltage_uV = pdata->reg_init_data->constraints.min_uV ? : pdata->base_voltage_uV = pdata->reg_init_data->constraints.min_uV ? :
TPS51632_MIN_VOLATGE; TPS51632_MIN_VOLTAGE;
pdata->max_voltage_uV = pdata->reg_init_data->constraints.max_uV ? : pdata->max_voltage_uV = pdata->reg_init_data->constraints.max_uV ? :
TPS51632_MAX_VOLATGE; TPS51632_MAX_VOLTAGE;
return pdata; return pdata;
} }
#else #else
@ -284,15 +284,15 @@ static int tps51632_probe(struct i2c_client *client,
} }
if (pdata->enable_pwm_dvfs) { if (pdata->enable_pwm_dvfs) {
if ((pdata->base_voltage_uV < TPS51632_MIN_VOLATGE) || if ((pdata->base_voltage_uV < TPS51632_MIN_VOLTAGE) ||
(pdata->base_voltage_uV > TPS51632_MAX_VOLATGE)) { (pdata->base_voltage_uV > TPS51632_MAX_VOLTAGE)) {
dev_err(&client->dev, "Invalid base_voltage_uV setting\n"); dev_err(&client->dev, "Invalid base_voltage_uV setting\n");
return -EINVAL; return -EINVAL;
} }
if ((pdata->max_voltage_uV) && if ((pdata->max_voltage_uV) &&
((pdata->max_voltage_uV < TPS51632_MIN_VOLATGE) || ((pdata->max_voltage_uV < TPS51632_MIN_VOLTAGE) ||
(pdata->max_voltage_uV > TPS51632_MAX_VOLATGE))) { (pdata->max_voltage_uV > TPS51632_MAX_VOLTAGE))) {
dev_err(&client->dev, "Invalid max_voltage_uV setting\n"); dev_err(&client->dev, "Invalid max_voltage_uV setting\n");
return -EINVAL; return -EINVAL;
} }
@ -305,11 +305,11 @@ static int tps51632_probe(struct i2c_client *client,
} }
tps->dev = &client->dev; tps->dev = &client->dev;
tps->desc.name = id->name; tps->desc.name = client->name;
tps->desc.id = 0; tps->desc.id = 0;
tps->desc.ramp_delay = TPS51632_DEFAULT_RAMP_DELAY; tps->desc.ramp_delay = TPS51632_DEFAULT_RAMP_DELAY;
tps->desc.min_uV = TPS51632_MIN_VOLATGE; tps->desc.min_uV = TPS51632_MIN_VOLTAGE;
tps->desc.uV_step = TPS51632_VOLATGE_STEP_10mV; tps->desc.uV_step = TPS51632_VOLTAGE_STEP_10mV;
tps->desc.linear_min_sel = TPS51632_MIN_VSEL; tps->desc.linear_min_sel = TPS51632_MIN_VSEL;
tps->desc.n_voltages = TPS51632_MAX_VSEL + 1; tps->desc.n_voltages = TPS51632_MAX_VSEL + 1;
tps->desc.ops = &tps51632_dcdc_ops; tps->desc.ops = &tps51632_dcdc_ops;

View file

@ -360,7 +360,7 @@ static int tps62360_probe(struct i2c_client *client,
dev_err(&client->dev, "Error: No device match found\n"); dev_err(&client->dev, "Error: No device match found\n");
return -ENODEV; return -ENODEV;
} }
chip_id = (int)match->data; chip_id = (int)(long)match->data;
if (!pdata) if (!pdata)
pdata = of_get_tps62360_platform_data(&client->dev); pdata = of_get_tps62360_platform_data(&client->dev);
} else if (id) { } else if (id) {

View file

@ -88,6 +88,11 @@ static const unsigned int VMMC_VSEL_table[] = {
1800000, 2800000, 3000000, 3300000, 1800000, 2800000, 3000000, 3300000,
}; };
/* supported BBCH voltages in microvolts */
static const unsigned int VBB_VSEL_table[] = {
3000000, 2520000, 3150000, 5000000,
};
struct tps_info { struct tps_info {
const char *name; const char *name;
const char *vin_name; const char *vin_name;
@ -183,6 +188,12 @@ static struct tps_info tps65910_regs[] = {
.voltage_table = VMMC_VSEL_table, .voltage_table = VMMC_VSEL_table,
.enable_time_us = 100, .enable_time_us = 100,
}, },
{
.name = "vbb",
.vin_name = "vcc7",
.n_voltages = ARRAY_SIZE(VBB_VSEL_table),
.voltage_table = VBB_VSEL_table,
},
}; };
static struct tps_info tps65911_regs[] = { static struct tps_info tps65911_regs[] = {
@ -339,6 +350,8 @@ static int tps65910_get_ctrl_register(int id)
return TPS65910_VAUX33; return TPS65910_VAUX33;
case TPS65910_REG_VMMC: case TPS65910_REG_VMMC:
return TPS65910_VMMC; return TPS65910_VMMC;
case TPS65910_REG_VBB:
return TPS65910_BBCH;
default: default:
return -EINVAL; return -EINVAL;
} }
@ -528,6 +541,10 @@ static int tps65910_get_voltage_sel(struct regulator_dev *dev)
value &= LDO_SEL_MASK; value &= LDO_SEL_MASK;
value >>= LDO_SEL_SHIFT; value >>= LDO_SEL_SHIFT;
break; break;
case TPS65910_REG_VBB:
value &= BBCH_BBSEL_MASK;
value >>= BBCH_BBSEL_SHIFT;
break;
default: default:
return -EINVAL; return -EINVAL;
} }
@ -638,6 +655,9 @@ static int tps65910_set_voltage_sel(struct regulator_dev *dev,
case TPS65910_REG_VMMC: case TPS65910_REG_VMMC:
return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK, return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK,
selector << LDO_SEL_SHIFT); selector << LDO_SEL_SHIFT);
case TPS65910_REG_VBB:
return tps65910_reg_update_bits(pmic->mfd, reg, BBCH_BBSEL_MASK,
selector << BBCH_BBSEL_SHIFT);
} }
return -EINVAL; return -EINVAL;
@ -669,6 +689,9 @@ static int tps65911_set_voltage_sel(struct regulator_dev *dev,
case TPS65910_REG_VIO: case TPS65910_REG_VIO:
return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK, return tps65910_reg_update_bits(pmic->mfd, reg, LDO_SEL_MASK,
selector << LDO_SEL_SHIFT); selector << LDO_SEL_SHIFT);
case TPS65910_REG_VBB:
return tps65910_reg_update_bits(pmic->mfd, reg, BBCH_BBSEL_MASK,
selector << BBCH_BBSEL_SHIFT);
} }
return -EINVAL; return -EINVAL;
@ -762,6 +785,18 @@ static struct regulator_ops tps65910_ops_vdd3 = {
.map_voltage = regulator_map_voltage_ascend, .map_voltage = regulator_map_voltage_ascend,
}; };
static struct regulator_ops tps65910_ops_vbb = {
.is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.set_mode = tps65910_set_mode,
.get_mode = tps65910_get_mode,
.get_voltage_sel = tps65910_get_voltage_sel,
.set_voltage_sel = tps65910_set_voltage_sel,
.list_voltage = regulator_list_voltage_table,
.map_voltage = regulator_map_voltage_iterate,
};
static struct regulator_ops tps65910_ops = { static struct regulator_ops tps65910_ops = {
.is_enabled = regulator_is_enabled_regmap, .is_enabled = regulator_is_enabled_regmap,
.enable = regulator_enable_regmap, .enable = regulator_enable_regmap,
@ -944,6 +979,7 @@ static struct of_regulator_match tps65910_matches[] = {
{ .name = "vaux2", .driver_data = (void *) &tps65910_regs[10] }, { .name = "vaux2", .driver_data = (void *) &tps65910_regs[10] },
{ .name = "vaux33", .driver_data = (void *) &tps65910_regs[11] }, { .name = "vaux33", .driver_data = (void *) &tps65910_regs[11] },
{ .name = "vmmc", .driver_data = (void *) &tps65910_regs[12] }, { .name = "vmmc", .driver_data = (void *) &tps65910_regs[12] },
{ .name = "vbb", .driver_data = (void *) &tps65910_regs[13] },
}; };
static struct of_regulator_match tps65911_matches[] = { static struct of_regulator_match tps65911_matches[] = {
@ -1145,6 +1181,10 @@ static int tps65910_probe(struct platform_device *pdev)
pmic->desc[i].ops = &tps65910_ops_dcdc; pmic->desc[i].ops = &tps65910_ops_dcdc;
pmic->desc[i].ramp_delay = 5000; pmic->desc[i].ramp_delay = 5000;
} }
} else if (i == TPS65910_REG_VBB &&
tps65910_chip_id(tps65910) == TPS65910) {
pmic->desc[i].ops = &tps65910_ops_vbb;
pmic->desc[i].volt_table = info->voltage_table;
} else { } else {
if (tps65910_chip_id(tps65910) == TPS65910) { if (tps65910_chip_id(tps65910) == TPS65910) {
pmic->desc[i].ops = &tps65910_ops; pmic->desc[i].ops = &tps65910_ops;

View file

@ -58,7 +58,7 @@ struct twlreg_info {
struct regulator_desc desc; struct regulator_desc desc;
/* chip specific features */ /* chip specific features */
unsigned long features; unsigned long features;
/* /*
* optional override functions for voltage set/get * optional override functions for voltage set/get
@ -1128,7 +1128,7 @@ static int twlreg_probe(struct platform_device *pdev)
if (!initdata) if (!initdata)
return -EINVAL; return -EINVAL;
info = kmemdup(template, sizeof (*info), GFP_KERNEL); info = kmemdup(template, sizeof(*info), GFP_KERNEL);
if (!info) if (!info)
return -ENOMEM; return -ENOMEM;

View file

@ -762,8 +762,7 @@ static int wm831x_boostp_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_REG, 0); res = platform_get_resource(pdev, IORESOURCE_REG, 0);
if (res == NULL) { if (res == NULL) {
dev_err(&pdev->dev, "No REG resource\n"); dev_err(&pdev->dev, "No REG resource\n");
ret = -EINVAL; return -EINVAL;
goto err;
} }
dcdc->base = res->start; dcdc->base = res->start;
@ -788,7 +787,7 @@ static int wm831x_boostp_probe(struct platform_device *pdev)
ret = PTR_ERR(dcdc->regulator); ret = PTR_ERR(dcdc->regulator);
dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n", dev_err(wm831x->dev, "Failed to register DCDC%d: %d\n",
id + 1, ret); id + 1, ret);
goto err; return ret;
} }
irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV")); irq = wm831x_irq(wm831x, platform_get_irq_byname(pdev, "UV"));
@ -799,15 +798,12 @@ static int wm831x_boostp_probe(struct platform_device *pdev)
if (ret != 0) { if (ret != 0) {
dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n", dev_err(&pdev->dev, "Failed to request UV IRQ %d: %d\n",
irq, ret); irq, ret);
goto err; return ret;
} }
platform_set_drvdata(pdev, dcdc); platform_set_drvdata(pdev, dcdc);
return 0; return 0;
err:
return ret;
} }
static struct platform_driver wm831x_boostp_driver = { static struct platform_driver wm831x_boostp_driver = {

View file

@ -151,6 +151,7 @@
#define AS3722_ASIC_ID1_REG 0x90 #define AS3722_ASIC_ID1_REG 0x90
#define AS3722_ASIC_ID2_REG 0x91 #define AS3722_ASIC_ID2_REG 0x91
#define AS3722_LOCK_REG 0x9E #define AS3722_LOCK_REG 0x9E
#define AS3722_FUSE7_REG 0xA7
#define AS3722_MAX_REGISTER 0xF4 #define AS3722_MAX_REGISTER 0xF4
#define AS3722_SD0_EXT_ENABLE_MASK 0x03 #define AS3722_SD0_EXT_ENABLE_MASK 0x03
@ -224,6 +225,7 @@
#define AS3722_SD_VSEL_MASK 0x7F #define AS3722_SD_VSEL_MASK 0x7F
#define AS3722_SD0_VSEL_MIN 0x01 #define AS3722_SD0_VSEL_MIN 0x01
#define AS3722_SD0_VSEL_MAX 0x5A #define AS3722_SD0_VSEL_MAX 0x5A
#define AS3722_SD0_VSEL_LOW_VOL_MAX 0x6E
#define AS3722_SD2_VSEL_MIN 0x01 #define AS3722_SD2_VSEL_MIN 0x01
#define AS3722_SD2_VSEL_MAX 0x7F #define AS3722_SD2_VSEL_MAX 0x7F
@ -342,6 +344,8 @@
#define AS3722_EXT_CONTROL_ENABLE2 0x2 #define AS3722_EXT_CONTROL_ENABLE2 0x2
#define AS3722_EXT_CONTROL_ENABLE3 0x3 #define AS3722_EXT_CONTROL_ENABLE3 0x3
#define AS3722_FUSE7_SD0_LOW_VOLTAGE BIT(4)
/* Interrupt IDs */ /* Interrupt IDs */
enum as3722_irq { enum as3722_irq {
AS3722_IRQ_LID, AS3722_IRQ_LID,

View file

@ -59,12 +59,6 @@ int sec_irq_init(struct sec_pmic_dev *sec_pmic);
void sec_irq_exit(struct sec_pmic_dev *sec_pmic); void sec_irq_exit(struct sec_pmic_dev *sec_pmic);
int sec_irq_resume(struct sec_pmic_dev *sec_pmic); int sec_irq_resume(struct sec_pmic_dev *sec_pmic);
extern int sec_reg_read(struct sec_pmic_dev *sec_pmic, u8 reg, void *dest);
extern int sec_bulk_read(struct sec_pmic_dev *sec_pmic, u8 reg, int count, u8 *buf);
extern int sec_reg_write(struct sec_pmic_dev *sec_pmic, u8 reg, u8 value);
extern int sec_bulk_write(struct sec_pmic_dev *sec_pmic, u8 reg, int count, u8 *buf);
extern int sec_reg_update(struct sec_pmic_dev *sec_pmic, u8 reg, u8 val, u8 mask);
struct sec_platform_data { struct sec_platform_data {
struct sec_regulator_data *regulators; struct sec_regulator_data *regulators;
struct sec_opmode_data *opmode; struct sec_opmode_data *opmode;

View file

@ -183,6 +183,22 @@ enum s5m8767_regulators {
S5M8767_REG_MAX, S5M8767_REG_MAX,
}; };
#define S5M8767_ENCTRL_SHIFT 6 #define S5M8767_ENCTRL_SHIFT 6
#define S5M8767_ENCTRL_MASK (0x3 << S5M8767_ENCTRL_SHIFT)
/*
* Values for BUCK_RAMP field in DVS_RAMP register, matching raw values
* in mV/us.
*/
enum s5m8767_dvs_buck_ramp_values {
S5M8767_DVS_BUCK_RAMP_5 = 0x4,
S5M8767_DVS_BUCK_RAMP_10 = 0x9,
S5M8767_DVS_BUCK_RAMP_12_5 = 0xb,
S5M8767_DVS_BUCK_RAMP_25 = 0xd,
S5M8767_DVS_BUCK_RAMP_50 = 0xe,
S5M8767_DVS_BUCK_RAMP_100 = 0xf,
};
#define S5M8767_DVS_BUCK_RAMP_SHIFT 4
#define S5M8767_DVS_BUCK_RAMP_MASK (0xf << S5M8767_DVS_BUCK_RAMP_SHIFT)
#endif /* __LINUX_MFD_S5M8767_H */ #endif /* __LINUX_MFD_S5M8767_H */

View file

@ -358,8 +358,6 @@
/*Register BBCH (0x80) register.RegisterDescription */ /*Register BBCH (0x80) register.RegisterDescription */
#define BBCH_BBSEL_MASK 0x06 #define BBCH_BBSEL_MASK 0x06
#define BBCH_BBSEL_SHIFT 1 #define BBCH_BBSEL_SHIFT 1
#define BBCH_BBCHEN_MASK 0x01
#define BBCH_BBCHEN_SHIFT 0
/*Register DCDCCTRL (0x80) register.RegisterDescription */ /*Register DCDCCTRL (0x80) register.RegisterDescription */
@ -833,6 +831,7 @@
#define TPS65910_REG_VAUX2 10 #define TPS65910_REG_VAUX2 10
#define TPS65910_REG_VAUX33 11 #define TPS65910_REG_VAUX33 11
#define TPS65910_REG_VMMC 12 #define TPS65910_REG_VMMC 12
#define TPS65910_REG_VBB 13
#define TPS65911_REG_VDDCTRL 4 #define TPS65911_REG_VDDCTRL 4
#define TPS65911_REG_LDO1 5 #define TPS65911_REG_LDO1 5
@ -845,7 +844,7 @@
#define TPS65911_REG_LDO8 12 #define TPS65911_REG_LDO8 12
/* Max number of TPS65910/11 regulators */ /* Max number of TPS65910/11 regulators */
#define TPS65910_NUM_REGS 13 #define TPS65910_NUM_REGS 14
/* External sleep controls through EN1/EN2/EN3/SLEEP inputs */ /* External sleep controls through EN1/EN2/EN3/SLEEP inputs */
#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 0x1 #define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 0x1

View file

@ -0,0 +1,53 @@
/*
* act8865.h -- Voltage regulation for the active-semi act8865
*
* Copyright (C) 2013 Atmel Corporation.
*
* 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 of the License.
*
* 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.
*/
#ifndef __LINUX_REGULATOR_ACT8865_H
#define __LINUX_REGULATOR_ACT8865_H
#include <linux/regulator/machine.h>
enum {
ACT8865_ID_DCDC1,
ACT8865_ID_DCDC2,
ACT8865_ID_DCDC3,
ACT8865_ID_LDO1,
ACT8865_ID_LDO2,
ACT8865_ID_LDO3,
ACT8865_ID_LDO4,
ACT8865_REG_NUM,
};
/**
* act8865_regulator_data - regulator data
* @id: regulator id
* @name: regulator name
* @platform_data: regulator init data
*/
struct act8865_regulator_data {
int id;
const char *name;
struct regulator_init_data *platform_data;
};
/**
* act8865_platform_data - platform data for act8865
* @num_regulators: number of regulators used
* @regulators: pointer to regulators used
*/
struct act8865_platform_data {
int num_regulators;
struct act8865_regulator_data *regulators;
};
#endif