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