Skip to content

Commit 993a448

Browse files
dumitruceclanmhennerich
authored andcommitted
iio: frequency: m2k-dac: Add support for raw vaules
In order to fix a bug regarding spikes when using a series of cyclical buffers the following changes were made: - Maintain the DAC output MUX on DMA selection permanently - Add out_voltage_raw attribute: the value determines the output of the DAC when raw_enable flag is enabled and the iio_buffer is disabled. Separate between channel A and B. - Add raw_enable attribute: enabling this attribute will cause the dac output to be switched to RAW from DMA after disabling the iio_buffer Separate between channel A and B. Disabled by default. Signed-off-by: Ceclan Dumitru <dumitru.ceclan@analog.com>
1 parent 3d3303b commit 993a448

File tree

1 file changed

+120
-21
lines changed

1 file changed

+120
-21
lines changed

drivers/iio/frequency/m2k-dac.c

Lines changed: 120 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,29 @@
3030
#define M2K_DAC_REG_CORRECTION_ENABLE 0x54
3131
#define M2K_DAC_REG_CORRECTION_COEFFICIENT(x) (0x58 + (x) * 4)
3232
#define M2K_DAC_REG_INSTRUMENT_TRIGGER 0x60
33+
#define M2K_DAC_REG_RAW_PATTERN 0x64
3334

3435
#define M2K_DAC_DMA_SYNC_BIT BIT(0)
3536
#define M2K_DAC_SYNC_START_BIT BIT(1)
37+
#define M2K_DAC_FLAGS_DMA_FLUSH_BIT BIT(3)
38+
#define M2K_DAC_FLAGS_RAW_ENABLE_CHAN_A_BIT BIT(4)
39+
#define M2K_DAC_FLAGS_RAW_ENABLE_CHAN_B_BIT BIT(5)
40+
#define M2K_DAC_FLAGS_RAW_IDLE_BIT(chan_num) (!(chan_num) ? M2K_DAC_FLAGS_RAW_ENABLE_CHAN_A_BIT :\
41+
M2K_DAC_FLAGS_RAW_ENABLE_CHAN_B_BIT)
42+
43+
#define M2K_DAC_FLAGS_DMA_FLUSH(x) FIELD_PREP(M2K_DAC_FLAGS_DMA_FLUSH_BIT, x)
44+
#define M2K_DAC_FLAGS_RAW_IDLE(x, chan_num) (!(chan_num) ? FIELD_PREP(M2K_DAC_FLAGS_RAW_ENABLE_CHAN_A_BIT, x) :\
45+
FIELD_PREP(M2K_DAC_FLAGS_RAW_ENABLE_CHAN_B_BIT, x))
3646

3747
#define M2K_DAC_TRIGGER_CONDITION_MASK(x) (0x155 << x)
3848
#define M2K_DAC_TRIGGER_SOURCE_MASK GENMASK(19, 16)
3949
#define M2K_DAC_TRIGGER_EXT_SOURCE GENMASK(17, 16)
50+
#define M2K_DAC_REG_RAW_PATTERN_CHAN_A_MASK GENMASK(15, 0)
51+
#define M2K_DAC_REG_RAW_PATTERN_CHAN_B_MASK GENMASK(31, 16)
52+
#define M2K_DAC_RAW_PATTERN_MASK(chan_num) (!(chan_num) ? M2K_DAC_REG_RAW_PATTERN_CHAN_A_MASK :\
53+
M2K_DAC_REG_RAW_PATTERN_CHAN_B_MASK)
54+
#define M2K_DAC_RAW_PATTERN(x, chan_num) (!(chan_num) ? FIELD_PREP(M2K_DAC_REG_RAW_PATTERN_CHAN_A_MASK, x) :\
55+
FIELD_PREP(M2K_DAC_REG_RAW_PATTERN_CHAN_B_MASK, x))
4056

4157
struct m2k_dac {
4258
void __iomem *regs;
@@ -52,6 +68,7 @@ struct m2k_dac {
5268
struct m2k_dac_ch {
5369
struct m2k_dac *dac;
5470
unsigned int num;
71+
unsigned char raw_idle_enable;
5572
};
5673

5774
static unsigned int cf_axi_dds_to_signed_mag_fmt(int val, int val2)
@@ -122,6 +139,23 @@ static int cf_axi_dds_signed_mag_fmt_to_iio(unsigned int val, int *r_val,
122139
return IIO_VAL_INT_PLUS_MICRO;
123140
}
124141

142+
static int m2k_dac_reg_update(struct iio_dev *indio_dev, unsigned int reg,
143+
unsigned int writeval, const unsigned int mask)
144+
{
145+
struct m2k_dac_ch *ch = iio_priv(indio_dev);
146+
struct m2k_dac *m2k_dac = ch->dac;
147+
unsigned int regval;
148+
149+
reg &= 0xffff;
150+
151+
regval = ioread32(m2k_dac->regs + reg);
152+
regval &= ~mask;
153+
writeval &= mask;
154+
iowrite32(writeval | regval, m2k_dac->regs + reg);
155+
156+
return 0;
157+
}
158+
125159
static int m2k_dac_ch_read_raw(struct iio_dev *indio_dev,
126160
struct iio_chan_spec const *chan, int *val, int *val2, long info)
127161
{
@@ -133,6 +167,15 @@ static int m2k_dac_ch_read_raw(struct iio_dev *indio_dev,
133167
mutex_lock(&m2k_dac->lock);
134168

135169
switch (info) {
170+
case IIO_CHAN_INFO_RAW:
171+
if (ch->num == 0)
172+
*val = FIELD_GET(M2K_DAC_REG_RAW_PATTERN_CHAN_A_MASK,
173+
ioread32(m2k_dac->regs + M2K_DAC_REG_RAW_PATTERN));
174+
else
175+
*val = FIELD_GET(M2K_DAC_REG_RAW_PATTERN_CHAN_B_MASK,
176+
ioread32(m2k_dac->regs + M2K_DAC_REG_RAW_PATTERN));
177+
ret = IIO_VAL_INT;
178+
break;
136179
case IIO_CHAN_INFO_SAMP_FREQ:
137180
*val = clk_get_rate(m2k_dac->clk);
138181
reg = ioread32(m2k_dac->regs + M2K_DAC_REG_FILTER(ch->num));
@@ -188,6 +231,11 @@ static int m2k_dac_ch_write_raw(struct iio_dev *indio_dev,
188231
mutex_lock(&m2k_dac->lock);
189232

190233
switch (info) {
234+
case IIO_CHAN_INFO_RAW:
235+
m2k_dac_reg_update(indio_dev, M2K_DAC_REG_RAW_PATTERN,
236+
M2K_DAC_RAW_PATTERN(val, ch->num),
237+
M2K_DAC_RAW_PATTERN_MASK(ch->num));
238+
break;
191239
case IIO_CHAN_INFO_SAMP_FREQ:
192240
rate = clk_get_rate(m2k_dac->clk);
193241
if (val >= rate)
@@ -249,23 +297,6 @@ static int m2k_dac_reg_access(struct iio_dev *indio_dev, unsigned int reg,
249297
return 0;
250298
}
251299

252-
static int m2k_dac_reg_update(struct iio_dev *indio_dev, unsigned int reg,
253-
unsigned int writeval, const unsigned int mask)
254-
{
255-
struct m2k_dac_ch *ch = iio_priv(indio_dev);
256-
struct m2k_dac *m2k_dac = ch->dac;
257-
unsigned int regval;
258-
259-
reg &= 0xffff;
260-
261-
regval = ioread32(m2k_dac->regs + reg);
262-
regval &= ~mask;
263-
writeval &= mask;
264-
iowrite32(writeval | regval, m2k_dac->regs + reg);
265-
266-
return 0;
267-
}
268-
269300
static ssize_t m2k_dac_read_dma_sync(struct device *dev,
270301
struct device_attribute *attr, char *buf)
271302
{
@@ -477,23 +508,67 @@ static const struct iio_enum m2k_dac_trig_src_enum = {
477508
.get = m2k_dac_get_trig_src,
478509
};
479510

511+
static int m2k_dac_get_raw_enable(struct iio_dev *indio_dev,
512+
const struct iio_chan_spec *chan)
513+
{
514+
struct m2k_dac_ch *ch = iio_priv(indio_dev);
515+
516+
return ch->raw_idle_enable;
517+
}
518+
519+
static int m2k_dac_set_raw_enable(struct iio_dev *indio_dev,
520+
const struct iio_chan_spec *chan, unsigned int val)
521+
{
522+
struct m2k_dac_ch *ch = iio_priv(indio_dev);
523+
int ret;
524+
525+
ch->raw_idle_enable = val;
526+
527+
ret = iio_device_claim_direct_mode(indio_dev);
528+
if (ret)
529+
return 0;
530+
531+
m2k_dac_reg_update(indio_dev, M2K_DAC_REG_FLAGS,
532+
M2K_DAC_FLAGS_RAW_IDLE(val, ch->num),
533+
M2K_DAC_FLAGS_RAW_IDLE_BIT(ch->num));
534+
535+
iio_device_release_direct_mode(indio_dev);
536+
537+
return 0;
538+
}
539+
540+
static const char * const m2k_dac_raw_enable_items[] = {
541+
"disabled",
542+
"enabled",
543+
};
544+
545+
static const struct iio_enum m2k_dac_raw_enable_enum = {
546+
.items = m2k_dac_raw_enable_items,
547+
.num_items = ARRAY_SIZE(m2k_dac_raw_enable_items),
548+
.set = m2k_dac_set_raw_enable,
549+
.get = m2k_dac_get_raw_enable,
550+
};
551+
480552
static const struct iio_chan_spec_ext_info m2k_dac_ext_info[] = {
481553
IIO_ENUM_AVAILABLE_SHARED("sampling_frequency", IIO_SHARED_BY_ALL,
482554
&m2k_dac_samp_freq_available_enum),
483555
IIO_ENUM("trigger_src", IIO_SHARED_BY_ALL, &m2k_dac_trig_src_enum),
484556
IIO_ENUM_AVAILABLE_SHARED("trigger_src", IIO_SHARED_BY_ALL,
485557
&m2k_dac_trig_src_enum),
486558
IIO_ENUM("trigger_condition", IIO_SHARED_BY_ALL,
487-
&m2k_dac_trig_condition_enum),
559+
&m2k_dac_trig_condition_enum),
488560
IIO_ENUM_AVAILABLE_SHARED("trigger_condition", IIO_SHARED_BY_ALL,
489-
&m2k_dac_trig_condition_enum),
561+
&m2k_dac_trig_condition_enum),
562+
IIO_ENUM_AVAILABLE_SHARED("raw_enable", IIO_SEPARATE, &m2k_dac_raw_enable_enum),
563+
IIO_ENUM("raw_enable", IIO_SEPARATE, &m2k_dac_raw_enable_enum),
490564
{ },
491565
};
492566

493567
static const struct iio_chan_spec m2k_dac_channel_info = {
494568
.type = IIO_VOLTAGE,
495569
.indexed = 1,
496570
.channel = 0,
571+
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
497572
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) |
498573
BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) |
499574
BIT(IIO_CHAN_INFO_CALIBSCALE),
@@ -518,8 +593,28 @@ static int m2k_dac_buffer_preenable(struct iio_dev *indio_dev)
518593
m2k_dac_reg_update(indio_dev, M2K_DAC_REG_FLAGS, 0,
519594
M2K_DAC_SYNC_START_BIT);
520595
}
596+
m2k_dac_reg_update(indio_dev, M2K_DAC_REG_FLAGS,
597+
M2K_DAC_FLAGS_RAW_IDLE(0, ch->num), M2K_DAC_FLAGS_RAW_IDLE_BIT(ch->num));
598+
return 0;
599+
}
600+
601+
/*
602+
* The raw flag must be enabled prior to the destruction of the iio_buffer due
603+
* to the specifics of the HDL DMA implementation. If the flag is enabled
604+
* post-destruction, it could result in improper data flushing by the DMA.
605+
*
606+
* Consequently, upon the next buffer enablement, a spike will occur, displaying
607+
* the last sample from the previous buffer.
608+
*/
609+
static int m2k_dac_buffer_predisable(struct iio_dev *indio_dev)
610+
{
611+
struct m2k_dac_ch *ch = iio_priv(indio_dev);
612+
613+
if (ch->raw_idle_enable)
614+
m2k_dac_reg_update(indio_dev, M2K_DAC_REG_FLAGS,
615+
M2K_DAC_FLAGS_RAW_IDLE(1, ch->num),
616+
M2K_DAC_FLAGS_RAW_IDLE_BIT(ch->num));
521617

522-
cf_axi_dds_datasel(m2k_dac->dds, ch->num, DATA_SEL_DMA);
523618
return 0;
524619
}
525620

@@ -534,7 +629,6 @@ static int m2k_dac_buffer_postdisable(struct iio_dev *indio_dev)
534629
M2K_DAC_SYNC_START_BIT);
535630
}
536631

537-
cf_axi_dds_datasel(m2k_dac->dds, ch->num, DATA_SEL_DDS);
538632
return 0;
539633
}
540634

@@ -546,6 +640,7 @@ static int m2k_dac_buffer_submit_block(struct iio_dma_buffer_queue *queue,
546640

547641
static const struct iio_buffer_setup_ops m2k_dac_buffer_setup_ops = {
548642
.preenable = m2k_dac_buffer_preenable,
643+
.predisable = m2k_dac_buffer_predisable,
549644
.postdisable = m2k_dac_buffer_postdisable,
550645
};
551646

@@ -584,6 +679,7 @@ static int m2k_dac_alloc_channel(struct platform_device *pdev,
584679
ch = iio_priv(indio_dev);
585680
ch->num = num;
586681
ch->dac = m2k_dac;
682+
ch->raw_idle_enable = 0;
587683

588684
indio_dev->dev.parent = &pdev->dev;
589685
indio_dev->name = m2k_dac_ch_dev_names[num];
@@ -703,6 +799,9 @@ static int m2k_dac_probe(struct platform_device *pdev)
703799

704800
platform_set_drvdata(pdev, m2k_dac);
705801

802+
cf_axi_dds_datasel(m2k_dac->dds, 0, DATA_SEL_DMA);
803+
cf_axi_dds_datasel(m2k_dac->dds, 1, DATA_SEL_DMA);
804+
706805
ret = devm_iio_device_register(&pdev->dev, m2k_dac->ch_indio_dev[0]);
707806
if (ret)
708807
return ret;

0 commit comments

Comments
 (0)