clk-wm831x.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. /*
  2. * WM831x clock control
  3. *
  4. * Copyright 2011-2 Wolfson Microelectronics PLC.
  5. *
  6. * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2 of the License, or (at your
  11. * option) any later version.
  12. *
  13. */
  14. #include <linux/clk-provider.h>
  15. #include <linux/delay.h>
  16. #include <linux/module.h>
  17. #include <linux/slab.h>
  18. #include <linux/platform_device.h>
  19. #include <linux/mfd/wm831x/core.h>
  20. struct wm831x_clk {
  21. struct wm831x *wm831x;
  22. struct clk_hw xtal_hw;
  23. struct clk_hw fll_hw;
  24. struct clk_hw clkout_hw;
  25. struct clk *xtal;
  26. struct clk *fll;
  27. struct clk *clkout;
  28. bool xtal_ena;
  29. };
  30. static int wm831x_xtal_is_prepared(struct clk_hw *hw)
  31. {
  32. struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
  33. xtal_hw);
  34. return clkdata->xtal_ena;
  35. }
  36. static unsigned long wm831x_xtal_recalc_rate(struct clk_hw *hw,
  37. unsigned long parent_rate)
  38. {
  39. struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
  40. xtal_hw);
  41. if (clkdata->xtal_ena)
  42. return 32768;
  43. else
  44. return 0;
  45. }
  46. static const struct clk_ops wm831x_xtal_ops = {
  47. .is_prepared = wm831x_xtal_is_prepared,
  48. .recalc_rate = wm831x_xtal_recalc_rate,
  49. };
  50. static struct clk_init_data wm831x_xtal_init = {
  51. .name = "xtal",
  52. .ops = &wm831x_xtal_ops,
  53. };
  54. static const unsigned long wm831x_fll_auto_rates[] = {
  55. 2048000,
  56. 11289600,
  57. 12000000,
  58. 12288000,
  59. 19200000,
  60. 22579600,
  61. 24000000,
  62. 24576000,
  63. };
  64. static int wm831x_fll_is_prepared(struct clk_hw *hw)
  65. {
  66. struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
  67. fll_hw);
  68. struct wm831x *wm831x = clkdata->wm831x;
  69. int ret;
  70. ret = wm831x_reg_read(wm831x, WM831X_FLL_CONTROL_1);
  71. if (ret < 0) {
  72. dev_err(wm831x->dev, "Unable to read FLL_CONTROL_1: %d\n",
  73. ret);
  74. return true;
  75. }
  76. return (ret & WM831X_FLL_ENA) != 0;
  77. }
  78. static int wm831x_fll_prepare(struct clk_hw *hw)
  79. {
  80. struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
  81. fll_hw);
  82. struct wm831x *wm831x = clkdata->wm831x;
  83. int ret;
  84. ret = wm831x_set_bits(wm831x, WM831X_FLL_CONTROL_1,
  85. WM831X_FLL_ENA, WM831X_FLL_ENA);
  86. if (ret != 0)
  87. dev_crit(wm831x->dev, "Failed to enable FLL: %d\n", ret);
  88. usleep_range(2000, 2000);
  89. return ret;
  90. }
  91. static void wm831x_fll_unprepare(struct clk_hw *hw)
  92. {
  93. struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
  94. fll_hw);
  95. struct wm831x *wm831x = clkdata->wm831x;
  96. int ret;
  97. ret = wm831x_set_bits(wm831x, WM831X_FLL_CONTROL_1, WM831X_FLL_ENA, 0);
  98. if (ret != 0)
  99. dev_crit(wm831x->dev, "Failed to disable FLL: %d\n", ret);
  100. }
  101. static unsigned long wm831x_fll_recalc_rate(struct clk_hw *hw,
  102. unsigned long parent_rate)
  103. {
  104. struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
  105. fll_hw);
  106. struct wm831x *wm831x = clkdata->wm831x;
  107. int ret;
  108. ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2);
  109. if (ret < 0) {
  110. dev_err(wm831x->dev, "Unable to read CLOCK_CONTROL_2: %d\n",
  111. ret);
  112. return 0;
  113. }
  114. if (ret & WM831X_FLL_AUTO)
  115. return wm831x_fll_auto_rates[ret & WM831X_FLL_AUTO_FREQ_MASK];
  116. dev_err(wm831x->dev, "FLL only supported in AUTO mode\n");
  117. return 0;
  118. }
  119. static long wm831x_fll_round_rate(struct clk_hw *hw, unsigned long rate,
  120. unsigned long *unused)
  121. {
  122. int best = 0;
  123. int i;
  124. for (i = 0; i < ARRAY_SIZE(wm831x_fll_auto_rates); i++)
  125. if (abs(wm831x_fll_auto_rates[i] - rate) <
  126. abs(wm831x_fll_auto_rates[best] - rate))
  127. best = i;
  128. return wm831x_fll_auto_rates[best];
  129. }
  130. static int wm831x_fll_set_rate(struct clk_hw *hw, unsigned long rate,
  131. unsigned long parent_rate)
  132. {
  133. struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
  134. fll_hw);
  135. struct wm831x *wm831x = clkdata->wm831x;
  136. int i;
  137. for (i = 0; i < ARRAY_SIZE(wm831x_fll_auto_rates); i++)
  138. if (wm831x_fll_auto_rates[i] == rate)
  139. break;
  140. if (i == ARRAY_SIZE(wm831x_fll_auto_rates))
  141. return -EINVAL;
  142. if (wm831x_fll_is_prepared(hw))
  143. return -EPERM;
  144. return wm831x_set_bits(wm831x, WM831X_CLOCK_CONTROL_2,
  145. WM831X_FLL_AUTO_FREQ_MASK, i);
  146. }
  147. static const char *wm831x_fll_parents[] = {
  148. "xtal",
  149. "clkin",
  150. };
  151. static u8 wm831x_fll_get_parent(struct clk_hw *hw)
  152. {
  153. struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
  154. fll_hw);
  155. struct wm831x *wm831x = clkdata->wm831x;
  156. int ret;
  157. /* AUTO mode is always clocked from the crystal */
  158. ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2);
  159. if (ret < 0) {
  160. dev_err(wm831x->dev, "Unable to read CLOCK_CONTROL_2: %d\n",
  161. ret);
  162. return 0;
  163. }
  164. if (ret & WM831X_FLL_AUTO)
  165. return 0;
  166. ret = wm831x_reg_read(wm831x, WM831X_FLL_CONTROL_5);
  167. if (ret < 0) {
  168. dev_err(wm831x->dev, "Unable to read FLL_CONTROL_5: %d\n",
  169. ret);
  170. return 0;
  171. }
  172. switch (ret & WM831X_FLL_CLK_SRC_MASK) {
  173. case 0:
  174. return 0;
  175. case 1:
  176. return 1;
  177. default:
  178. dev_err(wm831x->dev, "Unsupported FLL clock source %d\n",
  179. ret & WM831X_FLL_CLK_SRC_MASK);
  180. return 0;
  181. }
  182. }
  183. static const struct clk_ops wm831x_fll_ops = {
  184. .is_prepared = wm831x_fll_is_prepared,
  185. .prepare = wm831x_fll_prepare,
  186. .unprepare = wm831x_fll_unprepare,
  187. .round_rate = wm831x_fll_round_rate,
  188. .recalc_rate = wm831x_fll_recalc_rate,
  189. .set_rate = wm831x_fll_set_rate,
  190. .get_parent = wm831x_fll_get_parent,
  191. };
  192. static struct clk_init_data wm831x_fll_init = {
  193. .name = "fll",
  194. .ops = &wm831x_fll_ops,
  195. .parent_names = wm831x_fll_parents,
  196. .num_parents = ARRAY_SIZE(wm831x_fll_parents),
  197. .flags = CLK_SET_RATE_GATE,
  198. };
  199. static int wm831x_clkout_is_prepared(struct clk_hw *hw)
  200. {
  201. struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
  202. clkout_hw);
  203. struct wm831x *wm831x = clkdata->wm831x;
  204. int ret;
  205. ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_1);
  206. if (ret < 0) {
  207. dev_err(wm831x->dev, "Unable to read CLOCK_CONTROL_1: %d\n",
  208. ret);
  209. return true;
  210. }
  211. return (ret & WM831X_CLKOUT_ENA) != 0;
  212. }
  213. static int wm831x_clkout_prepare(struct clk_hw *hw)
  214. {
  215. struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
  216. clkout_hw);
  217. struct wm831x *wm831x = clkdata->wm831x;
  218. int ret;
  219. ret = wm831x_reg_unlock(wm831x);
  220. if (ret != 0) {
  221. dev_crit(wm831x->dev, "Failed to lock registers: %d\n", ret);
  222. return ret;
  223. }
  224. ret = wm831x_set_bits(wm831x, WM831X_CLOCK_CONTROL_1,
  225. WM831X_CLKOUT_ENA, WM831X_CLKOUT_ENA);
  226. if (ret != 0)
  227. dev_crit(wm831x->dev, "Failed to enable CLKOUT: %d\n", ret);
  228. wm831x_reg_lock(wm831x);
  229. return ret;
  230. }
  231. static void wm831x_clkout_unprepare(struct clk_hw *hw)
  232. {
  233. struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
  234. clkout_hw);
  235. struct wm831x *wm831x = clkdata->wm831x;
  236. int ret;
  237. ret = wm831x_reg_unlock(wm831x);
  238. if (ret != 0) {
  239. dev_crit(wm831x->dev, "Failed to lock registers: %d\n", ret);
  240. return;
  241. }
  242. ret = wm831x_set_bits(wm831x, WM831X_CLOCK_CONTROL_1,
  243. WM831X_CLKOUT_ENA, 0);
  244. if (ret != 0)
  245. dev_crit(wm831x->dev, "Failed to disable CLKOUT: %d\n", ret);
  246. wm831x_reg_lock(wm831x);
  247. }
  248. static const char *wm831x_clkout_parents[] = {
  249. "fll",
  250. "xtal",
  251. };
  252. static u8 wm831x_clkout_get_parent(struct clk_hw *hw)
  253. {
  254. struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
  255. clkout_hw);
  256. struct wm831x *wm831x = clkdata->wm831x;
  257. int ret;
  258. ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_1);
  259. if (ret < 0) {
  260. dev_err(wm831x->dev, "Unable to read CLOCK_CONTROL_1: %d\n",
  261. ret);
  262. return 0;
  263. }
  264. if (ret & WM831X_CLKOUT_SRC)
  265. return 1;
  266. else
  267. return 0;
  268. }
  269. static int wm831x_clkout_set_parent(struct clk_hw *hw, u8 parent)
  270. {
  271. struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
  272. clkout_hw);
  273. struct wm831x *wm831x = clkdata->wm831x;
  274. return wm831x_set_bits(wm831x, WM831X_CLOCK_CONTROL_1,
  275. WM831X_CLKOUT_SRC,
  276. parent << WM831X_CLKOUT_SRC_SHIFT);
  277. }
  278. static const struct clk_ops wm831x_clkout_ops = {
  279. .is_prepared = wm831x_clkout_is_prepared,
  280. .prepare = wm831x_clkout_prepare,
  281. .unprepare = wm831x_clkout_unprepare,
  282. .get_parent = wm831x_clkout_get_parent,
  283. .set_parent = wm831x_clkout_set_parent,
  284. };
  285. static struct clk_init_data wm831x_clkout_init = {
  286. .name = "clkout",
  287. .ops = &wm831x_clkout_ops,
  288. .parent_names = wm831x_clkout_parents,
  289. .num_parents = ARRAY_SIZE(wm831x_clkout_parents),
  290. .flags = CLK_SET_RATE_PARENT,
  291. };
  292. static int wm831x_clk_probe(struct platform_device *pdev)
  293. {
  294. struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
  295. struct wm831x_clk *clkdata;
  296. int ret;
  297. clkdata = devm_kzalloc(&pdev->dev, sizeof(*clkdata), GFP_KERNEL);
  298. if (!clkdata)
  299. return -ENOMEM;
  300. clkdata->wm831x = wm831x;
  301. /* XTAL_ENA can only be set via OTP/InstantConfig so just read once */
  302. ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2);
  303. if (ret < 0) {
  304. dev_err(wm831x->dev, "Unable to read CLOCK_CONTROL_2: %d\n",
  305. ret);
  306. return ret;
  307. }
  308. clkdata->xtal_ena = ret & WM831X_XTAL_ENA;
  309. clkdata->xtal_hw.init = &wm831x_xtal_init;
  310. clkdata->xtal = devm_clk_register(&pdev->dev, &clkdata->xtal_hw);
  311. if (IS_ERR(clkdata->xtal))
  312. return PTR_ERR(clkdata->xtal);
  313. clkdata->fll_hw.init = &wm831x_fll_init;
  314. clkdata->fll = devm_clk_register(&pdev->dev, &clkdata->fll_hw);
  315. if (IS_ERR(clkdata->fll))
  316. return PTR_ERR(clkdata->fll);
  317. clkdata->clkout_hw.init = &wm831x_clkout_init;
  318. clkdata->clkout = devm_clk_register(&pdev->dev, &clkdata->clkout_hw);
  319. if (IS_ERR(clkdata->clkout))
  320. return PTR_ERR(clkdata->clkout);
  321. platform_set_drvdata(pdev, clkdata);
  322. return 0;
  323. }
  324. static struct platform_driver wm831x_clk_driver = {
  325. .probe = wm831x_clk_probe,
  326. .driver = {
  327. .name = "wm831x-clk",
  328. },
  329. };
  330. module_platform_driver(wm831x_clk_driver);
  331. /* Module information */
  332. MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
  333. MODULE_DESCRIPTION("WM831x clock driver");
  334. MODULE_LICENSE("GPL");
  335. MODULE_ALIAS("platform:wm831x-clk");