Unverified Commit 21b15926 authored by Mark Brown's avatar Mark Brown
Browse files

Support BCLK input clock in tlv320aic31xx

Merge series from Ariel D'Alessandro <ariel.dalessandro@collabora.com>:

	This patchset modifies the tlv320aic31xx driver to update its sysclk if
	BCLK is used as the input clock. This allows to be used by the generic
	fsl-asoc-card, without having to add a specific driver.
parents 27744454 8c9b9cfb
Loading
Loading
Loading
Loading
+70 −35
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
@@ -169,6 +170,7 @@ struct aic31xx_priv {
	struct regulator_bulk_data supplies[AIC31XX_NUM_SUPPLIES];
	struct aic31xx_disable_nb disable_nb[AIC31XX_NUM_SUPPLIES];
	struct snd_soc_jack *jack;
	u32 sysclk_id;
	unsigned int sysclk;
	u8 p_div;
	int rate_div_line;
@@ -180,6 +182,7 @@ struct aic31xx_priv {
struct aic31xx_rate_divs {
	u32 mclk_p;
	u32 rate;
	u8 pll_r;
	u8 pll_j;
	u16 pll_d;
	u16 dosr;
@@ -192,51 +195,71 @@ struct aic31xx_rate_divs {

/* ADC dividers can be disabled by configuring them to 0 */
static const struct aic31xx_rate_divs aic31xx_divs[] = {
	/* mclk/p    rate  pll: j     d        dosr ndac mdac  aors nadc madc */
	/* mclk/p    rate  pll: r  j     d     dosr ndac mdac  aors nadc madc */
	/* 8k rate */
	{12000000,   8000,	8, 1920,	128,  48,  2,	128,  48,  2},
	{12000000,   8000,	8, 1920,	128,  32,  3,	128,  32,  3},
	{12500000,   8000,	7, 8643,	128,  48,  2,	128,  48,  2},
	{  512000,   8000,	4, 48,   0,	128,  48,  2,   128,  48,  2},
	{12000000,   8000,	1, 8, 1920,	128,  48,  2,	128,  48,  2},
	{12000000,   8000,	1, 8, 1920,	128,  32,  3,	128,  32,  3},
	{12500000,   8000,	1, 7, 8643,	128,  48,  2,	128,  48,  2},
	/* 11.025k rate */
	{12000000,  11025,	7, 5264,	128,  32,  2,	128,  32,  2},
	{12000000,  11025,	8, 4672,	128,  24,  3,	128,  24,  3},
	{12500000,  11025,	7, 2253,	128,  32,  2,	128,  32,  2},
	{  705600,  11025,	3, 48,   0,	128,  24,  3,	128,  24,  3},
	{12000000,  11025,	1, 7, 5264,	128,  32,  2,	128,  32,  2},
	{12000000,  11025,	1, 8, 4672,	128,  24,  3,	128,  24,  3},
	{12500000,  11025,	1, 7, 2253,	128,  32,  2,	128,  32,  2},
	/* 16k rate */
	{12000000,  16000,	8, 1920,	128,  24,  2,	128,  24,  2},
	{12000000,  16000,	8, 1920,	128,  16,  3,	128,  16,  3},
	{12500000,  16000,	7, 8643,	128,  24,  2,	128,  24,  2},
	{  512000,  16000,	4, 48,   0,	128,  16,  3,	128,  16,  3},
	{ 1024000,  16000,	2, 48,   0,	128,  16,  3,	128,  16,  3},
	{12000000,  16000,	1, 8, 1920,	128,  24,  2,	128,  24,  2},
	{12000000,  16000,	1, 8, 1920,	128,  16,  3,	128,  16,  3},
	{12500000,  16000,	1, 7, 8643,	128,  24,  2,	128,  24,  2},
	/* 22.05k rate */
	{12000000,  22050,	7, 5264,	128,  16,  2,	128,  16,  2},
	{12000000,  22050,	8, 4672,	128,  12,  3,	128,  12,  3},
	{12500000,  22050,	7, 2253,	128,  16,  2,	128,  16,  2},
	{  705600,  22050,	4, 36,   0,	128,  12,  3,	128,  12,  3},
	{ 1411200,  22050,	2, 36,   0,	128,  12,  3,	128,  12,  3},
	{12000000,  22050,	1, 7, 5264,	128,  16,  2,	128,  16,  2},
	{12000000,  22050,	1, 8, 4672,	128,  12,  3,	128,  12,  3},
	{12500000,  22050,	1, 7, 2253,	128,  16,  2,	128,  16,  2},
	/* 32k rate */
	{12000000,  32000,	8, 1920,	128,  12,  2,	128,  12,  2},
	{12000000,  32000,	8, 1920,	128,   8,  3,	128,   8,  3},
	{12500000,  32000,	7, 8643,	128,  12,  2,	128,  12,  2},
	{ 1024000,  32000,      2, 48,   0,	128,  12,  2,	128,  12,  2},
	{ 2048000,  32000,      1, 48,   0,	128,  12,  2,	128,  12,  2},
	{12000000,  32000,	1, 8, 1920,	128,  12,  2,	128,  12,  2},
	{12000000,  32000,	1, 8, 1920,	128,   8,  3,	128,   8,  3},
	{12500000,  32000,	1, 7, 8643,	128,  12,  2,	128,  12,  2},
	/* 44.1k rate */
	{12000000,  44100,	7, 5264,	128,   8,  2,	128,   8,  2},
	{12000000,  44100,	8, 4672,	128,   6,  3,	128,   6,  3},
	{12500000,  44100,	7, 2253,	128,   8,  2,	128,   8,  2},
	{ 1411200,  44100,	2, 32,   0,	128,   8,  2,	128,   8,  2},
	{ 2822400,  44100,	1, 32,   0,	128,   8,  2,	128,   8,  2},
	{12000000,  44100,	1, 7, 5264,	128,   8,  2,	128,   8,  2},
	{12000000,  44100,	1, 8, 4672,	128,   6,  3,	128,   6,  3},
	{12500000,  44100,	1, 7, 2253,	128,   8,  2,	128,   8,  2},
	/* 48k rate */
	{12000000,  48000,	8, 1920,	128,   8,  2,	128,   8,  2},
	{12000000,  48000,	7, 6800,	 96,   5,  4,	 96,   5,  4},
	{12500000,  48000,	7, 8643,	128,   8,  2,	128,   8,  2},
	{ 1536000,  48000,	2, 32,   0,	128,   8,  2,	128,   8,  2},
	{ 3072000,  48000,	1, 32,   0,	128,   8,  2,	128,   8,  2},
	{12000000,  48000,	1, 8, 1920,	128,   8,  2,	128,   8,  2},
	{12000000,  48000,	1, 7, 6800,	 96,   5,  4,	 96,   5,  4},
	{12500000,  48000,	1, 7, 8643,	128,   8,  2,	128,   8,  2},
	/* 88.2k rate */
	{12000000,  88200,	7, 5264,	 64,   8,  2,	 64,   8,  2},
	{12000000,  88200,	8, 4672,	 64,   6,  3,	 64,   6,  3},
	{12500000,  88200,	7, 2253,	 64,   8,  2,	 64,   8,  2},
	{ 2822400,  88200,	2, 16,   0,	 64,   8,  2,	 64,   8,  2},
	{ 5644800,  88200,	1, 16,   0,	 64,   8,  2,	 64,   8,  2},
	{12000000,  88200,	1, 7, 5264,	 64,   8,  2,	 64,   8,  2},
	{12000000,  88200,	1, 8, 4672,	 64,   6,  3,	 64,   6,  3},
	{12500000,  88200,	1, 7, 2253,	 64,   8,  2,	 64,   8,  2},
	/* 96k rate */
	{12000000,  96000,	8, 1920,	 64,   8,  2,	 64,   8,  2},
	{12000000,  96000,	7, 6800,	 48,   5,  4,	 48,   5,  4},
	{12500000,  96000,	7, 8643,	 64,   8,  2,	 64,   8,  2},
	{ 3072000,  96000,	2, 16,   0,	 64,   8,  2,	 64,   8,  2},
	{ 6144000,  96000,	1, 16,   0,	 64,   8,  2,	 64,   8,  2},
	{12000000,  96000,	1, 8, 1920,	 64,   8,  2,	 64,   8,  2},
	{12000000,  96000,	1, 7, 6800,	 48,   5,  4,	 48,   5,  4},
	{12500000,  96000,	1, 7, 8643,	 64,   8,  2,	 64,   8,  2},
	/* 176.4k rate */
	{12000000, 176400,	7, 5264,	 32,   8,  2,	 32,   8,  2},
	{12000000, 176400,	8, 4672,	 32,   6,  3,	 32,   6,  3},
	{12500000, 176400,	7, 2253,	 32,   8,  2,	 32,   8,  2},
	{ 5644800, 176400,	2, 8,    0,	 32,   8,  2,	 32,   8,  2},
	{11289600, 176400,	1, 8,    0,	 32,   8,  2,	 32,   8,  2},
	{12000000, 176400,	1, 7, 5264,	 32,   8,  2,	 32,   8,  2},
	{12000000, 176400,	1, 8, 4672,	 32,   6,  3,	 32,   6,  3},
	{12500000, 176400,	1, 7, 2253,	 32,   8,  2,	 32,   8,  2},
	/* 192k rate */
	{12000000, 192000,	8, 1920,	 32,   8,  2,	 32,   8,  2},
	{12000000, 192000,	7, 6800,	 24,   5,  4,	 24,   5,  4},
	{12500000, 192000,	7, 8643,	 32,   8,  2,	 32,   8,  2},
	{ 6144000, 192000,	2, 8,	 0,	 32,   8,  2,	 32,   8,  2},
	{12288000, 192000,	1, 8,	 0,	 32,   8,  2,	 32,   8,  2},
	{12000000, 192000,	1, 8, 1920,	 32,   8,  2,	 32,   8,  2},
	{12000000, 192000,	1, 7, 6800,	 24,   5,  4,	 24,   5,  4},
	{12500000, 192000,	1, 7, 8643,	 32,   8,  2,	 32,   8,  2},
};

static const char * const ldac_in_text[] = {
@@ -888,7 +911,7 @@ static int aic31xx_setup_pll(struct snd_soc_component *component,

	/* PLL configuration */
	snd_soc_component_update_bits(component, AIC31XX_PLLPR, AIC31XX_PLL_MASK,
			    (aic31xx->p_div << 4) | 0x01);
			    (aic31xx->p_div << 4) | aic31xx_divs[i].pll_r);
	snd_soc_component_write(component, AIC31XX_PLLJ, aic31xx_divs[i].pll_j);

	snd_soc_component_write(component, AIC31XX_PLLDMSB,
@@ -941,6 +964,7 @@ static int aic31xx_hw_params(struct snd_pcm_substream *substream,
			     struct snd_soc_dai *dai)
{
	struct snd_soc_component *component = dai->component;
	struct aic31xx_priv *aic31xx = snd_soc_component_get_drvdata(component);
	u8 data = 0;

	dev_dbg(component->dev, "## %s: width %d rate %d\n",
@@ -972,6 +996,16 @@ static int aic31xx_hw_params(struct snd_pcm_substream *substream,
			    AIC31XX_IFACE1_DATALEN_MASK,
			    data);

	/*
	 * If BCLK is used as PLL input, the sysclk is determined by the hw
	 * params. So it must be updated here to match the input frequency.
	 */
	if (aic31xx->sysclk_id == AIC31XX_PLL_CLKIN_BCLK) {
		aic31xx->sysclk = params_rate(params) * params_width(params) *
				  params_channels(params);
		aic31xx->p_div = 1;
	}

	return aic31xx_setup_pll(component, params);
}

@@ -1156,6 +1190,7 @@ static int aic31xx_set_dai_sysclk(struct snd_soc_dai *codec_dai,
	snd_soc_component_update_bits(component, AIC31XX_CLKMUX, AIC31XX_PLL_CLKIN_MASK,
			    clk_id << AIC31XX_PLL_CLKIN_SHIFT);

	aic31xx->sysclk_id = clk_id;
	aic31xx->sysclk = freq;

	return 0;
+1 −1
Original line number Diff line number Diff line
@@ -118,7 +118,7 @@ struct aic31xx_pdata {
#define AIC31XX_PLL_CLKIN_MASK		GENMASK(3, 2)
#define AIC31XX_PLL_CLKIN_SHIFT		(2)
#define AIC31XX_PLL_CLKIN_MCLK		0x00
#define AIC31XX_PLL_CLKIN_BCKL		0x01
#define AIC31XX_PLL_CLKIN_BCLK		0x01
#define AIC31XX_PLL_CLKIN_GPIO1		0x02
#define AIC31XX_PLL_CLKIN_DIN		0x03
#define AIC31XX_CODEC_CLKIN_MASK	GENMASK(1, 0)
+12 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@
#include "../codecs/wm8962.h"
#include "../codecs/wm8960.h"
#include "../codecs/wm8994.h"
#include "../codecs/tlv320aic31xx.h"

#define CS427x_SYSCLK_MCLK 0

@@ -629,6 +630,16 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
	} else if (of_device_is_compatible(np, "fsl,imx-audio-tlv320aic32x4")) {
		codec_dai_name = "tlv320aic32x4-hifi";
		priv->dai_fmt |= SND_SOC_DAIFMT_CBP_CFP;
	} else if (of_device_is_compatible(np, "fsl,imx-audio-tlv320aic31xx")) {
		codec_dai_name = "tlv320dac31xx-hifi";
		priv->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS;
		priv->dai_link[1].dpcm_capture = 0;
		priv->dai_link[2].dpcm_capture = 0;
		priv->cpu_priv.sysclk_dir[TX] = SND_SOC_CLOCK_OUT;
		priv->cpu_priv.sysclk_dir[RX] = SND_SOC_CLOCK_OUT;
		priv->codec_priv.mclk_id = AIC31XX_PLL_CLKIN_BCLK;
		priv->card.dapm_routes = audio_map_tx;
		priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx);
	} else if (of_device_is_compatible(np, "fsl,imx-audio-wm8962")) {
		codec_dai_name = "wm8962";
		priv->codec_priv.mclk_id = WM8962_SYSCLK_MCLK;
@@ -888,6 +899,7 @@ static const struct of_device_id fsl_asoc_card_dt_ids[] = {
	{ .compatible = "fsl,imx-audio-cs42888", },
	{ .compatible = "fsl,imx-audio-cs427x", },
	{ .compatible = "fsl,imx-audio-tlv320aic32x4", },
	{ .compatible = "fsl,imx-audio-tlv320aic31xx", },
	{ .compatible = "fsl,imx-audio-sgtl5000", },
	{ .compatible = "fsl,imx-audio-wm8962", },
	{ .compatible = "fsl,imx-audio-wm8960", },