patch-2.4.22 linux-2.4.22/drivers/sound/ac97_plugin_ad1980.c

Next file: linux-2.4.22/drivers/sound/ad1889.c
Previous file: linux-2.4.22/drivers/sound/ac97_codec.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.21/drivers/sound/ac97_plugin_ad1980.c linux-2.4.22/drivers/sound/ac97_plugin_ad1980.c
@@ -0,0 +1,124 @@
+/*
+    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/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 ad1980_remove(struct ac97_codec *codec)
+{
+	/* 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 | 0x0420);
+	
+	/* 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);

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)