/*
 * Linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
 * flexcop-pci.c - covers the PCI part including DMA transfers
 * see flexcop.c for copyright information
 */

#define FC_LOG_PREFIX "flexcop-pci"
#include "flexcop-common.h"

static int enable_pid_filtering = 1;
module_param(enable_pid_filtering, int, 0444);
MODULE_PARM_DESC(enable_pid_filtering,
	"enable hardware pid filtering: supported values: 0 (fullts), 1");

static int irq_chk_intv = 100;
module_param(irq_chk_intv, int, 0644);
MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog.");

#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
#define dprintk(level,args...) \
	do { if ((debug & level)) printk(args); } while (0)
#define DEBSTATUS ""
#else
#define dprintk(level,args...)
#define DEBSTATUS " (debugging is not enabled)"
#endif

#define deb_info(args...) dprintk(0x01, args)
#define deb_reg(args...) dprintk(0x02, args)
#define deb_ts(args...) dprintk(0x04, args)
#define deb_irq(args...) dprintk(0x08, args)
#define deb_chk(args...) dprintk(0x10, args)

static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug,
	"set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))."
	DEBSTATUS);

#define DRIVER_VERSION "0.1"
#define DRIVER_NAME "flexcop-pci"
#define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>"

struct flexcop_pci {
	struct pci_dev *pdev;

#define FC_PCI_INIT     0x01
#define FC_PCI_DMA_INIT 0x02
	int init_state;

	void __iomem *io_mem;
	u32 irq;
	/* buffersize (at least for DMA1, need to be % 188 == 0,
	 * this logic is required */
#define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188)
#define FC_DEFAULT_DMA2_BUFSIZE (10 * 188)
	struct flexcop_dma dma[2];

	int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */
	u32 last_dma1_cur_pos;
	/* position of the pointer last time the timer/packet irq occurred */
	int count;
	int count_prev;
	int stream_problem;

	spinlock_t irq_lock;
	unsigned long last_irq;

	struct delayed_work irq_check_work;
	struct flexcop_device *fc_dev;
};

static int lastwreg, lastwval, lastrreg, lastrval;

static flexcop_ibi_value flexcop_pci_read_ibi_reg(struct flexcop_device *fc,
		flexcop_ibi_register r)
{
	struct flexcop_pci *fc_pci = fc->bus_specific;
	flexcop_ibi_value v;
	v.raw = readl(fc_pci->io_mem + r);

	if (lastrreg != r || lastrval != v.raw) {
		lastrreg = r; lastrval = v.raw;
		deb_reg("new rd: %3x: %08x\n", r, v.raw);
	}

	return v;
}

static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc,
		flexcop_ibi_register r, flexcop_ibi_value v)
{
	struct flexcop_pci *fc_pci = fc->bus_specific;

	if (lastwreg != r || lastwval != v.raw) {
		lastwreg = r; lastwval = v.raw;
		deb_reg("new wr: %3x: %08x\n", r, v.raw);
	}

	writel(v.raw, fc_pci->io_mem + r);
	return 0;
}

static void flexcop_pci_irq_check_work(struct work_struct *work)
{
	struct flexcop_pci *fc_pci =
		container_of(work, struct flexcop_pci, irq_check_work.work);
	struct flexcop_device *fc = fc_pci->fc_dev;

	if (fc->feedcount) {

		if (fc_pci->count == fc_pci->count_prev) {
			deb_chk("no IRQ since the last check\n");
			if (fc_pci->stream_problem++ == 3) {
				struct dvb_demux_feed *feed;
				deb_info("flexcop-pci: stream problem, resetting pid filter\n");

				spin_lock_irq(&fc->demux.lock);
				list_for_each_entry(feed, &fc->demux.feed_list,
						list_head) {
					flexcop_pid_feed_control(fc, feed, 0);
				}

				list_for_each_entry(feed, &fc->demux.feed_list,
						list_head) {
					flexcop_pid_feed_control(fc, feed, 1);
				}
				spin_unlock_irq(&fc->demux.lock);

				fc_pci->stream_problem = 0;
			}
		} else {
			fc_pci->stream_problem = 0;
			fc_pci->count_prev = fc_pci->count;
		}
	}

	schedule_delayed_work(&fc_pci->irq_check_work,
			msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
}

/* When PID filtering is turned on, we use the timer IRQ, because small amounts
 * of data need to be passed to the user space instantly as well. When PID
 * filtering is turned off, we use the page-change-IRQ */
static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
{
	struct flexcop_pci *fc_pci = dev_id;
	struct flexcop_device *fc = fc_pci->fc_dev;
	unsigned long flags;
	flexcop_ibi_value v;
	irqreturn_t ret = IRQ_HANDLED;

	spin_lock_irqsave(&fc_pci->irq_lock, flags);
	v = fc->read_ibi_reg(fc, irq_20c);

	/* errors */
	if (v.irq_20c.Data_receiver_error)
		deb_chk("data receiver error\n");
	if (v.irq_20c.Continuity_error_flag)
		deb_chk("Contunuity error flag is set\n");
	if (v.irq_20c.LLC_SNAP_FLAG_set)
		deb_chk("LLC_SNAP_FLAG_set is set\n");
	if (v.irq_20c.Transport_Error)
		deb_chk("Transport error\n");

	if ((fc_pci->count % 1000) == 0)
		deb_chk("%d valid irq took place so far\n", fc_pci->count);

	if (v.irq_20c.DMA1_IRQ_Status == 1) {
		if (fc_pci->active_dma1_addr == 0)
			flexcop_pass_dmx_packets(fc_pci->fc_dev,
					fc_pci->dma[0].cpu_addr0,
					fc_pci->dma[0].size / 188);
		else
			flexcop_pass_dmx_packets(fc_pci->fc_dev,
					fc_pci->dma[0].cpu_addr1,
					fc_pci->dma[0].size / 188);

		deb_irq("page change to page: %d\n",!fc_pci->active_dma1_addr);
		fc_pci->active_dma1_addr = !fc_pci->active_dma1_addr;
		/* for the timer IRQ we only can use buffer dmx feeding, because we don't have
		 * complete TS packets when reading from the DMA memory */
	} else if (v.irq_20c.DMA1_Timer_Status == 1) {
		dma_addr_t cur_addr =
			fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
		u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;

		deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, "
			"last_cur_pos: %08x ",
				jiffies_to_usecs(jiffies - fc_pci->last_irq),
				v.raw, (unsigned long long)cur_addr, cur_pos,
				fc_pci->last_dma1_cur_pos);
		fc_pci->last_irq = jiffies;

		/* buffer end was reached, restarted from the beginning
		 * pass the data from last_cur_pos to the buffer end to the demux
		 */
		if (cur_pos < fc_pci->last_dma1_cur_pos) {
			deb_irq(" end was reached: passing %d bytes ",
				(fc_pci->dma[0].size*2 - 1) -
				fc_pci->last_dma1_cur_pos);
			flexcop_pass_dmx_data(fc_pci->fc_dev,
				fc_pci->dma[0].cpu_addr0 +
					fc_pci->last_dma1_cur_pos,
				(fc_pci->dma[0].size*2) -
					fc_pci->last_dma1_cur_pos);
			fc_pci->last_dma1_cur_pos = 0;
		}

		if (cur_pos > fc_pci->last_dma1_cur_pos) {
			deb_irq(" passing %d bytes ",
				cur_pos - fc_pci->last_dma1_cur_pos);
			flexcop_pass_dmx_data(fc_pci->fc_dev,
				fc_pci->dma[0].cpu_addr0 +
					fc_pci->last_dma1_cur_pos,
				cur_pos - fc_pci->last_dma1_cur_pos);
		}
		deb_irq("\n");

		fc_pci->last_dma1_cur_pos = cur_pos;
		fc_pci->count++;
	} else {
		deb_irq("isr for flexcop called, "
			"apparently without reason (%08x)\n", v.raw);
		ret = IRQ_NONE;
	}

	spin_unlock_irqrestore(&fc_pci->irq_lock, flags);
	return ret;
}

static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff)
{
	struct flexcop_pci *fc_pci = fc->bus_specific;
	if (onoff) {
		flexcop_dma_config(fc, &fc_pci->dma[0], FC_DMA_1);
		flexcop_dma_config(fc, &fc_pci->dma[1], FC_DMA_2);
		flexcop_dma_config_timer(fc, FC_DMA_1, 0);
		flexcop_dma_xfer_control(fc, FC_DMA_1,
				FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 1);
		deb_irq("DMA xfer enabled\n");

		fc_pci->last_dma1_cur_pos = 0;
		flexcop_dma_control_timer_irq(fc, FC_DMA_1, 1);
		deb_irq("IRQ enabled\n");
		fc_pci->count_prev = fc_pci->count;
	} else {
		flexcop_dma_control_timer_irq(fc, FC_DMA_1, 0);
		deb_irq("IRQ disabled\n");

		flexcop_dma_xfer_control(fc, FC_DMA_1,
			 FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 0);
		deb_irq("DMA xfer disabled\n");
	}
	return 0;
}

static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci)
{
	int ret;
	ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[0],
			FC_DEFAULT_DMA1_BUFSIZE);
	if (ret != 0)
		return ret;

	ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[1],
			FC_DEFAULT_DMA2_BUFSIZE);
	if (ret != 0) {
		flexcop_dma_free(&fc_pci->dma[0]);
		return ret;
	}

	flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_MEDIA |
			FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1);
	flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_CAO |
			FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
	fc_pci->init_state |= FC_PCI_DMA_INIT;
	return ret;
}

static void flexcop_pci_dma_exit(struct flexcop_pci *fc_pci)
{
	if (fc_pci->init_state & FC_PCI_DMA_INIT) {
		flexcop_dma_free(&fc_pci->dma[0]);
		flexcop_dma_free(&fc_pci->dma[1]);
	}
	fc_pci->init_state &= ~FC_PCI_DMA_INIT;
}

static int flexcop_pci_init(struct flexcop_pci *fc_pci)
{
	int ret;

	info("card revision %x", fc_pci->pdev->revision);

	if ((ret = pci_enable_device(fc_pci->pdev)) != 0)
		return ret;
	pci_set_master(fc_pci->pdev);

	if ((ret = pci_request_regions(fc_pci->pdev, DRIVER_NAME)) != 0)
		goto err_pci_disable_device;

	fc_pci->io_mem = pci_iomap(fc_pci->pdev, 0, 0x800);

	if (!fc_pci->io_mem) {
		err("cannot map io memory\n");
		ret = -EIO;
		goto err_pci_release_regions;
	}

	pci_set_drvdata(fc_pci->pdev, fc_pci);
	spin_lock_init(&fc_pci->irq_lock);
	if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_isr,
					IRQF_SHARED, DRIVER_NAME, fc_pci)) != 0)
		goto err_pci_iounmap;

	fc_pci->init_state |= FC_PCI_INIT;
	return ret;

err_pci_iounmap:
	pci_iounmap(fc_pci->pdev, fc_pci->io_mem);
	pci_set_drvdata(fc_pci->pdev, NULL);
err_pci_release_regions:
	pci_release_regions(fc_pci->pdev);
err_pci_disable_device:
	pci_disable_device(fc_pci->pdev);
	return ret;
}

static void flexcop_pci_exit(struct flexcop_pci *fc_pci)
{
	if (fc_pci->init_state & FC_PCI_INIT) {
		free_irq(fc_pci->pdev->irq, fc_pci);
		pci_iounmap(fc_pci->pdev, fc_pci->io_mem);
		pci_set_drvdata(fc_pci->pdev, NULL);
		pci_release_regions(fc_pci->pdev);
		pci_disable_device(fc_pci->pdev);
	}
	fc_pci->init_state &= ~FC_PCI_INIT;
}

static int flexcop_pci_probe(struct pci_dev *pdev,
		const struct pci_device_id *ent)
{
	struct flexcop_device *fc;
	struct flexcop_pci *fc_pci;
	int ret = -ENOMEM;

	if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_pci))) == NULL) {
		err("out of memory\n");
		return -ENOMEM;
	}

	/* general flexcop init */
	fc_pci = fc->bus_specific;
	fc_pci->fc_dev = fc;

	fc->read_ibi_reg = flexcop_pci_read_ibi_reg;
	fc->write_ibi_reg = flexcop_pci_write_ibi_reg;
	fc->i2c_request = flexcop_i2c_request;
	fc->get_mac_addr = flexcop_eeprom_check_mac_addr;
	fc->stream_control = flexcop_pci_stream_control;

	if (enable_pid_filtering)
		info("will use the HW PID filter.");
	else
		info("will pass the complete TS to the demuxer.");

	fc->pid_filtering = enable_pid_filtering;
	fc->bus_type = FC_PCI;
	fc->dev = &pdev->dev;
	fc->owner = THIS_MODULE;

	/* bus specific part */
	fc_pci->pdev = pdev;
	if ((ret = flexcop_pci_init(fc_pci)) != 0)
		goto err_kfree;

	/* init flexcop */
	if ((ret = flexcop_device_initialize(fc)) != 0)
		goto err_pci_exit;

	/* init dma */
	if ((ret = flexcop_pci_dma_init(fc_pci)) != 0)
		goto err_fc_exit;

	INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work);

	if (irq_chk_intv > 0)
		schedule_delayed_work(&fc_pci->irq_check_work,
				msecs_to_jiffies(irq_chk_intv < 100 ?
					100 :
					irq_chk_intv));
	return ret;

err_fc_exit:
	flexcop_device_exit(fc);
err_pci_exit:
	flexcop_pci_exit(fc_pci);
err_kfree:
	flexcop_device_kfree(fc);
	return ret;
}

/* in theory every _exit function should be called exactly two times,
 * here and in the bail-out-part of the _init-function
 */
static void flexcop_pci_remove(struct pci_dev *pdev)
{
	struct flexcop_pci *fc_pci = pci_get_drvdata(pdev);

	if (irq_chk_intv > 0)
		cancel_delayed_work(&fc_pci->irq_check_work);

	flexcop_pci_dma_exit(fc_pci);
	flexcop_device_exit(fc_pci->fc_dev);
	flexcop_pci_exit(fc_pci);
	flexcop_device_kfree(fc_pci->fc_dev);
}

static struct pci_device_id flexcop_pci_tbl[] = {
	{ PCI_DEVICE(0x13d0, 0x2103) },
	{ },
};

MODULE_DEVICE_TABLE(pci, flexcop_pci_tbl);

static struct pci_driver flexcop_pci_driver = {
	.name     = "b2c2_flexcop_pci",
	.id_table = flexcop_pci_tbl,
	.probe    = flexcop_pci_probe,
	.remove   = flexcop_pci_remove,
};

static int __init flexcop_pci_module_init(void)
{
	return pci_register_driver(&flexcop_pci_driver);
}

static void __exit flexcop_pci_module_exit(void)
{
	pci_unregister_driver(&flexcop_pci_driver);
}

module_init(flexcop_pci_module_init);
module_exit(flexcop_pci_module_exit);

MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_NAME);
MODULE_LICENSE("GPL");
