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