File Index
Files and directories
Sign in
FILE

bttv-audio-hook.c

File preview with syntax highlighting.

linux-6.19.14/drivers/media/pci/bt8xx/bttv-audio-hook.c 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
 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}
~/ Read-only file preview.