// SPDX-License-Identifier: GPL-2.0
/*
 * Greybus operations
 *
 * Copyright 2015-2016 Google Inc.
 */

#include <linux/slab.h>

#include "audio_manager.h"
#include "audio_manager_private.h"

#define to_gb_audio_module_attr(x)	\
		container_of(x, struct gb_audio_manager_module_attribute, attr)

static inline struct gb_audio_manager_module *to_gb_audio_module(struct kobject *kobj)
{
	return container_of(kobj, struct gb_audio_manager_module, kobj);
}

struct gb_audio_manager_module_attribute {
	struct attribute attr;
	ssize_t (*show)(struct gb_audio_manager_module *module,
			struct gb_audio_manager_module_attribute *attr,
			char *buf);
	ssize_t (*store)(struct gb_audio_manager_module *module,
			 struct gb_audio_manager_module_attribute *attr,
			 const char *buf, size_t count);
};

static ssize_t gb_audio_module_attr_show(struct kobject *kobj,
					 struct attribute *attr, char *buf)
{
	struct gb_audio_manager_module_attribute *attribute;
	struct gb_audio_manager_module *module;

	attribute = to_gb_audio_module_attr(attr);
	module = to_gb_audio_module(kobj);

	if (!attribute->show)
		return -EIO;

	return attribute->show(module, attribute, buf);
}

static ssize_t gb_audio_module_attr_store(struct kobject *kobj,
					  struct attribute *attr,
					  const char *buf, size_t len)
{
	struct gb_audio_manager_module_attribute *attribute;
	struct gb_audio_manager_module *module;

	attribute = to_gb_audio_module_attr(attr);
	module = to_gb_audio_module(kobj);

	if (!attribute->store)
		return -EIO;

	return attribute->store(module, attribute, buf, len);
}

static const struct sysfs_ops gb_audio_module_sysfs_ops = {
	.show = gb_audio_module_attr_show,
	.store = gb_audio_module_attr_store,
};

static void gb_audio_module_release(struct kobject *kobj)
{
	struct gb_audio_manager_module *module = to_gb_audio_module(kobj);

	pr_info("Destroying audio module #%d\n", module->id);
	/* TODO -> delete from list */
	kfree(module);
}

static ssize_t gb_audio_module_name_show(struct gb_audio_manager_module *module,
					 struct gb_audio_manager_module_attribute *attr, char *buf)
{
	return sprintf(buf, "%s", module->desc.name);
}

static struct gb_audio_manager_module_attribute gb_audio_module_name_attribute =
	__ATTR(name, 0664, gb_audio_module_name_show, NULL);

static ssize_t gb_audio_module_vid_show(struct gb_audio_manager_module *module,
					struct gb_audio_manager_module_attribute *attr, char *buf)
{
	return sprintf(buf, "%d", module->desc.vid);
}

static struct gb_audio_manager_module_attribute gb_audio_module_vid_attribute =
	__ATTR(vid, 0664, gb_audio_module_vid_show, NULL);

static ssize_t gb_audio_module_pid_show(struct gb_audio_manager_module *module,
					struct gb_audio_manager_module_attribute *attr, char *buf)
{
	return sprintf(buf, "%d", module->desc.pid);
}

static struct gb_audio_manager_module_attribute gb_audio_module_pid_attribute =
	__ATTR(pid, 0664, gb_audio_module_pid_show, NULL);

static ssize_t gb_audio_module_intf_id_show(struct gb_audio_manager_module *module,
					    struct gb_audio_manager_module_attribute *attr,
					    char *buf)
{
	return sprintf(buf, "%d", module->desc.intf_id);
}

static struct gb_audio_manager_module_attribute
					gb_audio_module_intf_id_attribute =
	__ATTR(intf_id, 0664, gb_audio_module_intf_id_show, NULL);

static ssize_t gb_audio_module_ip_devices_show(struct gb_audio_manager_module *module,
					       struct gb_audio_manager_module_attribute *attr,
					       char *buf)
{
	return sprintf(buf, "0x%X", module->desc.ip_devices);
}

static struct gb_audio_manager_module_attribute
					gb_audio_module_ip_devices_attribute =
	__ATTR(ip_devices, 0664, gb_audio_module_ip_devices_show, NULL);

static ssize_t gb_audio_module_op_devices_show(struct gb_audio_manager_module *module,
					       struct gb_audio_manager_module_attribute *attr,
					       char *buf)
{
	return sprintf(buf, "0x%X", module->desc.op_devices);
}

static struct gb_audio_manager_module_attribute
					gb_audio_module_op_devices_attribute =
	__ATTR(op_devices, 0664, gb_audio_module_op_devices_show, NULL);

static struct attribute *gb_audio_module_default_attrs[] = {
	&gb_audio_module_name_attribute.attr,
	&gb_audio_module_vid_attribute.attr,
	&gb_audio_module_pid_attribute.attr,
	&gb_audio_module_intf_id_attribute.attr,
	&gb_audio_module_ip_devices_attribute.attr,
	&gb_audio_module_op_devices_attribute.attr,
	NULL,   /* need to NULL terminate the list of attributes */
};
ATTRIBUTE_GROUPS(gb_audio_module_default);

static struct kobj_type gb_audio_module_type = {
	.sysfs_ops = &gb_audio_module_sysfs_ops,
	.release = gb_audio_module_release,
	.default_groups = gb_audio_module_default_groups,
};

static void send_add_uevent(struct gb_audio_manager_module *module)
{
	char name_string[128];
	char vid_string[64];
	char pid_string[64];
	char intf_id_string[64];
	char ip_devices_string[64];
	char op_devices_string[64];

	char *envp[] = {
		name_string,
		vid_string,
		pid_string,
		intf_id_string,
		ip_devices_string,
		op_devices_string,
		NULL
	};

	snprintf(name_string, 128, "NAME=%s", module->desc.name);
	snprintf(vid_string, 64, "VID=%d", module->desc.vid);
	snprintf(pid_string, 64, "PID=%d", module->desc.pid);
	snprintf(intf_id_string, 64, "INTF_ID=%d", module->desc.intf_id);
	snprintf(ip_devices_string, 64, "I/P DEVICES=0x%X",
		 module->desc.ip_devices);
	snprintf(op_devices_string, 64, "O/P DEVICES=0x%X",
		 module->desc.op_devices);

	kobject_uevent_env(&module->kobj, KOBJ_ADD, envp);
}

int gb_audio_manager_module_create(struct gb_audio_manager_module **module,
				   struct kset *manager_kset,
				   int id, struct gb_audio_manager_module_descriptor *desc)
{
	int err;
	struct gb_audio_manager_module *m;

	m = kzalloc(sizeof(*m), GFP_ATOMIC);
	if (!m)
		return -ENOMEM;

	/* Initialize the node */
	INIT_LIST_HEAD(&m->list);

	/* Set the module id */
	m->id = id;

	/* Copy the provided descriptor */
	memcpy(&m->desc, desc, sizeof(*desc));

	/* set the kset */
	m->kobj.kset = manager_kset;

	/*
	 * Initialize and add the kobject to the kernel.  All the default files
	 * will be created here.  As we have already specified a kset for this
	 * kobject, we don't have to set a parent for the kobject, the kobject
	 * will be placed beneath that kset automatically.
	 */
	err = kobject_init_and_add(&m->kobj, &gb_audio_module_type, NULL, "%d",
				   id);
	if (err) {
		pr_err("failed initializing kobject for audio module #%d\n", id);
		kobject_put(&m->kobj);
		return err;
	}

	/*
	 * Notify the object was created
	 */
	send_add_uevent(m);

	*module = m;
	pr_info("Created audio module #%d\n", id);
	return 0;
}

void gb_audio_manager_module_dump(struct gb_audio_manager_module *module)
{
	pr_info("audio module #%d name=%s vid=%d pid=%d intf_id=%d i/p devices=0x%X o/p devices=0x%X\n",
		module->id,
		module->desc.name,
		module->desc.vid,
		module->desc.pid,
		module->desc.intf_id,
		module->desc.ip_devices,
		module->desc.op_devices);
}
