staticint clear_codec(struct hda_codec *codec)
{ int err;
err = snd_hda_codec_reset(codec); if (err < 0) {
codec_err(codec, "The codec is being used, can't free.\n"); return err;
}
snd_hda_sysfs_clear(codec); return 0;
}
staticint reconfig_codec(struct hda_codec *codec)
{ int err;
snd_hda_power_up(codec);
codec_info(codec, "hda-codec: reconfiguring\n");
err = snd_hda_codec_reset(codec); if (err < 0) {
codec_err(codec, "The codec is being used, can't reconfigure.\n"); goto error;
}
err = device_reprobe(hda_codec_dev(codec)); if (err < 0) goto error;
err = snd_card_register(codec->card);
error:
snd_hda_power_down(codec); return err;
}
/* * allocate a string at most len chars, and remove the trailing EOL
*/ staticchar *kstrndup_noeol(constchar *src, size_t len)
{ char *s = kstrndup(src, len, GFP_KERNEL); char *p; if (!s) return NULL;
p = strchr(s, '\n'); if (p)
*p = 0; return s;
}
/* sysfs attributes exposed only when CONFIG_SND_HDA_RECONFIG=y */ static DEVICE_ATTR_RW(init_verbs); static DEVICE_ATTR_RW(hints); static DEVICE_ATTR_RW(user_pin_configs); static DEVICE_ATTR_WO(reconfig); static DEVICE_ATTR_WO(clear);
/** * snd_hda_get_hint - Look for hint string * @codec: the HDA codec * @key: the hint key string * * Look for a hint key/value pair matching with the given key string * and returns the value string. If nothing found, returns NULL.
*/ constchar *snd_hda_get_hint(struct hda_codec *codec, constchar *key)
{ struct hda_hint *hint = get_hint(codec, key); return hint ? hint->val : NULL;
}
EXPORT_SYMBOL_GPL(snd_hda_get_hint);
/** * snd_hda_get_bool_hint - Get a boolean hint value * @codec: the HDA codec * @key: the hint key string * * Look for a hint key/value pair matching with the given key string * and returns a boolean value parsed from the value. If no matching * key is found, return a negative value.
*/ int snd_hda_get_bool_hint(struct hda_codec *codec, constchar *key)
{ constchar *p; int ret;
mutex_lock(&codec->user_mutex);
p = snd_hda_get_hint(codec, key); if (!p || !*p)
ret = -ENOENT; else { switch (toupper(*p)) { case'T': /* true */ case'Y': /* yes */ case'1':
ret = 1; break; default:
ret = 0; break;
}
}
mutex_unlock(&codec->user_mutex); return ret;
}
EXPORT_SYMBOL_GPL(snd_hda_get_bool_hint);
/** * snd_hda_get_int_hint - Get an integer hint value * @codec: the HDA codec * @key: the hint key string * @valp: pointer to store a value * * Look for a hint key/value pair matching with the given key string * and stores the integer value to @valp. If no matching key is found, * return a negative error code. Otherwise it returns zero.
*/ int snd_hda_get_int_hint(struct hda_codec *codec, constchar *key, int *valp)
{ constchar *p; unsignedlong val; int ret;
mutex_lock(&codec->user_mutex);
p = snd_hda_get_hint(codec, key); if (!p)
ret = -ENOENT; elseif (kstrtoul(p, 0, &val))
ret = -EINVAL; else {
*valp = val;
ret = 0;
}
mutex_unlock(&codec->user_mutex); return ret;
}
EXPORT_SYMBOL_GPL(snd_hda_get_int_hint); #endif/* CONFIG_SND_HDA_RECONFIG */
/* parse the contents after the line "[codec]" * accept only the line with three numbers, and assign the current codec
*/ staticvoid parse_codec_mode(char *buf, struct hda_bus *bus, struct hda_codec **codecp)
{ int vendorid, subid, caddr; struct hda_codec *codec;
/* parse the contents after the other command tags, [pincfg], [verb], * [vendor_id], [subsystem_id], [revision_id], [chip_name], [hint] and [model] * just pass to the sysfs helper (only when any codec was specified)
*/ staticvoid parse_pincfg_mode(char *buf, struct hda_bus *bus, struct hda_codec **codecp)
{
parse_user_pin_configs(*codecp, buf);
}
/* check the line starting with '[' -- change the parser mode accordingly */ staticint parse_line_mode(char *buf, struct hda_bus *bus)
{ int i; for (i = 0; i < ARRAY_SIZE(patch_items); i++) { if (!patch_items[i].tag) continue; if (strmatch(buf, patch_items[i].tag)) return i; if (patch_items[i].alias && strmatch(buf, patch_items[i].alias)) return i;
} return LINE_MODE_NONE;
}
/* copy one line from the buffer in fw, and update the fields in fw * return zero if it reaches to the end of the buffer, or non-zero * if successfully copied a line * * the spaces at the beginning and the end of the line are stripped
*/ staticint get_line_from_fw(char *buf, int size, size_t *fw_size_p, constvoid **fw_data_p)
{ int len;
size_t fw_size = *fw_size_p; constchar *p = *fw_data_p;
while (isspace(*p) && fw_size) {
p++;
fw_size--;
} if (!fw_size) return 0;
for (len = 0; len < fw_size; len++) { if (!*p) break; if (*p == '\n') {
p++;
len++; break;
} if (len < size)
*buf++ = *p++;
}
*buf = 0;
*fw_size_p = fw_size - len;
*fw_data_p = p;
remove_trail_spaces(buf); return 1;
}
/** * snd_hda_load_patch - load a "patch" firmware file and parse it * @bus: HD-audio bus * @fw_size: the firmware byte size * @fw_buf: the firmware data
*/ int snd_hda_load_patch(struct hda_bus *bus, size_t fw_size, constvoid *fw_buf)
{ char buf[128]; struct hda_codec *codec; int line_mode;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.