diff options
Diffstat (limited to 'drivers/regulator')
-rw-r--r-- | drivers/regulator/max8973-regulator.c | 104 |
1 files changed, 84 insertions, 20 deletions
diff --git a/drivers/regulator/max8973-regulator.c b/drivers/regulator/max8973-regulator.c index 663e4df44048..89e53e049399 100644 --- a/drivers/regulator/max8973-regulator.c +++ b/drivers/regulator/max8973-regulator.c @@ -27,6 +27,7 @@ #include <linux/init.h> #include <linux/err.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/regulator/driver.h> #include <linux/regulator/machine.h> @@ -91,6 +92,11 @@ #define MAX8973_VOLATGE_STEP 6250 #define MAX8973_BUCK_N_VOLTAGE 0x80 +enum device_id { + MAX8973, + MAX77621 +}; + /* Maxim 8973 chip information */ struct max8973_chip { struct device *dev; @@ -104,6 +110,7 @@ struct max8973_chip { int curr_vout_reg; int curr_gpio_val; struct regulator_ops ops; + enum device_id id; }; /* @@ -390,7 +397,7 @@ static int max8973_init_dcdc(struct max8973_chip *max, } /* If external control is enabled then disable EN bit */ - if (max->enable_external_control) { + if (max->enable_external_control && (max->id == MAX8973)) { ret = regmap_update_bits(max->regmap, MAX8973_VOUT, MAX8973_VOUT_ENABLE, 0); if (ret < 0) @@ -448,6 +455,13 @@ static struct max8973_regulator_platform_data *max8973_parse_dt( return pdata; } +static const struct of_device_id of_max8973_match_tbl[] = { + { .compatible = "maxim,max8973", .data = (void *)MAX8973, }, + { .compatible = "maxim,max77621", .data = (void *)MAX77621, }, + { }, +}; +MODULE_DEVICE_TABLE(of, of_max8973_match_tbl); + static int max8973_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -457,6 +471,7 @@ static int max8973_probe(struct i2c_client *client, struct regulator_dev *rdev; struct max8973_chip *max; bool pdata_from_dt = false; + unsigned int chip_id; int ret; pdata = dev_get_platdata(&client->dev); @@ -486,6 +501,27 @@ static int max8973_probe(struct i2c_client *client, return ret; } + if (client->dev.of_node) { + const struct of_device_id *match; + + match = of_match_device(of_match_ptr(of_max8973_match_tbl), + &client->dev); + if (!match) + return -ENODATA; + max->id = (u32)((uintptr_t)match->data); + } else { + max->id = id->driver_data; + } + + ret = regmap_read(max->regmap, MAX8973_CHIPID1, &chip_id); + if (ret < 0) { + dev_err(&client->dev, "register CHIPID1 read failed, %d", ret); + return ret; + } + + dev_info(&client->dev, "CHIP-ID OTP: 0x%02x ID_M: 0x%02x\n", + (chip_id >> 4) & 0xF, (chip_id >> 1) & 0x7); + i2c_set_clientdata(client, max); max->ops = max8973_dcdc_ops; max->dev = &client->dev; @@ -507,14 +543,6 @@ static int max8973_probe(struct i2c_client *client, if (gpio_is_valid(max->enable_gpio)) max->enable_external_control = true; - if (!pdata->enable_ext_control) { - max->desc.enable_reg = MAX8973_VOUT; - max->desc.enable_mask = MAX8973_VOUT_ENABLE; - max->ops.enable = regulator_enable_regmap; - max->ops.disable = regulator_disable_regmap; - max->ops.is_enabled = regulator_is_enabled_regmap; - } - max->lru_index[0] = max->curr_vout_reg; if (gpio_is_valid(max->dvs_gpio)) { @@ -546,6 +574,50 @@ static int max8973_probe(struct i2c_client *client, pdata->reg_init_data = of_get_regulator_init_data(&client->dev, client->dev.of_node, &max->desc); + ridata = pdata->reg_init_data; + switch (max->id) { + case MAX8973: + if (!pdata->enable_ext_control) { + max->desc.enable_reg = MAX8973_VOUT; + max->desc.enable_mask = MAX8973_VOUT_ENABLE; + max->ops.enable = regulator_enable_regmap; + max->ops.disable = regulator_disable_regmap; + max->ops.is_enabled = regulator_is_enabled_regmap; + break; + } + + if (gpio_is_valid(max->enable_gpio)) { + config.ena_gpio_flags = GPIOF_OUT_INIT_LOW; + if (ridata && (ridata->constraints.always_on || + ridata->constraints.boot_on)) + config.ena_gpio_flags = GPIOF_OUT_INIT_HIGH; + config.ena_gpio = max->enable_gpio; + } + break; + + case MAX77621: + if (gpio_is_valid(max->enable_gpio)) { + ret = devm_gpio_request_one(&client->dev, + max->enable_gpio, GPIOF_OUT_INIT_HIGH, + "max8973-en-gpio"); + if (ret) { + dev_err(&client->dev, + "gpio_request for gpio %d failed: %d\n", + max->enable_gpio, ret); + return ret; + } + } + + max->desc.enable_reg = MAX8973_VOUT; + max->desc.enable_mask = MAX8973_VOUT_ENABLE; + max->ops.enable = regulator_enable_regmap; + max->ops.disable = regulator_disable_regmap; + max->ops.is_enabled = regulator_is_enabled_regmap; + break; + default: + break; + } + ret = max8973_init_dcdc(max, pdata); if (ret < 0) { dev_err(max->dev, "Max8973 Init failed, err = %d\n", ret); @@ -558,15 +630,6 @@ static int max8973_probe(struct i2c_client *client, config.of_node = client->dev.of_node; config.regmap = max->regmap; - if (gpio_is_valid(max->enable_gpio)) { - ridata = pdata->reg_init_data; - config.ena_gpio_flags = GPIOF_OUT_INIT_LOW; - if (ridata && (ridata->constraints.always_on || - ridata->constraints.boot_on)) - config.ena_gpio_flags = GPIOF_OUT_INIT_HIGH; - config.ena_gpio = max->enable_gpio; - } - /* Register the regulators */ rdev = devm_regulator_register(&client->dev, &max->desc, &config); if (IS_ERR(rdev)) { @@ -579,15 +642,16 @@ static int max8973_probe(struct i2c_client *client, } static const struct i2c_device_id max8973_id[] = { - {.name = "max8973",}, + {.name = "max8973", .driver_data = MAX8973}, + {.name = "max77621", .driver_data = MAX77621}, {}, }; - MODULE_DEVICE_TABLE(i2c, max8973_id); static struct i2c_driver max8973_i2c_driver = { .driver = { .name = "max8973", + .of_match_table = of_max8973_match_tbl, .owner = THIS_MODULE, }, .probe = max8973_probe, |