aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/em28xx
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@kernellabs.com>2009-05-16 16:09:28 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-06-16 17:21:08 -0400
commitd18e2fda7133287bf8a81809816e646cf17c332e (patch)
treed42b038af4ed02b31add846f6731dfabb5d78123 /drivers/media/video/em28xx
parent027aa2c771d9fb8dc6aae95c80b50e40e3c97dc5 (diff)
V4L/DVB (11810): em28xx: properly set packet size based on the device's eeprom configuration.
The em28xx actually has a register that tells the driver what the maximum packet size is (based on a value programmed into the eeprom). Make use of that register instead of assuming a hardcoded value of 564 (since 564 is not correct for devices that do QAM such as the KWorld 340u). Note that for now the em2874 code isn't there, falling back to the 564 value, however this is not a problem since there are not any em2874 based devices in the current v4l-dvb tree). Thanks to Jarod Wilson for detecting the initial problem and figuring out that the isoc configuration was wrong for his device. Cc: Jarod Wilson <jarod@wilsonet.com> Signed-off-by: Devin Heitmueller <dheitmueller@kernellabs.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/em28xx')
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c35
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c6
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h16
-rw-r--r--drivers/media/video/em28xx/em28xx.h1
4 files changed, 56 insertions, 2 deletions
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 7375353c04eb..b7a2fedc3904 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -1012,6 +1012,41 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
1012} 1012}
1013EXPORT_SYMBOL_GPL(em28xx_init_isoc); 1013EXPORT_SYMBOL_GPL(em28xx_init_isoc);
1014 1014
1015/* Determine the packet size for the DVB stream for the given device
1016 (underlying value programmed into the eeprom) */
1017int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
1018{
1019 unsigned int chip_cfg2;
1020 unsigned int packet_size = 564;
1021
1022 if (dev->chip_id == CHIP_ID_EM2874) {
1023 /* FIXME - for now assume 564 like it was before, but the
1024 em2874 code should be added to return the proper value... */
1025 packet_size = 564;
1026 } else {
1027 /* TS max packet size stored in bits 1-0 of R01 */
1028 chip_cfg2 = em28xx_read_reg(dev, EM28XX_R01_CHIPCFG2);
1029 switch (chip_cfg2 & EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK) {
1030 case EM28XX_CHIPCFG2_TS_PACKETSIZE_188:
1031 packet_size = 188;
1032 break;
1033 case EM28XX_CHIPCFG2_TS_PACKETSIZE_376:
1034 packet_size = 376;
1035 break;
1036 case EM28XX_CHIPCFG2_TS_PACKETSIZE_564:
1037 packet_size = 564;
1038 break;
1039 case EM28XX_CHIPCFG2_TS_PACKETSIZE_752:
1040 packet_size = 752;
1041 break;
1042 }
1043 }
1044
1045 em28xx_coredbg("dvb max packet size=%d\n", packet_size);
1046 return packet_size;
1047}
1048EXPORT_SYMBOL_GPL(em28xx_isoc_dvb_max_packetsize);
1049
1015/* 1050/*
1016 * em28xx_wake_i2c() 1051 * em28xx_wake_i2c()
1017 * configure i2c attached devices 1052 * configure i2c attached devices
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index c8188dc2b4b5..e0438acf1224 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -46,7 +46,6 @@ if (debug >= level) \
46} while (0) 46} while (0)
47 47
48#define EM28XX_DVB_NUM_BUFS 5 48#define EM28XX_DVB_NUM_BUFS 5
49#define EM28XX_DVB_MAX_PACKETSIZE 564
50#define EM28XX_DVB_MAX_PACKETS 64 49#define EM28XX_DVB_MAX_PACKETS 64
51 50
52struct em28xx_dvb { 51struct em28xx_dvb {
@@ -142,14 +141,17 @@ static int start_streaming(struct em28xx_dvb *dvb)
142{ 141{
143 int rc; 142 int rc;
144 struct em28xx *dev = dvb->adapter.priv; 143 struct em28xx *dev = dvb->adapter.priv;
144 int max_dvb_packet_size;
145 145
146 usb_set_interface(dev->udev, 0, 1); 146 usb_set_interface(dev->udev, 0, 1);
147 rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 147 rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
148 if (rc < 0) 148 if (rc < 0)
149 return rc; 149 return rc;
150 150
151 max_dvb_packet_size = em28xx_isoc_dvb_max_packetsize(dev);
152
151 return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS, 153 return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS,
152 EM28XX_DVB_NUM_BUFS, EM28XX_DVB_MAX_PACKETSIZE, 154 EM28XX_DVB_NUM_BUFS, max_dvb_packet_size,
153 dvb_isoc_copy); 155 dvb_isoc_copy);
154} 156}
155 157
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index 24e39c56811e..a2676d63cfd0 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -27,6 +27,22 @@
27#define EM28XX_CHIPCFG_AC97 0x10 27#define EM28XX_CHIPCFG_AC97 0x10
28#define EM28XX_CHIPCFG_AUDIOMASK 0x30 28#define EM28XX_CHIPCFG_AUDIOMASK 0x30
29 29
30#define EM28XX_R01_CHIPCFG2 0x01
31
32/* em28xx Chip Configuration 2 0x01 */
33#define EM28XX_CHIPCFG2_TS_PRESENT 0x10
34#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_MASK 0x0c /* bits 3-2 */
35#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_1MF 0x00
36#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_2MF 0x04
37#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_4MF 0x08
38#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_8MF 0x0c
39#define EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK 0x03 /* bits 0-1 */
40#define EM28XX_CHIPCFG2_TS_PACKETSIZE_188 0x00
41#define EM28XX_CHIPCFG2_TS_PACKETSIZE_376 0x01
42#define EM28XX_CHIPCFG2_TS_PACKETSIZE_564 0x02
43#define EM28XX_CHIPCFG2_TS_PACKETSIZE_752 0x03
44
45
30 /* GPIO/GPO registers */ 46 /* GPIO/GPO registers */
31#define EM2880_R04_GPO 0x04 /* em2880-em2883 only */ 47#define EM2880_R04_GPO 0x04 /* em2880-em2883 only */
32#define EM28XX_R08_GPIO 0x08 /* em2820 or upper */ 48#define EM28XX_R08_GPIO 0x08 /* em2820 or upper */
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 16f4c23f179b..e801f783bdc3 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -616,6 +616,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
616 int num_bufs, int max_pkt_size, 616 int num_bufs, int max_pkt_size,
617 int (*isoc_copy) (struct em28xx *dev, struct urb *urb)); 617 int (*isoc_copy) (struct em28xx *dev, struct urb *urb));
618void em28xx_uninit_isoc(struct em28xx *dev); 618void em28xx_uninit_isoc(struct em28xx *dev);
619int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev);
619int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); 620int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode);
620int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); 621int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio);
621void em28xx_wake_i2c(struct em28xx *dev); 622void em28xx_wake_i2c(struct em28xx *dev);