aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Hesselbarth <sebastian.hesselbarth@gmail.com>2013-04-11 15:42:29 -0400
committerMike Turquette <mturquette@linaro.org>2013-04-12 14:04:38 -0400
commit9abd5f0555df6cd36130feb742f1def6d99c60fe (patch)
tree8473cc9d9643b968a531dbdc1145270dd09f94ef
parent79b16641efabd14944dbfc2fde2ae1e8ae8413bc (diff)
clk: add si5351 i2c common clock driver
This patch adds a common clock driver for Silicon Labs Si5351a/b/c i2c programmable clock generators. Currently, the driver does not support VXCO feature of si5351b. Passing platform_data or DT bindings selectively allows to overwrite stored Si5351 configuration which is very helpful for clock generators with empty eeprom configuration. Corresponding device tree binding documentation is also added. Signed-off-by: Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> Tested-by: Daniel Mack <zonque@gmail.com> Acked-by: Guenter Roeck <linux@roeck-us.net> Tested-by: Michal Bachraty <michal.bachraty@streamunlimited.com> Signed-off-by: Mike Turquette <mturquette@linaro.org>
-rw-r--r--Documentation/devicetree/bindings/clock/silabs,si5351.txt114
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt1
-rw-r--r--drivers/clk/Kconfig9
-rw-r--r--drivers/clk/Makefile1
-rw-r--r--drivers/clk/clk-si5351.c1510
-rw-r--r--drivers/clk/clk-si5351.h155
-rw-r--r--include/linux/platform_data/si5351.h114
7 files changed, 1904 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/clock/silabs,si5351.txt b/Documentation/devicetree/bindings/clock/silabs,si5351.txt
new file mode 100644
index 000000000000..cc374651662c
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/silabs,si5351.txt
@@ -0,0 +1,114 @@
1Binding for Silicon Labs Si5351a/b/c programmable i2c clock generator.
2
3Reference
4[1] Si5351A/B/C Data Sheet
5 http://www.silabs.com/Support%20Documents/TechnicalDocs/Si5351.pdf
6
7The Si5351a/b/c are programmable i2c clock generators with upto 8 output
8clocks. Si5351a also has a reduced pin-count package (MSOP10) where only
93 output clocks are accessible. The internal structure of the clock
10generators can be found in [1].
11
12==I2C device node==
13
14Required properties:
15- compatible: shall be one of "silabs,si5351{a,a-msop,b,c}".
16- reg: i2c device address, shall be 0x60 or 0x61.
17- #clock-cells: from common clock binding; shall be set to 1.
18- clocks: from common clock binding; list of parent clock
19 handles, shall be xtal reference clock or xtal and clkin for
20 si5351c only.
21- #address-cells: shall be set to 1.
22- #size-cells: shall be set to 0.
23
24Optional properties:
25- silabs,pll-source: pair of (number, source) for each pll. Allows
26 to overwrite clock source of pll A (number=0) or B (number=1).
27
28==Child nodes==
29
30Each of the clock outputs can be overwritten individually by
31using a child node to the I2C device node. If a child node for a clock
32output is not set, the eeprom configuration is not overwritten.
33
34Required child node properties:
35- reg: number of clock output.
36
37Optional child node properties:
38- silabs,clock-source: source clock of the output divider stage N, shall be
39 0 = multisynth N
40 1 = multisynth 0 for output clocks 0-3, else multisynth4
41 2 = xtal
42 3 = clkin (si5351c only)
43- silabs,drive-strength: output drive strength in mA, shall be one of {2,4,6,8}.
44- silabs,multisynth-source: source pll A(0) or B(1) of corresponding multisynth
45 divider.
46- silabs,pll-master: boolean, multisynth can change pll frequency.
47
48==Example==
49
50/* 25MHz reference crystal */
51ref25: ref25M {
52 compatible = "fixed-clock";
53 #clock-cells = <0>;
54 clock-frequency = <25000000>;
55};
56
57i2c-master-node {
58
59 /* Si5351a msop10 i2c clock generator */
60 si5351a: clock-generator@60 {
61 compatible = "silabs,si5351a-msop";
62 reg = <0x60>;
63 #address-cells = <1>;
64 #size-cells = <0>;
65 #clock-cells = <1>;
66
67 /* connect xtal input to 25MHz reference */
68 clocks = <&ref25>;
69
70 /* connect xtal input as source of pll0 and pll1 */
71 silabs,pll-source = <0 0>, <1 0>;
72
73 /*
74 * overwrite clkout0 configuration with:
75 * - 8mA output drive strength
76 * - pll0 as clock source of multisynth0
77 * - multisynth0 as clock source of output divider
78 * - multisynth0 can change pll0
79 * - set initial clock frequency of 74.25MHz
80 */
81 clkout0 {
82 reg = <0>;
83 silabs,drive-strength = <8>;
84 silabs,multisynth-source = <0>;
85 silabs,clock-source = <0>;
86 silabs,pll-master;
87 clock-frequency = <74250000>;
88 };
89
90 /*
91 * overwrite clkout1 configuration with:
92 * - 4mA output drive strength
93 * - pll1 as clock source of multisynth1
94 * - multisynth1 as clock source of output divider
95 * - multisynth1 can change pll1
96 */
97 clkout1 {
98 reg = <1>;
99 silabs,drive-strength = <4>;
100 silabs,multisynth-source = <1>;
101 silabs,clock-source = <0>;
102 pll-master;
103 };
104
105 /*
106 * overwrite clkout2 configuration with:
107 * - xtal as clock source of output divider
108 */
109 clkout2 {
110 reg = <2>;
111 silabs,clock-source = <2>;
112 };
113 };
114};
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 19e1ef73ab0d..ca608496507b 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -48,6 +48,7 @@ samsung Samsung Semiconductor
48sbs Smart Battery System 48sbs Smart Battery System
49schindler Schindler 49schindler Schindler
50sil Silicon Image 50sil Silicon Image
51silabs Silicon Laboratories
51simtek 52simtek
52sirf SiRF Technology, Inc. 53sirf SiRF Technology, Inc.
53snps Synopsys, Inc. 54snps Synopsys, Inc.
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index a64caefdba12..186dd0edca8f 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -55,6 +55,15 @@ config COMMON_CLK_MAX77686
55 ---help--- 55 ---help---
56 This driver supports Maxim 77686 crystal oscillator clock. 56 This driver supports Maxim 77686 crystal oscillator clock.
57 57
58config COMMON_CLK_SI5351
59 tristate "Clock driver for SiLabs 5351A/B/C"
60 depends on I2C
61 select REGMAP_I2C
62 select RATIONAL
63 ---help---
64 This driver supports Silicon Labs 5351A/B/C programmable clock
65 generators.
66
58config CLK_TWL6040 67config CLK_TWL6040
59 tristate "External McPDM functional clock from twl6040" 68 tristate "External McPDM functional clock from twl6040"
60 depends on TWL6040_CORE 69 depends on TWL6040_CORE
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 79e98e416724..e7f7fe9b2f09 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -36,4 +36,5 @@ obj-$(CONFIG_X86) += x86/
36obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o 36obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
37obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o 37obj-$(CONFIG_COMMON_CLK_WM831X) += clk-wm831x.o
38obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o 38obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
39obj-$(CONFIG_COMMON_CLK_SI5351) += clk-si5351.o
39obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o 40obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
diff --git a/drivers/clk/clk-si5351.c b/drivers/clk/clk-si5351.c
new file mode 100644
index 000000000000..892728412e9d
--- /dev/null
+++ b/drivers/clk/clk-si5351.c
@@ -0,0 +1,1510 @@
1/*
2 * clk-si5351.c: Silicon Laboratories Si5351A/B/C I2C Clock Generator
3 *
4 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5 * Rabeeh Khoury <rabeeh@solid-run.com>
6 *
7 * References:
8 * [1] "Si5351A/B/C Data Sheet"
9 * http://www.silabs.com/Support%20Documents/TechnicalDocs/Si5351.pdf
10 * [2] "Manually Generating an Si5351 Register Map"
11 * http://www.silabs.com/Support%20Documents/TechnicalDocs/AN619.pdf
12 *
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version.
17 */
18
19#include <linux/module.h>
20#include <linux/kernel.h>
21#include <linux/clkdev.h>
22#include <linux/clk-provider.h>
23#include <linux/delay.h>
24#include <linux/err.h>
25#include <linux/errno.h>
26#include <linux/rational.h>
27#include <linux/i2c.h>
28#include <linux/of_platform.h>
29#include <linux/platform_data/si5351.h>
30#include <linux/regmap.h>
31#include <linux/slab.h>
32#include <linux/string.h>
33#include <asm/div64.h>
34
35#include "clk-si5351.h"
36
37struct si5351_driver_data;
38
39struct si5351_parameters {
40 unsigned long p1;
41 unsigned long p2;
42 unsigned long p3;
43 int valid;
44};
45
46struct si5351_hw_data {
47 struct clk_hw hw;
48 struct si5351_driver_data *drvdata;
49 struct si5351_parameters params;
50 unsigned char num;
51};
52
53struct si5351_driver_data {
54 enum si5351_variant variant;
55 struct i2c_client *client;
56 struct regmap *regmap;
57 struct clk_onecell_data onecell;
58
59 struct clk *pxtal;
60 const char *pxtal_name;
61 struct clk_hw xtal;
62 struct clk *pclkin;
63 const char *pclkin_name;
64 struct clk_hw clkin;
65
66 struct si5351_hw_data pll[2];
67 struct si5351_hw_data *msynth;
68 struct si5351_hw_data *clkout;
69};
70
71static const char const *si5351_input_names[] = {
72 "xtal", "clkin"
73};
74static const char const *si5351_pll_names[] = {
75 "plla", "pllb", "vxco"
76};
77static const char const *si5351_msynth_names[] = {
78 "ms0", "ms1", "ms2", "ms3", "ms4", "ms5", "ms6", "ms7"
79};
80static const char const *si5351_clkout_names[] = {
81 "clk0", "clk1", "clk2", "clk3", "clk4", "clk5", "clk6", "clk7"
82};
83
84/*
85 * Si5351 i2c regmap
86 */
87static inline u8 si5351_reg_read(struct si5351_driver_data *drvdata, u8 reg)
88{
89 u32 val;
90 int ret;
91
92 ret = regmap_read(drvdata->regmap, reg, &val);
93 if (ret) {
94 dev_err(&drvdata->client->dev,
95 "unable to read from reg%02x\n", reg);
96 return 0;
97 }
98
99 return (u8)val;
100}
101
102static inline int si5351_bulk_read(struct si5351_driver_data *drvdata,
103 u8 reg, u8 count, u8 *buf)
104{
105 return regmap_bulk_read(drvdata->regmap, reg, buf, count);
106}
107
108static inline int si5351_reg_write(struct si5351_driver_data *drvdata,
109 u8 reg, u8 val)
110{
111 return regmap_write(drvdata->regmap, reg, val);
112}
113
114static inline int si5351_bulk_write(struct si5351_driver_data *drvdata,
115 u8 reg, u8 count, const u8 *buf)
116{
117 return regmap_raw_write(drvdata->regmap, reg, buf, count);
118}
119
120static inline int si5351_set_bits(struct si5351_driver_data *drvdata,
121 u8 reg, u8 mask, u8 val)
122{
123 return regmap_update_bits(drvdata->regmap, reg, mask, val);
124}
125
126static inline u8 si5351_msynth_params_address(int num)
127{
128 if (num > 5)
129 return SI5351_CLK6_PARAMETERS + (num - 6);
130 return SI5351_CLK0_PARAMETERS + (SI5351_PARAMETERS_LENGTH * num);
131}
132
133static void si5351_read_parameters(struct si5351_driver_data *drvdata,
134 u8 reg, struct si5351_parameters *params)
135{
136 u8 buf[SI5351_PARAMETERS_LENGTH];
137
138 switch (reg) {
139 case SI5351_CLK6_PARAMETERS:
140 case SI5351_CLK7_PARAMETERS:
141 buf[0] = si5351_reg_read(drvdata, reg);
142 params->p1 = buf[0];
143 params->p2 = 0;
144 params->p3 = 1;
145 break;
146 default:
147 si5351_bulk_read(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
148 params->p1 = ((buf[2] & 0x03) << 16) | (buf[3] << 8) | buf[4];
149 params->p2 = ((buf[5] & 0x0f) << 16) | (buf[6] << 8) | buf[7];
150 params->p3 = ((buf[5] & 0xf0) << 12) | (buf[0] << 8) | buf[1];
151 }
152 params->valid = 1;
153}
154
155static void si5351_write_parameters(struct si5351_driver_data *drvdata,
156 u8 reg, struct si5351_parameters *params)
157{
158 u8 buf[SI5351_PARAMETERS_LENGTH];
159
160 switch (reg) {
161 case SI5351_CLK6_PARAMETERS:
162 case SI5351_CLK7_PARAMETERS:
163 buf[0] = params->p1 & 0xff;
164 si5351_reg_write(drvdata, reg, buf[0]);
165 break;
166 default:
167 buf[0] = ((params->p3 & 0x0ff00) >> 8) & 0xff;
168 buf[1] = params->p3 & 0xff;
169 /* save rdiv and divby4 */
170 buf[2] = si5351_reg_read(drvdata, reg + 2) & ~0x03;
171 buf[2] |= ((params->p1 & 0x30000) >> 16) & 0x03;
172 buf[3] = ((params->p1 & 0x0ff00) >> 8) & 0xff;
173 buf[4] = params->p1 & 0xff;
174 buf[5] = ((params->p3 & 0xf0000) >> 12) |
175 ((params->p2 & 0xf0000) >> 16);
176 buf[6] = ((params->p2 & 0x0ff00) >> 8) & 0xff;
177 buf[7] = params->p2 & 0xff;
178 si5351_bulk_write(drvdata, reg, SI5351_PARAMETERS_LENGTH, buf);
179 }
180}
181
182static bool si5351_regmap_is_volatile(struct device *dev, unsigned int reg)
183{
184 switch (reg) {
185 case SI5351_DEVICE_STATUS:
186 case SI5351_INTERRUPT_STATUS:
187 case SI5351_PLL_RESET:
188 return true;
189 }
190 return false;
191}
192
193static bool si5351_regmap_is_writeable(struct device *dev, unsigned int reg)
194{
195 /* reserved registers */
196 if (reg >= 4 && reg <= 8)
197 return false;
198 if (reg >= 10 && reg <= 14)
199 return false;
200 if (reg >= 173 && reg <= 176)
201 return false;
202 if (reg >= 178 && reg <= 182)
203 return false;
204 /* read-only */
205 if (reg == SI5351_DEVICE_STATUS)
206 return false;
207 return true;
208}
209
210static struct regmap_config si5351_regmap_config = {
211 .reg_bits = 8,
212 .val_bits = 8,
213 .cache_type = REGCACHE_RBTREE,
214 .max_register = 187,
215 .writeable_reg = si5351_regmap_is_writeable,
216 .volatile_reg = si5351_regmap_is_volatile,
217};
218
219/*
220 * Si5351 xtal clock input
221 */
222static int si5351_xtal_prepare(struct clk_hw *hw)
223{
224 struct si5351_driver_data *drvdata =
225 container_of(hw, struct si5351_driver_data, xtal);
226 si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE,
227 SI5351_XTAL_ENABLE, SI5351_XTAL_ENABLE);
228 return 0;
229}
230
231static void si5351_xtal_unprepare(struct clk_hw *hw)
232{
233 struct si5351_driver_data *drvdata =
234 container_of(hw, struct si5351_driver_data, xtal);
235 si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE,
236 SI5351_XTAL_ENABLE, 0);
237}
238
239static const struct clk_ops si5351_xtal_ops = {
240 .prepare = si5351_xtal_prepare,
241 .unprepare = si5351_xtal_unprepare,
242};
243
244/*
245 * Si5351 clkin clock input (Si5351C only)
246 */
247static int si5351_clkin_prepare(struct clk_hw *hw)
248{
249 struct si5351_driver_data *drvdata =
250 container_of(hw, struct si5351_driver_data, clkin);
251 si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE,
252 SI5351_CLKIN_ENABLE, SI5351_CLKIN_ENABLE);
253 return 0;
254}
255
256static void si5351_clkin_unprepare(struct clk_hw *hw)
257{
258 struct si5351_driver_data *drvdata =
259 container_of(hw, struct si5351_driver_data, clkin);
260 si5351_set_bits(drvdata, SI5351_FANOUT_ENABLE,
261 SI5351_CLKIN_ENABLE, 0);
262}
263
264/*
265 * CMOS clock source constraints:
266 * The input frequency range of the PLL is 10Mhz to 40MHz.
267 * If CLKIN is >40MHz, the input divider must be used.
268 */
269static unsigned long si5351_clkin_recalc_rate(struct clk_hw *hw,
270 unsigned long parent_rate)
271{
272 struct si5351_driver_data *drvdata =
273 container_of(hw, struct si5351_driver_data, clkin);
274 unsigned long rate;
275 unsigned char idiv;
276
277 rate = parent_rate;
278 if (parent_rate > 160000000) {
279 idiv = SI5351_CLKIN_DIV_8;
280 rate /= 8;
281 } else if (parent_rate > 80000000) {
282 idiv = SI5351_CLKIN_DIV_4;
283 rate /= 4;
284 } else if (parent_rate > 40000000) {
285 idiv = SI5351_CLKIN_DIV_2;
286 rate /= 2;
287 } else {
288 idiv = SI5351_CLKIN_DIV_1;
289 }
290
291 si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE,
292 SI5351_CLKIN_DIV_MASK, idiv);
293
294 dev_dbg(&drvdata->client->dev, "%s - clkin div = %d, rate = %lu\n",
295 __func__, (1 << (idiv >> 6)), rate);
296
297 return rate;
298}
299
300static const struct clk_ops si5351_clkin_ops = {
301 .prepare = si5351_clkin_prepare,
302 .unprepare = si5351_clkin_unprepare,
303 .recalc_rate = si5351_clkin_recalc_rate,
304};
305
306/*
307 * Si5351 vxco clock input (Si5351B only)
308 */
309
310static int si5351_vxco_prepare(struct clk_hw *hw)
311{
312 struct si5351_hw_data *hwdata =
313 container_of(hw, struct si5351_hw_data, hw);
314
315 dev_warn(&hwdata->drvdata->client->dev, "VXCO currently unsupported\n");
316
317 return 0;
318}
319
320static void si5351_vxco_unprepare(struct clk_hw *hw)
321{
322}
323
324static unsigned long si5351_vxco_recalc_rate(struct clk_hw *hw,
325 unsigned long parent_rate)
326{
327 return 0;
328}
329
330static int si5351_vxco_set_rate(struct clk_hw *hw, unsigned long rate,
331 unsigned long parent)
332{
333 return 0;
334}
335
336static const struct clk_ops si5351_vxco_ops = {
337 .prepare = si5351_vxco_prepare,
338 .unprepare = si5351_vxco_unprepare,
339 .recalc_rate = si5351_vxco_recalc_rate,
340 .set_rate = si5351_vxco_set_rate,
341};
342
343/*
344 * Si5351 pll a/b
345 *
346 * Feedback Multisynth Divider Equations [2]
347 *
348 * fVCO = fIN * (a + b/c)
349 *
350 * with 15 + 0/1048575 <= (a + b/c) <= 90 + 0/1048575 and
351 * fIN = fXTAL or fIN = fCLKIN/CLKIN_DIV
352 *
353 * Feedback Multisynth Register Equations
354 *
355 * (1) MSNx_P1[17:0] = 128 * a + floor(128 * b/c) - 512
356 * (2) MSNx_P2[19:0] = 128 * b - c * floor(128 * b/c) = (128*b) mod c
357 * (3) MSNx_P3[19:0] = c
358 *
359 * Transposing (2) yields: (4) floor(128 * b/c) = (128 * b / MSNx_P2)/c
360 *
361 * Using (4) on (1) yields:
362 * MSNx_P1 = 128 * a + (128 * b/MSNx_P2)/c - 512
363 * MSNx_P1 + 512 + MSNx_P2/c = 128 * a + 128 * b/c
364 *
365 * a + b/c = (MSNx_P1 + MSNx_P2/MSNx_P3 + 512)/128
366 * = (MSNx_P1*MSNx_P3 + MSNx_P2 + 512*MSNx_P3)/(128*MSNx_P3)
367 *
368 */
369static int _si5351_pll_reparent(struct si5351_driver_data *drvdata,
370 int num, enum si5351_pll_src parent)
371{
372 u8 mask = (num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
373
374 if (parent == SI5351_PLL_SRC_DEFAULT)
375 return 0;
376
377 if (num > 2)
378 return -EINVAL;
379
380 if (drvdata->variant != SI5351_VARIANT_C &&
381 parent != SI5351_PLL_SRC_XTAL)
382 return -EINVAL;
383
384 si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE, mask,
385 (parent == SI5351_PLL_SRC_XTAL) ? 0 : mask);
386 return 0;
387}
388
389static unsigned char si5351_pll_get_parent(struct clk_hw *hw)
390{
391 struct si5351_hw_data *hwdata =
392 container_of(hw, struct si5351_hw_data, hw);
393 u8 mask = (hwdata->num == 0) ? SI5351_PLLA_SOURCE : SI5351_PLLB_SOURCE;
394 u8 val;
395
396 val = si5351_reg_read(hwdata->drvdata, SI5351_PLL_INPUT_SOURCE);
397
398 return (val & mask) ? 1 : 0;
399}
400
401static int si5351_pll_set_parent(struct clk_hw *hw, u8 index)
402{
403 struct si5351_hw_data *hwdata =
404 container_of(hw, struct si5351_hw_data, hw);
405
406 if (hwdata->drvdata->variant != SI5351_VARIANT_C &&
407 index > 0)
408 return -EPERM;
409
410 if (index > 1)
411 return -EINVAL;
412
413 return _si5351_pll_reparent(hwdata->drvdata, hwdata->num,
414 (index == 0) ? SI5351_PLL_SRC_XTAL :
415 SI5351_PLL_SRC_CLKIN);
416}
417
418static unsigned long si5351_pll_recalc_rate(struct clk_hw *hw,
419 unsigned long parent_rate)
420{
421 struct si5351_hw_data *hwdata =
422 container_of(hw, struct si5351_hw_data, hw);
423 u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
424 SI5351_PLLB_PARAMETERS;
425 unsigned long long rate;
426
427 if (!hwdata->params.valid)
428 si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params);
429
430 if (hwdata->params.p3 == 0)
431 return parent_rate;
432
433 /* fVCO = fIN * (P1*P3 + 512*P3 + P2)/(128*P3) */
434 rate = hwdata->params.p1 * hwdata->params.p3;
435 rate += 512 * hwdata->params.p3;
436 rate += hwdata->params.p2;
437 rate *= parent_rate;
438 do_div(rate, 128 * hwdata->params.p3);
439
440 dev_dbg(&hwdata->drvdata->client->dev,
441 "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n",
442 __func__, __clk_get_name(hwdata->hw.clk),
443 hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
444 parent_rate, (unsigned long)rate);
445
446 return (unsigned long)rate;
447}
448
449static long si5351_pll_round_rate(struct clk_hw *hw, unsigned long rate,
450 unsigned long *parent_rate)
451{
452 struct si5351_hw_data *hwdata =
453 container_of(hw, struct si5351_hw_data, hw);
454 unsigned long rfrac, denom, a, b, c;
455 unsigned long long lltmp;
456
457 if (rate < SI5351_PLL_VCO_MIN)
458 rate = SI5351_PLL_VCO_MIN;
459 if (rate > SI5351_PLL_VCO_MAX)
460 rate = SI5351_PLL_VCO_MAX;
461
462 /* determine integer part of feedback equation */
463 a = rate / *parent_rate;
464
465 if (a < SI5351_PLL_A_MIN)
466 rate = *parent_rate * SI5351_PLL_A_MIN;
467 if (a > SI5351_PLL_A_MAX)
468 rate = *parent_rate * SI5351_PLL_A_MAX;
469
470 /* find best approximation for b/c = fVCO mod fIN */
471 denom = 1000 * 1000;
472 lltmp = rate % (*parent_rate);
473 lltmp *= denom;
474 do_div(lltmp, *parent_rate);
475 rfrac = (unsigned long)lltmp;
476
477 b = 0;
478 c = 1;
479 if (rfrac)
480 rational_best_approximation(rfrac, denom,
481 SI5351_PLL_B_MAX, SI5351_PLL_C_MAX, &b, &c);
482
483 /* calculate parameters */
484 hwdata->params.p3 = c;
485 hwdata->params.p2 = (128 * b) % c;
486 hwdata->params.p1 = 128 * a;
487 hwdata->params.p1 += (128 * b / c);
488 hwdata->params.p1 -= 512;
489
490 /* recalculate rate by fIN * (a + b/c) */
491 lltmp = *parent_rate;
492 lltmp *= b;
493 do_div(lltmp, c);
494
495 rate = (unsigned long)lltmp;
496 rate += *parent_rate * a;
497
498 dev_dbg(&hwdata->drvdata->client->dev,
499 "%s - %s: a = %lu, b = %lu, c = %lu, parent_rate = %lu, rate = %lu\n",
500 __func__, __clk_get_name(hwdata->hw.clk), a, b, c,
501 *parent_rate, rate);
502
503 return rate;
504}
505
506static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
507 unsigned long parent_rate)
508{
509 struct si5351_hw_data *hwdata =
510 container_of(hw, struct si5351_hw_data, hw);
511 u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
512 SI5351_PLLB_PARAMETERS;
513
514 /* write multisynth parameters */
515 si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
516
517 /* plla/pllb ctrl is in clk6/clk7 ctrl registers */
518 si5351_set_bits(hwdata->drvdata, SI5351_CLK6_CTRL + hwdata->num,
519 SI5351_CLK_INTEGER_MODE,
520 (hwdata->params.p2 == 0) ? SI5351_CLK_INTEGER_MODE : 0);
521
522 dev_dbg(&hwdata->drvdata->client->dev,
523 "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n",
524 __func__, __clk_get_name(hwdata->hw.clk),
525 hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
526 parent_rate, rate);
527
528 return 0;
529}
530
531static const struct clk_ops si5351_pll_ops = {
532 .set_parent = si5351_pll_set_parent,
533 .get_parent = si5351_pll_get_parent,
534 .recalc_rate = si5351_pll_recalc_rate,
535 .round_rate = si5351_pll_round_rate,
536 .set_rate = si5351_pll_set_rate,
537};
538
539/*
540 * Si5351 multisync divider
541 *
542 * for fOUT <= 150 MHz:
543 *
544 * fOUT = (fIN * (a + b/c)) / CLKOUTDIV
545 *
546 * with 6 + 0/1048575 <= (a + b/c) <= 1800 + 0/1048575 and
547 * fIN = fVCO0, fVCO1
548 *
549 * Output Clock Multisynth Register Equations
550 *
551 * MSx_P1[17:0] = 128 * a + floor(128 * b/c) - 512
552 * MSx_P2[19:0] = 128 * b - c * floor(128 * b/c) = (128*b) mod c
553 * MSx_P3[19:0] = c
554 *
555 * MS[6,7] are integer (P1) divide only, P2 = 0, P3 = 0
556 *
557 * for 150MHz < fOUT <= 160MHz:
558 *
559 * MSx_P1 = 0, MSx_P2 = 0, MSx_P3 = 1, MSx_INT = 1, MSx_DIVBY4 = 11b
560 */
561static int _si5351_msynth_reparent(struct si5351_driver_data *drvdata,
562 int num, enum si5351_multisynth_src parent)
563{
564 if (parent == SI5351_MULTISYNTH_SRC_DEFAULT)
565 return 0;
566
567 if (num > 8)
568 return -EINVAL;
569
570 si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num, SI5351_CLK_PLL_SELECT,
571 (parent == SI5351_MULTISYNTH_SRC_VCO0) ? 0 :
572 SI5351_CLK_PLL_SELECT);
573 return 0;
574}
575
576static unsigned char si5351_msynth_get_parent(struct clk_hw *hw)
577{
578 struct si5351_hw_data *hwdata =
579 container_of(hw, struct si5351_hw_data, hw);
580 u8 val;
581
582 val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);
583
584 return (val & SI5351_CLK_PLL_SELECT) ? 1 : 0;
585}
586
587static int si5351_msynth_set_parent(struct clk_hw *hw, u8 index)
588{
589 struct si5351_hw_data *hwdata =
590 container_of(hw, struct si5351_hw_data, hw);
591
592 return _si5351_msynth_reparent(hwdata->drvdata, hwdata->num,
593 (index == 0) ? SI5351_MULTISYNTH_SRC_VCO0 :
594 SI5351_MULTISYNTH_SRC_VCO1);
595}
596
597static unsigned long si5351_msynth_recalc_rate(struct clk_hw *hw,
598 unsigned long parent_rate)
599{
600 struct si5351_hw_data *hwdata =
601 container_of(hw, struct si5351_hw_data, hw);
602 u8 reg = si5351_msynth_params_address(hwdata->num);
603 unsigned long long rate;
604 unsigned long m;
605
606 if (!hwdata->params.valid)
607 si5351_read_parameters(hwdata->drvdata, reg, &hwdata->params);
608
609 if (hwdata->params.p3 == 0)
610 return parent_rate;
611
612 /*
613 * multisync0-5: fOUT = (128 * P3 * fIN) / (P1*P3 + P2 + 512*P3)
614 * multisync6-7: fOUT = fIN / P1
615 */
616 rate = parent_rate;
617 if (hwdata->num > 5) {
618 m = hwdata->params.p1;
619 } else if ((si5351_reg_read(hwdata->drvdata, reg + 2) &
620 SI5351_OUTPUT_CLK_DIVBY4) == SI5351_OUTPUT_CLK_DIVBY4) {
621 m = 4;
622 } else {
623 rate *= 128 * hwdata->params.p3;
624 m = hwdata->params.p1 * hwdata->params.p3;
625 m += hwdata->params.p2;
626 m += 512 * hwdata->params.p3;
627 }
628
629 if (m == 0)
630 return 0;
631 do_div(rate, m);
632
633 dev_dbg(&hwdata->drvdata->client->dev,
634 "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, m = %lu, parent_rate = %lu, rate = %lu\n",
635 __func__, __clk_get_name(hwdata->hw.clk),
636 hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
637 m, parent_rate, (unsigned long)rate);
638
639 return (unsigned long)rate;
640}
641
642static long si5351_msynth_round_rate(struct clk_hw *hw, unsigned long rate,
643 unsigned long *parent_rate)
644{
645 struct si5351_hw_data *hwdata =
646 container_of(hw, struct si5351_hw_data, hw);
647 unsigned long long lltmp;
648 unsigned long a, b, c;
649 int divby4;
650
651 /* multisync6-7 can only handle freqencies < 150MHz */
652 if (hwdata->num >= 6 && rate > SI5351_MULTISYNTH67_MAX_FREQ)
653 rate = SI5351_MULTISYNTH67_MAX_FREQ;
654
655 /* multisync frequency is 1MHz .. 160MHz */
656 if (rate > SI5351_MULTISYNTH_MAX_FREQ)
657 rate = SI5351_MULTISYNTH_MAX_FREQ;
658 if (rate < SI5351_MULTISYNTH_MIN_FREQ)
659 rate = SI5351_MULTISYNTH_MIN_FREQ;
660
661 divby4 = 0;
662 if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
663 divby4 = 1;
664
665 /* multisync can set pll */
666 if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
667 /*
668 * find largest integer divider for max
669 * vco frequency and given target rate
670 */
671 if (divby4 == 0) {
672 lltmp = SI5351_PLL_VCO_MAX;
673 do_div(lltmp, rate);
674 a = (unsigned long)lltmp;
675 } else
676 a = 4;
677
678 b = 0;
679 c = 1;
680
681 *parent_rate = a * rate;
682 } else {
683 unsigned long rfrac, denom;
684
685 /* disable divby4 */
686 if (divby4) {
687 rate = SI5351_MULTISYNTH_DIVBY4_FREQ;
688 divby4 = 0;
689 }
690
691 /* determine integer part of divider equation */
692 a = *parent_rate / rate;
693 if (a < SI5351_MULTISYNTH_A_MIN)
694 a = SI5351_MULTISYNTH_A_MIN;
695 if (hwdata->num >= 6 && a > SI5351_MULTISYNTH67_A_MAX)
696 a = SI5351_MULTISYNTH67_A_MAX;
697 else if (a > SI5351_MULTISYNTH_A_MAX)
698 a = SI5351_MULTISYNTH_A_MAX;
699
700 /* find best approximation for b/c = fVCO mod fOUT */
701 denom = 1000 * 1000;
702 lltmp = (*parent_rate) % rate;
703 lltmp *= denom;
704 do_div(lltmp, rate);
705 rfrac = (unsigned long)lltmp;
706
707 b = 0;
708 c = 1;
709 if (rfrac)
710 rational_best_approximation(rfrac, denom,
711 SI5351_MULTISYNTH_B_MAX, SI5351_MULTISYNTH_C_MAX,
712 &b, &c);
713 }
714
715 /* recalculate rate by fOUT = fIN / (a + b/c) */
716 lltmp = *parent_rate;
717 lltmp *= c;
718 do_div(lltmp, a * c + b);
719 rate = (unsigned long)lltmp;
720
721 /* calculate parameters */
722 if (divby4) {
723 hwdata->params.p3 = 1;
724 hwdata->params.p2 = 0;
725 hwdata->params.p1 = 0;
726 } else {
727 hwdata->params.p3 = c;
728 hwdata->params.p2 = (128 * b) % c;
729 hwdata->params.p1 = 128 * a;
730 hwdata->params.p1 += (128 * b / c);
731 hwdata->params.p1 -= 512;
732 }
733
734 dev_dbg(&hwdata->drvdata->client->dev,
735 "%s - %s: a = %lu, b = %lu, c = %lu, divby4 = %d, parent_rate = %lu, rate = %lu\n",
736 __func__, __clk_get_name(hwdata->hw.clk), a, b, c, divby4,
737 *parent_rate, rate);
738
739 return rate;
740}
741
742static int si5351_msynth_set_rate(struct clk_hw *hw, unsigned long rate,
743 unsigned long parent_rate)
744{
745 struct si5351_hw_data *hwdata =
746 container_of(hw, struct si5351_hw_data, hw);
747 u8 reg = si5351_msynth_params_address(hwdata->num);
748 int divby4 = 0;
749
750 /* write multisynth parameters */
751 si5351_write_parameters(hwdata->drvdata, reg, &hwdata->params);
752
753 if (rate > SI5351_MULTISYNTH_DIVBY4_FREQ)
754 divby4 = 1;
755
756 /* enable/disable integer mode and divby4 on multisynth0-5 */
757 if (hwdata->num < 6) {
758 si5351_set_bits(hwdata->drvdata, reg + 2,
759 SI5351_OUTPUT_CLK_DIVBY4,
760 (divby4) ? SI5351_OUTPUT_CLK_DIVBY4 : 0);
761 si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
762 SI5351_CLK_INTEGER_MODE,
763 (hwdata->params.p2 == 0) ? SI5351_CLK_INTEGER_MODE : 0);
764 }
765
766 dev_dbg(&hwdata->drvdata->client->dev,
767 "%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, divby4 = %d, parent_rate = %lu, rate = %lu\n",
768 __func__, __clk_get_name(hwdata->hw.clk),
769 hwdata->params.p1, hwdata->params.p2, hwdata->params.p3,
770 divby4, parent_rate, rate);
771
772 return 0;
773}
774
775static const struct clk_ops si5351_msynth_ops = {
776 .set_parent = si5351_msynth_set_parent,
777 .get_parent = si5351_msynth_get_parent,
778 .recalc_rate = si5351_msynth_recalc_rate,
779 .round_rate = si5351_msynth_round_rate,
780 .set_rate = si5351_msynth_set_rate,
781};
782
783/*
784 * Si5351 clkout divider
785 */
786static int _si5351_clkout_reparent(struct si5351_driver_data *drvdata,
787 int num, enum si5351_clkout_src parent)
788{
789 u8 val;
790
791 if (num > 8)
792 return -EINVAL;
793
794 switch (parent) {
795 case SI5351_CLKOUT_SRC_MSYNTH_N:
796 val = SI5351_CLK_INPUT_MULTISYNTH_N;
797 break;
798 case SI5351_CLKOUT_SRC_MSYNTH_0_4:
799 /* clk0/clk4 can only connect to its own multisync */
800 if (num == 0 || num == 4)
801 val = SI5351_CLK_INPUT_MULTISYNTH_N;
802 else
803 val = SI5351_CLK_INPUT_MULTISYNTH_0_4;
804 break;
805 case SI5351_CLKOUT_SRC_XTAL:
806 val = SI5351_CLK_INPUT_XTAL;
807 break;
808 case SI5351_CLKOUT_SRC_CLKIN:
809 if (drvdata->variant != SI5351_VARIANT_C)
810 return -EINVAL;
811
812 val = SI5351_CLK_INPUT_CLKIN;
813 break;
814 default:
815 return 0;
816 }
817
818 si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num,
819 SI5351_CLK_INPUT_MASK, val);
820 return 0;
821}
822
823static int _si5351_clkout_set_drive_strength(
824 struct si5351_driver_data *drvdata, int num,
825 enum si5351_drive_strength drive)
826{
827 u8 mask;
828
829 if (num > 8)
830 return -EINVAL;
831
832 switch (drive) {
833 case SI5351_DRIVE_2MA:
834 mask = SI5351_CLK_DRIVE_STRENGTH_2MA;
835 break;
836 case SI5351_DRIVE_4MA:
837 mask = SI5351_CLK_DRIVE_STRENGTH_4MA;
838 break;
839 case SI5351_DRIVE_6MA:
840 mask = SI5351_CLK_DRIVE_STRENGTH_6MA;
841 break;
842 case SI5351_DRIVE_8MA:
843 mask = SI5351_CLK_DRIVE_STRENGTH_8MA;
844 break;
845 default:
846 return 0;
847 }
848
849 si5351_set_bits(drvdata, SI5351_CLK0_CTRL + num,
850 SI5351_CLK_DRIVE_STRENGTH_MASK, mask);
851 return 0;
852}
853
854static int si5351_clkout_prepare(struct clk_hw *hw)
855{
856 struct si5351_hw_data *hwdata =
857 container_of(hw, struct si5351_hw_data, hw);
858
859 si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
860 SI5351_CLK_POWERDOWN, 0);
861 si5351_set_bits(hwdata->drvdata, SI5351_OUTPUT_ENABLE_CTRL,
862 (1 << hwdata->num), 0);
863 return 0;
864}
865
866static void si5351_clkout_unprepare(struct clk_hw *hw)
867{
868 struct si5351_hw_data *hwdata =
869 container_of(hw, struct si5351_hw_data, hw);
870
871 si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
872 SI5351_CLK_POWERDOWN, SI5351_CLK_POWERDOWN);
873 si5351_set_bits(hwdata->drvdata, SI5351_OUTPUT_ENABLE_CTRL,
874 (1 << hwdata->num), (1 << hwdata->num));
875}
876
877static u8 si5351_clkout_get_parent(struct clk_hw *hw)
878{
879 struct si5351_hw_data *hwdata =
880 container_of(hw, struct si5351_hw_data, hw);
881 int index = 0;
882 unsigned char val;
883
884 val = si5351_reg_read(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num);
885 switch (val & SI5351_CLK_INPUT_MASK) {
886 case SI5351_CLK_INPUT_MULTISYNTH_N:
887 index = 0;
888 break;
889 case SI5351_CLK_INPUT_MULTISYNTH_0_4:
890 index = 1;
891 break;
892 case SI5351_CLK_INPUT_XTAL:
893 index = 2;
894 break;
895 case SI5351_CLK_INPUT_CLKIN:
896 index = 3;
897 break;
898 }
899
900 return index;
901}
902
903static int si5351_clkout_set_parent(struct clk_hw *hw, u8 index)
904{
905 struct si5351_hw_data *hwdata =
906 container_of(hw, struct si5351_hw_data, hw);
907 enum si5351_clkout_src parent = SI5351_CLKOUT_SRC_DEFAULT;
908
909 switch (index) {
910 case 0:
911 parent = SI5351_CLKOUT_SRC_MSYNTH_N;
912 break;
913 case 1:
914 parent = SI5351_CLKOUT_SRC_MSYNTH_0_4;
915 break;
916 case 2:
917 parent = SI5351_CLKOUT_SRC_XTAL;
918 break;
919 case 3:
920 parent = SI5351_CLKOUT_SRC_CLKIN;
921 break;
922 }
923
924 return _si5351_clkout_reparent(hwdata->drvdata, hwdata->num, parent);
925}
926
927static unsigned long si5351_clkout_recalc_rate(struct clk_hw *hw,
928 unsigned long parent_rate)
929{
930 struct si5351_hw_data *hwdata =
931 container_of(hw, struct si5351_hw_data, hw);
932 unsigned char reg;
933 unsigned char rdiv;
934
935 if (hwdata->num > 5)
936 reg = si5351_msynth_params_address(hwdata->num) + 2;
937 else
938 reg = SI5351_CLK6_7_OUTPUT_DIVIDER;
939
940 rdiv = si5351_reg_read(hwdata->drvdata, reg);
941 if (hwdata->num == 6) {
942 rdiv &= SI5351_OUTPUT_CLK6_DIV_MASK;
943 } else {
944 rdiv &= SI5351_OUTPUT_CLK_DIV_MASK;
945 rdiv >>= SI5351_OUTPUT_CLK_DIV_SHIFT;
946 }
947
948 return parent_rate >> rdiv;
949}
950
951static long si5351_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
952 unsigned long *parent_rate)
953{
954 struct si5351_hw_data *hwdata =
955 container_of(hw, struct si5351_hw_data, hw);
956 unsigned char rdiv;
957
958 /* clkout6/7 can only handle output freqencies < 150MHz */
959 if (hwdata->num >= 6 && rate > SI5351_CLKOUT67_MAX_FREQ)
960 rate = SI5351_CLKOUT67_MAX_FREQ;
961
962 /* clkout freqency is 8kHz - 160MHz */
963 if (rate > SI5351_CLKOUT_MAX_FREQ)
964 rate = SI5351_CLKOUT_MAX_FREQ;
965 if (rate < SI5351_CLKOUT_MIN_FREQ)
966 rate = SI5351_CLKOUT_MIN_FREQ;
967
968 /* request frequency if multisync master */
969 if (__clk_get_flags(hwdata->hw.clk) & CLK_SET_RATE_PARENT) {
970 /* use r divider for frequencies below 1MHz */
971 rdiv = SI5351_OUTPUT_CLK_DIV_1;
972 while (rate < SI5351_MULTISYNTH_MIN_FREQ &&
973 rdiv < SI5351_OUTPUT_CLK_DIV_128) {
974 rdiv += 1;
975 rate *= 2;
976 }
977 *parent_rate = rate;
978 } else {
979 unsigned long new_rate, new_err, err;
980
981 /* round to closed rdiv */
982 rdiv = SI5351_OUTPUT_CLK_DIV_1;
983 new_rate = *parent_rate;
984 err = abs(new_rate - rate);
985 do {
986 new_rate >>= 1;
987 new_err = abs(new_rate - rate);
988 if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
989 break;
990 rdiv++;
991 err = new_err;
992 } while (1);
993 }
994 rate = *parent_rate >> rdiv;
995
996 dev_dbg(&hwdata->drvdata->client->dev,
997 "%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
998 __func__, __clk_get_name(hwdata->hw.clk), (1 << rdiv),
999 *parent_rate, rate);
1000
1001 return rate;
1002}
1003
1004static int si5351_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
1005 unsigned long parent_rate)
1006{
1007 struct si5351_hw_data *hwdata =
1008 container_of(hw, struct si5351_hw_data, hw);
1009 unsigned long new_rate, new_err, err;
1010 unsigned char rdiv;
1011
1012 /* round to closed rdiv */
1013 rdiv = SI5351_OUTPUT_CLK_DIV_1;
1014 new_rate = parent_rate;
1015 err = abs(new_rate - rate);
1016 do {
1017 new_rate >>= 1;
1018 new_err = abs(new_rate - rate);
1019 if (new_err > err || rdiv == SI5351_OUTPUT_CLK_DIV_128)
1020 break;
1021 rdiv++;
1022 err = new_err;
1023 } while (1);
1024
1025 /* write output divider */
1026 switch (hwdata->num) {
1027 case 6:
1028 si5351_set_bits(hwdata->drvdata, SI5351_CLK6_7_OUTPUT_DIVIDER,
1029 SI5351_OUTPUT_CLK6_DIV_MASK, rdiv);
1030 break;
1031 case 7:
1032 si5351_set_bits(hwdata->drvdata, SI5351_CLK6_7_OUTPUT_DIVIDER,
1033 SI5351_OUTPUT_CLK_DIV_MASK,
1034 rdiv << SI5351_OUTPUT_CLK_DIV_SHIFT);
1035 break;
1036 default:
1037 si5351_set_bits(hwdata->drvdata,
1038 si5351_msynth_params_address(hwdata->num) + 2,
1039 SI5351_OUTPUT_CLK_DIV_MASK,
1040 rdiv << SI5351_OUTPUT_CLK_DIV_SHIFT);
1041 }
1042
1043 /* powerup clkout */
1044 si5351_set_bits(hwdata->drvdata, SI5351_CLK0_CTRL + hwdata->num,
1045 SI5351_CLK_POWERDOWN, 0);
1046
1047 dev_dbg(&hwdata->drvdata->client->dev,
1048 "%s - %s: rdiv = %u, parent_rate = %lu, rate = %lu\n",
1049 __func__, __clk_get_name(hwdata->hw.clk), (1 << rdiv),
1050 parent_rate, rate);
1051
1052 return 0;
1053}
1054
1055static const struct clk_ops si5351_clkout_ops = {
1056 .prepare = si5351_clkout_prepare,
1057 .unprepare = si5351_clkout_unprepare,
1058 .set_parent = si5351_clkout_set_parent,
1059 .get_parent = si5351_clkout_get_parent,
1060 .recalc_rate = si5351_clkout_recalc_rate,
1061 .round_rate = si5351_clkout_round_rate,
1062 .set_rate = si5351_clkout_set_rate,
1063};
1064
1065/*
1066 * Si5351 i2c probe and DT
1067 */
1068#ifdef CONFIG_OF
1069static const struct of_device_id si5351_dt_ids[] = {
1070 { .compatible = "silabs,si5351a", .data = (void *)SI5351_VARIANT_A, },
1071 { .compatible = "silabs,si5351a-msop",
1072 .data = (void *)SI5351_VARIANT_A3, },
1073 { .compatible = "silabs,si5351b", .data = (void *)SI5351_VARIANT_B, },
1074 { .compatible = "silabs,si5351c", .data = (void *)SI5351_VARIANT_C, },
1075 { }
1076};
1077MODULE_DEVICE_TABLE(of, si5351_dt_ids);
1078
1079static int si5351_dt_parse(struct i2c_client *client)
1080{
1081 struct device_node *child, *np = client->dev.of_node;
1082 struct si5351_platform_data *pdata;
1083 const struct of_device_id *match;
1084 struct property *prop;
1085 const __be32 *p;
1086 int num = 0;
1087 u32 val;
1088
1089 if (np == NULL)
1090 return 0;
1091
1092 match = of_match_node(si5351_dt_ids, np);
1093 if (match == NULL)
1094 return -EINVAL;
1095
1096 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
1097 if (!pdata)
1098 return -ENOMEM;
1099
1100 pdata->variant = (enum si5351_variant)match->data;
1101 pdata->clk_xtal = of_clk_get(np, 0);
1102 if (!IS_ERR(pdata->clk_xtal))
1103 clk_put(pdata->clk_xtal);
1104 pdata->clk_clkin = of_clk_get(np, 1);
1105 if (!IS_ERR(pdata->clk_clkin))
1106 clk_put(pdata->clk_clkin);
1107
1108 /*
1109 * property silabs,pll-source : <num src>, [<..>]
1110 * allow to selectively set pll source
1111 */
1112 of_property_for_each_u32(np, "silabs,pll-source", prop, p, num) {
1113 if (num >= 2) {
1114 dev_err(&client->dev,
1115 "invalid pll %d on pll-source prop\n", num);
1116 return -EINVAL;
1117 }
1118
1119 p = of_prop_next_u32(prop, p, &val);
1120 if (!p) {
1121 dev_err(&client->dev,
1122 "missing pll-source for pll %d\n", num);
1123 return -EINVAL;
1124 }
1125
1126 switch (val) {
1127 case 0:
1128 pdata->pll_src[num] = SI5351_PLL_SRC_XTAL;
1129 break;
1130 case 1:
1131 if (pdata->variant != SI5351_VARIANT_C) {
1132 dev_err(&client->dev,
1133 "invalid parent %d for pll %d\n",
1134 val, num);
1135 return -EINVAL;
1136 }
1137 pdata->pll_src[num] = SI5351_PLL_SRC_CLKIN;
1138 break;
1139 default:
1140 dev_err(&client->dev,
1141 "invalid parent %d for pll %d\n", val, num);
1142 return -EINVAL;
1143 }
1144 }
1145
1146 /* per clkout properties */
1147 for_each_child_of_node(np, child) {
1148 if (of_property_read_u32(child, "reg", &num)) {
1149 dev_err(&client->dev, "missing reg property of %s\n",
1150 child->name);
1151 return -EINVAL;
1152 }
1153
1154 if (num >= 8 ||
1155 (pdata->variant == SI5351_VARIANT_A3 && num >= 3)) {
1156 dev_err(&client->dev, "invalid clkout %d\n", num);
1157 return -EINVAL;
1158 }
1159
1160 if (!of_property_read_u32(child, "silabs,multisynth-source",
1161 &val)) {
1162 switch (val) {
1163 case 0:
1164 pdata->clkout[num].multisynth_src =
1165 SI5351_MULTISYNTH_SRC_VCO0;
1166 break;
1167 case 1:
1168 pdata->clkout[num].multisynth_src =
1169 SI5351_MULTISYNTH_SRC_VCO1;
1170 break;
1171 default:
1172 dev_err(&client->dev,
1173 "invalid parent %d for multisynth %d\n",
1174 val, num);
1175 return -EINVAL;
1176 }
1177 }
1178
1179 if (!of_property_read_u32(child, "silabs,clock-source", &val)) {
1180 switch (val) {
1181 case 0:
1182 pdata->clkout[num].clkout_src =
1183 SI5351_CLKOUT_SRC_MSYNTH_N;
1184 break;
1185 case 1:
1186 pdata->clkout[num].clkout_src =
1187 SI5351_CLKOUT_SRC_MSYNTH_0_4;
1188 break;
1189 case 2:
1190 pdata->clkout[num].clkout_src =
1191 SI5351_CLKOUT_SRC_XTAL;
1192 break;
1193 case 3:
1194 if (pdata->variant != SI5351_VARIANT_C) {
1195 dev_err(&client->dev,
1196 "invalid parent %d for clkout %d\n",
1197 val, num);
1198 return -EINVAL;
1199 }
1200 pdata->clkout[num].clkout_src =
1201 SI5351_CLKOUT_SRC_CLKIN;
1202 break;
1203 default:
1204 dev_err(&client->dev,
1205 "invalid parent %d for clkout %d\n",
1206 val, num);
1207 return -EINVAL;
1208 }
1209 }
1210
1211 if (!of_property_read_u32(child, "silabs,drive-strength",
1212 &val)) {
1213 switch (val) {
1214 case SI5351_DRIVE_2MA:
1215 case SI5351_DRIVE_4MA:
1216 case SI5351_DRIVE_6MA:
1217 case SI5351_DRIVE_8MA:
1218 pdata->clkout[num].drive = val;
1219 break;
1220 default:
1221 dev_err(&client->dev,
1222 "invalid drive strength %d for clkout %d\n",
1223 val, num);
1224 return -EINVAL;
1225 }
1226 }
1227
1228 if (!of_property_read_u32(child, "clock-frequency", &val))
1229 pdata->clkout[num].rate = val;
1230
1231 pdata->clkout[num].pll_master =
1232 of_property_read_bool(child, "silabs,pll-master");
1233 }
1234 client->dev.platform_data = pdata;
1235
1236 return 0;
1237}
1238#else
1239static int si5351_dt_parse(struct i2c_client *client)
1240{
1241 return 0;
1242}
1243#endif /* CONFIG_OF */
1244
1245static int si5351_i2c_probe(struct i2c_client *client,
1246 const struct i2c_device_id *id)
1247{
1248 struct si5351_platform_data *pdata;
1249 struct si5351_driver_data *drvdata;
1250 struct clk_init_data init;
1251 struct clk *clk;
1252 const char *parent_names[4];
1253 u8 num_parents, num_clocks;
1254 int ret, n;
1255
1256 ret = si5351_dt_parse(client);
1257 if (ret)
1258 return ret;
1259
1260 pdata = client->dev.platform_data;
1261 if (!pdata)
1262 return -EINVAL;
1263
1264 drvdata = devm_kzalloc(&client->dev, sizeof(*drvdata), GFP_KERNEL);
1265 if (drvdata == NULL) {
1266 dev_err(&client->dev, "unable to allocate driver data\n");
1267 return -ENOMEM;
1268 }
1269
1270 i2c_set_clientdata(client, drvdata);
1271 drvdata->client = client;
1272 drvdata->variant = pdata->variant;
1273 drvdata->pxtal = pdata->clk_xtal;
1274 drvdata->pclkin = pdata->clk_clkin;
1275
1276 drvdata->regmap = devm_regmap_init_i2c(client, &si5351_regmap_config);
1277 if (IS_ERR(drvdata->regmap)) {
1278 dev_err(&client->dev, "failed to allocate register map\n");
1279 return PTR_ERR(drvdata->regmap);
1280 }
1281
1282 /* Disable interrupts */
1283 si5351_reg_write(drvdata, SI5351_INTERRUPT_MASK, 0xf0);
1284 /* Set disabled output drivers to drive low */
1285 si5351_reg_write(drvdata, SI5351_CLK3_0_DISABLE_STATE, 0x00);
1286 si5351_reg_write(drvdata, SI5351_CLK7_4_DISABLE_STATE, 0x00);
1287 /* Ensure pll select is on XTAL for Si5351A/B */
1288 if (drvdata->variant != SI5351_VARIANT_C)
1289 si5351_set_bits(drvdata, SI5351_PLL_INPUT_SOURCE,
1290 SI5351_PLLA_SOURCE | SI5351_PLLB_SOURCE, 0);
1291
1292 /* setup clock configuration */
1293 for (n = 0; n < 2; n++) {
1294 ret = _si5351_pll_reparent(drvdata, n, pdata->pll_src[n]);
1295 if (ret) {
1296 dev_err(&client->dev,
1297 "failed to reparent pll %d to %d\n",
1298 n, pdata->pll_src[n]);
1299 return ret;
1300 }
1301 }
1302
1303 for (n = 0; n < 8; n++) {
1304 ret = _si5351_msynth_reparent(drvdata, n,
1305 pdata->clkout[n].multisynth_src);
1306 if (ret) {
1307 dev_err(&client->dev,
1308 "failed to reparent multisynth %d to %d\n",
1309 n, pdata->clkout[n].multisynth_src);
1310 return ret;
1311 }
1312
1313 ret = _si5351_clkout_reparent(drvdata, n,
1314 pdata->clkout[n].clkout_src);
1315 if (ret) {
1316 dev_err(&client->dev,
1317 "failed to reparent clkout %d to %d\n",
1318 n, pdata->clkout[n].clkout_src);
1319 return ret;
1320 }
1321
1322 ret = _si5351_clkout_set_drive_strength(drvdata, n,
1323 pdata->clkout[n].drive);
1324 if (ret) {
1325 dev_err(&client->dev,
1326 "failed set drive strength of clkout%d to %d\n",
1327 n, pdata->clkout[n].drive);
1328 return ret;
1329 }
1330 }
1331
1332 /* register xtal input clock gate */
1333 memset(&init, 0, sizeof(init));
1334 init.name = si5351_input_names[0];
1335 init.ops = &si5351_xtal_ops;
1336 init.flags = 0;
1337 if (!IS_ERR(drvdata->pxtal)) {
1338 drvdata->pxtal_name = __clk_get_name(drvdata->pxtal);
1339 init.parent_names = &drvdata->pxtal_name;
1340 init.num_parents = 1;
1341 }
1342 drvdata->xtal.init = &init;
1343 clk = devm_clk_register(&client->dev, &drvdata->xtal);
1344 if (IS_ERR(clk)) {
1345 dev_err(&client->dev, "unable to register %s\n", init.name);
1346 return PTR_ERR(clk);
1347 }
1348
1349 /* register clkin input clock gate */
1350 if (drvdata->variant == SI5351_VARIANT_C) {
1351 memset(&init, 0, sizeof(init));
1352 init.name = si5351_input_names[1];
1353 init.ops = &si5351_clkin_ops;
1354 if (!IS_ERR(drvdata->pclkin)) {
1355 drvdata->pclkin_name = __clk_get_name(drvdata->pclkin);
1356 init.parent_names = &drvdata->pclkin_name;
1357 init.num_parents = 1;
1358 }
1359 drvdata->clkin.init = &init;
1360 clk = devm_clk_register(&client->dev, &drvdata->clkin);
1361 if (IS_ERR(clk)) {
1362 dev_err(&client->dev, "unable to register %s\n",
1363 init.name);
1364 return PTR_ERR(clk);
1365 }
1366 }
1367
1368 /* Si5351C allows to mux either xtal or clkin to PLL input */
1369 num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 2 : 1;
1370 parent_names[0] = si5351_input_names[0];
1371 parent_names[1] = si5351_input_names[1];
1372
1373 /* register PLLA */
1374 drvdata->pll[0].num = 0;
1375 drvdata->pll[0].drvdata = drvdata;
1376 drvdata->pll[0].hw.init = &init;
1377 memset(&init, 0, sizeof(init));
1378 init.name = si5351_pll_names[0];
1379 init.ops = &si5351_pll_ops;
1380 init.flags = 0;
1381 init.parent_names = parent_names;
1382 init.num_parents = num_parents;
1383 clk = devm_clk_register(&client->dev, &drvdata->pll[0].hw);
1384 if (IS_ERR(clk)) {
1385 dev_err(&client->dev, "unable to register %s\n", init.name);
1386 return -EINVAL;
1387 }
1388
1389 /* register PLLB or VXCO (Si5351B) */
1390 drvdata->pll[1].num = 1;
1391 drvdata->pll[1].drvdata = drvdata;
1392 drvdata->pll[1].hw.init = &init;
1393 memset(&init, 0, sizeof(init));
1394 if (drvdata->variant == SI5351_VARIANT_B) {
1395 init.name = si5351_pll_names[2];
1396 init.ops = &si5351_vxco_ops;
1397 init.flags = CLK_IS_ROOT;
1398 init.parent_names = NULL;
1399 init.num_parents = 0;
1400 } else {
1401 init.name = si5351_pll_names[1];
1402 init.ops = &si5351_pll_ops;
1403 init.flags = 0;
1404 init.parent_names = parent_names;
1405 init.num_parents = num_parents;
1406 }
1407 clk = devm_clk_register(&client->dev, &drvdata->pll[1].hw);
1408 if (IS_ERR(clk)) {
1409 dev_err(&client->dev, "unable to register %s\n", init.name);
1410 return -EINVAL;
1411 }
1412
1413 /* register clk multisync and clk out divider */
1414 num_clocks = (drvdata->variant == SI5351_VARIANT_A3) ? 3 : 8;
1415 parent_names[0] = si5351_pll_names[0];
1416 if (drvdata->variant == SI5351_VARIANT_B)
1417 parent_names[1] = si5351_pll_names[2];
1418 else
1419 parent_names[1] = si5351_pll_names[1];
1420
1421 drvdata->msynth = devm_kzalloc(&client->dev, num_clocks *
1422 sizeof(*drvdata->msynth), GFP_KERNEL);
1423 drvdata->clkout = devm_kzalloc(&client->dev, num_clocks *
1424 sizeof(*drvdata->clkout), GFP_KERNEL);
1425
1426 drvdata->onecell.clk_num = num_clocks;
1427 drvdata->onecell.clks = devm_kzalloc(&client->dev,
1428 num_clocks * sizeof(*drvdata->onecell.clks), GFP_KERNEL);
1429
1430 if (WARN_ON(!drvdata->msynth || !drvdata->clkout ||
1431 !drvdata->onecell.clks))
1432 return -ENOMEM;
1433
1434 for (n = 0; n < num_clocks; n++) {
1435 drvdata->msynth[n].num = n;
1436 drvdata->msynth[n].drvdata = drvdata;
1437 drvdata->msynth[n].hw.init = &init;
1438 memset(&init, 0, sizeof(init));
1439 init.name = si5351_msynth_names[n];
1440 init.ops = &si5351_msynth_ops;
1441 init.flags = 0;
1442 if (pdata->clkout[n].pll_master)
1443 init.flags |= CLK_SET_RATE_PARENT;
1444 init.parent_names = parent_names;
1445 init.num_parents = 2;
1446 clk = devm_clk_register(&client->dev, &drvdata->msynth[n].hw);
1447 if (IS_ERR(clk)) {
1448 dev_err(&client->dev, "unable to register %s\n",
1449 init.name);
1450 return -EINVAL;
1451 }
1452 }
1453
1454 num_parents = (drvdata->variant == SI5351_VARIANT_C) ? 4 : 3;
1455 parent_names[2] = si5351_input_names[0];
1456 parent_names[3] = si5351_input_names[1];
1457 for (n = 0; n < num_clocks; n++) {
1458 parent_names[0] = si5351_msynth_names[n];
1459 parent_names[1] = (n < 4) ? si5351_msynth_names[0] :
1460 si5351_msynth_names[4];
1461
1462 drvdata->clkout[n].num = n;
1463 drvdata->clkout[n].drvdata = drvdata;
1464 drvdata->clkout[n].hw.init = &init;
1465 memset(&init, 0, sizeof(init));
1466 init.name = si5351_clkout_names[n];
1467 init.ops = &si5351_clkout_ops;
1468 init.flags = 0;
1469 if (pdata->clkout[n].clkout_src == SI5351_CLKOUT_SRC_MSYNTH_N)
1470 init.flags |= CLK_SET_RATE_PARENT;
1471 init.parent_names = parent_names;
1472 init.num_parents = num_parents;
1473 clk = devm_clk_register(&client->dev, &drvdata->clkout[n].hw);
1474 if (IS_ERR(clk)) {
1475 dev_err(&client->dev, "unable to register %s\n",
1476 init.name);
1477 return -EINVAL;
1478 }
1479 drvdata->onecell.clks[n] = clk;
1480 }
1481
1482 ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get,
1483 &drvdata->onecell);
1484 if (ret) {
1485 dev_err(&client->dev, "unable to add clk provider\n");
1486 return ret;
1487 }
1488
1489 return 0;
1490}
1491
1492static const struct i2c_device_id si5351_i2c_ids[] = {
1493 { "silabs,si5351", 0 },
1494 { }
1495};
1496MODULE_DEVICE_TABLE(i2c, si5351_i2c_ids);
1497
1498static struct i2c_driver si5351_driver = {
1499 .driver = {
1500 .name = "si5351",
1501 .of_match_table = of_match_ptr(si5351_dt_ids),
1502 },
1503 .probe = si5351_i2c_probe,
1504 .id_table = si5351_i2c_ids,
1505};
1506module_i2c_driver(si5351_driver);
1507
1508MODULE_AUTHOR("Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com");
1509MODULE_DESCRIPTION("Silicon Labs Si5351A/B/C clock generator driver");
1510MODULE_LICENSE("GPL");
diff --git a/drivers/clk/clk-si5351.h b/drivers/clk/clk-si5351.h
new file mode 100644
index 000000000000..af41b5080f43
--- /dev/null
+++ b/drivers/clk/clk-si5351.h
@@ -0,0 +1,155 @@
1/*
2 * clk-si5351.h: Silicon Laboratories Si5351A/B/C I2C Clock Generator
3 *
4 * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
5 * Rabeeh Khoury <rabeeh@solid-run.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#ifndef _CLK_SI5351_H_
14#define _CLK_SI5351_H_
15
16#define SI5351_BUS_BASE_ADDR 0x60
17
18#define SI5351_PLL_VCO_MIN 600000000
19#define SI5351_PLL_VCO_MAX 900000000
20#define SI5351_MULTISYNTH_MIN_FREQ 1000000
21#define SI5351_MULTISYNTH_DIVBY4_FREQ 150000000
22#define SI5351_MULTISYNTH_MAX_FREQ 160000000
23#define SI5351_MULTISYNTH67_MAX_FREQ SI5351_MULTISYNTH_DIVBY4_FREQ
24#define SI5351_CLKOUT_MIN_FREQ 8000
25#define SI5351_CLKOUT_MAX_FREQ SI5351_MULTISYNTH_MAX_FREQ
26#define SI5351_CLKOUT67_MAX_FREQ SI5351_MULTISYNTH67_MAX_FREQ
27
28#define SI5351_PLL_A_MIN 15
29#define SI5351_PLL_A_MAX 90
30#define SI5351_PLL_B_MAX (SI5351_PLL_C_MAX-1)
31#define SI5351_PLL_C_MAX 1048575
32#define SI5351_MULTISYNTH_A_MIN 6
33#define SI5351_MULTISYNTH_A_MAX 1800
34#define SI5351_MULTISYNTH67_A_MAX 254
35#define SI5351_MULTISYNTH_B_MAX (SI5351_MULTISYNTH_C_MAX-1)
36#define SI5351_MULTISYNTH_C_MAX 1048575
37#define SI5351_MULTISYNTH_P1_MAX ((1<<18)-1)
38#define SI5351_MULTISYNTH_P2_MAX ((1<<20)-1)
39#define SI5351_MULTISYNTH_P3_MAX ((1<<20)-1)
40
41#define SI5351_DEVICE_STATUS 0
42#define SI5351_INTERRUPT_STATUS 1
43#define SI5351_INTERRUPT_MASK 2
44#define SI5351_STATUS_SYS_INIT (1<<7)
45#define SI5351_STATUS_LOL_B (1<<6)
46#define SI5351_STATUS_LOL_A (1<<5)
47#define SI5351_STATUS_LOS (1<<4)
48#define SI5351_OUTPUT_ENABLE_CTRL 3
49#define SI5351_OEB_PIN_ENABLE_CTRL 9
50#define SI5351_PLL_INPUT_SOURCE 15
51#define SI5351_CLKIN_DIV_MASK (3<<6)
52#define SI5351_CLKIN_DIV_1 (0<<6)
53#define SI5351_CLKIN_DIV_2 (1<<6)
54#define SI5351_CLKIN_DIV_4 (2<<6)
55#define SI5351_CLKIN_DIV_8 (3<<6)
56#define SI5351_PLLB_SOURCE (1<<3)
57#define SI5351_PLLA_SOURCE (1<<2)
58
59#define SI5351_CLK0_CTRL 16
60#define SI5351_CLK1_CTRL 17
61#define SI5351_CLK2_CTRL 18
62#define SI5351_CLK3_CTRL 19
63#define SI5351_CLK4_CTRL 20
64#define SI5351_CLK5_CTRL 21
65#define SI5351_CLK6_CTRL 22
66#define SI5351_CLK7_CTRL 23
67#define SI5351_CLK_POWERDOWN (1<<7)
68#define SI5351_CLK_INTEGER_MODE (1<<6)
69#define SI5351_CLK_PLL_SELECT (1<<5)
70#define SI5351_CLK_INVERT (1<<4)
71#define SI5351_CLK_INPUT_MASK (3<<2)
72#define SI5351_CLK_INPUT_XTAL (0<<2)
73#define SI5351_CLK_INPUT_CLKIN (1<<2)
74#define SI5351_CLK_INPUT_MULTISYNTH_0_4 (2<<2)
75#define SI5351_CLK_INPUT_MULTISYNTH_N (3<<2)
76#define SI5351_CLK_DRIVE_STRENGTH_MASK (3<<0)
77#define SI5351_CLK_DRIVE_STRENGTH_2MA (0<<0)
78#define SI5351_CLK_DRIVE_STRENGTH_4MA (1<<0)
79#define SI5351_CLK_DRIVE_STRENGTH_6MA (2<<0)
80#define SI5351_CLK_DRIVE_STRENGTH_8MA (3<<0)
81
82#define SI5351_CLK3_0_DISABLE_STATE 24
83#define SI5351_CLK7_4_DISABLE_STATE 25
84#define SI5351_CLK_DISABLE_STATE_LOW 0
85#define SI5351_CLK_DISABLE_STATE_HIGH 1
86#define SI5351_CLK_DISABLE_STATE_FLOAT 2
87#define SI5351_CLK_DISABLE_STATE_NEVER 3
88
89#define SI5351_PARAMETERS_LENGTH 8
90#define SI5351_PLLA_PARAMETERS 26
91#define SI5351_PLLB_PARAMETERS 34
92#define SI5351_CLK0_PARAMETERS 42
93#define SI5351_CLK1_PARAMETERS 50
94#define SI5351_CLK2_PARAMETERS 58
95#define SI5351_CLK3_PARAMETERS 66
96#define SI5351_CLK4_PARAMETERS 74
97#define SI5351_CLK5_PARAMETERS 82
98#define SI5351_CLK6_PARAMETERS 90
99#define SI5351_CLK7_PARAMETERS 91
100#define SI5351_CLK6_7_OUTPUT_DIVIDER 92
101#define SI5351_OUTPUT_CLK_DIV_MASK (7 << 4)
102#define SI5351_OUTPUT_CLK6_DIV_MASK (7 << 0)
103#define SI5351_OUTPUT_CLK_DIV_SHIFT 4
104#define SI5351_OUTPUT_CLK_DIV6_SHIFT 0
105#define SI5351_OUTPUT_CLK_DIV_1 0
106#define SI5351_OUTPUT_CLK_DIV_2 1
107#define SI5351_OUTPUT_CLK_DIV_4 2
108#define SI5351_OUTPUT_CLK_DIV_8 3
109#define SI5351_OUTPUT_CLK_DIV_16 4
110#define SI5351_OUTPUT_CLK_DIV_32 5
111#define SI5351_OUTPUT_CLK_DIV_64 6
112#define SI5351_OUTPUT_CLK_DIV_128 7
113#define SI5351_OUTPUT_CLK_DIVBY4 (3<<2)
114
115#define SI5351_SSC_PARAM0 149
116#define SI5351_SSC_PARAM1 150
117#define SI5351_SSC_PARAM2 151
118#define SI5351_SSC_PARAM3 152
119#define SI5351_SSC_PARAM4 153
120#define SI5351_SSC_PARAM5 154
121#define SI5351_SSC_PARAM6 155
122#define SI5351_SSC_PARAM7 156
123#define SI5351_SSC_PARAM8 157
124#define SI5351_SSC_PARAM9 158
125#define SI5351_SSC_PARAM10 159
126#define SI5351_SSC_PARAM11 160
127#define SI5351_SSC_PARAM12 161
128
129#define SI5351_VXCO_PARAMETERS_LOW 162
130#define SI5351_VXCO_PARAMETERS_MID 163
131#define SI5351_VXCO_PARAMETERS_HIGH 164
132
133#define SI5351_CLK0_PHASE_OFFSET 165
134#define SI5351_CLK1_PHASE_OFFSET 166
135#define SI5351_CLK2_PHASE_OFFSET 167
136#define SI5351_CLK3_PHASE_OFFSET 168
137#define SI5351_CLK4_PHASE_OFFSET 169
138#define SI5351_CLK5_PHASE_OFFSET 170
139
140#define SI5351_PLL_RESET 177
141#define SI5351_PLL_RESET_B (1<<7)
142#define SI5351_PLL_RESET_A (1<<5)
143
144#define SI5351_CRYSTAL_LOAD 183
145#define SI5351_CRYSTAL_LOAD_MASK (3<<6)
146#define SI5351_CRYSTAL_LOAD_6PF (1<<6)
147#define SI5351_CRYSTAL_LOAD_8PF (2<<6)
148#define SI5351_CRYSTAL_LOAD_10PF (3<<6)
149
150#define SI5351_FANOUT_ENABLE 187
151#define SI5351_CLKIN_ENABLE (1<<7)
152#define SI5351_XTAL_ENABLE (1<<6)
153#define SI5351_MULTISYNTH_ENABLE (1<<4)
154
155#endif
diff --git a/include/linux/platform_data/si5351.h b/include/linux/platform_data/si5351.h
new file mode 100644
index 000000000000..92dabcaf6499
--- /dev/null
+++ b/include/linux/platform_data/si5351.h
@@ -0,0 +1,114 @@
1/*
2 * Si5351A/B/C programmable clock generator platform_data.
3 */
4
5#ifndef __LINUX_PLATFORM_DATA_SI5351_H__
6#define __LINUX_PLATFORM_DATA_SI5351_H__
7
8struct clk;
9
10/**
11 * enum si5351_variant - SiLabs Si5351 chip variant
12 * @SI5351_VARIANT_A: Si5351A (8 output clocks, XTAL input)
13 * @SI5351_VARIANT_A3: Si5351A MSOP10 (3 output clocks, XTAL input)
14 * @SI5351_VARIANT_B: Si5351B (8 output clocks, XTAL/VXCO input)
15 * @SI5351_VARIANT_C: Si5351C (8 output clocks, XTAL/CLKIN input)
16 */
17enum si5351_variant {
18 SI5351_VARIANT_A = 1,
19 SI5351_VARIANT_A3 = 2,
20 SI5351_VARIANT_B = 3,
21 SI5351_VARIANT_C = 4,
22};
23
24/**
25 * enum si5351_pll_src - Si5351 pll clock source
26 * @SI5351_PLL_SRC_DEFAULT: default, do not change eeprom config
27 * @SI5351_PLL_SRC_XTAL: pll source clock is XTAL input
28 * @SI5351_PLL_SRC_CLKIN: pll source clock is CLKIN input (Si5351C only)
29 */
30enum si5351_pll_src {
31 SI5351_PLL_SRC_DEFAULT = 0,
32 SI5351_PLL_SRC_XTAL = 1,
33 SI5351_PLL_SRC_CLKIN = 2,
34};
35
36/**
37 * enum si5351_multisynth_src - Si5351 multisynth clock source
38 * @SI5351_MULTISYNTH_SRC_DEFAULT: default, do not change eeprom config
39 * @SI5351_MULTISYNTH_SRC_VCO0: multisynth source clock is VCO0
40 * @SI5351_MULTISYNTH_SRC_VCO1: multisynth source clock is VCO1/VXCO
41 */
42enum si5351_multisynth_src {
43 SI5351_MULTISYNTH_SRC_DEFAULT = 0,
44 SI5351_MULTISYNTH_SRC_VCO0 = 1,
45 SI5351_MULTISYNTH_SRC_VCO1 = 2,
46};
47
48/**
49 * enum si5351_clkout_src - Si5351 clock output clock source
50 * @SI5351_CLKOUT_SRC_DEFAULT: default, do not change eeprom config
51 * @SI5351_CLKOUT_SRC_MSYNTH_N: clkout N source clock is multisynth N
52 * @SI5351_CLKOUT_SRC_MSYNTH_0_4: clkout N source clock is multisynth 0 (N<4)
53 * or 4 (N>=4)
54 * @SI5351_CLKOUT_SRC_XTAL: clkout N source clock is XTAL
55 * @SI5351_CLKOUT_SRC_CLKIN: clkout N source clock is CLKIN (Si5351C only)
56 */
57enum si5351_clkout_src {
58 SI5351_CLKOUT_SRC_DEFAULT = 0,
59 SI5351_CLKOUT_SRC_MSYNTH_N = 1,
60 SI5351_CLKOUT_SRC_MSYNTH_0_4 = 2,
61 SI5351_CLKOUT_SRC_XTAL = 3,
62 SI5351_CLKOUT_SRC_CLKIN = 4,
63};
64
65/**
66 * enum si5351_drive_strength - Si5351 clock output drive strength
67 * @SI5351_DRIVE_DEFAULT: default, do not change eeprom config
68 * @SI5351_DRIVE_2MA: 2mA clock output drive strength
69 * @SI5351_DRIVE_4MA: 4mA clock output drive strength
70 * @SI5351_DRIVE_6MA: 6mA clock output drive strength
71 * @SI5351_DRIVE_8MA: 8mA clock output drive strength
72 */
73enum si5351_drive_strength {
74 SI5351_DRIVE_DEFAULT = 0,
75 SI5351_DRIVE_2MA = 2,
76 SI5351_DRIVE_4MA = 4,
77 SI5351_DRIVE_6MA = 6,
78 SI5351_DRIVE_8MA = 8,
79};
80
81/**
82 * struct si5351_clkout_config - Si5351 clock output configuration
83 * @clkout: clkout number
84 * @multisynth_src: multisynth source clock
85 * @clkout_src: clkout source clock
86 * @pll_master: if true, clkout can also change pll rate
87 * @drive: output drive strength
88 * @rate: initial clkout rate, or default if 0
89 */
90struct si5351_clkout_config {
91 enum si5351_multisynth_src multisynth_src;
92 enum si5351_clkout_src clkout_src;
93 enum si5351_drive_strength drive;
94 bool pll_master;
95 unsigned long rate;
96};
97
98/**
99 * struct si5351_platform_data - Platform data for the Si5351 clock driver
100 * @variant: Si5351 chip variant
101 * @clk_xtal: xtal input clock
102 * @clk_clkin: clkin input clock
103 * @pll_src: array of pll source clock setting
104 * @clkout: array of clkout configuration
105 */
106struct si5351_platform_data {
107 enum si5351_variant variant;
108 struct clk *clk_xtal;
109 struct clk *clk_clkin;
110 enum si5351_pll_src pll_src[2];
111 struct si5351_clkout_config clkout[8];
112};
113
114#endif