Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8938ad33 authored by Damir Didjusto's avatar Damir Didjusto
Browse files

ASoC: wcd9306: Add DMIC sample rate support to wcd9306



Add the capability to read DMIC sample rate from device
tree file to wcd9306. This enables different sample rates
without changing the codec driver.

CRs-fixed: 542737
Change-Id: I436df2114f9f19cb6a17c8e700df2654deede7e1
Signed-off-by: default avatarDamir Didjusto <damird@codeaurora.org>
parent 3e2b941d
Loading
Loading
Loading
Loading
+11 −11
Original line number Diff line number Diff line
@@ -1451,23 +1451,23 @@ static struct wcd9xxx_pdata *wcd9xxx_populate_dt_pdata(struct device *dev)
		dev_err(dev, "Looking up %s property in node %s failed",
			"qcom,cdc-dmic-sample-rate",
			dev->of_node->full_name);
		dmic_sample_rate = TAIKO_DMIC_SAMPLE_RATE_UNDEFINED;
		dmic_sample_rate = WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED;
	}
	if (pdata->mclk_rate == TAIKO_MCLK_CLK_9P6HZ) {
		if ((dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_2P4MHZ) &&
		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_3P2MHZ) &&
		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_4P8MHZ) &&
		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_UNDEFINED)) {
	if (pdata->mclk_rate == WCD9XXX_MCLK_CLK_9P6HZ) {
		if ((dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ) &&
		    (dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_3P2MHZ) &&
		    (dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ) &&
		    (dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED)) {
			dev_err(dev, "Invalid dmic rate %d for mclk %d\n",
				dmic_sample_rate, pdata->mclk_rate);
			ret = -EINVAL;
			goto err;
		}
	} else if (pdata->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ) {
		if ((dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_3P072MHZ) &&
		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_4P096MHZ) &&
		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_6P144MHZ) &&
		    (dmic_sample_rate != TAIKO_DMIC_SAMPLE_RATE_UNDEFINED)) {
	} else if (pdata->mclk_rate == WCD9XXX_MCLK_CLK_12P288MHZ) {
		if ((dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_3P072MHZ) &&
		    (dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ) &&
		    (dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_6P144MHZ) &&
		    (dmic_sample_rate != WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED)) {
			dev_err(dev, "Invalid dmic rate %d for mclk %d\n",
				dmic_sample_rate, pdata->mclk_rate);
			ret = -EINVAL;
+9 −9
Original line number Diff line number Diff line
@@ -69,20 +69,20 @@
#define TABLA_DCYCLE_3839 0xE
#define TABLA_DCYCLE_4095 0xF

#define TAIKO_MCLK_CLK_12P288MHZ 12288000
#define TAIKO_MCLK_CLK_9P6HZ 9600000
#define WCD9XXX_MCLK_CLK_12P288MHZ 12288000
#define WCD9XXX_MCLK_CLK_9P6HZ 9600000

/* Only valid for 9.6 MHz mclk */
#define TAIKO_DMIC_SAMPLE_RATE_2P4MHZ 2400000
#define TAIKO_DMIC_SAMPLE_RATE_3P2MHZ 3200000
#define TAIKO_DMIC_SAMPLE_RATE_4P8MHZ 4800000
#define WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ 2400000
#define WCD9XXX_DMIC_SAMPLE_RATE_3P2MHZ 3200000
#define WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ 4800000

/* Only valid for 12.288 MHz mclk */
#define TAIKO_DMIC_SAMPLE_RATE_3P072MHZ 3072000
#define TAIKO_DMIC_SAMPLE_RATE_4P096MHZ 4096000
#define TAIKO_DMIC_SAMPLE_RATE_6P144MHZ 6144000
#define WCD9XXX_DMIC_SAMPLE_RATE_3P072MHZ 3072000
#define WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ 4096000
#define WCD9XXX_DMIC_SAMPLE_RATE_6P144MHZ 6144000

#define TAIKO_DMIC_SAMPLE_RATE_UNDEFINED 0
#define WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED 0

struct wcd9xxx_amic {
	/*legacy mode, txfe_enable and txfe_buff take 7 input
+75 −9
Original line number Diff line number Diff line
@@ -4621,6 +4621,9 @@ static int tapan_handle_pdata(struct tapan_priv *tapan)
	u8 flag = pdata->amic_settings.use_pdata;
	u8 i = 0, j = 0;
	u8 val_txfe = 0, value = 0;
	u8 dmic_sample_rate_value = 0;
	u8 dmic_b1_ctl_value = 0;
	u8 anc_ctl_value = 0;

	if (!pdata) {
		dev_err(codec->dev, "%s: NULL pdata\n", __func__);
@@ -4714,6 +4717,78 @@ static int tapan_handle_pdata(struct tapan_priv *tapan)
		 0x00 : 0x10);
	snd_soc_update_bits(codec, TAPAN_A_MICB_3_CTL, 0x10, value);

	/* Set the DMIC sample rate */
	if (pdata->mclk_rate == TAPAN_MCLK_CLK_9P6MHZ) {
		switch (pdata->dmic_sample_rate) {
		case WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ:
			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_4;
			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_4;
			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
			break;
		case WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ:
			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_2;
			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_2;
			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_ON;
			break;
		case WCD9XXX_DMIC_SAMPLE_RATE_3P2MHZ:
		case WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED:
			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_3;
			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_3;
			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
			break;
		default:
			dev_err(codec->dev,
				"%s Invalid sample rate %d for mclk %d\n",
				__func__, pdata->dmic_sample_rate,
				pdata->mclk_rate);
			rc = -EINVAL;
			goto done;
		}
	} else if (pdata->mclk_rate == TAPAN_MCLK_CLK_12P288MHZ) {
		switch (pdata->dmic_sample_rate) {
		case WCD9XXX_DMIC_SAMPLE_RATE_3P072MHZ:
			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_4;
			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_4;
			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
			break;
		case WCD9XXX_DMIC_SAMPLE_RATE_6P144MHZ:
			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_2;
			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_2;
			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_ON;
			break;
		case WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ:
		case WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED:
			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_3;
			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_3;
			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
			break;
		default:
			dev_err(codec->dev,
				"%s Invalid sample rate %d for mclk %d\n",
				__func__, pdata->dmic_sample_rate,
				pdata->mclk_rate);
			rc = -EINVAL;
			goto done;
		}
	} else {
		dev_err(codec->dev, "%s MCLK is not set!\n", __func__);
		rc = -EINVAL;
		goto done;
	}

	snd_soc_update_bits(codec, TAPAN_A_CDC_TX1_DMIC_CTL,
		0x7, dmic_sample_rate_value);
	snd_soc_update_bits(codec, TAPAN_A_CDC_TX2_DMIC_CTL,
		0x7, dmic_sample_rate_value);
	snd_soc_update_bits(codec, TAPAN_A_CDC_TX3_DMIC_CTL,
		0x7, dmic_sample_rate_value);
	snd_soc_update_bits(codec, TAPAN_A_CDC_TX4_DMIC_CTL,
		0x7, dmic_sample_rate_value);
	snd_soc_update_bits(codec, TAPAN_A_CDC_CLK_DMIC_B1_CTL,
		0xEE, dmic_b1_ctl_value);
	snd_soc_update_bits(codec, TAPAN_A_CDC_ANC1_B2_CTL,
		0x1, anc_ctl_value);

done:
	return rc;
}
@@ -4907,15 +4982,6 @@ static const struct tapan_reg_mask_val tapan_codec_reg_init_val[] = {
	{TAPAN_A_CDC_TX3_MUX_CTL, 0x8, 0x0},
	{TAPAN_A_CDC_TX4_MUX_CTL, 0x8, 0x0},

	/* config Decimator for DMIC CLK_MODE_1(3.2Mhz@9.6Mhz mclk) */
	{TAPAN_A_CDC_TX1_DMIC_CTL, 0x7, 0x1},
	{TAPAN_A_CDC_TX2_DMIC_CTL, 0x7, 0x1},
	{TAPAN_A_CDC_TX3_DMIC_CTL, 0x7, 0x1},
	{TAPAN_A_CDC_TX4_DMIC_CTL, 0x7, 0x1},

	/* config DMIC clk to CLK_MODE_1 (3.2Mhz@9.6Mhz mclk) */
	{TAPAN_A_CDC_CLK_DMIC_B1_CTL, 0xEE, 0x22},

	/* Compander zone selection */
	{TAPAN_A_CDC_COMP0_B4_CTL, 0x3F, 0x37},
	{TAPAN_A_CDC_COMP1_B4_CTL, 0x3F, 0x37},
+32 −47
Original line number Diff line number Diff line
@@ -248,21 +248,6 @@ MODULE_PARM_DESC(spkr_drv_wrnd,

#define TAIKO_I2S_MASTER_MODE_MASK 0x08

#define TAIKO_DMIC_SAMPLE_RATE_DIV_2	0x0
#define TAIKO_DMIC_SAMPLE_RATE_DIV_3	0x1
#define TAIKO_DMIC_SAMPLE_RATE_DIV_4	0x2

#define TAIKO_DMIC_B1_CTL_DIV_2 0x00
#define TAIKO_DMIC_B1_CTL_DIV_3 0x22
#define TAIKO_DMIC_B1_CTL_DIV_4 0x44

#define TAIKO_DMIC_B2_CTL_DIV_2 0x00
#define TAIKO_DMIC_B2_CTL_DIV_3 0x02
#define TAIKO_DMIC_B2_CTL_DIV_4 0x04

#define TAIKO_ANC_DMIC_X2_ON	0x1
#define TAIKO_ANC_DMIC_X2_OFF	0x0

#define TAIKO_SLIM_CLOSE_TIMEOUT 1000
#define TAIKO_SLIM_IRQ_OVERFLOW (1 << 0)
#define TAIKO_SLIM_IRQ_UNDERFLOW (1 << 1)
@@ -5789,24 +5774,24 @@ static int taiko_handle_pdata(struct taiko_priv *taiko)
	/* Set the DMIC sample rate */
	if (pdata->mclk_rate == TAIKO_MCLK_CLK_9P6MHZ) {
		switch (pdata->dmic_sample_rate) {
		case TAIKO_DMIC_SAMPLE_RATE_2P4MHZ:
			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_4;
			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_4;
			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_4;
			anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
		case WCD9XXX_DMIC_SAMPLE_RATE_2P4MHZ:
			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_4;
			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_4;
			dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_4;
			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
			break;
		case TAIKO_DMIC_SAMPLE_RATE_4P8MHZ:
			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_2;
			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_2;
			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_2;
			anc_ctl_value = TAIKO_ANC_DMIC_X2_ON;
		case WCD9XXX_DMIC_SAMPLE_RATE_4P8MHZ:
			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_2;
			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_2;
			dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_2;
			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_ON;
			break;
		case TAIKO_DMIC_SAMPLE_RATE_3P2MHZ:
		case TAIKO_DMIC_SAMPLE_RATE_UNDEFINED:
			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_3;
			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_3;
			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_3;
			anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
		case WCD9XXX_DMIC_SAMPLE_RATE_3P2MHZ:
		case WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED:
			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_3;
			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_3;
			dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_3;
			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
			break;
		default:
			pr_err("%s Invalid sample rate %d for mclk %d\n",
@@ -5817,24 +5802,24 @@ static int taiko_handle_pdata(struct taiko_priv *taiko)
		}
	} else if (pdata->mclk_rate == TAIKO_MCLK_CLK_12P288MHZ) {
		switch (pdata->dmic_sample_rate) {
		case TAIKO_DMIC_SAMPLE_RATE_3P072MHZ:
			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_4;
			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_4;
			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_4;
			anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
		case WCD9XXX_DMIC_SAMPLE_RATE_3P072MHZ:
			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_4;
			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_4;
			dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_4;
			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
			break;
		case TAIKO_DMIC_SAMPLE_RATE_6P144MHZ:
			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_2;
			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_2;
			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_2;
			anc_ctl_value = TAIKO_ANC_DMIC_X2_ON;
		case WCD9XXX_DMIC_SAMPLE_RATE_6P144MHZ:
			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_2;
			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_2;
			dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_2;
			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_ON;
			break;
		case TAIKO_DMIC_SAMPLE_RATE_4P096MHZ:
		case TAIKO_DMIC_SAMPLE_RATE_UNDEFINED:
			dmic_sample_rate_value = TAIKO_DMIC_SAMPLE_RATE_DIV_3;
			dmic_b1_ctl_value = TAIKO_DMIC_B1_CTL_DIV_3;
			dmic_b2_ctl_value = TAIKO_DMIC_B2_CTL_DIV_3;
			anc_ctl_value = TAIKO_ANC_DMIC_X2_OFF;
		case WCD9XXX_DMIC_SAMPLE_RATE_4P096MHZ:
		case WCD9XXX_DMIC_SAMPLE_RATE_UNDEFINED:
			dmic_sample_rate_value = WCD9XXX_DMIC_SAMPLE_RATE_DIV_3;
			dmic_b1_ctl_value = WCD9XXX_DMIC_B1_CTL_DIV_3;
			dmic_b2_ctl_value = WCD9XXX_DMIC_B2_CTL_DIV_3;
			anc_ctl_value = WCD9XXX_ANC_DMIC_X2_OFF;
			break;
		default:
			pr_err("%s Invalid sample rate %d for mclk %d\n",
+15 −0
Original line number Diff line number Diff line
@@ -37,6 +37,21 @@
#define	WCD9XXX_CLSH_STATE_LO (0x01 << 3)
#define NUM_CLSH_STATES ((0x01 << 4) - 1)

#define WCD9XXX_DMIC_SAMPLE_RATE_DIV_2    0x0
#define WCD9XXX_DMIC_SAMPLE_RATE_DIV_3    0x1
#define WCD9XXX_DMIC_SAMPLE_RATE_DIV_4    0x2

#define WCD9XXX_DMIC_B1_CTL_DIV_2 0x00
#define WCD9XXX_DMIC_B1_CTL_DIV_3 0x22
#define WCD9XXX_DMIC_B1_CTL_DIV_4 0x44

#define WCD9XXX_DMIC_B2_CTL_DIV_2 0x00
#define WCD9XXX_DMIC_B2_CTL_DIV_3 0x02
#define WCD9XXX_DMIC_B2_CTL_DIV_4 0x04

#define WCD9XXX_ANC_DMIC_X2_ON    0x1
#define WCD9XXX_ANC_DMIC_X2_OFF   0x0

/* Derived State: Bits 1 and 2 should be set for Headphone stereo */
#define WCD9XXX_CLSH_STATE_HPH_ST (WCD9XXX_CLSH_STATE_HPHL | \
						WCD9XXX_CLSH_STATE_HPHR)