drivers/iio/adc/aspeed_adc.c

Source file repositories/reference/linux-study-clean/drivers/iio/adc/aspeed_adc.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/aspeed_adc.c
Extension
.c
Size
23221 bytes
Lines
790
Domain
Driver Families
Bucket
drivers/iio
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 aspeed_adc_trim_locate {
	const unsigned int offset;
	const unsigned int field;
};

struct aspeed_adc_model_data {
	const char *model_name;
	unsigned int min_sampling_rate;	// Hz
	unsigned int max_sampling_rate;	// Hz
	unsigned int vref_fixed_mv;
	bool wait_init_sequence;
	bool need_prescaler;
	bool bat_sense_sup;
	u8 scaler_bit_width;
	unsigned int num_channels;
	const struct aspeed_adc_trim_locate *trim_locate;
};

struct adc_gain {
	u8 mult;
	u8 div;
};

struct aspeed_adc_data {
	struct device		*dev;
	const struct aspeed_adc_model_data *model_data;
	void __iomem		*base;
	spinlock_t		clk_lock;
	struct clk_hw		*fixed_div_clk;
	struct clk_hw		*clk_prescaler;
	struct clk_hw		*clk_scaler;
	struct reset_control	*rst;
	int			vref_mv;
	u32			sample_period_ns;
	int			cv;
	bool			battery_sensing;
	struct adc_gain		battery_mode_gain;
};

/*
 * Enable multiple consecutive channels starting from channel 0.
 * This creates a bitmask for channels 0 to (num_channels - 1).
 * For example: num_channels=3 creates mask 0x0007 (channels 0,1,2)
 */
static inline u32 aspeed_adc_channels_mask(unsigned int num_channels)
{
	if (num_channels > 16)
		return GENMASK(15, 0);

	return BIT(num_channels) - 1;
}

static inline unsigned int aspeed_adc_get_active_channels(const struct aspeed_adc_data *data)
{
	/*
	 * For controllers with battery sensing capability, the last channel
	 * is reserved for battery sensing and should not be included in
	 * normal channel operations.
	 */
	if (data->model_data->bat_sense_sup)
		return data->model_data->num_channels - 1;
	return data->model_data->num_channels;
}

#define ASPEED_CHAN(_idx, _data_reg_addr) {			\
	.type = IIO_VOLTAGE,					\
	.indexed = 1,						\
	.channel = (_idx),					\
	.address = (_data_reg_addr),				\
	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\
	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) |	\
				BIT(IIO_CHAN_INFO_SAMP_FREQ) |	\
				BIT(IIO_CHAN_INFO_OFFSET),	\
}

static const struct iio_chan_spec aspeed_adc_iio_channels[] = {
	ASPEED_CHAN(0, 0x10),
	ASPEED_CHAN(1, 0x12),
	ASPEED_CHAN(2, 0x14),
	ASPEED_CHAN(3, 0x16),
	ASPEED_CHAN(4, 0x18),
	ASPEED_CHAN(5, 0x1A),
	ASPEED_CHAN(6, 0x1C),
	ASPEED_CHAN(7, 0x1E),
	ASPEED_CHAN(8, 0x20),
	ASPEED_CHAN(9, 0x22),
	ASPEED_CHAN(10, 0x24),
	ASPEED_CHAN(11, 0x26),
	ASPEED_CHAN(12, 0x28),
	ASPEED_CHAN(13, 0x2A),

Annotation

Implementation Notes