linux/drivers/regulator/fan53880.c
Uwe Kleine-König (The Capable Hub) 8e74b2db58
regulator: Use named initializers for arrays of i2c_device_data
While being less compact, using named initializers allows to more easily
see which members of the structs are assigned which value without having
to lookup the declaration of the struct. And it's also more robust
against changes to the struct definition.

The mentioned robustness is relevant for a planned change to struct
i2c_device_id that replaces .driver_data by an anonymous union.

While touching all these arrays, unify usage of whitespace and commas.

This patch doesn't modify the compiled arrays, only their representation
in source form benefits. The former was confirmed with x86 and arm64
builds.

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
Link: https://patch.msgid.link/2e83a9747ac2c92db8f91fd0e0eb311c4efe8e73.1782827697.git.u.kleine-koenig@baylibre.com
Signed-off-by: Mark Brown <broonie@kernel.org>
2026-06-30 23:40:20 +01:00

186 lines
4.8 KiB
C

// SPDX-License-Identifier: GPL-2.0+
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/regulator/driver.h>
enum fan53880_regulator_ids {
FAN53880_LDO1,
FAN53880_LDO2,
FAN53880_LDO3,
FAN53880_LDO4,
FAN53880_BUCK,
FAN53880_BOOST,
};
enum fan53880_registers {
FAN53880_PRODUCT_ID = 0x00,
FAN53880_SILICON_REV,
FAN53880_BUCKVOUT,
FAN53880_BOOSTVOUT,
FAN53880_LDO1VOUT,
FAN53880_LDO2VOUT,
FAN53880_LDO3VOUT,
FAN53880_LDO4VOUT,
FAN53880_IOUT,
FAN53880_ENABLE,
FAN53880_ENABLE_BOOST,
};
#define FAN53880_ID 0x01
static const struct regulator_ops fan53880_ops = {
.list_voltage = regulator_list_voltage_linear_range,
.map_voltage = regulator_map_voltage_linear_range,
.set_voltage_sel = regulator_set_voltage_sel_regmap,
.get_voltage_sel = regulator_get_voltage_sel_regmap,
.enable = regulator_enable_regmap,
.disable = regulator_disable_regmap,
.is_enabled = regulator_is_enabled_regmap,
};
#define FAN53880_LDO(_num, _supply, _default) \
[FAN53880_LDO ## _num] = { \
.name = "LDO"#_num, \
.of_match = "LDO"#_num, \
.regulators_node = "regulators", \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
.linear_ranges = (struct linear_range[]) { \
REGULATOR_LINEAR_RANGE(_default, 0x0, 0x0, 0), \
REGULATOR_LINEAR_RANGE(800000, 0xf, 0x73, 25000), \
}, \
.n_linear_ranges = 2, \
.n_voltages = 0x74, \
.vsel_reg = FAN53880_LDO ## _num ## VOUT, \
.vsel_mask = 0x7f, \
.enable_reg = FAN53880_ENABLE, \
.enable_mask = BIT(_num - 1), \
.enable_time = 150, \
.supply_name = _supply, \
.ops = &fan53880_ops, \
}
static const struct regulator_desc fan53880_regulators[] = {
FAN53880_LDO(1, "VIN12", 2800000),
FAN53880_LDO(2, "VIN12", 2800000),
FAN53880_LDO(3, "VIN3", 1800000),
FAN53880_LDO(4, "VIN4", 1800000),
[FAN53880_BUCK] = {
.name = "BUCK",
.of_match = "BUCK",
.regulators_node = "regulators",
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(1100000, 0x0, 0x0, 0),
REGULATOR_LINEAR_RANGE(600000, 0x1f, 0xf7, 12500),
},
.n_linear_ranges = 2,
.n_voltages = 0xf8,
.vsel_reg = FAN53880_BUCKVOUT,
.vsel_mask = 0xff,
.enable_reg = FAN53880_ENABLE,
.enable_mask = 0x10,
.enable_time = 480,
.supply_name = "PVIN",
.ops = &fan53880_ops,
},
[FAN53880_BOOST] = {
.name = "BOOST",
.of_match = "BOOST",
.regulators_node = "regulators",
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
.linear_ranges = (struct linear_range[]) {
REGULATOR_LINEAR_RANGE(5000000, 0x0, 0x0, 0),
REGULATOR_LINEAR_RANGE(3000000, 0x4, 0x70, 25000),
},
.n_linear_ranges = 2,
.n_voltages = 0x71,
.vsel_reg = FAN53880_BOOSTVOUT,
.vsel_mask = 0x7f,
.enable_reg = FAN53880_ENABLE_BOOST,
.enable_mask = 0xff,
.enable_time = 580,
.supply_name = "PVIN",
.ops = &fan53880_ops,
},
};
static const struct regmap_config fan53880_regmap = {
.reg_bits = 8,
.val_bits = 8,
.max_register = FAN53880_ENABLE_BOOST,
};
static int fan53880_i2c_probe(struct i2c_client *i2c)
{
struct regulator_config config = { };
struct regulator_dev *rdev;
struct regmap *regmap;
int i, ret;
unsigned int data;
regmap = devm_regmap_init_i2c(i2c, &fan53880_regmap);
if (IS_ERR(regmap)) {
ret = PTR_ERR(regmap);
dev_err(&i2c->dev, "Failed to create regmap: %d\n", ret);
return ret;
}
ret = regmap_read(regmap, FAN53880_PRODUCT_ID, &data);
if (ret < 0) {
dev_err(&i2c->dev, "Failed to read PRODUCT_ID: %d\n", ret);
return ret;
}
if (data != FAN53880_ID) {
dev_err(&i2c->dev, "Unsupported device id: 0x%x.\n", data);
return -ENODEV;
}
config.dev = &i2c->dev;
config.init_data = NULL;
for (i = 0; i < ARRAY_SIZE(fan53880_regulators); i++) {
rdev = devm_regulator_register(&i2c->dev,
&fan53880_regulators[i],
&config);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&i2c->dev, "Failed to register %s: %d\n",
fan53880_regulators[i].name, ret);
return ret;
}
}
return 0;
}
static const struct of_device_id fan53880_dt_ids[] = {
{ .compatible = "onnn,fan53880", },
{}
};
MODULE_DEVICE_TABLE(of, fan53880_dt_ids);
static const struct i2c_device_id fan53880_i2c_id[] = {
{ .name = "fan53880" },
{ }
};
MODULE_DEVICE_TABLE(i2c, fan53880_i2c_id);
static struct i2c_driver fan53880_regulator_driver = {
.driver = {
.name = "fan53880",
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
.of_match_table = fan53880_dt_ids,
},
.probe = fan53880_i2c_probe,
.id_table = fan53880_i2c_id,
};
module_i2c_driver(fan53880_regulator_driver);
MODULE_DESCRIPTION("FAN53880 PMIC voltage regulator driver");
MODULE_AUTHOR("Christoph Fritz <chf.fritz@googlemail.com>");
MODULE_LICENSE("GPL");