drivers/iio/adc/gehc-pmc-adc.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/adc/gehc-pmc-adc.c
Extension
.c
Size
6220 bytes
Lines
229
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 pmc_adc {
	struct i2c_client *client;
};

#define PMC_ADC_CMD_REQUEST_PROTOCOL_VERSION	0x01
#define PMC_ADC_CMD_READ_VOLTAGE(_ch)		(0x10 | (_ch))
#define PMC_ADC_CMD_READ_CURRENT(_ch)		(0x20 | (_ch))

#define PMC_ADC_VOLTAGE_CHANNEL(_ch, _ds_name) {			\
	.type = IIO_VOLTAGE,						\
	.indexed = 1,							\
	.channel = (_ch),						\
	.address = PMC_ADC_CMD_READ_VOLTAGE(_ch),			\
	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),		\
	.datasheet_name = (_ds_name),					\
}

#define PMC_ADC_CURRENT_CHANNEL(_ch, _ds_name) {			\
	.type = IIO_CURRENT,						\
	.indexed = 1,							\
	.channel = (_ch),						\
	.address = PMC_ADC_CMD_READ_CURRENT(_ch),			\
	.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),		\
	.datasheet_name = (_ds_name),					\
}

static const struct iio_chan_spec pmc_adc_channels[] = {
	PMC_ADC_VOLTAGE_CHANNEL(0, "CH0_V"),
	PMC_ADC_VOLTAGE_CHANNEL(1, "CH1_V"),
	PMC_ADC_VOLTAGE_CHANNEL(2, "CH2_V"),
	PMC_ADC_VOLTAGE_CHANNEL(3, "CH3_V"),
	PMC_ADC_VOLTAGE_CHANNEL(4, "CH4_V"),
	PMC_ADC_VOLTAGE_CHANNEL(5, "CH5_V"),
	PMC_ADC_VOLTAGE_CHANNEL(6, "CH6_V"),
	PMC_ADC_VOLTAGE_CHANNEL(7, "CH7_V"),
	PMC_ADC_VOLTAGE_CHANNEL(8, "CH8_V"),
	PMC_ADC_VOLTAGE_CHANNEL(9, "CH9_V"),
	PMC_ADC_VOLTAGE_CHANNEL(10, "CH10_V"),
	PMC_ADC_VOLTAGE_CHANNEL(11, "CH11_V"),
	PMC_ADC_VOLTAGE_CHANNEL(12, "CH12_V"),
	PMC_ADC_VOLTAGE_CHANNEL(13, "CH13_V"),
	PMC_ADC_VOLTAGE_CHANNEL(14, "CH14_V"),
	PMC_ADC_VOLTAGE_CHANNEL(15, "CH15_V"),

	PMC_ADC_CURRENT_CHANNEL(0, "CH0_I"),
	PMC_ADC_CURRENT_CHANNEL(1, "CH1_I"),
	PMC_ADC_CURRENT_CHANNEL(2, "CH2_I"),
	PMC_ADC_CURRENT_CHANNEL(3, "CH3_I"),
	PMC_ADC_CURRENT_CHANNEL(4, "CH4_I"),
	PMC_ADC_CURRENT_CHANNEL(5, "CH5_I"),
	PMC_ADC_CURRENT_CHANNEL(6, "CH6_I"),
	PMC_ADC_CURRENT_CHANNEL(7, "CH7_I"),
	PMC_ADC_CURRENT_CHANNEL(8, "CH8_I"),
	PMC_ADC_CURRENT_CHANNEL(9, "CH9_I"),
	PMC_ADC_CURRENT_CHANNEL(10, "CH10_I"),
	PMC_ADC_CURRENT_CHANNEL(11, "CH11_I"),
	PMC_ADC_CURRENT_CHANNEL(12, "CH12_I"),
	PMC_ADC_CURRENT_CHANNEL(13, "CH13_I"),
	PMC_ADC_CURRENT_CHANNEL(14, "CH14_I"),
	PMC_ADC_CURRENT_CHANNEL(15, "CH15_I"),
};

static int pmc_adc_read_raw_ch(struct pmc_adc *pmc_adc, u8 cmd, int *val)
{
	s32 ret;

	ret = i2c_smbus_read_word_swapped(pmc_adc->client, cmd);
	if (ret < 0) {
		dev_err(&pmc_adc->client->dev, "i2c read word failed (%d)\n", ret);
		return ret;
	}

	*val = sign_extend32(ret, 15);
	return 0;
}

static int pmc_adc_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
			    int *val, int *val2, long mask)
{
	struct pmc_adc *pmc_adc = iio_priv(indio_dev);
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_PROCESSED:
		/* Values are directly read in mV or mA */
		ret = pmc_adc_read_raw_ch(pmc_adc, chan->address, val);
		if (ret)
			return ret;
		return IIO_VAL_INT;
	}

Annotation

Implementation Notes