linux/drivers/media/video/bt8xx/bttv-audio-hook.c
<<
>>
Prefs
   1/*
   2 * Handlers for board audio hooks, splitted from bttv-cards
   3 *
   4 * Copyright (c) 2006 Mauro Carvalho Chehab (mchehab@infradead.org)
   5 * This code is placed under the terms of the GNU General Public License
   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 = 0;
  58
  59        if (set) {
  60                gpio_inout(0x300, 0x300);
  61                if (t->audmode & V4L2_TUNER_MODE_LANG1)
  62                        con = 0x000;
  63                if (t->audmode & V4L2_TUNER_MODE_LANG2)
  64                        con = 0x300;
  65                if (t->audmode & V4L2_TUNER_MODE_STEREO)
  66                        con = 0x200;
  67/*              if (t->audmode & V4L2_TUNER_MODE_MONO)
  68 *                      con = 0x100; */
  69                gpio_bits(0x300, con);
  70        } else {
  71                t->audmode = V4L2_TUNER_MODE_STEREO |
  72                          V4L2_TUNER_MODE_LANG1  | V4L2_TUNER_MODE_LANG2;
  73        }
  74}
  75
  76void gvbctv5pci_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
  77{
  78        unsigned int val, con;
  79
  80        if (btv->radio_user)
  81                return;
  82
  83        val = gpio_read();
  84        if (set) {
  85                con = 0x000;
  86                if (t->audmode & V4L2_TUNER_MODE_LANG2) {
  87                        if (t->audmode & V4L2_TUNER_MODE_LANG1) {
  88                                /* LANG1 + LANG2 */
  89                                con = 0x100;
  90                        }
  91                        else {
  92                                /* LANG2 */
  93                                con = 0x300;
  94                        }
  95                }
  96                if (con != (val & 0x300)) {
  97                        gpio_bits(0x300, con);
  98                        if (bttv_gpio)
  99                                bttv_gpio_tracking(btv,"gvbctv5pci");
 100                }
 101        } else {
 102                switch (val & 0x70) {
 103                  case 0x10:
 104                        t->rxsubchans = V4L2_TUNER_SUB_LANG1 |  V4L2_TUNER_SUB_LANG2;
 105                        break;
 106                  case 0x30:
 107                        t->rxsubchans = V4L2_TUNER_SUB_LANG2;
 108                        break;
 109                  case 0x50:
 110                        t->rxsubchans = V4L2_TUNER_SUB_LANG1;
 111                        break;
 112                  case 0x60:
 113                        t->rxsubchans = V4L2_TUNER_SUB_STEREO;
 114                        break;
 115                  case 0x70:
 116                        t->rxsubchans = V4L2_TUNER_SUB_MONO;
 117                        break;
 118                  default:
 119                        t->rxsubchans = V4L2_TUNER_SUB_MONO |
 120                                         V4L2_TUNER_SUB_STEREO |
 121                                         V4L2_TUNER_SUB_LANG1 |
 122                                         V4L2_TUNER_SUB_LANG2;
 123                }
 124                t->audmode = V4L2_TUNER_MODE_STEREO |
 125                          V4L2_TUNER_MODE_LANG1  | V4L2_TUNER_MODE_LANG2;
 126        }
 127}
 128
 129/*
 130 * Mario Medina Nussbaum <medisoft@alohabbs.org.mx>
 131 *  I discover that on BT848_GPIO_DATA address a byte 0xcce enable stereo,
 132 *  0xdde enables mono and 0xccd enables sap
 133 *
 134 * Petr Vandrovec <VANDROVE@vc.cvut.cz>
 135 *  P.S.: At least mask in line above is wrong - GPIO pins 3,2 select
 136 *  input/output sound connection, so both must be set for output mode.
 137 *
 138 * Looks like it's needed only for the "tvphone", the "tvphone 98"
 139 * handles this with a tda9840
 140 *
 141 */
 142
 143void avermedia_tvphone_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
 144{
 145        int val = 0;
 146
 147        if (set) {
 148                if (t->audmode & V4L2_TUNER_MODE_LANG2)   /* SAP */
 149                        val = 0x02;
 150                if (t->audmode & V4L2_TUNER_MODE_STEREO)
 151                        val = 0x01;
 152                if (val) {
 153                        gpio_bits(0x03,val);
 154                        if (bttv_gpio)
 155                                bttv_gpio_tracking(btv,"avermedia");
 156                }
 157        } else {
 158                t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
 159                        V4L2_TUNER_MODE_LANG1;
 160                return;
 161        }
 162}
 163
 164
 165void avermedia_tv_stereo_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
 166{
 167        int val = 0;
 168
 169        if (set) {
 170                if (t->audmode & V4L2_TUNER_MODE_LANG2)   /* SAP */
 171                        val = 0x01;
 172                if (t->audmode & V4L2_TUNER_MODE_STEREO)  /* STEREO */
 173                        val = 0x02;
 174                btaor(val, ~0x03, BT848_GPIO_DATA);
 175                if (bttv_gpio)
 176                        bttv_gpio_tracking(btv,"avermedia");
 177        } else {
 178                t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
 179                        V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
 180                return;
 181        }
 182}
 183
 184/* Lifetec 9415 handling */
 185
 186void lt9415_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
 187{
 188        int val = 0;
 189
 190        if (gpio_read() & 0x4000) {
 191                t->audmode = V4L2_TUNER_MODE_MONO;
 192                return;
 193        }
 194
 195        if (set) {
 196                if (t->audmode & V4L2_TUNER_MODE_LANG2)  /* A2 SAP */
 197                        val = 0x0080;
 198                if (t->audmode & V4L2_TUNER_MODE_STEREO) /* A2 stereo */
 199                        val = 0x0880;
 200                if ((t->audmode & V4L2_TUNER_MODE_LANG1) ||
 201                    (t->audmode & V4L2_TUNER_MODE_MONO))
 202                        val = 0;
 203                gpio_bits(0x0880, val);
 204                if (bttv_gpio)
 205                        bttv_gpio_tracking(btv,"lt9415");
 206        } else {
 207                /* autodetect doesn't work with this card :-( */
 208                t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
 209                        V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
 210                return;
 211        }
 212}
 213
 214/* TDA9821 on TerraTV+ Bt848, Bt878 */
 215void terratv_audio(struct bttv *btv,  struct v4l2_tuner *t, int set)
 216{
 217        unsigned int con = 0;
 218
 219        if (set) {
 220                gpio_inout(0x180000,0x180000);
 221                if (t->audmode & V4L2_TUNER_MODE_LANG2)
 222                        con = 0x080000;
 223                if (t->audmode & V4L2_TUNER_MODE_STEREO)
 224                        con = 0x180000;
 225                gpio_bits(0x180000, con);
 226                if (bttv_gpio)
 227                        bttv_gpio_tracking(btv,"terratv");
 228        } else {
 229                t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
 230                        V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
 231        }
 232}
 233
 234
 235void winfast2000_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
 236{
 237        unsigned long val = 0;
 238
 239        if (set) {
 240                /*btor (0xc32000, BT848_GPIO_OUT_EN);*/
 241                if (t->audmode & V4L2_TUNER_MODE_MONO)          /* Mono */
 242                        val = 0x420000;
 243                if (t->audmode & V4L2_TUNER_MODE_LANG1) /* Mono */
 244                        val = 0x420000;
 245                if (t->audmode & V4L2_TUNER_MODE_LANG2) /* SAP */
 246                        val = 0x410000;
 247                if (t->audmode & V4L2_TUNER_MODE_STEREO)        /* Stereo */
 248                        val = 0x020000;
 249                if (val) {
 250                        gpio_bits(0x430000, val);
 251                        if (bttv_gpio)
 252                                bttv_gpio_tracking(btv,"winfast2000");
 253                }
 254        } else {
 255                t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
 256                          V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
 257        }
 258}
 259
 260/*
 261 * Dariusz Kowalewski <darekk@automex.pl>
 262 * sound control for Prolink PV-BT878P+9B (PixelView PlayTV Pro FM+NICAM
 263 * revision 9B has on-board TDA9874A sound decoder).
 264 *
 265 * Note: There are card variants without tda9874a. Forcing the "stereo sound route"
 266 *       will mute this cards.
 267 */
 268void pvbt878p9b_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
 269{
 270        unsigned int val = 0;
 271
 272        if (btv->radio_user)
 273                return;
 274
 275        if (set) {
 276                if (t->audmode & V4L2_TUNER_MODE_MONO)  {
 277                        val = 0x01;
 278                }
 279                if ((t->audmode & (V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2))
 280                    || (t->audmode & V4L2_TUNER_MODE_STEREO)) {
 281                        val = 0x02;
 282                }
 283                if (val) {
 284                        gpio_bits(0x03,val);
 285                        if (bttv_gpio)
 286                                bttv_gpio_tracking(btv,"pvbt878p9b");
 287                }
 288        } else {
 289                t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
 290                        V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
 291        }
 292}
 293
 294/*
 295 * Dariusz Kowalewski <darekk@automex.pl>
 296 * sound control for FlyVideo 2000S (with tda9874 decoder)
 297 * based on pvbt878p9b_audio() - this is not tested, please fix!!!
 298 */
 299void fv2000s_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
 300{
 301        unsigned int val = 0xffff;
 302
 303        if (btv->radio_user)
 304                return;
 305
 306        if (set) {
 307                if (t->audmode & V4L2_TUNER_MODE_MONO)  {
 308                        val = 0x0000;
 309                }
 310                if ((t->audmode & (V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2))
 311                    || (t->audmode & V4L2_TUNER_MODE_STEREO)) {
 312                        val = 0x1080; /*-dk-???: 0x0880, 0x0080, 0x1800 ... */
 313                }
 314                if (val != 0xffff) {
 315                        gpio_bits(0x1800, val);
 316                        if (bttv_gpio)
 317                                bttv_gpio_tracking(btv,"fv2000s");
 318                }
 319        } else {
 320                t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
 321                        V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
 322        }
 323}
 324
 325/*
 326 * sound control for Canopus WinDVR PCI
 327 * Masaki Suzuki <masaki@btree.org>
 328 */
 329void windvr_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
 330{
 331        unsigned long val = 0;
 332
 333        if (set) {
 334                if (t->audmode & V4L2_TUNER_MODE_MONO)
 335                        val = 0x040000;
 336                if (t->audmode & V4L2_TUNER_MODE_LANG1)
 337                        val = 0;
 338                if (t->audmode & V4L2_TUNER_MODE_LANG2)
 339                        val = 0x100000;
 340                if (t->audmode & V4L2_TUNER_MODE_STEREO)
 341                        val = 0;
 342                if (val) {
 343                        gpio_bits(0x140000, val);
 344                        if (bttv_gpio)
 345                                bttv_gpio_tracking(btv,"windvr");
 346                }
 347        } else {
 348                t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
 349                          V4L2_TUNER_MODE_LANG1 | V4L2_TUNER_MODE_LANG2;
 350        }
 351}
 352
 353/*
 354 * sound control for AD-TVK503
 355 * Hiroshi Takekawa <sian@big.or.jp>
 356 */
 357void adtvk503_audio(struct bttv *btv, struct v4l2_tuner *t, int set)
 358{
 359        unsigned int con = 0xffffff;
 360
 361        /* btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN); */
 362
 363        if (set) {
 364                /* btor(***, BT848_GPIO_OUT_EN); */
 365                if (t->audmode & V4L2_TUNER_MODE_LANG1)
 366                        con = 0x00000000;
 367                if (t->audmode & V4L2_TUNER_MODE_LANG2)
 368                        con = 0x00180000;
 369                if (t->audmode & V4L2_TUNER_MODE_STEREO)
 370                        con = 0x00000000;
 371                if (t->audmode & V4L2_TUNER_MODE_MONO)
 372                        con = 0x00060000;
 373                if (con != 0xffffff) {
 374                        gpio_bits(0x1e0000,con);
 375                        if (bttv_gpio)
 376                                bttv_gpio_tracking(btv, "adtvk503");
 377                }
 378        } else {
 379                t->audmode = V4L2_TUNER_MODE_MONO | V4L2_TUNER_MODE_STEREO |
 380                          V4L2_TUNER_MODE_LANG1  | V4L2_TUNER_MODE_LANG2;
 381        }
 382}
 383