static void stk1160_set_std(struct stk1160 *dev) { int i; static struct regval std525[] = { /* 720x480 */ /* Frame start */ {STK116_CFSPO_STX_L, 0x0000}, {STK116_CFSPO_STX_H, 0x0000}, {STK116_CFSPO_STY_L, 0x0003}, {STK116_CFSPO_STY_H, 0x0000}, /* Frame end */ {STK116_CFEPO_ENX_L, 0x05a0}, {STK116_CFEPO_ENX_H, 0x0005}, {STK116_CFEPO_ENY_L, 0x00f3}, {STK116_CFEPO_ENY_H, 0x0000}, {0xffff, 0xffff} }; static struct regval std625[] = { /* 720x576 */ /* TODO: Each line of frame has some junk at the end */ /* Frame start */ {STK116_CFSPO, 0x0000}, {STK116_CFSPO+1, 0x0000}, {STK116_CFSPO+2, 0x0001}, {STK116_CFSPO+3, 0x0000}, /* Frame end */ {STK116_CFEPO, 0x05a0}, {STK116_CFEPO+1, 0x0005}, {STK116_CFEPO+2, 0x0121}, {STK116_CFEPO+3, 0x0001}, {0xffff, 0xffff} }; if (dev->norm & V4L2_STD_525_60) { stk1160_dbg("registers to NTSC like standard\n"); for (i = 0; std525[i].reg != 0xffff; i++) stk1160_write_reg(dev, std525[i].reg, std525[i].val); } else { stk1160_dbg("registers to PAL like standard\n"); for (i = 0; std625[i].reg != 0xffff; i++) stk1160_write_reg(dev, std625[i].reg, std625[i].val); } }
static int stk1160_stop_streaming(struct stk1160 *dev) { if (mutex_lock_interruptible(&dev->v4l_lock)) return -ERESTARTSYS; /* * Once URBs are cancelled, the URB complete handler * won't be running. This is required to safely release the * current buffer (dev->isoc_ctl.buf). */ stk1160_cancel_isoc(dev); /* * It is possible to keep buffers around using a module parameter. * This is intended to avoid memory fragmentation. */ if (!keep_buffers) stk1160_free_isoc(dev); stk1160_stop_hw(dev); stk1160_clear_queue(dev); stk1160_dbg("streaming stopped\n"); mutex_unlock(&dev->v4l_lock); return 0; }
/* * Set a new alternate setting. * Returns true is dev->max_pkt_size has changed, false otherwise. */ static bool stk1160_set_alternate(struct stk1160 *dev) { int i, prev_alt = dev->alt; unsigned int min_pkt_size; bool new_pkt_size; /* * If we don't set right alternate, * then we will get a green screen with junk. */ min_pkt_size = STK1160_MIN_PKT_SIZE; for (i = 0; i < dev->num_alt; i++) { /* stop when the selected alt setting offers enough bandwidth */ if (dev->alt_max_pkt_size[i] >= min_pkt_size) { dev->alt = i; break; /* * otherwise make sure that we end up with the maximum bandwidth * because the min_pkt_size equation might be wrong... */ } else if (dev->alt_max_pkt_size[i] > dev->alt_max_pkt_size[dev->alt]) dev->alt = i; } stk1160_info("setting alternate %d\n", dev->alt); if (dev->alt != prev_alt) { stk1160_dbg("minimum isoc packet size: %u (alt=%d)\n", min_pkt_size, dev->alt); stk1160_dbg("setting alt %d with wMaxPacketSize=%u\n", dev->alt, dev->alt_max_pkt_size[dev->alt]); usb_set_interface(dev->udev, 0, dev->alt); } new_pkt_size = dev->max_pkt_size != dev->alt_max_pkt_size[dev->alt]; dev->max_pkt_size = dev->alt_max_pkt_size[dev->alt]; return new_pkt_size; }
static int stk1160_stop_streaming(struct stk1160 *dev) { if (mutex_lock_interruptible(&dev->v4l_lock)) return -ERESTARTSYS; stk1160_cancel_isoc(dev); /* * It is possible to keep buffers around using a module parameter. * This is intended to avoid memory fragmentation. */ if (!keep_buffers) stk1160_free_isoc(dev); stk1160_stop_hw(dev); stk1160_clear_queue(dev); stk1160_dbg("streaming stopped\n"); mutex_unlock(&dev->v4l_lock); return 0; }
static int stk1160_start_streaming(struct stk1160 *dev) { bool new_pkt_size; int rc = 0; int i; /* Check device presence */ if (!dev->udev) return -ENODEV; if (mutex_lock_interruptible(&dev->v4l_lock)) return -ERESTARTSYS; /* * For some reason it is mandatory to set alternate *first* * and only *then* initialize isoc urbs. * Someone please explain me why ;) */ new_pkt_size = stk1160_set_alternate(dev); /* * We (re)allocate isoc urbs if: * there is no allocated isoc urbs, OR * a new dev->max_pkt_size is detected */ if (!dev->isoc_ctl.num_bufs || new_pkt_size) { rc = stk1160_alloc_isoc(dev); if (rc < 0) goto out_stop_hw; } /* submit urbs and enables IRQ */ for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_KERNEL); if (rc) { stk1160_err("cannot submit urb[%d] (%d)\n", i, rc); goto out_uninit; } } /* Start saa711x */ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 1); /* Start stk1160 */ stk1160_write_reg(dev, STK1160_DCTRL, 0xb3); stk1160_write_reg(dev, STK1160_DCTRL+3, 0x00); stk1160_dbg("streaming started\n"); mutex_unlock(&dev->v4l_lock); return 0; out_uninit: stk1160_uninit_isoc(dev); out_stop_hw: usb_set_interface(dev->udev, 0, 0); stk1160_clear_queue(dev); mutex_unlock(&dev->v4l_lock); return rc; }