V4L/DVB: saa7146_vv: fix regression where v4l2_device was registered too late
[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
LT
5
6 Visit http://www.mihu.de/linux/saa7146/mxb/
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;
cd7d9beb 172 int err;
1da177e4 173
cd7d9beb
HV
174 err = saa7146_vv_devinit(dev);
175 if (err)
176 return err;
7408187d 177 mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
1b8dac15 178 if (mxb == NULL) {
1da177e4
LT
179 DEB_D(("not enough kernel memory.\n"));
180 return -ENOMEM;
181 }
1da177e4 182
9ebeae56
HV
183 snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num);
184
1da177e4 185 saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
1b8dac15 186 if (i2c_add_adapter(&mxb->i2c_adapter) < 0) {
1da177e4
LT
187 DEB_S(("cannot register i2c-device. skipping.\n"));
188 kfree(mxb);
189 return -EFAULT;
190 }
191
e6574f2f 192 mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
53dacb15 193 "saa7115", "saa7111", I2C_SAA7111A, NULL);
e6574f2f 194 mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
53dacb15 195 "tea6420", "tea6420", I2C_TEA6420_1, NULL);
e6574f2f 196 mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
53dacb15 197 "tea6420", "tea6420", I2C_TEA6420_2, NULL);
e6574f2f 198 mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
53dacb15 199 "tea6415c", "tea6415c", I2C_TEA6415C, NULL);
e6574f2f 200 mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
53dacb15 201 "tda9840", "tda9840", I2C_TDA9840, NULL);
e6574f2f 202 mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
53dacb15 203 "tuner", "tuner", I2C_TUNER, NULL);
e6574f2f 204 if (v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
53dacb15 205 "saa5246a", "saa5246a", I2C_SAA5246A, NULL)) {
1b8dac15
HV
206 printk(KERN_INFO "mxb: found teletext decoder\n");
207 }
1da177e4
LT
208
209 /* check if all devices are present */
5fa1247a
AV
210 if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
211 !mxb->tda9840 || !mxb->saa7111a || !mxb->tuner) {
1da177e4
LT
212 printk("mxb: did not find all i2c devices. aborting\n");
213 i2c_del_adapter(&mxb->i2c_adapter);
214 kfree(mxb);
215 return -ENODEV;
216 }
217
a8733ca5 218 /* all devices are present, probe was successful */
1da177e4
LT
219
220 /* we store the pointer in our private data field */
221 dev->ext_priv = mxb;
222
223 return 0;
224}
225
a8733ca5 226/* some init data for the saa7740, the so-called 'sound arena module'.
1da177e4
LT
227 there are no specs available, so we simply use some init values */
228static struct {
229 int length;
230 char data[9];
231} mxb_saa7740_init[] = {
232 { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
233 { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
234 { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
235 { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
236 { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
237 { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
238 { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
239 { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
240 { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
241 { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
242 { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
243 { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
244 { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
245 { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
246 { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
247 { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
248 { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
249 { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
250 { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
251 { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
252 { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
253 { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
254 { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
255 { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
256 { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
257 { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
258 { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
259 { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
260 { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
261 { 3, { 0x48, 0x00, 0x01 } },
262 { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
263 { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
264 { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
265 { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
266 { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
267 { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
268 { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
269 { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
270 { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
271 { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
272 { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
273 { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
274 { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
275 { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
276 { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
277 { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
278 { 3, { 0x80, 0xb3, 0x0a } },
2633812f 279 {-1, { 0 } }
1da177e4
LT
280};
281
1da177e4
LT
282/* bring hardware to a sane state. this has to be done, just in case someone
283 wants to capture from this device before it has been properly initialized.
284 the capture engine would badly fail, because no valid signal arrives on the
285 saa7146, thus leading to timeouts and stuff. */
286static int mxb_init_done(struct saa7146_dev* dev)
287{
288 struct mxb* mxb = (struct mxb*)dev->ext_priv;
1da177e4 289 struct i2c_msg msg;
85369df3 290 struct tuner_setup tun_setup;
6acaba8e 291 v4l2_std_id std = V4L2_STD_PAL_BG;
1da177e4
LT
292
293 int i = 0, err = 0;
1da177e4
LT
294
295 /* select video mode in saa7111a */
f41737ec 296 saa7111a_call(mxb, core, s_std, std);
1da177e4
LT
297
298 /* select tuner-output on saa7111a */
299 i = 0;
5325b427
HV
300 saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
301 SAA7111_FMT_CCIR | SAA7111_VBI_BYPASS, 0);
1da177e4
LT
302
303 /* select a tuner type */
85369df3
MCC
304 tun_setup.mode_mask = T_ANALOG_TV;
305 tun_setup.addr = ADDR_UNSET;
9d2599d9 306 tun_setup.type = TUNER_PHILIPS_PAL;
1b8dac15 307 tuner_call(mxb, tuner, s_type_addr, &tun_setup);
9d2599d9
MH
308 /* tune in some frequency on tuner */
309 mxb->cur_freq.tuner = 0;
310 mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
311 mxb->cur_freq.frequency = freq;
1b8dac15 312 tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
9d2599d9 313
6acaba8e 314 /* set a default video standard */
f41737ec 315 tuner_call(mxb, core, s_std, std);
6acaba8e 316
1da177e4 317 /* mute audio on tea6420s */
5325b427
HV
318 tea6420_route_line(mxb, 6);
319 tea6420_route_cd(mxb, 6);
1da177e4 320
1b8dac15 321 /* switch to tuner-channel on tea6415c */
5325b427 322 tea6415c_call(mxb, video, s_routing, 3, 17, 0);
1da177e4 323
1b8dac15 324 /* select tuner-output on multicable on tea6415c */
5325b427 325 tea6415c_call(mxb, video, s_routing, 3, 13, 0);
a8733ca5 326
1da177e4
LT
327 /* the rest for mxb */
328 mxb->cur_input = 0;
1da177e4
LT
329 mxb->cur_mute = 1;
330
331 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
a8733ca5 332
1da177e4 333 /* check if the saa7740 (aka 'sound arena module') is present
a8733ca5 334 on the mxb. if so, we must initialize it. due to lack of
1da177e4
LT
335 informations about the saa7740, the values were reverse
336 engineered. */
337 msg.addr = 0x1b;
338 msg.flags = 0;
339 msg.len = mxb_saa7740_init[0].length;
340 msg.buf = &mxb_saa7740_init[0].data[0];
341
2633812f
HV
342 err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
343 if (err == 1) {
1da177e4
LT
344 /* the sound arena module is a pos, that's probably the reason
345 philips refuses to hand out a datasheet for the saa7740...
346 it seems to screw up the i2c bus, so we disable fast irq
347 based i2c transactions here and rely on the slow and safe
348 polling method ... */
349 extension.flags &= ~SAA7146_USE_I2C_IRQ;
2633812f
HV
350 for (i = 1; ; i++) {
351 if (-1 == mxb_saa7740_init[i].length)
1da177e4 352 break;
1da177e4 353
a8733ca5 354 msg.len = mxb_saa7740_init[i].length;
1da177e4 355 msg.buf = &mxb_saa7740_init[i].data[0];
2633812f
HV
356 err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
357 if (err != 1) {
1da177e4
LT
358 DEB_D(("failed to initialize 'sound arena module'.\n"));
359 goto err;
360 }
361 }
362 INFO(("'sound arena module' detected.\n"));
363 }
a8733ca5 364err:
1da177e4
LT
365 /* the rest for saa7146: you should definitely set some basic values
366 for the input-port handling of the saa7146. */
367
368 /* ext->saa has been filled by the core driver */
a8733ca5 369
1da177e4 370 /* some stuff is done via variables */
2633812f
HV
371 saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source,
372 input_port_selection[mxb->cur_input].hps_sync);
1da177e4
LT
373
374 /* some stuff is done via direct write to the registers */
375
376 /* this is ugly, but because of the fact that this is completely
377 hardware dependend, it should be done directly... */
a8733ca5 378 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
1da177e4
LT
379 saa7146_write(dev, DD1_INIT, 0x02000200);
380 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
381
382 return 0;
383}
384
385/* interrupt-handler. this gets called when irq_mask is != 0.
386 it must clear the interrupt-bits in irq_mask it has handled */
387/*
388void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
389{
390 struct mxb* mxb = (struct mxb*)dev->ext_priv;
391}
392*/
393
b960074f 394static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
1da177e4 395{
b960074f
HV
396 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
397 int i;
a8733ca5 398
b960074f
HV
399 for (i = MAXCONTROLS - 1; i >= 0; i--) {
400 if (mxb_controls[i].id == qc->id) {
401 *qc = mxb_controls[i];
402 DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
403 return 0;
404 }
405 }
406 return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
407}
1da177e4 408
b960074f
HV
409static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
410{
411 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
412 struct mxb *mxb = (struct mxb *)dev->ext_priv;
413 int i;
1da177e4 414
b960074f
HV
415 for (i = MAXCONTROLS - 1; i >= 0; i--) {
416 if (mxb_controls[i].id == vc->id)
417 break;
1da177e4 418 }
a8733ca5 419
b960074f
HV
420 if (i < 0)
421 return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
1da177e4 422
b960074f
HV
423 if (vc->id == V4L2_CID_AUDIO_MUTE) {
424 vc->value = mxb->cur_mute;
425 DEB_D(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
426 return 0;
427 }
1da177e4 428
b960074f 429 DEB_EE(("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d.\n", vc->value));
1da177e4
LT
430 return 0;
431}
432
b960074f 433static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
1da177e4 434{
b960074f 435 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
2633812f 436 struct mxb *mxb = (struct mxb *)dev->ext_priv;
b960074f 437 int i = 0;
1da177e4 438
b960074f
HV
439 for (i = MAXCONTROLS - 1; i >= 0; i--) {
440 if (mxb_controls[i].id == vc->id)
441 break;
442 }
1da177e4 443
b960074f
HV
444 if (i < 0)
445 return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
1da177e4 446
b960074f
HV
447 if (vc->id == V4L2_CID_AUDIO_MUTE) {
448 mxb->cur_mute = vc->value;
5325b427
HV
449 /* switch the audio-source */
450 tea6420_route_line(mxb, vc->value ? 6 :
451 video_audio_connect[mxb->cur_input]);
b960074f
HV
452 DEB_EE(("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d.\n", vc->value));
453 }
454 return 0;
455}
1da177e4 456
b960074f
HV
457static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
458{
459 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
223ffe5f 460 if (i->index >= MXB_INPUTS)
b960074f
HV
461 return -EINVAL;
462 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
1da177e4
LT
463 return 0;
464}
465
b960074f 466static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
1da177e4 467{
b960074f 468 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
2633812f 469 struct mxb *mxb = (struct mxb *)dev->ext_priv;
b960074f 470 *i = mxb->cur_input;
a8733ca5 471
b960074f
HV
472 DEB_EE(("VIDIOC_G_INPUT %d.\n", *i));
473 return 0;
474}
a8733ca5 475
b960074f
HV
476static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
477{
478 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
479 struct mxb *mxb = (struct mxb *)dev->ext_priv;
5325b427 480 int err = 0;
b960074f 481 int i = 0;
1da177e4 482
b960074f 483 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
a8733ca5 484
f14a2972 485 if (input >= MXB_INPUTS)
b960074f 486 return -EINVAL;
a8733ca5 487
b960074f 488 mxb->cur_input = input;
a8733ca5 489
b960074f
HV
490 saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
491 input_port_selection[input].hps_sync);
1da177e4 492
b960074f
HV
493 /* prepare switching of tea6415c and saa7111a;
494 have a look at the 'background'-file for further informations */
495 switch (input) {
496 case TUNER:
497 i = SAA7115_COMPOSITE0;
a8733ca5 498
5325b427
HV
499 err = tea6415c_call(mxb, video, s_routing, 3, 17, 0);
500
b960074f 501 /* connect tuner-output always to multicable */
5325b427
HV
502 if (!err)
503 err = tea6415c_call(mxb, video, s_routing, 3, 13, 0);
b960074f
HV
504 break;
505 case AUX3_YC:
506 /* nothing to be done here. aux3_yc is
507 directly connected to the saa711a */
508 i = SAA7115_SVIDEO1;
509 break;
510 case AUX3:
511 /* nothing to be done here. aux3 is
512 directly connected to the saa711a */
513 i = SAA7115_COMPOSITE1;
514 break;
515 case AUX1:
516 i = SAA7115_COMPOSITE0;
5325b427 517 err = tea6415c_call(mxb, video, s_routing, 1, 17, 0);
b960074f
HV
518 break;
519 }
a8733ca5 520
5325b427
HV
521 if (err)
522 return err;
1da177e4 523
b960074f 524 /* switch video in saa7111a */
5325b427 525 if (saa7111a_call(mxb, video, s_routing, i, 0, 0))
b960074f
HV
526 printk(KERN_ERR "VIDIOC_S_INPUT: could not address saa7111a #1.\n");
527
528 /* switch the audio-source only if necessary */
5325b427
HV
529 if (0 == mxb->cur_mute)
530 tea6420_route_line(mxb, video_audio_connect[input]);
1da177e4 531
b960074f
HV
532 return 0;
533}
1da177e4 534
b960074f
HV
535static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
536{
537 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
538 struct mxb *mxb = (struct mxb *)dev->ext_priv;
a8733ca5 539
b960074f
HV
540 if (t->index) {
541 DEB_D(("VIDIOC_G_TUNER: channel %d does not have a tuner attached.\n", t->index));
542 return -EINVAL;
543 }
a8733ca5 544
b960074f 545 DEB_EE(("VIDIOC_G_TUNER: %d\n", t->index));
a8733ca5 546
b960074f 547 memset(t, 0, sizeof(*t));
b960074f
HV
548 strlcpy(t->name, "TV Tuner", sizeof(t->name));
549 t->type = V4L2_TUNER_ANALOG_TV;
550 t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
551 V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
552 t->audmode = mxb->cur_mode;
1b8dac15 553 return call_all(dev, tuner, g_tuner, t);
b960074f 554}
1da177e4 555
b960074f
HV
556static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
557{
558 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
559 struct mxb *mxb = (struct mxb *)dev->ext_priv;
a8733ca5 560
b960074f
HV
561 if (t->index) {
562 DEB_D(("VIDIOC_S_TUNER: channel %d does not have a tuner attached.\n", t->index));
563 return -EINVAL;
564 }
1da177e4 565
b960074f 566 mxb->cur_mode = t->audmode;
1b8dac15 567 return call_all(dev, tuner, s_tuner, t);
b960074f 568}
1da177e4 569
b960074f
HV
570static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
571{
572 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
573 struct mxb *mxb = (struct mxb *)dev->ext_priv;
574
575 if (mxb->cur_input) {
576 DEB_D(("VIDIOC_G_FREQ: channel %d does not have a tuner!\n",
577 mxb->cur_input));
578 return -EINVAL;
1da177e4 579 }
1da177e4 580
b960074f 581 *f = mxb->cur_freq;
1da177e4 582
b960074f
HV
583 DEB_EE(("VIDIOC_G_FREQ: freq:0x%08x.\n", mxb->cur_freq.frequency));
584 return 0;
585}
1da177e4 586
b960074f
HV
587static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
588{
589 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
590 struct mxb *mxb = (struct mxb *)dev->ext_priv;
591 struct saa7146_vv *vv = dev->vv_data;
1da177e4 592
b960074f
HV
593 if (f->tuner)
594 return -EINVAL;
a8733ca5 595
b960074f
HV
596 if (V4L2_TUNER_ANALOG_TV != f->type)
597 return -EINVAL;
a8733ca5 598
b960074f
HV
599 if (mxb->cur_input) {
600 DEB_D(("VIDIOC_S_FREQ: channel %d does not have a tuner!\n", mxb->cur_input));
601 return -EINVAL;
1da177e4 602 }
1da177e4 603
b960074f
HV
604 mxb->cur_freq = *f;
605 DEB_EE(("VIDIOC_S_FREQUENCY: freq:0x%08x.\n", mxb->cur_freq.frequency));
1da177e4 606
b960074f 607 /* tune in desired frequency */
1b8dac15 608 tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
1da177e4 609
b960074f
HV
610 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
611 spin_lock(&dev->slock);
612 vv->vbi_fieldcount = 0;
613 spin_unlock(&dev->slock);
614
615 return 0;
616}
617
618static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
619{
620 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
621 struct mxb *mxb = (struct mxb *)dev->ext_priv;
622
223ffe5f 623 if (a->index > MXB_INPUTS) {
b960074f
HV
624 DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
625 return -EINVAL;
1da177e4 626 }
1da177e4 627
b960074f
HV
628 DEB_EE(("VIDIOC_G_AUDIO %d.\n", a->index));
629 memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
630 return 0;
631}
1da177e4 632
b960074f
HV
633static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
634{
635 DEB_D(("VIDIOC_S_AUDIO %d.\n", a->index));
636 return 0;
637}
a8733ca5 638
b960074f
HV
639#ifdef CONFIG_VIDEO_ADV_DEBUG
640static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
641{
642 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1da177e4 643
1b8dac15 644 return call_all(dev, core, g_register, reg);
b960074f 645}
1da177e4 646
b960074f
HV
647static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
648{
649 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1da177e4 650
1b8dac15 651 return call_all(dev, core, s_register, reg);
b960074f
HV
652}
653#endif
1da177e4 654
b960074f
HV
655static long vidioc_default(struct file *file, void *fh, int cmd, void *arg)
656{
657 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
658 struct mxb *mxb = (struct mxb *)dev->ext_priv;
659
660 switch (cmd) {
1da177e4
LT
661 case MXB_S_AUDIO_CD:
662 {
b960074f 663 int i = *(int *)arg;
a8733ca5 664
2633812f 665 if (i < 0 || i >= MXB_AUDIOS) {
b960074f 666 DEB_D(("illegal argument to MXB_S_AUDIO_CD: i:%d.\n", i));
1da177e4
LT
667 return -EINVAL;
668 }
a8733ca5 669
b960074f 670 DEB_EE(("MXB_S_AUDIO_CD: i:%d.\n", i));
1da177e4 671
5325b427 672 tea6420_route_cd(mxb, i);
1da177e4
LT
673 return 0;
674 }
675 case MXB_S_AUDIO_LINE:
676 {
b960074f 677 int i = *(int *)arg;
a8733ca5 678
2633812f 679 if (i < 0 || i >= MXB_AUDIOS) {
b960074f 680 DEB_D(("illegal argument to MXB_S_AUDIO_LINE: i:%d.\n", i));
1da177e4
LT
681 return -EINVAL;
682 }
a8733ca5 683
b960074f 684 DEB_EE(("MXB_S_AUDIO_LINE: i:%d.\n", i));
5325b427 685 tea6420_route_line(mxb, i);
1da177e4
LT
686 return 0;
687 }
b960074f
HV
688 default:
689/*
690 DEB2(printk("does not handle this ioctl.\n"));
691*/
692 return -ENOIOCTLCMD;
693 }
694 return 0;
695}
1da177e4 696
b960074f
HV
697static struct saa7146_ext_vv vv_data;
698
699/* this function only gets called when the probing was successful */
700static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
701{
702 struct mxb *mxb = (struct mxb *)dev->ext_priv;
a8733ca5 703
b960074f 704 DEB_EE(("dev:%p\n", dev));
a8733ca5 705
b960074f
HV
706 /* checking for i2c-devices can be omitted here, because we
707 already did this in "mxb_vl42_probe" */
2633812f 708
b960074f
HV
709 saa7146_vv_init(dev, &vv_data);
710 vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
711 vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
712 vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
713 vv_data.ops.vidioc_enum_input = vidioc_enum_input;
714 vv_data.ops.vidioc_g_input = vidioc_g_input;
715 vv_data.ops.vidioc_s_input = vidioc_s_input;
716 vv_data.ops.vidioc_g_tuner = vidioc_g_tuner;
717 vv_data.ops.vidioc_s_tuner = vidioc_s_tuner;
718 vv_data.ops.vidioc_g_frequency = vidioc_g_frequency;
719 vv_data.ops.vidioc_s_frequency = vidioc_s_frequency;
720 vv_data.ops.vidioc_g_audio = vidioc_g_audio;
721 vv_data.ops.vidioc_s_audio = vidioc_s_audio;
2633812f 722#ifdef CONFIG_VIDEO_ADV_DEBUG
b960074f
HV
723 vv_data.ops.vidioc_g_register = vidioc_g_register;
724 vv_data.ops.vidioc_s_register = vidioc_s_register;
2633812f 725#endif
b960074f
HV
726 vv_data.ops.vidioc_default = vidioc_default;
727 if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
728 ERR(("cannot register capture v4l2 device. skipping.\n"));
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
849 .probe = mxb_probe,
850 .attach = mxb_attach,
851 .detach = mxb_detach,
852
853 .irq_mask = 0,
854 .irq_func = NULL,
a8733ca5 855};
1da177e4
LT
856
857static int __init mxb_init_module(void)
858{
2633812f 859 if (saa7146_register_extension(&extension)) {
1da177e4
LT
860 DEB_S(("failed to register extension.\n"));
861 return -ENODEV;
862 }
a8733ca5 863
1da177e4
LT
864 return 0;
865}
866
867static void __exit mxb_cleanup_module(void)
868{
869 saa7146_unregister_extension(&extension);
870}
871
872module_init(mxb_init_module);
873module_exit(mxb_cleanup_module);
874
875MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
876MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
877MODULE_LICENSE("GPL");
This page took 0.792592 seconds and 5 git commands to generate.