drivers/iio/adc/qcom-spmi-adc5.c

Source file repositories/reference/linux-study-clean/drivers/iio/adc/qcom-spmi-adc5.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/qcom-spmi-adc5.c
Extension
.c
Size
25926 bytes
Lines
941
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 adc5_channel_prop {
	unsigned int		channel;
	enum adc5_cal_method	cal_method;
	enum adc5_cal_val	cal_val;
	unsigned int		decimation;
	unsigned int		sid;
	unsigned int		prescale;
	unsigned int		hw_settle_time;
	unsigned int		avg_samples;
	enum vadc_scale_fn_type	scale_fn_type;
	const char		*channel_name;
};

/**
 * struct adc5_chip - ADC private structure.
 * @regmap: SPMI ADC5 peripheral register map field.
 * @dev: SPMI ADC5 device.
 * @base: base address for the ADC peripheral.
 * @nchannels: number of ADC channels.
 * @chan_props: array of ADC channel properties.
 * @iio_chans: array of IIO channels specification.
 * @poll_eoc: use polling instead of interrupt.
 * @complete: ADC result notification after interrupt is received.
 * @lock: ADC lock for access to the peripheral.
 * @data: software configuration data.
 */
struct adc5_chip {
	struct regmap		*regmap;
	struct device		*dev;
	u16			base;
	unsigned int		nchannels;
	struct adc5_channel_prop	*chan_props;
	struct iio_chan_spec	*iio_chans;
	bool			poll_eoc;
	struct completion	complete;
	struct mutex		lock;
	const struct adc5_data	*data;
};

static int adc5_read(struct adc5_chip *adc, u16 offset, u8 *data, int len)
{
	return regmap_bulk_read(adc->regmap, adc->base + offset, data, len);
}

static int adc5_write(struct adc5_chip *adc, u16 offset, u8 *data, int len)
{
	return regmap_bulk_write(adc->regmap, adc->base + offset, data, len);
}

static int adc5_masked_write(struct adc5_chip *adc, u16 offset, u8 mask, u8 val)
{
	return regmap_update_bits(adc->regmap, adc->base + offset, mask, val);
}

static int adc5_read_voltage_data(struct adc5_chip *adc, u16 *data)
{
	int ret;
	u8 rslt_lsb, rslt_msb;

	ret = adc5_read(adc, ADC5_USR_DATA0, &rslt_lsb, sizeof(rslt_lsb));
	if (ret)
		return ret;

	ret = adc5_read(adc, ADC5_USR_DATA1, &rslt_msb, sizeof(rslt_lsb));
	if (ret)
		return ret;

	*data = (rslt_msb << 8) | rslt_lsb;

	if (*data == ADC5_USR_DATA_CHECK) {
		dev_err(adc->dev, "Invalid data:0x%x\n", *data);
		return -EINVAL;
	}

	dev_dbg(adc->dev, "voltage raw code:0x%x\n", *data);

	return 0;
}

static int adc5_poll_wait_eoc(struct adc5_chip *adc)
{
	unsigned int count, retry = ADC5_CONV_TIME_RETRY;
	u8 status1;
	int ret;

	for (count = 0; count < retry; count++) {
		ret = adc5_read(adc, ADC5_USR_STATUS1, &status1,
							sizeof(status1));
		if (ret)
			return ret;

Annotation

Implementation Notes