drivers/iio/frequency/admfm2000.c

Source file repositories/reference/linux-study-clean/drivers/iio/frequency/admfm2000.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/frequency/admfm2000.c
Extension
.c
Size
6623 bytes
Lines
271
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 admfm2000_state {
	struct mutex			lock; /* protect sensor state */
	struct gpio_desc		*sw1_ch[2];
	struct gpio_desc		*sw2_ch[2];
	struct gpio_desc		*dsa1_gpios[5];
	struct gpio_desc		*dsa2_gpios[5];
	u32				gain[2];
};

static int admfm2000_mode(struct iio_dev *indio_dev, u32 chan, u32 mode)
{
	struct admfm2000_state *st = iio_priv(indio_dev);
	int i;

	switch (mode) {
	case ADMFM2000_MIXER_MODE:
		for (i = 0; i < ADMFM2000_MODE_GPIOS; i++) {
			gpiod_set_value_cansleep(st->sw1_ch[i], (chan == 0) ? 1 : 0);
			gpiod_set_value_cansleep(st->sw2_ch[i], (chan == 0) ? 0 : 1);
		}
		return 0;
	case ADMFM2000_DIRECT_IF_MODE:
		for (i = 0; i < ADMFM2000_MODE_GPIOS; i++) {
			gpiod_set_value_cansleep(st->sw1_ch[i], (chan == 0) ? 0 : 1);
			gpiod_set_value_cansleep(st->sw2_ch[i], (chan == 0) ? 1 : 0);
		}
		return 0;
	default:
		return -EINVAL;
	}
}

static int admfm2000_attenuation(struct iio_dev *indio_dev, u32 chan, u32 value)
{
	struct admfm2000_state *st = iio_priv(indio_dev);
	int i;

	switch (chan) {
	case 0:
		for (i = 0; i < ADMFM2000_DSA_GPIOS; i++)
			gpiod_set_value_cansleep(st->dsa1_gpios[i], value & (1 << i));
		return 0;
	case 1:
		for (i = 0; i < ADMFM2000_DSA_GPIOS; i++)
			gpiod_set_value_cansleep(st->dsa2_gpios[i], value & (1 << i));
		return 0;
	default:
		return -EINVAL;
	}
}

static int admfm2000_read_raw(struct iio_dev *indio_dev,
			      struct iio_chan_spec const *chan, int *val,
			      int *val2, long mask)
{
	struct admfm2000_state *st = iio_priv(indio_dev);
	int gain;

	switch (mask) {
	case IIO_CHAN_INFO_HARDWAREGAIN:
		mutex_lock(&st->lock);
		gain = ~(st->gain[chan->channel]) * -1000;
		*val = gain / 1000;
		*val2 = (gain % 1000) * 1000;
		mutex_unlock(&st->lock);

		return IIO_VAL_INT_PLUS_MICRO_DB;
	default:
		return -EINVAL;
	}
}

static int admfm2000_write_raw(struct iio_dev *indio_dev,
			       struct iio_chan_spec const *chan, int val,
			       int val2, long mask)
{
	struct admfm2000_state *st = iio_priv(indio_dev);
	int gain, ret;

	if (val < 0)
		gain = (val * 1000) - (val2 / 1000);
	else
		gain = (val * 1000) + (val2 / 1000);

	if (gain > ADMFM2000_MAX_GAIN || gain < ADMFM2000_MIN_GAIN)
		return -EINVAL;

	switch (mask) {
	case IIO_CHAN_INFO_HARDWAREGAIN:
		mutex_lock(&st->lock);

Annotation

Implementation Notes