forked from Minki/linux
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>
This commit is contained in:
parent
b2e1859745
commit
603c401992
@ -756,12 +756,12 @@ static void __devinit init_hda_cache(struct hda_cache_rec *cache,
|
||||
{
|
||||
memset(cache, 0, sizeof(*cache));
|
||||
memset(cache->hash, 0xff, sizeof(cache->hash));
|
||||
cache->record_size = record_size;
|
||||
snd_array_init(&cache->buf, record_size, 64);
|
||||
}
|
||||
|
||||
static void free_hda_cache(struct hda_cache_rec *cache)
|
||||
{
|
||||
kfree(cache->buffer);
|
||||
snd_array_free(&cache->buf);
|
||||
}
|
||||
|
||||
/* query the hash. allocate an entry if not found. */
|
||||
@ -770,38 +770,18 @@ static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache,
|
||||
{
|
||||
u16 idx = key % (u16)ARRAY_SIZE(cache->hash);
|
||||
u16 cur = cache->hash[idx];
|
||||
struct hda_cache_head *info_head = cache->buf.list;
|
||||
struct hda_cache_head *info;
|
||||
|
||||
while (cur != 0xffff) {
|
||||
info = (struct hda_cache_head *)(cache->buffer +
|
||||
cur * cache->record_size);
|
||||
info = &info_head[cur];
|
||||
if (info->key == key)
|
||||
return info;
|
||||
cur = info->next;
|
||||
}
|
||||
|
||||
/* add a new hash entry */
|
||||
if (cache->num_entries >= cache->size) {
|
||||
/* reallocate the array */
|
||||
unsigned int new_size = cache->size + 64;
|
||||
void *new_buffer;
|
||||
new_buffer = kcalloc(new_size, cache->record_size, GFP_KERNEL);
|
||||
if (!new_buffer) {
|
||||
snd_printk(KERN_ERR "hda_codec: "
|
||||
"can't malloc amp_info\n");
|
||||
return NULL;
|
||||
}
|
||||
if (cache->buffer) {
|
||||
memcpy(new_buffer, cache->buffer,
|
||||
cache->size * cache->record_size);
|
||||
kfree(cache->buffer);
|
||||
}
|
||||
cache->size = new_size;
|
||||
cache->buffer = new_buffer;
|
||||
}
|
||||
cur = cache->num_entries++;
|
||||
info = (struct hda_cache_head *)(cache->buffer +
|
||||
cur * cache->record_size);
|
||||
info = snd_array_new(&cache->buf);
|
||||
info->key = key;
|
||||
info->val = 0;
|
||||
info->next = cache->hash[idx];
|
||||
@ -942,10 +922,10 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
|
||||
/* resume the all amp commands from the cache */
|
||||
void snd_hda_codec_resume_amp(struct hda_codec *codec)
|
||||
{
|
||||
struct hda_amp_info *buffer = codec->amp_cache.buffer;
|
||||
struct hda_amp_info *buffer = codec->amp_cache.buf.list;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < codec->amp_cache.size; i++, buffer++) {
|
||||
for (i = 0; i < codec->amp_cache.buf.used; i++, buffer++) {
|
||||
u32 key = buffer->head.key;
|
||||
hda_nid_t nid;
|
||||
unsigned int idx, dir, ch;
|
||||
@ -1779,10 +1759,10 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
|
||||
/* resume the all commands from the cache */
|
||||
void snd_hda_codec_resume_cache(struct hda_codec *codec)
|
||||
{
|
||||
struct hda_cache_head *buffer = codec->cmd_cache.buffer;
|
||||
struct hda_cache_head *buffer = codec->cmd_cache.buf.list;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < codec->cmd_cache.size; i++, buffer++) {
|
||||
for (i = 0; i < codec->cmd_cache.buf.used; i++, buffer++) {
|
||||
u32 key = buffer->key;
|
||||
if (!key)
|
||||
continue;
|
||||
|
@ -657,10 +657,7 @@ struct hda_amp_info {
|
||||
|
||||
struct hda_cache_rec {
|
||||
u16 hash[64]; /* hash table for index */
|
||||
unsigned int num_entries; /* number of assigned entries */
|
||||
unsigned int size; /* allocated size */
|
||||
unsigned int record_size; /* record size (including header) */
|
||||
void *buffer; /* hash table entries */
|
||||
struct snd_array buf; /* record entries */
|
||||
};
|
||||
|
||||
/* PCM callbacks */
|
||||
|
@ -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_kctls(struct hda_codec *codec)
|
||||
{
|
||||
struct ad198x_spec *spec = codec->spec;
|
||||
|
||||
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;
|
||||
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)
|
||||
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;
|
||||
|
||||
|
@ -86,8 +86,6 @@ struct conexant_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 hda_input_mux private_imux;
|
||||
hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
|
||||
|
||||
@ -344,15 +342,6 @@ static int conexant_init(struct hda_codec *codec)
|
||||
|
||||
static void conexant_free(struct hda_codec *codec)
|
||||
{
|
||||
struct conexant_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);
|
||||
}
|
||||
|
||||
kfree(codec->spec);
|
||||
}
|
||||
|
||||
|
@ -284,8 +284,7 @@ struct alc_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];
|
||||
|
||||
@ -1590,6 +1589,9 @@ static const char *alc_slave_sws[] = {
|
||||
/*
|
||||
* build control elements
|
||||
*/
|
||||
|
||||
static void alc_free_kctls(struct hda_codec *codec);
|
||||
|
||||
static int alc_build_controls(struct hda_codec *codec)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
@ -1636,6 +1638,7 @@ static int alc_build_controls(struct hda_codec *codec)
|
||||
return err;
|
||||
}
|
||||
|
||||
alc_free_kctls(codec); /* no longer needed */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2726,19 +2729,27 @@ static int alc_build_pcms(struct hda_codec *codec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void alc_free_kctls(struct hda_codec *codec)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
|
||||
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 alc_free(struct hda_codec *codec)
|
||||
{
|
||||
struct alc_spec *spec = codec->spec;
|
||||
unsigned int i;
|
||||
|
||||
if (!spec)
|
||||
return;
|
||||
|
||||
if (spec->kctl_alloc) {
|
||||
for (i = 0; i < spec->num_kctl_used; i++)
|
||||
kfree(spec->kctl_alloc[i].name);
|
||||
kfree(spec->kctl_alloc);
|
||||
}
|
||||
alc_free_kctls(codec);
|
||||
kfree(spec);
|
||||
codec->spec = NULL; /* to be sure */
|
||||
}
|
||||
@ -3423,9 +3434,6 @@ static struct alc_config_preset alc880_presets[] = {
|
||||
* Automatic parse of I/O pins from the BIOS configuration
|
||||
*/
|
||||
|
||||
#define NUM_CONTROL_ALLOC 32
|
||||
#define NUM_VERB_ALLOC 32
|
||||
|
||||
enum {
|
||||
ALC_CTL_WIDGET_VOL,
|
||||
ALC_CTL_WIDGET_MUTE,
|
||||
@ -3443,29 +3451,15 @@ static int add_control(struct alc_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;
|
||||
|
||||
/* array + terminator */
|
||||
knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
|
||||
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 = alc880_control_templates[type];
|
||||
knew->name = kstrdup(name, GFP_KERNEL);
|
||||
if (!knew->name)
|
||||
return -ENOMEM;
|
||||
knew->private_value = val;
|
||||
spec->num_kctl_used++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3789,8 +3783,8 @@ static int alc880_parse_auto_config(struct hda_codec *codec)
|
||||
if (spec->autocfg.dig_in_pin)
|
||||
spec->dig_in_nid = ALC880_DIGIN_NID;
|
||||
|
||||
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++] = alc880_volume_init_verbs;
|
||||
|
||||
@ -5177,7 +5171,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
|
||||
err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg);
|
||||
if (err < 0)
|
||||
return err;
|
||||
if (!spec->kctl_alloc)
|
||||
if (!spec->kctls.list)
|
||||
return 0; /* can't find valid BIOS pin config */
|
||||
err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg);
|
||||
if (err < 0)
|
||||
@ -5187,8 +5181,8 @@ static int alc260_parse_auto_config(struct hda_codec *codec)
|
||||
|
||||
if (spec->autocfg.dig_out_pin)
|
||||
spec->multiout.dig_out_nid = ALC260_DIGOUT_NID;
|
||||
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++] = alc260_volume_init_verbs;
|
||||
|
||||
@ -10256,8 +10250,8 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
|
||||
if (spec->autocfg.dig_in_pin)
|
||||
spec->dig_in_nid = ALC262_DIGIN_NID;
|
||||
|
||||
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++] = alc262_volume_init_verbs;
|
||||
spec->num_mux_defs = 1;
|
||||
@ -11387,8 +11381,8 @@ static int alc268_parse_auto_config(struct hda_codec *codec)
|
||||
if (spec->autocfg.dig_out_pin)
|
||||
spec->multiout.dig_out_nid = ALC268_DIGOUT_NID;
|
||||
|
||||
if (spec->kctl_alloc)
|
||||
spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
|
||||
if (spec->kctls.list)
|
||||
spec->mixers[spec->num_mixers++] = spec->kctls.list;
|
||||
|
||||
if (spec->autocfg.speaker_pins[0] != 0x1d)
|
||||
spec->mixers[spec->num_mixers++] = alc268_beep_mixer;
|
||||
@ -12159,8 +12153,8 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
|
||||
if (spec->autocfg.dig_out_pin)
|
||||
spec->multiout.dig_out_nid = ALC269_DIGOUT_NID;
|
||||
|
||||
if (spec->kctl_alloc)
|
||||
spec->mixers[spec->num_mixers++] = spec->kctl_alloc;
|
||||
if (spec->kctls.list)
|
||||
spec->mixers[spec->num_mixers++] = spec->kctls.list;
|
||||
|
||||
/* create a beep mixer control if the pin 0x1d isn't assigned */
|
||||
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)
|
||||
if (spec->autocfg.dig_out_pin)
|
||||
spec->multiout.dig_out_nid = ALC861_DIGOUT_NID;
|
||||
|
||||
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++] = alc861_auto_init_verbs;
|
||||
|
||||
@ -14368,8 +14362,8 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec)
|
||||
if (spec->autocfg.dig_out_pin)
|
||||
spec->multiout.dig_out_nid = ALC861VD_DIGOUT_NID;
|
||||
|
||||
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++]
|
||||
= alc861vd_volume_init_verbs;
|
||||
@ -16194,8 +16188,8 @@ static int alc662_parse_auto_config(struct hda_codec *codec)
|
||||
if (spec->autocfg.dig_out_pin)
|
||||
spec->multiout.dig_out_nid = ALC880_DIGOUT_NID;
|
||||
|
||||
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->num_mux_defs = 1;
|
||||
spec->input_mux = &spec->private_imux;
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include "hda_patch.h"
|
||||
#include "hda_beep.h"
|
||||
|
||||
#define NUM_CONTROL_ALLOC 32
|
||||
#define STAC_PWR_EVENT 0x20
|
||||
#define STAC_HP_EVENT 0x30
|
||||
#define STAC_VREF_EVENT 0x40
|
||||
@ -218,8 +217,7 @@ struct sigmatel_spec {
|
||||
|
||||
/* dynamic controls 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_dimux;
|
||||
struct hda_input_mux private_imux;
|
||||
struct hda_input_mux private_smux;
|
||||
@ -1233,6 +1231,8 @@ static const char *slave_sws[] = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static void stac92xx_free_kctls(struct hda_codec *codec);
|
||||
|
||||
static int stac92xx_build_controls(struct hda_codec *codec)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
@ -1305,6 +1305,7 @@ static int stac92xx_build_controls(struct hda_codec *codec)
|
||||
return err;
|
||||
}
|
||||
|
||||
stac92xx_free_kctls(codec); /* no longer needed */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2592,28 +2593,16 @@ static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type,
|
||||
{
|
||||
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 = stac92xx_control_templates[type];
|
||||
knew->index = idx;
|
||||
knew->name = kstrdup(name, GFP_KERNEL);
|
||||
if (! knew->name)
|
||||
return -ENOMEM;
|
||||
knew->private_value = val;
|
||||
spec->num_kctl_used++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3434,8 +3423,8 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out
|
||||
if (dig_in && spec->autocfg.dig_in_pin)
|
||||
spec->dig_in_nid = dig_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->input_mux = &spec->private_imux;
|
||||
spec->dinput_mux = &spec->private_dimux;
|
||||
@ -3536,8 +3525,8 @@ static int stac9200_parse_auto_config(struct hda_codec *codec)
|
||||
if (spec->autocfg.dig_in_pin)
|
||||
spec->dig_in_nid = 0x04;
|
||||
|
||||
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->input_mux = &spec->private_imux;
|
||||
spec->dinput_mux = &spec->private_dimux;
|
||||
@ -3698,20 +3687,26 @@ static int stac92xx_init(struct hda_codec *codec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void stac92xx_free_kctls(struct hda_codec *codec)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
|
||||
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 stac92xx_free(struct hda_codec *codec)
|
||||
{
|
||||
struct sigmatel_spec *spec = codec->spec;
|
||||
int i;
|
||||
|
||||
if (! spec)
|
||||
return;
|
||||
|
||||
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->bios_pin_configs)
|
||||
kfree(spec->bios_pin_configs);
|
||||
|
||||
|
@ -53,9 +53,6 @@
|
||||
#define AMP_VAL_IDX_SHIFT 19
|
||||
#define AMP_VAL_IDX_MASK (0x0f<<19)
|
||||
|
||||
#define NUM_CONTROL_ALLOC 32
|
||||
#define NUM_VERB_ALLOC 32
|
||||
|
||||
/* Pin Widget NID */
|
||||
#define VT1708_HP_NID 0x13
|
||||
#define VT1708_DIGOUT_NID 0x14
|
||||
@ -227,8 +224,7 @@ struct via_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[2];
|
||||
hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS];
|
||||
|
||||
@ -272,33 +268,31 @@ static int via_add_control(struct via_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;
|
||||
|
||||
/* array + terminator */
|
||||
knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL);
|
||||
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 = vt1708_control_templates[type];
|
||||
knew->name = kstrdup(name, GFP_KERNEL);
|
||||
|
||||
if (!knew->name)
|
||||
return -ENOMEM;
|
||||
knew->private_value = val;
|
||||
spec->num_kctl_used++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void via_free_kctls(struct hda_codec *codec)
|
||||
{
|
||||
struct via_spec *spec = codec->spec;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* create input playback/capture controls for the given pin */
|
||||
static int via_new_analog_input(struct via_spec *spec, hda_nid_t pin,
|
||||
const char *ctlname, int idx, int mix_nid)
|
||||
@ -896,6 +890,7 @@ static int via_build_controls(struct hda_codec *codec)
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
via_free_kctls(codec); /* no longer needed */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -941,17 +936,11 @@ static int via_build_pcms(struct hda_codec *codec)
|
||||
static void via_free(struct hda_codec *codec)
|
||||
{
|
||||
struct via_spec *spec = codec->spec;
|
||||
unsigned int i;
|
||||
|
||||
if (!spec)
|
||||
return;
|
||||
|
||||
if (spec->kctl_alloc) {
|
||||
for (i = 0; i < spec->num_kctl_used; i++)
|
||||
kfree(spec->kctl_alloc[i].name);
|
||||
kfree(spec->kctl_alloc);
|
||||
}
|
||||
|
||||
via_free_kctls(codec);
|
||||
kfree(codec->spec);
|
||||
}
|
||||
|
||||
@ -1373,8 +1362,8 @@ static int vt1708_parse_auto_config(struct hda_codec *codec)
|
||||
if (spec->autocfg.dig_in_pin)
|
||||
spec->dig_in_nid = VT1708_DIGIN_NID;
|
||||
|
||||
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_iverbs++] = vt1708_volume_init_verbs;
|
||||
|
||||
@ -1846,8 +1835,8 @@ static int vt1709_parse_auto_config(struct hda_codec *codec)
|
||||
if (spec->autocfg.dig_in_pin)
|
||||
spec->dig_in_nid = VT1709_DIGIN_NID;
|
||||
|
||||
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->input_mux = &spec->private_imux[0];
|
||||
|
||||
@ -2390,8 +2379,8 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec)
|
||||
if (spec->autocfg.dig_in_pin)
|
||||
spec->dig_in_nid = VT1708B_DIGIN_NID;
|
||||
|
||||
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->input_mux = &spec->private_imux[0];
|
||||
|
||||
@ -2855,8 +2844,8 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec)
|
||||
|
||||
spec->extra_dig_out_nid = 0x15;
|
||||
|
||||
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->input_mux = &spec->private_imux[0];
|
||||
|
||||
@ -3174,8 +3163,8 @@ static int vt1702_parse_auto_config(struct hda_codec *codec)
|
||||
|
||||
spec->extra_dig_out_nid = 0x1B;
|
||||
|
||||
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->input_mux = &spec->private_imux[0];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user