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