10000 iio: frequency: cf_axi_dds: Option to retrieve channels from TPL HDL-… · analogdevicesinc/linux@a16a077 · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Commit a16a077

Browse files
mhennerichcommodo
authored andcommitted
iio: frequency: cf_axi_dds: Option to retrieve channels from TPL HDL-Core
This patch increases to max number of supported buffer channels to 64. In addition we can optionally get the link configuration parameter (synthesis parameter) for the transport layer core (TPL), and generate the channel list automatically. Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
1 parent 306f628 commit a16a077

File tree

2 files changed

+161
-4
lines changed

2 files changed

+161
-4
lines changed

drivers/iio/frequency/cf_axi_dds.c

Lines changed: 128 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,41 @@
4040

4141
static const unsigned int interpolation_factors_available[] = {1, 8};
4242

43+
static const char * const dds_extend_names[] = {
44+
"TX1_I_F1", "TX1_I_F2", "TX1_Q_F1", "TX1_Q_F2",
45+
"TX2_I_F1", "TX2_I_F2", "TX2_Q_F1", "TX2_Q_F2",
46+
"TX3_I_F1", "TX3_I_F2", "TX3_Q_F1", "TX3_Q_F2",
47+
"TX4_I_F1", "TX4_I_F2", "TX4_Q_F1", "TX4_Q_F2",
48+
"TX5_I_F1", "TX5_I_F2", "TX5_Q_F1", "TX5_Q_F2",
49+
"TX6_I_F1", "TX6_I_F2", "TX6_Q_F1", "TX6_Q_F2",
50+
"TX7_I_F1", "TX7_I_F2", "TX7_Q_F1", "TX7_Q_F2",
51+
"TX8_I_F1", "TX8_I_F2", "TX8_Q_F1", "TX8_Q_F2",
52+
"TX9_I_F1", "TX9_I_F2", "TX9_Q_F1", "TX9_Q_F2",
53+
"TX10_I_F1", "TX10_I_F2", "TX10_Q_F1", "TX10_Q_F2",
54+
"TX11_I_F1", "TX11_I_F2", "TX11_Q_F1", "TX11_Q_F2",
55+
"TX12_I_F1", "TX12_I_F2", "TX12_Q_F1", "TX12_Q_F2",
56+
"TX13_I_F1", "TX13_I_F2", "TX13_Q_F1", "TX13_Q_F2",
57+
"TX14_I_F1", "TX14_I_F2", "TX14_Q_F1", "TX14_Q_F2",
58+
"TX15_I_F1", "TX15_I_F2", "TX15_Q_F1", "TX15_Q_F2",
59+
"TX16_I_F1", "TX16_I_F2", "TX16_Q_F1", "TX16_Q_F2",
60+
"TX17_I_F1", "TX17_I_F2", "TX17_Q_F1", "TX17_Q_F2",
61+
"TX18_I_F1", "TX18_I_F2", "TX18_Q_F1", "TX18_Q_F2",
62+
"TX19_I_F1", "TX19_I_F2", "TX19_Q_F1", "TX19_Q_F2",
63+
"TX20_I_F1", "TX20_I_F2", "TX20_Q_F1", "TX20_Q_F2",
64+
"TX21_I_F1", "TX21_I_F2", "TX21_Q_F1", "TX21_Q_F2",
65+
"TX22_I_F1", "TX22_I_F2", "TX22_Q_F1", "TX22_Q_F2",
66+
"TX23_I_F1", "TX23_I_F2", "TX23_Q_F1", "TX23_Q_F2",
67+
"TX24_I_F1", "TX24_I_F2", "TX24_Q_F1", "TX24_Q_F2",
68+
"TX25_I_F1", "TX25_I_F2", "TX25_Q_F1", "TX25_Q_F2",
69+
"TX26_I_F1", "TX26_I_F2", "TX26_Q_F1", "TX26_Q_F2",
70+
"TX27_I_F1", "TX27_I_F2", "TX27_Q_F1", "TX27_Q_F2",
71+
"TX28_I_F1", "TX28_I_F2", "TX28_Q_F1", "TX28_Q_F2",
72+
"TX29_I_F1", "TX29_I_F2", "TX29_Q_F1", "TX29_Q_F2",
73+
"TX30_I_F1", "TX30_I_F2", "TX30_Q_F1", "TX30_Q_F2",
74+
"TX31_I_F1", "TX31_I_F2", "TX31_Q_F1", "TX31_Q_F2",
75+
"TX32_I_F1", "TX32_I_F2", "TX32_Q_F1", "TX32_Q_F2",
76+
};
77+
4378
struct cf_axi_dds_state {
4479
struct device *dev_spi;
4580
struct clk *clk;
@@ -60,11 +95,12 @@ struct cf_axi_dds_state {
6095
void __iomem *master_regs;
6196
u64 dac_clk;
6297
unsigned int ddr_dds_interp_en;
63-
unsigned int cached_freq[16];
98+
unsigned int cached_freq[AXIDDS_MAX_NUM_DDS_CHAN];
6499
unsigned int version;
65100
unsigned int have_slave_channels;
66101
unsigned int interpolation_factor;
67102
struct notifier_block clk_nb;
103+
struct cf_axi_dds_chip_info chip_info_generated;
68104
};
69105

70106
bool cf_axi_dds_dma_fifo_en(struct cf_axi_dds_state *st)
@@ -1388,13 +1424,91 @@ static void dds_converter_put(struct device *conv_dev)
13881424
put_device(conv_dev);
13891425
}
13901426

1427+
static int cf_axi_dds_setup_chip_info_tbl(struct cf_axi_dds_state *st,
1428+
const char *name, bool complex)
1429+
{
1430+
u32 i, c, reg, m, n, np;
1431+
1432+
reg = dds_read(st, ADI_REG_TPL_DESCRIPTOR_1);
1433+
m = ADI_TO_JESD_M(reg);
1434+
1435+
if (m == 0 || m > ARRAY_SIZE(st->chip_info_generated.channel))
1436+
return -EINVAL;
1437+
1438+
reg = dds_read(st, ADI_REG_TPL_DESCRIPTOR_2);
1439+
n = ADI_TO_JESD_N(reg);
1440+
np = ADI_TO_JESD_NP(reg);
1441+
1442+
reg = dds_read(st, ADI_REG_CONFIG);
1443+
1444+
for (c = 0, i = 0; i < m; i++, c++) {
1445+
st->chip_info_generated.channel[c].type = IIO_VOLTAGE;
1446+
st->chip_info_generated.channel[c].output = 1;
1447+
st->chip_info_generated.channel[c].indexed = 1;
1448+
st->chip_info_generated.channel[c].modified = complex ? 1 : 0;
1449+
st->chip_info_generated.channel[c].channel =
1450+
complex ? i / 2 : i;
1451+
st->chip_info_generated.channel[c].channel2 =
1452+
(i & 1) ? IIO_MOD_Q : IIO_MOD_I;
1453+
st->chip_info_generated.channel[c].scan_index = i;
1454+
st->chip_info_generated.channel[c].info_mask_shared_by_type =
1455+
BIT(IIO_CHAN_INFO_SAMP_FREQ);
1456+
1457+
if (!(reg & ADI_IQCORRECTION_DISABLE))
1458+
st->chip_info_generated.channel[c].info_mask_separate =
1459+
BIT(IIO_CHAN_INFO_CALIBSCALE) |
1460+
BIT(IIO_CHAN_INFO_CALIBPHASE);
1461+
1462+
st->chip_info_generated.channel[c].scan_type.realbits = n;
1463+
st->chip_info_generated.channel[c].scan_type.storagebits = np;
1464+
st->chip_info_generated.channel[c].scan_type.sign = 's';
1465+
}
1466+
1467+
if (!(reg & ADI_DDS_DISABLE)) {
1468+
for (i = 0; i < 2 * m; i++, c++) {
1469+
if (c > ARRAY_SIZE(st->chip_info_generated.channel))
1470+
return -EINVAL;
1471+
st->chip_info_generated.channel[c].type =
1472+
IIO_ALTVOLTAGE;
1473+
st->chip_info_generated.channel[c].output = 1;
1474+
st->chip_info_generated.channel[c].indexed = 1;
1475+
st->chip_info_generated.channel[c].channel = i;
1476+
st->chip_info_generated.channel[c].scan_index = -1;
1477+
st->chip_info_generated.channel
1478+
[c].info_mask_shared_by_type =
1479+
BIT(IIO_CHAN_INFO_SAMP_FREQ);
1480+
st->chip_info_generated.channel[c].info_mask_separate =
1481+
BIT(IIO_CHAN_INFO_RAW) |
1482+
BIT(IIO_CHAN_INFO_SCALE) |
1483+
BIT(IIO_CHAN_INFO_PHASE) |
1484+
BIT(IIO_CHAN_INFO_FREQUENCY);
1485+
1486+
st->chip_info_generated.channel[c].ext_info =
1487+
cf_axi_dds_ext_info;
1488+
if (i < ARRAY_SIZE(dds_extend_names))
1489+
st->chip_info_generated.channel[
1490+
c].extend_name = dds_extend_names[i];
1491+
}
1492+
}
1493+
1494+
st->chip_info_generated.num_channels = c;
1495+
st->chip_info_generated.num_dp_disable_channels = m;
1496+
st->chip_info_generated.num_dds_channels = i;
1497+
st->chip_info_generated.num_buf_channels = m;
1498+
st->chip_info_generated.name = name;
1499+
1500+
return 0;
1501+
}
1502+
13911503
struct axidds_core_info {
13921504
unsigned int version;
13931505
bool standalone;
13941506
bool rate_format_skip_en;
1507+
bool complex_modified;
13951508
struct cf_axi_dds_chip_info *chip_info;
13961509
unsigned int data_format;
13971510
unsigned int rate;
1511+
const char *name;
13981512
};
13991513

14001514
static const struct axidds_core_info ad9122_6_00_a_info = {
@@ -1558,7 +1672,19 @@ static int cf_axi_dds_probe(struct platform_device *pdev)
15581672
st->clk_nb.notifier_call = cf_axi_dds_rate_change;
15591673
clk_notifier_register(st->clk, &st->clk_nb);
15601674

1561-
st->chip_info = info->chip_info;
1675+
if (info->chip_info) {
1676+
st->chip_info = info->chip_info;
1677+
} else {
1678+
ret = cf_axi_dds_setup_chip_info_tbl(st, info->name,
1679+
info->complex_modified);
1680+
if (ret) {
1681+
dev_err(&pdev->dev,
1682+
"Invalid number of converters identified");
1683+
goto err_iio_device_free;
1684+
}
1685+
1686+
st->chip_info = &st->chip_info_generated;
1687+
}
15621688
} else {
15631689
st->dev_spi = dds_converter_find(&pdev->dev);
15641690
if (IS_ERR(st->dev_spi)) {
@@ -1712,7 +1838,6 @@ static int cf_axi_dds_probe(struct platform_device *pdev)
17121838
if (IS_ERR(st->interpolation_gpio))
17131839
dev_err(&pdev->dev, "interpolation gpio error\n");
17141840
}
1715-
17161841
}
17171842

17181843
st->enable = true;

drivers/iio/frequency/cf_axi_dds.h

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,18 @@
1313
#include <linux/clk/clkscale.h>
1414
#include <linux/fpga/adi-axi-common.h>
1515

16+
#define ADI_REG_CONFIG 0x000C
17+
#define ADI_IQCORRECTION_DISABLE (1 << 0)
18+
#define ADI_DCFILTER_DISABLE (1 << 1)
19+
#define ADI_DATAFORMAT_DISABLE (1 << 2)
20+
#define ADI_USERPORTS_DISABLE (1 << 3)
21+
#define ADI_MODE_1R1T (1 << 4)
22+
#define ADI_DELAY_CONTROL_DISABLE (1 << 5)
23+
#define ADI_DDS_DISABLE (1 << 6)
24+
#define ADI_CMOS_OR_LVDS_N (1 << 7)
25+
#define ADI_PPS_RECEIVER_ENABLE (1 << 8)
26+
#define ADI_SCALECORRECTION_ONLY (1 << 9)
27+
1628
/* DAC COMMON */
1729

1830
#define ADI_REG_RSTN 0x0040
@@ -94,6 +106,21 @@ enum dds_data_select {
94106
#define ADI_REG_DAC_DP_DISABLE 0x00C0
95107
#define ADI_DAC_DP_DISABLE (1 << 0)
96108

109+
/* JESD TPL */
110+
111+
#define ADI_REG_TPL_CNTRL 0x0200
112+
#define ADI_REG_TPL_STATUS 0x0204
113+
#define ADI_REG_TPL_DESCRIPTOR_1 0x0240
114+
#define ADI_REG_TPL_DESCRIPTOR_2 0x0244
115+
116+
#define ADI_TO_JESD_M(x) (((x) >> 0) & 0xFF)
117+
#define ADI_TO_JESD_L(x) (((x) >> 8) & 0xFF)
118+
#define ADI_TO_JESD_S(x) (((x) >> 16) & 0xFF)
119+
#define ADI_TO_JESD_F(x) (((x) >> 24) & 0xFF)
120+
121+
#define ADI_TO_JESD_N(x) (((x) >> 0) & 0xFF)
122+
#define ADI_TO_JESD_NP(x) (((x) >> 8) & 0xFF)
123+
97124
/* DAC CHANNEL */
98125

99126
#define ADI_REG_CHAN_CNTRL_1_IIOCHAN(x) (0x0400 + ((x) >> 1) * 0x40 + ((x) & 1) * 0x8)
@@ -169,6 +196,11 @@ enum dds_data_select {
169196
/* debugfs direct register access */
170197
#define DEBUGFS_DRA_PCORE_REG_MAGIC 0x80000000
171198

199+
#define AXIDDS_MAX_NUM_BUF_CHAN 64
200+
#define AXIDDS_MAX_NUM_DDS_CHAN (2 * AXIDDS_MAX_NUM_BUF_CHAN)
201+
#define AXIDDS_MAX_NUM_CHANNELS (AXIDDS_MAX_NUM_BUF_CHAN + \
202+
AXIDDS_MAX_NUM_DDS_CHAN)
203+
172204
enum {
173205
ID_AD9122,
174206
ID_AD9739A,
@@ -198,7 +230,7 @@ struct cf_axi_dds_chip_info {
198230
unsigned int num_buf_channels;
199231
unsigned num_shadow_slave_channels;
200232
const unsigned long *scan_masks;
201-
struct iio_chan_spec channel[24];
233+
struct iio_chan_spec channel[AXIDDS_MAX_NUM_CHANNELS];
202234
};
203235

204236
struct cf_axi_dds_state;

0 commit comments

Comments
 (0)
0