diff options
author | Jérôme Pouiller <jerome.pouiller@silabs.com> | 2020-05-26 19:18:15 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-05-27 10:18:08 +0200 |
commit | c791f746c88f9d4ac7171807f15d4eaa724855a5 (patch) | |
tree | e2de34df314ceeaa7adedb778e15a89d36b786c6 /drivers/staging | |
parent | staging: wfx: drop unused function wfx_pending_requeue() (diff) | |
download | linux-c791f746c88f9d4ac7171807f15d4eaa724855a5.tar.xz linux-c791f746c88f9d4ac7171807f15d4eaa724855a5.zip |
staging: wfx: add support for tx_power_loop
During the calibration of the RF amplifier, the device is able to provide
some data about the status of the amplifier.
Record these data and expose them in debugfs.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200526171821.934581-5-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging')
-rw-r--r-- | drivers/staging/wfx/debug.c | 26 | ||||
-rw-r--r-- | drivers/staging/wfx/hif_api_general.h | 18 | ||||
-rw-r--r-- | drivers/staging/wfx/hif_rx.c | 7 | ||||
-rw-r--r-- | drivers/staging/wfx/main.c | 2 | ||||
-rw-r--r-- | drivers/staging/wfx/wfx.h | 2 |
5 files changed, 52 insertions, 3 deletions
diff --git a/drivers/staging/wfx/debug.c b/drivers/staging/wfx/debug.c index f52e7cf885cb..10d649985696 100644 --- a/drivers/staging/wfx/debug.c +++ b/drivers/staging/wfx/debug.c @@ -178,6 +178,30 @@ static int wfx_rx_stats_show(struct seq_file *seq, void *v) } DEFINE_SHOW_ATTRIBUTE(wfx_rx_stats); +static int wfx_tx_power_loop_show(struct seq_file *seq, void *v) +{ + struct wfx_dev *wdev = seq->private; + struct hif_tx_power_loop_info *st = &wdev->tx_power_loop_info; + int tmp; + + mutex_lock(&wdev->tx_power_loop_info_lock); + tmp = le16_to_cpu(st->tx_gain_dig); + seq_printf(seq, "Tx gain digital: %d\n", tmp); + tmp = le16_to_cpu(st->tx_gain_pa); + seq_printf(seq, "Tx gain PA: %d\n", tmp); + tmp = (s16)le16_to_cpu(st->target_pout); + seq_printf(seq, "Target Pout: %d.%02d dBm\n", tmp / 4, (tmp % 4) * 25); + tmp = (s16)le16_to_cpu(st->p_estimation); + seq_printf(seq, "FEM Pout: %d.%02d dBm\n", tmp / 4, (tmp % 4) * 25); + tmp = le16_to_cpu(st->vpdet); + seq_printf(seq, "Vpdet: %d mV\n", tmp); + seq_printf(seq, "Measure index: %d\n", st->measurement_index); + mutex_unlock(&wdev->tx_power_loop_info_lock); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(wfx_tx_power_loop); + static ssize_t wfx_send_pds_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) @@ -317,6 +341,8 @@ int wfx_debug_init(struct wfx_dev *wdev) d = debugfs_create_dir("wfx", wdev->hw->wiphy->debugfsdir); debugfs_create_file("counters", 0444, d, wdev, &wfx_counters_fops); debugfs_create_file("rx_stats", 0444, d, wdev, &wfx_rx_stats_fops); + debugfs_create_file("tx_power_loop", 0444, d, wdev, + &wfx_tx_power_loop_fops); debugfs_create_file("send_pds", 0200, d, wdev, &wfx_send_pds_fops); debugfs_create_file("burn_slk_key", 0200, d, wdev, &wfx_burn_slk_key_fops); diff --git a/drivers/staging/wfx/hif_api_general.h b/drivers/staging/wfx/hif_api_general.h index f5abd8174706..dba18a7ae919 100644 --- a/drivers/staging/wfx/hif_api_general.h +++ b/drivers/staging/wfx/hif_api_general.h @@ -201,9 +201,10 @@ struct hif_cnf_control_gpio { } __packed; enum hif_generic_indication_type { - HIF_GENERIC_INDICATION_TYPE_RAW = 0x0, - HIF_GENERIC_INDICATION_TYPE_STRING = 0x1, - HIF_GENERIC_INDICATION_TYPE_RX_STATS = 0x2 + HIF_GENERIC_INDICATION_TYPE_RAW = 0x0, + HIF_GENERIC_INDICATION_TYPE_STRING = 0x1, + HIF_GENERIC_INDICATION_TYPE_RX_STATS = 0x2, + HIF_GENERIC_INDICATION_TYPE_TX_POWER_LOOP_INFO = 0x3, }; struct hif_rx_stats { @@ -222,8 +223,19 @@ struct hif_rx_stats { s8 current_temp; } __packed; +struct hif_tx_power_loop_info { + __le16 tx_gain_dig; + __le16 tx_gain_pa; + __le16 target_pout; // signed value + __le16 p_estimation; // signed value + __le16 vpdet; + u8 measurement_index; + u8 reserved; +} __packed; + union hif_indication_data { struct hif_rx_stats rx_stats; + struct hif_tx_power_loop_info tx_power_loop_info; u8 raw_data[1]; }; diff --git a/drivers/staging/wfx/hif_rx.c b/drivers/staging/wfx/hif_rx.c index 88466063cc42..bb156033d1e1 100644 --- a/drivers/staging/wfx/hif_rx.c +++ b/drivers/staging/wfx/hif_rx.c @@ -278,6 +278,13 @@ static int hif_generic_indication(struct wfx_dev *wdev, sizeof(wdev->rx_stats)); mutex_unlock(&wdev->rx_stats_lock); return 0; + case HIF_GENERIC_INDICATION_TYPE_TX_POWER_LOOP_INFO: + mutex_lock(&wdev->tx_power_loop_info_lock); + memcpy(&wdev->tx_power_loop_info, + &body->indication_data.tx_power_loop_info, + sizeof(wdev->tx_power_loop_info)); + mutex_unlock(&wdev->tx_power_loop_info_lock); + return 0; default: dev_err(wdev->dev, "generic_indication: unknown indication type: %#.8x\n", type); diff --git a/drivers/staging/wfx/main.c b/drivers/staging/wfx/main.c index ae23a56f50e0..6bd96f476388 100644 --- a/drivers/staging/wfx/main.c +++ b/drivers/staging/wfx/main.c @@ -274,6 +274,7 @@ static void wfx_free_common(void *data) { struct wfx_dev *wdev = data; + mutex_destroy(&wdev->tx_power_loop_info_lock); mutex_destroy(&wdev->rx_stats_lock); mutex_destroy(&wdev->conf_mutex); ieee80211_free_hw(wdev->hw); @@ -344,6 +345,7 @@ struct wfx_dev *wfx_init_common(struct device *dev, mutex_init(&wdev->conf_mutex); mutex_init(&wdev->rx_stats_lock); + mutex_init(&wdev->tx_power_loop_info_lock); init_completion(&wdev->firmware_ready); INIT_DELAYED_WORK(&wdev->cooling_timeout_work, wfx_cooling_timeout_work); diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index cc9f7d16ee8b..73e216733ce4 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -58,6 +58,8 @@ struct wfx_dev { struct hif_rx_stats rx_stats; struct mutex rx_stats_lock; + struct hif_tx_power_loop_info tx_power_loop_info; + struct mutex tx_power_loop_info_lock; }; struct wfx_vif { |