root/drivers/media/pci/bt8xx/bttv-audio-hook.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. winview_volume
  2. gvbctv3pci_audio
  3. gvbctv5pci_audio
  4. avermedia_tvphone_audio
  5. avermedia_tv_stereo_audio
  6. lt9415_audio
  7. terratv_audio
  8. winfast2000_audio
  9. pvbt878p9b_audio
  10. fv2000s_audio
  11. windvr_audio
  12. adtvk503_audio

   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 }

/* [<][>][^][v][top][bottom][index][help] */