aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2014-09-03 02:36:14 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-09-04 10:30:53 -0400
commite15d1c12c5878b3a80d6573af1721e17264e0286 (patch)
tree88371b64c975b890d6a49b15b2607bdcab8509dd
parent5740f4e75f713015067e2667a52bd3b35ef91e07 (diff)
[media] tw68: refactor and cleanup the tw68 driver
Refactor and clean up the tw68 driver. It's now using the proper V4L2 core frameworks. Tested with my Techwell tw6805a and tw6816 grabber boards. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/pci/Kconfig1
-rw-r--r--drivers/media/pci/Makefile1
-rw-r--r--drivers/media/pci/tw68/Kconfig10
-rw-r--r--drivers/media/pci/tw68/Makefile3
-rw-r--r--drivers/media/pci/tw68/tw68-cards.c172
-rw-r--r--drivers/media/pci/tw68/tw68-core.c801
-rw-r--r--drivers/media/pci/tw68/tw68-i2c.c245
-rw-r--r--drivers/media/pci/tw68/tw68-reg.h10
-rw-r--r--drivers/media/pci/tw68/tw68-risc.c156
-rw-r--r--drivers/media/pci/tw68/tw68-ts.c66
-rw-r--r--drivers/media/pci/tw68/tw68-tvaudio.c80
-rw-r--r--drivers/media/pci/tw68/tw68-vbi.c76
-rw-r--r--drivers/media/pci/tw68/tw68-video.c1906
-rw-r--r--drivers/media/pci/tw68/tw68.h435
14 files changed, 558 insertions, 3404 deletions
diff --git a/drivers/media/pci/Kconfig b/drivers/media/pci/Kconfig
index 5c16c9c2203e..933280740176 100644
--- a/drivers/media/pci/Kconfig
+++ b/drivers/media/pci/Kconfig
@@ -20,6 +20,7 @@ source "drivers/media/pci/ivtv/Kconfig"
20source "drivers/media/pci/zoran/Kconfig" 20source "drivers/media/pci/zoran/Kconfig"
21source "drivers/media/pci/saa7146/Kconfig" 21source "drivers/media/pci/saa7146/Kconfig"
22source "drivers/media/pci/solo6x10/Kconfig" 22source "drivers/media/pci/solo6x10/Kconfig"
23source "drivers/media/pci/tw68/Kconfig"
23endif 24endif
24 25
25if MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT 26if MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT
diff --git a/drivers/media/pci/Makefile b/drivers/media/pci/Makefile
index dc2ebbe27306..73d9c0f11127 100644
--- a/drivers/media/pci/Makefile
+++ b/drivers/media/pci/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/
21obj-$(CONFIG_VIDEO_BT848) += bt8xx/ 21obj-$(CONFIG_VIDEO_BT848) += bt8xx/
22obj-$(CONFIG_VIDEO_SAA7134) += saa7134/ 22obj-$(CONFIG_VIDEO_SAA7134) += saa7134/
23obj-$(CONFIG_VIDEO_SAA7164) += saa7164/ 23obj-$(CONFIG_VIDEO_SAA7164) += saa7164/
24obj-$(CONFIG_VIDEO_TW68) += tw68/
24obj-$(CONFIG_VIDEO_MEYE) += meye/ 25obj-$(CONFIG_VIDEO_MEYE) += meye/
25obj-$(CONFIG_STA2X11_VIP) += sta2x11/ 26obj-$(CONFIG_STA2X11_VIP) += sta2x11/
26obj-$(CONFIG_VIDEO_SOLO6X10) += solo6x10/ 27obj-$(CONFIG_VIDEO_SOLO6X10) += solo6x10/
diff --git a/drivers/media/pci/tw68/Kconfig b/drivers/media/pci/tw68/Kconfig
new file mode 100644
index 000000000000..5425ba1e320d
--- /dev/null
+++ b/drivers/media/pci/tw68/Kconfig
@@ -0,0 +1,10 @@
1config VIDEO_TW68
2 tristate "Techwell tw68x Video For Linux"
3 depends on VIDEO_DEV && PCI && VIDEO_V4L2
4 select I2C_ALGOBIT
5 select VIDEOBUF2_DMA_SG
6 ---help---
7 Support for Techwell tw68xx based frame grabber boards.
8
9 To compile this driver as a module, choose M here: the
10 module will be called tw68.
diff --git a/drivers/media/pci/tw68/Makefile b/drivers/media/pci/tw68/Makefile
new file mode 100644
index 000000000000..3d02f28b14fb
--- /dev/null
+++ b/drivers/media/pci/tw68/Makefile
@@ -0,0 +1,3 @@
1tw68-objs := tw68-core.o tw68-video.o tw68-risc.o
2
3obj-$(CONFIG_VIDEO_TW68) += tw68.o
diff --git a/drivers/media/pci/tw68/tw68-cards.c b/drivers/media/pci/tw68/tw68-cards.c
deleted file mode 100644
index 62aec4faa0d1..000000000000
--- a/drivers/media/pci/tw68/tw68-cards.c
+++ /dev/null
@@ -1,172 +0,0 @@
1/*
2 * device driver for Techwell 68xx based cards
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 <wbrack@mmm.com.hk>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 */
27
28#include <linux/init.h>
29#include <linux/module.h>
30#include <linux/i2c.h> /* must appear before i2c-algo-bit.h */
31#include <linux/i2c-algo-bit.h>
32
33#include <media/v4l2-common.h>
34#include <media/tveeprom.h>
35
36#include "tw68.h"
37#include "tw68-reg.h"
38
39/* commly used strings */
40#if 0
41static char name_mute[] = "mute";
42static char name_radio[] = "Radio";
43static char name_tv[] = "Television";
44static char name_tv_mono[] = "TV (mono only)";
45static char name_svideo[] = "S-Video";
46static char name_comp[] = "Composite";
47#endif
48static char name_comp1[] = "Composite1";
49static char name_comp2[] = "Composite2";
50static char name_comp3[] = "Composite3";
51static char name_comp4[] = "Composite4";
52
53/* ------------------------------------------------------------------ */
54/* board config info */
55
56/* If radio_type !=UNSET, radio_addr should be specified
57 */
58
59struct tw68_board tw68_boards[] = {
60 [TW68_BOARD_UNKNOWN] = {
61 .name = "GENERIC",
62 .tuner_type = TUNER_ABSENT,
63 .radio_type = UNSET,
64 .tuner_addr = ADDR_UNSET,
65 .radio_addr = ADDR_UNSET,
66
67 .inputs = {
68 {
69 .name = name_comp1,
70 .vmux = 0,
71 }, {
72 .name = name_comp2,
73 .vmux = 1,
74 }, {
75 .name = name_comp3,
76 .vmux = 2,
77 }, {
78 .name = name_comp4,
79 .vmux = 3,
80 }, { /* Must have a NULL entry at end of list */
81 .name = NULL,
82 .vmux = 0,
83 }
84 },
85 },
86};
87
88const unsigned int tw68_bcount = ARRAY_SIZE(tw68_boards);
89
90/*
91 * Please add any new PCI IDs to: http://pci-ids.ucw.cz. This keeps
92 * the PCI ID database up to date. Note that the entries must be
93 * added under vendor 0x1797 (Techwell Inc.) as subsystem IDs.
94 */
95struct pci_device_id tw68_pci_tbl[] = {
96 {
97 .vendor = PCI_VENDOR_ID_TECHWELL,
98 .device = PCI_DEVICE_ID_6800,
99 .subvendor = PCI_ANY_ID,
100 .subdevice = PCI_ANY_ID,
101 .driver_data = TW68_BOARD_UNKNOWN,
102 }, {
103 .vendor = PCI_VENDOR_ID_TECHWELL,
104 .device = PCI_DEVICE_ID_6801,
105 .subvendor = PCI_ANY_ID,
106 .subdevice = PCI_ANY_ID,
107 .driver_data = TW68_BOARD_UNKNOWN,
108 }, {
109 .vendor = PCI_VENDOR_ID_TECHWELL,
110 .device = PCI_DEVICE_ID_6804,
111 .subvendor = PCI_ANY_ID,
112 .subdevice = PCI_ANY_ID,
113 .driver_data = TW68_BOARD_UNKNOWN,
114 }, {
115 .vendor = PCI_VENDOR_ID_TECHWELL,
116 .device = PCI_DEVICE_ID_6816_1,
117 .subvendor = PCI_ANY_ID,
118 .subdevice = PCI_ANY_ID,
119 .driver_data = TW68_BOARD_UNKNOWN,
120 }, {
121 .vendor = PCI_VENDOR_ID_TECHWELL,
122 .device = PCI_DEVICE_ID_6816_2,
123 .subvendor = PCI_ANY_ID,
124 .subdevice = PCI_ANY_ID,
125 .driver_data = TW68_BOARD_UNKNOWN,
126 }, {
127 .vendor = PCI_VENDOR_ID_TECHWELL,
128 .device = PCI_DEVICE_ID_6816_3,
129 .subvendor = PCI_ANY_ID,
130 .subdevice = PCI_ANY_ID,
131 .driver_data = TW68_BOARD_UNKNOWN,
132 }, {
133 .vendor = PCI_VENDOR_ID_TECHWELL,
134 .device = PCI_DEVICE_ID_6816_4,
135 .subvendor = PCI_ANY_ID,
136 .subdevice = PCI_ANY_ID,
137 .driver_data = TW68_BOARD_UNKNOWN,
138 }, {
139 /* end of list */
140 }
141};
142MODULE_DEVICE_TABLE(pci, tw68_pci_tbl);
143
144/* ------------------------------------------------------------ */
145/* stuff done before i2c enabled */
146int tw68_board_init1(struct tw68_dev *dev)
147{
148 /* Clear GPIO outputs */
149 tw_writel(TW68_GPOE, 0);
150 /* Remainder of setup according to board ID */
151 switch (dev->board) {
152 case TW68_BOARD_UNKNOWN:
153 printk(KERN_INFO "%s: Unable to determine board type, "
154 "using generic values\n", dev->name);
155 break;
156 }
157 dev->input = dev->hw_input = &card_in(dev,0);
158 return 0;
159}
160
161int tw68_tuner_setup(struct tw68_dev *dev)
162{
163 return 0;
164}
165
166/* stuff which needs working i2c */
167int tw68_board_init2(struct tw68_dev *dev)
168{
169 return 0;
170}
171
172
diff --git a/drivers/media/pci/tw68/tw68-core.c b/drivers/media/pci/tw68/tw68-core.c
index 2c5d7a5f3f8e..baf93af1d764 100644
--- a/drivers/media/pci/tw68/tw68-core.c
+++ b/drivers/media/pci/tw68/tw68-core.c
@@ -9,7 +9,11 @@
9 * acknowledged. Full credit goes to them - any problems within this code 9 * acknowledged. Full credit goes to them - any problems within this code
10 * are mine. 10 * are mine.
11 * 11 *
12 * Copyright (C) 2009 William M. Brack <wbrack@mmm.com.hk> 12 * Copyright (C) 2009 William M. Brack
13 *
14 * Refactored and updated to the latest v4l core frameworks:
15 *
16 * Copyright (C) 2014 Hans Verkuil <hverkuil@xs4all.nl>
13 * 17 *
14 * This program is free software; you can redistribute it and/or modify 18 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by 19 * it under the terms of the GNU General Public License as published by
@@ -20,10 +24,6 @@
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details. 26 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 */ 27 */
28 28
29#include <linux/init.h> 29#include <linux/init.h>
@@ -44,320 +44,44 @@
44#include "tw68-reg.h" 44#include "tw68-reg.h"
45 45
46MODULE_DESCRIPTION("v4l2 driver module for tw6800 based video capture cards"); 46MODULE_DESCRIPTION("v4l2 driver module for tw6800 based video capture cards");
47MODULE_AUTHOR("William M. Brack <wbrack@mmm.com.hk>"); 47MODULE_AUTHOR("William M. Brack");
48MODULE_AUTHOR("Hans Verkuil <hverkuil@xs4all.nl>");
48MODULE_LICENSE("GPL"); 49MODULE_LICENSE("GPL");
49 50
50static unsigned int core_debug;
51module_param(core_debug, int, 0644);
52MODULE_PARM_DESC(core_debug, "enable debug messages [core]");
53
54static unsigned int gpio_tracking;
55module_param(gpio_tracking, int, 0644);
56MODULE_PARM_DESC(gpio_tracking, "enable debug messages [gpio]");
57
58static unsigned int alsa = 1;
59module_param(alsa, int, 0644);
60MODULE_PARM_DESC(alsa, "enable/disable ALSA DMA sound [dmasound]");
61
62static unsigned int latency = UNSET; 51static unsigned int latency = UNSET;
63module_param(latency, int, 0444); 52module_param(latency, int, 0444);
64MODULE_PARM_DESC(latency, "pci latency timer"); 53MODULE_PARM_DESC(latency, "pci latency timer");
65 54
66static unsigned int nocomb;
67module_param(nocomb, int, 0644);
68MODULE_PARM_DESC(nocomb, "disable comb filter");
69
70static unsigned int video_nr[] = {[0 ... (TW68_MAXBOARDS - 1)] = UNSET }; 55static unsigned int video_nr[] = {[0 ... (TW68_MAXBOARDS - 1)] = UNSET };
71static unsigned int vbi_nr[] = {[0 ... (TW68_MAXBOARDS - 1)] = UNSET };
72static unsigned int radio_nr[] = {[0 ... (TW68_MAXBOARDS - 1)] = UNSET };
73static unsigned int tuner[] = {[0 ... (TW68_MAXBOARDS - 1)] = UNSET };
74static unsigned int card[] = {[0 ... (TW68_MAXBOARDS - 1)] = UNSET };
75
76module_param_array(video_nr, int, NULL, 0444); 56module_param_array(video_nr, int, NULL, 0444);
77module_param_array(vbi_nr, int, NULL, 0444);
78module_param_array(radio_nr, int, NULL, 0444);
79module_param_array(tuner, int, NULL, 0444);
80module_param_array(card, int, NULL, 0444);
81
82MODULE_PARM_DESC(video_nr, "video device number"); 57MODULE_PARM_DESC(video_nr, "video device number");
83MODULE_PARM_DESC(vbi_nr, "vbi device number");
84MODULE_PARM_DESC(radio_nr, "radio device number");
85MODULE_PARM_DESC(tuner, "tuner type");
86MODULE_PARM_DESC(card, "card type");
87
88LIST_HEAD(tw68_devlist);
89EXPORT_SYMBOL(tw68_devlist);
90DEFINE_MUTEX(tw68_devlist_lock);
91EXPORT_SYMBOL(tw68_devlist_lock);
92static LIST_HEAD(mops_list);
93static unsigned int tw68_devcount; /* curr tot num of devices present */
94 58
95int (*tw68_dmasound_init)(struct tw68_dev *dev); 59static unsigned int card[] = {[0 ... (TW68_MAXBOARDS - 1)] = UNSET };
96EXPORT_SYMBOL(tw68_dmasound_init); 60module_param_array(card, int, NULL, 0444);
97int (*tw68_dmasound_exit)(struct tw68_dev *dev); 61MODULE_PARM_DESC(card, "card type");
98EXPORT_SYMBOL(tw68_dmasound_exit);
99 62
100#define dprintk(level, fmt, arg...) if (core_debug & (level)) \ 63static atomic_t tw68_instance = ATOMIC_INIT(0);
101 printk(KERN_DEBUG "%s: " fmt, dev->name , ## arg)
102 64
103/* ------------------------------------------------------------------ */ 65/* ------------------------------------------------------------------ */
104 66
105void tw68_dma_free(struct videobuf_queue *q, struct tw68_buf *buf)
106{
107 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
108
109 if (core_debug & DBG_FLOW)
110 printk(KERN_DEBUG "%s: called\n", __func__);
111 BUG_ON(in_interrupt());
112
113#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36)
114 videobuf_waiton(&buf->vb, 0, 0);
115#else
116 videobuf_waiton(q, &buf->vb, 0, 0);
117#endif
118#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,35)
119 videobuf_dma_unmap(q, dma);
120#else
121 videobuf_dma_unmap(q->dev, dma);
122#endif
123 videobuf_dma_free(dma);
124 /* if no risc area allocated, btcx_riscmem_free just returns */
125 btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
126 buf->vb.state = VIDEOBUF_NEEDS_INIT;
127}
128
129/* ------------------------------------------------------------------ */
130/* ------------- placeholders for later development ----------------- */
131
132static int tw68_input_init1(struct tw68_dev *dev)
133{
134 return 0;
135}
136
137static void tw68_input_fini(struct tw68_dev *dev)
138{
139 return;
140}
141
142#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
143static void tw68_ir_start(struct tw68_dev *dev, struct card_ir *ir)
144{
145 return;
146}
147
148static void tw68_ir_stop(struct tw68_dev *dev)
149{
150 return;
151}
152#endif
153
154/* ------------------------------------------------------------------ */
155/* 67/*
156 * Buffer handling routines 68 * Please add any new PCI IDs to: http://pci-ids.ucw.cz. This keeps
157 * 69 * the PCI ID database up to date. Note that the entries must be
158 * These routines are "generic", i.e. are intended to be used by more 70 * added under vendor 0x1797 (Techwell Inc.) as subsystem IDs.
159 * than one module, e.g. the video and the transport stream modules.
160 * To accomplish this generality, callbacks are used whenever some
161 * module-specific test or action is required.
162 */ 71 */
163 72struct pci_device_id tw68_pci_tbl[] = {
164/* resends a current buffer in queue after resume */ 73 {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_6800)},
165int tw68_buffer_requeue(struct tw68_dev *dev, 74 {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_6801)},
166 struct tw68_dmaqueue *q) 75 {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_6804)},
167{ 76 {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_6816_1)},
168 struct tw68_buf *buf, *prev; 77 {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_6816_2)},
169 78 {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_6816_3)},
170 dprintk(DBG_FLOW | DBG_TESTING, "%s: called\n", __func__); 79 {PCI_DEVICE(PCI_VENDOR_ID_TECHWELL, PCI_DEVICE_ID_6816_4)},
171 if (!list_empty(&q->active)) { 80 {0,}
172 buf = list_entry(q->active.next, struct tw68_buf, vb.queue); 81};
173 dprintk(DBG_BUFF, "%s: [%p/%d] restart dma\n", __func__,
174 buf, buf->vb.i);
175 q->start_dma(dev, q, buf);
176 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
177 return 0;
178 }
179
180 prev = NULL;
181 for (;;) {
182 if (list_empty(&q->queued))
183 return 0;
184 buf = list_entry(q->queued.next, struct tw68_buf, vb.queue);
185 /* if nothing precedes this one */
186 if (NULL == prev) {
187 list_move_tail(&buf->vb.queue, &q->active);
188 q->start_dma(dev, q, buf);
189 buf->activate(dev, buf, NULL);
190 dprintk(DBG_BUFF, "%s: [%p/%d] first active\n",
191 __func__, buf, buf->vb.i);
192
193 } else if (q->buf_compat(prev, buf) &&
194 (prev->fmt == buf->fmt)) {
195 list_move_tail(&buf->vb.queue, &q->active);
196 buf->activate(dev, buf, NULL);
197 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
198 dprintk(DBG_BUFF, "%s: [%p/%d] move to active\n",
199 __func__, buf, buf->vb.i);
200 } else {
201 dprintk(DBG_BUFF, "%s: no action taken\n", __func__);
202 return 0;
203 }
204 prev = buf;
205 }
206}
207
208/* nr of (tw68-)pages for the given buffer size */
209static int tw68_buffer_pages(int size)
210{
211 size = PAGE_ALIGN(size);
212 size += PAGE_SIZE; /* for non-page-aligned buffers */
213 size /= 4096;
214 return size;
215}
216
217/* calc max # of buffers from size (must not exceed the 4MB virtual
218 * address space per DMA channel) */
219int tw68_buffer_count(unsigned int size, unsigned int count)
220{
221 unsigned int maxcount;
222
223 maxcount = 1024 / tw68_buffer_pages(size);
224 if (count > maxcount)
225 count = maxcount;
226 return count;
227}
228
229/*
230 * tw68_wakeup
231 *
232 * Called when the driver completes filling a buffer, and tasks waiting
233 * for the data need to be awakened.
234 */
235void tw68_wakeup(struct tw68_dmaqueue *q, unsigned int *fc)
236{
237 struct tw68_dev *dev = q->dev;
238 struct tw68_buf *buf;
239
240 dprintk(DBG_FLOW, "%s: called\n", __func__);
241 if (list_empty(&q->active)) {
242 dprintk(DBG_BUFF | DBG_TESTING, "%s: active list empty",
243 __func__);
244 del_timer(&q->timeout);
245 return;
246 }
247 buf = list_entry(q->active.next, struct tw68_buf, vb.queue);
248 do_gettimeofday(&buf->vb.ts);
249 buf->vb.field_count = (*fc)++;
250 dprintk(DBG_BUFF | DBG_TESTING, "%s: [%p/%d] field_count=%d\n",
251 __func__, buf, buf->vb.i, *fc);
252 buf->vb.state = VIDEOBUF_DONE;
253 list_del(&buf->vb.queue);
254 wake_up(&buf->vb.done);
255 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
256}
257
258/*
259 * tw68_buffer_queue
260 *
261 * Add specified buffer to specified queue
262 */
263void tw68_buffer_queue(struct tw68_dev *dev,
264 struct tw68_dmaqueue *q,
265 struct tw68_buf *buf)
266{
267 struct tw68_buf *prev;
268
269 dprintk(DBG_FLOW, "%s: called\n", __func__);
270 assert_spin_locked(&dev->slock);
271 dprintk(DBG_BUFF, "%s: queuing buffer %p\n", __func__, buf);
272
273 /* append a 'JUMP to stopper' to the buffer risc program */
274 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_INT_BIT);
275 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
276
277 /* if this buffer is not "compatible" (in dimensions and format)
278 * with the currently active chain of buffers, we must change
279 * settings before filling it; if a previous buffer has already
280 * been determined to require changes, this buffer must follow
281 * it. To do this, we maintain a "queued" chain. If that
282 * chain exists, append this buffer to it */
283 if (!list_empty(&q->queued)) {
284 list_add_tail(&buf->vb.queue, &q->queued);
285 buf->vb.state = VIDEOBUF_QUEUED;
286 dprintk(DBG_BUFF, "%s: [%p/%d] appended to queued\n",
287 __func__, buf, buf->vb.i);
288
289 /* else if the 'active' chain doesn't yet exist we create it now */
290 } else if (list_empty(&q->active)) {
291 dprintk(DBG_BUFF, "%s: [%p/%d] first active\n",
292 __func__, buf, buf->vb.i);
293 list_add_tail(&buf->vb.queue, &q->active);
294 q->start_dma(dev, q, buf); /* 1st one - start dma */
295 /* TODO - why have we removed buf->count and q->count? */
296 buf->activate(dev, buf, NULL);
297
298 /* else we would like to put this buffer on the tail of the
299 * active chain, provided it is "compatible". */
300 } else {
301 /* "compatibility" depends upon the type of buffer */
302 prev = list_entry(q->active.prev, struct tw68_buf, vb.queue);
303 if (q->buf_compat(prev, buf)) {
304 /* If "compatible", append to active chain */
305 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
306 /* the param 'prev' is only for debug printing */
307 buf->activate(dev, buf, prev);
308 list_add_tail(&buf->vb.queue, &q->active);
309 dprintk(DBG_BUFF, "%s: [%p/%d] appended to active\n",
310 __func__, buf, buf->vb.i);
311 } else {
312 /* If "incompatible", append to queued chain */
313 list_add_tail(&buf->vb.queue, &q->queued);
314 buf->vb.state = VIDEOBUF_QUEUED;
315 dprintk(DBG_BUFF, "%s: [%p/%d] incompatible - appended "
316 "to queued\n", __func__, buf, buf->vb.i);
317 }
318 }
319}
320
321/*
322 * tw68_buffer_timeout
323 *
324 * This routine is set as the video_q.timeout.function
325 *
326 * Log the event, try to reset the h/w.
327 * Flag the current buffer as failed, try to start again with next buff
328 */
329void tw68_buffer_timeout(unsigned long data)
330{
331 struct tw68_dmaqueue *q = (struct tw68_dmaqueue *)data;
332 struct tw68_dev *dev = q->dev;
333 struct tw68_buf *buf;
334 unsigned long flags;
335
336 dprintk(DBG_FLOW, "%s: called\n", __func__);
337 spin_lock_irqsave(&dev->slock, flags);
338
339 /* flag all current active buffers as failed */
340 while (!list_empty(&q->active)) {
341 buf = list_entry(q->active.next, struct tw68_buf, vb.queue);
342 list_del(&buf->vb.queue);
343 buf->vb.state = VIDEOBUF_ERROR;
344 wake_up(&buf->vb.done);
345 printk(KERN_INFO "%s/0: [%p/%d] timeout - dma=0x%08lx\n",
346 dev->name, buf, buf->vb.i,
347 (unsigned long)buf->risc.dma);
348 }
349 tw68_buffer_requeue(dev, q);
350 spin_unlock_irqrestore(&dev->slock, flags);
351}
352 82
353/* ------------------------------------------------------------------ */ 83/* ------------------------------------------------------------------ */
354/* early init (no i2c, no irq) */
355 84
356/* Called from tw68_hw_init1 and tw68_resume */
357static int tw68_hw_enable1(struct tw68_dev *dev)
358{
359 return 0;
360}
361 85
362/* 86/*
363 * The device is given a "soft reset". According to the specifications, 87 * The device is given a "soft reset". According to the specifications,
@@ -367,7 +91,6 @@ static int tw68_hw_enable1(struct tw68_dev *dev)
367 */ 91 */
368static int tw68_hw_init1(struct tw68_dev *dev) 92static int tw68_hw_init1(struct tw68_dev *dev)
369{ 93{
370 dprintk(DBG_FLOW, "%s: called\n", __func__);
371 /* Assure all interrupts are disabled */ 94 /* Assure all interrupts are disabled */
372 tw_writel(TW68_INTMASK, 0); /* 020 */ 95 tw_writel(TW68_INTMASK, 0); /* 020 */
373 /* Clear any pending interrupts */ 96 /* Clear any pending interrupts */
@@ -415,7 +138,7 @@ static int tw68_hw_init1(struct tw68_dev *dev)
415 tw_writeb(TW68_AGCGAIN, 0xf0); /* 288 AGC gain when loop disabled */ 138 tw_writeb(TW68_AGCGAIN, 0xf0); /* 288 AGC gain when loop disabled */
416 tw_writeb(TW68_PEAKWT, 0xd8); /* 28C White peak threshold */ 139 tw_writeb(TW68_PEAKWT, 0xd8); /* 28C White peak threshold */
417 tw_writeb(TW68_CLMPL, 0x3c); /* 290 Y channel clamp level */ 140 tw_writeb(TW68_CLMPL, 0x3c); /* 290 Y channel clamp level */
418// tw_writeb(TW68_SYNCT, 0x38); /* 294 Sync amplitude */ 141/* tw_writeb(TW68_SYNCT, 0x38);*/ /* 294 Sync amplitude */
419 tw_writeb(TW68_SYNCT, 0x30); /* 294 Sync amplitude */ 142 tw_writeb(TW68_SYNCT, 0x30); /* 294 Sync amplitude */
420 tw_writeb(TW68_MISSCNT, 0x44); /* 298 Horiz sync, VCR detect sens */ 143 tw_writeb(TW68_MISSCNT, 0x44); /* 298 Horiz sync, VCR detect sens */
421 tw_writeb(TW68_PCLAMP, 0x28); /* 29C Clamp pos from PLL sync */ 144 tw_writeb(TW68_PCLAMP, 0x28); /* 29C Clamp pos from PLL sync */
@@ -465,80 +188,9 @@ static int tw68_hw_init1(struct tw68_dev *dev)
465 188
466 /* Initialize any subsystems */ 189 /* Initialize any subsystems */
467 tw68_video_init1(dev); 190 tw68_video_init1(dev);
468 tw68_vbi_init1(dev);
469 if (card_has_mpeg(dev))
470 tw68_ts_init1(dev);
471 tw68_input_init1(dev);
472
473 /* Do any other h/w early initialisation at this point */
474 tw68_hw_enable1(dev);
475
476 return 0;
477}
478
479/* late init (with i2c + irq) */
480static int tw68_hw_enable2(struct tw68_dev *dev)
481{
482
483 dprintk(DBG_FLOW, "%s: called\n", __func__);
484#ifdef TW68_TESTING
485 dev->pci_irqmask |= TW68_I2C_INTS;
486#endif
487 tw_setl(TW68_INTMASK, dev->pci_irqmask);
488 return 0; 191 return 0;
489} 192}
490 193
491static int tw68_hw_init2(struct tw68_dev *dev)
492{
493 dprintk(DBG_FLOW, "%s: called\n", __func__);
494 tw68_video_init2(dev); /* initialise video function first */
495 tw68_tvaudio_init2(dev);/* audio next */
496
497 /* all other board-related things, incl. enabling interrupts */
498 tw68_hw_enable2(dev);
499 return 0;
500}
501
502/* shutdown */
503static int tw68_hwfini(struct tw68_dev *dev)
504{
505 dprintk(DBG_FLOW, "%s: called\n", __func__);
506 if (card_has_mpeg(dev))
507 tw68_ts_fini(dev);
508 tw68_input_fini(dev);
509 tw68_vbi_fini(dev);
510 tw68_tvaudio_fini(dev);
511 return 0;
512}
513
514static void __devinit must_configure_manually(void)
515{
516 unsigned int i, p;
517
518 printk(KERN_WARNING
519 "tw68: <rant>\n"
520 "tw68: Congratulations! Your TV card vendor saved a few\n"
521 "tw68: cents for a eeprom, thus your pci board has no\n"
522 "tw68: subsystem ID and I can't identify it automatically\n"
523 "tw68: </rant>\n"
524 "tw68: I feel better now. Ok, here is the good news:\n"
525 "tw68: You can use the card=<nr> insmod option to specify\n"
526 "tw68: which board you have. The list:\n");
527 for (i = 0; i < tw68_bcount; i++) {
528 printk(KERN_WARNING "tw68: card=%d -> %-40.40s",
529 i, tw68_boards[i].name);
530 for (p = 0; tw68_pci_tbl[p].driver_data; p++) {
531 if (tw68_pci_tbl[p].driver_data != i)
532 continue;
533 printk(" %04x:%04x",
534 tw68_pci_tbl[p].subvendor,
535 tw68_pci_tbl[p].subdevice);
536 }
537 printk("\n");
538 }
539}
540
541
542static irqreturn_t tw68_irq(int irq, void *dev_id) 194static irqreturn_t tw68_irq(int irq, void *dev_id)
543{ 195{
544 struct tw68_dev *dev = dev_id; 196 struct tw68_dev *dev = dev_id;
@@ -548,126 +200,39 @@ static irqreturn_t tw68_irq(int irq, void *dev_id)
548 status = orig = tw_readl(TW68_INTSTAT) & dev->pci_irqmask; 200 status = orig = tw_readl(TW68_INTSTAT) & dev->pci_irqmask;
549 /* Check if anything to do */ 201 /* Check if anything to do */
550 if (0 == status) 202 if (0 == status)
551 return IRQ_RETVAL(0); /* Nope - return */ 203 return IRQ_NONE; /* Nope - return */
552 for (loop = 0; loop < 10; loop++) { 204 for (loop = 0; loop < 10; loop++) {
553 if (status & dev->board_virqmask) /* video interrupt */ 205 if (status & dev->board_virqmask) /* video interrupt */
554 tw68_irq_video_done(dev, status); 206 tw68_irq_video_done(dev, status);
555#ifdef TW68_TESTING
556 if (status & TW68_I2C_INTS)
557 tw68_irq_i2c(dev, status);
558#endif
559 status = tw_readl(TW68_INTSTAT) & dev->pci_irqmask; 207 status = tw_readl(TW68_INTSTAT) & dev->pci_irqmask;
560 if (0 == status) 208 if (0 == status)
561 goto out; 209 return IRQ_HANDLED;
562 } 210 }
563 dprintk(DBG_UNEXPECTED, "%s: **** INTERRUPT NOT HANDLED - clearing mask" 211 dev_dbg(&dev->pci->dev, "%s: **** INTERRUPT NOT HANDLED - clearing mask (orig 0x%08x, cur 0x%08x)",
564 " (orig 0x%08x, cur 0x%08x)", 212 dev->name, orig, tw_readl(TW68_INTSTAT));
565 dev->name, orig, tw_readl(TW68_INTSTAT)); 213 dev_dbg(&dev->pci->dev, "%s: pci_irqmask 0x%08x; board_virqmask 0x%08x ****\n",
566 dprintk(DBG_UNEXPECTED, "%s: pci_irqmask 0x%08x; board_virqmask " 214 dev->name, dev->pci_irqmask, dev->board_virqmask);
567 "0x%08x ****\n", dev->name,
568 dev->pci_irqmask, dev->board_virqmask);
569 tw_clearl(TW68_INTMASK, dev->pci_irqmask); 215 tw_clearl(TW68_INTMASK, dev->pci_irqmask);
570out: 216 return IRQ_HANDLED;
571 return IRQ_RETVAL(1);
572}
573
574int tw68_set_dmabits(struct tw68_dev *dev)
575{
576 return 0;
577}
578
579static struct video_device *vdev_init(struct tw68_dev *dev,
580 struct video_device *template,
581 char *type)
582{
583 struct video_device *vfd;
584
585 dprintk(DBG_FLOW, "%s: called\n", __func__);
586 vfd = video_device_alloc();
587 if (NULL == vfd)
588 return NULL;
589 *vfd = *template;
590 vfd->minor = -1;
591 vfd->parent = &dev->pci->dev;
592 vfd->release = video_device_release;
593 /* vfd->debug = tw_video_debug; */
594 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
595 dev->name, type, tw68_boards[dev->board].name);
596 return vfd;
597} 217}
598 218
599static void tw68_unregister_video(struct tw68_dev *dev) 219static int tw68_initdev(struct pci_dev *pci_dev,
600{
601
602 dprintk(DBG_FLOW, "%s: called\n", __func__);
603 if (dev->video_dev) {
604 if (-1 != dev->video_dev->minor)
605 video_unregister_device(dev->video_dev);
606 else
607 video_device_release(dev->video_dev);
608 dev->video_dev = NULL;
609 }
610 if (dev->vbi_dev) {
611 if (-1 != dev->vbi_dev->minor)
612 video_unregister_device(dev->vbi_dev);
613 else
614 video_device_release(dev->vbi_dev);
615 dev->vbi_dev = NULL;
616 }
617 if (dev->radio_dev) {
618 if (-1 != dev->radio_dev->minor)
619 video_unregister_device(dev->radio_dev);
620 else
621 video_device_release(dev->radio_dev);
622 dev->radio_dev = NULL;
623 }
624}
625
626static void mpeg_ops_attach(struct tw68_mpeg_ops *ops,
627 struct tw68_dev *dev)
628{
629 int err;
630
631 dprintk(DBG_FLOW, "%s: called\n", __func__);
632 if (NULL != dev->mops)
633 return;
634 if (tw68_boards[dev->board].mpeg != ops->type)
635 return;
636 err = ops->init(dev);
637 if (0 != err)
638 return;
639 dev->mops = ops;
640}
641
642static void mpeg_ops_detach(struct tw68_mpeg_ops *ops,
643 struct tw68_dev *dev)
644{
645
646 if (NULL == dev->mops)
647 return;
648 if (dev->mops != ops)
649 return;
650 dev->mops->fini(dev);
651 dev->mops = NULL;
652}
653
654static int __devinit tw68_initdev(struct pci_dev *pci_dev,
655 const struct pci_device_id *pci_id) 220 const struct pci_device_id *pci_id)
656{ 221{
657 struct tw68_dev *dev; 222 struct tw68_dev *dev;
658 struct tw68_mpeg_ops *mops; 223 int vidnr = -1;
659 int err; 224 int err;
660 225
661 if (tw68_devcount == TW68_MAXBOARDS) 226 dev = devm_kzalloc(&pci_dev->dev, sizeof(*dev), GFP_KERNEL);
662 return -ENOMEM;
663
664 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
665 if (NULL == dev) 227 if (NULL == dev)
666 return -ENOMEM; 228 return -ENOMEM;
667 229
230 dev->instance = v4l2_device_set_name(&dev->v4l2_dev, "tw68",
231 &tw68_instance);
232
668 err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev); 233 err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
669 if (err) 234 if (err)
670 goto fail0; 235 return err;
671 236
672 /* pci init */ 237 /* pci init */
673 dev->pci = pci_dev; 238 dev->pci = pci_dev;
@@ -676,33 +241,10 @@ static int __devinit tw68_initdev(struct pci_dev *pci_dev,
676 goto fail1; 241 goto fail1;
677 } 242 }
678 243
679 dev->nr = tw68_devcount; 244 dev->name = dev->v4l2_dev.name;
680 sprintf(dev->name, "tw%x[%d]", pci_dev->device, dev->nr);
681 245
682 /* pci quirks */
683 if (pci_pci_problems) {
684 if (pci_pci_problems & PCIPCI_TRITON)
685 printk(KERN_INFO "%s: quirk: PCIPCI_TRITON\n",
686 dev->name);
687 if (pci_pci_problems & PCIPCI_NATOMA)
688 printk(KERN_INFO "%s: quirk: PCIPCI_NATOMA\n",
689 dev->name);
690 if (pci_pci_problems & PCIPCI_VIAETBF)
691 printk(KERN_INFO "%s: quirk: PCIPCI_VIAETBF\n",
692 dev->name);
693 if (pci_pci_problems & PCIPCI_VSFX)
694 printk(KERN_INFO "%s: quirk: PCIPCI_VSFX\n",
695 dev->name);
696#ifdef PCIPCI_ALIMAGIK
697 if (pci_pci_problems & PCIPCI_ALIMAGIK) {
698 printk(KERN_INFO "%s: quirk: PCIPCI_ALIMAGIK "
699 "-- latency fixup\n", dev->name);
700 latency = 0x0A;
701 }
702#endif
703 }
704 if (UNSET != latency) { 246 if (UNSET != latency) {
705 printk(KERN_INFO "%s: setting pci latency timer to %d\n", 247 pr_info("%s: setting pci latency timer to %d\n",
706 dev->name, latency); 248 dev->name, latency);
707 pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency); 249 pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency);
708 } 250 }
@@ -710,13 +252,12 @@ static int __devinit tw68_initdev(struct pci_dev *pci_dev,
710 /* print pci info */ 252 /* print pci info */
711 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); 253 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
712 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); 254 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
713 printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " 255 pr_info("%s: found at %s, rev: %d, irq: %d, latency: %d, mmio: 0x%llx\n",
714 "latency: %d, mmio: 0x%llx\n", dev->name, 256 dev->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
715 pci_name(pci_dev), dev->pci_rev, pci_dev->irq, dev->pci_lat, 257 dev->pci_lat, (u64)pci_resource_start(pci_dev, 0));
716 (unsigned long long)pci_resource_start(pci_dev, 0));
717 pci_set_master(pci_dev); 258 pci_set_master(pci_dev);
718 if (!pci_dma_supported(pci_dev, DMA_BIT_MASK(32))) { 259 if (!pci_dma_supported(pci_dev, DMA_BIT_MASK(32))) {
719 printk("%s: Oops: no 32bit PCI DMA ???\n", dev->name); 260 pr_info("%s: Oops: no 32bit PCI DMA ???\n", dev->name);
720 err = -EIO; 261 err = -EIO;
721 goto fail1; 262 goto fail1;
722 } 263 }
@@ -730,7 +271,7 @@ static int __devinit tw68_initdev(struct pci_dev *pci_dev,
730 dev->vdecoder = TW6801; 271 dev->vdecoder = TW6801;
731 dev->board_virqmask = TW68_VID_INTS | TW68_VID_INTSX; 272 dev->board_virqmask = TW68_VID_INTS | TW68_VID_INTSX;
732 break; 273 break;
733 case PCI_DEVICE_ID_6804: /* Video decoder for TW6805 */ 274 case PCI_DEVICE_ID_6804: /* Video decoder for TW6804 */
734 dev->vdecoder = TW6804; 275 dev->vdecoder = TW6804;
735 dev->board_virqmask = TW68_VID_INTS | TW68_VID_INTSX; 276 dev->board_virqmask = TW68_VID_INTS | TW68_VID_INTSX;
736 break; 277 break;
@@ -739,35 +280,13 @@ static int __devinit tw68_initdev(struct pci_dev *pci_dev,
739 dev->board_virqmask = TW68_VID_INTS | TW68_VID_INTSX; 280 dev->board_virqmask = TW68_VID_INTS | TW68_VID_INTSX;
740 break; 281 break;
741 } 282 }
742 /* board config */
743 dev->board = pci_id->driver_data;
744 if (card[dev->nr] >= 0 &&
745 card[dev->nr] < tw68_bcount)
746 dev->board = card[dev->nr];
747 if (TW68_BOARD_NOAUTO == dev->board) {
748 must_configure_manually();
749 dev->board = TW68_BOARD_UNKNOWN;
750 }
751 dev->autodetected = card[dev->nr] != dev->board;
752 dev->tuner_type = tw68_boards[dev->board].tuner_type;
753 dev->tuner_addr = tw68_boards[dev->board].tuner_addr;
754 dev->radio_type = tw68_boards[dev->board].radio_type;
755 dev->radio_addr = tw68_boards[dev->board].radio_addr;
756 dev->tda9887_conf = tw68_boards[dev->board].tda9887_conf;
757 if (UNSET != tuner[dev->nr])
758 dev->tuner_type = tuner[dev->nr];
759 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
760 dev->name, pci_dev->subsystem_vendor,
761 pci_dev->subsystem_device, tw68_boards[dev->board].name,
762 dev->board, dev->autodetected ?
763 "autodetected" : "insmod option");
764 283
765 /* get mmio */ 284 /* get mmio */
766 if (!request_mem_region(pci_resource_start(pci_dev, 0), 285 if (!request_mem_region(pci_resource_start(pci_dev, 0),
767 pci_resource_len(pci_dev, 0), 286 pci_resource_len(pci_dev, 0),
768 dev->name)) { 287 dev->name)) {
769 err = -EBUSY; 288 err = -EBUSY;
770 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", 289 pr_err("%s: can't get MMIO memory @ 0x%llx\n",
771 dev->name, 290 dev->name,
772 (unsigned long long)pci_resource_start(pci_dev, 0)); 291 (unsigned long long)pci_resource_start(pci_dev, 0));
773 goto fail1; 292 goto fail1;
@@ -777,185 +296,75 @@ static int __devinit tw68_initdev(struct pci_dev *pci_dev,
777 dev->bmmio = (__u8 __iomem *)dev->lmmio; 296 dev->bmmio = (__u8 __iomem *)dev->lmmio;
778 if (NULL == dev->lmmio) { 297 if (NULL == dev->lmmio) {
779 err = -EIO; 298 err = -EIO;
780 printk(KERN_ERR "%s: can't ioremap() MMIO memory\n", 299 pr_err("%s: can't ioremap() MMIO memory\n",
781 dev->name); 300 dev->name);
782 goto fail2; 301 goto fail2;
783 } 302 }
784 /* initialize hardware #1 */ 303 /* initialize hardware #1 */
785 /* First, take care of anything unique to a particular card */
786 tw68_board_init1(dev);
787 /* Then do any initialisation wanted before interrupts are on */ 304 /* Then do any initialisation wanted before interrupts are on */
788 tw68_hw_init1(dev); 305 tw68_hw_init1(dev);
789 306
790 /* get irq */ 307 /* get irq */
791 err = request_irq(pci_dev->irq, tw68_irq, 308 err = devm_request_irq(&pci_dev->dev, pci_dev->irq, tw68_irq,
792 IRQF_SHARED | IRQF_DISABLED, dev->name, dev); 309 IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
793 if (err < 0) { 310 if (err < 0) {
794 printk(KERN_ERR "%s: can't get IRQ %d\n", 311 pr_err("%s: can't get IRQ %d\n",
795 dev->name, pci_dev->irq); 312 dev->name, pci_dev->irq);
796 goto fail3; 313 goto fail3;
797 } 314 }
798 315
799#ifdef TW68_TESTING
800 dev->pci_irqmask |= TW68_SBDONE;
801 tw_setl(TW68_INTMASK, dev->pci_irqmask);
802 printk(KERN_INFO "Calling tw68_i2c_register\n");
803 /* Register the i2c bus */
804 tw68_i2c_register(dev);
805#endif
806
807 /* 316 /*
808 * Now do remainder of initialisation, first for 317 * Now do remainder of initialisation, first for
809 * things unique for this card, then for general board 318 * things unique for this card, then for general board
810 */ 319 */
811 tw68_board_init2(dev); 320 if (dev->instance < TW68_MAXBOARDS)
812 321 vidnr = video_nr[dev->instance];
813 tw68_hw_init2(dev); 322 /* initialise video function first */
814 323 err = tw68_video_init2(dev, vidnr);
815#if 0
816 /* load i2c helpers */
817 if (card_is_empress(dev)) {
818 struct v4l2_subdev *sd =
819 v4l2_i2c_new_subdev(&dev->i2c_adap, "saa6752hs",
820 "saa6752hs", 0x20);
821
822 if (sd)
823 sd->grp_id = GRP_EMPRESS;
824 }
825
826 request_submodules(dev);
827#endif
828
829 v4l2_prio_init(&dev->prio);
830
831 mutex_lock(&tw68_devlist_lock);
832 list_for_each_entry(mops, &mops_list, next)
833 mpeg_ops_attach(mops, dev);
834 list_add_tail(&dev->devlist, &tw68_devlist);
835 mutex_unlock(&tw68_devlist_lock);
836
837 /* check for signal */
838 tw68_irq_video_signalchange(dev);
839
840#if 0
841 if (TUNER_ABSENT != dev->tuner_type)
842 tw_call_all(dev, core, s_standby, 0);
843#endif
844
845 dev->video_dev = vdev_init(dev, &tw68_video_template, "video");
846 err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER,
847 video_nr[dev->nr]);
848 if (err < 0) { 324 if (err < 0) {
849 printk(KERN_INFO "%s: can't register video device\n", 325 pr_err("%s: can't register video device\n",
850 dev->name); 326 dev->name);
851 goto fail4; 327 goto fail4;
852 } 328 }
853 printk(KERN_INFO "%s: registered device video%d [v4l2]\n", 329 tw_setl(TW68_INTMASK, dev->pci_irqmask);
854 dev->name, dev->video_dev->num);
855
856 dev->vbi_dev = vdev_init(dev, &tw68_video_template, "vbi");
857
858 err = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
859 vbi_nr[dev->nr]);
860 if (err < 0) {
861 printk(KERN_INFO "%s: can't register vbi device\n",
862 dev->name);
863 goto fail4;
864 }
865 printk(KERN_INFO "%s: registered device vbi%d\n",
866 dev->name, dev->vbi_dev->num);
867
868 if (card_has_radio(dev)) {
869 dev->radio_dev = vdev_init(dev, &tw68_radio_template,
870 "radio");
871 err = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
872 radio_nr[dev->nr]);
873 if (err < 0) {
874 /* TODO - need to unregister vbi? */
875 printk(KERN_INFO "%s: can't register radio device\n",
876 dev->name);
877 goto fail4;
878 }
879 printk(KERN_INFO "%s: registered device radio%d\n",
880 dev->name, dev->radio_dev->num);
881 }
882
883 /* everything worked */
884 tw68_devcount++;
885 330
886 if (tw68_dmasound_init && !dev->dmasound.priv_data) 331 pr_info("%s: registered device %s\n",
887 tw68_dmasound_init(dev); 332 dev->name, video_device_node_name(&dev->vdev));
888 333
889 return 0; 334 return 0;
890 335
891 fail4: 336fail4:
892 tw68_unregister_video(dev); 337 video_unregister_device(&dev->vdev);
893#ifdef TW68_TESTING 338fail3:
894 tw68_i2c_unregister(dev);
895#endif
896 free_irq(pci_dev->irq, dev);
897 fail3:
898 tw68_hwfini(dev);
899 iounmap(dev->lmmio); 339 iounmap(dev->lmmio);
900 fail2: 340fail2:
901 release_mem_region(pci_resource_start(pci_dev, 0), 341 release_mem_region(pci_resource_start(pci_dev, 0),
902 pci_resource_len(pci_dev, 0)); 342 pci_resource_len(pci_dev, 0));
903 fail1: 343fail1:
904 v4l2_device_unregister(&dev->v4l2_dev); 344 v4l2_device_unregister(&dev->v4l2_dev);
905 fail0:
906 kfree(dev);
907 return err; 345 return err;
908} 346}
909 347
910static void __devexit tw68_finidev(struct pci_dev *pci_dev) 348static void tw68_finidev(struct pci_dev *pci_dev)
911{ 349{
912 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); 350 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
913 struct tw68_dev *dev = 351 struct tw68_dev *dev =
914 container_of(v4l2_dev, struct tw68_dev, v4l2_dev); 352 container_of(v4l2_dev, struct tw68_dev, v4l2_dev);
915 struct tw68_mpeg_ops *mops;
916
917 dprintk(DBG_FLOW, "%s: called\n", __func__);
918 /* Release DMA sound modules if present */
919 if (tw68_dmasound_exit && dev->dmasound.priv_data)
920 tw68_dmasound_exit(dev);
921 353
922 /* shutdown subsystems */ 354 /* shutdown subsystems */
923 tw68_hwfini(dev);
924 tw_clearl(TW68_DMAC, TW68_DMAP_EN | TW68_FIFO_EN); 355 tw_clearl(TW68_DMAC, TW68_DMAP_EN | TW68_FIFO_EN);
925 tw_writel(TW68_INTMASK, 0); 356 tw_writel(TW68_INTMASK, 0);
926 357
927 /* unregister */ 358 /* unregister */
928 mutex_lock(&tw68_devlist_lock); 359 video_unregister_device(&dev->vdev);
929 list_del(&dev->devlist); 360 v4l2_ctrl_handler_free(&dev->hdl);
930 list_for_each_entry(mops, &mops_list, next)
931 mpeg_ops_detach(mops, dev);
932 mutex_unlock(&tw68_devlist_lock);
933 tw68_devcount--;
934
935#ifdef TW68_TESTING
936 tw68_i2c_unregister(dev);
937#endif
938 tw68_unregister_video(dev);
939
940
941 /* the DMA sound modules should be unloaded before reaching
942 this, but just in case they are still present... */
943 if (dev->dmasound.priv_data != NULL) {
944 free_irq(pci_dev->irq, &dev->dmasound);
945 dev->dmasound.priv_data = NULL;
946 }
947
948 361
949 /* release resources */ 362 /* release resources */
950 free_irq(pci_dev->irq, dev);
951 iounmap(dev->lmmio); 363 iounmap(dev->lmmio);
952 release_mem_region(pci_resource_start(pci_dev, 0), 364 release_mem_region(pci_resource_start(pci_dev, 0),
953 pci_resource_len(pci_dev, 0)); 365 pci_resource_len(pci_dev, 0));
954 366
955 v4l2_device_unregister(&dev->v4l2_dev); 367 v4l2_device_unregister(&dev->v4l2_dev);
956
957 /* free memory */
958 kfree(dev);
959} 368}
960 369
961#ifdef CONFIG_PM 370#ifdef CONFIG_PM
@@ -966,28 +375,15 @@ static int tw68_suspend(struct pci_dev *pci_dev , pm_message_t state)
966 struct tw68_dev *dev = container_of(v4l2_dev, 375 struct tw68_dev *dev = container_of(v4l2_dev,
967 struct tw68_dev, v4l2_dev); 376 struct tw68_dev, v4l2_dev);
968 377
969 dprintk(DBG_FLOW, "%s: called\n", __func__);
970 tw_clearl(TW68_DMAC, TW68_DMAP_EN | TW68_FIFO_EN); 378 tw_clearl(TW68_DMAC, TW68_DMAP_EN | TW68_FIFO_EN);
971 dev->pci_irqmask &= ~TW68_VID_INTS; 379 dev->pci_irqmask &= ~TW68_VID_INTS;
972 tw_writel(TW68_INTMASK, 0); 380 tw_writel(TW68_INTMASK, 0);
973 381
974 dev->insuspend = 1;
975 synchronize_irq(pci_dev->irq); 382 synchronize_irq(pci_dev->irq);
976 383
977 /* Disable timeout timers - if we have active buffers, we will
978 fill them on resume*/
979
980 del_timer(&dev->video_q.timeout);
981 del_timer(&dev->vbi_q.timeout);
982 del_timer(&dev->ts_q.timeout);
983
984#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
985 if (dev->remote)
986 tw68_ir_stop(dev);
987#endif
988
989 pci_save_state(pci_dev); 384 pci_save_state(pci_dev);
990 pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state)); 385 pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state));
386 vb2_discard_done(&dev->vidq);
991 387
992 return 0; 388 return 0;
993} 389}
@@ -997,54 +393,25 @@ static int tw68_resume(struct pci_dev *pci_dev)
997 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); 393 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
998 struct tw68_dev *dev = container_of(v4l2_dev, 394 struct tw68_dev *dev = container_of(v4l2_dev,
999 struct tw68_dev, v4l2_dev); 395 struct tw68_dev, v4l2_dev);
396 struct tw68_buf *buf;
1000 unsigned long flags; 397 unsigned long flags;
1001 398
1002 dprintk(DBG_FLOW, "%s: called\n", __func__);
1003 pci_set_power_state(pci_dev, PCI_D0); 399 pci_set_power_state(pci_dev, PCI_D0);
1004 pci_restore_state(pci_dev); 400 pci_restore_state(pci_dev);
1005 401
1006 /* Do things that are done in tw68_initdev , 402 /* Do things that are done in tw68_initdev ,
1007 except of initializing memory structures.*/ 403 except of initializing memory structures.*/
1008 404
1009 tw68_board_init1(dev);
1010
1011 /* tw68_hw_init1 */
1012 if (tw68_boards[dev->board].video_out)
1013 tw68_videoport_init(dev);
1014 if (card_has_mpeg(dev))
1015 tw68_ts_init_hw(dev);
1016#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
1017 if (dev->remote)
1018 tw68_ir_start(dev, dev->remote);
1019#endif
1020 tw68_hw_enable1(dev);
1021
1022 msleep(100); 405 msleep(100);
1023 406
1024 tw68_board_init2(dev);
1025
1026 /*tw68_hw_init2*/
1027 tw68_set_tvnorm_hw(dev); 407 tw68_set_tvnorm_hw(dev);
1028 tw68_tvaudio_setmute(dev);
1029/* tw68_tvaudio_setvolume(dev, dev->ctl_volume); */
1030 tw68_tvaudio_init(dev);
1031 tw68_irq_video_signalchange(dev);
1032 408
1033 /*resume unfinished buffer(s)*/ 409 /*resume unfinished buffer(s)*/
1034 spin_lock_irqsave(&dev->slock, flags); 410 spin_lock_irqsave(&dev->slock, flags);
1035 tw68_buffer_requeue(dev, &dev->video_q); 411 buf = container_of(dev->active.next, struct tw68_buf, list);
1036 tw68_buffer_requeue(dev, &dev->vbi_q);
1037 tw68_buffer_requeue(dev, &dev->ts_q);
1038
1039 /* FIXME: Disable DMA audio sound - temporary till proper support
1040 is implemented*/
1041 412
1042 dev->dmasound.dma_running = 0; 413 tw68_video_start_dma(dev, buf);
1043 414
1044 /* start DMA now*/
1045 dev->insuspend = 0;
1046 smp_wmb();
1047 tw68_set_dmabits(dev);
1048 spin_unlock_irqrestore(&dev->slock, flags); 415 spin_unlock_irqrestore(&dev->slock, flags);
1049 416
1050 return 0; 417 return 0;
@@ -1057,35 +424,11 @@ static struct pci_driver tw68_pci_driver = {
1057 .name = "tw68", 424 .name = "tw68",
1058 .id_table = tw68_pci_tbl, 425 .id_table = tw68_pci_tbl,
1059 .probe = tw68_initdev, 426 .probe = tw68_initdev,
1060 .remove = __devexit_p(tw68_finidev), 427 .remove = tw68_finidev,
1061#ifdef CONFIG_PM 428#ifdef CONFIG_PM
1062 .suspend = tw68_suspend, 429 .suspend = tw68_suspend,
1063 .resume = tw68_resume 430 .resume = tw68_resume
1064#endif 431#endif
1065}; 432};
1066 433
1067static int tw68_init(void) 434module_pci_driver(tw68_pci_driver);
1068{
1069 if (core_debug & DBG_FLOW)
1070 printk(KERN_DEBUG "%s: called\n", __func__);
1071 INIT_LIST_HEAD(&tw68_devlist);
1072 printk(KERN_INFO "tw68: v4l2 driver version %d.%d.%d loaded\n",
1073 (TW68_VERSION_CODE >> 16) & 0xff,
1074 (TW68_VERSION_CODE >> 8) & 0xff,
1075 TW68_VERSION_CODE & 0xff);
1076#if 0
1077 printk(KERN_INFO "tw68: snapshot date %04d-%02d-%02d\n",
1078 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
1079#endif
1080 return pci_register_driver(&tw68_pci_driver);
1081}
1082
1083static void module_cleanup(void)
1084{
1085 if (core_debug & DBG_FLOW)
1086 printk(KERN_DEBUG "%s: called\n", __func__);
1087 pci_unregister_driver(&tw68_pci_driver);
1088}
1089
1090module_init(tw68_init);
1091module_exit(module_cleanup);
diff --git a/drivers/media/pci/tw68/tw68-i2c.c b/drivers/media/pci/tw68/tw68-i2c.c
deleted file mode 100644
index 38659d0b1e18..000000000000
--- a/drivers/media/pci/tw68/tw68-i2c.c
+++ /dev/null
@@ -1,245 +0,0 @@
1/*
2 * tw68 code to handle the i2c interface.
3 *
4 * Much of this code is derived from the bt87x driver. The original
5 * work was by Gerd Knorr; more recently the code was enhanced by Mauro
6 * Carvalho Chehab. Their work is gratefully acknowledged. Full credit
7 * goes to them - any problems within this code are mine.
8 *
9 * Copyright (C) 2009 William M. Brack <wbrack@mmm.com.hk>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26#include <linux/init.h>
27#include <linux/list.h>
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/slab.h>
31#include <linux/delay.h>
32
33#include "tw68.h"
34#include <media/v4l2-common.h>
35#include <linux/i2c-algo-bit.h>
36
37/*----------------------------------------------------------------*/
38
39static unsigned int i2c_debug;
40module_param(i2c_debug, int, 0644);
41MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
42
43#if 0
44static unsigned int i2c_scan;
45module_param(i2c_scan, int, 0444);
46MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
47#endif
48
49#define d1printk if (1 == i2c_debug) printk
50
51#define I2C_CLOCK 0xa6 /* 99.4 kHz */
52
53/*----------------------------------------------------------------------*/
54/* Although the TW68xx i2c controller has a "hardware" mode, where all of
55 * the low-level i2c/smbbus is handled by the chip, it appears that mode
56 * is not suitable for linux i2c handling routines because extended "bursts"
57 * of data (sequences of bytes without intervening START/STOP bits) are
58 * not possible. Instead, we put the chip into "software" mode, and handle
59 * the i2c bus at a low level. To accomplish this, we use the routines
60 * from the i2c modules.
61 *
62 * Because the particular boards which I had for testing did not have any
63 * devices attached to the i2c bus, I have been unable to test these
64 * routines.
65 */
66
67/*----------------------------------------------------------------------*/
68/* I2C functions - "bit-banging" adapter (software i2c) */
69
70/* tw68_bit_setcl
71 * Handles "toggling" the i2c clock bit
72 */
73static void tw68_bit_setscl(void *data, int state)
74{
75 struct tw68_dev *dev = data;
76
77 tw_andorb(TW68_SBUSC, (state ? 1 : 0) << TW68_SSCLK, TW68_SSCLK_B);
78}
79
80/* tw68_bit_setsda
81 * Handles "toggling" the i2c data bit
82 */
83static void tw68_bit_setsda(void *data, int state)
84{
85 struct tw68_dev *dev = data;
86
87 tw_andorb(TW68_SBUSC, (state ? 1 : 0) << TW68_SSDAT, TW68_SSDAT_B);
88}
89
90/* tw68_bit_getscl
91 *
92 * Returns the current state of the clock bit
93 */
94static int tw68_bit_getscl(void *data)
95{
96 struct tw68_dev *dev = data;
97
98 return (tw_readb(TW68_SBUSC) & TW68_SSCLK_B) ? 1 : 0;
99}
100
101/* tw68_bit_getsda
102 *
103 * Returns the current state of the data bit
104 */
105static int tw68_bit_getsda(void *data)
106{
107 struct tw68_dev *dev = data;
108
109 return (tw_readb(TW68_SBUSC) & TW68_SSDAT_B) ? 1 : 0;
110}
111
112static struct i2c_algo_bit_data __devinitdata tw68_i2c_algo_bit_template = {
113 .setsda = tw68_bit_setsda,
114 .setscl = tw68_bit_setscl,
115 .getsda = tw68_bit_getsda,
116 .getscl = tw68_bit_getscl,
117 .udelay = 16,
118 .timeout = 200,
119};
120
121static struct i2c_client tw68_client_template = {
122 .name = "tw68 internal",
123};
124
125/*----------------------------------------------------------------*/
126
127static int attach_inform(struct i2c_client *client)
128{
129/* struct tw68_dev *dev = client->adapter->algo_data; */
130
131 d1printk("%s i2c attach [addr=0x%x,client=%s]\n",
132 client->driver->driver.name, client->addr, client->name);
133
134 switch (client->addr) {
135 /* No info yet on what addresses to expect */
136 }
137
138 return 0;
139}
140
141static struct i2c_adapter tw68_adap_sw_template = {
142 .owner = THIS_MODULE,
143 .name = "tw68_sw",
144 .client_register = attach_inform,
145};
146
147static int tw68_i2c_eeprom(struct tw68_dev *dev, unsigned char *eedata,
148 int len)
149{
150 unsigned char buf;
151 int i, err;
152
153 dev->i2c_client.addr = 0xa0 >> 1;
154 buf = 256 - len;
155
156 err = i2c_master_send(&dev->i2c_client, &buf, 1);
157 if (1 != err) {
158 printk(KERN_INFO "%s: Huh, no eeprom present (err = %d)?\n",
159 dev->name, err);
160 return -1;
161 }
162 err = i2c_master_recv(&dev->i2c_client, eedata, len);
163 if (len != err) {
164 printk(KERN_WARNING "%s: i2c eeprom read error (err=%d)\n",
165 dev->name, err);
166 return -1;
167 }
168
169 for (i = 0; i < len; i++) {
170 if (0 == (i % 16))
171 printk(KERN_INFO "%s: i2c eeprom %02x:",
172 dev->name, i);
173 printk(KERN_INFO " %02x", eedata[i]);
174 if (15 == (i % 16))
175 printk("\n");
176 }
177 return 0;
178}
179
180#if 0
181static char *i2c_devs[128] = {
182 [0xa0 >> 1] = "eeprom",
183};
184
185static void do_i2c_scan(char *name, struct i2c_client *c)
186{
187 unsigned char buf;
188 int i, rc;
189
190 for (i = 0; i < ARRAY_SIZE(i2c_devs); i++) {
191 c->addr = i;
192 rc = i2c_master_recv(c, &buf, 1);
193 if (rc < 0)
194 continue;
195 printk(KERN_INFO "%s: i2c scan: found device "
196 "@ 0x%x [%s]\n", name, i << 1,
197 i2c_devs[i] ? i2c_devs[i] : "???");
198 }
199}
200#endif
201
202int __devinit tw68_i2c_register(struct tw68_dev *dev)
203{
204 int rc;
205
206printk(KERN_DEBUG "%s: Registering i2c module\n", __func__);
207 tw_writeb(TW68_I2C_RST, 1); /* reset the i2c module */
208
209 memcpy(&dev->i2c_client, &tw68_client_template,
210 sizeof(tw68_client_template));
211
212 memcpy(&dev->i2c_adap, &tw68_adap_sw_template,
213 sizeof(tw68_adap_sw_template));
214 dev->i2c_adap.algo_data = &dev->i2c_algo;
215 dev->i2c_adap.dev.parent = &dev->pci->dev;
216
217 memcpy(&dev->i2c_algo, &tw68_i2c_algo_bit_template,
218 sizeof(tw68_i2c_algo_bit_template));
219 dev->i2c_algo.data = dev;
220 /* TODO - may want to set better name (see bttv code) */
221
222 i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
223 dev->i2c_client.adapter = &dev->i2c_adap;
224
225 /* Assure chip is in "software" mode */
226 tw_writel(TW68_SBUSC, TW68_SSDAT | TW68_SSCLK);
227 tw68_bit_setscl(dev, 1);
228 tw68_bit_setsda(dev, 1);
229
230 rc = i2c_bit_add_bus(&dev->i2c_adap);
231
232 tw68_i2c_eeprom(dev, dev->eedata, sizeof(dev->eedata));
233#if 0
234 if (i2c_scan)
235 do_i2c_scan(dev->name, &dev->i2c_client);
236#endif
237
238 return rc;
239}
240
241int tw68_i2c_unregister(struct tw68_dev *dev)
242{
243 i2c_del_adapter(&dev->i2c_adap);
244 return 0;
245}
diff --git a/drivers/media/pci/tw68/tw68-reg.h b/drivers/media/pci/tw68/tw68-reg.h
index 314bc43cd9d3..f60b3a896fa7 100644
--- a/drivers/media/pci/tw68/tw68-reg.h
+++ b/drivers/media/pci/tw68/tw68-reg.h
@@ -8,7 +8,11 @@
8 * acknowledged. Full credit goes to them - any problems within this code 8 * acknowledged. Full credit goes to them - any problems within this code
9 * are mine. 9 * are mine.
10 * 10 *
11 * Copyright (C) William M. Brack <wbrack@mmm.com.hk> 11 * Copyright (C) William M. Brack
12 *
13 * Refactored and updated to the latest v4l core frameworks:
14 *
15 * Copyright (C) 2014 Hans Verkuil <hverkuil@xs4all.nl>
12 * 16 *
13 * This program is free software; you can redistribute it and/or modify 17 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by 18 * it under the terms of the GNU General Public License as published by
@@ -19,10 +23,6 @@
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details. 25 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26*/ 26*/
27 27
28#ifndef _TW68_REG_H_ 28#ifndef _TW68_REG_H_
diff --git a/drivers/media/pci/tw68/tw68-risc.c b/drivers/media/pci/tw68/tw68-risc.c
index 66273bbd51c5..7439db212a69 100644
--- a/drivers/media/pci/tw68/tw68-risc.c
+++ b/drivers/media/pci/tw68/tw68-risc.c
@@ -9,7 +9,11 @@
9 * acknowledged. Full credit goes to them - any problems within this code 9 * acknowledged. Full credit goes to them - any problems within this code
10 * are mine. 10 * are mine.
11 * 11 *
12 * Copyright (C) 2009 William M. Brack <wbrack@mmm.com.hk> 12 * Copyright (C) 2009 William M. Brack
13 *
14 * Refactored and updated to the latest v4l core frameworks:
15 *
16 * Copyright (C) 2014 Hans Verkuil <hverkuil@xs4all.nl>
13 * 17 *
14 * This program is free software; you can redistribute it and/or modify 18 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by 19 * it under the terms of the GNU General Public License as published by
@@ -20,16 +24,10 @@
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details. 26 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 */ 27 */
28 28
29#include "tw68.h" 29#include "tw68.h"
30 30
31#define NO_SYNC_LINE (-1U)
32
33/** 31/**
34 * @rp pointer to current risc program position 32 * @rp pointer to current risc program position
35 * @sglist pointer to "scatter-gather list" of buffer pointers 33 * @sglist pointer to "scatter-gather list" of buffer pointers
@@ -38,32 +36,35 @@
38 * @bpl number of bytes per scan line 36 * @bpl number of bytes per scan line
39 * @padding number of bytes of padding to add 37 * @padding number of bytes of padding to add
40 * @lines number of lines in field 38 * @lines number of lines in field
41 * @lpi lines per IRQ, or 0 to not generate irqs 39 * @jump insert a jump at the start
42 * Note: IRQ to be generated _after_ lpi lines are transferred
43 */ 40 */
44static __le32 *tw68_risc_field(__le32 *rp, struct scatterlist *sglist, 41static __le32 *tw68_risc_field(__le32 *rp, struct scatterlist *sglist,
45 unsigned int offset, u32 sync_line, 42 unsigned int offset, u32 sync_line,
46 unsigned int bpl, unsigned int padding, 43 unsigned int bpl, unsigned int padding,
47 unsigned int lines, unsigned int lpi) 44 unsigned int lines, bool jump)
48{ 45{
49 struct scatterlist *sg; 46 struct scatterlist *sg;
50 unsigned int line, todo, done; 47 unsigned int line, todo, done;
51 48
52 /* sync instruction */ 49 if (jump) {
53 if (sync_line != NO_SYNC_LINE) { 50 *(rp++) = cpu_to_le32(RISC_JUMP);
54 if (sync_line == 1)
55 *(rp++) = cpu_to_le32(RISC_SYNCO);
56 else
57 *(rp++) = cpu_to_le32(RISC_SYNCE);
58 *(rp++) = 0; 51 *(rp++) = 0;
59 } 52 }
53
54 /* sync instruction */
55 if (sync_line == 1)
56 *(rp++) = cpu_to_le32(RISC_SYNCO);
57 else
58 *(rp++) = cpu_to_le32(RISC_SYNCE);
59 *(rp++) = 0;
60
60 /* scan lines */ 61 /* scan lines */
61 sg = sglist; 62 sg = sglist;
62 for (line = 0; line < lines; line++) { 63 for (line = 0; line < lines; line++) {
63 /* calculate next starting position */ 64 /* calculate next starting position */
64 while (offset && offset >= sg_dma_len(sg)) { 65 while (offset && offset >= sg_dma_len(sg)) {
65 offset -= sg_dma_len(sg); 66 offset -= sg_dma_len(sg);
66 sg++; 67 sg = sg_next(sg);
67 } 68 }
68 if (bpl <= sg_dma_len(sg) - offset) { 69 if (bpl <= sg_dma_len(sg) - offset) {
69 /* fits into current chunk */ 70 /* fits into current chunk */
@@ -86,7 +87,7 @@ static __le32 *tw68_risc_field(__le32 *rp, struct scatterlist *sglist,
86 done); 87 done);
87 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset); 88 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
88 todo -= done; 89 todo -= done;
89 sg++; 90 sg = sg_next(sg);
90 /* succeeding fragments have no offset */ 91 /* succeeding fragments have no offset */
91 while (todo > sg_dma_len(sg)) { 92 while (todo > sg_dma_len(sg)) {
92 *(rp++) = cpu_to_le32(RISC_INLINE | 93 *(rp++) = cpu_to_le32(RISC_INLINE |
@@ -94,7 +95,7 @@ static __le32 *tw68_risc_field(__le32 *rp, struct scatterlist *sglist,
94 sg_dma_len(sg)); 95 sg_dma_len(sg));
95 *(rp++) = cpu_to_le32(sg_dma_address(sg)); 96 *(rp++) = cpu_to_le32(sg_dma_address(sg));
96 todo -= sg_dma_len(sg); 97 todo -= sg_dma_len(sg);
97 sg++; 98 sg = sg_next(sg);
98 done += sg_dma_len(sg); 99 done += sg_dma_len(sg);
99 } 100 }
100 if (todo) { 101 if (todo) {
@@ -107,9 +108,6 @@ static __le32 *tw68_risc_field(__le32 *rp, struct scatterlist *sglist,
107 offset = todo; 108 offset = todo;
108 } 109 }
109 offset += padding; 110 offset += padding;
110 /* If this line needs an interrupt, put it in */
111 if (lpi && line > 0 && !(line % lpi))
112 *(rp-2) |= RISC_INT_BIT;
113 } 111 }
114 112
115 return rp; 113 return rp;
@@ -118,25 +116,25 @@ static __le32 *tw68_risc_field(__le32 *rp, struct scatterlist *sglist,
118/** 116/**
119 * tw68_risc_buffer 117 * tw68_risc_buffer
120 * 118 *
121 * This routine is called by tw68-video. It allocates 119 * This routine is called by tw68-video. It allocates
122 * memory for the dma controller "program" and then fills in that 120 * memory for the dma controller "program" and then fills in that
123 * memory with the appropriate "instructions". 121 * memory with the appropriate "instructions".
124 * 122 *
125 * @pci_dev structure with info about the pci 123 * @pci_dev structure with info about the pci
126 * slot which our device is in. 124 * slot which our device is in.
127 * @risc structure with info about the memory 125 * @risc structure with info about the memory
128 * used for our controller program. 126 * used for our controller program.
129 * @sglist scatter-gather list entry 127 * @sglist scatter-gather list entry
130 * @top_offset offset within the risc program area for the 128 * @top_offset offset within the risc program area for the
131 * first odd frame line 129 * first odd frame line
132 * @bottom_offset offset within the risc program area for the 130 * @bottom_offset offset within the risc program area for the
133 * first even frame line 131 * first even frame line
134 * @bpl number of data bytes per scan line 132 * @bpl number of data bytes per scan line
135 * @padding number of extra bytes to add at end of line 133 * @padding number of extra bytes to add at end of line
136 * @lines number of scan lines 134 * @lines number of scan lines
137 */ 135 */
138int tw68_risc_buffer(struct pci_dev *pci, 136int tw68_risc_buffer(struct pci_dev *pci,
139 struct btcx_riscmem *risc, 137 struct tw68_buf *buf,
140 struct scatterlist *sglist, 138 struct scatterlist *sglist,
141 unsigned int top_offset, 139 unsigned int top_offset,
142 unsigned int bottom_offset, 140 unsigned int bottom_offset,
@@ -146,7 +144,6 @@ int tw68_risc_buffer(struct pci_dev *pci,
146{ 144{
147 u32 instructions, fields; 145 u32 instructions, fields;
148 __le32 *rp; 146 __le32 *rp;
149 int rc;
150 147
151 fields = 0; 148 fields = 0;
152 if (UNSET != top_offset) 149 if (UNSET != top_offset)
@@ -155,29 +152,31 @@ int tw68_risc_buffer(struct pci_dev *pci,
155 fields++; 152 fields++;
156 /* 153 /*
157 * estimate risc mem: worst case is one write per page border + 154 * estimate risc mem: worst case is one write per page border +
158 * one write per scan line + syncs + jump (all 2 dwords). 155 * one write per scan line + syncs + 2 jumps (all 2 dwords).
159 * Padding can cause next bpl to start close to a page border. 156 * Padding can cause next bpl to start close to a page border.
160 * First DMA region may be smaller than PAGE_SIZE 157 * First DMA region may be smaller than PAGE_SIZE
161 */ 158 */
162 instructions = fields * (1 + (((bpl + padding) * lines) / 159 instructions = fields * (1 + (((bpl + padding) * lines) /
163 PAGE_SIZE) + lines) + 2; 160 PAGE_SIZE) + lines) + 4;
164 rc = btcx_riscmem_alloc(pci, risc, instructions * 8); 161 buf->size = instructions * 8;
165 if (rc < 0) 162 buf->cpu = pci_alloc_consistent(pci, buf->size, &buf->dma);
166 return rc; 163 if (buf->cpu == NULL)
164 return -ENOMEM;
167 165
168 /* write risc instructions */ 166 /* write risc instructions */
169 rp = risc->cpu; 167 rp = buf->cpu;
170 if (UNSET != top_offset) /* generates SYNCO */ 168 if (UNSET != top_offset) /* generates SYNCO */
171 rp = tw68_risc_field(rp, sglist, top_offset, 1, 169 rp = tw68_risc_field(rp, sglist, top_offset, 1,
172 bpl, padding, lines, 0); 170 bpl, padding, lines, true);
173 if (UNSET != bottom_offset) /* generates SYNCE */ 171 if (UNSET != bottom_offset) /* generates SYNCE */
174 rp = tw68_risc_field(rp, sglist, bottom_offset, 2, 172 rp = tw68_risc_field(rp, sglist, bottom_offset, 2,
175 bpl, padding, lines, 0); 173 bpl, padding, lines, top_offset == UNSET);
176 174
177 /* save pointer to jmp instruction address */ 175 /* save pointer to jmp instruction address */
178 risc->jmp = rp; 176 buf->jmp = rp;
177 buf->cpu[1] = cpu_to_le32(buf->dma + 8);
179 /* assure risc buffer hasn't overflowed */ 178 /* assure risc buffer hasn't overflowed */
180 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); 179 BUG_ON((buf->jmp - buf->cpu + 2) * sizeof(buf->cpu[0]) > buf->size);
181 return 0; 180 return 0;
182} 181}
183 182
@@ -204,65 +203,28 @@ static void tw68_risc_decode(u32 risc, u32 addr)
204 203
205 p = RISC_OP(risc); 204 p = RISC_OP(risc);
206 if (!(risc & 0x80000000) || !instr[p].name) { 205 if (!(risc & 0x80000000) || !instr[p].name) {
207 printk(KERN_DEBUG "0x%08x [ INVALID ]\n", risc); 206 pr_debug("0x%08x [ INVALID ]\n", risc);
208 return; 207 return;
209 } 208 }
210 printk(KERN_DEBUG "0x%08x %-9s IRQ=%d", 209 pr_debug("0x%08x %-9s IRQ=%d",
211 risc, instr[p].name, (risc >> 27) & 1); 210 risc, instr[p].name, (risc >> 27) & 1);
212 if (instr[p].has_data_type) 211 if (instr[p].has_data_type)
213 printk(KERN_DEBUG " Type=%d", (risc >> 24) & 7); 212 pr_debug(" Type=%d", (risc >> 24) & 7);
214 if (instr[p].has_byte_info) 213 if (instr[p].has_byte_info)
215 printk(KERN_DEBUG " Start=0x%03x Count=%03u", 214 pr_debug(" Start=0x%03x Count=%03u",
216 (risc >> 12) & 0xfff, risc & 0xfff); 215 (risc >> 12) & 0xfff, risc & 0xfff);
217 if (instr[p].has_addr) 216 if (instr[p].has_addr)
218 printk(KERN_DEBUG " StartAddr=0x%08x", addr); 217 pr_debug(" StartAddr=0x%08x", addr);
219 printk(KERN_DEBUG "\n"); 218 pr_debug("\n");
220} 219}
221 220
222void tw68_risc_program_dump(struct tw68_core *core, 221void tw68_risc_program_dump(struct tw68_core *core, struct tw68_buf *buf)
223 struct btcx_riscmem *risc)
224{ 222{
225 __le32 *addr; 223 const __le32 *addr;
226 224
227 printk(KERN_DEBUG "%s: risc_program_dump: risc=%p, " 225 pr_debug("%s: risc_program_dump: risc=%p, buf->cpu=0x%p, buf->jmp=0x%p\n",
228 "risc->cpu=0x%p, risc->jmp=0x%p\n", 226 core->name, buf, buf->cpu, buf->jmp);
229 core->name, risc, risc->cpu, risc->jmp); 227 for (addr = buf->cpu; addr <= buf->jmp; addr += 2)
230 for (addr = risc->cpu; addr <= risc->jmp; addr += 2)
231 tw68_risc_decode(*addr, *(addr+1)); 228 tw68_risc_decode(*addr, *(addr+1));
232} 229}
233EXPORT_SYMBOL_GPL(tw68_risc_program_dump);
234#endif 230#endif
235
236/*
237 * tw68_risc_stopper
238 * Normally, the risc code generated for a buffer ends with a
239 * JUMP instruction to direct the DMAP processor to the code for
240 * the next buffer. However, when there is no additional buffer
241 * currently available, the code instead jumps to this routine.
242 *
243 * My first try for a "stopper" program was just a simple
244 * "jump to self" instruction. Unfortunately, this caused the
245 * video FIFO to overflow. My next attempt was to just disable
246 * the DMAP processor. Unfortunately, this caused the video
247 * decoder to lose its synchronization. The solution to this was to
248 * add a "Sync-Odd" instruction, which "eats" all the video data
249 * until the start of the next odd field.
250 */
251int tw68_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc)
252{
253 __le32 *rp;
254 int rc;
255
256 rc = btcx_riscmem_alloc(pci, risc, 8*4);
257 if (rc < 0)
258 return rc;
259
260 /* write risc inststructions */
261 rp = risc->cpu;
262 *(rp++) = cpu_to_le32(RISC_SYNCO);
263 *(rp++) = 0;
264 *(rp++) = cpu_to_le32(RISC_JUMP);
265 *(rp++) = cpu_to_le32(risc->dma);
266 risc->jmp = risc->cpu;
267 return 0;
268}
diff --git a/drivers/media/pci/tw68/tw68-ts.c b/drivers/media/pci/tw68/tw68-ts.c
deleted file mode 100644
index dacd6e621bae..000000000000
--- a/drivers/media/pci/tw68/tw68-ts.c
+++ /dev/null
@@ -1,66 +0,0 @@
1/*
2 * tw68_ts.c
3 * Part of the device driver for Techwell 68xx based cards
4 *
5 * Much of this code is derived from the cx88 and sa7134 drivers, which
6 * were in turn derived from the bt87x driver. The original work was by
7 * Gerd Knorr; more recently the code was enhanced by Mauro Carvalho Chehab,
8 * Hans Verkuil, Andy Walls and many others. Their work is gratefully
9 * acknowledged. Full credit goes to them - any problems within this code
10 * are mine.
11 *
12 * Copyright (C) 2009 William M. Brack <wbrack@mmm.com.hk>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 */
28
29#include "tw68.h"
30
31int tw68_ts_init1(struct tw68_dev *dev)
32{
33 return 0;
34}
35
36int tw68_ts_ini(struct tw68_dev *dev)
37{
38 return 0;
39}
40
41int tw68_ts_fini(struct tw68_dev *dev)
42{
43 return 0;
44}
45
46void tw68_irq_ts_done(struct tw68_dev *dev, unsigned long status)
47{
48 return;
49}
50
51int tw68_ts_register(struct tw68_mpeg_ops *ops)
52{
53 return 0;
54}
55
56void tw68_ts_unregister(struct tw68_mpeg_ops *ops)
57{
58 return;
59}
60
61int tw68_ts_init_hw(struct tw68_dev *dev)
62{
63 return 0;
64}
65
66
diff --git a/drivers/media/pci/tw68/tw68-tvaudio.c b/drivers/media/pci/tw68/tw68-tvaudio.c
deleted file mode 100644
index 656d462196f4..000000000000
--- a/drivers/media/pci/tw68/tw68-tvaudio.c
+++ /dev/null
@@ -1,80 +0,0 @@
1/*
2 * tw68_controls.c
3 * Part of the device driver for Techwell 68xx based cards
4 *
5 * Much of this code is derived from the cx88 and sa7134 drivers, which
6 * were in turn derived from the bt87x driver. The original work was by
7 * Gerd Knorr; more recently the code was enhanced by Mauro Carvalho Chehab,
8 * Hans Verkuil, Andy Walls and many others. Their work is gratefully
9 * acknowledged. Full credit goes to them - any problems within this code
10 * are mine.
11 *
12 * Copyright (C) 2009 William M. Brack <wbrack@mmm.com.hk>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 */
28
29#include "tw68.h"
30
31int tw68_tvaudio_rx2mode(u32 rx)
32{
33 return 0;
34}
35
36void tw68_tvaudio_setmute(struct tw68_dev *dev)
37{
38 return;
39}
40
41void tw68_tvaudio_setinput(struct tw68_dev *dev, struct tw68_input *in)
42{
43 return;
44}
45
46void tw68_tvaudio_setvolume(struct tw68_dev *dev, int level)
47{
48 return;
49}
50
51int tw68_tvaudio_getstereo(struct tw68_dev *dev)
52{
53 return 0;
54}
55
56void tw68_tvaudio_init(struct tw68_dev *dev)
57{
58 return;
59}
60
61int tw68_tvaudio_init2(struct tw68_dev *dev)
62{
63 return 0;
64}
65
66int tw68_tvaudio_fini(struct tw68_dev *dev)
67{
68 return 0;
69}
70
71int tw68_tvaudio_do_scan(struct tw68_dev *dev)
72{
73 return 0;
74}
75
76void tw68_enable_i2s(struct tw68_dev *dev)
77{
78 return;
79}
80
diff --git a/drivers/media/pci/tw68/tw68-vbi.c b/drivers/media/pci/tw68/tw68-vbi.c
deleted file mode 100644
index fbad3b998848..000000000000
--- a/drivers/media/pci/tw68/tw68-vbi.c
+++ /dev/null
@@ -1,76 +0,0 @@
1/*
2 * tw68_controls.c
3 * Part of the device driver for Techwell 68xx based cards
4 *
5 * Much of this code is derived from the cx88 and sa7134 drivers, which
6 * were in turn derived from the bt87x driver. The original work was by
7 * Gerd Knorr; more recently the code was enhanced by Mauro Carvalho Chehab,
8 * Hans Verkuil, Andy Walls and many others. Their work is gratefully
9 * acknowledged. Full credit goes to them - any problems within this code
10 * are mine.
11 *
12 * Copyright (C) 2009 William M. Brack <wbrack@mmm.com.hk>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 */
28
29#include "tw68.h"
30
31static int buffer_setup(struct videobuf_queue *q, unsigned int *count,
32 unsigned int *size) {
33 printk(KERN_INFO "%s: shouldn't be here!\n", __func__);
34 return 0;
35}
36static int buffer_prepare(struct videobuf_queue *q,
37 struct videobuf_buffer *vb,
38 enum v4l2_field field)
39{
40 printk(KERN_INFO "%s: shouldn't be here!\n", __func__);
41 return 0;
42}
43static void buffer_queue(struct videobuf_queue *q,
44 struct videobuf_buffer *vb)
45{
46 printk(KERN_INFO "%s: shouldn't be here!\n", __func__);
47}
48static void buffer_release(struct videobuf_queue *q,
49 struct videobuf_buffer *vb)
50{
51 printk(KERN_INFO "%s: shouldn't be here!\n", __func__);
52}
53struct videobuf_queue_ops tw68_vbi_qops = {
54 .buf_setup = buffer_setup,
55 .buf_prepare = buffer_prepare,
56 .buf_queue = buffer_queue,
57 .buf_release = buffer_release,
58};
59
60/* ------------------------------------------------------------------ */
61
62int tw68_vbi_init1(struct tw68_dev *dev)
63{
64 return 0;
65}
66
67int tw68_vbi_fini(struct tw68_dev *dev)
68{
69 return 0;
70}
71
72void tw68_irq_vbi_done(struct tw68_dev *dev, unsigned long status)
73{
74 return;
75}
76
diff --git a/drivers/media/pci/tw68/tw68-video.c b/drivers/media/pci/tw68/tw68-video.c
index ca08ca38d3bd..66fae2345fdd 100644
--- a/drivers/media/pci/tw68/tw68-video.c
+++ b/drivers/media/pci/tw68/tw68-video.c
@@ -8,7 +8,11 @@
8 * acknowledged. Full credit goes to them - any problems within this code 8 * acknowledged. Full credit goes to them - any problems within this code
9 * are mine. 9 * are mine.
10 * 10 *
11 * Copyright (C) 2009 William M. Brack <wbrack@mmm.com.hk> 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>
12 * 16 *
13 * This program is free software; you can redistribute it and/or modify 17 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by 18 * it under the terms of the GNU General Public License as published by
@@ -19,39 +23,16 @@
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details. 25 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 */ 26 */
27 27
28#include <linux/module.h> 28#include <linux/module.h>
29#include <media/v4l2-common.h> 29#include <media/v4l2-common.h>
30#include <linux/sort.h> 30#include <media/v4l2-event.h>
31#include <media/videobuf2-dma-sg.h>
31 32
32#include "tw68.h" 33#include "tw68.h"
33#include "tw68-reg.h" 34#include "tw68-reg.h"
34 35
35unsigned int video_debug;
36
37static unsigned int gbuffers = 8;
38static unsigned int noninterlaced; /* 0 */
39static unsigned int gbufsz = 768*576*4;
40static unsigned int gbufsz_max = 768*576*4;
41static char secam[] = "--";
42
43module_param(video_debug, int, 0644);
44MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
45module_param(gbuffers, int, 0444);
46MODULE_PARM_DESC(gbuffers, "number of capture buffers, range 2-32");
47module_param(noninterlaced, int, 0644);
48MODULE_PARM_DESC(noninterlaced, "capture non interlaced video");
49module_param_string(secam, secam, sizeof(secam), 0644);
50MODULE_PARM_DESC(secam, "force SECAM variant, either DK,L or Lc");
51
52#define dprintk(level, fmt, arg...) if (video_debug & (level)) \
53 printk(KERN_DEBUG "%s/0: " fmt, dev->name , ## arg)
54
55/* ------------------------------------------------------------------ */ 36/* ------------------------------------------------------------------ */
56/* data structs for video */ 37/* data structs for video */
57/* 38/*
@@ -60,7 +41,7 @@ MODULE_PARM_DESC(secam, "force SECAM variant, either DK,L or Lc");
60 * as "planar". These affect overlay mode, and are flagged with a field 41 * as "planar". These affect overlay mode, and are flagged with a field
61 * ".planar" in the format. Do we need to implement this in this driver? 42 * ".planar" in the format. Do we need to implement this in this driver?
62 */ 43 */
63static struct tw68_format formats[] = { 44static const struct tw68_format formats[] = {
64 { 45 {
65 .name = "15 bpp RGB, le", 46 .name = "15 bpp RGB, le",
66 .fourcc = V4L2_PIX_FMT_RGB555, 47 .fourcc = V4L2_PIX_FMT_RGB555,
@@ -145,47 +126,8 @@ static struct tw68_format formats[] = {
145 * match, then for an entry which contains the desired id. The table 126 * match, then for an entry which contains the desired id. The table
146 * entries should therefore be ordered in ascending order of specificity. 127 * entries should therefore be ordered in ascending order of specificity.
147 */ 128 */
148static struct tw68_tvnorm tvnorms[] = { 129static const struct tw68_tvnorm tvnorms[] = {
149 { 130 {
150 .name = "PAL-BG",
151 .id = V4L2_STD_PAL_BG,
152 NORM_625_50,
153
154 .sync_control = 0x18,
155 .luma_control = 0x40,
156 .chroma_ctrl1 = 0x81,
157 .chroma_gain = 0x2a,
158 .chroma_ctrl2 = 0x06,
159 .vgate_misc = 0x1c,
160 .format = VideoFormatPALBDGHI,
161
162 }, {
163 .name = "PAL-I",
164 .id = V4L2_STD_PAL_I,
165 NORM_625_50,
166
167 .sync_control = 0x18,
168 .luma_control = 0x40,
169 .chroma_ctrl1 = 0x81,
170 .chroma_gain = 0x2a,
171 .chroma_ctrl2 = 0x06,
172 .vgate_misc = 0x1c,
173 .format = VideoFormatPALBDGHI,
174
175 }, {
176 .name = "PAL-DK",
177 .id = V4L2_STD_PAL_DK,
178 NORM_625_50,
179
180 .sync_control = 0x18,
181 .luma_control = 0x40,
182 .chroma_ctrl1 = 0x81,
183 .chroma_gain = 0x2a,
184 .chroma_ctrl2 = 0x06,
185 .vgate_misc = 0x1c,
186 .format = VideoFormatPALBDGHI,
187
188 }, {
189 .name = "PAL", /* autodetect */ 131 .name = "PAL", /* autodetect */
190 .id = V4L2_STD_PAL, 132 .id = V4L2_STD_PAL,
191 NORM_625_50, 133 NORM_625_50,
@@ -197,7 +139,6 @@ static struct tw68_tvnorm tvnorms[] = {
197 .chroma_ctrl2 = 0x06, 139 .chroma_ctrl2 = 0x06,
198 .vgate_misc = 0x1c, 140 .vgate_misc = 0x1c,
199 .format = VideoFormatPALBDGHI, 141 .format = VideoFormatPALBDGHI,
200
201 }, { 142 }, {
202 .name = "NTSC", 143 .name = "NTSC",
203 .id = V4L2_STD_NTSC, 144 .id = V4L2_STD_NTSC,
@@ -210,46 +151,6 @@ static struct tw68_tvnorm tvnorms[] = {
210 .chroma_ctrl2 = 0x0e, 151 .chroma_ctrl2 = 0x0e,
211 .vgate_misc = 0x18, 152 .vgate_misc = 0x18,
212 .format = VideoFormatNTSC, 153 .format = VideoFormatNTSC,
213
214 }, {
215 .name = "SECAM-DK",
216 .id = V4L2_STD_SECAM_DK,
217 NORM_625_50,
218
219 .sync_control = 0x18,
220 .luma_control = 0x1b,
221 .chroma_ctrl1 = 0xd1,
222 .chroma_gain = 0x80,
223 .chroma_ctrl2 = 0x00,
224 .vgate_misc = 0x1c,
225 .format = VideoFormatSECAM,
226
227 }, {
228 .name = "SECAM-L",
229 .id = V4L2_STD_SECAM_L,
230 NORM_625_50,
231
232 .sync_control = 0x18,
233 .luma_control = 0x1b,
234 .chroma_ctrl1 = 0xd1,
235 .chroma_gain = 0x80,
236 .chroma_ctrl2 = 0x00,
237 .vgate_misc = 0x1c,
238 .format = VideoFormatSECAM,
239
240 }, {
241 .name = "SECAM-LC",
242 .id = V4L2_STD_SECAM_LC,
243 NORM_625_50,
244
245 .sync_control = 0x18,
246 .luma_control = 0x1b,
247 .chroma_ctrl1 = 0xd1,
248 .chroma_gain = 0x80,
249 .chroma_ctrl2 = 0x00,
250 .vgate_misc = 0x1c,
251 .format = VideoFormatSECAM,
252
253 }, { 154 }, {
254 .name = "SECAM", 155 .name = "SECAM",
255 .id = V4L2_STD_SECAM, 156 .id = V4L2_STD_SECAM,
@@ -262,7 +163,6 @@ static struct tw68_tvnorm tvnorms[] = {
262 .chroma_ctrl2 = 0x00, 163 .chroma_ctrl2 = 0x00,
263 .vgate_misc = 0x1c, 164 .vgate_misc = 0x1c,
264 .format = VideoFormatSECAM, 165 .format = VideoFormatSECAM,
265
266 }, { 166 }, {
267 .name = "PAL-M", 167 .name = "PAL-M",
268 .id = V4L2_STD_PAL_M, 168 .id = V4L2_STD_PAL_M,
@@ -275,7 +175,6 @@ static struct tw68_tvnorm tvnorms[] = {
275 .chroma_ctrl2 = 0x0e, 175 .chroma_ctrl2 = 0x0e,
276 .vgate_misc = 0x18, 176 .vgate_misc = 0x18,
277 .format = VideoFormatPALM, 177 .format = VideoFormatPALM,
278
279 }, { 178 }, {
280 .name = "PAL-Nc", 179 .name = "PAL-Nc",
281 .id = V4L2_STD_PAL_Nc, 180 .id = V4L2_STD_PAL_Nc,
@@ -288,7 +187,6 @@ static struct tw68_tvnorm tvnorms[] = {
288 .chroma_ctrl2 = 0x06, 187 .chroma_ctrl2 = 0x06,
289 .vgate_misc = 0x1c, 188 .vgate_misc = 0x1c,
290 .format = VideoFormatPALNC, 189 .format = VideoFormatPALNC,
291
292 }, { 190 }, {
293 .name = "PAL-60", 191 .name = "PAL-60",
294 .id = V4L2_STD_PAL_60, 192 .id = V4L2_STD_PAL_60,
@@ -309,127 +207,11 @@ static struct tw68_tvnorm tvnorms[] = {
309 .chroma_ctrl2 = 0x06, 207 .chroma_ctrl2 = 0x06,
310 .vgate_misc = 0x1c, 208 .vgate_misc = 0x1c,
311 .format = VideoFormatPAL60, 209 .format = VideoFormatPAL60,
312
313 }, {
314/*
315 * FIXME: The following are meant to be "catch-all", and need
316 * to be further thought out!
317 */
318 .name = "STD-525-60",
319 .id = V4L2_STD_525_60,
320 NORM_525_60,
321
322 .sync_control = 0x59,
323 .luma_control = 0x40,
324 .chroma_ctrl1 = 0x89,
325 .chroma_gain = 0x2a,
326 .chroma_ctrl2 = 0x0e,
327 .vgate_misc = 0x18,
328 .format = VideoFormatNTSC,
329
330 }, {
331 .name = "STD-625-50",
332 .id = V4L2_STD_625_50,
333 NORM_625_50,
334
335 .sync_control = 0x18,
336 .luma_control = 0x40,
337 .chroma_ctrl1 = 0x81,
338 .chroma_gain = 0x2a,
339 .chroma_ctrl2 = 0x06,
340 .vgate_misc = 0x1c,
341 .format = VideoFormatPALBDGHI,
342 } 210 }
343}; 211};
344#define TVNORMS ARRAY_SIZE(tvnorms) 212#define TVNORMS ARRAY_SIZE(tvnorms)
345 213
346static const struct v4l2_queryctrl no_ctrl = { 214static const struct tw68_format *format_by_fourcc(unsigned int fourcc)
347 .name = "42",
348 .flags = V4L2_CTRL_FLAG_DISABLED,
349};
350static const struct v4l2_queryctrl video_ctrls[] = {
351 /* --- video --- */
352 {
353 .id = V4L2_CID_BRIGHTNESS,
354 .name = "Brightness",
355 .minimum = -128,
356 .maximum = 127,
357 .step = 1,
358 .default_value = 20,
359 .type = V4L2_CTRL_TYPE_INTEGER,
360 }, {
361 .id = V4L2_CID_CONTRAST,
362 .name = "Contrast",
363 .minimum = 0,
364 .maximum = 255,
365 .step = 1,
366 .default_value = 100,
367 .type = V4L2_CTRL_TYPE_INTEGER,
368 }, {
369 .id = V4L2_CID_SATURATION,
370 .name = "Saturation",
371 .minimum = 0,
372 .maximum = 255,
373 .step = 1,
374 .default_value = 128,
375 .type = V4L2_CTRL_TYPE_INTEGER,
376 }, {
377 .id = V4L2_CID_HUE,
378 .name = "Hue",
379 .minimum = -128,
380 .maximum = 127,
381 .step = 1,
382 .default_value = 0,
383 .type = V4L2_CTRL_TYPE_INTEGER,
384 }, {
385 .id = V4L2_CID_COLOR_KILLER,
386 .name = "Color Killer",
387 .minimum = 0,
388 .maximum = 1,
389 .default_value = 1,
390 .type = V4L2_CTRL_TYPE_BOOLEAN,
391 }, {
392 .id = V4L2_CID_CHROMA_AGC,
393 .name = "Chroma AGC",
394 .minimum = 0,
395 .maximum = 1,
396 .default_value = 1,
397 .type = V4L2_CTRL_TYPE_BOOLEAN,
398 },
399 /* --- audio --- */
400 {
401 .id = V4L2_CID_AUDIO_MUTE,
402 .name = "Mute",
403 .minimum = 0,
404 .maximum = 1,
405 .type = V4L2_CTRL_TYPE_BOOLEAN,
406 }, {
407 .id = V4L2_CID_AUDIO_VOLUME,
408 .name = "Volume",
409 .minimum = -15,
410 .maximum = 15,
411 .step = 1,
412 .default_value = 0,
413 .type = V4L2_CTRL_TYPE_INTEGER,
414 }
415};
416static const unsigned int CTRLS = ARRAY_SIZE(video_ctrls);
417
418/*
419 * Routine to lookup a control by its ID, and return a pointer
420 * to the entry in the video_ctrls array for that control.
421 */
422static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id)
423{
424 unsigned int i;
425
426 for (i = 0; i < CTRLS; i++)
427 if (video_ctrls[i].id == id)
428 return video_ctrls+i;
429 return NULL;
430}
431
432static struct tw68_format *format_by_fourcc(unsigned int fourcc)
433{ 215{
434 unsigned int i; 216 unsigned int i;
435 217
@@ -439,99 +221,22 @@ static struct tw68_format *format_by_fourcc(unsigned int fourcc)
439 return NULL; 221 return NULL;
440} 222}
441 223
442/* ----------------------------------------------------------------------- */
443/* resource management */
444
445static int res_get(struct tw68_fh *fh, unsigned int bit)
446{
447 struct tw68_dev *dev = fh->dev;
448
449 if (fh->resources & bit)
450 /* have it already allocated */
451 return 1;
452
453 /* is it free? */
454 mutex_lock(&dev->lock);
455 if (dev->resources & bit) {
456 /* no, someone else uses it */
457 mutex_unlock(&fh->dev->lock);
458 return 0;
459 }
460 /* it's free, grab it */
461 fh->resources |= bit;
462 dev->resources |= bit;
463 dprintk(DBG_FLOW, "%s: %d\n", __func__, bit);
464 mutex_unlock(&dev->lock);
465 return 1;
466}
467
468static int res_check(struct tw68_fh *fh, unsigned int bit)
469{
470 return fh->resources & bit;
471}
472
473static int res_locked(struct tw68_dev *dev, unsigned int bit)
474{
475 return dev->resources & bit;
476}
477
478static void res_free(struct tw68_fh *fh,
479 unsigned int bits)
480{
481 struct tw68_dev *dev = fh->dev;
482
483 BUG_ON((fh->resources & bits) != bits);
484
485 mutex_lock(&fh->dev->lock);
486 fh->resources &= ~bits;
487 fh->dev->resources &= ~bits;
488 dprintk(DBG_FLOW, "%s: %d\n", __func__, bits);
489 mutex_unlock(&fh->dev->lock);
490}
491 224
492/* ------------------------------------------------------------------ */ 225/* ------------------------------------------------------------------ */
493/* 226/*
494 * Note that the cropping rectangles are described in terms of a single 227 * Note that the cropping rectangles are described in terms of a single
495 * frame, i.e. line positions are only 1/2 the interlaced equivalent 228 * frame, i.e. line positions are only 1/2 the interlaced equivalent
496 */ 229 */
497static void set_tvnorm(struct tw68_dev *dev, struct tw68_tvnorm *norm) 230static void set_tvnorm(struct tw68_dev *dev, const struct tw68_tvnorm *norm)
498{ 231{
499 dprintk(DBG_FLOW, "%s: %s\n", __func__, norm->name);
500 dev->tvnorm = norm;
501
502 /* setup cropping */
503 dev->crop_bounds.left = norm->h_start;
504 dev->crop_defrect.left = norm->h_start;
505 dev->crop_bounds.width = norm->h_stop - norm->h_start + 1;
506 dev->crop_defrect.width = norm->h_stop - norm->h_start + 1;
507
508 dev->crop_bounds.top = norm->video_v_start;
509 dev->crop_defrect.top = norm->video_v_start;
510 dev->crop_bounds.height = (((norm->id & V4L2_STD_525_60) ?
511 524 : 624)) / 2 - dev->crop_bounds.top;
512 dev->crop_defrect.height = (norm->video_v_stop -
513 norm->video_v_start + 1);
514
515 dev->crop_current = dev->crop_defrect;
516
517 if (norm != dev->tvnorm) { 232 if (norm != dev->tvnorm) {
233 dev->width = 720;
234 dev->height = (norm->id & V4L2_STD_525_60) ? 480 : 576;
518 dev->tvnorm = norm; 235 dev->tvnorm = norm;
519 tw68_set_tvnorm_hw(dev); 236 tw68_set_tvnorm_hw(dev);
520 } 237 }
521} 238}
522 239
523static void video_mux(struct tw68_dev *dev, int input)
524{
525 dprintk(DBG_FLOW, "%s: input = %d [%s]\n", __func__, input,
526 card_in(dev, input).name);
527 /*
528 * dev->input shows current application request,
529 * dev->hw_input shows current hardware setting
530 */
531 dev->input = &card_in(dev, input);
532 tw68_tvaudio_setinput(dev, &card_in(dev, input));
533}
534
535/* 240/*
536 * tw68_set_scale 241 * tw68_set_scale
537 * 242 *
@@ -544,7 +249,7 @@ static void video_mux(struct tw68_dev *dev, int input)
544 * before scaling. HDELAY represents the number of pixels skipped 249 * before scaling. HDELAY represents the number of pixels skipped
545 * between the start of the horizontal sync and the start of the image. 250 * between the start of the horizontal sync and the start of the image.
546 * HSCALE is calculated using the formula 251 * HSCALE is calculated using the formula
547 * HSCALE = (HACTIVE / (#pixels desired)) * 256 252 * HSCALE = (HACTIVE / (#pixels desired)) * 256
548 * 253 *
549 * The vertical registers are similar, except based upon the total number 254 * The vertical registers are similar, except based upon the total number
550 * of lines in the image, and the first line of the image (i.e. ignoring 255 * of lines in the image, and the first line of the image (i.e. ignoring
@@ -555,16 +260,16 @@ static void video_mux(struct tw68_dev *dev, int input)
555 * these values, especially HSCALE. 260 * these values, especially HSCALE.
556 * 261 *
557 * Parameters: 262 * Parameters:
558 * @dev pointer to the device structure, needed for 263 * @dev pointer to the device structure, needed for
559 * getting current norm (as well as debug print) 264 * getting current norm (as well as debug print)
560 * @width actual image width (from user buffer) 265 * @width actual image width (from user buffer)
561 * @height actual image height 266 * @height actual image height
562 * @field indicates Top, Bottom or Interlaced 267 * @field indicates Top, Bottom or Interlaced
563 */ 268 */
564static int tw68_set_scale(struct tw68_dev *dev, unsigned int width, 269static int tw68_set_scale(struct tw68_dev *dev, unsigned int width,
565 unsigned int height, enum v4l2_field field) 270 unsigned int height, enum v4l2_field field)
566{ 271{
567 272 const struct tw68_tvnorm *norm = dev->tvnorm;
568 /* set individually for debugging clarity */ 273 /* set individually for debugging clarity */
569 int hactive, hdelay, hscale; 274 int hactive, hdelay, hscale;
570 int vactive, vdelay, vscale; 275 int vactive, vdelay, vscale;
@@ -573,41 +278,38 @@ static int tw68_set_scale(struct tw68_dev *dev, unsigned int width,
573 if (V4L2_FIELD_HAS_BOTH(field)) /* if field is interlaced */ 278 if (V4L2_FIELD_HAS_BOTH(field)) /* if field is interlaced */
574 height /= 2; /* we must set for 1-frame */ 279 height /= 2; /* we must set for 1-frame */
575 280
576 dprintk(DBG_FLOW, "%s: width=%d, height=%d, both=%d\n Crop rect: " 281 pr_debug("%s: width=%d, height=%d, both=%d\n"
577 "top=%d, left=%d, width=%d height=%d\n" 282 " tvnorm h_delay=%d, h_start=%d, h_stop=%d, "
578 " tvnorm h_delay=%d, h_start=%d, h_stop=%d, " 283 "v_delay=%d, v_start=%d, v_stop=%d\n" , __func__,
579 "v_delay=%d, v_start=%d, v_stop=%d\n" , __func__,
580 width, height, V4L2_FIELD_HAS_BOTH(field), 284 width, height, V4L2_FIELD_HAS_BOTH(field),
581 dev->crop_bounds.top, dev->crop_bounds.left, 285 norm->h_delay, norm->h_start, norm->h_stop,
582 dev->crop_bounds.width, dev->crop_bounds.height, 286 norm->v_delay, norm->video_v_start,
583 dev->tvnorm->h_delay, dev->tvnorm->h_start, dev->tvnorm->h_stop, 287 norm->video_v_stop);
584 dev->tvnorm->v_delay, dev->tvnorm->video_v_start,
585 dev->tvnorm->video_v_stop);
586 288
587 switch (dev->vdecoder) { 289 switch (dev->vdecoder) {
588 case TW6800: 290 case TW6800:
589 hdelay = dev->tvnorm->h_delay0; 291 hdelay = norm->h_delay0;
590 break; 292 break;
591 default: 293 default:
592 hdelay = dev->tvnorm->h_delay; 294 hdelay = norm->h_delay;
593 break; 295 break;
594 } 296 }
595 hdelay += dev->crop_bounds.left; 297
596 hactive = dev->crop_bounds.width; 298 hdelay += norm->h_start;
299 hactive = norm->h_stop - norm->h_start + 1;
597 300
598 hscale = (hactive * 256) / (width); 301 hscale = (hactive * 256) / (width);
599 302
600 vdelay = dev->tvnorm->v_delay + dev->crop_bounds.top - 303 vdelay = norm->v_delay;
601 dev->crop_defrect.top; 304 vactive = ((norm->id & V4L2_STD_525_60) ? 524 : 624) / 2 - norm->video_v_start;
602 vactive = dev->crop_bounds.height;
603 vscale = (vactive * 256) / height; 305 vscale = (vactive * 256) / height;
604 306
605 dprintk(DBG_FLOW, "%s: %dx%d [%s%s,%s]\n", __func__, 307 pr_debug("%s: %dx%d [%s%s,%s]\n", __func__,
606 width, height, 308 width, height,
607 V4L2_FIELD_HAS_TOP(field) ? "T" : "", 309 V4L2_FIELD_HAS_TOP(field) ? "T" : "",
608 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "", 310 V4L2_FIELD_HAS_BOTTOM(field) ? "B" : "",
609 v4l2_norm_to_name(dev->tvnorm->id)); 311 v4l2_norm_to_name(dev->tvnorm->id));
610 dprintk(DBG_FLOW, "%s: hactive=%d, hdelay=%d, hscale=%d; " 312 pr_debug("%s: hactive=%d, hdelay=%d, hscale=%d; "
611 "vactive=%d, vdelay=%d, vscale=%d\n", __func__, 313 "vactive=%d, vdelay=%d, vscale=%d\n", __func__,
612 hactive, hdelay, hscale, vactive, vdelay, vscale); 314 hactive, hdelay, hscale, vactive, vdelay, vscale);
613 315
@@ -615,7 +317,7 @@ static int tw68_set_scale(struct tw68_dev *dev, unsigned int width,
615 ((vactive & 0x300) >> 4) | 317 ((vactive & 0x300) >> 4) |
616 ((hdelay & 0x300) >> 6) | 318 ((hdelay & 0x300) >> 6) |
617 ((hactive & 0x300) >> 8); 319 ((hactive & 0x300) >> 8);
618 dprintk(DBG_FLOW, "%s: setting CROP_HI=%02x, VDELAY_LO=%02x, " 320 pr_debug("%s: setting CROP_HI=%02x, VDELAY_LO=%02x, "
619 "VACTIVE_LO=%02x, HDELAY_LO=%02x, HACTIVE_LO=%02x\n", 321 "VACTIVE_LO=%02x, HDELAY_LO=%02x, HACTIVE_LO=%02x\n",
620 __func__, comb, vdelay, vactive, hdelay, hactive); 322 __func__, comb, vdelay, vactive, hdelay, hactive);
621 tw_writeb(TW68_CROP_HI, comb); 323 tw_writeb(TW68_CROP_HI, comb);
@@ -625,7 +327,7 @@ static int tw68_set_scale(struct tw68_dev *dev, unsigned int width,
625 tw_writeb(TW68_HACTIVE_LO, hactive & 0xff); 327 tw_writeb(TW68_HACTIVE_LO, hactive & 0xff);
626 328
627 comb = ((vscale & 0xf00) >> 4) | ((hscale & 0xf00) >> 8); 329 comb = ((vscale & 0xf00) >> 4) | ((hscale & 0xf00) >> 8);
628 dprintk(DBG_FLOW, "%s: setting SCALE_HI=%02x, VSCALE_LO=%02x, " 330 pr_debug("%s: setting SCALE_HI=%02x, VSCALE_LO=%02x, "
629 "HSCALE_LO=%02x\n", __func__, comb, vscale, hscale); 331 "HSCALE_LO=%02x\n", __func__, comb, vscale, hscale);
630 tw_writeb(TW68_SCALE_HI, comb); 332 tw_writeb(TW68_SCALE_HI, comb);
631 tw_writeb(TW68_VSCALE_LO, vscale); 333 tw_writeb(TW68_VSCALE_LO, vscale);
@@ -636,28 +338,21 @@ static int tw68_set_scale(struct tw68_dev *dev, unsigned int width,
636 338
637/* ------------------------------------------------------------------ */ 339/* ------------------------------------------------------------------ */
638 340
639static int tw68_video_start_dma(struct tw68_dev *dev, struct tw68_dmaqueue *q, 341int tw68_video_start_dma(struct tw68_dev *dev, struct tw68_buf *buf)
640 struct tw68_buf *buf) { 342{
641
642 dprintk(DBG_FLOW, "%s: Starting risc program\n", __func__);
643 /* Assure correct input */
644 if (dev->hw_input != dev->input) {
645 dev->hw_input = dev->input;
646 tw_andorb(TW68_INFORM, 0x03 << 2, dev->input->vmux << 2);
647 }
648 /* Set cropping and scaling */ 343 /* Set cropping and scaling */
649 tw68_set_scale(dev, buf->vb.width, buf->vb.height, buf->vb.field); 344 tw68_set_scale(dev, dev->width, dev->height, dev->field);
650 /* 345 /*
651 * Set start address for RISC program. Note that if the DMAP 346 * Set start address for RISC program. Note that if the DMAP
652 * processor is currently running, it must be stopped before 347 * processor is currently running, it must be stopped before
653 * a new address can be set. 348 * a new address can be set.
654 */ 349 */
655 tw_clearl(TW68_DMAC, TW68_DMAP_EN); 350 tw_clearl(TW68_DMAC, TW68_DMAP_EN);
656 tw_writel(TW68_DMAP_SA, cpu_to_le32(buf->risc.dma)); 351 tw_writel(TW68_DMAP_SA, cpu_to_le32(buf->dma));
657 /* Clear any pending interrupts */ 352 /* Clear any pending interrupts */
658 tw_writel(TW68_INTSTAT, dev->board_virqmask); 353 tw_writel(TW68_INTSTAT, dev->board_virqmask);
659 /* Enable the risc engine and the fifo */ 354 /* Enable the risc engine and the fifo */
660 tw_andorl(TW68_DMAC, 0xff, buf->fmt->twformat | 355 tw_andorl(TW68_DMAC, 0xff, dev->fmt->twformat |
661 ColorFormatGamma | TW68_DMAP_EN | TW68_FIFO_EN); 356 ColorFormatGamma | TW68_DMAP_EN | TW68_FIFO_EN);
662 dev->pci_irqmask |= dev->board_virqmask; 357 dev->pci_irqmask |= dev->board_virqmask;
663 tw_setl(TW68_INTMASK, dev->pci_irqmask); 358 tw_setl(TW68_INTMASK, dev->pci_irqmask);
@@ -665,638 +360,244 @@ static int tw68_video_start_dma(struct tw68_dev *dev, struct tw68_dmaqueue *q,
665} 360}
666 361
667/* ------------------------------------------------------------------ */ 362/* ------------------------------------------------------------------ */
668/* videobuf queue operations */
669 363
670/* 364/* nr of (tw68-)pages for the given buffer size */
671 * check_buf_fmt 365static int tw68_buffer_pages(int size)
672 *
673 * callback from tw68-core buffer_queue to determine whether the
674 * current buffer and the previous one are "compatible" (i.e. the
675 * risc programs can be chained without requiring a format change)
676 */
677static int tw68_check_video_fmt(struct tw68_buf *prev, struct tw68_buf *buf)
678{ 366{
679 return (prev->vb.width == buf->vb.width && 367 size = PAGE_ALIGN(size);
680 prev->vb.height == buf->vb.height && 368 size += PAGE_SIZE; /* for non-page-aligned buffers */
681 prev->fmt == buf->fmt); 369 size /= 4096;
370 return size;
682} 371}
683 372
684/* 373/* calc max # of buffers from size (must not exceed the 4MB virtual
685 * buffer_setup 374 * address space per DMA channel) */
686 * 375static int tw68_buffer_count(unsigned int size, unsigned int count)
687 * Calculate required size of buffer and maximum number allowed
688 */
689static int
690buffer_setup(struct videobuf_queue *q, unsigned int *count,
691 unsigned int *size)
692{ 376{
693 struct tw68_fh *fh = q->priv_data; 377 unsigned int maxcount;
694 378
695 *size = fh->fmt->depth * fh->width * fh->height >> 3; 379 maxcount = 1024 / tw68_buffer_pages(size);
696 if (0 == *count) 380 if (count > maxcount)
697 *count = gbuffers; 381 count = maxcount;
698 *count = tw68_buffer_count(*size, *count); 382 return count;
699 return 0;
700} 383}
701 384
702static int buffer_activate(struct tw68_dev *dev, struct tw68_buf *buf, 385/* ------------------------------------------------------------- */
703 struct tw68_buf *next) 386/* vb2 queue operations */
704{
705 dprintk(DBG_BUFF, "%s: dev=%p, buf=%p, next=%p\n",
706 __func__, dev, buf, next);
707 if (dev->hw_input != dev->input) {
708 dev->hw_input = dev->input;
709 tw_andorb(TW68_INFORM, 0x03 << 2,
710 dev->hw_input->vmux << 2);
711 }
712 buf->vb.state = VIDEOBUF_ACTIVE;
713 /* TODO - need to assure scaling/cropping are set correctly */
714 mod_timer(&dev->video_q.timeout, jiffies+BUFFER_TIMEOUT);
715 return 0;
716}
717 387
718/* 388static int tw68_queue_setup(struct vb2_queue *q, const struct v4l2_format *fmt,
719* buffer_prepare 389 unsigned int *num_buffers, unsigned int *num_planes,
720* 390 unsigned int sizes[], void *alloc_ctxs[])
721* Set the ancilliary information into the buffer structure. This
722* includes generating the necessary risc program if it hasn't already
723* been done for the current buffer format.
724* The structure fh contains the details of the format requested by the
725* user - type, width, height and #fields. This is compared with the
726* last format set for the current buffer. If they differ, the risc
727* code (which controls the filling of the buffer) is (re-)generated.
728*/
729static int
730buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
731 enum v4l2_field field)
732{ 391{
733 struct tw68_fh *fh = q->priv_data; 392 struct tw68_dev *dev = vb2_get_drv_priv(q);
734 struct tw68_dev *dev = fh->dev; 393 unsigned tot_bufs = q->num_buffers + *num_buffers;
735 struct tw68_buf *buf = container_of(vb, struct tw68_buf, vb);
736 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
737 int rc, init_buffer = 0;
738 unsigned int maxw, maxh;
739
740 BUG_ON(NULL == fh->fmt);
741 maxw = dev->tvnorm->h_stop - dev->tvnorm->h_start + 1;
742 maxh = 2*(dev->tvnorm->video_v_stop - dev->tvnorm->video_v_start + 1);
743 if (fh->width < 48 || fh->width > maxw || fh->height > maxh
744 || fh->height < 16) {
745 dprintk(DBG_UNEXPECTED, "%s: invalid dimensions - "
746 "fh->width=%d, fh->height=%d, maxw=%d, maxh=%d\n",
747 __func__, fh->width, fh->height, maxw, maxh);
748 return -EINVAL;
749 }
750 buf->vb.size = (fh->width * fh->height * (fh->fmt->depth)) >> 3;
751 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
752 return -EINVAL;
753
754 if (buf->fmt != fh->fmt ||
755 buf->vb.width != fh->width ||
756 buf->vb.height != fh->height ||
757 buf->vb.field != field) {
758 dprintk(DBG_BUFF, "%s: buf - fmt=%p, width=%3d, height=%3d, "
759 "field=%d\n%s: fh - fmt=%p, width=%3d, height=%3d, "
760 "field=%d\n", __func__, buf->fmt, buf->vb.width,
761 buf->vb.height, buf->vb.field, __func__, fh->fmt,
762 fh->width, fh->height, field);
763 buf->fmt = fh->fmt;
764 buf->vb.width = fh->width;
765 buf->vb.height = fh->height;
766 buf->vb.field = field;
767 init_buffer = 1; /* force risc code re-generation */
768 }
769 buf->input = dev->input;
770 394
771 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { 395 sizes[0] = (dev->fmt->depth * dev->width * dev->height) >> 3;
772 rc = videobuf_iolock(q, &buf->vb, NULL); 396 /*
773 if (0 != rc) 397 * We allow create_bufs, but only if the sizeimage is the same as the
774 goto fail; 398 * current sizeimage. The tw68_buffer_count calculation becomes quite
775 init_buffer = 1; /* force risc code re-generation */ 399 * difficult otherwise.
776 } 400 */
777 dprintk(DBG_BUFF, "%s: q=%p, vb=%p, init_buffer=%d\n", 401 if (fmt && fmt->fmt.pix.sizeimage < sizes[0])
778 __func__, q, vb, init_buffer); 402 return -EINVAL;
779 403 *num_planes = 1;
780 if (init_buffer) { 404 if (tot_bufs < 2)
781 buf->bpl = buf->vb.width * (buf->fmt->depth) >> 3; 405 tot_bufs = 2;
782 dprintk(DBG_TESTING, "%s: Generating new risc code " 406 tot_bufs = tw68_buffer_count(sizes[0], tot_bufs);
783 "[%dx%dx%d](%d)\n", __func__, buf->vb.width, 407 *num_buffers = tot_bufs - q->num_buffers;
784 buf->vb.height, buf->fmt->depth, buf->bpl);
785 switch (buf->vb.field) {
786 case V4L2_FIELD_TOP:
787 tw68_risc_buffer(dev->pci, &buf->risc,
788 dma->sglist,
789 0, UNSET,
790 buf->bpl, 0,
791 buf->vb.height);
792 break;
793 case V4L2_FIELD_BOTTOM:
794 tw68_risc_buffer(dev->pci, &buf->risc,
795 dma->sglist,
796 UNSET, 0,
797 buf->bpl, 0,
798 buf->vb.height);
799 break;
800 case V4L2_FIELD_INTERLACED:
801 tw68_risc_buffer(dev->pci, &buf->risc,
802 dma->sglist,
803 0, buf->bpl,
804 buf->bpl, buf->bpl,
805 buf->vb.height >> 1);
806 break;
807 case V4L2_FIELD_SEQ_TB:
808 tw68_risc_buffer(dev->pci, &buf->risc,
809 dma->sglist,
810 0, buf->bpl * (buf->vb.height >> 1),
811 buf->bpl, 0,
812 buf->vb.height >> 1);
813 break;
814 case V4L2_FIELD_SEQ_BT:
815 tw68_risc_buffer(dev->pci, &buf->risc,
816 dma->sglist,
817 buf->bpl * (buf->vb.height >> 1), 0,
818 buf->bpl, 0,
819 buf->vb.height >> 1);
820 break;
821 default:
822 BUG();
823 }
824 }
825 dprintk(DBG_BUFF, "%s: [%p/%d] - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
826 __func__, buf, buf->vb.i, fh->width, fh->height,
827 fh->fmt->depth, fh->fmt->name, (unsigned long)buf->risc.dma);
828 408
829 buf->vb.state = VIDEOBUF_PREPARED;
830 buf->activate = buffer_activate;
831 return 0; 409 return 0;
832
833 fail:
834 tw68_dma_free(q, buf);
835 return rc;
836} 410}
837 411
838/* 412/*
839 * buffer_queue 413 * The risc program for each buffers works as follows: it starts with a simple
414 * 'JUMP to addr + 8', which is effectively a NOP. Then the program to DMA the
415 * buffer follows and at the end we have a JUMP back to the start + 8 (skipping
416 * the initial JUMP).
417 *
418 * This is the program of the first buffer to be queued if the active list is
419 * empty and it just keeps DMAing this buffer without generating any interrupts.
840 * 420 *
841 * Callback whenever a buffer has been requested (by read() or QBUF) 421 * If a new buffer is added then the initial JUMP in the program generates an
422 * interrupt as well which signals that the previous buffer has been DMAed
423 * successfully and that it can be returned to userspace.
424 *
425 * It also sets the final jump of the previous buffer to the start of the new
426 * buffer, thus chaining the new buffer into the DMA chain. This is a single
427 * atomic u32 write, so there is no race condition.
428 *
429 * The end-result of all this that you only get an interrupt when a buffer
430 * is ready, so the control flow is very easy.
842 */ 431 */
843static void 432static void tw68_buf_queue(struct vb2_buffer *vb)
844buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
845{ 433{
846 struct tw68_fh *fh = q->priv_data; 434 struct vb2_queue *vq = vb->vb2_queue;
847 struct tw68_buf *buf = container_of(vb, struct tw68_buf, vb); 435 struct tw68_dev *dev = vb2_get_drv_priv(vq);
436 struct tw68_buf *buf = container_of(vb, struct tw68_buf, vb);
437 struct tw68_buf *prev;
438 unsigned long flags;
439
440 spin_lock_irqsave(&dev->slock, flags);
848 441
849 tw68_buffer_queue(fh->dev, &fh->dev->video_q, buf); 442 /* append a 'JUMP to start of buffer' to the buffer risc program */
443 buf->jmp[0] = cpu_to_le32(RISC_JUMP);
444 buf->jmp[1] = cpu_to_le32(buf->dma + 8);
445
446 if (!list_empty(&dev->active)) {
447 prev = list_entry(dev->active.prev, struct tw68_buf, list);
448 buf->cpu[0] |= cpu_to_le32(RISC_INT_BIT);
449 prev->jmp[1] = cpu_to_le32(buf->dma);
450 }
451 list_add_tail(&buf->list, &dev->active);
452 spin_unlock_irqrestore(&dev->slock, flags);
850} 453}
851 454
852/* 455/*
853 * buffer_release 456 * buffer_prepare
854 * 457 *
855 * Free a buffer previously allocated. 458 * Set the ancilliary information into the buffer structure. This
459 * includes generating the necessary risc program if it hasn't already
460 * been done for the current buffer format.
461 * The structure fh contains the details of the format requested by the
462 * user - type, width, height and #fields. This is compared with the
463 * last format set for the current buffer. If they differ, the risc
464 * code (which controls the filling of the buffer) is (re-)generated.
856 */ 465 */
857static void buffer_release(struct videobuf_queue *q, 466static int tw68_buf_prepare(struct vb2_buffer *vb)
858 struct videobuf_buffer *vb)
859{ 467{
468 struct vb2_queue *vq = vb->vb2_queue;
469 struct tw68_dev *dev = vb2_get_drv_priv(vq);
860 struct tw68_buf *buf = container_of(vb, struct tw68_buf, vb); 470 struct tw68_buf *buf = container_of(vb, struct tw68_buf, vb);
471 struct sg_table *dma = vb2_dma_sg_plane_desc(vb, 0);
472 unsigned size, bpl;
473 int rc;
861 474
862 tw68_dma_free(q, buf); 475 size = (dev->width * dev->height * dev->fmt->depth) >> 3;
863} 476 if (vb2_plane_size(vb, 0) < size)
864 477 return -EINVAL;
865static struct videobuf_queue_ops video_qops = { 478 vb2_set_plane_payload(vb, 0, size);
866 .buf_setup = buffer_setup,
867 .buf_prepare = buffer_prepare,
868 .buf_queue = buffer_queue,
869 .buf_release = buffer_release,
870};
871
872/* ------------------------------------------------------------------ */
873 479
874static int tw68_g_ctrl_internal(struct tw68_dev *dev, struct tw68_fh *fh, 480 rc = dma_map_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);
875 struct v4l2_control *c) 481 if (!rc)
876{ 482 return -EIO;
877 const struct v4l2_queryctrl *ctrl;
878 483
879 dprintk(DBG_FLOW, "%s\n", __func__); 484 bpl = (dev->width * dev->fmt->depth) >> 3;
880 ctrl = ctrl_by_id(c->id); 485 switch (dev->field) {
881 if (NULL == ctrl) 486 case V4L2_FIELD_TOP:
882 return -EINVAL; 487 tw68_risc_buffer(dev->pci, buf, dma->sgl,
883 switch (c->id) { 488 0, UNSET, bpl, 0, dev->height);
884 case V4L2_CID_BRIGHTNESS:
885 c->value = (char)tw_readb(TW68_BRIGHT);
886 break;
887 case V4L2_CID_HUE:
888 c->value = (char)tw_readb(TW68_HUE);
889 break;
890 case V4L2_CID_CONTRAST:
891 c->value = tw_readb(TW68_CONTRAST);
892 break;
893 case V4L2_CID_SATURATION:
894 c->value = tw_readb(TW68_SAT_U);
895 break;
896 case V4L2_CID_COLOR_KILLER:
897 c->value = 0 != (tw_readb(TW68_MISC2) & 0xe0);
898 break; 489 break;
899 case V4L2_CID_CHROMA_AGC: 490 case V4L2_FIELD_BOTTOM:
900 c->value = 0 != (tw_readb(TW68_LOOP) & 0x30); 491 tw68_risc_buffer(dev->pci, buf, dma->sgl,
492 UNSET, 0, bpl, 0, dev->height);
901 break; 493 break;
902 case V4L2_CID_AUDIO_MUTE: 494 case V4L2_FIELD_SEQ_TB:
903 /*hack to suppresss tvtime complaint */ 495 tw68_risc_buffer(dev->pci, buf, dma->sgl,
904 c->value = 0; 496 0, bpl * (dev->height >> 1),
497 bpl, 0, dev->height >> 1);
905 break; 498 break;
906#if 0 499 case V4L2_FIELD_SEQ_BT:
907 case V4L2_CID_AUDIO_VOLUME: 500 tw68_risc_buffer(dev->pci, buf, dma->sgl,
908 c->value = dev->ctl_volume; 501 bpl * (dev->height >> 1), 0,
502 bpl, 0, dev->height >> 1);
909 break; 503 break;
910#endif 504 case V4L2_FIELD_INTERLACED:
911 default: 505 default:
912 return -EINVAL; 506 tw68_risc_buffer(dev->pci, buf, dma->sgl,
507 0, bpl, bpl, bpl, dev->height >> 1);
508 break;
913 } 509 }
914 return 0; 510 return 0;
915} 511}
916 512
917static int tw68_g_ctrl(struct file *file, void *priv, struct v4l2_control *c) 513static void tw68_buf_finish(struct vb2_buffer *vb)
514{
515 struct vb2_queue *vq = vb->vb2_queue;
516 struct tw68_dev *dev = vb2_get_drv_priv(vq);
517 struct sg_table *dma = vb2_dma_sg_plane_desc(vb, 0);
518 struct tw68_buf *buf = container_of(vb, struct tw68_buf, vb);
519
520 dma_unmap_sg(&dev->pci->dev, dma->sgl, dma->nents, DMA_FROM_DEVICE);
521
522 pci_free_consistent(dev->pci, buf->size, buf->cpu, buf->dma);
523}
524
525static int tw68_start_streaming(struct vb2_queue *q, unsigned int count)
526{
527 struct tw68_dev *dev = vb2_get_drv_priv(q);
528 struct tw68_buf *buf =
529 container_of(dev->active.next, struct tw68_buf, list);
530
531 dev->seqnr = 0;
532 tw68_video_start_dma(dev, buf);
533 return 0;
534}
535
536static void tw68_stop_streaming(struct vb2_queue *q)
918{ 537{
919 struct tw68_fh *fh = priv; 538 struct tw68_dev *dev = vb2_get_drv_priv(q);
920 539
921 return tw68_g_ctrl_internal(fh->dev, fh, c); 540 /* Stop risc & fifo */
541 tw_clearl(TW68_DMAC, TW68_DMAP_EN | TW68_FIFO_EN);
542 while (!list_empty(&dev->active)) {
543 struct tw68_buf *buf =
544 container_of(dev->active.next, struct tw68_buf, list);
545
546 list_del(&buf->list);
547 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
548 }
922} 549}
923 550
924static int tw68_s_ctrl_value(struct tw68_dev *dev, __u32 id, int val) 551static struct vb2_ops tw68_video_qops = {
552 .queue_setup = tw68_queue_setup,
553 .buf_queue = tw68_buf_queue,
554 .buf_prepare = tw68_buf_prepare,
555 .buf_finish = tw68_buf_finish,
556 .start_streaming = tw68_start_streaming,
557 .stop_streaming = tw68_stop_streaming,
558 .wait_prepare = vb2_ops_wait_prepare,
559 .wait_finish = vb2_ops_wait_finish,
560};
561
562/* ------------------------------------------------------------------ */
563
564static int tw68_s_ctrl(struct v4l2_ctrl *ctrl)
925{ 565{
926 int err = 0; 566 struct tw68_dev *dev =
567 container_of(ctrl->handler, struct tw68_dev, hdl);
927 568
928 dprintk(DBG_FLOW, "%s\n", __func__); 569 switch (ctrl->id) {
929 switch (id) {
930 case V4L2_CID_BRIGHTNESS: 570 case V4L2_CID_BRIGHTNESS:
931 tw_writeb(TW68_BRIGHT, val); 571 tw_writeb(TW68_BRIGHT, ctrl->val);
932 break; 572 break;
933 case V4L2_CID_HUE: 573 case V4L2_CID_HUE:
934 tw_writeb(TW68_HUE, val); 574 tw_writeb(TW68_HUE, ctrl->val);
935 break; 575 break;
936 case V4L2_CID_CONTRAST: 576 case V4L2_CID_CONTRAST:
937 tw_writeb(TW68_CONTRAST, val); 577 tw_writeb(TW68_CONTRAST, ctrl->val);
938 break; 578 break;
939 case V4L2_CID_SATURATION: 579 case V4L2_CID_SATURATION:
940 tw_writeb(TW68_SAT_U, val); 580 tw_writeb(TW68_SAT_U, ctrl->val);
941 tw_writeb(TW68_SAT_V, val); 581 tw_writeb(TW68_SAT_V, ctrl->val);
942 break; 582 break;
943 case V4L2_CID_COLOR_KILLER: 583 case V4L2_CID_COLOR_KILLER:
944 if (val) 584 if (ctrl->val)
945 tw_andorb(TW68_MISC2, 0xe0, 0xe0); 585 tw_andorb(TW68_MISC2, 0xe0, 0xe0);
946 else 586 else
947 tw_andorb(TW68_MISC2, 0xe0, 0x00); 587 tw_andorb(TW68_MISC2, 0xe0, 0x00);
948 break; 588 break;
949 case V4L2_CID_CHROMA_AGC: 589 case V4L2_CID_CHROMA_AGC:
950 if (val) 590 if (ctrl->val)
951 tw_andorb(TW68_LOOP, 0x30, 0x20); 591 tw_andorb(TW68_LOOP, 0x30, 0x20);
952 else 592 else
953 tw_andorb(TW68_LOOP, 0x30, 0x00); 593 tw_andorb(TW68_LOOP, 0x30, 0x00);
954 break; 594 break;
955 case V4L2_CID_AUDIO_MUTE:
956 /* hack to suppress tvtime complaint */
957 break;
958#if 0
959 case V4L2_CID_AUDIO_VOLUME:
960 dev->ctl_volume = val;
961 tw68_tvaudio_setvolume(dev, dev->ctl_volume);
962 break;
963 case V4L2_CID_HFLIP:
964 dev->ctl_mirror = val;
965 break;
966 case V4L2_CID_PRIVATE_AUTOMUTE:
967 {
968 struct v4l2_priv_tun_config tda9887_cfg;
969
970 tda9887_cfg.tuner = TUNER_TDA9887;
971 tda9887_cfg.priv = &dev->tda9887_conf;
972
973 dev->ctl_automute = val;
974 if (dev->tda9887_conf) {
975 if (dev->ctl_automute)
976 dev->tda9887_conf |= TDA9887_AUTOMUTE;
977 else
978 dev->tda9887_conf &= ~TDA9887_AUTOMUTE;
979
980 tw_call_all(dev, tuner, s_config, &tda9887_cfg);
981 }
982 break;
983 } 595 }
984#endif
985 default:
986 err = -EINVAL;
987 }
988 return err;
989}
990
991static int tw68_s_ctrl_internal(struct tw68_dev *dev, struct tw68_fh *fh,
992 struct v4l2_control *c)
993{
994 const struct v4l2_queryctrl *ctrl;
995 int err;
996
997 dprintk(DBG_FLOW, "%s\n", __func__);
998 if (fh) {
999#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34)
1000 err = v4l2_prio_check(&dev->prio, &fh->prio);
1001#else
1002 err = v4l2_prio_check(&dev->prio, fh->prio);
1003#endif
1004 if (0 != err)
1005 return err;
1006 }
1007
1008 mutex_lock(&dev->lock);
1009
1010 ctrl = ctrl_by_id(c->id);
1011 if (NULL == ctrl) {
1012 err = -EINVAL;
1013 goto error;
1014 }
1015
1016 dprintk(DBG_BUFF, "%s: name=%s val=%d\n", __func__,
1017 ctrl->name, c->value);
1018 switch (ctrl->type) {
1019 case V4L2_CTRL_TYPE_BOOLEAN:
1020 case V4L2_CTRL_TYPE_MENU:
1021 case V4L2_CTRL_TYPE_INTEGER:
1022 if (c->value < ctrl->minimum)
1023 c->value = ctrl->minimum;
1024 if (c->value > ctrl->maximum)
1025 c->value = ctrl->maximum;
1026 break;
1027 default:
1028 /* nothing */;
1029 };
1030 err = tw68_s_ctrl_value(dev, c->id, c->value);
1031
1032error:
1033 mutex_unlock(&dev->lock);
1034 return err;
1035}
1036
1037static int tw68_s_ctrl(struct file *file, void *f, struct v4l2_control *c)
1038{
1039 struct tw68_fh *fh = f;
1040
1041 return tw68_s_ctrl_internal(fh->dev, fh, c);
1042}
1043
1044/* ------------------------------------------------------------------ */
1045
1046/*
1047 * Returns a pointer to the currently used queue (e.g. video, vbi, etc.)
1048 */
1049static struct videobuf_queue *tw68_queue(struct tw68_fh *fh)
1050{
1051 struct videobuf_queue *q = NULL;
1052
1053 switch (fh->type) {
1054 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1055 q = &fh->cap;
1056 break;
1057 case V4L2_BUF_TYPE_VBI_CAPTURE:
1058 q = &fh->vbi;
1059 break;
1060 default:
1061 BUG();
1062 }
1063 return q;
1064}
1065
1066static int tw68_resource(struct tw68_fh *fh)
1067{
1068 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1069 return RESOURCE_VIDEO;
1070
1071 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1072 return RESOURCE_VBI;
1073
1074 BUG();
1075 return 0;
1076}
1077
1078static int video_open(struct file *file)
1079{
1080 int minor = video_devdata(file)->minor;
1081 struct tw68_dev *dev;
1082 struct tw68_fh *fh;
1083 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1084 int radio = 0;
1085
1086 mutex_lock(&tw68_devlist_lock);
1087 list_for_each_entry(dev, &tw68_devlist, devlist) {
1088 if (dev->video_dev && (dev->video_dev->minor == minor))
1089 goto found;
1090 if (dev->radio_dev && (dev->radio_dev->minor == minor)) {
1091 radio = 1;
1092 goto found;
1093 }
1094 if (dev->vbi_dev && (dev->vbi_dev->minor == minor)) {
1095 type = V4L2_BUF_TYPE_VBI_CAPTURE;
1096 goto found;
1097 }
1098 }
1099 mutex_unlock(&tw68_devlist_lock);
1100 return -ENODEV;
1101
1102found:
1103 mutex_unlock(&tw68_devlist_lock);
1104
1105 dprintk(DBG_FLOW, "%s: minor=%d radio=%d type=%s\n", __func__, minor,
1106 radio, v4l2_type_names[type]);
1107
1108 /* allocate + initialize per filehandle data */
1109 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
1110 if (NULL == fh)
1111 return -ENOMEM;
1112
1113 file->private_data = fh;
1114 fh->dev = dev;
1115 fh->radio = radio;
1116 fh->type = type;
1117 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
1118 fh->width = 720;
1119 fh->height = 576;
1120 v4l2_prio_open(&dev->prio, &fh->prio);
1121
1122 videobuf_queue_sg_init(&fh->cap, &video_qops,
1123 &dev->pci->dev, &dev->slock,
1124 V4L2_BUF_TYPE_VIDEO_CAPTURE,
1125 V4L2_FIELD_INTERLACED,
1126 sizeof(struct tw68_buf),
1127#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,37)
1128 fh
1129#else
1130 fh, &dev->lock
1131#endif
1132 );
1133 videobuf_queue_sg_init(&fh->vbi, &tw68_vbi_qops,
1134 &dev->pci->dev, &dev->slock,
1135 V4L2_BUF_TYPE_VBI_CAPTURE,
1136 V4L2_FIELD_SEQ_TB,
1137 sizeof(struct tw68_buf),
1138#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,37)
1139 fh
1140#else
1141 fh, &dev->lock
1142#endif
1143 );
1144 if (fh->radio) {
1145 /* switch to radio mode */
1146 tw68_tvaudio_setinput(dev, &card(dev).radio);
1147 tw_call_all(dev, tuner, s_radio);
1148 } else {
1149 /* switch to video/vbi mode */
1150 tw68_tvaudio_setinput(dev, dev->input);
1151 }
1152 return 0;
1153}
1154
1155static ssize_t
1156video_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1157{
1158 struct tw68_fh *fh = file->private_data;
1159
1160 switch (fh->type) {
1161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1162 if (res_locked(fh->dev, RESOURCE_VIDEO))
1163 return -EBUSY;
1164 return videobuf_read_one(tw68_queue(fh),
1165 data, count, ppos,
1166 file->f_flags & O_NONBLOCK);
1167 case V4L2_BUF_TYPE_VBI_CAPTURE:
1168 if (!res_get(fh, RESOURCE_VBI))
1169 return -EBUSY;
1170 return videobuf_read_stream(tw68_queue(fh),
1171 data, count, ppos, 1,
1172 file->f_flags & O_NONBLOCK);
1173 break;
1174 default:
1175 BUG();
1176 return 0;
1177 }
1178}
1179
1180static unsigned int
1181video_poll(struct file *file, struct poll_table_struct *wait)
1182{
1183 struct tw68_fh *fh = file->private_data;
1184 struct videobuf_buffer *buf = NULL;
1185
1186 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
1187 return videobuf_poll_stream(file, &fh->vbi, wait);
1188
1189 if (res_check(fh, RESOURCE_VIDEO)) {
1190 if (!list_empty(&fh->cap.stream))
1191 buf = list_entry(fh->cap.stream.next,
1192 struct videobuf_buffer, stream);
1193 } else {
1194 mutex_lock(&fh->cap.vb_lock);
1195 if (UNSET == fh->cap.read_off) {
1196 /* need to capture a new frame */
1197 if (res_locked(fh->dev, RESOURCE_VIDEO))
1198 goto err;
1199 if (0 != fh->cap.ops->buf_prepare(&fh->cap,
1200 fh->cap.read_buf, fh->cap.field))
1201 goto err;
1202 fh->cap.ops->buf_queue(&fh->cap, fh->cap.read_buf);
1203 fh->cap.read_off = 0;
1204 }
1205 mutex_unlock(&fh->cap.vb_lock);
1206 buf = fh->cap.read_buf;
1207 }
1208
1209 if (!buf)
1210 return POLLERR;
1211
1212 poll_wait(file, &buf->done, wait);
1213 if (buf->state == VIDEOBUF_DONE ||
1214 buf->state == VIDEOBUF_ERROR)
1215 return POLLIN | POLLRDNORM;
1216 return 0;
1217
1218err:
1219 mutex_unlock(&fh->cap.vb_lock);
1220 return POLLERR;
1221}
1222
1223static int video_release(struct file *file)
1224{
1225 struct tw68_fh *fh = file->private_data;
1226 struct tw68_dev *dev = fh->dev;
1227
1228 /* stop video capture */
1229 if (res_check(fh, RESOURCE_VIDEO)) {
1230 videobuf_streamoff(&fh->cap);
1231 res_free(fh , RESOURCE_VIDEO);
1232 }
1233 if (fh->cap.read_buf) {
1234 buffer_release(&fh->cap, fh->cap.read_buf);
1235 kfree(fh->cap.read_buf);
1236 }
1237
1238 /* stop vbi capture */
1239 if (res_check(fh, RESOURCE_VBI)) {
1240 videobuf_stop(&fh->vbi);
1241 res_free(fh, RESOURCE_VBI);
1242 }
1243
1244#if 0
1245 tw_call_all(dev, core, s_standby, 0);
1246#endif
1247
1248 /* free stuff */
1249 videobuf_mmap_free(&fh->cap);
1250 videobuf_mmap_free(&fh->vbi);
1251
1252#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34)
1253 v4l2_prio_close(&dev->prio, &fh->prio);
1254#else
1255 v4l2_prio_close(&dev->prio, fh->prio);
1256#endif
1257 file->private_data = NULL;
1258 kfree(fh);
1259 return 0; 596 return 0;
1260} 597}
1261 598
1262static int video_mmap(struct file *file, struct vm_area_struct * vma)
1263{
1264 struct tw68_fh *fh = file->private_data;
1265
1266 return videobuf_mmap_mapper(tw68_queue(fh), vma);
1267}
1268
1269/* ------------------------------------------------------------------ */ 599/* ------------------------------------------------------------------ */
1270 600
1271#if 0
1272static int tw68_try_get_set_fmt_vbi_cap(struct file *file, void *priv,
1273 struct v4l2_format *f)
1274{
1275 struct tw68_fh *fh = priv;
1276 struct tw68_dev *dev = fh->dev;
1277 struct tw68_tvnorm *norm = dev->tvnorm;
1278
1279 f->fmt.vbi.sampling_rate = 6750000 * 4;
1280 f->fmt.vbi.samples_per_line = 2048 /* VBI_LINE_LENGTH */;
1281 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1282 f->fmt.vbi.offset = 64 * 4;
1283 f->fmt.vbi.start[0] = norm->vbi_v_start_0;
1284 f->fmt.vbi.count[0] = norm->vbi_v_stop_0 - norm->vbi_v_start_0 + 1;
1285 f->fmt.vbi.start[1] = norm->vbi_v_start_1;
1286 f->fmt.vbi.count[1] = f->fmt.vbi.count[0];
1287 f->fmt.vbi.flags = 0; /* VBI_UNSYNC VBI_INTERLACED */
1288
1289#if 0
1290 if (V4L2_STD_PAL == norm->id) {
1291 /* FIXME */
1292 f->fmt.vbi.start[0] += 3;
1293 f->fmt.vbi.start[1] += 3*2;
1294 }
1295#endif
1296 return 0;
1297}
1298#endif
1299
1300/* 601/*
1301 * Note that this routine returns what is stored in the fh structure, and 602 * Note that this routine returns what is stored in the fh structure, and
1302 * does not interrogate any of the device registers. 603 * does not interrogate any of the device registers.
@@ -1304,54 +605,50 @@ static int tw68_try_get_set_fmt_vbi_cap(struct file *file, void *priv,
1304static int tw68_g_fmt_vid_cap(struct file *file, void *priv, 605static int tw68_g_fmt_vid_cap(struct file *file, void *priv,
1305 struct v4l2_format *f) 606 struct v4l2_format *f)
1306{ 607{
1307 struct tw68_fh *fh = priv; 608 struct tw68_dev *dev = video_drvdata(file);
1308 struct tw68_dev *dev = fh->dev; 609
1309 610 f->fmt.pix.width = dev->width;
1310 dprintk(DBG_FLOW, "%s\n", __func__); 611 f->fmt.pix.height = dev->height;
1311 f->fmt.pix.width = fh->width; 612 f->fmt.pix.field = dev->field;
1312 f->fmt.pix.height = fh->height; 613 f->fmt.pix.pixelformat = dev->fmt->fourcc;
1313 f->fmt.pix.field = fh->cap.field;
1314 f->fmt.pix.pixelformat = fh->fmt->fourcc;
1315 f->fmt.pix.bytesperline = 614 f->fmt.pix.bytesperline =
1316 (f->fmt.pix.width * (fh->fmt->depth)) >> 3; 615 (f->fmt.pix.width * (dev->fmt->depth)) >> 3;
1317 f->fmt.pix.sizeimage = 616 f->fmt.pix.sizeimage =
1318 f->fmt.pix.height * f->fmt.pix.bytesperline; 617 f->fmt.pix.height * f->fmt.pix.bytesperline;
1319 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; 618 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
619 f->fmt.pix.priv = 0;
1320 return 0; 620 return 0;
1321} 621}
1322 622
1323static int tw68_try_fmt_vid_cap(struct file *file, void *priv, 623static int tw68_try_fmt_vid_cap(struct file *file, void *priv,
1324 struct v4l2_format *f) 624 struct v4l2_format *f)
1325{ 625{
1326 struct tw68_fh *fh = priv; 626 struct tw68_dev *dev = video_drvdata(file);
1327 struct tw68_dev *dev = fh->dev; 627 const struct tw68_format *fmt;
1328 struct tw68_format *fmt;
1329 enum v4l2_field field; 628 enum v4l2_field field;
1330 unsigned int maxw, maxh; 629 unsigned int maxh;
1331 630
1332 dprintk(DBG_FLOW, "%s\n", __func__);
1333 fmt = format_by_fourcc(f->fmt.pix.pixelformat); 631 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1334 if (NULL == fmt) 632 if (NULL == fmt)
1335 return -EINVAL; 633 return -EINVAL;
1336 634
1337 field = f->fmt.pix.field; 635 field = f->fmt.pix.field;
1338 maxw = min(dev->crop_current.width*4, dev->crop_bounds.width); 636 maxh = (dev->tvnorm->id & V4L2_STD_525_60) ? 480 : 576;
1339 maxh = min(dev->crop_current.height*4, dev->crop_bounds.height);
1340 637
1341 if (V4L2_FIELD_ANY == field) {
1342 field = (f->fmt.pix.height > maxh/2)
1343 ? V4L2_FIELD_INTERLACED
1344 : V4L2_FIELD_BOTTOM;
1345 }
1346 switch (field) { 638 switch (field) {
1347 case V4L2_FIELD_TOP: 639 case V4L2_FIELD_TOP:
1348 case V4L2_FIELD_BOTTOM: 640 case V4L2_FIELD_BOTTOM:
1349 break; 641 break;
1350 case V4L2_FIELD_INTERLACED: 642 case V4L2_FIELD_INTERLACED:
643 case V4L2_FIELD_SEQ_BT:
644 case V4L2_FIELD_SEQ_TB:
1351 maxh = maxh * 2; 645 maxh = maxh * 2;
1352 break; 646 break;
1353 default: 647 default:
1354 return -EINVAL; 648 field = (f->fmt.pix.height > maxh / 2)
649 ? V4L2_FIELD_INTERLACED
650 : V4L2_FIELD_BOTTOM;
651 break;
1355 } 652 }
1356 653
1357 f->fmt.pix.field = field; 654 f->fmt.pix.field = field;
@@ -1359,8 +656,8 @@ static int tw68_try_fmt_vid_cap(struct file *file, void *priv,
1359 f->fmt.pix.width = 48; 656 f->fmt.pix.width = 48;
1360 if (f->fmt.pix.height < 32) 657 if (f->fmt.pix.height < 32)
1361 f->fmt.pix.height = 32; 658 f->fmt.pix.height = 32;
1362 if (f->fmt.pix.width > maxw) 659 if (f->fmt.pix.width > 720)
1363 f->fmt.pix.width = maxw; 660 f->fmt.pix.width = 720;
1364 if (f->fmt.pix.height > maxh) 661 if (f->fmt.pix.height > maxh)
1365 f->fmt.pix.height = maxh; 662 f->fmt.pix.height = maxh;
1366 f->fmt.pix.width &= ~0x03; 663 f->fmt.pix.width &= ~0x03;
@@ -1368,7 +665,7 @@ static int tw68_try_fmt_vid_cap(struct file *file, void *priv,
1368 (f->fmt.pix.width * (fmt->depth)) >> 3; 665 (f->fmt.pix.width * (fmt->depth)) >> 3;
1369 f->fmt.pix.sizeimage = 666 f->fmt.pix.sizeimage =
1370 f->fmt.pix.height * f->fmt.pix.bytesperline; 667 f->fmt.pix.height * f->fmt.pix.bytesperline;
1371 668 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1372 return 0; 669 return 0;
1373} 670}
1374 671
@@ -1381,76 +678,35 @@ static int tw68_try_fmt_vid_cap(struct file *file, void *priv,
1381static int tw68_s_fmt_vid_cap(struct file *file, void *priv, 678static int tw68_s_fmt_vid_cap(struct file *file, void *priv,
1382 struct v4l2_format *f) 679 struct v4l2_format *f)
1383{ 680{
1384 struct tw68_fh *fh = priv; 681 struct tw68_dev *dev = video_drvdata(file);
1385 struct tw68_dev *dev = fh->dev;
1386 int err; 682 int err;
1387 683
1388 dprintk(DBG_FLOW, "%s\n", __func__);
1389 err = tw68_try_fmt_vid_cap(file, priv, f); 684 err = tw68_try_fmt_vid_cap(file, priv, f);
1390 if (0 != err) 685 if (0 != err)
1391 return err; 686 return err;
1392 687
1393 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat); 688 dev->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
1394 fh->width = f->fmt.pix.width; 689 dev->width = f->fmt.pix.width;
1395 fh->height = f->fmt.pix.height; 690 dev->height = f->fmt.pix.height;
1396 fh->cap.field = f->fmt.pix.field; 691 dev->field = f->fmt.pix.field;
1397 /*
1398 * The following lines are to make v4l2-test program happy.
1399 * The docs should be checked to assure they make sense.
1400 */
1401 f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
1402 f->fmt.pix.priv = 0;
1403 return 0;
1404}
1405
1406static int tw68_queryctrl(struct file *file, void *priv,
1407 struct v4l2_queryctrl *c)
1408{
1409 const struct v4l2_queryctrl *ctrl;
1410 struct tw68_fh *fh = priv;
1411 struct tw68_dev *dev = fh->dev;
1412
1413 dprintk(DBG_FLOW, "%s\n", __func__);
1414 if ((c->id < V4L2_CID_BASE || c->id >= V4L2_CID_LASTP1)
1415#if 0
1416 && (c->id < V4L2_CID_PRIVATE_BASE ||
1417 c->id >= V4L2_CID_PRIVATE_LASTP1)
1418#endif
1419 )
1420 return -EINVAL;
1421 ctrl = ctrl_by_id(c->id);
1422 if (NULL == ctrl)
1423 return -EINVAL;
1424 *c = *ctrl;
1425 return 0; 692 return 0;
1426} 693}
1427 694
1428static int tw68_enum_input(struct file *file, void *priv, 695static int tw68_enum_input(struct file *file, void *priv,
1429 struct v4l2_input *i) 696 struct v4l2_input *i)
1430{ 697{
1431 struct tw68_fh *fh = priv; 698 struct tw68_dev *dev = video_drvdata(file);
1432 struct tw68_dev *dev = fh->dev;
1433 unsigned int n; 699 unsigned int n;
1434 700
1435 n = i->index; 701 n = i->index;
1436 dprintk(DBG_FLOW, "%s: index is %d\n", __func__, n); 702 if (n >= TW68_INPUT_MAX)
1437 if (n >= TW68_INPUT_MAX) {
1438 dprintk(DBG_FLOW, "%s: INPUT_MAX reached\n", __func__);
1439 return -EINVAL;
1440 }
1441 if (NULL == card_in(dev, n).name) {
1442 dprintk(DBG_FLOW, "%s: End of list\n", __func__);
1443 return -EINVAL; 703 return -EINVAL;
1444 }
1445 memset(i, 0, sizeof(*i));
1446 i->index = n; 704 i->index = n;
1447 i->type = V4L2_INPUT_TYPE_CAMERA; 705 i->type = V4L2_INPUT_TYPE_CAMERA;
1448 strcpy(i->name, card_in(dev, n).name); 706 snprintf(i->name, sizeof(i->name), "Composite %d", n);
1449 if (card_in(dev, n).tv) 707
1450 i->type = V4L2_INPUT_TYPE_TUNER;
1451 i->audioset = 1;
1452 /* If the query is for the current input, get live data */ 708 /* If the query is for the current input, get live data */
1453 if (n == dev->hw_input->vmux) { 709 if (n == dev->input) {
1454 int v1 = tw_readb(TW68_STATUS1); 710 int v1 = tw_readb(TW68_STATUS1);
1455 int v2 = tw_readb(TW68_MVSN); 711 int v2 = tw_readb(TW68_MVSN);
1456 712
@@ -1465,305 +721,86 @@ static int tw68_enum_input(struct file *file, void *priv,
1465 if (0 != (v2 & (1 << 2))) 721 if (0 != (v2 & (1 << 2)))
1466 i->status |= V4L2_IN_ST_MACROVISION; 722 i->status |= V4L2_IN_ST_MACROVISION;
1467 } 723 }
1468 i->std = TW68_NORMS; 724 i->std = video_devdata(file)->tvnorms;
1469 return 0; 725 return 0;
1470} 726}
1471 727
1472static int tw68_g_input(struct file *file, void *priv, unsigned int *i) 728static int tw68_g_input(struct file *file, void *priv, unsigned int *i)
1473{ 729{
1474 struct tw68_fh *fh = priv; 730 struct tw68_dev *dev = video_drvdata(file);
1475 struct tw68_dev *dev = fh->dev;
1476 731
1477 dprintk(DBG_FLOW, "%s\n", __func__); 732 *i = dev->input;
1478 *i = dev->input->vmux;
1479 return 0; 733 return 0;
1480} 734}
1481 735
1482static int tw68_s_input(struct file *file, void *priv, unsigned int i) 736static int tw68_s_input(struct file *file, void *priv, unsigned int i)
1483{ 737{
1484 struct tw68_fh *fh = priv; 738 struct tw68_dev *dev = video_drvdata(file);
1485 struct tw68_dev *dev = fh->dev;
1486 int err;
1487
1488 dprintk(DBG_FLOW, "%s\n", __func__);
1489#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34)
1490 err = v4l2_prio_check(&dev->prio, &fh->prio);
1491#else
1492 err = v4l2_prio_check(&dev->prio, fh->prio);
1493#endif
1494 if (0 != err)
1495 if (0 != err)
1496 return err;
1497 739
1498 if (i < 0 || i >= TW68_INPUT_MAX) 740 if (i >= TW68_INPUT_MAX)
1499 return -EINVAL;
1500 if (NULL == card_in(dev, i).name)
1501 return -EINVAL; 741 return -EINVAL;
1502 mutex_lock(&dev->lock); 742 dev->input = i;
1503 video_mux(dev, i); 743 tw_andorb(TW68_INFORM, 0x03 << 2, dev->input << 2);
1504 mutex_unlock(&dev->lock);
1505 return 0; 744 return 0;
1506} 745}
1507 746
1508static int tw68_querycap(struct file *file, void *priv, 747static int tw68_querycap(struct file *file, void *priv,
1509 struct v4l2_capability *cap) 748 struct v4l2_capability *cap)
1510{ 749{
1511 struct tw68_fh *fh = priv; 750 struct tw68_dev *dev = video_drvdata(file);
1512 struct tw68_dev *dev = fh->dev;
1513 751
1514 unsigned int tuner_type = dev->tuner_type;
1515
1516 dprintk(DBG_FLOW, "%s\n", __func__);
1517 strcpy(cap->driver, "tw68"); 752 strcpy(cap->driver, "tw68");
1518 strlcpy(cap->card, tw68_boards[dev->board].name, 753 strlcpy(cap->card, "Techwell Capture Card",
1519 sizeof(cap->card)); 754 sizeof(cap->card));
1520 sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); 755 sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci));
1521 cap->version = TW68_VERSION_CODE; 756 cap->device_caps =
1522 cap->capabilities =
1523 V4L2_CAP_VIDEO_CAPTURE | 757 V4L2_CAP_VIDEO_CAPTURE |
1524 V4L2_CAP_VBI_CAPTURE |
1525 V4L2_CAP_READWRITE | 758 V4L2_CAP_READWRITE |
1526 V4L2_CAP_STREAMING | 759 V4L2_CAP_STREAMING;
1527 V4L2_CAP_TUNER;
1528 760
1529 if ((tuner_type == TUNER_ABSENT) || (tuner_type == UNSET)) 761 cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS;
1530 cap->capabilities &= ~V4L2_CAP_TUNER;
1531 return 0; 762 return 0;
1532} 763}
1533 764
1534static int tw68_s_std_internal(struct tw68_dev *dev, struct tw68_fh *fh, 765static int tw68_s_std(struct file *file, void *priv, v4l2_std_id id)
1535 v4l2_std_id *id)
1536{ 766{
1537/* unsigned long flags; */ 767 struct tw68_dev *dev = video_drvdata(file);
1538 unsigned int i; 768 unsigned int i;
1539 v4l2_std_id fixup;
1540 int err;
1541 769
1542 dprintk(DBG_FLOW, "%s\n", __func__); 770 if (vb2_is_busy(&dev->vidq))
1543 if (fh) { 771 return -EBUSY;
1544#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34)
1545 err = v4l2_prio_check(&dev->prio, &fh->prio);
1546#else
1547 err = v4l2_prio_check(&dev->prio, fh->prio);
1548#endif
1549 if (0 != err)
1550 if (0 != err)
1551 return err;
1552 }
1553 772
1554 /* Look for match on complete norm id (may have mult bits) */ 773 /* Look for match on complete norm id (may have mult bits) */
1555 for (i = 0; i < TVNORMS; i++) { 774 for (i = 0; i < TVNORMS; i++) {
1556 if (*id == tvnorms[i].id) 775 if (id == tvnorms[i].id)
1557 break; 776 break;
1558 } 777 }
1559 778
1560 /* If no exact match, look for norm which contains this one */ 779 /* If no exact match, look for norm which contains this one */
1561 if (i == TVNORMS) 780 if (i == TVNORMS) {
1562 for (i = 0; i < TVNORMS; i++) { 781 for (i = 0; i < TVNORMS; i++)
1563 if (*id & tvnorms[i].id) 782 if (id & tvnorms[i].id)
1564 break; 783 break;
1565 } 784 }
1566 /* If still not matched, give up */ 785 /* If still not matched, give up */
1567 if (i == TVNORMS) 786 if (i == TVNORMS)
1568 return -EINVAL; 787 return -EINVAL;
1569 788
1570 /* TODO - verify this additional work with SECAM applies to TW */
1571 if ((*id & V4L2_STD_SECAM) && (secam[0] != '-')) {
1572 if (secam[0] == 'L' || secam[0] == 'l') {
1573 if (secam[1] == 'C' || secam[1] == 'c')
1574 fixup = V4L2_STD_SECAM_LC;
1575 else
1576 fixup = V4L2_STD_SECAM_L;
1577 } else {
1578 if (secam[0] == 'D' || secam[0] == 'd')
1579 fixup = V4L2_STD_SECAM_DK;
1580 else
1581 fixup = V4L2_STD_SECAM;
1582 }
1583 for (i = 0; i < TVNORMS; i++)
1584 if (fixup == tvnorms[i].id)
1585 break;
1586 }
1587
1588 *id = tvnorms[i].id;
1589 mutex_lock(&dev->lock);
1590 set_tvnorm(dev, &tvnorms[i]); /* do the actual setting */ 789 set_tvnorm(dev, &tvnorms[i]); /* do the actual setting */
1591 tw68_tvaudio_do_scan(dev);
1592 mutex_unlock(&dev->lock);
1593 return 0; 790 return 0;
1594} 791}
1595 792
1596static int tw68_s_std(struct file *file, void *priv, v4l2_std_id *id)
1597{
1598 struct tw68_fh *fh = priv;
1599 struct tw68_dev *dev = fh->dev;
1600
1601 dprintk(DBG_FLOW, "%s\n", __func__);
1602 return tw68_s_std_internal(fh->dev, fh, id);
1603}
1604
1605static int tw68_g_std(struct file *file, void *priv, v4l2_std_id *id) 793static int tw68_g_std(struct file *file, void *priv, v4l2_std_id *id)
1606{ 794{
1607 struct tw68_fh *fh = priv; 795 struct tw68_dev *dev = video_drvdata(file);
1608 struct tw68_dev *dev = fh->dev;
1609 796
1610 dprintk(DBG_FLOW, "%s\n", __func__);
1611 *id = dev->tvnorm->id; 797 *id = dev->tvnorm->id;
1612 return 0; 798 return 0;
1613} 799}
1614 800
1615static int tw68_g_tuner(struct file *file, void *priv,
1616 struct v4l2_tuner *t)
1617{
1618 struct tw68_fh *fh = priv;
1619 struct tw68_dev *dev = fh->dev;
1620 int n;
1621
1622 if (unlikely(UNSET == dev->tuner_type))
1623 return -EINVAL;
1624 if (0 != t->index)
1625 return -EINVAL;
1626 memset(t, 0, sizeof(*t));
1627 for (n = 0; n < TW68_INPUT_MAX; n++)
1628 if (card_in(dev, n).tv)
1629 break;
1630 if (n == TW68_INPUT_MAX)
1631 return -EINVAL;
1632#if 0
1633 if (NULL != card_in(dev, n).name) {
1634 strcpy(t->name, "Television");
1635 t->type = V4L2_TUNER_ANALOG_TV;
1636 t->capability = V4L2_TUNER_CAP_NORM |
1637 V4L2_TUNER_CAP_STEREO |
1638 V4L2_TUNER_CAP_LANG1 |
1639 V4L2_TUNER_CAP_LANG2;
1640 t->rangehigh = 0xffffffffUL;
1641 t->rxsubchans = tw68_tvaudio_getstereo(dev);
1642 t->audmode = tw68_tvaudio_rx2mode(t->rxsubchans);
1643 }
1644 if (0 != (saa_readb(TW68_STATUS_VIDEO1) & 0x03))
1645 t->signal = 0xffff;
1646#endif
1647 return 0;
1648}
1649
1650static int tw68_s_tuner(struct file *file, void *priv,
1651 struct v4l2_tuner *t)
1652{
1653 struct tw68_fh *fh = priv;
1654 struct tw68_dev *dev = fh->dev;
1655 int err;
1656#if 0
1657 int rx, mode
1658#endif
1659
1660#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34)
1661 err = v4l2_prio_check(&dev->prio, &fh->prio);
1662#else
1663 err = v4l2_prio_check(&dev->prio, fh->prio);
1664#endif
1665 if (0 != err)
1666 if (0 != err)
1667 return err;
1668
1669#if 0
1670 mode = dev->thread.mode;
1671 if (UNSET == mode) {
1672 rx = tw68_tvaudio_getstereo(dev);
1673 mode = tw68_tvaudio_rx2mode(t->rxsubchans);
1674 }
1675 if (mode != t->audmode)
1676 dev->thread.mode = t->audmode;
1677#endif
1678 return 0;
1679}
1680
1681static int tw68_g_frequency(struct file *file, void *priv,
1682 struct v4l2_frequency *f)
1683{
1684 struct tw68_fh *fh = priv;
1685 struct tw68_dev *dev = fh->dev;
1686
1687 if (unlikely(dev->tuner_type))
1688 return -EINVAL;
1689 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1690/* f->frequency = dev->ctl_freq; */
1691
1692 return 0;
1693}
1694
1695static int tw68_s_frequency(struct file *file, void *priv,
1696 struct v4l2_frequency *f)
1697{
1698 struct tw68_fh *fh = priv;
1699 struct tw68_dev *dev = fh->dev;
1700 int err;
1701
1702 if (unlikely(UNSET == dev->tuner_type))
1703 return -EINVAL;
1704#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,34)
1705 err = v4l2_prio_check(&dev->prio, &fh->prio);
1706#else
1707 err = v4l2_prio_check(&dev->prio, fh->prio);
1708#endif
1709 if (0 != err)
1710 if (0 != err)
1711 return err;
1712
1713 if (0 != f->tuner)
1714 return -EINVAL;
1715 if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)
1716 return -EINVAL;
1717 if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
1718 return -EINVAL;
1719 mutex_lock(&dev->lock);
1720/* dev->ctl_freq = f->frequency; */
1721
1722 tw_call_all(dev, tuner, s_frequency, f);
1723
1724 tw68_tvaudio_do_scan(dev);
1725 mutex_unlock(&dev->lock);
1726 return 0;
1727}
1728
1729static int tw68_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
1730{
1731 strcpy(a->name, "audio");
1732 return 0;
1733}
1734
1735static int tw68_s_audio(struct file *file, void *priv, struct v4l2_audio *a)
1736{
1737 return 0;
1738}
1739
1740static int tw68_g_priority(struct file *file, void *f, enum v4l2_priority *p)
1741{
1742 struct tw68_fh *fh = f;
1743 struct tw68_dev *dev = fh->dev;
1744
1745 dprintk(DBG_FLOW, "%s\n", __func__);
1746 *p = v4l2_prio_max(&dev->prio);
1747 return 0;
1748}
1749
1750static int tw68_s_priority(struct file *file, void *f,
1751 enum v4l2_priority prio)
1752{
1753 struct tw68_fh *fh = f;
1754 struct tw68_dev *dev = fh->dev;
1755
1756 dprintk(DBG_FLOW, "%s\n", __func__);
1757 return v4l2_prio_change(&dev->prio, &fh->prio, prio);
1758}
1759
1760static int tw68_enum_fmt_vid_cap(struct file *file, void *priv, 801static int tw68_enum_fmt_vid_cap(struct file *file, void *priv,
1761 struct v4l2_fmtdesc *f) 802 struct v4l2_fmtdesc *f)
1762{ 803{
1763 struct tw68_fh *fh = priv;
1764 struct tw68_dev *dev = fh->dev;
1765
1766 dprintk(DBG_FLOW, "%s\n", __func__);
1767 if (f->index >= FORMATS) 804 if (f->index >= FORMATS)
1768 return -EINVAL; 805 return -EINVAL;
1769 806
@@ -1775,149 +812,6 @@ static int tw68_enum_fmt_vid_cap(struct file *file, void *priv,
1775 return 0; 812 return 0;
1776} 813}
1777 814
1778static int tw68_cropcap(struct file *file, void *priv,
1779 struct v4l2_cropcap *cap)
1780{
1781 struct tw68_fh *fh = priv;
1782 struct tw68_dev *dev = fh->dev;
1783
1784 dprintk(DBG_FLOW, "%s\n", __func__);
1785 if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1786 return -EINVAL;
1787 cap->bounds = dev->crop_bounds;
1788 cap->defrect = dev->crop_defrect;
1789 cap->pixelaspect.numerator = 1;
1790 cap->pixelaspect.denominator = 1;
1791 if (dev->tvnorm->id & V4L2_STD_525_60) {
1792 cap->pixelaspect.numerator = 11;
1793 cap->pixelaspect.denominator = 10;
1794 }
1795 if (dev->tvnorm->id & V4L2_STD_625_50) {
1796 cap->pixelaspect.numerator = 54;
1797 cap->pixelaspect.denominator = 59;
1798 }
1799 return 0;
1800}
1801
1802static int tw68_g_crop(struct file *file, void *f, struct v4l2_crop *crop)
1803{
1804 struct tw68_fh *fh = f;
1805 struct tw68_dev *dev = fh->dev;
1806
1807 dprintk(DBG_FLOW, "%s\n", __func__);
1808 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1809 return -EINVAL;
1810 crop->c = dev->crop_current;
1811 return 0;
1812}
1813
1814static int tw68_s_crop(struct file *file, void *f, struct v4l2_crop *crop)
1815{
1816 struct tw68_fh *fh = f;
1817 struct tw68_dev *dev = fh->dev;
1818 struct v4l2_rect *b = &dev->crop_bounds;
1819
1820 dprintk(DBG_FLOW, "%s\n", __func__);
1821 if (res_locked(fh->dev, RESOURCE_VIDEO))
1822 return -EBUSY;
1823
1824 if ((crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
1825 (crop->c.height < 0) || (crop->c.width < 0)) {
1826 dprintk(DBG_UNEXPECTED, "%s: invalid request\n", __func__);
1827 return -EINVAL;
1828 }
1829
1830 if (crop->c.top < b->top)
1831 crop->c.top = b->top;
1832 if (crop->c.top > b->top + b->height)
1833 crop->c.top = b->top + b->height;
1834 if (crop->c.height > b->top - crop->c.top + b->height)
1835 crop->c.height = b->top - crop->c.top + b->height;
1836
1837 if (crop->c.left < b->left)
1838 crop->c.left = b->left;
1839 if (crop->c.left > b->left + b->width)
1840 crop->c.left = b->left + b->width;
1841 if (crop->c.width > b->left - crop->c.left + b->width)
1842 crop->c.width = b->left - crop->c.left + b->width;
1843
1844 dprintk(DBG_FLOW, "%s: setting cropping rectangle: top=%d, left=%d, "
1845 "width=%d, height=%d\n", __func__, crop->c.top,
1846 crop->c.left, crop->c.width, crop->c.height);
1847 dev->crop_current = crop->c;
1848 return 0;
1849}
1850
1851/*
1852 * Wrappers for the v4l2_ioctl_ops functions
1853 */
1854#ifdef CONFIG_VIDEO_V4L1_COMPAT
1855static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
1856{
1857 struct tw68_fh *fh = file->private_data;
1858 return videobuf_cgmbuf(tw68_queue(fh), mbuf, 8);
1859}
1860#endif
1861
1862static int tw68_reqbufs(struct file *file, void *priv,
1863 struct v4l2_requestbuffers *p)
1864{
1865 struct tw68_fh *fh = priv;
1866 return videobuf_reqbufs(tw68_queue(fh), p);
1867}
1868
1869static int tw68_querybuf(struct file *file, void *priv,
1870 struct v4l2_buffer *b)
1871{
1872 struct tw68_fh *fh = priv;
1873 return videobuf_querybuf(tw68_queue(fh), b);
1874}
1875
1876static int tw68_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1877{
1878 struct tw68_fh *fh = priv;
1879 return videobuf_qbuf(tw68_queue(fh), b);
1880}
1881
1882static int tw68_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1883{
1884 struct tw68_fh *fh = priv;
1885 return videobuf_dqbuf(tw68_queue(fh), b,
1886 file->f_flags & O_NONBLOCK);
1887}
1888
1889static int tw68_streamon(struct file *file, void *priv,
1890 enum v4l2_buf_type type)
1891{
1892 struct tw68_fh *fh = priv;
1893 struct tw68_dev *dev = fh->dev;
1894 int res = tw68_resource(fh);
1895
1896 dprintk(DBG_FLOW, "%s\n", __func__);
1897 if (!res_get(fh, res))
1898 return -EBUSY;
1899
1900 tw68_buffer_requeue(dev, &dev->video_q);
1901 return videobuf_streamon(tw68_queue(fh));
1902}
1903
1904static int tw68_streamoff(struct file *file, void *priv,
1905 enum v4l2_buf_type type)
1906{
1907 int err;
1908 struct tw68_fh *fh = priv;
1909 struct tw68_dev *dev = fh->dev;
1910 int res = tw68_resource(fh);
1911
1912 dprintk(DBG_FLOW, "%s\n", __func__);
1913 err = videobuf_streamoff(tw68_queue(fh));
1914 if (err < 0)
1915 return err;
1916 res_free(fh, res);
1917 return 0;
1918}
1919
1920#ifdef CONFIG_VIDEO_ADV_DEBUG
1921/* 815/*
1922 * Used strictly for internal development and debugging, this routine 816 * Used strictly for internal development and debugging, this routine
1923 * prints out the current register contents for the tw68xx device. 817 * prints out the current register contents for the tw68xx device.
@@ -1928,7 +822,7 @@ static void tw68_dump_regs(struct tw68_dev *dev)
1928 int i, j, k; 822 int i, j, k;
1929 unsigned char *cptr; 823 unsigned char *cptr;
1930 824
1931 printk(KERN_DEBUG "Full dump of TW68 registers:\n"); 825 pr_info("Full dump of TW68 registers:\n");
1932 /* First we do the PCI regs, 8 4-byte regs per line */ 826 /* First we do the PCI regs, 8 4-byte regs per line */
1933 for (i = 0; i < 0x100; i += 32) { 827 for (i = 0; i < 0x100; i += 32) {
1934 cptr = line; 828 cptr = line;
@@ -1941,7 +835,7 @@ static void tw68_dump_regs(struct tw68_dev *dev)
1941 cptr += sprintf(cptr, "%08x ", tw_readl(j)); 835 cptr += sprintf(cptr, "%08x ", tw_readl(j));
1942 *cptr++ = '\n'; 836 *cptr++ = '\n';
1943 *cptr = 0; 837 *cptr = 0;
1944 printk(KERN_DEBUG "%s", line); 838 pr_info("%s", line);
1945 } 839 }
1946 /* Next the control regs, which are single-byte, address mod 4 */ 840 /* Next the control regs, which are single-byte, address mod 4 */
1947 while (i < 0x400) { 841 while (i < 0x400) {
@@ -1958,29 +852,24 @@ static void tw68_dump_regs(struct tw68_dev *dev)
1958 } 852 }
1959 *cptr++ = '\n'; 853 *cptr++ = '\n';
1960 *cptr = 0; 854 *cptr = 0;
1961 printk(KERN_DEBUG "%s", line); 855 pr_info("%s", line);
1962 } 856 }
1963} 857}
1964 858
1965static int vidioc_log_status(struct file *file, void *priv) 859static int vidioc_log_status(struct file *file, void *priv)
1966{ 860{
1967 struct tw68_fh *fh = priv; 861 struct tw68_dev *dev = video_drvdata(file);
1968 struct tw68_dev *dev = fh->dev;
1969 862
1970 tw68_dump_regs(dev); 863 tw68_dump_regs(dev);
1971 return 0; 864 return v4l2_ctrl_log_status(file, priv);
1972} 865}
1973 866
867#ifdef CONFIG_VIDEO_ADV_DEBUG
1974static int vidioc_g_register(struct file *file, void *priv, 868static int vidioc_g_register(struct file *file, void *priv,
1975 struct v4l2_dbg_register *reg) 869 struct v4l2_dbg_register *reg)
1976{ 870{
1977 struct tw68_fh *fh = priv; 871 struct tw68_dev *dev = video_drvdata(file);
1978 struct tw68_dev *dev = fh->dev; /* needed for tw_readb */
1979 872
1980 dprintk(DBG_FLOW, "%s\n", __func__);
1981 if (!v4l2_chip_match_host(&reg->match))
1982 dprintk(DBG_UNEXPECTED, "%s: match failed\n", __func__);
1983 return -EINVAL;
1984 if (reg->size == 1) 873 if (reg->size == 1)
1985 reg->val = tw_readb(reg->reg); 874 reg->val = tw_readb(reg->reg);
1986 else 875 else
@@ -1989,17 +878,10 @@ static int vidioc_g_register(struct file *file, void *priv,
1989} 878}
1990 879
1991static int vidioc_s_register(struct file *file, void *priv, 880static int vidioc_s_register(struct file *file, void *priv,
1992 struct v4l2_dbg_register *reg) 881 const struct v4l2_dbg_register *reg)
1993{ 882{
1994 struct tw68_fh *fh = priv; 883 struct tw68_dev *dev = video_drvdata(file);
1995 struct tw68_dev *dev = fh->dev; /* needed for tw_writeb */
1996 884
1997 dprintk(DBG_FLOW, "%s: request to set reg 0x%04x to 0x%02x\n",
1998 __func__, (unsigned int)reg->reg, (unsigned int)reg->val);
1999 if (!v4l2_chip_match_host(&reg->match)) {
2000 dprintk(DBG_UNEXPECTED, "%s: match failed\n", __func__);
2001 return -EINVAL;
2002 }
2003 if (reg->size == 1) 885 if (reg->size == 1)
2004 tw_writeb(reg->reg, reg->val); 886 tw_writeb(reg->reg, reg->val);
2005 else 887 else
@@ -2008,151 +890,120 @@ static int vidioc_s_register(struct file *file, void *priv,
2008} 890}
2009#endif 891#endif
2010 892
893static const struct v4l2_ctrl_ops tw68_ctrl_ops = {
894 .s_ctrl = tw68_s_ctrl,
895};
896
2011static const struct v4l2_file_operations video_fops = { 897static const struct v4l2_file_operations video_fops = {
2012 .owner = THIS_MODULE, 898 .owner = THIS_MODULE,
2013 .open = video_open, 899 .open = v4l2_fh_open,
2014 .release = video_release, 900 .release = vb2_fop_release,
2015 .read = video_read, 901 .read = vb2_fop_read,
2016 .poll = video_poll, 902 .poll = vb2_fop_poll,
2017 .mmap = video_mmap, 903 .mmap = vb2_fop_mmap,
2018 .ioctl = video_ioctl2, 904 .unlocked_ioctl = video_ioctl2,
2019}; 905};
2020 906
2021static const struct v4l2_ioctl_ops video_ioctl_ops = { 907static const struct v4l2_ioctl_ops video_ioctl_ops = {
2022 .vidioc_querycap = tw68_querycap, 908 .vidioc_querycap = tw68_querycap,
2023 .vidioc_enum_fmt_vid_cap = tw68_enum_fmt_vid_cap, 909 .vidioc_enum_fmt_vid_cap = tw68_enum_fmt_vid_cap,
2024 .vidioc_reqbufs = tw68_reqbufs, 910 .vidioc_reqbufs = vb2_ioctl_reqbufs,
2025 .vidioc_querybuf = tw68_querybuf, 911 .vidioc_create_bufs = vb2_ioctl_create_bufs,
2026 .vidioc_qbuf = tw68_qbuf, 912 .vidioc_querybuf = vb2_ioctl_querybuf,
2027 .vidioc_dqbuf = tw68_dqbuf, 913 .vidioc_qbuf = vb2_ioctl_qbuf,
914 .vidioc_dqbuf = vb2_ioctl_dqbuf,
2028 .vidioc_s_std = tw68_s_std, 915 .vidioc_s_std = tw68_s_std,
2029 .vidioc_g_std = tw68_g_std, 916 .vidioc_g_std = tw68_g_std,
2030 .vidioc_enum_input = tw68_enum_input, 917 .vidioc_enum_input = tw68_enum_input,
2031 .vidioc_g_input = tw68_g_input, 918 .vidioc_g_input = tw68_g_input,
2032 .vidioc_s_input = tw68_s_input, 919 .vidioc_s_input = tw68_s_input,
2033 .vidioc_queryctrl = tw68_queryctrl, 920 .vidioc_streamon = vb2_ioctl_streamon,
2034 .vidioc_g_ctrl = tw68_g_ctrl, 921 .vidioc_streamoff = vb2_ioctl_streamoff,
2035 .vidioc_s_ctrl = tw68_s_ctrl,
2036 .vidioc_streamon = tw68_streamon,
2037 .vidioc_streamoff = tw68_streamoff,
2038 .vidioc_g_priority = tw68_g_priority,
2039 .vidioc_s_priority = tw68_s_priority,
2040 .vidioc_g_fmt_vid_cap = tw68_g_fmt_vid_cap, 922 .vidioc_g_fmt_vid_cap = tw68_g_fmt_vid_cap,
2041 .vidioc_try_fmt_vid_cap = tw68_try_fmt_vid_cap, 923 .vidioc_try_fmt_vid_cap = tw68_try_fmt_vid_cap,
2042 .vidioc_s_fmt_vid_cap = tw68_s_fmt_vid_cap, 924 .vidioc_s_fmt_vid_cap = tw68_s_fmt_vid_cap,
2043 .vidioc_cropcap = tw68_cropcap,
2044 .vidioc_g_crop = tw68_g_crop,
2045 .vidioc_s_crop = tw68_s_crop,
2046/*
2047 * Functions not yet implemented / not yet passing tests.
2048 */
2049
2050#if 0
2051 .vidioc_g_fmt_vbi_cap = tw68_try_get_set_fmt_vbi_cap,
2052 .vidioc_try_fmt_vbi_cap = tw68_try_get_set_fmt_vbi_cap,
2053 .vidioc_s_fmt_vbi_cap = tw68_try_get_set_fmt_vbi_cap,
2054#endif
2055 .vidioc_g_audio = tw68_g_audio,
2056 .vidioc_s_audio = tw68_s_audio,
2057 .vidioc_g_tuner = tw68_g_tuner,
2058 .vidioc_s_tuner = tw68_s_tuner,
2059 .vidioc_g_frequency = tw68_g_frequency,
2060 .vidioc_s_frequency = tw68_s_frequency,
2061#ifdef CONFIG_VIDEO_V4L1_COMPAT
2062 .vidiocgmbuf = vidiocgmbuf,
2063#endif
2064#ifdef CONFIG_VIDEO_ADV_DEBUG
2065 .vidioc_log_status = vidioc_log_status, 925 .vidioc_log_status = vidioc_log_status,
926 .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
927 .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
928#ifdef CONFIG_VIDEO_ADV_DEBUG
2066 .vidioc_g_register = vidioc_g_register, 929 .vidioc_g_register = vidioc_g_register,
2067 .vidioc_s_register = vidioc_s_register, 930 .vidioc_s_register = vidioc_s_register,
2068#endif 931#endif
2069}; 932};
2070 933
2071/* ------------------------------------------------------------------ */ 934static struct video_device tw68_video_template = {
2072/* exported stuff */
2073struct video_device tw68_video_template = {
2074 .name = "tw68_video", 935 .name = "tw68_video",
2075 .fops = &video_fops, 936 .fops = &video_fops,
2076 .ioctl_ops = &video_ioctl_ops, 937 .ioctl_ops = &video_ioctl_ops,
2077 .minor = -1, 938 .release = video_device_release_empty,
2078 .tvnorms = TW68_NORMS, 939 .tvnorms = TW68_NORMS,
2079 .current_norm = V4L2_STD_PAL,
2080};
2081
2082struct video_device tw68_radio_template = {
2083 .name = "tw68_radio",
2084}; 940};
2085 941
2086int tw68_videoport_init(struct tw68_dev *dev) 942/* ------------------------------------------------------------------ */
2087{ 943/* exported stuff */
2088 return 0;
2089}
2090
2091void tw68_set_tvnorm_hw(struct tw68_dev *dev) 944void tw68_set_tvnorm_hw(struct tw68_dev *dev)
2092{ 945{
2093 tw_andorb(TW68_SDT, 0x07, dev->tvnorm->format); 946 tw_andorb(TW68_SDT, 0x07, dev->tvnorm->format);
2094 return;
2095} 947}
2096 948
2097int tw68_video_init1(struct tw68_dev *dev) 949int tw68_video_init1(struct tw68_dev *dev)
2098{ 950{
2099 int i; 951 struct v4l2_ctrl_handler *hdl = &dev->hdl;
2100 952
2101 dprintk(DBG_FLOW, "%s\n", __func__); 953 v4l2_ctrl_handler_init(hdl, 6);
2102 /* sanitycheck insmod options */ 954 v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
2103 if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME) 955 V4L2_CID_BRIGHTNESS, -128, 127, 1, 20);
2104 gbuffers = 2; 956 v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
2105 if (gbufsz < 0 || gbufsz > gbufsz_max) 957 V4L2_CID_CONTRAST, 0, 255, 1, 100);
2106 gbufsz = gbufsz_max; 958 v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
2107 gbufsz = (gbufsz + PAGE_SIZE - 1) & PAGE_MASK; 959 V4L2_CID_SATURATION, 0, 255, 1, 128);
2108 960 /* NTSC only */
2109 /* put some sensible defaults into the data structures ... */ 961 v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
2110 for (i = 0; i < CTRLS; i++) 962 V4L2_CID_HUE, -128, 127, 1, 0);
2111 tw68_s_ctrl_value(dev, video_ctrls[i].id, 963 v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
2112 video_ctrls[i].default_value); 964 V4L2_CID_COLOR_KILLER, 0, 1, 1, 0);
2113#if 0 965 v4l2_ctrl_new_std(hdl, &tw68_ctrl_ops,
2114 if (dev->tda9887_conf && dev->ctl_automute) 966 V4L2_CID_CHROMA_AGC, 0, 1, 1, 1);
2115 dev->tda9887_conf |= TDA9887_AUTOMUTE; 967 if (hdl->error) {
2116 dev->automute = 0; 968 v4l2_ctrl_handler_free(hdl);
2117#endif 969 return hdl->error;
2118 INIT_LIST_HEAD(&dev->video_q.queued); 970 }
2119 INIT_LIST_HEAD(&dev->video_q.active); 971 dev->v4l2_dev.ctrl_handler = hdl;
2120 init_timer(&dev->video_q.timeout); 972 v4l2_ctrl_handler_setup(hdl);
2121 dev->video_q.timeout.function = tw68_buffer_timeout;
2122 dev->video_q.timeout.data = (unsigned long)(&dev->video_q);
2123 dev->video_q.dev = dev;
2124 dev->video_q.buf_compat = tw68_check_video_fmt;
2125 dev->video_q.start_dma = tw68_video_start_dma;
2126 tw68_risc_stopper(dev->pci, &dev->video_q.stopper);
2127
2128 if (tw68_boards[dev->board].video_out)
2129 tw68_videoport_init(dev);
2130
2131 return 0; 973 return 0;
2132} 974}
2133 975
2134int tw68_video_init2(struct tw68_dev *dev) 976int tw68_video_init2(struct tw68_dev *dev, int video_nr)
2135{ 977{
2136 dprintk(DBG_FLOW, "%s\n", __func__); 978 int ret;
979
2137 set_tvnorm(dev, &tvnorms[0]); 980 set_tvnorm(dev, &tvnorms[0]);
2138 video_mux(dev, 0);
2139/*
2140 tw68_tvaudio_setmut(dev);
2141 tw68_tvaudio_setvolume(dev, dev->ctl_volume);
2142*/
2143 return 0;
2144}
2145 981
2146/* 982 dev->fmt = format_by_fourcc(V4L2_PIX_FMT_BGR24);
2147 * tw68_irq_video_signalchange 983 dev->width = 720;
2148 * 984 dev->height = 576;
2149 * TODO: 985 dev->field = V4L2_FIELD_INTERLACED;
2150 * Check for presence of video signal. If not present, mute audio. 986
2151 * If present, log type of signal present. 987 INIT_LIST_HEAD(&dev->active);
2152 */ 988 dev->vidq.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2153void tw68_irq_video_signalchange(struct tw68_dev *dev) 989 dev->vidq.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
2154{ 990 dev->vidq.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ | VB2_DMABUF;
2155 return; 991 dev->vidq.ops = &tw68_video_qops;
992 dev->vidq.mem_ops = &vb2_dma_sg_memops;
993 dev->vidq.drv_priv = dev;
994 dev->vidq.gfp_flags = __GFP_DMA32;
995 dev->vidq.buf_struct_size = sizeof(struct tw68_buf);
996 dev->vidq.lock = &dev->lock;
997 dev->vidq.min_buffers_needed = 2;
998 ret = vb2_queue_init(&dev->vidq);
999 if (ret)
1000 return ret;
1001 dev->vdev = tw68_video_template;
1002 dev->vdev.v4l2_dev = &dev->v4l2_dev;
1003 dev->vdev.lock = &dev->lock;
1004 dev->vdev.queue = &dev->vidq;
1005 video_set_drvdata(&dev->vdev, dev);
1006 return video_register_device(&dev->vdev, VFL_TYPE_GRABBER, video_nr);
2156} 1007}
2157 1008
2158/* 1009/*
@@ -2171,60 +1022,39 @@ void tw68_irq_video_done(struct tw68_dev *dev, unsigned long status)
2171 * for the current buffer. 1022 * for the current buffer.
2172 */ 1023 */
2173 if (status & TW68_DMAPI) { 1024 if (status & TW68_DMAPI) {
2174 struct tw68_dmaqueue *q = &dev->video_q; 1025 struct tw68_buf *buf;
2175 dprintk(DBG_FLOW | DBG_TESTING, "DMAPI interrupt\n"); 1026
2176 spin_lock(&dev->slock); 1027 spin_lock(&dev->slock);
2177 /* 1028 buf = list_entry(dev->active.next, struct tw68_buf, list);
2178 * tw68_wakeup will take care of the buffer handling, 1029 list_del(&buf->list);
2179 * plus any non-video requirements.
2180 */
2181 tw68_wakeup(q, &dev->video_fieldcount);
2182 spin_unlock(&dev->slock); 1030 spin_unlock(&dev->slock);
2183 /* Check whether we have gotten into 'stopper' code */ 1031 v4l2_get_timestamp(&buf->vb.v4l2_buf.timestamp);
2184 reg = tw_readl(TW68_DMAP_PP); 1032 buf->vb.v4l2_buf.field = dev->field;
2185 if ((reg >= q->stopper.dma) && 1033 buf->vb.v4l2_buf.sequence = dev->seqnr++;
2186 (reg < q->stopper.dma + q->stopper.size)) { 1034 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
2187 /* Yes - log the information */
2188 dprintk(DBG_FLOW | DBG_TESTING,
2189 "%s: stopper risc code entered\n", __func__);
2190 }
2191 status &= ~(TW68_DMAPI); 1035 status &= ~(TW68_DMAPI);
2192 if (0 == status) 1036 if (0 == status)
2193 return; 1037 return;
2194 } 1038 }
2195 if (status & (TW68_VLOCK | TW68_HLOCK)) { /* lost sync */ 1039 if (status & (TW68_VLOCK | TW68_HLOCK))
2196 dprintk(DBG_UNUSUAL, "Lost sync\n"); 1040 dev_dbg(&dev->pci->dev, "Lost sync\n");
2197 } 1041 if (status & TW68_PABORT)
2198 if (status & TW68_PABORT) { /* TODO - what should we do? */ 1042 dev_err(&dev->pci->dev, "PABORT interrupt\n");
2199 dprintk(DBG_UNEXPECTED, "PABORT interrupt\n"); 1043 if (status & TW68_DMAPERR)
2200 } 1044 dev_err(&dev->pci->dev, "DMAPERR interrupt\n");
2201 if (status & TW68_DMAPERR) {
2202 dprintk(DBG_UNEXPECTED, "DMAPERR interrupt\n");
2203#if 0
2204 /* Stop risc & fifo */
2205 tw_clearl(TW68_DMAC, TW68_DMAP_EN | TW68_FIFO_EN);
2206 tw_clearl(TW68_INTMASK, dev->board_virqmask);
2207 dev->pci_irqmask &= ~dev->board_virqmask;
2208#endif
2209 }
2210 /* 1045 /*
2211 * On TW6800, FDMIS is apparently generated if video input is switched 1046 * On TW6800, FDMIS is apparently generated if video input is switched
2212 * during operation. Therefore, it is not enabled for that chip. 1047 * during operation. Therefore, it is not enabled for that chip.
2213 */ 1048 */
2214 if (status & TW68_FDMIS) { /* logic error somewhere */ 1049 if (status & TW68_FDMIS)
2215 dprintk(DBG_UNEXPECTED, "FDMIS interrupt\n"); 1050 dev_dbg(&dev->pci->dev, "FDMIS interrupt\n");
2216 /* Stop risc & fifo */ 1051 if (status & TW68_FFOF) {
2217// tw_clearl(TW68_DMAC, TW68_DMAP_EN | TW68_FIFO_EN); 1052 /* probably a logic error */
2218// tw_clearl(TW68_INTMASK, dev->board_virqmask);
2219// dev->pci_irqmask &= ~dev->board_virqmask;
2220 }
2221 if (status & TW68_FFOF) { /* probably a logic error */
2222 reg = tw_readl(TW68_DMAC) & TW68_FIFO_EN; 1053 reg = tw_readl(TW68_DMAC) & TW68_FIFO_EN;
2223 tw_clearl(TW68_DMAC, TW68_FIFO_EN); 1054 tw_clearl(TW68_DMAC, TW68_FIFO_EN);
2224 dprintk(DBG_UNUSUAL, "FFOF interrupt\n"); 1055 dev_dbg(&dev->pci->dev, "FFOF interrupt\n");
2225 tw_setl(TW68_DMAC, reg); 1056 tw_setl(TW68_DMAC, reg);
2226 } 1057 }
2227 if (status & TW68_FFERR) 1058 if (status & TW68_FFERR)
2228 dprintk(DBG_UNEXPECTED, "FFERR interrupt\n"); 1059 dev_dbg(&dev->pci->dev, "FFERR interrupt\n");
2229 return;
2230} 1060}
diff --git a/drivers/media/pci/tw68/tw68.h b/drivers/media/pci/tw68/tw68.h
index e723efb5e623..2c8abe26b13b 100644
--- a/drivers/media/pci/tw68/tw68.h
+++ b/drivers/media/pci/tw68/tw68.h
@@ -8,7 +8,11 @@
8 * acknowledged. Full credit goes to them - any problems within this code 8 * acknowledged. Full credit goes to them - any problems within this code
9 * are mine. 9 * are mine.
10 * 10 *
11 * Copyright (C) 2009 William M. Brack <wbrack@mmm.com.hk> 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>
12 * 16 *
13 * This program is free software; you can redistribute it and/or modify 17 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by 18 * it under the terms of the GNU General Public License as published by
@@ -19,54 +23,26 @@
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details. 25 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
26 * 02111-1307 USA
27 */ 26 */
28 27
29#include <linux/version.h> 28#include <linux/version.h>
30#define TW68_VERSION_CODE KERNEL_VERSION(0, 0, 8)
31
32#include <linux/pci.h> 29#include <linux/pci.h>
33#include <linux/i2c.h>
34#include <linux/i2c-algo-bit.h>
35#include <linux/videodev2.h> 30#include <linux/videodev2.h>
36#include <linux/kdev_t.h>
37#include <linux/input.h>
38#include <linux/notifier.h> 31#include <linux/notifier.h>
39#include <linux/delay.h> 32#include <linux/delay.h>
40#include <linux/mutex.h> 33#include <linux/mutex.h>
41 34#include <linux/io.h>
42#include <asm/io.h>
43 35
44#include <media/v4l2-common.h> 36#include <media/v4l2-common.h>
45#include <media/v4l2-ioctl.h> 37#include <media/v4l2-ioctl.h>
38#include <media/v4l2-ctrls.h>
46#include <media/v4l2-device.h> 39#include <media/v4l2-device.h>
40#include <media/videobuf2-dma-sg.h>
47 41
48#include <media/tuner.h>
49#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
50# include <media/ir-common.h>
51#endif
52#include <media/ir-kbd-i2c.h>
53#include <media/videobuf-dma-sg.h>
54
55#include "btcx-risc.h"
56#include "tw68-reg.h" 42#include "tw68-reg.h"
57 43
58#define UNSET (-1U) 44#define UNSET (-1U)
59 45
60/*
61 * dprintk statement within the code use a 'level' argument. For
62 * our purposes, we use the following levels:
63 */
64#define DBG_UNEXPECTED (1 << 0)
65#define DBG_UNUSUAL (1 << 1)
66#define DBG_TESTING (1 << 2)
67#define DBG_BUFF (1 << 3)
68#define DBG_FLOW (1 << 15)
69
70/* system vendor and device ID's */ 46/* system vendor and device ID's */
71#define PCI_VENDOR_ID_TECHWELL 0x1797 47#define PCI_VENDOR_ID_TECHWELL 0x1797
72#define PCI_DEVICE_ID_6800 0x6800 48#define PCI_DEVICE_ID_6800 0x6800
@@ -83,15 +59,9 @@
83#define PCI_DEVICE_ID_6816_3 0x6812 59#define PCI_DEVICE_ID_6816_3 0x6812
84#define PCI_DEVICE_ID_6816_4 0x6813 60#define PCI_DEVICE_ID_6816_4 0x6813
85 61
86/* subsystem vendor ID's */ 62#define TW68_NORMS ( \
87#define TW68_PCI_ID_TECHWELL 0x1797 63 V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM | \
88 64 V4L2_STD_PAL_M | V4L2_STD_PAL_Nc | V4L2_STD_PAL_60)
89#define TW68_NORMS (\
90 V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM | \
91 V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \
92 V4L2_STD_PAL_M | V4L2_STD_PAL_Nc | V4L2_STD_PAL_60 | \
93 V4L2_STD_525_60 | V4L2_STD_625_50 | \
94 V4L2_STD_SECAM_L| V4L2_STD_SECAM_LC | V4L2_STD_SECAM_DK)
95 65
96#define TW68_VID_INTS (TW68_FFERR | TW68_PABORT | TW68_DMAPERR | \ 66#define TW68_VID_INTS (TW68_FFERR | TW68_PABORT | TW68_DMAPERR | \
97 TW68_FFOF | TW68_DMAPI) 67 TW68_FFOF | TW68_DMAPI)
@@ -101,12 +71,13 @@
101#define TW68_I2C_INTS (TW68_SBERR | TW68_SBDONE | TW68_SBERR2 | \ 71#define TW68_I2C_INTS (TW68_SBERR | TW68_SBDONE | TW68_SBERR2 | \
102 TW68_SBDONE2) 72 TW68_SBDONE2)
103 73
104typedef enum { 74enum tw68_decoder_type {
105 TW6800, 75 TW6800,
106 TW6801, 76 TW6801,
107 TW6804, 77 TW6804,
108 TWXXXX, 78 TWXXXX,
109} TW68_DECODER_TYPE; 79};
80
110/* ----------------------------------------------------------- */ 81/* ----------------------------------------------------------- */
111/* static data */ 82/* static data */
112 83
@@ -153,164 +124,24 @@ struct tw68_format {
153#define TW68_BOARD_GENERIC_6802 1 124#define TW68_BOARD_GENERIC_6802 1
154 125
155#define TW68_MAXBOARDS 16 126#define TW68_MAXBOARDS 16
156#define TW68_INPUT_MAX 8 127#define TW68_INPUT_MAX 4
157
158/* ----------------------------------------------------------- */
159/* enums */
160
161enum tw68_mpeg_type {
162 TW68_MPEG_UNUSED,
163 TW68_MPEG_EMPRESS,
164 TW68_MPEG_DVB,
165};
166
167enum tw68_audio_in {
168 TV = 1,
169 LINE1 = 2,
170 LINE2 = 3,
171 LINE2_LEFT,
172};
173
174enum tw68_video_out {
175 CCIR656 = 1,
176};
177
178/* Structs for card definition */
179struct tw68_input {
180 char *name; /* text description */
181 unsigned int vmux; /* mux value */
182 enum tw68_audio_in mux;
183 unsigned int gpio;
184 unsigned int tv:1;
185};
186
187struct tw68_board {
188 char *name;
189 unsigned int audio_clock;
190
191 /* input switching */
192 unsigned int gpiomask;
193 struct tw68_input inputs[TW68_INPUT_MAX];
194 struct tw68_input radio;
195 struct tw68_input mute;
196
197 /* i2c chip info */
198 unsigned int tuner_type;
199 unsigned int radio_type;
200 unsigned char tuner_addr;
201 unsigned char radio_addr;
202
203 unsigned int tda9887_conf;
204 unsigned int tuner_config;
205
206 enum tw68_video_out video_out;
207 enum tw68_mpeg_type mpeg;
208 unsigned int vid_port_opts;
209};
210
211#define card_has_radio(dev) (NULL != tw68_boards[dev->board].radio.name)
212#define card_has_mpeg(dev) (TW68_MPEG_UNUSED != \
213 tw68_boards[dev->board].mpeg)
214#define card_in(dev, n) (tw68_boards[dev->board].inputs[n])
215#define card(dev) (tw68_boards[dev->board])
216 128
217/* ----------------------------------------------------------- */ 129/* ----------------------------------------------------------- */
218/* device / file handle status */ 130/* device / file handle status */
219 131
220#define RESOURCE_VIDEO 1
221#define RESOURCE_VBI 2
222
223#define INTERLACE_AUTO 0
224#define INTERLACE_ON 1
225#define INTERLACE_OFF 2
226
227#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */ 132#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */
228 133
229struct tw68_dev; /* forward delclaration */ 134struct tw68_dev; /* forward delclaration */
230 135
231/* tvaudio thread status */
232struct tw68_thread {
233 struct task_struct *thread;
234 unsigned int scan1;
235 unsigned int scan2;
236 unsigned int mode;
237 unsigned int stopped;
238};
239
240/* buffer for one video/vbi/ts frame */ 136/* buffer for one video/vbi/ts frame */
241struct tw68_buf { 137struct tw68_buf {
242 /* common v4l buffer stuff -- must be first */ 138 struct vb2_buffer vb;
243 struct videobuf_buffer vb; 139 struct list_head list;
244
245 /* tw68 specific */
246 struct tw68_format *fmt;
247 struct tw68_input *input;
248 unsigned int top_seen;
249 int (*activate)(struct tw68_dev *dev,
250 struct tw68_buf *buf,
251 struct tw68_buf *next);
252 struct btcx_riscmem risc;
253 unsigned int bpl;
254};
255 140
256struct tw68_dmaqueue { 141 unsigned int size;
257 struct tw68_dev *dev; 142 __le32 *cpu;
258 struct list_head active; 143 __le32 *jmp;
259 struct list_head queued; 144 dma_addr_t dma;
260 struct timer_list timeout;
261 struct btcx_riscmem stopper;
262 int (*buf_compat)(struct tw68_buf *prev,
263 struct tw68_buf *buf);
264 int (*start_dma)(struct tw68_dev *dev,
265 struct tw68_dmaqueue *q,
266 struct tw68_buf *buf);
267};
268
269/* video filehandle status */
270struct tw68_fh {
271 struct tw68_dev *dev;
272 unsigned int radio;
273 enum v4l2_buf_type type;
274 unsigned int resources;
275 enum v4l2_priority prio;
276
277 /* video capture */
278 struct tw68_format *fmt;
279 unsigned int width, height;
280 struct videobuf_queue cap; /* also used for overlay */
281
282 /* vbi capture */
283 struct videobuf_queue vbi;
284};
285
286/* dmasound dsp status */
287struct tw68_dmasound {
288 struct mutex lock;
289 int minor_mixer;
290 int minor_dsp;
291 unsigned int users_dsp;
292
293 /* mixer */
294 enum tw68_audio_in input;
295 unsigned int count;
296 unsigned int line1;
297 unsigned int line2;
298
299 /* dsp */
300 unsigned int afmt;
301 unsigned int rate;
302 unsigned int channels;
303 unsigned int recording_on;
304 unsigned int dma_running;
305 unsigned int blocks;
306 unsigned int blksize;
307 unsigned int bufsize;
308 struct videobuf_dmabuf dma;
309 unsigned int dma_blk;
310 unsigned int read_offset;
311 unsigned int read_count;
312 void *priv_data;
313 struct snd_pcm_substream *substream;
314}; 145};
315 146
316struct tw68_fmt { 147struct tw68_fmt {
@@ -321,58 +152,20 @@ struct tw68_fmt {
321 u32 twformat; 152 u32 twformat;
322}; 153};
323 154
324/* ts/mpeg status */
325struct tw68_ts {
326 /* TS capture */
327 int nr_packets;
328 int nr_bufs;
329};
330
331/* ts/mpeg ops */
332struct tw68_mpeg_ops {
333 enum tw68_mpeg_type type;
334 struct list_head next;
335 int (*init)(struct tw68_dev *dev);
336 int (*fini)(struct tw68_dev *dev);
337 void (*signal_change)(struct tw68_dev *dev);
338};
339
340enum tw68_ts_status {
341 TW68_TS_STOPPED,
342 TW68_TS_BUFF_DONE,
343 TW68_TS_STARTED,
344};
345
346/* global device status */ 155/* global device status */
347struct tw68_dev { 156struct tw68_dev {
348 struct list_head devlist;
349 struct mutex lock; 157 struct mutex lock;
350 spinlock_t slock; 158 spinlock_t slock;
351 struct v4l2_prio_state prio; 159 u16 instance;
352 struct v4l2_device v4l2_dev; 160 struct v4l2_device v4l2_dev;
353 /* workstruct for loading modules */
354 struct work_struct request_module_wk;
355
356 /* insmod option/autodetected */
357 int autodetected;
358 161
359 /* various device info */ 162 /* various device info */
360 TW68_DECODER_TYPE vdecoder; 163 enum tw68_decoder_type vdecoder;
361 unsigned int resources; 164 struct video_device vdev;
362 struct video_device *video_dev; 165 struct v4l2_ctrl_handler hdl;
363 struct video_device *radio_dev;
364 struct video_device *vbi_dev;
365 struct tw68_dmasound dmasound;
366
367#if LINUX_VERSION_CODE < KERNEL_VERSION(3,0,0)
368 /* infrared remote */
369 int has_remote;
370 struct card_ir *remote;
371#endif
372 166
373 /* pci i/o */ 167 /* pci i/o */
374 char name[32]; 168 char *name;
375 int nr;
376 struct pci_dev *pci; 169 struct pci_dev *pci;
377 unsigned char pci_rev, pci_lat; 170 unsigned char pci_rev, pci_lat;
378 u32 __iomem *lmmio; 171 u32 __iomem *lmmio;
@@ -381,75 +174,18 @@ struct tw68_dev {
381 /* The irq mask to be used will depend upon the chip type */ 174 /* The irq mask to be used will depend upon the chip type */
382 u32 board_virqmask; 175 u32 board_virqmask;
383 176
384 /* config info */ 177 /* video capture */
385 unsigned int board; 178 const struct tw68_format *fmt;
386 unsigned int tuner_type; 179 unsigned width, height;
387 unsigned int radio_type; 180 unsigned seqnr;
388 unsigned char tuner_addr; 181 unsigned field;
389 unsigned char radio_addr; 182 struct vb2_queue vidq;
390 183 struct list_head active;
391 unsigned int tda9887_conf;
392 unsigned int gpio_value;
393
394 /* i2c i/o */
395 struct i2c_algo_bit_data i2c_algo;
396 struct i2c_adapter i2c_adap;
397 struct i2c_client i2c_client;
398 u32 i2c_state;
399 u32 i2c_done;
400 wait_queue_head_t i2c_queue;
401 int i2c_rc;
402 unsigned char eedata[256];
403
404 /* video+ts+vbi capture */
405 struct tw68_dmaqueue video_q;
406 struct tw68_dmaqueue vbi_q;
407 unsigned int video_fieldcount;
408 unsigned int vbi_fieldcount;
409 184
410 /* various v4l controls */ 185 /* various v4l controls */
411 struct tw68_tvnorm *tvnorm; /* video */ 186 const struct tw68_tvnorm *tvnorm; /* video */
412 struct tw68_tvaudio *tvaudio; 187
413#if 0 188 int input;
414 unsigned int ctl_input;
415 int ctl_bright;
416 int ctl_contrast;
417 int ctl_hue;
418 int ctl_saturation;
419 int ctl_freq;
420 int ctl_mute; /* audio */
421 int ctl_volume;
422 int ctl_invert; /* private */
423 int ctl_mirror;
424 int ctl_y_odd;
425 int ctl_y_even;
426 int ctl_automute;
427#endif
428
429 /* crop */
430 struct v4l2_rect crop_bounds;
431 struct v4l2_rect crop_defrect;
432 struct v4l2_rect crop_current;
433
434 /* other global state info */
435 unsigned int automute;
436 struct tw68_thread thread;
437 /* input is latest requested by app, hw_input is current hw setting */
438 struct tw68_input *input;
439 struct tw68_input *hw_input;
440 unsigned int hw_mute;
441 int last_carrier;
442 int nosignal;
443 unsigned int insuspend;
444
445 /* TW68_MPEG_* */
446 struct tw68_ts ts;
447 struct tw68_dmaqueue ts_q;
448 enum tw68_ts_status ts_state;
449 unsigned int buff_cnt;
450 struct tw68_mpeg_ops *mops;
451
452 void (*gate_ctrl)(struct tw68_dev *dev, int open);
453}; 189};
454 190
455/* ----------------------------------------------------------- */ 191/* ----------------------------------------------------------- */
@@ -473,116 +209,23 @@ struct tw68_dev {
473#define tw_clearb(reg, bit) \ 209#define tw_clearb(reg, bit) \
474 writeb((readb(dev->bmmio+(reg)) & ~(bit)), \ 210 writeb((readb(dev->bmmio+(reg)) & ~(bit)), \
475 dev->bmmio + (reg)) 211 dev->bmmio + (reg))
476#define tw_call_all(dev, o, f, args...) do { \
477 if (dev->gate_ctrl) \
478 dev->gate_ctrl(dev, 1); \
479 v4l2_device_call_all(&(dev)->v4l2_dev, 0, o, f , ##args); \
480 if (dev->gate_ctrl) \
481 dev->gate_ctrl(dev, 0); \
482} while (0)
483 212
484#define tw_wait(us) { udelay(us); } 213#define tw_wait(us) { udelay(us); }
485 214
486static inline struct tw68_dev *to_tw68_dev(struct v4l2_device *v4l2_dev)
487{
488 return container_of(v4l2_dev, struct tw68_dev, v4l2_dev);
489}
490
491/* ----------------------------------------------------------- */
492/* tw68-core.c */
493
494extern struct list_head tw68_devlist;
495extern struct mutex tw68_devlist_lock;
496extern unsigned int irq_debug;
497
498int tw68_buffer_count(unsigned int size, unsigned int count);
499void tw68_buffer_queue(struct tw68_dev *dev, struct tw68_dmaqueue *q,
500 struct tw68_buf *buf);
501void tw68_buffer_timeout(unsigned long data);
502int tw68_set_dmabits(struct tw68_dev *dev);
503void tw68_dma_free(struct videobuf_queue *q, struct tw68_buf *buf);
504void tw68_wakeup(struct tw68_dmaqueue *q, unsigned int *field_count);
505int tw68_buffer_requeue(struct tw68_dev *dev, struct tw68_dmaqueue *q);
506
507/* ----------------------------------------------------------- */
508/* tw68-cards.c */
509
510extern struct tw68_board tw68_boards[];
511extern const unsigned int tw68_bcount;
512extern struct pci_device_id __devinitdata tw68_pci_tbl[];
513
514int tw68_board_init1(struct tw68_dev *dev);
515int tw68_board_init2(struct tw68_dev *dev);
516int tw68_tuner_callback(void *priv, int component, int command, int arg);
517
518/* ----------------------------------------------------------- */
519/* tw68-i2c.c */
520
521int tw68_i2c_register(struct tw68_dev *dev);
522int tw68_i2c_unregister(struct tw68_dev *dev);
523void tw68_irq_i2c(struct tw68_dev *dev, int status);
524
525/* ----------------------------------------------------------- */ 215/* ----------------------------------------------------------- */
526/* tw68-video.c */ 216/* tw68-video.c */
527 217
528extern unsigned int video_debug;
529extern struct video_device tw68_video_template;
530extern struct video_device tw68_radio_template;
531
532int tw68_videoport_init(struct tw68_dev *dev);
533void tw68_set_tvnorm_hw(struct tw68_dev *dev); 218void tw68_set_tvnorm_hw(struct tw68_dev *dev);
534 219
535int tw68_video_init1(struct tw68_dev *dev); 220int tw68_video_init1(struct tw68_dev *dev);
536int tw68_video_init2(struct tw68_dev *dev); 221int tw68_video_init2(struct tw68_dev *dev, int video_nr);
537void tw68_irq_video_signalchange(struct tw68_dev *dev);
538void tw68_irq_video_done(struct tw68_dev *dev, unsigned long status); 222void tw68_irq_video_done(struct tw68_dev *dev, unsigned long status);
539 223int tw68_video_start_dma(struct tw68_dev *dev, struct tw68_buf *buf);
540/* ----------------------------------------------------------- */
541/* tw68-ts.c */
542
543int tw68_ts_init1(struct tw68_dev *dev);
544int tw68_ts_fini(struct tw68_dev *dev);
545void tw68_irq_ts_done(struct tw68_dev *dev, unsigned long status);
546
547int tw68_ts_register(struct tw68_mpeg_ops *ops);
548void tw68_ts_unregister(struct tw68_mpeg_ops *ops);
549
550int tw68_ts_init_hw(struct tw68_dev *dev);
551
552/* ----------------------------------------------------------- */
553/* tw68-vbi.c */
554
555extern struct videobuf_queue_ops tw68_vbi_qops;
556extern struct video_device tw68_vbi_template;
557
558int tw68_vbi_init1(struct tw68_dev *dev);
559int tw68_vbi_fini(struct tw68_dev *dev);
560void tw68_irq_vbi_done(struct tw68_dev *dev, unsigned long status);
561
562/* ----------------------------------------------------------- */
563/* tw68-tvaudio.c */
564
565int tw68_tvaudio_rx2mode(u32 rx);
566
567void tw68_tvaudio_setmute(struct tw68_dev *dev);
568void tw68_tvaudio_setinput(struct tw68_dev *dev,
569 struct tw68_input *in);
570void tw68_tvaudio_setvolume(struct tw68_dev *dev, int level);
571int tw68_tvaudio_getstereo(struct tw68_dev *dev);
572void tw68_tvaudio_init(struct tw68_dev *dev);
573int tw68_tvaudio_init2(struct tw68_dev *dev);
574int tw68_tvaudio_fini(struct tw68_dev *dev);
575int tw68_tvaudio_do_scan(struct tw68_dev *dev);
576int tw_dsp_writel(struct tw68_dev *dev, int reg, u32 value);
577void tw68_enable_i2s(struct tw68_dev *dev);
578 224
579/* ----------------------------------------------------------- */ 225/* ----------------------------------------------------------- */
580/* tw68-risc.c */ 226/* tw68-risc.c */
581 227
582int tw68_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, 228int tw68_risc_buffer(struct pci_dev *pci, struct tw68_buf *buf,
583 struct scatterlist *sglist, unsigned int top_offset, 229 struct scatterlist *sglist, unsigned int top_offset,
584 unsigned int bottom_offset, unsigned int bpl, 230 unsigned int bottom_offset, unsigned int bpl,
585 unsigned int padding, unsigned int lines); 231 unsigned int padding, unsigned int lines);
586int tw68_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc);
587int tw68_risc_overlay(struct tw68_fh *fh, struct btcx_riscmem *risc,
588 int field_type);