diff options
Diffstat (limited to 'sound/pci/hda/patch_sigmatel.c')
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 55 |
1 files changed, 25 insertions, 30 deletions
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index c5906551311..3db39adad79 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include "hda_patch.h" | 35 | #include "hda_patch.h" |
36 | #include "hda_beep.h" | 36 | #include "hda_beep.h" |
37 | 37 | ||
38 | #define NUM_CONTROL_ALLOC 32 | ||
39 | #define STAC_PWR_EVENT 0x20 | 38 | #define STAC_PWR_EVENT 0x20 |
40 | #define STAC_HP_EVENT 0x30 | 39 | #define STAC_HP_EVENT 0x30 |
41 | #define STAC_VREF_EVENT 0x40 | 40 | #define STAC_VREF_EVENT 0x40 |
@@ -218,8 +217,7 @@ struct sigmatel_spec { | |||
218 | 217 | ||
219 | /* dynamic controls and input_mux */ | 218 | /* dynamic controls and input_mux */ |
220 | struct auto_pin_cfg autocfg; | 219 | struct auto_pin_cfg autocfg; |
221 | unsigned int num_kctl_alloc, num_kctl_used; | 220 | struct snd_array kctls; |
222 | struct snd_kcontrol_new *kctl_alloc; | ||
223 | struct hda_input_mux private_dimux; | 221 | struct hda_input_mux private_dimux; |
224 | struct hda_input_mux private_imux; | 222 | struct hda_input_mux private_imux; |
225 | struct hda_input_mux private_smux; | 223 | struct hda_input_mux private_smux; |
@@ -1233,6 +1231,8 @@ static const char *slave_sws[] = { | |||
1233 | NULL | 1231 | NULL |
1234 | }; | 1232 | }; |
1235 | 1233 | ||
1234 | static void stac92xx_free_kctls(struct hda_codec *codec); | ||
1235 | |||
1236 | static int stac92xx_build_controls(struct hda_codec *codec) | 1236 | static int stac92xx_build_controls(struct hda_codec *codec) |
1237 | { | 1237 | { |
1238 | struct sigmatel_spec *spec = codec->spec; | 1238 | struct sigmatel_spec *spec = codec->spec; |
@@ -1305,6 +1305,7 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
1305 | return err; | 1305 | return err; |
1306 | } | 1306 | } |
1307 | 1307 | ||
1308 | stac92xx_free_kctls(codec); /* no longer needed */ | ||
1308 | return 0; | 1309 | return 0; |
1309 | } | 1310 | } |
1310 | 1311 | ||
@@ -2592,28 +2593,16 @@ static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type, | |||
2592 | { | 2593 | { |
2593 | struct snd_kcontrol_new *knew; | 2594 | struct snd_kcontrol_new *knew; |
2594 | 2595 | ||
2595 | if (spec->num_kctl_used >= spec->num_kctl_alloc) { | 2596 | snd_array_init(&spec->kctls, sizeof(*knew), 32); |
2596 | int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; | 2597 | knew = snd_array_new(&spec->kctls); |
2597 | 2598 | if (!knew) | |
2598 | knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ | 2599 | return -ENOMEM; |
2599 | if (! knew) | ||
2600 | return -ENOMEM; | ||
2601 | if (spec->kctl_alloc) { | ||
2602 | memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc); | ||
2603 | kfree(spec->kctl_alloc); | ||
2604 | } | ||
2605 | spec->kctl_alloc = knew; | ||
2606 | spec->num_kctl_alloc = num; | ||
2607 | } | ||
2608 | |||
2609 | knew = &spec->kctl_alloc[spec->num_kctl_used]; | ||
2610 | *knew = stac92xx_control_templates[type]; | 2600 | *knew = stac92xx_control_templates[type]; |
2611 | knew->index = idx; | 2601 | knew->index = idx; |
2612 | knew->name = kstrdup(name, GFP_KERNEL); | 2602 | knew->name = kstrdup(name, GFP_KERNEL); |
2613 | if (! knew->name) | 2603 | if (! knew->name) |
2614 | return -ENOMEM; | 2604 | return -ENOMEM; |
2615 | knew->private_value = val; | 2605 | knew->private_value = val; |
2616 | spec->num_kctl_used++; | ||
2617 | return 0; | 2606 | return 0; |
2618 | } | 2607 | } |
2619 | 2608 | ||
@@ -3434,8 +3423,8 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out | |||
3434 | if (dig_in && spec->autocfg.dig_in_pin) | 3423 | if (dig_in && spec->autocfg.dig_in_pin) |
3435 | spec->dig_in_nid = dig_in; | 3424 | spec->dig_in_nid = dig_in; |
3436 | 3425 | ||
3437 | if (spec->kctl_alloc) | 3426 | if (spec->kctls.list) |
3438 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 3427 | spec->mixers[spec->num_mixers++] = spec->kctls.list; |
3439 | 3428 | ||
3440 | spec->input_mux = &spec->private_imux; | 3429 | spec->input_mux = &spec->private_imux; |
3441 | spec->dinput_mux = &spec->private_dimux; | 3430 | spec->dinput_mux = &spec->private_dimux; |
@@ -3536,8 +3525,8 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) | |||
3536 | if (spec->autocfg.dig_in_pin) | 3525 | if (spec->autocfg.dig_in_pin) |
3537 | spec->dig_in_nid = 0x04; | 3526 | spec->dig_in_nid = 0x04; |
3538 | 3527 | ||
3539 | if (spec->kctl_alloc) | 3528 | if (spec->kctls.list) |
3540 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 3529 | spec->mixers[spec->num_mixers++] = spec->kctls.list; |
3541 | 3530 | ||
3542 | spec->input_mux = &spec->private_imux; | 3531 | spec->input_mux = &spec->private_imux; |
3543 | spec->dinput_mux = &spec->private_dimux; | 3532 | spec->dinput_mux = &spec->private_dimux; |
@@ -3698,20 +3687,26 @@ static int stac92xx_init(struct hda_codec *codec) | |||
3698 | return 0; | 3687 | return 0; |
3699 | } | 3688 | } |
3700 | 3689 | ||
3690 | static void stac92xx_free_kctls(struct hda_codec *codec) | ||
3691 | { | ||
3692 | struct sigmatel_spec *spec = codec->spec; | ||
3693 | |||
3694 | if (spec->kctls.list) { | ||
3695 | struct snd_kcontrol_new *kctl = spec->kctls.list; | ||
3696 | int i; | ||
3697 | for (i = 0; i < spec->kctls.used; i++) | ||
3698 | kfree(kctl[i].name); | ||
3699 | } | ||
3700 | snd_array_free(&spec->kctls); | ||
3701 | } | ||
3702 | |||
3701 | static void stac92xx_free(struct hda_codec *codec) | 3703 | static void stac92xx_free(struct hda_codec *codec) |
3702 | { | 3704 | { |
3703 | struct sigmatel_spec *spec = codec->spec; | 3705 | struct sigmatel_spec *spec = codec->spec; |
3704 | int i; | ||
3705 | 3706 | ||
3706 | if (! spec) | 3707 | if (! spec) |
3707 | return; | 3708 | return; |
3708 | 3709 | ||
3709 | if (spec->kctl_alloc) { | ||
3710 | for (i = 0; i < spec->num_kctl_used; i++) | ||
3711 | kfree(spec->kctl_alloc[i].name); | ||
3712 | kfree(spec->kctl_alloc); | ||
3713 | } | ||
3714 | |||
3715 | if (spec->bios_pin_configs) | 3710 | if (spec->bios_pin_configs) |
3716 | kfree(spec->bios_pin_configs); | 3711 | kfree(spec->bios_pin_configs); |
3717 | 3712 | ||