aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/bt8xx
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/bt8xx')
-rw-r--r--drivers/media/video/bt8xx/Kconfig25
-rw-r--r--drivers/media/video/bt8xx/Makefile12
-rw-r--r--drivers/media/video/bt8xx/bt832.c265
-rw-r--r--drivers/media/video/bt8xx/bt832.h305
-rw-r--r--drivers/media/video/bt8xx/bt848.h366
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c5078
-rw-r--r--drivers/media/video/bt8xx/bttv-driver.c4321
-rw-r--r--drivers/media/video/bt8xx/bttv-gpio.c208
-rw-r--r--drivers/media/video/bt8xx/bttv-i2c.c478
-rw-r--r--drivers/media/video/bt8xx/bttv-if.c159
-rw-r--r--drivers/media/video/bt8xx/bttv-input.c450
-rw-r--r--drivers/media/video/bt8xx/bttv-risc.c795
-rw-r--r--drivers/media/video/bt8xx/bttv-vbi.c221
-rw-r--r--drivers/media/video/bt8xx/bttv.h390
-rw-r--r--drivers/media/video/bt8xx/bttvp.h413
15 files changed, 13486 insertions, 0 deletions
diff --git a/drivers/media/video/bt8xx/Kconfig b/drivers/media/video/bt8xx/Kconfig
new file mode 100644
index 000000000000..085477c12612
--- /dev/null
+++ b/drivers/media/video/bt8xx/Kconfig
@@ -0,0 +1,25 @@
1config VIDEO_BT848
2 tristate "BT848 Video For Linux"
3 depends on VIDEO_DEV && PCI && I2C
4 select I2C_ALGOBIT
5 select FW_LOADER
6 select VIDEO_BTCX
7 select VIDEO_BUF
8 select VIDEO_IR
9 select VIDEO_TUNER
10 select VIDEO_TVEEPROM
11 select VIDEO_MSP3400
12 ---help---
13 Support for BT848 based frame grabber/overlay boards. This includes
14 the Miro, Hauppauge and STB boards. Please read the material in
15 <file:Documentation/video4linux/bttv/> for more information.
16
17 To compile this driver as a module, choose M here: the
18 module will be called bttv.
19
20config VIDEO_BT848_DVB
21 bool "DVB/ATSC Support for bt878 based TV cards"
22 depends on VIDEO_BT848 && DVB_CORE
23 select DVB_BT8XX
24 ---help---
25 This adds support for DVB/ATSC cards based on the BT878 chip.
diff --git a/drivers/media/video/bt8xx/Makefile b/drivers/media/video/bt8xx/Makefile
new file mode 100644
index 000000000000..94350f21cdc0
--- /dev/null
+++ b/drivers/media/video/bt8xx/Makefile
@@ -0,0 +1,12 @@
1#
2# Makefile for the video capture/playback device drivers.
3#
4
5bttv-objs := bttv-driver.o bttv-cards.o bttv-if.o \
6 bttv-risc.o bttv-vbi.o bttv-i2c.o bttv-gpio.o \
7 bttv-input.o
8
9obj-$(CONFIG_VIDEO_BT848) += bttv.o
10
11EXTRA_CFLAGS += -I$(src)/..
12EXTRA_CFLAGS += -I$(srctree)/drivers/media/dvb/dvb-core
diff --git a/drivers/media/video/bt8xx/bt832.c b/drivers/media/video/bt8xx/bt832.c
new file mode 100644
index 000000000000..a51876137880
--- /dev/null
+++ b/drivers/media/video/bt8xx/bt832.c
@@ -0,0 +1,265 @@
1/* Driver for Bt832 CMOS Camera Video Processor
2 i2c-addresses: 0x88 or 0x8a
3
4 The BT832 interfaces to a Quartzsight Digital Camera (352x288, 25 or 30 fps)
5 via a 9 pin connector ( 4-wire SDATA, 2-wire i2c, SCLK, VCC, GND).
6 It outputs an 8-bit 4:2:2 YUV or YCrCb video signal which can be directly
7 connected to bt848/bt878 GPIO pins on this purpose.
8 (see: VLSI Vision Ltd. www.vvl.co.uk for camera datasheets)
9
10 Supported Cards:
11 - Pixelview Rev.4E: 0x8a
12 GPIO 0x400000 toggles Bt832 RESET, and the chip changes to i2c 0x88 !
13
14 (c) Gunther Mayer, 2002
15
16 STATUS:
17 - detect chip and hexdump
18 - reset chip and leave low power mode
19 - detect camera present
20
21 TODO:
22 - make it work (find correct setup for Bt832 and Bt878)
23*/
24
25#include <linux/module.h>
26#include <linux/kernel.h>
27#include <linux/i2c.h>
28#include <linux/types.h>
29#include <linux/videodev.h>
30#include <linux/init.h>
31#include <linux/errno.h>
32#include <linux/slab.h>
33#include <media/v4l2-common.h>
34
35#include "bttv.h"
36#include "bt832.h"
37
38MODULE_LICENSE("GPL");
39
40/* Addresses to scan */
41static unsigned short normal_i2c[] = { I2C_ADDR_BT832_ALT1>>1, I2C_ADDR_BT832_ALT2>>1,
42 I2C_CLIENT_END };
43I2C_CLIENT_INSMOD;
44
45int debug; /* debug output */
46module_param(debug, int, 0644);
47
48/* ---------------------------------------------------------------------- */
49
50static int bt832_detach(struct i2c_client *client);
51
52
53static struct i2c_driver driver;
54static struct i2c_client client_template;
55
56struct bt832 {
57 struct i2c_client client;
58};
59
60int bt832_hexdump(struct i2c_client *i2c_client_s, unsigned char *buf)
61{
62 int i,rc;
63 buf[0]=0x80; // start at register 0 with auto-increment
64 if (1 != (rc = i2c_master_send(i2c_client_s,buf,1)))
65 v4l_err(i2c_client_s,"i2c i/o error: rc == %d (should be 1)\n",rc);
66
67 for(i=0;i<65;i++)
68 buf[i]=0;
69 if (65 != (rc=i2c_master_recv(i2c_client_s,buf,65)))
70 v4l_err(i2c_client_s,"i2c i/o error: rc == %d (should be 65)\n",rc);
71
72 // Note: On READ the first byte is the current index
73 // (e.g. 0x80, what we just wrote)
74
75 if(debug>1) {
76 int i;
77 v4l_dbg(2, debug,i2c_client_s,"hexdump:");
78 for(i=1;i<65;i++) {
79 if(i!=1) {
80 if(((i-1)%8)==0) printk(" ");
81 if(((i-1)%16)==0) {
82 printk("\n");
83 v4l_dbg(2, debug,i2c_client_s,"hexdump:");
84 }
85 }
86 printk(" %02x",buf[i]);
87 }
88 printk("\n");
89 }
90 return 0;
91}
92
93// Return: 1 (is a bt832), 0 (No bt832 here)
94int bt832_init(struct i2c_client *i2c_client_s)
95{
96 unsigned char *buf;
97 int rc;
98
99 buf=kmalloc(65,GFP_KERNEL);
100 bt832_hexdump(i2c_client_s,buf);
101
102 if(buf[0x40] != 0x31) {
103 v4l_err(i2c_client_s,"This i2c chip is no bt832 (id=%02x). Detaching.\n",buf[0x40]);
104 kfree(buf);
105 return 0;
106 }
107
108 v4l_err(i2c_client_s,"Write 0 tp VPSTATUS\n");
109 buf[0]=BT832_VP_STATUS; // Reg.52
110 buf[1]= 0x00;
111 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
112 v4l_err(i2c_client_s,"i2c i/o error VPS: rc == %d (should be 2)\n",rc);
113
114 bt832_hexdump(i2c_client_s,buf);
115
116
117 // Leave low power mode:
118 v4l_err(i2c_client_s,"leave low power mode.\n");
119 buf[0]=BT832_CAM_SETUP0; //0x39 57
120 buf[1]=0x08;
121 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
122 v4l_err(i2c_client_s,"i2c i/o error LLPM: rc == %d (should be 2)\n",rc);
123
124 bt832_hexdump(i2c_client_s,buf);
125
126 v4l_info(i2c_client_s,"Write 0 tp VPSTATUS\n");
127 buf[0]=BT832_VP_STATUS; // Reg.52
128 buf[1]= 0x00;
129 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
130 v4l_err(i2c_client_s,"i2c i/o error VPS: rc == %d (should be 2)\n",rc);
131
132 bt832_hexdump(i2c_client_s,buf);
133
134
135 // Enable Output
136 v4l_info(i2c_client_s,"Enable Output\n");
137 buf[0]=BT832_VP_CONTROL1; // Reg.40
138 buf[1]= 0x27 & (~0x01); // Default | !skip
139 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
140 v4l_err(i2c_client_s,"i2c i/o error EO: rc == %d (should be 2)\n",rc);
141
142 bt832_hexdump(i2c_client_s,buf);
143
144
145 // for testing (even works when no camera attached)
146 v4l_info(i2c_client_s,"*** Generate NTSC M Bars *****\n");
147 buf[0]=BT832_VP_TESTCONTROL0; // Reg. 42
148 buf[1]=3; // Generate NTSC System M bars, Generate Frame timing internally
149 if (2 != (rc = i2c_master_send(i2c_client_s,buf,2)))
150 v4l_info(i2c_client_s,"i2c i/o error MBAR: rc == %d (should be 2)\n",rc);
151
152 v4l_info(i2c_client_s,"Camera Present: %s\n",
153 (buf[1+BT832_CAM_STATUS] & BT832_56_CAMERA_PRESENT) ? "yes":"no");
154
155 bt832_hexdump(i2c_client_s,buf);
156 kfree(buf);
157 return 1;
158}
159
160
161
162static int bt832_attach(struct i2c_adapter *adap, int addr, int kind)
163{
164 struct bt832 *t;
165
166 client_template.adapter = adap;
167 client_template.addr = addr;
168
169 if (NULL == (t = kzalloc(sizeof(*t), GFP_KERNEL)))
170 return -ENOMEM;
171 t->client = client_template;
172 i2c_set_clientdata(&t->client, t);
173 i2c_attach_client(&t->client);
174
175 v4l_info(&t->client,"chip found @ 0x%x\n", addr<<1);
176
177
178 if(! bt832_init(&t->client)) {
179 bt832_detach(&t->client);
180 return -1;
181 }
182
183 return 0;
184}
185
186static int bt832_probe(struct i2c_adapter *adap)
187{
188 if (adap->class & I2C_CLASS_TV_ANALOG)
189 return i2c_probe(adap, &addr_data, bt832_attach);
190 return 0;
191}
192
193static int bt832_detach(struct i2c_client *client)
194{
195 struct bt832 *t = i2c_get_clientdata(client);
196
197 v4l_info(&t->client,"dettach\n");
198 i2c_detach_client(client);
199 kfree(t);
200 return 0;
201}
202
203static int
204bt832_command(struct i2c_client *client, unsigned int cmd, void *arg)
205{
206 struct bt832 *t = i2c_get_clientdata(client);
207
208 if (debug>1)
209 v4l_i2c_print_ioctl(&t->client,cmd);
210
211 switch (cmd) {
212 case BT832_HEXDUMP: {
213 unsigned char *buf;
214 buf=kmalloc(65,GFP_KERNEL);
215 bt832_hexdump(&t->client,buf);
216 kfree(buf);
217 }
218 break;
219 case BT832_REATTACH:
220 v4l_info(&t->client,"re-attach\n");
221 i2c_del_driver(&driver);
222 i2c_add_driver(&driver);
223 break;
224 }
225 return 0;
226}
227
228/* ----------------------------------------------------------------------- */
229
230static struct i2c_driver driver = {
231 .driver = {
232 .name = "bt832",
233 },
234 .id = 0, /* FIXME */
235 .attach_adapter = bt832_probe,
236 .detach_client = bt832_detach,
237 .command = bt832_command,
238};
239static struct i2c_client client_template =
240{
241 .name = "bt832",
242 .driver = &driver,
243};
244
245
246static int __init bt832_init_module(void)
247{
248 return i2c_add_driver(&driver);
249}
250
251static void __exit bt832_cleanup_module(void)
252{
253 i2c_del_driver(&driver);
254}
255
256module_init(bt832_init_module);
257module_exit(bt832_cleanup_module);
258
259/*
260 * Overrides for Emacs so that we follow Linus's tabbing style.
261 * ---------------------------------------------------------------------------
262 * Local variables:
263 * c-basic-offset: 8
264 * End:
265 */
diff --git a/drivers/media/video/bt8xx/bt832.h b/drivers/media/video/bt8xx/bt832.h
new file mode 100644
index 000000000000..1ce8fa71f7db
--- /dev/null
+++ b/drivers/media/video/bt8xx/bt832.h
@@ -0,0 +1,305 @@
1/* Bt832 CMOS Camera Video Processor (VP)
2
3 The Bt832 CMOS Camera Video Processor chip connects a Quartsight CMOS
4 color digital camera directly to video capture devices via an 8-bit,
5 4:2:2 YUV or YCrCb video interface.
6
7 i2c addresses: 0x88 or 0x8a
8 */
9
10/* The 64 registers: */
11
12// Input Processor
13#define BT832_OFFSET 0
14#define BT832_RCOMP 1
15#define BT832_G1COMP 2
16#define BT832_G2COMP 3
17#define BT832_BCOMP 4
18// Exposures:
19#define BT832_FINEH 5
20#define BT832_FINEL 6
21#define BT832_COARSEH 7
22#define BT832_COARSEL 8
23#define BT832_CAMGAIN 9
24// Main Processor:
25#define BT832_M00 10
26#define BT832_M01 11
27#define BT832_M02 12
28#define BT832_M10 13
29#define BT832_M11 14
30#define BT832_M12 15
31#define BT832_M20 16
32#define BT832_M21 17
33#define BT832_M22 18
34#define BT832_APCOR 19
35#define BT832_GAMCOR 20
36// Level Accumulator Inputs
37#define BT832_VPCONTROL2 21
38#define BT832_ZONECODE0 22
39#define BT832_ZONECODE1 23
40#define BT832_ZONECODE2 24
41#define BT832_ZONECODE3 25
42// Level Accumulator Outputs:
43#define BT832_RACC 26
44#define BT832_GACC 27
45#define BT832_BACC 28
46#define BT832_BLACKACC 29
47#define BT832_EXP_AGC 30
48#define BT832_LACC0 31
49#define BT832_LACC1 32
50#define BT832_LACC2 33
51#define BT832_LACC3 34
52#define BT832_LACC4 35
53#define BT832_LACC5 36
54#define BT832_LACC6 37
55#define BT832_LACC7 38
56// System:
57#define BT832_VP_CONTROL0 39
58#define BT832_VP_CONTROL1 40
59#define BT832_THRESH 41
60#define BT832_VP_TESTCONTROL0 42
61#define BT832_VP_DMCODE 43
62#define BT832_ACB_CONFIG 44
63#define BT832_ACB_GNBASE 45
64#define BT832_ACB_MU 46
65#define BT832_CAM_TEST0 47
66#define BT832_AEC_CONFIG 48
67#define BT832_AEC_TL 49
68#define BT832_AEC_TC 50
69#define BT832_AEC_TH 51
70// Status:
71#define BT832_VP_STATUS 52
72#define BT832_VP_LINECOUNT 53
73#define BT832_CAM_DEVICEL 54 // e.g. 0x19
74#define BT832_CAM_DEVICEH 55 // e.g. 0x40 == 0x194 Mask0, 0x194 = 404 decimal (VVL-404 camera)
75#define BT832_CAM_STATUS 56
76 #define BT832_56_CAMERA_PRESENT 0x20
77//Camera Setups:
78#define BT832_CAM_SETUP0 57
79#define BT832_CAM_SETUP1 58
80#define BT832_CAM_SETUP2 59
81#define BT832_CAM_SETUP3 60
82// System:
83#define BT832_DEFCOR 61
84#define BT832_VP_TESTCONTROL1 62
85#define BT832_DEVICE_ID 63
86# define BT832_DEVICE_ID__31 0x31 // Bt832 has ID 0x31
87
88/* STMicroelectronivcs VV5404 camera module
89 i2c: 0x20: sensor address
90 i2c: 0xa0: eeprom for ccd defect map
91 */
92#define VV5404_device_h 0x00 // 0x19
93#define VV5404_device_l 0x01 // 0x40
94#define VV5404_status0 0x02
95#define VV5404_linecountc 0x03 // current line counter
96#define VV5404_linecountl 0x04
97#define VV5404_setup0 0x10
98#define VV5404_setup1 0x11
99#define VV5404_setup2 0x12
100#define VV5404_setup4 0x14
101#define VV5404_setup5 0x15
102#define VV5404_fine_h 0x20 // fine exposure
103#define VV5404_fine_l 0x21
104#define VV5404_coarse_h 0x22 //coarse exposure
105#define VV5404_coarse_l 0x23
106#define VV5404_gain 0x24 // ADC pre-amp gain setting
107#define VV5404_clk_div 0x25
108#define VV5404_cr 0x76 // control register
109#define VV5404_as0 0x77 // ADC setup register
110
111
112// IOCTL
113#define BT832_HEXDUMP _IOR('b',1,int)
114#define BT832_REATTACH _IOR('b',2,int)
115
116/* from BT8x8VXD/capdrv/dialogs.cpp */
117
118/*
119typedef enum { SVI, Logitech, Rockwell } CAMERA;
120
121static COMBOBOX_ENTRY gwCameraOptions[] =
122{
123 { SVI, "Silicon Vision 512N" },
124 { Logitech, "Logitech VideoMan 1.3" },
125 { Rockwell, "Rockwell QuartzSight PCI 1.0" }
126};
127
128// SRAM table values
129//===========================================================================
130typedef enum { TGB_NTSC624, TGB_NTSC780, TGB_NTSC858, TGB_NTSC392 } TimeGenByte;
131
132BYTE SRAMTable[][ 60 ] =
133{
134 // TGB_NTSC624
135 {
136 0x33, // size of table = 51
137 0x0E, 0xC0, 0x00, 0x00, 0x90, 0x02, 0x03, 0x10, 0x03, 0x06,
138 0x10, 0x04, 0x12, 0x12, 0x05, 0x02, 0x13, 0x04, 0x19, 0x00,
139 0x04, 0x39, 0x00, 0x06, 0x59, 0x08, 0x03, 0x85, 0x08, 0x07,
140 0x03, 0x50, 0x00, 0x91, 0x40, 0x00, 0x11, 0x01, 0x01, 0x4D,
141 0x0D, 0x02, 0x03, 0x11, 0x01, 0x05, 0x37, 0x00, 0x37, 0x21, 0x00
142 },
143 // TGB_NTSC780
144 {
145 0x33, // size of table = 51
146 0x0e, 0xc0, 0x00, 0x00, 0x90, 0xe2, 0x03, 0x10, 0x03, 0x06,
147 0x10, 0x34, 0x12, 0x12, 0x65, 0x02, 0x13, 0x24, 0x19, 0x00,
148 0x24, 0x39, 0x00, 0x96, 0x59, 0x08, 0x93, 0x85, 0x08, 0x97,
149 0x03, 0x50, 0x50, 0xaf, 0x40, 0x30, 0x5f, 0x01, 0xf1, 0x7f,
150 0x0d, 0xf2, 0x03, 0x11, 0xf1, 0x05, 0x37, 0x30, 0x85, 0x21, 0x50
151 },
152 // TGB_NTSC858
153 {
154 0x33, // size of table = 51
155 0x0c, 0xc0, 0x00, 0x00, 0x90, 0xc2, 0x03, 0x10, 0x03, 0x06,
156 0x10, 0x34, 0x12, 0x12, 0x65, 0x02, 0x13, 0x24, 0x19, 0x00,
157 0x24, 0x39, 0x00, 0x96, 0x59, 0x08, 0x93, 0x83, 0x08, 0x97,
158 0x03, 0x50, 0x30, 0xc0, 0x40, 0x30, 0x86, 0x01, 0x01, 0xa6,
159 0x0d, 0x62, 0x03, 0x11, 0x61, 0x05, 0x37, 0x30, 0xac, 0x21, 0x50
160 },
161 // TGB_NTSC392
162 // This table has been modified to be used for Fusion Rev D
163 {
164 0x2A, // size of table = 42
165 0x06, 0x08, 0x04, 0x0a, 0xc0, 0x00, 0x18, 0x08, 0x03, 0x24,
166 0x08, 0x07, 0x02, 0x90, 0x02, 0x08, 0x10, 0x04, 0x0c, 0x10,
167 0x05, 0x2c, 0x11, 0x04, 0x55, 0x48, 0x00, 0x05, 0x50, 0x00,
168 0xbf, 0x0c, 0x02, 0x2f, 0x3d, 0x00, 0x2f, 0x3f, 0x00, 0xc3,
169 0x20, 0x00
170 }
171};
172
173//===========================================================================
174// This is the structure of the camera specifications
175//===========================================================================
176typedef struct tag_cameraSpec
177{
178 SignalFormat signal; // which digital signal format the camera has
179 VideoFormat vidFormat; // video standard
180 SyncVideoRef syncRef; // which sync video reference is used
181 State syncOutput; // enable sync output for sync video input?
182 DecInputClk iClk; // which input clock is used
183 TimeGenByte tgb; // which timing generator byte does the camera use
184 int HReset; // select 64, 48, 32, or 16 CLKx1 for HReset
185 PLLFreq pllFreq; // what synthesized frequency to set PLL to
186 VSIZEPARMS vSize; // video size the camera produces
187 int lineCount; // expected total number of half-line per frame - 1
188 BOOL interlace; // interlace signal?
189} CameraSpec;
190
191//===========================================================================
192// <UPDATE REQUIRED>
193// Camera specifications database. Update this table whenever camera spec
194// has been changed or added/deleted supported camera models
195//===========================================================================
196static CameraSpec dbCameraSpec[ N_CAMERAOPTIONS ] =
197{ // Silicon Vision 512N
198 { Signal_CCIR656, VFormat_NTSC, VRef_alignedCb, Off, DecClk_GPCLK, TGB_NTSC624, 64, KHz19636,
199 // Clkx1_HACTIVE, Clkx1_HDELAY, VActive, VDelay, linesPerField; lineCount, Interlace
200 { 512, 0x64, 480, 0x13, 240 }, 0, TRUE
201 },
202 // Logitech VideoMan 1.3
203 { Signal_CCIR656, VFormat_NTSC, VRef_alignedCb, Off, DecClk_GPCLK, TGB_NTSC780, 64, KHz24545,
204 // Clkx1_HACTIVE, Clkx1_HDELAY, VActive, VDelay, linesPerField; lineCount, Interlace
205 { 640, 0x80, 480, 0x1A, 240 }, 0, TRUE
206 },
207 // Rockwell QuartzSight
208 // Note: Fusion Rev D (rev ID 0x02) and later supports 16 pixels for HReset which is preferable.
209 // Use 32 for earlier version of hardware. Clkx1_HDELAY also changed from 0x27 to 0x20.
210 { Signal_CCIR656, VFormat_NTSC, VRef_alignedCb, Off, DecClk_GPCLK, TGB_NTSC392, 16, KHz28636,
211 // Clkx1_HACTIVE, Clkx1_HDELAY, VActive, VDelay, linesPerField; lineCount, Interlace
212 { 352, 0x20, 576, 0x08, 288 }, 607, FALSE
213 }
214};
215*/
216
217/*
218The corresponding APIs required to be invoked are:
219SetConnector( ConCamera, TRUE/FALSE );
220SetSignalFormat( spec.signal );
221SetVideoFormat( spec.vidFormat );
222SetSyncVideoRef( spec.syncRef );
223SetEnableSyncOutput( spec.syncOutput );
224SetTimGenByte( SRAMTable[ spec.tgb ], SRAMTableSize[ spec.tgb ] );
225SetHReset( spec.HReset );
226SetPLL( spec.pllFreq );
227SetDecInputClock( spec.iClk );
228SetVideoInfo( spec.vSize );
229SetTotalLineCount( spec.lineCount );
230SetInterlaceMode( spec.interlace );
231*/
232
233/* from web:
234 Video Sampling
235Digital video is a sampled form of analog video. The most common sampling schemes in use today are:
236 Pixel Clock Horiz Horiz Vert
237 Rate Total Active
238NTSC square pixel 12.27 MHz 780 640 525
239NTSC CCIR-601 13.5 MHz 858 720 525
240NTSC 4FSc 14.32 MHz 910 768 525
241PAL square pixel 14.75 MHz 944 768 625
242PAL CCIR-601 13.5 MHz 864 720 625
243PAL 4FSc 17.72 MHz 1135 948 625
244
245For the CCIR-601 standards, the sampling is based on a static orthogonal sampling grid. The luminance component (Y) is sampled at 13.5 MHz, while the two color difference signals, Cr and Cb are sampled at half that, or 6.75 MHz. The Cr and Cb samples are colocated with alternate Y samples, and they are taken at the same position on each line, such that one sample is coincident with the 50% point of the falling edge of analog sync. The samples are coded to either 8 or 10 bits per component.
246*/
247
248/* from DScaler:*/
249/*
250//===========================================================================
251// CCIR656 Digital Input Support: The tables were taken from DScaler proyect
252//
253// 13 Dec 2000 - Michael Eskin, Conexant Systems - Initial version
254//
255
256//===========================================================================
257// Timing generator SRAM table values for CCIR601 720x480 NTSC
258//===========================================================================
259// For NTSC CCIR656
260BYTE BtCard::SRAMTable_NTSC[] =
261{
262 // SRAM Timing Table for NTSC
263 0x0c, 0xc0, 0x00,
264 0x00, 0x90, 0xc2,
265 0x03, 0x10, 0x03,
266 0x06, 0x10, 0x34,
267 0x12, 0x12, 0x65,
268 0x02, 0x13, 0x24,
269 0x19, 0x00, 0x24,
270 0x39, 0x00, 0x96,
271 0x59, 0x08, 0x93,
272 0x83, 0x08, 0x97,
273 0x03, 0x50, 0x30,
274 0xc0, 0x40, 0x30,
275 0x86, 0x01, 0x01,
276 0xa6, 0x0d, 0x62,
277 0x03, 0x11, 0x61,
278 0x05, 0x37, 0x30,
279 0xac, 0x21, 0x50
280};
281
282//===========================================================================
283// Timing generator SRAM table values for CCIR601 720x576 NTSC
284//===========================================================================
285// For PAL CCIR656
286BYTE BtCard::SRAMTable_PAL[] =
287{
288 // SRAM Timing Table for PAL
289 0x36, 0x11, 0x01,
290 0x00, 0x90, 0x02,
291 0x05, 0x10, 0x04,
292 0x16, 0x14, 0x05,
293 0x11, 0x00, 0x04,
294 0x12, 0xc0, 0x00,
295 0x31, 0x00, 0x06,
296 0x51, 0x08, 0x03,
297 0x89, 0x08, 0x07,
298 0xc0, 0x44, 0x00,
299 0x81, 0x01, 0x01,
300 0xa9, 0x0d, 0x02,
301 0x02, 0x50, 0x03,
302 0x37, 0x3d, 0x00,
303 0xaf, 0x21, 0x00,
304};
305*/
diff --git a/drivers/media/video/bt8xx/bt848.h b/drivers/media/video/bt8xx/bt848.h
new file mode 100644
index 000000000000..0bcd95303bb0
--- /dev/null
+++ b/drivers/media/video/bt8xx/bt848.h
@@ -0,0 +1,366 @@
1/*
2 bt848.h - Bt848 register offsets
3
4 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef _BT848_H_
22#define _BT848_H_
23
24#ifndef PCI_VENDOR_ID_BROOKTREE
25#define PCI_VENDOR_ID_BROOKTREE 0x109e
26#endif
27#ifndef PCI_DEVICE_ID_BT848
28#define PCI_DEVICE_ID_BT848 0x350
29#endif
30#ifndef PCI_DEVICE_ID_BT849
31#define PCI_DEVICE_ID_BT849 0x351
32#endif
33#ifndef PCI_DEVICE_ID_BT878
34#define PCI_DEVICE_ID_BT878 0x36e
35#endif
36#ifndef PCI_DEVICE_ID_BT879
37#define PCI_DEVICE_ID_BT879 0x36f
38#endif
39
40
41/* Brooktree 848 registers */
42
43#define BT848_DSTATUS 0x000
44#define BT848_DSTATUS_PRES (1<<7)
45#define BT848_DSTATUS_HLOC (1<<6)
46#define BT848_DSTATUS_FIELD (1<<5)
47#define BT848_DSTATUS_NUML (1<<4)
48#define BT848_DSTATUS_CSEL (1<<3)
49#define BT848_DSTATUS_PLOCK (1<<2)
50#define BT848_DSTATUS_LOF (1<<1)
51#define BT848_DSTATUS_COF (1<<0)
52
53#define BT848_IFORM 0x004
54#define BT848_IFORM_HACTIVE (1<<7)
55#define BT848_IFORM_MUXSEL (3<<5)
56#define BT848_IFORM_MUX0 (2<<5)
57#define BT848_IFORM_MUX1 (3<<5)
58#define BT848_IFORM_MUX2 (1<<5)
59#define BT848_IFORM_XTSEL (3<<3)
60#define BT848_IFORM_XT0 (1<<3)
61#define BT848_IFORM_XT1 (2<<3)
62#define BT848_IFORM_XTAUTO (3<<3)
63#define BT848_IFORM_XTBOTH (3<<3)
64#define BT848_IFORM_NTSC 1
65#define BT848_IFORM_NTSC_J 2
66#define BT848_IFORM_PAL_BDGHI 3
67#define BT848_IFORM_PAL_M 4
68#define BT848_IFORM_PAL_N 5
69#define BT848_IFORM_SECAM 6
70#define BT848_IFORM_PAL_NC 7
71#define BT848_IFORM_AUTO 0
72#define BT848_IFORM_NORM 7
73
74#define BT848_TDEC 0x008
75#define BT848_TDEC_DEC_FIELD (1<<7)
76#define BT848_TDEC_FLDALIGN (1<<6)
77#define BT848_TDEC_DEC_RAT (0x1f)
78
79#define BT848_E_CROP 0x00C
80#define BT848_O_CROP 0x08C
81
82#define BT848_E_VDELAY_LO 0x010
83#define BT848_O_VDELAY_LO 0x090
84
85#define BT848_E_VACTIVE_LO 0x014
86#define BT848_O_VACTIVE_LO 0x094
87
88#define BT848_E_HDELAY_LO 0x018
89#define BT848_O_HDELAY_LO 0x098
90
91#define BT848_E_HACTIVE_LO 0x01C
92#define BT848_O_HACTIVE_LO 0x09C
93
94#define BT848_E_HSCALE_HI 0x020
95#define BT848_O_HSCALE_HI 0x0A0
96
97#define BT848_E_HSCALE_LO 0x024
98#define BT848_O_HSCALE_LO 0x0A4
99
100#define BT848_BRIGHT 0x028
101
102#define BT848_E_CONTROL 0x02C
103#define BT848_O_CONTROL 0x0AC
104#define BT848_CONTROL_LNOTCH (1<<7)
105#define BT848_CONTROL_COMP (1<<6)
106#define BT848_CONTROL_LDEC (1<<5)
107#define BT848_CONTROL_CBSENSE (1<<4)
108#define BT848_CONTROL_CON_MSB (1<<2)
109#define BT848_CONTROL_SAT_U_MSB (1<<1)
110#define BT848_CONTROL_SAT_V_MSB (1<<0)
111
112#define BT848_CONTRAST_LO 0x030
113#define BT848_SAT_U_LO 0x034
114#define BT848_SAT_V_LO 0x038
115#define BT848_HUE 0x03C
116
117#define BT848_E_SCLOOP 0x040
118#define BT848_O_SCLOOP 0x0C0
119#define BT848_SCLOOP_CAGC (1<<6)
120#define BT848_SCLOOP_CKILL (1<<5)
121#define BT848_SCLOOP_HFILT_AUTO (0<<3)
122#define BT848_SCLOOP_HFILT_CIF (1<<3)
123#define BT848_SCLOOP_HFILT_QCIF (2<<3)
124#define BT848_SCLOOP_HFILT_ICON (3<<3)
125
126#define BT848_SCLOOP_PEAK (1<<7)
127#define BT848_SCLOOP_HFILT_MINP (1<<3)
128#define BT848_SCLOOP_HFILT_MEDP (2<<3)
129#define BT848_SCLOOP_HFILT_MAXP (3<<3)
130
131
132#define BT848_OFORM 0x048
133#define BT848_OFORM_RANGE (1<<7)
134#define BT848_OFORM_CORE0 (0<<5)
135#define BT848_OFORM_CORE8 (1<<5)
136#define BT848_OFORM_CORE16 (2<<5)
137#define BT848_OFORM_CORE32 (3<<5)
138
139#define BT848_E_VSCALE_HI 0x04C
140#define BT848_O_VSCALE_HI 0x0CC
141#define BT848_VSCALE_YCOMB (1<<7)
142#define BT848_VSCALE_COMB (1<<6)
143#define BT848_VSCALE_INT (1<<5)
144#define BT848_VSCALE_HI 15
145
146#define BT848_E_VSCALE_LO 0x050
147#define BT848_O_VSCALE_LO 0x0D0
148#define BT848_TEST 0x054
149#define BT848_ADELAY 0x060
150#define BT848_BDELAY 0x064
151
152#define BT848_ADC 0x068
153#define BT848_ADC_RESERVED (2<<6)
154#define BT848_ADC_SYNC_T (1<<5)
155#define BT848_ADC_AGC_EN (1<<4)
156#define BT848_ADC_CLK_SLEEP (1<<3)
157#define BT848_ADC_Y_SLEEP (1<<2)
158#define BT848_ADC_C_SLEEP (1<<1)
159#define BT848_ADC_CRUSH (1<<0)
160
161#define BT848_WC_UP 0x044
162#define BT848_WC_DOWN 0x078
163
164#define BT848_E_VTC 0x06C
165#define BT848_O_VTC 0x0EC
166#define BT848_VTC_HSFMT (1<<7)
167#define BT848_VTC_VFILT_2TAP 0
168#define BT848_VTC_VFILT_3TAP 1
169#define BT848_VTC_VFILT_4TAP 2
170#define BT848_VTC_VFILT_5TAP 3
171
172#define BT848_SRESET 0x07C
173
174#define BT848_COLOR_FMT 0x0D4
175#define BT848_COLOR_FMT_O_RGB32 (0<<4)
176#define BT848_COLOR_FMT_O_RGB24 (1<<4)
177#define BT848_COLOR_FMT_O_RGB16 (2<<4)
178#define BT848_COLOR_FMT_O_RGB15 (3<<4)
179#define BT848_COLOR_FMT_O_YUY2 (4<<4)
180#define BT848_COLOR_FMT_O_BtYUV (5<<4)
181#define BT848_COLOR_FMT_O_Y8 (6<<4)
182#define BT848_COLOR_FMT_O_RGB8 (7<<4)
183#define BT848_COLOR_FMT_O_YCrCb422 (8<<4)
184#define BT848_COLOR_FMT_O_YCrCb411 (9<<4)
185#define BT848_COLOR_FMT_O_RAW (14<<4)
186#define BT848_COLOR_FMT_E_RGB32 0
187#define BT848_COLOR_FMT_E_RGB24 1
188#define BT848_COLOR_FMT_E_RGB16 2
189#define BT848_COLOR_FMT_E_RGB15 3
190#define BT848_COLOR_FMT_E_YUY2 4
191#define BT848_COLOR_FMT_E_BtYUV 5
192#define BT848_COLOR_FMT_E_Y8 6
193#define BT848_COLOR_FMT_E_RGB8 7
194#define BT848_COLOR_FMT_E_YCrCb422 8
195#define BT848_COLOR_FMT_E_YCrCb411 9
196#define BT848_COLOR_FMT_E_RAW 14
197
198#define BT848_COLOR_FMT_RGB32 0x00
199#define BT848_COLOR_FMT_RGB24 0x11
200#define BT848_COLOR_FMT_RGB16 0x22
201#define BT848_COLOR_FMT_RGB15 0x33
202#define BT848_COLOR_FMT_YUY2 0x44
203#define BT848_COLOR_FMT_BtYUV 0x55
204#define BT848_COLOR_FMT_Y8 0x66
205#define BT848_COLOR_FMT_RGB8 0x77
206#define BT848_COLOR_FMT_YCrCb422 0x88
207#define BT848_COLOR_FMT_YCrCb411 0x99
208#define BT848_COLOR_FMT_RAW 0xee
209
210#define BT848_VTOTAL_LO 0xB0
211#define BT848_VTOTAL_HI 0xB4
212
213#define BT848_COLOR_CTL 0x0D8
214#define BT848_COLOR_CTL_EXT_FRMRATE (1<<7)
215#define BT848_COLOR_CTL_COLOR_BARS (1<<6)
216#define BT848_COLOR_CTL_RGB_DED (1<<5)
217#define BT848_COLOR_CTL_GAMMA (1<<4)
218#define BT848_COLOR_CTL_WSWAP_ODD (1<<3)
219#define BT848_COLOR_CTL_WSWAP_EVEN (1<<2)
220#define BT848_COLOR_CTL_BSWAP_ODD (1<<1)
221#define BT848_COLOR_CTL_BSWAP_EVEN (1<<0)
222
223#define BT848_CAP_CTL 0x0DC
224#define BT848_CAP_CTL_DITH_FRAME (1<<4)
225#define BT848_CAP_CTL_CAPTURE_VBI_ODD (1<<3)
226#define BT848_CAP_CTL_CAPTURE_VBI_EVEN (1<<2)
227#define BT848_CAP_CTL_CAPTURE_ODD (1<<1)
228#define BT848_CAP_CTL_CAPTURE_EVEN (1<<0)
229
230#define BT848_VBI_PACK_SIZE 0x0E0
231
232#define BT848_VBI_PACK_DEL 0x0E4
233#define BT848_VBI_PACK_DEL_VBI_HDELAY 0xfc
234#define BT848_VBI_PACK_DEL_EXT_FRAME 2
235#define BT848_VBI_PACK_DEL_VBI_PKT_HI 1
236
237
238#define BT848_INT_STAT 0x100
239#define BT848_INT_MASK 0x104
240
241#define BT848_INT_ETBF (1<<23)
242
243#define BT848_INT_RISCS (0xf<<28)
244#define BT848_INT_RISC_EN (1<<27)
245#define BT848_INT_RACK (1<<25)
246#define BT848_INT_FIELD (1<<24)
247#define BT848_INT_SCERR (1<<19)
248#define BT848_INT_OCERR (1<<18)
249#define BT848_INT_PABORT (1<<17)
250#define BT848_INT_RIPERR (1<<16)
251#define BT848_INT_PPERR (1<<15)
252#define BT848_INT_FDSR (1<<14)
253#define BT848_INT_FTRGT (1<<13)
254#define BT848_INT_FBUS (1<<12)
255#define BT848_INT_RISCI (1<<11)
256#define BT848_INT_GPINT (1<<9)
257#define BT848_INT_I2CDONE (1<<8)
258#define BT848_INT_VPRES (1<<5)
259#define BT848_INT_HLOCK (1<<4)
260#define BT848_INT_OFLOW (1<<3)
261#define BT848_INT_HSYNC (1<<2)
262#define BT848_INT_VSYNC (1<<1)
263#define BT848_INT_FMTCHG (1<<0)
264
265
266#define BT848_GPIO_DMA_CTL 0x10C
267#define BT848_GPIO_DMA_CTL_GPINTC (1<<15)
268#define BT848_GPIO_DMA_CTL_GPINTI (1<<14)
269#define BT848_GPIO_DMA_CTL_GPWEC (1<<13)
270#define BT848_GPIO_DMA_CTL_GPIOMODE (3<<11)
271#define BT848_GPIO_DMA_CTL_GPCLKMODE (1<<10)
272#define BT848_GPIO_DMA_CTL_PLTP23_4 (0<<6)
273#define BT848_GPIO_DMA_CTL_PLTP23_8 (1<<6)
274#define BT848_GPIO_DMA_CTL_PLTP23_16 (2<<6)
275#define BT848_GPIO_DMA_CTL_PLTP23_32 (3<<6)
276#define BT848_GPIO_DMA_CTL_PLTP1_4 (0<<4)
277#define BT848_GPIO_DMA_CTL_PLTP1_8 (1<<4)
278#define BT848_GPIO_DMA_CTL_PLTP1_16 (2<<4)
279#define BT848_GPIO_DMA_CTL_PLTP1_32 (3<<4)
280#define BT848_GPIO_DMA_CTL_PKTP_4 (0<<2)
281#define BT848_GPIO_DMA_CTL_PKTP_8 (1<<2)
282#define BT848_GPIO_DMA_CTL_PKTP_16 (2<<2)
283#define BT848_GPIO_DMA_CTL_PKTP_32 (3<<2)
284#define BT848_GPIO_DMA_CTL_RISC_ENABLE (1<<1)
285#define BT848_GPIO_DMA_CTL_FIFO_ENABLE (1<<0)
286
287#define BT848_I2C 0x110
288#define BT878_I2C_MODE (1<<7)
289#define BT878_I2C_RATE (1<<6)
290#define BT878_I2C_NOSTOP (1<<5)
291#define BT878_I2C_NOSTART (1<<4)
292#define BT848_I2C_DIV (0xf<<4)
293#define BT848_I2C_SYNC (1<<3)
294#define BT848_I2C_W3B (1<<2)
295#define BT848_I2C_SCL (1<<1)
296#define BT848_I2C_SDA (1<<0)
297
298#define BT848_RISC_STRT_ADD 0x114
299#define BT848_GPIO_OUT_EN 0x118
300#define BT848_GPIO_REG_INP 0x11C
301#define BT848_RISC_COUNT 0x120
302#define BT848_GPIO_DATA 0x200
303
304
305/* Bt848 RISC commands */
306
307/* only for the SYNC RISC command */
308#define BT848_FIFO_STATUS_FM1 0x06
309#define BT848_FIFO_STATUS_FM3 0x0e
310#define BT848_FIFO_STATUS_SOL 0x02
311#define BT848_FIFO_STATUS_EOL4 0x01
312#define BT848_FIFO_STATUS_EOL3 0x0d
313#define BT848_FIFO_STATUS_EOL2 0x09
314#define BT848_FIFO_STATUS_EOL1 0x05
315#define BT848_FIFO_STATUS_VRE 0x04
316#define BT848_FIFO_STATUS_VRO 0x0c
317#define BT848_FIFO_STATUS_PXV 0x00
318
319#define BT848_RISC_RESYNC (1<<15)
320
321/* WRITE and SKIP */
322/* disable which bytes of each DWORD */
323#define BT848_RISC_BYTE0 (1U<<12)
324#define BT848_RISC_BYTE1 (1U<<13)
325#define BT848_RISC_BYTE2 (1U<<14)
326#define BT848_RISC_BYTE3 (1U<<15)
327#define BT848_RISC_BYTE_ALL (0x0fU<<12)
328#define BT848_RISC_BYTE_NONE 0
329/* cause RISCI */
330#define BT848_RISC_IRQ (1U<<24)
331/* RISC command is last one in this line */
332#define BT848_RISC_EOL (1U<<26)
333/* RISC command is first one in this line */
334#define BT848_RISC_SOL (1U<<27)
335
336#define BT848_RISC_WRITE (0x01U<<28)
337#define BT848_RISC_SKIP (0x02U<<28)
338#define BT848_RISC_WRITEC (0x05U<<28)
339#define BT848_RISC_JUMP (0x07U<<28)
340#define BT848_RISC_SYNC (0x08U<<28)
341
342#define BT848_RISC_WRITE123 (0x09U<<28)
343#define BT848_RISC_SKIP123 (0x0aU<<28)
344#define BT848_RISC_WRITE1S23 (0x0bU<<28)
345
346
347/* Bt848A and higher only !! */
348#define BT848_TGLB 0x080
349#define BT848_TGCTRL 0x084
350#define BT848_FCAP 0x0E8
351#define BT848_PLL_F_LO 0x0F0
352#define BT848_PLL_F_HI 0x0F4
353
354#define BT848_PLL_XCI 0x0F8
355#define BT848_PLL_X (1<<7)
356#define BT848_PLL_C (1<<6)
357
358#define BT848_DVSIF 0x0FC
359
360/* Bt878 register */
361
362#define BT878_DEVCTRL 0x40
363#define BT878_EN_TBFX 0x02
364#define BT878_EN_VSFX 0x04
365
366#endif
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
new file mode 100644
index 000000000000..f209a7492051
--- /dev/null
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -0,0 +1,5078 @@
1/*
2
3 bttv-cards.c
4
5 this file has configuration informations - card-specific stuff
6 like the big tvcards array for the most part
7
8 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
9 & Marcus Metzler (mocm@thp.uni-koeln.de)
10 (c) 1999-2001 Gerd Knorr <kraxel@goldbach.in-berlin.de>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25
26*/
27
28#include <linux/config.h>
29#include <linux/delay.h>
30#include <linux/module.h>
31#include <linux/moduleparam.h>
32#include <linux/kmod.h>
33#include <linux/init.h>
34#include <linux/pci.h>
35#include <linux/vmalloc.h>
36#include <linux/firmware.h>
37
38#include <asm/io.h>
39
40#include "bttvp.h"
41#include <media/v4l2-common.h>
42#include <media/tvaudio.h>
43
44/* fwd decl */
45static void boot_msp34xx(struct bttv *btv, int pin);
46static void boot_bt832(struct bttv *btv);
47static void hauppauge_eeprom(struct bttv *btv);
48static void avermedia_eeprom(struct bttv *btv);
49static void osprey_eeprom(struct bttv *btv);
50static void modtec_eeprom(struct bttv *btv);
51static void init_PXC200(struct bttv *btv);
52static void init_RTV24(struct bttv *btv);
53
54static void winview_audio(struct bttv *btv, struct video_audio *v, int set);
55static void lt9415_audio(struct bttv *btv, struct video_audio *v, int set);
56static void avermedia_tvphone_audio(struct bttv *btv, struct video_audio *v,
57 int set);
58static void avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v,
59 int set);
60static void terratv_audio(struct bttv *btv, struct video_audio *v, int set);
61static void gvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set);
62static void gvbctv5pci_audio(struct bttv *btv, struct video_audio *v, int set);
63static void winfast2000_audio(struct bttv *btv, struct video_audio *v, int set);
64static void pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set);
65static void fv2000s_audio(struct bttv *btv, struct video_audio *v, int set);
66static void windvr_audio(struct bttv *btv, struct video_audio *v, int set);
67static void adtvk503_audio(struct bttv *btv, struct video_audio *v, int set);
68static void rv605_muxsel(struct bttv *btv, unsigned int input);
69static void eagle_muxsel(struct bttv *btv, unsigned int input);
70static void xguard_muxsel(struct bttv *btv, unsigned int input);
71static void ivc120_muxsel(struct bttv *btv, unsigned int input);
72static void gvc1100_muxsel(struct bttv *btv, unsigned int input);
73
74static void PXC200_muxsel(struct bttv *btv, unsigned int input);
75
76static void picolo_tetra_muxsel(struct bttv *btv, unsigned int input);
77static void picolo_tetra_init(struct bttv *btv);
78
79static void tibetCS16_muxsel(struct bttv *btv, unsigned int input);
80static void tibetCS16_init(struct bttv *btv);
81
82static void kodicom4400r_muxsel(struct bttv *btv, unsigned int input);
83static void kodicom4400r_init(struct bttv *btv);
84
85static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input);
86static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input);
87
88static int terratec_active_radio_upgrade(struct bttv *btv);
89static int tea5757_read(struct bttv *btv);
90static int tea5757_write(struct bttv *btv, int value);
91static void identify_by_eeprom(struct bttv *btv,
92 unsigned char eeprom_data[256]);
93static int __devinit pvr_boot(struct bttv *btv);
94
95/* config variables */
96static unsigned int triton1;
97static unsigned int vsfx;
98static unsigned int latency = UNSET;
99int no_overlay=-1;
100
101static unsigned int card[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
102static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
103static unsigned int tuner[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
104static unsigned int svhs[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
105static unsigned int remote[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
106static struct bttv *master[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = NULL };
107#ifdef MODULE
108static unsigned int autoload = 1;
109#else
110static unsigned int autoload;
111#endif
112static unsigned int gpiomask = UNSET;
113static unsigned int audioall = UNSET;
114static unsigned int audiomux[5] = { [ 0 ... 4 ] = UNSET };
115
116/* insmod options */
117module_param(triton1, int, 0444);
118module_param(vsfx, int, 0444);
119module_param(no_overlay, int, 0444);
120module_param(latency, int, 0444);
121module_param(gpiomask, int, 0444);
122module_param(audioall, int, 0444);
123module_param(autoload, int, 0444);
124
125module_param_array(card, int, NULL, 0444);
126module_param_array(pll, int, NULL, 0444);
127module_param_array(tuner, int, NULL, 0444);
128module_param_array(svhs, int, NULL, 0444);
129module_param_array(remote, int, NULL, 0444);
130module_param_array(audiomux, int, NULL, 0444);
131
132MODULE_PARM_DESC(triton1,"set ETBF pci config bit "
133 "[enable bug compatibility for triton1 + others]");
134MODULE_PARM_DESC(vsfx,"set VSFX pci config bit "
135 "[yet another chipset flaw workaround]");
136MODULE_PARM_DESC(latency,"pci latency timer");
137MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list");
138MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)");
139MODULE_PARM_DESC(tuner,"specify installed tuner type");
140MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default is 1 (yes)");
141MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)"
142 " [some VIA/SIS chipsets are known to have problem with overlay]");
143
144/* ----------------------------------------------------------------------- */
145/* list of card IDs for bt878+ cards */
146
147static struct CARD {
148 unsigned id;
149 int cardnr;
150 char *name;
151} cards[] __devinitdata = {
152 { 0x13eb0070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV" },
153 { 0x39000070, BTTV_BOARD_HAUPPAUGE878, "Hauppauge WinTV-D" },
154 { 0x45000070, BTTV_BOARD_HAUPPAUGEPVR, "Hauppauge WinTV/PVR" },
155 { 0xff000070, BTTV_BOARD_OSPREY1x0, "Osprey-100" },
156 { 0xff010070, BTTV_BOARD_OSPREY2x0_SVID,"Osprey-200" },
157 { 0xff020070, BTTV_BOARD_OSPREY500, "Osprey-500" },
158 { 0xff030070, BTTV_BOARD_OSPREY2000, "Osprey-2000" },
159 { 0xff040070, BTTV_BOARD_OSPREY540, "Osprey-540" },
160 { 0xff070070, BTTV_BOARD_OSPREY440, "Osprey-440" },
161
162 { 0x00011002, BTTV_BOARD_ATI_TVWONDER, "ATI TV Wonder" },
163 { 0x00031002, BTTV_BOARD_ATI_TVWONDERVE,"ATI TV Wonder/VE" },
164
165 { 0x6606107d, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
166 { 0x6607107d, BTTV_BOARD_WINFASTVC100, "Leadtek WinFast VC 100" },
167 { 0x6609107d, BTTV_BOARD_WINFAST2000, "Leadtek TV 2000 XP" },
168 { 0x263610b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
169 { 0x264510b4, BTTV_BOARD_STB2, "STB TV PCI FM, Gateway P/N 6000704" },
170 { 0x402010fc, BTTV_BOARD_GVBCTV3PCI, "I-O Data Co. GV-BCTV3/PCI" },
171 { 0x405010fc, BTTV_BOARD_GVBCTV4PCI, "I-O Data Co. GV-BCTV4/PCI" },
172 { 0x407010fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
173 { 0xd01810fc, BTTV_BOARD_GVBCTV5PCI, "I-O Data Co. GV-BCTV5/PCI" },
174
175 { 0x001211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" },
176 /* some cards ship with byteswapped IDs ... */
177 { 0x1200bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" },
178 { 0xff00bd11, BTTV_BOARD_PINNACLE, "Pinnacle PCTV [bswap]" },
179 /* this seems to happen as well ... */
180 { 0xff1211bd, BTTV_BOARD_PINNACLE, "Pinnacle PCTV" },
181
182 { 0x3000121a, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
183 { 0x263710b4, BTTV_BOARD_VOODOOTV_FM, "3Dfx VoodooTV FM/ VoodooTV 200" },
184 { 0x3060121a, BTTV_BOARD_STB2, "3Dfx VoodooTV 100/ STB OEM" },
185
186 { 0x3000144f, BTTV_BOARD_MAGICTVIEW063, "(Askey Magic/others) TView99 CPH06x" },
187 { 0xa005144f, BTTV_BOARD_MAGICTVIEW063, "CPH06X TView99-Card" },
188 { 0x3002144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH05x" },
189 { 0x3005144f, BTTV_BOARD_MAGICTVIEW061, "(Askey Magic/others) TView99 CPH061/06L (T1/LC)" },
190 { 0x5000144f, BTTV_BOARD_MAGICTVIEW061, "Askey CPH050" },
191 { 0x300014ff, BTTV_BOARD_MAGICTVIEW061, "TView 99 (CPH061)" },
192 { 0x300214ff, BTTV_BOARD_PHOEBE_TVMAS, "Phoebe TV Master (CPH060)" },
193
194 { 0x00011461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" },
195 { 0x00021461, BTTV_BOARD_AVERMEDIA98, "AVermedia TVCapture 98" },
196 { 0x00031461, BTTV_BOARD_AVPHONE98, "AVerMedia TVPhone98" },
197 { 0x00041461, BTTV_BOARD_AVERMEDIA98, "AVerMedia TVCapture 98" },
198 { 0x03001461, BTTV_BOARD_AVERMEDIA98, "VDOMATE TV TUNER CARD" },
199
200 { 0x1117153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL B/G)" },
201 { 0x1118153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL B/G)" },
202 { 0x1119153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Philips PAL I)" },
203 { 0x111a153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (Temic PAL I)" },
204
205 { 0x1123153b, BTTV_BOARD_TERRATVRADIO, "Terratec TV Radio+" },
206 { 0x1127153b, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.05)" },
207 /* clashes with FlyVideo
208 *{ 0x18521852, BTTV_BOARD_TERRATV, "Terratec TV+ (V1.10)" }, */
209 { 0x1134153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue (LR102)" },
210 { 0x1135153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* LR102 */
211 { 0x5018153b, BTTV_BOARD_TERRATVALUE, "Terratec TValue" }, /* ?? */
212 { 0xff3b153b, BTTV_BOARD_TERRATVALUER, "Terratec TValue Radio" }, /* ?? */
213
214 { 0x400015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
215 { 0x400a15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV" },
216 { 0x400d15b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
217 { 0x401015b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
218 { 0x401615b0, BTTV_BOARD_ZOLTRIX_GENIE, "Zoltrix Genie TV / Radio" },
219
220 { 0x1430aa00, BTTV_BOARD_PV143, "Provideo PV143A" },
221 { 0x1431aa00, BTTV_BOARD_PV143, "Provideo PV143B" },
222 { 0x1432aa00, BTTV_BOARD_PV143, "Provideo PV143C" },
223 { 0x1433aa00, BTTV_BOARD_PV143, "Provideo PV143D" },
224 { 0x1433aa03, BTTV_BOARD_PV143, "Security Eyes" },
225
226 { 0x1460aa00, BTTV_BOARD_PV150, "Provideo PV150A-1" },
227 { 0x1461aa01, BTTV_BOARD_PV150, "Provideo PV150A-2" },
228 { 0x1462aa02, BTTV_BOARD_PV150, "Provideo PV150A-3" },
229 { 0x1463aa03, BTTV_BOARD_PV150, "Provideo PV150A-4" },
230
231 { 0x1464aa04, BTTV_BOARD_PV150, "Provideo PV150B-1" },
232 { 0x1465aa05, BTTV_BOARD_PV150, "Provideo PV150B-2" },
233 { 0x1466aa06, BTTV_BOARD_PV150, "Provideo PV150B-3" },
234 { 0x1467aa07, BTTV_BOARD_PV150, "Provideo PV150B-4" },
235
236 { 0xa132ff00, BTTV_BOARD_IVC100, "IVC-100" },
237 { 0xa1550000, BTTV_BOARD_IVC200, "IVC-200" },
238 { 0xa1550001, BTTV_BOARD_IVC200, "IVC-200" },
239 { 0xa1550002, BTTV_BOARD_IVC200, "IVC-200" },
240 { 0xa1550003, BTTV_BOARD_IVC200, "IVC-200" },
241 { 0xa1550100, BTTV_BOARD_IVC200, "IVC-200G" },
242 { 0xa1550101, BTTV_BOARD_IVC200, "IVC-200G" },
243 { 0xa1550102, BTTV_BOARD_IVC200, "IVC-200G" },
244 { 0xa1550103, BTTV_BOARD_IVC200, "IVC-200G" },
245 { 0xa182ff00, BTTV_BOARD_IVC120, "IVC-120G" },
246 { 0xa182ff01, BTTV_BOARD_IVC120, "IVC-120G" },
247 { 0xa182ff02, BTTV_BOARD_IVC120, "IVC-120G" },
248 { 0xa182ff03, BTTV_BOARD_IVC120, "IVC-120G" },
249 { 0xa182ff04, BTTV_BOARD_IVC120, "IVC-120G" },
250 { 0xa182ff05, BTTV_BOARD_IVC120, "IVC-120G" },
251 { 0xa182ff06, BTTV_BOARD_IVC120, "IVC-120G" },
252 { 0xa182ff07, BTTV_BOARD_IVC120, "IVC-120G" },
253 { 0xa182ff08, BTTV_BOARD_IVC120, "IVC-120G" },
254 { 0xa182ff09, BTTV_BOARD_IVC120, "IVC-120G" },
255 { 0xa182ff0a, BTTV_BOARD_IVC120, "IVC-120G" },
256 { 0xa182ff0b, BTTV_BOARD_IVC120, "IVC-120G" },
257 { 0xa182ff0c, BTTV_BOARD_IVC120, "IVC-120G" },
258 { 0xa182ff0d, BTTV_BOARD_IVC120, "IVC-120G" },
259 { 0xa182ff0e, BTTV_BOARD_IVC120, "IVC-120G" },
260 { 0xa182ff0f, BTTV_BOARD_IVC120, "IVC-120G" },
261
262 { 0x41424344, BTTV_BOARD_GRANDTEC, "GrandTec Multi Capture" },
263 { 0x01020304, BTTV_BOARD_XGUARD, "Grandtec Grand X-Guard" },
264
265 { 0x18501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
266 { 0xa0501851, BTTV_BOARD_CHRONOS_VS2, "FlyVideo 98 (LR50)/ Chronos Video Shuttle II" },
267 { 0x18511851, BTTV_BOARD_FLYVIDEO98EZ, "FlyVideo 98EZ (LR51)/ CyberMail AV" },
268 { 0x18521852, BTTV_BOARD_TYPHOON_TVIEW, "FlyVideo 98FM (LR50)/ Typhoon TView TV/FM Tuner" },
269 { 0x41a0a051, BTTV_BOARD_FLYVIDEO_98FM, "Lifeview FlyVideo 98 LR50 Rev Q" },
270 { 0x18501f7f, BTTV_BOARD_FLYVIDEO_98, "Lifeview Flyvideo 98" },
271
272 { 0x010115cb, BTTV_BOARD_GMV1, "AG GMV1" },
273 { 0x010114c7, BTTV_BOARD_MODTEC_205, "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV" },
274
275 { 0x10b42636, BTTV_BOARD_HAUPPAUGE878, "STB ???" },
276 { 0x217d6606, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
277 { 0xfff6f6ff, BTTV_BOARD_WINFAST2000, "Leadtek WinFast TV 2000" },
278 { 0x03116000, BTTV_BOARD_SENSORAY311, "Sensoray 311" },
279 { 0x00790e11, BTTV_BOARD_WINDVR, "Canopus WinDVR PCI" },
280 { 0xa0fca1a0, BTTV_BOARD_ZOLTRIX, "Face to Face Tvmax" },
281 { 0x82b2aa6a, BTTV_BOARD_SIMUS_GVC1100, "SIMUS GVC1100" },
282 { 0x146caa0c, BTTV_BOARD_PV951, "ituner spectra8" },
283 { 0x200a1295, BTTV_BOARD_PXC200, "ImageNation PXC200A" },
284
285 { 0x40111554, BTTV_BOARD_PV_BT878P_9B, "Prolink Pixelview PV-BT" },
286 { 0x17de0a01, BTTV_BOARD_KWORLD, "Mecer TV/FM/Video Tuner" },
287
288 { 0x01051805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #1" },
289 { 0x01061805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #2" },
290 { 0x01071805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #3" },
291 { 0x01081805, BTTV_BOARD_PICOLO_TETRA_CHIP, "Picolo Tetra Chip #4" },
292
293 { 0x15409511, BTTV_BOARD_ACORP_Y878F, "Acorp Y878F" },
294
295 /* likely broken, vendor id doesn't match the other magic views ...
296 * { 0xa0fca04f, BTTV_BOARD_MAGICTVIEW063, "Guillemot Maxi TV Video 3" }, */
297
298 /* Duplicate PCI ID, reconfigure for this board during the eeprom read.
299 * { 0x13eb0070, BTTV_BOARD_HAUPPAUGE_IMPACTVCB, "Hauppauge ImpactVCB" }, */
300
301 /* DVB cards (using pci function .1 for mpeg data xfer) */
302 { 0x001c11bd, BTTV_BOARD_PINNACLESAT, "Pinnacle PCTV Sat" },
303 { 0x01010071, BTTV_BOARD_NEBULA_DIGITV, "Nebula Electronics DigiTV" },
304 { 0x20007063, BTTV_BOARD_PC_HDTV, "pcHDTV HD-2000 TV"},
305 { 0x002611bd, BTTV_BOARD_TWINHAN_DST, "Pinnacle PCTV SAT CI" },
306 { 0x00011822, BTTV_BOARD_TWINHAN_DST, "Twinhan VisionPlus DVB" },
307 { 0xfc00270f, BTTV_BOARD_TWINHAN_DST, "ChainTech digitop DST-1000 DVB-S" },
308 { 0x07711461, BTTV_BOARD_AVDVBT_771, "AVermedia AverTV DVB-T 771" },
309 { 0x07611461, BTTV_BOARD_AVDVBT_761, "AverMedia AverTV DVB-T 761" },
310 { 0xdb1018ac, BTTV_BOARD_DVICO_DVBT_LITE, "DViCO FusionHDTV DVB-T Lite" },
311 { 0xd50018ac, BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE, "DViCO FusionHDTV 5 Lite" },
312
313 { 0, -1, NULL }
314};
315
316/* ----------------------------------------------------------------------- */
317/* array with description for bt848 / bt878 tv/grabber cards */
318
319struct tvcard bttv_tvcards[] = {
320 /* ---- card 0x00 ---------------------------------- */
321 [BTTV_BOARD_UNKNOWN] = {
322 .name = " *** UNKNOWN/GENERIC *** ",
323 .video_inputs = 4,
324 .audio_inputs = 1,
325 .tuner = 0,
326 .svhs = 2,
327 .muxsel = { 2, 3, 1, 0 },
328 .tuner_type = -1,
329 .tuner_addr = ADDR_UNSET,
330 .radio_addr = ADDR_UNSET,
331 },
332 [BTTV_BOARD_MIRO] = {
333 .name = "MIRO PCTV",
334 .video_inputs = 4,
335 .audio_inputs = 1,
336 .tuner = 0,
337 .svhs = 2,
338 .gpiomask = 15,
339 .muxsel = { 2, 3, 1, 1 },
340 .gpiomux = { 2, 0, 0, 0 },
341 .gpiomute = 10,
342 .needs_tvaudio = 1,
343 .tuner_type = -1,
344 .tuner_addr = ADDR_UNSET,
345 .radio_addr = ADDR_UNSET,
346 },
347 [BTTV_BOARD_HAUPPAUGE] = {
348 .name = "Hauppauge (bt848)",
349 .video_inputs = 4,
350 .audio_inputs = 1,
351 .tuner = 0,
352 .svhs = 2,
353 .gpiomask = 7,
354 .muxsel = { 2, 3, 1, 1 },
355 .gpiomux = { 0, 1, 2, 3 },
356 .gpiomute = 4,
357 .needs_tvaudio = 1,
358 .tuner_type = -1,
359 .tuner_addr = ADDR_UNSET,
360 .radio_addr = ADDR_UNSET,
361 },
362 [BTTV_BOARD_STB] = {
363 .name = "STB, Gateway P/N 6000699 (bt848)",
364 .video_inputs = 3,
365 .audio_inputs = 1,
366 .tuner = 0,
367 .svhs = 2,
368 .gpiomask = 7,
369 .muxsel = { 2, 3, 1, 1 },
370 .gpiomux = { 4, 0, 2, 3 },
371 .gpiomute = 1,
372 .no_msp34xx = 1,
373 .needs_tvaudio = 1,
374 .tuner_type = TUNER_PHILIPS_NTSC,
375 .tuner_addr = ADDR_UNSET,
376 .radio_addr = ADDR_UNSET,
377 .pll = PLL_28,
378 .has_radio = 1,
379 },
380
381 /* ---- card 0x04 ---------------------------------- */
382 [BTTV_BOARD_INTEL] = {
383 .name = "Intel Create and Share PCI/ Smart Video Recorder III",
384 .video_inputs = 4,
385 .audio_inputs = 0,
386 .tuner = -1,
387 .svhs = 2,
388 .gpiomask = 0,
389 .muxsel = { 2, 3, 1, 1 },
390 .gpiomux = { 0 },
391 .needs_tvaudio = 0,
392 .tuner_type = 4,
393 .tuner_addr = ADDR_UNSET,
394 .radio_addr = ADDR_UNSET,
395 },
396 [BTTV_BOARD_DIAMOND] = {
397 .name = "Diamond DTV2000",
398 .video_inputs = 4,
399 .audio_inputs = 1,
400 .tuner = 0,
401 .svhs = 2,
402 .gpiomask = 3,
403 .muxsel = { 2, 3, 1, 0 },
404 .gpiomux = { 0, 1, 0, 1 },
405 .gpiomute = 3,
406 .needs_tvaudio = 1,
407 .tuner_type = -1,
408 .tuner_addr = ADDR_UNSET,
409 .radio_addr = ADDR_UNSET,
410 },
411 [BTTV_BOARD_AVERMEDIA] = {
412 .name = "AVerMedia TVPhone",
413 .video_inputs = 3,
414 .audio_inputs = 1,
415 .tuner = 0,
416 .svhs = 3,
417 .muxsel = { 2, 3, 1, 1 },
418 .gpiomask = 0x0f,
419 .gpiomux = { 0x0c, 0x04, 0x08, 0x04 },
420 /* 0x04 for some cards ?? */
421 .needs_tvaudio = 1,
422 .tuner_type = -1,
423 .tuner_addr = ADDR_UNSET,
424 .radio_addr = ADDR_UNSET,
425 .audio_hook = avermedia_tvphone_audio,
426 .has_remote = 1,
427 },
428 [BTTV_BOARD_MATRIX_VISION] = {
429 .name = "MATRIX-Vision MV-Delta",
430 .video_inputs = 5,
431 .audio_inputs = 1,
432 .tuner = -1,
433 .svhs = 3,
434 .gpiomask = 0,
435 .muxsel = { 2, 3, 1, 0, 0 },
436 .gpiomux = { 0 },
437 .needs_tvaudio = 1,
438 .tuner_type = -1,
439 .tuner_addr = ADDR_UNSET,
440 .radio_addr = ADDR_UNSET,
441 },
442
443 /* ---- card 0x08 ---------------------------------- */
444 [BTTV_BOARD_FLYVIDEO] = {
445 .name = "Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26",
446 .video_inputs = 4,
447 .audio_inputs = 1,
448 .tuner = 0,
449 .svhs = 2,
450 .gpiomask = 0xc00,
451 .muxsel = { 2, 3, 1, 1 },
452 .gpiomux = { 0, 0xc00, 0x800, 0x400 },
453 .gpiomute = 0xc00,
454 .needs_tvaudio = 1,
455 .pll = PLL_28,
456 .tuner_type = -1,
457 .tuner_addr = ADDR_UNSET,
458 .radio_addr = ADDR_UNSET,
459 },
460 [BTTV_BOARD_TURBOTV] = {
461 .name = "IMS/IXmicro TurboTV",
462 .video_inputs = 3,
463 .audio_inputs = 1,
464 .tuner = 0,
465 .svhs = 2,
466 .gpiomask = 3,
467 .muxsel = { 2, 3, 1, 1 },
468 .gpiomux = { 1, 1, 2, 3 },
469 .needs_tvaudio = 0,
470 .pll = PLL_28,
471 .tuner_type = TUNER_TEMIC_PAL,
472 .tuner_addr = ADDR_UNSET,
473 .radio_addr = ADDR_UNSET,
474 },
475 [BTTV_BOARD_HAUPPAUGE878] = {
476 .name = "Hauppauge (bt878)",
477 .video_inputs = 4,
478 .audio_inputs = 1,
479 .tuner = 0,
480 .svhs = 2,
481 .gpiomask = 0x0f, /* old: 7 */
482 .muxsel = { 2, 0, 1, 1 },
483 .gpiomux = { 0, 1, 2, 3 },
484 .gpiomute = 4,
485 .needs_tvaudio = 1,
486 .pll = PLL_28,
487 .tuner_type = -1,
488 .tuner_addr = ADDR_UNSET,
489 .radio_addr = ADDR_UNSET,
490 },
491 [BTTV_BOARD_MIROPRO] = {
492 .name = "MIRO PCTV pro",
493 .video_inputs = 3,
494 .audio_inputs = 1,
495 .tuner = 0,
496 .svhs = 2,
497 .gpiomask = 0x3014f,
498 .muxsel = { 2, 3, 1, 1 },
499 .gpiomux = { 0x20001,0x10001, 0, 0 },
500 .gpiomute = 10,
501 .needs_tvaudio = 1,
502 .tuner_type = -1,
503 .tuner_addr = ADDR_UNSET,
504 .radio_addr = ADDR_UNSET,
505 },
506
507 /* ---- card 0x0c ---------------------------------- */
508 [BTTV_BOARD_ADSTECH_TV] = {
509 .name = "ADS Technologies Channel Surfer TV (bt848)",
510 .video_inputs = 3,
511 .audio_inputs = 1,
512 .tuner = 0,
513 .svhs = 2,
514 .gpiomask = 15,
515 .muxsel = { 2, 3, 1, 1 },
516 .gpiomux = { 13, 14, 11, 7 },
517 .needs_tvaudio = 1,
518 .tuner_type = -1,
519 .tuner_addr = ADDR_UNSET,
520 .radio_addr = ADDR_UNSET,
521 },
522 [BTTV_BOARD_AVERMEDIA98] = {
523 .name = "AVerMedia TVCapture 98",
524 .video_inputs = 3,
525 .audio_inputs = 4,
526 .tuner = 0,
527 .svhs = 2,
528 .gpiomask = 15,
529 .muxsel = { 2, 3, 1, 1 },
530 .gpiomux = { 13, 14, 11, 7 },
531 .needs_tvaudio = 1,
532 .msp34xx_alt = 1,
533 .pll = PLL_28,
534 .tuner_type = TUNER_PHILIPS_PAL,
535 .tuner_addr = ADDR_UNSET,
536 .radio_addr = ADDR_UNSET,
537 .audio_hook = avermedia_tv_stereo_audio,
538 .no_gpioirq = 1,
539 },
540 [BTTV_BOARD_VHX] = {
541 .name = "Aimslab Video Highway Xtreme (VHX)",
542 .video_inputs = 3,
543 .audio_inputs = 1,
544 .tuner = 0,
545 .svhs = 2,
546 .gpiomask = 7,
547 .muxsel = { 2, 3, 1, 1 },
548 .gpiomux = { 0, 2, 1, 3 }, /* old: {0, 1, 2, 3, 4} */
549 .gpiomute = 4,
550 .needs_tvaudio = 1,
551 .pll = PLL_28,
552 .tuner_type = -1,
553 .tuner_addr = ADDR_UNSET,
554 .radio_addr = ADDR_UNSET,
555 },
556 [BTTV_BOARD_ZOLTRIX] = {
557 .name = "Zoltrix TV-Max",
558 .video_inputs = 3,
559 .audio_inputs = 1,
560 .tuner = 0,
561 .svhs = 2,
562 .gpiomask = 15,
563 .muxsel = { 2, 3, 1, 1 },
564 .gpiomux = { 0, 0, 1, 0 },
565 .gpiomute = 10,
566 .needs_tvaudio = 1,
567 .tuner_type = -1,
568 .tuner_addr = ADDR_UNSET,
569 .radio_addr = ADDR_UNSET,
570 },
571
572 /* ---- card 0x10 ---------------------------------- */
573 [BTTV_BOARD_PIXVIEWPLAYTV] = {
574 .name = "Prolink Pixelview PlayTV (bt878)",
575 .video_inputs = 3,
576 .audio_inputs = 1,
577 .tuner = 0,
578 .svhs = 2,
579 .gpiomask = 0x01fe00,
580 .muxsel = { 2, 3, 1, 1 },
581 #if 0
582 /* old */
583 .gpiomux = { 0x01c000, 0, 0x018000, 0x014000, 0x002000 },
584 #else
585 /* 2003-10-20 by "Anton A. Arapov" <arapov@mail.ru> */
586 .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 },
587 .gpiomute = 0x002000,
588 #endif
589 .needs_tvaudio = 1,
590 .pll = PLL_28,
591 .tuner_type = -1,
592 },
593 [BTTV_BOARD_WINVIEW_601] = {
594 .name = "Leadtek WinView 601",
595 .video_inputs = 3,
596 .audio_inputs = 1,
597 .tuner = 0,
598 .svhs = 2,
599 .gpiomask = 0x8300f8,
600 .muxsel = { 2, 3, 1, 1,0 },
601 .gpiomux = { 0x4fa007,0xcfa007,0xcfa007,0xcfa007 },
602 .gpiomute = 0xcfa007,
603 .needs_tvaudio = 1,
604 .tuner_type = -1,
605 .tuner_addr = ADDR_UNSET,
606 .radio_addr = ADDR_UNSET,
607 .audio_hook = winview_audio,
608 .has_radio = 1,
609 },
610 [BTTV_BOARD_AVEC_INTERCAP] = {
611 .name = "AVEC Intercapture",
612 .video_inputs = 3,
613 .audio_inputs = 2,
614 .tuner = 0,
615 .svhs = 2,
616 .gpiomask = 0,
617 .muxsel = { 2, 3, 1, 1 },
618 .gpiomux = { 1, 0, 0, 0 },
619 .needs_tvaudio = 1,
620 .tuner_type = -1,
621 .tuner_addr = ADDR_UNSET,
622 .radio_addr = ADDR_UNSET,
623 },
624 [BTTV_BOARD_LIFE_FLYKIT] = {
625 .name = "Lifeview FlyVideo II EZ /FlyKit LR38 Bt848 (capture only)",
626 .video_inputs = 4,
627 .audio_inputs = 1,
628 .tuner = -1,
629 .svhs = -1,
630 .gpiomask = 0x8dff00,
631 .muxsel = { 2, 3, 1, 1 },
632 .gpiomux = { 0 },
633 .no_msp34xx = 1,
634 .tuner_type = -1,
635 .tuner_addr = ADDR_UNSET,
636 .radio_addr = ADDR_UNSET,
637 },
638
639 /* ---- card 0x14 ---------------------------------- */
640 [BTTV_BOARD_CEI_RAFFLES] = {
641 .name = "CEI Raffles Card",
642 .video_inputs = 3,
643 .audio_inputs = 3,
644 .tuner = 0,
645 .svhs = 2,
646 .muxsel = { 2, 3, 1, 1 },
647 .tuner_type = -1,
648 .tuner_addr = ADDR_UNSET,
649 .radio_addr = ADDR_UNSET,
650 },
651 [BTTV_BOARD_CONFERENCETV] = {
652 .name = "Lifeview FlyVideo 98/ Lucky Star Image World ConferenceTV LR50",
653 .video_inputs = 4,
654 .audio_inputs = 2, /* tuner, line in */
655 .tuner = 0,
656 .svhs = 2,
657 .gpiomask = 0x1800,
658 .muxsel = { 2, 3, 1, 1 },
659 .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
660 .gpiomute = 0x1800,
661 .pll = PLL_28,
662 .tuner_type = TUNER_PHILIPS_PAL_I,
663 .tuner_addr = ADDR_UNSET,
664 .radio_addr = ADDR_UNSET,
665 },
666 [BTTV_BOARD_PHOEBE_TVMAS] = {
667 .name = "Askey CPH050/ Phoebe Tv Master + FM",
668 .video_inputs = 3,
669 .audio_inputs = 1,
670 .tuner = 0,
671 .svhs = 2,
672 .gpiomask = 0xc00,
673 .muxsel = { 2, 3, 1, 1 },
674 .gpiomux = { 0, 1, 0x800, 0x400 },
675 .gpiomute = 0xc00,
676 .needs_tvaudio = 1,
677 .pll = PLL_28,
678 .tuner_type = -1,
679 .tuner_addr = ADDR_UNSET,
680 .radio_addr = ADDR_UNSET,
681 },
682 [BTTV_BOARD_MODTEC_205] = {
683 .name = "Modular Technology MM201/MM202/MM205/MM210/MM215 PCTV, bt878",
684 .video_inputs = 3,
685 .audio_inputs = 1,
686 .tuner = 0,
687 .svhs = -1,
688 .gpiomask = 7,
689 .muxsel = { 2, 3, -1 },
690 .digital_mode = DIGITAL_MODE_CAMERA,
691 .gpiomux = { 0, 0, 0, 0 },
692 .no_msp34xx = 1,
693 .pll = PLL_28,
694 .tuner_type = TUNER_ALPS_TSBB5_PAL_I,
695 .tuner_addr = ADDR_UNSET,
696 .radio_addr = ADDR_UNSET,
697 },
698
699 /* ---- card 0x18 ---------------------------------- */
700 [BTTV_BOARD_MAGICTVIEW061] = {
701 .name = "Askey CPH05X/06X (bt878) [many vendors]",
702 .video_inputs = 3,
703 .audio_inputs = 1,
704 .tuner = 0,
705 .svhs = 2,
706 .gpiomask = 0xe00,
707 .muxsel = { 2, 3, 1, 1 },
708 .gpiomux = {0x400, 0x400, 0x400, 0x400 },
709 .gpiomute = 0xc00,
710 .needs_tvaudio = 1,
711 .pll = PLL_28,
712 .tuner_type = -1,
713 .tuner_addr = ADDR_UNSET,
714 .radio_addr = ADDR_UNSET,
715 .has_remote = 1,
716 },
717 [BTTV_BOARD_VOBIS_BOOSTAR] = {
718 .name = "Terratec TerraTV+ Version 1.0 (Bt848)/ Terra TValue Version 1.0/ Vobis TV-Boostar",
719 .video_inputs = 3,
720 .audio_inputs = 1,
721 .tuner = 0,
722 .svhs = 2,
723 .gpiomask = 0x1f0fff,
724 .muxsel = { 2, 3, 1, 1 },
725 .gpiomux = { 0x20000, 0x30000, 0x10000, 0 },
726 .gpiomute = 0x40000,
727 .needs_tvaudio = 0,
728 .tuner_type = TUNER_PHILIPS_PAL,
729 .tuner_addr = ADDR_UNSET,
730 .radio_addr = ADDR_UNSET,
731 .audio_hook = terratv_audio,
732 },
733 [BTTV_BOARD_HAUPPAUG_WCAM] = {
734 .name = "Hauppauge WinCam newer (bt878)",
735 .video_inputs = 4,
736 .audio_inputs = 1,
737 .tuner = 0,
738 .svhs = 3,
739 .gpiomask = 7,
740 .muxsel = { 2, 0, 1, 1 },
741 .gpiomux = { 0, 1, 2, 3 },
742 .gpiomute = 4,
743 .needs_tvaudio = 1,
744 .tuner_type = -1,
745 .tuner_addr = ADDR_UNSET,
746 .radio_addr = ADDR_UNSET,
747 },
748 [BTTV_BOARD_MAXI] = {
749 .name = "Lifeview FlyVideo 98/ MAXI TV Video PCI2 LR50",
750 .video_inputs = 4,
751 .audio_inputs = 2,
752 .tuner = 0,
753 .svhs = 2,
754 .gpiomask = 0x1800,
755 .muxsel = { 2, 3, 1, 1 },
756 .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
757 .gpiomute = 0x1800,
758 .pll = PLL_28,
759 .tuner_type = TUNER_PHILIPS_SECAM,
760 .tuner_addr = ADDR_UNSET,
761 .radio_addr = ADDR_UNSET,
762 },
763
764 /* ---- card 0x1c ---------------------------------- */
765 [BTTV_BOARD_TERRATV] = {
766 .name = "Terratec TerraTV+ Version 1.1 (bt878)",
767 .video_inputs = 3,
768 .audio_inputs = 1,
769 .tuner = 0,
770 .svhs = 2,
771 .gpiomask = 0x1f0fff,
772 .muxsel = { 2, 3, 1, 1 },
773 .gpiomux = { 0x20000, 0x30000, 0x10000, 0x00000 },
774 .gpiomute = 0x40000,
775 .needs_tvaudio = 0,
776 .tuner_type = TUNER_PHILIPS_PAL,
777 .tuner_addr = ADDR_UNSET,
778 .radio_addr = ADDR_UNSET,
779 .audio_hook = terratv_audio,
780 /* GPIO wiring:
781 External 20 pin connector (for Active Radio Upgrade board)
782 gpio00: i2c-sda
783 gpio01: i2c-scl
784 gpio02: om5610-data
785 gpio03: om5610-clk
786 gpio04: om5610-wre
787 gpio05: om5610-stereo
788 gpio06: rds6588-davn
789 gpio07: Pin 7 n.c.
790 gpio08: nIOW
791 gpio09+10: nIOR, nSEL ?? (bt878)
792 gpio09: nIOR (bt848)
793 gpio10: nSEL (bt848)
794 Sound Routing:
795 gpio16: u2-A0 (1st 4052bt)
796 gpio17: u2-A1
797 gpio18: u2-nEN
798 gpio19: u4-A0 (2nd 4052)
799 gpio20: u4-A1
800 u4-nEN - GND
801 Btspy:
802 00000 : Cdrom (internal audio input)
803 10000 : ext. Video audio input
804 20000 : TV Mono
805 a0000 : TV Mono/2
806 1a0000 : TV Stereo
807 30000 : Radio
808 40000 : Mute
809 */
810
811 },
812 [BTTV_BOARD_PXC200] = {
813 /* Jannik Fritsch <jannik@techfak.uni-bielefeld.de> */
814 .name = "Imagenation PXC200",
815 .video_inputs = 5,
816 .audio_inputs = 1,
817 .tuner = -1,
818 .svhs = 1, /* was: 4 */
819 .gpiomask = 0,
820 .muxsel = { 2, 3, 1, 0, 0},
821 .gpiomux = { 0 },
822 .needs_tvaudio = 1,
823 .tuner_type = -1,
824 .tuner_addr = ADDR_UNSET,
825 .radio_addr = ADDR_UNSET,
826 .muxsel_hook = PXC200_muxsel,
827
828 },
829 [BTTV_BOARD_FLYVIDEO_98] = {
830 .name = "Lifeview FlyVideo 98 LR50",
831 .video_inputs = 4,
832 .audio_inputs = 1,
833 .tuner = 0,
834 .svhs = 2,
835 .gpiomask = 0x1800, /* 0x8dfe00 */
836 .muxsel = { 2, 3, 1, 1 },
837 .gpiomux = { 0, 0x0800, 0x1000, 0x1000 },
838 .gpiomute = 0x1800,
839 .pll = PLL_28,
840 .tuner_type = -1,
841 .tuner_addr = ADDR_UNSET,
842 .radio_addr = ADDR_UNSET,
843 },
844 [BTTV_BOARD_IPROTV] = {
845 .name = "Formac iProTV, Formac ProTV I (bt848)",
846 .video_inputs = 4,
847 .audio_inputs = 1,
848 .tuner = 0,
849 .svhs = 3,
850 .gpiomask = 1,
851 .muxsel = { 2, 3, 1, 1 },
852 .gpiomux = { 1, 0, 0, 0 },
853 .pll = PLL_28,
854 .tuner_type = TUNER_PHILIPS_PAL,
855 .tuner_addr = ADDR_UNSET,
856 .radio_addr = ADDR_UNSET,
857 },
858
859 /* ---- card 0x20 ---------------------------------- */
860 [BTTV_BOARD_INTEL_C_S_PCI] = {
861 .name = "Intel Create and Share PCI/ Smart Video Recorder III",
862 .video_inputs = 4,
863 .audio_inputs = 0,
864 .tuner = -1,
865 .svhs = 2,
866 .gpiomask = 0,
867 .muxsel = { 2, 3, 1, 1 },
868 .gpiomux = { 0 },
869 .needs_tvaudio = 0,
870 .tuner_type = 4,
871 .tuner_addr = ADDR_UNSET,
872 .radio_addr = ADDR_UNSET,
873 },
874 [BTTV_BOARD_TERRATVALUE] = {
875 .name = "Terratec TerraTValue Version Bt878",
876 .video_inputs = 3,
877 .audio_inputs = 1,
878 .tuner = 0,
879 .svhs = 2,
880 .gpiomask = 0xffff00,
881 .muxsel = { 2, 3, 1, 1 },
882 .gpiomux = { 0x500, 0, 0x300, 0x900 },
883 .gpiomute = 0x900,
884 .needs_tvaudio = 1,
885 .pll = PLL_28,
886 .tuner_type = TUNER_PHILIPS_PAL,
887 .tuner_addr = ADDR_UNSET,
888 .radio_addr = ADDR_UNSET,
889 },
890 [BTTV_BOARD_WINFAST2000] = {
891 .name = "Leadtek WinFast 2000/ WinFast 2000 XP",
892 .video_inputs = 4,
893 .audio_inputs = 1,
894 .tuner = 0,
895 .svhs = 2,
896 .muxsel = { 2, 3, 1, 1, 0 }, /* TV, CVid, SVid, CVid over SVid connector */
897 #if 0
898 .gpiomask = 0xc33000,
899 .gpiomux = { 0x422000,0x1000,0x0000,0x620000,0x800000 },
900 #else
901 /* Alexander Varakin <avarakin@hotmail.com> [stereo version] */
902 .gpiomask = 0xb33000,
903 .gpiomux = { 0x122000,0x1000,0x0000,0x620000 },
904 .gpiomute = 0x800000,
905 #endif
906 /* Audio Routing for "WinFast 2000 XP" (no tv stereo !)
907 gpio23 -- hef4052:nEnable (0x800000)
908 gpio12 -- hef4052:A1
909 gpio13 -- hef4052:A0
910 0x0000: external audio
911 0x1000: FM
912 0x2000: TV
913 0x3000: n.c.
914 Note: There exists another variant "Winfast 2000" with tv stereo !?
915 Note: eeprom only contains FF and pci subsystem id 107d:6606
916 */
917 .needs_tvaudio = 0,
918 .pll = PLL_28,
919 .has_radio = 1,
920 .tuner_type = 5, /* default for now, gpio reads BFFF06 for Pal bg+dk */
921 .tuner_addr = ADDR_UNSET,
922 .radio_addr = ADDR_UNSET,
923 .audio_hook = winfast2000_audio,
924 .has_remote = 1,
925 },
926 [BTTV_BOARD_CHRONOS_VS2] = {
927 .name = "Lifeview FlyVideo 98 LR50 / Chronos Video Shuttle II",
928 .video_inputs = 4,
929 .audio_inputs = 3,
930 .tuner = 0,
931 .svhs = 2,
932 .gpiomask = 0x1800,
933 .muxsel = { 2, 3, 1, 1 },
934 .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
935 .gpiomute = 0x1800,
936 .pll = PLL_28,
937 .tuner_type = -1,
938 .tuner_addr = ADDR_UNSET,
939 .radio_addr = ADDR_UNSET,
940 },
941
942 /* ---- card 0x24 ---------------------------------- */
943 [BTTV_BOARD_TYPHOON_TVIEW] = {
944 .name = "Lifeview FlyVideo 98FM LR50 / Typhoon TView TV/FM Tuner",
945 .video_inputs = 4,
946 .audio_inputs = 3,
947 .tuner = 0,
948 .svhs = 2,
949 .gpiomask = 0x1800,
950 .muxsel = { 2, 3, 1, 1 },
951 .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
952 .gpiomute = 0x1800,
953 .pll = PLL_28,
954 .tuner_type = -1,
955 .tuner_addr = ADDR_UNSET,
956 .radio_addr = ADDR_UNSET,
957 .has_radio = 1,
958 },
959 [BTTV_BOARD_PXELVWPLTVPRO] = {
960 .name = "Prolink PixelView PlayTV pro",
961 .video_inputs = 3,
962 .audio_inputs = 1,
963 .tuner = 0,
964 .svhs = 2,
965 .gpiomask = 0xff,
966 .muxsel = { 2, 3, 1, 1 },
967 .gpiomux = { 0x21, 0x20, 0x24, 0x2c },
968 .gpiomute = 0x29,
969 .no_msp34xx = 1,
970 .pll = PLL_28,
971 .tuner_type = -1,
972 .tuner_addr = ADDR_UNSET,
973 .radio_addr = ADDR_UNSET,
974 },
975 [BTTV_BOARD_MAGICTVIEW063] = {
976 .name = "Askey CPH06X TView99",
977 .video_inputs = 4,
978 .audio_inputs = 1,
979 .tuner = 0,
980 .svhs = 2,
981 .gpiomask = 0x551e00,
982 .muxsel = { 2, 3, 1, 0 },
983 .gpiomux = { 0x551400, 0x551200, 0, 0 },
984 .gpiomute = 0x551c00,
985 .needs_tvaudio = 1,
986 .pll = PLL_28,
987 .tuner_type = 1,
988 .tuner_addr = ADDR_UNSET,
989 .radio_addr = ADDR_UNSET,
990 .has_remote = 1,
991 },
992 [BTTV_BOARD_PINNACLE] = {
993 .name = "Pinnacle PCTV Studio/Rave",
994 .video_inputs = 3,
995 .audio_inputs = 1,
996 .tuner = 0,
997 .svhs = 2,
998 .gpiomask = 0x03000F,
999 .muxsel = { 2, 3, 1, 1 },
1000 .gpiomux = { 2, 0xd0001, 0, 0 },
1001 .gpiomute = 1,
1002 .needs_tvaudio = 0,
1003 .pll = PLL_28,
1004 .tuner_type = -1,
1005 .tuner_addr = ADDR_UNSET,
1006 .radio_addr = ADDR_UNSET,
1007 },
1008
1009 /* ---- card 0x28 ---------------------------------- */
1010 [BTTV_BOARD_STB2] = {
1011 .name = "STB TV PCI FM, Gateway P/N 6000704 (bt878), 3Dfx VoodooTV 100",
1012 .video_inputs = 3,
1013 .audio_inputs = 1,
1014 .tuner = 0,
1015 .svhs = 2,
1016 .gpiomask = 7,
1017 .muxsel = { 2, 3, 1, 1 },
1018 .gpiomux = { 4, 0, 2, 3 },
1019 .gpiomute = 1,
1020 .no_msp34xx = 1,
1021 .needs_tvaudio = 1,
1022 .tuner_type = TUNER_PHILIPS_NTSC,
1023 .tuner_addr = ADDR_UNSET,
1024 .radio_addr = ADDR_UNSET,
1025 .pll = PLL_28,
1026 .has_radio = 1,
1027 },
1028 [BTTV_BOARD_AVPHONE98] = {
1029 .name = "AVerMedia TVPhone 98",
1030 .video_inputs = 3,
1031 .audio_inputs = 4,
1032 .tuner = 0,
1033 .svhs = 2,
1034 .gpiomask = 15,
1035 .muxsel = { 2, 3, 1, 1 },
1036 .gpiomux = { 13, 4, 11, 7 },
1037 .needs_tvaudio = 1,
1038 .pll = PLL_28,
1039 .tuner_type = -1,
1040 .tuner_addr = ADDR_UNSET,
1041 .radio_addr = ADDR_UNSET,
1042 .has_radio = 1,
1043 .audio_hook = avermedia_tvphone_audio,
1044 },
1045 [BTTV_BOARD_PV951] = {
1046 .name = "ProVideo PV951", /* pic16c54 */
1047 .video_inputs = 3,
1048 .audio_inputs = 1,
1049 .tuner = 0,
1050 .svhs = 2,
1051 .gpiomask = 0,
1052 .muxsel = { 2, 3, 1, 1},
1053 .gpiomux = { 0, 0, 0, 0},
1054 .needs_tvaudio = 1,
1055 .no_msp34xx = 1,
1056 .pll = PLL_28,
1057 .tuner_type = 1,
1058 .tuner_addr = ADDR_UNSET,
1059 .radio_addr = ADDR_UNSET,
1060 },
1061 [BTTV_BOARD_ONAIR_TV] = {
1062 .name = "Little OnAir TV",
1063 .video_inputs = 3,
1064 .audio_inputs = 1,
1065 .tuner = 0,
1066 .svhs = 2,
1067 .gpiomask = 0xe00b,
1068 .muxsel = { 2, 3, 1, 1 },
1069 .gpiomux = { 0xff9ff6, 0xff9ff6, 0xff1ff7, 0 },
1070 .gpiomute = 0xff3ffc,
1071 .no_msp34xx = 1,
1072 .tuner_type = -1,
1073 .tuner_addr = ADDR_UNSET,
1074 .radio_addr = ADDR_UNSET,
1075 },
1076
1077 /* ---- card 0x2c ---------------------------------- */
1078 [BTTV_BOARD_SIGMA_TVII_FM] = {
1079 .name = "Sigma TVII-FM",
1080 .video_inputs = 2,
1081 .audio_inputs = 1,
1082 .tuner = 0,
1083 .svhs = -1,
1084 .gpiomask = 3,
1085 .muxsel = { 2, 3, 1, 1 },
1086 .gpiomux = { 1, 1, 0, 2 },
1087 .gpiomute = 3,
1088 .no_msp34xx = 1,
1089 .pll = PLL_NONE,
1090 .tuner_type = -1,
1091 .tuner_addr = ADDR_UNSET,
1092 .radio_addr = ADDR_UNSET,
1093 },
1094 [BTTV_BOARD_MATRIX_VISION2] = {
1095 .name = "MATRIX-Vision MV-Delta 2",
1096 .video_inputs = 5,
1097 .audio_inputs = 1,
1098 .tuner = -1,
1099 .svhs = 3,
1100 .gpiomask = 0,
1101 .muxsel = { 2, 3, 1, 0, 0 },
1102 .gpiomux = { 0 },
1103 .no_msp34xx = 1,
1104 .pll = PLL_28,
1105 .tuner_type = -1,
1106 .tuner_addr = ADDR_UNSET,
1107 .radio_addr = ADDR_UNSET,
1108 },
1109 [BTTV_BOARD_ZOLTRIX_GENIE] = {
1110 .name = "Zoltrix Genie TV/FM",
1111 .video_inputs = 3,
1112 .audio_inputs = 1,
1113 .tuner = 0,
1114 .svhs = 2,
1115 .gpiomask = 0xbcf03f,
1116 .muxsel = { 2, 3, 1, 1 },
1117 .gpiomux = { 0xbc803f, 0xbc903f, 0xbcb03f, 0 },
1118 .gpiomute = 0xbcb03f,
1119 .no_msp34xx = 1,
1120 .pll = PLL_28,
1121 .tuner_type = 21,
1122 .tuner_addr = ADDR_UNSET,
1123 .radio_addr = ADDR_UNSET,
1124 },
1125 [BTTV_BOARD_TERRATVRADIO] = {
1126 .name = "Terratec TV/Radio+",
1127 .video_inputs = 3,
1128 .audio_inputs = 1,
1129 .tuner = 0,
1130 .svhs = 2,
1131 .gpiomask = 0x70000,
1132 .muxsel = { 2, 3, 1, 1 },
1133 .gpiomux = { 0x20000, 0x30000, 0x10000, 0 },
1134 .gpiomute = 0x40000,
1135 .needs_tvaudio = 1,
1136 .no_msp34xx = 1,
1137 .pll = PLL_35,
1138 .tuner_type = 1,
1139 .tuner_addr = ADDR_UNSET,
1140 .radio_addr = ADDR_UNSET,
1141 .has_radio = 1,
1142 },
1143
1144 /* ---- card 0x30 ---------------------------------- */
1145 [BTTV_BOARD_DYNALINK] = {
1146 .name = "Askey CPH03x/ Dynalink Magic TView",
1147 .video_inputs = 3,
1148 .audio_inputs = 1,
1149 .tuner = 0,
1150 .svhs = 2,
1151 .gpiomask = 15,
1152 .muxsel = { 2, 3, 1, 1 },
1153 .gpiomux = {2,0,0,0 },
1154 .gpiomute = 1,
1155 .needs_tvaudio = 1,
1156 .pll = PLL_28,
1157 .tuner_type = -1,
1158 .tuner_addr = ADDR_UNSET,
1159 .radio_addr = ADDR_UNSET,
1160 },
1161 [BTTV_BOARD_GVBCTV3PCI] = {
1162 .name = "IODATA GV-BCTV3/PCI",
1163 .video_inputs = 3,
1164 .audio_inputs = 1,
1165 .tuner = 0,
1166 .svhs = 2,
1167 .gpiomask = 0x010f00,
1168 .muxsel = {2, 3, 0, 0 },
1169 .gpiomux = {0x10000, 0, 0x10000, 0 },
1170 .no_msp34xx = 1,
1171 .pll = PLL_28,
1172 .tuner_type = TUNER_ALPS_TSHC6_NTSC,
1173 .tuner_addr = ADDR_UNSET,
1174 .radio_addr = ADDR_UNSET,
1175 .audio_hook = gvbctv3pci_audio,
1176 },
1177 [BTTV_BOARD_PXELVWPLTVPAK] = {
1178 .name = "Prolink PV-BT878P+4E / PixelView PlayTV PAK / Lenco MXTV-9578 CP",
1179 .video_inputs = 5,
1180 .audio_inputs = 1,
1181 .tuner = 0,
1182 .svhs = 3,
1183 .gpiomask = 0xAA0000,
1184 .muxsel = { 2,3,1,1,-1 },
1185 .digital_mode = DIGITAL_MODE_CAMERA,
1186 .gpiomux = { 0x20000, 0, 0x80000, 0x80000 },
1187 .gpiomute = 0xa8000,
1188 .no_msp34xx = 1,
1189 .pll = PLL_28,
1190 .tuner_type = TUNER_PHILIPS_PAL_I,
1191 .tuner_addr = ADDR_UNSET,
1192 .radio_addr = ADDR_UNSET,
1193 .has_remote = 1,
1194 /* GPIO wiring: (different from Rev.4C !)
1195 GPIO17: U4.A0 (first hef4052bt)
1196 GPIO19: U4.A1
1197 GPIO20: U5.A1 (second hef4052bt)
1198 GPIO21: U4.nEN
1199 GPIO22: BT832 Reset Line
1200 GPIO23: A5,A0, U5,nEN
1201 Note: At i2c=0x8a is a Bt832 chip, which changes to 0x88 after being reset via GPIO22
1202 */
1203 },
1204 [BTTV_BOARD_EAGLE] = {
1205 .name = "Eagle Wireless Capricorn2 (bt878A)",
1206 .video_inputs = 4,
1207 .audio_inputs = 1,
1208 .tuner = 0,
1209 .svhs = 2,
1210 .gpiomask = 7,
1211 .muxsel = { 2, 0, 1, 1 },
1212 .gpiomux = { 0, 1, 2, 3 },
1213 .gpiomute = 4,
1214 .pll = PLL_28,
1215 .tuner_type = -1 /* TUNER_ALPS_TMDH2_NTSC */,
1216 .tuner_addr = ADDR_UNSET,
1217 .radio_addr = ADDR_UNSET,
1218 },
1219
1220 /* ---- card 0x34 ---------------------------------- */
1221 [BTTV_BOARD_PINNACLEPRO] = {
1222 /* David Härdeman <david@2gen.com> */
1223 .name = "Pinnacle PCTV Studio Pro",
1224 .video_inputs = 4,
1225 .audio_inputs = 1,
1226 .tuner = 0,
1227 .svhs = 3,
1228 .gpiomask = 0x03000F,
1229 .muxsel = { 2, 3, 1, 1 },
1230 .gpiomux = { 1, 0xd0001, 0, 0 },
1231 .gpiomute = 10,
1232 /* sound path (5 sources):
1233 MUX1 (mask 0x03), Enable Pin 0x08 (0=enable, 1=disable)
1234 0= ext. Audio IN
1235 1= from MUX2
1236 2= Mono TV sound from Tuner
1237 3= not connected
1238 MUX2 (mask 0x30000):
1239 0,2,3= from MSP34xx
1240 1= FM stereo Radio from Tuner */
1241 .needs_tvaudio = 0,
1242 .pll = PLL_28,
1243 .tuner_type = -1,
1244 .tuner_addr = ADDR_UNSET,
1245 .radio_addr = ADDR_UNSET,
1246 },
1247 [BTTV_BOARD_TVIEW_RDS_FM] = {
1248 /* Claas Langbehn <claas@bigfoot.com>,
1249 Sven Grothklags <sven@upb.de> */
1250 .name = "Typhoon TView RDS + FM Stereo / KNC1 TV Station RDS",
1251 .video_inputs = 4,
1252 .audio_inputs = 3,
1253 .tuner = 0,
1254 .svhs = 2,
1255 .gpiomask = 0x1c,
1256 .muxsel = { 2, 3, 1, 1 },
1257 .gpiomux = { 0, 0, 0x10, 8 },
1258 .gpiomute = 4,
1259 .needs_tvaudio = 1,
1260 .pll = PLL_28,
1261 .tuner_type = TUNER_PHILIPS_PAL,
1262 .tuner_addr = ADDR_UNSET,
1263 .radio_addr = ADDR_UNSET,
1264 .has_radio = 1,
1265 },
1266 [BTTV_BOARD_LIFETEC_9415] = {
1267 /* Tim Röstermundt <rosterm@uni-muenster.de>
1268 in de.comp.os.unix.linux.hardware:
1269 options bttv card=0 pll=1 radio=1 gpiomask=0x18e0
1270 gpiomux =0x44c71f,0x44d71f,0,0x44d71f,0x44dfff
1271 options tuner type=5 */
1272 .name = "Lifeview FlyVideo 2000 /FlyVideo A2/ Lifetec LT 9415 TV [LR90]",
1273 .video_inputs = 4,
1274 .audio_inputs = 1,
1275 .tuner = 0,
1276 .svhs = 2,
1277 .gpiomask = 0x18e0,
1278 .muxsel = { 2, 3, 1, 1 },
1279 .gpiomux = { 0x0000,0x0800,0x1000,0x1000 },
1280 .gpiomute = 0x18e0,
1281 /* For cards with tda9820/tda9821:
1282 0x0000: Tuner normal stereo
1283 0x0080: Tuner A2 SAP (second audio program = Zweikanalton)
1284 0x0880: Tuner A2 stereo */
1285 .pll = PLL_28,
1286 .tuner_type = -1,
1287 .tuner_addr = ADDR_UNSET,
1288 .radio_addr = ADDR_UNSET,
1289 },
1290 [BTTV_BOARD_BESTBUY_EASYTV] = {
1291 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1292 old Easy TV BT848 version (model CPH031) */
1293 .name = "Askey CPH031/ BESTBUY Easy TV",
1294 .video_inputs = 4,
1295 .audio_inputs = 1,
1296 .tuner = 0,
1297 .svhs = 2,
1298 .gpiomask = 0xF,
1299 .muxsel = { 2, 3, 1, 0 },
1300 .gpiomux = { 2, 0, 0, 0 },
1301 .gpiomute = 10,
1302 .needs_tvaudio = 0,
1303 .pll = PLL_28,
1304 .tuner_type = TUNER_TEMIC_PAL,
1305 .tuner_addr = ADDR_UNSET,
1306 .radio_addr = ADDR_UNSET,
1307 },
1308
1309 /* ---- card 0x38 ---------------------------------- */
1310 [BTTV_BOARD_FLYVIDEO_98FM] = {
1311 /* Gordon Heydon <gjheydon@bigfoot.com ('98) */
1312 .name = "Lifeview FlyVideo 98FM LR50",
1313 .video_inputs = 4,
1314 .audio_inputs = 3,
1315 .tuner = 0,
1316 .svhs = 2,
1317 .gpiomask = 0x1800,
1318 .muxsel = { 2, 3, 1, 1 },
1319 .gpiomux = { 0, 0x800, 0x1000, 0x1000 },
1320 .gpiomute = 0x1800,
1321 .pll = PLL_28,
1322 .tuner_type = 5,
1323 .tuner_addr = ADDR_UNSET,
1324 .radio_addr = ADDR_UNSET,
1325 },
1326 /* This is the ultimate cheapo capture card
1327 * just a BT848A on a small PCB!
1328 * Steve Hosgood <steve@equiinet.com> */
1329 [BTTV_BOARD_GRANDTEC] = {
1330 .name = "GrandTec 'Grand Video Capture' (Bt848)",
1331 .video_inputs = 2,
1332 .audio_inputs = 0,
1333 .tuner = -1,
1334 .svhs = 1,
1335 .gpiomask = 0,
1336 .muxsel = { 3, 1 },
1337 .gpiomux = { 0 },
1338 .needs_tvaudio = 0,
1339 .no_msp34xx = 1,
1340 .pll = PLL_35,
1341 .tuner_type = -1,
1342 .tuner_addr = ADDR_UNSET,
1343 .radio_addr = ADDR_UNSET,
1344 },
1345 [BTTV_BOARD_ASKEY_CPH060] = {
1346 /* Daniel Herrington <daniel.herrington@home.com> */
1347 .name = "Askey CPH060/ Phoebe TV Master Only (No FM)",
1348 .video_inputs = 3,
1349 .audio_inputs = 1,
1350 .tuner = 0,
1351 .svhs = 2,
1352 .gpiomask = 0xe00,
1353 .muxsel = { 2, 3, 1, 1},
1354 .gpiomux = { 0x400, 0x400, 0x400, 0x400 },
1355 .gpiomute = 0x800,
1356 .needs_tvaudio = 1,
1357 .pll = PLL_28,
1358 .tuner_type = TUNER_TEMIC_4036FY5_NTSC,
1359 .tuner_addr = ADDR_UNSET,
1360 .radio_addr = ADDR_UNSET,
1361 },
1362 [BTTV_BOARD_ASKEY_CPH03X] = {
1363 /* Matti Mottus <mottus@physic.ut.ee> */
1364 .name = "Askey CPH03x TV Capturer",
1365 .video_inputs = 4,
1366 .audio_inputs = 1,
1367 .tuner = 0,
1368 .svhs = 2,
1369 .gpiomask = 0x03000F,
1370 .muxsel = { 2, 3, 1, 0 },
1371 .gpiomux = { 2, 0, 0, 0 },
1372 .gpiomute = 1,
1373 .pll = PLL_28,
1374 .tuner_type = 0,
1375 .tuner_addr = ADDR_UNSET,
1376 .radio_addr = ADDR_UNSET,
1377 },
1378
1379 /* ---- card 0x3c ---------------------------------- */
1380 [BTTV_BOARD_MM100PCTV] = {
1381 /* Philip Blundell <philb@gnu.org> */
1382 .name = "Modular Technology MM100PCTV",
1383 .video_inputs = 2,
1384 .audio_inputs = 2,
1385 .tuner = 0,
1386 .svhs = -1,
1387 .gpiomask = 11,
1388 .muxsel = { 2, 3, 1, 1 },
1389 .gpiomux = { 2, 0, 0, 1 },
1390 .gpiomute = 8,
1391 .pll = PLL_35,
1392 .tuner_type = TUNER_TEMIC_PAL,
1393 .tuner_addr = ADDR_UNSET,
1394 .radio_addr = ADDR_UNSET,
1395 },
1396 [BTTV_BOARD_GMV1] = {
1397 /* Adrian Cox <adrian@humboldt.co.uk */
1398 .name = "AG Electronics GMV1",
1399 .video_inputs = 2,
1400 .audio_inputs = 0,
1401 .tuner = -1,
1402 .svhs = 1,
1403 .gpiomask = 0xF,
1404 .muxsel = { 2, 2 },
1405 .gpiomux = { },
1406 .no_msp34xx = 1,
1407 .needs_tvaudio = 0,
1408 .pll = PLL_28,
1409 .tuner_type = -1,
1410 .tuner_addr = ADDR_UNSET,
1411 .radio_addr = ADDR_UNSET,
1412 },
1413 [BTTV_BOARD_BESTBUY_EASYTV2] = {
1414 /* Miguel Angel Alvarez <maacruz@navegalia.com>
1415 new Easy TV BT878 version (model CPH061)
1416 special thanks to Informatica Mieres for providing the card */
1417 .name = "Askey CPH061/ BESTBUY Easy TV (bt878)",
1418 .video_inputs = 3,
1419 .audio_inputs = 2,
1420 .tuner = 0,
1421 .svhs = 2,
1422 .gpiomask = 0xFF,
1423 .muxsel = { 2, 3, 1, 0 },
1424 .gpiomux = { 1, 0, 4, 4 },
1425 .gpiomute = 9,
1426 .needs_tvaudio = 0,
1427 .pll = PLL_28,
1428 .tuner_type = TUNER_PHILIPS_PAL,
1429 .tuner_addr = ADDR_UNSET,
1430 .radio_addr = ADDR_UNSET,
1431 },
1432 [BTTV_BOARD_ATI_TVWONDER] = {
1433 /* Lukas Gebauer <geby@volny.cz> */
1434 .name = "ATI TV-Wonder",
1435 .video_inputs = 3,
1436 .audio_inputs = 1,
1437 .tuner = 0,
1438 .svhs = 2,
1439 .gpiomask = 0xf03f,
1440 .muxsel = { 2, 3, 1, 0 },
1441 .gpiomux = { 0xbffe, 0, 0xbfff, 0 },
1442 .gpiomute = 0xbffe,
1443 .pll = PLL_28,
1444 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1445 .tuner_addr = ADDR_UNSET,
1446 .radio_addr = ADDR_UNSET,
1447 },
1448
1449 /* ---- card 0x40 ---------------------------------- */
1450 [BTTV_BOARD_ATI_TVWONDERVE] = {
1451 /* Lukas Gebauer <geby@volny.cz> */
1452 .name = "ATI TV-Wonder VE",
1453 .video_inputs = 2,
1454 .audio_inputs = 1,
1455 .tuner = 0,
1456 .svhs = -1,
1457 .gpiomask = 1,
1458 .muxsel = { 2, 3, 0, 1 },
1459 .gpiomux = { 0, 0, 1, 0 },
1460 .no_msp34xx = 1,
1461 .pll = PLL_28,
1462 .tuner_type = TUNER_TEMIC_4006FN5_MULTI_PAL,
1463 .tuner_addr = ADDR_UNSET,
1464 .radio_addr = ADDR_UNSET,
1465 },
1466 [BTTV_BOARD_FLYVIDEO2000] = {
1467 /* DeeJay <deejay@westel900.net (2000S) */
1468 .name = "Lifeview FlyVideo 2000S LR90",
1469 .video_inputs = 3,
1470 .audio_inputs = 3,
1471 .tuner = 0,
1472 .svhs = 2,
1473 .gpiomask = 0x18e0,
1474 .muxsel = { 2, 3, 0, 1 },
1475 /* Radio changed from 1e80 to 0x800 to make
1476 FlyVideo2000S in .hu happy (gm)*/
1477 /* -dk-???: set mute=0x1800 for tda9874h daughterboard */
1478 .gpiomux = { 0x0000,0x0800,0x1000,0x1000 },
1479 .gpiomute = 0x1800,
1480 .audio_hook = fv2000s_audio,
1481 .no_msp34xx = 1,
1482 .no_tda9875 = 1,
1483 .needs_tvaudio = 1,
1484 .pll = PLL_28,
1485 .tuner_type = 5,
1486 .tuner_addr = ADDR_UNSET,
1487 .radio_addr = ADDR_UNSET,
1488 },
1489 [BTTV_BOARD_TERRATVALUER] = {
1490 .name = "Terratec TValueRadio",
1491 .video_inputs = 3,
1492 .audio_inputs = 1,
1493 .tuner = 0,
1494 .svhs = 2,
1495 .gpiomask = 0xffff00,
1496 .muxsel = { 2, 3, 1, 1 },
1497 .gpiomux = { 0x500, 0x500, 0x300, 0x900 },
1498 .gpiomute = 0x900,
1499 .needs_tvaudio = 1,
1500 .pll = PLL_28,
1501 .tuner_type = TUNER_PHILIPS_PAL,
1502 .tuner_addr = ADDR_UNSET,
1503 .radio_addr = ADDR_UNSET,
1504 .has_radio = 1,
1505 },
1506 [BTTV_BOARD_GVBCTV4PCI] = {
1507 /* TANAKA Kei <peg00625@nifty.com> */
1508 .name = "IODATA GV-BCTV4/PCI",
1509 .video_inputs = 3,
1510 .audio_inputs = 1,
1511 .tuner = 0,
1512 .svhs = 2,
1513 .gpiomask = 0x010f00,
1514 .muxsel = {2, 3, 0, 0 },
1515 .gpiomux = {0x10000, 0, 0x10000, 0 },
1516 .no_msp34xx = 1,
1517 .pll = PLL_28,
1518 .tuner_type = TUNER_SHARP_2U5JF5540_NTSC,
1519 .tuner_addr = ADDR_UNSET,
1520 .radio_addr = ADDR_UNSET,
1521 .audio_hook = gvbctv3pci_audio,
1522 },
1523
1524 /* ---- card 0x44 ---------------------------------- */
1525 [BTTV_BOARD_VOODOOTV_FM] = {
1526 .name = "3Dfx VoodooTV FM (Euro), VoodooTV 200 (USA)",
1527 /* try "insmod msp3400 simple=0" if you have
1528 * sound problems with this card. */
1529 .video_inputs = 4,
1530 .audio_inputs = 1,
1531 .tuner = 0,
1532 .svhs = -1,
1533 .gpiomask = 0x4f8a00,
1534 /* 0x100000: 1=MSP enabled (0=disable again)
1535 * 0x010000: Connected to "S0" on tda9880 (0=Pal/BG, 1=NTSC) */
1536 .gpiomux = {0x947fff, 0x987fff,0x947fff,0x947fff },
1537 .gpiomute = 0x947fff,
1538 /* tvtuner, radio, external,internal, mute, stereo
1539 * tuner, Composit, SVid, Composit-on-Svid-adapter */
1540 .muxsel = { 2, 3 ,0 ,1 },
1541 .tuner_type = TUNER_MT2032,
1542 .tuner_addr = ADDR_UNSET,
1543 .radio_addr = ADDR_UNSET,
1544 .pll = PLL_28,
1545 .has_radio = 1,
1546 },
1547 [BTTV_BOARD_AIMMS] = {
1548 /* Philip Blundell <pb@nexus.co.uk> */
1549 .name = "Active Imaging AIMMS",
1550 .video_inputs = 1,
1551 .audio_inputs = 0,
1552 .tuner = -1,
1553 .tuner_type = -1,
1554 .tuner_addr = ADDR_UNSET,
1555 .radio_addr = ADDR_UNSET,
1556 .pll = PLL_28,
1557 .muxsel = { 2 },
1558 .gpiomask = 0
1559 },
1560 [BTTV_BOARD_PV_BT878P_PLUS] = {
1561 /* Tomasz Pyra <hellfire@sedez.iq.pl> */
1562 .name = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
1563 .video_inputs = 3,
1564 .audio_inputs = 4,
1565 .tuner = 0,
1566 .svhs = 2,
1567 .gpiomask = 15,
1568 .muxsel = { 2, 3, 1, 1 },
1569 .gpiomux = { 0, 0, 11, 7 }, /* TV and Radio with same GPIO ! */
1570 .gpiomute = 13,
1571 .needs_tvaudio = 1,
1572 .pll = PLL_28,
1573 .tuner_type = 25,
1574 .tuner_addr = ADDR_UNSET,
1575 .radio_addr = ADDR_UNSET,
1576 .has_remote = 1,
1577 /* GPIO wiring:
1578 GPIO0: U4.A0 (hef4052bt)
1579 GPIO1: U4.A1
1580 GPIO2: U4.A1 (second hef4052bt)
1581 GPIO3: U4.nEN, U5.A0, A5.nEN
1582 GPIO8-15: vrd866b ?
1583 */
1584 },
1585 [BTTV_BOARD_FLYVIDEO98EZ] = {
1586 .name = "Lifeview FlyVideo 98EZ (capture only) LR51",
1587 .video_inputs = 4,
1588 .audio_inputs = 0,
1589 .tuner = -1,
1590 .svhs = 2,
1591 .muxsel = { 2, 3, 1, 1 }, /* AV1, AV2, SVHS, CVid adapter on SVHS */
1592 .pll = PLL_28,
1593 .no_msp34xx = 1,
1594 .tuner_type = UNSET,
1595 .tuner_addr = ADDR_UNSET,
1596 .radio_addr = ADDR_UNSET,
1597 },
1598
1599 /* ---- card 0x48 ---------------------------------- */
1600 [BTTV_BOARD_PV_BT878P_9B] = {
1601 /* Dariusz Kowalewski <darekk@automex.pl> */
1602 .name = "Prolink Pixelview PV-BT878P+9B (PlayTV Pro rev.9B FM+NICAM)",
1603 .video_inputs = 4,
1604 .audio_inputs = 1,
1605 .tuner = 0,
1606 .svhs = 2,
1607 .gpiomask = 0x3f,
1608 .muxsel = { 2, 3, 1, 1 },
1609 .gpiomux = { 0x01, 0x00, 0x03, 0x03 },
1610 .gpiomute = 0x09,
1611 .needs_tvaudio = 1,
1612 .no_msp34xx = 1,
1613 .no_tda9875 = 1,
1614 .pll = PLL_28,
1615 .tuner_type = 5,
1616 .tuner_addr = ADDR_UNSET,
1617 .radio_addr = ADDR_UNSET,
1618 .audio_hook = pvbt878p9b_audio, /* Note: not all cards have stereo */
1619 .has_radio = 1, /* Note: not all cards have radio */
1620 .has_remote = 1,
1621 /* GPIO wiring:
1622 GPIO0: A0 hef4052
1623 GPIO1: A1 hef4052
1624 GPIO3: nEN hef4052
1625 GPIO8-15: vrd866b
1626 GPIO20,22,23: R30,R29,R28
1627 */
1628 },
1629 [BTTV_BOARD_SENSORAY311] = {
1630 /* Clay Kunz <ckunz@mail.arc.nasa.gov> */
1631 /* you must jumper JP5 for the card to work */
1632 .name = "Sensoray 311",
1633 .video_inputs = 5,
1634 .audio_inputs = 0,
1635 .tuner = -1,
1636 .svhs = 4,
1637 .gpiomask = 0,
1638 .muxsel = { 2, 3, 1, 0, 0 },
1639 .gpiomux = { 0 },
1640 .needs_tvaudio = 0,
1641 .tuner_type = -1,
1642 .tuner_addr = ADDR_UNSET,
1643 .radio_addr = ADDR_UNSET,
1644 },
1645 [BTTV_BOARD_RV605] = {
1646 /* Miguel Freitas <miguel@cetuc.puc-rio.br> */
1647 .name = "RemoteVision MX (RV605)",
1648 .video_inputs = 16,
1649 .audio_inputs = 0,
1650 .tuner = -1,
1651 .svhs = -1,
1652 .gpiomask = 0x00,
1653 .gpiomask2 = 0x07ff,
1654 .muxsel = { 0x33, 0x13, 0x23, 0x43, 0xf3, 0x73, 0xe3, 0x03,
1655 0xd3, 0xb3, 0xc3, 0x63, 0x93, 0x53, 0x83, 0xa3 },
1656 .no_msp34xx = 1,
1657 .no_tda9875 = 1,
1658 .tuner_type = -1,
1659 .tuner_addr = ADDR_UNSET,
1660 .radio_addr = ADDR_UNSET,
1661 .muxsel_hook = rv605_muxsel,
1662 },
1663 [BTTV_BOARD_POWERCLR_MTV878] = {
1664 .name = "Powercolor MTV878/ MTV878R/ MTV878F",
1665 .video_inputs = 3,
1666 .audio_inputs = 2,
1667 .tuner = 0,
1668 .svhs = 2,
1669 .gpiomask = 0x1C800F, /* Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset */
1670 .muxsel = { 2, 1, 1, },
1671 .gpiomux = { 0, 1, 2, 2 },
1672 .gpiomute = 4,
1673 .needs_tvaudio = 0,
1674 .tuner_type = TUNER_PHILIPS_PAL,
1675 .tuner_addr = ADDR_UNSET,
1676 .radio_addr = ADDR_UNSET,
1677 .pll = PLL_28,
1678 .has_radio = 1,
1679 },
1680
1681 /* ---- card 0x4c ---------------------------------- */
1682 [BTTV_BOARD_WINDVR] = {
1683 /* Masaki Suzuki <masaki@btree.org> */
1684 .name = "Canopus WinDVR PCI (COMPAQ Presario 3524JP, 5112JP)",
1685 .video_inputs = 3,
1686 .audio_inputs = 1,
1687 .tuner = 0,
1688 .svhs = 2,
1689 .gpiomask = 0x140007,
1690 .muxsel = { 2, 3, 1, 1 },
1691 .gpiomux = { 0, 1, 2, 3 },
1692 .gpiomute = 4,
1693 .tuner_type = TUNER_PHILIPS_NTSC,
1694 .tuner_addr = ADDR_UNSET,
1695 .radio_addr = ADDR_UNSET,
1696 .audio_hook = windvr_audio,
1697 },
1698 [BTTV_BOARD_GRANDTEC_MULTI] = {
1699 .name = "GrandTec Multi Capture Card (Bt878)",
1700 .video_inputs = 4,
1701 .audio_inputs = 0,
1702 .tuner = -1,
1703 .svhs = -1,
1704 .gpiomask = 0,
1705 .muxsel = { 2, 3, 1, 0 },
1706 .gpiomux = { 0 },
1707 .needs_tvaudio = 0,
1708 .no_msp34xx = 1,
1709 .pll = PLL_28,
1710 .tuner_type = -1,
1711 .tuner_addr = ADDR_UNSET,
1712 .radio_addr = ADDR_UNSET,
1713 },
1714 [BTTV_BOARD_KWORLD] = {
1715 .name = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
1716 .video_inputs = 4,
1717 .audio_inputs = 3,
1718 .tuner = 0,
1719 .svhs = 2,
1720 .gpiomask = 7,
1721 .muxsel = { 2, 3, 1, 1 }, /* Tuner, SVid, SVHS, SVid to SVHS connector */
1722 .gpiomux = { 0, 0, 4, 4 },/* Yes, this tuner uses the same audio output for TV and FM radio!
1723 * This card lacks external Audio In, so we mute it on Ext. & Int.
1724 * The PCB can take a sbx1637/sbx1673, wiring unknown.
1725 * This card lacks PCI subsystem ID, sigh.
1726 * gpiomux =1: lower volume, 2+3: mute
1727 * btwincap uses 0x80000/0x80003
1728 */
1729 .gpiomute = 4,
1730 .needs_tvaudio = 0,
1731 .no_msp34xx = 1,
1732 .pll = PLL_28,
1733 .tuner_type = 5,
1734 .tuner_addr = ADDR_UNSET,
1735 .radio_addr = ADDR_UNSET,
1736 /* Samsung TCPA9095PC27A (BG+DK), philips compatible, w/FM, stereo and
1737 radio signal strength indicators work fine. */
1738 .has_radio = 1,
1739 /* GPIO Info:
1740 GPIO0,1: HEF4052 A0,A1
1741 GPIO2: HEF4052 nENABLE
1742 GPIO3-7: n.c.
1743 GPIO8-13: IRDC357 data0-5 (data6 n.c. ?) [chip not present on my card]
1744 GPIO14,15: ??
1745 GPIO16-21: n.c.
1746 GPIO22,23: ??
1747 ?? : mtu8b56ep microcontroller for IR (GPIO wiring unknown)*/
1748 },
1749 [BTTV_BOARD_DSP_TCVIDEO] = {
1750 /* Arthur Tetzlaff-Deas, DSP Design Ltd <software@dspdesign.com> */
1751 .name = "DSP Design TCVIDEO",
1752 .video_inputs = 4,
1753 .svhs = -1,
1754 .muxsel = { 2, 3, 1, 0 },
1755 .pll = PLL_28,
1756 .tuner_type = -1,
1757 .tuner_addr = ADDR_UNSET,
1758 .radio_addr = ADDR_UNSET,
1759 },
1760
1761 /* ---- card 0x50 ---------------------------------- */
1762 [BTTV_BOARD_HAUPPAUGEPVR] = {
1763 .name = "Hauppauge WinTV PVR",
1764 .video_inputs = 4,
1765 .audio_inputs = 1,
1766 .tuner = 0,
1767 .svhs = 2,
1768 .muxsel = { 2, 0, 1, 1 },
1769 .needs_tvaudio = 1,
1770 .pll = PLL_28,
1771 .tuner_type = -1,
1772 .tuner_addr = ADDR_UNSET,
1773 .radio_addr = ADDR_UNSET,
1774
1775 .gpiomask = 7,
1776 .gpiomux = {7},
1777 },
1778 [BTTV_BOARD_GVBCTV5PCI] = {
1779 .name = "IODATA GV-BCTV5/PCI",
1780 .video_inputs = 3,
1781 .audio_inputs = 1,
1782 .tuner = 0,
1783 .svhs = 2,
1784 .gpiomask = 0x0f0f80,
1785 .muxsel = {2, 3, 1, 0 },
1786 .gpiomux = {0x030000, 0x010000, 0, 0 },
1787 .gpiomute = 0x020000,
1788 .no_msp34xx = 1,
1789 .pll = PLL_28,
1790 .tuner_type = TUNER_PHILIPS_NTSC_M,
1791 .tuner_addr = ADDR_UNSET,
1792 .radio_addr = ADDR_UNSET,
1793 .audio_hook = gvbctv5pci_audio,
1794 .has_radio = 1,
1795 },
1796 [BTTV_BOARD_OSPREY1x0] = {
1797 .name = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
1798 .video_inputs = 4, /* id-inputs-clock */
1799 .audio_inputs = 0,
1800 .tuner = -1,
1801 .svhs = 3,
1802 .muxsel = { 3, 2, 0, 1 },
1803 .pll = PLL_28,
1804 .tuner_type = -1,
1805 .tuner_addr = ADDR_UNSET,
1806 .radio_addr = ADDR_UNSET,
1807 .no_msp34xx = 1,
1808 .no_tda9875 = 1,
1809 .no_tda7432 = 1,
1810 },
1811 [BTTV_BOARD_OSPREY1x0_848] = {
1812 .name = "Osprey 100/150 (848)", /* 0x04-54C0-C1 & older boards */
1813 .video_inputs = 3,
1814 .audio_inputs = 0,
1815 .tuner = -1,
1816 .svhs = 2,
1817 .muxsel = { 2, 3, 1 },
1818 .pll = PLL_28,
1819 .tuner_type = -1,
1820 .tuner_addr = ADDR_UNSET,
1821 .radio_addr = ADDR_UNSET,
1822 .no_msp34xx = 1,
1823 .no_tda9875 = 1,
1824 .no_tda7432 = 1,
1825 },
1826
1827 /* ---- card 0x54 ---------------------------------- */
1828 [BTTV_BOARD_OSPREY101_848] = {
1829 .name = "Osprey 101 (848)", /* 0x05-40C0-C1 */
1830 .video_inputs = 2,
1831 .audio_inputs = 0,
1832 .tuner = -1,
1833 .svhs = 1,
1834 .muxsel = { 3, 1 },
1835 .pll = PLL_28,
1836 .tuner_type = -1,
1837 .tuner_addr = ADDR_UNSET,
1838 .radio_addr = ADDR_UNSET,
1839 .no_msp34xx = 1,
1840 .no_tda9875 = 1,
1841 .no_tda7432 = 1,
1842 },
1843 [BTTV_BOARD_OSPREY1x1] = {
1844 .name = "Osprey 101/151", /* 0x1(4|5)-0004-C4 */
1845 .video_inputs = 1,
1846 .audio_inputs = 0,
1847 .tuner = -1,
1848 .svhs = -1,
1849 .muxsel = { 0 },
1850 .pll = PLL_28,
1851 .tuner_type = -1,
1852 .tuner_addr = ADDR_UNSET,
1853 .radio_addr = ADDR_UNSET,
1854 .no_msp34xx = 1,
1855 .no_tda9875 = 1,
1856 .no_tda7432 = 1,
1857 },
1858 [BTTV_BOARD_OSPREY1x1_SVID] = {
1859 .name = "Osprey 101/151 w/ svid", /* 0x(16|17|20)-00C4-C1 */
1860 .video_inputs = 2,
1861 .audio_inputs = 0,
1862 .tuner = -1,
1863 .svhs = 1,
1864 .muxsel = { 0, 1 },
1865 .pll = PLL_28,
1866 .tuner_type = -1,
1867 .tuner_addr = ADDR_UNSET,
1868 .radio_addr = ADDR_UNSET,
1869 .no_msp34xx = 1,
1870 .no_tda9875 = 1,
1871 .no_tda7432 = 1,
1872 },
1873 [BTTV_BOARD_OSPREY2xx] = {
1874 .name = "Osprey 200/201/250/251", /* 0x1(8|9|E|F)-0004-C4 */
1875 .video_inputs = 1,
1876 .audio_inputs = 1,
1877 .tuner = -1,
1878 .svhs = -1,
1879 .muxsel = { 0 },
1880 .pll = PLL_28,
1881 .tuner_type = UNSET,
1882 .tuner_addr = ADDR_UNSET,
1883 .radio_addr = ADDR_UNSET,
1884 .no_msp34xx = 1,
1885 .no_tda9875 = 1,
1886 .no_tda7432 = 1,
1887 },
1888
1889 /* ---- card 0x58 ---------------------------------- */
1890 [BTTV_BOARD_OSPREY2x0_SVID] = {
1891 .name = "Osprey 200/250", /* 0x1(A|B)-00C4-C1 */
1892 .video_inputs = 2,
1893 .audio_inputs = 1,
1894 .tuner = -1,
1895 .svhs = 1,
1896 .muxsel = { 0, 1 },
1897 .pll = PLL_28,
1898 .tuner_type = UNSET,
1899 .tuner_addr = ADDR_UNSET,
1900 .radio_addr = ADDR_UNSET,
1901 .no_msp34xx = 1,
1902 .no_tda9875 = 1,
1903 .no_tda7432 = 1,
1904 },
1905 [BTTV_BOARD_OSPREY2x0] = {
1906 .name = "Osprey 210/220", /* 0x1(A|B)-04C0-C1 */
1907 .video_inputs = 2,
1908 .audio_inputs = 1,
1909 .tuner = -1,
1910 .svhs = 1,
1911 .muxsel = { 2, 3 },
1912 .pll = PLL_28,
1913 .tuner_type = UNSET,
1914 .tuner_addr = ADDR_UNSET,
1915 .radio_addr = ADDR_UNSET,
1916 .no_msp34xx = 1,
1917 .no_tda9875 = 1,
1918 .no_tda7432 = 1,
1919 },
1920 [BTTV_BOARD_OSPREY500] = {
1921 .name = "Osprey 500", /* 500 */
1922 .video_inputs = 2,
1923 .audio_inputs = 1,
1924 .tuner = -1,
1925 .svhs = 1,
1926 .muxsel = { 2, 3 },
1927 .pll = PLL_28,
1928 .tuner_type = -1,
1929 .tuner_addr = ADDR_UNSET,
1930 .radio_addr = ADDR_UNSET,
1931 .no_msp34xx = 1,
1932 .no_tda9875 = 1,
1933 .no_tda7432 = 1,
1934 },
1935 [BTTV_BOARD_OSPREY540] = {
1936 .name = "Osprey 540", /* 540 */
1937 .video_inputs = 4,
1938 .audio_inputs = 1,
1939 .tuner = -1,
1940 #if 0 /* TODO ... */
1941 .svhs = OSPREY540_SVID_ANALOG,
1942 .muxsel = { [OSPREY540_COMP_ANALOG] = 2,
1943 [OSPREY540_SVID_ANALOG] = 3, },
1944 #endif
1945 .pll = PLL_28,
1946 .tuner_type = -1,
1947 .tuner_addr = ADDR_UNSET,
1948 .radio_addr = ADDR_UNSET,
1949 .no_msp34xx = 1,
1950 .no_tda9875 = 1,
1951 .no_tda7432 = 1,
1952 #if 0 /* TODO ... */
1953 .muxsel_hook = osprey_540_muxsel,
1954 .picture_hook = osprey_540_set_picture,
1955 #endif
1956 },
1957
1958 /* ---- card 0x5C ---------------------------------- */
1959 [BTTV_BOARD_OSPREY2000] = {
1960 .name = "Osprey 2000", /* 2000 */
1961 .video_inputs = 2,
1962 .audio_inputs = 1,
1963 .tuner = -1,
1964 .svhs = 1,
1965 .muxsel = { 2, 3 },
1966 .pll = PLL_28,
1967 .tuner_type = UNSET,
1968 .tuner_addr = ADDR_UNSET,
1969 .radio_addr = ADDR_UNSET,
1970 .no_msp34xx = 1,
1971 .no_tda9875 = 1,
1972 .no_tda7432 = 1, /* must avoid, conflicts with the bt860 */
1973 },
1974 [BTTV_BOARD_IDS_EAGLE] = {
1975 /* M G Berberich <berberic@forwiss.uni-passau.de> */
1976 .name = "IDS Eagle",
1977 .video_inputs = 4,
1978 .audio_inputs = 0,
1979 .tuner = -1,
1980 .tuner_type = -1,
1981 .tuner_addr = ADDR_UNSET,
1982 .radio_addr = ADDR_UNSET,
1983 .svhs = -1,
1984 .gpiomask = 0,
1985 .muxsel = { 0, 1, 2, 3 },
1986 .muxsel_hook = eagle_muxsel,
1987 .no_msp34xx = 1,
1988 .no_tda9875 = 1,
1989 .pll = PLL_28,
1990 },
1991 [BTTV_BOARD_PINNACLESAT] = {
1992 .name = "Pinnacle PCTV Sat",
1993 .video_inputs = 2,
1994 .audio_inputs = 0,
1995 .svhs = 1,
1996 .tuner = -1,
1997 .tuner_type = -1,
1998 .tuner_addr = ADDR_UNSET,
1999 .radio_addr = ADDR_UNSET,
2000 .no_msp34xx = 1,
2001 .no_tda9875 = 1,
2002 .no_tda7432 = 1,
2003 .muxsel = { 3, 0, 1, 2 },
2004 .pll = PLL_28,
2005 .no_gpioirq = 1,
2006 .has_dvb = 1,
2007 },
2008 [BTTV_BOARD_FORMAC_PROTV] = {
2009 .name = "Formac ProTV II (bt878)",
2010 .video_inputs = 4,
2011 .audio_inputs = 1,
2012 .tuner = 0,
2013 .svhs = 3,
2014 .gpiomask = 2,
2015 /* TV, Comp1, Composite over SVID con, SVID */
2016 .muxsel = { 2, 3, 1, 1 },
2017 .gpiomux = { 2, 2, 0, 0 },
2018 .pll = PLL_28,
2019 .has_radio = 1,
2020 .tuner_type = TUNER_PHILIPS_PAL,
2021 .tuner_addr = ADDR_UNSET,
2022 .radio_addr = ADDR_UNSET,
2023 /* sound routing:
2024 GPIO=0x00,0x01,0x03: mute (?)
2025 0x02: both TV and radio (tuner: FM1216/I)
2026 The card has onboard audio connectors labeled "cdrom" and "board",
2027 not soldered here, though unknown wiring.
2028 Card lacks: external audio in, pci subsystem id.
2029 */
2030 },
2031
2032 /* ---- card 0x60 ---------------------------------- */
2033 [BTTV_BOARD_MACHTV] = {
2034 .name = "MachTV",
2035 .video_inputs = 3,
2036 .audio_inputs = 1,
2037 .tuner = 0,
2038 .svhs = -1,
2039 .gpiomask = 7,
2040 .muxsel = { 2, 3, 1, 1},
2041 .gpiomux = { 0, 1, 2, 3},
2042 .gpiomute = 4,
2043 .needs_tvaudio = 1,
2044 .tuner_type = 5,
2045 .tuner_addr = ADDR_UNSET,
2046 .radio_addr = ADDR_UNSET,
2047 .pll = PLL_28,
2048 },
2049 [BTTV_BOARD_EURESYS_PICOLO] = {
2050 .name = "Euresys Picolo",
2051 .video_inputs = 3,
2052 .audio_inputs = 0,
2053 .tuner = -1,
2054 .svhs = 2,
2055 .gpiomask = 0,
2056 .no_msp34xx = 1,
2057 .no_tda9875 = 1,
2058 .no_tda7432 = 1,
2059 .muxsel = { 2, 0, 1},
2060 .pll = PLL_28,
2061 .tuner_type = UNSET,
2062 .tuner_addr = ADDR_UNSET,
2063 .radio_addr = ADDR_UNSET,
2064 },
2065 [BTTV_BOARD_PV150] = {
2066 /* Luc Van Hoeylandt <luc@e-magic.be> */
2067 .name = "ProVideo PV150", /* 0x4f */
2068 .video_inputs = 2,
2069 .audio_inputs = 0,
2070 .tuner = -1,
2071 .svhs = -1,
2072 .gpiomask = 0,
2073 .muxsel = { 2, 3 },
2074 .gpiomux = { 0 },
2075 .needs_tvaudio = 0,
2076 .no_msp34xx = 1,
2077 .pll = PLL_28,
2078 .tuner_type = UNSET,
2079 .tuner_addr = ADDR_UNSET,
2080 .radio_addr = ADDR_UNSET,
2081 },
2082 [BTTV_BOARD_AD_TVK503] = {
2083 /* Hiroshi Takekawa <sian@big.or.jp> */
2084 /* This card lacks subsystem ID */
2085 .name = "AD-TVK503", /* 0x63 */
2086 .video_inputs = 4,
2087 .audio_inputs = 1,
2088 .tuner = 0,
2089 .svhs = 2,
2090 .gpiomask = 0x001e8007,
2091 .muxsel = { 2, 3, 1, 0 },
2092 /* Tuner, Radio, external, internal, off, on */
2093 .gpiomux = { 0x08, 0x0f, 0x0a, 0x08 },
2094 .gpiomute = 0x0f,
2095 .needs_tvaudio = 0,
2096 .no_msp34xx = 1,
2097 .pll = PLL_28,
2098 .tuner_type = 2,
2099 .tuner_addr = ADDR_UNSET,
2100 .radio_addr = ADDR_UNSET,
2101 .audio_hook = adtvk503_audio,
2102 },
2103
2104 /* ---- card 0x64 ---------------------------------- */
2105 [BTTV_BOARD_HERCULES_SM_TV] = {
2106 .name = "Hercules Smart TV Stereo",
2107 .video_inputs = 4,
2108 .audio_inputs = 1,
2109 .tuner = 0,
2110 .svhs = 2,
2111 .gpiomask = 0x00,
2112 .muxsel = { 2, 3, 1, 1 },
2113 .needs_tvaudio = 1,
2114 .no_msp34xx = 1,
2115 .pll = PLL_28,
2116 .tuner_type = 5,
2117 .tuner_addr = ADDR_UNSET,
2118 .radio_addr = ADDR_UNSET,
2119 /* Notes:
2120 - card lacks subsystem ID
2121 - stereo variant w/ daughter board with tda9874a @0xb0
2122 - Audio Routing:
2123 always from tda9874 independent of GPIO (?)
2124 external line in: unknown
2125 - Other chips: em78p156elp @ 0x96 (probably IR remote control)
2126 hef4053 (instead 4052) for unknown function
2127 */
2128 },
2129 [BTTV_BOARD_PACETV] = {
2130 .name = "Pace TV & Radio Card",
2131 .video_inputs = 4,
2132 .audio_inputs = 1,
2133 .tuner = 0,
2134 .svhs = 2,
2135 .muxsel = { 2, 3, 1, 1 }, /* Tuner, CVid, SVid, CVid over SVid connector */
2136 .gpiomask = 0,
2137 .no_tda9875 = 1,
2138 .no_tda7432 = 1,
2139 .tuner_type = 1,
2140 .tuner_addr = ADDR_UNSET,
2141 .radio_addr = ADDR_UNSET,
2142 .has_radio = 1,
2143 .pll = PLL_28,
2144 /* Bt878, Bt832, FI1246 tuner; no pci subsystem id
2145 only internal line out: (4pin header) RGGL
2146 Radio must be decoded by msp3410d (not routed through)*/
2147 /*
2148 .digital_mode = DIGITAL_MODE_CAMERA, todo!
2149 */
2150 },
2151 [BTTV_BOARD_IVC200] = {
2152 /* Chris Willing <chris@vislab.usyd.edu.au> */
2153 .name = "IVC-200",
2154 .video_inputs = 1,
2155 .audio_inputs = 0,
2156 .tuner = -1,
2157 .tuner_type = -1,
2158 .tuner_addr = ADDR_UNSET,
2159 .radio_addr = ADDR_UNSET,
2160 .svhs = -1,
2161 .gpiomask = 0xdf,
2162 .muxsel = { 2 },
2163 .pll = PLL_28,
2164 },
2165 [BTTV_BOARD_XGUARD] = {
2166 .name = "Grand X-Guard / Trust 814PCI",
2167 .video_inputs = 16,
2168 .audio_inputs = 0,
2169 .tuner = -1,
2170 .svhs = -1,
2171 .tuner_type = 4,
2172 .tuner_addr = ADDR_UNSET,
2173 .radio_addr = ADDR_UNSET,
2174 .gpiomask2 = 0xff,
2175 .muxsel = { 2,2,2,2, 3,3,3,3, 1,1,1,1, 0,0,0,0 },
2176 .muxsel_hook = xguard_muxsel,
2177 .no_msp34xx = 1,
2178 .no_tda9875 = 1,
2179 .no_tda7432 = 1,
2180 .pll = PLL_28,
2181 },
2182
2183 /* ---- card 0x68 ---------------------------------- */
2184 [BTTV_BOARD_NEBULA_DIGITV] = {
2185 .name = "Nebula Electronics DigiTV",
2186 .video_inputs = 1,
2187 .tuner = -1,
2188 .svhs = -1,
2189 .muxsel = { 2, 3, 1, 0 },
2190 .no_msp34xx = 1,
2191 .no_tda9875 = 1,
2192 .no_tda7432 = 1,
2193 .pll = PLL_28,
2194 .tuner_type = -1,
2195 .tuner_addr = ADDR_UNSET,
2196 .radio_addr = ADDR_UNSET,
2197 .has_dvb = 1,
2198 .has_remote = 1,
2199 .gpiomask = 0x1b,
2200 .no_gpioirq = 1,
2201 },
2202 [BTTV_BOARD_PV143] = {
2203 /* Jorge Boncompte - DTI2 <jorge@dti2.net> */
2204 .name = "ProVideo PV143",
2205 .video_inputs = 4,
2206 .audio_inputs = 0,
2207 .tuner = -1,
2208 .svhs = -1,
2209 .gpiomask = 0,
2210 .muxsel = { 2, 3, 1, 0 },
2211 .gpiomux = { 0 },
2212 .needs_tvaudio = 0,
2213 .no_msp34xx = 1,
2214 .pll = PLL_28,
2215 .tuner_type = -1,
2216 .tuner_addr = ADDR_UNSET,
2217 .radio_addr = ADDR_UNSET,
2218 },
2219 [BTTV_BOARD_VD009X1_MINIDIN] = {
2220 /* M.Klahr@phytec.de */
2221 .name = "PHYTEC VD-009-X1 MiniDIN (bt878)",
2222 .video_inputs = 4,
2223 .audio_inputs = 0,
2224 .tuner = -1, /* card has no tuner */
2225 .svhs = 3,
2226 .gpiomask = 0x00,
2227 .muxsel = { 2, 3, 1, 0 },
2228 .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
2229 .needs_tvaudio = 1,
2230 .pll = PLL_28,
2231 .tuner_type = -1,
2232 .tuner_addr = ADDR_UNSET,
2233 .radio_addr = ADDR_UNSET,
2234 },
2235 [BTTV_BOARD_VD009X1_COMBI] = {
2236 .name = "PHYTEC VD-009-X1 Combi (bt878)",
2237 .video_inputs = 4,
2238 .audio_inputs = 0,
2239 .tuner = -1, /* card has no tuner */
2240 .svhs = 3,
2241 .gpiomask = 0x00,
2242 .muxsel = { 2, 3, 1, 1 },
2243 .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
2244 .needs_tvaudio = 1,
2245 .pll = PLL_28,
2246 .tuner_type = -1,
2247 .tuner_addr = ADDR_UNSET,
2248 .radio_addr = ADDR_UNSET,
2249 },
2250
2251 /* ---- card 0x6c ---------------------------------- */
2252 [BTTV_BOARD_VD009_MINIDIN] = {
2253 .name = "PHYTEC VD-009 MiniDIN (bt878)",
2254 .video_inputs = 10,
2255 .audio_inputs = 0,
2256 .tuner = -1, /* card has no tuner */
2257 .svhs = 9,
2258 .gpiomask = 0x00,
2259 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
2260 via the upper nibble of muxsel. here: used for
2261 xternal video-mux */
2262 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x00 },
2263 .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
2264 .needs_tvaudio = 1,
2265 .pll = PLL_28,
2266 .tuner_type = -1,
2267 .tuner_addr = ADDR_UNSET,
2268 .radio_addr = ADDR_UNSET,
2269 },
2270 [BTTV_BOARD_VD009_COMBI] = {
2271 .name = "PHYTEC VD-009 Combi (bt878)",
2272 .video_inputs = 10,
2273 .audio_inputs = 0,
2274 .tuner = -1, /* card has no tuner */
2275 .svhs = 9,
2276 .gpiomask = 0x00,
2277 .gpiomask2 = 0x03, /* gpiomask2 defines the bits used to switch audio
2278 via the upper nibble of muxsel. here: used for
2279 xternal video-mux */
2280 .muxsel = { 0x02, 0x12, 0x22, 0x32, 0x03, 0x13, 0x23, 0x33, 0x01, 0x01 },
2281 .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
2282 .needs_tvaudio = 1,
2283 .pll = PLL_28,
2284 .tuner_type = -1,
2285 .tuner_addr = ADDR_UNSET,
2286 .radio_addr = ADDR_UNSET,
2287 },
2288 [BTTV_BOARD_IVC100] = {
2289 .name = "IVC-100",
2290 .video_inputs = 4,
2291 .audio_inputs = 0,
2292 .tuner = -1,
2293 .tuner_type = -1,
2294 .tuner_addr = ADDR_UNSET,
2295 .radio_addr = ADDR_UNSET,
2296 .svhs = -1,
2297 .gpiomask = 0xdf,
2298 .muxsel = { 2, 3, 1, 0 },
2299 .pll = PLL_28,
2300 },
2301 [BTTV_BOARD_IVC120] = {
2302 /* IVC-120G - Alan Garfield <alan@fromorbit.com> */
2303 .name = "IVC-120G",
2304 .video_inputs = 16,
2305 .audio_inputs = 0, /* card has no audio */
2306 .tuner = -1, /* card has no tuner */
2307 .tuner_type = -1,
2308 .tuner_addr = ADDR_UNSET,
2309 .radio_addr = ADDR_UNSET,
2310 .svhs = -1, /* card has no svhs */
2311 .needs_tvaudio = 0,
2312 .no_msp34xx = 1,
2313 .no_tda9875 = 1,
2314 .no_tda7432 = 1,
2315 .gpiomask = 0x00,
2316 .muxsel = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
2317 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 },
2318 .muxsel_hook = ivc120_muxsel,
2319 .pll = PLL_28,
2320 },
2321
2322 /* ---- card 0x70 ---------------------------------- */
2323 [BTTV_BOARD_PC_HDTV] = {
2324 .name = "pcHDTV HD-2000 TV",
2325 .video_inputs = 4,
2326 .audio_inputs = 1,
2327 .tuner = 0,
2328 .svhs = 2,
2329 .muxsel = { 2, 3, 1, 0 },
2330 .tuner_type = TUNER_PHILIPS_ATSC,
2331 .tuner_addr = ADDR_UNSET,
2332 .radio_addr = ADDR_UNSET,
2333 .has_dvb = 1,
2334 },
2335 [BTTV_BOARD_TWINHAN_DST] = {
2336 .name = "Twinhan DST + clones",
2337 .no_msp34xx = 1,
2338 .no_tda9875 = 1,
2339 .no_tda7432 = 1,
2340 .tuner_type = TUNER_ABSENT,
2341 .tuner_addr = ADDR_UNSET,
2342 .radio_addr = ADDR_UNSET,
2343 .no_video = 1,
2344 .has_dvb = 1,
2345 },
2346 [BTTV_BOARD_WINFASTVC100] = {
2347 .name = "Winfast VC100",
2348 .video_inputs = 3,
2349 .audio_inputs = 0,
2350 .svhs = 1,
2351 .tuner = -1,
2352 .muxsel = { 3, 1, 1, 3 }, /* Vid In, SVid In, Vid over SVid in connector */
2353 .no_msp34xx = 1,
2354 .no_tda9875 = 1,
2355 .no_tda7432 = 1,
2356 .tuner_type = TUNER_ABSENT,
2357 .tuner_addr = ADDR_UNSET,
2358 .radio_addr = ADDR_UNSET,
2359 .pll = PLL_28,
2360 },
2361 [BTTV_BOARD_TEV560] = {
2362 .name = "Teppro TEV-560/InterVision IV-560",
2363 .video_inputs = 3,
2364 .audio_inputs = 1,
2365 .tuner = 0,
2366 .svhs = 2,
2367 .gpiomask = 3,
2368 .muxsel = { 2, 3, 1, 1 },
2369 .gpiomux = { 1, 1, 1, 1 },
2370 .needs_tvaudio = 1,
2371 .tuner_type = TUNER_PHILIPS_PAL,
2372 .tuner_addr = ADDR_UNSET,
2373 .radio_addr = ADDR_UNSET,
2374 .pll = PLL_35,
2375 },
2376
2377 /* ---- card 0x74 ---------------------------------- */
2378 [BTTV_BOARD_SIMUS_GVC1100] = {
2379 .name = "SIMUS GVC1100",
2380 .video_inputs = 4,
2381 .audio_inputs = 0,
2382 .tuner = -1,
2383 .svhs = -1,
2384 .tuner_type = -1,
2385 .tuner_addr = ADDR_UNSET,
2386 .radio_addr = ADDR_UNSET,
2387 .pll = PLL_28,
2388 .muxsel = { 2, 2, 2, 2 },
2389 .gpiomask = 0x3F,
2390 .muxsel_hook = gvc1100_muxsel,
2391 },
2392 [BTTV_BOARD_NGSTV_PLUS] = {
2393 /* Carlos Silva r3pek@r3pek.homelinux.org || card 0x75 */
2394 .name = "NGS NGSTV+",
2395 .video_inputs = 3,
2396 .tuner = 0,
2397 .svhs = 2,
2398 .gpiomask = 0x008007,
2399 .muxsel = { 2, 3, 0, 0 },
2400 .gpiomux = { 0, 0, 0, 0 },
2401 .gpiomute = 0x000003,
2402 .pll = PLL_28,
2403 .tuner_type = TUNER_PHILIPS_PAL,
2404 .tuner_addr = ADDR_UNSET,
2405 .radio_addr = ADDR_UNSET,
2406 .has_remote = 1,
2407 },
2408 [BTTV_BOARD_LMLBT4] = {
2409 /* http://linuxmedialabs.com */
2410 .name = "LMLBT4",
2411 .video_inputs = 4, /* IN1,IN2,IN3,IN4 */
2412 .audio_inputs = 0,
2413 .tuner = -1,
2414 .svhs = -1,
2415 .muxsel = { 2, 3, 1, 0 },
2416 .no_msp34xx = 1,
2417 .no_tda9875 = 1,
2418 .no_tda7432 = 1,
2419 .needs_tvaudio = 0,
2420 .tuner_type = -1,
2421 .tuner_addr = ADDR_UNSET,
2422 .radio_addr = ADDR_UNSET,
2423 },
2424 [BTTV_BOARD_TEKRAM_M205] = {
2425 /* Helmroos Harri <harri.helmroos@pp.inet.fi> */
2426 .name = "Tekram M205 PRO",
2427 .video_inputs = 3,
2428 .audio_inputs = 1,
2429 .tuner = 0,
2430 .tuner_type = TUNER_PHILIPS_PAL,
2431 .tuner_addr = ADDR_UNSET,
2432 .radio_addr = ADDR_UNSET,
2433 .svhs = 2,
2434 .needs_tvaudio = 0,
2435 .gpiomask = 0x68,
2436 .muxsel = { 2, 3, 1 },
2437 .gpiomux = { 0x68, 0x68, 0x61, 0x61 },
2438 .pll = PLL_28,
2439 },
2440
2441 /* ---- card 0x78 ---------------------------------- */
2442 [BTTV_BOARD_CONTVFMI] = {
2443 /* Javier Cendan Ares <jcendan@lycos.es> */
2444 /* bt878 TV + FM without subsystem ID */
2445 .name = "Conceptronic CONTVFMi",
2446 .video_inputs = 3,
2447 .audio_inputs = 1,
2448 .tuner = 0,
2449 .svhs = 2,
2450 .gpiomask = 0x008007,
2451 .muxsel = { 2, 3, 1, 1 },
2452 .gpiomux = { 0, 1, 2, 2 },
2453 .gpiomute = 3,
2454 .needs_tvaudio = 0,
2455 .pll = PLL_28,
2456 .tuner_type = TUNER_PHILIPS_PAL,
2457 .tuner_addr = ADDR_UNSET,
2458 .radio_addr = ADDR_UNSET,
2459 .has_remote = 1,
2460 .has_radio = 1,
2461 },
2462 [BTTV_BOARD_PICOLO_TETRA_CHIP] = {
2463 /*Eric DEBIEF <debief@telemsa.com>*/
2464 /*EURESYS Picolo Tetra : 4 Conexant Fusion 878A, no audio, video input set with analog multiplexers GPIO controled*/
2465 /* adds picolo_tetra_muxsel(), picolo_tetra_init(), the folowing declaration strucure, and #define BTTV_BOARD_PICOLO_TETRA_CHIP*/
2466 /*0x79 in bttv.h*/
2467 .name = "Euresys Picolo Tetra",
2468 .video_inputs = 4,
2469 .audio_inputs = 0,
2470 .tuner = -1,
2471 .svhs = -1,
2472 .gpiomask = 0,
2473 .gpiomask2 = 0x3C<<16,/*Set the GPIO[18]->GPIO[21] as output pin.==> drive the video inputs through analog multiplexers*/
2474 .no_msp34xx = 1,
2475 .no_tda9875 = 1,
2476 .no_tda7432 = 1,
2477 .muxsel = {2,2,2,2},/*878A input is always MUX0, see above.*/
2478 .gpiomux = { 0, 0, 0, 0 }, /* card has no audio */
2479 .pll = PLL_28,
2480 .needs_tvaudio = 0,
2481 .muxsel_hook = picolo_tetra_muxsel,/*Required as it doesn't follow the classic input selection policy*/
2482 .tuner_type = -1,
2483 .tuner_addr = ADDR_UNSET,
2484 .radio_addr = ADDR_UNSET,
2485 },
2486 [BTTV_BOARD_SPIRIT_TV] = {
2487 /* Spirit TV Tuner from http://spiritmodems.com.au */
2488 /* Stafford Goodsell <surge@goliath.homeunix.org> */
2489 .name = "Spirit TV Tuner",
2490 .video_inputs = 3,
2491 .audio_inputs = 1,
2492 .tuner = 0,
2493 .svhs = 2,
2494 .gpiomask = 0x0000000f,
2495 .muxsel = { 2, 1, 1 },
2496 .gpiomux = { 0x02, 0x00, 0x00, 0x00 },
2497 .tuner_type = TUNER_TEMIC_PAL,
2498 .tuner_addr = ADDR_UNSET,
2499 .radio_addr = ADDR_UNSET,
2500 .no_msp34xx = 1,
2501 .no_tda9875 = 1,
2502 },
2503 [BTTV_BOARD_AVDVBT_771] = {
2504 /* Wolfram Joost <wojo@frokaschwei.de> */
2505 .name = "AVerMedia AVerTV DVB-T 771",
2506 .video_inputs = 2,
2507 .svhs = 1,
2508 .tuner = -1,
2509 .tuner_type = TUNER_ABSENT,
2510 .tuner_addr = ADDR_UNSET,
2511 .radio_addr = ADDR_UNSET,
2512 .muxsel = { 3 , 3 },
2513 .no_msp34xx = 1,
2514 .no_tda9875 = 1,
2515 .no_tda7432 = 1,
2516 .pll = PLL_28,
2517 .has_dvb = 1,
2518 .no_gpioirq = 1,
2519 .has_remote = 1,
2520 },
2521 /* ---- card 0x7c ---------------------------------- */
2522 [BTTV_BOARD_AVDVBT_761] = {
2523 /* Matt Jesson <dvb@jesson.eclipse.co.uk> */
2524 /* Based on the Nebula card data - added remote and new card number - BTTV_BOARD_AVDVBT_761, see also ir-kbd-gpio.c */
2525 .name = "AverMedia AverTV DVB-T 761",
2526 .video_inputs = 2,
2527 .tuner = -1,
2528 .svhs = 1,
2529 .muxsel = { 3, 1, 2, 0 }, /* Comp0, S-Video, ?, ? */
2530 .no_msp34xx = 1,
2531 .no_tda9875 = 1,
2532 .no_tda7432 = 1,
2533 .pll = PLL_28,
2534 .tuner_type = -1,
2535 .tuner_addr = ADDR_UNSET,
2536 .radio_addr = ADDR_UNSET,
2537 .has_dvb = 1,
2538 .no_gpioirq = 1,
2539 .has_remote = 1,
2540 },
2541 [BTTV_BOARD_MATRIX_VISIONSQ] = {
2542 /* andre.schwarz@matrix-vision.de */
2543 .name = "MATRIX Vision Sigma-SQ",
2544 .video_inputs = 16,
2545 .audio_inputs = 0,
2546 .tuner = -1,
2547 .svhs = -1,
2548 .gpiomask = 0x0,
2549 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2,
2550 3, 3, 3, 3, 3, 3, 3, 3 },
2551 .muxsel_hook = sigmaSQ_muxsel,
2552 .gpiomux = { 0 },
2553 .no_msp34xx = 1,
2554 .pll = PLL_28,
2555 .tuner_type = -1,
2556 .tuner_addr = ADDR_UNSET,
2557 .radio_addr = ADDR_UNSET,
2558 },
2559 [BTTV_BOARD_MATRIX_VISIONSLC] = {
2560 /* andre.schwarz@matrix-vision.de */
2561 .name = "MATRIX Vision Sigma-SLC",
2562 .video_inputs = 4,
2563 .audio_inputs = 0,
2564 .tuner = -1,
2565 .svhs = -1,
2566 .gpiomask = 0x0,
2567 .muxsel = { 2, 2, 2, 2 },
2568 .muxsel_hook = sigmaSLC_muxsel,
2569 .gpiomux = { 0 },
2570 .no_msp34xx = 1,
2571 .pll = PLL_28,
2572 .tuner_type = -1,
2573 .tuner_addr = ADDR_UNSET,
2574 .radio_addr = ADDR_UNSET,
2575 },
2576 /* BTTV_BOARD_APAC_VIEWCOMP */
2577 [BTTV_BOARD_APAC_VIEWCOMP] = {
2578 /* Attila Kondoros <attila.kondoros@chello.hu> */
2579 /* bt878 TV + FM 0x00000000 subsystem ID */
2580 .name = "APAC Viewcomp 878(AMAX)",
2581 .video_inputs = 2,
2582 .audio_inputs = 1,
2583 .tuner = 0,
2584 .svhs = -1,
2585 .gpiomask = 0xFF,
2586 .muxsel = { 2, 3, 1, 1 },
2587 .gpiomux = { 2, 0, 0, 0 },
2588 .gpiomute = 10,
2589 .needs_tvaudio = 0,
2590 .pll = PLL_28,
2591 .tuner_type = TUNER_PHILIPS_PAL,
2592 .tuner_addr = ADDR_UNSET,
2593 .radio_addr = ADDR_UNSET,
2594 .has_remote = 1, /* miniremote works, see ir-kbd-gpio.c */
2595 .has_radio = 1, /* not every card has radio */
2596 },
2597
2598 /* ---- card 0x80 ---------------------------------- */
2599 [BTTV_BOARD_DVICO_DVBT_LITE] = {
2600 /* Chris Pascoe <c.pascoe@itee.uq.edu.au> */
2601 .name = "DViCO FusionHDTV DVB-T Lite",
2602 .tuner = -1,
2603 .no_msp34xx = 1,
2604 .no_tda9875 = 1,
2605 .no_tda7432 = 1,
2606 .pll = PLL_28,
2607 .no_video = 1,
2608 .has_dvb = 1,
2609 .tuner_type = -1,
2610 .tuner_addr = ADDR_UNSET,
2611 .radio_addr = ADDR_UNSET,
2612 },
2613 [BTTV_BOARD_VGEAR_MYVCD] = {
2614 /* Steven <photon38@pchome.com.tw> */
2615 .name = "V-Gear MyVCD",
2616 .video_inputs = 3,
2617 .audio_inputs = 1,
2618 .tuner = 0,
2619 .svhs = 2,
2620 .gpiomask = 0x3f,
2621 .muxsel = {2, 3, 1, 0 },
2622 .gpiomux = {0x31, 0x31, 0x31, 0x31 },
2623 .gpiomute = 0x31,
2624 .no_msp34xx = 1,
2625 .pll = PLL_28,
2626 .tuner_type = TUNER_PHILIPS_NTSC_M,
2627 .tuner_addr = ADDR_UNSET,
2628 .radio_addr = ADDR_UNSET,
2629 .has_radio = 0,
2630 #if 0
2631 .has_remote = 1,
2632 #endif
2633 },
2634 [BTTV_BOARD_SUPER_TV] = {
2635 /* Rick C <cryptdragoon@gmail.com> */
2636 .name = "Super TV Tuner",
2637 .video_inputs = 4,
2638 .audio_inputs = 1,
2639 .tuner = 0,
2640 .svhs = 2,
2641 .muxsel = { 2, 3, 1, 0 },
2642 .tuner_type = TUNER_PHILIPS_NTSC,
2643 .tuner_addr = ADDR_UNSET,
2644 .radio_addr = ADDR_UNSET,
2645 .gpiomask = 0x008007,
2646 .gpiomux = { 0, 0x000001,0,0 },
2647 .needs_tvaudio = 1,
2648 .has_radio = 1,
2649 },
2650 [BTTV_BOARD_TIBET_CS16] = {
2651 /* Chris Fanning <video4linux@haydon.net> */
2652 .name = "Tibet Systems 'Progress DVR' CS16",
2653 .video_inputs = 16,
2654 .audio_inputs = 0,
2655 .tuner = -1,
2656 .svhs = -1,
2657 .muxsel = { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
2658 .pll = PLL_28,
2659 .no_msp34xx = 1,
2660 .no_tda9875 = 1,
2661 .no_tda7432 = 1,
2662 .tuner_type = -1,
2663 .tuner_addr = ADDR_UNSET,
2664 .radio_addr = ADDR_UNSET,
2665 .muxsel_hook = tibetCS16_muxsel,
2666 },
2667 [BTTV_BOARD_KODICOM_4400R] = {
2668 /* Bill Brack <wbrack@mmm.com.hk> */
2669 /*
2670 * Note that, because of the card's wiring, the "master"
2671 * BT878A chip (i.e. the one which controls the analog switch
2672 * and must use this card type) is the 2nd one detected. The
2673 * other 3 chips should use card type 0x85, whose description
2674 * follows this one. There is a EEPROM on the card (which is
2675 * connected to the I2C of one of those other chips), but is
2676 * not currently handled. There is also a facility for a
2677 * "monitor", which is also not currently implemented.
2678 */
2679 .name = "Kodicom 4400R (master)",
2680 .video_inputs = 16,
2681 .audio_inputs = 0,
2682 .tuner = -1,
2683 .tuner_type = -1,
2684 .tuner_addr = ADDR_UNSET,
2685 .radio_addr = ADDR_UNSET,
2686 .svhs = -1,
2687 /* GPIO bits 0-9 used for analog switch:
2688 * 00 - 03: camera selector
2689 * 04 - 06: channel (controller) selector
2690 * 07: data (1->on, 0->off)
2691 * 08: strobe
2692 * 09: reset
2693 * bit 16 is input from sync separator for the channel
2694 */
2695 .gpiomask = 0x0003ff,
2696 .no_gpioirq = 1,
2697 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2698 .pll = PLL_28,
2699 .no_msp34xx = 1,
2700 .no_tda7432 = 1,
2701 .no_tda9875 = 1,
2702 .muxsel_hook = kodicom4400r_muxsel,
2703 },
2704 [BTTV_BOARD_KODICOM_4400R_SL] = {
2705 /* Bill Brack <wbrack@mmm.com.hk> */
2706 /* Note that, for reasons unknown, the "master" BT878A chip (i.e. the
2707 * one which controls the analog switch, and must use the card type)
2708 * is the 2nd one detected. The other 3 chips should use this card
2709 * type
2710 */
2711 .name = "Kodicom 4400R (slave)",
2712 .video_inputs = 16,
2713 .audio_inputs = 0,
2714 .tuner = -1,
2715 .tuner_type = -1,
2716 .tuner_addr = ADDR_UNSET,
2717 .radio_addr = ADDR_UNSET,
2718 .svhs = -1,
2719 .gpiomask = 0x010000,
2720 .no_gpioirq = 1,
2721 .muxsel = { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 },
2722 .pll = PLL_28,
2723 .no_msp34xx = 1,
2724 .no_tda7432 = 1,
2725 .no_tda9875 = 1,
2726 .muxsel_hook = kodicom4400r_muxsel,
2727 },
2728 /* ---- card 0x86---------------------------------- */
2729 [BTTV_BOARD_ADLINK_RTV24] = {
2730 /* Michael Henson <mhenson@clarityvi.com> */
2731 /* Adlink RTV24 with special unlock codes */
2732 .name = "Adlink RTV24",
2733 .video_inputs = 4,
2734 .audio_inputs = 1,
2735 .tuner = 0,
2736 .svhs = 2,
2737 .muxsel = { 2, 3, 1, 0 },
2738 .tuner_type = -1,
2739 .tuner_addr = ADDR_UNSET,
2740 .radio_addr = ADDR_UNSET,
2741 .pll = PLL_28,
2742 },
2743 /* ---- card 0x87---------------------------------- */
2744 [BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE] = {
2745 /* Michael Krufky <mkrufky@m1k.net> */
2746 .name = "DViCO FusionHDTV 5 Lite",
2747 .tuner = 0,
2748 .tuner_type = TUNER_LG_TDVS_H062F,
2749 .tuner_addr = ADDR_UNSET,
2750 .radio_addr = ADDR_UNSET,
2751 .video_inputs = 3,
2752 .audio_inputs = 1,
2753 .svhs = 2,
2754 .muxsel = { 2, 3, 1 },
2755 .gpiomask = 0x00e00007,
2756 .gpiomux = { 0x00400005, 0, 0x00000001, 0 },
2757 .gpiomute = 0x00c00007,
2758 .no_msp34xx = 1,
2759 .no_tda9875 = 1,
2760 .no_tda7432 = 1,
2761 .has_dvb = 1,
2762 },
2763 /* ---- card 0x88---------------------------------- */
2764 [BTTV_BOARD_ACORP_Y878F] = {
2765 /* Mauro Carvalho Chehab <mchehab@brturbo.com.br> */
2766 .name = "Acorp Y878F",
2767 .video_inputs = 3,
2768 .audio_inputs = 1,
2769 .tuner = 0,
2770 .svhs = 2,
2771 .gpiomask = 0x01fe00,
2772 .muxsel = { 2, 3, 1, 1 },
2773 .gpiomux = { 0x001e00, 0, 0x018000, 0x014000 },
2774 .gpiomute = 0x002000,
2775 .needs_tvaudio = 1,
2776 .pll = PLL_28,
2777 .tuner_type = TUNER_YMEC_TVF66T5_B_DFF,
2778 .tuner_addr = 0xc1 >>1,
2779 .radio_addr = 0xc1 >>1,
2780 .has_radio = 1,
2781 },
2782 /* ---- card 0x89 ---------------------------------- */
2783 [BTTV_BOARD_CONCEPTRONIC_CTVFMI2] = {
2784 .name = "Conceptronic CTVFMi v2",
2785 .video_inputs = 3,
2786 .audio_inputs = 1,
2787 .tuner = 0,
2788 .svhs = 2,
2789 .gpiomask = 0x001c0007,
2790 .muxsel = { 2, 3, 1, 1 },
2791 .gpiomux = { 0, 1, 2, 2 },
2792 .gpiomute = 3,
2793 .needs_tvaudio = 0,
2794 .pll = PLL_28,
2795 .tuner_type = TUNER_TENA_9533_DI,
2796 .tuner_addr = ADDR_UNSET,
2797 .radio_addr = ADDR_UNSET,
2798 .has_remote = 1,
2799 .has_radio = 1,
2800 },
2801 /* ---- card 0x8a ---------------------------------- */
2802 [BTTV_BOARD_PV_BT878P_2E] = {
2803 .name = "Prolink Pixelview PV-BT878P+ (Rev.2E)",
2804 .video_inputs = 5,
2805 .audio_inputs = 1,
2806 .tuner = 0,
2807 .svhs = 3,
2808 .gpiomask = 0x01fe00,
2809 .muxsel = { 2,3,1,1,-1 },
2810 .digital_mode = DIGITAL_MODE_CAMERA,
2811 .gpiomux = { 0x00400, 0x10400, 0x04400, 0x80000 },
2812 .gpiomute = 0x12400,
2813 .no_msp34xx = 1,
2814 .pll = PLL_28,
2815 .tuner_type = TUNER_LG_PAL_FM,
2816 .tuner_addr = ADDR_UNSET,
2817 .radio_addr = ADDR_UNSET,
2818 .has_remote = 1,
2819 },
2820 /* ---- card 0x8b ---------------------------------- */
2821 [BTTV_BOARD_PV_M4900] = {
2822 /* Sérgio Fortier <sergiofortier@yahoo.com.br> */
2823 .name = "Prolink PixelView PlayTV MPEG2 PV-M4900",
2824 .video_inputs = 3,
2825 .audio_inputs = 1,
2826 .tuner = 0,
2827 .svhs = 2,
2828 .gpiomask = 0x3f,
2829 .muxsel = { 2, 3, 1, 1 },
2830 .gpiomux = { 0x21, 0x20, 0x24, 0x2c },
2831 .gpiomute = 0x29,
2832 .no_msp34xx = 1,
2833 .pll = PLL_28,
2834 .tuner_type = TUNER_YMEC_TVF_5533MF,
2835 .tuner_addr = ADDR_UNSET,
2836 .radio_addr = ADDR_UNSET,
2837 .has_radio = 1,
2838 .has_remote = 1,
2839 },
2840 /* ---- card 0x8c ---------------------------------- */
2841 [BTTV_BOARD_OSPREY440] = {
2842 .name = "Osprey 440",
2843 .video_inputs = 1,
2844 .audio_inputs = 1,
2845 .tuner = -1,
2846 .svhs = 1,
2847 .muxsel = { 2 },
2848 .pll = PLL_28,
2849 .tuner_type = UNSET,
2850 .tuner_addr = ADDR_UNSET,
2851 .radio_addr = ADDR_UNSET,
2852 .no_msp34xx = 1,
2853 .no_tda9875 = 1,
2854 .no_tda7432 = 1,
2855 },
2856 /* ---- card 0x8d ---------------------------------- */
2857 [BTTV_BOARD_ASOUND_SKYEYE] = {
2858 .name = "Asound Skyeye PCTV",
2859 .video_inputs = 3,
2860 .audio_inputs = 1,
2861 .tuner = 0,
2862 .svhs = 2,
2863 .gpiomask = 15,
2864 .muxsel = { 2, 3, 1, 1 },
2865 .gpiomux = { 2, 0, 0, 0 },
2866 .gpiomute = 1,
2867 .needs_tvaudio = 1,
2868 .pll = PLL_28,
2869 .tuner_type = 2,
2870 .tuner_addr = ADDR_UNSET,
2871 .radio_addr = ADDR_UNSET,
2872 },
2873 /* ---- card 0x8e ---------------------------------- */
2874 [BTTV_BOARD_SABRENT_TVFM] = {
2875 .name = "Sabrent TV-FM (bttv version)",
2876 .video_inputs = 3,
2877 .audio_inputs = 1,
2878 .tuner = 0,
2879 .svhs = 2,
2880 .gpiomask = 0x108007,
2881 .muxsel = { 2, 3, 1, 1 },
2882 .gpiomux = { 100000, 100002, 100002, 100000 },
2883 .no_msp34xx = 1,
2884 .no_tda9875 = 1,
2885 .no_tda7432 = 1,
2886 .pll = PLL_28,
2887 .tuner_type = TUNER_TNF_5335MF,
2888 .tuner_addr = ADDR_UNSET,
2889 .has_radio = 1,
2890 },
2891 /* ---- card 0x8f ---------------------------------- */
2892 [BTTV_BOARD_HAUPPAUGE_IMPACTVCB] = {
2893 .name = "Hauppauge ImpactVCB (bt878)",
2894 .video_inputs = 4,
2895 .audio_inputs = 0,
2896 .tuner = -1,
2897 .svhs = -1,
2898 .gpiomask = 0x0f, /* old: 7 */
2899 .muxsel = { 0, 1, 3, 2 }, /* Composite 0-3 */
2900 .no_msp34xx = 1,
2901 .no_tda9875 = 1,
2902 .no_tda7432 = 1,
2903 .tuner_type = -1,
2904 .tuner_addr = ADDR_UNSET,
2905 .radio_addr = ADDR_UNSET,
2906 },
2907 [BTTV_BOARD_MACHTV_MAGICTV] = {
2908 /* Julian Calaby <julian.calaby@gmail.com>
2909 * Slightly different from original MachTV definition (0x60)
2910
2911 * FIXME: RegSpy says gpiomask should be "0x001c800f", but it
2912 * stuffs up remote chip. Bug is a pin on the jaecs is not set
2913 * properly (methinks) causing no keyup bits being set */
2914
2915 .name = "MagicTV", /* rebranded MachTV */
2916 .video_inputs = 3,
2917 .audio_inputs = 1,
2918 .tuner = 0,
2919 .svhs = 2,
2920 .gpiomask = 7,
2921 .muxsel = { 2, 3, 1, 1 },
2922 .gpiomux = { 0, 1, 2, 3 },
2923 .gpiomute = 4,
2924 .tuner_type = TUNER_TEMIC_4009FR5_PAL,
2925 .tuner_addr = ADDR_UNSET,
2926 .radio_addr = ADDR_UNSET,
2927 .pll = PLL_28,
2928 .has_radio = 1,
2929 .has_remote = 1,
2930 },
2931};
2932
2933static const unsigned int bttv_num_tvcards = ARRAY_SIZE(bttv_tvcards);
2934
2935/* ----------------------------------------------------------------------- */
2936
2937static unsigned char eeprom_data[256];
2938
2939/*
2940 * identify card
2941 */
2942void __devinit bttv_idcard(struct bttv *btv)
2943{
2944 unsigned int gpiobits;
2945 int i,type;
2946 unsigned short tmp;
2947
2948 /* read PCI subsystem ID */
2949 pci_read_config_word(btv->c.pci, PCI_SUBSYSTEM_ID, &tmp);
2950 btv->cardid = tmp << 16;
2951 pci_read_config_word(btv->c.pci, PCI_SUBSYSTEM_VENDOR_ID, &tmp);
2952 btv->cardid |= tmp;
2953
2954 if (0 != btv->cardid && 0xffffffff != btv->cardid) {
2955 /* look for the card */
2956 for (type = -1, i = 0; cards[i].id != 0; i++)
2957 if (cards[i].id == btv->cardid)
2958 type = i;
2959
2960 if (type != -1) {
2961 /* found it */
2962 printk(KERN_INFO "bttv%d: detected: %s [card=%d], "
2963 "PCI subsystem ID is %04x:%04x\n",
2964 btv->c.nr,cards[type].name,cards[type].cardnr,
2965 btv->cardid & 0xffff,
2966 (btv->cardid >> 16) & 0xffff);
2967 btv->c.type = cards[type].cardnr;
2968 } else {
2969 /* 404 */
2970 printk(KERN_INFO "bttv%d: subsystem: %04x:%04x (UNKNOWN)\n",
2971 btv->c.nr, btv->cardid & 0xffff,
2972 (btv->cardid >> 16) & 0xffff);
2973 printk(KERN_DEBUG "please mail id, board name and "
2974 "the correct card= insmod option to video4linux-list@redhat.com\n");
2975 }
2976 }
2977
2978 /* let the user override the autodetected type */
2979 if (card[btv->c.nr] < bttv_num_tvcards)
2980 btv->c.type=card[btv->c.nr];
2981
2982 /* print which card config we are using */
2983 printk(KERN_INFO "bttv%d: using: %s [card=%d,%s]\n",btv->c.nr,
2984 bttv_tvcards[btv->c.type].name, btv->c.type,
2985 card[btv->c.nr] < bttv_num_tvcards
2986 ? "insmod option" : "autodetected");
2987
2988 /* overwrite gpio stuff ?? */
2989 if (UNSET == audioall && UNSET == audiomux[0])
2990 return;
2991
2992 if (UNSET != audiomux[0]) {
2993 gpiobits = 0;
2994 for (i = 0; i < 5; i++) {
2995 bttv_tvcards[btv->c.type].gpiomux[i] = audiomux[i];
2996 gpiobits |= audiomux[i];
2997 }
2998 } else {
2999 gpiobits = audioall;
3000 for (i = 0; i < 5; i++) {
3001 bttv_tvcards[btv->c.type].gpiomux[i] = audioall;
3002 }
3003 }
3004 bttv_tvcards[btv->c.type].gpiomask = (UNSET != gpiomask) ? gpiomask : gpiobits;
3005 printk(KERN_INFO "bttv%d: gpio config override: mask=0x%x, mux=",
3006 btv->c.nr,bttv_tvcards[btv->c.type].gpiomask);
3007 for (i = 0; i < 5; i++) {
3008 printk("%s0x%x", i ? "," : "", bttv_tvcards[btv->c.type].gpiomux[i]);
3009 }
3010 printk("\n");
3011}
3012
3013/*
3014 * (most) board specific initialisations goes here
3015 */
3016
3017/* Some Modular Technology cards have an eeprom, but no subsystem ID */
3018static void identify_by_eeprom(struct bttv *btv, unsigned char eeprom_data[256])
3019{
3020 int type = -1;
3021
3022 if (0 == strncmp(eeprom_data,"GET MM20xPCTV",13))
3023 type = BTTV_BOARD_MODTEC_205;
3024 else if (0 == strncmp(eeprom_data+20,"Picolo",7))
3025 type = BTTV_BOARD_EURESYS_PICOLO;
3026 else if (eeprom_data[0] == 0x84 && eeprom_data[2]== 0)
3027 type = BTTV_BOARD_HAUPPAUGE; /* old bt848 */
3028
3029 if (-1 != type) {
3030 btv->c.type = type;
3031 printk("bttv%d: detected by eeprom: %s [card=%d]\n",
3032 btv->c.nr, bttv_tvcards[btv->c.type].name, btv->c.type);
3033 }
3034}
3035
3036static void flyvideo_gpio(struct bttv *btv)
3037{
3038 int gpio,has_remote,has_radio,is_capture_only,is_lr90,has_tda9820_tda9821;
3039 int tuner=-1,ttype;
3040
3041 gpio_inout(0xffffff, 0);
3042 udelay(8); /* without this we would see the 0x1800 mask */
3043 gpio = gpio_read();
3044 /* FIXME: must restore OUR_EN ??? */
3045
3046 /* all cards provide GPIO info, some have an additional eeprom
3047 * LR50: GPIO coding can be found lower right CP1 .. CP9
3048 * CP9=GPIO23 .. CP1=GPIO15; when OPEN, the corresponding GPIO reads 1.
3049 * GPIO14-12: n.c.
3050 * LR90: GP9=GPIO23 .. GP1=GPIO15 (right above the bt878)
3051
3052 * lowest 3 bytes are remote control codes (no handshake needed)
3053 * xxxFFF: No remote control chip soldered
3054 * xxxF00(LR26/LR50), xxxFE0(LR90): Remote control chip (LVA001 or CF45) soldered
3055 * Note: Some bits are Audio_Mask !
3056 */
3057 ttype=(gpio&0x0f0000)>>16;
3058 switch(ttype) {
3059 case 0x0: tuner=2; /* NTSC, e.g. TPI8NSR11P */
3060 break;
3061 case 0x2: tuner=39;/* LG NTSC (newer TAPC series) TAPC-H701P */
3062 break;
3063 case 0x4: tuner=5; /* Philips PAL TPI8PSB02P, TPI8PSB12P, TPI8PSB12D or FI1216, FM1216 */
3064 break;
3065 case 0x6: tuner=37;/* LG PAL (newer TAPC series) TAPC-G702P */
3066 break;
3067 case 0xC: tuner=3; /* Philips SECAM(+PAL) FQ1216ME or FI1216MF */
3068 break;
3069 default:
3070 printk(KERN_INFO "bttv%d: FlyVideo_gpio: unknown tuner type.\n", btv->c.nr);
3071 }
3072
3073 has_remote = gpio & 0x800000;
3074 has_radio = gpio & 0x400000;
3075 /* unknown 0x200000;
3076 * unknown2 0x100000; */
3077 is_capture_only = !(gpio & 0x008000); /* GPIO15 */
3078 has_tda9820_tda9821 = !(gpio & 0x004000);
3079 is_lr90 = !(gpio & 0x002000); /* else LR26/LR50 (LR38/LR51 f. capture only) */
3080 /*
3081 * gpio & 0x001000 output bit for audio routing */
3082
3083 if(is_capture_only)
3084 tuner=4; /* No tuner present */
3085
3086 printk(KERN_INFO "bttv%d: FlyVideo Radio=%s RemoteControl=%s Tuner=%d gpio=0x%06x\n",
3087 btv->c.nr, has_radio? "yes":"no ", has_remote? "yes":"no ", tuner, gpio);
3088 printk(KERN_INFO "bttv%d: FlyVideo LR90=%s tda9821/tda9820=%s capture_only=%s\n",
3089 btv->c.nr, is_lr90?"yes":"no ", has_tda9820_tda9821?"yes":"no ",
3090 is_capture_only?"yes":"no ");
3091
3092 if(tuner!= -1) /* only set if known tuner autodetected, else let insmod option through */
3093 btv->tuner_type = tuner;
3094 btv->has_radio = has_radio;
3095
3096 /* LR90 Audio Routing is done by 2 hef4052, so Audio_Mask has 4 bits: 0x001c80
3097 * LR26/LR50 only has 1 hef4052, Audio_Mask 0x000c00
3098 * Audio options: from tuner, from tda9821/tda9821(mono,stereo,sap), from tda9874, ext., mute */
3099 if(has_tda9820_tda9821) btv->audio_hook = lt9415_audio;
3100 /* todo: if(has_tda9874) btv->audio_hook = fv2000s_audio; */
3101}
3102
3103static int miro_tunermap[] = { 0,6,2,3, 4,5,6,0, 3,0,4,5, 5,2,16,1,
3104 14,2,17,1, 4,1,4,3, 1,2,16,1, 4,4,4,4 };
3105static int miro_fmtuner[] = { 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1,
3106 1,1,1,1, 1,1,1,0, 0,0,0,0, 0,1,0,0 };
3107
3108static void miro_pinnacle_gpio(struct bttv *btv)
3109{
3110 int id,msp,gpio;
3111 char *info;
3112
3113 gpio_inout(0xffffff, 0);
3114 gpio = gpio_read();
3115 id = ((gpio>>10) & 63) -1;
3116 msp = bttv_I2CRead(btv, I2C_ADDR_MSP3400, "MSP34xx");
3117 if (id < 32) {
3118 btv->tuner_type = miro_tunermap[id];
3119 if (0 == (gpio & 0x20)) {
3120 btv->has_radio = 1;
3121 if (!miro_fmtuner[id]) {
3122 btv->has_matchbox = 1;
3123 btv->mbox_we = (1<<6);
3124 btv->mbox_most = (1<<7);
3125 btv->mbox_clk = (1<<8);
3126 btv->mbox_data = (1<<9);
3127 btv->mbox_mask = (1<<6)|(1<<7)|(1<<8)|(1<<9);
3128 }
3129 } else {
3130 btv->has_radio = 0;
3131 }
3132 if (-1 != msp) {
3133 if (btv->c.type == BTTV_BOARD_MIRO)
3134 btv->c.type = BTTV_BOARD_MIROPRO;
3135 if (btv->c.type == BTTV_BOARD_PINNACLE)
3136 btv->c.type = BTTV_BOARD_PINNACLEPRO;
3137 }
3138 printk(KERN_INFO
3139 "bttv%d: miro: id=%d tuner=%d radio=%s stereo=%s\n",
3140 btv->c.nr, id+1, btv->tuner_type,
3141 !btv->has_radio ? "no" :
3142 (btv->has_matchbox ? "matchbox" : "fmtuner"),
3143 (-1 == msp) ? "no" : "yes");
3144 } else {
3145 /* new cards with microtune tuner */
3146 id = 63 - id;
3147 btv->has_radio = 0;
3148 switch (id) {
3149 case 1:
3150 info = "PAL / mono";
3151 btv->tda9887_conf = TDA9887_INTERCARRIER;
3152 break;
3153 case 2:
3154 info = "PAL+SECAM / stereo";
3155 btv->has_radio = 1;
3156 btv->tda9887_conf = TDA9887_QSS;
3157 break;
3158 case 3:
3159 info = "NTSC / stereo";
3160 btv->has_radio = 1;
3161 btv->tda9887_conf = TDA9887_QSS;
3162 break;
3163 case 4:
3164 info = "PAL+SECAM / mono";
3165 btv->tda9887_conf = TDA9887_QSS;
3166 break;
3167 case 5:
3168 info = "NTSC / mono";
3169 btv->tda9887_conf = TDA9887_INTERCARRIER;
3170 break;
3171 case 6:
3172 info = "NTSC / stereo";
3173 btv->tda9887_conf = TDA9887_INTERCARRIER;
3174 break;
3175 case 7:
3176 info = "PAL / stereo";
3177 btv->tda9887_conf = TDA9887_INTERCARRIER;
3178 break;
3179 default:
3180 info = "oops: unknown card";
3181 break;
3182 }
3183 if (-1 != msp)
3184 btv->c.type = BTTV_BOARD_PINNACLEPRO;
3185 printk(KERN_INFO
3186 "bttv%d: pinnacle/mt: id=%d info=\"%s\" radio=%s\n",
3187 btv->c.nr, id, info, btv->has_radio ? "yes" : "no");
3188 btv->tuner_type = TUNER_MT2032;
3189 }
3190}
3191
3192/* GPIO21 L: Buffer aktiv, H: Buffer inaktiv */
3193#define LM1882_SYNC_DRIVE 0x200000L
3194
3195static void init_ids_eagle(struct bttv *btv)
3196{
3197 gpio_inout(0xffffff,0xFFFF37);
3198 gpio_write(0x200020);
3199
3200 /* flash strobe inverter ?! */
3201 gpio_write(0x200024);
3202
3203 /* switch sync drive off */
3204 gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE);
3205
3206 /* set BT848 muxel to 2 */
3207 btaor((2)<<5, ~(2<<5), BT848_IFORM);
3208}
3209
3210/* Muxsel helper for the IDS Eagle.
3211 * the eagles does not use the standard muxsel-bits but
3212 * has its own multiplexer */
3213static void eagle_muxsel(struct bttv *btv, unsigned int input)
3214{
3215 btaor((2)<<5, ~(3<<5), BT848_IFORM);
3216 gpio_bits(3,bttv_tvcards[btv->c.type].muxsel[input&7]);
3217
3218 /* composite */
3219 /* set chroma ADC to sleep */
3220 btor(BT848_ADC_C_SLEEP, BT848_ADC);
3221 /* set to composite video */
3222 btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
3223 btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
3224
3225 /* switch sync drive off */
3226 gpio_bits(LM1882_SYNC_DRIVE,LM1882_SYNC_DRIVE);
3227}
3228
3229static void gvc1100_muxsel(struct bttv *btv, unsigned int input)
3230{
3231 static const int masks[] = {0x30, 0x01, 0x12, 0x23};
3232 gpio_write(masks[input%4]);
3233}
3234
3235/* LMLBT4x initialization - to allow access to GPIO bits for sensors input and
3236 alarms output
3237
3238 GPIObit | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
3239 assignment | TI | O3|INx| O2| O1|IN4|IN3|IN2|IN1| | |
3240
3241 IN - sensor inputs, INx - sensor inputs and TI XORed together
3242 O1,O2,O3 - alarm outputs (relays)
3243
3244 OUT ENABLE 1 1 0 . 1 1 0 0 . 0 0 0 0 = 0x6C0
3245
3246*/
3247
3248static void init_lmlbt4x(struct bttv *btv)
3249{
3250 printk(KERN_DEBUG "LMLBT4x init\n");
3251 btwrite(0x000000, BT848_GPIO_REG_INP);
3252 gpio_inout(0xffffff, 0x0006C0);
3253 gpio_write(0x000000);
3254}
3255
3256static void sigmaSQ_muxsel(struct bttv *btv, unsigned int input)
3257{
3258 unsigned int inmux = input % 8;
3259 gpio_inout( 0xf, 0xf );
3260 gpio_bits( 0xf, inmux );
3261}
3262
3263static void sigmaSLC_muxsel(struct bttv *btv, unsigned int input)
3264{
3265 unsigned int inmux = input % 4;
3266 gpio_inout( 3<<9, 3<<9 );
3267 gpio_bits( 3<<9, inmux<<9 );
3268}
3269
3270/* ----------------------------------------------------------------------- */
3271
3272static void bttv_reset_audio(struct bttv *btv)
3273{
3274 /*
3275 * BT878A has a audio-reset register.
3276 * 1. This register is an audio reset function but it is in
3277 * function-0 (video capture) address space.
3278 * 2. It is enough to do this once per power-up of the card.
3279 * 3. There is a typo in the Conexant doc -- it is not at
3280 * 0x5B, but at 0x058. (B is an odd-number, obviously a typo!).
3281 * --//Shrikumar 030609
3282 */
3283 if (btv->id != 878)
3284 return;
3285
3286 if (bttv_debug)
3287 printk("bttv%d: BT878A ARESET\n",btv->c.nr);
3288 btwrite((1<<7), 0x058);
3289 udelay(10);
3290 btwrite( 0, 0x058);
3291}
3292
3293/* initialization part one -- before registering i2c bus */
3294void __devinit bttv_init_card1(struct bttv *btv)
3295{
3296 switch (btv->c.type) {
3297 case BTTV_BOARD_HAUPPAUGE:
3298 case BTTV_BOARD_HAUPPAUGE878:
3299 boot_msp34xx(btv,5);
3300 break;
3301 case BTTV_BOARD_VOODOOTV_FM:
3302 boot_msp34xx(btv,20);
3303 break;
3304 case BTTV_BOARD_AVERMEDIA98:
3305 boot_msp34xx(btv,11);
3306 break;
3307 case BTTV_BOARD_HAUPPAUGEPVR:
3308 pvr_boot(btv);
3309 break;
3310 case BTTV_BOARD_TWINHAN_DST:
3311 case BTTV_BOARD_AVDVBT_771:
3312 case BTTV_BOARD_PINNACLESAT:
3313 btv->use_i2c_hw = 1;
3314 break;
3315 case BTTV_BOARD_ADLINK_RTV24:
3316 init_RTV24( btv );
3317 break;
3318
3319 }
3320 if (!bttv_tvcards[btv->c.type].has_dvb)
3321 bttv_reset_audio(btv);
3322}
3323
3324/* initialization part two -- after registering i2c bus */
3325void __devinit bttv_init_card2(struct bttv *btv)
3326{
3327 int tda9887;
3328 int addr=ADDR_UNSET;
3329
3330 btv->tuner_type = -1;
3331
3332 if (BTTV_BOARD_UNKNOWN == btv->c.type) {
3333 bttv_readee(btv,eeprom_data,0xa0);
3334 identify_by_eeprom(btv,eeprom_data);
3335 }
3336
3337 switch (btv->c.type) {
3338 case BTTV_BOARD_MIRO:
3339 case BTTV_BOARD_MIROPRO:
3340 case BTTV_BOARD_PINNACLE:
3341 case BTTV_BOARD_PINNACLEPRO:
3342 /* miro/pinnacle */
3343 miro_pinnacle_gpio(btv);
3344 break;
3345 case BTTV_BOARD_FLYVIDEO_98:
3346 case BTTV_BOARD_MAXI:
3347 case BTTV_BOARD_LIFE_FLYKIT:
3348 case BTTV_BOARD_FLYVIDEO:
3349 case BTTV_BOARD_TYPHOON_TVIEW:
3350 case BTTV_BOARD_CHRONOS_VS2:
3351 case BTTV_BOARD_FLYVIDEO_98FM:
3352 case BTTV_BOARD_FLYVIDEO2000:
3353 case BTTV_BOARD_FLYVIDEO98EZ:
3354 case BTTV_BOARD_CONFERENCETV:
3355 case BTTV_BOARD_LIFETEC_9415:
3356 flyvideo_gpio(btv);
3357 break;
3358 case BTTV_BOARD_HAUPPAUGE:
3359 case BTTV_BOARD_HAUPPAUGE878:
3360 case BTTV_BOARD_HAUPPAUGEPVR:
3361 /* pick up some config infos from the eeprom */
3362 bttv_readee(btv,eeprom_data,0xa0);
3363 hauppauge_eeprom(btv);
3364 break;
3365 case BTTV_BOARD_AVERMEDIA98:
3366 case BTTV_BOARD_AVPHONE98:
3367 bttv_readee(btv,eeprom_data,0xa0);
3368 avermedia_eeprom(btv);
3369 break;
3370 case BTTV_BOARD_PXC200:
3371 init_PXC200(btv);
3372 break;
3373 case BTTV_BOARD_PICOLO_TETRA_CHIP:
3374 picolo_tetra_init(btv);
3375 break;
3376 case BTTV_BOARD_VHX:
3377 btv->has_radio = 1;
3378 btv->has_matchbox = 1;
3379 btv->mbox_we = 0x20;
3380 btv->mbox_most = 0;
3381 btv->mbox_clk = 0x08;
3382 btv->mbox_data = 0x10;
3383 btv->mbox_mask = 0x38;
3384 break;
3385 case BTTV_BOARD_VOBIS_BOOSTAR:
3386 case BTTV_BOARD_TERRATV:
3387 terratec_active_radio_upgrade(btv);
3388 break;
3389 case BTTV_BOARD_MAGICTVIEW061:
3390 if (btv->cardid == 0x3002144f) {
3391 btv->has_radio=1;
3392 printk("bttv%d: radio detected by subsystem id (CPH05x)\n",btv->c.nr);
3393 }
3394 break;
3395 case BTTV_BOARD_STB2:
3396 if (btv->cardid == 0x3060121a) {
3397 /* Fix up entry for 3DFX VoodooTV 100,
3398 which is an OEM STB card variant. */
3399 btv->has_radio=0;
3400 btv->tuner_type=TUNER_TEMIC_NTSC;
3401 }
3402 break;
3403 case BTTV_BOARD_OSPREY1x0:
3404 case BTTV_BOARD_OSPREY1x0_848:
3405 case BTTV_BOARD_OSPREY101_848:
3406 case BTTV_BOARD_OSPREY1x1:
3407 case BTTV_BOARD_OSPREY1x1_SVID:
3408 case BTTV_BOARD_OSPREY2xx:
3409 case BTTV_BOARD_OSPREY2x0_SVID:
3410 case BTTV_BOARD_OSPREY2x0:
3411 case BTTV_BOARD_OSPREY500:
3412 case BTTV_BOARD_OSPREY540:
3413 case BTTV_BOARD_OSPREY2000:
3414 bttv_readee(btv,eeprom_data,0xa0);
3415 osprey_eeprom(btv);
3416 break;
3417 case BTTV_BOARD_IDS_EAGLE:
3418 init_ids_eagle(btv);
3419 break;
3420 case BTTV_BOARD_MODTEC_205:
3421 bttv_readee(btv,eeprom_data,0xa0);
3422 modtec_eeprom(btv);
3423 break;
3424 case BTTV_BOARD_LMLBT4:
3425 init_lmlbt4x(btv);
3426 break;
3427 case BTTV_BOARD_TIBET_CS16:
3428 tibetCS16_init(btv);
3429 break;
3430 case BTTV_BOARD_KODICOM_4400R:
3431 kodicom4400r_init(btv);
3432 break;
3433 }
3434
3435 /* pll configuration */
3436 if (!(btv->id==848 && btv->revision==0x11)) {
3437 /* defaults from card list */
3438 if (PLL_28 == bttv_tvcards[btv->c.type].pll) {
3439 btv->pll.pll_ifreq=28636363;
3440 btv->pll.pll_crystal=BT848_IFORM_XT0;
3441 }
3442 if (PLL_35 == bttv_tvcards[btv->c.type].pll) {
3443 btv->pll.pll_ifreq=35468950;
3444 btv->pll.pll_crystal=BT848_IFORM_XT1;
3445 }
3446 /* insmod options can override */
3447 switch (pll[btv->c.nr]) {
3448 case 0: /* none */
3449 btv->pll.pll_crystal = 0;
3450 btv->pll.pll_ifreq = 0;
3451 btv->pll.pll_ofreq = 0;
3452 break;
3453 case 1: /* 28 MHz */
3454 case 28:
3455 btv->pll.pll_ifreq = 28636363;
3456 btv->pll.pll_ofreq = 0;
3457 btv->pll.pll_crystal = BT848_IFORM_XT0;
3458 break;
3459 case 2: /* 35 MHz */
3460 case 35:
3461 btv->pll.pll_ifreq = 35468950;
3462 btv->pll.pll_ofreq = 0;
3463 btv->pll.pll_crystal = BT848_IFORM_XT1;
3464 break;
3465 }
3466 }
3467 btv->pll.pll_current = -1;
3468
3469 /* tuner configuration (from card list / autodetect / insmod option) */
3470 if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
3471 addr = bttv_tvcards[btv->c.type].tuner_addr;
3472
3473 if (UNSET != bttv_tvcards[btv->c.type].tuner_type)
3474 if(UNSET == btv->tuner_type)
3475 btv->tuner_type = bttv_tvcards[btv->c.type].tuner_type;
3476 if (UNSET != tuner[btv->c.nr])
3477 btv->tuner_type = tuner[btv->c.nr];
3478 printk("bttv%d: using tuner=%d\n",btv->c.nr,btv->tuner_type);
3479
3480 if (btv->tuner_type != UNSET) {
3481 struct tuner_setup tun_setup;
3482
3483 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
3484 tun_setup.type = btv->tuner_type;
3485 tun_setup.addr = addr;
3486
3487 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
3488 }
3489
3490 if (btv->tda9887_conf) {
3491 bttv_call_i2c_clients(btv, TDA9887_SET_CONFIG,
3492 &btv->tda9887_conf);
3493 }
3494
3495 btv->svhs = bttv_tvcards[btv->c.type].svhs;
3496 if (svhs[btv->c.nr] != UNSET)
3497 btv->svhs = svhs[btv->c.nr];
3498 if (remote[btv->c.nr] != UNSET)
3499 btv->has_remote = remote[btv->c.nr];
3500
3501 if (bttv_tvcards[btv->c.type].has_radio)
3502 btv->has_radio=1;
3503 if (bttv_tvcards[btv->c.type].has_remote)
3504 btv->has_remote=1;
3505 if (!bttv_tvcards[btv->c.type].no_gpioirq)
3506 btv->gpioirq=1;
3507 if (bttv_tvcards[btv->c.type].audio_hook)
3508 btv->audio_hook=bttv_tvcards[btv->c.type].audio_hook;
3509
3510 if (bttv_tvcards[btv->c.type].digital_mode == DIGITAL_MODE_CAMERA) {
3511 /* detect Bt832 chip for quartzsight digital camera */
3512 if ((bttv_I2CRead(btv, I2C_ADDR_BT832_ALT1, "Bt832") >=0) ||
3513 (bttv_I2CRead(btv, I2C_ADDR_BT832_ALT2, "Bt832") >=0))
3514 boot_bt832(btv);
3515 }
3516
3517 if (!autoload)
3518 return;
3519
3520 /* try to detect audio/fader chips */
3521 if (!bttv_tvcards[btv->c.type].no_msp34xx &&
3522 bttv_I2CRead(btv, I2C_ADDR_MSP3400, "MSP34xx") >=0)
3523 request_module("msp3400");
3524
3525 if (bttv_tvcards[btv->c.type].msp34xx_alt &&
3526 bttv_I2CRead(btv, I2C_ADDR_MSP3400_ALT, "MSP34xx (alternate address)") >=0)
3527 request_module("msp3400");
3528
3529 if (!bttv_tvcards[btv->c.type].no_tda9875 &&
3530 bttv_I2CRead(btv, I2C_ADDR_TDA9875, "TDA9875") >=0)
3531 request_module("tda9875");
3532
3533 if (!bttv_tvcards[btv->c.type].no_tda7432 &&
3534 bttv_I2CRead(btv, I2C_ADDR_TDA7432, "TDA7432") >=0)
3535 request_module("tda7432");
3536
3537 if (bttv_tvcards[btv->c.type].needs_tvaudio)
3538 request_module("tvaudio");
3539
3540 /* tuner modules */
3541 tda9887 = 0;
3542 if (btv->tda9887_conf)
3543 tda9887 = 1;
3544 if (0 == tda9887 && 0 == bttv_tvcards[btv->c.type].has_dvb &&
3545 bttv_I2CRead(btv, I2C_ADDR_TDA9887, "TDA9887") >=0)
3546 tda9887 = 1;
3547 /* Hybrid DVB card, DOES have a tda9887 */
3548 if (btv->c.type == BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE)
3549 tda9887 = 1;
3550 if((btv->tuner_type == TUNER_PHILIPS_FM1216ME_MK3) ||
3551 (btv->tuner_type == TUNER_PHILIPS_FM1236_MK3) ||
3552 (btv->tuner_type == TUNER_PHILIPS_FM1256_IH3) ||
3553 tda9887)
3554 request_module("tda9887");
3555 if (btv->tuner_type != UNSET)
3556 request_module("tuner");
3557}
3558
3559
3560/* ----------------------------------------------------------------------- */
3561
3562static void modtec_eeprom(struct bttv *btv)
3563{
3564 if( strncmp(&(eeprom_data[0x1e]),"Temic 4066 FY5",14) ==0) {
3565 btv->tuner_type=TUNER_TEMIC_4066FY5_PAL_I;
3566 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
3567 btv->c.nr,&eeprom_data[0x1e]);
3568 } else if (strncmp(&(eeprom_data[0x1e]),"Alps TSBB5",10) ==0) {
3569 btv->tuner_type=TUNER_ALPS_TSBB5_PAL_I;
3570 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
3571 btv->c.nr,&eeprom_data[0x1e]);
3572 } else if (strncmp(&(eeprom_data[0x1e]),"Philips FM1246",14) ==0) {
3573 btv->tuner_type=TUNER_PHILIPS_NTSC;
3574 printk("bttv%d: Modtec: Tuner autodetected by eeprom: %s\n",
3575 btv->c.nr,&eeprom_data[0x1e]);
3576 } else {
3577 printk("bttv%d: Modtec: Unknown TunerString: %s\n",
3578 btv->c.nr,&eeprom_data[0x1e]);
3579 }
3580}
3581
3582static void __devinit hauppauge_eeprom(struct bttv *btv)
3583{
3584 struct tveeprom tv;
3585
3586 tveeprom_hauppauge_analog(&btv->i2c_client, &tv, eeprom_data);
3587 btv->tuner_type = tv.tuner_type;
3588 btv->has_radio = tv.has_radio;
3589
3590 printk("bttv%d: Hauppauge eeprom indicates model#%d\n",
3591 btv->c.nr, tv.model);
3592
3593 /*
3594 * Some of the 878 boards have duplicate PCI IDs. Switch the board
3595 * type based on model #.
3596 */
3597 if(tv.model == 64900) {
3598 printk("bttv%d: Switching board type from %s to %s\n",
3599 btv->c.nr,
3600 bttv_tvcards[btv->c.type].name,
3601 bttv_tvcards[BTTV_BOARD_HAUPPAUGE_IMPACTVCB].name);
3602 btv->c.type = BTTV_BOARD_HAUPPAUGE_IMPACTVCB;
3603 }
3604}
3605
3606static int terratec_active_radio_upgrade(struct bttv *btv)
3607{
3608 int freq;
3609
3610 btv->has_radio = 1;
3611 btv->has_matchbox = 1;
3612 btv->mbox_we = 0x10;
3613 btv->mbox_most = 0x20;
3614 btv->mbox_clk = 0x08;
3615 btv->mbox_data = 0x04;
3616 btv->mbox_mask = 0x3c;
3617
3618 btv->mbox_iow = 1 << 8;
3619 btv->mbox_ior = 1 << 9;
3620 btv->mbox_csel = 1 << 10;
3621
3622 freq=88000/62.5;
3623 tea5757_write(btv, 5 * freq + 0x358); /* write 0x1ed8 */
3624 if (0x1ed8 == tea5757_read(btv)) {
3625 printk("bttv%d: Terratec Active Radio Upgrade found.\n",
3626 btv->c.nr);
3627 btv->has_radio = 1;
3628 btv->has_matchbox = 1;
3629 } else {
3630 btv->has_radio = 0;
3631 btv->has_matchbox = 0;
3632 }
3633 return 0;
3634}
3635
3636
3637/* ----------------------------------------------------------------------- */
3638
3639/*
3640 * minimal bootstrap for the WinTV/PVR -- upload altera firmware.
3641 *
3642 * The hcwamc.rbf firmware file is on the Hauppauge driver CD. Have
3643 * a look at Pvr/pvr45xxx.EXE (self-extracting zip archive, can be
3644 * unpacked with unzip).
3645 */
3646#define PVR_GPIO_DELAY 10
3647
3648#define BTTV_ALT_DATA 0x000001
3649#define BTTV_ALT_DCLK 0x100000
3650#define BTTV_ALT_NCONFIG 0x800000
3651
3652static int __devinit pvr_altera_load(struct bttv *btv, u8 *micro, u32 microlen)
3653{
3654 u32 n;
3655 u8 bits;
3656 int i;
3657
3658 gpio_inout(0xffffff,BTTV_ALT_DATA|BTTV_ALT_DCLK|BTTV_ALT_NCONFIG);
3659 gpio_write(0);
3660 udelay(PVR_GPIO_DELAY);
3661
3662 gpio_write(BTTV_ALT_NCONFIG);
3663 udelay(PVR_GPIO_DELAY);
3664
3665 for (n = 0; n < microlen; n++) {
3666 bits = micro[n];
3667 for ( i = 0 ; i < 8 ; i++ ) {
3668 gpio_bits(BTTV_ALT_DCLK,0);
3669 if (bits & 0x01)
3670 gpio_bits(BTTV_ALT_DATA,BTTV_ALT_DATA);
3671 else
3672 gpio_bits(BTTV_ALT_DATA,0);
3673 gpio_bits(BTTV_ALT_DCLK,BTTV_ALT_DCLK);
3674 bits >>= 1;
3675 }
3676 }
3677 gpio_bits(BTTV_ALT_DCLK,0);
3678 udelay(PVR_GPIO_DELAY);
3679
3680 /* begin Altera init loop (Not necessary,but doesn't hurt) */
3681 for (i = 0 ; i < 30 ; i++) {
3682 gpio_bits(BTTV_ALT_DCLK,0);
3683 gpio_bits(BTTV_ALT_DCLK,BTTV_ALT_DCLK);
3684 }
3685 gpio_bits(BTTV_ALT_DCLK,0);
3686 return 0;
3687}
3688
3689static int __devinit pvr_boot(struct bttv *btv)
3690{
3691 const struct firmware *fw_entry;
3692 int rc;
3693
3694 rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev);
3695 if (rc != 0) {
3696 printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n",
3697 btv->c.nr);
3698 return rc;
3699 }
3700 rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size);
3701 printk(KERN_INFO "bttv%d: altera firmware upload %s\n",
3702 btv->c.nr, (rc < 0) ? "failed" : "ok");
3703 release_firmware(fw_entry);
3704 return rc;
3705}
3706
3707/* ----------------------------------------------------------------------- */
3708/* some osprey specific stuff */
3709
3710static void __devinit osprey_eeprom(struct bttv *btv)
3711{
3712 int i = 0;
3713 unsigned char *ee = eeprom_data;
3714 unsigned long serial = 0;
3715
3716 if (btv->c.type == 0) {
3717 /* this might be an antique... check for MMAC label in eeprom */
3718 if ((ee[0]=='M') && (ee[1]=='M') && (ee[2]=='A') && (ee[3]=='C')) {
3719 unsigned char checksum = 0;
3720 for (i =0; i<21; i++)
3721 checksum += ee[i];
3722 if (checksum != ee[21])
3723 return;
3724 btv->c.type = BTTV_BOARD_OSPREY1x0_848;
3725 for (i = 12; i < 21; i++)
3726 serial *= 10, serial += ee[i] - '0';
3727 }
3728 } else {
3729 unsigned short type;
3730 int offset = 4*16;
3731
3732 for(; offset < 8*16; offset += 16) {
3733 unsigned short checksum = 0;
3734 /* verify the checksum */
3735 for(i = 0; i<14; i++) checksum += ee[i+offset];
3736 checksum = ~checksum; /* no idea why */
3737 if ((((checksum>>8)&0x0FF) == ee[offset+14]) &&
3738 ((checksum & 0x0FF) == ee[offset+15])) {
3739 break;
3740 }
3741 }
3742
3743 if (offset >= 8*16)
3744 return;
3745
3746 /* found a valid descriptor */
3747 type = (ee[offset+4]<<8) | (ee[offset+5]);
3748
3749 switch(type) {
3750
3751 /* 848 based */
3752 case 0x0004:
3753 btv->c.type = BTTV_BOARD_OSPREY1x0_848;
3754 break;
3755 case 0x0005:
3756 btv->c.type = BTTV_BOARD_OSPREY101_848;
3757 break;
3758
3759 /* 878 based */
3760 case 0x0012:
3761 case 0x0013:
3762 btv->c.type = BTTV_BOARD_OSPREY1x0;
3763 break;
3764 case 0x0014:
3765 case 0x0015:
3766 btv->c.type = BTTV_BOARD_OSPREY1x1;
3767 break;
3768 case 0x0016:
3769 case 0x0017:
3770 case 0x0020:
3771 btv->c.type = BTTV_BOARD_OSPREY1x1_SVID;
3772 break;
3773 case 0x0018:
3774 case 0x0019:
3775 case 0x001E:
3776 case 0x001F:
3777 btv->c.type = BTTV_BOARD_OSPREY2xx;
3778 break;
3779 case 0x001A:
3780 case 0x001B:
3781 btv->c.type = BTTV_BOARD_OSPREY2x0_SVID;
3782 break;
3783 case 0x0040:
3784 btv->c.type = BTTV_BOARD_OSPREY500;
3785 break;
3786 case 0x0050:
3787 case 0x0056:
3788 btv->c.type = BTTV_BOARD_OSPREY540;
3789 /* bttv_osprey_540_init(btv); */
3790 break;
3791 case 0x0060:
3792 case 0x0070:
3793 btv->c.type = BTTV_BOARD_OSPREY2x0;
3794 /* enable output on select control lines */
3795 gpio_inout(0xffffff,0x000303);
3796 break;
3797 default:
3798 /* unknown...leave generic, but get serial # */
3799 break;
3800 }
3801 serial = (ee[offset+6] << 24)
3802 | (ee[offset+7] << 16)
3803 | (ee[offset+8] << 8)
3804 | (ee[offset+9]);
3805 }
3806
3807 printk(KERN_INFO "bttv%d: osprey eeprom: card=%d name=%s serial=%ld\n",
3808 btv->c.nr, btv->c.type, bttv_tvcards[btv->c.type].name,serial);
3809}
3810
3811/* ----------------------------------------------------------------------- */
3812/* AVermedia specific stuff, from bktr_card.c */
3813
3814static int tuner_0_table[] = {
3815 TUNER_PHILIPS_NTSC, TUNER_PHILIPS_PAL /* PAL-BG*/,
3816 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL /* PAL-I*/,
3817 TUNER_PHILIPS_PAL, TUNER_PHILIPS_PAL,
3818 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_SECAM,
3819 TUNER_PHILIPS_SECAM, TUNER_PHILIPS_PAL,
3820 TUNER_PHILIPS_FM1216ME_MK3 };
3821
3822static int tuner_1_table[] = {
3823 TUNER_TEMIC_NTSC, TUNER_TEMIC_PAL,
3824 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3825 TUNER_TEMIC_PAL, TUNER_TEMIC_PAL,
3826 TUNER_TEMIC_4012FY5, TUNER_TEMIC_4012FY5, /* TUNER_TEMIC_SECAM */
3827 TUNER_TEMIC_4012FY5, TUNER_TEMIC_PAL};
3828
3829static void __devinit avermedia_eeprom(struct bttv *btv)
3830{
3831 int tuner_make,tuner_tv_fm,tuner_format,tuner=0;
3832
3833 tuner_make = (eeprom_data[0x41] & 0x7);
3834 tuner_tv_fm = (eeprom_data[0x41] & 0x18) >> 3;
3835 tuner_format = (eeprom_data[0x42] & 0xf0) >> 4;
3836 btv->has_remote = (eeprom_data[0x42] & 0x01);
3837
3838 if (tuner_make == 0 || tuner_make == 2)
3839 if(tuner_format <=0x0a)
3840 tuner = tuner_0_table[tuner_format];
3841 if (tuner_make == 1)
3842 if(tuner_format <=9)
3843 tuner = tuner_1_table[tuner_format];
3844
3845 if (tuner_make == 4)
3846 if(tuner_format == 0x09)
3847 tuner = TUNER_LG_NTSC_NEW_TAPC; /* TAPC-G702P */
3848
3849 printk(KERN_INFO "bttv%d: Avermedia eeprom[0x%02x%02x]: tuner=",
3850 btv->c.nr,eeprom_data[0x41],eeprom_data[0x42]);
3851 if(tuner) {
3852 btv->tuner_type=tuner;
3853 printk("%d",tuner);
3854 } else
3855 printk("Unknown type");
3856 printk(" radio:%s remote control:%s\n",
3857 tuner_tv_fm ? "yes" : "no",
3858 btv->has_remote ? "yes" : "no");
3859}
3860
3861/* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */
3862void bttv_tda9880_setnorm(struct bttv *btv, int norm)
3863{
3864 /* fix up our card entry */
3865 if(norm==VIDEO_MODE_NTSC) {
3866 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x957fff;
3867 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x957fff;
3868 dprintk("bttv_tda9880_setnorm to NTSC\n");
3869 }
3870 else {
3871 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomux[TVAUDIO_INPUT_TUNER]=0x947fff;
3872 bttv_tvcards[BTTV_BOARD_VOODOOTV_FM].gpiomute=0x947fff;
3873 dprintk("bttv_tda9880_setnorm to PAL\n");
3874 }
3875 /* set GPIO according */
3876 gpio_bits(bttv_tvcards[btv->c.type].gpiomask,
3877 bttv_tvcards[btv->c.type].gpiomux[btv->audio]);
3878}
3879
3880
3881/*
3882 * reset/enable the MSP on some Hauppauge cards
3883 * Thanks to Kyösti Mälkki (kmalkki@cc.hut.fi)!
3884 *
3885 * Hauppauge: pin 5
3886 * Voodoo: pin 20
3887 */
3888static void __devinit boot_msp34xx(struct bttv *btv, int pin)
3889{
3890 int mask = (1 << pin);
3891
3892 gpio_inout(mask,mask);
3893 gpio_bits(mask,0);
3894 udelay(2500);
3895 gpio_bits(mask,mask);
3896
3897 if (bttv_gpio)
3898 bttv_gpio_tracking(btv,"msp34xx");
3899 if (bttv_verbose)
3900 printk(KERN_INFO "bttv%d: Hauppauge/Voodoo msp34xx: reset line "
3901 "init [%d]\n", btv->c.nr, pin);
3902}
3903
3904static void __devinit boot_bt832(struct bttv *btv)
3905{
3906}
3907
3908/* ----------------------------------------------------------------------- */
3909/* Imagenation L-Model PXC200 Framegrabber */
3910/* This is basically the same procedure as
3911 * used by Alessandro Rubini in his pxc200
3912 * driver, but using BTTV functions */
3913
3914static void __devinit init_PXC200(struct bttv *btv)
3915{
3916 static int vals[] __devinitdata = { 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0d,
3917 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
3918 0x00 };
3919 unsigned int i;
3920 int tmp;
3921 u32 val;
3922
3923 /* Initialise GPIO-connevted stuff */
3924 gpio_inout(0xffffff, (1<<13));
3925 gpio_write(0);
3926 udelay(3);
3927 gpio_write(1<<13);
3928 /* GPIO inputs are pulled up, so no need to drive
3929 * reset pin any longer */
3930 gpio_bits(0xffffff, 0);
3931 if (bttv_gpio)
3932 bttv_gpio_tracking(btv,"pxc200");
3933
3934 /* we could/should try and reset/control the AD pots? but
3935 right now we simply turned off the crushing. Without
3936 this the AGC drifts drifts
3937 remember the EN is reverse logic -->
3938 setting BT848_ADC_AGC_EN disable the AGC
3939 tboult@eecs.lehigh.edu
3940 */
3941
3942 btwrite(BT848_ADC_RESERVED|BT848_ADC_AGC_EN, BT848_ADC);
3943
3944 /* Initialise MAX517 DAC */
3945 printk(KERN_INFO "Setting DAC reference voltage level ...\n");
3946 bttv_I2CWrite(btv,0x5E,0,0x80,1);
3947
3948 /* Initialise 12C508 PIC */
3949 /* The I2CWrite and I2CRead commmands are actually to the
3950 * same chips - but the R/W bit is included in the address
3951 * argument so the numbers are different */
3952
3953
3954 printk(KERN_INFO "Initialising 12C508 PIC chip ...\n");
3955
3956 /* First of all, enable the clock line. This is used in the PXC200-F */
3957 val = btread(BT848_GPIO_DMA_CTL);
3958 val |= BT848_GPIO_DMA_CTL_GPCLKMODE;
3959 btwrite(val, BT848_GPIO_DMA_CTL);
3960
3961 /* Then, push to 0 the reset pin long enough to reset the *
3962 * device same as above for the reset line, but not the same
3963 * value sent to the GPIO-connected stuff
3964 * which one is the good one? */
3965 gpio_inout(0xffffff,(1<<2));
3966 gpio_write(0);
3967 udelay(10);
3968 gpio_write(1<<2);
3969
3970 for (i = 0; i < ARRAY_SIZE(vals); i++) {
3971 tmp=bttv_I2CWrite(btv,0x1E,0,vals[i],1);
3972 if (tmp != -1) {
3973 printk(KERN_INFO
3974 "I2C Write(%2.2x) = %i\nI2C Read () = %2.2x\n\n",
3975 vals[i],tmp,bttv_I2CRead(btv,0x1F,NULL));
3976 }
3977 }
3978
3979 printk(KERN_INFO "PXC200 Initialised.\n");
3980}
3981
3982
3983
3984/* ----------------------------------------------------------------------- */
3985/*
3986 * The Adlink RTV-24 (aka Angelo) has some special initialisation to unlock
3987 * it. This apparently involves the following procedure for each 878 chip:
3988 *
3989 * 1) write 0x00C3FEFF to the GPIO_OUT_EN register
3990 *
3991 * 2) write to GPIO_DATA
3992 * - 0x0E
3993 * - sleep 1ms
3994 * - 0x10 + 0x0E
3995 * - sleep 10ms
3996 * - 0x0E
3997 * read from GPIO_DATA into buf (uint_32)
3998 * - if ( data>>18 & 0x01 != 0) || ( buf>>19 & 0x01 != 1 )
3999 * error. ERROR_CPLD_Check_Failed stop.
4000 *
4001 * 3) write to GPIO_DATA
4002 * - write 0x4400 + 0x0E
4003 * - sleep 10ms
4004 * - write 0x4410 + 0x0E
4005 * - sleep 1ms
4006 * - write 0x0E
4007 * read from GPIO_DATA into buf (uint_32)
4008 * - if ( buf>>18 & 0x01 ) || ( buf>>19 && 0x01 != 0 )
4009 * error. ERROR_CPLD_Check_Failed.
4010 */
4011/* ----------------------------------------------------------------------- */
4012static void
4013init_RTV24 (struct bttv *btv)
4014{
4015 uint32_t dataRead = 0;
4016 long watchdog_value = 0x0E;
4017
4018 printk (KERN_INFO
4019 "bttv%d: Adlink RTV-24 initialisation in progress ...\n",
4020 btv->c.nr);
4021
4022 btwrite (0x00c3feff, BT848_GPIO_OUT_EN);
4023
4024 btwrite (0 + watchdog_value, BT848_GPIO_DATA);
4025 msleep (1);
4026 btwrite (0x10 + watchdog_value, BT848_GPIO_DATA);
4027 msleep (10);
4028 btwrite (0 + watchdog_value, BT848_GPIO_DATA);
4029
4030 dataRead = btread (BT848_GPIO_DATA);
4031
4032 if ((((dataRead >> 18) & 0x01) != 0) || (((dataRead >> 19) & 0x01) != 1)) {
4033 printk (KERN_INFO
4034 "bttv%d: Adlink RTV-24 initialisation(1) ERROR_CPLD_Check_Failed (read %d)\n",
4035 btv->c.nr, dataRead);
4036 }
4037
4038 btwrite (0x4400 + watchdog_value, BT848_GPIO_DATA);
4039 msleep (10);
4040 btwrite (0x4410 + watchdog_value, BT848_GPIO_DATA);
4041 msleep (1);
4042 btwrite (watchdog_value, BT848_GPIO_DATA);
4043 msleep (1);
4044 dataRead = btread (BT848_GPIO_DATA);
4045
4046 if ((((dataRead >> 18) & 0x01) != 0) || (((dataRead >> 19) & 0x01) != 0)) {
4047 printk (KERN_INFO
4048 "bttv%d: Adlink RTV-24 initialisation(2) ERROR_CPLD_Check_Failed (read %d)\n",
4049 btv->c.nr, dataRead);
4050
4051 return;
4052 }
4053
4054 printk (KERN_INFO
4055 "bttv%d: Adlink RTV-24 initialisation complete.\n", btv->c.nr);
4056}
4057
4058
4059
4060/* ----------------------------------------------------------------------- */
4061/* Miro Pro radio stuff -- the tea5757 is connected to some GPIO ports */
4062/*
4063 * Copyright (c) 1999 Csaba Halasz <qgehali@uni-miskolc.hu>
4064 * This code is placed under the terms of the GNU General Public License
4065 *
4066 * Brutally hacked by Dan Sheridan <dan.sheridan@contact.org.uk> djs52 8/3/00
4067 */
4068
4069static void bus_low(struct bttv *btv, int bit)
4070{
4071 if (btv->mbox_ior) {
4072 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
4073 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
4074 udelay(5);
4075 }
4076
4077 gpio_bits(bit,0);
4078 udelay(5);
4079
4080 if (btv->mbox_ior) {
4081 gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
4082 udelay(5);
4083 }
4084}
4085
4086static void bus_high(struct bttv *btv, int bit)
4087{
4088 if (btv->mbox_ior) {
4089 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
4090 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
4091 udelay(5);
4092 }
4093
4094 gpio_bits(bit,bit);
4095 udelay(5);
4096
4097 if (btv->mbox_ior) {
4098 gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
4099 udelay(5);
4100 }
4101}
4102
4103static int bus_in(struct bttv *btv, int bit)
4104{
4105 if (btv->mbox_ior) {
4106 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
4107 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
4108 udelay(5);
4109
4110 gpio_bits(btv->mbox_iow | btv->mbox_csel, 0);
4111 udelay(5);
4112 }
4113 return gpio_read() & (bit);
4114}
4115
4116/* TEA5757 register bits */
4117#define TEA_FREQ 0:14
4118#define TEA_BUFFER 15:15
4119
4120#define TEA_SIGNAL_STRENGTH 16:17
4121
4122#define TEA_PORT1 18:18
4123#define TEA_PORT0 19:19
4124
4125#define TEA_BAND 20:21
4126#define TEA_BAND_FM 0
4127#define TEA_BAND_MW 1
4128#define TEA_BAND_LW 2
4129#define TEA_BAND_SW 3
4130
4131#define TEA_MONO 22:22
4132#define TEA_ALLOW_STEREO 0
4133#define TEA_FORCE_MONO 1
4134
4135#define TEA_SEARCH_DIRECTION 23:23
4136#define TEA_SEARCH_DOWN 0
4137#define TEA_SEARCH_UP 1
4138
4139#define TEA_STATUS 24:24
4140#define TEA_STATUS_TUNED 0
4141#define TEA_STATUS_SEARCHING 1
4142
4143/* Low-level stuff */
4144static int tea5757_read(struct bttv *btv)
4145{
4146 unsigned long timeout;
4147 int value = 0;
4148 int i;
4149
4150 /* better safe than sorry */
4151 gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we);
4152
4153 if (btv->mbox_ior) {
4154 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
4155 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
4156 udelay(5);
4157 }
4158
4159 if (bttv_gpio)
4160 bttv_gpio_tracking(btv,"tea5757 read");
4161
4162 bus_low(btv,btv->mbox_we);
4163 bus_low(btv,btv->mbox_clk);
4164
4165 udelay(10);
4166 timeout= jiffies + HZ;
4167
4168 /* wait for DATA line to go low; error if it doesn't */
4169 while (bus_in(btv,btv->mbox_data) && time_before(jiffies, timeout))
4170 schedule();
4171 if (bus_in(btv,btv->mbox_data)) {
4172 printk(KERN_WARNING "bttv%d: tea5757: read timeout\n",btv->c.nr);
4173 return -1;
4174 }
4175
4176 dprintk("bttv%d: tea5757:",btv->c.nr);
4177 for(i = 0; i < 24; i++)
4178 {
4179 udelay(5);
4180 bus_high(btv,btv->mbox_clk);
4181 udelay(5);
4182 dprintk("%c",(bus_in(btv,btv->mbox_most) == 0)?'T':'-');
4183 bus_low(btv,btv->mbox_clk);
4184 value <<= 1;
4185 value |= (bus_in(btv,btv->mbox_data) == 0)?0:1; /* MSB first */
4186 dprintk("%c", (bus_in(btv,btv->mbox_most) == 0)?'S':'M');
4187 }
4188 dprintk("\nbttv%d: tea5757: read 0x%X\n", btv->c.nr, value);
4189 return value;
4190}
4191
4192static int tea5757_write(struct bttv *btv, int value)
4193{
4194 int i;
4195 int reg = value;
4196
4197 gpio_inout(btv->mbox_mask, btv->mbox_clk | btv->mbox_we | btv->mbox_data);
4198
4199 if (btv->mbox_ior) {
4200 gpio_bits(btv->mbox_ior | btv->mbox_iow | btv->mbox_csel,
4201 btv->mbox_ior | btv->mbox_iow | btv->mbox_csel);
4202 udelay(5);
4203 }
4204 if (bttv_gpio)
4205 bttv_gpio_tracking(btv,"tea5757 write");
4206
4207 dprintk("bttv%d: tea5757: write 0x%X\n", btv->c.nr, value);
4208 bus_low(btv,btv->mbox_clk);
4209 bus_high(btv,btv->mbox_we);
4210 for(i = 0; i < 25; i++)
4211 {
4212 if (reg & 0x1000000)
4213 bus_high(btv,btv->mbox_data);
4214 else
4215 bus_low(btv,btv->mbox_data);
4216 reg <<= 1;
4217 bus_high(btv,btv->mbox_clk);
4218 udelay(10);
4219 bus_low(btv,btv->mbox_clk);
4220 udelay(10);
4221 }
4222 bus_low(btv,btv->mbox_we); /* unmute !!! */
4223 return 0;
4224}
4225
4226void tea5757_set_freq(struct bttv *btv, unsigned short freq)
4227{
4228 dprintk("tea5757_set_freq %d\n",freq);
4229 tea5757_write(btv, 5 * freq + 0x358); /* add 10.7MHz (see docs) */
4230}
4231
4232
4233/* ----------------------------------------------------------------------- */
4234/* winview */
4235
4236static void winview_audio(struct bttv *btv, struct video_audio *v, int set)
4237{
4238 /* PT2254A programming Jon Tombs, jon@gte.esi.us.es */
4239 int bits_out, loops, vol, data;
4240
4241 if (!set) {
4242 /* Fixed by Leandro Lucarella <luca@linuxmendoza.org.ar (07/31/01) */
4243 v->flags |= VIDEO_AUDIO_VOLUME;
4244 return;
4245 }
4246
4247 /* 32 levels logarithmic */
4248 vol = 32 - ((v->volume>>11));
4249 /* units */
4250 bits_out = (PT2254_DBS_IN_2>>(vol%5));
4251 /* tens */
4252 bits_out |= (PT2254_DBS_IN_10>>(vol/5));
4253 bits_out |= PT2254_L_CHANNEL | PT2254_R_CHANNEL;
4254 data = gpio_read();
4255 data &= ~(WINVIEW_PT2254_CLK| WINVIEW_PT2254_DATA|
4256 WINVIEW_PT2254_STROBE);
4257 for (loops = 17; loops >= 0 ; loops--) {
4258 if (bits_out & (1<<loops))
4259 data |= WINVIEW_PT2254_DATA;
4260 else
4261 data &= ~WINVIEW_PT2254_DATA;
4262 gpio_write(data);
4263 udelay(5);
4264 data |= WINVIEW_PT2254_CLK;
4265 gpio_write(data);
4266 udelay(5);
4267 data &= ~WINVIEW_PT2254_CLK;
4268 gpio_write(data);
4269 }
4270 data |= WINVIEW_PT2254_STROBE;
4271 data &= ~WINVIEW_PT2254_DATA;
4272 gpio_write(data);
4273 udelay(10);
4274 data &= ~WINVIEW_PT2254_STROBE;
4275 gpio_write(data);
4276}
4277
4278/* ----------------------------------------------------------------------- */
4279/* mono/stereo control for various cards (which don't use i2c chips but */
4280/* connect something to the GPIO pins */
4281
4282static void
4283gvbctv3pci_audio(struct bttv *btv, struct video_audio *v, int set)
4284{
4285 unsigned int con = 0;
4286
4287 if (set) {
4288 gpio_inout(0x300, 0x300);
4289 if (v->mode & VIDEO_SOUND_LANG1)
4290 con = 0x000;
4291 if (v->mode & VIDEO_SOUND_LANG2)
4292 con = 0x300;
4293 if (v->mode & VIDEO_SOUND_STEREO)
4294 con = 0x200;
4295/* if (v->mode & VIDEO_SOUND_MONO)
4296 * con = 0x100; */
4297 gpio_bits(0x300, con);
4298 } else {
4299 v->mode = VIDEO_SOUND_STEREO |
4300 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
4301 }
4302}
4303
4304static void
4305gvbctv5pci_audio(struct bttv *btv, struct video_audio *v, int set)
4306{
4307 unsigned int val, con;
4308
4309 if (btv->radio_user)
4310 return;
4311
4312 val = gpio_read();
4313 if (set) {
4314 con = 0x000;
4315 if (v->mode & VIDEO_SOUND_LANG2) {
4316 if (v->mode & VIDEO_SOUND_LANG1) {
4317 /* LANG1 + LANG2 */
4318 con = 0x100;
4319 }
4320 else {
4321 /* LANG2 */
4322 con = 0x300;
4323 }
4324 }
4325 if (con != (val & 0x300)) {
4326 gpio_bits(0x300, con);
4327 if (bttv_gpio)
4328 bttv_gpio_tracking(btv,"gvbctv5pci");
4329 }
4330 } else {
4331 switch (val & 0x70) {
4332 case 0x10:
4333 v->mode = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
4334 break;
4335 case 0x30:
4336 v->mode = VIDEO_SOUND_LANG2;
4337 break;
4338 case 0x50:
4339 v->mode = VIDEO_SOUND_LANG1;
4340 break;
4341 case 0x60:
4342 v->mode = VIDEO_SOUND_STEREO;
4343 break;
4344 case 0x70:
4345 v->mode = VIDEO_SOUND_MONO;
4346 break;
4347 default:
4348 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
4349 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
4350 }
4351 }
4352}
4353
4354/*
4355 * Mario Medina Nussbaum <medisoft@alohabbs.org.mx>
4356 * I discover that on BT848_GPIO_DATA address a byte 0xcce enable stereo,
4357 * 0xdde enables mono and 0xccd enables sap
4358 *
4359 * Petr Vandrovec <VANDROVE@vc.cvut.cz>
4360 * P.S.: At least mask in line above is wrong - GPIO pins 3,2 select
4361 * input/output sound connection, so both must be set for output mode.
4362 *
4363 * Looks like it's needed only for the "tvphone", the "tvphone 98"
4364 * handles this with a tda9840
4365 *
4366 */
4367static void
4368avermedia_tvphone_audio(struct bttv *btv, struct video_audio *v, int set)
4369{
4370 int val = 0;
4371
4372 if (set) {
4373 if (v->mode & VIDEO_SOUND_LANG2) /* SAP */
4374 val = 0x02;
4375 if (v->mode & VIDEO_SOUND_STEREO)
4376 val = 0x01;
4377 if (val) {
4378 gpio_bits(0x03,val);
4379 if (bttv_gpio)
4380 bttv_gpio_tracking(btv,"avermedia");
4381 }
4382 } else {
4383 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
4384 VIDEO_SOUND_LANG1;
4385 return;
4386 }
4387}
4388
4389static void
4390avermedia_tv_stereo_audio(struct bttv *btv, struct video_audio *v, int set)
4391{
4392 int val = 0;
4393
4394 if (set) {
4395 if (v->mode & VIDEO_SOUND_LANG2) /* SAP */
4396 val = 0x01;
4397 if (v->mode & VIDEO_SOUND_STEREO) /* STEREO */
4398 val = 0x02;
4399 btaor(val, ~0x03, BT848_GPIO_DATA);
4400 if (bttv_gpio)
4401 bttv_gpio_tracking(btv,"avermedia");
4402 } else {
4403 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
4404 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
4405 return;
4406 }
4407}
4408
4409/* Lifetec 9415 handling */
4410static void
4411lt9415_audio(struct bttv *btv, struct video_audio *v, int set)
4412{
4413 int val = 0;
4414
4415 if (gpio_read() & 0x4000) {
4416 v->mode = VIDEO_SOUND_MONO;
4417 return;
4418 }
4419
4420 if (set) {
4421 if (v->mode & VIDEO_SOUND_LANG2) /* A2 SAP */
4422 val = 0x0080;
4423 if (v->mode & VIDEO_SOUND_STEREO) /* A2 stereo */
4424 val = 0x0880;
4425 if ((v->mode & VIDEO_SOUND_LANG1) ||
4426 (v->mode & VIDEO_SOUND_MONO))
4427 val = 0;
4428 gpio_bits(0x0880, val);
4429 if (bttv_gpio)
4430 bttv_gpio_tracking(btv,"lt9415");
4431 } else {
4432 /* autodetect doesn't work with this card :-( */
4433 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
4434 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
4435 return;
4436 }
4437}
4438
4439/* TDA9821 on TerraTV+ Bt848, Bt878 */
4440static void
4441terratv_audio(struct bttv *btv, struct video_audio *v, int set)
4442{
4443 unsigned int con = 0;
4444
4445 if (set) {
4446 gpio_inout(0x180000,0x180000);
4447 if (v->mode & VIDEO_SOUND_LANG2)
4448 con = 0x080000;
4449 if (v->mode & VIDEO_SOUND_STEREO)
4450 con = 0x180000;
4451 gpio_bits(0x180000, con);
4452 if (bttv_gpio)
4453 bttv_gpio_tracking(btv,"terratv");
4454 } else {
4455 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
4456 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
4457 }
4458}
4459
4460static void
4461winfast2000_audio(struct bttv *btv, struct video_audio *v, int set)
4462{
4463 unsigned long val = 0;
4464
4465 if (set) {
4466 /*btor (0xc32000, BT848_GPIO_OUT_EN);*/
4467 if (v->mode & VIDEO_SOUND_MONO) /* Mono */
4468 val = 0x420000;
4469 if (v->mode & VIDEO_SOUND_LANG1) /* Mono */
4470 val = 0x420000;
4471 if (v->mode & VIDEO_SOUND_LANG2) /* SAP */
4472 val = 0x410000;
4473 if (v->mode & VIDEO_SOUND_STEREO) /* Stereo */
4474 val = 0x020000;
4475 if (val) {
4476 gpio_bits(0x430000, val);
4477 if (bttv_gpio)
4478 bttv_gpio_tracking(btv,"winfast2000");
4479 }
4480 } else {
4481 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
4482 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
4483 }
4484}
4485
4486/*
4487 * Dariusz Kowalewski <darekk@automex.pl>
4488 * sound control for Prolink PV-BT878P+9B (PixelView PlayTV Pro FM+NICAM
4489 * revision 9B has on-board TDA9874A sound decoder).
4490 *
4491 * Note: There are card variants without tda9874a. Forcing the "stereo sound route"
4492 * will mute this cards.
4493 */
4494static void
4495pvbt878p9b_audio(struct bttv *btv, struct video_audio *v, int set)
4496{
4497 unsigned int val = 0;
4498
4499 if (btv->radio_user)
4500 return;
4501
4502 if (set) {
4503 if (v->mode & VIDEO_SOUND_MONO) {
4504 val = 0x01;
4505 }
4506 if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2))
4507 || (v->mode & VIDEO_SOUND_STEREO)) {
4508 val = 0x02;
4509 }
4510 if (val) {
4511 gpio_bits(0x03,val);
4512 if (bttv_gpio)
4513 bttv_gpio_tracking(btv,"pvbt878p9b");
4514 }
4515 } else {
4516 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
4517 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
4518 }
4519}
4520
4521/*
4522 * Dariusz Kowalewski <darekk@automex.pl>
4523 * sound control for FlyVideo 2000S (with tda9874 decoder)
4524 * based on pvbt878p9b_audio() - this is not tested, please fix!!!
4525 */
4526static void
4527fv2000s_audio(struct bttv *btv, struct video_audio *v, int set)
4528{
4529 unsigned int val = 0xffff;
4530
4531 if (btv->radio_user)
4532 return;
4533 if (set) {
4534 if (v->mode & VIDEO_SOUND_MONO) {
4535 val = 0x0000;
4536 }
4537 if ((v->mode & (VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2))
4538 || (v->mode & VIDEO_SOUND_STEREO)) {
4539 val = 0x1080; /*-dk-???: 0x0880, 0x0080, 0x1800 ... */
4540 }
4541 if (val != 0xffff) {
4542 gpio_bits(0x1800, val);
4543 if (bttv_gpio)
4544 bttv_gpio_tracking(btv,"fv2000s");
4545 }
4546 } else {
4547 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
4548 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
4549 }
4550}
4551
4552/*
4553 * sound control for Canopus WinDVR PCI
4554 * Masaki Suzuki <masaki@btree.org>
4555 */
4556static void
4557windvr_audio(struct bttv *btv, struct video_audio *v, int set)
4558{
4559 unsigned long val = 0;
4560
4561 if (set) {
4562 if (v->mode & VIDEO_SOUND_MONO)
4563 val = 0x040000;
4564 if (v->mode & VIDEO_SOUND_LANG1)
4565 val = 0;
4566 if (v->mode & VIDEO_SOUND_LANG2)
4567 val = 0x100000;
4568 if (v->mode & VIDEO_SOUND_STEREO)
4569 val = 0;
4570 if (val) {
4571 gpio_bits(0x140000, val);
4572 if (bttv_gpio)
4573 bttv_gpio_tracking(btv,"windvr");
4574 }
4575 } else {
4576 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
4577 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
4578 }
4579}
4580
4581/*
4582 * sound control for AD-TVK503
4583 * Hiroshi Takekawa <sian@big.or.jp>
4584 */
4585static void
4586adtvk503_audio(struct bttv *btv, struct video_audio *v, int set)
4587{
4588 unsigned int con = 0xffffff;
4589
4590 /* btaor(0x1e0000, ~0x1e0000, BT848_GPIO_OUT_EN); */
4591
4592 if (set) {
4593 /* btor(***, BT848_GPIO_OUT_EN); */
4594 if (v->mode & VIDEO_SOUND_LANG1)
4595 con = 0x00000000;
4596 if (v->mode & VIDEO_SOUND_LANG2)
4597 con = 0x00180000;
4598 if (v->mode & VIDEO_SOUND_STEREO)
4599 con = 0x00000000;
4600 if (v->mode & VIDEO_SOUND_MONO)
4601 con = 0x00060000;
4602 if (con != 0xffffff) {
4603 gpio_bits(0x1e0000,con);
4604 if (bttv_gpio)
4605 bttv_gpio_tracking(btv, "adtvk503");
4606 }
4607 } else {
4608 v->mode = VIDEO_SOUND_MONO | VIDEO_SOUND_STEREO |
4609 VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
4610 }
4611}
4612
4613/* RemoteVision MX (rv605) muxsel helper [Miguel Freitas]
4614 *
4615 * This is needed because rv605 don't use a normal multiplex, but a crosspoint
4616 * switch instead (CD22M3494E). This IC can have multiple active connections
4617 * between Xn (input) and Yn (output) pins. We need to clear any existing
4618 * connection prior to establish a new one, pulsing the STROBE pin.
4619 *
4620 * The board hardwire Y0 (xpoint) to MUX1 and MUXOUT to Yin.
4621 * GPIO pins are wired as:
4622 * GPIO[0:3] - AX[0:3] (xpoint) - P1[0:3] (microcontroler)
4623 * GPIO[4:6] - AY[0:2] (xpoint) - P1[4:6] (microcontroler)
4624 * GPIO[7] - DATA (xpoint) - P1[7] (microcontroler)
4625 * GPIO[8] - - P3[5] (microcontroler)
4626 * GPIO[9] - RESET (xpoint) - P3[6] (microcontroler)
4627 * GPIO[10] - STROBE (xpoint) - P3[7] (microcontroler)
4628 * GPINTR - - P3[4] (microcontroler)
4629 *
4630 * The microcontroler is a 80C32 like. It should be possible to change xpoint
4631 * configuration either directly (as we are doing) or using the microcontroler
4632 * which is also wired to I2C interface. I have no further info on the
4633 * microcontroler features, one would need to disassembly the firmware.
4634 * note: the vendor refused to give any information on this product, all
4635 * that stuff was found using a multimeter! :)
4636 */
4637static void rv605_muxsel(struct bttv *btv, unsigned int input)
4638{
4639 /* reset all conections */
4640 gpio_bits(0x200,0x200);
4641 mdelay(1);
4642 gpio_bits(0x200,0x000);
4643 mdelay(1);
4644
4645 /* create a new conection */
4646 gpio_bits(0x480,0x080);
4647 gpio_bits(0x480,0x480);
4648 mdelay(1);
4649 gpio_bits(0x480,0x080);
4650 mdelay(1);
4651}
4652
4653/* Tibet Systems 'Progress DVR' CS16 muxsel helper [Chris Fanning]
4654 *
4655 * The CS16 (available on eBay cheap) is a PCI board with four Fusion
4656 * 878A chips, a PCI bridge, an Atmel microcontroller, four sync seperator
4657 * chips, ten eight input analog multiplexors, a not chip and a few
4658 * other components.
4659 *
4660 * 16 inputs on a secondary bracket are provided and can be selected
4661 * from each of the four capture chips. Two of the eight input
4662 * multiplexors are used to select from any of the 16 input signals.
4663 *
4664 * Unsupported hardware capabilities:
4665 * . A video output monitor on the secondary bracket can be selected from
4666 * one of the 878A chips.
4667 * . Another passthrough but I haven't spent any time investigating it.
4668 * . Digital I/O (logic level connected to GPIO) is available from an
4669 * onboard header.
4670 *
4671 * The on chip input mux should always be set to 2.
4672 * GPIO[16:19] - Video input selection
4673 * GPIO[0:3] - Video output monitor select (only available from one 878A)
4674 * GPIO[?:?] - Digital I/O.
4675 *
4676 * There is an ATMEL microcontroller with an 8031 core on board. I have not
4677 * determined what function (if any) it provides. With the microcontroller
4678 * and sync seperator chips a guess is that it might have to do with video
4679 * switching and maybe some digital I/O.
4680 */
4681static void tibetCS16_muxsel(struct bttv *btv, unsigned int input)
4682{
4683 /* video mux */
4684 gpio_bits(0x0f0000, input << 16);
4685}
4686
4687static void tibetCS16_init(struct bttv *btv)
4688{
4689 /* enable gpio bits, mask obtained via btSpy */
4690 gpio_inout(0xffffff, 0x0f7fff);
4691 gpio_write(0x0f7fff);
4692}
4693
4694/*
4695 * The following routines for the Kodicom-4400r get a little mind-twisting.
4696 * There is a "master" controller and three "slave" controllers, together
4697 * an analog switch which connects any of 16 cameras to any of the BT87A's.
4698 * The analog switch is controlled by the "master", but the detection order
4699 * of the four BT878A chips is in an order which I just don't understand.
4700 * The "master" is actually the second controller to be detected. The
4701 * logic on the board uses logical numbers for the 4 controlers, but
4702 * those numbers are different from the detection sequence. When working
4703 * with the analog switch, we need to "map" from the detection sequence
4704 * over to the board's logical controller number. This mapping sequence
4705 * is {3, 0, 2, 1}, i.e. the first controller to be detected is logical
4706 * unit 3, the second (which is the master) is logical unit 0, etc.
4707 * We need to maintain the status of the analog switch (which of the 16
4708 * cameras is connected to which of the 4 controllers). Rather than
4709 * add to the bttv structure for this, we use the data reserved for
4710 * the mbox (unused for this card type).
4711 */
4712
4713/*
4714 * First a routine to set the analog switch, which controls which camera
4715 * is routed to which controller. The switch comprises an X-address
4716 * (gpio bits 0-3, representing the camera, ranging from 0-15), and a
4717 * Y-address (gpio bits 4-6, representing the controller, ranging from 0-3).
4718 * A data value (gpio bit 7) of '1' enables the switch, and '0' disables
4719 * the switch. A STROBE bit (gpio bit 8) latches the data value into the
4720 * specified address. The idea is to set the address and data, then bring
4721 * STROBE high, and finally bring STROBE back to low.
4722 */
4723static void kodicom4400r_write(struct bttv *btv,
4724 unsigned char xaddr,
4725 unsigned char yaddr,
4726 unsigned char data) {
4727 unsigned int udata;
4728
4729 udata = (data << 7) | ((yaddr&3) << 4) | (xaddr&0xf);
4730 gpio_bits(0x1ff, udata); /* write ADDR and DAT */
4731 gpio_bits(0x1ff, udata | (1 << 8)); /* strobe high */
4732 gpio_bits(0x1ff, udata); /* strobe low */
4733}
4734
4735/*
4736 * Next the mux select. Both the "master" and "slave" 'cards' (controllers)
4737 * use this routine. The routine finds the "master" for the card, maps
4738 * the controller number from the detected position over to the logical
4739 * number, writes the appropriate data to the analog switch, and housekeeps
4740 * the local copy of the switch information. The parameter 'input' is the
4741 * requested camera number (0 - 15).
4742 */
4743static void kodicom4400r_muxsel(struct bttv *btv, unsigned int input)
4744{
4745 char *sw_status;
4746 int xaddr, yaddr;
4747 struct bttv *mctlr;
4748 static unsigned char map[4] = {3, 0, 2, 1};
4749
4750 mctlr = master[btv->c.nr];
4751 if (mctlr == NULL) { /* ignore if master not yet detected */
4752 return;
4753 }
4754 yaddr = (btv->c.nr - mctlr->c.nr + 1) & 3; /* the '&' is for safety */
4755 yaddr = map[yaddr];
4756 sw_status = (char *)(&mctlr->mbox_we);
4757 xaddr = input & 0xf;
4758 /* Check if the controller/camera pair has changed, else ignore */
4759 if (sw_status[yaddr] != xaddr)
4760 {
4761 /* "open" the old switch, "close" the new one, save the new */
4762 kodicom4400r_write(mctlr, sw_status[yaddr], yaddr, 0);
4763 sw_status[yaddr] = xaddr;
4764 kodicom4400r_write(mctlr, xaddr, yaddr, 1);
4765 }
4766}
4767
4768/*
4769 * During initialisation, we need to reset the analog switch. We
4770 * also preset the switch to map the 4 connectors on the card to the
4771 * *user's* (see above description of kodicom4400r_muxsel) channels
4772 * 0 through 3
4773 */
4774static void kodicom4400r_init(struct bttv *btv)
4775{
4776 char *sw_status = (char *)(&btv->mbox_we);
4777 int ix;
4778
4779 gpio_inout(0x0003ff, 0x0003ff);
4780 gpio_write(1 << 9); /* reset MUX */
4781 gpio_write(0);
4782 /* Preset camera 0 to the 4 controllers */
4783 for (ix=0; ix<4; ix++) {
4784 sw_status[ix] = ix;
4785 kodicom4400r_write(btv, ix, ix, 1);
4786 }
4787 /*
4788 * Since this is the "master", we need to set up the
4789 * other three controller chips' pointers to this structure
4790 * for later use in the muxsel routine.
4791 */
4792 if ((btv->c.nr<1) || (btv->c.nr>BTTV_MAX-3))
4793 return;
4794 master[btv->c.nr-1] = btv;
4795 master[btv->c.nr] = btv;
4796 master[btv->c.nr+1] = btv;
4797 master[btv->c.nr+2] = btv;
4798}
4799
4800/* The Grandtec X-Guard framegrabber card uses two Dual 4-channel
4801 * video multiplexers to provide up to 16 video inputs. These
4802 * multiplexers are controlled by the lower 8 GPIO pins of the
4803 * bt878. The multiplexers probably Pericom PI5V331Q or similar.
4804
4805 * xxx0 is pin xxx of multiplexer U5,
4806 * yyy1 is pin yyy of multiplexer U2
4807 */
4808#define ENA0 0x01
4809#define ENB0 0x02
4810#define ENA1 0x04
4811#define ENB1 0x08
4812
4813#define IN10 0x10
4814#define IN00 0x20
4815#define IN11 0x40
4816#define IN01 0x80
4817
4818static void xguard_muxsel(struct bttv *btv, unsigned int input)
4819{
4820 static const int masks[] = {
4821 ENB0, ENB0|IN00, ENB0|IN10, ENB0|IN00|IN10,
4822 ENA0, ENA0|IN00, ENA0|IN10, ENA0|IN00|IN10,
4823 ENB1, ENB1|IN01, ENB1|IN11, ENB1|IN01|IN11,
4824 ENA1, ENA1|IN01, ENA1|IN11, ENA1|IN01|IN11,
4825 };
4826 gpio_write(masks[input%16]);
4827}
4828static void picolo_tetra_init(struct bttv *btv)
4829{
4830 /*This is the video input redirection fonctionality : I DID NOT USED IT. */
4831 btwrite (0x08<<16,BT848_GPIO_DATA);/*GPIO[19] [==> 4053 B+C] set to 1 */
4832 btwrite (0x04<<16,BT848_GPIO_DATA);/*GPIO[18] [==> 4053 A] set to 1*/
4833}
4834static void picolo_tetra_muxsel (struct bttv* btv, unsigned int input)
4835{
4836
4837 dprintk (KERN_DEBUG "bttv%d : picolo_tetra_muxsel => input = %d\n",btv->c.nr,input);
4838 /*Just set the right path in the analog multiplexers : channel 1 -> 4 ==> Analog Mux ==> MUX0*/
4839 /*GPIO[20]&GPIO[21] used to choose the right input*/
4840 btwrite (input<<20,BT848_GPIO_DATA);
4841
4842}
4843
4844/*
4845 * ivc120_muxsel [Added by Alan Garfield <alan@fromorbit.com>]
4846 *
4847 * The IVC120G security card has 4 i2c controlled TDA8540 matrix
4848 * swichers to provide 16 channels to MUX0. The TDA8540's have
4849 * 4 indepedant outputs and as such the IVC120G also has the
4850 * optional "Monitor Out" bus. This allows the card to be looking
4851 * at one input while the monitor is looking at another.
4852 *
4853 * Since I've couldn't be bothered figuring out how to add an
4854 * independant muxsel for the monitor bus, I've just set it to
4855 * whatever the card is looking at.
4856 *
4857 * OUT0 of the TDA8540's is connected to MUX0 (0x03)
4858 * OUT1 of the TDA8540's is connected to "Monitor Out" (0x0C)
4859 *
4860 * TDA8540_ALT3 IN0-3 = Channel 13 - 16 (0x03)
4861 * TDA8540_ALT4 IN0-3 = Channel 1 - 4 (0x03)
4862 * TDA8540_ALT5 IN0-3 = Channel 5 - 8 (0x03)
4863 * TDA8540_ALT6 IN0-3 = Channel 9 - 12 (0x03)
4864 *
4865 */
4866
4867/* All 7 possible sub-ids for the TDA8540 Matrix Switcher */
4868#define I2C_TDA8540 0x90
4869#define I2C_TDA8540_ALT1 0x92
4870#define I2C_TDA8540_ALT2 0x94
4871#define I2C_TDA8540_ALT3 0x96
4872#define I2C_TDA8540_ALT4 0x98
4873#define I2C_TDA8540_ALT5 0x9a
4874#define I2C_TDA8540_ALT6 0x9c
4875
4876static void ivc120_muxsel(struct bttv *btv, unsigned int input)
4877{
4878 /* Simple maths */
4879 int key = input % 4;
4880 int matrix = input / 4;
4881
4882 dprintk("bttv%d: ivc120_muxsel: Input - %02d | TDA - %02d | In - %02d\n",
4883 btv->c.nr, input, matrix, key);
4884
4885 /* Handles the input selection on the TDA8540's */
4886 bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x00,
4887 ((matrix == 3) ? (key | key << 2) : 0x00), 1);
4888 bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x00,
4889 ((matrix == 0) ? (key | key << 2) : 0x00), 1);
4890 bttv_I2CWrite(btv, I2C_TDA8540_ALT5, 0x00,
4891 ((matrix == 1) ? (key | key << 2) : 0x00), 1);
4892 bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x00,
4893 ((matrix == 2) ? (key | key << 2) : 0x00), 1);
4894
4895 /* Handles the output enables on the TDA8540's */
4896 bttv_I2CWrite(btv, I2C_TDA8540_ALT3, 0x02,
4897 ((matrix == 3) ? 0x03 : 0x00), 1); /* 13 - 16 */
4898 bttv_I2CWrite(btv, I2C_TDA8540_ALT4, 0x02,
4899 ((matrix == 0) ? 0x03 : 0x00), 1); /* 1-4 */
4900 bttv_I2CWrite(btv, I2C_TDA8540_ALT5, 0x02,
4901 ((matrix == 1) ? 0x03 : 0x00), 1); /* 5-8 */
4902 bttv_I2CWrite(btv, I2C_TDA8540_ALT6, 0x02,
4903 ((matrix == 2) ? 0x03 : 0x00), 1); /* 9-12 */
4904
4905 /* Selects MUX0 for input on the 878 */
4906 btaor((0)<<5, ~(3<<5), BT848_IFORM);
4907}
4908
4909
4910/* PXC200 muxsel helper
4911 * luke@syseng.anu.edu.au
4912 * another transplant
4913 * from Alessandro Rubini (rubini@linux.it)
4914 *
4915 * There are 4 kinds of cards:
4916 * PXC200L which is bt848
4917 * PXC200F which is bt848 with PIC controlling mux
4918 * PXC200AL which is bt878
4919 * PXC200AF which is bt878 with PIC controlling mux
4920 */
4921#define PX_CFG_PXC200F 0x01
4922#define PX_FLAG_PXC200A 0x00001000 /* a pxc200A is bt-878 based */
4923#define PX_I2C_PIC 0x0f
4924#define PX_PXC200A_CARDID 0x200a1295
4925#define PX_I2C_CMD_CFG 0x00
4926
4927static void PXC200_muxsel(struct bttv *btv, unsigned int input)
4928{
4929 int rc;
4930 long mux;
4931 int bitmask;
4932 unsigned char buf[2];
4933
4934 /* Read PIC config to determine if this is a PXC200F */
4935 /* PX_I2C_CMD_CFG*/
4936 buf[0]=0;
4937 buf[1]=0;
4938 rc=bttv_I2CWrite(btv,(PX_I2C_PIC<<1),buf[0],buf[1],1);
4939 if (rc) {
4940 printk(KERN_DEBUG "bttv%d: PXC200_muxsel: pic cfg write failed:%d\n", btv->c.nr,rc);
4941 /* not PXC ? do nothing */
4942 return;
4943 }
4944
4945 rc=bttv_I2CRead(btv,(PX_I2C_PIC<<1),NULL);
4946 if (!(rc & PX_CFG_PXC200F)) {
4947 printk(KERN_DEBUG "bttv%d: PXC200_muxsel: not PXC200F rc:%d \n", btv->c.nr,rc);
4948 return;
4949 }
4950
4951
4952 /* The multiplexer in the 200F is handled by the GPIO port */
4953 /* get correct mapping between inputs */
4954 /* mux = bttv_tvcards[btv->type].muxsel[input] & 3; */
4955 /* ** not needed!? */
4956 mux = input;
4957
4958 /* make sure output pins are enabled */
4959 /* bitmask=0x30f; */
4960 bitmask=0x302;
4961 /* check whether we have a PXC200A */
4962 if (btv->cardid == PX_PXC200A_CARDID) {
4963 bitmask ^= 0x180; /* use 7 and 9, not 8 and 9 */
4964 bitmask |= 7<<4; /* the DAC */
4965 }
4966 btwrite(bitmask, BT848_GPIO_OUT_EN);
4967
4968 bitmask = btread(BT848_GPIO_DATA);
4969 if (btv->cardid == PX_PXC200A_CARDID)
4970 bitmask = (bitmask & ~0x280) | ((mux & 2) << 8) | ((mux & 1) << 7);
4971 else /* older device */
4972 bitmask = (bitmask & ~0x300) | ((mux & 3) << 8);
4973 btwrite(bitmask,BT848_GPIO_DATA);
4974
4975 /*
4976 * Was "to be safe, set the bt848 to input 0"
4977 * Actually, since it's ok at load time, better not messing
4978 * with these bits (on PXC200AF you need to set mux 2 here)
4979 *
4980 * needed because bttv-driver sets mux before calling this function
4981 */
4982 if (btv->cardid == PX_PXC200A_CARDID)
4983 btaor(2<<5, ~BT848_IFORM_MUXSEL, BT848_IFORM);
4984 else /* older device */
4985 btand(~BT848_IFORM_MUXSEL,BT848_IFORM);
4986
4987 printk(KERN_DEBUG "bttv%d: setting input channel to:%d\n", btv->c.nr,(int)mux);
4988}
4989
4990/* ----------------------------------------------------------------------- */
4991/* motherboard chipset specific stuff */
4992
4993void __devinit bttv_check_chipset(void)
4994{
4995 int pcipci_fail = 0;
4996 struct pci_dev *dev = NULL;
4997
4998 if (pci_pci_problems & PCIPCI_FAIL)
4999 pcipci_fail = 1;
5000 if (pci_pci_problems & (PCIPCI_TRITON|PCIPCI_NATOMA|PCIPCI_VIAETBF))
5001 triton1 = 1;
5002 if (pci_pci_problems & PCIPCI_VSFX)
5003 vsfx = 1;
5004#ifdef PCIPCI_ALIMAGIK
5005 if (pci_pci_problems & PCIPCI_ALIMAGIK)
5006 latency = 0x0A;
5007#endif
5008
5009
5010 /* print warnings about any quirks found */
5011 if (triton1)
5012 printk(KERN_INFO "bttv: Host bridge needs ETBF enabled.\n");
5013 if (vsfx)
5014 printk(KERN_INFO "bttv: Host bridge needs VSFX enabled.\n");
5015 if (pcipci_fail) {
5016 printk(KERN_INFO "bttv: bttv and your chipset may not work "
5017 "together.\n");
5018 if (!no_overlay) {
5019 printk(KERN_INFO "bttv: overlay will be disabled.\n");
5020 no_overlay = 1;
5021 } else {
5022 printk(KERN_INFO "bttv: overlay forced. Use this "
5023 "option at your own risk.\n");
5024 }
5025 }
5026 if (UNSET != latency)
5027 printk(KERN_INFO "bttv: pci latency fixup [%d]\n",latency);
5028 while ((dev = pci_get_device(PCI_VENDOR_ID_INTEL,
5029 PCI_DEVICE_ID_INTEL_82441, dev))) {
5030 unsigned char b;
5031 pci_read_config_byte(dev, 0x53, &b);
5032 if (bttv_debug)
5033 printk(KERN_INFO "bttv: Host bridge: 82441FX Natoma, "
5034 "bufcon=0x%02x\n",b);
5035 }
5036}
5037
5038int __devinit bttv_handle_chipset(struct bttv *btv)
5039{
5040 unsigned char command;
5041
5042 if (!triton1 && !vsfx && UNSET == latency)
5043 return 0;
5044
5045 if (bttv_verbose) {
5046 if (triton1)
5047 printk(KERN_INFO "bttv%d: enabling ETBF (430FX/VP3 compatibilty)\n",btv->c.nr);
5048 if (vsfx && btv->id >= 878)
5049 printk(KERN_INFO "bttv%d: enabling VSFX\n",btv->c.nr);
5050 if (UNSET != latency)
5051 printk(KERN_INFO "bttv%d: setting pci timer to %d\n",
5052 btv->c.nr,latency);
5053 }
5054
5055 if (btv->id < 878) {
5056 /* bt848 (mis)uses a bit in the irq mask for etbf */
5057 if (triton1)
5058 btv->triton1 = BT848_INT_ETBF;
5059 } else {
5060 /* bt878 has a bit in the pci config space for it */
5061 pci_read_config_byte(btv->c.pci, BT878_DEVCTRL, &command);
5062 if (triton1)
5063 command |= BT878_EN_TBFX;
5064 if (vsfx)
5065 command |= BT878_EN_VSFX;
5066 pci_write_config_byte(btv->c.pci, BT878_DEVCTRL, command);
5067 }
5068 if (UNSET != latency)
5069 pci_write_config_byte(btv->c.pci, PCI_LATENCY_TIMER, latency);
5070 return 0;
5071}
5072
5073
5074/*
5075 * Local variables:
5076 * c-basic-offset: 8
5077 * End:
5078 */
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c
new file mode 100644
index 000000000000..74def9c23952
--- /dev/null
+++ b/drivers/media/video/bt8xx/bttv-driver.c
@@ -0,0 +1,4321 @@
1/*
2
3 bttv - Bt848 frame grabber driver
4
5 Copyright (C) 1996,97,98 Ralph Metzler <rjkm@thp.uni-koeln.de>
6 & Marcus Metzler <mocm@thp.uni-koeln.de>
7 (c) 1999-2002 Gerd Knorr <kraxel@bytesex.org>
8
9 some v4l2 code lines are taken from Justin's bttv2 driver which is
10 (c) 2000 Justin Schoeman <justin@suntiger.ee.up.ac.za>
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25*/
26
27#include <linux/init.h>
28#include <linux/module.h>
29#include <linux/moduleparam.h>
30#include <linux/delay.h>
31#include <linux/errno.h>
32#include <linux/fs.h>
33#include <linux/kernel.h>
34#include <linux/sched.h>
35#include <linux/interrupt.h>
36#include <linux/kdev_t.h>
37#include "bttvp.h"
38#include <media/v4l2-common.h>
39#include <media/tvaudio.h>
40#include <media/msp3400.h>
41
42#include <linux/dma-mapping.h>
43
44#include <asm/io.h>
45#include <asm/byteorder.h>
46
47#include <media/rds.h>
48
49
50unsigned int bttv_num; /* number of Bt848s in use */
51struct bttv bttvs[BTTV_MAX];
52
53unsigned int bttv_debug;
54unsigned int bttv_verbose = 1;
55unsigned int bttv_gpio;
56
57/* config variables */
58#ifdef __BIG_ENDIAN
59static unsigned int bigendian=1;
60#else
61static unsigned int bigendian;
62#endif
63static unsigned int radio[BTTV_MAX];
64static unsigned int irq_debug;
65static unsigned int gbuffers = 8;
66static unsigned int gbufsize = 0x208000;
67
68static int video_nr = -1;
69static int radio_nr = -1;
70static int vbi_nr = -1;
71static int debug_latency;
72
73static unsigned int fdsr;
74
75/* options */
76static unsigned int combfilter;
77static unsigned int lumafilter;
78static unsigned int automute = 1;
79static unsigned int chroma_agc;
80static unsigned int adc_crush = 1;
81static unsigned int whitecrush_upper = 0xCF;
82static unsigned int whitecrush_lower = 0x7F;
83static unsigned int vcr_hack;
84static unsigned int irq_iswitch;
85static unsigned int uv_ratio = 50;
86static unsigned int full_luma_range;
87static unsigned int coring;
88extern int no_overlay;
89
90/* API features (turn on/off stuff for testing) */
91static unsigned int v4l2 = 1;
92
93/* insmod args */
94module_param(bttv_verbose, int, 0644);
95module_param(bttv_gpio, int, 0644);
96module_param(bttv_debug, int, 0644);
97module_param(irq_debug, int, 0644);
98module_param(debug_latency, int, 0644);
99
100module_param(fdsr, int, 0444);
101module_param(video_nr, int, 0444);
102module_param(radio_nr, int, 0444);
103module_param(vbi_nr, int, 0444);
104module_param(gbuffers, int, 0444);
105module_param(gbufsize, int, 0444);
106
107module_param(v4l2, int, 0644);
108module_param(bigendian, int, 0644);
109module_param(irq_iswitch, int, 0644);
110module_param(combfilter, int, 0444);
111module_param(lumafilter, int, 0444);
112module_param(automute, int, 0444);
113module_param(chroma_agc, int, 0444);
114module_param(adc_crush, int, 0444);
115module_param(whitecrush_upper, int, 0444);
116module_param(whitecrush_lower, int, 0444);
117module_param(vcr_hack, int, 0444);
118module_param(uv_ratio, int, 0444);
119module_param(full_luma_range, int, 0444);
120module_param(coring, int, 0444);
121
122module_param_array(radio, int, NULL, 0444);
123
124MODULE_PARM_DESC(radio,"The TV card supports radio, default is 0 (no)");
125MODULE_PARM_DESC(bigendian,"byte order of the framebuffer, default is native endian");
126MODULE_PARM_DESC(bttv_verbose,"verbose startup messages, default is 1 (yes)");
127MODULE_PARM_DESC(bttv_gpio,"log gpio changes, default is 0 (no)");
128MODULE_PARM_DESC(bttv_debug,"debug messages, default is 0 (no)");
129MODULE_PARM_DESC(irq_debug,"irq handler debug messages, default is 0 (no)");
130MODULE_PARM_DESC(gbuffers,"number of capture buffers. range 2-32, default 8");
131MODULE_PARM_DESC(gbufsize,"size of the capture buffers, default is 0x208000");
132MODULE_PARM_DESC(automute,"mute audio on bad/missing video signal, default is 1 (yes)");
133MODULE_PARM_DESC(chroma_agc,"enables the AGC of chroma signal, default is 0 (no)");
134MODULE_PARM_DESC(adc_crush,"enables the luminance ADC crush, default is 1 (yes)");
135MODULE_PARM_DESC(whitecrush_upper,"sets the white crush upper value, default is 207");
136MODULE_PARM_DESC(whitecrush_lower,"sets the white crush lower value, default is 127");
137MODULE_PARM_DESC(vcr_hack,"enables the VCR hack (improves synch on poor VCR tapes), default is 0 (no)");
138MODULE_PARM_DESC(irq_iswitch,"switch inputs in irq handler");
139MODULE_PARM_DESC(uv_ratio,"ratio between u and v gains, default is 50");
140MODULE_PARM_DESC(full_luma_range,"use the full luma range, default is 0 (no)");
141MODULE_PARM_DESC(coring,"set the luma coring level, default is 0 (no)");
142
143MODULE_DESCRIPTION("bttv - v4l/v4l2 driver module for bt848/878 based cards");
144MODULE_AUTHOR("Ralph Metzler & Marcus Metzler & Gerd Knorr");
145MODULE_LICENSE("GPL");
146
147/* ----------------------------------------------------------------------- */
148/* sysfs */
149
150static ssize_t show_card(struct class_device *cd, char *buf)
151{
152 struct video_device *vfd = to_video_device(cd);
153 struct bttv *btv = dev_get_drvdata(vfd->dev);
154 return sprintf(buf, "%d\n", btv ? btv->c.type : UNSET);
155}
156static CLASS_DEVICE_ATTR(card, S_IRUGO, show_card, NULL);
157
158/* ----------------------------------------------------------------------- */
159/* static data */
160
161/* special timing tables from conexant... */
162static u8 SRAM_Table[][60] =
163{
164 /* PAL digital input over GPIO[7:0] */
165 {
166 45, // 45 bytes following
167 0x36,0x11,0x01,0x00,0x90,0x02,0x05,0x10,0x04,0x16,
168 0x12,0x05,0x11,0x00,0x04,0x12,0xC0,0x00,0x31,0x00,
169 0x06,0x51,0x08,0x03,0x89,0x08,0x07,0xC0,0x44,0x00,
170 0x81,0x01,0x01,0xA9,0x0D,0x02,0x02,0x50,0x03,0x37,
171 0x37,0x00,0xAF,0x21,0x00
172 },
173 /* NTSC digital input over GPIO[7:0] */
174 {
175 51, // 51 bytes following
176 0x0C,0xC0,0x00,0x00,0x90,0x02,0x03,0x10,0x03,0x06,
177 0x10,0x04,0x12,0x12,0x05,0x02,0x13,0x04,0x19,0x00,
178 0x04,0x39,0x00,0x06,0x59,0x08,0x03,0x83,0x08,0x07,
179 0x03,0x50,0x00,0xC0,0x40,0x00,0x86,0x01,0x01,0xA6,
180 0x0D,0x02,0x03,0x11,0x01,0x05,0x37,0x00,0xAC,0x21,
181 0x00,
182 },
183 // TGB_NTSC392 // quartzsight
184 // This table has been modified to be used for Fusion Rev D
185 {
186 0x2A, // size of table = 42
187 0x06, 0x08, 0x04, 0x0a, 0xc0, 0x00, 0x18, 0x08, 0x03, 0x24,
188 0x08, 0x07, 0x02, 0x90, 0x02, 0x08, 0x10, 0x04, 0x0c, 0x10,
189 0x05, 0x2c, 0x11, 0x04, 0x55, 0x48, 0x00, 0x05, 0x50, 0x00,
190 0xbf, 0x0c, 0x02, 0x2f, 0x3d, 0x00, 0x2f, 0x3f, 0x00, 0xc3,
191 0x20, 0x00
192 }
193};
194
195const struct bttv_tvnorm bttv_tvnorms[] = {
196 /* PAL-BDGHI */
197 /* max. active video is actually 922, but 924 is divisible by 4 and 3! */
198 /* actually, max active PAL with HSCALE=0 is 948, NTSC is 768 - nil */
199 {
200 .v4l2_id = V4L2_STD_PAL,
201 .name = "PAL",
202 .Fsc = 35468950,
203 .swidth = 924,
204 .sheight = 576,
205 .totalwidth = 1135,
206 .adelay = 0x7f,
207 .bdelay = 0x72,
208 .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
209 .scaledtwidth = 1135,
210 .hdelayx1 = 186,
211 .hactivex1 = 924,
212 .vdelay = 0x20,
213 .vbipack = 255,
214 .sram = 0,
215 /* ITU-R frame line number of the first VBI line
216 we can capture, of the first and second field. */
217 .vbistart = { 7,320 },
218 },{
219 .v4l2_id = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
220 .name = "NTSC",
221 .Fsc = 28636363,
222 .swidth = 768,
223 .sheight = 480,
224 .totalwidth = 910,
225 .adelay = 0x68,
226 .bdelay = 0x5d,
227 .iform = (BT848_IFORM_NTSC|BT848_IFORM_XT0),
228 .scaledtwidth = 910,
229 .hdelayx1 = 128,
230 .hactivex1 = 910,
231 .vdelay = 0x1a,
232 .vbipack = 144,
233 .sram = 1,
234 .vbistart = { 10, 273 },
235 },{
236 .v4l2_id = V4L2_STD_SECAM,
237 .name = "SECAM",
238 .Fsc = 35468950,
239 .swidth = 924,
240 .sheight = 576,
241 .totalwidth = 1135,
242 .adelay = 0x7f,
243 .bdelay = 0xb0,
244 .iform = (BT848_IFORM_SECAM|BT848_IFORM_XT1),
245 .scaledtwidth = 1135,
246 .hdelayx1 = 186,
247 .hactivex1 = 922,
248 .vdelay = 0x20,
249 .vbipack = 255,
250 .sram = 0, /* like PAL, correct? */
251 .vbistart = { 7, 320 },
252 },{
253 .v4l2_id = V4L2_STD_PAL_Nc,
254 .name = "PAL-Nc",
255 .Fsc = 28636363,
256 .swidth = 640,
257 .sheight = 576,
258 .totalwidth = 910,
259 .adelay = 0x68,
260 .bdelay = 0x5d,
261 .iform = (BT848_IFORM_PAL_NC|BT848_IFORM_XT0),
262 .scaledtwidth = 780,
263 .hdelayx1 = 130,
264 .hactivex1 = 734,
265 .vdelay = 0x1a,
266 .vbipack = 144,
267 .sram = -1,
268 .vbistart = { 7, 320 },
269 },{
270 .v4l2_id = V4L2_STD_PAL_M,
271 .name = "PAL-M",
272 .Fsc = 28636363,
273 .swidth = 640,
274 .sheight = 480,
275 .totalwidth = 910,
276 .adelay = 0x68,
277 .bdelay = 0x5d,
278 .iform = (BT848_IFORM_PAL_M|BT848_IFORM_XT0),
279 .scaledtwidth = 780,
280 .hdelayx1 = 135,
281 .hactivex1 = 754,
282 .vdelay = 0x1a,
283 .vbipack = 144,
284 .sram = -1,
285 .vbistart = { 10, 273 },
286 },{
287 .v4l2_id = V4L2_STD_PAL_N,
288 .name = "PAL-N",
289 .Fsc = 35468950,
290 .swidth = 768,
291 .sheight = 576,
292 .totalwidth = 1135,
293 .adelay = 0x7f,
294 .bdelay = 0x72,
295 .iform = (BT848_IFORM_PAL_N|BT848_IFORM_XT1),
296 .scaledtwidth = 944,
297 .hdelayx1 = 186,
298 .hactivex1 = 922,
299 .vdelay = 0x20,
300 .vbipack = 144,
301 .sram = -1,
302 .vbistart = { 7, 320},
303 },{
304 .v4l2_id = V4L2_STD_NTSC_M_JP,
305 .name = "NTSC-JP",
306 .Fsc = 28636363,
307 .swidth = 640,
308 .sheight = 480,
309 .totalwidth = 910,
310 .adelay = 0x68,
311 .bdelay = 0x5d,
312 .iform = (BT848_IFORM_NTSC_J|BT848_IFORM_XT0),
313 .scaledtwidth = 780,
314 .hdelayx1 = 135,
315 .hactivex1 = 754,
316 .vdelay = 0x16,
317 .vbipack = 144,
318 .sram = -1,
319 .vbistart = {10, 273},
320 },{
321 /* that one hopefully works with the strange timing
322 * which video recorders produce when playing a NTSC
323 * tape on a PAL TV ... */
324 .v4l2_id = V4L2_STD_PAL_60,
325 .name = "PAL-60",
326 .Fsc = 35468950,
327 .swidth = 924,
328 .sheight = 480,
329 .totalwidth = 1135,
330 .adelay = 0x7f,
331 .bdelay = 0x72,
332 .iform = (BT848_IFORM_PAL_BDGHI|BT848_IFORM_XT1),
333 .scaledtwidth = 1135,
334 .hdelayx1 = 186,
335 .hactivex1 = 924,
336 .vdelay = 0x1a,
337 .vbipack = 255,
338 .vtotal = 524,
339 .sram = -1,
340 .vbistart = { 10, 273 },
341 }
342};
343static const unsigned int BTTV_TVNORMS = ARRAY_SIZE(bttv_tvnorms);
344
345/* ----------------------------------------------------------------------- */
346/* bttv format list
347 packed pixel formats must come first */
348static const struct bttv_format bttv_formats[] = {
349 {
350 .name = "8 bpp, gray",
351 .palette = VIDEO_PALETTE_GREY,
352 .fourcc = V4L2_PIX_FMT_GREY,
353 .btformat = BT848_COLOR_FMT_Y8,
354 .depth = 8,
355 .flags = FORMAT_FLAGS_PACKED,
356 },{
357 .name = "8 bpp, dithered color",
358 .palette = VIDEO_PALETTE_HI240,
359 .fourcc = V4L2_PIX_FMT_HI240,
360 .btformat = BT848_COLOR_FMT_RGB8,
361 .depth = 8,
362 .flags = FORMAT_FLAGS_PACKED | FORMAT_FLAGS_DITHER,
363 },{
364 .name = "15 bpp RGB, le",
365 .palette = VIDEO_PALETTE_RGB555,
366 .fourcc = V4L2_PIX_FMT_RGB555,
367 .btformat = BT848_COLOR_FMT_RGB15,
368 .depth = 16,
369 .flags = FORMAT_FLAGS_PACKED,
370 },{
371 .name = "15 bpp RGB, be",
372 .palette = -1,
373 .fourcc = V4L2_PIX_FMT_RGB555X,
374 .btformat = BT848_COLOR_FMT_RGB15,
375 .btswap = 0x03, /* byteswap */
376 .depth = 16,
377 .flags = FORMAT_FLAGS_PACKED,
378 },{
379 .name = "16 bpp RGB, le",
380 .palette = VIDEO_PALETTE_RGB565,
381 .fourcc = V4L2_PIX_FMT_RGB565,
382 .btformat = BT848_COLOR_FMT_RGB16,
383 .depth = 16,
384 .flags = FORMAT_FLAGS_PACKED,
385 },{
386 .name = "16 bpp RGB, be",
387 .palette = -1,
388 .fourcc = V4L2_PIX_FMT_RGB565X,
389 .btformat = BT848_COLOR_FMT_RGB16,
390 .btswap = 0x03, /* byteswap */
391 .depth = 16,
392 .flags = FORMAT_FLAGS_PACKED,
393 },{
394 .name = "24 bpp RGB, le",
395 .palette = VIDEO_PALETTE_RGB24,
396 .fourcc = V4L2_PIX_FMT_BGR24,
397 .btformat = BT848_COLOR_FMT_RGB24,
398 .depth = 24,
399 .flags = FORMAT_FLAGS_PACKED,
400 },{
401 .name = "32 bpp RGB, le",
402 .palette = VIDEO_PALETTE_RGB32,
403 .fourcc = V4L2_PIX_FMT_BGR32,
404 .btformat = BT848_COLOR_FMT_RGB32,
405 .depth = 32,
406 .flags = FORMAT_FLAGS_PACKED,
407 },{
408 .name = "32 bpp RGB, be",
409 .palette = -1,
410 .fourcc = V4L2_PIX_FMT_RGB32,
411 .btformat = BT848_COLOR_FMT_RGB32,
412 .btswap = 0x0f, /* byte+word swap */
413 .depth = 32,
414 .flags = FORMAT_FLAGS_PACKED,
415 },{
416 .name = "4:2:2, packed, YUYV",
417 .palette = VIDEO_PALETTE_YUV422,
418 .fourcc = V4L2_PIX_FMT_YUYV,
419 .btformat = BT848_COLOR_FMT_YUY2,
420 .depth = 16,
421 .flags = FORMAT_FLAGS_PACKED,
422 },{
423 .name = "4:2:2, packed, YUYV",
424 .palette = VIDEO_PALETTE_YUYV,
425 .fourcc = V4L2_PIX_FMT_YUYV,
426 .btformat = BT848_COLOR_FMT_YUY2,
427 .depth = 16,
428 .flags = FORMAT_FLAGS_PACKED,
429 },{
430 .name = "4:2:2, packed, UYVY",
431 .palette = VIDEO_PALETTE_UYVY,
432 .fourcc = V4L2_PIX_FMT_UYVY,
433 .btformat = BT848_COLOR_FMT_YUY2,
434 .btswap = 0x03, /* byteswap */
435 .depth = 16,
436 .flags = FORMAT_FLAGS_PACKED,
437 },{
438 .name = "4:2:2, planar, Y-Cb-Cr",
439 .palette = VIDEO_PALETTE_YUV422P,
440 .fourcc = V4L2_PIX_FMT_YUV422P,
441 .btformat = BT848_COLOR_FMT_YCrCb422,
442 .depth = 16,
443 .flags = FORMAT_FLAGS_PLANAR,
444 .hshift = 1,
445 .vshift = 0,
446 },{
447 .name = "4:2:0, planar, Y-Cb-Cr",
448 .palette = VIDEO_PALETTE_YUV420P,
449 .fourcc = V4L2_PIX_FMT_YUV420,
450 .btformat = BT848_COLOR_FMT_YCrCb422,
451 .depth = 12,
452 .flags = FORMAT_FLAGS_PLANAR,
453 .hshift = 1,
454 .vshift = 1,
455 },{
456 .name = "4:2:0, planar, Y-Cr-Cb",
457 .palette = -1,
458 .fourcc = V4L2_PIX_FMT_YVU420,
459 .btformat = BT848_COLOR_FMT_YCrCb422,
460 .depth = 12,
461 .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb,
462 .hshift = 1,
463 .vshift = 1,
464 },{
465 .name = "4:1:1, planar, Y-Cb-Cr",
466 .palette = VIDEO_PALETTE_YUV411P,
467 .fourcc = V4L2_PIX_FMT_YUV411P,
468 .btformat = BT848_COLOR_FMT_YCrCb411,
469 .depth = 12,
470 .flags = FORMAT_FLAGS_PLANAR,
471 .hshift = 2,
472 .vshift = 0,
473 },{
474 .name = "4:1:0, planar, Y-Cb-Cr",
475 .palette = VIDEO_PALETTE_YUV410P,
476 .fourcc = V4L2_PIX_FMT_YUV410,
477 .btformat = BT848_COLOR_FMT_YCrCb411,
478 .depth = 9,
479 .flags = FORMAT_FLAGS_PLANAR,
480 .hshift = 2,
481 .vshift = 2,
482 },{
483 .name = "4:1:0, planar, Y-Cr-Cb",
484 .palette = -1,
485 .fourcc = V4L2_PIX_FMT_YVU410,
486 .btformat = BT848_COLOR_FMT_YCrCb411,
487 .depth = 9,
488 .flags = FORMAT_FLAGS_PLANAR | FORMAT_FLAGS_CrCb,
489 .hshift = 2,
490 .vshift = 2,
491 },{
492 .name = "raw scanlines",
493 .palette = VIDEO_PALETTE_RAW,
494 .fourcc = -1,
495 .btformat = BT848_COLOR_FMT_RAW,
496 .depth = 8,
497 .flags = FORMAT_FLAGS_RAW,
498 }
499};
500static const unsigned int BTTV_FORMATS = ARRAY_SIZE(bttv_formats);
501
502/* ----------------------------------------------------------------------- */
503
504#define V4L2_CID_PRIVATE_CHROMA_AGC (V4L2_CID_PRIVATE_BASE + 0)
505#define V4L2_CID_PRIVATE_COMBFILTER (V4L2_CID_PRIVATE_BASE + 1)
506#define V4L2_CID_PRIVATE_AUTOMUTE (V4L2_CID_PRIVATE_BASE + 2)
507#define V4L2_CID_PRIVATE_LUMAFILTER (V4L2_CID_PRIVATE_BASE + 3)
508#define V4L2_CID_PRIVATE_AGC_CRUSH (V4L2_CID_PRIVATE_BASE + 4)
509#define V4L2_CID_PRIVATE_VCR_HACK (V4L2_CID_PRIVATE_BASE + 5)
510#define V4L2_CID_PRIVATE_WHITECRUSH_UPPER (V4L2_CID_PRIVATE_BASE + 6)
511#define V4L2_CID_PRIVATE_WHITECRUSH_LOWER (V4L2_CID_PRIVATE_BASE + 7)
512#define V4L2_CID_PRIVATE_UV_RATIO (V4L2_CID_PRIVATE_BASE + 8)
513#define V4L2_CID_PRIVATE_FULL_LUMA_RANGE (V4L2_CID_PRIVATE_BASE + 9)
514#define V4L2_CID_PRIVATE_CORING (V4L2_CID_PRIVATE_BASE + 10)
515#define V4L2_CID_PRIVATE_LASTP1 (V4L2_CID_PRIVATE_BASE + 11)
516
517static const struct v4l2_queryctrl no_ctl = {
518 .name = "42",
519 .flags = V4L2_CTRL_FLAG_DISABLED,
520};
521static const struct v4l2_queryctrl bttv_ctls[] = {
522 /* --- video --- */
523 {
524 .id = V4L2_CID_BRIGHTNESS,
525 .name = "Brightness",
526 .minimum = 0,
527 .maximum = 65535,
528 .step = 256,
529 .default_value = 32768,
530 .type = V4L2_CTRL_TYPE_INTEGER,
531 },{
532 .id = V4L2_CID_CONTRAST,
533 .name = "Contrast",
534 .minimum = 0,
535 .maximum = 65535,
536 .step = 128,
537 .default_value = 32768,
538 .type = V4L2_CTRL_TYPE_INTEGER,
539 },{
540 .id = V4L2_CID_SATURATION,
541 .name = "Saturation",
542 .minimum = 0,
543 .maximum = 65535,
544 .step = 128,
545 .default_value = 32768,
546 .type = V4L2_CTRL_TYPE_INTEGER,
547 },{
548 .id = V4L2_CID_HUE,
549 .name = "Hue",
550 .minimum = 0,
551 .maximum = 65535,
552 .step = 256,
553 .default_value = 32768,
554 .type = V4L2_CTRL_TYPE_INTEGER,
555 },
556 /* --- audio --- */
557 {
558 .id = V4L2_CID_AUDIO_MUTE,
559 .name = "Mute",
560 .minimum = 0,
561 .maximum = 1,
562 .type = V4L2_CTRL_TYPE_BOOLEAN,
563 },{
564 .id = V4L2_CID_AUDIO_VOLUME,
565 .name = "Volume",
566 .minimum = 0,
567 .maximum = 65535,
568 .step = 65535/100,
569 .default_value = 65535,
570 .type = V4L2_CTRL_TYPE_INTEGER,
571 },{
572 .id = V4L2_CID_AUDIO_BALANCE,
573 .name = "Balance",
574 .minimum = 0,
575 .maximum = 65535,
576 .step = 65535/100,
577 .default_value = 32768,
578 .type = V4L2_CTRL_TYPE_INTEGER,
579 },{
580 .id = V4L2_CID_AUDIO_BASS,
581 .name = "Bass",
582 .minimum = 0,
583 .maximum = 65535,
584 .step = 65535/100,
585 .default_value = 32768,
586 .type = V4L2_CTRL_TYPE_INTEGER,
587 },{
588 .id = V4L2_CID_AUDIO_TREBLE,
589 .name = "Treble",
590 .minimum = 0,
591 .maximum = 65535,
592 .step = 65535/100,
593 .default_value = 32768,
594 .type = V4L2_CTRL_TYPE_INTEGER,
595 },
596 /* --- private --- */
597 {
598 .id = V4L2_CID_PRIVATE_CHROMA_AGC,
599 .name = "chroma agc",
600 .minimum = 0,
601 .maximum = 1,
602 .type = V4L2_CTRL_TYPE_BOOLEAN,
603 },{
604 .id = V4L2_CID_PRIVATE_COMBFILTER,
605 .name = "combfilter",
606 .minimum = 0,
607 .maximum = 1,
608 .type = V4L2_CTRL_TYPE_BOOLEAN,
609 },{
610 .id = V4L2_CID_PRIVATE_AUTOMUTE,
611 .name = "automute",
612 .minimum = 0,
613 .maximum = 1,
614 .type = V4L2_CTRL_TYPE_BOOLEAN,
615 },{
616 .id = V4L2_CID_PRIVATE_LUMAFILTER,
617 .name = "luma decimation filter",
618 .minimum = 0,
619 .maximum = 1,
620 .type = V4L2_CTRL_TYPE_BOOLEAN,
621 },{
622 .id = V4L2_CID_PRIVATE_AGC_CRUSH,
623 .name = "agc crush",
624 .minimum = 0,
625 .maximum = 1,
626 .type = V4L2_CTRL_TYPE_BOOLEAN,
627 },{
628 .id = V4L2_CID_PRIVATE_VCR_HACK,
629 .name = "vcr hack",
630 .minimum = 0,
631 .maximum = 1,
632 .type = V4L2_CTRL_TYPE_BOOLEAN,
633 },{
634 .id = V4L2_CID_PRIVATE_WHITECRUSH_UPPER,
635 .name = "whitecrush upper",
636 .minimum = 0,
637 .maximum = 255,
638 .step = 1,
639 .default_value = 0xCF,
640 .type = V4L2_CTRL_TYPE_INTEGER,
641 },{
642 .id = V4L2_CID_PRIVATE_WHITECRUSH_LOWER,
643 .name = "whitecrush lower",
644 .minimum = 0,
645 .maximum = 255,
646 .step = 1,
647 .default_value = 0x7F,
648 .type = V4L2_CTRL_TYPE_INTEGER,
649 },{
650 .id = V4L2_CID_PRIVATE_UV_RATIO,
651 .name = "uv ratio",
652 .minimum = 0,
653 .maximum = 100,
654 .step = 1,
655 .default_value = 50,
656 .type = V4L2_CTRL_TYPE_INTEGER,
657 },{
658 .id = V4L2_CID_PRIVATE_FULL_LUMA_RANGE,
659 .name = "full luma range",
660 .minimum = 0,
661 .maximum = 1,
662 .type = V4L2_CTRL_TYPE_BOOLEAN,
663 },{
664 .id = V4L2_CID_PRIVATE_CORING,
665 .name = "coring",
666 .minimum = 0,
667 .maximum = 3,
668 .step = 1,
669 .default_value = 0,
670 .type = V4L2_CTRL_TYPE_INTEGER,
671 }
672
673
674
675};
676static const int BTTV_CTLS = ARRAY_SIZE(bttv_ctls);
677
678/* ----------------------------------------------------------------------- */
679/* resource management */
680
681static
682int check_alloc_btres(struct bttv *btv, struct bttv_fh *fh, int bit)
683{
684 if (fh->resources & bit)
685 /* have it already allocated */
686 return 1;
687
688 /* is it free? */
689 mutex_lock(&btv->reslock);
690 if (btv->resources & bit) {
691 /* no, someone else uses it */
692 mutex_unlock(&btv->reslock);
693 return 0;
694 }
695 /* it's free, grab it */
696 fh->resources |= bit;
697 btv->resources |= bit;
698 mutex_unlock(&btv->reslock);
699 return 1;
700}
701
702static
703int check_btres(struct bttv_fh *fh, int bit)
704{
705 return (fh->resources & bit);
706}
707
708static
709int locked_btres(struct bttv *btv, int bit)
710{
711 return (btv->resources & bit);
712}
713
714static
715void free_btres(struct bttv *btv, struct bttv_fh *fh, int bits)
716{
717 if ((fh->resources & bits) != bits) {
718 /* trying to free ressources not allocated by us ... */
719 printk("bttv: BUG! (btres)\n");
720 }
721 mutex_lock(&btv->reslock);
722 fh->resources &= ~bits;
723 btv->resources &= ~bits;
724 mutex_unlock(&btv->reslock);
725}
726
727/* ----------------------------------------------------------------------- */
728/* If Bt848a or Bt849, use PLL for PAL/SECAM and crystal for NTSC */
729
730/* Frequency = (F_input / PLL_X) * PLL_I.PLL_F/PLL_C
731 PLL_X = Reference pre-divider (0=1, 1=2)
732 PLL_C = Post divider (0=6, 1=4)
733 PLL_I = Integer input
734 PLL_F = Fractional input
735
736 F_input = 28.636363 MHz:
737 PAL (CLKx2 = 35.46895 MHz): PLL_X = 1, PLL_I = 0x0E, PLL_F = 0xDCF9, PLL_C = 0
738*/
739
740static void set_pll_freq(struct bttv *btv, unsigned int fin, unsigned int fout)
741{
742 unsigned char fl, fh, fi;
743
744 /* prevent overflows */
745 fin/=4;
746 fout/=4;
747
748 fout*=12;
749 fi=fout/fin;
750
751 fout=(fout%fin)*256;
752 fh=fout/fin;
753
754 fout=(fout%fin)*256;
755 fl=fout/fin;
756
757 btwrite(fl, BT848_PLL_F_LO);
758 btwrite(fh, BT848_PLL_F_HI);
759 btwrite(fi|BT848_PLL_X, BT848_PLL_XCI);
760}
761
762static void set_pll(struct bttv *btv)
763{
764 int i;
765
766 if (!btv->pll.pll_crystal)
767 return;
768
769 if (btv->pll.pll_ofreq == btv->pll.pll_current) {
770 dprintk("bttv%d: PLL: no change required\n",btv->c.nr);
771 return;
772 }
773
774 if (btv->pll.pll_ifreq == btv->pll.pll_ofreq) {
775 /* no PLL needed */
776 if (btv->pll.pll_current == 0)
777 return;
778 bttv_printk(KERN_INFO "bttv%d: PLL can sleep, using XTAL (%d).\n",
779 btv->c.nr,btv->pll.pll_ifreq);
780 btwrite(0x00,BT848_TGCTRL);
781 btwrite(0x00,BT848_PLL_XCI);
782 btv->pll.pll_current = 0;
783 return;
784 }
785
786 bttv_printk(KERN_INFO "bttv%d: PLL: %d => %d ",btv->c.nr,
787 btv->pll.pll_ifreq, btv->pll.pll_ofreq);
788 set_pll_freq(btv, btv->pll.pll_ifreq, btv->pll.pll_ofreq);
789
790 for (i=0; i<10; i++) {
791 /* Let other people run while the PLL stabilizes */
792 bttv_printk(".");
793 msleep(10);
794
795 if (btread(BT848_DSTATUS) & BT848_DSTATUS_PLOCK) {
796 btwrite(0,BT848_DSTATUS);
797 } else {
798 btwrite(0x08,BT848_TGCTRL);
799 btv->pll.pll_current = btv->pll.pll_ofreq;
800 bttv_printk(" ok\n");
801 return;
802 }
803 }
804 btv->pll.pll_current = -1;
805 bttv_printk("failed\n");
806 return;
807}
808
809/* used to switch between the bt848's analog/digital video capture modes */
810static void bt848A_set_timing(struct bttv *btv)
811{
812 int i, len;
813 int table_idx = bttv_tvnorms[btv->tvnorm].sram;
814 int fsc = bttv_tvnorms[btv->tvnorm].Fsc;
815
816 if (UNSET == bttv_tvcards[btv->c.type].muxsel[btv->input]) {
817 dprintk("bttv%d: load digital timing table (table_idx=%d)\n",
818 btv->c.nr,table_idx);
819
820 /* timing change...reset timing generator address */
821 btwrite(0x00, BT848_TGCTRL);
822 btwrite(0x02, BT848_TGCTRL);
823 btwrite(0x00, BT848_TGCTRL);
824
825 len=SRAM_Table[table_idx][0];
826 for(i = 1; i <= len; i++)
827 btwrite(SRAM_Table[table_idx][i],BT848_TGLB);
828 btv->pll.pll_ofreq = 27000000;
829
830 set_pll(btv);
831 btwrite(0x11, BT848_TGCTRL);
832 btwrite(0x41, BT848_DVSIF);
833 } else {
834 btv->pll.pll_ofreq = fsc;
835 set_pll(btv);
836 btwrite(0x0, BT848_DVSIF);
837 }
838}
839
840/* ----------------------------------------------------------------------- */
841
842static void bt848_bright(struct bttv *btv, int bright)
843{
844 int value;
845
846 // printk("bttv: set bright: %d\n",bright); // DEBUG
847 btv->bright = bright;
848
849 /* We want -128 to 127 we get 0-65535 */
850 value = (bright >> 8) - 128;
851 btwrite(value & 0xff, BT848_BRIGHT);
852}
853
854static void bt848_hue(struct bttv *btv, int hue)
855{
856 int value;
857
858 btv->hue = hue;
859
860 /* -128 to 127 */
861 value = (hue >> 8) - 128;
862 btwrite(value & 0xff, BT848_HUE);
863}
864
865static void bt848_contrast(struct bttv *btv, int cont)
866{
867 int value,hibit;
868
869 btv->contrast = cont;
870
871 /* 0-511 */
872 value = (cont >> 7);
873 hibit = (value >> 6) & 4;
874 btwrite(value & 0xff, BT848_CONTRAST_LO);
875 btaor(hibit, ~4, BT848_E_CONTROL);
876 btaor(hibit, ~4, BT848_O_CONTROL);
877}
878
879static void bt848_sat(struct bttv *btv, int color)
880{
881 int val_u,val_v,hibits;
882
883 btv->saturation = color;
884
885 /* 0-511 for the color */
886 val_u = ((color * btv->opt_uv_ratio) / 50) >> 7;
887 val_v = (((color * (100 - btv->opt_uv_ratio) / 50) >>7)*180L)/254;
888 hibits = (val_u >> 7) & 2;
889 hibits |= (val_v >> 8) & 1;
890 btwrite(val_u & 0xff, BT848_SAT_U_LO);
891 btwrite(val_v & 0xff, BT848_SAT_V_LO);
892 btaor(hibits, ~3, BT848_E_CONTROL);
893 btaor(hibits, ~3, BT848_O_CONTROL);
894}
895
896/* ----------------------------------------------------------------------- */
897
898static int
899video_mux(struct bttv *btv, unsigned int input)
900{
901 int mux,mask2;
902
903 if (input >= bttv_tvcards[btv->c.type].video_inputs)
904 return -EINVAL;
905
906 /* needed by RemoteVideo MX */
907 mask2 = bttv_tvcards[btv->c.type].gpiomask2;
908 if (mask2)
909 gpio_inout(mask2,mask2);
910
911 if (input == btv->svhs) {
912 btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
913 btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
914 } else {
915 btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
916 btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
917 }
918 mux = bttv_tvcards[btv->c.type].muxsel[input] & 3;
919 btaor(mux<<5, ~(3<<5), BT848_IFORM);
920 dprintk(KERN_DEBUG "bttv%d: video mux: input=%d mux=%d\n",
921 btv->c.nr,input,mux);
922
923 /* card specific hook */
924 if(bttv_tvcards[btv->c.type].muxsel_hook)
925 bttv_tvcards[btv->c.type].muxsel_hook (btv, input);
926 return 0;
927}
928
929static char *audio_modes[] = {
930 "audio: tuner", "audio: radio", "audio: extern",
931 "audio: intern", "audio: mute"
932};
933
934static int
935audio_mux(struct bttv *btv, int input, int mute)
936{
937 int gpio_val, signal;
938 struct v4l2_control ctrl;
939 struct i2c_client *c;
940
941 gpio_inout(bttv_tvcards[btv->c.type].gpiomask,
942 bttv_tvcards[btv->c.type].gpiomask);
943 signal = btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC;
944
945 btv->mute = mute;
946 btv->audio = input;
947
948 /* automute */
949 mute = mute || (btv->opt_automute && !signal && !btv->radio_user);
950
951 if (mute)
952 gpio_val = bttv_tvcards[btv->c.type].gpiomute;
953 else
954 gpio_val = bttv_tvcards[btv->c.type].gpiomux[input];
955
956 gpio_bits(bttv_tvcards[btv->c.type].gpiomask, gpio_val);
957 if (bttv_gpio)
958 bttv_gpio_tracking(btv, audio_modes[mute ? 4 : input]);
959 if (in_interrupt())
960 return 0;
961
962 ctrl.id = V4L2_CID_AUDIO_MUTE;
963 ctrl.value = btv->mute;
964 bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, &ctrl);
965 c = btv->i2c_msp34xx_client;
966 if (c) {
967 struct v4l2_routing route;
968
969 /* Note: the inputs tuner/radio/extern/intern are translated
970 to msp routings. This assumes common behavior for all msp3400
971 based TV cards. When this assumption fails, then the
972 specific MSP routing must be added to the card table.
973 For now this is sufficient. */
974 switch (input) {
975 case TVAUDIO_INPUT_RADIO:
976 route.input = MSP_INPUT(MSP_IN_SCART_2, MSP_IN_TUNER_1,
977 MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART);
978 break;
979 case TVAUDIO_INPUT_EXTERN:
980 route.input = MSP_INPUT(MSP_IN_SCART_1, MSP_IN_TUNER_1,
981 MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART);
982 break;
983 case TVAUDIO_INPUT_INTERN:
984 /* Yes, this is the same input as for RADIO. I doubt
985 if this is ever used. The only board with an INTERN
986 input is the BTTV_BOARD_AVERMEDIA98. I wonder how
987 that was tested. My guess is that the whole INTERN
988 input does not work. */
989 route.input = MSP_INPUT(MSP_IN_SCART_2, MSP_IN_TUNER_1,
990 MSP_DSP_OUT_SCART, MSP_DSP_OUT_SCART);
991 break;
992 case TVAUDIO_INPUT_TUNER:
993 default:
994 route.input = MSP_INPUT_DEFAULT;
995 break;
996 }
997 route.output = MSP_OUTPUT_DEFAULT;
998 c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
999 }
1000 c = btv->i2c_tvaudio_client;
1001 if (c) {
1002 struct v4l2_routing route;
1003
1004 route.input = input;
1005 route.output = 0;
1006 c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
1007 }
1008 return 0;
1009}
1010
1011static inline int
1012audio_mute(struct bttv *btv, int mute)
1013{
1014 return audio_mux(btv, btv->audio, mute);
1015}
1016
1017static inline int
1018audio_input(struct bttv *btv, int input)
1019{
1020 return audio_mux(btv, input, btv->mute);
1021}
1022
1023static void
1024i2c_vidiocschan(struct bttv *btv)
1025{
1026 struct video_channel c;
1027
1028 memset(&c,0,sizeof(c));
1029 c.norm = btv->tvnorm;
1030 c.channel = btv->input;
1031 bttv_call_i2c_clients(btv,VIDIOCSCHAN,&c);
1032 if (btv->c.type == BTTV_BOARD_VOODOOTV_FM)
1033 bttv_tda9880_setnorm(btv,c.norm);
1034}
1035
1036static int
1037set_tvnorm(struct bttv *btv, unsigned int norm)
1038{
1039 const struct bttv_tvnorm *tvnorm;
1040
1041 if (norm < 0 || norm >= BTTV_TVNORMS)
1042 return -EINVAL;
1043
1044 btv->tvnorm = norm;
1045 tvnorm = &bttv_tvnorms[norm];
1046
1047 btwrite(tvnorm->adelay, BT848_ADELAY);
1048 btwrite(tvnorm->bdelay, BT848_BDELAY);
1049 btaor(tvnorm->iform,~(BT848_IFORM_NORM|BT848_IFORM_XTBOTH),
1050 BT848_IFORM);
1051 btwrite(tvnorm->vbipack, BT848_VBI_PACK_SIZE);
1052 btwrite(1, BT848_VBI_PACK_DEL);
1053 bt848A_set_timing(btv);
1054
1055 switch (btv->c.type) {
1056 case BTTV_BOARD_VOODOOTV_FM:
1057 bttv_tda9880_setnorm(btv,norm);
1058 break;
1059 }
1060 return 0;
1061}
1062
1063static void
1064set_input(struct bttv *btv, unsigned int input)
1065{
1066 unsigned long flags;
1067
1068 btv->input = input;
1069 if (irq_iswitch) {
1070 spin_lock_irqsave(&btv->s_lock,flags);
1071 if (btv->curr.frame_irq) {
1072 /* active capture -> delayed input switch */
1073 btv->new_input = input;
1074 } else {
1075 video_mux(btv,input);
1076 }
1077 spin_unlock_irqrestore(&btv->s_lock,flags);
1078 } else {
1079 video_mux(btv,input);
1080 }
1081 audio_input(btv,(input == bttv_tvcards[btv->c.type].tuner ?
1082 TVAUDIO_INPUT_TUNER : TVAUDIO_INPUT_EXTERN));
1083 set_tvnorm(btv,btv->tvnorm);
1084 i2c_vidiocschan(btv);
1085}
1086
1087static void init_irqreg(struct bttv *btv)
1088{
1089 /* clear status */
1090 btwrite(0xfffffUL, BT848_INT_STAT);
1091
1092 if (bttv_tvcards[btv->c.type].no_video) {
1093 /* i2c only */
1094 btwrite(BT848_INT_I2CDONE,
1095 BT848_INT_MASK);
1096 } else {
1097 /* full video */
1098 btwrite((btv->triton1) |
1099 (btv->gpioirq ? BT848_INT_GPINT : 0) |
1100 BT848_INT_SCERR |
1101 (fdsr ? BT848_INT_FDSR : 0) |
1102 BT848_INT_RISCI|BT848_INT_OCERR|BT848_INT_VPRES|
1103 BT848_INT_FMTCHG|BT848_INT_HLOCK|
1104 BT848_INT_I2CDONE,
1105 BT848_INT_MASK);
1106 }
1107}
1108
1109static void init_bt848(struct bttv *btv)
1110{
1111 int val;
1112
1113 if (bttv_tvcards[btv->c.type].no_video) {
1114 /* very basic init only */
1115 init_irqreg(btv);
1116 return;
1117 }
1118
1119 btwrite(0x00, BT848_CAP_CTL);
1120 btwrite(BT848_COLOR_CTL_GAMMA, BT848_COLOR_CTL);
1121 btwrite(BT848_IFORM_XTAUTO | BT848_IFORM_AUTO, BT848_IFORM);
1122
1123 /* set planar and packed mode trigger points and */
1124 /* set rising edge of inverted GPINTR pin as irq trigger */
1125 btwrite(BT848_GPIO_DMA_CTL_PKTP_32|
1126 BT848_GPIO_DMA_CTL_PLTP1_16|
1127 BT848_GPIO_DMA_CTL_PLTP23_16|
1128 BT848_GPIO_DMA_CTL_GPINTC|
1129 BT848_GPIO_DMA_CTL_GPINTI,
1130 BT848_GPIO_DMA_CTL);
1131
1132 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
1133 btwrite(val, BT848_E_SCLOOP);
1134 btwrite(val, BT848_O_SCLOOP);
1135
1136 btwrite(0x20, BT848_E_VSCALE_HI);
1137 btwrite(0x20, BT848_O_VSCALE_HI);
1138 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
1139 BT848_ADC);
1140
1141 btwrite(whitecrush_upper, BT848_WC_UP);
1142 btwrite(whitecrush_lower, BT848_WC_DOWN);
1143
1144 if (btv->opt_lumafilter) {
1145 btwrite(0, BT848_E_CONTROL);
1146 btwrite(0, BT848_O_CONTROL);
1147 } else {
1148 btwrite(BT848_CONTROL_LDEC, BT848_E_CONTROL);
1149 btwrite(BT848_CONTROL_LDEC, BT848_O_CONTROL);
1150 }
1151
1152 bt848_bright(btv, btv->bright);
1153 bt848_hue(btv, btv->hue);
1154 bt848_contrast(btv, btv->contrast);
1155 bt848_sat(btv, btv->saturation);
1156
1157 /* interrupt */
1158 init_irqreg(btv);
1159}
1160
1161static void bttv_reinit_bt848(struct bttv *btv)
1162{
1163 unsigned long flags;
1164
1165 if (bttv_verbose)
1166 printk(KERN_INFO "bttv%d: reset, reinitialize\n",btv->c.nr);
1167 spin_lock_irqsave(&btv->s_lock,flags);
1168 btv->errors=0;
1169 bttv_set_dma(btv,0);
1170 spin_unlock_irqrestore(&btv->s_lock,flags);
1171
1172 init_bt848(btv);
1173 btv->pll.pll_current = -1;
1174 set_input(btv,btv->input);
1175}
1176
1177static int get_control(struct bttv *btv, struct v4l2_control *c)
1178{
1179 struct video_audio va;
1180 int i;
1181
1182 for (i = 0; i < BTTV_CTLS; i++)
1183 if (bttv_ctls[i].id == c->id)
1184 break;
1185 if (i == BTTV_CTLS)
1186 return -EINVAL;
1187 if (i >= 4 && i <= 8) {
1188 memset(&va,0,sizeof(va));
1189 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1190 if (btv->audio_hook)
1191 btv->audio_hook(btv,&va,0);
1192 }
1193 switch (c->id) {
1194 case V4L2_CID_BRIGHTNESS:
1195 c->value = btv->bright;
1196 break;
1197 case V4L2_CID_HUE:
1198 c->value = btv->hue;
1199 break;
1200 case V4L2_CID_CONTRAST:
1201 c->value = btv->contrast;
1202 break;
1203 case V4L2_CID_SATURATION:
1204 c->value = btv->saturation;
1205 break;
1206
1207 case V4L2_CID_AUDIO_MUTE:
1208 c->value = (VIDEO_AUDIO_MUTE & va.flags) ? 1 : 0;
1209 break;
1210 case V4L2_CID_AUDIO_VOLUME:
1211 c->value = va.volume;
1212 break;
1213 case V4L2_CID_AUDIO_BALANCE:
1214 c->value = va.balance;
1215 break;
1216 case V4L2_CID_AUDIO_BASS:
1217 c->value = va.bass;
1218 break;
1219 case V4L2_CID_AUDIO_TREBLE:
1220 c->value = va.treble;
1221 break;
1222
1223 case V4L2_CID_PRIVATE_CHROMA_AGC:
1224 c->value = btv->opt_chroma_agc;
1225 break;
1226 case V4L2_CID_PRIVATE_COMBFILTER:
1227 c->value = btv->opt_combfilter;
1228 break;
1229 case V4L2_CID_PRIVATE_LUMAFILTER:
1230 c->value = btv->opt_lumafilter;
1231 break;
1232 case V4L2_CID_PRIVATE_AUTOMUTE:
1233 c->value = btv->opt_automute;
1234 break;
1235 case V4L2_CID_PRIVATE_AGC_CRUSH:
1236 c->value = btv->opt_adc_crush;
1237 break;
1238 case V4L2_CID_PRIVATE_VCR_HACK:
1239 c->value = btv->opt_vcr_hack;
1240 break;
1241 case V4L2_CID_PRIVATE_WHITECRUSH_UPPER:
1242 c->value = btv->opt_whitecrush_upper;
1243 break;
1244 case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
1245 c->value = btv->opt_whitecrush_lower;
1246 break;
1247 case V4L2_CID_PRIVATE_UV_RATIO:
1248 c->value = btv->opt_uv_ratio;
1249 break;
1250 case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
1251 c->value = btv->opt_full_luma_range;
1252 break;
1253 case V4L2_CID_PRIVATE_CORING:
1254 c->value = btv->opt_coring;
1255 break;
1256 default:
1257 return -EINVAL;
1258 }
1259 return 0;
1260}
1261
1262static int set_control(struct bttv *btv, struct v4l2_control *c)
1263{
1264 struct video_audio va;
1265 int i,val;
1266
1267 for (i = 0; i < BTTV_CTLS; i++)
1268 if (bttv_ctls[i].id == c->id)
1269 break;
1270 if (i == BTTV_CTLS)
1271 return -EINVAL;
1272 if (i >= 4 && i <= 8) {
1273 memset(&va,0,sizeof(va));
1274 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1275 if (btv->audio_hook)
1276 btv->audio_hook(btv,&va,0);
1277 }
1278 switch (c->id) {
1279 case V4L2_CID_BRIGHTNESS:
1280 bt848_bright(btv,c->value);
1281 break;
1282 case V4L2_CID_HUE:
1283 bt848_hue(btv,c->value);
1284 break;
1285 case V4L2_CID_CONTRAST:
1286 bt848_contrast(btv,c->value);
1287 break;
1288 case V4L2_CID_SATURATION:
1289 bt848_sat(btv,c->value);
1290 break;
1291 case V4L2_CID_AUDIO_MUTE:
1292 if (c->value) {
1293 va.flags |= VIDEO_AUDIO_MUTE;
1294 audio_mute(btv, 1);
1295 } else {
1296 va.flags &= ~VIDEO_AUDIO_MUTE;
1297 audio_mute(btv, 0);
1298 }
1299 break;
1300
1301 case V4L2_CID_AUDIO_VOLUME:
1302 va.volume = c->value;
1303 break;
1304 case V4L2_CID_AUDIO_BALANCE:
1305 va.balance = c->value;
1306 break;
1307 case V4L2_CID_AUDIO_BASS:
1308 va.bass = c->value;
1309 break;
1310 case V4L2_CID_AUDIO_TREBLE:
1311 va.treble = c->value;
1312 break;
1313
1314 case V4L2_CID_PRIVATE_CHROMA_AGC:
1315 btv->opt_chroma_agc = c->value;
1316 val = btv->opt_chroma_agc ? BT848_SCLOOP_CAGC : 0;
1317 btwrite(val, BT848_E_SCLOOP);
1318 btwrite(val, BT848_O_SCLOOP);
1319 break;
1320 case V4L2_CID_PRIVATE_COMBFILTER:
1321 btv->opt_combfilter = c->value;
1322 break;
1323 case V4L2_CID_PRIVATE_LUMAFILTER:
1324 btv->opt_lumafilter = c->value;
1325 if (btv->opt_lumafilter) {
1326 btand(~BT848_CONTROL_LDEC, BT848_E_CONTROL);
1327 btand(~BT848_CONTROL_LDEC, BT848_O_CONTROL);
1328 } else {
1329 btor(BT848_CONTROL_LDEC, BT848_E_CONTROL);
1330 btor(BT848_CONTROL_LDEC, BT848_O_CONTROL);
1331 }
1332 break;
1333 case V4L2_CID_PRIVATE_AUTOMUTE:
1334 btv->opt_automute = c->value;
1335 break;
1336 case V4L2_CID_PRIVATE_AGC_CRUSH:
1337 btv->opt_adc_crush = c->value;
1338 btwrite(BT848_ADC_RESERVED | (btv->opt_adc_crush ? BT848_ADC_CRUSH : 0),
1339 BT848_ADC);
1340 break;
1341 case V4L2_CID_PRIVATE_VCR_HACK:
1342 btv->opt_vcr_hack = c->value;
1343 break;
1344 case V4L2_CID_PRIVATE_WHITECRUSH_UPPER:
1345 btv->opt_whitecrush_upper = c->value;
1346 btwrite(c->value, BT848_WC_UP);
1347 break;
1348 case V4L2_CID_PRIVATE_WHITECRUSH_LOWER:
1349 btv->opt_whitecrush_lower = c->value;
1350 btwrite(c->value, BT848_WC_DOWN);
1351 break;
1352 case V4L2_CID_PRIVATE_UV_RATIO:
1353 btv->opt_uv_ratio = c->value;
1354 bt848_sat(btv, btv->saturation);
1355 break;
1356 case V4L2_CID_PRIVATE_FULL_LUMA_RANGE:
1357 btv->opt_full_luma_range = c->value;
1358 btaor((c->value<<7), ~BT848_OFORM_RANGE, BT848_OFORM);
1359 break;
1360 case V4L2_CID_PRIVATE_CORING:
1361 btv->opt_coring = c->value;
1362 btaor((c->value<<5), ~BT848_OFORM_CORE32, BT848_OFORM);
1363 break;
1364 default:
1365 return -EINVAL;
1366 }
1367 if (i >= 4 && i <= 8) {
1368 bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va);
1369 if (btv->audio_hook)
1370 btv->audio_hook(btv,&va,1);
1371 }
1372 return 0;
1373}
1374
1375/* ----------------------------------------------------------------------- */
1376
1377void bttv_gpio_tracking(struct bttv *btv, char *comment)
1378{
1379 unsigned int outbits, data;
1380 outbits = btread(BT848_GPIO_OUT_EN);
1381 data = btread(BT848_GPIO_DATA);
1382 printk(KERN_DEBUG "bttv%d: gpio: en=%08x, out=%08x in=%08x [%s]\n",
1383 btv->c.nr,outbits,data & outbits, data & ~outbits, comment);
1384}
1385
1386static void bttv_field_count(struct bttv *btv)
1387{
1388 int need_count = 0;
1389
1390 if (btv->users)
1391 need_count++;
1392
1393 if (need_count) {
1394 /* start field counter */
1395 btor(BT848_INT_VSYNC,BT848_INT_MASK);
1396 } else {
1397 /* stop field counter */
1398 btand(~BT848_INT_VSYNC,BT848_INT_MASK);
1399 btv->field_count = 0;
1400 }
1401}
1402
1403static const struct bttv_format*
1404format_by_palette(int palette)
1405{
1406 unsigned int i;
1407
1408 for (i = 0; i < BTTV_FORMATS; i++) {
1409 if (-1 == bttv_formats[i].palette)
1410 continue;
1411 if (bttv_formats[i].palette == palette)
1412 return bttv_formats+i;
1413 }
1414 return NULL;
1415}
1416
1417static const struct bttv_format*
1418format_by_fourcc(int fourcc)
1419{
1420 unsigned int i;
1421
1422 for (i = 0; i < BTTV_FORMATS; i++) {
1423 if (-1 == bttv_formats[i].fourcc)
1424 continue;
1425 if (bttv_formats[i].fourcc == fourcc)
1426 return bttv_formats+i;
1427 }
1428 return NULL;
1429}
1430
1431/* ----------------------------------------------------------------------- */
1432/* misc helpers */
1433
1434static int
1435bttv_switch_overlay(struct bttv *btv, struct bttv_fh *fh,
1436 struct bttv_buffer *new)
1437{
1438 struct bttv_buffer *old;
1439 unsigned long flags;
1440 int retval = 0;
1441
1442 dprintk("switch_overlay: enter [new=%p]\n",new);
1443 if (new)
1444 new->vb.state = STATE_DONE;
1445 spin_lock_irqsave(&btv->s_lock,flags);
1446 old = btv->screen;
1447 btv->screen = new;
1448 btv->loop_irq |= 1;
1449 bttv_set_dma(btv, 0x03);
1450 spin_unlock_irqrestore(&btv->s_lock,flags);
1451 if (NULL == new)
1452 free_btres(btv,fh,RESOURCE_OVERLAY);
1453 if (NULL != old) {
1454 dprintk("switch_overlay: old=%p state is %d\n",old,old->vb.state);
1455 bttv_dma_free(&fh->cap,btv, old);
1456 kfree(old);
1457 }
1458 dprintk("switch_overlay: done\n");
1459 return retval;
1460}
1461
1462/* ----------------------------------------------------------------------- */
1463/* video4linux (1) interface */
1464
1465static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv,
1466 struct bttv_buffer *buf,
1467 const struct bttv_format *fmt,
1468 unsigned int width, unsigned int height,
1469 enum v4l2_field field)
1470{
1471 int redo_dma_risc = 0;
1472 int rc;
1473
1474 /* check settings */
1475 if (NULL == fmt)
1476 return -EINVAL;
1477 if (fmt->btformat == BT848_COLOR_FMT_RAW) {
1478 width = RAW_BPL;
1479 height = RAW_LINES*2;
1480 if (width*height > buf->vb.bsize)
1481 return -EINVAL;
1482 buf->vb.size = buf->vb.bsize;
1483 } else {
1484 if (width < 48 ||
1485 height < 32 ||
1486 width > bttv_tvnorms[btv->tvnorm].swidth ||
1487 height > bttv_tvnorms[btv->tvnorm].sheight)
1488 return -EINVAL;
1489 buf->vb.size = (width * height * fmt->depth) >> 3;
1490 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
1491 return -EINVAL;
1492 }
1493
1494 /* alloc + fill struct bttv_buffer (if changed) */
1495 if (buf->vb.width != width || buf->vb.height != height ||
1496 buf->vb.field != field ||
1497 buf->tvnorm != btv->tvnorm || buf->fmt != fmt) {
1498 buf->vb.width = width;
1499 buf->vb.height = height;
1500 buf->vb.field = field;
1501 buf->tvnorm = btv->tvnorm;
1502 buf->fmt = fmt;
1503 redo_dma_risc = 1;
1504 }
1505
1506 /* alloc risc memory */
1507 if (STATE_NEEDS_INIT == buf->vb.state) {
1508 redo_dma_risc = 1;
1509 if (0 != (rc = videobuf_iolock(q,&buf->vb,&btv->fbuf)))
1510 goto fail;
1511 }
1512
1513 if (redo_dma_risc)
1514 if (0 != (rc = bttv_buffer_risc(btv,buf)))
1515 goto fail;
1516
1517 buf->vb.state = STATE_PREPARED;
1518 return 0;
1519
1520 fail:
1521 bttv_dma_free(q,btv,buf);
1522 return rc;
1523}
1524
1525static int
1526buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
1527{
1528 struct bttv_fh *fh = q->priv_data;
1529
1530 *size = fh->fmt->depth*fh->width*fh->height >> 3;
1531 if (0 == *count)
1532 *count = gbuffers;
1533 while (*size * *count > gbuffers * gbufsize)
1534 (*count)--;
1535 return 0;
1536}
1537
1538static int
1539buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
1540 enum v4l2_field field)
1541{
1542 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
1543 struct bttv_fh *fh = q->priv_data;
1544
1545 return bttv_prepare_buffer(q,fh->btv, buf, fh->fmt,
1546 fh->width, fh->height, field);
1547}
1548
1549static void
1550buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
1551{
1552 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
1553 struct bttv_fh *fh = q->priv_data;
1554 struct bttv *btv = fh->btv;
1555
1556 buf->vb.state = STATE_QUEUED;
1557 list_add_tail(&buf->vb.queue,&btv->capture);
1558 if (!btv->curr.frame_irq) {
1559 btv->loop_irq |= 1;
1560 bttv_set_dma(btv, 0x03);
1561 }
1562}
1563
1564static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
1565{
1566 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
1567 struct bttv_fh *fh = q->priv_data;
1568
1569 bttv_dma_free(&fh->cap,fh->btv,buf);
1570}
1571
1572static struct videobuf_queue_ops bttv_video_qops = {
1573 .buf_setup = buffer_setup,
1574 .buf_prepare = buffer_prepare,
1575 .buf_queue = buffer_queue,
1576 .buf_release = buffer_release,
1577};
1578
1579static int bttv_common_ioctls(struct bttv *btv, unsigned int cmd, void *arg)
1580{
1581 switch (cmd) {
1582 case BTTV_VERSION:
1583 return BTTV_VERSION_CODE;
1584
1585 /* *** v4l1 *** ************************************************ */
1586 case VIDIOCGFREQ:
1587 {
1588 unsigned long *freq = arg;
1589 *freq = btv->freq;
1590 return 0;
1591 }
1592 case VIDIOCSFREQ:
1593 {
1594 unsigned long *freq = arg;
1595 mutex_lock(&btv->lock);
1596 btv->freq=*freq;
1597 bttv_call_i2c_clients(btv,VIDIOCSFREQ,freq);
1598 if (btv->has_matchbox && btv->radio_user)
1599 tea5757_set_freq(btv,*freq);
1600 mutex_unlock(&btv->lock);
1601 return 0;
1602 }
1603
1604 case VIDIOCGTUNER:
1605 {
1606 struct video_tuner *v = arg;
1607
1608 if (UNSET == bttv_tvcards[btv->c.type].tuner)
1609 return -EINVAL;
1610 if (v->tuner) /* Only tuner 0 */
1611 return -EINVAL;
1612 strcpy(v->name, "Television");
1613 v->rangelow = 0;
1614 v->rangehigh = 0x7FFFFFFF;
1615 v->flags = VIDEO_TUNER_PAL|VIDEO_TUNER_NTSC|VIDEO_TUNER_SECAM;
1616 v->mode = btv->tvnorm;
1617 v->signal = (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC) ? 0xFFFF : 0;
1618 bttv_call_i2c_clients(btv,cmd,v);
1619 return 0;
1620 }
1621 case VIDIOCSTUNER:
1622 {
1623 struct video_tuner *v = arg;
1624
1625 if (v->tuner) /* Only tuner 0 */
1626 return -EINVAL;
1627 if (v->mode >= BTTV_TVNORMS)
1628 return -EINVAL;
1629
1630 mutex_lock(&btv->lock);
1631 set_tvnorm(btv,v->mode);
1632 bttv_call_i2c_clients(btv,cmd,v);
1633 mutex_unlock(&btv->lock);
1634 return 0;
1635 }
1636
1637 case VIDIOCGCHAN:
1638 {
1639 struct video_channel *v = arg;
1640 unsigned int channel = v->channel;
1641
1642 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
1643 return -EINVAL;
1644 v->tuners=0;
1645 v->flags = VIDEO_VC_AUDIO;
1646 v->type = VIDEO_TYPE_CAMERA;
1647 v->norm = btv->tvnorm;
1648 if (channel == bttv_tvcards[btv->c.type].tuner) {
1649 strcpy(v->name,"Television");
1650 v->flags|=VIDEO_VC_TUNER;
1651 v->type=VIDEO_TYPE_TV;
1652 v->tuners=1;
1653 } else if (channel == btv->svhs) {
1654 strcpy(v->name,"S-Video");
1655 } else {
1656 sprintf(v->name,"Composite%d",channel);
1657 }
1658 return 0;
1659 }
1660 case VIDIOCSCHAN:
1661 {
1662 struct video_channel *v = arg;
1663 unsigned int channel = v->channel;
1664
1665 if (channel >= bttv_tvcards[btv->c.type].video_inputs)
1666 return -EINVAL;
1667 if (v->norm >= BTTV_TVNORMS)
1668 return -EINVAL;
1669
1670 mutex_lock(&btv->lock);
1671 if (channel == btv->input &&
1672 v->norm == btv->tvnorm) {
1673 /* nothing to do */
1674 mutex_unlock(&btv->lock);
1675 return 0;
1676 }
1677
1678 btv->tvnorm = v->norm;
1679 set_input(btv,v->channel);
1680 mutex_unlock(&btv->lock);
1681 return 0;
1682 }
1683
1684 case VIDIOCGAUDIO:
1685 {
1686 struct video_audio *v = arg;
1687
1688 memset(v,0,sizeof(*v));
1689 strcpy(v->name,"Television");
1690 v->flags |= VIDEO_AUDIO_MUTABLE;
1691 v->mode = VIDEO_SOUND_MONO;
1692
1693 mutex_lock(&btv->lock);
1694 bttv_call_i2c_clients(btv,cmd,v);
1695
1696 /* card specific hooks */
1697 if (btv->audio_hook)
1698 btv->audio_hook(btv,v,0);
1699
1700 mutex_unlock(&btv->lock);
1701 return 0;
1702 }
1703 case VIDIOCSAUDIO:
1704 {
1705 struct video_audio *v = arg;
1706 unsigned int audio = v->audio;
1707
1708 if (audio >= bttv_tvcards[btv->c.type].audio_inputs)
1709 return -EINVAL;
1710
1711 mutex_lock(&btv->lock);
1712 audio_mute(btv, (v->flags&VIDEO_AUDIO_MUTE) ? 1 : 0);
1713 bttv_call_i2c_clients(btv,cmd,v);
1714
1715 /* card specific hooks */
1716 if (btv->audio_hook)
1717 btv->audio_hook(btv,v,1);
1718
1719 mutex_unlock(&btv->lock);
1720 return 0;
1721 }
1722
1723 /* *** v4l2 *** ************************************************ */
1724 case VIDIOC_ENUMSTD:
1725 {
1726 struct v4l2_standard *e = arg;
1727 unsigned int index = e->index;
1728
1729 if (index >= BTTV_TVNORMS)
1730 return -EINVAL;
1731 v4l2_video_std_construct(e, bttv_tvnorms[e->index].v4l2_id,
1732 bttv_tvnorms[e->index].name);
1733 e->index = index;
1734 return 0;
1735 }
1736 case VIDIOC_G_STD:
1737 {
1738 v4l2_std_id *id = arg;
1739 *id = bttv_tvnorms[btv->tvnorm].v4l2_id;
1740 return 0;
1741 }
1742 case VIDIOC_S_STD:
1743 {
1744 v4l2_std_id *id = arg;
1745 unsigned int i;
1746
1747 for (i = 0; i < BTTV_TVNORMS; i++)
1748 if (*id & bttv_tvnorms[i].v4l2_id)
1749 break;
1750 if (i == BTTV_TVNORMS)
1751 return -EINVAL;
1752
1753 mutex_lock(&btv->lock);
1754 set_tvnorm(btv,i);
1755 i2c_vidiocschan(btv);
1756 mutex_unlock(&btv->lock);
1757 return 0;
1758 }
1759 case VIDIOC_QUERYSTD:
1760 {
1761 v4l2_std_id *id = arg;
1762
1763 if (btread(BT848_DSTATUS) & BT848_DSTATUS_NUML)
1764 *id = V4L2_STD_625_50;
1765 else
1766 *id = V4L2_STD_525_60;
1767 return 0;
1768 }
1769
1770 case VIDIOC_ENUMINPUT:
1771 {
1772 struct v4l2_input *i = arg;
1773 unsigned int n;
1774
1775 n = i->index;
1776 if (n >= bttv_tvcards[btv->c.type].video_inputs)
1777 return -EINVAL;
1778 memset(i,0,sizeof(*i));
1779 i->index = n;
1780 i->type = V4L2_INPUT_TYPE_CAMERA;
1781 i->audioset = 0;
1782 if (i->index == bttv_tvcards[btv->c.type].tuner) {
1783 sprintf(i->name, "Television");
1784 i->type = V4L2_INPUT_TYPE_TUNER;
1785 i->tuner = 0;
1786 } else if (i->index == btv->svhs) {
1787 sprintf(i->name, "S-Video");
1788 } else {
1789 sprintf(i->name,"Composite%d",i->index);
1790 }
1791 if (i->index == btv->input) {
1792 __u32 dstatus = btread(BT848_DSTATUS);
1793 if (0 == (dstatus & BT848_DSTATUS_PRES))
1794 i->status |= V4L2_IN_ST_NO_SIGNAL;
1795 if (0 == (dstatus & BT848_DSTATUS_HLOC))
1796 i->status |= V4L2_IN_ST_NO_H_LOCK;
1797 }
1798 for (n = 0; n < BTTV_TVNORMS; n++)
1799 i->std |= bttv_tvnorms[n].v4l2_id;
1800 return 0;
1801 }
1802 case VIDIOC_G_INPUT:
1803 {
1804 int *i = arg;
1805 *i = btv->input;
1806 return 0;
1807 }
1808 case VIDIOC_S_INPUT:
1809 {
1810 unsigned int *i = arg;
1811
1812 if (*i > bttv_tvcards[btv->c.type].video_inputs)
1813 return -EINVAL;
1814 mutex_lock(&btv->lock);
1815 set_input(btv,*i);
1816 mutex_unlock(&btv->lock);
1817 return 0;
1818 }
1819
1820 case VIDIOC_G_TUNER:
1821 {
1822 struct v4l2_tuner *t = arg;
1823
1824 if (UNSET == bttv_tvcards[btv->c.type].tuner)
1825 return -EINVAL;
1826 if (0 != t->index)
1827 return -EINVAL;
1828 mutex_lock(&btv->lock);
1829 memset(t,0,sizeof(*t));
1830 strcpy(t->name, "Television");
1831 t->type = V4L2_TUNER_ANALOG_TV;
1832 t->capability = V4L2_TUNER_CAP_NORM;
1833 t->rxsubchans = V4L2_TUNER_SUB_MONO;
1834 if (btread(BT848_DSTATUS)&BT848_DSTATUS_HLOC)
1835 t->signal = 0xffff;
1836 {
1837 struct video_tuner tuner;
1838
1839 memset(&tuner, 0, sizeof (tuner));
1840 tuner.rangehigh = 0xffffffffUL;
1841 bttv_call_i2c_clients(btv, VIDIOCGTUNER, &tuner);
1842 t->rangelow = tuner.rangelow;
1843 t->rangehigh = tuner.rangehigh;
1844 }
1845 {
1846 /* Hmmm ... */
1847 struct video_audio va;
1848 memset(&va, 0, sizeof(struct video_audio));
1849 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1850 if (btv->audio_hook)
1851 btv->audio_hook(btv,&va,0);
1852 if(va.mode & VIDEO_SOUND_STEREO) {
1853 t->audmode = V4L2_TUNER_MODE_STEREO;
1854 t->rxsubchans |= V4L2_TUNER_SUB_STEREO;
1855 }
1856 if(va.mode & VIDEO_SOUND_LANG1) {
1857 t->audmode = V4L2_TUNER_MODE_LANG1;
1858 t->rxsubchans = V4L2_TUNER_SUB_LANG1
1859 | V4L2_TUNER_SUB_LANG2;
1860 }
1861 }
1862 /* FIXME: fill capability+audmode */
1863 mutex_unlock(&btv->lock);
1864 return 0;
1865 }
1866 case VIDIOC_S_TUNER:
1867 {
1868 struct v4l2_tuner *t = arg;
1869
1870 if (UNSET == bttv_tvcards[btv->c.type].tuner)
1871 return -EINVAL;
1872 if (0 != t->index)
1873 return -EINVAL;
1874 mutex_lock(&btv->lock);
1875 {
1876 struct video_audio va;
1877 memset(&va, 0, sizeof(struct video_audio));
1878 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
1879 if (t->audmode == V4L2_TUNER_MODE_MONO)
1880 va.mode = VIDEO_SOUND_MONO;
1881 else if (t->audmode == V4L2_TUNER_MODE_STEREO ||
1882 t->audmode == V4L2_TUNER_MODE_LANG1_LANG2)
1883 va.mode = VIDEO_SOUND_STEREO;
1884 else if (t->audmode == V4L2_TUNER_MODE_LANG1)
1885 va.mode = VIDEO_SOUND_LANG1;
1886 else if (t->audmode == V4L2_TUNER_MODE_LANG2)
1887 va.mode = VIDEO_SOUND_LANG2;
1888 bttv_call_i2c_clients(btv, VIDIOCSAUDIO, &va);
1889 if (btv->audio_hook)
1890 btv->audio_hook(btv,&va,1);
1891 }
1892 mutex_unlock(&btv->lock);
1893 return 0;
1894 }
1895
1896 case VIDIOC_G_FREQUENCY:
1897 {
1898 struct v4l2_frequency *f = arg;
1899
1900 memset(f,0,sizeof(*f));
1901 f->type = V4L2_TUNER_ANALOG_TV;
1902 f->frequency = btv->freq;
1903 return 0;
1904 }
1905 case VIDIOC_S_FREQUENCY:
1906 {
1907 struct v4l2_frequency *f = arg;
1908
1909 if (unlikely(f->tuner != 0))
1910 return -EINVAL;
1911 if (unlikely (f->type != V4L2_TUNER_ANALOG_TV))
1912 return -EINVAL;
1913 mutex_lock(&btv->lock);
1914 btv->freq = f->frequency;
1915 bttv_call_i2c_clients(btv,VIDIOCSFREQ,&btv->freq);
1916 if (btv->has_matchbox && btv->radio_user)
1917 tea5757_set_freq(btv,btv->freq);
1918 mutex_unlock(&btv->lock);
1919 return 0;
1920 }
1921 case VIDIOC_LOG_STATUS:
1922 {
1923 bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, NULL);
1924 return 0;
1925 }
1926
1927 default:
1928 return -ENOIOCTLCMD;
1929
1930 }
1931 return 0;
1932}
1933
1934static int verify_window(const struct bttv_tvnorm *tvn,
1935 struct v4l2_window *win, int fixup)
1936{
1937 enum v4l2_field field;
1938 int maxw, maxh;
1939
1940 if (win->w.width < 48 || win->w.height < 32)
1941 return -EINVAL;
1942 if (win->clipcount > 2048)
1943 return -EINVAL;
1944
1945 field = win->field;
1946 maxw = tvn->swidth;
1947 maxh = tvn->sheight;
1948
1949 if (V4L2_FIELD_ANY == field) {
1950 field = (win->w.height > maxh/2)
1951 ? V4L2_FIELD_INTERLACED
1952 : V4L2_FIELD_TOP;
1953 }
1954 switch (field) {
1955 case V4L2_FIELD_TOP:
1956 case V4L2_FIELD_BOTTOM:
1957 maxh = maxh / 2;
1958 break;
1959 case V4L2_FIELD_INTERLACED:
1960 break;
1961 default:
1962 return -EINVAL;
1963 }
1964
1965 if (!fixup && (win->w.width > maxw || win->w.height > maxh))
1966 return -EINVAL;
1967
1968 if (win->w.width > maxw)
1969 win->w.width = maxw;
1970 if (win->w.height > maxh)
1971 win->w.height = maxh;
1972 win->field = field;
1973 return 0;
1974}
1975
1976static int setup_window(struct bttv_fh *fh, struct bttv *btv,
1977 struct v4l2_window *win, int fixup)
1978{
1979 struct v4l2_clip *clips = NULL;
1980 int n,size,retval = 0;
1981
1982 if (NULL == fh->ovfmt)
1983 return -EINVAL;
1984 if (!(fh->ovfmt->flags & FORMAT_FLAGS_PACKED))
1985 return -EINVAL;
1986 retval = verify_window(&bttv_tvnorms[btv->tvnorm],win,fixup);
1987 if (0 != retval)
1988 return retval;
1989
1990 /* copy clips -- luckily v4l1 + v4l2 are binary
1991 compatible here ...*/
1992 n = win->clipcount;
1993 size = sizeof(*clips)*(n+4);
1994 clips = kmalloc(size,GFP_KERNEL);
1995 if (NULL == clips)
1996 return -ENOMEM;
1997 if (n > 0) {
1998 if (copy_from_user(clips,win->clips,sizeof(struct v4l2_clip)*n)) {
1999 kfree(clips);
2000 return -EFAULT;
2001 }
2002 }
2003 /* clip against screen */
2004 if (NULL != btv->fbuf.base)
2005 n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height,
2006 &win->w, clips, n);
2007 btcx_sort_clips(clips,n);
2008
2009 /* 4-byte alignments */
2010 switch (fh->ovfmt->depth) {
2011 case 8:
2012 case 24:
2013 btcx_align(&win->w, clips, n, 3);
2014 break;
2015 case 16:
2016 btcx_align(&win->w, clips, n, 1);
2017 break;
2018 case 32:
2019 /* no alignment fixups needed */
2020 break;
2021 default:
2022 BUG();
2023 }
2024
2025 mutex_lock(&fh->cap.lock);
2026 kfree(fh->ov.clips);
2027 fh->ov.clips = clips;
2028 fh->ov.nclips = n;
2029
2030 fh->ov.w = win->w;
2031 fh->ov.field = win->field;
2032 fh->ov.setup_ok = 1;
2033 btv->init.ov.w.width = win->w.width;
2034 btv->init.ov.w.height = win->w.height;
2035 btv->init.ov.field = win->field;
2036
2037 /* update overlay if needed */
2038 retval = 0;
2039 if (check_btres(fh, RESOURCE_OVERLAY)) {
2040 struct bttv_buffer *new;
2041
2042 new = videobuf_alloc(sizeof(*new));
2043 bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
2044 retval = bttv_switch_overlay(btv,fh,new);
2045 }
2046 mutex_unlock(&fh->cap.lock);
2047 return retval;
2048}
2049
2050/* ----------------------------------------------------------------------- */
2051
2052static struct videobuf_queue* bttv_queue(struct bttv_fh *fh)
2053{
2054 struct videobuf_queue* q = NULL;
2055
2056 switch (fh->type) {
2057 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2058 q = &fh->cap;
2059 break;
2060 case V4L2_BUF_TYPE_VBI_CAPTURE:
2061 q = &fh->vbi;
2062 break;
2063 default:
2064 BUG();
2065 }
2066 return q;
2067}
2068
2069static int bttv_resource(struct bttv_fh *fh)
2070{
2071 int res = 0;
2072
2073 switch (fh->type) {
2074 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2075 res = RESOURCE_VIDEO;
2076 break;
2077 case V4L2_BUF_TYPE_VBI_CAPTURE:
2078 res = RESOURCE_VBI;
2079 break;
2080 default:
2081 BUG();
2082 }
2083 return res;
2084}
2085
2086static int bttv_switch_type(struct bttv_fh *fh, enum v4l2_buf_type type)
2087{
2088 struct videobuf_queue *q = bttv_queue(fh);
2089 int res = bttv_resource(fh);
2090
2091 if (check_btres(fh,res))
2092 return -EBUSY;
2093 if (videobuf_queue_is_busy(q))
2094 return -EBUSY;
2095 fh->type = type;
2096 return 0;
2097}
2098
2099static void
2100pix_format_set_size (struct v4l2_pix_format * f,
2101 const struct bttv_format * fmt,
2102 unsigned int width,
2103 unsigned int height)
2104{
2105 f->width = width;
2106 f->height = height;
2107
2108 if (fmt->flags & FORMAT_FLAGS_PLANAR) {
2109 f->bytesperline = width; /* Y plane */
2110 f->sizeimage = (width * height * fmt->depth) >> 3;
2111 } else {
2112 f->bytesperline = (width * fmt->depth) >> 3;
2113 f->sizeimage = height * f->bytesperline;
2114 }
2115}
2116
2117static int bttv_g_fmt(struct bttv_fh *fh, struct v4l2_format *f)
2118{
2119 switch (f->type) {
2120 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2121 memset(&f->fmt.pix,0,sizeof(struct v4l2_pix_format));
2122 pix_format_set_size (&f->fmt.pix, fh->fmt,
2123 fh->width, fh->height);
2124 f->fmt.pix.field = fh->cap.field;
2125 f->fmt.pix.pixelformat = fh->fmt->fourcc;
2126 return 0;
2127 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2128 memset(&f->fmt.win,0,sizeof(struct v4l2_window));
2129 f->fmt.win.w = fh->ov.w;
2130 f->fmt.win.field = fh->ov.field;
2131 return 0;
2132 case V4L2_BUF_TYPE_VBI_CAPTURE:
2133 bttv_vbi_get_fmt(fh,f);
2134 return 0;
2135 default:
2136 return -EINVAL;
2137 }
2138}
2139
2140static int bttv_try_fmt(struct bttv_fh *fh, struct bttv *btv,
2141 struct v4l2_format *f)
2142{
2143 switch (f->type) {
2144 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2145 {
2146 const struct bttv_format *fmt;
2147 enum v4l2_field field;
2148 unsigned int maxw,maxh;
2149
2150 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
2151 if (NULL == fmt)
2152 return -EINVAL;
2153
2154 /* fixup format */
2155 maxw = bttv_tvnorms[btv->tvnorm].swidth;
2156 maxh = bttv_tvnorms[btv->tvnorm].sheight;
2157 field = f->fmt.pix.field;
2158 if (V4L2_FIELD_ANY == field)
2159 field = (f->fmt.pix.height > maxh/2)
2160 ? V4L2_FIELD_INTERLACED
2161 : V4L2_FIELD_BOTTOM;
2162 if (V4L2_FIELD_SEQ_BT == field)
2163 field = V4L2_FIELD_SEQ_TB;
2164 switch (field) {
2165 case V4L2_FIELD_TOP:
2166 case V4L2_FIELD_BOTTOM:
2167 case V4L2_FIELD_ALTERNATE:
2168 maxh = maxh/2;
2169 break;
2170 case V4L2_FIELD_INTERLACED:
2171 break;
2172 case V4L2_FIELD_SEQ_TB:
2173 if (fmt->flags & FORMAT_FLAGS_PLANAR)
2174 return -EINVAL;
2175 break;
2176 default:
2177 return -EINVAL;
2178 }
2179
2180 /* update data for the application */
2181 f->fmt.pix.field = field;
2182 if (f->fmt.pix.width < 48)
2183 f->fmt.pix.width = 48;
2184 if (f->fmt.pix.height < 32)
2185 f->fmt.pix.height = 32;
2186 if (f->fmt.pix.width > maxw)
2187 f->fmt.pix.width = maxw;
2188 if (f->fmt.pix.height > maxh)
2189 f->fmt.pix.height = maxh;
2190 pix_format_set_size (&f->fmt.pix, fmt,
2191 f->fmt.pix.width & ~3,
2192 f->fmt.pix.height);
2193
2194 return 0;
2195 }
2196 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2197 return verify_window(&bttv_tvnorms[btv->tvnorm],
2198 &f->fmt.win, 1);
2199 case V4L2_BUF_TYPE_VBI_CAPTURE:
2200 bttv_vbi_try_fmt(fh,f);
2201 return 0;
2202 default:
2203 return -EINVAL;
2204 }
2205}
2206
2207static int bttv_s_fmt(struct bttv_fh *fh, struct bttv *btv,
2208 struct v4l2_format *f)
2209{
2210 int retval;
2211
2212 switch (f->type) {
2213 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2214 {
2215 const struct bttv_format *fmt;
2216
2217 retval = bttv_switch_type(fh,f->type);
2218 if (0 != retval)
2219 return retval;
2220 retval = bttv_try_fmt(fh,btv,f);
2221 if (0 != retval)
2222 return retval;
2223 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
2224
2225 /* update our state informations */
2226 mutex_lock(&fh->cap.lock);
2227 fh->fmt = fmt;
2228 fh->cap.field = f->fmt.pix.field;
2229 fh->cap.last = V4L2_FIELD_NONE;
2230 fh->width = f->fmt.pix.width;
2231 fh->height = f->fmt.pix.height;
2232 btv->init.fmt = fmt;
2233 btv->init.width = f->fmt.pix.width;
2234 btv->init.height = f->fmt.pix.height;
2235 mutex_unlock(&fh->cap.lock);
2236
2237 return 0;
2238 }
2239 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2240 if (no_overlay > 0) {
2241 printk ("V4L2_BUF_TYPE_VIDEO_OVERLAY: no_overlay\n");
2242 return -EINVAL;
2243 }
2244 return setup_window(fh, btv, &f->fmt.win, 1);
2245 case V4L2_BUF_TYPE_VBI_CAPTURE:
2246 retval = bttv_switch_type(fh,f->type);
2247 if (0 != retval)
2248 return retval;
2249 if (locked_btres(fh->btv, RESOURCE_VBI))
2250 return -EBUSY;
2251 bttv_vbi_try_fmt(fh,f);
2252 bttv_vbi_setlines(fh,btv,f->fmt.vbi.count[0]);
2253 bttv_vbi_get_fmt(fh,f);
2254 return 0;
2255 default:
2256 return -EINVAL;
2257 }
2258}
2259
2260static int bttv_do_ioctl(struct inode *inode, struct file *file,
2261 unsigned int cmd, void *arg)
2262{
2263 struct bttv_fh *fh = file->private_data;
2264 struct bttv *btv = fh->btv;
2265 unsigned long flags;
2266 int retval = 0;
2267
2268 if (bttv_debug > 1)
2269 v4l_print_ioctl(btv->c.name, cmd);
2270
2271 if (btv->errors)
2272 bttv_reinit_bt848(btv);
2273
2274 switch (cmd) {
2275 case VIDIOCSFREQ:
2276 case VIDIOCSTUNER:
2277 case VIDIOCSCHAN:
2278 case VIDIOC_S_CTRL:
2279 case VIDIOC_S_STD:
2280 case VIDIOC_S_INPUT:
2281 case VIDIOC_S_TUNER:
2282 case VIDIOC_S_FREQUENCY:
2283 retval = v4l2_prio_check(&btv->prio,&fh->prio);
2284 if (0 != retval)
2285 return retval;
2286 };
2287
2288 switch (cmd) {
2289
2290 /* *** v4l1 *** ************************************************ */
2291 case VIDIOCGCAP:
2292 {
2293 struct video_capability *cap = arg;
2294
2295 memset(cap,0,sizeof(*cap));
2296 strcpy(cap->name,btv->video_dev->name);
2297 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
2298 /* vbi */
2299 cap->type = VID_TYPE_TUNER|VID_TYPE_TELETEXT;
2300 } else {
2301 /* others */
2302 cap->type = VID_TYPE_CAPTURE|
2303 VID_TYPE_TUNER|
2304 VID_TYPE_CLIPPING|
2305 VID_TYPE_SCALES;
2306 if (no_overlay <= 0)
2307 cap->type |= VID_TYPE_OVERLAY;
2308
2309 cap->maxwidth = bttv_tvnorms[btv->tvnorm].swidth;
2310 cap->maxheight = bttv_tvnorms[btv->tvnorm].sheight;
2311 cap->minwidth = 48;
2312 cap->minheight = 32;
2313 }
2314 cap->channels = bttv_tvcards[btv->c.type].video_inputs;
2315 cap->audios = bttv_tvcards[btv->c.type].audio_inputs;
2316 return 0;
2317 }
2318
2319 case VIDIOCGPICT:
2320 {
2321 struct video_picture *pic = arg;
2322
2323 memset(pic,0,sizeof(*pic));
2324 pic->brightness = btv->bright;
2325 pic->contrast = btv->contrast;
2326 pic->hue = btv->hue;
2327 pic->colour = btv->saturation;
2328 if (fh->fmt) {
2329 pic->depth = fh->fmt->depth;
2330 pic->palette = fh->fmt->palette;
2331 }
2332 return 0;
2333 }
2334 case VIDIOCSPICT:
2335 {
2336 struct video_picture *pic = arg;
2337 const struct bttv_format *fmt;
2338
2339 fmt = format_by_palette(pic->palette);
2340 if (NULL == fmt)
2341 return -EINVAL;
2342 mutex_lock(&fh->cap.lock);
2343 if (fmt->depth != pic->depth) {
2344 retval = -EINVAL;
2345 goto fh_unlock_and_return;
2346 }
2347 if (fmt->flags & FORMAT_FLAGS_RAW) {
2348 /* VIDIOCMCAPTURE uses gbufsize, not RAW_BPL *
2349 RAW_LINES * 2. F1 is stored at offset 0, F2
2350 at buffer size / 2. */
2351 fh->width = RAW_BPL;
2352 fh->height = gbufsize / RAW_BPL;
2353 btv->init.width = RAW_BPL;
2354 btv->init.height = gbufsize / RAW_BPL;
2355 }
2356 fh->ovfmt = fmt;
2357 fh->fmt = fmt;
2358 btv->init.ovfmt = fmt;
2359 btv->init.fmt = fmt;
2360 if (bigendian) {
2361 /* dirty hack time: swap bytes for overlay if the
2362 display adaptor is big endian (insmod option) */
2363 if (fmt->palette == VIDEO_PALETTE_RGB555 ||
2364 fmt->palette == VIDEO_PALETTE_RGB565 ||
2365 fmt->palette == VIDEO_PALETTE_RGB32) {
2366 fh->ovfmt = fmt+1;
2367 }
2368 }
2369 bt848_bright(btv,pic->brightness);
2370 bt848_contrast(btv,pic->contrast);
2371 bt848_hue(btv,pic->hue);
2372 bt848_sat(btv,pic->colour);
2373 mutex_unlock(&fh->cap.lock);
2374 return 0;
2375 }
2376
2377 case VIDIOCGWIN:
2378 {
2379 struct video_window *win = arg;
2380
2381 memset(win,0,sizeof(*win));
2382 win->x = fh->ov.w.left;
2383 win->y = fh->ov.w.top;
2384 win->width = fh->ov.w.width;
2385 win->height = fh->ov.w.height;
2386 return 0;
2387 }
2388 case VIDIOCSWIN:
2389 {
2390 struct video_window *win = arg;
2391 struct v4l2_window w2;
2392
2393 if (no_overlay > 0) {
2394 printk ("VIDIOCSWIN: no_overlay\n");
2395 return -EINVAL;
2396 }
2397
2398 w2.field = V4L2_FIELD_ANY;
2399 w2.w.left = win->x;
2400 w2.w.top = win->y;
2401 w2.w.width = win->width;
2402 w2.w.height = win->height;
2403 w2.clipcount = win->clipcount;
2404 w2.clips = (struct v4l2_clip __user *)win->clips;
2405 retval = setup_window(fh, btv, &w2, 0);
2406 if (0 == retval) {
2407 /* on v4l1 this ioctl affects the read() size too */
2408 fh->width = fh->ov.w.width;
2409 fh->height = fh->ov.w.height;
2410 btv->init.width = fh->ov.w.width;
2411 btv->init.height = fh->ov.w.height;
2412 }
2413 return retval;
2414 }
2415
2416 case VIDIOCGFBUF:
2417 {
2418 struct video_buffer *fbuf = arg;
2419
2420 fbuf->base = btv->fbuf.base;
2421 fbuf->width = btv->fbuf.fmt.width;
2422 fbuf->height = btv->fbuf.fmt.height;
2423 fbuf->bytesperline = btv->fbuf.fmt.bytesperline;
2424 if (fh->ovfmt)
2425 fbuf->depth = fh->ovfmt->depth;
2426 return 0;
2427 }
2428 case VIDIOCSFBUF:
2429 {
2430 struct video_buffer *fbuf = arg;
2431 const struct bttv_format *fmt;
2432 unsigned long end;
2433
2434 if(!capable(CAP_SYS_ADMIN) &&
2435 !capable(CAP_SYS_RAWIO))
2436 return -EPERM;
2437 end = (unsigned long)fbuf->base +
2438 fbuf->height * fbuf->bytesperline;
2439 mutex_lock(&fh->cap.lock);
2440 retval = -EINVAL;
2441
2442 switch (fbuf->depth) {
2443 case 8:
2444 fmt = format_by_palette(VIDEO_PALETTE_HI240);
2445 break;
2446 case 16:
2447 fmt = format_by_palette(VIDEO_PALETTE_RGB565);
2448 break;
2449 case 24:
2450 fmt = format_by_palette(VIDEO_PALETTE_RGB24);
2451 break;
2452 case 32:
2453 fmt = format_by_palette(VIDEO_PALETTE_RGB32);
2454 break;
2455 case 15:
2456 fbuf->depth = 16;
2457 fmt = format_by_palette(VIDEO_PALETTE_RGB555);
2458 break;
2459 default:
2460 fmt = NULL;
2461 break;
2462 }
2463 if (NULL == fmt)
2464 goto fh_unlock_and_return;
2465
2466 fh->ovfmt = fmt;
2467 fh->fmt = fmt;
2468 btv->init.ovfmt = fmt;
2469 btv->init.fmt = fmt;
2470 btv->fbuf.base = fbuf->base;
2471 btv->fbuf.fmt.width = fbuf->width;
2472 btv->fbuf.fmt.height = fbuf->height;
2473 if (fbuf->bytesperline)
2474 btv->fbuf.fmt.bytesperline = fbuf->bytesperline;
2475 else
2476 btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fbuf->depth/8;
2477 mutex_unlock(&fh->cap.lock);
2478 return 0;
2479 }
2480
2481 case VIDIOCCAPTURE:
2482 case VIDIOC_OVERLAY:
2483 {
2484 struct bttv_buffer *new;
2485 int *on = arg;
2486
2487 if (*on) {
2488 /* verify args */
2489 if (NULL == btv->fbuf.base)
2490 return -EINVAL;
2491 if (!fh->ov.setup_ok) {
2492 dprintk("bttv%d: overlay: !setup_ok\n",btv->c.nr);
2493 return -EINVAL;
2494 }
2495 }
2496
2497 if (!check_alloc_btres(btv,fh,RESOURCE_OVERLAY))
2498 return -EBUSY;
2499
2500 mutex_lock(&fh->cap.lock);
2501 if (*on) {
2502 fh->ov.tvnorm = btv->tvnorm;
2503 new = videobuf_alloc(sizeof(*new));
2504 bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new);
2505 } else {
2506 new = NULL;
2507 }
2508
2509 /* switch over */
2510 retval = bttv_switch_overlay(btv,fh,new);
2511 mutex_unlock(&fh->cap.lock);
2512 return retval;
2513 }
2514
2515 case VIDIOCGMBUF:
2516 {
2517 struct video_mbuf *mbuf = arg;
2518 unsigned int i;
2519
2520 mutex_lock(&fh->cap.lock);
2521 retval = videobuf_mmap_setup(&fh->cap,gbuffers,gbufsize,
2522 V4L2_MEMORY_MMAP);
2523 if (retval < 0)
2524 goto fh_unlock_and_return;
2525 memset(mbuf,0,sizeof(*mbuf));
2526 mbuf->frames = gbuffers;
2527 mbuf->size = gbuffers * gbufsize;
2528 for (i = 0; i < gbuffers; i++)
2529 mbuf->offsets[i] = i * gbufsize;
2530 mutex_unlock(&fh->cap.lock);
2531 return 0;
2532 }
2533 case VIDIOCMCAPTURE:
2534 {
2535 struct video_mmap *vm = arg;
2536 struct bttv_buffer *buf;
2537 enum v4l2_field field;
2538
2539 if (vm->frame >= VIDEO_MAX_FRAME)
2540 return -EINVAL;
2541
2542 mutex_lock(&fh->cap.lock);
2543 retval = -EINVAL;
2544 buf = (struct bttv_buffer *)fh->cap.bufs[vm->frame];
2545 if (NULL == buf)
2546 goto fh_unlock_and_return;
2547 if (0 == buf->vb.baddr)
2548 goto fh_unlock_and_return;
2549 if (buf->vb.state == STATE_QUEUED ||
2550 buf->vb.state == STATE_ACTIVE)
2551 goto fh_unlock_and_return;
2552
2553 field = (vm->height > bttv_tvnorms[btv->tvnorm].sheight/2)
2554 ? V4L2_FIELD_INTERLACED
2555 : V4L2_FIELD_BOTTOM;
2556 retval = bttv_prepare_buffer(&fh->cap,btv,buf,
2557 format_by_palette(vm->format),
2558 vm->width,vm->height,field);
2559 if (0 != retval)
2560 goto fh_unlock_and_return;
2561 spin_lock_irqsave(&btv->s_lock,flags);
2562 buffer_queue(&fh->cap,&buf->vb);
2563 spin_unlock_irqrestore(&btv->s_lock,flags);
2564 mutex_unlock(&fh->cap.lock);
2565 return 0;
2566 }
2567 case VIDIOCSYNC:
2568 {
2569 int *frame = arg;
2570 struct bttv_buffer *buf;
2571
2572 if (*frame >= VIDEO_MAX_FRAME)
2573 return -EINVAL;
2574
2575 mutex_lock(&fh->cap.lock);
2576 retval = -EINVAL;
2577 buf = (struct bttv_buffer *)fh->cap.bufs[*frame];
2578 if (NULL == buf)
2579 goto fh_unlock_and_return;
2580 retval = videobuf_waiton(&buf->vb,0,1);
2581 if (0 != retval)
2582 goto fh_unlock_and_return;
2583 switch (buf->vb.state) {
2584 case STATE_ERROR:
2585 retval = -EIO;
2586 /* fall through */
2587 case STATE_DONE:
2588 videobuf_dma_sync(&fh->cap,&buf->vb.dma);
2589 bttv_dma_free(&fh->cap,btv,buf);
2590 break;
2591 default:
2592 retval = -EINVAL;
2593 break;
2594 }
2595 mutex_unlock(&fh->cap.lock);
2596 return retval;
2597 }
2598
2599 case VIDIOCGVBIFMT:
2600 {
2601 struct vbi_format *fmt = (void *) arg;
2602 struct v4l2_format fmt2;
2603
2604 if (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE) {
2605 retval = bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE);
2606 if (0 != retval)
2607 return retval;
2608 }
2609 bttv_vbi_get_fmt(fh, &fmt2);
2610
2611 memset(fmt,0,sizeof(*fmt));
2612 fmt->sampling_rate = fmt2.fmt.vbi.sampling_rate;
2613 fmt->samples_per_line = fmt2.fmt.vbi.samples_per_line;
2614 fmt->sample_format = VIDEO_PALETTE_RAW;
2615 fmt->start[0] = fmt2.fmt.vbi.start[0];
2616 fmt->count[0] = fmt2.fmt.vbi.count[0];
2617 fmt->start[1] = fmt2.fmt.vbi.start[1];
2618 fmt->count[1] = fmt2.fmt.vbi.count[1];
2619 if (fmt2.fmt.vbi.flags & V4L2_VBI_UNSYNC)
2620 fmt->flags |= VBI_UNSYNC;
2621 if (fmt2.fmt.vbi.flags & V4L2_VBI_INTERLACED)
2622 fmt->flags |= VBI_INTERLACED;
2623 return 0;
2624 }
2625 case VIDIOCSVBIFMT:
2626 {
2627 struct vbi_format *fmt = (void *) arg;
2628 struct v4l2_format fmt2;
2629
2630 retval = bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE);
2631 if (0 != retval)
2632 return retval;
2633 bttv_vbi_get_fmt(fh, &fmt2);
2634
2635 if (fmt->sampling_rate != fmt2.fmt.vbi.sampling_rate ||
2636 fmt->samples_per_line != fmt2.fmt.vbi.samples_per_line ||
2637 fmt->sample_format != VIDEO_PALETTE_RAW ||
2638 fmt->start[0] != fmt2.fmt.vbi.start[0] ||
2639 fmt->start[1] != fmt2.fmt.vbi.start[1] ||
2640 fmt->count[0] != fmt->count[1] ||
2641 fmt->count[0] < 1 ||
2642 fmt->count[0] > 32 /* VBI_MAXLINES */)
2643 return -EINVAL;
2644
2645 bttv_vbi_setlines(fh,btv,fmt->count[0]);
2646 return 0;
2647 }
2648
2649 case BTTV_VERSION:
2650 case VIDIOCGFREQ:
2651 case VIDIOCSFREQ:
2652 case VIDIOCGTUNER:
2653 case VIDIOCSTUNER:
2654 case VIDIOCGCHAN:
2655 case VIDIOCSCHAN:
2656 case VIDIOCGAUDIO:
2657 case VIDIOCSAUDIO:
2658 return bttv_common_ioctls(btv,cmd,arg);
2659
2660 /* *** v4l2 *** ************************************************ */
2661 case VIDIOC_QUERYCAP:
2662 {
2663 struct v4l2_capability *cap = arg;
2664
2665 if (0 == v4l2)
2666 return -EINVAL;
2667 memset(cap, 0, sizeof (*cap));
2668 strlcpy(cap->driver, "bttv", sizeof (cap->driver));
2669 strlcpy(cap->card, btv->video_dev->name, sizeof (cap->card));
2670 snprintf(cap->bus_info, sizeof (cap->bus_info),
2671 "PCI:%s", pci_name(btv->c.pci));
2672 cap->version = BTTV_VERSION_CODE;
2673 cap->capabilities =
2674 V4L2_CAP_VIDEO_CAPTURE |
2675 V4L2_CAP_VBI_CAPTURE |
2676 V4L2_CAP_READWRITE |
2677 V4L2_CAP_STREAMING;
2678 if (no_overlay <= 0)
2679 cap->capabilities |= V4L2_CAP_VIDEO_OVERLAY;
2680
2681 if (bttv_tvcards[btv->c.type].tuner != UNSET &&
2682 bttv_tvcards[btv->c.type].tuner != TUNER_ABSENT)
2683 cap->capabilities |= V4L2_CAP_TUNER;
2684 return 0;
2685 }
2686
2687 case VIDIOC_ENUM_FMT:
2688 {
2689 struct v4l2_fmtdesc *f = arg;
2690 enum v4l2_buf_type type;
2691 unsigned int i;
2692 int index;
2693
2694 type = f->type;
2695 if (V4L2_BUF_TYPE_VBI_CAPTURE == type) {
2696 /* vbi */
2697 index = f->index;
2698 if (0 != index)
2699 return -EINVAL;
2700 memset(f,0,sizeof(*f));
2701 f->index = index;
2702 f->type = type;
2703 f->pixelformat = V4L2_PIX_FMT_GREY;
2704 strcpy(f->description,"vbi data");
2705 return 0;
2706 }
2707
2708 /* video capture + overlay */
2709 index = -1;
2710 for (i = 0; i < BTTV_FORMATS; i++) {
2711 if (bttv_formats[i].fourcc != -1)
2712 index++;
2713 if ((unsigned int)index == f->index)
2714 break;
2715 }
2716 if (BTTV_FORMATS == i)
2717 return -EINVAL;
2718
2719 switch (f->type) {
2720 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2721 break;
2722 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
2723 if (!(bttv_formats[i].flags & FORMAT_FLAGS_PACKED))
2724 return -EINVAL;
2725 break;
2726 default:
2727 return -EINVAL;
2728 }
2729 memset(f,0,sizeof(*f));
2730 f->index = index;
2731 f->type = type;
2732 f->pixelformat = bttv_formats[i].fourcc;
2733 strlcpy(f->description,bttv_formats[i].name,sizeof(f->description));
2734 return 0;
2735 }
2736
2737 case VIDIOC_TRY_FMT:
2738 {
2739 struct v4l2_format *f = arg;
2740 return bttv_try_fmt(fh,btv,f);
2741 }
2742 case VIDIOC_G_FMT:
2743 {
2744 struct v4l2_format *f = arg;
2745 return bttv_g_fmt(fh,f);
2746 }
2747 case VIDIOC_S_FMT:
2748 {
2749 struct v4l2_format *f = arg;
2750 return bttv_s_fmt(fh,btv,f);
2751 }
2752
2753 case VIDIOC_G_FBUF:
2754 {
2755 struct v4l2_framebuffer *fb = arg;
2756
2757 *fb = btv->fbuf;
2758 fb->capability = V4L2_FBUF_CAP_LIST_CLIPPING;
2759 if (fh->ovfmt)
2760 fb->fmt.pixelformat = fh->ovfmt->fourcc;
2761 return 0;
2762 }
2763 case VIDIOC_S_FBUF:
2764 {
2765 struct v4l2_framebuffer *fb = arg;
2766 const struct bttv_format *fmt;
2767
2768 if(!capable(CAP_SYS_ADMIN) &&
2769 !capable(CAP_SYS_RAWIO))
2770 return -EPERM;
2771
2772 /* check args */
2773 fmt = format_by_fourcc(fb->fmt.pixelformat);
2774 if (NULL == fmt)
2775 return -EINVAL;
2776 if (0 == (fmt->flags & FORMAT_FLAGS_PACKED))
2777 return -EINVAL;
2778
2779 mutex_lock(&fh->cap.lock);
2780 retval = -EINVAL;
2781 if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
2782 if (fb->fmt.width > bttv_tvnorms[btv->tvnorm].swidth)
2783 goto fh_unlock_and_return;
2784 if (fb->fmt.height > bttv_tvnorms[btv->tvnorm].sheight)
2785 goto fh_unlock_and_return;
2786 }
2787
2788 /* ok, accept it */
2789 btv->fbuf.base = fb->base;
2790 btv->fbuf.fmt.width = fb->fmt.width;
2791 btv->fbuf.fmt.height = fb->fmt.height;
2792 if (0 != fb->fmt.bytesperline)
2793 btv->fbuf.fmt.bytesperline = fb->fmt.bytesperline;
2794 else
2795 btv->fbuf.fmt.bytesperline = btv->fbuf.fmt.width*fmt->depth/8;
2796
2797 retval = 0;
2798 fh->ovfmt = fmt;
2799 btv->init.ovfmt = fmt;
2800 if (fb->flags & V4L2_FBUF_FLAG_OVERLAY) {
2801 fh->ov.w.left = 0;
2802 fh->ov.w.top = 0;
2803 fh->ov.w.width = fb->fmt.width;
2804 fh->ov.w.height = fb->fmt.height;
2805 btv->init.ov.w.width = fb->fmt.width;
2806 btv->init.ov.w.height = fb->fmt.height;
2807 kfree(fh->ov.clips);
2808 fh->ov.clips = NULL;
2809 fh->ov.nclips = 0;
2810
2811 if (check_btres(fh, RESOURCE_OVERLAY)) {
2812 struct bttv_buffer *new;
2813
2814 new = videobuf_alloc(sizeof(*new));
2815 bttv_overlay_risc(btv,&fh->ov,fh->ovfmt,new);
2816 retval = bttv_switch_overlay(btv,fh,new);
2817 }
2818 }
2819 mutex_unlock(&fh->cap.lock);
2820 return retval;
2821 }
2822
2823 case VIDIOC_REQBUFS:
2824 return videobuf_reqbufs(bttv_queue(fh),arg);
2825
2826 case VIDIOC_QUERYBUF:
2827 return videobuf_querybuf(bttv_queue(fh),arg);
2828
2829 case VIDIOC_QBUF:
2830 return videobuf_qbuf(bttv_queue(fh),arg);
2831
2832 case VIDIOC_DQBUF:
2833 return videobuf_dqbuf(bttv_queue(fh),arg,
2834 file->f_flags & O_NONBLOCK);
2835
2836 case VIDIOC_STREAMON:
2837 {
2838 int res = bttv_resource(fh);
2839
2840 if (!check_alloc_btres(btv,fh,res))
2841 return -EBUSY;
2842 return videobuf_streamon(bttv_queue(fh));
2843 }
2844 case VIDIOC_STREAMOFF:
2845 {
2846 int res = bttv_resource(fh);
2847
2848 retval = videobuf_streamoff(bttv_queue(fh));
2849 if (retval < 0)
2850 return retval;
2851 free_btres(btv,fh,res);
2852 return 0;
2853 }
2854
2855 case VIDIOC_QUERYCTRL:
2856 {
2857 struct v4l2_queryctrl *c = arg;
2858 int i;
2859
2860 if ((c->id < V4L2_CID_BASE ||
2861 c->id >= V4L2_CID_LASTP1) &&
2862 (c->id < V4L2_CID_PRIVATE_BASE ||
2863 c->id >= V4L2_CID_PRIVATE_LASTP1))
2864 return -EINVAL;
2865 for (i = 0; i < BTTV_CTLS; i++)
2866 if (bttv_ctls[i].id == c->id)
2867 break;
2868 if (i == BTTV_CTLS) {
2869 *c = no_ctl;
2870 return 0;
2871 }
2872 *c = bttv_ctls[i];
2873 if (i >= 4 && i <= 8) {
2874 struct video_audio va;
2875 memset(&va,0,sizeof(va));
2876 bttv_call_i2c_clients(btv, VIDIOCGAUDIO, &va);
2877 if (btv->audio_hook)
2878 btv->audio_hook(btv,&va,0);
2879 switch (bttv_ctls[i].id) {
2880 case V4L2_CID_AUDIO_VOLUME:
2881 if (!(va.flags & VIDEO_AUDIO_VOLUME))
2882 *c = no_ctl;
2883 break;
2884 case V4L2_CID_AUDIO_BALANCE:
2885 if (!(va.flags & VIDEO_AUDIO_BALANCE))
2886 *c = no_ctl;
2887 break;
2888 case V4L2_CID_AUDIO_BASS:
2889 if (!(va.flags & VIDEO_AUDIO_BASS))
2890 *c = no_ctl;
2891 break;
2892 case V4L2_CID_AUDIO_TREBLE:
2893 if (!(va.flags & VIDEO_AUDIO_TREBLE))
2894 *c = no_ctl;
2895 break;
2896 }
2897 }
2898 return 0;
2899 }
2900 case VIDIOC_G_CTRL:
2901 return get_control(btv,arg);
2902 case VIDIOC_S_CTRL:
2903 return set_control(btv,arg);
2904 case VIDIOC_G_PARM:
2905 {
2906 struct v4l2_streamparm *parm = arg;
2907 struct v4l2_standard s;
2908 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
2909 return -EINVAL;
2910 memset(parm,0,sizeof(*parm));
2911 v4l2_video_std_construct(&s, bttv_tvnorms[btv->tvnorm].v4l2_id,
2912 bttv_tvnorms[btv->tvnorm].name);
2913 parm->parm.capture.timeperframe = s.frameperiod;
2914 return 0;
2915 }
2916
2917 case VIDIOC_G_PRIORITY:
2918 {
2919 enum v4l2_priority *p = arg;
2920
2921 *p = v4l2_prio_max(&btv->prio);
2922 return 0;
2923 }
2924 case VIDIOC_S_PRIORITY:
2925 {
2926 enum v4l2_priority *prio = arg;
2927
2928 return v4l2_prio_change(&btv->prio, &fh->prio, *prio);
2929 }
2930
2931 case VIDIOC_ENUMSTD:
2932 case VIDIOC_G_STD:
2933 case VIDIOC_S_STD:
2934 case VIDIOC_ENUMINPUT:
2935 case VIDIOC_G_INPUT:
2936 case VIDIOC_S_INPUT:
2937 case VIDIOC_G_TUNER:
2938 case VIDIOC_S_TUNER:
2939 case VIDIOC_G_FREQUENCY:
2940 case VIDIOC_S_FREQUENCY:
2941 case VIDIOC_LOG_STATUS:
2942 return bttv_common_ioctls(btv,cmd,arg);
2943
2944 default:
2945 return -ENOIOCTLCMD;
2946 }
2947 return 0;
2948
2949 fh_unlock_and_return:
2950 mutex_unlock(&fh->cap.lock);
2951 return retval;
2952}
2953
2954static int bttv_ioctl(struct inode *inode, struct file *file,
2955 unsigned int cmd, unsigned long arg)
2956{
2957 struct bttv_fh *fh = file->private_data;
2958
2959 switch (cmd) {
2960 case BTTV_VBISIZE:
2961 bttv_switch_type(fh,V4L2_BUF_TYPE_VBI_CAPTURE);
2962 return fh->lines * 2 * 2048;
2963 default:
2964 return video_usercopy(inode, file, cmd, arg, bttv_do_ioctl);
2965 }
2966}
2967
2968static ssize_t bttv_read(struct file *file, char __user *data,
2969 size_t count, loff_t *ppos)
2970{
2971 struct bttv_fh *fh = file->private_data;
2972 int retval = 0;
2973
2974 if (fh->btv->errors)
2975 bttv_reinit_bt848(fh->btv);
2976 dprintk("bttv%d: read count=%d type=%s\n",
2977 fh->btv->c.nr,(int)count,v4l2_type_names[fh->type]);
2978
2979 switch (fh->type) {
2980 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
2981 if (locked_btres(fh->btv,RESOURCE_VIDEO))
2982 return -EBUSY;
2983 retval = videobuf_read_one(&fh->cap, data, count, ppos,
2984 file->f_flags & O_NONBLOCK);
2985 break;
2986 case V4L2_BUF_TYPE_VBI_CAPTURE:
2987 if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI))
2988 return -EBUSY;
2989 retval = videobuf_read_stream(&fh->vbi, data, count, ppos, 1,
2990 file->f_flags & O_NONBLOCK);
2991 break;
2992 default:
2993 BUG();
2994 }
2995 return retval;
2996}
2997
2998static unsigned int bttv_poll(struct file *file, poll_table *wait)
2999{
3000 struct bttv_fh *fh = file->private_data;
3001 struct bttv_buffer *buf;
3002 enum v4l2_field field;
3003
3004 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) {
3005 if (!check_alloc_btres(fh->btv,fh,RESOURCE_VBI))
3006 return POLLERR;
3007 return videobuf_poll_stream(file, &fh->vbi, wait);
3008 }
3009
3010 if (check_btres(fh,RESOURCE_VIDEO)) {
3011 /* streaming capture */
3012 if (list_empty(&fh->cap.stream))
3013 return POLLERR;
3014 buf = list_entry(fh->cap.stream.next,struct bttv_buffer,vb.stream);
3015 } else {
3016 /* read() capture */
3017 mutex_lock(&fh->cap.lock);
3018 if (NULL == fh->cap.read_buf) {
3019 /* need to capture a new frame */
3020 if (locked_btres(fh->btv,RESOURCE_VIDEO)) {
3021 mutex_unlock(&fh->cap.lock);
3022 return POLLERR;
3023 }
3024 fh->cap.read_buf = videobuf_alloc(fh->cap.msize);
3025 if (NULL == fh->cap.read_buf) {
3026 mutex_unlock(&fh->cap.lock);
3027 return POLLERR;
3028 }
3029 fh->cap.read_buf->memory = V4L2_MEMORY_USERPTR;
3030 field = videobuf_next_field(&fh->cap);
3031 if (0 != fh->cap.ops->buf_prepare(&fh->cap,fh->cap.read_buf,field)) {
3032 kfree (fh->cap.read_buf);
3033 fh->cap.read_buf = NULL;
3034 mutex_unlock(&fh->cap.lock);
3035 return POLLERR;
3036 }
3037 fh->cap.ops->buf_queue(&fh->cap,fh->cap.read_buf);
3038 fh->cap.read_off = 0;
3039 }
3040 mutex_unlock(&fh->cap.lock);
3041 buf = (struct bttv_buffer*)fh->cap.read_buf;
3042 }
3043
3044 poll_wait(file, &buf->vb.done, wait);
3045 if (buf->vb.state == STATE_DONE ||
3046 buf->vb.state == STATE_ERROR)
3047 return POLLIN|POLLRDNORM;
3048 return 0;
3049}
3050
3051static int bttv_open(struct inode *inode, struct file *file)
3052{
3053 int minor = iminor(inode);
3054 struct bttv *btv = NULL;
3055 struct bttv_fh *fh;
3056 enum v4l2_buf_type type = 0;
3057 unsigned int i;
3058
3059 dprintk(KERN_DEBUG "bttv: open minor=%d\n",minor);
3060
3061 for (i = 0; i < bttv_num; i++) {
3062 if (bttvs[i].video_dev &&
3063 bttvs[i].video_dev->minor == minor) {
3064 btv = &bttvs[i];
3065 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
3066 break;
3067 }
3068 if (bttvs[i].vbi_dev &&
3069 bttvs[i].vbi_dev->minor == minor) {
3070 btv = &bttvs[i];
3071 type = V4L2_BUF_TYPE_VBI_CAPTURE;
3072 break;
3073 }
3074 }
3075 if (NULL == btv)
3076 return -ENODEV;
3077
3078 dprintk(KERN_DEBUG "bttv%d: open called (type=%s)\n",
3079 btv->c.nr,v4l2_type_names[type]);
3080
3081 /* allocate per filehandle data */
3082 fh = kmalloc(sizeof(*fh),GFP_KERNEL);
3083 if (NULL == fh)
3084 return -ENOMEM;
3085 file->private_data = fh;
3086 *fh = btv->init;
3087 fh->type = type;
3088 fh->ov.setup_ok = 0;
3089 v4l2_prio_open(&btv->prio,&fh->prio);
3090
3091 videobuf_queue_init(&fh->cap, &bttv_video_qops,
3092 btv->c.pci, &btv->s_lock,
3093 V4L2_BUF_TYPE_VIDEO_CAPTURE,
3094 V4L2_FIELD_INTERLACED,
3095 sizeof(struct bttv_buffer),
3096 fh);
3097 videobuf_queue_init(&fh->vbi, &bttv_vbi_qops,
3098 btv->c.pci, &btv->s_lock,
3099 V4L2_BUF_TYPE_VBI_CAPTURE,
3100 V4L2_FIELD_SEQ_TB,
3101 sizeof(struct bttv_buffer),
3102 fh);
3103 i2c_vidiocschan(btv);
3104
3105 btv->users++;
3106 if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
3107 bttv_vbi_setlines(fh,btv,16);
3108 bttv_field_count(btv);
3109 return 0;
3110}
3111
3112static int bttv_release(struct inode *inode, struct file *file)
3113{
3114 struct bttv_fh *fh = file->private_data;
3115 struct bttv *btv = fh->btv;
3116
3117 /* turn off overlay */
3118 if (check_btres(fh, RESOURCE_OVERLAY))
3119 bttv_switch_overlay(btv,fh,NULL);
3120
3121 /* stop video capture */
3122 if (check_btres(fh, RESOURCE_VIDEO)) {
3123 videobuf_streamoff(&fh->cap);
3124 free_btres(btv,fh,RESOURCE_VIDEO);
3125 }
3126 if (fh->cap.read_buf) {
3127 buffer_release(&fh->cap,fh->cap.read_buf);
3128 kfree(fh->cap.read_buf);
3129 }
3130
3131 /* stop vbi capture */
3132 if (check_btres(fh, RESOURCE_VBI)) {
3133 if (fh->vbi.streaming)
3134 videobuf_streamoff(&fh->vbi);
3135 if (fh->vbi.reading)
3136 videobuf_read_stop(&fh->vbi);
3137 free_btres(btv,fh,RESOURCE_VBI);
3138 }
3139
3140 /* free stuff */
3141 videobuf_mmap_free(&fh->cap);
3142 videobuf_mmap_free(&fh->vbi);
3143 v4l2_prio_close(&btv->prio,&fh->prio);
3144 file->private_data = NULL;
3145 kfree(fh);
3146
3147 btv->users--;
3148 bttv_field_count(btv);
3149 return 0;
3150}
3151
3152static int
3153bttv_mmap(struct file *file, struct vm_area_struct *vma)
3154{
3155 struct bttv_fh *fh = file->private_data;
3156
3157 dprintk("bttv%d: mmap type=%s 0x%lx+%ld\n",
3158 fh->btv->c.nr, v4l2_type_names[fh->type],
3159 vma->vm_start, vma->vm_end - vma->vm_start);
3160 return videobuf_mmap_mapper(bttv_queue(fh),vma);
3161}
3162
3163static struct file_operations bttv_fops =
3164{
3165 .owner = THIS_MODULE,
3166 .open = bttv_open,
3167 .release = bttv_release,
3168 .ioctl = bttv_ioctl,
3169 .compat_ioctl = v4l_compat_ioctl32,
3170 .llseek = no_llseek,
3171 .read = bttv_read,
3172 .mmap = bttv_mmap,
3173 .poll = bttv_poll,
3174};
3175
3176static struct video_device bttv_video_template =
3177{
3178 .name = "UNSET",
3179 .type = VID_TYPE_CAPTURE|VID_TYPE_TUNER|
3180 VID_TYPE_CLIPPING|VID_TYPE_SCALES,
3181 .hardware = VID_HARDWARE_BT848,
3182 .fops = &bttv_fops,
3183 .minor = -1,
3184};
3185
3186static struct video_device bttv_vbi_template =
3187{
3188 .name = "bt848/878 vbi",
3189 .type = VID_TYPE_TUNER|VID_TYPE_TELETEXT,
3190 .hardware = VID_HARDWARE_BT848,
3191 .fops = &bttv_fops,
3192 .minor = -1,
3193};
3194
3195/* ----------------------------------------------------------------------- */
3196/* radio interface */
3197
3198static int radio_open(struct inode *inode, struct file *file)
3199{
3200 int minor = iminor(inode);
3201 struct bttv *btv = NULL;
3202 unsigned int i;
3203
3204 dprintk("bttv: open minor=%d\n",minor);
3205
3206 for (i = 0; i < bttv_num; i++) {
3207 if (bttvs[i].radio_dev->minor == minor) {
3208 btv = &bttvs[i];
3209 break;
3210 }
3211 }
3212 if (NULL == btv)
3213 return -ENODEV;
3214
3215 dprintk("bttv%d: open called (radio)\n",btv->c.nr);
3216 mutex_lock(&btv->lock);
3217
3218 btv->radio_user++;
3219
3220 file->private_data = btv;
3221
3222 bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL);
3223 audio_input(btv,TVAUDIO_INPUT_RADIO);
3224
3225 mutex_unlock(&btv->lock);
3226 return 0;
3227}
3228
3229static int radio_release(struct inode *inode, struct file *file)
3230{
3231 struct bttv *btv = file->private_data;
3232 struct rds_command cmd;
3233
3234 btv->radio_user--;
3235
3236 bttv_call_i2c_clients(btv, RDS_CMD_CLOSE, &cmd);
3237
3238 return 0;
3239}
3240
3241static int radio_do_ioctl(struct inode *inode, struct file *file,
3242 unsigned int cmd, void *arg)
3243{
3244 struct bttv *btv = file->private_data;
3245
3246 switch (cmd) {
3247 case VIDIOCGCAP:
3248 {
3249 struct video_capability *cap = arg;
3250
3251 memset(cap,0,sizeof(*cap));
3252 strcpy(cap->name,btv->radio_dev->name);
3253 cap->type = VID_TYPE_TUNER;
3254 cap->channels = 1;
3255 cap->audios = 1;
3256 return 0;
3257 }
3258
3259 case VIDIOCGTUNER:
3260 {
3261 struct video_tuner *v = arg;
3262
3263 if(v->tuner)
3264 return -EINVAL;
3265 memset(v,0,sizeof(*v));
3266 strcpy(v->name, "Radio");
3267 bttv_call_i2c_clients(btv,cmd,v);
3268 return 0;
3269 }
3270 case VIDIOCSTUNER:
3271 /* nothing to do */
3272 return 0;
3273
3274 case BTTV_VERSION:
3275 case VIDIOCGFREQ:
3276 case VIDIOCSFREQ:
3277 case VIDIOCGAUDIO:
3278 case VIDIOCSAUDIO:
3279 case VIDIOC_LOG_STATUS:
3280 return bttv_common_ioctls(btv,cmd,arg);
3281
3282 default:
3283 return -ENOIOCTLCMD;
3284 }
3285 return 0;
3286}
3287
3288static int radio_ioctl(struct inode *inode, struct file *file,
3289 unsigned int cmd, unsigned long arg)
3290{
3291 return video_usercopy(inode, file, cmd, arg, radio_do_ioctl);
3292}
3293
3294static ssize_t radio_read(struct file *file, char __user *data,
3295 size_t count, loff_t *ppos)
3296{
3297 struct bttv *btv = file->private_data;
3298 struct rds_command cmd;
3299 cmd.block_count = count/3;
3300 cmd.buffer = data;
3301 cmd.instance = file;
3302 cmd.result = -ENODEV;
3303
3304 bttv_call_i2c_clients(btv, RDS_CMD_READ, &cmd);
3305
3306 return cmd.result;
3307}
3308
3309static unsigned int radio_poll(struct file *file, poll_table *wait)
3310{
3311 struct bttv *btv = file->private_data;
3312 struct rds_command cmd;
3313 cmd.instance = file;
3314 cmd.event_list = wait;
3315 cmd.result = -ENODEV;
3316 bttv_call_i2c_clients(btv, RDS_CMD_POLL, &cmd);
3317
3318 return cmd.result;
3319}
3320
3321static struct file_operations radio_fops =
3322{
3323 .owner = THIS_MODULE,
3324 .open = radio_open,
3325 .read = radio_read,
3326 .release = radio_release,
3327 .ioctl = radio_ioctl,
3328 .llseek = no_llseek,
3329 .poll = radio_poll,
3330};
3331
3332static struct video_device radio_template =
3333{
3334 .name = "bt848/878 radio",
3335 .type = VID_TYPE_TUNER,
3336 .hardware = VID_HARDWARE_BT848,
3337 .fops = &radio_fops,
3338 .minor = -1,
3339};
3340
3341/* ----------------------------------------------------------------------- */
3342/* some debug code */
3343
3344static int bttv_risc_decode(u32 risc)
3345{
3346 static char *instr[16] = {
3347 [ BT848_RISC_WRITE >> 28 ] = "write",
3348 [ BT848_RISC_SKIP >> 28 ] = "skip",
3349 [ BT848_RISC_WRITEC >> 28 ] = "writec",
3350 [ BT848_RISC_JUMP >> 28 ] = "jump",
3351 [ BT848_RISC_SYNC >> 28 ] = "sync",
3352 [ BT848_RISC_WRITE123 >> 28 ] = "write123",
3353 [ BT848_RISC_SKIP123 >> 28 ] = "skip123",
3354 [ BT848_RISC_WRITE1S23 >> 28 ] = "write1s23",
3355 };
3356 static int incr[16] = {
3357 [ BT848_RISC_WRITE >> 28 ] = 2,
3358 [ BT848_RISC_JUMP >> 28 ] = 2,
3359 [ BT848_RISC_SYNC >> 28 ] = 2,
3360 [ BT848_RISC_WRITE123 >> 28 ] = 5,
3361 [ BT848_RISC_SKIP123 >> 28 ] = 2,
3362 [ BT848_RISC_WRITE1S23 >> 28 ] = 3,
3363 };
3364 static char *bits[] = {
3365 "be0", "be1", "be2", "be3/resync",
3366 "set0", "set1", "set2", "set3",
3367 "clr0", "clr1", "clr2", "clr3",
3368 "irq", "res", "eol", "sol",
3369 };
3370 int i;
3371
3372 printk("0x%08x [ %s", risc,
3373 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
3374 for (i = ARRAY_SIZE(bits)-1; i >= 0; i--)
3375 if (risc & (1 << (i + 12)))
3376 printk(" %s",bits[i]);
3377 printk(" count=%d ]\n", risc & 0xfff);
3378 return incr[risc >> 28] ? incr[risc >> 28] : 1;
3379}
3380
3381static void bttv_risc_disasm(struct bttv *btv,
3382 struct btcx_riscmem *risc)
3383{
3384 unsigned int i,j,n;
3385
3386 printk("%s: risc disasm: %p [dma=0x%08lx]\n",
3387 btv->c.name, risc->cpu, (unsigned long)risc->dma);
3388 for (i = 0; i < (risc->size >> 2); i += n) {
3389 printk("%s: 0x%lx: ", btv->c.name,
3390 (unsigned long)(risc->dma + (i<<2)));
3391 n = bttv_risc_decode(risc->cpu[i]);
3392 for (j = 1; j < n; j++)
3393 printk("%s: 0x%lx: 0x%08x [ arg #%d ]\n",
3394 btv->c.name, (unsigned long)(risc->dma + ((i+j)<<2)),
3395 risc->cpu[i+j], j);
3396 if (0 == risc->cpu[i])
3397 break;
3398 }
3399}
3400
3401static void bttv_print_riscaddr(struct bttv *btv)
3402{
3403 printk(" main: %08Lx\n",
3404 (unsigned long long)btv->main.dma);
3405 printk(" vbi : o=%08Lx e=%08Lx\n",
3406 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
3407 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0);
3408 printk(" cap : o=%08Lx e=%08Lx\n",
3409 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
3410 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
3411 printk(" scr : o=%08Lx e=%08Lx\n",
3412 btv->screen ? (unsigned long long)btv->screen->top.dma : 0,
3413 btv->screen ? (unsigned long long)btv->screen->bottom.dma : 0);
3414 bttv_risc_disasm(btv, &btv->main);
3415}
3416
3417/* ----------------------------------------------------------------------- */
3418/* irq handler */
3419
3420static char *irq_name[] = {
3421 "FMTCHG", // format change detected (525 vs. 625)
3422 "VSYNC", // vertical sync (new field)
3423 "HSYNC", // horizontal sync
3424 "OFLOW", // chroma/luma AGC overflow
3425 "HLOCK", // horizontal lock changed
3426 "VPRES", // video presence changed
3427 "6", "7",
3428 "I2CDONE", // hw irc operation finished
3429 "GPINT", // gpio port triggered irq
3430 "10",
3431 "RISCI", // risc instruction triggered irq
3432 "FBUS", // pixel data fifo dropped data (high pci bus latencies)
3433 "FTRGT", // pixel data fifo overrun
3434 "FDSR", // fifo data stream resyncronisation
3435 "PPERR", // parity error (data transfer)
3436 "RIPERR", // parity error (read risc instructions)
3437 "PABORT", // pci abort
3438 "OCERR", // risc instruction error
3439 "SCERR", // syncronisation error
3440};
3441
3442static void bttv_print_irqbits(u32 print, u32 mark)
3443{
3444 unsigned int i;
3445
3446 printk("bits:");
3447 for (i = 0; i < ARRAY_SIZE(irq_name); i++) {
3448 if (print & (1 << i))
3449 printk(" %s",irq_name[i]);
3450 if (mark & (1 << i))
3451 printk("*");
3452 }
3453}
3454
3455static void bttv_irq_debug_low_latency(struct bttv *btv, u32 rc)
3456{
3457 printk("bttv%d: irq: skipped frame [main=%lx,o_vbi=%lx,o_field=%lx,rc=%lx]\n",
3458 btv->c.nr,
3459 (unsigned long)btv->main.dma,
3460 (unsigned long)btv->main.cpu[RISC_SLOT_O_VBI+1],
3461 (unsigned long)btv->main.cpu[RISC_SLOT_O_FIELD+1],
3462 (unsigned long)rc);
3463
3464 if (0 == (btread(BT848_DSTATUS) & BT848_DSTATUS_HLOC)) {
3465 printk("bttv%d: Oh, there (temporarely?) is no input signal. "
3466 "Ok, then this is harmless, don't worry ;)\n",
3467 btv->c.nr);
3468 return;
3469 }
3470 printk("bttv%d: Uhm. Looks like we have unusual high IRQ latencies.\n",
3471 btv->c.nr);
3472 printk("bttv%d: Lets try to catch the culpit red-handed ...\n",
3473 btv->c.nr);
3474 dump_stack();
3475}
3476
3477static int
3478bttv_irq_next_video(struct bttv *btv, struct bttv_buffer_set *set)
3479{
3480 struct bttv_buffer *item;
3481
3482 memset(set,0,sizeof(*set));
3483
3484 /* capture request ? */
3485 if (!list_empty(&btv->capture)) {
3486 set->frame_irq = 1;
3487 item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
3488 if (V4L2_FIELD_HAS_TOP(item->vb.field))
3489 set->top = item;
3490 if (V4L2_FIELD_HAS_BOTTOM(item->vb.field))
3491 set->bottom = item;
3492
3493 /* capture request for other field ? */
3494 if (!V4L2_FIELD_HAS_BOTH(item->vb.field) &&
3495 (item->vb.queue.next != &btv->capture)) {
3496 item = list_entry(item->vb.queue.next, struct bttv_buffer, vb.queue);
3497 if (!V4L2_FIELD_HAS_BOTH(item->vb.field)) {
3498 if (NULL == set->top &&
3499 V4L2_FIELD_TOP == item->vb.field) {
3500 set->top = item;
3501 }
3502 if (NULL == set->bottom &&
3503 V4L2_FIELD_BOTTOM == item->vb.field) {
3504 set->bottom = item;
3505 }
3506 if (NULL != set->top && NULL != set->bottom)
3507 set->top_irq = 2;
3508 }
3509 }
3510 }
3511
3512 /* screen overlay ? */
3513 if (NULL != btv->screen) {
3514 if (V4L2_FIELD_HAS_BOTH(btv->screen->vb.field)) {
3515 if (NULL == set->top && NULL == set->bottom) {
3516 set->top = btv->screen;
3517 set->bottom = btv->screen;
3518 }
3519 } else {
3520 if (V4L2_FIELD_TOP == btv->screen->vb.field &&
3521 NULL == set->top) {
3522 set->top = btv->screen;
3523 }
3524 if (V4L2_FIELD_BOTTOM == btv->screen->vb.field &&
3525 NULL == set->bottom) {
3526 set->bottom = btv->screen;
3527 }
3528 }
3529 }
3530
3531 dprintk("bttv%d: next set: top=%p bottom=%p [screen=%p,irq=%d,%d]\n",
3532 btv->c.nr,set->top, set->bottom,
3533 btv->screen,set->frame_irq,set->top_irq);
3534 return 0;
3535}
3536
3537static void
3538bttv_irq_wakeup_video(struct bttv *btv, struct bttv_buffer_set *wakeup,
3539 struct bttv_buffer_set *curr, unsigned int state)
3540{
3541 struct timeval ts;
3542
3543 do_gettimeofday(&ts);
3544
3545 if (wakeup->top == wakeup->bottom) {
3546 if (NULL != wakeup->top && curr->top != wakeup->top) {
3547 if (irq_debug > 1)
3548 printk("bttv%d: wakeup: both=%p\n",btv->c.nr,wakeup->top);
3549 wakeup->top->vb.ts = ts;
3550 wakeup->top->vb.field_count = btv->field_count;
3551 wakeup->top->vb.state = state;
3552 wake_up(&wakeup->top->vb.done);
3553 }
3554 } else {
3555 if (NULL != wakeup->top && curr->top != wakeup->top) {
3556 if (irq_debug > 1)
3557 printk("bttv%d: wakeup: top=%p\n",btv->c.nr,wakeup->top);
3558 wakeup->top->vb.ts = ts;
3559 wakeup->top->vb.field_count = btv->field_count;
3560 wakeup->top->vb.state = state;
3561 wake_up(&wakeup->top->vb.done);
3562 }
3563 if (NULL != wakeup->bottom && curr->bottom != wakeup->bottom) {
3564 if (irq_debug > 1)
3565 printk("bttv%d: wakeup: bottom=%p\n",btv->c.nr,wakeup->bottom);
3566 wakeup->bottom->vb.ts = ts;
3567 wakeup->bottom->vb.field_count = btv->field_count;
3568 wakeup->bottom->vb.state = state;
3569 wake_up(&wakeup->bottom->vb.done);
3570 }
3571 }
3572}
3573
3574static void
3575bttv_irq_wakeup_vbi(struct bttv *btv, struct bttv_buffer *wakeup,
3576 unsigned int state)
3577{
3578 struct timeval ts;
3579
3580 if (NULL == wakeup)
3581 return;
3582
3583 do_gettimeofday(&ts);
3584 wakeup->vb.ts = ts;
3585 wakeup->vb.field_count = btv->field_count;
3586 wakeup->vb.state = state;
3587 wake_up(&wakeup->vb.done);
3588}
3589
3590static void bttv_irq_timeout(unsigned long data)
3591{
3592 struct bttv *btv = (struct bttv *)data;
3593 struct bttv_buffer_set old,new;
3594 struct bttv_buffer *ovbi;
3595 struct bttv_buffer *item;
3596 unsigned long flags;
3597
3598 if (bttv_verbose) {
3599 printk(KERN_INFO "bttv%d: timeout: drop=%d irq=%d/%d, risc=%08x, ",
3600 btv->c.nr, btv->framedrop, btv->irq_me, btv->irq_total,
3601 btread(BT848_RISC_COUNT));
3602 bttv_print_irqbits(btread(BT848_INT_STAT),0);
3603 printk("\n");
3604 }
3605
3606 spin_lock_irqsave(&btv->s_lock,flags);
3607
3608 /* deactivate stuff */
3609 memset(&new,0,sizeof(new));
3610 old = btv->curr;
3611 ovbi = btv->cvbi;
3612 btv->curr = new;
3613 btv->cvbi = NULL;
3614 btv->loop_irq = 0;
3615 bttv_buffer_activate_video(btv, &new);
3616 bttv_buffer_activate_vbi(btv, NULL);
3617 bttv_set_dma(btv, 0);
3618
3619 /* wake up */
3620 bttv_irq_wakeup_video(btv, &old, &new, STATE_ERROR);
3621 bttv_irq_wakeup_vbi(btv, ovbi, STATE_ERROR);
3622
3623 /* cancel all outstanding capture / vbi requests */
3624 while (!list_empty(&btv->capture)) {
3625 item = list_entry(btv->capture.next, struct bttv_buffer, vb.queue);
3626 list_del(&item->vb.queue);
3627 item->vb.state = STATE_ERROR;
3628 wake_up(&item->vb.done);
3629 }
3630 while (!list_empty(&btv->vcapture)) {
3631 item = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue);
3632 list_del(&item->vb.queue);
3633 item->vb.state = STATE_ERROR;
3634 wake_up(&item->vb.done);
3635 }
3636
3637 btv->errors++;
3638 spin_unlock_irqrestore(&btv->s_lock,flags);
3639}
3640
3641static void
3642bttv_irq_wakeup_top(struct bttv *btv)
3643{
3644 struct bttv_buffer *wakeup = btv->curr.top;
3645
3646 if (NULL == wakeup)
3647 return;
3648
3649 spin_lock(&btv->s_lock);
3650 btv->curr.top_irq = 0;
3651 btv->curr.top = NULL;
3652 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
3653
3654 do_gettimeofday(&wakeup->vb.ts);
3655 wakeup->vb.field_count = btv->field_count;
3656 wakeup->vb.state = STATE_DONE;
3657 wake_up(&wakeup->vb.done);
3658 spin_unlock(&btv->s_lock);
3659}
3660
3661static inline int is_active(struct btcx_riscmem *risc, u32 rc)
3662{
3663 if (rc < risc->dma)
3664 return 0;
3665 if (rc > risc->dma + risc->size)
3666 return 0;
3667 return 1;
3668}
3669
3670static void
3671bttv_irq_switch_video(struct bttv *btv)
3672{
3673 struct bttv_buffer_set new;
3674 struct bttv_buffer_set old;
3675 dma_addr_t rc;
3676
3677 spin_lock(&btv->s_lock);
3678
3679 /* new buffer set */
3680 bttv_irq_next_video(btv, &new);
3681 rc = btread(BT848_RISC_COUNT);
3682 if ((btv->curr.top && is_active(&btv->curr.top->top, rc)) ||
3683 (btv->curr.bottom && is_active(&btv->curr.bottom->bottom, rc))) {
3684 btv->framedrop++;
3685 if (debug_latency)
3686 bttv_irq_debug_low_latency(btv, rc);
3687 spin_unlock(&btv->s_lock);
3688 return;
3689 }
3690
3691 /* switch over */
3692 old = btv->curr;
3693 btv->curr = new;
3694 btv->loop_irq &= ~1;
3695 bttv_buffer_activate_video(btv, &new);
3696 bttv_set_dma(btv, 0);
3697
3698 /* switch input */
3699 if (UNSET != btv->new_input) {
3700 video_mux(btv,btv->new_input);
3701 btv->new_input = UNSET;
3702 }
3703
3704 /* wake up finished buffers */
3705 bttv_irq_wakeup_video(btv, &old, &new, STATE_DONE);
3706 spin_unlock(&btv->s_lock);
3707}
3708
3709static void
3710bttv_irq_switch_vbi(struct bttv *btv)
3711{
3712 struct bttv_buffer *new = NULL;
3713 struct bttv_buffer *old;
3714 u32 rc;
3715
3716 spin_lock(&btv->s_lock);
3717
3718 if (!list_empty(&btv->vcapture))
3719 new = list_entry(btv->vcapture.next, struct bttv_buffer, vb.queue);
3720 old = btv->cvbi;
3721
3722 rc = btread(BT848_RISC_COUNT);
3723 if (NULL != old && (is_active(&old->top, rc) ||
3724 is_active(&old->bottom, rc))) {
3725 btv->framedrop++;
3726 if (debug_latency)
3727 bttv_irq_debug_low_latency(btv, rc);
3728 spin_unlock(&btv->s_lock);
3729 return;
3730 }
3731
3732 /* switch */
3733 btv->cvbi = new;
3734 btv->loop_irq &= ~4;
3735 bttv_buffer_activate_vbi(btv, new);
3736 bttv_set_dma(btv, 0);
3737
3738 bttv_irq_wakeup_vbi(btv, old, STATE_DONE);
3739 spin_unlock(&btv->s_lock);
3740}
3741
3742static irqreturn_t bttv_irq(int irq, void *dev_id, struct pt_regs * regs)
3743{
3744 u32 stat,astat;
3745 u32 dstat;
3746 int count;
3747 struct bttv *btv;
3748 int handled = 0;
3749
3750 btv=(struct bttv *)dev_id;
3751
3752 if (btv->custom_irq)
3753 handled = btv->custom_irq(btv);
3754
3755 count=0;
3756 while (1) {
3757 /* get/clear interrupt status bits */
3758 stat=btread(BT848_INT_STAT);
3759 astat=stat&btread(BT848_INT_MASK);
3760 if (!astat)
3761 break;
3762 handled = 1;
3763 btwrite(stat,BT848_INT_STAT);
3764
3765 /* get device status bits */
3766 dstat=btread(BT848_DSTATUS);
3767
3768 if (irq_debug) {
3769 printk(KERN_DEBUG "bttv%d: irq loop=%d fc=%d "
3770 "riscs=%x, riscc=%08x, ",
3771 btv->c.nr, count, btv->field_count,
3772 stat>>28, btread(BT848_RISC_COUNT));
3773 bttv_print_irqbits(stat,astat);
3774 if (stat & BT848_INT_HLOCK)
3775 printk(" HLOC => %s", (dstat & BT848_DSTATUS_HLOC)
3776 ? "yes" : "no");
3777 if (stat & BT848_INT_VPRES)
3778 printk(" PRES => %s", (dstat & BT848_DSTATUS_PRES)
3779 ? "yes" : "no");
3780 if (stat & BT848_INT_FMTCHG)
3781 printk(" NUML => %s", (dstat & BT848_DSTATUS_NUML)
3782 ? "625" : "525");
3783 printk("\n");
3784 }
3785
3786 if (astat&BT848_INT_VSYNC)
3787 btv->field_count++;
3788
3789 if ((astat & BT848_INT_GPINT) && btv->remote) {
3790 wake_up(&btv->gpioq);
3791 bttv_input_irq(btv);
3792 }
3793
3794 if (astat & BT848_INT_I2CDONE) {
3795 btv->i2c_done = stat;
3796 wake_up(&btv->i2c_queue);
3797 }
3798
3799 if ((astat & BT848_INT_RISCI) && (stat & (4<<28)))
3800 bttv_irq_switch_vbi(btv);
3801
3802 if ((astat & BT848_INT_RISCI) && (stat & (2<<28)))
3803 bttv_irq_wakeup_top(btv);
3804
3805 if ((astat & BT848_INT_RISCI) && (stat & (1<<28)))
3806 bttv_irq_switch_video(btv);
3807
3808 if ((astat & BT848_INT_HLOCK) && btv->opt_automute)
3809 audio_mute(btv, btv->mute); /* trigger automute */
3810
3811 if (astat & (BT848_INT_SCERR|BT848_INT_OCERR)) {
3812 printk(KERN_INFO "bttv%d: %s%s @ %08x,",btv->c.nr,
3813 (astat & BT848_INT_SCERR) ? "SCERR" : "",
3814 (astat & BT848_INT_OCERR) ? "OCERR" : "",
3815 btread(BT848_RISC_COUNT));
3816 bttv_print_irqbits(stat,astat);
3817 printk("\n");
3818 if (bttv_debug)
3819 bttv_print_riscaddr(btv);
3820 }
3821 if (fdsr && astat & BT848_INT_FDSR) {
3822 printk(KERN_INFO "bttv%d: FDSR @ %08x\n",
3823 btv->c.nr,btread(BT848_RISC_COUNT));
3824 if (bttv_debug)
3825 bttv_print_riscaddr(btv);
3826 }
3827
3828 count++;
3829 if (count > 4) {
3830
3831 if (count > 8 || !(astat & BT848_INT_GPINT)) {
3832 btwrite(0, BT848_INT_MASK);
3833
3834 printk(KERN_ERR
3835 "bttv%d: IRQ lockup, cleared int mask [", btv->c.nr);
3836 } else {
3837 printk(KERN_ERR
3838 "bttv%d: IRQ lockup, clearing GPINT from int mask [", btv->c.nr);
3839
3840 btwrite(btread(BT848_INT_MASK) & (-1 ^ BT848_INT_GPINT),
3841 BT848_INT_MASK);
3842 };
3843
3844 bttv_print_irqbits(stat,astat);
3845
3846 printk("]\n");
3847 }
3848 }
3849 btv->irq_total++;
3850 if (handled)
3851 btv->irq_me++;
3852 return IRQ_RETVAL(handled);
3853}
3854
3855
3856/* ----------------------------------------------------------------------- */
3857/* initialitation */
3858
3859static struct video_device *vdev_init(struct bttv *btv,
3860 struct video_device *template,
3861 char *type)
3862{
3863 struct video_device *vfd;
3864
3865 vfd = video_device_alloc();
3866 if (NULL == vfd)
3867 return NULL;
3868 *vfd = *template;
3869 vfd->minor = -1;
3870 vfd->dev = &btv->c.pci->dev;
3871 vfd->release = video_device_release;
3872 snprintf(vfd->name, sizeof(vfd->name), "BT%d%s %s (%s)",
3873 btv->id, (btv->id==848 && btv->revision==0x12) ? "A" : "",
3874 type, bttv_tvcards[btv->c.type].name);
3875 return vfd;
3876}
3877
3878static void bttv_unregister_video(struct bttv *btv)
3879{
3880 if (btv->video_dev) {
3881 if (-1 != btv->video_dev->minor)
3882 video_unregister_device(btv->video_dev);
3883 else
3884 video_device_release(btv->video_dev);
3885 btv->video_dev = NULL;
3886 }
3887 if (btv->vbi_dev) {
3888 if (-1 != btv->vbi_dev->minor)
3889 video_unregister_device(btv->vbi_dev);
3890 else
3891 video_device_release(btv->vbi_dev);
3892 btv->vbi_dev = NULL;
3893 }
3894 if (btv->radio_dev) {
3895 if (-1 != btv->radio_dev->minor)
3896 video_unregister_device(btv->radio_dev);
3897 else
3898 video_device_release(btv->radio_dev);
3899 btv->radio_dev = NULL;
3900 }
3901}
3902
3903/* register video4linux devices */
3904static int __devinit bttv_register_video(struct bttv *btv)
3905{
3906 if (no_overlay <= 0) {
3907 bttv_video_template.type |= VID_TYPE_OVERLAY;
3908 } else {
3909 printk("bttv: Overlay support disabled.\n");
3910 }
3911
3912 /* video */
3913 btv->video_dev = vdev_init(btv, &bttv_video_template, "video");
3914 if (NULL == btv->video_dev)
3915 goto err;
3916 if (video_register_device(btv->video_dev,VFL_TYPE_GRABBER,video_nr)<0)
3917 goto err;
3918 printk(KERN_INFO "bttv%d: registered device video%d\n",
3919 btv->c.nr,btv->video_dev->minor & 0x1f);
3920 video_device_create_file(btv->video_dev, &class_device_attr_card);
3921
3922 /* vbi */
3923 btv->vbi_dev = vdev_init(btv, &bttv_vbi_template, "vbi");
3924 if (NULL == btv->vbi_dev)
3925 goto err;
3926 if (video_register_device(btv->vbi_dev,VFL_TYPE_VBI,vbi_nr)<0)
3927 goto err;
3928 printk(KERN_INFO "bttv%d: registered device vbi%d\n",
3929 btv->c.nr,btv->vbi_dev->minor & 0x1f);
3930
3931 if (!btv->has_radio)
3932 return 0;
3933 /* radio */
3934 btv->radio_dev = vdev_init(btv, &radio_template, "radio");
3935 if (NULL == btv->radio_dev)
3936 goto err;
3937 if (video_register_device(btv->radio_dev, VFL_TYPE_RADIO,radio_nr)<0)
3938 goto err;
3939 printk(KERN_INFO "bttv%d: registered device radio%d\n",
3940 btv->c.nr,btv->radio_dev->minor & 0x1f);
3941
3942 /* all done */
3943 return 0;
3944
3945 err:
3946 bttv_unregister_video(btv);
3947 return -1;
3948}
3949
3950
3951/* on OpenFirmware machines (PowerMac at least), PCI memory cycle */
3952/* response on cards with no firmware is not enabled by OF */
3953static void pci_set_command(struct pci_dev *dev)
3954{
3955#if defined(__powerpc__)
3956 unsigned int cmd;
3957
3958 pci_read_config_dword(dev, PCI_COMMAND, &cmd);
3959 cmd = (cmd | PCI_COMMAND_MEMORY );
3960 pci_write_config_dword(dev, PCI_COMMAND, cmd);
3961#endif
3962}
3963
3964static int __devinit bttv_probe(struct pci_dev *dev,
3965 const struct pci_device_id *pci_id)
3966{
3967 int result;
3968 unsigned char lat;
3969 struct bttv *btv;
3970
3971 if (bttv_num == BTTV_MAX)
3972 return -ENOMEM;
3973 printk(KERN_INFO "bttv: Bt8xx card found (%d).\n", bttv_num);
3974 btv=&bttvs[bttv_num];
3975 memset(btv,0,sizeof(*btv));
3976 btv->c.nr = bttv_num;
3977 sprintf(btv->c.name,"bttv%d",btv->c.nr);
3978
3979 /* initialize structs / fill in defaults */
3980 mutex_init(&btv->lock);
3981 mutex_init(&btv->reslock);
3982 spin_lock_init(&btv->s_lock);
3983 spin_lock_init(&btv->gpio_lock);
3984 init_waitqueue_head(&btv->gpioq);
3985 init_waitqueue_head(&btv->i2c_queue);
3986 INIT_LIST_HEAD(&btv->c.subs);
3987 INIT_LIST_HEAD(&btv->capture);
3988 INIT_LIST_HEAD(&btv->vcapture);
3989 v4l2_prio_init(&btv->prio);
3990
3991 init_timer(&btv->timeout);
3992 btv->timeout.function = bttv_irq_timeout;
3993 btv->timeout.data = (unsigned long)btv;
3994
3995 btv->i2c_rc = -1;
3996 btv->tuner_type = UNSET;
3997 btv->new_input = UNSET;
3998 btv->has_radio=radio[btv->c.nr];
3999
4000 /* pci stuff (init, get irq/mmio, ... */
4001 btv->c.pci = dev;
4002 btv->id = dev->device;
4003 if (pci_enable_device(dev)) {
4004 printk(KERN_WARNING "bttv%d: Can't enable device.\n",
4005 btv->c.nr);
4006 return -EIO;
4007 }
4008 if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
4009 printk(KERN_WARNING "bttv%d: No suitable DMA available.\n",
4010 btv->c.nr);
4011 return -EIO;
4012 }
4013 if (!request_mem_region(pci_resource_start(dev,0),
4014 pci_resource_len(dev,0),
4015 btv->c.name)) {
4016 printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n",
4017 btv->c.nr, pci_resource_start(dev,0));
4018 return -EBUSY;
4019 }
4020 pci_set_master(dev);
4021 pci_set_command(dev);
4022 pci_set_drvdata(dev,btv);
4023
4024 pci_read_config_byte(dev, PCI_CLASS_REVISION, &btv->revision);
4025 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
4026 printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ",
4027 bttv_num,btv->id, btv->revision, pci_name(dev));
4028 printk("irq: %d, latency: %d, mmio: 0x%lx\n",
4029 btv->c.pci->irq, lat, pci_resource_start(dev,0));
4030 schedule();
4031
4032 btv->bt848_mmio=ioremap(pci_resource_start(dev,0), 0x1000);
4033 if (NULL == ioremap(pci_resource_start(dev,0), 0x1000)) {
4034 printk("bttv%d: ioremap() failed\n", btv->c.nr);
4035 result = -EIO;
4036 goto fail1;
4037 }
4038
4039 /* identify card */
4040 bttv_idcard(btv);
4041
4042 /* disable irqs, register irq handler */
4043 btwrite(0, BT848_INT_MASK);
4044 result = request_irq(btv->c.pci->irq, bttv_irq,
4045 SA_SHIRQ | SA_INTERRUPT,btv->c.name,(void *)btv);
4046 if (result < 0) {
4047 printk(KERN_ERR "bttv%d: can't get IRQ %d\n",
4048 bttv_num,btv->c.pci->irq);
4049 goto fail1;
4050 }
4051
4052 if (0 != bttv_handle_chipset(btv)) {
4053 result = -EIO;
4054 goto fail2;
4055 }
4056
4057 /* init options from insmod args */
4058 btv->opt_combfilter = combfilter;
4059 btv->opt_lumafilter = lumafilter;
4060 btv->opt_automute = automute;
4061 btv->opt_chroma_agc = chroma_agc;
4062 btv->opt_adc_crush = adc_crush;
4063 btv->opt_vcr_hack = vcr_hack;
4064 btv->opt_whitecrush_upper = whitecrush_upper;
4065 btv->opt_whitecrush_lower = whitecrush_lower;
4066 btv->opt_uv_ratio = uv_ratio;
4067 btv->opt_full_luma_range = full_luma_range;
4068 btv->opt_coring = coring;
4069
4070 /* fill struct bttv with some useful defaults */
4071 btv->init.btv = btv;
4072 btv->init.ov.w.width = 320;
4073 btv->init.ov.w.height = 240;
4074 btv->init.fmt = format_by_palette(VIDEO_PALETTE_RGB24);
4075 btv->init.width = 320;
4076 btv->init.height = 240;
4077 btv->init.lines = 16;
4078 btv->input = 0;
4079
4080 /* initialize hardware */
4081 if (bttv_gpio)
4082 bttv_gpio_tracking(btv,"pre-init");
4083
4084 bttv_risc_init_main(btv);
4085 init_bt848(btv);
4086
4087 /* gpio */
4088 btwrite(0x00, BT848_GPIO_REG_INP);
4089 btwrite(0x00, BT848_GPIO_OUT_EN);
4090 if (bttv_verbose)
4091 bttv_gpio_tracking(btv,"init");
4092
4093 /* needs to be done before i2c is registered */
4094 bttv_init_card1(btv);
4095
4096 /* register i2c + gpio */
4097 init_bttv_i2c(btv);
4098
4099 /* some card-specific stuff (needs working i2c) */
4100 bttv_init_card2(btv);
4101 init_irqreg(btv);
4102
4103 /* register video4linux + input */
4104 if (!bttv_tvcards[btv->c.type].no_video) {
4105 bttv_register_video(btv);
4106 bt848_bright(btv,32768);
4107 bt848_contrast(btv,32768);
4108 bt848_hue(btv,32768);
4109 bt848_sat(btv,32768);
4110 audio_mute(btv, 1);
4111 set_input(btv,0);
4112 }
4113
4114 /* add subdevices */
4115 if (bttv_tvcards[btv->c.type].has_dvb)
4116 bttv_sub_add_device(&btv->c, "dvb");
4117
4118 bttv_input_init(btv);
4119
4120 /* everything is fine */
4121 bttv_num++;
4122 return 0;
4123
4124 fail2:
4125 free_irq(btv->c.pci->irq,btv);
4126
4127 fail1:
4128 if (btv->bt848_mmio)
4129 iounmap(btv->bt848_mmio);
4130 release_mem_region(pci_resource_start(btv->c.pci,0),
4131 pci_resource_len(btv->c.pci,0));
4132 pci_set_drvdata(dev,NULL);
4133 return result;
4134}
4135
4136static void __devexit bttv_remove(struct pci_dev *pci_dev)
4137{
4138 struct bttv *btv = pci_get_drvdata(pci_dev);
4139
4140 if (bttv_verbose)
4141 printk("bttv%d: unloading\n",btv->c.nr);
4142
4143 /* shutdown everything (DMA+IRQs) */
4144 btand(~15, BT848_GPIO_DMA_CTL);
4145 btwrite(0, BT848_INT_MASK);
4146 btwrite(~0x0, BT848_INT_STAT);
4147 btwrite(0x0, BT848_GPIO_OUT_EN);
4148 if (bttv_gpio)
4149 bttv_gpio_tracking(btv,"cleanup");
4150
4151 /* tell gpio modules we are leaving ... */
4152 btv->shutdown=1;
4153 wake_up(&btv->gpioq);
4154 bttv_input_fini(btv);
4155 bttv_sub_del_devices(&btv->c);
4156
4157 /* unregister i2c_bus + input */
4158 fini_bttv_i2c(btv);
4159
4160 /* unregister video4linux */
4161 bttv_unregister_video(btv);
4162
4163 /* free allocated memory */
4164 btcx_riscmem_free(btv->c.pci,&btv->main);
4165
4166 /* free ressources */
4167 free_irq(btv->c.pci->irq,btv);
4168 iounmap(btv->bt848_mmio);
4169 release_mem_region(pci_resource_start(btv->c.pci,0),
4170 pci_resource_len(btv->c.pci,0));
4171
4172 pci_set_drvdata(pci_dev, NULL);
4173 return;
4174}
4175
4176static int bttv_suspend(struct pci_dev *pci_dev, pm_message_t state)
4177{
4178 struct bttv *btv = pci_get_drvdata(pci_dev);
4179 struct bttv_buffer_set idle;
4180 unsigned long flags;
4181
4182 dprintk("bttv%d: suspend %d\n", btv->c.nr, state.event);
4183
4184 /* stop dma + irqs */
4185 spin_lock_irqsave(&btv->s_lock,flags);
4186 memset(&idle, 0, sizeof(idle));
4187 btv->state.video = btv->curr;
4188 btv->state.vbi = btv->cvbi;
4189 btv->state.loop_irq = btv->loop_irq;
4190 btv->curr = idle;
4191 btv->loop_irq = 0;
4192 bttv_buffer_activate_video(btv, &idle);
4193 bttv_buffer_activate_vbi(btv, NULL);
4194 bttv_set_dma(btv, 0);
4195 btwrite(0, BT848_INT_MASK);
4196 spin_unlock_irqrestore(&btv->s_lock,flags);
4197
4198 /* save bt878 state */
4199 btv->state.gpio_enable = btread(BT848_GPIO_OUT_EN);
4200 btv->state.gpio_data = gpio_read();
4201
4202 /* save pci state */
4203 pci_save_state(pci_dev);
4204 if (0 != pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) {
4205 pci_disable_device(pci_dev);
4206 btv->state.disabled = 1;
4207 }
4208 return 0;
4209}
4210
4211static int bttv_resume(struct pci_dev *pci_dev)
4212{
4213 struct bttv *btv = pci_get_drvdata(pci_dev);
4214 unsigned long flags;
4215 int err;
4216
4217 dprintk("bttv%d: resume\n", btv->c.nr);
4218
4219 /* restore pci state */
4220 if (btv->state.disabled) {
4221 err=pci_enable_device(pci_dev);
4222 if (err) {
4223 printk(KERN_WARNING "bttv%d: Can't enable device.\n",
4224 btv->c.nr);
4225 return err;
4226 }
4227 btv->state.disabled = 0;
4228 }
4229 err=pci_set_power_state(pci_dev, PCI_D0);
4230 if (err) {
4231 pci_disable_device(pci_dev);
4232 printk(KERN_WARNING "bttv%d: Can't enable device.\n",
4233 btv->c.nr);
4234 btv->state.disabled = 1;
4235 return err;
4236 }
4237
4238 pci_restore_state(pci_dev);
4239
4240 /* restore bt878 state */
4241 bttv_reinit_bt848(btv);
4242 gpio_inout(0xffffff, btv->state.gpio_enable);
4243 gpio_write(btv->state.gpio_data);
4244
4245 /* restart dma */
4246 spin_lock_irqsave(&btv->s_lock,flags);
4247 btv->curr = btv->state.video;
4248 btv->cvbi = btv->state.vbi;
4249 btv->loop_irq = btv->state.loop_irq;
4250 bttv_buffer_activate_video(btv, &btv->curr);
4251 bttv_buffer_activate_vbi(btv, btv->cvbi);
4252 bttv_set_dma(btv, 0);
4253 spin_unlock_irqrestore(&btv->s_lock,flags);
4254 return 0;
4255}
4256
4257static struct pci_device_id bttv_pci_tbl[] = {
4258 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
4259 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4260 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
4261 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4262 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT878,
4263 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4264 {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT879,
4265 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
4266 {0,}
4267};
4268
4269MODULE_DEVICE_TABLE(pci, bttv_pci_tbl);
4270
4271static struct pci_driver bttv_pci_driver = {
4272 .name = "bttv",
4273 .id_table = bttv_pci_tbl,
4274 .probe = bttv_probe,
4275 .remove = __devexit_p(bttv_remove),
4276 .suspend = bttv_suspend,
4277 .resume = bttv_resume,
4278};
4279
4280static int bttv_init_module(void)
4281{
4282 bttv_num = 0;
4283
4284 printk(KERN_INFO "bttv: driver version %d.%d.%d loaded\n",
4285 (BTTV_VERSION_CODE >> 16) & 0xff,
4286 (BTTV_VERSION_CODE >> 8) & 0xff,
4287 BTTV_VERSION_CODE & 0xff);
4288#ifdef SNAPSHOT
4289 printk(KERN_INFO "bttv: snapshot date %04d-%02d-%02d\n",
4290 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
4291#endif
4292 if (gbuffers < 2 || gbuffers > VIDEO_MAX_FRAME)
4293 gbuffers = 2;
4294 if (gbufsize < 0 || gbufsize > BTTV_MAX_FBUF)
4295 gbufsize = BTTV_MAX_FBUF;
4296 gbufsize = (gbufsize + PAGE_SIZE - 1) & PAGE_MASK;
4297 if (bttv_verbose)
4298 printk(KERN_INFO "bttv: using %d buffers with %dk (%d pages) each for capture\n",
4299 gbuffers, gbufsize >> 10, gbufsize >> PAGE_SHIFT);
4300
4301 bttv_check_chipset();
4302
4303 bus_register(&bttv_sub_bus_type);
4304 return pci_register_driver(&bttv_pci_driver);
4305}
4306
4307static void bttv_cleanup_module(void)
4308{
4309 pci_unregister_driver(&bttv_pci_driver);
4310 bus_unregister(&bttv_sub_bus_type);
4311 return;
4312}
4313
4314module_init(bttv_init_module);
4315module_exit(bttv_cleanup_module);
4316
4317/*
4318 * Local variables:
4319 * c-basic-offset: 8
4320 * End:
4321 */
diff --git a/drivers/media/video/bt8xx/bttv-gpio.c b/drivers/media/video/bt8xx/bttv-gpio.c
new file mode 100644
index 000000000000..c4d5e2b70c28
--- /dev/null
+++ b/drivers/media/video/bt8xx/bttv-gpio.c
@@ -0,0 +1,208 @@
1/*
2
3 bttv-gpio.c -- gpio sub drivers
4
5 sysfs-based sub driver interface for bttv
6 mainly intented for gpio access
7
8
9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
10 & Marcus Metzler (mocm@thp.uni-koeln.de)
11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
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
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
27*/
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/delay.h>
32#include <linux/device.h>
33#include <asm/io.h>
34
35#include "bttvp.h"
36
37/* ----------------------------------------------------------------------- */
38/* internal: the bttv "bus" */
39
40static int bttv_sub_bus_match(struct device *dev, struct device_driver *drv)
41{
42 struct bttv_sub_driver *sub = to_bttv_sub_drv(drv);
43 int len = strlen(sub->wanted);
44
45 if (0 == strncmp(dev->bus_id, sub->wanted, len))
46 return 1;
47 return 0;
48}
49
50static int bttv_sub_probe(struct device *dev)
51{
52 struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
53 struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
54
55 return sub->probe ? sub->probe(sdev) : -ENODEV;
56}
57
58static int bttv_sub_remove(struct device *dev)
59{
60 struct bttv_sub_device *sdev = to_bttv_sub_dev(dev);
61 struct bttv_sub_driver *sub = to_bttv_sub_drv(dev->driver);
62
63 if (sub->remove)
64 sub->remove(sdev);
65 return 0;
66}
67
68struct bus_type bttv_sub_bus_type = {
69 .name = "bttv-sub",
70 .match = &bttv_sub_bus_match,
71 .probe = bttv_sub_probe,
72 .remove = bttv_sub_remove,
73};
74EXPORT_SYMBOL(bttv_sub_bus_type);
75
76static void release_sub_device(struct device *dev)
77{
78 struct bttv_sub_device *sub = to_bttv_sub_dev(dev);
79 kfree(sub);
80}
81
82int bttv_sub_add_device(struct bttv_core *core, char *name)
83{
84 struct bttv_sub_device *sub;
85 int err;
86
87 sub = kzalloc(sizeof(*sub),GFP_KERNEL);
88 if (NULL == sub)
89 return -ENOMEM;
90
91 sub->core = core;
92 sub->dev.parent = &core->pci->dev;
93 sub->dev.bus = &bttv_sub_bus_type;
94 sub->dev.release = release_sub_device;
95 snprintf(sub->dev.bus_id,sizeof(sub->dev.bus_id),"%s%d",
96 name, core->nr);
97
98 err = device_register(&sub->dev);
99 if (0 != err) {
100 kfree(sub);
101 return err;
102 }
103 printk("bttv%d: add subdevice \"%s\"\n", core->nr, sub->dev.bus_id);
104 list_add_tail(&sub->list,&core->subs);
105 return 0;
106}
107
108int bttv_sub_del_devices(struct bttv_core *core)
109{
110 struct bttv_sub_device *sub;
111 struct list_head *item,*save;
112
113 list_for_each_safe(item,save,&core->subs) {
114 sub = list_entry(item,struct bttv_sub_device,list);
115 list_del(&sub->list);
116 device_unregister(&sub->dev);
117 }
118 return 0;
119}
120
121void bttv_gpio_irq(struct bttv_core *core)
122{
123 struct bttv_sub_driver *drv;
124 struct bttv_sub_device *dev;
125 struct list_head *item;
126
127 list_for_each(item,&core->subs) {
128 dev = list_entry(item,struct bttv_sub_device,list);
129 drv = to_bttv_sub_drv(dev->dev.driver);
130 if (drv && drv->gpio_irq)
131 drv->gpio_irq(dev);
132 }
133}
134
135/* ----------------------------------------------------------------------- */
136/* external: sub-driver register/unregister */
137
138int bttv_sub_register(struct bttv_sub_driver *sub, char *wanted)
139{
140 sub->drv.bus = &bttv_sub_bus_type;
141 snprintf(sub->wanted,sizeof(sub->wanted),"%s",wanted);
142 return driver_register(&sub->drv);
143}
144EXPORT_SYMBOL(bttv_sub_register);
145
146int bttv_sub_unregister(struct bttv_sub_driver *sub)
147{
148 driver_unregister(&sub->drv);
149 return 0;
150}
151EXPORT_SYMBOL(bttv_sub_unregister);
152
153/* ----------------------------------------------------------------------- */
154/* external: gpio access functions */
155
156void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits)
157{
158 struct bttv *btv = container_of(core, struct bttv, c);
159 unsigned long flags;
160 u32 data;
161
162 spin_lock_irqsave(&btv->gpio_lock,flags);
163 data = btread(BT848_GPIO_OUT_EN);
164 data = data & ~mask;
165 data = data | (mask & outbits);
166 btwrite(data,BT848_GPIO_OUT_EN);
167 spin_unlock_irqrestore(&btv->gpio_lock,flags);
168}
169EXPORT_SYMBOL(bttv_gpio_inout);
170
171u32 bttv_gpio_read(struct bttv_core *core)
172{
173 struct bttv *btv = container_of(core, struct bttv, c);
174 u32 value;
175
176 value = btread(BT848_GPIO_DATA);
177 return value;
178}
179EXPORT_SYMBOL(bttv_gpio_read);
180
181void bttv_gpio_write(struct bttv_core *core, u32 value)
182{
183 struct bttv *btv = container_of(core, struct bttv, c);
184
185 btwrite(value,BT848_GPIO_DATA);
186}
187EXPORT_SYMBOL(bttv_gpio_write);
188
189void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits)
190{
191 struct bttv *btv = container_of(core, struct bttv, c);
192 unsigned long flags;
193 u32 data;
194
195 spin_lock_irqsave(&btv->gpio_lock,flags);
196 data = btread(BT848_GPIO_DATA);
197 data = data & ~mask;
198 data = data | (mask & bits);
199 btwrite(data,BT848_GPIO_DATA);
200 spin_unlock_irqrestore(&btv->gpio_lock,flags);
201}
202EXPORT_SYMBOL(bttv_gpio_bits);
203
204/*
205 * Local variables:
206 * c-basic-offset: 8
207 * End:
208 */
diff --git a/drivers/media/video/bt8xx/bttv-i2c.c b/drivers/media/video/bt8xx/bttv-i2c.c
new file mode 100644
index 000000000000..4b562b386fcf
--- /dev/null
+++ b/drivers/media/video/bt8xx/bttv-i2c.c
@@ -0,0 +1,478 @@
1/*
2
3 bttv-i2c.c -- all the i2c code is here
4
5 bttv - Bt848 frame grabber driver
6
7 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
8 & Marcus Metzler (mocm@thp.uni-koeln.de)
9 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
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
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25*/
26
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30#include <linux/delay.h>
31
32#include "bttvp.h"
33#include <media/v4l2-common.h>
34#include <linux/jiffies.h>
35#include <asm/io.h>
36
37static struct i2c_algo_bit_data bttv_i2c_algo_bit_template;
38static struct i2c_adapter bttv_i2c_adap_sw_template;
39static struct i2c_adapter bttv_i2c_adap_hw_template;
40static struct i2c_client bttv_i2c_client_template;
41
42static int attach_inform(struct i2c_client *client);
43
44static int i2c_debug;
45static int i2c_hw;
46static int i2c_scan;
47module_param(i2c_debug, int, 0644);
48module_param(i2c_hw, int, 0444);
49module_param(i2c_scan, int, 0444);
50MODULE_PARM_DESC(i2c_scan,"scan i2c bus at insmod time");
51
52/* ----------------------------------------------------------------------- */
53/* I2C functions - bitbanging adapter (software i2c) */
54
55static void bttv_bit_setscl(void *data, int state)
56{
57 struct bttv *btv = (struct bttv*)data;
58
59 if (state)
60 btv->i2c_state |= 0x02;
61 else
62 btv->i2c_state &= ~0x02;
63 btwrite(btv->i2c_state, BT848_I2C);
64 btread(BT848_I2C);
65}
66
67static void bttv_bit_setsda(void *data, int state)
68{
69 struct bttv *btv = (struct bttv*)data;
70
71 if (state)
72 btv->i2c_state |= 0x01;
73 else
74 btv->i2c_state &= ~0x01;
75 btwrite(btv->i2c_state, BT848_I2C);
76 btread(BT848_I2C);
77}
78
79static int bttv_bit_getscl(void *data)
80{
81 struct bttv *btv = (struct bttv*)data;
82 int state;
83
84 state = btread(BT848_I2C) & 0x02 ? 1 : 0;
85 return state;
86}
87
88static int bttv_bit_getsda(void *data)
89{
90 struct bttv *btv = (struct bttv*)data;
91 int state;
92
93 state = btread(BT848_I2C) & 0x01;
94 return state;
95}
96
97static struct i2c_algo_bit_data bttv_i2c_algo_bit_template = {
98 .setsda = bttv_bit_setsda,
99 .setscl = bttv_bit_setscl,
100 .getsda = bttv_bit_getsda,
101 .getscl = bttv_bit_getscl,
102 .udelay = 16,
103 .mdelay = 10,
104 .timeout = 200,
105};
106
107static struct i2c_adapter bttv_i2c_adap_sw_template = {
108 .owner = THIS_MODULE,
109 .class = I2C_CLASS_TV_ANALOG,
110 .name = "bttv",
111 .id = I2C_HW_B_BT848,
112 .client_register = attach_inform,
113};
114
115/* ----------------------------------------------------------------------- */
116/* I2C functions - hardware i2c */
117
118static int algo_control(struct i2c_adapter *adapter,
119 unsigned int cmd, unsigned long arg)
120{
121 return 0;
122}
123
124static u32 functionality(struct i2c_adapter *adap)
125{
126 return I2C_FUNC_SMBUS_EMUL;
127}
128
129static int
130bttv_i2c_wait_done(struct bttv *btv)
131{
132 int rc = 0;
133
134 /* timeout */
135 if (wait_event_interruptible_timeout(btv->i2c_queue,
136 btv->i2c_done, msecs_to_jiffies(85)) == -ERESTARTSYS)
137
138 rc = -EIO;
139
140 if (btv->i2c_done & BT848_INT_RACK)
141 rc = 1;
142 btv->i2c_done = 0;
143 return rc;
144}
145
146#define I2C_HW (BT878_I2C_MODE | BT848_I2C_SYNC |\
147 BT848_I2C_SCL | BT848_I2C_SDA)
148
149static int
150bttv_i2c_sendbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
151{
152 u32 xmit;
153 int retval,cnt;
154
155 /* sanity checks */
156 if (0 == msg->len)
157 return -EINVAL;
158
159 /* start, address + first byte */
160 xmit = (msg->addr << 25) | (msg->buf[0] << 16) | I2C_HW;
161 if (msg->len > 1 || !last)
162 xmit |= BT878_I2C_NOSTOP;
163 btwrite(xmit, BT848_I2C);
164 retval = bttv_i2c_wait_done(btv);
165 if (retval < 0)
166 goto err;
167 if (retval == 0)
168 goto eio;
169 if (i2c_debug) {
170 printk(" <W %02x %02x", msg->addr << 1, msg->buf[0]);
171 if (!(xmit & BT878_I2C_NOSTOP))
172 printk(" >\n");
173 }
174
175 for (cnt = 1; cnt < msg->len; cnt++ ) {
176 /* following bytes */
177 xmit = (msg->buf[cnt] << 24) | I2C_HW | BT878_I2C_NOSTART;
178 if (cnt < msg->len-1 || !last)
179 xmit |= BT878_I2C_NOSTOP;
180 btwrite(xmit, BT848_I2C);
181 retval = bttv_i2c_wait_done(btv);
182 if (retval < 0)
183 goto err;
184 if (retval == 0)
185 goto eio;
186 if (i2c_debug) {
187 printk(" %02x", msg->buf[cnt]);
188 if (!(xmit & BT878_I2C_NOSTOP))
189 printk(" >\n");
190 }
191 }
192 return msg->len;
193
194 eio:
195 retval = -EIO;
196 err:
197 if (i2c_debug)
198 printk(" ERR: %d\n",retval);
199 return retval;
200}
201
202static int
203bttv_i2c_readbytes(struct bttv *btv, const struct i2c_msg *msg, int last)
204{
205 u32 xmit;
206 u32 cnt;
207 int retval;
208
209 for(cnt = 0; cnt < msg->len; cnt++) {
210 xmit = (msg->addr << 25) | (1 << 24) | I2C_HW;
211 if (cnt < msg->len-1)
212 xmit |= BT848_I2C_W3B;
213 if (cnt < msg->len-1 || !last)
214 xmit |= BT878_I2C_NOSTOP;
215 if (cnt)
216 xmit |= BT878_I2C_NOSTART;
217 btwrite(xmit, BT848_I2C);
218 retval = bttv_i2c_wait_done(btv);
219 if (retval < 0)
220 goto err;
221 if (retval == 0)
222 goto eio;
223 msg->buf[cnt] = ((u32)btread(BT848_I2C) >> 8) & 0xff;
224 if (i2c_debug) {
225 if (!(xmit & BT878_I2C_NOSTART))
226 printk(" <R %02x", (msg->addr << 1) +1);
227 printk(" =%02x", msg->buf[cnt]);
228 if (!(xmit & BT878_I2C_NOSTOP))
229 printk(" >\n");
230 }
231 }
232 return msg->len;
233
234 eio:
235 retval = -EIO;
236 err:
237 if (i2c_debug)
238 printk(" ERR: %d\n",retval);
239 return retval;
240}
241
242static int bttv_i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
243{
244 struct bttv *btv = i2c_get_adapdata(i2c_adap);
245 int retval = 0;
246 int i;
247
248 if (i2c_debug)
249 printk("bt-i2c:");
250 btwrite(BT848_INT_I2CDONE|BT848_INT_RACK, BT848_INT_STAT);
251 for (i = 0 ; i < num; i++) {
252 if (msgs[i].flags & I2C_M_RD) {
253 /* read */
254 retval = bttv_i2c_readbytes(btv, &msgs[i], i+1 == num);
255 if (retval < 0)
256 goto err;
257 } else {
258 /* write */
259 retval = bttv_i2c_sendbytes(btv, &msgs[i], i+1 == num);
260 if (retval < 0)
261 goto err;
262 }
263 }
264 return num;
265
266 err:
267 return retval;
268}
269
270static struct i2c_algorithm bttv_algo = {
271 .master_xfer = bttv_i2c_xfer,
272 .algo_control = algo_control,
273 .functionality = functionality,
274};
275
276static struct i2c_adapter bttv_i2c_adap_hw_template = {
277 .owner = THIS_MODULE,
278 .class = I2C_CLASS_TV_ANALOG,
279 .name = "bt878",
280 .id = I2C_HW_B_BT848 /* FIXME */,
281 .algo = &bttv_algo,
282 .client_register = attach_inform,
283};
284
285/* ----------------------------------------------------------------------- */
286/* I2C functions - common stuff */
287
288static int attach_inform(struct i2c_client *client)
289{
290 struct bttv *btv = i2c_get_adapdata(client->adapter);
291 int addr=ADDR_UNSET;
292
293
294 if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
295 addr = bttv_tvcards[btv->c.type].tuner_addr;
296
297
298 if (bttv_debug)
299 printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n",
300 btv->c.nr, client->driver->driver.name, client->addr,
301 client->name);
302 if (!client->driver->command)
303 return 0;
304
305 if (client->driver->id == I2C_DRIVERID_MSP3400)
306 btv->i2c_msp34xx_client = client;
307 if (client->driver->id == I2C_DRIVERID_TVAUDIO)
308 btv->i2c_tvaudio_client = client;
309 if (btv->tuner_type != UNSET) {
310 struct tuner_setup tun_setup;
311
312 if ((addr==ADDR_UNSET) ||
313 (addr==client->addr)) {
314
315 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV | T_RADIO;
316 tun_setup.type = btv->tuner_type;
317 tun_setup.addr = addr;
318 bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
319 }
320
321 }
322
323 return 0;
324}
325
326void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
327{
328 if (0 != btv->i2c_rc)
329 return;
330 i2c_clients_command(&btv->c.i2c_adap, cmd, arg);
331}
332
333static struct i2c_client bttv_i2c_client_template = {
334 .name = "bttv internal",
335};
336
337
338/* read I2C */
339int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
340{
341 unsigned char buffer = 0;
342
343 if (0 != btv->i2c_rc)
344 return -1;
345 if (bttv_verbose && NULL != probe_for)
346 printk(KERN_INFO "bttv%d: i2c: checking for %s @ 0x%02x... ",
347 btv->c.nr,probe_for,addr);
348 btv->i2c_client.addr = addr >> 1;
349 if (1 != i2c_master_recv(&btv->i2c_client, &buffer, 1)) {
350 if (NULL != probe_for) {
351 if (bttv_verbose)
352 printk("not found\n");
353 } else
354 printk(KERN_WARNING "bttv%d: i2c read 0x%x: error\n",
355 btv->c.nr,addr);
356 return -1;
357 }
358 if (bttv_verbose && NULL != probe_for)
359 printk("found\n");
360 return buffer;
361}
362
363/* write I2C */
364int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
365 unsigned char b2, int both)
366{
367 unsigned char buffer[2];
368 int bytes = both ? 2 : 1;
369
370 if (0 != btv->i2c_rc)
371 return -1;
372 btv->i2c_client.addr = addr >> 1;
373 buffer[0] = b1;
374 buffer[1] = b2;
375 if (bytes != i2c_master_send(&btv->i2c_client, buffer, bytes))
376 return -1;
377 return 0;
378}
379
380/* read EEPROM content */
381void __devinit bttv_readee(struct bttv *btv, unsigned char *eedata, int addr)
382{
383 memset(eedata, 0, 256);
384 if (0 != btv->i2c_rc)
385 return;
386 btv->i2c_client.addr = addr >> 1;
387 tveeprom_read(&btv->i2c_client, eedata, 256);
388}
389
390static char *i2c_devs[128] = {
391 [ 0x1c >> 1 ] = "lgdt330x",
392 [ 0x30 >> 1 ] = "IR (hauppauge)",
393 [ 0x80 >> 1 ] = "msp34xx",
394 [ 0x86 >> 1 ] = "tda9887",
395 [ 0xa0 >> 1 ] = "eeprom",
396 [ 0xc0 >> 1 ] = "tuner (analog)",
397 [ 0xc2 >> 1 ] = "tuner (analog)",
398};
399
400static void do_i2c_scan(char *name, struct i2c_client *c)
401{
402 unsigned char buf;
403 int i,rc;
404
405 for (i = 0; i < 128; i++) {
406 c->addr = i;
407 rc = i2c_master_recv(c,&buf,0);
408 if (rc < 0)
409 continue;
410 printk("%s: i2c scan: found device @ 0x%x [%s]\n",
411 name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
412 }
413}
414
415/* init + register i2c algo-bit adapter */
416int __devinit init_bttv_i2c(struct bttv *btv)
417{
418 memcpy(&btv->i2c_client, &bttv_i2c_client_template,
419 sizeof(bttv_i2c_client_template));
420
421 if (i2c_hw)
422 btv->use_i2c_hw = 1;
423 if (btv->use_i2c_hw) {
424 /* bt878 */
425 memcpy(&btv->c.i2c_adap, &bttv_i2c_adap_hw_template,
426 sizeof(bttv_i2c_adap_hw_template));
427 } else {
428 /* bt848 */
429 memcpy(&btv->c.i2c_adap, &bttv_i2c_adap_sw_template,
430 sizeof(bttv_i2c_adap_sw_template));
431 memcpy(&btv->i2c_algo, &bttv_i2c_algo_bit_template,
432 sizeof(bttv_i2c_algo_bit_template));
433 btv->i2c_algo.data = btv;
434 btv->c.i2c_adap.algo_data = &btv->i2c_algo;
435 }
436
437 btv->c.i2c_adap.dev.parent = &btv->c.pci->dev;
438 snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name),
439 "bt%d #%d [%s]", btv->id, btv->c.nr,
440 btv->use_i2c_hw ? "hw" : "sw");
441
442 i2c_set_adapdata(&btv->c.i2c_adap, btv);
443 btv->i2c_client.adapter = &btv->c.i2c_adap;
444
445 if (bttv_tvcards[btv->c.type].no_video)
446 btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG;
447 if (bttv_tvcards[btv->c.type].has_dvb)
448 btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
449
450 if (btv->use_i2c_hw) {
451 btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap);
452 } else {
453 bttv_bit_setscl(btv,1);
454 bttv_bit_setsda(btv,1);
455 btv->i2c_rc = i2c_bit_add_bus(&btv->c.i2c_adap);
456 }
457 if (0 == btv->i2c_rc && i2c_scan)
458 do_i2c_scan(btv->c.name,&btv->i2c_client);
459 return btv->i2c_rc;
460}
461
462int __devexit fini_bttv_i2c(struct bttv *btv)
463{
464 if (0 != btv->i2c_rc)
465 return 0;
466
467 if (btv->use_i2c_hw) {
468 return i2c_del_adapter(&btv->c.i2c_adap);
469 } else {
470 return i2c_bit_del_bus(&btv->c.i2c_adap);
471 }
472}
473
474/*
475 * Local variables:
476 * c-basic-offset: 8
477 * End:
478 */
diff --git a/drivers/media/video/bt8xx/bttv-if.c b/drivers/media/video/bt8xx/bttv-if.c
new file mode 100644
index 000000000000..19b564ab0e92
--- /dev/null
+++ b/drivers/media/video/bt8xx/bttv-if.c
@@ -0,0 +1,159 @@
1/*
2
3 bttv-if.c -- old gpio interface to other kernel modules
4 don't use in new code, will go away in 2.7
5 have a look at bttv-gpio.c instead.
6
7 bttv - Bt848 frame grabber driver
8
9 Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de)
10 & Marcus Metzler (mocm@thp.uni-koeln.de)
11 (c) 1999-2003 Gerd Knorr <kraxel@bytesex.org>
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
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26
27*/
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/delay.h>
32#include <asm/io.h>
33
34#include "bttvp.h"
35
36EXPORT_SYMBOL(bttv_get_cardinfo);
37EXPORT_SYMBOL(bttv_get_pcidev);
38EXPORT_SYMBOL(bttv_get_id);
39EXPORT_SYMBOL(bttv_gpio_enable);
40EXPORT_SYMBOL(bttv_read_gpio);
41EXPORT_SYMBOL(bttv_write_gpio);
42EXPORT_SYMBOL(bttv_get_gpio_queue);
43EXPORT_SYMBOL(bttv_i2c_call);
44
45/* ----------------------------------------------------------------------- */
46/* Exported functions - for other modules which want to access the */
47/* gpio ports (IR for example) */
48/* see bttv.h for comments */
49
50int bttv_get_cardinfo(unsigned int card, int *type, unsigned *cardid)
51{
52 printk("The bttv_* interface is obsolete and will go away,\n"
53 "please use the new, sysfs based interface instead.\n");
54 if (card >= bttv_num) {
55 return -1;
56 }
57 *type = bttvs[card].c.type;
58 *cardid = bttvs[card].cardid;
59 return 0;
60}
61
62struct pci_dev* bttv_get_pcidev(unsigned int card)
63{
64 if (card >= bttv_num)
65 return NULL;
66 return bttvs[card].c.pci;
67}
68
69int bttv_get_id(unsigned int card)
70{
71 printk("The bttv_* interface is obsolete and will go away,\n"
72 "please use the new, sysfs based interface instead.\n");
73 if (card >= bttv_num) {
74 return -1;
75 }
76 return bttvs[card].c.type;
77}
78
79
80int bttv_gpio_enable(unsigned int card, unsigned long mask, unsigned long data)
81{
82 struct bttv *btv;
83
84 if (card >= bttv_num) {
85 return -EINVAL;
86 }
87
88 btv = &bttvs[card];
89 gpio_inout(mask,data);
90 if (bttv_gpio)
91 bttv_gpio_tracking(btv,"extern enable");
92 return 0;
93}
94
95int bttv_read_gpio(unsigned int card, unsigned long *data)
96{
97 struct bttv *btv;
98
99 if (card >= bttv_num) {
100 return -EINVAL;
101 }
102
103 btv = &bttvs[card];
104
105 if(btv->shutdown) {
106 return -ENODEV;
107 }
108
109/* prior setting BT848_GPIO_REG_INP is (probably) not needed
110 because we set direct input on init */
111 *data = gpio_read();
112 return 0;
113}
114
115int bttv_write_gpio(unsigned int card, unsigned long mask, unsigned long data)
116{
117 struct bttv *btv;
118
119 if (card >= bttv_num) {
120 return -EINVAL;
121 }
122
123 btv = &bttvs[card];
124
125/* prior setting BT848_GPIO_REG_INP is (probably) not needed
126 because direct input is set on init */
127 gpio_bits(mask,data);
128 if (bttv_gpio)
129 bttv_gpio_tracking(btv,"extern write");
130 return 0;
131}
132
133wait_queue_head_t* bttv_get_gpio_queue(unsigned int card)
134{
135 struct bttv *btv;
136
137 if (card >= bttv_num) {
138 return NULL;
139 }
140
141 btv = &bttvs[card];
142 if (bttvs[card].shutdown) {
143 return NULL;
144 }
145 return &btv->gpioq;
146}
147
148void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg)
149{
150 if (card >= bttv_num)
151 return;
152 bttv_call_i2c_clients(&bttvs[card], cmd, arg);
153}
154
155/*
156 * Local variables:
157 * c-basic-offset: 8
158 * End:
159 */
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
new file mode 100644
index 000000000000..69efa0e5174d
--- /dev/null
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -0,0 +1,450 @@
1/*
2 *
3 * Copyright (c) 2003 Gerd Knorr
4 * Copyright (c) 2003 Pavel Machek
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/module.h>
22#include <linux/moduleparam.h>
23#include <linux/init.h>
24#include <linux/delay.h>
25#include <linux/interrupt.h>
26#include <linux/input.h>
27
28#include "bttv.h"
29#include "bttvp.h"
30
31
32static int debug;
33module_param(debug, int, 0644); /* debug level (0,1,2) */
34static int repeat_delay = 500;
35module_param(repeat_delay, int, 0644);
36static int repeat_period = 33;
37module_param(repeat_period, int, 0644);
38
39#define DEVNAME "bttv-input"
40
41/* ---------------------------------------------------------------------- */
42
43static void ir_handle_key(struct bttv *btv)
44{
45 struct bttv_ir *ir = btv->remote;
46 u32 gpio,data;
47
48 /* read gpio value */
49 gpio = bttv_gpio_read(&btv->c);
50 if (ir->polling) {
51 if (ir->last_gpio == gpio)
52 return;
53 ir->last_gpio = gpio;
54 }
55
56 /* extract data */
57 data = ir_extract_bits(gpio, ir->mask_keycode);
58 dprintk(KERN_INFO DEVNAME ": irq gpio=0x%x code=%d | %s%s%s\n",
59 gpio, data,
60 ir->polling ? "poll" : "irq",
61 (gpio & ir->mask_keydown) ? " down" : "",
62 (gpio & ir->mask_keyup) ? " up" : "");
63
64 if ((ir->mask_keydown && (0 != (gpio & ir->mask_keydown))) ||
65 (ir->mask_keyup && (0 == (gpio & ir->mask_keyup)))) {
66 ir_input_keydown(ir->dev,&ir->ir,data,data);
67 } else {
68 ir_input_nokey(ir->dev,&ir->ir);
69 }
70
71}
72
73void bttv_input_irq(struct bttv *btv)
74{
75 struct bttv_ir *ir = btv->remote;
76
77 if (!ir->polling)
78 ir_handle_key(btv);
79}
80
81static void bttv_input_timer(unsigned long data)
82{
83 struct bttv *btv = (struct bttv*)data;
84 struct bttv_ir *ir = btv->remote;
85 unsigned long timeout;
86
87 ir_handle_key(btv);
88 timeout = jiffies + (ir->polling * HZ / 1000);
89 mod_timer(&ir->timer, timeout);
90}
91
92/* ---------------------------------------------------------------*/
93
94static int rc5_remote_gap = 885;
95module_param(rc5_remote_gap, int, 0644);
96static int rc5_key_timeout = 200;
97module_param(rc5_key_timeout, int, 0644);
98
99#define RC5_START(x) (((x)>>12)&3)
100#define RC5_TOGGLE(x) (((x)>>11)&1)
101#define RC5_ADDR(x) (((x)>>6)&31)
102#define RC5_INSTR(x) ((x)&63)
103
104/* decode raw bit pattern to RC5 code */
105static u32 rc5_decode(unsigned int code)
106{
107 unsigned int org_code = code;
108 unsigned int pair;
109 unsigned int rc5 = 0;
110 int i;
111
112 code = (code << 1) | 1;
113 for (i = 0; i < 14; ++i) {
114 pair = code & 0x3;
115 code >>= 2;
116
117 rc5 <<= 1;
118 switch (pair) {
119 case 0:
120 case 2:
121 break;
122 case 1:
123 rc5 |= 1;
124 break;
125 case 3:
126 dprintk(KERN_WARNING "bad code: %x\n", org_code);
127 return 0;
128 }
129 }
130 dprintk(KERN_WARNING "code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
131 "instr=%x\n", rc5, org_code, RC5_START(rc5),
132 RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
133 return rc5;
134}
135
136static int bttv_rc5_irq(struct bttv *btv)
137{
138 struct bttv_ir *ir = btv->remote;
139 struct timeval tv;
140 u32 gpio;
141 u32 gap;
142 unsigned long current_jiffies, timeout;
143
144 /* read gpio port */
145 gpio = bttv_gpio_read(&btv->c);
146
147 /* remote IRQ? */
148 if (!(gpio & 0x20))
149 return 0;
150
151 /* get time of bit */
152 current_jiffies = jiffies;
153 do_gettimeofday(&tv);
154
155 /* avoid overflow with gap >1s */
156 if (tv.tv_sec - ir->base_time.tv_sec > 1) {
157 gap = 200000;
158 } else {
159 gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
160 tv.tv_usec - ir->base_time.tv_usec;
161 }
162
163 /* active code => add bit */
164 if (ir->active) {
165 /* only if in the code (otherwise spurious IRQ or timer
166 late) */
167 if (ir->last_bit < 28) {
168 ir->last_bit = (gap - rc5_remote_gap / 2) /
169 rc5_remote_gap;
170 ir->code |= 1 << ir->last_bit;
171 }
172 /* starting new code */
173 } else {
174 ir->active = 1;
175 ir->code = 0;
176 ir->base_time = tv;
177 ir->last_bit = 0;
178
179 timeout = current_jiffies + (500 + 30 * HZ) / 1000;
180 mod_timer(&ir->timer_end, timeout);
181 }
182
183 /* toggle GPIO pin 4 to reset the irq */
184 bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
185 bttv_gpio_write(&btv->c, gpio | (1 << 4));
186 return 1;
187}
188
189
190static void bttv_rc5_timer_end(unsigned long data)
191{
192 struct bttv_ir *ir = (struct bttv_ir *)data;
193 struct timeval tv;
194 unsigned long current_jiffies, timeout;
195 u32 gap;
196
197 /* get time */
198 current_jiffies = jiffies;
199 do_gettimeofday(&tv);
200
201 /* avoid overflow with gap >1s */
202 if (tv.tv_sec - ir->base_time.tv_sec > 1) {
203 gap = 200000;
204 } else {
205 gap = 1000000 * (tv.tv_sec - ir->base_time.tv_sec) +
206 tv.tv_usec - ir->base_time.tv_usec;
207 }
208
209 /* Allow some timmer jitter (RC5 is ~24ms anyway so this is ok) */
210 if (gap < 28000) {
211 dprintk(KERN_WARNING "spurious timer_end\n");
212 return;
213 }
214
215 ir->active = 0;
216 if (ir->last_bit < 20) {
217 /* ignore spurious codes (caused by light/other remotes) */
218 dprintk(KERN_WARNING "short code: %x\n", ir->code);
219 } else {
220 u32 rc5 = rc5_decode(ir->code);
221
222 /* two start bits? */
223 if (RC5_START(rc5) != 3) {
224 dprintk(KERN_WARNING "rc5 start bits invalid: %u\n", RC5_START(rc5));
225
226 /* right address? */
227 } else if (RC5_ADDR(rc5) == 0x0) {
228 u32 toggle = RC5_TOGGLE(rc5);
229 u32 instr = RC5_INSTR(rc5);
230
231 /* Good code, decide if repeat/repress */
232 if (toggle != RC5_TOGGLE(ir->last_rc5) ||
233 instr != RC5_INSTR(ir->last_rc5)) {
234 dprintk(KERN_WARNING "instruction %x, toggle %x\n", instr,
235 toggle);
236 ir_input_nokey(ir->dev, &ir->ir);
237 ir_input_keydown(ir->dev, &ir->ir, instr,
238 instr);
239 }
240
241 /* Set/reset key-up timer */
242 timeout = current_jiffies + (500 + rc5_key_timeout
243 * HZ) / 1000;
244 mod_timer(&ir->timer_keyup, timeout);
245
246 /* Save code for repeat test */
247 ir->last_rc5 = rc5;
248 }
249 }
250}
251
252static void bttv_rc5_timer_keyup(unsigned long data)
253{
254 struct bttv_ir *ir = (struct bttv_ir *)data;
255
256 dprintk(KERN_DEBUG "key released\n");
257 ir_input_nokey(ir->dev, &ir->ir);
258}
259
260/* ---------------------------------------------------------------------- */
261
262int bttv_input_init(struct bttv *btv)
263{
264 struct bttv_ir *ir;
265 IR_KEYTAB_TYPE *ir_codes = NULL;
266 struct input_dev *input_dev;
267 int ir_type = IR_TYPE_OTHER;
268
269 if (!btv->has_remote)
270 return -ENODEV;
271
272 ir = kzalloc(sizeof(*ir),GFP_KERNEL);
273 input_dev = input_allocate_device();
274 if (!ir || !input_dev) {
275 kfree(ir);
276 input_free_device(input_dev);
277 return -ENOMEM;
278 }
279 memset(ir,0,sizeof(*ir));
280
281 /* detect & configure */
282 switch (btv->c.type) {
283 case BTTV_BOARD_AVERMEDIA:
284 case BTTV_BOARD_AVPHONE98:
285 case BTTV_BOARD_AVERMEDIA98:
286 ir_codes = ir_codes_avermedia;
287 ir->mask_keycode = 0xf88000;
288 ir->mask_keydown = 0x010000;
289 ir->polling = 50; // ms
290 break;
291
292 case BTTV_BOARD_AVDVBT_761:
293 case BTTV_BOARD_AVDVBT_771:
294 ir_codes = ir_codes_avermedia_dvbt;
295 ir->mask_keycode = 0x0f00c0;
296 ir->mask_keydown = 0x000020;
297 ir->polling = 50; // ms
298 break;
299
300 case BTTV_BOARD_PXELVWPLTVPAK:
301 ir_codes = ir_codes_pixelview;
302 ir->mask_keycode = 0x003e00;
303 ir->mask_keyup = 0x010000;
304 ir->polling = 50; // ms
305 break;
306 case BTTV_BOARD_PV_BT878P_9B:
307 case BTTV_BOARD_PV_BT878P_PLUS:
308 ir_codes = ir_codes_pixelview;
309 ir->mask_keycode = 0x001f00;
310 ir->mask_keyup = 0x008000;
311 ir->polling = 50; // ms
312 break;
313
314 case BTTV_BOARD_WINFAST2000:
315 ir_codes = ir_codes_winfast;
316 ir->mask_keycode = 0x1f8;
317 break;
318 case BTTV_BOARD_MAGICTVIEW061:
319 case BTTV_BOARD_MAGICTVIEW063:
320 ir_codes = ir_codes_winfast;
321 ir->mask_keycode = 0x0008e000;
322 ir->mask_keydown = 0x00200000;
323 break;
324 case BTTV_BOARD_APAC_VIEWCOMP:
325 ir_codes = ir_codes_apac_viewcomp;
326 ir->mask_keycode = 0x001f00;
327 ir->mask_keyup = 0x008000;
328 ir->polling = 50; // ms
329 break;
330 case BTTV_BOARD_CONCEPTRONIC_CTVFMI2:
331 case BTTV_BOARD_CONTVFMI:
332 ir_codes = ir_codes_pixelview;
333 ir->mask_keycode = 0x001F00;
334 ir->mask_keyup = 0x006000;
335 ir->polling = 50; // ms
336 break;
337 case BTTV_BOARD_NEBULA_DIGITV:
338 ir_codes = ir_codes_nebula;
339 btv->custom_irq = bttv_rc5_irq;
340 ir->rc5_gpio = 1;
341 break;
342 case BTTV_BOARD_MACHTV_MAGICTV:
343 ir_codes = ir_codes_apac_viewcomp;
344 ir->mask_keycode = 0x001F00;
345 ir->mask_keyup = 0x004000;
346 ir->polling = 50; /* ms */
347 break;
348 }
349 if (NULL == ir_codes) {
350 dprintk(KERN_INFO "Ooops: IR config error [card=%d]\n",btv->c.type);
351 kfree(ir);
352 input_free_device(input_dev);
353 return -ENODEV;
354 }
355
356 if (ir->rc5_gpio) {
357 u32 gpio;
358 /* enable remote irq */
359 bttv_gpio_inout(&btv->c, (1 << 4), 1 << 4);
360 gpio = bttv_gpio_read(&btv->c);
361 bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
362 bttv_gpio_write(&btv->c, gpio | (1 << 4));
363 } else {
364 /* init hardware-specific stuff */
365 bttv_gpio_inout(&btv->c, ir->mask_keycode | ir->mask_keydown, 0);
366 }
367
368 /* init input device */
369 ir->dev = input_dev;
370
371 snprintf(ir->name, sizeof(ir->name), "bttv IR (card=%d)",
372 btv->c.type);
373 snprintf(ir->phys, sizeof(ir->phys), "pci-%s/ir0",
374 pci_name(btv->c.pci));
375
376 ir_input_init(input_dev, &ir->ir, ir_type, ir_codes);
377 input_dev->name = ir->name;
378 input_dev->phys = ir->phys;
379 input_dev->id.bustype = BUS_PCI;
380 input_dev->id.version = 1;
381 if (btv->c.pci->subsystem_vendor) {
382 input_dev->id.vendor = btv->c.pci->subsystem_vendor;
383 input_dev->id.product = btv->c.pci->subsystem_device;
384 } else {
385 input_dev->id.vendor = btv->c.pci->vendor;
386 input_dev->id.product = btv->c.pci->device;
387 }
388 input_dev->cdev.dev = &btv->c.pci->dev;
389
390 btv->remote = ir;
391 if (ir->polling) {
392 init_timer(&ir->timer);
393 ir->timer.function = bttv_input_timer;
394 ir->timer.data = (unsigned long)btv;
395 ir->timer.expires = jiffies + HZ;
396 add_timer(&ir->timer);
397 } else if (ir->rc5_gpio) {
398 /* set timer_end for code completion */
399 init_timer(&ir->timer_end);
400 ir->timer_end.function = bttv_rc5_timer_end;
401 ir->timer_end.data = (unsigned long)ir;
402
403 init_timer(&ir->timer_keyup);
404 ir->timer_keyup.function = bttv_rc5_timer_keyup;
405 ir->timer_keyup.data = (unsigned long)ir;
406 }
407
408 /* all done */
409 input_register_device(btv->remote->dev);
410 printk(DEVNAME ": %s detected at %s\n",ir->name,ir->phys);
411
412 /* the remote isn't as bouncy as a keyboard */
413 ir->dev->rep[REP_DELAY] = repeat_delay;
414 ir->dev->rep[REP_PERIOD] = repeat_period;
415
416 return 0;
417}
418
419void bttv_input_fini(struct bttv *btv)
420{
421 if (btv->remote == NULL)
422 return;
423
424 if (btv->remote->polling) {
425 del_timer_sync(&btv->remote->timer);
426 flush_scheduled_work();
427 }
428
429
430 if (btv->remote->rc5_gpio) {
431 u32 gpio;
432
433 del_timer_sync(&btv->remote->timer_end);
434 flush_scheduled_work();
435
436 gpio = bttv_gpio_read(&btv->c);
437 bttv_gpio_write(&btv->c, gpio & ~(1 << 4));
438 }
439
440 input_unregister_device(btv->remote->dev);
441 kfree(btv->remote);
442 btv->remote = NULL;
443}
444
445
446/*
447 * Local variables:
448 * c-basic-offset: 8
449 * End:
450 */
diff --git a/drivers/media/video/bt8xx/bttv-risc.c b/drivers/media/video/bt8xx/bttv-risc.c
new file mode 100644
index 000000000000..16323a5d68ac
--- /dev/null
+++ b/drivers/media/video/bt8xx/bttv-risc.c
@@ -0,0 +1,795 @@
1/*
2
3 bttv-risc.c -- interfaces to other kernel modules
4
5 bttv risc code handling
6 - memory management
7 - generation
8
9 (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
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
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25*/
26
27#include <linux/module.h>
28#include <linux/init.h>
29#include <linux/pci.h>
30#include <linux/vmalloc.h>
31#include <linux/interrupt.h>
32#include <asm/page.h>
33#include <asm/pgtable.h>
34
35#include "bttvp.h"
36
37#define VCR_HACK_LINES 4
38
39/* ---------------------------------------------------------- */
40/* risc code generators */
41
42int
43bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
44 struct scatterlist *sglist,
45 unsigned int offset, unsigned int bpl,
46 unsigned int padding, unsigned int lines)
47{
48 u32 instructions,line,todo;
49 struct scatterlist *sg;
50 u32 *rp;
51 int rc;
52
53 /* estimate risc mem: worst case is one write per page border +
54 one write per scan line + sync + jump (all 2 dwords). padding
55 can cause next bpl to start close to a page border. First DMA
56 region may be smaller than PAGE_SIZE */
57 instructions = 1 + ((bpl + padding) * lines) / PAGE_SIZE + lines;
58 instructions += 2;
59 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0)
60 return rc;
61
62 /* sync instruction */
63 rp = risc->cpu;
64 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
65 *(rp++) = cpu_to_le32(0);
66
67 /* scan lines */
68 sg = sglist;
69 for (line = 0; line < lines; line++) {
70 if ((btv->opt_vcr_hack) &&
71 (line >= (lines - VCR_HACK_LINES)))
72 continue;
73 while (offset && offset >= sg_dma_len(sg)) {
74 offset -= sg_dma_len(sg);
75 sg++;
76 }
77 if (bpl <= sg_dma_len(sg)-offset) {
78 /* fits into current chunk */
79 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
80 BT848_RISC_EOL|bpl);
81 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
82 offset+=bpl;
83 } else {
84 /* scanline needs to be splitted */
85 todo = bpl;
86 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
87 (sg_dma_len(sg)-offset));
88 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
89 todo -= (sg_dma_len(sg)-offset);
90 offset = 0;
91 sg++;
92 while (todo > sg_dma_len(sg)) {
93 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
94 sg_dma_len(sg));
95 *(rp++)=cpu_to_le32(sg_dma_address(sg));
96 todo -= sg_dma_len(sg);
97 sg++;
98 }
99 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
100 todo);
101 *(rp++)=cpu_to_le32(sg_dma_address(sg));
102 offset += todo;
103 }
104 offset += padding;
105 }
106
107 /* save pointer to jmp instruction address */
108 risc->jmp = rp;
109 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
110 return 0;
111}
112
113static int
114bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
115 struct scatterlist *sglist,
116 unsigned int yoffset, unsigned int ybpl,
117 unsigned int ypadding, unsigned int ylines,
118 unsigned int uoffset, unsigned int voffset,
119 unsigned int hshift, unsigned int vshift,
120 unsigned int cpadding)
121{
122 unsigned int instructions,line,todo,ylen,chroma;
123 u32 *rp,ri;
124 struct scatterlist *ysg;
125 struct scatterlist *usg;
126 struct scatterlist *vsg;
127 int topfield = (0 == yoffset);
128 int rc;
129
130 /* estimate risc mem: worst case is one write per page border +
131 one write per scan line (5 dwords)
132 plus sync + jump (2 dwords) */
133 instructions = (ybpl * ylines * 2) / PAGE_SIZE + ylines;
134 instructions += 2;
135 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
136 return rc;
137
138 /* sync instruction */
139 rp = risc->cpu;
140 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
141 *(rp++) = cpu_to_le32(0);
142
143 /* scan lines */
144 ysg = sglist;
145 usg = sglist;
146 vsg = sglist;
147 for (line = 0; line < ylines; line++) {
148 if ((btv->opt_vcr_hack) &&
149 (line >= (ylines - VCR_HACK_LINES)))
150 continue;
151 switch (vshift) {
152 case 0:
153 chroma = 1;
154 break;
155 case 1:
156 if (topfield)
157 chroma = ((line & 1) == 0);
158 else
159 chroma = ((line & 1) == 1);
160 break;
161 case 2:
162 if (topfield)
163 chroma = ((line & 3) == 0);
164 else
165 chroma = ((line & 3) == 2);
166 break;
167 default:
168 chroma = 0;
169 break;
170 }
171
172 for (todo = ybpl; todo > 0; todo -= ylen) {
173 /* go to next sg entry if needed */
174 while (yoffset && yoffset >= sg_dma_len(ysg)) {
175 yoffset -= sg_dma_len(ysg);
176 ysg++;
177 }
178 while (uoffset && uoffset >= sg_dma_len(usg)) {
179 uoffset -= sg_dma_len(usg);
180 usg++;
181 }
182 while (voffset && voffset >= sg_dma_len(vsg)) {
183 voffset -= sg_dma_len(vsg);
184 vsg++;
185 }
186
187 /* calculate max number of bytes we can write */
188 ylen = todo;
189 if (yoffset + ylen > sg_dma_len(ysg))
190 ylen = sg_dma_len(ysg) - yoffset;
191 if (chroma) {
192 if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
193 ylen = (sg_dma_len(usg) - uoffset) << hshift;
194 if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
195 ylen = (sg_dma_len(vsg) - voffset) << hshift;
196 ri = BT848_RISC_WRITE123;
197 } else {
198 ri = BT848_RISC_WRITE1S23;
199 }
200 if (ybpl == todo)
201 ri |= BT848_RISC_SOL;
202 if (ylen == todo)
203 ri |= BT848_RISC_EOL;
204
205 /* write risc instruction */
206 *(rp++)=cpu_to_le32(ri | ylen);
207 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
208 (ylen >> hshift));
209 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
210 yoffset += ylen;
211 if (chroma) {
212 *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
213 uoffset += ylen >> hshift;
214 *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
215 voffset += ylen >> hshift;
216 }
217 }
218 yoffset += ypadding;
219 if (chroma) {
220 uoffset += cpadding;
221 voffset += cpadding;
222 }
223 }
224
225 /* save pointer to jmp instruction address */
226 risc->jmp = rp;
227 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
228 return 0;
229}
230
231static int
232bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
233 const struct bttv_format *fmt, struct bttv_overlay *ov,
234 int skip_even, int skip_odd)
235{
236 int instructions,rc,line,maxy,start,end,skip,nskips;
237 struct btcx_skiplist *skips;
238 u32 *rp,ri,ra;
239 u32 addr;
240
241 /* skip list for window clipping */
242 if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
243 return -ENOMEM;
244
245 /* estimate risc mem: worst case is (clip+1) * lines instructions
246 + sync + jump (all 2 dwords) */
247 instructions = (ov->nclips + 1) *
248 ((skip_even || skip_odd) ? ov->w.height>>1 : ov->w.height);
249 instructions += 2;
250 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0) {
251 kfree(skips);
252 return rc;
253 }
254
255 /* sync instruction */
256 rp = risc->cpu;
257 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
258 *(rp++) = cpu_to_le32(0);
259
260 addr = (unsigned long)btv->fbuf.base;
261 addr += btv->fbuf.fmt.bytesperline * ov->w.top;
262 addr += (fmt->depth >> 3) * ov->w.left;
263
264 /* scan lines */
265 for (maxy = -1, line = 0; line < ov->w.height;
266 line++, addr += btv->fbuf.fmt.bytesperline) {
267 if ((btv->opt_vcr_hack) &&
268 (line >= (ov->w.height - VCR_HACK_LINES)))
269 continue;
270 if ((line%2) == 0 && skip_even)
271 continue;
272 if ((line%2) == 1 && skip_odd)
273 continue;
274
275 /* calculate clipping */
276 if (line > maxy)
277 btcx_calc_skips(line, ov->w.width, &maxy,
278 skips, &nskips, ov->clips, ov->nclips);
279 else
280 nskips = 0;
281
282 /* write out risc code */
283 for (start = 0, skip = 0; start < ov->w.width; start = end) {
284 if (skip >= nskips) {
285 ri = BT848_RISC_WRITE;
286 end = ov->w.width;
287 } else if (start < skips[skip].start) {
288 ri = BT848_RISC_WRITE;
289 end = skips[skip].start;
290 } else {
291 ri = BT848_RISC_SKIP;
292 end = skips[skip].end;
293 skip++;
294 }
295 if (BT848_RISC_WRITE == ri)
296 ra = addr + (fmt->depth>>3)*start;
297 else
298 ra = 0;
299
300 if (0 == start)
301 ri |= BT848_RISC_SOL;
302 if (ov->w.width == end)
303 ri |= BT848_RISC_EOL;
304 ri |= (fmt->depth>>3) * (end-start);
305
306 *(rp++)=cpu_to_le32(ri);
307 if (0 != ra)
308 *(rp++)=cpu_to_le32(ra);
309 }
310 }
311
312 /* save pointer to jmp instruction address */
313 risc->jmp = rp;
314 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
315 kfree(skips);
316 return 0;
317}
318
319/* ---------------------------------------------------------- */
320
321static void
322bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
323 int width, int height, int interleaved, int norm)
324{
325 const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm];
326 u32 xsf, sr;
327 int vdelay;
328
329 int swidth = tvnorm->swidth;
330 int totalwidth = tvnorm->totalwidth;
331 int scaledtwidth = tvnorm->scaledtwidth;
332
333 if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
334 swidth = 720;
335 totalwidth = 858;
336 scaledtwidth = 858;
337 }
338
339 vdelay = tvnorm->vdelay;
340
341 xsf = (width*scaledtwidth)/swidth;
342 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
343 geo->hdelay = tvnorm->hdelayx1;
344 geo->hdelay = (geo->hdelay*width)/swidth;
345 geo->hdelay &= 0x3fe;
346 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
347 geo->vscale = (0x10000UL-sr) & 0x1fff;
348 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
349 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
350 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
351 geo->vdelay = vdelay;
352 geo->width = width;
353 geo->sheight = tvnorm->sheight;
354 geo->vtotal = tvnorm->vtotal;
355
356 if (btv->opt_combfilter) {
357 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
358 geo->comb = (width < 769) ? 1 : 0;
359 } else {
360 geo->vtc = 0;
361 geo->comb = 0;
362 }
363}
364
365static void
366bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
367{
368 int off = odd ? 0x80 : 0x00;
369
370 if (geo->comb)
371 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
372 else
373 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
374
375 btwrite(geo->vtc, BT848_E_VTC+off);
376 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
377 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
378 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
379 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
380 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
381 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
382 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
383 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
384 btwrite(geo->crop, BT848_E_CROP+off);
385 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
386 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
387}
388
389/* ---------------------------------------------------------- */
390/* risc group / risc main loop / dma management */
391
392void
393bttv_set_dma(struct bttv *btv, int override)
394{
395 unsigned long cmd;
396 int capctl;
397
398 btv->cap_ctl = 0;
399 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
400 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
401 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
402
403 capctl = 0;
404 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
405 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
406 capctl |= override;
407
408 d2printk(KERN_DEBUG
409 "bttv%d: capctl=%x lirq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
410 btv->c.nr,capctl,btv->loop_irq,
411 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
412 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
413 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
414 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
415
416 cmd = BT848_RISC_JUMP;
417 if (btv->loop_irq) {
418 cmd |= BT848_RISC_IRQ;
419 cmd |= (btv->loop_irq & 0x0f) << 16;
420 cmd |= (~btv->loop_irq & 0x0f) << 20;
421 }
422 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
423 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
424 } else {
425 del_timer(&btv->timeout);
426 }
427 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
428
429 btaor(capctl, ~0x0f, BT848_CAP_CTL);
430 if (capctl) {
431 if (btv->dma_on)
432 return;
433 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
434 btor(3, BT848_GPIO_DMA_CTL);
435 btv->dma_on = 1;
436 } else {
437 if (!btv->dma_on)
438 return;
439 btand(~3, BT848_GPIO_DMA_CTL);
440 btv->dma_on = 0;
441 }
442 return;
443}
444
445int
446bttv_risc_init_main(struct bttv *btv)
447{
448 int rc;
449
450 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
451 return rc;
452 dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
453 btv->c.nr,(unsigned long long)btv->main.dma);
454
455 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
456 BT848_FIFO_STATUS_VRE);
457 btv->main.cpu[1] = cpu_to_le32(0);
458 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
459 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
460
461 /* top field */
462 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
463 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
464 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
465 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
466
467 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
468 BT848_FIFO_STATUS_VRO);
469 btv->main.cpu[9] = cpu_to_le32(0);
470
471 /* bottom field */
472 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
473 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
474 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
475 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
476
477 /* jump back to top field */
478 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
479 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
480
481 return 0;
482}
483
484int
485bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
486 int irqflags)
487{
488 unsigned long cmd;
489 unsigned long next = btv->main.dma + ((slot+2) << 2);
490
491 if (NULL == risc) {
492 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n",
493 btv->c.nr,risc,slot);
494 btv->main.cpu[slot+1] = cpu_to_le32(next);
495 } else {
496 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
497 btv->c.nr,risc,slot,(unsigned long long)risc->dma,irqflags);
498 cmd = BT848_RISC_JUMP;
499 if (irqflags) {
500 cmd |= BT848_RISC_IRQ;
501 cmd |= (irqflags & 0x0f) << 16;
502 cmd |= (~irqflags & 0x0f) << 20;
503 }
504 risc->jmp[0] = cpu_to_le32(cmd);
505 risc->jmp[1] = cpu_to_le32(next);
506 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
507 }
508 return 0;
509}
510
511void
512bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
513{
514 BUG_ON(in_interrupt());
515 videobuf_waiton(&buf->vb,0,0);
516 videobuf_dma_unmap(q, &buf->vb.dma);
517 videobuf_dma_free(&buf->vb.dma);
518 btcx_riscmem_free(btv->c.pci,&buf->bottom);
519 btcx_riscmem_free(btv->c.pci,&buf->top);
520 buf->vb.state = STATE_NEEDS_INIT;
521}
522
523int
524bttv_buffer_activate_vbi(struct bttv *btv,
525 struct bttv_buffer *vbi)
526{
527 /* vbi capture */
528 if (vbi) {
529 vbi->vb.state = STATE_ACTIVE;
530 list_del(&vbi->vb.queue);
531 bttv_risc_hook(btv, RISC_SLOT_O_VBI, &vbi->top, 0);
532 bttv_risc_hook(btv, RISC_SLOT_E_VBI, &vbi->bottom, 4);
533 } else {
534 bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0);
535 bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0);
536 }
537 return 0;
538}
539
540int
541bttv_buffer_activate_video(struct bttv *btv,
542 struct bttv_buffer_set *set)
543{
544 /* video capture */
545 if (NULL != set->top && NULL != set->bottom) {
546 if (set->top == set->bottom) {
547 set->top->vb.state = STATE_ACTIVE;
548 if (set->top->vb.queue.next)
549 list_del(&set->top->vb.queue);
550 } else {
551 set->top->vb.state = STATE_ACTIVE;
552 set->bottom->vb.state = STATE_ACTIVE;
553 if (set->top->vb.queue.next)
554 list_del(&set->top->vb.queue);
555 if (set->bottom->vb.queue.next)
556 list_del(&set->bottom->vb.queue);
557 }
558 bttv_apply_geo(btv, &set->top->geo, 1);
559 bttv_apply_geo(btv, &set->bottom->geo,0);
560 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
561 set->top_irq);
562 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
563 set->frame_irq);
564 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
565 ~0xff, BT848_COLOR_FMT);
566 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
567 ~0x0f, BT848_COLOR_CTL);
568 } else if (NULL != set->top) {
569 set->top->vb.state = STATE_ACTIVE;
570 if (set->top->vb.queue.next)
571 list_del(&set->top->vb.queue);
572 bttv_apply_geo(btv, &set->top->geo,1);
573 bttv_apply_geo(btv, &set->top->geo,0);
574 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
575 set->frame_irq);
576 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
577 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
578 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
579 } else if (NULL != set->bottom) {
580 set->bottom->vb.state = STATE_ACTIVE;
581 if (set->bottom->vb.queue.next)
582 list_del(&set->bottom->vb.queue);
583 bttv_apply_geo(btv, &set->bottom->geo,1);
584 bttv_apply_geo(btv, &set->bottom->geo,0);
585 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
586 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
587 set->frame_irq);
588 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
589 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
590 } else {
591 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
592 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
593 }
594 return 0;
595}
596
597/* ---------------------------------------------------------- */
598
599/* calculate geometry, build risc code */
600int
601bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
602{
603 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
604
605 dprintk(KERN_DEBUG
606 "bttv%d: buffer field: %s format: %s size: %dx%d\n",
607 btv->c.nr, v4l2_field_names[buf->vb.field],
608 buf->fmt->name, buf->vb.width, buf->vb.height);
609
610 /* packed pixel modes */
611 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
612 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
613 int bpf = bpl * (buf->vb.height >> 1);
614
615 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
616 V4L2_FIELD_HAS_BOTH(buf->vb.field),buf->tvnorm);
617
618 switch (buf->vb.field) {
619 case V4L2_FIELD_TOP:
620 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
621 0,bpl,0,buf->vb.height);
622 break;
623 case V4L2_FIELD_BOTTOM:
624 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
625 0,bpl,0,buf->vb.height);
626 break;
627 case V4L2_FIELD_INTERLACED:
628 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
629 0,bpl,bpl,buf->vb.height >> 1);
630 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
631 bpl,bpl,bpl,buf->vb.height >> 1);
632 break;
633 case V4L2_FIELD_SEQ_TB:
634 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
635 0,bpl,0,buf->vb.height >> 1);
636 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
637 bpf,bpl,0,buf->vb.height >> 1);
638 break;
639 default:
640 BUG();
641 }
642 }
643
644 /* planar modes */
645 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
646 int uoffset, voffset;
647 int ypadding, cpadding, lines;
648
649 /* calculate chroma offsets */
650 uoffset = buf->vb.width * buf->vb.height;
651 voffset = buf->vb.width * buf->vb.height;
652 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
653 /* Y-Cr-Cb plane order */
654 uoffset >>= buf->fmt->hshift;
655 uoffset >>= buf->fmt->vshift;
656 uoffset += voffset;
657 } else {
658 /* Y-Cb-Cr plane order */
659 voffset >>= buf->fmt->hshift;
660 voffset >>= buf->fmt->vshift;
661 voffset += uoffset;
662 }
663
664 switch (buf->vb.field) {
665 case V4L2_FIELD_TOP:
666 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
667 buf->vb.height,0,buf->tvnorm);
668 bttv_risc_planar(btv, &buf->top, buf->vb.dma.sglist,
669 0,buf->vb.width,0,buf->vb.height,
670 uoffset,voffset,buf->fmt->hshift,
671 buf->fmt->vshift,0);
672 break;
673 case V4L2_FIELD_BOTTOM:
674 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
675 buf->vb.height,0,buf->tvnorm);
676 bttv_risc_planar(btv, &buf->bottom, buf->vb.dma.sglist,
677 0,buf->vb.width,0,buf->vb.height,
678 uoffset,voffset,buf->fmt->hshift,
679 buf->fmt->vshift,0);
680 break;
681 case V4L2_FIELD_INTERLACED:
682 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
683 buf->vb.height,1,buf->tvnorm);
684 lines = buf->vb.height >> 1;
685 ypadding = buf->vb.width;
686 cpadding = buf->vb.width >> buf->fmt->hshift;
687 bttv_risc_planar(btv,&buf->top,
688 buf->vb.dma.sglist,
689 0,buf->vb.width,ypadding,lines,
690 uoffset,voffset,
691 buf->fmt->hshift,
692 buf->fmt->vshift,
693 cpadding);
694 bttv_risc_planar(btv,&buf->bottom,
695 buf->vb.dma.sglist,
696 ypadding,buf->vb.width,ypadding,lines,
697 uoffset+cpadding,
698 voffset+cpadding,
699 buf->fmt->hshift,
700 buf->fmt->vshift,
701 cpadding);
702 break;
703 case V4L2_FIELD_SEQ_TB:
704 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
705 buf->vb.height,1,buf->tvnorm);
706 lines = buf->vb.height >> 1;
707 ypadding = buf->vb.width;
708 cpadding = buf->vb.width >> buf->fmt->hshift;
709 bttv_risc_planar(btv,&buf->top,
710 buf->vb.dma.sglist,
711 0,buf->vb.width,0,lines,
712 uoffset >> 1,
713 voffset >> 1,
714 buf->fmt->hshift,
715 buf->fmt->vshift,
716 0);
717 bttv_risc_planar(btv,&buf->bottom,
718 buf->vb.dma.sglist,
719 lines * ypadding,buf->vb.width,0,lines,
720 lines * ypadding + (uoffset >> 1),
721 lines * ypadding + (voffset >> 1),
722 buf->fmt->hshift,
723 buf->fmt->vshift,
724 0);
725 break;
726 default:
727 BUG();
728 }
729 }
730
731 /* raw data */
732 if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
733 /* build risc code */
734 buf->vb.field = V4L2_FIELD_SEQ_TB;
735 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
736 1,buf->tvnorm);
737 bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist,
738 0, RAW_BPL, 0, RAW_LINES);
739 bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
740 buf->vb.size/2 , RAW_BPL, 0, RAW_LINES);
741 }
742
743 /* copy format info */
744 buf->btformat = buf->fmt->btformat;
745 buf->btswap = buf->fmt->btswap;
746 return 0;
747}
748
749/* ---------------------------------------------------------- */
750
751/* calculate geometry, build risc code */
752int
753bttv_overlay_risc(struct bttv *btv,
754 struct bttv_overlay *ov,
755 const struct bttv_format *fmt,
756 struct bttv_buffer *buf)
757{
758 /* check interleave, bottom+top fields */
759 dprintk(KERN_DEBUG
760 "bttv%d: overlay fields: %s format: %s size: %dx%d\n",
761 btv->c.nr, v4l2_field_names[buf->vb.field],
762 fmt->name,ov->w.width,ov->w.height);
763
764 /* calculate geometry */
765 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
766 V4L2_FIELD_HAS_BOTH(ov->field), ov->tvnorm);
767
768 /* build risc code */
769 switch (ov->field) {
770 case V4L2_FIELD_TOP:
771 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
772 break;
773 case V4L2_FIELD_BOTTOM:
774 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
775 break;
776 case V4L2_FIELD_INTERLACED:
777 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
778 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
779 break;
780 default:
781 BUG();
782 }
783
784 /* copy format info */
785 buf->btformat = fmt->btformat;
786 buf->btswap = fmt->btswap;
787 buf->vb.field = ov->field;
788 return 0;
789}
790
791/*
792 * Local variables:
793 * c-basic-offset: 8
794 * End:
795 */
diff --git a/drivers/media/video/bt8xx/bttv-vbi.c b/drivers/media/video/bt8xx/bttv-vbi.c
new file mode 100644
index 000000000000..e20ff238e409
--- /dev/null
+++ b/drivers/media/video/bt8xx/bttv-vbi.c
@@ -0,0 +1,221 @@
1/*
2
3 bttv - Bt848 frame grabber driver
4 vbi interface
5
6 (c) 2002 Gerd Knorr <kraxel@bytesex.org>
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21*/
22
23#include <linux/module.h>
24#include <linux/moduleparam.h>
25#include <linux/errno.h>
26#include <linux/fs.h>
27#include <linux/kernel.h>
28#include <linux/sched.h>
29#include <linux/interrupt.h>
30#include <linux/kdev_t.h>
31#include <asm/io.h>
32#include "bttvp.h"
33
34/* Offset from line sync pulse leading edge (0H) in 1 / sampling_rate:
35 bt8x8 /HRESET pulse starts at 0H and has length 64 / fCLKx1 (E|O_VTC
36 HSFMT = 0). VBI_HDELAY (always 0) is an offset from the trailing edge
37 of /HRESET in 1 / fCLKx1, and the sampling_rate tvnorm->Fsc is fCLKx2. */
38#define VBI_OFFSET ((64 + 0) * 2)
39
40#define VBI_DEFLINES 16
41#define VBI_MAXLINES 32
42
43static unsigned int vbibufs = 4;
44static unsigned int vbi_debug = 0;
45
46module_param(vbibufs, int, 0444);
47module_param(vbi_debug, int, 0644);
48MODULE_PARM_DESC(vbibufs,"number of vbi buffers, range 2-32, default 4");
49MODULE_PARM_DESC(vbi_debug,"vbi code debug messages, default is 0 (no)");
50
51#ifdef dprintk
52# undef dprintk
53#endif
54#define dprintk(fmt, arg...) if (vbi_debug) \
55 printk(KERN_DEBUG "bttv%d/vbi: " fmt, btv->c.nr , ## arg)
56
57/* ----------------------------------------------------------------------- */
58/* vbi risc code + mm */
59
60static int
61vbi_buffer_risc(struct bttv *btv, struct bttv_buffer *buf, int lines)
62{
63 int bpl = 2048;
64
65 bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist,
66 0, bpl-4, 4, lines);
67 bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
68 lines * bpl, bpl-4, 4, lines);
69 return 0;
70}
71
72static int vbi_buffer_setup(struct videobuf_queue *q,
73 unsigned int *count, unsigned int *size)
74{
75 struct bttv_fh *fh = q->priv_data;
76 struct bttv *btv = fh->btv;
77
78 if (0 == *count)
79 *count = vbibufs;
80 *size = fh->lines * 2 * 2048;
81 dprintk("setup: lines=%d\n",fh->lines);
82 return 0;
83}
84
85static int vbi_buffer_prepare(struct videobuf_queue *q,
86 struct videobuf_buffer *vb,
87 enum v4l2_field field)
88{
89 struct bttv_fh *fh = q->priv_data;
90 struct bttv *btv = fh->btv;
91 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
92 int rc;
93
94 buf->vb.size = fh->lines * 2 * 2048;
95 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
96 return -EINVAL;
97
98 if (STATE_NEEDS_INIT == buf->vb.state) {
99 if (0 != (rc = videobuf_iolock(q, &buf->vb, NULL)))
100 goto fail;
101 if (0 != (rc = vbi_buffer_risc(btv,buf,fh->lines)))
102 goto fail;
103 }
104 buf->vb.state = STATE_PREPARED;
105 buf->vb.field = field;
106 dprintk("buf prepare %p: top=%p bottom=%p field=%s\n",
107 vb, &buf->top, &buf->bottom,
108 v4l2_field_names[buf->vb.field]);
109 return 0;
110
111 fail:
112 bttv_dma_free(q,btv,buf);
113 return rc;
114}
115
116static void
117vbi_buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
118{
119 struct bttv_fh *fh = q->priv_data;
120 struct bttv *btv = fh->btv;
121 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
122
123 dprintk("queue %p\n",vb);
124 buf->vb.state = STATE_QUEUED;
125 list_add_tail(&buf->vb.queue,&btv->vcapture);
126 if (NULL == btv->cvbi) {
127 fh->btv->loop_irq |= 4;
128 bttv_set_dma(btv,0x0c);
129 }
130}
131
132static void vbi_buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
133{
134 struct bttv_fh *fh = q->priv_data;
135 struct bttv *btv = fh->btv;
136 struct bttv_buffer *buf = container_of(vb,struct bttv_buffer,vb);
137
138 dprintk("free %p\n",vb);
139 bttv_dma_free(&fh->cap,fh->btv,buf);
140}
141
142struct videobuf_queue_ops bttv_vbi_qops = {
143 .buf_setup = vbi_buffer_setup,
144 .buf_prepare = vbi_buffer_prepare,
145 .buf_queue = vbi_buffer_queue,
146 .buf_release = vbi_buffer_release,
147};
148
149/* ----------------------------------------------------------------------- */
150
151void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines)
152{
153 int vdelay;
154
155 if (lines < 1)
156 lines = 1;
157 if (lines > VBI_MAXLINES)
158 lines = VBI_MAXLINES;
159 fh->lines = lines;
160
161 vdelay = btread(BT848_E_VDELAY_LO);
162 if (vdelay < lines*2) {
163 vdelay = lines*2;
164 btwrite(vdelay,BT848_E_VDELAY_LO);
165 btwrite(vdelay,BT848_O_VDELAY_LO);
166 }
167}
168
169void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f)
170{
171 const struct bttv_tvnorm *tvnorm;
172 s64 count0,count1,count;
173
174 tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
175 f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
176 f->fmt.vbi.sampling_rate = tvnorm->Fsc;
177 f->fmt.vbi.samples_per_line = 2048;
178 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
179 f->fmt.vbi.offset = VBI_OFFSET;
180 f->fmt.vbi.flags = 0;
181
182 /* s64 to prevent overflow. */
183 count0 = (s64) f->fmt.vbi.start[0] + f->fmt.vbi.count[0]
184 - tvnorm->vbistart[0];
185 count1 = (s64) f->fmt.vbi.start[1] + f->fmt.vbi.count[1]
186 - tvnorm->vbistart[1];
187 count = clamp (max (count0, count1), 1LL, (s64) VBI_MAXLINES);
188
189 f->fmt.vbi.start[0] = tvnorm->vbistart[0];
190 f->fmt.vbi.start[1] = tvnorm->vbistart[1];
191 f->fmt.vbi.count[0] = count;
192 f->fmt.vbi.count[1] = count;
193
194 f->fmt.vbi.reserved[0] = 0;
195 f->fmt.vbi.reserved[1] = 0;
196}
197
198void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f)
199{
200 const struct bttv_tvnorm *tvnorm;
201
202 tvnorm = &bttv_tvnorms[fh->btv->tvnorm];
203 memset(f,0,sizeof(*f));
204 f->type = V4L2_BUF_TYPE_VBI_CAPTURE;
205 f->fmt.vbi.sampling_rate = tvnorm->Fsc;
206 f->fmt.vbi.samples_per_line = 2048;
207 f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
208 f->fmt.vbi.offset = VBI_OFFSET;
209 f->fmt.vbi.start[0] = tvnorm->vbistart[0];
210 f->fmt.vbi.start[1] = tvnorm->vbistart[1];
211 f->fmt.vbi.count[0] = fh->lines;
212 f->fmt.vbi.count[1] = fh->lines;
213 f->fmt.vbi.flags = 0;
214}
215
216/* ----------------------------------------------------------------------- */
217/*
218 * Local variables:
219 * c-basic-offset: 8
220 * End:
221 */
diff --git a/drivers/media/video/bt8xx/bttv.h b/drivers/media/video/bt8xx/bttv.h
new file mode 100644
index 000000000000..3a23265c1538
--- /dev/null
+++ b/drivers/media/video/bt8xx/bttv.h
@@ -0,0 +1,390 @@
1/*
2 *
3 * bttv - Bt848 frame grabber driver
4 *
5 * card ID's and external interfaces of the bttv driver
6 * basically stuff needed by other drivers (i2c, lirc, ...)
7 * and is supported not to change much over time.
8 *
9 * Copyright (C) 1996,97 Ralph Metzler (rjkm@thp.uni-koeln.de)
10 * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de>
11 *
12 */
13
14#ifndef _BTTV_H_
15#define _BTTV_H_
16
17#include <linux/videodev.h>
18#include <linux/i2c.h>
19#include <media/ir-common.h>
20#include <media/ir-kbd-i2c.h>
21#include <media/i2c-addr.h>
22
23/* ---------------------------------------------------------- */
24/* exported by bttv-cards.c */
25
26#define BTTV_BOARD_UNKNOWN 0x00
27#define BTTV_BOARD_MIRO 0x01
28#define BTTV_BOARD_HAUPPAUGE 0x02
29#define BTTV_BOARD_STB 0x03
30#define BTTV_BOARD_INTEL 0x04
31#define BTTV_BOARD_DIAMOND 0x05
32#define BTTV_BOARD_AVERMEDIA 0x06
33#define BTTV_BOARD_MATRIX_VISION 0x07
34#define BTTV_BOARD_FLYVIDEO 0x08
35#define BTTV_BOARD_TURBOTV 0x09
36#define BTTV_BOARD_HAUPPAUGE878 0x0a
37#define BTTV_BOARD_MIROPRO 0x0b
38#define BTTV_BOARD_ADSTECH_TV 0x0c
39#define BTTV_BOARD_AVERMEDIA98 0x0d
40#define BTTV_BOARD_VHX 0x0e
41#define BTTV_BOARD_ZOLTRIX 0x0f
42#define BTTV_BOARD_PIXVIEWPLAYTV 0x10
43#define BTTV_BOARD_WINVIEW_601 0x11
44#define BTTV_BOARD_AVEC_INTERCAP 0x12
45#define BTTV_BOARD_LIFE_FLYKIT 0x13
46#define BTTV_BOARD_CEI_RAFFLES 0x14
47#define BTTV_BOARD_CONFERENCETV 0x15
48#define BTTV_BOARD_PHOEBE_TVMAS 0x16
49#define BTTV_BOARD_MODTEC_205 0x17
50#define BTTV_BOARD_MAGICTVIEW061 0x18
51#define BTTV_BOARD_VOBIS_BOOSTAR 0x19
52#define BTTV_BOARD_HAUPPAUG_WCAM 0x1a
53#define BTTV_BOARD_MAXI 0x1b
54#define BTTV_BOARD_TERRATV 0x1c
55#define BTTV_BOARD_PXC200 0x1d
56#define BTTV_BOARD_FLYVIDEO_98 0x1e
57#define BTTV_BOARD_IPROTV 0x1f
58#define BTTV_BOARD_INTEL_C_S_PCI 0x20
59#define BTTV_BOARD_TERRATVALUE 0x21
60#define BTTV_BOARD_WINFAST2000 0x22
61#define BTTV_BOARD_CHRONOS_VS2 0x23
62#define BTTV_BOARD_TYPHOON_TVIEW 0x24
63#define BTTV_BOARD_PXELVWPLTVPRO 0x25
64#define BTTV_BOARD_MAGICTVIEW063 0x26
65#define BTTV_BOARD_PINNACLE 0x27
66#define BTTV_BOARD_STB2 0x28
67#define BTTV_BOARD_AVPHONE98 0x29
68#define BTTV_BOARD_PV951 0x2a
69#define BTTV_BOARD_ONAIR_TV 0x2b
70#define BTTV_BOARD_SIGMA_TVII_FM 0x2c
71#define BTTV_BOARD_MATRIX_VISION2 0x2d
72#define BTTV_BOARD_ZOLTRIX_GENIE 0x2e
73#define BTTV_BOARD_TERRATVRADIO 0x2f
74#define BTTV_BOARD_DYNALINK 0x30
75#define BTTV_BOARD_GVBCTV3PCI 0x31
76#define BTTV_BOARD_PXELVWPLTVPAK 0x32
77#define BTTV_BOARD_EAGLE 0x33
78#define BTTV_BOARD_PINNACLEPRO 0x34
79#define BTTV_BOARD_TVIEW_RDS_FM 0x35
80#define BTTV_BOARD_LIFETEC_9415 0x36
81#define BTTV_BOARD_BESTBUY_EASYTV 0x37
82#define BTTV_BOARD_FLYVIDEO_98FM 0x38
83#define BTTV_BOARD_GRANDTEC 0x39
84#define BTTV_BOARD_ASKEY_CPH060 0x3a
85#define BTTV_BOARD_ASKEY_CPH03X 0x3b
86#define BTTV_BOARD_MM100PCTV 0x3c
87#define BTTV_BOARD_GMV1 0x3d
88#define BTTV_BOARD_BESTBUY_EASYTV2 0x3e
89#define BTTV_BOARD_ATI_TVWONDER 0x3f
90#define BTTV_BOARD_ATI_TVWONDERVE 0x40
91#define BTTV_BOARD_FLYVIDEO2000 0x41
92#define BTTV_BOARD_TERRATVALUER 0x42
93#define BTTV_BOARD_GVBCTV4PCI 0x43
94#define BTTV_BOARD_VOODOOTV_FM 0x44
95#define BTTV_BOARD_AIMMS 0x45
96#define BTTV_BOARD_PV_BT878P_PLUS 0x46
97#define BTTV_BOARD_FLYVIDEO98EZ 0x47
98#define BTTV_BOARD_PV_BT878P_9B 0x48
99#define BTTV_BOARD_SENSORAY311 0x49
100#define BTTV_BOARD_RV605 0x4a
101#define BTTV_BOARD_POWERCLR_MTV878 0x4b
102#define BTTV_BOARD_WINDVR 0x4c
103#define BTTV_BOARD_GRANDTEC_MULTI 0x4d
104#define BTTV_BOARD_KWORLD 0x4e
105#define BTTV_BOARD_DSP_TCVIDEO 0x4f
106#define BTTV_BOARD_HAUPPAUGEPVR 0x50
107#define BTTV_BOARD_GVBCTV5PCI 0x51
108#define BTTV_BOARD_OSPREY1x0 0x52
109#define BTTV_BOARD_OSPREY1x0_848 0x53
110#define BTTV_BOARD_OSPREY101_848 0x54
111#define BTTV_BOARD_OSPREY1x1 0x55
112#define BTTV_BOARD_OSPREY1x1_SVID 0x56
113#define BTTV_BOARD_OSPREY2xx 0x57
114#define BTTV_BOARD_OSPREY2x0_SVID 0x58
115#define BTTV_BOARD_OSPREY2x0 0x59
116#define BTTV_BOARD_OSPREY500 0x5a
117#define BTTV_BOARD_OSPREY540 0x5b
118#define BTTV_BOARD_OSPREY2000 0x5c
119#define BTTV_BOARD_IDS_EAGLE 0x5d
120#define BTTV_BOARD_PINNACLESAT 0x5e
121#define BTTV_BOARD_FORMAC_PROTV 0x5f
122#define BTTV_BOARD_MACHTV 0x60
123#define BTTV_BOARD_EURESYS_PICOLO 0x61
124#define BTTV_BOARD_PV150 0x62
125#define BTTV_BOARD_AD_TVK503 0x63
126#define BTTV_BOARD_HERCULES_SM_TV 0x64
127#define BTTV_BOARD_PACETV 0x65
128#define BTTV_BOARD_IVC200 0x66
129#define BTTV_BOARD_XGUARD 0x67
130#define BTTV_BOARD_NEBULA_DIGITV 0x68
131#define BTTV_BOARD_PV143 0x69
132#define BTTV_BOARD_VD009X1_MINIDIN 0x6a
133#define BTTV_BOARD_VD009X1_COMBI 0x6b
134#define BTTV_BOARD_VD009_MINIDIN 0x6c
135#define BTTV_BOARD_VD009_COMBI 0x6d
136#define BTTV_BOARD_IVC100 0x6e
137#define BTTV_BOARD_IVC120 0x6f
138#define BTTV_BOARD_PC_HDTV 0x70
139#define BTTV_BOARD_TWINHAN_DST 0x71
140#define BTTV_BOARD_WINFASTVC100 0x72
141#define BTTV_BOARD_TEV560 0x73
142#define BTTV_BOARD_SIMUS_GVC1100 0x74
143#define BTTV_BOARD_NGSTV_PLUS 0x75
144#define BTTV_BOARD_LMLBT4 0x76
145#define BTTV_BOARD_TEKRAM_M205 0x77
146#define BTTV_BOARD_CONTVFMI 0x78
147#define BTTV_BOARD_PICOLO_TETRA_CHIP 0x79
148#define BTTV_BOARD_SPIRIT_TV 0x7a
149#define BTTV_BOARD_AVDVBT_771 0x7b
150#define BTTV_BOARD_AVDVBT_761 0x7c
151#define BTTV_BOARD_MATRIX_VISIONSQ 0x7d
152#define BTTV_BOARD_MATRIX_VISIONSLC 0x7e
153#define BTTV_BOARD_APAC_VIEWCOMP 0x7f
154#define BTTV_BOARD_DVICO_DVBT_LITE 0x80
155#define BTTV_BOARD_VGEAR_MYVCD 0x81
156#define BTTV_BOARD_SUPER_TV 0x82
157#define BTTV_BOARD_TIBET_CS16 0x83
158#define BTTV_BOARD_KODICOM_4400R 0x84
159#define BTTV_BOARD_KODICOM_4400R_SL 0x85
160#define BTTV_BOARD_ADLINK_RTV24 0x86
161#define BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE 0x87
162#define BTTV_BOARD_ACORP_Y878F 0x88
163#define BTTV_BOARD_CONCEPTRONIC_CTVFMI2 0x89
164#define BTTV_BOARD_PV_BT878P_2E 0x8a
165#define BTTV_BOARD_PV_M4900 0x8b
166#define BTTV_BOARD_OSPREY440 0x8c
167#define BTTV_BOARD_ASOUND_SKYEYE 0x8d
168#define BTTV_BOARD_SABRENT_TVFM 0x8e
169#define BTTV_BOARD_HAUPPAUGE_IMPACTVCB 0x8f
170#define BTTV_BOARD_MACHTV_MAGICTV 0x90
171
172/* more card-specific defines */
173#define PT2254_L_CHANNEL 0x10
174#define PT2254_R_CHANNEL 0x08
175#define PT2254_DBS_IN_2 0x400
176#define PT2254_DBS_IN_10 0x20000
177#define WINVIEW_PT2254_CLK 0x40
178#define WINVIEW_PT2254_DATA 0x20
179#define WINVIEW_PT2254_STROBE 0x80
180
181/* digital_mode */
182#define DIGITAL_MODE_VIDEO 1
183#define DIGITAL_MODE_CAMERA 2
184
185struct bttv_core {
186 /* device structs */
187 struct pci_dev *pci;
188 struct i2c_adapter i2c_adap;
189 struct list_head subs; /* struct bttv_sub_device */
190
191 /* device config */
192 unsigned int nr; /* dev nr (for printk("bttv%d: ..."); */
193 unsigned int type; /* card type (pointer into tvcards[]) */
194 char name[8]; /* dev name */
195};
196
197struct bttv;
198
199
200struct bttv_ir {
201 struct input_dev *dev;
202 struct ir_input_state ir;
203 char name[32];
204 char phys[32];
205
206 /* Usual gpio signalling */
207
208 u32 mask_keycode;
209 u32 mask_keydown;
210 u32 mask_keyup;
211 u32 polling;
212 u32 last_gpio;
213 struct work_struct work;
214 struct timer_list timer;
215
216 /* RC5 gpio */
217 u32 rc5_gpio;
218 struct timer_list timer_end; /* timer_end for code completion */
219 struct timer_list timer_keyup; /* timer_end for key release */
220 u32 last_rc5; /* last good rc5 code */
221 u32 last_bit; /* last raw bit seen */
222 u32 code; /* raw code under construction */
223 struct timeval base_time; /* time of last seen code */
224 int active; /* building raw code */
225};
226
227struct tvcard
228{
229 char *name;
230 unsigned int video_inputs;
231 unsigned int audio_inputs;
232 unsigned int tuner;
233 unsigned int svhs;
234 unsigned int digital_mode; // DIGITAL_MODE_CAMERA or DIGITAL_MODE_VIDEO
235 u32 gpiomask;
236 u32 muxsel[16];
237 u32 gpiomux[4]; /* Tuner, Radio, external, internal */
238 u32 gpiomute; /* GPIO mute setting */
239 u32 gpiomask2; /* GPIO MUX mask */
240
241 /* i2c audio flags */
242 unsigned int no_msp34xx:1;
243 unsigned int no_tda9875:1;
244 unsigned int no_tda7432:1;
245 unsigned int needs_tvaudio:1;
246 unsigned int msp34xx_alt:1;
247
248 /* flag: video pci function is unused */
249 unsigned int no_video:1;
250 unsigned int has_dvb:1;
251 unsigned int has_remote:1;
252 unsigned int no_gpioirq:1;
253
254 /* other settings */
255 unsigned int pll;
256#define PLL_NONE 0
257#define PLL_28 1
258#define PLL_35 2
259
260 unsigned int tuner_type;
261 unsigned int tuner_addr;
262 unsigned int radio_addr;
263
264 unsigned int has_radio;
265 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
266 void (*muxsel_hook)(struct bttv *btv, unsigned int input);
267};
268
269extern struct tvcard bttv_tvcards[];
270
271/* identification / initialization of the card */
272extern void bttv_idcard(struct bttv *btv);
273extern void bttv_init_card1(struct bttv *btv);
274extern void bttv_init_card2(struct bttv *btv);
275
276/* card-specific funtions */
277extern void tea5757_set_freq(struct bttv *btv, unsigned short freq);
278extern void bttv_tda9880_setnorm(struct bttv *btv, int norm);
279
280/* extra tweaks for some chipsets */
281extern void bttv_check_chipset(void);
282extern int bttv_handle_chipset(struct bttv *btv);
283
284/* ---------------------------------------------------------- */
285/* exported by bttv-if.c */
286
287/* this obsolete -- please use the sysfs-based
288 interface below for new code */
289
290/* returns card type + card ID (for bt878-based ones)
291 for possible values see lines below beginning with #define BTTV_BOARD_UNKNOWN
292 returns negative value if error occurred
293*/
294extern int bttv_get_cardinfo(unsigned int card, int *type,
295 unsigned int *cardid);
296extern struct pci_dev* bttv_get_pcidev(unsigned int card);
297
298/* obsolete, use bttv_get_cardinfo instead */
299extern int bttv_get_id(unsigned int card);
300
301/* sets GPOE register (BT848_GPIO_OUT_EN) to new value:
302 data | (current_GPOE_value & ~mask)
303 returns negative value if error occurred
304*/
305extern int bttv_gpio_enable(unsigned int card,
306 unsigned long mask, unsigned long data);
307
308/* fills data with GPDATA register contents
309 returns negative value if error occurred
310*/
311extern int bttv_read_gpio(unsigned int card, unsigned long *data);
312
313/* sets GPDATA register to new value:
314 (data & mask) | (current_GPDATA_value & ~mask)
315 returns negative value if error occurred
316*/
317extern int bttv_write_gpio(unsigned int card,
318 unsigned long mask, unsigned long data);
319
320/* returns pointer to task queue which can be used as parameter to
321 interruptible_sleep_on
322 in interrupt handler if BT848_INT_GPINT bit is set - this queue is activated
323 (wake_up_interruptible) and following call to the function bttv_read_gpio
324 should return new value of GPDATA,
325 returns NULL value if error occurred or queue is not available
326 WARNING: because there is no buffer for GPIO data, one MUST
327 process data ASAP
328*/
329extern wait_queue_head_t* bttv_get_gpio_queue(unsigned int card);
330
331/* call i2c clients
332*/
333extern void bttv_i2c_call(unsigned int card, unsigned int cmd, void *arg);
334
335
336
337/* ---------------------------------------------------------- */
338/* sysfs/driver-moded based gpio access interface */
339
340
341struct bttv_sub_device {
342 struct device dev;
343 struct bttv_core *core;
344 struct list_head list;
345};
346#define to_bttv_sub_dev(x) container_of((x), struct bttv_sub_device, dev)
347
348struct bttv_sub_driver {
349 struct device_driver drv;
350 char wanted[BUS_ID_SIZE];
351 int (*probe)(struct bttv_sub_device *sub);
352 void (*remove)(struct bttv_sub_device *sub);
353 void (*gpio_irq)(struct bttv_sub_device *sub);
354};
355#define to_bttv_sub_drv(x) container_of((x), struct bttv_sub_driver, drv)
356
357int bttv_sub_register(struct bttv_sub_driver *drv, char *wanted);
358int bttv_sub_unregister(struct bttv_sub_driver *drv);
359
360/* gpio access functions */
361void bttv_gpio_inout(struct bttv_core *core, u32 mask, u32 outbits);
362u32 bttv_gpio_read(struct bttv_core *core);
363void bttv_gpio_write(struct bttv_core *core, u32 value);
364void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits);
365
366#define gpio_inout(mask,bits) bttv_gpio_inout(&btv->c, mask, bits)
367#define gpio_read() bttv_gpio_read(&btv->c)
368#define gpio_write(value) bttv_gpio_write(&btv->c, value)
369#define gpio_bits(mask,bits) bttv_gpio_bits(&btv->c, mask, bits)
370
371
372/* ---------------------------------------------------------- */
373/* i2c */
374
375extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg);
376extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for);
377extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
378 unsigned char b2, int both);
379extern void bttv_readee(struct bttv *btv, unsigned char *eedata, int addr);
380
381extern int bttv_input_init(struct bttv *dev);
382extern void bttv_input_fini(struct bttv *dev);
383extern void bttv_input_irq(struct bttv *dev);
384
385#endif /* _BTTV_H_ */
386/*
387 * Local variables:
388 * c-basic-offset: 8
389 * End:
390 */
diff --git a/drivers/media/video/bt8xx/bttvp.h b/drivers/media/video/bt8xx/bttvp.h
new file mode 100644
index 000000000000..ee989d2e15d9
--- /dev/null
+++ b/drivers/media/video/bt8xx/bttvp.h
@@ -0,0 +1,413 @@
1/*
2
3 bttv - Bt848 frame grabber driver
4
5 bttv's *private* header file -- nobody other than bttv itself
6 should ever include this file.
7
8 (c) 2000-2002 Gerd Knorr <kraxel@bytesex.org>
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23*/
24
25#ifndef _BTTVP_H_
26#define _BTTVP_H_
27
28#include <linux/version.h>
29#define BTTV_VERSION_CODE KERNEL_VERSION(0,9,16)
30
31#include <linux/types.h>
32#include <linux/wait.h>
33#include <linux/i2c.h>
34#include <linux/i2c-algo-bit.h>
35#include <linux/videodev.h>
36#include <linux/pci.h>
37#include <linux/input.h>
38#include <linux/mutex.h>
39#include <asm/scatterlist.h>
40#include <asm/io.h>
41
42#include <linux/device.h>
43#include <media/video-buf.h>
44#include <media/tuner.h>
45#include <media/tveeprom.h>
46#include <media/ir-common.h>
47
48
49#include "bt848.h"
50#include "bttv.h"
51#include "btcx-risc.h"
52
53#ifdef __KERNEL__
54
55#define FORMAT_FLAGS_DITHER 0x01
56#define FORMAT_FLAGS_PACKED 0x02
57#define FORMAT_FLAGS_PLANAR 0x04
58#define FORMAT_FLAGS_RAW 0x08
59#define FORMAT_FLAGS_CrCb 0x10
60
61#define RISC_SLOT_O_VBI 4
62#define RISC_SLOT_O_FIELD 6
63#define RISC_SLOT_E_VBI 10
64#define RISC_SLOT_E_FIELD 12
65#define RISC_SLOT_LOOP 14
66
67#define RESOURCE_OVERLAY 1
68#define RESOURCE_VIDEO 2
69#define RESOURCE_VBI 4
70
71#define RAW_LINES 640
72#define RAW_BPL 1024
73
74#define UNSET (-1U)
75
76#define clamp(x, low, high) min (max (low, x), high)
77
78/* ---------------------------------------------------------- */
79
80struct bttv_tvnorm {
81 int v4l2_id;
82 char *name;
83 u32 Fsc;
84 u16 swidth, sheight; /* scaled standard width, height */
85 u16 totalwidth;
86 u8 adelay, bdelay, iform;
87 u32 scaledtwidth;
88 u16 hdelayx1, hactivex1;
89 u16 vdelay;
90 u8 vbipack;
91 u16 vtotal;
92 int sram;
93 /* ITU-R frame line number of the first VBI line we can
94 capture, of the first and second field. */
95 u16 vbistart[2];
96};
97extern const struct bttv_tvnorm bttv_tvnorms[];
98
99struct bttv_format {
100 char *name;
101 int palette; /* video4linux 1 */
102 int fourcc; /* video4linux 2 */
103 int btformat; /* BT848_COLOR_FMT_* */
104 int btswap; /* BT848_COLOR_CTL_* */
105 int depth; /* bit/pixel */
106 int flags;
107 int hshift,vshift; /* for planar modes */
108};
109
110/* ---------------------------------------------------------- */
111
112struct bttv_geometry {
113 u8 vtc,crop,comb;
114 u16 width,hscale,hdelay;
115 u16 sheight,vscale,vdelay,vtotal;
116};
117
118struct bttv_buffer {
119 /* common v4l buffer stuff -- must be first */
120 struct videobuf_buffer vb;
121
122 /* bttv specific */
123 const struct bttv_format *fmt;
124 int tvnorm;
125 int btformat;
126 int btswap;
127 struct bttv_geometry geo;
128 struct btcx_riscmem top;
129 struct btcx_riscmem bottom;
130};
131
132struct bttv_buffer_set {
133 struct bttv_buffer *top; /* top field buffer */
134 struct bttv_buffer *bottom; /* bottom field buffer */
135 unsigned int top_irq;
136 unsigned int frame_irq;
137};
138
139struct bttv_overlay {
140 int tvnorm;
141 struct v4l2_rect w;
142 enum v4l2_field field;
143 struct v4l2_clip *clips;
144 int nclips;
145 int setup_ok;
146};
147
148struct bttv_fh {
149 struct bttv *btv;
150 int resources;
151#ifdef VIDIOC_G_PRIORITY
152 enum v4l2_priority prio;
153#endif
154 enum v4l2_buf_type type;
155
156 /* video capture */
157 struct videobuf_queue cap;
158 const struct bttv_format *fmt;
159 int width;
160 int height;
161
162 /* current settings */
163 const struct bttv_format *ovfmt;
164 struct bttv_overlay ov;
165
166 /* video overlay */
167 struct videobuf_queue vbi;
168 int lines;
169};
170
171/* ---------------------------------------------------------- */
172/* bttv-risc.c */
173
174/* risc code generators - capture */
175int bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
176 struct scatterlist *sglist,
177 unsigned int offset, unsigned int bpl,
178 unsigned int pitch, unsigned int lines);
179
180/* control dma register + risc main loop */
181void bttv_set_dma(struct bttv *btv, int override);
182int bttv_risc_init_main(struct bttv *btv);
183int bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
184 int irqflags);
185
186/* capture buffer handling */
187int bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf);
188int bttv_buffer_activate_video(struct bttv *btv,
189 struct bttv_buffer_set *set);
190int bttv_buffer_activate_vbi(struct bttv *btv,
191 struct bttv_buffer *vbi);
192void bttv_dma_free(struct videobuf_queue *q, struct bttv *btv,
193 struct bttv_buffer *buf);
194
195/* overlay handling */
196int bttv_overlay_risc(struct bttv *btv, struct bttv_overlay *ov,
197 const struct bttv_format *fmt,
198 struct bttv_buffer *buf);
199
200
201/* ---------------------------------------------------------- */
202/* bttv-vbi.c */
203
204void bttv_vbi_try_fmt(struct bttv_fh *fh, struct v4l2_format *f);
205void bttv_vbi_get_fmt(struct bttv_fh *fh, struct v4l2_format *f);
206void bttv_vbi_setlines(struct bttv_fh *fh, struct bttv *btv, int lines);
207
208extern struct videobuf_queue_ops bttv_vbi_qops;
209
210/* ---------------------------------------------------------- */
211/* bttv-gpio.c */
212
213
214extern struct bus_type bttv_sub_bus_type;
215int bttv_sub_add_device(struct bttv_core *core, char *name);
216int bttv_sub_del_devices(struct bttv_core *core);
217void bttv_gpio_irq(struct bttv_core *core);
218
219
220/* ---------------------------------------------------------- */
221/* bttv-driver.c */
222
223/* insmod options */
224extern unsigned int bttv_verbose;
225extern unsigned int bttv_debug;
226extern unsigned int bttv_gpio;
227extern void bttv_gpio_tracking(struct bttv *btv, char *comment);
228extern int init_bttv_i2c(struct bttv *btv);
229extern int fini_bttv_i2c(struct bttv *btv);
230
231#define bttv_printk if (bttv_verbose) printk
232#define dprintk if (bttv_debug >= 1) printk
233#define d2printk if (bttv_debug >= 2) printk
234
235#define BTTV_MAX_FBUF 0x208000
236#define VBIBUF_SIZE (2048*VBI_MAXLINES*2)
237#define BTTV_TIMEOUT (HZ/2) /* 0.5 seconds */
238#define BTTV_FREE_IDLE (HZ) /* one second */
239
240
241struct bttv_pll_info {
242 unsigned int pll_ifreq; /* PLL input frequency */
243 unsigned int pll_ofreq; /* PLL output frequency */
244 unsigned int pll_crystal; /* Crystal used for input */
245 unsigned int pll_current; /* Currently programmed ofreq */
246};
247
248/* for gpio-connected remote control */
249struct bttv_input {
250 struct input_dev *dev;
251 struct ir_input_state ir;
252 char name[32];
253 char phys[32];
254 u32 mask_keycode;
255 u32 mask_keydown;
256};
257
258struct bttv_suspend_state {
259 u32 gpio_enable;
260 u32 gpio_data;
261 int disabled;
262 int loop_irq;
263 struct bttv_buffer_set video;
264 struct bttv_buffer *vbi;
265};
266
267struct bttv {
268 struct bttv_core c;
269
270 /* pci device config */
271 unsigned short id;
272 unsigned char revision;
273 unsigned char __iomem *bt848_mmio; /* pointer to mmio */
274
275 /* card configuration info */
276 unsigned int cardid; /* pci subsystem id (bt878 based ones) */
277 unsigned int tuner_type; /* tuner chip type */
278 unsigned int tda9887_conf;
279 unsigned int svhs;
280 struct bttv_pll_info pll;
281 int triton1;
282 int gpioirq;
283 int (*custom_irq)(struct bttv *btv);
284
285 int use_i2c_hw;
286
287 /* old gpio interface */
288 wait_queue_head_t gpioq;
289 int shutdown;
290 void (*audio_hook)(struct bttv *btv, struct video_audio *v, int set);
291
292 /* new gpio interface */
293 spinlock_t gpio_lock;
294
295 /* i2c layer */
296 struct i2c_algo_bit_data i2c_algo;
297 struct i2c_client i2c_client;
298 int i2c_state, i2c_rc;
299 int i2c_done;
300 wait_queue_head_t i2c_queue;
301 struct i2c_client *i2c_msp34xx_client;
302 struct i2c_client *i2c_tvaudio_client;
303
304 /* video4linux (1) */
305 struct video_device *video_dev;
306 struct video_device *radio_dev;
307 struct video_device *vbi_dev;
308
309 /* infrared remote */
310 int has_remote;
311 struct bttv_ir *remote;
312
313 /* locking */
314 spinlock_t s_lock;
315 struct mutex lock;
316 int resources;
317 struct mutex reslock;
318#ifdef VIDIOC_G_PRIORITY
319 struct v4l2_prio_state prio;
320#endif
321
322 /* video state */
323 unsigned int input;
324 unsigned int audio;
325 unsigned int mute;
326 unsigned long freq;
327 int tvnorm,hue,contrast,bright,saturation;
328 struct v4l2_framebuffer fbuf;
329 unsigned int field_count;
330
331 /* various options */
332 int opt_combfilter;
333 int opt_lumafilter;
334 int opt_automute;
335 int opt_chroma_agc;
336 int opt_adc_crush;
337 int opt_vcr_hack;
338 int opt_whitecrush_upper;
339 int opt_whitecrush_lower;
340 int opt_uv_ratio;
341 int opt_full_luma_range;
342 int opt_coring;
343
344 /* radio data/state */
345 int has_radio;
346 int radio_user;
347
348 /* miro/pinnacle + Aimslab VHX
349 philips matchbox (tea5757 radio tuner) support */
350 int has_matchbox;
351 int mbox_we;
352 int mbox_data;
353 int mbox_clk;
354 int mbox_most;
355 int mbox_mask;
356
357 /* ISA stuff (Terratec Active Radio Upgrade) */
358 int mbox_ior;
359 int mbox_iow;
360 int mbox_csel;
361
362 /* risc memory management data
363 - must aquire s_lock before changing these
364 - only the irq handler is supported to touch top + bottom + vcurr */
365 struct btcx_riscmem main;
366 struct bttv_buffer *screen; /* overlay */
367 struct list_head capture; /* video capture queue */
368 struct list_head vcapture; /* vbi capture queue */
369 struct bttv_buffer_set curr; /* active buffers */
370 struct bttv_buffer *cvbi; /* active vbi buffer */
371 int loop_irq;
372 int new_input;
373
374 unsigned long cap_ctl;
375 unsigned long dma_on;
376 struct timer_list timeout;
377 struct bttv_suspend_state state;
378
379 /* stats */
380 unsigned int errors;
381 unsigned int framedrop;
382 unsigned int irq_total;
383 unsigned int irq_me;
384
385 unsigned int users;
386 struct bttv_fh init;
387};
388
389/* our devices */
390#define BTTV_MAX 16
391extern unsigned int bttv_num;
392extern struct bttv bttvs[BTTV_MAX];
393
394/* private ioctls */
395#define BTTV_VERSION _IOR('v' , BASE_VIDIOCPRIVATE+6, int)
396#define BTTV_VBISIZE _IOR('v' , BASE_VIDIOCPRIVATE+8, int)
397
398#endif
399
400#define btwrite(dat,adr) writel((dat), btv->bt848_mmio+(adr))
401#define btread(adr) readl(btv->bt848_mmio+(adr))
402
403#define btand(dat,adr) btwrite((dat) & btread(adr), adr)
404#define btor(dat,adr) btwrite((dat) | btread(adr), adr)
405#define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr)
406
407#endif /* _BTTVP_H_ */
408
409/*
410 * Local variables:
411 * c-basic-offset: 8
412 * End:
413 */