pwm-atmel-hlcdc.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2014 Free Electrons
  4. * Copyright (C) 2014 Atmel
  5. *
  6. * Author: Boris BREZILLON <[email protected]>
  7. */
  8. #include <linux/clk.h>
  9. #include <linux/delay.h>
  10. #include <linux/mfd/atmel-hlcdc.h>
  11. #include <linux/module.h>
  12. #include <linux/platform_device.h>
  13. #include <linux/pwm.h>
  14. #include <linux/regmap.h>
  15. #define ATMEL_HLCDC_PWMCVAL_MASK GENMASK(15, 8)
  16. #define ATMEL_HLCDC_PWMCVAL(x) (((x) << 8) & ATMEL_HLCDC_PWMCVAL_MASK)
  17. #define ATMEL_HLCDC_PWMPOL BIT(4)
  18. #define ATMEL_HLCDC_PWMPS_MASK GENMASK(2, 0)
  19. #define ATMEL_HLCDC_PWMPS_MAX 0x6
  20. #define ATMEL_HLCDC_PWMPS(x) ((x) & ATMEL_HLCDC_PWMPS_MASK)
  21. struct atmel_hlcdc_pwm_errata {
  22. bool slow_clk_erratum;
  23. bool div1_clk_erratum;
  24. };
  25. struct atmel_hlcdc_pwm {
  26. struct pwm_chip chip;
  27. struct atmel_hlcdc *hlcdc;
  28. struct clk *cur_clk;
  29. const struct atmel_hlcdc_pwm_errata *errata;
  30. };
  31. static inline struct atmel_hlcdc_pwm *to_atmel_hlcdc_pwm(struct pwm_chip *chip)
  32. {
  33. return container_of(chip, struct atmel_hlcdc_pwm, chip);
  34. }
  35. static int atmel_hlcdc_pwm_apply(struct pwm_chip *c, struct pwm_device *pwm,
  36. const struct pwm_state *state)
  37. {
  38. struct atmel_hlcdc_pwm *chip = to_atmel_hlcdc_pwm(c);
  39. struct atmel_hlcdc *hlcdc = chip->hlcdc;
  40. unsigned int status;
  41. int ret;
  42. if (state->enabled) {
  43. struct clk *new_clk = hlcdc->slow_clk;
  44. u64 pwmcval = state->duty_cycle * 256;
  45. unsigned long clk_freq;
  46. u64 clk_period_ns;
  47. u32 pwmcfg;
  48. int pres;
  49. if (!chip->errata || !chip->errata->slow_clk_erratum) {
  50. clk_freq = clk_get_rate(new_clk);
  51. if (!clk_freq)
  52. return -EINVAL;
  53. clk_period_ns = (u64)NSEC_PER_SEC * 256;
  54. do_div(clk_period_ns, clk_freq);
  55. }
  56. /* Errata: cannot use slow clk on some IP revisions */
  57. if ((chip->errata && chip->errata->slow_clk_erratum) ||
  58. clk_period_ns > state->period) {
  59. new_clk = hlcdc->sys_clk;
  60. clk_freq = clk_get_rate(new_clk);
  61. if (!clk_freq)
  62. return -EINVAL;
  63. clk_period_ns = (u64)NSEC_PER_SEC * 256;
  64. do_div(clk_period_ns, clk_freq);
  65. }
  66. for (pres = 0; pres <= ATMEL_HLCDC_PWMPS_MAX; pres++) {
  67. /* Errata: cannot divide by 1 on some IP revisions */
  68. if (!pres && chip->errata &&
  69. chip->errata->div1_clk_erratum)
  70. continue;
  71. if ((clk_period_ns << pres) >= state->period)
  72. break;
  73. }
  74. if (pres > ATMEL_HLCDC_PWMPS_MAX)
  75. return -EINVAL;
  76. pwmcfg = ATMEL_HLCDC_PWMPS(pres);
  77. if (new_clk != chip->cur_clk) {
  78. u32 gencfg = 0;
  79. int ret;
  80. ret = clk_prepare_enable(new_clk);
  81. if (ret)
  82. return ret;
  83. clk_disable_unprepare(chip->cur_clk);
  84. chip->cur_clk = new_clk;
  85. if (new_clk == hlcdc->sys_clk)
  86. gencfg = ATMEL_HLCDC_CLKPWMSEL;
  87. ret = regmap_update_bits(hlcdc->regmap,
  88. ATMEL_HLCDC_CFG(0),
  89. ATMEL_HLCDC_CLKPWMSEL,
  90. gencfg);
  91. if (ret)
  92. return ret;
  93. }
  94. do_div(pwmcval, state->period);
  95. /*
  96. * The PWM duty cycle is configurable from 0/256 to 255/256 of
  97. * the period cycle. Hence we can't set a duty cycle occupying
  98. * the whole period cycle if we're asked to.
  99. * Set it to 255 if pwmcval is greater than 256.
  100. */
  101. if (pwmcval > 255)
  102. pwmcval = 255;
  103. pwmcfg |= ATMEL_HLCDC_PWMCVAL(pwmcval);
  104. if (state->polarity == PWM_POLARITY_NORMAL)
  105. pwmcfg |= ATMEL_HLCDC_PWMPOL;
  106. ret = regmap_update_bits(hlcdc->regmap, ATMEL_HLCDC_CFG(6),
  107. ATMEL_HLCDC_PWMCVAL_MASK |
  108. ATMEL_HLCDC_PWMPS_MASK |
  109. ATMEL_HLCDC_PWMPOL,
  110. pwmcfg);
  111. if (ret)
  112. return ret;
  113. ret = regmap_write(hlcdc->regmap, ATMEL_HLCDC_EN,
  114. ATMEL_HLCDC_PWM);
  115. if (ret)
  116. return ret;
  117. ret = regmap_read_poll_timeout(hlcdc->regmap, ATMEL_HLCDC_SR,
  118. status,
  119. status & ATMEL_HLCDC_PWM,
  120. 10, 0);
  121. if (ret)
  122. return ret;
  123. } else {
  124. ret = regmap_write(hlcdc->regmap, ATMEL_HLCDC_DIS,
  125. ATMEL_HLCDC_PWM);
  126. if (ret)
  127. return ret;
  128. ret = regmap_read_poll_timeout(hlcdc->regmap, ATMEL_HLCDC_SR,
  129. status,
  130. !(status & ATMEL_HLCDC_PWM),
  131. 10, 0);
  132. if (ret)
  133. return ret;
  134. clk_disable_unprepare(chip->cur_clk);
  135. chip->cur_clk = NULL;
  136. }
  137. return 0;
  138. }
  139. static const struct pwm_ops atmel_hlcdc_pwm_ops = {
  140. .apply = atmel_hlcdc_pwm_apply,
  141. .owner = THIS_MODULE,
  142. };
  143. static const struct atmel_hlcdc_pwm_errata atmel_hlcdc_pwm_at91sam9x5_errata = {
  144. .slow_clk_erratum = true,
  145. };
  146. static const struct atmel_hlcdc_pwm_errata atmel_hlcdc_pwm_sama5d3_errata = {
  147. .div1_clk_erratum = true,
  148. };
  149. #ifdef CONFIG_PM_SLEEP
  150. static int atmel_hlcdc_pwm_suspend(struct device *dev)
  151. {
  152. struct atmel_hlcdc_pwm *chip = dev_get_drvdata(dev);
  153. /* Keep the periph clock enabled if the PWM is still running. */
  154. if (pwm_is_enabled(&chip->chip.pwms[0]))
  155. clk_disable_unprepare(chip->hlcdc->periph_clk);
  156. return 0;
  157. }
  158. static int atmel_hlcdc_pwm_resume(struct device *dev)
  159. {
  160. struct atmel_hlcdc_pwm *chip = dev_get_drvdata(dev);
  161. struct pwm_state state;
  162. int ret;
  163. pwm_get_state(&chip->chip.pwms[0], &state);
  164. /* Re-enable the periph clock it was stopped during suspend. */
  165. if (!state.enabled) {
  166. ret = clk_prepare_enable(chip->hlcdc->periph_clk);
  167. if (ret)
  168. return ret;
  169. }
  170. return atmel_hlcdc_pwm_apply(&chip->chip, &chip->chip.pwms[0], &state);
  171. }
  172. #endif
  173. static SIMPLE_DEV_PM_OPS(atmel_hlcdc_pwm_pm_ops,
  174. atmel_hlcdc_pwm_suspend, atmel_hlcdc_pwm_resume);
  175. static const struct of_device_id atmel_hlcdc_dt_ids[] = {
  176. {
  177. .compatible = "atmel,at91sam9n12-hlcdc",
  178. /* 9n12 has same errata as 9x5 HLCDC PWM */
  179. .data = &atmel_hlcdc_pwm_at91sam9x5_errata,
  180. },
  181. {
  182. .compatible = "atmel,at91sam9x5-hlcdc",
  183. .data = &atmel_hlcdc_pwm_at91sam9x5_errata,
  184. },
  185. {
  186. .compatible = "atmel,sama5d2-hlcdc",
  187. },
  188. {
  189. .compatible = "atmel,sama5d3-hlcdc",
  190. .data = &atmel_hlcdc_pwm_sama5d3_errata,
  191. },
  192. {
  193. .compatible = "atmel,sama5d4-hlcdc",
  194. .data = &atmel_hlcdc_pwm_sama5d3_errata,
  195. },
  196. { .compatible = "microchip,sam9x60-hlcdc", },
  197. { /* sentinel */ },
  198. };
  199. MODULE_DEVICE_TABLE(of, atmel_hlcdc_dt_ids);
  200. static int atmel_hlcdc_pwm_probe(struct platform_device *pdev)
  201. {
  202. const struct of_device_id *match;
  203. struct device *dev = &pdev->dev;
  204. struct atmel_hlcdc_pwm *chip;
  205. struct atmel_hlcdc *hlcdc;
  206. int ret;
  207. hlcdc = dev_get_drvdata(dev->parent);
  208. chip = devm_kzalloc(dev, sizeof(*chip), GFP_KERNEL);
  209. if (!chip)
  210. return -ENOMEM;
  211. ret = clk_prepare_enable(hlcdc->periph_clk);
  212. if (ret)
  213. return ret;
  214. match = of_match_node(atmel_hlcdc_dt_ids, dev->parent->of_node);
  215. if (match)
  216. chip->errata = match->data;
  217. chip->hlcdc = hlcdc;
  218. chip->chip.ops = &atmel_hlcdc_pwm_ops;
  219. chip->chip.dev = dev;
  220. chip->chip.npwm = 1;
  221. ret = pwmchip_add(&chip->chip);
  222. if (ret) {
  223. clk_disable_unprepare(hlcdc->periph_clk);
  224. return ret;
  225. }
  226. platform_set_drvdata(pdev, chip);
  227. return 0;
  228. }
  229. static int atmel_hlcdc_pwm_remove(struct platform_device *pdev)
  230. {
  231. struct atmel_hlcdc_pwm *chip = platform_get_drvdata(pdev);
  232. pwmchip_remove(&chip->chip);
  233. clk_disable_unprepare(chip->hlcdc->periph_clk);
  234. return 0;
  235. }
  236. static const struct of_device_id atmel_hlcdc_pwm_dt_ids[] = {
  237. { .compatible = "atmel,hlcdc-pwm" },
  238. { /* sentinel */ },
  239. };
  240. static struct platform_driver atmel_hlcdc_pwm_driver = {
  241. .driver = {
  242. .name = "atmel-hlcdc-pwm",
  243. .of_match_table = atmel_hlcdc_pwm_dt_ids,
  244. .pm = &atmel_hlcdc_pwm_pm_ops,
  245. },
  246. .probe = atmel_hlcdc_pwm_probe,
  247. .remove = atmel_hlcdc_pwm_remove,
  248. };
  249. module_platform_driver(atmel_hlcdc_pwm_driver);
  250. MODULE_ALIAS("platform:atmel-hlcdc-pwm");
  251. MODULE_AUTHOR("Boris Brezillon <[email protected]>");
  252. MODULE_DESCRIPTION("Atmel HLCDC PWM driver");
  253. MODULE_LICENSE("GPL v2");