Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * WM831x clock control
0004  *
0005  * Copyright 2011-2 Wolfson Microelectronics PLC.
0006  *
0007  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
0008  */
0009 
0010 #include <linux/clk-provider.h>
0011 #include <linux/delay.h>
0012 #include <linux/module.h>
0013 #include <linux/slab.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/mfd/wm831x/core.h>
0016 
0017 struct wm831x_clk {
0018     struct wm831x *wm831x;
0019     struct clk_hw xtal_hw;
0020     struct clk_hw fll_hw;
0021     struct clk_hw clkout_hw;
0022     bool xtal_ena;
0023 };
0024 
0025 static int wm831x_xtal_is_prepared(struct clk_hw *hw)
0026 {
0027     struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
0028                           xtal_hw);
0029 
0030     return clkdata->xtal_ena;
0031 }
0032 
0033 static unsigned long wm831x_xtal_recalc_rate(struct clk_hw *hw,
0034                          unsigned long parent_rate)
0035 {
0036     struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
0037                           xtal_hw);
0038 
0039     if (clkdata->xtal_ena)
0040         return 32768;
0041     else
0042         return 0;
0043 }
0044 
0045 static const struct clk_ops wm831x_xtal_ops = {
0046     .is_prepared = wm831x_xtal_is_prepared,
0047     .recalc_rate = wm831x_xtal_recalc_rate,
0048 };
0049 
0050 static const struct clk_init_data wm831x_xtal_init = {
0051     .name = "xtal",
0052     .ops = &wm831x_xtal_ops,
0053 };
0054 
0055 static const unsigned long wm831x_fll_auto_rates[] = {
0056      2048000,
0057     11289600,
0058     12000000,
0059     12288000,
0060     19200000,
0061     22579600,
0062     24000000,
0063     24576000,
0064 };
0065 
0066 static int wm831x_fll_is_prepared(struct clk_hw *hw)
0067 {
0068     struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
0069                           fll_hw);
0070     struct wm831x *wm831x = clkdata->wm831x;
0071     int ret;
0072 
0073     ret = wm831x_reg_read(wm831x, WM831X_FLL_CONTROL_1);
0074     if (ret < 0) {
0075         dev_err(wm831x->dev, "Unable to read FLL_CONTROL_1: %d\n",
0076             ret);
0077         return true;
0078     }
0079 
0080     return (ret & WM831X_FLL_ENA) != 0;
0081 }
0082 
0083 static int wm831x_fll_prepare(struct clk_hw *hw)
0084 {
0085     struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
0086                           fll_hw);
0087     struct wm831x *wm831x = clkdata->wm831x;
0088     int ret;
0089 
0090     ret = wm831x_set_bits(wm831x, WM831X_FLL_CONTROL_1,
0091                   WM831X_FLL_ENA, WM831X_FLL_ENA);
0092     if (ret != 0)
0093         dev_crit(wm831x->dev, "Failed to enable FLL: %d\n", ret);
0094 
0095     /* wait 2-3 ms for new frequency taking effect */
0096     usleep_range(2000, 3000);
0097 
0098     return ret;
0099 }
0100 
0101 static void wm831x_fll_unprepare(struct clk_hw *hw)
0102 {
0103     struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
0104                           fll_hw);
0105     struct wm831x *wm831x = clkdata->wm831x;
0106     int ret;
0107 
0108     ret = wm831x_set_bits(wm831x, WM831X_FLL_CONTROL_1, WM831X_FLL_ENA, 0);
0109     if (ret != 0)
0110         dev_crit(wm831x->dev, "Failed to disable FLL: %d\n", ret);
0111 }
0112 
0113 static unsigned long wm831x_fll_recalc_rate(struct clk_hw *hw,
0114                         unsigned long parent_rate)
0115 {
0116     struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
0117                           fll_hw);
0118     struct wm831x *wm831x = clkdata->wm831x;
0119     int ret;
0120 
0121     ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2);
0122     if (ret < 0) {
0123         dev_err(wm831x->dev, "Unable to read CLOCK_CONTROL_2: %d\n",
0124             ret);
0125         return 0;
0126     }
0127 
0128     if (ret & WM831X_FLL_AUTO)
0129         return wm831x_fll_auto_rates[ret & WM831X_FLL_AUTO_FREQ_MASK];
0130 
0131     dev_err(wm831x->dev, "FLL only supported in AUTO mode\n");
0132 
0133     return 0;
0134 }
0135 
0136 static long wm831x_fll_round_rate(struct clk_hw *hw, unsigned long rate,
0137                   unsigned long *unused)
0138 {
0139     int best = 0;
0140     int i;
0141 
0142     for (i = 0; i < ARRAY_SIZE(wm831x_fll_auto_rates); i++)
0143         if (abs(wm831x_fll_auto_rates[i] - rate) <
0144             abs(wm831x_fll_auto_rates[best] - rate))
0145             best = i;
0146 
0147     return wm831x_fll_auto_rates[best];
0148 }
0149 
0150 static int wm831x_fll_set_rate(struct clk_hw *hw, unsigned long rate,
0151                    unsigned long parent_rate)
0152 {
0153     struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
0154                           fll_hw);
0155     struct wm831x *wm831x = clkdata->wm831x;
0156     int i;
0157 
0158     for (i = 0; i < ARRAY_SIZE(wm831x_fll_auto_rates); i++)
0159         if (wm831x_fll_auto_rates[i] == rate)
0160             break;
0161     if (i == ARRAY_SIZE(wm831x_fll_auto_rates))
0162         return -EINVAL;
0163 
0164     if (wm831x_fll_is_prepared(hw))
0165         return -EPERM;
0166 
0167     return wm831x_set_bits(wm831x, WM831X_CLOCK_CONTROL_2,
0168                    WM831X_FLL_AUTO_FREQ_MASK, i);
0169 }
0170 
0171 static const char *wm831x_fll_parents[] = {
0172     "xtal",
0173     "clkin",
0174 };
0175 
0176 static u8 wm831x_fll_get_parent(struct clk_hw *hw)
0177 {
0178     struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
0179                           fll_hw);
0180     struct wm831x *wm831x = clkdata->wm831x;
0181     int ret;
0182 
0183     /* AUTO mode is always clocked from the crystal */
0184     ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2);
0185     if (ret < 0) {
0186         dev_err(wm831x->dev, "Unable to read CLOCK_CONTROL_2: %d\n",
0187             ret);
0188         return 0;
0189     }
0190 
0191     if (ret & WM831X_FLL_AUTO)
0192         return 0;
0193 
0194     ret = wm831x_reg_read(wm831x, WM831X_FLL_CONTROL_5);
0195     if (ret < 0) {
0196         dev_err(wm831x->dev, "Unable to read FLL_CONTROL_5: %d\n",
0197             ret);
0198         return 0;
0199     }
0200 
0201     switch (ret & WM831X_FLL_CLK_SRC_MASK) {
0202     case 0:
0203         return 0;
0204     case 1:
0205         return 1;
0206     default:
0207         dev_err(wm831x->dev, "Unsupported FLL clock source %d\n",
0208             ret & WM831X_FLL_CLK_SRC_MASK);
0209         return 0;
0210     }
0211 }
0212 
0213 static const struct clk_ops wm831x_fll_ops = {
0214     .is_prepared = wm831x_fll_is_prepared,
0215     .prepare = wm831x_fll_prepare,
0216     .unprepare = wm831x_fll_unprepare,
0217     .round_rate = wm831x_fll_round_rate,
0218     .recalc_rate = wm831x_fll_recalc_rate,
0219     .set_rate = wm831x_fll_set_rate,
0220     .get_parent = wm831x_fll_get_parent,
0221 };
0222 
0223 static const struct clk_init_data wm831x_fll_init = {
0224     .name = "fll",
0225     .ops = &wm831x_fll_ops,
0226     .parent_names = wm831x_fll_parents,
0227     .num_parents = ARRAY_SIZE(wm831x_fll_parents),
0228     .flags = CLK_SET_RATE_GATE,
0229 };
0230 
0231 static int wm831x_clkout_is_prepared(struct clk_hw *hw)
0232 {
0233     struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
0234                           clkout_hw);
0235     struct wm831x *wm831x = clkdata->wm831x;
0236     int ret;
0237 
0238     ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_1);
0239     if (ret < 0) {
0240         dev_err(wm831x->dev, "Unable to read CLOCK_CONTROL_1: %d\n",
0241             ret);
0242         return false;
0243     }
0244 
0245     return (ret & WM831X_CLKOUT_ENA) != 0;
0246 }
0247 
0248 static int wm831x_clkout_prepare(struct clk_hw *hw)
0249 {
0250     struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
0251                           clkout_hw);
0252     struct wm831x *wm831x = clkdata->wm831x;
0253     int ret;
0254 
0255     ret = wm831x_reg_unlock(wm831x);
0256     if (ret != 0) {
0257         dev_crit(wm831x->dev, "Failed to lock registers: %d\n", ret);
0258         return ret;
0259     }
0260 
0261     ret = wm831x_set_bits(wm831x, WM831X_CLOCK_CONTROL_1,
0262                   WM831X_CLKOUT_ENA, WM831X_CLKOUT_ENA);
0263     if (ret != 0)
0264         dev_crit(wm831x->dev, "Failed to enable CLKOUT: %d\n", ret);
0265 
0266     wm831x_reg_lock(wm831x);
0267 
0268     return ret;
0269 }
0270 
0271 static void wm831x_clkout_unprepare(struct clk_hw *hw)
0272 {
0273     struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
0274                           clkout_hw);
0275     struct wm831x *wm831x = clkdata->wm831x;
0276     int ret;
0277 
0278     ret = wm831x_reg_unlock(wm831x);
0279     if (ret != 0) {
0280         dev_crit(wm831x->dev, "Failed to lock registers: %d\n", ret);
0281         return;
0282     }
0283 
0284     ret = wm831x_set_bits(wm831x, WM831X_CLOCK_CONTROL_1,
0285                   WM831X_CLKOUT_ENA, 0);
0286     if (ret != 0)
0287         dev_crit(wm831x->dev, "Failed to disable CLKOUT: %d\n", ret);
0288 
0289     wm831x_reg_lock(wm831x);
0290 }
0291 
0292 static const char *wm831x_clkout_parents[] = {
0293     "fll",
0294     "xtal",
0295 };
0296 
0297 static u8 wm831x_clkout_get_parent(struct clk_hw *hw)
0298 {
0299     struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
0300                           clkout_hw);
0301     struct wm831x *wm831x = clkdata->wm831x;
0302     int ret;
0303 
0304     ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_1);
0305     if (ret < 0) {
0306         dev_err(wm831x->dev, "Unable to read CLOCK_CONTROL_1: %d\n",
0307             ret);
0308         return 0;
0309     }
0310 
0311     if (ret & WM831X_CLKOUT_SRC)
0312         return 1;
0313     else
0314         return 0;
0315 }
0316 
0317 static int wm831x_clkout_set_parent(struct clk_hw *hw, u8 parent)
0318 {
0319     struct wm831x_clk *clkdata = container_of(hw, struct wm831x_clk,
0320                           clkout_hw);
0321     struct wm831x *wm831x = clkdata->wm831x;
0322 
0323     return wm831x_set_bits(wm831x, WM831X_CLOCK_CONTROL_1,
0324                    WM831X_CLKOUT_SRC,
0325                    parent << WM831X_CLKOUT_SRC_SHIFT);
0326 }
0327 
0328 static const struct clk_ops wm831x_clkout_ops = {
0329     .is_prepared = wm831x_clkout_is_prepared,
0330     .prepare = wm831x_clkout_prepare,
0331     .unprepare = wm831x_clkout_unprepare,
0332     .get_parent = wm831x_clkout_get_parent,
0333     .set_parent = wm831x_clkout_set_parent,
0334 };
0335 
0336 static const struct clk_init_data wm831x_clkout_init = {
0337     .name = "clkout",
0338     .ops = &wm831x_clkout_ops,
0339     .parent_names = wm831x_clkout_parents,
0340     .num_parents = ARRAY_SIZE(wm831x_clkout_parents),
0341     .flags = CLK_SET_RATE_PARENT,
0342 };
0343 
0344 static int wm831x_clk_probe(struct platform_device *pdev)
0345 {
0346     struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
0347     struct wm831x_clk *clkdata;
0348     int ret;
0349 
0350     clkdata = devm_kzalloc(&pdev->dev, sizeof(*clkdata), GFP_KERNEL);
0351     if (!clkdata)
0352         return -ENOMEM;
0353 
0354     clkdata->wm831x = wm831x;
0355 
0356     /* XTAL_ENA can only be set via OTP/InstantConfig so just read once */
0357     ret = wm831x_reg_read(wm831x, WM831X_CLOCK_CONTROL_2);
0358     if (ret < 0) {
0359         dev_err(wm831x->dev, "Unable to read CLOCK_CONTROL_2: %d\n",
0360             ret);
0361         return ret;
0362     }
0363     clkdata->xtal_ena = ret & WM831X_XTAL_ENA;
0364 
0365     clkdata->xtal_hw.init = &wm831x_xtal_init;
0366     ret = devm_clk_hw_register(&pdev->dev, &clkdata->xtal_hw);
0367     if (ret)
0368         return ret;
0369 
0370     clkdata->fll_hw.init = &wm831x_fll_init;
0371     ret = devm_clk_hw_register(&pdev->dev, &clkdata->fll_hw);
0372     if (ret)
0373         return ret;
0374 
0375     clkdata->clkout_hw.init = &wm831x_clkout_init;
0376     ret = devm_clk_hw_register(&pdev->dev, &clkdata->clkout_hw);
0377     if (ret)
0378         return ret;
0379 
0380     platform_set_drvdata(pdev, clkdata);
0381 
0382     return 0;
0383 }
0384 
0385 static struct platform_driver wm831x_clk_driver = {
0386     .probe = wm831x_clk_probe,
0387     .driver     = {
0388         .name   = "wm831x-clk",
0389     },
0390 };
0391 
0392 module_platform_driver(wm831x_clk_driver);
0393 
0394 /* Module information */
0395 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
0396 MODULE_DESCRIPTION("WM831x clock driver");
0397 MODULE_LICENSE("GPL");
0398 MODULE_ALIAS("platform:wm831x-clk");