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
winview_volume(struct bttv * btv,__u16 volume)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
gvbctv3pci_audio(struct bttv * btv,struct v4l2_tuner * t,int set)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
gvbctv5pci_audio(struct bttv * btv,struct v4l2_tuner * t,int set)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
avermedia_tvphone_audio(struct bttv * btv,struct v4l2_tuner * t,int set)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
avermedia_tv_stereo_audio(struct bttv * btv,struct v4l2_tuner * t,int set)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
lt9415_audio(struct bttv * btv,struct v4l2_tuner * t,int set)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 */
terratv_audio(struct bttv * btv,struct v4l2_tuner * t,int set)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
winfast2000_audio(struct bttv * btv,struct v4l2_tuner * t,int set)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 */
pvbt878p9b_audio(struct bttv * btv,struct v4l2_tuner * t,int set)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 */
fv2000s_audio(struct bttv * btv,struct v4l2_tuner * t,int set)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 */
windvr_audio(struct bttv * btv,struct v4l2_tuner * t,int set)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 */
adtvk503_audio(struct bttv * btv,struct v4l2_tuner * t,int set)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 }
383