1/*
2 *  tw68 driver common header file
3 *
4 *  Much of this code is derived from the cx88 and sa7134 drivers, which
5 *  were in turn derived from the bt87x driver.  The original work was by
6 *  Gerd Knorr; more recently the code was enhanced by Mauro Carvalho Chehab,
7 *  Hans Verkuil, Andy Walls and many others.  Their work is gratefully
8 *  acknowledged.  Full credit goes to them - any problems within this code
9 *  are mine.
10 *
11 *  Copyright (C) 2009  William M. Brack
12 *
13 *  Refactored and updated to the latest v4l core frameworks:
14 *
15 *  Copyright (C) 2014 Hans Verkuil <hverkuil@xs4all.nl>
16 *
17 *  This program is free software; you can redistribute it and/or modify
18 *  it under the terms of the GNU General Public License as published by
19 *  the Free Software Foundation; either version 2 of the License, or
20 *  (at your option) any later version.
21 *
22 *  This program is distributed in the hope that it will be useful,
23 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
24 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25 *  GNU General Public License for more details.
26 */
27
28#include <linux/version.h>
29#include <linux/pci.h>
30#include <linux/videodev2.h>
31#include <linux/notifier.h>
32#include <linux/delay.h>
33#include <linux/mutex.h>
34#include <linux/io.h>
35
36#include <media/v4l2-common.h>
37#include <media/v4l2-ioctl.h>
38#include <media/v4l2-ctrls.h>
39#include <media/v4l2-device.h>
40#include <media/videobuf2-dma-sg.h>
41
42#include "tw68-reg.h"
43
44#define	UNSET	(-1U)
45
46/* system vendor and device ID's */
47#define	PCI_VENDOR_ID_TECHWELL	0x1797
48#define	PCI_DEVICE_ID_6800	0x6800
49#define	PCI_DEVICE_ID_6801	0x6801
50#define	PCI_DEVICE_ID_AUDIO2	0x6802
51#define	PCI_DEVICE_ID_TS3	0x6803
52#define	PCI_DEVICE_ID_6804	0x6804
53#define	PCI_DEVICE_ID_AUDIO5	0x6805
54#define	PCI_DEVICE_ID_TS6	0x6806
55
56/* tw6816 based cards */
57#define	PCI_DEVICE_ID_6816_1   0x6810
58#define	PCI_DEVICE_ID_6816_2   0x6811
59#define	PCI_DEVICE_ID_6816_3   0x6812
60#define	PCI_DEVICE_ID_6816_4   0x6813
61
62#define TW68_NORMS ( \
63	V4L2_STD_NTSC    | V4L2_STD_PAL       | V4L2_STD_SECAM    | \
64	V4L2_STD_PAL_M   | V4L2_STD_PAL_Nc    | V4L2_STD_PAL_60)
65
66#define	TW68_VID_INTS	(TW68_FFERR | TW68_PABORT | TW68_DMAPERR | \
67			 TW68_FFOF   | TW68_DMAPI)
68/* TW6800 chips have trouble with these, so we don't set them for that chip */
69#define	TW68_VID_INTSX	(TW68_FDMIS | TW68_HLOCK | TW68_VLOCK)
70
71#define	TW68_I2C_INTS	(TW68_SBERR | TW68_SBDONE | TW68_SBERR2  | \
72			 TW68_SBDONE2)
73
74enum tw68_decoder_type {
75	TW6800,
76	TW6801,
77	TW6804,
78	TWXXXX,
79};
80
81/* ----------------------------------------------------------- */
82/* static data                                                 */
83
84struct tw68_tvnorm {
85	char		*name;
86	v4l2_std_id	id;
87
88	/* video decoder */
89	u32	sync_control;
90	u32	luma_control;
91	u32	chroma_ctrl1;
92	u32	chroma_gain;
93	u32	chroma_ctrl2;
94	u32	vgate_misc;
95
96	/* video scaler */
97	u32	h_delay;
98	u32	h_delay0;	/* for TW6800 */
99	u32	h_start;
100	u32	h_stop;
101	u32	v_delay;
102	u32	video_v_start;
103	u32	video_v_stop;
104	u32	vbi_v_start_0;
105	u32	vbi_v_stop_0;
106	u32	vbi_v_start_1;
107
108	/* Techwell specific */
109	u32	format;
110};
111
112struct tw68_format {
113	char	*name;
114	u32	fourcc;
115	u32	depth;
116	u32	twformat;
117};
118
119/* ----------------------------------------------------------- */
120/* card configuration					  */
121
122#define TW68_BOARD_NOAUTO		UNSET
123#define TW68_BOARD_UNKNOWN		0
124#define	TW68_BOARD_GENERIC_6802		1
125
126#define	TW68_MAXBOARDS			16
127#define	TW68_INPUT_MAX			4
128
129/* ----------------------------------------------------------- */
130/* device / file handle status                                 */
131
132#define	BUFFER_TIMEOUT	msecs_to_jiffies(500)	/* 0.5 seconds */
133
134struct tw68_dev;	/* forward delclaration */
135
136/* buffer for one video/vbi/ts frame */
137struct tw68_buf {
138	struct vb2_buffer vb;
139	struct list_head list;
140
141	unsigned int   size;
142	__le32         *cpu;
143	__le32         *jmp;
144	dma_addr_t     dma;
145};
146
147struct tw68_fmt {
148	char			*name;
149	u32			fourcc;	/* v4l2 format id */
150	int			depth;
151	int			flags;
152	u32			twformat;
153};
154
155/* global device status */
156struct tw68_dev {
157	struct mutex		lock;
158	spinlock_t		slock;
159	u16			instance;
160	struct v4l2_device	v4l2_dev;
161
162	/* various device info */
163	enum tw68_decoder_type	vdecoder;
164	struct video_device	vdev;
165	struct v4l2_ctrl_handler hdl;
166
167	/* pci i/o */
168	char			*name;
169	struct pci_dev		*pci;
170	unsigned char		pci_rev, pci_lat;
171	u32			__iomem *lmmio;
172	u8			__iomem *bmmio;
173	u32			pci_irqmask;
174	/* The irq mask to be used will depend upon the chip type */
175	u32			board_virqmask;
176
177	/* video capture */
178	const struct tw68_format *fmt;
179	unsigned		width, height;
180	unsigned		seqnr;
181	unsigned		field;
182	struct vb2_queue	vidq;
183	struct list_head	active;
184
185	/* various v4l controls */
186	const struct tw68_tvnorm *tvnorm;	/* video */
187
188	int			input;
189};
190
191/* ----------------------------------------------------------- */
192
193#define tw_readl(reg)		readl(dev->lmmio + ((reg) >> 2))
194#define	tw_readb(reg)		readb(dev->bmmio + (reg))
195#define tw_writel(reg, value)	writel((value), dev->lmmio + ((reg) >> 2))
196#define	tw_writeb(reg, value)	writeb((value), dev->bmmio + (reg))
197
198#define tw_andorl(reg, mask, value) \
199		writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\
200		((value) & (mask)), dev->lmmio+((reg)>>2))
201#define	tw_andorb(reg, mask, value) \
202		writeb((readb(dev->bmmio + (reg)) & ~(mask)) |\
203		((value) & (mask)), dev->bmmio+(reg))
204#define tw_setl(reg, bit)	tw_andorl((reg), (bit), (bit))
205#define	tw_setb(reg, bit)	tw_andorb((reg), (bit), (bit))
206#define	tw_clearl(reg, bit)	\
207		writel((readl(dev->lmmio + ((reg) >> 2)) & ~(bit)), \
208		dev->lmmio + ((reg) >> 2))
209#define	tw_clearb(reg, bit)	\
210		writeb((readb(dev->bmmio+(reg)) & ~(bit)), \
211		dev->bmmio + (reg))
212
213#define tw_wait(us) { udelay(us); }
214
215/* ----------------------------------------------------------- */
216/* tw68-video.c                                                */
217
218void tw68_set_tvnorm_hw(struct tw68_dev *dev);
219
220int tw68_video_init1(struct tw68_dev *dev);
221int tw68_video_init2(struct tw68_dev *dev, int video_nr);
222void tw68_irq_video_done(struct tw68_dev *dev, unsigned long status);
223int tw68_video_start_dma(struct tw68_dev *dev, struct tw68_buf *buf);
224
225/* ----------------------------------------------------------- */
226/* tw68-risc.c                                                 */
227
228int tw68_risc_buffer(struct pci_dev *pci, struct tw68_buf *buf,
229	struct scatterlist *sglist, unsigned int top_offset,
230	unsigned int bottom_offset, unsigned int bpl,
231	unsigned int padding, unsigned int lines);
232