^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Auvitek AU0828 USB Bridge (Analog video support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2005-2008 Auvitek International, Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) /* Developer Notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * The hardware scaler supported is unimplemented
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * AC97 audio support is unimplemented (only i2s audio mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "au0828.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "au8522.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <media/v4l2-common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <media/v4l2-mc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <media/v4l2-ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <media/v4l2-event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <media/tuner.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "au0828-reg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static DEFINE_MUTEX(au0828_sysfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) /* ------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) Videobuf operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) ------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static unsigned int isoc_debug;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) module_param(isoc_debug, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) MODULE_PARM_DESC(isoc_debug, "enable debug messages [isoc transfers]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define au0828_isocdbg(fmt, arg...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) do {\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) if (isoc_debug) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) pr_info("au0828 %s :"fmt, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) __func__ , ##arg); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static inline void i2c_gate_ctrl(struct au0828_dev *dev, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) if (dev->dvb.frontend && dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) dev->dvb.frontend->ops.analog_ops.i2c_gate_ctrl(dev->dvb.frontend, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static inline void print_err_status(struct au0828_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) int packet, int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) char *errmsg = "Unknown";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) errmsg = "unlinked synchronously";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) case -ECONNRESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) errmsg = "unlinked asynchronously";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) case -ENOSR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) errmsg = "Buffer error (overrun)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) case -EPIPE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) errmsg = "Stalled (device not responding)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) case -EOVERFLOW:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) errmsg = "Babble (bad cable?)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) case -EPROTO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) errmsg = "Bit-stuff error (bad cable?)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) case -EILSEQ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) errmsg = "CRC/Timeout (could be anything)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) case -ETIME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) errmsg = "Device does not respond";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (packet < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) au0828_isocdbg("URB status %d [%s].\n", status, errmsg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) au0828_isocdbg("URB packet %d, status %d [%s].\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) packet, status, errmsg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static int check_dev(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (test_bit(DEV_DISCONNECTED, &dev->dev_state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) pr_info("v4l2 ioctl: device not present\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) if (test_bit(DEV_MISCONFIGURED, &dev->dev_state)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) pr_info("v4l2 ioctl: device is misconfigured; close and open it again\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * IRQ callback, called by URB callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static void au0828_irq_callback(struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) struct au0828_dmaqueue *dma_q = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) switch (urb->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) case 0: /* success */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) case -ETIMEDOUT: /* NAK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) case -ECONNRESET: /* kill */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) case -ENOENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) case -ESHUTDOWN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) au0828_isocdbg("au0828_irq_callback called: status kill\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) default: /* unknown error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) au0828_isocdbg("urb completion error %d.\n", urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* Copy data from URB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) spin_lock_irqsave(&dev->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) dev->isoc_ctl.isoc_copy(dev, urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) spin_unlock_irqrestore(&dev->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* Reset urb buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) for (i = 0; i < urb->number_of_packets; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) urb->iso_frame_desc[i].status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) urb->iso_frame_desc[i].actual_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) urb->status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) urb->status = usb_submit_urb(urb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) if (urb->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) au0828_isocdbg("urb resubmit failed (error=%i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) dev->stream_state = STREAM_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * Stop and Deallocate URBs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static void au0828_uninit_isoc(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) au0828_isocdbg("au0828: called au0828_uninit_isoc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) dev->isoc_ctl.nfields = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) urb = dev->isoc_ctl.urb[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (!irqs_disabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) usb_kill_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) usb_unlink_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (dev->isoc_ctl.transfer_buffer[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) usb_free_coherent(dev->usbdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) urb->transfer_buffer_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) dev->isoc_ctl.transfer_buffer[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) urb->transfer_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) usb_free_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) dev->isoc_ctl.urb[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) dev->isoc_ctl.transfer_buffer[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) kfree(dev->isoc_ctl.urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) kfree(dev->isoc_ctl.transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) dev->isoc_ctl.urb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) dev->isoc_ctl.transfer_buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) dev->isoc_ctl.num_bufs = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) dev->stream_state = STREAM_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * Allocate URBs and start IRQ
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int au0828_init_isoc(struct au0828_dev *dev, int max_packets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) int num_bufs, int max_pkt_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) int (*isoc_copy) (struct au0828_dev *dev, struct urb *urb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct au0828_dmaqueue *dma_q = &dev->vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) int sb_size, pipe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int j, k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) au0828_isocdbg("au0828: called au0828_prepare_isoc\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) dev->isoc_ctl.isoc_copy = isoc_copy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) dev->isoc_ctl.num_bufs = num_bufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) dev->isoc_ctl.urb = kcalloc(num_bufs, sizeof(void *), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) if (!dev->isoc_ctl.urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) au0828_isocdbg("cannot alloc memory for usb buffers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) dev->isoc_ctl.transfer_buffer = kcalloc(num_bufs, sizeof(void *),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (!dev->isoc_ctl.transfer_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) au0828_isocdbg("cannot allocate memory for usb transfer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) kfree(dev->isoc_ctl.urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) dev->isoc_ctl.max_pkt_size = max_pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) dev->isoc_ctl.buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) sb_size = max_packets * dev->isoc_ctl.max_pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) /* allocate urbs and transfer buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) urb = usb_alloc_urb(max_packets, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (!urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) au0828_uninit_isoc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) dev->isoc_ctl.urb[i] = urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->usbdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) sb_size, GFP_KERNEL, &urb->transfer_dma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) if (!dev->isoc_ctl.transfer_buffer[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) printk("unable to allocate %i bytes for transfer buffer %i%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) sb_size, i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) in_interrupt() ? " while in int" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) au0828_uninit_isoc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) pipe = usb_rcvisocpipe(dev->usbdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) dev->isoc_in_endpointaddr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) usb_fill_int_urb(urb, dev->usbdev, pipe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) dev->isoc_ctl.transfer_buffer[i], sb_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) au0828_irq_callback, dma_q, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) urb->number_of_packets = max_packets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) k = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) for (j = 0; j < max_packets; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) urb->iso_frame_desc[j].offset = k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) urb->iso_frame_desc[j].length =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) dev->isoc_ctl.max_pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) k += dev->isoc_ctl.max_pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /* submit urbs and enables IRQ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) au0828_isocdbg("submit of urb %i failed (error=%i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) i, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) au0828_uninit_isoc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * Announces that a buffer were filled and request the next
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static inline void buffer_filled(struct au0828_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct au0828_dmaqueue *dma_q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct au0828_buffer *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct vb2_v4l2_buffer *vb = &buf->vb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct vb2_queue *q = vb->vb2_buf.vb2_queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /* Advice that buffer was filled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) au0828_isocdbg("[%p/%d] wakeup\n", buf, buf->top_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) if (q->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) vb->sequence = dev->frame_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) vb->sequence = dev->vbi_frame_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) vb->field = V4L2_FIELD_INTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) vb->vb2_buf.timestamp = ktime_get_ns();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) vb2_buffer_done(&vb->vb2_buf, VB2_BUF_STATE_DONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * Identify the buffer header type and properly handles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) static void au0828_copy_video(struct au0828_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) struct au0828_dmaqueue *dma_q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) struct au0828_buffer *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) unsigned char *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) unsigned char *outp, unsigned long len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) void *fieldstart, *startwrite, *startread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) int linesdone, currlinedone, offset, lencopy, remain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) int bytesperline = dev->width << 1; /* Assumes 16-bit depth @@@@ */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (dma_q->pos + len > buf->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) len = buf->length - dma_q->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) startread = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) remain = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* Interlaces frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (buf->top_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) fieldstart = outp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) fieldstart = outp + bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) linesdone = dma_q->pos / bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) currlinedone = dma_q->pos % bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) offset = linesdone * bytesperline * 2 + currlinedone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) startwrite = fieldstart + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) lencopy = bytesperline - currlinedone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) lencopy = lencopy > remain ? remain : lencopy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if ((char *)startwrite + lencopy > (char *)outp + buf->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) au0828_isocdbg("Overflow of %zi bytes past buffer end (1)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) ((char *)startwrite + lencopy) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) ((char *)outp + buf->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) remain = (char *)outp + buf->length - (char *)startwrite;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) lencopy = remain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (lencopy <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) memcpy(startwrite, startread, lencopy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) remain -= lencopy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) while (remain > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) startwrite += lencopy + bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) startread += lencopy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (bytesperline > remain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) lencopy = remain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) lencopy = bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) if ((char *)startwrite + lencopy > (char *)outp +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) buf->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) au0828_isocdbg("Overflow %zi bytes past buf end (2)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) ((char *)startwrite + lencopy) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ((char *)outp + buf->length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) lencopy = remain = (char *)outp + buf->length -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) (char *)startwrite;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (lencopy <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) memcpy(startwrite, startread, lencopy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) remain -= lencopy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) if (offset > 1440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) /* We have enough data to check for greenscreen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (outp[0] < 0x60 && outp[1440] < 0x60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) dev->greenscreen_detected = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) dma_q->pos += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * video-buf generic routine to get the next available buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static inline void get_next_buf(struct au0828_dmaqueue *dma_q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) struct au0828_buffer **buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vidq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (list_empty(&dma_q->active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) au0828_isocdbg("No active queue to serve\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) dev->isoc_ctl.buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) *buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* Get the next buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) *buf = list_entry(dma_q->active.next, struct au0828_buffer, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /* Cleans up buffer - Useful for testing for frame/URB loss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) list_del(&(*buf)->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) dma_q->pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) (*buf)->vb_buf = (*buf)->mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) dev->isoc_ctl.buf = *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static void au0828_copy_vbi(struct au0828_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) struct au0828_dmaqueue *dma_q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) struct au0828_buffer *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) unsigned char *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) unsigned char *outp, unsigned long len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) unsigned char *startwrite, *startread;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) int bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) int i, j = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (dev == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) au0828_isocdbg("dev is null\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (dma_q == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) au0828_isocdbg("dma_q is null\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (p == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) au0828_isocdbg("p is null\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (outp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) au0828_isocdbg("outp is null\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) bytesperline = dev->vbi_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (dma_q->pos + len > buf->length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) len = buf->length - dma_q->pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) startread = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) startwrite = outp + (dma_q->pos / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /* Make sure the bottom field populates the second half of the frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) if (buf->top_field == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) startwrite += bytesperline * dev->vbi_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) for (i = 0; i < len; i += 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) startwrite[j++] = startread[i+1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) dma_q->pos += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * video-buf generic routine to get the next available VBI buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static inline void vbi_get_next_buf(struct au0828_dmaqueue *dma_q,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct au0828_buffer **buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) struct au0828_dev *dev = container_of(dma_q, struct au0828_dev, vbiq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (list_empty(&dma_q->active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) au0828_isocdbg("No active queue to serve\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) dev->isoc_ctl.vbi_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) *buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) /* Get the next buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) *buf = list_entry(dma_q->active.next, struct au0828_buffer, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) /* Cleans up buffer - Useful for testing for frame/URB loss */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) list_del(&(*buf)->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) dma_q->pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) (*buf)->vb_buf = (*buf)->mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) dev->isoc_ctl.vbi_buf = *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * Controls the isoc copy of each urb packet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) static inline int au0828_isoc_copy(struct au0828_dev *dev, struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) struct au0828_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) struct au0828_buffer *vbi_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) struct au0828_dmaqueue *dma_q = urb->context;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct au0828_dmaqueue *vbi_dma_q = &dev->vbiq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) unsigned char *outp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) unsigned char *vbioutp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) int i, len = 0, rc = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) unsigned char *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) unsigned char fbyte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) unsigned int vbi_field_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) unsigned int remain, lencopy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (test_bit(DEV_DISCONNECTED, &dev->dev_state) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) test_bit(DEV_MISCONFIGURED, &dev->dev_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (urb->status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) print_err_status(dev, -1, urb->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (urb->status == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) buf = dev->isoc_ctl.buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) if (buf != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) outp = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) vbi_buf = dev->isoc_ctl.vbi_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (vbi_buf != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) vbioutp = vb2_plane_vaddr(&vbi_buf->vb.vb2_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) for (i = 0; i < urb->number_of_packets; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) int status = urb->iso_frame_desc[i].status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) print_err_status(dev, i, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) if (urb->iso_frame_desc[i].status != -EPROTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (urb->iso_frame_desc[i].actual_length <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) if (urb->iso_frame_desc[i].actual_length >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) dev->max_pkt_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) au0828_isocdbg("packet bigger than packet size");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) fbyte = p[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) len = urb->iso_frame_desc[i].actual_length - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) p += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (fbyte & 0x80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) len -= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) p += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) au0828_isocdbg("Video frame %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) (fbyte & 0x40) ? "odd" : "even");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (fbyte & 0x40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) /* VBI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (vbi_buf != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) buffer_filled(dev, vbi_dma_q, vbi_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) vbi_get_next_buf(vbi_dma_q, &vbi_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (vbi_buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) vbioutp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) vbioutp = vb2_plane_vaddr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) &vbi_buf->vb.vb2_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* Video */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) if (buf != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) buffer_filled(dev, dma_q, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) get_next_buf(dma_q, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (buf == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) outp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) outp = vb2_plane_vaddr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) &buf->vb.vb2_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) /* As long as isoc traffic is arriving, keep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) resetting the timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) if (dev->vid_timeout_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) mod_timer(&dev->vid_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) jiffies + (HZ / 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) if (dev->vbi_timeout_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) mod_timer(&dev->vbi_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) jiffies + (HZ / 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (buf != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (fbyte & 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) buf->top_field = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) buf->top_field = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) if (vbi_buf != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (fbyte & 0x40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) vbi_buf->top_field = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) vbi_buf->top_field = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) dev->vbi_read = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) vbi_dma_q->pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) dma_q->pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) vbi_field_size = dev->vbi_width * dev->vbi_height * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (dev->vbi_read < vbi_field_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) remain = vbi_field_size - dev->vbi_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) if (len < remain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) lencopy = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) lencopy = remain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (vbi_buf != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) au0828_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) vbioutp, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) len -= lencopy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) p += lencopy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) dev->vbi_read += lencopy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (dev->vbi_read >= vbi_field_size && buf != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) au0828_copy_video(dev, dma_q, buf, p, outp, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) void au0828_usb_v4l2_media_release(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) #ifdef CONFIG_MEDIA_CONTROLLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) for (i = 0; i < AU0828_MAX_INPUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) media_device_unregister_entity(&dev->input_ent[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) static void au0828_usb_v4l2_release(struct v4l2_device *v4l2_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) struct au0828_dev *dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) container_of(v4l2_dev, struct au0828_dev, v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) v4l2_ctrl_handler_free(&dev->v4l2_ctrl_hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) v4l2_device_unregister(&dev->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) au0828_usb_v4l2_media_release(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) au0828_usb_release(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) int au0828_v4l2_device_register(struct usb_interface *interface,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) if (AUVI_INPUT(0).type == AU0828_VMUX_UNDEFINED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /* Create the v4l2_device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) #ifdef CONFIG_MEDIA_CONTROLLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) dev->v4l2_dev.mdev = dev->media_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) retval = v4l2_device_register(&interface->dev, &dev->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) pr_err("%s() v4l2_device_register failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) dev->v4l2_dev.release = au0828_usb_v4l2_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /* This control handler will inherit the controls from au8522 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) retval = v4l2_ctrl_handler_init(&dev->v4l2_ctrl_hdl, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) pr_err("%s() v4l2_ctrl_handler_init failed\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) dev->v4l2_dev.ctrl_handler = &dev->v4l2_ctrl_hdl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static int queue_setup(struct vb2_queue *vq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) unsigned int *nbuffers, unsigned int *nplanes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) unsigned int sizes[], struct device *alloc_devs[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct au0828_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) unsigned long size = dev->height * dev->bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (*nplanes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) return sizes[0] < size ? -EINVAL : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) *nplanes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) sizes[0] = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) buffer_prepare(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) struct au0828_buffer *buf = container_of(vbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) struct au0828_buffer, vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) buf->length = dev->height * dev->bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) if (vb2_plane_size(vb, 0) < buf->length) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) pr_err("%s data will not fit into plane (%lu < %lu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) __func__, vb2_plane_size(vb, 0), buf->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) buffer_queue(struct vb2_buffer *vb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) struct au0828_buffer *buf = container_of(vbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) struct au0828_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) vb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) struct au0828_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) struct au0828_dmaqueue *vidq = &dev->vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) buf->mem = vb2_plane_vaddr(vb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) buf->length = vb2_plane_size(vb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) spin_lock_irqsave(&dev->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) list_add_tail(&buf->list, &vidq->active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) spin_unlock_irqrestore(&dev->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) static int au0828_i2s_init(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /* Enable i2s mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) au0828_writereg(dev, AU0828_AUDIOCTRL_50C, 0x01);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * Auvitek au0828 analog stream enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) static int au0828_analog_stream_enable(struct au0828_dev *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct usb_interface *iface;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) int ret, h, w;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) dprintk(1, "au0828_analog_stream_enable called\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (test_bit(DEV_DISCONNECTED, &d->dev_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) iface = usb_ifnum_to_if(d->usbdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (iface && iface->cur_altsetting->desc.bAlternateSetting != 5) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) dprintk(1, "Changing intf#0 to alt 5\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) /* set au0828 interface0 to AS5 here again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) ret = usb_set_interface(d->usbdev, 0, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) pr_info("Au0828 can't set alt setting to 5!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) h = d->height / 2 + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) w = d->width * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) au0828_writereg(d, AU0828_SENSORCTRL_VBI_103, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) au0828_writereg(d, 0x106, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) /* set x position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) au0828_writereg(d, 0x110, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) au0828_writereg(d, 0x111, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) au0828_writereg(d, 0x114, w & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) au0828_writereg(d, 0x115, w >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) /* set y position */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) au0828_writereg(d, 0x112, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) au0828_writereg(d, 0x113, 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) au0828_writereg(d, 0x116, h & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) au0828_writereg(d, 0x117, h >> 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) au0828_writereg(d, AU0828_SENSORCTRL_100, 0xb3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) static int au0828_analog_stream_disable(struct au0828_dev *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) dprintk(1, "au0828_analog_stream_disable called\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) au0828_writereg(d, AU0828_SENSORCTRL_100, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) static void au0828_analog_stream_reset(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) dprintk(1, "au0828_analog_stream_reset called\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) au0828_writereg(dev, AU0828_SENSORCTRL_100, 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) mdelay(30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) au0828_writereg(dev, AU0828_SENSORCTRL_100, 0xb3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * Some operations needs to stop current streaming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) static int au0828_stream_interrupt(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) dev->stream_state = STREAM_INTERRUPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) if (test_bit(DEV_DISCONNECTED, &dev->dev_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) int au0828_start_analog_streaming(struct vb2_queue *vq, unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) struct au0828_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) dprintk(1, "au0828_start_analog_streaming called %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) dev->streaming_users);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) dev->frame_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) dev->vbi_frame_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) if (dev->streaming_users == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) /* If we were doing ac97 instead of i2s, it would go here...*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) au0828_i2s_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) rc = au0828_init_isoc(dev, AU0828_ISO_PACKETS_PER_URB,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) AU0828_MAX_ISO_BUFS, dev->max_pkt_size,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) au0828_isoc_copy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) pr_info("au0828_init_isoc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) dev->vid_timeout_running = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) } else if (vq->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) dev->vbi_timeout_running = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) dev->streaming_users++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) static void au0828_stop_streaming(struct vb2_queue *vq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) struct au0828_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) struct au0828_dmaqueue *vidq = &dev->vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) dprintk(1, "au0828_stop_streaming called %d\n", dev->streaming_users);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (dev->streaming_users-- == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) au0828_uninit_isoc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) dev->vid_timeout_running = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) del_timer_sync(&dev->vid_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) spin_lock_irqsave(&dev->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (dev->isoc_ctl.buf != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) vb2_buffer_done(&dev->isoc_ctl.buf->vb.vb2_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) VB2_BUF_STATE_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) dev->isoc_ctl.buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) while (!list_empty(&vidq->active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) struct au0828_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) buf = list_entry(vidq->active.next, struct au0828_buffer, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) list_del(&buf->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) spin_unlock_irqrestore(&dev->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) void au0828_stop_vbi_streaming(struct vb2_queue *vq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct au0828_dev *dev = vb2_get_drv_priv(vq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) struct au0828_dmaqueue *vbiq = &dev->vbiq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) dprintk(1, "au0828_stop_vbi_streaming called %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) dev->streaming_users);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (dev->streaming_users-- == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) au0828_uninit_isoc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) spin_lock_irqsave(&dev->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (dev->isoc_ctl.vbi_buf != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) vb2_buffer_done(&dev->isoc_ctl.vbi_buf->vb.vb2_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) VB2_BUF_STATE_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) dev->isoc_ctl.vbi_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) while (!list_empty(&vbiq->active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) struct au0828_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) buf = list_entry(vbiq->active.next, struct au0828_buffer, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) list_del(&buf->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) spin_unlock_irqrestore(&dev->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) dev->vbi_timeout_running = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) del_timer_sync(&dev->vbi_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) static const struct vb2_ops au0828_video_qops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) .queue_setup = queue_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) .buf_prepare = buffer_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) .buf_queue = buffer_queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) .start_streaming = au0828_start_analog_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) .stop_streaming = au0828_stop_streaming,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) .wait_prepare = vb2_ops_wait_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) .wait_finish = vb2_ops_wait_finish,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) /* ------------------------------------------------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) V4L2 interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) ------------------------------------------------------------------*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) * au0828_analog_unregister
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) * unregister v4l2 devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) int au0828_analog_unregister(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) dprintk(1, "au0828_analog_unregister called\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) /* No analog TV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) if (AUVI_INPUT(0).type == AU0828_VMUX_UNDEFINED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) mutex_lock(&au0828_sysfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) vb2_video_unregister_device(&dev->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) vb2_video_unregister_device(&dev->vbi_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) mutex_unlock(&au0828_sysfs_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) v4l2_device_disconnect(&dev->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) v4l2_device_put(&dev->v4l2_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) /* This function ensures that video frames continue to be delivered even if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) the ITU-656 input isn't receiving any data (thereby preventing applications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) such as tvtime from hanging) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) static void au0828_vid_buffer_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) struct au0828_dev *dev = from_timer(dev, t, vid_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) struct au0828_dmaqueue *dma_q = &dev->vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) struct au0828_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) unsigned char *vid_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) spin_lock_irqsave(&dev->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) buf = dev->isoc_ctl.buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (buf != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) vid_data = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) memset(vid_data, 0x00, buf->length); /* Blank green frame */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) buffer_filled(dev, dma_q, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) get_next_buf(dma_q, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (dev->vid_timeout_running == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) spin_unlock_irqrestore(&dev->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) static void au0828_vbi_buffer_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) struct au0828_dev *dev = from_timer(dev, t, vbi_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) struct au0828_dmaqueue *dma_q = &dev->vbiq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) struct au0828_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) unsigned char *vbi_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) spin_lock_irqsave(&dev->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) buf = dev->isoc_ctl.vbi_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) if (buf != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) vbi_data = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) memset(vbi_data, 0x00, buf->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) buffer_filled(dev, dma_q, buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) vbi_get_next_buf(dma_q, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (dev->vbi_timeout_running == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) spin_unlock_irqrestore(&dev->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) static int au0828_v4l2_open(struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) struct au0828_dev *dev = video_drvdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) dprintk(1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) "%s called std_set %d dev_state %ld stream users %d users %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) __func__, dev->std_set_in_tuner_core, dev->dev_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) dev->streaming_users, dev->users);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (mutex_lock_interruptible(&dev->lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) ret = v4l2_fh_open(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) au0828_isocdbg("%s: v4l2_fh_open() returned error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) mutex_unlock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (dev->users == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) au0828_analog_stream_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) au0828_analog_stream_reset(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) dev->stream_state = STREAM_OFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) set_bit(DEV_INITIALIZED, &dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) dev->users++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) mutex_unlock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) static int au0828_v4l2_close(struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) struct au0828_dev *dev = video_drvdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) struct video_device *vdev = video_devdata(filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) dprintk(1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) "%s called std_set %d dev_state %ld stream users %d users %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) __func__, dev->std_set_in_tuner_core, dev->dev_state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) dev->streaming_users, dev->users);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) mutex_lock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) if (vdev->vfl_type == VFL_TYPE_VIDEO && dev->vid_timeout_running) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) /* Cancel timeout thread in case they didn't call streamoff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) dev->vid_timeout_running = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) del_timer_sync(&dev->vid_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) } else if (vdev->vfl_type == VFL_TYPE_VBI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) dev->vbi_timeout_running) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) /* Cancel timeout thread in case they didn't call streamoff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) dev->vbi_timeout_running = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) del_timer_sync(&dev->vbi_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (test_bit(DEV_DISCONNECTED, &dev->dev_state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) goto end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) if (dev->users == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) * Avoid putting tuner in sleep if DVB or ALSA are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) * streaming.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) * On most USB devices like au0828 the tuner can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) * be safely put in sleep state here if ALSA isn't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) * streaming. Exceptions are some very old USB tuner
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) * models such as em28xx-based WinTV USB2 which have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) * a separate audio output jack. The devices that have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) * a separate audio output jack have analog tuners,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) * like Philips FM1236. Those devices are always on,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) * so the s_power callback are silently ignored.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) * So, the current logic here does the following:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) * Disable (put tuner to sleep) when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) * - ALSA and DVB aren't streaming.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) * - the last V4L2 file handler is closed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) * FIXME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) * Additionally, this logic could be improved to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) * disable the media source if the above conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) * are met and if the device:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) * - doesn't have a separate audio out plug (or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) * - doesn't use a silicon tuner like xc2028/3028/4000/5000).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) * Once this additional logic is in place, a callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) * is needed to enable the media source and power on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) * the tuner, for radio to work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) ret = v4l_enable_media_source(vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) if (ret == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) v4l2_device_call_all(&dev->v4l2_dev, 0, tuner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) standby);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) dev->std_set_in_tuner_core = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) /* When close the device, set the usb intf0 into alt0 to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) USB bandwidth */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) ret = usb_set_interface(dev->usbdev, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) pr_info("Au0828 can't set alternate to 0!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) end:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) _vb2_fop_release(filp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) dev->users--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) mutex_unlock(&dev->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) /* Must be called with dev->lock held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) static void au0828_init_tuner(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) struct v4l2_frequency f = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) .frequency = dev->ctrl_freq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) .type = V4L2_TUNER_ANALOG_TV,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) if (dev->std_set_in_tuner_core)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) dev->std_set_in_tuner_core = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) i2c_gate_ctrl(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) /* If we've never sent the standard in tuner core, do so now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) We don't do this at device probe because we don't want to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) incur the cost of a firmware load */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, dev->std);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) i2c_gate_ctrl(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) struct v4l2_format *format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) int width = format->fmt.pix.width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) int height = format->fmt.pix.height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) /* If they are demanding a format other than the one we support,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) bail out (tvtime asks for UYVY and then retries with YUYV) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (format->fmt.pix.pixelformat != V4L2_PIX_FMT_UYVY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) /* format->fmt.pix.width only support 720 and height 480 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) if (width != 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) width = 720;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) if (height != 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) height = 480;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) format->fmt.pix.width = width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) format->fmt.pix.height = height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) format->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) format->fmt.pix.bytesperline = width * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) format->fmt.pix.sizeimage = width * height * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) format->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) format->fmt.pix.field = V4L2_FIELD_INTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (cmd == VIDIOC_TRY_FMT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) /* maybe set new image format, driver current only support 720*480 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) dev->width = width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) dev->height = height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) dev->frame_size = width * height * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) dev->field_size = width * height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) dev->bytesperline = width * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (dev->stream_state == STREAM_ON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) dprintk(1, "VIDIOC_SET_FMT: interrupting stream!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) ret = au0828_stream_interrupt(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) dprintk(1, "error interrupting video stream!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) au0828_analog_stream_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) static int vidioc_querycap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) struct v4l2_capability *cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) strscpy(cap->driver, "au0828", sizeof(cap->driver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) strscpy(cap->card, dev->board.name, sizeof(cap->card));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) usb_make_path(dev->usbdev, cap->bus_info, sizeof(cap->bus_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) /* set the device capabilities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) cap->capabilities =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_VIDEO_CAPTURE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) V4L2_CAP_DEVICE_CAPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) struct v4l2_fmtdesc *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) if (f->index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) dprintk(1, "%s called\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) f->pixelformat = V4L2_PIX_FMT_UYVY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) f->fmt.pix.width = dev->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) f->fmt.pix.height = dev->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) f->fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) f->fmt.pix.bytesperline = dev->bytesperline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) f->fmt.pix.sizeimage = dev->frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; /* NTSC/PAL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) f->fmt.pix.field = V4L2_FIELD_INTERLACED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) return au0828_set_format(dev, VIDIOC_TRY_FMT, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) struct v4l2_format *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) rc = check_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (vb2_is_busy(&dev->vb_vidq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) pr_info("%s queue busy\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) rc = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) rc = au0828_set_format(dev, VIDIOC_S_FMT, f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id norm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (norm == dev->std)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) if (dev->streaming_users > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) dev->std = norm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) au0828_init_tuner(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) i2c_gate_ctrl(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) * FIXME: when we support something other than 60Hz standards,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) * we are going to have to make the au0828 bridge adjust the size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) * of its capture buffer, which is currently hardcoded at 720x480
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_std, norm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) i2c_gate_ctrl(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) *norm = dev->std;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) static int vidioc_enum_input(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) struct v4l2_input *input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) unsigned int tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) static const char *inames[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) [AU0828_VMUX_UNDEFINED] = "Undefined",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) [AU0828_VMUX_COMPOSITE] = "Composite",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) [AU0828_VMUX_SVIDEO] = "S-Video",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) [AU0828_VMUX_CABLE] = "Cable TV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) [AU0828_VMUX_TELEVISION] = "Television",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) [AU0828_VMUX_DVB] = "DVB",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) tmp = input->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) if (tmp >= AU0828_MAX_INPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) if (AUVI_INPUT(tmp).type == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) input->index = tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) strscpy(input->name, inames[AUVI_INPUT(tmp).type], sizeof(input->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) if ((AUVI_INPUT(tmp).type == AU0828_VMUX_TELEVISION) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) (AUVI_INPUT(tmp).type == AU0828_VMUX_CABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) input->type |= V4L2_INPUT_TYPE_TUNER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) input->audioset = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) input->type |= V4L2_INPUT_TYPE_CAMERA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) input->audioset = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) input->std = dev->vdev.tvnorms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) static int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) *i = dev->ctrl_input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) static void au0828_s_input(struct au0828_dev *dev, int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) switch (AUVI_INPUT(index).type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) case AU0828_VMUX_SVIDEO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) dev->input_type = AU0828_VMUX_SVIDEO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) dev->ctrl_ainput = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) case AU0828_VMUX_COMPOSITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) dev->input_type = AU0828_VMUX_COMPOSITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) dev->ctrl_ainput = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) case AU0828_VMUX_TELEVISION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) dev->input_type = AU0828_VMUX_TELEVISION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) dev->ctrl_ainput = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) dprintk(1, "unknown input type set [%d]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) AUVI_INPUT(index).type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) dev->ctrl_input = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) AUVI_INPUT(index).vmux, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) for (i = 0; i < AU0828_MAX_INPUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) int enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) if (AUVI_INPUT(i).audio_setup == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) if (i == index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) enable = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) enable = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) if (enable) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) (AUVI_INPUT(i).audio_setup)(dev, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) /* Make sure we leave it turned on if some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) other input is routed to this callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) if ((AUVI_INPUT(i).audio_setup) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) ((AUVI_INPUT(index).audio_setup))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) (AUVI_INPUT(i).audio_setup)(dev, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) AUVI_INPUT(index).amux, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) static int vidioc_s_input(struct file *file, void *priv, unsigned int index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) struct video_device *vfd = video_devdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) dprintk(1, "VIDIOC_S_INPUT in function %s, input=%d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) if (index >= AU0828_MAX_INPUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) if (AUVI_INPUT(index).type == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) if (dev->ctrl_input == index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) au0828_s_input(dev, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) * Input has been changed. Disable the media source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) * associated with the old input and enable source
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) * for the newly set input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) v4l_disable_media_source(vfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) return v4l_enable_media_source(vfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) static int vidioc_enumaudio(struct file *file, void *priv, struct v4l2_audio *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) if (a->index > 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) dprintk(1, "%s called\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) if (a->index == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) strscpy(a->name, "Television", sizeof(a->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) strscpy(a->name, "Line in", sizeof(a->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) a->capability = V4L2_AUDCAP_STEREO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) a->index = dev->ctrl_ainput;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) if (a->index == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) strscpy(a->name, "Television", sizeof(a->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) strscpy(a->name, "Line in", sizeof(a->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) a->capability = V4L2_AUDCAP_STEREO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) static int vidioc_s_audio(struct file *file, void *priv, const struct v4l2_audio *a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) if (a->index != dev->ctrl_ainput)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) static int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) struct video_device *vfd = video_devdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) if (t->index != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) ret = v4l_enable_media_source(vfd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) strscpy(t->name, "Auvitek tuner", sizeof(t->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) au0828_init_tuner(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) i2c_gate_ctrl(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) i2c_gate_ctrl(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) static int vidioc_s_tuner(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) const struct v4l2_tuner *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) if (t->index != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) au0828_init_tuner(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) i2c_gate_ctrl(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) i2c_gate_ctrl(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) dprintk(1, "VIDIOC_S_TUNER: signal = %x, afc = %x\n", t->signal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) t->afc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) static int vidioc_g_frequency(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) struct v4l2_frequency *freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) if (freq->tuner != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) freq->frequency = dev->ctrl_freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) static int vidioc_s_frequency(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) const struct v4l2_frequency *freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) struct v4l2_frequency new_freq = *freq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) if (freq->tuner != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) au0828_init_tuner(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) i2c_gate_ctrl(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) /* Get the actual set (and possibly clamped) frequency */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, &new_freq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) dev->ctrl_freq = new_freq.frequency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) i2c_gate_ctrl(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) au0828_analog_stream_reset(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) /* RAW VBI ioctls */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) struct v4l2_format *format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) format->fmt.vbi.samples_per_line = dev->vbi_width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) format->fmt.vbi.offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) format->fmt.vbi.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) format->fmt.vbi.sampling_rate = 6750000 * 4 / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) format->fmt.vbi.count[0] = dev->vbi_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) format->fmt.vbi.count[1] = dev->vbi_height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) format->fmt.vbi.start[0] = 21;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) format->fmt.vbi.start[1] = 284;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) memset(format->fmt.vbi.reserved, 0, sizeof(format->fmt.vbi.reserved));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) static int vidioc_g_pixelaspect(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) int type, struct v4l2_fract *f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) f->numerator = 54;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) f->denominator = 59;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) static int vidioc_g_selection(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) struct v4l2_selection *s)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) switch (s->target) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) case V4L2_SEL_TGT_CROP_BOUNDS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) case V4L2_SEL_TGT_CROP_DEFAULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) s->r.left = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) s->r.top = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) s->r.width = dev->width;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) s->r.height = dev->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) #ifdef CONFIG_VIDEO_ADV_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) static int vidioc_g_register(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) struct v4l2_dbg_register *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) reg->val = au0828_read(dev, reg->reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) reg->size = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) static int vidioc_s_register(struct file *file, void *priv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) const struct v4l2_dbg_register *reg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) struct au0828_dev *dev = video_drvdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) dprintk(1, "%s called std_set %d dev_state %ld\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) dev->std_set_in_tuner_core, dev->dev_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) return au0828_writereg(dev, reg->reg, reg->val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) static int vidioc_log_status(struct file *file, void *fh)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) struct video_device *vdev = video_devdata(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) dprintk(1, "%s called\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) v4l2_ctrl_log_status(file, fh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) v4l2_device_call_all(vdev->v4l2_dev, 0, core, log_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) void au0828_v4l2_suspend(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) struct urb *urb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) pr_info("stopping V4L2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) if (dev->stream_state == STREAM_ON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) pr_info("stopping V4L2 active URBs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) au0828_analog_stream_disable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) /* stop urbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) urb = dev->isoc_ctl.urb[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) if (urb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) if (!irqs_disabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) usb_kill_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) usb_unlink_urb(urb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) if (dev->vid_timeout_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) del_timer_sync(&dev->vid_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) if (dev->vbi_timeout_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) del_timer_sync(&dev->vbi_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) void au0828_v4l2_resume(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) int i, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) pr_info("restarting V4L2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) if (dev->stream_state == STREAM_ON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) au0828_stream_interrupt(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) au0828_init_tuner(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) if (dev->vid_timeout_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) mod_timer(&dev->vid_timeout, jiffies + (HZ / 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) if (dev->vbi_timeout_running)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) mod_timer(&dev->vbi_timeout, jiffies + (HZ / 10));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) /* If we were doing ac97 instead of i2s, it would go here...*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) au0828_i2s_init(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) au0828_analog_stream_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) if (!(dev->stream_state == STREAM_ON)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) au0828_analog_stream_reset(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) /* submit urbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) au0828_isocdbg("submit of urb %i failed (error=%i)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) i, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) au0828_uninit_isoc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) static const struct v4l2_file_operations au0828_v4l_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) .open = au0828_v4l2_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) .release = au0828_v4l2_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) .read = vb2_fop_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) .poll = vb2_fop_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) .mmap = vb2_fop_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) .unlocked_ioctl = video_ioctl2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) static const struct v4l2_ioctl_ops video_ioctl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) .vidioc_querycap = vidioc_querycap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) .vidioc_try_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) .vidioc_s_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) .vidioc_enumaudio = vidioc_enumaudio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) .vidioc_g_audio = vidioc_g_audio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) .vidioc_s_audio = vidioc_s_audio,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) .vidioc_g_pixelaspect = vidioc_g_pixelaspect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) .vidioc_g_selection = vidioc_g_selection,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) .vidioc_reqbufs = vb2_ioctl_reqbufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) .vidioc_create_bufs = vb2_ioctl_create_bufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) .vidioc_prepare_buf = vb2_ioctl_prepare_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) .vidioc_querybuf = vb2_ioctl_querybuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) .vidioc_qbuf = vb2_ioctl_qbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) .vidioc_dqbuf = vb2_ioctl_dqbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) .vidioc_expbuf = vb2_ioctl_expbuf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) .vidioc_s_std = vidioc_s_std,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) .vidioc_g_std = vidioc_g_std,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) .vidioc_enum_input = vidioc_enum_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) .vidioc_g_input = vidioc_g_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) .vidioc_s_input = vidioc_s_input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) .vidioc_streamon = vb2_ioctl_streamon,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) .vidioc_streamoff = vb2_ioctl_streamoff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) .vidioc_g_tuner = vidioc_g_tuner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) .vidioc_s_tuner = vidioc_s_tuner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) .vidioc_g_frequency = vidioc_g_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) .vidioc_s_frequency = vidioc_s_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) #ifdef CONFIG_VIDEO_ADV_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) .vidioc_g_register = vidioc_g_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) .vidioc_s_register = vidioc_s_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) .vidioc_log_status = vidioc_log_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) static const struct video_device au0828_video_template = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) .fops = &au0828_v4l_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) .release = video_device_release_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) .ioctl_ops = &video_ioctl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_M,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) static int au0828_vb2_setup(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) struct vb2_queue *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) /* Setup Videobuf2 for Video capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) q = &dev->vb_vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) q->drv_priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) q->buf_struct_size = sizeof(struct au0828_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) q->ops = &au0828_video_qops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) q->mem_ops = &vb2_vmalloc_memops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) rc = vb2_queue_init(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) /* Setup Videobuf2 for VBI capture */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) q = &dev->vb_vbiq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) q->type = V4L2_BUF_TYPE_VBI_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) q->io_modes = VB2_READ | VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) q->drv_priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) q->buf_struct_size = sizeof(struct au0828_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) q->ops = &au0828_vbi_qops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) q->mem_ops = &vb2_vmalloc_memops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) rc = vb2_queue_init(q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) static void au0828_analog_create_entities(struct au0828_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) #if defined(CONFIG_MEDIA_CONTROLLER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) static const char * const inames[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) [AU0828_VMUX_COMPOSITE] = "Composite",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) [AU0828_VMUX_SVIDEO] = "S-Video",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) [AU0828_VMUX_CABLE] = "Cable TV",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) [AU0828_VMUX_TELEVISION] = "Television",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) [AU0828_VMUX_DVB] = "DVB",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) /* Initialize Video and VBI pads */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) dev->video_pad.flags = MEDIA_PAD_FL_SINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) ret = media_entity_pads_init(&dev->vdev.entity, 1, &dev->video_pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) pr_err("failed to initialize video media entity!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) dev->vbi_pad.flags = MEDIA_PAD_FL_SINK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) ret = media_entity_pads_init(&dev->vbi_dev.entity, 1, &dev->vbi_pad);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) pr_err("failed to initialize vbi media entity!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) /* Create entities for each input connector */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) for (i = 0; i < AU0828_MAX_INPUT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) struct media_entity *ent = &dev->input_ent[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) if (AUVI_INPUT(i).type == AU0828_VMUX_UNDEFINED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) ent->name = inames[AUVI_INPUT(i).type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) ent->flags = MEDIA_ENT_FL_CONNECTOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) dev->input_pad[i].flags = MEDIA_PAD_FL_SOURCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) switch (AUVI_INPUT(i).type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) case AU0828_VMUX_COMPOSITE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) ent->function = MEDIA_ENT_F_CONN_COMPOSITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) case AU0828_VMUX_SVIDEO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) ent->function = MEDIA_ENT_F_CONN_SVIDEO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) case AU0828_VMUX_CABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) case AU0828_VMUX_TELEVISION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) case AU0828_VMUX_DVB:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) default: /* Just to shut up a warning */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) ent->function = MEDIA_ENT_F_CONN_RF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) ret = media_entity_pads_init(ent, 1, &dev->input_pad[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) pr_err("failed to initialize input pad[%d]!\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) ret = media_device_register_entity(dev->media_dev, ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) pr_err("failed to register input entity %d!\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) /**************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) int au0828_analog_register(struct au0828_dev *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) struct usb_interface *interface)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) int retval = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) struct usb_host_interface *iface_desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) struct usb_endpoint_descriptor *endpoint;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) dprintk(1, "au0828_analog_register called for intf#%d!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) interface->cur_altsetting->desc.bInterfaceNumber);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) /* No analog TV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) if (AUVI_INPUT(0).type == AU0828_VMUX_UNDEFINED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) /* set au0828 usb interface0 to as5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) retval = usb_set_interface(dev->usbdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) interface->cur_altsetting->desc.bInterfaceNumber, 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) if (retval != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) pr_info("Failure setting usb interface0 to as5\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) return retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) /* Figure out which endpoint has the isoc interface */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) iface_desc = interface->cur_altsetting;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) for (i = 0; i < iface_desc->desc.bNumEndpoints; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) endpoint = &iface_desc->endpoint[i].desc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) == USB_DIR_IN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) == USB_ENDPOINT_XFER_ISOC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) /* we find our isoc in endpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) u16 tmp = le16_to_cpu(endpoint->wMaxPacketSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) dev->max_pkt_size = (tmp & 0x07ff) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) (((tmp & 0x1800) >> 11) + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) dev->isoc_in_endpointaddr = endpoint->bEndpointAddress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) dprintk(1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) "Found isoc endpoint 0x%02x, max size = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) dev->isoc_in_endpointaddr, dev->max_pkt_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) if (!(dev->isoc_in_endpointaddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) pr_info("Could not locate isoc endpoint\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) init_waitqueue_head(&dev->open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) spin_lock_init(&dev->slock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) /* init video dma queues */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) INIT_LIST_HEAD(&dev->vidq.active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) INIT_LIST_HEAD(&dev->vbiq.active);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) timer_setup(&dev->vid_timeout, au0828_vid_buffer_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) timer_setup(&dev->vbi_timeout, au0828_vbi_buffer_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) dev->width = NTSC_STD_W;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) dev->height = NTSC_STD_H;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) dev->field_size = dev->width * dev->height;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) dev->frame_size = dev->field_size << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) dev->bytesperline = dev->width << 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) dev->vbi_width = 720;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) dev->vbi_height = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) dev->ctrl_ainput = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) dev->ctrl_freq = 960;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) dev->std = V4L2_STD_NTSC_M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) /* Default input is TV Tuner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) au0828_s_input(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) mutex_init(&dev->vb_queue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) mutex_init(&dev->vb_vbi_queue_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) /* Fill the video capture device struct */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) dev->vdev = au0828_video_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) dev->vdev.v4l2_dev = &dev->v4l2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) dev->vdev.lock = &dev->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) dev->vdev.queue = &dev->vb_vidq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) dev->vdev.queue->lock = &dev->vb_queue_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) dev->vdev.device_caps =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) V4L2_CAP_TUNER | V4L2_CAP_VIDEO_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) strscpy(dev->vdev.name, "au0828a video", sizeof(dev->vdev.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) /* Setup the VBI device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) dev->vbi_dev = au0828_video_template;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) dev->vbi_dev.v4l2_dev = &dev->v4l2_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) dev->vbi_dev.lock = &dev->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) dev->vbi_dev.queue = &dev->vb_vbiq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) dev->vbi_dev.queue->lock = &dev->vb_vbi_queue_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) dev->vbi_dev.device_caps =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) strscpy(dev->vbi_dev.name, "au0828a vbi", sizeof(dev->vbi_dev.name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) /* Init entities at the Media Controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) au0828_analog_create_entities(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) /* initialize videobuf2 stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) retval = au0828_vb2_setup(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) if (retval != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) dprintk(1, "unable to setup videobuf2 queues (error = %d).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) /* Register the v4l2 device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) video_set_drvdata(&dev->vdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) retval = video_register_device(&dev->vdev, VFL_TYPE_VIDEO, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) if (retval != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) dprintk(1, "unable to register video device (error = %d).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) /* Register the vbi device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) video_set_drvdata(&dev->vbi_dev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) retval = video_register_device(&dev->vbi_dev, VFL_TYPE_VBI, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) if (retval != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) dprintk(1, "unable to register vbi device (error = %d).\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) goto err_reg_vbi_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) #ifdef CONFIG_MEDIA_CONTROLLER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) retval = v4l2_mc_create_media_graph(dev->media_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) pr_err("%s() au0282_dev_register failed to create graph\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) goto err_reg_vbi_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) dprintk(1, "%s completed!\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) err_reg_vbi_dev:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) vb2_video_unregister_device(&dev->vdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045)