new file mode 100644
@@ -0,0 +1,52 @@
+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;
+ };
@@ -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,
};
@@ -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;
};