338 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*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 0x3019#define PWMCS_EN_PWM0 BIT(0)20#define PWMCS_EN_PWM1 BIT(1)21#define PWMCS_EN_PWM2 BIT(2)22#define STMPE24XX_PWMIC0 0x3823#define STMPE24XX_PWMIC1 0x3924#define STMPE24XX_PWMIC2 0x3a25 26#define STMPE_PWM_24XX_PINBASE 2127 28struct stmpe_pwm {29 struct stmpe *stmpe;30 u8 last_duty;31};32 33static inline struct stmpe_pwm *to_stmpe_pwm(struct pwm_chip *chip)34{35 return pwmchip_get_drvdata(chip);36}37 38static int stmpe_24xx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)39{40 struct stmpe_pwm *stmpe_pwm = to_stmpe_pwm(chip);41 u8 value;42 int ret;43 44 ret = stmpe_reg_read(stmpe_pwm->stmpe, STMPE24XX_PWMCS);45 if (ret < 0) {46 dev_dbg(pwmchip_parent(chip), "error reading PWM#%u control\n",47 pwm->hwpwm);48 return ret;49 }50 51 value = ret | BIT(pwm->hwpwm);52 53 ret = stmpe_reg_write(stmpe_pwm->stmpe, STMPE24XX_PWMCS, value);54 if (ret) {55 dev_dbg(pwmchip_parent(chip), "error writing PWM#%u control\n",56 pwm->hwpwm);57 return ret;58 }59 60 return 0;61}62 63static int stmpe_24xx_pwm_disable(struct pwm_chip *chip,64 struct pwm_device *pwm)65{66 struct stmpe_pwm *stmpe_pwm = to_stmpe_pwm(chip);67 u8 value;68 int ret;69 70 ret = stmpe_reg_read(stmpe_pwm->stmpe, STMPE24XX_PWMCS);71 if (ret < 0) {72 dev_dbg(pwmchip_parent(chip), "error reading PWM#%u control\n",73 pwm->hwpwm);74 return ret;75 }76 77 value = ret & ~BIT(pwm->hwpwm);78 79 ret = stmpe_reg_write(stmpe_pwm->stmpe, STMPE24XX_PWMCS, value);80 if (ret)81 dev_dbg(pwmchip_parent(chip), "error writing PWM#%u control\n",82 pwm->hwpwm);83 return ret;84}85 86/* STMPE 24xx PWM instructions */87#define SMAX 0x007f88#define SMIN 0x00ff89#define GTS 0x000090#define LOAD BIT(14) /* Only available on 2403 */91#define RAMPUP 0x000092#define RAMPDOWN BIT(7)93#define PRESCALE_512 BIT(14)94#define STEPTIME_1 BIT(8)95#define BRANCH (BIT(15) | BIT(13))96 97static int stmpe_24xx_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,98 int duty_ns, int period_ns)99{100 struct stmpe_pwm *stmpe_pwm = to_stmpe_pwm(chip);101 unsigned int i, pin;102 u16 program[3] = {103 SMAX,104 GTS,105 GTS,106 };107 u8 offset;108 int ret;109 110 /* Make sure we are disabled */111 if (pwm_is_enabled(pwm)) {112 ret = stmpe_24xx_pwm_disable(chip, pwm);113 if (ret)114 return ret;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(pwmchip_parent(chip), "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(pwmchip_parent(chip), "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 the178 * counter from the ramp, if this is >= PWM counter the output179 * is high. With LOAD we can define how much of the cycle it180 * is on.181 *182 * Prescale = 0 -> 2 kHz -> T = 1/f = 488281.25 ns183 */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 else208 /* 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(pwmchip_parent(chip),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_dbg(pwmchip_parent(chip), "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_dbg(pwmchip_parent(chip), "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(pwmchip_parent(chip), "programmed PWM#%u, %u bytes\n", pwm->hwpwm, i);258 259 return 0;260}261 262static int stmpe_24xx_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,263 const struct pwm_state *state)264{265 int err;266 267 if (state->polarity != PWM_POLARITY_NORMAL)268 return -EINVAL;269 270 if (!state->enabled) {271 if (pwm->state.enabled)272 return stmpe_24xx_pwm_disable(chip, pwm);273 274 return 0;275 }276 277 err = stmpe_24xx_pwm_config(chip, pwm, state->duty_cycle, state->period);278 if (err)279 return err;280 281 if (!pwm->state.enabled)282 err = stmpe_24xx_pwm_enable(chip, pwm);283 284 return err;285}286 287static const struct pwm_ops stmpe_24xx_pwm_ops = {288 .apply = stmpe_24xx_pwm_apply,289};290 291static int __init stmpe_pwm_probe(struct platform_device *pdev)292{293 struct stmpe *stmpe = dev_get_drvdata(pdev->dev.parent);294 struct pwm_chip *chip;295 struct stmpe_pwm *stmpe_pwm;296 int ret;297 298 switch (stmpe->partnum) {299 case STMPE2401:300 case STMPE2403:301 break;302 case STMPE1601:303 return dev_err_probe(&pdev->dev, -ENODEV,304 "STMPE1601 not yet supported\n");305 default:306 return dev_err_probe(&pdev->dev, -ENODEV,307 "Unknown STMPE PWM\n");308 }309 310 chip = devm_pwmchip_alloc(&pdev->dev, 3, sizeof(*stmpe_pwm));311 if (IS_ERR(chip))312 return PTR_ERR(chip);313 stmpe_pwm = to_stmpe_pwm(chip);314 315 stmpe_pwm->stmpe = stmpe;316 317 chip->ops = &stmpe_24xx_pwm_ops;318 319 ret = stmpe_enable(stmpe, STMPE_BLOCK_PWM);320 if (ret)321 return ret;322 323 ret = pwmchip_add(chip);324 if (ret) {325 stmpe_disable(stmpe, STMPE_BLOCK_PWM);326 return ret;327 }328 329 return 0;330}331 332static struct platform_driver stmpe_pwm_driver = {333 .driver = {334 .name = "stmpe-pwm",335 },336};337builtin_platform_driver_probe(stmpe_pwm_driver, stmpe_pwm_probe);338