// SPDX-License-Identifier: GPL-2.0-only /* * AD5755, AD5755-1, AD5757, AD5735, AD5737 Digital to analog converters driver * * Copyright 2012 Analog Devices Inc.
*/
/** * struct ad5755_platform_data - AD5755 DAC driver platform data * @ext_dc_dc_compenstation_resistor: Whether an external DC-DC converter * compensation register is used. * @dc_dc_phase: DC-DC converter phase. * @dc_dc_freq: DC-DC converter frequency. * @dc_dc_maxv: DC-DC maximum allowed boost voltage. * @dac: Per DAC instance parameters. * @dac.mode: The mode to be used for the DAC output. * @dac.ext_current_sense_resistor: Whether an external current sense resistor * is used. * @dac.enable_voltage_overrange: Whether to enable 20% voltage output overrange. * @dac.slew.enable: Whether to enable digital slew. * @dac.slew.rate: Slew rate of the digital slew. * @dac.slew.step_size: Slew step size of the digital slew.
**/ struct ad5755_platform_data { bool ext_dc_dc_compenstation_resistor; enum ad5755_dc_dc_phase dc_dc_phase; enum ad5755_dc_dc_freq dc_dc_freq; enum ad5755_dc_dc_maxv dc_dc_maxv;
/** * struct ad5755_chip_info - chip specific information * @channel_template: channel specification * @calib_shift: shift for the calibration data registers * @has_voltage_out: whether the chip has voltage outputs
*/ struct ad5755_chip_info { conststruct iio_chan_spec channel_template; unsignedint calib_shift; bool has_voltage_out;
};
/** * struct ad5755_state - driver instance specific data * @spi: spi device the driver is attached to * @chip_info: chip model specific constants, available modes etc * @pwr_down: bitmask which contains hether a channel is powered down or not * @ctrl: software shadow of the channel ctrl registers * @channels: iio channel spec for the device * @lock: lock to protect the data buffer during SPI ops * @data: spi transfer buffers
*/ struct ad5755_state { struct spi_device *spi; conststruct ad5755_chip_info *chip_info; unsignedint pwr_down; unsignedint ctrl[AD5755_NUM_CHANNELS]; struct iio_chan_spec channels[AD5755_NUM_CHANNELS]; struct mutex lock;
/* * DMA (thus cache coherency maintenance) may require the * transfer buffers to live in their own cache lines.
*/
union {
__be32 d32;
u8 d8[4];
} data[2] __aligned(IIO_DMA_MINALIGN);
};
staticbool ad5755_is_valid_mode(struct ad5755_state *st, enum ad5755_mode mode)
{ switch (mode) { case AD5755_MODE_VOLTAGE_0V_5V: case AD5755_MODE_VOLTAGE_0V_10V: case AD5755_MODE_VOLTAGE_PLUSMINUS_5V: case AD5755_MODE_VOLTAGE_PLUSMINUS_10V: return st->chip_info->has_voltage_out; case AD5755_MODE_CURRENT_4mA_20mA: case AD5755_MODE_CURRENT_0mA_20mA: case AD5755_MODE_CURRENT_0mA_24mA: returntrue; default: returnfalse;
}
}
val = pdata->dc_dc_maxv << AD5755_DC_DC_MAXV;
val |= pdata->dc_dc_freq << AD5755_DC_DC_FREQ_SHIFT;
val |= pdata->dc_dc_phase << AD5755_DC_DC_PHASE_SHIFT; if (pdata->ext_dc_dc_compenstation_resistor)
val |= AD5755_EXT_DC_DC_COMP_RES;
ret = ad5755_write_ctrl(indio_dev, 0, AD5755_CTRL_REG_DC_DC, val); if (ret < 0) return ret;
for (i = 0; i < ARRAY_SIZE(pdata->dac); ++i) {
val = pdata->dac[i].slew.step_size <<
AD5755_SLEW_STEP_SIZE_SHIFT;
val |= pdata->dac[i].slew.rate <<
AD5755_SLEW_RATE_SHIFT; if (pdata->dac[i].slew.enable)
val |= AD5755_SLEW_ENABLE;
ret = ad5755_write_ctrl(indio_dev, i,
AD5755_CTRL_REG_SLEW, val); if (ret < 0) return ret;
}
for (i = 0; i < ARRAY_SIZE(pdata->dac); ++i) { if (!ad5755_is_valid_mode(st, pdata->dac[i].mode)) return -EINVAL;
val = 0; if (!pdata->dac[i].ext_current_sense_resistor)
val |= AD5755_DAC_INT_CURRENT_SENSE_RESISTOR; if (pdata->dac[i].enable_voltage_overrange)
val |= AD5755_DAC_VOLTAGE_OVERRANGE_EN;
val |= pdata->dac[i].mode;
ret = ad5755_update_dac_ctrl(indio_dev, i, val, 0); if (ret < 0) return ret;
}
return 0;
}
staticbool ad5755_is_voltage_mode(enum ad5755_mode mode)
{ switch (mode) { case AD5755_MODE_VOLTAGE_0V_5V: case AD5755_MODE_VOLTAGE_0V_10V: case AD5755_MODE_VOLTAGE_PLUSMINUS_5V: case AD5755_MODE_VOLTAGE_PLUSMINUS_10V: returntrue; default: returnfalse;
}
}
pdata->dc_dc_freq = AD5755_DC_DC_FREQ_410kHZ; if (!device_property_read_u32(dev, "adi,dc-dc-freq-hz", &tmp)) { for (i = 0; i < ARRAY_SIZE(ad5755_dcdc_freq_table); i++) { if (tmp == ad5755_dcdc_freq_table[i][0]) {
pdata->dc_dc_freq = ad5755_dcdc_freq_table[i][1]; break;
}
}
if (i == ARRAY_SIZE(ad5755_dcdc_freq_table))
dev_err(dev, "adi,dc-dc-freq out of range selecting 410kHz\n");
}
pdata->dc_dc_maxv = AD5755_DC_DC_MAXV_23V; if (!device_property_read_u32(dev, "adi,dc-dc-max-microvolt", &tmp)) { for (i = 0; i < ARRAY_SIZE(ad5755_dcdc_maxv_table); i++) { if (tmp == ad5755_dcdc_maxv_table[i][0]) {
pdata->dc_dc_maxv = ad5755_dcdc_maxv_table[i][1]; break;
}
} if (i == ARRAY_SIZE(ad5755_dcdc_maxv_table))
dev_err(dev, "adi,dc-dc-maxv out of range selecting 23V\n");
}
devnr = 0;
device_for_each_child_node_scoped(dev, pp) { if (devnr >= AD5755_NUM_CHANNELS) {
dev_err(dev, "There are too many channels defined in DT\n");
devm_kfree(dev, pdata); return NULL;
}
if (!fwnode_property_read_u32_array(pp, "adi,slew", tmparray, 3)) {
pdata->dac[devnr].slew.enable = tmparray[0];
pdata->dac[devnr].slew.rate = AD5755_SLEW_RATE_64k; for (i = 0; i < ARRAY_SIZE(ad5755_slew_rate_table); i++) { if (tmparray[1] == ad5755_slew_rate_table[i][0]) {
pdata->dac[devnr].slew.rate =
ad5755_slew_rate_table[i][1]; break;
}
} if (i == ARRAY_SIZE(ad5755_slew_rate_table))
dev_err(dev, "channel %d slew rate out of range selecting 64kHz\n",
devnr);
pdata->dac[devnr].slew.step_size = AD5755_SLEW_STEP_SIZE_1; for (i = 0; i < ARRAY_SIZE(ad5755_slew_step_table); i++) { if (tmparray[2] == ad5755_slew_step_table[i][0]) {
pdata->dac[devnr].slew.step_size =
ad5755_slew_step_table[i][1]; break;
}
} if (i == ARRAY_SIZE(ad5755_slew_step_table))
dev_err(dev, "channel %d slew step size out of range selecting 1 LSB\n",
devnr);
} else {
pdata->dac[devnr].slew.enable = false;
pdata->dac[devnr].slew.rate = AD5755_SLEW_RATE_64k;
pdata->dac[devnr].slew.step_size =
AD5755_SLEW_STEP_SIZE_1;
}
devnr++;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.