drivers/clk/clk-renesas-pcie.c

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

File Facts

System
Linux kernel
Corpus path
drivers/clk/clk-renesas-pcie.c
Extension
.c
Size
11153 bytes
Lines
429
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 rs9_chip_info {
	unsigned int		num_clks;
	u8			outshift;
	u8			did;
};

struct rs9_driver_data {
	struct i2c_client	*client;
	struct regmap		*regmap;
	const struct rs9_chip_info *chip_info;
	struct clk_hw		*clk_dif[8];
	u8			pll_amplitude;
	u8			pll_ssc;
	u8			clk_dif_sr;
};

/*
 * Renesas 9-series i2c regmap
 */
static const struct regmap_range rs9_readable_ranges[] = {
	regmap_reg_range(RS9_REG_OE, RS9_REG_REF),
	regmap_reg_range(RS9_REG_VID, RS9_REG_BCP),
};

static const struct regmap_access_table rs9_readable_table = {
	.yes_ranges = rs9_readable_ranges,
	.n_yes_ranges = ARRAY_SIZE(rs9_readable_ranges),
};

static const struct regmap_range rs9_writeable_ranges[] = {
	regmap_reg_range(RS9_REG_OE, RS9_REG_REF),
	regmap_reg_range(RS9_REG_BCP, RS9_REG_BCP),
};

static const struct regmap_access_table rs9_writeable_table = {
	.yes_ranges = rs9_writeable_ranges,
	.n_yes_ranges = ARRAY_SIZE(rs9_writeable_ranges),
};

static int rs9_regmap_i2c_write(void *context,
				unsigned int reg, unsigned int val)
{
	struct i2c_client *i2c = context;
	const u8 data[3] = { reg, 1, val };
	const int count = ARRAY_SIZE(data);
	int ret;

	ret = i2c_master_send(i2c, data, count);
	if (ret == count)
		return 0;
	else if (ret < 0)
		return ret;
	else
		return -EIO;
}

static int rs9_regmap_i2c_read(void *context,
			       unsigned int reg, unsigned int *val)
{
	struct i2c_client *i2c = context;
	struct i2c_msg xfer[2];
	u8 txdata = reg;
	u8 rxdata[2];
	int ret;

	xfer[0].addr = i2c->addr;
	xfer[0].flags = 0;
	xfer[0].len = 1;
	xfer[0].buf = (void *)&txdata;

	xfer[1].addr = i2c->addr;
	xfer[1].flags = I2C_M_RD;
	xfer[1].len = 2;
	xfer[1].buf = (void *)rxdata;

	ret = i2c_transfer(i2c->adapter, xfer, 2);
	if (ret < 0)
		return ret;
	if (ret != 2)
		return -EIO;

	/*
	 * Byte 0 is transfer length, which is always 1 due
	 * to BCP register programming to 1 in rs9_probe(),
	 * ignore it and use data from Byte 1.
	 */
	*val = rxdata[1];
	return 0;
}

Annotation

Implementation Notes