linux/drivers/regulator/pca9450-regulator.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright 2020 NXP.
   4 * NXP PCA9450 pmic driver
   5 */
   6
   7#include <linux/err.h>
   8#include <linux/gpio/consumer.h>
   9#include <linux/i2c.h>
  10#include <linux/interrupt.h>
  11#include <linux/kernel.h>
  12#include <linux/module.h>
  13#include <linux/of.h>
  14#include <linux/of_device.h>
  15#include <linux/platform_device.h>
  16#include <linux/regulator/driver.h>
  17#include <linux/regulator/machine.h>
  18#include <linux/regulator/of_regulator.h>
  19#include <linux/regulator/pca9450.h>
  20
  21struct pc9450_dvs_config {
  22        unsigned int run_reg; /* dvs0 */
  23        unsigned int run_mask;
  24        unsigned int standby_reg; /* dvs1 */
  25        unsigned int standby_mask;
  26};
  27
  28struct pca9450_regulator_desc {
  29        struct regulator_desc desc;
  30        const struct pc9450_dvs_config dvs;
  31};
  32
  33struct pca9450 {
  34        struct device *dev;
  35        struct regmap *regmap;
  36        struct gpio_desc *sd_vsel_gpio;
  37        enum pca9450_chip_type type;
  38        unsigned int rcnt;
  39        int irq;
  40};
  41
  42static const struct regmap_range pca9450_status_range = {
  43        .range_min = PCA9450_REG_INT1,
  44        .range_max = PCA9450_REG_PWRON_STAT,
  45};
  46
  47static const struct regmap_access_table pca9450_volatile_regs = {
  48        .yes_ranges = &pca9450_status_range,
  49        .n_yes_ranges = 1,
  50};
  51
  52static const struct regmap_config pca9450_regmap_config = {
  53        .reg_bits = 8,
  54        .val_bits = 8,
  55        .volatile_table = &pca9450_volatile_regs,
  56        .max_register = PCA9450_MAX_REGISTER - 1,
  57        .cache_type = REGCACHE_RBTREE,
  58};
  59
  60/*
  61 * BUCK1/2/3
  62 * BUCK1RAM[1:0] BUCK1 DVS ramp rate setting
  63 * 00: 25mV/1usec
  64 * 01: 25mV/2usec
  65 * 10: 25mV/4usec
  66 * 11: 25mV/8usec
  67 */
  68static const unsigned int pca9450_dvs_buck_ramp_table[] = {
  69        25000, 12500, 6250, 3125
  70};
  71
  72static const struct regulator_ops pca9450_dvs_buck_regulator_ops = {
  73        .enable = regulator_enable_regmap,
  74        .disable = regulator_disable_regmap,
  75        .is_enabled = regulator_is_enabled_regmap,
  76        .list_voltage = regulator_list_voltage_linear_range,
  77        .set_voltage_sel = regulator_set_voltage_sel_regmap,
  78        .get_voltage_sel = regulator_get_voltage_sel_regmap,
  79        .set_voltage_time_sel = regulator_set_voltage_time_sel,
  80        .set_ramp_delay = regulator_set_ramp_delay_regmap,
  81};
  82
  83static const struct regulator_ops pca9450_buck_regulator_ops = {
  84        .enable = regulator_enable_regmap,
  85        .disable = regulator_disable_regmap,
  86        .is_enabled = regulator_is_enabled_regmap,
  87        .list_voltage = regulator_list_voltage_linear_range,
  88        .set_voltage_sel = regulator_set_voltage_sel_regmap,
  89        .get_voltage_sel = regulator_get_voltage_sel_regmap,
  90        .set_voltage_time_sel = regulator_set_voltage_time_sel,
  91};
  92
  93static const struct regulator_ops pca9450_ldo_regulator_ops = {
  94        .enable = regulator_enable_regmap,
  95        .disable = regulator_disable_regmap,
  96        .is_enabled = regulator_is_enabled_regmap,
  97        .list_voltage = regulator_list_voltage_linear_range,
  98        .set_voltage_sel = regulator_set_voltage_sel_regmap,
  99        .get_voltage_sel = regulator_get_voltage_sel_regmap,
 100};
 101
 102/*
 103 * BUCK1/2/3
 104 * 0.60 to 2.1875V (12.5mV step)
 105 */
 106static const struct linear_range pca9450_dvs_buck_volts[] = {
 107        REGULATOR_LINEAR_RANGE(600000,  0x00, 0x7F, 12500),
 108};
 109
 110/*
 111 * BUCK4/5/6
 112 * 0.6V to 3.4V (25mV step)
 113 */
 114static const struct linear_range pca9450_buck_volts[] = {
 115        REGULATOR_LINEAR_RANGE(600000, 0x00, 0x70, 25000),
 116        REGULATOR_LINEAR_RANGE(3400000, 0x71, 0x7F, 0),
 117};
 118
 119/*
 120 * LDO1
 121 * 1.6 to 3.3V ()
 122 */
 123static const struct linear_range pca9450_ldo1_volts[] = {
 124        REGULATOR_LINEAR_RANGE(1600000, 0x00, 0x03, 100000),
 125        REGULATOR_LINEAR_RANGE(3000000, 0x04, 0x07, 100000),
 126};
 127
 128/*
 129 * LDO2
 130 * 0.8 to 1.15V (50mV step)
 131 */
 132static const struct linear_range pca9450_ldo2_volts[] = {
 133        REGULATOR_LINEAR_RANGE(800000, 0x00, 0x07, 50000),
 134};
 135
 136/*
 137 * LDO3/4
 138 * 0.8 to 3.3V (100mV step)
 139 */
 140static const struct linear_range pca9450_ldo34_volts[] = {
 141        REGULATOR_LINEAR_RANGE(800000, 0x00, 0x19, 100000),
 142        REGULATOR_LINEAR_RANGE(3300000, 0x1A, 0x1F, 0),
 143};
 144
 145/*
 146 * LDO5
 147 * 1.8 to 3.3V (100mV step)
 148 */
 149static const struct linear_range pca9450_ldo5_volts[] = {
 150        REGULATOR_LINEAR_RANGE(1800000,  0x00, 0x0F, 100000),
 151};
 152
 153static int buck_set_dvs(const struct regulator_desc *desc,
 154                        struct device_node *np, struct regmap *regmap,
 155                        char *prop, unsigned int reg, unsigned int mask)
 156{
 157        int ret, i;
 158        uint32_t uv;
 159
 160        ret = of_property_read_u32(np, prop, &uv);
 161        if (ret == -EINVAL)
 162                return 0;
 163        else if (ret)
 164                return ret;
 165
 166        for (i = 0; i < desc->n_voltages; i++) {
 167                ret = regulator_desc_list_voltage_linear_range(desc, i);
 168                if (ret < 0)
 169                        continue;
 170                if (ret == uv) {
 171                        i <<= ffs(desc->vsel_mask) - 1;
 172                        ret = regmap_update_bits(regmap, reg, mask, i);
 173                        break;
 174                }
 175        }
 176
 177        return ret;
 178}
 179
 180static int pca9450_set_dvs_levels(struct device_node *np,
 181                            const struct regulator_desc *desc,
 182                            struct regulator_config *cfg)
 183{
 184        struct pca9450_regulator_desc *data = container_of(desc,
 185                                        struct pca9450_regulator_desc, desc);
 186        const struct pc9450_dvs_config *dvs = &data->dvs;
 187        unsigned int reg, mask;
 188        char *prop;
 189        int i, ret = 0;
 190
 191        for (i = 0; i < PCA9450_DVS_LEVEL_MAX; i++) {
 192                switch (i) {
 193                case PCA9450_DVS_LEVEL_RUN:
 194                        prop = "nxp,dvs-run-voltage";
 195                        reg = dvs->run_reg;
 196                        mask = dvs->run_mask;
 197                        break;
 198                case PCA9450_DVS_LEVEL_STANDBY:
 199                        prop = "nxp,dvs-standby-voltage";
 200                        reg = dvs->standby_reg;
 201                        mask = dvs->standby_mask;
 202                        break;
 203                default:
 204                        return -EINVAL;
 205                }
 206
 207                ret = buck_set_dvs(desc, np, cfg->regmap, prop, reg, mask);
 208                if (ret)
 209                        break;
 210        }
 211
 212        return ret;
 213}
 214
 215static const struct pca9450_regulator_desc pca9450a_regulators[] = {
 216        {
 217                .desc = {
 218                        .name = "buck1",
 219                        .of_match = of_match_ptr("BUCK1"),
 220                        .regulators_node = of_match_ptr("regulators"),
 221                        .id = PCA9450_BUCK1,
 222                        .ops = &pca9450_dvs_buck_regulator_ops,
 223                        .type = REGULATOR_VOLTAGE,
 224                        .n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
 225                        .linear_ranges = pca9450_dvs_buck_volts,
 226                        .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
 227                        .vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
 228                        .vsel_mask = BUCK1OUT_DVS0_MASK,
 229                        .enable_reg = PCA9450_REG_BUCK1CTRL,
 230                        .enable_mask = BUCK1_ENMODE_MASK,
 231                        .ramp_reg = PCA9450_REG_BUCK1CTRL,
 232                        .ramp_mask = BUCK1_RAMP_MASK,
 233                        .ramp_delay_table = pca9450_dvs_buck_ramp_table,
 234                        .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
 235                        .owner = THIS_MODULE,
 236                        .of_parse_cb = pca9450_set_dvs_levels,
 237                },
 238                .dvs = {
 239                        .run_reg = PCA9450_REG_BUCK1OUT_DVS0,
 240                        .run_mask = BUCK1OUT_DVS0_MASK,
 241                        .standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
 242                        .standby_mask = BUCK1OUT_DVS1_MASK,
 243                },
 244        },
 245        {
 246                .desc = {
 247                        .name = "buck2",
 248                        .of_match = of_match_ptr("BUCK2"),
 249                        .regulators_node = of_match_ptr("regulators"),
 250                        .id = PCA9450_BUCK2,
 251                        .ops = &pca9450_dvs_buck_regulator_ops,
 252                        .type = REGULATOR_VOLTAGE,
 253                        .n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
 254                        .linear_ranges = pca9450_dvs_buck_volts,
 255                        .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
 256                        .vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
 257                        .vsel_mask = BUCK2OUT_DVS0_MASK,
 258                        .enable_reg = PCA9450_REG_BUCK2CTRL,
 259                        .enable_mask = BUCK1_ENMODE_MASK,
 260                        .ramp_reg = PCA9450_REG_BUCK2CTRL,
 261                        .ramp_mask = BUCK2_RAMP_MASK,
 262                        .ramp_delay_table = pca9450_dvs_buck_ramp_table,
 263                        .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
 264                        .owner = THIS_MODULE,
 265                        .of_parse_cb = pca9450_set_dvs_levels,
 266                },
 267                .dvs = {
 268                        .run_reg = PCA9450_REG_BUCK2OUT_DVS0,
 269                        .run_mask = BUCK2OUT_DVS0_MASK,
 270                        .standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
 271                        .standby_mask = BUCK2OUT_DVS1_MASK,
 272                },
 273        },
 274        {
 275                .desc = {
 276                        .name = "buck3",
 277                        .of_match = of_match_ptr("BUCK3"),
 278                        .regulators_node = of_match_ptr("regulators"),
 279                        .id = PCA9450_BUCK3,
 280                        .ops = &pca9450_dvs_buck_regulator_ops,
 281                        .type = REGULATOR_VOLTAGE,
 282                        .n_voltages = PCA9450_BUCK3_VOLTAGE_NUM,
 283                        .linear_ranges = pca9450_dvs_buck_volts,
 284                        .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
 285                        .vsel_reg = PCA9450_REG_BUCK3OUT_DVS0,
 286                        .vsel_mask = BUCK3OUT_DVS0_MASK,
 287                        .enable_reg = PCA9450_REG_BUCK3CTRL,
 288                        .enable_mask = BUCK3_ENMODE_MASK,
 289                        .ramp_reg = PCA9450_REG_BUCK3CTRL,
 290                        .ramp_mask = BUCK3_RAMP_MASK,
 291                        .ramp_delay_table = pca9450_dvs_buck_ramp_table,
 292                        .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
 293                        .owner = THIS_MODULE,
 294                        .of_parse_cb = pca9450_set_dvs_levels,
 295                },
 296                .dvs = {
 297                        .run_reg = PCA9450_REG_BUCK3OUT_DVS0,
 298                        .run_mask = BUCK3OUT_DVS0_MASK,
 299                        .standby_reg = PCA9450_REG_BUCK3OUT_DVS1,
 300                        .standby_mask = BUCK3OUT_DVS1_MASK,
 301                },
 302        },
 303        {
 304                .desc = {
 305                        .name = "buck4",
 306                        .of_match = of_match_ptr("BUCK4"),
 307                        .regulators_node = of_match_ptr("regulators"),
 308                        .id = PCA9450_BUCK4,
 309                        .ops = &pca9450_buck_regulator_ops,
 310                        .type = REGULATOR_VOLTAGE,
 311                        .n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
 312                        .linear_ranges = pca9450_buck_volts,
 313                        .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
 314                        .vsel_reg = PCA9450_REG_BUCK4OUT,
 315                        .vsel_mask = BUCK4OUT_MASK,
 316                        .enable_reg = PCA9450_REG_BUCK4CTRL,
 317                        .enable_mask = BUCK4_ENMODE_MASK,
 318                        .owner = THIS_MODULE,
 319                },
 320        },
 321        {
 322                .desc = {
 323                        .name = "buck5",
 324                        .of_match = of_match_ptr("BUCK5"),
 325                        .regulators_node = of_match_ptr("regulators"),
 326                        .id = PCA9450_BUCK5,
 327                        .ops = &pca9450_buck_regulator_ops,
 328                        .type = REGULATOR_VOLTAGE,
 329                        .n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
 330                        .linear_ranges = pca9450_buck_volts,
 331                        .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
 332                        .vsel_reg = PCA9450_REG_BUCK5OUT,
 333                        .vsel_mask = BUCK5OUT_MASK,
 334                        .enable_reg = PCA9450_REG_BUCK5CTRL,
 335                        .enable_mask = BUCK5_ENMODE_MASK,
 336                        .owner = THIS_MODULE,
 337                },
 338        },
 339        {
 340                .desc = {
 341                        .name = "buck6",
 342                        .of_match = of_match_ptr("BUCK6"),
 343                        .regulators_node = of_match_ptr("regulators"),
 344                        .id = PCA9450_BUCK6,
 345                        .ops = &pca9450_buck_regulator_ops,
 346                        .type = REGULATOR_VOLTAGE,
 347                        .n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
 348                        .linear_ranges = pca9450_buck_volts,
 349                        .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
 350                        .vsel_reg = PCA9450_REG_BUCK6OUT,
 351                        .vsel_mask = BUCK6OUT_MASK,
 352                        .enable_reg = PCA9450_REG_BUCK6CTRL,
 353                        .enable_mask = BUCK6_ENMODE_MASK,
 354                        .owner = THIS_MODULE,
 355                },
 356        },
 357        {
 358                .desc = {
 359                        .name = "ldo1",
 360                        .of_match = of_match_ptr("LDO1"),
 361                        .regulators_node = of_match_ptr("regulators"),
 362                        .id = PCA9450_LDO1,
 363                        .ops = &pca9450_ldo_regulator_ops,
 364                        .type = REGULATOR_VOLTAGE,
 365                        .n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
 366                        .linear_ranges = pca9450_ldo1_volts,
 367                        .n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
 368                        .vsel_reg = PCA9450_REG_LDO1CTRL,
 369                        .vsel_mask = LDO1OUT_MASK,
 370                        .enable_reg = PCA9450_REG_LDO1CTRL,
 371                        .enable_mask = LDO1_EN_MASK,
 372                        .owner = THIS_MODULE,
 373                },
 374        },
 375        {
 376                .desc = {
 377                        .name = "ldo2",
 378                        .of_match = of_match_ptr("LDO2"),
 379                        .regulators_node = of_match_ptr("regulators"),
 380                        .id = PCA9450_LDO2,
 381                        .ops = &pca9450_ldo_regulator_ops,
 382                        .type = REGULATOR_VOLTAGE,
 383                        .n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
 384                        .linear_ranges = pca9450_ldo2_volts,
 385                        .n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
 386                        .vsel_reg = PCA9450_REG_LDO2CTRL,
 387                        .vsel_mask = LDO2OUT_MASK,
 388                        .enable_reg = PCA9450_REG_LDO2CTRL,
 389                        .enable_mask = LDO2_EN_MASK,
 390                        .owner = THIS_MODULE,
 391                },
 392        },
 393        {
 394                .desc = {
 395                        .name = "ldo3",
 396                        .of_match = of_match_ptr("LDO3"),
 397                        .regulators_node = of_match_ptr("regulators"),
 398                        .id = PCA9450_LDO3,
 399                        .ops = &pca9450_ldo_regulator_ops,
 400                        .type = REGULATOR_VOLTAGE,
 401                        .n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
 402                        .linear_ranges = pca9450_ldo34_volts,
 403                        .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
 404                        .vsel_reg = PCA9450_REG_LDO3CTRL,
 405                        .vsel_mask = LDO3OUT_MASK,
 406                        .enable_reg = PCA9450_REG_LDO3CTRL,
 407                        .enable_mask = LDO3_EN_MASK,
 408                        .owner = THIS_MODULE,
 409                },
 410        },
 411        {
 412                .desc = {
 413                        .name = "ldo4",
 414                        .of_match = of_match_ptr("LDO4"),
 415                        .regulators_node = of_match_ptr("regulators"),
 416                        .id = PCA9450_LDO4,
 417                        .ops = &pca9450_ldo_regulator_ops,
 418                        .type = REGULATOR_VOLTAGE,
 419                        .n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
 420                        .linear_ranges = pca9450_ldo34_volts,
 421                        .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
 422                        .vsel_reg = PCA9450_REG_LDO4CTRL,
 423                        .vsel_mask = LDO4OUT_MASK,
 424                        .enable_reg = PCA9450_REG_LDO4CTRL,
 425                        .enable_mask = LDO4_EN_MASK,
 426                        .owner = THIS_MODULE,
 427                },
 428        },
 429        {
 430                .desc = {
 431                        .name = "ldo5",
 432                        .of_match = of_match_ptr("LDO5"),
 433                        .regulators_node = of_match_ptr("regulators"),
 434                        .id = PCA9450_LDO5,
 435                        .ops = &pca9450_ldo_regulator_ops,
 436                        .type = REGULATOR_VOLTAGE,
 437                        .n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
 438                        .linear_ranges = pca9450_ldo5_volts,
 439                        .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
 440                        .vsel_reg = PCA9450_REG_LDO5CTRL_H,
 441                        .vsel_mask = LDO5HOUT_MASK,
 442                        .enable_reg = PCA9450_REG_LDO5CTRL_H,
 443                        .enable_mask = LDO5H_EN_MASK,
 444                        .owner = THIS_MODULE,
 445                },
 446        },
 447};
 448
 449/*
 450 * Buck3 removed on PCA9450B and connected with Buck1 internal for dual phase
 451 * on PCA9450C as no Buck3.
 452 */
 453static const struct pca9450_regulator_desc pca9450bc_regulators[] = {
 454        {
 455                .desc = {
 456                        .name = "buck1",
 457                        .of_match = of_match_ptr("BUCK1"),
 458                        .regulators_node = of_match_ptr("regulators"),
 459                        .id = PCA9450_BUCK1,
 460                        .ops = &pca9450_dvs_buck_regulator_ops,
 461                        .type = REGULATOR_VOLTAGE,
 462                        .n_voltages = PCA9450_BUCK1_VOLTAGE_NUM,
 463                        .linear_ranges = pca9450_dvs_buck_volts,
 464                        .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
 465                        .vsel_reg = PCA9450_REG_BUCK1OUT_DVS0,
 466                        .vsel_mask = BUCK1OUT_DVS0_MASK,
 467                        .enable_reg = PCA9450_REG_BUCK1CTRL,
 468                        .enable_mask = BUCK1_ENMODE_MASK,
 469                        .ramp_reg = PCA9450_REG_BUCK1CTRL,
 470                        .ramp_mask = BUCK1_RAMP_MASK,
 471                        .ramp_delay_table = pca9450_dvs_buck_ramp_table,
 472                        .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
 473                        .owner = THIS_MODULE,
 474                        .of_parse_cb = pca9450_set_dvs_levels,
 475                },
 476                .dvs = {
 477                        .run_reg = PCA9450_REG_BUCK1OUT_DVS0,
 478                        .run_mask = BUCK1OUT_DVS0_MASK,
 479                        .standby_reg = PCA9450_REG_BUCK1OUT_DVS1,
 480                        .standby_mask = BUCK1OUT_DVS1_MASK,
 481                },
 482        },
 483        {
 484                .desc = {
 485                        .name = "buck2",
 486                        .of_match = of_match_ptr("BUCK2"),
 487                        .regulators_node = of_match_ptr("regulators"),
 488                        .id = PCA9450_BUCK2,
 489                        .ops = &pca9450_dvs_buck_regulator_ops,
 490                        .type = REGULATOR_VOLTAGE,
 491                        .n_voltages = PCA9450_BUCK2_VOLTAGE_NUM,
 492                        .linear_ranges = pca9450_dvs_buck_volts,
 493                        .n_linear_ranges = ARRAY_SIZE(pca9450_dvs_buck_volts),
 494                        .vsel_reg = PCA9450_REG_BUCK2OUT_DVS0,
 495                        .vsel_mask = BUCK2OUT_DVS0_MASK,
 496                        .enable_reg = PCA9450_REG_BUCK2CTRL,
 497                        .enable_mask = BUCK1_ENMODE_MASK,
 498                        .ramp_reg = PCA9450_REG_BUCK2CTRL,
 499                        .ramp_mask = BUCK2_RAMP_MASK,
 500                        .ramp_delay_table = pca9450_dvs_buck_ramp_table,
 501                        .n_ramp_values = ARRAY_SIZE(pca9450_dvs_buck_ramp_table),
 502                        .owner = THIS_MODULE,
 503                        .of_parse_cb = pca9450_set_dvs_levels,
 504                },
 505                .dvs = {
 506                        .run_reg = PCA9450_REG_BUCK2OUT_DVS0,
 507                        .run_mask = BUCK2OUT_DVS0_MASK,
 508                        .standby_reg = PCA9450_REG_BUCK2OUT_DVS1,
 509                        .standby_mask = BUCK2OUT_DVS1_MASK,
 510                },
 511        },
 512        {
 513                .desc = {
 514                        .name = "buck4",
 515                        .of_match = of_match_ptr("BUCK4"),
 516                        .regulators_node = of_match_ptr("regulators"),
 517                        .id = PCA9450_BUCK4,
 518                        .ops = &pca9450_buck_regulator_ops,
 519                        .type = REGULATOR_VOLTAGE,
 520                        .n_voltages = PCA9450_BUCK4_VOLTAGE_NUM,
 521                        .linear_ranges = pca9450_buck_volts,
 522                        .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
 523                        .vsel_reg = PCA9450_REG_BUCK4OUT,
 524                        .vsel_mask = BUCK4OUT_MASK,
 525                        .enable_reg = PCA9450_REG_BUCK4CTRL,
 526                        .enable_mask = BUCK4_ENMODE_MASK,
 527                        .owner = THIS_MODULE,
 528                },
 529        },
 530        {
 531                .desc = {
 532                        .name = "buck5",
 533                        .of_match = of_match_ptr("BUCK5"),
 534                        .regulators_node = of_match_ptr("regulators"),
 535                        .id = PCA9450_BUCK5,
 536                        .ops = &pca9450_buck_regulator_ops,
 537                        .type = REGULATOR_VOLTAGE,
 538                        .n_voltages = PCA9450_BUCK5_VOLTAGE_NUM,
 539                        .linear_ranges = pca9450_buck_volts,
 540                        .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
 541                        .vsel_reg = PCA9450_REG_BUCK5OUT,
 542                        .vsel_mask = BUCK5OUT_MASK,
 543                        .enable_reg = PCA9450_REG_BUCK5CTRL,
 544                        .enable_mask = BUCK5_ENMODE_MASK,
 545                        .owner = THIS_MODULE,
 546                },
 547        },
 548        {
 549                .desc = {
 550                        .name = "buck6",
 551                        .of_match = of_match_ptr("BUCK6"),
 552                        .regulators_node = of_match_ptr("regulators"),
 553                        .id = PCA9450_BUCK6,
 554                        .ops = &pca9450_buck_regulator_ops,
 555                        .type = REGULATOR_VOLTAGE,
 556                        .n_voltages = PCA9450_BUCK6_VOLTAGE_NUM,
 557                        .linear_ranges = pca9450_buck_volts,
 558                        .n_linear_ranges = ARRAY_SIZE(pca9450_buck_volts),
 559                        .vsel_reg = PCA9450_REG_BUCK6OUT,
 560                        .vsel_mask = BUCK6OUT_MASK,
 561                        .enable_reg = PCA9450_REG_BUCK6CTRL,
 562                        .enable_mask = BUCK6_ENMODE_MASK,
 563                        .owner = THIS_MODULE,
 564                },
 565        },
 566        {
 567                .desc = {
 568                        .name = "ldo1",
 569                        .of_match = of_match_ptr("LDO1"),
 570                        .regulators_node = of_match_ptr("regulators"),
 571                        .id = PCA9450_LDO1,
 572                        .ops = &pca9450_ldo_regulator_ops,
 573                        .type = REGULATOR_VOLTAGE,
 574                        .n_voltages = PCA9450_LDO1_VOLTAGE_NUM,
 575                        .linear_ranges = pca9450_ldo1_volts,
 576                        .n_linear_ranges = ARRAY_SIZE(pca9450_ldo1_volts),
 577                        .vsel_reg = PCA9450_REG_LDO1CTRL,
 578                        .vsel_mask = LDO1OUT_MASK,
 579                        .enable_reg = PCA9450_REG_LDO1CTRL,
 580                        .enable_mask = LDO1_EN_MASK,
 581                        .owner = THIS_MODULE,
 582                },
 583        },
 584        {
 585                .desc = {
 586                        .name = "ldo2",
 587                        .of_match = of_match_ptr("LDO2"),
 588                        .regulators_node = of_match_ptr("regulators"),
 589                        .id = PCA9450_LDO2,
 590                        .ops = &pca9450_ldo_regulator_ops,
 591                        .type = REGULATOR_VOLTAGE,
 592                        .n_voltages = PCA9450_LDO2_VOLTAGE_NUM,
 593                        .linear_ranges = pca9450_ldo2_volts,
 594                        .n_linear_ranges = ARRAY_SIZE(pca9450_ldo2_volts),
 595                        .vsel_reg = PCA9450_REG_LDO2CTRL,
 596                        .vsel_mask = LDO2OUT_MASK,
 597                        .enable_reg = PCA9450_REG_LDO2CTRL,
 598                        .enable_mask = LDO2_EN_MASK,
 599                        .owner = THIS_MODULE,
 600                },
 601        },
 602        {
 603                .desc = {
 604                        .name = "ldo3",
 605                        .of_match = of_match_ptr("LDO3"),
 606                        .regulators_node = of_match_ptr("regulators"),
 607                        .id = PCA9450_LDO3,
 608                        .ops = &pca9450_ldo_regulator_ops,
 609                        .type = REGULATOR_VOLTAGE,
 610                        .n_voltages = PCA9450_LDO3_VOLTAGE_NUM,
 611                        .linear_ranges = pca9450_ldo34_volts,
 612                        .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
 613                        .vsel_reg = PCA9450_REG_LDO3CTRL,
 614                        .vsel_mask = LDO3OUT_MASK,
 615                        .enable_reg = PCA9450_REG_LDO3CTRL,
 616                        .enable_mask = LDO3_EN_MASK,
 617                        .owner = THIS_MODULE,
 618                },
 619        },
 620        {
 621                .desc = {
 622                        .name = "ldo4",
 623                        .of_match = of_match_ptr("LDO4"),
 624                        .regulators_node = of_match_ptr("regulators"),
 625                        .id = PCA9450_LDO4,
 626                        .ops = &pca9450_ldo_regulator_ops,
 627                        .type = REGULATOR_VOLTAGE,
 628                        .n_voltages = PCA9450_LDO4_VOLTAGE_NUM,
 629                        .linear_ranges = pca9450_ldo34_volts,
 630                        .n_linear_ranges = ARRAY_SIZE(pca9450_ldo34_volts),
 631                        .vsel_reg = PCA9450_REG_LDO4CTRL,
 632                        .vsel_mask = LDO4OUT_MASK,
 633                        .enable_reg = PCA9450_REG_LDO4CTRL,
 634                        .enable_mask = LDO4_EN_MASK,
 635                        .owner = THIS_MODULE,
 636                },
 637        },
 638        {
 639                .desc = {
 640                        .name = "ldo5",
 641                        .of_match = of_match_ptr("LDO5"),
 642                        .regulators_node = of_match_ptr("regulators"),
 643                        .id = PCA9450_LDO5,
 644                        .ops = &pca9450_ldo_regulator_ops,
 645                        .type = REGULATOR_VOLTAGE,
 646                        .n_voltages = PCA9450_LDO5_VOLTAGE_NUM,
 647                        .linear_ranges = pca9450_ldo5_volts,
 648                        .n_linear_ranges = ARRAY_SIZE(pca9450_ldo5_volts),
 649                        .vsel_reg = PCA9450_REG_LDO5CTRL_H,
 650                        .vsel_mask = LDO5HOUT_MASK,
 651                        .enable_reg = PCA9450_REG_LDO5CTRL_H,
 652                        .enable_mask = LDO5H_EN_MASK,
 653                        .owner = THIS_MODULE,
 654                },
 655        },
 656};
 657
 658static irqreturn_t pca9450_irq_handler(int irq, void *data)
 659{
 660        struct pca9450 *pca9450 = data;
 661        struct regmap *regmap = pca9450->regmap;
 662        unsigned int status;
 663        int ret;
 664
 665        ret = regmap_read(regmap, PCA9450_REG_INT1, &status);
 666        if (ret < 0) {
 667                dev_err(pca9450->dev,
 668                        "Failed to read INT1(%d)\n", ret);
 669                return IRQ_NONE;
 670        }
 671
 672        if (status & IRQ_PWRON)
 673                dev_warn(pca9450->dev, "PWRON interrupt.\n");
 674
 675        if (status & IRQ_WDOGB)
 676                dev_warn(pca9450->dev, "WDOGB interrupt.\n");
 677
 678        if (status & IRQ_VR_FLT1)
 679                dev_warn(pca9450->dev, "VRFLT1 interrupt.\n");
 680
 681        if (status & IRQ_VR_FLT2)
 682                dev_warn(pca9450->dev, "VRFLT2 interrupt.\n");
 683
 684        if (status & IRQ_LOWVSYS)
 685                dev_warn(pca9450->dev, "LOWVSYS interrupt.\n");
 686
 687        if (status & IRQ_THERM_105)
 688                dev_warn(pca9450->dev, "IRQ_THERM_105 interrupt.\n");
 689
 690        if (status & IRQ_THERM_125)
 691                dev_warn(pca9450->dev, "IRQ_THERM_125 interrupt.\n");
 692
 693        return IRQ_HANDLED;
 694}
 695
 696static int pca9450_i2c_probe(struct i2c_client *i2c,
 697                             const struct i2c_device_id *id)
 698{
 699        enum pca9450_chip_type type = (unsigned int)(uintptr_t)
 700                                      of_device_get_match_data(&i2c->dev);
 701        const struct pca9450_regulator_desc     *regulator_desc;
 702        struct regulator_config config = { };
 703        struct pca9450 *pca9450;
 704        unsigned int device_id, i;
 705        int ret;
 706
 707        if (!i2c->irq) {
 708                dev_err(&i2c->dev, "No IRQ configured?\n");
 709                return -EINVAL;
 710        }
 711
 712        pca9450 = devm_kzalloc(&i2c->dev, sizeof(struct pca9450), GFP_KERNEL);
 713        if (!pca9450)
 714                return -ENOMEM;
 715
 716        switch (type) {
 717        case PCA9450_TYPE_PCA9450A:
 718                regulator_desc = pca9450a_regulators;
 719                pca9450->rcnt = ARRAY_SIZE(pca9450a_regulators);
 720                break;
 721        case PCA9450_TYPE_PCA9450BC:
 722                regulator_desc = pca9450bc_regulators;
 723                pca9450->rcnt = ARRAY_SIZE(pca9450bc_regulators);
 724                break;
 725        default:
 726                dev_err(&i2c->dev, "Unknown device type");
 727                return -EINVAL;
 728        }
 729
 730        pca9450->irq = i2c->irq;
 731        pca9450->type = type;
 732        pca9450->dev = &i2c->dev;
 733
 734        dev_set_drvdata(&i2c->dev, pca9450);
 735
 736        pca9450->regmap = devm_regmap_init_i2c(i2c,
 737                                               &pca9450_regmap_config);
 738        if (IS_ERR(pca9450->regmap)) {
 739                dev_err(&i2c->dev, "regmap initialization failed\n");
 740                return PTR_ERR(pca9450->regmap);
 741        }
 742
 743        ret = regmap_read(pca9450->regmap, PCA9450_REG_DEV_ID, &device_id);
 744        if (ret) {
 745                dev_err(&i2c->dev, "Read device id error\n");
 746                return ret;
 747        }
 748
 749        /* Check your board and dts for match the right pmic */
 750        if (((device_id >> 4) != 0x1 && type == PCA9450_TYPE_PCA9450A) ||
 751            ((device_id >> 4) != 0x3 && type == PCA9450_TYPE_PCA9450BC)) {
 752                dev_err(&i2c->dev, "Device id(%x) mismatched\n",
 753                        device_id >> 4);
 754                return -EINVAL;
 755        }
 756
 757        for (i = 0; i < pca9450->rcnt; i++) {
 758                const struct regulator_desc *desc;
 759                struct regulator_dev *rdev;
 760                const struct pca9450_regulator_desc *r;
 761
 762                r = &regulator_desc[i];
 763                desc = &r->desc;
 764
 765                config.regmap = pca9450->regmap;
 766                config.dev = pca9450->dev;
 767
 768                rdev = devm_regulator_register(pca9450->dev, desc, &config);
 769                if (IS_ERR(rdev)) {
 770                        ret = PTR_ERR(rdev);
 771                        dev_err(pca9450->dev,
 772                                "Failed to register regulator(%s): %d\n",
 773                                desc->name, ret);
 774                        return ret;
 775                }
 776        }
 777
 778        ret = devm_request_threaded_irq(pca9450->dev, pca9450->irq, NULL,
 779                                        pca9450_irq_handler,
 780                                        (IRQF_TRIGGER_FALLING | IRQF_ONESHOT),
 781                                        "pca9450-irq", pca9450);
 782        if (ret != 0) {
 783                dev_err(pca9450->dev, "Failed to request IRQ: %d\n",
 784                        pca9450->irq);
 785                return ret;
 786        }
 787        /* Unmask all interrupt except PWRON/WDOG/RSVD */
 788        ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_INT1_MSK,
 789                                IRQ_VR_FLT1 | IRQ_VR_FLT2 | IRQ_LOWVSYS |
 790                                IRQ_THERM_105 | IRQ_THERM_125,
 791                                IRQ_PWRON | IRQ_WDOGB | IRQ_RSVD);
 792        if (ret) {
 793                dev_err(&i2c->dev, "Unmask irq error\n");
 794                return ret;
 795        }
 796
 797        /* Clear PRESET_EN bit in BUCK123_DVS to use DVS registers */
 798        ret = regmap_clear_bits(pca9450->regmap, PCA9450_REG_BUCK123_DVS,
 799                                BUCK123_PRESET_EN);
 800        if (ret) {
 801                dev_err(&i2c->dev, "Failed to clear PRESET_EN bit: %d\n", ret);
 802                return ret;
 803        }
 804
 805        /* Set reset behavior on assertion of WDOG_B signal */
 806        ret = regmap_update_bits(pca9450->regmap, PCA9450_REG_RESET_CTRL,
 807                                WDOG_B_CFG_MASK, WDOG_B_CFG_COLD_LDO12);
 808        if (ret) {
 809                dev_err(&i2c->dev, "Failed to set WDOG_B reset behavior\n");
 810                return ret;
 811        }
 812
 813        /*
 814         * The driver uses the LDO5CTRL_H register to control the LDO5 regulator.
 815         * This is only valid if the SD_VSEL input of the PMIC is high. Let's
 816         * check if the pin is available as GPIO and set it to high.
 817         */
 818        pca9450->sd_vsel_gpio = gpiod_get_optional(pca9450->dev, "sd-vsel", GPIOD_OUT_HIGH);
 819
 820        if (IS_ERR(pca9450->sd_vsel_gpio)) {
 821                dev_err(&i2c->dev, "Failed to get SD_VSEL GPIO\n");
 822                return PTR_ERR(pca9450->sd_vsel_gpio);
 823        }
 824
 825        dev_info(&i2c->dev, "%s probed.\n",
 826                type == PCA9450_TYPE_PCA9450A ? "pca9450a" : "pca9450bc");
 827
 828        return 0;
 829}
 830
 831static const struct of_device_id pca9450_of_match[] = {
 832        {
 833                .compatible = "nxp,pca9450a",
 834                .data = (void *)PCA9450_TYPE_PCA9450A,
 835        },
 836        {
 837                .compatible = "nxp,pca9450b",
 838                .data = (void *)PCA9450_TYPE_PCA9450BC,
 839        },
 840        {
 841                .compatible = "nxp,pca9450c",
 842                .data = (void *)PCA9450_TYPE_PCA9450BC,
 843        },
 844        { }
 845};
 846MODULE_DEVICE_TABLE(of, pca9450_of_match);
 847
 848static struct i2c_driver pca9450_i2c_driver = {
 849        .driver = {
 850                .name = "nxp-pca9450",
 851                .of_match_table = pca9450_of_match,
 852        },
 853        .probe = pca9450_i2c_probe,
 854};
 855
 856module_i2c_driver(pca9450_i2c_driver);
 857
 858MODULE_AUTHOR("Robin Gong <yibin.gong@nxp.com>");
 859MODULE_DESCRIPTION("NXP PCA9450 Power Management IC driver");
 860MODULE_LICENSE("GPL");
 861