Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 101 additions & 1 deletion drivers/iio/adc/adrv902x/adrv9025.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// SPDX-License-Identifier: GPL-2.0
/*
* ADRV9025/6 RF Transceiver
Expand All @@ -18,6 +18,7 @@
#include <linux/string.h>
#include <linux/debugfs.h>
#include <linux/uaccess.h>
#include <linux/seq_file.h>
#include <linux/firmware.h>
#include <linux/interrupt.h>
#include <linux/types.h>
Expand Down Expand Up @@ -1931,6 +1932,90 @@
.write = adrv9025_debugfs_write,
};

static int adrv9025_tx_advanced_dpd_status_show(struct seq_file *s, void *ignored)
{
struct adrv9025_tx_chan_ctx *ctx = s->private;
adi_adrv9025_DpdStatus_v2_t dpdStatus = { 0 };
struct adrv9025_rf_phy *phy = ctx->phy;
adi_adrv9025_TxChannels_e txChannel;
u8 chan = ctx->channel;
int ret;

/* Convert channel index to TX channel enum */
txChannel = ADI_ADRV9025_TX1 << chan;

mutex_lock(&phy->lock);
ret = adi_adrv9025_DpdStatusGet_v2(phy->madDevice, txChannel, &dpdStatus);
mutex_unlock(&phy->lock);
if (ret)
return adrv9025_dev_err(phy);

seq_printf(s, "ADRV9025 TX%u Advanced DPD Status\n", chan);

/* Basic Status */
seq_puts(s, "Basic Status:\n");
seq_printf(s, " Error Code: %d\n", dpdStatus.dpdErrorCode);
seq_printf(s, " Percent Complete: %u%%\n", dpdStatus.dpdPercentComplete);
seq_printf(s, " Iteration Count: %u\n", dpdStatus.dpdIterCount);
seq_printf(s, " Update Count: %u\n", dpdStatus.dpdUpdateCount);
seq_printf(s, " Sync Status: %d\n", dpdStatus.dpdSyncStatus);
seq_printf(s, " Model Table: %d\n", dpdStatus.dpdModelTable);

/* Power Statistics */
seq_puts(s, "\nPower Statistics:\n");
seq_printf(s, " Mean TU Power: %d.%03d dBFS\n",
dpdStatus.dpdStatistics.dpdMeanTuPower_mdB / 1000,
abs(dpdStatus.dpdStatistics.dpdMeanTuPower_mdB % 1000));
seq_printf(s, " Peak TU Power: %d.%03d dBFS\n",
dpdStatus.dpdStatistics.dpdPeakTuPower_mdB / 1000,
abs(dpdStatus.dpdStatistics.dpdPeakTuPower_mdB % 1000));
seq_printf(s, " Mean TX Power: %d.%03d dBFS\n",
dpdStatus.dpdStatistics.dpdMeanTxPower_mdB / 1000,
abs(dpdStatus.dpdStatistics.dpdMeanTxPower_mdB % 1000));
seq_printf(s, " Peak TX Power: %d.%03d dBFS\n",
dpdStatus.dpdStatistics.dpdPeakTxPower_mdB / 1000,
abs(dpdStatus.dpdStatistics.dpdPeakTxPower_mdB % 1000));
seq_printf(s, " Mean ORx Power: %d.%03d dBFS\n",
dpdStatus.dpdStatistics.dpdMeanOrxPower_mdB / 1000,
abs(dpdStatus.dpdStatistics.dpdMeanOrxPower_mdB % 1000));
seq_printf(s, " Peak ORx Power: %d.%03d dBFS\n",
dpdStatus.dpdStatistics.dpdPeakOrxPower_mdB / 1000,
abs(dpdStatus.dpdStatistics.dpdPeakOrxPower_mdB % 1000));

/* Error Metrics */
seq_puts(s, "\nError Metrics:\n");
seq_printf(s, " Direct EVM: %u.%04u%%\n",
dpdStatus.dpdStatistics.dpdDirectEvm_xM / 10000,
dpdStatus.dpdStatistics.dpdDirectEvm_xM % 10000);
seq_printf(s, " Indirect EVM: %u.%04u%%\n",
dpdStatus.dpdStatistics.dpdIndirectEvm_xM / 10000,
dpdStatus.dpdStatistics.dpdIndirectEvm_xM % 10000);
seq_printf(s, " Select Error: %u.%04u%%\n",
dpdStatus.dpdStatistics.dpdSelectError_xM / 10000,
dpdStatus.dpdStatistics.dpdSelectError_xM % 10000);
seq_printf(s, " Indirect Error: %u.%04u%%\n",
dpdStatus.dpdStatistics.dpdIndirectError_xM / 10000,
dpdStatus.dpdStatistics.dpdIndirectError_xM % 10000);

/* Error Status */
seq_puts(s, "\nError Status:\n");
seq_printf(s, " Error Status 0: metrics_mask=0x%04x, action_mask=0x%04x\n",
dpdStatus.dpdErrorStatus0.dpdMetricsMask,
dpdStatus.dpdErrorStatus0.dpdActionMask);
seq_printf(s, " Error Status 1: metrics_mask=0x%04x, action_mask=0x%04x\n",
dpdStatus.dpdErrorStatus1.dpdMetricsMask,
dpdStatus.dpdErrorStatus1.dpdActionMask);
seq_printf(s, " Persistent Error 0: metrics_mask=0x%04x, action_mask=0x%04x\n",
dpdStatus.dpdPersistentErrorStatus0.dpdMetricsMask,
dpdStatus.dpdPersistentErrorStatus0.dpdActionMask);
seq_printf(s, " Persistent Error 1: metrics_mask=0x%04x, action_mask=0x%04x\n",
dpdStatus.dpdPersistentErrorStatus1.dpdMetricsMask,
dpdStatus.dpdPersistentErrorStatus1.dpdActionMask);

return 0;
}
DEFINE_SHOW_ATTRIBUTE(adrv9025_tx_advanced_dpd_status);

static void adrv9025_add_debugfs_entry(struct adrv9025_rf_phy *phy,
const char *propname, unsigned int cmd)
{
Expand Down Expand Up @@ -1991,6 +2076,21 @@
&phy->debugfs_entry[i],
&adrv9025_debugfs_reg_fops);
}

/* Create seqfile-based debugfs entries for each TX channel */
for (i = 0; i < ADRV9025_NUMBER_OF_TX_CHANNELS; i++) {
char attr[64];

phy->tx_chan_ctx[i].phy = phy;
phy->tx_chan_ctx[i].channel = i;

sprintf(attr, "tx%d_advanced_dpd_status", i);
debugfs_create_file(attr, 0444,
iio_get_debugfs_dentry(indio_dev),
&phy->tx_chan_ctx[i],
&adrv9025_tx_advanced_dpd_status_fops);
}

return 0;
}

Expand Down Expand Up @@ -2034,7 +2134,7 @@
static long adrv9025_bb_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *prate)
{
struct adrv9025_clock *clk_priv = to_clk_priv(hw);

Check warning on line 2137 in drivers/iio/adc/adrv902x/adrv9025.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'clk_priv' during its initialization is never read [deadcode.DeadStores] 2137 | struct adrv9025_clock *clk_priv = to_clk_priv(hw); | ^~~~~~~~ ~~~~~~~~~~~~~~~

dev_dbg(&clk_priv->spi->dev, "%s: Rate %lu Hz", __func__, rate);

Expand Down Expand Up @@ -2172,7 +2272,7 @@
static int adrv9025_jesd204_link_pre_setup(struct jesd204_dev *jdev,
enum jesd204_state_op_reason reason)
{
struct device *dev = jesd204_dev_to_device(jdev);

Check warning on line 2275 in drivers/iio/adc/adrv902x/adrv9025.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'dev' during its initialization is never read [deadcode.DeadStores] 2275 | struct device *dev = jesd204_dev_to_device(jdev); | ^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct adrv9025_jesd204_priv *priv = jesd204_dev_priv(jdev);
struct adrv9025_rf_phy *phy = priv->phy;
long dev_clk;
Expand Down Expand Up @@ -2207,7 +2307,7 @@
enum jesd204_state_op_reason reason,
struct jesd204_link *lnk)
{
struct device *dev = jesd204_dev_to_device(jdev);

Check warning on line 2310 in drivers/iio/adc/adrv902x/adrv9025.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'dev' during its initialization is never read [deadcode.DeadStores] 2310 | struct device *dev = jesd204_dev_to_device(jdev); | ^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct adrv9025_jesd204_priv *priv = jesd204_dev_priv(jdev);
struct adrv9025_rf_phy *phy = priv->phy;
adi_adrv9025_FrmCfg_t *framer = NULL;
Expand Down Expand Up @@ -2317,7 +2417,7 @@
static int adrv9025_jesd204_link_setup(struct jesd204_dev *jdev,
enum jesd204_state_op_reason reason)
{
struct device *dev = jesd204_dev_to_device(jdev);

Check warning on line 2420 in drivers/iio/adc/adrv902x/adrv9025.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'dev' during its initialization is never read [deadcode.DeadStores] 2420 | struct device *dev = jesd204_dev_to_device(jdev); | ^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct adrv9025_jesd204_priv *priv = jesd204_dev_priv(jdev);
struct adrv9025_rf_phy *phy = priv->phy;
int ret;
Expand Down Expand Up @@ -2375,7 +2475,7 @@
static int adrv9025_jesd204_setup_stage1(struct jesd204_dev *jdev,
enum jesd204_state_op_reason reason)
{
struct device *dev = jesd204_dev_to_device(jdev);

Check warning on line 2478 in drivers/iio/adc/adrv902x/adrv9025.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'dev' during its initialization is never read [deadcode.DeadStores] 2478 | struct device *dev = jesd204_dev_to_device(jdev); | ^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct adrv9025_jesd204_priv *priv = jesd204_dev_priv(jdev);
struct adrv9025_rf_phy *phy = priv->phy;
int ret, i;
Expand Down Expand Up @@ -2414,7 +2514,7 @@
static int adrv9025_jesd204_setup_stage2(struct jesd204_dev *jdev,
enum jesd204_state_op_reason reason)
{
struct device *dev = jesd204_dev_to_device(jdev);

Check warning on line 2517 in drivers/iio/adc/adrv902x/adrv9025.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'dev' during its initialization is never read [deadcode.DeadStores] 2517 | struct device *dev = jesd204_dev_to_device(jdev); | ^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct adrv9025_jesd204_priv *priv = jesd204_dev_priv(jdev);
struct adrv9025_rf_phy *phy = priv->phy;
int ret;
Expand Down Expand Up @@ -2448,7 +2548,7 @@
enum jesd204_state_op_reason reason,
struct jesd204_link *lnk)
{
struct device *dev = jesd204_dev_to_device(jdev);

Check warning on line 2551 in drivers/iio/adc/adrv902x/adrv9025.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'dev' during its initialization is never read [deadcode.DeadStores] 2551 | struct device *dev = jesd204_dev_to_device(jdev); | ^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct adrv9025_jesd204_priv *priv = jesd204_dev_priv(jdev);
struct adrv9025_rf_phy *phy = priv->phy;
int ret;
Expand Down Expand Up @@ -2556,7 +2656,7 @@
enum jesd204_state_op_reason reason,
struct jesd204_link *lnk)
{
struct device *dev = jesd204_dev_to_device(jdev);

Check warning on line 2659 in drivers/iio/adc/adrv902x/adrv9025.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'dev' during its initialization is never read [deadcode.DeadStores] 2659 | struct device *dev = jesd204_dev_to_device(jdev); | ^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct adrv9025_jesd204_priv *priv = jesd204_dev_priv(jdev);
struct adrv9025_rf_phy *phy = priv->phy;
int ret;
Expand Down Expand Up @@ -2611,7 +2711,7 @@
enum jesd204_state_op_reason reason,
struct jesd204_link *lnk)
{
struct device *dev = jesd204_dev_to_device(jdev);

Check warning on line 2714 in drivers/iio/adc/adrv902x/adrv9025.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'dev' during its initialization is never read [deadcode.DeadStores] 2714 | struct device *dev = jesd204_dev_to_device(jdev); | ^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct adrv9025_jesd204_priv *priv = jesd204_dev_priv(jdev);
struct adrv9025_rf_phy *phy = priv->phy;
int ret;
Expand Down Expand Up @@ -2686,7 +2786,7 @@
static int adrv9025_jesd204_post_running_stage(struct jesd204_dev *jdev,
enum jesd204_state_op_reason reason)
{
struct device *dev = jesd204_dev_to_device(jdev);

Check warning on line 2789 in drivers/iio/adc/adrv902x/adrv9025.c

View workflow job for this annotation

GitHub Actions / build_llvm_x86_64 / build

clang_analyzer: Value stored to 'dev' during its initialization is never read [deadcode.DeadStores] 2789 | struct device *dev = jesd204_dev_to_device(jdev); | ^~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
struct adrv9025_jesd204_priv *priv = jesd204_dev_priv(jdev);
struct adrv9025_rf_phy *phy = priv->phy;
int ret;
Expand Down Expand Up @@ -3293,7 +3393,7 @@
phy->spi_device_id = id;
phy->dev_clk = clk;
phy->jdev = jdev;
phy->agcConfig = kzalloc(sizeof(adi_adrv9025_AgcCfg_t), GFP_KERNEL);
phy->agcConfig = devm_kzalloc(&spi->dev, sizeof(adi_adrv9025_AgcCfg_t), GFP_KERNEL);
if (!(phy->agcConfig))
return -ENOMEM;
phy->dpdModelConfig = devm_kzalloc(&spi->dev, sizeof(adi_adrv9025_DpdModelConfig_v2_t), GFP_KERNEL);
Expand Down
9 changes: 9 additions & 0 deletions drivers/iio/adc/adrv902x/adrv9025.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ enum debugfs_cmd {
DBGFS_TX1_DPD_STATUS,
DBGFS_TX2_DPD_STATUS,
DBGFS_TX3_DPD_STATUS,
DBGFS_ADVANCED_DPD_STATUS,
};

enum adrv9025_rx_ext_info {
Expand Down Expand Up @@ -109,6 +110,11 @@ struct adrv9025_debugfs_entry {
u8 cmd;
};

struct adrv9025_tx_chan_ctx {
struct adrv9025_rf_phy *phy;
u8 channel;
};

enum adrv9025_clocks {
RX_SAMPL_CLK,
TX_SAMPL_CLK,
Expand Down Expand Up @@ -172,6 +178,9 @@ struct adrv9025_rf_phy {
adi_adrv9025_DpdModelConfig_v2_t *dpdModelConfig;
adi_adrv9025_TxChannels_e dpdTxChannel;
adi_adrv9025_DpdTrackingConfig_t *dpdTrackingConfig;

/* TX channel context for debugfs */
struct adrv9025_tx_chan_ctx tx_chan_ctx[4];
};

int adrv9025_hdl_loopback(struct adrv9025_rf_phy *phy, bool enable);
Expand Down
Loading