mirror of
https://github.com/brain-hackers/linux-brain.git
synced 2024-06-09 23:36:23 +09:00
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>
This commit is contained in:
parent
f186a4e65f
commit
02f2735702
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
|
109
sound/soc/fsl/fsl_xcvr_sysfs.c
Normal file
109
sound/soc/fsl/fsl_xcvr_sysfs.c
Normal file
|
@ -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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user