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