linux/drivers/regulator/fan53555.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2//
   3// FAN53555 Fairchild Digitally Programmable TinyBuck Regulator Driver.
   4//
   5// Supported Part Numbers:
   6// FAN53555UC00X/01X/03X/04X/05X
   7//
   8// Copyright (c) 2012 Marvell Technology Ltd.
   9// Yunfan Zhang <yfzhang@marvell.com>
  10
  11#include <linux/module.h>
  12#include <linux/param.h>
  13#include <linux/err.h>
  14#include <linux/platform_device.h>
  15#include <linux/regulator/driver.h>
  16#include <linux/regulator/machine.h>
  17#include <linux/regulator/of_regulator.h>
  18#include <linux/of_device.h>
  19#include <linux/i2c.h>
  20#include <linux/slab.h>
  21#include <linux/regmap.h>
  22#include <linux/regulator/fan53555.h>
  23
  24/* Voltage setting */
  25#define FAN53555_VSEL0          0x00
  26#define FAN53555_VSEL1          0x01
  27/* Control register */
  28#define FAN53555_CONTROL        0x02
  29/* IC Type */
  30#define FAN53555_ID1            0x03
  31/* IC mask version */
  32#define FAN53555_ID2            0x04
  33/* Monitor register */
  34#define FAN53555_MONITOR        0x05
  35
  36/* VSEL bit definitions */
  37#define VSEL_BUCK_EN    (1 << 7)
  38#define VSEL_MODE               (1 << 6)
  39/* Chip ID and Verison */
  40#define DIE_ID          0x0F    /* ID1 */
  41#define DIE_REV         0x0F    /* ID2 */
  42/* Control bit definitions */
  43#define CTL_OUTPUT_DISCHG       (1 << 7)
  44#define CTL_SLEW_MASK           (0x7 << 4)
  45#define CTL_SLEW_SHIFT          4
  46#define CTL_RESET                       (1 << 2)
  47#define CTL_MODE_VSEL0_MODE     BIT(0)
  48#define CTL_MODE_VSEL1_MODE     BIT(1)
  49
  50#define FAN53555_NVOLTAGES      64      /* Numbers of voltages */
  51#define FAN53526_NVOLTAGES      128
  52
  53enum fan53555_vendor {
  54        FAN53526_VENDOR_FAIRCHILD = 0,
  55        FAN53555_VENDOR_FAIRCHILD,
  56        FAN53555_VENDOR_SILERGY,
  57};
  58
  59enum {
  60        FAN53526_CHIP_ID_01 = 1,
  61};
  62
  63enum {
  64        FAN53526_CHIP_REV_08 = 8,
  65};
  66
  67/* IC Type */
  68enum {
  69        FAN53555_CHIP_ID_00 = 0,
  70        FAN53555_CHIP_ID_01,
  71        FAN53555_CHIP_ID_02,
  72        FAN53555_CHIP_ID_03,
  73        FAN53555_CHIP_ID_04,
  74        FAN53555_CHIP_ID_05,
  75        FAN53555_CHIP_ID_08 = 8,
  76};
  77
  78/* IC mask revision */
  79enum {
  80        FAN53555_CHIP_REV_00 = 0x3,
  81        FAN53555_CHIP_REV_13 = 0xf,
  82};
  83
  84enum {
  85        SILERGY_SYR82X = 8,
  86};
  87
  88struct fan53555_device_info {
  89        enum fan53555_vendor vendor;
  90        struct device *dev;
  91        struct regulator_desc desc;
  92        struct regulator_init_data *regulator;
  93        /* IC Type and Rev */
  94        int chip_id;
  95        int chip_rev;
  96        /* Voltage setting register */
  97        unsigned int vol_reg;
  98        unsigned int sleep_reg;
  99        /* Voltage range and step(linear) */
 100        unsigned int vsel_min;
 101        unsigned int vsel_step;
 102        unsigned int vsel_count;
 103        /* Mode */
 104        unsigned int mode_reg;
 105        unsigned int mode_mask;
 106        /* Sleep voltage cache */
 107        unsigned int sleep_vol_cache;
 108};
 109
 110static int fan53555_set_suspend_voltage(struct regulator_dev *rdev, int uV)
 111{
 112        struct fan53555_device_info *di = rdev_get_drvdata(rdev);
 113        int ret;
 114
 115        if (di->sleep_vol_cache == uV)
 116                return 0;
 117        ret = regulator_map_voltage_linear(rdev, uV, uV);
 118        if (ret < 0)
 119                return ret;
 120        ret = regmap_update_bits(rdev->regmap, di->sleep_reg,
 121                                 di->desc.vsel_mask, ret);
 122        if (ret < 0)
 123                return ret;
 124        /* Cache the sleep voltage setting.
 125         * Might not be the real voltage which is rounded */
 126        di->sleep_vol_cache = uV;
 127
 128        return 0;
 129}
 130
 131static int fan53555_set_suspend_enable(struct regulator_dev *rdev)
 132{
 133        struct fan53555_device_info *di = rdev_get_drvdata(rdev);
 134
 135        return regmap_update_bits(rdev->regmap, di->sleep_reg,
 136                                  VSEL_BUCK_EN, VSEL_BUCK_EN);
 137}
 138
 139static int fan53555_set_suspend_disable(struct regulator_dev *rdev)
 140{
 141        struct fan53555_device_info *di = rdev_get_drvdata(rdev);
 142
 143        return regmap_update_bits(rdev->regmap, di->sleep_reg,
 144                                  VSEL_BUCK_EN, 0);
 145}
 146
 147static int fan53555_set_mode(struct regulator_dev *rdev, unsigned int mode)
 148{
 149        struct fan53555_device_info *di = rdev_get_drvdata(rdev);
 150
 151        switch (mode) {
 152        case REGULATOR_MODE_FAST:
 153                regmap_update_bits(rdev->regmap, di->mode_reg,
 154                                   di->mode_mask, di->mode_mask);
 155                break;
 156        case REGULATOR_MODE_NORMAL:
 157                regmap_update_bits(rdev->regmap, di->vol_reg, di->mode_mask, 0);
 158                break;
 159        default:
 160                return -EINVAL;
 161        }
 162        return 0;
 163}
 164
 165static unsigned int fan53555_get_mode(struct regulator_dev *rdev)
 166{
 167        struct fan53555_device_info *di = rdev_get_drvdata(rdev);
 168        unsigned int val;
 169        int ret = 0;
 170
 171        ret = regmap_read(rdev->regmap, di->mode_reg, &val);
 172        if (ret < 0)
 173                return ret;
 174        if (val & di->mode_mask)
 175                return REGULATOR_MODE_FAST;
 176        else
 177                return REGULATOR_MODE_NORMAL;
 178}
 179
 180static const int slew_rates[] = {
 181        64000,
 182        32000,
 183        16000,
 184         8000,
 185         4000,
 186         2000,
 187         1000,
 188          500,
 189};
 190
 191static int fan53555_set_ramp(struct regulator_dev *rdev, int ramp)
 192{
 193        struct fan53555_device_info *di = rdev_get_drvdata(rdev);
 194        int regval = -1, i;
 195
 196        for (i = 0; i < ARRAY_SIZE(slew_rates); i++) {
 197                if (ramp <= slew_rates[i])
 198                        regval = i;
 199                else
 200                        break;
 201        }
 202
 203        if (regval < 0) {
 204                dev_err(di->dev, "unsupported ramp value %d\n", ramp);
 205                return -EINVAL;
 206        }
 207
 208        return regmap_update_bits(rdev->regmap, FAN53555_CONTROL,
 209                                  CTL_SLEW_MASK, regval << CTL_SLEW_SHIFT);
 210}
 211
 212static const struct regulator_ops fan53555_regulator_ops = {
 213        .set_voltage_sel = regulator_set_voltage_sel_regmap,
 214        .get_voltage_sel = regulator_get_voltage_sel_regmap,
 215        .set_voltage_time_sel = regulator_set_voltage_time_sel,
 216        .map_voltage = regulator_map_voltage_linear,
 217        .list_voltage = regulator_list_voltage_linear,
 218        .set_suspend_voltage = fan53555_set_suspend_voltage,
 219        .enable = regulator_enable_regmap,
 220        .disable = regulator_disable_regmap,
 221        .is_enabled = regulator_is_enabled_regmap,
 222        .set_mode = fan53555_set_mode,
 223        .get_mode = fan53555_get_mode,
 224        .set_ramp_delay = fan53555_set_ramp,
 225        .set_suspend_enable = fan53555_set_suspend_enable,
 226        .set_suspend_disable = fan53555_set_suspend_disable,
 227};
 228
 229static int fan53526_voltages_setup_fairchild(struct fan53555_device_info *di)
 230{
 231        /* Init voltage range and step */
 232        switch (di->chip_id) {
 233        case FAN53526_CHIP_ID_01:
 234                switch (di->chip_rev) {
 235                case FAN53526_CHIP_REV_08:
 236                        di->vsel_min = 600000;
 237                        di->vsel_step = 6250;
 238                        break;
 239                default:
 240                        dev_err(di->dev,
 241                                "Chip ID %d with rev %d not supported!\n",
 242                                di->chip_id, di->chip_rev);
 243                        return -EINVAL;
 244                }
 245                break;
 246        default:
 247                dev_err(di->dev,
 248                        "Chip ID %d not supported!\n", di->chip_id);
 249                return -EINVAL;
 250        }
 251
 252        di->vsel_count = FAN53526_NVOLTAGES;
 253
 254        return 0;
 255}
 256
 257static int fan53555_voltages_setup_fairchild(struct fan53555_device_info *di)
 258{
 259        /* Init voltage range and step */
 260        switch (di->chip_id) {
 261        case FAN53555_CHIP_ID_00:
 262                switch (di->chip_rev) {
 263                case FAN53555_CHIP_REV_00:
 264                        di->vsel_min = 600000;
 265                        di->vsel_step = 10000;
 266                        break;
 267                case FAN53555_CHIP_REV_13:
 268                        di->vsel_min = 800000;
 269                        di->vsel_step = 10000;
 270                        break;
 271                default:
 272                        dev_err(di->dev,
 273                                "Chip ID %d with rev %d not supported!\n",
 274                                di->chip_id, di->chip_rev);
 275                        return -EINVAL;
 276                }
 277                break;
 278        case FAN53555_CHIP_ID_01:
 279        case FAN53555_CHIP_ID_03:
 280        case FAN53555_CHIP_ID_05:
 281        case FAN53555_CHIP_ID_08:
 282                di->vsel_min = 600000;
 283                di->vsel_step = 10000;
 284                break;
 285        case FAN53555_CHIP_ID_04:
 286                di->vsel_min = 603000;
 287                di->vsel_step = 12826;
 288                break;
 289        default:
 290                dev_err(di->dev,
 291                        "Chip ID %d not supported!\n", di->chip_id);
 292                return -EINVAL;
 293        }
 294
 295        di->vsel_count = FAN53555_NVOLTAGES;
 296
 297        return 0;
 298}
 299
 300static int fan53555_voltages_setup_silergy(struct fan53555_device_info *di)
 301{
 302        /* Init voltage range and step */
 303        switch (di->chip_id) {
 304        case SILERGY_SYR82X:
 305                di->vsel_min = 712500;
 306                di->vsel_step = 12500;
 307                break;
 308        default:
 309                dev_err(di->dev,
 310                        "Chip ID %d not supported!\n", di->chip_id);
 311                return -EINVAL;
 312        }
 313
 314        di->vsel_count = FAN53555_NVOLTAGES;
 315
 316        return 0;
 317}
 318
 319/* For 00,01,03,05 options:
 320 * VOUT = 0.60V + NSELx * 10mV, from 0.60 to 1.23V.
 321 * For 04 option:
 322 * VOUT = 0.603V + NSELx * 12.826mV, from 0.603 to 1.411V.
 323 * */
 324static int fan53555_device_setup(struct fan53555_device_info *di,
 325                                struct fan53555_platform_data *pdata)
 326{
 327        int ret = 0;
 328
 329        /* Setup voltage control register */
 330        switch (pdata->sleep_vsel_id) {
 331        case FAN53555_VSEL_ID_0:
 332                di->sleep_reg = FAN53555_VSEL0;
 333                di->vol_reg = FAN53555_VSEL1;
 334                break;
 335        case FAN53555_VSEL_ID_1:
 336                di->sleep_reg = FAN53555_VSEL1;
 337                di->vol_reg = FAN53555_VSEL0;
 338                break;
 339        default:
 340                dev_err(di->dev, "Invalid VSEL ID!\n");
 341                return -EINVAL;
 342        }
 343
 344        /* Setup mode control register */
 345        switch (di->vendor) {
 346        case FAN53526_VENDOR_FAIRCHILD:
 347                di->mode_reg = FAN53555_CONTROL;
 348
 349                switch (pdata->sleep_vsel_id) {
 350                case FAN53555_VSEL_ID_0:
 351                        di->mode_mask = CTL_MODE_VSEL1_MODE;
 352                        break;
 353                case FAN53555_VSEL_ID_1:
 354                        di->mode_mask = CTL_MODE_VSEL0_MODE;
 355                        break;
 356                }
 357                break;
 358        case FAN53555_VENDOR_FAIRCHILD:
 359        case FAN53555_VENDOR_SILERGY:
 360                di->mode_reg = di->vol_reg;
 361                di->mode_mask = VSEL_MODE;
 362                break;
 363        default:
 364                dev_err(di->dev, "vendor %d not supported!\n", di->vendor);
 365                return -EINVAL;
 366        }
 367
 368        /* Setup voltage range */
 369        switch (di->vendor) {
 370        case FAN53526_VENDOR_FAIRCHILD:
 371                ret = fan53526_voltages_setup_fairchild(di);
 372                break;
 373        case FAN53555_VENDOR_FAIRCHILD:
 374                ret = fan53555_voltages_setup_fairchild(di);
 375                break;
 376        case FAN53555_VENDOR_SILERGY:
 377                ret = fan53555_voltages_setup_silergy(di);
 378                break;
 379        default:
 380                dev_err(di->dev, "vendor %d not supported!\n", di->vendor);
 381                return -EINVAL;
 382        }
 383
 384        return ret;
 385}
 386
 387static int fan53555_regulator_register(struct fan53555_device_info *di,
 388                        struct regulator_config *config)
 389{
 390        struct regulator_desc *rdesc = &di->desc;
 391        struct regulator_dev *rdev;
 392
 393        rdesc->name = "fan53555-reg";
 394        rdesc->supply_name = "vin";
 395        rdesc->ops = &fan53555_regulator_ops;
 396        rdesc->type = REGULATOR_VOLTAGE;
 397        rdesc->n_voltages = di->vsel_count;
 398        rdesc->enable_reg = di->vol_reg;
 399        rdesc->enable_mask = VSEL_BUCK_EN;
 400        rdesc->min_uV = di->vsel_min;
 401        rdesc->uV_step = di->vsel_step;
 402        rdesc->vsel_reg = di->vol_reg;
 403        rdesc->vsel_mask = di->vsel_count - 1;
 404        rdesc->owner = THIS_MODULE;
 405
 406        rdev = devm_regulator_register(di->dev, &di->desc, config);
 407        return PTR_ERR_OR_ZERO(rdev);
 408}
 409
 410static const struct regmap_config fan53555_regmap_config = {
 411        .reg_bits = 8,
 412        .val_bits = 8,
 413};
 414
 415static struct fan53555_platform_data *fan53555_parse_dt(struct device *dev,
 416                                              struct device_node *np,
 417                                              const struct regulator_desc *desc)
 418{
 419        struct fan53555_platform_data *pdata;
 420        int ret;
 421        u32 tmp;
 422
 423        pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
 424        if (!pdata)
 425                return NULL;
 426
 427        pdata->regulator = of_get_regulator_init_data(dev, np, desc);
 428
 429        ret = of_property_read_u32(np, "fcs,suspend-voltage-selector",
 430                                   &tmp);
 431        if (!ret)
 432                pdata->sleep_vsel_id = tmp;
 433
 434        return pdata;
 435}
 436
 437static const struct of_device_id fan53555_dt_ids[] = {
 438        {
 439                .compatible = "fcs,fan53526",
 440                .data = (void *)FAN53526_VENDOR_FAIRCHILD,
 441        }, {
 442                .compatible = "fcs,fan53555",
 443                .data = (void *)FAN53555_VENDOR_FAIRCHILD
 444        }, {
 445                .compatible = "silergy,syr827",
 446                .data = (void *)FAN53555_VENDOR_SILERGY,
 447        }, {
 448                .compatible = "silergy,syr828",
 449                .data = (void *)FAN53555_VENDOR_SILERGY,
 450        },
 451        { }
 452};
 453MODULE_DEVICE_TABLE(of, fan53555_dt_ids);
 454
 455static int fan53555_regulator_probe(struct i2c_client *client,
 456                                const struct i2c_device_id *id)
 457{
 458        struct device_node *np = client->dev.of_node;
 459        struct fan53555_device_info *di;
 460        struct fan53555_platform_data *pdata;
 461        struct regulator_config config = { };
 462        struct regmap *regmap;
 463        unsigned int val;
 464        int ret;
 465
 466        di = devm_kzalloc(&client->dev, sizeof(struct fan53555_device_info),
 467                                        GFP_KERNEL);
 468        if (!di)
 469                return -ENOMEM;
 470
 471        pdata = dev_get_platdata(&client->dev);
 472        if (!pdata)
 473                pdata = fan53555_parse_dt(&client->dev, np, &di->desc);
 474
 475        if (!pdata || !pdata->regulator) {
 476                dev_err(&client->dev, "Platform data not found!\n");
 477                return -ENODEV;
 478        }
 479
 480        di->regulator = pdata->regulator;
 481        if (client->dev.of_node) {
 482                di->vendor =
 483                        (unsigned long)of_device_get_match_data(&client->dev);
 484        } else {
 485                /* if no ramp constraint set, get the pdata ramp_delay */
 486                if (!di->regulator->constraints.ramp_delay) {
 487                        if (pdata->slew_rate >= ARRAY_SIZE(slew_rates)) {
 488                                dev_err(&client->dev, "Invalid slew_rate\n");
 489                                return -EINVAL;
 490                        }
 491
 492                        di->regulator->constraints.ramp_delay
 493                                        = slew_rates[pdata->slew_rate];
 494                }
 495
 496                di->vendor = id->driver_data;
 497        }
 498
 499        regmap = devm_regmap_init_i2c(client, &fan53555_regmap_config);
 500        if (IS_ERR(regmap)) {
 501                dev_err(&client->dev, "Failed to allocate regmap!\n");
 502                return PTR_ERR(regmap);
 503        }
 504        di->dev = &client->dev;
 505        i2c_set_clientdata(client, di);
 506        /* Get chip ID */
 507        ret = regmap_read(regmap, FAN53555_ID1, &val);
 508        if (ret < 0) {
 509                dev_err(&client->dev, "Failed to get chip ID!\n");
 510                return ret;
 511        }
 512        di->chip_id = val & DIE_ID;
 513        /* Get chip revision */
 514        ret = regmap_read(regmap, FAN53555_ID2, &val);
 515        if (ret < 0) {
 516                dev_err(&client->dev, "Failed to get chip Rev!\n");
 517                return ret;
 518        }
 519        di->chip_rev = val & DIE_REV;
 520        dev_info(&client->dev, "FAN53555 Option[%d] Rev[%d] Detected!\n",
 521                                di->chip_id, di->chip_rev);
 522        /* Device init */
 523        ret = fan53555_device_setup(di, pdata);
 524        if (ret < 0) {
 525                dev_err(&client->dev, "Failed to setup device!\n");
 526                return ret;
 527        }
 528        /* Register regulator */
 529        config.dev = di->dev;
 530        config.init_data = di->regulator;
 531        config.regmap = regmap;
 532        config.driver_data = di;
 533        config.of_node = np;
 534
 535        ret = fan53555_regulator_register(di, &config);
 536        if (ret < 0)
 537                dev_err(&client->dev, "Failed to register regulator!\n");
 538        return ret;
 539
 540}
 541
 542static const struct i2c_device_id fan53555_id[] = {
 543        {
 544                .name = "fan53526",
 545                .driver_data = FAN53526_VENDOR_FAIRCHILD
 546        }, {
 547                .name = "fan53555",
 548                .driver_data = FAN53555_VENDOR_FAIRCHILD
 549        }, {
 550                .name = "syr827",
 551                .driver_data = FAN53555_VENDOR_SILERGY
 552        }, {
 553                .name = "syr828",
 554                .driver_data = FAN53555_VENDOR_SILERGY
 555        },
 556        { },
 557};
 558MODULE_DEVICE_TABLE(i2c, fan53555_id);
 559
 560static struct i2c_driver fan53555_regulator_driver = {
 561        .driver = {
 562                .name = "fan53555-regulator",
 563                .of_match_table = of_match_ptr(fan53555_dt_ids),
 564        },
 565        .probe = fan53555_regulator_probe,
 566        .id_table = fan53555_id,
 567};
 568
 569module_i2c_driver(fan53555_regulator_driver);
 570
 571MODULE_AUTHOR("Yunfan Zhang <yfzhang@marvell.com>");
 572MODULE_DESCRIPTION("FAN53555 regulator driver");
 573MODULE_LICENSE("GPL v2");
 574