// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * netup_unidvb_core.c
 *
 * Main module for NetUP Universal Dual DVB-CI
 *
 * Copyright (C) 2014 NetUP Inc.
 * Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
 * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kmod.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/list.h>
#include <media/videobuf2-v4l2.h>
#include <media/videobuf2-vmalloc.h>

#include "netup_unidvb.h"
#include "cxd2841er.h"
#include "horus3a.h"
#include "ascot2e.h"
#include "helene.h"
#include "lnbh25.h"

static int spi_enable;
module_param(spi_enable, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

MODULE_DESCRIPTION("Driver for NetUP Dual Universal DVB CI PCIe card");
MODULE_AUTHOR("info@netup.ru");
MODULE_VERSION(NETUP_UNIDVB_VERSION);
MODULE_LICENSE("GPL");

DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);

/* Avalon-MM PCI-E registers */
#define	AVL_PCIE_IENR		0x50
#define AVL_PCIE_ISR		0x40
#define AVL_IRQ_ENABLE		0x80
#define AVL_IRQ_ASSERTED	0x80
/* GPIO registers */
#define GPIO_REG_IO		0x4880
#define GPIO_REG_IO_TOGGLE	0x4882
#define GPIO_REG_IO_SET		0x4884
#define GPIO_REG_IO_CLEAR	0x4886
/* GPIO bits */
#define GPIO_FEA_RESET		(1 << 0)
#define GPIO_FEB_RESET		(1 << 1)
#define GPIO_RFA_CTL		(1 << 2)
#define GPIO_RFB_CTL		(1 << 3)
#define GPIO_FEA_TU_RESET	(1 << 4)
#define GPIO_FEB_TU_RESET	(1 << 5)
/* DMA base address */
#define NETUP_DMA0_ADDR		0x4900
#define NETUP_DMA1_ADDR		0x4940
/* 8 DMA blocks * 128 packets * 188 bytes*/
#define NETUP_DMA_BLOCKS_COUNT	8
#define NETUP_DMA_PACKETS_COUNT	128
/* DMA status bits */
#define BIT_DMA_RUN		1
#define BIT_DMA_ERROR		2
#define BIT_DMA_IRQ		0x200

/**
 * struct netup_dma_regs - the map of DMA module registers
 * @ctrlstat_set:	Control register, write to set control bits
 * @ctrlstat_clear:	Control register, write to clear control bits
 * @start_addr_lo:	DMA ring buffer start address, lower part
 * @start_addr_hi:	DMA ring buffer start address, higher part
 * @size:		DMA ring buffer size register
 *			* Bits [0-7]:	DMA packet size, 188 bytes
 *			* Bits [16-23]:	packets count in block, 128 packets
 *			* Bits [24-31]:	blocks count, 8 blocks
 * @timeout:		DMA timeout in units of 8ns
 *			For example, value of 375000000 equals to 3 sec
 * @curr_addr_lo:	Current ring buffer head address, lower part
 * @curr_addr_hi:	Current ring buffer head address, higher part
 * @stat_pkt_received:	Statistic register, not tested
 * @stat_pkt_accepted:	Statistic register, not tested
 * @stat_pkt_overruns:	Statistic register, not tested
 * @stat_pkt_underruns:	Statistic register, not tested
 * @stat_fifo_overruns:	Statistic register, not tested
 */
struct netup_dma_regs {
	__le32	ctrlstat_set;
	__le32	ctrlstat_clear;
	__le32	start_addr_lo;
	__le32	start_addr_hi;
	__le32	size;
	__le32	timeout;
	__le32	curr_addr_lo;
	__le32	curr_addr_hi;
	__le32	stat_pkt_received;
	__le32	stat_pkt_accepted;
	__le32	stat_pkt_overruns;
	__le32	stat_pkt_underruns;
	__le32	stat_fifo_overruns;
} __packed __aligned(1);

struct netup_unidvb_buffer {
	struct vb2_v4l2_buffer vb;
	struct list_head	list;
	u32			size;
};

static int netup_unidvb_tuner_ctrl(void *priv, int is_dvb_tc);
static void netup_unidvb_queue_cleanup(struct netup_dma *dma);

static struct cxd2841er_config demod_config = {
	.i2c_addr = 0xc8,
	.xtal = SONY_XTAL_24000,
	.flags = CXD2841ER_USE_GATECTRL | CXD2841ER_ASCOT
};

static struct horus3a_config horus3a_conf = {
	.i2c_address = 0xc0,
	.xtal_freq_mhz = 16,
	.set_tuner_callback = netup_unidvb_tuner_ctrl
};

static struct ascot2e_config ascot2e_conf = {
	.i2c_address = 0xc2,
	.set_tuner_callback = netup_unidvb_tuner_ctrl
};

static struct helene_config helene_conf = {
	.i2c_address = 0xc0,
	.xtal = SONY_HELENE_XTAL_24000,
	.set_tuner_callback = netup_unidvb_tuner_ctrl
};

static struct lnbh25_config lnbh25_conf = {
	.i2c_address = 0x10,
	.data2_config = LNBH25_TEN | LNBH25_EXTM
};

static int netup_unidvb_tuner_ctrl(void *priv, int is_dvb_tc)
{
	u8 reg, mask;
	struct netup_dma *dma = priv;
	struct netup_unidvb_dev *ndev;

	if (!priv)
		return -EINVAL;
	ndev = dma->ndev;
	dev_dbg(&ndev->pci_dev->dev, "%s(): num %d is_dvb_tc %d\n",
		__func__, dma->num, is_dvb_tc);
	reg = readb(ndev->bmmio0 + GPIO_REG_IO);
	mask = (dma->num == 0) ? GPIO_RFA_CTL : GPIO_RFB_CTL;

	/* inverted tuner control in hw rev. 1.4 */
	if (ndev->rev == NETUP_HW_REV_1_4)
		is_dvb_tc = !is_dvb_tc;

	if (!is_dvb_tc)
		reg |= mask;
	else
		reg &= ~mask;
	writeb(reg, ndev->bmmio0 + GPIO_REG_IO);
	return 0;
}

static void netup_unidvb_dev_enable(struct netup_unidvb_dev *ndev)
{
	u16 gpio_reg;

	/* enable PCI-E interrupts */
	writel(AVL_IRQ_ENABLE, ndev->bmmio0 + AVL_PCIE_IENR);
	/* unreset frontends bits[0:1] */
	writeb(0x00, ndev->bmmio0 + GPIO_REG_IO);
	msleep(100);
	gpio_reg =
		GPIO_FEA_RESET | GPIO_FEB_RESET |
		GPIO_FEA_TU_RESET | GPIO_FEB_TU_RESET |
		GPIO_RFA_CTL | GPIO_RFB_CTL;
	writeb(gpio_reg, ndev->bmmio0 + GPIO_REG_IO);
	dev_dbg(&ndev->pci_dev->dev,
		"%s(): AVL_PCIE_IENR 0x%x GPIO_REG_IO 0x%x\n",
		__func__, readl(ndev->bmmio0 + AVL_PCIE_IENR),
		(int)readb(ndev->bmmio0 + GPIO_REG_IO));

}

static void netup_unidvb_dma_enable(struct netup_dma *dma, int enable)
{
	u32 irq_mask = (dma->num == 0 ?
		NETUP_UNIDVB_IRQ_DMA1 : NETUP_UNIDVB_IRQ_DMA2);

	dev_dbg(&dma->ndev->pci_dev->dev,
		"%s(): DMA%d enable %d\n", __func__, dma->num, enable);
	if (enable) {
		writel(BIT_DMA_RUN, &dma->regs->ctrlstat_set);
		writew(irq_mask, dma->ndev->bmmio0 + REG_IMASK_SET);
	} else {
		writel(BIT_DMA_RUN, &dma->regs->ctrlstat_clear);
		writew(irq_mask, dma->ndev->bmmio0 + REG_IMASK_CLEAR);
	}
}

static irqreturn_t netup_dma_interrupt(struct netup_dma *dma)
{
	u64 addr_curr;
	u32 size;
	unsigned long flags;
	struct device *dev = &dma->ndev->pci_dev->dev;

	spin_lock_irqsave(&dma->lock, flags);
	addr_curr = ((u64)readl(&dma->regs->curr_addr_hi) << 32) |
		(u64)readl(&dma->regs->curr_addr_lo) | dma->high_addr;
	/* clear IRQ */
	writel(BIT_DMA_IRQ, &dma->regs->ctrlstat_clear);
	/* sanity check */
	if (addr_curr < dma->addr_phys ||
			addr_curr > dma->addr_phys +  dma->ring_buffer_size) {
		if (addr_curr != 0) {
			dev_err(dev,
				"%s(): addr 0x%llx not from 0x%llx:0x%llx\n",
				__func__, addr_curr, (u64)dma->addr_phys,
				(u64)(dma->addr_phys + dma->ring_buffer_size));
		}
		goto irq_handled;
	}
	size = (addr_curr >= dma->addr_last) ?
		(u32)(addr_curr - dma->addr_last) :
		(u32)(dma->ring_buffer_size - (dma->addr_last - addr_curr));
	if (dma->data_size != 0) {
		printk_ratelimited("%s(): lost interrupt, data size %d\n",
			__func__, dma->data_size);
		dma->data_size += size;
	}
	if (dma->data_size == 0 || dma->data_size > dma->ring_buffer_size) {
		dma->data_size = size;
		dma->data_offset = (u32)(dma->addr_last - dma->addr_phys);
	}
	dma->addr_last = addr_curr;
	queue_work(dma->ndev->wq, &dma->work);
irq_handled:
	spin_unlock_irqrestore(&dma->lock, flags);
	return IRQ_HANDLED;
}

static irqreturn_t netup_unidvb_isr(int irq, void *dev_id)
{
	struct pci_dev *pci_dev = (struct pci_dev *)dev_id;
	struct netup_unidvb_dev *ndev = pci_get_drvdata(pci_dev);
	u32 reg40, reg_isr;
	irqreturn_t iret = IRQ_NONE;

	/* disable interrupts */
	writel(0, ndev->bmmio0 + AVL_PCIE_IENR);
	/* check IRQ source */
	reg40 = readl(ndev->bmmio0 + AVL_PCIE_ISR);
	if ((reg40 & AVL_IRQ_ASSERTED) != 0) {
		/* IRQ is being signaled */
		reg_isr = readw(ndev->bmmio0 + REG_ISR);
		if (reg_isr & NETUP_UNIDVB_IRQ_I2C0) {
			iret = netup_i2c_interrupt(&ndev->i2c[0]);
		} else if (reg_isr & NETUP_UNIDVB_IRQ_I2C1) {
			iret = netup_i2c_interrupt(&ndev->i2c[1]);
		} else if (reg_isr & NETUP_UNIDVB_IRQ_SPI) {
			iret = netup_spi_interrupt(ndev->spi);
		} else if (reg_isr & NETUP_UNIDVB_IRQ_DMA1) {
			iret = netup_dma_interrupt(&ndev->dma[0]);
		} else if (reg_isr & NETUP_UNIDVB_IRQ_DMA2) {
			iret = netup_dma_interrupt(&ndev->dma[1]);
		} else if (reg_isr & NETUP_UNIDVB_IRQ_CI) {
			iret = netup_ci_interrupt(ndev);
		} else {
			dev_err(&pci_dev->dev,
				"%s(): unknown interrupt 0x%x\n",
				__func__, reg_isr);
		}
	}
	/* re-enable interrupts */
	writel(AVL_IRQ_ENABLE, ndev->bmmio0 + AVL_PCIE_IENR);
	return iret;
}

static int netup_unidvb_queue_setup(struct vb2_queue *vq,
				    unsigned int *nbuffers,
				    unsigned int *nplanes,
				    unsigned int sizes[],
				    struct device *alloc_devs[])
{
	struct netup_dma *dma = vb2_get_drv_priv(vq);

	dev_dbg(&dma->ndev->pci_dev->dev, "%s()\n", __func__);

	*nplanes = 1;
	if (vq->num_buffers + *nbuffers < VIDEO_MAX_FRAME)
		*nbuffers = VIDEO_MAX_FRAME - vq->num_buffers;
	sizes[0] = PAGE_ALIGN(NETUP_DMA_PACKETS_COUNT * 188);
	dev_dbg(&dma->ndev->pci_dev->dev, "%s() nbuffers=%d sizes[0]=%d\n",
		__func__, *nbuffers, sizes[0]);
	return 0;
}

static int netup_unidvb_buf_prepare(struct vb2_buffer *vb)
{
	struct netup_dma *dma = vb2_get_drv_priv(vb->vb2_queue);
	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
	struct netup_unidvb_buffer *buf = container_of(vbuf,
				struct netup_unidvb_buffer, vb);

	dev_dbg(&dma->ndev->pci_dev->dev, "%s(): buf 0x%p\n", __func__, buf);
	buf->size = 0;
	return 0;
}

static void netup_unidvb_buf_queue(struct vb2_buffer *vb)
{
	unsigned long flags;
	struct netup_dma *dma = vb2_get_drv_priv(vb->vb2_queue);
	struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
	struct netup_unidvb_buffer *buf = container_of(vbuf,
				struct netup_unidvb_buffer, vb);

	dev_dbg(&dma->ndev->pci_dev->dev, "%s(): %p\n", __func__, buf);
	spin_lock_irqsave(&dma->lock, flags);
	list_add_tail(&buf->list, &dma->free_buffers);
	spin_unlock_irqrestore(&dma->lock, flags);
	mod_timer(&dma->timeout, jiffies + msecs_to_jiffies(1000));
}

static int netup_unidvb_start_streaming(struct vb2_queue *q, unsigned int count)
{
	struct netup_dma *dma = vb2_get_drv_priv(q);

	dev_dbg(&dma->ndev->pci_dev->dev, "%s()\n", __func__);
	netup_unidvb_dma_enable(dma, 1);
	return 0;
}

static void netup_unidvb_stop_streaming(struct vb2_queue *q)
{
	struct netup_dma *dma = vb2_get_drv_priv(q);

	dev_dbg(&dma->ndev->pci_dev->dev, "%s()\n", __func__);
	netup_unidvb_dma_enable(dma, 0);
	netup_unidvb_queue_cleanup(dma);
}

static const struct vb2_ops dvb_qops = {
	.queue_setup		= netup_unidvb_queue_setup,
	.buf_prepare		= netup_unidvb_buf_prepare,
	.buf_queue		= netup_unidvb_buf_queue,
	.start_streaming	= netup_unidvb_start_streaming,
	.stop_streaming		= netup_unidvb_stop_streaming,
};

static int netup_unidvb_queue_init(struct netup_dma *dma,
				   struct vb2_queue *vb_queue)
{
	int res;

	/* Init videobuf2 queue structure */
	vb_queue->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
	vb_queue->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
	vb_queue->drv_priv = dma;
	vb_queue->buf_struct_size = sizeof(struct netup_unidvb_buffer);
	vb_queue->ops = &dvb_qops;
	vb_queue->mem_ops = &vb2_vmalloc_memops;
	vb_queue->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
	res = vb2_queue_init(vb_queue);
	if (res != 0) {
		dev_err(&dma->ndev->pci_dev->dev,
			"%s(): vb2_queue_init failed (%d)\n", __func__, res);
	}
	return res;
}

static int netup_unidvb_dvb_init(struct netup_unidvb_dev *ndev,
				 int num)
{
	int fe_count = 2;
	int i = 0;
	struct vb2_dvb_frontend *fes[2];
	u8 fe_name[32];

	if (ndev->rev == NETUP_HW_REV_1_3)
		demod_config.xtal = SONY_XTAL_20500;
	else
		demod_config.xtal = SONY_XTAL_24000;

	if (num < 0 || num > 1) {
		dev_dbg(&ndev->pci_dev->dev,
			"%s(): unable to init DVB bus %d\n", __func__, num);
		return -ENODEV;
	}
	mutex_init(&ndev->frontends[num].lock);
	INIT_LIST_HEAD(&ndev->frontends[num].felist);

	for (i = 0; i < fe_count; i++) {
		if (vb2_dvb_alloc_frontend(&ndev->frontends[num], i+1)
				== NULL) {
			dev_err(&ndev->pci_dev->dev,
					"%s(): unable to allocate vb2_dvb_frontend\n",
					__func__);
			return -ENOMEM;
		}
	}

	for (i = 0; i < fe_count; i++) {
		fes[i] = vb2_dvb_get_frontend(&ndev->frontends[num], i+1);
		if (fes[i] == NULL) {
			dev_err(&ndev->pci_dev->dev,
				"%s(): frontends has not been allocated\n",
				__func__);
			return -EINVAL;
		}
	}

	for (i = 0; i < fe_count; i++) {
		netup_unidvb_queue_init(&ndev->dma[num], &fes[i]->dvb.dvbq);
		snprintf(fe_name, sizeof(fe_name), "netup_fe%d", i);
		fes[i]->dvb.name = fe_name;
	}

	fes[0]->dvb.frontend = dvb_attach(cxd2841er_attach_s,
		&demod_config, &ndev->i2c[num].adap);
	if (fes[0]->dvb.frontend == NULL) {
		dev_dbg(&ndev->pci_dev->dev,
			"%s(): unable to attach DVB-S/S2 frontend\n",
			__func__);
		goto frontend_detach;
	}

	if (ndev->rev == NETUP_HW_REV_1_3) {
		horus3a_conf.set_tuner_priv = &ndev->dma[num];
		if (!dvb_attach(horus3a_attach, fes[0]->dvb.frontend,
					&horus3a_conf, &ndev->i2c[num].adap)) {
			dev_dbg(&ndev->pci_dev->dev,
					"%s(): unable to attach HORUS3A DVB-S/S2 tuner frontend\n",
					__func__);
			goto frontend_detach;
		}
	} else {
		helene_conf.set_tuner_priv = &ndev->dma[num];
		if (!dvb_attach(helene_attach_s, fes[0]->dvb.frontend,
					&helene_conf, &ndev->i2c[num].adap)) {
			dev_err(&ndev->pci_dev->dev,
					"%s(): unable to attach HELENE DVB-S/S2 tuner frontend\n",
					__func__);
			goto frontend_detach;
		}
	}

	if (!dvb_attach(lnbh25_attach, fes[0]->dvb.frontend,
			&lnbh25_conf, &ndev->i2c[num].adap)) {
		dev_dbg(&ndev->pci_dev->dev,
			"%s(): unable to attach SEC frontend\n", __func__);
		goto frontend_detach;
	}

	/* DVB-T/T2 frontend */
	fes[1]->dvb.frontend = dvb_attach(cxd2841er_attach_t_c,
		&demod_config, &ndev->i2c[num].adap);
	if (fes[1]->dvb.frontend == NULL) {
		dev_dbg(&ndev->pci_dev->dev,
			"%s(): unable to attach Ter frontend\n", __func__);
		goto frontend_detach;
	}
	fes[1]->dvb.frontend->id = 1;
	if (ndev->rev == NETUP_HW_REV_1_3) {
		ascot2e_conf.set_tuner_priv = &ndev->dma[num];
		if (!dvb_attach(ascot2e_attach, fes[1]->dvb.frontend,
					&ascot2e_conf, &ndev->i2c[num].adap)) {
			dev_dbg(&ndev->pci_dev->dev,
					"%s(): unable to attach Ter tuner frontend\n",
					__func__);
			goto frontend_detach;
		}
	} else {
		helene_conf.set_tuner_priv = &ndev->dma[num];
		if (!dvb_attach(helene_attach, fes[1]->dvb.frontend,
					&helene_conf, &ndev->i2c[num].adap)) {
			dev_err(&ndev->pci_dev->dev,
					"%s(): unable to attach HELENE Ter tuner frontend\n",
					__func__);
			goto frontend_detach;
		}
	}

	if (vb2_dvb_register_bus(&ndev->frontends[num],
				 THIS_MODULE, NULL,
				 &ndev->pci_dev->dev, NULL, adapter_nr, 1)) {
		dev_dbg(&ndev->pci_dev->dev,
			"%s(): unable to register DVB bus %d\n",
			__func__, num);
		goto frontend_detach;
	}
	dev_info(&ndev->pci_dev->dev, "DVB init done, num=%d\n", num);
	return 0;
frontend_detach:
	vb2_dvb_dealloc_frontends(&ndev->frontends[num]);
	return -EINVAL;
}

static void netup_unidvb_dvb_fini(struct netup_unidvb_dev *ndev, int num)
{
	if (num < 0 || num > 1) {
		dev_err(&ndev->pci_dev->dev,
			"%s(): unable to unregister DVB bus %d\n",
			__func__, num);
		return;
	}
	vb2_dvb_unregister_bus(&ndev->frontends[num]);
	dev_info(&ndev->pci_dev->dev,
		"%s(): DVB bus %d unregistered\n", __func__, num);
}

static int netup_unidvb_dvb_setup(struct netup_unidvb_dev *ndev)
{
	int res;

	res = netup_unidvb_dvb_init(ndev, 0);
	if (res)
		return res;
	res = netup_unidvb_dvb_init(ndev, 1);
	if (res) {
		netup_unidvb_dvb_fini(ndev, 0);
		return res;
	}
	return 0;
}

static int netup_unidvb_ring_copy(struct netup_dma *dma,
				  struct netup_unidvb_buffer *buf)
{
	u32 copy_bytes, ring_bytes;
	u32 buff_bytes = NETUP_DMA_PACKETS_COUNT * 188 - buf->size;
	u8 *p = vb2_plane_vaddr(&buf->vb.vb2_buf, 0);
	struct netup_unidvb_dev *ndev = dma->ndev;

	if (p == NULL) {
		dev_err(&ndev->pci_dev->dev,
			"%s(): buffer is NULL\n", __func__);
		return -EINVAL;
	}
	p += buf->size;
	if (dma->data_offset + dma->data_size > dma->ring_buffer_size) {
		ring_bytes = dma->ring_buffer_size - dma->data_offset;
		copy_bytes = (ring_bytes > buff_bytes) ?
			buff_bytes : ring_bytes;
		memcpy_fromio(p, (u8 __iomem *)(dma->addr_virt + dma->data_offset), copy_bytes);
		p += copy_bytes;
		buf->size += copy_bytes;
		buff_bytes -= copy_bytes;
		dma->data_size -= copy_bytes;
		dma->data_offset += copy_bytes;
		if (dma->data_offset == dma->ring_buffer_size)
			dma->data_offset = 0;
	}
	if (buff_bytes > 0) {
		ring_bytes = dma->data_size;
		copy_bytes = (ring_bytes > buff_bytes) ?
				buff_bytes : ring_bytes;
		memcpy_fromio(p, (u8 __iomem *)(dma->addr_virt + dma->data_offset), copy_bytes);
		buf->size += copy_bytes;
		dma->data_size -= copy_bytes;
		dma->data_offset += copy_bytes;
		if (dma->data_offset == dma->ring_buffer_size)
			dma->data_offset = 0;
	}
	return 0;
}

static void netup_unidvb_dma_worker(struct work_struct *work)
{
	struct netup_dma *dma = container_of(work, struct netup_dma, work);
	struct netup_unidvb_dev *ndev = dma->ndev;
	struct netup_unidvb_buffer *buf;
	unsigned long flags;

	spin_lock_irqsave(&dma->lock, flags);
	if (dma->data_size == 0) {
		dev_dbg(&ndev->pci_dev->dev,
			"%s(): data_size == 0\n", __func__);
		goto work_done;
	}
	while (dma->data_size > 0) {
		if (list_empty(&dma->free_buffers)) {
			dev_dbg(&ndev->pci_dev->dev,
				"%s(): no free buffers\n", __func__);
			goto work_done;
		}
		buf = list_first_entry(&dma->free_buffers,
			struct netup_unidvb_buffer, list);
		if (buf->size >= NETUP_DMA_PACKETS_COUNT * 188) {
			dev_dbg(&ndev->pci_dev->dev,
				"%s(): buffer overflow, size %d\n",
				__func__, buf->size);
			goto work_done;
		}
		if (netup_unidvb_ring_copy(dma, buf))
			goto work_done;
		if (buf->size == NETUP_DMA_PACKETS_COUNT * 188) {
			list_del(&buf->list);
			dev_dbg(&ndev->pci_dev->dev,
				"%s(): buffer %p done, size %d\n",
				__func__, buf, buf->size);
			buf->vb.vb2_buf.timestamp = ktime_get_ns();
			vb2_set_plane_payload(&buf->vb.vb2_buf, 0, buf->size);
			vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_DONE);
		}
	}
work_done:
	dma->data_size = 0;
	spin_unlock_irqrestore(&dma->lock, flags);
}

static void netup_unidvb_queue_cleanup(struct netup_dma *dma)
{
	struct netup_unidvb_buffer *buf;
	unsigned long flags;

	spin_lock_irqsave(&dma->lock, flags);
	while (!list_empty(&dma->free_buffers)) {
		buf = list_first_entry(&dma->free_buffers,
			struct netup_unidvb_buffer, list);
		list_del(&buf->list);
		vb2_buffer_done(&buf->vb.vb2_buf, VB2_BUF_STATE_ERROR);
	}
	spin_unlock_irqrestore(&dma->lock, flags);
}

static void netup_unidvb_dma_timeout(struct timer_list *t)
{
	struct netup_dma *dma = from_timer(dma, t, timeout);
	struct netup_unidvb_dev *ndev = dma->ndev;

	dev_dbg(&ndev->pci_dev->dev, "%s()\n", __func__);
	netup_unidvb_queue_cleanup(dma);
}

static int netup_unidvb_dma_init(struct netup_unidvb_dev *ndev, int num)
{
	struct netup_dma *dma;
	struct device *dev = &ndev->pci_dev->dev;

	if (num < 0 || num > 1) {
		dev_err(dev, "%s(): unable to register DMA%d\n",
			__func__, num);
		return -ENODEV;
	}
	dma = &ndev->dma[num];
	dev_info(dev, "%s(): starting DMA%d\n", __func__, num);
	dma->num = num;
	dma->ndev = ndev;
	spin_lock_init(&dma->lock);
	INIT_WORK(&dma->work, netup_unidvb_dma_worker);
	INIT_LIST_HEAD(&dma->free_buffers);
	timer_setup(&dma->timeout, netup_unidvb_dma_timeout, 0);
	dma->ring_buffer_size = ndev->dma_size / 2;
	dma->addr_virt = ndev->dma_virt + dma->ring_buffer_size * num;
	dma->addr_phys = (dma_addr_t)((u64)ndev->dma_phys +
		dma->ring_buffer_size * num);
	dev_info(dev, "%s(): DMA%d buffer virt/phys 0x%p/0x%llx size %d\n",
		__func__, num, dma->addr_virt,
		(unsigned long long)dma->addr_phys,
		dma->ring_buffer_size);
	memset_io((u8 __iomem *)dma->addr_virt, 0, dma->ring_buffer_size);
	dma->addr_last = dma->addr_phys;
	dma->high_addr = (u32)(dma->addr_phys & 0xC0000000);
	dma->regs = (struct netup_dma_regs __iomem *)(num == 0 ?
		ndev->bmmio0 + NETUP_DMA0_ADDR :
		ndev->bmmio0 + NETUP_DMA1_ADDR);
	writel((NETUP_DMA_BLOCKS_COUNT << 24) |
		(NETUP_DMA_PACKETS_COUNT << 8) | 188, &dma->regs->size);
	writel((u32)(dma->addr_phys & 0x3FFFFFFF), &dma->regs->start_addr_lo);
	writel(0, &dma->regs->start_addr_hi);
	writel(dma->high_addr, ndev->bmmio0 + 0x1000);
	writel(375000000, &dma->regs->timeout);
	msleep(1000);
	writel(BIT_DMA_IRQ, &dma->regs->ctrlstat_clear);
	return 0;
}

static void netup_unidvb_dma_fini(struct netup_unidvb_dev *ndev, int num)
{
	struct netup_dma *dma;

	if (num < 0 || num > 1)
		return;
	dev_dbg(&ndev->pci_dev->dev, "%s(): num %d\n", __func__, num);
	dma = &ndev->dma[num];
	netup_unidvb_dma_enable(dma, 0);
	msleep(50);
	cancel_work_sync(&dma->work);
	del_timer(&dma->timeout);
}

static int netup_unidvb_dma_setup(struct netup_unidvb_dev *ndev)
{
	int res;

	res = netup_unidvb_dma_init(ndev, 0);
	if (res)
		return res;
	res = netup_unidvb_dma_init(ndev, 1);
	if (res) {
		netup_unidvb_dma_fini(ndev, 0);
		return res;
	}
	netup_unidvb_dma_enable(&ndev->dma[0], 0);
	netup_unidvb_dma_enable(&ndev->dma[1], 0);
	return 0;
}

static int netup_unidvb_ci_setup(struct netup_unidvb_dev *ndev,
				 struct pci_dev *pci_dev)
{
	int res;

	writew(NETUP_UNIDVB_IRQ_CI, ndev->bmmio0 + REG_IMASK_SET);
	res = netup_unidvb_ci_register(ndev, 0, pci_dev);
	if (res)
		return res;
	res = netup_unidvb_ci_register(ndev, 1, pci_dev);
	if (res)
		netup_unidvb_ci_unregister(ndev, 0);
	return res;
}

static int netup_unidvb_request_mmio(struct pci_dev *pci_dev)
{
	if (!request_mem_region(pci_resource_start(pci_dev, 0),
			pci_resource_len(pci_dev, 0), NETUP_UNIDVB_NAME)) {
		dev_err(&pci_dev->dev,
			"%s(): unable to request MMIO bar 0 at 0x%llx\n",
			__func__,
			(unsigned long long)pci_resource_start(pci_dev, 0));
		return -EBUSY;
	}
	if (!request_mem_region(pci_resource_start(pci_dev, 1),
			pci_resource_len(pci_dev, 1), NETUP_UNIDVB_NAME)) {
		dev_err(&pci_dev->dev,
			"%s(): unable to request MMIO bar 1 at 0x%llx\n",
			__func__,
			(unsigned long long)pci_resource_start(pci_dev, 1));
		release_mem_region(pci_resource_start(pci_dev, 0),
			pci_resource_len(pci_dev, 0));
		return -EBUSY;
	}
	return 0;
}

static int netup_unidvb_request_modules(struct device *dev)
{
	static const char * const modules[] = {
		"lnbh25", "ascot2e", "horus3a", "cxd2841er", "helene", NULL
	};
	const char * const *curr_mod = modules;
	int err;

	while (*curr_mod != NULL) {
		err = request_module(*curr_mod);
		if (err) {
			dev_warn(dev, "request_module(%s) failed: %d\n",
				*curr_mod, err);
		}
		++curr_mod;
	}
	return 0;
}

static int netup_unidvb_initdev(struct pci_dev *pci_dev,
				const struct pci_device_id *pci_id)
{
	u8 board_revision;
	u16 board_vendor;
	struct netup_unidvb_dev *ndev;
	int old_firmware = 0;

	netup_unidvb_request_modules(&pci_dev->dev);

	/* Check card revision */
	if (pci_dev->revision != NETUP_PCI_DEV_REVISION) {
		dev_err(&pci_dev->dev,
			"netup_unidvb: expected card revision %d, got %d\n",
			NETUP_PCI_DEV_REVISION, pci_dev->revision);
		dev_err(&pci_dev->dev,
			"Please upgrade firmware!\n");
		dev_err(&pci_dev->dev,
			"Instructions on http://www.netup.tv\n");
		old_firmware = 1;
		spi_enable = 1;
	}

	/* allocate device context */
	ndev = kzalloc(sizeof(*ndev), GFP_KERNEL);
	if (!ndev)
		goto dev_alloc_err;

	/* detect hardware revision */
	if (pci_dev->device == NETUP_HW_REV_1_3)
		ndev->rev = NETUP_HW_REV_1_3;
	else
		ndev->rev = NETUP_HW_REV_1_4;

	dev_info(&pci_dev->dev,
		"%s(): board (0x%x) hardware revision 0x%x\n",
		__func__, pci_dev->device, ndev->rev);

	ndev->old_fw = old_firmware;
	ndev->wq = create_singlethread_workqueue(NETUP_UNIDVB_NAME);
	if (!ndev->wq) {
		dev_err(&pci_dev->dev,
			"%s(): unable to create workqueue\n", __func__);
		goto wq_create_err;
	}
	ndev->pci_dev = pci_dev;
	ndev->pci_bus = pci_dev->bus->number;
	ndev->pci_slot = PCI_SLOT(pci_dev->devfn);
	ndev->pci_func = PCI_FUNC(pci_dev->devfn);
	ndev->board_num = ndev->pci_bus*10 + ndev->pci_slot;
	pci_set_drvdata(pci_dev, ndev);
	/* PCI init */
	dev_info(&pci_dev->dev, "%s(): PCI device (%d). Bus:0x%x Slot:0x%x\n",
		__func__, ndev->board_num, ndev->pci_bus, ndev->pci_slot);

	if (pci_enable_device(pci_dev)) {
		dev_err(&pci_dev->dev, "%s(): pci_enable_device failed\n",
			__func__);
		goto pci_enable_err;
	}
	/* read PCI info */
	pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &board_revision);
	pci_read_config_word(pci_dev, PCI_VENDOR_ID, &board_vendor);
	if (board_vendor != NETUP_VENDOR_ID) {
		dev_err(&pci_dev->dev, "%s(): unknown board vendor 0x%x",
			__func__, board_vendor);
		goto pci_detect_err;
	}
	dev_info(&pci_dev->dev,
		"%s(): board vendor 0x%x, revision 0x%x\n",
		__func__, board_vendor, board_revision);
	pci_set_master(pci_dev);
	if (pci_set_dma_mask(pci_dev, 0xffffffff) < 0) {
		dev_err(&pci_dev->dev,
			"%s(): 32bit PCI DMA is not supported\n", __func__);
		goto pci_detect_err;
	}
	dev_info(&pci_dev->dev, "%s(): using 32bit PCI DMA\n", __func__);
	/* Clear "no snoop" and "relaxed ordering" bits, use default MRRS. */
	pcie_capability_clear_and_set_word(pci_dev, PCI_EXP_DEVCTL,
		PCI_EXP_DEVCTL_READRQ | PCI_EXP_DEVCTL_RELAX_EN |
		PCI_EXP_DEVCTL_NOSNOOP_EN, 0);
	/* Adjust PCIe completion timeout. */
	pcie_capability_clear_and_set_word(pci_dev,
		PCI_EXP_DEVCTL2, PCI_EXP_DEVCTL2_COMP_TIMEOUT, 0x2);

	if (netup_unidvb_request_mmio(pci_dev)) {
		dev_err(&pci_dev->dev,
			"%s(): unable to request MMIO regions\n", __func__);
		goto pci_detect_err;
	}
	ndev->lmmio0 = ioremap(pci_resource_start(pci_dev, 0),
		pci_resource_len(pci_dev, 0));
	if (!ndev->lmmio0) {
		dev_err(&pci_dev->dev,
			"%s(): unable to remap MMIO bar 0\n", __func__);
		goto pci_bar0_error;
	}
	ndev->lmmio1 = ioremap(pci_resource_start(pci_dev, 1),
		pci_resource_len(pci_dev, 1));
	if (!ndev->lmmio1) {
		dev_err(&pci_dev->dev,
			"%s(): unable to remap MMIO bar 1\n", __func__);
		goto pci_bar1_error;
	}
	ndev->bmmio0 = (u8 __iomem *)ndev->lmmio0;
	ndev->bmmio1 = (u8 __iomem *)ndev->lmmio1;
	dev_info(&pci_dev->dev,
		"%s(): PCI MMIO at 0x%p (%d); 0x%p (%d); IRQ %d",
		__func__,
		ndev->lmmio0, (u32)pci_resource_len(pci_dev, 0),
		ndev->lmmio1, (u32)pci_resource_len(pci_dev, 1),
		pci_dev->irq);
	if (request_irq(pci_dev->irq, netup_unidvb_isr, IRQF_SHARED,
			"netup_unidvb", pci_dev) < 0) {
		dev_err(&pci_dev->dev,
			"%s(): can't get IRQ %d\n", __func__, pci_dev->irq);
		goto irq_request_err;
	}
	ndev->dma_size = 2 * 188 *
		NETUP_DMA_BLOCKS_COUNT * NETUP_DMA_PACKETS_COUNT;
	ndev->dma_virt = dma_alloc_coherent(&pci_dev->dev,
		ndev->dma_size, &ndev->dma_phys, GFP_KERNEL);
	if (!ndev->dma_virt) {
		dev_err(&pci_dev->dev, "%s(): unable to allocate DMA buffer\n",
			__func__);
		goto dma_alloc_err;
	}
	netup_unidvb_dev_enable(ndev);
	if (spi_enable && netup_spi_init(ndev)) {
		dev_warn(&pci_dev->dev,
			"netup_unidvb: SPI flash setup failed\n");
		goto spi_setup_err;
	}
	if (old_firmware) {
		dev_err(&pci_dev->dev,
			"netup_unidvb: card initialization was incomplete\n");
		return 0;
	}
	if (netup_i2c_register(ndev)) {
		dev_err(&pci_dev->dev, "netup_unidvb: I2C setup failed\n");
		goto i2c_setup_err;
	}
	/* enable I2C IRQs */
	writew(NETUP_UNIDVB_IRQ_I2C0 | NETUP_UNIDVB_IRQ_I2C1,
		ndev->bmmio0 + REG_IMASK_SET);
	usleep_range(5000, 10000);
	if (netup_unidvb_dvb_setup(ndev)) {
		dev_err(&pci_dev->dev, "netup_unidvb: DVB setup failed\n");
		goto dvb_setup_err;
	}
	if (netup_unidvb_ci_setup(ndev, pci_dev)) {
		dev_err(&pci_dev->dev, "netup_unidvb: CI setup failed\n");
		goto ci_setup_err;
	}
	if (netup_unidvb_dma_setup(ndev)) {
		dev_err(&pci_dev->dev, "netup_unidvb: DMA setup failed\n");
		goto dma_setup_err;
	}
	dev_info(&pci_dev->dev,
		"netup_unidvb: device has been initialized\n");
	return 0;
dma_setup_err:
	netup_unidvb_ci_unregister(ndev, 0);
	netup_unidvb_ci_unregister(ndev, 1);
ci_setup_err:
	netup_unidvb_dvb_fini(ndev, 0);
	netup_unidvb_dvb_fini(ndev, 1);
dvb_setup_err:
	netup_i2c_unregister(ndev);
i2c_setup_err:
	if (ndev->spi)
		netup_spi_release(ndev);
spi_setup_err:
	dma_free_coherent(&pci_dev->dev, ndev->dma_size,
			ndev->dma_virt, ndev->dma_phys);
dma_alloc_err:
	free_irq(pci_dev->irq, pci_dev);
irq_request_err:
	iounmap(ndev->lmmio1);
pci_bar1_error:
	iounmap(ndev->lmmio0);
pci_bar0_error:
	release_mem_region(pci_resource_start(pci_dev, 0),
		pci_resource_len(pci_dev, 0));
	release_mem_region(pci_resource_start(pci_dev, 1),
		pci_resource_len(pci_dev, 1));
pci_detect_err:
	pci_disable_device(pci_dev);
pci_enable_err:
	pci_set_drvdata(pci_dev, NULL);
	destroy_workqueue(ndev->wq);
wq_create_err:
	kfree(ndev);
dev_alloc_err:
	dev_err(&pci_dev->dev,
		"%s(): failed to initialize device\n", __func__);
	return -EIO;
}

static void netup_unidvb_finidev(struct pci_dev *pci_dev)
{
	struct netup_unidvb_dev *ndev = pci_get_drvdata(pci_dev);

	dev_info(&pci_dev->dev, "%s(): trying to stop device\n", __func__);
	if (!ndev->old_fw) {
		netup_unidvb_dma_fini(ndev, 0);
		netup_unidvb_dma_fini(ndev, 1);
		netup_unidvb_ci_unregister(ndev, 0);
		netup_unidvb_ci_unregister(ndev, 1);
		netup_unidvb_dvb_fini(ndev, 0);
		netup_unidvb_dvb_fini(ndev, 1);
		netup_i2c_unregister(ndev);
	}
	if (ndev->spi)
		netup_spi_release(ndev);
	writew(0xffff, ndev->bmmio0 + REG_IMASK_CLEAR);
	dma_free_coherent(&ndev->pci_dev->dev, ndev->dma_size,
			ndev->dma_virt, ndev->dma_phys);
	free_irq(pci_dev->irq, pci_dev);
	iounmap(ndev->lmmio0);
	iounmap(ndev->lmmio1);
	release_mem_region(pci_resource_start(pci_dev, 0),
		pci_resource_len(pci_dev, 0));
	release_mem_region(pci_resource_start(pci_dev, 1),
		pci_resource_len(pci_dev, 1));
	pci_disable_device(pci_dev);
	pci_set_drvdata(pci_dev, NULL);
	destroy_workqueue(ndev->wq);
	kfree(ndev);
	dev_info(&pci_dev->dev,
		"%s(): device has been successfully stopped\n", __func__);
}


static const struct pci_device_id netup_unidvb_pci_tbl[] = {
	{ PCI_DEVICE(0x1b55, 0x18f6) }, /* hw rev. 1.3 */
	{ PCI_DEVICE(0x1b55, 0x18f7) }, /* hw rev. 1.4 */
	{ 0, }
};
MODULE_DEVICE_TABLE(pci, netup_unidvb_pci_tbl);

static struct pci_driver netup_unidvb_pci_driver = {
	.name     = "netup_unidvb",
	.id_table = netup_unidvb_pci_tbl,
	.probe    = netup_unidvb_initdev,
	.remove   = netup_unidvb_finidev,
	.suspend  = NULL,
	.resume   = NULL,
};

module_pci_driver(netup_unidvb_pci_driver);
