Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'asoc-fix-v5.16-rc3' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Fixes for v5.16

There's a large but repetitive set of fixes here for issues with the
Tegra kcontrols not correctly reporting changes to userspace, a fix for
some issues with matching on older x86 platforms introduced during the
merge window together with a set of smaller fixes and one new system
quirk.

+817 -273
+1 -1
include/sound/soc-acpi.h
··· 147 147 */ 148 148 /* Descriptor for SST ASoC machine driver */ 149 149 struct snd_soc_acpi_mach { 150 - const u8 id[ACPI_ID_LEN]; 150 + u8 id[ACPI_ID_LEN]; 151 151 const struct snd_soc_acpi_codecs *comp_ids; 152 152 const u32 link_mask; 153 153 const struct snd_soc_acpi_link_adr *links;
+3 -29
sound/soc/codecs/cs35l41-spi.c
··· 42 42 43 43 MODULE_DEVICE_TABLE(spi, cs35l41_id_spi); 44 44 45 - static void cs35l41_spi_otp_setup(struct cs35l41_private *cs35l41, 46 - bool is_pre_setup, unsigned int *freq) 47 - { 48 - struct spi_device *spi; 49 - u32 orig_spi_freq; 50 - 51 - spi = to_spi_device(cs35l41->dev); 52 - 53 - if (!spi) { 54 - dev_err(cs35l41->dev, "%s: No SPI device\n", __func__); 55 - return; 56 - } 57 - 58 - if (is_pre_setup) { 59 - orig_spi_freq = spi->max_speed_hz; 60 - if (orig_spi_freq > CS35L41_SPI_MAX_FREQ_OTP) { 61 - spi->max_speed_hz = CS35L41_SPI_MAX_FREQ_OTP; 62 - spi_setup(spi); 63 - } 64 - *freq = orig_spi_freq; 65 - } else { 66 - if (spi->max_speed_hz != *freq) { 67 - spi->max_speed_hz = *freq; 68 - spi_setup(spi); 69 - } 70 - } 71 - } 72 - 73 45 static int cs35l41_spi_probe(struct spi_device *spi) 74 46 { 75 47 const struct regmap_config *regmap_config = &cs35l41_regmap_spi; ··· 53 81 if (!cs35l41) 54 82 return -ENOMEM; 55 83 84 + spi->max_speed_hz = CS35L41_SPI_MAX_FREQ; 85 + spi_setup(spi); 86 + 56 87 spi_set_drvdata(spi, cs35l41); 57 88 cs35l41->regmap = devm_regmap_init_spi(spi, regmap_config); 58 89 if (IS_ERR(cs35l41->regmap)) { ··· 66 91 67 92 cs35l41->dev = &spi->dev; 68 93 cs35l41->irq = spi->irq; 69 - cs35l41->otp_setup = cs35l41_spi_otp_setup; 70 94 71 95 return cs35l41_probe(cs35l41, pdata); 72 96 }
-7
sound/soc/codecs/cs35l41.c
··· 302 302 const struct cs35l41_otp_packed_element_t *otp_map; 303 303 struct cs35l41_private *cs35l41 = data; 304 304 int bit_offset, word_offset, ret, i; 305 - unsigned int orig_spi_freq; 306 305 unsigned int bit_sum = 8; 307 306 u32 otp_val, otp_id_reg; 308 307 u32 *otp_mem; ··· 325 326 goto err_otp_unpack; 326 327 } 327 328 328 - if (cs35l41->otp_setup) 329 - cs35l41->otp_setup(cs35l41, true, &orig_spi_freq); 330 - 331 329 ret = regmap_bulk_read(cs35l41->regmap, CS35L41_OTP_MEM0, otp_mem, 332 330 CS35L41_OTP_SIZE_WORDS); 333 331 if (ret < 0) { 334 332 dev_err(cs35l41->dev, "Read OTP Mem failed: %d\n", ret); 335 333 goto err_otp_unpack; 336 334 } 337 - 338 - if (cs35l41->otp_setup) 339 - cs35l41->otp_setup(cs35l41, false, &orig_spi_freq); 340 335 341 336 otp_map = otp_map_match->map; 342 337
+1 -3
sound/soc/codecs/cs35l41.h
··· 726 726 #define CS35L41_FS2_WINDOW_MASK 0x00FFF800 727 727 #define CS35L41_FS2_WINDOW_SHIFT 12 728 728 729 - #define CS35L41_SPI_MAX_FREQ_OTP 4000000 729 + #define CS35L41_SPI_MAX_FREQ 4000000 730 730 731 731 #define CS35L41_RX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) 732 732 #define CS35L41_TX_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE) ··· 764 764 int irq; 765 765 /* GPIO for /RST */ 766 766 struct gpio_desc *reset_gpio; 767 - void (*otp_setup)(struct cs35l41_private *cs35l41, bool is_pre_setup, 768 - unsigned int *freq); 769 767 }; 770 768 771 769 int cs35l41_probe(struct cs35l41_private *cs35l41,
+1
sound/soc/codecs/rk817_codec.c
··· 539 539 MODULE_DESCRIPTION("ASoC RK817 codec driver"); 540 540 MODULE_AUTHOR("binyuan <kevan.lan@rock-chips.com>"); 541 541 MODULE_LICENSE("GPL v2"); 542 + MODULE_ALIAS("platform:rk817-codec");
+6
sound/soc/intel/common/soc-acpi-intel-cml-match.c
··· 81 81 .sof_fw_filename = "sof-cml.ri", 82 82 .sof_tplg_filename = "sof-cml-da7219-max98390.tplg", 83 83 }, 84 + { 85 + .id = "ESSX8336", 86 + .drv_name = "sof-essx8336", 87 + .sof_fw_filename = "sof-cml.ri", 88 + .sof_tplg_filename = "sof-cml-es8336.tplg", 89 + }, 84 90 {}, 85 91 }; 86 92 EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_cml_machines);
+3 -1
sound/soc/soc-acpi.c
··· 20 20 21 21 if (comp_ids) { 22 22 for (i = 0; i < comp_ids->num_codecs; i++) { 23 - if (acpi_dev_present(comp_ids->codecs[i], NULL, -1)) 23 + if (acpi_dev_present(comp_ids->codecs[i], NULL, -1)) { 24 + strscpy(machine->id, comp_ids->codecs[i], ACPI_ID_LEN); 24 25 return true; 26 + } 25 27 } 26 28 } 27 29
+7
sound/soc/sof/intel/hda.c
··· 58 58 return -EINVAL; 59 59 } 60 60 61 + /* DAI already configured, reset it before reconfiguring it */ 62 + if (sof_dai->configured) { 63 + ret = hda_ctrl_dai_widget_free(w); 64 + if (ret < 0) 65 + return ret; 66 + } 67 + 61 68 config = &sof_dai->dai_config[sof_dai->current_config]; 62 69 63 70 /*
+146 -33
sound/soc/tegra/tegra186_dspk.c
··· 26 26 { TEGRA186_DSPK_CODEC_CTRL, 0x03000000 }, 27 27 }; 28 28 29 - static int tegra186_dspk_get_control(struct snd_kcontrol *kcontrol, 29 + static int tegra186_dspk_get_fifo_th(struct snd_kcontrol *kcontrol, 30 30 struct snd_ctl_elem_value *ucontrol) 31 31 { 32 32 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 33 33 struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); 34 34 35 - if (strstr(kcontrol->id.name, "FIFO Threshold")) 36 - ucontrol->value.integer.value[0] = dspk->rx_fifo_th; 37 - else if (strstr(kcontrol->id.name, "OSR Value")) 38 - ucontrol->value.integer.value[0] = dspk->osr_val; 39 - else if (strstr(kcontrol->id.name, "LR Polarity Select")) 40 - ucontrol->value.integer.value[0] = dspk->lrsel; 41 - else if (strstr(kcontrol->id.name, "Channel Select")) 42 - ucontrol->value.integer.value[0] = dspk->ch_sel; 43 - else if (strstr(kcontrol->id.name, "Mono To Stereo")) 44 - ucontrol->value.integer.value[0] = dspk->mono_to_stereo; 45 - else if (strstr(kcontrol->id.name, "Stereo To Mono")) 46 - ucontrol->value.integer.value[0] = dspk->stereo_to_mono; 35 + ucontrol->value.integer.value[0] = dspk->rx_fifo_th; 47 36 48 37 return 0; 49 38 } 50 39 51 - static int tegra186_dspk_put_control(struct snd_kcontrol *kcontrol, 40 + static int tegra186_dspk_put_fifo_th(struct snd_kcontrol *kcontrol, 52 41 struct snd_ctl_elem_value *ucontrol) 53 42 { 54 43 struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 55 44 struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); 56 - int val = ucontrol->value.integer.value[0]; 45 + int value = ucontrol->value.integer.value[0]; 57 46 58 - if (strstr(kcontrol->id.name, "FIFO Threshold")) 59 - dspk->rx_fifo_th = val; 60 - else if (strstr(kcontrol->id.name, "OSR Value")) 61 - dspk->osr_val = val; 62 - else if (strstr(kcontrol->id.name, "LR Polarity Select")) 63 - dspk->lrsel = val; 64 - else if (strstr(kcontrol->id.name, "Channel Select")) 65 - dspk->ch_sel = val; 66 - else if (strstr(kcontrol->id.name, "Mono To Stereo")) 67 - dspk->mono_to_stereo = val; 68 - else if (strstr(kcontrol->id.name, "Stereo To Mono")) 69 - dspk->stereo_to_mono = val; 47 + if (value == dspk->rx_fifo_th) 48 + return 0; 49 + 50 + dspk->rx_fifo_th = value; 51 + 52 + return 1; 53 + } 54 + 55 + static int tegra186_dspk_get_osr_val(struct snd_kcontrol *kcontrol, 56 + struct snd_ctl_elem_value *ucontrol) 57 + { 58 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 59 + struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); 60 + 61 + ucontrol->value.enumerated.item[0] = dspk->osr_val; 70 62 71 63 return 0; 64 + } 65 + 66 + static int tegra186_dspk_put_osr_val(struct snd_kcontrol *kcontrol, 67 + struct snd_ctl_elem_value *ucontrol) 68 + { 69 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 70 + struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); 71 + unsigned int value = ucontrol->value.enumerated.item[0]; 72 + 73 + if (value == dspk->osr_val) 74 + return 0; 75 + 76 + dspk->osr_val = value; 77 + 78 + return 1; 79 + } 80 + 81 + static int tegra186_dspk_get_pol_sel(struct snd_kcontrol *kcontrol, 82 + struct snd_ctl_elem_value *ucontrol) 83 + { 84 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 85 + struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); 86 + 87 + ucontrol->value.enumerated.item[0] = dspk->lrsel; 88 + 89 + return 0; 90 + } 91 + 92 + static int tegra186_dspk_put_pol_sel(struct snd_kcontrol *kcontrol, 93 + struct snd_ctl_elem_value *ucontrol) 94 + { 95 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 96 + struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); 97 + unsigned int value = ucontrol->value.enumerated.item[0]; 98 + 99 + if (value == dspk->lrsel) 100 + return 0; 101 + 102 + dspk->lrsel = value; 103 + 104 + return 1; 105 + } 106 + 107 + static int tegra186_dspk_get_ch_sel(struct snd_kcontrol *kcontrol, 108 + struct snd_ctl_elem_value *ucontrol) 109 + { 110 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 111 + struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); 112 + 113 + ucontrol->value.enumerated.item[0] = dspk->ch_sel; 114 + 115 + return 0; 116 + } 117 + 118 + static int tegra186_dspk_put_ch_sel(struct snd_kcontrol *kcontrol, 119 + struct snd_ctl_elem_value *ucontrol) 120 + { 121 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 122 + struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); 123 + unsigned int value = ucontrol->value.enumerated.item[0]; 124 + 125 + if (value == dspk->ch_sel) 126 + return 0; 127 + 128 + dspk->ch_sel = value; 129 + 130 + return 1; 131 + } 132 + 133 + static int tegra186_dspk_get_mono_to_stereo(struct snd_kcontrol *kcontrol, 134 + struct snd_ctl_elem_value *ucontrol) 135 + { 136 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 137 + struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); 138 + 139 + ucontrol->value.enumerated.item[0] = dspk->mono_to_stereo; 140 + 141 + return 0; 142 + } 143 + 144 + static int tegra186_dspk_put_mono_to_stereo(struct snd_kcontrol *kcontrol, 145 + struct snd_ctl_elem_value *ucontrol) 146 + { 147 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 148 + struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); 149 + unsigned int value = ucontrol->value.enumerated.item[0]; 150 + 151 + if (value == dspk->mono_to_stereo) 152 + return 0; 153 + 154 + dspk->mono_to_stereo = value; 155 + 156 + return 1; 157 + } 158 + 159 + static int tegra186_dspk_get_stereo_to_mono(struct snd_kcontrol *kcontrol, 160 + struct snd_ctl_elem_value *ucontrol) 161 + { 162 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 163 + struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); 164 + 165 + ucontrol->value.enumerated.item[0] = dspk->stereo_to_mono; 166 + 167 + return 0; 168 + } 169 + 170 + static int tegra186_dspk_put_stereo_to_mono(struct snd_kcontrol *kcontrol, 171 + struct snd_ctl_elem_value *ucontrol) 172 + { 173 + struct snd_soc_component *codec = snd_soc_kcontrol_component(kcontrol); 174 + struct tegra186_dspk *dspk = snd_soc_component_get_drvdata(codec); 175 + unsigned int value = ucontrol->value.enumerated.item[0]; 176 + 177 + if (value == dspk->stereo_to_mono) 178 + return 0; 179 + 180 + dspk->stereo_to_mono = value; 181 + 182 + return 1; 72 183 } 73 184 74 185 static int __maybe_unused tegra186_dspk_runtime_suspend(struct device *dev) ··· 390 279 static const struct snd_kcontrol_new tegrat186_dspk_controls[] = { 391 280 SOC_SINGLE_EXT("FIFO Threshold", SND_SOC_NOPM, 0, 392 281 TEGRA186_DSPK_RX_FIFO_DEPTH - 1, 0, 393 - tegra186_dspk_get_control, tegra186_dspk_put_control), 282 + tegra186_dspk_get_fifo_th, tegra186_dspk_put_fifo_th), 394 283 SOC_ENUM_EXT("OSR Value", tegra186_dspk_osr_enum, 395 - tegra186_dspk_get_control, tegra186_dspk_put_control), 284 + tegra186_dspk_get_osr_val, tegra186_dspk_put_osr_val), 396 285 SOC_ENUM_EXT("LR Polarity Select", tegra186_dspk_lrsel_enum, 397 - tegra186_dspk_get_control, tegra186_dspk_put_control), 286 + tegra186_dspk_get_pol_sel, tegra186_dspk_put_pol_sel), 398 287 SOC_ENUM_EXT("Channel Select", tegra186_dspk_ch_sel_enum, 399 - tegra186_dspk_get_control, tegra186_dspk_put_control), 288 + tegra186_dspk_get_ch_sel, tegra186_dspk_put_ch_sel), 400 289 SOC_ENUM_EXT("Mono To Stereo", tegra186_dspk_mono_conv_enum, 401 - tegra186_dspk_get_control, tegra186_dspk_put_control), 290 + tegra186_dspk_get_mono_to_stereo, 291 + tegra186_dspk_put_mono_to_stereo), 402 292 SOC_ENUM_EXT("Stereo To Mono", tegra186_dspk_stereo_conv_enum, 403 - tegra186_dspk_get_control, tegra186_dspk_put_control), 293 + tegra186_dspk_get_stereo_to_mono, 294 + tegra186_dspk_put_stereo_to_mono), 404 295 }; 405 296 406 297 static const struct snd_soc_component_driver tegra186_dspk_cmpnt = {
+112 -32
sound/soc/tegra/tegra210_admaif.c
··· 424 424 .trigger = tegra_admaif_trigger, 425 425 }; 426 426 427 - static int tegra_admaif_get_control(struct snd_kcontrol *kcontrol, 428 - struct snd_ctl_elem_value *ucontrol) 427 + static int tegra210_admaif_pget_mono_to_stereo(struct snd_kcontrol *kcontrol, 428 + struct snd_ctl_elem_value *ucontrol) 429 429 { 430 430 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 431 - struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 432 431 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 433 - long *uctl_val = &ucontrol->value.integer.value[0]; 432 + struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 434 433 435 - if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) 436 - *uctl_val = admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg]; 437 - else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) 438 - *uctl_val = admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg]; 439 - else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) 440 - *uctl_val = admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg]; 441 - else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) 442 - *uctl_val = admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg]; 434 + ucontrol->value.enumerated.item[0] = 435 + admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg]; 443 436 444 437 return 0; 445 438 } 446 439 447 - static int tegra_admaif_put_control(struct snd_kcontrol *kcontrol, 448 - struct snd_ctl_elem_value *ucontrol) 440 + static int tegra210_admaif_pput_mono_to_stereo(struct snd_kcontrol *kcontrol, 441 + struct snd_ctl_elem_value *ucontrol) 449 442 { 450 443 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 451 - struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 452 444 struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 453 - int value = ucontrol->value.integer.value[0]; 445 + struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 446 + unsigned int value = ucontrol->value.enumerated.item[0]; 454 447 455 - if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) 456 - admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value; 457 - else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) 458 - admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value; 459 - else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) 460 - admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value; 461 - else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) 462 - admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value; 448 + if (value == admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg]) 449 + return 0; 450 + 451 + admaif->mono_to_stereo[ADMAIF_TX_PATH][ec->reg] = value; 452 + 453 + return 1; 454 + } 455 + 456 + static int tegra210_admaif_cget_mono_to_stereo(struct snd_kcontrol *kcontrol, 457 + struct snd_ctl_elem_value *ucontrol) 458 + { 459 + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 460 + struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 461 + struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 462 + 463 + ucontrol->value.enumerated.item[0] = 464 + admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg]; 463 465 464 466 return 0; 467 + } 468 + 469 + static int tegra210_admaif_cput_mono_to_stereo(struct snd_kcontrol *kcontrol, 470 + struct snd_ctl_elem_value *ucontrol) 471 + { 472 + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 473 + struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 474 + struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 475 + unsigned int value = ucontrol->value.enumerated.item[0]; 476 + 477 + if (value == admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg]) 478 + return 0; 479 + 480 + admaif->mono_to_stereo[ADMAIF_RX_PATH][ec->reg] = value; 481 + 482 + return 1; 483 + } 484 + 485 + static int tegra210_admaif_pget_stereo_to_mono(struct snd_kcontrol *kcontrol, 486 + struct snd_ctl_elem_value *ucontrol) 487 + { 488 + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 489 + struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 490 + struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 491 + 492 + ucontrol->value.enumerated.item[0] = 493 + admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg]; 494 + 495 + return 0; 496 + } 497 + 498 + static int tegra210_admaif_pput_stereo_to_mono(struct snd_kcontrol *kcontrol, 499 + struct snd_ctl_elem_value *ucontrol) 500 + { 501 + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 502 + struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 503 + struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 504 + unsigned int value = ucontrol->value.enumerated.item[0]; 505 + 506 + if (value == admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg]) 507 + return 0; 508 + 509 + admaif->stereo_to_mono[ADMAIF_TX_PATH][ec->reg] = value; 510 + 511 + return 1; 512 + } 513 + 514 + static int tegra210_admaif_cget_stereo_to_mono(struct snd_kcontrol *kcontrol, 515 + struct snd_ctl_elem_value *ucontrol) 516 + { 517 + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 518 + struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 519 + struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 520 + 521 + ucontrol->value.enumerated.item[0] = 522 + admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg]; 523 + 524 + return 0; 525 + } 526 + 527 + static int tegra210_admaif_cput_stereo_to_mono(struct snd_kcontrol *kcontrol, 528 + struct snd_ctl_elem_value *ucontrol) 529 + { 530 + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 531 + struct tegra_admaif *admaif = snd_soc_component_get_drvdata(cmpnt); 532 + struct soc_enum *ec = (struct soc_enum *)kcontrol->private_value; 533 + unsigned int value = ucontrol->value.enumerated.item[0]; 534 + 535 + if (value == admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg]) 536 + return 0; 537 + 538 + admaif->stereo_to_mono[ADMAIF_RX_PATH][ec->reg] = value; 539 + 540 + return 1; 465 541 } 466 542 467 543 static int tegra_admaif_dai_probe(struct snd_soc_dai *dai) ··· 635 559 } 636 560 637 561 #define TEGRA_ADMAIF_CIF_CTRL(reg) \ 638 - NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1,\ 639 - tegra_admaif_get_control, tegra_admaif_put_control, \ 562 + NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Mono To Stereo", reg - 1, \ 563 + tegra210_admaif_pget_mono_to_stereo, \ 564 + tegra210_admaif_pput_mono_to_stereo, \ 640 565 tegra_admaif_mono_conv_text), \ 641 - NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1,\ 642 - tegra_admaif_get_control, tegra_admaif_put_control, \ 566 + NV_SOC_ENUM_EXT("ADMAIF" #reg " Playback Stereo To Mono", reg - 1, \ 567 + tegra210_admaif_pget_stereo_to_mono, \ 568 + tegra210_admaif_pput_stereo_to_mono, \ 643 569 tegra_admaif_stereo_conv_text), \ 644 - NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1, \ 645 - tegra_admaif_get_control, tegra_admaif_put_control, \ 570 + NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Mono To Stereo", reg - 1, \ 571 + tegra210_admaif_cget_mono_to_stereo, \ 572 + tegra210_admaif_cput_mono_to_stereo, \ 646 573 tegra_admaif_mono_conv_text), \ 647 - NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1, \ 648 - tegra_admaif_get_control, tegra_admaif_put_control, \ 574 + NV_SOC_ENUM_EXT("ADMAIF" #reg " Capture Stereo To Mono", reg - 1, \ 575 + tegra210_admaif_cget_stereo_to_mono, \ 576 + tegra210_admaif_cput_stereo_to_mono, \ 649 577 tegra_admaif_stereo_conv_text) 650 578 651 579 static struct snd_kcontrol_new tegra210_admaif_controls[] = {
+3
sound/soc/tegra/tegra210_adx.c
··· 193 193 struct soc_mixer_control *mc = 194 194 (struct soc_mixer_control *)kcontrol->private_value;; 195 195 196 + if (value == bytes_map[mc->reg]) 197 + return 0; 198 + 196 199 if (value >= 0 && value <= 255) { 197 200 /* update byte map and enable slot */ 198 201 bytes_map[mc->reg] = value;
+7 -4
sound/soc/tegra/tegra210_ahub.c
··· 62 62 unsigned int *item = uctl->value.enumerated.item; 63 63 unsigned int value = e->values[item[0]]; 64 64 unsigned int i, bit_pos, reg_idx = 0, reg_val = 0; 65 + int change = 0; 65 66 66 67 if (item[0] >= e->items) 67 68 return -EINVAL; ··· 87 86 88 87 /* Update widget power if state has changed */ 89 88 if (snd_soc_component_test_bits(cmpnt, update[i].reg, 90 - update[i].mask, update[i].val)) 91 - snd_soc_dapm_mux_update_power(dapm, kctl, item[0], e, 92 - &update[i]); 89 + update[i].mask, 90 + update[i].val)) 91 + change |= snd_soc_dapm_mux_update_power(dapm, kctl, 92 + item[0], e, 93 + &update[i]); 93 94 } 94 95 95 - return 0; 96 + return change; 96 97 } 97 98 98 99 static struct snd_soc_dai_driver tegra210_ahub_dais[] = {
+3
sound/soc/tegra/tegra210_amx.c
··· 222 222 int reg = mc->reg; 223 223 int value = ucontrol->value.integer.value[0]; 224 224 225 + if (value == bytes_map[reg]) 226 + return 0; 227 + 225 228 if (value >= 0 && value <= 255) { 226 229 /* Update byte map and enable slot */ 227 230 bytes_map[reg] = value;
+150 -36
sound/soc/tegra/tegra210_dmic.c
··· 156 156 return 0; 157 157 } 158 158 159 - static int tegra210_dmic_get_control(struct snd_kcontrol *kcontrol, 160 - struct snd_ctl_elem_value *ucontrol) 159 + static int tegra210_dmic_get_boost_gain(struct snd_kcontrol *kcontrol, 160 + struct snd_ctl_elem_value *ucontrol) 161 161 { 162 162 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 163 163 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 164 164 165 - if (strstr(kcontrol->id.name, "Boost Gain Volume")) 166 - ucontrol->value.integer.value[0] = dmic->boost_gain; 167 - else if (strstr(kcontrol->id.name, "Channel Select")) 168 - ucontrol->value.integer.value[0] = dmic->ch_select; 169 - else if (strstr(kcontrol->id.name, "Mono To Stereo")) 170 - ucontrol->value.integer.value[0] = dmic->mono_to_stereo; 171 - else if (strstr(kcontrol->id.name, "Stereo To Mono")) 172 - ucontrol->value.integer.value[0] = dmic->stereo_to_mono; 173 - else if (strstr(kcontrol->id.name, "OSR Value")) 174 - ucontrol->value.integer.value[0] = dmic->osr_val; 175 - else if (strstr(kcontrol->id.name, "LR Polarity Select")) 176 - ucontrol->value.integer.value[0] = dmic->lrsel; 165 + ucontrol->value.integer.value[0] = dmic->boost_gain; 177 166 178 167 return 0; 179 168 } 180 169 181 - static int tegra210_dmic_put_control(struct snd_kcontrol *kcontrol, 182 - struct snd_ctl_elem_value *ucontrol) 170 + static int tegra210_dmic_put_boost_gain(struct snd_kcontrol *kcontrol, 171 + struct snd_ctl_elem_value *ucontrol) 183 172 { 184 173 struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 185 174 struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 186 175 int value = ucontrol->value.integer.value[0]; 187 176 188 - if (strstr(kcontrol->id.name, "Boost Gain Volume")) 189 - dmic->boost_gain = value; 190 - else if (strstr(kcontrol->id.name, "Channel Select")) 191 - dmic->ch_select = ucontrol->value.integer.value[0]; 192 - else if (strstr(kcontrol->id.name, "Mono To Stereo")) 193 - dmic->mono_to_stereo = value; 194 - else if (strstr(kcontrol->id.name, "Stereo To Mono")) 195 - dmic->stereo_to_mono = value; 196 - else if (strstr(kcontrol->id.name, "OSR Value")) 197 - dmic->osr_val = value; 198 - else if (strstr(kcontrol->id.name, "LR Polarity Select")) 199 - dmic->lrsel = value; 177 + if (value == dmic->boost_gain) 178 + return 0; 179 + 180 + dmic->boost_gain = value; 181 + 182 + return 1; 183 + } 184 + 185 + static int tegra210_dmic_get_ch_select(struct snd_kcontrol *kcontrol, 186 + struct snd_ctl_elem_value *ucontrol) 187 + { 188 + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 189 + struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 190 + 191 + ucontrol->value.enumerated.item[0] = dmic->ch_select; 200 192 201 193 return 0; 194 + } 195 + 196 + static int tegra210_dmic_put_ch_select(struct snd_kcontrol *kcontrol, 197 + struct snd_ctl_elem_value *ucontrol) 198 + { 199 + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 200 + struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 201 + unsigned int value = ucontrol->value.enumerated.item[0]; 202 + 203 + if (value == dmic->ch_select) 204 + return 0; 205 + 206 + dmic->ch_select = value; 207 + 208 + return 1; 209 + } 210 + 211 + static int tegra210_dmic_get_mono_to_stereo(struct snd_kcontrol *kcontrol, 212 + struct snd_ctl_elem_value *ucontrol) 213 + { 214 + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 215 + struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 216 + 217 + ucontrol->value.enumerated.item[0] = dmic->mono_to_stereo; 218 + 219 + return 0; 220 + } 221 + 222 + static int tegra210_dmic_put_mono_to_stereo(struct snd_kcontrol *kcontrol, 223 + struct snd_ctl_elem_value *ucontrol) 224 + { 225 + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 226 + struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 227 + unsigned int value = ucontrol->value.enumerated.item[0]; 228 + 229 + if (value == dmic->mono_to_stereo) 230 + return 0; 231 + 232 + dmic->mono_to_stereo = value; 233 + 234 + return 1; 235 + } 236 + 237 + static int tegra210_dmic_get_stereo_to_mono(struct snd_kcontrol *kcontrol, 238 + struct snd_ctl_elem_value *ucontrol) 239 + { 240 + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 241 + struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 242 + 243 + ucontrol->value.enumerated.item[0] = dmic->stereo_to_mono; 244 + 245 + return 0; 246 + } 247 + 248 + static int tegra210_dmic_put_stereo_to_mono(struct snd_kcontrol *kcontrol, 249 + struct snd_ctl_elem_value *ucontrol) 250 + { 251 + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 252 + struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 253 + unsigned int value = ucontrol->value.enumerated.item[0]; 254 + 255 + if (value == dmic->stereo_to_mono) 256 + return 0; 257 + 258 + dmic->stereo_to_mono = value; 259 + 260 + return 1; 261 + } 262 + 263 + static int tegra210_dmic_get_osr_val(struct snd_kcontrol *kcontrol, 264 + struct snd_ctl_elem_value *ucontrol) 265 + { 266 + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 267 + struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 268 + 269 + ucontrol->value.enumerated.item[0] = dmic->osr_val; 270 + 271 + return 0; 272 + } 273 + 274 + static int tegra210_dmic_put_osr_val(struct snd_kcontrol *kcontrol, 275 + struct snd_ctl_elem_value *ucontrol) 276 + { 277 + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 278 + struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 279 + unsigned int value = ucontrol->value.enumerated.item[0]; 280 + 281 + if (value == dmic->osr_val) 282 + return 0; 283 + 284 + dmic->osr_val = value; 285 + 286 + return 1; 287 + } 288 + 289 + static int tegra210_dmic_get_pol_sel(struct snd_kcontrol *kcontrol, 290 + struct snd_ctl_elem_value *ucontrol) 291 + { 292 + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 293 + struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 294 + 295 + ucontrol->value.enumerated.item[0] = dmic->lrsel; 296 + 297 + return 0; 298 + } 299 + 300 + static int tegra210_dmic_put_pol_sel(struct snd_kcontrol *kcontrol, 301 + struct snd_ctl_elem_value *ucontrol) 302 + { 303 + struct snd_soc_component *comp = snd_soc_kcontrol_component(kcontrol); 304 + struct tegra210_dmic *dmic = snd_soc_component_get_drvdata(comp); 305 + unsigned int value = ucontrol->value.enumerated.item[0]; 306 + 307 + if (value == dmic->lrsel) 308 + return 0; 309 + 310 + dmic->lrsel = value; 311 + 312 + return 1; 202 313 } 203 314 204 315 static const struct snd_soc_dai_ops tegra210_dmic_dai_ops = { ··· 398 287 399 288 static const struct snd_kcontrol_new tegra210_dmic_controls[] = { 400 289 SOC_SINGLE_EXT("Boost Gain Volume", 0, 0, MAX_BOOST_GAIN, 0, 401 - tegra210_dmic_get_control, tegra210_dmic_put_control), 290 + tegra210_dmic_get_boost_gain, 291 + tegra210_dmic_put_boost_gain), 402 292 SOC_ENUM_EXT("Channel Select", tegra210_dmic_ch_enum, 403 - tegra210_dmic_get_control, tegra210_dmic_put_control), 293 + tegra210_dmic_get_ch_select, tegra210_dmic_put_ch_select), 404 294 SOC_ENUM_EXT("Mono To Stereo", 405 - tegra210_dmic_mono_conv_enum, tegra210_dmic_get_control, 406 - tegra210_dmic_put_control), 295 + tegra210_dmic_mono_conv_enum, 296 + tegra210_dmic_get_mono_to_stereo, 297 + tegra210_dmic_put_mono_to_stereo), 407 298 SOC_ENUM_EXT("Stereo To Mono", 408 - tegra210_dmic_stereo_conv_enum, tegra210_dmic_get_control, 409 - tegra210_dmic_put_control), 299 + tegra210_dmic_stereo_conv_enum, 300 + tegra210_dmic_get_stereo_to_mono, 301 + tegra210_dmic_put_stereo_to_mono), 410 302 SOC_ENUM_EXT("OSR Value", tegra210_dmic_osr_enum, 411 - tegra210_dmic_get_control, tegra210_dmic_put_control), 303 + tegra210_dmic_get_osr_val, tegra210_dmic_put_osr_val), 412 304 SOC_ENUM_EXT("LR Polarity Select", tegra210_dmic_lrsel_enum, 413 - tegra210_dmic_get_control, tegra210_dmic_put_control), 305 + tegra210_dmic_get_pol_sel, tegra210_dmic_put_pol_sel), 414 306 }; 415 307 416 308 static const struct snd_soc_component_driver tegra210_dmic_compnt = {
+240 -84
sound/soc/tegra/tegra210_i2s.c
··· 302 302 return 0; 303 303 } 304 304 305 + static int tegra210_i2s_get_loopback(struct snd_kcontrol *kcontrol, 306 + struct snd_ctl_elem_value *ucontrol) 307 + { 308 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 309 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 310 + 311 + ucontrol->value.integer.value[0] = i2s->loopback; 312 + 313 + return 0; 314 + } 315 + 316 + static int tegra210_i2s_put_loopback(struct snd_kcontrol *kcontrol, 317 + struct snd_ctl_elem_value *ucontrol) 318 + { 319 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 320 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 321 + int value = ucontrol->value.integer.value[0]; 322 + 323 + if (value == i2s->loopback) 324 + return 0; 325 + 326 + i2s->loopback = value; 327 + 328 + regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, I2S_CTRL_LPBK_MASK, 329 + i2s->loopback << I2S_CTRL_LPBK_SHIFT); 330 + 331 + return 1; 332 + } 333 + 334 + static int tegra210_i2s_get_fsync_width(struct snd_kcontrol *kcontrol, 335 + struct snd_ctl_elem_value *ucontrol) 336 + { 337 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 338 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 339 + 340 + ucontrol->value.integer.value[0] = i2s->fsync_width; 341 + 342 + return 0; 343 + } 344 + 345 + static int tegra210_i2s_put_fsync_width(struct snd_kcontrol *kcontrol, 346 + struct snd_ctl_elem_value *ucontrol) 347 + { 348 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 349 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 350 + int value = ucontrol->value.integer.value[0]; 351 + 352 + if (value == i2s->fsync_width) 353 + return 0; 354 + 355 + i2s->fsync_width = value; 356 + 357 + /* 358 + * Frame sync width is used only for FSYNC modes and not 359 + * applicable for LRCK modes. Reset value for this field is "0", 360 + * which means the width is one bit clock wide. 361 + * The width requirement may depend on the codec and in such 362 + * cases mixer control is used to update custom values. A value 363 + * of "N" here means, width is "N + 1" bit clock wide. 364 + */ 365 + regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, 366 + I2S_CTRL_FSYNC_WIDTH_MASK, 367 + i2s->fsync_width << I2S_FSYNC_WIDTH_SHIFT); 368 + 369 + return 1; 370 + } 371 + 372 + static int tegra210_i2s_cget_stereo_to_mono(struct snd_kcontrol *kcontrol, 373 + struct snd_ctl_elem_value *ucontrol) 374 + { 375 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 376 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 377 + 378 + ucontrol->value.enumerated.item[0] = i2s->stereo_to_mono[I2S_TX_PATH]; 379 + 380 + return 0; 381 + } 382 + 383 + static int tegra210_i2s_cput_stereo_to_mono(struct snd_kcontrol *kcontrol, 384 + struct snd_ctl_elem_value *ucontrol) 385 + { 386 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 387 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 388 + unsigned int value = ucontrol->value.enumerated.item[0]; 389 + 390 + if (value == i2s->stereo_to_mono[I2S_TX_PATH]) 391 + return 0; 392 + 393 + i2s->stereo_to_mono[I2S_TX_PATH] = value; 394 + 395 + return 1; 396 + } 397 + 398 + static int tegra210_i2s_cget_mono_to_stereo(struct snd_kcontrol *kcontrol, 399 + struct snd_ctl_elem_value *ucontrol) 400 + { 401 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 402 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 403 + 404 + ucontrol->value.enumerated.item[0] = i2s->mono_to_stereo[I2S_TX_PATH]; 405 + 406 + return 0; 407 + } 408 + 409 + static int tegra210_i2s_cput_mono_to_stereo(struct snd_kcontrol *kcontrol, 410 + struct snd_ctl_elem_value *ucontrol) 411 + { 412 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 413 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 414 + unsigned int value = ucontrol->value.enumerated.item[0]; 415 + 416 + if (value == i2s->mono_to_stereo[I2S_TX_PATH]) 417 + return 0; 418 + 419 + i2s->mono_to_stereo[I2S_TX_PATH] = value; 420 + 421 + return 1; 422 + } 423 + 424 + static int tegra210_i2s_pget_stereo_to_mono(struct snd_kcontrol *kcontrol, 425 + struct snd_ctl_elem_value *ucontrol) 426 + { 427 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 428 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 429 + 430 + ucontrol->value.enumerated.item[0] = i2s->stereo_to_mono[I2S_RX_PATH]; 431 + 432 + return 0; 433 + } 434 + 435 + static int tegra210_i2s_pput_stereo_to_mono(struct snd_kcontrol *kcontrol, 436 + struct snd_ctl_elem_value *ucontrol) 437 + { 438 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 439 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 440 + unsigned int value = ucontrol->value.enumerated.item[0]; 441 + 442 + if (value == i2s->stereo_to_mono[I2S_RX_PATH]) 443 + return 0; 444 + 445 + i2s->stereo_to_mono[I2S_RX_PATH] = value; 446 + 447 + return 1; 448 + } 449 + 450 + static int tegra210_i2s_pget_mono_to_stereo(struct snd_kcontrol *kcontrol, 451 + struct snd_ctl_elem_value *ucontrol) 452 + { 453 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 454 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 455 + 456 + ucontrol->value.enumerated.item[0] = i2s->mono_to_stereo[I2S_RX_PATH]; 457 + 458 + return 0; 459 + } 460 + 461 + static int tegra210_i2s_pput_mono_to_stereo(struct snd_kcontrol *kcontrol, 462 + struct snd_ctl_elem_value *ucontrol) 463 + { 464 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 465 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 466 + unsigned int value = ucontrol->value.enumerated.item[0]; 467 + 468 + if (value == i2s->mono_to_stereo[I2S_RX_PATH]) 469 + return 0; 470 + 471 + i2s->mono_to_stereo[I2S_RX_PATH] = value; 472 + 473 + return 1; 474 + } 475 + 476 + static int tegra210_i2s_pget_fifo_th(struct snd_kcontrol *kcontrol, 477 + struct snd_ctl_elem_value *ucontrol) 478 + { 479 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 480 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 481 + 482 + ucontrol->value.integer.value[0] = i2s->rx_fifo_th; 483 + 484 + return 0; 485 + } 486 + 487 + static int tegra210_i2s_pput_fifo_th(struct snd_kcontrol *kcontrol, 488 + struct snd_ctl_elem_value *ucontrol) 489 + { 490 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 491 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 492 + int value = ucontrol->value.integer.value[0]; 493 + 494 + if (value == i2s->rx_fifo_th) 495 + return 0; 496 + 497 + i2s->rx_fifo_th = value; 498 + 499 + return 1; 500 + } 501 + 502 + static int tegra210_i2s_get_bclk_ratio(struct snd_kcontrol *kcontrol, 503 + struct snd_ctl_elem_value *ucontrol) 504 + { 505 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 506 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 507 + 508 + ucontrol->value.integer.value[0] = i2s->bclk_ratio; 509 + 510 + return 0; 511 + } 512 + 513 + static int tegra210_i2s_put_bclk_ratio(struct snd_kcontrol *kcontrol, 514 + struct snd_ctl_elem_value *ucontrol) 515 + { 516 + struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 517 + struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 518 + int value = ucontrol->value.integer.value[0]; 519 + 520 + if (value == i2s->bclk_ratio) 521 + return 0; 522 + 523 + i2s->bclk_ratio = value; 524 + 525 + return 1; 526 + } 527 + 305 528 static int tegra210_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai, 306 529 unsigned int ratio) 307 530 { 308 531 struct tegra210_i2s *i2s = snd_soc_dai_get_drvdata(dai); 309 532 310 533 i2s->bclk_ratio = ratio; 311 - 312 - return 0; 313 - } 314 - 315 - static int tegra210_i2s_get_control(struct snd_kcontrol *kcontrol, 316 - struct snd_ctl_elem_value *ucontrol) 317 - { 318 - struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 319 - struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 320 - long *uctl_val = &ucontrol->value.integer.value[0]; 321 - 322 - if (strstr(kcontrol->id.name, "Loopback")) 323 - *uctl_val = i2s->loopback; 324 - else if (strstr(kcontrol->id.name, "FSYNC Width")) 325 - *uctl_val = i2s->fsync_width; 326 - else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) 327 - *uctl_val = i2s->stereo_to_mono[I2S_TX_PATH]; 328 - else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) 329 - *uctl_val = i2s->mono_to_stereo[I2S_TX_PATH]; 330 - else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) 331 - *uctl_val = i2s->stereo_to_mono[I2S_RX_PATH]; 332 - else if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) 333 - *uctl_val = i2s->mono_to_stereo[I2S_RX_PATH]; 334 - else if (strstr(kcontrol->id.name, "Playback FIFO Threshold")) 335 - *uctl_val = i2s->rx_fifo_th; 336 - else if (strstr(kcontrol->id.name, "BCLK Ratio")) 337 - *uctl_val = i2s->bclk_ratio; 338 - 339 - return 0; 340 - } 341 - 342 - static int tegra210_i2s_put_control(struct snd_kcontrol *kcontrol, 343 - struct snd_ctl_elem_value *ucontrol) 344 - { 345 - struct snd_soc_component *compnt = snd_soc_kcontrol_component(kcontrol); 346 - struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt); 347 - int value = ucontrol->value.integer.value[0]; 348 - 349 - if (strstr(kcontrol->id.name, "Loopback")) { 350 - i2s->loopback = value; 351 - 352 - regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, 353 - I2S_CTRL_LPBK_MASK, 354 - i2s->loopback << I2S_CTRL_LPBK_SHIFT); 355 - 356 - } else if (strstr(kcontrol->id.name, "FSYNC Width")) { 357 - /* 358 - * Frame sync width is used only for FSYNC modes and not 359 - * applicable for LRCK modes. Reset value for this field is "0", 360 - * which means the width is one bit clock wide. 361 - * The width requirement may depend on the codec and in such 362 - * cases mixer control is used to update custom values. A value 363 - * of "N" here means, width is "N + 1" bit clock wide. 364 - */ 365 - i2s->fsync_width = value; 366 - 367 - regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL, 368 - I2S_CTRL_FSYNC_WIDTH_MASK, 369 - i2s->fsync_width << I2S_FSYNC_WIDTH_SHIFT); 370 - 371 - } else if (strstr(kcontrol->id.name, "Capture Stereo To Mono")) { 372 - i2s->stereo_to_mono[I2S_TX_PATH] = value; 373 - } else if (strstr(kcontrol->id.name, "Capture Mono To Stereo")) { 374 - i2s->mono_to_stereo[I2S_TX_PATH] = value; 375 - } else if (strstr(kcontrol->id.name, "Playback Stereo To Mono")) { 376 - i2s->stereo_to_mono[I2S_RX_PATH] = value; 377 - } else if (strstr(kcontrol->id.name, "Playback Mono To Stereo")) { 378 - i2s->mono_to_stereo[I2S_RX_PATH] = value; 379 - } else if (strstr(kcontrol->id.name, "Playback FIFO Threshold")) { 380 - i2s->rx_fifo_th = value; 381 - } else if (strstr(kcontrol->id.name, "BCLK Ratio")) { 382 - i2s->bclk_ratio = value; 383 - } 384 534 385 535 return 0; 386 536 } ··· 748 598 tegra210_i2s_stereo_conv_text); 749 599 750 600 static const struct snd_kcontrol_new tegra210_i2s_controls[] = { 751 - SOC_SINGLE_EXT("Loopback", 0, 0, 1, 0, tegra210_i2s_get_control, 752 - tegra210_i2s_put_control), 753 - SOC_SINGLE_EXT("FSYNC Width", 0, 0, 255, 0, tegra210_i2s_get_control, 754 - tegra210_i2s_put_control), 601 + SOC_SINGLE_EXT("Loopback", 0, 0, 1, 0, tegra210_i2s_get_loopback, 602 + tegra210_i2s_put_loopback), 603 + SOC_SINGLE_EXT("FSYNC Width", 0, 0, 255, 0, 604 + tegra210_i2s_get_fsync_width, 605 + tegra210_i2s_put_fsync_width), 755 606 SOC_ENUM_EXT("Capture Stereo To Mono", tegra210_i2s_stereo_conv_enum, 756 - tegra210_i2s_get_control, tegra210_i2s_put_control), 607 + tegra210_i2s_cget_stereo_to_mono, 608 + tegra210_i2s_cput_stereo_to_mono), 757 609 SOC_ENUM_EXT("Capture Mono To Stereo", tegra210_i2s_mono_conv_enum, 758 - tegra210_i2s_get_control, tegra210_i2s_put_control), 610 + tegra210_i2s_cget_mono_to_stereo, 611 + tegra210_i2s_cput_mono_to_stereo), 759 612 SOC_ENUM_EXT("Playback Stereo To Mono", tegra210_i2s_stereo_conv_enum, 760 - tegra210_i2s_get_control, tegra210_i2s_put_control), 613 + tegra210_i2s_pget_mono_to_stereo, 614 + tegra210_i2s_pput_mono_to_stereo), 761 615 SOC_ENUM_EXT("Playback Mono To Stereo", tegra210_i2s_mono_conv_enum, 762 - tegra210_i2s_get_control, tegra210_i2s_put_control), 616 + tegra210_i2s_pget_stereo_to_mono, 617 + tegra210_i2s_pput_stereo_to_mono), 763 618 SOC_SINGLE_EXT("Playback FIFO Threshold", 0, 0, I2S_RX_FIFO_DEPTH - 1, 764 - 0, tegra210_i2s_get_control, tegra210_i2s_put_control), 765 - SOC_SINGLE_EXT("BCLK Ratio", 0, 0, INT_MAX, 0, tegra210_i2s_get_control, 766 - tegra210_i2s_put_control), 619 + 0, tegra210_i2s_pget_fifo_th, tegra210_i2s_pput_fifo_th), 620 + SOC_SINGLE_EXT("BCLK Ratio", 0, 0, INT_MAX, 0, 621 + tegra210_i2s_get_bclk_ratio, 622 + tegra210_i2s_put_bclk_ratio), 767 623 }; 768 624 769 625 static const struct snd_soc_dapm_widget tegra210_i2s_widgets[] = {
+19 -7
sound/soc/tegra/tegra210_mixer.c
··· 192 192 return 0; 193 193 } 194 194 195 - static int tegra210_mixer_put_gain(struct snd_kcontrol *kcontrol, 196 - struct snd_ctl_elem_value *ucontrol) 195 + static int tegra210_mixer_apply_gain(struct snd_kcontrol *kcontrol, 196 + struct snd_ctl_elem_value *ucontrol, 197 + bool instant_gain) 197 198 { 198 199 struct soc_mixer_control *mc = 199 200 (struct soc_mixer_control *)kcontrol->private_value; 200 201 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 201 202 struct tegra210_mixer *mixer = snd_soc_component_get_drvdata(cmpnt); 202 203 unsigned int reg = mc->reg, id; 203 - bool instant_gain = false; 204 204 int err; 205 - 206 - if (strstr(kcontrol->id.name, "Instant Gain Volume")) 207 - instant_gain = true; 208 205 209 206 /* Save gain value for specific MIXER input */ 210 207 id = (reg - TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_0) / 211 208 TEGRA210_MIXER_GAIN_CFG_RAM_ADDR_STRIDE; 209 + 210 + if (mixer->gain_value[id] == ucontrol->value.integer.value[0]) 211 + return 0; 212 212 213 213 mixer->gain_value[id] = ucontrol->value.integer.value[0]; 214 214 ··· 219 219 } 220 220 221 221 return 1; 222 + } 223 + 224 + static int tegra210_mixer_put_gain(struct snd_kcontrol *kcontrol, 225 + struct snd_ctl_elem_value *ucontrol) 226 + { 227 + return tegra210_mixer_apply_gain(kcontrol, ucontrol, false); 228 + } 229 + 230 + static int tegra210_mixer_put_instant_gain(struct snd_kcontrol *kcontrol, 231 + struct snd_ctl_elem_value *ucontrol) 232 + { 233 + return tegra210_mixer_apply_gain(kcontrol, ucontrol, true); 222 234 } 223 235 224 236 static int tegra210_mixer_set_audio_cif(struct tegra210_mixer *mixer, ··· 400 388 SOC_SINGLE_EXT("RX" #id " Instant Gain Volume", \ 401 389 MIXER_GAIN_CFG_RAM_ADDR((id) - 1), 0, \ 402 390 0x20000, 0, tegra210_mixer_get_gain, \ 403 - tegra210_mixer_put_gain), 391 + tegra210_mixer_put_instant_gain), 404 392 405 393 /* Volume controls for all MIXER inputs */ 406 394 static const struct snd_kcontrol_new tegra210_mixer_gain_ctls[] = {
+22 -8
sound/soc/tegra/tegra210_mvc.c
··· 136 136 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 137 137 struct tegra210_mvc *mvc = snd_soc_component_get_drvdata(cmpnt); 138 138 unsigned int value; 139 - u8 mute_mask; 139 + u8 new_mask, old_mask; 140 140 int err; 141 141 142 142 pm_runtime_get_sync(cmpnt->dev); ··· 148 148 if (err < 0) 149 149 goto end; 150 150 151 - mute_mask = ucontrol->value.integer.value[0]; 151 + regmap_read(mvc->regmap, TEGRA210_MVC_CTRL, &value); 152 + 153 + old_mask = (value >> TEGRA210_MVC_MUTE_SHIFT) & TEGRA210_MUTE_MASK_EN; 154 + new_mask = ucontrol->value.integer.value[0]; 155 + 156 + if (new_mask == old_mask) { 157 + err = 0; 158 + goto end; 159 + } 152 160 153 161 err = regmap_update_bits(mvc->regmap, mc->reg, 154 162 TEGRA210_MVC_MUTE_MASK, 155 - mute_mask << TEGRA210_MVC_MUTE_SHIFT); 163 + new_mask << TEGRA210_MVC_MUTE_SHIFT); 156 164 if (err < 0) 157 165 goto end; 158 166 ··· 203 195 unsigned int reg = mc->reg; 204 196 unsigned int value; 205 197 u8 chan; 206 - int err; 198 + int err, old_volume; 207 199 208 200 pm_runtime_get_sync(cmpnt->dev); 209 201 ··· 215 207 goto end; 216 208 217 209 chan = (reg - TEGRA210_MVC_TARGET_VOL) / REG_SIZE; 210 + old_volume = mvc->volume[chan]; 218 211 219 212 tegra210_mvc_conv_vol(mvc, chan, 220 213 ucontrol->value.integer.value[0]); 214 + 215 + if (mvc->volume[chan] == old_volume) { 216 + err = 0; 217 + goto end; 218 + } 221 219 222 220 /* Configure init volume same as target volume */ 223 221 regmap_write(mvc->regmap, ··· 289 275 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 290 276 struct tegra210_mvc *mvc = snd_soc_component_get_drvdata(cmpnt); 291 277 292 - ucontrol->value.integer.value[0] = mvc->curve_type; 278 + ucontrol->value.enumerated.item[0] = mvc->curve_type; 293 279 294 280 return 0; 295 281 } ··· 299 285 { 300 286 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 301 287 struct tegra210_mvc *mvc = snd_soc_component_get_drvdata(cmpnt); 302 - int value; 288 + unsigned int value; 303 289 304 290 regmap_read(mvc->regmap, TEGRA210_MVC_ENABLE, &value); 305 291 if (value & TEGRA210_MVC_EN) { ··· 308 294 return -EINVAL; 309 295 } 310 296 311 - if (mvc->curve_type == ucontrol->value.integer.value[0]) 297 + if (mvc->curve_type == ucontrol->value.enumerated.item[0]) 312 298 return 0; 313 299 314 - mvc->curve_type = ucontrol->value.integer.value[0]; 300 + mvc->curve_type = ucontrol->value.enumerated.item[0]; 315 301 316 302 tegra210_mvc_reset_vol_settings(mvc, cmpnt->dev); 317 303
+93 -28
sound/soc/tegra/tegra210_sfc.c
··· 3244 3244 return tegra210_sfc_write_coeff_ram(cmpnt); 3245 3245 } 3246 3246 3247 - static int tegra210_sfc_get_control(struct snd_kcontrol *kcontrol, 3247 + static int tegra210_sfc_iget_stereo_to_mono(struct snd_kcontrol *kcontrol, 3248 3248 struct snd_ctl_elem_value *ucontrol) 3249 3249 { 3250 3250 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 3251 3251 struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); 3252 3252 3253 - if (strstr(kcontrol->id.name, "Input Stereo To Mono")) 3254 - ucontrol->value.integer.value[0] = 3255 - sfc->stereo_to_mono[SFC_RX_PATH]; 3256 - else if (strstr(kcontrol->id.name, "Input Mono To Stereo")) 3257 - ucontrol->value.integer.value[0] = 3258 - sfc->mono_to_stereo[SFC_RX_PATH]; 3259 - else if (strstr(kcontrol->id.name, "Output Stereo To Mono")) 3260 - ucontrol->value.integer.value[0] = 3261 - sfc->stereo_to_mono[SFC_TX_PATH]; 3262 - else if (strstr(kcontrol->id.name, "Output Mono To Stereo")) 3263 - ucontrol->value.integer.value[0] = 3264 - sfc->mono_to_stereo[SFC_TX_PATH]; 3253 + ucontrol->value.enumerated.item[0] = sfc->stereo_to_mono[SFC_RX_PATH]; 3265 3254 3266 3255 return 0; 3267 3256 } 3268 3257 3269 - static int tegra210_sfc_put_control(struct snd_kcontrol *kcontrol, 3258 + static int tegra210_sfc_iput_stereo_to_mono(struct snd_kcontrol *kcontrol, 3270 3259 struct snd_ctl_elem_value *ucontrol) 3271 3260 { 3272 3261 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 3273 3262 struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); 3274 - int value = ucontrol->value.integer.value[0]; 3263 + unsigned int value = ucontrol->value.enumerated.item[0]; 3275 3264 3276 - if (strstr(kcontrol->id.name, "Input Stereo To Mono")) 3277 - sfc->stereo_to_mono[SFC_RX_PATH] = value; 3278 - else if (strstr(kcontrol->id.name, "Input Mono To Stereo")) 3279 - sfc->mono_to_stereo[SFC_RX_PATH] = value; 3280 - else if (strstr(kcontrol->id.name, "Output Stereo To Mono")) 3281 - sfc->stereo_to_mono[SFC_TX_PATH] = value; 3282 - else if (strstr(kcontrol->id.name, "Output Mono To Stereo")) 3283 - sfc->mono_to_stereo[SFC_TX_PATH] = value; 3284 - else 3265 + if (value == sfc->stereo_to_mono[SFC_RX_PATH]) 3285 3266 return 0; 3267 + 3268 + sfc->stereo_to_mono[SFC_RX_PATH] = value; 3269 + 3270 + return 1; 3271 + } 3272 + 3273 + static int tegra210_sfc_iget_mono_to_stereo(struct snd_kcontrol *kcontrol, 3274 + struct snd_ctl_elem_value *ucontrol) 3275 + { 3276 + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 3277 + struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); 3278 + 3279 + ucontrol->value.enumerated.item[0] = sfc->mono_to_stereo[SFC_RX_PATH]; 3280 + 3281 + return 0; 3282 + } 3283 + 3284 + static int tegra210_sfc_iput_mono_to_stereo(struct snd_kcontrol *kcontrol, 3285 + struct snd_ctl_elem_value *ucontrol) 3286 + { 3287 + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 3288 + struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); 3289 + unsigned int value = ucontrol->value.enumerated.item[0]; 3290 + 3291 + if (value == sfc->mono_to_stereo[SFC_RX_PATH]) 3292 + return 0; 3293 + 3294 + sfc->mono_to_stereo[SFC_RX_PATH] = value; 3295 + 3296 + return 1; 3297 + } 3298 + 3299 + static int tegra210_sfc_oget_stereo_to_mono(struct snd_kcontrol *kcontrol, 3300 + struct snd_ctl_elem_value *ucontrol) 3301 + { 3302 + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 3303 + struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); 3304 + 3305 + ucontrol->value.enumerated.item[0] = sfc->stereo_to_mono[SFC_TX_PATH]; 3306 + 3307 + return 0; 3308 + } 3309 + 3310 + static int tegra210_sfc_oput_stereo_to_mono(struct snd_kcontrol *kcontrol, 3311 + struct snd_ctl_elem_value *ucontrol) 3312 + { 3313 + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 3314 + struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); 3315 + unsigned int value = ucontrol->value.enumerated.item[0]; 3316 + 3317 + if (value == sfc->stereo_to_mono[SFC_TX_PATH]) 3318 + return 0; 3319 + 3320 + sfc->stereo_to_mono[SFC_TX_PATH] = value; 3321 + 3322 + return 1; 3323 + } 3324 + 3325 + static int tegra210_sfc_oget_mono_to_stereo(struct snd_kcontrol *kcontrol, 3326 + struct snd_ctl_elem_value *ucontrol) 3327 + { 3328 + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 3329 + struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); 3330 + 3331 + ucontrol->value.enumerated.item[0] = sfc->mono_to_stereo[SFC_TX_PATH]; 3332 + 3333 + return 0; 3334 + } 3335 + 3336 + static int tegra210_sfc_oput_mono_to_stereo(struct snd_kcontrol *kcontrol, 3337 + struct snd_ctl_elem_value *ucontrol) 3338 + { 3339 + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 3340 + struct tegra210_sfc *sfc = snd_soc_component_get_drvdata(cmpnt); 3341 + unsigned int value = ucontrol->value.enumerated.item[0]; 3342 + 3343 + if (value == sfc->mono_to_stereo[SFC_TX_PATH]) 3344 + return 0; 3345 + 3346 + sfc->mono_to_stereo[SFC_TX_PATH] = value; 3286 3347 3287 3348 return 1; 3288 3349 } ··· 3445 3384 3446 3385 static const struct snd_kcontrol_new tegra210_sfc_controls[] = { 3447 3386 SOC_ENUM_EXT("Input Stereo To Mono", tegra210_sfc_stereo_conv_enum, 3448 - tegra210_sfc_get_control, tegra210_sfc_put_control), 3387 + tegra210_sfc_iget_stereo_to_mono, 3388 + tegra210_sfc_iput_stereo_to_mono), 3449 3389 SOC_ENUM_EXT("Input Mono To Stereo", tegra210_sfc_mono_conv_enum, 3450 - tegra210_sfc_get_control, tegra210_sfc_put_control), 3390 + tegra210_sfc_iget_mono_to_stereo, 3391 + tegra210_sfc_iput_mono_to_stereo), 3451 3392 SOC_ENUM_EXT("Output Stereo To Mono", tegra210_sfc_stereo_conv_enum, 3452 - tegra210_sfc_get_control, tegra210_sfc_put_control), 3393 + tegra210_sfc_oget_stereo_to_mono, 3394 + tegra210_sfc_oput_stereo_to_mono), 3453 3395 SOC_ENUM_EXT("Output Mono To Stereo", tegra210_sfc_mono_conv_enum, 3454 - tegra210_sfc_get_control, tegra210_sfc_put_control), 3396 + tegra210_sfc_oget_mono_to_stereo, 3397 + tegra210_sfc_oput_mono_to_stereo), 3455 3398 }; 3456 3399 3457 3400 static const struct snd_soc_component_driver tegra210_sfc_cmpnt = {