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