aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@brturbo.com.br>2005-11-09 00:37:24 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-11-09 10:56:17 -0500
commit596d92d5128d308b5a79f21c3e72c87f5fc7e58b (patch)
tree3957529296b0765e7979f205a9dd0bce7de1eb7a
parent2b5200a7b19a53969db68c97d379339592ca6a4f (diff)
[PATCH] v4l: 767: included support for em2800
- Included support for em2800. Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--Documentation/video4linux/CARDLIST.em28xx13
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c125
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c13
-rw-r--r--drivers/media/video/em28xx/em28xx-i2c.c182
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c73
-rw-r--r--drivers/media/video/em28xx/em28xx.h29
6 files changed, 375 insertions, 60 deletions
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index a33ddea0b6f5..d86aae09450b 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -1,4 +1,9 @@
1 0 -> Terratec Cinergy 250 USB [0ccd:0036] 1 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800]
2 1 -> Pinnacle PCTV USB 2 [2304:0208] 2 1 -> Unknown EM2820/2840 video grabber (em2820/em2840) [eb1a:2820]
3 2 -> Hauppauge WinTV USB 2 [2040:4200] 3 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036]
4 3 -> MSI VOX USB 2.0 [eb1a:2820] 4 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208]
5 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200]
6 5 -> MSI VOX USB 2.0 (em2820/em2840)
7 6 -> Terratec Cinergy 200 USB (em2800)
8 7 -> Leadtek Winfast USB II (em2800)
9 8 -> Kworld USB2800 (em2800)
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 7333bbad8871..91c70ebd0ea4 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1,5 +1,5 @@
1/* 1/*
2 em2820-cards.c - driver for Empia EM2820/2840 USB video capture devices 2 em2820-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3 3
4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> 4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
5 Ludovico Cavedon <cavedon@sssup.it> 5 Ludovico Cavedon <cavedon@sssup.it>
@@ -35,14 +35,43 @@
35 35
36#include "em2820.h" 36#include "em2820.h"
37 37
38enum em2820_board_entry {
39 EM2820_BOARD_TERRATEC_CINERGY_250,
40 EM2820_BOARD_PINNACLE_USB_2,
41 EM2820_BOARD_HAUPPAUGE_WINTV_USB_2,
42 EM2820_BOARD_MSI_VOX_USB_2
43};
44
45struct em2820_board em2820_boards[] = { 38struct em2820_board em2820_boards[] = {
39 [EM2800_BOARD_UNKNOWN] = {
40 .name = "Unknown EM2800 video grabber",
41 .is_em2800 = 1,
42 .vchannels = 2,
43 .norm = VIDEO_MODE_PAL,
44 .tda9887_conf = TDA9887_PRESENT,
45 .has_tuner = 1,
46 .decoder = EM2820_SAA7113,
47 .input = {{
48 .type = EM2820_VMUX_COMPOSITE1,
49 .vmux = 0,
50 .amux = 1,
51 },{
52 .type = EM2820_VMUX_SVIDEO,
53 .vmux = 9,
54 .amux = 1,
55 }},
56 },
57 [EM2820_BOARD_UNKNOWN] = {
58 .name = "Unknown EM2820/2840 video grabber",
59 .is_em2800 = 0,
60 .vchannels = 2,
61 .norm = VIDEO_MODE_PAL,
62 .tda9887_conf = TDA9887_PRESENT,
63 .has_tuner = 1,
64 .decoder = EM2820_SAA7113,
65 .input = {{
66 .type = EM2820_VMUX_COMPOSITE1,
67 .vmux = 0,
68 .amux = 1,
69 },{
70 .type = EM2820_VMUX_SVIDEO,
71 .vmux = 9,
72 .amux = 1,
73 }},
74 },
46 [EM2820_BOARD_TERRATEC_CINERGY_250] = { 75 [EM2820_BOARD_TERRATEC_CINERGY_250] = {
47 .name = "Terratec Cinergy 250 USB", 76 .name = "Terratec Cinergy 250 USB",
48 .vchannels = 3, 77 .vchannels = 3,
@@ -129,17 +158,88 @@ struct em2820_board em2820_boards[] = {
129 .amux = 1, 158 .amux = 1,
130 }}, 159 }},
131 }, 160 },
132 { } /* Terminating entry */ 161 [EM2800_BOARD_TERRATEC_CINERGY_200] = {
162 .name = "Terratec Cinergy 200 USB",
163 .chip_id = 0x4,
164 .is_em2800 = 1,
165 .vchannels = 3,
166 .norm = VIDEO_MODE_PAL,
167 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
168 .tda9887_conf = TDA9887_PRESENT,
169 .has_tuner = 1,
170 .decoder = EM2820_SAA7113,
171 .input = {{
172 .type = EM2820_VMUX_TELEVISION,
173 .vmux = 2,
174 .amux = 0,
175 },{
176 .type = EM2820_VMUX_COMPOSITE1,
177 .vmux = 0,
178 .amux = 1,
179 },{
180 .type = EM2820_VMUX_SVIDEO,
181 .vmux = 9,
182 .amux = 1,
183 }},
184 },
185 [EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
186 .name = "Leadtek Winfast USB II",
187 .chip_id = 0x2,
188 .is_em2800 = 1,
189 .vchannels = 3,
190 .norm = VIDEO_MODE_PAL,
191 .tuner_type = TUNER_LG_PAL_NEW_TAPC,
192 .tda9887_conf = TDA9887_PRESENT,
193 .has_tuner = 1,
194 .decoder = EM2820_SAA7113,
195 .input = {{
196 .type = EM2820_VMUX_TELEVISION,
197 .vmux = 2,
198 .amux = 0,
199 },{
200 .type = EM2820_VMUX_COMPOSITE1,
201 .vmux = 0,
202 .amux = 1,
203 },{
204 .type = EM2820_VMUX_SVIDEO,
205 .vmux = 9,
206 .amux = 1,
207 }},
208 },
209 [EM2800_BOARD_KWORLD_USB2800] = {
210 .name = "Kworld USB2800",
211 .chip_id = 0x7,
212 .is_em2800 = 1,
213 .vchannels = 3,
214 .norm = VIDEO_MODE_PAL,
215 .tuner_type = TUNER_PHILIPS_ATSC,
216 .tda9887_conf = TDA9887_PRESENT,
217 .has_tuner = 1,
218 .decoder = EM2820_SAA7113,
219 .input = {{
220 .type = EM2820_VMUX_TELEVISION,
221 .vmux = 2,
222 .amux = 0,
223 },{
224 .type = EM2820_VMUX_COMPOSITE1,
225 .vmux = 0,
226 .amux = 1,
227 },{
228 .type = EM2820_VMUX_SVIDEO,
229 .vmux = 9,
230 .amux = 1,
231 }},
232 },
133}; 233};
234const unsigned int em2820_bcount = ARRAY_SIZE(em2820_boards);
134 235
135/* table of devices that work with this driver */ 236/* table of devices that work with this driver */
136struct usb_device_id em2820_id_table [] = { 237struct usb_device_id em2820_id_table [] = {
137 /* Terratec Cinerhy 200 USB: em2800 nor supported, at the moment */ 238 { USB_DEVICE(0xeb1a, 0x2800), .driver_info = EM2800_BOARD_UNKNOWN },
138 /* { USB_DEVICE(0xeb1a, 0x2800), .driver_info = EM2800_BOARD_TERRATEC_CINERGY_200 }, */ 239 { USB_DEVICE(0xeb1a, 0x2820), .driver_info = EM2820_BOARD_UNKNOWN },
139 { USB_DEVICE(0x0ccd, 0x0036), .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 }, 240 { USB_DEVICE(0x0ccd, 0x0036), .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
140 { USB_DEVICE(0x2304, 0x0208), .driver_info = EM2820_BOARD_PINNACLE_USB_2 }, 241 { USB_DEVICE(0x2304, 0x0208), .driver_info = EM2820_BOARD_PINNACLE_USB_2 },
141 { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 }, 242 { USB_DEVICE(0x2040, 0x4200), .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
142 { USB_DEVICE(0xeb1a, 0x2820), .driver_info = EM2820_BOARD_MSI_VOX_USB_2 },
143 { }, 243 { },
144}; 244};
145 245
@@ -163,6 +263,7 @@ void em2820_card_setup(struct em2820 *dev)
163} 263}
164 264
165EXPORT_SYMBOL(em2820_boards); 265EXPORT_SYMBOL(em2820_boards);
266EXPORT_SYMBOL(em2820_bcount);
166EXPORT_SYMBOL(em2820_id_table); 267EXPORT_SYMBOL(em2820_id_table);
167 268
168MODULE_DEVICE_TABLE (usb, em2820_id_table); 269MODULE_DEVICE_TABLE (usb, em2820_id_table);
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index e187422f6d6d..594e6d681ba4 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -1,5 +1,5 @@
1/* 1/*
2 em2820-core.c - driver for Empia EM2820/2840 USB video capture devices 2 em2820-core.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3 3
4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> 4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
5 Ludovico Cavedon <cavedon@sssup.it> 5 Ludovico Cavedon <cavedon@sssup.it>
@@ -562,6 +562,11 @@ static inline void em2820_isoc_video_copy(struct em2820 *dev,
562 void *fieldstart, *startwrite, *startread; 562 void *fieldstart, *startwrite, *startread;
563 int linesdone, currlinedone, offset, lencopy,remain; 563 int linesdone, currlinedone, offset, lencopy,remain;
564 564
565 if(dev->frame_size != (*f)->buf.length){
566 em2820_err("frame_size %i and buf.length %i are different!!!\n",dev->frame_size,(*f)->buf.length);
567 return;
568 }
569
565 if ((*f)->fieldbytesused + len > dev->field_size) 570 if ((*f)->fieldbytesused + len > dev->field_size)
566 len =dev->field_size - (*f)->fieldbytesused; 571 len =dev->field_size - (*f)->fieldbytesused;
567 remain = len; 572 remain = len;
@@ -780,6 +785,11 @@ int em2820_set_alternate(struct em2820 *dev)
780 dev->alt = alt; 785 dev->alt = alt;
781 if (dev->alt == 0) { 786 if (dev->alt == 0) {
782 int i; 787 int i;
788 if(dev->is_em2800){ /* always use the max packet size for em2800 based devices */
789 for(i=0;i< EM2820_MAX_ALT; i++)
790 if(dev->alt_max_pkt_size[i]>dev->alt_max_pkt_size[dev->alt])
791 dev->alt=i;
792 }else{
783 unsigned int min_pkt_size = dev->field_size / 137; /* FIXME: empiric magic number */ 793 unsigned int min_pkt_size = dev->field_size / 137; /* FIXME: empiric magic number */
784 em2820_coredbg("minimum isoc packet size: %u", min_pkt_size); 794 em2820_coredbg("minimum isoc packet size: %u", min_pkt_size);
785 dev->alt = 7; 795 dev->alt = 7;
@@ -788,6 +798,7 @@ int em2820_set_alternate(struct em2820 *dev)
788 dev->alt = i; 798 dev->alt = i;
789 break; 799 break;
790 } 800 }
801 }
791 } 802 }
792 803
793 if (dev->alt != prev_alt) { 804 if (dev->alt != prev_alt) {
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c
index 3065ddb4b368..b7360d579a8a 100644
--- a/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/drivers/media/video/em28xx/em28xx-i2c.c
@@ -1,5 +1,5 @@
1/* 1/*
2 em2820-i2c.c - driver for Empia EM2820/2840 USB video capture devices 2 em2820-i2c.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3 3
4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> 4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
5 Ludovico Cavedon <cavedon@sssup.it> 5 Ludovico Cavedon <cavedon@sssup.it>
@@ -29,11 +29,6 @@
29#include <media/tuner.h> 29#include <media/tuner.h>
30#include <linux/video_decoder.h> 30#include <linux/video_decoder.h>
31 31
32/* To be moved to compat.h */
33#if !defined(I2C_HW_B_EM2820)
34#define I2C_HW_B_EM2820 0x99
35#endif
36
37#include "em2820.h" 32#include "em2820.h"
38 33
39/* ----------------------------------------------------------- */ 34/* ----------------------------------------------------------- */
@@ -56,11 +51,132 @@ MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
56 printk(fmt , ##args); } while (0) 51 printk(fmt , ##args); } while (0)
57 52
58/* 53/*
59 * i2c_send_bytes() 54 * em2800_i2c_send_max4()
55 * send up to 4 bytes to the i2c device
56 */
57static int em2800_i2c_send_max4(struct em2820 *dev, unsigned char addr,
58 char *buf, int len)
59{
60 int ret;
61 int write_timeout;
62 unsigned char b2[6];
63 BUG_ON(len < 1 || len > 4);
64 b2[5] = 0x80 + len - 1;
65 b2[4] = addr;
66 b2[3] = buf[0];
67 if (len > 1)
68 b2[2] = buf[1];
69 if (len > 2)
70 b2[1] = buf[2];
71 if (len > 3)
72 b2[0] = buf[3];
73
74 ret = dev->em2820_write_regs(dev, 4 - len, &b2[4 - len], 2 + len);
75 if (ret != 2 + len) {
76 em2820_warn("writting to i2c device failed (error=%i)\n", ret);
77 return -EIO;
78 }
79 for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;
80 write_timeout -= 5) {
81 ret = dev->em2820_read_reg(dev, 0x05);
82 if (ret == 0x80 + len - 1)
83 return len;
84 mdelay(5);
85 }
86 em2820_warn("i2c write timed out\n");
87 return -EIO;
88}
89
90/*
91 * em2800_i2c_send_bytes()
92 */
93static int em2800_i2c_send_bytes(void *data, unsigned char addr, char *buf,
94 short len)
95{
96 char *bufPtr = buf;
97 int ret;
98 int wrcount = 0;
99 int count;
100 int maxLen = 4;
101 struct em2820 *dev = (struct em2820 *)data;
102 while (len > 0) {
103 count = (len > maxLen) ? maxLen : len;
104 ret = em2800_i2c_send_max4(dev, addr, bufPtr, count);
105 if (ret > 0) {
106 len -= count;
107 bufPtr += count;
108 wrcount += count;
109 } else
110 return (ret < 0) ? ret : -EFAULT;
111 }
112 return wrcount;
113}
114
115/*
116 * em2800_i2c_check_for_device()
117 * check if there is a i2c_device at the supplied address
118 */
119static int em2800_i2c_check_for_device(struct em2820 *dev, unsigned char addr)
120{
121 char msg;
122 int ret;
123 int write_timeout;
124 msg = addr;
125 ret = dev->em2820_write_regs(dev, 0x04, &msg, 1);
126 if (ret < 0) {
127 em2820_warn("setting i2c device address failed (error=%i)\n",
128 ret);
129 return ret;
130 }
131 msg = 0x84;
132 ret = dev->em2820_write_regs(dev, 0x05, &msg, 1);
133 if (ret < 0) {
134 em2820_warn("preparing i2c read failed (error=%i)\n", ret);
135 return ret;
136 }
137 for (write_timeout = EM2800_I2C_WRITE_TIMEOUT; write_timeout > 0;
138 write_timeout -= 5) {
139 unsigned msg = dev->em2820_read_reg(dev, 0x5);
140 if (msg == 0x94)
141 return -ENODEV;
142 else if (msg == 0x84)
143 return 0;
144 mdelay(5);
145 }
146 return -ENODEV;
147}
148
149/*
150 * em2800_i2c_recv_bytes()
151 * read from the i2c device
152 */
153static int em2800_i2c_recv_bytes(struct em2820 *dev, unsigned char addr,
154 char *buf, int len)
155{
156 int ret;
157 /* check for the device and set i2c read address */
158 ret = em2800_i2c_check_for_device(dev, addr);
159 if (ret) {
160 em2820_warn
161 ("preparing read at i2c address 0x%x failed (error=%i)\n",
162 addr, ret);
163 return ret;
164 }
165 ret = dev->em2820_read_reg_req_len(dev, 0x0, 0x3, buf, len);
166 if (ret < 0) {
167 em2820_warn("reading from i2c device at 0x%x failed (error=%i)",
168 addr, ret);
169 return ret;
170 }
171 return ret;
172}
173
174/*
175 * em2820_i2c_send_bytes()
60 * untested for more than 4 bytes 176 * untested for more than 4 bytes
61 */ 177 */
62static int i2c_send_bytes(void *data, unsigned char addr, char *buf, short len, 178static int em2820_i2c_send_bytes(void *data, unsigned char addr, char *buf,
63 int stop) 179 short len, int stop)
64{ 180{
65 int wrcount = 0; 181 int wrcount = 0;
66 struct em2820 *dev = (struct em2820 *)data; 182 struct em2820 *dev = (struct em2820 *)data;
@@ -71,11 +187,11 @@ static int i2c_send_bytes(void *data, unsigned char addr, char *buf, short len,
71} 187}
72 188
73/* 189/*
74 * i2c_recv_byte() 190 * em2820_i2c_recv_bytes()
75 * read a byte from the i2c device 191 * read a byte from the i2c device
76 */ 192 */
77static int i2c_recv_bytes(struct em2820 *dev, unsigned char addr, char *buf, 193static int em2820_i2c_recv_bytes(struct em2820 *dev, unsigned char addr,
78 int len) 194 char *buf, int len)
79{ 195{
80 int ret; 196 int ret;
81 ret = dev->em2820_read_reg_req_len(dev, 2, addr, buf, len); 197 ret = dev->em2820_read_reg_req_len(dev, 2, addr, buf, len);
@@ -89,10 +205,10 @@ static int i2c_recv_bytes(struct em2820 *dev, unsigned char addr, char *buf,
89} 205}
90 206
91/* 207/*
92 * i2c_check_for_device() 208 * em2820_i2c_check_for_device()
93 * check if there is a i2c_device at the supplied address 209 * check if there is a i2c_device at the supplied address
94 */ 210 */
95static int i2c_check_for_device(struct em2820 *dev, unsigned char addr) 211static int em2820_i2c_check_for_device(struct em2820 *dev, unsigned char addr)
96{ 212{
97 char msg; 213 char msg;
98 int ret; 214 int ret;
@@ -126,18 +242,25 @@ static int em2820_i2c_xfer(struct i2c_adapter *i2c_adap,
126 (msgs[i].flags & I2C_M_RD) ? "read" : "write", 242 (msgs[i].flags & I2C_M_RD) ? "read" : "write",
127 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); 243 i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
128 if (!msgs[i].len) { /* no len: check only for device presence */ 244 if (!msgs[i].len) { /* no len: check only for device presence */
129 rc = i2c_check_for_device(dev, addr); 245 if (dev->is_em2800)
246 rc = em2800_i2c_check_for_device(dev, addr);
247 else
248 rc = em2820_i2c_check_for_device(dev, addr);
130 if (rc < 0) { 249 if (rc < 0) {
131 dprintk2(" no device\n"); 250 dprintk2(" no device\n");
132 return rc; 251 return rc;
133 } 252 }
134 253
135 } 254 } else if (msgs[i].flags & I2C_M_RD) {
136 if (msgs[i].flags & I2C_M_RD) {
137 /* read bytes */ 255 /* read bytes */
138 256 if (dev->is_em2800)
139 rc = i2c_recv_bytes(dev, addr, msgs[i].buf, 257 rc = em2800_i2c_recv_bytes(dev, addr,
140 msgs[i].len); 258 msgs[i].buf,
259 msgs[i].len);
260 else
261 rc = em2820_i2c_recv_bytes(dev, addr,
262 msgs[i].buf,
263 msgs[i].len);
141 if (i2c_debug) { 264 if (i2c_debug) {
142 for (byte = 0; byte < msgs[i].len; byte++) { 265 for (byte = 0; byte < msgs[i].len; byte++) {
143 printk(" %02x", msgs[i].buf[byte]); 266 printk(" %02x", msgs[i].buf[byte]);
@@ -149,8 +272,15 @@ static int em2820_i2c_xfer(struct i2c_adapter *i2c_adap,
149 for (byte = 0; byte < msgs[i].len; byte++) 272 for (byte = 0; byte < msgs[i].len; byte++)
150 printk(" %02x", msgs[i].buf[byte]); 273 printk(" %02x", msgs[i].buf[byte]);
151 } 274 }
152 rc = i2c_send_bytes(dev, addr, msgs[i].buf, msgs[i].len, 275 if (dev->is_em2800)
153 i == num - 1); 276 rc = em2800_i2c_send_bytes(dev, addr,
277 msgs[i].buf,
278 msgs[i].len);
279 else
280 rc = em2820_i2c_send_bytes(dev, addr,
281 msgs[i].buf,
282 msgs[i].len,
283 i == num - 1);
154 if (rc < 0) 284 if (rc < 0)
155 goto err; 285 goto err;
156 } 286 }
@@ -171,6 +301,12 @@ static int em2820_i2c_eeprom(struct em2820 *dev, unsigned char *eedata, int len)
171 int i, err, size = len, block; 301 int i, err, size = len, block;
172 302
173 dev->i2c_client.addr = 0xa0 >> 1; 303 dev->i2c_client.addr = 0xa0 >> 1;
304
305 /* Check if board has eeprom */
306 err = i2c_master_recv(&dev->i2c_client, &buf, 0);
307 if (err < 0)
308 return -1;
309
174 buf = 0; 310 buf = 0;
175 if (1 != (err = i2c_master_send(&dev->i2c_client, &buf, 1))) { 311 if (1 != (err = i2c_master_send(&dev->i2c_client, &buf, 1))) {
176 printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", 312 printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n",
@@ -389,7 +525,7 @@ static void do_i2c_scan(char *name, struct i2c_client *c)
389 rc = i2c_master_recv(c, &buf, 0); 525 rc = i2c_master_recv(c, &buf, 0);
390 if (rc < 0) 526 if (rc < 0)
391 continue; 527 continue;
392 printk(KERN_INFO "%s: found device @ 0x%x [%s]", name, 528 printk(KERN_INFO "%s: found i2c device @ 0x%x [%s]\n", name,
393 i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); 529 i << 1, i2c_devs[i] ? i2c_devs[i] : "???");
394 } 530 }
395} 531}
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index 7e4114ea15f9..d3a959b9ee64 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1,5 +1,5 @@
1/* 1/*
2 em2820-video.c - driver for Empia EM2820/2840 USB video capture devices 2 em2820-video.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3 3
4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> 4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
5 Ludovico Cavedon <cavedon@sssup.it> 5 Ludovico Cavedon <cavedon@sssup.it>
@@ -50,6 +50,11 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
50MODULE_DESCRIPTION(DRIVER_DESC); 50MODULE_DESCRIPTION(DRIVER_DESC);
51MODULE_LICENSE("GPL"); 51MODULE_LICENSE("GPL");
52 52
53static unsigned int card[] = {[0 ... (EM2820_MAXBOARDS - 1)] = UNSET };
54
55module_param_array(card, int, NULL, 0444);
56MODULE_PARM_DESC(card,"card type");
57
53static int tuner = -1; 58static int tuner = -1;
54module_param(tuner, int, 0444); 59module_param(tuner, int, 0444);
55MODULE_PARM_DESC(tuner, "tuner type"); 60MODULE_PARM_DESC(tuner, "tuner type");
@@ -1081,7 +1086,7 @@ static int em2820_do_ioctl(struct inode *inode, struct file *filp,
1081 struct v4l2_cropcap *cc = arg; 1086 struct v4l2_cropcap *cc = arg;
1082 1087
1083 if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1088 if (cc->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1084 return EINVAL; 1089 return -EINVAL;
1085 cc->bounds.left = 0; 1090 cc->bounds.left = 0;
1086 cc->bounds.top = 0; 1091 cc->bounds.top = 0;
1087 cc->bounds.width = dev->width; 1092 cc->bounds.width = dev->width;
@@ -1520,21 +1525,12 @@ static struct file_operations em2820_v4l_fops = {
1520static int em2820_init_dev(struct em2820 **devhandle, struct usb_device *udev, 1525static int em2820_init_dev(struct em2820 **devhandle, struct usb_device *udev,
1521 int minor, int model) 1526 int minor, int model)
1522{ 1527{
1523 struct em2820 *dev; 1528 struct em2820 *dev = *devhandle;
1524 int retval = -ENOMEM; 1529 int retval = -ENOMEM;
1525 int errCode, i; 1530 int errCode, i;
1526 unsigned int maxh, maxw; 1531 unsigned int maxh, maxw;
1527 struct usb_interface *uif; 1532 struct usb_interface *uif;
1528 1533
1529 /* allocate memory for our device state and initialize it */
1530 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
1531 if (dev == NULL) {
1532 em2820_err(DRIVER_NAME ": out of memory!\n");
1533 return -ENOMEM;
1534 }
1535 memset(dev, 0x00, sizeof(*dev));
1536
1537 snprintf(dev->name, 29, "em2820 #%d", minor);
1538 dev->udev = udev; 1534 dev->udev = udev;
1539 dev->model = model; 1535 dev->model = model;
1540 init_MUTEX(&dev->lock); 1536 init_MUTEX(&dev->lock);
@@ -1545,6 +1541,7 @@ static int em2820_init_dev(struct em2820 **devhandle, struct usb_device *udev,
1545 dev->em2820_read_reg_req_len = em2820_read_reg_req_len; 1541 dev->em2820_read_reg_req_len = em2820_read_reg_req_len;
1546 dev->em2820_write_regs_req = em2820_write_regs_req; 1542 dev->em2820_write_regs_req = em2820_write_regs_req;
1547 dev->em2820_read_reg_req = em2820_read_reg_req; 1543 dev->em2820_read_reg_req = em2820_read_reg_req;
1544 dev->is_em2800 = em2820_boards[model].is_em2800;
1548 dev->has_tuner = em2820_boards[model].has_tuner; 1545 dev->has_tuner = em2820_boards[model].has_tuner;
1549 dev->has_msp34xx = em2820_boards[model].has_msp34xx; 1546 dev->has_msp34xx = em2820_boards[model].has_msp34xx;
1550 dev->tda9887_conf = em2820_boards[model].tda9887_conf; 1547 dev->tda9887_conf = em2820_boards[model].tda9887_conf;
@@ -1595,7 +1592,7 @@ static int em2820_init_dev(struct em2820 **devhandle, struct usb_device *udev,
1595 /* compute alternate max packet sizes */ 1592 /* compute alternate max packet sizes */
1596 uif = dev->udev->actconfig->interface[0]; 1593 uif = dev->udev->actconfig->interface[0];
1597 dev->alt_max_pkt_size[0] = 0; 1594 dev->alt_max_pkt_size[0] = 0;
1598 for (i = 1; i <= EM2820_MAX_ALT; i++) { 1595 for (i = 1; i <= EM2820_MAX_ALT && i < uif->num_altsetting ; i++) {
1599 u16 tmp = 1596 u16 tmp =
1600 le16_to_cpu(uif->altsetting[i].endpoint[1].desc. 1597 le16_to_cpu(uif->altsetting[i].endpoint[1].desc.
1601 wMaxPacketSize); 1598 wMaxPacketSize);
@@ -1688,7 +1685,6 @@ static int em2820_init_dev(struct em2820 **devhandle, struct usb_device *udev,
1688 em2820_info("V4L2 device registered as /dev/video%d\n", 1685 em2820_info("V4L2 device registered as /dev/video%d\n",
1689 dev->vdev->minor); 1686 dev->vdev->minor);
1690 1687
1691 *devhandle = dev;
1692 return 0; 1688 return 0;
1693} 1689}
1694 1690
@@ -1703,27 +1699,68 @@ static int em2820_usb_probe(struct usb_interface *interface,
1703 struct usb_device *udev; 1699 struct usb_device *udev;
1704 struct em2820 *dev = NULL; 1700 struct em2820 *dev = NULL;
1705 int retval = -ENODEV; 1701 int retval = -ENODEV;
1702 int model,i,nr;
1706 1703
1707 udev = usb_get_dev(interface_to_usbdev(interface)); 1704 udev = usb_get_dev(interface_to_usbdev(interface));
1708 endpoint = &interface->cur_altsetting->endpoint[1].desc; 1705 endpoint = &interface->cur_altsetting->endpoint[1].desc;
1709 1706
1707 /* Don't register audio interfaces */
1708 if (interface->altsetting[1].desc.bInterfaceClass == USB_CLASS_AUDIO)
1709 return -ENODEV;
1710
1710 /* check if the the device has the iso in endpoint at the correct place */ 1711 /* check if the the device has the iso in endpoint at the correct place */
1711 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != 1712 if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) !=
1712 USB_ENDPOINT_XFER_ISOC) { 1713 USB_ENDPOINT_XFER_ISOC) {
1713/* em2820_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n"); */ 1714 em2820_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n");
1714 return -ENODEV; 1715 return -ENODEV;
1715 } 1716 }
1716 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { 1717 if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) {
1717/* em2820_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n"); */ 1718 em2820_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n");
1718 return -ENODEV; 1719 return -ENODEV;
1719 } 1720 }
1720 1721
1722 model=id->driver_info;
1723 nr=interface->minor;
1724
1725 if (nr>EM2820_MAXBOARDS) {
1726 printk ("em2820: Supports only %i em28xx boards.\n",EM2820_MAXBOARDS);
1727 return -ENOMEM;
1728 }
1729
1730 /* allocate memory for our device state and initialize it */
1731 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
1732 if (dev == NULL) {
1733 em2820_err(DRIVER_NAME ": out of memory!\n");
1734 return -ENOMEM;
1735 }
1736 memset(dev, 0, sizeof(*dev));
1737
1738 snprintf(dev->name, 29, "em2820 #%d", nr);
1739
1740 if ((card[nr]>=0)&&(card[nr]<em2820_bcount))
1741 model=card[nr];
1742
1743 if ((model==EM2800_BOARD_UNKNOWN)||(model==EM2820_BOARD_UNKNOWN)) {
1744 printk( "%s: Your board has no eeprom inside it and thus can't\n"
1745 "%s: be autodetected. Please pass card=<n> insmod option to\n"
1746 "%s: workaround that. Redirect complaints to the vendor of\n"
1747 "%s: the TV card. Best regards,\n"
1748 "%s: -- tux\n",
1749 dev->name,dev->name,dev->name,dev->name,dev->name);
1750 printk("%s: Here is a list of valid choices for the card=<n> insmod option:\n",
1751 dev->name);
1752 for (i = 0; i < em2820_bcount; i++) {
1753 printk("%s: card=%d -> %s\n",
1754 dev->name, i, em2820_boards[i].name);
1755 }
1756 }
1757
1721 /* allocate device struct */ 1758 /* allocate device struct */
1722 retval = em2820_init_dev(&dev, udev, interface->minor, id->driver_info); 1759 retval = em2820_init_dev(&dev, udev, nr, model);
1723 if (retval) 1760 if (retval)
1724 return retval; 1761 return retval;
1725 1762
1726 em2820_info("Found %s\n", em2820_boards[id->driver_info].name); 1763 em2820_info("Found %s\n", em2820_boards[model].name);
1727 1764
1728 /* save our data pointer in this interface device */ 1765 /* save our data pointer in this interface device */
1729 usb_set_intfdata(interface, dev); 1766 usb_set_intfdata(interface, dev);
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 7779121a3dea..4115938a1731 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -1,5 +1,5 @@
1/* 1/*
2 em2820-cards.c - driver for Empia EM2820/2840 USB video capture devices 2 em2820-cards.c - driver for Empia EM2800/EM2820/2840 USB video capture devices
3 3
4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com> 4 Copyright (C) 2005 Markus Rechberger <mrechberger@gmail.com>
5 Ludovico Cavedon <cavedon@sssup.it> 5 Ludovico Cavedon <cavedon@sssup.it>
@@ -28,6 +28,23 @@
28#include <linux/videodev.h> 28#include <linux/videodev.h>
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30 30
31/* Boards supported by driver */
32
33#define EM2800_BOARD_UNKNOWN 0
34#define EM2820_BOARD_UNKNOWN 1
35#define EM2820_BOARD_TERRATEC_CINERGY_250 2
36#define EM2820_BOARD_PINNACLE_USB_2 3
37#define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 4
38#define EM2820_BOARD_MSI_VOX_USB_2 5
39#define EM2800_BOARD_TERRATEC_CINERGY_200 6
40#define EM2800_BOARD_LEADTEK_WINFAST_USBII 7
41#define EM2800_BOARD_KWORLD_USB2800 8
42
43#define UNSET -1
44
45/* maximum number of em28xx boards */
46#define EM2820_MAXBOARDS 1 /*FIXME: should be bigger */
47
31/* maximum number of frames that can be queued */ 48/* maximum number of frames that can be queued */
32#define EM2820_NUM_FRAMES 5 49#define EM2820_NUM_FRAMES 5
33/* number of frames that get used for v4l2_read() */ 50/* number of frames that get used for v4l2_read() */
@@ -79,6 +96,9 @@
79/* time to wait when stopping the isoc transfer */ 96/* time to wait when stopping the isoc transfer */
80#define EM2820_URB_TIMEOUT msecs_to_jiffies(EM2820_NUM_BUFS * EM2820_NUM_PACKETS) 97#define EM2820_URB_TIMEOUT msecs_to_jiffies(EM2820_NUM_BUFS * EM2820_NUM_PACKETS)
81 98
99/* time in msecs to wait for i2c writes to finish */
100#define EM2800_I2C_WRITE_TIMEOUT 20
101
82/* the various frame states */ 102/* the various frame states */
83enum em2820_frame_state { 103enum em2820_frame_state {
84 F_UNUSED = 0, 104 F_UNUSED = 0,
@@ -145,12 +165,13 @@ enum em2820_decoder {
145 165
146struct em2820_board { 166struct em2820_board {
147 char *name; 167 char *name;
148 168 unsigned char chip_id;
149 int vchannels; 169 int vchannels;
150 int norm; 170 int norm;
151 int tuner_type; 171 int tuner_type;
152 172
153 /* i2c flags */ 173 /* i2c flags */
174 unsigned int is_em2800;
154 unsigned int tda9887_conf; 175 unsigned int tda9887_conf;
155 176
156 unsigned int has_tuner:1; 177 unsigned int has_tuner:1;
@@ -195,6 +216,7 @@ struct em2820 {
195 /* generic device properties */ 216 /* generic device properties */
196 char name[30]; /* name (including minor) of the device */ 217 char name[30]; /* name (including minor) of the device */
197 int model; /* index in the device_data struct */ 218 int model; /* index in the device_data struct */
219 unsigned int is_em2800;
198 int video_inputs; /* number of video inputs */ 220 int video_inputs; /* number of video inputs */
199 unsigned int has_tuner:1; 221 unsigned int has_tuner:1;
200 unsigned int has_msp34xx:1; 222 unsigned int has_msp34xx:1;
@@ -304,11 +326,14 @@ void em2820_uninit_isoc(struct em2820 *dev);
304int em2820_set_alternate(struct em2820 *dev); 326int em2820_set_alternate(struct em2820 *dev);
305 327
306/* Provided by em2820-cards.c */ 328/* Provided by em2820-cards.c */
329extern int em2800_variant_detect(struct usb_device* udev,int model);
307extern void em2820_card_setup(struct em2820 *dev); 330extern void em2820_card_setup(struct em2820 *dev);
308extern struct em2820_board em2820_boards[]; 331extern struct em2820_board em2820_boards[];
309extern struct usb_device_id em2820_id_table[]; 332extern struct usb_device_id em2820_id_table[];
333extern const unsigned int em2820_bcount;
310 334
311/* em2820 registers */ 335/* em2820 registers */
336#define CHIPID_REG 0x0a
312#define USBSUSP_REG 0x0c /* */ 337#define USBSUSP_REG 0x0c /* */
313 338
314#define AUDIOSRC_REG 0x0e 339#define AUDIOSRC_REG 0x0e