#include <media/saa7146_vv.h>

#define BOARD_CAN_DO_VBI(dev)   (dev->revision != 0 && dev->vv_data->vbi_minor != -1) 

/****************************************************************************/
/* resource management functions, shamelessly stolen from saa7134 driver */

int saa7146_res_get(struct saa7146_fh *fh, unsigned int bit)
{
	struct saa7146_dev *dev = fh->dev;
	struct saa7146_vv *vv = dev->vv_data;

	if (fh->resources & bit) {
		DEB_D(("already allocated! want: 0x%02x, cur:0x%02x\n",bit,vv->resources));
		/* have it already allocated */
		return 1;
	}

	/* is it free? */
	down(&dev->lock);
	if (vv->resources & bit) {
		DEB_D(("locked! vv->resources:0x%02x, we want:0x%02x\n",vv->resources,bit));
		/* no, someone else uses it */
		up(&dev->lock);
		return 0;
	}
	/* it's free, grab it */
	fh->resources  |= bit;
	vv->resources |= bit;
	DEB_D(("res: get 0x%02x, cur:0x%02x\n",bit,vv->resources));
	up(&dev->lock);
	return 1;
}

void saa7146_res_free(struct saa7146_fh *fh, unsigned int bits)
{
	struct saa7146_dev *dev = fh->dev;
	struct saa7146_vv *vv = dev->vv_data;

	if ((fh->resources & bits) != bits)
		BUG();

	down(&dev->lock);
	fh->resources  &= ~bits;
	vv->resources &= ~bits;
	DEB_D(("res: put 0x%02x, cur:0x%02x\n",bits,vv->resources));
	up(&dev->lock);
}


/********************************************************************************/
/* common dma functions */

void saa7146_dma_free(struct saa7146_dev *dev,struct saa7146_buf *buf)
{
	DEB_EE(("dev:%p, buf:%p\n",dev,buf));

	if (in_interrupt())
		BUG();

	videobuf_waiton(&buf->vb,0,0);
	videobuf_dma_pci_unmap(dev->pci, &buf->vb.dma);
	videobuf_dma_free(&buf->vb.dma);
	buf->vb.state = STATE_NEEDS_INIT;
}


/********************************************************************************/
/* common buffer functions */

int saa7146_buffer_queue(struct saa7146_dev *dev,
			 struct saa7146_dmaqueue *q,
			 struct saa7146_buf *buf)
{
	assert_spin_locked(&dev->slock);
	DEB_EE(("dev:%p, dmaq:%p, buf:%p\n", dev, q, buf));

	BUG_ON(!q);

	if (NULL == q->curr) {
		q->curr = buf;
		DEB_D(("immediately activating buffer %p\n", buf));
		buf->activate(dev,buf,NULL);
	} else {
		list_add_tail(&buf->vb.queue,&q->queue);
		buf->vb.state = STATE_QUEUED;
		DEB_D(("adding buffer %p to queue. (active buffer present)\n", buf));
	}
	return 0;
}

void saa7146_buffer_finish(struct saa7146_dev *dev,
			   struct saa7146_dmaqueue *q,
			   int state)
{
	assert_spin_locked(&dev->slock);
	DEB_EE(("dev:%p, dmaq:%p, state:%d\n", dev, q, state));
	DEB_EE(("q->curr:%p\n",q->curr));

	BUG_ON(!q->curr);

	/* finish current buffer */
	if (NULL == q->curr) {
		DEB_D(("aiii. no current buffer\n"));
		return;	
	}
			
	q->curr->vb.state = state;
	do_gettimeofday(&q->curr->vb.ts);
	wake_up(&q->curr->vb.done);

	q->curr = NULL;
}

void saa7146_buffer_next(struct saa7146_dev *dev,
			 struct saa7146_dmaqueue *q, int vbi)
{
	struct saa7146_buf *buf,*next = NULL;

	BUG_ON(!q);

	DEB_INT(("dev:%p, dmaq:%p, vbi:%d\n", dev, q, vbi));

	assert_spin_locked(&dev->slock);
	if (!list_empty(&q->queue)) {
		/* activate next one from queue */
		buf = list_entry(q->queue.next,struct saa7146_buf,vb.queue);
		list_del(&buf->vb.queue);
		if (!list_empty(&q->queue))
			next = list_entry(q->queue.next,struct saa7146_buf, vb.queue);
		q->curr = buf;
		DEB_INT(("next buffer: buf:%p, prev:%p, next:%p\n", buf, q->queue.prev,q->queue.next));
		buf->activate(dev,buf,next);
	} else {
		DEB_INT(("no next buffer. stopping.\n"));
		if( 0 != vbi ) {
			/* turn off video-dma3 */
			saa7146_write(dev,MC1, MASK_20);
		} else {
			/* nothing to do -- just prevent next video-dma1 transfer
			   by lowering the protection address */

			// fixme: fix this for vflip != 0

			saa7146_write(dev, PROT_ADDR1, 0);
			saa7146_write(dev, MC2, (MASK_02|MASK_18));		

			/* write the address of the rps-program */
			saa7146_write(dev, RPS_ADDR0, dev->d_rps0.dma_handle);
			/* turn on rps */
			saa7146_write(dev, MC1, (MASK_12 | MASK_28));
				
/*
			printk("vdma%d.base_even:     0x%08x\n", 1,saa7146_read(dev,BASE_EVEN1));
			printk("vdma%d.base_odd:      0x%08x\n", 1,saa7146_read(dev,BASE_ODD1));
			printk("vdma%d.prot_addr:     0x%08x\n", 1,saa7146_read(dev,PROT_ADDR1));
			printk("vdma%d.base_page:     0x%08x\n", 1,saa7146_read(dev,BASE_PAGE1));
			printk("vdma%d.pitch:         0x%08x\n", 1,saa7146_read(dev,PITCH1));
			printk("vdma%d.num_line_byte: 0x%08x\n", 1,saa7146_read(dev,NUM_LINE_BYTE1));
*/
		}
		del_timer(&q->timeout);
	}
}

void saa7146_buffer_timeout(unsigned long data)
{
	struct saa7146_dmaqueue *q = (struct saa7146_dmaqueue*)data;
	struct saa7146_dev *dev = q->dev;
	unsigned long flags;

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

	spin_lock_irqsave(&dev->slock,flags);
	if (q->curr) {
		DEB_D(("timeout on %p\n", q->curr));
		saa7146_buffer_finish(dev,q,STATE_ERROR);
	}

	/* we don't restart the transfer here like other drivers do. when
	   a streaming capture is disabled, the timeout function will be
	   called for the current buffer. if we activate the next buffer now,
	   we mess up our capture logic. if a timeout occurs on another buffer,
	   then something is seriously broken before, so no need to buffer the
	   next capture IMHO... */
/*
	saa7146_buffer_next(dev,q);
*/
	spin_unlock_irqrestore(&dev->slock,flags);
}

/********************************************************************************/
/* file operations */

static int fops_open(struct inode *inode, struct file *file)
{
	unsigned int minor = iminor(inode);
	struct saa7146_dev *h = NULL, *dev = NULL;
	struct list_head *list;
	struct saa7146_fh *fh = NULL;
	int result = 0;

	enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

	DEB_EE(("inode:%p, file:%p, minor:%d\n",inode,file,minor));

	if (down_interruptible(&saa7146_devices_lock))
		return -ERESTARTSYS;

	list_for_each(list,&saa7146_devices) {
		h = list_entry(list, struct saa7146_dev, item);
		if( NULL == h->vv_data ) {
			DEB_D(("device %p has not registered video devices.\n",h));
			continue;
		}
		DEB_D(("trying: %p @ major %d,%d\n",h,h->vv_data->video_minor,h->vv_data->vbi_minor));

		if (h->vv_data->video_minor == minor) {
			dev = h;
		}
		if (h->vv_data->vbi_minor == minor) {
			type = V4L2_BUF_TYPE_VBI_CAPTURE;
			dev = h;
		}
	}
	if (NULL == dev) {
		DEB_S(("no such video device.\n"));
		result = -ENODEV;
		goto out;
	}

	DEB_D(("using: %p\n",dev));

	/* check if an extension is registered */
	if( NULL == dev->ext ) {
		DEB_S(("no extension registered for this device.\n"));
		result = -ENODEV;
		goto out;
	}

	/* allocate per open data */
	fh = kmalloc(sizeof(*fh),GFP_KERNEL);
	if (NULL == fh) {
		DEB_S(("cannot allocate memory for per open data.\n"));
		result = -ENOMEM;
		goto out;
	}
	memset(fh,0,sizeof(*fh));
	
	file->private_data = fh;
	fh->dev = dev;
	fh->type = type;

	if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
		DEB_S(("initializing vbi...\n"));
		result = saa7146_vbi_uops.open(dev,file);
	} else {
		DEB_S(("initializing video...\n"));
		result = saa7146_video_uops.open(dev,file);
	}

	if (0 != result) {
		goto out;
	}

	if( 0 == try_module_get(dev->ext->module)) {
		result = -EINVAL;
		goto out;
	}

	result = 0;
out:
	if( fh != 0 && result != 0 ) {
		kfree(fh);
		file->private_data = NULL;
	}
	up(&saa7146_devices_lock);
        return result;
}

static int fops_release(struct inode *inode, struct file *file)
{
	struct saa7146_fh  *fh  = file->private_data;
	struct saa7146_dev *dev = fh->dev;

	DEB_EE(("inode:%p, file:%p\n",inode,file));

	if (down_interruptible(&saa7146_devices_lock))
		return -ERESTARTSYS;

	if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
		saa7146_vbi_uops.release(dev,file);
	} else {
		saa7146_video_uops.release(dev,file);
	}

	module_put(dev->ext->module);
	file->private_data = NULL;
	kfree(fh);

	up(&saa7146_devices_lock);

	return 0;
}

int saa7146_video_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg);
static int fops_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
/*
	DEB_EE(("inode:%p, file:%p, cmd:%d, arg:%li\n",inode, file, cmd, arg));
*/
	return video_usercopy(inode, file, cmd, arg, saa7146_video_do_ioctl);
}

static int fops_mmap(struct file *file, struct vm_area_struct * vma)
{
	struct saa7146_fh *fh = file->private_data;
	struct videobuf_queue *q;

	switch (fh->type) {
	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
		DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, vma:%p\n",file, vma));
		q = &fh->video_q;
		break;
		}
	case V4L2_BUF_TYPE_VBI_CAPTURE: {
		DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, vma:%p\n",file, vma));
		q = &fh->vbi_q;
		break;
		}
	default:
		BUG();
		return 0;
	}
	return videobuf_mmap_mapper(q,vma);
}

static unsigned int fops_poll(struct file *file, struct poll_table_struct *wait)
{
	struct saa7146_fh *fh = file->private_data;
	struct videobuf_buffer *buf = NULL;
	struct videobuf_queue *q;

	DEB_EE(("file:%p, poll:%p\n",file, wait));

	if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
		if( 0 == fh->vbi_q.streaming )
			return videobuf_poll_stream(file, &fh->vbi_q, wait);
		q = &fh->vbi_q;
	} else {
		DEB_D(("using video queue.\n"));
		q = &fh->video_q;
	}

	if (!list_empty(&q->stream))
		buf = list_entry(q->stream.next, struct videobuf_buffer, stream);

	if (!buf) {
		DEB_D(("buf == NULL!\n"));
		return POLLERR;
	}

	poll_wait(file, &buf->done, wait);
	if (buf->state == STATE_DONE || buf->state == STATE_ERROR) {
		DEB_D(("poll succeeded!\n"));
		return POLLIN|POLLRDNORM;
	}

	DEB_D(("nothing to poll for, buf->state:%d\n",buf->state));
	return 0;
}

static ssize_t fops_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
{
	struct saa7146_fh *fh = file->private_data;

	switch (fh->type) {
	case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
//		DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: file:%p, data:%p, count:%lun", file, data, (unsigned long)count));
		return saa7146_video_uops.read(file,data,count,ppos);
		}
	case V4L2_BUF_TYPE_VBI_CAPTURE: {
//		DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count));
		return saa7146_vbi_uops.read(file,data,count,ppos);
		}
		break;
	default:
		BUG();
		return 0;
	}
}

static struct file_operations video_fops =
{
	.owner		= THIS_MODULE,
	.open		= fops_open,
	.release	= fops_release,
	.read		= fops_read,
	.poll		= fops_poll,
	.mmap		= fops_mmap,
	.ioctl		= fops_ioctl,
	.llseek		= no_llseek,
};

static void vv_callback(struct saa7146_dev *dev, unsigned long status)
{
	u32 isr = status;
	
	DEB_INT(("dev:%p, isr:0x%08x\n",dev,(u32)status));

	if (0 != (isr & (MASK_27))) {
		DEB_INT(("irq: RPS0 (0x%08x).\n",isr));
		saa7146_video_uops.irq_done(dev,isr);
	}

	if (0 != (isr & (MASK_28))) {
		u32 mc2 = saa7146_read(dev, MC2);
		if( 0 != (mc2 & MASK_15)) {
			DEB_INT(("irq: RPS1 vbi workaround (0x%08x).\n",isr));
			wake_up(&dev->vv_data->vbi_wq);
			saa7146_write(dev,MC2, MASK_31);
			return;
		}
		DEB_INT(("irq: RPS1 (0x%08x).\n",isr));
		saa7146_vbi_uops.irq_done(dev,isr);
	}
}

static struct video_device device_template =
{
	.hardware	= VID_HARDWARE_SAA7146,
	.fops		= &video_fops,
	.minor		= -1,
};

int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
{
	struct saa7146_vv *vv = kmalloc (sizeof(struct saa7146_vv),GFP_KERNEL);
	if( NULL == vv ) {
		ERR(("out of memory. aborting.\n"));
		return -1;
	}
	memset(vv, 0x0, sizeof(*vv));

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

	/* set default values for video parts of the saa7146 */
	saa7146_write(dev, BCS_CTRL, 0x80400040);

	/* enable video-port pins */
	saa7146_write(dev, MC1, (MASK_10 | MASK_26));

	/* save per-device extension data (one extension can
	   handle different devices that might need different
	   configuration data) */
	dev->ext_vv_data = ext_vv;
	
	vv->video_minor = -1;
	vv->vbi_minor = -1;

	vv->d_clipping.cpu_addr = pci_alloc_consistent(dev->pci, SAA7146_CLIPPING_MEM, &vv->d_clipping.dma_handle);	
	if( NULL == vv->d_clipping.cpu_addr ) {
		ERR(("out of memory. aborting.\n"));
		kfree(vv);
		return -1;
	}
	memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM);

	saa7146_video_uops.init(dev,vv);
	saa7146_vbi_uops.init(dev,vv);
	
	dev->vv_data = vv;
	dev->vv_callback = &vv_callback;

	return 0;
}

int saa7146_vv_release(struct saa7146_dev* dev)
{
	struct saa7146_vv *vv = dev->vv_data;

	DEB_EE(("dev:%p\n",dev));
 
	pci_free_consistent(dev->pci, SAA7146_RPS_MEM, vv->d_clipping.cpu_addr, vv->d_clipping.dma_handle);
 	kfree(vv);
	dev->vv_data = NULL;
	dev->vv_callback = NULL;
	
	return 0;
}

int saa7146_register_device(struct video_device **vid, struct saa7146_dev* dev,
			    char *name, int type)
{
	struct saa7146_vv *vv = dev->vv_data;
	struct video_device *vfd;

	DEB_EE(("dev:%p, name:'%s', type:%d\n",dev,name,type));

	// released by vfd->release
 	vfd = video_device_alloc();
	if (vfd == NULL)
		return -ENOMEM;

	memcpy(vfd, &device_template, sizeof(struct video_device));
	strlcpy(vfd->name, name, sizeof(vfd->name));
	vfd->release = video_device_release;
	vfd->priv = dev;

	// fixme: -1 should be an insmod parameter *for the extension* (like "video_nr");
	if (video_register_device(vfd, type, -1) < 0) {
		ERR(("cannot register v4l2 device. skipping.\n"));
		return -1;
	}

	if( VFL_TYPE_GRABBER == type ) {
		vv->video_minor = vfd->minor;
		INFO(("%s: registered device video%d [v4l2]\n",
			dev->name, vfd->minor & 0x1f));
	} else {
		vv->vbi_minor = vfd->minor;
		INFO(("%s: registered device vbi%d [v4l2]\n",
			dev->name, vfd->minor & 0x1f));
	}

	*vid = vfd;
	return 0;
}

int saa7146_unregister_device(struct video_device **vid, struct saa7146_dev* dev)
{
	struct saa7146_vv *vv = dev->vv_data;
	
	DEB_EE(("dev:%p\n",dev));

	if( VFL_TYPE_GRABBER == (*vid)->type ) {
		vv->video_minor = -1;
	} else {
		vv->vbi_minor = -1;
	}

	video_unregister_device(*vid);
	*vid = NULL;

	return 0;
}

static int __init saa7146_vv_init_module(void)
{
	return 0;
}


static void __exit saa7146_vv_cleanup_module(void)
{
}

module_init(saa7146_vv_init_module);
module_exit(saa7146_vv_cleanup_module);

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