1.1 --- a/pkg/devices/lib/cpm/src/common.cc Sun Sep 17 19:20:18 2023 +0200
1.2 +++ b/pkg/devices/lib/cpm/src/common.cc Sun Sep 17 21:36:19 2023 +0200
1.3 @@ -292,6 +292,19 @@
1.4 return source_frequency / get_divider(regs);
1.5 }
1.6
1.7 +int
1.8 +Divider::get_parameters(Cpm_regs ®s, uint32_t parameters[])
1.9 +{
1.10 + parameters[0] = get_divider(regs);
1.11 + return 1;
1.12 +}
1.13 +
1.14 +void
1.15 +Divider::set_parameters(Cpm_regs ®s, uint32_t parameters[])
1.16 +{
1.17 + set_divider(regs, parameters[0]);
1.18 +}
1.19 +
1.20 // Undefined divider.
1.21
1.22 Divider Divider::undefined;
1.23 @@ -357,13 +370,21 @@
1.24 (get_input_divider(regs) * get_output_divider(regs));
1.25 }
1.26
1.27 -void
1.28 -Divider_pll::set_parameters(Cpm_regs ®s, uint32_t multiplier,
1.29 - uint32_t in_divider, uint32_t out_divider)
1.30 +int
1.31 +Divider_pll::get_parameters(Cpm_regs ®s, uint32_t parameters[])
1.32 {
1.33 - set_multiplier(regs, multiplier);
1.34 - set_input_divider(regs, in_divider);
1.35 - set_output_divider(regs, out_divider);
1.36 + parameters[0] = get_multiplier(regs);
1.37 + parameters[1] = get_input_divider(regs);
1.38 + parameters[2] = get_output_divider(regs);
1.39 + return 3;
1.40 +}
1.41 +
1.42 +void
1.43 +Divider_pll::set_parameters(Cpm_regs ®s, uint32_t parameters[])
1.44 +{
1.45 + set_multiplier(regs, parameters[0]);
1.46 + set_input_divider(regs, parameters[1]);
1.47 + set_output_divider(regs, parameters[2]);
1.48 }
1.49
1.50
1.51 @@ -377,34 +398,44 @@
1.52 }
1.53
1.54 uint32_t
1.55 +Divider_i2s::get_divider_N(Cpm_regs ®s)
1.56 +{
1.57 + return _divider_N.get_field(regs);
1.58 +}
1.59 +
1.60 +uint32_t
1.61 Divider_i2s::get_divider_D(Cpm_regs ®s)
1.62 {
1.63 return _divider_D.get_field(regs);
1.64 }
1.65
1.66 uint32_t
1.67 -Divider_i2s::get_divider_N(Cpm_regs ®s)
1.68 -{
1.69 - return _divider_N.get_field(regs);
1.70 -}
1.71 -
1.72 -uint32_t
1.73 Divider_i2s::get_frequency(Cpm_regs ®s, uint32_t source_frequency)
1.74 {
1.75 return (source_frequency * get_multiplier(regs)) /
1.76 (get_divider_N(regs) * get_divider_D(regs));
1.77 }
1.78
1.79 +int
1.80 +Divider_i2s::get_parameters(Cpm_regs ®s, uint32_t parameters[])
1.81 +{
1.82 + parameters[0] = get_multiplier(regs);
1.83 + parameters[1] = get_divider_N(regs);
1.84 + parameters[2] = get_divider_D(regs);
1.85 + return 3;
1.86 +}
1.87 +
1.88 void
1.89 -Divider_i2s::set_parameters(Cpm_regs ®s, uint32_t multiplier,
1.90 - uint32_t divider_N, uint32_t divider_D)
1.91 +Divider_i2s::set_parameters(Cpm_regs ®s, uint32_t parameters[])
1.92 {
1.93 - if (divider_N < 2 * multiplier)
1.94 + // Test for N < 2M.
1.95 +
1.96 + if (parameters[1] < 2 * parameters[0] )
1.97 return;
1.98
1.99 - _multiplier.set_field(regs, multiplier);
1.100 - _divider_N.set_field(regs, divider_N);
1.101 - _divider_D.set_field(regs, divider_D);
1.102 + _multiplier.set_field(regs, parameters[0]);
1.103 + _divider_N.set_field(regs, parameters[1]);
1.104 + _divider_D.set_field(regs, parameters[2]);
1.105 }
1.106
1.107
1.108 @@ -557,6 +588,19 @@
1.109 return _get_divider().get_frequency(regs, get_source_frequency(regs));
1.110 }
1.111
1.112 +int
1.113 +Clock_divided::get_parameters(Cpm_regs ®s, uint32_t parameters[])
1.114 +{
1.115 + return _get_divider().get_parameters(regs, parameters);
1.116 +}
1.117 +
1.118 +void
1.119 +Clock_divided::set_parameters(Cpm_regs ®s, uint32_t parameters[])
1.120 +{
1.121 + _get_divider().set_parameters(regs, parameters);
1.122 + _get_control().wait_busy(regs);
1.123 +}
1.124 +
1.125
1.126
1.127 // PLL boilerplate.
1.128 @@ -621,14 +665,6 @@
1.129 return 0;
1.130 }
1.131
1.132 -void
1.133 -Pll::set_parameters(Cpm_regs ®s, uint32_t multiplier,
1.134 - uint32_t in_divider, uint32_t out_divider)
1.135 -{
1.136 - _divider.set_parameters(regs, multiplier, in_divider, out_divider);
1.137 - _control.wait_busy(regs);
1.138 -}
1.139 -
1.140
1.141
1.142 // Clock dividers.