clk_synthesizer.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * clk-synthesizer.c
  4. *
  5. * Clock synthesizer apis
  6. *
  7. * Copyright (C) 2016, Texas Instruments, Incorporated - http://www.ti.com/
  8. */
  9. #include <common.h>
  10. #include <asm/arch/clk_synthesizer.h>
  11. #include <i2c.h>
  12. /**
  13. * clk_synthesizer_reg_read - Read register from synthesizer.
  14. * dev: i2c bus device (not used if CONFIG_DM_I2C is not set)
  15. * @addr: addr within the i2c device
  16. * buf: Buffer to which value is to be read.
  17. *
  18. * For reading the register from this clock synthesizer, a command needs to
  19. * be send along with enabling byte read more, and then read can happen.
  20. * Returns 0 on success
  21. */
  22. static int clk_synthesizer_reg_read(struct udevice *dev, int addr, u8 *buf)
  23. {
  24. int rc;
  25. /* Enable Bye read */
  26. addr = addr | CLK_SYNTHESIZER_BYTE_MODE;
  27. #ifndef CONFIG_DM_I2C
  28. /* Send the command byte */
  29. rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
  30. if (rc)
  31. printf("Failed to send command to clock synthesizer\n");
  32. /* Read the Data */
  33. return i2c_read(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
  34. #else
  35. /* Send the command byte */
  36. rc = dm_i2c_reg_write(dev, addr, *buf);
  37. if (rc)
  38. printf("Failed to send command to clock synthesizer\n");
  39. /* Read the Data */
  40. rc = dm_i2c_reg_read(dev, addr);
  41. if (rc < 0)
  42. return rc;
  43. *buf = (u8)rc;
  44. return 0;
  45. #endif
  46. }
  47. /**
  48. * clk_synthesizer_reg_write - Write a value to register in synthesizer.
  49. * dev: i2c bus device (not used if CONFIG_DM_I2C is not set)
  50. * @addr: addr within the i2c device
  51. * val: Value to be written in the addr.
  52. *
  53. * Enable the byte read mode in the address and start the i2c transfer.
  54. * Returns 0 on success
  55. */
  56. static int clk_synthesizer_reg_write(struct udevice *dev, int addr, u8 val)
  57. {
  58. u8 cmd[2];
  59. int rc = 0;
  60. /* Enable byte write */
  61. cmd[0] = addr | CLK_SYNTHESIZER_BYTE_MODE;
  62. cmd[1] = val;
  63. #ifndef CONFIG_DM_I2C
  64. rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, cmd, 2);
  65. #else
  66. rc = dm_i2c_write(dev, addr, cmd, 2);
  67. #endif
  68. if (rc)
  69. printf("Clock synthesizer reg write failed at addr = 0x%x\n",
  70. addr);
  71. return rc;
  72. }
  73. /**
  74. * setup_clock_syntherizer - Program the clock synthesizer to get the desired
  75. * frequency.
  76. * @data: Data containing the desired output
  77. *
  78. * This is a PLL-based high performance synthesizer which gives 3 outputs
  79. * as per the PLL_DIV and load capacitor programmed.
  80. */
  81. int setup_clock_synthesizer(struct clk_synth *data)
  82. {
  83. int rc;
  84. u8 val = 0;
  85. struct udevice *dev = NULL;
  86. #ifndef CONFIG_DM_I2C
  87. rc = i2c_probe(CLK_SYNTHESIZER_I2C_ADDR);
  88. if (rc) {
  89. printf("i2c probe failed at address 0x%x\n",
  90. CLK_SYNTHESIZER_I2C_ADDR);
  91. return rc;
  92. }
  93. #else
  94. rc = i2c_get_chip_for_busnum(0, CLK_SYNTHESIZER_I2C_ADDR, 1, &dev);
  95. if (rc) {
  96. printf("failed to get device for synthesizer at address 0x%x\n",
  97. CLK_SYNTHESIZER_I2C_ADDR);
  98. return rc;
  99. }
  100. #endif
  101. rc = clk_synthesizer_reg_read(dev, CLK_SYNTHESIZER_ID_REG, &val);
  102. if (val != data->id)
  103. return rc;
  104. /* Crystal Load capacitor selection */
  105. rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_XCSEL,
  106. data->capacitor);
  107. if (rc)
  108. return rc;
  109. rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_MUX_REG,
  110. data->mux);
  111. if (rc)
  112. return rc;
  113. rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_PDIV2_REG,
  114. data->pdiv2);
  115. if (rc)
  116. return rc;
  117. rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_PDIV3_REG,
  118. data->pdiv3);
  119. if (rc)
  120. return rc;
  121. return 0;
  122. }