summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/regulator/max8973-regulator.c104
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,
OpenPOWER on IntegriCloud