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
15void 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
55void 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
86void 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
157void 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
188void 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
221void 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 */
259void 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
292void 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 */
328void 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 */
369void 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 */
408void 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 */
443void 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}
482