Lines Matching +full:sel +full:- +full:clk
1 // SPDX-License-Identifier: GPL-2.0
3 // Helper routines for R-Car sound ADG.
6 #include <linux/clk-provider.h>
34 struct clk *adg;
35 struct clk *clkin[CLKINMAX];
36 struct clk *clkout[CLKOUTMAX];
37 struct clk *null_clk;
52 (i < adg->clkin_size) && \
53 ((pos) = adg->clkin[i]); \
57 (i < adg->clkout_size) && \
58 ((pos) = adg->clkout[i]); \
60 #define rsnd_priv_to_adg(priv) ((struct rsnd_adg *)(priv)->adg)
87 for (i = 3; i >= 0; i--) { in rsnd_adg_calculate_brgx()
90 return (u32)((i << 8) | ((div / ratio) - 1)); in rsnd_adg_calculate_brgx()
136 int sel; in __rsnd_adg_get_timesel_ratio() local
140 adg->clkin_rate[CLKA], /* 0000: CLKA */ in __rsnd_adg_get_timesel_ratio()
141 adg->clkin_rate[CLKB], /* 0001: CLKB */ in __rsnd_adg_get_timesel_ratio()
142 adg->clkin_rate[CLKC], /* 0010: CLKC */ in __rsnd_adg_get_timesel_ratio()
143 adg->brg_rate[ADG_HZ_441], /* 0011: BRGA */ in __rsnd_adg_get_timesel_ratio()
144 adg->brg_rate[ADG_HZ_48], /* 0100: BRGB */ in __rsnd_adg_get_timesel_ratio()
150 for (sel = 0; sel < ARRAY_SIZE(sel_rate); sel++) { in __rsnd_adg_get_timesel_ratio()
155 if (!sel_rate[sel]) in __rsnd_adg_get_timesel_ratio()
159 diff = abs(target_rate - sel_rate[sel] / div); in __rsnd_adg_get_timesel_ratio()
161 val = (sel << 8) | idx; in __rsnd_adg_get_timesel_ratio()
163 en = 1 << (sel + 1); /* fixme */ in __rsnd_adg_get_timesel_ratio()
210 if (runtime->rate != in_rate) { in rsnd_adg_get_timesel_ratio()
213 } else if (runtime->rate != out_rate) { in rsnd_adg_get_timesel_ratio()
315 struct clk *clk; in rsnd_adg_clk_query() local
328 for_each_rsnd_clkin(clk, adg, i) in rsnd_adg_clk_query()
329 if (rate == adg->clkin_rate[i]) in rsnd_adg_clk_query()
335 if (rate == adg->brg_rate[ADG_HZ_441]) in rsnd_adg_clk_query()
338 if (rate == adg->brg_rate[ADG_HZ_48]) in rsnd_adg_clk_query()
341 return -EIO; in rsnd_adg_clk_query()
366 ckr = adg->ckr & ~BRGCKR_31; in rsnd_adg_ssi_clk_try_start()
369 if (ckr != adg->ckr) { in rsnd_adg_ssi_clk_try_start()
370 rsnd_mod_bset(adg_mod, BRGCKR, 0x80770000, adg->ckr); in rsnd_adg_ssi_clk_try_start()
371 adg->ckr = ckr; in rsnd_adg_ssi_clk_try_start()
376 (ckr) ? adg->brg_rate[ADG_HZ_48] : in rsnd_adg_ssi_clk_try_start()
377 adg->brg_rate[ADG_HZ_441]); in rsnd_adg_ssi_clk_try_start()
386 struct clk *clk; in rsnd_adg_clk_control() local
390 ret = clk_prepare_enable(adg->adg); in rsnd_adg_clk_control()
394 rsnd_mod_bset(adg_mod, BRGCKR, 0x80770000, adg->ckr); in rsnd_adg_clk_control()
395 rsnd_mod_write(adg_mod, BRRA, adg->brga); in rsnd_adg_clk_control()
396 rsnd_mod_write(adg_mod, BRRB, adg->brgb); in rsnd_adg_clk_control()
399 for_each_rsnd_clkin(clk, adg, i) { in rsnd_adg_clk_control()
401 ret = clk_prepare_enable(clk); in rsnd_adg_clk_control()
411 adg->clkin_rate[i] = clk_get_rate(clk); in rsnd_adg_clk_control()
413 if (adg->clkin_rate[i]) in rsnd_adg_clk_control()
414 clk_disable_unprepare(clk); in rsnd_adg_clk_control()
416 adg->clkin_rate[i] = 0; in rsnd_adg_clk_control()
429 clk_disable_unprepare(adg->adg); in rsnd_adg_clk_control()
434 static struct clk *rsnd_adg_create_null_clk(struct rsnd_priv *priv, in rsnd_adg_create_null_clk()
439 struct clk *clk; in rsnd_adg_create_null_clk() local
441 clk = clk_register_fixed_rate(dev, name, parent, 0, 0); in rsnd_adg_create_null_clk()
442 if (IS_ERR_OR_NULL(clk)) { in rsnd_adg_create_null_clk()
443 dev_err(dev, "create null clk error\n"); in rsnd_adg_create_null_clk()
444 return ERR_CAST(clk); in rsnd_adg_create_null_clk()
447 return clk; in rsnd_adg_create_null_clk()
450 static struct clk *rsnd_adg_null_clk_get(struct rsnd_priv *priv) in rsnd_adg_null_clk_get()
452 struct rsnd_adg *adg = priv->adg; in rsnd_adg_null_clk_get()
454 if (!adg->null_clk) { in rsnd_adg_null_clk_get()
457 adg->null_clk = rsnd_adg_create_null_clk(priv, name, NULL); in rsnd_adg_null_clk_get()
460 return adg->null_clk; in rsnd_adg_null_clk_get()
465 struct rsnd_adg *adg = priv->adg; in rsnd_adg_null_clk_clean()
467 if (adg->null_clk) in rsnd_adg_null_clk_clean()
468 clk_unregister_fixed_rate(adg->null_clk); in rsnd_adg_null_clk_clean()
473 struct rsnd_adg *adg = priv->adg; in rsnd_adg_get_clkin()
475 struct clk *clk; in rsnd_adg_get_clkin() local
491 clk = devm_clk_get(dev, "adg"); in rsnd_adg_get_clkin()
492 if (IS_ERR_OR_NULL(clk)) in rsnd_adg_get_clkin()
493 clk = rsnd_adg_null_clk_get(priv); in rsnd_adg_get_clkin()
494 adg->adg = clk; in rsnd_adg_get_clkin()
498 clk = devm_clk_get(dev, clkin_name[i]); in rsnd_adg_get_clkin()
500 if (IS_ERR_OR_NULL(clk)) in rsnd_adg_get_clkin()
501 clk = rsnd_adg_null_clk_get(priv); in rsnd_adg_get_clkin()
502 if (IS_ERR_OR_NULL(clk)) in rsnd_adg_get_clkin()
505 adg->clkin[i] = clk; in rsnd_adg_get_clkin()
508 adg->clkin_size = clkin_size; in rsnd_adg_get_clkin()
517 return -EIO; in rsnd_adg_get_clkin()
522 struct rsnd_adg *adg = priv->adg; in rsnd_adg_unregister_clkout()
523 struct clk *clk; in rsnd_adg_unregister_clkout() local
526 for_each_rsnd_clkout(clk, adg, i) in rsnd_adg_unregister_clkout()
527 clk_unregister_fixed_rate(clk); in rsnd_adg_unregister_clkout()
532 struct rsnd_adg *adg = priv->adg; in rsnd_adg_get_clkout()
533 struct clk *clk; in rsnd_adg_get_clkout() local
535 struct device_node *np = dev->of_node; in rsnd_adg_get_clkout()
561 prop = of_find_property(np, "clock-frequency", NULL); in rsnd_adg_get_clkout()
565 req_size = prop->length / sizeof(u32); in rsnd_adg_get_clkout()
567 dev_err(dev, "too many clock-frequency\n"); in rsnd_adg_get_clkout()
568 return -EINVAL; in rsnd_adg_get_clkout()
571 of_property_read_u32_array(np, "clock-frequency", req_rate, req_size); in rsnd_adg_get_clkout()
585 * SSI itself can divide parent clock by 1/1 - 1/16 in rsnd_adg_get_clkout()
600 * - Minimum division of BRRA/BRRB in rsnd_adg_get_clkout()
601 * - rsnd_ssi_clk_query() in rsnd_adg_get_clkout()
608 * clock-frequency = <22579200 24576000>; in rsnd_adg_get_clkout()
610 for_each_rsnd_clkin(clk, adg, i) { in rsnd_adg_get_clkout()
613 rate = clk_get_rate(clk); in rsnd_adg_get_clkout()
622 rate = (clk_get_rate(clk) / req_Hz[ADG_HZ_441]) * req_Hz[ADG_HZ_441]; in rsnd_adg_get_clkout()
623 if (!adg->brg_rate[ADG_HZ_441] && req_Hz[ADG_HZ_441] && (0 == rate % 44100)) { in rsnd_adg_get_clkout()
628 adg->brg_rate[ADG_HZ_441] = rate / div; in rsnd_adg_get_clkout()
631 parent_clk_name = __clk_get_name(clk); in rsnd_adg_get_clkout()
641 rate = (clk_get_rate(clk) / req_Hz[ADG_HZ_48]) * req_Hz[ADG_HZ_48]; in rsnd_adg_get_clkout()
642 if (!adg->brg_rate[ADG_HZ_48] && req_Hz[ADG_HZ_48] && (0 == rate % 48000)) { in rsnd_adg_get_clkout()
647 adg->brg_rate[ADG_HZ_48] = rate / div; in rsnd_adg_get_clkout()
650 parent_clk_name = __clk_get_name(clk); in rsnd_adg_get_clkout()
657 if (!(adg->brg_rate[ADG_HZ_48] && req_Hz[ADG_HZ_48]) && in rsnd_adg_get_clkout()
658 !(adg->brg_rate[ADG_HZ_441] && req_Hz[ADG_HZ_441])) in rsnd_adg_get_clkout()
674 of_property_read_u32(np, "#clock-cells", &count); in rsnd_adg_get_clkout()
679 clk = clk_register_fixed_rate(dev, clkout_name[CLKOUT], in rsnd_adg_get_clkout()
681 if (IS_ERR_OR_NULL(clk)) in rsnd_adg_get_clkout()
684 adg->clkout[CLKOUT] = clk; in rsnd_adg_get_clkout()
685 adg->clkout_size = 1; in rsnd_adg_get_clkout()
686 of_clk_add_provider(np, of_clk_src_simple_get, clk); in rsnd_adg_get_clkout()
693 clk = clk_register_fixed_rate(dev, clkout_name[i], in rsnd_adg_get_clkout()
696 if (IS_ERR_OR_NULL(clk)) in rsnd_adg_get_clkout()
699 adg->clkout[i] = clk; in rsnd_adg_get_clkout()
701 adg->onecell.clks = adg->clkout; in rsnd_adg_get_clkout()
702 adg->onecell.clk_num = clkout_size; in rsnd_adg_get_clkout()
703 adg->clkout_size = clkout_size; in rsnd_adg_get_clkout()
705 &adg->onecell); in rsnd_adg_get_clkout()
712 adg->ckr = ckr; in rsnd_adg_get_clkout()
713 adg->brga = brga; in rsnd_adg_get_clkout()
714 adg->brgb = brgb; in rsnd_adg_get_clkout()
723 return -EIO; in rsnd_adg_get_clkout()
748 struct clk *clk; in rsnd_adg_clk_dbg_info() local
751 for_each_rsnd_clkin(clk, adg, i) in rsnd_adg_clk_dbg_info()
752 dbg_msg(dev, m, "%-18s : %pa : %ld\n", in rsnd_adg_clk_dbg_info()
753 __clk_get_name(clk), clk, clk_get_rate(clk)); in rsnd_adg_clk_dbg_info()
756 adg->ckr, adg->brga, adg->brgb); in rsnd_adg_clk_dbg_info()
757 dbg_msg(dev, m, "BRGA (for 44100 base) = %d\n", adg->brg_rate[ADG_HZ_441]); in rsnd_adg_clk_dbg_info()
758 dbg_msg(dev, m, "BRGB (for 48000 base) = %d\n", adg->brg_rate[ADG_HZ_48]); in rsnd_adg_clk_dbg_info()
764 for_each_rsnd_clkout(clk, adg, i) in rsnd_adg_clk_dbg_info()
765 dbg_msg(dev, m, "%-18s : %pa : %ld\n", in rsnd_adg_clk_dbg_info()
766 __clk_get_name(clk), clk, clk_get_rate(clk)); in rsnd_adg_clk_dbg_info()
780 return -ENOMEM; in rsnd_adg_probe()
782 ret = rsnd_mod_init(priv, &adg->mod, &adg_ops, in rsnd_adg_probe()
787 priv->adg = adg; in rsnd_adg_probe()
809 struct device_node *np = dev->of_node; in rsnd_adg_remove()