123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- // SPDX-License-Identifier: GPL-2.0+
- /*
- * clk-synthesizer.c
- *
- * Clock synthesizer apis
- *
- * Copyright (C) 2016, Texas Instruments, Incorporated - http://www.ti.com/
- */
- #include <common.h>
- #include <asm/arch/clk_synthesizer.h>
- #include <i2c.h>
- /**
- * clk_synthesizer_reg_read - Read register from synthesizer.
- * dev: i2c bus device (not used if CONFIG_DM_I2C is not set)
- * @addr: addr within the i2c device
- * buf: Buffer to which value is to be read.
- *
- * For reading the register from this clock synthesizer, a command needs to
- * be send along with enabling byte read more, and then read can happen.
- * Returns 0 on success
- */
- static int clk_synthesizer_reg_read(struct udevice *dev, int addr, u8 *buf)
- {
- int rc;
- /* Enable Bye read */
- addr = addr | CLK_SYNTHESIZER_BYTE_MODE;
- #ifndef CONFIG_DM_I2C
- /* Send the command byte */
- rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
- if (rc)
- printf("Failed to send command to clock synthesizer\n");
- /* Read the Data */
- return i2c_read(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
- #else
- /* Send the command byte */
- rc = dm_i2c_reg_write(dev, addr, *buf);
- if (rc)
- printf("Failed to send command to clock synthesizer\n");
- /* Read the Data */
- rc = dm_i2c_reg_read(dev, addr);
- if (rc < 0)
- return rc;
- *buf = (u8)rc;
- return 0;
- #endif
- }
- /**
- * clk_synthesizer_reg_write - Write a value to register in synthesizer.
- * dev: i2c bus device (not used if CONFIG_DM_I2C is not set)
- * @addr: addr within the i2c device
- * val: Value to be written in the addr.
- *
- * Enable the byte read mode in the address and start the i2c transfer.
- * Returns 0 on success
- */
- static int clk_synthesizer_reg_write(struct udevice *dev, int addr, u8 val)
- {
- u8 cmd[2];
- int rc = 0;
- /* Enable byte write */
- cmd[0] = addr | CLK_SYNTHESIZER_BYTE_MODE;
- cmd[1] = val;
- #ifndef CONFIG_DM_I2C
- rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, cmd, 2);
- #else
- rc = dm_i2c_write(dev, addr, cmd, 2);
- #endif
- if (rc)
- printf("Clock synthesizer reg write failed at addr = 0x%x\n",
- addr);
- return rc;
- }
- /**
- * setup_clock_syntherizer - Program the clock synthesizer to get the desired
- * frequency.
- * @data: Data containing the desired output
- *
- * This is a PLL-based high performance synthesizer which gives 3 outputs
- * as per the PLL_DIV and load capacitor programmed.
- */
- int setup_clock_synthesizer(struct clk_synth *data)
- {
- int rc;
- u8 val = 0;
- struct udevice *dev = NULL;
- #ifndef CONFIG_DM_I2C
- rc = i2c_probe(CLK_SYNTHESIZER_I2C_ADDR);
- if (rc) {
- printf("i2c probe failed at address 0x%x\n",
- CLK_SYNTHESIZER_I2C_ADDR);
- return rc;
- }
- #else
- rc = i2c_get_chip_for_busnum(0, CLK_SYNTHESIZER_I2C_ADDR, 1, &dev);
- if (rc) {
- printf("failed to get device for synthesizer at address 0x%x\n",
- CLK_SYNTHESIZER_I2C_ADDR);
- return rc;
- }
- #endif
- rc = clk_synthesizer_reg_read(dev, CLK_SYNTHESIZER_ID_REG, &val);
- if (val != data->id)
- return rc;
- /* Crystal Load capacitor selection */
- rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_XCSEL,
- data->capacitor);
- if (rc)
- return rc;
- rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_MUX_REG,
- data->mux);
- if (rc)
- return rc;
- rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_PDIV2_REG,
- data->pdiv2);
- if (rc)
- return rc;
- rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_PDIV3_REG,
- data->pdiv3);
- if (rc)
- return rc;
- return 0;
- }
|