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 /* Not much to do here */ 298 t->audmode = V4L2_TUNER_MODE_LANG1; 299 t->rxsubchans = V4L2_TUNER_SUB_MONO | 300 V4L2_TUNER_SUB_STEREO | 301 V4L2_TUNER_SUB_LANG1 | 302 V4L2_TUNER_SUB_LANG2; 303 304 return; 305 } 306 307 /*btor (0xc32000, BT848_GPIO_OUT_EN);*/ 308 switch (t->audmode) { 309 case V4L2_TUNER_MODE_MONO: 310 case V4L2_TUNER_MODE_LANG1: 311 val = 0x420000; 312 break; 313 case V4L2_TUNER_MODE_LANG2: /* SAP */ 314 val = 0x410000; 315 break; 316 case V4L2_TUNER_MODE_STEREO: 317 val = 0x020000; 318 break; 319 default: 320 return; 321 } 322 323 gpio_bits(0x430000, val); 324 if (bttv_gpio) 325 bttv_gpio_tracking(btv, "winfast2000"); 326 } 327 328 /* 329 * Dariusz Kowalewski <darekk@automex.pl> 330 * sound control for Prolink PV-BT878P+9B (PixelView PlayTV Pro FM+NICAM 331 * revision 9B has on-board TDA9874A sound decoder). 332 * 333 * Note: There are card variants without tda9874a. Forcing the "stereo sound route" 334 * will mute this cards. 335 */ 336 void pvbt878p9b_audio(struct bttv *btv, struct v4l2_tuner *t, int set) 337 { 338 unsigned int val = 0; 339 340 if (btv->radio_user) 341 return; 342 343 if (!set) { 344 /* Not much to do here */ 345 t->audmode = V4L2_TUNER_MODE_LANG1; 346 t->rxsubchans = V4L2_TUNER_SUB_MONO | 347 V4L2_TUNER_SUB_STEREO | 348 V4L2_TUNER_SUB_LANG1 | 349 V4L2_TUNER_SUB_LANG2; 350 351 return; 352 } 353 354 switch (t->audmode) { 355 case V4L2_TUNER_MODE_MONO: 356 val = 0x01; 357 break; 358 case V4L2_TUNER_MODE_LANG1: 359 case V4L2_TUNER_MODE_LANG2: 360 case V4L2_TUNER_MODE_STEREO: 361 val = 0x02; 362 break; 363 default: 364 return; 365 } 366 367 gpio_bits(0x03, val); 368 if (bttv_gpio) 369 bttv_gpio_tracking(btv, "pvbt878p9b"); 370 } 371 372 /* 373 * Dariusz Kowalewski <darekk@automex.pl> 374 * sound control for FlyVideo 2000S (with tda9874 decoder) 375 * based on pvbt878p9b_audio() - this is not tested, please fix!!! 376 */ 377 void fv2000s_audio(struct bttv *btv, struct v4l2_tuner *t, int set) 378 { 379 unsigned int val; 380 381 if (btv->radio_user) 382 return; 383 384 if (!set) { 385 /* Not much to do here */ 386 t->audmode = V4L2_TUNER_MODE_LANG1; 387 t->rxsubchans = V4L2_TUNER_SUB_MONO | 388 V4L2_TUNER_SUB_STEREO | 389 V4L2_TUNER_SUB_LANG1 | 390 V4L2_TUNER_SUB_LANG2; 391 392 return; 393 } 394 395 switch (t->audmode) { 396 case V4L2_TUNER_MODE_MONO: 397 val = 0x0000; 398 break; 399 case V4L2_TUNER_MODE_LANG1: 400 case V4L2_TUNER_MODE_LANG2: 401 case V4L2_TUNER_MODE_STEREO: 402 val = 0x1080; /*-dk-???: 0x0880, 0x0080, 0x1800 ... */ 403 break; 404 default: 405 return; 406 } 407 gpio_bits(0x1800, val); 408 if (bttv_gpio) 409 bttv_gpio_tracking(btv, "fv2000s"); 410 } 411 412 /* 413 * sound control for Canopus WinDVR PCI 414 * Masaki Suzuki <masaki@btree.org> 415 */ 416 void windvr_audio(struct bttv *btv, struct v4l2_tuner *t, int set) 417 { 418 unsigned long val; 419 420 if (!set) { 421 /* Not much to do here */ 422 t->audmode = V4L2_TUNER_MODE_LANG1; 423 t->rxsubchans = V4L2_TUNER_SUB_MONO | 424 V4L2_TUNER_SUB_STEREO | 425 V4L2_TUNER_SUB_LANG1 | 426 V4L2_TUNER_SUB_LANG2; 427 428 return; 429 } 430 431 switch (t->audmode) { 432 case V4L2_TUNER_MODE_MONO: 433 val = 0x040000; 434 break; 435 case V4L2_TUNER_MODE_LANG2: 436 val = 0x100000; 437 break; 438 default: 439 return; 440 } 441 442 gpio_bits(0x140000, val); 443 if (bttv_gpio) 444 bttv_gpio_tracking(btv, "windvr"); 445 } 446 447 /* 448 * sound control for AD-TVK503 449 * Hiroshi Takekawa <sian@big.or.jp> 450 */ 451 void adtvk503_audio(struct bttv *btv, struct v4l2_tuner *t, int set) 452 { 453 unsigned int con = 0xffffff; 454 455 /* btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN); */ 456 457 if (!set) { 458 /* Not much to do here */ 459 t->audmode = V4L2_TUNER_MODE_LANG1; 460 t->rxsubchans = V4L2_TUNER_SUB_MONO | 461 V4L2_TUNER_SUB_STEREO | 462 V4L2_TUNER_SUB_LANG1 | 463 V4L2_TUNER_SUB_LANG2; 464 465 return; 466 } 467 468 /* btor(***, BT848_GPIO_OUT_EN); */ 469 switch (t->audmode) { 470 case V4L2_TUNER_MODE_LANG1: 471 con = 0x00000000; 472 break; 473 case V4L2_TUNER_MODE_LANG2: 474 con = 0x00180000; 475 break; 476 case V4L2_TUNER_MODE_STEREO: 477 con = 0x00000000; 478 break; 479 case V4L2_TUNER_MODE_MONO: 480 con = 0x00060000; 481 break; 482 default: 483 return; 484 } 485 486 gpio_bits(0x1e0000, con); 487 if (bttv_gpio) 488 bttv_gpio_tracking(btv, "adtvk503"); 489 } 490