/*
 * Copyright (C) 2016 Robert Jarzmik <robert.jarzmik@free.fr>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/device.h>
#include <linux/idr.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/sysfs.h>
#include <sound/ac97/codec.h>
#include <sound/ac97/controller.h>
#include <sound/ac97/regs.h>

#include "ac97_core.h"

/*
 * Protects ac97_controllers and each ac97_controller structure.
 */
static DEFINE_MUTEX(ac97_controllers_mutex);
static DEFINE_IDR(ac97_adapter_idr);
static LIST_HEAD(ac97_controllers);

static struct bus_type ac97_bus_type;

static inline struct ac97_controller*
to_ac97_controller(struct device *ac97_adapter)
{
	return container_of(ac97_adapter, struct ac97_controller, adap);
}

static int ac97_unbound_ctrl_write(struct ac97_controller *adrv, int slot,
		     unsigned short reg, unsigned short val)
{
	return -ENODEV;
}

static int ac97_unbound_ctrl_read(struct ac97_controller *adrv, int slot,
				  unsigned short reg)
{
	return -ENODEV;
}

static const struct ac97_controller_ops ac97_unbound_ctrl_ops = {
	.write = ac97_unbound_ctrl_write,
	.read = ac97_unbound_ctrl_read,
};

static struct ac97_controller ac97_unbound_ctrl = {
	.ops = &ac97_unbound_ctrl_ops,
};

static struct ac97_codec_device *
ac97_codec_find(struct ac97_controller *ac97_ctrl, unsigned int codec_num)
{
	if (codec_num >= AC97_BUS_MAX_CODECS)
		return ERR_PTR(-EINVAL);

	return ac97_ctrl->codecs[codec_num];
}

static void ac97_codec_release(struct device *dev)
{
	struct ac97_codec_device *adev;
	struct ac97_controller *ac97_ctrl;

	adev = to_ac97_device(dev);
	ac97_ctrl = adev->ac97_ctrl;
	ac97_ctrl->codecs[adev->num] = NULL;
	kfree(adev);
}

static int ac97_codec_add(struct ac97_controller *ac97_ctrl, int idx,
		   unsigned int vendor_id)
{
	struct ac97_codec_device *codec;
	int ret;

	codec = kzalloc(sizeof(*codec), GFP_KERNEL);
	if (!codec)
		return -ENOMEM;
	ac97_ctrl->codecs[idx] = codec;
	codec->vendor_id = vendor_id;
	codec->dev.release = ac97_codec_release;
	codec->dev.bus = &ac97_bus_type;
	codec->dev.parent = &ac97_ctrl->adap;
	codec->num = idx;
	codec->ac97_ctrl = ac97_ctrl;

	device_initialize(&codec->dev);
	dev_set_name(&codec->dev, "%s:%u", dev_name(ac97_ctrl->parent), idx);

	ret = device_add(&codec->dev);
	if (ret)
		goto err_free_codec;

	return 0;
err_free_codec:
	put_device(&codec->dev);
	kfree(codec);
	ac97_ctrl->codecs[idx] = NULL;

	return ret;
}

unsigned int snd_ac97_bus_scan_one(struct ac97_controller *adrv,
				   unsigned int codec_num)
{
	unsigned short vid1, vid2;
	int ret;

	ret = adrv->ops->read(adrv, codec_num, AC97_VENDOR_ID1);
	vid1 = (ret & 0xffff);
	if (ret < 0)
		return 0;

	ret = adrv->ops->read(adrv, codec_num, AC97_VENDOR_ID2);
	vid2 = (ret & 0xffff);
	if (ret < 0)
		return 0;

	dev_dbg(&adrv->adap, "%s(codec_num=%u): vendor_id=0x%08x\n",
		__func__, codec_num, AC97_ID(vid1, vid2));
	return AC97_ID(vid1, vid2);
}

static int ac97_bus_scan(struct ac97_controller *ac97_ctrl)
{
	int ret, i;
	unsigned int vendor_id;

	for (i = 0; i < AC97_BUS_MAX_CODECS; i++) {
		if (ac97_codec_find(ac97_ctrl, i))
			continue;
		if (!(ac97_ctrl->slots_available & BIT(i)))
			continue;
		vendor_id = snd_ac97_bus_scan_one(ac97_ctrl, i);
		if (!vendor_id)
			continue;

		ret = ac97_codec_add(ac97_ctrl, i, vendor_id);
		if (ret < 0)
			return ret;
	}
	return 0;
}

static int ac97_bus_reset(struct ac97_controller *ac97_ctrl)
{
	ac97_ctrl->ops->reset(ac97_ctrl);

	return 0;
}

/**
 * snd_ac97_codec_driver_register - register an AC97 codec driver
 * @dev: AC97 driver codec to register
 *
 * Register an AC97 codec driver to the ac97 bus driver, aka. the AC97 digital
 * controller.
 *
 * Returns 0 on success or error code
 */
int snd_ac97_codec_driver_register(struct ac97_codec_driver *drv)
{
	drv->driver.bus = &ac97_bus_type;
	return driver_register(&drv->driver);
}
EXPORT_SYMBOL_GPL(snd_ac97_codec_driver_register);

/**
 * snd_ac97_codec_driver_unregister - unregister an AC97 codec driver
 * @dev: AC97 codec driver to unregister
 *
 * Unregister a previously registered ac97 codec driver.
 */
void snd_ac97_codec_driver_unregister(struct ac97_codec_driver *drv)
{
	driver_unregister(&drv->driver);
}
EXPORT_SYMBOL_GPL(snd_ac97_codec_driver_unregister);

/**
 * snd_ac97_codec_get_platdata - get platform_data
 * @adev: the ac97 codec device
 *
 * For legacy platforms, in order to have platform_data in codec drivers
 * available, while ac97 device are auto-created upon probe, this retrieves the
 * platdata which was setup on ac97 controller registration.
 *
 * Returns the platform data pointer
 */
void *snd_ac97_codec_get_platdata(const struct ac97_codec_device *adev)
{
	struct ac97_controller *ac97_ctrl = adev->ac97_ctrl;

	return ac97_ctrl->codecs_pdata[adev->num];
}
EXPORT_SYMBOL_GPL(snd_ac97_codec_get_platdata);

static void ac97_ctrl_codecs_unregister(struct ac97_controller *ac97_ctrl)
{
	int i;

	for (i = 0; i < AC97_BUS_MAX_CODECS; i++)
		if (ac97_ctrl->codecs[i]) {
			ac97_ctrl->codecs[i]->ac97_ctrl = &ac97_unbound_ctrl;
			device_unregister(&ac97_ctrl->codecs[i]->dev);
		}
}

static ssize_t cold_reset_store(struct device *dev,
				struct device_attribute *attr, const char *buf,
				size_t len)
{
	struct ac97_controller *ac97_ctrl;

	mutex_lock(&ac97_controllers_mutex);
	ac97_ctrl = to_ac97_controller(dev);
	ac97_ctrl->ops->reset(ac97_ctrl);
	mutex_unlock(&ac97_controllers_mutex);
	return len;
}
static DEVICE_ATTR_WO(cold_reset);

static ssize_t warm_reset_store(struct device *dev,
				struct device_attribute *attr, const char *buf,
				size_t len)
{
	struct ac97_controller *ac97_ctrl;

	if (!dev)
		return -ENODEV;

	mutex_lock(&ac97_controllers_mutex);
	ac97_ctrl = to_ac97_controller(dev);
	ac97_ctrl->ops->warm_reset(ac97_ctrl);
	mutex_unlock(&ac97_controllers_mutex);
	return len;
}
static DEVICE_ATTR_WO(warm_reset);

static struct attribute *ac97_controller_device_attrs[] = {
	&dev_attr_cold_reset.attr,
	&dev_attr_warm_reset.attr,
	NULL
};

static struct attribute_group ac97_adapter_attr_group = {
	.name	= "ac97_operations",
	.attrs	= ac97_controller_device_attrs,
};

static const struct attribute_group *ac97_adapter_groups[] = {
	&ac97_adapter_attr_group,
	NULL,
};

static void ac97_del_adapter(struct ac97_controller *ac97_ctrl)
{
	mutex_lock(&ac97_controllers_mutex);
	ac97_ctrl_codecs_unregister(ac97_ctrl);
	list_del(&ac97_ctrl->controllers);
	mutex_unlock(&ac97_controllers_mutex);

	device_unregister(&ac97_ctrl->adap);
}

static void ac97_adapter_release(struct device *dev)
{
	struct ac97_controller *ac97_ctrl;

	ac97_ctrl = to_ac97_controller(dev);
	idr_remove(&ac97_adapter_idr, ac97_ctrl->nr);
	dev_dbg(&ac97_ctrl->adap, "adapter unregistered by %s\n",
		dev_name(ac97_ctrl->parent));
}

static const struct device_type ac97_adapter_type = {
	.groups		= ac97_adapter_groups,
	.release	= ac97_adapter_release,
};

static int ac97_add_adapter(struct ac97_controller *ac97_ctrl)
{
	int ret;

	mutex_lock(&ac97_controllers_mutex);
	ret = idr_alloc(&ac97_adapter_idr, ac97_ctrl, 0, 0, GFP_KERNEL);
	ac97_ctrl->nr = ret;
	if (ret >= 0) {
		dev_set_name(&ac97_ctrl->adap, "ac97-%d", ret);
		ac97_ctrl->adap.type = &ac97_adapter_type;
		ac97_ctrl->adap.parent = ac97_ctrl->parent;
		ret = device_register(&ac97_ctrl->adap);
		if (ret)
			put_device(&ac97_ctrl->adap);
	}
	if (!ret)
		list_add(&ac97_ctrl->controllers, &ac97_controllers);
	mutex_unlock(&ac97_controllers_mutex);

	if (!ret)
		dev_dbg(&ac97_ctrl->adap, "adapter registered by %s\n",
			dev_name(ac97_ctrl->parent));
	return ret;
}

/**
 * snd_ac97_controller_register - register an ac97 controller
 * @ops: the ac97 bus operations
 * @dev: the device providing the ac97 DC function
 * @slots_available: mask of the ac97 codecs that can be scanned and probed
 *                   bit0 => codec 0, bit1 => codec 1 ... bit 3 => codec 3
 *
 * Register a digital controller which can control up to 4 ac97 codecs. This is
 * the controller side of the AC97 AC-link, while the slave side are the codecs.
 *
 * Returns a valid controller upon success, negative pointer value upon error
 */
struct ac97_controller *snd_ac97_controller_register(
	const struct ac97_controller_ops *ops, struct device *dev,
	unsigned short slots_available, void **codecs_pdata)
{
	struct ac97_controller *ac97_ctrl;
	int ret, i;

	ac97_ctrl = kzalloc(sizeof(*ac97_ctrl), GFP_KERNEL);
	if (!ac97_ctrl)
		return ERR_PTR(-ENOMEM);

	for (i = 0; i < AC97_BUS_MAX_CODECS && codecs_pdata; i++)
		ac97_ctrl->codecs_pdata[i] = codecs_pdata[i];

	ac97_ctrl->ops = ops;
	ac97_ctrl->slots_available = slots_available;
	ac97_ctrl->parent = dev;
	ret = ac97_add_adapter(ac97_ctrl);

	if (ret)
		goto err;
	ac97_bus_reset(ac97_ctrl);
	ac97_bus_scan(ac97_ctrl);

	return ac97_ctrl;
err:
	kfree(ac97_ctrl);
	return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(snd_ac97_controller_register);

/**
 * snd_ac97_controller_unregister - unregister an ac97 controller
 * @ac97_ctrl: the device previously provided to ac97_controller_register()
 *
 */
void snd_ac97_controller_unregister(struct ac97_controller *ac97_ctrl)
{
	ac97_del_adapter(ac97_ctrl);
}
EXPORT_SYMBOL_GPL(snd_ac97_controller_unregister);

#ifdef CONFIG_PM
static int ac97_pm_runtime_suspend(struct device *dev)
{
	struct ac97_codec_device *codec = to_ac97_device(dev);
	int ret = pm_generic_runtime_suspend(dev);

	if (ret == 0 && dev->driver) {
		if (pm_runtime_is_irq_safe(dev))
			clk_disable(codec->clk);
		else
			clk_disable_unprepare(codec->clk);
	}

	return ret;
}

static int ac97_pm_runtime_resume(struct device *dev)
{
	struct ac97_codec_device *codec = to_ac97_device(dev);
	int ret;

	if (dev->driver) {
		if (pm_runtime_is_irq_safe(dev))
			ret = clk_enable(codec->clk);
		else
			ret = clk_prepare_enable(codec->clk);
		if (ret)
			return ret;
	}

	return pm_generic_runtime_resume(dev);
}
#endif /* CONFIG_PM */

static const struct dev_pm_ops ac97_pm = {
	.suspend	= pm_generic_suspend,
	.resume		= pm_generic_resume,
	.freeze		= pm_generic_freeze,
	.thaw		= pm_generic_thaw,
	.poweroff	= pm_generic_poweroff,
	.restore	= pm_generic_restore,
	SET_RUNTIME_PM_OPS(
		ac97_pm_runtime_suspend,
		ac97_pm_runtime_resume,
		NULL)
};

static int ac97_get_enable_clk(struct ac97_codec_device *adev)
{
	int ret;

	adev->clk = clk_get(&adev->dev, "ac97_clk");
	if (IS_ERR(adev->clk))
		return PTR_ERR(adev->clk);

	ret = clk_prepare_enable(adev->clk);
	if (ret)
		clk_put(adev->clk);

	return ret;
}

static void ac97_put_disable_clk(struct ac97_codec_device *adev)
{
	clk_disable_unprepare(adev->clk);
	clk_put(adev->clk);
}

static ssize_t vendor_id_show(struct device *dev,
			      struct device_attribute *attr, char *buf)
{
	struct ac97_codec_device *codec = to_ac97_device(dev);

	return sprintf(buf, "%08x", codec->vendor_id);
}
DEVICE_ATTR_RO(vendor_id);

static struct attribute *ac97_dev_attrs[] = {
	&dev_attr_vendor_id.attr,
	NULL,
};
ATTRIBUTE_GROUPS(ac97_dev);

static int ac97_bus_match(struct device *dev, struct device_driver *drv)
{
	struct ac97_codec_device *adev = to_ac97_device(dev);
	struct ac97_codec_driver *adrv = to_ac97_driver(drv);
	const struct ac97_id *id = adrv->id_table;
	int i = 0;

	if (adev->vendor_id == 0x0 || adev->vendor_id == 0xffffffff)
		return false;

	do {
		if (ac97_ids_match(id[i].id, adev->vendor_id, id[i].mask))
			return true;
	} while (id[i++].id);

	return false;
}

static int ac97_bus_probe(struct device *dev)
{
	struct ac97_codec_device *adev = to_ac97_device(dev);
	struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
	int ret;

	ret = ac97_get_enable_clk(adev);
	if (ret)
		return ret;

	pm_runtime_get_noresume(dev);
	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);

	ret = adrv->probe(adev);
	if (ret == 0)
		return 0;

	pm_runtime_disable(dev);
	pm_runtime_set_suspended(dev);
	pm_runtime_put_noidle(dev);
	ac97_put_disable_clk(adev);

	return ret;
}

static int ac97_bus_remove(struct device *dev)
{
	struct ac97_codec_device *adev = to_ac97_device(dev);
	struct ac97_codec_driver *adrv = to_ac97_driver(dev->driver);
	int ret;

	ret = pm_runtime_get_sync(dev);
	if (ret)
		return ret;

	ret = adrv->remove(adev);
	pm_runtime_put_noidle(dev);
	if (ret == 0)
		ac97_put_disable_clk(adev);

	return ret;
}

static struct bus_type ac97_bus_type = {
	.name		= "ac97bus",
	.dev_groups	= ac97_dev_groups,
	.match		= ac97_bus_match,
	.pm		= &ac97_pm,
	.probe		= ac97_bus_probe,
	.remove		= ac97_bus_remove,
};

static int __init ac97_bus_init(void)
{
	return bus_register(&ac97_bus_type);
}
subsys_initcall(ac97_bus_init);

static void __exit ac97_bus_exit(void)
{
	bus_unregister(&ac97_bus_type);
}
module_exit(ac97_bus_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Robert Jarzmik <robert.jarzmik@free.fr>");
