aboutsummaryrefslogtreecommitdiffstats
path: root/samples/uhid
AgeCommit message (Expand)Author
2017-11-18kbuild: remove all dummy assignments to obj-Masahiro Yamada
2017-11-02License cleanup: add SPDX GPL-2.0 license identifier to files with no licenseGreg Kroah-Hartman
2013-09-04HID: uhid: improve uhid example clientDavid Herrmann
2012-06-18HID: uhid: add example programDavid Herrmann
pan>card); } /* * allocate a string at most len chars, and remove the trailing EOL */ static char *kstrndup_noeol(const char *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; } #define CODEC_INFO_SHOW(type) \ static ssize_t type##_show(struct device *dev, \ struct device_attribute *attr, \ char *buf) \ { \ struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ struct hda_codec *codec = hwdep->private_data; \ return sprintf(buf, "0x%x\n", codec->type); \ } #define CODEC_INFO_STR_SHOW(type) \ static ssize_t type##_show(struct device *dev, \ struct device_attribute *attr, \ char *buf) \ { \ struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ struct hda_codec *codec = hwdep->private_data; \ return sprintf(buf, "%s\n", \ codec->type ? codec->type : ""); \ } CODEC_INFO_SHOW(vendor_id); CODEC_INFO_SHOW(subsystem_id); CODEC_INFO_SHOW(revision_id); CODEC_INFO_SHOW(afg); CODEC_INFO_SHOW(mfg); CODEC_INFO_STR_SHOW(name); CODEC_INFO_STR_SHOW(modelname); #define CODEC_INFO_STORE(type) \ static ssize_t type##_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 *after; \ codec->type = simple_strtoul(buf, &after, 0); \ return count; \ } #define CODEC_INFO_STR_STORE(type) \ static ssize_t type##_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 *s = kstrndup_noeol(buf, 64); \ if (!s) \ return -ENOMEM; \ kfree(codec->type); \ codec->type = s; \ return count; \ } CODEC_INFO_STORE(vendor_id); CODEC_INFO_STORE(subsystem_id); CODEC_INFO_STORE(revision_id); CODEC_INFO_STR_STORE(name); CODEC_INFO_STR_STORE(modelname); #define CODEC_ACTION_STORE(type) \ static ssize_t type##_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; \ int err = 0; \ if (*buf) \ err = type##_codec(codec); \ return err < 0 ? err : count; \ } CODEC_ACTION_STORE(reconfig); CODEC_ACTION_STORE(clear); static ssize_t init_verbs_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; struct hda_verb *v; int nid, verb, param; if (sscanf(buf, "%i %i %i", &nid, &verb, &param) != 3) return -EINVAL; if (!nid || !verb) return -EINVAL; v = snd_array_new(&codec->init_verbs); if (!v) return -ENOMEM; v->nid = nid; v->verb = verb; v->param = param; return count; } 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; if (!*buf || isspace(*buf) || *buf == '#' || *buf == '\n') return count; p = kstrndup_noeol(buf, 1024); if (!p) return -ENOMEM; hint = snd_array_new(&codec->hints); if (!hint) { kfree(p); return -ENOMEM; } *hint = p; return count; } #define CODEC_ATTR_RW(type) \ __ATTR(type, 0644, type##_show, type##_store) #define CODEC_ATTR_RO(type) \ __ATTR_RO(type) #define CODEC_ATTR_WO(type) \ __ATTR(type, 0200, NULL, type##_store) static struct device_attribute codec_attrs[] = { CODEC_ATTR_RW(vendor_id), CODEC_ATTR_RW(subsystem_id), CODEC_ATTR_RW(revision_id), CODEC_ATTR_RO(afg), CODEC_ATTR_RO(mfg), CODEC_ATTR_RW(name), CODEC_ATTR_RW(modelname), CODEC_ATTR_WO(init_verbs), CODEC_ATTR_WO(hints), CODEC_ATTR_WO(reconfig), CODEC_ATTR_WO(clear), }; /* * create sysfs files on hwdep directory */ int snd_hda_hwdep_add_sysfs(struct hda_codec *codec) { struct snd_hwdep *hwdep = codec->hwdep; int i; for (i = 0; i < ARRAY_SIZE(codec_attrs); i++) snd_add_device_sysfs_file(SNDRV_DEVICE_TYPE_HWDEP, hwdep->card, hwdep->device, &codec_attrs[i]); return 0; } #endif /* CONFIG_SND_HDA_RECONFIG */