xref: /openbmc/linux/drivers/clk/clk-cdce706.c (revision d7a3d85e)
1 /*
2  * TI CDCE706 programmable 3-PLL clock synthesizer driver
3  *
4  * Copyright (c) 2014 Cadence Design Systems Inc.
5  *
6  * Reference: http://www.ti.com/lit/ds/symlink/cdce706.pdf
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 as
10  * published by the Free Software Foundation.
11  */
12 
13 #include <linux/clk-provider.h>
14 #include <linux/delay.h>
15 #include <linux/i2c.h>
16 #include <linux/interrupt.h>
17 #include <linux/mod_devicetable.h>
18 #include <linux/module.h>
19 #include <linux/of.h>
20 #include <linux/rational.h>
21 #include <linux/regmap.h>
22 #include <linux/slab.h>
23 
24 #define CDCE706_CLKIN_CLOCK		10
25 #define CDCE706_CLKIN_SOURCE		11
26 #define CDCE706_PLL_M_LOW(pll)		(1 + 3 * (pll))
27 #define CDCE706_PLL_N_LOW(pll)		(2 + 3 * (pll))
28 #define CDCE706_PLL_HI(pll)		(3 + 3 * (pll))
29 #define CDCE706_PLL_MUX			3
30 #define CDCE706_PLL_FVCO		6
31 #define CDCE706_DIVIDER(div)		(13 + (div))
32 #define CDCE706_CLKOUT(out)		(19 + (out))
33 
34 #define CDCE706_CLKIN_CLOCK_MASK	0x10
35 #define CDCE706_CLKIN_SOURCE_SHIFT	6
36 #define CDCE706_CLKIN_SOURCE_MASK	0xc0
37 #define CDCE706_CLKIN_SOURCE_LVCMOS	0x40
38 
39 #define CDCE706_PLL_MUX_MASK(pll)	(0x80 >> (pll))
40 #define CDCE706_PLL_LOW_M_MASK		0xff
41 #define CDCE706_PLL_LOW_N_MASK		0xff
42 #define CDCE706_PLL_HI_M_MASK		0x1
43 #define CDCE706_PLL_HI_N_MASK		0x1e
44 #define CDCE706_PLL_HI_N_SHIFT		1
45 #define CDCE706_PLL_M_MAX		0x1ff
46 #define CDCE706_PLL_N_MAX		0xfff
47 #define CDCE706_PLL_FVCO_MASK(pll)	(0x80 >> (pll))
48 #define CDCE706_PLL_FREQ_MIN		 80000000
49 #define CDCE706_PLL_FREQ_MAX		300000000
50 #define CDCE706_PLL_FREQ_HI		180000000
51 
52 #define CDCE706_DIVIDER_PLL(div)	(9 + (div) - ((div) > 2) - ((div) > 4))
53 #define CDCE706_DIVIDER_PLL_SHIFT(div)	((div) < 2 ? 5 : 3 * ((div) & 1))
54 #define CDCE706_DIVIDER_PLL_MASK(div)	(0x7 << CDCE706_DIVIDER_PLL_SHIFT(div))
55 #define CDCE706_DIVIDER_DIVIDER_MASK	0x7f
56 #define CDCE706_DIVIDER_DIVIDER_MAX	0x7f
57 
58 #define CDCE706_CLKOUT_DIVIDER_MASK	0x7
59 #define CDCE706_CLKOUT_ENABLE_MASK	0x8
60 
61 static const struct regmap_config cdce706_regmap_config = {
62 	.reg_bits = 8,
63 	.val_bits = 8,
64 	.val_format_endian = REGMAP_ENDIAN_NATIVE,
65 };
66 
67 #define to_hw_data(phw) (container_of((phw), struct cdce706_hw_data, hw))
68 
69 struct cdce706_hw_data {
70 	struct cdce706_dev_data *dev_data;
71 	unsigned idx;
72 	unsigned parent;
73 	struct clk *clk;
74 	struct clk_hw hw;
75 	unsigned div;
76 	unsigned mul;
77 	unsigned mux;
78 };
79 
80 struct cdce706_dev_data {
81 	struct i2c_client *client;
82 	struct regmap *regmap;
83 	struct clk_onecell_data onecell;
84 	struct clk *clks[6];
85 	struct clk *clkin_clk[2];
86 	const char *clkin_name[2];
87 	struct cdce706_hw_data clkin[1];
88 	struct cdce706_hw_data pll[3];
89 	struct cdce706_hw_data divider[6];
90 	struct cdce706_hw_data clkout[6];
91 };
92 
93 static const char * const cdce706_source_name[] = {
94 	"clk_in0", "clk_in1",
95 };
96 
97 static const char *cdce706_clkin_name[] = {
98 	"clk_in",
99 };
100 
101 static const char * const cdce706_pll_name[] = {
102 	"pll1", "pll2", "pll3",
103 };
104 
105 static const char *cdce706_divider_parent_name[] = {
106 	"clk_in", "pll1", "pll2", "pll2", "pll3",
107 };
108 
109 static const char *cdce706_divider_name[] = {
110 	"p0", "p1", "p2", "p3", "p4", "p5",
111 };
112 
113 static const char * const cdce706_clkout_name[] = {
114 	"clk_out0", "clk_out1", "clk_out2", "clk_out3", "clk_out4", "clk_out5",
115 };
116 
117 static int cdce706_reg_read(struct cdce706_dev_data *dev_data, unsigned reg,
118 			    unsigned *val)
119 {
120 	int rc = regmap_read(dev_data->regmap, reg | 0x80, val);
121 
122 	if (rc < 0)
123 		dev_err(&dev_data->client->dev, "error reading reg %u", reg);
124 	return rc;
125 }
126 
127 static int cdce706_reg_write(struct cdce706_dev_data *dev_data, unsigned reg,
128 			     unsigned val)
129 {
130 	int rc = regmap_write(dev_data->regmap, reg | 0x80, val);
131 
132 	if (rc < 0)
133 		dev_err(&dev_data->client->dev, "error writing reg %u", reg);
134 	return rc;
135 }
136 
137 static int cdce706_reg_update(struct cdce706_dev_data *dev_data, unsigned reg,
138 			      unsigned mask, unsigned val)
139 {
140 	int rc = regmap_update_bits(dev_data->regmap, reg | 0x80, mask, val);
141 
142 	if (rc < 0)
143 		dev_err(&dev_data->client->dev, "error updating reg %u", reg);
144 	return rc;
145 }
146 
147 static int cdce706_clkin_set_parent(struct clk_hw *hw, u8 index)
148 {
149 	struct cdce706_hw_data *hwd = to_hw_data(hw);
150 
151 	hwd->parent = index;
152 	return 0;
153 }
154 
155 static u8 cdce706_clkin_get_parent(struct clk_hw *hw)
156 {
157 	struct cdce706_hw_data *hwd = to_hw_data(hw);
158 
159 	return hwd->parent;
160 }
161 
162 static const struct clk_ops cdce706_clkin_ops = {
163 	.set_parent = cdce706_clkin_set_parent,
164 	.get_parent = cdce706_clkin_get_parent,
165 };
166 
167 static unsigned long cdce706_pll_recalc_rate(struct clk_hw *hw,
168 					     unsigned long parent_rate)
169 {
170 	struct cdce706_hw_data *hwd = to_hw_data(hw);
171 
172 	dev_dbg(&hwd->dev_data->client->dev,
173 		"%s, pll: %d, mux: %d, mul: %u, div: %u\n",
174 		__func__, hwd->idx, hwd->mux, hwd->mul, hwd->div);
175 
176 	if (!hwd->mux) {
177 		if (hwd->div && hwd->mul) {
178 			u64 res = (u64)parent_rate * hwd->mul;
179 
180 			do_div(res, hwd->div);
181 			return res;
182 		}
183 	} else {
184 		if (hwd->div)
185 			return parent_rate / hwd->div;
186 	}
187 	return 0;
188 }
189 
190 static long cdce706_pll_round_rate(struct clk_hw *hw, unsigned long rate,
191 				   unsigned long *parent_rate)
192 {
193 	struct cdce706_hw_data *hwd = to_hw_data(hw);
194 	unsigned long mul, div;
195 	u64 res;
196 
197 	dev_dbg(&hwd->dev_data->client->dev,
198 		"%s, rate: %lu, parent_rate: %lu\n",
199 		__func__, rate, *parent_rate);
200 
201 	rational_best_approximation(rate, *parent_rate,
202 				    CDCE706_PLL_N_MAX, CDCE706_PLL_M_MAX,
203 				    &mul, &div);
204 	hwd->mul = mul;
205 	hwd->div = div;
206 
207 	dev_dbg(&hwd->dev_data->client->dev,
208 		"%s, pll: %d, mul: %lu, div: %lu\n",
209 		__func__, hwd->idx, mul, div);
210 
211 	res = (u64)*parent_rate * hwd->mul;
212 	do_div(res, hwd->div);
213 	return res;
214 }
215 
216 static int cdce706_pll_set_rate(struct clk_hw *hw, unsigned long rate,
217 				unsigned long parent_rate)
218 {
219 	struct cdce706_hw_data *hwd = to_hw_data(hw);
220 	unsigned long mul = hwd->mul, div = hwd->div;
221 	int err;
222 
223 	dev_dbg(&hwd->dev_data->client->dev,
224 		"%s, pll: %d, mul: %lu, div: %lu\n",
225 		__func__, hwd->idx, mul, div);
226 
227 	err = cdce706_reg_update(hwd->dev_data,
228 				 CDCE706_PLL_HI(hwd->idx),
229 				 CDCE706_PLL_HI_M_MASK | CDCE706_PLL_HI_N_MASK,
230 				 ((div >> 8) & CDCE706_PLL_HI_M_MASK) |
231 				 ((mul >> (8 - CDCE706_PLL_HI_N_SHIFT)) &
232 				  CDCE706_PLL_HI_N_MASK));
233 	if (err < 0)
234 		return err;
235 
236 	err = cdce706_reg_write(hwd->dev_data,
237 				CDCE706_PLL_M_LOW(hwd->idx),
238 				div & CDCE706_PLL_LOW_M_MASK);
239 	if (err < 0)
240 		return err;
241 
242 	err = cdce706_reg_write(hwd->dev_data,
243 				CDCE706_PLL_N_LOW(hwd->idx),
244 				mul & CDCE706_PLL_LOW_N_MASK);
245 	if (err < 0)
246 		return err;
247 
248 	err = cdce706_reg_update(hwd->dev_data,
249 				 CDCE706_PLL_FVCO,
250 				 CDCE706_PLL_FVCO_MASK(hwd->idx),
251 				 rate > CDCE706_PLL_FREQ_HI ?
252 				 CDCE706_PLL_FVCO_MASK(hwd->idx) : 0);
253 	return err;
254 }
255 
256 static const struct clk_ops cdce706_pll_ops = {
257 	.recalc_rate = cdce706_pll_recalc_rate,
258 	.round_rate = cdce706_pll_round_rate,
259 	.set_rate = cdce706_pll_set_rate,
260 };
261 
262 static int cdce706_divider_set_parent(struct clk_hw *hw, u8 index)
263 {
264 	struct cdce706_hw_data *hwd = to_hw_data(hw);
265 
266 	if (hwd->parent == index)
267 		return 0;
268 	hwd->parent = index;
269 	return cdce706_reg_update(hwd->dev_data,
270 				  CDCE706_DIVIDER_PLL(hwd->idx),
271 				  CDCE706_DIVIDER_PLL_MASK(hwd->idx),
272 				  index << CDCE706_DIVIDER_PLL_SHIFT(hwd->idx));
273 }
274 
275 static u8 cdce706_divider_get_parent(struct clk_hw *hw)
276 {
277 	struct cdce706_hw_data *hwd = to_hw_data(hw);
278 
279 	return hwd->parent;
280 }
281 
282 static unsigned long cdce706_divider_recalc_rate(struct clk_hw *hw,
283 						 unsigned long parent_rate)
284 {
285 	struct cdce706_hw_data *hwd = to_hw_data(hw);
286 
287 	dev_dbg(&hwd->dev_data->client->dev,
288 		"%s, divider: %d, div: %u\n",
289 		__func__, hwd->idx, hwd->div);
290 	if (hwd->div)
291 		return parent_rate / hwd->div;
292 	return 0;
293 }
294 
295 static long cdce706_divider_round_rate(struct clk_hw *hw, unsigned long rate,
296 				       unsigned long *parent_rate)
297 {
298 	struct cdce706_hw_data *hwd = to_hw_data(hw);
299 	struct cdce706_dev_data *cdce = hwd->dev_data;
300 	unsigned long mul, div;
301 
302 	dev_dbg(&hwd->dev_data->client->dev,
303 		"%s, rate: %lu, parent_rate: %lu\n",
304 		__func__, rate, *parent_rate);
305 
306 	rational_best_approximation(rate, *parent_rate,
307 				    1, CDCE706_DIVIDER_DIVIDER_MAX,
308 				    &mul, &div);
309 	if (!mul)
310 		div = CDCE706_DIVIDER_DIVIDER_MAX;
311 
312 	if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) {
313 		unsigned long best_diff = rate;
314 		unsigned long best_div = 0;
315 		struct clk *gp_clk = cdce->clkin_clk[cdce->clkin[0].parent];
316 		unsigned long gp_rate = gp_clk ? clk_get_rate(gp_clk) : 0;
317 
318 		for (div = CDCE706_PLL_FREQ_MIN / rate; best_diff &&
319 		     div <= CDCE706_PLL_FREQ_MAX / rate; ++div) {
320 			unsigned long n, m;
321 			unsigned long diff;
322 			unsigned long div_rate;
323 			u64 div_rate64;
324 
325 			if (rate * div < CDCE706_PLL_FREQ_MIN)
326 				continue;
327 
328 			rational_best_approximation(rate * div, gp_rate,
329 						    CDCE706_PLL_N_MAX,
330 						    CDCE706_PLL_M_MAX,
331 						    &n, &m);
332 			div_rate64 = (u64)gp_rate * n;
333 			do_div(div_rate64, m);
334 			do_div(div_rate64, div);
335 			div_rate = div_rate64;
336 			diff = max(div_rate, rate) - min(div_rate, rate);
337 
338 			if (diff < best_diff) {
339 				best_diff = diff;
340 				best_div = div;
341 				dev_dbg(&hwd->dev_data->client->dev,
342 					"%s, %lu * %lu / %lu / %lu = %lu\n",
343 					__func__, gp_rate, n, m, div, div_rate);
344 			}
345 		}
346 
347 		div = best_div;
348 
349 		dev_dbg(&hwd->dev_data->client->dev,
350 			"%s, altering parent rate: %lu -> %lu\n",
351 			__func__, *parent_rate, rate * div);
352 		*parent_rate = rate * div;
353 	}
354 	hwd->div = div;
355 
356 	dev_dbg(&hwd->dev_data->client->dev,
357 		"%s, divider: %d, div: %lu\n",
358 		__func__, hwd->idx, div);
359 
360 	return *parent_rate / div;
361 }
362 
363 static int cdce706_divider_set_rate(struct clk_hw *hw, unsigned long rate,
364 				    unsigned long parent_rate)
365 {
366 	struct cdce706_hw_data *hwd = to_hw_data(hw);
367 
368 	dev_dbg(&hwd->dev_data->client->dev,
369 		"%s, divider: %d, div: %u\n",
370 		__func__, hwd->idx, hwd->div);
371 
372 	return cdce706_reg_update(hwd->dev_data,
373 				  CDCE706_DIVIDER(hwd->idx),
374 				  CDCE706_DIVIDER_DIVIDER_MASK,
375 				  hwd->div);
376 }
377 
378 static const struct clk_ops cdce706_divider_ops = {
379 	.set_parent = cdce706_divider_set_parent,
380 	.get_parent = cdce706_divider_get_parent,
381 	.recalc_rate = cdce706_divider_recalc_rate,
382 	.round_rate = cdce706_divider_round_rate,
383 	.set_rate = cdce706_divider_set_rate,
384 };
385 
386 static int cdce706_clkout_prepare(struct clk_hw *hw)
387 {
388 	struct cdce706_hw_data *hwd = to_hw_data(hw);
389 
390 	return cdce706_reg_update(hwd->dev_data, CDCE706_CLKOUT(hwd->idx),
391 				  CDCE706_CLKOUT_ENABLE_MASK,
392 				  CDCE706_CLKOUT_ENABLE_MASK);
393 }
394 
395 static void cdce706_clkout_unprepare(struct clk_hw *hw)
396 {
397 	struct cdce706_hw_data *hwd = to_hw_data(hw);
398 
399 	cdce706_reg_update(hwd->dev_data, CDCE706_CLKOUT(hwd->idx),
400 			   CDCE706_CLKOUT_ENABLE_MASK, 0);
401 }
402 
403 static int cdce706_clkout_set_parent(struct clk_hw *hw, u8 index)
404 {
405 	struct cdce706_hw_data *hwd = to_hw_data(hw);
406 
407 	if (hwd->parent == index)
408 		return 0;
409 	hwd->parent = index;
410 	return cdce706_reg_update(hwd->dev_data,
411 				  CDCE706_CLKOUT(hwd->idx),
412 				  CDCE706_CLKOUT_ENABLE_MASK, index);
413 }
414 
415 static u8 cdce706_clkout_get_parent(struct clk_hw *hw)
416 {
417 	struct cdce706_hw_data *hwd = to_hw_data(hw);
418 
419 	return hwd->parent;
420 }
421 
422 static unsigned long cdce706_clkout_recalc_rate(struct clk_hw *hw,
423 						unsigned long parent_rate)
424 {
425 	return parent_rate;
426 }
427 
428 static long cdce706_clkout_round_rate(struct clk_hw *hw, unsigned long rate,
429 				      unsigned long *parent_rate)
430 {
431 	*parent_rate = rate;
432 	return rate;
433 }
434 
435 static int cdce706_clkout_set_rate(struct clk_hw *hw, unsigned long rate,
436 				   unsigned long parent_rate)
437 {
438 	return 0;
439 }
440 
441 static const struct clk_ops cdce706_clkout_ops = {
442 	.prepare = cdce706_clkout_prepare,
443 	.unprepare = cdce706_clkout_unprepare,
444 	.set_parent = cdce706_clkout_set_parent,
445 	.get_parent = cdce706_clkout_get_parent,
446 	.recalc_rate = cdce706_clkout_recalc_rate,
447 	.round_rate = cdce706_clkout_round_rate,
448 	.set_rate = cdce706_clkout_set_rate,
449 };
450 
451 static int cdce706_register_hw(struct cdce706_dev_data *cdce,
452 			       struct cdce706_hw_data *hw, unsigned num_hw,
453 			       const char * const *clk_names,
454 			       struct clk_init_data *init)
455 {
456 	unsigned i;
457 
458 	for (i = 0; i < num_hw; ++i, ++hw) {
459 		init->name = clk_names[i];
460 		hw->dev_data = cdce;
461 		hw->idx = i;
462 		hw->hw.init = init;
463 		hw->clk = devm_clk_register(&cdce->client->dev,
464 					    &hw->hw);
465 		if (IS_ERR(hw->clk)) {
466 			dev_err(&cdce->client->dev, "Failed to register %s\n",
467 				clk_names[i]);
468 			return PTR_ERR(hw->clk);
469 		}
470 	}
471 	return 0;
472 }
473 
474 static int cdce706_register_clkin(struct cdce706_dev_data *cdce)
475 {
476 	struct clk_init_data init = {
477 		.ops = &cdce706_clkin_ops,
478 		.parent_names = cdce->clkin_name,
479 		.num_parents = ARRAY_SIZE(cdce->clkin_name),
480 	};
481 	unsigned i;
482 	int ret;
483 	unsigned clock, source;
484 
485 	for (i = 0; i < ARRAY_SIZE(cdce->clkin_name); ++i) {
486 		struct clk *parent = devm_clk_get(&cdce->client->dev,
487 						  cdce706_source_name[i]);
488 
489 		if (IS_ERR(parent)) {
490 			cdce->clkin_name[i] = cdce706_source_name[i];
491 		} else {
492 			cdce->clkin_name[i] = __clk_get_name(parent);
493 			cdce->clkin_clk[i] = parent;
494 		}
495 	}
496 
497 	ret = cdce706_reg_read(cdce, CDCE706_CLKIN_SOURCE, &source);
498 	if (ret < 0)
499 		return ret;
500 	if ((source & CDCE706_CLKIN_SOURCE_MASK) ==
501 	    CDCE706_CLKIN_SOURCE_LVCMOS) {
502 		ret = cdce706_reg_read(cdce, CDCE706_CLKIN_CLOCK, &clock);
503 		if (ret < 0)
504 			return ret;
505 		cdce->clkin[0].parent = !!(clock & CDCE706_CLKIN_CLOCK_MASK);
506 	}
507 
508 	ret = cdce706_register_hw(cdce, cdce->clkin,
509 				  ARRAY_SIZE(cdce->clkin),
510 				  cdce706_clkin_name, &init);
511 	return ret;
512 }
513 
514 static int cdce706_register_plls(struct cdce706_dev_data *cdce)
515 {
516 	struct clk_init_data init = {
517 		.ops = &cdce706_pll_ops,
518 		.parent_names = cdce706_clkin_name,
519 		.num_parents = ARRAY_SIZE(cdce706_clkin_name),
520 	};
521 	unsigned i;
522 	int ret;
523 	unsigned mux;
524 
525 	ret = cdce706_reg_read(cdce, CDCE706_PLL_MUX, &mux);
526 	if (ret < 0)
527 		return ret;
528 
529 	for (i = 0; i < ARRAY_SIZE(cdce->pll); ++i) {
530 		unsigned m, n, v;
531 
532 		ret = cdce706_reg_read(cdce, CDCE706_PLL_M_LOW(i), &m);
533 		if (ret < 0)
534 			return ret;
535 		ret = cdce706_reg_read(cdce, CDCE706_PLL_N_LOW(i), &n);
536 		if (ret < 0)
537 			return ret;
538 		ret = cdce706_reg_read(cdce, CDCE706_PLL_HI(i), &v);
539 		if (ret < 0)
540 			return ret;
541 		cdce->pll[i].div = m | ((v & CDCE706_PLL_HI_M_MASK) << 8);
542 		cdce->pll[i].mul = n | ((v & CDCE706_PLL_HI_N_MASK) <<
543 					(8 - CDCE706_PLL_HI_N_SHIFT));
544 		cdce->pll[i].mux = mux & CDCE706_PLL_MUX_MASK(i);
545 		dev_dbg(&cdce->client->dev,
546 			"%s: i: %u, div: %u, mul: %u, mux: %d\n", __func__, i,
547 			cdce->pll[i].div, cdce->pll[i].mul, cdce->pll[i].mux);
548 	}
549 
550 	ret = cdce706_register_hw(cdce, cdce->pll,
551 				  ARRAY_SIZE(cdce->pll),
552 				  cdce706_pll_name, &init);
553 	return ret;
554 }
555 
556 static int cdce706_register_dividers(struct cdce706_dev_data *cdce)
557 {
558 	struct clk_init_data init = {
559 		.ops = &cdce706_divider_ops,
560 		.parent_names = cdce706_divider_parent_name,
561 		.num_parents = ARRAY_SIZE(cdce706_divider_parent_name),
562 		.flags = CLK_SET_RATE_PARENT,
563 	};
564 	unsigned i;
565 	int ret;
566 
567 	for (i = 0; i < ARRAY_SIZE(cdce->divider); ++i) {
568 		unsigned val;
569 
570 		ret = cdce706_reg_read(cdce, CDCE706_DIVIDER_PLL(i), &val);
571 		if (ret < 0)
572 			return ret;
573 		cdce->divider[i].parent =
574 			(val & CDCE706_DIVIDER_PLL_MASK(i)) >>
575 			CDCE706_DIVIDER_PLL_SHIFT(i);
576 
577 		ret = cdce706_reg_read(cdce, CDCE706_DIVIDER(i), &val);
578 		if (ret < 0)
579 			return ret;
580 		cdce->divider[i].div = val & CDCE706_DIVIDER_DIVIDER_MASK;
581 		dev_dbg(&cdce->client->dev,
582 			"%s: i: %u, parent: %u, div: %u\n", __func__, i,
583 			cdce->divider[i].parent, cdce->divider[i].div);
584 	}
585 
586 	ret = cdce706_register_hw(cdce, cdce->divider,
587 				  ARRAY_SIZE(cdce->divider),
588 				  cdce706_divider_name, &init);
589 	return ret;
590 }
591 
592 static int cdce706_register_clkouts(struct cdce706_dev_data *cdce)
593 {
594 	struct clk_init_data init = {
595 		.ops = &cdce706_clkout_ops,
596 		.parent_names = cdce706_divider_name,
597 		.num_parents = ARRAY_SIZE(cdce706_divider_name),
598 		.flags = CLK_SET_RATE_PARENT,
599 	};
600 	unsigned i;
601 	int ret;
602 
603 	for (i = 0; i < ARRAY_SIZE(cdce->clkout); ++i) {
604 		unsigned val;
605 
606 		ret = cdce706_reg_read(cdce, CDCE706_CLKOUT(i), &val);
607 		if (ret < 0)
608 			return ret;
609 		cdce->clkout[i].parent = val & CDCE706_CLKOUT_DIVIDER_MASK;
610 		dev_dbg(&cdce->client->dev,
611 			"%s: i: %u, parent: %u\n", __func__, i,
612 			cdce->clkout[i].parent);
613 	}
614 
615 	ret = cdce706_register_hw(cdce, cdce->clkout,
616 				  ARRAY_SIZE(cdce->clkout),
617 				  cdce706_clkout_name, &init);
618 	for (i = 0; i < ARRAY_SIZE(cdce->clkout); ++i)
619 		cdce->clks[i] = cdce->clkout[i].clk;
620 
621 	return ret;
622 }
623 
624 static int cdce706_probe(struct i2c_client *client,
625 			 const struct i2c_device_id *id)
626 {
627 	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
628 	struct cdce706_dev_data *cdce;
629 	int ret;
630 
631 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
632 		return -EIO;
633 
634 	cdce = devm_kzalloc(&client->dev, sizeof(*cdce), GFP_KERNEL);
635 	if (!cdce)
636 		return -ENOMEM;
637 
638 	cdce->client = client;
639 	cdce->regmap = devm_regmap_init_i2c(client, &cdce706_regmap_config);
640 	if (IS_ERR(cdce->regmap)) {
641 		dev_err(&client->dev, "Failed to initialize regmap\n");
642 		return -EINVAL;
643 	}
644 
645 	i2c_set_clientdata(client, cdce);
646 
647 	ret = cdce706_register_clkin(cdce);
648 	if (ret < 0)
649 		return ret;
650 	ret = cdce706_register_plls(cdce);
651 	if (ret < 0)
652 		return ret;
653 	ret = cdce706_register_dividers(cdce);
654 	if (ret < 0)
655 		return ret;
656 	ret = cdce706_register_clkouts(cdce);
657 	if (ret < 0)
658 		return ret;
659 	cdce->onecell.clks = cdce->clks;
660 	cdce->onecell.clk_num = ARRAY_SIZE(cdce->clks);
661 	ret = of_clk_add_provider(client->dev.of_node, of_clk_src_onecell_get,
662 				  &cdce->onecell);
663 
664 	return ret;
665 }
666 
667 static int cdce706_remove(struct i2c_client *client)
668 {
669 	return 0;
670 }
671 
672 
673 #ifdef CONFIG_OF
674 static const struct of_device_id cdce706_dt_match[] = {
675 	{ .compatible = "ti,cdce706" },
676 	{ },
677 };
678 MODULE_DEVICE_TABLE(of, cdce706_dt_match);
679 #endif
680 
681 static const struct i2c_device_id cdce706_id[] = {
682 	{ "cdce706", 0 },
683 	{ }
684 };
685 MODULE_DEVICE_TABLE(i2c, cdce706_id);
686 
687 static struct i2c_driver cdce706_i2c_driver = {
688 	.driver	= {
689 		.name	= "cdce706",
690 		.of_match_table = of_match_ptr(cdce706_dt_match),
691 	},
692 	.probe		= cdce706_probe,
693 	.remove		= cdce706_remove,
694 	.id_table	= cdce706_id,
695 };
696 module_i2c_driver(cdce706_i2c_driver);
697 
698 MODULE_AUTHOR("Max Filippov <jcmvbkbc@gmail.com>");
699 MODULE_DESCRIPTION("TI CDCE 706 clock synthesizer driver");
700 MODULE_LICENSE("GPL");
701