sound fixes for 5.16-rc5

Another collection of small fixes.  It's still not quite calm yet,
 but nothing looks scary.
 
 ALSA core got a few fixes for covering the issues detected by fuzzer
 and the 32bit compat problem of control API, while the rest are all
 device-specific small fixes, including the continued fixes for Tegra.
 -----BEGIN PGP SIGNATURE-----
 
 iQJCBAABCAAsFiEEIXTw5fNLNI7mMiVaLtJE4w1nLE8FAmGyKGsOHHRpd2FpQHN1
 c2UuZGUACgkQLtJE4w1nLE+56w/+ME2YljtbD2RhYzJs2X8ARvusOO3mX1Zjr/36
 +7wBRi8WwRVH3jn59CnhgCDXSxTaM8GYbFje8kAyYv0Ib+f9bAvao7pgFAPFEd//
 ZRZBQ0bCF18Pp4oNqbR/F6K2XyLyzQeRQPWl2z0oZq4zuWXtK59pQnXbEYV/UGx8
 MMciRA4aj7qYaaQj4juBNKuxgixAyCatcOJh6t5O4dy2N9naQi0TShMF49ca8uRR
 nSOq1YeEBpIOd4DVto4P6sQ7tpyfffj4qPhXGvemYnhBfwMhUVJyWxFjXXGJY2rT
 KrFtuOHlS7NlScvT36GowbQdB5wgXJ7eLJg/JXVi3HBCrV4zHlp7Jn/Nbr62SYIu
 h5gkgNN04Hjgel5lTvsJPiirxfxWpbVeF84HOrkrx6teOsGWZtW10Zms0YkovKmg
 hR23YRNbX4qko6evBvg4lRlSlbTznOvzHKY323joebjSYp4kSJyNdqc+8fgVpK3E
 Fx9DJmBSyGp/n2gkKZEhDVSgcWZyGvPkFqondCjwxqWV+jvJWSnScTjUyMeOfUCt
 lFV4tlIMQ58t5u6BRaMGTenTxQ6Dqf5nOR1hwK5EPR5RQwu3chFfYDsm0C9ZKfsG
 mCMe3BTvdl3W2nShwIH11B/ukieqAVZ7uugSFAarYamDfupPcwO69lPIeFAEuzjw
 N+us0rg=
 =g4gf
 -----END PGP SIGNATURE-----

Merge tag 'sound-5.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound

Pull sound fixes from Takashi Iwai:
 "Another collection of small fixes. It's still not quite calm yet, but
  nothing looks scary.

  ALSA core got a few fixes for covering the issues detected by fuzzer
  and the 32bit compat problem of control API, while the rest are all
  device-specific small fixes, including the continued fixes for Tegra"

* tag 'sound-5.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (23 commits)
  ALSA: hda/realtek - Add headset Mic support for Lenovo ALC897 platform
  ALSA: usb-audio: Reorder snd_djm_devices[] entries
  ALSA: hda/realtek: Fix quirk for TongFang PHxTxX1
  ALSA: ctl: Fix copy of updated id with element read/write
  ALSA: pcm: oss: Handle missing errors in snd_pcm_oss_change_params*()
  ALSA: pcm: oss: Limit the period size to 16MB
  ALSA: pcm: oss: Fix negative period/buffer sizes
  ASoC: codecs: wsa881x: fix return values from kcontrol put
  ASoC: codecs: wcd934x: return correct value from mixer put
  ASoC: codecs: wcd934x: handle channel mappping list correctly
  ASoC: qdsp6: q6routing: Fix return value from msm_routing_put_audio_mixer
  ASoC: SOF: Intel: Retry codec probing if it fails
  ASoC: amd: fix uninitialized variable in snd_acp6x_probe()
  ASoC: rockchip: i2s_tdm: Dup static DAI template
  ASoC: rt5682s: Fix crash due to out of scope stack vars
  ASoC: rt5682: Fix crash due to out of scope stack vars
  ASoC: tegra: Use normal system sleep for ADX
  ASoC: tegra: Use normal system sleep for AMX
  ASoC: tegra: Use normal system sleep for Mixer
  ASoC: tegra: Use normal system sleep for MVC
  ...
This commit is contained in:
Linus Torvalds 2021-12-10 11:43:00 -08:00
commit 5b46fb0383
18 changed files with 274 additions and 122 deletions

View File

@ -19,6 +19,9 @@ properties:
clocks: clocks:
maxItems: 1 maxItems: 1
interrupts:
maxItems: 1
"#sound-dai-cells": "#sound-dai-cells":
const: 0 const: 0

View File

@ -264,6 +264,7 @@ static int copy_ctl_value_to_user(void __user *userdata,
struct snd_ctl_elem_value *data, struct snd_ctl_elem_value *data,
int type, int count) int type, int count)
{ {
struct snd_ctl_elem_value32 __user *data32 = userdata;
int i, size; int i, size;
if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN || if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
@ -280,6 +281,8 @@ static int copy_ctl_value_to_user(void __user *userdata,
if (copy_to_user(valuep, data->value.bytes.data, size)) if (copy_to_user(valuep, data->value.bytes.data, size))
return -EFAULT; return -EFAULT;
} }
if (copy_to_user(&data32->id, &data->id, sizeof(data32->id)))
return -EFAULT;
return 0; return 0;
} }

View File

@ -147,7 +147,7 @@ snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params,
* *
* Return the maximum value for field PAR. * Return the maximum value for field PAR.
*/ */
static unsigned int static int
snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params, snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params,
snd_pcm_hw_param_t var, int *dir) snd_pcm_hw_param_t var, int *dir)
{ {
@ -682,18 +682,24 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *oss_params, struct snd_pcm_hw_params *oss_params,
struct snd_pcm_hw_params *slave_params) struct snd_pcm_hw_params *slave_params)
{ {
size_t s; ssize_t s;
size_t oss_buffer_size, oss_period_size, oss_periods; ssize_t oss_buffer_size;
size_t min_period_size, max_period_size; ssize_t oss_period_size, oss_periods;
ssize_t min_period_size, max_period_size;
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
size_t oss_frame_size; size_t oss_frame_size;
oss_frame_size = snd_pcm_format_physical_width(params_format(oss_params)) * oss_frame_size = snd_pcm_format_physical_width(params_format(oss_params)) *
params_channels(oss_params) / 8; params_channels(oss_params) / 8;
oss_buffer_size = snd_pcm_hw_param_value_max(slave_params,
SNDRV_PCM_HW_PARAM_BUFFER_SIZE,
NULL);
if (oss_buffer_size <= 0)
return -EINVAL;
oss_buffer_size = snd_pcm_plug_client_size(substream, oss_buffer_size = snd_pcm_plug_client_size(substream,
snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size; oss_buffer_size * oss_frame_size);
if (!oss_buffer_size) if (oss_buffer_size <= 0)
return -EINVAL; return -EINVAL;
oss_buffer_size = rounddown_pow_of_two(oss_buffer_size); oss_buffer_size = rounddown_pow_of_two(oss_buffer_size);
if (atomic_read(&substream->mmap_count)) { if (atomic_read(&substream->mmap_count)) {
@ -730,7 +736,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
min_period_size = snd_pcm_plug_client_size(substream, min_period_size = snd_pcm_plug_client_size(substream,
snd_pcm_hw_param_value_min(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL)); snd_pcm_hw_param_value_min(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL));
if (min_period_size) { if (min_period_size > 0) {
min_period_size *= oss_frame_size; min_period_size *= oss_frame_size;
min_period_size = roundup_pow_of_two(min_period_size); min_period_size = roundup_pow_of_two(min_period_size);
if (oss_period_size < min_period_size) if (oss_period_size < min_period_size)
@ -739,7 +745,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
max_period_size = snd_pcm_plug_client_size(substream, max_period_size = snd_pcm_plug_client_size(substream,
snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL)); snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL));
if (max_period_size) { if (max_period_size > 0) {
max_period_size *= oss_frame_size; max_period_size *= oss_frame_size;
max_period_size = rounddown_pow_of_two(max_period_size); max_period_size = rounddown_pow_of_two(max_period_size);
if (oss_period_size > max_period_size) if (oss_period_size > max_period_size)
@ -752,7 +758,7 @@ static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
oss_periods = substream->oss.setup.periods; oss_periods = substream->oss.setup.periods;
s = snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIODS, NULL); s = snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIODS, NULL);
if (runtime->oss.maxfrags && s > runtime->oss.maxfrags) if (s > 0 && runtime->oss.maxfrags && s > runtime->oss.maxfrags)
s = runtime->oss.maxfrags; s = runtime->oss.maxfrags;
if (oss_periods > s) if (oss_periods > s)
oss_periods = s; oss_periods = s;
@ -878,8 +884,15 @@ static int snd_pcm_oss_change_params_locked(struct snd_pcm_substream *substream)
err = -EINVAL; err = -EINVAL;
goto failure; goto failure;
} }
choose_rate(substream, sparams, runtime->oss.rate);
snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_CHANNELS, runtime->oss.channels, NULL); err = choose_rate(substream, sparams, runtime->oss.rate);
if (err < 0)
goto failure;
err = snd_pcm_hw_param_near(substream, sparams,
SNDRV_PCM_HW_PARAM_CHANNELS,
runtime->oss.channels, NULL);
if (err < 0)
goto failure;
format = snd_pcm_oss_format_from(runtime->oss.format); format = snd_pcm_oss_format_from(runtime->oss.format);
@ -1956,7 +1969,7 @@ static int snd_pcm_oss_set_fragment1(struct snd_pcm_substream *substream, unsign
if (runtime->oss.subdivision || runtime->oss.fragshift) if (runtime->oss.subdivision || runtime->oss.fragshift)
return -EINVAL; return -EINVAL;
fragshift = val & 0xffff; fragshift = val & 0xffff;
if (fragshift >= 31) if (fragshift >= 25) /* should be large enough */
return -EINVAL; return -EINVAL;
runtime->oss.fragshift = fragshift; runtime->oss.fragshift = fragshift;
runtime->oss.maxfrags = (val >> 16) & 0xffff; runtime->oss.maxfrags = (val >> 16) & 0xffff;

View File

@ -6503,22 +6503,26 @@ static void alc287_fixup_legion_15imhg05_speakers(struct hda_codec *codec,
/* for alc285_fixup_ideapad_s740_coef() */ /* for alc285_fixup_ideapad_s740_coef() */
#include "ideapad_s740_helper.c" #include "ideapad_s740_helper.c"
static void alc256_fixup_tongfang_reset_persistent_settings(struct hda_codec *codec, static const struct coef_fw alc256_fixup_set_coef_defaults_coefs[] = {
const struct hda_fixup *fix, WRITE_COEF(0x10, 0x0020), WRITE_COEF(0x24, 0x0000),
int action) WRITE_COEF(0x26, 0x0000), WRITE_COEF(0x29, 0x3000),
WRITE_COEF(0x37, 0xfe05), WRITE_COEF(0x45, 0x5089),
{}
};
static void alc256_fixup_set_coef_defaults(struct hda_codec *codec,
const struct hda_fixup *fix,
int action)
{ {
/* /*
* A certain other OS sets these coeffs to different values. On at least one TongFang * A certain other OS sets these coeffs to different values. On at least
* barebone these settings might survive even a cold reboot. So to restore a clean slate the * one TongFang barebone these settings might survive even a cold
* values are explicitly reset to default here. Without this, the external microphone is * reboot. So to restore a clean slate the values are explicitly reset
* always in a plugged-in state, while the internal microphone is always in an unplugged * to default here. Without this, the external microphone is always in a
* state, breaking the ability to use the internal microphone. * plugged-in state, while the internal microphone is always in an
*/ * unplugged state, breaking the ability to use the internal microphone.
alc_write_coef_idx(codec, 0x24, 0x0000); */
alc_write_coef_idx(codec, 0x26, 0x0000); alc_process_coef_fw(codec, alc256_fixup_set_coef_defaults_coefs);
alc_write_coef_idx(codec, 0x29, 0x3000);
alc_write_coef_idx(codec, 0x37, 0xfe05);
alc_write_coef_idx(codec, 0x45, 0x5089);
} }
static const struct coef_fw alc233_fixup_no_audio_jack_coefs[] = { static const struct coef_fw alc233_fixup_no_audio_jack_coefs[] = {
@ -6759,7 +6763,7 @@ enum {
ALC287_FIXUP_LEGION_15IMHG05_AUTOMUTE, ALC287_FIXUP_LEGION_15IMHG05_AUTOMUTE,
ALC287_FIXUP_YOGA7_14ITL_SPEAKERS, ALC287_FIXUP_YOGA7_14ITL_SPEAKERS,
ALC287_FIXUP_13S_GEN2_SPEAKERS, ALC287_FIXUP_13S_GEN2_SPEAKERS,
ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS, ALC256_FIXUP_SET_COEF_DEFAULTS,
ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE, ALC256_FIXUP_SYSTEM76_MIC_NO_PRESENCE,
ALC233_FIXUP_NO_AUDIO_JACK, ALC233_FIXUP_NO_AUDIO_JACK,
}; };
@ -8465,9 +8469,9 @@ static const struct hda_fixup alc269_fixups[] = {
.chained = true, .chained = true,
.chain_id = ALC269_FIXUP_HEADSET_MODE, .chain_id = ALC269_FIXUP_HEADSET_MODE,
}, },
[ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS] = { [ALC256_FIXUP_SET_COEF_DEFAULTS] = {
.type = HDA_FIXUP_FUNC, .type = HDA_FIXUP_FUNC,
.v.func = alc256_fixup_tongfang_reset_persistent_settings, .v.func = alc256_fixup_set_coef_defaults,
}, },
[ALC245_FIXUP_HP_GPIO_LED] = { [ALC245_FIXUP_HP_GPIO_LED] = {
.type = HDA_FIXUP_FUNC, .type = HDA_FIXUP_FUNC,
@ -8929,7 +8933,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802), SND_PCI_QUIRK(0x1c06, 0x2013, "Lemote A1802", ALC269_FIXUP_LEMOTE_A1802),
SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X), SND_PCI_QUIRK(0x1c06, 0x2015, "Lemote A190X", ALC269_FIXUP_LEMOTE_A190X),
SND_PCI_QUIRK(0x1d05, 0x1132, "TongFang PHxTxX1", ALC256_FIXUP_TONGFANG_RESET_PERSISTENT_SETTINGS), SND_PCI_QUIRK(0x1d05, 0x1132, "TongFang PHxTxX1", ALC256_FIXUP_SET_COEF_DEFAULTS),
SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC), SND_PCI_QUIRK(0x1d72, 0x1602, "RedmiBook", ALC255_FIXUP_XIAOMI_HEADSET_MIC),
SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE), SND_PCI_QUIRK(0x1d72, 0x1701, "XiaomiNotebook Pro", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC), SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC),
@ -10231,6 +10235,27 @@ static void alc671_fixup_hp_headset_mic2(struct hda_codec *codec,
} }
} }
static void alc897_hp_automute_hook(struct hda_codec *codec,
struct hda_jack_callback *jack)
{
struct alc_spec *spec = codec->spec;
int vref;
snd_hda_gen_hp_automute(codec, jack);
vref = spec->gen.hp_jack_present ? (PIN_HP | AC_PINCTL_VREF_100) : PIN_HP;
snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
vref);
}
static void alc897_fixup_lenovo_headset_mic(struct hda_codec *codec,
const struct hda_fixup *fix, int action)
{
struct alc_spec *spec = codec->spec;
if (action == HDA_FIXUP_ACT_PRE_PROBE) {
spec->gen.hp_automute_hook = alc897_hp_automute_hook;
}
}
static const struct coef_fw alc668_coefs[] = { static const struct coef_fw alc668_coefs[] = {
WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0), WRITE_COEF(0x01, 0xbebe), WRITE_COEF(0x02, 0xaaaa), WRITE_COEF(0x03, 0x0),
WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80), WRITE_COEF(0x04, 0x0180), WRITE_COEF(0x06, 0x0), WRITE_COEF(0x07, 0x0f80),
@ -10311,6 +10336,8 @@ enum {
ALC668_FIXUP_ASUS_NO_HEADSET_MIC, ALC668_FIXUP_ASUS_NO_HEADSET_MIC,
ALC668_FIXUP_HEADSET_MIC, ALC668_FIXUP_HEADSET_MIC,
ALC668_FIXUP_MIC_DET_COEF, ALC668_FIXUP_MIC_DET_COEF,
ALC897_FIXUP_LENOVO_HEADSET_MIC,
ALC897_FIXUP_HEADSET_MIC_PIN,
}; };
static const struct hda_fixup alc662_fixups[] = { static const struct hda_fixup alc662_fixups[] = {
@ -10717,6 +10744,19 @@ static const struct hda_fixup alc662_fixups[] = {
{} {}
}, },
}, },
[ALC897_FIXUP_LENOVO_HEADSET_MIC] = {
.type = HDA_FIXUP_FUNC,
.v.func = alc897_fixup_lenovo_headset_mic,
},
[ALC897_FIXUP_HEADSET_MIC_PIN] = {
.type = HDA_FIXUP_PINS,
.v.pins = (const struct hda_pintbl[]) {
{ 0x1a, 0x03a11050 },
{ }
},
.chained = true,
.chain_id = ALC897_FIXUP_LENOVO_HEADSET_MIC
},
}; };
static const struct snd_pci_quirk alc662_fixup_tbl[] = { static const struct snd_pci_quirk alc662_fixup_tbl[] = {
@ -10761,6 +10801,10 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE), SND_PCI_QUIRK(0x14cd, 0x5003, "USI", ALC662_FIXUP_USI_HEADSET_MODE),
SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS), SND_PCI_QUIRK(0x17aa, 0x1036, "Lenovo P520", ALC662_FIXUP_LENOVO_MULTI_CODECS),
SND_PCI_QUIRK(0x17aa, 0x32ca, "Lenovo ThinkCentre M80", ALC897_FIXUP_HEADSET_MIC_PIN),
SND_PCI_QUIRK(0x17aa, 0x32cb, "Lenovo ThinkCentre M70", ALC897_FIXUP_HEADSET_MIC_PIN),
SND_PCI_QUIRK(0x17aa, 0x32cf, "Lenovo ThinkCentre M950", ALC897_FIXUP_HEADSET_MIC_PIN),
SND_PCI_QUIRK(0x17aa, 0x32f7, "Lenovo ThinkCentre M90", ALC897_FIXUP_HEADSET_MIC_PIN),
SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO), SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),

View File

@ -146,10 +146,11 @@ static int snd_acp6x_probe(struct pci_dev *pci,
{ {
struct acp6x_dev_data *adata; struct acp6x_dev_data *adata;
struct platform_device_info pdevinfo[ACP6x_DEVS]; struct platform_device_info pdevinfo[ACP6x_DEVS];
int ret, index; int index = 0;
int val = 0x00; int val = 0x00;
u32 addr; u32 addr;
unsigned int irqflags; unsigned int irqflags;
int ret;
irqflags = IRQF_SHARED; irqflags = IRQF_SHARED;
/* Yellow Carp device check */ /* Yellow Carp device check */

View File

@ -2858,6 +2858,8 @@ int rt5682_register_dai_clks(struct rt5682_priv *rt5682)
for (i = 0; i < RT5682_DAI_NUM_CLKS; ++i) { for (i = 0; i < RT5682_DAI_NUM_CLKS; ++i) {
struct clk_init_data init = { }; struct clk_init_data init = { };
struct clk_parent_data parent_data;
const struct clk_hw *parent;
dai_clk_hw = &rt5682->dai_clks_hw[i]; dai_clk_hw = &rt5682->dai_clks_hw[i];
@ -2865,17 +2867,17 @@ int rt5682_register_dai_clks(struct rt5682_priv *rt5682)
case RT5682_DAI_WCLK_IDX: case RT5682_DAI_WCLK_IDX:
/* Make MCLK the parent of WCLK */ /* Make MCLK the parent of WCLK */
if (rt5682->mclk) { if (rt5682->mclk) {
init.parent_data = &(struct clk_parent_data){ parent_data = (struct clk_parent_data){
.fw_name = "mclk", .fw_name = "mclk",
}; };
init.parent_data = &parent_data;
init.num_parents = 1; init.num_parents = 1;
} }
break; break;
case RT5682_DAI_BCLK_IDX: case RT5682_DAI_BCLK_IDX:
/* Make WCLK the parent of BCLK */ /* Make WCLK the parent of BCLK */
init.parent_hws = &(const struct clk_hw *){ parent = &rt5682->dai_clks_hw[RT5682_DAI_WCLK_IDX];
&rt5682->dai_clks_hw[RT5682_DAI_WCLK_IDX] init.parent_hws = &parent;
};
init.num_parents = 1; init.num_parents = 1;
break; break;
default: default:

View File

@ -2693,6 +2693,8 @@ static int rt5682s_register_dai_clks(struct snd_soc_component *component)
for (i = 0; i < RT5682S_DAI_NUM_CLKS; ++i) { for (i = 0; i < RT5682S_DAI_NUM_CLKS; ++i) {
struct clk_init_data init = { }; struct clk_init_data init = { };
struct clk_parent_data parent_data;
const struct clk_hw *parent;
dai_clk_hw = &rt5682s->dai_clks_hw[i]; dai_clk_hw = &rt5682s->dai_clks_hw[i];
@ -2700,17 +2702,17 @@ static int rt5682s_register_dai_clks(struct snd_soc_component *component)
case RT5682S_DAI_WCLK_IDX: case RT5682S_DAI_WCLK_IDX:
/* Make MCLK the parent of WCLK */ /* Make MCLK the parent of WCLK */
if (rt5682s->mclk) { if (rt5682s->mclk) {
init.parent_data = &(struct clk_parent_data){ parent_data = (struct clk_parent_data){
.fw_name = "mclk", .fw_name = "mclk",
}; };
init.parent_data = &parent_data;
init.num_parents = 1; init.num_parents = 1;
} }
break; break;
case RT5682S_DAI_BCLK_IDX: case RT5682S_DAI_BCLK_IDX:
/* Make WCLK the parent of BCLK */ /* Make WCLK the parent of BCLK */
init.parent_hws = &(const struct clk_hw *){ parent = &rt5682s->dai_clks_hw[RT5682S_DAI_WCLK_IDX];
&rt5682s->dai_clks_hw[RT5682S_DAI_WCLK_IDX] init.parent_hws = &parent;
};
init.num_parents = 1; init.num_parents = 1;
break; break;
default: default:

View File

@ -3256,6 +3256,9 @@ static int wcd934x_compander_set(struct snd_kcontrol *kc,
int value = ucontrol->value.integer.value[0]; int value = ucontrol->value.integer.value[0];
int sel; int sel;
if (wcd->comp_enabled[comp] == value)
return 0;
wcd->comp_enabled[comp] = value; wcd->comp_enabled[comp] = value;
sel = value ? WCD934X_HPH_GAIN_SRC_SEL_COMPANDER : sel = value ? WCD934X_HPH_GAIN_SRC_SEL_COMPANDER :
WCD934X_HPH_GAIN_SRC_SEL_REGISTER; WCD934X_HPH_GAIN_SRC_SEL_REGISTER;
@ -3279,10 +3282,10 @@ static int wcd934x_compander_set(struct snd_kcontrol *kc,
case COMPANDER_8: case COMPANDER_8:
break; break;
default: default:
break; return 0;
} }
return 0; return 1;
} }
static int wcd934x_rx_hph_mode_get(struct snd_kcontrol *kc, static int wcd934x_rx_hph_mode_get(struct snd_kcontrol *kc,
@ -3326,6 +3329,31 @@ static int slim_rx_mux_get(struct snd_kcontrol *kc,
return 0; return 0;
} }
static int slim_rx_mux_to_dai_id(int mux)
{
int aif_id;
switch (mux) {
case 1:
aif_id = AIF1_PB;
break;
case 2:
aif_id = AIF2_PB;
break;
case 3:
aif_id = AIF3_PB;
break;
case 4:
aif_id = AIF4_PB;
break;
default:
aif_id = -1;
break;
}
return aif_id;
}
static int slim_rx_mux_put(struct snd_kcontrol *kc, static int slim_rx_mux_put(struct snd_kcontrol *kc,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
@ -3333,43 +3361,59 @@ static int slim_rx_mux_put(struct snd_kcontrol *kc,
struct wcd934x_codec *wcd = dev_get_drvdata(w->dapm->dev); struct wcd934x_codec *wcd = dev_get_drvdata(w->dapm->dev);
struct soc_enum *e = (struct soc_enum *)kc->private_value; struct soc_enum *e = (struct soc_enum *)kc->private_value;
struct snd_soc_dapm_update *update = NULL; struct snd_soc_dapm_update *update = NULL;
struct wcd934x_slim_ch *ch, *c;
u32 port_id = w->shift; u32 port_id = w->shift;
bool found = false;
int mux_idx;
int prev_mux_idx = wcd->rx_port_value[port_id];
int aif_id;
if (wcd->rx_port_value[port_id] == ucontrol->value.enumerated.item[0]) mux_idx = ucontrol->value.enumerated.item[0];
if (mux_idx == prev_mux_idx)
return 0; return 0;
wcd->rx_port_value[port_id] = ucontrol->value.enumerated.item[0]; switch(mux_idx) {
switch (wcd->rx_port_value[port_id]) {
case 0: case 0:
list_del_init(&wcd->rx_chs[port_id].list); aif_id = slim_rx_mux_to_dai_id(prev_mux_idx);
if (aif_id < 0)
return 0;
list_for_each_entry_safe(ch, c, &wcd->dai[aif_id].slim_ch_list, list) {
if (ch->port == port_id + WCD934X_RX_START) {
found = true;
list_del_init(&ch->list);
break;
}
}
if (!found)
return 0;
break; break;
case 1: case 1 ... 4:
list_add_tail(&wcd->rx_chs[port_id].list, aif_id = slim_rx_mux_to_dai_id(mux_idx);
&wcd->dai[AIF1_PB].slim_ch_list); if (aif_id < 0)
break; return 0;
case 2:
list_add_tail(&wcd->rx_chs[port_id].list, if (list_empty(&wcd->rx_chs[port_id].list)) {
&wcd->dai[AIF2_PB].slim_ch_list); list_add_tail(&wcd->rx_chs[port_id].list,
break; &wcd->dai[aif_id].slim_ch_list);
case 3: } else {
list_add_tail(&wcd->rx_chs[port_id].list, dev_err(wcd->dev ,"SLIM_RX%d PORT is busy\n", port_id);
&wcd->dai[AIF3_PB].slim_ch_list); return 0;
break; }
case 4:
list_add_tail(&wcd->rx_chs[port_id].list,
&wcd->dai[AIF4_PB].slim_ch_list);
break; break;
default: default:
dev_err(wcd->dev, "Unknown AIF %d\n", dev_err(wcd->dev, "Unknown AIF %d\n", mux_idx);
wcd->rx_port_value[port_id]);
goto err; goto err;
} }
wcd->rx_port_value[port_id] = mux_idx;
snd_soc_dapm_mux_update_power(w->dapm, kc, wcd->rx_port_value[port_id], snd_soc_dapm_mux_update_power(w->dapm, kc, wcd->rx_port_value[port_id],
e, update); e, update);
return 0; return 1;
err: err:
return -EINVAL; return -EINVAL;
} }
@ -3815,6 +3859,7 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kc,
struct soc_mixer_control *mixer = struct soc_mixer_control *mixer =
(struct soc_mixer_control *)kc->private_value; (struct soc_mixer_control *)kc->private_value;
int enable = ucontrol->value.integer.value[0]; int enable = ucontrol->value.integer.value[0];
struct wcd934x_slim_ch *ch, *c;
int dai_id = widget->shift; int dai_id = widget->shift;
int port_id = mixer->shift; int port_id = mixer->shift;
@ -3822,17 +3867,32 @@ static int slim_tx_mixer_put(struct snd_kcontrol *kc,
if (enable == wcd->tx_port_value[port_id]) if (enable == wcd->tx_port_value[port_id])
return 0; return 0;
if (enable) {
if (list_empty(&wcd->tx_chs[port_id].list)) {
list_add_tail(&wcd->tx_chs[port_id].list,
&wcd->dai[dai_id].slim_ch_list);
} else {
dev_err(wcd->dev ,"SLIM_TX%d PORT is busy\n", port_id);
return 0;
}
} else {
bool found = false;
list_for_each_entry_safe(ch, c, &wcd->dai[dai_id].slim_ch_list, list) {
if (ch->port == port_id) {
found = true;
list_del_init(&wcd->tx_chs[port_id].list);
break;
}
}
if (!found)
return 0;
}
wcd->tx_port_value[port_id] = enable; wcd->tx_port_value[port_id] = enable;
if (enable)
list_add_tail(&wcd->tx_chs[port_id].list,
&wcd->dai[dai_id].slim_ch_list);
else
list_del_init(&wcd->tx_chs[port_id].list);
snd_soc_dapm_mixer_update_power(widget->dapm, kc, enable, update); snd_soc_dapm_mixer_update_power(widget->dapm, kc, enable, update);
return 0; return 1;
} }
static const struct snd_kcontrol_new aif1_slim_cap_mixer[] = { static const struct snd_kcontrol_new aif1_slim_cap_mixer[] = {

View File

@ -772,7 +772,8 @@ static int wsa881x_put_pa_gain(struct snd_kcontrol *kc,
usleep_range(1000, 1010); usleep_range(1000, 1010);
} }
return 0;
return 1;
} }
static int wsa881x_get_port(struct snd_kcontrol *kcontrol, static int wsa881x_get_port(struct snd_kcontrol *kcontrol,
@ -816,15 +817,22 @@ static int wsa881x_set_port(struct snd_kcontrol *kcontrol,
(struct soc_mixer_control *)kcontrol->private_value; (struct soc_mixer_control *)kcontrol->private_value;
int portidx = mixer->reg; int portidx = mixer->reg;
if (ucontrol->value.integer.value[0]) if (ucontrol->value.integer.value[0]) {
if (data->port_enable[portidx])
return 0;
data->port_enable[portidx] = true; data->port_enable[portidx] = true;
else } else {
if (!data->port_enable[portidx])
return 0;
data->port_enable[portidx] = false; data->port_enable[portidx] = false;
}
if (portidx == WSA881X_PORT_BOOST) /* Boost Switch */ if (portidx == WSA881X_PORT_BOOST) /* Boost Switch */
wsa881x_boost_ctrl(comp, data->port_enable[portidx]); wsa881x_boost_ctrl(comp, data->port_enable[portidx]);
return 0; return 1;
} }
static const char * const smart_boost_lvl_text[] = { static const char * const smart_boost_lvl_text[] = {

View File

@ -498,14 +498,16 @@ static int msm_routing_put_audio_mixer(struct snd_kcontrol *kcontrol,
struct session_data *session = &data->sessions[session_id]; struct session_data *session = &data->sessions[session_id];
if (ucontrol->value.integer.value[0]) { if (ucontrol->value.integer.value[0]) {
if (session->port_id == be_id)
return 0;
session->port_id = be_id; session->port_id = be_id;
snd_soc_dapm_mixer_update_power(dapm, kcontrol, 1, update); snd_soc_dapm_mixer_update_power(dapm, kcontrol, 1, update);
} else { } else {
if (session->port_id == be_id) { if (session->port_id == -1 || session->port_id != be_id)
session->port_id = -1;
return 0; return 0;
}
session->port_id = -1;
snd_soc_dapm_mixer_update_power(dapm, kcontrol, 0, update); snd_soc_dapm_mixer_update_power(dapm, kcontrol, 0, update);
} }

View File

@ -95,6 +95,7 @@ struct rk_i2s_tdm_dev {
spinlock_t lock; /* xfer lock */ spinlock_t lock; /* xfer lock */
bool has_playback; bool has_playback;
bool has_capture; bool has_capture;
struct snd_soc_dai_driver *dai;
}; };
static int to_ch_num(unsigned int val) static int to_ch_num(unsigned int val)
@ -1310,19 +1311,14 @@ static const struct of_device_id rockchip_i2s_tdm_match[] = {
{}, {},
}; };
static struct snd_soc_dai_driver i2s_tdm_dai = { static const struct snd_soc_dai_driver i2s_tdm_dai = {
.probe = rockchip_i2s_tdm_dai_probe, .probe = rockchip_i2s_tdm_dai_probe,
.playback = {
.stream_name = "Playback",
},
.capture = {
.stream_name = "Capture",
},
.ops = &rockchip_i2s_tdm_dai_ops, .ops = &rockchip_i2s_tdm_dai_ops,
}; };
static void rockchip_i2s_tdm_init_dai(struct rk_i2s_tdm_dev *i2s_tdm) static int rockchip_i2s_tdm_init_dai(struct rk_i2s_tdm_dev *i2s_tdm)
{ {
struct snd_soc_dai_driver *dai;
struct property *dma_names; struct property *dma_names;
const char *dma_name; const char *dma_name;
u64 formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | u64 formats = (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |
@ -1337,19 +1333,33 @@ static void rockchip_i2s_tdm_init_dai(struct rk_i2s_tdm_dev *i2s_tdm)
i2s_tdm->has_capture = true; i2s_tdm->has_capture = true;
} }
dai = devm_kmemdup(i2s_tdm->dev, &i2s_tdm_dai,
sizeof(*dai), GFP_KERNEL);
if (!dai)
return -ENOMEM;
if (i2s_tdm->has_playback) { if (i2s_tdm->has_playback) {
i2s_tdm_dai.playback.channels_min = 2; dai->playback.stream_name = "Playback";
i2s_tdm_dai.playback.channels_max = 8; dai->playback.channels_min = 2;
i2s_tdm_dai.playback.rates = SNDRV_PCM_RATE_8000_192000; dai->playback.channels_max = 8;
i2s_tdm_dai.playback.formats = formats; dai->playback.rates = SNDRV_PCM_RATE_8000_192000;
dai->playback.formats = formats;
} }
if (i2s_tdm->has_capture) { if (i2s_tdm->has_capture) {
i2s_tdm_dai.capture.channels_min = 2; dai->capture.stream_name = "Capture";
i2s_tdm_dai.capture.channels_max = 8; dai->capture.channels_min = 2;
i2s_tdm_dai.capture.rates = SNDRV_PCM_RATE_8000_192000; dai->capture.channels_max = 8;
i2s_tdm_dai.capture.formats = formats; dai->capture.rates = SNDRV_PCM_RATE_8000_192000;
dai->capture.formats = formats;
} }
if (i2s_tdm->clk_trcm != TRCM_TXRX)
dai->symmetric_rate = 1;
i2s_tdm->dai = dai;
return 0;
} }
static int rockchip_i2s_tdm_path_check(struct rk_i2s_tdm_dev *i2s_tdm, static int rockchip_i2s_tdm_path_check(struct rk_i2s_tdm_dev *i2s_tdm,
@ -1541,8 +1551,6 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
spin_lock_init(&i2s_tdm->lock); spin_lock_init(&i2s_tdm->lock);
i2s_tdm->soc_data = (struct rk_i2s_soc_data *)of_id->data; i2s_tdm->soc_data = (struct rk_i2s_soc_data *)of_id->data;
rockchip_i2s_tdm_init_dai(i2s_tdm);
i2s_tdm->frame_width = 64; i2s_tdm->frame_width = 64;
i2s_tdm->clk_trcm = TRCM_TXRX; i2s_tdm->clk_trcm = TRCM_TXRX;
@ -1555,8 +1563,10 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
} }
i2s_tdm->clk_trcm = TRCM_RX; i2s_tdm->clk_trcm = TRCM_RX;
} }
if (i2s_tdm->clk_trcm != TRCM_TXRX)
i2s_tdm_dai.symmetric_rate = 1; ret = rockchip_i2s_tdm_init_dai(i2s_tdm);
if (ret)
return ret;
i2s_tdm->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf"); i2s_tdm->grf = syscon_regmap_lookup_by_phandle(node, "rockchip,grf");
if (IS_ERR(i2s_tdm->grf)) if (IS_ERR(i2s_tdm->grf))
@ -1678,7 +1688,7 @@ static int rockchip_i2s_tdm_probe(struct platform_device *pdev)
ret = devm_snd_soc_register_component(&pdev->dev, ret = devm_snd_soc_register_component(&pdev->dev,
&rockchip_i2s_tdm_component, &rockchip_i2s_tdm_component,
&i2s_tdm_dai, 1); i2s_tdm->dai, 1);
if (ret) { if (ret) {
dev_err(&pdev->dev, "Could not register DAI\n"); dev_err(&pdev->dev, "Could not register DAI\n");

View File

@ -22,6 +22,7 @@
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
#define IDISP_VID_INTEL 0x80860000 #define IDISP_VID_INTEL 0x80860000
#define CODEC_PROBE_RETRIES 3
/* load the legacy HDA codec driver */ /* load the legacy HDA codec driver */
static int request_codec_module(struct hda_codec *codec) static int request_codec_module(struct hda_codec *codec)
@ -121,12 +122,15 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
u32 hda_cmd = (address << 28) | (AC_NODE_ROOT << 20) | u32 hda_cmd = (address << 28) | (AC_NODE_ROOT << 20) |
(AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
u32 resp = -1; u32 resp = -1;
int ret; int ret, retry = 0;
do {
mutex_lock(&hbus->core.cmd_mutex);
snd_hdac_bus_send_cmd(&hbus->core, hda_cmd);
snd_hdac_bus_get_response(&hbus->core, address, &resp);
mutex_unlock(&hbus->core.cmd_mutex);
} while (resp == -1 && retry++ < CODEC_PROBE_RETRIES);
mutex_lock(&hbus->core.cmd_mutex);
snd_hdac_bus_send_cmd(&hbus->core, hda_cmd);
snd_hdac_bus_get_response(&hbus->core, address, &resp);
mutex_unlock(&hbus->core.cmd_mutex);
if (resp == -1) if (resp == -1)
return -EIO; return -EIO;
dev_dbg(sdev->dev, "HDA codec #%d probed OK: response: %x\n", dev_dbg(sdev->dev, "HDA codec #%d probed OK: response: %x\n",

View File

@ -514,8 +514,8 @@ static int tegra210_adx_platform_remove(struct platform_device *pdev)
static const struct dev_pm_ops tegra210_adx_pm_ops = { static const struct dev_pm_ops tegra210_adx_pm_ops = {
SET_RUNTIME_PM_OPS(tegra210_adx_runtime_suspend, SET_RUNTIME_PM_OPS(tegra210_adx_runtime_suspend,
tegra210_adx_runtime_resume, NULL) tegra210_adx_runtime_resume, NULL)
SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume) pm_runtime_force_resume)
}; };
static struct platform_driver tegra210_adx_driver = { static struct platform_driver tegra210_adx_driver = {

View File

@ -583,8 +583,8 @@ static int tegra210_amx_platform_remove(struct platform_device *pdev)
static const struct dev_pm_ops tegra210_amx_pm_ops = { static const struct dev_pm_ops tegra210_amx_pm_ops = {
SET_RUNTIME_PM_OPS(tegra210_amx_runtime_suspend, SET_RUNTIME_PM_OPS(tegra210_amx_runtime_suspend,
tegra210_amx_runtime_resume, NULL) tegra210_amx_runtime_resume, NULL)
SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume) pm_runtime_force_resume)
}; };
static struct platform_driver tegra210_amx_driver = { static struct platform_driver tegra210_amx_driver = {

View File

@ -666,8 +666,8 @@ static int tegra210_mixer_platform_remove(struct platform_device *pdev)
static const struct dev_pm_ops tegra210_mixer_pm_ops = { static const struct dev_pm_ops tegra210_mixer_pm_ops = {
SET_RUNTIME_PM_OPS(tegra210_mixer_runtime_suspend, SET_RUNTIME_PM_OPS(tegra210_mixer_runtime_suspend,
tegra210_mixer_runtime_resume, NULL) tegra210_mixer_runtime_resume, NULL)
SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume) pm_runtime_force_resume)
}; };
static struct platform_driver tegra210_mixer_driver = { static struct platform_driver tegra210_mixer_driver = {

View File

@ -164,7 +164,7 @@ static int tegra210_mvc_put_mute(struct snd_kcontrol *kcontrol,
if (err < 0) if (err < 0)
goto end; goto end;
return 1; err = 1;
end: end:
pm_runtime_put(cmpnt->dev); pm_runtime_put(cmpnt->dev);
@ -236,7 +236,7 @@ static int tegra210_mvc_put_vol(struct snd_kcontrol *kcontrol,
TEGRA210_MVC_VOLUME_SWITCH_MASK, TEGRA210_MVC_VOLUME_SWITCH_MASK,
TEGRA210_MVC_VOLUME_SWITCH_TRIGGER); TEGRA210_MVC_VOLUME_SWITCH_TRIGGER);
return 1; err = 1;
end: end:
pm_runtime_put(cmpnt->dev); pm_runtime_put(cmpnt->dev);
@ -639,8 +639,8 @@ static int tegra210_mvc_platform_remove(struct platform_device *pdev)
static const struct dev_pm_ops tegra210_mvc_pm_ops = { static const struct dev_pm_ops tegra210_mvc_pm_ops = {
SET_RUNTIME_PM_OPS(tegra210_mvc_runtime_suspend, SET_RUNTIME_PM_OPS(tegra210_mvc_runtime_suspend,
tegra210_mvc_runtime_resume, NULL) tegra210_mvc_runtime_resume, NULL)
SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume) pm_runtime_force_resume)
}; };
static struct platform_driver tegra210_mvc_driver = { static struct platform_driver tegra210_mvc_driver = {

View File

@ -3594,8 +3594,8 @@ static int tegra210_sfc_platform_remove(struct platform_device *pdev)
static const struct dev_pm_ops tegra210_sfc_pm_ops = { static const struct dev_pm_ops tegra210_sfc_pm_ops = {
SET_RUNTIME_PM_OPS(tegra210_sfc_runtime_suspend, SET_RUNTIME_PM_OPS(tegra210_sfc_runtime_suspend,
tegra210_sfc_runtime_resume, NULL) tegra210_sfc_runtime_resume, NULL)
SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume) pm_runtime_force_resume)
}; };
static struct platform_driver tegra210_sfc_driver = { static struct platform_driver tegra210_sfc_driver = {

View File

@ -3016,11 +3016,11 @@ static const struct snd_djm_ctl snd_djm_ctls_750mk2[] = {
static const struct snd_djm_device snd_djm_devices[] = { static const struct snd_djm_device snd_djm_devices[] = {
SND_DJM_DEVICE(250mk2), [SND_DJM_250MK2_IDX] = SND_DJM_DEVICE(250mk2),
SND_DJM_DEVICE(750), [SND_DJM_750_IDX] = SND_DJM_DEVICE(750),
SND_DJM_DEVICE(750mk2), [SND_DJM_850_IDX] = SND_DJM_DEVICE(850),
SND_DJM_DEVICE(850), [SND_DJM_900NXS2_IDX] = SND_DJM_DEVICE(900nxs2),
SND_DJM_DEVICE(900nxs2) [SND_DJM_750MK2_IDX] = SND_DJM_DEVICE(750mk2),
}; };