GNU Linux-libre 6.7.9-gnu
[releases.git] / drivers / media / pci / bt8xx / bttv-audio-hook.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Handlers for board audio hooks, split from bttv-cards
4  *
5  * Copyright (c) 2006 Mauro Carvalho Chehab <mchehab@kernel.org>
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;
58
59         if (!set) {
60                 /* Not much to do here */
61                 t->audmode = V4L2_TUNER_MODE_LANG1;
62                 t->rxsubchans = V4L2_TUNER_SUB_MONO |
63                                 V4L2_TUNER_SUB_STEREO |
64                                 V4L2_TUNER_SUB_LANG1 |
65                                 V4L2_TUNER_SUB_LANG2;
66
67                 return;
68         }
69
70         gpio_inout(0x300, 0x300);
71         switch (t->audmode) {
72         case V4L2_TUNER_MODE_LANG1:
73         default:
74                 con = 0x000;
75                 break;
76         case V4L2_TUNER_MODE_LANG2:
77                 con = 0x300;
78                 break;
79         case V4L2_TUNER_MODE_STEREO:
80                 con = 0x200;
81                 break;
82         }
83         gpio_bits(0x300, con);
84 }
85
86 void gvbctv5pci_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
87 {
88         unsigned int val, con;
89
90         if (btv->radio_user)
91                 return;
92
93         val = gpio_read();
94         if (set) {
95                 switch (t->audmode) {
96                 case V4L2_TUNER_MODE_LANG2:
97                         con = 0x300;
98                         break;
99                 case V4L2_TUNER_MODE_LANG1_LANG2:
100                         con = 0x100;
101                         break;
102                 default:
103                         con = 0x000;
104                         break;
105                 }
106                 if (con != (val & 0x300)) {
107                         gpio_bits(0x300, con);
108                         if (bttv_gpio)
109                                 bttv_gpio_tracking(btv, "gvbctv5pci");
110                 }
111         } else {
112                 switch (val & 0x70) {
113                   case 0x10:
114                         t->rxsubchans = V4L2_TUNER_SUB_LANG1 |  V4L2_TUNER_SUB_LANG2;
115                         t->audmode = V4L2_TUNER_MODE_LANG1_LANG2;
116                         break;
117                   case 0x30:
118                         t->rxsubchans = V4L2_TUNER_SUB_LANG2;
119                         t->audmode = V4L2_TUNER_MODE_LANG1_LANG2;
120                         break;
121                   case 0x50:
122                         t->rxsubchans = V4L2_TUNER_SUB_LANG1;
123                         t->audmode = V4L2_TUNER_MODE_LANG1_LANG2;
124                         break;
125                   case 0x60:
126                         t->rxsubchans = V4L2_TUNER_SUB_STEREO;
127                         t->audmode = V4L2_TUNER_MODE_STEREO;
128                         break;
129                   case 0x70:
130                         t->rxsubchans = V4L2_TUNER_SUB_MONO;
131                         t->audmode = V4L2_TUNER_MODE_MONO;
132                         break;
133                   default:
134                         t->rxsubchans = V4L2_TUNER_SUB_MONO |
135                                          V4L2_TUNER_SUB_STEREO |
136                                          V4L2_TUNER_SUB_LANG1 |
137                                          V4L2_TUNER_SUB_LANG2;
138                         t->audmode = V4L2_TUNER_MODE_LANG1;
139                 }
140         }
141 }
142
143 /*
144  * Mario Medina Nussbaum <medisoft@alohabbs.org.mx>
145  *  I discover that on BT848_GPIO_DATA address a byte 0xcce enable stereo,
146  *  0xdde enables mono and 0xccd enables sap
147  *
148  * Petr Vandrovec <VANDROVE@vc.cvut.cz>
149  *  P.S.: At least mask in line above is wrong - GPIO pins 3,2 select
150  *  input/output sound connection, so both must be set for output mode.
151  *
152  * Looks like it's needed only for the "tvphone", the "tvphone 98"
153  * handles this with a tda9840
154  *
155  */
156
157 void avermedia_tvphone_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
158 {
159         int val;
160
161         if (!set) {
162                 /* Not much to do here */
163                 t->audmode = V4L2_TUNER_MODE_LANG1;
164                 t->rxsubchans = V4L2_TUNER_SUB_MONO |
165                                 V4L2_TUNER_SUB_STEREO |
166                                 V4L2_TUNER_SUB_LANG1 |
167                                 V4L2_TUNER_SUB_LANG2;
168
169                 return;
170         }
171
172         switch (t->audmode) {
173         case V4L2_TUNER_MODE_LANG2:   /* SAP */
174                 val = 0x02;
175                 break;
176         case V4L2_TUNER_MODE_STEREO:
177                 val = 0x01;
178                 break;
179         default:
180                 return;
181         }
182         gpio_bits(0x03, val);
183         if (bttv_gpio)
184                 bttv_gpio_tracking(btv, "avermedia");
185 }
186
187
188 void avermedia_tv_stereo_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
189 {
190         int val = 0;
191
192         if (!set) {
193                 /* Not much to do here */
194                 t->audmode = V4L2_TUNER_MODE_LANG1;
195                 t->rxsubchans = V4L2_TUNER_SUB_MONO |
196                                 V4L2_TUNER_SUB_STEREO |
197                                 V4L2_TUNER_SUB_LANG1 |
198                                 V4L2_TUNER_SUB_LANG2;
199
200                 return;
201         }
202
203         switch (t->audmode) {
204         case V4L2_TUNER_MODE_LANG2:   /* SAP */
205                 val = 0x01;
206                 break;
207         case V4L2_TUNER_MODE_STEREO:
208                 val = 0x02;
209                 break;
210         default:
211                 val = 0;
212                 break;
213         }
214         btaor(val, ~0x03, BT848_GPIO_DATA);
215         if (bttv_gpio)
216                 bttv_gpio_tracking(btv, "avermedia");
217 }
218
219 /* Lifetec 9415 handling */
220
221 void lt9415_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
222 {
223         int val = 0;
224
225         if (gpio_read() & 0x4000) {
226                 t->audmode = V4L2_TUNER_MODE_MONO;
227                 return;
228         }
229
230         if (!set) {
231                 /* Not much to do here */
232                 t->audmode = V4L2_TUNER_MODE_LANG1;
233                 t->rxsubchans = V4L2_TUNER_SUB_MONO |
234                                 V4L2_TUNER_SUB_STEREO |
235                                 V4L2_TUNER_SUB_LANG1 |
236                                 V4L2_TUNER_SUB_LANG2;
237
238                 return;
239         }
240
241         switch (t->audmode) {
242         case V4L2_TUNER_MODE_LANG2:     /* A2 SAP */
243                 val = 0x0080;
244                 break;
245         case V4L2_TUNER_MODE_STEREO:    /* A2 stereo */
246                 val = 0x0880;
247                 break;
248         default:
249                 val = 0;
250                 break;
251         }
252
253         gpio_bits(0x0880, val);
254         if (bttv_gpio)
255                 bttv_gpio_tracking(btv, "lt9415");
256 }
257
258 /* TDA9821 on TerraTV+ Bt848, Bt878 */
259 void terratv_audio(struct bttv *btv,  struct v4l2_tuner *t, int set)
260 {
261         unsigned int con = 0;
262
263         if (!set) {
264                 /* Not much to do here */
265                 t->audmode = V4L2_TUNER_MODE_LANG1;
266                 t->rxsubchans = V4L2_TUNER_SUB_MONO |
267                                 V4L2_TUNER_SUB_STEREO |
268                                 V4L2_TUNER_SUB_LANG1 |
269                                 V4L2_TUNER_SUB_LANG2;
270
271                 return;
272         }
273
274         gpio_inout(0x180000, 0x180000);
275         switch (t->audmode) {
276         case V4L2_TUNER_MODE_LANG2:
277                 con = 0x080000;
278                 break;
279         case V4L2_TUNER_MODE_STEREO:
280                 con = 0x180000;
281                 break;
282         default:
283                 con = 0;
284                 break;
285         }
286         gpio_bits(0x180000, con);
287         if (bttv_gpio)
288                 bttv_gpio_tracking(btv, "terratv");
289 }
290
291
292 void winfast2000_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
293 {
294         unsigned long val;
295
296         if (!set)
297                 return;
298
299         /*btor (0xc32000, BT848_GPIO_OUT_EN);*/
300         switch (t->audmode) {
301         case V4L2_TUNER_MODE_MONO:
302         case V4L2_TUNER_MODE_LANG1:
303                 val = 0x420000;
304                 break;
305         case V4L2_TUNER_MODE_LANG2: /* SAP */
306                 val = 0x410000;
307                 break;
308         case V4L2_TUNER_MODE_STEREO:
309                 val = 0x020000;
310                 break;
311         default:
312                 return;
313         }
314
315         gpio_bits(0x430000, val);
316         if (bttv_gpio)
317                 bttv_gpio_tracking(btv, "winfast2000");
318 }
319
320 /*
321  * Dariusz Kowalewski <darekk@automex.pl>
322  * sound control for Prolink PV-BT878P+9B (PixelView PlayTV Pro FM+NICAM
323  * revision 9B has on-board TDA9874A sound decoder).
324  *
325  * Note: There are card variants without tda9874a. Forcing the "stereo sound route"
326  *       will mute this cards.
327  */
328 void pvbt878p9b_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
329 {
330         unsigned int val = 0;
331
332         if (btv->radio_user)
333                 return;
334
335         if (!set) {
336                 /* Not much to do here */
337                 t->audmode = V4L2_TUNER_MODE_LANG1;
338                 t->rxsubchans = V4L2_TUNER_SUB_MONO |
339                                 V4L2_TUNER_SUB_STEREO |
340                                 V4L2_TUNER_SUB_LANG1 |
341                                 V4L2_TUNER_SUB_LANG2;
342
343                 return;
344         }
345
346         switch (t->audmode) {
347         case V4L2_TUNER_MODE_MONO:
348                 val = 0x01;
349                 break;
350         case V4L2_TUNER_MODE_LANG1:
351         case V4L2_TUNER_MODE_LANG2:
352         case V4L2_TUNER_MODE_STEREO:
353                 val = 0x02;
354                 break;
355         default:
356                 return;
357         }
358
359         gpio_bits(0x03, val);
360         if (bttv_gpio)
361                 bttv_gpio_tracking(btv, "pvbt878p9b");
362 }
363
364 /*
365  * Dariusz Kowalewski <darekk@automex.pl>
366  * sound control for FlyVideo 2000S (with tda9874 decoder)
367  * based on pvbt878p9b_audio() - this is not tested, please fix!!!
368  */
369 void fv2000s_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
370 {
371         unsigned int val;
372
373         if (btv->radio_user)
374                 return;
375
376         if (!set) {
377                 /* Not much to do here */
378                 t->audmode = V4L2_TUNER_MODE_LANG1;
379                 t->rxsubchans = V4L2_TUNER_SUB_MONO |
380                                 V4L2_TUNER_SUB_STEREO |
381                                 V4L2_TUNER_SUB_LANG1 |
382                                 V4L2_TUNER_SUB_LANG2;
383
384                 return;
385         }
386
387         switch (t->audmode) {
388         case V4L2_TUNER_MODE_MONO:
389                 val = 0x0000;
390                 break;
391         case V4L2_TUNER_MODE_LANG1:
392         case V4L2_TUNER_MODE_LANG2:
393         case V4L2_TUNER_MODE_STEREO:
394                 val = 0x1080; /*-dk-???: 0x0880, 0x0080, 0x1800 ... */
395                 break;
396         default:
397                 return;
398         }
399         gpio_bits(0x1800, val);
400         if (bttv_gpio)
401                 bttv_gpio_tracking(btv, "fv2000s");
402 }
403
404 /*
405  * sound control for Canopus WinDVR PCI
406  * Masaki Suzuki <masaki@btree.org>
407  */
408 void windvr_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
409 {
410         unsigned long val;
411
412         if (!set) {
413                 /* Not much to do here */
414                 t->audmode = V4L2_TUNER_MODE_LANG1;
415                 t->rxsubchans = V4L2_TUNER_SUB_MONO |
416                                 V4L2_TUNER_SUB_STEREO |
417                                 V4L2_TUNER_SUB_LANG1 |
418                                 V4L2_TUNER_SUB_LANG2;
419
420                 return;
421         }
422
423         switch (t->audmode) {
424         case V4L2_TUNER_MODE_MONO:
425                 val = 0x040000;
426                 break;
427         case V4L2_TUNER_MODE_LANG2:
428                 val = 0x100000;
429                 break;
430         default:
431                 return;
432         }
433
434         gpio_bits(0x140000, val);
435         if (bttv_gpio)
436                 bttv_gpio_tracking(btv, "windvr");
437 }
438
439 /*
440  * sound control for AD-TVK503
441  * Hiroshi Takekawa <sian@big.or.jp>
442  */
443 void adtvk503_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
444 {
445         unsigned int con = 0xffffff;
446
447         /* btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN); */
448
449         if (!set) {
450                 /* Not much to do here */
451                 t->audmode = V4L2_TUNER_MODE_LANG1;
452                 t->rxsubchans = V4L2_TUNER_SUB_MONO |
453                                 V4L2_TUNER_SUB_STEREO |
454                                 V4L2_TUNER_SUB_LANG1 |
455                                 V4L2_TUNER_SUB_LANG2;
456
457                 return;
458         }
459
460         /* btor(***, BT848_GPIO_OUT_EN); */
461         switch (t->audmode) {
462         case V4L2_TUNER_MODE_LANG1:
463                 con = 0x00000000;
464                 break;
465         case V4L2_TUNER_MODE_LANG2:
466                 con = 0x00180000;
467                 break;
468         case V4L2_TUNER_MODE_STEREO:
469                 con = 0x00000000;
470                 break;
471         case V4L2_TUNER_MODE_MONO:
472                 con = 0x00060000;
473                 break;
474         default:
475                 return;
476         }
477
478         gpio_bits(0x1e0000, con);
479         if (bttv_gpio)
480                 bttv_gpio_tracking(btv, "adtvk503");
481 }