Unverified Commit 07a79102 authored by Sugar Zhang's avatar Sugar Zhang Committed by Mark Brown
Browse files

ASoC: rockchip: spdif: Fill IEC958 CS info per params

parent c43ec509
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ config SND_SOC_ROCKCHIP_SAI

config SND_SOC_ROCKCHIP_SPDIF
	tristate "Rockchip SPDIF Device Driver"
	select SND_PCM_IEC958
	select SND_SOC_GENERIC_DMAENGINE_PCM
	help
	  Say Y or M if you want to add support for SPDIF driver for
+41 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
#include <sound/pcm_params.h>
#include <sound/pcm_iec958.h>
#include <sound/dmaengine_pcm.h>

#include "rockchip_spdif.h"
@@ -27,6 +28,24 @@ enum rk_spdif_type {
	RK_SPDIF_RK3366,
};

/*
 *      |  7  |  6  |  5  |  4  |  3  |  2  |  1  |  0  |
 * CS0: |   Mode    |        d        |  c  |  b  |  a  |
 * CS1: |               Category Code                   |
 * CS2: |    Channel Number     |     Source Number     |
 * CS3: |    Clock Accuracy     |     Sample Freq       |
 * CS4: |    Ori Sample Freq    |     Word Length       |
 * CS5: |                                   |   CGMS-A  |
 * CS6~CS23: Reserved
 *
 * a: use of channel status block
 * b: linear PCM identification: 0 for lpcm, 1 for nlpcm
 * c: copyright information
 * d: additional format information
 */
#define CS_BYTE			6
#define CS_FRAME(c)		((c) << 16 | (c))

#define RK3288_GRF_SOC_CON2	0x24c

struct rk_spdif_dev {
@@ -88,8 +107,20 @@ static int rk_spdif_hw_params(struct snd_pcm_substream *substream,
	struct rk_spdif_dev *spdif = snd_soc_dai_get_drvdata(dai);
	unsigned int mclk_rate = clk_get_rate(spdif->mclk);
	unsigned int val = SPDIF_CFGR_HALFWORD_ENABLE;
	int bmc, div;
	int ret;
	int bmc, div, ret, i;
	u16 *fc;
	u8 cs[CS_BYTE];

	ret = snd_pcm_create_iec958_consumer_hw_params(params, cs, sizeof(cs));
	if (ret < 0)
		return ret;

	fc = (u16 *)cs;
	for (i = 0; i < CS_BYTE / 2; i++)
		regmap_write(spdif->regmap, SPDIF_CHNSRn(i), CS_FRAME(fc[i]));

	regmap_update_bits(spdif->regmap, SPDIF_CFGR, SPDIF_CFGR_CSE_MASK,
			   SPDIF_CFGR_CSE_EN);

	/* bmc = 128fs */
	bmc = 128 * params_rate(params);
@@ -239,6 +270,9 @@ static bool rk_spdif_wr_reg(struct device *dev, unsigned int reg)
	case SPDIF_INTCR:
	case SPDIF_XFER:
	case SPDIF_SMPDR:
	case SPDIF_VLDFRn(0) ... SPDIF_VLDFRn(11):
	case SPDIF_USRDRn(0) ... SPDIF_USRDRn(11):
	case SPDIF_CHNSRn(0) ... SPDIF_CHNSRn(11):
		return true;
	default:
		return false;
@@ -254,6 +288,9 @@ static bool rk_spdif_rd_reg(struct device *dev, unsigned int reg)
	case SPDIF_INTSR:
	case SPDIF_XFER:
	case SPDIF_SMPDR:
	case SPDIF_VLDFRn(0) ... SPDIF_VLDFRn(11):
	case SPDIF_USRDRn(0) ... SPDIF_USRDRn(11):
	case SPDIF_CHNSRn(0) ... SPDIF_CHNSRn(11):
		return true;
	default:
		return false;
@@ -276,7 +313,7 @@ static const struct regmap_config rk_spdif_regmap_config = {
	.reg_bits = 32,
	.reg_stride = 4,
	.val_bits = 32,
	.max_register = SPDIF_SMPDR,
	.max_register = SPDIF_VERSION,
	.writeable_reg = rk_spdif_wr_reg,
	.readable_reg = rk_spdif_rd_reg,
	.volatile_reg = rk_spdif_volatile_reg,
+8 −0
Original line number Diff line number Diff line
@@ -21,6 +21,10 @@
#define SPDIF_CFGR_CLR_EN		BIT(7)
#define SPDIF_CFGR_CLR_DIS		0

#define SPDIF_CFGR_CSE_MASK		BIT(6)
#define SPDIF_CFGR_CSE_EN		BIT(6)
#define SPDIF_CFGR_CSE_DIS		0

#define SPDIF_CFGR_ADJ_MASK		BIT(3)
#define SPDIF_CFGR_ADJ_LEFT_J		BIT(3)
#define SPDIF_CFGR_ADJ_RIGHT_J		0
@@ -64,5 +68,9 @@
#define SPDIF_INTSR	(0x0010)
#define SPDIF_XFER	(0x0018)
#define SPDIF_SMPDR	(0x0020)
#define SPDIF_VLDFRn(x)	(0x0060 + (x) * 4)
#define SPDIF_USRDRn(x)	(0x0090 + (x) * 4)
#define SPDIF_CHNSRn(x)	(0x00c0 + (x) * 4)
#define SPDIF_VERSION	(0x01c0)

#endif /* _ROCKCHIP_SPDIF_H */