]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/clk/clk-cdce706.c
Merge tag 'pci-v4.3-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
[karo-tx-linux.git] / drivers / clk / clk-cdce706.c
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 * const 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 * const 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         of_clk_del_provider(client->dev.of_node);
670         return 0;
671 }
672
673
674 #ifdef CONFIG_OF
675 static const struct of_device_id cdce706_dt_match[] = {
676         { .compatible = "ti,cdce706" },
677         { },
678 };
679 MODULE_DEVICE_TABLE(of, cdce706_dt_match);
680 #endif
681
682 static const struct i2c_device_id cdce706_id[] = {
683         { "cdce706", 0 },
684         { }
685 };
686 MODULE_DEVICE_TABLE(i2c, cdce706_id);
687
688 static struct i2c_driver cdce706_i2c_driver = {
689         .driver = {
690                 .name   = "cdce706",
691                 .of_match_table = of_match_ptr(cdce706_dt_match),
692         },
693         .probe          = cdce706_probe,
694         .remove         = cdce706_remove,
695         .id_table       = cdce706_id,
696 };
697 module_i2c_driver(cdce706_i2c_driver);
698
699 MODULE_AUTHOR("Max Filippov <jcmvbkbc@gmail.com>");
700 MODULE_DESCRIPTION("TI CDCE 706 clock synthesizer driver");
701 MODULE_LICENSE("GPL");