Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 133090
b: refs/heads/master
c: 43b6271
h: refs/heads/master
v: v3
  • Loading branch information
Takashi Iwai committed Mar 2, 2009
1 parent 78b2c95 commit 17b812f
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6e655bf21697d2594243098a14e0699e8d4a4059
refs/heads/master: 43b62713f67d9f0655f3a61f5bd14d6297ddd3ce
112 changes: 99 additions & 13 deletions trunk/sound/pci/hda/hda_hwdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@
#include <sound/hda_hwdep.h>
#include <sound/minors.h>

/* hint string pair */
struct hda_hint {
const char *key;
const char *val; /* contained in the same alloc as key */
};

/*
* write/read an out-of-bound verb
*/
Expand Down Expand Up @@ -99,15 +105,15 @@ static int hda_hwdep_open(struct snd_hwdep *hw, struct file *file)

static void clear_hwdep_elements(struct hda_codec *codec)
{
char **head;
int i;

/* clear init verbs */
snd_array_free(&codec->init_verbs);
/* clear hints */
head = codec->hints.list;
for (i = 0; i < codec->hints.used; i++, head++)
kfree(*head);
for (i = 0; i < codec->hints.used; i++) {
struct hda_hint *hint = snd_array_elem(&codec->hints, i);
kfree(hint->key); /* we don't need to free hint->val */
}
snd_array_free(&codec->hints);
snd_array_free(&codec->user_pins);
}
Expand Down Expand Up @@ -141,7 +147,7 @@ int /*__devinit*/ snd_hda_create_hwdep(struct hda_codec *codec)
#endif

snd_array_init(&codec->init_verbs, sizeof(struct hda_verb), 32);
snd_array_init(&codec->hints, sizeof(char *), 32);
snd_array_init(&codec->hints, sizeof(struct hda_hint), 32);
snd_array_init(&codec->user_pins, sizeof(struct hda_pincfg), 16);

return 0;
Expand Down Expand Up @@ -306,26 +312,81 @@ static ssize_t init_verbs_store(struct device *dev,
return count;
}

static struct hda_hint *get_hint(struct hda_codec *codec, const char *key)
{
int i;

for (i = 0; i < codec->hints.used; i++) {
struct hda_hint *hint = snd_array_elem(&codec->hints, i);
if (!strcmp(hint->key, key))
return hint;
}
return NULL;
}

static void remove_trail_spaces(char *str)
{
char *p;
if (!*str)
return;
p = str + strlen(str) - 1;
for (; isspace(*p); p--) {
*p = 0;
if (p == str)
return;
}
}

#define MAX_HINTS 1024

static ssize_t hints_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct snd_hwdep *hwdep = dev_get_drvdata(dev);
struct hda_codec *codec = hwdep->private_data;
char *p;
char **hint;
char *key, *val;
struct hda_hint *hint;

if (!*buf || isspace(*buf) || *buf == '#' || *buf == '\n')
while (isspace(*buf))
buf++;
if (!*buf || *buf == '#' || *buf == '\n')
return count;
p = kstrndup_noeol(buf, 1024);
if (!p)
if (*buf == '=')
return -EINVAL;
key = kstrndup_noeol(buf, 1024);
if (!key)
return -ENOMEM;
hint = snd_array_new(&codec->hints);
/* extract key and val */
val = strchr(key, '=');
if (!val) {
kfree(key);
return -EINVAL;
}
*val++ = 0;
while (isspace(*val))
val++;
remove_trail_spaces(key);
remove_trail_spaces(val);
hint = get_hint(codec, key);
if (hint) {
/* replace */
kfree(hint->key);
hint->key = key;
hint->val = val;
return count;
}
/* allocate a new hint entry */
if (codec->hints.used >= MAX_HINTS)
hint = NULL;
else
hint = snd_array_new(&codec->hints);
if (!hint) {
kfree(p);
kfree(key);
return -ENOMEM;
}
*hint = p;
hint->key = key;
hint->val = val;
return count;
}

Expand Down Expand Up @@ -428,4 +489,29 @@ int snd_hda_hwdep_add_sysfs(struct hda_codec *codec)
return 0;
}

/*
* Look for hint string
*/
const char *snd_hda_get_hint(struct hda_codec *codec, const char *key)
{
struct hda_hint *hint = get_hint(codec, key);
return hint ? hint->val : NULL;
}
EXPORT_SYMBOL_HDA(snd_hda_get_hint);

int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
{
const char *p = snd_hda_get_hint(codec, key);
if (!p || !*p)
return -ENOENT;
switch (toupper(*p)) {
case 'T': /* true */
case 'Y': /* yes */
case '1':
return 1;
}
return 0;
}
EXPORT_SYMBOL_HDA(snd_hda_get_bool_hint);

#endif /* CONFIG_SND_HDA_RECONFIG */
17 changes: 17 additions & 0 deletions trunk/sound/pci/hda/hda_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,23 @@ static inline int snd_hda_hwdep_add_sysfs(struct hda_codec *codec)
}
#endif

#ifdef CONFIG_SND_HDA_RECONFIG
const char *snd_hda_get_hint(struct hda_codec *codec, const char *key);
int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key);
#else
static inline
const char *snd_hda_get_hint(struct hda_codec *codec, const char *key)
{
return NULL;
}

static inline
int snd_hda_get_bool_hint(struct hda_codec *codec, const char *key)
{
return -ENOENT;
}
#endif

/*
* power-management
*/
Expand Down

0 comments on commit 17b812f

Please sign in to comment.