/*
 * Apple Onboard Audio driver core
 *
 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
 *
 * GPL v2, can be found in COPYING.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/list.h>
#include "../aoa.h"
#include "alsa.h"

MODULE_DESCRIPTION("Apple Onboard Audio Sound Driver");
MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
MODULE_LICENSE("GPL");

/* We allow only one fabric. This simplifies things,
 * and more don't really make that much sense */
static struct aoa_fabric *fabric;
static LIST_HEAD(codec_list);

static int attach_codec_to_fabric(struct aoa_codec *c)
{
	int err;

	if (!try_module_get(c->owner))
		return -EBUSY;
	/* found_codec has to be assigned */
	err = -ENOENT;
	if (fabric->found_codec)
		err = fabric->found_codec(c);
	if (err) {
		module_put(c->owner);
		printk(KERN_ERR "snd-aoa: fabric didn't like codec %s\n",
				c->name);
		return err;
	}
	c->fabric = fabric;

	err = 0;
	if (c->init)
		err = c->init(c);
	if (err) {
		printk(KERN_ERR "snd-aoa: codec %s didn't init\n", c->name);
		c->fabric = NULL;
		if (fabric->remove_codec)
			fabric->remove_codec(c);
		module_put(c->owner);
		return err;
	}
	if (fabric->attached_codec)
		fabric->attached_codec(c);
	return 0;
}

int aoa_codec_register(struct aoa_codec *codec)
{
	int err = 0;

	/* if there's a fabric already, we can tell if we
	 * will want to have this codec, so propagate error
	 * through. Otherwise, this will happen later... */
	if (fabric)
		err = attach_codec_to_fabric(codec);
	if (!err)
		list_add(&codec->list, &codec_list);
	return err;
}
EXPORT_SYMBOL_GPL(aoa_codec_register);

void aoa_codec_unregister(struct aoa_codec *codec)
{
	list_del(&codec->list);
	if (codec->fabric && codec->exit)
		codec->exit(codec);
	if (fabric && fabric->remove_codec)
		fabric->remove_codec(codec);
	codec->fabric = NULL;
	module_put(codec->owner);
}
EXPORT_SYMBOL_GPL(aoa_codec_unregister);

int aoa_fabric_register(struct aoa_fabric *new_fabric, struct device *dev)
{
	struct aoa_codec *c;
	int err;

	/* allow querying for presence of fabric
	 * (i.e. do this test first!) */
	if (new_fabric == fabric) {
		err = -EALREADY;
		goto attach;
	}
	if (fabric)
		return -EEXIST;
	if (!new_fabric)
		return -EINVAL;

	err = aoa_alsa_init(new_fabric->name, new_fabric->owner, dev);
	if (err)
		return err;

	fabric = new_fabric;

 attach:
	list_for_each_entry(c, &codec_list, list) {
		if (c->fabric != fabric)
			attach_codec_to_fabric(c);
	}
	return err;
}
EXPORT_SYMBOL_GPL(aoa_fabric_register);

void aoa_fabric_unregister(struct aoa_fabric *old_fabric)
{
	struct aoa_codec *c;

	if (fabric != old_fabric)
		return;

	list_for_each_entry(c, &codec_list, list) {
		if (c->fabric)
			aoa_fabric_unlink_codec(c);
	}

	aoa_alsa_cleanup();

	fabric = NULL;
}
EXPORT_SYMBOL_GPL(aoa_fabric_unregister);

void aoa_fabric_unlink_codec(struct aoa_codec *codec)
{
	if (!codec->fabric) {
		printk(KERN_ERR "snd-aoa: fabric unassigned "
				"in aoa_fabric_unlink_codec\n");
		dump_stack();
		return;
	}
	if (codec->exit)
		codec->exit(codec);
	if (codec->fabric->remove_codec)
		codec->fabric->remove_codec(codec);
	codec->fabric = NULL;
	module_put(codec->owner);
}
EXPORT_SYMBOL_GPL(aoa_fabric_unlink_codec);

static int __init aoa_init(void)
{
	return 0;
}

static void __exit aoa_exit(void)
{
	aoa_alsa_cleanup();
}

module_init(aoa_init);
module_exit(aoa_exit);
