482 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Handlers for board audio hooks, split from bttv-cards4 *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 else34 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 sap147 *148 * Petr Vandrovec <VANDROVE@vc.cvut.cz>149 * P.S.: At least mask in line above is wrong - GPIO pins 3,2 select150 * 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 tda9840154 *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+NICAM323 * 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 PCI406 * 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-TVK503441 * 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