linux/drivers/media/pci/saa7146/mxb.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3    mxb - v4l2 driver for the Multimedia eXtension Board
   4
   5    Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de>
   6
   7    Visit http://www.themm.net/~mihu/linux/saa7146/mxb.html
   8    for further details about this card.
   9
  10*/
  11
  12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  13
  14#define DEBUG_VARIABLE debug
  15
  16#include <media/drv-intf/saa7146_vv.h>
  17#include <media/tuner.h>
  18#include <media/v4l2-common.h>
  19#include <media/i2c/saa7115.h>
  20#include <linux/module.h>
  21#include <linux/kernel.h>
  22
  23#include "tea6415c.h"
  24#include "tea6420.h"
  25
  26#define MXB_AUDIOS      6
  27
  28#define I2C_SAA7111A  0x24
  29#define I2C_TDA9840   0x42
  30#define I2C_TEA6415C  0x43
  31#define I2C_TEA6420_1 0x4c
  32#define I2C_TEA6420_2 0x4d
  33#define I2C_TUNER     0x60
  34
  35#define MXB_BOARD_CAN_DO_VBI(dev)   (dev->revision != 0)
  36
  37/* global variable */
  38static int mxb_num;
  39
  40/* initial frequence the tuner will be tuned to.
  41   in verden (lower saxony, germany) 4148 is a
  42   channel called "phoenix" */
  43static int freq = 4148;
  44module_param(freq, int, 0644);
  45MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup");
  46
  47static int debug;
  48module_param(debug, int, 0644);
  49MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
  50
  51#define MXB_INPUTS 4
  52enum { TUNER, AUX1, AUX3, AUX3_YC };
  53
  54static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
  55        { TUNER,   "Tuner",          V4L2_INPUT_TYPE_TUNER,  0x3f, 0,
  56                V4L2_STD_PAL_BG | V4L2_STD_PAL_I, 0, V4L2_IN_CAP_STD },
  57        { AUX1,    "AUX1",           V4L2_INPUT_TYPE_CAMERA, 0x3f, 0,
  58                V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
  59        { AUX3,    "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0,
  60                V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
  61        { AUX3_YC, "AUX3 S-Video",   V4L2_INPUT_TYPE_CAMERA, 0x3f, 0,
  62                V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
  63};
  64
  65/* this array holds the information, which port of the saa7146 each
  66   input actually uses. the mxb uses port 0 for every input */
  67static struct {
  68        int hps_source;
  69        int hps_sync;
  70} input_port_selection[MXB_INPUTS] = {
  71        { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
  72        { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
  73        { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
  74        { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
  75};
  76
  77/* this array holds the information of the audio source (mxb_audios),
  78   which has to be switched corresponding to the video source (mxb_channels) */
  79static int video_audio_connect[MXB_INPUTS] =
  80        { 0, 1, 3, 3 };
  81
  82struct mxb_routing {
  83        u32 input;
  84        u32 output;
  85};
  86
  87/* these are the available audio sources, which can switched
  88   to the line- and cd-output individually */
  89static struct v4l2_audio mxb_audios[MXB_AUDIOS] = {
  90            {
  91                .index  = 0,
  92                .name   = "Tuner",
  93                .capability = V4L2_AUDCAP_STEREO,
  94        } , {
  95                .index  = 1,
  96                .name   = "AUX1",
  97                .capability = V4L2_AUDCAP_STEREO,
  98        } , {
  99                .index  = 2,
 100                .name   = "AUX2",
 101                .capability = V4L2_AUDCAP_STEREO,
 102        } , {
 103                .index  = 3,
 104                .name   = "AUX3",
 105                .capability = V4L2_AUDCAP_STEREO,
 106        } , {
 107                .index  = 4,
 108                .name   = "Radio (X9)",
 109                .capability = V4L2_AUDCAP_STEREO,
 110        } , {
 111                .index  = 5,
 112                .name   = "CD-ROM (X10)",
 113                .capability = V4L2_AUDCAP_STEREO,
 114        }
 115};
 116
 117/* These are the necessary input-output-pins for bringing one audio source
 118   (see above) to the CD-output. Note that gain is set to 0 in this table. */
 119static struct mxb_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
 120        { { 1, 1 }, { 1, 1 } }, /* Tuner */
 121        { { 5, 1 }, { 6, 1 } }, /* AUX 1 */
 122        { { 4, 1 }, { 6, 1 } }, /* AUX 2 */
 123        { { 3, 1 }, { 6, 1 } }, /* AUX 3 */
 124        { { 1, 1 }, { 3, 1 } }, /* Radio */
 125        { { 1, 1 }, { 2, 1 } }, /* CD-Rom */
 126        { { 6, 1 }, { 6, 1 } }  /* Mute */
 127};
 128
 129/* These are the necessary input-output-pins for bringing one audio source
 130   (see above) to the line-output. Note that gain is set to 0 in this table. */
 131static struct mxb_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
 132        { { 2, 3 }, { 1, 2 } },
 133        { { 5, 3 }, { 6, 2 } },
 134        { { 4, 3 }, { 6, 2 } },
 135        { { 3, 3 }, { 6, 2 } },
 136        { { 2, 3 }, { 3, 2 } },
 137        { { 2, 3 }, { 2, 2 } },
 138        { { 6, 3 }, { 6, 2 } }  /* Mute */
 139};
 140
 141struct mxb
 142{
 143        struct video_device     video_dev;
 144        struct video_device     vbi_dev;
 145
 146        struct i2c_adapter      i2c_adapter;
 147
 148        struct v4l2_subdev      *saa7111a;
 149        struct v4l2_subdev      *tda9840;
 150        struct v4l2_subdev      *tea6415c;
 151        struct v4l2_subdev      *tuner;
 152        struct v4l2_subdev      *tea6420_1;
 153        struct v4l2_subdev      *tea6420_2;
 154
 155        int     cur_mode;       /* current audio mode (mono, stereo, ...) */
 156        int     cur_input;      /* current input */
 157        int     cur_audinput;   /* current audio input */
 158        int     cur_mute;       /* current mute status */
 159        struct v4l2_frequency   cur_freq;       /* current frequency the tuner is tuned to */
 160};
 161
 162#define saa7111a_call(mxb, o, f, args...) \
 163        v4l2_subdev_call(mxb->saa7111a, o, f, ##args)
 164#define tda9840_call(mxb, o, f, args...) \
 165        v4l2_subdev_call(mxb->tda9840, o, f, ##args)
 166#define tea6415c_call(mxb, o, f, args...) \
 167        v4l2_subdev_call(mxb->tea6415c, o, f, ##args)
 168#define tuner_call(mxb, o, f, args...) \
 169        v4l2_subdev_call(mxb->tuner, o, f, ##args)
 170#define call_all(dev, o, f, args...) \
 171        v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
 172
 173static void mxb_update_audmode(struct mxb *mxb)
 174{
 175        struct v4l2_tuner t = {
 176                .audmode = mxb->cur_mode,
 177        };
 178
 179        tda9840_call(mxb, tuner, s_tuner, &t);
 180}
 181
 182static inline void tea6420_route(struct mxb *mxb, int idx)
 183{
 184        v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
 185                TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0);
 186        v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
 187                TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0);
 188        v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
 189                TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0);
 190        v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
 191                TEA6420_line[idx][1].input, TEA6420_line[idx][1].output, 0);
 192}
 193
 194static struct saa7146_extension extension;
 195
 196static int mxb_s_ctrl(struct v4l2_ctrl *ctrl)
 197{
 198        struct saa7146_dev *dev = container_of(ctrl->handler,
 199                                struct saa7146_dev, ctrl_handler);
 200        struct mxb *mxb = dev->ext_priv;
 201
 202        switch (ctrl->id) {
 203        case V4L2_CID_AUDIO_MUTE:
 204                mxb->cur_mute = ctrl->val;
 205                /* switch the audio-source */
 206                tea6420_route(mxb, ctrl->val ? 6 :
 207                                video_audio_connect[mxb->cur_input]);
 208                break;
 209        default:
 210                return -EINVAL;
 211        }
 212        return 0;
 213}
 214
 215static const struct v4l2_ctrl_ops mxb_ctrl_ops = {
 216        .s_ctrl = mxb_s_ctrl,
 217};
 218
 219static int mxb_probe(struct saa7146_dev *dev)
 220{
 221        struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
 222        struct mxb *mxb = NULL;
 223
 224        v4l2_ctrl_new_std(hdl, &mxb_ctrl_ops,
 225                        V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
 226        if (hdl->error)
 227                return hdl->error;
 228        mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
 229        if (mxb == NULL) {
 230                DEB_D("not enough kernel memory\n");
 231                return -ENOMEM;
 232        }
 233
 234
 235        snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num);
 236
 237        saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
 238        if (i2c_add_adapter(&mxb->i2c_adapter) < 0) {
 239                DEB_S("cannot register i2c-device. skipping.\n");
 240                kfree(mxb);
 241                return -EFAULT;
 242        }
 243
 244        mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
 245                        "saa7111", I2C_SAA7111A, NULL);
 246        mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
 247                        "tea6420", I2C_TEA6420_1, NULL);
 248        mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
 249                        "tea6420", I2C_TEA6420_2, NULL);
 250        mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
 251                        "tea6415c", I2C_TEA6415C, NULL);
 252        mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
 253                        "tda9840", I2C_TDA9840, NULL);
 254        mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
 255                        "tuner", I2C_TUNER, NULL);
 256
 257        /* check if all devices are present */
 258        if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
 259            !mxb->tda9840 || !mxb->saa7111a || !mxb->tuner) {
 260                pr_err("did not find all i2c devices. aborting\n");
 261                i2c_del_adapter(&mxb->i2c_adapter);
 262                kfree(mxb);
 263                return -ENODEV;
 264        }
 265
 266        /* all devices are present, probe was successful */
 267
 268        /* we store the pointer in our private data field */
 269        dev->ext_priv = mxb;
 270
 271        v4l2_ctrl_handler_setup(hdl);
 272
 273        return 0;
 274}
 275
 276/* some init data for the saa7740, the so-called 'sound arena module'.
 277   there are no specs available, so we simply use some init values */
 278static struct {
 279        int     length;
 280        char    data[9];
 281} mxb_saa7740_init[] = {
 282        { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
 283        { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
 284        { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
 285        { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
 286        { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
 287        { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
 288        { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
 289        { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
 290        { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
 291        { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
 292        { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
 293        { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
 294        { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
 295        { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
 296        { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
 297        { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
 298        { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
 299        { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
 300        { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
 301        { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
 302        { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
 303        { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
 304        { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
 305        { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
 306        { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
 307        { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
 308        { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
 309        { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
 310        { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
 311        { 3, { 0x48, 0x00, 0x01 } },
 312        { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
 313        { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
 314        { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
 315        { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
 316        { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
 317        { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
 318        { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
 319        { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
 320        { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
 321        { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
 322        { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
 323        { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
 324        { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
 325        { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
 326        { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
 327        { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
 328        { 3, { 0x80, 0xb3, 0x0a } },
 329        {-1, { 0 } }
 330};
 331
 332/* bring hardware to a sane state. this has to be done, just in case someone
 333   wants to capture from this device before it has been properly initialized.
 334   the capture engine would badly fail, because no valid signal arrives on the
 335   saa7146, thus leading to timeouts and stuff. */
 336static int mxb_init_done(struct saa7146_dev* dev)
 337{
 338        struct mxb* mxb = (struct mxb*)dev->ext_priv;
 339        struct i2c_msg msg;
 340        struct tuner_setup tun_setup;
 341        v4l2_std_id std = V4L2_STD_PAL_BG;
 342
 343        int i = 0, err = 0;
 344
 345        /* mute audio on tea6420s */
 346        tea6420_route(mxb, 6);
 347
 348        /* select video mode in saa7111a */
 349        saa7111a_call(mxb, video, s_std, std);
 350
 351        /* select tuner-output on saa7111a */
 352        i = 0;
 353        saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
 354                SAA7111_FMT_CCIR, 0);
 355
 356        /* select a tuner type */
 357        tun_setup.mode_mask = T_ANALOG_TV;
 358        tun_setup.addr = ADDR_UNSET;
 359        tun_setup.type = TUNER_PHILIPS_PAL;
 360        tuner_call(mxb, tuner, s_type_addr, &tun_setup);
 361        /* tune in some frequency on tuner */
 362        mxb->cur_freq.tuner = 0;
 363        mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
 364        mxb->cur_freq.frequency = freq;
 365        tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
 366
 367        /* set a default video standard */
 368        /* These two gpio calls set the GPIO pins that control the tda9820 */
 369        saa7146_write(dev, GPIO_CTRL, 0x00404050);
 370        saa7111a_call(mxb, core, s_gpio, 1);
 371        saa7111a_call(mxb, video, s_std, std);
 372        tuner_call(mxb, video, s_std, std);
 373
 374        /* switch to tuner-channel on tea6415c */
 375        tea6415c_call(mxb, video, s_routing, 3, 17, 0);
 376
 377        /* select tuner-output on multicable on tea6415c */
 378        tea6415c_call(mxb, video, s_routing, 3, 13, 0);
 379
 380        /* the rest for mxb */
 381        mxb->cur_input = 0;
 382        mxb->cur_audinput = video_audio_connect[mxb->cur_input];
 383        mxb->cur_mute = 1;
 384
 385        mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
 386        mxb_update_audmode(mxb);
 387
 388        /* check if the saa7740 (aka 'sound arena module') is present
 389           on the mxb. if so, we must initialize it. due to lack of
 390           information about the saa7740, the values were reverse
 391           engineered. */
 392        msg.addr = 0x1b;
 393        msg.flags = 0;
 394        msg.len = mxb_saa7740_init[0].length;
 395        msg.buf = &mxb_saa7740_init[0].data[0];
 396
 397        err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
 398        if (err == 1) {
 399                /* the sound arena module is a pos, that's probably the reason
 400                   philips refuses to hand out a datasheet for the saa7740...
 401                   it seems to screw up the i2c bus, so we disable fast irq
 402                   based i2c transactions here and rely on the slow and safe
 403                   polling method ... */
 404                extension.flags &= ~SAA7146_USE_I2C_IRQ;
 405                for (i = 1; ; i++) {
 406                        if (-1 == mxb_saa7740_init[i].length)
 407                                break;
 408
 409                        msg.len = mxb_saa7740_init[i].length;
 410                        msg.buf = &mxb_saa7740_init[i].data[0];
 411                        err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
 412                        if (err != 1) {
 413                                DEB_D("failed to initialize 'sound arena module'\n");
 414                                goto err;
 415                        }
 416                }
 417                pr_info("'sound arena module' detected\n");
 418        }
 419err:
 420        /* the rest for saa7146: you should definitely set some basic values
 421           for the input-port handling of the saa7146. */
 422
 423        /* ext->saa has been filled by the core driver */
 424
 425        /* some stuff is done via variables */
 426        saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source,
 427                        input_port_selection[mxb->cur_input].hps_sync);
 428
 429        /* some stuff is done via direct write to the registers */
 430
 431        /* this is ugly, but because of the fact that this is completely
 432           hardware dependend, it should be done directly... */
 433        saa7146_write(dev, DD1_STREAM_B,        0x00000000);
 434        saa7146_write(dev, DD1_INIT,            0x02000200);
 435        saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
 436
 437        return 0;
 438}
 439
 440/* interrupt-handler. this gets called when irq_mask is != 0.
 441   it must clear the interrupt-bits in irq_mask it has handled */
 442/*
 443void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
 444{
 445        struct mxb* mxb = (struct mxb*)dev->ext_priv;
 446}
 447*/
 448
 449static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
 450{
 451        DEB_EE("VIDIOC_ENUMINPUT %d\n", i->index);
 452        if (i->index >= MXB_INPUTS)
 453                return -EINVAL;
 454        memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
 455        return 0;
 456}
 457
 458static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
 459{
 460        struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 461        struct mxb *mxb = (struct mxb *)dev->ext_priv;
 462        *i = mxb->cur_input;
 463
 464        DEB_EE("VIDIOC_G_INPUT %d\n", *i);
 465        return 0;
 466}
 467
 468static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
 469{
 470        struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 471        struct mxb *mxb = (struct mxb *)dev->ext_priv;
 472        int err = 0;
 473        int i = 0;
 474
 475        DEB_EE("VIDIOC_S_INPUT %d\n", input);
 476
 477        if (input >= MXB_INPUTS)
 478                return -EINVAL;
 479
 480        mxb->cur_input = input;
 481
 482        saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
 483                        input_port_selection[input].hps_sync);
 484
 485        /* prepare switching of tea6415c and saa7111a;
 486           have a look at the 'background'-file for further information  */
 487        switch (input) {
 488        case TUNER:
 489                i = SAA7115_COMPOSITE0;
 490
 491                err = tea6415c_call(mxb, video, s_routing, 3, 17, 0);
 492
 493                /* connect tuner-output always to multicable */
 494                if (!err)
 495                        err = tea6415c_call(mxb, video, s_routing, 3, 13, 0);
 496                break;
 497        case AUX3_YC:
 498                /* nothing to be done here. aux3_yc is
 499                   directly connected to the saa711a */
 500                i = SAA7115_SVIDEO1;
 501                break;
 502        case AUX3:
 503                /* nothing to be done here. aux3 is
 504                   directly connected to the saa711a */
 505                i = SAA7115_COMPOSITE1;
 506                break;
 507        case AUX1:
 508                i = SAA7115_COMPOSITE0;
 509                err = tea6415c_call(mxb, video, s_routing, 1, 17, 0);
 510                break;
 511        }
 512
 513        if (err)
 514                return err;
 515
 516        /* switch video in saa7111a */
 517        if (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0))
 518                pr_err("VIDIOC_S_INPUT: could not address saa7111a\n");
 519
 520        mxb->cur_audinput = video_audio_connect[input];
 521        /* switch the audio-source only if necessary */
 522        if (0 == mxb->cur_mute)
 523                tea6420_route(mxb, mxb->cur_audinput);
 524        if (mxb->cur_audinput == 0)
 525                mxb_update_audmode(mxb);
 526
 527        return 0;
 528}
 529
 530static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
 531{
 532        struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 533        struct mxb *mxb = (struct mxb *)dev->ext_priv;
 534
 535        if (t->index) {
 536                DEB_D("VIDIOC_G_TUNER: channel %d does not have a tuner attached\n",
 537                      t->index);
 538                return -EINVAL;
 539        }
 540
 541        DEB_EE("VIDIOC_G_TUNER: %d\n", t->index);
 542
 543        memset(t, 0, sizeof(*t));
 544        strscpy(t->name, "TV Tuner", sizeof(t->name));
 545        t->type = V4L2_TUNER_ANALOG_TV;
 546        t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
 547                        V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
 548        t->audmode = mxb->cur_mode;
 549        return call_all(dev, tuner, g_tuner, t);
 550}
 551
 552static int vidioc_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *t)
 553{
 554        struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 555        struct mxb *mxb = (struct mxb *)dev->ext_priv;
 556
 557        if (t->index) {
 558                DEB_D("VIDIOC_S_TUNER: channel %d does not have a tuner attached\n",
 559                      t->index);
 560                return -EINVAL;
 561        }
 562
 563        mxb->cur_mode = t->audmode;
 564        return call_all(dev, tuner, s_tuner, t);
 565}
 566
 567static int vidioc_querystd(struct file *file, void *fh, v4l2_std_id *norm)
 568{
 569        struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 570
 571        return call_all(dev, video, querystd, norm);
 572}
 573
 574static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
 575{
 576        struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 577        struct mxb *mxb = (struct mxb *)dev->ext_priv;
 578
 579        if (f->tuner)
 580                return -EINVAL;
 581        *f = mxb->cur_freq;
 582
 583        DEB_EE("VIDIOC_G_FREQ: freq:0x%08x\n", mxb->cur_freq.frequency);
 584        return 0;
 585}
 586
 587static int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *f)
 588{
 589        struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 590        struct mxb *mxb = (struct mxb *)dev->ext_priv;
 591        struct saa7146_vv *vv = dev->vv_data;
 592
 593        if (f->tuner)
 594                return -EINVAL;
 595
 596        if (V4L2_TUNER_ANALOG_TV != f->type)
 597                return -EINVAL;
 598
 599        DEB_EE("VIDIOC_S_FREQUENCY: freq:0x%08x\n", mxb->cur_freq.frequency);
 600
 601        /* tune in desired frequency */
 602        tuner_call(mxb, tuner, s_frequency, f);
 603        /* let the tuner subdev clamp the frequency to the tuner range */
 604        mxb->cur_freq = *f;
 605        tuner_call(mxb, tuner, g_frequency, &mxb->cur_freq);
 606        if (mxb->cur_audinput == 0)
 607                mxb_update_audmode(mxb);
 608
 609        if (mxb->cur_input)
 610                return 0;
 611
 612        /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
 613        spin_lock(&dev->slock);
 614        vv->vbi_fieldcount = 0;
 615        spin_unlock(&dev->slock);
 616
 617        return 0;
 618}
 619
 620static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
 621{
 622        if (a->index >= MXB_AUDIOS)
 623                return -EINVAL;
 624        *a = mxb_audios[a->index];
 625        return 0;
 626}
 627
 628static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
 629{
 630        struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 631        struct mxb *mxb = (struct mxb *)dev->ext_priv;
 632
 633        DEB_EE("VIDIOC_G_AUDIO\n");
 634        *a = mxb_audios[mxb->cur_audinput];
 635        return 0;
 636}
 637
 638static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a)
 639{
 640        struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 641        struct mxb *mxb = (struct mxb *)dev->ext_priv;
 642
 643        DEB_D("VIDIOC_S_AUDIO %d\n", a->index);
 644        if (mxb_inputs[mxb->cur_input].audioset & (1 << a->index)) {
 645                if (mxb->cur_audinput != a->index) {
 646                        mxb->cur_audinput = a->index;
 647                        tea6420_route(mxb, a->index);
 648                        if (mxb->cur_audinput == 0)
 649                                mxb_update_audmode(mxb);
 650                }
 651                return 0;
 652        }
 653        return -EINVAL;
 654}
 655
 656#ifdef CONFIG_VIDEO_ADV_DEBUG
 657static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
 658{
 659        struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 660
 661        if (reg->reg > pci_resource_len(dev->pci, 0) - 4)
 662                return -EINVAL;
 663        reg->val = saa7146_read(dev, reg->reg);
 664        reg->size = 4;
 665        return 0;
 666}
 667
 668static int vidioc_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg)
 669{
 670        struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
 671
 672        if (reg->reg > pci_resource_len(dev->pci, 0) - 4)
 673                return -EINVAL;
 674        saa7146_write(dev, reg->reg, reg->val);
 675        return 0;
 676}
 677#endif
 678
 679static struct saa7146_ext_vv vv_data;
 680
 681/* this function only gets called when the probing was successful */
 682static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
 683{
 684        struct mxb *mxb;
 685
 686        DEB_EE("dev:%p\n", dev);
 687
 688        saa7146_vv_init(dev, &vv_data);
 689        if (mxb_probe(dev)) {
 690                saa7146_vv_release(dev);
 691                return -1;
 692        }
 693        mxb = (struct mxb *)dev->ext_priv;
 694
 695        vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
 696        vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
 697        vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
 698        vv_data.vid_ops.vidioc_querystd = vidioc_querystd;
 699        vv_data.vid_ops.vidioc_g_tuner = vidioc_g_tuner;
 700        vv_data.vid_ops.vidioc_s_tuner = vidioc_s_tuner;
 701        vv_data.vid_ops.vidioc_g_frequency = vidioc_g_frequency;
 702        vv_data.vid_ops.vidioc_s_frequency = vidioc_s_frequency;
 703        vv_data.vid_ops.vidioc_enumaudio = vidioc_enumaudio;
 704        vv_data.vid_ops.vidioc_g_audio = vidioc_g_audio;
 705        vv_data.vid_ops.vidioc_s_audio = vidioc_s_audio;
 706#ifdef CONFIG_VIDEO_ADV_DEBUG
 707        vv_data.vid_ops.vidioc_g_register = vidioc_g_register;
 708        vv_data.vid_ops.vidioc_s_register = vidioc_s_register;
 709#endif
 710        if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
 711                ERR("cannot register capture v4l2 device. skipping.\n");
 712                saa7146_vv_release(dev);
 713                return -1;
 714        }
 715
 716        /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
 717        if (MXB_BOARD_CAN_DO_VBI(dev)) {
 718                if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
 719                        ERR("cannot register vbi v4l2 device. skipping.\n");
 720                }
 721        }
 722
 723        pr_info("found Multimedia eXtension Board #%d\n", mxb_num);
 724
 725        mxb_num++;
 726        mxb_init_done(dev);
 727        return 0;
 728}
 729
 730static int mxb_detach(struct saa7146_dev *dev)
 731{
 732        struct mxb *mxb = (struct mxb *)dev->ext_priv;
 733
 734        DEB_EE("dev:%p\n", dev);
 735
 736        /* mute audio on tea6420s */
 737        tea6420_route(mxb, 6);
 738
 739        saa7146_unregister_device(&mxb->video_dev,dev);
 740        if (MXB_BOARD_CAN_DO_VBI(dev))
 741                saa7146_unregister_device(&mxb->vbi_dev, dev);
 742        saa7146_vv_release(dev);
 743
 744        mxb_num--;
 745
 746        i2c_del_adapter(&mxb->i2c_adapter);
 747        kfree(mxb);
 748
 749        return 0;
 750}
 751
 752static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
 753{
 754        struct mxb *mxb = (struct mxb *)dev->ext_priv;
 755
 756        if (V4L2_STD_PAL_I == standard->id) {
 757                v4l2_std_id std = V4L2_STD_PAL_I;
 758
 759                DEB_D("VIDIOC_S_STD: setting mxb for PAL_I\n");
 760                /* These two gpio calls set the GPIO pins that control the tda9820 */
 761                saa7146_write(dev, GPIO_CTRL, 0x00404050);
 762                saa7111a_call(mxb, core, s_gpio, 0);
 763                saa7111a_call(mxb, video, s_std, std);
 764                if (mxb->cur_input == 0)
 765                        tuner_call(mxb, video, s_std, std);
 766        } else {
 767                v4l2_std_id std = V4L2_STD_PAL_BG;
 768
 769                if (mxb->cur_input)
 770                        std = standard->id;
 771                DEB_D("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM\n");
 772                /* These two gpio calls set the GPIO pins that control the tda9820 */
 773                saa7146_write(dev, GPIO_CTRL, 0x00404050);
 774                saa7111a_call(mxb, core, s_gpio, 1);
 775                saa7111a_call(mxb, video, s_std, std);
 776                if (mxb->cur_input == 0)
 777                        tuner_call(mxb, video, s_std, std);
 778        }
 779        return 0;
 780}
 781
 782static struct saa7146_standard standard[] = {
 783        {
 784                .name   = "PAL-BG",     .id     = V4L2_STD_PAL_BG,
 785                .v_offset       = 0x17, .v_field        = 288,
 786                .h_offset       = 0x14, .h_pixels       = 680,
 787                .v_max_out      = 576,  .h_max_out      = 768,
 788        }, {
 789                .name   = "PAL-I",      .id     = V4L2_STD_PAL_I,
 790                .v_offset       = 0x17, .v_field        = 288,
 791                .h_offset       = 0x14, .h_pixels       = 680,
 792                .v_max_out      = 576,  .h_max_out      = 768,
 793        }, {
 794                .name   = "NTSC",       .id     = V4L2_STD_NTSC,
 795                .v_offset       = 0x16, .v_field        = 240,
 796                .h_offset       = 0x06, .h_pixels       = 708,
 797                .v_max_out      = 480,  .h_max_out      = 640,
 798        }, {
 799                .name   = "SECAM",      .id     = V4L2_STD_SECAM,
 800                .v_offset       = 0x14, .v_field        = 288,
 801                .h_offset       = 0x14, .h_pixels       = 720,
 802                .v_max_out      = 576,  .h_max_out      = 768,
 803        }
 804};
 805
 806static struct saa7146_pci_extension_data mxb = {
 807        .ext_priv = "Multimedia eXtension Board",
 808        .ext = &extension,
 809};
 810
 811static const struct pci_device_id pci_tbl[] = {
 812        {
 813                .vendor    = PCI_VENDOR_ID_PHILIPS,
 814                .device    = PCI_DEVICE_ID_PHILIPS_SAA7146,
 815                .subvendor = 0x0000,
 816                .subdevice = 0x0000,
 817                .driver_data = (unsigned long)&mxb,
 818        }, {
 819                .vendor = 0,
 820        }
 821};
 822
 823MODULE_DEVICE_TABLE(pci, pci_tbl);
 824
 825static struct saa7146_ext_vv vv_data = {
 826        .inputs         = MXB_INPUTS,
 827        .capabilities   = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_AUDIO,
 828        .stds           = &standard[0],
 829        .num_stds       = ARRAY_SIZE(standard),
 830        .std_callback   = &std_callback,
 831};
 832
 833static struct saa7146_extension extension = {
 834        .name           = "Multimedia eXtension Board",
 835        .flags          = SAA7146_USE_I2C_IRQ,
 836
 837        .pci_tbl        = &pci_tbl[0],
 838        .module         = THIS_MODULE,
 839
 840        .attach         = mxb_attach,
 841        .detach         = mxb_detach,
 842
 843        .irq_mask       = 0,
 844        .irq_func       = NULL,
 845};
 846
 847static int __init mxb_init_module(void)
 848{
 849        if (saa7146_register_extension(&extension)) {
 850                DEB_S("failed to register extension\n");
 851                return -ENODEV;
 852        }
 853
 854        return 0;
 855}
 856
 857static void __exit mxb_cleanup_module(void)
 858{
 859        saa7146_unregister_extension(&extension);
 860}
 861
 862module_init(mxb_init_module);
 863module_exit(mxb_cleanup_module);
 864
 865MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
 866MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
 867MODULE_LICENSE("GPL");
 868