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 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 */ 328 void 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 */ 369 void 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 */ 408 void 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 */ 443 void 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