diff options
author | Viorel Suman <viorel.suman@nxp.com> | 2020-11-02 09:39:57 +0200 |
---|---|---|
committer | Viorel Suman <viorel.suman@nxp.com> | 2020-11-05 09:39:08 +0200 |
commit | 02f2735702118a80b3beb9626de5d14de0e32d73 (patch) | |
tree | c8163937cab60421d7559927fa42a56e59b84ccf /sound/soc | |
parent | f186a4e65f54a28973c743f8c007b18c1ce95be6 (diff) |
MLK-24965: ASoC: fsl_xcvr: bit and timestamp counters
Add support for bit and timestamp counters.
Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
Reviewed-by: Shengjiu Wang <shengjiu.wang@nxp.com>
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/fsl/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_xcvr.c | 87 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_xcvr.h | 54 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_xcvr_sysfs.c | 109 |
4 files changed, 220 insertions, 32 deletions
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index 5b4a150b865c..65dcc5c33e0a 100644 --- a/sound/soc/fsl/Makefile +++ b/sound/soc/fsl/Makefile @@ -29,7 +29,7 @@ snd-soc-fsl-utils-objs := fsl_utils.o snd-soc-fsl-dma-objs := fsl_dma.o snd-soc-fsl-easrc-objs := fsl_easrc.o fsl_easrc_dma.o snd-soc-fsl-aud2htx-objs := fsl_aud2htx.o -snd-soc-fsl-xcvr-objs := fsl_xcvr.o +snd-soc-fsl-xcvr-objs := fsl_xcvr.o fsl_xcvr_sysfs.o snd-soc-fsl-esai-client-objs := fsl_esai_client.o obj-$(CONFIG_SND_SOC_FSL_AUDMIX) += snd-soc-fsl-audmix.o diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c index d82de4f220b0..47a33ef139a8 100644 --- a/sound/soc/fsl/fsl_xcvr.c +++ b/sound/soc/fsl/fsl_xcvr.c @@ -8,41 +8,11 @@ #include <linux/module.h> #include <linux/of_platform.h> #include <linux/pm_runtime.h> -#include <linux/regmap.h> -#include <linux/reset.h> -#include <sound/dmaengine_pcm.h> -#include <sound/pcm_iec958.h> #include <sound/pcm_params.h> #include "fsl_xcvr.h" #include "imx-pcm.h" -#define FSL_XCVR_CAPDS_SIZE 256 - -struct fsl_xcvr_soc_data { - const char *fw_name; -}; - -struct fsl_xcvr { - const struct fsl_xcvr_soc_data *soc_data; - struct platform_device *pdev; - struct regmap *regmap; - struct clk *ipg_clk; - struct clk *pll_ipg_clk; - struct clk *phy_clk; - struct clk *spba_clk; - struct reset_control *reset; - u8 streams; - u32 mode; - u32 arc_mode; - void __iomem *ram_addr; - struct snd_dmaengine_dai_dma_data dma_prms_rx; - struct snd_dmaengine_dai_dma_data dma_prms_tx; - struct snd_aes_iec958 rx_iec958; - struct snd_aes_iec958 tx_iec958; - u8 cap_ds[FSL_XCVR_CAPDS_SIZE]; -}; - static const struct fsl_xcvr_pll_conf { u8 mfi; /* min=0x18, max=0x38 */ u32 mfn; /* signed int, 2's compl., min=0x3FFF0000, max=0x00010000 */ @@ -926,6 +896,14 @@ static const struct reg_default fsl_xcvr_reg_defaults[] = { { FSL_XCVR_RX_DPTH_CTRL_SET, 0x00002C89 }, { FSL_XCVR_RX_DPTH_CTRL_CLR, 0x00002C89 }, { FSL_XCVR_RX_DPTH_CTRL_TOG, 0x00002C89 }, + { FSL_XCVR_RX_DPTH_CNTR_CTRL, 0x00000000 }, + { FSL_XCVR_RX_DPTH_CNTR_CTRL_SET, 0x00000000 }, + { FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR, 0x00000000 }, + { FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG, 0x00000000 }, + { FSL_XCVR_RX_DPTH_TSCR, 0x00000000 }, + { FSL_XCVR_RX_DPTH_BCR, 0x00000000 }, + { FSL_XCVR_RX_DPTH_BCTR, 0x00000000 }, + { FSL_XCVR_RX_DPTH_BCRR, 0x00000000 }, { FSL_XCVR_TX_DPTH_CTRL, 0x00000000 }, { FSL_XCVR_TX_DPTH_CTRL_SET, 0x00000000 }, { FSL_XCVR_TX_DPTH_CTRL_CLR, 0x00000000 }, @@ -936,6 +914,14 @@ static const struct reg_default fsl_xcvr_reg_defaults[] = { { FSL_XCVR_TX_CS_DATA_3, 0x00000000 }, { FSL_XCVR_TX_CS_DATA_4, 0x00000000 }, { FSL_XCVR_TX_CS_DATA_5, 0x00000000 }, + { FSL_XCVR_TX_DPTH_CNTR_CTRL, 0x00000000 }, + { FSL_XCVR_TX_DPTH_CNTR_CTRL_SET, 0x00000000 }, + { FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR, 0x00000000 }, + { FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG, 0x00000000 }, + { FSL_XCVR_TX_DPTH_TSCR, 0x00000000 }, + { FSL_XCVR_TX_DPTH_BCR, 0x00000000 }, + { FSL_XCVR_TX_DPTH_BCTR, 0x00000000 }, + { FSL_XCVR_TX_DPTH_BCRR, 0x00000000 }, { FSL_XCVR_DEBUG_REG_0, 0x00000000 }, { FSL_XCVR_DEBUG_REG_1, 0x00000000 }, }; @@ -967,6 +953,14 @@ static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg) case FSL_XCVR_RX_DPTH_CTRL_SET: case FSL_XCVR_RX_DPTH_CTRL_CLR: case FSL_XCVR_RX_DPTH_CTRL_TOG: + case FSL_XCVR_RX_DPTH_CNTR_CTRL: + case FSL_XCVR_RX_DPTH_CNTR_CTRL_SET: + case FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR: + case FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG: + case FSL_XCVR_RX_DPTH_TSCR: + case FSL_XCVR_RX_DPTH_BCR: + case FSL_XCVR_RX_DPTH_BCTR: + case FSL_XCVR_RX_DPTH_BCRR: case FSL_XCVR_TX_DPTH_CTRL: case FSL_XCVR_TX_DPTH_CTRL_SET: case FSL_XCVR_TX_DPTH_CTRL_CLR: @@ -977,6 +971,14 @@ static bool fsl_xcvr_readable_reg(struct device *dev, unsigned int reg) case FSL_XCVR_TX_CS_DATA_3: case FSL_XCVR_TX_CS_DATA_4: case FSL_XCVR_TX_CS_DATA_5: + case FSL_XCVR_TX_DPTH_CNTR_CTRL: + case FSL_XCVR_TX_DPTH_CNTR_CTRL_SET: + case FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR: + case FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG: + case FSL_XCVR_TX_DPTH_TSCR: + case FSL_XCVR_TX_DPTH_BCR: + case FSL_XCVR_TX_DPTH_BCTR: + case FSL_XCVR_TX_DPTH_BCRR: case FSL_XCVR_DEBUG_REG_0: case FSL_XCVR_DEBUG_REG_1: return true; @@ -1009,6 +1011,10 @@ static bool fsl_xcvr_writeable_reg(struct device *dev, unsigned int reg) case FSL_XCVR_RX_DPTH_CTRL_SET: case FSL_XCVR_RX_DPTH_CTRL_CLR: case FSL_XCVR_RX_DPTH_CTRL_TOG: + case FSL_XCVR_RX_DPTH_CNTR_CTRL: + case FSL_XCVR_RX_DPTH_CNTR_CTRL_SET: + case FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR: + case FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG: case FSL_XCVR_TX_DPTH_CTRL_SET: case FSL_XCVR_TX_DPTH_CTRL_CLR: case FSL_XCVR_TX_DPTH_CTRL_TOG: @@ -1018,6 +1024,10 @@ static bool fsl_xcvr_writeable_reg(struct device *dev, unsigned int reg) case FSL_XCVR_TX_CS_DATA_3: case FSL_XCVR_TX_CS_DATA_4: case FSL_XCVR_TX_CS_DATA_5: + case FSL_XCVR_TX_DPTH_CNTR_CTRL: + case FSL_XCVR_TX_DPTH_CNTR_CTRL_SET: + case FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR: + case FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG: return true; default: return false; @@ -1229,12 +1239,26 @@ static int fsl_xcvr_probe(struct platform_device *pdev) } ret = imx_pcm_platform_register(dev); - if (ret) + if (ret) { dev_err(dev, "failed to pcm register\n"); + return ret; + } + + ret = sysfs_create_group(&pdev->dev.kobj, fsl_xcvr_get_attr_grp()); + if (ret) + dev_err(&pdev->dev, "fail to create sys group\n"); return ret; } +static int fsl_xcvr_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, fsl_xcvr_get_attr_grp()); + pm_runtime_disable(&pdev->dev); + + return 0; +} + static __maybe_unused int fsl_xcvr_runtime_suspend(struct device *dev) { struct fsl_xcvr *xcvr = dev_get_drvdata(dev); @@ -1346,6 +1370,7 @@ static const struct dev_pm_ops fsl_xcvr_pm_ops = { static struct platform_driver fsl_xcvr_driver = { .probe = fsl_xcvr_probe, + .remove = fsl_xcvr_remove, .driver = { .name = "fsl,imx8mp-audio-xcvr", .pm = &fsl_xcvr_pm_ops, diff --git a/sound/soc/fsl/fsl_xcvr.h b/sound/soc/fsl/fsl_xcvr.h index 7f2853c60085..022fddc0310c 100644 --- a/sound/soc/fsl/fsl_xcvr.h +++ b/sound/soc/fsl/fsl_xcvr.h @@ -8,6 +8,11 @@ #ifndef __FSL_XCVR_H #define __FSL_XCVR_H +#include <linux/regmap.h> +#include <linux/reset.h> +#include <sound/dmaengine_pcm.h> +#include <sound/pcm_iec958.h> + #define FSL_XCVR_MODE_SPDIF 0 #define FSL_XCVR_MODE_ARC 1 #define FSL_XCVR_MODE_EARC 2 @@ -49,6 +54,16 @@ #define FSL_XCVR_RX_DPTH_CTRL_CLR 0x188 #define FSL_XCVR_RX_DPTH_CTRL_TOG 0x18c +#define FSL_XCVR_RX_DPTH_CNTR_CTRL 0x1C0 +#define FSL_XCVR_RX_DPTH_CNTR_CTRL_SET 0x1C4 +#define FSL_XCVR_RX_DPTH_CNTR_CTRL_CLR 0x1C8 +#define FSL_XCVR_RX_DPTH_CNTR_CTRL_TOG 0x1CC + +#define FSL_XCVR_RX_DPTH_TSCR 0x1D0 +#define FSL_XCVR_RX_DPTH_BCR 0x1D4 +#define FSL_XCVR_RX_DPTH_BCTR 0x1D8 +#define FSL_XCVR_RX_DPTH_BCRR 0x1DC + #define FSL_XCVR_TX_DPTH_CTRL 0x220 /* TX datapath ctrl reg */ #define FSL_XCVR_TX_DPTH_CTRL_SET 0x224 #define FSL_XCVR_TX_DPTH_CTRL_CLR 0x228 @@ -59,6 +74,17 @@ #define FSL_XCVR_TX_CS_DATA_3 0x23C #define FSL_XCVR_TX_CS_DATA_4 0x240 #define FSL_XCVR_TX_CS_DATA_5 0x244 + +#define FSL_XCVR_TX_DPTH_CNTR_CTRL 0x260 +#define FSL_XCVR_TX_DPTH_CNTR_CTRL_SET 0x264 +#define FSL_XCVR_TX_DPTH_CNTR_CTRL_CLR 0x268 +#define FSL_XCVR_TX_DPTH_CNTR_CTRL_TOG 0x26C + +#define FSL_XCVR_TX_DPTH_TSCR 0x270 +#define FSL_XCVR_TX_DPTH_BCR 0x274 +#define FSL_XCVR_TX_DPTH_BCTR 0x278 +#define FSL_XCVR_TX_DPTH_BCRR 0x27C + #define FSL_XCVR_DEBUG_REG_0 0x2E0 #define FSL_XCVR_DEBUG_REG_1 0x2F0 @@ -263,4 +289,32 @@ #define FSL_XCVR_RX_CS_BUFF_1 0xA0 /* Second RX CS buffer */ #define FSL_XCVR_CAP_DATA_STR 0x300 /* Capabilities data structure */ +#define FSL_XCVR_CAPDS_SIZE 256 + +struct fsl_xcvr_soc_data { + const char *fw_name; +}; + +struct fsl_xcvr { + const struct fsl_xcvr_soc_data *soc_data; + struct platform_device *pdev; + struct regmap *regmap; + struct clk *ipg_clk; + struct clk *pll_ipg_clk; + struct clk *phy_clk; + struct clk *spba_clk; + struct reset_control *reset; + u8 streams; + u32 mode; + u32 arc_mode; + void __iomem *ram_addr; + struct snd_dmaengine_dai_dma_data dma_prms_rx; + struct snd_dmaengine_dai_dma_data dma_prms_tx; + struct snd_aes_iec958 rx_iec958; + struct snd_aes_iec958 tx_iec958; + u8 cap_ds[FSL_XCVR_CAPDS_SIZE]; +}; + +const struct attribute_group *fsl_xcvr_get_attr_grp(void); + #endif /* __FSL_XCVR_H */ diff --git a/sound/soc/fsl/fsl_xcvr_sysfs.c b/sound/soc/fsl/fsl_xcvr_sysfs.c new file mode 100644 index 000000000000..77f425b88b86 --- /dev/null +++ b/sound/soc/fsl/fsl_xcvr_sysfs.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright 2020 NXP Semiconductors. + +#include <linux/clk.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/kdev_t.h> +#include <linux/pm_runtime.h> + +#include "fsl_xcvr.h" + +static ssize_t read(struct device *dev, struct device_attribute *attr, char *buf, unsigned int reg) +{ + struct fsl_xcvr *xcvr = dev_get_drvdata(dev); + unsigned int val = 0; + + regmap_read(xcvr->regmap, reg, &val); + + return sprintf(buf, "%u\n", val); +} + +#define XRDC_RO_ATTR(_name, _reg) \ +static ssize_t _name##_show(struct device *dev, struct device_attribute *attr, char *buf) \ +{ /* read bitcounter */ \ + return read(dev, attr, buf, _reg); \ +} \ +static DEVICE_ATTR_RO(_name); + +XRDC_RO_ATTR(rx_bitcnt, FSL_XCVR_RX_DPTH_BCR) +XRDC_RO_ATTR(tx_bitcnt, FSL_XCVR_TX_DPTH_BCR) +XRDC_RO_ATTR(rx_timestamp, FSL_XCVR_RX_DPTH_TSCR) +XRDC_RO_ATTR(tx_timestamp, FSL_XCVR_TX_DPTH_TSCR) +XRDC_RO_ATTR(rx_bitcnt_latched_timestamp, FSL_XCVR_RX_DPTH_BCRR) +XRDC_RO_ATTR(tx_bitcnt_latched_timestamp, FSL_XCVR_TX_DPTH_BCRR) + +/* ============ */ +static ssize_t show(struct device *dev, struct device_attribute *attr, char *buf, u32 reg, u32 bit) +{ + struct fsl_xcvr *xcvr = dev_get_drvdata(dev); + unsigned int val = 0; + + regmap_read(xcvr->regmap, reg, &val); + + return sprintf(buf, "%u\n", (val & BIT(bit)) ? 1 : 0); +} + +static ssize_t store(struct device *dev, struct device_attribute *attr, const char *buf, size_t n, + u32 reg, u32 bit) +{ + struct fsl_xcvr *xcvr = dev_get_drvdata(dev); + unsigned int val = 0; + + if (kstrtouint(buf, 0, &val)) + return -EINVAL; + + regmap_update_bits(xcvr->regmap, reg, BIT(bit), val ? BIT(bit) : 0); + + return n; +} + +#define XRDC_RW_ATTR(_name, _reg, _bit) \ +static ssize_t _name##_show(struct device *dev, struct device_attribute *attr, char *buf) \ +{ \ + return show(dev, attr, buf, _reg, _bit); \ +} \ +\ +static ssize_t _name##_store(struct device *dev, struct device_attribute *attr, const char *buf, \ + size_t n) \ +{ \ + return store(dev, attr, buf, n, _reg, _bit); \ +} \ +static DEVICE_ATTR_RW(_name); + +XRDC_RW_ATTR(rx_bitcnt_reset, FSL_XCVR_RX_DPTH_CNTR_CTRL, 8) +XRDC_RW_ATTR(tx_bitcnt_reset, FSL_XCVR_TX_DPTH_CNTR_CTRL, 8) +XRDC_RW_ATTR(rx_timestamp_enable, FSL_XCVR_RX_DPTH_CNTR_CTRL, 0) +XRDC_RW_ATTR(tx_timestamp_enable, FSL_XCVR_TX_DPTH_CNTR_CTRL, 0) +XRDC_RW_ATTR(rx_timestamp_increment, FSL_XCVR_RX_DPTH_CNTR_CTRL, 1) +XRDC_RW_ATTR(tx_timestamp_increment, FSL_XCVR_TX_DPTH_CNTR_CTRL, 1) +XRDC_RW_ATTR(rx_timestamp_reset, FSL_XCVR_RX_DPTH_CNTR_CTRL, 9) +XRDC_RW_ATTR(tx_timestamp_reset, FSL_XCVR_TX_DPTH_CNTR_CTRL, 9) + +static struct attribute *fsl_xcvr_attrs[] = { + &dev_attr_tx_bitcnt.attr, + &dev_attr_rx_bitcnt.attr, + &dev_attr_tx_timestamp.attr, + &dev_attr_rx_timestamp.attr, + &dev_attr_tx_bitcnt_latched_timestamp.attr, + &dev_attr_rx_bitcnt_latched_timestamp.attr, + &dev_attr_tx_timestamp_enable.attr, + &dev_attr_rx_timestamp_enable.attr, + &dev_attr_tx_timestamp_increment.attr, + &dev_attr_rx_timestamp_increment.attr, + &dev_attr_tx_bitcnt_reset.attr, + &dev_attr_rx_bitcnt_reset.attr, + &dev_attr_tx_timestamp_reset.attr, + &dev_attr_rx_timestamp_reset.attr, + NULL, +}; + +static struct attribute_group fsl_xcvr_attr_group = { + .name = "counters", + .attrs = fsl_xcvr_attrs, +}; + +const struct attribute_group *fsl_xcvr_get_attr_grp() +{ + return &fsl_xcvr_attr_group; +} |