clk_synthesizer.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  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. * @addr: addr within the i2c device
  15. * buf: Buffer to which value is to be read.
  16. *
  17. * For reading the register from this clock synthesizer, a command needs to
  18. * be send along with enabling byte read more, and then read can happen.
  19. * Returns 0 on success
  20. */
  21. static int clk_synthesizer_reg_read(int addr, uint8_t *buf)
  22. {
  23. int rc;
  24. /* Enable Bye read */
  25. addr = addr | CLK_SYNTHESIZER_BYTE_MODE;
  26. /* Send the command byte */
  27. rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
  28. if (rc)
  29. printf("Failed to send command to clock synthesizer\n");
  30. /* Read the Data */
  31. return i2c_read(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
  32. }
  33. /**
  34. * clk_synthesizer_reg_write - Write a value to register in synthesizer.
  35. * @addr: addr within the i2c device
  36. * val: Value to be written in the addr.
  37. *
  38. * Enable the byte read mode in the address and start the i2c transfer.
  39. * Returns 0 on success
  40. */
  41. static int clk_synthesizer_reg_write(int addr, uint8_t val)
  42. {
  43. uint8_t cmd[2];
  44. int rc = 0;
  45. /* Enable byte write */
  46. cmd[0] = addr | CLK_SYNTHESIZER_BYTE_MODE;
  47. cmd[1] = val;
  48. rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, cmd, 2);
  49. if (rc)
  50. printf("Clock synthesizer reg write failed at addr = 0x%x\n",
  51. addr);
  52. return rc;
  53. }
  54. /**
  55. * setup_clock_syntherizer - Program the clock synthesizer to get the desired
  56. * frequency.
  57. * @data: Data containing the desired output
  58. *
  59. * This is a PLL-based high performance synthesizer which gives 3 outputs
  60. * as per the PLL_DIV and load capacitor programmed.
  61. */
  62. int setup_clock_synthesizer(struct clk_synth *data)
  63. {
  64. int rc;
  65. uint8_t val;
  66. rc = i2c_probe(CLK_SYNTHESIZER_I2C_ADDR);
  67. if (rc) {
  68. printf("i2c probe failed at address 0x%x\n",
  69. CLK_SYNTHESIZER_I2C_ADDR);
  70. return rc;
  71. }
  72. rc = clk_synthesizer_reg_read(CLK_SYNTHESIZER_ID_REG, &val);
  73. if (val != data->id)
  74. return rc;
  75. /* Crystal Load capacitor selection */
  76. rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_XCSEL, data->capacitor);
  77. if (rc)
  78. return rc;
  79. rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_MUX_REG, data->mux);
  80. if (rc)
  81. return rc;
  82. rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV2_REG, data->pdiv2);
  83. if (rc)
  84. return rc;
  85. rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV3_REG, data->pdiv3);
  86. if (rc)
  87. return rc;
  88. return 0;
  89. }