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