mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 10:58:48 +09: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 <sound/dmaengine_pcm.h>
|
||||||
|
|
||||||
#include "rockchip_i2s.h"
|
#include "rockchip_i2s.h"
|
||||||
|
#include "rockchip_dlp_pcm.h"
|
||||||
|
|
||||||
#define DRV_NAME "rockchip-i2s"
|
#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_CLR:
|
||||||
case I2S_TXDR:
|
case I2S_TXDR:
|
||||||
case I2S_RXDR:
|
case I2S_RXDR:
|
||||||
case I2S_FIFOLR:
|
case I2S_TXFIFOLR:
|
||||||
|
case I2S_RXFIFOLR:
|
||||||
case I2S_INTSR:
|
case I2S_INTSR:
|
||||||
return true;
|
return true;
|
||||||
default:
|
default:
|
||||||
@@ -811,7 +813,8 @@ static bool rockchip_i2s_volatile_reg(struct device *dev, unsigned int reg)
|
|||||||
switch (reg) {
|
switch (reg) {
|
||||||
case I2S_INTSR:
|
case I2S_INTSR:
|
||||||
case I2S_CLR:
|
case I2S_CLR:
|
||||||
case I2S_FIFOLR:
|
case I2S_TXFIFOLR:
|
||||||
|
case I2S_RXFIFOLR:
|
||||||
case I2S_TXDR:
|
case I2S_TXDR:
|
||||||
case I2S_RXDR:
|
case I2S_RXDR:
|
||||||
return true;
|
return true;
|
||||||
@@ -1016,6 +1019,36 @@ static int rockchip_i2s_keep_clk_always_on(struct rk_i2s_dev *i2s)
|
|||||||
return 0;
|
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)
|
static int rockchip_i2s_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
@@ -1141,7 +1174,11 @@ static int rockchip_i2s_probe(struct platform_device *pdev)
|
|||||||
return 0;
|
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) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "Could not register PCM\n");
|
dev_err(&pdev->dev, "Could not register PCM\n");
|
||||||
goto err_suspend;
|
goto err_suspend;
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ enum {
|
|||||||
#define I2S_TXCR (0x0000)
|
#define I2S_TXCR (0x0000)
|
||||||
#define I2S_RXCR (0x0004)
|
#define I2S_RXCR (0x0004)
|
||||||
#define I2S_CKR (0x0008)
|
#define I2S_CKR (0x0008)
|
||||||
#define I2S_FIFOLR (0x000c)
|
#define I2S_TXFIFOLR (0x000c)
|
||||||
#define I2S_DMACR (0x0010)
|
#define I2S_DMACR (0x0010)
|
||||||
#define I2S_INTCR (0x0014)
|
#define I2S_INTCR (0x0014)
|
||||||
#define I2S_INTSR (0x0018)
|
#define I2S_INTSR (0x0018)
|
||||||
@@ -237,6 +237,7 @@ enum {
|
|||||||
#define I2S_CLR (0x0020)
|
#define I2S_CLR (0x0020)
|
||||||
#define I2S_TXDR (0x0024)
|
#define I2S_TXDR (0x0024)
|
||||||
#define I2S_RXDR (0x0028)
|
#define I2S_RXDR (0x0028)
|
||||||
|
#define I2S_RXFIFOLR (0x002c)
|
||||||
|
|
||||||
/* io direction cfg register */
|
/* io direction cfg register */
|
||||||
#define I2S_IO_DIRECTION_MASK (7)
|
#define I2S_IO_DIRECTION_MASK (7)
|
||||||
@@ -245,4 +246,11 @@ enum {
|
|||||||
#define I2S_IO_4CH_OUT_6CH_IN (6)
|
#define I2S_IO_4CH_OUT_6CH_IN (6)
|
||||||
#define I2S_IO_2CH_OUT_8CH_IN (7)
|
#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 */
|
#endif /* _ROCKCHIP_IIS_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user