root/drivers/clk/clk-wm831x.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. wm831x_xtal_is_prepared
  2. wm831x_xtal_recalc_rate
  3. wm831x_fll_is_prepared
  4. wm831x_fll_prepare
  5. wm831x_fll_unprepare
  6. wm831x_fll_recalc_rate
  7. wm831x_fll_round_rate
  8. wm831x_fll_set_rate
  9. wm831x_fll_get_parent
  10. wm831x_clkout_is_prepared
  11. wm831x_clkout_prepare
  12. wm831x_clkout_unprepare
  13. wm831x_clkout_get_parent
  14. wm831x_clkout_set_parent
  15. wm831x_clk_probe

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

/* [<][>][^][v][top][bottom][index][help] */