// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * STK1160 driver
 *
 * Copyright (C) 2012 Ezequiel Garcia
 * <elezegarcia--a.t--gmail.com>
 *
 * Based on Easycap driver by R.M. Thomas
 *	Copyright (C) 2010 R.M. Thomas
 *	<rmthomas--a.t--sciolus.org>
 */

#include <linux/module.h>
#include <linux/usb.h>
#include <linux/slab.h>
#include <linux/ratelimit.h>

#include "stk1160.h"

static unsigned int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "enable debug messages");

static inline void print_err_status(struct stk1160 *dev,
				     int packet, int status)
{
	char *errmsg = "Unknown";

	switch (status) {
	case -ENOENT:
		errmsg = "unlinked synchronously";
		break;
	case -ECONNRESET:
		errmsg = "unlinked asynchronously";
		break;
	case -ENOSR:
		errmsg = "Buffer error (overrun)";
		break;
	case -EPIPE:
		errmsg = "Stalled (device not responding)";
		break;
	case -EOVERFLOW:
		errmsg = "Babble (bad cable?)";
		break;
	case -EPROTO:
		errmsg = "Bit-stuff error (bad cable?)";
		break;
	case -EILSEQ:
		errmsg = "CRC/Timeout (could be anything)";
		break;
	case -ETIME:
		errmsg = "Device does not respond";
		break;
	}

	if (packet < 0)
		printk_ratelimited(KERN_WARNING "URB status %d [%s].\n",
				status, errmsg);
	else
		printk_ratelimited(KERN_INFO "URB packet %d, status %d [%s].\n",
			       packet, status, errmsg);
}

static inline
struct stk1160_buffer *stk1160_next_buffer(struct stk1160 *dev)
{
	struct stk1160_buffer *buf = NULL;
	unsigned long flags = 0;

	/* Current buffer must be NULL when this functions gets called */
	WARN_ON(dev->isoc_ctl.buf);

	spin_lock_irqsave(&dev->buf_lock, flags);
	if (!list_empty(&dev->avail_bufs)) {
		buf = list_first_entry(&dev->avail_bufs,
				struct stk1160_buffer, list);
		list_del(&buf->list);
	}
	spin_unlock_irqrestore(&dev->buf_lock, flags);

	return buf;
}

static inline
void stk1160_buffer_done(struct stk1160 *dev)
{
	struct stk1160_buffer *buf = dev->isoc_ctl.buf;

	buf->vb.sequence = dev->sequence++;
	buf->vb.field = V4L2_FIELD_INTERLACED;
	buf->vb.vb2_buf.timestamp = ktime_get_ns();

	vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->bytesused);
	vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);

	dev->isoc_ctl.buf = NULL;
}

static inline
void stk1160_copy_video(struct stk1160 *dev, u8 *src, int len)
{
	int linesdone, lineoff, lencopy;
	int bytesperline = dev->width * 2;
	struct stk1160_buffer *buf = dev->isoc_ctl.buf;
	u8 *dst = buf->mem;
	int remain;

	/*
	 * TODO: These stk1160_dbg are very spammy!
	 * We should check why we are getting them.
	 *
	 * UPDATE: One of the reasons (the only one?) for getting these
	 * is incorrect standard (mismatch between expected and configured).
	 * So perhaps, we could add a counter for errors. When the counter
	 * reaches some value, we simply stop streaming.
	 */

	len -= 4;
	src += 4;

	remain = len;

	linesdone = buf->pos / bytesperline;
	lineoff = buf->pos % bytesperline; /* offset in current line */

	if (!buf->odd)
		dst += bytesperline;

	/* Multiply linesdone by two, to take account of the other field */
	dst += linesdone * bytesperline * 2 + lineoff;

	/* Copy the remaining of current line */
	if (remain < (bytesperline - lineoff))
		lencopy = remain;
	else
		lencopy = bytesperline - lineoff;

	/*
	 * Check if we have enough space left in the buffer.
	 * In that case, we force loop exit after copy.
	 */
	if (lencopy > buf->bytesused - buf->length) {
		lencopy = buf->bytesused - buf->length;
		remain = lencopy;
	}

	/* Check if the copy is done */
	if (lencopy == 0 || remain == 0)
		return;

	/* Let the bug hunt begin! sanity checks! */
	if (lencopy < 0) {
		printk_ratelimited(KERN_DEBUG "copy skipped: negative lencopy\n");
		return;
	}

	if ((unsigned long)dst + lencopy >
		(unsigned long)buf->mem + buf->length) {
		printk_ratelimited(KERN_WARNING "stk1160: buffer overflow detected\n");
		return;
	}

	memcpy(dst, src, lencopy);

	buf->bytesused += lencopy;
	buf->pos += lencopy;
	remain -= lencopy;

	/* Copy current field line by line, interlacing with the other field */
	while (remain > 0) {

		dst += lencopy + bytesperline;
		src += lencopy;

		/* Copy one line at a time */
		if (remain < bytesperline)
			lencopy = remain;
		else
			lencopy = bytesperline;

		/*
		 * Check if we have enough space left in the buffer.
		 * In that case, we force loop exit after copy.
		 */
		if (lencopy > buf->bytesused - buf->length) {
			lencopy = buf->bytesused - buf->length;
			remain = lencopy;
		}

		/* Check if the copy is done */
		if (lencopy == 0 || remain == 0)
			return;

		if (lencopy < 0) {
			printk_ratelimited(KERN_WARNING "stk1160: negative lencopy detected\n");
			return;
		}

		if ((unsigned long)dst + lencopy >
			(unsigned long)buf->mem + buf->length) {
			printk_ratelimited(KERN_WARNING "stk1160: buffer overflow detected\n");
			return;
		}

		memcpy(dst, src, lencopy);
		remain -= lencopy;

		buf->bytesused += lencopy;
		buf->pos += lencopy;
	}
}

/*
 * Controls the isoc copy of each urb packet
 */
static void stk1160_process_isoc(struct stk1160 *dev, struct urb *urb)
{
	int i, len, status;
	u8 *p;

	if (!dev) {
		stk1160_warn("%s called with null device\n", __func__);
		return;
	}

	if (urb->status < 0) {
		/* Print status and drop current packet (or field?) */
		print_err_status(dev, -1, urb->status);
		return;
	}

	for (i = 0; i < urb->number_of_packets; i++) {
		status = urb->iso_frame_desc[i].status;
		if (status < 0) {
			print_err_status(dev, i, status);
			continue;
		}

		/* Get packet actual length and pointer to data */
		p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
		len = urb->iso_frame_desc[i].actual_length;

		/* Empty packet */
		if (len <= 4)
			continue;

		/*
		 * An 8-byte packet sequence means end of field.
		 * So if we don't have any packet, we start receiving one now
		 * and if we do have a packet, then we are done with it.
		 *
		 * These end of field packets are always 0xc0 or 0x80,
		 * but not always 8-byte long so we don't check packet length.
		 */
		if (p[0] == 0xc0) {

			/*
			 * If first byte is 0xc0 then we received
			 * second field, and frame has ended.
			 */
			if (dev->isoc_ctl.buf != NULL)
				stk1160_buffer_done(dev);

			dev->isoc_ctl.buf = stk1160_next_buffer(dev);
			if (dev->isoc_ctl.buf == NULL)
				return;
		}

		/*
		 * If we don't have a buffer here, then it means we
		 * haven't found the start mark sequence.
		 */
		if (dev->isoc_ctl.buf == NULL)
			continue;

		if (p[0] == 0xc0 || p[0] == 0x80) {

			/* We set next packet parity and
			 * continue to get next one
			 */
			dev->isoc_ctl.buf->odd = *p & 0x40;
			dev->isoc_ctl.buf->pos = 0;
			continue;
		}

		stk1160_copy_video(dev, p, len);
	}
}


/*
 * IRQ callback, called by URB callback
 */
static void stk1160_isoc_irq(struct urb *urb)
{
	int i, rc;
	struct stk1160_urb *stk_urb = urb->context;
	struct stk1160 *dev = stk_urb->dev;
	struct device *dma_dev = stk1160_get_dmadev(dev);

	switch (urb->status) {
	case 0:
		break;
	case -ECONNRESET:   /* kill */
	case -ENOENT:
	case -ESHUTDOWN:
		/* TODO: check uvc driver: he frees the queue here */
		return;
	default:
		stk1160_err("urb error! status %d\n", urb->status);
		return;
	}

	invalidate_kernel_vmap_range(stk_urb->transfer_buffer,
				     urb->transfer_buffer_length);
	dma_sync_sgtable_for_cpu(dma_dev, stk_urb->sgt, DMA_FROM_DEVICE);

	stk1160_process_isoc(dev, urb);

	/* Reset urb buffers */
	for (i = 0; i < urb->number_of_packets; i++) {
		urb->iso_frame_desc[i].status = 0;
		urb->iso_frame_desc[i].actual_length = 0;
	}

	dma_sync_sgtable_for_device(dma_dev, stk_urb->sgt, DMA_FROM_DEVICE);
	rc = usb_submit_urb(urb, GFP_ATOMIC);
	if (rc)
		stk1160_err("urb re-submit failed (%d)\n", rc);
}

/*
 * Cancel urbs
 * This function can't be called in atomic context
 */
void stk1160_cancel_isoc(struct stk1160 *dev)
{
	int i, num_bufs = dev->isoc_ctl.num_bufs;

	/*
	 * This check is not necessary, but we add it
	 * to avoid a spurious debug message
	 */
	if (!num_bufs)
		return;

	stk1160_dbg("killing %d urbs...\n", num_bufs);

	for (i = 0; i < num_bufs; i++) {

		/*
		 * To kill urbs we can't be in atomic context.
		 * We don't care for NULL pointer since
		 * usb_kill_urb allows it.
		 */
		usb_kill_urb(dev->isoc_ctl.urb_ctl[i].urb);
	}

	stk1160_dbg("all urbs killed\n");
}

static void stk_free_urb(struct stk1160 *dev, struct stk1160_urb *stk_urb)
{
	struct device *dma_dev = stk1160_get_dmadev(dev);

	dma_vunmap_noncontiguous(dma_dev, stk_urb->transfer_buffer);
	dma_free_noncontiguous(dma_dev, stk_urb->urb->transfer_buffer_length,
			       stk_urb->sgt, DMA_FROM_DEVICE);
	usb_free_urb(stk_urb->urb);

	stk_urb->transfer_buffer = NULL;
	stk_urb->sgt = NULL;
	stk_urb->urb = NULL;
	stk_urb->dev = NULL;
	stk_urb->dma = 0;
}

/*
 * Releases urb and transfer buffers
 * Obviusly, associated urb must be killed before releasing it.
 */
void stk1160_free_isoc(struct stk1160 *dev)
{
	int i, num_bufs = dev->isoc_ctl.num_bufs;

	stk1160_dbg("freeing %d urb buffers...\n", num_bufs);

	for (i = 0; i < num_bufs; i++)
		stk_free_urb(dev, &dev->isoc_ctl.urb_ctl[i]);

	dev->isoc_ctl.num_bufs = 0;

	stk1160_dbg("all urb buffers freed\n");
}

/*
 * Helper for cancelling and freeing urbs
 * This function can't be called in atomic context
 */
void stk1160_uninit_isoc(struct stk1160 *dev)
{
	stk1160_cancel_isoc(dev);
	stk1160_free_isoc(dev);
}

static int stk1160_fill_urb(struct stk1160 *dev, struct stk1160_urb *stk_urb,
			    int sb_size, int max_packets)
{
	struct device *dma_dev = stk1160_get_dmadev(dev);

	stk_urb->urb = usb_alloc_urb(max_packets, GFP_KERNEL);
	if (!stk_urb->urb)
		return -ENOMEM;
	stk_urb->sgt = dma_alloc_noncontiguous(dma_dev, sb_size,
					       DMA_FROM_DEVICE, GFP_KERNEL, 0);

	/*
	 * If the buffer allocation failed, we exit but return 0 since
	 * we allow the driver working with less buffers
	 */
	if (!stk_urb->sgt)
		goto free_urb;

	stk_urb->transfer_buffer = dma_vmap_noncontiguous(dma_dev, sb_size,
							  stk_urb->sgt);
	if (!stk_urb->transfer_buffer)
		goto free_sgt;

	stk_urb->dma = stk_urb->sgt->sgl->dma_address;
	stk_urb->dev = dev;
	return 0;
free_sgt:
	dma_free_noncontiguous(dma_dev, sb_size, stk_urb->sgt, DMA_FROM_DEVICE);
	stk_urb->sgt = NULL;
free_urb:
	usb_free_urb(stk_urb->urb);
	stk_urb->urb = NULL;

	return 0;
}
/*
 * Allocate URBs
 */
int stk1160_alloc_isoc(struct stk1160 *dev)
{
	struct urb *urb;
	int i, j, k, sb_size, max_packets, num_bufs;
	int ret;

	/*
	 * It may be necessary to release isoc here,
	 * since isoc are only released on disconnection.
	 * (see new_pkt_size flag)
	 */
	if (dev->isoc_ctl.num_bufs)
		stk1160_uninit_isoc(dev);

	stk1160_dbg("allocating urbs...\n");

	num_bufs = STK1160_NUM_BUFS;
	max_packets = STK1160_NUM_PACKETS;
	sb_size = max_packets * dev->max_pkt_size;

	dev->isoc_ctl.buf = NULL;
	dev->isoc_ctl.max_pkt_size = dev->max_pkt_size;

	/* allocate urbs and transfer buffers */
	for (i = 0; i < num_bufs; i++) {

		ret = stk1160_fill_urb(dev, &dev->isoc_ctl.urb_ctl[i],
				       sb_size, max_packets);
		if (ret)
			goto free_i_bufs;

		urb = dev->isoc_ctl.urb_ctl[i].urb;

		if (!urb) {
			/* Not enough transfer buffers, so just give up */
			if (i < STK1160_MIN_BUFS)
				goto free_i_bufs;
			goto nomore_tx_bufs;
		}
		memset(dev->isoc_ctl.urb_ctl[i].transfer_buffer, 0, sb_size);

		/*
		 * FIXME: Where can I get the endpoint?
		 */
		urb->dev = dev->udev;
		urb->pipe = usb_rcvisocpipe(dev->udev, STK1160_EP_VIDEO);
		urb->transfer_buffer = dev->isoc_ctl.urb_ctl[i].transfer_buffer;
		urb->transfer_buffer_length = sb_size;
		urb->complete = stk1160_isoc_irq;
		urb->context = &dev->isoc_ctl.urb_ctl[i];
		urb->interval = 1;
		urb->start_frame = 0;
		urb->number_of_packets = max_packets;
		urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
		urb->transfer_dma = dev->isoc_ctl.urb_ctl[i].dma;

		k = 0;
		for (j = 0; j < max_packets; j++) {
			urb->iso_frame_desc[j].offset = k;
			urb->iso_frame_desc[j].length =
					dev->isoc_ctl.max_pkt_size;
			k += dev->isoc_ctl.max_pkt_size;
		}
	}

	stk1160_dbg("%d urbs allocated\n", num_bufs);

	/* At last we can say we have some buffers */
	dev->isoc_ctl.num_bufs = num_bufs;

	return 0;

nomore_tx_bufs:
	/*
	 * Failed to allocate desired buffer count. However, we may have
	 * enough to work fine, so we just free the extra urb,
	 * store the allocated count and keep going, fingers crossed!
	 */

	stk1160_warn("%d urbs allocated. Trying to continue...\n", i);

	dev->isoc_ctl.num_bufs = i;

	return 0;

free_i_bufs:
	/* Save the allocated buffers so far, so we can properly free them */
	dev->isoc_ctl.num_bufs = i;
	stk1160_free_isoc(dev);
	return -ENOMEM;
}

