ad9523.c
1 /***************************************************************************//** 2 * @file AD9523.c 3 * @brief Implementation of AD9523 Driver. 4 * @author ACozma(andrei.cozma@analog.com) 5 ******************************************************************************** 6 * Copyright 2012-2016(c) Analog Devices, Inc. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright notice, 12 * this list of conditions and the following disclaimer. 13 * 14 * 2. Redistributions in binary form must reproduce the above copyright notice, 15 * this list of conditions and the following disclaimer in the documentation 16 * and/or other materials provided with the distribution. 17 * 18 * 3. Neither the name of Analog Devices, Inc. nor the names of its 19 * contributors may be used to endorse or promote products derived from this 20 * software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. “AS IS” AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 24 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 25 * EVENT SHALL ANALOG DEVICES, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 28 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 31 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 *******************************************************************************/ 34 35 #include <stdlib.h> 36 #include <stdio.h> 37 #include "ad9523.h" 38 #include "no_os_alloc.h" 39 40 /* Helpers to avoid excess line breaks */ 41 #define AD_IFE(_pde, _a, _b) ((dev->pdata->_pde) ? _a : _b) 42 #define AD_IF(_pde, _a) AD_IFE(_pde, _a, 0) 43 44 /***************************************************************************//** 45 * @brief Reads the value of the selected register. 46 * 47 * @param dev - The device structure. 48 * @param reg_addr - The address of the register to read. 49 * @param reg_data - Pointer to the read value. 50 51 * @return Returns 0 in case of success or negative error code. 52 *******************************************************************************/ 53 int32_t ad9523_spi_read(struct ad9523_dev *dev, 54 uint32_t reg_addr, 55 uint32_t *reg_data) 56 { 57 uint8_t buf[3]; 58 59 int32_t ret = 0; 60 uint8_t index; 61 62 *reg_data = 0; 63 for (index = 0; index < AD9523_TRANSF_LEN(reg_addr); index++) { 64 buf[0] = 0x80 | (reg_addr >> 8); 65 buf[1] = reg_addr & 0xFF; 66 buf[2] = 0x00; 67 ret |= no_os_spi_write_and_read(dev->spi_desc, 68 buf, 69 3); 70 reg_addr--; 71 *reg_data <<= 8; 72 *reg_data |= buf[2]; 73 } 74 75 return ret; 76 } 77 78 /***************************************************************************//** 79 * @brief Writes a value to the selected register. 80 * 81 * @param dev - The device structure. 82 * @param reg_addr - The address of the register to write to. 83 * @param reg_data - The value to write to the register. 84 * 85 * @return Returns 0 in case of success or negative error code. 86 *******************************************************************************/ 87 int32_t ad9523_spi_write(struct ad9523_dev *dev, 88 uint32_t reg_addr, 89 uint32_t reg_data) 90 { 91 uint8_t buf[3]; 92 93 int32_t ret = 0; 94 uint8_t index; 95 96 for (index = 0; index < AD9523_TRANSF_LEN(reg_addr); index++) { 97 buf[0] = reg_addr >> 8; 98 buf[1] = reg_addr & 0xFF; 99 buf[2] = (reg_data >> ((AD9523_TRANSF_LEN(reg_addr) - index - 1) * 8)) & 0xFF; 100 ret |= no_os_spi_write_and_read(dev->spi_desc, 101 buf, 102 3); 103 reg_addr--; 104 } 105 106 return ret; 107 } 108 109 /***************************************************************************//** 110 * @brief Updates the AD9523 configuration 111 * 112 * @param dev - The device structure. 113 * 114 * @return Returns 0 in case of success or negative error code. 115 *******************************************************************************/ 116 int32_t ad9523_io_update(struct ad9523_dev *dev) 117 { 118 return ad9523_spi_write(dev, 119 AD9523_IO_UPDATE, 120 AD9523_IO_UPDATE_EN); 121 } 122 123 /***************************************************************************//** 124 * @brief Sets the clock provider for selected channel. 125 * 126 * @param dev - The device structure. 127 * @param ch - Selected channel. 128 * @param out - Selected clock provider. 129 * 130 * @return Returns 0 in case of success or negative error code. 131 *******************************************************************************/ 132 int32_t ad9523_vco_out_map(struct ad9523_dev *dev, 133 uint32_t ch, 134 uint32_t out) 135 { 136 int32_t ret; 137 uint32_t mask; 138 uint32_t reg_data; 139 140 switch (ch) { 141 case 0 ... 3: 142 ret = ad9523_spi_read(dev, 143 AD9523_PLL1_OUTPUT_CHANNEL_CTRL, 144 ®_data); 145 if (ret < 0) 146 break; 147 mask = AD9523_PLL1_OUTP_CH_CTRL_VCXO_SRC_SEL_CH0 << ch; 148 if (out) { 149 reg_data |= mask; 150 out = AD9523_VCXO; 151 } else { 152 reg_data &= ~mask; 153 } 154 ret = ad9523_spi_write(dev, 155 AD9523_PLL1_OUTPUT_CHANNEL_CTRL, 156 reg_data); 157 break; 158 case 4 ... 6: 159 ret = ad9523_spi_read(dev, 160 AD9523_PLL1_OUTPUT_CTRL, 161 ®_data); 162 if (ret < 0) 163 break; 164 mask = AD9523_PLL1_OUTP_CTRL_VCO_DIV_SEL_CH4_M2 << (ch - 4); 165 if (out) 166 reg_data |= mask; 167 else 168 reg_data &= ~mask; 169 ret = ad9523_spi_write(dev, 170 AD9523_PLL1_OUTPUT_CTRL, 171 reg_data); 172 break; 173 case 7 ... 9: 174 ret = ad9523_spi_read(dev, 175 AD9523_PLL1_OUTPUT_CHANNEL_CTRL, 176 ®_data); 177 if (ret < 0) 178 break; 179 mask = AD9523_PLL1_OUTP_CH_CTRL_VCO_DIV_SEL_CH7_M2 << (ch - 7); 180 if (out) 181 reg_data |= mask; 182 else 183 reg_data &= ~mask; 184 ret = ad9523_spi_write(dev, 185 AD9523_PLL1_OUTPUT_CHANNEL_CTRL, 186 reg_data); 187 break; 188 default: 189 return 0; 190 } 191 192 dev->ad9523_st.vco_out_map[ch] = out; 193 194 return ret; 195 } 196 197 /***************************************************************************//** 198 * @brief Updates the AD9523 configuration. 199 * 200 * @return Returns 0 in case of success or negative error code. 201 *******************************************************************************/ 202 203 // vco calibration on default setup may not work (as it is a buffered write) 204 // calibration requires all registers to be written (not in hold registers) first. 205 206 int32_t ad9523_calibrate(struct ad9523_dev *dev) 207 { 208 uint32_t reg_data; 209 uint32_t timeout; 210 211 ad9523_spi_write(dev, 212 AD9523_PLL2_VCO_CTRL, 213 AD9523_PLL2_VCO_CALIBRATE); 214 ad9523_io_update(dev); 215 216 timeout = 0; 217 while (timeout < 100) { 218 no_os_mdelay(1); 219 timeout = timeout + 1; 220 ad9523_spi_read(dev, 221 AD9523_READBACK_1, 222 ®_data); 223 if ((reg_data & 0x1) == 0x0) 224 break; 225 } 226 ad9523_spi_read(dev, 227 AD9523_READBACK_1, 228 ®_data); 229 if ((reg_data & 0x1) != 0x0) { 230 printf("AD9523: VCO calibration failed (%#06lx)!\n", reg_data); 231 return (-1); 232 } 233 234 return (0); 235 } 236 237 /***************************************************************************//** 238 * @brief Updates the AD9523 configuration. 239 * 240 * @param dev - The device structure. 241 * 242 * @return Returns 0 in case of success or negative error code. 243 *******************************************************************************/ 244 245 // status 246 // calibration requires all registers to be written (not in hold registers) first. 247 248 int32_t ad9523_status(struct ad9523_dev *dev) 249 { 250 int32_t ret; 251 uint32_t reg_data; 252 uint32_t status; 253 uint32_t timeout; 254 255 status = 0; 256 257 // vcxo + pll2 must always be okay- (is it not?) 258 259 status = status | AD9523_READBACK_0_STAT_VCXO; 260 status = status | AD9523_READBACK_0_STAT_PLL2_LD; 261 262 if (dev->pdata->pll1_bypass_en == 0) { 263 status = status | AD9523_READBACK_0_STAT_PLL2_REF_CLK; 264 status = status | AD9523_READBACK_0_STAT_PLL2_FB_CLK; 265 status = status | AD9523_READBACK_0_STAT_REF_TEST; 266 status = status | AD9523_READBACK_0_STAT_REFB; 267 status = status | AD9523_READBACK_0_STAT_REFA; 268 status = status | AD9523_READBACK_0_STAT_PLL1_LD; 269 } 270 271 timeout = 0; 272 while (timeout < 100) { 273 no_os_mdelay(1); 274 timeout = timeout + 1; 275 ad9523_spi_read(dev, 276 AD9523_READBACK_0, 277 ®_data); 278 if ((reg_data & status) == status) 279 break; 280 } 281 282 ret = 0; 283 if ((reg_data & AD9523_READBACK_0_STAT_VCXO) != AD9523_READBACK_0_STAT_VCXO) { 284 printf("AD9523: VCXO status errors (%#06lx)!\n", reg_data); 285 ret = -1; 286 } 287 288 if ((reg_data & AD9523_READBACK_0_STAT_PLL2_LD) != 289 AD9523_READBACK_0_STAT_PLL2_LD) { 290 printf("AD9523: PLL2 NOT locked (%#06lx)!\n", reg_data); 291 ret = -1; 292 } 293 294 return (ret); 295 } 296 297 /***************************************************************************//** 298 * @brief Updates the AD9523 configuration. 299 * 300 * @param dev - The device structure. 301 * 302 * @return Returns 0 in case of success or negative error code. 303 *******************************************************************************/ 304 int32_t ad9523_sync(struct ad9523_dev *dev) 305 { 306 int32_t ret, tmp; 307 uint32_t reg_data; 308 309 ret = ad9523_spi_read(dev, 310 AD9523_STATUS_SIGNALS, 311 ®_data); 312 if (ret < 0) 313 return ret; 314 315 tmp = reg_data; 316 tmp |= AD9523_STATUS_SIGNALS_SYNC_MAN_CTRL; 317 318 ret = ad9523_spi_write(dev, 319 AD9523_STATUS_SIGNALS, 320 tmp); 321 if (ret < 0) 322 return ret; 323 324 ad9523_io_update(dev); 325 tmp &= ~AD9523_STATUS_SIGNALS_SYNC_MAN_CTRL; 326 327 ret = ad9523_spi_write(dev, 328 AD9523_STATUS_SIGNALS, 329 tmp); 330 if (ret < 0) 331 return ret; 332 333 return ad9523_io_update(dev); 334 335 } 336 337 /***************************************************************************//** 338 * @brief Initialize the AD9523 data structure with the default register values. 339 * 340 * @param init_param - The device initial parameters. 341 * 342 * @return Always return 0. 343 *******************************************************************************/ 344 int32_t ad9523_init(struct ad9523_init_param *init_param) 345 { 346 347 int32_t i = 0; 348 349 init_param->pdata->vcxo_freq = 0; 350 init_param->pdata->spi3wire = 0; 351 352 /* Differential/ Single-Ended Input Configuration */ 353 init_param->pdata->refa_diff_rcv_en = 0; 354 init_param->pdata->refb_diff_rcv_en = 0; 355 init_param->pdata->zd_in_diff_en = 0; 356 init_param->pdata->osc_in_diff_en = 0; 357 358 /* 359 * Valid if differential input disabled 360 * if not true defaults to pos input 361 */ 362 init_param->pdata->refa_cmos_neg_inp_en = 0; 363 init_param->pdata->refb_cmos_neg_inp_en = 0; 364 init_param->pdata->zd_in_cmos_neg_inp_en = 0; 365 init_param->pdata->osc_in_cmos_neg_inp_en = 0; 366 367 /* PLL1 Setting */ 368 init_param->pdata->refa_r_div = 1; 369 init_param->pdata->refb_r_div = 1; 370 init_param->pdata->pll1_feedback_div = 1; 371 init_param->pdata->pll1_charge_pump_current_nA = 0; 372 init_param->pdata->zero_delay_mode_internal_en = 0; 373 init_param->pdata->osc_in_feedback_en = 0; 374 init_param->pdata->pll1_bypass_en = 1; 375 init_param->pdata->pll1_loop_filter_rzero = 1; 376 377 /* Reference */ 378 init_param->pdata->ref_mode = 0; 379 380 /* PLL2 Setting */ 381 init_param->pdata->pll2_charge_pump_current_nA = 0; 382 init_param->pdata->pll2_ndiv_a_cnt = 0; 383 init_param->pdata->pll2_ndiv_b_cnt = 4; 384 init_param->pdata->pll2_freq_doubler_en = 0; 385 init_param->pdata->pll2_r2_div = 0; 386 init_param->pdata->pll2_vco_diff_m1 = 0; /* 3..5 */ 387 init_param->pdata->pll2_vco_diff_m2 = 0; /* 3..5 */ 388 389 /* Loop Filter PLL2 */ 390 init_param->pdata->rpole2 = 0; 391 init_param->pdata->rzero = 0; 392 init_param->pdata->cpole1 = 0; 393 init_param->pdata->rzero_bypass_en = 0; 394 395 /* Output Channel Configuration */ 396 for (i = 0; i < init_param->pdata->num_channels; i++) { 397 (&init_param->pdata->channels[i])->channel_num = 0; 398 (&init_param->pdata->channels[i])->divider_output_invert_en = 0; 399 (&init_param->pdata->channels[i])->sync_ignore_en = 0; 400 (&init_param->pdata->channels[i])->low_power_mode_en = 0; 401 (&init_param->pdata->channels[i])->use_alt_clock_src = 0; 402 (&init_param->pdata->channels[i])->output_dis = 0; 403 (&init_param->pdata->channels[i])->driver_mode = LVPECL_8mA; 404 (&init_param->pdata->channels[i])->divider_phase = 0; 405 (&init_param->pdata->channels[i])->channel_divider = 0; 406 } 407 return 0; 408 } 409 410 411 /***************************************************************************//** 412 * @brief Setup the AD9523 device. 413 * 414 * @param device - The device structure. 415 * @param init_param - The structure holding the device initial parameters. 416 * 417 * @return Returns 0 in case of success or negative error code. 418 *******************************************************************************/ 419 int32_t ad9523_setup(struct ad9523_dev **device, 420 const struct ad9523_init_param *init_param) 421 422 { 423 struct ad9523_channel_spec *chan; 424 uint32_t active_mask = 0; 425 int32_t ret, i; 426 uint32_t reg_data; 427 uint32_t version_id; 428 struct ad9523_dev *dev; 429 430 dev = (struct ad9523_dev *)no_os_malloc(sizeof(*dev)); 431 if (!dev) 432 return -1; 433 434 /* SPI */ 435 ret = no_os_spi_init(&dev->spi_desc, &init_param->spi_init); 436 if (ret < 0) 437 return ret; 438 439 dev->pdata = init_param->pdata; 440 441 ret = ad9523_spi_write(dev, 442 AD9523_SERIAL_PORT_CONFIG, 443 AD9523_SER_CONF_SOFT_RESET | 444 (dev->pdata->spi3wire ? 0 : 445 AD9523_SER_CONF_SDO_ACTIVE)); 446 if (ret < 0) 447 return ret; 448 no_os_mdelay(1); 449 450 ret = ad9523_spi_write(dev, 451 AD9523_READBACK_CTRL, 452 AD9523_READBACK_CTRL_READ_BUFFERED); 453 if (ret < 0) 454 return ret; 455 456 ret = ad9523_io_update(dev); 457 if (ret < 0) 458 return ret; 459 460 ret = ad9523_spi_read(dev, 461 AD9523_EEPROM_CUSTOMER_VERSION_ID, 462 &version_id); 463 if (ret < 0) 464 return ret; 465 466 ret = ad9523_spi_write(dev, 467 AD9523_EEPROM_CUSTOMER_VERSION_ID, 468 0xAD95); 469 if (ret < 0) 470 return ret; 471 472 ret = ad9523_spi_read(dev, 473 AD9523_EEPROM_CUSTOMER_VERSION_ID, 474 ®_data); 475 if (ret < 0) 476 return ret; 477 478 if (reg_data != 0xAD95) { 479 printf("AD9523: SPI write-verify failed (%#06lX)!\n\r", 480 reg_data); 481 return -1; 482 } 483 484 ret = ad9523_spi_write(dev, 485 AD9523_EEPROM_CUSTOMER_VERSION_ID, 486 version_id); 487 if (ret < 0) 488 return ret; 489 490 /* 491 * PLL1 Setup 492 */ 493 ret = ad9523_spi_write(dev, 494 AD9523_PLL1_REF_A_DIVIDER, 495 dev->pdata->refa_r_div); 496 if (ret < 0) 497 return ret; 498 499 ret = ad9523_spi_write(dev, 500 AD9523_PLL1_REF_B_DIVIDER, 501 dev->pdata->refb_r_div); 502 if (ret < 0) 503 return ret; 504 505 ret = ad9523_spi_write(dev, 506 AD9523_PLL1_FEEDBACK_DIVIDER, 507 dev->pdata->pll1_feedback_div); 508 if (ret < 0) 509 return ret; 510 511 ret = ad9523_spi_write(dev, 512 AD9523_PLL1_CHARGE_PUMP_CTRL, 513 AD_IFE(pll1_bypass_en, AD9523_PLL1_CHARGE_PUMP_TRISTATE, 514 AD9523_PLL1_CHARGE_PUMP_CURRENT_nA(dev->pdata-> 515 pll1_charge_pump_current_nA) | 516 AD9523_PLL1_CHARGE_PUMP_MODE_NORMAL | 517 AD9523_PLL1_BACKLASH_PW_MIN)); 518 if (ret < 0) 519 return ret; 520 521 ret = ad9523_spi_write(dev, 522 AD9523_PLL1_INPUT_RECEIVERS_CTRL, 523 AD_IFE(pll1_bypass_en, AD9523_PLL1_REFA_REFB_PWR_CTRL_EN | 524 AD_IF(osc_in_diff_en, AD9523_PLL1_OSC_IN_DIFF_EN) | 525 AD_IF(osc_in_cmos_neg_inp_en, AD9523_PLL1_OSC_IN_CMOS_NEG_INP_EN), 526 AD_IF(refa_diff_rcv_en, AD9523_PLL1_REFA_RCV_EN) | 527 AD_IF(refb_diff_rcv_en, AD9523_PLL1_REFB_RCV_EN) | 528 AD_IF(osc_in_diff_en, AD9523_PLL1_OSC_IN_DIFF_EN) | 529 AD_IF(osc_in_cmos_neg_inp_en, 530 AD9523_PLL1_OSC_IN_CMOS_NEG_INP_EN) | 531 AD_IF(refa_diff_rcv_en, AD9523_PLL1_REFA_DIFF_RCV_EN) | 532 AD_IF(refb_diff_rcv_en, AD9523_PLL1_REFB_DIFF_RCV_EN))); 533 if (ret < 0) 534 return ret; 535 536 ret = ad9523_spi_write(dev, 537 AD9523_PLL1_REF_CTRL, 538 AD_IFE(pll1_bypass_en, AD9523_PLL1_BYPASS_FEEDBACK_DIV_EN | 539 AD9523_PLL1_ZERO_DELAY_MODE_INT, 540 AD_IF(zd_in_diff_en, AD9523_PLL1_ZD_IN_DIFF_EN) | 541 AD_IF(zd_in_cmos_neg_inp_en, 542 AD9523_PLL1_ZD_IN_CMOS_NEG_INP_EN) | 543 AD_IF(zero_delay_mode_internal_en, 544 AD9523_PLL1_ZERO_DELAY_MODE_INT) | 545 AD_IF(osc_in_feedback_en, AD9523_PLL1_OSC_IN_PLL_FEEDBACK_EN) | 546 AD_IF(refa_cmos_neg_inp_en, AD9523_PLL1_REFA_CMOS_NEG_INP_EN) | 547 AD_IF(refb_cmos_neg_inp_en, AD9523_PLL1_REFB_CMOS_NEG_INP_EN))); 548 if (ret < 0) 549 return ret; 550 551 ret = ad9523_spi_write(dev, 552 AD9523_PLL1_MISC_CTRL, 553 AD9523_PLL1_REFB_INDEP_DIV_CTRL_EN | 554 AD9523_PLL1_REF_MODE(dev->pdata->ref_mode)); 555 if (ret < 0) 556 return ret; 557 558 ret = ad9523_spi_write(dev, 559 AD9523_PLL1_LOOP_FILTER_CTRL, 560 AD9523_PLL1_LOOP_FILTER_RZERO(dev->pdata-> 561 pll1_loop_filter_rzero)); 562 if (ret < 0) 563 return ret; 564 565 /* 566 * PLL2 Setup 567 */ 568 569 ret = ad9523_spi_write(dev, 570 AD9523_PLL2_CHARGE_PUMP, 571 AD9523_PLL2_CHARGE_PUMP_CURRENT_nA(dev->pdata-> 572 pll2_charge_pump_current_nA)); 573 if (ret < 0) 574 return ret; 575 576 ret = ad9523_spi_write(dev, 577 AD9523_PLL2_FEEDBACK_DIVIDER_AB, 578 AD9523_PLL2_FB_NDIV_A_CNT(dev->pdata->pll2_ndiv_a_cnt) | 579 AD9523_PLL2_FB_NDIV_B_CNT(dev->pdata->pll2_ndiv_b_cnt)); 580 if (ret < 0) 581 return ret; 582 583 ret = ad9523_spi_write(dev, 584 AD9523_PLL2_CTRL, 585 AD9523_PLL2_CHARGE_PUMP_MODE_NORMAL | 586 AD9523_PLL2_BACKLASH_CTRL_EN | 587 AD_IF(pll2_freq_doubler_en, 588 AD9523_PLL2_FREQ_DOUBLER_EN)); 589 if (ret < 0) 590 return ret; 591 592 dev->ad9523_st.vco_freq = (dev->pdata->vcxo_freq * 593 (dev->pdata->pll2_freq_doubler_en ? 2 : 1) 594 / dev->pdata->pll2_r2_div) * AD9523_PLL2_FB_NDIV(dev->pdata-> 595 pll2_ndiv_a_cnt, 596 dev->pdata-> 597 pll2_ndiv_b_cnt); 598 599 ret = ad9523_spi_write(dev, 600 AD9523_PLL2_VCO_CTRL, 601 AD9523_PLL2_VCO_CALIBRATE); 602 if (ret < 0) 603 return ret; 604 605 ret = ad9523_spi_write(dev, 606 AD9523_PLL2_VCO_DIVIDER, 607 AD9523_PLL2_VCO_DIV_M1(dev->pdata-> 608 pll2_vco_diff_m1) | 609 AD9523_PLL2_VCO_DIV_M2(dev->pdata-> 610 pll2_vco_diff_m2) | 611 AD_IFE(pll2_vco_diff_m1, 612 0, 613 AD9523_PLL2_VCO_DIV_M1_PWR_DOWN_EN) | 614 AD_IFE(pll2_vco_diff_m2, 615 0, 616 AD9523_PLL2_VCO_DIV_M2_PWR_DOWN_EN)); 617 if (ret < 0) 618 return ret; 619 620 if (dev->pdata->pll2_vco_diff_m1) 621 dev->ad9523_st.vco_out_freq[AD9523_VCO1] = 622 dev->ad9523_st.vco_freq / dev->pdata->pll2_vco_diff_m1; 623 624 if (dev->pdata->pll2_vco_diff_m2) 625 dev->ad9523_st.vco_out_freq[AD9523_VCO2] = 626 dev->ad9523_st.vco_freq / dev->pdata->pll2_vco_diff_m2; 627 628 dev->ad9523_st.vco_out_freq[AD9523_VCXO] = dev->pdata->vcxo_freq; 629 630 ret = ad9523_spi_write(dev, 631 AD9523_PLL2_R2_DIVIDER, 632 AD9523_PLL2_R2_DIVIDER_VAL(dev->pdata->pll2_r2_div)); 633 if (ret < 0) 634 return ret; 635 636 ret = ad9523_spi_write(dev, 637 AD9523_PLL2_LOOP_FILTER_CTRL, 638 AD9523_PLL2_LOOP_FILTER_CPOLE1(dev->pdata->cpole1) | 639 AD9523_PLL2_LOOP_FILTER_RZERO(dev->pdata->rzero) | 640 AD9523_PLL2_LOOP_FILTER_RPOLE2(dev->pdata->rpole2) | 641 AD_IF(rzero_bypass_en, 642 AD9523_PLL2_LOOP_FILTER_RZERO_BYPASS_EN)); 643 if (ret < 0) 644 return ret; 645 646 for (i = 0; i < dev->pdata->num_channels; i++) { 647 chan = &dev->pdata->channels[i]; 648 if (chan->channel_num < AD9523_NUM_CHAN) { 649 active_mask |= (1 << chan->channel_num); 650 ret = ad9523_spi_write(dev, 651 AD9523_CHANNEL_CLOCK_DIST(chan->channel_num), 652 AD9523_CLK_DIST_DRIVER_MODE(chan->driver_mode) | 653 AD9523_CLK_DIST_DIV(chan->channel_divider) | 654 AD9523_CLK_DIST_DIV_PHASE(chan->divider_phase) | 655 (chan->sync_ignore_en ? 656 AD9523_CLK_DIST_IGNORE_SYNC_EN : 0) | 657 (chan->divider_output_invert_en ? 658 AD9523_CLK_DIST_INV_DIV_OUTPUT_EN : 0) | 659 (chan->low_power_mode_en ? 660 AD9523_CLK_DIST_LOW_PWR_MODE_EN : 0) | 661 (chan->output_dis ? 662 AD9523_CLK_DIST_PWR_DOWN_EN : 0)); 663 if (ret < 0) 664 return ret; 665 666 ret = ad9523_vco_out_map(dev, 667 chan->channel_num, 668 chan->use_alt_clock_src); 669 if (ret < 0) 670 return ret; 671 } 672 } 673 674 for (i = 0; i < AD9523_NUM_CHAN; i++) { 675 if (!(active_mask & (1 << i))) { 676 ad9523_spi_write(dev, 677 AD9523_CHANNEL_CLOCK_DIST(i), 678 AD9523_CLK_DIST_DRIVER_MODE(TRISTATE) | 679 AD9523_CLK_DIST_PWR_DOWN_EN); 680 } 681 } 682 683 ret = ad9523_spi_write(dev, 684 AD9523_POWER_DOWN_CTRL, 685 0); 686 if (ret < 0) 687 return ret; 688 689 ret = ad9523_spi_write(dev, 690 AD9523_STATUS_SIGNALS, 691 AD9523_STATUS_MONITOR_01_PLL12_LOCKED); 692 if (ret < 0) 693 return ret; 694 695 ret = ad9523_io_update(dev); 696 if (ret < 0) 697 return ret; 698 699 ret = ad9523_sync(dev); 700 if (ret < 0) 701 return ret; 702 703 ad9523_spi_write(dev, 704 AD9523_READBACK_CTRL, 705 0x0); 706 ad9523_io_update(dev); 707 ad9523_calibrate(dev); 708 ad9523_sync(dev); 709 710 *device = dev; 711 712 return (ad9523_status(dev)); 713 } 714 715 /***************************************************************************//** 716 * @brief Free the resources allocated by ad9523_setup(). 717 * 718 * @param dev - The device structure. 719 * 720 * @return 0 in case of success, negative error code otherwise. 721 *******************************************************************************/ 722 int32_t ad9523_remove(struct ad9523_dev *dev) 723 { 724 int32_t ret; 725 726 ret = no_os_spi_remove(dev->spi_desc); 727 728 no_os_free(dev); 729 730 return ret; 731 }