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