| /* |
| 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"); |