drivers/clk/clk-versaclock5.c

Source file repositories/reference/linux-study-clean/drivers/clk/clk-versaclock5.c

File Facts

System
Linux kernel
Corpus path
drivers/clk/clk-versaclock5.c
Extension
.c
Size
37790 bytes
Lines
1356
Domain
Driver Families
Bucket
drivers/clk
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct vc5_chip_info {
	const enum vc5_model	model;
	const unsigned int	clk_fod_cnt;
	const unsigned int	clk_out_cnt;
	const u32		flags;
	const unsigned long	vco_max;
};

struct vc5_driver_data;

struct vc5_hw_data {
	struct clk_hw		hw;
	struct vc5_driver_data	*vc5;
	u32			div_int;
	u32			div_frc;
	unsigned int		num;
};

struct vc5_out_data {
	struct clk_hw		hw;
	struct vc5_driver_data	*vc5;
	unsigned int		num;
	unsigned int		clk_output_cfg0;
	unsigned int		clk_output_cfg0_mask;
};

struct vc5_driver_data {
	struct i2c_client	*client;
	struct regmap		*regmap;
	const struct vc5_chip_info	*chip_info;

	struct clk		*pin_xin;
	struct clk		*pin_clkin;
	unsigned char		clk_mux_ins;
	struct clk_hw		clk_mux;
	struct clk_hw		clk_mul;
	struct clk_hw		clk_pfd;
	struct vc5_hw_data	clk_pll;
	struct vc5_hw_data	clk_fod[VC5_MAX_FOD_NUM];
	struct vc5_out_data	clk_out[VC5_MAX_CLK_OUT_NUM];
};

/*
 * VersaClock5 i2c regmap
 */
static bool vc5_regmap_is_writeable(struct device *dev, unsigned int reg)
{
	/* Factory reserved regs, make them read-only */
	if (reg <= 0xf)
		return false;

	/* Factory reserved regs, make them read-only */
	if (reg == 0x14 || reg == 0x1c || reg == 0x1d)
		return false;

	return true;
}

static const struct regmap_config vc5_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.cache_type = REGCACHE_MAPLE,
	.max_register = 0x76,
	.writeable_reg = vc5_regmap_is_writeable,
};

/*
 * VersaClock5 input multiplexer between XTAL and CLKIN divider
 */
static unsigned char vc5_mux_get_parent(struct clk_hw *hw)
{
	struct vc5_driver_data *vc5 =
		container_of(hw, struct vc5_driver_data, clk_mux);
	const u8 mask = VC5_PRIM_SRC_SHDN_EN_XTAL | VC5_PRIM_SRC_SHDN_EN_CLKIN;
	unsigned int src;
	int ret;

	ret = regmap_read(vc5->regmap, VC5_PRIM_SRC_SHDN, &src);
	if (ret)
		return 0;

	src &= mask;

	if (src == VC5_PRIM_SRC_SHDN_EN_XTAL)
		return 0;

	if (src == VC5_PRIM_SRC_SHDN_EN_CLKIN)
		return 1;

	dev_warn(&vc5->client->dev,

Annotation

Implementation Notes