Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | ac97_plugin_ad1980.c Copyright (C) 2003 Red Hat, Inc. All rights reserved. | |
3 | ||
4 | The contents of this file are subject to the Open Software License version 1.1 | |
5 | that can be found at http://www.opensource.org/licenses/osl-1.1.txt and is | |
6 | included herein by reference. | |
7 | ||
8 | Alternatively, the contents of this file may be used under the | |
9 | terms of the GNU General Public License version 2 (the "GPL") as | |
10 | distributed in the kernel source COPYING file, in which | |
11 | case the provisions of the GPL are applicable instead of the | |
12 | above. If you wish to allow the use of your version of this file | |
13 | only under the terms of the GPL and not to allow others to use | |
14 | your version of this file under the OSL, indicate your decision | |
15 | by deleting the provisions above and replace them with the notice | |
16 | and other provisions required by the GPL. If you do not delete | |
17 | the provisions above, a recipient may use your version of this | |
18 | file under either the OSL or the GPL. | |
19 | ||
20 | Authors: Alan Cox <alan@redhat.com> | |
21 | ||
22 | This is an example codec plugin. This one switches the connections | |
23 | around to match the setups some vendors use with audio switched to | |
24 | non standard front connectors not the normal rear ones | |
25 | ||
26 | This code primarily exists to demonstrate how to use the codec | |
27 | interface | |
28 | ||
29 | */ | |
30 | ||
31 | #include <linux/config.h> | |
32 | #include <linux/module.h> | |
33 | #include <linux/init.h> | |
34 | #include <linux/kernel.h> | |
35 | #include <linux/ac97_codec.h> | |
36 | ||
37 | /** | |
38 | * ad1980_remove - codec remove callback | |
39 | * @codec: The codec that is being removed | |
40 | * | |
41 | * This callback occurs when an AC97 codec is being removed. A | |
42 | * codec remove call will not occur for a codec during that codec | |
43 | * probe callback. | |
44 | * | |
45 | * Most drivers will need to lock their remove versus their | |
46 | * use of the codec after the probe function. | |
47 | */ | |
48 | ||
49 | static void __devexit ad1980_remove(struct ac97_codec *codec, struct ac97_driver *driver) | |
50 | { | |
51 | /* Nothing to do in the simple example */ | |
52 | } | |
53 | ||
54 | ||
55 | /** | |
56 | * ad1980_probe - codec found callback | |
57 | * @codec: ac97 codec matching the idents | |
58 | * @driver: ac97_driver it matched | |
59 | * | |
60 | * This entry point is called when a codec is found which matches | |
61 | * the driver. At the point it is called the codec is basically | |
62 | * operational, mixer operations have been initialised and can | |
63 | * be overriden. Called in process context. The field driver_private | |
64 | * is available for the driver to use to store stuff. | |
65 | * | |
66 | * The caller can claim the device by returning zero, or return | |
67 | * a negative error code. | |
68 | */ | |
69 | ||
70 | static int ad1980_probe(struct ac97_codec *codec, struct ac97_driver *driver) | |
71 | { | |
72 | u16 control; | |
73 | ||
74 | #define AC97_AD_MISC 0x76 | |
75 | ||
76 | /* Switch the inputs/outputs over (from Dell code) */ | |
77 | control = codec->codec_read(codec, AC97_AD_MISC); | |
78 | codec->codec_write(codec, AC97_AD_MISC, control | 0x4420); | |
79 | ||
80 | /* We could refuse the device since we dont need to hang around, | |
81 | but we will claim it */ | |
82 | return 0; | |
83 | } | |
84 | ||
85 | ||
86 | static struct ac97_driver ad1980_driver = { | |
87 | .codec_id = 0x41445370, | |
88 | .codec_mask = 0xFFFFFFFF, | |
89 | .name = "AD1980 example", | |
90 | .probe = ad1980_probe, | |
91 | .remove = __devexit_p(ad1980_remove), | |
92 | }; | |
93 | ||
94 | /** | |
95 | * ad1980_exit - module exit path | |
96 | * | |
97 | * Our module is being unloaded. At this point unregister_driver | |
98 | * will call back our remove handler for any existing codecs. You | |
99 | * may not unregister_driver from interrupt context or from a | |
100 | * probe/remove callback. | |
101 | */ | |
102 | ||
103 | static void ad1980_exit(void) | |
104 | { | |
105 | ac97_unregister_driver(&ad1980_driver); | |
106 | } | |
107 | ||
108 | /** | |
109 | * ad1980_init - set up ad1980 handlers | |
110 | * | |
111 | * After we call the register function it will call our probe | |
112 | * function for each existing matching device before returning to us. | |
113 | * Any devices appearing afterwards whose id's match the codec_id | |
114 | * will also cause the probe function to be called. | |
115 | * You may not register_driver from interrupt context or from a | |
116 | * probe/remove callback. | |
117 | */ | |
118 | ||
119 | static int ad1980_init(void) | |
120 | { | |
121 | return ac97_register_driver(&ad1980_driver); | |
122 | } | |
123 | ||
124 | module_init(ad1980_init); | |
125 | module_exit(ad1980_exit); | |
126 | MODULE_LICENSE("GPL"); |