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