drivers/iio/dac/ad8460.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/dac/ad8460.c
Extension
.c
Size
25857 bytes
Lines
958
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 ad8460_state {
	struct spi_device *spi;
	struct regmap *regmap;
	struct iio_channel *tmp_adc_channel;
	struct clk *sync_clk;
	/* lock to protect against multiple access to the device and shared data */
	struct mutex lock;
	int refio_1p2v_mv;
	u32 ext_resistor_ohms;
	/*
	 * DMA (thus cache coherency maintenance) requires the
	 * transfer buffers to live in their own cache lines.
	 */
	__le16 spi_tx_buf __aligned(IIO_DMA_MINALIGN);
};

static int ad8460_hv_reset(struct ad8460_state *state)
{
	int ret;

	ret = regmap_set_bits(state->regmap, AD8460_CTRL_REG(0x00),
			      AD8460_HV_RESET_MSK);
	if (ret)
		return ret;

	fsleep(20);

	return regmap_clear_bits(state->regmap, AD8460_CTRL_REG(0x00),
				 AD8460_HV_RESET_MSK);
}

static int ad8460_reset(const struct ad8460_state *state)
{
	struct device *dev = &state->spi->dev;
	struct gpio_desc *reset;

	reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
	if (IS_ERR(reset))
		return dev_err_probe(dev, PTR_ERR(reset),
				     "Failed to get reset gpio");
	if (reset) {
		/* minimum duration of 10ns */
		ndelay(10);
		gpiod_set_value_cansleep(reset, 1);
		return 0;
	}

	/* bring all registers to their default state */
	return regmap_write(state->regmap, AD8460_CTRL_REG(0x03), 1);
}

static int ad8460_enable_apg_mode(struct ad8460_state *state, int val)
{
	int ret;

	ret = regmap_update_bits(state->regmap, AD8460_CTRL_REG(0x02),
				 AD8460_APG_MODE_ENABLE_MSK,
				 FIELD_PREP(AD8460_APG_MODE_ENABLE_MSK, val));
	if (ret)
		return ret;

	return regmap_update_bits(state->regmap, AD8460_CTRL_REG(0x00),
				  AD8460_WAVE_GEN_MODE_MSK,
				  FIELD_PREP(AD8460_WAVE_GEN_MODE_MSK, val));
}

static int ad8460_read_shutdown_flag(struct ad8460_state *state, u64 *flag)
{
	int ret, val;

	ret = regmap_read(state->regmap, AD8460_CTRL_REG(0x0E), &val);
	if (ret)
		return ret;

	*flag = FIELD_GET(AD8460_SHUTDOWN_FLAG_MSK, val);
	return 0;
}

static int ad8460_get_hvdac_word(struct ad8460_state *state, int index, int *val)
{
	int ret;

	ret = regmap_bulk_read(state->regmap, AD8460_HVDAC_DATA_WORD(index),
			       &state->spi_tx_buf, AD8460_DATA_BYTE_WORD_LENGTH);
	if (ret)
		return ret;

	*val = le16_to_cpu(state->spi_tx_buf);

	return ret;

Annotation

Implementation Notes