1 // SPDX-License-Identifier: GPL-2.0-only
3 * Apple Onboard Audio driver core
5 * Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
8 #include <linux/init.h>
9 #include <linux/module.h>
10 #include <linux/list.h>
14 MODULE_DESCRIPTION("Apple Onboard Audio Sound Driver");
15 MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
16 MODULE_LICENSE("GPL");
18 /* We allow only one fabric. This simplifies things,
19 * and more don't really make that much sense */
20 static struct aoa_fabric *fabric;
21 static LIST_HEAD(codec_list);
23 static int attach_codec_to_fabric(struct aoa_codec *c)
27 if (!try_module_get(c->owner))
29 /* found_codec has to be assigned */
31 if (fabric->found_codec)
32 err = fabric->found_codec(c);
35 printk(KERN_ERR "snd-aoa: fabric didn't like codec %s\n",
45 printk(KERN_ERR "snd-aoa: codec %s didn't init\n", c->name);
47 if (fabric->remove_codec)
48 fabric->remove_codec(c);
52 if (fabric->attached_codec)
53 fabric->attached_codec(c);
57 int aoa_codec_register(struct aoa_codec *codec)
61 /* if there's a fabric already, we can tell if we
62 * will want to have this codec, so propagate error
63 * through. Otherwise, this will happen later... */
65 err = attach_codec_to_fabric(codec);
67 list_add(&codec->list, &codec_list);
70 EXPORT_SYMBOL_GPL(aoa_codec_register);
72 void aoa_codec_unregister(struct aoa_codec *codec)
74 list_del(&codec->list);
75 if (codec->fabric && codec->exit)
77 if (fabric && fabric->remove_codec)
78 fabric->remove_codec(codec);
80 module_put(codec->owner);
82 EXPORT_SYMBOL_GPL(aoa_codec_unregister);
84 int aoa_fabric_register(struct aoa_fabric *new_fabric, struct device *dev)
89 /* allow querying for presence of fabric
90 * (i.e. do this test first!) */
91 if (new_fabric == fabric) {
100 err = aoa_alsa_init(new_fabric->name, new_fabric->owner, dev);
107 list_for_each_entry(c, &codec_list, list) {
108 if (c->fabric != fabric)
109 attach_codec_to_fabric(c);
113 EXPORT_SYMBOL_GPL(aoa_fabric_register);
115 void aoa_fabric_unregister(struct aoa_fabric *old_fabric)
119 if (fabric != old_fabric)
122 list_for_each_entry(c, &codec_list, list) {
124 aoa_fabric_unlink_codec(c);
131 EXPORT_SYMBOL_GPL(aoa_fabric_unregister);
133 void aoa_fabric_unlink_codec(struct aoa_codec *codec)
135 if (!codec->fabric) {
136 printk(KERN_ERR "snd-aoa: fabric unassigned "
137 "in aoa_fabric_unlink_codec\n");
143 if (codec->fabric->remove_codec)
144 codec->fabric->remove_codec(codec);
145 codec->fabric = NULL;
146 module_put(codec->owner);
148 EXPORT_SYMBOL_GPL(aoa_fabric_unlink_codec);
150 static int __init aoa_init(void)
155 static void __exit aoa_exit(void)
160 module_init(aoa_init);
161 module_exit(aoa_exit);