1 // SPDX-License-Identifier: GPL-2.0-or-later
3 mxb - v4l2 driver for the Multimedia eXtension Board
5 Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de>
7 Visit http://www.themm.net/~mihu/linux/saa7146/mxb.html
8 for further details about this card.
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14 #define DEBUG_VARIABLE debug
16 #include <media/drv-intf/saa7146_vv.h>
17 #include <media/tuner.h>
18 #include <media/v4l2-common.h>
19 #include <media/i2c/saa7115.h>
20 #include <linux/module.h>
21 #include <linux/kernel.h>
28 #define I2C_SAA7111A 0x24
29 #define I2C_TDA9840 0x42
30 #define I2C_TEA6415C 0x43
31 #define I2C_TEA6420_1 0x4c
32 #define I2C_TEA6420_2 0x4d
33 #define I2C_TUNER 0x60
35 #define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
40 /* initial frequence the tuner will be tuned to.
41 in verden (lower saxony, germany) 4148 is a
42 channel called "phoenix" */
43 static int freq
= 4148;
44 module_param(freq
, int, 0644);
45 MODULE_PARM_DESC(freq
, "initial frequency the tuner will be tuned to while setup");
48 module_param(debug
, int, 0644);
49 MODULE_PARM_DESC(debug
, "Turn on/off device debugging (default:off).");
51 #define MXB_STD (V4L2_STD_PAL_BG | V4L2_STD_PAL_I | V4L2_STD_SECAM | V4L2_STD_NTSC)
53 enum { TUNER
, AUX1
, AUX3
, AUX3_YC
};
55 static struct v4l2_input mxb_inputs
[MXB_INPUTS
] = {
56 { TUNER
, "Tuner", V4L2_INPUT_TYPE_TUNER
, 0x3f, 0,
57 V4L2_STD_PAL_BG
| V4L2_STD_PAL_I
, 0, V4L2_IN_CAP_STD
},
58 { AUX1
, "AUX1", V4L2_INPUT_TYPE_CAMERA
, 0x3f, 0,
59 MXB_STD
, 0, V4L2_IN_CAP_STD
},
60 { AUX3
, "AUX3 Composite", V4L2_INPUT_TYPE_CAMERA
, 0x3f, 0,
61 MXB_STD
, 0, V4L2_IN_CAP_STD
},
62 { AUX3_YC
, "AUX3 S-Video", V4L2_INPUT_TYPE_CAMERA
, 0x3f, 0,
63 MXB_STD
, 0, V4L2_IN_CAP_STD
},
66 /* this array holds the information, which port of the saa7146 each
67 input actually uses. the mxb uses port 0 for every input */
71 } input_port_selection
[MXB_INPUTS
] = {
72 { SAA7146_HPS_SOURCE_PORT_A
, SAA7146_HPS_SYNC_PORT_A
},
73 { SAA7146_HPS_SOURCE_PORT_A
, SAA7146_HPS_SYNC_PORT_A
},
74 { SAA7146_HPS_SOURCE_PORT_A
, SAA7146_HPS_SYNC_PORT_A
},
75 { SAA7146_HPS_SOURCE_PORT_A
, SAA7146_HPS_SYNC_PORT_A
},
78 /* this array holds the information of the audio source (mxb_audios),
79 which has to be switched corresponding to the video source (mxb_channels) */
80 static int video_audio_connect
[MXB_INPUTS
] =
88 /* these are the available audio sources, which can switched
89 to the line- and cd-output individually */
90 static struct v4l2_audio mxb_audios
[MXB_AUDIOS
] = {
94 .capability
= V4L2_AUDCAP_STEREO
,
98 .capability
= V4L2_AUDCAP_STEREO
,
102 .capability
= V4L2_AUDCAP_STEREO
,
106 .capability
= V4L2_AUDCAP_STEREO
,
109 .name
= "Radio (X9)",
110 .capability
= V4L2_AUDCAP_STEREO
,
113 .name
= "CD-ROM (X10)",
114 .capability
= V4L2_AUDCAP_STEREO
,
118 /* These are the necessary input-output-pins for bringing one audio source
119 (see above) to the CD-output. Note that gain is set to 0 in this table. */
120 static struct mxb_routing TEA6420_cd
[MXB_AUDIOS
+ 1][2] = {
121 { { 1, 1 }, { 1, 1 } }, /* Tuner */
122 { { 5, 1 }, { 6, 1 } }, /* AUX 1 */
123 { { 4, 1 }, { 6, 1 } }, /* AUX 2 */
124 { { 3, 1 }, { 6, 1 } }, /* AUX 3 */
125 { { 1, 1 }, { 3, 1 } }, /* Radio */
126 { { 1, 1 }, { 2, 1 } }, /* CD-Rom */
127 { { 6, 1 }, { 6, 1 } } /* Mute */
130 /* These are the necessary input-output-pins for bringing one audio source
131 (see above) to the line-output. Note that gain is set to 0 in this table. */
132 static struct mxb_routing TEA6420_line
[MXB_AUDIOS
+ 1][2] = {
133 { { 2, 3 }, { 1, 2 } },
134 { { 5, 3 }, { 6, 2 } },
135 { { 4, 3 }, { 6, 2 } },
136 { { 3, 3 }, { 6, 2 } },
137 { { 2, 3 }, { 3, 2 } },
138 { { 2, 3 }, { 2, 2 } },
139 { { 6, 3 }, { 6, 2 } } /* Mute */
144 struct video_device video_dev
;
145 struct video_device vbi_dev
;
147 struct i2c_adapter i2c_adapter
;
149 struct v4l2_subdev
*saa7111a
;
150 struct v4l2_subdev
*tda9840
;
151 struct v4l2_subdev
*tea6415c
;
152 struct v4l2_subdev
*tuner
;
153 struct v4l2_subdev
*tea6420_1
;
154 struct v4l2_subdev
*tea6420_2
;
156 int cur_mode
; /* current audio mode (mono, stereo, ...) */
157 int cur_input
; /* current input */
158 int cur_audinput
; /* current audio input */
159 int cur_mute
; /* current mute status */
160 struct v4l2_frequency cur_freq
; /* current frequency the tuner is tuned to */
163 #define saa7111a_call(mxb, o, f, args...) \
164 v4l2_subdev_call(mxb->saa7111a, o, f, ##args)
165 #define tda9840_call(mxb, o, f, args...) \
166 v4l2_subdev_call(mxb->tda9840, o, f, ##args)
167 #define tea6415c_call(mxb, o, f, args...) \
168 v4l2_subdev_call(mxb->tea6415c, o, f, ##args)
169 #define tuner_call(mxb, o, f, args...) \
170 v4l2_subdev_call(mxb->tuner, o, f, ##args)
171 #define call_all(dev, o, f, args...) \
172 v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
174 static void mxb_update_audmode(struct mxb
*mxb
)
176 struct v4l2_tuner t
= {
177 .audmode
= mxb
->cur_mode
,
180 tda9840_call(mxb
, tuner
, s_tuner
, &t
);
183 static inline void tea6420_route(struct mxb
*mxb
, int idx
)
185 v4l2_subdev_call(mxb
->tea6420_1
, audio
, s_routing
,
186 TEA6420_cd
[idx
][0].input
, TEA6420_cd
[idx
][0].output
, 0);
187 v4l2_subdev_call(mxb
->tea6420_2
, audio
, s_routing
,
188 TEA6420_cd
[idx
][1].input
, TEA6420_cd
[idx
][1].output
, 0);
189 v4l2_subdev_call(mxb
->tea6420_1
, audio
, s_routing
,
190 TEA6420_line
[idx
][0].input
, TEA6420_line
[idx
][0].output
, 0);
191 v4l2_subdev_call(mxb
->tea6420_2
, audio
, s_routing
,
192 TEA6420_line
[idx
][1].input
, TEA6420_line
[idx
][1].output
, 0);
195 static struct saa7146_extension extension
;
197 static int mxb_s_ctrl(struct v4l2_ctrl
*ctrl
)
199 struct saa7146_dev
*dev
= container_of(ctrl
->handler
,
200 struct saa7146_dev
, ctrl_handler
);
201 struct mxb
*mxb
= dev
->ext_priv
;
204 case V4L2_CID_AUDIO_MUTE
:
205 mxb
->cur_mute
= ctrl
->val
;
206 /* switch the audio-source */
207 tea6420_route(mxb
, ctrl
->val
? 6 :
208 video_audio_connect
[mxb
->cur_input
]);
216 static const struct v4l2_ctrl_ops mxb_ctrl_ops
= {
217 .s_ctrl
= mxb_s_ctrl
,
220 static int mxb_probe(struct saa7146_dev
*dev
)
222 struct v4l2_ctrl_handler
*hdl
= &dev
->ctrl_handler
;
223 struct mxb
*mxb
= NULL
;
225 v4l2_ctrl_new_std(hdl
, &mxb_ctrl_ops
,
226 V4L2_CID_AUDIO_MUTE
, 0, 1, 1, 1);
229 mxb
= kzalloc(sizeof(struct mxb
), GFP_KERNEL
);
231 DEB_D("not enough kernel memory\n");
236 snprintf(mxb
->i2c_adapter
.name
, sizeof(mxb
->i2c_adapter
.name
), "mxb%d", mxb_num
);
238 saa7146_i2c_adapter_prepare(dev
, &mxb
->i2c_adapter
, SAA7146_I2C_BUS_BIT_RATE_480
);
239 if (i2c_add_adapter(&mxb
->i2c_adapter
) < 0) {
240 DEB_S("cannot register i2c-device. skipping.\n");
245 mxb
->saa7111a
= v4l2_i2c_new_subdev(&dev
->v4l2_dev
, &mxb
->i2c_adapter
,
246 "saa7111", I2C_SAA7111A
, NULL
);
247 mxb
->tea6420_1
= v4l2_i2c_new_subdev(&dev
->v4l2_dev
, &mxb
->i2c_adapter
,
248 "tea6420", I2C_TEA6420_1
, NULL
);
249 mxb
->tea6420_2
= v4l2_i2c_new_subdev(&dev
->v4l2_dev
, &mxb
->i2c_adapter
,
250 "tea6420", I2C_TEA6420_2
, NULL
);
251 mxb
->tea6415c
= v4l2_i2c_new_subdev(&dev
->v4l2_dev
, &mxb
->i2c_adapter
,
252 "tea6415c", I2C_TEA6415C
, NULL
);
253 mxb
->tda9840
= v4l2_i2c_new_subdev(&dev
->v4l2_dev
, &mxb
->i2c_adapter
,
254 "tda9840", I2C_TDA9840
, NULL
);
255 mxb
->tuner
= v4l2_i2c_new_subdev(&dev
->v4l2_dev
, &mxb
->i2c_adapter
,
256 "tuner", I2C_TUNER
, NULL
);
258 /* check if all devices are present */
259 if (!mxb
->tea6420_1
|| !mxb
->tea6420_2
|| !mxb
->tea6415c
||
260 !mxb
->tda9840
|| !mxb
->saa7111a
|| !mxb
->tuner
) {
261 pr_err("did not find all i2c devices. aborting\n");
262 i2c_del_adapter(&mxb
->i2c_adapter
);
267 /* all devices are present, probe was successful */
269 /* we store the pointer in our private data field */
272 v4l2_ctrl_handler_setup(hdl
);
277 /* some init data for the saa7740, the so-called 'sound arena module'.
278 there are no specs available, so we simply use some init values */
282 } mxb_saa7740_init
[] = {
283 { 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
284 { 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
285 { 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
286 { 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
287 { 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
288 { 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
289 { 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
290 { 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
291 { 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
292 { 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
293 { 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
294 { 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
295 { 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
296 { 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
297 { 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
298 { 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
299 { 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
300 { 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
301 { 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
302 { 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
303 { 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
304 { 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
305 { 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
306 { 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
307 { 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
308 { 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
309 { 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
310 { 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
311 { 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
312 { 3, { 0x48, 0x00, 0x01 } },
313 { 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
314 { 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
315 { 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
316 { 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
317 { 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
318 { 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
319 { 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
320 { 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
321 { 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
322 { 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
323 { 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
324 { 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
325 { 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
326 { 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
327 { 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
328 { 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
329 { 3, { 0x80, 0xb3, 0x0a } },
333 /* bring hardware to a sane state. this has to be done, just in case someone
334 wants to capture from this device before it has been properly initialized.
335 the capture engine would badly fail, because no valid signal arrives on the
336 saa7146, thus leading to timeouts and stuff. */
337 static int mxb_init_done(struct saa7146_dev
* dev
)
339 struct mxb
* mxb
= (struct mxb
*)dev
->ext_priv
;
341 struct tuner_setup tun_setup
;
342 v4l2_std_id std
= V4L2_STD_PAL_BG
;
346 /* mute audio on tea6420s */
347 tea6420_route(mxb
, 6);
349 /* select video mode in saa7111a */
350 saa7111a_call(mxb
, video
, s_std
, std
);
352 /* select tuner-output on saa7111a */
353 saa7111a_call(mxb
, video
, s_routing
, SAA7115_COMPOSITE0
,
354 SAA7111_FMT_CCIR
, 0);
356 /* select a tuner type */
357 tun_setup
.mode_mask
= T_ANALOG_TV
;
358 tun_setup
.addr
= ADDR_UNSET
;
359 tun_setup
.type
= TUNER_PHILIPS_PAL
;
360 tuner_call(mxb
, tuner
, s_type_addr
, &tun_setup
);
361 /* tune in some frequency on tuner */
362 mxb
->cur_freq
.tuner
= 0;
363 mxb
->cur_freq
.type
= V4L2_TUNER_ANALOG_TV
;
364 mxb
->cur_freq
.frequency
= freq
;
365 tuner_call(mxb
, tuner
, s_frequency
, &mxb
->cur_freq
);
367 /* set a default video standard */
368 /* These two gpio calls set the GPIO pins that control the tda9820 */
369 saa7146_write(dev
, GPIO_CTRL
, 0x00404050);
370 saa7111a_call(mxb
, core
, s_gpio
, 1);
371 saa7111a_call(mxb
, video
, s_std
, std
);
372 tuner_call(mxb
, video
, s_std
, std
);
374 /* switch to tuner-channel on tea6415c */
375 tea6415c_call(mxb
, video
, s_routing
, 3, 17, 0);
377 /* select tuner-output on multicable on tea6415c */
378 tea6415c_call(mxb
, video
, s_routing
, 3, 13, 0);
380 /* the rest for mxb */
382 mxb
->cur_audinput
= video_audio_connect
[mxb
->cur_input
];
385 mxb
->cur_mode
= V4L2_TUNER_MODE_STEREO
;
386 mxb_update_audmode(mxb
);
388 /* check if the saa7740 (aka 'sound arena module') is present
389 on the mxb. if so, we must initialize it. due to lack of
390 information about the saa7740, the values were reverse
394 msg
.len
= mxb_saa7740_init
[0].length
;
395 msg
.buf
= &mxb_saa7740_init
[0].data
[0];
397 err
= i2c_transfer(&mxb
->i2c_adapter
, &msg
, 1);
399 /* the sound arena module is a pos, that's probably the reason
400 philips refuses to hand out a datasheet for the saa7740...
401 it seems to screw up the i2c bus, so we disable fast irq
402 based i2c transactions here and rely on the slow and safe
403 polling method ... */
404 extension
.flags
&= ~SAA7146_USE_I2C_IRQ
;
406 if (-1 == mxb_saa7740_init
[i
].length
)
409 msg
.len
= mxb_saa7740_init
[i
].length
;
410 msg
.buf
= &mxb_saa7740_init
[i
].data
[0];
411 err
= i2c_transfer(&mxb
->i2c_adapter
, &msg
, 1);
413 DEB_D("failed to initialize 'sound arena module'\n");
417 pr_info("'sound arena module' detected\n");
420 /* the rest for saa7146: you should definitely set some basic values
421 for the input-port handling of the saa7146. */
423 /* ext->saa has been filled by the core driver */
425 /* some stuff is done via variables */
426 saa7146_set_hps_source_and_sync(dev
, input_port_selection
[mxb
->cur_input
].hps_source
,
427 input_port_selection
[mxb
->cur_input
].hps_sync
);
429 /* some stuff is done via direct write to the registers */
431 /* this is ugly, but because of the fact that this is completely
432 hardware dependend, it should be done directly... */
433 saa7146_write(dev
, DD1_STREAM_B
, 0x00000000);
434 saa7146_write(dev
, DD1_INIT
, 0x02000200);
435 saa7146_write(dev
, MC2
, (MASK_09
| MASK_25
| MASK_10
| MASK_26
));
440 /* interrupt-handler. this gets called when irq_mask is != 0.
441 it must clear the interrupt-bits in irq_mask it has handled */
443 void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
445 struct mxb* mxb = (struct mxb*)dev->ext_priv;
449 static int vidioc_enum_input(struct file
*file
, void *fh
, struct v4l2_input
*i
)
451 DEB_EE("VIDIOC_ENUMINPUT %d\n", i
->index
);
452 if (i
->index
>= MXB_INPUTS
)
454 memcpy(i
, &mxb_inputs
[i
->index
], sizeof(struct v4l2_input
));
458 static int vidioc_g_input(struct file
*file
, void *fh
, unsigned int *i
)
460 struct saa7146_dev
*dev
= video_drvdata(file
);
461 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
464 DEB_EE("VIDIOC_G_INPUT %d\n", *i
);
468 static int vidioc_s_input(struct file
*file
, void *fh
, unsigned int input
)
470 struct saa7146_dev
*dev
= video_drvdata(file
);
471 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
475 DEB_EE("VIDIOC_S_INPUT %d\n", input
);
477 if (input
>= MXB_INPUTS
)
480 mxb
->cur_input
= input
;
482 saa7146_set_hps_source_and_sync(dev
, input_port_selection
[input
].hps_source
,
483 input_port_selection
[input
].hps_sync
);
485 /* prepare switching of tea6415c and saa7111a;
486 have a look at the 'background'-file for further information */
489 i
= SAA7115_COMPOSITE0
;
491 err
= tea6415c_call(mxb
, video
, s_routing
, 3, 17, 0);
493 /* connect tuner-output always to multicable */
495 err
= tea6415c_call(mxb
, video
, s_routing
, 3, 13, 0);
498 /* nothing to be done here. aux3_yc is
499 directly connected to the saa711a */
503 /* nothing to be done here. aux3 is
504 directly connected to the saa711a */
505 i
= SAA7115_COMPOSITE1
;
508 i
= SAA7115_COMPOSITE0
;
509 err
= tea6415c_call(mxb
, video
, s_routing
, 1, 17, 0);
516 mxb
->video_dev
.tvnorms
= mxb_inputs
[input
].std
;
517 mxb
->vbi_dev
.tvnorms
= mxb_inputs
[input
].std
;
519 /* switch video in saa7111a */
520 if (saa7111a_call(mxb
, video
, s_routing
, i
, SAA7111_FMT_CCIR
, 0))
521 pr_err("VIDIOC_S_INPUT: could not address saa7111a\n");
523 mxb
->cur_audinput
= video_audio_connect
[input
];
524 /* switch the audio-source only if necessary */
525 if (0 == mxb
->cur_mute
)
526 tea6420_route(mxb
, mxb
->cur_audinput
);
527 if (mxb
->cur_audinput
== 0)
528 mxb_update_audmode(mxb
);
533 static int vidioc_g_tuner(struct file
*file
, void *fh
, struct v4l2_tuner
*t
)
535 struct saa7146_dev
*dev
= video_drvdata(file
);
536 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
539 DEB_D("VIDIOC_G_TUNER: channel %d does not have a tuner attached\n",
544 DEB_EE("VIDIOC_G_TUNER: %d\n", t
->index
);
546 memset(t
, 0, sizeof(*t
));
547 strscpy(t
->name
, "TV Tuner", sizeof(t
->name
));
548 t
->type
= V4L2_TUNER_ANALOG_TV
;
549 t
->capability
= V4L2_TUNER_CAP_NORM
| V4L2_TUNER_CAP_STEREO
|
550 V4L2_TUNER_CAP_LANG1
| V4L2_TUNER_CAP_LANG2
| V4L2_TUNER_CAP_SAP
;
551 t
->audmode
= mxb
->cur_mode
;
552 return call_all(dev
, tuner
, g_tuner
, t
);
555 static int vidioc_s_tuner(struct file
*file
, void *fh
, const struct v4l2_tuner
*t
)
557 struct saa7146_dev
*dev
= video_drvdata(file
);
558 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
561 DEB_D("VIDIOC_S_TUNER: channel %d does not have a tuner attached\n",
566 mxb
->cur_mode
= t
->audmode
;
567 return call_all(dev
, tuner
, s_tuner
, t
);
570 static int vidioc_querystd(struct file
*file
, void *fh
, v4l2_std_id
*norm
)
572 struct saa7146_dev
*dev
= video_drvdata(file
);
574 return call_all(dev
, video
, querystd
, norm
);
577 static int vidioc_g_frequency(struct file
*file
, void *fh
, struct v4l2_frequency
*f
)
579 struct saa7146_dev
*dev
= video_drvdata(file
);
580 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
586 DEB_EE("VIDIOC_G_FREQ: freq:0x%08x\n", mxb
->cur_freq
.frequency
);
590 static int vidioc_s_frequency(struct file
*file
, void *fh
, const struct v4l2_frequency
*f
)
592 struct saa7146_dev
*dev
= video_drvdata(file
);
593 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
598 if (V4L2_TUNER_ANALOG_TV
!= f
->type
)
601 DEB_EE("VIDIOC_S_FREQUENCY: freq:0x%08x\n", mxb
->cur_freq
.frequency
);
603 /* tune in desired frequency */
604 tuner_call(mxb
, tuner
, s_frequency
, f
);
605 /* let the tuner subdev clamp the frequency to the tuner range */
607 tuner_call(mxb
, tuner
, g_frequency
, &mxb
->cur_freq
);
608 if (mxb
->cur_audinput
== 0)
609 mxb_update_audmode(mxb
);
613 static int vidioc_enumaudio(struct file
*file
, void *fh
, struct v4l2_audio
*a
)
615 if (a
->index
>= MXB_AUDIOS
)
617 *a
= mxb_audios
[a
->index
];
621 static int vidioc_g_audio(struct file
*file
, void *fh
, struct v4l2_audio
*a
)
623 struct saa7146_dev
*dev
= video_drvdata(file
);
624 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
626 DEB_EE("VIDIOC_G_AUDIO\n");
627 *a
= mxb_audios
[mxb
->cur_audinput
];
631 static int vidioc_s_audio(struct file
*file
, void *fh
, const struct v4l2_audio
*a
)
633 struct saa7146_dev
*dev
= video_drvdata(file
);
634 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
636 DEB_D("VIDIOC_S_AUDIO %d\n", a
->index
);
637 if (a
->index
>= 32 ||
638 !(mxb_inputs
[mxb
->cur_input
].audioset
& (1 << a
->index
)))
641 if (mxb
->cur_audinput
!= a
->index
) {
642 mxb
->cur_audinput
= a
->index
;
643 tea6420_route(mxb
, a
->index
);
644 if (mxb
->cur_audinput
== 0)
645 mxb_update_audmode(mxb
);
650 #ifdef CONFIG_VIDEO_ADV_DEBUG
651 static int vidioc_g_register(struct file
*file
, void *fh
, struct v4l2_dbg_register
*reg
)
653 struct saa7146_dev
*dev
= video_drvdata(file
);
655 if (reg
->reg
> pci_resource_len(dev
->pci
, 0) - 4)
657 reg
->val
= saa7146_read(dev
, reg
->reg
);
662 static int vidioc_s_register(struct file
*file
, void *fh
, const struct v4l2_dbg_register
*reg
)
664 struct saa7146_dev
*dev
= video_drvdata(file
);
666 if (reg
->reg
> pci_resource_len(dev
->pci
, 0) - 4)
668 saa7146_write(dev
, reg
->reg
, reg
->val
);
673 static struct saa7146_ext_vv vv_data
;
675 /* this function only gets called when the probing was successful */
676 static int mxb_attach(struct saa7146_dev
*dev
, struct saa7146_pci_extension_data
*info
)
681 DEB_EE("dev:%p\n", dev
);
683 ret
= saa7146_vv_init(dev
, &vv_data
);
685 ERR("Error in saa7146_vv_init()");
689 if (mxb_probe(dev
)) {
690 saa7146_vv_release(dev
);
693 mxb
= (struct mxb
*)dev
->ext_priv
;
695 vv_data
.vid_ops
.vidioc_enum_input
= vidioc_enum_input
;
696 vv_data
.vid_ops
.vidioc_g_input
= vidioc_g_input
;
697 vv_data
.vid_ops
.vidioc_s_input
= vidioc_s_input
;
698 vv_data
.vid_ops
.vidioc_querystd
= vidioc_querystd
;
699 vv_data
.vid_ops
.vidioc_g_tuner
= vidioc_g_tuner
;
700 vv_data
.vid_ops
.vidioc_s_tuner
= vidioc_s_tuner
;
701 vv_data
.vid_ops
.vidioc_g_frequency
= vidioc_g_frequency
;
702 vv_data
.vid_ops
.vidioc_s_frequency
= vidioc_s_frequency
;
703 vv_data
.vid_ops
.vidioc_enumaudio
= vidioc_enumaudio
;
704 vv_data
.vid_ops
.vidioc_g_audio
= vidioc_g_audio
;
705 vv_data
.vid_ops
.vidioc_s_audio
= vidioc_s_audio
;
706 #ifdef CONFIG_VIDEO_ADV_DEBUG
707 vv_data
.vid_ops
.vidioc_g_register
= vidioc_g_register
;
708 vv_data
.vid_ops
.vidioc_s_register
= vidioc_s_register
;
710 vv_data
.vbi_ops
.vidioc_enum_input
= vidioc_enum_input
;
711 vv_data
.vbi_ops
.vidioc_g_input
= vidioc_g_input
;
712 vv_data
.vbi_ops
.vidioc_s_input
= vidioc_s_input
;
713 vv_data
.vbi_ops
.vidioc_querystd
= vidioc_querystd
;
714 vv_data
.vbi_ops
.vidioc_g_tuner
= vidioc_g_tuner
;
715 vv_data
.vbi_ops
.vidioc_s_tuner
= vidioc_s_tuner
;
716 vv_data
.vbi_ops
.vidioc_g_frequency
= vidioc_g_frequency
;
717 vv_data
.vbi_ops
.vidioc_s_frequency
= vidioc_s_frequency
;
718 vv_data
.vbi_ops
.vidioc_enumaudio
= vidioc_enumaudio
;
719 vv_data
.vbi_ops
.vidioc_g_audio
= vidioc_g_audio
;
720 vv_data
.vbi_ops
.vidioc_s_audio
= vidioc_s_audio
;
721 if (saa7146_register_device(&mxb
->video_dev
, dev
, "mxb", VFL_TYPE_VIDEO
)) {
722 ERR("cannot register capture v4l2 device. skipping.\n");
723 saa7146_vv_release(dev
);
727 /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
728 if (MXB_BOARD_CAN_DO_VBI(dev
)) {
729 if (saa7146_register_device(&mxb
->vbi_dev
, dev
, "mxb", VFL_TYPE_VBI
)) {
730 ERR("cannot register vbi v4l2 device. skipping.\n");
734 pr_info("found Multimedia eXtension Board #%d\n", mxb_num
);
741 static int mxb_detach(struct saa7146_dev
*dev
)
743 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
745 DEB_EE("dev:%p\n", dev
);
747 /* mute audio on tea6420s */
748 tea6420_route(mxb
, 6);
750 saa7146_unregister_device(&mxb
->video_dev
,dev
);
751 if (MXB_BOARD_CAN_DO_VBI(dev
))
752 saa7146_unregister_device(&mxb
->vbi_dev
, dev
);
753 saa7146_vv_release(dev
);
757 i2c_del_adapter(&mxb
->i2c_adapter
);
763 static int std_callback(struct saa7146_dev
*dev
, struct saa7146_standard
*standard
)
765 struct mxb
*mxb
= (struct mxb
*)dev
->ext_priv
;
767 if (V4L2_STD_PAL_I
== standard
->id
) {
768 v4l2_std_id std
= V4L2_STD_PAL_I
;
770 DEB_D("VIDIOC_S_STD: setting mxb for PAL_I\n");
771 /* These two gpio calls set the GPIO pins that control the tda9820 */
772 saa7146_write(dev
, GPIO_CTRL
, 0x00404050);
773 saa7111a_call(mxb
, core
, s_gpio
, 0);
774 saa7111a_call(mxb
, video
, s_std
, std
);
775 if (mxb
->cur_input
== 0)
776 tuner_call(mxb
, video
, s_std
, std
);
778 v4l2_std_id std
= V4L2_STD_PAL_BG
;
782 DEB_D("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM\n");
783 /* These two gpio calls set the GPIO pins that control the tda9820 */
784 saa7146_write(dev
, GPIO_CTRL
, 0x00404050);
785 saa7111a_call(mxb
, core
, s_gpio
, 1);
786 saa7111a_call(mxb
, video
, s_std
, std
);
787 if (mxb
->cur_input
== 0)
788 tuner_call(mxb
, video
, s_std
, std
);
793 static struct saa7146_standard standard
[] = {
795 .name
= "PAL-BG", .id
= V4L2_STD_PAL_BG
,
796 .v_offset
= 0x17, .v_field
= 288,
797 .h_offset
= 0x14, .h_pixels
= 680,
798 .v_max_out
= 576, .h_max_out
= 768,
800 .name
= "PAL-I", .id
= V4L2_STD_PAL_I
,
801 .v_offset
= 0x17, .v_field
= 288,
802 .h_offset
= 0x14, .h_pixels
= 680,
803 .v_max_out
= 576, .h_max_out
= 768,
805 .name
= "NTSC", .id
= V4L2_STD_NTSC
,
806 .v_offset
= 0x16, .v_field
= 240,
807 .h_offset
= 0x06, .h_pixels
= 708,
808 .v_max_out
= 480, .h_max_out
= 640,
810 .name
= "SECAM", .id
= V4L2_STD_SECAM
,
811 .v_offset
= 0x14, .v_field
= 288,
812 .h_offset
= 0x14, .h_pixels
= 720,
813 .v_max_out
= 576, .h_max_out
= 768,
817 static struct saa7146_pci_extension_data mxb
= {
818 .ext_priv
= "Multimedia eXtension Board",
822 static const struct pci_device_id pci_tbl
[] = {
824 .vendor
= PCI_VENDOR_ID_PHILIPS
,
825 .device
= PCI_DEVICE_ID_PHILIPS_SAA7146
,
828 .driver_data
= (unsigned long)&mxb
,
834 MODULE_DEVICE_TABLE(pci
, pci_tbl
);
836 static struct saa7146_ext_vv vv_data
= {
837 .inputs
= MXB_INPUTS
,
838 .capabilities
= V4L2_CAP_TUNER
| V4L2_CAP_VBI_CAPTURE
| V4L2_CAP_AUDIO
,
839 .stds
= &standard
[0],
840 .num_stds
= ARRAY_SIZE(standard
),
841 .std_callback
= &std_callback
,
844 static struct saa7146_extension extension
= {
845 .name
= "Multimedia eXtension Board",
846 .flags
= SAA7146_USE_I2C_IRQ
,
848 .pci_tbl
= &pci_tbl
[0],
849 .module
= THIS_MODULE
,
851 .attach
= mxb_attach
,
852 .detach
= mxb_detach
,
858 static int __init
mxb_init_module(void)
860 if (saa7146_register_extension(&extension
)) {
861 DEB_S("failed to register extension\n");
868 static void __exit
mxb_cleanup_module(void)
870 saa7146_unregister_extension(&extension
);
873 module_init(mxb_init_module
);
874 module_exit(mxb_cleanup_module
);
876 MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
877 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
878 MODULE_LICENSE("GPL");