hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
 * clk-synthesizer.c
 *
 * Clock synthesizer apis
 *
 * Copyright (C) 2016, Texas Instruments, Incorporated - http://www.ti.com/
 *
 * SPDX-License-Identifier:    GPL-2.0+
 */
 
 
#include <common.h>
#include <asm/arch/clk_synthesizer.h>
#include <i2c.h>
 
/**
 * clk_synthesizer_reg_read - Read register from synthesizer.
 * @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(int addr, uint8_t *buf)
{
   int rc;
 
   /* Enable Bye read */
   addr = addr | CLK_SYNTHESIZER_BYTE_MODE;
 
   /* 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);
}
 
/**
 * clk_synthesizer_reg_write - Write a value to register in synthesizer.
 * @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(int addr, uint8_t val)
{
   uint8_t cmd[2];
   int rc = 0;
 
   /* Enable byte write */
   cmd[0] = addr | CLK_SYNTHESIZER_BYTE_MODE;
   cmd[1] = val;
 
   rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, cmd, 2);
   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;
   uint8_t val;
 
   rc =  i2c_probe(CLK_SYNTHESIZER_I2C_ADDR);
   if (rc) {
       printf("i2c probe failed at address 0x%x\n",
              CLK_SYNTHESIZER_I2C_ADDR);
       return rc;
   }
 
   rc = clk_synthesizer_reg_read(CLK_SYNTHESIZER_ID_REG, &val);
   if (val != data->id)
       return rc;
 
   /* Crystal Load capacitor selection */
   rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_XCSEL, data->capacitor);
   if (rc)
       return rc;
   rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_MUX_REG, data->mux);
   if (rc)
       return rc;
   rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV2_REG, data->pdiv2);
   if (rc)
       return rc;
   rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV3_REG, data->pdiv3);
   if (rc)
       return rc;
 
   return 0;
}