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