Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 603c4019 authored by Takashi Iwai's avatar Takashi Iwai
Browse files

ALSA: hda - Use generic array helpers



Use generic array helpers to simplify array handling in snd-hda-intel.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent b2e18597
Loading
Loading
Loading
Loading
+9 −29
Original line number Diff line number Diff line
@@ -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;
+1 −4
Original line number Diff line number Diff line
@@ -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 */
+27 −29
Original line number Diff line number Diff line
@@ -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 */
	snd_array_init(&spec->kctls, sizeof(*knew), 32);
	knew = snd_array_new(&spec->kctls);
	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];
	*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;

+0 −11
Original line number Diff line number Diff line
@@ -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);
}

+40 −46
Original line number Diff line number Diff line
@@ -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);
	snd_array_init(&spec->kctls, sizeof(*knew), 32);
	knew = snd_array_new(&spec->kctls);
	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];
	*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;
Loading