drivers/hwmon/ltc4282.c

Source file repositories/reference/linux-study-clean/drivers/hwmon/ltc4282.c

File Facts

System
Linux kernel
Corpus path
drivers/hwmon/ltc4282.c
Extension
.c
Size
45534 bytes
Lines
1711
Domain
Driver Families
Bucket
drivers/hwmon
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 ltc4282_cache {
	u32 in_max_raw;
	u32 in_min_raw;
	long in_highest;
	long in_lowest;
	bool en;
};

struct ltc4282_state {
	struct regmap *map;
	struct clk_hw clk_hw;
	/*
	 * Used to cache values for VDD/VSOURCE depending which will be used
	 * when hwmon is not enabled for that channel. Needed because they share
	 * the same registers.
	 */
	struct ltc4282_cache in0_1_cache[LTC4282_CHAN_VGPIO];
	u32 vsense_max;
	long power_max;
	u32 rsense;
	u16 vdd;
	u16 vfs_out;
	bool energy_en;
};

enum {
	LTC4282_CLKOUT_NONE,
	LTC4282_CLKOUT_INT,
	LTC4282_CLKOUT_TICK,
};

static int ltc4282_set_rate(struct clk_hw *hw,
			    unsigned long rate, unsigned long parent_rate)
{
	struct ltc4282_state *st = container_of(hw, struct ltc4282_state,
						clk_hw);
	u32 val = LTC4282_CLKOUT_INT;

	if (rate == LTC4282_CLKOUT_CNV)
		val = LTC4282_CLKOUT_TICK;

	return regmap_update_bits(st->map, LTC4282_CLK_DIV, LTC4282_CLKOUT_MASK,
				  FIELD_PREP(LTC4282_CLKOUT_MASK, val));
}

/*
 * Note the 15HZ conversion rate assumes 12bit ADC which is what we are
 * supporting for now.
 */
static const unsigned int ltc4282_out_rates[] = {
	LTC4282_CLKOUT_CNV, LTC4282_CLKOUT_SYSTEM
};

static int ltc4282_determine_rate(struct clk_hw *hw,
				  struct clk_rate_request *req)
{
	int idx = find_closest(req->rate, ltc4282_out_rates,
			       ARRAY_SIZE(ltc4282_out_rates));

	req->rate = ltc4282_out_rates[idx];

	return 0;
}

static unsigned long ltc4282_recalc_rate(struct clk_hw *hw,
					 unsigned long parent)
{
	struct ltc4282_state *st = container_of(hw, struct ltc4282_state,
						clk_hw);
	u32 clkdiv;
	int ret;

	ret = regmap_read(st->map, LTC4282_CLK_DIV, &clkdiv);
	if (ret)
		return 0;

	clkdiv = FIELD_GET(LTC4282_CLKOUT_MASK, clkdiv);
	if (!clkdiv)
		return 0;
	if (clkdiv == LTC4282_CLKOUT_INT)
		return LTC4282_CLKOUT_SYSTEM;

	return LTC4282_CLKOUT_CNV;
}

static void ltc4282_disable(struct clk_hw *clk_hw)
{
	struct ltc4282_state *st = container_of(clk_hw, struct ltc4282_state,
						clk_hw);

Annotation

Implementation Notes