1*a99a9f0eSIvan Vecera // SPDX-License-Identifier: GPL-2.0-only 2*a99a9f0eSIvan Vecera 3*a99a9f0eSIvan Vecera #include <linux/array_size.h> 4*a99a9f0eSIvan Vecera #include <linux/dev_printk.h> 5*a99a9f0eSIvan Vecera #include <linux/err.h> 6*a99a9f0eSIvan Vecera #include <linux/errno.h> 7*a99a9f0eSIvan Vecera #include <linux/fwnode.h> 8*a99a9f0eSIvan Vecera #include <linux/property.h> 9*a99a9f0eSIvan Vecera #include <linux/slab.h> 10*a99a9f0eSIvan Vecera #include <linux/string.h> 11*a99a9f0eSIvan Vecera 12*a99a9f0eSIvan Vecera #include "core.h" 13*a99a9f0eSIvan Vecera #include "prop.h" 14*a99a9f0eSIvan Vecera 15*a99a9f0eSIvan Vecera /** 16*a99a9f0eSIvan Vecera * zl3073x_pin_check_freq - verify frequency for given pin 17*a99a9f0eSIvan Vecera * @zldev: pointer to zl3073x device 18*a99a9f0eSIvan Vecera * @dir: pin direction 19*a99a9f0eSIvan Vecera * @id: pin index 20*a99a9f0eSIvan Vecera * @freq: frequency to check 21*a99a9f0eSIvan Vecera * 22*a99a9f0eSIvan Vecera * The function checks the given frequency is valid for the device. For input 23*a99a9f0eSIvan Vecera * pins it checks that the frequency can be factorized using supported base 24*a99a9f0eSIvan Vecera * frequencies. For output pins it checks that the frequency divides connected 25*a99a9f0eSIvan Vecera * synth frequency without remainder. 26*a99a9f0eSIvan Vecera * 27*a99a9f0eSIvan Vecera * Return: true if the frequency is valid, false if not. 28*a99a9f0eSIvan Vecera */ 29*a99a9f0eSIvan Vecera static bool 30*a99a9f0eSIvan Vecera zl3073x_pin_check_freq(struct zl3073x_dev *zldev, enum dpll_pin_direction dir, 31*a99a9f0eSIvan Vecera u8 id, u64 freq) 32*a99a9f0eSIvan Vecera { 33*a99a9f0eSIvan Vecera if (freq > U32_MAX) 34*a99a9f0eSIvan Vecera goto err_inv_freq; 35*a99a9f0eSIvan Vecera 36*a99a9f0eSIvan Vecera if (dir == DPLL_PIN_DIRECTION_INPUT) { 37*a99a9f0eSIvan Vecera int rc; 38*a99a9f0eSIvan Vecera 39*a99a9f0eSIvan Vecera /* Check if the frequency can be factorized */ 40*a99a9f0eSIvan Vecera rc = zl3073x_ref_freq_factorize(freq, NULL, NULL); 41*a99a9f0eSIvan Vecera if (rc) 42*a99a9f0eSIvan Vecera goto err_inv_freq; 43*a99a9f0eSIvan Vecera } else { 44*a99a9f0eSIvan Vecera u32 synth_freq; 45*a99a9f0eSIvan Vecera u8 out, synth; 46*a99a9f0eSIvan Vecera 47*a99a9f0eSIvan Vecera /* Get output pin synthesizer */ 48*a99a9f0eSIvan Vecera out = zl3073x_output_pin_out_get(id); 49*a99a9f0eSIvan Vecera synth = zl3073x_out_synth_get(zldev, out); 50*a99a9f0eSIvan Vecera 51*a99a9f0eSIvan Vecera /* Get synth frequency */ 52*a99a9f0eSIvan Vecera synth_freq = zl3073x_synth_freq_get(zldev, synth); 53*a99a9f0eSIvan Vecera 54*a99a9f0eSIvan Vecera /* Check the frequency divides synth frequency */ 55*a99a9f0eSIvan Vecera if (synth_freq % (u32)freq) 56*a99a9f0eSIvan Vecera goto err_inv_freq; 57*a99a9f0eSIvan Vecera } 58*a99a9f0eSIvan Vecera 59*a99a9f0eSIvan Vecera return true; 60*a99a9f0eSIvan Vecera 61*a99a9f0eSIvan Vecera err_inv_freq: 62*a99a9f0eSIvan Vecera dev_warn(zldev->dev, 63*a99a9f0eSIvan Vecera "Unsupported frequency %llu Hz in firmware node\n", freq); 64*a99a9f0eSIvan Vecera 65*a99a9f0eSIvan Vecera return false; 66*a99a9f0eSIvan Vecera } 67*a99a9f0eSIvan Vecera 68*a99a9f0eSIvan Vecera /** 69*a99a9f0eSIvan Vecera * zl3073x_prop_pin_package_label_set - get package label for the pin 70*a99a9f0eSIvan Vecera * @zldev: pointer to zl3073x device 71*a99a9f0eSIvan Vecera * @props: pointer to pin properties 72*a99a9f0eSIvan Vecera * @dir: pin direction 73*a99a9f0eSIvan Vecera * @id: pin index 74*a99a9f0eSIvan Vecera * 75*a99a9f0eSIvan Vecera * Generates package label string and stores it into pin properties structure. 76*a99a9f0eSIvan Vecera * 77*a99a9f0eSIvan Vecera * Possible formats: 78*a99a9f0eSIvan Vecera * REF<n> - differential input reference 79*a99a9f0eSIvan Vecera * REF<n>P & REF<n>N - single-ended input reference (P or N pin) 80*a99a9f0eSIvan Vecera * OUT<n> - differential output 81*a99a9f0eSIvan Vecera * OUT<n>P & OUT<n>N - single-ended output (P or N pin) 82*a99a9f0eSIvan Vecera */ 83*a99a9f0eSIvan Vecera static void 84*a99a9f0eSIvan Vecera zl3073x_prop_pin_package_label_set(struct zl3073x_dev *zldev, 85*a99a9f0eSIvan Vecera struct zl3073x_pin_props *props, 86*a99a9f0eSIvan Vecera enum dpll_pin_direction dir, u8 id) 87*a99a9f0eSIvan Vecera { 88*a99a9f0eSIvan Vecera const char *prefix, *suffix; 89*a99a9f0eSIvan Vecera bool is_diff; 90*a99a9f0eSIvan Vecera 91*a99a9f0eSIvan Vecera if (dir == DPLL_PIN_DIRECTION_INPUT) { 92*a99a9f0eSIvan Vecera u8 ref; 93*a99a9f0eSIvan Vecera 94*a99a9f0eSIvan Vecera prefix = "REF"; 95*a99a9f0eSIvan Vecera ref = zl3073x_input_pin_ref_get(id); 96*a99a9f0eSIvan Vecera is_diff = zl3073x_ref_is_diff(zldev, ref); 97*a99a9f0eSIvan Vecera } else { 98*a99a9f0eSIvan Vecera u8 out; 99*a99a9f0eSIvan Vecera 100*a99a9f0eSIvan Vecera prefix = "OUT"; 101*a99a9f0eSIvan Vecera out = zl3073x_output_pin_out_get(id); 102*a99a9f0eSIvan Vecera is_diff = zl3073x_out_is_diff(zldev, out); 103*a99a9f0eSIvan Vecera } 104*a99a9f0eSIvan Vecera 105*a99a9f0eSIvan Vecera if (!is_diff) 106*a99a9f0eSIvan Vecera suffix = zl3073x_is_p_pin(id) ? "P" : "N"; 107*a99a9f0eSIvan Vecera else 108*a99a9f0eSIvan Vecera suffix = ""; /* No suffix for differential one */ 109*a99a9f0eSIvan Vecera 110*a99a9f0eSIvan Vecera snprintf(props->package_label, sizeof(props->package_label), "%s%u%s", 111*a99a9f0eSIvan Vecera prefix, id / 2, suffix); 112*a99a9f0eSIvan Vecera 113*a99a9f0eSIvan Vecera /* Set package_label pointer in DPLL core properties to generated 114*a99a9f0eSIvan Vecera * string. 115*a99a9f0eSIvan Vecera */ 116*a99a9f0eSIvan Vecera props->dpll_props.package_label = props->package_label; 117*a99a9f0eSIvan Vecera } 118*a99a9f0eSIvan Vecera 119*a99a9f0eSIvan Vecera /** 120*a99a9f0eSIvan Vecera * zl3073x_prop_pin_fwnode_get - get fwnode for given pin 121*a99a9f0eSIvan Vecera * @zldev: pointer to zl3073x device 122*a99a9f0eSIvan Vecera * @props: pointer to pin properties 123*a99a9f0eSIvan Vecera * @dir: pin direction 124*a99a9f0eSIvan Vecera * @id: pin index 125*a99a9f0eSIvan Vecera * 126*a99a9f0eSIvan Vecera * Return: 0 on success, -ENOENT if the firmware node does not exist 127*a99a9f0eSIvan Vecera */ 128*a99a9f0eSIvan Vecera static int 129*a99a9f0eSIvan Vecera zl3073x_prop_pin_fwnode_get(struct zl3073x_dev *zldev, 130*a99a9f0eSIvan Vecera struct zl3073x_pin_props *props, 131*a99a9f0eSIvan Vecera enum dpll_pin_direction dir, u8 id) 132*a99a9f0eSIvan Vecera { 133*a99a9f0eSIvan Vecera struct fwnode_handle *pins_node, *pin_node; 134*a99a9f0eSIvan Vecera const char *node_name; 135*a99a9f0eSIvan Vecera 136*a99a9f0eSIvan Vecera if (dir == DPLL_PIN_DIRECTION_INPUT) 137*a99a9f0eSIvan Vecera node_name = "input-pins"; 138*a99a9f0eSIvan Vecera else 139*a99a9f0eSIvan Vecera node_name = "output-pins"; 140*a99a9f0eSIvan Vecera 141*a99a9f0eSIvan Vecera /* Get node containing input or output pins */ 142*a99a9f0eSIvan Vecera pins_node = device_get_named_child_node(zldev->dev, node_name); 143*a99a9f0eSIvan Vecera if (!pins_node) { 144*a99a9f0eSIvan Vecera dev_dbg(zldev->dev, "'%s' sub-node is missing\n", node_name); 145*a99a9f0eSIvan Vecera return -ENOENT; 146*a99a9f0eSIvan Vecera } 147*a99a9f0eSIvan Vecera 148*a99a9f0eSIvan Vecera /* Enumerate child pin nodes and find the requested one */ 149*a99a9f0eSIvan Vecera fwnode_for_each_child_node(pins_node, pin_node) { 150*a99a9f0eSIvan Vecera u32 reg; 151*a99a9f0eSIvan Vecera 152*a99a9f0eSIvan Vecera if (fwnode_property_read_u32(pin_node, "reg", ®)) 153*a99a9f0eSIvan Vecera continue; 154*a99a9f0eSIvan Vecera 155*a99a9f0eSIvan Vecera if (id == reg) 156*a99a9f0eSIvan Vecera break; 157*a99a9f0eSIvan Vecera } 158*a99a9f0eSIvan Vecera 159*a99a9f0eSIvan Vecera /* Release pin parent node */ 160*a99a9f0eSIvan Vecera fwnode_handle_put(pins_node); 161*a99a9f0eSIvan Vecera 162*a99a9f0eSIvan Vecera /* Save found node */ 163*a99a9f0eSIvan Vecera props->fwnode = pin_node; 164*a99a9f0eSIvan Vecera 165*a99a9f0eSIvan Vecera dev_dbg(zldev->dev, "Firmware node for %s %sfound\n", 166*a99a9f0eSIvan Vecera props->package_label, pin_node ? "" : "NOT "); 167*a99a9f0eSIvan Vecera 168*a99a9f0eSIvan Vecera return pin_node ? 0 : -ENOENT; 169*a99a9f0eSIvan Vecera } 170*a99a9f0eSIvan Vecera 171*a99a9f0eSIvan Vecera /** 172*a99a9f0eSIvan Vecera * zl3073x_pin_props_get - get pin properties 173*a99a9f0eSIvan Vecera * @zldev: pointer to zl3073x device 174*a99a9f0eSIvan Vecera * @dir: pin direction 175*a99a9f0eSIvan Vecera * @index: pin index 176*a99a9f0eSIvan Vecera * 177*a99a9f0eSIvan Vecera * The function looks for firmware node for the given pin if it is provided 178*a99a9f0eSIvan Vecera * by the system firmware (DT or ACPI), allocates pin properties structure, 179*a99a9f0eSIvan Vecera * generates package label string according pin type and optionally fetches 180*a99a9f0eSIvan Vecera * board label, connection type, supported frequencies and esync capability 181*a99a9f0eSIvan Vecera * from the firmware node if it does exist. 182*a99a9f0eSIvan Vecera * 183*a99a9f0eSIvan Vecera * Pointer that is returned by this function should be freed using 184*a99a9f0eSIvan Vecera * @zl3073x_pin_props_put(). 185*a99a9f0eSIvan Vecera * 186*a99a9f0eSIvan Vecera * Return: 187*a99a9f0eSIvan Vecera * * pointer to allocated pin properties structure on success 188*a99a9f0eSIvan Vecera * * error pointer in case of error 189*a99a9f0eSIvan Vecera */ 190*a99a9f0eSIvan Vecera struct zl3073x_pin_props *zl3073x_pin_props_get(struct zl3073x_dev *zldev, 191*a99a9f0eSIvan Vecera enum dpll_pin_direction dir, 192*a99a9f0eSIvan Vecera u8 index) 193*a99a9f0eSIvan Vecera { 194*a99a9f0eSIvan Vecera struct dpll_pin_frequency *ranges; 195*a99a9f0eSIvan Vecera struct zl3073x_pin_props *props; 196*a99a9f0eSIvan Vecera int i, j, num_freqs, rc; 197*a99a9f0eSIvan Vecera const char *type; 198*a99a9f0eSIvan Vecera u64 *freqs; 199*a99a9f0eSIvan Vecera 200*a99a9f0eSIvan Vecera props = kzalloc(sizeof(*props), GFP_KERNEL); 201*a99a9f0eSIvan Vecera if (!props) 202*a99a9f0eSIvan Vecera return ERR_PTR(-ENOMEM); 203*a99a9f0eSIvan Vecera 204*a99a9f0eSIvan Vecera /* Set default pin type */ 205*a99a9f0eSIvan Vecera if (dir == DPLL_PIN_DIRECTION_INPUT) 206*a99a9f0eSIvan Vecera props->dpll_props.type = DPLL_PIN_TYPE_EXT; 207*a99a9f0eSIvan Vecera else 208*a99a9f0eSIvan Vecera props->dpll_props.type = DPLL_PIN_TYPE_GNSS; 209*a99a9f0eSIvan Vecera 210*a99a9f0eSIvan Vecera props->dpll_props.phase_range.min = S32_MIN; 211*a99a9f0eSIvan Vecera props->dpll_props.phase_range.max = S32_MAX; 212*a99a9f0eSIvan Vecera 213*a99a9f0eSIvan Vecera zl3073x_prop_pin_package_label_set(zldev, props, dir, index); 214*a99a9f0eSIvan Vecera 215*a99a9f0eSIvan Vecera /* Get firmware node for the given pin */ 216*a99a9f0eSIvan Vecera rc = zl3073x_prop_pin_fwnode_get(zldev, props, dir, index); 217*a99a9f0eSIvan Vecera if (rc) 218*a99a9f0eSIvan Vecera return props; /* Return if it does not exist */ 219*a99a9f0eSIvan Vecera 220*a99a9f0eSIvan Vecera /* Look for label property and store the value as board label */ 221*a99a9f0eSIvan Vecera fwnode_property_read_string(props->fwnode, "label", 222*a99a9f0eSIvan Vecera &props->dpll_props.board_label); 223*a99a9f0eSIvan Vecera 224*a99a9f0eSIvan Vecera /* Look for pin type property and translate its value to DPLL 225*a99a9f0eSIvan Vecera * pin type enum if it is present. 226*a99a9f0eSIvan Vecera */ 227*a99a9f0eSIvan Vecera if (!fwnode_property_read_string(props->fwnode, "connection-type", 228*a99a9f0eSIvan Vecera &type)) { 229*a99a9f0eSIvan Vecera if (!strcmp(type, "ext")) 230*a99a9f0eSIvan Vecera props->dpll_props.type = DPLL_PIN_TYPE_EXT; 231*a99a9f0eSIvan Vecera else if (!strcmp(type, "gnss")) 232*a99a9f0eSIvan Vecera props->dpll_props.type = DPLL_PIN_TYPE_GNSS; 233*a99a9f0eSIvan Vecera else if (!strcmp(type, "int")) 234*a99a9f0eSIvan Vecera props->dpll_props.type = DPLL_PIN_TYPE_INT_OSCILLATOR; 235*a99a9f0eSIvan Vecera else if (!strcmp(type, "synce")) 236*a99a9f0eSIvan Vecera props->dpll_props.type = DPLL_PIN_TYPE_SYNCE_ETH_PORT; 237*a99a9f0eSIvan Vecera else 238*a99a9f0eSIvan Vecera dev_warn(zldev->dev, 239*a99a9f0eSIvan Vecera "Unknown or unsupported pin type '%s'\n", 240*a99a9f0eSIvan Vecera type); 241*a99a9f0eSIvan Vecera } 242*a99a9f0eSIvan Vecera 243*a99a9f0eSIvan Vecera /* Check if the pin supports embedded sync control */ 244*a99a9f0eSIvan Vecera props->esync_control = fwnode_property_read_bool(props->fwnode, 245*a99a9f0eSIvan Vecera "esync-control"); 246*a99a9f0eSIvan Vecera 247*a99a9f0eSIvan Vecera /* Read supported frequencies property if it is specified */ 248*a99a9f0eSIvan Vecera num_freqs = fwnode_property_count_u64(props->fwnode, 249*a99a9f0eSIvan Vecera "supported-frequencies-hz"); 250*a99a9f0eSIvan Vecera if (num_freqs <= 0) 251*a99a9f0eSIvan Vecera /* Return if the property does not exist or number is 0 */ 252*a99a9f0eSIvan Vecera return props; 253*a99a9f0eSIvan Vecera 254*a99a9f0eSIvan Vecera /* The firmware node specifies list of supported frequencies while 255*a99a9f0eSIvan Vecera * DPLL core pin properties requires list of frequency ranges. 256*a99a9f0eSIvan Vecera * So read the frequency list into temporary array. 257*a99a9f0eSIvan Vecera */ 258*a99a9f0eSIvan Vecera freqs = kcalloc(num_freqs, sizeof(*freqs), GFP_KERNEL); 259*a99a9f0eSIvan Vecera if (!freqs) { 260*a99a9f0eSIvan Vecera rc = -ENOMEM; 261*a99a9f0eSIvan Vecera goto err_alloc_freqs; 262*a99a9f0eSIvan Vecera } 263*a99a9f0eSIvan Vecera 264*a99a9f0eSIvan Vecera /* Read frequencies list from firmware node */ 265*a99a9f0eSIvan Vecera fwnode_property_read_u64_array(props->fwnode, 266*a99a9f0eSIvan Vecera "supported-frequencies-hz", freqs, 267*a99a9f0eSIvan Vecera num_freqs); 268*a99a9f0eSIvan Vecera 269*a99a9f0eSIvan Vecera /* Allocate frequency ranges list and fill it */ 270*a99a9f0eSIvan Vecera ranges = kcalloc(num_freqs, sizeof(*ranges), GFP_KERNEL); 271*a99a9f0eSIvan Vecera if (!ranges) { 272*a99a9f0eSIvan Vecera rc = -ENOMEM; 273*a99a9f0eSIvan Vecera goto err_alloc_ranges; 274*a99a9f0eSIvan Vecera } 275*a99a9f0eSIvan Vecera 276*a99a9f0eSIvan Vecera /* Convert list of frequencies to list of frequency ranges but 277*a99a9f0eSIvan Vecera * filter-out frequencies that are not representable by device 278*a99a9f0eSIvan Vecera */ 279*a99a9f0eSIvan Vecera for (i = 0, j = 0; i < num_freqs; i++) { 280*a99a9f0eSIvan Vecera struct dpll_pin_frequency freq = DPLL_PIN_FREQUENCY(freqs[i]); 281*a99a9f0eSIvan Vecera 282*a99a9f0eSIvan Vecera if (zl3073x_pin_check_freq(zldev, dir, index, freqs[i])) { 283*a99a9f0eSIvan Vecera ranges[j] = freq; 284*a99a9f0eSIvan Vecera j++; 285*a99a9f0eSIvan Vecera } 286*a99a9f0eSIvan Vecera } 287*a99a9f0eSIvan Vecera 288*a99a9f0eSIvan Vecera /* Save number of freq ranges and pointer to them into pin properties */ 289*a99a9f0eSIvan Vecera props->dpll_props.freq_supported = ranges; 290*a99a9f0eSIvan Vecera props->dpll_props.freq_supported_num = j; 291*a99a9f0eSIvan Vecera 292*a99a9f0eSIvan Vecera /* Free temporary array */ 293*a99a9f0eSIvan Vecera kfree(freqs); 294*a99a9f0eSIvan Vecera 295*a99a9f0eSIvan Vecera return props; 296*a99a9f0eSIvan Vecera 297*a99a9f0eSIvan Vecera err_alloc_ranges: 298*a99a9f0eSIvan Vecera kfree(freqs); 299*a99a9f0eSIvan Vecera err_alloc_freqs: 300*a99a9f0eSIvan Vecera fwnode_handle_put(props->fwnode); 301*a99a9f0eSIvan Vecera kfree(props); 302*a99a9f0eSIvan Vecera 303*a99a9f0eSIvan Vecera return ERR_PTR(rc); 304*a99a9f0eSIvan Vecera } 305*a99a9f0eSIvan Vecera 306*a99a9f0eSIvan Vecera /** 307*a99a9f0eSIvan Vecera * zl3073x_pin_props_put - release pin properties 308*a99a9f0eSIvan Vecera * @props: pin properties to free 309*a99a9f0eSIvan Vecera * 310*a99a9f0eSIvan Vecera * The function deallocates given pin properties structure. 311*a99a9f0eSIvan Vecera */ 312*a99a9f0eSIvan Vecera void zl3073x_pin_props_put(struct zl3073x_pin_props *props) 313*a99a9f0eSIvan Vecera { 314*a99a9f0eSIvan Vecera /* Free supported frequency ranges list if it is present */ 315*a99a9f0eSIvan Vecera kfree(props->dpll_props.freq_supported); 316*a99a9f0eSIvan Vecera 317*a99a9f0eSIvan Vecera /* Put firmware handle if it is present */ 318*a99a9f0eSIvan Vecera if (props->fwnode) 319*a99a9f0eSIvan Vecera fwnode_handle_put(props->fwnode); 320*a99a9f0eSIvan Vecera 321*a99a9f0eSIvan Vecera kfree(props); 322*a99a9f0eSIvan Vecera } 323*a99a9f0eSIvan Vecera 324*a99a9f0eSIvan Vecera /** 325*a99a9f0eSIvan Vecera * zl3073x_prop_dpll_type_get - get DPLL channel type 326*a99a9f0eSIvan Vecera * @zldev: pointer to zl3073x device 327*a99a9f0eSIvan Vecera * @index: DPLL channel index 328*a99a9f0eSIvan Vecera * 329*a99a9f0eSIvan Vecera * Return: DPLL type for given DPLL channel 330*a99a9f0eSIvan Vecera */ 331*a99a9f0eSIvan Vecera enum dpll_type 332*a99a9f0eSIvan Vecera zl3073x_prop_dpll_type_get(struct zl3073x_dev *zldev, u8 index) 333*a99a9f0eSIvan Vecera { 334*a99a9f0eSIvan Vecera const char *types[ZL3073X_MAX_CHANNELS]; 335*a99a9f0eSIvan Vecera int count; 336*a99a9f0eSIvan Vecera 337*a99a9f0eSIvan Vecera /* Read dpll types property from firmware */ 338*a99a9f0eSIvan Vecera count = device_property_read_string_array(zldev->dev, "dpll-types", 339*a99a9f0eSIvan Vecera types, ARRAY_SIZE(types)); 340*a99a9f0eSIvan Vecera 341*a99a9f0eSIvan Vecera /* Return default if property or entry for given channel is missing */ 342*a99a9f0eSIvan Vecera if (index >= count) 343*a99a9f0eSIvan Vecera return DPLL_TYPE_PPS; 344*a99a9f0eSIvan Vecera 345*a99a9f0eSIvan Vecera if (!strcmp(types[index], "pps")) 346*a99a9f0eSIvan Vecera return DPLL_TYPE_PPS; 347*a99a9f0eSIvan Vecera else if (!strcmp(types[index], "eec")) 348*a99a9f0eSIvan Vecera return DPLL_TYPE_EEC; 349*a99a9f0eSIvan Vecera 350*a99a9f0eSIvan Vecera dev_info(zldev->dev, "Unknown DPLL type '%s', using default\n", 351*a99a9f0eSIvan Vecera types[index]); 352*a99a9f0eSIvan Vecera 353*a99a9f0eSIvan Vecera return DPLL_TYPE_PPS; /* Default */ 354*a99a9f0eSIvan Vecera } 355