aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/patch_via.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/patch_via.c')
-rw-r--r--sound/pci/hda/patch_via.c71
1 files changed, 30 insertions, 41 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index 63e4871e5d8f..760e14ae3bff 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -53,9 +53,6 @@
53#define AMP_VAL_IDX_SHIFT 19 53#define AMP_VAL_IDX_SHIFT 19
54#define AMP_VAL_IDX_MASK (0x0f<<19) 54#define AMP_VAL_IDX_MASK (0x0f<<19)
55 55
56#define NUM_CONTROL_ALLOC 32
57#define NUM_VERB_ALLOC 32
58
59/* Pin Widget NID */ 56/* Pin Widget NID */
60#define VT1708_HP_NID 0x13 57#define VT1708_HP_NID 0x13
61#define VT1708_DIGOUT_NID 0x14 58#define VT1708_DIGOUT_NID 0x14
@@ -227,8 +224,7 @@ struct via_spec {
227 224
228 /* dynamic controls, init_verbs and input_mux */ 225 /* dynamic controls, init_verbs and input_mux */
229 struct auto_pin_cfg autocfg; 226 struct auto_pin_cfg autocfg;
230 unsigned int num_kctl_alloc, num_kctl_used; 227 struct snd_array kctls;
231 struct snd_kcontrol_new *kctl_alloc;
232 struct hda_input_mux private_imux[2]; 228 struct hda_input_mux private_imux[2];
233 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; 229 hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
234 230
@@ -272,33 +268,31 @@ static int via_add_control(struct via_spec *spec, int type, const char *name,
272{ 268{
273 struct snd_kcontrol_new *knew; 269 struct snd_kcontrol_new *knew;
274 270
275 if (spec->num_kctl_used >= spec->num_kctl_alloc) { 271 snd_array_init(&spec->kctls, sizeof(*knew), 32);
276 int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; 272 knew = snd_array_new(&spec->kctls);
277 273 if (!knew)
278 /* array + terminator */ 274 return -ENOMEM;
279 knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
280 if (!knew)
281 return -ENOMEM;
282 if (spec->kctl_alloc) {
283 memcpy(knew, spec->kctl_alloc,
284 sizeof(*knew) * spec->num_kctl_alloc);
285 kfree(spec->kctl_alloc);
286 }
287 spec->kctl_alloc = knew;
288 spec->num_kctl_alloc = num;
289 }
290
291 knew = &spec->kctl_alloc[spec->num_kctl_used];
292 *knew = vt1708_control_templates[type]; 275 *knew = vt1708_control_templates[type];
293 knew->name = kstrdup(name, GFP_KERNEL); 276 knew->name = kstrdup(name, GFP_KERNEL);
294
295 if (!knew->name) 277 if (!knew->name)
296 return -ENOMEM; 278 return -ENOMEM;
297 knew->private_value = val; 279 knew->private_value = val;
298 spec->num_kctl_used++;
299 return 0; 280 return 0;
300} 281}
301 282
283static void via_free_kctls(struct hda_codec *codec)
284{
285 struct via_spec *spec = codec->spec;
286
287 if (spec->kctls.list) {
288 struct snd_kcontrol_new *kctl = spec->kctls.list;
289 int i;
290 for (i = 0; i < spec->kctls.used; i++)
291 kfree(kctl[i].name);
292 }
293 snd_array_free(&spec->kctls);
294}
295
302/* create input playback/capture controls for the given pin */ 296/* create input playback/capture controls for the given pin */
303static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin, 297static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin,
304 const char *ctlname, int idx, int mix_nid) 298 const char *ctlname, int idx, int mix_nid)
@@ -896,6 +890,7 @@ static int via_build_controls(struct hda_codec *codec)
896 if (err < 0) 890 if (err < 0)
897 return err; 891 return err;
898 } 892 }
893 via_free_kctls(codec); /* no longer needed */
899 return 0; 894 return 0;
900} 895}
901 896
@@ -941,17 +936,11 @@ static int via_build_pcms(struct hda_codec *codec)
941static void via_free(struct hda_codec *codec) 936static void via_free(struct hda_codec *codec)
942{ 937{
943 struct via_spec *spec = codec->spec; 938 struct via_spec *spec = codec->spec;
944 unsigned int i;
945 939
946 if (!spec) 940 if (!spec)
947 return; 941 return;
948 942
949 if (spec->kctl_alloc) { 943 via_free_kctls(codec);
950 for (i = 0; i < spec->num_kctl_used; i++)
951 kfree(spec->kctl_alloc[i].name);
952 kfree(spec->kctl_alloc);
953 }
954
955 kfree(codec->spec); 944 kfree(codec->spec);
956} 945}
957 946
@@ -1373,8 +1362,8 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
1373 if (spec->autocfg.dig_in_pin) 1362 if (spec->autocfg.dig_in_pin)
1374 spec->dig_in_nid = VT1708_DIGIN_NID; 1363 spec->dig_in_nid = VT1708_DIGIN_NID;
1375 1364
1376 if (spec->kctl_alloc) 1365 if (spec->kctls.list)
1377 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1366 spec->mixers[spec->num_mixers++] = spec->kctls.list;
1378 1367
1379 spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs; 1368 spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs;
1380 1369
@@ -1846,8 +1835,8 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
1846 if (spec->autocfg.dig_in_pin) 1835 if (spec->autocfg.dig_in_pin)
1847 spec->dig_in_nid = VT1709_DIGIN_NID; 1836 spec->dig_in_nid = VT1709_DIGIN_NID;
1848 1837
1849 if (spec->kctl_alloc) 1838 if (spec->kctls.list)
1850 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 1839 spec->mixers[spec->num_mixers++] = spec->kctls.list;
1851 1840
1852 spec->input_mux = &spec->private_imux[0]; 1841 spec->input_mux = &spec->private_imux[0];
1853 1842
@@ -2390,8 +2379,8 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
2390 if (spec->autocfg.dig_in_pin) 2379 if (spec->autocfg.dig_in_pin)
2391 spec->dig_in_nid = VT1708B_DIGIN_NID; 2380 spec->dig_in_nid = VT1708B_DIGIN_NID;
2392 2381
2393 if (spec->kctl_alloc) 2382 if (spec->kctls.list)
2394 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 2383 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2395 2384
2396 spec->input_mux = &spec->private_imux[0]; 2385 spec->input_mux = &spec->private_imux[0];
2397 2386
@@ -2855,8 +2844,8 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
2855 2844
2856 spec->extra_dig_out_nid = 0x15; 2845 spec->extra_dig_out_nid = 0x15;
2857 2846
2858 if (spec->kctl_alloc) 2847 if (spec->kctls.list)
2859 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 2848 spec->mixers[spec->num_mixers++] = spec->kctls.list;
2860 2849
2861 spec->input_mux = &spec->private_imux[0]; 2850 spec->input_mux = &spec->private_imux[0];
2862 2851
@@ -3174,8 +3163,8 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
3174 3163
3175 spec->extra_dig_out_nid = 0x1B; 3164 spec->extra_dig_out_nid = 0x1B;
3176 3165
3177 if (spec->kctl_alloc) 3166 if (spec->kctls.list)
3178 spec->mixers[spec->num_mixers++] = spec->kctl_alloc; 3167 spec->mixers[spec->num_mixers++] = spec->kctls.list;
3179 3168
3180 spec->input_mux = &spec->private_imux[0]; 3169 spec->input_mux = &spec->private_imux[0];
3181 3170