linux/drivers/pwm/pwm-stmpe.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright (C) 2016 Linaro Ltd.
   4 *
   5 * Author: Linus Walleij <linus.walleij@linaro.org>
   6 */
   7
   8#include <linux/bitops.h>
   9#include <linux/delay.h>
  10#include <linux/err.h>
  11#include <linux/mfd/stmpe.h>
  12#include <linux/module.h>
  13#include <linux/of.h>
  14#include <linux/platform_device.h>
  15#include <linux/pwm.h>
  16#include <linux/slab.h>
  17
  18#define STMPE24XX_PWMCS         0x30
  19#define PWMCS_EN_PWM0           BIT(0)
  20#define PWMCS_EN_PWM1           BIT(1)
  21#define PWMCS_EN_PWM2           BIT(2)
  22#define STMPE24XX_PWMIC0        0x38
  23#define STMPE24XX_PWMIC1        0x39
  24#define STMPE24XX_PWMIC2        0x3a
  25
  26#define STMPE_PWM_24XX_PINBASE  21
  27
  28struct stmpe_pwm {
  29        struct stmpe *stmpe;
  30        struct pwm_chip chip;
  31        u8 last_duty;
  32};
  33
  34static inline struct stmpe_pwm *to_stmpe_pwm(struct pwm_chip *chip)
  35{
  36        return container_of(chip, struct stmpe_pwm, chip);
  37}
  38
  39static int stmpe_24xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
  40{
  41        struct stmpe_pwm *stmpe_pwm = to_stmpe_pwm(chip);
  42        u8 value;
  43        int ret;
  44
  45        ret = stmpe_reg_read(stmpe_pwm->stmpe, STMPE24XX_PWMCS);
  46        if (ret < 0) {
  47                dev_err(chip->dev, "error reading PWM#%u control\n",
  48                        pwm->hwpwm);
  49                return ret;
  50        }
  51
  52        value = ret | BIT(pwm->hwpwm);
  53
  54        ret = stmpe_reg_write(stmpe_pwm->stmpe, STMPE24XX_PWMCS, value);
  55        if (ret) {
  56                dev_err(chip->dev, "error writing PWM#%u control\n",
  57                        pwm->hwpwm);
  58                return ret;
  59        }
  60
  61        return 0;
  62}
  63
  64static void stmpe_24xx_pwm_disable(struct pwm_chip *chip,
  65                                   struct pwm_device *pwm)
  66{
  67        struct stmpe_pwm *stmpe_pwm = to_stmpe_pwm(chip);
  68        u8 value;
  69        int ret;
  70
  71        ret = stmpe_reg_read(stmpe_pwm->stmpe, STMPE24XX_PWMCS);
  72        if (ret < 0) {
  73                dev_err(chip->dev, "error reading PWM#%u control\n",
  74                        pwm->hwpwm);
  75                return;
  76        }
  77
  78        value = ret & ~BIT(pwm->hwpwm);
  79
  80        ret = stmpe_reg_write(stmpe_pwm->stmpe, STMPE24XX_PWMCS, value);
  81        if (ret) {
  82                dev_err(chip->dev, "error writing PWM#%u control\n",
  83                        pwm->hwpwm);
  84                return;
  85        }
  86}
  87
  88/* STMPE 24xx PWM instructions */
  89#define SMAX            0x007f
  90#define SMIN            0x00ff
  91#define GTS             0x0000
  92#define LOAD            BIT(14) /* Only available on 2403 */
  93#define RAMPUP          0x0000
  94#define RAMPDOWN        BIT(7)
  95#define PRESCALE_512    BIT(14)
  96#define STEPTIME_1      BIT(8)
  97#define BRANCH          (BIT(15) | BIT(13))
  98
  99static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
 100                                 int duty_ns, int period_ns)
 101{
 102        struct stmpe_pwm *stmpe_pwm = to_stmpe_pwm(chip);
 103        unsigned int i, pin;
 104        u16 program[3] = {
 105                SMAX,
 106                GTS,
 107                GTS,
 108        };
 109        u8 offset;
 110        int ret;
 111
 112        /* Make sure we are disabled */
 113        if (pwm_is_enabled(pwm)) {
 114                stmpe_24xx_pwm_disable(chip, pwm);
 115        } else {
 116                /* Connect the PWM to the pin */
 117                pin = pwm->hwpwm;
 118
 119                /* On STMPE2401 and 2403 pins 21,22,23 are used */
 120                if (stmpe_pwm->stmpe->partnum == STMPE2401 ||
 121                    stmpe_pwm->stmpe->partnum == STMPE2403)
 122                        pin += STMPE_PWM_24XX_PINBASE;
 123
 124                ret = stmpe_set_altfunc(stmpe_pwm->stmpe, BIT(pin),
 125                                        STMPE_BLOCK_PWM);
 126                if (ret) {
 127                        dev_err(chip->dev, "unable to connect PWM#%u to pin\n",
 128                                pwm->hwpwm);
 129                        return ret;
 130                }
 131        }
 132
 133        /* STMPE24XX */
 134        switch (pwm->hwpwm) {
 135        case 0:
 136                offset = STMPE24XX_PWMIC0;
 137                break;
 138
 139        case 1:
 140                offset = STMPE24XX_PWMIC1;
 141                break;
 142
 143        case 2:
 144                offset = STMPE24XX_PWMIC2;
 145                break;
 146
 147        default:
 148                /* Should not happen as npwm is 3 */
 149                return -ENODEV;
 150        }
 151
 152        dev_dbg(chip->dev, "PWM#%u: config duty %d ns, period %d ns\n",
 153                pwm->hwpwm, duty_ns, period_ns);
 154
 155        if (duty_ns == 0) {
 156                if (stmpe_pwm->stmpe->partnum == STMPE2401)
 157                        program[0] = SMAX; /* off all the time */
 158
 159                if (stmpe_pwm->stmpe->partnum == STMPE2403)
 160                        program[0] = LOAD | 0xff; /* LOAD 0xff */
 161
 162                stmpe_pwm->last_duty = 0x00;
 163        } else if (duty_ns == period_ns) {
 164                if (stmpe_pwm->stmpe->partnum == STMPE2401)
 165                        program[0] = SMIN; /* on all the time */
 166
 167                if (stmpe_pwm->stmpe->partnum == STMPE2403)
 168                        program[0] = LOAD | 0x00; /* LOAD 0x00 */
 169
 170                stmpe_pwm->last_duty = 0xff;
 171        } else {
 172                u8 value, last = stmpe_pwm->last_duty;
 173                unsigned long duty;
 174
 175                /*
 176                 * Counter goes from 0x00 to 0xff repeatedly at 32768 Hz,
 177                 * (means a period of 30517 ns) then this is compared to the
 178                 * counter from the ramp, if this is >= PWM counter the output
 179                 * is high. With LOAD we can define how much of the cycle it
 180                 * is on.
 181                 *
 182                 * Prescale = 0 -> 2 kHz -> T = 1/f = 488281.25 ns
 183                 */
 184
 185                /* Scale to 0..0xff */
 186                duty = duty_ns * 256;
 187                duty = DIV_ROUND_CLOSEST(duty, period_ns);
 188                value = duty;
 189
 190                if (value == last) {
 191                        /* Run the old program */
 192                        if (pwm_is_enabled(pwm))
 193                                stmpe_24xx_pwm_enable(chip, pwm);
 194
 195                        return 0;
 196                } else if (stmpe_pwm->stmpe->partnum == STMPE2403) {
 197                        /* STMPE2403 can simply set the right PWM value */
 198                        program[0] = LOAD | value;
 199                        program[1] = 0x0000;
 200                } else if (stmpe_pwm->stmpe->partnum == STMPE2401) {
 201                        /* STMPE2401 need a complex program */
 202                        u16 incdec = 0x0000;
 203
 204                        if (last < value)
 205                                /* Count up */
 206                                incdec = RAMPUP | (value - last);
 207                        else
 208                                /* Count down */
 209                                incdec = RAMPDOWN | (last - value);
 210
 211                        /* Step to desired value, smoothly */
 212                        program[0] = PRESCALE_512 | STEPTIME_1 | incdec;
 213
 214                        /* Loop eternally to 0x00 */
 215                        program[1] = BRANCH;
 216                }
 217
 218                dev_dbg(chip->dev,
 219                        "PWM#%u: value = %02x, last_duty = %02x, program=%04x,%04x,%04x\n",
 220                        pwm->hwpwm, value, last, program[0], program[1],
 221                        program[2]);
 222                stmpe_pwm->last_duty = value;
 223        }
 224
 225        /*
 226         * We can write programs of up to 64 16-bit words into this channel.
 227         */
 228        for (i = 0; i < ARRAY_SIZE(program); i++) {
 229                u8 value;
 230
 231                value = (program[i] >> 8) & 0xff;
 232
 233                ret = stmpe_reg_write(stmpe_pwm->stmpe, offset, value);
 234                if (ret) {
 235                        dev_err(chip->dev, "error writing register %02x: %d\n",
 236                                offset, ret);
 237                        return ret;
 238                }
 239
 240                value = program[i] & 0xff;
 241
 242                ret = stmpe_reg_write(stmpe_pwm->stmpe, offset, value);
 243                if (ret) {
 244                        dev_err(chip->dev, "error writing register %02x: %d\n",
 245                                offset, ret);
 246                        return ret;
 247                }
 248        }
 249
 250        /* If we were enabled, re-enable this PWM */
 251        if (pwm_is_enabled(pwm))
 252                stmpe_24xx_pwm_enable(chip, pwm);
 253
 254        /* Sleep for 200ms so we're sure it will take effect */
 255        msleep(200);
 256
 257        dev_dbg(chip->dev, "programmed PWM#%u, %u bytes\n", pwm->hwpwm, i);
 258
 259        return 0;
 260}
 261
 262static const struct pwm_ops stmpe_24xx_pwm_ops = {
 263        .config = stmpe_24xx_pwm_config,
 264        .enable = stmpe_24xx_pwm_enable,
 265        .disable = stmpe_24xx_pwm_disable,
 266        .owner = THIS_MODULE,
 267};
 268
 269static int __init stmpe_pwm_probe(struct platform_device *pdev)
 270{
 271        struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);
 272        struct stmpe_pwm *pwm;
 273        int ret;
 274
 275        pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL);
 276        if (!pwm)
 277                return -ENOMEM;
 278
 279        pwm->stmpe = stmpe;
 280        pwm->chip.dev = &pdev->dev;
 281
 282        if (stmpe->partnum == STMPE2401 || stmpe->partnum == STMPE2403) {
 283                pwm->chip.ops = &stmpe_24xx_pwm_ops;
 284                pwm->chip.npwm = 3;
 285        } else {
 286                if (stmpe->partnum == STMPE1601)
 287                        dev_err(&pdev->dev, "STMPE1601 not yet supported\n");
 288                else
 289                        dev_err(&pdev->dev, "Unknown STMPE PWM\n");
 290
 291                return -ENODEV;
 292        }
 293
 294        ret = stmpe_enable(stmpe, STMPE_BLOCK_PWM);
 295        if (ret)
 296                return ret;
 297
 298        ret = pwmchip_add(&pwm->chip);
 299        if (ret) {
 300                stmpe_disable(stmpe, STMPE_BLOCK_PWM);
 301                return ret;
 302        }
 303
 304        platform_set_drvdata(pdev, pwm);
 305
 306        return 0;
 307}
 308
 309static struct platform_driver stmpe_pwm_driver = {
 310        .driver = {
 311                .name = "stmpe-pwm",
 312        },
 313};
 314builtin_platform_driver_probe(stmpe_pwm_driver, stmpe_pwm_probe);
 315