|
@@ -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,
|