diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-07-30 09:01:44 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-10-12 20:42:59 -0400 |
commit | 603c40199252f0c3b91fca02fd3283c4f8e55179 (patch) | |
tree | dbd8643b288a1d3088d6f5af30e58d699e2761b4 /sound/pci/hda/patch_realtek.c | |
parent | b2e1859745b783922533d29e3b03af29378a23f0 (diff) |
ALSA: hda - Use generic array helpers
Use generic array helpers to simplify array handling in snd-hda-intel.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/patch_realtek.c')
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 86 |
1 files changed, 40 insertions, 46 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0b6e682c46d0..3e21a7198656 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -284,8 +284,7 @@ struct alc_spec { | |||
284 | 284 | ||
285 | /* dynamic controls, init_verbs and input_mux */ | 285 | /* dynamic controls, init_verbs and input_mux */ |
286 | struct auto_pin_cfg autocfg; | 286 | struct auto_pin_cfg autocfg; |
287 | unsigned int num_kctl_alloc, num_kctl_used; | 287 | struct snd_array kctls; |
288 | struct snd_kcontrol_new *kctl_alloc; | ||
289 | struct hda_input_mux private_imux; | 288 | struct hda_input_mux private_imux; |
290 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; | 289 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; |
291 | 290 | ||
@@ -1590,6 +1589,9 @@ static const char *alc_slave_sws[] = { | |||
1590 | /* | 1589 | /* |
1591 | * build control elements | 1590 | * build control elements |
1592 | */ | 1591 | */ |
1592 | |||
1593 | static void alc_free_kctls(struct hda_codec *codec); | ||
1594 | |||
1593 | static int alc_build_controls(struct hda_codec *codec) | 1595 | static int alc_build_controls(struct hda_codec *codec) |
1594 | { | 1596 | { |
1595 | struct alc_spec *spec = codec->spec; | 1597 | struct alc_spec *spec = codec->spec; |
@@ -1636,6 +1638,7 @@ static int alc_build_controls(struct hda_codec *codec) | |||
1636 | return err; | 1638 | return err; |
1637 | } | 1639 | } |
1638 | 1640 | ||
1641 | alc_free_kctls(codec); /* no longer needed */ | ||
1639 | return 0; | 1642 | return 0; |
1640 | } | 1643 | } |
1641 | 1644 | ||
@@ -2726,19 +2729,27 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
2726 | return 0; | 2729 | return 0; |
2727 | } | 2730 | } |
2728 | 2731 | ||
2732 | static void alc_free_kctls(struct hda_codec *codec) | ||
2733 | { | ||
2734 | struct alc_spec *spec = codec->spec; | ||
2735 | |||
2736 | if (spec->kctls.list) { | ||
2737 | struct snd_kcontrol_new *kctl = spec->kctls.list; | ||
2738 | int i; | ||
2739 | for (i = 0; i < spec->kctls.used; i++) | ||
2740 | kfree(kctl[i].name); | ||
2741 | } | ||
2742 | snd_array_free(&spec->kctls); | ||
2743 | } | ||
2744 | |||
2729 | static void alc_free(struct hda_codec *codec) | 2745 | static void alc_free(struct hda_codec *codec) |
2730 | { | 2746 | { |
2731 | struct alc_spec *spec = codec->spec; | 2747 | struct alc_spec *spec = codec->spec; |
2732 | unsigned int i; | ||
2733 | 2748 | ||
2734 | if (!spec) | 2749 | if (!spec) |
2735 | return; | 2750 | return; |
2736 | 2751 | ||
2737 | if (spec->kctl_alloc) { | 2752 | alc_free_kctls(codec); |
2738 | for (i = 0; i < spec->num_kctl_used; i++) | ||
2739 | kfree(spec->kctl_alloc[i].name); | ||
2740 | kfree(spec->kctl_alloc); | ||
2741 | } | ||
2742 | kfree(spec); | 2753 | kfree(spec); |
2743 | codec->spec = NULL; /* to be sure */ | 2754 | codec->spec = NULL; /* to be sure */ |
2744 | } | 2755 | } |
@@ -3423,9 +3434,6 @@ static struct alc_config_preset alc880_presets[] = { | |||
3423 | * Automatic parse of I/O pins from the BIOS configuration | 3434 | * Automatic parse of I/O pins from the BIOS configuration |
3424 | */ | 3435 | */ |
3425 | 3436 | ||
3426 | #define NUM_CONTROL_ALLOC 32 | ||
3427 | #define NUM_VERB_ALLOC 32 | ||
3428 | |||
3429 | enum { | 3437 | enum { |
3430 | ALC_CTL_WIDGET_VOL, | 3438 | ALC_CTL_WIDGET_VOL, |
3431 | ALC_CTL_WIDGET_MUTE, | 3439 | ALC_CTL_WIDGET_MUTE, |
@@ -3443,29 +3451,15 @@ static int add_control(struct alc_spec *spec, int type, const char *name, | |||
3443 | { | 3451 | { |
3444 | struct snd_kcontrol_new *knew; | 3452 | struct snd_kcontrol_new *knew; |
3445 | 3453 | ||
3446 | if (spec->num_kctl_used >= spec->num_kctl_alloc) { | 3454 | snd_array_init(&spec->kctls, sizeof(*knew), 32); |
3447 | int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; | 3455 | knew = snd_array_new(&spec->kctls); |
3448 | 3456 | if (!knew) | |
3449 | /* array + terminator */ | 3457 | return -ENOMEM; |
3450 | knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); | ||
3451 | if (!knew) | ||
3452 | return -ENOMEM; | ||
3453 | if (spec->kctl_alloc) { | ||
3454 | memcpy(knew, spec->kctl_alloc, | ||
3455 | sizeof(*knew) * spec->num_kctl_alloc); | ||
3456 | kfree(spec->kctl_alloc); | ||
3457 | } | ||
3458 | spec->kctl_alloc = knew; | ||
3459 | spec->num_kctl_alloc = num; | ||
3460 | } | ||
3461 | |||
3462 | knew = &spec->kctl_alloc[spec->num_kctl_used]; | ||
3463 | *knew = alc880_control_templates[type]; | 3458 | *knew = alc880_control_templates[type]; |
3464 | knew->name = kstrdup(name, GFP_KERNEL); | 3459 | knew->name = kstrdup(name, GFP_KERNEL); |
3465 | if (!knew->name) | 3460 | if (!knew->name) |
3466 | return -ENOMEM; | 3461 | return -ENOMEM; |
3467 | knew->private_value = val; | 3462 | knew->private_value = val; |
3468 | spec->num_kctl_used++; | ||
3469 | return 0; | 3463 | return 0; |
3470 | } | 3464 | } |
3471 | 3465 | ||
@@ -3789,8 +3783,8 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
3789 | if (spec->autocfg.dig_in_pin) | 3783 | if (spec->autocfg.dig_in_pin) |
3790 | spec->dig_in_nid = ALC880_DIGIN_NID; | 3784 | spec->dig_in_nid = ALC880_DIGIN_NID; |
3791 | 3785 | ||
3792 | if (spec->kctl_alloc) | 3786 | if (spec->kctls.list) |
3793 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 3787 | spec->mixers[spec->num_mixers++] = spec->kctls.list; |
3794 | 3788 | ||
3795 | spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs; | 3789 | spec->init_verbs[spec->num_init_verbs++] = alc880_volume_init_verbs; |
3796 | 3790 | ||
@@ -5177,7 +5171,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
5177 | err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); | 5171 | err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); |
5178 | if (err < 0) | 5172 | if (err < 0) |
5179 | return err; | 5173 | return err; |
5180 | if (!spec->kctl_alloc) | 5174 | if (!spec->kctls.list) |
5181 | return 0; /* can't find valid BIOS pin config */ | 5175 | return 0; /* can't find valid BIOS pin config */ |
5182 | err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); | 5176 | err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); |
5183 | if (err < 0) | 5177 | if (err < 0) |
@@ -5187,8 +5181,8 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
5187 | 5181 | ||
5188 | if (spec->autocfg.dig_out_pin) | 5182 | if (spec->autocfg.dig_out_pin) |
5189 | spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; | 5183 | spec->multiout.dig_out_nid = ALC260_DIGOUT_NID; |
5190 | if (spec->kctl_alloc) | 5184 | if (spec->kctls.list) |
5191 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 5185 | spec->mixers[spec->num_mixers++] = spec->kctls.list; |
5192 | 5186 | ||
5193 | spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs; | 5187 | spec->init_verbs[spec->num_init_verbs++] = alc260_volume_init_verbs; |
5194 | 5188 | ||
@@ -10256,8 +10250,8 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
10256 | if (spec->autocfg.dig_in_pin) | 10250 | if (spec->autocfg.dig_in_pin) |
10257 | spec->dig_in_nid = ALC262_DIGIN_NID; | 10251 | spec->dig_in_nid = ALC262_DIGIN_NID; |
10258 | 10252 | ||
10259 | if (spec->kctl_alloc) | 10253 | if (spec->kctls.list) |
10260 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 10254 | spec->mixers[spec->num_mixers++] = spec->kctls.list; |
10261 | 10255 | ||
10262 | spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs; | 10256 | spec->init_verbs[spec->num_init_verbs++] = alc262_volume_init_verbs; |
10263 | spec->num_mux_defs = 1; | 10257 | spec->num_mux_defs = 1; |
@@ -11387,8 +11381,8 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
11387 | if (spec->autocfg.dig_out_pin) | 11381 | if (spec->autocfg.dig_out_pin) |
11388 | spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; | 11382 | spec->multiout.dig_out_nid = ALC268_DIGOUT_NID; |
11389 | 11383 | ||
11390 | if (spec->kctl_alloc) | 11384 | if (spec->kctls.list) |
11391 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 11385 | spec->mixers[spec->num_mixers++] = spec->kctls.list; |
11392 | 11386 | ||
11393 | if (spec->autocfg.speaker_pins[0] != 0x1d) | 11387 | if (spec->autocfg.speaker_pins[0] != 0x1d) |
11394 | spec->mixers[spec->num_mixers++] = alc268_beep_mixer; | 11388 | spec->mixers[spec->num_mixers++] = alc268_beep_mixer; |
@@ -12159,8 +12153,8 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
12159 | if (spec->autocfg.dig_out_pin) | 12153 | if (spec->autocfg.dig_out_pin) |
12160 | spec->multiout.dig_out_nid = ALC269_DIGOUT_NID; | 12154 | spec->multiout.dig_out_nid = ALC269_DIGOUT_NID; |
12161 | 12155 | ||
12162 | if (spec->kctl_alloc) | 12156 | if (spec->kctls.list) |
12163 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 12157 | spec->mixers[spec->num_mixers++] = spec->kctls.list; |
12164 | 12158 | ||
12165 | /* create a beep mixer control if the pin 0x1d isn't assigned */ | 12159 | /* create a beep mixer control if the pin 0x1d isn't assigned */ |
12166 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++) | 12160 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++) |
@@ -13257,8 +13251,8 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
13257 | if (spec->autocfg.dig_out_pin) | 13251 | if (spec->autocfg.dig_out_pin) |
13258 | spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; | 13252 | spec->multiout.dig_out_nid = ALC861_DIGOUT_NID; |
13259 | 13253 | ||
13260 | if (spec->kctl_alloc) | 13254 | if (spec->kctls.list) |
13261 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 13255 | spec->mixers[spec->num_mixers++] = spec->kctls.list; |
13262 | 13256 | ||
13263 | spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs; | 13257 | spec->init_verbs[spec->num_init_verbs++] = alc861_auto_init_verbs; |
13264 | 13258 | ||
@@ -14368,8 +14362,8 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
14368 | if (spec->autocfg.dig_out_pin) | 14362 | if (spec->autocfg.dig_out_pin) |
14369 | spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; | 14363 | spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID; |
14370 | 14364 | ||
14371 | if (spec->kctl_alloc) | 14365 | if (spec->kctls.list) |
14372 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 14366 | spec->mixers[spec->num_mixers++] = spec->kctls.list; |
14373 | 14367 | ||
14374 | spec->init_verbs[spec->num_init_verbs++] | 14368 | spec->init_verbs[spec->num_init_verbs++] |
14375 | = alc861vd_volume_init_verbs; | 14369 | = alc861vd_volume_init_verbs; |
@@ -16194,8 +16188,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
16194 | if (spec->autocfg.dig_out_pin) | 16188 | if (spec->autocfg.dig_out_pin) |
16195 | spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; | 16189 | spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; |
16196 | 16190 | ||
16197 | if (spec->kctl_alloc) | 16191 | if (spec->kctls.list) |
16198 | spec->mixers[spec->num_mixers++] = spec->kctl_alloc; | 16192 | spec->mixers[spec->num_mixers++] = spec->kctls.list; |
16199 | 16193 | ||
16200 | spec->num_mux_defs = 1; | 16194 | spec->num_mux_defs = 1; |
16201 | spec->input_mux = &spec->private_imux; | 16195 | spec->input_mux = &spec->private_imux; |