]> err.no Git - linux-2.6/blob - drivers/media/video/bt8xx/bttv-audio-hook.c
V4L/DVB (6415): Restructurize volume hook and drop unused mute hook
[linux-2.6] / drivers / media / video / bt8xx / bttv-audio-hook.c
1 /*
2  * Handlers for board audio hooks, splitted from bttv-cards
3  *
4  * Copyright (c) 2006 Mauro Carvalho Chehab (mchehab@infradead.org)
5  * This code is placed under the terms of the GNU General Public License
6  */
7
8 #include "bttv-audio-hook.h"
9
10 /* ----------------------------------------------------------------------- */
11 /* winview                                                                 */
12
13  void winview_audio(struct bttv *btv, struct video_audio *v, int set)
14 {
15         /* PT2254A programming Jon Tombs, jon@gte.esi.us.es */
16         int bits_out, loops, vol, data;
17
18         if (!set) {
19                 /* Fixed by Leandro Lucarella <luca@linuxmendoza.org.ar (07/31/01) */
20                 v->flags |= VIDEO_AUDIO_VOLUME;
21                 return;
22         }
23
24         /* 32 levels logarithmic */
25         vol = 32 - ((v->volume>>11));
26         /* units */
27         bits_out = (PT2254_DBS_IN_2>>(vol%5));
28         /* tens */
29         bits_out |= (PT2254_DBS_IN_10>>(vol/5));
30         bits_out |= PT2254_L_CHANNEL | PT2254_R_CHANNEL;
31         data = gpio_read();
32         data &= ~(WINVIEW_PT2254_CLK| WINVIEW_PT2254_DATA|
33                   WINVIEW_PT2254_STROBE);
34         for (loops = 17; loops >= 0 ; loops--) {
35                 if (bits_out & (1<<loops))
36                         data |=  WINVIEW_PT2254_DATA;
37                 else
38                         data &= ~WINVIEW_PT2254_DATA;
39                 gpio_write(data);
40                 udelay(5);
41                 data |= WINVIEW_PT2254_CLK;
42                 gpio_write(data);
43                 udelay(5);
44                 data &= ~WINVIEW_PT2254_CLK;
45                 gpio_write(data);
46         }
47         data |=  WINVIEW_PT2254_STROBE;
48         data &= ~WINVIEW_PT2254_DATA;
49         gpio_write(data);
50         udelay(10);
51         data &= ~WINVIEW_PT2254_STROBE;
52         gpio_write(data);
53 }
54
55 /* ----------------------------------------------------------------------- */
56 /* mono/stereo control for various cards (which don't use i2c chips but    */
57 /* connect something to the GPIO pins                                      */
58
59  void
60 gvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set)
61 {
62         unsigned int con = 0;
63
64         if (set) {
65                 gpio_inout(0x300, 0x300);
66                 if (v->mode & VIDEO_SOUND_LANG1)
67                         con = 0x000;
68                 if (v->mode & VIDEO_SOUND_LANG2)
69                         con = 0x300;
70                 if (v->mode & VIDEO_SOUND_STEREO)
71                         con = 0x200;
72 /*              if (v->mode & VIDEO_SOUND_MONO)
73  *                      con = 0x100; */
74                 gpio_bits(0x300, con);
75         } else {
76                 v->mode = VIDEO_SOUND_STEREO |
77                           VIDEO_SOUND_LANG1  | VIDEO_SOUND_LANG2;
78         }
79 }
80
81  void
82 gvbctv5pci_audio(struct bttv *btv, struct video_audio *v, int set)
83 {
84         unsigned int val, con;
85
86         if (btv->radio_user)
87                 return;
88
89         val = gpio_read();
90         if (set) {
91                 con = 0x000;
92                 if (v->mode & VIDEO_SOUND_LANG2) {
93                         if (v->mode & VIDEO_SOUND_LANG1) {
94                                 /* LANG1 + LANG2 */
95                                 con = 0x100;
96                         }
97                         else {
98                                 /* LANG2 */
99                                 con = 0x300;
100                         }
101                 }
102                 if (con != (val & 0x300)) {
103                         gpio_bits(0x300, con);
104                         if (bttv_gpio)
105                                 bttv_gpio_tracking(btv,"gvbctv5pci");
106                 }
107         } else {
108                 switch (val & 0x70) {
109                   case 0x10:
110                         v->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
111                         break;
112                   case 0x30:
113                         v->mode = VIDEO_SOUND_LANG2;
114                         break;
115                   case 0x50:
116                         v->mode = VIDEO_SOUND_LANG1;
117                         break;
118                   case 0x60:
119                         v->mode = VIDEO_SOUND_STEREO;
120                         break;
121                   case 0x70:
122                         v->mode = VIDEO_SOUND_MONO;
123                         break;
124                   default:
125                         v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
126                                   VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
127                 }
128         }
129 }
130
131 /*
132  * Mario Medina Nussbaum <medisoft@alohabbs.org.mx>
133  *  I discover that on BT848_GPIO_DATA address a byte 0xcce enable stereo,
134  *  0xdde enables mono and 0xccd enables sap
135  *
136  * Petr Vandrovec <VANDROVE@vc.cvut.cz>
137  *  P.S.: At least mask in line above is wrong - GPIO pins 3,2 select
138  *  input/output sound connection, so both must be set for output mode.
139  *
140  * Looks like it's needed only for the "tvphone", the "tvphone 98"
141  * handles this with a tda9840
142  *
143  */
144  void
145 avermedia_tvphone_audio(struct bttv *btv, struct video_audio *v, int set)
146 {
147         int val = 0;
148
149         if (set) {
150                 if (v->mode & VIDEO_SOUND_LANG2)   /* SAP */
151                         val = 0x02;
152                 if (v->mode & VIDEO_SOUND_STEREO)
153                         val = 0x01;
154                 if (val) {
155                         gpio_bits(0x03,val);
156                         if (bttv_gpio)
157                                 bttv_gpio_tracking(btv,"avermedia");
158                 }
159         } else {
160                 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
161                         VIDEO_SOUND_LANG1;
162                 return;
163         }
164 }
165
166  void
167 avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v, int set)
168 {
169         int val = 0;
170
171         if (set) {
172                 if (v->mode & VIDEO_SOUND_LANG2)   /* SAP */
173                         val = 0x01;
174                 if (v->mode & VIDEO_SOUND_STEREO)  /* STEREO */
175                         val = 0x02;
176                 btaor(val, ~0x03, BT848_GPIO_DATA);
177                 if (bttv_gpio)
178                         bttv_gpio_tracking(btv,"avermedia");
179         } else {
180                 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
181                         VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
182                 return;
183         }
184 }
185
186 /* Lifetec 9415 handling */
187  void
188 lt9415_audio(struct bttv *btv, struct video_audio *v, int set)
189 {
190         int val = 0;
191
192         if (gpio_read() & 0x4000) {
193                 v->mode = VIDEO_SOUND_MONO;
194                 return;
195         }
196
197         if (set) {
198                 if (v->mode & VIDEO_SOUND_LANG2)  /* A2 SAP */
199                         val = 0x0080;
200                 if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */
201                         val = 0x0880;
202                 if ((v->mode & VIDEO_SOUND_LANG1) ||
203                     (v->mode & VIDEO_SOUND_MONO))
204                         val = 0;
205                 gpio_bits(0x0880, val);
206                 if (bttv_gpio)
207                         bttv_gpio_tracking(btv,"lt9415");
208         } else {
209                 /* autodetect doesn't work with this card :-( */
210                 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
211                         VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
212                 return;
213         }
214 }
215
216 /* TDA9821 on TerraTV+ Bt848, Bt878 */
217  void
218 terratv_audio(struct bttv *btv, struct video_audio *v, int set)
219 {
220         unsigned int con = 0;
221
222         if (set) {
223                 gpio_inout(0x180000,0x180000);
224                 if (v->mode & VIDEO_SOUND_LANG2)
225                         con = 0x080000;
226                 if (v->mode & VIDEO_SOUND_STEREO)
227                         con = 0x180000;
228                 gpio_bits(0x180000, con);
229                 if (bttv_gpio)
230                         bttv_gpio_tracking(btv,"terratv");
231         } else {
232                 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
233                         VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
234         }
235 }
236
237  void
238 winfast2000_audio(struct bttv *btv, struct video_audio *v, int set)
239 {
240         unsigned long val = 0;
241
242         if (set) {
243                 /*btor (0xc32000, BT848_GPIO_OUT_EN);*/
244                 if (v->mode & VIDEO_SOUND_MONO)         /* Mono */
245                         val = 0x420000;
246                 if (v->mode & VIDEO_SOUND_LANG1)        /* Mono */
247                         val = 0x420000;
248                 if (v->mode & VIDEO_SOUND_LANG2)        /* SAP */
249                         val = 0x410000;
250                 if (v->mode & VIDEO_SOUND_STEREO)       /* Stereo */
251                         val = 0x020000;
252                 if (val) {
253                         gpio_bits(0x430000, val);
254                         if (bttv_gpio)
255                                 bttv_gpio_tracking(btv,"winfast2000");
256                 }
257         } else {
258                 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
259                           VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
260         }
261 }
262
263 /*
264  * Dariusz Kowalewski <darekk@automex.pl>
265  * sound control for Prolink PV-BT878P+9B (PixelView PlayTV Pro FM+NICAM
266  * revision 9B has on-board TDA9874A sound decoder).
267  *
268  * Note: There are card variants without tda9874a. Forcing the "stereo sound route"
269  *       will mute this cards.
270  */
271  void
272 pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set)
273 {
274         unsigned int val = 0;
275
276         if (btv->radio_user)
277                 return;
278
279         if (set) {
280                 if (v->mode & VIDEO_SOUND_MONO) {
281                         val = 0x01;
282                 }
283                 if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2))
284                     || (v->mode & VIDEO_SOUND_STEREO)) {
285                         val = 0x02;
286                 }
287                 if (val) {
288                         gpio_bits(0x03,val);
289                         if (bttv_gpio)
290                                 bttv_gpio_tracking(btv,"pvbt878p9b");
291                 }
292         } else {
293                 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
294                         VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
295         }
296 }
297
298 /*
299  * Dariusz Kowalewski <darekk@automex.pl>
300  * sound control for FlyVideo 2000S (with tda9874 decoder)
301  * based on pvbt878p9b_audio() - this is not tested, please fix!!!
302  */
303  void
304 fv2000s_audio(struct bttv *btv, struct video_audio *v, int set)
305 {
306         unsigned int val = 0xffff;
307
308         if (btv->radio_user)
309                 return;
310
311         if (set) {
312                 if (v->mode & VIDEO_SOUND_MONO) {
313                         val = 0x0000;
314                 }
315                 if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2))
316                     || (v->mode & VIDEO_SOUND_STEREO)) {
317                         val = 0x1080; /*-dk-???: 0x0880, 0x0080, 0x1800 ... */
318                 }
319                 if (val != 0xffff) {
320                         gpio_bits(0x1800, val);
321                         if (bttv_gpio)
322                                 bttv_gpio_tracking(btv,"fv2000s");
323                 }
324         } else {
325                 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
326                         VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
327         }
328 }
329
330 /*
331  * sound control for Canopus WinDVR PCI
332  * Masaki Suzuki <masaki@btree.org>
333  */
334  void
335 windvr_audio(struct bttv *btv, struct video_audio *v, int set)
336 {
337         unsigned long val = 0;
338
339         if (set) {
340                 if (v->mode & VIDEO_SOUND_MONO)
341                         val = 0x040000;
342                 if (v->mode & VIDEO_SOUND_LANG1)
343                         val = 0;
344                 if (v->mode & VIDEO_SOUND_LANG2)
345                         val = 0x100000;
346                 if (v->mode & VIDEO_SOUND_STEREO)
347                         val = 0;
348                 if (val) {
349                         gpio_bits(0x140000, val);
350                         if (bttv_gpio)
351                                 bttv_gpio_tracking(btv,"windvr");
352                 }
353         } else {
354                 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
355                           VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
356         }
357 }
358
359 /*
360  * sound control for AD-TVK503
361  * Hiroshi Takekawa <sian@big.or.jp>
362  */
363  void
364 adtvk503_audio(struct bttv *btv, struct video_audio *v, int set)
365 {
366         unsigned int con = 0xffffff;
367
368         /* btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN); */
369
370         if (set) {
371                 /* btor(***, BT848_GPIO_OUT_EN); */
372                 if (v->mode & VIDEO_SOUND_LANG1)
373                         con = 0x00000000;
374                 if (v->mode & VIDEO_SOUND_LANG2)
375                         con = 0x00180000;
376                 if (v->mode & VIDEO_SOUND_STEREO)
377                         con = 0x00000000;
378                 if (v->mode & VIDEO_SOUND_MONO)
379                         con = 0x00060000;
380                 if (con != 0xffffff) {
381                         gpio_bits(0x1e0000,con);
382                         if (bttv_gpio)
383                                 bttv_gpio_tracking(btv, "adtvk503");
384                 }
385         } else {
386                 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
387                           VIDEO_SOUND_LANG1  | VIDEO_SOUND_LANG2;
388         }
389 }