drivers/iio/dac/ad5592r-base.c

Source file repositories/reference/linux-study-clean/drivers/iio/dac/ad5592r-base.c

File Facts

System
Linux kernel
Corpus path
drivers/iio/dac/ad5592r-base.c
Extension
.c
Size
14618 bytes
Lines
667
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

switch (st->channel_modes[i]) {
		case CH_MODE_DAC:
			dac |= BIT(i);
			break;

		case CH_MODE_ADC:
			adc |= BIT(i);
			break;

		case CH_MODE_DAC_AND_ADC:
			dac |= BIT(i);
			adc |= BIT(i);
			break;

		case CH_MODE_GPIO:
			st->gpio_map |= BIT(i);
			st->gpio_in |= BIT(i); /* Default to input */
			break;

		case CH_MODE_UNUSED:
		default:
			switch (st->channel_offstate[i]) {
			case CH_OFFSTATE_OUT_TRISTATE:
				tristate |= BIT(i);
				break;

			case CH_OFFSTATE_OUT_LOW:
				st->gpio_out |= BIT(i);
				break;

			case CH_OFFSTATE_OUT_HIGH:
				st->gpio_out |= BIT(i);
				st->gpio_val |= BIT(i);
				break;

			case CH_OFFSTATE_PULLDOWN:
			default:
				pulldown |= BIT(i);
				break;
			}
		}
	}

	guard(mutex)(&st->lock);

	/* Pull down unused pins to GND */
	ret = ops->reg_write(st, AD5592R_REG_PULLDOWN, pulldown);
	if (ret)
		return ret;

	ret = ops->reg_write(st, AD5592R_REG_TRISTATE, tristate);
	if (ret)
		return ret;

	/* Configure pins that we use */
	ret = ops->reg_write(st, AD5592R_REG_DAC_EN, dac);
	if (ret)
		return ret;

	ret = ops->reg_write(st, AD5592R_REG_ADC_EN, adc);
	if (ret)
		return ret;

	ret = ops->reg_write(st, AD5592R_REG_GPIO_SET, st->gpio_val);
	if (ret)
		return ret;

	ret = ops->reg_write(st, AD5592R_REG_GPIO_OUT_EN, st->gpio_out);
	if (ret)
		return ret;

	ret = ops->reg_write(st, AD5592R_REG_GPIO_IN_EN, st->gpio_in);
	if (ret)
		return ret;

	/* Verify that we can read back at least one register */
	ret = ops->reg_read(st, AD5592R_REG_ADC_EN, &read_back);
	if (!ret && (read_back & 0xff) != adc)
		return -EIO;

	return 0;
}

static int ad5592r_reset_channel_modes(struct ad5592r_state *st)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(st->channel_modes); i++)
		st->channel_modes[i] = CH_MODE_UNUSED;

Annotation

Implementation Notes