11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mxb - v4l2 driver for the Multimedia eXtension Board 3a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 46acaba8e22bb355409e06d9e7ce4e7bef1bcaa04Michael Hunold Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de> 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6631dd1a885b6d7e9f6f51b4e5b311c2bb04c323cJustin P. Mattock Visit http://www.themm.net/~mihu/linux/saa7146/mxb.html 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for further details about this card. 8a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This program is free software; you can redistribute it and/or modify 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds it under the terms of the GNU General Public License as published by 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds the Free Software Foundation; either version 2 of the License, or 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (at your option) any later version. 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This program is distributed in the hope that it will be useful, 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds but WITHOUT ANY WARRANTY; without even the implied warranty of 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GNU General Public License for more details. 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds You should have received a copy of the GNU General Public License 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds along with this program; if not, write to the Free Software 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2444d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 2544d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEBUG_VARIABLE debug 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <media/saa7146_vv.h> 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <media/tuner.h> 305e453dc757385ec892a818e4e3b5de027987ced9Michael Krufky#include <media/v4l2-common.h> 31707ecf4603a9439dcf409e13c5e9ed4e164ddfffHans Verkuil#include <media/saa7115.h> 327a707b89202f905bd9f9fbde326933c59a81214cPaul Gortmaker#include <linux/module.h> 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "tea6415c.h" 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "tea6420.h" 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 376680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil#define MXB_AUDIOS 6 386680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil 391b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil#define I2C_SAA7111A 0x24 401b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil#define I2C_TDA9840 0x42 411b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil#define I2C_TEA6415C 0x43 421b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil#define I2C_TEA6420_1 0x4c 431b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil#define I2C_TEA6420_2 0x4d 441b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil#define I2C_TUNER 0x60 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 46a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab#define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* global variable */ 49ff699e6bd02eb1c6d02c7c2b576c2ee6caab201cDouglas Schilling Landgrafstatic int mxb_num; 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab/* initial frequence the tuner will be tuned to. 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds in verden (lower saxony, germany) 4148 is a 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds channel called "phoenix" */ 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int freq = 4148; 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(freq, int, 0644); 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup"); 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 58ff699e6bd02eb1c6d02c7c2b576c2ee6caab201cDouglas Schilling Landgrafstatic int debug; 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(debug, int, 0644); 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off)."); 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MXB_INPUTS 4 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsenum { TUNER, AUX1, AUX3, AUX3_YC }; 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct v4l2_input mxb_inputs[MXB_INPUTS] = { 664894b709d14c593466cc05e55ee493af931205e8Hans Verkuil { TUNER, "Tuner", V4L2_INPUT_TYPE_TUNER, 0x3f, 0, 676680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil V4L2_STD_PAL_BG | V4L2_STD_PAL_I, 0, V4L2_IN_CAP_STD }, 684894b709d14c593466cc05e55ee493af931205e8Hans Verkuil { AUX1, "AUX1", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0, 696680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, 704894b709d14c593466cc05e55ee493af931205e8Hans Verkuil { AUX3, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0, 716680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, 724894b709d14c593466cc05e55ee493af931205e8Hans Verkuil { AUX3_YC, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA, 0x3f, 0, 736680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil V4L2_STD_ALL, 0, V4L2_IN_CAP_STD }, 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* this array holds the information, which port of the saa7146 each 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds input actually uses. the mxb uses port 0 for every input */ 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct { 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int hps_source; 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int hps_sync; 81a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab} input_port_selection[MXB_INPUTS] = { 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A }, 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* this array holds the information of the audio source (mxb_audios), 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds which has to be switched corresponding to the video source (mxb_channels) */ 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int video_audio_connect[MXB_INPUTS] = 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 0, 1, 3, 3 }; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 935325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuilstruct mxb_routing { 945325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil u32 input; 955325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil u32 output; 965325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil}; 975325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil 986e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil/* these are the available audio sources, which can switched 996e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil to the line- and cd-output individually */ 1006e65ca942b9664a987866ac0c62e7e450777056bHans Verkuilstatic struct v4l2_audio mxb_audios[MXB_AUDIOS] = { 1016e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil { 1026e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .index = 0, 1036e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .name = "Tuner", 1046e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .capability = V4L2_AUDCAP_STEREO, 1056e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil } , { 1066e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .index = 1, 1076e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .name = "AUX1", 1086e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .capability = V4L2_AUDCAP_STEREO, 1096e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil } , { 1106e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .index = 2, 1116e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .name = "AUX2", 1126e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .capability = V4L2_AUDCAP_STEREO, 1136e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil } , { 1146e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .index = 3, 1156e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .name = "AUX3", 1166e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .capability = V4L2_AUDCAP_STEREO, 1176e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil } , { 1186e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .index = 4, 1196e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .name = "Radio (X9)", 1206e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .capability = V4L2_AUDCAP_STEREO, 1216e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil } , { 1226e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .index = 5, 1236e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .name = "CD-ROM (X10)", 1246e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .capability = V4L2_AUDCAP_STEREO, 1256e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil } 1266e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil}; 1276e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil 1281b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil/* These are the necessary input-output-pins for bringing one audio source 1291b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil (see above) to the CD-output. Note that gain is set to 0 in this table. */ 1305325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuilstatic struct mxb_routing TEA6420_cd[MXB_AUDIOS + 1][2] = { 1311b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil { { 1, 1 }, { 1, 1 } }, /* Tuner */ 1321b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil { { 5, 1 }, { 6, 1 } }, /* AUX 1 */ 1331b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil { { 4, 1 }, { 6, 1 } }, /* AUX 2 */ 1341b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil { { 3, 1 }, { 6, 1 } }, /* AUX 3 */ 1351b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil { { 1, 1 }, { 3, 1 } }, /* Radio */ 1361b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil { { 1, 1 }, { 2, 1 } }, /* CD-Rom */ 1371b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil { { 6, 1 }, { 6, 1 } } /* Mute */ 1381b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil}; 1391b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil 1401b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil/* These are the necessary input-output-pins for bringing one audio source 1411b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil (see above) to the line-output. Note that gain is set to 0 in this table. */ 1425325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuilstatic struct mxb_routing TEA6420_line[MXB_AUDIOS + 1][2] = { 1431b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil { { 2, 3 }, { 1, 2 } }, 1441b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil { { 5, 3 }, { 6, 2 } }, 1451b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil { { 4, 3 }, { 6, 2 } }, 1461b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil { { 3, 3 }, { 6, 2 } }, 1471b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil { { 2, 3 }, { 3, 2 } }, 1481b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil { { 2, 3 }, { 2, 2 } }, 1491b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil { { 6, 3 }, { 6, 2 } } /* Mute */ 1501b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil}; 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct mxb 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct video_device *video_dev; 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct video_device *vbi_dev; 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 157a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab struct i2c_adapter i2c_adapter; 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1591b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil struct v4l2_subdev *saa7111a; 1601b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil struct v4l2_subdev *tda9840; 1611b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil struct v4l2_subdev *tea6415c; 1621b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil struct v4l2_subdev *tuner; 1631b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil struct v4l2_subdev *tea6420_1; 1641b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil struct v4l2_subdev *tea6420_2; 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cur_mode; /* current audio mode (mono, stereo, ...) */ 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cur_input; /* current input */ 1686680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil int cur_audinput; /* current audio input */ 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cur_mute; /* current mute status */ 1709d2599d98e9cb511f326b2d1b353e462bc360774Michael Hunold struct v4l2_frequency cur_freq; /* current frequency the tuner is tuned to */ 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1731b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil#define saa7111a_call(mxb, o, f, args...) \ 1741b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil v4l2_subdev_call(mxb->saa7111a, o, f, ##args) 1751b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil#define tda9840_call(mxb, o, f, args...) \ 1761b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil v4l2_subdev_call(mxb->tda9840, o, f, ##args) 1771b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil#define tea6415c_call(mxb, o, f, args...) \ 1781b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil v4l2_subdev_call(mxb->tea6415c, o, f, ##args) 1791b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil#define tuner_call(mxb, o, f, args...) \ 1801b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil v4l2_subdev_call(mxb->tuner, o, f, ##args) 1811b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil#define call_all(dev, o, f, args...) \ 1821b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args) 183961f80f9c0c0f7c45d7818f9c9969dfaa9e4463dJean Delvare 1844894b709d14c593466cc05e55ee493af931205e8Hans Verkuilstatic void mxb_update_audmode(struct mxb *mxb) 1854894b709d14c593466cc05e55ee493af931205e8Hans Verkuil{ 1864894b709d14c593466cc05e55ee493af931205e8Hans Verkuil struct v4l2_tuner t = { 1874894b709d14c593466cc05e55ee493af931205e8Hans Verkuil .audmode = mxb->cur_mode, 1884894b709d14c593466cc05e55ee493af931205e8Hans Verkuil }; 1894894b709d14c593466cc05e55ee493af931205e8Hans Verkuil 1904894b709d14c593466cc05e55ee493af931205e8Hans Verkuil tda9840_call(mxb, tuner, s_tuner, &t); 1914894b709d14c593466cc05e55ee493af931205e8Hans Verkuil} 1924894b709d14c593466cc05e55ee493af931205e8Hans Verkuil 1936680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuilstatic inline void tea6420_route(struct mxb *mxb, int idx) 1945325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil{ 1955325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil v4l2_subdev_call(mxb->tea6420_1, audio, s_routing, 1965325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0); 1975325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil v4l2_subdev_call(mxb->tea6420_2, audio, s_routing, 1985325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0); 1995325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil v4l2_subdev_call(mxb->tea6420_1, audio, s_routing, 2005325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0); 2015325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil v4l2_subdev_call(mxb->tea6420_2, audio, s_routing, 2025325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil TEA6420_line[idx][1].input, TEA6420_line[idx][1].output, 0); 2035325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil} 2045325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil 2051b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuilstatic struct saa7146_extension extension; 206961f80f9c0c0f7c45d7818f9c9969dfaa9e4463dJean Delvare 2076e65ca942b9664a987866ac0c62e7e450777056bHans Verkuilstatic int mxb_s_ctrl(struct v4l2_ctrl *ctrl) 2086e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil{ 2096e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil struct saa7146_dev *dev = container_of(ctrl->handler, 2106e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil struct saa7146_dev, ctrl_handler); 2116e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil struct mxb *mxb = dev->ext_priv; 2126e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil 2136e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil switch (ctrl->id) { 2146e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil case V4L2_CID_AUDIO_MUTE: 2156e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil mxb->cur_mute = ctrl->val; 2166e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil /* switch the audio-source */ 2176680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil tea6420_route(mxb, ctrl->val ? 6 : 2186e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil video_audio_connect[mxb->cur_input]); 2196e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil break; 2206e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil default: 2216e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil return -EINVAL; 2226e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil } 2236e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil return 0; 2246e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil} 2256e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil 2266e65ca942b9664a987866ac0c62e7e450777056bHans Verkuilstatic const struct v4l2_ctrl_ops mxb_ctrl_ops = { 2276e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .s_ctrl = mxb_s_ctrl, 2286e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil}; 2296e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil 2301b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuilstatic int mxb_probe(struct saa7146_dev *dev) 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2326e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler; 2331b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil struct mxb *mxb = NULL; 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2356e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil v4l2_ctrl_new_std(hdl, &mxb_ctrl_ops, 2364894b709d14c593466cc05e55ee493af931205e8Hans Verkuil V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); 2376e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil if (hdl->error) 2386e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil return hdl->error; 2397408187d223f63d46a13b6a35b8f96b032c2f623Panagiotis Issaris mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL); 2401b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil if (mxb == NULL) { 24144d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_D("not enough kernel memory\n"); 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2456e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil 2469ebeae5641b141a71ed442e9fcb4993f6c0cd04fHans Verkuil snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num); 2479ebeae5641b141a71ed442e9fcb4993f6c0cd04fHans Verkuil 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); 2491b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil if (i2c_add_adapter(&mxb->i2c_adapter) < 0) { 25044d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_S("cannot register i2c-device. skipping.\n"); 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(mxb); 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EFAULT; 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 255e6574f2fbecdb8af807169d345c10131ae060a88Hans Verkuil mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 2569a1f8b34aa539000da17a06235e4bec254d0bfb5Laurent Pinchart "saa7111", I2C_SAA7111A, NULL); 257e6574f2fbecdb8af807169d345c10131ae060a88Hans Verkuil mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 2589a1f8b34aa539000da17a06235e4bec254d0bfb5Laurent Pinchart "tea6420", I2C_TEA6420_1, NULL); 259e6574f2fbecdb8af807169d345c10131ae060a88Hans Verkuil mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 2609a1f8b34aa539000da17a06235e4bec254d0bfb5Laurent Pinchart "tea6420", I2C_TEA6420_2, NULL); 261e6574f2fbecdb8af807169d345c10131ae060a88Hans Verkuil mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 2629a1f8b34aa539000da17a06235e4bec254d0bfb5Laurent Pinchart "tea6415c", I2C_TEA6415C, NULL); 263e6574f2fbecdb8af807169d345c10131ae060a88Hans Verkuil mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 2649a1f8b34aa539000da17a06235e4bec254d0bfb5Laurent Pinchart "tda9840", I2C_TDA9840, NULL); 265e6574f2fbecdb8af807169d345c10131ae060a88Hans Verkuil mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 2669a1f8b34aa539000da17a06235e4bec254d0bfb5Laurent Pinchart "tuner", I2C_TUNER, NULL); 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if all devices are present */ 2695fa1247a2b56f33f88432c24e109deaf91ef8281Al Viro if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c || 2705fa1247a2b56f33f88432c24e109deaf91ef8281Al Viro !mxb->tda9840 || !mxb->saa7111a || !mxb->tuner) { 27144d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches pr_err("did not find all i2c devices. aborting\n"); 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i2c_del_adapter(&mxb->i2c_adapter); 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(mxb); 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 277a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab /* all devices are present, probe was successful */ 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* we store the pointer in our private data field */ 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dev->ext_priv = mxb; 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 282d69f4a517c0a9b0b4795f4604aed8cf96dcd5223Hans Verkuil v4l2_ctrl_handler_setup(hdl); 283d69f4a517c0a9b0b4795f4604aed8cf96dcd5223Hans Verkuil 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 287a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab/* some init data for the saa7740, the so-called 'sound arena module'. 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds there are no specs available, so we simply use some init values */ 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct { 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int length; 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char data[9]; 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} mxb_saa7740_init[] = { 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } }, 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } }, 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } }, 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } }, 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } }, 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } }, 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } }, 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } }, 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } }, 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } }, 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } }, 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } }, 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } }, 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } }, 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } }, 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } }, 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } }, 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } }, 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } }, 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } }, 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } }, 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } }, 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } }, 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } }, 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } }, 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } }, 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } }, 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } }, 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } }, 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x48, 0x00, 0x01 } }, 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } }, 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } }, 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } }, 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } }, 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } }, 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } }, 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } }, 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } }, 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } }, 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } }, 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } }, 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } }, 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } }, 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } }, 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } }, 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } }, 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 3, { 0x80, 0xb3, 0x0a } }, 3402633812f897cc354071699e86ea82e3bfd77cddcHans Verkuil {-1, { 0 } } 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* bring hardware to a sane state. this has to be done, just in case someone 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wants to capture from this device before it has been properly initialized. 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds the capture engine would badly fail, because no valid signal arrives on the 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146, thus leading to timeouts and stuff. */ 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mxb_init_done(struct saa7146_dev* dev) 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mxb* mxb = (struct mxb*)dev->ext_priv; 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct i2c_msg msg; 35185369df350b138f26eac779da33de0960635ca4dMauro Carvalho Chehab struct tuner_setup tun_setup; 3526acaba8e22bb355409e06d9e7ce4e7bef1bcaa04Michael Hunold v4l2_std_id std = V4L2_STD_PAL_BG; 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i = 0, err = 0; 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3564894b709d14c593466cc05e55ee493af931205e8Hans Verkuil /* mute audio on tea6420s */ 3574894b709d14c593466cc05e55ee493af931205e8Hans Verkuil tea6420_route(mxb, 6); 3584894b709d14c593466cc05e55ee493af931205e8Hans Verkuil 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* select video mode in saa7111a */ 3608774bed9ce832d8d9ccb79e92800b808aa2d2ad2Laurent Pinchart saa7111a_call(mxb, video, s_std, std); 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* select tuner-output on saa7111a */ 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i = 0; 3645325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0, 365340dde817a4f68af79453ed295ca0e8de7232669Hans Verkuil SAA7111_FMT_CCIR, 0); 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* select a tuner type */ 36885369df350b138f26eac779da33de0960635ca4dMauro Carvalho Chehab tun_setup.mode_mask = T_ANALOG_TV; 36985369df350b138f26eac779da33de0960635ca4dMauro Carvalho Chehab tun_setup.addr = ADDR_UNSET; 3709d2599d98e9cb511f326b2d1b353e462bc360774Michael Hunold tun_setup.type = TUNER_PHILIPS_PAL; 3711b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil tuner_call(mxb, tuner, s_type_addr, &tun_setup); 3729d2599d98e9cb511f326b2d1b353e462bc360774Michael Hunold /* tune in some frequency on tuner */ 3739d2599d98e9cb511f326b2d1b353e462bc360774Michael Hunold mxb->cur_freq.tuner = 0; 3749d2599d98e9cb511f326b2d1b353e462bc360774Michael Hunold mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV; 3759d2599d98e9cb511f326b2d1b353e462bc360774Michael Hunold mxb->cur_freq.frequency = freq; 3761b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq); 3779d2599d98e9cb511f326b2d1b353e462bc360774Michael Hunold 3786acaba8e22bb355409e06d9e7ce4e7bef1bcaa04Michael Hunold /* set a default video standard */ 3794894b709d14c593466cc05e55ee493af931205e8Hans Verkuil /* These two gpio calls set the GPIO pins that control the tda9820 */ 3804894b709d14c593466cc05e55ee493af931205e8Hans Verkuil saa7146_write(dev, GPIO_CTRL, 0x00404050); 3814894b709d14c593466cc05e55ee493af931205e8Hans Verkuil saa7111a_call(mxb, core, s_gpio, 1); 3828774bed9ce832d8d9ccb79e92800b808aa2d2ad2Laurent Pinchart saa7111a_call(mxb, video, s_std, std); 3838774bed9ce832d8d9ccb79e92800b808aa2d2ad2Laurent Pinchart tuner_call(mxb, video, s_std, std); 3846acaba8e22bb355409e06d9e7ce4e7bef1bcaa04Michael Hunold 3851b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil /* switch to tuner-channel on tea6415c */ 3865325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil tea6415c_call(mxb, video, s_routing, 3, 17, 0); 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3881b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil /* select tuner-output on multicable on tea6415c */ 3895325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil tea6415c_call(mxb, video, s_routing, 3, 13, 0); 390a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* the rest for mxb */ 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mxb->cur_input = 0; 3936680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil mxb->cur_audinput = video_audio_connect[mxb->cur_input]; 3944894b709d14c593466cc05e55ee493af931205e8Hans Verkuil mxb->cur_mute = 1; 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mxb->cur_mode = V4L2_TUNER_MODE_STEREO; 3974894b709d14c593466cc05e55ee493af931205e8Hans Verkuil mxb_update_audmode(mxb); 398a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* check if the saa7740 (aka 'sound arena module') is present 400a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab on the mxb. if so, we must initialize it. due to lack of 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds informations about the saa7740, the values were reverse 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds engineered. */ 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg.addr = 0x1b; 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg.flags = 0; 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg.len = mxb_saa7740_init[0].length; 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg.buf = &mxb_saa7740_init[0].data[0]; 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4082633812f897cc354071699e86ea82e3bfd77cddcHans Verkuil err = i2c_transfer(&mxb->i2c_adapter, &msg, 1); 4092633812f897cc354071699e86ea82e3bfd77cddcHans Verkuil if (err == 1) { 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* the sound arena module is a pos, that's probably the reason 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds philips refuses to hand out a datasheet for the saa7740... 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds it seems to screw up the i2c bus, so we disable fast irq 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds based i2c transactions here and rely on the slow and safe 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds polling method ... */ 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds extension.flags &= ~SAA7146_USE_I2C_IRQ; 4162633812f897cc354071699e86ea82e3bfd77cddcHans Verkuil for (i = 1; ; i++) { 4172633812f897cc354071699e86ea82e3bfd77cddcHans Verkuil if (-1 == mxb_saa7740_init[i].length) 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 420a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab msg.len = mxb_saa7740_init[i].length; 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg.buf = &mxb_saa7740_init[i].data[0]; 4222633812f897cc354071699e86ea82e3bfd77cddcHans Verkuil err = i2c_transfer(&mxb->i2c_adapter, &msg, 1); 4232633812f897cc354071699e86ea82e3bfd77cddcHans Verkuil if (err != 1) { 42444d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_D("failed to initialize 'sound arena module'\n"); 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds goto err; 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 42844d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches pr_info("'sound arena module' detected\n"); 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 430a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehaberr: 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* the rest for saa7146: you should definitely set some basic values 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for the input-port handling of the saa7146. */ 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* ext->saa has been filled by the core driver */ 435a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* some stuff is done via variables */ 4372633812f897cc354071699e86ea82e3bfd77cddcHans Verkuil saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source, 4382633812f897cc354071699e86ea82e3bfd77cddcHans Verkuil input_port_selection[mxb->cur_input].hps_sync); 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* some stuff is done via direct write to the registers */ 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* this is ugly, but because of the fact that this is completely 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hardware dependend, it should be done directly... */ 444a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab saa7146_write(dev, DD1_STREAM_B, 0x00000000); 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_write(dev, DD1_INIT, 0x02000200); 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* interrupt-handler. this gets called when irq_mask is != 0. 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds it must clear the interrupt-bits in irq_mask it has handled */ 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask) 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mxb* mxb = (struct mxb*)dev->ext_priv; 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 460b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuilstatic int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i) 461b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil{ 46244d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_EE("VIDIOC_ENUMINPUT %d\n", i->index); 463223ffe5f8270ba9d069f1cbff9acec095a6f58b1Roel Kluin if (i->index >= MXB_INPUTS) 464b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil return -EINVAL; 465b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input)); 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 469b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuilstatic int vidioc_g_input(struct file *file, void *fh, unsigned int *i) 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 471b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 4722633812f897cc354071699e86ea82e3bfd77cddcHans Verkuil struct mxb *mxb = (struct mxb *)dev->ext_priv; 473b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil *i = mxb->cur_input; 474a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 47544d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_EE("VIDIOC_G_INPUT %d\n", *i); 476b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil return 0; 477b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil} 478a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 479b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuilstatic int vidioc_s_input(struct file *file, void *fh, unsigned int input) 480b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil{ 481b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 482b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct mxb *mxb = (struct mxb *)dev->ext_priv; 4835325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil int err = 0; 484b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil int i = 0; 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48644d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_EE("VIDIOC_S_INPUT %d\n", input); 487a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 488f14a2972e40dbfbe7077ec7ab21cc2729f7e7d6dRoel Kluin if (input >= MXB_INPUTS) 489b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil return -EINVAL; 490a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 491b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil mxb->cur_input = input; 492a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 493b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, 494b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil input_port_selection[input].hps_sync); 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 496b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil /* prepare switching of tea6415c and saa7111a; 497b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil have a look at the 'background'-file for further informations */ 498b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil switch (input) { 499b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil case TUNER: 500b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil i = SAA7115_COMPOSITE0; 501a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 5025325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil err = tea6415c_call(mxb, video, s_routing, 3, 17, 0); 5035325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil 504b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil /* connect tuner-output always to multicable */ 5055325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil if (!err) 5065325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil err = tea6415c_call(mxb, video, s_routing, 3, 13, 0); 507b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil break; 508b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil case AUX3_YC: 509b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil /* nothing to be done here. aux3_yc is 510b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil directly connected to the saa711a */ 511b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil i = SAA7115_SVIDEO1; 512b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil break; 513b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil case AUX3: 514b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil /* nothing to be done here. aux3 is 515b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil directly connected to the saa711a */ 516b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil i = SAA7115_COMPOSITE1; 517b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil break; 518b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil case AUX1: 519b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil i = SAA7115_COMPOSITE0; 5205325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil err = tea6415c_call(mxb, video, s_routing, 1, 17, 0); 521b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil break; 522b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil } 523a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 5245325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil if (err) 5255325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil return err; 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 527b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil /* switch video in saa7111a */ 528340dde817a4f68af79453ed295ca0e8de7232669Hans Verkuil if (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0)) 52944d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches pr_err("VIDIOC_S_INPUT: could not address saa7111a\n"); 530b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil 5316680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil mxb->cur_audinput = video_audio_connect[input]; 532b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil /* switch the audio-source only if necessary */ 5335325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil if (0 == mxb->cur_mute) 5346680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil tea6420_route(mxb, mxb->cur_audinput); 5354894b709d14c593466cc05e55ee493af931205e8Hans Verkuil if (mxb->cur_audinput == 0) 5364894b709d14c593466cc05e55ee493af931205e8Hans Verkuil mxb_update_audmode(mxb); 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 538b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil return 0; 539b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil} 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 541b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuilstatic int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t) 542b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil{ 543b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 544b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct mxb *mxb = (struct mxb *)dev->ext_priv; 545a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 546b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil if (t->index) { 54744d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_D("VIDIOC_G_TUNER: channel %d does not have a tuner attached\n", 54844d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches t->index); 549b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil return -EINVAL; 550b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil } 551a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 55244d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_EE("VIDIOC_G_TUNER: %d\n", t->index); 553a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 554b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil memset(t, 0, sizeof(*t)); 555b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil strlcpy(t->name, "TV Tuner", sizeof(t->name)); 556b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil t->type = V4L2_TUNER_ANALOG_TV; 557b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | 558b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; 559b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil t->audmode = mxb->cur_mode; 5601b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil return call_all(dev, tuner, g_tuner, t); 561b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil} 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5632f73c7c582a685b3198b974cd6d964d0338f8ab5Hans Verkuilstatic int vidioc_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *t) 564b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil{ 565b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 566b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct mxb *mxb = (struct mxb *)dev->ext_priv; 567a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 568b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil if (t->index) { 56944d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_D("VIDIOC_S_TUNER: channel %d does not have a tuner attached\n", 57044d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches t->index); 571b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil return -EINVAL; 572b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil } 5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 574b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil mxb->cur_mode = t->audmode; 5751b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil return call_all(dev, tuner, s_tuner, t); 576b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil} 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 578313fce750a073b041526f6e595f755f6233f8e73Hans Verkuilstatic int vidioc_querystd(struct file *file, void *fh, v4l2_std_id *norm) 579313fce750a073b041526f6e595f755f6233f8e73Hans Verkuil{ 580313fce750a073b041526f6e595f755f6233f8e73Hans Verkuil struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 581313fce750a073b041526f6e595f755f6233f8e73Hans Verkuil 582313fce750a073b041526f6e595f755f6233f8e73Hans Verkuil return call_all(dev, video, querystd, norm); 583313fce750a073b041526f6e595f755f6233f8e73Hans Verkuil} 584313fce750a073b041526f6e595f755f6233f8e73Hans Verkuil 585b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuilstatic int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f) 586b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil{ 587b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 588b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct mxb *mxb = (struct mxb *)dev->ext_priv; 589b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil 5906e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil if (f->tuner) 591b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil return -EINVAL; 592b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil *f = mxb->cur_freq; 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 59444d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_EE("VIDIOC_G_FREQ: freq:0x%08x\n", mxb->cur_freq.frequency); 595b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil return 0; 596b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil} 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 598b530a447bb588fdf43fdf4eb909e4ee1921d47acHans Verkuilstatic int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *f) 599b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil{ 600b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 601b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct mxb *mxb = (struct mxb *)dev->ext_priv; 602b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct saa7146_vv *vv = dev->vv_data; 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 604b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil if (f->tuner) 605b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil return -EINVAL; 606a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 607b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil if (V4L2_TUNER_ANALOG_TV != f->type) 608b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil return -EINVAL; 609a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 61044d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_EE("VIDIOC_S_FREQUENCY: freq:0x%08x\n", mxb->cur_freq.frequency); 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 612b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil /* tune in desired frequency */ 6136e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil tuner_call(mxb, tuner, s_frequency, f); 6146e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil /* let the tuner subdev clamp the frequency to the tuner range */ 6156e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil mxb->cur_freq = *f; 616b530a447bb588fdf43fdf4eb909e4ee1921d47acHans Verkuil tuner_call(mxb, tuner, g_frequency, &mxb->cur_freq); 6174894b709d14c593466cc05e55ee493af931205e8Hans Verkuil if (mxb->cur_audinput == 0) 6184894b709d14c593466cc05e55ee493af931205e8Hans Verkuil mxb_update_audmode(mxb); 6196e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil 6206e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil if (mxb->cur_input) 6216e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil return 0; 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 623b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */ 624b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil spin_lock(&dev->slock); 625b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil vv->vbi_fieldcount = 0; 626b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil spin_unlock(&dev->slock); 627b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil 628b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil return 0; 629b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil} 630b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil 6316e65ca942b9664a987866ac0c62e7e450777056bHans Verkuilstatic int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a) 6326e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil{ 6336e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil if (a->index >= MXB_AUDIOS) 6346e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil return -EINVAL; 6356e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil *a = mxb_audios[a->index]; 6366e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil return 0; 6376e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil} 6386e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil 639b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuilstatic int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a) 640b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil{ 641b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 642b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct mxb *mxb = (struct mxb *)dev->ext_priv; 643b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil 6444894b709d14c593466cc05e55ee493af931205e8Hans Verkuil DEB_EE("VIDIOC_G_AUDIO\n"); 6454894b709d14c593466cc05e55ee493af931205e8Hans Verkuil *a = mxb_audios[mxb->cur_audinput]; 646b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil return 0; 647b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil} 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6490e8025b9f6011a6bd69d01080d584bc95a89d02eHans Verkuilstatic int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a) 650b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil{ 6516e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 6526e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil struct mxb *mxb = (struct mxb *)dev->ext_priv; 6536e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil 65444d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_D("VIDIOC_S_AUDIO %d\n", a->index); 6556680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil if (mxb_inputs[mxb->cur_input].audioset & (1 << a->index)) { 6566680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil if (mxb->cur_audinput != a->index) { 6576680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil mxb->cur_audinput = a->index; 6586680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil tea6420_route(mxb, a->index); 6594894b709d14c593466cc05e55ee493af931205e8Hans Verkuil if (mxb->cur_audinput == 0) 6604894b709d14c593466cc05e55ee493af931205e8Hans Verkuil mxb_update_audmode(mxb); 6616680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil } 6626e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil return 0; 6636680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil } 6646e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil return -EINVAL; 665b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil} 666a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 667b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil#ifdef CONFIG_VIDEO_ADV_DEBUG 668b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuilstatic int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) 669b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil{ 670b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 6711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 672d2cac168160aa7afd472d4a04d0da3f146243710Hans Verkuil if (reg->reg > pci_resource_len(dev->pci, 0) - 4) 673d2cac168160aa7afd472d4a04d0da3f146243710Hans Verkuil return -EINVAL; 674abca2056dc3dd0d813ba2f8b013e98cf009ba168Hans Verkuil reg->val = saa7146_read(dev, reg->reg); 675abca2056dc3dd0d813ba2f8b013e98cf009ba168Hans Verkuil reg->size = 4; 676ab49ae0f201f1e7e07250d011fffde8ed2530175Hans Verkuil return 0; 677b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil} 6781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 679977ba3b1b73f24fae2d0c8bd59d7a4696f1e0cccHans Verkuilstatic int vidioc_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg) 680b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil{ 681b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 6821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 683d2cac168160aa7afd472d4a04d0da3f146243710Hans Verkuil if (reg->reg > pci_resource_len(dev->pci, 0) - 4) 684d2cac168160aa7afd472d4a04d0da3f146243710Hans Verkuil return -EINVAL; 685abca2056dc3dd0d813ba2f8b013e98cf009ba168Hans Verkuil saa7146_write(dev, reg->reg, reg->val); 686abca2056dc3dd0d813ba2f8b013e98cf009ba168Hans Verkuil return 0; 687b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil} 688b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil#endif 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 690b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuilstatic struct saa7146_ext_vv vv_data; 691b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil 692b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil/* this function only gets called when the probing was successful */ 693b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuilstatic int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) 694b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil{ 69503b1930efd3c2320b1dcba76c8af15f7e454919dHans Verkuil struct mxb *mxb; 696a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 69744d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_EE("dev:%p\n", dev); 698a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 699b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil saa7146_vv_init(dev, &vv_data); 70003b1930efd3c2320b1dcba76c8af15f7e454919dHans Verkuil if (mxb_probe(dev)) { 70103b1930efd3c2320b1dcba76c8af15f7e454919dHans Verkuil saa7146_vv_release(dev); 70203b1930efd3c2320b1dcba76c8af15f7e454919dHans Verkuil return -1; 70303b1930efd3c2320b1dcba76c8af15f7e454919dHans Verkuil } 70403b1930efd3c2320b1dcba76c8af15f7e454919dHans Verkuil mxb = (struct mxb *)dev->ext_priv; 70503b1930efd3c2320b1dcba76c8af15f7e454919dHans Verkuil 706ab49ae0f201f1e7e07250d011fffde8ed2530175Hans Verkuil vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input; 707ab49ae0f201f1e7e07250d011fffde8ed2530175Hans Verkuil vv_data.vid_ops.vidioc_g_input = vidioc_g_input; 708ab49ae0f201f1e7e07250d011fffde8ed2530175Hans Verkuil vv_data.vid_ops.vidioc_s_input = vidioc_s_input; 709313fce750a073b041526f6e595f755f6233f8e73Hans Verkuil vv_data.vid_ops.vidioc_querystd = vidioc_querystd; 710ab49ae0f201f1e7e07250d011fffde8ed2530175Hans Verkuil vv_data.vid_ops.vidioc_g_tuner = vidioc_g_tuner; 711ab49ae0f201f1e7e07250d011fffde8ed2530175Hans Verkuil vv_data.vid_ops.vidioc_s_tuner = vidioc_s_tuner; 712ab49ae0f201f1e7e07250d011fffde8ed2530175Hans Verkuil vv_data.vid_ops.vidioc_g_frequency = vidioc_g_frequency; 713ab49ae0f201f1e7e07250d011fffde8ed2530175Hans Verkuil vv_data.vid_ops.vidioc_s_frequency = vidioc_s_frequency; 714ab49ae0f201f1e7e07250d011fffde8ed2530175Hans Verkuil vv_data.vid_ops.vidioc_enumaudio = vidioc_enumaudio; 715ab49ae0f201f1e7e07250d011fffde8ed2530175Hans Verkuil vv_data.vid_ops.vidioc_g_audio = vidioc_g_audio; 716ab49ae0f201f1e7e07250d011fffde8ed2530175Hans Verkuil vv_data.vid_ops.vidioc_s_audio = vidioc_s_audio; 7172633812f897cc354071699e86ea82e3bfd77cddcHans Verkuil#ifdef CONFIG_VIDEO_ADV_DEBUG 718ab49ae0f201f1e7e07250d011fffde8ed2530175Hans Verkuil vv_data.vid_ops.vidioc_g_register = vidioc_g_register; 719ab49ae0f201f1e7e07250d011fffde8ed2530175Hans Verkuil vv_data.vid_ops.vidioc_s_register = vidioc_s_register; 7202633812f897cc354071699e86ea82e3bfd77cddcHans Verkuil#endif 721b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) { 72244d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches ERR("cannot register capture v4l2 device. skipping.\n"); 72303b1930efd3c2320b1dcba76c8af15f7e454919dHans Verkuil saa7146_vv_release(dev); 724b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil return -1; 725b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil } 726b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil 727b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ 728b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil if (MXB_BOARD_CAN_DO_VBI(dev)) { 729b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) { 73044d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches ERR("cannot register vbi v4l2 device. skipping.\n"); 731b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil } 7321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 733b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil 73444d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches pr_info("found Multimedia eXtension Board #%d\n", mxb_num); 735b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil 736b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil mxb_num++; 737b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil mxb_init_done(dev); 738b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil return 0; 739b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil} 740b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil 741b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuilstatic int mxb_detach(struct saa7146_dev *dev) 742b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil{ 743b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil struct mxb *mxb = (struct mxb *)dev->ext_priv; 744b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil 74544d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_EE("dev:%p\n", dev); 746b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil 747d69f4a517c0a9b0b4795f4604aed8cf96dcd5223Hans Verkuil /* mute audio on tea6420s */ 7486680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil tea6420_route(mxb, 6); 749d69f4a517c0a9b0b4795f4604aed8cf96dcd5223Hans Verkuil 750b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil saa7146_unregister_device(&mxb->video_dev,dev); 751b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil if (MXB_BOARD_CAN_DO_VBI(dev)) 752b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil saa7146_unregister_device(&mxb->vbi_dev, dev); 753b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil saa7146_vv_release(dev); 754b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil 755b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil mxb_num--; 756b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil 757b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil i2c_del_adapter(&mxb->i2c_adapter); 758b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil kfree(mxb); 759b960074fec573fb1b226d9e2686ce51be807cdf1Hans Verkuil 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 763c6eb8eafdba4ad18b4520a0d28a38bc9e61883eaHans Verkuilstatic int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard) 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 765c6eb8eafdba4ad18b4520a0d28a38bc9e61883eaHans Verkuil struct mxb *mxb = (struct mxb *)dev->ext_priv; 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 767c6eb8eafdba4ad18b4520a0d28a38bc9e61883eaHans Verkuil if (V4L2_STD_PAL_I == standard->id) { 7686acaba8e22bb355409e06d9e7ce4e7bef1bcaa04Michael Hunold v4l2_std_id std = V4L2_STD_PAL_I; 769c6eb8eafdba4ad18b4520a0d28a38bc9e61883eaHans Verkuil 77044d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_D("VIDIOC_S_STD: setting mxb for PAL_I\n"); 7714894b709d14c593466cc05e55ee493af931205e8Hans Verkuil /* These two gpio calls set the GPIO pins that control the tda9820 */ 772a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab saa7146_write(dev, GPIO_CTRL, 0x00404050); 7731b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil saa7111a_call(mxb, core, s_gpio, 0); 7748774bed9ce832d8d9ccb79e92800b808aa2d2ad2Laurent Pinchart saa7111a_call(mxb, video, s_std, std); 775d69f4a517c0a9b0b4795f4604aed8cf96dcd5223Hans Verkuil if (mxb->cur_input == 0) 7768774bed9ce832d8d9ccb79e92800b808aa2d2ad2Laurent Pinchart tuner_call(mxb, video, s_std, std); 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 7786acaba8e22bb355409e06d9e7ce4e7bef1bcaa04Michael Hunold v4l2_std_id std = V4L2_STD_PAL_BG; 779c6eb8eafdba4ad18b4520a0d28a38bc9e61883eaHans Verkuil 780d69f4a517c0a9b0b4795f4604aed8cf96dcd5223Hans Verkuil if (mxb->cur_input) 781d69f4a517c0a9b0b4795f4604aed8cf96dcd5223Hans Verkuil std = standard->id; 78244d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_D("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM\n"); 7834894b709d14c593466cc05e55ee493af931205e8Hans Verkuil /* These two gpio calls set the GPIO pins that control the tda9820 */ 784a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab saa7146_write(dev, GPIO_CTRL, 0x00404050); 7851b8dac150a01e2312d8e3fedd6462a0ec34c96d0Hans Verkuil saa7111a_call(mxb, core, s_gpio, 1); 7868774bed9ce832d8d9ccb79e92800b808aa2d2ad2Laurent Pinchart saa7111a_call(mxb, video, s_std, std); 787d69f4a517c0a9b0b4795f4604aed8cf96dcd5223Hans Verkuil if (mxb->cur_input == 0) 7888774bed9ce832d8d9ccb79e92800b808aa2d2ad2Laurent Pinchart tuner_call(mxb, video, s_std, std); 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct saa7146_standard standard[] = { 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "PAL-BG", .id = V4L2_STD_PAL_BG, 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .v_offset = 0x17, .v_field = 288, 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .h_offset = 0x14, .h_pixels = 680, 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .v_max_out = 576, .h_max_out = 768, 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, { 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "PAL-I", .id = V4L2_STD_PAL_I, 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .v_offset = 0x17, .v_field = 288, 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .h_offset = 0x14, .h_pixels = 680, 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .v_max_out = 576, .h_max_out = 768, 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, { 8051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "NTSC", .id = V4L2_STD_NTSC, 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .v_offset = 0x16, .v_field = 240, 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .h_offset = 0x06, .h_pixels = 708, 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .v_max_out = 480, .h_max_out = 640, 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, { 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "SECAM", .id = V4L2_STD_SECAM, 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .v_offset = 0x14, .v_field = 288, 8121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .h_offset = 0x14, .h_pixels = 720, 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .v_max_out = 576, .h_max_out = 768, 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct saa7146_pci_extension_data mxb = { 818a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab .ext_priv = "Multimedia eXtension Board", 819a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab .ext = &extension, 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 8211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pci_device_id pci_tbl[] = { 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .vendor = PCI_VENDOR_ID_PHILIPS, 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .device = PCI_DEVICE_ID_PHILIPS_SAA7146, 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .subvendor = 0x0000, 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .subdevice = 0x0000, 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .driver_data = (unsigned long)&mxb, 8291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, { 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .vendor = 0, 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 8331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DEVICE_TABLE(pci, pci_tbl); 8351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct saa7146_ext_vv vv_data = { 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .inputs = MXB_INPUTS, 8386e65ca942b9664a987866ac0c62e7e450777056bHans Verkuil .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_AUDIO, 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .stds = &standard[0], 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), 841a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab .std_callback = &std_callback, 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct saa7146_extension extension = { 8456680427791c94e611220a6cb34ae47dac9e3aa98Hans Verkuil .name = "Multimedia eXtension Board", 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .flags = SAA7146_USE_I2C_IRQ, 847a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 8481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .pci_tbl = &pci_tbl[0], 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .module = THIS_MODULE, 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .attach = mxb_attach, 8521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .detach = mxb_detach, 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .irq_mask = 0, 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .irq_func = NULL, 856a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab}; 8571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init mxb_init_module(void) 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8602633812f897cc354071699e86ea82e3bfd77cddcHans Verkuil if (saa7146_register_extension(&extension)) { 86144d0b80e5ff741d502a6ccc8685a18bda1ac9da4Joe Perches DEB_S("failed to register extension\n"); 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENODEV; 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 864a8733ca5141c256322ab5ea9fd3074942a209bbaMauro Carvalho Chehab 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit mxb_cleanup_module(void) 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds saa7146_unregister_extension(&extension); 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(mxb_init_module); 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(mxb_cleanup_module); 8751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'"); 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Michael Hunold <michael@mihu.de>"); 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 879