clk_synthesizer.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. /*
  2. * clk-synthesizer.c
  3. *
  4. * Clock synthesizer apis
  5. *
  6. * Copyright (C) 2016, Texas Instruments, Incorporated - http://www.ti.com/
  7. *
  8. * SPDX-License-Identifier: GPL-2.0+
  9. */
  10. #include <common.h>
  11. #include <asm/arch/clk_synthesizer.h>
  12. #include <i2c.h>
  13. /**
  14. * clk_synthesizer_reg_read - Read register from synthesizer.
  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(int addr, uint8_t *buf)
  23. {
  24. int rc;
  25. /* Enable Bye read */
  26. addr = addr | CLK_SYNTHESIZER_BYTE_MODE;
  27. /* Send the command byte */
  28. rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
  29. if (rc)
  30. printf("Failed to send command to clock synthesizer\n");
  31. /* Read the Data */
  32. return i2c_read(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
  33. }
  34. /**
  35. * clk_synthesizer_reg_write - Write a value to register in synthesizer.
  36. * @addr: addr within the i2c device
  37. * val: Value to be written in the addr.
  38. *
  39. * Enable the byte read mode in the address and start the i2c transfer.
  40. * Returns 0 on success
  41. */
  42. static int clk_synthesizer_reg_write(int addr, uint8_t val)
  43. {
  44. uint8_t cmd[2];
  45. int rc = 0;
  46. /* Enable byte write */
  47. cmd[0] = addr | CLK_SYNTHESIZER_BYTE_MODE;
  48. cmd[1] = val;
  49. rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, cmd, 2);
  50. if (rc)
  51. printf("Clock synthesizer reg write failed at addr = 0x%x\n",
  52. addr);
  53. return rc;
  54. }
  55. /**
  56. * setup_clock_syntherizer - Program the clock synthesizer to get the desired
  57. * frequency.
  58. * @data: Data containing the desired output
  59. *
  60. * This is a PLL-based high performance synthesizer which gives 3 outputs
  61. * as per the PLL_DIV and load capacitor programmed.
  62. */
  63. int setup_clock_synthesizer(struct clk_synth *data)
  64. {
  65. int rc;
  66. uint8_t val;
  67. rc = i2c_probe(CLK_SYNTHESIZER_I2C_ADDR);
  68. if (rc) {
  69. printf("i2c probe failed at address 0x%x\n",
  70. CLK_SYNTHESIZER_I2C_ADDR);
  71. return rc;
  72. }
  73. rc = clk_synthesizer_reg_read(CLK_SYNTHESIZER_ID_REG, &val);
  74. if (val != data->id)
  75. return rc;
  76. /* Crystal Load capacitor selection */
  77. rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_XCSEL, data->capacitor);
  78. if (rc)
  79. return rc;
  80. rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_MUX_REG, data->mux);
  81. if (rc)
  82. return rc;
  83. rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV2_REG, data->pdiv2);
  84. if (rc)
  85. return rc;
  86. rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV3_REG, data->pdiv3);
  87. if (rc)
  88. return rc;
  89. return 0;
  90. }