// SPDX-License-Identifier: GPL-2.0-or-later
/*
    saa7146.o - driver for generic saa7146-based hardware

    Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>

*/

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <media/drv-intf/saa7146.h>
#include <linux/module.h>

static int saa7146_num;

unsigned int saa7146_debug;

module_param(saa7146_debug, uint, 0644);
MODULE_PARM_DESC(saa7146_debug, "debug level (default: 0)");

#if 0
static void dump_registers(struct saa7146_dev* dev)
{
	int i = 0;

	pr_info(" @ %li jiffies:\n", jiffies);
	for (i = 0; i <= 0x148; i += 4)
		pr_info("0x%03x: 0x%08x\n", i, saa7146_read(dev, i));
}
#endif

/****************************************************************************
 * gpio and debi helper functions
 ****************************************************************************/

void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data)
{
	u32 value = 0;

	BUG_ON(port > 3);

	value = saa7146_read(dev, GPIO_CTRL);
	value &= ~(0xff << (8*port));
	value |= (data << (8*port));
	saa7146_write(dev, GPIO_CTRL, value);
}

/* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */
static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev,
				unsigned long us1, unsigned long us2)
{
	unsigned long timeout;
	int err;

	/* wait for registers to be programmed */
	timeout = jiffies + usecs_to_jiffies(us1);
	while (1) {
		err = time_after(jiffies, timeout);
		if (saa7146_read(dev, MC2) & 2)
			break;
		if (err) {
			pr_debug("%s: %s timed out while waiting for registers getting programmed\n",
			       dev->name, __func__);
			return -ETIMEDOUT;
		}
		msleep(1);
	}

	/* wait for transfer to complete */
	timeout = jiffies + usecs_to_jiffies(us2);
	while (1) {
		err = time_after(jiffies, timeout);
		if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
			break;
		saa7146_read(dev, MC2);
		if (err) {
			DEB_S("%s: %s timed out while waiting for transfer completion\n",
			      dev->name, __func__);
			return -ETIMEDOUT;
		}
		msleep(1);
	}

	return 0;
}

static inline int saa7146_wait_for_debi_done_busyloop(struct saa7146_dev *dev,
				unsigned long us1, unsigned long us2)
{
	unsigned long loops;

	/* wait for registers to be programmed */
	loops = us1;
	while (1) {
		if (saa7146_read(dev, MC2) & 2)
			break;
		if (!loops--) {
			pr_err("%s: %s timed out while waiting for registers getting programmed\n",
			       dev->name, __func__);
			return -ETIMEDOUT;
		}
		udelay(1);
	}

	/* wait for transfer to complete */
	loops = us2 / 5;
	while (1) {
		if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
			break;
		saa7146_read(dev, MC2);
		if (!loops--) {
			DEB_S("%s: %s timed out while waiting for transfer completion\n",
			      dev->name, __func__);
			return -ETIMEDOUT;
		}
		udelay(5);
	}

	return 0;
}

int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
{
	if (nobusyloop)
		return saa7146_wait_for_debi_done_sleep(dev, 50000, 250000);
	else
		return saa7146_wait_for_debi_done_busyloop(dev, 50000, 250000);
}

/****************************************************************************
 * general helper functions
 ****************************************************************************/

/* this is videobuf_vmalloc_to_sg() from videobuf-dma-sg.c
   make sure virt has been allocated with vmalloc_32(), otherwise the BUG()
   may be triggered on highmem machines */
static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
{
	struct scatterlist *sglist;
	struct page *pg;
	int i;

	sglist = kmalloc_array(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
	if (NULL == sglist)
		return NULL;
	sg_init_table(sglist, nr_pages);
	for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
		pg = vmalloc_to_page(virt);
		if (NULL == pg)
			goto err;
		BUG_ON(PageHighMem(pg));
		sg_set_page(&sglist[i], pg, PAGE_SIZE, 0);
	}
	return sglist;

 err:
	kfree(sglist);
	return NULL;
}

/********************************************************************************/
/* common page table functions */

void *saa7146_vmalloc_build_pgtable(struct pci_dev *pci, long length, struct saa7146_pgtable *pt)
{
	int pages = (length+PAGE_SIZE-1)/PAGE_SIZE;
	void *mem = vmalloc_32(length);
	int slen = 0;

	if (NULL == mem)
		goto err_null;

	if (!(pt->slist = vmalloc_to_sg(mem, pages)))
		goto err_free_mem;

	if (saa7146_pgtable_alloc(pci, pt))
		goto err_free_slist;

	pt->nents = pages;
	slen = dma_map_sg(&pci->dev, pt->slist, pt->nents, DMA_FROM_DEVICE);
	if (0 == slen)
		goto err_free_pgtable;

	if (0 != saa7146_pgtable_build_single(pci, pt, pt->slist, slen))
		goto err_unmap_sg;

	return mem;

err_unmap_sg:
	dma_unmap_sg(&pci->dev, pt->slist, pt->nents, DMA_FROM_DEVICE);
err_free_pgtable:
	saa7146_pgtable_free(pci, pt);
err_free_slist:
	kfree(pt->slist);
	pt->slist = NULL;
err_free_mem:
	vfree(mem);
err_null:
	return NULL;
}

void saa7146_vfree_destroy_pgtable(struct pci_dev *pci, void *mem, struct saa7146_pgtable *pt)
{
	dma_unmap_sg(&pci->dev, pt->slist, pt->nents, DMA_FROM_DEVICE);
	saa7146_pgtable_free(pci, pt);
	kfree(pt->slist);
	pt->slist = NULL;
	vfree(mem);
}

void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt)
{
	if (NULL == pt->cpu)
		return;
	dma_free_coherent(&pci->dev, pt->size, pt->cpu, pt->dma);
	pt->cpu = NULL;
}

int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt)
{
	__le32       *cpu;
	dma_addr_t   dma_addr = 0;

	cpu = dma_alloc_coherent(&pci->dev, PAGE_SIZE, &dma_addr, GFP_KERNEL);
	if (NULL == cpu) {
		return -ENOMEM;
	}
	pt->size = PAGE_SIZE;
	pt->cpu  = cpu;
	pt->dma  = dma_addr;

	return 0;
}

int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt,
	struct scatterlist *list, int sglen  )
{
	__le32 *ptr, fill;
	int nr_pages = 0;
	int i,p;

	BUG_ON(0 == sglen);
	BUG_ON(list->offset > PAGE_SIZE);

	/* if we have a user buffer, the first page may not be
	   aligned to a page boundary. */
	pt->offset = list->offset;

	ptr = pt->cpu;
	for (i = 0; i < sglen; i++, list++) {
/*
		pr_debug("i:%d, adr:0x%08x, len:%d, offset:%d\n",
			 i, sg_dma_address(list), sg_dma_len(list),
			 list->offset);
*/
		for (p = 0; p * 4096 < sg_dma_len(list); p++, ptr++) {
			*ptr = cpu_to_le32(sg_dma_address(list) + p * 4096);
			nr_pages++;
		}
	}


	/* safety; fill the page table up with the last valid page */
	fill = *(ptr-1);
	for(i=nr_pages;i<1024;i++) {
		*ptr++ = fill;
	}

/*
	ptr = pt->cpu;
	pr_debug("offset: %d\n", pt->offset);
	for(i=0;i<5;i++) {
		pr_debug("ptr1 %d: 0x%08x\n", i, ptr[i]);
	}
*/
	return 0;
}

/********************************************************************************/
/* interrupt handler */
static irqreturn_t interrupt_hw(int irq, void *dev_id)
{
	struct saa7146_dev *dev = dev_id;
	u32 isr;
	u32 ack_isr;

	/* read out the interrupt status register */
	ack_isr = isr = saa7146_read(dev, ISR);

	/* is this our interrupt? */
	if ( 0 == isr ) {
		/* nope, some other device */
		return IRQ_NONE;
	}

	if (dev->ext) {
		if (dev->ext->irq_mask & isr) {
			if (dev->ext->irq_func)
				dev->ext->irq_func(dev, &isr);
			isr &= ~dev->ext->irq_mask;
		}
	}
	if (0 != (isr & (MASK_27))) {
		DEB_INT("irq: RPS0 (0x%08x)\n", isr);
		if (dev->vv_data && dev->vv_callback)
			dev->vv_callback(dev,isr);
		isr &= ~MASK_27;
	}
	if (0 != (isr & (MASK_28))) {
		if (dev->vv_data && dev->vv_callback)
			dev->vv_callback(dev,isr);
		isr &= ~MASK_28;
	}
	if (0 != (isr & (MASK_16|MASK_17))) {
		SAA7146_IER_DISABLE(dev, MASK_16|MASK_17);
		/* only wake up if we expect something */
		if (0 != dev->i2c_op) {
			dev->i2c_op = 0;
			wake_up(&dev->i2c_wq);
		} else {
			u32 psr = saa7146_read(dev, PSR);
			u32 ssr = saa7146_read(dev, SSR);
			pr_warn("%s: unexpected i2c irq: isr %08x psr %08x ssr %08x\n",
				dev->name, isr, psr, ssr);
		}
		isr &= ~(MASK_16|MASK_17);
	}
	if( 0 != isr ) {
		ERR("warning: interrupt enabled, but not handled properly.(0x%08x)\n",
		    isr);
		ERR("disabling interrupt source(s)!\n");
		SAA7146_IER_DISABLE(dev,isr);
	}
	saa7146_write(dev, ISR, ack_isr);
	return IRQ_HANDLED;
}

/*********************************************************************************/
/* configuration-functions                                                       */

static int saa7146_init_one(struct pci_dev *pci, const struct pci_device_id *ent)
{
	struct saa7146_pci_extension_data *pci_ext = (struct saa7146_pci_extension_data *)ent->driver_data;
	struct saa7146_extension *ext = pci_ext->ext;
	struct saa7146_dev *dev;
	int err = -ENOMEM;

	/* clear out mem for sure */
	dev = kzalloc(sizeof(struct saa7146_dev), GFP_KERNEL);
	if (!dev) {
		ERR("out of memory\n");
		goto out;
	}

	/* create a nice device name */
	sprintf(dev->name, "saa7146 (%d)", saa7146_num);

	DEB_EE("pci:%p\n", pci);

	err = pci_enable_device(pci);
	if (err < 0) {
		ERR("pci_enable_device() failed\n");
		goto err_free;
	}

	/* enable bus-mastering */
	pci_set_master(pci);

	dev->pci = pci;

	/* get chip-revision; this is needed to enable bug-fixes */
	dev->revision = pci->revision;

	/* remap the memory from virtual to physical address */

	err = pci_request_region(pci, 0, "saa7146");
	if (err < 0)
		goto err_disable;

	dev->mem = ioremap(pci_resource_start(pci, 0),
			   pci_resource_len(pci, 0));
	if (!dev->mem) {
		ERR("ioremap() failed\n");
		err = -ENODEV;
		goto err_release;
	}

	/* we don't do a master reset here anymore, it screws up
	   some boards that don't have an i2c-eeprom for configuration
	   values */
/*
	saa7146_write(dev, MC1, MASK_31);
*/

	/* disable all irqs */
	saa7146_write(dev, IER, 0);

	/* shut down all dma transfers and rps tasks */
	saa7146_write(dev, MC1, 0x30ff0000);

	/* clear out any rps-signals pending */
	saa7146_write(dev, MC2, 0xf8000000);

	/* request an interrupt for the saa7146 */
	err = request_irq(pci->irq, interrupt_hw, IRQF_SHARED,
			  dev->name, dev);
	if (err < 0) {
		ERR("request_irq() failed\n");
		goto err_unmap;
	}

	err = -ENOMEM;

	/* get memory for various stuff */
	dev->d_rps0.cpu_addr = dma_alloc_coherent(&pci->dev, SAA7146_RPS_MEM,
						  &dev->d_rps0.dma_handle,
						  GFP_KERNEL);
	if (!dev->d_rps0.cpu_addr)
		goto err_free_irq;

	dev->d_rps1.cpu_addr = dma_alloc_coherent(&pci->dev, SAA7146_RPS_MEM,
						  &dev->d_rps1.dma_handle,
						  GFP_KERNEL);
	if (!dev->d_rps1.cpu_addr)
		goto err_free_rps0;

	dev->d_i2c.cpu_addr = dma_alloc_coherent(&pci->dev, SAA7146_RPS_MEM,
						 &dev->d_i2c.dma_handle, GFP_KERNEL);
	if (!dev->d_i2c.cpu_addr)
		goto err_free_rps1;

	/* the rest + print status message */

	pr_info("found saa7146 @ mem %p (revision %d, irq %d) (0x%04x,0x%04x)\n",
		dev->mem, dev->revision, pci->irq,
		pci->subsystem_vendor, pci->subsystem_device);
	dev->ext = ext;

	mutex_init(&dev->v4l2_lock);
	spin_lock_init(&dev->int_slock);
	spin_lock_init(&dev->slock);

	mutex_init(&dev->i2c_lock);

	dev->module = THIS_MODULE;
	init_waitqueue_head(&dev->i2c_wq);

	/* set some sane pci arbitrition values */
	saa7146_write(dev, PCI_BT_V1, 0x1c00101f);

	/* TODO: use the status code of the callback */

	err = -ENODEV;

	if (ext->probe && ext->probe(dev)) {
		DEB_D("ext->probe() failed for %p. skipping device.\n", dev);
		goto err_free_i2c;
	}

	if (ext->attach(dev, pci_ext)) {
		DEB_D("ext->attach() failed for %p. skipping device.\n", dev);
		goto err_free_i2c;
	}
	/* V4L extensions will set the pci drvdata to the v4l2_device in the
	   attach() above. So for those cards that do not use V4L we have to
	   set it explicitly. */
	pci_set_drvdata(pci, &dev->v4l2_dev);

	saa7146_num++;

	err = 0;
out:
	return err;

err_free_i2c:
	dma_free_coherent(&pci->dev, SAA7146_RPS_MEM, dev->d_i2c.cpu_addr,
			  dev->d_i2c.dma_handle);
err_free_rps1:
	dma_free_coherent(&pci->dev, SAA7146_RPS_MEM, dev->d_rps1.cpu_addr,
			  dev->d_rps1.dma_handle);
err_free_rps0:
	dma_free_coherent(&pci->dev, SAA7146_RPS_MEM, dev->d_rps0.cpu_addr,
			  dev->d_rps0.dma_handle);
err_free_irq:
	free_irq(pci->irq, (void *)dev);
err_unmap:
	iounmap(dev->mem);
err_release:
	pci_release_region(pci, 0);
err_disable:
	pci_disable_device(pci);
err_free:
	kfree(dev);
	goto out;
}

static void saa7146_remove_one(struct pci_dev *pdev)
{
	struct v4l2_device *v4l2_dev = pci_get_drvdata(pdev);
	struct saa7146_dev *dev = to_saa7146_dev(v4l2_dev);
	struct {
		void *addr;
		dma_addr_t dma;
	} dev_map[] = {
		{ dev->d_i2c.cpu_addr, dev->d_i2c.dma_handle },
		{ dev->d_rps1.cpu_addr, dev->d_rps1.dma_handle },
		{ dev->d_rps0.cpu_addr, dev->d_rps0.dma_handle },
		{ NULL, 0 }
	}, *p;

	DEB_EE("dev:%p\n", dev);

	dev->ext->detach(dev);

	/* shut down all video dma transfers */
	saa7146_write(dev, MC1, 0x00ff0000);

	/* disable all irqs, release irq-routine */
	saa7146_write(dev, IER, 0);

	free_irq(pdev->irq, dev);

	for (p = dev_map; p->addr; p++)
		dma_free_coherent(&pdev->dev, SAA7146_RPS_MEM, p->addr,
				  p->dma);

	iounmap(dev->mem);
	pci_release_region(pdev, 0);
	pci_disable_device(pdev);
	kfree(dev);

	saa7146_num--;
}

/*********************************************************************************/
/* extension handling functions                                                  */

int saa7146_register_extension(struct saa7146_extension* ext)
{
	DEB_EE("ext:%p\n", ext);

	ext->driver.name = ext->name;
	ext->driver.id_table = ext->pci_tbl;
	ext->driver.probe = saa7146_init_one;
	ext->driver.remove = saa7146_remove_one;

	pr_info("register extension '%s'\n", ext->name);
	return pci_register_driver(&ext->driver);
}

int saa7146_unregister_extension(struct saa7146_extension* ext)
{
	DEB_EE("ext:%p\n", ext);
	pr_info("unregister extension '%s'\n", ext->name);
	pci_unregister_driver(&ext->driver);
	return 0;
}

EXPORT_SYMBOL_GPL(saa7146_register_extension);
EXPORT_SYMBOL_GPL(saa7146_unregister_extension);

/* misc functions used by extension modules */
EXPORT_SYMBOL_GPL(saa7146_pgtable_alloc);
EXPORT_SYMBOL_GPL(saa7146_pgtable_free);
EXPORT_SYMBOL_GPL(saa7146_pgtable_build_single);
EXPORT_SYMBOL_GPL(saa7146_vmalloc_build_pgtable);
EXPORT_SYMBOL_GPL(saa7146_vfree_destroy_pgtable);
EXPORT_SYMBOL_GPL(saa7146_wait_for_debi_done);

EXPORT_SYMBOL_GPL(saa7146_setgpio);

EXPORT_SYMBOL_GPL(saa7146_i2c_adapter_prepare);

EXPORT_SYMBOL_GPL(saa7146_debug);

MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
MODULE_DESCRIPTION("driver for generic saa7146-based hardware");
MODULE_LICENSE("GPL");
