1 /* 2 * STM32 Low-Power Timer PWM driver 3 * 4 * Copyright (C) STMicroelectronics 2017 5 * 6 * Author: Gerald Baeza <gerald.baeza@st.com> 7 * 8 * License terms: GNU General Public License (GPL), version 2 9 * 10 * Inspired by Gerald Baeza's pwm-stm32 driver 11 */ 12 13 #include <linux/bitfield.h> 14 #include <linux/mfd/stm32-lptimer.h> 15 #include <linux/module.h> 16 #include <linux/of.h> 17 #include <linux/platform_device.h> 18 #include <linux/pwm.h> 19 20 struct stm32_pwm_lp { 21 struct pwm_chip chip; 22 struct clk *clk; 23 struct regmap *regmap; 24 }; 25 26 static inline struct stm32_pwm_lp *to_stm32_pwm_lp(struct pwm_chip *chip) 27 { 28 return container_of(chip, struct stm32_pwm_lp, chip); 29 } 30 31 /* STM32 Low-Power Timer is preceded by a configurable power-of-2 prescaler */ 32 #define STM32_LPTIM_MAX_PRESCALER 128 33 34 static int stm32_pwm_lp_apply(struct pwm_chip *chip, struct pwm_device *pwm, 35 struct pwm_state *state) 36 { 37 struct stm32_pwm_lp *priv = to_stm32_pwm_lp(chip); 38 unsigned long long prd, div, dty; 39 struct pwm_state cstate; 40 u32 val, mask, cfgr, presc = 0; 41 bool reenable; 42 int ret; 43 44 pwm_get_state(pwm, &cstate); 45 reenable = !cstate.enabled; 46 47 if (!state->enabled) { 48 if (cstate.enabled) { 49 /* Disable LP timer */ 50 ret = regmap_write(priv->regmap, STM32_LPTIM_CR, 0); 51 if (ret) 52 return ret; 53 /* disable clock to PWM counter */ 54 clk_disable(priv->clk); 55 } 56 return 0; 57 } 58 59 /* Calculate the period and prescaler value */ 60 div = (unsigned long long)clk_get_rate(priv->clk) * state->period; 61 do_div(div, NSEC_PER_SEC); 62 prd = div; 63 while (div > STM32_LPTIM_MAX_ARR) { 64 presc++; 65 if ((1 << presc) > STM32_LPTIM_MAX_PRESCALER) { 66 dev_err(priv->chip.dev, "max prescaler exceeded\n"); 67 return -EINVAL; 68 } 69 div = prd >> presc; 70 } 71 prd = div; 72 73 /* Calculate the duty cycle */ 74 dty = prd * state->duty_cycle; 75 do_div(dty, state->period); 76 77 if (!cstate.enabled) { 78 /* enable clock to drive PWM counter */ 79 ret = clk_enable(priv->clk); 80 if (ret) 81 return ret; 82 } 83 84 ret = regmap_read(priv->regmap, STM32_LPTIM_CFGR, &cfgr); 85 if (ret) 86 goto err; 87 88 if ((FIELD_GET(STM32_LPTIM_PRESC, cfgr) != presc) || 89 (FIELD_GET(STM32_LPTIM_WAVPOL, cfgr) != state->polarity)) { 90 val = FIELD_PREP(STM32_LPTIM_PRESC, presc); 91 val |= FIELD_PREP(STM32_LPTIM_WAVPOL, state->polarity); 92 mask = STM32_LPTIM_PRESC | STM32_LPTIM_WAVPOL; 93 94 /* Must disable LP timer to modify CFGR */ 95 reenable = true; 96 ret = regmap_write(priv->regmap, STM32_LPTIM_CR, 0); 97 if (ret) 98 goto err; 99 100 ret = regmap_update_bits(priv->regmap, STM32_LPTIM_CFGR, mask, 101 val); 102 if (ret) 103 goto err; 104 } 105 106 if (reenable) { 107 /* Must (re)enable LP timer to modify CMP & ARR */ 108 ret = regmap_write(priv->regmap, STM32_LPTIM_CR, 109 STM32_LPTIM_ENABLE); 110 if (ret) 111 goto err; 112 } 113 114 ret = regmap_write(priv->regmap, STM32_LPTIM_ARR, prd - 1); 115 if (ret) 116 goto err; 117 118 ret = regmap_write(priv->regmap, STM32_LPTIM_CMP, prd - (1 + dty)); 119 if (ret) 120 goto err; 121 122 /* ensure CMP & ARR registers are properly written */ 123 ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val, 124 (val & STM32_LPTIM_CMPOK_ARROK), 125 100, 1000); 126 if (ret) { 127 dev_err(priv->chip.dev, "ARR/CMP registers write issue\n"); 128 goto err; 129 } 130 ret = regmap_write(priv->regmap, STM32_LPTIM_ICR, 131 STM32_LPTIM_CMPOKCF_ARROKCF); 132 if (ret) 133 goto err; 134 135 if (reenable) { 136 /* Start LP timer in continuous mode */ 137 ret = regmap_update_bits(priv->regmap, STM32_LPTIM_CR, 138 STM32_LPTIM_CNTSTRT, 139 STM32_LPTIM_CNTSTRT); 140 if (ret) { 141 regmap_write(priv->regmap, STM32_LPTIM_CR, 0); 142 goto err; 143 } 144 } 145 146 return 0; 147 err: 148 if (!cstate.enabled) 149 clk_disable(priv->clk); 150 151 return ret; 152 } 153 154 static void stm32_pwm_lp_get_state(struct pwm_chip *chip, 155 struct pwm_device *pwm, 156 struct pwm_state *state) 157 { 158 struct stm32_pwm_lp *priv = to_stm32_pwm_lp(chip); 159 unsigned long rate = clk_get_rate(priv->clk); 160 u32 val, presc, prd; 161 u64 tmp; 162 163 regmap_read(priv->regmap, STM32_LPTIM_CR, &val); 164 state->enabled = !!FIELD_GET(STM32_LPTIM_ENABLE, val); 165 /* Keep PWM counter clock refcount in sync with PWM initial state */ 166 if (state->enabled) 167 clk_enable(priv->clk); 168 169 regmap_read(priv->regmap, STM32_LPTIM_CFGR, &val); 170 presc = FIELD_GET(STM32_LPTIM_PRESC, val); 171 state->polarity = FIELD_GET(STM32_LPTIM_WAVPOL, val); 172 173 regmap_read(priv->regmap, STM32_LPTIM_ARR, &prd); 174 tmp = prd + 1; 175 tmp = (tmp << presc) * NSEC_PER_SEC; 176 state->period = DIV_ROUND_CLOSEST_ULL(tmp, rate); 177 178 regmap_read(priv->regmap, STM32_LPTIM_CMP, &val); 179 tmp = prd - val; 180 tmp = (tmp << presc) * NSEC_PER_SEC; 181 state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, rate); 182 } 183 184 static const struct pwm_ops stm32_pwm_lp_ops = { 185 .owner = THIS_MODULE, 186 .apply = stm32_pwm_lp_apply, 187 .get_state = stm32_pwm_lp_get_state, 188 }; 189 190 static int stm32_pwm_lp_probe(struct platform_device *pdev) 191 { 192 struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent); 193 struct stm32_pwm_lp *priv; 194 int ret; 195 196 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 197 if (!priv) 198 return -ENOMEM; 199 200 priv->regmap = ddata->regmap; 201 priv->clk = ddata->clk; 202 priv->chip.base = -1; 203 priv->chip.dev = &pdev->dev; 204 priv->chip.ops = &stm32_pwm_lp_ops; 205 priv->chip.npwm = 1; 206 207 ret = pwmchip_add(&priv->chip); 208 if (ret < 0) 209 return ret; 210 211 platform_set_drvdata(pdev, priv); 212 213 return 0; 214 } 215 216 static int stm32_pwm_lp_remove(struct platform_device *pdev) 217 { 218 struct stm32_pwm_lp *priv = platform_get_drvdata(pdev); 219 unsigned int i; 220 221 for (i = 0; i < priv->chip.npwm; i++) 222 pwm_disable(&priv->chip.pwms[i]); 223 224 return pwmchip_remove(&priv->chip); 225 } 226 227 static const struct of_device_id stm32_pwm_lp_of_match[] = { 228 { .compatible = "st,stm32-pwm-lp", }, 229 {}, 230 }; 231 MODULE_DEVICE_TABLE(of, stm32_pwm_lp_of_match); 232 233 static struct platform_driver stm32_pwm_lp_driver = { 234 .probe = stm32_pwm_lp_probe, 235 .remove = stm32_pwm_lp_remove, 236 .driver = { 237 .name = "stm32-pwm-lp", 238 .of_match_table = of_match_ptr(stm32_pwm_lp_of_match), 239 }, 240 }; 241 module_platform_driver(stm32_pwm_lp_driver); 242 243 MODULE_ALIAS("platform:stm32-pwm-lp"); 244 MODULE_DESCRIPTION("STMicroelectronics STM32 PWM LP driver"); 245 MODULE_LICENSE("GPL v2"); 246