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