drivers/clk/clk-cs2000-cp.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/clk-cs2000-cp.c
Extension
.c
Size
14197 bytes
Lines
639
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 cs2000_priv {
	struct clk_hw hw;
	struct i2c_client *client;
	struct clk *clk_in;
	struct clk *ref_clk;
	struct regmap *regmap;

	bool dynamic_mode;
	bool lf_ratio;
	bool clk_skip;

	/* suspend/resume */
	unsigned long saved_rate;
	unsigned long saved_parent_rate;
};

static const struct of_device_id cs2000_of_match[] = {
	{ .compatible = "cirrus,cs2000-cp", },
	{},
};
MODULE_DEVICE_TABLE(of, cs2000_of_match);

static const struct i2c_device_id cs2000_id[] = {
	{ "cs2000-cp", },
	{}
};
MODULE_DEVICE_TABLE(i2c, cs2000_id);

static int cs2000_enable_dev_config(struct cs2000_priv *priv, bool enable)
{
	int ret;

	ret = regmap_update_bits(priv->regmap, DEVICE_CFG1, ENDEV1,
				 enable ? ENDEV1 : 0);
	if (ret < 0)
		return ret;

	ret = regmap_update_bits(priv->regmap, GLOBAL_CFG,  ENDEV2,
				 enable ? ENDEV2 : 0);
	if (ret < 0)
		return ret;

	ret = regmap_update_bits(priv->regmap, FUNC_CFG1, CLKSKIPEN,
				 (enable && priv->clk_skip) ? CLKSKIPEN : 0);
	if (ret < 0)
		return ret;

	return 0;
}

static int cs2000_ref_clk_bound_rate(struct cs2000_priv *priv,
				     u32 rate_in)
{
	u32 val;

	if (rate_in >= 32000000 && rate_in < 56000000)
		val = 0x0;
	else if (rate_in >= 16000000 && rate_in < 28000000)
		val = 0x1;
	else if (rate_in >= 8000000 && rate_in < 14000000)
		val = 0x2;
	else
		return -EINVAL;

	return regmap_update_bits(priv->regmap, FUNC_CFG1,
				  REFCLKDIV_MASK,
				  REFCLKDIV(val));
}

static int cs2000_wait_pll_lock(struct cs2000_priv *priv)
{
	struct device *dev = priv_to_dev(priv);
	unsigned int i, val;
	int ret;

	for (i = 0; i < 256; i++) {
		ret = regmap_read(priv->regmap, DEVICE_CTRL, &val);
		if (ret < 0)
			return ret;
		if (!(val & PLL_UNLOCK))
			return 0;
		udelay(1);
	}

	dev_err(dev, "pll lock failed\n");

	return -ETIMEDOUT;
}

static int cs2000_clk_out_enable(struct cs2000_priv *priv, bool enable)

Annotation

Implementation Notes