diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-13 23:13:22 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-15 15:25:07 -0400 |
commit | 0c0d06cac63ee327ceaab4b5ffe2206574ab86bd (patch) | |
tree | e759f0dc3185d97f2a0c6b5cd5e32ea6faa74d40 /drivers/media/video/em28xx | |
parent | 84cfe9e79bd5ac11c963f4841158454fefa872f6 (diff) |
[media] rename most media/video usb drivers to media/usb
Rename all USB drivers with their own directory under
drivers/media/video into drivers/media/usb and update the
building system.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/em28xx')
-rw-r--r-- | drivers/media/video/em28xx/Kconfig | 58 | ||||
-rw-r--r-- | drivers/media/video/em28xx/Makefile | 15 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-audio.c | 751 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-cards.c | 3417 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 1260 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-dvb.c | 1197 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-i2c.c | 568 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-input.c | 645 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-reg.h | 226 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-vbi.c | 145 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 2624 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 809 |
12 files changed, 0 insertions, 11715 deletions
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig deleted file mode 100644 index 928ef0d0429f..000000000000 --- a/drivers/media/video/em28xx/Kconfig +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | config VIDEO_EM28XX | ||
2 | tristate "Empia EM28xx USB video capture support" | ||
3 | depends on VIDEO_DEV && I2C | ||
4 | select VIDEO_TUNER | ||
5 | select VIDEO_TVEEPROM | ||
6 | select VIDEOBUF_VMALLOC | ||
7 | select VIDEO_SAA711X if VIDEO_HELPER_CHIPS_AUTO | ||
8 | select VIDEO_TVP5150 if VIDEO_HELPER_CHIPS_AUTO | ||
9 | select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO | ||
10 | select VIDEO_MT9V011 if VIDEO_HELPER_CHIPS_AUTO | ||
11 | |||
12 | ---help--- | ||
13 | This is a video4linux driver for Empia 28xx based TV cards. | ||
14 | |||
15 | To compile this driver as a module, choose M here: the | ||
16 | module will be called em28xx | ||
17 | |||
18 | config VIDEO_EM28XX_ALSA | ||
19 | depends on VIDEO_EM28XX && SND | ||
20 | select SND_PCM | ||
21 | tristate "Empia EM28xx ALSA audio module" | ||
22 | ---help--- | ||
23 | This is an ALSA driver for some Empia 28xx based TV cards. | ||
24 | |||
25 | This is not required for em2800/em2820/em2821 boards. However, | ||
26 | newer em28xx devices uses Vendor Class for audio, instead of | ||
27 | implementing the USB Audio Class. For those chips, this module | ||
28 | will enable digital audio. | ||
29 | |||
30 | To compile this driver as a module, choose M here: the | ||
31 | module will be called em28xx-alsa | ||
32 | |||
33 | config VIDEO_EM28XX_DVB | ||
34 | tristate "DVB/ATSC Support for em28xx based TV cards" | ||
35 | depends on VIDEO_EM28XX && DVB_CORE | ||
36 | select DVB_LGDT330X if !DVB_FE_CUSTOMISE | ||
37 | select DVB_ZL10353 if !DVB_FE_CUSTOMISE | ||
38 | select DVB_TDA10023 if !DVB_FE_CUSTOMISE | ||
39 | select DVB_S921 if !DVB_FE_CUSTOMISE | ||
40 | select DVB_DRXD if !DVB_FE_CUSTOMISE | ||
41 | select DVB_CXD2820R if !DVB_FE_CUSTOMISE | ||
42 | select DVB_DRXK if !DVB_FE_CUSTOMISE | ||
43 | select DVB_TDA18271C2DD if !DVB_FE_CUSTOMISE | ||
44 | select DVB_TDA10071 if !DVB_FE_CUSTOMISE | ||
45 | select DVB_A8293 if !DVB_FE_CUSTOMISE | ||
46 | select VIDEOBUF_DVB | ||
47 | ---help--- | ||
48 | This adds support for DVB cards based on the | ||
49 | Empiatech em28xx chips. | ||
50 | |||
51 | config VIDEO_EM28XX_RC | ||
52 | tristate "EM28XX Remote Controller support" | ||
53 | depends on RC_CORE | ||
54 | depends on VIDEO_EM28XX | ||
55 | depends on !(RC_CORE=m && VIDEO_EM28XX=y) | ||
56 | default VIDEO_EM28XX | ||
57 | ---help--- | ||
58 | Enables Remote Controller support on em28xx driver. | ||
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile deleted file mode 100644 index 65c7c29e4161..000000000000 --- a/drivers/media/video/em28xx/Makefile +++ /dev/null | |||
@@ -1,15 +0,0 @@ | |||
1 | em28xx-y := em28xx-video.o em28xx-i2c.o em28xx-cards.o | ||
2 | em28xx-y += em28xx-core.o em28xx-vbi.o | ||
3 | |||
4 | em28xx-alsa-objs := em28xx-audio.o | ||
5 | em28xx-rc-objs := em28xx-input.o | ||
6 | |||
7 | obj-$(CONFIG_VIDEO_EM28XX) += em28xx.o | ||
8 | obj-$(CONFIG_VIDEO_EM28XX_ALSA) += em28xx-alsa.o | ||
9 | obj-$(CONFIG_VIDEO_EM28XX_DVB) += em28xx-dvb.o | ||
10 | obj-$(CONFIG_VIDEO_EM28XX_RC) += em28xx-rc.o | ||
11 | |||
12 | ccflags-y += -Idrivers/media/video | ||
13 | ccflags-y += -Idrivers/media/tuners | ||
14 | ccflags-y += -Idrivers/media/dvb-core | ||
15 | ccflags-y += -Idrivers/media/dvb-frontends | ||
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c deleted file mode 100644 index 2fdb66ee44ab..000000000000 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ /dev/null | |||
@@ -1,751 +0,0 @@ | |||
1 | /* | ||
2 | * Empiatech em28x1 audio extension | ||
3 | * | ||
4 | * Copyright (C) 2006 Markus Rechberger <mrechberger@gmail.com> | ||
5 | * | ||
6 | * Copyright (C) 2007-2011 Mauro Carvalho Chehab <mchehab@redhat.com> | ||
7 | * - Port to work with the in-kernel driver | ||
8 | * - Cleanups, fixes, alsa-controls, etc. | ||
9 | * | ||
10 | * This driver is based on my previous au600 usb pstn audio driver | ||
11 | * and inherits all the copyrights | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License as published by | ||
15 | * the Free Software Foundation; either version 2 of the License, or | ||
16 | * (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | */ | ||
27 | |||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/usb.h> | ||
30 | #include <linux/init.h> | ||
31 | #include <linux/sound.h> | ||
32 | #include <linux/spinlock.h> | ||
33 | #include <linux/soundcard.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/vmalloc.h> | ||
36 | #include <linux/proc_fs.h> | ||
37 | #include <linux/module.h> | ||
38 | #include <sound/core.h> | ||
39 | #include <sound/pcm.h> | ||
40 | #include <sound/pcm_params.h> | ||
41 | #include <sound/info.h> | ||
42 | #include <sound/initval.h> | ||
43 | #include <sound/control.h> | ||
44 | #include <sound/tlv.h> | ||
45 | #include <sound/ac97_codec.h> | ||
46 | #include <media/v4l2-common.h> | ||
47 | #include "em28xx.h" | ||
48 | |||
49 | static int debug; | ||
50 | module_param(debug, int, 0644); | ||
51 | MODULE_PARM_DESC(debug, "activates debug info"); | ||
52 | |||
53 | #define dprintk(fmt, arg...) do { \ | ||
54 | if (debug) \ | ||
55 | printk(KERN_INFO "em28xx-audio %s: " fmt, \ | ||
56 | __func__, ##arg); \ | ||
57 | } while (0) | ||
58 | |||
59 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | ||
60 | |||
61 | static int em28xx_deinit_isoc_audio(struct em28xx *dev) | ||
62 | { | ||
63 | int i; | ||
64 | |||
65 | dprintk("Stopping isoc\n"); | ||
66 | for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { | ||
67 | if (!irqs_disabled()) | ||
68 | usb_kill_urb(dev->adev.urb[i]); | ||
69 | else | ||
70 | usb_unlink_urb(dev->adev.urb[i]); | ||
71 | |||
72 | usb_free_urb(dev->adev.urb[i]); | ||
73 | dev->adev.urb[i] = NULL; | ||
74 | |||
75 | kfree(dev->adev.transfer_buffer[i]); | ||
76 | dev->adev.transfer_buffer[i] = NULL; | ||
77 | } | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static void em28xx_audio_isocirq(struct urb *urb) | ||
83 | { | ||
84 | struct em28xx *dev = urb->context; | ||
85 | int i; | ||
86 | unsigned int oldptr; | ||
87 | int period_elapsed = 0; | ||
88 | int status; | ||
89 | unsigned char *cp; | ||
90 | unsigned int stride; | ||
91 | struct snd_pcm_substream *substream; | ||
92 | struct snd_pcm_runtime *runtime; | ||
93 | |||
94 | switch (urb->status) { | ||
95 | case 0: /* success */ | ||
96 | case -ETIMEDOUT: /* NAK */ | ||
97 | break; | ||
98 | case -ECONNRESET: /* kill */ | ||
99 | case -ENOENT: | ||
100 | case -ESHUTDOWN: | ||
101 | return; | ||
102 | default: /* error */ | ||
103 | dprintk("urb completition error %d.\n", urb->status); | ||
104 | break; | ||
105 | } | ||
106 | |||
107 | if (atomic_read(&dev->stream_started) == 0) | ||
108 | return; | ||
109 | |||
110 | if (dev->adev.capture_pcm_substream) { | ||
111 | substream = dev->adev.capture_pcm_substream; | ||
112 | runtime = substream->runtime; | ||
113 | stride = runtime->frame_bits >> 3; | ||
114 | |||
115 | for (i = 0; i < urb->number_of_packets; i++) { | ||
116 | int length = | ||
117 | urb->iso_frame_desc[i].actual_length / stride; | ||
118 | cp = (unsigned char *)urb->transfer_buffer + | ||
119 | urb->iso_frame_desc[i].offset; | ||
120 | |||
121 | if (!length) | ||
122 | continue; | ||
123 | |||
124 | oldptr = dev->adev.hwptr_done_capture; | ||
125 | if (oldptr + length >= runtime->buffer_size) { | ||
126 | unsigned int cnt = | ||
127 | runtime->buffer_size - oldptr; | ||
128 | memcpy(runtime->dma_area + oldptr * stride, cp, | ||
129 | cnt * stride); | ||
130 | memcpy(runtime->dma_area, cp + cnt * stride, | ||
131 | length * stride - cnt * stride); | ||
132 | } else { | ||
133 | memcpy(runtime->dma_area + oldptr * stride, cp, | ||
134 | length * stride); | ||
135 | } | ||
136 | |||
137 | snd_pcm_stream_lock(substream); | ||
138 | |||
139 | dev->adev.hwptr_done_capture += length; | ||
140 | if (dev->adev.hwptr_done_capture >= | ||
141 | runtime->buffer_size) | ||
142 | dev->adev.hwptr_done_capture -= | ||
143 | runtime->buffer_size; | ||
144 | |||
145 | dev->adev.capture_transfer_done += length; | ||
146 | if (dev->adev.capture_transfer_done >= | ||
147 | runtime->period_size) { | ||
148 | dev->adev.capture_transfer_done -= | ||
149 | runtime->period_size; | ||
150 | period_elapsed = 1; | ||
151 | } | ||
152 | |||
153 | snd_pcm_stream_unlock(substream); | ||
154 | } | ||
155 | if (period_elapsed) | ||
156 | snd_pcm_period_elapsed(substream); | ||
157 | } | ||
158 | urb->status = 0; | ||
159 | |||
160 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
161 | if (status < 0) { | ||
162 | em28xx_errdev("resubmit of audio urb failed (error=%i)\n", | ||
163 | status); | ||
164 | } | ||
165 | return; | ||
166 | } | ||
167 | |||
168 | static int em28xx_init_audio_isoc(struct em28xx *dev) | ||
169 | { | ||
170 | int i, errCode; | ||
171 | const int sb_size = EM28XX_NUM_AUDIO_PACKETS * | ||
172 | EM28XX_AUDIO_MAX_PACKET_SIZE; | ||
173 | |||
174 | dprintk("Starting isoc transfers\n"); | ||
175 | |||
176 | for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { | ||
177 | struct urb *urb; | ||
178 | int j, k; | ||
179 | |||
180 | dev->adev.transfer_buffer[i] = kmalloc(sb_size, GFP_ATOMIC); | ||
181 | if (!dev->adev.transfer_buffer[i]) | ||
182 | return -ENOMEM; | ||
183 | |||
184 | memset(dev->adev.transfer_buffer[i], 0x80, sb_size); | ||
185 | urb = usb_alloc_urb(EM28XX_NUM_AUDIO_PACKETS, GFP_ATOMIC); | ||
186 | if (!urb) { | ||
187 | em28xx_errdev("usb_alloc_urb failed!\n"); | ||
188 | for (j = 0; j < i; j++) { | ||
189 | usb_free_urb(dev->adev.urb[j]); | ||
190 | kfree(dev->adev.transfer_buffer[j]); | ||
191 | } | ||
192 | return -ENOMEM; | ||
193 | } | ||
194 | |||
195 | urb->dev = dev->udev; | ||
196 | urb->context = dev; | ||
197 | urb->pipe = usb_rcvisocpipe(dev->udev, EM28XX_EP_AUDIO); | ||
198 | urb->transfer_flags = URB_ISO_ASAP; | ||
199 | urb->transfer_buffer = dev->adev.transfer_buffer[i]; | ||
200 | urb->interval = 1; | ||
201 | urb->complete = em28xx_audio_isocirq; | ||
202 | urb->number_of_packets = EM28XX_NUM_AUDIO_PACKETS; | ||
203 | urb->transfer_buffer_length = sb_size; | ||
204 | |||
205 | for (j = k = 0; j < EM28XX_NUM_AUDIO_PACKETS; | ||
206 | j++, k += EM28XX_AUDIO_MAX_PACKET_SIZE) { | ||
207 | urb->iso_frame_desc[j].offset = k; | ||
208 | urb->iso_frame_desc[j].length = | ||
209 | EM28XX_AUDIO_MAX_PACKET_SIZE; | ||
210 | } | ||
211 | dev->adev.urb[i] = urb; | ||
212 | } | ||
213 | |||
214 | for (i = 0; i < EM28XX_AUDIO_BUFS; i++) { | ||
215 | errCode = usb_submit_urb(dev->adev.urb[i], GFP_ATOMIC); | ||
216 | if (errCode) { | ||
217 | em28xx_errdev("submit of audio urb failed\n"); | ||
218 | em28xx_deinit_isoc_audio(dev); | ||
219 | atomic_set(&dev->stream_started, 0); | ||
220 | return errCode; | ||
221 | } | ||
222 | |||
223 | } | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, | ||
229 | size_t size) | ||
230 | { | ||
231 | struct snd_pcm_runtime *runtime = subs->runtime; | ||
232 | |||
233 | dprintk("Allocating vbuffer\n"); | ||
234 | if (runtime->dma_area) { | ||
235 | if (runtime->dma_bytes > size) | ||
236 | return 0; | ||
237 | |||
238 | vfree(runtime->dma_area); | ||
239 | } | ||
240 | runtime->dma_area = vmalloc(size); | ||
241 | if (!runtime->dma_area) | ||
242 | return -ENOMEM; | ||
243 | |||
244 | runtime->dma_bytes = size; | ||
245 | |||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static struct snd_pcm_hardware snd_em28xx_hw_capture = { | ||
250 | .info = SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
251 | SNDRV_PCM_INFO_MMAP | | ||
252 | SNDRV_PCM_INFO_INTERLEAVED | | ||
253 | SNDRV_PCM_INFO_BATCH | | ||
254 | SNDRV_PCM_INFO_MMAP_VALID, | ||
255 | |||
256 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | ||
257 | |||
258 | .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_KNOT, | ||
259 | |||
260 | .rate_min = 48000, | ||
261 | .rate_max = 48000, | ||
262 | .channels_min = 2, | ||
263 | .channels_max = 2, | ||
264 | .buffer_bytes_max = 62720 * 8, /* just about the value in usbaudio.c */ | ||
265 | .period_bytes_min = 64, /* 12544/2, */ | ||
266 | .period_bytes_max = 12544, | ||
267 | .periods_min = 2, | ||
268 | .periods_max = 98, /* 12544, */ | ||
269 | }; | ||
270 | |||
271 | static int snd_em28xx_capture_open(struct snd_pcm_substream *substream) | ||
272 | { | ||
273 | struct em28xx *dev = snd_pcm_substream_chip(substream); | ||
274 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
275 | int ret = 0; | ||
276 | |||
277 | dprintk("opening device and trying to acquire exclusive lock\n"); | ||
278 | |||
279 | if (!dev) { | ||
280 | em28xx_err("BUG: em28xx can't find device struct." | ||
281 | " Can't proceed with open\n"); | ||
282 | return -ENODEV; | ||
283 | } | ||
284 | |||
285 | runtime->hw = snd_em28xx_hw_capture; | ||
286 | if ((dev->alt == 0 || dev->audio_ifnum) && dev->adev.users == 0) { | ||
287 | if (dev->audio_ifnum) | ||
288 | dev->alt = 1; | ||
289 | else | ||
290 | dev->alt = 7; | ||
291 | |||
292 | dprintk("changing alternate number on interface %d to %d\n", | ||
293 | dev->audio_ifnum, dev->alt); | ||
294 | usb_set_interface(dev->udev, dev->audio_ifnum, dev->alt); | ||
295 | |||
296 | /* Sets volume, mute, etc */ | ||
297 | dev->mute = 0; | ||
298 | mutex_lock(&dev->lock); | ||
299 | ret = em28xx_audio_analog_set(dev); | ||
300 | if (ret < 0) | ||
301 | goto err; | ||
302 | |||
303 | dev->adev.users++; | ||
304 | mutex_unlock(&dev->lock); | ||
305 | } | ||
306 | |||
307 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | ||
308 | dev->adev.capture_pcm_substream = substream; | ||
309 | |||
310 | return 0; | ||
311 | err: | ||
312 | mutex_unlock(&dev->lock); | ||
313 | |||
314 | em28xx_err("Error while configuring em28xx mixer\n"); | ||
315 | return ret; | ||
316 | } | ||
317 | |||
318 | static int snd_em28xx_pcm_close(struct snd_pcm_substream *substream) | ||
319 | { | ||
320 | struct em28xx *dev = snd_pcm_substream_chip(substream); | ||
321 | |||
322 | dprintk("closing device\n"); | ||
323 | |||
324 | dev->mute = 1; | ||
325 | mutex_lock(&dev->lock); | ||
326 | dev->adev.users--; | ||
327 | if (atomic_read(&dev->stream_started) > 0) { | ||
328 | atomic_set(&dev->stream_started, 0); | ||
329 | schedule_work(&dev->wq_trigger); | ||
330 | } | ||
331 | |||
332 | em28xx_audio_analog_set(dev); | ||
333 | if (substream->runtime->dma_area) { | ||
334 | dprintk("freeing\n"); | ||
335 | vfree(substream->runtime->dma_area); | ||
336 | substream->runtime->dma_area = NULL; | ||
337 | } | ||
338 | mutex_unlock(&dev->lock); | ||
339 | |||
340 | return 0; | ||
341 | } | ||
342 | |||
343 | static int snd_em28xx_hw_capture_params(struct snd_pcm_substream *substream, | ||
344 | struct snd_pcm_hw_params *hw_params) | ||
345 | { | ||
346 | int ret; | ||
347 | |||
348 | dprintk("Setting capture parameters\n"); | ||
349 | |||
350 | ret = snd_pcm_alloc_vmalloc_buffer(substream, | ||
351 | params_buffer_bytes(hw_params)); | ||
352 | if (ret < 0) | ||
353 | return ret; | ||
354 | #if 0 | ||
355 | /* TODO: set up em28xx audio chip to deliver the correct audio format, | ||
356 | current default is 48000hz multiplexed => 96000hz mono | ||
357 | which shouldn't matter since analogue TV only supports mono */ | ||
358 | unsigned int channels, rate, format; | ||
359 | |||
360 | format = params_format(hw_params); | ||
361 | rate = params_rate(hw_params); | ||
362 | channels = params_channels(hw_params); | ||
363 | #endif | ||
364 | |||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static int snd_em28xx_hw_capture_free(struct snd_pcm_substream *substream) | ||
369 | { | ||
370 | struct em28xx *dev = snd_pcm_substream_chip(substream); | ||
371 | |||
372 | dprintk("Stop capture, if needed\n"); | ||
373 | |||
374 | if (atomic_read(&dev->stream_started) > 0) { | ||
375 | atomic_set(&dev->stream_started, 0); | ||
376 | schedule_work(&dev->wq_trigger); | ||
377 | } | ||
378 | |||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | static int snd_em28xx_prepare(struct snd_pcm_substream *substream) | ||
383 | { | ||
384 | struct em28xx *dev = snd_pcm_substream_chip(substream); | ||
385 | |||
386 | dev->adev.hwptr_done_capture = 0; | ||
387 | dev->adev.capture_transfer_done = 0; | ||
388 | |||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static void audio_trigger(struct work_struct *work) | ||
393 | { | ||
394 | struct em28xx *dev = container_of(work, struct em28xx, wq_trigger); | ||
395 | |||
396 | if (atomic_read(&dev->stream_started)) { | ||
397 | dprintk("starting capture"); | ||
398 | em28xx_init_audio_isoc(dev); | ||
399 | } else { | ||
400 | dprintk("stopping capture"); | ||
401 | em28xx_deinit_isoc_audio(dev); | ||
402 | } | ||
403 | } | ||
404 | |||
405 | static int snd_em28xx_capture_trigger(struct snd_pcm_substream *substream, | ||
406 | int cmd) | ||
407 | { | ||
408 | struct em28xx *dev = snd_pcm_substream_chip(substream); | ||
409 | int retval = 0; | ||
410 | |||
411 | switch (cmd) { | ||
412 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: /* fall through */ | ||
413 | case SNDRV_PCM_TRIGGER_RESUME: /* fall through */ | ||
414 | case SNDRV_PCM_TRIGGER_START: | ||
415 | atomic_set(&dev->stream_started, 1); | ||
416 | break; | ||
417 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: /* fall through */ | ||
418 | case SNDRV_PCM_TRIGGER_SUSPEND: /* fall through */ | ||
419 | case SNDRV_PCM_TRIGGER_STOP: | ||
420 | atomic_set(&dev->stream_started, 0); | ||
421 | break; | ||
422 | default: | ||
423 | retval = -EINVAL; | ||
424 | } | ||
425 | schedule_work(&dev->wq_trigger); | ||
426 | return retval; | ||
427 | } | ||
428 | |||
429 | static snd_pcm_uframes_t snd_em28xx_capture_pointer(struct snd_pcm_substream | ||
430 | *substream) | ||
431 | { | ||
432 | unsigned long flags; | ||
433 | struct em28xx *dev; | ||
434 | snd_pcm_uframes_t hwptr_done; | ||
435 | |||
436 | dev = snd_pcm_substream_chip(substream); | ||
437 | spin_lock_irqsave(&dev->adev.slock, flags); | ||
438 | hwptr_done = dev->adev.hwptr_done_capture; | ||
439 | spin_unlock_irqrestore(&dev->adev.slock, flags); | ||
440 | |||
441 | return hwptr_done; | ||
442 | } | ||
443 | |||
444 | static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs, | ||
445 | unsigned long offset) | ||
446 | { | ||
447 | void *pageptr = subs->runtime->dma_area + offset; | ||
448 | |||
449 | return vmalloc_to_page(pageptr); | ||
450 | } | ||
451 | |||
452 | /* | ||
453 | * AC97 volume control support | ||
454 | */ | ||
455 | static int em28xx_vol_info(struct snd_kcontrol *kcontrol, | ||
456 | struct snd_ctl_elem_info *info) | ||
457 | { | ||
458 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
459 | info->count = 2; | ||
460 | info->value.integer.min = 0; | ||
461 | info->value.integer.max = 0x1f; | ||
462 | |||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | static int em28xx_vol_put(struct snd_kcontrol *kcontrol, | ||
467 | struct snd_ctl_elem_value *value) | ||
468 | { | ||
469 | struct em28xx *dev = snd_kcontrol_chip(kcontrol); | ||
470 | u16 val = (0x1f - (value->value.integer.value[0] & 0x1f)) | | ||
471 | (0x1f - (value->value.integer.value[1] & 0x1f)) << 8; | ||
472 | int rc; | ||
473 | |||
474 | mutex_lock(&dev->lock); | ||
475 | rc = em28xx_read_ac97(dev, kcontrol->private_value); | ||
476 | if (rc < 0) | ||
477 | goto err; | ||
478 | |||
479 | val |= rc & 0x8000; /* Preserve the mute flag */ | ||
480 | |||
481 | rc = em28xx_write_ac97(dev, kcontrol->private_value, val); | ||
482 | if (rc < 0) | ||
483 | goto err; | ||
484 | |||
485 | dprintk("%sleft vol %d, right vol %d (0x%04x) to ac97 volume control 0x%04x\n", | ||
486 | (val & 0x8000) ? "muted " : "", | ||
487 | 0x1f - ((val >> 8) & 0x1f), 0x1f - (val & 0x1f), | ||
488 | val, (int)kcontrol->private_value); | ||
489 | |||
490 | err: | ||
491 | mutex_unlock(&dev->lock); | ||
492 | return rc; | ||
493 | } | ||
494 | |||
495 | static int em28xx_vol_get(struct snd_kcontrol *kcontrol, | ||
496 | struct snd_ctl_elem_value *value) | ||
497 | { | ||
498 | struct em28xx *dev = snd_kcontrol_chip(kcontrol); | ||
499 | int val; | ||
500 | |||
501 | mutex_lock(&dev->lock); | ||
502 | val = em28xx_read_ac97(dev, kcontrol->private_value); | ||
503 | mutex_unlock(&dev->lock); | ||
504 | if (val < 0) | ||
505 | return val; | ||
506 | |||
507 | dprintk("%sleft vol %d, right vol %d (0x%04x) from ac97 volume control 0x%04x\n", | ||
508 | (val & 0x8000) ? "muted " : "", | ||
509 | 0x1f - ((val >> 8) & 0x1f), 0x1f - (val & 0x1f), | ||
510 | val, (int)kcontrol->private_value); | ||
511 | |||
512 | value->value.integer.value[0] = 0x1f - (val & 0x1f); | ||
513 | value->value.integer.value[1] = 0x1f - ((val << 8) & 0x1f); | ||
514 | |||
515 | return 0; | ||
516 | } | ||
517 | |||
518 | static int em28xx_vol_put_mute(struct snd_kcontrol *kcontrol, | ||
519 | struct snd_ctl_elem_value *value) | ||
520 | { | ||
521 | struct em28xx *dev = snd_kcontrol_chip(kcontrol); | ||
522 | u16 val = value->value.integer.value[0]; | ||
523 | int rc; | ||
524 | |||
525 | mutex_lock(&dev->lock); | ||
526 | rc = em28xx_read_ac97(dev, kcontrol->private_value); | ||
527 | if (rc < 0) | ||
528 | goto err; | ||
529 | |||
530 | if (val) | ||
531 | rc &= 0x1f1f; | ||
532 | else | ||
533 | rc |= 0x8000; | ||
534 | |||
535 | rc = em28xx_write_ac97(dev, kcontrol->private_value, rc); | ||
536 | if (rc < 0) | ||
537 | goto err; | ||
538 | |||
539 | dprintk("%sleft vol %d, right vol %d (0x%04x) to ac97 volume control 0x%04x\n", | ||
540 | (val & 0x8000) ? "muted " : "", | ||
541 | 0x1f - ((val >> 8) & 0x1f), 0x1f - (val & 0x1f), | ||
542 | val, (int)kcontrol->private_value); | ||
543 | |||
544 | err: | ||
545 | mutex_unlock(&dev->lock); | ||
546 | return rc; | ||
547 | } | ||
548 | |||
549 | static int em28xx_vol_get_mute(struct snd_kcontrol *kcontrol, | ||
550 | struct snd_ctl_elem_value *value) | ||
551 | { | ||
552 | struct em28xx *dev = snd_kcontrol_chip(kcontrol); | ||
553 | int val; | ||
554 | |||
555 | mutex_lock(&dev->lock); | ||
556 | val = em28xx_read_ac97(dev, kcontrol->private_value); | ||
557 | mutex_unlock(&dev->lock); | ||
558 | if (val < 0) | ||
559 | return val; | ||
560 | |||
561 | if (val & 0x8000) | ||
562 | value->value.integer.value[0] = 0; | ||
563 | else | ||
564 | value->value.integer.value[0] = 1; | ||
565 | |||
566 | dprintk("%sleft vol %d, right vol %d (0x%04x) from ac97 volume control 0x%04x\n", | ||
567 | (val & 0x8000) ? "muted " : "", | ||
568 | 0x1f - ((val >> 8) & 0x1f), 0x1f - (val & 0x1f), | ||
569 | val, (int)kcontrol->private_value); | ||
570 | |||
571 | return 0; | ||
572 | } | ||
573 | |||
574 | static const DECLARE_TLV_DB_SCALE(em28xx_db_scale, -3450, 150, 0); | ||
575 | |||
576 | static int em28xx_cvol_new(struct snd_card *card, struct em28xx *dev, | ||
577 | char *name, int id) | ||
578 | { | ||
579 | int err; | ||
580 | char ctl_name[44]; | ||
581 | struct snd_kcontrol *kctl; | ||
582 | struct snd_kcontrol_new tmp; | ||
583 | |||
584 | memset (&tmp, 0, sizeof(tmp)); | ||
585 | tmp.iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
586 | tmp.private_value = id, | ||
587 | tmp.name = ctl_name, | ||
588 | |||
589 | /* Add Mute Control */ | ||
590 | sprintf(ctl_name, "%s Switch", name); | ||
591 | tmp.get = em28xx_vol_get_mute; | ||
592 | tmp.put = em28xx_vol_put_mute; | ||
593 | tmp.info = snd_ctl_boolean_mono_info; | ||
594 | kctl = snd_ctl_new1(&tmp, dev); | ||
595 | err = snd_ctl_add(card, kctl); | ||
596 | if (err < 0) | ||
597 | return err; | ||
598 | dprintk("Added control %s for ac97 volume control 0x%04x\n", | ||
599 | ctl_name, id); | ||
600 | |||
601 | memset (&tmp, 0, sizeof(tmp)); | ||
602 | tmp.iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
603 | tmp.private_value = id, | ||
604 | tmp.name = ctl_name, | ||
605 | |||
606 | /* Add Volume Control */ | ||
607 | sprintf(ctl_name, "%s Volume", name); | ||
608 | tmp.get = em28xx_vol_get; | ||
609 | tmp.put = em28xx_vol_put; | ||
610 | tmp.info = em28xx_vol_info; | ||
611 | tmp.tlv.p = em28xx_db_scale, | ||
612 | kctl = snd_ctl_new1(&tmp, dev); | ||
613 | err = snd_ctl_add(card, kctl); | ||
614 | if (err < 0) | ||
615 | return err; | ||
616 | dprintk("Added control %s for ac97 volume control 0x%04x\n", | ||
617 | ctl_name, id); | ||
618 | |||
619 | return 0; | ||
620 | } | ||
621 | |||
622 | /* | ||
623 | * register/unregister code and data | ||
624 | */ | ||
625 | static struct snd_pcm_ops snd_em28xx_pcm_capture = { | ||
626 | .open = snd_em28xx_capture_open, | ||
627 | .close = snd_em28xx_pcm_close, | ||
628 | .ioctl = snd_pcm_lib_ioctl, | ||
629 | .hw_params = snd_em28xx_hw_capture_params, | ||
630 | .hw_free = snd_em28xx_hw_capture_free, | ||
631 | .prepare = snd_em28xx_prepare, | ||
632 | .trigger = snd_em28xx_capture_trigger, | ||
633 | .pointer = snd_em28xx_capture_pointer, | ||
634 | .page = snd_pcm_get_vmalloc_page, | ||
635 | }; | ||
636 | |||
637 | static int em28xx_audio_init(struct em28xx *dev) | ||
638 | { | ||
639 | struct em28xx_audio *adev = &dev->adev; | ||
640 | struct snd_pcm *pcm; | ||
641 | struct snd_card *card; | ||
642 | static int devnr; | ||
643 | int err; | ||
644 | |||
645 | if (!dev->has_alsa_audio || dev->audio_ifnum < 0) { | ||
646 | /* This device does not support the extension (in this case | ||
647 | the device is expecting the snd-usb-audio module or | ||
648 | doesn't have analog audio support at all) */ | ||
649 | return 0; | ||
650 | } | ||
651 | |||
652 | printk(KERN_INFO "em28xx-audio.c: probing for em28xx Audio Vendor Class\n"); | ||
653 | printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2006 Markus " | ||
654 | "Rechberger\n"); | ||
655 | printk(KERN_INFO "em28xx-audio.c: Copyright (C) 2007-2011 Mauro Carvalho Chehab\n"); | ||
656 | |||
657 | err = snd_card_create(index[devnr], "Em28xx Audio", THIS_MODULE, 0, | ||
658 | &card); | ||
659 | if (err < 0) | ||
660 | return err; | ||
661 | |||
662 | spin_lock_init(&adev->slock); | ||
663 | err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); | ||
664 | if (err < 0) { | ||
665 | snd_card_free(card); | ||
666 | return err; | ||
667 | } | ||
668 | |||
669 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture); | ||
670 | pcm->info_flags = 0; | ||
671 | pcm->private_data = dev; | ||
672 | strcpy(pcm->name, "Empia 28xx Capture"); | ||
673 | |||
674 | snd_card_set_dev(card, &dev->udev->dev); | ||
675 | strcpy(card->driver, "Em28xx-Audio"); | ||
676 | strcpy(card->shortname, "Em28xx Audio"); | ||
677 | strcpy(card->longname, "Empia Em28xx Audio"); | ||
678 | |||
679 | INIT_WORK(&dev->wq_trigger, audio_trigger); | ||
680 | |||
681 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { | ||
682 | em28xx_cvol_new(card, dev, "Video", AC97_VIDEO); | ||
683 | em28xx_cvol_new(card, dev, "Line In", AC97_LINE); | ||
684 | em28xx_cvol_new(card, dev, "Phone", AC97_PHONE); | ||
685 | em28xx_cvol_new(card, dev, "Microphone", AC97_MIC); | ||
686 | em28xx_cvol_new(card, dev, "CD", AC97_CD); | ||
687 | em28xx_cvol_new(card, dev, "AUX", AC97_AUX); | ||
688 | em28xx_cvol_new(card, dev, "PCM", AC97_PCM); | ||
689 | |||
690 | em28xx_cvol_new(card, dev, "Master", AC97_MASTER); | ||
691 | em28xx_cvol_new(card, dev, "Line", AC97_HEADPHONE); | ||
692 | em28xx_cvol_new(card, dev, "Mono", AC97_MASTER_MONO); | ||
693 | em28xx_cvol_new(card, dev, "LFE", AC97_CENTER_LFE_MASTER); | ||
694 | em28xx_cvol_new(card, dev, "Surround", AC97_SURROUND_MASTER); | ||
695 | } | ||
696 | |||
697 | err = snd_card_register(card); | ||
698 | if (err < 0) { | ||
699 | snd_card_free(card); | ||
700 | return err; | ||
701 | } | ||
702 | adev->sndcard = card; | ||
703 | adev->udev = dev->udev; | ||
704 | |||
705 | return 0; | ||
706 | } | ||
707 | |||
708 | static int em28xx_audio_fini(struct em28xx *dev) | ||
709 | { | ||
710 | if (dev == NULL) | ||
711 | return 0; | ||
712 | |||
713 | if (dev->has_alsa_audio != 1) { | ||
714 | /* This device does not support the extension (in this case | ||
715 | the device is expecting the snd-usb-audio module or | ||
716 | doesn't have analog audio support at all) */ | ||
717 | return 0; | ||
718 | } | ||
719 | |||
720 | if (dev->adev.sndcard) { | ||
721 | snd_card_free(dev->adev.sndcard); | ||
722 | dev->adev.sndcard = NULL; | ||
723 | } | ||
724 | |||
725 | return 0; | ||
726 | } | ||
727 | |||
728 | static struct em28xx_ops audio_ops = { | ||
729 | .id = EM28XX_AUDIO, | ||
730 | .name = "Em28xx Audio Extension", | ||
731 | .init = em28xx_audio_init, | ||
732 | .fini = em28xx_audio_fini, | ||
733 | }; | ||
734 | |||
735 | static int __init em28xx_alsa_register(void) | ||
736 | { | ||
737 | return em28xx_register_extension(&audio_ops); | ||
738 | } | ||
739 | |||
740 | static void __exit em28xx_alsa_unregister(void) | ||
741 | { | ||
742 | em28xx_unregister_extension(&audio_ops); | ||
743 | } | ||
744 | |||
745 | MODULE_LICENSE("GPL"); | ||
746 | MODULE_AUTHOR("Markus Rechberger <mrechberger@gmail.com>"); | ||
747 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); | ||
748 | MODULE_DESCRIPTION("Em28xx Audio driver"); | ||
749 | |||
750 | module_init(em28xx_alsa_register); | ||
751 | module_exit(em28xx_alsa_unregister); | ||
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c deleted file mode 100644 index ca62b9981380..000000000000 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ /dev/null | |||
@@ -1,3417 +0,0 @@ | |||
1 | /* | ||
2 | em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB | ||
3 | video capture devices | ||
4 | |||
5 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | ||
6 | Markus Rechberger <mrechberger@gmail.com> | ||
7 | Mauro Carvalho Chehab <mchehab@infradead.org> | ||
8 | Sascha Sommer <saschasommer@freenet.de> | ||
9 | |||
10 | This program is free software; you can redistribute it and/or modify | ||
11 | it under the terms of the GNU General Public License as published by | ||
12 | the Free Software Foundation; either version 2 of the License, or | ||
13 | (at your option) any later version. | ||
14 | |||
15 | This program is distributed in the hope that it will be useful, | ||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | GNU General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU General Public License | ||
21 | along with this program; if not, write to the Free Software | ||
22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | #include <linux/init.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/delay.h> | ||
29 | #include <linux/i2c.h> | ||
30 | #include <linux/usb.h> | ||
31 | #include <media/tuner.h> | ||
32 | #include <media/msp3400.h> | ||
33 | #include <media/saa7115.h> | ||
34 | #include <media/tvp5150.h> | ||
35 | #include <media/tvaudio.h> | ||
36 | #include <media/mt9v011.h> | ||
37 | #include <media/i2c-addr.h> | ||
38 | #include <media/tveeprom.h> | ||
39 | #include <media/v4l2-common.h> | ||
40 | #include <media/v4l2-chip-ident.h> | ||
41 | |||
42 | #include "em28xx.h" | ||
43 | |||
44 | #define DRIVER_NAME "em28xx" | ||
45 | |||
46 | static int tuner = -1; | ||
47 | module_param(tuner, int, 0444); | ||
48 | MODULE_PARM_DESC(tuner, "tuner type"); | ||
49 | |||
50 | static unsigned int disable_ir; | ||
51 | module_param(disable_ir, int, 0444); | ||
52 | MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); | ||
53 | |||
54 | static unsigned int disable_usb_speed_check; | ||
55 | module_param(disable_usb_speed_check, int, 0444); | ||
56 | MODULE_PARM_DESC(disable_usb_speed_check, | ||
57 | "override min bandwidth requirement of 480M bps"); | ||
58 | |||
59 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | ||
60 | module_param_array(card, int, NULL, 0444); | ||
61 | MODULE_PARM_DESC(card, "card type"); | ||
62 | |||
63 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS - 1 */ | ||
64 | static unsigned long em28xx_devused; | ||
65 | |||
66 | struct em28xx_hash_table { | ||
67 | unsigned long hash; | ||
68 | unsigned int model; | ||
69 | unsigned int tuner; | ||
70 | }; | ||
71 | |||
72 | static void em28xx_pre_card_setup(struct em28xx *dev); | ||
73 | |||
74 | /* | ||
75 | * Reset sequences for analog/digital modes | ||
76 | */ | ||
77 | |||
78 | /* Reset for the most [analog] boards */ | ||
79 | static struct em28xx_reg_seq default_analog[] = { | ||
80 | {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, | ||
81 | { -1, -1, -1, -1}, | ||
82 | }; | ||
83 | |||
84 | /* Reset for the most [digital] boards */ | ||
85 | static struct em28xx_reg_seq default_digital[] = { | ||
86 | {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, | ||
87 | { -1, -1, -1, -1}, | ||
88 | }; | ||
89 | |||
90 | /* Board Hauppauge WinTV HVR 900 analog */ | ||
91 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { | ||
92 | {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10}, | ||
93 | {0x05, 0xff, 0x10, 10}, | ||
94 | { -1, -1, -1, -1}, | ||
95 | }; | ||
96 | |||
97 | /* Board Hauppauge WinTV HVR 900 digital */ | ||
98 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { | ||
99 | {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10}, | ||
100 | {EM2880_R04_GPO, 0x04, 0x0f, 10}, | ||
101 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, | ||
102 | { -1, -1, -1, -1}, | ||
103 | }; | ||
104 | |||
105 | /* Board Hauppauge WinTV HVR 900 (R2) digital */ | ||
106 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900R2_digital[] = { | ||
107 | {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10}, | ||
108 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, | ||
109 | { -1, -1, -1, -1}, | ||
110 | }; | ||
111 | |||
112 | /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ | ||
113 | static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { | ||
114 | {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10}, | ||
115 | { -1, -1, -1, -1}, | ||
116 | }; | ||
117 | |||
118 | /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ | ||
119 | |||
120 | /* Board - EM2870 Kworld 355u | ||
121 | Analog - No input analog */ | ||
122 | |||
123 | /* Board - EM2882 Kworld 315U digital */ | ||
124 | static struct em28xx_reg_seq em2882_kworld_315u_digital[] = { | ||
125 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
126 | {EM28XX_R08_GPIO, 0xfe, 0xff, 10}, | ||
127 | {EM2880_R04_GPO, 0x04, 0xff, 10}, | ||
128 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | ||
129 | {EM28XX_R08_GPIO, 0x7e, 0xff, 10}, | ||
130 | { -1, -1, -1, -1}, | ||
131 | }; | ||
132 | |||
133 | static struct em28xx_reg_seq em2882_kworld_315u_tuner_gpio[] = { | ||
134 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | ||
135 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | ||
136 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | ||
137 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | ||
138 | { -1, -1, -1, -1}, | ||
139 | }; | ||
140 | |||
141 | static struct em28xx_reg_seq kworld_330u_analog[] = { | ||
142 | {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, | ||
143 | {EM2880_R04_GPO, 0x00, 0xff, 10}, | ||
144 | { -1, -1, -1, -1}, | ||
145 | }; | ||
146 | |||
147 | static struct em28xx_reg_seq kworld_330u_digital[] = { | ||
148 | {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, | ||
149 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | ||
150 | { -1, -1, -1, -1}, | ||
151 | }; | ||
152 | |||
153 | /* Evga inDtube | ||
154 | GPIO0 - Enable digital power (s5h1409) - low to enable | ||
155 | GPIO1 - Enable analog power (tvp5150/emp202) - low to enable | ||
156 | GPIO4 - xc3028 reset | ||
157 | GOP3 - s5h1409 reset | ||
158 | */ | ||
159 | static struct em28xx_reg_seq evga_indtube_analog[] = { | ||
160 | {EM28XX_R08_GPIO, 0x79, 0xff, 60}, | ||
161 | { -1, -1, -1, -1}, | ||
162 | }; | ||
163 | |||
164 | static struct em28xx_reg_seq evga_indtube_digital[] = { | ||
165 | {EM28XX_R08_GPIO, 0x7a, 0xff, 1}, | ||
166 | {EM2880_R04_GPO, 0x04, 0xff, 10}, | ||
167 | {EM2880_R04_GPO, 0x0c, 0xff, 1}, | ||
168 | { -1, -1, -1, -1}, | ||
169 | }; | ||
170 | |||
171 | /* | ||
172 | * KWorld PlusTV 340U and UB435-Q (ATSC) GPIOs map: | ||
173 | * EM_GPIO_0 - currently unknown | ||
174 | * EM_GPIO_1 - LED disable/enable (1 = off, 0 = on) | ||
175 | * EM_GPIO_2 - currently unknown | ||
176 | * EM_GPIO_3 - currently unknown | ||
177 | * EM_GPIO_4 - TDA18271HD/C1 tuner (1 = active, 0 = in reset) | ||
178 | * EM_GPIO_5 - LGDT3304 ATSC/QAM demod (1 = active, 0 = in reset) | ||
179 | * EM_GPIO_6 - currently unknown | ||
180 | * EM_GPIO_7 - currently unknown | ||
181 | */ | ||
182 | static struct em28xx_reg_seq kworld_a340_digital[] = { | ||
183 | {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, | ||
184 | { -1, -1, -1, -1}, | ||
185 | }; | ||
186 | |||
187 | /* Pinnacle Hybrid Pro eb1a:2881 */ | ||
188 | static struct em28xx_reg_seq pinnacle_hybrid_pro_analog[] = { | ||
189 | {EM28XX_R08_GPIO, 0xfd, ~EM_GPIO_4, 10}, | ||
190 | { -1, -1, -1, -1}, | ||
191 | }; | ||
192 | |||
193 | static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = { | ||
194 | {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, | ||
195 | {EM2880_R04_GPO, 0x04, 0xff, 100},/* zl10353 reset */ | ||
196 | {EM2880_R04_GPO, 0x0c, 0xff, 1}, | ||
197 | { -1, -1, -1, -1}, | ||
198 | }; | ||
199 | |||
200 | static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_analog[] = { | ||
201 | {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, | ||
202 | {EM2880_R04_GPO, 0x00, 0xff, 10}, | ||
203 | { -1, -1, -1, -1}, | ||
204 | }; | ||
205 | |||
206 | static struct em28xx_reg_seq terratec_cinergy_USB_XS_FR_digital[] = { | ||
207 | {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, | ||
208 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | ||
209 | { -1, -1, -1, -1}, | ||
210 | }; | ||
211 | |||
212 | /* eb1a:2868 Reddo DVB-C USB TV Box | ||
213 | GPIO4 - CU1216L NIM | ||
214 | Other GPIOs seems to be don't care. */ | ||
215 | static struct em28xx_reg_seq reddo_dvb_c_usb_box[] = { | ||
216 | {EM28XX_R08_GPIO, 0xfe, 0xff, 10}, | ||
217 | {EM28XX_R08_GPIO, 0xde, 0xff, 10}, | ||
218 | {EM28XX_R08_GPIO, 0xfe, 0xff, 10}, | ||
219 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
220 | {EM28XX_R08_GPIO, 0x7f, 0xff, 10}, | ||
221 | {EM28XX_R08_GPIO, 0x6f, 0xff, 10}, | ||
222 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
223 | {-1, -1, -1, -1}, | ||
224 | }; | ||
225 | |||
226 | /* Callback for the most boards */ | ||
227 | static struct em28xx_reg_seq default_tuner_gpio[] = { | ||
228 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, | ||
229 | {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10}, | ||
230 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, | ||
231 | { -1, -1, -1, -1}, | ||
232 | }; | ||
233 | |||
234 | /* Mute/unmute */ | ||
235 | static struct em28xx_reg_seq compro_unmute_tv_gpio[] = { | ||
236 | {EM28XX_R08_GPIO, 5, 7, 10}, | ||
237 | { -1, -1, -1, -1}, | ||
238 | }; | ||
239 | |||
240 | static struct em28xx_reg_seq compro_unmute_svid_gpio[] = { | ||
241 | {EM28XX_R08_GPIO, 4, 7, 10}, | ||
242 | { -1, -1, -1, -1}, | ||
243 | }; | ||
244 | |||
245 | static struct em28xx_reg_seq compro_mute_gpio[] = { | ||
246 | {EM28XX_R08_GPIO, 6, 7, 10}, | ||
247 | { -1, -1, -1, -1}, | ||
248 | }; | ||
249 | |||
250 | /* Terratec AV350 */ | ||
251 | static struct em28xx_reg_seq terratec_av350_mute_gpio[] = { | ||
252 | {EM28XX_R08_GPIO, 0xff, 0x7f, 10}, | ||
253 | { -1, -1, -1, -1}, | ||
254 | }; | ||
255 | |||
256 | static struct em28xx_reg_seq terratec_av350_unmute_gpio[] = { | ||
257 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
258 | { -1, -1, -1, -1}, | ||
259 | }; | ||
260 | |||
261 | static struct em28xx_reg_seq silvercrest_reg_seq[] = { | ||
262 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
263 | {EM28XX_R08_GPIO, 0x01, 0xf7, 10}, | ||
264 | { -1, -1, -1, -1}, | ||
265 | }; | ||
266 | |||
267 | static struct em28xx_reg_seq vc211a_enable[] = { | ||
268 | {EM28XX_R08_GPIO, 0xff, 0x07, 10}, | ||
269 | {EM28XX_R08_GPIO, 0xff, 0x0f, 10}, | ||
270 | {EM28XX_R08_GPIO, 0xff, 0x0b, 10}, | ||
271 | { -1, -1, -1, -1}, | ||
272 | }; | ||
273 | |||
274 | static struct em28xx_reg_seq dikom_dk300_digital[] = { | ||
275 | {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, | ||
276 | {EM2880_R04_GPO, 0x08, 0xff, 10}, | ||
277 | { -1, -1, -1, -1}, | ||
278 | }; | ||
279 | |||
280 | |||
281 | /* Reset for the most [digital] boards */ | ||
282 | static struct em28xx_reg_seq leadership_digital[] = { | ||
283 | {EM2874_R80_GPIO, 0x70, 0xff, 10}, | ||
284 | { -1, -1, -1, -1}, | ||
285 | }; | ||
286 | |||
287 | static struct em28xx_reg_seq leadership_reset[] = { | ||
288 | {EM2874_R80_GPIO, 0xf0, 0xff, 10}, | ||
289 | {EM2874_R80_GPIO, 0xb0, 0xff, 10}, | ||
290 | {EM2874_R80_GPIO, 0xf0, 0xff, 10}, | ||
291 | { -1, -1, -1, -1}, | ||
292 | }; | ||
293 | |||
294 | /* 2013:024f PCTV nanoStick T2 290e | ||
295 | * GPIO_6 - demod reset | ||
296 | * GPIO_7 - LED | ||
297 | */ | ||
298 | static struct em28xx_reg_seq pctv_290e[] = { | ||
299 | {EM2874_R80_GPIO, 0x00, 0xff, 80}, | ||
300 | {EM2874_R80_GPIO, 0x40, 0xff, 80}, /* GPIO_6 = 1 */ | ||
301 | {EM2874_R80_GPIO, 0xc0, 0xff, 80}, /* GPIO_7 = 1 */ | ||
302 | {-1, -1, -1, -1}, | ||
303 | }; | ||
304 | |||
305 | #if 0 | ||
306 | static struct em28xx_reg_seq terratec_h5_gpio[] = { | ||
307 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
308 | {EM2874_R80_GPIO, 0xf6, 0xff, 100}, | ||
309 | {EM2874_R80_GPIO, 0xf2, 0xff, 50}, | ||
310 | {EM2874_R80_GPIO, 0xf6, 0xff, 50}, | ||
311 | { -1, -1, -1, -1}, | ||
312 | }; | ||
313 | |||
314 | static struct em28xx_reg_seq terratec_h5_digital[] = { | ||
315 | {EM2874_R80_GPIO, 0xf6, 0xff, 10}, | ||
316 | {EM2874_R80_GPIO, 0xe6, 0xff, 100}, | ||
317 | {EM2874_R80_GPIO, 0xa6, 0xff, 10}, | ||
318 | { -1, -1, -1, -1}, | ||
319 | }; | ||
320 | #endif | ||
321 | |||
322 | /* 2013:024f PCTV DVB-S2 Stick 460e | ||
323 | * GPIO_0 - POWER_ON | ||
324 | * GPIO_1 - BOOST | ||
325 | * GPIO_2 - VUV_LNB (red LED) | ||
326 | * GPIO_3 - EXT_12V | ||
327 | * GPIO_4 - INT_DEM (DEMOD GPIO_0) | ||
328 | * GPIO_5 - INT_LNB | ||
329 | * GPIO_6 - RESET_DEM | ||
330 | * GPIO_7 - LED (green LED) | ||
331 | */ | ||
332 | static struct em28xx_reg_seq pctv_460e[] = { | ||
333 | {EM2874_R80_GPIO, 0x01, 0xff, 50}, | ||
334 | {0x0d, 0xff, 0xff, 50}, | ||
335 | {EM2874_R80_GPIO, 0x41, 0xff, 50}, /* GPIO_6=1 */ | ||
336 | {0x0d, 0x42, 0xff, 50}, | ||
337 | {EM2874_R80_GPIO, 0x61, 0xff, 50}, /* GPIO_5=1 */ | ||
338 | { -1, -1, -1, -1}, | ||
339 | }; | ||
340 | |||
341 | #if 0 | ||
342 | static struct em28xx_reg_seq hauppauge_930c_gpio[] = { | ||
343 | {EM2874_R80_GPIO, 0x6f, 0xff, 10}, | ||
344 | {EM2874_R80_GPIO, 0x4f, 0xff, 10}, /* xc5000 reset */ | ||
345 | {EM2874_R80_GPIO, 0x6f, 0xff, 10}, | ||
346 | {EM2874_R80_GPIO, 0x4f, 0xff, 10}, | ||
347 | { -1, -1, -1, -1}, | ||
348 | }; | ||
349 | |||
350 | static struct em28xx_reg_seq hauppauge_930c_digital[] = { | ||
351 | {EM2874_R80_GPIO, 0xf6, 0xff, 10}, | ||
352 | {EM2874_R80_GPIO, 0xe6, 0xff, 100}, | ||
353 | {EM2874_R80_GPIO, 0xa6, 0xff, 10}, | ||
354 | { -1, -1, -1, -1}, | ||
355 | }; | ||
356 | #endif | ||
357 | |||
358 | /* 1b80:e425 MaxMedia UB425-TC | ||
359 | * GPIO_6 - demod reset, 0=active | ||
360 | * GPIO_7 - LED, 0=active | ||
361 | */ | ||
362 | static struct em28xx_reg_seq maxmedia_ub425_tc[] = { | ||
363 | {EM2874_R80_GPIO, 0x83, 0xff, 100}, | ||
364 | {EM2874_R80_GPIO, 0xc3, 0xff, 100}, /* GPIO_6 = 1 */ | ||
365 | {EM2874_R80_GPIO, 0x43, 0xff, 000}, /* GPIO_7 = 0 */ | ||
366 | {-1, -1, -1, -1}, | ||
367 | }; | ||
368 | |||
369 | /* 2304:0242 PCTV QuatroStick (510e) | ||
370 | * GPIO_2: decoder reset, 0=active | ||
371 | * GPIO_4: decoder suspend, 0=active | ||
372 | * GPIO_6: demod reset, 0=active | ||
373 | * GPIO_7: LED, 1=active | ||
374 | */ | ||
375 | static struct em28xx_reg_seq pctv_510e[] = { | ||
376 | {EM2874_R80_GPIO, 0x10, 0xff, 100}, | ||
377 | {EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ | ||
378 | {EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ | ||
379 | { -1, -1, -1, -1}, | ||
380 | }; | ||
381 | |||
382 | /* 2013:0251 PCTV QuatroStick nano (520e) | ||
383 | * GPIO_2: decoder reset, 0=active | ||
384 | * GPIO_4: decoder suspend, 0=active | ||
385 | * GPIO_6: demod reset, 0=active | ||
386 | * GPIO_7: LED, 1=active | ||
387 | */ | ||
388 | static struct em28xx_reg_seq pctv_520e[] = { | ||
389 | {EM2874_R80_GPIO, 0x10, 0xff, 100}, | ||
390 | {EM2874_R80_GPIO, 0x14, 0xff, 100}, /* GPIO_2 = 1 */ | ||
391 | {EM2874_R80_GPIO, 0x54, 0xff, 050}, /* GPIO_6 = 1 */ | ||
392 | {EM2874_R80_GPIO, 0xd4, 0xff, 000}, /* GPIO_7 = 1 */ | ||
393 | { -1, -1, -1, -1}, | ||
394 | }; | ||
395 | |||
396 | /* | ||
397 | * Board definitions | ||
398 | */ | ||
399 | struct em28xx_board em28xx_boards[] = { | ||
400 | [EM2750_BOARD_UNKNOWN] = { | ||
401 | .name = "EM2710/EM2750/EM2751 webcam grabber", | ||
402 | .xclk = EM28XX_XCLK_FREQUENCY_20MHZ, | ||
403 | .tuner_type = TUNER_ABSENT, | ||
404 | .is_webcam = 1, | ||
405 | .input = { { | ||
406 | .type = EM28XX_VMUX_COMPOSITE1, | ||
407 | .vmux = 0, | ||
408 | .amux = EM28XX_AMUX_VIDEO, | ||
409 | .gpio = silvercrest_reg_seq, | ||
410 | } }, | ||
411 | }, | ||
412 | [EM2800_BOARD_UNKNOWN] = { | ||
413 | .name = "Unknown EM2800 video grabber", | ||
414 | .is_em2800 = 1, | ||
415 | .tda9887_conf = TDA9887_PRESENT, | ||
416 | .decoder = EM28XX_SAA711X, | ||
417 | .tuner_type = TUNER_ABSENT, | ||
418 | .input = { { | ||
419 | .type = EM28XX_VMUX_COMPOSITE1, | ||
420 | .vmux = SAA7115_COMPOSITE0, | ||
421 | .amux = EM28XX_AMUX_LINE_IN, | ||
422 | }, { | ||
423 | .type = EM28XX_VMUX_SVIDEO, | ||
424 | .vmux = SAA7115_SVIDEO3, | ||
425 | .amux = EM28XX_AMUX_LINE_IN, | ||
426 | } }, | ||
427 | }, | ||
428 | [EM2820_BOARD_UNKNOWN] = { | ||
429 | .name = "Unknown EM2750/28xx video grabber", | ||
430 | .tuner_type = TUNER_ABSENT, | ||
431 | .is_webcam = 1, /* To enable sensor probe */ | ||
432 | }, | ||
433 | [EM2750_BOARD_DLCW_130] = { | ||
434 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ | ||
435 | .name = "Huaqi DLCW-130", | ||
436 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
437 | .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, | ||
438 | .tuner_type = TUNER_ABSENT, | ||
439 | .is_webcam = 1, | ||
440 | .input = { { | ||
441 | .type = EM28XX_VMUX_COMPOSITE1, | ||
442 | .vmux = 0, | ||
443 | .amux = EM28XX_AMUX_VIDEO, | ||
444 | } }, | ||
445 | }, | ||
446 | [EM2820_BOARD_KWORLD_PVRTV2800RF] = { | ||
447 | .name = "Kworld PVR TV 2800 RF", | ||
448 | .tuner_type = TUNER_TEMIC_PAL, | ||
449 | .tda9887_conf = TDA9887_PRESENT, | ||
450 | .decoder = EM28XX_SAA711X, | ||
451 | .input = { { | ||
452 | .type = EM28XX_VMUX_COMPOSITE1, | ||
453 | .vmux = SAA7115_COMPOSITE0, | ||
454 | .amux = EM28XX_AMUX_LINE_IN, | ||
455 | }, { | ||
456 | .type = EM28XX_VMUX_SVIDEO, | ||
457 | .vmux = SAA7115_SVIDEO3, | ||
458 | .amux = EM28XX_AMUX_LINE_IN, | ||
459 | } }, | ||
460 | }, | ||
461 | [EM2820_BOARD_GADMEI_TVR200] = { | ||
462 | .name = "Gadmei TVR200", | ||
463 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
464 | .tda9887_conf = TDA9887_PRESENT, | ||
465 | .decoder = EM28XX_SAA711X, | ||
466 | .input = { { | ||
467 | .type = EM28XX_VMUX_TELEVISION, | ||
468 | .vmux = SAA7115_COMPOSITE2, | ||
469 | .amux = EM28XX_AMUX_LINE_IN, | ||
470 | }, { | ||
471 | .type = EM28XX_VMUX_COMPOSITE1, | ||
472 | .vmux = SAA7115_COMPOSITE0, | ||
473 | .amux = EM28XX_AMUX_LINE_IN, | ||
474 | }, { | ||
475 | .type = EM28XX_VMUX_SVIDEO, | ||
476 | .vmux = SAA7115_SVIDEO3, | ||
477 | .amux = EM28XX_AMUX_LINE_IN, | ||
478 | } }, | ||
479 | }, | ||
480 | [EM2820_BOARD_TERRATEC_CINERGY_250] = { | ||
481 | .name = "Terratec Cinergy 250 USB", | ||
482 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
483 | .has_ir_i2c = 1, | ||
484 | .tda9887_conf = TDA9887_PRESENT, | ||
485 | .decoder = EM28XX_SAA711X, | ||
486 | .input = { { | ||
487 | .type = EM28XX_VMUX_TELEVISION, | ||
488 | .vmux = SAA7115_COMPOSITE2, | ||
489 | .amux = EM28XX_AMUX_LINE_IN, | ||
490 | }, { | ||
491 | .type = EM28XX_VMUX_COMPOSITE1, | ||
492 | .vmux = SAA7115_COMPOSITE0, | ||
493 | .amux = EM28XX_AMUX_LINE_IN, | ||
494 | }, { | ||
495 | .type = EM28XX_VMUX_SVIDEO, | ||
496 | .vmux = SAA7115_SVIDEO3, | ||
497 | .amux = EM28XX_AMUX_LINE_IN, | ||
498 | } }, | ||
499 | }, | ||
500 | [EM2820_BOARD_PINNACLE_USB_2] = { | ||
501 | .name = "Pinnacle PCTV USB 2", | ||
502 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
503 | .has_ir_i2c = 1, | ||
504 | .tda9887_conf = TDA9887_PRESENT, | ||
505 | .decoder = EM28XX_SAA711X, | ||
506 | .input = { { | ||
507 | .type = EM28XX_VMUX_TELEVISION, | ||
508 | .vmux = SAA7115_COMPOSITE2, | ||
509 | .amux = EM28XX_AMUX_VIDEO, | ||
510 | }, { | ||
511 | .type = EM28XX_VMUX_COMPOSITE1, | ||
512 | .vmux = SAA7115_COMPOSITE0, | ||
513 | .amux = EM28XX_AMUX_LINE_IN, | ||
514 | }, { | ||
515 | .type = EM28XX_VMUX_SVIDEO, | ||
516 | .vmux = SAA7115_SVIDEO3, | ||
517 | .amux = EM28XX_AMUX_LINE_IN, | ||
518 | } }, | ||
519 | }, | ||
520 | [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = { | ||
521 | .name = "Hauppauge WinTV USB 2", | ||
522 | .tuner_type = TUNER_PHILIPS_FM1236_MK3, | ||
523 | .tda9887_conf = TDA9887_PRESENT | | ||
524 | TDA9887_PORT1_ACTIVE | | ||
525 | TDA9887_PORT2_ACTIVE, | ||
526 | .decoder = EM28XX_TVP5150, | ||
527 | .has_msp34xx = 1, | ||
528 | .has_ir_i2c = 1, | ||
529 | .input = { { | ||
530 | .type = EM28XX_VMUX_TELEVISION, | ||
531 | .vmux = TVP5150_COMPOSITE0, | ||
532 | .amux = MSP_INPUT_DEFAULT, | ||
533 | }, { | ||
534 | .type = EM28XX_VMUX_SVIDEO, | ||
535 | .vmux = TVP5150_SVIDEO, | ||
536 | .amux = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1, | ||
537 | MSP_DSP_IN_SCART, MSP_DSP_IN_SCART), | ||
538 | } }, | ||
539 | }, | ||
540 | [EM2820_BOARD_DLINK_USB_TV] = { | ||
541 | .name = "D-Link DUB-T210 TV Tuner", | ||
542 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
543 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
544 | .tda9887_conf = TDA9887_PRESENT, | ||
545 | .decoder = EM28XX_SAA711X, | ||
546 | .input = { { | ||
547 | .type = EM28XX_VMUX_TELEVISION, | ||
548 | .vmux = SAA7115_COMPOSITE2, | ||
549 | .amux = EM28XX_AMUX_LINE_IN, | ||
550 | }, { | ||
551 | .type = EM28XX_VMUX_COMPOSITE1, | ||
552 | .vmux = SAA7115_COMPOSITE0, | ||
553 | .amux = EM28XX_AMUX_LINE_IN, | ||
554 | }, { | ||
555 | .type = EM28XX_VMUX_SVIDEO, | ||
556 | .vmux = SAA7115_SVIDEO3, | ||
557 | .amux = EM28XX_AMUX_LINE_IN, | ||
558 | } }, | ||
559 | }, | ||
560 | [EM2820_BOARD_HERCULES_SMART_TV_USB2] = { | ||
561 | .name = "Hercules Smart TV USB 2.0", | ||
562 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
563 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
564 | .tda9887_conf = TDA9887_PRESENT, | ||
565 | .decoder = EM28XX_SAA711X, | ||
566 | .input = { { | ||
567 | .type = EM28XX_VMUX_TELEVISION, | ||
568 | .vmux = SAA7115_COMPOSITE2, | ||
569 | .amux = EM28XX_AMUX_LINE_IN, | ||
570 | }, { | ||
571 | .type = EM28XX_VMUX_COMPOSITE1, | ||
572 | .vmux = SAA7115_COMPOSITE0, | ||
573 | .amux = EM28XX_AMUX_LINE_IN, | ||
574 | }, { | ||
575 | .type = EM28XX_VMUX_SVIDEO, | ||
576 | .vmux = SAA7115_SVIDEO3, | ||
577 | .amux = EM28XX_AMUX_LINE_IN, | ||
578 | } }, | ||
579 | }, | ||
580 | [EM2820_BOARD_PINNACLE_USB_2_FM1216ME] = { | ||
581 | .name = "Pinnacle PCTV USB 2 (Philips FM1216ME)", | ||
582 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
583 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
584 | .tda9887_conf = TDA9887_PRESENT, | ||
585 | .decoder = EM28XX_SAA711X, | ||
586 | .input = { { | ||
587 | .type = EM28XX_VMUX_TELEVISION, | ||
588 | .vmux = SAA7115_COMPOSITE2, | ||
589 | .amux = EM28XX_AMUX_VIDEO, | ||
590 | }, { | ||
591 | .type = EM28XX_VMUX_COMPOSITE1, | ||
592 | .vmux = SAA7115_COMPOSITE0, | ||
593 | .amux = EM28XX_AMUX_LINE_IN, | ||
594 | }, { | ||
595 | .type = EM28XX_VMUX_SVIDEO, | ||
596 | .vmux = SAA7115_SVIDEO3, | ||
597 | .amux = EM28XX_AMUX_LINE_IN, | ||
598 | } }, | ||
599 | }, | ||
600 | [EM2820_BOARD_GADMEI_UTV310] = { | ||
601 | .name = "Gadmei UTV310", | ||
602 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
603 | .tuner_type = TUNER_TNF_5335MF, | ||
604 | .tda9887_conf = TDA9887_PRESENT, | ||
605 | .decoder = EM28XX_SAA711X, | ||
606 | .input = { { | ||
607 | .type = EM28XX_VMUX_TELEVISION, | ||
608 | .vmux = SAA7115_COMPOSITE1, | ||
609 | .amux = EM28XX_AMUX_LINE_IN, | ||
610 | }, { | ||
611 | .type = EM28XX_VMUX_COMPOSITE1, | ||
612 | .vmux = SAA7115_COMPOSITE0, | ||
613 | .amux = EM28XX_AMUX_LINE_IN, | ||
614 | }, { | ||
615 | .type = EM28XX_VMUX_SVIDEO, | ||
616 | .vmux = SAA7115_SVIDEO3, | ||
617 | .amux = EM28XX_AMUX_LINE_IN, | ||
618 | } }, | ||
619 | }, | ||
620 | [EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE] = { | ||
621 | .name = "Leadtek Winfast USB II Deluxe", | ||
622 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
623 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | ||
624 | .has_ir_i2c = 1, | ||
625 | .tvaudio_addr = 0x58, | ||
626 | .tda9887_conf = TDA9887_PRESENT | | ||
627 | TDA9887_PORT2_ACTIVE | | ||
628 | TDA9887_QSS, | ||
629 | .decoder = EM28XX_SAA711X, | ||
630 | .adecoder = EM28XX_TVAUDIO, | ||
631 | .input = { { | ||
632 | .type = EM28XX_VMUX_TELEVISION, | ||
633 | .vmux = SAA7115_COMPOSITE4, | ||
634 | .amux = EM28XX_AMUX_AUX, | ||
635 | }, { | ||
636 | .type = EM28XX_VMUX_COMPOSITE1, | ||
637 | .vmux = SAA7115_COMPOSITE5, | ||
638 | .amux = EM28XX_AMUX_LINE_IN, | ||
639 | }, { | ||
640 | .type = EM28XX_VMUX_SVIDEO, | ||
641 | .vmux = SAA7115_SVIDEO3, | ||
642 | .amux = EM28XX_AMUX_LINE_IN, | ||
643 | } }, | ||
644 | .radio = { | ||
645 | .type = EM28XX_RADIO, | ||
646 | .amux = EM28XX_AMUX_AUX, | ||
647 | } | ||
648 | }, | ||
649 | [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = { | ||
650 | .name = "Videology 20K14XUSB USB2.0", | ||
651 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
652 | .tuner_type = TUNER_ABSENT, | ||
653 | .is_webcam = 1, | ||
654 | .input = { { | ||
655 | .type = EM28XX_VMUX_COMPOSITE1, | ||
656 | .vmux = 0, | ||
657 | .amux = EM28XX_AMUX_VIDEO, | ||
658 | } }, | ||
659 | }, | ||
660 | [EM2820_BOARD_SILVERCREST_WEBCAM] = { | ||
661 | .name = "Silvercrest Webcam 1.3mpix", | ||
662 | .tuner_type = TUNER_ABSENT, | ||
663 | .is_webcam = 1, | ||
664 | .input = { { | ||
665 | .type = EM28XX_VMUX_COMPOSITE1, | ||
666 | .vmux = 0, | ||
667 | .amux = EM28XX_AMUX_VIDEO, | ||
668 | .gpio = silvercrest_reg_seq, | ||
669 | } }, | ||
670 | }, | ||
671 | [EM2821_BOARD_SUPERCOMP_USB_2] = { | ||
672 | .name = "Supercomp USB 2.0 TV", | ||
673 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
674 | .tuner_type = TUNER_PHILIPS_FM1236_MK3, | ||
675 | .tda9887_conf = TDA9887_PRESENT | | ||
676 | TDA9887_PORT1_ACTIVE | | ||
677 | TDA9887_PORT2_ACTIVE, | ||
678 | .decoder = EM28XX_SAA711X, | ||
679 | .input = { { | ||
680 | .type = EM28XX_VMUX_TELEVISION, | ||
681 | .vmux = SAA7115_COMPOSITE2, | ||
682 | .amux = EM28XX_AMUX_LINE_IN, | ||
683 | }, { | ||
684 | .type = EM28XX_VMUX_COMPOSITE1, | ||
685 | .vmux = SAA7115_COMPOSITE0, | ||
686 | .amux = EM28XX_AMUX_VIDEO, | ||
687 | }, { | ||
688 | .type = EM28XX_VMUX_SVIDEO, | ||
689 | .vmux = SAA7115_SVIDEO3, | ||
690 | .amux = EM28XX_AMUX_LINE_IN, | ||
691 | } }, | ||
692 | }, | ||
693 | [EM2821_BOARD_USBGEAR_VD204] = { | ||
694 | .name = "Usbgear VD204v9", | ||
695 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
696 | .tuner_type = TUNER_ABSENT, /* Capture only device */ | ||
697 | .decoder = EM28XX_SAA711X, | ||
698 | .input = { { | ||
699 | .type = EM28XX_VMUX_COMPOSITE1, | ||
700 | .vmux = SAA7115_COMPOSITE0, | ||
701 | .amux = EM28XX_AMUX_LINE_IN, | ||
702 | }, { | ||
703 | .type = EM28XX_VMUX_SVIDEO, | ||
704 | .vmux = SAA7115_SVIDEO3, | ||
705 | .amux = EM28XX_AMUX_LINE_IN, | ||
706 | } }, | ||
707 | }, | ||
708 | [EM2860_BOARD_NETGMBH_CAM] = { | ||
709 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ | ||
710 | .name = "NetGMBH Cam", | ||
711 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
712 | .tuner_type = TUNER_ABSENT, | ||
713 | .is_webcam = 1, | ||
714 | .input = { { | ||
715 | .type = EM28XX_VMUX_COMPOSITE1, | ||
716 | .vmux = 0, | ||
717 | .amux = EM28XX_AMUX_VIDEO, | ||
718 | } }, | ||
719 | }, | ||
720 | [EM2860_BOARD_TYPHOON_DVD_MAKER] = { | ||
721 | .name = "Typhoon DVD Maker", | ||
722 | .decoder = EM28XX_SAA711X, | ||
723 | .tuner_type = TUNER_ABSENT, /* Capture only device */ | ||
724 | .input = { { | ||
725 | .type = EM28XX_VMUX_COMPOSITE1, | ||
726 | .vmux = SAA7115_COMPOSITE0, | ||
727 | .amux = EM28XX_AMUX_LINE_IN, | ||
728 | }, { | ||
729 | .type = EM28XX_VMUX_SVIDEO, | ||
730 | .vmux = SAA7115_SVIDEO3, | ||
731 | .amux = EM28XX_AMUX_LINE_IN, | ||
732 | } }, | ||
733 | }, | ||
734 | [EM2860_BOARD_GADMEI_UTV330] = { | ||
735 | .name = "Gadmei UTV330", | ||
736 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
737 | .tuner_type = TUNER_TNF_5335MF, | ||
738 | .tda9887_conf = TDA9887_PRESENT, | ||
739 | .decoder = EM28XX_SAA711X, | ||
740 | .input = { { | ||
741 | .type = EM28XX_VMUX_TELEVISION, | ||
742 | .vmux = SAA7115_COMPOSITE2, | ||
743 | .amux = EM28XX_AMUX_VIDEO, | ||
744 | }, { | ||
745 | .type = EM28XX_VMUX_COMPOSITE1, | ||
746 | .vmux = SAA7115_COMPOSITE0, | ||
747 | .amux = EM28XX_AMUX_LINE_IN, | ||
748 | }, { | ||
749 | .type = EM28XX_VMUX_SVIDEO, | ||
750 | .vmux = SAA7115_SVIDEO3, | ||
751 | .amux = EM28XX_AMUX_LINE_IN, | ||
752 | } }, | ||
753 | }, | ||
754 | [EM2861_BOARD_GADMEI_UTV330PLUS] = { | ||
755 | .name = "Gadmei UTV330+", | ||
756 | .tuner_type = TUNER_TNF_5335MF, | ||
757 | .tda9887_conf = TDA9887_PRESENT, | ||
758 | .ir_codes = RC_MAP_GADMEI_RM008Z, | ||
759 | .decoder = EM28XX_SAA711X, | ||
760 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
761 | .input = { { | ||
762 | .type = EM28XX_VMUX_TELEVISION, | ||
763 | .vmux = SAA7115_COMPOSITE2, | ||
764 | .amux = EM28XX_AMUX_VIDEO, | ||
765 | }, { | ||
766 | .type = EM28XX_VMUX_COMPOSITE1, | ||
767 | .vmux = SAA7115_COMPOSITE0, | ||
768 | .amux = EM28XX_AMUX_LINE_IN, | ||
769 | }, { | ||
770 | .type = EM28XX_VMUX_SVIDEO, | ||
771 | .vmux = SAA7115_SVIDEO3, | ||
772 | .amux = EM28XX_AMUX_LINE_IN, | ||
773 | } }, | ||
774 | }, | ||
775 | [EM2860_BOARD_TERRATEC_HYBRID_XS] = { | ||
776 | .name = "Terratec Cinergy A Hybrid XS", | ||
777 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
778 | .tuner_type = TUNER_XC2028, | ||
779 | .tuner_gpio = default_tuner_gpio, | ||
780 | .decoder = EM28XX_TVP5150, | ||
781 | |||
782 | .input = { { | ||
783 | .type = EM28XX_VMUX_TELEVISION, | ||
784 | .vmux = TVP5150_COMPOSITE0, | ||
785 | .amux = EM28XX_AMUX_VIDEO, | ||
786 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
787 | }, { | ||
788 | .type = EM28XX_VMUX_COMPOSITE1, | ||
789 | .vmux = TVP5150_COMPOSITE1, | ||
790 | .amux = EM28XX_AMUX_LINE_IN, | ||
791 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
792 | }, { | ||
793 | .type = EM28XX_VMUX_SVIDEO, | ||
794 | .vmux = TVP5150_SVIDEO, | ||
795 | .amux = EM28XX_AMUX_LINE_IN, | ||
796 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
797 | } }, | ||
798 | }, | ||
799 | [EM2861_BOARD_KWORLD_PVRTV_300U] = { | ||
800 | .name = "KWorld PVRTV 300U", | ||
801 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
802 | .tuner_type = TUNER_XC2028, | ||
803 | .tuner_gpio = default_tuner_gpio, | ||
804 | .decoder = EM28XX_TVP5150, | ||
805 | .input = { { | ||
806 | .type = EM28XX_VMUX_TELEVISION, | ||
807 | .vmux = TVP5150_COMPOSITE0, | ||
808 | .amux = EM28XX_AMUX_VIDEO, | ||
809 | }, { | ||
810 | .type = EM28XX_VMUX_COMPOSITE1, | ||
811 | .vmux = TVP5150_COMPOSITE1, | ||
812 | .amux = EM28XX_AMUX_LINE_IN, | ||
813 | }, { | ||
814 | .type = EM28XX_VMUX_SVIDEO, | ||
815 | .vmux = TVP5150_SVIDEO, | ||
816 | .amux = EM28XX_AMUX_LINE_IN, | ||
817 | } }, | ||
818 | }, | ||
819 | [EM2861_BOARD_YAKUMO_MOVIE_MIXER] = { | ||
820 | .name = "Yakumo MovieMixer", | ||
821 | .tuner_type = TUNER_ABSENT, /* Capture only device */ | ||
822 | .decoder = EM28XX_TVP5150, | ||
823 | .input = { { | ||
824 | .type = EM28XX_VMUX_TELEVISION, | ||
825 | .vmux = TVP5150_COMPOSITE0, | ||
826 | .amux = EM28XX_AMUX_VIDEO, | ||
827 | }, { | ||
828 | .type = EM28XX_VMUX_COMPOSITE1, | ||
829 | .vmux = TVP5150_COMPOSITE1, | ||
830 | .amux = EM28XX_AMUX_LINE_IN, | ||
831 | }, { | ||
832 | .type = EM28XX_VMUX_SVIDEO, | ||
833 | .vmux = TVP5150_SVIDEO, | ||
834 | .amux = EM28XX_AMUX_LINE_IN, | ||
835 | } }, | ||
836 | }, | ||
837 | [EM2860_BOARD_TVP5150_REFERENCE_DESIGN] = { | ||
838 | .name = "EM2860/TVP5150 Reference Design", | ||
839 | .tuner_type = TUNER_ABSENT, /* Capture only device */ | ||
840 | .decoder = EM28XX_TVP5150, | ||
841 | .input = { { | ||
842 | .type = EM28XX_VMUX_COMPOSITE1, | ||
843 | .vmux = TVP5150_COMPOSITE1, | ||
844 | .amux = EM28XX_AMUX_LINE_IN, | ||
845 | }, { | ||
846 | .type = EM28XX_VMUX_SVIDEO, | ||
847 | .vmux = TVP5150_SVIDEO, | ||
848 | .amux = EM28XX_AMUX_LINE_IN, | ||
849 | } }, | ||
850 | }, | ||
851 | [EM2861_BOARD_PLEXTOR_PX_TV100U] = { | ||
852 | .name = "Plextor ConvertX PX-TV100U", | ||
853 | .tuner_type = TUNER_TNF_5335MF, | ||
854 | .xclk = EM28XX_XCLK_I2S_MSB_TIMING | | ||
855 | EM28XX_XCLK_FREQUENCY_12MHZ, | ||
856 | .tda9887_conf = TDA9887_PRESENT, | ||
857 | .decoder = EM28XX_TVP5150, | ||
858 | .has_msp34xx = 1, | ||
859 | .input = { { | ||
860 | .type = EM28XX_VMUX_TELEVISION, | ||
861 | .vmux = TVP5150_COMPOSITE0, | ||
862 | .amux = EM28XX_AMUX_LINE_IN, | ||
863 | .gpio = pinnacle_hybrid_pro_analog, | ||
864 | }, { | ||
865 | .type = EM28XX_VMUX_COMPOSITE1, | ||
866 | .vmux = TVP5150_COMPOSITE1, | ||
867 | .amux = EM28XX_AMUX_LINE_IN, | ||
868 | .gpio = pinnacle_hybrid_pro_analog, | ||
869 | }, { | ||
870 | .type = EM28XX_VMUX_SVIDEO, | ||
871 | .vmux = TVP5150_SVIDEO, | ||
872 | .amux = EM28XX_AMUX_LINE_IN, | ||
873 | .gpio = pinnacle_hybrid_pro_analog, | ||
874 | } }, | ||
875 | }, | ||
876 | |||
877 | /* Those boards with em2870 are DVB Only*/ | ||
878 | |||
879 | [EM2870_BOARD_TERRATEC_XS] = { | ||
880 | .name = "Terratec Cinergy T XS", | ||
881 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
882 | .tuner_type = TUNER_XC2028, | ||
883 | .tuner_gpio = default_tuner_gpio, | ||
884 | }, | ||
885 | [EM2870_BOARD_TERRATEC_XS_MT2060] = { | ||
886 | .name = "Terratec Cinergy T XS (MT2060)", | ||
887 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
888 | .tuner_type = TUNER_ABSENT, /* MT2060 */ | ||
889 | }, | ||
890 | [EM2870_BOARD_KWORLD_350U] = { | ||
891 | .name = "Kworld 350 U DVB-T", | ||
892 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
893 | .tuner_type = TUNER_XC2028, | ||
894 | .tuner_gpio = default_tuner_gpio, | ||
895 | }, | ||
896 | [EM2870_BOARD_KWORLD_355U] = { | ||
897 | .name = "Kworld 355 U DVB-T", | ||
898 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
899 | .tuner_type = TUNER_ABSENT, | ||
900 | .tuner_gpio = default_tuner_gpio, | ||
901 | .has_dvb = 1, | ||
902 | .dvb_gpio = default_digital, | ||
903 | }, | ||
904 | [EM2870_BOARD_PINNACLE_PCTV_DVB] = { | ||
905 | .name = "Pinnacle PCTV DVB-T", | ||
906 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
907 | .tuner_type = TUNER_ABSENT, /* MT2060 */ | ||
908 | /* djh - I have serious doubts this is right... */ | ||
909 | .xclk = EM28XX_XCLK_IR_RC5_MODE | | ||
910 | EM28XX_XCLK_FREQUENCY_10MHZ, | ||
911 | }, | ||
912 | [EM2870_BOARD_COMPRO_VIDEOMATE] = { | ||
913 | .name = "Compro, VideoMate U3", | ||
914 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
915 | .tuner_type = TUNER_ABSENT, /* MT2060 */ | ||
916 | }, | ||
917 | |||
918 | [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = { | ||
919 | .name = "Terratec Hybrid XS Secam", | ||
920 | .has_msp34xx = 1, | ||
921 | .tuner_type = TUNER_XC2028, | ||
922 | .tuner_gpio = default_tuner_gpio, | ||
923 | .decoder = EM28XX_TVP5150, | ||
924 | .has_dvb = 1, | ||
925 | .dvb_gpio = terratec_cinergy_USB_XS_FR_digital, | ||
926 | .input = { { | ||
927 | .type = EM28XX_VMUX_TELEVISION, | ||
928 | .vmux = TVP5150_COMPOSITE0, | ||
929 | .amux = EM28XX_AMUX_VIDEO, | ||
930 | .gpio = terratec_cinergy_USB_XS_FR_analog, | ||
931 | }, { | ||
932 | .type = EM28XX_VMUX_COMPOSITE1, | ||
933 | .vmux = TVP5150_COMPOSITE1, | ||
934 | .amux = EM28XX_AMUX_LINE_IN, | ||
935 | .gpio = terratec_cinergy_USB_XS_FR_analog, | ||
936 | }, { | ||
937 | .type = EM28XX_VMUX_SVIDEO, | ||
938 | .vmux = TVP5150_SVIDEO, | ||
939 | .amux = EM28XX_AMUX_LINE_IN, | ||
940 | .gpio = terratec_cinergy_USB_XS_FR_analog, | ||
941 | } }, | ||
942 | }, | ||
943 | [EM2884_BOARD_TERRATEC_H5] = { | ||
944 | .name = "Terratec Cinergy H5", | ||
945 | .has_dvb = 1, | ||
946 | #if 0 | ||
947 | .tuner_type = TUNER_PHILIPS_TDA8290, | ||
948 | .tuner_addr = 0x41, | ||
949 | .dvb_gpio = terratec_h5_digital, /* FIXME: probably wrong */ | ||
950 | .tuner_gpio = terratec_h5_gpio, | ||
951 | #else | ||
952 | .tuner_type = TUNER_ABSENT, | ||
953 | #endif | ||
954 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
955 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
956 | EM28XX_I2C_FREQ_400_KHZ, | ||
957 | }, | ||
958 | [EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C] = { | ||
959 | .name = "Hauppauge WinTV HVR 930C", | ||
960 | .has_dvb = 1, | ||
961 | #if 0 /* FIXME: Add analog support */ | ||
962 | .tuner_type = TUNER_XC5000, | ||
963 | .tuner_addr = 0x41, | ||
964 | .dvb_gpio = hauppauge_930c_digital, | ||
965 | .tuner_gpio = hauppauge_930c_gpio, | ||
966 | #else | ||
967 | .tuner_type = TUNER_ABSENT, | ||
968 | #endif | ||
969 | .ir_codes = RC_MAP_HAUPPAUGE, | ||
970 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
971 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
972 | EM28XX_I2C_FREQ_400_KHZ, | ||
973 | }, | ||
974 | [EM2884_BOARD_CINERGY_HTC_STICK] = { | ||
975 | .name = "Terratec Cinergy HTC Stick", | ||
976 | .has_dvb = 1, | ||
977 | .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, | ||
978 | .tuner_type = TUNER_ABSENT, | ||
979 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
980 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
981 | EM28XX_I2C_FREQ_400_KHZ, | ||
982 | }, | ||
983 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { | ||
984 | .name = "Hauppauge WinTV HVR 900", | ||
985 | .tda9887_conf = TDA9887_PRESENT, | ||
986 | .tuner_type = TUNER_XC2028, | ||
987 | .tuner_gpio = default_tuner_gpio, | ||
988 | .mts_firmware = 1, | ||
989 | .has_dvb = 1, | ||
990 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
991 | .ir_codes = RC_MAP_HAUPPAUGE, | ||
992 | .decoder = EM28XX_TVP5150, | ||
993 | .input = { { | ||
994 | .type = EM28XX_VMUX_TELEVISION, | ||
995 | .vmux = TVP5150_COMPOSITE0, | ||
996 | .amux = EM28XX_AMUX_VIDEO, | ||
997 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
998 | }, { | ||
999 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1000 | .vmux = TVP5150_COMPOSITE1, | ||
1001 | .amux = EM28XX_AMUX_LINE_IN, | ||
1002 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1003 | }, { | ||
1004 | .type = EM28XX_VMUX_SVIDEO, | ||
1005 | .vmux = TVP5150_SVIDEO, | ||
1006 | .amux = EM28XX_AMUX_LINE_IN, | ||
1007 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1008 | } }, | ||
1009 | }, | ||
1010 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = { | ||
1011 | .name = "Hauppauge WinTV HVR 900 (R2)", | ||
1012 | .tda9887_conf = TDA9887_PRESENT, | ||
1013 | .tuner_type = TUNER_XC2028, | ||
1014 | .tuner_gpio = default_tuner_gpio, | ||
1015 | .mts_firmware = 1, | ||
1016 | .has_dvb = 1, | ||
1017 | .dvb_gpio = hauppauge_wintv_hvr_900R2_digital, | ||
1018 | .ir_codes = RC_MAP_HAUPPAUGE, | ||
1019 | .decoder = EM28XX_TVP5150, | ||
1020 | .input = { { | ||
1021 | .type = EM28XX_VMUX_TELEVISION, | ||
1022 | .vmux = TVP5150_COMPOSITE0, | ||
1023 | .amux = EM28XX_AMUX_VIDEO, | ||
1024 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1025 | }, { | ||
1026 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1027 | .vmux = TVP5150_COMPOSITE1, | ||
1028 | .amux = EM28XX_AMUX_LINE_IN, | ||
1029 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1030 | }, { | ||
1031 | .type = EM28XX_VMUX_SVIDEO, | ||
1032 | .vmux = TVP5150_SVIDEO, | ||
1033 | .amux = EM28XX_AMUX_LINE_IN, | ||
1034 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1035 | } }, | ||
1036 | }, | ||
1037 | [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850] = { | ||
1038 | .name = "Hauppauge WinTV HVR 850", | ||
1039 | .tuner_type = TUNER_XC2028, | ||
1040 | .tuner_gpio = default_tuner_gpio, | ||
1041 | .mts_firmware = 1, | ||
1042 | .has_dvb = 1, | ||
1043 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
1044 | .ir_codes = RC_MAP_HAUPPAUGE, | ||
1045 | .decoder = EM28XX_TVP5150, | ||
1046 | .input = { { | ||
1047 | .type = EM28XX_VMUX_TELEVISION, | ||
1048 | .vmux = TVP5150_COMPOSITE0, | ||
1049 | .amux = EM28XX_AMUX_VIDEO, | ||
1050 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1051 | }, { | ||
1052 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1053 | .vmux = TVP5150_COMPOSITE1, | ||
1054 | .amux = EM28XX_AMUX_LINE_IN, | ||
1055 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1056 | }, { | ||
1057 | .type = EM28XX_VMUX_SVIDEO, | ||
1058 | .vmux = TVP5150_SVIDEO, | ||
1059 | .amux = EM28XX_AMUX_LINE_IN, | ||
1060 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1061 | } }, | ||
1062 | }, | ||
1063 | [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = { | ||
1064 | .name = "Hauppauge WinTV HVR 950", | ||
1065 | .tuner_type = TUNER_XC2028, | ||
1066 | .tuner_gpio = default_tuner_gpio, | ||
1067 | .mts_firmware = 1, | ||
1068 | .has_dvb = 1, | ||
1069 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
1070 | .ir_codes = RC_MAP_HAUPPAUGE, | ||
1071 | .decoder = EM28XX_TVP5150, | ||
1072 | .input = { { | ||
1073 | .type = EM28XX_VMUX_TELEVISION, | ||
1074 | .vmux = TVP5150_COMPOSITE0, | ||
1075 | .amux = EM28XX_AMUX_VIDEO, | ||
1076 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1077 | }, { | ||
1078 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1079 | .vmux = TVP5150_COMPOSITE1, | ||
1080 | .amux = EM28XX_AMUX_LINE_IN, | ||
1081 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1082 | }, { | ||
1083 | .type = EM28XX_VMUX_SVIDEO, | ||
1084 | .vmux = TVP5150_SVIDEO, | ||
1085 | .amux = EM28XX_AMUX_LINE_IN, | ||
1086 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1087 | } }, | ||
1088 | }, | ||
1089 | [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = { | ||
1090 | .name = "Pinnacle PCTV HD Pro Stick", | ||
1091 | .tuner_type = TUNER_XC2028, | ||
1092 | .tuner_gpio = default_tuner_gpio, | ||
1093 | .mts_firmware = 1, | ||
1094 | .has_dvb = 1, | ||
1095 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
1096 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | ||
1097 | .decoder = EM28XX_TVP5150, | ||
1098 | .input = { { | ||
1099 | .type = EM28XX_VMUX_TELEVISION, | ||
1100 | .vmux = TVP5150_COMPOSITE0, | ||
1101 | .amux = EM28XX_AMUX_VIDEO, | ||
1102 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1103 | }, { | ||
1104 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1105 | .vmux = TVP5150_COMPOSITE1, | ||
1106 | .amux = EM28XX_AMUX_LINE_IN, | ||
1107 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1108 | }, { | ||
1109 | .type = EM28XX_VMUX_SVIDEO, | ||
1110 | .vmux = TVP5150_SVIDEO, | ||
1111 | .amux = EM28XX_AMUX_LINE_IN, | ||
1112 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1113 | } }, | ||
1114 | }, | ||
1115 | [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { | ||
1116 | .name = "AMD ATI TV Wonder HD 600", | ||
1117 | .tuner_type = TUNER_XC2028, | ||
1118 | .tuner_gpio = default_tuner_gpio, | ||
1119 | .mts_firmware = 1, | ||
1120 | .has_dvb = 1, | ||
1121 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
1122 | .ir_codes = RC_MAP_ATI_TV_WONDER_HD_600, | ||
1123 | .decoder = EM28XX_TVP5150, | ||
1124 | .input = { { | ||
1125 | .type = EM28XX_VMUX_TELEVISION, | ||
1126 | .vmux = TVP5150_COMPOSITE0, | ||
1127 | .amux = EM28XX_AMUX_VIDEO, | ||
1128 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1129 | }, { | ||
1130 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1131 | .vmux = TVP5150_COMPOSITE1, | ||
1132 | .amux = EM28XX_AMUX_LINE_IN, | ||
1133 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1134 | }, { | ||
1135 | .type = EM28XX_VMUX_SVIDEO, | ||
1136 | .vmux = TVP5150_SVIDEO, | ||
1137 | .amux = EM28XX_AMUX_LINE_IN, | ||
1138 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1139 | } }, | ||
1140 | }, | ||
1141 | [EM2880_BOARD_TERRATEC_HYBRID_XS] = { | ||
1142 | .name = "Terratec Hybrid XS", | ||
1143 | .tuner_type = TUNER_XC2028, | ||
1144 | .tuner_gpio = default_tuner_gpio, | ||
1145 | .decoder = EM28XX_TVP5150, | ||
1146 | .has_dvb = 1, | ||
1147 | .dvb_gpio = default_digital, | ||
1148 | .ir_codes = RC_MAP_TERRATEC_CINERGY_XS, | ||
1149 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */ | ||
1150 | .input = { { | ||
1151 | .type = EM28XX_VMUX_TELEVISION, | ||
1152 | .vmux = TVP5150_COMPOSITE0, | ||
1153 | .amux = EM28XX_AMUX_VIDEO, | ||
1154 | .gpio = default_analog, | ||
1155 | }, { | ||
1156 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1157 | .vmux = TVP5150_COMPOSITE1, | ||
1158 | .amux = EM28XX_AMUX_LINE_IN, | ||
1159 | .gpio = default_analog, | ||
1160 | }, { | ||
1161 | .type = EM28XX_VMUX_SVIDEO, | ||
1162 | .vmux = TVP5150_SVIDEO, | ||
1163 | .amux = EM28XX_AMUX_LINE_IN, | ||
1164 | .gpio = default_analog, | ||
1165 | } }, | ||
1166 | }, | ||
1167 | /* maybe there's a reason behind it why Terratec sells the Hybrid XS | ||
1168 | as Prodigy XS with a different PID, let's keep it separated for now | ||
1169 | maybe we'll need it lateron */ | ||
1170 | [EM2880_BOARD_TERRATEC_PRODIGY_XS] = { | ||
1171 | .name = "Terratec Prodigy XS", | ||
1172 | .tuner_type = TUNER_XC2028, | ||
1173 | .tuner_gpio = default_tuner_gpio, | ||
1174 | .decoder = EM28XX_TVP5150, | ||
1175 | .input = { { | ||
1176 | .type = EM28XX_VMUX_TELEVISION, | ||
1177 | .vmux = TVP5150_COMPOSITE0, | ||
1178 | .amux = EM28XX_AMUX_VIDEO, | ||
1179 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1180 | }, { | ||
1181 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1182 | .vmux = TVP5150_COMPOSITE1, | ||
1183 | .amux = EM28XX_AMUX_LINE_IN, | ||
1184 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1185 | }, { | ||
1186 | .type = EM28XX_VMUX_SVIDEO, | ||
1187 | .vmux = TVP5150_SVIDEO, | ||
1188 | .amux = EM28XX_AMUX_LINE_IN, | ||
1189 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1190 | } }, | ||
1191 | }, | ||
1192 | [EM2820_BOARD_MSI_VOX_USB_2] = { | ||
1193 | .name = "MSI VOX USB 2.0", | ||
1194 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
1195 | .tda9887_conf = TDA9887_PRESENT | | ||
1196 | TDA9887_PORT1_ACTIVE | | ||
1197 | TDA9887_PORT2_ACTIVE, | ||
1198 | .max_range_640_480 = 1, | ||
1199 | .decoder = EM28XX_SAA711X, | ||
1200 | .input = { { | ||
1201 | .type = EM28XX_VMUX_TELEVISION, | ||
1202 | .vmux = SAA7115_COMPOSITE4, | ||
1203 | .amux = EM28XX_AMUX_VIDEO, | ||
1204 | }, { | ||
1205 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1206 | .vmux = SAA7115_COMPOSITE0, | ||
1207 | .amux = EM28XX_AMUX_LINE_IN, | ||
1208 | }, { | ||
1209 | .type = EM28XX_VMUX_SVIDEO, | ||
1210 | .vmux = SAA7115_SVIDEO3, | ||
1211 | .amux = EM28XX_AMUX_LINE_IN, | ||
1212 | } }, | ||
1213 | }, | ||
1214 | [EM2800_BOARD_TERRATEC_CINERGY_200] = { | ||
1215 | .name = "Terratec Cinergy 200 USB", | ||
1216 | .is_em2800 = 1, | ||
1217 | .has_ir_i2c = 1, | ||
1218 | .tuner_type = TUNER_LG_TALN, | ||
1219 | .tda9887_conf = TDA9887_PRESENT, | ||
1220 | .decoder = EM28XX_SAA711X, | ||
1221 | .input = { { | ||
1222 | .type = EM28XX_VMUX_TELEVISION, | ||
1223 | .vmux = SAA7115_COMPOSITE2, | ||
1224 | .amux = EM28XX_AMUX_VIDEO, | ||
1225 | }, { | ||
1226 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1227 | .vmux = SAA7115_COMPOSITE0, | ||
1228 | .amux = EM28XX_AMUX_LINE_IN, | ||
1229 | }, { | ||
1230 | .type = EM28XX_VMUX_SVIDEO, | ||
1231 | .vmux = SAA7115_SVIDEO3, | ||
1232 | .amux = EM28XX_AMUX_LINE_IN, | ||
1233 | } }, | ||
1234 | }, | ||
1235 | [EM2800_BOARD_GRABBEEX_USB2800] = { | ||
1236 | .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder", | ||
1237 | .is_em2800 = 1, | ||
1238 | .decoder = EM28XX_SAA711X, | ||
1239 | .tuner_type = TUNER_ABSENT, /* capture only board */ | ||
1240 | .input = { { | ||
1241 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1242 | .vmux = SAA7115_COMPOSITE0, | ||
1243 | .amux = EM28XX_AMUX_LINE_IN, | ||
1244 | }, { | ||
1245 | .type = EM28XX_VMUX_SVIDEO, | ||
1246 | .vmux = SAA7115_SVIDEO3, | ||
1247 | .amux = EM28XX_AMUX_LINE_IN, | ||
1248 | } }, | ||
1249 | }, | ||
1250 | [EM2800_BOARD_VC211A] = { | ||
1251 | .name = "Actionmaster/LinXcel/Digitus VC211A", | ||
1252 | .is_em2800 = 1, | ||
1253 | .tuner_type = TUNER_ABSENT, /* Capture-only board */ | ||
1254 | .decoder = EM28XX_SAA711X, | ||
1255 | .input = { { | ||
1256 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1257 | .vmux = SAA7115_COMPOSITE0, | ||
1258 | .amux = EM28XX_AMUX_LINE_IN, | ||
1259 | .gpio = vc211a_enable, | ||
1260 | }, { | ||
1261 | .type = EM28XX_VMUX_SVIDEO, | ||
1262 | .vmux = SAA7115_SVIDEO3, | ||
1263 | .amux = EM28XX_AMUX_LINE_IN, | ||
1264 | .gpio = vc211a_enable, | ||
1265 | } }, | ||
1266 | }, | ||
1267 | [EM2800_BOARD_LEADTEK_WINFAST_USBII] = { | ||
1268 | .name = "Leadtek Winfast USB II", | ||
1269 | .is_em2800 = 1, | ||
1270 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
1271 | .tda9887_conf = TDA9887_PRESENT, | ||
1272 | .decoder = EM28XX_SAA711X, | ||
1273 | .input = { { | ||
1274 | .type = EM28XX_VMUX_TELEVISION, | ||
1275 | .vmux = SAA7115_COMPOSITE2, | ||
1276 | .amux = EM28XX_AMUX_VIDEO, | ||
1277 | }, { | ||
1278 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1279 | .vmux = SAA7115_COMPOSITE0, | ||
1280 | .amux = EM28XX_AMUX_LINE_IN, | ||
1281 | }, { | ||
1282 | .type = EM28XX_VMUX_SVIDEO, | ||
1283 | .vmux = SAA7115_SVIDEO3, | ||
1284 | .amux = EM28XX_AMUX_LINE_IN, | ||
1285 | } }, | ||
1286 | }, | ||
1287 | [EM2800_BOARD_KWORLD_USB2800] = { | ||
1288 | .name = "Kworld USB2800", | ||
1289 | .is_em2800 = 1, | ||
1290 | .tuner_type = TUNER_PHILIPS_FCV1236D, | ||
1291 | .tda9887_conf = TDA9887_PRESENT, | ||
1292 | .decoder = EM28XX_SAA711X, | ||
1293 | .input = { { | ||
1294 | .type = EM28XX_VMUX_TELEVISION, | ||
1295 | .vmux = SAA7115_COMPOSITE2, | ||
1296 | .amux = EM28XX_AMUX_VIDEO, | ||
1297 | }, { | ||
1298 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1299 | .vmux = SAA7115_COMPOSITE0, | ||
1300 | .amux = EM28XX_AMUX_LINE_IN, | ||
1301 | }, { | ||
1302 | .type = EM28XX_VMUX_SVIDEO, | ||
1303 | .vmux = SAA7115_SVIDEO3, | ||
1304 | .amux = EM28XX_AMUX_LINE_IN, | ||
1305 | } }, | ||
1306 | }, | ||
1307 | [EM2820_BOARD_PINNACLE_DVC_90] = { | ||
1308 | .name = "Pinnacle Dazzle DVC 90/100/101/107 / Kaiser Baas Video to DVD maker " | ||
1309 | "/ Kworld DVD Maker 2 / Plextor ConvertX PX-AV100U", | ||
1310 | .tuner_type = TUNER_ABSENT, /* capture only board */ | ||
1311 | .decoder = EM28XX_SAA711X, | ||
1312 | .input = { { | ||
1313 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1314 | .vmux = SAA7115_COMPOSITE0, | ||
1315 | .amux = EM28XX_AMUX_LINE_IN, | ||
1316 | }, { | ||
1317 | .type = EM28XX_VMUX_SVIDEO, | ||
1318 | .vmux = SAA7115_SVIDEO3, | ||
1319 | .amux = EM28XX_AMUX_LINE_IN, | ||
1320 | } }, | ||
1321 | }, | ||
1322 | [EM2800_BOARD_VGEAR_POCKETTV] = { | ||
1323 | .name = "V-Gear PocketTV", | ||
1324 | .is_em2800 = 1, | ||
1325 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
1326 | .tda9887_conf = TDA9887_PRESENT, | ||
1327 | .decoder = EM28XX_SAA711X, | ||
1328 | .input = { { | ||
1329 | .type = EM28XX_VMUX_TELEVISION, | ||
1330 | .vmux = SAA7115_COMPOSITE2, | ||
1331 | .amux = EM28XX_AMUX_VIDEO, | ||
1332 | }, { | ||
1333 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1334 | .vmux = SAA7115_COMPOSITE0, | ||
1335 | .amux = EM28XX_AMUX_LINE_IN, | ||
1336 | }, { | ||
1337 | .type = EM28XX_VMUX_SVIDEO, | ||
1338 | .vmux = SAA7115_SVIDEO3, | ||
1339 | .amux = EM28XX_AMUX_LINE_IN, | ||
1340 | } }, | ||
1341 | }, | ||
1342 | [EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2] = { | ||
1343 | .name = "Pixelview PlayTV Box 4 USB 2.0", | ||
1344 | .tda9887_conf = TDA9887_PRESENT, | ||
1345 | .tuner_type = TUNER_YMEC_TVF_5533MF, | ||
1346 | .decoder = EM28XX_SAA711X, | ||
1347 | .input = { { | ||
1348 | .type = EM28XX_VMUX_TELEVISION, | ||
1349 | .vmux = SAA7115_COMPOSITE2, | ||
1350 | .amux = EM28XX_AMUX_VIDEO, | ||
1351 | .aout = EM28XX_AOUT_MONO | /* I2S */ | ||
1352 | EM28XX_AOUT_MASTER, /* Line out pin */ | ||
1353 | }, { | ||
1354 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1355 | .vmux = SAA7115_COMPOSITE0, | ||
1356 | .amux = EM28XX_AMUX_LINE_IN, | ||
1357 | }, { | ||
1358 | .type = EM28XX_VMUX_SVIDEO, | ||
1359 | .vmux = SAA7115_SVIDEO3, | ||
1360 | .amux = EM28XX_AMUX_LINE_IN, | ||
1361 | } }, | ||
1362 | }, | ||
1363 | [EM2820_BOARD_PROLINK_PLAYTV_USB2] = { | ||
1364 | .name = "SIIG AVTuner-PVR / Pixelview Prolink PlayTV USB 2.0", | ||
1365 | .has_snapshot_button = 1, | ||
1366 | .tda9887_conf = TDA9887_PRESENT, | ||
1367 | .tuner_type = TUNER_YMEC_TVF_5533MF, | ||
1368 | .decoder = EM28XX_SAA711X, | ||
1369 | .input = { { | ||
1370 | .type = EM28XX_VMUX_TELEVISION, | ||
1371 | .vmux = SAA7115_COMPOSITE2, | ||
1372 | .amux = EM28XX_AMUX_VIDEO, | ||
1373 | .aout = EM28XX_AOUT_MONO | /* I2S */ | ||
1374 | EM28XX_AOUT_MASTER, /* Line out pin */ | ||
1375 | }, { | ||
1376 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1377 | .vmux = SAA7115_COMPOSITE0, | ||
1378 | .amux = EM28XX_AMUX_LINE_IN, | ||
1379 | }, { | ||
1380 | .type = EM28XX_VMUX_SVIDEO, | ||
1381 | .vmux = SAA7115_SVIDEO3, | ||
1382 | .amux = EM28XX_AMUX_LINE_IN, | ||
1383 | } }, | ||
1384 | }, | ||
1385 | [EM2860_BOARD_SAA711X_REFERENCE_DESIGN] = { | ||
1386 | .name = "EM2860/SAA711X Reference Design", | ||
1387 | .has_snapshot_button = 1, | ||
1388 | .tuner_type = TUNER_ABSENT, | ||
1389 | .decoder = EM28XX_SAA711X, | ||
1390 | .input = { { | ||
1391 | .type = EM28XX_VMUX_SVIDEO, | ||
1392 | .vmux = SAA7115_SVIDEO3, | ||
1393 | }, { | ||
1394 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1395 | .vmux = SAA7115_COMPOSITE0, | ||
1396 | } }, | ||
1397 | }, | ||
1398 | |||
1399 | [EM2874_BOARD_LEADERSHIP_ISDBT] = { | ||
1400 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
1401 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
1402 | EM28XX_I2C_FREQ_100_KHZ, | ||
1403 | .xclk = EM28XX_XCLK_FREQUENCY_10MHZ, | ||
1404 | .name = "EM2874 Leadership ISDBT", | ||
1405 | .tuner_type = TUNER_ABSENT, | ||
1406 | .tuner_gpio = leadership_reset, | ||
1407 | .dvb_gpio = leadership_digital, | ||
1408 | .has_dvb = 1, | ||
1409 | }, | ||
1410 | |||
1411 | [EM2880_BOARD_MSI_DIGIVOX_AD] = { | ||
1412 | .name = "MSI DigiVox A/D", | ||
1413 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
1414 | .tuner_type = TUNER_XC2028, | ||
1415 | .tuner_gpio = default_tuner_gpio, | ||
1416 | .decoder = EM28XX_TVP5150, | ||
1417 | .input = { { | ||
1418 | .type = EM28XX_VMUX_TELEVISION, | ||
1419 | .vmux = TVP5150_COMPOSITE0, | ||
1420 | .amux = EM28XX_AMUX_VIDEO, | ||
1421 | .gpio = em2880_msi_digivox_ad_analog, | ||
1422 | }, { | ||
1423 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1424 | .vmux = TVP5150_COMPOSITE1, | ||
1425 | .amux = EM28XX_AMUX_LINE_IN, | ||
1426 | .gpio = em2880_msi_digivox_ad_analog, | ||
1427 | }, { | ||
1428 | .type = EM28XX_VMUX_SVIDEO, | ||
1429 | .vmux = TVP5150_SVIDEO, | ||
1430 | .amux = EM28XX_AMUX_LINE_IN, | ||
1431 | .gpio = em2880_msi_digivox_ad_analog, | ||
1432 | } }, | ||
1433 | }, | ||
1434 | [EM2880_BOARD_MSI_DIGIVOX_AD_II] = { | ||
1435 | .name = "MSI DigiVox A/D II", | ||
1436 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
1437 | .tuner_type = TUNER_XC2028, | ||
1438 | .tuner_gpio = default_tuner_gpio, | ||
1439 | .decoder = EM28XX_TVP5150, | ||
1440 | .input = { { | ||
1441 | .type = EM28XX_VMUX_TELEVISION, | ||
1442 | .vmux = TVP5150_COMPOSITE0, | ||
1443 | .amux = EM28XX_AMUX_VIDEO, | ||
1444 | .gpio = em2880_msi_digivox_ad_analog, | ||
1445 | }, { | ||
1446 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1447 | .vmux = TVP5150_COMPOSITE1, | ||
1448 | .amux = EM28XX_AMUX_LINE_IN, | ||
1449 | .gpio = em2880_msi_digivox_ad_analog, | ||
1450 | }, { | ||
1451 | .type = EM28XX_VMUX_SVIDEO, | ||
1452 | .vmux = TVP5150_SVIDEO, | ||
1453 | .amux = EM28XX_AMUX_LINE_IN, | ||
1454 | .gpio = em2880_msi_digivox_ad_analog, | ||
1455 | } }, | ||
1456 | }, | ||
1457 | [EM2880_BOARD_KWORLD_DVB_305U] = { | ||
1458 | .name = "KWorld DVB-T 305U", | ||
1459 | .tuner_type = TUNER_XC2028, | ||
1460 | .tuner_gpio = default_tuner_gpio, | ||
1461 | .decoder = EM28XX_TVP5150, | ||
1462 | .input = { { | ||
1463 | .type = EM28XX_VMUX_TELEVISION, | ||
1464 | .vmux = TVP5150_COMPOSITE0, | ||
1465 | .amux = EM28XX_AMUX_VIDEO, | ||
1466 | }, { | ||
1467 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1468 | .vmux = TVP5150_COMPOSITE1, | ||
1469 | .amux = EM28XX_AMUX_LINE_IN, | ||
1470 | }, { | ||
1471 | .type = EM28XX_VMUX_SVIDEO, | ||
1472 | .vmux = TVP5150_SVIDEO, | ||
1473 | .amux = EM28XX_AMUX_LINE_IN, | ||
1474 | } }, | ||
1475 | }, | ||
1476 | [EM2880_BOARD_KWORLD_DVB_310U] = { | ||
1477 | .name = "KWorld DVB-T 310U", | ||
1478 | .tuner_type = TUNER_XC2028, | ||
1479 | .tuner_gpio = default_tuner_gpio, | ||
1480 | .has_dvb = 1, | ||
1481 | .dvb_gpio = default_digital, | ||
1482 | .mts_firmware = 1, | ||
1483 | .decoder = EM28XX_TVP5150, | ||
1484 | .input = { { | ||
1485 | .type = EM28XX_VMUX_TELEVISION, | ||
1486 | .vmux = TVP5150_COMPOSITE0, | ||
1487 | .amux = EM28XX_AMUX_VIDEO, | ||
1488 | .gpio = default_analog, | ||
1489 | }, { | ||
1490 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1491 | .vmux = TVP5150_COMPOSITE1, | ||
1492 | .amux = EM28XX_AMUX_LINE_IN, | ||
1493 | .gpio = default_analog, | ||
1494 | }, { /* S-video has not been tested yet */ | ||
1495 | .type = EM28XX_VMUX_SVIDEO, | ||
1496 | .vmux = TVP5150_SVIDEO, | ||
1497 | .amux = EM28XX_AMUX_LINE_IN, | ||
1498 | .gpio = default_analog, | ||
1499 | } }, | ||
1500 | }, | ||
1501 | [EM2882_BOARD_KWORLD_ATSC_315U] = { | ||
1502 | .name = "KWorld ATSC 315U HDTV TV Box", | ||
1503 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
1504 | .tuner_type = TUNER_THOMSON_DTT761X, | ||
1505 | .tuner_gpio = em2882_kworld_315u_tuner_gpio, | ||
1506 | .tda9887_conf = TDA9887_PRESENT, | ||
1507 | .decoder = EM28XX_SAA711X, | ||
1508 | .has_dvb = 1, | ||
1509 | .dvb_gpio = em2882_kworld_315u_digital, | ||
1510 | .ir_codes = RC_MAP_KWORLD_315U, | ||
1511 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1512 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE, | ||
1513 | /* Analog mode - still not ready */ | ||
1514 | /*.input = { { | ||
1515 | .type = EM28XX_VMUX_TELEVISION, | ||
1516 | .vmux = SAA7115_COMPOSITE2, | ||
1517 | .amux = EM28XX_AMUX_VIDEO, | ||
1518 | .gpio = em2882_kworld_315u_analog, | ||
1519 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1520 | }, { | ||
1521 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1522 | .vmux = SAA7115_COMPOSITE0, | ||
1523 | .amux = EM28XX_AMUX_LINE_IN, | ||
1524 | .gpio = em2882_kworld_315u_analog1, | ||
1525 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1526 | }, { | ||
1527 | .type = EM28XX_VMUX_SVIDEO, | ||
1528 | .vmux = SAA7115_SVIDEO3, | ||
1529 | .amux = EM28XX_AMUX_LINE_IN, | ||
1530 | .gpio = em2882_kworld_315u_analog1, | ||
1531 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1532 | } }, */ | ||
1533 | }, | ||
1534 | [EM2880_BOARD_EMPIRE_DUAL_TV] = { | ||
1535 | .name = "Empire dual TV", | ||
1536 | .tuner_type = TUNER_XC2028, | ||
1537 | .tuner_gpio = default_tuner_gpio, | ||
1538 | .has_dvb = 1, | ||
1539 | .dvb_gpio = default_digital, | ||
1540 | .mts_firmware = 1, | ||
1541 | .decoder = EM28XX_TVP5150, | ||
1542 | .input = { { | ||
1543 | .type = EM28XX_VMUX_TELEVISION, | ||
1544 | .vmux = TVP5150_COMPOSITE0, | ||
1545 | .amux = EM28XX_AMUX_VIDEO, | ||
1546 | .gpio = default_analog, | ||
1547 | }, { | ||
1548 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1549 | .vmux = TVP5150_COMPOSITE1, | ||
1550 | .amux = EM28XX_AMUX_LINE_IN, | ||
1551 | .gpio = default_analog, | ||
1552 | }, { | ||
1553 | .type = EM28XX_VMUX_SVIDEO, | ||
1554 | .vmux = TVP5150_SVIDEO, | ||
1555 | .amux = EM28XX_AMUX_LINE_IN, | ||
1556 | .gpio = default_analog, | ||
1557 | } }, | ||
1558 | }, | ||
1559 | [EM2881_BOARD_DNT_DA2_HYBRID] = { | ||
1560 | .name = "DNT DA2 Hybrid", | ||
1561 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
1562 | .tuner_type = TUNER_XC2028, | ||
1563 | .tuner_gpio = default_tuner_gpio, | ||
1564 | .decoder = EM28XX_TVP5150, | ||
1565 | .input = { { | ||
1566 | .type = EM28XX_VMUX_TELEVISION, | ||
1567 | .vmux = TVP5150_COMPOSITE0, | ||
1568 | .amux = EM28XX_AMUX_VIDEO, | ||
1569 | .gpio = default_analog, | ||
1570 | }, { | ||
1571 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1572 | .vmux = TVP5150_COMPOSITE1, | ||
1573 | .amux = EM28XX_AMUX_LINE_IN, | ||
1574 | .gpio = default_analog, | ||
1575 | }, { | ||
1576 | .type = EM28XX_VMUX_SVIDEO, | ||
1577 | .vmux = TVP5150_SVIDEO, | ||
1578 | .amux = EM28XX_AMUX_LINE_IN, | ||
1579 | .gpio = default_analog, | ||
1580 | } }, | ||
1581 | }, | ||
1582 | [EM2881_BOARD_PINNACLE_HYBRID_PRO] = { | ||
1583 | .name = "Pinnacle Hybrid Pro", | ||
1584 | .tuner_type = TUNER_XC2028, | ||
1585 | .tuner_gpio = default_tuner_gpio, | ||
1586 | .decoder = EM28XX_TVP5150, | ||
1587 | .has_dvb = 1, | ||
1588 | .dvb_gpio = pinnacle_hybrid_pro_digital, | ||
1589 | .input = { { | ||
1590 | .type = EM28XX_VMUX_TELEVISION, | ||
1591 | .vmux = TVP5150_COMPOSITE0, | ||
1592 | .amux = EM28XX_AMUX_VIDEO, | ||
1593 | .gpio = pinnacle_hybrid_pro_analog, | ||
1594 | }, { | ||
1595 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1596 | .vmux = TVP5150_COMPOSITE1, | ||
1597 | .amux = EM28XX_AMUX_LINE_IN, | ||
1598 | .gpio = pinnacle_hybrid_pro_analog, | ||
1599 | }, { | ||
1600 | .type = EM28XX_VMUX_SVIDEO, | ||
1601 | .vmux = TVP5150_SVIDEO, | ||
1602 | .amux = EM28XX_AMUX_LINE_IN, | ||
1603 | .gpio = pinnacle_hybrid_pro_analog, | ||
1604 | } }, | ||
1605 | }, | ||
1606 | [EM2882_BOARD_PINNACLE_HYBRID_PRO_330E] = { | ||
1607 | .name = "Pinnacle Hybrid Pro (330e)", | ||
1608 | .tuner_type = TUNER_XC2028, | ||
1609 | .tuner_gpio = default_tuner_gpio, | ||
1610 | .mts_firmware = 1, | ||
1611 | .has_dvb = 1, | ||
1612 | .dvb_gpio = hauppauge_wintv_hvr_900R2_digital, | ||
1613 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | ||
1614 | .decoder = EM28XX_TVP5150, | ||
1615 | .input = { { | ||
1616 | .type = EM28XX_VMUX_TELEVISION, | ||
1617 | .vmux = TVP5150_COMPOSITE0, | ||
1618 | .amux = EM28XX_AMUX_VIDEO, | ||
1619 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1620 | }, { | ||
1621 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1622 | .vmux = TVP5150_COMPOSITE1, | ||
1623 | .amux = EM28XX_AMUX_LINE_IN, | ||
1624 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1625 | }, { | ||
1626 | .type = EM28XX_VMUX_SVIDEO, | ||
1627 | .vmux = TVP5150_SVIDEO, | ||
1628 | .amux = EM28XX_AMUX_LINE_IN, | ||
1629 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1630 | } }, | ||
1631 | }, | ||
1632 | [EM2882_BOARD_KWORLD_VS_DVBT] = { | ||
1633 | .name = "Kworld VS-DVB-T 323UR", | ||
1634 | .tuner_type = TUNER_XC2028, | ||
1635 | .tuner_gpio = default_tuner_gpio, | ||
1636 | .decoder = EM28XX_TVP5150, | ||
1637 | .mts_firmware = 1, | ||
1638 | .has_dvb = 1, | ||
1639 | .dvb_gpio = kworld_330u_digital, | ||
1640 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */ | ||
1641 | .ir_codes = RC_MAP_KWORLD_315U, | ||
1642 | .input = { { | ||
1643 | .type = EM28XX_VMUX_TELEVISION, | ||
1644 | .vmux = TVP5150_COMPOSITE0, | ||
1645 | .amux = EM28XX_AMUX_VIDEO, | ||
1646 | }, { | ||
1647 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1648 | .vmux = TVP5150_COMPOSITE1, | ||
1649 | .amux = EM28XX_AMUX_LINE_IN, | ||
1650 | }, { | ||
1651 | .type = EM28XX_VMUX_SVIDEO, | ||
1652 | .vmux = TVP5150_SVIDEO, | ||
1653 | .amux = EM28XX_AMUX_LINE_IN, | ||
1654 | } }, | ||
1655 | }, | ||
1656 | [EM2882_BOARD_TERRATEC_HYBRID_XS] = { | ||
1657 | .name = "Terratec Cinnergy Hybrid T USB XS (em2882)", | ||
1658 | .tuner_type = TUNER_XC2028, | ||
1659 | .tuner_gpio = default_tuner_gpio, | ||
1660 | .mts_firmware = 1, | ||
1661 | .decoder = EM28XX_TVP5150, | ||
1662 | .has_dvb = 1, | ||
1663 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
1664 | .ir_codes = RC_MAP_TERRATEC_CINERGY_XS, | ||
1665 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1666 | .input = { { | ||
1667 | .type = EM28XX_VMUX_TELEVISION, | ||
1668 | .vmux = TVP5150_COMPOSITE0, | ||
1669 | .amux = EM28XX_AMUX_VIDEO, | ||
1670 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1671 | }, { | ||
1672 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1673 | .vmux = TVP5150_COMPOSITE1, | ||
1674 | .amux = EM28XX_AMUX_LINE_IN, | ||
1675 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1676 | }, { | ||
1677 | .type = EM28XX_VMUX_SVIDEO, | ||
1678 | .vmux = TVP5150_SVIDEO, | ||
1679 | .amux = EM28XX_AMUX_LINE_IN, | ||
1680 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1681 | } }, | ||
1682 | }, | ||
1683 | [EM2882_BOARD_DIKOM_DK300] = { | ||
1684 | .name = "Dikom DK300", | ||
1685 | .tuner_type = TUNER_XC2028, | ||
1686 | .tuner_gpio = default_tuner_gpio, | ||
1687 | .decoder = EM28XX_TVP5150, | ||
1688 | .mts_firmware = 1, | ||
1689 | .has_dvb = 1, | ||
1690 | .dvb_gpio = dikom_dk300_digital, | ||
1691 | .input = { { | ||
1692 | .type = EM28XX_VMUX_TELEVISION, | ||
1693 | .vmux = TVP5150_COMPOSITE0, | ||
1694 | .amux = EM28XX_AMUX_VIDEO, | ||
1695 | .gpio = default_analog, | ||
1696 | } }, | ||
1697 | }, | ||
1698 | [EM2883_BOARD_KWORLD_HYBRID_330U] = { | ||
1699 | .name = "Kworld PlusTV HD Hybrid 330", | ||
1700 | .tuner_type = TUNER_XC2028, | ||
1701 | .tuner_gpio = default_tuner_gpio, | ||
1702 | .decoder = EM28XX_TVP5150, | ||
1703 | .mts_firmware = 1, | ||
1704 | .has_dvb = 1, | ||
1705 | .dvb_gpio = kworld_330u_digital, | ||
1706 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1707 | .i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | | ||
1708 | EM28XX_I2C_EEPROM_ON_BOARD | | ||
1709 | EM28XX_I2C_EEPROM_KEY_VALID, | ||
1710 | .input = { { | ||
1711 | .type = EM28XX_VMUX_TELEVISION, | ||
1712 | .vmux = TVP5150_COMPOSITE0, | ||
1713 | .amux = EM28XX_AMUX_VIDEO, | ||
1714 | .gpio = kworld_330u_analog, | ||
1715 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1716 | }, { | ||
1717 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1718 | .vmux = TVP5150_COMPOSITE1, | ||
1719 | .amux = EM28XX_AMUX_LINE_IN, | ||
1720 | .gpio = kworld_330u_analog, | ||
1721 | .aout = EM28XX_AOUT_PCM_IN | EM28XX_AOUT_PCM_STEREO, | ||
1722 | }, { | ||
1723 | .type = EM28XX_VMUX_SVIDEO, | ||
1724 | .vmux = TVP5150_SVIDEO, | ||
1725 | .amux = EM28XX_AMUX_LINE_IN, | ||
1726 | .gpio = kworld_330u_analog, | ||
1727 | } }, | ||
1728 | }, | ||
1729 | [EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = { | ||
1730 | .name = "Compro VideoMate ForYou/Stereo", | ||
1731 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | ||
1732 | .tvaudio_addr = 0xb0, | ||
1733 | .tda9887_conf = TDA9887_PRESENT, | ||
1734 | .decoder = EM28XX_TVP5150, | ||
1735 | .adecoder = EM28XX_TVAUDIO, | ||
1736 | .mute_gpio = compro_mute_gpio, | ||
1737 | .input = { { | ||
1738 | .type = EM28XX_VMUX_TELEVISION, | ||
1739 | .vmux = TVP5150_COMPOSITE0, | ||
1740 | .amux = EM28XX_AMUX_VIDEO, | ||
1741 | .gpio = compro_unmute_tv_gpio, | ||
1742 | }, { | ||
1743 | .type = EM28XX_VMUX_SVIDEO, | ||
1744 | .vmux = TVP5150_SVIDEO, | ||
1745 | .amux = EM28XX_AMUX_LINE_IN, | ||
1746 | .gpio = compro_unmute_svid_gpio, | ||
1747 | } }, | ||
1748 | }, | ||
1749 | [EM2860_BOARD_KAIOMY_TVNPC_U2] = { | ||
1750 | .name = "Kaiomy TVnPC U2", | ||
1751 | .vchannels = 3, | ||
1752 | .tuner_type = TUNER_XC2028, | ||
1753 | .tuner_addr = 0x61, | ||
1754 | .mts_firmware = 1, | ||
1755 | .decoder = EM28XX_TVP5150, | ||
1756 | .tuner_gpio = default_tuner_gpio, | ||
1757 | .ir_codes = RC_MAP_KAIOMY, | ||
1758 | .input = { { | ||
1759 | .type = EM28XX_VMUX_TELEVISION, | ||
1760 | .vmux = TVP5150_COMPOSITE0, | ||
1761 | .amux = EM28XX_AMUX_VIDEO, | ||
1762 | |||
1763 | }, { | ||
1764 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1765 | .vmux = TVP5150_COMPOSITE1, | ||
1766 | .amux = EM28XX_AMUX_LINE_IN, | ||
1767 | }, { | ||
1768 | .type = EM28XX_VMUX_SVIDEO, | ||
1769 | .vmux = TVP5150_SVIDEO, | ||
1770 | .amux = EM28XX_AMUX_LINE_IN, | ||
1771 | } }, | ||
1772 | .radio = { | ||
1773 | .type = EM28XX_RADIO, | ||
1774 | .amux = EM28XX_AMUX_LINE_IN, | ||
1775 | } | ||
1776 | }, | ||
1777 | [EM2860_BOARD_EASYCAP] = { | ||
1778 | .name = "Easy Cap Capture DC-60", | ||
1779 | .vchannels = 2, | ||
1780 | .tuner_type = TUNER_ABSENT, | ||
1781 | .decoder = EM28XX_SAA711X, | ||
1782 | .input = { { | ||
1783 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1784 | .vmux = SAA7115_COMPOSITE0, | ||
1785 | .amux = EM28XX_AMUX_LINE_IN, | ||
1786 | }, { | ||
1787 | .type = EM28XX_VMUX_SVIDEO, | ||
1788 | .vmux = SAA7115_SVIDEO3, | ||
1789 | .amux = EM28XX_AMUX_LINE_IN, | ||
1790 | } }, | ||
1791 | }, | ||
1792 | [EM2820_BOARD_IODATA_GVMVP_SZ] = { | ||
1793 | .name = "IO-DATA GV-MVP/SZ", | ||
1794 | .tuner_type = TUNER_PHILIPS_FM1236_MK3, | ||
1795 | .tuner_gpio = default_tuner_gpio, | ||
1796 | .tda9887_conf = TDA9887_PRESENT, | ||
1797 | .decoder = EM28XX_TVP5150, | ||
1798 | .input = { { | ||
1799 | .type = EM28XX_VMUX_TELEVISION, | ||
1800 | .vmux = TVP5150_COMPOSITE0, | ||
1801 | .amux = EM28XX_AMUX_VIDEO, | ||
1802 | }, { /* Composite has not been tested yet */ | ||
1803 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1804 | .vmux = TVP5150_COMPOSITE1, | ||
1805 | .amux = EM28XX_AMUX_VIDEO, | ||
1806 | }, { /* S-video has not been tested yet */ | ||
1807 | .type = EM28XX_VMUX_SVIDEO, | ||
1808 | .vmux = TVP5150_SVIDEO, | ||
1809 | .amux = EM28XX_AMUX_VIDEO, | ||
1810 | } }, | ||
1811 | }, | ||
1812 | [EM2860_BOARD_TERRATEC_GRABBY] = { | ||
1813 | .name = "Terratec Grabby", | ||
1814 | .vchannels = 2, | ||
1815 | .tuner_type = TUNER_ABSENT, | ||
1816 | .decoder = EM28XX_SAA711X, | ||
1817 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1818 | .input = { { | ||
1819 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1820 | .vmux = SAA7115_COMPOSITE0, | ||
1821 | .amux = EM28XX_AMUX_LINE_IN, | ||
1822 | }, { | ||
1823 | .type = EM28XX_VMUX_SVIDEO, | ||
1824 | .vmux = SAA7115_SVIDEO3, | ||
1825 | .amux = EM28XX_AMUX_LINE_IN, | ||
1826 | } }, | ||
1827 | }, | ||
1828 | [EM2860_BOARD_TERRATEC_AV350] = { | ||
1829 | .name = "Terratec AV350", | ||
1830 | .vchannels = 2, | ||
1831 | .tuner_type = TUNER_ABSENT, | ||
1832 | .decoder = EM28XX_TVP5150, | ||
1833 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, | ||
1834 | .mute_gpio = terratec_av350_mute_gpio, | ||
1835 | .input = { { | ||
1836 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1837 | .vmux = TVP5150_COMPOSITE1, | ||
1838 | .amux = EM28XX_AUDIO_SRC_LINE, | ||
1839 | .gpio = terratec_av350_unmute_gpio, | ||
1840 | |||
1841 | }, { | ||
1842 | .type = EM28XX_VMUX_SVIDEO, | ||
1843 | .vmux = TVP5150_SVIDEO, | ||
1844 | .amux = EM28XX_AUDIO_SRC_LINE, | ||
1845 | .gpio = terratec_av350_unmute_gpio, | ||
1846 | } }, | ||
1847 | }, | ||
1848 | |||
1849 | [EM2860_BOARD_ELGATO_VIDEO_CAPTURE] = { | ||
1850 | .name = "Elgato Video Capture", | ||
1851 | .decoder = EM28XX_SAA711X, | ||
1852 | .tuner_type = TUNER_ABSENT, /* Capture only device */ | ||
1853 | .input = { { | ||
1854 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1855 | .vmux = SAA7115_COMPOSITE0, | ||
1856 | .amux = EM28XX_AMUX_LINE_IN, | ||
1857 | }, { | ||
1858 | .type = EM28XX_VMUX_SVIDEO, | ||
1859 | .vmux = SAA7115_SVIDEO3, | ||
1860 | .amux = EM28XX_AMUX_LINE_IN, | ||
1861 | } }, | ||
1862 | }, | ||
1863 | |||
1864 | [EM2882_BOARD_EVGA_INDTUBE] = { | ||
1865 | .name = "Evga inDtube", | ||
1866 | .tuner_type = TUNER_XC2028, | ||
1867 | .tuner_gpio = default_tuner_gpio, | ||
1868 | .decoder = EM28XX_TVP5150, | ||
1869 | .xclk = EM28XX_XCLK_FREQUENCY_12MHZ, /* NEC IR */ | ||
1870 | .mts_firmware = 1, | ||
1871 | .has_dvb = 1, | ||
1872 | .dvb_gpio = evga_indtube_digital, | ||
1873 | .ir_codes = RC_MAP_EVGA_INDTUBE, | ||
1874 | .input = { { | ||
1875 | .type = EM28XX_VMUX_TELEVISION, | ||
1876 | .vmux = TVP5150_COMPOSITE0, | ||
1877 | .amux = EM28XX_AMUX_VIDEO, | ||
1878 | .gpio = evga_indtube_analog, | ||
1879 | }, { | ||
1880 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1881 | .vmux = TVP5150_COMPOSITE1, | ||
1882 | .amux = EM28XX_AMUX_LINE_IN, | ||
1883 | .gpio = evga_indtube_analog, | ||
1884 | }, { | ||
1885 | .type = EM28XX_VMUX_SVIDEO, | ||
1886 | .vmux = TVP5150_SVIDEO, | ||
1887 | .amux = EM28XX_AMUX_LINE_IN, | ||
1888 | .gpio = evga_indtube_analog, | ||
1889 | } }, | ||
1890 | }, | ||
1891 | /* eb1a:2868 Empia EM2870 + Philips CU1216L NIM (Philips TDA10023 + | ||
1892 | Infineon TUA6034) */ | ||
1893 | [EM2870_BOARD_REDDO_DVB_C_USB_BOX] = { | ||
1894 | .name = "Reddo DVB-C USB TV Box", | ||
1895 | .tuner_type = TUNER_ABSENT, | ||
1896 | .tuner_gpio = reddo_dvb_c_usb_box, | ||
1897 | .has_dvb = 1, | ||
1898 | }, | ||
1899 | /* 1b80:a340 - Empia EM2870, NXP TDA18271HD and LG DT3304, sold | ||
1900 | * initially as the KWorld PlusTV 340U, then as the UB435-Q. | ||
1901 | * Early variants have a TDA18271HD/C1, later ones a TDA18271HD/C2 */ | ||
1902 | [EM2870_BOARD_KWORLD_A340] = { | ||
1903 | .name = "KWorld PlusTV 340U or UB435-Q (ATSC)", | ||
1904 | .tuner_type = TUNER_ABSENT, /* Digital-only TDA18271HD */ | ||
1905 | .has_dvb = 1, | ||
1906 | .dvb_gpio = kworld_a340_digital, | ||
1907 | .tuner_gpio = default_tuner_gpio, | ||
1908 | }, | ||
1909 | /* 2013:024f PCTV nanoStick T2 290e. | ||
1910 | * Empia EM28174, Sony CXD2820R and NXP TDA18271HD/C2 */ | ||
1911 | [EM28174_BOARD_PCTV_290E] = { | ||
1912 | .name = "PCTV nanoStick T2 290e", | ||
1913 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
1914 | EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_100_KHZ, | ||
1915 | .tuner_type = TUNER_ABSENT, | ||
1916 | .tuner_gpio = pctv_290e, | ||
1917 | .has_dvb = 1, | ||
1918 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | ||
1919 | }, | ||
1920 | /* 2013:024f PCTV DVB-S2 Stick 460e | ||
1921 | * Empia EM28174, NXP TDA10071, Conexant CX24118A and Allegro A8293 */ | ||
1922 | [EM28174_BOARD_PCTV_460E] = { | ||
1923 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
1924 | EM28XX_I2C_CLK_WAIT_ENABLE | EM28XX_I2C_FREQ_400_KHZ, | ||
1925 | .name = "PCTV DVB-S2 Stick (460e)", | ||
1926 | .tuner_type = TUNER_ABSENT, | ||
1927 | .tuner_gpio = pctv_460e, | ||
1928 | .has_dvb = 1, | ||
1929 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | ||
1930 | }, | ||
1931 | /* eb1a:5006 Honestech VIDBOX NW03 | ||
1932 | * Empia EM2860, Philips SAA7113, Empia EMP202, No Tuner */ | ||
1933 | [EM2860_BOARD_HT_VIDBOX_NW03] = { | ||
1934 | .name = "Honestech Vidbox NW03", | ||
1935 | .tuner_type = TUNER_ABSENT, | ||
1936 | .decoder = EM28XX_SAA711X, | ||
1937 | .input = { { | ||
1938 | .type = EM28XX_VMUX_COMPOSITE1, | ||
1939 | .vmux = SAA7115_COMPOSITE0, | ||
1940 | .amux = EM28XX_AMUX_LINE_IN, | ||
1941 | }, { | ||
1942 | .type = EM28XX_VMUX_SVIDEO, | ||
1943 | .vmux = SAA7115_SVIDEO3, /* S-VIDEO needs confirming */ | ||
1944 | .amux = EM28XX_AMUX_LINE_IN, | ||
1945 | } }, | ||
1946 | }, | ||
1947 | /* 1b80:e425 MaxMedia UB425-TC | ||
1948 | * Empia EM2874B + Micronas DRX 3913KA2 + NXP TDA18271HDC2 */ | ||
1949 | [EM2874_BOARD_MAXMEDIA_UB425_TC] = { | ||
1950 | .name = "MaxMedia UB425-TC", | ||
1951 | .tuner_type = TUNER_ABSENT, | ||
1952 | .tuner_gpio = maxmedia_ub425_tc, | ||
1953 | .has_dvb = 1, | ||
1954 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
1955 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
1956 | EM28XX_I2C_FREQ_400_KHZ, | ||
1957 | }, | ||
1958 | /* 2304:0242 PCTV QuatroStick (510e) | ||
1959 | * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 */ | ||
1960 | [EM2884_BOARD_PCTV_510E] = { | ||
1961 | .name = "PCTV QuatroStick (510e)", | ||
1962 | .tuner_type = TUNER_ABSENT, | ||
1963 | .tuner_gpio = pctv_510e, | ||
1964 | .has_dvb = 1, | ||
1965 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | ||
1966 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
1967 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
1968 | EM28XX_I2C_FREQ_400_KHZ, | ||
1969 | }, | ||
1970 | /* 2013:0251 PCTV QuatroStick nano (520e) | ||
1971 | * Empia EM2884 + Micronas DRX 3926K + NXP TDA18271HDC2 */ | ||
1972 | [EM2884_BOARD_PCTV_520E] = { | ||
1973 | .name = "PCTV QuatroStick nano (520e)", | ||
1974 | .tuner_type = TUNER_ABSENT, | ||
1975 | .tuner_gpio = pctv_520e, | ||
1976 | .has_dvb = 1, | ||
1977 | .ir_codes = RC_MAP_PINNACLE_PCTV_HD, | ||
1978 | .i2c_speed = EM2874_I2C_SECONDARY_BUS_SELECT | | ||
1979 | EM28XX_I2C_CLK_WAIT_ENABLE | | ||
1980 | EM28XX_I2C_FREQ_400_KHZ, | ||
1981 | }, | ||
1982 | }; | ||
1983 | const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); | ||
1984 | |||
1985 | /* table of devices that work with this driver */ | ||
1986 | struct usb_device_id em28xx_id_table[] = { | ||
1987 | { USB_DEVICE(0xeb1a, 0x2750), | ||
1988 | .driver_info = EM2750_BOARD_UNKNOWN }, | ||
1989 | { USB_DEVICE(0xeb1a, 0x2751), | ||
1990 | .driver_info = EM2750_BOARD_UNKNOWN }, | ||
1991 | { USB_DEVICE(0xeb1a, 0x2800), | ||
1992 | .driver_info = EM2800_BOARD_UNKNOWN }, | ||
1993 | { USB_DEVICE(0xeb1a, 0x2710), | ||
1994 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
1995 | { USB_DEVICE(0xeb1a, 0x2820), | ||
1996 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
1997 | { USB_DEVICE(0xeb1a, 0x2821), | ||
1998 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
1999 | { USB_DEVICE(0xeb1a, 0x2860), | ||
2000 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2001 | { USB_DEVICE(0xeb1a, 0x2861), | ||
2002 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2003 | { USB_DEVICE(0xeb1a, 0x2862), | ||
2004 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2005 | { USB_DEVICE(0xeb1a, 0x2863), | ||
2006 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2007 | { USB_DEVICE(0xeb1a, 0x2870), | ||
2008 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2009 | { USB_DEVICE(0xeb1a, 0x2881), | ||
2010 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2011 | { USB_DEVICE(0xeb1a, 0x2883), | ||
2012 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2013 | { USB_DEVICE(0xeb1a, 0x2868), | ||
2014 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2015 | { USB_DEVICE(0xeb1a, 0x2875), | ||
2016 | .driver_info = EM2820_BOARD_UNKNOWN }, | ||
2017 | { USB_DEVICE(0xeb1a, 0xe300), | ||
2018 | .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U }, | ||
2019 | { USB_DEVICE(0xeb1a, 0xe303), | ||
2020 | .driver_info = EM2860_BOARD_KAIOMY_TVNPC_U2 }, | ||
2021 | { USB_DEVICE(0xeb1a, 0xe305), | ||
2022 | .driver_info = EM2880_BOARD_KWORLD_DVB_305U }, | ||
2023 | { USB_DEVICE(0xeb1a, 0xe310), | ||
2024 | .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD }, | ||
2025 | { USB_DEVICE(0xeb1a, 0xa313), | ||
2026 | .driver_info = EM2882_BOARD_KWORLD_ATSC_315U }, | ||
2027 | { USB_DEVICE(0xeb1a, 0xa316), | ||
2028 | .driver_info = EM2883_BOARD_KWORLD_HYBRID_330U }, | ||
2029 | { USB_DEVICE(0xeb1a, 0xe320), | ||
2030 | .driver_info = EM2880_BOARD_MSI_DIGIVOX_AD_II }, | ||
2031 | { USB_DEVICE(0xeb1a, 0xe323), | ||
2032 | .driver_info = EM2882_BOARD_KWORLD_VS_DVBT }, | ||
2033 | { USB_DEVICE(0xeb1a, 0xe350), | ||
2034 | .driver_info = EM2870_BOARD_KWORLD_350U }, | ||
2035 | { USB_DEVICE(0xeb1a, 0xe355), | ||
2036 | .driver_info = EM2870_BOARD_KWORLD_355U }, | ||
2037 | { USB_DEVICE(0xeb1a, 0x2801), | ||
2038 | .driver_info = EM2800_BOARD_GRABBEEX_USB2800 }, | ||
2039 | { USB_DEVICE(0xeb1a, 0xe357), | ||
2040 | .driver_info = EM2870_BOARD_KWORLD_355U }, | ||
2041 | { USB_DEVICE(0xeb1a, 0xe359), | ||
2042 | .driver_info = EM2870_BOARD_KWORLD_355U }, | ||
2043 | { USB_DEVICE(0x1b80, 0xe302), | ||
2044 | .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kaiser Baas Video to DVD maker */ | ||
2045 | { USB_DEVICE(0x1b80, 0xe304), | ||
2046 | .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, /* Kworld DVD Maker 2 */ | ||
2047 | { USB_DEVICE(0x0ccd, 0x0036), | ||
2048 | .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 }, | ||
2049 | { USB_DEVICE(0x0ccd, 0x004c), | ||
2050 | .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS_FR }, | ||
2051 | { USB_DEVICE(0x0ccd, 0x004f), | ||
2052 | .driver_info = EM2860_BOARD_TERRATEC_HYBRID_XS }, | ||
2053 | { USB_DEVICE(0x0ccd, 0x005e), | ||
2054 | .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS }, | ||
2055 | { USB_DEVICE(0x0ccd, 0x0042), | ||
2056 | .driver_info = EM2882_BOARD_TERRATEC_HYBRID_XS }, | ||
2057 | { USB_DEVICE(0x0ccd, 0x0043), | ||
2058 | .driver_info = EM2870_BOARD_TERRATEC_XS }, | ||
2059 | { USB_DEVICE(0x0ccd, 0x008e), /* Cinergy HTC USB XS Rev. 1 */ | ||
2060 | .driver_info = EM2884_BOARD_TERRATEC_H5 }, | ||
2061 | { USB_DEVICE(0x0ccd, 0x00ac), /* Cinergy HTC USB XS Rev. 2 */ | ||
2062 | .driver_info = EM2884_BOARD_TERRATEC_H5 }, | ||
2063 | { USB_DEVICE(0x0ccd, 0x10a2), /* H5 Rev. 1 */ | ||
2064 | .driver_info = EM2884_BOARD_TERRATEC_H5 }, | ||
2065 | { USB_DEVICE(0x0ccd, 0x10ad), /* H5 Rev. 2 */ | ||
2066 | .driver_info = EM2884_BOARD_TERRATEC_H5 }, | ||
2067 | { USB_DEVICE(0x0ccd, 0x0084), | ||
2068 | .driver_info = EM2860_BOARD_TERRATEC_AV350 }, | ||
2069 | { USB_DEVICE(0x0ccd, 0x0096), | ||
2070 | .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, | ||
2071 | { USB_DEVICE(0x0ccd, 0x10AF), | ||
2072 | .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, | ||
2073 | { USB_DEVICE(0x0ccd, 0x00b2), | ||
2074 | .driver_info = EM2884_BOARD_CINERGY_HTC_STICK }, | ||
2075 | { USB_DEVICE(0x0fd9, 0x0033), | ||
2076 | .driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE}, | ||
2077 | { USB_DEVICE(0x185b, 0x2870), | ||
2078 | .driver_info = EM2870_BOARD_COMPRO_VIDEOMATE }, | ||
2079 | { USB_DEVICE(0x185b, 0x2041), | ||
2080 | .driver_info = EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU }, | ||
2081 | { USB_DEVICE(0x2040, 0x4200), | ||
2082 | .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, | ||
2083 | { USB_DEVICE(0x2040, 0x4201), | ||
2084 | .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, | ||
2085 | { USB_DEVICE(0x2040, 0x6500), | ||
2086 | .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 }, | ||
2087 | { USB_DEVICE(0x2040, 0x6502), | ||
2088 | .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 }, | ||
2089 | { USB_DEVICE(0x2040, 0x6513), /* HCW HVR-980 */ | ||
2090 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, | ||
2091 | { USB_DEVICE(0x2040, 0x6517), /* HP HVR-950 */ | ||
2092 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, | ||
2093 | { USB_DEVICE(0x2040, 0x651b), /* RP HVR-950 */ | ||
2094 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, | ||
2095 | { USB_DEVICE(0x2040, 0x651f), | ||
2096 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 }, | ||
2097 | { USB_DEVICE(0x0438, 0xb002), | ||
2098 | .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, | ||
2099 | { USB_DEVICE(0x2001, 0xf112), | ||
2100 | .driver_info = EM2820_BOARD_DLINK_USB_TV }, | ||
2101 | { USB_DEVICE(0x2304, 0x0207), | ||
2102 | .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, | ||
2103 | { USB_DEVICE(0x2304, 0x0208), | ||
2104 | .driver_info = EM2820_BOARD_PINNACLE_USB_2 }, | ||
2105 | { USB_DEVICE(0x2304, 0x021a), | ||
2106 | .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, | ||
2107 | { USB_DEVICE(0x2304, 0x0226), | ||
2108 | .driver_info = EM2882_BOARD_PINNACLE_HYBRID_PRO_330E }, | ||
2109 | { USB_DEVICE(0x2304, 0x0227), | ||
2110 | .driver_info = EM2880_BOARD_PINNACLE_PCTV_HD_PRO }, | ||
2111 | { USB_DEVICE(0x0413, 0x6023), | ||
2112 | .driver_info = EM2800_BOARD_LEADTEK_WINFAST_USBII }, | ||
2113 | { USB_DEVICE(0x093b, 0xa003), | ||
2114 | .driver_info = EM2820_BOARD_PINNACLE_DVC_90 }, | ||
2115 | { USB_DEVICE(0x093b, 0xa005), | ||
2116 | .driver_info = EM2861_BOARD_PLEXTOR_PX_TV100U }, | ||
2117 | { USB_DEVICE(0x04bb, 0x0515), | ||
2118 | .driver_info = EM2820_BOARD_IODATA_GVMVP_SZ }, | ||
2119 | { USB_DEVICE(0xeb1a, 0x50a6), | ||
2120 | .driver_info = EM2860_BOARD_GADMEI_UTV330 }, | ||
2121 | { USB_DEVICE(0x1b80, 0xa340), | ||
2122 | .driver_info = EM2870_BOARD_KWORLD_A340 }, | ||
2123 | { USB_DEVICE(0x2013, 0x024f), | ||
2124 | .driver_info = EM28174_BOARD_PCTV_290E }, | ||
2125 | { USB_DEVICE(0x2013, 0x024c), | ||
2126 | .driver_info = EM28174_BOARD_PCTV_460E }, | ||
2127 | { USB_DEVICE(0x2040, 0x1605), | ||
2128 | .driver_info = EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C }, | ||
2129 | { USB_DEVICE(0xeb1a, 0x5006), | ||
2130 | .driver_info = EM2860_BOARD_HT_VIDBOX_NW03 }, | ||
2131 | { USB_DEVICE(0x1b80, 0xe309), /* Sveon STV40 */ | ||
2132 | .driver_info = EM2860_BOARD_EASYCAP }, | ||
2133 | { USB_DEVICE(0x1b80, 0xe425), | ||
2134 | .driver_info = EM2874_BOARD_MAXMEDIA_UB425_TC }, | ||
2135 | { USB_DEVICE(0x2304, 0x0242), | ||
2136 | .driver_info = EM2884_BOARD_PCTV_510E }, | ||
2137 | { USB_DEVICE(0x2013, 0x0251), | ||
2138 | .driver_info = EM2884_BOARD_PCTV_520E }, | ||
2139 | { }, | ||
2140 | }; | ||
2141 | MODULE_DEVICE_TABLE(usb, em28xx_id_table); | ||
2142 | |||
2143 | /* | ||
2144 | * EEPROM hash table for devices with generic USB IDs | ||
2145 | */ | ||
2146 | static struct em28xx_hash_table em28xx_eeprom_hash[] = { | ||
2147 | /* P/N: SA 60002070465 Tuner: TVF7533-MF */ | ||
2148 | {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, | ||
2149 | {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF}, | ||
2150 | {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, | ||
2151 | {0x166a0441, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028}, | ||
2152 | {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028}, | ||
2153 | {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028}, | ||
2154 | {0x63f653bd, EM2870_BOARD_REDDO_DVB_C_USB_BOX, TUNER_ABSENT}, | ||
2155 | {0x4e913442, EM2882_BOARD_DIKOM_DK300, TUNER_XC2028}, | ||
2156 | }; | ||
2157 | |||
2158 | /* I2C devicelist hash table for devices with generic USB IDs */ | ||
2159 | static struct em28xx_hash_table em28xx_i2c_hash[] = { | ||
2160 | {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC}, | ||
2161 | {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC}, | ||
2162 | {0x1ba50080, EM2860_BOARD_SAA711X_REFERENCE_DESIGN, TUNER_ABSENT}, | ||
2163 | {0x77800080, EM2860_BOARD_TVP5150_REFERENCE_DESIGN, TUNER_ABSENT}, | ||
2164 | {0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC}, | ||
2165 | {0x4ba50080, EM2861_BOARD_GADMEI_UTV330PLUS, TUNER_TNF_5335MF}, | ||
2166 | {0x6b800080, EM2874_BOARD_LEADERSHIP_ISDBT, TUNER_ABSENT}, | ||
2167 | }; | ||
2168 | |||
2169 | /* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */ | ||
2170 | static unsigned short saa711x_addrs[] = { | ||
2171 | 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */ | ||
2172 | 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */ | ||
2173 | I2C_CLIENT_END }; | ||
2174 | |||
2175 | static unsigned short tvp5150_addrs[] = { | ||
2176 | 0xb8 >> 1, | ||
2177 | 0xba >> 1, | ||
2178 | I2C_CLIENT_END | ||
2179 | }; | ||
2180 | |||
2181 | static unsigned short msp3400_addrs[] = { | ||
2182 | 0x80 >> 1, | ||
2183 | 0x88 >> 1, | ||
2184 | I2C_CLIENT_END | ||
2185 | }; | ||
2186 | |||
2187 | int em28xx_tuner_callback(void *ptr, int component, int command, int arg) | ||
2188 | { | ||
2189 | int rc = 0; | ||
2190 | struct em28xx *dev = ptr; | ||
2191 | |||
2192 | if (dev->tuner_type != TUNER_XC2028 && dev->tuner_type != TUNER_XC5000) | ||
2193 | return 0; | ||
2194 | |||
2195 | if (command != XC2028_TUNER_RESET && command != XC5000_TUNER_RESET) | ||
2196 | return 0; | ||
2197 | |||
2198 | rc = em28xx_gpio_set(dev, dev->board.tuner_gpio); | ||
2199 | |||
2200 | return rc; | ||
2201 | } | ||
2202 | EXPORT_SYMBOL_GPL(em28xx_tuner_callback); | ||
2203 | |||
2204 | static inline void em28xx_set_model(struct em28xx *dev) | ||
2205 | { | ||
2206 | memcpy(&dev->board, &em28xx_boards[dev->model], sizeof(dev->board)); | ||
2207 | |||
2208 | /* Those are the default values for the majority of boards | ||
2209 | Use those values if not specified otherwise at boards entry | ||
2210 | */ | ||
2211 | if (!dev->board.xclk) | ||
2212 | dev->board.xclk = EM28XX_XCLK_IR_RC5_MODE | | ||
2213 | EM28XX_XCLK_FREQUENCY_12MHZ; | ||
2214 | |||
2215 | if (!dev->board.i2c_speed) | ||
2216 | dev->board.i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | | ||
2217 | EM28XX_I2C_FREQ_100_KHZ; | ||
2218 | } | ||
2219 | |||
2220 | |||
2221 | /* FIXME: Should be replaced by a proper mt9m111 driver */ | ||
2222 | static int em28xx_initialize_mt9m111(struct em28xx *dev) | ||
2223 | { | ||
2224 | int i; | ||
2225 | unsigned char regs[][3] = { | ||
2226 | { 0x0d, 0x00, 0x01, }, /* reset and use defaults */ | ||
2227 | { 0x0d, 0x00, 0x00, }, | ||
2228 | { 0x0a, 0x00, 0x21, }, | ||
2229 | { 0x21, 0x04, 0x00, }, /* full readout speed, no row/col skipping */ | ||
2230 | }; | ||
2231 | |||
2232 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
2233 | i2c_master_send(&dev->i2c_client, ®s[i][0], 3); | ||
2234 | |||
2235 | return 0; | ||
2236 | } | ||
2237 | |||
2238 | |||
2239 | /* FIXME: Should be replaced by a proper mt9m001 driver */ | ||
2240 | static int em28xx_initialize_mt9m001(struct em28xx *dev) | ||
2241 | { | ||
2242 | int i; | ||
2243 | unsigned char regs[][3] = { | ||
2244 | { 0x0d, 0x00, 0x01, }, | ||
2245 | { 0x0d, 0x00, 0x00, }, | ||
2246 | { 0x04, 0x05, 0x00, }, /* hres = 1280 */ | ||
2247 | { 0x03, 0x04, 0x00, }, /* vres = 1024 */ | ||
2248 | { 0x20, 0x11, 0x00, }, | ||
2249 | { 0x06, 0x00, 0x10, }, | ||
2250 | { 0x2b, 0x00, 0x24, }, | ||
2251 | { 0x2e, 0x00, 0x24, }, | ||
2252 | { 0x35, 0x00, 0x24, }, | ||
2253 | { 0x2d, 0x00, 0x20, }, | ||
2254 | { 0x2c, 0x00, 0x20, }, | ||
2255 | { 0x09, 0x0a, 0xd4, }, | ||
2256 | { 0x35, 0x00, 0x57, }, | ||
2257 | }; | ||
2258 | |||
2259 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
2260 | i2c_master_send(&dev->i2c_client, ®s[i][0], 3); | ||
2261 | |||
2262 | return 0; | ||
2263 | } | ||
2264 | |||
2265 | /* HINT method: webcam I2C chips | ||
2266 | * | ||
2267 | * This method works for webcams with Micron sensors | ||
2268 | */ | ||
2269 | static int em28xx_hint_sensor(struct em28xx *dev) | ||
2270 | { | ||
2271 | int rc; | ||
2272 | char *sensor_name; | ||
2273 | unsigned char cmd; | ||
2274 | __be16 version_be; | ||
2275 | u16 version; | ||
2276 | |||
2277 | /* Micron sensor detection */ | ||
2278 | dev->i2c_client.addr = 0xba >> 1; | ||
2279 | cmd = 0; | ||
2280 | i2c_master_send(&dev->i2c_client, &cmd, 1); | ||
2281 | rc = i2c_master_recv(&dev->i2c_client, (char *)&version_be, 2); | ||
2282 | if (rc != 2) | ||
2283 | return -EINVAL; | ||
2284 | |||
2285 | version = be16_to_cpu(version_be); | ||
2286 | switch (version) { | ||
2287 | case 0x8232: /* mt9v011 640x480 1.3 Mpix sensor */ | ||
2288 | case 0x8243: /* mt9v011 rev B 640x480 1.3 Mpix sensor */ | ||
2289 | dev->model = EM2820_BOARD_SILVERCREST_WEBCAM; | ||
2290 | em28xx_set_model(dev); | ||
2291 | |||
2292 | sensor_name = "mt9v011"; | ||
2293 | dev->em28xx_sensor = EM28XX_MT9V011; | ||
2294 | dev->sensor_xres = 640; | ||
2295 | dev->sensor_yres = 480; | ||
2296 | /* | ||
2297 | * FIXME: mt9v011 uses I2S speed as xtal clk - at least with | ||
2298 | * the Silvercrest cam I have here for testing - for higher | ||
2299 | * resolutions, a high clock cause horizontal artifacts, so we | ||
2300 | * need to use a lower xclk frequency. | ||
2301 | * Yet, it would be possible to adjust xclk depending on the | ||
2302 | * desired resolution, since this affects directly the | ||
2303 | * frame rate. | ||
2304 | */ | ||
2305 | dev->board.xclk = EM28XX_XCLK_FREQUENCY_4_3MHZ; | ||
2306 | dev->sensor_xtal = 4300000; | ||
2307 | |||
2308 | /* probably means GRGB 16 bit bayer */ | ||
2309 | dev->vinmode = 0x0d; | ||
2310 | dev->vinctl = 0x00; | ||
2311 | |||
2312 | break; | ||
2313 | |||
2314 | case 0x143a: /* MT9M111 as found in the ECS G200 */ | ||
2315 | dev->model = EM2750_BOARD_UNKNOWN; | ||
2316 | em28xx_set_model(dev); | ||
2317 | |||
2318 | sensor_name = "mt9m111"; | ||
2319 | dev->board.xclk = EM28XX_XCLK_FREQUENCY_48MHZ; | ||
2320 | dev->em28xx_sensor = EM28XX_MT9M111; | ||
2321 | em28xx_initialize_mt9m111(dev); | ||
2322 | dev->sensor_xres = 640; | ||
2323 | dev->sensor_yres = 512; | ||
2324 | |||
2325 | dev->vinmode = 0x0a; | ||
2326 | dev->vinctl = 0x00; | ||
2327 | |||
2328 | break; | ||
2329 | |||
2330 | case 0x8431: | ||
2331 | dev->model = EM2750_BOARD_UNKNOWN; | ||
2332 | em28xx_set_model(dev); | ||
2333 | |||
2334 | sensor_name = "mt9m001"; | ||
2335 | dev->em28xx_sensor = EM28XX_MT9M001; | ||
2336 | em28xx_initialize_mt9m001(dev); | ||
2337 | dev->sensor_xres = 1280; | ||
2338 | dev->sensor_yres = 1024; | ||
2339 | |||
2340 | /* probably means BGGR 16 bit bayer */ | ||
2341 | dev->vinmode = 0x0c; | ||
2342 | dev->vinctl = 0x00; | ||
2343 | |||
2344 | break; | ||
2345 | default: | ||
2346 | printk("Unknown Micron Sensor 0x%04x\n", version); | ||
2347 | return -EINVAL; | ||
2348 | } | ||
2349 | |||
2350 | /* Setup webcam defaults */ | ||
2351 | em28xx_pre_card_setup(dev); | ||
2352 | |||
2353 | em28xx_errdev("Sensor is %s, using model %s entry.\n", | ||
2354 | sensor_name, em28xx_boards[dev->model].name); | ||
2355 | |||
2356 | return 0; | ||
2357 | } | ||
2358 | |||
2359 | /* Since em28xx_pre_card_setup() requires a proper dev->model, | ||
2360 | * this won't work for boards with generic PCI IDs | ||
2361 | */ | ||
2362 | static void em28xx_pre_card_setup(struct em28xx *dev) | ||
2363 | { | ||
2364 | /* Set the initial XCLK and I2C clock values based on the board | ||
2365 | definition */ | ||
2366 | em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk & 0x7f); | ||
2367 | if (!dev->board.is_em2800) | ||
2368 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); | ||
2369 | msleep(50); | ||
2370 | |||
2371 | /* request some modules */ | ||
2372 | switch (dev->model) { | ||
2373 | case EM2861_BOARD_PLEXTOR_PX_TV100U: | ||
2374 | /* Sets the msp34xx I2S speed */ | ||
2375 | dev->i2s_speed = 2048000; | ||
2376 | break; | ||
2377 | case EM2861_BOARD_KWORLD_PVRTV_300U: | ||
2378 | case EM2880_BOARD_KWORLD_DVB_305U: | ||
2379 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x6d); | ||
2380 | msleep(10); | ||
2381 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x7d); | ||
2382 | msleep(10); | ||
2383 | break; | ||
2384 | case EM2870_BOARD_COMPRO_VIDEOMATE: | ||
2385 | /* TODO: someone can do some cleanup here... | ||
2386 | not everything's needed */ | ||
2387 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x00); | ||
2388 | msleep(10); | ||
2389 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x01); | ||
2390 | msleep(10); | ||
2391 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); | ||
2392 | mdelay(70); | ||
2393 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc); | ||
2394 | mdelay(70); | ||
2395 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xdc); | ||
2396 | mdelay(70); | ||
2397 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc); | ||
2398 | mdelay(70); | ||
2399 | break; | ||
2400 | case EM2870_BOARD_TERRATEC_XS_MT2060: | ||
2401 | /* this device needs some gpio writes to get the DVB-T | ||
2402 | demod work */ | ||
2403 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); | ||
2404 | mdelay(70); | ||
2405 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde); | ||
2406 | mdelay(70); | ||
2407 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); | ||
2408 | mdelay(70); | ||
2409 | break; | ||
2410 | case EM2870_BOARD_PINNACLE_PCTV_DVB: | ||
2411 | /* this device needs some gpio writes to get the | ||
2412 | DVB-T demod work */ | ||
2413 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); | ||
2414 | mdelay(70); | ||
2415 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde); | ||
2416 | mdelay(70); | ||
2417 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); | ||
2418 | mdelay(70); | ||
2419 | break; | ||
2420 | case EM2820_BOARD_GADMEI_UTV310: | ||
2421 | case EM2820_BOARD_MSI_VOX_USB_2: | ||
2422 | /* enables audio for that devices */ | ||
2423 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); | ||
2424 | break; | ||
2425 | |||
2426 | case EM2882_BOARD_KWORLD_ATSC_315U: | ||
2427 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff); | ||
2428 | msleep(10); | ||
2429 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); | ||
2430 | msleep(10); | ||
2431 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x00); | ||
2432 | msleep(10); | ||
2433 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x08); | ||
2434 | msleep(10); | ||
2435 | break; | ||
2436 | |||
2437 | case EM2860_BOARD_KAIOMY_TVNPC_U2: | ||
2438 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1); | ||
2439 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | ||
2440 | em28xx_write_regs(dev, 0x0d, "\x42", 1); | ||
2441 | em28xx_write_regs(dev, 0x08, "\xfd", 1); | ||
2442 | msleep(10); | ||
2443 | em28xx_write_regs(dev, 0x08, "\xff", 1); | ||
2444 | msleep(10); | ||
2445 | em28xx_write_regs(dev, 0x08, "\x7f", 1); | ||
2446 | msleep(10); | ||
2447 | em28xx_write_regs(dev, 0x08, "\x6b", 1); | ||
2448 | |||
2449 | break; | ||
2450 | case EM2860_BOARD_EASYCAP: | ||
2451 | em28xx_write_regs(dev, 0x08, "\xf8", 1); | ||
2452 | break; | ||
2453 | |||
2454 | case EM2820_BOARD_IODATA_GVMVP_SZ: | ||
2455 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff); | ||
2456 | msleep(70); | ||
2457 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7); | ||
2458 | msleep(10); | ||
2459 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); | ||
2460 | msleep(70); | ||
2461 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); | ||
2462 | msleep(70); | ||
2463 | break; | ||
2464 | } | ||
2465 | |||
2466 | em28xx_gpio_set(dev, dev->board.tuner_gpio); | ||
2467 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | ||
2468 | |||
2469 | /* Unlock device */ | ||
2470 | em28xx_set_mode(dev, EM28XX_SUSPEND); | ||
2471 | } | ||
2472 | |||
2473 | static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) | ||
2474 | { | ||
2475 | memset(ctl, 0, sizeof(*ctl)); | ||
2476 | |||
2477 | ctl->fname = XC2028_DEFAULT_FIRMWARE; | ||
2478 | ctl->max_len = 64; | ||
2479 | ctl->mts = em28xx_boards[dev->model].mts_firmware; | ||
2480 | |||
2481 | switch (dev->model) { | ||
2482 | case EM2880_BOARD_EMPIRE_DUAL_TV: | ||
2483 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
2484 | case EM2882_BOARD_TERRATEC_HYBRID_XS: | ||
2485 | ctl->demod = XC3028_FE_ZARLINK456; | ||
2486 | break; | ||
2487 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | ||
2488 | case EM2880_BOARD_TERRATEC_HYBRID_XS_FR: | ||
2489 | case EM2881_BOARD_PINNACLE_HYBRID_PRO: | ||
2490 | ctl->demod = XC3028_FE_ZARLINK456; | ||
2491 | break; | ||
2492 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: | ||
2493 | case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E: | ||
2494 | ctl->demod = XC3028_FE_DEFAULT; | ||
2495 | break; | ||
2496 | case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: | ||
2497 | ctl->demod = XC3028_FE_DEFAULT; | ||
2498 | ctl->fname = XC3028L_DEFAULT_FIRMWARE; | ||
2499 | break; | ||
2500 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: | ||
2501 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: | ||
2502 | case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: | ||
2503 | /* FIXME: Better to specify the needed IF */ | ||
2504 | ctl->demod = XC3028_FE_DEFAULT; | ||
2505 | break; | ||
2506 | case EM2883_BOARD_KWORLD_HYBRID_330U: | ||
2507 | case EM2882_BOARD_DIKOM_DK300: | ||
2508 | case EM2882_BOARD_KWORLD_VS_DVBT: | ||
2509 | ctl->demod = XC3028_FE_CHINA; | ||
2510 | ctl->fname = XC2028_DEFAULT_FIRMWARE; | ||
2511 | break; | ||
2512 | case EM2882_BOARD_EVGA_INDTUBE: | ||
2513 | ctl->demod = XC3028_FE_CHINA; | ||
2514 | ctl->fname = XC3028L_DEFAULT_FIRMWARE; | ||
2515 | break; | ||
2516 | default: | ||
2517 | ctl->demod = XC3028_FE_OREN538; | ||
2518 | } | ||
2519 | } | ||
2520 | |||
2521 | static void em28xx_tuner_setup(struct em28xx *dev) | ||
2522 | { | ||
2523 | struct tuner_setup tun_setup; | ||
2524 | struct v4l2_frequency f; | ||
2525 | |||
2526 | if (dev->tuner_type == TUNER_ABSENT) | ||
2527 | return; | ||
2528 | |||
2529 | memset(&tun_setup, 0, sizeof(tun_setup)); | ||
2530 | |||
2531 | tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; | ||
2532 | tun_setup.tuner_callback = em28xx_tuner_callback; | ||
2533 | |||
2534 | if (dev->board.radio.type) { | ||
2535 | tun_setup.type = dev->board.radio.type; | ||
2536 | tun_setup.addr = dev->board.radio_addr; | ||
2537 | |||
2538 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup); | ||
2539 | } | ||
2540 | |||
2541 | if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) { | ||
2542 | tun_setup.type = dev->tuner_type; | ||
2543 | tun_setup.addr = dev->tuner_addr; | ||
2544 | |||
2545 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup); | ||
2546 | } | ||
2547 | |||
2548 | if (dev->tda9887_conf) { | ||
2549 | struct v4l2_priv_tun_config tda9887_cfg; | ||
2550 | |||
2551 | tda9887_cfg.tuner = TUNER_TDA9887; | ||
2552 | tda9887_cfg.priv = &dev->tda9887_conf; | ||
2553 | |||
2554 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &tda9887_cfg); | ||
2555 | } | ||
2556 | |||
2557 | if (dev->tuner_type == TUNER_XC2028) { | ||
2558 | struct v4l2_priv_tun_config xc2028_cfg; | ||
2559 | struct xc2028_ctrl ctl; | ||
2560 | |||
2561 | memset(&xc2028_cfg, 0, sizeof(xc2028_cfg)); | ||
2562 | memset(&ctl, 0, sizeof(ctl)); | ||
2563 | |||
2564 | em28xx_setup_xc3028(dev, &ctl); | ||
2565 | |||
2566 | xc2028_cfg.tuner = TUNER_XC2028; | ||
2567 | xc2028_cfg.priv = &ctl; | ||
2568 | |||
2569 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &xc2028_cfg); | ||
2570 | } | ||
2571 | |||
2572 | /* configure tuner */ | ||
2573 | f.tuner = 0; | ||
2574 | f.type = V4L2_TUNER_ANALOG_TV; | ||
2575 | f.frequency = 9076; /* just a magic number */ | ||
2576 | dev->ctl_freq = f.frequency; | ||
2577 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); | ||
2578 | } | ||
2579 | |||
2580 | static int em28xx_hint_board(struct em28xx *dev) | ||
2581 | { | ||
2582 | int i; | ||
2583 | |||
2584 | /* HINT method: EEPROM | ||
2585 | * | ||
2586 | * This method works only for boards with eeprom. | ||
2587 | * Uses a hash of all eeprom bytes. The hash should be | ||
2588 | * unique for a vendor/tuner pair. | ||
2589 | * There are a high chance that tuners for different | ||
2590 | * video standards produce different hashes. | ||
2591 | */ | ||
2592 | for (i = 0; i < ARRAY_SIZE(em28xx_eeprom_hash); i++) { | ||
2593 | if (dev->hash == em28xx_eeprom_hash[i].hash) { | ||
2594 | dev->model = em28xx_eeprom_hash[i].model; | ||
2595 | dev->tuner_type = em28xx_eeprom_hash[i].tuner; | ||
2596 | |||
2597 | em28xx_errdev("Your board has no unique USB ID.\n"); | ||
2598 | em28xx_errdev("A hint were successfully done, " | ||
2599 | "based on eeprom hash.\n"); | ||
2600 | em28xx_errdev("This method is not 100%% failproof.\n"); | ||
2601 | em28xx_errdev("If the board were missdetected, " | ||
2602 | "please email this log to:\n"); | ||
2603 | em28xx_errdev("\tV4L Mailing List " | ||
2604 | " <linux-media@vger.kernel.org>\n"); | ||
2605 | em28xx_errdev("Board detected as %s\n", | ||
2606 | em28xx_boards[dev->model].name); | ||
2607 | |||
2608 | return 0; | ||
2609 | } | ||
2610 | } | ||
2611 | |||
2612 | /* HINT method: I2C attached devices | ||
2613 | * | ||
2614 | * This method works for all boards. | ||
2615 | * Uses a hash of i2c scanned devices. | ||
2616 | * Devices with the same i2c attached chips will | ||
2617 | * be considered equal. | ||
2618 | * This method is less precise than the eeprom one. | ||
2619 | */ | ||
2620 | |||
2621 | /* user did not request i2c scanning => do it now */ | ||
2622 | if (!dev->i2c_hash) | ||
2623 | em28xx_do_i2c_scan(dev); | ||
2624 | |||
2625 | for (i = 0; i < ARRAY_SIZE(em28xx_i2c_hash); i++) { | ||
2626 | if (dev->i2c_hash == em28xx_i2c_hash[i].hash) { | ||
2627 | dev->model = em28xx_i2c_hash[i].model; | ||
2628 | dev->tuner_type = em28xx_i2c_hash[i].tuner; | ||
2629 | em28xx_errdev("Your board has no unique USB ID.\n"); | ||
2630 | em28xx_errdev("A hint were successfully done, " | ||
2631 | "based on i2c devicelist hash.\n"); | ||
2632 | em28xx_errdev("This method is not 100%% failproof.\n"); | ||
2633 | em28xx_errdev("If the board were missdetected, " | ||
2634 | "please email this log to:\n"); | ||
2635 | em28xx_errdev("\tV4L Mailing List " | ||
2636 | " <linux-media@vger.kernel.org>\n"); | ||
2637 | em28xx_errdev("Board detected as %s\n", | ||
2638 | em28xx_boards[dev->model].name); | ||
2639 | |||
2640 | return 0; | ||
2641 | } | ||
2642 | } | ||
2643 | |||
2644 | em28xx_errdev("Your board has no unique USB ID and thus need a " | ||
2645 | "hint to be detected.\n"); | ||
2646 | em28xx_errdev("You may try to use card=<n> insmod option to " | ||
2647 | "workaround that.\n"); | ||
2648 | em28xx_errdev("Please send an email with this log to:\n"); | ||
2649 | em28xx_errdev("\tV4L Mailing List <linux-media@vger.kernel.org>\n"); | ||
2650 | em28xx_errdev("Board eeprom hash is 0x%08lx\n", dev->hash); | ||
2651 | em28xx_errdev("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash); | ||
2652 | |||
2653 | em28xx_errdev("Here is a list of valid choices for the card=<n>" | ||
2654 | " insmod option:\n"); | ||
2655 | for (i = 0; i < em28xx_bcount; i++) { | ||
2656 | em28xx_errdev(" card=%d -> %s\n", | ||
2657 | i, em28xx_boards[i].name); | ||
2658 | } | ||
2659 | return -1; | ||
2660 | } | ||
2661 | |||
2662 | static void em28xx_card_setup(struct em28xx *dev) | ||
2663 | { | ||
2664 | /* | ||
2665 | * If the device can be a webcam, seek for a sensor. | ||
2666 | * If sensor is not found, then it isn't a webcam. | ||
2667 | */ | ||
2668 | if (dev->board.is_webcam) { | ||
2669 | if (em28xx_hint_sensor(dev) < 0) | ||
2670 | dev->board.is_webcam = 0; | ||
2671 | else | ||
2672 | dev->progressive = 1; | ||
2673 | } | ||
2674 | |||
2675 | if (!dev->board.is_webcam) { | ||
2676 | switch (dev->model) { | ||
2677 | case EM2820_BOARD_UNKNOWN: | ||
2678 | case EM2800_BOARD_UNKNOWN: | ||
2679 | /* | ||
2680 | * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD. | ||
2681 | * | ||
2682 | * This occurs because they share identical USB vendor and | ||
2683 | * product IDs. | ||
2684 | * | ||
2685 | * What we do here is look up the EEPROM hash of the K-WORLD | ||
2686 | * and if it is found then we decide that we do not have | ||
2687 | * a DIGIVOX and reset the device to the K-WORLD instead. | ||
2688 | * | ||
2689 | * This solution is only valid if they do not share eeprom | ||
2690 | * hash identities which has not been determined as yet. | ||
2691 | */ | ||
2692 | if (em28xx_hint_board(dev) < 0) | ||
2693 | em28xx_errdev("Board not discovered\n"); | ||
2694 | else { | ||
2695 | em28xx_set_model(dev); | ||
2696 | em28xx_pre_card_setup(dev); | ||
2697 | } | ||
2698 | break; | ||
2699 | default: | ||
2700 | em28xx_set_model(dev); | ||
2701 | } | ||
2702 | } | ||
2703 | |||
2704 | em28xx_info("Identified as %s (card=%d)\n", | ||
2705 | dev->board.name, dev->model); | ||
2706 | |||
2707 | dev->tuner_type = em28xx_boards[dev->model].tuner_type; | ||
2708 | if (em28xx_boards[dev->model].tuner_addr) | ||
2709 | dev->tuner_addr = em28xx_boards[dev->model].tuner_addr; | ||
2710 | |||
2711 | if (em28xx_boards[dev->model].tda9887_conf) | ||
2712 | dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf; | ||
2713 | |||
2714 | /* request some modules */ | ||
2715 | switch (dev->model) { | ||
2716 | case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: | ||
2717 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
2718 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: | ||
2719 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: | ||
2720 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: | ||
2721 | { | ||
2722 | struct tveeprom tv; | ||
2723 | #if defined(CONFIG_MODULES) && defined(MODULE) | ||
2724 | request_module("tveeprom"); | ||
2725 | #endif | ||
2726 | /* Call first TVeeprom */ | ||
2727 | |||
2728 | dev->i2c_client.addr = 0xa0 >> 1; | ||
2729 | tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata); | ||
2730 | |||
2731 | dev->tuner_type = tv.tuner_type; | ||
2732 | |||
2733 | if (tv.audio_processor == V4L2_IDENT_MSPX4XX) { | ||
2734 | dev->i2s_speed = 2048000; | ||
2735 | dev->board.has_msp34xx = 1; | ||
2736 | } | ||
2737 | break; | ||
2738 | } | ||
2739 | case EM2882_BOARD_KWORLD_ATSC_315U: | ||
2740 | em28xx_write_reg(dev, 0x0d, 0x42); | ||
2741 | msleep(10); | ||
2742 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); | ||
2743 | msleep(10); | ||
2744 | break; | ||
2745 | case EM2820_BOARD_KWORLD_PVRTV2800RF: | ||
2746 | /* GPIO enables sound on KWORLD PVR TV 2800RF */ | ||
2747 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9); | ||
2748 | break; | ||
2749 | case EM2820_BOARD_UNKNOWN: | ||
2750 | case EM2800_BOARD_UNKNOWN: | ||
2751 | /* | ||
2752 | * The K-WORLD DVB-T 310U is detected as an MSI Digivox AD. | ||
2753 | * | ||
2754 | * This occurs because they share identical USB vendor and | ||
2755 | * product IDs. | ||
2756 | * | ||
2757 | * What we do here is look up the EEPROM hash of the K-WORLD | ||
2758 | * and if it is found then we decide that we do not have | ||
2759 | * a DIGIVOX and reset the device to the K-WORLD instead. | ||
2760 | * | ||
2761 | * This solution is only valid if they do not share eeprom | ||
2762 | * hash identities which has not been determined as yet. | ||
2763 | */ | ||
2764 | case EM2880_BOARD_MSI_DIGIVOX_AD: | ||
2765 | if (!em28xx_hint_board(dev)) | ||
2766 | em28xx_set_model(dev); | ||
2767 | |||
2768 | /* In cases where we had to use a board hint, the call to | ||
2769 | em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, | ||
2770 | so make the call now so the analog GPIOs are set properly | ||
2771 | before probing the i2c bus. */ | ||
2772 | em28xx_gpio_set(dev, dev->board.tuner_gpio); | ||
2773 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | ||
2774 | break; | ||
2775 | |||
2776 | /* | ||
2777 | * The Dikom DK300 is detected as an Kworld VS-DVB-T 323UR. | ||
2778 | * | ||
2779 | * This occurs because they share identical USB vendor and | ||
2780 | * product IDs. | ||
2781 | * | ||
2782 | * What we do here is look up the EEPROM hash of the Dikom | ||
2783 | * and if it is found then we decide that we do not have | ||
2784 | * a Kworld and reset the device to the Dikom instead. | ||
2785 | * | ||
2786 | * This solution is only valid if they do not share eeprom | ||
2787 | * hash identities which has not been determined as yet. | ||
2788 | */ | ||
2789 | case EM2882_BOARD_KWORLD_VS_DVBT: | ||
2790 | if (!em28xx_hint_board(dev)) | ||
2791 | em28xx_set_model(dev); | ||
2792 | |||
2793 | /* In cases where we had to use a board hint, the call to | ||
2794 | em28xx_set_mode() in em28xx_pre_card_setup() was a no-op, | ||
2795 | so make the call now so the analog GPIOs are set properly | ||
2796 | before probing the i2c bus. */ | ||
2797 | em28xx_gpio_set(dev, dev->board.tuner_gpio); | ||
2798 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | ||
2799 | break; | ||
2800 | } | ||
2801 | |||
2802 | if (dev->board.valid == EM28XX_BOARD_NOT_VALIDATED) { | ||
2803 | em28xx_errdev("\n\n"); | ||
2804 | em28xx_errdev("The support for this board weren't " | ||
2805 | "valid yet.\n"); | ||
2806 | em28xx_errdev("Please send a report of having this working\n"); | ||
2807 | em28xx_errdev("not to V4L mailing list (and/or to other " | ||
2808 | "addresses)\n\n"); | ||
2809 | } | ||
2810 | |||
2811 | /* Allow override tuner type by a module parameter */ | ||
2812 | if (tuner >= 0) | ||
2813 | dev->tuner_type = tuner; | ||
2814 | |||
2815 | /* request some modules */ | ||
2816 | if (dev->board.has_msp34xx) | ||
2817 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | ||
2818 | "msp3400", 0, msp3400_addrs); | ||
2819 | |||
2820 | if (dev->board.decoder == EM28XX_SAA711X) | ||
2821 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | ||
2822 | "saa7115_auto", 0, saa711x_addrs); | ||
2823 | |||
2824 | if (dev->board.decoder == EM28XX_TVP5150) | ||
2825 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | ||
2826 | "tvp5150", 0, tvp5150_addrs); | ||
2827 | |||
2828 | if (dev->em28xx_sensor == EM28XX_MT9V011) { | ||
2829 | struct mt9v011_platform_data pdata; | ||
2830 | struct i2c_board_info mt9v011_info = { | ||
2831 | .type = "mt9v011", | ||
2832 | .addr = 0xba >> 1, | ||
2833 | .platform_data = &pdata, | ||
2834 | }; | ||
2835 | |||
2836 | pdata.xtal = dev->sensor_xtal; | ||
2837 | v4l2_i2c_new_subdev_board(&dev->v4l2_dev, &dev->i2c_adap, | ||
2838 | &mt9v011_info, NULL); | ||
2839 | } | ||
2840 | |||
2841 | |||
2842 | if (dev->board.adecoder == EM28XX_TVAUDIO) | ||
2843 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | ||
2844 | "tvaudio", dev->board.tvaudio_addr, NULL); | ||
2845 | |||
2846 | if (dev->board.tuner_type != TUNER_ABSENT) { | ||
2847 | int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); | ||
2848 | |||
2849 | if (dev->board.radio.type) | ||
2850 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | ||
2851 | "tuner", dev->board.radio_addr, NULL); | ||
2852 | |||
2853 | if (has_demod) | ||
2854 | v4l2_i2c_new_subdev(&dev->v4l2_dev, | ||
2855 | &dev->i2c_adap, "tuner", | ||
2856 | 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); | ||
2857 | if (dev->tuner_addr == 0) { | ||
2858 | enum v4l2_i2c_tuner_type type = | ||
2859 | has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; | ||
2860 | struct v4l2_subdev *sd; | ||
2861 | |||
2862 | sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, | ||
2863 | &dev->i2c_adap, "tuner", | ||
2864 | 0, v4l2_i2c_tuner_addrs(type)); | ||
2865 | |||
2866 | if (sd) | ||
2867 | dev->tuner_addr = v4l2_i2c_subdev_addr(sd); | ||
2868 | } else { | ||
2869 | v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, | ||
2870 | "tuner", dev->tuner_addr, NULL); | ||
2871 | } | ||
2872 | } | ||
2873 | |||
2874 | em28xx_tuner_setup(dev); | ||
2875 | } | ||
2876 | |||
2877 | |||
2878 | #if defined(CONFIG_MODULES) && defined(MODULE) | ||
2879 | static void request_module_async(struct work_struct *work) | ||
2880 | { | ||
2881 | struct em28xx *dev = container_of(work, | ||
2882 | struct em28xx, request_module_wk); | ||
2883 | |||
2884 | if (dev->has_audio_class) | ||
2885 | request_module("snd-usb-audio"); | ||
2886 | else if (dev->has_alsa_audio) | ||
2887 | request_module("em28xx-alsa"); | ||
2888 | |||
2889 | if (dev->board.has_dvb) | ||
2890 | request_module("em28xx-dvb"); | ||
2891 | if (dev->board.ir_codes && !disable_ir) | ||
2892 | request_module("em28xx-rc"); | ||
2893 | } | ||
2894 | |||
2895 | static void request_modules(struct em28xx *dev) | ||
2896 | { | ||
2897 | INIT_WORK(&dev->request_module_wk, request_module_async); | ||
2898 | schedule_work(&dev->request_module_wk); | ||
2899 | } | ||
2900 | |||
2901 | static void flush_request_modules(struct em28xx *dev) | ||
2902 | { | ||
2903 | flush_work_sync(&dev->request_module_wk); | ||
2904 | } | ||
2905 | #else | ||
2906 | #define request_modules(dev) | ||
2907 | #define flush_request_modules(dev) | ||
2908 | #endif /* CONFIG_MODULES */ | ||
2909 | |||
2910 | /* | ||
2911 | * em28xx_release_resources() | ||
2912 | * unregisters the v4l2,i2c and usb devices | ||
2913 | * called when the device gets disconnected or at module unload | ||
2914 | */ | ||
2915 | void em28xx_release_resources(struct em28xx *dev) | ||
2916 | { | ||
2917 | /*FIXME: I2C IR should be disconnected */ | ||
2918 | |||
2919 | em28xx_release_analog_resources(dev); | ||
2920 | |||
2921 | em28xx_i2c_unregister(dev); | ||
2922 | |||
2923 | v4l2_device_unregister(&dev->v4l2_dev); | ||
2924 | |||
2925 | usb_put_dev(dev->udev); | ||
2926 | |||
2927 | /* Mark device as unused */ | ||
2928 | clear_bit(dev->devno, &em28xx_devused); | ||
2929 | }; | ||
2930 | |||
2931 | /* | ||
2932 | * em28xx_init_dev() | ||
2933 | * allocates and inits the device structs, registers i2c bus and v4l device | ||
2934 | */ | ||
2935 | static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, | ||
2936 | struct usb_interface *interface, | ||
2937 | int minor) | ||
2938 | { | ||
2939 | int retval; | ||
2940 | |||
2941 | dev->udev = udev; | ||
2942 | mutex_init(&dev->ctrl_urb_lock); | ||
2943 | spin_lock_init(&dev->slock); | ||
2944 | |||
2945 | dev->em28xx_write_regs = em28xx_write_regs; | ||
2946 | dev->em28xx_read_reg = em28xx_read_reg; | ||
2947 | dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len; | ||
2948 | dev->em28xx_write_regs_req = em28xx_write_regs_req; | ||
2949 | dev->em28xx_read_reg_req = em28xx_read_reg_req; | ||
2950 | dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800; | ||
2951 | |||
2952 | em28xx_set_model(dev); | ||
2953 | |||
2954 | /* Set the default GPO/GPIO for legacy devices */ | ||
2955 | dev->reg_gpo_num = EM2880_R04_GPO; | ||
2956 | dev->reg_gpio_num = EM28XX_R08_GPIO; | ||
2957 | |||
2958 | dev->wait_after_write = 5; | ||
2959 | |||
2960 | /* Based on the Chip ID, set the device configuration */ | ||
2961 | retval = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); | ||
2962 | if (retval > 0) { | ||
2963 | dev->chip_id = retval; | ||
2964 | |||
2965 | switch (dev->chip_id) { | ||
2966 | case CHIP_ID_EM2800: | ||
2967 | em28xx_info("chip ID is em2800\n"); | ||
2968 | break; | ||
2969 | case CHIP_ID_EM2710: | ||
2970 | em28xx_info("chip ID is em2710\n"); | ||
2971 | break; | ||
2972 | case CHIP_ID_EM2750: | ||
2973 | em28xx_info("chip ID is em2750\n"); | ||
2974 | break; | ||
2975 | case CHIP_ID_EM2820: | ||
2976 | em28xx_info("chip ID is em2820 (or em2710)\n"); | ||
2977 | break; | ||
2978 | case CHIP_ID_EM2840: | ||
2979 | em28xx_info("chip ID is em2840\n"); | ||
2980 | break; | ||
2981 | case CHIP_ID_EM2860: | ||
2982 | em28xx_info("chip ID is em2860\n"); | ||
2983 | break; | ||
2984 | case CHIP_ID_EM2870: | ||
2985 | em28xx_info("chip ID is em2870\n"); | ||
2986 | dev->wait_after_write = 0; | ||
2987 | break; | ||
2988 | case CHIP_ID_EM2874: | ||
2989 | em28xx_info("chip ID is em2874\n"); | ||
2990 | dev->reg_gpio_num = EM2874_R80_GPIO; | ||
2991 | dev->wait_after_write = 0; | ||
2992 | break; | ||
2993 | case CHIP_ID_EM28174: | ||
2994 | em28xx_info("chip ID is em28174\n"); | ||
2995 | dev->reg_gpio_num = EM2874_R80_GPIO; | ||
2996 | dev->wait_after_write = 0; | ||
2997 | break; | ||
2998 | case CHIP_ID_EM2883: | ||
2999 | em28xx_info("chip ID is em2882/em2883\n"); | ||
3000 | dev->wait_after_write = 0; | ||
3001 | break; | ||
3002 | case CHIP_ID_EM2884: | ||
3003 | em28xx_info("chip ID is em2884\n"); | ||
3004 | dev->reg_gpio_num = EM2874_R80_GPIO; | ||
3005 | dev->wait_after_write = 0; | ||
3006 | break; | ||
3007 | default: | ||
3008 | em28xx_info("em28xx chip ID = %d\n", dev->chip_id); | ||
3009 | } | ||
3010 | } | ||
3011 | |||
3012 | if (dev->is_audio_only) { | ||
3013 | retval = em28xx_audio_setup(dev); | ||
3014 | if (retval) | ||
3015 | return -ENODEV; | ||
3016 | em28xx_init_extension(dev); | ||
3017 | |||
3018 | return 0; | ||
3019 | } | ||
3020 | |||
3021 | /* Prepopulate cached GPO register content */ | ||
3022 | retval = em28xx_read_reg(dev, dev->reg_gpo_num); | ||
3023 | if (retval >= 0) | ||
3024 | dev->reg_gpo = retval; | ||
3025 | |||
3026 | em28xx_pre_card_setup(dev); | ||
3027 | |||
3028 | if (!dev->board.is_em2800) { | ||
3029 | /* Resets I2C speed */ | ||
3030 | retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); | ||
3031 | if (retval < 0) { | ||
3032 | em28xx_errdev("%s: em28xx_write_reg failed!" | ||
3033 | " retval [%d]\n", | ||
3034 | __func__, retval); | ||
3035 | return retval; | ||
3036 | } | ||
3037 | } | ||
3038 | |||
3039 | retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev); | ||
3040 | if (retval < 0) { | ||
3041 | em28xx_errdev("Call to v4l2_device_register() failed!\n"); | ||
3042 | return retval; | ||
3043 | } | ||
3044 | |||
3045 | /* register i2c bus */ | ||
3046 | retval = em28xx_i2c_register(dev); | ||
3047 | if (retval < 0) { | ||
3048 | em28xx_errdev("%s: em28xx_i2c_register - error [%d]!\n", | ||
3049 | __func__, retval); | ||
3050 | goto unregister_dev; | ||
3051 | } | ||
3052 | |||
3053 | /* | ||
3054 | * Default format, used for tvp5150 or saa711x output formats | ||
3055 | */ | ||
3056 | dev->vinmode = 0x10; | ||
3057 | dev->vinctl = EM28XX_VINCTRL_INTERLACED | | ||
3058 | EM28XX_VINCTRL_CCIR656_ENABLE; | ||
3059 | |||
3060 | /* Do board specific init and eeprom reading */ | ||
3061 | em28xx_card_setup(dev); | ||
3062 | |||
3063 | /* Configure audio */ | ||
3064 | retval = em28xx_audio_setup(dev); | ||
3065 | if (retval < 0) { | ||
3066 | em28xx_errdev("%s: Error while setting audio - error [%d]!\n", | ||
3067 | __func__, retval); | ||
3068 | goto fail; | ||
3069 | } | ||
3070 | |||
3071 | /* wake i2c devices */ | ||
3072 | em28xx_wake_i2c(dev); | ||
3073 | |||
3074 | /* init video dma queues */ | ||
3075 | INIT_LIST_HEAD(&dev->vidq.active); | ||
3076 | INIT_LIST_HEAD(&dev->vbiq.active); | ||
3077 | |||
3078 | if (dev->board.has_msp34xx) { | ||
3079 | /* Send a reset to other chips via gpio */ | ||
3080 | retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7); | ||
3081 | if (retval < 0) { | ||
3082 | em28xx_errdev("%s: em28xx_write_reg - " | ||
3083 | "msp34xx(1) failed! error [%d]\n", | ||
3084 | __func__, retval); | ||
3085 | goto fail; | ||
3086 | } | ||
3087 | msleep(3); | ||
3088 | |||
3089 | retval = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff); | ||
3090 | if (retval < 0) { | ||
3091 | em28xx_errdev("%s: em28xx_write_reg - " | ||
3092 | "msp34xx(2) failed! error [%d]\n", | ||
3093 | __func__, retval); | ||
3094 | goto fail; | ||
3095 | } | ||
3096 | msleep(3); | ||
3097 | } | ||
3098 | |||
3099 | retval = em28xx_register_analog_devices(dev); | ||
3100 | if (retval < 0) { | ||
3101 | goto fail; | ||
3102 | } | ||
3103 | |||
3104 | /* Save some power by putting tuner to sleep */ | ||
3105 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0); | ||
3106 | |||
3107 | return 0; | ||
3108 | |||
3109 | fail: | ||
3110 | em28xx_i2c_unregister(dev); | ||
3111 | |||
3112 | unregister_dev: | ||
3113 | v4l2_device_unregister(&dev->v4l2_dev); | ||
3114 | |||
3115 | return retval; | ||
3116 | } | ||
3117 | |||
3118 | /* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */ | ||
3119 | #define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03)) | ||
3120 | |||
3121 | /* | ||
3122 | * em28xx_usb_probe() | ||
3123 | * checks for supported devices | ||
3124 | */ | ||
3125 | static int em28xx_usb_probe(struct usb_interface *interface, | ||
3126 | const struct usb_device_id *id) | ||
3127 | { | ||
3128 | struct usb_device *udev; | ||
3129 | struct em28xx *dev = NULL; | ||
3130 | int retval; | ||
3131 | bool has_audio = false, has_video = false, has_dvb = false; | ||
3132 | int i, nr; | ||
3133 | const int ifnum = interface->altsetting[0].desc.bInterfaceNumber; | ||
3134 | char *speed; | ||
3135 | |||
3136 | udev = usb_get_dev(interface_to_usbdev(interface)); | ||
3137 | |||
3138 | /* Check to see next free device and mark as used */ | ||
3139 | do { | ||
3140 | nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS); | ||
3141 | if (nr >= EM28XX_MAXBOARDS) { | ||
3142 | /* No free device slots */ | ||
3143 | printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", | ||
3144 | EM28XX_MAXBOARDS); | ||
3145 | retval = -ENOMEM; | ||
3146 | goto err_no_slot; | ||
3147 | } | ||
3148 | } while (test_and_set_bit(nr, &em28xx_devused)); | ||
3149 | |||
3150 | /* Don't register audio interfaces */ | ||
3151 | if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { | ||
3152 | em28xx_err(DRIVER_NAME " audio device (%04x:%04x): " | ||
3153 | "interface %i, class %i\n", | ||
3154 | le16_to_cpu(udev->descriptor.idVendor), | ||
3155 | le16_to_cpu(udev->descriptor.idProduct), | ||
3156 | ifnum, | ||
3157 | interface->altsetting[0].desc.bInterfaceClass); | ||
3158 | |||
3159 | retval = -ENODEV; | ||
3160 | goto err; | ||
3161 | } | ||
3162 | |||
3163 | /* allocate memory for our device state and initialize it */ | ||
3164 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
3165 | if (dev == NULL) { | ||
3166 | em28xx_err(DRIVER_NAME ": out of memory!\n"); | ||
3167 | retval = -ENOMEM; | ||
3168 | goto err; | ||
3169 | } | ||
3170 | |||
3171 | /* compute alternate max packet sizes */ | ||
3172 | dev->alt_max_pkt_size = kmalloc(sizeof(dev->alt_max_pkt_size[0]) * | ||
3173 | interface->num_altsetting, GFP_KERNEL); | ||
3174 | if (dev->alt_max_pkt_size == NULL) { | ||
3175 | em28xx_errdev("out of memory!\n"); | ||
3176 | kfree(dev); | ||
3177 | retval = -ENOMEM; | ||
3178 | goto err; | ||
3179 | } | ||
3180 | |||
3181 | /* Get endpoints */ | ||
3182 | for (i = 0; i < interface->num_altsetting; i++) { | ||
3183 | int ep; | ||
3184 | |||
3185 | for (ep = 0; ep < interface->altsetting[i].desc.bNumEndpoints; ep++) { | ||
3186 | const struct usb_endpoint_descriptor *e; | ||
3187 | int sizedescr, size; | ||
3188 | |||
3189 | e = &interface->altsetting[i].endpoint[ep].desc; | ||
3190 | |||
3191 | sizedescr = le16_to_cpu(e->wMaxPacketSize); | ||
3192 | size = sizedescr & 0x7ff; | ||
3193 | |||
3194 | if (udev->speed == USB_SPEED_HIGH) | ||
3195 | size = size * hb_mult(sizedescr); | ||
3196 | |||
3197 | if (usb_endpoint_xfer_isoc(e) && | ||
3198 | usb_endpoint_dir_in(e)) { | ||
3199 | switch (e->bEndpointAddress) { | ||
3200 | case EM28XX_EP_AUDIO: | ||
3201 | has_audio = true; | ||
3202 | break; | ||
3203 | case EM28XX_EP_ANALOG: | ||
3204 | has_video = true; | ||
3205 | dev->alt_max_pkt_size[i] = size; | ||
3206 | break; | ||
3207 | case EM28XX_EP_DIGITAL: | ||
3208 | has_dvb = true; | ||
3209 | if (size > dev->dvb_max_pkt_size) { | ||
3210 | dev->dvb_max_pkt_size = size; | ||
3211 | dev->dvb_alt = i; | ||
3212 | } | ||
3213 | break; | ||
3214 | } | ||
3215 | } | ||
3216 | } | ||
3217 | } | ||
3218 | |||
3219 | if (!(has_audio || has_video || has_dvb)) { | ||
3220 | retval = -ENODEV; | ||
3221 | goto err_free; | ||
3222 | } | ||
3223 | |||
3224 | switch (udev->speed) { | ||
3225 | case USB_SPEED_LOW: | ||
3226 | speed = "1.5"; | ||
3227 | break; | ||
3228 | case USB_SPEED_UNKNOWN: | ||
3229 | case USB_SPEED_FULL: | ||
3230 | speed = "12"; | ||
3231 | break; | ||
3232 | case USB_SPEED_HIGH: | ||
3233 | speed = "480"; | ||
3234 | break; | ||
3235 | default: | ||
3236 | speed = "unknown"; | ||
3237 | } | ||
3238 | |||
3239 | printk(KERN_INFO DRIVER_NAME | ||
3240 | ": New device %s %s @ %s Mbps " | ||
3241 | "(%04x:%04x, interface %d, class %d)\n", | ||
3242 | udev->manufacturer ? udev->manufacturer : "", | ||
3243 | udev->product ? udev->product : "", | ||
3244 | speed, | ||
3245 | le16_to_cpu(udev->descriptor.idVendor), | ||
3246 | le16_to_cpu(udev->descriptor.idProduct), | ||
3247 | ifnum, | ||
3248 | interface->altsetting->desc.bInterfaceNumber); | ||
3249 | |||
3250 | if (has_audio) | ||
3251 | printk(KERN_INFO DRIVER_NAME | ||
3252 | ": Audio Vendor Class interface %i found\n", | ||
3253 | ifnum); | ||
3254 | if (has_video) | ||
3255 | printk(KERN_INFO DRIVER_NAME | ||
3256 | ": Video interface %i found\n", | ||
3257 | ifnum); | ||
3258 | if (has_dvb) | ||
3259 | printk(KERN_INFO DRIVER_NAME | ||
3260 | ": DVB interface %i found\n", | ||
3261 | ifnum); | ||
3262 | |||
3263 | /* | ||
3264 | * Make sure we have 480 Mbps of bandwidth, otherwise things like | ||
3265 | * video stream wouldn't likely work, since 12 Mbps is generally | ||
3266 | * not enough even for most Digital TV streams. | ||
3267 | */ | ||
3268 | if (udev->speed != USB_SPEED_HIGH && disable_usb_speed_check == 0) { | ||
3269 | printk(DRIVER_NAME ": Device initialization failed.\n"); | ||
3270 | printk(DRIVER_NAME ": Device must be connected to a high-speed" | ||
3271 | " USB 2.0 port.\n"); | ||
3272 | retval = -ENODEV; | ||
3273 | goto err_free; | ||
3274 | } | ||
3275 | |||
3276 | snprintf(dev->name, sizeof(dev->name), "em28xx #%d", nr); | ||
3277 | dev->devno = nr; | ||
3278 | dev->model = id->driver_info; | ||
3279 | dev->alt = -1; | ||
3280 | dev->is_audio_only = has_audio && !(has_video || has_dvb); | ||
3281 | dev->has_alsa_audio = has_audio; | ||
3282 | dev->audio_ifnum = ifnum; | ||
3283 | |||
3284 | /* Checks if audio is provided by some interface */ | ||
3285 | for (i = 0; i < udev->config->desc.bNumInterfaces; i++) { | ||
3286 | struct usb_interface *uif = udev->config->interface[i]; | ||
3287 | if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { | ||
3288 | dev->has_audio_class = 1; | ||
3289 | break; | ||
3290 | } | ||
3291 | } | ||
3292 | |||
3293 | dev->num_alt = interface->num_altsetting; | ||
3294 | |||
3295 | if ((card[nr] >= 0) && (card[nr] < em28xx_bcount)) | ||
3296 | dev->model = card[nr]; | ||
3297 | |||
3298 | /* save our data pointer in this interface device */ | ||
3299 | usb_set_intfdata(interface, dev); | ||
3300 | |||
3301 | /* allocate device struct */ | ||
3302 | mutex_init(&dev->lock); | ||
3303 | mutex_lock(&dev->lock); | ||
3304 | retval = em28xx_init_dev(dev, udev, interface, nr); | ||
3305 | if (retval) { | ||
3306 | goto unlock_and_free; | ||
3307 | } | ||
3308 | |||
3309 | if (has_dvb) { | ||
3310 | /* pre-allocate DVB isoc transfer buffers */ | ||
3311 | retval = em28xx_alloc_isoc(dev, EM28XX_DIGITAL_MODE, | ||
3312 | EM28XX_DVB_MAX_PACKETS, | ||
3313 | EM28XX_DVB_NUM_BUFS, | ||
3314 | dev->dvb_max_pkt_size); | ||
3315 | if (retval) { | ||
3316 | goto unlock_and_free; | ||
3317 | } | ||
3318 | } | ||
3319 | |||
3320 | request_modules(dev); | ||
3321 | |||
3322 | /* Should be the last thing to do, to avoid newer udev's to | ||
3323 | open the device before fully initializing it | ||
3324 | */ | ||
3325 | mutex_unlock(&dev->lock); | ||
3326 | |||
3327 | /* | ||
3328 | * These extensions can be modules. If the modules are already | ||
3329 | * loaded then we can initialise the device now, otherwise we | ||
3330 | * will initialise it when the modules load instead. | ||
3331 | */ | ||
3332 | em28xx_init_extension(dev); | ||
3333 | |||
3334 | return 0; | ||
3335 | |||
3336 | unlock_and_free: | ||
3337 | mutex_unlock(&dev->lock); | ||
3338 | |||
3339 | err_free: | ||
3340 | kfree(dev->alt_max_pkt_size); | ||
3341 | kfree(dev); | ||
3342 | |||
3343 | err: | ||
3344 | clear_bit(nr, &em28xx_devused); | ||
3345 | |||
3346 | err_no_slot: | ||
3347 | usb_put_dev(udev); | ||
3348 | return retval; | ||
3349 | } | ||
3350 | |||
3351 | /* | ||
3352 | * em28xx_usb_disconnect() | ||
3353 | * called when the device gets disconnected | ||
3354 | * video device will be unregistered on v4l2_close in case it is still open | ||
3355 | */ | ||
3356 | static void em28xx_usb_disconnect(struct usb_interface *interface) | ||
3357 | { | ||
3358 | struct em28xx *dev; | ||
3359 | |||
3360 | dev = usb_get_intfdata(interface); | ||
3361 | usb_set_intfdata(interface, NULL); | ||
3362 | |||
3363 | if (!dev) | ||
3364 | return; | ||
3365 | |||
3366 | if (dev->is_audio_only) { | ||
3367 | mutex_lock(&dev->lock); | ||
3368 | em28xx_close_extension(dev); | ||
3369 | mutex_unlock(&dev->lock); | ||
3370 | return; | ||
3371 | } | ||
3372 | |||
3373 | em28xx_info("disconnecting %s\n", dev->vdev->name); | ||
3374 | |||
3375 | flush_request_modules(dev); | ||
3376 | |||
3377 | /* wait until all current v4l2 io is finished then deallocate | ||
3378 | resources */ | ||
3379 | mutex_lock(&dev->lock); | ||
3380 | |||
3381 | v4l2_device_disconnect(&dev->v4l2_dev); | ||
3382 | |||
3383 | if (dev->users) { | ||
3384 | em28xx_warn | ||
3385 | ("device %s is open! Deregistration and memory " | ||
3386 | "deallocation are deferred on close.\n", | ||
3387 | video_device_node_name(dev->vdev)); | ||
3388 | |||
3389 | dev->state |= DEV_MISCONFIGURED; | ||
3390 | em28xx_uninit_isoc(dev, dev->mode); | ||
3391 | dev->state |= DEV_DISCONNECTED; | ||
3392 | } else { | ||
3393 | dev->state |= DEV_DISCONNECTED; | ||
3394 | em28xx_release_resources(dev); | ||
3395 | } | ||
3396 | |||
3397 | /* free DVB isoc buffers */ | ||
3398 | em28xx_uninit_isoc(dev, EM28XX_DIGITAL_MODE); | ||
3399 | |||
3400 | mutex_unlock(&dev->lock); | ||
3401 | |||
3402 | em28xx_close_extension(dev); | ||
3403 | |||
3404 | if (!dev->users) { | ||
3405 | kfree(dev->alt_max_pkt_size); | ||
3406 | kfree(dev); | ||
3407 | } | ||
3408 | } | ||
3409 | |||
3410 | static struct usb_driver em28xx_usb_driver = { | ||
3411 | .name = "em28xx", | ||
3412 | .probe = em28xx_usb_probe, | ||
3413 | .disconnect = em28xx_usb_disconnect, | ||
3414 | .id_table = em28xx_id_table, | ||
3415 | }; | ||
3416 | |||
3417 | module_usb_driver(em28xx_usb_driver); | ||
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c deleted file mode 100644 index bed07a6c33f8..000000000000 --- a/drivers/media/video/em28xx/em28xx-core.c +++ /dev/null | |||
@@ -1,1260 +0,0 @@ | |||
1 | /* | ||
2 | em28xx-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices | ||
3 | |||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | ||
5 | Markus Rechberger <mrechberger@gmail.com> | ||
6 | Mauro Carvalho Chehab <mchehab@infradead.org> | ||
7 | Sascha Sommer <saschasommer@freenet.de> | ||
8 | |||
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 | |||
24 | #include <linux/init.h> | ||
25 | #include <linux/list.h> | ||
26 | #include <linux/module.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/usb.h> | ||
29 | #include <linux/vmalloc.h> | ||
30 | #include <sound/ac97_codec.h> | ||
31 | #include <media/v4l2-common.h> | ||
32 | |||
33 | #include "em28xx.h" | ||
34 | |||
35 | /* #define ENABLE_DEBUG_ISOC_FRAMES */ | ||
36 | |||
37 | static unsigned int core_debug; | ||
38 | module_param(core_debug, int, 0644); | ||
39 | MODULE_PARM_DESC(core_debug, "enable debug messages [core]"); | ||
40 | |||
41 | #define em28xx_coredbg(fmt, arg...) do {\ | ||
42 | if (core_debug) \ | ||
43 | printk(KERN_INFO "%s %s :"fmt, \ | ||
44 | dev->name, __func__ , ##arg); } while (0) | ||
45 | |||
46 | static unsigned int reg_debug; | ||
47 | module_param(reg_debug, int, 0644); | ||
48 | MODULE_PARM_DESC(reg_debug, "enable debug messages [URB reg]"); | ||
49 | |||
50 | #define em28xx_regdbg(fmt, arg...) do {\ | ||
51 | if (reg_debug) \ | ||
52 | printk(KERN_INFO "%s %s :"fmt, \ | ||
53 | dev->name, __func__ , ##arg); } while (0) | ||
54 | |||
55 | static int alt; | ||
56 | module_param(alt, int, 0644); | ||
57 | MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); | ||
58 | |||
59 | static unsigned int disable_vbi; | ||
60 | module_param(disable_vbi, int, 0644); | ||
61 | MODULE_PARM_DESC(disable_vbi, "disable vbi support"); | ||
62 | |||
63 | /* FIXME */ | ||
64 | #define em28xx_isocdbg(fmt, arg...) do {\ | ||
65 | if (core_debug) \ | ||
66 | printk(KERN_INFO "%s %s :"fmt, \ | ||
67 | dev->name, __func__ , ##arg); } while (0) | ||
68 | |||
69 | /* | ||
70 | * em28xx_read_reg_req() | ||
71 | * reads data from the usb device specifying bRequest | ||
72 | */ | ||
73 | int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | ||
74 | char *buf, int len) | ||
75 | { | ||
76 | int ret; | ||
77 | int pipe = usb_rcvctrlpipe(dev->udev, 0); | ||
78 | |||
79 | if (dev->state & DEV_DISCONNECTED) | ||
80 | return -ENODEV; | ||
81 | |||
82 | if (len > URB_MAX_CTRL_SIZE) | ||
83 | return -EINVAL; | ||
84 | |||
85 | if (reg_debug) { | ||
86 | printk(KERN_DEBUG "(pipe 0x%08x): " | ||
87 | "IN: %02x %02x %02x %02x %02x %02x %02x %02x ", | ||
88 | pipe, | ||
89 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
90 | req, 0, 0, | ||
91 | reg & 0xff, reg >> 8, | ||
92 | len & 0xff, len >> 8); | ||
93 | } | ||
94 | |||
95 | mutex_lock(&dev->ctrl_urb_lock); | ||
96 | ret = usb_control_msg(dev->udev, pipe, req, | ||
97 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
98 | 0x0000, reg, dev->urb_buf, len, HZ); | ||
99 | if (ret < 0) { | ||
100 | if (reg_debug) | ||
101 | printk(" failed!\n"); | ||
102 | mutex_unlock(&dev->ctrl_urb_lock); | ||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | if (len) | ||
107 | memcpy(buf, dev->urb_buf, len); | ||
108 | |||
109 | mutex_unlock(&dev->ctrl_urb_lock); | ||
110 | |||
111 | if (reg_debug) { | ||
112 | int byte; | ||
113 | |||
114 | printk("<<<"); | ||
115 | for (byte = 0; byte < len; byte++) | ||
116 | printk(" %02x", (unsigned char)buf[byte]); | ||
117 | printk("\n"); | ||
118 | } | ||
119 | |||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * em28xx_read_reg_req() | ||
125 | * reads data from the usb device specifying bRequest | ||
126 | */ | ||
127 | int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg) | ||
128 | { | ||
129 | int ret; | ||
130 | u8 val; | ||
131 | |||
132 | ret = em28xx_read_reg_req_len(dev, req, reg, &val, 1); | ||
133 | if (ret < 0) | ||
134 | return ret; | ||
135 | |||
136 | return val; | ||
137 | } | ||
138 | |||
139 | int em28xx_read_reg(struct em28xx *dev, u16 reg) | ||
140 | { | ||
141 | return em28xx_read_reg_req(dev, USB_REQ_GET_STATUS, reg); | ||
142 | } | ||
143 | EXPORT_SYMBOL_GPL(em28xx_read_reg); | ||
144 | |||
145 | /* | ||
146 | * em28xx_write_regs_req() | ||
147 | * sends data to the usb device, specifying bRequest | ||
148 | */ | ||
149 | int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | ||
150 | int len) | ||
151 | { | ||
152 | int ret; | ||
153 | int pipe = usb_sndctrlpipe(dev->udev, 0); | ||
154 | |||
155 | if (dev->state & DEV_DISCONNECTED) | ||
156 | return -ENODEV; | ||
157 | |||
158 | if ((len < 1) || (len > URB_MAX_CTRL_SIZE)) | ||
159 | return -EINVAL; | ||
160 | |||
161 | if (reg_debug) { | ||
162 | int byte; | ||
163 | |||
164 | printk(KERN_DEBUG "(pipe 0x%08x): " | ||
165 | "OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>", | ||
166 | pipe, | ||
167 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
168 | req, 0, 0, | ||
169 | reg & 0xff, reg >> 8, | ||
170 | len & 0xff, len >> 8); | ||
171 | |||
172 | for (byte = 0; byte < len; byte++) | ||
173 | printk(" %02x", (unsigned char)buf[byte]); | ||
174 | printk("\n"); | ||
175 | } | ||
176 | |||
177 | mutex_lock(&dev->ctrl_urb_lock); | ||
178 | memcpy(dev->urb_buf, buf, len); | ||
179 | ret = usb_control_msg(dev->udev, pipe, req, | ||
180 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
181 | 0x0000, reg, dev->urb_buf, len, HZ); | ||
182 | mutex_unlock(&dev->ctrl_urb_lock); | ||
183 | |||
184 | if (dev->wait_after_write) | ||
185 | msleep(dev->wait_after_write); | ||
186 | |||
187 | return ret; | ||
188 | } | ||
189 | |||
190 | int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len) | ||
191 | { | ||
192 | int rc; | ||
193 | |||
194 | rc = em28xx_write_regs_req(dev, USB_REQ_GET_STATUS, reg, buf, len); | ||
195 | |||
196 | /* Stores GPO/GPIO values at the cache, if changed | ||
197 | Only write values should be stored, since input on a GPIO | ||
198 | register will return the input bits. | ||
199 | Not sure what happens on reading GPO register. | ||
200 | */ | ||
201 | if (rc >= 0) { | ||
202 | if (reg == dev->reg_gpo_num) | ||
203 | dev->reg_gpo = buf[0]; | ||
204 | else if (reg == dev->reg_gpio_num) | ||
205 | dev->reg_gpio = buf[0]; | ||
206 | } | ||
207 | |||
208 | return rc; | ||
209 | } | ||
210 | EXPORT_SYMBOL_GPL(em28xx_write_regs); | ||
211 | |||
212 | /* Write a single register */ | ||
213 | int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val) | ||
214 | { | ||
215 | return em28xx_write_regs(dev, reg, &val, 1); | ||
216 | } | ||
217 | EXPORT_SYMBOL_GPL(em28xx_write_reg); | ||
218 | |||
219 | /* | ||
220 | * em28xx_write_reg_bits() | ||
221 | * sets only some bits (specified by bitmask) of a register, by first reading | ||
222 | * the actual value | ||
223 | */ | ||
224 | int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, | ||
225 | u8 bitmask) | ||
226 | { | ||
227 | int oldval; | ||
228 | u8 newval; | ||
229 | |||
230 | /* Uses cache for gpo/gpio registers */ | ||
231 | if (reg == dev->reg_gpo_num) | ||
232 | oldval = dev->reg_gpo; | ||
233 | else if (reg == dev->reg_gpio_num) | ||
234 | oldval = dev->reg_gpio; | ||
235 | else | ||
236 | oldval = em28xx_read_reg(dev, reg); | ||
237 | |||
238 | if (oldval < 0) | ||
239 | return oldval; | ||
240 | |||
241 | newval = (((u8) oldval) & ~bitmask) | (val & bitmask); | ||
242 | |||
243 | return em28xx_write_regs(dev, reg, &newval, 1); | ||
244 | } | ||
245 | EXPORT_SYMBOL_GPL(em28xx_write_reg_bits); | ||
246 | |||
247 | /* | ||
248 | * em28xx_is_ac97_ready() | ||
249 | * Checks if ac97 is ready | ||
250 | */ | ||
251 | static int em28xx_is_ac97_ready(struct em28xx *dev) | ||
252 | { | ||
253 | int ret, i; | ||
254 | |||
255 | /* Wait up to 50 ms for AC97 command to complete */ | ||
256 | for (i = 0; i < 10; i++, msleep(5)) { | ||
257 | ret = em28xx_read_reg(dev, EM28XX_R43_AC97BUSY); | ||
258 | if (ret < 0) | ||
259 | return ret; | ||
260 | |||
261 | if (!(ret & 0x01)) | ||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | em28xx_warn("AC97 command still being executed: not handled properly!\n"); | ||
266 | return -EBUSY; | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * em28xx_read_ac97() | ||
271 | * write a 16 bit value to the specified AC97 address (LSB first!) | ||
272 | */ | ||
273 | int em28xx_read_ac97(struct em28xx *dev, u8 reg) | ||
274 | { | ||
275 | int ret; | ||
276 | u8 addr = (reg & 0x7f) | 0x80; | ||
277 | u16 val; | ||
278 | |||
279 | ret = em28xx_is_ac97_ready(dev); | ||
280 | if (ret < 0) | ||
281 | return ret; | ||
282 | |||
283 | ret = em28xx_write_regs(dev, EM28XX_R42_AC97ADDR, &addr, 1); | ||
284 | if (ret < 0) | ||
285 | return ret; | ||
286 | |||
287 | ret = dev->em28xx_read_reg_req_len(dev, 0, EM28XX_R40_AC97LSB, | ||
288 | (u8 *)&val, sizeof(val)); | ||
289 | |||
290 | if (ret < 0) | ||
291 | return ret; | ||
292 | return le16_to_cpu(val); | ||
293 | } | ||
294 | EXPORT_SYMBOL_GPL(em28xx_read_ac97); | ||
295 | |||
296 | /* | ||
297 | * em28xx_write_ac97() | ||
298 | * write a 16 bit value to the specified AC97 address (LSB first!) | ||
299 | */ | ||
300 | int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val) | ||
301 | { | ||
302 | int ret; | ||
303 | u8 addr = reg & 0x7f; | ||
304 | __le16 value; | ||
305 | |||
306 | value = cpu_to_le16(val); | ||
307 | |||
308 | ret = em28xx_is_ac97_ready(dev); | ||
309 | if (ret < 0) | ||
310 | return ret; | ||
311 | |||
312 | ret = em28xx_write_regs(dev, EM28XX_R40_AC97LSB, (u8 *) &value, 2); | ||
313 | if (ret < 0) | ||
314 | return ret; | ||
315 | |||
316 | ret = em28xx_write_regs(dev, EM28XX_R42_AC97ADDR, &addr, 1); | ||
317 | if (ret < 0) | ||
318 | return ret; | ||
319 | |||
320 | return 0; | ||
321 | } | ||
322 | EXPORT_SYMBOL_GPL(em28xx_write_ac97); | ||
323 | |||
324 | struct em28xx_vol_itable { | ||
325 | enum em28xx_amux mux; | ||
326 | u8 reg; | ||
327 | }; | ||
328 | |||
329 | static struct em28xx_vol_itable inputs[] = { | ||
330 | { EM28XX_AMUX_VIDEO, AC97_VIDEO }, | ||
331 | { EM28XX_AMUX_LINE_IN, AC97_LINE }, | ||
332 | { EM28XX_AMUX_PHONE, AC97_PHONE }, | ||
333 | { EM28XX_AMUX_MIC, AC97_MIC }, | ||
334 | { EM28XX_AMUX_CD, AC97_CD }, | ||
335 | { EM28XX_AMUX_AUX, AC97_AUX }, | ||
336 | { EM28XX_AMUX_PCM_OUT, AC97_PCM }, | ||
337 | }; | ||
338 | |||
339 | static int set_ac97_input(struct em28xx *dev) | ||
340 | { | ||
341 | int ret, i; | ||
342 | enum em28xx_amux amux = dev->ctl_ainput; | ||
343 | |||
344 | /* EM28XX_AMUX_VIDEO2 is a special case used to indicate that | ||
345 | em28xx should point to LINE IN, while AC97 should use VIDEO | ||
346 | */ | ||
347 | if (amux == EM28XX_AMUX_VIDEO2) | ||
348 | amux = EM28XX_AMUX_VIDEO; | ||
349 | |||
350 | /* Mute all entres but the one that were selected */ | ||
351 | for (i = 0; i < ARRAY_SIZE(inputs); i++) { | ||
352 | if (amux == inputs[i].mux) | ||
353 | ret = em28xx_write_ac97(dev, inputs[i].reg, 0x0808); | ||
354 | else | ||
355 | ret = em28xx_write_ac97(dev, inputs[i].reg, 0x8000); | ||
356 | |||
357 | if (ret < 0) | ||
358 | em28xx_warn("couldn't setup AC97 register %d\n", | ||
359 | inputs[i].reg); | ||
360 | } | ||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | static int em28xx_set_audio_source(struct em28xx *dev) | ||
365 | { | ||
366 | int ret; | ||
367 | u8 input; | ||
368 | |||
369 | if (dev->board.is_em2800) { | ||
370 | if (dev->ctl_ainput == EM28XX_AMUX_VIDEO) | ||
371 | input = EM2800_AUDIO_SRC_TUNER; | ||
372 | else | ||
373 | input = EM2800_AUDIO_SRC_LINE; | ||
374 | |||
375 | ret = em28xx_write_regs(dev, EM2800_R08_AUDIOSRC, &input, 1); | ||
376 | if (ret < 0) | ||
377 | return ret; | ||
378 | } | ||
379 | |||
380 | if (dev->board.has_msp34xx) | ||
381 | input = EM28XX_AUDIO_SRC_TUNER; | ||
382 | else { | ||
383 | switch (dev->ctl_ainput) { | ||
384 | case EM28XX_AMUX_VIDEO: | ||
385 | input = EM28XX_AUDIO_SRC_TUNER; | ||
386 | break; | ||
387 | default: | ||
388 | input = EM28XX_AUDIO_SRC_LINE; | ||
389 | break; | ||
390 | } | ||
391 | } | ||
392 | |||
393 | if (dev->board.mute_gpio && dev->mute) | ||
394 | em28xx_gpio_set(dev, dev->board.mute_gpio); | ||
395 | else | ||
396 | em28xx_gpio_set(dev, INPUT(dev->ctl_input)->gpio); | ||
397 | |||
398 | ret = em28xx_write_reg_bits(dev, EM28XX_R0E_AUDIOSRC, input, 0xc0); | ||
399 | if (ret < 0) | ||
400 | return ret; | ||
401 | msleep(5); | ||
402 | |||
403 | switch (dev->audio_mode.ac97) { | ||
404 | case EM28XX_NO_AC97: | ||
405 | break; | ||
406 | default: | ||
407 | ret = set_ac97_input(dev); | ||
408 | } | ||
409 | |||
410 | return ret; | ||
411 | } | ||
412 | |||
413 | struct em28xx_vol_otable { | ||
414 | enum em28xx_aout mux; | ||
415 | u8 reg; | ||
416 | }; | ||
417 | |||
418 | static const struct em28xx_vol_otable outputs[] = { | ||
419 | { EM28XX_AOUT_MASTER, AC97_MASTER }, | ||
420 | { EM28XX_AOUT_LINE, AC97_HEADPHONE }, | ||
421 | { EM28XX_AOUT_MONO, AC97_MASTER_MONO }, | ||
422 | { EM28XX_AOUT_LFE, AC97_CENTER_LFE_MASTER }, | ||
423 | { EM28XX_AOUT_SURR, AC97_SURROUND_MASTER }, | ||
424 | }; | ||
425 | |||
426 | int em28xx_audio_analog_set(struct em28xx *dev) | ||
427 | { | ||
428 | int ret, i; | ||
429 | u8 xclk; | ||
430 | |||
431 | if (!dev->audio_mode.has_audio) | ||
432 | return 0; | ||
433 | |||
434 | /* It is assumed that all devices use master volume for output. | ||
435 | It would be possible to use also line output. | ||
436 | */ | ||
437 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { | ||
438 | /* Mute all outputs */ | ||
439 | for (i = 0; i < ARRAY_SIZE(outputs); i++) { | ||
440 | ret = em28xx_write_ac97(dev, outputs[i].reg, 0x8000); | ||
441 | if (ret < 0) | ||
442 | em28xx_warn("couldn't setup AC97 register %d\n", | ||
443 | outputs[i].reg); | ||
444 | } | ||
445 | } | ||
446 | |||
447 | xclk = dev->board.xclk & 0x7f; | ||
448 | if (!dev->mute) | ||
449 | xclk |= EM28XX_XCLK_AUDIO_UNMUTE; | ||
450 | |||
451 | ret = em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk); | ||
452 | if (ret < 0) | ||
453 | return ret; | ||
454 | msleep(10); | ||
455 | |||
456 | /* Selects the proper audio input */ | ||
457 | ret = em28xx_set_audio_source(dev); | ||
458 | |||
459 | /* Sets volume */ | ||
460 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { | ||
461 | int vol; | ||
462 | |||
463 | em28xx_write_ac97(dev, AC97_POWERDOWN, 0x4200); | ||
464 | em28xx_write_ac97(dev, AC97_EXTENDED_STATUS, 0x0031); | ||
465 | em28xx_write_ac97(dev, AC97_PCM_LR_ADC_RATE, 0xbb80); | ||
466 | |||
467 | /* LSB: left channel - both channels with the same level */ | ||
468 | vol = (0x1f - dev->volume) | ((0x1f - dev->volume) << 8); | ||
469 | |||
470 | /* Mute device, if needed */ | ||
471 | if (dev->mute) | ||
472 | vol |= 0x8000; | ||
473 | |||
474 | /* Sets volume */ | ||
475 | for (i = 0; i < ARRAY_SIZE(outputs); i++) { | ||
476 | if (dev->ctl_aoutput & outputs[i].mux) | ||
477 | ret = em28xx_write_ac97(dev, outputs[i].reg, | ||
478 | vol); | ||
479 | if (ret < 0) | ||
480 | em28xx_warn("couldn't setup AC97 register %d\n", | ||
481 | outputs[i].reg); | ||
482 | } | ||
483 | |||
484 | if (dev->ctl_aoutput & EM28XX_AOUT_PCM_IN) { | ||
485 | int sel = ac97_return_record_select(dev->ctl_aoutput); | ||
486 | |||
487 | /* Use the same input for both left and right | ||
488 | channels */ | ||
489 | sel |= (sel << 8); | ||
490 | |||
491 | em28xx_write_ac97(dev, AC97_REC_SEL, sel); | ||
492 | } | ||
493 | } | ||
494 | |||
495 | return ret; | ||
496 | } | ||
497 | EXPORT_SYMBOL_GPL(em28xx_audio_analog_set); | ||
498 | |||
499 | int em28xx_audio_setup(struct em28xx *dev) | ||
500 | { | ||
501 | int vid1, vid2, feat, cfg; | ||
502 | u32 vid; | ||
503 | |||
504 | if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874 | ||
505 | || dev->chip_id == CHIP_ID_EM28174) { | ||
506 | /* Digital only device - don't load any alsa module */ | ||
507 | dev->audio_mode.has_audio = false; | ||
508 | dev->has_audio_class = false; | ||
509 | dev->has_alsa_audio = false; | ||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | dev->audio_mode.has_audio = true; | ||
514 | |||
515 | /* See how this device is configured */ | ||
516 | cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG); | ||
517 | em28xx_info("Config register raw data: 0x%02x\n", cfg); | ||
518 | if (cfg < 0) { | ||
519 | /* Register read error? */ | ||
520 | cfg = EM28XX_CHIPCFG_AC97; /* Be conservative */ | ||
521 | } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == 0x00) { | ||
522 | /* The device doesn't have vendor audio at all */ | ||
523 | dev->has_alsa_audio = false; | ||
524 | dev->audio_mode.has_audio = false; | ||
525 | return 0; | ||
526 | } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == | ||
527 | EM28XX_CHIPCFG_I2S_3_SAMPRATES) { | ||
528 | em28xx_info("I2S Audio (3 sample rates)\n"); | ||
529 | dev->audio_mode.i2s_3rates = 1; | ||
530 | } else if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == | ||
531 | EM28XX_CHIPCFG_I2S_5_SAMPRATES) { | ||
532 | em28xx_info("I2S Audio (5 sample rates)\n"); | ||
533 | dev->audio_mode.i2s_5rates = 1; | ||
534 | } | ||
535 | |||
536 | if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) != EM28XX_CHIPCFG_AC97) { | ||
537 | /* Skip the code that does AC97 vendor detection */ | ||
538 | dev->audio_mode.ac97 = EM28XX_NO_AC97; | ||
539 | goto init_audio; | ||
540 | } | ||
541 | |||
542 | dev->audio_mode.ac97 = EM28XX_AC97_OTHER; | ||
543 | |||
544 | vid1 = em28xx_read_ac97(dev, AC97_VENDOR_ID1); | ||
545 | if (vid1 < 0) { | ||
546 | /* | ||
547 | * Device likely doesn't support AC97 | ||
548 | * Note: (some) em2800 devices without eeprom reports 0x91 on | ||
549 | * CHIPCFG register, even not having an AC97 chip | ||
550 | */ | ||
551 | em28xx_warn("AC97 chip type couldn't be determined\n"); | ||
552 | dev->audio_mode.ac97 = EM28XX_NO_AC97; | ||
553 | dev->has_alsa_audio = false; | ||
554 | dev->audio_mode.has_audio = false; | ||
555 | goto init_audio; | ||
556 | } | ||
557 | |||
558 | vid2 = em28xx_read_ac97(dev, AC97_VENDOR_ID2); | ||
559 | if (vid2 < 0) | ||
560 | goto init_audio; | ||
561 | |||
562 | vid = vid1 << 16 | vid2; | ||
563 | |||
564 | dev->audio_mode.ac97_vendor_id = vid; | ||
565 | em28xx_warn("AC97 vendor ID = 0x%08x\n", vid); | ||
566 | |||
567 | feat = em28xx_read_ac97(dev, AC97_RESET); | ||
568 | if (feat < 0) | ||
569 | goto init_audio; | ||
570 | |||
571 | dev->audio_mode.ac97_feat = feat; | ||
572 | em28xx_warn("AC97 features = 0x%04x\n", feat); | ||
573 | |||
574 | /* Try to identify what audio processor we have */ | ||
575 | if (((vid == 0xffffffff) || (vid == 0x83847650)) && (feat == 0x6a90)) | ||
576 | dev->audio_mode.ac97 = EM28XX_AC97_EM202; | ||
577 | else if ((vid >> 8) == 0x838476) | ||
578 | dev->audio_mode.ac97 = EM28XX_AC97_SIGMATEL; | ||
579 | |||
580 | init_audio: | ||
581 | /* Reports detected AC97 processor */ | ||
582 | switch (dev->audio_mode.ac97) { | ||
583 | case EM28XX_NO_AC97: | ||
584 | em28xx_info("No AC97 audio processor\n"); | ||
585 | break; | ||
586 | case EM28XX_AC97_EM202: | ||
587 | em28xx_info("Empia 202 AC97 audio processor detected\n"); | ||
588 | break; | ||
589 | case EM28XX_AC97_SIGMATEL: | ||
590 | em28xx_info("Sigmatel audio processor detected(stac 97%02x)\n", | ||
591 | dev->audio_mode.ac97_vendor_id & 0xff); | ||
592 | break; | ||
593 | case EM28XX_AC97_OTHER: | ||
594 | em28xx_warn("Unknown AC97 audio processor detected!\n"); | ||
595 | break; | ||
596 | default: | ||
597 | break; | ||
598 | } | ||
599 | |||
600 | return em28xx_audio_analog_set(dev); | ||
601 | } | ||
602 | EXPORT_SYMBOL_GPL(em28xx_audio_setup); | ||
603 | |||
604 | int em28xx_colorlevels_set_default(struct em28xx *dev) | ||
605 | { | ||
606 | em28xx_write_reg(dev, EM28XX_R20_YGAIN, 0x10); /* contrast */ | ||
607 | em28xx_write_reg(dev, EM28XX_R21_YOFFSET, 0x00); /* brightness */ | ||
608 | em28xx_write_reg(dev, EM28XX_R22_UVGAIN, 0x10); /* saturation */ | ||
609 | em28xx_write_reg(dev, EM28XX_R23_UOFFSET, 0x00); | ||
610 | em28xx_write_reg(dev, EM28XX_R24_VOFFSET, 0x00); | ||
611 | em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, 0x00); | ||
612 | |||
613 | em28xx_write_reg(dev, EM28XX_R14_GAMMA, 0x20); | ||
614 | em28xx_write_reg(dev, EM28XX_R15_RGAIN, 0x20); | ||
615 | em28xx_write_reg(dev, EM28XX_R16_GGAIN, 0x20); | ||
616 | em28xx_write_reg(dev, EM28XX_R17_BGAIN, 0x20); | ||
617 | em28xx_write_reg(dev, EM28XX_R18_ROFFSET, 0x00); | ||
618 | em28xx_write_reg(dev, EM28XX_R19_GOFFSET, 0x00); | ||
619 | return em28xx_write_reg(dev, EM28XX_R1A_BOFFSET, 0x00); | ||
620 | } | ||
621 | |||
622 | int em28xx_capture_start(struct em28xx *dev, int start) | ||
623 | { | ||
624 | int rc; | ||
625 | |||
626 | if (dev->chip_id == CHIP_ID_EM2874 || | ||
627 | dev->chip_id == CHIP_ID_EM2884 || | ||
628 | dev->chip_id == CHIP_ID_EM28174) { | ||
629 | /* The Transport Stream Enable Register moved in em2874 */ | ||
630 | if (!start) { | ||
631 | rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE, | ||
632 | 0x00, | ||
633 | EM2874_TS1_CAPTURE_ENABLE); | ||
634 | return rc; | ||
635 | } | ||
636 | |||
637 | /* Enable Transport Stream */ | ||
638 | rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE, | ||
639 | EM2874_TS1_CAPTURE_ENABLE, | ||
640 | EM2874_TS1_CAPTURE_ENABLE); | ||
641 | return rc; | ||
642 | } | ||
643 | |||
644 | |||
645 | /* FIXME: which is the best order? */ | ||
646 | /* video registers are sampled by VREF */ | ||
647 | rc = em28xx_write_reg_bits(dev, EM28XX_R0C_USBSUSP, | ||
648 | start ? 0x10 : 0x00, 0x10); | ||
649 | if (rc < 0) | ||
650 | return rc; | ||
651 | |||
652 | if (!start) { | ||
653 | /* disable video capture */ | ||
654 | rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x27); | ||
655 | return rc; | ||
656 | } | ||
657 | |||
658 | if (dev->board.is_webcam) | ||
659 | rc = em28xx_write_reg(dev, 0x13, 0x0c); | ||
660 | |||
661 | /* enable video capture */ | ||
662 | rc = em28xx_write_reg(dev, 0x48, 0x00); | ||
663 | |||
664 | if (dev->mode == EM28XX_ANALOG_MODE) | ||
665 | rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67); | ||
666 | else | ||
667 | rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); | ||
668 | |||
669 | msleep(6); | ||
670 | |||
671 | return rc; | ||
672 | } | ||
673 | |||
674 | int em28xx_vbi_supported(struct em28xx *dev) | ||
675 | { | ||
676 | /* Modprobe option to manually disable */ | ||
677 | if (disable_vbi == 1) | ||
678 | return 0; | ||
679 | |||
680 | if (dev->chip_id == CHIP_ID_EM2860 || | ||
681 | dev->chip_id == CHIP_ID_EM2883) | ||
682 | return 1; | ||
683 | |||
684 | /* Version of em28xx that does not support VBI */ | ||
685 | return 0; | ||
686 | } | ||
687 | |||
688 | int em28xx_set_outfmt(struct em28xx *dev) | ||
689 | { | ||
690 | int ret; | ||
691 | u8 vinctrl; | ||
692 | |||
693 | ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT, | ||
694 | dev->format->reg | 0x20, 0xff); | ||
695 | if (ret < 0) | ||
696 | return ret; | ||
697 | |||
698 | ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, dev->vinmode); | ||
699 | if (ret < 0) | ||
700 | return ret; | ||
701 | |||
702 | vinctrl = dev->vinctl; | ||
703 | if (em28xx_vbi_supported(dev) == 1) { | ||
704 | vinctrl |= EM28XX_VINCTRL_VBI_RAW; | ||
705 | em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00); | ||
706 | em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, dev->vbi_width/4); | ||
707 | em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, dev->vbi_height); | ||
708 | if (dev->norm & V4L2_STD_525_60) { | ||
709 | /* NTSC */ | ||
710 | em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09); | ||
711 | } else if (dev->norm & V4L2_STD_625_50) { | ||
712 | /* PAL */ | ||
713 | em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x07); | ||
714 | } | ||
715 | } | ||
716 | |||
717 | return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl); | ||
718 | } | ||
719 | |||
720 | static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, | ||
721 | u8 ymin, u8 ymax) | ||
722 | { | ||
723 | em28xx_coredbg("em28xx Scale: (%d,%d)-(%d,%d)\n", | ||
724 | xmin, ymin, xmax, ymax); | ||
725 | |||
726 | em28xx_write_regs(dev, EM28XX_R28_XMIN, &xmin, 1); | ||
727 | em28xx_write_regs(dev, EM28XX_R29_XMAX, &xmax, 1); | ||
728 | em28xx_write_regs(dev, EM28XX_R2A_YMIN, &ymin, 1); | ||
729 | return em28xx_write_regs(dev, EM28XX_R2B_YMAX, &ymax, 1); | ||
730 | } | ||
731 | |||
732 | static int em28xx_capture_area_set(struct em28xx *dev, u8 hstart, u8 vstart, | ||
733 | u16 width, u16 height) | ||
734 | { | ||
735 | u8 cwidth = width; | ||
736 | u8 cheight = height; | ||
737 | u8 overflow = (height >> 7 & 0x02) | (width >> 8 & 0x01); | ||
738 | |||
739 | em28xx_coredbg("em28xx Area Set: (%d,%d)\n", | ||
740 | (width | (overflow & 2) << 7), | ||
741 | (height | (overflow & 1) << 8)); | ||
742 | |||
743 | em28xx_write_regs(dev, EM28XX_R1C_HSTART, &hstart, 1); | ||
744 | em28xx_write_regs(dev, EM28XX_R1D_VSTART, &vstart, 1); | ||
745 | em28xx_write_regs(dev, EM28XX_R1E_CWIDTH, &cwidth, 1); | ||
746 | em28xx_write_regs(dev, EM28XX_R1F_CHEIGHT, &cheight, 1); | ||
747 | return em28xx_write_regs(dev, EM28XX_R1B_OFLOW, &overflow, 1); | ||
748 | } | ||
749 | |||
750 | static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) | ||
751 | { | ||
752 | u8 mode; | ||
753 | /* the em2800 scaler only supports scaling down to 50% */ | ||
754 | |||
755 | if (dev->board.is_em2800) { | ||
756 | mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); | ||
757 | } else { | ||
758 | u8 buf[2]; | ||
759 | |||
760 | buf[0] = h; | ||
761 | buf[1] = h >> 8; | ||
762 | em28xx_write_regs(dev, EM28XX_R30_HSCALELOW, (char *)buf, 2); | ||
763 | |||
764 | buf[0] = v; | ||
765 | buf[1] = v >> 8; | ||
766 | em28xx_write_regs(dev, EM28XX_R32_VSCALELOW, (char *)buf, 2); | ||
767 | /* it seems that both H and V scalers must be active | ||
768 | to work correctly */ | ||
769 | mode = (h || v) ? 0x30 : 0x00; | ||
770 | } | ||
771 | return em28xx_write_reg_bits(dev, EM28XX_R26_COMPR, mode, 0x30); | ||
772 | } | ||
773 | |||
774 | /* FIXME: this only function read values from dev */ | ||
775 | int em28xx_resolution_set(struct em28xx *dev) | ||
776 | { | ||
777 | int width, height; | ||
778 | width = norm_maxw(dev); | ||
779 | height = norm_maxh(dev); | ||
780 | |||
781 | /* Properly setup VBI */ | ||
782 | dev->vbi_width = 720; | ||
783 | if (dev->norm & V4L2_STD_525_60) | ||
784 | dev->vbi_height = 12; | ||
785 | else | ||
786 | dev->vbi_height = 18; | ||
787 | |||
788 | em28xx_set_outfmt(dev); | ||
789 | |||
790 | em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); | ||
791 | |||
792 | /* If we don't set the start position to 2 in VBI mode, we end up | ||
793 | with line 20/21 being YUYV encoded instead of being in 8-bit | ||
794 | greyscale. The core of the issue is that line 21 (and line 23 for | ||
795 | PAL WSS) are inside of active video region, and as a result they | ||
796 | get the pixelformatting associated with that area. So by cropping | ||
797 | it out, we end up with the same format as the rest of the VBI | ||
798 | region */ | ||
799 | if (em28xx_vbi_supported(dev) == 1) | ||
800 | em28xx_capture_area_set(dev, 0, 2, width >> 2, height >> 2); | ||
801 | else | ||
802 | em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2); | ||
803 | |||
804 | return em28xx_scaler_set(dev, dev->hscale, dev->vscale); | ||
805 | } | ||
806 | |||
807 | int em28xx_set_alternate(struct em28xx *dev) | ||
808 | { | ||
809 | int errCode, prev_alt = dev->alt; | ||
810 | int i; | ||
811 | unsigned int min_pkt_size = dev->width * 2 + 4; | ||
812 | |||
813 | /* | ||
814 | * alt = 0 is used only for control messages, so, only values | ||
815 | * greater than 0 can be used for streaming. | ||
816 | */ | ||
817 | if (alt && alt < dev->num_alt) { | ||
818 | em28xx_coredbg("alternate forced to %d\n", dev->alt); | ||
819 | dev->alt = alt; | ||
820 | goto set_alt; | ||
821 | } | ||
822 | |||
823 | /* When image size is bigger than a certain value, | ||
824 | the frame size should be increased, otherwise, only | ||
825 | green screen will be received. | ||
826 | */ | ||
827 | if (dev->width * 2 * dev->height > 720 * 240 * 2) | ||
828 | min_pkt_size *= 2; | ||
829 | |||
830 | for (i = 0; i < dev->num_alt; i++) { | ||
831 | /* stop when the selected alt setting offers enough bandwidth */ | ||
832 | if (dev->alt_max_pkt_size[i] >= min_pkt_size) { | ||
833 | dev->alt = i; | ||
834 | break; | ||
835 | /* otherwise make sure that we end up with the maximum bandwidth | ||
836 | because the min_pkt_size equation might be wrong... | ||
837 | */ | ||
838 | } else if (dev->alt_max_pkt_size[i] > | ||
839 | dev->alt_max_pkt_size[dev->alt]) | ||
840 | dev->alt = i; | ||
841 | } | ||
842 | |||
843 | set_alt: | ||
844 | if (dev->alt != prev_alt) { | ||
845 | em28xx_coredbg("minimum isoc packet size: %u (alt=%d)\n", | ||
846 | min_pkt_size, dev->alt); | ||
847 | dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt]; | ||
848 | em28xx_coredbg("setting alternate %d with wMaxPacketSize=%u\n", | ||
849 | dev->alt, dev->max_pkt_size); | ||
850 | errCode = usb_set_interface(dev->udev, 0, dev->alt); | ||
851 | if (errCode < 0) { | ||
852 | em28xx_errdev("cannot change alternate number to %d (error=%i)\n", | ||
853 | dev->alt, errCode); | ||
854 | return errCode; | ||
855 | } | ||
856 | } | ||
857 | return 0; | ||
858 | } | ||
859 | |||
860 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio) | ||
861 | { | ||
862 | int rc = 0; | ||
863 | |||
864 | if (!gpio) | ||
865 | return rc; | ||
866 | |||
867 | if (dev->mode != EM28XX_SUSPEND) { | ||
868 | em28xx_write_reg(dev, 0x48, 0x00); | ||
869 | if (dev->mode == EM28XX_ANALOG_MODE) | ||
870 | em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67); | ||
871 | else | ||
872 | em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); | ||
873 | msleep(6); | ||
874 | } | ||
875 | |||
876 | /* Send GPIO reset sequences specified at board entry */ | ||
877 | while (gpio->sleep >= 0) { | ||
878 | if (gpio->reg >= 0) { | ||
879 | rc = em28xx_write_reg_bits(dev, | ||
880 | gpio->reg, | ||
881 | gpio->val, | ||
882 | gpio->mask); | ||
883 | if (rc < 0) | ||
884 | return rc; | ||
885 | } | ||
886 | if (gpio->sleep > 0) | ||
887 | msleep(gpio->sleep); | ||
888 | |||
889 | gpio++; | ||
890 | } | ||
891 | return rc; | ||
892 | } | ||
893 | EXPORT_SYMBOL_GPL(em28xx_gpio_set); | ||
894 | |||
895 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode) | ||
896 | { | ||
897 | if (dev->mode == set_mode) | ||
898 | return 0; | ||
899 | |||
900 | if (set_mode == EM28XX_SUSPEND) { | ||
901 | dev->mode = set_mode; | ||
902 | |||
903 | /* FIXME: add suspend support for ac97 */ | ||
904 | |||
905 | return em28xx_gpio_set(dev, dev->board.suspend_gpio); | ||
906 | } | ||
907 | |||
908 | dev->mode = set_mode; | ||
909 | |||
910 | if (dev->mode == EM28XX_DIGITAL_MODE) | ||
911 | return em28xx_gpio_set(dev, dev->board.dvb_gpio); | ||
912 | else | ||
913 | return em28xx_gpio_set(dev, INPUT(dev->ctl_input)->gpio); | ||
914 | } | ||
915 | EXPORT_SYMBOL_GPL(em28xx_set_mode); | ||
916 | |||
917 | /* ------------------------------------------------------------------ | ||
918 | URB control | ||
919 | ------------------------------------------------------------------*/ | ||
920 | |||
921 | /* | ||
922 | * IRQ callback, called by URB callback | ||
923 | */ | ||
924 | static void em28xx_irq_callback(struct urb *urb) | ||
925 | { | ||
926 | struct em28xx *dev = urb->context; | ||
927 | int i; | ||
928 | |||
929 | switch (urb->status) { | ||
930 | case 0: /* success */ | ||
931 | case -ETIMEDOUT: /* NAK */ | ||
932 | break; | ||
933 | case -ECONNRESET: /* kill */ | ||
934 | case -ENOENT: | ||
935 | case -ESHUTDOWN: | ||
936 | return; | ||
937 | default: /* error */ | ||
938 | em28xx_isocdbg("urb completition error %d.\n", urb->status); | ||
939 | break; | ||
940 | } | ||
941 | |||
942 | /* Copy data from URB */ | ||
943 | spin_lock(&dev->slock); | ||
944 | dev->isoc_ctl.isoc_copy(dev, urb); | ||
945 | spin_unlock(&dev->slock); | ||
946 | |||
947 | /* Reset urb buffers */ | ||
948 | for (i = 0; i < urb->number_of_packets; i++) { | ||
949 | urb->iso_frame_desc[i].status = 0; | ||
950 | urb->iso_frame_desc[i].actual_length = 0; | ||
951 | } | ||
952 | urb->status = 0; | ||
953 | |||
954 | urb->status = usb_submit_urb(urb, GFP_ATOMIC); | ||
955 | if (urb->status) { | ||
956 | em28xx_isocdbg("urb resubmit failed (error=%i)\n", | ||
957 | urb->status); | ||
958 | } | ||
959 | } | ||
960 | |||
961 | /* | ||
962 | * Stop and Deallocate URBs | ||
963 | */ | ||
964 | void em28xx_uninit_isoc(struct em28xx *dev, enum em28xx_mode mode) | ||
965 | { | ||
966 | struct urb *urb; | ||
967 | struct em28xx_usb_isoc_bufs *isoc_bufs; | ||
968 | int i; | ||
969 | |||
970 | em28xx_isocdbg("em28xx: called em28xx_uninit_isoc in mode %d\n", mode); | ||
971 | |||
972 | if (mode == EM28XX_DIGITAL_MODE) | ||
973 | isoc_bufs = &dev->isoc_ctl.digital_bufs; | ||
974 | else | ||
975 | isoc_bufs = &dev->isoc_ctl.analog_bufs; | ||
976 | |||
977 | for (i = 0; i < isoc_bufs->num_bufs; i++) { | ||
978 | urb = isoc_bufs->urb[i]; | ||
979 | if (urb) { | ||
980 | if (!irqs_disabled()) | ||
981 | usb_kill_urb(urb); | ||
982 | else | ||
983 | usb_unlink_urb(urb); | ||
984 | |||
985 | if (isoc_bufs->transfer_buffer[i]) { | ||
986 | usb_free_coherent(dev->udev, | ||
987 | urb->transfer_buffer_length, | ||
988 | isoc_bufs->transfer_buffer[i], | ||
989 | urb->transfer_dma); | ||
990 | } | ||
991 | usb_free_urb(urb); | ||
992 | isoc_bufs->urb[i] = NULL; | ||
993 | } | ||
994 | isoc_bufs->transfer_buffer[i] = NULL; | ||
995 | } | ||
996 | |||
997 | kfree(isoc_bufs->urb); | ||
998 | kfree(isoc_bufs->transfer_buffer); | ||
999 | |||
1000 | isoc_bufs->urb = NULL; | ||
1001 | isoc_bufs->transfer_buffer = NULL; | ||
1002 | isoc_bufs->num_bufs = 0; | ||
1003 | |||
1004 | em28xx_capture_start(dev, 0); | ||
1005 | } | ||
1006 | EXPORT_SYMBOL_GPL(em28xx_uninit_isoc); | ||
1007 | |||
1008 | /* | ||
1009 | * Stop URBs | ||
1010 | */ | ||
1011 | void em28xx_stop_urbs(struct em28xx *dev) | ||
1012 | { | ||
1013 | int i; | ||
1014 | struct urb *urb; | ||
1015 | struct em28xx_usb_isoc_bufs *isoc_bufs = &dev->isoc_ctl.digital_bufs; | ||
1016 | |||
1017 | em28xx_isocdbg("em28xx: called em28xx_stop_urbs\n"); | ||
1018 | |||
1019 | for (i = 0; i < isoc_bufs->num_bufs; i++) { | ||
1020 | urb = isoc_bufs->urb[i]; | ||
1021 | if (urb) { | ||
1022 | if (!irqs_disabled()) | ||
1023 | usb_kill_urb(urb); | ||
1024 | else | ||
1025 | usb_unlink_urb(urb); | ||
1026 | } | ||
1027 | } | ||
1028 | |||
1029 | em28xx_capture_start(dev, 0); | ||
1030 | } | ||
1031 | EXPORT_SYMBOL_GPL(em28xx_stop_urbs); | ||
1032 | |||
1033 | /* | ||
1034 | * Allocate URBs | ||
1035 | */ | ||
1036 | int em28xx_alloc_isoc(struct em28xx *dev, enum em28xx_mode mode, | ||
1037 | int max_packets, int num_bufs, int max_pkt_size) | ||
1038 | { | ||
1039 | struct em28xx_usb_isoc_bufs *isoc_bufs; | ||
1040 | int i; | ||
1041 | int sb_size, pipe; | ||
1042 | struct urb *urb; | ||
1043 | int j, k; | ||
1044 | |||
1045 | em28xx_isocdbg("em28xx: called em28xx_alloc_isoc in mode %d\n", mode); | ||
1046 | |||
1047 | if (mode == EM28XX_DIGITAL_MODE) | ||
1048 | isoc_bufs = &dev->isoc_ctl.digital_bufs; | ||
1049 | else | ||
1050 | isoc_bufs = &dev->isoc_ctl.analog_bufs; | ||
1051 | |||
1052 | /* De-allocates all pending stuff */ | ||
1053 | em28xx_uninit_isoc(dev, mode); | ||
1054 | |||
1055 | isoc_bufs->num_bufs = num_bufs; | ||
1056 | |||
1057 | isoc_bufs->urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL); | ||
1058 | if (!isoc_bufs->urb) { | ||
1059 | em28xx_errdev("cannot alloc memory for usb buffers\n"); | ||
1060 | return -ENOMEM; | ||
1061 | } | ||
1062 | |||
1063 | isoc_bufs->transfer_buffer = kzalloc(sizeof(void *)*num_bufs, | ||
1064 | GFP_KERNEL); | ||
1065 | if (!isoc_bufs->transfer_buffer) { | ||
1066 | em28xx_errdev("cannot allocate memory for usb transfer\n"); | ||
1067 | kfree(isoc_bufs->urb); | ||
1068 | return -ENOMEM; | ||
1069 | } | ||
1070 | |||
1071 | isoc_bufs->max_pkt_size = max_pkt_size; | ||
1072 | isoc_bufs->num_packets = max_packets; | ||
1073 | dev->isoc_ctl.vid_buf = NULL; | ||
1074 | dev->isoc_ctl.vbi_buf = NULL; | ||
1075 | |||
1076 | sb_size = isoc_bufs->num_packets * isoc_bufs->max_pkt_size; | ||
1077 | |||
1078 | /* allocate urbs and transfer buffers */ | ||
1079 | for (i = 0; i < isoc_bufs->num_bufs; i++) { | ||
1080 | urb = usb_alloc_urb(isoc_bufs->num_packets, GFP_KERNEL); | ||
1081 | if (!urb) { | ||
1082 | em28xx_err("cannot alloc isoc_ctl.urb %i\n", i); | ||
1083 | em28xx_uninit_isoc(dev, mode); | ||
1084 | return -ENOMEM; | ||
1085 | } | ||
1086 | isoc_bufs->urb[i] = urb; | ||
1087 | |||
1088 | isoc_bufs->transfer_buffer[i] = usb_alloc_coherent(dev->udev, | ||
1089 | sb_size, GFP_KERNEL, &urb->transfer_dma); | ||
1090 | if (!isoc_bufs->transfer_buffer[i]) { | ||
1091 | em28xx_err("unable to allocate %i bytes for transfer" | ||
1092 | " buffer %i%s\n", | ||
1093 | sb_size, i, | ||
1094 | in_interrupt() ? " while in int" : ""); | ||
1095 | em28xx_uninit_isoc(dev, mode); | ||
1096 | return -ENOMEM; | ||
1097 | } | ||
1098 | memset(isoc_bufs->transfer_buffer[i], 0, sb_size); | ||
1099 | |||
1100 | /* FIXME: this is a hack - should be | ||
1101 | 'desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK' | ||
1102 | should also be using 'desc.bInterval' | ||
1103 | */ | ||
1104 | pipe = usb_rcvisocpipe(dev->udev, | ||
1105 | mode == EM28XX_ANALOG_MODE ? | ||
1106 | EM28XX_EP_ANALOG : EM28XX_EP_DIGITAL); | ||
1107 | |||
1108 | usb_fill_int_urb(urb, dev->udev, pipe, | ||
1109 | isoc_bufs->transfer_buffer[i], sb_size, | ||
1110 | em28xx_irq_callback, dev, 1); | ||
1111 | |||
1112 | urb->number_of_packets = isoc_bufs->num_packets; | ||
1113 | urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; | ||
1114 | |||
1115 | k = 0; | ||
1116 | for (j = 0; j < isoc_bufs->num_packets; j++) { | ||
1117 | urb->iso_frame_desc[j].offset = k; | ||
1118 | urb->iso_frame_desc[j].length = | ||
1119 | isoc_bufs->max_pkt_size; | ||
1120 | k += isoc_bufs->max_pkt_size; | ||
1121 | } | ||
1122 | } | ||
1123 | |||
1124 | return 0; | ||
1125 | } | ||
1126 | EXPORT_SYMBOL_GPL(em28xx_alloc_isoc); | ||
1127 | |||
1128 | /* | ||
1129 | * Allocate URBs and start IRQ | ||
1130 | */ | ||
1131 | int em28xx_init_isoc(struct em28xx *dev, enum em28xx_mode mode, | ||
1132 | int max_packets, int num_bufs, int max_pkt_size, | ||
1133 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb)) | ||
1134 | { | ||
1135 | struct em28xx_dmaqueue *dma_q = &dev->vidq; | ||
1136 | struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq; | ||
1137 | struct em28xx_usb_isoc_bufs *isoc_bufs; | ||
1138 | int i; | ||
1139 | int rc; | ||
1140 | int alloc; | ||
1141 | |||
1142 | em28xx_isocdbg("em28xx: called em28xx_init_isoc in mode %d\n", mode); | ||
1143 | |||
1144 | dev->isoc_ctl.isoc_copy = isoc_copy; | ||
1145 | |||
1146 | if (mode == EM28XX_DIGITAL_MODE) { | ||
1147 | isoc_bufs = &dev->isoc_ctl.digital_bufs; | ||
1148 | /* no need to free/alloc isoc buffers in digital mode */ | ||
1149 | alloc = 0; | ||
1150 | } else { | ||
1151 | isoc_bufs = &dev->isoc_ctl.analog_bufs; | ||
1152 | alloc = 1; | ||
1153 | } | ||
1154 | |||
1155 | if (alloc) { | ||
1156 | rc = em28xx_alloc_isoc(dev, mode, max_packets, | ||
1157 | num_bufs, max_pkt_size); | ||
1158 | if (rc) | ||
1159 | return rc; | ||
1160 | } | ||
1161 | |||
1162 | init_waitqueue_head(&dma_q->wq); | ||
1163 | init_waitqueue_head(&vbi_dma_q->wq); | ||
1164 | |||
1165 | em28xx_capture_start(dev, 1); | ||
1166 | |||
1167 | /* submit urbs and enables IRQ */ | ||
1168 | for (i = 0; i < isoc_bufs->num_bufs; i++) { | ||
1169 | rc = usb_submit_urb(isoc_bufs->urb[i], GFP_ATOMIC); | ||
1170 | if (rc) { | ||
1171 | em28xx_err("submit of urb %i failed (error=%i)\n", i, | ||
1172 | rc); | ||
1173 | em28xx_uninit_isoc(dev, mode); | ||
1174 | return rc; | ||
1175 | } | ||
1176 | } | ||
1177 | |||
1178 | return 0; | ||
1179 | } | ||
1180 | EXPORT_SYMBOL_GPL(em28xx_init_isoc); | ||
1181 | |||
1182 | /* | ||
1183 | * em28xx_wake_i2c() | ||
1184 | * configure i2c attached devices | ||
1185 | */ | ||
1186 | void em28xx_wake_i2c(struct em28xx *dev) | ||
1187 | { | ||
1188 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, reset, 0); | ||
1189 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing, | ||
1190 | INPUT(dev->ctl_input)->vmux, 0, 0); | ||
1191 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0); | ||
1192 | } | ||
1193 | |||
1194 | /* | ||
1195 | * Device control list | ||
1196 | */ | ||
1197 | |||
1198 | static LIST_HEAD(em28xx_devlist); | ||
1199 | static DEFINE_MUTEX(em28xx_devlist_mutex); | ||
1200 | |||
1201 | /* | ||
1202 | * Extension interface | ||
1203 | */ | ||
1204 | |||
1205 | static LIST_HEAD(em28xx_extension_devlist); | ||
1206 | |||
1207 | int em28xx_register_extension(struct em28xx_ops *ops) | ||
1208 | { | ||
1209 | struct em28xx *dev = NULL; | ||
1210 | |||
1211 | mutex_lock(&em28xx_devlist_mutex); | ||
1212 | list_add_tail(&ops->next, &em28xx_extension_devlist); | ||
1213 | list_for_each_entry(dev, &em28xx_devlist, devlist) { | ||
1214 | ops->init(dev); | ||
1215 | } | ||
1216 | mutex_unlock(&em28xx_devlist_mutex); | ||
1217 | printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); | ||
1218 | return 0; | ||
1219 | } | ||
1220 | EXPORT_SYMBOL(em28xx_register_extension); | ||
1221 | |||
1222 | void em28xx_unregister_extension(struct em28xx_ops *ops) | ||
1223 | { | ||
1224 | struct em28xx *dev = NULL; | ||
1225 | |||
1226 | mutex_lock(&em28xx_devlist_mutex); | ||
1227 | list_for_each_entry(dev, &em28xx_devlist, devlist) { | ||
1228 | ops->fini(dev); | ||
1229 | } | ||
1230 | list_del(&ops->next); | ||
1231 | mutex_unlock(&em28xx_devlist_mutex); | ||
1232 | printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); | ||
1233 | } | ||
1234 | EXPORT_SYMBOL(em28xx_unregister_extension); | ||
1235 | |||
1236 | void em28xx_init_extension(struct em28xx *dev) | ||
1237 | { | ||
1238 | const struct em28xx_ops *ops = NULL; | ||
1239 | |||
1240 | mutex_lock(&em28xx_devlist_mutex); | ||
1241 | list_add_tail(&dev->devlist, &em28xx_devlist); | ||
1242 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { | ||
1243 | if (ops->init) | ||
1244 | ops->init(dev); | ||
1245 | } | ||
1246 | mutex_unlock(&em28xx_devlist_mutex); | ||
1247 | } | ||
1248 | |||
1249 | void em28xx_close_extension(struct em28xx *dev) | ||
1250 | { | ||
1251 | const struct em28xx_ops *ops = NULL; | ||
1252 | |||
1253 | mutex_lock(&em28xx_devlist_mutex); | ||
1254 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { | ||
1255 | if (ops->fini) | ||
1256 | ops->fini(dev); | ||
1257 | } | ||
1258 | list_del(&dev->devlist); | ||
1259 | mutex_unlock(&em28xx_devlist_mutex); | ||
1260 | } | ||
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c deleted file mode 100644 index a16531fa937a..000000000000 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ /dev/null | |||
@@ -1,1197 +0,0 @@ | |||
1 | /* | ||
2 | DVB device driver for em28xx | ||
3 | |||
4 | (c) 2008-2011 Mauro Carvalho Chehab <mchehab@infradead.org> | ||
5 | |||
6 | (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> | ||
7 | - Fixes for the driver to properly work with HVR-950 | ||
8 | - Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick | ||
9 | - Fixes for the driver to properly work with AMD ATI TV Wonder HD 600 | ||
10 | |||
11 | (c) 2008 Aidan Thornton <makosoft@googlemail.com> | ||
12 | |||
13 | Based on cx88-dvb, saa7134-dvb and videobuf-dvb originally written by: | ||
14 | (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> | ||
15 | (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] | ||
16 | |||
17 | This program is free software; you can redistribute it and/or modify | ||
18 | it under the terms of the GNU General Public License as published by | ||
19 | the Free Software Foundation; either version 2 of the License. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/usb.h> | ||
25 | |||
26 | #include "em28xx.h" | ||
27 | #include <media/v4l2-common.h> | ||
28 | #include <media/videobuf-vmalloc.h> | ||
29 | #include <media/tuner.h> | ||
30 | #include "tuner-simple.h" | ||
31 | |||
32 | #include "lgdt330x.h" | ||
33 | #include "lgdt3305.h" | ||
34 | #include "zl10353.h" | ||
35 | #include "s5h1409.h" | ||
36 | #include "mt352.h" | ||
37 | #include "mt352_priv.h" /* FIXME */ | ||
38 | #include "tda1002x.h" | ||
39 | #include "tda18271.h" | ||
40 | #include "s921.h" | ||
41 | #include "drxd.h" | ||
42 | #include "cxd2820r.h" | ||
43 | #include "tda18271c2dd.h" | ||
44 | #include "drxk.h" | ||
45 | #include "tda10071.h" | ||
46 | #include "a8293.h" | ||
47 | #include "qt1010.h" | ||
48 | |||
49 | MODULE_DESCRIPTION("driver for em28xx based DVB cards"); | ||
50 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | ||
51 | MODULE_LICENSE("GPL"); | ||
52 | |||
53 | static unsigned int debug; | ||
54 | module_param(debug, int, 0644); | ||
55 | MODULE_PARM_DESC(debug, "enable debug messages [dvb]"); | ||
56 | |||
57 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
58 | |||
59 | #define dprintk(level, fmt, arg...) do { \ | ||
60 | if (debug >= level) \ | ||
61 | printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \ | ||
62 | } while (0) | ||
63 | |||
64 | struct em28xx_dvb { | ||
65 | struct dvb_frontend *fe[2]; | ||
66 | |||
67 | /* feed count management */ | ||
68 | struct mutex lock; | ||
69 | int nfeeds; | ||
70 | |||
71 | /* general boilerplate stuff */ | ||
72 | struct dvb_adapter adapter; | ||
73 | struct dvb_demux demux; | ||
74 | struct dmxdev dmxdev; | ||
75 | struct dmx_frontend fe_hw; | ||
76 | struct dmx_frontend fe_mem; | ||
77 | struct dvb_net net; | ||
78 | |||
79 | /* Due to DRX-K - probably need changes */ | ||
80 | int (*gate_ctrl)(struct dvb_frontend *, int); | ||
81 | struct semaphore pll_mutex; | ||
82 | bool dont_attach_fe1; | ||
83 | }; | ||
84 | |||
85 | |||
86 | static inline void print_err_status(struct em28xx *dev, | ||
87 | int packet, int status) | ||
88 | { | ||
89 | char *errmsg = "Unknown"; | ||
90 | |||
91 | switch (status) { | ||
92 | case -ENOENT: | ||
93 | errmsg = "unlinked synchronuously"; | ||
94 | break; | ||
95 | case -ECONNRESET: | ||
96 | errmsg = "unlinked asynchronuously"; | ||
97 | break; | ||
98 | case -ENOSR: | ||
99 | errmsg = "Buffer error (overrun)"; | ||
100 | break; | ||
101 | case -EPIPE: | ||
102 | errmsg = "Stalled (device not responding)"; | ||
103 | break; | ||
104 | case -EOVERFLOW: | ||
105 | errmsg = "Babble (bad cable?)"; | ||
106 | break; | ||
107 | case -EPROTO: | ||
108 | errmsg = "Bit-stuff error (bad cable?)"; | ||
109 | break; | ||
110 | case -EILSEQ: | ||
111 | errmsg = "CRC/Timeout (could be anything)"; | ||
112 | break; | ||
113 | case -ETIME: | ||
114 | errmsg = "Device does not respond"; | ||
115 | break; | ||
116 | } | ||
117 | if (packet < 0) { | ||
118 | dprintk(1, "URB status %d [%s].\n", status, errmsg); | ||
119 | } else { | ||
120 | dprintk(1, "URB packet %d, status %d [%s].\n", | ||
121 | packet, status, errmsg); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | static inline int em28xx_dvb_isoc_copy(struct em28xx *dev, struct urb *urb) | ||
126 | { | ||
127 | int i; | ||
128 | |||
129 | if (!dev) | ||
130 | return 0; | ||
131 | |||
132 | if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) | ||
133 | return 0; | ||
134 | |||
135 | if (urb->status < 0) { | ||
136 | print_err_status(dev, -1, urb->status); | ||
137 | if (urb->status == -ENOENT) | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | for (i = 0; i < urb->number_of_packets; i++) { | ||
142 | int status = urb->iso_frame_desc[i].status; | ||
143 | |||
144 | if (status < 0) { | ||
145 | print_err_status(dev, i, status); | ||
146 | if (urb->iso_frame_desc[i].status != -EPROTO) | ||
147 | continue; | ||
148 | } | ||
149 | |||
150 | dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer + | ||
151 | urb->iso_frame_desc[i].offset, | ||
152 | urb->iso_frame_desc[i].actual_length); | ||
153 | } | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int em28xx_start_streaming(struct em28xx_dvb *dvb) | ||
159 | { | ||
160 | int rc; | ||
161 | struct em28xx *dev = dvb->adapter.priv; | ||
162 | int max_dvb_packet_size; | ||
163 | |||
164 | usb_set_interface(dev->udev, 0, dev->dvb_alt); | ||
165 | rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | ||
166 | if (rc < 0) | ||
167 | return rc; | ||
168 | |||
169 | max_dvb_packet_size = dev->dvb_max_pkt_size; | ||
170 | if (max_dvb_packet_size < 0) | ||
171 | return max_dvb_packet_size; | ||
172 | dprintk(1, "Using %d buffers each with %d x %d bytes\n", | ||
173 | EM28XX_DVB_NUM_BUFS, | ||
174 | EM28XX_DVB_MAX_PACKETS, | ||
175 | max_dvb_packet_size); | ||
176 | |||
177 | return em28xx_init_isoc(dev, EM28XX_DIGITAL_MODE, | ||
178 | EM28XX_DVB_MAX_PACKETS, EM28XX_DVB_NUM_BUFS, | ||
179 | max_dvb_packet_size, em28xx_dvb_isoc_copy); | ||
180 | } | ||
181 | |||
182 | static int em28xx_stop_streaming(struct em28xx_dvb *dvb) | ||
183 | { | ||
184 | struct em28xx *dev = dvb->adapter.priv; | ||
185 | |||
186 | em28xx_stop_urbs(dev); | ||
187 | |||
188 | em28xx_set_mode(dev, EM28XX_SUSPEND); | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static int em28xx_start_feed(struct dvb_demux_feed *feed) | ||
194 | { | ||
195 | struct dvb_demux *demux = feed->demux; | ||
196 | struct em28xx_dvb *dvb = demux->priv; | ||
197 | int rc, ret; | ||
198 | |||
199 | if (!demux->dmx.frontend) | ||
200 | return -EINVAL; | ||
201 | |||
202 | mutex_lock(&dvb->lock); | ||
203 | dvb->nfeeds++; | ||
204 | rc = dvb->nfeeds; | ||
205 | |||
206 | if (dvb->nfeeds == 1) { | ||
207 | ret = em28xx_start_streaming(dvb); | ||
208 | if (ret < 0) | ||
209 | rc = ret; | ||
210 | } | ||
211 | |||
212 | mutex_unlock(&dvb->lock); | ||
213 | return rc; | ||
214 | } | ||
215 | |||
216 | static int em28xx_stop_feed(struct dvb_demux_feed *feed) | ||
217 | { | ||
218 | struct dvb_demux *demux = feed->demux; | ||
219 | struct em28xx_dvb *dvb = demux->priv; | ||
220 | int err = 0; | ||
221 | |||
222 | mutex_lock(&dvb->lock); | ||
223 | dvb->nfeeds--; | ||
224 | |||
225 | if (0 == dvb->nfeeds) | ||
226 | err = em28xx_stop_streaming(dvb); | ||
227 | |||
228 | mutex_unlock(&dvb->lock); | ||
229 | return err; | ||
230 | } | ||
231 | |||
232 | |||
233 | |||
234 | /* ------------------------------------------------------------------ */ | ||
235 | static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) | ||
236 | { | ||
237 | struct em28xx *dev = fe->dvb->priv; | ||
238 | |||
239 | if (acquire) | ||
240 | return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | ||
241 | else | ||
242 | return em28xx_set_mode(dev, EM28XX_SUSPEND); | ||
243 | } | ||
244 | |||
245 | /* ------------------------------------------------------------------ */ | ||
246 | |||
247 | static struct lgdt330x_config em2880_lgdt3303_dev = { | ||
248 | .demod_address = 0x0e, | ||
249 | .demod_chip = LGDT3303, | ||
250 | }; | ||
251 | |||
252 | static struct lgdt3305_config em2870_lgdt3304_dev = { | ||
253 | .i2c_addr = 0x0e, | ||
254 | .demod_chip = LGDT3304, | ||
255 | .spectral_inversion = 1, | ||
256 | .deny_i2c_rptr = 1, | ||
257 | .mpeg_mode = LGDT3305_MPEG_PARALLEL, | ||
258 | .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE, | ||
259 | .tpvalid_polarity = LGDT3305_TP_VALID_HIGH, | ||
260 | .vsb_if_khz = 3250, | ||
261 | .qam_if_khz = 4000, | ||
262 | }; | ||
263 | |||
264 | static struct s921_config sharp_isdbt = { | ||
265 | .demod_address = 0x30 >> 1 | ||
266 | }; | ||
267 | |||
268 | static struct zl10353_config em28xx_zl10353_with_xc3028 = { | ||
269 | .demod_address = (0x1e >> 1), | ||
270 | .no_tuner = 1, | ||
271 | .parallel_ts = 1, | ||
272 | .if2 = 45600, | ||
273 | }; | ||
274 | |||
275 | static struct s5h1409_config em28xx_s5h1409_with_xc3028 = { | ||
276 | .demod_address = 0x32 >> 1, | ||
277 | .output_mode = S5H1409_PARALLEL_OUTPUT, | ||
278 | .gpio = S5H1409_GPIO_OFF, | ||
279 | .inversion = S5H1409_INVERSION_OFF, | ||
280 | .status_mode = S5H1409_DEMODLOCKING, | ||
281 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK | ||
282 | }; | ||
283 | |||
284 | static struct tda18271_std_map kworld_a340_std_map = { | ||
285 | .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 0, | ||
286 | .if_lvl = 1, .rfagc_top = 0x37, }, | ||
287 | .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 1, | ||
288 | .if_lvl = 1, .rfagc_top = 0x37, }, | ||
289 | }; | ||
290 | |||
291 | static struct tda18271_config kworld_a340_config = { | ||
292 | .std_map = &kworld_a340_std_map, | ||
293 | }; | ||
294 | |||
295 | static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = { | ||
296 | .demod_address = (0x1e >> 1), | ||
297 | .no_tuner = 1, | ||
298 | .disable_i2c_gate_ctrl = 1, | ||
299 | .parallel_ts = 1, | ||
300 | .if2 = 45600, | ||
301 | }; | ||
302 | |||
303 | static struct drxd_config em28xx_drxd = { | ||
304 | .demod_address = 0x70, | ||
305 | .demod_revision = 0xa2, | ||
306 | .pll_type = DRXD_PLL_NONE, | ||
307 | .clock = 12000, | ||
308 | .insert_rs_byte = 1, | ||
309 | .IF = 42800000, | ||
310 | .disable_i2c_gate_ctrl = 1, | ||
311 | }; | ||
312 | |||
313 | static struct drxk_config terratec_h5_drxk = { | ||
314 | .adr = 0x29, | ||
315 | .single_master = 1, | ||
316 | .no_i2c_bridge = 1, | ||
317 | .microcode_name = "dvb-usb-terratec-h5-drxk.fw", | ||
318 | .qam_demod_parameter_count = 2, | ||
319 | }; | ||
320 | |||
321 | static struct drxk_config hauppauge_930c_drxk = { | ||
322 | .adr = 0x29, | ||
323 | .single_master = 1, | ||
324 | .no_i2c_bridge = 1, | ||
325 | .microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw", | ||
326 | .chunk_size = 56, | ||
327 | .qam_demod_parameter_count = 2, | ||
328 | }; | ||
329 | |||
330 | struct drxk_config terratec_htc_stick_drxk = { | ||
331 | .adr = 0x29, | ||
332 | .single_master = 1, | ||
333 | .no_i2c_bridge = 1, | ||
334 | .microcode_name = "dvb-usb-terratec-htc-stick-drxk.fw", | ||
335 | .chunk_size = 54, | ||
336 | .qam_demod_parameter_count = 2, | ||
337 | /* Required for the antenna_gpio to disable LNA. */ | ||
338 | .antenna_dvbt = true, | ||
339 | /* The windows driver uses the same. This will disable LNA. */ | ||
340 | .antenna_gpio = 0x6, | ||
341 | }; | ||
342 | |||
343 | static struct drxk_config maxmedia_ub425_tc_drxk = { | ||
344 | .adr = 0x29, | ||
345 | .single_master = 1, | ||
346 | .no_i2c_bridge = 1, | ||
347 | }; | ||
348 | |||
349 | static struct drxk_config pctv_520e_drxk = { | ||
350 | .adr = 0x29, | ||
351 | .single_master = 1, | ||
352 | .microcode_name = "dvb-demod-drxk-pctv.fw", | ||
353 | .qam_demod_parameter_count = 2, | ||
354 | .chunk_size = 58, | ||
355 | .antenna_dvbt = true, /* disable LNA */ | ||
356 | .antenna_gpio = (1 << 2), /* disable LNA */ | ||
357 | }; | ||
358 | |||
359 | static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
360 | { | ||
361 | struct em28xx_dvb *dvb = fe->sec_priv; | ||
362 | int status; | ||
363 | |||
364 | if (!dvb) | ||
365 | return -EINVAL; | ||
366 | |||
367 | if (enable) { | ||
368 | down(&dvb->pll_mutex); | ||
369 | status = dvb->gate_ctrl(fe, 1); | ||
370 | } else { | ||
371 | status = dvb->gate_ctrl(fe, 0); | ||
372 | up(&dvb->pll_mutex); | ||
373 | } | ||
374 | return status; | ||
375 | } | ||
376 | |||
377 | static void hauppauge_hvr930c_init(struct em28xx *dev) | ||
378 | { | ||
379 | int i; | ||
380 | |||
381 | struct em28xx_reg_seq hauppauge_hvr930c_init[] = { | ||
382 | {EM2874_R80_GPIO, 0xff, 0xff, 0x65}, | ||
383 | {EM2874_R80_GPIO, 0xfb, 0xff, 0x32}, | ||
384 | {EM2874_R80_GPIO, 0xff, 0xff, 0xb8}, | ||
385 | { -1, -1, -1, -1}, | ||
386 | }; | ||
387 | struct em28xx_reg_seq hauppauge_hvr930c_end[] = { | ||
388 | {EM2874_R80_GPIO, 0xef, 0xff, 0x01}, | ||
389 | {EM2874_R80_GPIO, 0xaf, 0xff, 0x65}, | ||
390 | {EM2874_R80_GPIO, 0xef, 0xff, 0x76}, | ||
391 | {EM2874_R80_GPIO, 0xef, 0xff, 0x01}, | ||
392 | {EM2874_R80_GPIO, 0xcf, 0xff, 0x0b}, | ||
393 | {EM2874_R80_GPIO, 0xef, 0xff, 0x40}, | ||
394 | |||
395 | {EM2874_R80_GPIO, 0xcf, 0xff, 0x65}, | ||
396 | {EM2874_R80_GPIO, 0xef, 0xff, 0x65}, | ||
397 | {EM2874_R80_GPIO, 0xcf, 0xff, 0x0b}, | ||
398 | {EM2874_R80_GPIO, 0xef, 0xff, 0x65}, | ||
399 | |||
400 | { -1, -1, -1, -1}, | ||
401 | }; | ||
402 | |||
403 | struct { | ||
404 | unsigned char r[4]; | ||
405 | int len; | ||
406 | } regs[] = { | ||
407 | {{ 0x06, 0x02, 0x00, 0x31 }, 4}, | ||
408 | {{ 0x01, 0x02 }, 2}, | ||
409 | {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, | ||
410 | {{ 0x01, 0x00 }, 2}, | ||
411 | {{ 0x01, 0x00, 0xff, 0xaf }, 4}, | ||
412 | {{ 0x01, 0x00, 0x03, 0xa0 }, 4}, | ||
413 | {{ 0x01, 0x00 }, 2}, | ||
414 | {{ 0x01, 0x00, 0x73, 0xaf }, 4}, | ||
415 | {{ 0x04, 0x00 }, 2}, | ||
416 | {{ 0x00, 0x04 }, 2}, | ||
417 | {{ 0x00, 0x04, 0x00, 0x0a }, 4}, | ||
418 | {{ 0x04, 0x14 }, 2}, | ||
419 | {{ 0x04, 0x14, 0x00, 0x00 }, 4}, | ||
420 | }; | ||
421 | |||
422 | em28xx_gpio_set(dev, hauppauge_hvr930c_init); | ||
423 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); | ||
424 | msleep(10); | ||
425 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); | ||
426 | msleep(10); | ||
427 | |||
428 | dev->i2c_client.addr = 0x82 >> 1; | ||
429 | |||
430 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
431 | i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); | ||
432 | em28xx_gpio_set(dev, hauppauge_hvr930c_end); | ||
433 | |||
434 | msleep(100); | ||
435 | |||
436 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); | ||
437 | msleep(30); | ||
438 | |||
439 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); | ||
440 | msleep(10); | ||
441 | |||
442 | } | ||
443 | |||
444 | static void terratec_h5_init(struct em28xx *dev) | ||
445 | { | ||
446 | int i; | ||
447 | struct em28xx_reg_seq terratec_h5_init[] = { | ||
448 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
449 | {EM2874_R80_GPIO, 0xf6, 0xff, 100}, | ||
450 | {EM2874_R80_GPIO, 0xf2, 0xff, 50}, | ||
451 | {EM2874_R80_GPIO, 0xf6, 0xff, 100}, | ||
452 | { -1, -1, -1, -1}, | ||
453 | }; | ||
454 | struct em28xx_reg_seq terratec_h5_end[] = { | ||
455 | {EM2874_R80_GPIO, 0xe6, 0xff, 100}, | ||
456 | {EM2874_R80_GPIO, 0xa6, 0xff, 50}, | ||
457 | {EM2874_R80_GPIO, 0xe6, 0xff, 100}, | ||
458 | { -1, -1, -1, -1}, | ||
459 | }; | ||
460 | struct { | ||
461 | unsigned char r[4]; | ||
462 | int len; | ||
463 | } regs[] = { | ||
464 | {{ 0x06, 0x02, 0x00, 0x31 }, 4}, | ||
465 | {{ 0x01, 0x02 }, 2}, | ||
466 | {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, | ||
467 | {{ 0x01, 0x00 }, 2}, | ||
468 | {{ 0x01, 0x00, 0xff, 0xaf }, 4}, | ||
469 | {{ 0x01, 0x00, 0x03, 0xa0 }, 4}, | ||
470 | {{ 0x01, 0x00 }, 2}, | ||
471 | {{ 0x01, 0x00, 0x73, 0xaf }, 4}, | ||
472 | {{ 0x04, 0x00 }, 2}, | ||
473 | {{ 0x00, 0x04 }, 2}, | ||
474 | {{ 0x00, 0x04, 0x00, 0x0a }, 4}, | ||
475 | {{ 0x04, 0x14 }, 2}, | ||
476 | {{ 0x04, 0x14, 0x00, 0x00 }, 4}, | ||
477 | }; | ||
478 | |||
479 | em28xx_gpio_set(dev, terratec_h5_init); | ||
480 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); | ||
481 | msleep(10); | ||
482 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); | ||
483 | msleep(10); | ||
484 | |||
485 | dev->i2c_client.addr = 0x82 >> 1; | ||
486 | |||
487 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
488 | i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); | ||
489 | em28xx_gpio_set(dev, terratec_h5_end); | ||
490 | }; | ||
491 | |||
492 | static void terratec_htc_stick_init(struct em28xx *dev) | ||
493 | { | ||
494 | int i; | ||
495 | |||
496 | /* | ||
497 | * GPIO configuration: | ||
498 | * 0xff: unknown (does not affect DVB-T). | ||
499 | * 0xf6: DRX-K (demodulator). | ||
500 | * 0xe6: unknown (does not affect DVB-T). | ||
501 | * 0xb6: unknown (does not affect DVB-T). | ||
502 | */ | ||
503 | struct em28xx_reg_seq terratec_htc_stick_init[] = { | ||
504 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
505 | {EM2874_R80_GPIO, 0xf6, 0xff, 100}, | ||
506 | {EM2874_R80_GPIO, 0xe6, 0xff, 50}, | ||
507 | {EM2874_R80_GPIO, 0xf6, 0xff, 100}, | ||
508 | { -1, -1, -1, -1}, | ||
509 | }; | ||
510 | struct em28xx_reg_seq terratec_htc_stick_end[] = { | ||
511 | {EM2874_R80_GPIO, 0xb6, 0xff, 100}, | ||
512 | {EM2874_R80_GPIO, 0xf6, 0xff, 50}, | ||
513 | { -1, -1, -1, -1}, | ||
514 | }; | ||
515 | |||
516 | /* Init the analog decoder? */ | ||
517 | struct { | ||
518 | unsigned char r[4]; | ||
519 | int len; | ||
520 | } regs[] = { | ||
521 | {{ 0x06, 0x02, 0x00, 0x31 }, 4}, | ||
522 | {{ 0x01, 0x02 }, 2}, | ||
523 | {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, | ||
524 | {{ 0x01, 0x00 }, 2}, | ||
525 | {{ 0x01, 0x00, 0xff, 0xaf }, 4}, | ||
526 | }; | ||
527 | |||
528 | em28xx_gpio_set(dev, terratec_htc_stick_init); | ||
529 | |||
530 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); | ||
531 | msleep(10); | ||
532 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); | ||
533 | msleep(10); | ||
534 | |||
535 | dev->i2c_client.addr = 0x82 >> 1; | ||
536 | |||
537 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
538 | i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); | ||
539 | |||
540 | em28xx_gpio_set(dev, terratec_htc_stick_end); | ||
541 | }; | ||
542 | |||
543 | static void pctv_520e_init(struct em28xx *dev) | ||
544 | { | ||
545 | /* | ||
546 | * Init AVF4910B analog decoder. Looks like I2C traffic to | ||
547 | * digital demodulator and tuner are routed via AVF4910B. | ||
548 | */ | ||
549 | int i; | ||
550 | struct { | ||
551 | unsigned char r[4]; | ||
552 | int len; | ||
553 | } regs[] = { | ||
554 | {{ 0x06, 0x02, 0x00, 0x31 }, 4}, | ||
555 | {{ 0x01, 0x02 }, 2}, | ||
556 | {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, | ||
557 | {{ 0x01, 0x00 }, 2}, | ||
558 | {{ 0x01, 0x00, 0xff, 0xaf }, 4}, | ||
559 | {{ 0x01, 0x00, 0x03, 0xa0 }, 4}, | ||
560 | {{ 0x01, 0x00 }, 2}, | ||
561 | {{ 0x01, 0x00, 0x73, 0xaf }, 4}, | ||
562 | }; | ||
563 | |||
564 | dev->i2c_client.addr = 0x82 >> 1; /* 0x41 */ | ||
565 | |||
566 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
567 | i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); | ||
568 | }; | ||
569 | |||
570 | static int em28xx_mt352_terratec_xs_init(struct dvb_frontend *fe) | ||
571 | { | ||
572 | /* Values extracted from a USB trace of the Terratec Windows driver */ | ||
573 | static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x2c }; | ||
574 | static u8 reset[] = { RESET, 0x80 }; | ||
575 | static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 }; | ||
576 | static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0xa0 }; | ||
577 | static u8 input_freq_cfg[] = { INPUT_FREQ_1, 0x31, 0xb8 }; | ||
578 | static u8 rs_err_cfg[] = { RS_ERR_PER_1, 0x00, 0x4d }; | ||
579 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | ||
580 | static u8 trl_nom_cfg[] = { TRL_NOMINAL_RATE_1, 0x64, 0x00 }; | ||
581 | static u8 tps_given_cfg[] = { TPS_GIVEN_1, 0x40, 0x80, 0x50 }; | ||
582 | static u8 tuner_go[] = { TUNER_GO, 0x01}; | ||
583 | |||
584 | mt352_write(fe, clock_config, sizeof(clock_config)); | ||
585 | udelay(200); | ||
586 | mt352_write(fe, reset, sizeof(reset)); | ||
587 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | ||
588 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | ||
589 | mt352_write(fe, input_freq_cfg, sizeof(input_freq_cfg)); | ||
590 | mt352_write(fe, rs_err_cfg, sizeof(rs_err_cfg)); | ||
591 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | ||
592 | mt352_write(fe, trl_nom_cfg, sizeof(trl_nom_cfg)); | ||
593 | mt352_write(fe, tps_given_cfg, sizeof(tps_given_cfg)); | ||
594 | mt352_write(fe, tuner_go, sizeof(tuner_go)); | ||
595 | return 0; | ||
596 | } | ||
597 | |||
598 | static struct mt352_config terratec_xs_mt352_cfg = { | ||
599 | .demod_address = (0x1e >> 1), | ||
600 | .no_tuner = 1, | ||
601 | .if2 = 45600, | ||
602 | .demod_init = em28xx_mt352_terratec_xs_init, | ||
603 | }; | ||
604 | |||
605 | static struct tda10023_config em28xx_tda10023_config = { | ||
606 | .demod_address = 0x0c, | ||
607 | .invert = 1, | ||
608 | }; | ||
609 | |||
610 | static struct cxd2820r_config em28xx_cxd2820r_config = { | ||
611 | .i2c_address = (0xd8 >> 1), | ||
612 | .ts_mode = CXD2820R_TS_SERIAL, | ||
613 | |||
614 | /* enable LNA for DVB-T, DVB-T2 and DVB-C */ | ||
615 | .gpio_dvbt[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L, | ||
616 | .gpio_dvbt2[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L, | ||
617 | .gpio_dvbc[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L, | ||
618 | }; | ||
619 | |||
620 | static struct tda18271_config em28xx_cxd2820r_tda18271_config = { | ||
621 | .output_opt = TDA18271_OUTPUT_LT_OFF, | ||
622 | .gate = TDA18271_GATE_DIGITAL, | ||
623 | }; | ||
624 | |||
625 | static const struct tda10071_config em28xx_tda10071_config = { | ||
626 | .i2c_address = 0x55, /* (0xaa >> 1) */ | ||
627 | .i2c_wr_max = 64, | ||
628 | .ts_mode = TDA10071_TS_SERIAL, | ||
629 | .spec_inv = 0, | ||
630 | .xtal = 40444000, /* 40.444 MHz */ | ||
631 | .pll_multiplier = 20, | ||
632 | }; | ||
633 | |||
634 | static const struct a8293_config em28xx_a8293_config = { | ||
635 | .i2c_addr = 0x08, /* (0x10 >> 1) */ | ||
636 | }; | ||
637 | |||
638 | static struct zl10353_config em28xx_zl10353_no_i2c_gate_dev = { | ||
639 | .demod_address = (0x1e >> 1), | ||
640 | .disable_i2c_gate_ctrl = 1, | ||
641 | .no_tuner = 1, | ||
642 | .parallel_ts = 1, | ||
643 | }; | ||
644 | static struct qt1010_config em28xx_qt1010_config = { | ||
645 | .i2c_address = 0x62 | ||
646 | |||
647 | }; | ||
648 | |||
649 | /* ------------------------------------------------------------------ */ | ||
650 | |||
651 | static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev) | ||
652 | { | ||
653 | struct dvb_frontend *fe; | ||
654 | struct xc2028_config cfg; | ||
655 | |||
656 | memset(&cfg, 0, sizeof(cfg)); | ||
657 | cfg.i2c_adap = &dev->i2c_adap; | ||
658 | cfg.i2c_addr = addr; | ||
659 | |||
660 | if (!dev->dvb->fe[0]) { | ||
661 | em28xx_errdev("/2: dvb frontend not attached. " | ||
662 | "Can't attach xc3028\n"); | ||
663 | return -EINVAL; | ||
664 | } | ||
665 | |||
666 | fe = dvb_attach(xc2028_attach, dev->dvb->fe[0], &cfg); | ||
667 | if (!fe) { | ||
668 | em28xx_errdev("/2: xc3028 attach failed\n"); | ||
669 | dvb_frontend_detach(dev->dvb->fe[0]); | ||
670 | dev->dvb->fe[0] = NULL; | ||
671 | return -EINVAL; | ||
672 | } | ||
673 | |||
674 | em28xx_info("%s/2: xc3028 attached\n", dev->name); | ||
675 | |||
676 | return 0; | ||
677 | } | ||
678 | |||
679 | /* ------------------------------------------------------------------ */ | ||
680 | |||
681 | static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, | ||
682 | struct em28xx *dev, struct device *device) | ||
683 | { | ||
684 | int result; | ||
685 | |||
686 | mutex_init(&dvb->lock); | ||
687 | |||
688 | /* register adapter */ | ||
689 | result = dvb_register_adapter(&dvb->adapter, dev->name, module, device, | ||
690 | adapter_nr); | ||
691 | if (result < 0) { | ||
692 | printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", | ||
693 | dev->name, result); | ||
694 | goto fail_adapter; | ||
695 | } | ||
696 | |||
697 | /* Ensure all frontends negotiate bus access */ | ||
698 | dvb->fe[0]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl; | ||
699 | if (dvb->fe[1]) | ||
700 | dvb->fe[1]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl; | ||
701 | |||
702 | dvb->adapter.priv = dev; | ||
703 | |||
704 | /* register frontend */ | ||
705 | result = dvb_register_frontend(&dvb->adapter, dvb->fe[0]); | ||
706 | if (result < 0) { | ||
707 | printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", | ||
708 | dev->name, result); | ||
709 | goto fail_frontend0; | ||
710 | } | ||
711 | |||
712 | /* register 2nd frontend */ | ||
713 | if (dvb->fe[1]) { | ||
714 | result = dvb_register_frontend(&dvb->adapter, dvb->fe[1]); | ||
715 | if (result < 0) { | ||
716 | printk(KERN_WARNING "%s: 2nd dvb_register_frontend failed (errno = %d)\n", | ||
717 | dev->name, result); | ||
718 | goto fail_frontend1; | ||
719 | } | ||
720 | } | ||
721 | |||
722 | /* register demux stuff */ | ||
723 | dvb->demux.dmx.capabilities = | ||
724 | DMX_TS_FILTERING | DMX_SECTION_FILTERING | | ||
725 | DMX_MEMORY_BASED_FILTERING; | ||
726 | dvb->demux.priv = dvb; | ||
727 | dvb->demux.filternum = 256; | ||
728 | dvb->demux.feednum = 256; | ||
729 | dvb->demux.start_feed = em28xx_start_feed; | ||
730 | dvb->demux.stop_feed = em28xx_stop_feed; | ||
731 | |||
732 | result = dvb_dmx_init(&dvb->demux); | ||
733 | if (result < 0) { | ||
734 | printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n", | ||
735 | dev->name, result); | ||
736 | goto fail_dmx; | ||
737 | } | ||
738 | |||
739 | dvb->dmxdev.filternum = 256; | ||
740 | dvb->dmxdev.demux = &dvb->demux.dmx; | ||
741 | dvb->dmxdev.capabilities = 0; | ||
742 | result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); | ||
743 | if (result < 0) { | ||
744 | printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", | ||
745 | dev->name, result); | ||
746 | goto fail_dmxdev; | ||
747 | } | ||
748 | |||
749 | dvb->fe_hw.source = DMX_FRONTEND_0; | ||
750 | result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
751 | if (result < 0) { | ||
752 | printk(KERN_WARNING "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", | ||
753 | dev->name, result); | ||
754 | goto fail_fe_hw; | ||
755 | } | ||
756 | |||
757 | dvb->fe_mem.source = DMX_MEMORY_FE; | ||
758 | result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); | ||
759 | if (result < 0) { | ||
760 | printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", | ||
761 | dev->name, result); | ||
762 | goto fail_fe_mem; | ||
763 | } | ||
764 | |||
765 | result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
766 | if (result < 0) { | ||
767 | printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n", | ||
768 | dev->name, result); | ||
769 | goto fail_fe_conn; | ||
770 | } | ||
771 | |||
772 | /* register network adapter */ | ||
773 | dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); | ||
774 | return 0; | ||
775 | |||
776 | fail_fe_conn: | ||
777 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); | ||
778 | fail_fe_mem: | ||
779 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
780 | fail_fe_hw: | ||
781 | dvb_dmxdev_release(&dvb->dmxdev); | ||
782 | fail_dmxdev: | ||
783 | dvb_dmx_release(&dvb->demux); | ||
784 | fail_dmx: | ||
785 | if (dvb->fe[1]) | ||
786 | dvb_unregister_frontend(dvb->fe[1]); | ||
787 | dvb_unregister_frontend(dvb->fe[0]); | ||
788 | fail_frontend1: | ||
789 | if (dvb->fe[1]) | ||
790 | dvb_frontend_detach(dvb->fe[1]); | ||
791 | fail_frontend0: | ||
792 | dvb_frontend_detach(dvb->fe[0]); | ||
793 | dvb_unregister_adapter(&dvb->adapter); | ||
794 | fail_adapter: | ||
795 | return result; | ||
796 | } | ||
797 | |||
798 | static void em28xx_unregister_dvb(struct em28xx_dvb *dvb) | ||
799 | { | ||
800 | dvb_net_release(&dvb->net); | ||
801 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); | ||
802 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
803 | dvb_dmxdev_release(&dvb->dmxdev); | ||
804 | dvb_dmx_release(&dvb->demux); | ||
805 | if (dvb->fe[1]) | ||
806 | dvb_unregister_frontend(dvb->fe[1]); | ||
807 | dvb_unregister_frontend(dvb->fe[0]); | ||
808 | if (dvb->fe[1] && !dvb->dont_attach_fe1) | ||
809 | dvb_frontend_detach(dvb->fe[1]); | ||
810 | dvb_frontend_detach(dvb->fe[0]); | ||
811 | dvb_unregister_adapter(&dvb->adapter); | ||
812 | } | ||
813 | |||
814 | static int em28xx_dvb_init(struct em28xx *dev) | ||
815 | { | ||
816 | int result = 0, mfe_shared = 0; | ||
817 | struct em28xx_dvb *dvb; | ||
818 | |||
819 | if (!dev->board.has_dvb) { | ||
820 | /* This device does not support the extension */ | ||
821 | printk(KERN_INFO "em28xx_dvb: This device does not support the extension\n"); | ||
822 | return 0; | ||
823 | } | ||
824 | |||
825 | dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); | ||
826 | |||
827 | if (dvb == NULL) { | ||
828 | em28xx_info("em28xx_dvb: memory allocation failed\n"); | ||
829 | return -ENOMEM; | ||
830 | } | ||
831 | dev->dvb = dvb; | ||
832 | dvb->fe[0] = dvb->fe[1] = NULL; | ||
833 | |||
834 | mutex_lock(&dev->lock); | ||
835 | em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | ||
836 | /* init frontend */ | ||
837 | switch (dev->model) { | ||
838 | case EM2874_BOARD_LEADERSHIP_ISDBT: | ||
839 | dvb->fe[0] = dvb_attach(s921_attach, | ||
840 | &sharp_isdbt, &dev->i2c_adap); | ||
841 | |||
842 | if (!dvb->fe[0]) { | ||
843 | result = -EINVAL; | ||
844 | goto out_free; | ||
845 | } | ||
846 | |||
847 | break; | ||
848 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: | ||
849 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: | ||
850 | case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: | ||
851 | case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: | ||
852 | dvb->fe[0] = dvb_attach(lgdt330x_attach, | ||
853 | &em2880_lgdt3303_dev, | ||
854 | &dev->i2c_adap); | ||
855 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | ||
856 | result = -EINVAL; | ||
857 | goto out_free; | ||
858 | } | ||
859 | break; | ||
860 | case EM2880_BOARD_KWORLD_DVB_310U: | ||
861 | dvb->fe[0] = dvb_attach(zl10353_attach, | ||
862 | &em28xx_zl10353_with_xc3028, | ||
863 | &dev->i2c_adap); | ||
864 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | ||
865 | result = -EINVAL; | ||
866 | goto out_free; | ||
867 | } | ||
868 | break; | ||
869 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
870 | case EM2882_BOARD_TERRATEC_HYBRID_XS: | ||
871 | case EM2880_BOARD_EMPIRE_DUAL_TV: | ||
872 | dvb->fe[0] = dvb_attach(zl10353_attach, | ||
873 | &em28xx_zl10353_xc3028_no_i2c_gate, | ||
874 | &dev->i2c_adap); | ||
875 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | ||
876 | result = -EINVAL; | ||
877 | goto out_free; | ||
878 | } | ||
879 | break; | ||
880 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | ||
881 | case EM2880_BOARD_TERRATEC_HYBRID_XS_FR: | ||
882 | case EM2881_BOARD_PINNACLE_HYBRID_PRO: | ||
883 | case EM2882_BOARD_DIKOM_DK300: | ||
884 | case EM2882_BOARD_KWORLD_VS_DVBT: | ||
885 | dvb->fe[0] = dvb_attach(zl10353_attach, | ||
886 | &em28xx_zl10353_xc3028_no_i2c_gate, | ||
887 | &dev->i2c_adap); | ||
888 | if (dvb->fe[0] == NULL) { | ||
889 | /* This board could have either a zl10353 or a mt352. | ||
890 | If the chip id isn't for zl10353, try mt352 */ | ||
891 | dvb->fe[0] = dvb_attach(mt352_attach, | ||
892 | &terratec_xs_mt352_cfg, | ||
893 | &dev->i2c_adap); | ||
894 | } | ||
895 | |||
896 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | ||
897 | result = -EINVAL; | ||
898 | goto out_free; | ||
899 | } | ||
900 | break; | ||
901 | case EM2870_BOARD_KWORLD_355U: | ||
902 | dvb->fe[0] = dvb_attach(zl10353_attach, | ||
903 | &em28xx_zl10353_no_i2c_gate_dev, | ||
904 | &dev->i2c_adap); | ||
905 | if (dvb->fe[0] != NULL) | ||
906 | dvb_attach(qt1010_attach, dvb->fe[0], | ||
907 | &dev->i2c_adap, &em28xx_qt1010_config); | ||
908 | break; | ||
909 | case EM2883_BOARD_KWORLD_HYBRID_330U: | ||
910 | case EM2882_BOARD_EVGA_INDTUBE: | ||
911 | dvb->fe[0] = dvb_attach(s5h1409_attach, | ||
912 | &em28xx_s5h1409_with_xc3028, | ||
913 | &dev->i2c_adap); | ||
914 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | ||
915 | result = -EINVAL; | ||
916 | goto out_free; | ||
917 | } | ||
918 | break; | ||
919 | case EM2882_BOARD_KWORLD_ATSC_315U: | ||
920 | dvb->fe[0] = dvb_attach(lgdt330x_attach, | ||
921 | &em2880_lgdt3303_dev, | ||
922 | &dev->i2c_adap); | ||
923 | if (dvb->fe[0] != NULL) { | ||
924 | if (!dvb_attach(simple_tuner_attach, dvb->fe[0], | ||
925 | &dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) { | ||
926 | result = -EINVAL; | ||
927 | goto out_free; | ||
928 | } | ||
929 | } | ||
930 | break; | ||
931 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: | ||
932 | case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E: | ||
933 | dvb->fe[0] = dvb_attach(drxd_attach, &em28xx_drxd, NULL, | ||
934 | &dev->i2c_adap, &dev->udev->dev); | ||
935 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | ||
936 | result = -EINVAL; | ||
937 | goto out_free; | ||
938 | } | ||
939 | break; | ||
940 | case EM2870_BOARD_REDDO_DVB_C_USB_BOX: | ||
941 | /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */ | ||
942 | dvb->fe[0] = dvb_attach(tda10023_attach, | ||
943 | &em28xx_tda10023_config, | ||
944 | &dev->i2c_adap, 0x48); | ||
945 | if (dvb->fe[0]) { | ||
946 | if (!dvb_attach(simple_tuner_attach, dvb->fe[0], | ||
947 | &dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) { | ||
948 | result = -EINVAL; | ||
949 | goto out_free; | ||
950 | } | ||
951 | } | ||
952 | break; | ||
953 | case EM2870_BOARD_KWORLD_A340: | ||
954 | dvb->fe[0] = dvb_attach(lgdt3305_attach, | ||
955 | &em2870_lgdt3304_dev, | ||
956 | &dev->i2c_adap); | ||
957 | if (dvb->fe[0] != NULL) | ||
958 | dvb_attach(tda18271_attach, dvb->fe[0], 0x60, | ||
959 | &dev->i2c_adap, &kworld_a340_config); | ||
960 | break; | ||
961 | case EM28174_BOARD_PCTV_290E: | ||
962 | dvb->fe[0] = dvb_attach(cxd2820r_attach, | ||
963 | &em28xx_cxd2820r_config, | ||
964 | &dev->i2c_adap); | ||
965 | if (dvb->fe[0]) { | ||
966 | /* FE 0 attach tuner */ | ||
967 | if (!dvb_attach(tda18271_attach, | ||
968 | dvb->fe[0], | ||
969 | 0x60, | ||
970 | &dev->i2c_adap, | ||
971 | &em28xx_cxd2820r_tda18271_config)) { | ||
972 | |||
973 | dvb_frontend_detach(dvb->fe[0]); | ||
974 | result = -EINVAL; | ||
975 | goto out_free; | ||
976 | } | ||
977 | } | ||
978 | break; | ||
979 | case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: | ||
980 | { | ||
981 | struct xc5000_config cfg; | ||
982 | hauppauge_hvr930c_init(dev); | ||
983 | |||
984 | dvb->fe[0] = dvb_attach(drxk_attach, | ||
985 | &hauppauge_930c_drxk, &dev->i2c_adap); | ||
986 | if (!dvb->fe[0]) { | ||
987 | result = -EINVAL; | ||
988 | goto out_free; | ||
989 | } | ||
990 | /* FIXME: do we need a pll semaphore? */ | ||
991 | dvb->fe[0]->sec_priv = dvb; | ||
992 | sema_init(&dvb->pll_mutex, 1); | ||
993 | dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl; | ||
994 | dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; | ||
995 | |||
996 | /* Attach xc5000 */ | ||
997 | memset(&cfg, 0, sizeof(cfg)); | ||
998 | cfg.i2c_address = 0x61; | ||
999 | cfg.if_khz = 4000; | ||
1000 | |||
1001 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | ||
1002 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); | ||
1003 | if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap, | ||
1004 | &cfg)) { | ||
1005 | result = -EINVAL; | ||
1006 | goto out_free; | ||
1007 | } | ||
1008 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | ||
1009 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0); | ||
1010 | |||
1011 | break; | ||
1012 | } | ||
1013 | case EM2884_BOARD_TERRATEC_H5: | ||
1014 | terratec_h5_init(dev); | ||
1015 | |||
1016 | dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, &dev->i2c_adap); | ||
1017 | if (!dvb->fe[0]) { | ||
1018 | result = -EINVAL; | ||
1019 | goto out_free; | ||
1020 | } | ||
1021 | /* FIXME: do we need a pll semaphore? */ | ||
1022 | dvb->fe[0]->sec_priv = dvb; | ||
1023 | sema_init(&dvb->pll_mutex, 1); | ||
1024 | dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl; | ||
1025 | dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; | ||
1026 | |||
1027 | /* Attach tda18271 to DVB-C frontend */ | ||
1028 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | ||
1029 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); | ||
1030 | if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], &dev->i2c_adap, 0x60)) { | ||
1031 | result = -EINVAL; | ||
1032 | goto out_free; | ||
1033 | } | ||
1034 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | ||
1035 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0); | ||
1036 | |||
1037 | break; | ||
1038 | case EM28174_BOARD_PCTV_460E: | ||
1039 | /* attach demod */ | ||
1040 | dvb->fe[0] = dvb_attach(tda10071_attach, | ||
1041 | &em28xx_tda10071_config, &dev->i2c_adap); | ||
1042 | |||
1043 | /* attach SEC */ | ||
1044 | if (dvb->fe[0]) | ||
1045 | dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap, | ||
1046 | &em28xx_a8293_config); | ||
1047 | break; | ||
1048 | case EM2874_BOARD_MAXMEDIA_UB425_TC: | ||
1049 | /* attach demodulator */ | ||
1050 | dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk, | ||
1051 | &dev->i2c_adap); | ||
1052 | |||
1053 | if (dvb->fe[0]) { | ||
1054 | /* disable I2C-gate */ | ||
1055 | dvb->fe[0]->ops.i2c_gate_ctrl = NULL; | ||
1056 | |||
1057 | /* attach tuner */ | ||
1058 | if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], | ||
1059 | &dev->i2c_adap, 0x60)) { | ||
1060 | dvb_frontend_detach(dvb->fe[0]); | ||
1061 | result = -EINVAL; | ||
1062 | goto out_free; | ||
1063 | } | ||
1064 | } | ||
1065 | |||
1066 | /* TODO: we need drx-3913k firmware in order to support DVB-T */ | ||
1067 | em28xx_info("MaxMedia UB425-TC: only DVB-C supported by that " \ | ||
1068 | "driver version\n"); | ||
1069 | |||
1070 | break; | ||
1071 | case EM2884_BOARD_PCTV_510E: | ||
1072 | case EM2884_BOARD_PCTV_520E: | ||
1073 | pctv_520e_init(dev); | ||
1074 | |||
1075 | /* attach demodulator */ | ||
1076 | dvb->fe[0] = dvb_attach(drxk_attach, &pctv_520e_drxk, | ||
1077 | &dev->i2c_adap); | ||
1078 | |||
1079 | if (dvb->fe[0]) { | ||
1080 | /* attach tuner */ | ||
1081 | if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, | ||
1082 | &dev->i2c_adap, | ||
1083 | &em28xx_cxd2820r_tda18271_config)) { | ||
1084 | dvb_frontend_detach(dvb->fe[0]); | ||
1085 | result = -EINVAL; | ||
1086 | goto out_free; | ||
1087 | } | ||
1088 | } | ||
1089 | break; | ||
1090 | case EM2884_BOARD_CINERGY_HTC_STICK: | ||
1091 | terratec_htc_stick_init(dev); | ||
1092 | |||
1093 | /* attach demodulator */ | ||
1094 | dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk, | ||
1095 | &dev->i2c_adap); | ||
1096 | if (!dvb->fe[0]) { | ||
1097 | result = -EINVAL; | ||
1098 | goto out_free; | ||
1099 | } | ||
1100 | |||
1101 | /* Attach the demodulator. */ | ||
1102 | if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, | ||
1103 | &dev->i2c_adap, | ||
1104 | &em28xx_cxd2820r_tda18271_config)) { | ||
1105 | result = -EINVAL; | ||
1106 | goto out_free; | ||
1107 | } | ||
1108 | break; | ||
1109 | default: | ||
1110 | em28xx_errdev("/2: The frontend of your DVB/ATSC card" | ||
1111 | " isn't supported yet\n"); | ||
1112 | break; | ||
1113 | } | ||
1114 | if (NULL == dvb->fe[0]) { | ||
1115 | em28xx_errdev("/2: frontend initialization failed\n"); | ||
1116 | result = -EINVAL; | ||
1117 | goto out_free; | ||
1118 | } | ||
1119 | /* define general-purpose callback pointer */ | ||
1120 | dvb->fe[0]->callback = em28xx_tuner_callback; | ||
1121 | if (dvb->fe[1]) | ||
1122 | dvb->fe[1]->callback = em28xx_tuner_callback; | ||
1123 | |||
1124 | /* register everything */ | ||
1125 | result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); | ||
1126 | |||
1127 | if (result < 0) | ||
1128 | goto out_free; | ||
1129 | |||
1130 | /* MFE lock */ | ||
1131 | dvb->adapter.mfe_shared = mfe_shared; | ||
1132 | |||
1133 | em28xx_info("Successfully loaded em28xx-dvb\n"); | ||
1134 | ret: | ||
1135 | em28xx_set_mode(dev, EM28XX_SUSPEND); | ||
1136 | mutex_unlock(&dev->lock); | ||
1137 | return result; | ||
1138 | |||
1139 | out_free: | ||
1140 | kfree(dvb); | ||
1141 | dev->dvb = NULL; | ||
1142 | goto ret; | ||
1143 | } | ||
1144 | |||
1145 | static inline void prevent_sleep(struct dvb_frontend_ops *ops) | ||
1146 | { | ||
1147 | ops->set_voltage = NULL; | ||
1148 | ops->sleep = NULL; | ||
1149 | ops->tuner_ops.sleep = NULL; | ||
1150 | } | ||
1151 | |||
1152 | static int em28xx_dvb_fini(struct em28xx *dev) | ||
1153 | { | ||
1154 | if (!dev->board.has_dvb) { | ||
1155 | /* This device does not support the extension */ | ||
1156 | return 0; | ||
1157 | } | ||
1158 | |||
1159 | if (dev->dvb) { | ||
1160 | struct em28xx_dvb *dvb = dev->dvb; | ||
1161 | |||
1162 | if (dev->state & DEV_DISCONNECTED) { | ||
1163 | /* We cannot tell the device to sleep | ||
1164 | * once it has been unplugged. */ | ||
1165 | if (dvb->fe[0]) | ||
1166 | prevent_sleep(&dvb->fe[0]->ops); | ||
1167 | if (dvb->fe[1]) | ||
1168 | prevent_sleep(&dvb->fe[1]->ops); | ||
1169 | } | ||
1170 | |||
1171 | em28xx_unregister_dvb(dvb); | ||
1172 | kfree(dvb); | ||
1173 | dev->dvb = NULL; | ||
1174 | } | ||
1175 | |||
1176 | return 0; | ||
1177 | } | ||
1178 | |||
1179 | static struct em28xx_ops dvb_ops = { | ||
1180 | .id = EM28XX_DVB, | ||
1181 | .name = "Em28xx dvb Extension", | ||
1182 | .init = em28xx_dvb_init, | ||
1183 | .fini = em28xx_dvb_fini, | ||
1184 | }; | ||
1185 | |||
1186 | static int __init em28xx_dvb_register(void) | ||
1187 | { | ||
1188 | return em28xx_register_extension(&dvb_ops); | ||
1189 | } | ||
1190 | |||
1191 | static void __exit em28xx_dvb_unregister(void) | ||
1192 | { | ||
1193 | em28xx_unregister_extension(&dvb_ops); | ||
1194 | } | ||
1195 | |||
1196 | module_init(em28xx_dvb_register); | ||
1197 | module_exit(em28xx_dvb_unregister); | ||
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c deleted file mode 100644 index 1683bd9d51ee..000000000000 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ /dev/null | |||
@@ -1,568 +0,0 @@ | |||
1 | /* | ||
2 | em28xx-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices | ||
3 | |||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | ||
5 | Markus Rechberger <mrechberger@gmail.com> | ||
6 | Mauro Carvalho Chehab <mchehab@infradead.org> | ||
7 | Sascha Sommer <saschasommer@freenet.de> | ||
8 | |||
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 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/usb.h> | ||
27 | #include <linux/i2c.h> | ||
28 | |||
29 | #include "em28xx.h" | ||
30 | #include "tuner-xc2028.h" | ||
31 | #include <media/v4l2-common.h> | ||
32 | #include <media/tuner.h> | ||
33 | |||
34 | /* ----------------------------------------------------------- */ | ||
35 | |||
36 | static unsigned int i2c_scan; | ||
37 | module_param(i2c_scan, int, 0444); | ||
38 | MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); | ||
39 | |||
40 | static unsigned int i2c_debug; | ||
41 | module_param(i2c_debug, int, 0644); | ||
42 | MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); | ||
43 | |||
44 | #define dprintk2(lvl, fmt, args...) \ | ||
45 | do { \ | ||
46 | if (i2c_debug >= lvl) { \ | ||
47 | printk(KERN_DEBUG "%s at %s: " fmt, \ | ||
48 | dev->name, __func__ , ##args); \ | ||
49 | } \ | ||
50 | } while (0) | ||
51 | |||
52 | /* | ||
53 | * em2800_i2c_send_max4() | ||
54 | * send up to 4 bytes to the i2c device | ||
55 | */ | ||
56 | static int em2800_i2c_send_max4(struct em28xx *dev, unsigned char addr, | ||
57 | char *buf, int len) | ||
58 | { | ||
59 | int ret; | ||
60 | int write_timeout; | ||
61 | unsigned char b2[6]; | ||
62 | BUG_ON(len < 1 || len > 4); | ||
63 | b2[5] = 0x80 + len - 1; | ||
64 | b2[4] = addr; | ||
65 | b2[3] = buf[0]; | ||
66 | if (len > 1) | ||
67 | b2[2] = buf[1]; | ||
68 | if (len > 2) | ||
69 | b2[1] = buf[2]; | ||
70 | if (len > 3) | ||
71 | b2[0] = buf[3]; | ||
72 | |||
73 | ret = dev->em28xx_write_regs(dev, 4 - len, &b2[4 - len], 2 + len); | ||
74 | if (ret != 2 + len) { | ||
75 | em28xx_warn("writing to i2c device failed (error=%i)\n", ret); | ||
76 | return -EIO; | ||
77 | } | ||
78 | for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0; | ||
79 | write_timeout -= 5) { | ||
80 | ret = dev->em28xx_read_reg(dev, 0x05); | ||
81 | if (ret == 0x80 + len - 1) | ||
82 | return len; | ||
83 | msleep(5); | ||
84 | } | ||
85 | em28xx_warn("i2c write timed out\n"); | ||
86 | return -EIO; | ||
87 | } | ||
88 | |||
89 | /* | ||
90 | * em2800_i2c_send_bytes() | ||
91 | */ | ||
92 | static int em2800_i2c_send_bytes(void *data, unsigned char addr, char *buf, | ||
93 | short len) | ||
94 | { | ||
95 | char *bufPtr = buf; | ||
96 | int ret; | ||
97 | int wrcount = 0; | ||
98 | int count; | ||
99 | int maxLen = 4; | ||
100 | struct em28xx *dev = (struct em28xx *)data; | ||
101 | while (len > 0) { | ||
102 | count = (len > maxLen) ? maxLen : len; | ||
103 | ret = em2800_i2c_send_max4(dev, addr, bufPtr, count); | ||
104 | if (ret > 0) { | ||
105 | len -= count; | ||
106 | bufPtr += count; | ||
107 | wrcount += count; | ||
108 | } else | ||
109 | return (ret < 0) ? ret : -EFAULT; | ||
110 | } | ||
111 | return wrcount; | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * em2800_i2c_check_for_device() | ||
116 | * check if there is a i2c_device at the supplied address | ||
117 | */ | ||
118 | static int em2800_i2c_check_for_device(struct em28xx *dev, unsigned char addr) | ||
119 | { | ||
120 | char msg; | ||
121 | int ret; | ||
122 | int write_timeout; | ||
123 | msg = addr; | ||
124 | ret = dev->em28xx_write_regs(dev, 0x04, &msg, 1); | ||
125 | if (ret < 0) { | ||
126 | em28xx_warn("setting i2c device address failed (error=%i)\n", | ||
127 | ret); | ||
128 | return ret; | ||
129 | } | ||
130 | msg = 0x84; | ||
131 | ret = dev->em28xx_write_regs(dev, 0x05, &msg, 1); | ||
132 | if (ret < 0) { | ||
133 | em28xx_warn("preparing i2c read failed (error=%i)\n", ret); | ||
134 | return ret; | ||
135 | } | ||
136 | for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0; | ||
137 | write_timeout -= 5) { | ||
138 | unsigned reg = dev->em28xx_read_reg(dev, 0x5); | ||
139 | |||
140 | if (reg == 0x94) | ||
141 | return -ENODEV; | ||
142 | else if (reg == 0x84) | ||
143 | return 0; | ||
144 | msleep(5); | ||
145 | } | ||
146 | return -ENODEV; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * em2800_i2c_recv_bytes() | ||
151 | * read from the i2c device | ||
152 | */ | ||
153 | static int em2800_i2c_recv_bytes(struct em28xx *dev, unsigned char addr, | ||
154 | char *buf, int len) | ||
155 | { | ||
156 | int ret; | ||
157 | /* check for the device and set i2c read address */ | ||
158 | ret = em2800_i2c_check_for_device(dev, addr); | ||
159 | if (ret) { | ||
160 | em28xx_warn | ||
161 | ("preparing read at i2c address 0x%x failed (error=%i)\n", | ||
162 | addr, ret); | ||
163 | return ret; | ||
164 | } | ||
165 | ret = dev->em28xx_read_reg_req_len(dev, 0x0, 0x3, buf, len); | ||
166 | if (ret < 0) { | ||
167 | em28xx_warn("reading from i2c device at 0x%x failed (error=%i)", | ||
168 | addr, ret); | ||
169 | return ret; | ||
170 | } | ||
171 | return ret; | ||
172 | } | ||
173 | |||
174 | /* | ||
175 | * em28xx_i2c_send_bytes() | ||
176 | */ | ||
177 | static int em28xx_i2c_send_bytes(void *data, unsigned char addr, char *buf, | ||
178 | short len, int stop) | ||
179 | { | ||
180 | int wrcount = 0; | ||
181 | struct em28xx *dev = (struct em28xx *)data; | ||
182 | int write_timeout, ret; | ||
183 | |||
184 | wrcount = dev->em28xx_write_regs_req(dev, stop ? 2 : 3, addr, buf, len); | ||
185 | |||
186 | /* Seems to be required after a write */ | ||
187 | for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0; | ||
188 | write_timeout -= 5) { | ||
189 | ret = dev->em28xx_read_reg(dev, 0x05); | ||
190 | if (!ret) | ||
191 | break; | ||
192 | msleep(5); | ||
193 | } | ||
194 | |||
195 | return wrcount; | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * em28xx_i2c_recv_bytes() | ||
200 | * read a byte from the i2c device | ||
201 | */ | ||
202 | static int em28xx_i2c_recv_bytes(struct em28xx *dev, unsigned char addr, | ||
203 | char *buf, int len) | ||
204 | { | ||
205 | int ret; | ||
206 | ret = dev->em28xx_read_reg_req_len(dev, 2, addr, buf, len); | ||
207 | if (ret < 0) { | ||
208 | em28xx_warn("reading i2c device failed (error=%i)\n", ret); | ||
209 | return ret; | ||
210 | } | ||
211 | if (dev->em28xx_read_reg(dev, 0x5) != 0) | ||
212 | return -ENODEV; | ||
213 | return ret; | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * em28xx_i2c_check_for_device() | ||
218 | * check if there is a i2c_device at the supplied address | ||
219 | */ | ||
220 | static int em28xx_i2c_check_for_device(struct em28xx *dev, unsigned char addr) | ||
221 | { | ||
222 | int ret; | ||
223 | |||
224 | ret = dev->em28xx_read_reg_req(dev, 2, addr); | ||
225 | if (ret < 0) { | ||
226 | em28xx_warn("reading from i2c device failed (error=%i)\n", ret); | ||
227 | return ret; | ||
228 | } | ||
229 | if (dev->em28xx_read_reg(dev, 0x5) != 0) | ||
230 | return -ENODEV; | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | /* | ||
235 | * em28xx_i2c_xfer() | ||
236 | * the main i2c transfer function | ||
237 | */ | ||
238 | static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, | ||
239 | struct i2c_msg msgs[], int num) | ||
240 | { | ||
241 | struct em28xx *dev = i2c_adap->algo_data; | ||
242 | int addr, rc, i, byte; | ||
243 | |||
244 | if (num <= 0) | ||
245 | return 0; | ||
246 | for (i = 0; i < num; i++) { | ||
247 | addr = msgs[i].addr << 1; | ||
248 | dprintk2(2, "%s %s addr=%x len=%d:", | ||
249 | (msgs[i].flags & I2C_M_RD) ? "read" : "write", | ||
250 | i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); | ||
251 | if (!msgs[i].len) { /* no len: check only for device presence */ | ||
252 | if (dev->board.is_em2800) | ||
253 | rc = em2800_i2c_check_for_device(dev, addr); | ||
254 | else | ||
255 | rc = em28xx_i2c_check_for_device(dev, addr); | ||
256 | if (rc < 0) { | ||
257 | dprintk2(2, " no device\n"); | ||
258 | return rc; | ||
259 | } | ||
260 | |||
261 | } else if (msgs[i].flags & I2C_M_RD) { | ||
262 | /* read bytes */ | ||
263 | if (dev->board.is_em2800) | ||
264 | rc = em2800_i2c_recv_bytes(dev, addr, | ||
265 | msgs[i].buf, | ||
266 | msgs[i].len); | ||
267 | else | ||
268 | rc = em28xx_i2c_recv_bytes(dev, addr, | ||
269 | msgs[i].buf, | ||
270 | msgs[i].len); | ||
271 | if (i2c_debug >= 2) { | ||
272 | for (byte = 0; byte < msgs[i].len; byte++) | ||
273 | printk(" %02x", msgs[i].buf[byte]); | ||
274 | } | ||
275 | } else { | ||
276 | /* write bytes */ | ||
277 | if (i2c_debug >= 2) { | ||
278 | for (byte = 0; byte < msgs[i].len; byte++) | ||
279 | printk(" %02x", msgs[i].buf[byte]); | ||
280 | } | ||
281 | if (dev->board.is_em2800) | ||
282 | rc = em2800_i2c_send_bytes(dev, addr, | ||
283 | msgs[i].buf, | ||
284 | msgs[i].len); | ||
285 | else | ||
286 | rc = em28xx_i2c_send_bytes(dev, addr, | ||
287 | msgs[i].buf, | ||
288 | msgs[i].len, | ||
289 | i == num - 1); | ||
290 | } | ||
291 | if (rc < 0) | ||
292 | goto err; | ||
293 | if (i2c_debug >= 2) | ||
294 | printk("\n"); | ||
295 | } | ||
296 | |||
297 | return num; | ||
298 | err: | ||
299 | dprintk2(2, " ERROR: %i\n", rc); | ||
300 | return rc; | ||
301 | } | ||
302 | |||
303 | /* based on linux/sunrpc/svcauth.h and linux/hash.h | ||
304 | * The original hash function returns a different value, if arch is x86_64 | ||
305 | * or i386. | ||
306 | */ | ||
307 | static inline unsigned long em28xx_hash_mem(char *buf, int length, int bits) | ||
308 | { | ||
309 | unsigned long hash = 0; | ||
310 | unsigned long l = 0; | ||
311 | int len = 0; | ||
312 | unsigned char c; | ||
313 | do { | ||
314 | if (len == length) { | ||
315 | c = (char)len; | ||
316 | len = -1; | ||
317 | } else | ||
318 | c = *buf++; | ||
319 | l = (l << 8) | c; | ||
320 | len++; | ||
321 | if ((len & (32 / 8 - 1)) == 0) | ||
322 | hash = ((hash^l) * 0x9e370001UL); | ||
323 | } while (len); | ||
324 | |||
325 | return (hash >> (32 - bits)) & 0xffffffffUL; | ||
326 | } | ||
327 | |||
328 | static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) | ||
329 | { | ||
330 | unsigned char buf, *p = eedata; | ||
331 | struct em28xx_eeprom *em_eeprom = (void *)eedata; | ||
332 | int i, err, size = len, block; | ||
333 | |||
334 | if (dev->chip_id == CHIP_ID_EM2874 || | ||
335 | dev->chip_id == CHIP_ID_EM28174 || | ||
336 | dev->chip_id == CHIP_ID_EM2884) { | ||
337 | /* Empia switched to a 16-bit addressable eeprom in newer | ||
338 | devices. While we could certainly write a routine to read | ||
339 | the eeprom, there is nothing of use in there that cannot be | ||
340 | accessed through registers, and there is the risk that we | ||
341 | could corrupt the eeprom (since a 16-bit read call is | ||
342 | interpreted as a write call by 8-bit eeproms). | ||
343 | */ | ||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | dev->i2c_client.addr = 0xa0 >> 1; | ||
348 | |||
349 | /* Check if board has eeprom */ | ||
350 | err = i2c_master_recv(&dev->i2c_client, &buf, 0); | ||
351 | if (err < 0) { | ||
352 | em28xx_errdev("board has no eeprom\n"); | ||
353 | memset(eedata, 0, len); | ||
354 | return -ENODEV; | ||
355 | } | ||
356 | |||
357 | buf = 0; | ||
358 | |||
359 | err = i2c_master_send(&dev->i2c_client, &buf, 1); | ||
360 | if (err != 1) { | ||
361 | printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", | ||
362 | dev->name, err); | ||
363 | return err; | ||
364 | } | ||
365 | while (size > 0) { | ||
366 | if (size > 16) | ||
367 | block = 16; | ||
368 | else | ||
369 | block = size; | ||
370 | |||
371 | if (block != | ||
372 | (err = i2c_master_recv(&dev->i2c_client, p, block))) { | ||
373 | printk(KERN_WARNING | ||
374 | "%s: i2c eeprom read error (err=%d)\n", | ||
375 | dev->name, err); | ||
376 | return err; | ||
377 | } | ||
378 | size -= block; | ||
379 | p += block; | ||
380 | } | ||
381 | for (i = 0; i < len; i++) { | ||
382 | if (0 == (i % 16)) | ||
383 | printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i); | ||
384 | printk(" %02x", eedata[i]); | ||
385 | if (15 == (i % 16)) | ||
386 | printk("\n"); | ||
387 | } | ||
388 | |||
389 | if (em_eeprom->id == 0x9567eb1a) | ||
390 | dev->hash = em28xx_hash_mem(eedata, len, 32); | ||
391 | |||
392 | printk(KERN_INFO "%s: EEPROM ID= 0x%08x, EEPROM hash = 0x%08lx\n", | ||
393 | dev->name, em_eeprom->id, dev->hash); | ||
394 | |||
395 | printk(KERN_INFO "%s: EEPROM info:\n", dev->name); | ||
396 | |||
397 | switch (em_eeprom->chip_conf >> 4 & 0x3) { | ||
398 | case 0: | ||
399 | printk(KERN_INFO "%s:\tNo audio on board.\n", dev->name); | ||
400 | break; | ||
401 | case 1: | ||
402 | printk(KERN_INFO "%s:\tAC97 audio (5 sample rates)\n", | ||
403 | dev->name); | ||
404 | break; | ||
405 | case 2: | ||
406 | printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n", | ||
407 | dev->name); | ||
408 | break; | ||
409 | case 3: | ||
410 | printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n", | ||
411 | dev->name); | ||
412 | break; | ||
413 | } | ||
414 | |||
415 | if (em_eeprom->chip_conf & 1 << 3) | ||
416 | printk(KERN_INFO "%s:\tUSB Remote wakeup capable\n", dev->name); | ||
417 | |||
418 | if (em_eeprom->chip_conf & 1 << 2) | ||
419 | printk(KERN_INFO "%s:\tUSB Self power capable\n", dev->name); | ||
420 | |||
421 | switch (em_eeprom->chip_conf & 0x3) { | ||
422 | case 0: | ||
423 | printk(KERN_INFO "%s:\t500mA max power\n", dev->name); | ||
424 | break; | ||
425 | case 1: | ||
426 | printk(KERN_INFO "%s:\t400mA max power\n", dev->name); | ||
427 | break; | ||
428 | case 2: | ||
429 | printk(KERN_INFO "%s:\t300mA max power\n", dev->name); | ||
430 | break; | ||
431 | case 3: | ||
432 | printk(KERN_INFO "%s:\t200mA max power\n", dev->name); | ||
433 | break; | ||
434 | } | ||
435 | printk(KERN_INFO "%s:\tTable at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", | ||
436 | dev->name, | ||
437 | em_eeprom->string_idx_table, | ||
438 | em_eeprom->string1, | ||
439 | em_eeprom->string2, | ||
440 | em_eeprom->string3); | ||
441 | |||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | /* ----------------------------------------------------------- */ | ||
446 | |||
447 | /* | ||
448 | * functionality() | ||
449 | */ | ||
450 | static u32 functionality(struct i2c_adapter *adap) | ||
451 | { | ||
452 | return I2C_FUNC_SMBUS_EMUL; | ||
453 | } | ||
454 | |||
455 | static struct i2c_algorithm em28xx_algo = { | ||
456 | .master_xfer = em28xx_i2c_xfer, | ||
457 | .functionality = functionality, | ||
458 | }; | ||
459 | |||
460 | static struct i2c_adapter em28xx_adap_template = { | ||
461 | .owner = THIS_MODULE, | ||
462 | .name = "em28xx", | ||
463 | .algo = &em28xx_algo, | ||
464 | }; | ||
465 | |||
466 | static struct i2c_client em28xx_client_template = { | ||
467 | .name = "em28xx internal", | ||
468 | }; | ||
469 | |||
470 | /* ----------------------------------------------------------- */ | ||
471 | |||
472 | /* | ||
473 | * i2c_devs | ||
474 | * incomplete list of known devices | ||
475 | */ | ||
476 | static char *i2c_devs[128] = { | ||
477 | [0x4a >> 1] = "saa7113h", | ||
478 | [0x52 >> 1] = "drxk", | ||
479 | [0x60 >> 1] = "remote IR sensor", | ||
480 | [0x8e >> 1] = "remote IR sensor", | ||
481 | [0x86 >> 1] = "tda9887", | ||
482 | [0x80 >> 1] = "msp34xx", | ||
483 | [0x88 >> 1] = "msp34xx", | ||
484 | [0xa0 >> 1] = "eeprom", | ||
485 | [0xb0 >> 1] = "tda9874", | ||
486 | [0xb8 >> 1] = "tvp5150a", | ||
487 | [0xba >> 1] = "webcam sensor or tvp5150a", | ||
488 | [0xc0 >> 1] = "tuner (analog)", | ||
489 | [0xc2 >> 1] = "tuner (analog)", | ||
490 | [0xc4 >> 1] = "tuner (analog)", | ||
491 | [0xc6 >> 1] = "tuner (analog)", | ||
492 | }; | ||
493 | |||
494 | /* | ||
495 | * do_i2c_scan() | ||
496 | * check i2c address range for devices | ||
497 | */ | ||
498 | void em28xx_do_i2c_scan(struct em28xx *dev) | ||
499 | { | ||
500 | u8 i2c_devicelist[128]; | ||
501 | unsigned char buf; | ||
502 | int i, rc; | ||
503 | |||
504 | memset(i2c_devicelist, 0, ARRAY_SIZE(i2c_devicelist)); | ||
505 | |||
506 | for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) { | ||
507 | dev->i2c_client.addr = i; | ||
508 | rc = i2c_master_recv(&dev->i2c_client, &buf, 0); | ||
509 | if (rc < 0) | ||
510 | continue; | ||
511 | i2c_devicelist[i] = i; | ||
512 | printk(KERN_INFO "%s: found i2c device @ 0x%x [%s]\n", | ||
513 | dev->name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); | ||
514 | } | ||
515 | |||
516 | dev->i2c_hash = em28xx_hash_mem(i2c_devicelist, | ||
517 | ARRAY_SIZE(i2c_devicelist), 32); | ||
518 | } | ||
519 | |||
520 | /* | ||
521 | * em28xx_i2c_register() | ||
522 | * register i2c bus | ||
523 | */ | ||
524 | int em28xx_i2c_register(struct em28xx *dev) | ||
525 | { | ||
526 | int retval; | ||
527 | |||
528 | BUG_ON(!dev->em28xx_write_regs || !dev->em28xx_read_reg); | ||
529 | BUG_ON(!dev->em28xx_write_regs_req || !dev->em28xx_read_reg_req); | ||
530 | dev->i2c_adap = em28xx_adap_template; | ||
531 | dev->i2c_adap.dev.parent = &dev->udev->dev; | ||
532 | strcpy(dev->i2c_adap.name, dev->name); | ||
533 | dev->i2c_adap.algo_data = dev; | ||
534 | i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev); | ||
535 | |||
536 | retval = i2c_add_adapter(&dev->i2c_adap); | ||
537 | if (retval < 0) { | ||
538 | em28xx_errdev("%s: i2c_add_adapter failed! retval [%d]\n", | ||
539 | __func__, retval); | ||
540 | return retval; | ||
541 | } | ||
542 | |||
543 | dev->i2c_client = em28xx_client_template; | ||
544 | dev->i2c_client.adapter = &dev->i2c_adap; | ||
545 | |||
546 | retval = em28xx_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata)); | ||
547 | if ((retval < 0) && (retval != -ENODEV)) { | ||
548 | em28xx_errdev("%s: em28xx_i2_eeprom failed! retval [%d]\n", | ||
549 | __func__, retval); | ||
550 | |||
551 | return retval; | ||
552 | } | ||
553 | |||
554 | if (i2c_scan) | ||
555 | em28xx_do_i2c_scan(dev); | ||
556 | |||
557 | return 0; | ||
558 | } | ||
559 | |||
560 | /* | ||
561 | * em28xx_i2c_unregister() | ||
562 | * unregister i2c_bus | ||
563 | */ | ||
564 | int em28xx_i2c_unregister(struct em28xx *dev) | ||
565 | { | ||
566 | i2c_del_adapter(&dev->i2c_adap); | ||
567 | return 0; | ||
568 | } | ||
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c deleted file mode 100644 index 97d36b4f19db..000000000000 --- a/drivers/media/video/em28xx/em28xx-input.c +++ /dev/null | |||
@@ -1,645 +0,0 @@ | |||
1 | /* | ||
2 | handle em28xx IR remotes via linux kernel input layer. | ||
3 | |||
4 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | ||
5 | Markus Rechberger <mrechberger@gmail.com> | ||
6 | Mauro Carvalho Chehab <mchehab@infradead.org> | ||
7 | Sascha Sommer <saschasommer@freenet.de> | ||
8 | |||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/interrupt.h> | ||
28 | #include <linux/usb.h> | ||
29 | #include <linux/slab.h> | ||
30 | |||
31 | #include "em28xx.h" | ||
32 | |||
33 | #define EM28XX_SNAPSHOT_KEY KEY_CAMERA | ||
34 | #define EM28XX_SBUTTON_QUERY_INTERVAL 500 | ||
35 | #define EM28XX_R0C_USBSUSP_SNAPSHOT 0x20 | ||
36 | |||
37 | static unsigned int ir_debug; | ||
38 | module_param(ir_debug, int, 0644); | ||
39 | MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); | ||
40 | |||
41 | #define MODULE_NAME "em28xx" | ||
42 | |||
43 | #define i2cdprintk(fmt, arg...) \ | ||
44 | if (ir_debug) { \ | ||
45 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ | ||
46 | } | ||
47 | |||
48 | #define dprintk(fmt, arg...) \ | ||
49 | if (ir_debug) { \ | ||
50 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ | ||
51 | } | ||
52 | |||
53 | /********************************************************** | ||
54 | Polling structure used by em28xx IR's | ||
55 | **********************************************************/ | ||
56 | |||
57 | struct em28xx_ir_poll_result { | ||
58 | unsigned int toggle_bit:1; | ||
59 | unsigned int read_count:7; | ||
60 | u8 rc_address; | ||
61 | u8 rc_data[4]; /* 1 byte on em2860/2880, 4 on em2874 */ | ||
62 | }; | ||
63 | |||
64 | struct em28xx_IR { | ||
65 | struct em28xx *dev; | ||
66 | struct rc_dev *rc; | ||
67 | char name[32]; | ||
68 | char phys[32]; | ||
69 | |||
70 | /* poll external decoder */ | ||
71 | int polling; | ||
72 | struct delayed_work work; | ||
73 | unsigned int full_code:1; | ||
74 | unsigned int last_readcount; | ||
75 | |||
76 | int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); | ||
77 | }; | ||
78 | |||
79 | /********************************************************** | ||
80 | I2C IR based get keycodes - should be used with ir-kbd-i2c | ||
81 | **********************************************************/ | ||
82 | |||
83 | static int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
84 | { | ||
85 | unsigned char b; | ||
86 | |||
87 | /* poll IR chip */ | ||
88 | if (1 != i2c_master_recv(ir->c, &b, 1)) { | ||
89 | i2cdprintk("read error\n"); | ||
90 | return -EIO; | ||
91 | } | ||
92 | |||
93 | /* it seems that 0xFE indicates that a button is still hold | ||
94 | down, while 0xff indicates that no button is hold | ||
95 | down. 0xfe sequences are sometimes interrupted by 0xFF */ | ||
96 | |||
97 | i2cdprintk("key %02x\n", b); | ||
98 | |||
99 | if (b == 0xff) | ||
100 | return 0; | ||
101 | |||
102 | if (b == 0xfe) | ||
103 | /* keep old data */ | ||
104 | return 1; | ||
105 | |||
106 | *ir_key = b; | ||
107 | *ir_raw = b; | ||
108 | return 1; | ||
109 | } | ||
110 | |||
111 | static int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | ||
112 | { | ||
113 | unsigned char buf[2]; | ||
114 | u16 code; | ||
115 | int size; | ||
116 | |||
117 | /* poll IR chip */ | ||
118 | size = i2c_master_recv(ir->c, buf, sizeof(buf)); | ||
119 | |||
120 | if (size != 2) | ||
121 | return -EIO; | ||
122 | |||
123 | /* Does eliminate repeated parity code */ | ||
124 | if (buf[1] == 0xff) | ||
125 | return 0; | ||
126 | |||
127 | ir->old = buf[1]; | ||
128 | |||
129 | /* | ||
130 | * Rearranges bits to the right order. | ||
131 | * The bit order were determined experimentally by using | ||
132 | * The original Hauppauge Grey IR and another RC5 that uses addr=0x08 | ||
133 | * The RC5 code has 14 bits, but we've experimentally determined | ||
134 | * the meaning for only 11 bits. | ||
135 | * So, the code translation is not complete. Yet, it is enough to | ||
136 | * work with the provided RC5 IR. | ||
137 | */ | ||
138 | code = | ||
139 | ((buf[0] & 0x01) ? 0x0020 : 0) | /* 0010 0000 */ | ||
140 | ((buf[0] & 0x02) ? 0x0010 : 0) | /* 0001 0000 */ | ||
141 | ((buf[0] & 0x04) ? 0x0008 : 0) | /* 0000 1000 */ | ||
142 | ((buf[0] & 0x08) ? 0x0004 : 0) | /* 0000 0100 */ | ||
143 | ((buf[0] & 0x10) ? 0x0002 : 0) | /* 0000 0010 */ | ||
144 | ((buf[0] & 0x20) ? 0x0001 : 0) | /* 0000 0001 */ | ||
145 | ((buf[1] & 0x08) ? 0x1000 : 0) | /* 0001 0000 */ | ||
146 | ((buf[1] & 0x10) ? 0x0800 : 0) | /* 0000 1000 */ | ||
147 | ((buf[1] & 0x20) ? 0x0400 : 0) | /* 0000 0100 */ | ||
148 | ((buf[1] & 0x40) ? 0x0200 : 0) | /* 0000 0010 */ | ||
149 | ((buf[1] & 0x80) ? 0x0100 : 0); /* 0000 0001 */ | ||
150 | |||
151 | i2cdprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x%02x)\n", | ||
152 | code, buf[1], buf[0]); | ||
153 | |||
154 | /* return key */ | ||
155 | *ir_key = code; | ||
156 | *ir_raw = code; | ||
157 | return 1; | ||
158 | } | ||
159 | |||
160 | static int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, | ||
161 | u32 *ir_raw) | ||
162 | { | ||
163 | unsigned char buf[3]; | ||
164 | |||
165 | /* poll IR chip */ | ||
166 | |||
167 | if (3 != i2c_master_recv(ir->c, buf, 3)) { | ||
168 | i2cdprintk("read error\n"); | ||
169 | return -EIO; | ||
170 | } | ||
171 | |||
172 | i2cdprintk("key %02x\n", buf[2]&0x3f); | ||
173 | if (buf[0] != 0x00) | ||
174 | return 0; | ||
175 | |||
176 | *ir_key = buf[2]&0x3f; | ||
177 | *ir_raw = buf[2]&0x3f; | ||
178 | |||
179 | return 1; | ||
180 | } | ||
181 | |||
182 | static int em28xx_get_key_winfast_usbii_deluxe(struct IR_i2c *ir, u32 *ir_key, | ||
183 | u32 *ir_raw) | ||
184 | { | ||
185 | unsigned char subaddr, keydetect, key; | ||
186 | |||
187 | struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0, .buf = &subaddr, .len = 1}, | ||
188 | |||
189 | { .addr = ir->c->addr, .flags = I2C_M_RD, .buf = &keydetect, .len = 1} }; | ||
190 | |||
191 | subaddr = 0x10; | ||
192 | if (2 != i2c_transfer(ir->c->adapter, msg, 2)) { | ||
193 | i2cdprintk("read error\n"); | ||
194 | return -EIO; | ||
195 | } | ||
196 | if (keydetect == 0x00) | ||
197 | return 0; | ||
198 | |||
199 | subaddr = 0x00; | ||
200 | msg[1].buf = &key; | ||
201 | if (2 != i2c_transfer(ir->c->adapter, msg, 2)) { | ||
202 | i2cdprintk("read error\n"); | ||
203 | return -EIO; | ||
204 | } | ||
205 | if (key == 0x00) | ||
206 | return 0; | ||
207 | |||
208 | *ir_key = key; | ||
209 | *ir_raw = key; | ||
210 | return 1; | ||
211 | } | ||
212 | |||
213 | /********************************************************** | ||
214 | Poll based get keycode functions | ||
215 | **********************************************************/ | ||
216 | |||
217 | /* This is for the em2860/em2880 */ | ||
218 | static int default_polling_getkey(struct em28xx_IR *ir, | ||
219 | struct em28xx_ir_poll_result *poll_result) | ||
220 | { | ||
221 | struct em28xx *dev = ir->dev; | ||
222 | int rc; | ||
223 | u8 msg[3] = { 0, 0, 0 }; | ||
224 | |||
225 | /* Read key toggle, brand, and key code | ||
226 | on registers 0x45, 0x46 and 0x47 | ||
227 | */ | ||
228 | rc = dev->em28xx_read_reg_req_len(dev, 0, EM28XX_R45_IR, | ||
229 | msg, sizeof(msg)); | ||
230 | if (rc < 0) | ||
231 | return rc; | ||
232 | |||
233 | /* Infrared toggle (Reg 0x45[7]) */ | ||
234 | poll_result->toggle_bit = (msg[0] >> 7); | ||
235 | |||
236 | /* Infrared read count (Reg 0x45[6:0] */ | ||
237 | poll_result->read_count = (msg[0] & 0x7f); | ||
238 | |||
239 | /* Remote Control Address (Reg 0x46) */ | ||
240 | poll_result->rc_address = msg[1]; | ||
241 | |||
242 | /* Remote Control Data (Reg 0x47) */ | ||
243 | poll_result->rc_data[0] = msg[2]; | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | static int em2874_polling_getkey(struct em28xx_IR *ir, | ||
249 | struct em28xx_ir_poll_result *poll_result) | ||
250 | { | ||
251 | struct em28xx *dev = ir->dev; | ||
252 | int rc; | ||
253 | u8 msg[5] = { 0, 0, 0, 0, 0 }; | ||
254 | |||
255 | /* Read key toggle, brand, and key code | ||
256 | on registers 0x51-55 | ||
257 | */ | ||
258 | rc = dev->em28xx_read_reg_req_len(dev, 0, EM2874_R51_IR, | ||
259 | msg, sizeof(msg)); | ||
260 | if (rc < 0) | ||
261 | return rc; | ||
262 | |||
263 | /* Infrared toggle (Reg 0x51[7]) */ | ||
264 | poll_result->toggle_bit = (msg[0] >> 7); | ||
265 | |||
266 | /* Infrared read count (Reg 0x51[6:0] */ | ||
267 | poll_result->read_count = (msg[0] & 0x7f); | ||
268 | |||
269 | /* Remote Control Address (Reg 0x52) */ | ||
270 | poll_result->rc_address = msg[1]; | ||
271 | |||
272 | /* Remote Control Data (Reg 0x53-55) */ | ||
273 | poll_result->rc_data[0] = msg[2]; | ||
274 | poll_result->rc_data[1] = msg[3]; | ||
275 | poll_result->rc_data[2] = msg[4]; | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | /********************************************************** | ||
281 | Polling code for em28xx | ||
282 | **********************************************************/ | ||
283 | |||
284 | static void em28xx_ir_handle_key(struct em28xx_IR *ir) | ||
285 | { | ||
286 | int result; | ||
287 | struct em28xx_ir_poll_result poll_result; | ||
288 | |||
289 | /* read the registers containing the IR status */ | ||
290 | result = ir->get_key(ir, &poll_result); | ||
291 | if (unlikely(result < 0)) { | ||
292 | dprintk("ir->get_key() failed %d\n", result); | ||
293 | return; | ||
294 | } | ||
295 | |||
296 | if (unlikely(poll_result.read_count != ir->last_readcount)) { | ||
297 | dprintk("%s: toggle: %d, count: %d, key 0x%02x%02x\n", __func__, | ||
298 | poll_result.toggle_bit, poll_result.read_count, | ||
299 | poll_result.rc_address, poll_result.rc_data[0]); | ||
300 | if (ir->full_code) | ||
301 | rc_keydown(ir->rc, | ||
302 | poll_result.rc_address << 8 | | ||
303 | poll_result.rc_data[0], | ||
304 | poll_result.toggle_bit); | ||
305 | else | ||
306 | rc_keydown(ir->rc, | ||
307 | poll_result.rc_data[0], | ||
308 | poll_result.toggle_bit); | ||
309 | |||
310 | if (ir->dev->chip_id == CHIP_ID_EM2874 || | ||
311 | ir->dev->chip_id == CHIP_ID_EM2884) | ||
312 | /* The em2874 clears the readcount field every time the | ||
313 | register is read. The em2860/2880 datasheet says that it | ||
314 | is supposed to clear the readcount, but it doesn't. So with | ||
315 | the em2874, we are looking for a non-zero read count as | ||
316 | opposed to a readcount that is incrementing */ | ||
317 | ir->last_readcount = 0; | ||
318 | else | ||
319 | ir->last_readcount = poll_result.read_count; | ||
320 | } | ||
321 | } | ||
322 | |||
323 | static void em28xx_ir_work(struct work_struct *work) | ||
324 | { | ||
325 | struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work.work); | ||
326 | |||
327 | em28xx_ir_handle_key(ir); | ||
328 | schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); | ||
329 | } | ||
330 | |||
331 | static int em28xx_ir_start(struct rc_dev *rc) | ||
332 | { | ||
333 | struct em28xx_IR *ir = rc->priv; | ||
334 | |||
335 | INIT_DELAYED_WORK(&ir->work, em28xx_ir_work); | ||
336 | schedule_delayed_work(&ir->work, 0); | ||
337 | |||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | static void em28xx_ir_stop(struct rc_dev *rc) | ||
342 | { | ||
343 | struct em28xx_IR *ir = rc->priv; | ||
344 | |||
345 | cancel_delayed_work_sync(&ir->work); | ||
346 | } | ||
347 | |||
348 | static int em28xx_ir_change_protocol(struct rc_dev *rc_dev, u64 rc_type) | ||
349 | { | ||
350 | int rc = 0; | ||
351 | struct em28xx_IR *ir = rc_dev->priv; | ||
352 | struct em28xx *dev = ir->dev; | ||
353 | u8 ir_config = EM2874_IR_RC5; | ||
354 | |||
355 | /* Adjust xclk based o IR table for RC5/NEC tables */ | ||
356 | |||
357 | if (rc_type == RC_TYPE_RC5) { | ||
358 | dev->board.xclk |= EM28XX_XCLK_IR_RC5_MODE; | ||
359 | ir->full_code = 1; | ||
360 | } else if (rc_type == RC_TYPE_NEC) { | ||
361 | dev->board.xclk &= ~EM28XX_XCLK_IR_RC5_MODE; | ||
362 | ir_config = EM2874_IR_NEC; | ||
363 | ir->full_code = 1; | ||
364 | } else if (rc_type != RC_TYPE_UNKNOWN) | ||
365 | rc = -EINVAL; | ||
366 | |||
367 | em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, dev->board.xclk, | ||
368 | EM28XX_XCLK_IR_RC5_MODE); | ||
369 | |||
370 | /* Setup the proper handler based on the chip */ | ||
371 | switch (dev->chip_id) { | ||
372 | case CHIP_ID_EM2860: | ||
373 | case CHIP_ID_EM2883: | ||
374 | ir->get_key = default_polling_getkey; | ||
375 | break; | ||
376 | case CHIP_ID_EM2884: | ||
377 | case CHIP_ID_EM2874: | ||
378 | case CHIP_ID_EM28174: | ||
379 | ir->get_key = em2874_polling_getkey; | ||
380 | em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1); | ||
381 | break; | ||
382 | default: | ||
383 | printk("Unrecognized em28xx chip id 0x%02x: IR not supported\n", | ||
384 | dev->chip_id); | ||
385 | rc = -EINVAL; | ||
386 | } | ||
387 | |||
388 | return rc; | ||
389 | } | ||
390 | |||
391 | static void em28xx_register_i2c_ir(struct em28xx *dev) | ||
392 | { | ||
393 | /* Leadtek winfast tv USBII deluxe can find a non working IR-device */ | ||
394 | /* at address 0x18, so if that address is needed for another board in */ | ||
395 | /* the future, please put it after 0x1f. */ | ||
396 | struct i2c_board_info info; | ||
397 | const unsigned short addr_list[] = { | ||
398 | 0x1f, 0x30, 0x47, I2C_CLIENT_END | ||
399 | }; | ||
400 | |||
401 | memset(&info, 0, sizeof(struct i2c_board_info)); | ||
402 | memset(&dev->init_data, 0, sizeof(dev->init_data)); | ||
403 | strlcpy(info.type, "ir_video", I2C_NAME_SIZE); | ||
404 | |||
405 | /* detect & configure */ | ||
406 | switch (dev->model) { | ||
407 | case EM2800_BOARD_TERRATEC_CINERGY_200: | ||
408 | case EM2820_BOARD_TERRATEC_CINERGY_250: | ||
409 | dev->init_data.ir_codes = RC_MAP_EM_TERRATEC; | ||
410 | dev->init_data.get_key = em28xx_get_key_terratec; | ||
411 | dev->init_data.name = "i2c IR (EM28XX Terratec)"; | ||
412 | break; | ||
413 | case EM2820_BOARD_PINNACLE_USB_2: | ||
414 | dev->init_data.ir_codes = RC_MAP_PINNACLE_GREY; | ||
415 | dev->init_data.get_key = em28xx_get_key_pinnacle_usb_grey; | ||
416 | dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)"; | ||
417 | break; | ||
418 | case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: | ||
419 | dev->init_data.ir_codes = RC_MAP_HAUPPAUGE; | ||
420 | dev->init_data.get_key = em28xx_get_key_em_haup; | ||
421 | dev->init_data.name = "i2c IR (EM2840 Hauppauge)"; | ||
422 | break; | ||
423 | case EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE: | ||
424 | dev->init_data.ir_codes = RC_MAP_WINFAST_USBII_DELUXE; | ||
425 | dev->init_data.get_key = em28xx_get_key_winfast_usbii_deluxe; | ||
426 | dev->init_data.name = "i2c IR (EM2820 Winfast TV USBII Deluxe)"; | ||
427 | break; | ||
428 | } | ||
429 | |||
430 | if (dev->init_data.name) | ||
431 | info.platform_data = &dev->init_data; | ||
432 | i2c_new_probed_device(&dev->i2c_adap, &info, addr_list, NULL); | ||
433 | } | ||
434 | |||
435 | /********************************************************** | ||
436 | Handle Webcam snapshot button | ||
437 | **********************************************************/ | ||
438 | |||
439 | static void em28xx_query_sbutton(struct work_struct *work) | ||
440 | { | ||
441 | /* Poll the register and see if the button is depressed */ | ||
442 | struct em28xx *dev = | ||
443 | container_of(work, struct em28xx, sbutton_query_work.work); | ||
444 | int ret; | ||
445 | |||
446 | ret = em28xx_read_reg(dev, EM28XX_R0C_USBSUSP); | ||
447 | |||
448 | if (ret & EM28XX_R0C_USBSUSP_SNAPSHOT) { | ||
449 | u8 cleared; | ||
450 | /* Button is depressed, clear the register */ | ||
451 | cleared = ((u8) ret) & ~EM28XX_R0C_USBSUSP_SNAPSHOT; | ||
452 | em28xx_write_regs(dev, EM28XX_R0C_USBSUSP, &cleared, 1); | ||
453 | |||
454 | /* Not emulate the keypress */ | ||
455 | input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY, | ||
456 | 1); | ||
457 | /* Now unpress the key */ | ||
458 | input_report_key(dev->sbutton_input_dev, EM28XX_SNAPSHOT_KEY, | ||
459 | 0); | ||
460 | } | ||
461 | |||
462 | /* Schedule next poll */ | ||
463 | schedule_delayed_work(&dev->sbutton_query_work, | ||
464 | msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL)); | ||
465 | } | ||
466 | |||
467 | static void em28xx_register_snapshot_button(struct em28xx *dev) | ||
468 | { | ||
469 | struct input_dev *input_dev; | ||
470 | int err; | ||
471 | |||
472 | em28xx_info("Registering snapshot button...\n"); | ||
473 | input_dev = input_allocate_device(); | ||
474 | if (!input_dev) { | ||
475 | em28xx_errdev("input_allocate_device failed\n"); | ||
476 | return; | ||
477 | } | ||
478 | |||
479 | usb_make_path(dev->udev, dev->snapshot_button_path, | ||
480 | sizeof(dev->snapshot_button_path)); | ||
481 | strlcat(dev->snapshot_button_path, "/sbutton", | ||
482 | sizeof(dev->snapshot_button_path)); | ||
483 | INIT_DELAYED_WORK(&dev->sbutton_query_work, em28xx_query_sbutton); | ||
484 | |||
485 | input_dev->name = "em28xx snapshot button"; | ||
486 | input_dev->phys = dev->snapshot_button_path; | ||
487 | input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); | ||
488 | set_bit(EM28XX_SNAPSHOT_KEY, input_dev->keybit); | ||
489 | input_dev->keycodesize = 0; | ||
490 | input_dev->keycodemax = 0; | ||
491 | input_dev->id.bustype = BUS_USB; | ||
492 | input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); | ||
493 | input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); | ||
494 | input_dev->id.version = 1; | ||
495 | input_dev->dev.parent = &dev->udev->dev; | ||
496 | |||
497 | err = input_register_device(input_dev); | ||
498 | if (err) { | ||
499 | em28xx_errdev("input_register_device failed\n"); | ||
500 | input_free_device(input_dev); | ||
501 | return; | ||
502 | } | ||
503 | |||
504 | dev->sbutton_input_dev = input_dev; | ||
505 | schedule_delayed_work(&dev->sbutton_query_work, | ||
506 | msecs_to_jiffies(EM28XX_SBUTTON_QUERY_INTERVAL)); | ||
507 | return; | ||
508 | |||
509 | } | ||
510 | |||
511 | static void em28xx_deregister_snapshot_button(struct em28xx *dev) | ||
512 | { | ||
513 | if (dev->sbutton_input_dev != NULL) { | ||
514 | em28xx_info("Deregistering snapshot button\n"); | ||
515 | cancel_delayed_work_sync(&dev->sbutton_query_work); | ||
516 | input_unregister_device(dev->sbutton_input_dev); | ||
517 | dev->sbutton_input_dev = NULL; | ||
518 | } | ||
519 | return; | ||
520 | } | ||
521 | |||
522 | static int em28xx_ir_init(struct em28xx *dev) | ||
523 | { | ||
524 | struct em28xx_IR *ir; | ||
525 | struct rc_dev *rc; | ||
526 | int err = -ENOMEM; | ||
527 | |||
528 | if (dev->board.ir_codes == NULL) { | ||
529 | /* No remote control support */ | ||
530 | em28xx_warn("Remote control support is not available for " | ||
531 | "this card.\n"); | ||
532 | return 0; | ||
533 | } | ||
534 | |||
535 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); | ||
536 | rc = rc_allocate_device(); | ||
537 | if (!ir || !rc) | ||
538 | goto err_out_free; | ||
539 | |||
540 | /* record handles to ourself */ | ||
541 | ir->dev = dev; | ||
542 | dev->ir = ir; | ||
543 | ir->rc = rc; | ||
544 | |||
545 | /* | ||
546 | * em2874 supports more protocols. For now, let's just announce | ||
547 | * the two protocols that were already tested | ||
548 | */ | ||
549 | rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC; | ||
550 | rc->priv = ir; | ||
551 | rc->change_protocol = em28xx_ir_change_protocol; | ||
552 | rc->open = em28xx_ir_start; | ||
553 | rc->close = em28xx_ir_stop; | ||
554 | |||
555 | /* By default, keep protocol field untouched */ | ||
556 | err = em28xx_ir_change_protocol(rc, RC_TYPE_UNKNOWN); | ||
557 | if (err) | ||
558 | goto err_out_free; | ||
559 | |||
560 | /* This is how often we ask the chip for IR information */ | ||
561 | ir->polling = 100; /* ms */ | ||
562 | |||
563 | /* init input device */ | ||
564 | snprintf(ir->name, sizeof(ir->name), "em28xx IR (%s)", | ||
565 | dev->name); | ||
566 | |||
567 | usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); | ||
568 | strlcat(ir->phys, "/input0", sizeof(ir->phys)); | ||
569 | |||
570 | rc->input_name = ir->name; | ||
571 | rc->input_phys = ir->phys; | ||
572 | rc->input_id.bustype = BUS_USB; | ||
573 | rc->input_id.version = 1; | ||
574 | rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); | ||
575 | rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct); | ||
576 | rc->dev.parent = &dev->udev->dev; | ||
577 | rc->map_name = dev->board.ir_codes; | ||
578 | rc->driver_name = MODULE_NAME; | ||
579 | |||
580 | /* all done */ | ||
581 | err = rc_register_device(rc); | ||
582 | if (err) | ||
583 | goto err_out_stop; | ||
584 | |||
585 | em28xx_register_i2c_ir(dev); | ||
586 | |||
587 | #if defined(CONFIG_MODULES) && defined(MODULE) | ||
588 | if (dev->board.has_ir_i2c) | ||
589 | request_module("ir-kbd-i2c"); | ||
590 | #endif | ||
591 | if (dev->board.has_snapshot_button) | ||
592 | em28xx_register_snapshot_button(dev); | ||
593 | |||
594 | return 0; | ||
595 | |||
596 | err_out_stop: | ||
597 | dev->ir = NULL; | ||
598 | err_out_free: | ||
599 | rc_free_device(rc); | ||
600 | kfree(ir); | ||
601 | return err; | ||
602 | } | ||
603 | |||
604 | static int em28xx_ir_fini(struct em28xx *dev) | ||
605 | { | ||
606 | struct em28xx_IR *ir = dev->ir; | ||
607 | |||
608 | em28xx_deregister_snapshot_button(dev); | ||
609 | |||
610 | /* skip detach on non attached boards */ | ||
611 | if (!ir) | ||
612 | return 0; | ||
613 | |||
614 | if (ir->rc) | ||
615 | rc_unregister_device(ir->rc); | ||
616 | |||
617 | /* done */ | ||
618 | kfree(ir); | ||
619 | dev->ir = NULL; | ||
620 | return 0; | ||
621 | } | ||
622 | |||
623 | static struct em28xx_ops rc_ops = { | ||
624 | .id = EM28XX_RC, | ||
625 | .name = "Em28xx Input Extension", | ||
626 | .init = em28xx_ir_init, | ||
627 | .fini = em28xx_ir_fini, | ||
628 | }; | ||
629 | |||
630 | static int __init em28xx_rc_register(void) | ||
631 | { | ||
632 | return em28xx_register_extension(&rc_ops); | ||
633 | } | ||
634 | |||
635 | static void __exit em28xx_rc_unregister(void) | ||
636 | { | ||
637 | em28xx_unregister_extension(&rc_ops); | ||
638 | } | ||
639 | |||
640 | MODULE_LICENSE("GPL"); | ||
641 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); | ||
642 | MODULE_DESCRIPTION("Em28xx Input driver"); | ||
643 | |||
644 | module_init(em28xx_rc_register); | ||
645 | module_exit(em28xx_rc_unregister); | ||
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h deleted file mode 100644 index 6ff368297f6e..000000000000 --- a/drivers/media/video/em28xx/em28xx-reg.h +++ /dev/null | |||
@@ -1,226 +0,0 @@ | |||
1 | #define EM_GPIO_0 (1 << 0) | ||
2 | #define EM_GPIO_1 (1 << 1) | ||
3 | #define EM_GPIO_2 (1 << 2) | ||
4 | #define EM_GPIO_3 (1 << 3) | ||
5 | #define EM_GPIO_4 (1 << 4) | ||
6 | #define EM_GPIO_5 (1 << 5) | ||
7 | #define EM_GPIO_6 (1 << 6) | ||
8 | #define EM_GPIO_7 (1 << 7) | ||
9 | |||
10 | #define EM_GPO_0 (1 << 0) | ||
11 | #define EM_GPO_1 (1 << 1) | ||
12 | #define EM_GPO_2 (1 << 2) | ||
13 | #define EM_GPO_3 (1 << 3) | ||
14 | |||
15 | /* em28xx endpoints */ | ||
16 | #define EM28XX_EP_ANALOG 0x82 | ||
17 | #define EM28XX_EP_AUDIO 0x83 | ||
18 | #define EM28XX_EP_DIGITAL 0x84 | ||
19 | |||
20 | /* em2800 registers */ | ||
21 | #define EM2800_R08_AUDIOSRC 0x08 | ||
22 | |||
23 | /* em28xx registers */ | ||
24 | |||
25 | #define EM28XX_R00_CHIPCFG 0x00 | ||
26 | |||
27 | /* em28xx Chip Configuration 0x00 */ | ||
28 | #define EM28XX_CHIPCFG_VENDOR_AUDIO 0x80 | ||
29 | #define EM28XX_CHIPCFG_I2S_VOLUME_CAPABLE 0x40 | ||
30 | #define EM28XX_CHIPCFG_I2S_5_SAMPRATES 0x30 | ||
31 | #define EM28XX_CHIPCFG_I2S_3_SAMPRATES 0x20 | ||
32 | #define EM28XX_CHIPCFG_AC97 0x10 | ||
33 | #define EM28XX_CHIPCFG_AUDIOMASK 0x30 | ||
34 | |||
35 | #define EM28XX_R01_CHIPCFG2 0x01 | ||
36 | |||
37 | /* em28xx Chip Configuration 2 0x01 */ | ||
38 | #define EM28XX_CHIPCFG2_TS_PRESENT 0x10 | ||
39 | #define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_MASK 0x0c /* bits 3-2 */ | ||
40 | #define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_1MF 0x00 | ||
41 | #define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_2MF 0x04 | ||
42 | #define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_4MF 0x08 | ||
43 | #define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_8MF 0x0c | ||
44 | #define EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK 0x03 /* bits 0-1 */ | ||
45 | #define EM28XX_CHIPCFG2_TS_PACKETSIZE_188 0x00 | ||
46 | #define EM28XX_CHIPCFG2_TS_PACKETSIZE_376 0x01 | ||
47 | #define EM28XX_CHIPCFG2_TS_PACKETSIZE_564 0x02 | ||
48 | #define EM28XX_CHIPCFG2_TS_PACKETSIZE_752 0x03 | ||
49 | |||
50 | |||
51 | /* GPIO/GPO registers */ | ||
52 | #define EM2880_R04_GPO 0x04 /* em2880-em2883 only */ | ||
53 | #define EM28XX_R08_GPIO 0x08 /* em2820 or upper */ | ||
54 | |||
55 | #define EM28XX_R06_I2C_CLK 0x06 | ||
56 | |||
57 | /* em28xx I2C Clock Register (0x06) */ | ||
58 | #define EM28XX_I2C_CLK_ACK_LAST_READ 0x80 | ||
59 | #define EM28XX_I2C_CLK_WAIT_ENABLE 0x40 | ||
60 | #define EM28XX_I2C_EEPROM_ON_BOARD 0x08 | ||
61 | #define EM28XX_I2C_EEPROM_KEY_VALID 0x04 | ||
62 | #define EM2874_I2C_SECONDARY_BUS_SELECT 0x04 /* em2874 has two i2c busses */ | ||
63 | #define EM28XX_I2C_FREQ_1_5_MHZ 0x03 /* bus frequency (bits [1-0]) */ | ||
64 | #define EM28XX_I2C_FREQ_25_KHZ 0x02 | ||
65 | #define EM28XX_I2C_FREQ_400_KHZ 0x01 | ||
66 | #define EM28XX_I2C_FREQ_100_KHZ 0x00 | ||
67 | |||
68 | |||
69 | #define EM28XX_R0A_CHIPID 0x0a | ||
70 | #define EM28XX_R0C_USBSUSP 0x0c /* */ | ||
71 | |||
72 | #define EM28XX_R0E_AUDIOSRC 0x0e | ||
73 | #define EM28XX_R0F_XCLK 0x0f | ||
74 | |||
75 | /* em28xx XCLK Register (0x0f) */ | ||
76 | #define EM28XX_XCLK_AUDIO_UNMUTE 0x80 /* otherwise audio muted */ | ||
77 | #define EM28XX_XCLK_I2S_MSB_TIMING 0x40 /* otherwise standard timing */ | ||
78 | #define EM28XX_XCLK_IR_RC5_MODE 0x20 /* otherwise NEC mode */ | ||
79 | #define EM28XX_XCLK_IR_NEC_CHK_PARITY 0x10 | ||
80 | #define EM28XX_XCLK_FREQUENCY_30MHZ 0x00 /* Freq. select (bits [3-0]) */ | ||
81 | #define EM28XX_XCLK_FREQUENCY_15MHZ 0x01 | ||
82 | #define EM28XX_XCLK_FREQUENCY_10MHZ 0x02 | ||
83 | #define EM28XX_XCLK_FREQUENCY_7_5MHZ 0x03 | ||
84 | #define EM28XX_XCLK_FREQUENCY_6MHZ 0x04 | ||
85 | #define EM28XX_XCLK_FREQUENCY_5MHZ 0x05 | ||
86 | #define EM28XX_XCLK_FREQUENCY_4_3MHZ 0x06 | ||
87 | #define EM28XX_XCLK_FREQUENCY_12MHZ 0x07 | ||
88 | #define EM28XX_XCLK_FREQUENCY_20MHZ 0x08 | ||
89 | #define EM28XX_XCLK_FREQUENCY_20MHZ_2 0x09 | ||
90 | #define EM28XX_XCLK_FREQUENCY_48MHZ 0x0a | ||
91 | #define EM28XX_XCLK_FREQUENCY_24MHZ 0x0b | ||
92 | |||
93 | #define EM28XX_R10_VINMODE 0x10 | ||
94 | |||
95 | #define EM28XX_R11_VINCTRL 0x11 | ||
96 | |||
97 | /* em28xx Video Input Control Register 0x11 */ | ||
98 | #define EM28XX_VINCTRL_VBI_SLICED 0x80 | ||
99 | #define EM28XX_VINCTRL_VBI_RAW 0x40 | ||
100 | #define EM28XX_VINCTRL_VOUT_MODE_IN 0x20 /* HREF,VREF,VACT in output */ | ||
101 | #define EM28XX_VINCTRL_CCIR656_ENABLE 0x10 | ||
102 | #define EM28XX_VINCTRL_VBI_16BIT_RAW 0x08 /* otherwise 8-bit raw */ | ||
103 | #define EM28XX_VINCTRL_FID_ON_HREF 0x04 | ||
104 | #define EM28XX_VINCTRL_DUAL_EDGE_STROBE 0x02 | ||
105 | #define EM28XX_VINCTRL_INTERLACED 0x01 | ||
106 | |||
107 | #define EM28XX_R12_VINENABLE 0x12 /* */ | ||
108 | |||
109 | #define EM28XX_R14_GAMMA 0x14 | ||
110 | #define EM28XX_R15_RGAIN 0x15 | ||
111 | #define EM28XX_R16_GGAIN 0x16 | ||
112 | #define EM28XX_R17_BGAIN 0x17 | ||
113 | #define EM28XX_R18_ROFFSET 0x18 | ||
114 | #define EM28XX_R19_GOFFSET 0x19 | ||
115 | #define EM28XX_R1A_BOFFSET 0x1a | ||
116 | |||
117 | #define EM28XX_R1B_OFLOW 0x1b | ||
118 | #define EM28XX_R1C_HSTART 0x1c | ||
119 | #define EM28XX_R1D_VSTART 0x1d | ||
120 | #define EM28XX_R1E_CWIDTH 0x1e | ||
121 | #define EM28XX_R1F_CHEIGHT 0x1f | ||
122 | |||
123 | #define EM28XX_R20_YGAIN 0x20 | ||
124 | #define EM28XX_R21_YOFFSET 0x21 | ||
125 | #define EM28XX_R22_UVGAIN 0x22 | ||
126 | #define EM28XX_R23_UOFFSET 0x23 | ||
127 | #define EM28XX_R24_VOFFSET 0x24 | ||
128 | #define EM28XX_R25_SHARPNESS 0x25 | ||
129 | |||
130 | #define EM28XX_R26_COMPR 0x26 | ||
131 | #define EM28XX_R27_OUTFMT 0x27 | ||
132 | |||
133 | /* em28xx Output Format Register (0x27) */ | ||
134 | #define EM28XX_OUTFMT_RGB_8_RGRG 0x00 | ||
135 | #define EM28XX_OUTFMT_RGB_8_GRGR 0x01 | ||
136 | #define EM28XX_OUTFMT_RGB_8_GBGB 0x02 | ||
137 | #define EM28XX_OUTFMT_RGB_8_BGBG 0x03 | ||
138 | #define EM28XX_OUTFMT_RGB_16_656 0x04 | ||
139 | #define EM28XX_OUTFMT_RGB_8_BAYER 0x08 /* Pattern in Reg 0x10[1-0] */ | ||
140 | #define EM28XX_OUTFMT_YUV211 0x10 | ||
141 | #define EM28XX_OUTFMT_YUV422_Y0UY1V 0x14 | ||
142 | #define EM28XX_OUTFMT_YUV422_Y1UY0V 0x15 | ||
143 | #define EM28XX_OUTFMT_YUV411 0x18 | ||
144 | |||
145 | |||
146 | #define EM28XX_R28_XMIN 0x28 | ||
147 | #define EM28XX_R29_XMAX 0x29 | ||
148 | #define EM28XX_R2A_YMIN 0x2a | ||
149 | #define EM28XX_R2B_YMAX 0x2b | ||
150 | |||
151 | #define EM28XX_R30_HSCALELOW 0x30 | ||
152 | #define EM28XX_R31_HSCALEHIGH 0x31 | ||
153 | #define EM28XX_R32_VSCALELOW 0x32 | ||
154 | #define EM28XX_R33_VSCALEHIGH 0x33 | ||
155 | #define EM28XX_R34_VBI_START_H 0x34 | ||
156 | #define EM28XX_R35_VBI_START_V 0x35 | ||
157 | #define EM28XX_R36_VBI_WIDTH 0x36 | ||
158 | #define EM28XX_R37_VBI_HEIGHT 0x37 | ||
159 | |||
160 | #define EM28XX_R40_AC97LSB 0x40 | ||
161 | #define EM28XX_R41_AC97MSB 0x41 | ||
162 | #define EM28XX_R42_AC97ADDR 0x42 | ||
163 | #define EM28XX_R43_AC97BUSY 0x43 | ||
164 | |||
165 | #define EM28XX_R45_IR 0x45 | ||
166 | /* 0x45 bit 7 - parity bit | ||
167 | bits 6-0 - count | ||
168 | 0x46 IR brand | ||
169 | 0x47 IR data | ||
170 | */ | ||
171 | |||
172 | /* em2874 registers */ | ||
173 | #define EM2874_R50_IR_CONFIG 0x50 | ||
174 | #define EM2874_R51_IR 0x51 | ||
175 | #define EM2874_R5F_TS_ENABLE 0x5f | ||
176 | #define EM2874_R80_GPIO 0x80 | ||
177 | |||
178 | /* em2874 IR config register (0x50) */ | ||
179 | #define EM2874_IR_NEC 0x00 | ||
180 | #define EM2874_IR_RC5 0x04 | ||
181 | #define EM2874_IR_RC6_MODE_0 0x08 | ||
182 | #define EM2874_IR_RC6_MODE_6A 0x0b | ||
183 | |||
184 | /* em2874 Transport Stream Enable Register (0x5f) */ | ||
185 | #define EM2874_TS1_CAPTURE_ENABLE (1 << 0) | ||
186 | #define EM2874_TS1_FILTER_ENABLE (1 << 1) | ||
187 | #define EM2874_TS1_NULL_DISCARD (1 << 2) | ||
188 | #define EM2874_TS2_CAPTURE_ENABLE (1 << 4) | ||
189 | #define EM2874_TS2_FILTER_ENABLE (1 << 5) | ||
190 | #define EM2874_TS2_NULL_DISCARD (1 << 6) | ||
191 | |||
192 | /* register settings */ | ||
193 | #define EM2800_AUDIO_SRC_TUNER 0x0d | ||
194 | #define EM2800_AUDIO_SRC_LINE 0x0c | ||
195 | #define EM28XX_AUDIO_SRC_TUNER 0xc0 | ||
196 | #define EM28XX_AUDIO_SRC_LINE 0x80 | ||
197 | |||
198 | /* FIXME: Need to be populated with the other chip ID's */ | ||
199 | enum em28xx_chip_id { | ||
200 | CHIP_ID_EM2800 = 7, | ||
201 | CHIP_ID_EM2710 = 17, | ||
202 | CHIP_ID_EM2820 = 18, /* Also used by some em2710 */ | ||
203 | CHIP_ID_EM2840 = 20, | ||
204 | CHIP_ID_EM2750 = 33, | ||
205 | CHIP_ID_EM2860 = 34, | ||
206 | CHIP_ID_EM2870 = 35, | ||
207 | CHIP_ID_EM2883 = 36, | ||
208 | CHIP_ID_EM2874 = 65, | ||
209 | CHIP_ID_EM2884 = 68, | ||
210 | CHIP_ID_EM28174 = 113, | ||
211 | }; | ||
212 | |||
213 | /* | ||
214 | * Registers used by em202 | ||
215 | */ | ||
216 | |||
217 | /* EMP202 vendor registers */ | ||
218 | #define EM202_EXT_MODEM_CTRL 0x3e | ||
219 | #define EM202_GPIO_CONF 0x4c | ||
220 | #define EM202_GPIO_POLARITY 0x4e | ||
221 | #define EM202_GPIO_STICKY 0x50 | ||
222 | #define EM202_GPIO_MASK 0x52 | ||
223 | #define EM202_GPIO_STATUS 0x54 | ||
224 | #define EM202_SPDIF_OUT_SEL 0x6a | ||
225 | #define EM202_ANTIPOP 0x72 | ||
226 | #define EM202_EAPD_GPIO_ACCESS 0x74 | ||
diff --git a/drivers/media/video/em28xx/em28xx-vbi.c b/drivers/media/video/em28xx/em28xx-vbi.c deleted file mode 100644 index 2b4c9cba2d67..000000000000 --- a/drivers/media/video/em28xx/em28xx-vbi.c +++ /dev/null | |||
@@ -1,145 +0,0 @@ | |||
1 | /* | ||
2 | em28xx-vbi.c - VBI driver for em28xx | ||
3 | |||
4 | Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com> | ||
5 | |||
6 | This work was sponsored by EyeMagnet Limited. | ||
7 | |||
8 | This program is free software; you can redistribute it and/or modify | ||
9 | it under the terms of the GNU General Public License as published by | ||
10 | the Free Software Foundation; either version 2 of the License, or | ||
11 | (at your option) any later version. | ||
12 | |||
13 | This program is distributed in the hope that it will be useful, | ||
14 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | GNU General Public License for more details. | ||
17 | |||
18 | You should have received a copy of the GNU General Public License | ||
19 | along with this program; if not, write to the Free Software | ||
20 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
21 | 02110-1301, USA. | ||
22 | */ | ||
23 | |||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/module.h> | ||
26 | #include <linux/hardirq.h> | ||
27 | #include <linux/init.h> | ||
28 | |||
29 | #include "em28xx.h" | ||
30 | |||
31 | static unsigned int vbibufs = 5; | ||
32 | module_param(vbibufs, int, 0644); | ||
33 | MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32"); | ||
34 | |||
35 | static unsigned int vbi_debug; | ||
36 | module_param(vbi_debug, int, 0644); | ||
37 | MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]"); | ||
38 | |||
39 | #define dprintk(level, fmt, arg...) if (vbi_debug >= level) \ | ||
40 | printk(KERN_DEBUG "%s: " fmt, dev->core->name , ## arg) | ||
41 | |||
42 | /* ------------------------------------------------------------------ */ | ||
43 | |||
44 | static void | ||
45 | free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf) | ||
46 | { | ||
47 | struct em28xx_fh *fh = vq->priv_data; | ||
48 | struct em28xx *dev = fh->dev; | ||
49 | unsigned long flags = 0; | ||
50 | if (in_interrupt()) | ||
51 | BUG(); | ||
52 | |||
53 | /* We used to wait for the buffer to finish here, but this didn't work | ||
54 | because, as we were keeping the state as VIDEOBUF_QUEUED, | ||
55 | videobuf_queue_cancel marked it as finished for us. | ||
56 | (Also, it could wedge forever if the hardware was misconfigured.) | ||
57 | |||
58 | This should be safe; by the time we get here, the buffer isn't | ||
59 | queued anymore. If we ever start marking the buffers as | ||
60 | VIDEOBUF_ACTIVE, it won't be, though. | ||
61 | */ | ||
62 | spin_lock_irqsave(&dev->slock, flags); | ||
63 | if (dev->isoc_ctl.vbi_buf == buf) | ||
64 | dev->isoc_ctl.vbi_buf = NULL; | ||
65 | spin_unlock_irqrestore(&dev->slock, flags); | ||
66 | |||
67 | videobuf_vmalloc_free(&buf->vb); | ||
68 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | ||
69 | } | ||
70 | |||
71 | static int | ||
72 | vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) | ||
73 | { | ||
74 | struct em28xx_fh *fh = q->priv_data; | ||
75 | struct em28xx *dev = fh->dev; | ||
76 | |||
77 | *size = dev->vbi_width * dev->vbi_height * 2; | ||
78 | |||
79 | if (0 == *count) | ||
80 | *count = vbibufs; | ||
81 | if (*count < 2) | ||
82 | *count = 2; | ||
83 | if (*count > 32) | ||
84 | *count = 32; | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | static int | ||
89 | vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, | ||
90 | enum v4l2_field field) | ||
91 | { | ||
92 | struct em28xx_fh *fh = q->priv_data; | ||
93 | struct em28xx *dev = fh->dev; | ||
94 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); | ||
95 | int rc = 0; | ||
96 | |||
97 | buf->vb.size = dev->vbi_width * dev->vbi_height * 2; | ||
98 | |||
99 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | ||
100 | return -EINVAL; | ||
101 | |||
102 | buf->vb.width = dev->vbi_width; | ||
103 | buf->vb.height = dev->vbi_height; | ||
104 | buf->vb.field = field; | ||
105 | |||
106 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | ||
107 | rc = videobuf_iolock(q, &buf->vb, NULL); | ||
108 | if (rc < 0) | ||
109 | goto fail; | ||
110 | } | ||
111 | |||
112 | buf->vb.state = VIDEOBUF_PREPARED; | ||
113 | return 0; | ||
114 | |||
115 | fail: | ||
116 | free_buffer(q, buf); | ||
117 | return rc; | ||
118 | } | ||
119 | |||
120 | static void | ||
121 | vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | ||
122 | { | ||
123 | struct em28xx_buffer *buf = container_of(vb, | ||
124 | struct em28xx_buffer, | ||
125 | vb); | ||
126 | struct em28xx_fh *fh = vq->priv_data; | ||
127 | struct em28xx *dev = fh->dev; | ||
128 | struct em28xx_dmaqueue *vbiq = &dev->vbiq; | ||
129 | |||
130 | buf->vb.state = VIDEOBUF_QUEUED; | ||
131 | list_add_tail(&buf->vb.queue, &vbiq->active); | ||
132 | } | ||
133 | |||
134 | static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb) | ||
135 | { | ||
136 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); | ||
137 | free_buffer(q, buf); | ||
138 | } | ||
139 | |||
140 | struct videobuf_queue_ops em28xx_vbi_qops = { | ||
141 | .buf_setup = vbi_setup, | ||
142 | .buf_prepare = vbi_prepare, | ||
143 | .buf_queue = vbi_queue, | ||
144 | .buf_release = vbi_release, | ||
145 | }; | ||
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c deleted file mode 100644 index ecb23df7f16e..000000000000 --- a/drivers/media/video/em28xx/em28xx-video.c +++ /dev/null | |||
@@ -1,2624 +0,0 @@ | |||
1 | /* | ||
2 | em28xx-video.c - driver for Empia EM2800/EM2820/2840 USB | ||
3 | video capture devices | ||
4 | |||
5 | Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> | ||
6 | Markus Rechberger <mrechberger@gmail.com> | ||
7 | Mauro Carvalho Chehab <mchehab@infradead.org> | ||
8 | Sascha Sommer <saschasommer@freenet.de> | ||
9 | |||
10 | Some parts based on SN9C10x PC Camera Controllers GPL driver made | ||
11 | by Luca Risolia <luca.risolia@studio.unibo.it> | ||
12 | |||
13 | This program is free software; you can redistribute it and/or modify | ||
14 | it under the terms of the GNU General Public License as published by | ||
15 | the Free Software Foundation; either version 2 of the License, or | ||
16 | (at your option) any later version. | ||
17 | |||
18 | This program is distributed in the hope that it will be useful, | ||
19 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | GNU General Public License for more details. | ||
22 | |||
23 | You should have received a copy of the GNU General Public License | ||
24 | along with this program; if not, write to the Free Software | ||
25 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
26 | */ | ||
27 | |||
28 | #include <linux/init.h> | ||
29 | #include <linux/list.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/bitmap.h> | ||
33 | #include <linux/usb.h> | ||
34 | #include <linux/i2c.h> | ||
35 | #include <linux/mm.h> | ||
36 | #include <linux/mutex.h> | ||
37 | #include <linux/slab.h> | ||
38 | |||
39 | #include "em28xx.h" | ||
40 | #include <media/v4l2-common.h> | ||
41 | #include <media/v4l2-ioctl.h> | ||
42 | #include <media/v4l2-chip-ident.h> | ||
43 | #include <media/msp3400.h> | ||
44 | #include <media/tuner.h> | ||
45 | |||
46 | #define DRIVER_AUTHOR "Ludovico Cavedon <cavedon@sssup.it>, " \ | ||
47 | "Markus Rechberger <mrechberger@gmail.com>, " \ | ||
48 | "Mauro Carvalho Chehab <mchehab@infradead.org>, " \ | ||
49 | "Sascha Sommer <saschasommer@freenet.de>" | ||
50 | |||
51 | #define DRIVER_DESC "Empia em28xx based USB video device driver" | ||
52 | |||
53 | #define EM28XX_VERSION "0.1.3" | ||
54 | |||
55 | #define em28xx_videodbg(fmt, arg...) do {\ | ||
56 | if (video_debug) \ | ||
57 | printk(KERN_INFO "%s %s :"fmt, \ | ||
58 | dev->name, __func__ , ##arg); } while (0) | ||
59 | |||
60 | static unsigned int isoc_debug; | ||
61 | module_param(isoc_debug, int, 0644); | ||
62 | MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]"); | ||
63 | |||
64 | #define em28xx_isocdbg(fmt, arg...) \ | ||
65 | do {\ | ||
66 | if (isoc_debug) { \ | ||
67 | printk(KERN_INFO "%s %s :"fmt, \ | ||
68 | dev->name, __func__ , ##arg); \ | ||
69 | } \ | ||
70 | } while (0) | ||
71 | |||
72 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
73 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
74 | MODULE_LICENSE("GPL"); | ||
75 | MODULE_VERSION(EM28XX_VERSION); | ||
76 | |||
77 | static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | ||
78 | static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | ||
79 | static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | ||
80 | |||
81 | module_param_array(video_nr, int, NULL, 0444); | ||
82 | module_param_array(vbi_nr, int, NULL, 0444); | ||
83 | module_param_array(radio_nr, int, NULL, 0444); | ||
84 | MODULE_PARM_DESC(video_nr, "video device numbers"); | ||
85 | MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); | ||
86 | MODULE_PARM_DESC(radio_nr, "radio device numbers"); | ||
87 | |||
88 | static unsigned int video_debug; | ||
89 | module_param(video_debug, int, 0644); | ||
90 | MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); | ||
91 | |||
92 | /* supported video standards */ | ||
93 | static struct em28xx_fmt format[] = { | ||
94 | { | ||
95 | .name = "16 bpp YUY2, 4:2:2, packed", | ||
96 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
97 | .depth = 16, | ||
98 | .reg = EM28XX_OUTFMT_YUV422_Y0UY1V, | ||
99 | }, { | ||
100 | .name = "16 bpp RGB 565, LE", | ||
101 | .fourcc = V4L2_PIX_FMT_RGB565, | ||
102 | .depth = 16, | ||
103 | .reg = EM28XX_OUTFMT_RGB_16_656, | ||
104 | }, { | ||
105 | .name = "8 bpp Bayer BGBG..GRGR", | ||
106 | .fourcc = V4L2_PIX_FMT_SBGGR8, | ||
107 | .depth = 8, | ||
108 | .reg = EM28XX_OUTFMT_RGB_8_BGBG, | ||
109 | }, { | ||
110 | .name = "8 bpp Bayer GRGR..BGBG", | ||
111 | .fourcc = V4L2_PIX_FMT_SGRBG8, | ||
112 | .depth = 8, | ||
113 | .reg = EM28XX_OUTFMT_RGB_8_GRGR, | ||
114 | }, { | ||
115 | .name = "8 bpp Bayer GBGB..RGRG", | ||
116 | .fourcc = V4L2_PIX_FMT_SGBRG8, | ||
117 | .depth = 8, | ||
118 | .reg = EM28XX_OUTFMT_RGB_8_GBGB, | ||
119 | }, { | ||
120 | .name = "12 bpp YUV411", | ||
121 | .fourcc = V4L2_PIX_FMT_YUV411P, | ||
122 | .depth = 12, | ||
123 | .reg = EM28XX_OUTFMT_YUV411, | ||
124 | }, | ||
125 | }; | ||
126 | |||
127 | /* supported controls */ | ||
128 | /* Common to all boards */ | ||
129 | static struct v4l2_queryctrl ac97_qctrl[] = { | ||
130 | { | ||
131 | .id = V4L2_CID_AUDIO_VOLUME, | ||
132 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
133 | .name = "Volume", | ||
134 | .minimum = 0x0, | ||
135 | .maximum = 0x1f, | ||
136 | .step = 0x1, | ||
137 | .default_value = 0x1f, | ||
138 | .flags = V4L2_CTRL_FLAG_SLIDER, | ||
139 | }, { | ||
140 | .id = V4L2_CID_AUDIO_MUTE, | ||
141 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
142 | .name = "Mute", | ||
143 | .minimum = 0, | ||
144 | .maximum = 1, | ||
145 | .step = 1, | ||
146 | .default_value = 1, | ||
147 | .flags = 0, | ||
148 | } | ||
149 | }; | ||
150 | |||
151 | /* ------------------------------------------------------------------ | ||
152 | DMA and thread functions | ||
153 | ------------------------------------------------------------------*/ | ||
154 | |||
155 | /* | ||
156 | * Announces that a buffer were filled and request the next | ||
157 | */ | ||
158 | static inline void buffer_filled(struct em28xx *dev, | ||
159 | struct em28xx_dmaqueue *dma_q, | ||
160 | struct em28xx_buffer *buf) | ||
161 | { | ||
162 | /* Advice that buffer was filled */ | ||
163 | em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i); | ||
164 | buf->vb.state = VIDEOBUF_DONE; | ||
165 | buf->vb.field_count++; | ||
166 | do_gettimeofday(&buf->vb.ts); | ||
167 | |||
168 | dev->isoc_ctl.vid_buf = NULL; | ||
169 | |||
170 | list_del(&buf->vb.queue); | ||
171 | wake_up(&buf->vb.done); | ||
172 | } | ||
173 | |||
174 | static inline void vbi_buffer_filled(struct em28xx *dev, | ||
175 | struct em28xx_dmaqueue *dma_q, | ||
176 | struct em28xx_buffer *buf) | ||
177 | { | ||
178 | /* Advice that buffer was filled */ | ||
179 | em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i); | ||
180 | |||
181 | buf->vb.state = VIDEOBUF_DONE; | ||
182 | buf->vb.field_count++; | ||
183 | do_gettimeofday(&buf->vb.ts); | ||
184 | |||
185 | dev->isoc_ctl.vbi_buf = NULL; | ||
186 | |||
187 | list_del(&buf->vb.queue); | ||
188 | wake_up(&buf->vb.done); | ||
189 | } | ||
190 | |||
191 | /* | ||
192 | * Identify the buffer header type and properly handles | ||
193 | */ | ||
194 | static void em28xx_copy_video(struct em28xx *dev, | ||
195 | struct em28xx_dmaqueue *dma_q, | ||
196 | struct em28xx_buffer *buf, | ||
197 | unsigned char *p, | ||
198 | unsigned char *outp, unsigned long len) | ||
199 | { | ||
200 | void *fieldstart, *startwrite, *startread; | ||
201 | int linesdone, currlinedone, offset, lencopy, remain; | ||
202 | int bytesperline = dev->width << 1; | ||
203 | |||
204 | if (dma_q->pos + len > buf->vb.size) | ||
205 | len = buf->vb.size - dma_q->pos; | ||
206 | |||
207 | startread = p; | ||
208 | remain = len; | ||
209 | |||
210 | if (dev->progressive) | ||
211 | fieldstart = outp; | ||
212 | else { | ||
213 | /* Interlaces two half frames */ | ||
214 | if (buf->top_field) | ||
215 | fieldstart = outp; | ||
216 | else | ||
217 | fieldstart = outp + bytesperline; | ||
218 | } | ||
219 | |||
220 | linesdone = dma_q->pos / bytesperline; | ||
221 | currlinedone = dma_q->pos % bytesperline; | ||
222 | |||
223 | if (dev->progressive) | ||
224 | offset = linesdone * bytesperline + currlinedone; | ||
225 | else | ||
226 | offset = linesdone * bytesperline * 2 + currlinedone; | ||
227 | |||
228 | startwrite = fieldstart + offset; | ||
229 | lencopy = bytesperline - currlinedone; | ||
230 | lencopy = lencopy > remain ? remain : lencopy; | ||
231 | |||
232 | if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) { | ||
233 | em28xx_isocdbg("Overflow of %zi bytes past buffer end (1)\n", | ||
234 | ((char *)startwrite + lencopy) - | ||
235 | ((char *)outp + buf->vb.size)); | ||
236 | remain = (char *)outp + buf->vb.size - (char *)startwrite; | ||
237 | lencopy = remain; | ||
238 | } | ||
239 | if (lencopy <= 0) | ||
240 | return; | ||
241 | memcpy(startwrite, startread, lencopy); | ||
242 | |||
243 | remain -= lencopy; | ||
244 | |||
245 | while (remain > 0) { | ||
246 | startwrite += lencopy + bytesperline; | ||
247 | startread += lencopy; | ||
248 | if (bytesperline > remain) | ||
249 | lencopy = remain; | ||
250 | else | ||
251 | lencopy = bytesperline; | ||
252 | |||
253 | if ((char *)startwrite + lencopy > (char *)outp + | ||
254 | buf->vb.size) { | ||
255 | em28xx_isocdbg("Overflow of %zi bytes past buffer end" | ||
256 | "(2)\n", | ||
257 | ((char *)startwrite + lencopy) - | ||
258 | ((char *)outp + buf->vb.size)); | ||
259 | lencopy = remain = (char *)outp + buf->vb.size - | ||
260 | (char *)startwrite; | ||
261 | } | ||
262 | if (lencopy <= 0) | ||
263 | break; | ||
264 | |||
265 | memcpy(startwrite, startread, lencopy); | ||
266 | |||
267 | remain -= lencopy; | ||
268 | } | ||
269 | |||
270 | dma_q->pos += len; | ||
271 | } | ||
272 | |||
273 | static void em28xx_copy_vbi(struct em28xx *dev, | ||
274 | struct em28xx_dmaqueue *dma_q, | ||
275 | struct em28xx_buffer *buf, | ||
276 | unsigned char *p, | ||
277 | unsigned char *outp, unsigned long len) | ||
278 | { | ||
279 | void *startwrite, *startread; | ||
280 | int offset; | ||
281 | int bytesperline; | ||
282 | |||
283 | if (dev == NULL) { | ||
284 | em28xx_isocdbg("dev is null\n"); | ||
285 | return; | ||
286 | } | ||
287 | bytesperline = dev->vbi_width; | ||
288 | |||
289 | if (dma_q == NULL) { | ||
290 | em28xx_isocdbg("dma_q is null\n"); | ||
291 | return; | ||
292 | } | ||
293 | if (buf == NULL) { | ||
294 | return; | ||
295 | } | ||
296 | if (p == NULL) { | ||
297 | em28xx_isocdbg("p is null\n"); | ||
298 | return; | ||
299 | } | ||
300 | if (outp == NULL) { | ||
301 | em28xx_isocdbg("outp is null\n"); | ||
302 | return; | ||
303 | } | ||
304 | |||
305 | if (dma_q->pos + len > buf->vb.size) | ||
306 | len = buf->vb.size - dma_q->pos; | ||
307 | |||
308 | startread = p; | ||
309 | |||
310 | startwrite = outp + dma_q->pos; | ||
311 | offset = dma_q->pos; | ||
312 | |||
313 | /* Make sure the bottom field populates the second half of the frame */ | ||
314 | if (buf->top_field == 0) { | ||
315 | startwrite += bytesperline * dev->vbi_height; | ||
316 | offset += bytesperline * dev->vbi_height; | ||
317 | } | ||
318 | |||
319 | memcpy(startwrite, startread, len); | ||
320 | dma_q->pos += len; | ||
321 | } | ||
322 | |||
323 | static inline void print_err_status(struct em28xx *dev, | ||
324 | int packet, int status) | ||
325 | { | ||
326 | char *errmsg = "Unknown"; | ||
327 | |||
328 | switch (status) { | ||
329 | case -ENOENT: | ||
330 | errmsg = "unlinked synchronuously"; | ||
331 | break; | ||
332 | case -ECONNRESET: | ||
333 | errmsg = "unlinked asynchronuously"; | ||
334 | break; | ||
335 | case -ENOSR: | ||
336 | errmsg = "Buffer error (overrun)"; | ||
337 | break; | ||
338 | case -EPIPE: | ||
339 | errmsg = "Stalled (device not responding)"; | ||
340 | break; | ||
341 | case -EOVERFLOW: | ||
342 | errmsg = "Babble (bad cable?)"; | ||
343 | break; | ||
344 | case -EPROTO: | ||
345 | errmsg = "Bit-stuff error (bad cable?)"; | ||
346 | break; | ||
347 | case -EILSEQ: | ||
348 | errmsg = "CRC/Timeout (could be anything)"; | ||
349 | break; | ||
350 | case -ETIME: | ||
351 | errmsg = "Device does not respond"; | ||
352 | break; | ||
353 | } | ||
354 | if (packet < 0) { | ||
355 | em28xx_isocdbg("URB status %d [%s].\n", status, errmsg); | ||
356 | } else { | ||
357 | em28xx_isocdbg("URB packet %d, status %d [%s].\n", | ||
358 | packet, status, errmsg); | ||
359 | } | ||
360 | } | ||
361 | |||
362 | /* | ||
363 | * video-buf generic routine to get the next available buffer | ||
364 | */ | ||
365 | static inline void get_next_buf(struct em28xx_dmaqueue *dma_q, | ||
366 | struct em28xx_buffer **buf) | ||
367 | { | ||
368 | struct em28xx *dev = container_of(dma_q, struct em28xx, vidq); | ||
369 | char *outp; | ||
370 | |||
371 | if (list_empty(&dma_q->active)) { | ||
372 | em28xx_isocdbg("No active queue to serve\n"); | ||
373 | dev->isoc_ctl.vid_buf = NULL; | ||
374 | *buf = NULL; | ||
375 | return; | ||
376 | } | ||
377 | |||
378 | /* Get the next buffer */ | ||
379 | *buf = list_entry(dma_q->active.next, struct em28xx_buffer, vb.queue); | ||
380 | |||
381 | /* Cleans up buffer - Useful for testing for frame/URB loss */ | ||
382 | outp = videobuf_to_vmalloc(&(*buf)->vb); | ||
383 | memset(outp, 0, (*buf)->vb.size); | ||
384 | |||
385 | dev->isoc_ctl.vid_buf = *buf; | ||
386 | |||
387 | return; | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * video-buf generic routine to get the next available VBI buffer | ||
392 | */ | ||
393 | static inline void vbi_get_next_buf(struct em28xx_dmaqueue *dma_q, | ||
394 | struct em28xx_buffer **buf) | ||
395 | { | ||
396 | struct em28xx *dev = container_of(dma_q, struct em28xx, vbiq); | ||
397 | char *outp; | ||
398 | |||
399 | if (list_empty(&dma_q->active)) { | ||
400 | em28xx_isocdbg("No active queue to serve\n"); | ||
401 | dev->isoc_ctl.vbi_buf = NULL; | ||
402 | *buf = NULL; | ||
403 | return; | ||
404 | } | ||
405 | |||
406 | /* Get the next buffer */ | ||
407 | *buf = list_entry(dma_q->active.next, struct em28xx_buffer, vb.queue); | ||
408 | /* Cleans up buffer - Useful for testing for frame/URB loss */ | ||
409 | outp = videobuf_to_vmalloc(&(*buf)->vb); | ||
410 | memset(outp, 0x00, (*buf)->vb.size); | ||
411 | |||
412 | dev->isoc_ctl.vbi_buf = *buf; | ||
413 | |||
414 | return; | ||
415 | } | ||
416 | |||
417 | /* | ||
418 | * Controls the isoc copy of each urb packet | ||
419 | */ | ||
420 | static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb) | ||
421 | { | ||
422 | struct em28xx_buffer *buf; | ||
423 | struct em28xx_dmaqueue *dma_q = &dev->vidq; | ||
424 | unsigned char *outp = NULL; | ||
425 | int i, len = 0, rc = 1; | ||
426 | unsigned char *p; | ||
427 | |||
428 | if (!dev) | ||
429 | return 0; | ||
430 | |||
431 | if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) | ||
432 | return 0; | ||
433 | |||
434 | if (urb->status < 0) { | ||
435 | print_err_status(dev, -1, urb->status); | ||
436 | if (urb->status == -ENOENT) | ||
437 | return 0; | ||
438 | } | ||
439 | |||
440 | buf = dev->isoc_ctl.vid_buf; | ||
441 | if (buf != NULL) | ||
442 | outp = videobuf_to_vmalloc(&buf->vb); | ||
443 | |||
444 | for (i = 0; i < urb->number_of_packets; i++) { | ||
445 | int status = urb->iso_frame_desc[i].status; | ||
446 | |||
447 | if (status < 0) { | ||
448 | print_err_status(dev, i, status); | ||
449 | if (urb->iso_frame_desc[i].status != -EPROTO) | ||
450 | continue; | ||
451 | } | ||
452 | |||
453 | len = urb->iso_frame_desc[i].actual_length - 4; | ||
454 | |||
455 | if (urb->iso_frame_desc[i].actual_length <= 0) { | ||
456 | /* em28xx_isocdbg("packet %d is empty",i); - spammy */ | ||
457 | continue; | ||
458 | } | ||
459 | if (urb->iso_frame_desc[i].actual_length > | ||
460 | dev->max_pkt_size) { | ||
461 | em28xx_isocdbg("packet bigger than packet size"); | ||
462 | continue; | ||
463 | } | ||
464 | |||
465 | p = urb->transfer_buffer + urb->iso_frame_desc[i].offset; | ||
466 | |||
467 | /* FIXME: incomplete buffer checks where removed to make | ||
468 | logic simpler. Impacts of those changes should be evaluated | ||
469 | */ | ||
470 | if (p[0] == 0x33 && p[1] == 0x95 && p[2] == 0x00) { | ||
471 | em28xx_isocdbg("VBI HEADER!!!\n"); | ||
472 | /* FIXME: Should add vbi copy */ | ||
473 | continue; | ||
474 | } | ||
475 | if (p[0] == 0x22 && p[1] == 0x5a) { | ||
476 | em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2], | ||
477 | len, (p[2] & 1) ? "odd" : "even"); | ||
478 | |||
479 | if (dev->progressive || !(p[2] & 1)) { | ||
480 | if (buf != NULL) | ||
481 | buffer_filled(dev, dma_q, buf); | ||
482 | get_next_buf(dma_q, &buf); | ||
483 | if (buf == NULL) | ||
484 | outp = NULL; | ||
485 | else | ||
486 | outp = videobuf_to_vmalloc(&buf->vb); | ||
487 | } | ||
488 | |||
489 | if (buf != NULL) { | ||
490 | if (p[2] & 1) | ||
491 | buf->top_field = 0; | ||
492 | else | ||
493 | buf->top_field = 1; | ||
494 | } | ||
495 | |||
496 | dma_q->pos = 0; | ||
497 | } | ||
498 | if (buf != NULL) { | ||
499 | if (p[0] != 0x88 && p[0] != 0x22) { | ||
500 | em28xx_isocdbg("frame is not complete\n"); | ||
501 | len += 4; | ||
502 | } else { | ||
503 | p += 4; | ||
504 | } | ||
505 | em28xx_copy_video(dev, dma_q, buf, p, outp, len); | ||
506 | } | ||
507 | } | ||
508 | return rc; | ||
509 | } | ||
510 | |||
511 | /* Version of isoc handler that takes into account a mixture of video and | ||
512 | VBI data */ | ||
513 | static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb) | ||
514 | { | ||
515 | struct em28xx_buffer *buf, *vbi_buf; | ||
516 | struct em28xx_dmaqueue *dma_q = &dev->vidq; | ||
517 | struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq; | ||
518 | unsigned char *outp = NULL; | ||
519 | unsigned char *vbioutp = NULL; | ||
520 | int i, len = 0, rc = 1; | ||
521 | unsigned char *p; | ||
522 | int vbi_size; | ||
523 | |||
524 | if (!dev) | ||
525 | return 0; | ||
526 | |||
527 | if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) | ||
528 | return 0; | ||
529 | |||
530 | if (urb->status < 0) { | ||
531 | print_err_status(dev, -1, urb->status); | ||
532 | if (urb->status == -ENOENT) | ||
533 | return 0; | ||
534 | } | ||
535 | |||
536 | buf = dev->isoc_ctl.vid_buf; | ||
537 | if (buf != NULL) | ||
538 | outp = videobuf_to_vmalloc(&buf->vb); | ||
539 | |||
540 | vbi_buf = dev->isoc_ctl.vbi_buf; | ||
541 | if (vbi_buf != NULL) | ||
542 | vbioutp = videobuf_to_vmalloc(&vbi_buf->vb); | ||
543 | |||
544 | for (i = 0; i < urb->number_of_packets; i++) { | ||
545 | int status = urb->iso_frame_desc[i].status; | ||
546 | |||
547 | if (status < 0) { | ||
548 | print_err_status(dev, i, status); | ||
549 | if (urb->iso_frame_desc[i].status != -EPROTO) | ||
550 | continue; | ||
551 | } | ||
552 | |||
553 | len = urb->iso_frame_desc[i].actual_length; | ||
554 | if (urb->iso_frame_desc[i].actual_length <= 0) { | ||
555 | /* em28xx_isocdbg("packet %d is empty",i); - spammy */ | ||
556 | continue; | ||
557 | } | ||
558 | if (urb->iso_frame_desc[i].actual_length > | ||
559 | dev->max_pkt_size) { | ||
560 | em28xx_isocdbg("packet bigger than packet size"); | ||
561 | continue; | ||
562 | } | ||
563 | |||
564 | p = urb->transfer_buffer + urb->iso_frame_desc[i].offset; | ||
565 | |||
566 | /* capture type 0 = vbi start | ||
567 | capture type 1 = video start | ||
568 | capture type 2 = video in progress */ | ||
569 | if (p[0] == 0x33 && p[1] == 0x95) { | ||
570 | dev->capture_type = 0; | ||
571 | dev->vbi_read = 0; | ||
572 | em28xx_isocdbg("VBI START HEADER!!!\n"); | ||
573 | dev->cur_field = p[2]; | ||
574 | p += 4; | ||
575 | len -= 4; | ||
576 | } else if (p[0] == 0x88 && p[1] == 0x88 && | ||
577 | p[2] == 0x88 && p[3] == 0x88) { | ||
578 | /* continuation */ | ||
579 | p += 4; | ||
580 | len -= 4; | ||
581 | } else if (p[0] == 0x22 && p[1] == 0x5a) { | ||
582 | /* start video */ | ||
583 | p += 4; | ||
584 | len -= 4; | ||
585 | } | ||
586 | |||
587 | vbi_size = dev->vbi_width * dev->vbi_height; | ||
588 | |||
589 | if (dev->capture_type == 0) { | ||
590 | if (dev->vbi_read >= vbi_size) { | ||
591 | /* We've already read all the VBI data, so | ||
592 | treat the rest as video */ | ||
593 | em28xx_isocdbg("dev->vbi_read > vbi_size\n"); | ||
594 | } else if ((dev->vbi_read + len) < vbi_size) { | ||
595 | /* This entire frame is VBI data */ | ||
596 | if (dev->vbi_read == 0 && | ||
597 | (!(dev->cur_field & 1))) { | ||
598 | /* Brand new frame */ | ||
599 | if (vbi_buf != NULL) | ||
600 | vbi_buffer_filled(dev, | ||
601 | vbi_dma_q, | ||
602 | vbi_buf); | ||
603 | vbi_get_next_buf(vbi_dma_q, &vbi_buf); | ||
604 | if (vbi_buf == NULL) | ||
605 | vbioutp = NULL; | ||
606 | else | ||
607 | vbioutp = videobuf_to_vmalloc( | ||
608 | &vbi_buf->vb); | ||
609 | } | ||
610 | |||
611 | if (dev->vbi_read == 0) { | ||
612 | vbi_dma_q->pos = 0; | ||
613 | if (vbi_buf != NULL) { | ||
614 | if (dev->cur_field & 1) | ||
615 | vbi_buf->top_field = 0; | ||
616 | else | ||
617 | vbi_buf->top_field = 1; | ||
618 | } | ||
619 | } | ||
620 | |||
621 | dev->vbi_read += len; | ||
622 | em28xx_copy_vbi(dev, vbi_dma_q, vbi_buf, p, | ||
623 | vbioutp, len); | ||
624 | } else { | ||
625 | /* Some of this frame is VBI data and some is | ||
626 | video data */ | ||
627 | int vbi_data_len = vbi_size - dev->vbi_read; | ||
628 | dev->vbi_read += vbi_data_len; | ||
629 | em28xx_copy_vbi(dev, vbi_dma_q, vbi_buf, p, | ||
630 | vbioutp, vbi_data_len); | ||
631 | dev->capture_type = 1; | ||
632 | p += vbi_data_len; | ||
633 | len -= vbi_data_len; | ||
634 | } | ||
635 | } | ||
636 | |||
637 | if (dev->capture_type == 1) { | ||
638 | dev->capture_type = 2; | ||
639 | if (dev->progressive || !(dev->cur_field & 1)) { | ||
640 | if (buf != NULL) | ||
641 | buffer_filled(dev, dma_q, buf); | ||
642 | get_next_buf(dma_q, &buf); | ||
643 | if (buf == NULL) | ||
644 | outp = NULL; | ||
645 | else | ||
646 | outp = videobuf_to_vmalloc(&buf->vb); | ||
647 | } | ||
648 | if (buf != NULL) { | ||
649 | if (dev->cur_field & 1) | ||
650 | buf->top_field = 0; | ||
651 | else | ||
652 | buf->top_field = 1; | ||
653 | } | ||
654 | |||
655 | dma_q->pos = 0; | ||
656 | } | ||
657 | |||
658 | if (buf != NULL && dev->capture_type == 2) { | ||
659 | if (len >= 4 && p[0] == 0x88 && p[1] == 0x88 && | ||
660 | p[2] == 0x88 && p[3] == 0x88) { | ||
661 | p += 4; | ||
662 | len -= 4; | ||
663 | } | ||
664 | if (len >= 4 && p[0] == 0x22 && p[1] == 0x5a) { | ||
665 | em28xx_isocdbg("Video frame %d, len=%i, %s\n", | ||
666 | p[2], len, (p[2] & 1) ? | ||
667 | "odd" : "even"); | ||
668 | p += 4; | ||
669 | len -= 4; | ||
670 | } | ||
671 | |||
672 | if (len > 0) | ||
673 | em28xx_copy_video(dev, dma_q, buf, p, outp, | ||
674 | len); | ||
675 | } | ||
676 | } | ||
677 | return rc; | ||
678 | } | ||
679 | |||
680 | |||
681 | /* ------------------------------------------------------------------ | ||
682 | Videobuf operations | ||
683 | ------------------------------------------------------------------*/ | ||
684 | |||
685 | static int | ||
686 | buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | ||
687 | { | ||
688 | struct em28xx_fh *fh = vq->priv_data; | ||
689 | struct em28xx *dev = fh->dev; | ||
690 | struct v4l2_frequency f; | ||
691 | |||
692 | *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) | ||
693 | >> 3; | ||
694 | |||
695 | if (0 == *count) | ||
696 | *count = EM28XX_DEF_BUF; | ||
697 | |||
698 | if (*count < EM28XX_MIN_BUF) | ||
699 | *count = EM28XX_MIN_BUF; | ||
700 | |||
701 | /* Ask tuner to go to analog or radio mode */ | ||
702 | memset(&f, 0, sizeof(f)); | ||
703 | f.frequency = dev->ctl_freq; | ||
704 | f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
705 | |||
706 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); | ||
707 | |||
708 | return 0; | ||
709 | } | ||
710 | |||
711 | /* This is called *without* dev->slock held; please keep it that way */ | ||
712 | static void free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf) | ||
713 | { | ||
714 | struct em28xx_fh *fh = vq->priv_data; | ||
715 | struct em28xx *dev = fh->dev; | ||
716 | unsigned long flags = 0; | ||
717 | if (in_interrupt()) | ||
718 | BUG(); | ||
719 | |||
720 | /* We used to wait for the buffer to finish here, but this didn't work | ||
721 | because, as we were keeping the state as VIDEOBUF_QUEUED, | ||
722 | videobuf_queue_cancel marked it as finished for us. | ||
723 | (Also, it could wedge forever if the hardware was misconfigured.) | ||
724 | |||
725 | This should be safe; by the time we get here, the buffer isn't | ||
726 | queued anymore. If we ever start marking the buffers as | ||
727 | VIDEOBUF_ACTIVE, it won't be, though. | ||
728 | */ | ||
729 | spin_lock_irqsave(&dev->slock, flags); | ||
730 | if (dev->isoc_ctl.vid_buf == buf) | ||
731 | dev->isoc_ctl.vid_buf = NULL; | ||
732 | spin_unlock_irqrestore(&dev->slock, flags); | ||
733 | |||
734 | videobuf_vmalloc_free(&buf->vb); | ||
735 | buf->vb.state = VIDEOBUF_NEEDS_INIT; | ||
736 | } | ||
737 | |||
738 | static int | ||
739 | buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | ||
740 | enum v4l2_field field) | ||
741 | { | ||
742 | struct em28xx_fh *fh = vq->priv_data; | ||
743 | struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb); | ||
744 | struct em28xx *dev = fh->dev; | ||
745 | int rc = 0, urb_init = 0; | ||
746 | |||
747 | buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth | ||
748 | + 7) >> 3; | ||
749 | |||
750 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | ||
751 | return -EINVAL; | ||
752 | |||
753 | buf->vb.width = dev->width; | ||
754 | buf->vb.height = dev->height; | ||
755 | buf->vb.field = field; | ||
756 | |||
757 | if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { | ||
758 | rc = videobuf_iolock(vq, &buf->vb, NULL); | ||
759 | if (rc < 0) | ||
760 | goto fail; | ||
761 | } | ||
762 | |||
763 | if (!dev->isoc_ctl.analog_bufs.num_bufs) | ||
764 | urb_init = 1; | ||
765 | |||
766 | if (urb_init) { | ||
767 | if (em28xx_vbi_supported(dev) == 1) | ||
768 | rc = em28xx_init_isoc(dev, EM28XX_ANALOG_MODE, | ||
769 | EM28XX_NUM_PACKETS, | ||
770 | EM28XX_NUM_BUFS, | ||
771 | dev->max_pkt_size, | ||
772 | em28xx_isoc_copy_vbi); | ||
773 | else | ||
774 | rc = em28xx_init_isoc(dev, EM28XX_ANALOG_MODE, | ||
775 | EM28XX_NUM_PACKETS, | ||
776 | EM28XX_NUM_BUFS, | ||
777 | dev->max_pkt_size, | ||
778 | em28xx_isoc_copy); | ||
779 | if (rc < 0) | ||
780 | goto fail; | ||
781 | } | ||
782 | |||
783 | buf->vb.state = VIDEOBUF_PREPARED; | ||
784 | return 0; | ||
785 | |||
786 | fail: | ||
787 | free_buffer(vq, buf); | ||
788 | return rc; | ||
789 | } | ||
790 | |||
791 | static void | ||
792 | buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) | ||
793 | { | ||
794 | struct em28xx_buffer *buf = container_of(vb, | ||
795 | struct em28xx_buffer, | ||
796 | vb); | ||
797 | struct em28xx_fh *fh = vq->priv_data; | ||
798 | struct em28xx *dev = fh->dev; | ||
799 | struct em28xx_dmaqueue *vidq = &dev->vidq; | ||
800 | |||
801 | buf->vb.state = VIDEOBUF_QUEUED; | ||
802 | list_add_tail(&buf->vb.queue, &vidq->active); | ||
803 | |||
804 | } | ||
805 | |||
806 | static void buffer_release(struct videobuf_queue *vq, | ||
807 | struct videobuf_buffer *vb) | ||
808 | { | ||
809 | struct em28xx_buffer *buf = container_of(vb, | ||
810 | struct em28xx_buffer, | ||
811 | vb); | ||
812 | struct em28xx_fh *fh = vq->priv_data; | ||
813 | struct em28xx *dev = (struct em28xx *)fh->dev; | ||
814 | |||
815 | em28xx_isocdbg("em28xx: called buffer_release\n"); | ||
816 | |||
817 | free_buffer(vq, buf); | ||
818 | } | ||
819 | |||
820 | static struct videobuf_queue_ops em28xx_video_qops = { | ||
821 | .buf_setup = buffer_setup, | ||
822 | .buf_prepare = buffer_prepare, | ||
823 | .buf_queue = buffer_queue, | ||
824 | .buf_release = buffer_release, | ||
825 | }; | ||
826 | |||
827 | /********************* v4l2 interface **************************************/ | ||
828 | |||
829 | static void video_mux(struct em28xx *dev, int index) | ||
830 | { | ||
831 | dev->ctl_input = index; | ||
832 | dev->ctl_ainput = INPUT(index)->amux; | ||
833 | dev->ctl_aoutput = INPUT(index)->aout; | ||
834 | |||
835 | if (!dev->ctl_aoutput) | ||
836 | dev->ctl_aoutput = EM28XX_AOUT_MASTER; | ||
837 | |||
838 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing, | ||
839 | INPUT(index)->vmux, 0, 0); | ||
840 | |||
841 | if (dev->board.has_msp34xx) { | ||
842 | if (dev->i2s_speed) { | ||
843 | v4l2_device_call_all(&dev->v4l2_dev, 0, audio, | ||
844 | s_i2s_clock_freq, dev->i2s_speed); | ||
845 | } | ||
846 | /* Note: this is msp3400 specific */ | ||
847 | v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing, | ||
848 | dev->ctl_ainput, MSP_OUTPUT(MSP_SC_IN_DSP_SCART1), 0); | ||
849 | } | ||
850 | |||
851 | if (dev->board.adecoder != EM28XX_NOADECODER) { | ||
852 | v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing, | ||
853 | dev->ctl_ainput, dev->ctl_aoutput, 0); | ||
854 | } | ||
855 | |||
856 | em28xx_audio_analog_set(dev); | ||
857 | } | ||
858 | |||
859 | /* Usage lock check functions */ | ||
860 | static int res_get(struct em28xx_fh *fh, unsigned int bit) | ||
861 | { | ||
862 | struct em28xx *dev = fh->dev; | ||
863 | |||
864 | if (fh->resources & bit) | ||
865 | /* have it already allocated */ | ||
866 | return 1; | ||
867 | |||
868 | /* is it free? */ | ||
869 | if (dev->resources & bit) { | ||
870 | /* no, someone else uses it */ | ||
871 | return 0; | ||
872 | } | ||
873 | /* it's free, grab it */ | ||
874 | fh->resources |= bit; | ||
875 | dev->resources |= bit; | ||
876 | em28xx_videodbg("res: get %d\n", bit); | ||
877 | return 1; | ||
878 | } | ||
879 | |||
880 | static int res_check(struct em28xx_fh *fh, unsigned int bit) | ||
881 | { | ||
882 | return fh->resources & bit; | ||
883 | } | ||
884 | |||
885 | static int res_locked(struct em28xx *dev, unsigned int bit) | ||
886 | { | ||
887 | return dev->resources & bit; | ||
888 | } | ||
889 | |||
890 | static void res_free(struct em28xx_fh *fh, unsigned int bits) | ||
891 | { | ||
892 | struct em28xx *dev = fh->dev; | ||
893 | |||
894 | BUG_ON((fh->resources & bits) != bits); | ||
895 | |||
896 | fh->resources &= ~bits; | ||
897 | dev->resources &= ~bits; | ||
898 | em28xx_videodbg("res: put %d\n", bits); | ||
899 | } | ||
900 | |||
901 | static int get_ressource(struct em28xx_fh *fh) | ||
902 | { | ||
903 | switch (fh->type) { | ||
904 | case V4L2_BUF_TYPE_VIDEO_CAPTURE: | ||
905 | return EM28XX_RESOURCE_VIDEO; | ||
906 | case V4L2_BUF_TYPE_VBI_CAPTURE: | ||
907 | return EM28XX_RESOURCE_VBI; | ||
908 | default: | ||
909 | BUG(); | ||
910 | return 0; | ||
911 | } | ||
912 | } | ||
913 | |||
914 | /* | ||
915 | * ac97_queryctrl() | ||
916 | * return the ac97 supported controls | ||
917 | */ | ||
918 | static int ac97_queryctrl(struct v4l2_queryctrl *qc) | ||
919 | { | ||
920 | int i; | ||
921 | |||
922 | for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++) { | ||
923 | if (qc->id && qc->id == ac97_qctrl[i].id) { | ||
924 | memcpy(qc, &(ac97_qctrl[i]), sizeof(*qc)); | ||
925 | return 0; | ||
926 | } | ||
927 | } | ||
928 | |||
929 | /* Control is not ac97 related */ | ||
930 | return 1; | ||
931 | } | ||
932 | |||
933 | /* | ||
934 | * ac97_get_ctrl() | ||
935 | * return the current values for ac97 mute and volume | ||
936 | */ | ||
937 | static int ac97_get_ctrl(struct em28xx *dev, struct v4l2_control *ctrl) | ||
938 | { | ||
939 | switch (ctrl->id) { | ||
940 | case V4L2_CID_AUDIO_MUTE: | ||
941 | ctrl->value = dev->mute; | ||
942 | return 0; | ||
943 | case V4L2_CID_AUDIO_VOLUME: | ||
944 | ctrl->value = dev->volume; | ||
945 | return 0; | ||
946 | default: | ||
947 | /* Control is not ac97 related */ | ||
948 | return 1; | ||
949 | } | ||
950 | } | ||
951 | |||
952 | /* | ||
953 | * ac97_set_ctrl() | ||
954 | * set values for ac97 mute and volume | ||
955 | */ | ||
956 | static int ac97_set_ctrl(struct em28xx *dev, const struct v4l2_control *ctrl) | ||
957 | { | ||
958 | int i; | ||
959 | |||
960 | for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++) | ||
961 | if (ctrl->id == ac97_qctrl[i].id) | ||
962 | goto handle; | ||
963 | |||
964 | /* Announce that hasn't handle it */ | ||
965 | return 1; | ||
966 | |||
967 | handle: | ||
968 | if (ctrl->value < ac97_qctrl[i].minimum || | ||
969 | ctrl->value > ac97_qctrl[i].maximum) | ||
970 | return -ERANGE; | ||
971 | |||
972 | switch (ctrl->id) { | ||
973 | case V4L2_CID_AUDIO_MUTE: | ||
974 | dev->mute = ctrl->value; | ||
975 | break; | ||
976 | case V4L2_CID_AUDIO_VOLUME: | ||
977 | dev->volume = ctrl->value; | ||
978 | break; | ||
979 | } | ||
980 | |||
981 | return em28xx_audio_analog_set(dev); | ||
982 | } | ||
983 | |||
984 | static int check_dev(struct em28xx *dev) | ||
985 | { | ||
986 | if (dev->state & DEV_DISCONNECTED) { | ||
987 | em28xx_errdev("v4l2 ioctl: device not present\n"); | ||
988 | return -ENODEV; | ||
989 | } | ||
990 | |||
991 | if (dev->state & DEV_MISCONFIGURED) { | ||
992 | em28xx_errdev("v4l2 ioctl: device is misconfigured; " | ||
993 | "close and open it again\n"); | ||
994 | return -EIO; | ||
995 | } | ||
996 | return 0; | ||
997 | } | ||
998 | |||
999 | static void get_scale(struct em28xx *dev, | ||
1000 | unsigned int width, unsigned int height, | ||
1001 | unsigned int *hscale, unsigned int *vscale) | ||
1002 | { | ||
1003 | unsigned int maxw = norm_maxw(dev); | ||
1004 | unsigned int maxh = norm_maxh(dev); | ||
1005 | |||
1006 | *hscale = (((unsigned long)maxw) << 12) / width - 4096L; | ||
1007 | if (*hscale >= 0x4000) | ||
1008 | *hscale = 0x3fff; | ||
1009 | |||
1010 | *vscale = (((unsigned long)maxh) << 12) / height - 4096L; | ||
1011 | if (*vscale >= 0x4000) | ||
1012 | *vscale = 0x3fff; | ||
1013 | } | ||
1014 | |||
1015 | /* ------------------------------------------------------------------ | ||
1016 | IOCTL vidioc handling | ||
1017 | ------------------------------------------------------------------*/ | ||
1018 | |||
1019 | static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | ||
1020 | struct v4l2_format *f) | ||
1021 | { | ||
1022 | struct em28xx_fh *fh = priv; | ||
1023 | struct em28xx *dev = fh->dev; | ||
1024 | |||
1025 | f->fmt.pix.width = dev->width; | ||
1026 | f->fmt.pix.height = dev->height; | ||
1027 | f->fmt.pix.pixelformat = dev->format->fourcc; | ||
1028 | f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3; | ||
1029 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height; | ||
1030 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
1031 | |||
1032 | /* FIXME: TOP? NONE? BOTTOM? ALTENATE? */ | ||
1033 | if (dev->progressive) | ||
1034 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
1035 | else | ||
1036 | f->fmt.pix.field = dev->interlaced ? | ||
1037 | V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; | ||
1038 | return 0; | ||
1039 | } | ||
1040 | |||
1041 | static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc) | ||
1042 | { | ||
1043 | unsigned int i; | ||
1044 | |||
1045 | for (i = 0; i < ARRAY_SIZE(format); i++) | ||
1046 | if (format[i].fourcc == fourcc) | ||
1047 | return &format[i]; | ||
1048 | |||
1049 | return NULL; | ||
1050 | } | ||
1051 | |||
1052 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | ||
1053 | struct v4l2_format *f) | ||
1054 | { | ||
1055 | struct em28xx_fh *fh = priv; | ||
1056 | struct em28xx *dev = fh->dev; | ||
1057 | unsigned int width = f->fmt.pix.width; | ||
1058 | unsigned int height = f->fmt.pix.height; | ||
1059 | unsigned int maxw = norm_maxw(dev); | ||
1060 | unsigned int maxh = norm_maxh(dev); | ||
1061 | unsigned int hscale, vscale; | ||
1062 | struct em28xx_fmt *fmt; | ||
1063 | |||
1064 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | ||
1065 | if (!fmt) { | ||
1066 | em28xx_videodbg("Fourcc format (%08x) invalid.\n", | ||
1067 | f->fmt.pix.pixelformat); | ||
1068 | return -EINVAL; | ||
1069 | } | ||
1070 | |||
1071 | if (dev->board.is_em2800) { | ||
1072 | /* the em2800 can only scale down to 50% */ | ||
1073 | height = height > (3 * maxh / 4) ? maxh : maxh / 2; | ||
1074 | width = width > (3 * maxw / 4) ? maxw : maxw / 2; | ||
1075 | /* MaxPacketSize for em2800 is too small to capture at full resolution | ||
1076 | * use half of maxw as the scaler can only scale to 50% */ | ||
1077 | if (width == maxw && height == maxh) | ||
1078 | width /= 2; | ||
1079 | } else { | ||
1080 | /* width must even because of the YUYV format | ||
1081 | height must be even because of interlacing */ | ||
1082 | v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, | ||
1083 | 1, 0); | ||
1084 | } | ||
1085 | |||
1086 | get_scale(dev, width, height, &hscale, &vscale); | ||
1087 | |||
1088 | width = (((unsigned long)maxw) << 12) / (hscale + 4096L); | ||
1089 | height = (((unsigned long)maxh) << 12) / (vscale + 4096L); | ||
1090 | |||
1091 | f->fmt.pix.width = width; | ||
1092 | f->fmt.pix.height = height; | ||
1093 | f->fmt.pix.pixelformat = fmt->fourcc; | ||
1094 | f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3; | ||
1095 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height; | ||
1096 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | ||
1097 | if (dev->progressive) | ||
1098 | f->fmt.pix.field = V4L2_FIELD_NONE; | ||
1099 | else | ||
1100 | f->fmt.pix.field = dev->interlaced ? | ||
1101 | V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP; | ||
1102 | |||
1103 | return 0; | ||
1104 | } | ||
1105 | |||
1106 | static int em28xx_set_video_format(struct em28xx *dev, unsigned int fourcc, | ||
1107 | unsigned width, unsigned height) | ||
1108 | { | ||
1109 | struct em28xx_fmt *fmt; | ||
1110 | |||
1111 | fmt = format_by_fourcc(fourcc); | ||
1112 | if (!fmt) | ||
1113 | return -EINVAL; | ||
1114 | |||
1115 | dev->format = fmt; | ||
1116 | dev->width = width; | ||
1117 | dev->height = height; | ||
1118 | |||
1119 | /* set new image size */ | ||
1120 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); | ||
1121 | |||
1122 | em28xx_set_alternate(dev); | ||
1123 | em28xx_resolution_set(dev); | ||
1124 | |||
1125 | return 0; | ||
1126 | } | ||
1127 | |||
1128 | static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | ||
1129 | struct v4l2_format *f) | ||
1130 | { | ||
1131 | struct em28xx_fh *fh = priv; | ||
1132 | struct em28xx *dev = fh->dev; | ||
1133 | int rc; | ||
1134 | |||
1135 | rc = check_dev(dev); | ||
1136 | if (rc < 0) | ||
1137 | return rc; | ||
1138 | |||
1139 | vidioc_try_fmt_vid_cap(file, priv, f); | ||
1140 | |||
1141 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { | ||
1142 | em28xx_errdev("%s queue busy\n", __func__); | ||
1143 | return -EBUSY; | ||
1144 | } | ||
1145 | |||
1146 | return em28xx_set_video_format(dev, f->fmt.pix.pixelformat, | ||
1147 | f->fmt.pix.width, f->fmt.pix.height); | ||
1148 | } | ||
1149 | |||
1150 | static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm) | ||
1151 | { | ||
1152 | struct em28xx_fh *fh = priv; | ||
1153 | struct em28xx *dev = fh->dev; | ||
1154 | int rc; | ||
1155 | |||
1156 | rc = check_dev(dev); | ||
1157 | if (rc < 0) | ||
1158 | return rc; | ||
1159 | |||
1160 | *norm = dev->norm; | ||
1161 | |||
1162 | return 0; | ||
1163 | } | ||
1164 | |||
1165 | static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *norm) | ||
1166 | { | ||
1167 | struct em28xx_fh *fh = priv; | ||
1168 | struct em28xx *dev = fh->dev; | ||
1169 | int rc; | ||
1170 | |||
1171 | rc = check_dev(dev); | ||
1172 | if (rc < 0) | ||
1173 | return rc; | ||
1174 | |||
1175 | v4l2_device_call_all(&dev->v4l2_dev, 0, video, querystd, norm); | ||
1176 | |||
1177 | return 0; | ||
1178 | } | ||
1179 | |||
1180 | static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) | ||
1181 | { | ||
1182 | struct em28xx_fh *fh = priv; | ||
1183 | struct em28xx *dev = fh->dev; | ||
1184 | struct v4l2_format f; | ||
1185 | int rc; | ||
1186 | |||
1187 | rc = check_dev(dev); | ||
1188 | if (rc < 0) | ||
1189 | return rc; | ||
1190 | |||
1191 | dev->norm = *norm; | ||
1192 | |||
1193 | /* Adjusts width/height, if needed */ | ||
1194 | f.fmt.pix.width = dev->width; | ||
1195 | f.fmt.pix.height = dev->height; | ||
1196 | vidioc_try_fmt_vid_cap(file, priv, &f); | ||
1197 | |||
1198 | /* set new image size */ | ||
1199 | dev->width = f.fmt.pix.width; | ||
1200 | dev->height = f.fmt.pix.height; | ||
1201 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); | ||
1202 | |||
1203 | em28xx_resolution_set(dev); | ||
1204 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm); | ||
1205 | |||
1206 | return 0; | ||
1207 | } | ||
1208 | |||
1209 | static int vidioc_g_parm(struct file *file, void *priv, | ||
1210 | struct v4l2_streamparm *p) | ||
1211 | { | ||
1212 | struct em28xx_fh *fh = priv; | ||
1213 | struct em28xx *dev = fh->dev; | ||
1214 | int rc = 0; | ||
1215 | |||
1216 | if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1217 | return -EINVAL; | ||
1218 | |||
1219 | if (dev->board.is_webcam) | ||
1220 | rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0, | ||
1221 | video, g_parm, p); | ||
1222 | else | ||
1223 | v4l2_video_std_frame_period(dev->norm, | ||
1224 | &p->parm.capture.timeperframe); | ||
1225 | |||
1226 | return rc; | ||
1227 | } | ||
1228 | |||
1229 | static int vidioc_s_parm(struct file *file, void *priv, | ||
1230 | struct v4l2_streamparm *p) | ||
1231 | { | ||
1232 | struct em28xx_fh *fh = priv; | ||
1233 | struct em28xx *dev = fh->dev; | ||
1234 | |||
1235 | if (!dev->board.is_webcam) | ||
1236 | return -EINVAL; | ||
1237 | |||
1238 | if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1239 | return -EINVAL; | ||
1240 | |||
1241 | return v4l2_device_call_until_err(&dev->v4l2_dev, 0, video, s_parm, p); | ||
1242 | } | ||
1243 | |||
1244 | static const char *iname[] = { | ||
1245 | [EM28XX_VMUX_COMPOSITE1] = "Composite1", | ||
1246 | [EM28XX_VMUX_COMPOSITE2] = "Composite2", | ||
1247 | [EM28XX_VMUX_COMPOSITE3] = "Composite3", | ||
1248 | [EM28XX_VMUX_COMPOSITE4] = "Composite4", | ||
1249 | [EM28XX_VMUX_SVIDEO] = "S-Video", | ||
1250 | [EM28XX_VMUX_TELEVISION] = "Television", | ||
1251 | [EM28XX_VMUX_CABLE] = "Cable TV", | ||
1252 | [EM28XX_VMUX_DVB] = "DVB", | ||
1253 | [EM28XX_VMUX_DEBUG] = "for debug only", | ||
1254 | }; | ||
1255 | |||
1256 | static int vidioc_enum_input(struct file *file, void *priv, | ||
1257 | struct v4l2_input *i) | ||
1258 | { | ||
1259 | struct em28xx_fh *fh = priv; | ||
1260 | struct em28xx *dev = fh->dev; | ||
1261 | unsigned int n; | ||
1262 | |||
1263 | n = i->index; | ||
1264 | if (n >= MAX_EM28XX_INPUT) | ||
1265 | return -EINVAL; | ||
1266 | if (0 == INPUT(n)->type) | ||
1267 | return -EINVAL; | ||
1268 | |||
1269 | i->index = n; | ||
1270 | i->type = V4L2_INPUT_TYPE_CAMERA; | ||
1271 | |||
1272 | strcpy(i->name, iname[INPUT(n)->type]); | ||
1273 | |||
1274 | if ((EM28XX_VMUX_TELEVISION == INPUT(n)->type) || | ||
1275 | (EM28XX_VMUX_CABLE == INPUT(n)->type)) | ||
1276 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
1277 | |||
1278 | i->std = dev->vdev->tvnorms; | ||
1279 | |||
1280 | return 0; | ||
1281 | } | ||
1282 | |||
1283 | static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) | ||
1284 | { | ||
1285 | struct em28xx_fh *fh = priv; | ||
1286 | struct em28xx *dev = fh->dev; | ||
1287 | |||
1288 | *i = dev->ctl_input; | ||
1289 | |||
1290 | return 0; | ||
1291 | } | ||
1292 | |||
1293 | static int vidioc_s_input(struct file *file, void *priv, unsigned int i) | ||
1294 | { | ||
1295 | struct em28xx_fh *fh = priv; | ||
1296 | struct em28xx *dev = fh->dev; | ||
1297 | int rc; | ||
1298 | |||
1299 | rc = check_dev(dev); | ||
1300 | if (rc < 0) | ||
1301 | return rc; | ||
1302 | |||
1303 | if (i >= MAX_EM28XX_INPUT) | ||
1304 | return -EINVAL; | ||
1305 | if (0 == INPUT(i)->type) | ||
1306 | return -EINVAL; | ||
1307 | |||
1308 | video_mux(dev, i); | ||
1309 | return 0; | ||
1310 | } | ||
1311 | |||
1312 | static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) | ||
1313 | { | ||
1314 | struct em28xx_fh *fh = priv; | ||
1315 | struct em28xx *dev = fh->dev; | ||
1316 | |||
1317 | if (!dev->audio_mode.has_audio) | ||
1318 | return -EINVAL; | ||
1319 | |||
1320 | switch (a->index) { | ||
1321 | case EM28XX_AMUX_VIDEO: | ||
1322 | strcpy(a->name, "Television"); | ||
1323 | break; | ||
1324 | case EM28XX_AMUX_LINE_IN: | ||
1325 | strcpy(a->name, "Line In"); | ||
1326 | break; | ||
1327 | case EM28XX_AMUX_VIDEO2: | ||
1328 | strcpy(a->name, "Television alt"); | ||
1329 | break; | ||
1330 | case EM28XX_AMUX_PHONE: | ||
1331 | strcpy(a->name, "Phone"); | ||
1332 | break; | ||
1333 | case EM28XX_AMUX_MIC: | ||
1334 | strcpy(a->name, "Mic"); | ||
1335 | break; | ||
1336 | case EM28XX_AMUX_CD: | ||
1337 | strcpy(a->name, "CD"); | ||
1338 | break; | ||
1339 | case EM28XX_AMUX_AUX: | ||
1340 | strcpy(a->name, "Aux"); | ||
1341 | break; | ||
1342 | case EM28XX_AMUX_PCM_OUT: | ||
1343 | strcpy(a->name, "PCM"); | ||
1344 | break; | ||
1345 | default: | ||
1346 | return -EINVAL; | ||
1347 | } | ||
1348 | |||
1349 | a->index = dev->ctl_ainput; | ||
1350 | a->capability = V4L2_AUDCAP_STEREO; | ||
1351 | |||
1352 | return 0; | ||
1353 | } | ||
1354 | |||
1355 | static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) | ||
1356 | { | ||
1357 | struct em28xx_fh *fh = priv; | ||
1358 | struct em28xx *dev = fh->dev; | ||
1359 | |||
1360 | |||
1361 | if (!dev->audio_mode.has_audio) | ||
1362 | return -EINVAL; | ||
1363 | |||
1364 | if (a->index >= MAX_EM28XX_INPUT) | ||
1365 | return -EINVAL; | ||
1366 | if (0 == INPUT(a->index)->type) | ||
1367 | return -EINVAL; | ||
1368 | |||
1369 | dev->ctl_ainput = INPUT(a->index)->amux; | ||
1370 | dev->ctl_aoutput = INPUT(a->index)->aout; | ||
1371 | |||
1372 | if (!dev->ctl_aoutput) | ||
1373 | dev->ctl_aoutput = EM28XX_AOUT_MASTER; | ||
1374 | |||
1375 | return 0; | ||
1376 | } | ||
1377 | |||
1378 | static int vidioc_queryctrl(struct file *file, void *priv, | ||
1379 | struct v4l2_queryctrl *qc) | ||
1380 | { | ||
1381 | struct em28xx_fh *fh = priv; | ||
1382 | struct em28xx *dev = fh->dev; | ||
1383 | int id = qc->id; | ||
1384 | int rc; | ||
1385 | |||
1386 | rc = check_dev(dev); | ||
1387 | if (rc < 0) | ||
1388 | return rc; | ||
1389 | |||
1390 | memset(qc, 0, sizeof(*qc)); | ||
1391 | |||
1392 | qc->id = id; | ||
1393 | |||
1394 | /* enumerate AC97 controls */ | ||
1395 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { | ||
1396 | rc = ac97_queryctrl(qc); | ||
1397 | if (!rc) | ||
1398 | return 0; | ||
1399 | } | ||
1400 | |||
1401 | /* enumerate V4L2 device controls */ | ||
1402 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc); | ||
1403 | |||
1404 | if (qc->type) | ||
1405 | return 0; | ||
1406 | else | ||
1407 | return -EINVAL; | ||
1408 | } | ||
1409 | |||
1410 | /* | ||
1411 | * FIXME: This is an indirect way to check if a control exists at a | ||
1412 | * subdev. Instead of that hack, maybe the better would be to change all | ||
1413 | * subdevs to return -ENOIOCTLCMD, if an ioctl is not supported. | ||
1414 | */ | ||
1415 | static int check_subdev_ctrl(struct em28xx *dev, int id) | ||
1416 | { | ||
1417 | struct v4l2_queryctrl qc; | ||
1418 | |||
1419 | memset(&qc, 0, sizeof(qc)); | ||
1420 | qc.id = id; | ||
1421 | |||
1422 | /* enumerate V4L2 device controls */ | ||
1423 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, &qc); | ||
1424 | |||
1425 | if (qc.type) | ||
1426 | return 0; | ||
1427 | else | ||
1428 | return -EINVAL; | ||
1429 | } | ||
1430 | |||
1431 | static int vidioc_g_ctrl(struct file *file, void *priv, | ||
1432 | struct v4l2_control *ctrl) | ||
1433 | { | ||
1434 | struct em28xx_fh *fh = priv; | ||
1435 | struct em28xx *dev = fh->dev; | ||
1436 | int rc; | ||
1437 | |||
1438 | rc = check_dev(dev); | ||
1439 | if (rc < 0) | ||
1440 | return rc; | ||
1441 | rc = 0; | ||
1442 | |||
1443 | /* Set an AC97 control */ | ||
1444 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) | ||
1445 | rc = ac97_get_ctrl(dev, ctrl); | ||
1446 | else | ||
1447 | rc = 1; | ||
1448 | |||
1449 | /* It were not an AC97 control. Sends it to the v4l2 dev interface */ | ||
1450 | if (rc == 1) { | ||
1451 | if (check_subdev_ctrl(dev, ctrl->id)) | ||
1452 | return -EINVAL; | ||
1453 | |||
1454 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl); | ||
1455 | rc = 0; | ||
1456 | } | ||
1457 | |||
1458 | return rc; | ||
1459 | } | ||
1460 | |||
1461 | static int vidioc_s_ctrl(struct file *file, void *priv, | ||
1462 | struct v4l2_control *ctrl) | ||
1463 | { | ||
1464 | struct em28xx_fh *fh = priv; | ||
1465 | struct em28xx *dev = fh->dev; | ||
1466 | int rc; | ||
1467 | |||
1468 | rc = check_dev(dev); | ||
1469 | if (rc < 0) | ||
1470 | return rc; | ||
1471 | |||
1472 | /* Set an AC97 control */ | ||
1473 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) | ||
1474 | rc = ac97_set_ctrl(dev, ctrl); | ||
1475 | else | ||
1476 | rc = 1; | ||
1477 | |||
1478 | /* It isn't an AC97 control. Sends it to the v4l2 dev interface */ | ||
1479 | if (rc == 1) { | ||
1480 | rc = check_subdev_ctrl(dev, ctrl->id); | ||
1481 | if (!rc) | ||
1482 | v4l2_device_call_all(&dev->v4l2_dev, 0, | ||
1483 | core, s_ctrl, ctrl); | ||
1484 | /* | ||
1485 | * In the case of non-AC97 volume controls, we still need | ||
1486 | * to do some setups at em28xx, in order to mute/unmute | ||
1487 | * and to adjust audio volume. However, the value ranges | ||
1488 | * should be checked by the corresponding V4L subdriver. | ||
1489 | */ | ||
1490 | switch (ctrl->id) { | ||
1491 | case V4L2_CID_AUDIO_MUTE: | ||
1492 | dev->mute = ctrl->value; | ||
1493 | rc = em28xx_audio_analog_set(dev); | ||
1494 | break; | ||
1495 | case V4L2_CID_AUDIO_VOLUME: | ||
1496 | dev->volume = ctrl->value; | ||
1497 | rc = em28xx_audio_analog_set(dev); | ||
1498 | } | ||
1499 | } | ||
1500 | return (rc < 0) ? rc : 0; | ||
1501 | } | ||
1502 | |||
1503 | static int vidioc_g_tuner(struct file *file, void *priv, | ||
1504 | struct v4l2_tuner *t) | ||
1505 | { | ||
1506 | struct em28xx_fh *fh = priv; | ||
1507 | struct em28xx *dev = fh->dev; | ||
1508 | int rc; | ||
1509 | |||
1510 | rc = check_dev(dev); | ||
1511 | if (rc < 0) | ||
1512 | return rc; | ||
1513 | |||
1514 | if (0 != t->index) | ||
1515 | return -EINVAL; | ||
1516 | |||
1517 | strcpy(t->name, "Tuner"); | ||
1518 | t->type = V4L2_TUNER_ANALOG_TV; | ||
1519 | |||
1520 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t); | ||
1521 | return 0; | ||
1522 | } | ||
1523 | |||
1524 | static int vidioc_s_tuner(struct file *file, void *priv, | ||
1525 | struct v4l2_tuner *t) | ||
1526 | { | ||
1527 | struct em28xx_fh *fh = priv; | ||
1528 | struct em28xx *dev = fh->dev; | ||
1529 | int rc; | ||
1530 | |||
1531 | rc = check_dev(dev); | ||
1532 | if (rc < 0) | ||
1533 | return rc; | ||
1534 | |||
1535 | if (0 != t->index) | ||
1536 | return -EINVAL; | ||
1537 | |||
1538 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t); | ||
1539 | return 0; | ||
1540 | } | ||
1541 | |||
1542 | static int vidioc_g_frequency(struct file *file, void *priv, | ||
1543 | struct v4l2_frequency *f) | ||
1544 | { | ||
1545 | struct em28xx_fh *fh = priv; | ||
1546 | struct em28xx *dev = fh->dev; | ||
1547 | |||
1548 | f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
1549 | f->frequency = dev->ctl_freq; | ||
1550 | return 0; | ||
1551 | } | ||
1552 | |||
1553 | static int vidioc_s_frequency(struct file *file, void *priv, | ||
1554 | struct v4l2_frequency *f) | ||
1555 | { | ||
1556 | struct em28xx_fh *fh = priv; | ||
1557 | struct em28xx *dev = fh->dev; | ||
1558 | int rc; | ||
1559 | |||
1560 | rc = check_dev(dev); | ||
1561 | if (rc < 0) | ||
1562 | return rc; | ||
1563 | |||
1564 | if (0 != f->tuner) | ||
1565 | return -EINVAL; | ||
1566 | |||
1567 | if (unlikely(0 == fh->radio && f->type != V4L2_TUNER_ANALOG_TV)) | ||
1568 | return -EINVAL; | ||
1569 | if (unlikely(1 == fh->radio && f->type != V4L2_TUNER_RADIO)) | ||
1570 | return -EINVAL; | ||
1571 | |||
1572 | dev->ctl_freq = f->frequency; | ||
1573 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f); | ||
1574 | |||
1575 | return 0; | ||
1576 | } | ||
1577 | |||
1578 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
1579 | static int em28xx_reg_len(int reg) | ||
1580 | { | ||
1581 | switch (reg) { | ||
1582 | case EM28XX_R40_AC97LSB: | ||
1583 | case EM28XX_R30_HSCALELOW: | ||
1584 | case EM28XX_R32_VSCALELOW: | ||
1585 | return 2; | ||
1586 | default: | ||
1587 | return 1; | ||
1588 | } | ||
1589 | } | ||
1590 | |||
1591 | static int vidioc_g_chip_ident(struct file *file, void *priv, | ||
1592 | struct v4l2_dbg_chip_ident *chip) | ||
1593 | { | ||
1594 | struct em28xx_fh *fh = priv; | ||
1595 | struct em28xx *dev = fh->dev; | ||
1596 | |||
1597 | chip->ident = V4L2_IDENT_NONE; | ||
1598 | chip->revision = 0; | ||
1599 | |||
1600 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip); | ||
1601 | |||
1602 | return 0; | ||
1603 | } | ||
1604 | |||
1605 | |||
1606 | static int vidioc_g_register(struct file *file, void *priv, | ||
1607 | struct v4l2_dbg_register *reg) | ||
1608 | { | ||
1609 | struct em28xx_fh *fh = priv; | ||
1610 | struct em28xx *dev = fh->dev; | ||
1611 | int ret; | ||
1612 | |||
1613 | switch (reg->match.type) { | ||
1614 | case V4L2_CHIP_MATCH_AC97: | ||
1615 | ret = em28xx_read_ac97(dev, reg->reg); | ||
1616 | if (ret < 0) | ||
1617 | return ret; | ||
1618 | |||
1619 | reg->val = ret; | ||
1620 | reg->size = 1; | ||
1621 | return 0; | ||
1622 | case V4L2_CHIP_MATCH_I2C_DRIVER: | ||
1623 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg); | ||
1624 | return 0; | ||
1625 | case V4L2_CHIP_MATCH_I2C_ADDR: | ||
1626 | /* TODO: is this correct? */ | ||
1627 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg); | ||
1628 | return 0; | ||
1629 | default: | ||
1630 | if (!v4l2_chip_match_host(®->match)) | ||
1631 | return -EINVAL; | ||
1632 | } | ||
1633 | |||
1634 | /* Match host */ | ||
1635 | reg->size = em28xx_reg_len(reg->reg); | ||
1636 | if (reg->size == 1) { | ||
1637 | ret = em28xx_read_reg(dev, reg->reg); | ||
1638 | |||
1639 | if (ret < 0) | ||
1640 | return ret; | ||
1641 | |||
1642 | reg->val = ret; | ||
1643 | } else { | ||
1644 | __le16 val = 0; | ||
1645 | ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, | ||
1646 | reg->reg, (char *)&val, 2); | ||
1647 | if (ret < 0) | ||
1648 | return ret; | ||
1649 | |||
1650 | reg->val = le16_to_cpu(val); | ||
1651 | } | ||
1652 | |||
1653 | return 0; | ||
1654 | } | ||
1655 | |||
1656 | static int vidioc_s_register(struct file *file, void *priv, | ||
1657 | struct v4l2_dbg_register *reg) | ||
1658 | { | ||
1659 | struct em28xx_fh *fh = priv; | ||
1660 | struct em28xx *dev = fh->dev; | ||
1661 | __le16 buf; | ||
1662 | |||
1663 | switch (reg->match.type) { | ||
1664 | case V4L2_CHIP_MATCH_AC97: | ||
1665 | return em28xx_write_ac97(dev, reg->reg, reg->val); | ||
1666 | case V4L2_CHIP_MATCH_I2C_DRIVER: | ||
1667 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg); | ||
1668 | return 0; | ||
1669 | case V4L2_CHIP_MATCH_I2C_ADDR: | ||
1670 | /* TODO: is this correct? */ | ||
1671 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg); | ||
1672 | return 0; | ||
1673 | default: | ||
1674 | if (!v4l2_chip_match_host(®->match)) | ||
1675 | return -EINVAL; | ||
1676 | } | ||
1677 | |||
1678 | /* Match host */ | ||
1679 | buf = cpu_to_le16(reg->val); | ||
1680 | |||
1681 | return em28xx_write_regs(dev, reg->reg, (char *)&buf, | ||
1682 | em28xx_reg_len(reg->reg)); | ||
1683 | } | ||
1684 | #endif | ||
1685 | |||
1686 | |||
1687 | static int vidioc_cropcap(struct file *file, void *priv, | ||
1688 | struct v4l2_cropcap *cc) | ||
1689 | { | ||
1690 | struct em28xx_fh *fh = priv; | ||
1691 | struct em28xx *dev = fh->dev; | ||
1692 | |||
1693 | if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1694 | return -EINVAL; | ||
1695 | |||
1696 | cc->bounds.left = 0; | ||
1697 | cc->bounds.top = 0; | ||
1698 | cc->bounds.width = dev->width; | ||
1699 | cc->bounds.height = dev->height; | ||
1700 | cc->defrect = cc->bounds; | ||
1701 | cc->pixelaspect.numerator = 54; /* 4:3 FIXME: remove magic numbers */ | ||
1702 | cc->pixelaspect.denominator = 59; | ||
1703 | |||
1704 | return 0; | ||
1705 | } | ||
1706 | |||
1707 | static int vidioc_streamon(struct file *file, void *priv, | ||
1708 | enum v4l2_buf_type type) | ||
1709 | { | ||
1710 | struct em28xx_fh *fh = priv; | ||
1711 | struct em28xx *dev = fh->dev; | ||
1712 | int rc = -EINVAL; | ||
1713 | |||
1714 | rc = check_dev(dev); | ||
1715 | if (rc < 0) | ||
1716 | return rc; | ||
1717 | |||
1718 | if (unlikely(type != fh->type)) | ||
1719 | return -EINVAL; | ||
1720 | |||
1721 | em28xx_videodbg("vidioc_streamon fh=%p t=%d fh->res=%d dev->res=%d\n", | ||
1722 | fh, type, fh->resources, dev->resources); | ||
1723 | |||
1724 | if (unlikely(!res_get(fh, get_ressource(fh)))) | ||
1725 | return -EBUSY; | ||
1726 | |||
1727 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1728 | rc = videobuf_streamon(&fh->vb_vidq); | ||
1729 | else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) | ||
1730 | rc = videobuf_streamon(&fh->vb_vbiq); | ||
1731 | |||
1732 | return rc; | ||
1733 | } | ||
1734 | |||
1735 | static int vidioc_streamoff(struct file *file, void *priv, | ||
1736 | enum v4l2_buf_type type) | ||
1737 | { | ||
1738 | struct em28xx_fh *fh = priv; | ||
1739 | struct em28xx *dev = fh->dev; | ||
1740 | int rc; | ||
1741 | |||
1742 | rc = check_dev(dev); | ||
1743 | if (rc < 0) | ||
1744 | return rc; | ||
1745 | |||
1746 | if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && | ||
1747 | fh->type != V4L2_BUF_TYPE_VBI_CAPTURE) | ||
1748 | return -EINVAL; | ||
1749 | if (type != fh->type) | ||
1750 | return -EINVAL; | ||
1751 | |||
1752 | em28xx_videodbg("vidioc_streamoff fh=%p t=%d fh->res=%d dev->res=%d\n", | ||
1753 | fh, type, fh->resources, dev->resources); | ||
1754 | |||
1755 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
1756 | if (res_check(fh, EM28XX_RESOURCE_VIDEO)) { | ||
1757 | videobuf_streamoff(&fh->vb_vidq); | ||
1758 | res_free(fh, EM28XX_RESOURCE_VIDEO); | ||
1759 | } | ||
1760 | } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | ||
1761 | if (res_check(fh, EM28XX_RESOURCE_VBI)) { | ||
1762 | videobuf_streamoff(&fh->vb_vbiq); | ||
1763 | res_free(fh, EM28XX_RESOURCE_VBI); | ||
1764 | } | ||
1765 | } | ||
1766 | |||
1767 | return 0; | ||
1768 | } | ||
1769 | |||
1770 | static int vidioc_querycap(struct file *file, void *priv, | ||
1771 | struct v4l2_capability *cap) | ||
1772 | { | ||
1773 | struct em28xx_fh *fh = priv; | ||
1774 | struct em28xx *dev = fh->dev; | ||
1775 | |||
1776 | strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); | ||
1777 | strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); | ||
1778 | usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); | ||
1779 | |||
1780 | cap->capabilities = | ||
1781 | V4L2_CAP_SLICED_VBI_CAPTURE | | ||
1782 | V4L2_CAP_VIDEO_CAPTURE | | ||
1783 | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; | ||
1784 | |||
1785 | if (dev->vbi_dev) | ||
1786 | cap->capabilities |= V4L2_CAP_VBI_CAPTURE; | ||
1787 | |||
1788 | if (dev->audio_mode.has_audio) | ||
1789 | cap->capabilities |= V4L2_CAP_AUDIO; | ||
1790 | |||
1791 | if (dev->tuner_type != TUNER_ABSENT) | ||
1792 | cap->capabilities |= V4L2_CAP_TUNER; | ||
1793 | |||
1794 | return 0; | ||
1795 | } | ||
1796 | |||
1797 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | ||
1798 | struct v4l2_fmtdesc *f) | ||
1799 | { | ||
1800 | if (unlikely(f->index >= ARRAY_SIZE(format))) | ||
1801 | return -EINVAL; | ||
1802 | |||
1803 | strlcpy(f->description, format[f->index].name, sizeof(f->description)); | ||
1804 | f->pixelformat = format[f->index].fourcc; | ||
1805 | |||
1806 | return 0; | ||
1807 | } | ||
1808 | |||
1809 | static int vidioc_enum_framesizes(struct file *file, void *priv, | ||
1810 | struct v4l2_frmsizeenum *fsize) | ||
1811 | { | ||
1812 | struct em28xx_fh *fh = priv; | ||
1813 | struct em28xx *dev = fh->dev; | ||
1814 | struct em28xx_fmt *fmt; | ||
1815 | unsigned int maxw = norm_maxw(dev); | ||
1816 | unsigned int maxh = norm_maxh(dev); | ||
1817 | |||
1818 | fmt = format_by_fourcc(fsize->pixel_format); | ||
1819 | if (!fmt) { | ||
1820 | em28xx_videodbg("Fourcc format (%08x) invalid.\n", | ||
1821 | fsize->pixel_format); | ||
1822 | return -EINVAL; | ||
1823 | } | ||
1824 | |||
1825 | if (dev->board.is_em2800) { | ||
1826 | if (fsize->index > 1) | ||
1827 | return -EINVAL; | ||
1828 | fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE; | ||
1829 | fsize->discrete.width = maxw / (1 + fsize->index); | ||
1830 | fsize->discrete.height = maxh / (1 + fsize->index); | ||
1831 | return 0; | ||
1832 | } | ||
1833 | |||
1834 | if (fsize->index != 0) | ||
1835 | return -EINVAL; | ||
1836 | |||
1837 | /* Report a continuous range */ | ||
1838 | fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE; | ||
1839 | fsize->stepwise.min_width = 48; | ||
1840 | fsize->stepwise.min_height = 32; | ||
1841 | fsize->stepwise.max_width = maxw; | ||
1842 | fsize->stepwise.max_height = maxh; | ||
1843 | fsize->stepwise.step_width = 1; | ||
1844 | fsize->stepwise.step_height = 1; | ||
1845 | return 0; | ||
1846 | } | ||
1847 | |||
1848 | /* Sliced VBI ioctls */ | ||
1849 | static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv, | ||
1850 | struct v4l2_format *f) | ||
1851 | { | ||
1852 | struct em28xx_fh *fh = priv; | ||
1853 | struct em28xx *dev = fh->dev; | ||
1854 | int rc; | ||
1855 | |||
1856 | rc = check_dev(dev); | ||
1857 | if (rc < 0) | ||
1858 | return rc; | ||
1859 | |||
1860 | f->fmt.sliced.service_set = 0; | ||
1861 | v4l2_device_call_all(&dev->v4l2_dev, 0, vbi, g_sliced_fmt, &f->fmt.sliced); | ||
1862 | |||
1863 | if (f->fmt.sliced.service_set == 0) | ||
1864 | rc = -EINVAL; | ||
1865 | |||
1866 | return rc; | ||
1867 | } | ||
1868 | |||
1869 | static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv, | ||
1870 | struct v4l2_format *f) | ||
1871 | { | ||
1872 | struct em28xx_fh *fh = priv; | ||
1873 | struct em28xx *dev = fh->dev; | ||
1874 | int rc; | ||
1875 | |||
1876 | rc = check_dev(dev); | ||
1877 | if (rc < 0) | ||
1878 | return rc; | ||
1879 | |||
1880 | v4l2_device_call_all(&dev->v4l2_dev, 0, vbi, g_sliced_fmt, &f->fmt.sliced); | ||
1881 | |||
1882 | if (f->fmt.sliced.service_set == 0) | ||
1883 | return -EINVAL; | ||
1884 | |||
1885 | return 0; | ||
1886 | } | ||
1887 | |||
1888 | /* RAW VBI ioctls */ | ||
1889 | |||
1890 | static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv, | ||
1891 | struct v4l2_format *format) | ||
1892 | { | ||
1893 | struct em28xx_fh *fh = priv; | ||
1894 | struct em28xx *dev = fh->dev; | ||
1895 | |||
1896 | format->fmt.vbi.samples_per_line = dev->vbi_width; | ||
1897 | format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
1898 | format->fmt.vbi.offset = 0; | ||
1899 | format->fmt.vbi.flags = 0; | ||
1900 | format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; | ||
1901 | format->fmt.vbi.count[0] = dev->vbi_height; | ||
1902 | format->fmt.vbi.count[1] = dev->vbi_height; | ||
1903 | |||
1904 | /* Varies by video standard (NTSC, PAL, etc.) */ | ||
1905 | if (dev->norm & V4L2_STD_525_60) { | ||
1906 | /* NTSC */ | ||
1907 | format->fmt.vbi.start[0] = 10; | ||
1908 | format->fmt.vbi.start[1] = 273; | ||
1909 | } else if (dev->norm & V4L2_STD_625_50) { | ||
1910 | /* PAL */ | ||
1911 | format->fmt.vbi.start[0] = 6; | ||
1912 | format->fmt.vbi.start[1] = 318; | ||
1913 | } | ||
1914 | |||
1915 | return 0; | ||
1916 | } | ||
1917 | |||
1918 | static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv, | ||
1919 | struct v4l2_format *format) | ||
1920 | { | ||
1921 | struct em28xx_fh *fh = priv; | ||
1922 | struct em28xx *dev = fh->dev; | ||
1923 | |||
1924 | format->fmt.vbi.samples_per_line = dev->vbi_width; | ||
1925 | format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; | ||
1926 | format->fmt.vbi.offset = 0; | ||
1927 | format->fmt.vbi.flags = 0; | ||
1928 | format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; | ||
1929 | format->fmt.vbi.count[0] = dev->vbi_height; | ||
1930 | format->fmt.vbi.count[1] = dev->vbi_height; | ||
1931 | |||
1932 | /* Varies by video standard (NTSC, PAL, etc.) */ | ||
1933 | if (dev->norm & V4L2_STD_525_60) { | ||
1934 | /* NTSC */ | ||
1935 | format->fmt.vbi.start[0] = 10; | ||
1936 | format->fmt.vbi.start[1] = 273; | ||
1937 | } else if (dev->norm & V4L2_STD_625_50) { | ||
1938 | /* PAL */ | ||
1939 | format->fmt.vbi.start[0] = 6; | ||
1940 | format->fmt.vbi.start[1] = 318; | ||
1941 | } | ||
1942 | |||
1943 | return 0; | ||
1944 | } | ||
1945 | |||
1946 | static int vidioc_reqbufs(struct file *file, void *priv, | ||
1947 | struct v4l2_requestbuffers *rb) | ||
1948 | { | ||
1949 | struct em28xx_fh *fh = priv; | ||
1950 | struct em28xx *dev = fh->dev; | ||
1951 | int rc; | ||
1952 | |||
1953 | rc = check_dev(dev); | ||
1954 | if (rc < 0) | ||
1955 | return rc; | ||
1956 | |||
1957 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1958 | return videobuf_reqbufs(&fh->vb_vidq, rb); | ||
1959 | else | ||
1960 | return videobuf_reqbufs(&fh->vb_vbiq, rb); | ||
1961 | } | ||
1962 | |||
1963 | static int vidioc_querybuf(struct file *file, void *priv, | ||
1964 | struct v4l2_buffer *b) | ||
1965 | { | ||
1966 | struct em28xx_fh *fh = priv; | ||
1967 | struct em28xx *dev = fh->dev; | ||
1968 | int rc; | ||
1969 | |||
1970 | rc = check_dev(dev); | ||
1971 | if (rc < 0) | ||
1972 | return rc; | ||
1973 | |||
1974 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
1975 | return videobuf_querybuf(&fh->vb_vidq, b); | ||
1976 | else { | ||
1977 | /* FIXME: I'm not sure yet whether this is a bug in zvbi or | ||
1978 | the videobuf framework, but we probably shouldn't be | ||
1979 | returning a buffer larger than that which was asked for. | ||
1980 | At a minimum, it causes a crash in zvbi since it does | ||
1981 | a memcpy based on the source buffer length */ | ||
1982 | int result = videobuf_querybuf(&fh->vb_vbiq, b); | ||
1983 | b->length = dev->vbi_width * dev->vbi_height * 2; | ||
1984 | |||
1985 | return result; | ||
1986 | } | ||
1987 | } | ||
1988 | |||
1989 | static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) | ||
1990 | { | ||
1991 | struct em28xx_fh *fh = priv; | ||
1992 | struct em28xx *dev = fh->dev; | ||
1993 | int rc; | ||
1994 | |||
1995 | rc = check_dev(dev); | ||
1996 | if (rc < 0) | ||
1997 | return rc; | ||
1998 | |||
1999 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
2000 | return videobuf_qbuf(&fh->vb_vidq, b); | ||
2001 | else | ||
2002 | return videobuf_qbuf(&fh->vb_vbiq, b); | ||
2003 | } | ||
2004 | |||
2005 | static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) | ||
2006 | { | ||
2007 | struct em28xx_fh *fh = priv; | ||
2008 | struct em28xx *dev = fh->dev; | ||
2009 | int rc; | ||
2010 | |||
2011 | rc = check_dev(dev); | ||
2012 | if (rc < 0) | ||
2013 | return rc; | ||
2014 | |||
2015 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
2016 | return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & | ||
2017 | O_NONBLOCK); | ||
2018 | else | ||
2019 | return videobuf_dqbuf(&fh->vb_vbiq, b, file->f_flags & | ||
2020 | O_NONBLOCK); | ||
2021 | } | ||
2022 | |||
2023 | /* ----------------------------------------------------------- */ | ||
2024 | /* RADIO ESPECIFIC IOCTLS */ | ||
2025 | /* ----------------------------------------------------------- */ | ||
2026 | |||
2027 | static int radio_querycap(struct file *file, void *priv, | ||
2028 | struct v4l2_capability *cap) | ||
2029 | { | ||
2030 | struct em28xx *dev = ((struct em28xx_fh *)priv)->dev; | ||
2031 | |||
2032 | strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); | ||
2033 | strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); | ||
2034 | usb_make_path(dev->udev, cap->bus_info, sizeof(cap->bus_info)); | ||
2035 | |||
2036 | cap->capabilities = V4L2_CAP_TUNER; | ||
2037 | return 0; | ||
2038 | } | ||
2039 | |||
2040 | static int radio_g_tuner(struct file *file, void *priv, | ||
2041 | struct v4l2_tuner *t) | ||
2042 | { | ||
2043 | struct em28xx *dev = ((struct em28xx_fh *)priv)->dev; | ||
2044 | |||
2045 | if (unlikely(t->index > 0)) | ||
2046 | return -EINVAL; | ||
2047 | |||
2048 | strcpy(t->name, "Radio"); | ||
2049 | t->type = V4L2_TUNER_RADIO; | ||
2050 | |||
2051 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t); | ||
2052 | |||
2053 | return 0; | ||
2054 | } | ||
2055 | |||
2056 | static int radio_enum_input(struct file *file, void *priv, | ||
2057 | struct v4l2_input *i) | ||
2058 | { | ||
2059 | if (i->index != 0) | ||
2060 | return -EINVAL; | ||
2061 | strcpy(i->name, "Radio"); | ||
2062 | i->type = V4L2_INPUT_TYPE_TUNER; | ||
2063 | |||
2064 | return 0; | ||
2065 | } | ||
2066 | |||
2067 | static int radio_g_audio(struct file *file, void *priv, struct v4l2_audio *a) | ||
2068 | { | ||
2069 | if (unlikely(a->index)) | ||
2070 | return -EINVAL; | ||
2071 | |||
2072 | strcpy(a->name, "Radio"); | ||
2073 | return 0; | ||
2074 | } | ||
2075 | |||
2076 | static int radio_s_tuner(struct file *file, void *priv, | ||
2077 | struct v4l2_tuner *t) | ||
2078 | { | ||
2079 | struct em28xx *dev = ((struct em28xx_fh *)priv)->dev; | ||
2080 | |||
2081 | if (0 != t->index) | ||
2082 | return -EINVAL; | ||
2083 | |||
2084 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t); | ||
2085 | |||
2086 | return 0; | ||
2087 | } | ||
2088 | |||
2089 | static int radio_s_audio(struct file *file, void *fh, | ||
2090 | struct v4l2_audio *a) | ||
2091 | { | ||
2092 | return 0; | ||
2093 | } | ||
2094 | |||
2095 | static int radio_s_input(struct file *file, void *fh, unsigned int i) | ||
2096 | { | ||
2097 | return 0; | ||
2098 | } | ||
2099 | |||
2100 | static int radio_queryctrl(struct file *file, void *priv, | ||
2101 | struct v4l2_queryctrl *qc) | ||
2102 | { | ||
2103 | int i; | ||
2104 | |||
2105 | if (qc->id < V4L2_CID_BASE || | ||
2106 | qc->id >= V4L2_CID_LASTP1) | ||
2107 | return -EINVAL; | ||
2108 | |||
2109 | for (i = 0; i < ARRAY_SIZE(ac97_qctrl); i++) { | ||
2110 | if (qc->id && qc->id == ac97_qctrl[i].id) { | ||
2111 | memcpy(qc, &(ac97_qctrl[i]), sizeof(*qc)); | ||
2112 | return 0; | ||
2113 | } | ||
2114 | } | ||
2115 | |||
2116 | return -EINVAL; | ||
2117 | } | ||
2118 | |||
2119 | /* | ||
2120 | * em28xx_v4l2_open() | ||
2121 | * inits the device and starts isoc transfer | ||
2122 | */ | ||
2123 | static int em28xx_v4l2_open(struct file *filp) | ||
2124 | { | ||
2125 | int errCode = 0, radio = 0; | ||
2126 | struct video_device *vdev = video_devdata(filp); | ||
2127 | struct em28xx *dev = video_drvdata(filp); | ||
2128 | enum v4l2_buf_type fh_type = 0; | ||
2129 | struct em28xx_fh *fh; | ||
2130 | enum v4l2_field field; | ||
2131 | |||
2132 | switch (vdev->vfl_type) { | ||
2133 | case VFL_TYPE_GRABBER: | ||
2134 | fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
2135 | break; | ||
2136 | case VFL_TYPE_VBI: | ||
2137 | fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
2138 | break; | ||
2139 | case VFL_TYPE_RADIO: | ||
2140 | radio = 1; | ||
2141 | break; | ||
2142 | } | ||
2143 | |||
2144 | em28xx_videodbg("open dev=%s type=%s users=%d\n", | ||
2145 | video_device_node_name(vdev), v4l2_type_names[fh_type], | ||
2146 | dev->users); | ||
2147 | |||
2148 | |||
2149 | if (mutex_lock_interruptible(&dev->lock)) | ||
2150 | return -ERESTARTSYS; | ||
2151 | fh = kzalloc(sizeof(struct em28xx_fh), GFP_KERNEL); | ||
2152 | if (!fh) { | ||
2153 | em28xx_errdev("em28xx-video.c: Out of memory?!\n"); | ||
2154 | mutex_unlock(&dev->lock); | ||
2155 | return -ENOMEM; | ||
2156 | } | ||
2157 | fh->dev = dev; | ||
2158 | fh->radio = radio; | ||
2159 | fh->type = fh_type; | ||
2160 | filp->private_data = fh; | ||
2161 | |||
2162 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) { | ||
2163 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | ||
2164 | em28xx_set_alternate(dev); | ||
2165 | em28xx_resolution_set(dev); | ||
2166 | |||
2167 | /* Needed, since GPIO might have disabled power of | ||
2168 | some i2c device | ||
2169 | */ | ||
2170 | em28xx_wake_i2c(dev); | ||
2171 | |||
2172 | } | ||
2173 | if (fh->radio) { | ||
2174 | em28xx_videodbg("video_open: setting radio device\n"); | ||
2175 | v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio); | ||
2176 | } | ||
2177 | |||
2178 | dev->users++; | ||
2179 | |||
2180 | if (dev->progressive) | ||
2181 | field = V4L2_FIELD_NONE; | ||
2182 | else | ||
2183 | field = V4L2_FIELD_INTERLACED; | ||
2184 | |||
2185 | videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops, | ||
2186 | NULL, &dev->slock, | ||
2187 | V4L2_BUF_TYPE_VIDEO_CAPTURE, field, | ||
2188 | sizeof(struct em28xx_buffer), fh, &dev->lock); | ||
2189 | |||
2190 | videobuf_queue_vmalloc_init(&fh->vb_vbiq, &em28xx_vbi_qops, | ||
2191 | NULL, &dev->slock, | ||
2192 | V4L2_BUF_TYPE_VBI_CAPTURE, | ||
2193 | V4L2_FIELD_SEQ_TB, | ||
2194 | sizeof(struct em28xx_buffer), fh, &dev->lock); | ||
2195 | mutex_unlock(&dev->lock); | ||
2196 | |||
2197 | return errCode; | ||
2198 | } | ||
2199 | |||
2200 | /* | ||
2201 | * em28xx_realease_resources() | ||
2202 | * unregisters the v4l2,i2c and usb devices | ||
2203 | * called when the device gets disconected or at module unload | ||
2204 | */ | ||
2205 | void em28xx_release_analog_resources(struct em28xx *dev) | ||
2206 | { | ||
2207 | |||
2208 | /*FIXME: I2C IR should be disconnected */ | ||
2209 | |||
2210 | if (dev->radio_dev) { | ||
2211 | if (video_is_registered(dev->radio_dev)) | ||
2212 | video_unregister_device(dev->radio_dev); | ||
2213 | else | ||
2214 | video_device_release(dev->radio_dev); | ||
2215 | dev->radio_dev = NULL; | ||
2216 | } | ||
2217 | if (dev->vbi_dev) { | ||
2218 | em28xx_info("V4L2 device %s deregistered\n", | ||
2219 | video_device_node_name(dev->vbi_dev)); | ||
2220 | if (video_is_registered(dev->vbi_dev)) | ||
2221 | video_unregister_device(dev->vbi_dev); | ||
2222 | else | ||
2223 | video_device_release(dev->vbi_dev); | ||
2224 | dev->vbi_dev = NULL; | ||
2225 | } | ||
2226 | if (dev->vdev) { | ||
2227 | em28xx_info("V4L2 device %s deregistered\n", | ||
2228 | video_device_node_name(dev->vdev)); | ||
2229 | if (video_is_registered(dev->vdev)) | ||
2230 | video_unregister_device(dev->vdev); | ||
2231 | else | ||
2232 | video_device_release(dev->vdev); | ||
2233 | dev->vdev = NULL; | ||
2234 | } | ||
2235 | } | ||
2236 | |||
2237 | /* | ||
2238 | * em28xx_v4l2_close() | ||
2239 | * stops streaming and deallocates all resources allocated by the v4l2 | ||
2240 | * calls and ioctls | ||
2241 | */ | ||
2242 | static int em28xx_v4l2_close(struct file *filp) | ||
2243 | { | ||
2244 | struct em28xx_fh *fh = filp->private_data; | ||
2245 | struct em28xx *dev = fh->dev; | ||
2246 | int errCode; | ||
2247 | |||
2248 | em28xx_videodbg("users=%d\n", dev->users); | ||
2249 | |||
2250 | mutex_lock(&dev->lock); | ||
2251 | if (res_check(fh, EM28XX_RESOURCE_VIDEO)) { | ||
2252 | videobuf_stop(&fh->vb_vidq); | ||
2253 | res_free(fh, EM28XX_RESOURCE_VIDEO); | ||
2254 | } | ||
2255 | |||
2256 | if (res_check(fh, EM28XX_RESOURCE_VBI)) { | ||
2257 | videobuf_stop(&fh->vb_vbiq); | ||
2258 | res_free(fh, EM28XX_RESOURCE_VBI); | ||
2259 | } | ||
2260 | |||
2261 | if (dev->users == 1) { | ||
2262 | /* the device is already disconnect, | ||
2263 | free the remaining resources */ | ||
2264 | if (dev->state & DEV_DISCONNECTED) { | ||
2265 | em28xx_release_resources(dev); | ||
2266 | kfree(dev->alt_max_pkt_size); | ||
2267 | kfree(dev); | ||
2268 | kfree(fh); | ||
2269 | mutex_unlock(&dev->lock); | ||
2270 | return 0; | ||
2271 | } | ||
2272 | |||
2273 | /* Save some power by putting tuner to sleep */ | ||
2274 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0); | ||
2275 | |||
2276 | /* do this before setting alternate! */ | ||
2277 | em28xx_uninit_isoc(dev, EM28XX_ANALOG_MODE); | ||
2278 | em28xx_set_mode(dev, EM28XX_SUSPEND); | ||
2279 | |||
2280 | /* set alternate 0 */ | ||
2281 | dev->alt = 0; | ||
2282 | em28xx_videodbg("setting alternate 0\n"); | ||
2283 | errCode = usb_set_interface(dev->udev, 0, 0); | ||
2284 | if (errCode < 0) { | ||
2285 | em28xx_errdev("cannot change alternate number to " | ||
2286 | "0 (error=%i)\n", errCode); | ||
2287 | } | ||
2288 | } | ||
2289 | |||
2290 | videobuf_mmap_free(&fh->vb_vidq); | ||
2291 | videobuf_mmap_free(&fh->vb_vbiq); | ||
2292 | kfree(fh); | ||
2293 | dev->users--; | ||
2294 | mutex_unlock(&dev->lock); | ||
2295 | return 0; | ||
2296 | } | ||
2297 | |||
2298 | /* | ||
2299 | * em28xx_v4l2_read() | ||
2300 | * will allocate buffers when called for the first time | ||
2301 | */ | ||
2302 | static ssize_t | ||
2303 | em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count, | ||
2304 | loff_t *pos) | ||
2305 | { | ||
2306 | struct em28xx_fh *fh = filp->private_data; | ||
2307 | struct em28xx *dev = fh->dev; | ||
2308 | int rc; | ||
2309 | |||
2310 | rc = check_dev(dev); | ||
2311 | if (rc < 0) | ||
2312 | return rc; | ||
2313 | |||
2314 | if (mutex_lock_interruptible(&dev->lock)) | ||
2315 | return -ERESTARTSYS; | ||
2316 | /* FIXME: read() is not prepared to allow changing the video | ||
2317 | resolution while streaming. Seems a bug at em28xx_set_fmt | ||
2318 | */ | ||
2319 | |||
2320 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
2321 | if (res_locked(dev, EM28XX_RESOURCE_VIDEO)) | ||
2322 | rc = -EBUSY; | ||
2323 | else | ||
2324 | rc = videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, | ||
2325 | filp->f_flags & O_NONBLOCK); | ||
2326 | } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | ||
2327 | if (!res_get(fh, EM28XX_RESOURCE_VBI)) | ||
2328 | rc = -EBUSY; | ||
2329 | else | ||
2330 | rc = videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0, | ||
2331 | filp->f_flags & O_NONBLOCK); | ||
2332 | } | ||
2333 | mutex_unlock(&dev->lock); | ||
2334 | |||
2335 | return rc; | ||
2336 | } | ||
2337 | |||
2338 | /* | ||
2339 | * em28xx_poll() | ||
2340 | * will allocate buffers when called for the first time | ||
2341 | */ | ||
2342 | static unsigned int em28xx_poll(struct file *filp, poll_table *wait) | ||
2343 | { | ||
2344 | struct em28xx_fh *fh = filp->private_data; | ||
2345 | struct em28xx *dev = fh->dev; | ||
2346 | int rc; | ||
2347 | |||
2348 | rc = check_dev(dev); | ||
2349 | if (rc < 0) | ||
2350 | return rc; | ||
2351 | |||
2352 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | ||
2353 | if (!res_get(fh, EM28XX_RESOURCE_VIDEO)) | ||
2354 | return POLLERR; | ||
2355 | return videobuf_poll_stream(filp, &fh->vb_vidq, wait); | ||
2356 | } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { | ||
2357 | if (!res_get(fh, EM28XX_RESOURCE_VBI)) | ||
2358 | return POLLERR; | ||
2359 | return videobuf_poll_stream(filp, &fh->vb_vbiq, wait); | ||
2360 | } else { | ||
2361 | return POLLERR; | ||
2362 | } | ||
2363 | } | ||
2364 | |||
2365 | static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait) | ||
2366 | { | ||
2367 | struct em28xx_fh *fh = filp->private_data; | ||
2368 | struct em28xx *dev = fh->dev; | ||
2369 | unsigned int res; | ||
2370 | |||
2371 | mutex_lock(&dev->lock); | ||
2372 | res = em28xx_poll(filp, wait); | ||
2373 | mutex_unlock(&dev->lock); | ||
2374 | return res; | ||
2375 | } | ||
2376 | |||
2377 | /* | ||
2378 | * em28xx_v4l2_mmap() | ||
2379 | */ | ||
2380 | static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) | ||
2381 | { | ||
2382 | struct em28xx_fh *fh = filp->private_data; | ||
2383 | struct em28xx *dev = fh->dev; | ||
2384 | int rc; | ||
2385 | |||
2386 | rc = check_dev(dev); | ||
2387 | if (rc < 0) | ||
2388 | return rc; | ||
2389 | |||
2390 | if (mutex_lock_interruptible(&dev->lock)) | ||
2391 | return -ERESTARTSYS; | ||
2392 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
2393 | rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); | ||
2394 | else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) | ||
2395 | rc = videobuf_mmap_mapper(&fh->vb_vbiq, vma); | ||
2396 | mutex_unlock(&dev->lock); | ||
2397 | |||
2398 | em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n", | ||
2399 | (unsigned long)vma->vm_start, | ||
2400 | (unsigned long)vma->vm_end-(unsigned long)vma->vm_start, | ||
2401 | rc); | ||
2402 | |||
2403 | return rc; | ||
2404 | } | ||
2405 | |||
2406 | static const struct v4l2_file_operations em28xx_v4l_fops = { | ||
2407 | .owner = THIS_MODULE, | ||
2408 | .open = em28xx_v4l2_open, | ||
2409 | .release = em28xx_v4l2_close, | ||
2410 | .read = em28xx_v4l2_read, | ||
2411 | .poll = em28xx_v4l2_poll, | ||
2412 | .mmap = em28xx_v4l2_mmap, | ||
2413 | .unlocked_ioctl = video_ioctl2, | ||
2414 | }; | ||
2415 | |||
2416 | static const struct v4l2_ioctl_ops video_ioctl_ops = { | ||
2417 | .vidioc_querycap = vidioc_querycap, | ||
2418 | .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, | ||
2419 | .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, | ||
2420 | .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, | ||
2421 | .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, | ||
2422 | .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap, | ||
2423 | .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap, | ||
2424 | .vidioc_enum_framesizes = vidioc_enum_framesizes, | ||
2425 | .vidioc_g_audio = vidioc_g_audio, | ||
2426 | .vidioc_s_audio = vidioc_s_audio, | ||
2427 | .vidioc_cropcap = vidioc_cropcap, | ||
2428 | .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap, | ||
2429 | .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap, | ||
2430 | .vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap, | ||
2431 | |||
2432 | .vidioc_reqbufs = vidioc_reqbufs, | ||
2433 | .vidioc_querybuf = vidioc_querybuf, | ||
2434 | .vidioc_qbuf = vidioc_qbuf, | ||
2435 | .vidioc_dqbuf = vidioc_dqbuf, | ||
2436 | .vidioc_g_std = vidioc_g_std, | ||
2437 | .vidioc_querystd = vidioc_querystd, | ||
2438 | .vidioc_s_std = vidioc_s_std, | ||
2439 | .vidioc_g_parm = vidioc_g_parm, | ||
2440 | .vidioc_s_parm = vidioc_s_parm, | ||
2441 | .vidioc_enum_input = vidioc_enum_input, | ||
2442 | .vidioc_g_input = vidioc_g_input, | ||
2443 | .vidioc_s_input = vidioc_s_input, | ||
2444 | .vidioc_queryctrl = vidioc_queryctrl, | ||
2445 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
2446 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
2447 | .vidioc_streamon = vidioc_streamon, | ||
2448 | .vidioc_streamoff = vidioc_streamoff, | ||
2449 | .vidioc_g_tuner = vidioc_g_tuner, | ||
2450 | .vidioc_s_tuner = vidioc_s_tuner, | ||
2451 | .vidioc_g_frequency = vidioc_g_frequency, | ||
2452 | .vidioc_s_frequency = vidioc_s_frequency, | ||
2453 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
2454 | .vidioc_g_register = vidioc_g_register, | ||
2455 | .vidioc_s_register = vidioc_s_register, | ||
2456 | .vidioc_g_chip_ident = vidioc_g_chip_ident, | ||
2457 | #endif | ||
2458 | }; | ||
2459 | |||
2460 | static const struct video_device em28xx_video_template = { | ||
2461 | .fops = &em28xx_v4l_fops, | ||
2462 | .release = video_device_release, | ||
2463 | .ioctl_ops = &video_ioctl_ops, | ||
2464 | |||
2465 | .tvnorms = V4L2_STD_ALL, | ||
2466 | .current_norm = V4L2_STD_PAL, | ||
2467 | }; | ||
2468 | |||
2469 | static const struct v4l2_file_operations radio_fops = { | ||
2470 | .owner = THIS_MODULE, | ||
2471 | .open = em28xx_v4l2_open, | ||
2472 | .release = em28xx_v4l2_close, | ||
2473 | .unlocked_ioctl = video_ioctl2, | ||
2474 | }; | ||
2475 | |||
2476 | static const struct v4l2_ioctl_ops radio_ioctl_ops = { | ||
2477 | .vidioc_querycap = radio_querycap, | ||
2478 | .vidioc_g_tuner = radio_g_tuner, | ||
2479 | .vidioc_enum_input = radio_enum_input, | ||
2480 | .vidioc_g_audio = radio_g_audio, | ||
2481 | .vidioc_s_tuner = radio_s_tuner, | ||
2482 | .vidioc_s_audio = radio_s_audio, | ||
2483 | .vidioc_s_input = radio_s_input, | ||
2484 | .vidioc_queryctrl = radio_queryctrl, | ||
2485 | .vidioc_g_ctrl = vidioc_g_ctrl, | ||
2486 | .vidioc_s_ctrl = vidioc_s_ctrl, | ||
2487 | .vidioc_g_frequency = vidioc_g_frequency, | ||
2488 | .vidioc_s_frequency = vidioc_s_frequency, | ||
2489 | #ifdef CONFIG_VIDEO_ADV_DEBUG | ||
2490 | .vidioc_g_register = vidioc_g_register, | ||
2491 | .vidioc_s_register = vidioc_s_register, | ||
2492 | #endif | ||
2493 | }; | ||
2494 | |||
2495 | static struct video_device em28xx_radio_template = { | ||
2496 | .name = "em28xx-radio", | ||
2497 | .fops = &radio_fops, | ||
2498 | .ioctl_ops = &radio_ioctl_ops, | ||
2499 | }; | ||
2500 | |||
2501 | /******************************** usb interface ******************************/ | ||
2502 | |||
2503 | |||
2504 | |||
2505 | static struct video_device *em28xx_vdev_init(struct em28xx *dev, | ||
2506 | const struct video_device *template, | ||
2507 | const char *type_name) | ||
2508 | { | ||
2509 | struct video_device *vfd; | ||
2510 | |||
2511 | vfd = video_device_alloc(); | ||
2512 | if (NULL == vfd) | ||
2513 | return NULL; | ||
2514 | |||
2515 | *vfd = *template; | ||
2516 | vfd->v4l2_dev = &dev->v4l2_dev; | ||
2517 | vfd->release = video_device_release; | ||
2518 | vfd->debug = video_debug; | ||
2519 | vfd->lock = &dev->lock; | ||
2520 | |||
2521 | snprintf(vfd->name, sizeof(vfd->name), "%s %s", | ||
2522 | dev->name, type_name); | ||
2523 | |||
2524 | video_set_drvdata(vfd, dev); | ||
2525 | return vfd; | ||
2526 | } | ||
2527 | |||
2528 | int em28xx_register_analog_devices(struct em28xx *dev) | ||
2529 | { | ||
2530 | u8 val; | ||
2531 | int ret; | ||
2532 | unsigned int maxw; | ||
2533 | |||
2534 | printk(KERN_INFO "%s: v4l2 driver version %s\n", | ||
2535 | dev->name, EM28XX_VERSION); | ||
2536 | |||
2537 | /* set default norm */ | ||
2538 | dev->norm = em28xx_video_template.current_norm; | ||
2539 | v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm); | ||
2540 | dev->interlaced = EM28XX_INTERLACED_DEFAULT; | ||
2541 | |||
2542 | /* Analog specific initialization */ | ||
2543 | dev->format = &format[0]; | ||
2544 | |||
2545 | maxw = norm_maxw(dev); | ||
2546 | /* MaxPacketSize for em2800 is too small to capture at full resolution | ||
2547 | * use half of maxw as the scaler can only scale to 50% */ | ||
2548 | if (dev->board.is_em2800) | ||
2549 | maxw /= 2; | ||
2550 | |||
2551 | em28xx_set_video_format(dev, format[0].fourcc, | ||
2552 | maxw, norm_maxh(dev)); | ||
2553 | |||
2554 | video_mux(dev, 0); | ||
2555 | |||
2556 | /* Audio defaults */ | ||
2557 | dev->mute = 1; | ||
2558 | dev->volume = 0x1f; | ||
2559 | |||
2560 | /* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */ | ||
2561 | val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK); | ||
2562 | em28xx_write_reg(dev, EM28XX_R0F_XCLK, | ||
2563 | (EM28XX_XCLK_AUDIO_UNMUTE | val)); | ||
2564 | |||
2565 | em28xx_set_outfmt(dev); | ||
2566 | em28xx_colorlevels_set_default(dev); | ||
2567 | em28xx_compression_disable(dev); | ||
2568 | |||
2569 | /* allocate and fill video video_device struct */ | ||
2570 | dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); | ||
2571 | if (!dev->vdev) { | ||
2572 | em28xx_errdev("cannot allocate video_device.\n"); | ||
2573 | return -ENODEV; | ||
2574 | } | ||
2575 | |||
2576 | /* register v4l2 video video_device */ | ||
2577 | ret = video_register_device(dev->vdev, VFL_TYPE_GRABBER, | ||
2578 | video_nr[dev->devno]); | ||
2579 | if (ret) { | ||
2580 | em28xx_errdev("unable to register video device (error=%i).\n", | ||
2581 | ret); | ||
2582 | return ret; | ||
2583 | } | ||
2584 | |||
2585 | /* Allocate and fill vbi video_device struct */ | ||
2586 | if (em28xx_vbi_supported(dev) == 1) { | ||
2587 | dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, | ||
2588 | "vbi"); | ||
2589 | |||
2590 | /* register v4l2 vbi video_device */ | ||
2591 | ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, | ||
2592 | vbi_nr[dev->devno]); | ||
2593 | if (ret < 0) { | ||
2594 | em28xx_errdev("unable to register vbi device\n"); | ||
2595 | return ret; | ||
2596 | } | ||
2597 | } | ||
2598 | |||
2599 | if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { | ||
2600 | dev->radio_dev = em28xx_vdev_init(dev, &em28xx_radio_template, | ||
2601 | "radio"); | ||
2602 | if (!dev->radio_dev) { | ||
2603 | em28xx_errdev("cannot allocate video_device.\n"); | ||
2604 | return -ENODEV; | ||
2605 | } | ||
2606 | ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, | ||
2607 | radio_nr[dev->devno]); | ||
2608 | if (ret < 0) { | ||
2609 | em28xx_errdev("can't register radio device\n"); | ||
2610 | return ret; | ||
2611 | } | ||
2612 | em28xx_info("Registered radio device as %s\n", | ||
2613 | video_device_node_name(dev->radio_dev)); | ||
2614 | } | ||
2615 | |||
2616 | em28xx_info("V4L2 video device registered as %s\n", | ||
2617 | video_device_node_name(dev->vdev)); | ||
2618 | |||
2619 | if (dev->vbi_dev) | ||
2620 | em28xx_info("V4L2 VBI device registered as %s\n", | ||
2621 | video_device_node_name(dev->vbi_dev)); | ||
2622 | |||
2623 | return 0; | ||
2624 | } | ||
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h deleted file mode 100644 index 8757523e6863..000000000000 --- a/drivers/media/video/em28xx/em28xx.h +++ /dev/null | |||
@@ -1,809 +0,0 @@ | |||
1 | /* | ||
2 | em28xx.h - driver for Empia EM2800/EM2820/2840 USB video capture devices | ||
3 | |||
4 | Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> | ||
5 | Ludovico Cavedon <cavedon@sssup.it> | ||
6 | Mauro Carvalho Chehab <mchehab@infradead.org> | ||
7 | |||
8 | Based on the em2800 driver from Sascha Sommer <saschasommer@freenet.de> | ||
9 | |||
10 | This program is free software; you can redistribute it and/or modify | ||
11 | it under the terms of the GNU General Public License as published by | ||
12 | the Free Software Foundation; either version 2 of the License, or | ||
13 | (at your option) any later version. | ||
14 | |||
15 | This program is distributed in the hope that it will be useful, | ||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | GNU General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU General Public License | ||
21 | along with this program; if not, write to the Free Software | ||
22 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | #ifndef _EM28XX_H | ||
26 | #define _EM28XX_H | ||
27 | |||
28 | #include <linux/workqueue.h> | ||
29 | #include <linux/i2c.h> | ||
30 | #include <linux/mutex.h> | ||
31 | #include <linux/videodev2.h> | ||
32 | |||
33 | #include <media/videobuf-vmalloc.h> | ||
34 | #include <media/v4l2-device.h> | ||
35 | #include <media/ir-kbd-i2c.h> | ||
36 | #include <media/rc-core.h> | ||
37 | #if defined(CONFIG_VIDEO_EM28XX_DVB) || defined(CONFIG_VIDEO_EM28XX_DVB_MODULE) | ||
38 | #include <media/videobuf-dvb.h> | ||
39 | #endif | ||
40 | #include "tuner-xc2028.h" | ||
41 | #include "xc5000.h" | ||
42 | #include "em28xx-reg.h" | ||
43 | |||
44 | /* Boards supported by driver */ | ||
45 | #define EM2800_BOARD_UNKNOWN 0 | ||
46 | #define EM2820_BOARD_UNKNOWN 1 | ||
47 | #define EM2820_BOARD_TERRATEC_CINERGY_250 2 | ||
48 | #define EM2820_BOARD_PINNACLE_USB_2 3 | ||
49 | #define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4 | ||
50 | #define EM2820_BOARD_MSI_VOX_USB_2 5 | ||
51 | #define EM2800_BOARD_TERRATEC_CINERGY_200 6 | ||
52 | #define EM2800_BOARD_LEADTEK_WINFAST_USBII 7 | ||
53 | #define EM2800_BOARD_KWORLD_USB2800 8 | ||
54 | #define EM2820_BOARD_PINNACLE_DVC_90 9 | ||
55 | #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 10 | ||
56 | #define EM2880_BOARD_TERRATEC_HYBRID_XS 11 | ||
57 | #define EM2820_BOARD_KWORLD_PVRTV2800RF 12 | ||
58 | #define EM2880_BOARD_TERRATEC_PRODIGY_XS 13 | ||
59 | #define EM2820_BOARD_PROLINK_PLAYTV_USB2 14 | ||
60 | #define EM2800_BOARD_VGEAR_POCKETTV 15 | ||
61 | #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 16 | ||
62 | #define EM2880_BOARD_PINNACLE_PCTV_HD_PRO 17 | ||
63 | #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2 18 | ||
64 | #define EM2860_BOARD_SAA711X_REFERENCE_DESIGN 19 | ||
65 | #define EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 20 | ||
66 | #define EM2800_BOARD_GRABBEEX_USB2800 21 | ||
67 | #define EM2750_BOARD_UNKNOWN 22 | ||
68 | #define EM2750_BOARD_DLCW_130 23 | ||
69 | #define EM2820_BOARD_DLINK_USB_TV 24 | ||
70 | #define EM2820_BOARD_GADMEI_UTV310 25 | ||
71 | #define EM2820_BOARD_HERCULES_SMART_TV_USB2 26 | ||
72 | #define EM2820_BOARD_PINNACLE_USB_2_FM1216ME 27 | ||
73 | #define EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE 28 | ||
74 | #define EM2860_BOARD_TVP5150_REFERENCE_DESIGN 29 | ||
75 | #define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30 | ||
76 | #define EM2821_BOARD_USBGEAR_VD204 31 | ||
77 | #define EM2821_BOARD_SUPERCOMP_USB_2 32 | ||
78 | #define EM2860_BOARD_ELGATO_VIDEO_CAPTURE 33 | ||
79 | #define EM2860_BOARD_TERRATEC_HYBRID_XS 34 | ||
80 | #define EM2860_BOARD_TYPHOON_DVD_MAKER 35 | ||
81 | #define EM2860_BOARD_NETGMBH_CAM 36 | ||
82 | #define EM2860_BOARD_GADMEI_UTV330 37 | ||
83 | #define EM2861_BOARD_YAKUMO_MOVIE_MIXER 38 | ||
84 | #define EM2861_BOARD_KWORLD_PVRTV_300U 39 | ||
85 | #define EM2861_BOARD_PLEXTOR_PX_TV100U 40 | ||
86 | #define EM2870_BOARD_KWORLD_350U 41 | ||
87 | #define EM2870_BOARD_KWORLD_355U 42 | ||
88 | #define EM2870_BOARD_TERRATEC_XS 43 | ||
89 | #define EM2870_BOARD_TERRATEC_XS_MT2060 44 | ||
90 | #define EM2870_BOARD_PINNACLE_PCTV_DVB 45 | ||
91 | #define EM2870_BOARD_COMPRO_VIDEOMATE 46 | ||
92 | #define EM2880_BOARD_KWORLD_DVB_305U 47 | ||
93 | #define EM2880_BOARD_KWORLD_DVB_310U 48 | ||
94 | #define EM2880_BOARD_MSI_DIGIVOX_AD 49 | ||
95 | #define EM2880_BOARD_MSI_DIGIVOX_AD_II 50 | ||
96 | #define EM2880_BOARD_TERRATEC_HYBRID_XS_FR 51 | ||
97 | #define EM2881_BOARD_DNT_DA2_HYBRID 52 | ||
98 | #define EM2881_BOARD_PINNACLE_HYBRID_PRO 53 | ||
99 | #define EM2882_BOARD_KWORLD_VS_DVBT 54 | ||
100 | #define EM2882_BOARD_TERRATEC_HYBRID_XS 55 | ||
101 | #define EM2882_BOARD_PINNACLE_HYBRID_PRO_330E 56 | ||
102 | #define EM2883_BOARD_KWORLD_HYBRID_330U 57 | ||
103 | #define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58 | ||
104 | #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60 | ||
105 | #define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61 | ||
106 | #define EM2820_BOARD_GADMEI_TVR200 62 | ||
107 | #define EM2860_BOARD_KAIOMY_TVNPC_U2 63 | ||
108 | #define EM2860_BOARD_EASYCAP 64 | ||
109 | #define EM2820_BOARD_IODATA_GVMVP_SZ 65 | ||
110 | #define EM2880_BOARD_EMPIRE_DUAL_TV 66 | ||
111 | #define EM2860_BOARD_TERRATEC_GRABBY 67 | ||
112 | #define EM2860_BOARD_TERRATEC_AV350 68 | ||
113 | #define EM2882_BOARD_KWORLD_ATSC_315U 69 | ||
114 | #define EM2882_BOARD_EVGA_INDTUBE 70 | ||
115 | #define EM2820_BOARD_SILVERCREST_WEBCAM 71 | ||
116 | #define EM2861_BOARD_GADMEI_UTV330PLUS 72 | ||
117 | #define EM2870_BOARD_REDDO_DVB_C_USB_BOX 73 | ||
118 | #define EM2800_BOARD_VC211A 74 | ||
119 | #define EM2882_BOARD_DIKOM_DK300 75 | ||
120 | #define EM2870_BOARD_KWORLD_A340 76 | ||
121 | #define EM2874_BOARD_LEADERSHIP_ISDBT 77 | ||
122 | #define EM28174_BOARD_PCTV_290E 78 | ||
123 | #define EM2884_BOARD_TERRATEC_H5 79 | ||
124 | #define EM28174_BOARD_PCTV_460E 80 | ||
125 | #define EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C 81 | ||
126 | #define EM2884_BOARD_CINERGY_HTC_STICK 82 | ||
127 | #define EM2860_BOARD_HT_VIDBOX_NW03 83 | ||
128 | #define EM2874_BOARD_MAXMEDIA_UB425_TC 84 | ||
129 | #define EM2884_BOARD_PCTV_510E 85 | ||
130 | #define EM2884_BOARD_PCTV_520E 86 | ||
131 | |||
132 | /* Limits minimum and default number of buffers */ | ||
133 | #define EM28XX_MIN_BUF 4 | ||
134 | #define EM28XX_DEF_BUF 8 | ||
135 | |||
136 | /*Limits the max URB message size */ | ||
137 | #define URB_MAX_CTRL_SIZE 80 | ||
138 | |||
139 | /* Params for validated field */ | ||
140 | #define EM28XX_BOARD_NOT_VALIDATED 1 | ||
141 | #define EM28XX_BOARD_VALIDATED 0 | ||
142 | |||
143 | /* Params for em28xx_cmd() audio */ | ||
144 | #define EM28XX_START_AUDIO 1 | ||
145 | #define EM28XX_STOP_AUDIO 0 | ||
146 | |||
147 | /* maximum number of em28xx boards */ | ||
148 | #define EM28XX_MAXBOARDS 4 /*FIXME: should be bigger */ | ||
149 | |||
150 | /* maximum number of frames that can be queued */ | ||
151 | #define EM28XX_NUM_FRAMES 5 | ||
152 | /* number of frames that get used for v4l2_read() */ | ||
153 | #define EM28XX_NUM_READ_FRAMES 2 | ||
154 | |||
155 | /* number of buffers for isoc transfers */ | ||
156 | #define EM28XX_NUM_BUFS 5 | ||
157 | #define EM28XX_DVB_NUM_BUFS 5 | ||
158 | |||
159 | /* number of packets for each buffer | ||
160 | windows requests only 64 packets .. so we better do the same | ||
161 | this is what I found out for all alternate numbers there! | ||
162 | */ | ||
163 | #define EM28XX_NUM_PACKETS 64 | ||
164 | #define EM28XX_DVB_MAX_PACKETS 64 | ||
165 | |||
166 | #define EM28XX_INTERLACED_DEFAULT 1 | ||
167 | |||
168 | /* | ||
169 | #define (use usbview if you want to get the other alternate number infos) | ||
170 | #define | ||
171 | #define alternate number 2 | ||
172 | #define Endpoint Address: 82 | ||
173 | Direction: in | ||
174 | Attribute: 1 | ||
175 | Type: Isoc | ||
176 | Max Packet Size: 1448 | ||
177 | Interval: 125us | ||
178 | |||
179 | alternate number 7 | ||
180 | |||
181 | Endpoint Address: 82 | ||
182 | Direction: in | ||
183 | Attribute: 1 | ||
184 | Type: Isoc | ||
185 | Max Packet Size: 3072 | ||
186 | Interval: 125us | ||
187 | */ | ||
188 | |||
189 | /* time to wait when stopping the isoc transfer */ | ||
190 | #define EM28XX_URB_TIMEOUT \ | ||
191 | msecs_to_jiffies(EM28XX_NUM_BUFS * EM28XX_NUM_PACKETS) | ||
192 | |||
193 | /* time in msecs to wait for i2c writes to finish */ | ||
194 | #define EM2800_I2C_WRITE_TIMEOUT 20 | ||
195 | |||
196 | enum em28xx_mode { | ||
197 | EM28XX_SUSPEND, | ||
198 | EM28XX_ANALOG_MODE, | ||
199 | EM28XX_DIGITAL_MODE, | ||
200 | }; | ||
201 | |||
202 | |||
203 | struct em28xx; | ||
204 | |||
205 | struct em28xx_usb_isoc_bufs { | ||
206 | /* max packet size of isoc transaction */ | ||
207 | int max_pkt_size; | ||
208 | |||
209 | /* number of packets in each buffer */ | ||
210 | int num_packets; | ||
211 | |||
212 | /* number of allocated urbs */ | ||
213 | int num_bufs; | ||
214 | |||
215 | /* urb for isoc transfers */ | ||
216 | struct urb **urb; | ||
217 | |||
218 | /* transfer buffers for isoc transfer */ | ||
219 | char **transfer_buffer; | ||
220 | }; | ||
221 | |||
222 | struct em28xx_usb_isoc_ctl { | ||
223 | /* isoc transfer buffers for analog mode */ | ||
224 | struct em28xx_usb_isoc_bufs analog_bufs; | ||
225 | |||
226 | /* isoc transfer buffers for digital mode */ | ||
227 | struct em28xx_usb_isoc_bufs digital_bufs; | ||
228 | |||
229 | /* Stores already requested buffers */ | ||
230 | struct em28xx_buffer *vid_buf; | ||
231 | struct em28xx_buffer *vbi_buf; | ||
232 | |||
233 | /* isoc urb callback */ | ||
234 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb); | ||
235 | |||
236 | }; | ||
237 | |||
238 | /* Struct to enumberate video formats */ | ||
239 | struct em28xx_fmt { | ||
240 | char *name; | ||
241 | u32 fourcc; /* v4l2 format id */ | ||
242 | int depth; | ||
243 | int reg; | ||
244 | }; | ||
245 | |||
246 | /* buffer for one video frame */ | ||
247 | struct em28xx_buffer { | ||
248 | /* common v4l buffer stuff -- must be first */ | ||
249 | struct videobuf_buffer vb; | ||
250 | |||
251 | struct list_head frame; | ||
252 | int top_field; | ||
253 | }; | ||
254 | |||
255 | struct em28xx_dmaqueue { | ||
256 | struct list_head active; | ||
257 | |||
258 | wait_queue_head_t wq; | ||
259 | |||
260 | /* Counters to control buffer fill */ | ||
261 | int pos; | ||
262 | }; | ||
263 | |||
264 | /* inputs */ | ||
265 | |||
266 | #define MAX_EM28XX_INPUT 4 | ||
267 | enum enum28xx_itype { | ||
268 | EM28XX_VMUX_COMPOSITE1 = 1, | ||
269 | EM28XX_VMUX_COMPOSITE2, | ||
270 | EM28XX_VMUX_COMPOSITE3, | ||
271 | EM28XX_VMUX_COMPOSITE4, | ||
272 | EM28XX_VMUX_SVIDEO, | ||
273 | EM28XX_VMUX_TELEVISION, | ||
274 | EM28XX_VMUX_CABLE, | ||
275 | EM28XX_VMUX_DVB, | ||
276 | EM28XX_VMUX_DEBUG, | ||
277 | EM28XX_RADIO, | ||
278 | }; | ||
279 | |||
280 | enum em28xx_ac97_mode { | ||
281 | EM28XX_NO_AC97 = 0, | ||
282 | EM28XX_AC97_EM202, | ||
283 | EM28XX_AC97_SIGMATEL, | ||
284 | EM28XX_AC97_OTHER, | ||
285 | }; | ||
286 | |||
287 | struct em28xx_audio_mode { | ||
288 | enum em28xx_ac97_mode ac97; | ||
289 | |||
290 | u16 ac97_feat; | ||
291 | u32 ac97_vendor_id; | ||
292 | |||
293 | unsigned int has_audio:1; | ||
294 | |||
295 | unsigned int i2s_3rates:1; | ||
296 | unsigned int i2s_5rates:1; | ||
297 | }; | ||
298 | |||
299 | /* em28xx has two audio inputs: tuner and line in. | ||
300 | However, on most devices, an auxiliary AC97 codec device is used. | ||
301 | The AC97 device may have several different inputs and outputs, | ||
302 | depending on their model. So, it is possible to use AC97 mixer to | ||
303 | address more than two different entries. | ||
304 | */ | ||
305 | enum em28xx_amux { | ||
306 | /* This is the only entry for em28xx tuner input */ | ||
307 | EM28XX_AMUX_VIDEO, /* em28xx tuner, AC97 mixer Video */ | ||
308 | |||
309 | EM28XX_AMUX_LINE_IN, /* AC97 mixer Line In */ | ||
310 | |||
311 | /* Some less-common mixer setups */ | ||
312 | EM28XX_AMUX_VIDEO2, /* em28xx Line in, AC97 mixer Video */ | ||
313 | EM28XX_AMUX_PHONE, | ||
314 | EM28XX_AMUX_MIC, | ||
315 | EM28XX_AMUX_CD, | ||
316 | EM28XX_AMUX_AUX, | ||
317 | EM28XX_AMUX_PCM_OUT, | ||
318 | }; | ||
319 | |||
320 | enum em28xx_aout { | ||
321 | /* AC97 outputs */ | ||
322 | EM28XX_AOUT_MASTER = 1 << 0, | ||
323 | EM28XX_AOUT_LINE = 1 << 1, | ||
324 | EM28XX_AOUT_MONO = 1 << 2, | ||
325 | EM28XX_AOUT_LFE = 1 << 3, | ||
326 | EM28XX_AOUT_SURR = 1 << 4, | ||
327 | |||
328 | /* PCM IN Mixer - used by AC97_RECORD_SELECT register */ | ||
329 | EM28XX_AOUT_PCM_IN = 1 << 7, | ||
330 | |||
331 | /* Bits 10-8 are used to indicate the PCM IN record select */ | ||
332 | EM28XX_AOUT_PCM_MIC_PCM = 0 << 8, | ||
333 | EM28XX_AOUT_PCM_CD = 1 << 8, | ||
334 | EM28XX_AOUT_PCM_VIDEO = 2 << 8, | ||
335 | EM28XX_AOUT_PCM_AUX = 3 << 8, | ||
336 | EM28XX_AOUT_PCM_LINE = 4 << 8, | ||
337 | EM28XX_AOUT_PCM_STEREO = 5 << 8, | ||
338 | EM28XX_AOUT_PCM_MONO = 6 << 8, | ||
339 | EM28XX_AOUT_PCM_PHONE = 7 << 8, | ||
340 | }; | ||
341 | |||
342 | static inline int ac97_return_record_select(int a_out) | ||
343 | { | ||
344 | return (a_out & 0x700) >> 8; | ||
345 | } | ||
346 | |||
347 | struct em28xx_reg_seq { | ||
348 | int reg; | ||
349 | unsigned char val, mask; | ||
350 | int sleep; | ||
351 | }; | ||
352 | |||
353 | struct em28xx_input { | ||
354 | enum enum28xx_itype type; | ||
355 | unsigned int vmux; | ||
356 | enum em28xx_amux amux; | ||
357 | enum em28xx_aout aout; | ||
358 | struct em28xx_reg_seq *gpio; | ||
359 | }; | ||
360 | |||
361 | #define INPUT(nr) (&em28xx_boards[dev->model].input[nr]) | ||
362 | |||
363 | enum em28xx_decoder { | ||
364 | EM28XX_NODECODER = 0, | ||
365 | EM28XX_TVP5150, | ||
366 | EM28XX_SAA711X, | ||
367 | }; | ||
368 | |||
369 | enum em28xx_sensor { | ||
370 | EM28XX_NOSENSOR = 0, | ||
371 | EM28XX_MT9V011, | ||
372 | EM28XX_MT9M001, | ||
373 | EM28XX_MT9M111, | ||
374 | }; | ||
375 | |||
376 | enum em28xx_adecoder { | ||
377 | EM28XX_NOADECODER = 0, | ||
378 | EM28XX_TVAUDIO, | ||
379 | }; | ||
380 | |||
381 | struct em28xx_board { | ||
382 | char *name; | ||
383 | int vchannels; | ||
384 | int tuner_type; | ||
385 | int tuner_addr; | ||
386 | |||
387 | /* i2c flags */ | ||
388 | unsigned int tda9887_conf; | ||
389 | |||
390 | /* GPIO sequences */ | ||
391 | struct em28xx_reg_seq *dvb_gpio; | ||
392 | struct em28xx_reg_seq *suspend_gpio; | ||
393 | struct em28xx_reg_seq *tuner_gpio; | ||
394 | struct em28xx_reg_seq *mute_gpio; | ||
395 | |||
396 | unsigned int is_em2800:1; | ||
397 | unsigned int has_msp34xx:1; | ||
398 | unsigned int mts_firmware:1; | ||
399 | unsigned int max_range_640_480:1; | ||
400 | unsigned int has_dvb:1; | ||
401 | unsigned int has_snapshot_button:1; | ||
402 | unsigned int is_webcam:1; | ||
403 | unsigned int valid:1; | ||
404 | unsigned int has_ir_i2c:1; | ||
405 | |||
406 | unsigned char xclk, i2c_speed; | ||
407 | unsigned char radio_addr; | ||
408 | unsigned short tvaudio_addr; | ||
409 | |||
410 | enum em28xx_decoder decoder; | ||
411 | enum em28xx_adecoder adecoder; | ||
412 | |||
413 | struct em28xx_input input[MAX_EM28XX_INPUT]; | ||
414 | struct em28xx_input radio; | ||
415 | char *ir_codes; | ||
416 | }; | ||
417 | |||
418 | struct em28xx_eeprom { | ||
419 | u32 id; /* 0x9567eb1a */ | ||
420 | u16 vendor_ID; | ||
421 | u16 product_ID; | ||
422 | |||
423 | u16 chip_conf; | ||
424 | |||
425 | u16 board_conf; | ||
426 | |||
427 | u16 string1, string2, string3; | ||
428 | |||
429 | u8 string_idx_table; | ||
430 | }; | ||
431 | |||
432 | /* device states */ | ||
433 | enum em28xx_dev_state { | ||
434 | DEV_INITIALIZED = 0x01, | ||
435 | DEV_DISCONNECTED = 0x02, | ||
436 | DEV_MISCONFIGURED = 0x04, | ||
437 | }; | ||
438 | |||
439 | #define EM28XX_AUDIO_BUFS 5 | ||
440 | #define EM28XX_NUM_AUDIO_PACKETS 64 | ||
441 | #define EM28XX_AUDIO_MAX_PACKET_SIZE 196 /* static value */ | ||
442 | #define EM28XX_CAPTURE_STREAM_EN 1 | ||
443 | |||
444 | /* em28xx extensions */ | ||
445 | #define EM28XX_AUDIO 0x10 | ||
446 | #define EM28XX_DVB 0x20 | ||
447 | #define EM28XX_RC 0x30 | ||
448 | |||
449 | /* em28xx resource types (used for res_get/res_lock etc */ | ||
450 | #define EM28XX_RESOURCE_VIDEO 0x01 | ||
451 | #define EM28XX_RESOURCE_VBI 0x02 | ||
452 | |||
453 | struct em28xx_audio { | ||
454 | char name[50]; | ||
455 | char *transfer_buffer[EM28XX_AUDIO_BUFS]; | ||
456 | struct urb *urb[EM28XX_AUDIO_BUFS]; | ||
457 | struct usb_device *udev; | ||
458 | unsigned int capture_transfer_done; | ||
459 | struct snd_pcm_substream *capture_pcm_substream; | ||
460 | |||
461 | unsigned int hwptr_done_capture; | ||
462 | struct snd_card *sndcard; | ||
463 | |||
464 | int users; | ||
465 | spinlock_t slock; | ||
466 | }; | ||
467 | |||
468 | struct em28xx; | ||
469 | |||
470 | struct em28xx_fh { | ||
471 | struct em28xx *dev; | ||
472 | int radio; | ||
473 | unsigned int resources; | ||
474 | |||
475 | struct videobuf_queue vb_vidq; | ||
476 | struct videobuf_queue vb_vbiq; | ||
477 | |||
478 | enum v4l2_buf_type type; | ||
479 | }; | ||
480 | |||
481 | /* main device struct */ | ||
482 | struct em28xx { | ||
483 | /* generic device properties */ | ||
484 | char name[30]; /* name (including minor) of the device */ | ||
485 | int model; /* index in the device_data struct */ | ||
486 | int devno; /* marks the number of this device */ | ||
487 | enum em28xx_chip_id chip_id; | ||
488 | |||
489 | int audio_ifnum; | ||
490 | |||
491 | struct v4l2_device v4l2_dev; | ||
492 | struct em28xx_board board; | ||
493 | |||
494 | /* Webcam specific fields */ | ||
495 | enum em28xx_sensor em28xx_sensor; | ||
496 | int sensor_xres, sensor_yres; | ||
497 | int sensor_xtal; | ||
498 | |||
499 | /* Allows progressive (e. g. non-interlaced) mode */ | ||
500 | int progressive; | ||
501 | |||
502 | /* Vinmode/Vinctl used at the driver */ | ||
503 | int vinmode, vinctl; | ||
504 | |||
505 | unsigned int has_audio_class:1; | ||
506 | unsigned int has_alsa_audio:1; | ||
507 | unsigned int is_audio_only:1; | ||
508 | |||
509 | /* Controls audio streaming */ | ||
510 | struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ | ||
511 | atomic_t stream_started; /* stream should be running if true */ | ||
512 | |||
513 | struct em28xx_fmt *format; | ||
514 | |||
515 | struct em28xx_IR *ir; | ||
516 | |||
517 | /* Some older em28xx chips needs a waiting time after writing */ | ||
518 | unsigned int wait_after_write; | ||
519 | |||
520 | struct list_head devlist; | ||
521 | |||
522 | u32 i2s_speed; /* I2S speed for audio digital stream */ | ||
523 | |||
524 | struct em28xx_audio_mode audio_mode; | ||
525 | |||
526 | int tuner_type; /* type of the tuner */ | ||
527 | int tuner_addr; /* tuner address */ | ||
528 | int tda9887_conf; | ||
529 | /* i2c i/o */ | ||
530 | struct i2c_adapter i2c_adap; | ||
531 | struct i2c_client i2c_client; | ||
532 | /* video for linux */ | ||
533 | int users; /* user count for exclusive use */ | ||
534 | struct video_device *vdev; /* video for linux device struct */ | ||
535 | v4l2_std_id norm; /* selected tv norm */ | ||
536 | int ctl_freq; /* selected frequency */ | ||
537 | unsigned int ctl_input; /* selected input */ | ||
538 | unsigned int ctl_ainput;/* selected audio input */ | ||
539 | unsigned int ctl_aoutput;/* selected audio output */ | ||
540 | int mute; | ||
541 | int volume; | ||
542 | /* frame properties */ | ||
543 | int width; /* current frame width */ | ||
544 | int height; /* current frame height */ | ||
545 | unsigned hscale; /* horizontal scale factor (see datasheet) */ | ||
546 | unsigned vscale; /* vertical scale factor (see datasheet) */ | ||
547 | int interlaced; /* 1=interlace fileds, 0=just top fileds */ | ||
548 | unsigned int video_bytesread; /* Number of bytes read */ | ||
549 | |||
550 | unsigned long hash; /* eeprom hash - for boards with generic ID */ | ||
551 | unsigned long i2c_hash; /* i2c devicelist hash - | ||
552 | for boards with generic ID */ | ||
553 | |||
554 | struct em28xx_audio adev; | ||
555 | |||
556 | /* states */ | ||
557 | enum em28xx_dev_state state; | ||
558 | |||
559 | /* vbi related state tracking */ | ||
560 | int capture_type; | ||
561 | int vbi_read; | ||
562 | unsigned char cur_field; | ||
563 | unsigned int vbi_width; | ||
564 | unsigned int vbi_height; /* lines per field */ | ||
565 | |||
566 | struct work_struct request_module_wk; | ||
567 | |||
568 | /* locks */ | ||
569 | struct mutex lock; | ||
570 | struct mutex ctrl_urb_lock; /* protects urb_buf */ | ||
571 | /* spinlock_t queue_lock; */ | ||
572 | struct list_head inqueue, outqueue; | ||
573 | struct video_device *vbi_dev; | ||
574 | struct video_device *radio_dev; | ||
575 | |||
576 | /* resources in use */ | ||
577 | unsigned int resources; | ||
578 | |||
579 | unsigned char eedata[256]; | ||
580 | |||
581 | /* Isoc control struct */ | ||
582 | struct em28xx_dmaqueue vidq; | ||
583 | struct em28xx_dmaqueue vbiq; | ||
584 | struct em28xx_usb_isoc_ctl isoc_ctl; | ||
585 | spinlock_t slock; | ||
586 | |||
587 | /* usb transfer */ | ||
588 | struct usb_device *udev; /* the usb device */ | ||
589 | int alt; /* alternate */ | ||
590 | int max_pkt_size; /* max packet size of isoc transaction */ | ||
591 | int num_alt; /* Number of alternative settings */ | ||
592 | unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */ | ||
593 | int dvb_alt; /* alternate for DVB */ | ||
594 | unsigned int dvb_max_pkt_size; /* wMaxPacketSize for DVB */ | ||
595 | char urb_buf[URB_MAX_CTRL_SIZE]; /* urb control msg buffer */ | ||
596 | |||
597 | /* helper funcs that call usb_control_msg */ | ||
598 | int (*em28xx_write_regs) (struct em28xx *dev, u16 reg, | ||
599 | char *buf, int len); | ||
600 | int (*em28xx_read_reg) (struct em28xx *dev, u16 reg); | ||
601 | int (*em28xx_read_reg_req_len) (struct em28xx *dev, u8 req, u16 reg, | ||
602 | char *buf, int len); | ||
603 | int (*em28xx_write_regs_req) (struct em28xx *dev, u8 req, u16 reg, | ||
604 | char *buf, int len); | ||
605 | int (*em28xx_read_reg_req) (struct em28xx *dev, u8 req, u16 reg); | ||
606 | |||
607 | enum em28xx_mode mode; | ||
608 | |||
609 | /* register numbers for GPO/GPIO registers */ | ||
610 | u16 reg_gpo_num, reg_gpio_num; | ||
611 | |||
612 | /* Caches GPO and GPIO registers */ | ||
613 | unsigned char reg_gpo, reg_gpio; | ||
614 | |||
615 | /* Snapshot button */ | ||
616 | char snapshot_button_path[30]; /* path of the input dev */ | ||
617 | struct input_dev *sbutton_input_dev; | ||
618 | struct delayed_work sbutton_query_work; | ||
619 | |||
620 | struct em28xx_dvb *dvb; | ||
621 | |||
622 | /* I2C keyboard data */ | ||
623 | struct IR_i2c_init_data init_data; | ||
624 | }; | ||
625 | |||
626 | struct em28xx_ops { | ||
627 | struct list_head next; | ||
628 | char *name; | ||
629 | int id; | ||
630 | int (*init)(struct em28xx *); | ||
631 | int (*fini)(struct em28xx *); | ||
632 | }; | ||
633 | |||
634 | /* Provided by em28xx-i2c.c */ | ||
635 | void em28xx_do_i2c_scan(struct em28xx *dev); | ||
636 | int em28xx_i2c_register(struct em28xx *dev); | ||
637 | int em28xx_i2c_unregister(struct em28xx *dev); | ||
638 | |||
639 | /* Provided by em28xx-core.c */ | ||
640 | |||
641 | u32 em28xx_request_buffers(struct em28xx *dev, u32 count); | ||
642 | void em28xx_queue_unusedframes(struct em28xx *dev); | ||
643 | void em28xx_release_buffers(struct em28xx *dev); | ||
644 | |||
645 | int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | ||
646 | char *buf, int len); | ||
647 | int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg); | ||
648 | int em28xx_read_reg(struct em28xx *dev, u16 reg); | ||
649 | int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | ||
650 | int len); | ||
651 | int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len); | ||
652 | int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val); | ||
653 | int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, | ||
654 | u8 bitmask); | ||
655 | |||
656 | int em28xx_read_ac97(struct em28xx *dev, u8 reg); | ||
657 | int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val); | ||
658 | |||
659 | int em28xx_audio_analog_set(struct em28xx *dev); | ||
660 | int em28xx_audio_setup(struct em28xx *dev); | ||
661 | |||
662 | int em28xx_colorlevels_set_default(struct em28xx *dev); | ||
663 | int em28xx_capture_start(struct em28xx *dev, int start); | ||
664 | int em28xx_vbi_supported(struct em28xx *dev); | ||
665 | int em28xx_set_outfmt(struct em28xx *dev); | ||
666 | int em28xx_resolution_set(struct em28xx *dev); | ||
667 | int em28xx_set_alternate(struct em28xx *dev); | ||
668 | int em28xx_alloc_isoc(struct em28xx *dev, enum em28xx_mode mode, | ||
669 | int max_packets, int num_bufs, int max_pkt_size); | ||
670 | int em28xx_init_isoc(struct em28xx *dev, enum em28xx_mode mode, | ||
671 | int max_packets, int num_bufs, int max_pkt_size, | ||
672 | int (*isoc_copy) (struct em28xx *dev, struct urb *urb)); | ||
673 | void em28xx_uninit_isoc(struct em28xx *dev, enum em28xx_mode mode); | ||
674 | void em28xx_stop_urbs(struct em28xx *dev); | ||
675 | int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev); | ||
676 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); | ||
677 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); | ||
678 | void em28xx_wake_i2c(struct em28xx *dev); | ||
679 | int em28xx_register_extension(struct em28xx_ops *dev); | ||
680 | void em28xx_unregister_extension(struct em28xx_ops *dev); | ||
681 | void em28xx_init_extension(struct em28xx *dev); | ||
682 | void em28xx_close_extension(struct em28xx *dev); | ||
683 | |||
684 | /* Provided by em28xx-video.c */ | ||
685 | int em28xx_register_analog_devices(struct em28xx *dev); | ||
686 | void em28xx_release_analog_resources(struct em28xx *dev); | ||
687 | |||
688 | /* Provided by em28xx-cards.c */ | ||
689 | extern int em2800_variant_detect(struct usb_device *udev, int model); | ||
690 | extern struct em28xx_board em28xx_boards[]; | ||
691 | extern struct usb_device_id em28xx_id_table[]; | ||
692 | extern const unsigned int em28xx_bcount; | ||
693 | int em28xx_tuner_callback(void *ptr, int component, int command, int arg); | ||
694 | void em28xx_release_resources(struct em28xx *dev); | ||
695 | |||
696 | /* Provided by em28xx-vbi.c */ | ||
697 | extern struct videobuf_queue_ops em28xx_vbi_qops; | ||
698 | |||
699 | /* printk macros */ | ||
700 | |||
701 | #define em28xx_err(fmt, arg...) do {\ | ||
702 | printk(KERN_ERR fmt , ##arg); } while (0) | ||
703 | |||
704 | #define em28xx_errdev(fmt, arg...) do {\ | ||
705 | printk(KERN_ERR "%s: "fmt,\ | ||
706 | dev->name , ##arg); } while (0) | ||
707 | |||
708 | #define em28xx_info(fmt, arg...) do {\ | ||
709 | printk(KERN_INFO "%s: "fmt,\ | ||
710 | dev->name , ##arg); } while (0) | ||
711 | #define em28xx_warn(fmt, arg...) do {\ | ||
712 | printk(KERN_WARNING "%s: "fmt,\ | ||
713 | dev->name , ##arg); } while (0) | ||
714 | |||
715 | static inline int em28xx_compression_disable(struct em28xx *dev) | ||
716 | { | ||
717 | /* side effect of disabling scaler and mixer */ | ||
718 | return em28xx_write_reg(dev, EM28XX_R26_COMPR, 0x00); | ||
719 | } | ||
720 | |||
721 | static inline int em28xx_contrast_get(struct em28xx *dev) | ||
722 | { | ||
723 | return em28xx_read_reg(dev, EM28XX_R20_YGAIN) & 0x1f; | ||
724 | } | ||
725 | |||
726 | static inline int em28xx_brightness_get(struct em28xx *dev) | ||
727 | { | ||
728 | return em28xx_read_reg(dev, EM28XX_R21_YOFFSET); | ||
729 | } | ||
730 | |||
731 | static inline int em28xx_saturation_get(struct em28xx *dev) | ||
732 | { | ||
733 | return em28xx_read_reg(dev, EM28XX_R22_UVGAIN) & 0x1f; | ||
734 | } | ||
735 | |||
736 | static inline int em28xx_u_balance_get(struct em28xx *dev) | ||
737 | { | ||
738 | return em28xx_read_reg(dev, EM28XX_R23_UOFFSET); | ||
739 | } | ||
740 | |||
741 | static inline int em28xx_v_balance_get(struct em28xx *dev) | ||
742 | { | ||
743 | return em28xx_read_reg(dev, EM28XX_R24_VOFFSET); | ||
744 | } | ||
745 | |||
746 | static inline int em28xx_gamma_get(struct em28xx *dev) | ||
747 | { | ||
748 | return em28xx_read_reg(dev, EM28XX_R14_GAMMA) & 0x3f; | ||
749 | } | ||
750 | |||
751 | static inline int em28xx_contrast_set(struct em28xx *dev, s32 val) | ||
752 | { | ||
753 | u8 tmp = (u8) val; | ||
754 | return em28xx_write_regs(dev, EM28XX_R20_YGAIN, &tmp, 1); | ||
755 | } | ||
756 | |||
757 | static inline int em28xx_brightness_set(struct em28xx *dev, s32 val) | ||
758 | { | ||
759 | u8 tmp = (u8) val; | ||
760 | return em28xx_write_regs(dev, EM28XX_R21_YOFFSET, &tmp, 1); | ||
761 | } | ||
762 | |||
763 | static inline int em28xx_saturation_set(struct em28xx *dev, s32 val) | ||
764 | { | ||
765 | u8 tmp = (u8) val; | ||
766 | return em28xx_write_regs(dev, EM28XX_R22_UVGAIN, &tmp, 1); | ||
767 | } | ||
768 | |||
769 | static inline int em28xx_u_balance_set(struct em28xx *dev, s32 val) | ||
770 | { | ||
771 | u8 tmp = (u8) val; | ||
772 | return em28xx_write_regs(dev, EM28XX_R23_UOFFSET, &tmp, 1); | ||
773 | } | ||
774 | |||
775 | static inline int em28xx_v_balance_set(struct em28xx *dev, s32 val) | ||
776 | { | ||
777 | u8 tmp = (u8) val; | ||
778 | return em28xx_write_regs(dev, EM28XX_R24_VOFFSET, &tmp, 1); | ||
779 | } | ||
780 | |||
781 | static inline int em28xx_gamma_set(struct em28xx *dev, s32 val) | ||
782 | { | ||
783 | u8 tmp = (u8) val; | ||
784 | return em28xx_write_regs(dev, EM28XX_R14_GAMMA, &tmp, 1); | ||
785 | } | ||
786 | |||
787 | /*FIXME: maxw should be dependent of alt mode */ | ||
788 | static inline unsigned int norm_maxw(struct em28xx *dev) | ||
789 | { | ||
790 | if (dev->board.is_webcam) | ||
791 | return dev->sensor_xres; | ||
792 | |||
793 | if (dev->board.max_range_640_480) | ||
794 | return 640; | ||
795 | |||
796 | return 720; | ||
797 | } | ||
798 | |||
799 | static inline unsigned int norm_maxh(struct em28xx *dev) | ||
800 | { | ||
801 | if (dev->board.is_webcam) | ||
802 | return dev->sensor_yres; | ||
803 | |||
804 | if (dev->board.max_range_640_480) | ||
805 | return 480; | ||
806 | |||
807 | return (dev->norm & V4L2_STD_625_50) ? 576 : 480; | ||
808 | } | ||
809 | #endif | ||