Blame view

drivers/media/video/mxb.c 26.1 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
  /*
      mxb - v4l2 driver for the Multimedia eXtension Board
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
3

6acaba8e2   Michael Hunold   [PATCH] Restore t...
4
      Copyright (C) 1998-2006 Michael Hunold <michael@mihu.de>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5

631dd1a88   Justin P. Mattock   Update broken web...
6
      Visit http://www.themm.net/~mihu/linux/saa7146/mxb.html 
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
      for further details about this card.
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
8

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
11
12
13
14
15
16
17
18
19
20
21
22
      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
      the Free Software Foundation; either version 2 of the License, or
      (at your option) any later version.
  
      This program is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.
  
      You should have received a copy of the GNU General Public License
      along with this program; if not, write to the Free Software
      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
44d0b80e5   Joe Perches   [media] saa7146: ...
23
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
25
26
27
  #define DEBUG_VARIABLE debug
  
  #include <media/saa7146_vv.h>
  #include <media/tuner.h>
5e453dc75   Michael Krufky   V4L/DVB (3269): i...
28
  #include <media/v4l2-common.h>
707ecf460   Hans Verkuil   V4L/DVB (8941): m...
29
  #include <media/saa7115.h>
7a707b892   Paul Gortmaker   drivers/media: Ad...
30
  #include <linux/module.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
33
34
  
  #include "mxb.h"
  #include "tea6415c.h"
  #include "tea6420.h"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35

1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
36
37
38
39
40
41
  #define I2C_SAA7111A  0x24
  #define	I2C_TDA9840   0x42
  #define	I2C_TEA6415C  0x43
  #define	I2C_TEA6420_1 0x4c
  #define	I2C_TEA6420_2 0x4d
  #define	I2C_TUNER     0x60
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
42

a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
43
  #define MXB_BOARD_CAN_DO_VBI(dev)   (dev->revision != 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
44
45
  
  /* global variable */
ff699e6bd   Douglas Schilling Landgraf   V4L/DVB (7094): ...
46
  static int mxb_num;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
47

a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
48
  /* initial frequence the tuner will be tuned to.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
51
52
53
     in verden (lower saxony, germany) 4148 is a
     channel called "phoenix" */
  static int freq = 4148;
  module_param(freq, int, 0644);
  MODULE_PARM_DESC(freq, "initial frequency the tuner will be tuned to while setup");
ff699e6bd   Douglas Schilling Landgraf   V4L/DVB (7094): ...
54
  static int debug;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
55
56
57
58
59
60
61
  module_param(debug, int, 0644);
  MODULE_PARM_DESC(debug, "Turn on/off device debugging (default:off).");
  
  #define MXB_INPUTS 4
  enum { TUNER, AUX1, AUX3, AUX3_YC };
  
  static struct v4l2_input mxb_inputs[MXB_INPUTS] = {
657f22710   Hans Verkuil   [media] v4l: fix ...
62
63
64
65
  	{ TUNER,	"Tuner",		V4L2_INPUT_TYPE_TUNER,	1, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
  	{ AUX1,		"AUX1",			V4L2_INPUT_TYPE_CAMERA,	2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
  	{ AUX3,		"AUX3 Composite",	V4L2_INPUT_TYPE_CAMERA,	4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
  	{ AUX3_YC,	"AUX3 S-Video",		V4L2_INPUT_TYPE_CAMERA,	4, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0, V4L2_IN_CAP_STD },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
66
67
68
69
70
71
72
  };
  
  /* this array holds the information, which port of the saa7146 each
     input actually uses. the mxb uses port 0 for every input */
  static struct {
  	int hps_source;
  	int hps_sync;
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
73
  } input_port_selection[MXB_INPUTS] = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
74
75
76
77
78
79
80
81
82
83
  	{ SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
  	{ SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
  	{ SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
  	{ SAA7146_HPS_SOURCE_PORT_A, SAA7146_HPS_SYNC_PORT_A },
  };
  
  /* this array holds the information of the audio source (mxb_audios),
     which has to be switched corresponding to the video source (mxb_channels) */
  static int video_audio_connect[MXB_INPUTS] =
  	{ 0, 1, 3, 3 };
5325b4272   Hans Verkuil   V4L/DVB (11380): ...
84
85
86
87
  struct mxb_routing {
  	u32 input;
  	u32 output;
  };
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
88
89
  /* These are the necessary input-output-pins for bringing one audio source
     (see above) to the CD-output. Note that gain is set to 0 in this table. */
5325b4272   Hans Verkuil   V4L/DVB (11380): ...
90
  static struct mxb_routing TEA6420_cd[MXB_AUDIOS + 1][2] = {
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
91
92
93
94
95
96
97
98
99
100
101
  	{ { 1, 1 }, { 1, 1 } },	/* Tuner */
  	{ { 5, 1 }, { 6, 1 } },	/* AUX 1 */
  	{ { 4, 1 }, { 6, 1 } },	/* AUX 2 */
  	{ { 3, 1 }, { 6, 1 } },	/* AUX 3 */
  	{ { 1, 1 }, { 3, 1 } },	/* Radio */
  	{ { 1, 1 }, { 2, 1 } },	/* CD-Rom */
  	{ { 6, 1 }, { 6, 1 } }	/* Mute */
  };
  
  /* These are the necessary input-output-pins for bringing one audio source
     (see above) to the line-output. Note that gain is set to 0 in this table. */
5325b4272   Hans Verkuil   V4L/DVB (11380): ...
102
  static struct mxb_routing TEA6420_line[MXB_AUDIOS + 1][2] = {
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
103
104
105
106
107
108
109
110
  	{ { 2, 3 }, { 1, 2 } },
  	{ { 5, 3 }, { 6, 2 } },
  	{ { 4, 3 }, { 6, 2 } },
  	{ { 3, 3 }, { 6, 2 } },
  	{ { 2, 3 }, { 3, 2 } },
  	{ { 2, 3 }, { 2, 2 } },
  	{ { 6, 3 }, { 6, 2 } }	/* Mute */
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
111
112
113
114
115
  
  #define MAXCONTROLS	1
  static struct v4l2_queryctrl mxb_controls[] = {
  	{ V4L2_CID_AUDIO_MUTE, V4L2_CTRL_TYPE_BOOLEAN, "Mute", 0, 1, 1, 0, 0 },
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
117
118
119
  struct mxb
  {
  	struct video_device	*video_dev;
  	struct video_device	*vbi_dev;
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
120
  	struct i2c_adapter	i2c_adapter;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121

1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
122
123
124
125
126
127
  	struct v4l2_subdev	*saa7111a;
  	struct v4l2_subdev	*tda9840;
  	struct v4l2_subdev	*tea6415c;
  	struct v4l2_subdev	*tuner;
  	struct v4l2_subdev	*tea6420_1;
  	struct v4l2_subdev	*tea6420_2;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
128
129
130
  
  	int	cur_mode;	/* current audio mode (mono, stereo, ...) */
  	int	cur_input;	/* current input */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
  	int	cur_mute;	/* current mute status */
9d2599d98   Michael Hunold   [PATCH] v4l: fix ...
132
  	struct v4l2_frequency	cur_freq;	/* current frequency the tuner is tuned to */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
133
  };
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
134
135
  #define saa7111a_call(mxb, o, f, args...) \
  	v4l2_subdev_call(mxb->saa7111a, o, f, ##args)
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
136
137
138
139
140
141
142
143
  #define tda9840_call(mxb, o, f, args...) \
  	v4l2_subdev_call(mxb->tda9840, o, f, ##args)
  #define tea6415c_call(mxb, o, f, args...) \
  	v4l2_subdev_call(mxb->tea6415c, o, f, ##args)
  #define tuner_call(mxb, o, f, args...) \
  	v4l2_subdev_call(mxb->tuner, o, f, ##args)
  #define call_all(dev, o, f, args...) \
  	v4l2_device_call_until_err(&dev->v4l2_dev, 0, o, f, ##args)
961f80f9c   Jean Delvare   i2c: Drivers stop...
144

5325b4272   Hans Verkuil   V4L/DVB (11380): ...
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
  static inline void tea6420_route_cd(struct mxb *mxb, int idx)
  {
  	v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
  		TEA6420_cd[idx][0].input, TEA6420_cd[idx][0].output, 0);
  	v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
  		TEA6420_cd[idx][1].input, TEA6420_cd[idx][1].output, 0);
  }
  
  static inline void tea6420_route_line(struct mxb *mxb, int idx)
  {
  	v4l2_subdev_call(mxb->tea6420_1, audio, s_routing,
  		TEA6420_line[idx][0].input, TEA6420_line[idx][0].output, 0);
  	v4l2_subdev_call(mxb->tea6420_2, audio, s_routing,
  		TEA6420_line[idx][1].input, TEA6420_line[idx][1].output, 0);
  }
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
160
  static struct saa7146_extension extension;
961f80f9c   Jean Delvare   i2c: Drivers stop...
161

1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
162
  static int mxb_probe(struct saa7146_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
163
  {
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
164
  	struct mxb *mxb = NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
165

7408187d2   Panagiotis Issaris   (7408187d223f63d4...
166
  	mxb = kzalloc(sizeof(struct mxb), GFP_KERNEL);
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
167
  	if (mxb == NULL) {
44d0b80e5   Joe Perches   [media] saa7146: ...
168
169
  		DEB_D("not enough kernel memory
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
171
  		return -ENOMEM;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172

9ebeae564   Hans Verkuil   V4L/DVB (8945): m...
173
  	snprintf(mxb->i2c_adapter.name, sizeof(mxb->i2c_adapter.name), "mxb%d", mxb_num);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
  	saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
175
  	if (i2c_add_adapter(&mxb->i2c_adapter) < 0) {
44d0b80e5   Joe Perches   [media] saa7146: ...
176
177
  		DEB_S("cannot register i2c-device. skipping.
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
179
180
  		kfree(mxb);
  		return -EFAULT;
  	}
e6574f2fb   Hans Verkuil   V4L/DVB (11373): ...
181
  	mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
9a1f8b34a   Laurent Pinchart   [media] v4l: Remo...
182
  			"saa7111", I2C_SAA7111A, NULL);
e6574f2fb   Hans Verkuil   V4L/DVB (11373): ...
183
  	mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
9a1f8b34a   Laurent Pinchart   [media] v4l: Remo...
184
  			"tea6420", I2C_TEA6420_1, NULL);
e6574f2fb   Hans Verkuil   V4L/DVB (11373): ...
185
  	mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
9a1f8b34a   Laurent Pinchart   [media] v4l: Remo...
186
  			"tea6420", I2C_TEA6420_2, NULL);
e6574f2fb   Hans Verkuil   V4L/DVB (11373): ...
187
  	mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
9a1f8b34a   Laurent Pinchart   [media] v4l: Remo...
188
  			"tea6415c", I2C_TEA6415C, NULL);
e6574f2fb   Hans Verkuil   V4L/DVB (11373): ...
189
  	mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
9a1f8b34a   Laurent Pinchart   [media] v4l: Remo...
190
  			"tda9840", I2C_TDA9840, NULL);
e6574f2fb   Hans Verkuil   V4L/DVB (11373): ...
191
  	mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
9a1f8b34a   Laurent Pinchart   [media] v4l: Remo...
192
  			"tuner", I2C_TUNER, NULL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
193
194
  
  	/* check if all devices are present */
5fa1247a2   Al Viro   NULL noise: drive...
195
196
  	if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
  	    !mxb->tda9840 || !mxb->saa7111a || !mxb->tuner) {
44d0b80e5   Joe Perches   [media] saa7146: ...
197
198
  		pr_err("did not find all i2c devices. aborting
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
200
201
202
  		i2c_del_adapter(&mxb->i2c_adapter);
  		kfree(mxb);
  		return -ENODEV;
  	}
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
203
  	/* all devices are present, probe was successful */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
204
205
206
207
208
209
  
  	/* we store the pointer in our private data field */
  	dev->ext_priv = mxb;
  
  	return 0;
  }
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
210
  /* some init data for the saa7740, the so-called 'sound arena module'.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
     there are no specs available, so we simply use some init values */
  static struct {
  	int	length;
  	char	data[9];
  } mxb_saa7740_init[] = {
  	{ 3, { 0x80, 0x00, 0x00 } },{ 3, { 0x80, 0x89, 0x00 } },
  	{ 3, { 0x80, 0xb0, 0x0a } },{ 3, { 0x00, 0x00, 0x00 } },
  	{ 3, { 0x49, 0x00, 0x00 } },{ 3, { 0x4a, 0x00, 0x00 } },
  	{ 3, { 0x4b, 0x00, 0x00 } },{ 3, { 0x4c, 0x00, 0x00 } },
  	{ 3, { 0x4d, 0x00, 0x00 } },{ 3, { 0x4e, 0x00, 0x00 } },
  	{ 3, { 0x4f, 0x00, 0x00 } },{ 3, { 0x50, 0x00, 0x00 } },
  	{ 3, { 0x51, 0x00, 0x00 } },{ 3, { 0x52, 0x00, 0x00 } },
  	{ 3, { 0x53, 0x00, 0x00 } },{ 3, { 0x54, 0x00, 0x00 } },
  	{ 3, { 0x55, 0x00, 0x00 } },{ 3, { 0x56, 0x00, 0x00 } },
  	{ 3, { 0x57, 0x00, 0x00 } },{ 3, { 0x58, 0x00, 0x00 } },
  	{ 3, { 0x59, 0x00, 0x00 } },{ 3, { 0x5a, 0x00, 0x00 } },
  	{ 3, { 0x5b, 0x00, 0x00 } },{ 3, { 0x5c, 0x00, 0x00 } },
  	{ 3, { 0x5d, 0x00, 0x00 } },{ 3, { 0x5e, 0x00, 0x00 } },
  	{ 3, { 0x5f, 0x00, 0x00 } },{ 3, { 0x60, 0x00, 0x00 } },
  	{ 3, { 0x61, 0x00, 0x00 } },{ 3, { 0x62, 0x00, 0x00 } },
  	{ 3, { 0x63, 0x00, 0x00 } },{ 3, { 0x64, 0x00, 0x00 } },
  	{ 3, { 0x65, 0x00, 0x00 } },{ 3, { 0x66, 0x00, 0x00 } },
  	{ 3, { 0x67, 0x00, 0x00 } },{ 3, { 0x68, 0x00, 0x00 } },
  	{ 3, { 0x69, 0x00, 0x00 } },{ 3, { 0x6a, 0x00, 0x00 } },
  	{ 3, { 0x6b, 0x00, 0x00 } },{ 3, { 0x6c, 0x00, 0x00 } },
  	{ 3, { 0x6d, 0x00, 0x00 } },{ 3, { 0x6e, 0x00, 0x00 } },
  	{ 3, { 0x6f, 0x00, 0x00 } },{ 3, { 0x70, 0x00, 0x00 } },
  	{ 3, { 0x71, 0x00, 0x00 } },{ 3, { 0x72, 0x00, 0x00 } },
  	{ 3, { 0x73, 0x00, 0x00 } },{ 3, { 0x74, 0x00, 0x00 } },
  	{ 3, { 0x75, 0x00, 0x00 } },{ 3, { 0x76, 0x00, 0x00 } },
  	{ 3, { 0x77, 0x00, 0x00 } },{ 3, { 0x41, 0x00, 0x42 } },
  	{ 3, { 0x42, 0x10, 0x42 } },{ 3, { 0x43, 0x20, 0x42 } },
  	{ 3, { 0x44, 0x30, 0x42 } },{ 3, { 0x45, 0x00, 0x01 } },
  	{ 3, { 0x46, 0x00, 0x01 } },{ 3, { 0x47, 0x00, 0x01 } },
  	{ 3, { 0x48, 0x00, 0x01 } },
  	{ 9, { 0x01, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
  	{ 9, { 0x21, 0x03, 0xc5, 0x5c, 0x7a, 0x85, 0x01, 0x00, 0x54 } },
  	{ 9, { 0x09, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
  	{ 9, { 0x29, 0x0b, 0xb4, 0x6b, 0x74, 0x85, 0x95, 0x00, 0x34 } },
  	{ 9, { 0x11, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
  	{ 9, { 0x31, 0x17, 0x43, 0x62, 0x68, 0x89, 0xd1, 0xff, 0xb0 } },
  	{ 9, { 0x19, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
  	{ 9, { 0x39, 0x20, 0x62, 0x51, 0x5a, 0x95, 0x19, 0x01, 0x50 } },
  	{ 9, { 0x05, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
  	{ 9, { 0x25, 0x3e, 0xd2, 0x69, 0x4e, 0x9a, 0x51, 0x00, 0xf0 } },
  	{ 9, { 0x0d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
  	{ 9, { 0x2d, 0x3d, 0xa1, 0x40, 0x7d, 0x9f, 0x29, 0xfe, 0x14 } },
  	{ 9, { 0x15, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
  	{ 9, { 0x35, 0x73, 0xa1, 0x50, 0x5d, 0xa6, 0xf5, 0xfe, 0x38 } },
  	{ 9, { 0x1d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
  	{ 9, { 0x3d, 0xed, 0xd0, 0x68, 0x29, 0xb4, 0xe1, 0x00, 0xb8 } },
  	{ 3, { 0x80, 0xb3, 0x0a } },
2633812f8   Hans Verkuil   V4L/DVB (8942): m...
263
  	{-1, { 0 } }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
264
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
266
267
268
269
270
271
  /* bring hardware to a sane state. this has to be done, just in case someone
     wants to capture from this device before it has been properly initialized.
     the capture engine would badly fail, because no valid signal arrives on the
     saa7146, thus leading to timeouts and stuff. */
  static int mxb_init_done(struct saa7146_dev* dev)
  {
  	struct mxb* mxb = (struct mxb*)dev->ext_priv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
272
  	struct i2c_msg msg;
85369df35   Mauro Carvalho Chehab   [PATCH] v4l: MXB ...
273
  	struct tuner_setup tun_setup;
6acaba8e2   Michael Hunold   [PATCH] Restore t...
274
  	v4l2_std_id std = V4L2_STD_PAL_BG;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
275
276
  
  	int i = 0, err = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
277
278
  
  	/* select video mode in saa7111a */
f41737ece   Hans Verkuil   V4L/DVB (11370): ...
279
  	saa7111a_call(mxb, core, s_std, std);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
281
282
  
  	/* select tuner-output on saa7111a */
  	i = 0;
5325b4272   Hans Verkuil   V4L/DVB (11380): ...
283
  	saa7111a_call(mxb, video, s_routing, SAA7115_COMPOSITE0,
340dde817   Hans Verkuil   V4L/DVB: saa7115:...
284
  		SAA7111_FMT_CCIR, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
286
  
  	/* select a tuner type */
85369df35   Mauro Carvalho Chehab   [PATCH] v4l: MXB ...
287
288
  	tun_setup.mode_mask = T_ANALOG_TV;
  	tun_setup.addr = ADDR_UNSET;
9d2599d98   Michael Hunold   [PATCH] v4l: fix ...
289
  	tun_setup.type = TUNER_PHILIPS_PAL;
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
290
  	tuner_call(mxb, tuner, s_type_addr, &tun_setup);
9d2599d98   Michael Hunold   [PATCH] v4l: fix ...
291
292
293
294
  	/* tune in some frequency on tuner */
  	mxb->cur_freq.tuner = 0;
  	mxb->cur_freq.type = V4L2_TUNER_ANALOG_TV;
  	mxb->cur_freq.frequency = freq;
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
295
  	tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
9d2599d98   Michael Hunold   [PATCH] v4l: fix ...
296

6acaba8e2   Michael Hunold   [PATCH] Restore t...
297
  	/* set a default video standard */
f41737ece   Hans Verkuil   V4L/DVB (11370): ...
298
  	tuner_call(mxb, core, s_std, std);
6acaba8e2   Michael Hunold   [PATCH] Restore t...
299

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
300
  	/* mute audio on tea6420s */
5325b4272   Hans Verkuil   V4L/DVB (11380): ...
301
302
  	tea6420_route_line(mxb, 6);
  	tea6420_route_cd(mxb, 6);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303

1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
304
  	/* switch to tuner-channel on tea6415c */
5325b4272   Hans Verkuil   V4L/DVB (11380): ...
305
  	tea6415c_call(mxb, video, s_routing, 3, 17, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306

1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
307
  	/* select tuner-output on multicable on tea6415c */
5325b4272   Hans Verkuil   V4L/DVB (11380): ...
308
  	tea6415c_call(mxb, video, s_routing, 3, 13, 0);
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
309

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
311
  	/* the rest for mxb */
  	mxb->cur_input = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312
313
314
  	mxb->cur_mute = 1;
  
  	mxb->cur_mode = V4L2_TUNER_MODE_STEREO;
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
315

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
316
  	/* check if the saa7740 (aka 'sound arena module') is present
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
317
  	   on the mxb. if so, we must initialize it. due to lack of
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318
319
320
321
322
323
  	   informations about the saa7740, the values were reverse
  	   engineered. */
  	msg.addr = 0x1b;
  	msg.flags = 0;
  	msg.len = mxb_saa7740_init[0].length;
  	msg.buf = &mxb_saa7740_init[0].data[0];
2633812f8   Hans Verkuil   V4L/DVB (8942): m...
324
325
  	err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
  	if (err == 1) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
326
327
328
329
330
331
  		/* the sound arena module is a pos, that's probably the reason
  		   philips refuses to hand out a datasheet for the saa7740...
  		   it seems to screw up the i2c bus, so we disable fast irq
  		   based i2c transactions here and rely on the slow and safe
  		   polling method ... */
  		extension.flags &= ~SAA7146_USE_I2C_IRQ;
2633812f8   Hans Verkuil   V4L/DVB (8942): m...
332
333
  		for (i = 1; ; i++) {
  			if (-1 == mxb_saa7740_init[i].length)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
334
  				break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
335

a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
336
  			msg.len = mxb_saa7740_init[i].length;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
337
  			msg.buf = &mxb_saa7740_init[i].data[0];
2633812f8   Hans Verkuil   V4L/DVB (8942): m...
338
339
  			err = i2c_transfer(&mxb->i2c_adapter, &msg, 1);
  			if (err != 1) {
44d0b80e5   Joe Perches   [media] saa7146: ...
340
341
  				DEB_D("failed to initialize 'sound arena module'
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
342
343
344
  				goto err;
  			}
  		}
44d0b80e5   Joe Perches   [media] saa7146: ...
345
346
  		pr_info("'sound arena module' detected
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347
  	}
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
348
  err:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
350
351
352
  	/* the rest for saa7146: you should definitely set some basic values
  	   for the input-port handling of the saa7146. */
  
  	/* ext->saa has been filled by the core driver */
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
353

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354
  	/* some stuff is done via variables */
2633812f8   Hans Verkuil   V4L/DVB (8942): m...
355
356
  	saa7146_set_hps_source_and_sync(dev, input_port_selection[mxb->cur_input].hps_source,
  			input_port_selection[mxb->cur_input].hps_sync);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
357
358
359
360
361
  
  	/* some stuff is done via direct write to the registers */
  
  	/* this is ugly, but because of the fact that this is completely
  	   hardware dependend, it should be done directly... */
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
362
  	saa7146_write(dev, DD1_STREAM_B,	0x00000000);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
363
364
365
366
367
368
369
370
371
372
373
374
375
376
  	saa7146_write(dev, DD1_INIT,		0x02000200);
  	saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
  
  	return 0;
  }
  
  /* interrupt-handler. this gets called when irq_mask is != 0.
     it must clear the interrupt-bits in irq_mask it has handled */
  /*
  void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
  {
  	struct mxb* mxb = (struct mxb*)dev->ext_priv;
  }
  */
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
377
  static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378
  {
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
379
380
  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  	int i;
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
381

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
382
383
384
  	for (i = MAXCONTROLS - 1; i >= 0; i--) {
  		if (mxb_controls[i].id == qc->id) {
  			*qc = mxb_controls[i];
44d0b80e5   Joe Perches   [media] saa7146: ...
385
386
  			DEB_D("VIDIOC_QUERYCTRL %d
  ", qc->id);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
387
388
389
390
391
  			return 0;
  		}
  	}
  	return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
392

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
393
394
395
396
397
  static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
  {
  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  	struct mxb *mxb = (struct mxb *)dev->ext_priv;
  	int i;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
398

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
399
400
401
  	for (i = MAXCONTROLS - 1; i >= 0; i--) {
  		if (mxb_controls[i].id == vc->id)
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
  	}
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
403

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
404
405
  	if (i < 0)
  		return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
406

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
407
408
  	if (vc->id == V4L2_CID_AUDIO_MUTE) {
  		vc->value = mxb->cur_mute;
44d0b80e5   Joe Perches   [media] saa7146: ...
409
410
  		DEB_D("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d
  ", vc->value);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
411
412
  		return 0;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
413

44d0b80e5   Joe Perches   [media] saa7146: ...
414
415
  	DEB_EE("VIDIOC_G_CTRL V4L2_CID_AUDIO_MUTE:%d
  ", vc->value);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
416
417
  	return 0;
  }
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
418
  static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
419
  {
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
420
  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
2633812f8   Hans Verkuil   V4L/DVB (8942): m...
421
  	struct mxb *mxb = (struct mxb *)dev->ext_priv;
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
422
  	int i = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
424
425
426
427
  	for (i = MAXCONTROLS - 1; i >= 0; i--) {
  		if (mxb_controls[i].id == vc->id)
  			break;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
428

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
429
430
  	if (i < 0)
  		return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
431

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
432
433
  	if (vc->id == V4L2_CID_AUDIO_MUTE) {
  		mxb->cur_mute = vc->value;
5325b4272   Hans Verkuil   V4L/DVB (11380): ...
434
435
436
  		/* switch the audio-source */
  		tea6420_route_line(mxb, vc->value ? 6 :
  				video_audio_connect[mxb->cur_input]);
44d0b80e5   Joe Perches   [media] saa7146: ...
437
438
  		DEB_EE("VIDIOC_S_CTRL, V4L2_CID_AUDIO_MUTE: %d
  ", vc->value);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
439
440
441
  	}
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
443
444
  static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
  {
44d0b80e5   Joe Perches   [media] saa7146: ...
445
446
  	DEB_EE("VIDIOC_ENUMINPUT %d
  ", i->index);
223ffe5f8   Roel Kluin   V4L/DVB: cleanup ...
447
  	if (i->index >= MXB_INPUTS)
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
448
449
  		return -EINVAL;
  	memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
450
451
  	return 0;
  }
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
452
  static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
453
  {
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
454
  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
2633812f8   Hans Verkuil   V4L/DVB (8942): m...
455
  	struct mxb *mxb = (struct mxb *)dev->ext_priv;
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
456
  	*i = mxb->cur_input;
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
457

44d0b80e5   Joe Perches   [media] saa7146: ...
458
459
  	DEB_EE("VIDIOC_G_INPUT %d
  ", *i);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
460
461
  	return 0;
  }
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
462

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
463
464
465
466
  static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
  {
  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  	struct mxb *mxb = (struct mxb *)dev->ext_priv;
5325b4272   Hans Verkuil   V4L/DVB (11380): ...
467
  	int err = 0;
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
468
  	int i = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
469

44d0b80e5   Joe Perches   [media] saa7146: ...
470
471
  	DEB_EE("VIDIOC_S_INPUT %d
  ", input);
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
472

f14a2972e   Roel Kluin   V4L/DVB (13241): ...
473
  	if (input >= MXB_INPUTS)
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
474
  		return -EINVAL;
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
475

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
476
  	mxb->cur_input = input;
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
477

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
478
479
  	saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source,
  			input_port_selection[input].hps_sync);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
480

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
481
482
483
484
485
  	/* prepare switching of tea6415c and saa7111a;
  	   have a look at the 'background'-file for further informations  */
  	switch (input) {
  	case TUNER:
  		i = SAA7115_COMPOSITE0;
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
486

5325b4272   Hans Verkuil   V4L/DVB (11380): ...
487
  		err = tea6415c_call(mxb, video, s_routing, 3, 17, 0);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
488
  		/* connect tuner-output always to multicable */
5325b4272   Hans Verkuil   V4L/DVB (11380): ...
489
490
  		if (!err)
  			err = tea6415c_call(mxb, video, s_routing, 3, 13, 0);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
491
492
493
494
495
496
497
498
499
500
501
502
503
  		break;
  	case AUX3_YC:
  		/* nothing to be done here. aux3_yc is
  		   directly connected to the saa711a */
  		i = SAA7115_SVIDEO1;
  		break;
  	case AUX3:
  		/* nothing to be done here. aux3 is
  		   directly connected to the saa711a */
  		i = SAA7115_COMPOSITE1;
  		break;
  	case AUX1:
  		i = SAA7115_COMPOSITE0;
5325b4272   Hans Verkuil   V4L/DVB (11380): ...
504
  		err = tea6415c_call(mxb, video, s_routing, 1, 17, 0);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
505
506
  		break;
  	}
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
507

5325b4272   Hans Verkuil   V4L/DVB (11380): ...
508
509
  	if (err)
  		return err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
510

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
511
  	/* switch video in saa7111a */
340dde817   Hans Verkuil   V4L/DVB: saa7115:...
512
  	if (saa7111a_call(mxb, video, s_routing, i, SAA7111_FMT_CCIR, 0))
44d0b80e5   Joe Perches   [media] saa7146: ...
513
514
  		pr_err("VIDIOC_S_INPUT: could not address saa7111a
  ");
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
515
516
  
  	/* switch the audio-source only if necessary */
5325b4272   Hans Verkuil   V4L/DVB (11380): ...
517
518
  	if (0 == mxb->cur_mute)
  		tea6420_route_line(mxb, video_audio_connect[input]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
519

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
520
521
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
522

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
523
524
525
526
  static int vidioc_g_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
  {
  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  	struct mxb *mxb = (struct mxb *)dev->ext_priv;
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
527

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
528
  	if (t->index) {
44d0b80e5   Joe Perches   [media] saa7146: ...
529
530
531
  		DEB_D("VIDIOC_G_TUNER: channel %d does not have a tuner attached
  ",
  		      t->index);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
532
533
  		return -EINVAL;
  	}
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
534

44d0b80e5   Joe Perches   [media] saa7146: ...
535
536
  	DEB_EE("VIDIOC_G_TUNER: %d
  ", t->index);
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
537

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
538
  	memset(t, 0, sizeof(*t));
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
539
540
541
542
543
  	strlcpy(t->name, "TV Tuner", sizeof(t->name));
  	t->type = V4L2_TUNER_ANALOG_TV;
  	t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO |
  			V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
  	t->audmode = mxb->cur_mode;
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
544
  	return call_all(dev, tuner, g_tuner, t);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
545
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
546

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
547
548
549
550
  static int vidioc_s_tuner(struct file *file, void *fh, struct v4l2_tuner *t)
  {
  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  	struct mxb *mxb = (struct mxb *)dev->ext_priv;
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
551

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
552
  	if (t->index) {
44d0b80e5   Joe Perches   [media] saa7146: ...
553
554
555
  		DEB_D("VIDIOC_S_TUNER: channel %d does not have a tuner attached
  ",
  		      t->index);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
556
557
  		return -EINVAL;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
558

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
559
  	mxb->cur_mode = t->audmode;
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
560
  	return call_all(dev, tuner, s_tuner, t);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
561
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
562

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
563
564
565
566
567
568
  static int vidioc_g_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
  {
  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  	struct mxb *mxb = (struct mxb *)dev->ext_priv;
  
  	if (mxb->cur_input) {
44d0b80e5   Joe Perches   [media] saa7146: ...
569
570
571
  		DEB_D("VIDIOC_G_FREQ: channel %d does not have a tuner!
  ",
  		      mxb->cur_input);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
572
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
573
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
574

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
575
  	*f = mxb->cur_freq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
576

44d0b80e5   Joe Perches   [media] saa7146: ...
577
578
  	DEB_EE("VIDIOC_G_FREQ: freq:0x%08x
  ", mxb->cur_freq.frequency);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
579
580
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
581

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
582
583
584
585
586
  static int vidioc_s_frequency(struct file *file, void *fh, struct v4l2_frequency *f)
  {
  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  	struct mxb *mxb = (struct mxb *)dev->ext_priv;
  	struct saa7146_vv *vv = dev->vv_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
587

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
588
589
  	if (f->tuner)
  		return -EINVAL;
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
590

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
591
592
  	if (V4L2_TUNER_ANALOG_TV != f->type)
  		return -EINVAL;
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
593

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
594
  	if (mxb->cur_input) {
44d0b80e5   Joe Perches   [media] saa7146: ...
595
596
597
  		DEB_D("VIDIOC_S_FREQ: channel %d does not have a tuner!
  ",
  		      mxb->cur_input);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
598
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
599
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
600

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
601
  	mxb->cur_freq = *f;
44d0b80e5   Joe Perches   [media] saa7146: ...
602
603
  	DEB_EE("VIDIOC_S_FREQUENCY: freq:0x%08x
  ", mxb->cur_freq.frequency);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
604

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
605
  	/* tune in desired frequency */
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
606
  	tuner_call(mxb, tuner, s_frequency, &mxb->cur_freq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
607

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
608
609
610
611
612
613
614
615
616
617
618
619
  	/* hack: changing the frequency should invalidate the vbi-counter (=> alevt) */
  	spin_lock(&dev->slock);
  	vv->vbi_fieldcount = 0;
  	spin_unlock(&dev->slock);
  
  	return 0;
  }
  
  static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
  {
  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  	struct mxb *mxb = (struct mxb *)dev->ext_priv;
223ffe5f8   Roel Kluin   V4L/DVB: cleanup ...
620
  	if (a->index > MXB_INPUTS) {
44d0b80e5   Joe Perches   [media] saa7146: ...
621
622
  		DEB_D("VIDIOC_G_AUDIO %d out of range
  ", a->index);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
623
  		return -EINVAL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
624
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
625

44d0b80e5   Joe Perches   [media] saa7146: ...
626
627
  	DEB_EE("VIDIOC_G_AUDIO %d
  ", a->index);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
628
629
630
  	memcpy(a, &mxb_audios[video_audio_connect[mxb->cur_input]], sizeof(struct v4l2_audio));
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
631

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
632
633
  static int vidioc_s_audio(struct file *file, void *fh, struct v4l2_audio *a)
  {
44d0b80e5   Joe Perches   [media] saa7146: ...
634
635
  	DEB_D("VIDIOC_S_AUDIO %d
  ", a->index);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
636
637
  	return 0;
  }
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
638

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
639
640
641
642
  #ifdef CONFIG_VIDEO_ADV_DEBUG
  static int vidioc_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
  {
  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
643

1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
644
  	return call_all(dev, core, g_register, reg);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
645
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
647
648
649
  static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
  {
  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
650

1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
651
  	return call_all(dev, core, s_register, reg);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
652
653
  }
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
654

99cd47bc7   Hans Verkuil   [media] v4l2-ioct...
655
656
  static long vidioc_default(struct file *file, void *fh, bool valid_prio,
  							int cmd, void *arg)
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
657
658
659
660
661
  {
  	struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
  	struct mxb *mxb = (struct mxb *)dev->ext_priv;
  
  	switch (cmd) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
663
  	case MXB_S_AUDIO_CD:
  	{
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
664
  		int i = *(int *)arg;
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
665

2633812f8   Hans Verkuil   V4L/DVB (8942): m...
666
  		if (i < 0 || i >= MXB_AUDIOS) {
44d0b80e5   Joe Perches   [media] saa7146: ...
667
668
  			DEB_D("invalid argument to MXB_S_AUDIO_CD: i:%d
  ", i);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
669
670
  			return -EINVAL;
  		}
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
671

44d0b80e5   Joe Perches   [media] saa7146: ...
672
673
  		DEB_EE("MXB_S_AUDIO_CD: i:%d
  ", i);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
674

5325b4272   Hans Verkuil   V4L/DVB (11380): ...
675
  		tea6420_route_cd(mxb, i);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
676
677
678
679
  		return 0;
  	}
  	case MXB_S_AUDIO_LINE:
  	{
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
680
  		int i = *(int *)arg;
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
681

2633812f8   Hans Verkuil   V4L/DVB (8942): m...
682
  		if (i < 0 || i >= MXB_AUDIOS) {
44d0b80e5   Joe Perches   [media] saa7146: ...
683
684
685
  			DEB_D("invalid argument to MXB_S_AUDIO_LINE: i:%d
  ",
  			      i);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
686
687
  			return -EINVAL;
  		}
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
688

44d0b80e5   Joe Perches   [media] saa7146: ...
689
690
  		DEB_EE("MXB_S_AUDIO_LINE: i:%d
  ", i);
5325b4272   Hans Verkuil   V4L/DVB (11380): ...
691
  		tea6420_route_line(mxb, i);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
692
693
  		return 0;
  	}
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
694
695
  	default:
  /*
44d0b80e5   Joe Perches   [media] saa7146: ...
696
697
  		DEB2(pr_err("does not handle this ioctl
  "));
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
698
699
700
701
702
  */
  		return -ENOIOCTLCMD;
  	}
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
703

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
704
705
706
707
708
  static struct saa7146_ext_vv vv_data;
  
  /* this function only gets called when the probing was successful */
  static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
  {
03b1930ef   Hans Verkuil   V4L/DVB: saa7146:...
709
  	struct mxb *mxb;
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
710

44d0b80e5   Joe Perches   [media] saa7146: ...
711
712
  	DEB_EE("dev:%p
  ", dev);
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
713

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
714
  	saa7146_vv_init(dev, &vv_data);
03b1930ef   Hans Verkuil   V4L/DVB: saa7146:...
715
716
717
718
719
  	if (mxb_probe(dev)) {
  		saa7146_vv_release(dev);
  		return -1;
  	}
  	mxb = (struct mxb *)dev->ext_priv;
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
720
721
722
723
724
725
726
727
728
729
730
731
  	vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
  	vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
  	vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
  	vv_data.ops.vidioc_enum_input = vidioc_enum_input;
  	vv_data.ops.vidioc_g_input = vidioc_g_input;
  	vv_data.ops.vidioc_s_input = vidioc_s_input;
  	vv_data.ops.vidioc_g_tuner = vidioc_g_tuner;
  	vv_data.ops.vidioc_s_tuner = vidioc_s_tuner;
  	vv_data.ops.vidioc_g_frequency = vidioc_g_frequency;
  	vv_data.ops.vidioc_s_frequency = vidioc_s_frequency;
  	vv_data.ops.vidioc_g_audio = vidioc_g_audio;
  	vv_data.ops.vidioc_s_audio = vidioc_s_audio;
2633812f8   Hans Verkuil   V4L/DVB (8942): m...
732
  #ifdef CONFIG_VIDEO_ADV_DEBUG
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
733
734
  	vv_data.ops.vidioc_g_register = vidioc_g_register;
  	vv_data.ops.vidioc_s_register = vidioc_s_register;
2633812f8   Hans Verkuil   V4L/DVB (8942): m...
735
  #endif
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
736
737
  	vv_data.ops.vidioc_default = vidioc_default;
  	if (saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
44d0b80e5   Joe Perches   [media] saa7146: ...
738
739
  		ERR("cannot register capture v4l2 device. skipping.
  ");
03b1930ef   Hans Verkuil   V4L/DVB: saa7146:...
740
  		saa7146_vv_release(dev);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
741
742
743
744
745
746
  		return -1;
  	}
  
  	/* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
  	if (MXB_BOARD_CAN_DO_VBI(dev)) {
  		if (saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
44d0b80e5   Joe Perches   [media] saa7146: ...
747
748
  			ERR("cannot register vbi v4l2 device. skipping.
  ");
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
749
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
750
  	}
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
751

44d0b80e5   Joe Perches   [media] saa7146: ...
752
753
  	pr_info("found Multimedia eXtension Board #%d
  ", mxb_num);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
754
755
756
757
758
759
760
761
762
  
  	mxb_num++;
  	mxb_init_done(dev);
  	return 0;
  }
  
  static int mxb_detach(struct saa7146_dev *dev)
  {
  	struct mxb *mxb = (struct mxb *)dev->ext_priv;
44d0b80e5   Joe Perches   [media] saa7146: ...
763
764
  	DEB_EE("dev:%p
  ", dev);
b960074fe   Hans Verkuil   V4L/DVB (10271): ...
765

b960074fe   Hans Verkuil   V4L/DVB (10271): ...
766
767
768
769
770
771
772
773
774
  	saa7146_unregister_device(&mxb->video_dev,dev);
  	if (MXB_BOARD_CAN_DO_VBI(dev))
  		saa7146_unregister_device(&mxb->vbi_dev, dev);
  	saa7146_vv_release(dev);
  
  	mxb_num--;
  
  	i2c_del_adapter(&mxb->i2c_adapter);
  	kfree(mxb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
775
776
  	return 0;
  }
c6eb8eafd   Hans Verkuil   V4L/DVB (8757): v...
777
  static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *standard)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
778
  {
c6eb8eafd   Hans Verkuil   V4L/DVB (8757): v...
779
  	struct mxb *mxb = (struct mxb *)dev->ext_priv;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
780

c6eb8eafd   Hans Verkuil   V4L/DVB (8757): v...
781
  	if (V4L2_STD_PAL_I == standard->id) {
6acaba8e2   Michael Hunold   [PATCH] Restore t...
782
  		v4l2_std_id std = V4L2_STD_PAL_I;
c6eb8eafd   Hans Verkuil   V4L/DVB (8757): v...
783

44d0b80e5   Joe Perches   [media] saa7146: ...
784
785
  		DEB_D("VIDIOC_S_STD: setting mxb for PAL_I
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
786
  		/* set the 7146 gpio register -- I don't know what this does exactly */
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
787
  		saa7146_write(dev, GPIO_CTRL, 0x00404050);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
788
  		/* unset the 7111 gpio register -- I don't know what this does exactly */
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
789
  		saa7111a_call(mxb, core, s_gpio, 0);
f41737ece   Hans Verkuil   V4L/DVB (11370): ...
790
  		tuner_call(mxb, core, s_std, std);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
791
  	} else {
6acaba8e2   Michael Hunold   [PATCH] Restore t...
792
  		v4l2_std_id std = V4L2_STD_PAL_BG;
c6eb8eafd   Hans Verkuil   V4L/DVB (8757): v...
793

44d0b80e5   Joe Perches   [media] saa7146: ...
794
795
  		DEB_D("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
796
  		/* set the 7146 gpio register -- I don't know what this does exactly */
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
797
  		saa7146_write(dev, GPIO_CTRL, 0x00404050);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
798
  		/* set the 7111 gpio register -- I don't know what this does exactly */
1b8dac150   Hans Verkuil   V4L/DVB (10499): ...
799
  		saa7111a_call(mxb, core, s_gpio, 1);
f41737ece   Hans Verkuil   V4L/DVB (11370): ...
800
  		tuner_call(mxb, core, s_std, std);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
  	}
  	return 0;
  }
  
  static struct saa7146_standard standard[] = {
  	{
  		.name	= "PAL-BG", 	.id	= V4L2_STD_PAL_BG,
  		.v_offset	= 0x17,	.v_field 	= 288,
  		.h_offset	= 0x14,	.h_pixels 	= 680,
  		.v_max_out	= 576,	.h_max_out	= 768,
  	}, {
  		.name	= "PAL-I", 	.id	= V4L2_STD_PAL_I,
  		.v_offset	= 0x17,	.v_field 	= 288,
  		.h_offset	= 0x14,	.h_pixels 	= 680,
  		.v_max_out	= 576,	.h_max_out	= 768,
  	}, {
  		.name	= "NTSC", 	.id	= V4L2_STD_NTSC,
  		.v_offset	= 0x16,	.v_field 	= 240,
  		.h_offset	= 0x06,	.h_pixels 	= 708,
  		.v_max_out	= 480,	.h_max_out	= 640,
  	}, {
  		.name	= "SECAM", 	.id	= V4L2_STD_SECAM,
  		.v_offset	= 0x14,	.v_field 	= 288,
  		.h_offset	= 0x14,	.h_pixels 	= 720,
  		.v_max_out	= 576,	.h_max_out	= 768,
  	}
  };
  
  static struct saa7146_pci_extension_data mxb = {
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
830
831
  	.ext_priv = "Multimedia eXtension Board",
  	.ext = &extension,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
  };
  
  static struct pci_device_id pci_tbl[] = {
  	{
  		.vendor    = PCI_VENDOR_ID_PHILIPS,
  		.device	   = PCI_DEVICE_ID_PHILIPS_SAA7146,
  		.subvendor = 0x0000,
  		.subdevice = 0x0000,
  		.driver_data = (unsigned long)&mxb,
  	}, {
  		.vendor	= 0,
  	}
  };
  
  MODULE_DEVICE_TABLE(pci, pci_tbl);
  
  static struct saa7146_ext_vv vv_data = {
  	.inputs		= MXB_INPUTS,
  	.capabilities	= V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
  	.stds		= &standard[0],
  	.num_stds	= sizeof(standard)/sizeof(struct saa7146_standard),
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
853
  	.std_callback	= &std_callback,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
854
855
856
857
858
  };
  
  static struct saa7146_extension extension = {
  	.name		= MXB_IDENTIFIER,
  	.flags		= SAA7146_USE_I2C_IRQ,
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
859

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
860
861
  	.pci_tbl	= &pci_tbl[0],
  	.module		= THIS_MODULE,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
862
863
864
865
866
  	.attach		= mxb_attach,
  	.detach		= mxb_detach,
  
  	.irq_mask	= 0,
  	.irq_func	= NULL,
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
867
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
868
869
870
  
  static int __init mxb_init_module(void)
  {
2633812f8   Hans Verkuil   V4L/DVB (8942): m...
871
  	if (saa7146_register_extension(&extension)) {
44d0b80e5   Joe Perches   [media] saa7146: ...
872
873
  		DEB_S("failed to register extension
  ");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
874
875
  		return -ENODEV;
  	}
a8733ca51   Mauro Carvalho Chehab   V4L/DVB (3537a): ...
876

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
877
878
879
880
881
882
883
884
885
886
887
888
889
890
  	return 0;
  }
  
  static void __exit mxb_cleanup_module(void)
  {
  	saa7146_unregister_extension(&extension);
  }
  
  module_init(mxb_init_module);
  module_exit(mxb_cleanup_module);
  
  MODULE_DESCRIPTION("video4linux-2 driver for the Siemens-Nixdorf 'Multimedia eXtension board'");
  MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
  MODULE_LICENSE("GPL");