drivers/clk/clk-twl.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/clk-twl.c
Extension
.c
Size
4860 bytes
Lines
215
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 twl_clock_info {
	struct device *dev;
	enum twl_type type;
	u8 base;
	struct clk_hw hw;
};

static inline int
twlclk_read(struct twl_clock_info *info, unsigned int slave_subgp,
	    unsigned int offset)
{
	u8 value;
	int status;

	status = twl_i2c_read_u8(slave_subgp, &value,
				 info->base + offset);
	return (status < 0) ? status : value;
}

static inline int
twlclk_write(struct twl_clock_info *info, unsigned int slave_subgp,
	     unsigned int offset, u8 value)
{
	return twl_i2c_write_u8(slave_subgp, value,
				info->base + offset);
}

static inline struct twl_clock_info *to_twl_clks_info(struct clk_hw *hw)
{
	return container_of(hw, struct twl_clock_info, hw);
}

static unsigned long twl_clks_recalc_rate(struct clk_hw *hw,
					  unsigned long parent_rate)
{
	return 32768;
}

static int twl6032_clks_prepare(struct clk_hw *hw)
{
	struct twl_clock_info *cinfo = to_twl_clks_info(hw);

	if (cinfo->type == TWL_TYPE_6030) {
		int grp;

		grp = twlclk_read(cinfo, TWL_MODULE_PM_RECEIVER, VREG_GRP);
		if (grp < 0)
			return grp;

		return twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
				    grp << TWL6030_CFG_STATE_GRP_SHIFT |
				    TWL6030_CFG_STATE_ON);
	}

	return twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
			    TWL6030_CFG_STATE_ON);
}

static void twl6032_clks_unprepare(struct clk_hw *hw)
{
	struct twl_clock_info *cinfo = to_twl_clks_info(hw);
	int ret;

	if (cinfo->type == TWL_TYPE_6030)
		ret = twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
				   ALL_GRP << TWL6030_CFG_STATE_GRP_SHIFT |
				   TWL6030_CFG_STATE_OFF);
	else
		ret = twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
				   TWL6030_CFG_STATE_OFF);

	if (ret < 0)
		dev_err(cinfo->dev, "clk unprepare failed\n");
}

static const struct clk_ops twl6032_clks_ops = {
	.prepare	= twl6032_clks_prepare,
	.unprepare	= twl6032_clks_unprepare,
	.recalc_rate	= twl_clks_recalc_rate,
};

struct twl_clks_data {
	struct clk_init_data init;
	u8 base;
};

static const struct twl_clks_data twl6032_clks[] = {
	{
		.init = {
			.name = "clk32kg",

Annotation

Implementation Notes