aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@linuxtv.org>2009-03-11 02:00:40 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:43:25 -0400
commit8b2f079523450fa2d65cbb3f8453820bf1e17533 (patch)
tree8cb0df3d17674cbe1cc012010b3d322e1235a53f
parent968cf78285ef03672ae514e9ad7a60919eb97551 (diff)
V4L/DVB (11066): au0828: add support for analog functionality in bridge
Add support for the analog functionality found in the au0828 bridge Thanks to Michael Krufky <mkrufky@linuxtv.org> and Steven Toth <stoth@linuxtv.org> for providing sample hardware, engineering level support, and testing. Signed-off-by: Devin Heitmueller <dheitmueller@linuxtv.org> Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> [mchehab@redhat.com: fix compilation by adding linux/version.h] Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/au0828/Makefile2
-rw-r--r--drivers/media/video/au0828/au0828-cards.c41
-rw-r--r--drivers/media/video/au0828/au0828-core.c33
-rw-r--r--drivers/media/video/au0828/au0828-reg.h6
-rw-r--r--drivers/media/video/au0828/au0828-video.c1677
-rw-r--r--drivers/media/video/au0828/au0828.h174
6 files changed, 1920 insertions, 13 deletions
diff --git a/drivers/media/video/au0828/Makefile b/drivers/media/video/au0828/Makefile
index cd2c58281b4e..4d2623158188 100644
--- a/drivers/media/video/au0828/Makefile
+++ b/drivers/media/video/au0828/Makefile
@@ -1,4 +1,4 @@
1au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o 1au0828-objs := au0828-core.o au0828-i2c.o au0828-cards.o au0828-dvb.o au0828-video.o
2 2
3obj-$(CONFIG_VIDEO_AU0828) += au0828.o 3obj-$(CONFIG_VIDEO_AU0828) += au0828.o
4 4
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index d60123b413f5..aa79e6b7ecab 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -21,6 +21,18 @@
21 21
22#include "au0828.h" 22#include "au0828.h"
23#include "au0828-cards.h" 23#include "au0828-cards.h"
24#include "au8522.h"
25
26void hvr950q_cs5340_audio(void *priv, int enable)
27{
28 /* Because the HVR-950q shares an i2s bus between the cs5340 and the
29 au8522, we need to hold cs5340 in reset when using the au8522 */
30 struct au0828_dev *dev = priv;
31 if (enable == 1)
32 au0828_set(dev, REG_000, 0x10);
33 else
34 au0828_clear(dev, REG_000, 0x10);
35}
24 36
25struct au0828_board au0828_boards[] = { 37struct au0828_board au0828_boards[] = {
26 [AU0828_BOARD_UNKNOWN] = { 38 [AU0828_BOARD_UNKNOWN] = {
@@ -31,6 +43,25 @@ struct au0828_board au0828_boards[] = {
31 }, 43 },
32 [AU0828_BOARD_HAUPPAUGE_HVR950Q] = { 44 [AU0828_BOARD_HAUPPAUGE_HVR950Q] = {
33 .name = "Hauppauge HVR950Q", 45 .name = "Hauppauge HVR950Q",
46 .input = {
47 {
48 .type = AU0828_VMUX_TELEVISION,
49 .vmux = AU8522_COMPOSITE_CH4_SIF,
50 .amux = AU8522_AUDIO_SIF,
51 },
52 {
53 .type = AU0828_VMUX_COMPOSITE,
54 .vmux = AU8522_COMPOSITE_CH1,
55 .amux = AU8522_AUDIO_NONE,
56 .audio_setup = hvr950q_cs5340_audio,
57 },
58 {
59 .type = AU0828_VMUX_SVIDEO,
60 .vmux = AU8522_SVIDEO_CH13,
61 .amux = AU8522_AUDIO_NONE,
62 .audio_setup = hvr950q_cs5340_audio,
63 },
64 },
34 }, 65 },
35 [AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL] = { 66 [AU0828_BOARD_HAUPPAUGE_HVR950Q_MXL] = {
36 .name = "Hauppauge HVR950Q rev xxF8", 67 .name = "Hauppauge HVR950Q rev xxF8",
@@ -144,21 +175,23 @@ void au0828_gpio_setup(struct au0828_dev *dev)
144 * 4 - CS5340 175 * 4 - CS5340
145 * 5 - AU8522 Demodulator 176 * 5 - AU8522 Demodulator
146 * 6 - eeprom W/P 177 * 6 - eeprom W/P
178 * 7 - power supply
147 * 9 - XC5000 Tuner 179 * 9 - XC5000 Tuner
148 */ 180 */
149 181
150 /* Into reset */ 182 /* Into reset */
151 au0828_write(dev, REG_003, 0x02); 183 au0828_write(dev, REG_003, 0x02);
152 au0828_write(dev, REG_002, 0x88 | 0x20); 184 au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10);
153 au0828_write(dev, REG_001, 0x0); 185 au0828_write(dev, REG_001, 0x0);
154 au0828_write(dev, REG_000, 0x0); 186 au0828_write(dev, REG_000, 0x0);
155 msleep(100); 187 msleep(100);
156 188
157 /* Out of reset */ 189 /* Out of reset (leave the cs5340 in reset until needed) */
158 au0828_write(dev, REG_003, 0x02); 190 au0828_write(dev, REG_003, 0x02);
159 au0828_write(dev, REG_001, 0x02); 191 au0828_write(dev, REG_001, 0x02);
160 au0828_write(dev, REG_002, 0x88 | 0x20); 192 au0828_write(dev, REG_002, 0x80 | 0x20 | 0x10);
161 au0828_write(dev, REG_000, 0x88 | 0x20 | 0x40); 193 au0828_write(dev, REG_000, 0x80 | 0x40 | 0x20);
194
162 msleep(250); 195 msleep(250);
163 break; 196 break;
164 case AU0828_BOARD_DVICO_FUSIONHDTV7: 197 case AU0828_BOARD_DVICO_FUSIONHDTV7:
diff --git a/drivers/media/video/au0828/au0828-core.c b/drivers/media/video/au0828/au0828-core.c
index 5765e8656376..680e88f61397 100644
--- a/drivers/media/video/au0828/au0828-core.c
+++ b/drivers/media/video/au0828/au0828-core.c
@@ -146,6 +146,8 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
146 /* Digital TV */ 146 /* Digital TV */
147 au0828_dvb_unregister(dev); 147 au0828_dvb_unregister(dev);
148 148
149 au0828_analog_unregister(dev);
150
149 /* I2C */ 151 /* I2C */
150 au0828_i2c_unregister(dev); 152 au0828_i2c_unregister(dev);
151 153
@@ -162,9 +164,11 @@ static void au0828_usb_disconnect(struct usb_interface *interface)
162static int au0828_usb_probe(struct usb_interface *interface, 164static int au0828_usb_probe(struct usb_interface *interface,
163 const struct usb_device_id *id) 165 const struct usb_device_id *id)
164{ 166{
165 int ifnum; 167 int ifnum, i;
166 struct au0828_dev *dev; 168 struct au0828_dev *dev;
167 struct usb_device *usbdev = interface_to_usbdev(interface); 169 struct usb_device *usbdev = interface_to_usbdev(interface);
170 struct usb_host_interface *iface_desc;
171 struct usb_endpoint_descriptor *endpoint;
168 172
169 ifnum = interface->altsetting->desc.bInterfaceNumber; 173 ifnum = interface->altsetting->desc.bInterfaceNumber;
170 174
@@ -189,6 +193,30 @@ static int au0828_usb_probe(struct usb_interface *interface,
189 193
190 usb_set_intfdata(interface, dev); 194 usb_set_intfdata(interface, dev);
191 195
196 /* set au0828 usb interface0 to as5 */
197 usb_set_interface(usbdev,
198 interface->cur_altsetting->desc.bInterfaceNumber, 5);
199
200 /* Figure out which endpoint has the isoc interface */
201 iface_desc = interface->cur_altsetting;
202 for(i = 0; i < iface_desc->desc.bNumEndpoints; i++){
203 endpoint = &iface_desc->endpoint[i].desc;
204 if(((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) &&
205 ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_ISOC)){
206
207 /* we find our isoc in endpoint */
208 u16 tmp = le16_to_cpu(endpoint->wMaxPacketSize);
209 dev->max_pkt_size = (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1);
210 dev->isoc_in_endpointaddr = endpoint->bEndpointAddress;
211 }
212 }
213 if(!(dev->isoc_in_endpointaddr)) {
214 printk("Could not locate isoc endpoint\n");
215 kfree(dev);
216 return -ENODEV;
217 }
218
219
192 /* Power Up the bridge */ 220 /* Power Up the bridge */
193 au0828_write(dev, REG_600, 1 << 4); 221 au0828_write(dev, REG_600, 1 << 4);
194 222
@@ -201,6 +229,9 @@ static int au0828_usb_probe(struct usb_interface *interface,
201 /* Setup */ 229 /* Setup */
202 au0828_card_setup(dev); 230 au0828_card_setup(dev);
203 231
232 /* Analog TV */
233 au0828_analog_register(dev);
234
204 /* Digital TV */ 235 /* Digital TV */
205 au0828_dvb_register(dev); 236 au0828_dvb_register(dev);
206 237
diff --git a/drivers/media/video/au0828/au0828-reg.h b/drivers/media/video/au0828/au0828-reg.h
index 1e87fa0c6842..b15e4a3b6fc0 100644
--- a/drivers/media/video/au0828/au0828-reg.h
+++ b/drivers/media/video/au0828/au0828-reg.h
@@ -27,6 +27,9 @@
27#define REG_002 0x002 27#define REG_002 0x002
28#define REG_003 0x003 28#define REG_003 0x003
29 29
30#define AU0828_SENSORCTRL_100 0x100
31#define AU0828_SENSORCTRL_VBI_103 0x103
32
30#define REG_200 0x200 33#define REG_200 0x200
31#define REG_201 0x201 34#define REG_201 0x201
32#define REG_202 0x202 35#define REG_202 0x202
@@ -35,4 +38,7 @@
35#define REG_209 0x209 38#define REG_209 0x209
36#define REG_2FF 0x2ff 39#define REG_2FF 0x2ff
37 40
41/* Audio registers */
42#define AU0828_AUDIOCTRL_50C 0x50C
43
38#define REG_600 0x600 44#define REG_600 0x600
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
new file mode 100644
index 000000000000..e34464f81f36
--- /dev/null
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -0,0 +1,1677 @@
1/*
2 * Auvitek AU0828 USB Bridge (Analog video support)
3 *
4 * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
5 * Copyright (C) 2005-2008 Auvitek International, Ltd.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * As published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 */
22
23/* Developer Notes:
24 *
25 * VBI support is not yet working
26 * The hardware scaler supported is unimplemented
27 * AC97 audio support is unimplemented (only i2s audio mode)
28 *
29 */
30
31#include <linux/module.h>
32#include <linux/init.h>
33#include <linux/device.h>
34#include <linux/suspend.h>
35#include <linux/version.h>
36#include <linux/videodev.h>
37#include <media/v4l2-common.h>
38#include <media/v4l2-ioctl.h>
39#include <media/v4l2-chip-ident.h>
40#include <media/tuner.h>
41#include "au0828.h"
42#include "au0828-reg.h"
43
44static LIST_HEAD(au0828_devlist);
45static DEFINE_MUTEX(au0828_sysfs_lock);
46
47#define AU0828_VERSION_CODE KERNEL_VERSION(0, 0, 1)
48
49/* Forward declarations */
50void au0828_analog_stream_reset(struct au0828_dev *dev);
51
52/* ------------------------------------------------------------------
53 Videobuf operations
54 ------------------------------------------------------------------*/
55
56static unsigned int isoc_debug;
57module_param(isoc_debug, int, 0644);
58MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
59
60#define au0828_isocdbg(fmt, arg...) \
61do {\
62 if (isoc_debug) { \
63 printk(KERN_INFO "au0828 %s :"fmt, \
64 __func__ , ##arg); \
65 } \
66 } while (0)
67
68static inline void print_err_status(struct au0828_dev *dev,
69 int packet, int status)
70{
71 char *errmsg = "Unknown";
72
73 switch (status) {
74 case -ENOENT:
75 errmsg = "unlinked synchronuously";
76 break;
77 case -ECONNRESET:
78 errmsg = "unlinked asynchronuously";
79 break;
80 case -ENOSR:
81 errmsg = "Buffer error (overrun)";
82 break;
83 case -EPIPE:
84 errmsg = "Stalled (device not responding)";
85 break;
86 case -EOVERFLOW:
87 errmsg = "Babble (bad cable?)";
88 break;
89 case -EPROTO:
90 errmsg = "Bit-stuff error (bad cable?)";
91 break;
92 case -EILSEQ:
93 errmsg = "CRC/Timeout (could be anything)";
94 break;
95 case -ETIME:
96 errmsg = "Device does not respond";
97 break;
98 }
99 if (packet < 0) {
100 au0828_isocdbg("URB status %d [%s].\n", status, errmsg);
101 } else {
102 au0828_isocdbg("URB packet %d, status %d [%s].\n",
103 packet, status, errmsg);
104 }
105}
106
107static int check_dev(struct au0828_dev *dev)
108{
109 if (dev->dev_state & DEV_DISCONNECTED) {
110 printk("v4l2 ioctl: device not present\n");
111 return -ENODEV;
112 }
113
114 if (dev->dev_state & DEV_MISCONFIGURED) {
115 printk("v4l2 ioctl: device is misconfigured; "
116 "close and open it again\n");
117 return -EIO;
118 }
119 return 0;
120}
121
122/*
123 * IRQ callback, called by URB callback
124 */
125static void au0828_irq_callback(struct urb *urb)
126{
127 struct au0828_dmaqueue *dma_q = urb->context;
128 struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
129 int rc, i;
130
131 switch (urb->status) {
132 case 0: /* success */
133 case -ETIMEDOUT: /* NAK */
134 break;
135 case -ECONNRESET: /* kill */
136 case -ENOENT:
137 case -ESHUTDOWN:
138 au0828_isocdbg("au0828_irq_callback called: status kill\n");
139 return;
140 default: /* unknown error */
141 au0828_isocdbg("urb completition error %d.\n", urb->status);
142 break;
143 }
144
145 /* Copy data from URB */
146 spin_lock(&dev->slock);
147 rc = dev->isoc_ctl.isoc_copy(dev, urb);
148 spin_unlock(&dev->slock);
149
150 /* Reset urb buffers */
151 for (i = 0; i < urb->number_of_packets; i++) {
152 urb->iso_frame_desc[i].status = 0;
153 urb->iso_frame_desc[i].actual_length = 0;
154 }
155 urb->status = 0;
156
157 urb->status = usb_submit_urb(urb, GFP_ATOMIC);
158 if (urb->status) {
159 au0828_isocdbg("urb resubmit failed (error=%i)\n",
160 urb->status);
161 }
162}
163
164/*
165 * Stop and Deallocate URBs
166 */
167void au0828_uninit_isoc(struct au0828_dev *dev)
168{
169 struct urb *urb;
170 int i;
171
172 au0828_isocdbg("au0828: called au0828_uninit_isoc\n");
173
174 dev->isoc_ctl.nfields = -1;
175 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
176 urb = dev->isoc_ctl.urb[i];
177 if (urb) {
178 if (!irqs_disabled())
179 usb_kill_urb(urb);
180 else
181 usb_unlink_urb(urb);
182
183 if (dev->isoc_ctl.transfer_buffer[i]) {
184 usb_buffer_free(dev->usbdev,
185 urb->transfer_buffer_length,
186 dev->isoc_ctl.transfer_buffer[i],
187 urb->transfer_dma);
188 }
189 usb_free_urb(urb);
190 dev->isoc_ctl.urb[i] = NULL;
191 }
192 dev->isoc_ctl.transfer_buffer[i] = NULL;
193 }
194
195 kfree(dev->isoc_ctl.urb);
196 kfree(dev->isoc_ctl.transfer_buffer);
197
198 dev->isoc_ctl.urb = NULL;
199 dev->isoc_ctl.transfer_buffer = NULL;
200 dev->isoc_ctl.num_bufs = 0;
201}
202
203/*
204 * Allocate URBs and start IRQ
205 */
206int au0828_init_isoc(struct au0828_dev *dev, int max_packets,
207 int num_bufs, int max_pkt_size,
208 int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb))
209{
210 struct au0828_dmaqueue *dma_q = &dev->vidq;
211 int i;
212 int sb_size, pipe;
213 struct urb *urb;
214 int j, k;
215 int rc;
216
217 au0828_isocdbg("au0828: called au0828_prepare_isoc\n");
218
219 /* De-allocates all pending stuff */
220 au0828_uninit_isoc(dev);
221
222 dev->isoc_ctl.isoc_copy = isoc_copy;
223 dev->isoc_ctl.num_bufs = num_bufs;
224
225 dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
226 if (!dev->isoc_ctl.urb) {
227 au0828_isocdbg("cannot alloc memory for usb buffers\n");
228 return -ENOMEM;
229 }
230
231 dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
232 GFP_KERNEL);
233 if (!dev->isoc_ctl.transfer_buffer) {
234 au0828_isocdbg("cannot allocate memory for usb transfer\n");
235 kfree(dev->isoc_ctl.urb);
236 return -ENOMEM;
237 }
238
239 dev->isoc_ctl.max_pkt_size = max_pkt_size;
240 dev->isoc_ctl.buf = NULL;
241
242 sb_size = max_packets * dev->isoc_ctl.max_pkt_size;
243
244 /* allocate urbs and transfer buffers */
245 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
246 urb = usb_alloc_urb(max_packets, GFP_KERNEL);
247 if (!urb) {
248 au0828_isocdbg("cannot alloc isoc_ctl.urb %i\n", i);
249 au0828_uninit_isoc(dev);
250 return -ENOMEM;
251 }
252 dev->isoc_ctl.urb[i] = urb;
253
254 dev->isoc_ctl.transfer_buffer[i] = usb_buffer_alloc(dev->usbdev,
255 sb_size, GFP_KERNEL, &urb->transfer_dma);
256 if (!dev->isoc_ctl.transfer_buffer[i]) {
257 printk("unable to allocate %i bytes for transfer"
258 " buffer %i%s\n",
259 sb_size, i,
260 in_interrupt() ? " while in int" : "");
261 au0828_uninit_isoc(dev);
262 return -ENOMEM;
263 }
264 memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
265
266 pipe = usb_rcvisocpipe(dev->usbdev,
267 dev->isoc_in_endpointaddr),
268
269 usb_fill_int_urb(urb, dev->usbdev, pipe,
270 dev->isoc_ctl.transfer_buffer[i], sb_size,
271 au0828_irq_callback, dma_q, 1);
272
273 urb->number_of_packets = max_packets;
274 urb->transfer_flags = URB_ISO_ASAP;
275
276 k = 0;
277 for (j = 0; j < max_packets; j++) {
278 urb->iso_frame_desc[j].offset = k;
279 urb->iso_frame_desc[j].length =
280 dev->isoc_ctl.max_pkt_size;
281 k += dev->isoc_ctl.max_pkt_size;
282 }
283 }
284
285 init_waitqueue_head(&dma_q->wq);
286
287 /* submit urbs and enables IRQ */
288 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
289 rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC);
290 if (rc) {
291 au0828_isocdbg("submit of urb %i failed (error=%i)\n",
292 i, rc);
293 au0828_uninit_isoc(dev);
294 return rc;
295 }
296 }
297
298 return 0;
299}
300
301/*
302 * Announces that a buffer were filled and request the next
303 */
304static inline void buffer_filled(struct au0828_dev *dev,
305 struct au0828_dmaqueue *dma_q,
306 struct au0828_buffer *buf)
307{
308 /* Advice that buffer was filled */
309 au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
310
311 buf->vb.state = VIDEOBUF_DONE;
312 buf->vb.field_count++;
313 do_gettimeofday(&buf->vb.ts);
314
315 dev->isoc_ctl.buf = NULL;
316
317 list_del(&buf->vb.queue);
318 wake_up(&buf->vb.done);
319}
320
321/*
322 * Identify the buffer header type and properly handles
323 */
324static void au0828_copy_video(struct au0828_dev *dev,
325 struct au0828_dmaqueue *dma_q,
326 struct au0828_buffer *buf,
327 unsigned char *p,
328 unsigned char *outp, unsigned long len)
329{
330 void *fieldstart, *startwrite, *startread;
331 int linesdone, currlinedone, offset, lencopy, remain;
332 int bytesperline = dev->width << 1; /* Assumes 16-bit depth @@@@ */
333
334 if (dma_q->pos + len > buf->vb.size)
335 len = buf->vb.size - dma_q->pos;
336
337 startread = p;
338 remain = len;
339
340 /* Interlaces frame */
341 if (buf->top_field)
342 fieldstart = outp;
343 else
344 fieldstart = outp + bytesperline;
345
346 linesdone = dma_q->pos / bytesperline;
347 currlinedone = dma_q->pos % bytesperline;
348 offset = linesdone * bytesperline * 2 + currlinedone;
349 startwrite = fieldstart + offset;
350 lencopy = bytesperline - currlinedone;
351 lencopy = lencopy > remain ? remain : lencopy;
352
353 if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
354 au0828_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
355 ((char *)startwrite + lencopy) -
356 ((char *)outp + buf->vb.size));
357 remain = (char *)outp + buf->vb.size - (char *)startwrite;
358 lencopy = remain;
359 }
360 if (lencopy <= 0)
361 return;
362 memcpy(startwrite, startread, lencopy);
363
364 remain -= lencopy;
365
366 while (remain > 0) {
367 startwrite += lencopy + bytesperline;
368 startread += lencopy;
369 if (bytesperline > remain)
370 lencopy = remain;
371 else
372 lencopy = bytesperline;
373
374 if ((char *)startwrite + lencopy > (char *)outp +
375 buf->vb.size) {
376 au0828_isocdbg("Overflow of %zi bytes past buffer end (2)\n",
377 ((char *)startwrite + lencopy) -
378 ((char *)outp + buf->vb.size));
379 lencopy = remain = (char *)outp + buf->vb.size -
380 (char *)startwrite;
381 }
382 if (lencopy <= 0)
383 break;
384
385 memcpy(startwrite, startread, lencopy);
386
387 remain -= lencopy;
388 }
389
390 if (offset > 1440) {
391 /* We have enough data to check for greenscreen */
392 if (outp[0] < 0x60 && outp[1440] < 0x60) {
393 dev->greenscreen_detected = 1;
394 }
395 }
396
397 dma_q->pos += len;
398}
399
400/*
401 * video-buf generic routine to get the next available buffer
402 */
403static inline void get_next_buf(struct au0828_dmaqueue *dma_q,
404 struct au0828_buffer **buf)
405{
406 struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
407
408 if (list_empty(&dma_q->active)) {
409 au0828_isocdbg("No active queue to serve\n");
410 dev->isoc_ctl.buf = NULL;
411 *buf = NULL;
412 return;
413 }
414
415 /* Get the next buffer */
416 *buf = list_entry(dma_q->active.next, struct au0828_buffer, vb.queue);
417 dev->isoc_ctl.buf = *buf;
418
419 return;
420}
421
422/*
423 * Controls the isoc copy of each urb packet
424 */
425static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
426{
427 struct au0828_buffer *buf;
428 struct au0828_dmaqueue *dma_q = urb->context;
429 unsigned char *outp = NULL;
430 int i, len = 0, rc = 1;
431 unsigned char *p;
432 unsigned char fbyte;
433
434 if (!dev)
435 return 0;
436
437 if ((dev->dev_state & DEV_DISCONNECTED) ||
438 (dev->dev_state & DEV_MISCONFIGURED))
439 return 0;
440
441 if (urb->status < 0) {
442 print_err_status(dev, -1, urb->status);
443 if (urb->status == -ENOENT)
444 return 0;
445 }
446
447 buf = dev->isoc_ctl.buf;
448 if (buf != NULL)
449 outp = videobuf_to_vmalloc(&buf->vb);
450
451 for (i = 0; i < urb->number_of_packets; i++) {
452 int status = urb->iso_frame_desc[i].status;
453
454 if (status < 0) {
455 print_err_status(dev, i, status);
456 if (urb->iso_frame_desc[i].status != -EPROTO)
457 continue;
458 }
459
460 if (urb->iso_frame_desc[i].actual_length <= 0) {
461 continue;
462 }
463 if (urb->iso_frame_desc[i].actual_length >
464 dev->max_pkt_size) {
465 au0828_isocdbg("packet bigger than packet size");
466 continue;
467 }
468
469 p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
470 fbyte = p[0];
471 len = urb->iso_frame_desc[i].actual_length - 4;
472 p += 4;
473
474 if (fbyte & 0x80) {
475 len -= 4;
476 p += 4;
477 au0828_isocdbg("Video frame %s\n",
478 (fbyte & 0x40) ? "odd" : "even");
479 if (!(fbyte & 0x40)) {
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 (fbyte & 0x40) {
491 buf->top_field = 1;
492 } else {
493 buf->top_field = 0;
494 }
495 }
496
497 dma_q->pos = 0;
498 }
499 if (buf != NULL) {
500 au0828_copy_video(dev, dma_q, buf, p, outp, len);
501 }
502 }
503 return rc;
504}
505
506static int
507buffer_setup(struct videobuf_queue *vq, unsigned int *count,
508 unsigned int *size)
509{
510 struct au0828_fh *fh = vq->priv_data;
511 *size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
512
513 if (0 == *count)
514 *count = AU0828_DEF_BUF;
515
516 if (*count < AU0828_MIN_BUF)
517 *count = AU0828_MIN_BUF;
518 return 0;
519}
520
521/* This is called *without* dev->slock held; please keep it that way */
522static void free_buffer(struct videobuf_queue *vq, struct au0828_buffer *buf)
523{
524 struct au0828_fh *fh = vq->priv_data;
525 struct au0828_dev *dev = fh->dev;
526 unsigned long flags = 0;
527 if (in_interrupt())
528 BUG();
529
530 /* We used to wait for the buffer to finish here, but this didn't work
531 because, as we were keeping the state as VIDEOBUF_QUEUED,
532 videobuf_queue_cancel marked it as finished for us.
533 (Also, it could wedge forever if the hardware was misconfigured.)
534
535 This should be safe; by the time we get here, the buffer isn't
536 queued anymore. If we ever start marking the buffers as
537 VIDEOBUF_ACTIVE, it won't be, though.
538 */
539 spin_lock_irqsave(&dev->slock, flags);
540 if (dev->isoc_ctl.buf == buf)
541 dev->isoc_ctl.buf = NULL;
542 spin_unlock_irqrestore(&dev->slock, flags);
543
544 videobuf_vmalloc_free(&buf->vb);
545 buf->vb.state = VIDEOBUF_NEEDS_INIT;
546}
547
548static int
549buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
550 enum v4l2_field field)
551{
552 struct au0828_fh *fh = vq->priv_data;
553 struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
554 struct au0828_dev *dev = fh->dev;
555 int rc = 0, urb_init = 0;
556
557 buf->vb.size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
558
559 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
560 return -EINVAL;
561
562 buf->vb.width = dev->width;
563 buf->vb.height = dev->height;
564 buf->vb.field = field;
565
566 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
567 rc = videobuf_iolock(vq, &buf->vb, NULL);
568 if (rc < 0) {
569 printk("videobuf_iolock failed\n");
570 goto fail;
571 }
572 }
573
574 if (!dev->isoc_ctl.num_bufs)
575 urb_init = 1;
576
577 if (urb_init) {
578 rc = au0828_init_isoc(dev, AU0828_ISO_PACKETS_PER_URB,
579 AU0828_MAX_ISO_BUFS, dev->max_pkt_size,
580 au0828_isoc_copy);
581 if (rc < 0) {
582 printk("au0828_init_isoc failed\n");
583 goto fail;
584 }
585 }
586
587 buf->vb.state = VIDEOBUF_PREPARED;
588 return 0;
589
590fail:
591 free_buffer(vq, buf);
592 return rc;
593}
594
595static void
596buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
597{
598 struct au0828_buffer *buf = container_of(vb,
599 struct au0828_buffer,
600 vb);
601 struct au0828_fh *fh = vq->priv_data;
602 struct au0828_dev *dev = fh->dev;
603 struct au0828_dmaqueue *vidq = &dev->vidq;
604
605 buf->vb.state = VIDEOBUF_QUEUED;
606 list_add_tail(&buf->vb.queue, &vidq->active);
607}
608
609static void buffer_release(struct videobuf_queue *vq,
610 struct videobuf_buffer *vb)
611{
612 struct au0828_buffer *buf = container_of(vb,
613 struct au0828_buffer,
614 vb);
615
616 free_buffer(vq, buf);
617}
618
619static struct videobuf_queue_ops au0828_video_qops = {
620 .buf_setup = buffer_setup,
621 .buf_prepare = buffer_prepare,
622 .buf_queue = buffer_queue,
623 .buf_release = buffer_release,
624};
625
626/* ------------------------------------------------------------------
627 V4L2 interface
628 ------------------------------------------------------------------*/
629
630static int au0828_i2s_init(struct au0828_dev *dev)
631{
632 /* Enable i2s mode */
633 au0828_writereg(dev, AU0828_AUDIOCTRL_50C, 0x01);
634 return 0;
635}
636
637/*
638 * Auvitek au0828 analog stream enable
639 * Please set interface0 to AS5 before enable the stream
640 */
641int au0828_analog_stream_enable(struct au0828_dev *d)
642{
643 dprintk(1, "au0828_analog_stream_enable called\n");
644 au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
645 au0828_writereg(d, 0x106, 0x00);
646 /* set x position */
647 au0828_writereg(d, 0x110, 0x00);
648 au0828_writereg(d, 0x111, 0x00);
649 au0828_writereg(d, 0x114, 0xa0);
650 au0828_writereg(d, 0x115, 0x05);
651 /* set y position */
652 au0828_writereg(d, 0x112, 0x02);
653 au0828_writereg(d, 0x113, 0x00);
654 au0828_writereg(d, 0x116, 0xf2);
655 au0828_writereg(d, 0x117, 0x00);
656 au0828_writereg(d, AU0828_SENSORCTRL_100, 0xb3);
657
658 return 0;
659}
660
661int au0828_analog_stream_disable(struct au0828_dev *d)
662{
663 dprintk(1, "au0828_analog_stream_disable called\n");
664 au0828_writereg(d, AU0828_SENSORCTRL_100, 0x0);
665 return 0;
666}
667
668void au0828_analog_stream_reset(struct au0828_dev *dev)
669{
670 dprintk(1, "au0828_analog_stream_reset called\n");
671 au0828_writereg(dev, AU0828_SENSORCTRL_100, 0x0);
672 mdelay(30);
673 au0828_writereg(dev, AU0828_SENSORCTRL_100, 0xb3);
674}
675
676/*
677 * Some operations needs to stop current streaming
678 */
679static int au0828_stream_interrupt(struct au0828_dev *dev)
680{
681 int ret = 0;
682
683 dev->stream_state = STREAM_INTERRUPT;
684 if(dev->dev_state == DEV_DISCONNECTED)
685 return -ENODEV;
686 else if(ret) {
687 dev->dev_state = DEV_MISCONFIGURED;
688 dprintk(1, "%s device is misconfigured!\n", __FUNCTION__);
689 return ret;
690 }
691 return 0;
692}
693
694/*
695 * au0828_release_resources
696 * unregister v4l2 devices
697 */
698void au0828_analog_unregister(struct au0828_dev *dev)
699{
700 dprintk(1, "au0828_release_resources called\n");
701 mutex_lock(&au0828_sysfs_lock);
702
703 list_del(&dev->au0828list);
704 video_unregister_device(dev->vdev);
705 video_unregister_device(dev->vbi_dev);
706
707 mutex_unlock(&au0828_sysfs_lock);
708}
709
710
711/* Usage lock check functions */
712static int res_get(struct au0828_fh *fh)
713{
714 struct au0828_dev *dev = fh->dev;
715 int rc = 0;
716
717 /* This instance already has stream_on */
718 if (fh->stream_on)
719 return rc;
720
721 if (dev->stream_on)
722 return -EBUSY;
723
724 dev->stream_on = 1;
725 fh->stream_on = 1;
726 return rc;
727}
728
729static int res_check(struct au0828_fh *fh)
730{
731 return fh->stream_on;
732}
733
734static void res_free(struct au0828_fh *fh)
735{
736 struct au0828_dev *dev = fh->dev;
737
738 fh->stream_on = 0;
739 dev->stream_on = 0;
740}
741
742static int au0828_v4l2_open(struct file *filp)
743{
744 int minor = video_devdata(filp)->minor;
745 int ret = 0;
746 struct au0828_dev *h, *dev = NULL;
747 struct au0828_fh *fh;
748 int type = 0;
749 struct list_head *list;
750
751 list_for_each(list, &au0828_devlist) {
752 h = list_entry(list, struct au0828_dev, au0828list);
753 if(h->vdev->minor == minor) {
754 dev = h;
755 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
756 }
757 if(h->vbi_dev->minor == minor) {
758 dev = h;
759 type = V4L2_BUF_TYPE_VBI_CAPTURE;
760 }
761 }
762
763 if(NULL == dev)
764 return -ENODEV;
765
766 fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL);
767 if(NULL == fh) {
768 dprintk(1, "Failed allocate au0828_fh struct!\n");
769 return -ENOMEM;
770 }
771
772 fh->type = type;
773 fh->dev = dev;
774 filp->private_data = fh;
775
776 if(fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
777 /* set au0828 interface0 to AS5 here again */
778 ret = usb_set_interface(dev->usbdev, 0, 5);
779 if(ret < 0) {
780 printk("Au0828 can't set alt setting to 5!\n");
781 return -EBUSY;
782 }
783 dev->width = NTSC_STD_W;
784 dev->height = NTSC_STD_H;
785 dev->frame_size = dev->width * dev->height * 2;
786 dev->field_size = dev->width * dev->height;
787 dev->bytesperline = dev->width * 2;
788
789 au0828_analog_stream_enable(dev);
790 au0828_analog_stream_reset(dev);
791
792 /* If we were doing ac97 instead of i2s, it would go here...*/
793 au0828_i2s_init(dev);
794
795 dev->stream_state = STREAM_OFF;
796 dev->dev_state |= DEV_INITIALIZED;
797 }
798
799 dev->users++;
800
801 videobuf_queue_vmalloc_init(&fh->vb_vidq, &au0828_video_qops,
802 NULL, &dev->slock, fh->type,
803 V4L2_FIELD_INTERLACED,
804 sizeof(struct au0828_buffer), fh);
805
806 return ret;
807}
808
809static int au0828_v4l2_close(struct file *filp)
810{
811 int ret;
812 struct au0828_fh *fh = filp->private_data;
813 struct au0828_dev *dev = fh->dev;
814
815 mutex_lock(&dev->lock);
816 if (res_check(fh))
817 res_free(fh);
818
819 if(dev->users == 1) {
820 videobuf_stop(&fh->vb_vidq);
821 videobuf_mmap_free(&fh->vb_vidq);
822
823 if(dev->dev_state & DEV_DISCONNECTED) {
824 au0828_analog_unregister(dev);
825 mutex_unlock(&dev->lock);
826 kfree(dev);
827 return 0;
828 }
829
830 au0828_analog_stream_disable(dev);
831
832 au0828_uninit_isoc(dev);
833
834 /* When close the device, set the usb intf0 into alt0 to free
835 USB bandwidth */
836 ret = usb_set_interface(dev->usbdev, 0, 0);
837 if(ret < 0)
838 printk("Au0828 can't set alt setting to 0!\n");
839 }
840
841 kfree(fh);
842 dev->users--;
843 wake_up_interruptible_nr(&dev->open, 1);
844 mutex_unlock(&dev->lock);
845 return 0;
846}
847
848static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf,
849 size_t count, loff_t *pos)
850{
851 struct au0828_fh *fh = filp->private_data;
852 struct au0828_dev *dev = fh->dev;
853 int rc;
854
855 rc = check_dev(dev);
856 if (rc < 0)
857 return rc;
858
859 if(fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
860 mutex_lock(&dev->lock);
861 rc = res_get(fh);
862 mutex_unlock(&dev->lock);
863
864 if (unlikely(rc < 0))
865 return rc;
866
867 return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
868 filp->f_flags & O_NONBLOCK);
869 }
870 return 0;
871}
872
873static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait)
874{
875 struct au0828_fh *fh = filp->private_data;
876 struct au0828_dev *dev = fh->dev;
877 int rc;
878
879 rc = check_dev(dev);
880 if (rc < 0)
881 return rc;
882
883 mutex_lock(&dev->lock);
884 rc = res_get(fh);
885 mutex_unlock(&dev->lock);
886
887 if (unlikely(rc < 0))
888 return POLLERR;
889
890 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type)
891 return POLLERR;
892
893 return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
894}
895
896static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
897{
898 struct au0828_fh *fh = filp->private_data;
899 struct au0828_dev *dev = fh->dev;
900 int rc;
901
902 rc = check_dev(dev);
903 if (rc < 0)
904 return rc;
905
906 mutex_lock(&dev->lock);
907 rc = res_get(fh);
908 mutex_unlock(&dev->lock);
909
910 if (unlikely(rc < 0))
911 return rc;
912
913 rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
914
915 dprintk(2, "vma start=0x%08lx, size=%ld, ret=%d\n",
916 (unsigned long)vma->vm_start,
917 (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
918 rc);
919
920 return rc;
921}
922
923static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
924 struct v4l2_format *format)
925{
926 int ret;
927 int width = format->fmt.pix.width;
928 int height = format->fmt.pix.height;
929 unsigned int maxwidth, maxheight;
930
931 maxwidth = 720;
932 maxheight = 480;
933
934 if(format->type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
935 dprintk(1, "VBI format set: to be supported!\n");
936 return 0;
937 }
938 if(format->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
939 return 0;
940 }
941 if(format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
942 return -EINVAL;
943 }
944
945 /* If they are demanding a format other than the one we support,
946 bail out (tvtime asks for UYVY and then retries with YUYV) */
947 if (format->fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY) {
948 return -EINVAL;
949 }
950
951 /* format->fmt.pix.width only support 720 and height 480 */
952 if(width != 720)
953 width = 720;
954 if(height != 480)
955 height = 480;
956
957 format->fmt.pix.width = width;
958 format->fmt.pix.height = height;
959 format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
960 format->fmt.pix.bytesperline = width * 2;
961 format->fmt.pix.sizeimage = width * height * 2;
962 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
963 format->fmt.pix.field = V4L2_FIELD_INTERLACED;
964
965 if(cmd == VIDIOC_TRY_FMT)
966 return 0;
967
968 /* maybe set new image format, driver current only support 720*480 */
969 dev->width = width;
970 dev->height = height;
971 dev->frame_size = width * height * 2;
972 dev->field_size = width * height;
973 dev->bytesperline = width * 2;
974
975 if(dev->stream_state == STREAM_ON) {
976 dprintk(1, "VIDIOC_SET_FMT: interrupting stream!\n");
977 if((ret = au0828_stream_interrupt(dev))) {
978 dprintk(1, "error interrupting video stream!\n");
979 return ret;
980 }
981 }
982
983 /* set au0828 interface0 to AS5 here again */
984 ret = usb_set_interface(dev->usbdev, 0, 5);
985 if(ret < 0) {
986 printk("Au0828 can't set alt setting to 5!\n");
987 return -EBUSY;
988 }
989
990 au0828_analog_stream_enable(dev);
991
992 return 0;
993}
994
995
996static int vidioc_queryctrl(struct file *file, void *priv,
997 struct v4l2_queryctrl *qc)
998{
999 struct au0828_fh *fh = priv;
1000 struct au0828_dev *dev = fh->dev;
1001 au0828_call_i2c_clients(dev, VIDIOC_QUERYCTRL, qc);
1002 if (qc->type)
1003 return 0;
1004 else
1005 return -EINVAL;
1006}
1007
1008static int vidioc_querycap(struct file *file, void *priv,
1009 struct v4l2_capability *cap)
1010{
1011 struct au0828_fh *fh = priv;
1012 struct au0828_dev *dev = fh->dev;
1013
1014 memset(cap, 0, sizeof(*cap));
1015 strlcpy(cap->driver, "au0828", sizeof(cap->driver));
1016 strlcpy(cap->card, au0828_boards[dev->board].name, sizeof(cap->card));
1017 strlcpy(cap->bus_info, dev->usbdev->dev.bus_id, sizeof(cap->bus_info));
1018
1019 cap->version = AU0828_VERSION_CODE;
1020
1021 /*set the device capabilities */
1022 cap->capabilities = V4L2_CAP_VBI_CAPTURE |
1023 V4L2_CAP_VIDEO_CAPTURE |
1024 V4L2_CAP_AUDIO |
1025 V4L2_CAP_READWRITE |
1026 V4L2_CAP_STREAMING |
1027 V4L2_CAP_TUNER;
1028 return 0;
1029}
1030
1031static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
1032 struct v4l2_fmtdesc *f)
1033{
1034 if(f->index)
1035 return -EINVAL;
1036
1037 memset(f, 0, sizeof(*f));
1038 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1039 strcpy(f->description, "Packed YUV2");
1040
1041 f->flags = 0;
1042 f->pixelformat = V4L2_PIX_FMT_UYVY;
1043
1044 memset(f->reserved, 0, sizeof(f->reserved));
1045 return 0;
1046}
1047
1048static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
1049 struct v4l2_format *f)
1050{
1051 struct au0828_fh *fh = priv;
1052 struct au0828_dev *dev = fh->dev;
1053
1054 f->fmt.pix.width = dev->width;
1055 f->fmt.pix.height = dev->height;
1056 f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
1057 f->fmt.pix.bytesperline = dev->bytesperline;
1058 f->fmt.pix.sizeimage = dev->frame_size;
1059 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* NTSC/PAL */
1060 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
1061 return 0;
1062}
1063
1064static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
1065 struct v4l2_format *f)
1066{
1067 struct au0828_fh *fh = priv;
1068 struct au0828_dev *dev = fh->dev;
1069
1070 return au0828_set_format(dev, VIDIOC_TRY_FMT, f);
1071}
1072
1073static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1074 struct v4l2_format *f)
1075{
1076 struct au0828_fh *fh = priv;
1077 struct au0828_dev *dev = fh->dev;
1078 int rc;
1079
1080 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
1081 printk("%s queue busy\n", __func__);
1082 rc = -EBUSY;
1083 goto out;
1084 }
1085
1086 if (dev->stream_on && !fh->stream_on) {
1087 printk("%s device in use by another fh\n", __func__);
1088 rc = -EBUSY;
1089 goto out;
1090 }
1091
1092 return au0828_set_format(dev, VIDIOC_S_FMT, f);
1093out:
1094 return rc;
1095}
1096
1097static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm)
1098{
1099 struct au0828_fh *fh = priv;
1100 struct au0828_dev *dev = fh->dev;
1101
1102 /* FIXME: when we support something other than NTSC, we are going to
1103 have to make the au0828 bridge adjust the size of its capture
1104 buffer, which is currently hardcoded at 720x480 */
1105
1106 au0828_call_i2c_clients(dev, VIDIOC_S_STD, norm);
1107 return 0;
1108}
1109
1110static int vidioc_enum_input(struct file *file, void *priv,
1111 struct v4l2_input *input)
1112{
1113 struct au0828_fh *fh = priv;
1114 struct au0828_dev *dev = fh->dev;
1115 unsigned int tmp;
1116
1117 static const char *inames[] = {
1118 [AU0828_VMUX_COMPOSITE] = "Composite",
1119 [AU0828_VMUX_SVIDEO] = "S-Video",
1120 [AU0828_VMUX_CABLE] = "Cable TV",
1121 [AU0828_VMUX_TELEVISION] = "Television",
1122 [AU0828_VMUX_DVB] = "DVB",
1123 [AU0828_VMUX_DEBUG] = "tv debug"
1124 };
1125
1126 tmp = input->index;
1127
1128 if(tmp > AU0828_MAX_INPUT)
1129 return -EINVAL;
1130 if(AUVI_INPUT(tmp)->type == 0)
1131 return -EINVAL;
1132
1133 memset(input, 0, sizeof(*input));
1134 input->index = tmp;
1135 strcpy(input->name, inames[AUVI_INPUT(tmp)->type]);
1136 if((AUVI_INPUT(tmp)->type == AU0828_VMUX_TELEVISION) ||
1137 (AUVI_INPUT(tmp)->type == AU0828_VMUX_CABLE))
1138 input->type |= V4L2_INPUT_TYPE_TUNER;
1139 else
1140 input->type |= V4L2_INPUT_TYPE_CAMERA;
1141
1142 input->std = dev->vdev->tvnorms;
1143
1144 return 0;
1145}
1146
1147static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1148{
1149 struct au0828_fh *fh = priv;
1150 struct au0828_dev *dev = fh->dev;
1151 *i = dev->ctrl_input;
1152 return 0;
1153}
1154
1155static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
1156{
1157 struct au0828_fh *fh = priv;
1158 struct au0828_dev *dev = fh->dev;
1159 int i;
1160 struct v4l2_routing route;
1161
1162 dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __FUNCTION__,
1163 index);
1164 if(index >= AU0828_MAX_INPUT)
1165 return -EINVAL;
1166 if(AUVI_INPUT(index)->type == 0)
1167 return -EINVAL;
1168 dev->ctrl_input = index;
1169
1170 switch(AUVI_INPUT(index)->type) {
1171 case AU0828_VMUX_SVIDEO:
1172 {
1173 dev->input_type = AU0828_VMUX_SVIDEO;
1174 break;
1175 }
1176 case AU0828_VMUX_COMPOSITE:
1177 {
1178 dev->input_type = AU0828_VMUX_COMPOSITE;
1179 break;
1180 }
1181 case AU0828_VMUX_TELEVISION:
1182 {
1183 dev->input_type = AU0828_VMUX_TELEVISION;
1184 break;
1185 }
1186 default:
1187 ;
1188 }
1189
1190 route.input = AUVI_INPUT(index)->vmux;
1191 route.output = 0;
1192 au0828_call_i2c_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
1193
1194 for (i = 0; i < AU0828_MAX_INPUT; i++) {
1195 int enable = 0;
1196 if (AUVI_INPUT(i)->audio_setup == NULL) {
1197 continue;
1198 }
1199
1200 if (i == index)
1201 enable = 1;
1202 else
1203 enable = 0;
1204 if (enable) {
1205 (AUVI_INPUT(i)->audio_setup)(dev, enable);
1206 } else {
1207 /* Make sure we leave it turned on if some
1208 other input is routed to this callback */
1209 if ((AUVI_INPUT(i)->audio_setup) !=
1210 ((AUVI_INPUT(index)->audio_setup))) {
1211 (AUVI_INPUT(i)->audio_setup)(dev, enable);
1212 }
1213 }
1214 }
1215
1216 route.input = AUVI_INPUT(index)->amux;
1217 au0828_call_i2c_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
1218 &route);
1219 return 0;
1220}
1221
1222static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
1223{
1224 struct au0828_fh *fh = priv;
1225 struct au0828_dev *dev = fh->dev;
1226 unsigned int index = a->index;
1227
1228 if(a->index > 1)
1229 return -EINVAL;
1230
1231 memset(a, 0, sizeof(*a));
1232 index = dev->ctrl_ainput;
1233 if(index == 0)
1234 strcpy(a->name, "Television");
1235 else
1236 strcpy(a->name, "Line in");
1237
1238 a->capability = V4L2_AUDCAP_STEREO;
1239 a->index = index;
1240 return 0;
1241}
1242
1243static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
1244{
1245 struct au0828_fh *fh = priv;
1246 struct au0828_dev *dev = fh->dev;
1247 if(a->index != dev->ctrl_ainput)
1248 return -EINVAL;
1249 return 0;
1250}
1251
1252static int vidioc_g_ctrl(struct file *file, void *priv,
1253 struct v4l2_control *ctrl)
1254{
1255 struct au0828_fh *fh = priv;
1256 struct au0828_dev *dev = fh->dev;
1257
1258 au0828_call_i2c_clients(dev, VIDIOC_G_CTRL, ctrl);
1259 return 0;
1260
1261}
1262
1263static int vidioc_s_ctrl(struct file *file, void *priv,
1264 struct v4l2_control *ctrl)
1265{
1266 struct au0828_fh *fh = priv;
1267 struct au0828_dev *dev = fh->dev;
1268 au0828_call_i2c_clients(dev, VIDIOC_S_CTRL, ctrl);
1269 return 0;
1270}
1271
1272static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1273{
1274 struct au0828_fh *fh = priv;
1275 struct au0828_dev *dev = fh->dev;
1276
1277 if(t->index != 0)
1278 return -EINVAL;
1279
1280 memset(t, 0, sizeof(*t));
1281 strcpy(t->name, "Auvitek tuner");
1282
1283 au0828_call_i2c_clients(dev, VIDIOC_G_TUNER, t);
1284 return 0;
1285}
1286
1287static int vidioc_s_tuner(struct file *file, void *priv,
1288 struct v4l2_tuner *t)
1289{
1290 struct au0828_fh *fh = priv;
1291 struct au0828_dev *dev = fh->dev;
1292
1293 if(t->index != 0)
1294 return -EINVAL;
1295
1296 t->type = V4L2_TUNER_ANALOG_TV;
1297 au0828_call_i2c_clients(dev, VIDIOC_S_TUNER, t);
1298 dprintk(1, "VIDIOC_S_TUNER: signal = %x, afc = %x\n", t->signal,
1299 t->afc);
1300 return 0;
1301
1302}
1303
1304static int vidioc_g_frequency(struct file *file, void *priv,
1305 struct v4l2_frequency *freq)
1306{
1307 struct au0828_fh *fh = priv;
1308 struct au0828_dev *dev = fh->dev;
1309 memset(freq, 0, sizeof(*freq));
1310 freq->type = V4L2_TUNER_ANALOG_TV;
1311 freq->frequency = dev->ctrl_freq;
1312 return 0;
1313}
1314
1315static int vidioc_s_frequency(struct file *file, void *priv,
1316 struct v4l2_frequency *freq)
1317{
1318 struct au0828_fh *fh = priv;
1319 struct au0828_dev *dev = fh->dev;
1320
1321 if(freq->tuner != 0)
1322 return -EINVAL;
1323 if(freq->type != V4L2_TUNER_ANALOG_TV)
1324 return -EINVAL;
1325
1326 dev->ctrl_freq = freq->frequency;
1327
1328 au0828_call_i2c_clients(dev, VIDIOC_S_FREQUENCY, freq);
1329
1330 au0828_analog_stream_reset(dev);
1331
1332 return 0;
1333}
1334
1335static int vidioc_g_chip_ident(struct file *file, void *priv,
1336 struct v4l2_dbg_chip_ident *chip)
1337{
1338 struct au0828_fh *fh = priv;
1339 struct au0828_dev *dev = fh->dev;
1340 chip->ident = V4L2_IDENT_NONE;
1341 chip->revision = 0;
1342
1343 au0828_call_i2c_clients(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
1344 return 0;
1345}
1346
1347static int vidioc_cropcap(struct file *file, void *priv,
1348 struct v4l2_cropcap *cc)
1349{
1350 struct au0828_fh *fh = priv;
1351 struct au0828_dev *dev = fh->dev;
1352
1353 if(cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1354 return -EINVAL;
1355
1356 cc->bounds.left = 0;
1357 cc->bounds.top = 0;
1358 cc->bounds.width = dev->width;
1359 cc->bounds.height = dev->height;
1360
1361 cc->defrect = cc->bounds;
1362
1363 cc->pixelaspect.numerator = 54;
1364 cc->pixelaspect.denominator = 59;
1365
1366 return 0;
1367}
1368
1369static int vidioc_streamon(struct file *file, void *priv,
1370 enum v4l2_buf_type type)
1371{
1372 struct au0828_fh *fh = priv;
1373 struct au0828_dev *dev = fh->dev;
1374 int b = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1375 int rc;
1376
1377 rc = check_dev(dev);
1378 if (rc < 0)
1379 return rc;
1380
1381 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1382 au0828_analog_stream_enable(dev);
1383 au0828_call_i2c_clients(dev, VIDIOC_STREAMON, &b);
1384 }
1385
1386 mutex_lock(&dev->lock);
1387 rc = res_get(fh);
1388
1389 if (likely(rc >= 0))
1390 rc = videobuf_streamon(&fh->vb_vidq);
1391 mutex_unlock(&dev->lock);
1392
1393 return rc;
1394}
1395
1396static int vidioc_streamoff(struct file *file, void *priv,
1397 enum v4l2_buf_type type)
1398{
1399 struct au0828_fh *fh = priv;
1400 struct au0828_dev *dev = fh->dev;
1401 int b = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1402 int i;
1403 int ret;
1404 int rc;
1405
1406 rc = check_dev(dev);
1407 if (rc < 0)
1408 return rc;
1409
1410 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1411 return -EINVAL;
1412 if (type != fh->type)
1413 return -EINVAL;
1414
1415 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1416 au0828_call_i2c_clients(dev, VIDIOC_STREAMOFF, &b);
1417 if((ret = au0828_stream_interrupt(dev)) != 0)
1418 return ret;
1419 }
1420
1421 for (i = 0; i < AU0828_MAX_INPUT; i++) {
1422 if (AUVI_INPUT(i)->audio_setup == NULL) {
1423 continue;
1424 }
1425 (AUVI_INPUT(i)->audio_setup)(dev, 0);
1426 }
1427
1428 mutex_lock(&dev->lock);
1429 videobuf_streamoff(&fh->vb_vidq);
1430 res_free(fh);
1431 mutex_unlock(&dev->lock);
1432
1433 return 0;
1434}
1435
1436static int vidioc_g_register(struct file *file, void *priv,
1437 struct v4l2_dbg_register *reg)
1438{
1439 struct au0828_fh *fh = priv;
1440 struct au0828_dev *dev = fh->dev;
1441
1442 switch (reg->match.type) {
1443 case V4L2_CHIP_MATCH_I2C_DRIVER:
1444 au0828_call_i2c_clients(dev, VIDIOC_DBG_G_REGISTER, reg);
1445 return 0;
1446 default:
1447 return -EINVAL;
1448 }
1449}
1450
1451static int vidioc_s_register(struct file *file, void *priv,
1452 struct v4l2_dbg_register *reg)
1453{
1454 struct au0828_fh *fh = priv;
1455 struct au0828_dev *dev = fh->dev;
1456
1457 switch (reg->match.type) {
1458 case V4L2_CHIP_MATCH_I2C_DRIVER:
1459 au0828_call_i2c_clients(dev, VIDIOC_DBG_S_REGISTER, reg);
1460 return 0;
1461 default:
1462 return -EINVAL;
1463 }
1464 return 0;
1465}
1466
1467static int vidioc_reqbufs(struct file *file, void *priv,
1468 struct v4l2_requestbuffers *rb)
1469{
1470 struct au0828_fh *fh = priv;
1471 struct au0828_dev *dev = fh->dev;
1472 int rc;
1473
1474 rc = check_dev(dev);
1475 if (rc < 0)
1476 return rc;
1477
1478 return videobuf_reqbufs(&fh->vb_vidq, rb);
1479}
1480
1481static int vidioc_querybuf(struct file *file, void *priv,
1482 struct v4l2_buffer *b)
1483{
1484 struct au0828_fh *fh = priv;
1485 struct au0828_dev *dev = fh->dev;
1486 int rc;
1487
1488 rc = check_dev(dev);
1489 if (rc < 0)
1490 return rc;
1491
1492 return videobuf_querybuf(&fh->vb_vidq, b);
1493}
1494
1495static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1496{
1497 struct au0828_fh *fh = priv;
1498 struct au0828_dev *dev = fh->dev;
1499 int rc;
1500
1501 rc = check_dev(dev);
1502 if (rc < 0)
1503 return rc;
1504
1505 return videobuf_qbuf(&fh->vb_vidq, b);
1506}
1507
1508static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1509{
1510 struct au0828_fh *fh = priv;
1511 struct au0828_dev *dev = fh->dev;
1512 int rc;
1513
1514 rc = check_dev(dev);
1515 if (rc < 0)
1516 return rc;
1517
1518 /* Workaround for a bug in the au0828 hardware design that sometimes
1519 results in the colorspace being inverted */
1520 if (dev->greenscreen_detected == 1) {
1521 dprintk(1, "Detected green frame. Resetting stream...\n");
1522 au0828_analog_stream_reset(dev);
1523 dev->greenscreen_detected = 0;
1524 }
1525
1526 return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
1527}
1528
1529#ifdef CONFIG_VIDEO_V4L1_COMPAT
1530static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
1531{
1532 struct au0828_fh *fh = priv;
1533
1534 return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
1535}
1536#endif
1537
1538static struct v4l2_file_operations au0828_v4l_fops = {
1539 .owner = THIS_MODULE,
1540 .open = au0828_v4l2_open,
1541 .release = au0828_v4l2_close,
1542 .read = au0828_v4l2_read,
1543 .poll = au0828_v4l2_poll,
1544 .mmap = au0828_v4l2_mmap,
1545 .ioctl = video_ioctl2,
1546};
1547
1548static const struct v4l2_ioctl_ops video_ioctl_ops = {
1549 .vidioc_querycap = vidioc_querycap,
1550 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1551 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1552 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1553 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
1554 .vidioc_g_audio = vidioc_g_audio,
1555 .vidioc_s_audio = vidioc_s_audio,
1556 .vidioc_cropcap = vidioc_cropcap,
1557#ifdef AAA
1558 .vidioc_g_fmt_sliced_vbi_cap = vidioc_g_fmt_sliced_vbi_cap,
1559 .vidioc_try_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
1560 .vidioc_s_fmt_sliced_vbi_cap = vidioc_try_set_sliced_vbi_cap,
1561#endif
1562 .vidioc_reqbufs = vidioc_reqbufs,
1563 .vidioc_querybuf = vidioc_querybuf,
1564 .vidioc_qbuf = vidioc_qbuf,
1565 .vidioc_dqbuf = vidioc_dqbuf,
1566 .vidioc_s_std = vidioc_s_std,
1567 .vidioc_enum_input = vidioc_enum_input,
1568 .vidioc_g_input = vidioc_g_input,
1569 .vidioc_s_input = vidioc_s_input,
1570 .vidioc_queryctrl = vidioc_queryctrl,
1571 .vidioc_g_ctrl = vidioc_g_ctrl,
1572 .vidioc_s_ctrl = vidioc_s_ctrl,
1573 .vidioc_streamon = vidioc_streamon,
1574 .vidioc_streamoff = vidioc_streamoff,
1575 .vidioc_g_tuner = vidioc_g_tuner,
1576 .vidioc_s_tuner = vidioc_s_tuner,
1577 .vidioc_g_frequency = vidioc_g_frequency,
1578 .vidioc_s_frequency = vidioc_s_frequency,
1579#ifdef CONFIG_VIDEO_ADV_DEBUG
1580 .vidioc_g_register = vidioc_g_register,
1581 .vidioc_s_register = vidioc_s_register,
1582 .vidioc_g_chip_ident = vidioc_g_chip_ident,
1583#endif
1584#ifdef CONFIG_VIDEO_V4L1_COMPAT
1585 .vidiocgmbuf = vidiocgmbuf,
1586#endif
1587};
1588
1589static const struct video_device au0828_video_template = {
1590 .fops = &au0828_v4l_fops,
1591 .release = video_device_release,
1592 .ioctl_ops = &video_ioctl_ops,
1593 .minor = -1,
1594 .tvnorms = V4L2_STD_NTSC,
1595 .current_norm = V4L2_STD_NTSC,
1596};
1597
1598/**************************************************************************/
1599
1600int au0828_analog_register(struct au0828_dev *dev)
1601{
1602 int retval = -ENOMEM;
1603
1604 dprintk(1, "au0828_analog_register called!\n");
1605
1606 /* Load the analog demodulator driver (note this would need to be
1607 abstracted out if we ever need to support a different demod) */
1608 request_module("au8522");
1609
1610 /* Load the tuner module, which results in i2c enumeration and
1611 attachment of whatever tuner is on the bus */
1612 request_module("tuner");
1613
1614 init_waitqueue_head(&dev->open);
1615 spin_lock_init(&dev->slock);
1616 mutex_init(&dev->lock);
1617
1618 INIT_LIST_HEAD(&dev->vidq.active);
1619 INIT_LIST_HEAD(&dev->vidq.queued);
1620
1621 dev->width = NTSC_STD_W;
1622 dev->height = NTSC_STD_H;
1623 dev->field_size = dev->width * dev->height;
1624 dev->frame_size = dev->field_size << 1;
1625 dev->bytesperline = dev->width << 1;
1626 dev->ctrl_ainput = 0;
1627
1628 /* allocate and fill v4l2 video struct */
1629 dev->vdev = video_device_alloc();
1630 if(NULL == dev->vdev) {
1631 dprintk(1, "Can't allocate video_device.\n");
1632 return -ENOMEM;
1633 }
1634
1635 dev->vbi_dev = video_device_alloc();
1636 if(NULL == dev->vbi_dev) {
1637 dprintk(1, "Can't allocate vbi_device.\n");
1638 kfree(dev->vdev);
1639 return -ENOMEM;
1640 }
1641
1642 /* Fill the video capture device struct */
1643 *dev->vdev = au0828_video_template;
1644 dev->vdev->vfl_type = VID_TYPE_CAPTURE | VID_TYPE_TUNER;
1645 dev->vdev->parent = &dev->usbdev->dev;
1646 strcpy(dev->vdev->name, "au0828a video");
1647
1648 /* Setup the VBI device */
1649 *dev->vbi_dev = au0828_video_template;
1650 dev->vbi_dev->vfl_type = VFL_TYPE_VBI;
1651 dev->vbi_dev->parent = &dev->usbdev->dev;
1652 strcpy(dev->vbi_dev->name, "au0828a vbi");
1653
1654 list_add_tail(&dev->au0828list, &au0828_devlist);
1655
1656 /* Register the v4l2 device */
1657 if((retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1)) != 0) {
1658 dprintk(1, "unable to register video device (error = %d).\n", retval);
1659 list_del(&dev->au0828list);
1660 video_device_release(dev->vdev);
1661 return -ENODEV;
1662 }
1663
1664 /* Register the vbi device */
1665 if((retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1)) != 0) {
1666 dprintk(1, "unable to register vbi device (error = %d).\n", retval);
1667 list_del(&dev->au0828list);
1668 video_device_release(dev->vbi_dev);
1669 video_device_release(dev->vdev);
1670 return -ENODEV;
1671 }
1672
1673 dprintk(1, "%s completed!\n", __FUNCTION__);
1674
1675 return 0;
1676}
1677
diff --git a/drivers/media/video/au0828/au0828.h b/drivers/media/video/au0828/au0828.h
index 9d6a1161dc98..3b8e3e913475 100644
--- a/drivers/media/video/au0828/au0828.h
+++ b/drivers/media/video/au0828/au0828.h
@@ -24,6 +24,10 @@
24#include <linux/i2c-algo-bit.h> 24#include <linux/i2c-algo-bit.h>
25#include <media/tveeprom.h> 25#include <media/tveeprom.h>
26 26
27/* Analog */
28#include <linux/videodev2.h>
29#include <media/videobuf-vmalloc.h>
30
27/* DVB */ 31/* DVB */
28#include "demux.h" 32#include "demux.h"
29#include "dmxdev.h" 33#include "dmxdev.h"
@@ -39,8 +43,48 @@
39#define URB_COUNT 16 43#define URB_COUNT 16
40#define URB_BUFSIZE (0xe522) 44#define URB_BUFSIZE (0xe522)
41 45
46/* Analog constants */
47#define NTSC_STD_W 720
48#define NTSC_STD_H 480
49
50#define AU0828_INTERLACED_DEFAULT 1
51#define V4L2_CID_PRIVATE_SHARPNESS (V4L2_CID_PRIVATE_BASE + 0)
52
53/* Defination for AU0828 USB transfer */
54#define AU0828_MAX_ISO_BUFS 12 /* maybe resize this value in the future */
55#define AU0828_ISO_PACKETS_PER_URB 10
56#define AU0828_ISO_MAX_FRAME_SIZE (3 * 1024)
57#define AU0828_ISO_BUFFER_SIZE (AU0828_ISO_PACKETS_PER_URB * AU0828_ISO_MAX_FRAME_SIZE)
58
59#define AU0828_MIN_BUF 4
60#define AU0828_DEF_BUF 8
61
62#define AU0828_MAX_IMAGES 10
63#define AU0828_FRAME_SIZE (1028 * 1024 * 4)
64#define AU0828_URB_TIMEOUT msecs_to_jiffies(AU0828_MAX_ISO_BUFS * AU0828_ISO_PACKETS_PER_URB)
65
66#define AU0828_MAX_INPUT 4
67
68enum au0828_itype {
69 AU0828_VMUX_COMPOSITE = 1,
70 AU0828_VMUX_SVIDEO,
71 AU0828_VMUX_CABLE,
72 AU0828_VMUX_TELEVISION,
73 AU0828_VMUX_DVB,
74 AU0828_VMUX_DEBUG
75};
76
77struct au0828_input {
78 enum au0828_itype type;
79 unsigned int vmux;
80 unsigned int amux;
81 void (*audio_setup) (void *priv, int enable);
82};
83
42struct au0828_board { 84struct au0828_board {
43 char *name; 85 char *name;
86 struct au0828_input input[AU0828_MAX_INPUT];
87
44}; 88};
45 89
46struct au0828_dvb { 90struct au0828_dvb {
@@ -55,6 +99,83 @@ struct au0828_dvb {
55 int feeding; 99 int feeding;
56}; 100};
57 101
102enum au0828_stream_state {
103 STREAM_OFF,
104 STREAM_INTERRUPT,
105 STREAM_ON
106};
107
108#define AUVI_INPUT(nr) (&au0828_boards[dev->board].input[nr])
109
110/* device state */
111enum au0828_dev_state {
112 DEV_INITIALIZED = 0x01,
113 DEV_DISCONNECTED = 0x02,
114 DEV_MISCONFIGURED = 0x04
115};
116
117struct au0828_fh {
118 struct au0828_dev *dev;
119 unsigned int stream_on:1; /* Locks streams */
120 struct videobuf_queue vb_vidq;
121 enum v4l2_buf_type type;
122};
123
124struct au0828_usb_isoc_ctl {
125 /* max packet size of isoc transaction */
126 int max_pkt_size;
127
128 /* number of allocated urbs */
129 int num_bufs;
130
131 /* urb for isoc transfers */
132 struct urb **urb;
133
134 /* transfer buffers for isoc transfer */
135 char **transfer_buffer;
136
137 /* Last buffer command and region */
138 u8 cmd;
139 int pos, size, pktsize;
140
141 /* Last field: ODD or EVEN? */
142 int field;
143
144 /* Stores incomplete commands */
145 u32 tmp_buf;
146 int tmp_buf_len;
147
148 /* Stores already requested buffers */
149 struct au0828_buffer *buf;
150
151 /* Stores the number of received fields */
152 int nfields;
153
154 /* isoc urb callback */
155 int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb);
156
157};
158
159/* buffer for one video frame */
160struct au0828_buffer {
161 /* common v4l buffer stuff -- must be first */
162 struct videobuf_buffer vb;
163
164 struct list_head frame;
165 int top_field;
166 int receiving;
167};
168
169struct au0828_dmaqueue {
170 struct list_head active;
171 struct list_head queued;
172
173 wait_queue_head_t wq;
174
175 /* Counters to control buffer fill */
176 int pos;
177};
178
58struct au0828_dev { 179struct au0828_dev {
59 struct mutex mutex; 180 struct mutex mutex;
60 struct usb_device *usbdev; 181 struct usb_device *usbdev;
@@ -70,16 +191,49 @@ struct au0828_dev {
70 /* Digital */ 191 /* Digital */
71 struct au0828_dvb dvb; 192 struct au0828_dvb dvb;
72 193
194 /* Analog */
195 struct list_head au0828list;
196 int users;
197 unsigned int stream_on:1; /* Locks streams */
198 struct video_device *vdev;
199 struct video_device *vbi_dev;
200 int width;
201 int height;
202 u32 field_size;
203 u32 frame_size;
204 u32 bytesperline;
205 int type;
206 u8 ctrl_ainput;
207 __u8 isoc_in_endpointaddr;
208 u8 isoc_init_ok;
209 int greenscreen_detected;
210 unsigned int frame_count;
211 int ctrl_freq;
212 int input_type;
213 unsigned int ctrl_input;
214 enum au0828_dev_state dev_state;
215 enum au0828_stream_state stream_state;
216 wait_queue_head_t open;
217
218 struct mutex lock;
219
220 /* Isoc control struct */
221 struct au0828_dmaqueue vidq;
222 struct au0828_usb_isoc_ctl isoc_ctl;
223 spinlock_t slock;
224
225 /* usb transfer */
226 int alt; /* alternate */
227 int max_pkt_size; /* max packet size of isoc transaction */
228 int num_alt; /* Number of alternative settings */
229 unsigned int *alt_max_pkt_size; /* array of wMaxPacketSize */
230 struct urb *urb[AU0828_MAX_ISO_BUFS]; /* urb for isoc transfers */
231 char *transfer_buffer[AU0828_MAX_ISO_BUFS];/* transfer buffers for isoc
232 transfer */
233
73 /* USB / URB Related */ 234 /* USB / URB Related */
74 int urb_streaming; 235 int urb_streaming;
75 struct urb *urbs[URB_COUNT]; 236 struct urb *urbs[URB_COUNT];
76
77};
78
79struct au0828_buff {
80 struct au0828_dev *dev;
81 struct urb *purb;
82 struct list_head buff_list;
83}; 237};
84 238
85/* ----------------------------------------------------------- */ 239/* ----------------------------------------------------------- */
@@ -115,6 +269,12 @@ extern void au0828_call_i2c_clients(struct au0828_dev *dev,
115 unsigned int cmd, void *arg); 269 unsigned int cmd, void *arg);
116 270
117/* ----------------------------------------------------------- */ 271/* ----------------------------------------------------------- */
272/* au0828-video.c */
273int au0828_analog_register(struct au0828_dev *dev);
274int au0828_analog_stream_disable(struct au0828_dev *d);
275void au0828_analog_unregister(struct au0828_dev *dev);
276
277/* ----------------------------------------------------------- */
118/* au0828-dvb.c */ 278/* au0828-dvb.c */
119extern int au0828_dvb_register(struct au0828_dev *dev); 279extern int au0828_dvb_register(struct au0828_dev *dev);
120extern void au0828_dvb_unregister(struct au0828_dev *dev); 280extern void au0828_dvb_unregister(struct au0828_dev *dev);