|
@@ -81,16 +81,17 @@ enum {
|
|
|
struct max8660 {
|
|
|
struct i2c_client *client;
|
|
|
u8 shadow_regs[MAX8660_N_REGS]; /* as chip is write only */
|
|
|
- struct regulator_dev *rdev[];
|
|
|
};
|
|
|
|
|
|
static int max8660_write(struct max8660 *max8660, u8 reg, u8 mask, u8 val)
|
|
|
{
|
|
|
- static const u8 max8660_addresses[MAX8660_N_REGS] =
|
|
|
- { 0x10, 0x12, 0x20, 0x23, 0x24, 0x29, 0x2a, 0x32, 0x33, 0x39, 0x80 };
|
|
|
+ static const u8 max8660_addresses[MAX8660_N_REGS] = {
|
|
|
+ 0x10, 0x12, 0x20, 0x23, 0x24, 0x29, 0x2a, 0x32, 0x33, 0x39, 0x80
|
|
|
+ };
|
|
|
|
|
|
int ret;
|
|
|
u8 reg_val = (max8660->shadow_regs[reg] & mask) | val;
|
|
|
+
|
|
|
dev_vdbg(&max8660->client->dev, "Writing reg %02x with %02x\n",
|
|
|
max8660_addresses[reg], reg_val);
|
|
|
|
|
@@ -112,6 +113,7 @@ static int max8660_dcdc_is_enabled(struct regulator_dev *rdev)
|
|
|
struct max8660 *max8660 = rdev_get_drvdata(rdev);
|
|
|
u8 val = max8660->shadow_regs[MAX8660_OVER1];
|
|
|
u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4;
|
|
|
+
|
|
|
return !!(val & mask);
|
|
|
}
|
|
|
|
|
@@ -119,6 +121,7 @@ static int max8660_dcdc_enable(struct regulator_dev *rdev)
|
|
|
{
|
|
|
struct max8660 *max8660 = rdev_get_drvdata(rdev);
|
|
|
u8 bit = (rdev_get_id(rdev) == MAX8660_V3) ? 1 : 4;
|
|
|
+
|
|
|
return max8660_write(max8660, MAX8660_OVER1, 0xff, bit);
|
|
|
}
|
|
|
|
|
@@ -126,15 +129,16 @@ static int max8660_dcdc_disable(struct regulator_dev *rdev)
|
|
|
{
|
|
|
struct max8660 *max8660 = rdev_get_drvdata(rdev);
|
|
|
u8 mask = (rdev_get_id(rdev) == MAX8660_V3) ? ~1 : ~4;
|
|
|
+
|
|
|
return max8660_write(max8660, MAX8660_OVER1, mask, 0);
|
|
|
}
|
|
|
|
|
|
static int max8660_dcdc_get_voltage_sel(struct regulator_dev *rdev)
|
|
|
{
|
|
|
struct max8660 *max8660 = rdev_get_drvdata(rdev);
|
|
|
-
|
|
|
u8 reg = (rdev_get_id(rdev) == MAX8660_V3) ? MAX8660_ADTV2 : MAX8660_SDTV2;
|
|
|
u8 selector = max8660->shadow_regs[reg];
|
|
|
+
|
|
|
return selector;
|
|
|
}
|
|
|
|
|
@@ -207,6 +211,7 @@ static int max8660_ldo67_is_enabled(struct regulator_dev *rdev)
|
|
|
struct max8660 *max8660 = rdev_get_drvdata(rdev);
|
|
|
u8 val = max8660->shadow_regs[MAX8660_OVER2];
|
|
|
u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4;
|
|
|
+
|
|
|
return !!(val & mask);
|
|
|
}
|
|
|
|
|
@@ -214,6 +219,7 @@ static int max8660_ldo67_enable(struct regulator_dev *rdev)
|
|
|
{
|
|
|
struct max8660 *max8660 = rdev_get_drvdata(rdev);
|
|
|
u8 bit = (rdev_get_id(rdev) == MAX8660_V6) ? 2 : 4;
|
|
|
+
|
|
|
return max8660_write(max8660, MAX8660_OVER2, 0xff, bit);
|
|
|
}
|
|
|
|
|
@@ -221,15 +227,16 @@ static int max8660_ldo67_disable(struct regulator_dev *rdev)
|
|
|
{
|
|
|
struct max8660 *max8660 = rdev_get_drvdata(rdev);
|
|
|
u8 mask = (rdev_get_id(rdev) == MAX8660_V6) ? ~2 : ~4;
|
|
|
+
|
|
|
return max8660_write(max8660, MAX8660_OVER2, mask, 0);
|
|
|
}
|
|
|
|
|
|
static int max8660_ldo67_get_voltage_sel(struct regulator_dev *rdev)
|
|
|
{
|
|
|
struct max8660 *max8660 = rdev_get_drvdata(rdev);
|
|
|
-
|
|
|
u8 shift = (rdev_get_id(rdev) == MAX8660_V6) ? 0 : 4;
|
|
|
u8 selector = (max8660->shadow_regs[MAX8660_L12VCR] >> shift) & 0xf;
|
|
|
+
|
|
|
return selector;
|
|
|
}
|
|
|
|
|
@@ -330,7 +337,7 @@ static int max8660_pdata_from_dt(struct device *dev,
|
|
|
struct max8660_subdev_data *sub;
|
|
|
struct of_regulator_match rmatch[ARRAY_SIZE(max8660_reg)];
|
|
|
|
|
|
- np = of_find_node_by_name(dev->of_node, "regulators");
|
|
|
+ np = of_get_child_by_name(dev->of_node, "regulators");
|
|
|
if (!np) {
|
|
|
dev_err(dev, "missing 'regulators' subnode in DT\n");
|
|
|
return -EINVAL;
|
|
@@ -340,6 +347,7 @@ static int max8660_pdata_from_dt(struct device *dev,
|
|
|
rmatch[i].name = max8660_reg[i].name;
|
|
|
|
|
|
matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(rmatch));
|
|
|
+ of_node_put(np);
|
|
|
if (matched <= 0)
|
|
|
return matched;
|
|
|
|
|
@@ -373,7 +381,6 @@ static inline int max8660_pdata_from_dt(struct device *dev,
|
|
|
static int max8660_probe(struct i2c_client *client,
|
|
|
const struct i2c_device_id *i2c_id)
|
|
|
{
|
|
|
- struct regulator_dev **rdev;
|
|
|
struct device *dev = &client->dev;
|
|
|
struct max8660_platform_data *pdata = dev_get_platdata(dev);
|
|
|
struct regulator_config config = { };
|
|
@@ -406,14 +413,11 @@ static int max8660_probe(struct i2c_client *client,
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
- max8660 = devm_kzalloc(dev, sizeof(struct max8660) +
|
|
|
- sizeof(struct regulator_dev *) * MAX8660_V_END,
|
|
|
- GFP_KERNEL);
|
|
|
+ max8660 = devm_kzalloc(dev, sizeof(struct max8660), GFP_KERNEL);
|
|
|
if (!max8660)
|
|
|
return -ENOMEM;
|
|
|
|
|
|
max8660->client = client;
|
|
|
- rdev = max8660->rdev;
|
|
|
|
|
|
if (pdata->en34_is_high) {
|
|
|
/* Simulate always on */
|
|
@@ -481,6 +485,7 @@ static int max8660_probe(struct i2c_client *client,
|
|
|
|
|
|
/* Finally register devices */
|
|
|
for (i = 0; i < pdata->num_subdevs; i++) {
|
|
|
+ struct regulator_dev *rdev;
|
|
|
|
|
|
id = pdata->subdevs[i].id;
|
|
|
|
|
@@ -489,13 +494,13 @@ static int max8660_probe(struct i2c_client *client,
|
|
|
config.of_node = of_node[i];
|
|
|
config.driver_data = max8660;
|
|
|
|
|
|
- rdev[i] = devm_regulator_register(&client->dev,
|
|
|
+ rdev = devm_regulator_register(&client->dev,
|
|
|
&max8660_reg[id], &config);
|
|
|
- if (IS_ERR(rdev[i])) {
|
|
|
- ret = PTR_ERR(rdev[i]);
|
|
|
+ if (IS_ERR(rdev)) {
|
|
|
+ ret = PTR_ERR(rdev);
|
|
|
dev_err(&client->dev, "failed to register %s\n",
|
|
|
max8660_reg[id].name);
|
|
|
- return PTR_ERR(rdev[i]);
|
|
|
+ return PTR_ERR(rdev);
|
|
|
}
|
|
|
}
|
|
|
|