blob: 85d83ca5a4cd04c2d00ee999d28c739e201496af [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/tuner.h>
40#include "au0828.h"
41#include "au0828-reg.h"
42
Devin Heitmueller8b2f0792009-03-11 03:00:40 -030043static DEFINE_MUTEX(au0828_sysfs_lock);
44
Devin Heitmueller8b2f0792009-03-11 03:00:40 -030045/* ------------------------------------------------------------------
46 Videobuf operations
47 ------------------------------------------------------------------*/
48
49static unsigned int isoc_debug;
50module_param(isoc_debug, int, 0644);
51MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
52
53#define au0828_isocdbg(fmt, arg...) \
54do {\
55 if (isoc_debug) { \
56 printk(KERN_INFO "au0828 %s :"fmt, \
57 __func__ , ##arg); \
58 } \
59 } while (0)
60
Hans Verkuilfa09cb92013-03-11 16:10:33 -030061static inline void i2c_gate_ctrl(struct au0828_dev *dev, int val)
62{
63 if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
64 dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, val);
65}
66
Devin Heitmueller8b2f0792009-03-11 03:00:40 -030067static inline void print_err_status(struct au0828_dev *dev,
68 int packet, int status)
69{
70 char *errmsg = "Unknown";
71
72 switch (status) {
73 case -ENOENT:
74 errmsg = "unlinked synchronuously";
75 break;
76 case -ECONNRESET:
77 errmsg = "unlinked asynchronuously";
78 break;
79 case -ENOSR:
80 errmsg = "Buffer error (overrun)";
81 break;
82 case -EPIPE:
83 errmsg = "Stalled (device not responding)";
84 break;
85 case -EOVERFLOW:
86 errmsg = "Babble (bad cable?)";
87 break;
88 case -EPROTO:
89 errmsg = "Bit-stuff error (bad cable?)";
90 break;
91 case -EILSEQ:
92 errmsg = "CRC/Timeout (could be anything)";
93 break;
94 case -ETIME:
95 errmsg = "Device does not respond";
96 break;
97 }
98 if (packet < 0) {
99 au0828_isocdbg("URB status %d [%s].\n", status, errmsg);
100 } else {
101 au0828_isocdbg("URB packet %d, status %d [%s].\n",
102 packet, status, errmsg);
103 }
104}
105
106static int check_dev(struct au0828_dev *dev)
107{
108 if (dev->dev_state & DEV_DISCONNECTED) {
Devin Heitmueller62899a22009-03-15 18:48:52 -0300109 printk(KERN_INFO "v4l2 ioctl: device not present\n");
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300110 return -ENODEV;
111 }
112
113 if (dev->dev_state & DEV_MISCONFIGURED) {
Devin Heitmueller62899a22009-03-15 18:48:52 -0300114 printk(KERN_INFO "v4l2 ioctl: device is misconfigured; "
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300115 "close and open it again\n");
116 return -EIO;
117 }
118 return 0;
119}
120
121/*
122 * IRQ callback, called by URB callback
123 */
124static void au0828_irq_callback(struct urb *urb)
125{
126 struct au0828_dmaqueue *dma_q = urb->context;
127 struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300128 unsigned long flags = 0;
Hans Verkuile92ba282012-05-14 10:17:35 -0300129 int i;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300130
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 */
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300146 spin_lock_irqsave(&dev->slock, flags);
Hans Verkuile92ba282012-05-14 10:17:35 -0300147 dev->isoc_ctl.isoc_copy(dev, urb);
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300148 spin_unlock_irqrestore(&dev->slock, flags);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300149
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 */
Mauro Carvalho Chehaba094ca42012-10-27 14:00:30 -0300167static void au0828_uninit_isoc(struct au0828_dev *dev)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300168{
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]) {
Daniel Mack997ea582010-04-12 13:17:25 +0200184 usb_free_coherent(dev->usbdev,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300185 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 */
Mauro Carvalho Chehaba094ca42012-10-27 14:00:30 -0300206static int 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))
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300209{
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
Daniel Mack997ea582010-04-12 13:17:25 +0200254 dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->usbdev,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300255 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;
Devin Heitmuellerfadadb72009-03-22 23:42:26 -0300274 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300275
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++;
Sakari Ailus8e6057b2012-09-15 15:14:42 -0300313 v4l2_get_timestamp(&buf->vb.ts);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300314
315 dev->isoc_ctl.buf = NULL;
316
317 list_del(&buf->vb.queue);
318 wake_up(&buf->vb.done);
319}
320
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300321static inline void vbi_buffer_filled(struct au0828_dev *dev,
322 struct au0828_dmaqueue *dma_q,
323 struct au0828_buffer *buf)
324{
325 /* Advice that buffer was filled */
326 au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
327
328 buf->vb.state = VIDEOBUF_DONE;
329 buf->vb.field_count++;
Sakari Ailus8e6057b2012-09-15 15:14:42 -0300330 v4l2_get_timestamp(&buf->vb.ts);
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300331
332 dev->isoc_ctl.vbi_buf = NULL;
333
334 list_del(&buf->vb.queue);
335 wake_up(&buf->vb.done);
336}
337
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300338/*
339 * Identify the buffer header type and properly handles
340 */
341static void au0828_copy_video(struct au0828_dev *dev,
342 struct au0828_dmaqueue *dma_q,
343 struct au0828_buffer *buf,
344 unsigned char *p,
345 unsigned char *outp, unsigned long len)
346{
347 void *fieldstart, *startwrite, *startread;
348 int linesdone, currlinedone, offset, lencopy, remain;
349 int bytesperline = dev->width << 1; /* Assumes 16-bit depth @@@@ */
350
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300351 if (len == 0)
352 return;
353
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300354 if (dma_q->pos + len > buf->vb.size)
355 len = buf->vb.size - dma_q->pos;
356
357 startread = p;
358 remain = len;
359
360 /* Interlaces frame */
361 if (buf->top_field)
362 fieldstart = outp;
363 else
364 fieldstart = outp + bytesperline;
365
366 linesdone = dma_q->pos / bytesperline;
367 currlinedone = dma_q->pos % bytesperline;
368 offset = linesdone * bytesperline * 2 + currlinedone;
369 startwrite = fieldstart + offset;
370 lencopy = bytesperline - currlinedone;
371 lencopy = lencopy > remain ? remain : lencopy;
372
373 if ((char *)startwrite + lencopy > (char *)outp + buf->vb.size) {
374 au0828_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
375 ((char *)startwrite + lencopy) -
376 ((char *)outp + buf->vb.size));
377 remain = (char *)outp + buf->vb.size - (char *)startwrite;
378 lencopy = remain;
379 }
380 if (lencopy <= 0)
381 return;
382 memcpy(startwrite, startread, lencopy);
383
384 remain -= lencopy;
385
386 while (remain > 0) {
387 startwrite += lencopy + bytesperline;
388 startread += lencopy;
389 if (bytesperline > remain)
390 lencopy = remain;
391 else
392 lencopy = bytesperline;
393
394 if ((char *)startwrite + lencopy > (char *)outp +
395 buf->vb.size) {
Devin Heitmueller62899a22009-03-15 18:48:52 -0300396 au0828_isocdbg("Overflow %zi bytes past buf end (2)\n",
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300397 ((char *)startwrite + lencopy) -
398 ((char *)outp + buf->vb.size));
399 lencopy = remain = (char *)outp + buf->vb.size -
400 (char *)startwrite;
401 }
402 if (lencopy <= 0)
403 break;
404
405 memcpy(startwrite, startread, lencopy);
406
407 remain -= lencopy;
408 }
409
410 if (offset > 1440) {
411 /* We have enough data to check for greenscreen */
Devin Heitmueller62899a22009-03-15 18:48:52 -0300412 if (outp[0] < 0x60 && outp[1440] < 0x60)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300413 dev->greenscreen_detected = 1;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300414 }
415
416 dma_q->pos += len;
417}
418
419/*
420 * video-buf generic routine to get the next available buffer
421 */
422static inline void get_next_buf(struct au0828_dmaqueue *dma_q,
423 struct au0828_buffer **buf)
424{
425 struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
426
427 if (list_empty(&dma_q->active)) {
428 au0828_isocdbg("No active queue to serve\n");
429 dev->isoc_ctl.buf = NULL;
430 *buf = NULL;
431 return;
432 }
433
434 /* Get the next buffer */
435 *buf = list_entry(dma_q->active.next, struct au0828_buffer, vb.queue);
436 dev->isoc_ctl.buf = *buf;
437
438 return;
439}
440
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300441static void au0828_copy_vbi(struct au0828_dev *dev,
442 struct au0828_dmaqueue *dma_q,
443 struct au0828_buffer *buf,
444 unsigned char *p,
445 unsigned char *outp, unsigned long len)
446{
447 unsigned char *startwrite, *startread;
Dan Carpenterb5f59332010-07-23 07:09:20 -0300448 int bytesperline;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300449 int i, j = 0;
450
451 if (dev == NULL) {
452 au0828_isocdbg("dev is null\n");
453 return;
454 }
455
456 if (dma_q == NULL) {
457 au0828_isocdbg("dma_q is null\n");
458 return;
459 }
460 if (buf == NULL)
461 return;
462 if (p == NULL) {
463 au0828_isocdbg("p is null\n");
464 return;
465 }
466 if (outp == NULL) {
467 au0828_isocdbg("outp is null\n");
468 return;
469 }
470
Dan Carpenterb5f59332010-07-23 07:09:20 -0300471 bytesperline = dev->vbi_width;
472
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300473 if (dma_q->pos + len > buf->vb.size)
474 len = buf->vb.size - dma_q->pos;
475
476 startread = p;
477 startwrite = outp + (dma_q->pos / 2);
478
479 /* Make sure the bottom field populates the second half of the frame */
480 if (buf->top_field == 0)
481 startwrite += bytesperline * dev->vbi_height;
482
483 for (i = 0; i < len; i += 2)
484 startwrite[j++] = startread[i+1];
485
486 dma_q->pos += len;
487}
488
489
490/*
491 * video-buf generic routine to get the next available VBI buffer
492 */
493static inline void vbi_get_next_buf(struct au0828_dmaqueue *dma_q,
494 struct au0828_buffer **buf)
495{
496 struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vbiq);
497 char *outp;
498
499 if (list_empty(&dma_q->active)) {
500 au0828_isocdbg("No active queue to serve\n");
501 dev->isoc_ctl.vbi_buf = NULL;
502 *buf = NULL;
503 return;
504 }
505
506 /* Get the next buffer */
507 *buf = list_entry(dma_q->active.next, struct au0828_buffer, vb.queue);
Lucas De Marchi25985ed2011-03-30 22:57:33 -0300508 /* Cleans up buffer - Useful for testing for frame/URB loss */
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300509 outp = videobuf_to_vmalloc(&(*buf)->vb);
510 memset(outp, 0x00, (*buf)->vb.size);
511
512 dev->isoc_ctl.vbi_buf = *buf;
513
514 return;
515}
516
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300517/*
518 * Controls the isoc copy of each urb packet
519 */
520static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
521{
522 struct au0828_buffer *buf;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300523 struct au0828_buffer *vbi_buf;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300524 struct au0828_dmaqueue *dma_q = urb->context;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300525 struct au0828_dmaqueue *vbi_dma_q = &dev->vbiq;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300526 unsigned char *outp = NULL;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300527 unsigned char *vbioutp = NULL;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300528 int i, len = 0, rc = 1;
529 unsigned char *p;
530 unsigned char fbyte;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300531 unsigned int vbi_field_size;
532 unsigned int remain, lencopy;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300533
534 if (!dev)
535 return 0;
536
537 if ((dev->dev_state & DEV_DISCONNECTED) ||
538 (dev->dev_state & DEV_MISCONFIGURED))
539 return 0;
540
541 if (urb->status < 0) {
542 print_err_status(dev, -1, urb->status);
543 if (urb->status == -ENOENT)
544 return 0;
545 }
546
547 buf = dev->isoc_ctl.buf;
548 if (buf != NULL)
549 outp = videobuf_to_vmalloc(&buf->vb);
550
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300551 vbi_buf = dev->isoc_ctl.vbi_buf;
552 if (vbi_buf != NULL)
553 vbioutp = videobuf_to_vmalloc(&vbi_buf->vb);
554
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300555 for (i = 0; i < urb->number_of_packets; i++) {
556 int status = urb->iso_frame_desc[i].status;
557
558 if (status < 0) {
559 print_err_status(dev, i, status);
560 if (urb->iso_frame_desc[i].status != -EPROTO)
561 continue;
562 }
563
Devin Heitmueller62899a22009-03-15 18:48:52 -0300564 if (urb->iso_frame_desc[i].actual_length <= 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300565 continue;
Devin Heitmueller62899a22009-03-15 18:48:52 -0300566
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300567 if (urb->iso_frame_desc[i].actual_length >
568 dev->max_pkt_size) {
569 au0828_isocdbg("packet bigger than packet size");
570 continue;
571 }
572
573 p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
574 fbyte = p[0];
575 len = urb->iso_frame_desc[i].actual_length - 4;
576 p += 4;
577
578 if (fbyte & 0x80) {
579 len -= 4;
580 p += 4;
581 au0828_isocdbg("Video frame %s\n",
582 (fbyte & 0x40) ? "odd" : "even");
Devin Heitmuellerbde3bb92010-07-05 13:05:16 -0300583 if (fbyte & 0x40) {
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300584 /* VBI */
585 if (vbi_buf != NULL)
586 vbi_buffer_filled(dev,
587 vbi_dma_q,
588 vbi_buf);
589 vbi_get_next_buf(vbi_dma_q, &vbi_buf);
590 if (vbi_buf == NULL)
591 vbioutp = NULL;
592 else
593 vbioutp = videobuf_to_vmalloc(
594 &vbi_buf->vb);
595
596 /* Video */
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300597 if (buf != NULL)
598 buffer_filled(dev, dma_q, buf);
599 get_next_buf(dma_q, &buf);
Devin Heitmueller62899a22009-03-15 18:48:52 -0300600 if (buf == NULL)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300601 outp = NULL;
Devin Heitmueller62899a22009-03-15 18:48:52 -0300602 else
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300603 outp = videobuf_to_vmalloc(&buf->vb);
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300604
605 /* As long as isoc traffic is arriving, keep
606 resetting the timer */
607 if (dev->vid_timeout_running)
608 mod_timer(&dev->vid_timeout,
609 jiffies + (HZ / 10));
610 if (dev->vbi_timeout_running)
611 mod_timer(&dev->vbi_timeout,
612 jiffies + (HZ / 10));
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300613 }
614
615 if (buf != NULL) {
Devin Heitmueller62899a22009-03-15 18:48:52 -0300616 if (fbyte & 0x40)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300617 buf->top_field = 1;
Devin Heitmueller62899a22009-03-15 18:48:52 -0300618 else
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300619 buf->top_field = 0;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300620 }
621
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300622 if (vbi_buf != NULL) {
623 if (fbyte & 0x40)
624 vbi_buf->top_field = 1;
625 else
626 vbi_buf->top_field = 0;
627 }
628
629 dev->vbi_read = 0;
630 vbi_dma_q->pos = 0;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300631 dma_q->pos = 0;
632 }
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300633
634 vbi_field_size = dev->vbi_width * dev->vbi_height * 2;
635 if (dev->vbi_read < vbi_field_size) {
636 remain = vbi_field_size - dev->vbi_read;
637 if (len < remain)
638 lencopy = len;
639 else
640 lencopy = remain;
641
642 if (vbi_buf != NULL)
643 au0828_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
644 vbioutp, len);
645
646 len -= lencopy;
647 p += lencopy;
648 dev->vbi_read += lencopy;
649 }
650
651 if (dev->vbi_read >= vbi_field_size && buf != NULL)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300652 au0828_copy_video(dev, dma_q, buf, p, outp, len);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300653 }
654 return rc;
655}
656
657static int
658buffer_setup(struct videobuf_queue *vq, unsigned int *count,
659 unsigned int *size)
660{
661 struct au0828_fh *fh = vq->priv_data;
662 *size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
663
664 if (0 == *count)
665 *count = AU0828_DEF_BUF;
666
667 if (*count < AU0828_MIN_BUF)
668 *count = AU0828_MIN_BUF;
669 return 0;
670}
671
672/* This is called *without* dev->slock held; please keep it that way */
673static void free_buffer(struct videobuf_queue *vq, struct au0828_buffer *buf)
674{
675 struct au0828_fh *fh = vq->priv_data;
676 struct au0828_dev *dev = fh->dev;
677 unsigned long flags = 0;
678 if (in_interrupt())
679 BUG();
680
681 /* We used to wait for the buffer to finish here, but this didn't work
682 because, as we were keeping the state as VIDEOBUF_QUEUED,
683 videobuf_queue_cancel marked it as finished for us.
684 (Also, it could wedge forever if the hardware was misconfigured.)
685
686 This should be safe; by the time we get here, the buffer isn't
687 queued anymore. If we ever start marking the buffers as
688 VIDEOBUF_ACTIVE, it won't be, though.
689 */
690 spin_lock_irqsave(&dev->slock, flags);
691 if (dev->isoc_ctl.buf == buf)
692 dev->isoc_ctl.buf = NULL;
693 spin_unlock_irqrestore(&dev->slock, flags);
694
695 videobuf_vmalloc_free(&buf->vb);
696 buf->vb.state = VIDEOBUF_NEEDS_INIT;
697}
698
699static int
700buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
701 enum v4l2_field field)
702{
703 struct au0828_fh *fh = vq->priv_data;
704 struct au0828_buffer *buf = container_of(vb, struct au0828_buffer, vb);
705 struct au0828_dev *dev = fh->dev;
706 int rc = 0, urb_init = 0;
707
708 buf->vb.size = (fh->dev->width * fh->dev->height * 16 + 7) >> 3;
709
710 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
711 return -EINVAL;
712
713 buf->vb.width = dev->width;
714 buf->vb.height = dev->height;
715 buf->vb.field = field;
716
717 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
718 rc = videobuf_iolock(vq, &buf->vb, NULL);
719 if (rc < 0) {
Devin Heitmueller62899a22009-03-15 18:48:52 -0300720 printk(KERN_INFO "videobuf_iolock failed\n");
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300721 goto fail;
722 }
723 }
724
725 if (!dev->isoc_ctl.num_bufs)
726 urb_init = 1;
727
728 if (urb_init) {
729 rc = au0828_init_isoc(dev, AU0828_ISO_PACKETS_PER_URB,
730 AU0828_MAX_ISO_BUFS, dev->max_pkt_size,
731 au0828_isoc_copy);
732 if (rc < 0) {
Devin Heitmueller62899a22009-03-15 18:48:52 -0300733 printk(KERN_INFO "au0828_init_isoc failed\n");
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300734 goto fail;
735 }
736 }
737
738 buf->vb.state = VIDEOBUF_PREPARED;
739 return 0;
740
741fail:
742 free_buffer(vq, buf);
743 return rc;
744}
745
746static void
747buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
748{
749 struct au0828_buffer *buf = container_of(vb,
750 struct au0828_buffer,
751 vb);
752 struct au0828_fh *fh = vq->priv_data;
753 struct au0828_dev *dev = fh->dev;
754 struct au0828_dmaqueue *vidq = &dev->vidq;
755
756 buf->vb.state = VIDEOBUF_QUEUED;
757 list_add_tail(&buf->vb.queue, &vidq->active);
758}
759
760static void buffer_release(struct videobuf_queue *vq,
761 struct videobuf_buffer *vb)
762{
763 struct au0828_buffer *buf = container_of(vb,
764 struct au0828_buffer,
765 vb);
766
767 free_buffer(vq, buf);
768}
769
770static struct videobuf_queue_ops au0828_video_qops = {
771 .buf_setup = buffer_setup,
772 .buf_prepare = buffer_prepare,
773 .buf_queue = buffer_queue,
774 .buf_release = buffer_release,
775};
776
777/* ------------------------------------------------------------------
778 V4L2 interface
779 ------------------------------------------------------------------*/
780
781static int au0828_i2s_init(struct au0828_dev *dev)
782{
783 /* Enable i2s mode */
784 au0828_writereg(dev, AU0828_AUDIOCTRL_50C, 0x01);
785 return 0;
786}
787
788/*
789 * Auvitek au0828 analog stream enable
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300790 */
Mauro Carvalho Chehaba094ca42012-10-27 14:00:30 -0300791static int au0828_analog_stream_enable(struct au0828_dev *d)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300792{
Mauro Carvalho Chehab64ea37b2014-06-08 13:54:57 -0300793 struct usb_interface *iface;
794 int ret;
795
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300796 dprintk(1, "au0828_analog_stream_enable called\n");
Mauro Carvalho Chehab64ea37b2014-06-08 13:54:57 -0300797
798 iface = usb_ifnum_to_if(d->usbdev, 0);
799 if (iface && iface->cur_altsetting->desc.bAlternateSetting != 5) {
800 dprintk(1, "Changing intf#0 to alt 5\n");
801 /* set au0828 interface0 to AS5 here again */
802 ret = usb_set_interface(d->usbdev, 0, 5);
803 if (ret < 0) {
804 printk(KERN_INFO "Au0828 can't set alt setting to 5!\n");
805 return -EBUSY;
806 }
807 }
808
809 /* FIXME: size should be calculated using d->width, d->height */
810
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300811 au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
812 au0828_writereg(d, 0x106, 0x00);
813 /* set x position */
814 au0828_writereg(d, 0x110, 0x00);
815 au0828_writereg(d, 0x111, 0x00);
816 au0828_writereg(d, 0x114, 0xa0);
817 au0828_writereg(d, 0x115, 0x05);
818 /* set y position */
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300819 au0828_writereg(d, 0x112, 0x00);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300820 au0828_writereg(d, 0x113, 0x00);
821 au0828_writereg(d, 0x116, 0xf2);
822 au0828_writereg(d, 0x117, 0x00);
823 au0828_writereg(d, AU0828_SENSORCTRL_100, 0xb3);
824
825 return 0;
826}
827
828int au0828_analog_stream_disable(struct au0828_dev *d)
829{
830 dprintk(1, "au0828_analog_stream_disable called\n");
831 au0828_writereg(d, AU0828_SENSORCTRL_100, 0x0);
832 return 0;
833}
834
Mauro Carvalho Chehaba094ca42012-10-27 14:00:30 -0300835static void au0828_analog_stream_reset(struct au0828_dev *dev)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300836{
837 dprintk(1, "au0828_analog_stream_reset called\n");
838 au0828_writereg(dev, AU0828_SENSORCTRL_100, 0x0);
839 mdelay(30);
840 au0828_writereg(dev, AU0828_SENSORCTRL_100, 0xb3);
841}
842
843/*
844 * Some operations needs to stop current streaming
845 */
846static int au0828_stream_interrupt(struct au0828_dev *dev)
847{
848 int ret = 0;
849
850 dev->stream_state = STREAM_INTERRUPT;
Devin Heitmueller62899a22009-03-15 18:48:52 -0300851 if (dev->dev_state == DEV_DISCONNECTED)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300852 return -ENODEV;
Devin Heitmueller62899a22009-03-15 18:48:52 -0300853 else if (ret) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300854 dev->dev_state = DEV_MISCONFIGURED;
Devin Heitmueller62899a22009-03-15 18:48:52 -0300855 dprintk(1, "%s device is misconfigured!\n", __func__);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300856 return ret;
857 }
858 return 0;
859}
860
861/*
862 * au0828_release_resources
863 * unregister v4l2 devices
864 */
865void au0828_analog_unregister(struct au0828_dev *dev)
866{
867 dprintk(1, "au0828_release_resources called\n");
868 mutex_lock(&au0828_sysfs_lock);
869
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -0200870 if (dev->vdev)
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -0300871 video_unregister_device(dev->vdev);
872 if (dev->vbi_dev)
873 video_unregister_device(dev->vbi_dev);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300874
875 mutex_unlock(&au0828_sysfs_lock);
876}
877
878
879/* Usage lock check functions */
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300880static int res_get(struct au0828_fh *fh, unsigned int bit)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300881{
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300882 struct au0828_dev *dev = fh->dev;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300883
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300884 if (fh->resources & bit)
885 /* have it already allocated */
886 return 1;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300887
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300888 /* is it free? */
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300889 if (dev->resources & bit) {
890 /* no, someone else uses it */
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300891 return 0;
892 }
893 /* it's free, grab it */
894 fh->resources |= bit;
895 dev->resources |= bit;
896 dprintk(1, "res: get %d\n", bit);
Devin Heitmueller549ee4d2012-08-06 22:46:58 -0300897
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300898 return 1;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300899}
900
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300901static int res_check(struct au0828_fh *fh, unsigned int bit)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300902{
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300903 return fh->resources & bit;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300904}
905
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300906static int res_locked(struct au0828_dev *dev, unsigned int bit)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300907{
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300908 return dev->resources & bit;
909}
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300910
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300911static void res_free(struct au0828_fh *fh, unsigned int bits)
912{
913 struct au0828_dev *dev = fh->dev;
914
915 BUG_ON((fh->resources & bits) != bits);
916
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300917 fh->resources &= ~bits;
918 dev->resources &= ~bits;
919 dprintk(1, "res: put %d\n", bits);
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300920}
921
922static int get_ressource(struct au0828_fh *fh)
923{
924 switch (fh->type) {
925 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
926 return AU0828_RESOURCE_VIDEO;
927 case V4L2_BUF_TYPE_VBI_CAPTURE:
928 return AU0828_RESOURCE_VBI;
929 default:
930 BUG();
931 return 0;
932 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300933}
934
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300935/* This function ensures that video frames continue to be delivered even if
936 the ITU-656 input isn't receiving any data (thereby preventing applications
937 such as tvtime from hanging) */
Mauro Carvalho Chehaba094ca42012-10-27 14:00:30 -0300938static void au0828_vid_buffer_timeout(unsigned long data)
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300939{
940 struct au0828_dev *dev = (struct au0828_dev *) data;
941 struct au0828_dmaqueue *dma_q = &dev->vidq;
942 struct au0828_buffer *buf;
943 unsigned char *vid_data;
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300944 unsigned long flags = 0;
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300945
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300946 spin_lock_irqsave(&dev->slock, flags);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300947
948 buf = dev->isoc_ctl.buf;
949 if (buf != NULL) {
950 vid_data = videobuf_to_vmalloc(&buf->vb);
951 memset(vid_data, 0x00, buf->vb.size); /* Blank green frame */
952 buffer_filled(dev, dma_q, buf);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300953 }
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300954 get_next_buf(dma_q, &buf);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300955
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300956 if (dev->vid_timeout_running == 1)
957 mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
958
959 spin_unlock_irqrestore(&dev->slock, flags);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300960}
961
Mauro Carvalho Chehaba094ca42012-10-27 14:00:30 -0300962static void au0828_vbi_buffer_timeout(unsigned long data)
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300963{
964 struct au0828_dev *dev = (struct au0828_dev *) data;
965 struct au0828_dmaqueue *dma_q = &dev->vbiq;
966 struct au0828_buffer *buf;
967 unsigned char *vbi_data;
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300968 unsigned long flags = 0;
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300969
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300970 spin_lock_irqsave(&dev->slock, flags);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300971
972 buf = dev->isoc_ctl.vbi_buf;
973 if (buf != NULL) {
974 vbi_data = videobuf_to_vmalloc(&buf->vb);
975 memset(vbi_data, 0x00, buf->vb.size);
976 vbi_buffer_filled(dev, dma_q, buf);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300977 }
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300978 vbi_get_next_buf(dma_q, &buf);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300979
Devin Heitmueller78ca5002010-10-09 14:43:53 -0300980 if (dev->vbi_timeout_running == 1)
981 mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
982 spin_unlock_irqrestore(&dev->slock, flags);
Devin Heitmueller6e04b7b2010-09-01 22:03:43 -0300983}
984
985
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300986static int au0828_v4l2_open(struct file *filp)
987{
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300988 int ret = 0;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300989 struct video_device *vdev = video_devdata(filp);
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -0200990 struct au0828_dev *dev = video_drvdata(filp);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300991 struct au0828_fh *fh;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300992 int type;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -0300993
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -0300994 switch (vdev->vfl_type) {
995 case VFL_TYPE_GRABBER:
996 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
997 break;
998 case VFL_TYPE_VBI:
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -0200999 type = V4L2_BUF_TYPE_VBI_CAPTURE;
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001000 break;
1001 default:
1002 return -EINVAL;
1003 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001004
1005 fh = kzalloc(sizeof(struct au0828_fh), GFP_KERNEL);
Devin Heitmueller62899a22009-03-15 18:48:52 -03001006 if (NULL == fh) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001007 dprintk(1, "Failed allocate au0828_fh struct!\n");
1008 return -ENOMEM;
1009 }
1010
1011 fh->type = type;
1012 fh->dev = dev;
Hans Verkuil83b09422013-02-15 09:14:00 -03001013 v4l2_fh_init(&fh->fh, vdev);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001014 filp->private_data = fh;
1015
Hans Verkuilea86968f2013-03-11 16:22:13 -03001016 if (mutex_lock_interruptible(&dev->lock)) {
1017 kfree(fh);
1018 return -ERESTARTSYS;
1019 }
1020 if (dev->users == 0) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001021 au0828_analog_stream_enable(dev);
1022 au0828_analog_stream_reset(dev);
1023
1024 /* If we were doing ac97 instead of i2s, it would go here...*/
1025 au0828_i2s_init(dev);
1026
1027 dev->stream_state = STREAM_OFF;
1028 dev->dev_state |= DEV_INITIALIZED;
1029 }
1030
1031 dev->users++;
Hans Verkuilea86968f2013-03-11 16:22:13 -03001032 mutex_unlock(&dev->lock);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001033
1034 videobuf_queue_vmalloc_init(&fh->vb_vidq, &au0828_video_qops,
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001035 NULL, &dev->slock,
1036 V4L2_BUF_TYPE_VIDEO_CAPTURE,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001037 V4L2_FIELD_INTERLACED,
Devin Heitmueller549ee4d2012-08-06 22:46:58 -03001038 sizeof(struct au0828_buffer), fh,
1039 &dev->lock);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001040
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001041 /* VBI Setup */
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001042 videobuf_queue_vmalloc_init(&fh->vb_vbiq, &au0828_vbi_qops,
1043 NULL, &dev->slock,
1044 V4L2_BUF_TYPE_VBI_CAPTURE,
1045 V4L2_FIELD_SEQ_TB,
Devin Heitmueller549ee4d2012-08-06 22:46:58 -03001046 sizeof(struct au0828_buffer), fh,
1047 &dev->lock);
Hans Verkuil83b09422013-02-15 09:14:00 -03001048 v4l2_fh_add(&fh->fh);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001049 return ret;
1050}
1051
1052static int au0828_v4l2_close(struct file *filp)
1053{
1054 int ret;
1055 struct au0828_fh *fh = filp->private_data;
1056 struct au0828_dev *dev = fh->dev;
1057
Hans Verkuil83b09422013-02-15 09:14:00 -03001058 v4l2_fh_del(&fh->fh);
1059 v4l2_fh_exit(&fh->fh);
Hans Verkuilea86968f2013-03-11 16:22:13 -03001060 mutex_lock(&dev->lock);
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001061 if (res_check(fh, AU0828_RESOURCE_VIDEO)) {
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001062 /* Cancel timeout thread in case they didn't call streamoff */
1063 dev->vid_timeout_running = 0;
1064 del_timer_sync(&dev->vid_timeout);
1065
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001066 videobuf_stop(&fh->vb_vidq);
1067 res_free(fh, AU0828_RESOURCE_VIDEO);
1068 }
1069
1070 if (res_check(fh, AU0828_RESOURCE_VBI)) {
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001071 /* Cancel timeout thread in case they didn't call streamoff */
1072 dev->vbi_timeout_running = 0;
1073 del_timer_sync(&dev->vbi_timeout);
1074
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001075 videobuf_stop(&fh->vb_vbiq);
1076 res_free(fh, AU0828_RESOURCE_VBI);
1077 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001078
Hans Verkuil823beb72013-03-11 10:16:45 -03001079 if (dev->users == 1 && video_is_registered(video_devdata(filp))) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001080 au0828_analog_stream_disable(dev);
1081
1082 au0828_uninit_isoc(dev);
1083
Devin Heitmuellere4b8bc52009-05-06 20:54:00 -03001084 /* Save some power by putting tuner to sleep */
Laurent Pinchart622b8282009-10-05 10:48:17 -03001085 v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_power, 0);
Hans Verkuilea86968f2013-03-11 16:22:13 -03001086 dev->std_set_in_tuner_core = 0;
Devin Heitmuellere4b8bc52009-05-06 20:54:00 -03001087
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001088 /* When close the device, set the usb intf0 into alt0 to free
1089 USB bandwidth */
1090 ret = usb_set_interface(dev->usbdev, 0, 0);
Devin Heitmueller62899a22009-03-15 18:48:52 -03001091 if (ret < 0)
1092 printk(KERN_INFO "Au0828 can't set alternate to 0!\n");
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001093 }
Hans Verkuilea86968f2013-03-11 16:22:13 -03001094 mutex_unlock(&dev->lock);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001095
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001096 videobuf_mmap_free(&fh->vb_vidq);
1097 videobuf_mmap_free(&fh->vb_vbiq);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001098 kfree(fh);
1099 dev->users--;
1100 wake_up_interruptible_nr(&dev->open, 1);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001101 return 0;
1102}
1103
Hans Verkuilea86968f2013-03-11 16:22:13 -03001104/* Must be called with dev->lock held */
1105static void au0828_init_tuner(struct au0828_dev *dev)
1106{
1107 struct v4l2_frequency f = {
1108 .frequency = dev->ctrl_freq,
1109 .type = V4L2_TUNER_ANALOG_TV,
1110 };
1111
1112 if (dev->std_set_in_tuner_core)
1113 return;
1114 dev->std_set_in_tuner_core = 1;
1115 i2c_gate_ctrl(dev, 1);
1116 /* If we've never sent the standard in tuner core, do so now.
1117 We don't do this at device probe because we don't want to
1118 incur the cost of a firmware load */
Laurent Pinchart8774bed2014-04-28 16:53:01 -03001119 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, dev->std);
Hans Verkuilea86968f2013-03-11 16:22:13 -03001120 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
1121 i2c_gate_ctrl(dev, 0);
1122}
1123
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001124static ssize_t au0828_v4l2_read(struct file *filp, char __user *buf,
1125 size_t count, loff_t *pos)
1126{
1127 struct au0828_fh *fh = filp->private_data;
1128 struct au0828_dev *dev = fh->dev;
1129 int rc;
1130
1131 rc = check_dev(dev);
1132 if (rc < 0)
1133 return rc;
1134
Hans Verkuilea86968f2013-03-11 16:22:13 -03001135 if (mutex_lock_interruptible(&dev->lock))
1136 return -ERESTARTSYS;
1137 au0828_init_tuner(dev);
1138 mutex_unlock(&dev->lock);
1139
Devin Heitmueller62899a22009-03-15 18:48:52 -03001140 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001141 if (res_locked(dev, AU0828_RESOURCE_VIDEO))
1142 return -EBUSY;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001143
1144 return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
1145 filp->f_flags & O_NONBLOCK);
1146 }
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001147
1148 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1149 if (!res_get(fh, AU0828_RESOURCE_VBI))
1150 return -EBUSY;
1151
Devin Heitmuellerbf797162010-10-09 15:09:17 -03001152 if (dev->vbi_timeout_running == 0) {
1153 /* Handle case where caller tries to read without
1154 calling streamon first */
1155 dev->vbi_timeout_running = 1;
1156 mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
1157 }
1158
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001159 return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
1160 filp->f_flags & O_NONBLOCK);
1161 }
1162
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001163 return 0;
1164}
1165
1166static unsigned int au0828_v4l2_poll(struct file *filp, poll_table *wait)
1167{
1168 struct au0828_fh *fh = filp->private_data;
1169 struct au0828_dev *dev = fh->dev;
Hans Verkuil83b09422013-02-15 09:14:00 -03001170 unsigned long req_events = poll_requested_events(wait);
1171 unsigned int res;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001172
Hans Verkuil83b09422013-02-15 09:14:00 -03001173 if (check_dev(dev) < 0)
1174 return POLLERR;
1175
1176 res = v4l2_ctrl_poll(filp, wait);
1177 if (!(req_events & (POLLIN | POLLRDNORM)))
1178 return res;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001179
Hans Verkuilea86968f2013-03-11 16:22:13 -03001180 if (mutex_lock_interruptible(&dev->lock))
1181 return -ERESTARTSYS;
1182 au0828_init_tuner(dev);
1183 mutex_unlock(&dev->lock);
1184
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001185 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1186 if (!res_get(fh, AU0828_RESOURCE_VIDEO))
1187 return POLLERR;
Hans Verkuil83b09422013-02-15 09:14:00 -03001188 return res | videobuf_poll_stream(filp, &fh->vb_vidq, wait);
1189 }
1190 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001191 if (!res_get(fh, AU0828_RESOURCE_VBI))
1192 return POLLERR;
Hans Verkuil83b09422013-02-15 09:14:00 -03001193 return res | videobuf_poll_stream(filp, &fh->vb_vbiq, wait);
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001194 }
Hans Verkuil83b09422013-02-15 09:14:00 -03001195 return POLLERR;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001196}
1197
1198static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
1199{
1200 struct au0828_fh *fh = filp->private_data;
1201 struct au0828_dev *dev = fh->dev;
1202 int rc;
1203
1204 rc = check_dev(dev);
1205 if (rc < 0)
1206 return rc;
1207
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001208 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1209 rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
1210 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1211 rc = videobuf_mmap_mapper(&fh->vb_vbiq, vma);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001212
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001213 return rc;
1214}
1215
1216static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
1217 struct v4l2_format *format)
1218{
1219 int ret;
1220 int width = format->fmt.pix.width;
1221 int height = format->fmt.pix.height;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001222
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001223 /* If they are demanding a format other than the one we support,
1224 bail out (tvtime asks for UYVY and then retries with YUYV) */
Devin Heitmueller62899a22009-03-15 18:48:52 -03001225 if (format->fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001226 return -EINVAL;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001227
1228 /* format->fmt.pix.width only support 720 and height 480 */
Devin Heitmueller62899a22009-03-15 18:48:52 -03001229 if (width != 720)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001230 width = 720;
Devin Heitmueller62899a22009-03-15 18:48:52 -03001231 if (height != 480)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001232 height = 480;
1233
1234 format->fmt.pix.width = width;
1235 format->fmt.pix.height = height;
1236 format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
1237 format->fmt.pix.bytesperline = width * 2;
1238 format->fmt.pix.sizeimage = width * height * 2;
1239 format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1240 format->fmt.pix.field = V4L2_FIELD_INTERLACED;
Hans Verkuil8d86e4e2013-03-11 17:48:34 -03001241 format->fmt.pix.priv = 0;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001242
Devin Heitmueller62899a22009-03-15 18:48:52 -03001243 if (cmd == VIDIOC_TRY_FMT)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001244 return 0;
1245
1246 /* maybe set new image format, driver current only support 720*480 */
1247 dev->width = width;
1248 dev->height = height;
1249 dev->frame_size = width * height * 2;
1250 dev->field_size = width * height;
1251 dev->bytesperline = width * 2;
1252
Devin Heitmueller62899a22009-03-15 18:48:52 -03001253 if (dev->stream_state == STREAM_ON) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001254 dprintk(1, "VIDIOC_SET_FMT: interrupting stream!\n");
Devin Heitmueller62899a22009-03-15 18:48:52 -03001255 ret = au0828_stream_interrupt(dev);
1256 if (ret != 0) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001257 dprintk(1, "error interrupting video stream!\n");
1258 return ret;
1259 }
1260 }
1261
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001262 au0828_analog_stream_enable(dev);
1263
1264 return 0;
1265}
1266
1267
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001268static int vidioc_querycap(struct file *file, void *priv,
1269 struct v4l2_capability *cap)
1270{
Hans Verkuil59e05482013-02-15 08:11:04 -03001271 struct video_device *vdev = video_devdata(file);
1272 struct au0828_fh *fh = priv;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001273 struct au0828_dev *dev = fh->dev;
1274
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001275 strlcpy(cap->driver, "au0828", sizeof(cap->driver));
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001276 strlcpy(cap->card, dev->board.name, sizeof(cap->card));
Hans Verkuil59e05482013-02-15 08:11:04 -03001277 usb_make_path(dev->usbdev, cap->bus_info, sizeof(cap->bus_info));
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001278
Hans Verkuil59e05482013-02-15 08:11:04 -03001279 /* set the device capabilities */
1280 cap->device_caps = V4L2_CAP_AUDIO |
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001281 V4L2_CAP_READWRITE |
1282 V4L2_CAP_STREAMING |
1283 V4L2_CAP_TUNER;
Hans Verkuil59e05482013-02-15 08:11:04 -03001284 if (vdev->vfl_type == VFL_TYPE_GRABBER)
1285 cap->device_caps |= V4L2_CAP_VIDEO_CAPTURE;
1286 else
1287 cap->device_caps |= V4L2_CAP_VBI_CAPTURE;
1288 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS |
1289 V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001290 return 0;
1291}
1292
1293static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
1294 struct v4l2_fmtdesc *f)
1295{
Devin Heitmueller62899a22009-03-15 18:48:52 -03001296 if (f->index)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001297 return -EINVAL;
1298
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001299 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1300 strcpy(f->description, "Packed YUV2");
1301
1302 f->flags = 0;
1303 f->pixelformat = V4L2_PIX_FMT_UYVY;
1304
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001305 return 0;
1306}
1307
1308static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
1309 struct v4l2_format *f)
1310{
1311 struct au0828_fh *fh = priv;
1312 struct au0828_dev *dev = fh->dev;
1313
1314 f->fmt.pix.width = dev->width;
1315 f->fmt.pix.height = dev->height;
1316 f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
1317 f->fmt.pix.bytesperline = dev->bytesperline;
1318 f->fmt.pix.sizeimage = dev->frame_size;
1319 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* NTSC/PAL */
1320 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
Hans Verkuil8d86e4e2013-03-11 17:48:34 -03001321 f->fmt.pix.priv = 0;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001322 return 0;
1323}
1324
1325static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
1326 struct v4l2_format *f)
1327{
1328 struct au0828_fh *fh = priv;
1329 struct au0828_dev *dev = fh->dev;
1330
1331 return au0828_set_format(dev, VIDIOC_TRY_FMT, f);
1332}
1333
1334static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1335 struct v4l2_format *f)
1336{
1337 struct au0828_fh *fh = priv;
1338 struct au0828_dev *dev = fh->dev;
1339 int rc;
1340
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001341 rc = check_dev(dev);
1342 if (rc < 0)
1343 return rc;
1344
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001345 if (videobuf_queue_is_busy(&fh->vb_vidq)) {
Devin Heitmueller62899a22009-03-15 18:48:52 -03001346 printk(KERN_INFO "%s queue busy\n", __func__);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001347 rc = -EBUSY;
1348 goto out;
1349 }
1350
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001351 rc = au0828_set_format(dev, VIDIOC_S_FMT, f);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001352out:
1353 return rc;
1354}
1355
Hans Verkuil314527a2013-03-15 06:10:40 -03001356static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001357{
1358 struct au0828_fh *fh = priv;
1359 struct au0828_dev *dev = fh->dev;
1360
Hans Verkuilea86968f2013-03-11 16:22:13 -03001361 dev->std = norm;
1362
1363 au0828_init_tuner(dev);
1364
Hans Verkuilfa09cb92013-03-11 16:10:33 -03001365 i2c_gate_ctrl(dev, 1);
Devin Heitmuellere58071f2012-08-06 22:47:12 -03001366
Mauro Carvalho Chehabf2fd7ce2014-06-08 13:54:56 -03001367 /*
1368 * FIXME: when we support something other than 60Hz standards,
1369 * we are going to have to make the au0828 bridge adjust the size
1370 * of its capture buffer, which is currently hardcoded at 720x480
1371 */
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001372
Laurent Pinchart8774bed2014-04-28 16:53:01 -03001373 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, norm);
Devin Heitmuellere58071f2012-08-06 22:47:12 -03001374
Hans Verkuilfa09cb92013-03-11 16:10:33 -03001375 i2c_gate_ctrl(dev, 0);
Devin Heitmuellere58071f2012-08-06 22:47:12 -03001376
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001377 return 0;
1378}
1379
Hans Verkuil33b6b892013-02-15 09:22:37 -03001380static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
1381{
1382 struct au0828_fh *fh = priv;
1383 struct au0828_dev *dev = fh->dev;
1384
1385 *norm = dev->std;
1386 return 0;
1387}
1388
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001389static int vidioc_enum_input(struct file *file, void *priv,
1390 struct v4l2_input *input)
1391{
1392 struct au0828_fh *fh = priv;
1393 struct au0828_dev *dev = fh->dev;
1394 unsigned int tmp;
1395
1396 static const char *inames[] = {
Devin Heitmueller3d622872009-03-15 17:48:26 -03001397 [AU0828_VMUX_UNDEFINED] = "Undefined",
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001398 [AU0828_VMUX_COMPOSITE] = "Composite",
1399 [AU0828_VMUX_SVIDEO] = "S-Video",
1400 [AU0828_VMUX_CABLE] = "Cable TV",
1401 [AU0828_VMUX_TELEVISION] = "Television",
1402 [AU0828_VMUX_DVB] = "DVB",
1403 [AU0828_VMUX_DEBUG] = "tv debug"
1404 };
1405
1406 tmp = input->index;
1407
Dan Carpenterf5e20c32010-03-28 08:21:18 -03001408 if (tmp >= AU0828_MAX_INPUT)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001409 return -EINVAL;
Devin Heitmueller62899a22009-03-15 18:48:52 -03001410 if (AUVI_INPUT(tmp).type == 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001411 return -EINVAL;
1412
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001413 input->index = tmp;
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001414 strcpy(input->name, inames[AUVI_INPUT(tmp).type]);
Devin Heitmueller62899a22009-03-15 18:48:52 -03001415 if ((AUVI_INPUT(tmp).type == AU0828_VMUX_TELEVISION) ||
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001416 (AUVI_INPUT(tmp).type == AU0828_VMUX_CABLE)) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001417 input->type |= V4L2_INPUT_TYPE_TUNER;
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001418 input->audioset = 1;
1419 } else {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001420 input->type |= V4L2_INPUT_TYPE_CAMERA;
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001421 input->audioset = 2;
1422 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001423
1424 input->std = dev->vdev->tvnorms;
1425
1426 return 0;
1427}
1428
1429static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
1430{
1431 struct au0828_fh *fh = priv;
1432 struct au0828_dev *dev = fh->dev;
1433 *i = dev->ctrl_input;
1434 return 0;
1435}
1436
Hans Verkuil56230d12013-03-11 16:18:31 -03001437static void au0828_s_input(struct au0828_dev *dev, int index)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001438{
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001439 int i;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001440
Devin Heitmueller62899a22009-03-15 18:48:52 -03001441 switch (AUVI_INPUT(index).type) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001442 case AU0828_VMUX_SVIDEO:
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001443 dev->input_type = AU0828_VMUX_SVIDEO;
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001444 dev->ctrl_ainput = 1;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001445 break;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001446 case AU0828_VMUX_COMPOSITE:
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001447 dev->input_type = AU0828_VMUX_COMPOSITE;
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001448 dev->ctrl_ainput = 1;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001449 break;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001450 case AU0828_VMUX_TELEVISION:
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001451 dev->input_type = AU0828_VMUX_TELEVISION;
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001452 dev->ctrl_ainput = 0;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001453 break;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001454 default:
Hans Verkuil56230d12013-03-11 16:18:31 -03001455 dprintk(1, "unknown input type set [%d]\n",
Devin Heitmuellera1094c42009-03-15 17:43:13 -03001456 AUVI_INPUT(index).type);
1457 break;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001458 }
1459
Hans Verkuil5325b422009-04-02 11:26:22 -03001460 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
1461 AUVI_INPUT(index).vmux, 0, 0);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001462
1463 for (i = 0; i < AU0828_MAX_INPUT; i++) {
1464 int enable = 0;
Devin Heitmueller62899a22009-03-15 18:48:52 -03001465 if (AUVI_INPUT(i).audio_setup == NULL)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001466 continue;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001467
1468 if (i == index)
1469 enable = 1;
1470 else
1471 enable = 0;
1472 if (enable) {
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001473 (AUVI_INPUT(i).audio_setup)(dev, enable);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001474 } else {
1475 /* Make sure we leave it turned on if some
1476 other input is routed to this callback */
Devin Heitmuellerf1add5b2009-03-11 03:00:47 -03001477 if ((AUVI_INPUT(i).audio_setup) !=
1478 ((AUVI_INPUT(index).audio_setup))) {
1479 (AUVI_INPUT(i).audio_setup)(dev, enable);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001480 }
1481 }
1482 }
1483
Hans Verkuil5325b422009-04-02 11:26:22 -03001484 v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
1485 AUVI_INPUT(index).amux, 0, 0);
Hans Verkuil56230d12013-03-11 16:18:31 -03001486}
1487
1488static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
1489{
1490 struct au0828_fh *fh = priv;
1491 struct au0828_dev *dev = fh->dev;
1492
1493 dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __func__,
1494 index);
1495 if (index >= AU0828_MAX_INPUT)
1496 return -EINVAL;
1497 if (AUVI_INPUT(index).type == 0)
1498 return -EINVAL;
1499 dev->ctrl_input = index;
1500 au0828_s_input(dev, index);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001501 return 0;
1502}
1503
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001504static int vidioc_enumaudio(struct file *file, void *priv, struct v4l2_audio *a)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001505{
Devin Heitmueller62899a22009-03-15 18:48:52 -03001506 if (a->index > 1)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001507 return -EINVAL;
1508
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001509 if (a->index == 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001510 strcpy(a->name, "Television");
1511 else
1512 strcpy(a->name, "Line in");
1513
1514 a->capability = V4L2_AUDCAP_STEREO;
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001515 return 0;
1516}
1517
1518static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
1519{
1520 struct au0828_fh *fh = priv;
1521 struct au0828_dev *dev = fh->dev;
1522
1523 a->index = dev->ctrl_ainput;
1524 if (a->index == 0)
1525 strcpy(a->name, "Television");
1526 else
1527 strcpy(a->name, "Line in");
1528
1529 a->capability = V4L2_AUDCAP_STEREO;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001530 return 0;
1531}
1532
Hans Verkuil0e8025b92012-09-04 11:59:31 -03001533static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001534{
1535 struct au0828_fh *fh = priv;
1536 struct au0828_dev *dev = fh->dev;
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001537
Devin Heitmueller62899a22009-03-15 18:48:52 -03001538 if (a->index != dev->ctrl_ainput)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001539 return -EINVAL;
1540 return 0;
1541}
1542
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001543static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1544{
1545 struct au0828_fh *fh = priv;
1546 struct au0828_dev *dev = fh->dev;
1547
Devin Heitmueller62899a22009-03-15 18:48:52 -03001548 if (t->index != 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001549 return -EINVAL;
1550
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001551 strcpy(t->name, "Auvitek tuner");
Hans Verkuilea86968f2013-03-11 16:22:13 -03001552
1553 au0828_init_tuner(dev);
1554 i2c_gate_ctrl(dev, 1);
Devin Heitmueller2689d3d2009-03-15 20:01:53 -03001555 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
Hans Verkuilea86968f2013-03-11 16:22:13 -03001556 i2c_gate_ctrl(dev, 0);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001557 return 0;
1558}
1559
1560static int vidioc_s_tuner(struct file *file, void *priv,
Hans Verkuil2f73c7c2013-03-15 06:10:06 -03001561 const struct v4l2_tuner *t)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001562{
1563 struct au0828_fh *fh = priv;
1564 struct au0828_dev *dev = fh->dev;
1565
Devin Heitmueller62899a22009-03-15 18:48:52 -03001566 if (t->index != 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001567 return -EINVAL;
1568
Hans Verkuilea86968f2013-03-11 16:22:13 -03001569 au0828_init_tuner(dev);
Hans Verkuilfa09cb92013-03-11 16:10:33 -03001570 i2c_gate_ctrl(dev, 1);
Devin Heitmueller2689d3d2009-03-15 20:01:53 -03001571 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
Hans Verkuilfa09cb92013-03-11 16:10:33 -03001572 i2c_gate_ctrl(dev, 0);
Devin Heitmuellere58071f2012-08-06 22:47:12 -03001573
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001574 dprintk(1, "VIDIOC_S_TUNER: signal = %x, afc = %x\n", t->signal,
1575 t->afc);
Devin Heitmuellere58071f2012-08-06 22:47:12 -03001576
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001577 return 0;
1578
1579}
1580
1581static int vidioc_g_frequency(struct file *file, void *priv,
1582 struct v4l2_frequency *freq)
1583{
1584 struct au0828_fh *fh = priv;
1585 struct au0828_dev *dev = fh->dev;
Devin Heitmuellerc8889232009-03-15 17:38:47 -03001586
Hans Verkuile1cf6582013-03-22 13:32:20 -03001587 if (freq->tuner != 0)
1588 return -EINVAL;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001589 freq->frequency = dev->ctrl_freq;
1590 return 0;
1591}
1592
1593static int vidioc_s_frequency(struct file *file, void *priv,
Hans Verkuilb530a442013-03-19 04:09:26 -03001594 const struct v4l2_frequency *freq)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001595{
1596 struct au0828_fh *fh = priv;
1597 struct au0828_dev *dev = fh->dev;
Hans Verkuile1cf6582013-03-22 13:32:20 -03001598 struct v4l2_frequency new_freq = *freq;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001599
Devin Heitmueller62899a22009-03-15 18:48:52 -03001600 if (freq->tuner != 0)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001601 return -EINVAL;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001602
Hans Verkuilea86968f2013-03-11 16:22:13 -03001603 au0828_init_tuner(dev);
Hans Verkuilfa09cb92013-03-11 16:10:33 -03001604 i2c_gate_ctrl(dev, 1);
Devin Heitmueller4a03daf2012-08-06 22:47:02 -03001605
Devin Heitmueller2689d3d2009-03-15 20:01:53 -03001606 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, freq);
Hans Verkuile1cf6582013-03-22 13:32:20 -03001607 /* Get the actual set (and possibly clamped) frequency */
1608 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, &new_freq);
1609 dev->ctrl_freq = new_freq.frequency;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001610
Hans Verkuilfa09cb92013-03-11 16:10:33 -03001611 i2c_gate_ctrl(dev, 0);
Devin Heitmueller4a03daf2012-08-06 22:47:02 -03001612
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001613 au0828_analog_stream_reset(dev);
1614
1615 return 0;
1616}
1617
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001618
1619/* RAW VBI ioctls */
1620
1621static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
1622 struct v4l2_format *format)
1623{
1624 struct au0828_fh *fh = priv;
1625 struct au0828_dev *dev = fh->dev;
1626
1627 format->fmt.vbi.samples_per_line = dev->vbi_width;
1628 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1629 format->fmt.vbi.offset = 0;
1630 format->fmt.vbi.flags = 0;
1631 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
1632
1633 format->fmt.vbi.count[0] = dev->vbi_height;
1634 format->fmt.vbi.count[1] = dev->vbi_height;
1635 format->fmt.vbi.start[0] = 21;
1636 format->fmt.vbi.start[1] = 284;
Hans Verkuil8d86e4e2013-03-11 17:48:34 -03001637 memset(format->fmt.vbi.reserved, 0, sizeof(format->fmt.vbi.reserved));
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001638
1639 return 0;
1640}
1641
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001642static int vidioc_cropcap(struct file *file, void *priv,
1643 struct v4l2_cropcap *cc)
1644{
1645 struct au0828_fh *fh = priv;
1646 struct au0828_dev *dev = fh->dev;
1647
Devin Heitmueller62899a22009-03-15 18:48:52 -03001648 if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001649 return -EINVAL;
1650
1651 cc->bounds.left = 0;
1652 cc->bounds.top = 0;
1653 cc->bounds.width = dev->width;
1654 cc->bounds.height = dev->height;
1655
1656 cc->defrect = cc->bounds;
1657
1658 cc->pixelaspect.numerator = 54;
1659 cc->pixelaspect.denominator = 59;
1660
1661 return 0;
1662}
1663
1664static int vidioc_streamon(struct file *file, void *priv,
1665 enum v4l2_buf_type type)
1666{
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001667 struct au0828_fh *fh = priv;
1668 struct au0828_dev *dev = fh->dev;
1669 int rc = -EINVAL;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001670
1671 rc = check_dev(dev);
1672 if (rc < 0)
1673 return rc;
1674
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001675 if (unlikely(type != fh->type))
1676 return -EINVAL;
1677
1678 dprintk(1, "vidioc_streamon fh=%p t=%d fh->res=%d dev->res=%d\n",
1679 fh, type, fh->resources, dev->resources);
1680
1681 if (unlikely(!res_get(fh, get_ressource(fh))))
1682 return -EBUSY;
1683
Hans Verkuilea86968f2013-03-11 16:22:13 -03001684 au0828_init_tuner(dev);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001685 if (type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1686 au0828_analog_stream_enable(dev);
Devin Heitmueller2689d3d2009-03-15 20:01:53 -03001687 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001688 }
1689
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001690 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001691 rc = videobuf_streamon(&fh->vb_vidq);
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001692 dev->vid_timeout_running = 1;
1693 mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
1694 } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001695 rc = videobuf_streamon(&fh->vb_vbiq);
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001696 dev->vbi_timeout_running = 1;
1697 mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
1698 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001699
1700 return rc;
1701}
1702
1703static int vidioc_streamoff(struct file *file, void *priv,
1704 enum v4l2_buf_type type)
1705{
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001706 struct au0828_fh *fh = priv;
1707 struct au0828_dev *dev = fh->dev;
1708 int rc;
1709 int i;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001710
1711 rc = check_dev(dev);
1712 if (rc < 0)
1713 return rc;
1714
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001715 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1716 fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001717 return -EINVAL;
1718 if (type != fh->type)
1719 return -EINVAL;
1720
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001721 dprintk(1, "vidioc_streamoff fh=%p t=%d fh->res=%d dev->res=%d\n",
1722 fh, type, fh->resources, dev->resources);
1723
1724 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001725 dev->vid_timeout_running = 0;
1726 del_timer_sync(&dev->vid_timeout);
1727
Devin Heitmueller2689d3d2009-03-15 20:01:53 -03001728 v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001729 rc = au0828_stream_interrupt(dev);
1730 if (rc != 0)
1731 return rc;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001732
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001733 for (i = 0; i < AU0828_MAX_INPUT; i++) {
1734 if (AUVI_INPUT(i).audio_setup == NULL)
1735 continue;
1736 (AUVI_INPUT(i).audio_setup)(dev, 0);
1737 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001738
Devin Heitmuellera595c1c2012-08-06 22:47:03 -03001739 if (res_check(fh, AU0828_RESOURCE_VIDEO)) {
1740 videobuf_streamoff(&fh->vb_vidq);
1741 res_free(fh, AU0828_RESOURCE_VIDEO);
1742 }
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001743 } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001744 dev->vbi_timeout_running = 0;
1745 del_timer_sync(&dev->vbi_timeout);
1746
Devin Heitmuellera595c1c2012-08-06 22:47:03 -03001747 if (res_check(fh, AU0828_RESOURCE_VBI)) {
1748 videobuf_streamoff(&fh->vb_vbiq);
1749 res_free(fh, AU0828_RESOURCE_VBI);
1750 }
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001751 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001752
1753 return 0;
1754}
1755
Mauro Carvalho Chehab80c6e352009-03-19 19:26:23 -03001756#ifdef CONFIG_VIDEO_ADV_DEBUG
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001757static int vidioc_g_register(struct file *file, void *priv,
1758 struct v4l2_dbg_register *reg)
1759{
1760 struct au0828_fh *fh = priv;
1761 struct au0828_dev *dev = fh->dev;
1762
Devin Heitmueller364d2db2012-08-06 22:46:54 -03001763 reg->val = au0828_read(dev, reg->reg);
Hans Verkuilead5bc42013-05-29 07:00:03 -03001764 reg->size = 1;
Devin Heitmueller364d2db2012-08-06 22:46:54 -03001765 return 0;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001766}
1767
1768static int vidioc_s_register(struct file *file, void *priv,
Hans Verkuil977ba3b2013-03-24 08:28:46 -03001769 const struct v4l2_dbg_register *reg)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001770{
1771 struct au0828_fh *fh = priv;
1772 struct au0828_dev *dev = fh->dev;
1773
Devin Heitmueller364d2db2012-08-06 22:46:54 -03001774 return au0828_writereg(dev, reg->reg, reg->val);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001775}
Mauro Carvalho Chehab80c6e352009-03-19 19:26:23 -03001776#endif
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001777
Hans Verkuil83b09422013-02-15 09:14:00 -03001778static int vidioc_log_status(struct file *file, void *fh)
1779{
1780 struct video_device *vdev = video_devdata(file);
1781
1782 v4l2_ctrl_log_status(file, fh);
1783 v4l2_device_call_all(vdev->v4l2_dev, 0, core, log_status);
1784 return 0;
1785}
1786
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001787static int vidioc_reqbufs(struct file *file, void *priv,
1788 struct v4l2_requestbuffers *rb)
1789{
1790 struct au0828_fh *fh = priv;
1791 struct au0828_dev *dev = fh->dev;
1792 int rc;
1793
1794 rc = check_dev(dev);
1795 if (rc < 0)
1796 return rc;
1797
Devin Heitmueller54ebb8b2011-01-23 19:12:27 -03001798 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1799 rc = videobuf_reqbufs(&fh->vb_vidq, rb);
1800 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1801 rc = videobuf_reqbufs(&fh->vb_vbiq, rb);
1802
1803 return rc;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001804}
1805
1806static int vidioc_querybuf(struct file *file, void *priv,
1807 struct v4l2_buffer *b)
1808{
1809 struct au0828_fh *fh = priv;
1810 struct au0828_dev *dev = fh->dev;
1811 int rc;
1812
1813 rc = check_dev(dev);
1814 if (rc < 0)
1815 return rc;
1816
Devin Heitmueller54ebb8b2011-01-23 19:12:27 -03001817 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1818 rc = videobuf_querybuf(&fh->vb_vidq, b);
1819 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1820 rc = videobuf_querybuf(&fh->vb_vbiq, b);
1821
1822 return rc;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001823}
1824
1825static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1826{
1827 struct au0828_fh *fh = priv;
1828 struct au0828_dev *dev = fh->dev;
1829 int rc;
1830
1831 rc = check_dev(dev);
1832 if (rc < 0)
1833 return rc;
1834
Devin Heitmueller54ebb8b2011-01-23 19:12:27 -03001835 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1836 rc = videobuf_qbuf(&fh->vb_vidq, b);
1837 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1838 rc = videobuf_qbuf(&fh->vb_vbiq, b);
1839
1840 return rc;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001841}
1842
1843static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1844{
1845 struct au0828_fh *fh = priv;
1846 struct au0828_dev *dev = fh->dev;
1847 int rc;
1848
1849 rc = check_dev(dev);
1850 if (rc < 0)
1851 return rc;
1852
1853 /* Workaround for a bug in the au0828 hardware design that sometimes
1854 results in the colorspace being inverted */
1855 if (dev->greenscreen_detected == 1) {
1856 dprintk(1, "Detected green frame. Resetting stream...\n");
1857 au0828_analog_stream_reset(dev);
1858 dev->greenscreen_detected = 0;
1859 }
1860
Devin Heitmueller54ebb8b2011-01-23 19:12:27 -03001861 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1862 rc = videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK);
1863 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1864 rc = videobuf_dqbuf(&fh->vb_vbiq, b, file->f_flags & O_NONBLOCK);
1865
1866 return rc;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001867}
1868
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001869static struct v4l2_file_operations au0828_v4l_fops = {
1870 .owner = THIS_MODULE,
1871 .open = au0828_v4l2_open,
1872 .release = au0828_v4l2_close,
1873 .read = au0828_v4l2_read,
1874 .poll = au0828_v4l2_poll,
1875 .mmap = au0828_v4l2_mmap,
Devin Heitmueller549ee4d2012-08-06 22:46:58 -03001876 .unlocked_ioctl = video_ioctl2,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001877};
1878
1879static const struct v4l2_ioctl_ops video_ioctl_ops = {
1880 .vidioc_querycap = vidioc_querycap,
1881 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1882 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1883 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1884 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
Devin Heitmueller5a5a4e12009-03-11 03:00:55 -03001885 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Hans Verkuil8d86e4e2013-03-11 17:48:34 -03001886 .vidioc_try_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001887 .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
Hans Verkuila2cf96f2013-02-15 08:41:24 -03001888 .vidioc_enumaudio = vidioc_enumaudio,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001889 .vidioc_g_audio = vidioc_g_audio,
1890 .vidioc_s_audio = vidioc_s_audio,
1891 .vidioc_cropcap = vidioc_cropcap,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001892 .vidioc_reqbufs = vidioc_reqbufs,
1893 .vidioc_querybuf = vidioc_querybuf,
1894 .vidioc_qbuf = vidioc_qbuf,
1895 .vidioc_dqbuf = vidioc_dqbuf,
1896 .vidioc_s_std = vidioc_s_std,
Hans Verkuil33b6b892013-02-15 09:22:37 -03001897 .vidioc_g_std = vidioc_g_std,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001898 .vidioc_enum_input = vidioc_enum_input,
1899 .vidioc_g_input = vidioc_g_input,
1900 .vidioc_s_input = vidioc_s_input,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001901 .vidioc_streamon = vidioc_streamon,
1902 .vidioc_streamoff = vidioc_streamoff,
1903 .vidioc_g_tuner = vidioc_g_tuner,
1904 .vidioc_s_tuner = vidioc_s_tuner,
1905 .vidioc_g_frequency = vidioc_g_frequency,
1906 .vidioc_s_frequency = vidioc_s_frequency,
1907#ifdef CONFIG_VIDEO_ADV_DEBUG
1908 .vidioc_g_register = vidioc_g_register,
1909 .vidioc_s_register = vidioc_s_register,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001910#endif
Hans Verkuil83b09422013-02-15 09:14:00 -03001911 .vidioc_log_status = vidioc_log_status,
1912 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1913 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001914};
1915
1916static const struct video_device au0828_video_template = {
1917 .fops = &au0828_v4l_fops,
1918 .release = video_device_release,
1919 .ioctl_ops = &video_ioctl_ops,
Mauro Carvalho Chehabf2fd7ce2014-06-08 13:54:56 -03001920 .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_M,
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001921};
1922
1923/**************************************************************************/
1924
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001925int au0828_analog_register(struct au0828_dev *dev,
1926 struct usb_interface *interface)
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001927{
1928 int retval = -ENOMEM;
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001929 struct usb_host_interface *iface_desc;
1930 struct usb_endpoint_descriptor *endpoint;
Julia Lawalld63b21b2012-04-22 07:54:42 -03001931 int i, ret;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001932
1933 dprintk(1, "au0828_analog_register called!\n");
1934
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001935 /* set au0828 usb interface0 to as5 */
1936 retval = usb_set_interface(dev->usbdev,
Devin Heitmueller62899a22009-03-15 18:48:52 -03001937 interface->cur_altsetting->desc.bInterfaceNumber, 5);
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001938 if (retval != 0) {
Devin Heitmueller62899a22009-03-15 18:48:52 -03001939 printk(KERN_INFO "Failure setting usb interface0 to as5\n");
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001940 return retval;
1941 }
1942
1943 /* Figure out which endpoint has the isoc interface */
1944 iface_desc = interface->cur_altsetting;
Devin Heitmueller62899a22009-03-15 18:48:52 -03001945 for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001946 endpoint = &iface_desc->endpoint[i].desc;
Devin Heitmueller62899a22009-03-15 18:48:52 -03001947 if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
1948 == USB_DIR_IN) &&
1949 ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
1950 == USB_ENDPOINT_XFER_ISOC)) {
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001951
1952 /* we find our isoc in endpoint */
1953 u16 tmp = le16_to_cpu(endpoint->wMaxPacketSize);
Devin Heitmueller62899a22009-03-15 18:48:52 -03001954 dev->max_pkt_size = (tmp & 0x07ff) *
1955 (((tmp & 0x1800) >> 11) + 1);
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001956 dev->isoc_in_endpointaddr = endpoint->bEndpointAddress;
1957 }
1958 }
Devin Heitmueller62899a22009-03-15 18:48:52 -03001959 if (!(dev->isoc_in_endpointaddr)) {
1960 printk(KERN_INFO "Could not locate isoc endpoint\n");
Devin Heitmuellerfc4ce6c2009-03-11 03:01:00 -03001961 kfree(dev);
1962 return -ENODEV;
1963 }
1964
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001965 init_waitqueue_head(&dev->open);
1966 spin_lock_init(&dev->slock);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001967
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001968 /* init video dma queues */
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001969 INIT_LIST_HEAD(&dev->vidq.active);
1970 INIT_LIST_HEAD(&dev->vidq.queued);
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03001971 INIT_LIST_HEAD(&dev->vbiq.active);
1972 INIT_LIST_HEAD(&dev->vbiq.queued);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001973
Devin Heitmueller78ca5002010-10-09 14:43:53 -03001974 dev->vid_timeout.function = au0828_vid_buffer_timeout;
1975 dev->vid_timeout.data = (unsigned long) dev;
1976 init_timer(&dev->vid_timeout);
1977
1978 dev->vbi_timeout.function = au0828_vbi_buffer_timeout;
1979 dev->vbi_timeout.data = (unsigned long) dev;
1980 init_timer(&dev->vbi_timeout);
1981
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001982 dev->width = NTSC_STD_W;
1983 dev->height = NTSC_STD_H;
1984 dev->field_size = dev->width * dev->height;
1985 dev->frame_size = dev->field_size << 1;
1986 dev->bytesperline = dev->width << 1;
Hans Verkuilde8d2bb2013-03-11 16:12:17 -03001987 dev->vbi_width = 720;
1988 dev->vbi_height = 1;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001989 dev->ctrl_ainput = 0;
Hans Verkuile1cf6582013-03-22 13:32:20 -03001990 dev->ctrl_freq = 960;
Hans Verkuil33b6b892013-02-15 09:22:37 -03001991 dev->std = V4L2_STD_NTSC_M;
Hans Verkuil56230d12013-03-11 16:18:31 -03001992 au0828_s_input(dev, 0);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001993
1994 /* allocate and fill v4l2 video struct */
1995 dev->vdev = video_device_alloc();
Devin Heitmueller62899a22009-03-15 18:48:52 -03001996 if (NULL == dev->vdev) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03001997 dprintk(1, "Can't allocate video_device.\n");
1998 return -ENOMEM;
1999 }
2000
Devin Heitmueller7f8eacd2010-05-29 17:18:45 -03002001 /* allocate the VBI struct */
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002002 dev->vbi_dev = video_device_alloc();
Devin Heitmueller62899a22009-03-15 18:48:52 -03002003 if (NULL == dev->vbi_dev) {
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002004 dprintk(1, "Can't allocate vbi_device.\n");
Julia Lawalld63b21b2012-04-22 07:54:42 -03002005 ret = -ENOMEM;
2006 goto err_vdev;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002007 }
2008
2009 /* Fill the video capture device struct */
2010 *dev->vdev = au0828_video_template;
Hans Verkuile8c26f42013-02-15 08:55:41 -03002011 dev->vdev->v4l2_dev = &dev->v4l2_dev;
Devin Heitmueller549ee4d2012-08-06 22:46:58 -03002012 dev->vdev->lock = &dev->lock;
Hans Verkuil83b09422013-02-15 09:14:00 -03002013 set_bit(V4L2_FL_USE_FH_PRIO, &dev->vdev->flags);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002014 strcpy(dev->vdev->name, "au0828a video");
2015
2016 /* Setup the VBI device */
2017 *dev->vbi_dev = au0828_video_template;
Hans Verkuile8c26f42013-02-15 08:55:41 -03002018 dev->vbi_dev->v4l2_dev = &dev->v4l2_dev;
Devin Heitmueller549ee4d2012-08-06 22:46:58 -03002019 dev->vbi_dev->lock = &dev->lock;
Hans Verkuil83b09422013-02-15 09:14:00 -03002020 set_bit(V4L2_FL_USE_FH_PRIO, &dev->vbi_dev->flags);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002021 strcpy(dev->vbi_dev->name, "au0828a vbi");
2022
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002023 /* Register the v4l2 device */
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02002024 video_set_drvdata(dev->vdev, dev);
Devin Heitmueller62899a22009-03-15 18:48:52 -03002025 retval = video_register_device(dev->vdev, VFL_TYPE_GRABBER, -1);
2026 if (retval != 0) {
2027 dprintk(1, "unable to register video device (error = %d).\n",
2028 retval);
Julia Lawalld63b21b2012-04-22 07:54:42 -03002029 ret = -ENODEV;
2030 goto err_vbi_dev;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002031 }
2032
2033 /* Register the vbi device */
Laurent Pinchart63b0d5a2009-12-10 11:44:04 -02002034 video_set_drvdata(dev->vbi_dev, dev);
Devin Heitmueller62899a22009-03-15 18:48:52 -03002035 retval = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, -1);
2036 if (retval != 0) {
2037 dprintk(1, "unable to register vbi device (error = %d).\n",
2038 retval);
Julia Lawalld63b21b2012-04-22 07:54:42 -03002039 ret = -ENODEV;
2040 goto err_vbi_dev;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002041 }
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002042
Devin Heitmueller62899a22009-03-15 18:48:52 -03002043 dprintk(1, "%s completed!\n", __func__);
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002044
2045 return 0;
Julia Lawalld63b21b2012-04-22 07:54:42 -03002046
2047err_vbi_dev:
2048 video_device_release(dev->vbi_dev);
2049err_vdev:
2050 video_device_release(dev->vdev);
2051 return ret;
Devin Heitmueller8b2f0792009-03-11 03:00:40 -03002052}
2053