Skip to content

Commit

Permalink
ALSA: hda - Use generic array helpers
Browse files Browse the repository at this point in the history
Use generic array helpers to simplify array handling in snd-hda-intel.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
  • Loading branch information
tiwai committed Oct 13, 2008
1 parent b2e1859 commit 603c401
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 190 deletions.
38 changes: 9 additions & 29 deletions sound/pci/hda/hda_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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. */
Expand All @@ -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];
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 1 addition & 4 deletions sound/pci/hda/hda_codec.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
56 changes: 27 additions & 29 deletions sound/pci/hda/patch_analog.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -202,6 +203,7 @@ static int ad198x_build_controls(struct hda_codec *codec)
return err;
}

ad198x_free_kctls(codec); /* no longer needed */
return 0;
}

Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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,
Expand All @@ -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;
}

Expand Down Expand Up @@ -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;

Expand Down
11 changes: 0 additions & 11 deletions sound/pci/hda/patch_conexant.c
Original file line number Diff line number Diff line change
Expand Up @@ -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];

Expand Down Expand Up @@ -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);
}

Expand Down
Loading

0 comments on commit 603c401

Please sign in to comment.