diff options
Diffstat (limited to 'sound/pci/hda/patch_analog.c')
-rw-r--r-- | sound/pci/hda/patch_analog.c | 56 |
1 files changed, 27 insertions, 29 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 2b00c4afdf9..02643bce563 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -67,8 +67,7 @@ struct ad198x_spec { /* dynamic controls, init_verbs and input_mux */ struct auto_pin_cfg autocfg; - unsigned int num_kctl_alloc, num_kctl_used; - struct snd_kcontrol_new *kctl_alloc; + struct snd_array kctls; struct hda_input_mux private_imux; hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; @@ -154,6 +153,8 @@ static const char *ad_slave_sws[] = { NULL }; +static void ad198x_free_kctls(struct hda_codec *codec); + static int ad198x_build_controls(struct hda_codec *codec) { struct ad198x_spec *spec = codec->spec; @@ -202,6 +203,7 @@ static int ad198x_build_controls(struct hda_codec *codec) return err; } + ad198x_free_kctls(codec); /* no longer needed */ return 0; } @@ -375,16 +377,27 @@ static int ad198x_build_pcms(struct hda_codec *codec) return 0; } -static void ad198x_free(struct hda_codec *codec) +static void ad198x_free_kctls(struct hda_codec *codec) { struct ad198x_spec *spec = codec->spec; - unsigned int i; - if (spec->kctl_alloc) { - for (i = 0; i < spec->num_kctl_used; i++) - kfree(spec->kctl_alloc[i].name); - kfree(spec->kctl_alloc); + if (spec->kctls.list) { + struct snd_kcontrol_new *kctl = spec->kctls.list; + int i; + for (i = 0; i < spec->kctls.used; i++) + kfree(kctl[i].name); } + snd_array_free(&spec->kctls); +} + +static void ad198x_free(struct hda_codec *codec) +{ + struct ad198x_spec *spec = codec->spec; + + if (!spec) + return; + + ad198x_free_kctls(codec); kfree(codec->spec); } @@ -2452,9 +2465,6 @@ static struct hda_amp_list ad1988_loopbacks[] = { * Automatic parse of I/O pins from the BIOS configuration */ -#define NUM_CONTROL_ALLOC 32 -#define NUM_VERB_ALLOC 32 - enum { AD_CTL_WIDGET_VOL, AD_CTL_WIDGET_MUTE, @@ -2472,27 +2482,15 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name, { struct snd_kcontrol_new *knew; - if (spec->num_kctl_used >= spec->num_kctl_alloc) { - int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; - - knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ - if (! knew) - return -ENOMEM; - if (spec->kctl_alloc) { - memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc); - kfree(spec->kctl_alloc); - } - spec->kctl_alloc = knew; - spec->num_kctl_alloc = num; - } - - knew = &spec->kctl_alloc[spec->num_kctl_used]; + snd_array_init(&spec->kctls, sizeof(*knew), 32); + knew = snd_array_new(&spec->kctls); + if (!knew) + return -ENOMEM; *knew = ad1988_control_templates[type]; knew->name = kstrdup(name, GFP_KERNEL); if (! knew->name) return -ENOMEM; knew->private_value = val; - spec->num_kctl_used++; return 0; } @@ -2846,8 +2844,8 @@ static int ad1988_parse_auto_config(struct hda_codec *codec) if (spec->autocfg.dig_in_pin) spec->dig_in_nid = AD1988_SPDIF_IN; - if (spec->kctl_alloc) - spec->mixers[spec->num_mixers++] = spec->kctl_alloc; + if (spec->kctls.list) + spec->mixers[spec->num_mixers++] = spec->kctls.list; spec->init_verbs[spec->num_init_verbs++] = ad1988_6stack_init_verbs; |