You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
ASoC: rockchip: i2s: Add support for DLP
This patch add support DMA-based digital loopback for I2S.
Ref: commit 9975bc50f3 ("ASoC: rockchip: Add support for Digital Loopback")
Signed-off-by: Sugar Zhang <sugar.zhang@rock-chips.com>
Change-Id: I8a0ea59b216e18ed8c9758f529ef600a333913d7
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
#include <sound/dmaengine_pcm.h>
|
||||
|
||||
#include "rockchip_i2s.h"
|
||||
#include "rockchip_dlp_pcm.h"
|
||||
|
||||
#define DRV_NAME "rockchip-i2s"
|
||||
|
||||
@@ -798,7 +799,8 @@ static bool rockchip_i2s_rd_reg(struct device *dev, unsigned int reg)
|
||||
case I2S_CLR:
|
||||
case I2S_TXDR:
|
||||
case I2S_RXDR:
|
||||
case I2S_FIFOLR:
|
||||
case I2S_TXFIFOLR:
|
||||
case I2S_RXFIFOLR:
|
||||
case I2S_INTSR:
|
||||
return true;
|
||||
default:
|
||||
@@ -811,7 +813,8 @@ static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg)
|
||||
switch (reg) {
|
||||
case I2S_INTSR:
|
||||
case I2S_CLR:
|
||||
case I2S_FIFOLR:
|
||||
case I2S_TXFIFOLR:
|
||||
case I2S_RXFIFOLR:
|
||||
case I2S_TXDR:
|
||||
case I2S_RXDR:
|
||||
return true;
|
||||
@@ -1016,6 +1019,36 @@ static int rockchip_i2s_keep_clk_always_on(struct rk_i2s_dev *i2s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_i2s_get_fifo_count(struct device *dev,
|
||||
struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct rk_i2s_dev *i2s = dev_get_drvdata(dev);
|
||||
unsigned int tx, rx;
|
||||
int val = 0;
|
||||
|
||||
regmap_read(i2s->regmap, I2S_TXFIFOLR, &tx);
|
||||
regmap_read(i2s->regmap, I2S_RXFIFOLR, &rx);
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
val = I2S_FIFOLR_XFL3(tx) +
|
||||
I2S_FIFOLR_XFL2(tx) +
|
||||
I2S_FIFOLR_XFL1(tx) +
|
||||
I2S_FIFOLR_XFL0(tx);
|
||||
else
|
||||
/* XFL4 is compatible for old version */
|
||||
val = I2S_FIFOLR_XFL4(tx) +
|
||||
I2S_FIFOLR_XFL3(rx) +
|
||||
I2S_FIFOLR_XFL2(rx) +
|
||||
I2S_FIFOLR_XFL1(rx) +
|
||||
I2S_FIFOLR_XFL0(rx);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
static const struct snd_dlp_config dconfig = {
|
||||
.get_fifo_count = rockchip_i2s_get_fifo_count,
|
||||
};
|
||||
|
||||
static int rockchip_i2s_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
@@ -1141,7 +1174,11 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
|
||||
if (device_property_read_bool(&pdev->dev, "rockchip,digital-loopback"))
|
||||
ret = devm_snd_dmaengine_dlp_register(&pdev->dev, &dconfig);
|
||||
else
|
||||
ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
|
||||
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Could not register PCM\n");
|
||||
goto err_suspend;
|
||||
|
||||
@@ -229,7 +229,7 @@ enum {
|
||||
#define I2S_TXCR (0x0000)
|
||||
#define I2S_RXCR (0x0004)
|
||||
#define I2S_CKR (0x0008)
|
||||
#define I2S_FIFOLR (0x000c)
|
||||
#define I2S_TXFIFOLR (0x000c)
|
||||
#define I2S_DMACR (0x0010)
|
||||
#define I2S_INTCR (0x0014)
|
||||
#define I2S_INTSR (0x0018)
|
||||
@@ -237,6 +237,7 @@ enum {
|
||||
#define I2S_CLR (0x0020)
|
||||
#define I2S_TXDR (0x0024)
|
||||
#define I2S_RXDR (0x0028)
|
||||
#define I2S_RXFIFOLR (0x002c)
|
||||
|
||||
/* io direction cfg register */
|
||||
#define I2S_IO_DIRECTION_MASK (7)
|
||||
@@ -245,4 +246,11 @@ enum {
|
||||
#define I2S_IO_4CH_OUT_6CH_IN (6)
|
||||
#define I2S_IO_2CH_OUT_8CH_IN (7)
|
||||
|
||||
/* XFL4 is compatible for old version */
|
||||
#define I2S_FIFOLR_XFL4(v) (((v) & GENMASK(29, 24)) >> 24)
|
||||
#define I2S_FIFOLR_XFL3(v) (((v) & GENMASK(23, 18)) >> 18)
|
||||
#define I2S_FIFOLR_XFL2(v) (((v) & GENMASK(17, 12)) >> 12)
|
||||
#define I2S_FIFOLR_XFL1(v) (((v) & GENMASK(11, 6)) >> 6)
|
||||
#define I2S_FIFOLR_XFL0(v) (((v) & GENMASK(5, 0)) >> 0)
|
||||
|
||||
#endif /* _ROCKCHIP_IIS_H */
|
||||
|
||||
Reference in New Issue
Block a user