// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * dsp_pipeline.c: pipelined audio processing
 *
 * Copyright (C) 2007, Nadi Sarrar
 *
 * Nadi Sarrar <nadi@beronet.com>
 */

#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/string.h>
#include <linux/mISDNif.h>
#include <linux/mISDNdsp.h>
#include <linux/export.h>
#include "dsp.h"
#include "dsp_hwec.h"

struct dsp_pipeline_entry {
	struct mISDN_dsp_element *elem;
	void                *p;
	struct list_head     list;
};
struct dsp_element_entry {
	struct mISDN_dsp_element *elem;
	struct device	     dev;
	struct list_head     list;
};

static LIST_HEAD(dsp_elements);

/* sysfs */
static const struct class elements_class = {
	.name = "dsp_pipeline",
};

static ssize_t
attr_show_args(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct mISDN_dsp_element *elem = dev_get_drvdata(dev);
	int i;
	char *p = buf;

	*buf = 0;
	for (i = 0; i < elem->num_args; i++)
		p += sprintf(p, "Name:        %s\n%s%s%sDescription: %s\n\n",
			     elem->args[i].name,
			     elem->args[i].def ? "Default:     " : "",
			     elem->args[i].def ? elem->args[i].def : "",
			     elem->args[i].def ? "\n" : "",
			     elem->args[i].desc);

	return p - buf;
}

static struct device_attribute element_attributes[] = {
	__ATTR(args, 0444, attr_show_args, NULL),
};

static void
mISDN_dsp_dev_release(struct device *dev)
{
	struct dsp_element_entry *entry =
		container_of(dev, struct dsp_element_entry, dev);
	list_del(&entry->list);
	kfree(entry);
}

int mISDN_dsp_element_register(struct mISDN_dsp_element *elem)
{
	struct dsp_element_entry *entry;
	int ret, i;

	if (!elem)
		return -EINVAL;

	entry = kzalloc(sizeof(struct dsp_element_entry), GFP_ATOMIC);
	if (!entry)
		return -ENOMEM;

	INIT_LIST_HEAD(&entry->list);
	entry->elem = elem;

	entry->dev.class = &elements_class;
	entry->dev.release = mISDN_dsp_dev_release;
	dev_set_drvdata(&entry->dev, elem);
	dev_set_name(&entry->dev, "%s", elem->name);
	ret = device_register(&entry->dev);
	if (ret) {
		printk(KERN_ERR "%s: failed to register %s\n",
		       __func__, elem->name);
		goto err1;
	}
	list_add_tail(&entry->list, &dsp_elements);

	for (i = 0; i < ARRAY_SIZE(element_attributes); ++i) {
		ret = device_create_file(&entry->dev,
					 &element_attributes[i]);
		if (ret) {
			printk(KERN_ERR "%s: failed to create device file\n",
			       __func__);
			goto err2;
		}
	}

	return 0;

err2:
	device_unregister(&entry->dev);
	return ret;
err1:
	put_device(&entry->dev);
	return ret;
}
EXPORT_SYMBOL(mISDN_dsp_element_register);

void mISDN_dsp_element_unregister(struct mISDN_dsp_element *elem)
{
	struct dsp_element_entry *entry, *n;

	if (!elem)
		return;

	list_for_each_entry_safe(entry, n, &dsp_elements, list)
		if (entry->elem == elem) {
			device_unregister(&entry->dev);
			return;
		}
	printk(KERN_ERR "%s: element %s not in list.\n", __func__, elem->name);
}
EXPORT_SYMBOL(mISDN_dsp_element_unregister);

int dsp_pipeline_module_init(void)
{
	int err;

	err = class_register(&elements_class);
	if (err)
		return err;

	dsp_hwec_init();

	return 0;
}

void dsp_pipeline_module_exit(void)
{
	struct dsp_element_entry *entry, *n;

	dsp_hwec_exit();

	class_unregister(&elements_class);

	list_for_each_entry_safe(entry, n, &dsp_elements, list) {
		list_del(&entry->list);
		printk(KERN_WARNING "%s: element was still registered: %s\n",
		       __func__, entry->elem->name);
		kfree(entry);
	}
}

int dsp_pipeline_init(struct dsp_pipeline *pipeline)
{
	if (!pipeline)
		return -EINVAL;

	INIT_LIST_HEAD(&pipeline->list);

	return 0;
}

static inline void _dsp_pipeline_destroy(struct dsp_pipeline *pipeline)
{
	struct dsp_pipeline_entry *entry, *n;

	list_for_each_entry_safe(entry, n, &pipeline->list, list) {
		list_del(&entry->list);
		if (entry->elem == dsp_hwec)
			dsp_hwec_disable(container_of(pipeline, struct dsp,
						      pipeline));
		else
			entry->elem->free(entry->p);
		kfree(entry);
	}
}

void dsp_pipeline_destroy(struct dsp_pipeline *pipeline)
{

	if (!pipeline)
		return;

	_dsp_pipeline_destroy(pipeline);
}

int dsp_pipeline_build(struct dsp_pipeline *pipeline, const char *cfg)
{
	int found = 0;
	char *dup, *next, *tok, *name, *args;
	struct dsp_element_entry *entry, *n;
	struct dsp_pipeline_entry *pipeline_entry;
	struct mISDN_dsp_element *elem;

	if (!pipeline)
		return -EINVAL;

	if (!list_empty(&pipeline->list))
		_dsp_pipeline_destroy(pipeline);

	dup = next = kstrdup(cfg, GFP_ATOMIC);
	if (!dup)
		return 0;
	while ((tok = strsep(&next, "|"))) {
		if (!strlen(tok))
			continue;
		name = strsep(&tok, "(");
		args = strsep(&tok, ")");
		if (args && !*args)
			args = NULL;

		list_for_each_entry_safe(entry, n, &dsp_elements, list)
			if (!strcmp(entry->elem->name, name)) {
				elem = entry->elem;

				pipeline_entry = kmalloc(sizeof(struct
								dsp_pipeline_entry), GFP_ATOMIC);
				if (!pipeline_entry) {
					printk(KERN_ERR "%s: failed to add "
					       "entry to pipeline: %s (out of "
					       "memory)\n", __func__, elem->name);
					goto _out;
				}
				pipeline_entry->elem = elem;

				if (elem == dsp_hwec) {
					/* This is a hack to make the hwec
					   available as a pipeline module */
					dsp_hwec_enable(container_of(pipeline,
								     struct dsp, pipeline), args);
					list_add_tail(&pipeline_entry->list,
						      &pipeline->list);
				} else {
					pipeline_entry->p = elem->new(args);
					if (pipeline_entry->p) {
						list_add_tail(&pipeline_entry->
							      list, &pipeline->list);
					} else {
						printk(KERN_ERR "%s: failed "
						       "to add entry to pipeline: "
						       "%s (new() returned NULL)\n",
						       __func__, elem->name);
						kfree(pipeline_entry);
					}
				}
				found = 1;
				break;
			}

		if (found)
			found = 0;
		else
			printk(KERN_ERR "%s: element not found, skipping: "
			       "%s\n", __func__, name);
	}

_out:
	if (!list_empty(&pipeline->list))
		pipeline->inuse = 1;
	else
		pipeline->inuse = 0;

	kfree(dup);
	return 0;
}

void dsp_pipeline_process_tx(struct dsp_pipeline *pipeline, u8 *data, int len)
{
	struct dsp_pipeline_entry *entry;

	if (!pipeline)
		return;

	list_for_each_entry(entry, &pipeline->list, list)
		if (entry->elem->process_tx)
			entry->elem->process_tx(entry->p, data, len);
}

void dsp_pipeline_process_rx(struct dsp_pipeline *pipeline, u8 *data, int len,
			     unsigned int txlen)
{
	struct dsp_pipeline_entry *entry;

	if (!pipeline)
		return;

	list_for_each_entry_reverse(entry, &pipeline->list, list)
		if (entry->elem->process_rx)
			entry->elem->process_rx(entry->p, data, len, txlen);
}
