blob: 691df9157e51647d97ee41a0c6443091ff66fc82 [file] [log] [blame]
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001/*
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>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090032#include <linux/slab.h>
Devin Heitmueller8b2f0792009-03-11 03:00:40 -030033#include <linux/init.h>
34#include <linux/device.h>
35#include <linux/suspend.h>
Devin Heitmueller8b2f0792009-03-11 03:00:40 -030036#include <media/v4l2-common.h>
37#include <media/v4l2-ioctl.h>
Hans Verkuil83b09422013-02-15 09:14:00 -030038#include <media/v4l2-event.h>
Devin Heitmueller8b2f0792009-03-11 03:00:40 -030039#include <media/v4l2-chip-ident.h>
40#include <media/tuner.h>
41#include "au0828.h"
42#include "au0828-reg.h"
43
Devin Heitmueller8b2f0792009-03-11 03:00:40 -030044static DEFINE_MUTEX(au0828_sysfs_lock);
45
Devin Heitmueller8b2f0792009-03-11 03:00:40 -030046/* ------------------------------------------------------------------
47 Videobuf operations
48 ------------------------------------------------------------------*/
49
50static unsigned int isoc_debug;
51module_param(isoc_debug, int, 0644);
52MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
53
54#define au0828_isocdbg(fmt, arg...) \
55do {\
56 if (isoc_debug) { \
57 printk(KERN_INFO "au0828 %s :"fmt, \
58 __func__ , ##arg); \
59 } \
60 } while (0)
61
62static inline void print_err_status(struct au0828_dev *dev,
63 int packet, int status)
64{
65 char *errmsg = "Unknown";
66
67 switch (status) {
68 case -ENOENT:
69 errmsg = "unlinked synchronuously";
70 break;
71 case -ECONNRESET:
72 errmsg = "unlinked asynchronuously";
73 break;
74 case -ENOSR:
75 errmsg = "Buffer error (overrun)";
76 break;
77 case -EPIPE:
78 errmsg = "Stalled (device not responding)";
79 break;
80 case -EOVERFLOW:
81 errmsg = "Babble (bad cable?)";
82 break;
83 case -EPROTO:
84 errmsg = "Bit-stuff error (bad cable?)";
85 break;
86 case -EILSEQ:
87 errmsg = "CRC/Timeout (could be anything)";
88 break;
89 case -ETIME:
90 errmsg = "Device does not respond";
91 break;
92 }
93 if (packet < 0) {
94 au0828_isocdbg("URB status %d [%s].\n", status, errmsg);
95 } else {
96 au0828_isocdbg("URB packet %d, status %d [%s].\n",
97 packet, status, errmsg);
98 }
99}
100
101static int check_dev(struct au0828_dev *dev)
102{
103 if (dev->dev_state & DEV_DISCONNECTED) {
Devin Heitmueller62899a22009-03-15 18:48:52 -0300104 printk(KERN_INFO "v4l2 ioctl: device not present\n");
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300105 return -ENODEV;
106 }
107
108 if (dev->dev_state & DEV_MISCONFIGURED) {
Devin Heitmueller62899a22009-03-15 18:48:52 -0300109 printk(KERN_INFO "v4l2 ioctl: device is misconfigured; "
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300110 "close and open it again\n");
111 return -EIO;
112 }
113 return 0;
114}
115
116/*
117 * IRQ callback, called by URB callback
118 */
119static void au0828_irq_callback(struct urb *urb)
120{
121 struct au0828_dmaqueue *dma_q = urb->context;
122 struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300123 unsigned long flags = 0;
Hans Verkuile92ba282012-05-14 10:17:35 -0300124 int i;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300125
126 switch (urb->status) {
127 case 0: /* success */
128 case -ETIMEDOUT: /* NAK */
129 break;
130 case -ECONNRESET: /* kill */
131 case -ENOENT:
132 case -ESHUTDOWN:
133 au0828_isocdbg("au0828_irq_callback called: status kill\n");
134 return;
135 default: /* unknown error */
136 au0828_isocdbg("urb completition error %d.\n", urb->status);
137 break;
138 }
139
140 /* Copy data from URB */
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300141 spin_lock_irqsave(&dev->slock, flags);
Hans Verkuile92ba282012-05-14 10:17:35 -0300142 dev->isoc_ctl.isoc_copy(dev, urb);
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300143 spin_unlock_irqrestore(&dev->slock, flags);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300144
145 /* Reset urb buffers */
146 for (i = 0; i < urb->number_of_packets; i++) {
147 urb->iso_frame_desc[i].status = 0;
148 urb->iso_frame_desc[i].actual_length = 0;
149 }
150 urb->status = 0;
151
152 urb->status = usb_submit_urb(urb, GFP_ATOMIC);
153 if (urb->status) {
154 au0828_isocdbg("urb resubmit failed (error=%i)\n",
155 urb->status);
156 }
157}
158
159/*
160 * Stop and Deallocate URBs
161 */
Mauro Carvalho Chehaba094ca42012-10-27 14:00:30 -0300162static void au0828_uninit_isoc(struct au0828_dev *dev)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300163{
164 struct urb *urb;
165 int i;
166
167 au0828_isocdbg("au0828: called au0828_uninit_isoc\n");
168
169 dev->isoc_ctl.nfields = -1;
170 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
171 urb = dev->isoc_ctl.urb[i];
172 if (urb) {
173 if (!irqs_disabled())
174 usb_kill_urb(urb);
175 else
176 usb_unlink_urb(urb);
177
178 if (dev->isoc_ctl.transfer_buffer[i]) {
Daniel Mack997ea582010-04-12 13:17:25 +0200179 usb_free_coherent(dev->usbdev,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300180 urb->transfer_buffer_length,
181 dev->isoc_ctl.transfer_buffer[i],
182 urb->transfer_dma);
183 }
184 usb_free_urb(urb);
185 dev->isoc_ctl.urb[i] = NULL;
186 }
187 dev->isoc_ctl.transfer_buffer[i] = NULL;
188 }
189
190 kfree(dev->isoc_ctl.urb);
191 kfree(dev->isoc_ctl.transfer_buffer);
192
193 dev->isoc_ctl.urb = NULL;
194 dev->isoc_ctl.transfer_buffer = NULL;
195 dev->isoc_ctl.num_bufs = 0;
196}
197
198/*
199 * Allocate URBs and start IRQ
200 */
Mauro Carvalho Chehaba094ca42012-10-27 14:00:30 -0300201static int au0828_init_isoc(struct au0828_dev *dev, int max_packets,
202 int num_bufs, int max_pkt_size,
203 int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb))
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300204{
205 struct au0828_dmaqueue *dma_q = &dev->vidq;
206 int i;
207 int sb_size, pipe;
208 struct urb *urb;
209 int j, k;
210 int rc;
211
212 au0828_isocdbg("au0828: called au0828_prepare_isoc\n");
213
214 /* De-allocates all pending stuff */
215 au0828_uninit_isoc(dev);
216
217 dev->isoc_ctl.isoc_copy = isoc_copy;
218 dev->isoc_ctl.num_bufs = num_bufs;
219
220 dev->isoc_ctl.urb = kzalloc(sizeof(void *)*num_bufs, GFP_KERNEL);
221 if (!dev->isoc_ctl.urb) {
222 au0828_isocdbg("cannot alloc memory for usb buffers\n");
223 return -ENOMEM;
224 }
225
226 dev->isoc_ctl.transfer_buffer = kzalloc(sizeof(void *)*num_bufs,
227 GFP_KERNEL);
228 if (!dev->isoc_ctl.transfer_buffer) {
229 au0828_isocdbg("cannot allocate memory for usb transfer\n");
230 kfree(dev->isoc_ctl.urb);
231 return -ENOMEM;
232 }
233
234 dev->isoc_ctl.max_pkt_size = max_pkt_size;
235 dev->isoc_ctl.buf = NULL;
236
237 sb_size = max_packets * dev->isoc_ctl.max_pkt_size;
238
239 /* allocate urbs and transfer buffers */
240 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
241 urb = usb_alloc_urb(max_packets, GFP_KERNEL);
242 if (!urb) {
243 au0828_isocdbg("cannot alloc isoc_ctl.urb %i\n", i);
244 au0828_uninit_isoc(dev);
245 return -ENOMEM;
246 }
247 dev->isoc_ctl.urb[i] = urb;
248
Daniel Mack997ea582010-04-12 13:17:25 +0200249 dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->usbdev,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300250 sb_size, GFP_KERNEL, &urb->transfer_dma);
251 if (!dev->isoc_ctl.transfer_buffer[i]) {
252 printk("unable to allocate %i bytes for transfer"
253 " buffer %i%s\n",
254 sb_size, i,
255 in_interrupt() ? " while in int" : "");
256 au0828_uninit_isoc(dev);
257 return -ENOMEM;
258 }
259 memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
260
261 pipe = usb_rcvisocpipe(dev->usbdev,
262 dev->isoc_in_endpointaddr),
263
264 usb_fill_int_urb(urb, dev->usbdev, pipe,
265 dev->isoc_ctl.transfer_buffer[i], sb_size,
266 au0828_irq_callback, dma_q, 1);
267
268 urb->number_of_packets = max_packets;
Devin Heitmuellerfadadb72009-03-22 23:42:26 -0300269 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300270
271 k = 0;
272 for (j = 0; j < max_packets; j++) {
273 urb->iso_frame_desc[j].offset = k;
274 urb->iso_frame_desc[j].length =
275 dev->isoc_ctl.max_pkt_size;
276 k += dev->isoc_ctl.max_pkt_size;
277 }
278 }
279
280 init_waitqueue_head(&dma_q->wq);
281
282 /* submit urbs and enables IRQ */
283 for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
284 rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC);
285 if (rc) {
286 au0828_isocdbg("submit of urb %i failed (error=%i)\n",
287 i, rc);
288 au0828_uninit_isoc(dev);
289 return rc;
290 }
291 }
292
293 return 0;
294}
295
296/*
297 * Announces that a buffer were filled and request the next
298 */
299static inline void buffer_filled(struct au0828_dev *dev,
300 struct au0828_dmaqueue *dma_q,
301 struct au0828_buffer *buf)
302{
303 /* Advice that buffer was filled */
304 au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
305
306 buf->vb.state = VIDEOBUF_DONE;
307 buf->vb.field_count++;
Sakari Ailus8e6057b2012-09-15 15:14:42 -0300308 v4l2_get_timestamp(&buf->vb.ts);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300309
310 dev->isoc_ctl.buf = NULL;
311
312 list_del(&buf->vb.queue);
313 wake_up(&buf->vb.done);
314}
315
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300316static inline void vbi_buffer_filled(struct au0828_dev *dev,
317 struct au0828_dmaqueue *dma_q,
318 struct au0828_buffer *buf)
319{
320 /* Advice that buffer was filled */
321 au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
322
323 buf->vb.state = VIDEOBUF_DONE;
324 buf->vb.field_count++;
Sakari Ailus8e6057b2012-09-15 15:14:42 -0300325 v4l2_get_timestamp(&buf->vb.ts);
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300326
327 dev->isoc_ctl.vbi_buf = NULL;
328
329 list_del(&buf->vb.queue);
330 wake_up(&buf->vb.done);
331}
332
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300333/*
334 * Identify the buffer header type and properly handles
335 */
336static void au0828_copy_video(struct au0828_dev *dev,
337 struct au0828_dmaqueue *dma_q,
338 struct au0828_buffer *buf,
339 unsigned char *p,
340 unsigned char *outp, unsigned long len)
341{
342 void *fieldstart, *startwrite, *startread;
343 int linesdone, currlinedone, offset, lencopy, remain;
344 int bytesperline = dev->width << 1; /* Assumes 16-bit depth @@@@ */
345
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300346 if (len == 0)
347 return;
348
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300349 if (dma_q->pos + len > buf->vb.size)
350 len = buf->vb.size - dma_q->pos;
351
352 startread = p;
353 remain = len;
354
355 /* Interlaces frame */
356 if (buf->top_field)
357 fieldstart = outp;
358 else
359 fieldstart = outp + bytesperline;
360
361 linesdone = dma_q->pos / bytesperline;
362 currlinedone = dma_q->pos % bytesperline;
363 offset = linesdone * bytesperline * 2 + currlinedone;
364 startwrite = fieldstart + offset;
365 lencopy = bytesperline - currlinedone;
366 lencopy = lencopy > remain ? remain : lencopy;
367
368 if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
369 au0828_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
370 ((char *)startwrite + lencopy) -
371 ((char *)outp + buf->vb.size));
372 remain = (char *)outp + buf->vb.size - (char *)startwrite;
373 lencopy = remain;
374 }
375 if (lencopy <= 0)
376 return;
377 memcpy(startwrite, startread, lencopy);
378
379 remain -= lencopy;
380
381 while (remain > 0) {
382 startwrite += lencopy + bytesperline;
383 startread += lencopy;
384 if (bytesperline > remain)
385 lencopy = remain;
386 else
387 lencopy = bytesperline;
388
389 if ((char *)startwrite + lencopy > (char *)outp +
390 buf->vb.size) {
Devin Heitmueller62899a22009-03-15 18:48:52 -0300391 au0828_isocdbg("Overflow %zi bytes past buf end (2)\n",
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300392 ((char *)startwrite + lencopy) -
393 ((char *)outp + buf->vb.size));
394 lencopy = remain = (char *)outp + buf->vb.size -
395 (char *)startwrite;
396 }
397 if (lencopy <= 0)
398 break;
399
400 memcpy(startwrite, startread, lencopy);
401
402 remain -= lencopy;
403 }
404
405 if (offset > 1440) {
406 /* We have enough data to check for greenscreen */
Devin Heitmueller62899a22009-03-15 18:48:52 -0300407 if (outp[0] < 0x60 && outp[1440] < 0x60)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300408 dev->greenscreen_detected = 1;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300409 }
410
411 dma_q->pos += len;
412}
413
414/*
415 * video-buf generic routine to get the next available buffer
416 */
417static inline void get_next_buf(struct au0828_dmaqueue *dma_q,
418 struct au0828_buffer **buf)
419{
420 struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
421
422 if (list_empty(&dma_q->active)) {
423 au0828_isocdbg("No active queue to serve\n");
424 dev->isoc_ctl.buf = NULL;
425 *buf = NULL;
426 return;
427 }
428
429 /* Get the next buffer */
430 *buf = list_entry(dma_q->active.next, struct au0828_buffer, vb.queue);
431 dev->isoc_ctl.buf = *buf;
432
433 return;
434}
435
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300436static void au0828_copy_vbi(struct au0828_dev *dev,
437 struct au0828_dmaqueue *dma_q,
438 struct au0828_buffer *buf,
439 unsigned char *p,
440 unsigned char *outp, unsigned long len)
441{
442 unsigned char *startwrite, *startread;
Dan Carpenterb5f59332010-07-23 07:09:20 -0300443 int bytesperline;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300444 int i, j = 0;
445
446 if (dev == NULL) {
447 au0828_isocdbg("dev is null\n");
448 return;
449 }
450
451 if (dma_q == NULL) {
452 au0828_isocdbg("dma_q is null\n");
453 return;
454 }
455 if (buf == NULL)
456 return;
457 if (p == NULL) {
458 au0828_isocdbg("p is null\n");
459 return;
460 }
461 if (outp == NULL) {
462 au0828_isocdbg("outp is null\n");
463 return;
464 }
465
Dan Carpenterb5f59332010-07-23 07:09:20 -0300466 bytesperline = dev->vbi_width;
467
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300468 if (dma_q->pos + len > buf->vb.size)
469 len = buf->vb.size - dma_q->pos;
470
471 startread = p;
472 startwrite = outp + (dma_q->pos / 2);
473
474 /* Make sure the bottom field populates the second half of the frame */
475 if (buf->top_field == 0)
476 startwrite += bytesperline * dev->vbi_height;
477
478 for (i = 0; i < len; i += 2)
479 startwrite[j++] = startread[i+1];
480
481 dma_q->pos += len;
482}
483
484
485/*
486 * video-buf generic routine to get the next available VBI buffer
487 */
488static inline void vbi_get_next_buf(struct au0828_dmaqueue *dma_q,
489 struct au0828_buffer **buf)
490{
491 struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vbiq);
492 char *outp;
493
494 if (list_empty(&dma_q->active)) {
495 au0828_isocdbg("No active queue to serve\n");
496 dev->isoc_ctl.vbi_buf = NULL;
497 *buf = NULL;
498 return;
499 }
500
501 /* Get the next buffer */
502 *buf = list_entry(dma_q->active.next, struct au0828_buffer, vb.queue);
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300503 /* Cleans up buffer - Useful for testing for frame/URB loss */
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300504 outp = videobuf_to_vmalloc(&(*buf)->vb);
505 memset(outp, 0x00, (*buf)->vb.size);
506
507 dev->isoc_ctl.vbi_buf = *buf;
508
509 return;
510}
511
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300512/*
513 * Controls the isoc copy of each urb packet
514 */
515static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
516{
517 struct au0828_buffer *buf;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300518 struct au0828_buffer *vbi_buf;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300519 struct au0828_dmaqueue *dma_q = urb->context;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300520 struct au0828_dmaqueue *vbi_dma_q = &dev->vbiq;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300521 unsigned char *outp = NULL;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300522 unsigned char *vbioutp = NULL;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300523 int i, len = 0, rc = 1;
524 unsigned char *p;
525 unsigned char fbyte;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300526 unsigned int vbi_field_size;
527 unsigned int remain, lencopy;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300528
529 if (!dev)
530 return 0;
531
532 if ((dev->dev_state & DEV_DISCONNECTED) ||
533 (dev->dev_state & DEV_MISCONFIGURED))
534 return 0;
535
536 if (urb->status < 0) {
537 print_err_status(dev, -1, urb->status);
538 if (urb->status == -ENOENT)
539 return 0;
540 }
541
542 buf = dev->isoc_ctl.buf;
543 if (buf != NULL)
544 outp = videobuf_to_vmalloc(&buf->vb);
545
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300546 vbi_buf = dev->isoc_ctl.vbi_buf;
547 if (vbi_buf != NULL)
548 vbioutp = videobuf_to_vmalloc(&vbi_buf->vb);
549
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300550 for (i = 0; i < urb->number_of_packets; i++) {
551 int status = urb->iso_frame_desc[i].status;
552
553 if (status < 0) {
554 print_err_status(dev, i, status);
555 if (urb->iso_frame_desc[i].status != -EPROTO)
556 continue;
557 }
558
Devin Heitmueller62899a22009-03-15 18:48:52 -0300559 if (urb->iso_frame_desc[i].actual_length <= 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300560 continue;
Devin Heitmueller62899a22009-03-15 18:48:52 -0300561
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300562 if (urb->iso_frame_desc[i].actual_length >
563 dev->max_pkt_size) {
564 au0828_isocdbg("packet bigger than packet size");
565 continue;
566 }
567
568 p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
569 fbyte = p[0];
570 len = urb->iso_frame_desc[i].actual_length - 4;
571 p += 4;
572
573 if (fbyte & 0x80) {
574 len -= 4;
575 p += 4;
576 au0828_isocdbg("Video frame %s\n",
577 (fbyte & 0x40) ? "odd" : "even");
Devin Heitmuellerbde3bb92010-07-05 13:05:16 -0300578 if (fbyte & 0x40) {
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300579 /* VBI */
580 if (vbi_buf != NULL)
581 vbi_buffer_filled(dev,
582 vbi_dma_q,
583 vbi_buf);
584 vbi_get_next_buf(vbi_dma_q, &vbi_buf);
585 if (vbi_buf == NULL)
586 vbioutp = NULL;
587 else
588 vbioutp = videobuf_to_vmalloc(
589 &vbi_buf->vb);
590
591 /* Video */
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300592 if (buf != NULL)
593 buffer_filled(dev, dma_q, buf);
594 get_next_buf(dma_q, &buf);
Devin Heitmueller62899a22009-03-15 18:48:52 -0300595 if (buf == NULL)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300596 outp = NULL;
Devin Heitmueller62899a22009-03-15 18:48:52 -0300597 else
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300598 outp = videobuf_to_vmalloc(&buf->vb);
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300599
600 /* As long as isoc traffic is arriving, keep
601 resetting the timer */
602 if (dev->vid_timeout_running)
603 mod_timer(&dev->vid_timeout,
604 jiffies + (HZ / 10));
605 if (dev->vbi_timeout_running)
606 mod_timer(&dev->vbi_timeout,
607 jiffies + (HZ / 10));
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300608 }
609
610 if (buf != NULL) {
Devin Heitmueller62899a22009-03-15 18:48:52 -0300611 if (fbyte & 0x40)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300612 buf->top_field = 1;
Devin Heitmueller62899a22009-03-15 18:48:52 -0300613 else
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300614 buf->top_field = 0;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300615 }
616
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300617 if (vbi_buf != NULL) {
618 if (fbyte & 0x40)
619 vbi_buf->top_field = 1;
620 else
621 vbi_buf->top_field = 0;
622 }
623
624 dev->vbi_read = 0;
625 vbi_dma_q->pos = 0;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300626 dma_q->pos = 0;
627 }
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300628
629 vbi_field_size = dev->vbi_width * dev->vbi_height * 2;
630 if (dev->vbi_read < vbi_field_size) {
631 remain = vbi_field_size - dev->vbi_read;
632 if (len < remain)
633 lencopy = len;
634 else
635 lencopy = remain;
636
637 if (vbi_buf != NULL)
638 au0828_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
639 vbioutp, len);
640
641 len -= lencopy;
642 p += lencopy;
643 dev->vbi_read += lencopy;
644 }
645
646 if (dev->vbi_read >= vbi_field_size && buf != NULL)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300647 au0828_copy_video(dev, dma_q, buf, p, outp, len);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300648 }
649 return rc;
650}
651
652static int
653buffer_setup(struct videobuf_queue *vq, unsigned int *count,
654 unsigned int *size)
655{
656 struct au0828_fh *fh = vq->priv_data;
657 *size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
658
659 if (0 == *count)
660 *count = AU0828_DEF_BUF;
661
662 if (*count < AU0828_MIN_BUF)
663 *count = AU0828_MIN_BUF;
664 return 0;
665}
666
667/* This is called *without* dev->slock held; please keep it that way */
668static void free_buffer(struct videobuf_queue *vq, struct au0828_buffer *buf)
669{
670 struct au0828_fh *fh = vq->priv_data;
671 struct au0828_dev *dev = fh->dev;
672 unsigned long flags = 0;
673 if (in_interrupt())
674 BUG();
675
676 /* We used to wait for the buffer to finish here, but this didn't work
677 because, as we were keeping the state as VIDEOBUF_QUEUED,
678 videobuf_queue_cancel marked it as finished for us.
679 (Also, it could wedge forever if the hardware was misconfigured.)
680
681 This should be safe; by the time we get here, the buffer isn't
682 queued anymore. If we ever start marking the buffers as
683 VIDEOBUF_ACTIVE, it won't be, though.
684 */
685 spin_lock_irqsave(&dev->slock, flags);
686 if (dev->isoc_ctl.buf == buf)
687 dev->isoc_ctl.buf = NULL;
688 spin_unlock_irqrestore(&dev->slock, flags);
689
690 videobuf_vmalloc_free(&buf->vb);
691 buf->vb.state = VIDEOBUF_NEEDS_INIT;
692}
693
694static int
695buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
696 enum v4l2_field field)
697{
698 struct au0828_fh *fh = vq->priv_data;
699 struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
700 struct au0828_dev *dev = fh->dev;
701 int rc = 0, urb_init = 0;
702
703 buf->vb.size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
704
705 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
706 return -EINVAL;
707
708 buf->vb.width = dev->width;
709 buf->vb.height = dev->height;
710 buf->vb.field = field;
711
712 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
713 rc = videobuf_iolock(vq, &buf->vb, NULL);
714 if (rc < 0) {
Devin Heitmueller62899a22009-03-15 18:48:52 -0300715 printk(KERN_INFO "videobuf_iolock failed\n");
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300716 goto fail;
717 }
718 }
719
720 if (!dev->isoc_ctl.num_bufs)
721 urb_init = 1;
722
723 if (urb_init) {
724 rc = au0828_init_isoc(dev, AU0828_ISO_PACKETS_PER_URB,
725 AU0828_MAX_ISO_BUFS, dev->max_pkt_size,
726 au0828_isoc_copy);
727 if (rc < 0) {
Devin Heitmueller62899a22009-03-15 18:48:52 -0300728 printk(KERN_INFO "au0828_init_isoc failed\n");
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300729 goto fail;
730 }
731 }
732
733 buf->vb.state = VIDEOBUF_PREPARED;
734 return 0;
735
736fail:
737 free_buffer(vq, buf);
738 return rc;
739}
740
741static void
742buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
743{
744 struct au0828_buffer *buf = container_of(vb,
745 struct au0828_buffer,
746 vb);
747 struct au0828_fh *fh = vq->priv_data;
748 struct au0828_dev *dev = fh->dev;
749 struct au0828_dmaqueue *vidq = &dev->vidq;
750
751 buf->vb.state = VIDEOBUF_QUEUED;
752 list_add_tail(&buf->vb.queue, &vidq->active);
753}
754
755static void buffer_release(struct videobuf_queue *vq,
756 struct videobuf_buffer *vb)
757{
758 struct au0828_buffer *buf = container_of(vb,
759 struct au0828_buffer,
760 vb);
761
762 free_buffer(vq, buf);
763}
764
765static struct videobuf_queue_ops au0828_video_qops = {
766 .buf_setup = buffer_setup,
767 .buf_prepare = buffer_prepare,
768 .buf_queue = buffer_queue,
769 .buf_release = buffer_release,
770};
771
772/* ------------------------------------------------------------------
773 V4L2 interface
774 ------------------------------------------------------------------*/
775
776static int au0828_i2s_init(struct au0828_dev *dev)
777{
778 /* Enable i2s mode */
779 au0828_writereg(dev, AU0828_AUDIOCTRL_50C, 0x01);
780 return 0;
781}
782
783/*
784 * Auvitek au0828 analog stream enable
785 * Please set interface0 to AS5 before enable the stream
786 */
Mauro Carvalho Chehaba094ca42012-10-27 14:00:30 -0300787static int au0828_analog_stream_enable(struct au0828_dev *d)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300788{
789 dprintk(1, "au0828_analog_stream_enable called\n");
790 au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
791 au0828_writereg(d, 0x106, 0x00);
792 /* set x position */
793 au0828_writereg(d, 0x110, 0x00);
794 au0828_writereg(d, 0x111, 0x00);
795 au0828_writereg(d, 0x114, 0xa0);
796 au0828_writereg(d, 0x115, 0x05);
797 /* set y position */
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300798 au0828_writereg(d, 0x112, 0x00);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300799 au0828_writereg(d, 0x113, 0x00);
800 au0828_writereg(d, 0x116, 0xf2);
801 au0828_writereg(d, 0x117, 0x00);
802 au0828_writereg(d, AU0828_SENSORCTRL_100, 0xb3);
803
804 return 0;
805}
806
807int au0828_analog_stream_disable(struct au0828_dev *d)
808{
809 dprintk(1, "au0828_analog_stream_disable called\n");
810 au0828_writereg(d, AU0828_SENSORCTRL_100, 0x0);
811 return 0;
812}
813
Mauro Carvalho Chehaba094ca42012-10-27 14:00:30 -0300814static void au0828_analog_stream_reset(struct au0828_dev *dev)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300815{
816 dprintk(1, "au0828_analog_stream_reset called\n");
817 au0828_writereg(dev, AU0828_SENSORCTRL_100, 0x0);
818 mdelay(30);
819 au0828_writereg(dev, AU0828_SENSORCTRL_100, 0xb3);
820}
821
822/*
823 * Some operations needs to stop current streaming
824 */
825static int au0828_stream_interrupt(struct au0828_dev *dev)
826{
827 int ret = 0;
828
829 dev->stream_state = STREAM_INTERRUPT;
Devin Heitmueller62899a22009-03-15 18:48:52 -0300830 if (dev->dev_state == DEV_DISCONNECTED)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300831 return -ENODEV;
Devin Heitmueller62899a22009-03-15 18:48:52 -0300832 else if (ret) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300833 dev->dev_state = DEV_MISCONFIGURED;
Devin Heitmueller62899a22009-03-15 18:48:52 -0300834 dprintk(1, "%s device is misconfigured!\n", __func__);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300835 return ret;
836 }
837 return 0;
838}
839
840/*
841 * au0828_release_resources
842 * unregister v4l2 devices
843 */
844void au0828_analog_unregister(struct au0828_dev *dev)
845{
846 dprintk(1, "au0828_release_resources called\n");
847 mutex_lock(&au0828_sysfs_lock);
848
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -0200849 if (dev->vdev)
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -0300850 video_unregister_device(dev->vdev);
851 if (dev->vbi_dev)
852 video_unregister_device(dev->vbi_dev);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300853
854 mutex_unlock(&au0828_sysfs_lock);
855}
856
857
858/* Usage lock check functions */
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300859static int res_get(struct au0828_fh *fh, unsigned int bit)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300860{
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300861 struct au0828_dev *dev = fh->dev;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300862
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300863 if (fh->resources & bit)
864 /* have it already allocated */
865 return 1;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300866
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300867 /* is it free? */
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300868 if (dev->resources & bit) {
869 /* no, someone else uses it */
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300870 return 0;
871 }
872 /* it's free, grab it */
873 fh->resources |= bit;
874 dev->resources |= bit;
875 dprintk(1, "res: get %d\n", bit);
Devin Heitmueller549ee4d2012-08-06 22:46:58 -0300876
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300877 return 1;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300878}
879
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300880static int res_check(struct au0828_fh *fh, unsigned int bit)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300881{
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300882 return fh->resources & bit;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300883}
884
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300885static int res_locked(struct au0828_dev *dev, unsigned int bit)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300886{
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300887 return dev->resources & bit;
888}
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300889
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300890static void res_free(struct au0828_fh *fh, unsigned int bits)
891{
892 struct au0828_dev *dev = fh->dev;
893
894 BUG_ON((fh->resources & bits) != bits);
895
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300896 fh->resources &= ~bits;
897 dev->resources &= ~bits;
898 dprintk(1, "res: put %d\n", bits);
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300899}
900
901static int get_ressource(struct au0828_fh *fh)
902{
903 switch (fh->type) {
904 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
905 return AU0828_RESOURCE_VIDEO;
906 case V4L2_BUF_TYPE_VBI_CAPTURE:
907 return AU0828_RESOURCE_VBI;
908 default:
909 BUG();
910 return 0;
911 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300912}
913
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300914/* This function ensures that video frames continue to be delivered even if
915 the ITU-656 input isn't receiving any data (thereby preventing applications
916 such as tvtime from hanging) */
Mauro Carvalho Chehaba094ca42012-10-27 14:00:30 -0300917static void au0828_vid_buffer_timeout(unsigned long data)
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300918{
919 struct au0828_dev *dev = (struct au0828_dev *) data;
920 struct au0828_dmaqueue *dma_q = &dev->vidq;
921 struct au0828_buffer *buf;
922 unsigned char *vid_data;
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300923 unsigned long flags = 0;
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300924
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300925 spin_lock_irqsave(&dev->slock, flags);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300926
927 buf = dev->isoc_ctl.buf;
928 if (buf != NULL) {
929 vid_data = videobuf_to_vmalloc(&buf->vb);
930 memset(vid_data, 0x00, buf->vb.size); /* Blank green frame */
931 buffer_filled(dev, dma_q, buf);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300932 }
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300933 get_next_buf(dma_q, &buf);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300934
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300935 if (dev->vid_timeout_running == 1)
936 mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
937
938 spin_unlock_irqrestore(&dev->slock, flags);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300939}
940
Mauro Carvalho Chehaba094ca42012-10-27 14:00:30 -0300941static void au0828_vbi_buffer_timeout(unsigned long data)
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300942{
943 struct au0828_dev *dev = (struct au0828_dev *) data;
944 struct au0828_dmaqueue *dma_q = &dev->vbiq;
945 struct au0828_buffer *buf;
946 unsigned char *vbi_data;
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300947 unsigned long flags = 0;
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300948
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300949 spin_lock_irqsave(&dev->slock, flags);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300950
951 buf = dev->isoc_ctl.vbi_buf;
952 if (buf != NULL) {
953 vbi_data = videobuf_to_vmalloc(&buf->vb);
954 memset(vbi_data, 0x00, buf->vb.size);
955 vbi_buffer_filled(dev, dma_q, buf);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300956 }
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300957 vbi_get_next_buf(dma_q, &buf);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300958
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300959 if (dev->vbi_timeout_running == 1)
960 mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
961 spin_unlock_irqrestore(&dev->slock, flags);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300962}
963
964
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300965static int au0828_v4l2_open(struct file *filp)
966{
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300967 int ret = 0;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300968 struct video_device *vdev = video_devdata(filp);
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -0200969 struct au0828_dev *dev = video_drvdata(filp);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300970 struct au0828_fh *fh;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300971 int type;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300972
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300973 switch (vdev->vfl_type) {
974 case VFL_TYPE_GRABBER:
975 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
976 break;
977 case VFL_TYPE_VBI:
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -0200978 type = V4L2_BUF_TYPE_VBI_CAPTURE;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300979 break;
980 default:
981 return -EINVAL;
982 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300983
984 fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL);
Devin Heitmueller62899a22009-03-15 18:48:52 -0300985 if (NULL == fh) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300986 dprintk(1, "Failed allocate au0828_fh struct!\n");
987 return -ENOMEM;
988 }
989
990 fh->type = type;
991 fh->dev = dev;
Hans Verkuil83b09422013-02-15 09:14:00 -0300992 v4l2_fh_init(&fh->fh, vdev);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300993 filp->private_data = fh;
994
Devin Heitmueller62899a22009-03-15 18:48:52 -0300995 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && dev->users == 0) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300996 /* set au0828 interface0 to AS5 here again */
997 ret = usb_set_interface(dev->usbdev, 0, 5);
Devin Heitmueller62899a22009-03-15 18:48:52 -0300998 if (ret < 0) {
999 printk(KERN_INFO "Au0828 can't set alternate to 5!\n");
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001000 return -EBUSY;
1001 }
1002 dev->width = NTSC_STD_W;
1003 dev->height = NTSC_STD_H;
1004 dev->frame_size = dev->width * dev->height * 2;
1005 dev->field_size = dev->width * dev->height;
1006 dev->bytesperline = dev->width * 2;
1007
1008 au0828_analog_stream_enable(dev);
1009 au0828_analog_stream_reset(dev);
1010
1011 /* If we were doing ac97 instead of i2s, it would go here...*/
1012 au0828_i2s_init(dev);
1013
1014 dev->stream_state = STREAM_OFF;
1015 dev->dev_state |= DEV_INITIALIZED;
1016 }
1017
1018 dev->users++;
1019
1020 videobuf_queue_vmalloc_init(&fh->vb_vidq, &au0828_video_qops,
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001021 NULL, &dev->slock,
1022 V4L2_BUF_TYPE_VIDEO_CAPTURE,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001023 V4L2_FIELD_INTERLACED,
Devin Heitmueller549ee4d2012-08-06 22:46:58 -03001024 sizeof(struct au0828_buffer), fh,
1025 &dev->lock);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001026
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001027 /* VBI Setup */
1028 dev->vbi_width = 720;
1029 dev->vbi_height = 1;
1030 videobuf_queue_vmalloc_init(&fh->vb_vbiq, &au0828_vbi_qops,
1031 NULL, &dev->slock,
1032 V4L2_BUF_TYPE_VBI_CAPTURE,
1033 V4L2_FIELD_SEQ_TB,
Devin Heitmueller549ee4d2012-08-06 22:46:58 -03001034 sizeof(struct au0828_buffer), fh,
1035 &dev->lock);
Hans Verkuil83b09422013-02-15 09:14:00 -03001036 v4l2_fh_add(&fh->fh);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001037 return ret;
1038}
1039
1040static int au0828_v4l2_close(struct file *filp)
1041{
1042 int ret;
1043 struct au0828_fh *fh = filp->private_data;
1044 struct au0828_dev *dev = fh->dev;
1045
Hans Verkuil83b09422013-02-15 09:14:00 -03001046 v4l2_fh_del(&fh->fh);
1047 v4l2_fh_exit(&fh->fh);
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001048 if (res_check(fh, AU0828_RESOURCE_VIDEO)) {
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001049 /* Cancel timeout thread in case they didn't call streamoff */
1050 dev->vid_timeout_running = 0;
1051 del_timer_sync(&dev->vid_timeout);
1052
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001053 videobuf_stop(&fh->vb_vidq);
1054 res_free(fh, AU0828_RESOURCE_VIDEO);
1055 }
1056
1057 if (res_check(fh, AU0828_RESOURCE_VBI)) {
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001058 /* Cancel timeout thread in case they didn't call streamoff */
1059 dev->vbi_timeout_running = 0;
1060 del_timer_sync(&dev->vbi_timeout);
1061
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001062 videobuf_stop(&fh->vb_vbiq);
1063 res_free(fh, AU0828_RESOURCE_VBI);
1064 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001065
Devin Heitmueller62899a22009-03-15 18:48:52 -03001066 if (dev->users == 1) {
Devin Heitmueller62899a22009-03-15 18:48:52 -03001067 if (dev->dev_state & DEV_DISCONNECTED) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001068 au0828_analog_unregister(dev);
Hans Verkuil83b09422013-02-15 09:14:00 -03001069 kfree(fh);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001070 kfree(dev);
1071 return 0;
1072 }
1073
1074 au0828_analog_stream_disable(dev);
1075
1076 au0828_uninit_isoc(dev);
1077
Devin Heitmuellere4b8bc52009-05-06 20:54:00 -03001078 /* Save some power by putting tuner to sleep */
Laurent Pinchart622b8282009-10-05 10:48:17 -03001079 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
Devin Heitmuellere4b8bc52009-05-06 20:54:00 -03001080
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001081 /* When close the device, set the usb intf0 into alt0 to free
1082 USB bandwidth */
1083 ret = usb_set_interface(dev->usbdev, 0, 0);
Devin Heitmueller62899a22009-03-15 18:48:52 -03001084 if (ret < 0)
1085 printk(KERN_INFO "Au0828 can't set alternate to 0!\n");
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001086 }
1087
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001088 videobuf_mmap_free(&fh->vb_vidq);
1089 videobuf_mmap_free(&fh->vb_vbiq);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001090 kfree(fh);
1091 dev->users--;
1092 wake_up_interruptible_nr(&dev->open, 1);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001093 return 0;
1094}
1095
1096static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf,
1097 size_t count, loff_t *pos)
1098{
1099 struct au0828_fh *fh = filp->private_data;
1100 struct au0828_dev *dev = fh->dev;
1101 int rc;
1102
1103 rc = check_dev(dev);
1104 if (rc < 0)
1105 return rc;
1106
Devin Heitmueller62899a22009-03-15 18:48:52 -03001107 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001108 if (res_locked(dev, AU0828_RESOURCE_VIDEO))
1109 return -EBUSY;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001110
1111 return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
1112 filp->f_flags & O_NONBLOCK);
1113 }
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001114
1115 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1116 if (!res_get(fh, AU0828_RESOURCE_VBI))
1117 return -EBUSY;
1118
Devin Heitmuellerbf797162010-10-09 15:09:17 -03001119 if (dev->vbi_timeout_running == 0) {
1120 /* Handle case where caller tries to read without
1121 calling streamon first */
1122 dev->vbi_timeout_running = 1;
1123 mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
1124 }
1125
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001126 return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
1127 filp->f_flags & O_NONBLOCK);
1128 }
1129
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001130 return 0;
1131}
1132
1133static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait)
1134{
1135 struct au0828_fh *fh = filp->private_data;
1136 struct au0828_dev *dev = fh->dev;
Hans Verkuil83b09422013-02-15 09:14:00 -03001137 unsigned long req_events = poll_requested_events(wait);
1138 unsigned int res;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001139
Hans Verkuil83b09422013-02-15 09:14:00 -03001140 if (check_dev(dev) < 0)
1141 return POLLERR;
1142
1143 res = v4l2_ctrl_poll(filp, wait);
1144 if (!(req_events & (POLLIN | POLLRDNORM)))
1145 return res;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001146
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001147 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1148 if (!res_get(fh, AU0828_RESOURCE_VIDEO))
1149 return POLLERR;
Hans Verkuil83b09422013-02-15 09:14:00 -03001150 return res | videobuf_poll_stream(filp, &fh->vb_vidq, wait);
1151 }
1152 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001153 if (!res_get(fh, AU0828_RESOURCE_VBI))
1154 return POLLERR;
Hans Verkuil83b09422013-02-15 09:14:00 -03001155 return res | videobuf_poll_stream(filp, &fh->vb_vbiq, wait);
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001156 }
Hans Verkuil83b09422013-02-15 09:14:00 -03001157 return POLLERR;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001158}
1159
1160static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
1161{
1162 struct au0828_fh *fh = filp->private_data;
1163 struct au0828_dev *dev = fh->dev;
1164 int rc;
1165
1166 rc = check_dev(dev);
1167 if (rc < 0)
1168 return rc;
1169
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001170 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1171 rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
1172 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1173 rc = videobuf_mmap_mapper(&fh->vb_vbiq, vma);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001174
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001175 return rc;
1176}
1177
1178static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
1179 struct v4l2_format *format)
1180{
1181 int ret;
1182 int width = format->fmt.pix.width;
1183 int height = format->fmt.pix.height;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001184
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001185 /* If they are demanding a format other than the one we support,
1186 bail out (tvtime asks for UYVY and then retries with YUYV) */
Devin Heitmueller62899a22009-03-15 18:48:52 -03001187 if (format->fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001188 return -EINVAL;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001189
1190 /* format->fmt.pix.width only support 720 and height 480 */
Devin Heitmueller62899a22009-03-15 18:48:52 -03001191 if (width != 720)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001192 width = 720;
Devin Heitmueller62899a22009-03-15 18:48:52 -03001193 if (height != 480)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001194 height = 480;
1195
1196 format->fmt.pix.width = width;
1197 format->fmt.pix.height = height;
1198 format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
1199 format->fmt.pix.bytesperline = width * 2;
1200 format->fmt.pix.sizeimage = width * height * 2;
1201 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1202 format->fmt.pix.field = V4L2_FIELD_INTERLACED;
Hans Verkuil8d86e4e2013-03-11 17:48:34 -03001203 format->fmt.pix.priv = 0;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001204
Devin Heitmueller62899a22009-03-15 18:48:52 -03001205 if (cmd == VIDIOC_TRY_FMT)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001206 return 0;
1207
1208 /* maybe set new image format, driver current only support 720*480 */
1209 dev->width = width;
1210 dev->height = height;
1211 dev->frame_size = width * height * 2;
1212 dev->field_size = width * height;
1213 dev->bytesperline = width * 2;
1214
Devin Heitmueller62899a22009-03-15 18:48:52 -03001215 if (dev->stream_state == STREAM_ON) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001216 dprintk(1, "VIDIOC_SET_FMT: interrupting stream!\n");
Devin Heitmueller62899a22009-03-15 18:48:52 -03001217 ret = au0828_stream_interrupt(dev);
1218 if (ret != 0) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001219 dprintk(1, "error interrupting video stream!\n");
1220 return ret;
1221 }
1222 }
1223
1224 /* set au0828 interface0 to AS5 here again */
1225 ret = usb_set_interface(dev->usbdev, 0, 5);
Devin Heitmueller62899a22009-03-15 18:48:52 -03001226 if (ret < 0) {
1227 printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001228 return -EBUSY;
1229 }
1230
1231 au0828_analog_stream_enable(dev);
1232
1233 return 0;
1234}
1235
1236
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001237static int vidioc_querycap(struct file *file, void *priv,
1238 struct v4l2_capability *cap)
1239{
Hans Verkuil59e05482013-02-15 08:11:04 -03001240 struct video_device *vdev = video_devdata(file);
1241 struct au0828_fh *fh = priv;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001242 struct au0828_dev *dev = fh->dev;
1243
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001244 strlcpy(cap->driver, "au0828", sizeof(cap->driver));
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001245 strlcpy(cap->card, dev->board.name, sizeof(cap->card));
Hans Verkuil59e05482013-02-15 08:11:04 -03001246 usb_make_path(dev->usbdev, cap->bus_info, sizeof(cap->bus_info));
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001247
Hans Verkuil59e05482013-02-15 08:11:04 -03001248 /* set the device capabilities */
1249 cap->device_caps = V4L2_CAP_AUDIO |
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001250 V4L2_CAP_READWRITE |
1251 V4L2_CAP_STREAMING |
1252 V4L2_CAP_TUNER;
Hans Verkuil59e05482013-02-15 08:11:04 -03001253 if (vdev->vfl_type == VFL_TYPE_GRABBER)
1254 cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE;
1255 else
1256 cap->device_caps |= V4L2_CAP_VBI_CAPTURE;
1257 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS |
1258 V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001259 return 0;
1260}
1261
1262static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
1263 struct v4l2_fmtdesc *f)
1264{
Devin Heitmueller62899a22009-03-15 18:48:52 -03001265 if (f->index)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001266 return -EINVAL;
1267
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001268 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1269 strcpy(f->description, "Packed YUV2");
1270
1271 f->flags = 0;
1272 f->pixelformat = V4L2_PIX_FMT_UYVY;
1273
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001274 return 0;
1275}
1276
1277static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
1278 struct v4l2_format *f)
1279{
1280 struct au0828_fh *fh = priv;
1281 struct au0828_dev *dev = fh->dev;
1282
1283 f->fmt.pix.width = dev->width;
1284 f->fmt.pix.height = dev->height;
1285 f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
1286 f->fmt.pix.bytesperline = dev->bytesperline;
1287 f->fmt.pix.sizeimage = dev->frame_size;
1288 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* NTSC/PAL */
1289 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
Hans Verkuil8d86e4e2013-03-11 17:48:34 -03001290 f->fmt.pix.priv = 0;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001291 return 0;
1292}
1293
1294static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
1295 struct v4l2_format *f)
1296{
1297 struct au0828_fh *fh = priv;
1298 struct au0828_dev *dev = fh->dev;
1299
1300 return au0828_set_format(dev, VIDIOC_TRY_FMT, f);
1301}
1302
1303static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1304 struct v4l2_format *f)
1305{
1306 struct au0828_fh *fh = priv;
1307 struct au0828_dev *dev = fh->dev;
1308 int rc;
1309
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001310 rc = check_dev(dev);
1311 if (rc < 0)
1312 return rc;
1313
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001314 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
Devin Heitmueller62899a22009-03-15 18:48:52 -03001315 printk(KERN_INFO "%s queue busy\n", __func__);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001316 rc = -EBUSY;
1317 goto out;
1318 }
1319
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001320 rc = au0828_set_format(dev, VIDIOC_S_FMT, f);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001321out:
1322 return rc;
1323}
1324
Hans Verkuil314527a2013-03-15 06:10:40 -03001325static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001326{
1327 struct au0828_fh *fh = priv;
1328 struct au0828_dev *dev = fh->dev;
1329
Devin Heitmuellere58071f2012-08-06 22:47:12 -03001330 if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
1331 dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 1);
1332
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001333 /* FIXME: when we support something other than NTSC, we are going to
1334 have to make the au0828 bridge adjust the size of its capture
1335 buffer, which is currently hardcoded at 720x480 */
1336
Hans Verkuil314527a2013-03-15 06:10:40 -03001337 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, norm);
Devin Heitmuellerc98bc032012-08-06 22:46:59 -03001338 dev->std_set_in_tuner_core = 1;
Devin Heitmuellere58071f2012-08-06 22:47:12 -03001339
1340 if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
1341 dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 0);
Hans Verkuil33b6b892013-02-15 09:22:37 -03001342 dev->std = norm;
Devin Heitmuellere58071f2012-08-06 22:47:12 -03001343
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001344 return 0;
1345}
1346
Hans Verkuil33b6b892013-02-15 09:22:37 -03001347static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
1348{
1349 struct au0828_fh *fh = priv;
1350 struct au0828_dev *dev = fh->dev;
1351
1352 *norm = dev->std;
1353 return 0;
1354}
1355
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001356static int vidioc_enum_input(struct file *file, void *priv,
1357 struct v4l2_input *input)
1358{
1359 struct au0828_fh *fh = priv;
1360 struct au0828_dev *dev = fh->dev;
1361 unsigned int tmp;
1362
1363 static const char *inames[] = {
Devin Heitmueller3d622872009-03-15 17:48:26 -03001364 [AU0828_VMUX_UNDEFINED] = "Undefined",
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001365 [AU0828_VMUX_COMPOSITE] = "Composite",
1366 [AU0828_VMUX_SVIDEO] = "S-Video",
1367 [AU0828_VMUX_CABLE] = "Cable TV",
1368 [AU0828_VMUX_TELEVISION] = "Television",
1369 [AU0828_VMUX_DVB] = "DVB",
1370 [AU0828_VMUX_DEBUG] = "tv debug"
1371 };
1372
1373 tmp = input->index;
1374
Dan Carpenterf5e20c32010-03-28 08:21:18 -03001375 if (tmp >= AU0828_MAX_INPUT)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001376 return -EINVAL;
Devin Heitmueller62899a22009-03-15 18:48:52 -03001377 if (AUVI_INPUT(tmp).type == 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001378 return -EINVAL;
1379
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001380 input->index = tmp;
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001381 strcpy(input->name, inames[AUVI_INPUT(tmp).type]);
Devin Heitmueller62899a22009-03-15 18:48:52 -03001382 if ((AUVI_INPUT(tmp).type == AU0828_VMUX_TELEVISION) ||
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001383 (AUVI_INPUT(tmp).type == AU0828_VMUX_CABLE)) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001384 input->type |= V4L2_INPUT_TYPE_TUNER;
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001385 input->audioset = 1;
1386 } else {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001387 input->type |= V4L2_INPUT_TYPE_CAMERA;
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001388 input->audioset = 2;
1389 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001390
1391 input->std = dev->vdev->tvnorms;
1392
1393 return 0;
1394}
1395
1396static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1397{
1398 struct au0828_fh *fh = priv;
1399 struct au0828_dev *dev = fh->dev;
1400 *i = dev->ctrl_input;
1401 return 0;
1402}
1403
1404static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
1405{
1406 struct au0828_fh *fh = priv;
1407 struct au0828_dev *dev = fh->dev;
1408 int i;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001409
Devin Heitmueller62899a22009-03-15 18:48:52 -03001410 dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __func__,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001411 index);
Devin Heitmueller62899a22009-03-15 18:48:52 -03001412 if (index >= AU0828_MAX_INPUT)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001413 return -EINVAL;
Devin Heitmueller62899a22009-03-15 18:48:52 -03001414 if (AUVI_INPUT(index).type == 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001415 return -EINVAL;
1416 dev->ctrl_input = index;
1417
Devin Heitmueller62899a22009-03-15 18:48:52 -03001418 switch (AUVI_INPUT(index).type) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001419 case AU0828_VMUX_SVIDEO:
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001420 dev->input_type = AU0828_VMUX_SVIDEO;
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001421 dev->ctrl_ainput = 1;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001422 break;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001423 case AU0828_VMUX_COMPOSITE:
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001424 dev->input_type = AU0828_VMUX_COMPOSITE;
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001425 dev->ctrl_ainput = 1;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001426 break;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001427 case AU0828_VMUX_TELEVISION:
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001428 dev->input_type = AU0828_VMUX_TELEVISION;
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001429 dev->ctrl_ainput = 0;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001430 break;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001431 default:
Devin Heitmuellera1094c42009-03-15 17:43:13 -03001432 dprintk(1, "VIDIOC_S_INPUT unknown input type set [%d]\n",
1433 AUVI_INPUT(index).type);
1434 break;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001435 }
1436
Hans Verkuil5325b422009-04-02 11:26:22 -03001437 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
1438 AUVI_INPUT(index).vmux, 0, 0);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001439
1440 for (i = 0; i < AU0828_MAX_INPUT; i++) {
1441 int enable = 0;
Devin Heitmueller62899a22009-03-15 18:48:52 -03001442 if (AUVI_INPUT(i).audio_setup == NULL)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001443 continue;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001444
1445 if (i == index)
1446 enable = 1;
1447 else
1448 enable = 0;
1449 if (enable) {
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001450 (AUVI_INPUT(i).audio_setup)(dev, enable);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001451 } else {
1452 /* Make sure we leave it turned on if some
1453 other input is routed to this callback */
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001454 if ((AUVI_INPUT(i).audio_setup) !=
1455 ((AUVI_INPUT(index).audio_setup))) {
1456 (AUVI_INPUT(i).audio_setup)(dev, enable);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001457 }
1458 }
1459 }
1460
Hans Verkuil5325b422009-04-02 11:26:22 -03001461 v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
1462 AUVI_INPUT(index).amux, 0, 0);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001463 return 0;
1464}
1465
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001466static int vidioc_enumaudio(struct file *file, void *priv, struct v4l2_audio *a)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001467{
Devin Heitmueller62899a22009-03-15 18:48:52 -03001468 if (a->index > 1)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001469 return -EINVAL;
1470
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001471 if (a->index == 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001472 strcpy(a->name, "Television");
1473 else
1474 strcpy(a->name, "Line in");
1475
1476 a->capability = V4L2_AUDCAP_STEREO;
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001477 return 0;
1478}
1479
1480static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
1481{
1482 struct au0828_fh *fh = priv;
1483 struct au0828_dev *dev = fh->dev;
1484
1485 a->index = dev->ctrl_ainput;
1486 if (a->index == 0)
1487 strcpy(a->name, "Television");
1488 else
1489 strcpy(a->name, "Line in");
1490
1491 a->capability = V4L2_AUDCAP_STEREO;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001492 return 0;
1493}
1494
Hans Verkuil0e8025b92012-09-04 11:59:31 -03001495static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001496{
1497 struct au0828_fh *fh = priv;
1498 struct au0828_dev *dev = fh->dev;
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001499
Devin Heitmueller62899a22009-03-15 18:48:52 -03001500 if (a->index != dev->ctrl_ainput)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001501 return -EINVAL;
1502 return 0;
1503}
1504
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001505static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1506{
1507 struct au0828_fh *fh = priv;
1508 struct au0828_dev *dev = fh->dev;
1509
Devin Heitmueller62899a22009-03-15 18:48:52 -03001510 if (t->index != 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001511 return -EINVAL;
1512
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001513 strcpy(t->name, "Auvitek tuner");
Devin Heitmueller2689d3d2009-03-15 20:01:53 -03001514 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001515 return 0;
1516}
1517
1518static int vidioc_s_tuner(struct file *file, void *priv,
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001519 const struct v4l2_tuner *t)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001520{
1521 struct au0828_fh *fh = priv;
1522 struct au0828_dev *dev = fh->dev;
1523
Devin Heitmueller62899a22009-03-15 18:48:52 -03001524 if (t->index != 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001525 return -EINVAL;
1526
Devin Heitmuellere58071f2012-08-06 22:47:12 -03001527 if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
1528 dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 1);
1529
Devin Heitmueller2689d3d2009-03-15 20:01:53 -03001530 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
Devin Heitmuellere58071f2012-08-06 22:47:12 -03001531
1532 if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
1533 dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 0);
1534
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001535 dprintk(1, "VIDIOC_S_TUNER: signal = %x, afc = %x\n", t->signal,
1536 t->afc);
Devin Heitmuellere58071f2012-08-06 22:47:12 -03001537
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001538 return 0;
1539
1540}
1541
1542static int vidioc_g_frequency(struct file *file, void *priv,
1543 struct v4l2_frequency *freq)
1544{
1545 struct au0828_fh *fh = priv;
1546 struct au0828_dev *dev = fh->dev;
Devin Heitmuellerc8889232009-03-15 17:38:47 -03001547
Hans Verkuile1cf6582013-03-22 13:32:20 -03001548 if (freq->tuner != 0)
1549 return -EINVAL;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001550 freq->frequency = dev->ctrl_freq;
1551 return 0;
1552}
1553
1554static int vidioc_s_frequency(struct file *file, void *priv,
Hans Verkuilb530a442013-03-19 04:09:26 -03001555 const struct v4l2_frequency *freq)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001556{
1557 struct au0828_fh *fh = priv;
1558 struct au0828_dev *dev = fh->dev;
Hans Verkuile1cf6582013-03-22 13:32:20 -03001559 struct v4l2_frequency new_freq = *freq;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001560
Devin Heitmueller62899a22009-03-15 18:48:52 -03001561 if (freq->tuner != 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001562 return -EINVAL;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001563
Devin Heitmueller4a03daf2012-08-06 22:47:02 -03001564 if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
1565 dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 1);
1566
Devin Heitmuellerc98bc032012-08-06 22:46:59 -03001567 if (dev->std_set_in_tuner_core == 0) {
Hans Verkuil38823b22013-02-15 08:28:27 -03001568 /* If we've never sent the standard in tuner core, do so now.
1569 We don't do this at device probe because we don't want to
1570 incur the cost of a firmware load */
1571 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std,
1572 dev->vdev->tvnorms);
1573 dev->std_set_in_tuner_core = 1;
Devin Heitmuellerc98bc032012-08-06 22:46:59 -03001574 }
1575
Devin Heitmueller2689d3d2009-03-15 20:01:53 -03001576 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, freq);
Hans Verkuile1cf6582013-03-22 13:32:20 -03001577 /* Get the actual set (and possibly clamped) frequency */
1578 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, &new_freq);
1579 dev->ctrl_freq = new_freq.frequency;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001580
Devin Heitmueller4a03daf2012-08-06 22:47:02 -03001581 if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
1582 dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, 0);
1583
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001584 au0828_analog_stream_reset(dev);
1585
1586 return 0;
1587}
1588
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001589
1590/* RAW VBI ioctls */
1591
1592static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
1593 struct v4l2_format *format)
1594{
1595 struct au0828_fh *fh = priv;
1596 struct au0828_dev *dev = fh->dev;
1597
1598 format->fmt.vbi.samples_per_line = dev->vbi_width;
1599 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1600 format->fmt.vbi.offset = 0;
1601 format->fmt.vbi.flags = 0;
1602 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
1603
1604 format->fmt.vbi.count[0] = dev->vbi_height;
1605 format->fmt.vbi.count[1] = dev->vbi_height;
1606 format->fmt.vbi.start[0] = 21;
1607 format->fmt.vbi.start[1] = 284;
Hans Verkuil8d86e4e2013-03-11 17:48:34 -03001608 memset(format->fmt.vbi.reserved, 0, sizeof(format->fmt.vbi.reserved));
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001609
1610 return 0;
1611}
1612
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001613static int vidioc_g_chip_ident(struct file *file, void *priv,
1614 struct v4l2_dbg_chip_ident *chip)
1615{
1616 struct au0828_fh *fh = priv;
1617 struct au0828_dev *dev = fh->dev;
1618 chip->ident = V4L2_IDENT_NONE;
1619 chip->revision = 0;
1620
Devin Heitmuellerd9109be2009-03-11 03:00:58 -03001621 if (v4l2_chip_match_host(&chip->match)) {
1622 chip->ident = V4L2_IDENT_AU0828;
1623 return 0;
1624 }
1625
Devin Heitmueller2689d3d2009-03-15 20:01:53 -03001626 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
Devin Heitmuellerd9109be2009-03-11 03:00:58 -03001627 if (chip->ident == V4L2_IDENT_NONE)
1628 return -EINVAL;
1629
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001630 return 0;
1631}
1632
1633static int vidioc_cropcap(struct file *file, void *priv,
1634 struct v4l2_cropcap *cc)
1635{
1636 struct au0828_fh *fh = priv;
1637 struct au0828_dev *dev = fh->dev;
1638
Devin Heitmueller62899a22009-03-15 18:48:52 -03001639 if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001640 return -EINVAL;
1641
1642 cc->bounds.left = 0;
1643 cc->bounds.top = 0;
1644 cc->bounds.width = dev->width;
1645 cc->bounds.height = dev->height;
1646
1647 cc->defrect = cc->bounds;
1648
1649 cc->pixelaspect.numerator = 54;
1650 cc->pixelaspect.denominator = 59;
1651
1652 return 0;
1653}
1654
1655static int vidioc_streamon(struct file *file, void *priv,
1656 enum v4l2_buf_type type)
1657{
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001658 struct au0828_fh *fh = priv;
1659 struct au0828_dev *dev = fh->dev;
1660 int rc = -EINVAL;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001661
1662 rc = check_dev(dev);
1663 if (rc < 0)
1664 return rc;
1665
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001666 if (unlikely(type != fh->type))
1667 return -EINVAL;
1668
1669 dprintk(1, "vidioc_streamon fh=%p t=%d fh->res=%d dev->res=%d\n",
1670 fh, type, fh->resources, dev->resources);
1671
1672 if (unlikely(!res_get(fh, get_ressource(fh))))
1673 return -EBUSY;
1674
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001675 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1676 au0828_analog_stream_enable(dev);
Devin Heitmueller2689d3d2009-03-15 20:01:53 -03001677 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001678 }
1679
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001680 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001681 rc = videobuf_streamon(&fh->vb_vidq);
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001682 dev->vid_timeout_running = 1;
1683 mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
1684 } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001685 rc = videobuf_streamon(&fh->vb_vbiq);
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001686 dev->vbi_timeout_running = 1;
1687 mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
1688 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001689
1690 return rc;
1691}
1692
1693static int vidioc_streamoff(struct file *file, void *priv,
1694 enum v4l2_buf_type type)
1695{
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001696 struct au0828_fh *fh = priv;
1697 struct au0828_dev *dev = fh->dev;
1698 int rc;
1699 int i;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001700
1701 rc = check_dev(dev);
1702 if (rc < 0)
1703 return rc;
1704
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001705 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1706 fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001707 return -EINVAL;
1708 if (type != fh->type)
1709 return -EINVAL;
1710
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001711 dprintk(1, "vidioc_streamoff fh=%p t=%d fh->res=%d dev->res=%d\n",
1712 fh, type, fh->resources, dev->resources);
1713
1714 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001715 dev->vid_timeout_running = 0;
1716 del_timer_sync(&dev->vid_timeout);
1717
Devin Heitmueller2689d3d2009-03-15 20:01:53 -03001718 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001719 rc = au0828_stream_interrupt(dev);
1720 if (rc != 0)
1721 return rc;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001722
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001723 for (i = 0; i < AU0828_MAX_INPUT; i++) {
1724 if (AUVI_INPUT(i).audio_setup == NULL)
1725 continue;
1726 (AUVI_INPUT(i).audio_setup)(dev, 0);
1727 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001728
Devin Heitmuellera595c1c2012-08-06 22:47:03 -03001729 if (res_check(fh, AU0828_RESOURCE_VIDEO)) {
1730 videobuf_streamoff(&fh->vb_vidq);
1731 res_free(fh, AU0828_RESOURCE_VIDEO);
1732 }
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001733 } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001734 dev->vbi_timeout_running = 0;
1735 del_timer_sync(&dev->vbi_timeout);
1736
Devin Heitmuellera595c1c2012-08-06 22:47:03 -03001737 if (res_check(fh, AU0828_RESOURCE_VBI)) {
1738 videobuf_streamoff(&fh->vb_vbiq);
1739 res_free(fh, AU0828_RESOURCE_VBI);
1740 }
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001741 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001742
1743 return 0;
1744}
1745
Mauro Carvalho Chehab80c6e352009-03-19 19:26:23 -03001746#ifdef CONFIG_VIDEO_ADV_DEBUG
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001747static int vidioc_g_register(struct file *file, void *priv,
1748 struct v4l2_dbg_register *reg)
1749{
1750 struct au0828_fh *fh = priv;
1751 struct au0828_dev *dev = fh->dev;
1752
1753 switch (reg->match.type) {
1754 case V4L2_CHIP_MATCH_I2C_DRIVER:
Devin Heitmueller2689d3d2009-03-15 20:01:53 -03001755 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001756 return 0;
1757 default:
Devin Heitmueller364d2db2012-08-06 22:46:54 -03001758 if (!v4l2_chip_match_host(&reg->match))
1759 return -EINVAL;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001760 }
Devin Heitmueller364d2db2012-08-06 22:46:54 -03001761
1762 reg->val = au0828_read(dev, reg->reg);
1763 return 0;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001764}
1765
1766static int vidioc_s_register(struct file *file, void *priv,
Hans Verkuil977ba3b2013-03-24 08:28:46 -03001767 const struct v4l2_dbg_register *reg)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001768{
1769 struct au0828_fh *fh = priv;
1770 struct au0828_dev *dev = fh->dev;
1771
1772 switch (reg->match.type) {
1773 case V4L2_CHIP_MATCH_I2C_DRIVER:
Devin Heitmueller2689d3d2009-03-15 20:01:53 -03001774 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001775 return 0;
1776 default:
Devin Heitmueller364d2db2012-08-06 22:46:54 -03001777 if (!v4l2_chip_match_host(&reg->match))
1778 return -EINVAL;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001779 }
Devin Heitmueller364d2db2012-08-06 22:46:54 -03001780 return au0828_writereg(dev, reg->reg, reg->val);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001781}
Mauro Carvalho Chehab80c6e352009-03-19 19:26:23 -03001782#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001783
Hans Verkuil83b09422013-02-15 09:14:00 -03001784static int vidioc_log_status(struct file *file, void *fh)
1785{
1786 struct video_device *vdev = video_devdata(file);
1787
1788 v4l2_ctrl_log_status(file, fh);
1789 v4l2_device_call_all(vdev->v4l2_dev, 0, core, log_status);
1790 return 0;
1791}
1792
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001793static int vidioc_reqbufs(struct file *file, void *priv,
1794 struct v4l2_requestbuffers *rb)
1795{
1796 struct au0828_fh *fh = priv;
1797 struct au0828_dev *dev = fh->dev;
1798 int rc;
1799
1800 rc = check_dev(dev);
1801 if (rc < 0)
1802 return rc;
1803
Devin Heitmueller54ebb8b2011-01-23 19:12:27 -03001804 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1805 rc = videobuf_reqbufs(&fh->vb_vidq, rb);
1806 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1807 rc = videobuf_reqbufs(&fh->vb_vbiq, rb);
1808
1809 return rc;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001810}
1811
1812static int vidioc_querybuf(struct file *file, void *priv,
1813 struct v4l2_buffer *b)
1814{
1815 struct au0828_fh *fh = priv;
1816 struct au0828_dev *dev = fh->dev;
1817 int rc;
1818
1819 rc = check_dev(dev);
1820 if (rc < 0)
1821 return rc;
1822
Devin Heitmueller54ebb8b2011-01-23 19:12:27 -03001823 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1824 rc = videobuf_querybuf(&fh->vb_vidq, b);
1825 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1826 rc = videobuf_querybuf(&fh->vb_vbiq, b);
1827
1828 return rc;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001829}
1830
1831static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1832{
1833 struct au0828_fh *fh = priv;
1834 struct au0828_dev *dev = fh->dev;
1835 int rc;
1836
1837 rc = check_dev(dev);
1838 if (rc < 0)
1839 return rc;
1840
Devin Heitmueller54ebb8b2011-01-23 19:12:27 -03001841 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1842 rc = videobuf_qbuf(&fh->vb_vidq, b);
1843 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1844 rc = videobuf_qbuf(&fh->vb_vbiq, b);
1845
1846 return rc;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001847}
1848
1849static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1850{
1851 struct au0828_fh *fh = priv;
1852 struct au0828_dev *dev = fh->dev;
1853 int rc;
1854
1855 rc = check_dev(dev);
1856 if (rc < 0)
1857 return rc;
1858
1859 /* Workaround for a bug in the au0828 hardware design that sometimes
1860 results in the colorspace being inverted */
1861 if (dev->greenscreen_detected == 1) {
1862 dprintk(1, "Detected green frame. Resetting stream...\n");
1863 au0828_analog_stream_reset(dev);
1864 dev->greenscreen_detected = 0;
1865 }
1866
Devin Heitmueller54ebb8b2011-01-23 19:12:27 -03001867 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1868 rc = videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
1869 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1870 rc = videobuf_dqbuf(&fh->vb_vbiq, b, file->f_flags & O_NONBLOCK);
1871
1872 return rc;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001873}
1874
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001875static struct v4l2_file_operations au0828_v4l_fops = {
1876 .owner = THIS_MODULE,
1877 .open = au0828_v4l2_open,
1878 .release = au0828_v4l2_close,
1879 .read = au0828_v4l2_read,
1880 .poll = au0828_v4l2_poll,
1881 .mmap = au0828_v4l2_mmap,
Devin Heitmueller549ee4d2012-08-06 22:46:58 -03001882 .unlocked_ioctl = video_ioctl2,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001883};
1884
1885static const struct v4l2_ioctl_ops video_ioctl_ops = {
1886 .vidioc_querycap = vidioc_querycap,
1887 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1888 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1889 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1890 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001891 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Hans Verkuil8d86e4e2013-03-11 17:48:34 -03001892 .vidioc_try_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001893 .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001894 .vidioc_enumaudio = vidioc_enumaudio,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001895 .vidioc_g_audio = vidioc_g_audio,
1896 .vidioc_s_audio = vidioc_s_audio,
1897 .vidioc_cropcap = vidioc_cropcap,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001898 .vidioc_reqbufs = vidioc_reqbufs,
1899 .vidioc_querybuf = vidioc_querybuf,
1900 .vidioc_qbuf = vidioc_qbuf,
1901 .vidioc_dqbuf = vidioc_dqbuf,
1902 .vidioc_s_std = vidioc_s_std,
Hans Verkuil33b6b892013-02-15 09:22:37 -03001903 .vidioc_g_std = vidioc_g_std,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001904 .vidioc_enum_input = vidioc_enum_input,
1905 .vidioc_g_input = vidioc_g_input,
1906 .vidioc_s_input = vidioc_s_input,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001907 .vidioc_streamon = vidioc_streamon,
1908 .vidioc_streamoff = vidioc_streamoff,
1909 .vidioc_g_tuner = vidioc_g_tuner,
1910 .vidioc_s_tuner = vidioc_s_tuner,
1911 .vidioc_g_frequency = vidioc_g_frequency,
1912 .vidioc_s_frequency = vidioc_s_frequency,
1913#ifdef CONFIG_VIDEO_ADV_DEBUG
1914 .vidioc_g_register = vidioc_g_register,
1915 .vidioc_s_register = vidioc_s_register,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001916#endif
Mauro Carvalho Chehab80c6e352009-03-19 19:26:23 -03001917 .vidioc_g_chip_ident = vidioc_g_chip_ident,
Hans Verkuil83b09422013-02-15 09:14:00 -03001918 .vidioc_log_status = vidioc_log_status,
1919 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1920 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001921};
1922
1923static const struct video_device au0828_video_template = {
1924 .fops = &au0828_v4l_fops,
1925 .release = video_device_release,
1926 .ioctl_ops = &video_ioctl_ops,
Devin Heitmueller0ef210712009-03-11 03:00:53 -03001927 .tvnorms = V4L2_STD_NTSC_M,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001928};
1929
1930/**************************************************************************/
1931
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001932int au0828_analog_register(struct au0828_dev *dev,
1933 struct usb_interface *interface)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001934{
1935 int retval = -ENOMEM;
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001936 struct usb_host_interface *iface_desc;
1937 struct usb_endpoint_descriptor *endpoint;
Julia Lawalld63b21b2012-04-22 07:54:42 -03001938 int i, ret;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001939
1940 dprintk(1, "au0828_analog_register called!\n");
1941
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001942 /* set au0828 usb interface0 to as5 */
1943 retval = usb_set_interface(dev->usbdev,
Devin Heitmueller62899a22009-03-15 18:48:52 -03001944 interface->cur_altsetting->desc.bInterfaceNumber, 5);
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001945 if (retval != 0) {
Devin Heitmueller62899a22009-03-15 18:48:52 -03001946 printk(KERN_INFO "Failure setting usb interface0 to as5\n");
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001947 return retval;
1948 }
1949
1950 /* Figure out which endpoint has the isoc interface */
1951 iface_desc = interface->cur_altsetting;
Devin Heitmueller62899a22009-03-15 18:48:52 -03001952 for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001953 endpoint = &iface_desc->endpoint[i].desc;
Devin Heitmueller62899a22009-03-15 18:48:52 -03001954 if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
1955 == USB_DIR_IN) &&
1956 ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
1957 == USB_ENDPOINT_XFER_ISOC)) {
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001958
1959 /* we find our isoc in endpoint */
1960 u16 tmp = le16_to_cpu(endpoint->wMaxPacketSize);
Devin Heitmueller62899a22009-03-15 18:48:52 -03001961 dev->max_pkt_size = (tmp & 0x07ff) *
1962 (((tmp & 0x1800) >> 11) + 1);
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001963 dev->isoc_in_endpointaddr = endpoint->bEndpointAddress;
1964 }
1965 }
Devin Heitmueller62899a22009-03-15 18:48:52 -03001966 if (!(dev->isoc_in_endpointaddr)) {
1967 printk(KERN_INFO "Could not locate isoc endpoint\n");
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001968 kfree(dev);
1969 return -ENODEV;
1970 }
1971
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001972 init_waitqueue_head(&dev->open);
1973 spin_lock_init(&dev->slock);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001974
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001975 /* init video dma queues */
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001976 INIT_LIST_HEAD(&dev->vidq.active);
1977 INIT_LIST_HEAD(&dev->vidq.queued);
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001978 INIT_LIST_HEAD(&dev->vbiq.active);
1979 INIT_LIST_HEAD(&dev->vbiq.queued);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001980
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001981 dev->vid_timeout.function = au0828_vid_buffer_timeout;
1982 dev->vid_timeout.data = (unsigned long) dev;
1983 init_timer(&dev->vid_timeout);
1984
1985 dev->vbi_timeout.function = au0828_vbi_buffer_timeout;
1986 dev->vbi_timeout.data = (unsigned long) dev;
1987 init_timer(&dev->vbi_timeout);
1988
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001989 dev->width = NTSC_STD_W;
1990 dev->height = NTSC_STD_H;
1991 dev->field_size = dev->width * dev->height;
1992 dev->frame_size = dev->field_size << 1;
1993 dev->bytesperline = dev->width << 1;
1994 dev->ctrl_ainput = 0;
Hans Verkuile1cf6582013-03-22 13:32:20 -03001995 dev->ctrl_freq = 960;
Hans Verkuil33b6b892013-02-15 09:22:37 -03001996 dev->std = V4L2_STD_NTSC_M;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001997
1998 /* allocate and fill v4l2 video struct */
1999 dev->vdev = video_device_alloc();
Devin Heitmueller62899a22009-03-15 18:48:52 -03002000 if (NULL == dev->vdev) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002001 dprintk(1, "Can't allocate video_device.\n");
2002 return -ENOMEM;
2003 }
2004
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03002005 /* allocate the VBI struct */
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002006 dev->vbi_dev = video_device_alloc();
Devin Heitmueller62899a22009-03-15 18:48:52 -03002007 if (NULL == dev->vbi_dev) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002008 dprintk(1, "Can't allocate vbi_device.\n");
Julia Lawalld63b21b2012-04-22 07:54:42 -03002009 ret = -ENOMEM;
2010 goto err_vdev;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002011 }
2012
2013 /* Fill the video capture device struct */
2014 *dev->vdev = au0828_video_template;
Hans Verkuile8c26f42013-02-15 08:55:41 -03002015 dev->vdev->v4l2_dev = &dev->v4l2_dev;
Devin Heitmueller549ee4d2012-08-06 22:46:58 -03002016 dev->vdev->lock = &dev->lock;
Hans Verkuil83b09422013-02-15 09:14:00 -03002017 set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev->flags);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002018 strcpy(dev->vdev->name, "au0828a video");
2019
2020 /* Setup the VBI device */
2021 *dev->vbi_dev = au0828_video_template;
Hans Verkuile8c26f42013-02-15 08:55:41 -03002022 dev->vbi_dev->v4l2_dev = &dev->v4l2_dev;
Devin Heitmueller549ee4d2012-08-06 22:46:58 -03002023 dev->vbi_dev->lock = &dev->lock;
Hans Verkuil83b09422013-02-15 09:14:00 -03002024 set_bit(V4L2_FL_USE_FH_PRIO, &dev->vbi_dev->flags);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002025 strcpy(dev->vbi_dev->name, "au0828a vbi");
2026
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002027 /* Register the v4l2 device */
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02002028 video_set_drvdata(dev->vdev, dev);
Devin Heitmueller62899a22009-03-15 18:48:52 -03002029 retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1);
2030 if (retval != 0) {
2031 dprintk(1, "unable to register video device (error = %d).\n",
2032 retval);
Julia Lawalld63b21b2012-04-22 07:54:42 -03002033 ret = -ENODEV;
2034 goto err_vbi_dev;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002035 }
2036
2037 /* Register the vbi device */
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02002038 video_set_drvdata(dev->vbi_dev, dev);
Devin Heitmueller62899a22009-03-15 18:48:52 -03002039 retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1);
2040 if (retval != 0) {
2041 dprintk(1, "unable to register vbi device (error = %d).\n",
2042 retval);
Julia Lawalld63b21b2012-04-22 07:54:42 -03002043 ret = -ENODEV;
2044 goto err_vbi_dev;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002045 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002046
Devin Heitmueller62899a22009-03-15 18:48:52 -03002047 dprintk(1, "%s completed!\n", __func__);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002048
2049 return 0;
Julia Lawalld63b21b2012-04-22 07:54:42 -03002050
2051err_vbi_dev:
2052 video_device_release(dev->vbi_dev);
2053err_vdev:
2054 video_device_release(dev->vdev);
2055 return ret;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002056}
2057