Skip to content

Commit

Permalink
regulator: act8865: prepare support for other act88xx devices
Browse files Browse the repository at this point in the history
This patch prepares support for other devices in the act88xx family of
PMUs manufactured by Active-Semi.

http://www.active-semi.com/products/power-management-units/act88xx/

Signed-off-by: Beniamino Galvani <b.galvani@gmail.com>
Tested-by: Wenyou Yang <wenyou.yang@atmel.com>
Reviewed-by: Axel Lin <axel.lin@ingics.com>
Signed-off-by: Mark Brown <broonie@linaro.org>
  • Loading branch information
Beniamino Galvani authored and Mark Brown committed Aug 5, 2014
1 parent bbb83f3 commit 50a03e3
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 129 deletions.
211 changes: 83 additions & 128 deletions drivers/regulator/act8865-regulator.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* act8865-regulator.c - Voltage regulation for the active-semi ACT8865
* http://www.active-semi.com/sheets/ACT8865_Datasheet.pdf
* act8865-regulator.c - Voltage regulation for active-semi ACT88xx PMUs
*
* http://www.active-semi.com/products/power-management-units/act88xx/
*
* Copyright (C) 2013 Atmel Corporation
*
Expand Down Expand Up @@ -70,7 +71,7 @@ static const struct regmap_config act8865_regmap_config = {
.val_bits = 8,
};

static const struct regulator_linear_range act8865_volatge_ranges[] = {
static const struct regulator_linear_range act8865_voltage_ranges[] = {
REGULATOR_LINEAR_RANGE(600000, 0, 23, 25000),
REGULATOR_LINEAR_RANGE(1200000, 24, 47, 50000),
REGULATOR_LINEAR_RANGE(2400000, 48, 63, 100000),
Expand All @@ -86,110 +87,35 @@ static struct regulator_ops act8865_ops = {
.is_enabled = regulator_is_enabled_regmap,
};

static const struct regulator_desc act8865_reg[] = {
{
.name = "DCDC_REG1",
.id = ACT8865_ID_DCDC1,
.ops = &act8865_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = ACT8865_VOLTAGE_NUM,
.linear_ranges = act8865_volatge_ranges,
.n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
.vsel_reg = ACT8865_DCDC1_VSET1,
.vsel_mask = ACT8865_VSEL_MASK,
.enable_reg = ACT8865_DCDC1_CTRL,
.enable_mask = ACT8865_ENA,
.owner = THIS_MODULE,
},
{
.name = "DCDC_REG2",
.id = ACT8865_ID_DCDC2,
.ops = &act8865_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = ACT8865_VOLTAGE_NUM,
.linear_ranges = act8865_volatge_ranges,
.n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
.vsel_reg = ACT8865_DCDC2_VSET1,
.vsel_mask = ACT8865_VSEL_MASK,
.enable_reg = ACT8865_DCDC2_CTRL,
.enable_mask = ACT8865_ENA,
.owner = THIS_MODULE,
},
{
.name = "DCDC_REG3",
.id = ACT8865_ID_DCDC3,
.ops = &act8865_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = ACT8865_VOLTAGE_NUM,
.linear_ranges = act8865_volatge_ranges,
.n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
.vsel_reg = ACT8865_DCDC3_VSET1,
.vsel_mask = ACT8865_VSEL_MASK,
.enable_reg = ACT8865_DCDC3_CTRL,
.enable_mask = ACT8865_ENA,
.owner = THIS_MODULE,
},
{
.name = "LDO_REG1",
.id = ACT8865_ID_LDO1,
.ops = &act8865_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = ACT8865_VOLTAGE_NUM,
.linear_ranges = act8865_volatge_ranges,
.n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
.vsel_reg = ACT8865_LDO1_VSET,
.vsel_mask = ACT8865_VSEL_MASK,
.enable_reg = ACT8865_LDO1_CTRL,
.enable_mask = ACT8865_ENA,
.owner = THIS_MODULE,
},
{
.name = "LDO_REG2",
.id = ACT8865_ID_LDO2,
.ops = &act8865_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = ACT8865_VOLTAGE_NUM,
.linear_ranges = act8865_volatge_ranges,
.n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
.vsel_reg = ACT8865_LDO2_VSET,
.vsel_mask = ACT8865_VSEL_MASK,
.enable_reg = ACT8865_LDO2_CTRL,
.enable_mask = ACT8865_ENA,
.owner = THIS_MODULE,
},
{
.name = "LDO_REG3",
.id = ACT8865_ID_LDO3,
.ops = &act8865_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = ACT8865_VOLTAGE_NUM,
.linear_ranges = act8865_volatge_ranges,
.n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
.vsel_reg = ACT8865_LDO3_VSET,
.vsel_mask = ACT8865_VSEL_MASK,
.enable_reg = ACT8865_LDO3_CTRL,
.enable_mask = ACT8865_ENA,
.owner = THIS_MODULE,
},
{
.name = "LDO_REG4",
.id = ACT8865_ID_LDO4,
.ops = &act8865_ops,
.type = REGULATOR_VOLTAGE,
.n_voltages = ACT8865_VOLTAGE_NUM,
.linear_ranges = act8865_volatge_ranges,
.n_linear_ranges = ARRAY_SIZE(act8865_volatge_ranges),
.vsel_reg = ACT8865_LDO4_VSET,
.vsel_mask = ACT8865_VSEL_MASK,
.enable_reg = ACT8865_LDO4_CTRL,
.enable_mask = ACT8865_ENA,
.owner = THIS_MODULE,
},
#define ACT88xx_REG(_name, _family, _id, _vsel_reg) \
[_family##_ID_##_id] = { \
.name = _name, \
.id = _family##_ID_##_id, \
.type = REGULATOR_VOLTAGE, \
.ops = &act8865_ops, \
.n_voltages = ACT8865_VOLTAGE_NUM, \
.linear_ranges = act8865_voltage_ranges, \
.n_linear_ranges = ARRAY_SIZE(act8865_voltage_ranges), \
.vsel_reg = _family##_##_id##_##_vsel_reg, \
.vsel_mask = ACT8865_VSEL_MASK, \
.enable_reg = _family##_##_id##_CTRL, \
.enable_mask = ACT8865_ENA, \
.owner = THIS_MODULE, \
}

static const struct regulator_desc act8865_regulators[] = {
ACT88xx_REG("DCDC_REG1", ACT8865, DCDC1, VSET1),
ACT88xx_REG("DCDC_REG2", ACT8865, DCDC2, VSET1),
ACT88xx_REG("DCDC_REG3", ACT8865, DCDC3, VSET1),
ACT88xx_REG("LDO_REG1", ACT8865, LDO1, VSET),
ACT88xx_REG("LDO_REG2", ACT8865, LDO2, VSET),
ACT88xx_REG("LDO_REG3", ACT8865, LDO3, VSET),
ACT88xx_REG("LDO_REG4", ACT8865, LDO4, VSET),
};

#ifdef CONFIG_OF
static const struct of_device_id act8865_dt_ids[] = {
{ .compatible = "active-semi,act8865" },
{ .compatible = "active-semi,act8865", .data = (void *)ACT8865 },
{ }
};
MODULE_DEVICE_TABLE(of, act8865_dt_ids);
Expand All @@ -206,7 +132,9 @@ static struct of_regulator_match act8865_matches[] = {

static int act8865_pdata_from_dt(struct device *dev,
struct device_node **of_node,
struct act8865_platform_data *pdata)
struct act8865_platform_data *pdata,
struct of_regulator_match *matches,
int num_matches)
{
int matched, i;
struct device_node *np;
Expand All @@ -218,26 +146,25 @@ static int act8865_pdata_from_dt(struct device *dev,
return -EINVAL;
}

matched = of_regulator_match(dev, np,
act8865_matches, ARRAY_SIZE(act8865_matches));
matched = of_regulator_match(dev, np, matches, num_matches);
of_node_put(np);
if (matched <= 0)
return matched;

pdata->regulators = devm_kzalloc(dev,
sizeof(struct act8865_regulator_data) *
ARRAY_SIZE(act8865_matches), GFP_KERNEL);
sizeof(struct act8865_regulator_data) *
num_matches, GFP_KERNEL);
if (!pdata->regulators)
return -ENOMEM;

pdata->num_regulators = ARRAY_SIZE(act8865_matches);
pdata->num_regulators = num_matches;
regulator = pdata->regulators;

for (i = 0; i < ARRAY_SIZE(act8865_matches); i++) {
for (i = 0; i < num_matches; i++) {
regulator->id = i;
regulator->name = act8865_matches[i].name;
regulator->platform_data = act8865_matches[i].init_data;
of_node[i] = act8865_matches[i].of_node;
regulator->name = matches[i].name;
regulator->platform_data = matches[i].init_data;
of_node[i] = matches[i].of_node;
regulator++;
}

Expand Down Expand Up @@ -269,34 +196,59 @@ static struct regulator_init_data
}

static int act8865_pmic_probe(struct i2c_client *client,
const struct i2c_device_id *i2c_id)
const struct i2c_device_id *i2c_id)
{
struct regulator_dev *rdev;
static const struct regulator_desc *regulators;
struct act8865_platform_data pdata_of, *pdata;
struct of_regulator_match *matches;
struct device *dev = &client->dev;
struct act8865_platform_data *pdata = dev_get_platdata(dev);
struct regulator_config config = { };
struct device_node **of_node;
int i, ret, num_regulators;
struct act8865 *act8865;
struct device_node *of_node[ACT8865_REG_NUM];
int i;
int ret;
unsigned long type;

pdata = dev_get_platdata(dev);

if (dev->of_node && !pdata) {
const struct of_device_id *id;
struct act8865_platform_data pdata_of;

id = of_match_device(of_match_ptr(act8865_dt_ids), dev);
if (!id)
return -ENODEV;

ret = act8865_pdata_from_dt(dev, of_node, &pdata_of);
type = (unsigned long) id->data;
} else {
type = i2c_id->driver_data;
}

switch (type) {
case ACT8865:
matches = act8865_matches;
regulators = act8865_regulators;
num_regulators = ARRAY_SIZE(act8865_regulators);
break;
default:
dev_err(dev, "invalid device id %lu\n", type);
return -EINVAL;
}

of_node = devm_kzalloc(dev, sizeof(struct device_node *) *
num_regulators, GFP_KERNEL);
if (!of_node)
return -ENOMEM;

if (dev->of_node && !pdata) {
ret = act8865_pdata_from_dt(dev, of_node, &pdata_of, matches,
num_regulators);
if (ret < 0)
return ret;

pdata = &pdata_of;
}

if (pdata->num_regulators > ACT8865_REG_NUM) {
dev_err(dev, "Too many regulators found!\n");
if (pdata->num_regulators > num_regulators) {
dev_err(dev, "too many regulators: %d\n",
pdata->num_regulators);
return -EINVAL;
}

Expand All @@ -313,8 +265,10 @@ static int act8865_pmic_probe(struct i2c_client *client,
}

/* Finally register devices */
for (i = 0; i < ACT8865_REG_NUM; i++) {
const struct regulator_desc *desc = &act8865_reg[i];
for (i = 0; i < num_regulators; i++) {
const struct regulator_desc *desc = &regulators[i];
struct regulator_config config = { };
struct regulator_dev *rdev;

config.dev = dev;
config.init_data = act8865_get_init_data(desc->id, pdata);
Expand All @@ -330,12 +284,13 @@ static int act8865_pmic_probe(struct i2c_client *client,
}

i2c_set_clientdata(client, act8865);
devm_kfree(dev, of_node);

return 0;
}

static const struct i2c_device_id act8865_ids[] = {
{ "act8865", 0 },
{ .name = "act8865", .driver_data = ACT8865 },
{ },
};
MODULE_DEVICE_TABLE(i2c, act8865_ids);
Expand All @@ -351,6 +306,6 @@ static struct i2c_driver act8865_pmic_driver = {

module_i2c_driver(act8865_pmic_driver);

MODULE_DESCRIPTION("active-semi act8865 voltage regulator driver");
MODULE_DESCRIPTION("active-semi act88xx voltage regulator driver");
MODULE_AUTHOR("Wenyou Yang <wenyou.yang@atmel.com>");
MODULE_LICENSE("GPL v2");
6 changes: 5 additions & 1 deletion include/linux/regulator/act8865.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* act8865.h -- Voltage regulation for the active-semi act8865
* act8865.h -- Voltage regulation for active-semi act88xx PMUs
*
* Copyright (C) 2013 Atmel Corporation.
*
Expand Down Expand Up @@ -29,6 +29,10 @@ enum {
ACT8865_REG_NUM,
};

enum {
ACT8865,
};

/**
* act8865_regulator_data - regulator data
* @id: regulator id
Expand Down

0 comments on commit 50a03e3

Please sign in to comment.