Skip to content

Commit

Permalink
iio: frequency: cf_axi_dds: Bypass PL DDR FIFO for non-cyclic transfers
Browse files Browse the repository at this point in the history
In case the user requests streaming transfers the FIFO must be disabled.

Signed-off-by: Michael Hennerich <[email protected]>
  • Loading branch information
mhennerich authored and commodo committed Aug 20, 2018
1 parent 422f871 commit 6bf9422
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 16 deletions.
40 changes: 27 additions & 13 deletions drivers/iio/frequency/cf_axi_dds.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,26 @@ static int cf_axi_dds_twos_fmt_to_iio(s16 val, int *r_val, int *r_val2)
}
#endif

int cf_axi_dds_pl_ddr_fifo_ctrl(struct cf_axi_dds_state *st, bool enable)
{
enum fifo_ctrl mode;
int ret;

if (IS_ERR(st->plddrbypass_gpio))
return -ENODEV;

mode = (enable ? FIFO_ENABLE : FIFO_DISABLE);

if (st->gpio_dma_fifo_ctrl == mode)
return 0;

ret = gpiod_direction_output(st->plddrbypass_gpio, !enable);
if (ret == 0)
st->gpio_dma_fifo_ctrl = mode;

return ret;
}

static int cf_axi_get_parent_sampling_frequency(struct cf_axi_dds_state *st, unsigned long *freq)
{
struct cf_axi_converter *conv;
Expand Down Expand Up @@ -1140,9 +1160,9 @@ static ssize_t cf_axi_dds_debugfs_write(struct file *file,
if (ret < 0)
return -EINVAL;

if (!IS_ERR(st->plddrbypass_gpio)) {
gpiod_direction_output(st->plddrbypass_gpio, !st->pl_dma_fifo_en);
}
ret = cf_axi_dds_pl_ddr_fifo_ctrl(st, st->pl_dma_fifo_en);
if (ret)
return ret;

return count;
}
Expand Down Expand Up @@ -1525,16 +1545,10 @@ static int cf_axi_dds_probe(struct platform_device *pdev)
(unsigned long long)res->start, st->regs, st->chip_info->name);

st->plddrbypass_gpio = devm_gpiod_get(&pdev->dev, "plddrbypass", GPIOD_ASIS);
if (!IS_ERR(st->plddrbypass_gpio)) {

if (iio_get_debugfs_dentry(indio_dev))
debugfs_create_file("pl_ddr_fifo_enable", 0644,
iio_get_debugfs_dentry(indio_dev),
indio_dev, &cf_axi_dds_debugfs_fops);

ret = gpiod_direction_output(st->plddrbypass_gpio, !st->pl_dma_fifo_en);
}

if (!IS_ERR(st->plddrbypass_gpio) && iio_get_debugfs_dentry(indio_dev))
debugfs_create_file("pl_ddr_fifo_enable", 0644,
iio_get_debugfs_dentry(indio_dev),
indio_dev, &cf_axi_dds_debugfs_fops);

platform_set_drvdata(pdev, indio_dev);

Expand Down
8 changes: 8 additions & 0 deletions drivers/iio/frequency/cf_axi_dds.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,12 @@ enum {
ID_AD9162_COMPLEX,
};

enum fifo_ctrl {
FIFO_UNSET,
FIFO_DISABLE,
FIFO_ENABLE,
};

struct cf_axi_dds_chip_info {
const char *name;
unsigned int num_channels;
Expand All @@ -213,6 +219,7 @@ struct cf_axi_dds_state {
bool dp_disable;
bool enable;
bool pl_dma_fifo_en;
enum fifo_ctrl gpio_dma_fifo_ctrl;

struct iio_info iio_info;
size_t regs_size;
Expand Down Expand Up @@ -292,6 +299,7 @@ int cf_axi_dds_datasel(struct cf_axi_dds_state *st,
int channel, enum dds_data_select sel);
void cf_axi_dds_stop(struct cf_axi_dds_state *st);
void cf_axi_dds_start_sync(struct cf_axi_dds_state *st, bool force_on);
int cf_axi_dds_pl_ddr_fifo_ctrl(struct cf_axi_dds_state *st, bool enable);

/*
* IO accessors
Expand Down
13 changes: 10 additions & 3 deletions drivers/iio/frequency/cf_axi_dds_buffer_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,21 @@ static int dds_buffer_submit_block(struct iio_dma_buffer_queue *queue,
{
struct cf_axi_dds_state *st = iio_priv(queue->driver_data);

if (st->pl_dma_fifo_en && (block->block.flags & IIO_BUFFER_BLOCK_FLAG_CYCLIC)) {
block->block.flags &= ~IIO_BUFFER_BLOCK_FLAG_CYCLIC;
if (block->block.bytes_used) {
bool enable_fifo = false;

if (st->pl_dma_fifo_en &&
(block->block.flags & IIO_BUFFER_BLOCK_FLAG_CYCLIC)) {
block->block.flags &= ~IIO_BUFFER_BLOCK_FLAG_CYCLIC;
enable_fifo = true;
}

cf_axi_dds_pl_ddr_fifo_ctrl(st, enable_fifo);
}

return iio_dmaengine_buffer_submit_block(queue, block, DMA_TO_DEVICE);
}


static int dds_buffer_state_set(struct iio_dev *indio_dev, bool state)
{
struct cf_axi_dds_state *st = iio_priv(indio_dev);
Expand Down

0 comments on commit 6bf9422

Please sign in to comment.