// SPDX-License-Identifier: GPL-2.0
/*
 * sysfs support for HD-audio core device
 */

#include <linux/slab.h>
#include <linux/sysfs.h>
#include <linux/device.h>
#include <sound/core.h>
#include <sound/hdaudio.h>
#include "local.h"

struct hdac_widget_tree {
	struct kobject *root;
	struct kobject *afg;
	struct kobject **nodes;
};

#define CODEC_ATTR(type)					\
static ssize_t type##_show(struct device *dev,			\
			   struct device_attribute *attr,	\
			   char *buf)				\
{								\
	struct hdac_device *codec = dev_to_hdac_dev(dev);	\
	return sysfs_emit(buf, "0x%x\n", codec->type);		\
} \
static DEVICE_ATTR_RO(type)

#define CODEC_ATTR_STR(type)					\
static ssize_t type##_show(struct device *dev,			\
			     struct device_attribute *attr,	\
					char *buf)		\
{								\
	struct hdac_device *codec = dev_to_hdac_dev(dev);	\
	return sysfs_emit(buf, "%s\n",				\
			  codec->type ? codec->type : "");	\
} \
static DEVICE_ATTR_RO(type)

CODEC_ATTR(type);
CODEC_ATTR(vendor_id);
CODEC_ATTR(subsystem_id);
CODEC_ATTR(revision_id);
CODEC_ATTR(afg);
CODEC_ATTR(mfg);
CODEC_ATTR_STR(vendor_name);
CODEC_ATTR_STR(chip_name);

static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
	return snd_hdac_codec_modalias(dev_to_hdac_dev(dev), buf, 256);
}
static DEVICE_ATTR_RO(modalias);

static struct attribute *hdac_dev_attrs[] = {
	&dev_attr_type.attr,
	&dev_attr_vendor_id.attr,
	&dev_attr_subsystem_id.attr,
	&dev_attr_revision_id.attr,
	&dev_attr_afg.attr,
	&dev_attr_mfg.attr,
	&dev_attr_vendor_name.attr,
	&dev_attr_chip_name.attr,
	&dev_attr_modalias.attr,
	NULL
};

static const struct attribute_group hdac_dev_attr_group = {
	.attrs	= hdac_dev_attrs,
};

const struct attribute_group *hdac_dev_attr_groups[] = {
	&hdac_dev_attr_group,
	NULL
};

/*
 * Widget tree sysfs
 *
 * This is a tree showing the attributes of each widget.  It appears like
 * /sys/bus/hdaudioC0D0/widgets/04/caps
 */

struct widget_attribute;

struct widget_attribute {
	struct attribute	attr;
	ssize_t (*show)(struct hdac_device *codec, hda_nid_t nid,
			struct widget_attribute *attr, char *buf);
	ssize_t (*store)(struct hdac_device *codec, hda_nid_t nid,
			 struct widget_attribute *attr,
			 const char *buf, size_t count);
};

static int get_codec_nid(struct kobject *kobj, struct hdac_device **codecp)
{
	struct device *dev = kobj_to_dev(kobj->parent->parent);
	int nid;
	ssize_t ret;

	ret = kstrtoint(kobj->name, 16, &nid);
	if (ret < 0)
		return ret;
	*codecp = dev_to_hdac_dev(dev);
	return nid;
}

static ssize_t widget_attr_show(struct kobject *kobj, struct attribute *attr,
				char *buf)
{
	struct widget_attribute *wid_attr =
		container_of(attr, struct widget_attribute, attr);
	struct hdac_device *codec;
	int nid;

	if (!wid_attr->show)
		return -EIO;
	nid = get_codec_nid(kobj, &codec);
	if (nid < 0)
		return nid;
	return wid_attr->show(codec, nid, wid_attr, buf);
}

static ssize_t widget_attr_store(struct kobject *kobj, struct attribute *attr,
				 const char *buf, size_t count)
{
	struct widget_attribute *wid_attr =
		container_of(attr, struct widget_attribute, attr);
	struct hdac_device *codec;
	int nid;

	if (!wid_attr->store)
		return -EIO;
	nid = get_codec_nid(kobj, &codec);
	if (nid < 0)
		return nid;
	return wid_attr->store(codec, nid, wid_attr, buf, count);
}

static const struct sysfs_ops widget_sysfs_ops = {
	.show	= widget_attr_show,
	.store	= widget_attr_store,
};

static void widget_release(struct kobject *kobj)
{
	kfree(kobj);
}

static struct kobj_type widget_ktype = {
	.release	= widget_release,
	.sysfs_ops	= &widget_sysfs_ops,
};

#define WIDGET_ATTR_RO(_name) \
	struct widget_attribute wid_attr_##_name = __ATTR_RO(_name)
#define WIDGET_ATTR_RW(_name) \
	struct widget_attribute wid_attr_##_name = __ATTR_RW(_name)

static ssize_t caps_show(struct hdac_device *codec, hda_nid_t nid,
			struct widget_attribute *attr, char *buf)
{
	return sysfs_emit(buf, "0x%08x\n", get_wcaps(codec, nid));
}

static ssize_t pin_caps_show(struct hdac_device *codec, hda_nid_t nid,
			     struct widget_attribute *attr, char *buf)
{
	if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
		return 0;
	return sysfs_emit(buf, "0x%08x\n",
			  snd_hdac_read_parm(codec, nid, AC_PAR_PIN_CAP));
}

static ssize_t pin_cfg_show(struct hdac_device *codec, hda_nid_t nid,
			    struct widget_attribute *attr, char *buf)
{
	unsigned int val;

	if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
		return 0;
	if (snd_hdac_read(codec, nid, AC_VERB_GET_CONFIG_DEFAULT, 0, &val))
		return 0;
	return sysfs_emit(buf, "0x%08x\n", val);
}

static bool has_pcm_cap(struct hdac_device *codec, hda_nid_t nid)
{
	if (nid == codec->afg || nid == codec->mfg)
		return true;
	switch (get_wcaps_type(get_wcaps(codec, nid))) {
	case AC_WID_AUD_OUT:
	case AC_WID_AUD_IN:
		return true;
	default:
		return false;
	}
}

static ssize_t pcm_caps_show(struct hdac_device *codec, hda_nid_t nid,
			     struct widget_attribute *attr, char *buf)
{
	if (!has_pcm_cap(codec, nid))
		return 0;
	return sysfs_emit(buf, "0x%08x\n",
			  snd_hdac_read_parm(codec, nid, AC_PAR_PCM));
}

static ssize_t pcm_formats_show(struct hdac_device *codec, hda_nid_t nid,
				struct widget_attribute *attr, char *buf)
{
	if (!has_pcm_cap(codec, nid))
		return 0;
	return sysfs_emit(buf, "0x%08x\n",
			  snd_hdac_read_parm(codec, nid, AC_PAR_STREAM));
}

static ssize_t amp_in_caps_show(struct hdac_device *codec, hda_nid_t nid,
				struct widget_attribute *attr, char *buf)
{
	if (nid != codec->afg && !(get_wcaps(codec, nid) & AC_WCAP_IN_AMP))
		return 0;
	return sysfs_emit(buf, "0x%08x\n",
			  snd_hdac_read_parm(codec, nid, AC_PAR_AMP_IN_CAP));
}

static ssize_t amp_out_caps_show(struct hdac_device *codec, hda_nid_t nid,
				 struct widget_attribute *attr, char *buf)
{
	if (nid != codec->afg && !(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP))
		return 0;
	return sysfs_emit(buf, "0x%08x\n",
			  snd_hdac_read_parm(codec, nid, AC_PAR_AMP_OUT_CAP));
}

static ssize_t power_caps_show(struct hdac_device *codec, hda_nid_t nid,
			       struct widget_attribute *attr, char *buf)
{
	if (nid != codec->afg && !(get_wcaps(codec, nid) & AC_WCAP_POWER))
		return 0;
	return sysfs_emit(buf, "0x%08x\n",
			  snd_hdac_read_parm(codec, nid, AC_PAR_POWER_STATE));
}

static ssize_t gpio_caps_show(struct hdac_device *codec, hda_nid_t nid,
			      struct widget_attribute *attr, char *buf)
{
	return sysfs_emit(buf, "0x%08x\n",
			  snd_hdac_read_parm(codec, nid, AC_PAR_GPIO_CAP));
}

static ssize_t connections_show(struct hdac_device *codec, hda_nid_t nid,
				struct widget_attribute *attr, char *buf)
{
	hda_nid_t list[32];
	int i, nconns;
	ssize_t ret = 0;

	nconns = snd_hdac_get_connections(codec, nid, list, ARRAY_SIZE(list));
	if (nconns <= 0)
		return nconns;
	for (i = 0; i < nconns; i++)
		ret += sysfs_emit_at(buf,  ret, "%s0x%02x", i ? " " : "", list[i]);
	ret += sysfs_emit_at(buf, ret, "\n");
	return ret;
}

static WIDGET_ATTR_RO(caps);
static WIDGET_ATTR_RO(pin_caps);
static WIDGET_ATTR_RO(pin_cfg);
static WIDGET_ATTR_RO(pcm_caps);
static WIDGET_ATTR_RO(pcm_formats);
static WIDGET_ATTR_RO(amp_in_caps);
static WIDGET_ATTR_RO(amp_out_caps);
static WIDGET_ATTR_RO(power_caps);
static WIDGET_ATTR_RO(gpio_caps);
static WIDGET_ATTR_RO(connections);

static struct attribute *widget_node_attrs[] = {
	&wid_attr_caps.attr,
	&wid_attr_pin_caps.attr,
	&wid_attr_pin_cfg.attr,
	&wid_attr_pcm_caps.attr,
	&wid_attr_pcm_formats.attr,
	&wid_attr_amp_in_caps.attr,
	&wid_attr_amp_out_caps.attr,
	&wid_attr_power_caps.attr,
	&wid_attr_connections.attr,
	NULL,
};

static struct attribute *widget_afg_attrs[] = {
	&wid_attr_pcm_caps.attr,
	&wid_attr_pcm_formats.attr,
	&wid_attr_amp_in_caps.attr,
	&wid_attr_amp_out_caps.attr,
	&wid_attr_power_caps.attr,
	&wid_attr_gpio_caps.attr,
	NULL,
};

static const struct attribute_group widget_node_group = {
	.attrs = widget_node_attrs,
};

static const struct attribute_group widget_afg_group = {
	.attrs = widget_afg_attrs,
};

static void free_widget_node(struct kobject *kobj,
			     const struct attribute_group *group)
{
	if (kobj) {
		sysfs_remove_group(kobj, group);
		kobject_put(kobj);
	}
}

static void widget_tree_free(struct hdac_device *codec)
{
	struct hdac_widget_tree *tree = codec->widgets;
	struct kobject **p;

	if (!tree)
		return;
	free_widget_node(tree->afg, &widget_afg_group);
	if (tree->nodes) {
		for (p = tree->nodes; *p; p++)
			free_widget_node(*p, &widget_node_group);
		kfree(tree->nodes);
	}
	kobject_put(tree->root);
	kfree(tree);
	codec->widgets = NULL;
}

static int add_widget_node(struct kobject *parent, hda_nid_t nid,
			   const struct attribute_group *group,
			   struct kobject **res)
{
	struct kobject *kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
	int err;

	if (!kobj)
		return -ENOMEM;
	kobject_init(kobj, &widget_ktype);
	err = kobject_add(kobj, parent, "%02x", nid);
	if (err < 0)
		return err;
	err = sysfs_create_group(kobj, group);
	if (err < 0) {
		kobject_put(kobj);
		return err;
	}

	*res = kobj;
	return 0;
}

static int widget_tree_create(struct hdac_device *codec)
{
	struct hdac_widget_tree *tree;
	int i, err;
	hda_nid_t nid;

	tree = codec->widgets = kzalloc(sizeof(*tree), GFP_KERNEL);
	if (!tree)
		return -ENOMEM;

	tree->root = kobject_create_and_add("widgets", &codec->dev.kobj);
	if (!tree->root)
		return -ENOMEM;

	tree->nodes = kcalloc(codec->num_nodes + 1, sizeof(*tree->nodes),
			      GFP_KERNEL);
	if (!tree->nodes)
		return -ENOMEM;

	for (i = 0, nid = codec->start_nid; i < codec->num_nodes; i++, nid++) {
		err = add_widget_node(tree->root, nid, &widget_node_group,
				      &tree->nodes[i]);
		if (err < 0)
			return err;
	}

	if (codec->afg) {
		err = add_widget_node(tree->root, codec->afg,
				      &widget_afg_group, &tree->afg);
		if (err < 0)
			return err;
	}

	kobject_uevent(tree->root, KOBJ_CHANGE);
	return 0;
}

/* call with codec->widget_lock held */
int hda_widget_sysfs_init(struct hdac_device *codec)
{
	int err;

	if (codec->widgets)
		return 0; /* already created */

	err = widget_tree_create(codec);
	if (err < 0) {
		widget_tree_free(codec);
		return err;
	}

	return 0;
}

/* call with codec->widget_lock held */
void hda_widget_sysfs_exit(struct hdac_device *codec)
{
	widget_tree_free(codec);
}

/* call with codec->widget_lock held */
int hda_widget_sysfs_reinit(struct hdac_device *codec,
			    hda_nid_t start_nid, int num_nodes)
{
	struct hdac_widget_tree *tree;
	hda_nid_t end_nid = start_nid + num_nodes;
	hda_nid_t nid;
	int i;

	if (!codec->widgets)
		return 0;

	tree = kmemdup(codec->widgets, sizeof(*tree), GFP_KERNEL);
	if (!tree)
		return -ENOMEM;

	tree->nodes = kcalloc(num_nodes + 1, sizeof(*tree->nodes), GFP_KERNEL);
	if (!tree->nodes) {
		kfree(tree);
		return -ENOMEM;
	}

	/* prune non-existing nodes */
	for (i = 0, nid = codec->start_nid; i < codec->num_nodes; i++, nid++) {
		if (nid < start_nid || nid >= end_nid)
			free_widget_node(codec->widgets->nodes[i],
					 &widget_node_group);
	}

	/* add new nodes */
	for (i = 0, nid = start_nid; i < num_nodes; i++, nid++) {
		if (nid < codec->start_nid || nid >= codec->end_nid)
			add_widget_node(tree->root, nid, &widget_node_group,
					&tree->nodes[i]);
		else
			tree->nodes[i] =
				codec->widgets->nodes[nid - codec->start_nid];
	}

	/* replace with the new tree */
	kfree(codec->widgets->nodes);
	kfree(codec->widgets);
	codec->widgets = tree;

	kobject_uevent(tree->root, KOBJ_CHANGE);
	return 0;
}
