/*
 * Greybus operations
 *
 * Copyright 2015-2016 Google Inc.
 *
 * Released under the GPLv2 only.
 */

#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)
#define to_gb_audio_module(x)		\
		container_of(x, 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_slot_show(
	struct gb_audio_manager_module *module,
	struct gb_audio_manager_module_attribute *attr, char *buf)
{
	return sprintf(buf, "%d", module->desc.slot);
}

static struct gb_audio_manager_module_attribute gb_audio_module_slot_attribute =
	__ATTR(slot, 0664, gb_audio_module_slot_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_cport_show(
	struct gb_audio_manager_module *module,
	struct gb_audio_manager_module_attribute *attr, char *buf)
{
	return sprintf(buf, "%d", module->desc.cport);
}

static struct gb_audio_manager_module_attribute
					gb_audio_module_cport_attribute =
	__ATTR(cport, 0664, gb_audio_module_cport_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_slot_attribute.attr,
	&gb_audio_module_vid_attribute.attr,
	&gb_audio_module_pid_attribute.attr,
	&gb_audio_module_cport_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 */
};

static struct kobj_type gb_audio_module_type = {
	.sysfs_ops = &gb_audio_module_sysfs_ops,
	.release = gb_audio_module_release,
	.default_attrs = gb_audio_module_default_attrs,
};

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

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

	snprintf(name_string, 128, "NAME=%s", module->desc.name);
	snprintf(slot_string, 64, "SLOT=%d", module->desc.slot);
	snprintf(vid_string, 64, "VID=%d", module->desc.vid);
	snprintf(pid_string, 64, "PID=%d", module->desc.pid);
	snprintf(cport_string, 64, "CPORT=%d", module->desc.cport);
	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 slot=%d vid=%d pid=%d cport=%d i/p devices=0x%X o/p devices=0x%X\n",
		module->id,
		module->desc.name,
		module->desc.slot,
		module->desc.vid,
		module->desc.pid,
		module->desc.cport,
		module->desc.ip_devices,
		module->desc.op_devices);
}
