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

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/qcom-spmi-adc5-gen3.c
Extension
.c
Size
24390 bytes
Lines
861
Domain
Driver Families
Bucket
drivers/iio
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 {
	struct adc5_channel_common_prop common_props;
	int adc_tm;
	struct adc5_chip *chip;
};

/**
 * struct adc5_chip - ADC private structure.
 * @dev: SPMI ADC5 Gen3 device.
 * @dev_data: Top-level ADC device data.
 * @nchannels: number of ADC channels.
 * @chan_props: array of ADC channel properties.
 * @iio_chans: array of IIO channels specification.
 * @complete: ADC result notification after interrupt is received.
 * @lock: ADC lock for access to the peripheral, to prevent concurrent
 *	requests from multiple clients.
 * @data: software configuration data.
 * @n_tm_channels: number of ADC channels used for TM measurements.
 * @handler: TM callback to be called for threshold violation interrupt
 *	on first SDAM.
 * @tm_aux: pointer to auxiliary TM device.
 */
struct adc5_chip {
	struct device *dev;
	struct adc5_device_data dev_data;
	unsigned int nchannels;
	struct adc5_channel_prop *chan_props;
	struct iio_chan_spec *iio_chans;
	struct completion complete;
	struct mutex lock;
	const struct adc5_data *data;
	unsigned int n_tm_channels;
	void (*handler)(struct auxiliary_device *tm_aux);
	struct auxiliary_device *tm_aux;
};

int adc5_gen3_read(struct adc5_device_data *adc, unsigned int sdam_index,
		   u16 offset, u8 *data, int len)
{
	return regmap_bulk_read(adc->regmap,
				adc->base[sdam_index].base_addr + offset,
				data, len);
}
EXPORT_SYMBOL_NS_GPL(adc5_gen3_read, "QCOM_SPMI_ADC5_GEN3");

int adc5_gen3_write(struct adc5_device_data *adc, unsigned int sdam_index,
		    u16 offset, u8 *data, int len)
{
	return regmap_bulk_write(adc->regmap,
				 adc->base[sdam_index].base_addr + offset,
				 data, len);
}
EXPORT_SYMBOL_NS_GPL(adc5_gen3_write, "QCOM_SPMI_ADC5_GEN3");

static int adc5_gen3_read_voltage_data(struct adc5_chip *adc, u16 *data)
{
	u8 rslt[2];
	int ret;

	ret = adc5_gen3_read(&adc->dev_data, ADC5_GEN3_VADC_SDAM,
			     ADC5_GEN3_CH_DATA0(0), rslt, sizeof(rslt));
	if (ret)
		return ret;

	*data = get_unaligned_le16(rslt);

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

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

	return 0;
}

void adc5_gen3_update_dig_param(struct adc5_channel_common_prop *prop, u8 *data)
{
	/* Update calibration select and decimation ratio select */
	*data &= ~(ADC5_GEN3_DIG_PARAM_CAL_SEL_MASK | ADC5_GEN3_DIG_PARAM_DEC_RATIO_SEL_MASK);
	*data |= FIELD_PREP(ADC5_GEN3_DIG_PARAM_CAL_SEL_MASK, prop->cal_method);
	*data |= FIELD_PREP(ADC5_GEN3_DIG_PARAM_DEC_RATIO_SEL_MASK, prop->decimation);
}
EXPORT_SYMBOL_NS_GPL(adc5_gen3_update_dig_param, "QCOM_SPMI_ADC5_GEN3");

#define ADC5_GEN3_READ_CONFIG_REGS 7

static int adc5_gen3_configure(struct adc5_chip *adc,
			       struct adc5_channel_common_prop *prop)
{

Annotation

Implementation Notes