linux/drivers/regulator/pv88080-regulator.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2//
   3// pv88080-regulator.c - Regulator device driver for PV88080
   4// Copyright (C) 2016  Powerventure Semiconductor Ltd.
   5
   6#include <linux/err.h>
   7#include <linux/i2c.h>
   8#include <linux/module.h>
   9#include <linux/of.h>
  10#include <linux/init.h>
  11#include <linux/slab.h>
  12#include <linux/regulator/driver.h>
  13#include <linux/regulator/machine.h>
  14#include <linux/regmap.h>
  15#include <linux/irq.h>
  16#include <linux/interrupt.h>
  17#include <linux/regulator/of_regulator.h>
  18#include "pv88080-regulator.h"
  19
  20#define PV88080_MAX_REGULATORS  4
  21
  22/* PV88080 REGULATOR IDs */
  23enum {
  24        /* BUCKs */
  25        PV88080_ID_BUCK1,
  26        PV88080_ID_BUCK2,
  27        PV88080_ID_BUCK3,
  28        PV88080_ID_HVBUCK,
  29};
  30
  31enum pv88080_types {
  32        TYPE_PV88080_AA,
  33        TYPE_PV88080_BA,
  34};
  35
  36struct pv88080_regulator {
  37        struct regulator_desc desc;
  38        unsigned int mode_reg;
  39        unsigned int conf2;
  40        unsigned int conf5;
  41};
  42
  43struct pv88080 {
  44        struct device *dev;
  45        struct regmap *regmap;
  46        struct regulator_dev *rdev[PV88080_MAX_REGULATORS];
  47        unsigned long type;
  48        const struct pv88080_compatible_regmap *regmap_config;
  49};
  50
  51struct pv88080_buck_voltage {
  52        int min_uV;
  53        int max_uV;
  54        int uV_step;
  55};
  56
  57struct pv88080_buck_regmap {
  58        /* REGS */
  59        int buck_enable_reg;
  60        int buck_vsel_reg;
  61        int buck_mode_reg;
  62        int buck_limit_reg;
  63        int buck_vdac_range_reg;
  64        int buck_vrange_gain_reg;
  65        /* MASKS */
  66        int buck_enable_mask;
  67        int buck_vsel_mask;
  68        int buck_limit_mask;
  69};
  70
  71struct pv88080_compatible_regmap {
  72        /* BUCK1, 2, 3 */
  73        struct pv88080_buck_regmap buck_regmap[PV88080_MAX_REGULATORS-1];
  74        /* HVBUCK */
  75        int hvbuck_enable_reg;
  76        int hvbuck_vsel_reg;
  77        int hvbuck_enable_mask;
  78        int hvbuck_vsel_mask;
  79};
  80
  81static const struct regmap_config pv88080_regmap_config = {
  82        .reg_bits = 8,
  83        .val_bits = 8,
  84};
  85
  86/* Current limits array (in uA) for BUCK1, BUCK2, BUCK3.
  87 * Entry indexes corresponds to register values.
  88 */
  89
  90static const unsigned int pv88080_buck1_limits[] = {
  91        3230000, 5130000, 6960000, 8790000
  92};
  93
  94static const unsigned int pv88080_buck23_limits[] = {
  95        1496000, 2393000, 3291000, 4189000
  96};
  97
  98static const struct pv88080_buck_voltage pv88080_buck_vol[2] = {
  99        {
 100                .min_uV = 600000,
 101                .max_uV = 1393750,
 102                .uV_step = 6250,
 103        },
 104        {
 105                .min_uV = 1400000,
 106                .max_uV = 2193750,
 107                .uV_step = 6250,
 108        },
 109};
 110
 111static const struct pv88080_compatible_regmap pv88080_aa_regs = {
 112        /* BUCK1 */
 113        .buck_regmap[0] = {
 114                .buck_enable_reg      = PV88080AA_REG_BUCK1_CONF0,
 115                .buck_vsel_reg        = PV88080AA_REG_BUCK1_CONF0,
 116                .buck_mode_reg        = PV88080AA_REG_BUCK1_CONF1,
 117                .buck_limit_reg       = PV88080AA_REG_BUCK1_CONF1,
 118                .buck_vdac_range_reg  = PV88080AA_REG_BUCK1_CONF2,
 119                .buck_vrange_gain_reg = PV88080AA_REG_BUCK1_CONF5,
 120                .buck_enable_mask     = PV88080_BUCK1_EN,
 121                .buck_vsel_mask       = PV88080_VBUCK1_MASK,
 122                .buck_limit_mask      = PV88080_BUCK1_ILIM_MASK,
 123        },
 124        /* BUCK2 */
 125        .buck_regmap[1] = {
 126                .buck_enable_reg      = PV88080AA_REG_BUCK2_CONF0,
 127                .buck_vsel_reg        = PV88080AA_REG_BUCK2_CONF0,
 128                .buck_mode_reg        = PV88080AA_REG_BUCK2_CONF1,
 129                .buck_limit_reg       = PV88080AA_REG_BUCK2_CONF1,
 130                .buck_vdac_range_reg  = PV88080AA_REG_BUCK2_CONF2,
 131                .buck_vrange_gain_reg = PV88080AA_REG_BUCK2_CONF5,
 132                .buck_enable_mask         = PV88080_BUCK2_EN,
 133                .buck_vsel_mask       = PV88080_VBUCK2_MASK,
 134                .buck_limit_mask      = PV88080_BUCK2_ILIM_MASK,
 135        },
 136        /* BUCK3 */
 137        .buck_regmap[2] = {
 138                .buck_enable_reg          = PV88080AA_REG_BUCK3_CONF0,
 139                .buck_vsel_reg        = PV88080AA_REG_BUCK3_CONF0,
 140                .buck_mode_reg        = PV88080AA_REG_BUCK3_CONF1,
 141                .buck_limit_reg       = PV88080AA_REG_BUCK3_CONF1,
 142                .buck_vdac_range_reg  = PV88080AA_REG_BUCK3_CONF2,
 143                .buck_vrange_gain_reg = PV88080AA_REG_BUCK3_CONF5,
 144                .buck_enable_mask         = PV88080_BUCK3_EN,
 145                .buck_vsel_mask       = PV88080_VBUCK3_MASK,
 146                .buck_limit_mask      = PV88080_BUCK3_ILIM_MASK,
 147        },
 148        /* HVBUCK */
 149        .hvbuck_enable_reg            = PV88080AA_REG_HVBUCK_CONF2,
 150        .hvbuck_vsel_reg          = PV88080AA_REG_HVBUCK_CONF1,
 151        .hvbuck_enable_mask       = PV88080_HVBUCK_EN,
 152        .hvbuck_vsel_mask         = PV88080_VHVBUCK_MASK,
 153};
 154
 155static const struct pv88080_compatible_regmap pv88080_ba_regs = {
 156        /* BUCK1 */
 157        .buck_regmap[0] = {
 158                .buck_enable_reg          = PV88080BA_REG_BUCK1_CONF0,
 159                .buck_vsel_reg        = PV88080BA_REG_BUCK1_CONF0,
 160                .buck_mode_reg        = PV88080BA_REG_BUCK1_CONF1,
 161                .buck_limit_reg       = PV88080BA_REG_BUCK1_CONF1,
 162                .buck_vdac_range_reg  = PV88080BA_REG_BUCK1_CONF2,
 163                .buck_vrange_gain_reg = PV88080BA_REG_BUCK1_CONF5,
 164                .buck_enable_mask     = PV88080_BUCK1_EN,
 165                .buck_vsel_mask       = PV88080_VBUCK1_MASK,
 166                .buck_limit_mask          = PV88080_BUCK1_ILIM_MASK,
 167        },
 168        /* BUCK2 */
 169        .buck_regmap[1] = {
 170                .buck_enable_reg          = PV88080BA_REG_BUCK2_CONF0,
 171                .buck_vsel_reg        = PV88080BA_REG_BUCK2_CONF0,
 172                .buck_mode_reg        = PV88080BA_REG_BUCK2_CONF1,
 173                .buck_limit_reg       = PV88080BA_REG_BUCK2_CONF1,
 174                .buck_vdac_range_reg  = PV88080BA_REG_BUCK2_CONF2,
 175                .buck_vrange_gain_reg = PV88080BA_REG_BUCK2_CONF5,
 176                .buck_enable_mask         = PV88080_BUCK2_EN,
 177                .buck_vsel_mask       = PV88080_VBUCK2_MASK,
 178                .buck_limit_mask          = PV88080_BUCK2_ILIM_MASK,
 179        },
 180        /* BUCK3 */
 181        .buck_regmap[2] = {
 182                .buck_enable_reg          = PV88080BA_REG_BUCK3_CONF0,
 183                .buck_vsel_reg        = PV88080BA_REG_BUCK3_CONF0,
 184                .buck_mode_reg        = PV88080BA_REG_BUCK3_CONF1,
 185                .buck_limit_reg       = PV88080BA_REG_BUCK3_CONF1,
 186                .buck_vdac_range_reg  = PV88080BA_REG_BUCK3_CONF2,
 187                .buck_vrange_gain_reg = PV88080BA_REG_BUCK3_CONF5,
 188                .buck_enable_mask         = PV88080_BUCK3_EN,
 189                .buck_vsel_mask       = PV88080_VBUCK3_MASK,
 190                .buck_limit_mask          = PV88080_BUCK3_ILIM_MASK,
 191        },
 192        /* HVBUCK */
 193        .hvbuck_enable_reg            = PV88080BA_REG_HVBUCK_CONF2,
 194        .hvbuck_vsel_reg          = PV88080BA_REG_HVBUCK_CONF1,
 195        .hvbuck_enable_mask       = PV88080_HVBUCK_EN,
 196        .hvbuck_vsel_mask                 = PV88080_VHVBUCK_MASK,
 197};
 198
 199#ifdef CONFIG_OF
 200static const struct of_device_id pv88080_dt_ids[] = {
 201        { .compatible = "pvs,pv88080",    .data = (void *)TYPE_PV88080_AA },
 202        { .compatible = "pvs,pv88080-aa", .data = (void *)TYPE_PV88080_AA },
 203        { .compatible = "pvs,pv88080-ba", .data = (void *)TYPE_PV88080_BA },
 204        {},
 205};
 206MODULE_DEVICE_TABLE(of, pv88080_dt_ids);
 207#endif
 208
 209static unsigned int pv88080_buck_get_mode(struct regulator_dev *rdev)
 210{
 211        struct pv88080_regulator *info = rdev_get_drvdata(rdev);
 212        unsigned int data;
 213        int ret, mode = 0;
 214
 215        ret = regmap_read(rdev->regmap, info->mode_reg, &data);
 216        if (ret < 0)
 217                return ret;
 218
 219        switch (data & PV88080_BUCK1_MODE_MASK) {
 220        case PV88080_BUCK_MODE_SYNC:
 221                mode = REGULATOR_MODE_FAST;
 222                break;
 223        case PV88080_BUCK_MODE_AUTO:
 224                mode = REGULATOR_MODE_NORMAL;
 225                break;
 226        case PV88080_BUCK_MODE_SLEEP:
 227                mode = REGULATOR_MODE_STANDBY;
 228                break;
 229        default:
 230                return -EINVAL;
 231        }
 232
 233        return mode;
 234}
 235
 236static int pv88080_buck_set_mode(struct regulator_dev *rdev,
 237                                        unsigned int mode)
 238{
 239        struct pv88080_regulator *info = rdev_get_drvdata(rdev);
 240        int val = 0;
 241
 242        switch (mode) {
 243        case REGULATOR_MODE_FAST:
 244                val = PV88080_BUCK_MODE_SYNC;
 245                break;
 246        case REGULATOR_MODE_NORMAL:
 247                val = PV88080_BUCK_MODE_AUTO;
 248                break;
 249        case REGULATOR_MODE_STANDBY:
 250                val = PV88080_BUCK_MODE_SLEEP;
 251                break;
 252        default:
 253                return -EINVAL;
 254        }
 255
 256        return regmap_update_bits(rdev->regmap, info->mode_reg,
 257                                        PV88080_BUCK1_MODE_MASK, val);
 258}
 259
 260static const struct regulator_ops pv88080_buck_ops = {
 261        .get_mode = pv88080_buck_get_mode,
 262        .set_mode = pv88080_buck_set_mode,
 263        .enable = regulator_enable_regmap,
 264        .disable = regulator_disable_regmap,
 265        .is_enabled = regulator_is_enabled_regmap,
 266        .set_voltage_sel = regulator_set_voltage_sel_regmap,
 267        .get_voltage_sel = regulator_get_voltage_sel_regmap,
 268        .list_voltage = regulator_list_voltage_linear,
 269        .set_current_limit = regulator_set_current_limit_regmap,
 270        .get_current_limit = regulator_get_current_limit_regmap,
 271};
 272
 273static const struct regulator_ops pv88080_hvbuck_ops = {
 274        .enable = regulator_enable_regmap,
 275        .disable = regulator_disable_regmap,
 276        .is_enabled = regulator_is_enabled_regmap,
 277        .set_voltage_sel = regulator_set_voltage_sel_regmap,
 278        .get_voltage_sel = regulator_get_voltage_sel_regmap,
 279        .list_voltage = regulator_list_voltage_linear,
 280};
 281
 282#define PV88080_BUCK(chip, regl_name, min, step, max, limits_array) \
 283{\
 284        .desc   =       {\
 285                .id = chip##_ID_##regl_name,\
 286                .name = __stringify(chip##_##regl_name),\
 287                .of_match = of_match_ptr(#regl_name),\
 288                .regulators_node = of_match_ptr("regulators"),\
 289                .type = REGULATOR_VOLTAGE,\
 290                .owner = THIS_MODULE,\
 291                .ops = &pv88080_buck_ops,\
 292                .min_uV = min, \
 293                .uV_step = step, \
 294                .n_voltages = ((max) - (min))/(step) + 1, \
 295                .curr_table = limits_array, \
 296                .n_current_limits = ARRAY_SIZE(limits_array), \
 297        },\
 298}
 299
 300#define PV88080_HVBUCK(chip, regl_name, min, step, max) \
 301{\
 302        .desc   =       {\
 303                .id = chip##_ID_##regl_name,\
 304                .name = __stringify(chip##_##regl_name),\
 305                .of_match = of_match_ptr(#regl_name),\
 306                .regulators_node = of_match_ptr("regulators"),\
 307                .type = REGULATOR_VOLTAGE,\
 308                .owner = THIS_MODULE,\
 309                .ops = &pv88080_hvbuck_ops,\
 310                .min_uV = min, \
 311                .uV_step = step, \
 312                .n_voltages = ((max) - (min))/(step) + 1, \
 313        },\
 314}
 315
 316static struct pv88080_regulator pv88080_regulator_info[] = {
 317        PV88080_BUCK(PV88080, BUCK1, 600000, 6250, 1393750,
 318                pv88080_buck1_limits),
 319        PV88080_BUCK(PV88080, BUCK2, 600000, 6250, 1393750,
 320                pv88080_buck23_limits),
 321        PV88080_BUCK(PV88080, BUCK3, 600000, 6250, 1393750,
 322                pv88080_buck23_limits),
 323        PV88080_HVBUCK(PV88080, HVBUCK, 0, 5000, 1275000),
 324};
 325
 326static irqreturn_t pv88080_irq_handler(int irq, void *data)
 327{
 328        struct pv88080 *chip = data;
 329        int i, reg_val, err, ret = IRQ_NONE;
 330
 331        err = regmap_read(chip->regmap, PV88080_REG_EVENT_A, &reg_val);
 332        if (err < 0)
 333                goto error_i2c;
 334
 335        if (reg_val & PV88080_E_VDD_FLT) {
 336                for (i = 0; i < PV88080_MAX_REGULATORS; i++) {
 337                        if (chip->rdev[i] != NULL)
 338                                regulator_notifier_call_chain(chip->rdev[i],
 339                                        REGULATOR_EVENT_UNDER_VOLTAGE,
 340                                        NULL);
 341                }
 342
 343                err = regmap_write(chip->regmap, PV88080_REG_EVENT_A,
 344                        PV88080_E_VDD_FLT);
 345                if (err < 0)
 346                        goto error_i2c;
 347
 348                ret = IRQ_HANDLED;
 349        }
 350
 351        if (reg_val & PV88080_E_OVER_TEMP) {
 352                for (i = 0; i < PV88080_MAX_REGULATORS; i++) {
 353                        if (chip->rdev[i] != NULL)
 354                                regulator_notifier_call_chain(chip->rdev[i],
 355                                        REGULATOR_EVENT_OVER_TEMP,
 356                                        NULL);
 357                }
 358
 359                err = regmap_write(chip->regmap, PV88080_REG_EVENT_A,
 360                        PV88080_E_OVER_TEMP);
 361                if (err < 0)
 362                        goto error_i2c;
 363
 364                ret = IRQ_HANDLED;
 365        }
 366
 367        return ret;
 368
 369error_i2c:
 370        dev_err(chip->dev, "I2C error : %d\n", err);
 371        return IRQ_NONE;
 372}
 373
 374/*
 375 * I2C driver interface functions
 376 */
 377static int pv88080_i2c_probe(struct i2c_client *i2c,
 378                const struct i2c_device_id *id)
 379{
 380        struct regulator_init_data *init_data = dev_get_platdata(&i2c->dev);
 381        struct pv88080 *chip;
 382        const struct pv88080_compatible_regmap *regmap_config;
 383        const struct of_device_id *match;
 384        struct regulator_config config = { };
 385        int i, error, ret;
 386        unsigned int conf2, conf5;
 387
 388        chip = devm_kzalloc(&i2c->dev, sizeof(struct pv88080), GFP_KERNEL);
 389        if (!chip)
 390                return -ENOMEM;
 391
 392        chip->dev = &i2c->dev;
 393        chip->regmap = devm_regmap_init_i2c(i2c, &pv88080_regmap_config);
 394        if (IS_ERR(chip->regmap)) {
 395                error = PTR_ERR(chip->regmap);
 396                dev_err(chip->dev, "Failed to allocate register map: %d\n",
 397                        error);
 398                return error;
 399        }
 400
 401        if (i2c->dev.of_node) {
 402                match = of_match_node(pv88080_dt_ids, i2c->dev.of_node);
 403                if (!match) {
 404                        dev_err(chip->dev, "Failed to get of_match_node\n");
 405                        return -EINVAL;
 406                }
 407                chip->type = (unsigned long)match->data;
 408        } else {
 409                chip->type = id->driver_data;
 410        }
 411
 412        i2c_set_clientdata(i2c, chip);
 413
 414        if (i2c->irq != 0) {
 415                ret = regmap_write(chip->regmap, PV88080_REG_MASK_A, 0xFF);
 416                if (ret < 0) {
 417                        dev_err(chip->dev,
 418                                "Failed to mask A reg: %d\n", ret);
 419                        return ret;
 420                }
 421                ret = regmap_write(chip->regmap, PV88080_REG_MASK_B, 0xFF);
 422                if (ret < 0) {
 423                        dev_err(chip->dev,
 424                                "Failed to mask B reg: %d\n", ret);
 425                        return ret;
 426                }
 427                ret = regmap_write(chip->regmap, PV88080_REG_MASK_C, 0xFF);
 428                if (ret < 0) {
 429                        dev_err(chip->dev,
 430                                "Failed to mask C reg: %d\n", ret);
 431                        return ret;
 432                }
 433
 434                ret = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
 435                                        pv88080_irq_handler,
 436                                        IRQF_TRIGGER_LOW|IRQF_ONESHOT,
 437                                        "pv88080", chip);
 438                if (ret != 0) {
 439                        dev_err(chip->dev, "Failed to request IRQ: %d\n",
 440                                i2c->irq);
 441                        return ret;
 442                }
 443
 444                ret = regmap_update_bits(chip->regmap, PV88080_REG_MASK_A,
 445                        PV88080_M_VDD_FLT | PV88080_M_OVER_TEMP, 0);
 446                if (ret < 0) {
 447                        dev_err(chip->dev,
 448                                "Failed to update mask reg: %d\n", ret);
 449                        return ret;
 450                }
 451        } else {
 452                dev_warn(chip->dev, "No IRQ configured\n");
 453        }
 454
 455        switch (chip->type) {
 456        case TYPE_PV88080_AA:
 457                chip->regmap_config = &pv88080_aa_regs;
 458                break;
 459        case TYPE_PV88080_BA:
 460                chip->regmap_config = &pv88080_ba_regs;
 461                break;
 462        }
 463
 464        regmap_config = chip->regmap_config;
 465        config.dev = chip->dev;
 466        config.regmap = chip->regmap;
 467
 468        /* Registeration for BUCK1, 2, 3 */
 469        for (i = 0; i < PV88080_MAX_REGULATORS-1; i++) {
 470                if (init_data)
 471                        config.init_data = &init_data[i];
 472
 473                pv88080_regulator_info[i].desc.csel_reg
 474                        = regmap_config->buck_regmap[i].buck_limit_reg;
 475                pv88080_regulator_info[i].desc.csel_mask
 476                        = regmap_config->buck_regmap[i].buck_limit_mask;
 477                pv88080_regulator_info[i].mode_reg
 478                        = regmap_config->buck_regmap[i].buck_mode_reg;
 479                pv88080_regulator_info[i].conf2
 480                        = regmap_config->buck_regmap[i].buck_vdac_range_reg;
 481                pv88080_regulator_info[i].conf5
 482                        = regmap_config->buck_regmap[i].buck_vrange_gain_reg;
 483                pv88080_regulator_info[i].desc.enable_reg
 484                        = regmap_config->buck_regmap[i].buck_enable_reg;
 485                pv88080_regulator_info[i].desc.enable_mask
 486                        = regmap_config->buck_regmap[i].buck_enable_mask;
 487                pv88080_regulator_info[i].desc.vsel_reg
 488                        = regmap_config->buck_regmap[i].buck_vsel_reg;
 489                pv88080_regulator_info[i].desc.vsel_mask
 490                        = regmap_config->buck_regmap[i].buck_vsel_mask;
 491
 492                ret = regmap_read(chip->regmap,
 493                                pv88080_regulator_info[i].conf2, &conf2);
 494                if (ret < 0)
 495                        return ret;
 496                conf2 = ((conf2 >> PV88080_BUCK_VDAC_RANGE_SHIFT) &
 497                        PV88080_BUCK_VDAC_RANGE_MASK);
 498
 499                ret = regmap_read(chip->regmap,
 500                                pv88080_regulator_info[i].conf5, &conf5);
 501                if (ret < 0)
 502                        return ret;
 503                conf5 = ((conf5 >> PV88080_BUCK_VRANGE_GAIN_SHIFT) &
 504                        PV88080_BUCK_VRANGE_GAIN_MASK);
 505
 506                pv88080_regulator_info[i].desc.min_uV =
 507                        pv88080_buck_vol[conf2].min_uV * (conf5+1);
 508                pv88080_regulator_info[i].desc.uV_step =
 509                        pv88080_buck_vol[conf2].uV_step * (conf5+1);
 510                pv88080_regulator_info[i].desc.n_voltages =
 511                        ((pv88080_buck_vol[conf2].max_uV * (conf5+1))
 512                        - (pv88080_regulator_info[i].desc.min_uV))
 513                        /(pv88080_regulator_info[i].desc.uV_step) + 1;
 514
 515                config.driver_data = (void *)&pv88080_regulator_info[i];
 516                chip->rdev[i] = devm_regulator_register(chip->dev,
 517                        &pv88080_regulator_info[i].desc, &config);
 518                if (IS_ERR(chip->rdev[i])) {
 519                        dev_err(chip->dev,
 520                                "Failed to register PV88080 regulator\n");
 521                        return PTR_ERR(chip->rdev[i]);
 522                }
 523        }
 524
 525        pv88080_regulator_info[PV88080_ID_HVBUCK].desc.enable_reg
 526                = regmap_config->hvbuck_enable_reg;
 527        pv88080_regulator_info[PV88080_ID_HVBUCK].desc.enable_mask
 528                = regmap_config->hvbuck_enable_mask;
 529        pv88080_regulator_info[PV88080_ID_HVBUCK].desc.vsel_reg
 530                = regmap_config->hvbuck_vsel_reg;
 531        pv88080_regulator_info[PV88080_ID_HVBUCK].desc.vsel_mask
 532                = regmap_config->hvbuck_vsel_mask;
 533
 534        /* Registeration for HVBUCK */
 535        if (init_data)
 536                config.init_data = &init_data[PV88080_ID_HVBUCK];
 537
 538        config.driver_data = (void *)&pv88080_regulator_info[PV88080_ID_HVBUCK];
 539        chip->rdev[PV88080_ID_HVBUCK] = devm_regulator_register(chip->dev,
 540                &pv88080_regulator_info[PV88080_ID_HVBUCK].desc, &config);
 541        if (IS_ERR(chip->rdev[PV88080_ID_HVBUCK])) {
 542                dev_err(chip->dev, "Failed to register PV88080 regulator\n");
 543                return PTR_ERR(chip->rdev[PV88080_ID_HVBUCK]);
 544        }
 545
 546        return 0;
 547}
 548
 549static const struct i2c_device_id pv88080_i2c_id[] = {
 550        { "pv88080",    TYPE_PV88080_AA },
 551        { "pv88080-aa", TYPE_PV88080_AA },
 552        { "pv88080-ba", TYPE_PV88080_BA },
 553        {},
 554};
 555MODULE_DEVICE_TABLE(i2c, pv88080_i2c_id);
 556
 557static struct i2c_driver pv88080_regulator_driver = {
 558        .driver = {
 559                .name = "pv88080",
 560                .of_match_table = of_match_ptr(pv88080_dt_ids),
 561        },
 562        .probe = pv88080_i2c_probe,
 563        .id_table = pv88080_i2c_id,
 564};
 565
 566module_i2c_driver(pv88080_regulator_driver);
 567
 568MODULE_AUTHOR("James Ban <James.Ban.opensource@diasemi.com>");
 569MODULE_DESCRIPTION("Regulator device driver for Powerventure PV88080");
 570MODULE_LICENSE("GPL");
 571