Commit a2c05e91 authored by Mark Brown's avatar Mark Brown

Merge remote-tracking branch 'regulator/topic/max8952' into v3.9-rc8

parents 2e1be9f7 71622e15
Maxim MAX8952 voltage regulator
Required properties:
- compatible: must be equal to "maxim,max8952"
- reg: I2C slave address, usually 0x60
- max8952,dvs-mode-microvolt: array of 4 integer values defining DVS voltages
in microvolts. All values must be from range <770000, 1400000>
- any required generic properties defined in regulator.txt
Optional properties:
- max8952,vid-gpios: array of two GPIO pins used for DVS voltage selection
- max8952,en-gpio: GPIO used to control enable status of regulator
- max8952,default-mode: index of default DVS voltage, from <0, 3> range
- max8952,sync-freq: sync frequency, must be one of following values:
- 0: 26 MHz
- 1: 13 MHz
- 2: 19.2 MHz
Defaults to 26 MHz if not specified.
- max8952,ramp-speed: voltage ramp speed, must be one of following values:
- 0: 32mV/us
- 1: 16mV/us
- 2: 8mV/us
- 3: 4mV/us
- 4: 2mV/us
- 5: 1mV/us
- 6: 0.5mV/us
- 7: 0.25mV/us
Defaults to 32mV/us if not specified.
- any available generic properties defined in regulator.txt
Example:
vdd_arm_reg: pmic@60 {
compatible = "maxim,max8952";
reg = <0x60>;
/* max8952-specific properties */
max8952,vid-gpios = <&gpx0 3 0>, <&gpx0 4 0>;
max8952,en-gpio = <&gpx0 1 0>;
max8952,default-mode = <0>;
max8952,dvs-mode-microvolt = <1250000>, <1200000>,
<1050000>, <950000>;
max8952,sync-freq = <0>;
max8952,ramp-speed = <0>;
/* generic regulator properties */
regulator-name = "vdd_arm";
regulator-min-microvolt = <770000>;
regulator-max-microvolt = <1400000>;
regulator-always-on;
regulator-boot-on;
};
...@@ -97,16 +97,7 @@ static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = { ...@@ -97,16 +97,7 @@ static struct s3c2410_uartcfg universal_uartcfgs[] __initdata = {
static struct regulator_consumer_supply max8952_consumer = static struct regulator_consumer_supply max8952_consumer =
REGULATOR_SUPPLY("vdd_arm", NULL); REGULATOR_SUPPLY("vdd_arm", NULL);
static struct max8952_platform_data universal_max8952_pdata __initdata = { static struct regulator_init_data universal_max8952_reg_data = {
.gpio_vid0 = EXYNOS4_GPX0(3),
.gpio_vid1 = EXYNOS4_GPX0(4),
.gpio_en = -1, /* Not controllable, set "Always High" */
.default_mode = 0, /* vid0 = 0, vid1 = 0 */
.dvs_mode = { 48, 32, 28, 18 }, /* 1.25, 1.20, 1.05, 0.95V */
.sync_freq = 0, /* default: fastest */
.ramp_speed = 0, /* default: fastest */
.reg_data = {
.constraints = { .constraints = {
.name = "VARM_1.2V", .name = "VARM_1.2V",
.min_uV = 770000, .min_uV = 770000,
...@@ -117,7 +108,17 @@ static struct max8952_platform_data universal_max8952_pdata __initdata = { ...@@ -117,7 +108,17 @@ static struct max8952_platform_data universal_max8952_pdata __initdata = {
}, },
.num_consumer_supplies = 1, .num_consumer_supplies = 1,
.consumer_supplies = &max8952_consumer, .consumer_supplies = &max8952_consumer,
}, };
static struct max8952_platform_data universal_max8952_pdata __initdata = {
.gpio_vid0 = EXYNOS4_GPX0(3),
.gpio_vid1 = EXYNOS4_GPX0(4),
.gpio_en = -1, /* Not controllable, set "Always High" */
.default_mode = 0, /* vid0 = 0, vid1 = 0 */
.dvs_mode = { 48, 32, 28, 18 }, /* 1.25, 1.20, 1.05, 0.95V */
.sync_freq = 0, /* default: fastest */
.ramp_speed = 0, /* default: fastest */
.reg_data = &universal_max8952_reg_data,
}; };
static struct regulator_consumer_supply lp3974_buck1_consumer = static struct regulator_consumer_supply lp3974_buck1_consumer =
......
...@@ -28,6 +28,9 @@ ...@@ -28,6 +28,9 @@
#include <linux/regulator/max8952.h> #include <linux/regulator/max8952.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/io.h> #include <linux/io.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/regulator/of_regulator.h>
#include <linux/slab.h> #include <linux/slab.h>
/* Registers */ /* Registers */
...@@ -126,6 +129,69 @@ static const struct regulator_desc regulator = { ...@@ -126,6 +129,69 @@ static const struct regulator_desc regulator = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
#ifdef CONFIG_OF
static struct of_device_id max8952_dt_match[] = {
{ .compatible = "maxim,max8952" },
{},
};
MODULE_DEVICE_TABLE(of, max8952_dt_match);
static struct max8952_platform_data *max8952_parse_dt(struct device *dev)
{
struct max8952_platform_data *pd;
struct device_node *np = dev->of_node;
int ret;
int i;
pd = devm_kzalloc(dev, sizeof(*pd), GFP_KERNEL);
if (!pd) {
dev_err(dev, "Failed to allocate platform data\n");
return NULL;
}
pd->gpio_vid0 = of_get_named_gpio(np, "max8952,vid-gpios", 0);
pd->gpio_vid1 = of_get_named_gpio(np, "max8952,vid-gpios", 1);
pd->gpio_en = of_get_named_gpio(np, "max8952,en-gpio", 0);
if (of_property_read_u32(np, "max8952,default-mode", &pd->default_mode))
dev_warn(dev, "Default mode not specified, assuming 0\n");
ret = of_property_read_u32_array(np, "max8952,dvs-mode-microvolt",
pd->dvs_mode, ARRAY_SIZE(pd->dvs_mode));
if (ret) {
dev_err(dev, "max8952,dvs-mode-microvolt property not specified");
return NULL;
}
for (i = 0; i < ARRAY_SIZE(pd->dvs_mode); ++i) {
if (pd->dvs_mode[i] < 770000 || pd->dvs_mode[i] > 1400000) {
dev_err(dev, "DVS voltage %d out of range\n", i);
return NULL;
}
pd->dvs_mode[i] = (pd->dvs_mode[i] - 770000) / 10000;
}
if (of_property_read_u32(np, "max8952,sync-freq", &pd->sync_freq))
dev_warn(dev, "max8952,sync-freq property not specified, defaulting to 26MHz\n");
if (of_property_read_u32(np, "max8952,ramp-speed", &pd->ramp_speed))
dev_warn(dev, "max8952,ramp-speed property not specified, defaulting to 32mV/us\n");
pd->reg_data = of_get_regulator_init_data(dev, np);
if (!pd->reg_data) {
dev_err(dev, "Failed to parse regulator init data\n");
return NULL;
}
return pd;
}
#else
static struct max8952_platform_data *max8952_parse_dt(struct device *dev)
{
return NULL;
}
#endif
static int max8952_pmic_probe(struct i2c_client *client, static int max8952_pmic_probe(struct i2c_client *client,
const struct i2c_device_id *i2c_id) const struct i2c_device_id *i2c_id)
{ {
...@@ -136,6 +202,9 @@ static int max8952_pmic_probe(struct i2c_client *client, ...@@ -136,6 +202,9 @@ static int max8952_pmic_probe(struct i2c_client *client,
int ret = 0, err = 0; int ret = 0, err = 0;
if (client->dev.of_node)
pdata = max8952_parse_dt(&client->dev);
if (!pdata) { if (!pdata) {
dev_err(&client->dev, "Require the platform data\n"); dev_err(&client->dev, "Require the platform data\n");
return -EINVAL; return -EINVAL;
...@@ -154,11 +223,12 @@ static int max8952_pmic_probe(struct i2c_client *client, ...@@ -154,11 +223,12 @@ static int max8952_pmic_probe(struct i2c_client *client,
max8952->pdata = pdata; max8952->pdata = pdata;
config.dev = max8952->dev; config.dev = max8952->dev;
config.init_data = &pdata->reg_data; config.init_data = pdata->reg_data;
config.driver_data = max8952; config.driver_data = max8952;
config.of_node = client->dev.of_node;
config.ena_gpio = pdata->gpio_en; config.ena_gpio = pdata->gpio_en;
if (pdata->reg_data.constraints.boot_on) if (pdata->reg_data->constraints.boot_on)
config.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH; config.ena_gpio_flags |= GPIOF_OUT_INIT_HIGH;
max8952->rdev = regulator_register(&regulator, &config); max8952->rdev = regulator_register(&regulator, &config);
...@@ -271,6 +341,7 @@ static struct i2c_driver max8952_pmic_driver = { ...@@ -271,6 +341,7 @@ static struct i2c_driver max8952_pmic_driver = {
.remove = max8952_pmic_remove, .remove = max8952_pmic_remove,
.driver = { .driver = {
.name = "max8952", .name = "max8952",
.of_match_table = of_match_ptr(max8952_dt_match),
}, },
.id_table = max8952_ids, .id_table = max8952_ids,
}; };
......
...@@ -122,13 +122,13 @@ struct max8952_platform_data { ...@@ -122,13 +122,13 @@ struct max8952_platform_data {
int gpio_vid1; int gpio_vid1;
int gpio_en; int gpio_en;
u8 default_mode; u32 default_mode;
u8 dvs_mode[MAX8952_NUM_DVS_MODE]; /* MAX8952_DVS_MODEx_XXXXmV */ u32 dvs_mode[MAX8952_NUM_DVS_MODE]; /* MAX8952_DVS_MODEx_XXXXmV */
u8 sync_freq; u32 sync_freq;
u8 ramp_speed; u32 ramp_speed;
struct regulator_init_data reg_data; struct regulator_init_data *reg_data;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment