linux/drivers/clk/clk-wm831x.c
<<
>>
Prefs
   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
  17struct 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
  25static 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
  33static 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
  45static const struct clk_ops wm831x_xtal_ops = {
  46        .is_prepared = wm831x_xtal_is_prepared,
  47        .recalc_rate = wm831x_xtal_recalc_rate,
  48};
  49
  50static const struct clk_init_data wm831x_xtal_init = {
  51        .name = "xtal",
  52        .ops = &wm831x_xtal_ops,
  53};
  54
  55static 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
  66static 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
  83static 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
 101static 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
 113static 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
 136static 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
 150static 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
 171static const char *wm831x_fll_parents[] = {
 172        "xtal",
 173        "clkin",
 174};
 175
 176static 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
 213static 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
 223static 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
 231static 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
 248static 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
 271static 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
 292static const char *wm831x_clkout_parents[] = {
 293        "fll",
 294        "xtal",
 295};
 296
 297static 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
 317static 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
 328static 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
 336static 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
 344static 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
 385static struct platform_driver wm831x_clk_driver = {
 386        .probe = wm831x_clk_probe,
 387        .driver         = {
 388                .name   = "wm831x-clk",
 389        },
 390};
 391
 392module_platform_driver(wm831x_clk_driver);
 393
 394/* Module information */
 395MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
 396MODULE_DESCRIPTION("WM831x clock driver");
 397MODULE_LICENSE("GPL");
 398MODULE_ALIAS("platform:wm831x-clk");
 399