linux/drivers/pwm/pwm-lp3943.c
<<
>>
Prefs
   1/*
   2 * TI/National Semiconductor LP3943 PWM driver
   3 *
   4 * Copyright 2013 Texas Instruments
   5 *
   6 * Author: Milo Kim <milo.kim@ti.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; version 2.
  11 */
  12
  13#include <linux/err.h>
  14#include <linux/i2c.h>
  15#include <linux/mfd/lp3943.h>
  16#include <linux/module.h>
  17#include <linux/platform_device.h>
  18#include <linux/pwm.h>
  19#include <linux/slab.h>
  20
  21#define LP3943_MAX_DUTY                 255
  22#define LP3943_MIN_PERIOD               6250
  23#define LP3943_MAX_PERIOD               1600000
  24
  25struct lp3943_pwm {
  26        struct pwm_chip chip;
  27        struct lp3943 *lp3943;
  28        struct lp3943_platform_data *pdata;
  29};
  30
  31static inline struct lp3943_pwm *to_lp3943_pwm(struct pwm_chip *_chip)
  32{
  33        return container_of(_chip, struct lp3943_pwm, chip);
  34}
  35
  36static struct lp3943_pwm_map *
  37lp3943_pwm_request_map(struct lp3943_pwm *lp3943_pwm, int hwpwm)
  38{
  39        struct lp3943_platform_data *pdata = lp3943_pwm->pdata;
  40        struct lp3943 *lp3943 = lp3943_pwm->lp3943;
  41        struct lp3943_pwm_map *pwm_map;
  42        int i, offset;
  43
  44        pwm_map = kzalloc(sizeof(*pwm_map), GFP_KERNEL);
  45        if (!pwm_map)
  46                return ERR_PTR(-ENOMEM);
  47
  48        pwm_map->output = pdata->pwms[hwpwm]->output;
  49        pwm_map->num_outputs = pdata->pwms[hwpwm]->num_outputs;
  50
  51        for (i = 0; i < pwm_map->num_outputs; i++) {
  52                offset = pwm_map->output[i];
  53
  54                /* Return an error if the pin is already assigned */
  55                if (test_and_set_bit(offset, &lp3943->pin_used)) {
  56                        kfree(pwm_map);
  57                        return ERR_PTR(-EBUSY);
  58                }
  59        }
  60
  61        return pwm_map;
  62}
  63
  64static int lp3943_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
  65{
  66        struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
  67        struct lp3943_pwm_map *pwm_map;
  68
  69        pwm_map = lp3943_pwm_request_map(lp3943_pwm, pwm->hwpwm);
  70        if (IS_ERR(pwm_map))
  71                return PTR_ERR(pwm_map);
  72
  73        return pwm_set_chip_data(pwm, pwm_map);
  74}
  75
  76static void lp3943_pwm_free_map(struct lp3943_pwm *lp3943_pwm,
  77                                struct lp3943_pwm_map *pwm_map)
  78{
  79        struct lp3943 *lp3943 = lp3943_pwm->lp3943;
  80        int i, offset;
  81
  82        for (i = 0; i < pwm_map->num_outputs; i++) {
  83                offset = pwm_map->output[i];
  84                clear_bit(offset, &lp3943->pin_used);
  85        }
  86
  87        kfree(pwm_map);
  88}
  89
  90static void lp3943_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
  91{
  92        struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
  93        struct lp3943_pwm_map *pwm_map = pwm_get_chip_data(pwm);
  94
  95        lp3943_pwm_free_map(lp3943_pwm, pwm_map);
  96}
  97
  98static int lp3943_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
  99                             int duty_ns, int period_ns)
 100{
 101        struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
 102        struct lp3943 *lp3943 = lp3943_pwm->lp3943;
 103        u8 val, reg_duty, reg_prescale;
 104        int err;
 105
 106        /*
 107         * How to configure the LP3943 PWMs
 108         *
 109         * 1) Period = 6250 ~ 1600000
 110         * 2) Prescale = period / 6250 -1
 111         * 3) Duty = input duty
 112         *
 113         * Prescale and duty are register values
 114         */
 115
 116        if (pwm->hwpwm == 0) {
 117                reg_prescale = LP3943_REG_PRESCALE0;
 118                reg_duty     = LP3943_REG_PWM0;
 119        } else {
 120                reg_prescale = LP3943_REG_PRESCALE1;
 121                reg_duty     = LP3943_REG_PWM1;
 122        }
 123
 124        period_ns = clamp(period_ns, LP3943_MIN_PERIOD, LP3943_MAX_PERIOD);
 125        val       = (u8)(period_ns / LP3943_MIN_PERIOD - 1);
 126
 127        err = lp3943_write_byte(lp3943, reg_prescale, val);
 128        if (err)
 129                return err;
 130
 131        val = (u8)(duty_ns * LP3943_MAX_DUTY / period_ns);
 132
 133        return lp3943_write_byte(lp3943, reg_duty, val);
 134}
 135
 136static int lp3943_pwm_set_mode(struct lp3943_pwm *lp3943_pwm,
 137                               struct lp3943_pwm_map *pwm_map,
 138                               u8 val)
 139{
 140        struct lp3943 *lp3943 = lp3943_pwm->lp3943;
 141        const struct lp3943_reg_cfg *mux = lp3943->mux_cfg;
 142        int i, index, err;
 143
 144        for (i = 0; i < pwm_map->num_outputs; i++) {
 145                index = pwm_map->output[i];
 146                err = lp3943_update_bits(lp3943, mux[index].reg,
 147                                         mux[index].mask,
 148                                         val << mux[index].shift);
 149                if (err)
 150                        return err;
 151        }
 152
 153        return 0;
 154}
 155
 156static int lp3943_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
 157{
 158        struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
 159        struct lp3943_pwm_map *pwm_map = pwm_get_chip_data(pwm);
 160        u8 val;
 161
 162        if (pwm->hwpwm == 0)
 163                val = LP3943_DIM_PWM0;
 164        else
 165                val = LP3943_DIM_PWM1;
 166
 167        /*
 168         * Each PWM generator is set to control any of outputs of LP3943.
 169         * To enable/disable the PWM, these output pins should be configured.
 170         */
 171
 172        return lp3943_pwm_set_mode(lp3943_pwm, pwm_map, val);
 173}
 174
 175static void lp3943_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
 176{
 177        struct lp3943_pwm *lp3943_pwm = to_lp3943_pwm(chip);
 178        struct lp3943_pwm_map *pwm_map = pwm_get_chip_data(pwm);
 179
 180        /*
 181         * LP3943 outputs are open-drain, so the pin should be configured
 182         * when the PWM is disabled.
 183         */
 184
 185        lp3943_pwm_set_mode(lp3943_pwm, pwm_map, LP3943_GPIO_OUT_HIGH);
 186}
 187
 188static const struct pwm_ops lp3943_pwm_ops = {
 189        .request        = lp3943_pwm_request,
 190        .free           = lp3943_pwm_free,
 191        .config         = lp3943_pwm_config,
 192        .enable         = lp3943_pwm_enable,
 193        .disable        = lp3943_pwm_disable,
 194        .owner          = THIS_MODULE,
 195};
 196
 197static int lp3943_pwm_parse_dt(struct device *dev,
 198                               struct lp3943_pwm *lp3943_pwm)
 199{
 200        static const char * const name[] = { "ti,pwm0", "ti,pwm1", };
 201        struct device_node *node = dev->of_node;
 202        struct lp3943_platform_data *pdata;
 203        struct lp3943_pwm_map *pwm_map;
 204        enum lp3943_pwm_output *output;
 205        int i, err, proplen, count = 0;
 206        u32 num_outputs;
 207
 208        if (!node)
 209                return -EINVAL;
 210
 211        pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
 212        if (!pdata)
 213                return -ENOMEM;
 214
 215        /*
 216         * Read the output map configuration from the device tree.
 217         * Each of the two PWM generators can drive zero or more outputs.
 218         */
 219
 220        for (i = 0; i < LP3943_NUM_PWMS; i++) {
 221                if (!of_get_property(node, name[i], &proplen))
 222                        continue;
 223
 224                num_outputs = proplen / sizeof(u32);
 225                if (num_outputs == 0)
 226                        continue;
 227
 228                output = devm_kzalloc(dev, sizeof(*output) * num_outputs,
 229                                      GFP_KERNEL);
 230                if (!output)
 231                        return -ENOMEM;
 232
 233                err = of_property_read_u32_array(node, name[i], output,
 234                                                 num_outputs);
 235                if (err)
 236                        return err;
 237
 238                pwm_map = devm_kzalloc(dev, sizeof(*pwm_map), GFP_KERNEL);
 239                if (!pwm_map)
 240                        return -ENOMEM;
 241
 242                pwm_map->output = output;
 243                pwm_map->num_outputs = num_outputs;
 244                pdata->pwms[i] = pwm_map;
 245
 246                count++;
 247        }
 248
 249        if (count == 0)
 250                return -ENODATA;
 251
 252        lp3943_pwm->pdata = pdata;
 253        return 0;
 254}
 255
 256static int lp3943_pwm_probe(struct platform_device *pdev)
 257{
 258        struct lp3943 *lp3943 = dev_get_drvdata(pdev->dev.parent);
 259        struct lp3943_pwm *lp3943_pwm;
 260        int ret;
 261
 262        lp3943_pwm = devm_kzalloc(&pdev->dev, sizeof(*lp3943_pwm), GFP_KERNEL);
 263        if (!lp3943_pwm)
 264                return -ENOMEM;
 265
 266        lp3943_pwm->pdata = lp3943->pdata;
 267        if (!lp3943_pwm->pdata) {
 268                if (IS_ENABLED(CONFIG_OF))
 269                        ret = lp3943_pwm_parse_dt(&pdev->dev, lp3943_pwm);
 270                else
 271                        ret = -ENODEV;
 272
 273                if (ret)
 274                        return ret;
 275        }
 276
 277        lp3943_pwm->lp3943 = lp3943;
 278        lp3943_pwm->chip.dev = &pdev->dev;
 279        lp3943_pwm->chip.ops = &lp3943_pwm_ops;
 280        lp3943_pwm->chip.npwm = LP3943_NUM_PWMS;
 281        lp3943_pwm->chip.can_sleep = true;
 282
 283        platform_set_drvdata(pdev, lp3943_pwm);
 284
 285        return pwmchip_add(&lp3943_pwm->chip);
 286}
 287
 288static int lp3943_pwm_remove(struct platform_device *pdev)
 289{
 290        struct lp3943_pwm *lp3943_pwm = platform_get_drvdata(pdev);
 291
 292        return pwmchip_remove(&lp3943_pwm->chip);
 293}
 294
 295#ifdef CONFIG_OF
 296static const struct of_device_id lp3943_pwm_of_match[] = {
 297        { .compatible = "ti,lp3943-pwm", },
 298        { }
 299};
 300MODULE_DEVICE_TABLE(of, lp3943_pwm_of_match);
 301#endif
 302
 303static struct platform_driver lp3943_pwm_driver = {
 304        .probe = lp3943_pwm_probe,
 305        .remove = lp3943_pwm_remove,
 306        .driver = {
 307                .name = "lp3943-pwm",
 308                .of_match_table = of_match_ptr(lp3943_pwm_of_match),
 309        },
 310};
 311module_platform_driver(lp3943_pwm_driver);
 312
 313MODULE_DESCRIPTION("LP3943 PWM driver");
 314MODULE_ALIAS("platform:lp3943-pwm");
 315MODULE_AUTHOR("Milo Kim");
 316MODULE_LICENSE("GPL");
 317