linux/drivers/media/pci/bt8xx/bttv-audio-hook.c
<<
>>
Prefs
   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                /* 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 */
 336void 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 */
 377void 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 */
 416void 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 */
 451void 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