aboutsummaryrefslogtreecommitdiffstats
path: root/sound/oss/ac97_plugin_ad1980.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/oss/ac97_plugin_ad1980.c')
-rw-r--r--sound/oss/ac97_plugin_ad1980.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/sound/oss/ac97_plugin_ad1980.c b/sound/oss/ac97_plugin_ad1980.c
new file mode 100644
index 000000000000..24a9acd28160
--- /dev/null
+++ b/sound/oss/ac97_plugin_ad1980.c
@@ -0,0 +1,126 @@
+/*
+ ac97_plugin_ad1980.c Copyright (C) 2003 Red Hat, Inc. All rights reserved.
+
+ The contents of this file are subject to the Open Software License version 1.1
+ that can be found at http://www.opensource.org/licenses/osl-1.1.txt and is
+ included herein by reference.
+
+ Alternatively, the contents of this file may be used under the
+ terms of the GNU General Public License version 2 (the "GPL") as
+ distributed in the kernel source COPYING file, in which
+ case the provisions of the GPL are applicable instead of the
+ above. If you wish to allow the use of your version of this file
+ only under the terms of the GPL and not to allow others to use
+ your version of this file under the OSL, indicate your decision
+ by deleting the provisions above and replace them with the notice
+ and other provisions required by the GPL. If you do not delete
+ the provisions above, a recipient may use your version of this
+ file under either the OSL or the GPL.
+
+ Authors: Alan Cox <alan@redhat.com>
+
+ This is an example codec plugin. This one switches the connections
+ around to match the setups some vendors use with audio switched to
+ non standard front connectors not the normal rear ones
+
+ This code primarily exists to demonstrate how to use the codec
+ interface
+
+*/
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/ac97_codec.h>
+
+/**
+ * ad1980_remove - codec remove callback
+ * @codec: The codec that is being removed
+ *
+ * This callback occurs when an AC97 codec is being removed. A
+ * codec remove call will not occur for a codec during that codec
+ * probe callback.
+ *
+ * Most drivers will need to lock their remove versus their
+ * use of the codec after the probe function.
+ */
+
+static void __devexit ad1980_remove(struct ac97_codec *codec, struct ac97_driver *driver)
+{
+ /* Nothing to do in the simple example */
+}
+
+
+/**
+ * ad1980_probe - codec found callback
+ * @codec: ac97 codec matching the idents
+ * @driver: ac97_driver it matched
+ *
+ * This entry point is called when a codec is found which matches
+ * the driver. At the point it is called the codec is basically
+ * operational, mixer operations have been initialised and can
+ * be overriden. Called in process context. The field driver_private
+ * is available for the driver to use to store stuff.
+ *
+ * The caller can claim the device by returning zero, or return
+ * a negative error code.
+ */
+
+static int ad1980_probe(struct ac97_codec *codec, struct ac97_driver *driver)
+{
+ u16 control;
+
+#define AC97_AD_MISC 0x76
+
+ /* Switch the inputs/outputs over (from Dell code) */
+ control = codec->codec_read(codec, AC97_AD_MISC);
+ codec->codec_write(codec, AC97_AD_MISC, control | 0x4420);
+
+ /* We could refuse the device since we dont need to hang around,
+ but we will claim it */
+ return 0;
+}
+
+
+static struct ac97_driver ad1980_driver = {
+ .codec_id = 0x41445370,
+ .codec_mask = 0xFFFFFFFF,
+ .name = "AD1980 example",
+ .probe = ad1980_probe,
+ .remove = __devexit_p(ad1980_remove),
+};
+
+/**
+ * ad1980_exit - module exit path
+ *
+ * Our module is being unloaded. At this point unregister_driver
+ * will call back our remove handler for any existing codecs. You
+ * may not unregister_driver from interrupt context or from a
+ * probe/remove callback.
+ */
+
+static void ad1980_exit(void)
+{
+ ac97_unregister_driver(&ad1980_driver);
+}
+
+/**
+ * ad1980_init - set up ad1980 handlers
+ *
+ * After we call the register function it will call our probe
+ * function for each existing matching device before returning to us.
+ * Any devices appearing afterwards whose id's match the codec_id
+ * will also cause the probe function to be called.
+ * You may not register_driver from interrupt context or from a
+ * probe/remove callback.
+ */
+
+static int ad1980_init(void)
+{
+ return ac97_register_driver(&ad1980_driver);
+}
+
+module_init(ad1980_init);
+module_exit(ad1980_exit);
+MODULE_LICENSE("GPL");