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