1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 mxb - v4l2 driver for the Multimedia eXtension Board
4
5 Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de>
6
7 Visit http://www.themm.net/~mihu/linux/saa7146/mxb.html
8 for further details about this card.
9
10*/
11
12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13
14#define DEBUG_VARIABLE debug
15
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>
22
23#include "tea6415c.h"
24#include "tea6420.h"
25
26#define MXB_AUDIOS 6
27
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
34
35#define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
36
37/* global variable */
38static int mxb_num;
39
40/* initial frequence the tuner will be tuned to.
41 in verden (lower saxony, germany) 4148 is a
42 channel called "phoenix" */
43static int freq = 4148;
44module_param(freq, int, 0644);
45MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup");
46
47static int debug;
48module_param(debug, int, 0644);
49MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
50
51#define MXB_STD (V4L2_STD_PAL_BG | V4L2_STD_PAL_I | V4L2_STD_SECAM | V4L2_STD_NTSC)
52#define MXB_INPUTS 4
53enum { TUNER, AUX1, AUX3, AUX3_YC };
54
55static 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 },
64};
65
66/* this array holds the information, which port of the saa7146 each
67 input actually uses. the mxb uses port 0 for every input */
68static struct {
69 int hps_source;
70 int hps_sync;
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 },
76};
77
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) */
80static int video_audio_connect[MXB_INPUTS] =
81 { 0, 1, 3, 3 };
82
83struct mxb_routing {
84 u32 input;
85 u32 output;
86};
87
88/* these are the available audio sources, which can switched
89 to the line- and cd-output individually */
90static struct v4l2_audio mxb_audios[MXB_AUDIOS] = {
91 {
92 .index = 0,
93 .name = "Tuner",
94 .capability = V4L2_AUDCAP_STEREO,
95 } , {
96 .index = 1,
97 .name = "AUX1",
98 .capability = V4L2_AUDCAP_STEREO,
99 } , {
100 .index = 2,
101 .name = "AUX2",
102 .capability = V4L2_AUDCAP_STEREO,
103 } , {
104 .index = 3,
105 .name = "AUX3",
106 .capability = V4L2_AUDCAP_STEREO,
107 } , {
108 .index = 4,
109 .name = "Radio (X9)",
110 .capability = V4L2_AUDCAP_STEREO,
111 } , {
112 .index = 5,
113 .name = "CD-ROM (X10)",
114 .capability = V4L2_AUDCAP_STEREO,
115 }
116};
117
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. */
120static 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 */
128};
129
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. */
132static 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 */
140};
141
142struct mxb
143{
144 struct video_device video_dev;
145 struct video_device vbi_dev;
146
147 struct i2c_adapter i2c_adapter;
148
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;
155
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 */
161};
162
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)
173
174static void mxb_update_audmode(struct mxb *mxb)
175{
176 struct v4l2_tuner t = {
177 .audmode = mxb->cur_mode,
178 };
179
180 tda9840_call(mxb, tuner, s_tuner, &t);
181}
182
183static inline void tea6420_route(struct mxb *mxb, int idx)
184{
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);
193}
194
195static struct saa7146_extension extension;
196
197static int mxb_s_ctrl(struct v4l2_ctrl *ctrl)
198{
199 struct saa7146_dev *dev = container_of(ctrl->handler,
200 struct saa7146_dev, ctrl_handler);
201 struct mxb *mxb = dev->ext_priv;
202
203 switch (ctrl->id) {
204 case V4L2_CID_AUDIO_MUTE:
205 mxb->cur_mute = ctrl->val;
206 /* switch the audio-source */
207 tea6420_route(mxb, idx: ctrl->val ? 6 :
208 video_audio_connect[mxb->cur_input]);
209 break;
210 default:
211 return -EINVAL;
212 }
213 return 0;
214}
215
216static const struct v4l2_ctrl_ops mxb_ctrl_ops = {
217 .s_ctrl = mxb_s_ctrl,
218};
219
220static int mxb_probe(struct saa7146_dev *dev)
221{
222 struct v4l2_ctrl_handler *hdl = &dev->ctrl_handler;
223 struct mxb *mxb = NULL;
224
225 v4l2_ctrl_new_std(hdl, ops: &mxb_ctrl_ops,
226 V4L2_CID_AUDIO_MUTE, min: 0, max: 1, step: 1, def: 1);
227 if (hdl->error)
228 return hdl->error;
229 mxb = kzalloc(size: sizeof(struct mxb), GFP_KERNEL);
230 if (mxb == NULL) {
231 DEB_D("not enough kernel memory\n");
232 return -ENOMEM;
233 }
234
235
236 snprintf(buf: mxb->i2c_adapter.name, size: sizeof(mxb->i2c_adapter.name), fmt: "mxb%d", mxb_num);
237
238 saa7146_i2c_adapter_prepare(dev, i2c_adapter: &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
239 if (i2c_add_adapter(adap: &mxb->i2c_adapter) < 0) {
240 DEB_S("cannot register i2c-device. skipping.\n");
241 kfree(objp: mxb);
242 return -EFAULT;
243 }
244
245 mxb->saa7111a = v4l2_i2c_new_subdev(v4l2_dev: &dev->v4l2_dev, adapter: &mxb->i2c_adapter,
246 client_type: "saa7111", I2C_SAA7111A, NULL);
247 mxb->tea6420_1 = v4l2_i2c_new_subdev(v4l2_dev: &dev->v4l2_dev, adapter: &mxb->i2c_adapter,
248 client_type: "tea6420", I2C_TEA6420_1, NULL);
249 mxb->tea6420_2 = v4l2_i2c_new_subdev(v4l2_dev: &dev->v4l2_dev, adapter: &mxb->i2c_adapter,
250 client_type: "tea6420", I2C_TEA6420_2, NULL);
251 mxb->tea6415c = v4l2_i2c_new_subdev(v4l2_dev: &dev->v4l2_dev, adapter: &mxb->i2c_adapter,
252 client_type: "tea6415c", I2C_TEA6415C, NULL);
253 mxb->tda9840 = v4l2_i2c_new_subdev(v4l2_dev: &dev->v4l2_dev, adapter: &mxb->i2c_adapter,
254 client_type: "tda9840", I2C_TDA9840, NULL);
255 mxb->tuner = v4l2_i2c_new_subdev(v4l2_dev: &dev->v4l2_dev, adapter: &mxb->i2c_adapter,
256 client_type: "tuner", I2C_TUNER, NULL);
257
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(adap: &mxb->i2c_adapter);
263 kfree(objp: mxb);
264 return -ENODEV;
265 }
266
267 /* all devices are present, probe was successful */
268
269 /* we store the pointer in our private data field */
270 dev->ext_priv = mxb;
271
272 v4l2_ctrl_handler_setup(hdl);
273
274 return 0;
275}
276
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 */
279static struct {
280 int length;
281 char data[9];
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 } },
330 {-1, { 0 } }
331};
332
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. */
337static int mxb_init_done(struct saa7146_dev* dev)
338{
339 struct mxb* mxb = (struct mxb*)dev->ext_priv;
340 struct i2c_msg msg;
341 struct tuner_setup tun_setup;
342 v4l2_std_id std = V4L2_STD_PAL_BG;
343
344 int i, err = 0;
345
346 /* mute audio on tea6420s */
347 tea6420_route(mxb, idx: 6);
348
349 /* select video mode in saa7111a */
350 saa7111a_call(mxb, video, s_std, std);
351
352 /* select tuner-output on saa7111a */
353 saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
354 SAA7111_FMT_CCIR, 0);
355
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);
366
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);
373
374 /* switch to tuner-channel on tea6415c */
375 tea6415c_call(mxb, video, s_routing, 3, 17, 0);
376
377 /* select tuner-output on multicable on tea6415c */
378 tea6415c_call(mxb, video, s_routing, 3, 13, 0);
379
380 /* the rest for mxb */
381 mxb->cur_input = 0;
382 mxb->cur_audinput = video_audio_connect[mxb->cur_input];
383 mxb->cur_mute = 1;
384
385 mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
386 mxb_update_audmode(mxb);
387
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
391 engineered. */
392 msg.addr = 0x1b;
393 msg.flags = 0;
394 msg.len = mxb_saa7740_init[0].length;
395 msg.buf = &mxb_saa7740_init[0].data[0];
396
397 err = i2c_transfer(adap: &mxb->i2c_adapter, msgs: &msg, num: 1);
398 if (err == 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;
405 for (i = 1; ; i++) {
406 if (-1 == mxb_saa7740_init[i].length)
407 break;
408
409 msg.len = mxb_saa7740_init[i].length;
410 msg.buf = &mxb_saa7740_init[i].data[0];
411 err = i2c_transfer(adap: &mxb->i2c_adapter, msgs: &msg, num: 1);
412 if (err != 1) {
413 DEB_D("failed to initialize 'sound arena module'\n");
414 goto err;
415 }
416 }
417 pr_info("'sound arena module' detected\n");
418 }
419err:
420 /* the rest for saa7146: you should definitely set some basic values
421 for the input-port handling of the saa7146. */
422
423 /* ext->saa has been filled by the core driver */
424
425 /* some stuff is done via variables */
426 saa7146_set_hps_source_and_sync(saa: dev, source: input_port_selection[mxb->cur_input].hps_source,
427 sync: input_port_selection[mxb->cur_input].hps_sync);
428
429 /* some stuff is done via direct write to the registers */
430
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));
436
437 return 0;
438}
439
440/* interrupt-handler. this gets called when irq_mask is != 0.
441 it must clear the interrupt-bits in irq_mask it has handled */
442/*
443void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
444{
445 struct mxb* mxb = (struct mxb*)dev->ext_priv;
446}
447*/
448
449static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
450{
451 DEB_EE("VIDIOC_ENUMINPUT %d\n", i->index);
452 if (i->index >= MXB_INPUTS)
453 return -EINVAL;
454 memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
455 return 0;
456}
457
458static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
459{
460 struct saa7146_dev *dev = video_drvdata(file);
461 struct mxb *mxb = (struct mxb *)dev->ext_priv;
462 *i = mxb->cur_input;
463
464 DEB_EE("VIDIOC_G_INPUT %d\n", *i);
465 return 0;
466}
467
468static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
469{
470 struct saa7146_dev *dev = video_drvdata(file);
471 struct mxb *mxb = (struct mxb *)dev->ext_priv;
472 int err = 0;
473 int i = 0;
474
475 DEB_EE("VIDIOC_S_INPUT %d\n", input);
476
477 if (input >= MXB_INPUTS)
478 return -EINVAL;
479
480 mxb->cur_input = input;
481
482 saa7146_set_hps_source_and_sync(saa: dev, source: input_port_selection[input].hps_source,
483 sync: input_port_selection[input].hps_sync);
484
485 /* prepare switching of tea6415c and saa7111a;
486 have a look at the 'background'-file for further information */
487 switch (input) {
488 case TUNER:
489 i = SAA7115_COMPOSITE0;
490
491 err = tea6415c_call(mxb, video, s_routing, 3, 17, 0);
492
493 /* connect tuner-output always to multicable */
494 if (!err)
495 err = tea6415c_call(mxb, video, s_routing, 3, 13, 0);
496 break;
497 case AUX3_YC:
498 /* nothing to be done here. aux3_yc is
499 directly connected to the saa711a */
500 i = SAA7115_SVIDEO1;
501 break;
502 case AUX3:
503 /* nothing to be done here. aux3 is
504 directly connected to the saa711a */
505 i = SAA7115_COMPOSITE1;
506 break;
507 case AUX1:
508 i = SAA7115_COMPOSITE0;
509 err = tea6415c_call(mxb, video, s_routing, 1, 17, 0);
510 break;
511 }
512
513 if (err)
514 return err;
515
516 mxb->video_dev.tvnorms = mxb_inputs[input].std;
517 mxb->vbi_dev.tvnorms = mxb_inputs[input].std;
518
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");
522
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, idx: mxb->cur_audinput);
527 if (mxb->cur_audinput == 0)
528 mxb_update_audmode(mxb);
529
530 return 0;
531}
532
533static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
534{
535 struct saa7146_dev *dev = video_drvdata(file);
536 struct mxb *mxb = (struct mxb *)dev->ext_priv;
537
538 if (t->index) {
539 DEB_D("VIDIOC_G_TUNER: channel %d does not have a tuner attached\n",
540 t->index);
541 return -EINVAL;
542 }
543
544 DEB_EE("VIDIOC_G_TUNER: %d\n", t->index);
545
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);
553}
554
555static int vidioc_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *t)
556{
557 struct saa7146_dev *dev = video_drvdata(file);
558 struct mxb *mxb = (struct mxb *)dev->ext_priv;
559
560 if (t->index) {
561 DEB_D("VIDIOC_S_TUNER: channel %d does not have a tuner attached\n",
562 t->index);
563 return -EINVAL;
564 }
565
566 mxb->cur_mode = t->audmode;
567 return call_all(dev, tuner, s_tuner, t);
568}
569
570static int vidioc_querystd(struct file *file, void *fh, v4l2_std_id *norm)
571{
572 struct saa7146_dev *dev = video_drvdata(file);
573
574 return call_all(dev, video, querystd, norm);
575}
576
577static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
578{
579 struct saa7146_dev *dev = video_drvdata(file);
580 struct mxb *mxb = (struct mxb *)dev->ext_priv;
581
582 if (f->tuner)
583 return -EINVAL;
584 *f = mxb->cur_freq;
585
586 DEB_EE("VIDIOC_G_FREQ: freq:0x%08x\n", mxb->cur_freq.frequency);
587 return 0;
588}
589
590static int vidioc_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *f)
591{
592 struct saa7146_dev *dev = video_drvdata(file);
593 struct mxb *mxb = (struct mxb *)dev->ext_priv;
594
595 if (f->tuner)
596 return -EINVAL;
597
598 if (V4L2_TUNER_ANALOG_TV != f->type)
599 return -EINVAL;
600
601 DEB_EE("VIDIOC_S_FREQUENCY: freq:0x%08x\n", mxb->cur_freq.frequency);
602
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 */
606 mxb->cur_freq = *f;
607 tuner_call(mxb, tuner, g_frequency, &mxb->cur_freq);
608 if (mxb->cur_audinput == 0)
609 mxb_update_audmode(mxb);
610 return 0;
611}
612
613static int vidioc_enumaudio(struct file *file, void *fh, struct v4l2_audio *a)
614{
615 if (a->index >= MXB_AUDIOS)
616 return -EINVAL;
617 *a = mxb_audios[a->index];
618 return 0;
619}
620
621static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
622{
623 struct saa7146_dev *dev = video_drvdata(file);
624 struct mxb *mxb = (struct mxb *)dev->ext_priv;
625
626 DEB_EE("VIDIOC_G_AUDIO\n");
627 *a = mxb_audios[mxb->cur_audinput];
628 return 0;
629}
630
631static int vidioc_s_audio(struct file *file, void *fh, const struct v4l2_audio *a)
632{
633 struct saa7146_dev *dev = video_drvdata(file);
634 struct mxb *mxb = (struct mxb *)dev->ext_priv;
635
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)))
639 return -EINVAL;
640
641 if (mxb->cur_audinput != a->index) {
642 mxb->cur_audinput = a->index;
643 tea6420_route(mxb, idx: a->index);
644 if (mxb->cur_audinput == 0)
645 mxb_update_audmode(mxb);
646 }
647 return 0;
648}
649
650#ifdef CONFIG_VIDEO_ADV_DEBUG
651static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
652{
653 struct saa7146_dev *dev = video_drvdata(file);
654
655 if (reg->reg > pci_resource_len(dev->pci, 0) - 4)
656 return -EINVAL;
657 reg->val = saa7146_read(dev, reg->reg);
658 reg->size = 4;
659 return 0;
660}
661
662static int vidioc_s_register(struct file *file, void *fh, const struct v4l2_dbg_register *reg)
663{
664 struct saa7146_dev *dev = video_drvdata(file);
665
666 if (reg->reg > pci_resource_len(dev->pci, 0) - 4)
667 return -EINVAL;
668 saa7146_write(dev, reg->reg, reg->val);
669 return 0;
670}
671#endif
672
673static struct saa7146_ext_vv vv_data;
674
675/* this function only gets called when the probing was successful */
676static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
677{
678 struct mxb *mxb;
679 int ret;
680
681 DEB_EE("dev:%p\n", dev);
682
683 ret = saa7146_vv_init(dev, ext_vv: &vv_data);
684 if (ret) {
685 ERR("Error in saa7146_vv_init()");
686 return ret;
687 }
688
689 if (mxb_probe(dev)) {
690 saa7146_vv_release(dev);
691 return -1;
692 }
693 mxb = (struct mxb *)dev->ext_priv;
694
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;
709#endif
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(vid: &mxb->video_dev, dev, name: "mxb", type: VFL_TYPE_VIDEO)) {
722 ERR("cannot register capture v4l2 device. skipping.\n");
723 saa7146_vv_release(dev);
724 return -1;
725 }
726
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(vid: &mxb->vbi_dev, dev, name: "mxb", type: VFL_TYPE_VBI)) {
730 ERR("cannot register vbi v4l2 device. skipping.\n");
731 }
732 }
733
734 pr_info("found Multimedia eXtension Board #%d\n", mxb_num);
735
736 mxb_num++;
737 mxb_init_done(dev);
738 return 0;
739}
740
741static int mxb_detach(struct saa7146_dev *dev)
742{
743 struct mxb *mxb = (struct mxb *)dev->ext_priv;
744
745 DEB_EE("dev:%p\n", dev);
746
747 /* mute audio on tea6420s */
748 tea6420_route(mxb, idx: 6);
749
750 saa7146_unregister_device(vid: &mxb->video_dev,dev);
751 if (MXB_BOARD_CAN_DO_VBI(dev))
752 saa7146_unregister_device(vid: &mxb->vbi_dev, dev);
753 saa7146_vv_release(dev);
754
755 mxb_num--;
756
757 i2c_del_adapter(adap: &mxb->i2c_adapter);
758 kfree(objp: mxb);
759
760 return 0;
761}
762
763static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
764{
765 struct mxb *mxb = (struct mxb *)dev->ext_priv;
766
767 if (V4L2_STD_PAL_I == standard->id) {
768 v4l2_std_id std = V4L2_STD_PAL_I;
769
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);
777 } else {
778 v4l2_std_id std = V4L2_STD_PAL_BG;
779
780 if (mxb->cur_input)
781 std = standard->id;
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);
789 }
790 return 0;
791}
792
793static struct saa7146_standard standard[] = {
794 {
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,
799 }, {
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,
804 }, {
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,
809 }, {
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,
814 }
815};
816
817static struct saa7146_pci_extension_data mxb = {
818 .ext_priv = "Multimedia eXtension Board",
819 .ext = &extension,
820};
821
822static const struct pci_device_id pci_tbl[] = {
823 {
824 .vendor = PCI_VENDOR_ID_PHILIPS,
825 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
826 .subvendor = 0x0000,
827 .subdevice = 0x0000,
828 .driver_data = (unsigned long)&mxb,
829 }, {
830 .vendor = 0,
831 }
832};
833
834MODULE_DEVICE_TABLE(pci, pci_tbl);
835
836static 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,
842};
843
844static struct saa7146_extension extension = {
845 .name = "Multimedia eXtension Board",
846 .flags = SAA7146_USE_I2C_IRQ,
847
848 .pci_tbl = &pci_tbl[0],
849 .module = THIS_MODULE,
850
851 .attach = mxb_attach,
852 .detach = mxb_detach,
853
854 .irq_mask = 0,
855 .irq_func = NULL,
856};
857
858static int __init mxb_init_module(void)
859{
860 if (saa7146_register_extension(&extension)) {
861 DEB_S("failed to register extension\n");
862 return -ENODEV;
863 }
864
865 return 0;
866}
867
868static void __exit mxb_cleanup_module(void)
869{
870 saa7146_unregister_extension(&extension);
871}
872
873module_init(mxb_init_module);
874module_exit(mxb_cleanup_module);
875
876MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
877MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
878MODULE_LICENSE("GPL");
879

source code of linux/drivers/media/pci/saa7146/mxb.c