linux/drivers/regulator/88pg86x.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/module.h>
   3#include <linux/i2c.h>
   4#include <linux/of.h>
   5#include <linux/regulator/driver.h>
   6#include <linux/regmap.h>
   7
   8static const struct regulator_ops pg86x_ops = {
   9        .set_voltage_sel = regulator_set_voltage_sel_regmap,
  10        .get_voltage_sel = regulator_get_voltage_sel_regmap,
  11        .list_voltage = regulator_list_voltage_linear_range,
  12};
  13
  14static const struct linear_range pg86x_buck1_ranges[] = {
  15        REGULATOR_LINEAR_RANGE(      0,  0, 10,     0),
  16        REGULATOR_LINEAR_RANGE(1000000, 11, 34, 25000),
  17        REGULATOR_LINEAR_RANGE(1600000, 35, 47, 50000),
  18};
  19
  20static const struct linear_range pg86x_buck2_ranges[] = {
  21        REGULATOR_LINEAR_RANGE(      0,  0, 15,     0),
  22        REGULATOR_LINEAR_RANGE(1000000, 16, 39, 25000),
  23        REGULATOR_LINEAR_RANGE(1600000, 40, 52, 50000),
  24};
  25
  26static const struct regulator_desc pg86x_regulators[] = {
  27        {
  28                .id = 0,
  29                .type = REGULATOR_VOLTAGE,
  30                .name = "buck1",
  31                .of_match = of_match_ptr("buck1"),
  32                .n_voltages = 11 + 24 + 13,
  33                .linear_ranges = pg86x_buck1_ranges,
  34                .n_linear_ranges = 3,
  35                .vsel_reg  = 0x24,
  36                .vsel_mask = 0xff,
  37                .ops = &pg86x_ops,
  38                .owner = THIS_MODULE
  39        },
  40        {
  41                .id = 1,
  42                .type = REGULATOR_VOLTAGE,
  43                .name = "buck2",
  44                .of_match = of_match_ptr("buck2"),
  45                .n_voltages = 16 + 24 + 13,
  46                .linear_ranges = pg86x_buck2_ranges,
  47                .n_linear_ranges = 3,
  48                .vsel_reg  = 0x13,
  49                .vsel_mask = 0xff,
  50                .ops = &pg86x_ops,
  51                .owner = THIS_MODULE
  52        },
  53};
  54
  55static const struct regmap_config pg86x_regmap = {
  56        .reg_bits = 8,
  57        .val_bits = 8,
  58};
  59
  60static int pg86x_i2c_probe(struct i2c_client *i2c)
  61{
  62        int id, ret;
  63        struct regulator_config config = {.dev = &i2c->dev};
  64        struct regmap *regmap = devm_regmap_init_i2c(i2c, &pg86x_regmap);
  65
  66        if (IS_ERR(regmap)) {
  67                ret = PTR_ERR(regmap);
  68                dev_err(&i2c->dev, "regmap init failed: %d\n", ret);
  69                return ret;
  70        }
  71
  72        for (id = 0; id < ARRAY_SIZE(pg86x_regulators); id++) {
  73                struct regulator_dev *rdev;
  74                rdev = devm_regulator_register(&i2c->dev,
  75                                               &pg86x_regulators[id],
  76                                               &config);
  77                if (IS_ERR(rdev)) {
  78                        ret = PTR_ERR(rdev);
  79                        dev_err(&i2c->dev, "failed to register %s: %d\n",
  80                                pg86x_regulators[id].name, ret);
  81                        return ret;
  82                }
  83        }
  84        return 0;
  85}
  86
  87static const struct of_device_id __maybe_unused pg86x_dt_ids[] = {
  88        { .compatible = "marvell,88pg867" },
  89        { .compatible = "marvell,88pg868" },
  90        { }
  91};
  92MODULE_DEVICE_TABLE(of, pg86x_dt_ids);
  93
  94static const struct i2c_device_id pg86x_i2c_id[] = {
  95        { "88pg867", },
  96        { "88pg868", },
  97        { }
  98};
  99MODULE_DEVICE_TABLE(i2c, pg86x_i2c_id);
 100
 101static struct i2c_driver pg86x_regulator_driver = {
 102        .driver = {
 103                .name = "88pg86x",
 104                .of_match_table = of_match_ptr(pg86x_dt_ids),
 105        },
 106        .probe_new = pg86x_i2c_probe,
 107        .id_table = pg86x_i2c_id,
 108};
 109
 110module_i2c_driver(pg86x_regulator_driver);
 111
 112MODULE_DESCRIPTION("Marvell 88PG86X voltage regulator");
 113MODULE_AUTHOR("Alexander Monakov <amonakov@gmail.com>");
 114MODULE_LICENSE("GPL");
 115