root/drivers/regulator/pwm-regulator.c

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

DEFINITIONS

This source file includes following definitions.
  1. pwm_regulator_init_state
  2. pwm_regulator_get_voltage_sel
  3. pwm_regulator_set_voltage_sel
  4. pwm_regulator_list_voltage
  5. pwm_regulator_enable
  6. pwm_regulator_disable
  7. pwm_regulator_is_enabled
  8. pwm_regulator_get_voltage
  9. pwm_regulator_set_voltage
  10. pwm_regulator_init_table
  11. pwm_regulator_init_continuous
  12. pwm_regulator_probe

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Regulator driver for PWM Regulators
   4  *
   5  * Copyright (C) 2014 - STMicroelectronics Inc.
   6  *
   7  * Author: Lee Jones <lee.jones@linaro.org>
   8  */
   9 
  10 #include <linux/module.h>
  11 #include <linux/init.h>
  12 #include <linux/err.h>
  13 #include <linux/regulator/driver.h>
  14 #include <linux/regulator/machine.h>
  15 #include <linux/regulator/of_regulator.h>
  16 #include <linux/of.h>
  17 #include <linux/of_device.h>
  18 #include <linux/pwm.h>
  19 #include <linux/gpio/consumer.h>
  20 
  21 struct pwm_continuous_reg_data {
  22         unsigned int min_uV_dutycycle;
  23         unsigned int max_uV_dutycycle;
  24         unsigned int dutycycle_unit;
  25 };
  26 
  27 struct pwm_regulator_data {
  28         /*  Shared */
  29         struct pwm_device *pwm;
  30 
  31         /* Voltage table */
  32         struct pwm_voltages *duty_cycle_table;
  33 
  34         /* Continuous mode info */
  35         struct pwm_continuous_reg_data continuous;
  36 
  37         /* regulator descriptor */
  38         struct regulator_desc desc;
  39 
  40         int state;
  41 
  42         /* Enable GPIO */
  43         struct gpio_desc *enb_gpio;
  44 };
  45 
  46 struct pwm_voltages {
  47         unsigned int uV;
  48         unsigned int dutycycle;
  49 };
  50 
  51 /**
  52  * Voltage table call-backs
  53  */
  54 static void pwm_regulator_init_state(struct regulator_dev *rdev)
  55 {
  56         struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
  57         struct pwm_state pwm_state;
  58         unsigned int dutycycle;
  59         int i;
  60 
  61         pwm_get_state(drvdata->pwm, &pwm_state);
  62         dutycycle = pwm_get_relative_duty_cycle(&pwm_state, 100);
  63 
  64         for (i = 0; i < rdev->desc->n_voltages; i++) {
  65                 if (dutycycle == drvdata->duty_cycle_table[i].dutycycle) {
  66                         drvdata->state = i;
  67                         return;
  68                 }
  69         }
  70 }
  71 
  72 static int pwm_regulator_get_voltage_sel(struct regulator_dev *rdev)
  73 {
  74         struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
  75 
  76         if (drvdata->state < 0)
  77                 pwm_regulator_init_state(rdev);
  78 
  79         return drvdata->state;
  80 }
  81 
  82 static int pwm_regulator_set_voltage_sel(struct regulator_dev *rdev,
  83                                          unsigned selector)
  84 {
  85         struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
  86         struct pwm_state pstate;
  87         int ret;
  88 
  89         pwm_init_state(drvdata->pwm, &pstate);
  90         pwm_set_relative_duty_cycle(&pstate,
  91                         drvdata->duty_cycle_table[selector].dutycycle, 100);
  92 
  93         ret = pwm_apply_state(drvdata->pwm, &pstate);
  94         if (ret) {
  95                 dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret);
  96                 return ret;
  97         }
  98 
  99         drvdata->state = selector;
 100 
 101         return 0;
 102 }
 103 
 104 static int pwm_regulator_list_voltage(struct regulator_dev *rdev,
 105                                       unsigned selector)
 106 {
 107         struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
 108 
 109         if (selector >= rdev->desc->n_voltages)
 110                 return -EINVAL;
 111 
 112         return drvdata->duty_cycle_table[selector].uV;
 113 }
 114 
 115 static int pwm_regulator_enable(struct regulator_dev *dev)
 116 {
 117         struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
 118 
 119         gpiod_set_value_cansleep(drvdata->enb_gpio, 1);
 120 
 121         return pwm_enable(drvdata->pwm);
 122 }
 123 
 124 static int pwm_regulator_disable(struct regulator_dev *dev)
 125 {
 126         struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
 127 
 128         pwm_disable(drvdata->pwm);
 129 
 130         gpiod_set_value_cansleep(drvdata->enb_gpio, 0);
 131 
 132         return 0;
 133 }
 134 
 135 static int pwm_regulator_is_enabled(struct regulator_dev *dev)
 136 {
 137         struct pwm_regulator_data *drvdata = rdev_get_drvdata(dev);
 138 
 139         if (drvdata->enb_gpio && !gpiod_get_value_cansleep(drvdata->enb_gpio))
 140                 return false;
 141 
 142         return pwm_is_enabled(drvdata->pwm);
 143 }
 144 
 145 static int pwm_regulator_get_voltage(struct regulator_dev *rdev)
 146 {
 147         struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
 148         unsigned int min_uV_duty = drvdata->continuous.min_uV_dutycycle;
 149         unsigned int max_uV_duty = drvdata->continuous.max_uV_dutycycle;
 150         unsigned int duty_unit = drvdata->continuous.dutycycle_unit;
 151         int min_uV = rdev->constraints->min_uV;
 152         int max_uV = rdev->constraints->max_uV;
 153         int diff_uV = max_uV - min_uV;
 154         struct pwm_state pstate;
 155         unsigned int diff_duty;
 156         unsigned int voltage;
 157 
 158         pwm_get_state(drvdata->pwm, &pstate);
 159 
 160         voltage = pwm_get_relative_duty_cycle(&pstate, duty_unit);
 161 
 162         /*
 163          * The dutycycle for min_uV might be greater than the one for max_uV.
 164          * This is happening when the user needs an inversed polarity, but the
 165          * PWM device does not support inversing it in hardware.
 166          */
 167         if (max_uV_duty < min_uV_duty) {
 168                 voltage = min_uV_duty - voltage;
 169                 diff_duty = min_uV_duty - max_uV_duty;
 170         } else {
 171                 voltage = voltage - min_uV_duty;
 172                 diff_duty = max_uV_duty - min_uV_duty;
 173         }
 174 
 175         voltage = DIV_ROUND_CLOSEST_ULL((u64)voltage * diff_uV, diff_duty);
 176 
 177         return voltage + min_uV;
 178 }
 179 
 180 static int pwm_regulator_set_voltage(struct regulator_dev *rdev,
 181                                      int req_min_uV, int req_max_uV,
 182                                      unsigned int *selector)
 183 {
 184         struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev);
 185         unsigned int min_uV_duty = drvdata->continuous.min_uV_dutycycle;
 186         unsigned int max_uV_duty = drvdata->continuous.max_uV_dutycycle;
 187         unsigned int duty_unit = drvdata->continuous.dutycycle_unit;
 188         int min_uV = rdev->constraints->min_uV;
 189         int max_uV = rdev->constraints->max_uV;
 190         int diff_uV = max_uV - min_uV;
 191         struct pwm_state pstate;
 192         unsigned int diff_duty;
 193         unsigned int dutycycle;
 194         int ret;
 195 
 196         pwm_init_state(drvdata->pwm, &pstate);
 197 
 198         /*
 199          * The dutycycle for min_uV might be greater than the one for max_uV.
 200          * This is happening when the user needs an inversed polarity, but the
 201          * PWM device does not support inversing it in hardware.
 202          */
 203         if (max_uV_duty < min_uV_duty)
 204                 diff_duty = min_uV_duty - max_uV_duty;
 205         else
 206                 diff_duty = max_uV_duty - min_uV_duty;
 207 
 208         dutycycle = DIV_ROUND_CLOSEST_ULL((u64)(req_min_uV - min_uV) *
 209                                           diff_duty,
 210                                           diff_uV);
 211 
 212         if (max_uV_duty < min_uV_duty)
 213                 dutycycle = min_uV_duty - dutycycle;
 214         else
 215                 dutycycle = min_uV_duty + dutycycle;
 216 
 217         pwm_set_relative_duty_cycle(&pstate, dutycycle, duty_unit);
 218 
 219         ret = pwm_apply_state(drvdata->pwm, &pstate);
 220         if (ret) {
 221                 dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret);
 222                 return ret;
 223         }
 224 
 225         return 0;
 226 }
 227 
 228 static const struct regulator_ops pwm_regulator_voltage_table_ops = {
 229         .set_voltage_sel = pwm_regulator_set_voltage_sel,
 230         .get_voltage_sel = pwm_regulator_get_voltage_sel,
 231         .list_voltage    = pwm_regulator_list_voltage,
 232         .map_voltage     = regulator_map_voltage_iterate,
 233         .enable          = pwm_regulator_enable,
 234         .disable         = pwm_regulator_disable,
 235         .is_enabled      = pwm_regulator_is_enabled,
 236 };
 237 
 238 static const struct regulator_ops pwm_regulator_voltage_continuous_ops = {
 239         .get_voltage = pwm_regulator_get_voltage,
 240         .set_voltage = pwm_regulator_set_voltage,
 241         .enable          = pwm_regulator_enable,
 242         .disable         = pwm_regulator_disable,
 243         .is_enabled      = pwm_regulator_is_enabled,
 244 };
 245 
 246 static const struct regulator_desc pwm_regulator_desc = {
 247         .name           = "pwm-regulator",
 248         .type           = REGULATOR_VOLTAGE,
 249         .owner          = THIS_MODULE,
 250         .supply_name    = "pwm",
 251 };
 252 
 253 static int pwm_regulator_init_table(struct platform_device *pdev,
 254                                     struct pwm_regulator_data *drvdata)
 255 {
 256         struct device_node *np = pdev->dev.of_node;
 257         struct pwm_voltages *duty_cycle_table;
 258         unsigned int length = 0;
 259         int ret;
 260 
 261         of_find_property(np, "voltage-table", &length);
 262 
 263         if ((length < sizeof(*duty_cycle_table)) ||
 264             (length % sizeof(*duty_cycle_table))) {
 265                 dev_err(&pdev->dev, "voltage-table length(%d) is invalid\n",
 266                         length);
 267                 return -EINVAL;
 268         }
 269 
 270         duty_cycle_table = devm_kzalloc(&pdev->dev, length, GFP_KERNEL);
 271         if (!duty_cycle_table)
 272                 return -ENOMEM;
 273 
 274         ret = of_property_read_u32_array(np, "voltage-table",
 275                                          (u32 *)duty_cycle_table,
 276                                          length / sizeof(u32));
 277         if (ret) {
 278                 dev_err(&pdev->dev, "Failed to read voltage-table: %d\n", ret);
 279                 return ret;
 280         }
 281 
 282         drvdata->state                  = -EINVAL;
 283         drvdata->duty_cycle_table       = duty_cycle_table;
 284         drvdata->desc.ops = &pwm_regulator_voltage_table_ops;
 285         drvdata->desc.n_voltages        = length / sizeof(*duty_cycle_table);
 286 
 287         return 0;
 288 }
 289 
 290 static int pwm_regulator_init_continuous(struct platform_device *pdev,
 291                                          struct pwm_regulator_data *drvdata)
 292 {
 293         u32 dutycycle_range[2] = { 0, 100 };
 294         u32 dutycycle_unit = 100;
 295 
 296         drvdata->desc.ops = &pwm_regulator_voltage_continuous_ops;
 297         drvdata->desc.continuous_voltage_range = true;
 298 
 299         of_property_read_u32_array(pdev->dev.of_node,
 300                                    "pwm-dutycycle-range",
 301                                    dutycycle_range, 2);
 302         of_property_read_u32(pdev->dev.of_node, "pwm-dutycycle-unit",
 303                              &dutycycle_unit);
 304 
 305         if (dutycycle_range[0] > dutycycle_unit ||
 306             dutycycle_range[1] > dutycycle_unit)
 307                 return -EINVAL;
 308 
 309         drvdata->continuous.dutycycle_unit = dutycycle_unit;
 310         drvdata->continuous.min_uV_dutycycle = dutycycle_range[0];
 311         drvdata->continuous.max_uV_dutycycle = dutycycle_range[1];
 312 
 313         return 0;
 314 }
 315 
 316 static int pwm_regulator_probe(struct platform_device *pdev)
 317 {
 318         const struct regulator_init_data *init_data;
 319         struct pwm_regulator_data *drvdata;
 320         struct regulator_dev *regulator;
 321         struct regulator_config config = { };
 322         struct device_node *np = pdev->dev.of_node;
 323         enum gpiod_flags gpio_flags;
 324         int ret;
 325 
 326         if (!np) {
 327                 dev_err(&pdev->dev, "Device Tree node missing\n");
 328                 return -EINVAL;
 329         }
 330 
 331         drvdata = devm_kzalloc(&pdev->dev, sizeof(*drvdata), GFP_KERNEL);
 332         if (!drvdata)
 333                 return -ENOMEM;
 334 
 335         memcpy(&drvdata->desc, &pwm_regulator_desc, sizeof(drvdata->desc));
 336 
 337         if (of_find_property(np, "voltage-table", NULL))
 338                 ret = pwm_regulator_init_table(pdev, drvdata);
 339         else
 340                 ret = pwm_regulator_init_continuous(pdev, drvdata);
 341         if (ret)
 342                 return ret;
 343 
 344         init_data = of_get_regulator_init_data(&pdev->dev, np,
 345                                                &drvdata->desc);
 346         if (!init_data)
 347                 return -ENOMEM;
 348 
 349         config.of_node = np;
 350         config.dev = &pdev->dev;
 351         config.driver_data = drvdata;
 352         config.init_data = init_data;
 353 
 354         drvdata->pwm = devm_pwm_get(&pdev->dev, NULL);
 355         if (IS_ERR(drvdata->pwm)) {
 356                 ret = PTR_ERR(drvdata->pwm);
 357                 dev_err(&pdev->dev, "Failed to get PWM: %d\n", ret);
 358                 return ret;
 359         }
 360 
 361         if (init_data->constraints.boot_on || init_data->constraints.always_on)
 362                 gpio_flags = GPIOD_OUT_HIGH;
 363         else
 364                 gpio_flags = GPIOD_OUT_LOW;
 365         drvdata->enb_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
 366                                                     gpio_flags);
 367         if (IS_ERR(drvdata->enb_gpio)) {
 368                 ret = PTR_ERR(drvdata->enb_gpio);
 369                 dev_err(&pdev->dev, "Failed to get enable GPIO: %d\n", ret);
 370                 return ret;
 371         }
 372 
 373         ret = pwm_adjust_config(drvdata->pwm);
 374         if (ret)
 375                 return ret;
 376 
 377         regulator = devm_regulator_register(&pdev->dev,
 378                                             &drvdata->desc, &config);
 379         if (IS_ERR(regulator)) {
 380                 ret = PTR_ERR(regulator);
 381                 dev_err(&pdev->dev, "Failed to register regulator %s: %d\n",
 382                         drvdata->desc.name, ret);
 383                 return ret;
 384         }
 385 
 386         return 0;
 387 }
 388 
 389 static const struct of_device_id pwm_of_match[] = {
 390         { .compatible = "pwm-regulator" },
 391         { },
 392 };
 393 MODULE_DEVICE_TABLE(of, pwm_of_match);
 394 
 395 static struct platform_driver pwm_regulator_driver = {
 396         .driver = {
 397                 .name           = "pwm-regulator",
 398                 .of_match_table = of_match_ptr(pwm_of_match),
 399         },
 400         .probe = pwm_regulator_probe,
 401 };
 402 
 403 module_platform_driver(pwm_regulator_driver);
 404 
 405 MODULE_LICENSE("GPL");
 406 MODULE_AUTHOR("Lee Jones <lee.jones@linaro.org>");
 407 MODULE_DESCRIPTION("PWM Regulator Driver");
 408 MODULE_ALIAS("platform:pwm-regulator");

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