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