Loading sound/soc/codecs/wcd9306.c +70 −26 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) { Loading Loading @@ -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) Loading Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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, Loading Loading @@ -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, Loading Loading
sound/soc/codecs/wcd9306.c +70 −26 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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) { Loading Loading @@ -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) Loading Loading @@ -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; Loading Loading @@ -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, Loading Loading @@ -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, Loading Loading @@ -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, Loading