Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3ff4aa95 authored by Tomasz Figa's avatar Tomasz Figa Committed by Mark Brown
Browse files

regulator: max8952: Add Device Tree support



This patch adds Device Tree support to max8952 regulator driver.

Signed-off-by: default avatarTomasz Figa <t.figa@samsung.com>
Signed-off-by: default avatarKyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: default avatarMark Brown <broonie@opensource.wolfsonmicro.com>
parent 3ec6eb9c
Loading
Loading
Loading
Loading
+52 −0
Original line number Diff line number Diff line
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;
	};
+70 −0
Original line number Diff line number Diff line
@@ -28,6 +28,9 @@
#include <linux/regulator/max8952.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/regulator/of_regulator.h>
#include <linux/slab.h>

/* Registers */
@@ -126,6 +129,69 @@ static const struct regulator_desc regulator = {
	.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,
		const struct i2c_device_id *i2c_id)
{
@@ -136,6 +202,9 @@ static int max8952_pmic_probe(struct i2c_client *client,

	int ret = 0, err = 0;

	if (client->dev.of_node)
		pdata = max8952_parse_dt(&client->dev);

	if (!pdata) {
		dev_err(&client->dev, "Require the platform data\n");
		return -EINVAL;
@@ -271,6 +340,7 @@ static struct i2c_driver max8952_pmic_driver = {
	.remove		= max8952_pmic_remove,
	.driver		= {
		.name	= "max8952",
		.of_match_table = of_match_ptr(max8952_dt_match),
	},
	.id_table	= max8952_ids,
};
+4 −4
Original line number Diff line number Diff line
@@ -122,11 +122,11 @@ struct max8952_platform_data {
	int gpio_vid1;
	int gpio_en;

	u8 default_mode;
	u8 dvs_mode[MAX8952_NUM_DVS_MODE]; /* MAX8952_DVS_MODEx_XXXXmV */
	u32 default_mode;
	u32 dvs_mode[MAX8952_NUM_DVS_MODE]; /* MAX8952_DVS_MODEx_XXXXmV */

	u8 sync_freq;
	u8 ramp_speed;
	u32 sync_freq;
	u32 ramp_speed;

	struct regulator_init_data *reg_data;
};