uboot/arch/arm/mach-omap2/am33xx/clk_synthesizer.c
<<
>>
Prefs
   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 * dev:         i2c bus device (not used if CONFIG_DM_I2C is not set)
  18 * @addr:       addr within the i2c device
  19 * buf:         Buffer to which value is to be read.
  20 *
  21 * For reading the register from this clock synthesizer, a command needs to
  22 * be send along with enabling byte read more, and then read can happen.
  23 * Returns 0 on success
  24 */
  25static int clk_synthesizer_reg_read(struct udevice *dev, int addr, u8 *buf)
  26{
  27        int rc;
  28
  29        /* Enable Bye read */
  30        addr = addr | CLK_SYNTHESIZER_BYTE_MODE;
  31
  32#if !CONFIG_IS_ENABLED(DM_I2C)
  33        /* Send the command byte */
  34        rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
  35        if (rc)
  36                printf("Failed to send command to clock synthesizer\n");
  37
  38        /* Read the Data */
  39        return i2c_read(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
  40#else
  41        /* Send the command byte */
  42        rc = dm_i2c_reg_write(dev, addr, *buf);
  43        if (rc)
  44                printf("Failed to send command to clock synthesizer\n");
  45
  46        /* Read the Data */
  47        rc = dm_i2c_reg_read(dev, addr);
  48        if (rc < 0)
  49                return rc;
  50
  51        *buf = (u8)rc;
  52        return 0;
  53#endif
  54
  55}
  56
  57/**
  58 * clk_synthesizer_reg_write - Write a value to register in synthesizer.
  59 * dev:         i2c bus device (not used if CONFIG_DM_I2C is not set)
  60 * @addr:       addr within the i2c device
  61 * val:         Value to be written in the addr.
  62 *
  63 * Enable the byte read mode in the address and start the i2c transfer.
  64 * Returns 0 on success
  65 */
  66static int clk_synthesizer_reg_write(struct udevice *dev, int addr, u8 val)
  67{
  68        u8 cmd[2];
  69        int rc = 0;
  70
  71        /* Enable byte write */
  72        cmd[0] = addr | CLK_SYNTHESIZER_BYTE_MODE;
  73        cmd[1] = val;
  74
  75#if !CONFIG_IS_ENABLED(DM_I2C)
  76        rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, cmd, 2);
  77#else
  78        rc = dm_i2c_write(dev, addr, cmd, 2);
  79#endif
  80        if (rc)
  81                printf("Clock synthesizer reg write failed at addr = 0x%x\n",
  82                       addr);
  83        return rc;
  84}
  85
  86/**
  87 * setup_clock_syntherizer - Program the clock synthesizer to get the desired
  88 *                              frequency.
  89 * @data: Data containing the desired output
  90 *
  91 * This is a PLL-based high performance synthesizer which gives 3 outputs
  92 * as per the PLL_DIV and load capacitor programmed.
  93 */
  94int setup_clock_synthesizer(struct clk_synth *data)
  95{
  96        int rc;
  97        u8 val = 0;
  98        struct udevice *dev = NULL;
  99#if !CONFIG_IS_ENABLED(DM_I2C)
 100        rc =  i2c_probe(CLK_SYNTHESIZER_I2C_ADDR);
 101        if (rc) {
 102                printf("i2c probe failed at address 0x%x\n",
 103                       CLK_SYNTHESIZER_I2C_ADDR);
 104                return rc;
 105        }
 106#else
 107        rc = i2c_get_chip_for_busnum(0, CLK_SYNTHESIZER_I2C_ADDR, 1, &dev);
 108        if (rc) {
 109                printf("failed to get device for synthesizer at address 0x%x\n",
 110                       CLK_SYNTHESIZER_I2C_ADDR);
 111                return rc;
 112        }
 113#endif
 114        rc = clk_synthesizer_reg_read(dev, CLK_SYNTHESIZER_ID_REG, &val);
 115        if (val != data->id)
 116                return rc;
 117
 118        /* Crystal Load capacitor selection */
 119        rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_XCSEL,
 120                                       data->capacitor);
 121        if (rc)
 122                return rc;
 123        rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_MUX_REG,
 124                                       data->mux);
 125        if (rc)
 126                return rc;
 127        rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_PDIV2_REG,
 128                                       data->pdiv2);
 129        if (rc)
 130                return rc;
 131        rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_PDIV3_REG,
 132                                       data->pdiv3);
 133        if (rc)
 134                return rc;
 135
 136        return 0;
 137}
 138