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

Commit d6aaaff8 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: wcd9xxx: Add support for 24-bit playback for WCD9306"

parents b235a4b2 9d35aa1e
Loading
Loading
Loading
Loading
+70 −26
Original line number Diff line number Diff line
@@ -43,6 +43,8 @@
#define TAPAN_HPH_PA_SETTLE_COMP_OFF 13000

#define DAPM_MICBIAS2_EXTERNAL_STANDALONE "MIC BIAS2 External Standalone"
#define TAPAN_VALIDATE_RX_SBPORT_RANGE(port) ((port >= 16) && (port <= 20))
#define TAPAN_CONVERT_RX_SBPORT_ID(port) (port - 16) /* RX1 port ID = 0 */

#define TAPAN_VDD_CX_OPTIMAL_UA 10000
#define TAPAN_VDD_CX_SLEEP_UA 2000
@@ -3279,6 +3281,8 @@ static int tapan_volatile(struct snd_soc_codec *ssc, unsigned int reg)
}

#define TAPAN_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
#define TAPAN_FORMATS_S16_S24_LE (SNDRV_PCM_FMTBIT_S16_LE | \
				  SNDRV_PCM_FORMAT_S24_LE)
static int tapan_write(struct snd_soc_codec *codec, unsigned int reg,
	unsigned int value)
{
@@ -3686,6 +3690,68 @@ static int tapan_set_decimator_rate(struct snd_soc_dai *dai,
	return 0;
}

static void tapan_set_rxsb_port_format(struct snd_pcm_hw_params *params,
				       struct snd_soc_dai *dai)
{
	struct snd_soc_codec *codec = dai->codec;
	struct tapan_priv *tapan_p = snd_soc_codec_get_drvdata(codec);
	struct wcd9xxx_codec_dai_data *cdc_dai;
	struct wcd9xxx_ch *ch;
	int port;
	u8 bit_sel;
	u16 sb_ctl_reg, field_shift;

	switch (params_format(params)) {
	case SNDRV_PCM_FORMAT_S16_LE:
		bit_sel = 0x2;
		tapan_p->dai[dai->id].bit_width = 16;
		break;
	case SNDRV_PCM_FORMAT_S24_LE:
		bit_sel = 0x0;
		tapan_p->dai[dai->id].bit_width = 24;
		break;
	default:
		dev_err(codec->dev, "Invalid format %x\n",
			params_format(params));
		return;
	}

	cdc_dai = &tapan_p->dai[dai->id];

	list_for_each_entry(ch, &cdc_dai->wcd9xxx_ch_list, list) {
		port = wcd9xxx_get_slave_port(ch->ch_num);

		if (IS_ERR_VALUE(port) ||
		    !TAPAN_VALIDATE_RX_SBPORT_RANGE(port)) {
			dev_warn(codec->dev,
				 "%s: invalid port ID %d returned for RX DAI\n",
				 __func__, port);
			return;
		}

		port = TAPAN_CONVERT_RX_SBPORT_ID(port);

		if (port <= 3) {
			sb_ctl_reg = TAPAN_A_CDC_CONN_RX_SB_B1_CTL;
			field_shift = port << 1;
		} else if (port <= 4) {
			sb_ctl_reg = TAPAN_A_CDC_CONN_RX_SB_B2_CTL;
			field_shift = (port - 4) << 1;
		} else { /* should not happen */
			dev_warn(codec->dev,
				 "%s: bad port ID %d\n", __func__, port);
			return;
		}

		dev_dbg(codec->dev, "%s: sb_ctl_reg %x field_shift %x\n"
			"bit_sel %x\n", __func__, sb_ctl_reg, field_shift,
			bit_sel);
		snd_soc_update_bits(codec, sb_ctl_reg, 0x3 << field_shift,
				    bit_sel << field_shift);
	}
}


static int tapan_hw_params(struct snd_pcm_substream *substream,
			    struct snd_pcm_hw_params *params,
			    struct snd_soc_dai *dai)
@@ -3798,29 +3864,7 @@ static int tapan_hw_params(struct snd_pcm_substream *substream,
			snd_soc_update_bits(codec, TAPAN_A_CDC_CLK_I2S_CTL,
					    0x03, (rx_fs_rate >> 0x05));
		} else {
			switch (params_format(params)) {
			case SNDRV_PCM_FORMAT_S16_LE:
				snd_soc_update_bits(codec,
					TAPAN_A_CDC_CONN_RX_SB_B1_CTL,
					0xFF, 0xAA);
				snd_soc_update_bits(codec,
					TAPAN_A_CDC_CONN_RX_SB_B2_CTL,
					0xFF, 0x2A);
				tapan->dai[dai->id].bit_width = 16;
				break;
			case SNDRV_PCM_FORMAT_S24_LE:
				snd_soc_update_bits(codec,
					TAPAN_A_CDC_CONN_RX_SB_B1_CTL,
					0xFF, 0x00);
				snd_soc_update_bits(codec,
					TAPAN_A_CDC_CONN_RX_SB_B2_CTL,
					0xFF, 0x00);
				tapan->dai[dai->id].bit_width = 24;
				break;
			default:
				dev_err(codec->dev, "Invalid format\n");
				break;
			}
			tapan_set_rxsb_port_format(params, dai);
			tapan->dai[dai->id].rate   = params_rate(params);
		}
		break;
@@ -3937,7 +3981,7 @@ static struct snd_soc_dai_driver tapan_dai[] = {
		.playback = {
			.stream_name = "AIF1 Playback",
			.rates = WCD9306_RATES,
			.formats = TAPAN_FORMATS,
			.formats = TAPAN_FORMATS_S16_S24_LE,
			.rate_max = 192000,
			.rate_min = 8000,
			.channels_min = 1,
@@ -3965,7 +4009,7 @@ static struct snd_soc_dai_driver tapan_dai[] = {
		.playback = {
			.stream_name = "AIF2 Playback",
			.rates = WCD9306_RATES,
			.formats = TAPAN_FORMATS,
			.formats = TAPAN_FORMATS_S16_S24_LE,
			.rate_min = 8000,
			.rate_max = 192000,
			.channels_min = 1,
@@ -3993,7 +4037,7 @@ static struct snd_soc_dai_driver tapan_dai[] = {
		.playback = {
			.stream_name = "AIF3 Playback",
			.rates = WCD9306_RATES,
			.formats = TAPAN_FORMATS,
			.formats = TAPAN_FORMATS_S16_S24_LE,
			.rate_min = 8000,
			.rate_max = 192000,
			.channels_min = 1,