drivers/iio/dac/ti-dac5571.c

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

File Facts

System
Linux kernel
Corpus path
drivers/iio/dac/ti-dac5571.c
Extension
.c
Size
11493 bytes
Lines
434
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 dac5571_spec {
	u8 num_channels;
	u8 resolution;
};

static const struct dac5571_spec dac5571_spec[] = {
	[single_8bit]  = {.num_channels = 1, .resolution =  8},
	[single_10bit] = {.num_channels = 1, .resolution = 10},
	[single_12bit] = {.num_channels = 1, .resolution = 12},
	[quad_8bit]    = {.num_channels = 4, .resolution =  8},
	[quad_10bit]   = {.num_channels = 4, .resolution = 10},
	[quad_12bit]   = {.num_channels = 4, .resolution = 12},
};

struct dac5571_data {
	struct i2c_client *client;
	struct mutex lock;
	struct regulator *vref;
	u16 val[4];
	bool powerdown[4];
	u8 powerdown_mode[4];
	struct dac5571_spec const *spec;
	int (*dac5571_cmd)(struct dac5571_data *data, int channel, u16 val);
	int (*dac5571_pwrdwn)(struct dac5571_data *data, int channel, u8 pwrdwn);
	u8 buf[3] __aligned(IIO_DMA_MINALIGN);
};

#define DAC5571_POWERDOWN(mode)		((mode) + 1)
#define DAC5571_POWERDOWN_FLAG		BIT(0)
#define DAC5571_CHANNEL_SELECT		1
#define DAC5571_LOADMODE_DIRECT		BIT(4)
#define DAC5571_SINGLE_PWRDWN_BITS	4
#define DAC5571_QUAD_PWRDWN_BITS	6

static int dac5571_cmd_single(struct dac5571_data *data, int channel, u16 val)
{
	unsigned int shift;

	shift = 12 - data->spec->resolution;
	data->buf[1] = val << shift;
	data->buf[0] = val >> (8 - shift);

	if (i2c_master_send(data->client, data->buf, 2) != 2)
		return -EIO;

	return 0;
}

static int dac5571_cmd_quad(struct dac5571_data *data, int channel, u16 val)
{
	unsigned int shift;

	shift = 16 - data->spec->resolution;
	data->buf[2] = val << shift;
	data->buf[1] = (val >> (8 - shift));
	data->buf[0] = (channel << DAC5571_CHANNEL_SELECT) |
		       DAC5571_LOADMODE_DIRECT;

	if (i2c_master_send(data->client, data->buf, 3) != 3)
		return -EIO;

	return 0;
}

static int dac5571_pwrdwn_single(struct dac5571_data *data, int channel, u8 pwrdwn)
{
	data->buf[1] = 0;
	data->buf[0] = pwrdwn << DAC5571_SINGLE_PWRDWN_BITS;

	if (i2c_master_send(data->client, data->buf, 2) != 2)
		return -EIO;

	return 0;
}

static int dac5571_pwrdwn_quad(struct dac5571_data *data, int channel, u8 pwrdwn)
{
	data->buf[2] = 0;
	data->buf[1] = pwrdwn << DAC5571_QUAD_PWRDWN_BITS;
	data->buf[0] = (channel << DAC5571_CHANNEL_SELECT) |
		       DAC5571_LOADMODE_DIRECT | DAC5571_POWERDOWN_FLAG;

	if (i2c_master_send(data->client, data->buf, 3) != 3)
		return -EIO;

	return 0;
}

static const char *const dac5571_powerdown_modes[] = {
	"1kohm_to_gnd", "100kohm_to_gnd", "three_state",

Annotation

Implementation Notes