linux/drivers/clk/clk-versaclock5.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Driver for IDT Versaclock 5
 *
 * Copyright (C) 2017 Marek Vasut <[email protected]>
 */

/*
 * Possible optimizations:
 * - Use spread spectrum
 * - Use integer divider in FOD if applicable
 */

#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/slab.h>

#include <dt-bindings/clock/versaclock.h>

/* VersaClock5 registers */
#define VC5_OTP_CONTROL

/* Factory-reserved register block */
#define VC5_RSVD_DEVICE_ID
#define VC5_RSVD_ADC_GAIN_7_0
#define VC5_RSVD_ADC_GAIN_15_8
#define VC5_RSVD_ADC_OFFSET_7_0
#define VC5_RSVD_ADC_OFFSET_15_8
#define VC5_RSVD_TEMPY
#define VC5_RSVD_OFFSET_TBIN
#define VC5_RSVD_GAIN
#define VC5_RSVD_TEST_NP
#define VC5_RSVD_UNUSED
#define VC5_RSVD_BANDGAP_TRIM_UP
#define VC5_RSVD_BANDGAP_TRIM_DN
#define VC5_RSVD_CLK_R_12_CLK_AMP_4
#define VC5_RSVD_CLK_R_34_CLK_AMP_4
#define VC5_RSVD_CLK_AMP_123

/* Configuration register block */
#define VC5_PRIM_SRC_SHDN
#define VC5_PRIM_SRC_SHDN_EN_XTAL
#define VC5_PRIM_SRC_SHDN_EN_CLKIN
#define VC5_PRIM_SRC_SHDN_EN_DOUBLE_XTAL_FREQ
#define VC5_PRIM_SRC_SHDN_SP
#define VC5_PRIM_SRC_SHDN_EN_GBL_SHDN

#define VC5_VCO_BAND
#define VC5_XTAL_X1_LOAD_CAP
#define VC5_XTAL_X2_LOAD_CAP
#define VC5_REF_DIVIDER
#define VC5_REF_DIVIDER_SEL_PREDIV2
#define VC5_REF_DIVIDER_REF_DIV(n)

#define VC5_VCO_CTRL_AND_PREDIV
#define VC5_VCO_CTRL_AND_PREDIV_BYPASS_PREDIV

#define VC5_FEEDBACK_INT_DIV
#define VC5_FEEDBACK_INT_DIV_BITS
#define VC5_FEEDBACK_FRAC_DIV(n)
#define VC5_RC_CONTROL0
#define VC5_RC_CONTROL1

/* These registers are named "Unused Factory Reserved Registers" */
#define VC5_RESERVED_X0(idx)
#define VC5_RESERVED_X0_BYPASS_SYNC

/* Output divider control for divider 1,2,3,4 */
#define VC5_OUT_DIV_CONTROL(idx)
#define VC5_OUT_DIV_CONTROL_RESET
#define VC5_OUT_DIV_CONTROL_SELB_NORM
#define VC5_OUT_DIV_CONTROL_SEL_EXT
#define VC5_OUT_DIV_CONTROL_INT_MODE
#define VC5_OUT_DIV_CONTROL_EN_FOD

#define VC5_OUT_DIV_FRAC(idx, n)
#define VC5_OUT_DIV_FRAC4_OD_SCEE

#define VC5_OUT_DIV_STEP_SPREAD(idx, n)
#define VC5_OUT_DIV_SPREAD_MOD(idx, n)
#define VC5_OUT_DIV_SKEW_INT(idx, n)
#define VC5_OUT_DIV_INT(idx, n)
#define VC5_OUT_DIV_SKEW_FRAC(idx)

/* Clock control register for clock 1,2 */
#define VC5_CLK_OUTPUT_CFG(idx, n)
#define VC5_CLK_OUTPUT_CFG0_CFG_SHIFT
#define VC5_CLK_OUTPUT_CFG0_CFG_MASK

#define VC5_CLK_OUTPUT_CFG0_CFG_LVPECL
#define VC5_CLK_OUTPUT_CFG0_CFG_CMOS
#define VC5_CLK_OUTPUT_CFG0_CFG_HCSL33
#define VC5_CLK_OUTPUT_CFG0_CFG_LVDS
#define VC5_CLK_OUTPUT_CFG0_CFG_CMOS2
#define VC5_CLK_OUTPUT_CFG0_CFG_CMOSD
#define VC5_CLK_OUTPUT_CFG0_CFG_HCSL25

#define VC5_CLK_OUTPUT_CFG0_PWR_SHIFT
#define VC5_CLK_OUTPUT_CFG0_PWR_MASK
#define VC5_CLK_OUTPUT_CFG0_PWR_18
#define VC5_CLK_OUTPUT_CFG0_PWR_25
#define VC5_CLK_OUTPUT_CFG0_PWR_33
#define VC5_CLK_OUTPUT_CFG0_SLEW_SHIFT
#define VC5_CLK_OUTPUT_CFG0_SLEW_MASK
#define VC5_CLK_OUTPUT_CFG0_SLEW_80
#define VC5_CLK_OUTPUT_CFG0_SLEW_85
#define VC5_CLK_OUTPUT_CFG0_SLEW_90
#define VC5_CLK_OUTPUT_CFG0_SLEW_100
#define VC5_CLK_OUTPUT_CFG1_EN_CLKBUF

#define VC5_CLK_OE_SHDN
#define VC5_CLK_OS_SHDN

#define VC5_GLOBAL_REGISTER
#define VC5_GLOBAL_REGISTER_GLOBAL_RESET

/* The minimum VCO frequency is 2.5 GHz. The maximum is variant specific. */
#define VC5_PLL_VCO_MIN

/* VC5 Input mux settings */
#define VC5_MUX_IN_XIN
#define VC5_MUX_IN_CLKIN

/* Maximum number of clk_out supported by this driver */
#define VC5_MAX_CLK_OUT_NUM

/* Maximum number of FODs supported by this driver */
#define VC5_MAX_FOD_NUM

/* flags to describe chip features */
/* chip has built-in oscilator */
#define VC5_HAS_INTERNAL_XTAL
/* chip has PFD requency doubler */
#define VC5_HAS_PFD_FREQ_DBL
/* chip has bits to disable FOD sync */
#define VC5_HAS_BYPASS_SYNC_BIT

/* Supported IDT VC5 models. */
enum vc5_model {};

/* Structure to describe features of a particular VC5 model */
struct vc5_chip_info {};

struct vc5_driver_data;

struct vc5_hw_data {};

struct vc5_out_data {};

struct vc5_driver_data {};

/*
 * VersaClock5 i2c regmap
 */
static bool vc5_regmap_is_writeable(struct device *dev, unsigned int reg)
{}

static const struct regmap_config vc5_regmap_config =;

/*
 * VersaClock5 input multiplexer between XTAL and CLKIN divider
 */
static unsigned char vc5_mux_get_parent(struct clk_hw *hw)
{}

static int vc5_mux_set_parent(struct clk_hw *hw, u8 index)
{}

static const struct clk_ops vc5_mux_ops =;

static unsigned long vc5_dbl_recalc_rate(struct clk_hw *hw,
					 unsigned long parent_rate)
{}

static long vc5_dbl_round_rate(struct clk_hw *hw, unsigned long rate,
			       unsigned long *parent_rate)
{}

static int vc5_dbl_set_rate(struct clk_hw *hw, unsigned long rate,
			    unsigned long parent_rate)
{}

static const struct clk_ops vc5_dbl_ops =;

static unsigned long vc5_pfd_recalc_rate(struct clk_hw *hw,
					 unsigned long parent_rate)
{}

static long vc5_pfd_round_rate(struct clk_hw *hw, unsigned long rate,
			       unsigned long *parent_rate)
{}

static int vc5_pfd_set_rate(struct clk_hw *hw, unsigned long rate,
			    unsigned long parent_rate)
{}

static const struct clk_ops vc5_pfd_ops =;

/*
 * VersaClock5 PLL/VCO
 */
static unsigned long vc5_pll_recalc_rate(struct clk_hw *hw,
					 unsigned long parent_rate)
{}

static long vc5_pll_round_rate(struct clk_hw *hw, unsigned long rate,
			       unsigned long *parent_rate)
{}

static int vc5_pll_set_rate(struct clk_hw *hw, unsigned long rate,
			    unsigned long parent_rate)
{}

static const struct clk_ops vc5_pll_ops =;

static unsigned long vc5_fod_recalc_rate(struct clk_hw *hw,
					 unsigned long parent_rate)
{}

static long vc5_fod_round_rate(struct clk_hw *hw, unsigned long rate,
			       unsigned long *parent_rate)
{}

static int vc5_fod_set_rate(struct clk_hw *hw, unsigned long rate,
			    unsigned long parent_rate)
{}

static const struct clk_ops vc5_fod_ops =;

static int vc5_clk_out_prepare(struct clk_hw *hw)
{}

static void vc5_clk_out_unprepare(struct clk_hw *hw)
{}

static unsigned char vc5_clk_out_get_parent(struct clk_hw *hw)
{}

static int vc5_clk_out_set_parent(struct clk_hw *hw, u8 index)
{}

static const struct clk_ops vc5_clk_out_ops =;

static struct clk_hw *vc5_of_clk_get(struct of_phandle_args *clkspec,
				     void *data)
{}

static int vc5_map_index_to_output(const enum vc5_model model,
				   const unsigned int n)
{}

static int vc5_update_mode(struct device_node *np_output,
			   struct vc5_out_data *clk_out)
{}

static int vc5_update_power(struct device_node *np_output,
			    struct vc5_out_data *clk_out)
{}

static int vc5_map_cap_value(u32 femtofarads)
{}
static int vc5_update_cap_load(struct device_node *node, struct vc5_driver_data *vc5)
{}

static int vc5_update_slew(struct device_node *np_output,
			   struct vc5_out_data *clk_out)
{}

static int vc5_get_output_config(struct i2c_client *client,
				 struct vc5_out_data *clk_out)
{}

static const struct of_device_id clk_vc5_of_match[];

static int vc5_probe(struct i2c_client *client)
{}

static void vc5_remove(struct i2c_client *client)
{}

static int __maybe_unused vc5_suspend(struct device *dev)
{}

static int __maybe_unused vc5_resume(struct device *dev)
{}

static const struct vc5_chip_info idt_5p49v5923_info =;

static const struct vc5_chip_info idt_5p49v5925_info =;

static const struct vc5_chip_info idt_5p49v5933_info =;

static const struct vc5_chip_info idt_5p49v5935_info =;

static const struct vc5_chip_info idt_5p49v60_info =;

static const struct vc5_chip_info idt_5p49v6901_info =;

static const struct vc5_chip_info idt_5p49v6965_info =;

static const struct vc5_chip_info idt_5p49v6975_info =;

static const struct i2c_device_id vc5_id[] =;
MODULE_DEVICE_TABLE(i2c, vc5_id);

static const struct of_device_id clk_vc5_of_match[] =;
MODULE_DEVICE_TABLE(of, clk_vc5_of_match);

static SIMPLE_DEV_PM_OPS(vc5_pm_ops, vc5_suspend, vc5_resume);

static struct i2c_driver vc5_driver =;
module_i2c_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();