PageRenderTime 69ms CodeModel.GetById 19ms app.highlight 45ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/media/video/arv.c

https://bitbucket.org/abioy/linux
C | 917 lines | 693 code | 100 blank | 124 comment | 99 complexity | 66444da40cd6e3a54ae36339a06cfb57 MD5 | raw file
Possible License(s): CC-BY-SA-3.0, GPL-2.0, LGPL-2.0, AGPL-1.0
  1/*
  2 * Colour AR M64278(VGA) driver for Video4Linux
  3 *
  4 * Copyright (C) 2003	Takeo Takahashi <takahashi.takeo@renesas.com>
  5 *
  6 * This program is free software; you can redistribute it and/or
  7 * modify it under the terms of the GNU General Public License
  8 * as published by the Free Software Foundation; either version
  9 * 2 of the License, or (at your option) any later version.
 10 *
 11 * Some code is taken from AR driver sample program for M3T-M32700UT.
 12 *
 13 * AR driver sample (M32R SDK):
 14 *     Copyright (c) 2003 RENESAS TECHNOROGY CORPORATION
 15 *     AND RENESAS SOLUTIONS CORPORATION
 16 *     All Rights Reserved.
 17 *
 18 * 2003-09-01:	Support w3cam by Takeo Takahashi
 19 */
 20
 21#include <linux/init.h>
 22#include <linux/module.h>
 23#include <linux/delay.h>
 24#include <linux/errno.h>
 25#include <linux/fs.h>
 26#include <linux/kernel.h>
 27#include <linux/slab.h>
 28#include <linux/mm.h>
 29#include <linux/sched.h>
 30#include <linux/videodev.h>
 31#include <media/v4l2-common.h>
 32#include <media/v4l2-ioctl.h>
 33#include <linux/mutex.h>
 34
 35#include <asm/uaccess.h>
 36#include <asm/m32r.h>
 37#include <asm/io.h>
 38#include <asm/dma.h>
 39#include <asm/byteorder.h>
 40
 41#if 0
 42#define DEBUG(n, args...) printk(args)
 43#define CHECK_LOST	1
 44#else
 45#define DEBUG(n, args...)
 46#define CHECK_LOST	0
 47#endif
 48
 49/*
 50 * USE_INT is always 0, interrupt mode is not available
 51 * on linux due to lack of speed
 52 */
 53#define USE_INT		0	/* Don't modify */
 54
 55#define VERSION	"0.03"
 56
 57#define ar_inl(addr) 		inl((unsigned long)(addr))
 58#define ar_outl(val, addr)	outl((unsigned long)(val),(unsigned long)(addr))
 59
 60extern struct cpuinfo_m32r	boot_cpu_data;
 61
 62/*
 63 * CCD pixel size
 64 *	Note that M32700UT does not support CIF mode, but QVGA is
 65 *	supported by M32700UT hardware using VGA mode of AR LSI.
 66 *
 67 * 	Supported: VGA  (Normal mode, Interlace mode)
 68 *		   QVGA (Always Interlace mode of VGA)
 69 *
 70 */
 71#define AR_WIDTH_VGA		640
 72#define AR_HEIGHT_VGA		480
 73#define AR_WIDTH_QVGA		320
 74#define AR_HEIGHT_QVGA		240
 75#define MIN_AR_WIDTH		AR_WIDTH_QVGA
 76#define MIN_AR_HEIGHT		AR_HEIGHT_QVGA
 77#define MAX_AR_WIDTH		AR_WIDTH_VGA
 78#define MAX_AR_HEIGHT		AR_HEIGHT_VGA
 79
 80/* bits & bytes per pixel */
 81#define AR_BITS_PER_PIXEL	16
 82#define AR_BYTES_PER_PIXEL	(AR_BITS_PER_PIXEL/8)
 83
 84/* line buffer size */
 85#define AR_LINE_BYTES_VGA	(AR_WIDTH_VGA * AR_BYTES_PER_PIXEL)
 86#define AR_LINE_BYTES_QVGA	(AR_WIDTH_QVGA * AR_BYTES_PER_PIXEL)
 87#define MAX_AR_LINE_BYTES	AR_LINE_BYTES_VGA
 88
 89/* frame size & type */
 90#define AR_FRAME_BYTES_VGA \
 91	(AR_WIDTH_VGA * AR_HEIGHT_VGA * AR_BYTES_PER_PIXEL)
 92#define AR_FRAME_BYTES_QVGA \
 93	(AR_WIDTH_QVGA * AR_HEIGHT_QVGA * AR_BYTES_PER_PIXEL)
 94#define MAX_AR_FRAME_BYTES \
 95	(MAX_AR_WIDTH * MAX_AR_HEIGHT * AR_BYTES_PER_PIXEL)
 96
 97#define AR_MAX_FRAME		15
 98
 99/* capture size */
100#define AR_SIZE_VGA		0
101#define AR_SIZE_QVGA		1
102
103/* capture mode */
104#define AR_MODE_INTERLACE	0
105#define AR_MODE_NORMAL		1
106
107struct ar_device {
108	struct video_device *vdev;
109	unsigned int start_capture;	/* duaring capture in INT. mode. */
110#if USE_INT
111	unsigned char *line_buff;	/* DMA line buffer */
112#endif
113	unsigned char *frame[MAX_AR_HEIGHT];	/* frame data */
114	short size;			/* capture size */
115	short mode;			/* capture mode */
116	int width, height;
117	int frame_bytes, line_bytes;
118	wait_queue_head_t wait;
119	unsigned long in_use;
120	struct mutex lock;
121};
122
123static int video_nr = -1;	/* video device number (first free) */
124static unsigned char	yuv[MAX_AR_FRAME_BYTES];
125
126/* module parameters */
127/* default frequency */
128#define DEFAULT_FREQ	50	/* 50 or 75 (MHz) is available as BCLK */
129static int freq = DEFAULT_FREQ;	/* BCLK: available 50 or 70 (MHz) */
130static int vga;			/* default mode(0:QVGA mode, other:VGA mode) */
131static int vga_interlace;	/* 0 is normal mode for, else interlace mode */
132module_param(freq, int, 0);
133module_param(vga, int, 0);
134module_param(vga_interlace, int, 0);
135
136static int ar_initialize(struct video_device *dev);
137
138static inline void wait_for_vsync(void)
139{
140	while (ar_inl(ARVCR0) & ARVCR0_VDS)	/* wait for VSYNC */
141		cpu_relax();
142	while (!(ar_inl(ARVCR0) & ARVCR0_VDS))	/* wait for VSYNC */
143		cpu_relax();
144}
145
146static inline void wait_acknowledge(void)
147{
148	int i;
149
150	for (i = 0; i < 1000; i++)
151		cpu_relax();
152	while (ar_inl(PLDI2CSTS) & PLDI2CSTS_NOACK)
153		cpu_relax();
154}
155
156/*******************************************************************
157 * I2C functions
158 *******************************************************************/
159void iic(int n, unsigned long addr, unsigned long data1, unsigned long data2,
160	 unsigned long data3)
161{
162	int i;
163
164	/* Slave Address */
165	ar_outl(addr, PLDI2CDATA);
166	wait_for_vsync();
167
168	/* Start */
169	ar_outl(1, PLDI2CCND);
170	wait_acknowledge();
171
172	/* Transfer data 1 */
173	ar_outl(data1, PLDI2CDATA);
174	wait_for_vsync();
175	ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
176	wait_acknowledge();
177
178	/* Transfer data 2 */
179	ar_outl(data2, PLDI2CDATA);
180	wait_for_vsync();
181	ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
182	wait_acknowledge();
183
184	if (n == 3) {
185		/* Transfer data 3 */
186		ar_outl(data3, PLDI2CDATA);
187		wait_for_vsync();
188		ar_outl(PLDI2CSTEN_STEN, PLDI2CSTEN);
189		wait_acknowledge();
190	}
191
192	/* Stop */
193	for (i = 0; i < 100; i++)
194		cpu_relax();
195	ar_outl(2, PLDI2CCND);
196	ar_outl(2, PLDI2CCND);
197
198	while (ar_inl(PLDI2CSTS) & PLDI2CSTS_BB)
199		cpu_relax();
200}
201
202
203void init_iic(void)
204{
205	DEBUG(1, "init_iic:\n");
206
207	/*
208	 * ICU Setting (iic)
209	 */
210	/* I2C Setting */
211	ar_outl(0x0, PLDI2CCR);      	/* I2CCR Disable                   */
212	ar_outl(0x0300, PLDI2CMOD); 	/* I2CMOD ACK/8b-data/7b-addr/auto */
213	ar_outl(0x1, PLDI2CACK);	/* I2CACK ACK                      */
214
215	/* I2C CLK */
216	/* 50MH-100k */
217	if (freq == 75) {
218		ar_outl(369, PLDI2CFREQ);	/* BCLK = 75MHz */
219	} else if (freq == 50) {
220		ar_outl(244, PLDI2CFREQ);	/* BCLK = 50MHz */
221	} else {
222		ar_outl(244, PLDI2CFREQ);	/* default: BCLK = 50MHz */
223	}
224	ar_outl(0x1, PLDI2CCR); 	/* I2CCR Enable */
225}
226
227/**************************************************************************
228 *
229 * Video4Linux Interface functions
230 *
231 **************************************************************************/
232
233static inline void disable_dma(void)
234{
235	ar_outl(0x8000, M32R_DMAEN_PORTL);	/* disable DMA0 */
236}
237
238static inline void enable_dma(void)
239{
240	ar_outl(0x8080, M32R_DMAEN_PORTL);	/* enable DMA0 */
241}
242
243static inline void clear_dma_status(void)
244{
245	ar_outl(0x8000, M32R_DMAEDET_PORTL);	/* clear status */
246}
247
248static inline void wait_for_vertical_sync(int exp_line)
249{
250#if CHECK_LOST
251	int tmout = 10000;	/* FIXME */
252	int l;
253
254	/*
255	 * check HCOUNT because we cannot check vertical sync.
256	 */
257	for (; tmout >= 0; tmout--) {
258		l = ar_inl(ARVHCOUNT);
259		if (l == exp_line)
260			break;
261	}
262	if (tmout < 0)
263		printk("arv: lost %d -> %d\n", exp_line, l);
264#else
265	while (ar_inl(ARVHCOUNT) != exp_line)
266		cpu_relax();
267#endif
268}
269
270static ssize_t ar_read(struct file *file, char *buf, size_t count, loff_t *ppos)
271{
272	struct video_device *v = video_devdata(file);
273	struct ar_device *ar = video_get_drvdata(v);
274	long ret = ar->frame_bytes;		/* return read bytes */
275	unsigned long arvcr1 = 0;
276	unsigned long flags;
277	unsigned char *p;
278	int h, w;
279	unsigned char *py, *pu, *pv;
280#if ! USE_INT
281	int l;
282#endif
283
284	DEBUG(1, "ar_read()\n");
285
286	if (ar->size == AR_SIZE_QVGA)
287		arvcr1 |= ARVCR1_QVGA;
288	if (ar->mode == AR_MODE_NORMAL)
289		arvcr1 |= ARVCR1_NORMAL;
290
291	mutex_lock(&ar->lock);
292
293#if USE_INT
294	local_irq_save(flags);
295	disable_dma();
296	ar_outl(0xa1871300, M32R_DMA0CR0_PORTL);
297	ar_outl(0x01000000, M32R_DMA0CR1_PORTL);
298
299	/* set AR FIFO address as source(BSEL5) */
300	ar_outl(ARDATA32, M32R_DMA0CSA_PORTL);
301	ar_outl(ARDATA32, M32R_DMA0RSA_PORTL);
302	ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL);	/* destination addr. */
303	ar_outl(ar->line_buff, M32R_DMA0RDA_PORTL); 	/* reload address */
304	ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL); 	/* byte count (bytes) */
305	ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL); 	/* reload count (bytes) */
306
307	/*
308	 * Okey , kicks AR LSI to invoke an interrupt
309	 */
310	ar->start_capture = 0;
311	ar_outl(arvcr1 | ARVCR1_HIEN, ARVCR1);
312	local_irq_restore(flags);
313	/* .... AR interrupts .... */
314	interruptible_sleep_on(&ar->wait);
315	if (signal_pending(current)) {
316		printk("arv: interrupted while get frame data.\n");
317		ret = -EINTR;
318		goto out_up;
319	}
320#else	/* ! USE_INT */
321	/* polling */
322	ar_outl(arvcr1, ARVCR1);
323	disable_dma();
324	ar_outl(0x8000, M32R_DMAEDET_PORTL);
325	ar_outl(0xa0861300, M32R_DMA0CR0_PORTL);
326	ar_outl(0x01000000, M32R_DMA0CR1_PORTL);
327	ar_outl(ARDATA32, M32R_DMA0CSA_PORTL);
328	ar_outl(ARDATA32, M32R_DMA0RSA_PORTL);
329	ar_outl(ar->line_bytes, M32R_DMA0CBCUT_PORTL);
330	ar_outl(ar->line_bytes, M32R_DMA0RBCUT_PORTL);
331
332	local_irq_save(flags);
333	while (ar_inl(ARVHCOUNT) != 0)		/* wait for 0 */
334		cpu_relax();
335	if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
336		for (h = 0; h < ar->height; h++) {
337			wait_for_vertical_sync(h);
338			if (h < (AR_HEIGHT_VGA/2))
339				l = h << 1;
340			else
341				l = (((h - (AR_HEIGHT_VGA/2)) << 1) + 1);
342			ar_outl(virt_to_phys(ar->frame[l]), M32R_DMA0CDA_PORTL);
343			enable_dma();
344			while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000))
345				cpu_relax();
346			disable_dma();
347			clear_dma_status();
348			ar_outl(0xa0861300, M32R_DMA0CR0_PORTL);
349		}
350	} else {
351		for (h = 0; h < ar->height; h++) {
352			wait_for_vertical_sync(h);
353			ar_outl(virt_to_phys(ar->frame[h]), M32R_DMA0CDA_PORTL);
354			enable_dma();
355			while (!(ar_inl(M32R_DMAEDET_PORTL) & 0x8000))
356				cpu_relax();
357			disable_dma();
358			clear_dma_status();
359			ar_outl(0xa0861300, M32R_DMA0CR0_PORTL);
360		}
361	}
362	local_irq_restore(flags);
363#endif	/* ! USE_INT */
364
365	/*
366	 * convert YUV422 to YUV422P
367	 * 	+--------------------+
368	 *	|  Y0,Y1,...	     |
369	 *	|  ..............Yn  |
370	 *	+--------------------+
371	 *	|  U0,U1,........Un  |
372	 *	+--------------------+
373	 *	|  V0,V1,........Vn  |
374	 *	+--------------------+
375	 */
376	py = yuv;
377	pu = py + (ar->frame_bytes / 2);
378	pv = pu + (ar->frame_bytes / 4);
379	for (h = 0; h < ar->height; h++) {
380		p = ar->frame[h];
381		for (w = 0; w < ar->line_bytes; w += 4) {
382			*py++ = *p++;
383			*pu++ = *p++;
384			*py++ = *p++;
385			*pv++ = *p++;
386		}
387	}
388	if (copy_to_user(buf, yuv, ar->frame_bytes)) {
389		printk("arv: failed while copy_to_user yuv.\n");
390		ret = -EFAULT;
391		goto out_up;
392	}
393	DEBUG(1, "ret = %d\n", ret);
394out_up:
395	mutex_unlock(&ar->lock);
396	return ret;
397}
398
399static long ar_do_ioctl(struct file *file, unsigned int cmd, void *arg)
400{
401	struct video_device *dev = video_devdata(file);
402	struct ar_device *ar = video_get_drvdata(dev);
403
404	DEBUG(1, "ar_ioctl()\n");
405	switch(cmd) {
406	case VIDIOCGCAP:
407	{
408		struct video_capability *b = arg;
409		DEBUG(1, "VIDIOCGCAP:\n");
410		strcpy(b->name, ar->vdev->name);
411		b->type = VID_TYPE_CAPTURE;
412		b->channels = 0;
413		b->audios = 0;
414		b->maxwidth = MAX_AR_WIDTH;
415		b->maxheight = MAX_AR_HEIGHT;
416		b->minwidth = MIN_AR_WIDTH;
417		b->minheight = MIN_AR_HEIGHT;
418		return 0;
419	}
420	case VIDIOCGCHAN:
421		DEBUG(1, "VIDIOCGCHAN:\n");
422		return 0;
423	case VIDIOCSCHAN:
424		DEBUG(1, "VIDIOCSCHAN:\n");
425		return 0;
426	case VIDIOCGTUNER:
427		DEBUG(1, "VIDIOCGTUNER:\n");
428		return 0;
429	case VIDIOCSTUNER:
430		DEBUG(1, "VIDIOCSTUNER:\n");
431		return 0;
432	case VIDIOCGPICT:
433		DEBUG(1, "VIDIOCGPICT:\n");
434		return 0;
435	case VIDIOCSPICT:
436		DEBUG(1, "VIDIOCSPICT:\n");
437		return 0;
438	case VIDIOCCAPTURE:
439		DEBUG(1, "VIDIOCCAPTURE:\n");
440		return -EINVAL;
441	case VIDIOCGWIN:
442	{
443		struct video_window *w = arg;
444		DEBUG(1, "VIDIOCGWIN:\n");
445		memset(w, 0, sizeof(*w));
446		w->width = ar->width;
447		w->height = ar->height;
448		return 0;
449	}
450	case VIDIOCSWIN:
451	{
452		struct video_window *w = arg;
453		DEBUG(1, "VIDIOCSWIN:\n");
454		if ((w->width != AR_WIDTH_VGA || w->height != AR_HEIGHT_VGA) &&
455		    (w->width != AR_WIDTH_QVGA || w->height != AR_HEIGHT_QVGA))
456				return -EINVAL;
457
458		mutex_lock(&ar->lock);
459		ar->width = w->width;
460		ar->height = w->height;
461		if (ar->width == AR_WIDTH_VGA) {
462			ar->size = AR_SIZE_VGA;
463			ar->frame_bytes = AR_FRAME_BYTES_VGA;
464			ar->line_bytes = AR_LINE_BYTES_VGA;
465			if (vga_interlace)
466				ar->mode = AR_MODE_INTERLACE;
467			else
468				ar->mode = AR_MODE_NORMAL;
469		} else {
470			ar->size = AR_SIZE_QVGA;
471			ar->frame_bytes = AR_FRAME_BYTES_QVGA;
472			ar->line_bytes = AR_LINE_BYTES_QVGA;
473			ar->mode = AR_MODE_INTERLACE;
474		}
475		mutex_unlock(&ar->lock);
476		return 0;
477	}
478	case VIDIOCGFBUF:
479		DEBUG(1, "VIDIOCGFBUF:\n");
480		return -EINVAL;
481	case VIDIOCSFBUF:
482		DEBUG(1, "VIDIOCSFBUF:\n");
483		return -EINVAL;
484	case VIDIOCKEY:
485		DEBUG(1, "VIDIOCKEY:\n");
486		return 0;
487	case VIDIOCGFREQ:
488		DEBUG(1, "VIDIOCGFREQ:\n");
489		return -EINVAL;
490	case VIDIOCSFREQ:
491		DEBUG(1, "VIDIOCSFREQ:\n");
492		return -EINVAL;
493	case VIDIOCGAUDIO:
494		DEBUG(1, "VIDIOCGAUDIO:\n");
495		return -EINVAL;
496	case VIDIOCSAUDIO:
497		DEBUG(1, "VIDIOCSAUDIO:\n");
498		return -EINVAL;
499	case VIDIOCSYNC:
500		DEBUG(1, "VIDIOCSYNC:\n");
501		return -EINVAL;
502	case VIDIOCMCAPTURE:
503		DEBUG(1, "VIDIOCMCAPTURE:\n");
504		return -EINVAL;
505	case VIDIOCGMBUF:
506		DEBUG(1, "VIDIOCGMBUF:\n");
507		return -EINVAL;
508	case VIDIOCGUNIT:
509		DEBUG(1, "VIDIOCGUNIT:\n");
510		return -EINVAL;
511	case VIDIOCGCAPTURE:
512		DEBUG(1, "VIDIOCGCAPTURE:\n");
513		return -EINVAL;
514	case VIDIOCSCAPTURE:
515		DEBUG(1, "VIDIOCSCAPTURE:\n");
516		return -EINVAL;
517	case VIDIOCSPLAYMODE:
518		DEBUG(1, "VIDIOCSPLAYMODE:\n");
519		return -EINVAL;
520	case VIDIOCSWRITEMODE:
521		DEBUG(1, "VIDIOCSWRITEMODE:\n");
522		return -EINVAL;
523	case VIDIOCGPLAYINFO:
524		DEBUG(1, "VIDIOCGPLAYINFO:\n");
525		return -EINVAL;
526	case VIDIOCSMICROCODE:
527		DEBUG(1, "VIDIOCSMICROCODE:\n");
528		return -EINVAL;
529	case VIDIOCGVBIFMT:
530		DEBUG(1, "VIDIOCGVBIFMT:\n");
531		return -EINVAL;
532	case VIDIOCSVBIFMT:
533		DEBUG(1, "VIDIOCSVBIFMT:\n");
534		return -EINVAL;
535	default:
536		DEBUG(1, "Unknown ioctl(0x%08x)\n", cmd);
537		return -ENOIOCTLCMD;
538	}
539	return 0;
540}
541
542static long ar_ioctl(struct file *file, unsigned int cmd,
543		    unsigned long arg)
544{
545	return video_usercopy(file, cmd, arg, ar_do_ioctl);
546}
547
548#if USE_INT
549/*
550 * Interrupt handler
551 */
552static void ar_interrupt(int irq, void *dev)
553{
554	struct ar_device *ar = dev;
555	unsigned int line_count;
556	unsigned int line_number;
557	unsigned int arvcr1;
558
559	line_count = ar_inl(ARVHCOUNT);			/* line number */
560	if (ar->mode == AR_MODE_INTERLACE && ar->size == AR_SIZE_VGA) {
561		/* operations for interlace mode */
562		if ( line_count < (AR_HEIGHT_VGA/2) ) 	/* even line */
563			line_number = (line_count << 1);
564		else 					/* odd line */
565			line_number =
566			(((line_count - (AR_HEIGHT_VGA/2)) << 1) + 1);
567	} else {
568		line_number = line_count;
569	}
570
571	if (line_number == 0) {
572		/*
573		 * It is an interrupt for line 0.
574		 * we have to start capture.
575		 */
576		disable_dma();
577#if 0
578		ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL);	/* needless? */
579#endif
580		memcpy(ar->frame[0], ar->line_buff, ar->line_bytes);
581#if 0
582		ar_outl(0xa1861300, M32R_DMA0CR0_PORTL);
583#endif
584		enable_dma();
585		ar->start_capture = 1;			/* during capture */
586		return;
587	}
588
589	if (ar->start_capture == 1 && line_number <= (ar->height - 1)) {
590		disable_dma();
591		memcpy(ar->frame[line_number], ar->line_buff, ar->line_bytes);
592
593		/*
594		 * if captured all line of a frame, disable AR interrupt
595		 * and wake a process up.
596		 */
597		if (line_number == (ar->height - 1)) { 	/* end  of line */
598
599			ar->start_capture = 0;
600
601			/* disable AR interrupt request */
602			arvcr1 = ar_inl(ARVCR1);
603			arvcr1 &= ~ARVCR1_HIEN;		/* clear int. flag */
604			ar_outl(arvcr1, ARVCR1);	/* disable */
605			wake_up_interruptible(&ar->wait);
606		} else {
607#if 0
608			ar_outl(ar->line_buff, M32R_DMA0CDA_PORTL);
609			ar_outl(0xa1861300, M32R_DMA0CR0_PORTL);
610#endif
611			enable_dma();
612		}
613	}
614}
615#endif
616
617/*
618 * ar_initialize()
619 * 	ar_initialize() is called by video_register_device() and
620 *	initializes AR LSI and peripherals.
621 *
622 *	-1 is returned in all failures.
623 *	0 is returned in success.
624 *
625 */
626static int ar_initialize(struct video_device *dev)
627{
628	struct ar_device *ar = video_get_drvdata(dev);
629	unsigned long cr = 0;
630	int i,found=0;
631
632	DEBUG(1, "ar_initialize:\n");
633
634	/*
635	 * initialize AR LSI
636	 */
637	ar_outl(0, ARVCR0);		/* assert reset of AR LSI */
638	for (i = 0; i < 0x18; i++)	/* wait for over 10 cycles @ 27MHz */
639		cpu_relax();
640	ar_outl(ARVCR0_RST, ARVCR0);	/* negate reset of AR LSI (enable) */
641	for (i = 0; i < 0x40d; i++)	/* wait for over 420 cycles @ 27MHz */
642		cpu_relax();
643
644	/* AR uses INT3 of CPU as interrupt pin. */
645	ar_outl(ARINTSEL_INT3, ARINTSEL);
646
647	if (ar->size == AR_SIZE_QVGA)
648		cr |= ARVCR1_QVGA;
649	if (ar->mode == AR_MODE_NORMAL)
650		cr |= ARVCR1_NORMAL;
651	ar_outl(cr, ARVCR1);
652
653	/*
654	 * Initialize IIC so that CPU can communicate with AR LSI,
655	 * and send boot commands to AR LSI.
656	 */
657	init_iic();
658
659	for (i = 0; i < 0x100000; i++) {	/* > 0xa1d10,  56ms */
660		if ((ar_inl(ARVCR0) & ARVCR0_VDS)) {	/* VSYNC */
661			found = 1;
662			break;
663		}
664	}
665
666	if (found == 0)
667		return -ENODEV;
668
669	printk("arv: Initializing ");
670
671	iic(2,0x78,0x11,0x01,0x00);	/* start */
672	iic(3,0x78,0x12,0x00,0x06);
673	iic(3,0x78,0x12,0x12,0x30);
674	iic(3,0x78,0x12,0x15,0x58);
675	iic(3,0x78,0x12,0x17,0x30);
676	printk(".");
677	iic(3,0x78,0x12,0x1a,0x97);
678	iic(3,0x78,0x12,0x1b,0xff);
679	iic(3,0x78,0x12,0x1c,0xff);
680	iic(3,0x78,0x12,0x26,0x10);
681	iic(3,0x78,0x12,0x27,0x00);
682	printk(".");
683	iic(2,0x78,0x34,0x02,0x00);
684	iic(2,0x78,0x7a,0x10,0x00);
685	iic(2,0x78,0x80,0x39,0x00);
686	iic(2,0x78,0x81,0xe6,0x00);
687	iic(2,0x78,0x8d,0x00,0x00);
688	printk(".");
689	iic(2,0x78,0x8e,0x0c,0x00);
690	iic(2,0x78,0x8f,0x00,0x00);
691#if 0
692	iic(2,0x78,0x90,0x00,0x00);	/* AWB on=1 off=0 */
693#endif
694	iic(2,0x78,0x93,0x01,0x00);
695	iic(2,0x78,0x94,0xcd,0x00);
696	iic(2,0x78,0x95,0x00,0x00);
697	printk(".");
698	iic(2,0x78,0x96,0xa0,0x00);
699	iic(2,0x78,0x97,0x00,0x00);
700	iic(2,0x78,0x98,0x60,0x00);
701	iic(2,0x78,0x99,0x01,0x00);
702	iic(2,0x78,0x9a,0x19,0x00);
703	printk(".");
704	iic(2,0x78,0x9b,0x02,0x00);
705	iic(2,0x78,0x9c,0xe8,0x00);
706	iic(2,0x78,0x9d,0x02,0x00);
707	iic(2,0x78,0x9e,0x2e,0x00);
708	iic(2,0x78,0xb8,0x78,0x00);
709	iic(2,0x78,0xba,0x05,0x00);
710#if 0
711	iic(2,0x78,0x83,0x8c,0x00);	/* brightness */
712#endif
713	printk(".");
714
715	/* color correction */
716	iic(3,0x78,0x49,0x00,0x95);	/* a		*/
717	iic(3,0x78,0x49,0x01,0x96);	/* b		*/
718	iic(3,0x78,0x49,0x03,0x85);	/* c		*/
719	iic(3,0x78,0x49,0x04,0x97);	/* d		*/
720	iic(3,0x78,0x49,0x02,0x7e);	/* e(Lo)	*/
721	iic(3,0x78,0x49,0x05,0xa4);	/* f(Lo)	*/
722	iic(3,0x78,0x49,0x06,0x04);	/* e(Hi)	*/
723	iic(3,0x78,0x49,0x07,0x04);	/* e(Hi)	*/
724	iic(2,0x78,0x48,0x01,0x00);	/* on=1 off=0	*/
725
726	printk(".");
727	iic(2,0x78,0x11,0x00,0x00);	/* end */
728	printk(" done\n");
729	return 0;
730}
731
732
733void ar_release(struct video_device *vfd)
734{
735	struct ar_device *ar = video_get_drvdata(vfd);
736	mutex_lock(&ar->lock);
737	video_device_release(vfd);
738}
739
740/****************************************************************************
741 *
742 * Video4Linux Module functions
743 *
744 ****************************************************************************/
745static struct ar_device ardev;
746
747static int ar_exclusive_open(struct file *file)
748{
749	return test_and_set_bit(0, &ardev.in_use) ? -EBUSY : 0;
750}
751
752static int ar_exclusive_release(struct file *file)
753{
754	clear_bit(0, &ardev.in_use);
755	return 0;
756}
757
758static const struct v4l2_file_operations ar_fops = {
759	.owner		= THIS_MODULE,
760	.open		= ar_exclusive_open,
761	.release	= ar_exclusive_release,
762	.read		= ar_read,
763	.ioctl		= ar_ioctl,
764};
765
766static struct video_device ar_template = {
767	.name		= "Colour AR VGA",
768	.fops		= &ar_fops,
769	.release	= ar_release,
770};
771
772#define ALIGN4(x)	((((int)(x)) & 0x3) == 0)
773
774static int __init ar_init(void)
775{
776	struct ar_device *ar;
777	int ret;
778	int i;
779
780	DEBUG(1, "ar_init:\n");
781	ret = -EIO;
782	printk(KERN_INFO "arv: Colour AR VGA driver %s\n", VERSION);
783
784	ar = &ardev;
785	memset(ar, 0, sizeof(struct ar_device));
786
787#if USE_INT
788	/* allocate a DMA buffer for 1 line.  */
789	ar->line_buff = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL | GFP_DMA);
790	if (ar->line_buff == NULL || ! ALIGN4(ar->line_buff)) {
791		printk("arv: buffer allocation failed for DMA.\n");
792		ret = -ENOMEM;
793		goto out_end;
794	}
795#endif
796	/* allocate buffers for a frame */
797	for (i = 0; i < MAX_AR_HEIGHT; i++) {
798		ar->frame[i] = kmalloc(MAX_AR_LINE_BYTES, GFP_KERNEL);
799		if (ar->frame[i] == NULL || ! ALIGN4(ar->frame[i])) {
800			printk("arv: buffer allocation failed for frame.\n");
801			ret = -ENOMEM;
802			goto out_line_buff;
803		}
804	}
805
806	ar->vdev = video_device_alloc();
807	if (!ar->vdev) {
808		printk(KERN_ERR "arv: video_device_alloc() failed\n");
809		return -ENOMEM;
810	}
811	memcpy(ar->vdev, &ar_template, sizeof(ar_template));
812	video_set_drvdata(ar->vdev, ar);
813
814	if (vga) {
815		ar->width 	= AR_WIDTH_VGA;
816		ar->height 	= AR_HEIGHT_VGA;
817		ar->size 	= AR_SIZE_VGA;
818		ar->frame_bytes = AR_FRAME_BYTES_VGA;
819		ar->line_bytes	= AR_LINE_BYTES_VGA;
820		if (vga_interlace)
821			ar->mode = AR_MODE_INTERLACE;
822		else
823			ar->mode = AR_MODE_NORMAL;
824	} else {
825		ar->width 	= AR_WIDTH_QVGA;
826		ar->height 	= AR_HEIGHT_QVGA;
827		ar->size 	= AR_SIZE_QVGA;
828		ar->frame_bytes = AR_FRAME_BYTES_QVGA;
829		ar->line_bytes	= AR_LINE_BYTES_QVGA;
830		ar->mode	= AR_MODE_INTERLACE;
831	}
832	mutex_init(&ar->lock);
833	init_waitqueue_head(&ar->wait);
834
835#if USE_INT
836	if (request_irq(M32R_IRQ_INT3, ar_interrupt, 0, "arv", ar)) {
837		printk("arv: request_irq(%d) failed.\n", M32R_IRQ_INT3);
838		ret = -EIO;
839		goto out_irq;
840	}
841#endif
842
843	if (ar_initialize(ar->vdev) != 0) {
844		printk("arv: M64278 not found.\n");
845		ret = -ENODEV;
846		goto out_dev;
847	}
848
849	/*
850	 * ok, we can initialize h/w according to parameters,
851	 * so register video device as a frame grabber type.
852	 * device is named "video[0-64]".
853	 * video_register_device() initializes h/w using ar_initialize().
854	 */
855	if (video_register_device(ar->vdev, VFL_TYPE_GRABBER, video_nr) != 0) {
856		/* return -1, -ENFILE(full) or others */
857		printk("arv: register video (Colour AR) failed.\n");
858		ret = -ENODEV;
859		goto out_dev;
860	}
861
862	printk("%s: Found M64278 VGA (IRQ %d, Freq %dMHz).\n",
863		video_device_node_name(ar->vdev), M32R_IRQ_INT3, freq);
864
865	return 0;
866
867out_dev:
868#if USE_INT
869	free_irq(M32R_IRQ_INT3, ar);
870
871out_irq:
872#endif
873	for (i = 0; i < MAX_AR_HEIGHT; i++)
874		kfree(ar->frame[i]);
875
876out_line_buff:
877#if USE_INT
878	kfree(ar->line_buff);
879
880out_end:
881#endif
882	return ret;
883}
884
885
886static int __init ar_init_module(void)
887{
888	freq = (boot_cpu_data.bus_clock / 1000000);
889	printk("arv: Bus clock %d\n", freq);
890	if (freq != 50 && freq != 75)
891		freq = DEFAULT_FREQ;
892	return ar_init();
893}
894
895static void __exit ar_cleanup_module(void)
896{
897	struct ar_device *ar;
898	int i;
899
900	ar = &ardev;
901	video_unregister_device(ar->vdev);
902#if USE_INT
903	free_irq(M32R_IRQ_INT3, ar);
904#endif
905	for (i = 0; i < MAX_AR_HEIGHT; i++)
906		kfree(ar->frame[i]);
907#if USE_INT
908	kfree(ar->line_buff);
909#endif
910}
911
912module_init(ar_init_module);
913module_exit(ar_cleanup_module);
914
915MODULE_AUTHOR("Takeo Takahashi <takahashi.takeo@renesas.com>");
916MODULE_DESCRIPTION("Colour AR M64278(VGA) for Video4Linux");
917MODULE_LICENSE("GPL");