Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'dpll-zl3073x-add-ref-sync-pair-support'

Ivan Vecera says:

====================
dpll: zl3073x: add ref-sync pair support

This series adds Reference-Sync pair support to the ZL3073x DPLL driver.
A Ref-Sync pair consists of a clock reference and a low-frequency sync
signal (e.g. 1 PPS) where the DPLL locks to the clock reference but
phase-aligns to the sync reference.

Patches 1-3 are preparatory cleanups and helper additions:
- Clean up esync get/set callbacks with early returns and use the
zl3073x_out_is_ndiv() helper
- Convert open-coded clear-and-set bitfield patterns to FIELD_MODIFY()
- Add ref sync control and output clock type accessor helpers

Patch 4 adds the 'ref-sync-sources' phandle-array property to the
dpll-pin device tree binding schema and updates the ZL3073x binding
examples.

Patch 5 implements the driver support:
- ref_sync_get/set callbacks with frequency validation
- Automatic sync source exclusion from reference selection
- Device tree based ref-sync pair registration

Tested and verified on Microchip EDS2 (pcb8385) development board.
====================

Link: https://patch.msgid.link/20260408102716.443099-1-ivecera@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+351 -82
+13
Documentation/devicetree/bindings/dpll/dpll-pin.yaml
··· 36 36 description: String exposed as the pin board label 37 37 $ref: /schemas/types.yaml#/definitions/string 38 38 39 + ref-sync-sources: 40 + description: | 41 + List of phandles to input pins that can serve as the sync source 42 + in a Reference-Sync pair with this pin acting as the clock source. 43 + A Ref-Sync pair consists of a clock reference and a low-frequency 44 + sync signal. The DPLL locks to the clock reference but 45 + phase-aligns to the sync reference. 46 + Only valid for input pins. Each referenced pin must be a 47 + different input pin on the same device. 48 + $ref: /schemas/types.yaml#/definitions/phandle-array 49 + items: 50 + maxItems: 1 51 + 39 52 supported-frequencies-hz: 40 53 description: List of supported frequencies for this pin, expressed in Hz. 41 54
+23 -7
Documentation/devicetree/bindings/dpll/microchip,zl30731.yaml
··· 52 52 #address-cells = <1>; 53 53 #size-cells = <0>; 54 54 55 - pin@0 { /* REF0P */ 55 + sync0: pin@0 { /* REF0P - 1 PPS sync source */ 56 56 reg = <0>; 57 57 connection-type = "ext"; 58 - label = "Input 0"; 59 - supported-frequencies-hz = /bits/ 64 <1 1000>; 58 + label = "SMA1"; 59 + supported-frequencies-hz = /bits/ 64 <1>; 60 + }; 61 + 62 + pin@1 { /* REF0N - clock source, can pair with sync0 */ 63 + reg = <1>; 64 + connection-type = "ext"; 65 + label = "SMA2"; 66 + supported-frequencies-hz = /bits/ 64 <10000 10000000>; 67 + ref-sync-sources = <&sync0>; 60 68 }; 61 69 }; 62 70 ··· 98 90 #address-cells = <1>; 99 91 #size-cells = <0>; 100 92 101 - pin@0 { /* REF0P */ 93 + sync1: pin@0 { /* REF0P - 1 PPS sync source */ 102 94 reg = <0>; 103 - connection-type = "ext"; 104 - label = "Input 0"; 105 - supported-frequencies-hz = /bits/ 64 <1 1000>; 95 + connection-type = "gnss"; 96 + label = "GNSS_1PPS_IN"; 97 + supported-frequencies-hz = /bits/ 64 <1>; 98 + }; 99 + 100 + pin@1 { /* REF0N - clock source */ 101 + reg = <1>; 102 + connection-type = "gnss"; 103 + label = "GNSS_10M_IN"; 104 + supported-frequencies-hz = /bits/ 64 <10000000>; 105 + ref-sync-sources = <&sync1>; 106 106 }; 107 107 }; 108 108
+6 -11
drivers/dpll/zl3073x/chan.h
··· 66 66 */ 67 67 static inline void zl3073x_chan_mode_set(struct zl3073x_chan *chan, u8 mode) 68 68 { 69 - chan->mode_refsel &= ~ZL_DPLL_MODE_REFSEL_MODE; 70 - chan->mode_refsel |= FIELD_PREP(ZL_DPLL_MODE_REFSEL_MODE, mode); 69 + FIELD_MODIFY(ZL_DPLL_MODE_REFSEL_MODE, &chan->mode_refsel, mode); 71 70 } 72 71 73 72 /** ··· 76 77 */ 77 78 static inline void zl3073x_chan_ref_set(struct zl3073x_chan *chan, u8 ref) 78 79 { 79 - chan->mode_refsel &= ~ZL_DPLL_MODE_REFSEL_REF; 80 - chan->mode_refsel |= FIELD_PREP(ZL_DPLL_MODE_REFSEL_REF, ref); 80 + FIELD_MODIFY(ZL_DPLL_MODE_REFSEL_REF, &chan->mode_refsel, ref); 81 81 } 82 82 83 83 /** ··· 108 110 { 109 111 u8 *val = &chan->ref_prio[ref / 2]; 110 112 111 - if (!(ref & 1)) { 112 - *val &= ~ZL_DPLL_REF_PRIO_REF_P; 113 - *val |= FIELD_PREP(ZL_DPLL_REF_PRIO_REF_P, prio); 114 - } else { 115 - *val &= ~ZL_DPLL_REF_PRIO_REF_N; 116 - *val |= FIELD_PREP(ZL_DPLL_REF_PRIO_REF_N, prio); 117 - } 113 + if (!(ref & 1)) 114 + FIELD_MODIFY(ZL_DPLL_REF_PRIO_REF_P, val, prio); 115 + else 116 + FIELD_MODIFY(ZL_DPLL_REF_PRIO_REF_N, val, prio); 118 117 } 119 118 120 119 /**
+1 -2
drivers/dpll/zl3073x/core.c
··· 805 805 value = (factor + 1) & 0x0f; 806 806 807 807 /* Update phase measurement control register */ 808 - dpll_meas_ctrl &= ~ZL_DPLL_MEAS_CTRL_AVG_FACTOR; 809 - dpll_meas_ctrl |= FIELD_PREP(ZL_DPLL_MEAS_CTRL_AVG_FACTOR, value); 808 + FIELD_MODIFY(ZL_DPLL_MEAS_CTRL_AVG_FACTOR, &dpll_meas_ctrl, value); 810 809 rc = zl3073x_write_u8(zldev, ZL_REG_DPLL_MEAS_CTRL, dpll_meas_ctrl); 811 810 if (rc) 812 811 return rc;
+237 -60
drivers/dpll/zl3073x/dpll.c
··· 13 13 #include <linux/module.h> 14 14 #include <linux/netlink.h> 15 15 #include <linux/platform_device.h> 16 + #include <linux/property.h> 16 17 #include <linux/slab.h> 17 18 #include <linux/sprintf.h> 18 19 ··· 31 30 * @dpll: DPLL the pin is registered to 32 31 * @dpll_pin: pointer to registered dpll_pin 33 32 * @tracker: tracking object for the acquired reference 33 + * @fwnode: firmware node handle 34 34 * @label: package label 35 35 * @dir: pin direction 36 36 * @id: pin id ··· 48 46 struct zl3073x_dpll *dpll; 49 47 struct dpll_pin *dpll_pin; 50 48 dpll_tracker tracker; 49 + struct fwnode_handle *fwnode; 51 50 char label[8]; 52 51 enum dpll_pin_direction dir; 53 52 u8 id; ··· 136 133 ref_id = zl3073x_input_pin_ref_get(pin->id); 137 134 ref = zl3073x_ref_state_get(zldev, ref_id); 138 135 139 - switch (FIELD_GET(ZL_REF_SYNC_CTRL_MODE, ref->sync_ctrl)) { 136 + if (!pin->esync_control || zl3073x_ref_freq_get(ref) <= 1) 137 + return -EOPNOTSUPP; 138 + 139 + esync->range = esync_freq_ranges; 140 + esync->range_num = ARRAY_SIZE(esync_freq_ranges); 141 + 142 + switch (zl3073x_ref_sync_mode_get(ref)) { 140 143 case ZL_REF_SYNC_CTRL_MODE_50_50_ESYNC_25_75: 141 144 esync->freq = ref->esync_n_div == ZL_REF_ESYNC_DIV_1HZ ? 1 : 0; 142 145 esync->pulse = 25; ··· 151 142 esync->freq = 0; 152 143 esync->pulse = 0; 153 144 break; 154 - } 155 - 156 - /* If the pin supports esync control expose its range but only 157 - * if the current reference frequency is > 1 Hz. 158 - */ 159 - if (pin->esync_control && zl3073x_ref_freq_get(ref) > 1) { 160 - esync->range = esync_freq_ranges; 161 - esync->range_num = ARRAY_SIZE(esync_freq_ranges); 162 - } else { 163 - esync->range = NULL; 164 - esync->range_num = 0; 165 145 } 166 146 167 147 return 0; ··· 178 180 else 179 181 sync_mode = ZL_REF_SYNC_CTRL_MODE_50_50_ESYNC_25_75; 180 182 181 - ref.sync_ctrl &= ~ZL_REF_SYNC_CTRL_MODE; 182 - ref.sync_ctrl |= FIELD_PREP(ZL_REF_SYNC_CTRL_MODE, sync_mode); 183 + zl3073x_ref_sync_mode_set(&ref, sync_mode); 183 184 184 185 if (freq) { 185 186 /* 1 Hz is only supported frequency now */ ··· 187 190 188 191 /* Update reference configuration */ 189 192 return zl3073x_ref_state_set(zldev, ref_id, &ref); 193 + } 194 + 195 + static int 196 + zl3073x_dpll_input_pin_ref_sync_get(const struct dpll_pin *dpll_pin, 197 + void *pin_priv, 198 + const struct dpll_pin *ref_sync_pin, 199 + void *ref_sync_pin_priv, 200 + enum dpll_pin_state *state, 201 + struct netlink_ext_ack *extack) 202 + { 203 + struct zl3073x_dpll_pin *sync_pin = ref_sync_pin_priv; 204 + struct zl3073x_dpll_pin *pin = pin_priv; 205 + struct zl3073x_dpll *zldpll = pin->dpll; 206 + struct zl3073x_dev *zldev = zldpll->dev; 207 + const struct zl3073x_ref *ref; 208 + u8 ref_id, mode, pair; 209 + 210 + ref_id = zl3073x_input_pin_ref_get(pin->id); 211 + ref = zl3073x_ref_state_get(zldev, ref_id); 212 + mode = zl3073x_ref_sync_mode_get(ref); 213 + pair = zl3073x_ref_sync_pair_get(ref); 214 + 215 + if (mode == ZL_REF_SYNC_CTRL_MODE_REFSYNC_PAIR && 216 + pair == zl3073x_input_pin_ref_get(sync_pin->id)) 217 + *state = DPLL_PIN_STATE_CONNECTED; 218 + else 219 + *state = DPLL_PIN_STATE_DISCONNECTED; 220 + 221 + return 0; 222 + } 223 + 224 + static int 225 + zl3073x_dpll_input_pin_ref_sync_set(const struct dpll_pin *dpll_pin, 226 + void *pin_priv, 227 + const struct dpll_pin *ref_sync_pin, 228 + void *ref_sync_pin_priv, 229 + const enum dpll_pin_state state, 230 + struct netlink_ext_ack *extack) 231 + { 232 + struct zl3073x_dpll_pin *sync_pin = ref_sync_pin_priv; 233 + struct zl3073x_dpll_pin *pin = pin_priv; 234 + struct zl3073x_dpll *zldpll = pin->dpll; 235 + struct zl3073x_dev *zldev = zldpll->dev; 236 + u8 mode, ref_id, sync_ref_id; 237 + struct zl3073x_chan chan; 238 + struct zl3073x_ref ref; 239 + int rc; 240 + 241 + ref_id = zl3073x_input_pin_ref_get(pin->id); 242 + sync_ref_id = zl3073x_input_pin_ref_get(sync_pin->id); 243 + ref = *zl3073x_ref_state_get(zldev, ref_id); 244 + 245 + if (state == DPLL_PIN_STATE_CONNECTED) { 246 + const struct zl3073x_ref *sync_ref; 247 + u32 ref_freq, sync_freq; 248 + 249 + sync_ref = zl3073x_ref_state_get(zldev, sync_ref_id); 250 + ref_freq = zl3073x_ref_freq_get(&ref); 251 + sync_freq = zl3073x_ref_freq_get(sync_ref); 252 + 253 + /* Sync signal must be 8 kHz or less and clock reference 254 + * must be 1 kHz or more and higher than the sync signal. 255 + */ 256 + if (sync_freq > 8000) { 257 + NL_SET_ERR_MSG(extack, 258 + "sync frequency must be 8 kHz or less"); 259 + return -EINVAL; 260 + } 261 + if (ref_freq < 1000) { 262 + NL_SET_ERR_MSG(extack, 263 + "clock frequency must be 1 kHz or more"); 264 + return -EINVAL; 265 + } 266 + if (ref_freq <= sync_freq) { 267 + NL_SET_ERR_MSG(extack, 268 + "clock frequency must be higher than sync frequency"); 269 + return -EINVAL; 270 + } 271 + 272 + zl3073x_ref_sync_pair_set(&ref, sync_ref_id); 273 + mode = ZL_REF_SYNC_CTRL_MODE_REFSYNC_PAIR; 274 + } else { 275 + mode = ZL_REF_SYNC_CTRL_MODE_REFSYNC_PAIR_OFF; 276 + } 277 + 278 + zl3073x_ref_sync_mode_set(&ref, mode); 279 + 280 + rc = zl3073x_ref_state_set(zldev, ref_id, &ref); 281 + if (rc) 282 + return rc; 283 + 284 + /* Exclude sync source from automatic reference selection by setting 285 + * its priority to NONE. On disconnect the priority is left as NONE 286 + * and the user must explicitly make the pin selectable again. 287 + */ 288 + if (state == DPLL_PIN_STATE_CONNECTED) { 289 + chan = *zl3073x_chan_state_get(zldev, zldpll->id); 290 + zl3073x_chan_ref_prio_set(&chan, sync_ref_id, 291 + ZL_DPLL_REF_PRIO_NONE); 292 + return zl3073x_chan_state_set(zldev, zldpll->id, &chan); 293 + } 294 + 295 + return 0; 190 296 } 191 297 192 298 static int ··· 699 599 struct zl3073x_dpll_pin *pin = pin_priv; 700 600 const struct zl3073x_synth *synth; 701 601 const struct zl3073x_out *out; 702 - u8 clock_type, out_id; 703 - u32 synth_freq; 602 + u32 synth_freq, out_freq; 603 + u8 out_id; 704 604 705 605 out_id = zl3073x_output_pin_out_get(pin->id); 706 606 out = zl3073x_out_state_get(zldev, out_id); ··· 709 609 * for N-division is also used for the esync divider so both cannot 710 610 * be used. 711 611 */ 712 - switch (zl3073x_out_signal_format_get(out)) { 713 - case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV: 714 - case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV_INV: 612 + if (zl3073x_out_is_ndiv(out)) 715 613 return -EOPNOTSUPP; 716 - default: 717 - break; 718 - } 719 614 720 615 /* Get attached synth frequency */ 721 616 synth = zl3073x_synth_state_get(zldev, zl3073x_out_synth_get(out)); 722 617 synth_freq = zl3073x_synth_freq_get(synth); 618 + out_freq = synth_freq / out->div; 723 619 724 - clock_type = FIELD_GET(ZL_OUTPUT_MODE_CLOCK_TYPE, out->mode); 725 - if (clock_type != ZL_OUTPUT_MODE_CLOCK_TYPE_ESYNC) { 620 + if (!pin->esync_control || out_freq <= 1) 621 + return -EOPNOTSUPP; 622 + 623 + esync->range = esync_freq_ranges; 624 + esync->range_num = ARRAY_SIZE(esync_freq_ranges); 625 + 626 + if (zl3073x_out_clock_type_get(out) != ZL_OUTPUT_MODE_CLOCK_TYPE_ESYNC) { 726 627 /* No need to read esync data if it is not enabled */ 727 628 esync->freq = 0; 728 629 esync->pulse = 0; 729 630 730 - goto finish; 631 + return 0; 731 632 } 732 633 733 634 /* Compute esync frequency */ 734 - esync->freq = synth_freq / out->div / out->esync_n_period; 635 + esync->freq = out_freq / out->esync_n_period; 735 636 736 637 /* By comparing the esync_pulse_width to the half of the pulse width 737 638 * the esync pulse percentage can be determined. ··· 740 639 * is why it reduces down to be output_div. 741 640 */ 742 641 esync->pulse = (50 * out->esync_n_width) / out->div; 743 - 744 - finish: 745 - /* Set supported esync ranges if the pin supports esync control and 746 - * if the output frequency is > 1 Hz. 747 - */ 748 - if (pin->esync_control && (synth_freq / out->div) > 1) { 749 - esync->range = esync_freq_ranges; 750 - esync->range_num = ARRAY_SIZE(esync_freq_ranges); 751 - } else { 752 - esync->range = NULL; 753 - esync->range_num = 0; 754 - } 755 642 756 643 return 0; 757 644 } ··· 756 667 struct zl3073x_dpll_pin *pin = pin_priv; 757 668 const struct zl3073x_synth *synth; 758 669 struct zl3073x_out out; 759 - u8 clock_type, out_id; 760 670 u32 synth_freq; 671 + u8 out_id; 761 672 762 673 out_id = zl3073x_output_pin_out_get(pin->id); 763 674 out = *zl3073x_out_state_get(zldev, out_id); ··· 766 677 * for N-division is also used for the esync divider so both cannot 767 678 * be used. 768 679 */ 769 - switch (zl3073x_out_signal_format_get(&out)) { 770 - case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV: 771 - case ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV_INV: 680 + if (zl3073x_out_is_ndiv(&out)) 772 681 return -EOPNOTSUPP; 773 - default: 774 - break; 775 - } 776 - 777 - /* Select clock type */ 778 - if (freq) 779 - clock_type = ZL_OUTPUT_MODE_CLOCK_TYPE_ESYNC; 780 - else 781 - clock_type = ZL_OUTPUT_MODE_CLOCK_TYPE_NORMAL; 782 682 783 683 /* Update clock type in output mode */ 784 - out.mode &= ~ZL_OUTPUT_MODE_CLOCK_TYPE; 785 - out.mode |= FIELD_PREP(ZL_OUTPUT_MODE_CLOCK_TYPE, clock_type); 684 + if (freq) 685 + zl3073x_out_clock_type_set(&out, 686 + ZL_OUTPUT_MODE_CLOCK_TYPE_ESYNC); 687 + else 688 + zl3073x_out_clock_type_set(&out, 689 + ZL_OUTPUT_MODE_CLOCK_TYPE_NORMAL); 786 690 787 691 /* If esync is being disabled just write mailbox and finish */ 788 692 if (!freq) ··· 827 745 struct zl3073x_dev *zldev = zldpll->dev; 828 746 struct zl3073x_dpll_pin *pin = pin_priv; 829 747 const struct zl3073x_synth *synth; 830 - u8 out_id, signal_format; 831 748 u32 new_div, synth_freq; 832 749 struct zl3073x_out out; 750 + u8 out_id; 833 751 834 752 out_id = zl3073x_output_pin_out_get(pin->id); 835 753 out = *zl3073x_out_state_get(zldev, out_id); ··· 839 757 synth_freq = zl3073x_synth_freq_get(synth); 840 758 new_div = synth_freq / (u32)frequency; 841 759 842 - /* Get used signal format for the given output */ 843 - signal_format = zl3073x_out_signal_format_get(&out); 844 - 845 760 /* Check signal format */ 846 - if (signal_format != ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV && 847 - signal_format != ZL_OUTPUT_MODE_SIGNAL_FORMAT_2_NDIV_INV) { 761 + if (!zl3073x_out_is_ndiv(&out)) { 848 762 /* For non N-divided signal formats the frequency is computed 849 763 * as division of synth frequency and output divisor. 850 764 */ ··· 1253 1175 .phase_adjust_set = zl3073x_dpll_input_pin_phase_adjust_set, 1254 1176 .prio_get = zl3073x_dpll_input_pin_prio_get, 1255 1177 .prio_set = zl3073x_dpll_input_pin_prio_set, 1178 + .ref_sync_get = zl3073x_dpll_input_pin_ref_sync_get, 1179 + .ref_sync_set = zl3073x_dpll_input_pin_ref_sync_set, 1256 1180 .state_on_dpll_get = zl3073x_dpll_input_pin_state_on_dpll_get, 1257 1181 .state_on_dpll_set = zl3073x_dpll_input_pin_state_on_dpll_set, 1258 1182 }; ··· 1347 1267 if (IS_ERR(props)) 1348 1268 return PTR_ERR(props); 1349 1269 1350 - /* Save package label, esync capability and phase adjust granularity */ 1270 + /* Save package label, fwnode, esync capability and phase adjust 1271 + * granularity. 1272 + */ 1351 1273 strscpy(pin->label, props->package_label); 1274 + pin->fwnode = fwnode_handle_get(props->fwnode); 1352 1275 pin->esync_control = props->esync_control; 1353 1276 pin->phase_gran = props->dpll_props.phase_gran; 1354 1277 ··· 1396 1313 dpll_pin_put(pin->dpll_pin, &pin->tracker); 1397 1314 pin->dpll_pin = NULL; 1398 1315 err_pin_get: 1316 + fwnode_handle_put(pin->fwnode); 1317 + pin->fwnode = NULL; 1399 1318 zl3073x_pin_props_put(props); 1400 1319 1401 1320 return rc; ··· 1427 1342 1428 1343 dpll_pin_put(pin->dpll_pin, &pin->tracker); 1429 1344 pin->dpll_pin = NULL; 1345 + 1346 + fwnode_handle_put(pin->fwnode); 1347 + pin->fwnode = NULL; 1430 1348 } 1431 1349 1432 1350 /** ··· 1944 1856 } 1945 1857 1946 1858 /** 1859 + * zl3073x_dpll_ref_sync_pair_register - register ref_sync pairs for a pin 1860 + * @pin: pointer to zl3073x_dpll_pin structure 1861 + * 1862 + * Iterates 'ref-sync-sources' phandles in the pin's firmware node and 1863 + * registers each declared pairing. 1864 + * 1865 + * Return: 0 on success, <0 on error 1866 + */ 1867 + static int 1868 + zl3073x_dpll_ref_sync_pair_register(struct zl3073x_dpll_pin *pin) 1869 + { 1870 + struct zl3073x_dev *zldev = pin->dpll->dev; 1871 + struct fwnode_handle *fwnode; 1872 + struct dpll_pin *sync_pin; 1873 + dpll_tracker tracker; 1874 + int n, rc; 1875 + 1876 + for (n = 0; ; n++) { 1877 + /* Get n'th ref-sync source */ 1878 + fwnode = fwnode_find_reference(pin->fwnode, "ref-sync-sources", 1879 + n); 1880 + if (IS_ERR(fwnode)) { 1881 + rc = PTR_ERR(fwnode); 1882 + break; 1883 + } 1884 + 1885 + /* Find associated dpll pin */ 1886 + sync_pin = fwnode_dpll_pin_find(fwnode, &tracker); 1887 + fwnode_handle_put(fwnode); 1888 + if (!sync_pin) { 1889 + dev_warn(zldev->dev, "%s: ref-sync source %d not found", 1890 + pin->label, n); 1891 + continue; 1892 + } 1893 + 1894 + /* Register new ref-sync pair */ 1895 + rc = dpll_pin_ref_sync_pair_add(pin->dpll_pin, sync_pin); 1896 + dpll_pin_put(sync_pin, &tracker); 1897 + 1898 + /* -EBUSY means pairing already exists from another DPLL's 1899 + * registration. 1900 + */ 1901 + if (rc && rc != -EBUSY) { 1902 + dev_err(zldev->dev, 1903 + "%s: failed to add ref-sync source %d: %pe", 1904 + pin->label, n, ERR_PTR(rc)); 1905 + break; 1906 + } 1907 + } 1908 + 1909 + return rc != -ENOENT ? rc : 0; 1910 + } 1911 + 1912 + /** 1913 + * zl3073x_dpll_ref_sync_pairs_register - register ref_sync pairs for a DPLL 1914 + * @zldpll: pointer to zl3073x_dpll structure 1915 + * 1916 + * Iterates all registered input pins of the given DPLL and establishes 1917 + * ref_sync pairings declared by 'ref-sync-sources' phandles in the 1918 + * device tree. 1919 + * 1920 + * Return: 0 on success, <0 on error 1921 + */ 1922 + static int 1923 + zl3073x_dpll_ref_sync_pairs_register(struct zl3073x_dpll *zldpll) 1924 + { 1925 + struct zl3073x_dpll_pin *pin; 1926 + int rc; 1927 + 1928 + list_for_each_entry(pin, &zldpll->pins, list) { 1929 + if (!zl3073x_dpll_is_input_pin(pin) || !pin->fwnode) 1930 + continue; 1931 + 1932 + rc = zl3073x_dpll_ref_sync_pair_register(pin); 1933 + if (rc) 1934 + return rc; 1935 + } 1936 + 1937 + return 0; 1938 + } 1939 + 1940 + /** 1947 1941 * zl3073x_dpll_register - register DPLL device and all its pins 1948 1942 * @zldpll: pointer to zl3073x_dpll structure 1949 1943 * ··· 2044 1874 2045 1875 rc = zl3073x_dpll_pins_register(zldpll); 2046 1876 if (rc) { 1877 + zl3073x_dpll_device_unregister(zldpll); 1878 + return rc; 1879 + } 1880 + 1881 + rc = zl3073x_dpll_ref_sync_pairs_register(zldpll); 1882 + if (rc) { 1883 + zl3073x_dpll_pins_unregister(zldpll); 2047 1884 zl3073x_dpll_device_unregister(zldpll); 2048 1885 return rc; 2049 1886 }
+1 -2
drivers/dpll/zl3073x/flash.c
··· 194 194 if (rc) 195 195 return rc; 196 196 197 - value &= ~ZL_WRITE_FLASH_OP; 198 - value |= FIELD_PREP(ZL_WRITE_FLASH_OP, operation); 197 + FIELD_MODIFY(ZL_WRITE_FLASH_OP, &value, operation); 199 198 200 199 rc = zl3073x_write_u8(zldev, ZL_REG_WRITE_FLASH, value); 201 200 if (rc)
+22
drivers/dpll/zl3073x/out.h
··· 43 43 const struct zl3073x_out *out); 44 44 45 45 /** 46 + * zl3073x_out_clock_type_get - get output clock type 47 + * @out: pointer to out state 48 + * 49 + * Return: clock type of given output (ZL_OUTPUT_MODE_CLOCK_TYPE_*) 50 + */ 51 + static inline u8 zl3073x_out_clock_type_get(const struct zl3073x_out *out) 52 + { 53 + return FIELD_GET(ZL_OUTPUT_MODE_CLOCK_TYPE, out->mode); 54 + } 55 + 56 + /** 57 + * zl3073x_out_clock_type_set - set output clock type 58 + * @out: pointer to out state 59 + * @type: clock type (ZL_OUTPUT_MODE_CLOCK_TYPE_*) 60 + */ 61 + static inline void 62 + zl3073x_out_clock_type_set(struct zl3073x_out *out, u8 type) 63 + { 64 + FIELD_MODIFY(ZL_OUTPUT_MODE_CLOCK_TYPE, &out->mode, type); 65 + } 66 + 67 + /** 46 68 * zl3073x_out_signal_format_get - get output signal format 47 69 * @out: pointer to out state 48 70 *
+46
drivers/dpll/zl3073x/ref.h
··· 121 121 } 122 122 123 123 /** 124 + * zl3073x_ref_sync_mode_get - get sync control mode 125 + * @ref: pointer to ref state 126 + * 127 + * Return: sync control mode (ZL_REF_SYNC_CTRL_MODE_*) 128 + */ 129 + static inline u8 130 + zl3073x_ref_sync_mode_get(const struct zl3073x_ref *ref) 131 + { 132 + return FIELD_GET(ZL_REF_SYNC_CTRL_MODE, ref->sync_ctrl); 133 + } 134 + 135 + /** 136 + * zl3073x_ref_sync_mode_set - set sync control mode 137 + * @ref: pointer to ref state 138 + * @mode: sync control mode (ZL_REF_SYNC_CTRL_MODE_*) 139 + */ 140 + static inline void 141 + zl3073x_ref_sync_mode_set(struct zl3073x_ref *ref, u8 mode) 142 + { 143 + FIELD_MODIFY(ZL_REF_SYNC_CTRL_MODE, &ref->sync_ctrl, mode); 144 + } 145 + 146 + /** 147 + * zl3073x_ref_sync_pair_get - get sync pair reference index 148 + * @ref: pointer to ref state 149 + * 150 + * Return: paired reference index 151 + */ 152 + static inline u8 153 + zl3073x_ref_sync_pair_get(const struct zl3073x_ref *ref) 154 + { 155 + return FIELD_GET(ZL_REF_SYNC_CTRL_PAIR, ref->sync_ctrl); 156 + } 157 + 158 + /** 159 + * zl3073x_ref_sync_pair_set - set sync pair reference index 160 + * @ref: pointer to ref state 161 + * @pair: paired reference index 162 + */ 163 + static inline void 164 + zl3073x_ref_sync_pair_set(struct zl3073x_ref *ref, u8 pair) 165 + { 166 + FIELD_MODIFY(ZL_REF_SYNC_CTRL_PAIR, &ref->sync_ctrl, pair); 167 + } 168 + 169 + /** 124 170 * zl3073x_ref_is_diff - check if the given input reference is differential 125 171 * @ref: pointer to ref state 126 172 *
+2
drivers/dpll/zl3073x/regs.h
··· 213 213 #define ZL_REG_REF_SYNC_CTRL ZL_REG(10, 0x2e, 1) 214 214 #define ZL_REF_SYNC_CTRL_MODE GENMASK(2, 0) 215 215 #define ZL_REF_SYNC_CTRL_MODE_REFSYNC_PAIR_OFF 0 216 + #define ZL_REF_SYNC_CTRL_MODE_REFSYNC_PAIR 1 216 217 #define ZL_REF_SYNC_CTRL_MODE_50_50_ESYNC_25_75 2 218 + #define ZL_REF_SYNC_CTRL_PAIR GENMASK(7, 4) 217 219 218 220 #define ZL_REG_REF_ESYNC_DIV ZL_REG(10, 0x30, 4) 219 221 #define ZL_REF_ESYNC_DIV_1HZ 0