root/drivers/regulator/fan53555.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. fan53555_set_suspend_voltage
  2. fan53555_set_suspend_enable
  3. fan53555_set_suspend_disable
  4. fan53555_set_mode
  5. fan53555_get_mode
  6. fan53555_set_ramp
  7. fan53526_voltages_setup_fairchild
  8. fan53555_voltages_setup_fairchild
  9. fan53555_voltages_setup_silergy
  10. fan53555_device_setup
  11. fan53555_regulator_register
  12. fan53555_parse_dt
  13. fan53555_regulator_probe

   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 
  53 enum fan53555_vendor {
  54         FAN53526_VENDOR_FAIRCHILD = 0,
  55         FAN53555_VENDOR_FAIRCHILD,
  56         FAN53555_VENDOR_SILERGY,
  57 };
  58 
  59 enum {
  60         FAN53526_CHIP_ID_01 = 1,
  61 };
  62 
  63 enum {
  64         FAN53526_CHIP_REV_08 = 8,
  65 };
  66 
  67 /* IC Type */
  68 enum {
  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 */
  79 enum {
  80         FAN53555_CHIP_REV_00 = 0x3,
  81         FAN53555_CHIP_REV_13 = 0xf,
  82 };
  83 
  84 enum {
  85         SILERGY_SYR82X = 8,
  86 };
  87 
  88 struct 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 
 110 static 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 
 131 static 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 
 139 static 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 
 147 static 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 
 165 static 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 
 180 static const int slew_rates[] = {
 181         64000,
 182         32000,
 183         16000,
 184          8000,
 185          4000,
 186          2000,
 187          1000,
 188           500,
 189 };
 190 
 191 static 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 
 212 static 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 
 229 static 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 
 257 static 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 
 300 static 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  * */
 324 static 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 
 387 static 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 
 410 static const struct regmap_config fan53555_regmap_config = {
 411         .reg_bits = 8,
 412         .val_bits = 8,
 413 };
 414 
 415 static 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 
 437 static 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 };
 453 MODULE_DEVICE_TABLE(of, fan53555_dt_ids);
 454 
 455 static 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 
 542 static 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 };
 558 MODULE_DEVICE_TABLE(i2c, fan53555_id);
 559 
 560 static 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 
 569 module_i2c_driver(fan53555_regulator_driver);
 570 
 571 MODULE_AUTHOR("Yunfan Zhang <yfzhang@marvell.com>");
 572 MODULE_DESCRIPTION("FAN53555 regulator driver");
 573 MODULE_LICENSE("GPL v2");

/* [<][>][^][v][top][bottom][index][help] */