1/***************************************************************************
2 *   Copyright (C) 2006-2010 by Marin Mitov                                *
3 *   mitov@issp.bas.bg                                                     *
4 *                                                                         *
5 *   This program is free software; you can redistribute it and/or modify  *
6 *   it under the terms of the GNU General Public License as published by  *
7 *   the Free Software Foundation; either version 2 of the License, or     *
8 *   (at your option) any later version.                                   *
9 *                                                                         *
10 *   This program is distributed in the hope that it will be useful,       *
11 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13 *   GNU General Public License for more details.                          *
14 *                                                                         *
15 *   You should have received a copy of the GNU General Public License     *
16 *   along with this program; if not, write to the                         *
17 *   Free Software Foundation, Inc.,                                       *
18 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19 ***************************************************************************/
20
21#include <linux/module.h>
22#include <linux/version.h>
23#include <linux/stringify.h>
24#include <linux/delay.h>
25#include <linux/kthread.h>
26#include <linux/slab.h>
27#include <media/v4l2-dev.h>
28#include <media/v4l2-ioctl.h>
29#include <media/v4l2-common.h>
30#include <media/videobuf2-dma-contig.h>
31
32#include "dt3155v4l.h"
33
34#define DT3155_DEVICE_ID 0x1223
35
36/* DT3155_CHUNK_SIZE is 4M (2^22) 8 full size buffers */
37#define DT3155_CHUNK_SIZE (1U << 22)
38
39#define DT3155_COH_FLAGS (GFP_KERNEL | GFP_DMA32 | __GFP_COLD | __GFP_NOWARN)
40
41#define DT3155_BUF_SIZE (768 * 576)
42
43#ifdef CONFIG_DT3155_STREAMING
44#define DT3155_CAPTURE_METHOD V4L2_CAP_STREAMING
45#else
46#define DT3155_CAPTURE_METHOD V4L2_CAP_READWRITE
47#endif
48
49/*  global initializers (for all boards)  */
50#ifdef CONFIG_DT3155_CCIR
51static const u8 csr2_init = VT_50HZ;
52#define DT3155_CURRENT_NORM V4L2_STD_625_50
53static const unsigned int img_width = 768;
54static const unsigned int img_height = 576;
55static const unsigned int frames_per_sec = 25;
56static const struct v4l2_fmtdesc frame_std[] = {
57	{
58	.index = 0,
59	.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
60	.flags = 0,
61	.description = "CCIR/50Hz 8 bits gray",
62	.pixelformat = V4L2_PIX_FMT_GREY,
63	},
64};
65#else
66static const u8 csr2_init = VT_60HZ;
67#define DT3155_CURRENT_NORM V4L2_STD_525_60
68static const unsigned int img_width = 640;
69static const unsigned int img_height = 480;
70static const unsigned int frames_per_sec = 30;
71static const struct v4l2_fmtdesc frame_std[] = {
72	{
73	.index = 0,
74	.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
75	.flags = 0,
76	.description = "RS-170/60Hz 8 bits gray",
77	.pixelformat = V4L2_PIX_FMT_GREY,
78	},
79};
80#endif
81
82#define NUM_OF_FORMATS ARRAY_SIZE(frame_std)
83
84static u8 config_init = ACQ_MODE_EVEN;
85
86/**
87 * read_i2c_reg - reads an internal i2c register
88 *
89 * @addr:	dt3155 mmio base address
90 * @index:	index (internal address) of register to read
91 * @data:	pointer to byte the read data will be placed in
92 *
93 * returns:	zero on success or error code
94 *
95 * This function starts reading the specified (by index) register
96 * and busy waits for the process to finish. The result is placed
97 * in a byte pointed by data.
98 */
99static int
100read_i2c_reg(void __iomem *addr, u8 index, u8 *data)
101{
102	u32 tmp = index;
103
104	iowrite32((tmp<<17) | IIC_READ, addr + IIC_CSR2);
105	mmiowb();
106	udelay(45); /* wait at least 43 usec for NEW_CYCLE to clear */
107	if (ioread32(addr + IIC_CSR2) & NEW_CYCLE)
108		return -EIO; /* error: NEW_CYCLE not cleared */
109	tmp = ioread32(addr + IIC_CSR1);
110	if (tmp & DIRECT_ABORT) {
111		/* reset DIRECT_ABORT bit */
112		iowrite32(DIRECT_ABORT, addr + IIC_CSR1);
113		return -EIO; /* error: DIRECT_ABORT set */
114	}
115	*data = tmp>>24;
116	return 0;
117}
118
119/**
120 * write_i2c_reg - writes to an internal i2c register
121 *
122 * @addr:	dt3155 mmio base address
123 * @index:	index (internal address) of register to read
124 * @data:	data to be written
125 *
126 * returns:	zero on success or error code
127 *
128 * This function starts writting the specified (by index) register
129 * and busy waits for the process to finish.
130 */
131static int
132write_i2c_reg(void __iomem *addr, u8 index, u8 data)
133{
134	u32 tmp = index;
135
136	iowrite32((tmp<<17) | IIC_WRITE | data, addr + IIC_CSR2);
137	mmiowb();
138	udelay(65); /* wait at least 63 usec for NEW_CYCLE to clear */
139	if (ioread32(addr + IIC_CSR2) & NEW_CYCLE)
140		return -EIO; /* error: NEW_CYCLE not cleared */
141	if (ioread32(addr + IIC_CSR1) & DIRECT_ABORT) {
142		/* reset DIRECT_ABORT bit */
143		iowrite32(DIRECT_ABORT, addr + IIC_CSR1);
144		return -EIO; /* error: DIRECT_ABORT set */
145	}
146	return 0;
147}
148
149/**
150 * write_i2c_reg_nowait - writes to an internal i2c register
151 *
152 * @addr:	dt3155 mmio base address
153 * @index:	index (internal address) of register to read
154 * @data:	data to be written
155 *
156 * This function starts writting the specified (by index) register
157 * and then returns.
158 */
159static void write_i2c_reg_nowait(void __iomem *addr, u8 index, u8 data)
160{
161	u32 tmp = index;
162
163	iowrite32((tmp<<17) | IIC_WRITE | data, addr + IIC_CSR2);
164	mmiowb();
165}
166
167/**
168 * wait_i2c_reg - waits the read/write to finish
169 *
170 * @addr:	dt3155 mmio base address
171 *
172 * returns:	zero on success or error code
173 *
174 * This function waits reading/writting to finish.
175 */
176static int wait_i2c_reg(void __iomem *addr)
177{
178	if (ioread32(addr + IIC_CSR2) & NEW_CYCLE)
179		udelay(65); /* wait at least 63 usec for NEW_CYCLE to clear */
180	if (ioread32(addr + IIC_CSR2) & NEW_CYCLE)
181		return -EIO; /* error: NEW_CYCLE not cleared */
182	if (ioread32(addr + IIC_CSR1) & DIRECT_ABORT) {
183		/* reset DIRECT_ABORT bit */
184		iowrite32(DIRECT_ABORT, addr + IIC_CSR1);
185		return -EIO; /* error: DIRECT_ABORT set */
186	}
187	return 0;
188}
189
190static int
191dt3155_start_acq(struct dt3155_priv *pd)
192{
193	struct vb2_buffer *vb = pd->curr_buf;
194	dma_addr_t dma_addr;
195
196	dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0);
197	iowrite32(dma_addr, pd->regs + EVEN_DMA_START);
198	iowrite32(dma_addr + img_width, pd->regs + ODD_DMA_START);
199	iowrite32(img_width, pd->regs + EVEN_DMA_STRIDE);
200	iowrite32(img_width, pd->regs + ODD_DMA_STRIDE);
201	/* enable interrupts, clear all irq flags */
202	iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START |
203			FLD_END_EVEN | FLD_END_ODD, pd->regs + INT_CSR);
204	iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN |
205		  FLD_DN_ODD | FLD_DN_EVEN | CAP_CONT_EVEN | CAP_CONT_ODD,
206							pd->regs + CSR1);
207	wait_i2c_reg(pd->regs);
208	write_i2c_reg(pd->regs, CONFIG, pd->config);
209	write_i2c_reg(pd->regs, EVEN_CSR, CSR_ERROR | CSR_DONE);
210	write_i2c_reg(pd->regs, ODD_CSR, CSR_ERROR | CSR_DONE);
211
212	/*  start the board  */
213	write_i2c_reg(pd->regs, CSR2, pd->csr2 | BUSY_EVEN | BUSY_ODD);
214	return 0; /* success  */
215}
216
217/*
218 *	driver-specific callbacks (vb2_ops)
219 */
220static int
221dt3155_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
222		unsigned int *num_buffers, unsigned int *num_planes,
223		unsigned int sizes[], void *alloc_ctxs[])
224
225{
226	struct dt3155_priv *pd = vb2_get_drv_priv(q);
227	void *ret;
228
229	if (*num_buffers == 0)
230		*num_buffers = 1;
231	*num_planes = 1;
232	sizes[0] = img_width * img_height;
233	if (pd->q->alloc_ctx[0])
234		return 0;
235	ret = vb2_dma_contig_init_ctx(&pd->pdev->dev);
236	if (IS_ERR(ret))
237		return PTR_ERR(ret);
238	pd->q->alloc_ctx[0] = ret;
239	return 0;
240}
241
242static void
243dt3155_wait_prepare(struct vb2_queue *q)
244{
245	struct dt3155_priv *pd = vb2_get_drv_priv(q);
246
247	mutex_unlock(pd->vdev.lock);
248}
249
250static void
251dt3155_wait_finish(struct vb2_queue *q)
252{
253	struct dt3155_priv *pd = vb2_get_drv_priv(q);
254
255	mutex_lock(pd->vdev.lock);
256}
257
258static int
259dt3155_buf_prepare(struct vb2_buffer *vb)
260{
261	vb2_set_plane_payload(vb, 0, img_width * img_height);
262	return 0;
263}
264
265static void
266dt3155_stop_streaming(struct vb2_queue *q)
267{
268	struct dt3155_priv *pd = vb2_get_drv_priv(q);
269	struct vb2_buffer *vb;
270
271	spin_lock_irq(&pd->lock);
272	while (!list_empty(&pd->dmaq)) {
273		vb = list_first_entry(&pd->dmaq, typeof(*vb), done_entry);
274		list_del(&vb->done_entry);
275		vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
276	}
277	spin_unlock_irq(&pd->lock);
278	msleep(45); /* irq hendler will stop the hardware */
279}
280
281static void
282dt3155_buf_queue(struct vb2_buffer *vb)
283{
284	struct dt3155_priv *pd = vb2_get_drv_priv(vb->vb2_queue);
285
286	/*  pd->q->streaming = 1 when dt3155_buf_queue() is invoked  */
287	spin_lock_irq(&pd->lock);
288	if (pd->curr_buf)
289		list_add_tail(&vb->done_entry, &pd->dmaq);
290	else {
291		pd->curr_buf = vb;
292		dt3155_start_acq(pd);
293	}
294	spin_unlock_irq(&pd->lock);
295}
296/*
297 *	end driver-specific callbacks
298 */
299
300static const struct vb2_ops q_ops = {
301	.queue_setup = dt3155_queue_setup,
302	.wait_prepare = dt3155_wait_prepare,
303	.wait_finish = dt3155_wait_finish,
304	.buf_prepare = dt3155_buf_prepare,
305	.stop_streaming = dt3155_stop_streaming,
306	.buf_queue = dt3155_buf_queue,
307};
308
309static irqreturn_t
310dt3155_irq_handler_even(int irq, void *dev_id)
311{
312	struct dt3155_priv *ipd = dev_id;
313	struct vb2_buffer *ivb;
314	dma_addr_t dma_addr;
315	u32 tmp;
316
317	tmp = ioread32(ipd->regs + INT_CSR) & (FLD_START | FLD_END_ODD);
318	if (!tmp)
319		return IRQ_NONE;  /* not our irq */
320	if ((tmp & FLD_START) && !(tmp & FLD_END_ODD)) {
321		iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START,
322							ipd->regs + INT_CSR);
323		ipd->field_count++;
324		return IRQ_HANDLED; /* start of field irq */
325	}
326	if ((tmp & FLD_START) && (tmp & FLD_END_ODD))
327		ipd->stats.start_before_end++;
328	/*	check for corrupted fields     */
329/*	write_i2c_reg(ipd->regs, EVEN_CSR, CSR_ERROR | CSR_DONE);	*/
330/*	write_i2c_reg(ipd->regs, ODD_CSR, CSR_ERROR | CSR_DONE);	*/
331	tmp = ioread32(ipd->regs + CSR1) & (FLD_CRPT_EVEN | FLD_CRPT_ODD);
332	if (tmp) {
333		ipd->stats.corrupted_fields++;
334		iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN |
335						FLD_DN_ODD | FLD_DN_EVEN |
336						CAP_CONT_EVEN | CAP_CONT_ODD,
337							ipd->regs + CSR1);
338		mmiowb();
339	}
340
341	spin_lock(&ipd->lock);
342	if (ipd->curr_buf) {
343		v4l2_get_timestamp(&ipd->curr_buf->v4l2_buf.timestamp);
344		ipd->curr_buf->v4l2_buf.sequence = (ipd->field_count) >> 1;
345		vb2_buffer_done(ipd->curr_buf, VB2_BUF_STATE_DONE);
346	}
347
348	if (!ipd->q->streaming || list_empty(&ipd->dmaq))
349		goto stop_dma;
350	ivb = list_first_entry(&ipd->dmaq, typeof(*ivb), done_entry);
351	list_del(&ivb->done_entry);
352	ipd->curr_buf = ivb;
353	dma_addr = vb2_dma_contig_plane_dma_addr(ivb, 0);
354	iowrite32(dma_addr, ipd->regs + EVEN_DMA_START);
355	iowrite32(dma_addr + img_width, ipd->regs + ODD_DMA_START);
356	iowrite32(img_width, ipd->regs + EVEN_DMA_STRIDE);
357	iowrite32(img_width, ipd->regs + ODD_DMA_STRIDE);
358	mmiowb();
359	/* enable interrupts, clear all irq flags */
360	iowrite32(FLD_START_EN | FLD_END_ODD_EN | FLD_START |
361			FLD_END_EVEN | FLD_END_ODD, ipd->regs + INT_CSR);
362	spin_unlock(&ipd->lock);
363	return IRQ_HANDLED;
364
365stop_dma:
366	ipd->curr_buf = NULL;
367	/* stop the board */
368	write_i2c_reg_nowait(ipd->regs, CSR2, ipd->csr2);
369	iowrite32(FIFO_EN | SRST | FLD_CRPT_ODD | FLD_CRPT_EVEN |
370		  FLD_DN_ODD | FLD_DN_EVEN, ipd->regs + CSR1);
371	/* disable interrupts, clear all irq flags */
372	iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD, ipd->regs + INT_CSR);
373	spin_unlock(&ipd->lock);
374	return IRQ_HANDLED;
375}
376
377static int
378dt3155_open(struct file *filp)
379{
380	int ret = 0;
381	struct dt3155_priv *pd = video_drvdata(filp);
382
383	if (mutex_lock_interruptible(&pd->mux))
384		return -ERESTARTSYS;
385	if (!pd->users) {
386		pd->q = kzalloc(sizeof(*pd->q), GFP_KERNEL);
387		if (!pd->q) {
388			ret = -ENOMEM;
389			goto err_alloc_queue;
390		}
391		pd->q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
392		pd->q->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
393		pd->q->io_modes = VB2_READ | VB2_MMAP;
394		pd->q->ops = &q_ops;
395		pd->q->mem_ops = &vb2_dma_contig_memops;
396		pd->q->drv_priv = pd;
397		pd->curr_buf = NULL;
398		pd->field_count = 0;
399		ret = vb2_queue_init(pd->q);
400		if (ret < 0)
401			goto err_request_irq;
402		INIT_LIST_HEAD(&pd->dmaq);
403		spin_lock_init(&pd->lock);
404		/* disable all irqs, clear all irq flags */
405		iowrite32(FLD_START | FLD_END_EVEN | FLD_END_ODD,
406						pd->regs + INT_CSR);
407		ret = request_irq(pd->pdev->irq, dt3155_irq_handler_even,
408						IRQF_SHARED, DT3155_NAME, pd);
409		if (ret)
410			goto err_request_irq;
411	}
412	pd->users++;
413	mutex_unlock(&pd->mux);
414	return 0; /* success */
415err_request_irq:
416	kfree(pd->q);
417	pd->q = NULL;
418err_alloc_queue:
419	mutex_unlock(&pd->mux);
420	return ret;
421}
422
423static int
424dt3155_release(struct file *filp)
425{
426	struct dt3155_priv *pd = video_drvdata(filp);
427
428	mutex_lock(&pd->mux);
429	pd->users--;
430	BUG_ON(pd->users < 0);
431	if (!pd->users) {
432		vb2_queue_release(pd->q);
433		free_irq(pd->pdev->irq, pd);
434		if (pd->q->alloc_ctx[0])
435			vb2_dma_contig_cleanup_ctx(pd->q->alloc_ctx[0]);
436		kfree(pd->q);
437		pd->q = NULL;
438	}
439	mutex_unlock(&pd->mux);
440	return 0;
441}
442
443static ssize_t
444dt3155_read(struct file *filp, char __user *user, size_t size, loff_t *loff)
445{
446	struct dt3155_priv *pd = video_drvdata(filp);
447	ssize_t res;
448
449	if (mutex_lock_interruptible(&pd->mux))
450		return -ERESTARTSYS;
451	res = vb2_read(pd->q, user, size, loff, filp->f_flags & O_NONBLOCK);
452	mutex_unlock(&pd->mux);
453	return res;
454}
455
456static unsigned int
457dt3155_poll(struct file *filp, struct poll_table_struct *polltbl)
458{
459	struct dt3155_priv *pd = video_drvdata(filp);
460	unsigned int res;
461
462	mutex_lock(&pd->mux);
463	res = vb2_poll(pd->q, filp, polltbl);
464	mutex_unlock(&pd->mux);
465	return res;
466}
467
468static int
469dt3155_mmap(struct file *filp, struct vm_area_struct *vma)
470{
471	struct dt3155_priv *pd = video_drvdata(filp);
472	int res;
473
474	if (mutex_lock_interruptible(&pd->mux))
475		return -ERESTARTSYS;
476	res = vb2_mmap(pd->q, vma);
477	mutex_unlock(&pd->mux);
478	return res;
479}
480
481static const struct v4l2_file_operations dt3155_fops = {
482	.owner = THIS_MODULE,
483	.open = dt3155_open,
484	.release = dt3155_release,
485	.read = dt3155_read,
486	.poll = dt3155_poll,
487	.unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */
488	.mmap = dt3155_mmap,
489};
490
491static int
492dt3155_ioc_streamon(struct file *filp, void *p, enum v4l2_buf_type type)
493{
494	struct dt3155_priv *pd = video_drvdata(filp);
495
496	return vb2_streamon(pd->q, type);
497}
498
499static int
500dt3155_ioc_streamoff(struct file *filp, void *p, enum v4l2_buf_type type)
501{
502	struct dt3155_priv *pd = video_drvdata(filp);
503
504	return vb2_streamoff(pd->q, type);
505}
506
507static int
508dt3155_ioc_querycap(struct file *filp, void *p, struct v4l2_capability *cap)
509{
510	struct dt3155_priv *pd = video_drvdata(filp);
511
512	strcpy(cap->driver, DT3155_NAME);
513	strcpy(cap->card, DT3155_NAME " frame grabber");
514	sprintf(cap->bus_info, "PCI:%s", pci_name(pd->pdev));
515	cap->device_caps = V4L2_CAP_VIDEO_CAPTURE |
516				DT3155_CAPTURE_METHOD;
517	cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
518	return 0;
519}
520
521static int
522dt3155_ioc_enum_fmt_vid_cap(struct file *filp, void *p, struct v4l2_fmtdesc *f)
523{
524	if (f->index >= NUM_OF_FORMATS)
525		return -EINVAL;
526	*f = frame_std[f->index];
527	return 0;
528}
529
530static int
531dt3155_ioc_g_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f)
532{
533	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
534		return -EINVAL;
535	f->fmt.pix.width = img_width;
536	f->fmt.pix.height = img_height;
537	f->fmt.pix.pixelformat = V4L2_PIX_FMT_GREY;
538	f->fmt.pix.field = V4L2_FIELD_NONE;
539	f->fmt.pix.bytesperline = f->fmt.pix.width;
540	f->fmt.pix.sizeimage = f->fmt.pix.width * f->fmt.pix.height;
541	f->fmt.pix.colorspace = 0;
542	f->fmt.pix.priv = 0;
543	return 0;
544}
545
546static int
547dt3155_ioc_try_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f)
548{
549	if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
550		return -EINVAL;
551	if (f->fmt.pix.width == img_width &&
552		f->fmt.pix.height == img_height &&
553		f->fmt.pix.pixelformat == V4L2_PIX_FMT_GREY &&
554		f->fmt.pix.field == V4L2_FIELD_NONE &&
555		f->fmt.pix.bytesperline == f->fmt.pix.width &&
556		f->fmt.pix.sizeimage == f->fmt.pix.width * f->fmt.pix.height)
557			return 0;
558	else
559		return -EINVAL;
560}
561
562static int
563dt3155_ioc_s_fmt_vid_cap(struct file *filp, void *p, struct v4l2_format *f)
564{
565	return dt3155_ioc_g_fmt_vid_cap(filp, p, f);
566}
567
568static int
569dt3155_ioc_reqbufs(struct file *filp, void *p, struct v4l2_requestbuffers *b)
570{
571	struct dt3155_priv *pd = video_drvdata(filp);
572
573	return vb2_reqbufs(pd->q, b);
574}
575
576static int
577dt3155_ioc_querybuf(struct file *filp, void *p, struct v4l2_buffer *b)
578{
579	struct dt3155_priv *pd = video_drvdata(filp);
580
581	return vb2_querybuf(pd->q, b);
582}
583
584static int
585dt3155_ioc_qbuf(struct file *filp, void *p, struct v4l2_buffer *b)
586{
587	struct dt3155_priv *pd = video_drvdata(filp);
588
589	return vb2_qbuf(pd->q, b);
590}
591
592static int
593dt3155_ioc_dqbuf(struct file *filp, void *p, struct v4l2_buffer *b)
594{
595	struct dt3155_priv *pd = video_drvdata(filp);
596
597	return vb2_dqbuf(pd->q, b, filp->f_flags & O_NONBLOCK);
598}
599
600static int
601dt3155_ioc_querystd(struct file *filp, void *p, v4l2_std_id *norm)
602{
603	*norm = DT3155_CURRENT_NORM;
604	return 0;
605}
606
607static int
608dt3155_ioc_g_std(struct file *filp, void *p, v4l2_std_id *norm)
609{
610	*norm = DT3155_CURRENT_NORM;
611	return 0;
612}
613
614static int
615dt3155_ioc_s_std(struct file *filp, void *p, v4l2_std_id norm)
616{
617	if (norm & DT3155_CURRENT_NORM)
618		return 0;
619	return -EINVAL;
620}
621
622static int
623dt3155_ioc_enum_input(struct file *filp, void *p, struct v4l2_input *input)
624{
625	if (input->index)
626		return -EINVAL;
627	strcpy(input->name, "Coax in");
628	input->type = V4L2_INPUT_TYPE_CAMERA;
629	/*
630	 * FIXME: input->std = 0 according to v4l2 API
631	 * VIDIOC_G_STD, VIDIOC_S_STD, VIDIOC_QUERYSTD and VIDIOC_ENUMSTD
632	 * should return -EINVAL
633	 */
634	input->std = DT3155_CURRENT_NORM;
635	input->status = 0;/* FIXME: add sync detection & V4L2_IN_ST_NO_H_LOCK */
636	return 0;
637}
638
639static int
640dt3155_ioc_g_input(struct file *filp, void *p, unsigned int *i)
641{
642	*i = 0;
643	return 0;
644}
645
646static int
647dt3155_ioc_s_input(struct file *filp, void *p, unsigned int i)
648{
649	if (i)
650		return -EINVAL;
651	return 0;
652}
653
654static int
655dt3155_ioc_g_parm(struct file *filp, void *p, struct v4l2_streamparm *parms)
656{
657	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
658		return -EINVAL;
659	parms->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
660	parms->parm.capture.capturemode = 0;
661	parms->parm.capture.timeperframe.numerator = 1001;
662	parms->parm.capture.timeperframe.denominator = frames_per_sec * 1000;
663	parms->parm.capture.extendedmode = 0;
664	parms->parm.capture.readbuffers = 1; /* FIXME: 2 buffers? */
665	return 0;
666}
667
668static int
669dt3155_ioc_s_parm(struct file *filp, void *p, struct v4l2_streamparm *parms)
670{
671	if (parms->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
672		return -EINVAL;
673	parms->parm.capture.capability = V4L2_CAP_TIMEPERFRAME;
674	parms->parm.capture.capturemode = 0;
675	parms->parm.capture.timeperframe.numerator = 1001;
676	parms->parm.capture.timeperframe.denominator = frames_per_sec * 1000;
677	parms->parm.capture.extendedmode = 0;
678	parms->parm.capture.readbuffers = 1; /* FIXME: 2 buffers? */
679	return 0;
680}
681
682static const struct v4l2_ioctl_ops dt3155_ioctl_ops = {
683	.vidioc_streamon = dt3155_ioc_streamon,
684	.vidioc_streamoff = dt3155_ioc_streamoff,
685	.vidioc_querycap = dt3155_ioc_querycap,
686/*
687	.vidioc_g_priority = dt3155_ioc_g_priority,
688	.vidioc_s_priority = dt3155_ioc_s_priority,
689*/
690	.vidioc_enum_fmt_vid_cap = dt3155_ioc_enum_fmt_vid_cap,
691	.vidioc_try_fmt_vid_cap = dt3155_ioc_try_fmt_vid_cap,
692	.vidioc_g_fmt_vid_cap = dt3155_ioc_g_fmt_vid_cap,
693	.vidioc_s_fmt_vid_cap = dt3155_ioc_s_fmt_vid_cap,
694	.vidioc_reqbufs = dt3155_ioc_reqbufs,
695	.vidioc_querybuf = dt3155_ioc_querybuf,
696	.vidioc_qbuf = dt3155_ioc_qbuf,
697	.vidioc_dqbuf = dt3155_ioc_dqbuf,
698	.vidioc_querystd = dt3155_ioc_querystd,
699	.vidioc_g_std = dt3155_ioc_g_std,
700	.vidioc_s_std = dt3155_ioc_s_std,
701	.vidioc_enum_input = dt3155_ioc_enum_input,
702	.vidioc_g_input = dt3155_ioc_g_input,
703	.vidioc_s_input = dt3155_ioc_s_input,
704/*
705	.vidioc_queryctrl = dt3155_ioc_queryctrl,
706	.vidioc_g_ctrl = dt3155_ioc_g_ctrl,
707	.vidioc_s_ctrl = dt3155_ioc_s_ctrl,
708	.vidioc_querymenu = dt3155_ioc_querymenu,
709	.vidioc_g_ext_ctrls = dt3155_ioc_g_ext_ctrls,
710	.vidioc_s_ext_ctrls = dt3155_ioc_s_ext_ctrls,
711*/
712	.vidioc_g_parm = dt3155_ioc_g_parm,
713	.vidioc_s_parm = dt3155_ioc_s_parm,
714/*
715	.vidioc_cropcap = dt3155_ioc_cropcap,
716	.vidioc_g_crop = dt3155_ioc_g_crop,
717	.vidioc_s_crop = dt3155_ioc_s_crop,
718	.vidioc_enum_framesizes = dt3155_ioc_enum_framesizes,
719	.vidioc_enum_frameintervals = dt3155_ioc_enum_frameintervals,
720*/
721};
722
723static int
724dt3155_init_board(struct pci_dev *pdev)
725{
726	struct dt3155_priv *pd = pci_get_drvdata(pdev);
727	void *buf_cpu;
728	dma_addr_t buf_dma;
729	int i;
730	u8 tmp;
731
732	pci_set_master(pdev); /* dt3155 needs it */
733
734	/*  resetting the adapter  */
735	iowrite32(FLD_CRPT_ODD | FLD_CRPT_EVEN | FLD_DN_ODD | FLD_DN_EVEN,
736							pd->regs + CSR1);
737	mmiowb();
738	msleep(20);
739
740	/*  initializing adaper registers  */
741	iowrite32(FIFO_EN | SRST, pd->regs + CSR1);
742	mmiowb();
743	iowrite32(0xEEEEEE01, pd->regs + EVEN_PIXEL_FMT);
744	iowrite32(0xEEEEEE01, pd->regs + ODD_PIXEL_FMT);
745	iowrite32(0x00000020, pd->regs + FIFO_TRIGER);
746	iowrite32(0x00000103, pd->regs + XFER_MODE);
747	iowrite32(0, pd->regs + RETRY_WAIT_CNT);
748	iowrite32(0, pd->regs + INT_CSR);
749	iowrite32(1, pd->regs + EVEN_FLD_MASK);
750	iowrite32(1, pd->regs + ODD_FLD_MASK);
751	iowrite32(0, pd->regs + MASK_LENGTH);
752	iowrite32(0x0005007C, pd->regs + FIFO_FLAG_CNT);
753	iowrite32(0x01010101, pd->regs + IIC_CLK_DUR);
754	mmiowb();
755
756	/* verifying that we have a DT3155 board (not just a SAA7116 chip) */
757	read_i2c_reg(pd->regs, DT_ID, &tmp);
758	if (tmp != DT3155_ID)
759		return -ENODEV;
760
761	/* initialize AD LUT */
762	write_i2c_reg(pd->regs, AD_ADDR, 0);
763	for (i = 0; i < 256; i++)
764		write_i2c_reg(pd->regs, AD_LUT, i);
765
766	/* initialize ADC references */
767	/* FIXME: pos_ref & neg_ref depend on VT_50HZ */
768	write_i2c_reg(pd->regs, AD_ADDR, AD_CMD_REG);
769	write_i2c_reg(pd->regs, AD_CMD, VIDEO_CNL_1 | SYNC_CNL_1 | SYNC_LVL_3);
770	write_i2c_reg(pd->regs, AD_ADDR, AD_POS_REF);
771	write_i2c_reg(pd->regs, AD_CMD, 34);
772	write_i2c_reg(pd->regs, AD_ADDR, AD_NEG_REF);
773	write_i2c_reg(pd->regs, AD_CMD, 0);
774
775	/* initialize PM LUT */
776	write_i2c_reg(pd->regs, CONFIG, pd->config | PM_LUT_PGM);
777	for (i = 0; i < 256; i++) {
778		write_i2c_reg(pd->regs, PM_LUT_ADDR, i);
779		write_i2c_reg(pd->regs, PM_LUT_DATA, i);
780	}
781	write_i2c_reg(pd->regs, CONFIG, pd->config | PM_LUT_PGM | PM_LUT_SEL);
782	for (i = 0; i < 256; i++) {
783		write_i2c_reg(pd->regs, PM_LUT_ADDR, i);
784		write_i2c_reg(pd->regs, PM_LUT_DATA, i);
785	}
786	write_i2c_reg(pd->regs, CONFIG, pd->config); /*  ACQ_MODE_EVEN  */
787
788	/* select channel 1 for input and set sync level */
789	write_i2c_reg(pd->regs, AD_ADDR, AD_CMD_REG);
790	write_i2c_reg(pd->regs, AD_CMD, VIDEO_CNL_1 | SYNC_CNL_1 | SYNC_LVL_3);
791
792	/* allocate memory, and initialize the DMA machine */
793	buf_cpu = dma_alloc_coherent(&pdev->dev, DT3155_BUF_SIZE, &buf_dma,
794								GFP_KERNEL);
795	if (!buf_cpu)
796		return -ENOMEM;
797	iowrite32(buf_dma, pd->regs + EVEN_DMA_START);
798	iowrite32(buf_dma, pd->regs + ODD_DMA_START);
799	iowrite32(0, pd->regs + EVEN_DMA_STRIDE);
800	iowrite32(0, pd->regs + ODD_DMA_STRIDE);
801
802	/*  Perform a pseudo even field acquire    */
803	iowrite32(FIFO_EN | SRST | CAP_CONT_ODD, pd->regs + CSR1);
804	write_i2c_reg(pd->regs, CSR2, pd->csr2 | SYNC_SNTL);
805	write_i2c_reg(pd->regs, CONFIG, pd->config);
806	write_i2c_reg(pd->regs, EVEN_CSR, CSR_SNGL);
807	write_i2c_reg(pd->regs, CSR2, pd->csr2 | BUSY_EVEN | SYNC_SNTL);
808	msleep(100);
809	read_i2c_reg(pd->regs, CSR2, &tmp);
810	write_i2c_reg(pd->regs, EVEN_CSR, CSR_ERROR | CSR_SNGL | CSR_DONE);
811	write_i2c_reg(pd->regs, ODD_CSR, CSR_ERROR | CSR_SNGL | CSR_DONE);
812	write_i2c_reg(pd->regs, CSR2, pd->csr2);
813	iowrite32(FIFO_EN | SRST | FLD_DN_EVEN | FLD_DN_ODD, pd->regs + CSR1);
814
815	/*  deallocate memory  */
816	dma_free_coherent(&pdev->dev, DT3155_BUF_SIZE, buf_cpu, buf_dma);
817	if (tmp & BUSY_EVEN)
818		return -EIO;
819	return 0;
820}
821
822static struct video_device dt3155_vdev = {
823	.name = DT3155_NAME,
824	.fops = &dt3155_fops,
825	.ioctl_ops = &dt3155_ioctl_ops,
826	.minor = -1,
827	.release = video_device_release_empty,
828	.tvnorms = DT3155_CURRENT_NORM,
829};
830
831/* same as in drivers/base/dma-coherent.c */
832struct dma_coherent_mem {
833	void		*virt_base;
834	dma_addr_t	device_base;
835	int		size;
836	int		flags;
837	unsigned long	*bitmap;
838};
839
840static int
841dt3155_alloc_coherent(struct device *dev, size_t size, int flags)
842{
843	struct dma_coherent_mem *mem;
844	dma_addr_t dev_base;
845	int pages = size >> PAGE_SHIFT;
846	int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
847
848	if ((flags & DMA_MEMORY_MAP) == 0)
849		goto out;
850	if (!size)
851		goto out;
852	if (dev->dma_mem)
853		goto out;
854
855	mem = kzalloc(sizeof(*mem), GFP_KERNEL);
856	if (!mem)
857		goto out;
858	mem->virt_base = dma_alloc_coherent(dev, size, &dev_base,
859							DT3155_COH_FLAGS);
860	if (!mem->virt_base)
861		goto err_alloc_coherent;
862	mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
863	if (!mem->bitmap)
864		goto err_bitmap;
865
866	/* coherent_dma_mask is already set to 32 bits */
867	mem->device_base = dev_base;
868	mem->size = pages;
869	mem->flags = flags;
870	dev->dma_mem = mem;
871	return DMA_MEMORY_MAP;
872
873err_bitmap:
874	dma_free_coherent(dev, size, mem->virt_base, dev_base);
875err_alloc_coherent:
876	kfree(mem);
877out:
878	return 0;
879}
880
881static void
882dt3155_free_coherent(struct device *dev)
883{
884	struct dma_coherent_mem *mem = dev->dma_mem;
885
886	if (!mem)
887		return;
888	dev->dma_mem = NULL;
889	dma_free_coherent(dev, mem->size << PAGE_SHIFT,
890					mem->virt_base, mem->device_base);
891	kfree(mem->bitmap);
892	kfree(mem);
893}
894
895static int
896dt3155_probe(struct pci_dev *pdev, const struct pci_device_id *id)
897{
898	int err;
899	struct dt3155_priv *pd;
900
901	err = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32));
902	if (err)
903		return -ENODEV;
904	pd = devm_kzalloc(&pdev->dev, sizeof(*pd), GFP_KERNEL);
905	if (!pd)
906		return -ENOMEM;
907
908	pd->vdev = dt3155_vdev;
909	pci_set_drvdata(pdev, pd);    /* for use in dt3155_remove() */
910	video_set_drvdata(&pd->vdev, pd);  /* for use in video_fops */
911	pd->users = 0;
912	pd->pdev = pdev;
913	INIT_LIST_HEAD(&pd->dmaq);
914	mutex_init(&pd->mux);
915	pd->vdev.lock = &pd->mux; /* for locking v4l2_file_operations */
916	spin_lock_init(&pd->lock);
917	pd->csr2 = csr2_init;
918	pd->config = config_init;
919	err = pci_enable_device(pdev);
920	if (err)
921		return err;
922	err = pci_request_region(pdev, 0, pci_name(pdev));
923	if (err)
924		goto err_req_region;
925	pd->regs = pci_iomap(pdev, 0, pci_resource_len(pd->pdev, 0));
926	if (!pd->regs) {
927		err = -ENOMEM;
928		goto err_pci_iomap;
929	}
930	err = dt3155_init_board(pdev);
931	if (err)
932		goto err_init_board;
933	err = video_register_device(&pd->vdev, VFL_TYPE_GRABBER, -1);
934	if (err)
935		goto err_init_board;
936	if (dt3155_alloc_coherent(&pdev->dev, DT3155_CHUNK_SIZE,
937							DMA_MEMORY_MAP))
938		dev_info(&pdev->dev, "preallocated 8 buffers\n");
939	dev_info(&pdev->dev, "/dev/video%i is ready\n", pd->vdev.minor);
940	return 0;  /*   success   */
941
942err_init_board:
943	pci_iounmap(pdev, pd->regs);
944err_pci_iomap:
945	pci_release_region(pdev, 0);
946err_req_region:
947	pci_disable_device(pdev);
948	return err;
949}
950
951static void
952dt3155_remove(struct pci_dev *pdev)
953{
954	struct dt3155_priv *pd = pci_get_drvdata(pdev);
955
956	dt3155_free_coherent(&pdev->dev);
957	video_unregister_device(&pd->vdev);
958	pci_iounmap(pdev, pd->regs);
959	pci_release_region(pdev, 0);
960	pci_disable_device(pdev);
961}
962
963static const struct pci_device_id pci_ids[] = {
964	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, DT3155_DEVICE_ID) },
965	{ 0, /* zero marks the end */ },
966};
967MODULE_DEVICE_TABLE(pci, pci_ids);
968
969static struct pci_driver pci_driver = {
970	.name = DT3155_NAME,
971	.id_table = pci_ids,
972	.probe = dt3155_probe,
973	.remove = dt3155_remove,
974};
975
976module_pci_driver(pci_driver);
977
978MODULE_DESCRIPTION("video4linux pci-driver for dt3155 frame grabber");
979MODULE_AUTHOR("Marin Mitov <mitov@issp.bas.bg>");
980MODULE_VERSION(DT3155_VERSION);
981MODULE_LICENSE("GPL");
982