2 mxb - v4l2 driver for the Multimedia eXtension Board
4 Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de>
6 Visit http://www.themm.net/~mihu/linux/saa7146/mxb.html
7 for further details about this card.
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.
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.
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.
24 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
26 #define DEBUG_VARIABLE debug
28 #include <media/saa7146_vv.h>
29 #include <media/tuner.h>
30 #include <media/v4l2-common.h>
31 #include <media/saa7115.h>
32 #include <linux/module.h>
39 #define I2C_SAA7111A 0x24
40 #define I2C_TDA9840 0x42
41 #define I2C_TEA6415C 0x43
42 #define I2C_TEA6420_1 0x4c
43 #define I2C_TEA6420_2 0x4d
44 #define I2C_TUNER 0x60
46 #define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
51 /* initial frequence the tuner will be tuned to.
52 in verden (lower saxony, germany) 4148 is a
53 channel called "phoenix" */
54 static int freq
= 4148;
55 module_param(freq
, int, 0644);
56 MODULE_PARM_DESC(freq
, "initial frequency the tuner will be tuned to while setup");
59 module_param(debug
, int, 0644);
60 MODULE_PARM_DESC(debug
, "Turn on/off device debugging (default:off).");
63 enum { TUNER
, AUX1
, AUX3
, AUX3_YC
};
65 static struct v4l2_input mxb_inputs
[MXB_INPUTS
] = {
66 { TUNER
, "Tuner", V4L2_INPUT_TYPE_TUNER
, 0x2f, 0,
67 V4L2_STD_PAL_BG
| V4L2_STD_PAL_I
, 0, V4L2_IN_CAP_STD
},
68 { AUX1
, "AUX1", V4L2_INPUT_TYPE_CAMERA
, 0x2f, 0,
69 V4L2_STD_ALL
, 0, V4L2_IN_CAP_STD
},
70 { AUX3
, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA
, 0x2f, 0,
71 V4L2_STD_ALL
, 0, V4L2_IN_CAP_STD
},
72 { AUX3_YC
, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA
, 0x2f, 0,
73 V4L2_STD_ALL
, 0, V4L2_IN_CAP_STD
},
76 /* this array holds the information, which port of the saa7146 each
77 input actually uses. the mxb uses port 0 for every input */
81 } input_port_selection
[MXB_INPUTS
] = {
82 { SAA7146_HPS_SOURCE_PORT_A
, SAA7146_HPS_SYNC_PORT_A
},
83 { SAA7146_HPS_SOURCE_PORT_A
, SAA7146_HPS_SYNC_PORT_A
},
84 { SAA7146_HPS_SOURCE_PORT_A
, SAA7146_HPS_SYNC_PORT_A
},
85 { SAA7146_HPS_SOURCE_PORT_A
, SAA7146_HPS_SYNC_PORT_A
},
88 /* this array holds the information of the audio source (mxb_audios),
89 which has to be switched corresponding to the video source (mxb_channels) */
90 static int video_audio_connect
[MXB_INPUTS
] =
98 /* these are the available audio sources, which can switched
99 to the line- and cd-output individually */
100 static struct v4l2_audio mxb_audios
[MXB_AUDIOS
] = {
104 .capability
= V4L2_AUDCAP_STEREO
,
108 .capability
= V4L2_AUDCAP_STEREO
,
112 .capability
= V4L2_AUDCAP_STEREO
,
116 .capability
= V4L2_AUDCAP_STEREO
,
119 .name
= "Radio (X9)",
120 .capability
= V4L2_AUDCAP_STEREO
,
123 .name
= "CD-ROM (X10)",
124 .capability
= V4L2_AUDCAP_STEREO
,
128 /* These are the necessary input-output-pins for bringing one audio source
129 (see above) to the CD-output. Note that gain is set to 0 in this table. */
130 static struct mxb_routing TEA6420_cd
[MXB_AUDIOS
+ 1][2] = {
131 { { 1, 1 }, { 1, 1 } }, /* Tuner */
132 { { 5, 1 }, { 6, 1 } }, /* AUX 1 */
133 { { 4, 1 }, { 6, 1 } }, /* AUX 2 */
134 { { 3, 1 }, { 6, 1 } }, /* AUX 3 */
135 { { 1, 1 }, { 3, 1 } }, /* Radio */
136 { { 1, 1 }, { 2, 1 } }, /* CD-Rom */
137 { { 6, 1 }, { 6, 1 } } /* Mute */
140 /* These are the necessary input-output-pins for bringing one audio source
141 (see above) to the line-output. Note that gain is set to 0 in this table. */
142 static struct mxb_routing TEA6420_line
[MXB_AUDIOS
+ 1][2] = {
143 { { 2, 3 }, { 1, 2 } },
144 { { 5, 3 }, { 6, 2 } },
145 { { 4, 3 }, { 6, 2 } },
146 { { 3, 3 }, { 6, 2 } },
147 { { 2, 3 }, { 3, 2 } },
148 { { 2, 3 }, { 2, 2 } },
149 { { 6, 3 }, { 6, 2 } } /* Mute */
154 struct video_device
*video_dev
;
155 struct video_device
*vbi_dev
;
157 struct i2c_adapter i2c_adapter
;
159 struct v4l2_subdev
*saa7111a
;
160 struct v4l2_subdev
*tda9840
;
161 struct v4l2_subdev
*tea6415c
;
162 struct v4l2_subdev
*tuner
;
163 struct v4l2_subdev
*tea6420_1
;
164 struct v4l2_subdev
*tea6420_2
;
166 int cur_mode
; /* current audio mode (mono, stereo, ...) */
167 int cur_input
; /* current input */
168 int cur_audinput
; /* current audio input */
169 int cur_mute
; /* current mute status */
170 struct v4l2_frequency cur_freq
; /* current frequency the tuner is tuned to */
173 #define saa7111a_call(mxb, o, f, args...) \
174 v4l2_subdev_call(mxb->saa7111a, o, f, ##args)
175 #define tda9840_call(mxb, o, f, args...) \
176 v4l2_subdev_call(mxb->tda9840, o, f, ##args)
177 #define tea6415c_call(mxb, o, f, args...) \
178 v4l2_subdev_call(mxb->tea6415c, o, f, ##args)
179 #define tuner_call(mxb, o, f, args...) \
180 v4l2_subdev_call(mxb->tuner, o, f, ##args)
181 #define call_all(dev, o, f, args...) \
182 v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
184 static inline void tea6420_route(struct mxb
*mxb
, int idx
)
186 v4l2_subdev_call(mxb
->tea6420_1
, audio
, s_routing
,
187 TEA6420_cd
[idx
][0].input
, TEA6420_cd
[idx
][0].output
, 0);
188 v4l2_subdev_call(mxb
->tea6420_2
, audio
, s_routing
,
189 TEA6420_cd
[idx
][1].input
, TEA6420_cd
[idx
][1].output
, 0);
190 v4l2_subdev_call(mxb
->tea6420_1
, audio
, s_routing
,
191 TEA6420_line
[idx
][0].input
, TEA6420_line
[idx
][0].output
, 0);
192 v4l2_subdev_call(mxb
->tea6420_2
, audio
, s_routing
,
193 TEA6420_line
[idx
][1].input
, TEA6420_line
[idx
][1].output
, 0);
196 static struct saa7146_extension extension
;
198 static int mxb_s_ctrl(struct v4l2_ctrl
*ctrl
)
200 struct saa7146_dev
*dev
= container_of(ctrl
->handler
,
201 struct saa7146_dev
, ctrl_handler
);
202 struct mxb
*mxb
= dev
->ext_priv
;
205 case V4L2_CID_AUDIO_MUTE
:
206 mxb
->cur_mute
= ctrl
->val
;
207 /* switch the audio-source */
208 tea6420_route(mxb
, ctrl
->val
? 6 :
209 video_audio_connect
[mxb
->cur_input
]);
217 static const struct v4l2_ctrl_ops mxb_ctrl_ops
= {
218 .s_ctrl
= mxb_s_ctrl
,
221 static int mxb_probe(struct saa7146_dev
*dev
)
223 struct v4l2_ctrl_handler
*hdl
= &dev
->ctrl_handler
;
224 struct mxb
*mxb
= NULL
;
226 v4l2_ctrl_new_std(hdl
, &mxb_ctrl_ops
,
227 V4L2_CID_AUDIO_MUTE
, 0, 1, 1, 0);
230 mxb
= kzalloc(sizeof(struct mxb
), GFP_KERNEL
);
232 DEB_D("not enough kernel memory\n");
237 snprintf(mxb
->i2c_adapter
.name
, sizeof(mxb
->i2c_adapter
.name
), "mxb%d", mxb_num
);
239 saa7146_i2c_adapter_prepare(dev
, &mxb
->i2c_adapter
, SAA7146_I2C_BUS_BIT_RATE_480
);
240 if (i2c_add_adapter(&mxb
->i2c_adapter
) < 0) {
241 DEB_S("cannot register i2c-device. skipping.\n");
246 mxb
->saa7111a
= v4l2_i2c_new_subdev(&dev
->v4l2_dev
, &mxb
->i2c_adapter
,
247 "saa7111", I2C_SAA7111A
, NULL
);
248 mxb
->tea6420_1
= v4l2_i2c_new_subdev(&dev
->v4l2_dev
, &mxb
->i2c_adapter
,
249 "tea6420", I2C_TEA6420_1
, NULL
);
250 mxb
->tea6420_2
= v4l2_i2c_new_subdev(&dev
->v4l2_dev
, &mxb
->i2c_adapter
,
251 "tea6420", I2C_TEA6420_2
, NULL
);
252 mxb
->tea6415c
= v4l2_i2c_new_subdev(&dev
->v4l2_dev
, &mxb
->i2c_adapter
,
253 "tea6415c", I2C_TEA6415C
, NULL
);
254 mxb
->tda9840
= v4l2_i2c_new_subdev(&dev
->v4l2_dev
, &mxb
->i2c_adapter
,
255 "tda9840", I2C_TDA9840
, NULL
);
256 mxb
->tuner
= v4l2_i2c_new_subdev(&dev
->v4l2_dev
, &mxb
->i2c_adapter
,
257 "tuner", I2C_TUNER
, NULL
);
259 /* check if all devices are present */
260 if (!mxb
->tea6420_1
|| !mxb
->tea6420_2
|| !mxb
->tea6415c
||
261 !mxb
->tda9840
|| !mxb
->saa7111a
|| !mxb
->tuner
) {
262 pr_err("did not find all i2c devices. aborting\n");
263 i2c_del_adapter(&mxb
->i2c_adapter
);
268 /* all devices are present, probe was successful */
270 /* we store the pointer in our private data field */
273 v4l2_ctrl_handler_setup(hdl
);
278 /* some init data for the saa7740, the so-called 'sound arena module'.
279 there are no specs available, so we simply use some init values */
283 } mxb_saa7740_init
[] = {
284 { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
285 { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
286 { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
287 { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
288 { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
289 { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
290 { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
291 { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
292 { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
293 { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
294 { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
295 { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
296 { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
297 { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
298 { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
299 { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
300 { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
301 { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
302 { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
303 { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
304 { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
305 { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
306 { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
307 { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
308 { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
309 { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
310 { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
311 { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
312 { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
313 { 3, { 0x48, 0x00, 0x01 } },
314 { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
315 { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
316 { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
317 { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
318 { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
319 { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
320 { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
321 { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
322 { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
323 { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
324 { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
325 { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
326 { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
327 { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
328 { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
329 { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
330 { 3, { 0x80, 0xb3, 0x0a } },
334 /* bring hardware to a sane state. this has to be done, just in case someone
335 wants to capture from this device before it has been properly initialized.
336 the capture engine would badly fail, because no valid signal arrives on the
337 saa7146, thus leading to timeouts and stuff. */
338 static int mxb_init_done(struct saa7146_dev
* dev
)
340 struct mxb
* mxb
= (struct mxb
*)dev
->ext_priv
;
342 struct tuner_setup tun_setup
;
343 v4l2_std_id std
= V4L2_STD_PAL_BG
;
347 /* select video mode in saa7111a */
348 saa7111a_call(mxb
, core
, s_std
, std
);
350 /* select tuner-output on saa7111a */
352 saa7111a_call(mxb
, video
, s_routing
, SAA7115_COMPOSITE0
,
353 SAA7111_FMT_CCIR
, 0);
355 /* select a tuner type */
356 tun_setup
.mode_mask
= T_ANALOG_TV
;
357 tun_setup
.addr
= ADDR_UNSET
;
358 tun_setup
.type
= TUNER_PHILIPS_PAL
;
359 tuner_call(mxb
, tuner
, s_type_addr
, &tun_setup
);
360 /* tune in some frequency on tuner */
361 mxb
->cur_freq
.tuner
= 0;
362 mxb
->cur_freq
.type
= V4L2_TUNER_ANALOG_TV
;
363 mxb
->cur_freq
.frequency
= freq
;
364 tuner_call(mxb
, tuner
, s_frequency
, &mxb
->cur_freq
);
366 /* set a default video standard */
367 tuner_call(mxb
, core
, s_std
, std
);
369 /* mute audio on tea6420s */
370 tea6420_route(mxb
, 6);
372 /* switch to tuner-channel on tea6415c */
373 tea6415c_call(mxb
, video
, s_routing
, 3, 17, 0);
375 /* select tuner-output on multicable on tea6415c */
376 tea6415c_call(mxb
, video
, s_routing
, 3, 13, 0);
378 /* the rest for mxb */
380 mxb
->cur_audinput
= video_audio_connect
[mxb
->cur_input
];
383 mxb
->cur_mode
= V4L2_TUNER_MODE_STEREO
;
385 /* check if the saa7740 (aka 'sound arena module') is present
386 on the mxb. if so, we must initialize it. due to lack of
387 informations about the saa7740, the values were reverse
391 msg
.len
= mxb_saa7740_init
[0].length
;
392 msg
.buf
= &mxb_saa7740_init
[0].data
[0];
394 err
= i2c_transfer(&mxb
->i2c_adapter
, &msg
, 1);
396 /* the sound arena module is a pos, that's probably the reason
397 philips refuses to hand out a datasheet for the saa7740...
398 it seems to screw up the i2c bus, so we disable fast irq
399 based i2c transactions here and rely on the slow and safe
400 polling method ... */
401 extension
.flags
&= ~SAA7146_USE_I2C_IRQ
;
403 if (-1 == mxb_saa7740_init
[i
].length
)
406 msg
.len
= mxb_saa7740_init
[i
].length
;
407 msg
.buf
= &mxb_saa7740_init
[i
].data
[0];
408 err
= i2c_transfer(&mxb
->i2c_adapter
, &msg
, 1);
410 DEB_D("failed to initialize 'sound arena module'\n");
414 pr_info("'sound arena module' detected\n");
417 /* the rest for saa7146: you should definitely set some basic values
418 for the input-port handling of the saa7146. */
420 /* ext->saa has been filled by the core driver */
422 /* some stuff is done via variables */
423 saa7146_set_hps_source_and_sync(dev
, input_port_selection
[mxb
->cur_input
].hps_source
,
424 input_port_selection
[mxb
->cur_input
].hps_sync
);
426 /* some stuff is done via direct write to the registers */
428 /* this is ugly, but because of the fact that this is completely
429 hardware dependend, it should be done directly... */
430 saa7146_write(dev
, DD1_STREAM_B
, 0x00000000);
431 saa7146_write(dev
, DD1_INIT
, 0x02000200);
432 saa7146_write(dev
, MC2
, (MASK_09
| MASK_25
| MASK_10
| MASK_26
));
437 /* interrupt-handler. this gets called when irq_mask is != 0.
438 it must clear the interrupt-bits in irq_mask it has handled */
440 void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
442 struct mxb* mxb = (struct mxb*)dev->ext_priv;
446 static int vidioc_enum_input(struct file
*file
, void *fh
, struct v4l2_input
*i
)
448 DEB_EE("VIDIOC_ENUMINPUT %d\n", i
->index
);
449 if (i
->index
>= MXB_INPUTS
)
451 memcpy(i
, &mxb_inputs
[i
->index
], sizeof(struct v4l2_input
));
455 static int vidioc_g_input(struct file
*file
, void *fh
, unsigned int *i
)
457 struct saa7146_dev
*dev
= ((struct saa7146_fh
*)fh
)->dev
;
458 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
461 DEB_EE("VIDIOC_G_INPUT %d\n", *i
);
465 static int vidioc_s_input(struct file
*file
, void *fh
, unsigned int input
)
467 struct saa7146_dev
*dev
= ((struct saa7146_fh
*)fh
)->dev
;
468 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
472 DEB_EE("VIDIOC_S_INPUT %d\n", input
);
474 if (input
>= MXB_INPUTS
)
477 mxb
->cur_input
= input
;
479 saa7146_set_hps_source_and_sync(dev
, input_port_selection
[input
].hps_source
,
480 input_port_selection
[input
].hps_sync
);
482 /* prepare switching of tea6415c and saa7111a;
483 have a look at the 'background'-file for further informations */
486 i
= SAA7115_COMPOSITE0
;
488 err
= tea6415c_call(mxb
, video
, s_routing
, 3, 17, 0);
490 /* connect tuner-output always to multicable */
492 err
= tea6415c_call(mxb
, video
, s_routing
, 3, 13, 0);
495 /* nothing to be done here. aux3_yc is
496 directly connected to the saa711a */
500 /* nothing to be done here. aux3 is
501 directly connected to the saa711a */
502 i
= SAA7115_COMPOSITE1
;
505 i
= SAA7115_COMPOSITE0
;
506 err
= tea6415c_call(mxb
, video
, s_routing
, 1, 17, 0);
513 /* switch video in saa7111a */
514 if (saa7111a_call(mxb
, video
, s_routing
, i
, SAA7111_FMT_CCIR
, 0))
515 pr_err("VIDIOC_S_INPUT: could not address saa7111a\n");
517 mxb
->cur_audinput
= video_audio_connect
[input
];
518 /* switch the audio-source only if necessary */
519 if (0 == mxb
->cur_mute
)
520 tea6420_route(mxb
, mxb
->cur_audinput
);
525 static int vidioc_g_tuner(struct file
*file
, void *fh
, struct v4l2_tuner
*t
)
527 struct saa7146_dev
*dev
= ((struct saa7146_fh
*)fh
)->dev
;
528 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
531 DEB_D("VIDIOC_G_TUNER: channel %d does not have a tuner attached\n",
536 DEB_EE("VIDIOC_G_TUNER: %d\n", t
->index
);
538 memset(t
, 0, sizeof(*t
));
539 strlcpy(t
->name
, "TV Tuner", sizeof(t
->name
));
540 t
->type
= V4L2_TUNER_ANALOG_TV
;
541 t
->capability
= V4L2_TUNER_CAP_NORM
| V4L2_TUNER_CAP_STEREO
|
542 V4L2_TUNER_CAP_LANG1
| V4L2_TUNER_CAP_LANG2
| V4L2_TUNER_CAP_SAP
;
543 t
->audmode
= mxb
->cur_mode
;
544 return call_all(dev
, tuner
, g_tuner
, t
);
547 static int vidioc_s_tuner(struct file
*file
, void *fh
, struct v4l2_tuner
*t
)
549 struct saa7146_dev
*dev
= ((struct saa7146_fh
*)fh
)->dev
;
550 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
553 DEB_D("VIDIOC_S_TUNER: channel %d does not have a tuner attached\n",
558 mxb
->cur_mode
= t
->audmode
;
559 return call_all(dev
, tuner
, s_tuner
, t
);
562 static int vidioc_g_frequency(struct file
*file
, void *fh
, struct v4l2_frequency
*f
)
564 struct saa7146_dev
*dev
= ((struct saa7146_fh
*)fh
)->dev
;
565 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
571 DEB_EE("VIDIOC_G_FREQ: freq:0x%08x\n", mxb
->cur_freq
.frequency
);
575 static int vidioc_s_frequency(struct file
*file
, void *fh
, struct v4l2_frequency
*f
)
577 struct saa7146_dev
*dev
= ((struct saa7146_fh
*)fh
)->dev
;
578 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
579 struct saa7146_vv
*vv
= dev
->vv_data
;
584 if (V4L2_TUNER_ANALOG_TV
!= f
->type
)
587 DEB_EE("VIDIOC_S_FREQUENCY: freq:0x%08x\n", mxb
->cur_freq
.frequency
);
589 /* tune in desired frequency */
590 tuner_call(mxb
, tuner
, s_frequency
, f
);
591 /* let the tuner subdev clamp the frequency to the tuner range */
592 tuner_call(mxb
, tuner
, g_frequency
, f
);
598 /* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
599 spin_lock(&dev
->slock
);
600 vv
->vbi_fieldcount
= 0;
601 spin_unlock(&dev
->slock
);
606 static int vidioc_enumaudio(struct file
*file
, void *fh
, struct v4l2_audio
*a
)
608 if (a
->index
>= MXB_AUDIOS
)
610 *a
= mxb_audios
[a
->index
];
614 static int vidioc_g_audio(struct file
*file
, void *fh
, struct v4l2_audio
*a
)
616 struct saa7146_dev
*dev
= ((struct saa7146_fh
*)fh
)->dev
;
617 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
619 if (a
->index
> MXB_INPUTS
) {
620 DEB_D("VIDIOC_G_AUDIO %d out of range\n", a
->index
);
624 DEB_EE("VIDIOC_G_AUDIO %d\n", a
->index
);
625 memcpy(a
, &mxb_audios
[video_audio_connect
[mxb
->cur_audinput
]], sizeof(struct v4l2_audio
));
629 static int vidioc_s_audio(struct file
*file
, void *fh
, struct v4l2_audio
*a
)
631 struct saa7146_dev
*dev
= ((struct saa7146_fh
*)fh
)->dev
;
632 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
634 DEB_D("VIDIOC_S_AUDIO %d\n", a
->index
);
635 if (mxb_inputs
[mxb
->cur_input
].audioset
& (1 << a
->index
)) {
636 if (mxb
->cur_audinput
!= a
->index
) {
637 mxb
->cur_audinput
= a
->index
;
638 tea6420_route(mxb
, a
->index
);
645 #ifdef CONFIG_VIDEO_ADV_DEBUG
646 static int vidioc_g_register(struct file
*file
, void *fh
, struct v4l2_dbg_register
*reg
)
648 struct saa7146_dev
*dev
= ((struct saa7146_fh
*)fh
)->dev
;
650 return call_all(dev
, core
, g_register
, reg
);
653 static int vidioc_s_register(struct file
*file
, void *fh
, struct v4l2_dbg_register
*reg
)
655 struct saa7146_dev
*dev
= ((struct saa7146_fh
*)fh
)->dev
;
657 return call_all(dev
, core
, s_register
, reg
);
661 static struct saa7146_ext_vv vv_data
;
663 /* this function only gets called when the probing was successful */
664 static int mxb_attach(struct saa7146_dev
*dev
, struct saa7146_pci_extension_data
*info
)
668 DEB_EE("dev:%p\n", dev
);
670 saa7146_vv_init(dev
, &vv_data
);
671 if (mxb_probe(dev
)) {
672 saa7146_vv_release(dev
);
675 mxb
= (struct mxb
*)dev
->ext_priv
;
677 vv_data
.ops
.vidioc_enum_input
= vidioc_enum_input
;
678 vv_data
.ops
.vidioc_g_input
= vidioc_g_input
;
679 vv_data
.ops
.vidioc_s_input
= vidioc_s_input
;
680 vv_data
.ops
.vidioc_g_tuner
= vidioc_g_tuner
;
681 vv_data
.ops
.vidioc_s_tuner
= vidioc_s_tuner
;
682 vv_data
.ops
.vidioc_g_frequency
= vidioc_g_frequency
;
683 vv_data
.ops
.vidioc_s_frequency
= vidioc_s_frequency
;
684 vv_data
.ops
.vidioc_enumaudio
= vidioc_enumaudio
;
685 vv_data
.ops
.vidioc_g_audio
= vidioc_g_audio
;
686 vv_data
.ops
.vidioc_s_audio
= vidioc_s_audio
;
687 #ifdef CONFIG_VIDEO_ADV_DEBUG
688 vv_data
.ops
.vidioc_g_register
= vidioc_g_register
;
689 vv_data
.ops
.vidioc_s_register
= vidioc_s_register
;
691 if (saa7146_register_device(&mxb
->video_dev
, dev
, "mxb", VFL_TYPE_GRABBER
)) {
692 ERR("cannot register capture v4l2 device. skipping.\n");
693 saa7146_vv_release(dev
);
697 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
698 if (MXB_BOARD_CAN_DO_VBI(dev
)) {
699 if (saa7146_register_device(&mxb
->vbi_dev
, dev
, "mxb", VFL_TYPE_VBI
)) {
700 ERR("cannot register vbi v4l2 device. skipping.\n");
704 pr_info("found Multimedia eXtension Board #%d\n", mxb_num
);
711 static int mxb_detach(struct saa7146_dev
*dev
)
713 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
715 DEB_EE("dev:%p\n", dev
);
717 /* mute audio on tea6420s */
718 tea6420_route(mxb
, 6);
720 saa7146_unregister_device(&mxb
->video_dev
,dev
);
721 if (MXB_BOARD_CAN_DO_VBI(dev
))
722 saa7146_unregister_device(&mxb
->vbi_dev
, dev
);
723 saa7146_vv_release(dev
);
727 i2c_del_adapter(&mxb
->i2c_adapter
);
733 static int std_callback(struct saa7146_dev
*dev
, struct saa7146_standard
*standard
)
735 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
737 if (V4L2_STD_PAL_I
== standard
->id
) {
738 v4l2_std_id std
= V4L2_STD_PAL_I
;
740 DEB_D("VIDIOC_S_STD: setting mxb for PAL_I\n");
741 /* set the 7146 gpio register -- I don't know what this does exactly */
742 saa7146_write(dev
, GPIO_CTRL
, 0x00404050);
743 /* unset the 7111 gpio register -- I don't know what this does exactly */
744 saa7111a_call(mxb
, core
, s_gpio
, 0);
745 saa7111a_call(mxb
, core
, s_std
, std
);
746 if (mxb
->cur_input
== 0)
747 tuner_call(mxb
, core
, s_std
, std
);
749 v4l2_std_id std
= V4L2_STD_PAL_BG
;
753 DEB_D("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM\n");
754 /* set the 7146 gpio register -- I don't know what this does exactly */
755 saa7146_write(dev
, GPIO_CTRL
, 0x00404050);
756 /* set the 7111 gpio register -- I don't know what this does exactly */
757 saa7111a_call(mxb
, core
, s_gpio
, 1);
758 saa7111a_call(mxb
, core
, s_std
, std
);
759 if (mxb
->cur_input
== 0)
760 tuner_call(mxb
, core
, s_std
, std
);
765 static struct saa7146_standard standard
[] = {
767 .name
= "PAL-BG", .id
= V4L2_STD_PAL_BG
,
768 .v_offset
= 0x17, .v_field
= 288,
769 .h_offset
= 0x14, .h_pixels
= 680,
770 .v_max_out
= 576, .h_max_out
= 768,
772 .name
= "PAL-I", .id
= V4L2_STD_PAL_I
,
773 .v_offset
= 0x17, .v_field
= 288,
774 .h_offset
= 0x14, .h_pixels
= 680,
775 .v_max_out
= 576, .h_max_out
= 768,
777 .name
= "NTSC", .id
= V4L2_STD_NTSC
,
778 .v_offset
= 0x16, .v_field
= 240,
779 .h_offset
= 0x06, .h_pixels
= 708,
780 .v_max_out
= 480, .h_max_out
= 640,
782 .name
= "SECAM", .id
= V4L2_STD_SECAM
,
783 .v_offset
= 0x14, .v_field
= 288,
784 .h_offset
= 0x14, .h_pixels
= 720,
785 .v_max_out
= 576, .h_max_out
= 768,
789 static struct saa7146_pci_extension_data mxb
= {
790 .ext_priv
= "Multimedia eXtension Board",
794 static struct pci_device_id pci_tbl
[] = {
796 .vendor
= PCI_VENDOR_ID_PHILIPS
,
797 .device
= PCI_DEVICE_ID_PHILIPS_SAA7146
,
800 .driver_data
= (unsigned long)&mxb
,
806 MODULE_DEVICE_TABLE(pci
, pci_tbl
);
808 static struct saa7146_ext_vv vv_data
= {
809 .inputs
= MXB_INPUTS
,
810 .capabilities
= V4L2_CAP_TUNER
| V4L2_CAP_VBI_CAPTURE
| V4L2_CAP_AUDIO
,
811 .stds
= &standard
[0],
812 .num_stds
= sizeof(standard
)/sizeof(struct saa7146_standard
),
813 .std_callback
= &std_callback
,
816 static struct saa7146_extension extension
= {
817 .name
= "Multimedia eXtension Board",
818 .flags
= SAA7146_USE_I2C_IRQ
,
820 .pci_tbl
= &pci_tbl
[0],
821 .module
= THIS_MODULE
,
823 .attach
= mxb_attach
,
824 .detach
= mxb_detach
,
830 static int __init
mxb_init_module(void)
832 if (saa7146_register_extension(&extension
)) {
833 DEB_S("failed to register extension\n");
840 static void __exit
mxb_cleanup_module(void)
842 saa7146_unregister_extension(&extension
);
845 module_init(mxb_init_module
);
846 module_exit(mxb_cleanup_module
);
848 MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
849 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
850 MODULE_LICENSE("GPL");