drivers/iio/dac/mcp4728.c
Source file repositories/reference/linux-study-clean/drivers/iio/dac/mcp4728.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/iio/dac/mcp4728.c- Extension
.c- Size
- 15244 bytes
- Lines
- 600
- 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.
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/delay.hlinux/err.hlinux/i2c.hlinux/iio/iio.hlinux/iio/sysfs.hlinux/module.hlinux/mod_devicetable.hlinux/property.hlinux/regulator/consumer.h
Detected Declarations
struct mcp4728_channel_datastruct mcp4728_dataenum vref_modeenum gain_modeenum iio_powerdown_modeenum mcp4728_scalefunction mcp4728_store_eepromfunction mcp4728_program_channel_cfgfunction mcp4728_get_powerdown_modefunction mcp4728_set_powerdown_modefunction mcp4728_read_powerdownfunction mcp4728_write_powerdownfunction mcp4728_get_scale_availfunction mcp4728_get_scalefunction mcp4728_find_matching_scalefunction mcp4728_set_scalefunction mcp4728_read_rawfunction mcp4728_write_rawfunction mcp4728_init_scale_availfunction mcp4728_init_scales_availfunction mcp4728_read_availfunction mcp4728_suspendfunction mcp4728_resumefunction mcp4728_init_channels_datafunction mcp4728_probe
Annotated Snippet
struct mcp4728_channel_data {
enum vref_mode ref_mode;
enum iio_powerdown_mode pd_mode;
enum gain_mode g_mode;
u16 dac_value;
};
/* MCP4728 Full Scale Ranges
* the device available ranges are
* - VREF = VDD FSR = from 0.0V to VDD
* - VREF = Internal Gain = 1 FSR = from 0.0V to VREF
* - VREF = Internal Gain = 2 FSR = from 0.0V to 2*VREF
*/
enum mcp4728_scale {
MCP4728_SCALE_VDD,
MCP4728_SCALE_VINT_NO_GAIN,
MCP4728_SCALE_VINT_GAIN_X2,
MCP4728_N_SCALES
};
struct mcp4728_data {
struct i2c_client *client;
bool powerdown;
int scales_avail[MCP4728_N_SCALES * 2];
struct mcp4728_channel_data chdata[MCP4728_N_CHANNELS];
};
#define MCP4728_CHAN(chan) { \
.type = IIO_VOLTAGE, \
.output = 1, \
.indexed = 1, \
.channel = chan, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE), \
.info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE), \
.ext_info = mcp4728_ext_info, \
}
static int mcp4728_suspend(struct device *dev);
static int mcp4728_resume(struct device *dev);
static ssize_t mcp4728_store_eeprom(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct mcp4728_data *data = iio_priv(indio_dev);
u8 outbuf[MCP4728_WRITE_EEPROM_LEN];
int tries = 20;
u8 inbuf[3];
bool state;
int ret;
unsigned int i;
ret = kstrtobool(buf, &state);
if (ret < 0)
return ret;
if (!state)
return 0;
outbuf[0] = FIELD_PREP(MCP4728_CMD_MASK, MCP4728_SW_CMD);
for (i = 0; i < MCP4728_N_CHANNELS; i++) {
struct mcp4728_channel_data *ch = &data->chdata[i];
int offset = 1 + i * 2;
outbuf[offset] = FIELD_PREP(MCP4728_VREF_MASK, ch->ref_mode);
if (data->powerdown) {
u8 mcp4728_pd_mode = ch->pd_mode + 1;
outbuf[offset] |= FIELD_PREP(MCP4728_PDMODE_MASK,
mcp4728_pd_mode);
}
outbuf[offset] |= FIELD_PREP(MCP4728_GAIN_MASK, ch->g_mode);
outbuf[offset] |=
FIELD_PREP(MCP4728_DAC_H_MASK, ch->dac_value >> 8);
outbuf[offset + 1] =
FIELD_PREP(MCP4728_DAC_L_MASK, ch->dac_value);
}
ret = i2c_master_send(data->client, outbuf, MCP4728_WRITE_EEPROM_LEN);
if (ret < 0)
return ret;
else if (ret != MCP4728_WRITE_EEPROM_LEN)
return -EIO;
/* wait RDY signal for write complete, takes up to 50ms */
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/delay.h`, `linux/err.h`, `linux/i2c.h`, `linux/iio/iio.h`, `linux/iio/sysfs.h`, `linux/module.h`, `linux/mod_devicetable.h`.
- Detected declarations: `struct mcp4728_channel_data`, `struct mcp4728_data`, `enum vref_mode`, `enum gain_mode`, `enum iio_powerdown_mode`, `enum mcp4728_scale`, `function mcp4728_store_eeprom`, `function mcp4728_program_channel_cfg`, `function mcp4728_get_powerdown_mode`, `function mcp4728_set_powerdown_mode`.
- Atlas domain: Driver Families / drivers/iio.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.