diff options
Diffstat (limited to 'sound/oss/ac97_plugin_ad1980.c')
-rw-r--r-- | sound/oss/ac97_plugin_ad1980.c | 126 |
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"); |