diff options
Diffstat (limited to 'drivers/media/video/em28xx')
-rw-r--r-- | drivers/media/video/em28xx/em28xx-audio.c | 21 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-cards.c | 1464 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-core.c | 628 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-dvb.c | 14 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-i2c.c | 49 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-input.c | 311 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-reg.h | 153 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx-video.c | 851 | ||||
-rw-r--r-- | drivers/media/video/em28xx/em28xx.h | 148 |
9 files changed, 2312 insertions, 1327 deletions
diff --git a/drivers/media/video/em28xx/em28xx-audio.c b/drivers/media/video/em28xx/em28xx-audio.c index 7a8d49ef646e..15c03f0e69ad 100644 --- a/drivers/media/video/em28xx/em28xx-audio.c +++ b/drivers/media/video/em28xx/em28xx-audio.c | |||
@@ -424,11 +424,12 @@ static int em28xx_audio_init(struct em28xx *dev) | |||
424 | struct snd_pcm *pcm; | 424 | struct snd_pcm *pcm; |
425 | struct snd_card *card; | 425 | struct snd_card *card; |
426 | static int devnr; | 426 | static int devnr; |
427 | int ret, err; | 427 | int err; |
428 | 428 | ||
429 | if (dev->has_audio_class) { | 429 | if (dev->has_alsa_audio != 1) { |
430 | /* This device does not support the extension (in this case | 430 | /* This device does not support the extension (in this case |
431 | the device is expecting the snd-usb-audio module */ | 431 | the device is expecting the snd-usb-audio module or |
432 | doesn't have analog audio support at all) */ | ||
432 | return 0; | 433 | return 0; |
433 | } | 434 | } |
434 | 435 | ||
@@ -449,7 +450,12 @@ static int em28xx_audio_init(struct em28xx *dev) | |||
449 | } | 450 | } |
450 | 451 | ||
451 | spin_lock_init(&adev->slock); | 452 | spin_lock_init(&adev->slock); |
452 | ret = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); | 453 | err = snd_pcm_new(card, "Em28xx Audio", 0, 0, 1, &pcm); |
454 | if (err < 0) { | ||
455 | snd_card_free(card); | ||
456 | return err; | ||
457 | } | ||
458 | |||
453 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture); | 459 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_em28xx_pcm_capture); |
454 | pcm->info_flags = 0; | 460 | pcm->info_flags = 0; |
455 | pcm->private_data = dev; | 461 | pcm->private_data = dev; |
@@ -461,7 +467,7 @@ static int em28xx_audio_init(struct em28xx *dev) | |||
461 | err = snd_card_register(card); | 467 | err = snd_card_register(card); |
462 | if (err < 0) { | 468 | if (err < 0) { |
463 | snd_card_free(card); | 469 | snd_card_free(card); |
464 | return -ENOMEM; | 470 | return err; |
465 | } | 471 | } |
466 | adev->sndcard = card; | 472 | adev->sndcard = card; |
467 | adev->udev = dev->udev; | 473 | adev->udev = dev->udev; |
@@ -475,9 +481,10 @@ static int em28xx_audio_fini(struct em28xx *dev) | |||
475 | if (dev == NULL) | 481 | if (dev == NULL) |
476 | return 0; | 482 | return 0; |
477 | 483 | ||
478 | if (dev->has_audio_class) { | 484 | if (dev->has_alsa_audio != 1) { |
479 | /* This device does not support the extension (in this case | 485 | /* This device does not support the extension (in this case |
480 | the device is expecting the snd-usb-audio module */ | 486 | the device is expecting the snd-usb-audio module or |
487 | doesn't have analog audio support at all) */ | ||
481 | return 0; | 488 | return 0; |
482 | } | 489 | } |
483 | 490 | ||
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index d65d0572403b..e776699b62f9 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -37,6 +37,8 @@ | |||
37 | 37 | ||
38 | #include "em28xx.h" | 38 | #include "em28xx.h" |
39 | 39 | ||
40 | #define DRIVER_NAME "em28xx" | ||
41 | |||
40 | static int tuner = -1; | 42 | static int tuner = -1; |
41 | module_param(tuner, int, 0444); | 43 | module_param(tuner, int, 0444); |
42 | MODULE_PARM_DESC(tuner, "tuner type"); | 44 | MODULE_PARM_DESC(tuner, "tuner type"); |
@@ -45,122 +47,177 @@ static unsigned int disable_ir; | |||
45 | module_param(disable_ir, int, 0444); | 47 | module_param(disable_ir, int, 0444); |
46 | MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); | 48 | MODULE_PARM_DESC(disable_ir, "disable infrared remote support"); |
47 | 49 | ||
50 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | ||
51 | module_param_array(card, int, NULL, 0444); | ||
52 | MODULE_PARM_DESC(card, "card type"); | ||
53 | |||
54 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ | ||
55 | static unsigned long em28xx_devused; | ||
56 | |||
48 | struct em28xx_hash_table { | 57 | struct em28xx_hash_table { |
49 | unsigned long hash; | 58 | unsigned long hash; |
50 | unsigned int model; | 59 | unsigned int model; |
51 | unsigned int tuner; | 60 | unsigned int tuner; |
52 | }; | 61 | }; |
53 | 62 | ||
63 | /* | ||
64 | * Reset sequences for analog/digital modes | ||
65 | */ | ||
66 | |||
67 | /* Reset for the most [analog] boards */ | ||
68 | static struct em28xx_reg_seq default_analog[] = { | ||
69 | {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, | ||
70 | { -1, -1, -1, -1}, | ||
71 | }; | ||
72 | |||
73 | /* Reset for the most [digital] boards */ | ||
74 | static struct em28xx_reg_seq default_digital[] = { | ||
75 | {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, | ||
76 | { -1, -1, -1, -1}, | ||
77 | }; | ||
78 | |||
79 | /* Board Hauppauge WinTV HVR 900 analog */ | ||
80 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { | ||
81 | {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10}, | ||
82 | {0x05, 0xff, 0x10, 10}, | ||
83 | { -1, -1, -1, -1}, | ||
84 | }; | ||
85 | |||
86 | /* Board Hauppauge WinTV HVR 900 digital */ | ||
87 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { | ||
88 | {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10}, | ||
89 | {EM2880_R04_GPO, 0x04, 0x0f, 10}, | ||
90 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, | ||
91 | { -1, -1, -1, -1}, | ||
92 | }; | ||
93 | |||
94 | /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ | ||
95 | static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { | ||
96 | {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10}, | ||
97 | { -1, -1, -1, -1}, | ||
98 | }; | ||
99 | |||
100 | /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ | ||
101 | |||
102 | /* Board - EM2870 Kworld 355u | ||
103 | Analog - No input analog */ | ||
104 | |||
105 | /* Callback for the most boards */ | ||
106 | static struct em28xx_reg_seq default_tuner_gpio[] = { | ||
107 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, | ||
108 | {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10}, | ||
109 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, | ||
110 | { -1, -1, -1, -1}, | ||
111 | }; | ||
112 | |||
113 | /* | ||
114 | * Board definitions | ||
115 | */ | ||
54 | struct em28xx_board em28xx_boards[] = { | 116 | struct em28xx_board em28xx_boards[] = { |
55 | [EM2750_BOARD_UNKNOWN] = { | 117 | [EM2750_BOARD_UNKNOWN] = { |
56 | .name = "Unknown EM2750/EM2751 webcam grabber", | 118 | .name = "Unknown EM2750/EM2751 webcam grabber", |
57 | .vchannels = 1, | 119 | .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, |
120 | .tuner_type = TUNER_ABSENT, /* This is a webcam */ | ||
58 | .input = { { | 121 | .input = { { |
59 | .type = EM28XX_VMUX_COMPOSITE1, | 122 | .type = EM28XX_VMUX_COMPOSITE1, |
60 | .vmux = 0, | 123 | .vmux = 0, |
61 | .amux = 0, | 124 | .amux = EM28XX_AMUX_VIDEO, |
62 | } }, | 125 | } }, |
63 | }, | 126 | }, |
64 | [EM2800_BOARD_UNKNOWN] = { | 127 | [EM2800_BOARD_UNKNOWN] = { |
65 | .name = "Unknown EM2800 video grabber", | 128 | .name = "Unknown EM2800 video grabber", |
66 | .is_em2800 = 1, | 129 | .is_em2800 = 1, |
67 | .vchannels = 2, | ||
68 | .tda9887_conf = TDA9887_PRESENT, | 130 | .tda9887_conf = TDA9887_PRESENT, |
69 | .decoder = EM28XX_SAA7113, | 131 | .decoder = EM28XX_SAA711X, |
70 | .input = { { | 132 | .tuner_type = TUNER_ABSENT, |
133 | .input = { { | ||
71 | .type = EM28XX_VMUX_COMPOSITE1, | 134 | .type = EM28XX_VMUX_COMPOSITE1, |
72 | .vmux = SAA7115_COMPOSITE0, | 135 | .vmux = SAA7115_COMPOSITE0, |
73 | .amux = 1, | 136 | .amux = EM28XX_AMUX_LINE_IN, |
74 | }, { | 137 | }, { |
75 | .type = EM28XX_VMUX_SVIDEO, | 138 | .type = EM28XX_VMUX_SVIDEO, |
76 | .vmux = SAA7115_SVIDEO3, | 139 | .vmux = SAA7115_SVIDEO3, |
77 | .amux = 1, | 140 | .amux = EM28XX_AMUX_LINE_IN, |
78 | } }, | 141 | } }, |
79 | }, | 142 | }, |
80 | [EM2820_BOARD_UNKNOWN] = { | 143 | [EM2820_BOARD_UNKNOWN] = { |
81 | .name = "Unknown EM2750/28xx video grabber", | 144 | .name = "Unknown EM2750/28xx video grabber", |
82 | .is_em2800 = 0, | 145 | .tuner_type = TUNER_ABSENT, |
83 | .tuner_type = TUNER_ABSENT, | ||
84 | }, | 146 | }, |
85 | [EM2750_BOARD_DLCW_130] = { | 147 | [EM2750_BOARD_DLCW_130] = { |
86 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ | 148 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ |
87 | .name = "Huaqi DLCW-130", | 149 | .name = "Huaqi DLCW-130", |
88 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 150 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
89 | .vchannels = 1, | 151 | .xclk = EM28XX_XCLK_FREQUENCY_48MHZ, |
152 | .tuner_type = TUNER_ABSENT, /* This is a webcam */ | ||
90 | .input = { { | 153 | .input = { { |
91 | .type = EM28XX_VMUX_COMPOSITE1, | 154 | .type = EM28XX_VMUX_COMPOSITE1, |
92 | .vmux = 0, | 155 | .vmux = 0, |
93 | .amux = 0, | 156 | .amux = EM28XX_AMUX_VIDEO, |
94 | } }, | 157 | } }, |
95 | }, | 158 | }, |
96 | [EM2820_BOARD_KWORLD_PVRTV2800RF] = { | 159 | [EM2820_BOARD_KWORLD_PVRTV2800RF] = { |
97 | .name = "Kworld PVR TV 2800 RF", | 160 | .name = "Kworld PVR TV 2800 RF", |
98 | .is_em2800 = 0, | ||
99 | .vchannels = 2, | ||
100 | .tuner_type = TUNER_TEMIC_PAL, | 161 | .tuner_type = TUNER_TEMIC_PAL, |
101 | .tda9887_conf = TDA9887_PRESENT, | 162 | .tda9887_conf = TDA9887_PRESENT, |
102 | .decoder = EM28XX_SAA7113, | 163 | .decoder = EM28XX_SAA711X, |
103 | .input = { { | 164 | .input = { { |
104 | .type = EM28XX_VMUX_COMPOSITE1, | 165 | .type = EM28XX_VMUX_COMPOSITE1, |
105 | .vmux = SAA7115_COMPOSITE0, | 166 | .vmux = SAA7115_COMPOSITE0, |
106 | .amux = 1, | 167 | .amux = EM28XX_AMUX_LINE_IN, |
107 | }, { | 168 | }, { |
108 | .type = EM28XX_VMUX_SVIDEO, | 169 | .type = EM28XX_VMUX_SVIDEO, |
109 | .vmux = SAA7115_SVIDEO3, | 170 | .vmux = SAA7115_SVIDEO3, |
110 | .amux = 1, | 171 | .amux = EM28XX_AMUX_LINE_IN, |
111 | } }, | 172 | } }, |
112 | }, | 173 | }, |
113 | [EM2820_BOARD_TERRATEC_CINERGY_250] = { | 174 | [EM2820_BOARD_TERRATEC_CINERGY_250] = { |
114 | .name = "Terratec Cinergy 250 USB", | 175 | .name = "Terratec Cinergy 250 USB", |
115 | .vchannels = 3, | ||
116 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | 176 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, |
117 | .tda9887_conf = TDA9887_PRESENT, | 177 | .tda9887_conf = TDA9887_PRESENT, |
118 | .decoder = EM28XX_SAA7113, | 178 | .decoder = EM28XX_SAA711X, |
119 | .input = { { | 179 | .input = { { |
120 | .type = EM28XX_VMUX_TELEVISION, | 180 | .type = EM28XX_VMUX_TELEVISION, |
121 | .vmux = SAA7115_COMPOSITE2, | 181 | .vmux = SAA7115_COMPOSITE2, |
122 | .amux = 1, | 182 | .amux = EM28XX_AMUX_LINE_IN, |
123 | }, { | 183 | }, { |
124 | .type = EM28XX_VMUX_COMPOSITE1, | 184 | .type = EM28XX_VMUX_COMPOSITE1, |
125 | .vmux = SAA7115_COMPOSITE0, | 185 | .vmux = SAA7115_COMPOSITE0, |
126 | .amux = 1, | 186 | .amux = EM28XX_AMUX_LINE_IN, |
127 | }, { | 187 | }, { |
128 | .type = EM28XX_VMUX_SVIDEO, | 188 | .type = EM28XX_VMUX_SVIDEO, |
129 | .vmux = SAA7115_SVIDEO3, | 189 | .vmux = SAA7115_SVIDEO3, |
130 | .amux = 1, | 190 | .amux = EM28XX_AMUX_LINE_IN, |
131 | } }, | 191 | } }, |
132 | }, | 192 | }, |
133 | [EM2820_BOARD_PINNACLE_USB_2] = { | 193 | [EM2820_BOARD_PINNACLE_USB_2] = { |
134 | .name = "Pinnacle PCTV USB 2", | 194 | .name = "Pinnacle PCTV USB 2", |
135 | .vchannels = 3, | ||
136 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | 195 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, |
137 | .tda9887_conf = TDA9887_PRESENT, | 196 | .tda9887_conf = TDA9887_PRESENT, |
138 | .decoder = EM28XX_SAA7113, | 197 | .decoder = EM28XX_SAA711X, |
139 | .input = { { | 198 | .input = { { |
140 | .type = EM28XX_VMUX_TELEVISION, | 199 | .type = EM28XX_VMUX_TELEVISION, |
141 | .vmux = SAA7115_COMPOSITE2, | 200 | .vmux = SAA7115_COMPOSITE2, |
142 | .amux = 0, | 201 | .amux = EM28XX_AMUX_VIDEO, |
143 | }, { | 202 | }, { |
144 | .type = EM28XX_VMUX_COMPOSITE1, | 203 | .type = EM28XX_VMUX_COMPOSITE1, |
145 | .vmux = SAA7115_COMPOSITE0, | 204 | .vmux = SAA7115_COMPOSITE0, |
146 | .amux = 1, | 205 | .amux = EM28XX_AMUX_LINE_IN, |
147 | }, { | 206 | }, { |
148 | .type = EM28XX_VMUX_SVIDEO, | 207 | .type = EM28XX_VMUX_SVIDEO, |
149 | .vmux = SAA7115_SVIDEO3, | 208 | .vmux = SAA7115_SVIDEO3, |
150 | .amux = 1, | 209 | .amux = EM28XX_AMUX_LINE_IN, |
151 | } }, | 210 | } }, |
152 | }, | 211 | }, |
153 | [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = { | 212 | [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = { |
154 | .name = "Hauppauge WinTV USB 2", | 213 | .name = "Hauppauge WinTV USB 2", |
155 | .vchannels = 3, | ||
156 | .tuner_type = TUNER_PHILIPS_FM1236_MK3, | 214 | .tuner_type = TUNER_PHILIPS_FM1236_MK3, |
157 | .tda9887_conf = TDA9887_PRESENT | | 215 | .tda9887_conf = TDA9887_PRESENT | |
158 | TDA9887_PORT1_ACTIVE| | 216 | TDA9887_PORT1_ACTIVE| |
159 | TDA9887_PORT2_ACTIVE, | 217 | TDA9887_PORT2_ACTIVE, |
160 | .decoder = EM28XX_TVP5150, | 218 | .decoder = EM28XX_TVP5150, |
161 | .has_msp34xx = 1, | 219 | .has_msp34xx = 1, |
162 | /*FIXME: S-Video not tested */ | 220 | .input = { { |
163 | .input = { { | ||
164 | .type = EM28XX_VMUX_TELEVISION, | 221 | .type = EM28XX_VMUX_TELEVISION, |
165 | .vmux = TVP5150_COMPOSITE0, | 222 | .vmux = TVP5150_COMPOSITE0, |
166 | .amux = MSP_INPUT_DEFAULT, | 223 | .amux = MSP_INPUT_DEFAULT, |
@@ -174,327 +231,305 @@ struct em28xx_board em28xx_boards[] = { | |||
174 | [EM2820_BOARD_DLINK_USB_TV] = { | 231 | [EM2820_BOARD_DLINK_USB_TV] = { |
175 | .name = "D-Link DUB-T210 TV Tuner", | 232 | .name = "D-Link DUB-T210 TV Tuner", |
176 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 233 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
177 | .vchannels = 3, | ||
178 | .is_em2800 = 0, | ||
179 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | 234 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, |
180 | .tda9887_conf = TDA9887_PRESENT, | 235 | .tda9887_conf = TDA9887_PRESENT, |
181 | .decoder = EM28XX_SAA7113, | 236 | .decoder = EM28XX_SAA711X, |
182 | .input = { { | 237 | .input = { { |
183 | .type = EM28XX_VMUX_TELEVISION, | 238 | .type = EM28XX_VMUX_TELEVISION, |
184 | .vmux = SAA7115_COMPOSITE2, | 239 | .vmux = SAA7115_COMPOSITE2, |
185 | .amux = 1, | 240 | .amux = EM28XX_AMUX_LINE_IN, |
186 | }, { | 241 | }, { |
187 | .type = EM28XX_VMUX_COMPOSITE1, | 242 | .type = EM28XX_VMUX_COMPOSITE1, |
188 | .vmux = SAA7115_COMPOSITE0, | 243 | .vmux = SAA7115_COMPOSITE0, |
189 | .amux = 1, | 244 | .amux = EM28XX_AMUX_LINE_IN, |
190 | }, { | 245 | }, { |
191 | .type = EM28XX_VMUX_SVIDEO, | 246 | .type = EM28XX_VMUX_SVIDEO, |
192 | .vmux = SAA7115_SVIDEO3, | 247 | .vmux = SAA7115_SVIDEO3, |
193 | .amux = 1, | 248 | .amux = EM28XX_AMUX_LINE_IN, |
194 | } }, | 249 | } }, |
195 | }, | 250 | }, |
196 | [EM2820_BOARD_HERCULES_SMART_TV_USB2] = { | 251 | [EM2820_BOARD_HERCULES_SMART_TV_USB2] = { |
197 | .name = "Hercules Smart TV USB 2.0", | 252 | .name = "Hercules Smart TV USB 2.0", |
198 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 253 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
199 | .vchannels = 3, | ||
200 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | 254 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, |
201 | .tda9887_conf = TDA9887_PRESENT, | 255 | .tda9887_conf = TDA9887_PRESENT, |
202 | .decoder = EM28XX_SAA7113, | 256 | .decoder = EM28XX_SAA711X, |
203 | .input = { { | 257 | .input = { { |
204 | .type = EM28XX_VMUX_TELEVISION, | 258 | .type = EM28XX_VMUX_TELEVISION, |
205 | .vmux = SAA7115_COMPOSITE2, | 259 | .vmux = SAA7115_COMPOSITE2, |
206 | .amux = 1, | 260 | .amux = EM28XX_AMUX_LINE_IN, |
207 | }, { | 261 | }, { |
208 | .type = EM28XX_VMUX_COMPOSITE1, | 262 | .type = EM28XX_VMUX_COMPOSITE1, |
209 | .vmux = SAA7115_COMPOSITE0, | 263 | .vmux = SAA7115_COMPOSITE0, |
210 | .amux = 1, | 264 | .amux = EM28XX_AMUX_LINE_IN, |
211 | }, { | 265 | }, { |
212 | .type = EM28XX_VMUX_SVIDEO, | 266 | .type = EM28XX_VMUX_SVIDEO, |
213 | .vmux = SAA7115_SVIDEO3, | 267 | .vmux = SAA7115_SVIDEO3, |
214 | .amux = 1, | 268 | .amux = EM28XX_AMUX_LINE_IN, |
215 | } }, | 269 | } }, |
216 | }, | 270 | }, |
217 | [EM2820_BOARD_PINNACLE_USB_2_FM1216ME] = { | 271 | [EM2820_BOARD_PINNACLE_USB_2_FM1216ME] = { |
218 | .name = "Pinnacle PCTV USB 2 (Philips FM1216ME)", | 272 | .name = "Pinnacle PCTV USB 2 (Philips FM1216ME)", |
219 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 273 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
220 | .vchannels = 3, | ||
221 | .is_em2800 = 0, | ||
222 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 274 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
223 | .tda9887_conf = TDA9887_PRESENT, | 275 | .tda9887_conf = TDA9887_PRESENT, |
224 | .decoder = EM28XX_SAA7113, | 276 | .decoder = EM28XX_SAA711X, |
225 | .input = { { | 277 | .input = { { |
226 | .type = EM28XX_VMUX_TELEVISION, | 278 | .type = EM28XX_VMUX_TELEVISION, |
227 | .vmux = SAA7115_COMPOSITE2, | 279 | .vmux = SAA7115_COMPOSITE2, |
228 | .amux = 0, | 280 | .amux = EM28XX_AMUX_VIDEO, |
229 | }, { | 281 | }, { |
230 | .type = EM28XX_VMUX_COMPOSITE1, | 282 | .type = EM28XX_VMUX_COMPOSITE1, |
231 | .vmux = SAA7115_COMPOSITE0, | 283 | .vmux = SAA7115_COMPOSITE0, |
232 | .amux = 1, | 284 | .amux = EM28XX_AMUX_LINE_IN, |
233 | }, { | 285 | }, { |
234 | .type = EM28XX_VMUX_SVIDEO, | 286 | .type = EM28XX_VMUX_SVIDEO, |
235 | .vmux = SAA7115_SVIDEO3, | 287 | .vmux = SAA7115_SVIDEO3, |
236 | .amux = 1, | 288 | .amux = EM28XX_AMUX_LINE_IN, |
237 | } }, | 289 | } }, |
238 | }, | 290 | }, |
239 | [EM2820_BOARD_GADMEI_UTV310] = { | 291 | [EM2820_BOARD_GADMEI_UTV310] = { |
240 | .name = "Gadmei UTV310", | 292 | .name = "Gadmei UTV310", |
241 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 293 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
242 | .vchannels = 3, | ||
243 | .tuner_type = TUNER_TNF_5335MF, | 294 | .tuner_type = TUNER_TNF_5335MF, |
244 | .tda9887_conf = TDA9887_PRESENT, | 295 | .tda9887_conf = TDA9887_PRESENT, |
245 | .decoder = EM28XX_SAA7113, | 296 | .decoder = EM28XX_SAA711X, |
246 | .input = { { | 297 | .input = { { |
247 | .type = EM28XX_VMUX_TELEVISION, | 298 | .type = EM28XX_VMUX_TELEVISION, |
248 | .vmux = SAA7115_COMPOSITE1, | 299 | .vmux = SAA7115_COMPOSITE1, |
249 | .amux = 1, | 300 | .amux = EM28XX_AMUX_LINE_IN, |
250 | }, { | 301 | }, { |
251 | .type = EM28XX_VMUX_COMPOSITE1, | 302 | .type = EM28XX_VMUX_COMPOSITE1, |
252 | .vmux = SAA7115_COMPOSITE0, | 303 | .vmux = SAA7115_COMPOSITE0, |
253 | .amux = 1, | 304 | .amux = EM28XX_AMUX_LINE_IN, |
254 | }, { | 305 | }, { |
255 | .type = EM28XX_VMUX_SVIDEO, | 306 | .type = EM28XX_VMUX_SVIDEO, |
256 | .vmux = SAA7115_SVIDEO3, | 307 | .vmux = SAA7115_SVIDEO3, |
257 | .amux = 1, | 308 | .amux = EM28XX_AMUX_LINE_IN, |
258 | } }, | 309 | } }, |
259 | }, | 310 | }, |
260 | [EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE] = { | 311 | [EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE] = { |
261 | .name = "Leadtek Winfast USB II Deluxe", | 312 | .name = "Leadtek Winfast USB II Deluxe", |
262 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 313 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
263 | .vchannels = 3, | ||
264 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 314 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
265 | .tda9887_conf = TDA9887_PRESENT, | 315 | .tda9887_conf = TDA9887_PRESENT, |
266 | .decoder = EM28XX_SAA7114, | 316 | .decoder = EM28XX_SAA711X, |
267 | .input = { { | 317 | .input = { { |
268 | .type = EM28XX_VMUX_TELEVISION, | 318 | .type = EM28XX_VMUX_TELEVISION, |
269 | .vmux = 2, | 319 | .vmux = SAA7115_COMPOSITE2, |
270 | .amux = 0, | 320 | .amux = EM28XX_AMUX_VIDEO, |
271 | }, { | 321 | }, { |
272 | .type = EM28XX_VMUX_COMPOSITE1, | 322 | .type = EM28XX_VMUX_COMPOSITE1, |
273 | .vmux = 0, | ||
274 | .amux = 1, | ||
275 | }, { | ||
276 | .type = EM28XX_VMUX_SVIDEO, | ||
277 | .vmux = 9, | ||
278 | .amux = 1, | ||
279 | } }, | ||
280 | }, | ||
281 | [EM2820_BOARD_PINNACLE_DVC_100] = { | ||
282 | .name = "Pinnacle Dazzle DVC 100", | ||
283 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
284 | .vchannels = 3, | ||
285 | .decoder = EM28XX_SAA7113, | ||
286 | .input = { { | ||
287 | .type = EM28XX_VMUX_COMPOSITE1, | ||
288 | .vmux = SAA7115_COMPOSITE0, | 323 | .vmux = SAA7115_COMPOSITE0, |
289 | .amux = 1, | 324 | .amux = EM28XX_AMUX_LINE_IN, |
290 | }, { | 325 | }, { |
291 | .type = EM28XX_VMUX_SVIDEO, | 326 | .type = EM28XX_VMUX_SVIDEO, |
292 | .vmux = SAA7115_SVIDEO3, | 327 | .vmux = SAA7115_COMPOSITE0, |
293 | .amux = 1, | 328 | .amux = EM28XX_AMUX_LINE_IN, |
294 | } }, | 329 | } }, |
295 | }, | 330 | }, |
296 | [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = { | 331 | [EM2820_BOARD_VIDEOLOGY_20K14XUSB] = { |
297 | .name = "Videology 20K14XUSB USB2.0", | 332 | .name = "Videology 20K14XUSB USB2.0", |
298 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 333 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
299 | .vchannels = 1, | 334 | .tuner_type = TUNER_ABSENT, /* This is a webcam */ |
300 | .input = { { | 335 | .input = { { |
301 | .type = EM28XX_VMUX_COMPOSITE1, | 336 | .type = EM28XX_VMUX_COMPOSITE1, |
302 | .vmux = 0, | 337 | .vmux = 0, |
303 | .amux = 0, | 338 | .amux = EM28XX_AMUX_VIDEO, |
304 | } }, | 339 | } }, |
305 | }, | 340 | }, |
306 | [EM2821_BOARD_PROLINK_PLAYTV_USB2] = { | 341 | [EM2821_BOARD_PROLINK_PLAYTV_USB2] = { |
307 | .name = "SIIG AVTuner-PVR/Prolink PlayTV USB 2.0", | 342 | .name = "SIIG AVTuner-PVR/Prolink PlayTV USB 2.0", |
308 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 343 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
309 | .vchannels = 3, | ||
310 | .is_em2800 = 0, | ||
311 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, /* unknown? */ | 344 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, /* unknown? */ |
312 | .tda9887_conf = TDA9887_PRESENT, /* unknown? */ | 345 | .tda9887_conf = TDA9887_PRESENT, /* unknown? */ |
313 | .decoder = EM28XX_SAA7113, | 346 | .decoder = EM28XX_SAA711X, |
314 | .input = { { | 347 | .input = { { |
315 | .type = EM28XX_VMUX_TELEVISION, | 348 | .type = EM28XX_VMUX_TELEVISION, |
316 | .vmux = SAA7115_COMPOSITE2, | 349 | .vmux = SAA7115_COMPOSITE2, |
317 | .amux = 1, | 350 | .amux = EM28XX_AMUX_LINE_IN, |
318 | }, { | 351 | }, { |
319 | .type = EM28XX_VMUX_COMPOSITE1, | 352 | .type = EM28XX_VMUX_COMPOSITE1, |
320 | .vmux = SAA7115_COMPOSITE0, | 353 | .vmux = SAA7115_COMPOSITE0, |
321 | .amux = 1, | 354 | .amux = EM28XX_AMUX_LINE_IN, |
322 | }, { | 355 | }, { |
323 | .type = EM28XX_VMUX_SVIDEO, | 356 | .type = EM28XX_VMUX_SVIDEO, |
324 | .vmux = SAA7115_SVIDEO3, | 357 | .vmux = SAA7115_SVIDEO3, |
325 | .amux = 1, | 358 | .amux = EM28XX_AMUX_LINE_IN, |
326 | } }, | 359 | } }, |
327 | }, | 360 | }, |
328 | [EM2821_BOARD_SUPERCOMP_USB_2] = { | 361 | [EM2821_BOARD_SUPERCOMP_USB_2] = { |
329 | .name = "Supercomp USB 2.0 TV", | 362 | .name = "Supercomp USB 2.0 TV", |
330 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 363 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
331 | .vchannels = 3, | ||
332 | .is_em2800 = 0, | ||
333 | .tuner_type = TUNER_PHILIPS_FM1236_MK3, | 364 | .tuner_type = TUNER_PHILIPS_FM1236_MK3, |
334 | .tda9887_conf = TDA9887_PRESENT | | 365 | .tda9887_conf = TDA9887_PRESENT | |
335 | TDA9887_PORT1_ACTIVE | | 366 | TDA9887_PORT1_ACTIVE | |
336 | TDA9887_PORT2_ACTIVE, | 367 | TDA9887_PORT2_ACTIVE, |
337 | .decoder = EM28XX_SAA7113, | 368 | .decoder = EM28XX_SAA711X, |
338 | .input = { { | 369 | .input = { { |
339 | .type = EM28XX_VMUX_TELEVISION, | 370 | .type = EM28XX_VMUX_TELEVISION, |
340 | .vmux = SAA7115_COMPOSITE2, | 371 | .vmux = SAA7115_COMPOSITE2, |
341 | .amux = 1, | 372 | .amux = EM28XX_AMUX_LINE_IN, |
342 | }, { | 373 | }, { |
343 | .type = EM28XX_VMUX_COMPOSITE1, | 374 | .type = EM28XX_VMUX_COMPOSITE1, |
344 | .vmux = SAA7115_COMPOSITE0, | 375 | .vmux = SAA7115_COMPOSITE0, |
345 | .amux = 0, | 376 | .amux = EM28XX_AMUX_VIDEO, |
346 | }, { | 377 | }, { |
347 | .type = EM28XX_VMUX_SVIDEO, | 378 | .type = EM28XX_VMUX_SVIDEO, |
348 | .vmux = SAA7115_SVIDEO3, | 379 | .vmux = SAA7115_SVIDEO3, |
349 | .amux = 1, | 380 | .amux = EM28XX_AMUX_LINE_IN, |
350 | } }, | 381 | } }, |
351 | }, | 382 | }, |
352 | [EM2821_BOARD_USBGEAR_VD204] = { | 383 | [EM2821_BOARD_USBGEAR_VD204] = { |
353 | .name = "Usbgear VD204v9", | 384 | .name = "Usbgear VD204v9", |
354 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 385 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
355 | .vchannels = 2, | 386 | .tuner_type = TUNER_ABSENT, /* Capture only device */ |
356 | .decoder = EM28XX_SAA7113, | 387 | .decoder = EM28XX_SAA711X, |
357 | .input = { { | 388 | .input = { { |
358 | .type = EM28XX_VMUX_COMPOSITE1, | 389 | .type = EM28XX_VMUX_COMPOSITE1, |
359 | .vmux = SAA7115_COMPOSITE0, | 390 | .vmux = SAA7115_COMPOSITE0, |
360 | .amux = 1, | 391 | .amux = EM28XX_AMUX_LINE_IN, |
361 | }, { | 392 | }, { |
362 | .type = EM28XX_VMUX_SVIDEO, | 393 | .type = EM28XX_VMUX_SVIDEO, |
363 | .vmux = SAA7115_SVIDEO3, | 394 | .vmux = SAA7115_SVIDEO3, |
364 | .amux = 1, | 395 | .amux = EM28XX_AMUX_LINE_IN, |
365 | } }, | 396 | } }, |
366 | }, | 397 | }, |
367 | [EM2860_BOARD_NETGMBH_CAM] = { | 398 | [EM2860_BOARD_NETGMBH_CAM] = { |
368 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ | 399 | /* Beijing Huaqi Information Digital Technology Co., Ltd */ |
369 | .name = "NetGMBH Cam", | 400 | .name = "NetGMBH Cam", |
370 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 401 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
371 | .vchannels = 1, | 402 | .tuner_type = TUNER_ABSENT, /* This is a webcam */ |
372 | .input = { { | 403 | .input = { { |
373 | .type = EM28XX_VMUX_COMPOSITE1, | 404 | .type = EM28XX_VMUX_COMPOSITE1, |
374 | .vmux = 0, | 405 | .vmux = 0, |
375 | .amux = 0, | 406 | .amux = EM28XX_AMUX_VIDEO, |
376 | } }, | 407 | } }, |
377 | }, | 408 | }, |
378 | [EM2860_BOARD_TYPHOON_DVD_MAKER] = { | 409 | [EM2860_BOARD_TYPHOON_DVD_MAKER] = { |
379 | .name = "Typhoon DVD Maker", | 410 | .name = "Typhoon DVD Maker", |
380 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 411 | .decoder = EM28XX_SAA711X, |
381 | .vchannels = 2, | 412 | .tuner_type = TUNER_ABSENT, /* Capture only device */ |
382 | .decoder = EM28XX_SAA7113, | 413 | .input = { { |
383 | .input = { { | ||
384 | .type = EM28XX_VMUX_COMPOSITE1, | 414 | .type = EM28XX_VMUX_COMPOSITE1, |
385 | .vmux = SAA7115_COMPOSITE0, | 415 | .vmux = SAA7115_COMPOSITE0, |
386 | .amux = 1, | 416 | .amux = EM28XX_AMUX_LINE_IN, |
387 | }, { | 417 | }, { |
388 | .type = EM28XX_VMUX_SVIDEO, | 418 | .type = EM28XX_VMUX_SVIDEO, |
389 | .vmux = SAA7115_SVIDEO3, | 419 | .vmux = SAA7115_SVIDEO3, |
390 | .amux = 1, | 420 | .amux = EM28XX_AMUX_LINE_IN, |
391 | } }, | 421 | } }, |
392 | }, | 422 | }, |
393 | [EM2860_BOARD_GADMEI_UTV330] = { | 423 | [EM2860_BOARD_GADMEI_UTV330] = { |
394 | .name = "Gadmei UTV330", | 424 | .name = "Gadmei UTV330", |
395 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 425 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
396 | .vchannels = 3, | ||
397 | .tuner_type = TUNER_TNF_5335MF, | 426 | .tuner_type = TUNER_TNF_5335MF, |
398 | .tda9887_conf = TDA9887_PRESENT, | 427 | .tda9887_conf = TDA9887_PRESENT, |
399 | .decoder = EM28XX_SAA7113, | 428 | .decoder = EM28XX_SAA711X, |
400 | .input = { { | 429 | .input = { { |
401 | .type = EM28XX_VMUX_TELEVISION, | 430 | .type = EM28XX_VMUX_TELEVISION, |
402 | .vmux = SAA7115_COMPOSITE2, | 431 | .vmux = SAA7115_COMPOSITE2, |
403 | .amux = 0, | 432 | .amux = EM28XX_AMUX_VIDEO, |
404 | }, { | 433 | }, { |
405 | .type = EM28XX_VMUX_COMPOSITE1, | 434 | .type = EM28XX_VMUX_COMPOSITE1, |
406 | .vmux = SAA7115_COMPOSITE0, | 435 | .vmux = SAA7115_COMPOSITE0, |
407 | .amux = 1, | 436 | .amux = EM28XX_AMUX_LINE_IN, |
408 | }, { | 437 | }, { |
409 | .type = EM28XX_VMUX_SVIDEO, | 438 | .type = EM28XX_VMUX_SVIDEO, |
410 | .vmux = SAA7115_SVIDEO3, | 439 | .vmux = SAA7115_SVIDEO3, |
411 | .amux = 1, | 440 | .amux = EM28XX_AMUX_LINE_IN, |
412 | } }, | 441 | } }, |
413 | }, | 442 | }, |
414 | [EM2860_BOARD_TERRATEC_HYBRID_XS] = { | 443 | [EM2860_BOARD_TERRATEC_HYBRID_XS] = { |
415 | .name = "Terratec Cinergy A Hybrid XS", | 444 | .name = "Terratec Cinergy A Hybrid XS", |
416 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 445 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
417 | .vchannels = 3, | ||
418 | .tuner_type = TUNER_XC2028, | 446 | .tuner_type = TUNER_XC2028, |
447 | .tuner_gpio = default_tuner_gpio, | ||
419 | .decoder = EM28XX_TVP5150, | 448 | .decoder = EM28XX_TVP5150, |
420 | .input = { { | 449 | |
450 | .input = { { | ||
421 | .type = EM28XX_VMUX_TELEVISION, | 451 | .type = EM28XX_VMUX_TELEVISION, |
422 | .vmux = TVP5150_COMPOSITE0, | 452 | .vmux = TVP5150_COMPOSITE0, |
423 | .amux = 0, | 453 | .amux = EM28XX_AMUX_VIDEO, |
454 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
424 | }, { | 455 | }, { |
425 | .type = EM28XX_VMUX_COMPOSITE1, | 456 | .type = EM28XX_VMUX_COMPOSITE1, |
426 | .vmux = TVP5150_COMPOSITE1, | 457 | .vmux = TVP5150_COMPOSITE1, |
427 | .amux = 1, | 458 | .amux = EM28XX_AMUX_LINE_IN, |
459 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
428 | }, { | 460 | }, { |
429 | .type = EM28XX_VMUX_SVIDEO, | 461 | .type = EM28XX_VMUX_SVIDEO, |
430 | .vmux = TVP5150_SVIDEO, | 462 | .vmux = TVP5150_SVIDEO, |
431 | .amux = 1, | 463 | .amux = EM28XX_AMUX_LINE_IN, |
464 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
432 | } }, | 465 | } }, |
433 | }, | 466 | }, |
434 | [EM2861_BOARD_KWORLD_PVRTV_300U] = { | 467 | [EM2861_BOARD_KWORLD_PVRTV_300U] = { |
435 | .name = "KWorld PVRTV 300U", | 468 | .name = "KWorld PVRTV 300U", |
436 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 469 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
437 | .vchannels = 3, | ||
438 | .tuner_type = TUNER_XC2028, | 470 | .tuner_type = TUNER_XC2028, |
471 | .tuner_gpio = default_tuner_gpio, | ||
439 | .decoder = EM28XX_TVP5150, | 472 | .decoder = EM28XX_TVP5150, |
440 | .input = { { | 473 | .input = { { |
441 | .type = EM28XX_VMUX_TELEVISION, | 474 | .type = EM28XX_VMUX_TELEVISION, |
442 | .vmux = TVP5150_COMPOSITE0, | 475 | .vmux = TVP5150_COMPOSITE0, |
443 | .amux = 0, | 476 | .amux = EM28XX_AMUX_VIDEO, |
444 | }, { | 477 | }, { |
445 | .type = EM28XX_VMUX_COMPOSITE1, | 478 | .type = EM28XX_VMUX_COMPOSITE1, |
446 | .vmux = TVP5150_COMPOSITE1, | 479 | .vmux = TVP5150_COMPOSITE1, |
447 | .amux = 1, | 480 | .amux = EM28XX_AMUX_LINE_IN, |
448 | }, { | 481 | }, { |
449 | .type = EM28XX_VMUX_SVIDEO, | 482 | .type = EM28XX_VMUX_SVIDEO, |
450 | .vmux = TVP5150_SVIDEO, | 483 | .vmux = TVP5150_SVIDEO, |
451 | .amux = 1, | 484 | .amux = EM28XX_AMUX_LINE_IN, |
452 | } }, | 485 | } }, |
453 | }, | 486 | }, |
454 | [EM2861_BOARD_YAKUMO_MOVIE_MIXER] = { | 487 | [EM2861_BOARD_YAKUMO_MOVIE_MIXER] = { |
455 | .name = "Yakumo MovieMixer", | 488 | .name = "Yakumo MovieMixer", |
456 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 489 | .tuner_type = TUNER_ABSENT, /* Capture only device */ |
457 | .vchannels = 1, | ||
458 | .decoder = EM28XX_TVP5150, | 490 | .decoder = EM28XX_TVP5150, |
459 | .input = { { | 491 | .input = { { |
460 | .type = EM28XX_VMUX_TELEVISION, | 492 | .type = EM28XX_VMUX_TELEVISION, |
461 | .vmux = TVP5150_COMPOSITE0, | 493 | .vmux = TVP5150_COMPOSITE0, |
462 | .amux = 0, | 494 | .amux = EM28XX_AMUX_VIDEO, |
463 | }, { | 495 | }, { |
464 | .type = EM28XX_VMUX_COMPOSITE1, | 496 | .type = EM28XX_VMUX_COMPOSITE1, |
465 | .vmux = TVP5150_COMPOSITE1, | 497 | .vmux = TVP5150_COMPOSITE1, |
466 | .amux = 1, | 498 | .amux = EM28XX_AMUX_LINE_IN, |
467 | }, { | 499 | }, { |
468 | .type = EM28XX_VMUX_SVIDEO, | 500 | .type = EM28XX_VMUX_SVIDEO, |
469 | .vmux = TVP5150_SVIDEO, | 501 | .vmux = TVP5150_SVIDEO, |
470 | .amux = 1, | 502 | .amux = EM28XX_AMUX_LINE_IN, |
471 | } }, | 503 | } }, |
472 | }, | 504 | }, |
473 | [EM2861_BOARD_PLEXTOR_PX_TV100U] = { | 505 | [EM2861_BOARD_PLEXTOR_PX_TV100U] = { |
474 | .name = "Plextor ConvertX PX-TV100U", | 506 | .name = "Plextor ConvertX PX-TV100U", |
475 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 507 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
476 | .vchannels = 3, | ||
477 | .tuner_type = TUNER_TNF_5335MF, | 508 | .tuner_type = TUNER_TNF_5335MF, |
478 | .tda9887_conf = TDA9887_PRESENT, | 509 | .tda9887_conf = TDA9887_PRESENT, |
479 | .decoder = EM28XX_TVP5150, | 510 | .decoder = EM28XX_TVP5150, |
480 | .input = { { | 511 | .input = { { |
481 | .type = EM28XX_VMUX_TELEVISION, | 512 | .type = EM28XX_VMUX_TELEVISION, |
482 | .vmux = TVP5150_COMPOSITE0, | 513 | .vmux = TVP5150_COMPOSITE0, |
483 | .amux = 1, | 514 | .amux = EM28XX_AMUX_LINE_IN, |
484 | }, { | 515 | }, { |
485 | .type = EM28XX_VMUX_COMPOSITE1, | 516 | .type = EM28XX_VMUX_COMPOSITE1, |
486 | .vmux = TVP5150_COMPOSITE1, | 517 | .vmux = TVP5150_COMPOSITE1, |
487 | .amux = 1, | 518 | .amux = EM28XX_AMUX_LINE_IN, |
488 | }, { | 519 | }, { |
489 | .type = EM28XX_VMUX_SVIDEO, | 520 | .type = EM28XX_VMUX_SVIDEO, |
490 | .vmux = TVP5150_SVIDEO, | 521 | .vmux = TVP5150_SVIDEO, |
491 | .amux = 1, | 522 | .amux = EM28XX_AMUX_LINE_IN, |
492 | } }, | 523 | } }, |
493 | }, | 524 | }, |
525 | |||
526 | /* Those boards with em2870 are DVB Only*/ | ||
527 | |||
494 | [EM2870_BOARD_TERRATEC_XS] = { | 528 | [EM2870_BOARD_TERRATEC_XS] = { |
495 | .name = "Terratec Cinergy T XS", | 529 | .name = "Terratec Cinergy T XS", |
496 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 530 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
497 | .tuner_type = TUNER_XC2028, | 531 | .tuner_type = TUNER_XC2028, |
532 | .tuner_gpio = default_tuner_gpio, | ||
498 | }, | 533 | }, |
499 | [EM2870_BOARD_TERRATEC_XS_MT2060] = { | 534 | [EM2870_BOARD_TERRATEC_XS_MT2060] = { |
500 | .name = "Terratec Cinergy T XS (MT2060)", | 535 | .name = "Terratec Cinergy T XS (MT2060)", |
@@ -505,6 +540,7 @@ struct em28xx_board em28xx_boards[] = { | |||
505 | .name = "Kworld 350 U DVB-T", | 540 | .name = "Kworld 350 U DVB-T", |
506 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 541 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
507 | .tuner_type = TUNER_XC2028, | 542 | .tuner_type = TUNER_XC2028, |
543 | .tuner_gpio = default_tuner_gpio, | ||
508 | }, | 544 | }, |
509 | [EM2870_BOARD_KWORLD_355U] = { | 545 | [EM2870_BOARD_KWORLD_355U] = { |
510 | .name = "Kworld 355 U DVB-T", | 546 | .name = "Kworld 355 U DVB-T", |
@@ -514,164 +550,216 @@ struct em28xx_board em28xx_boards[] = { | |||
514 | .name = "Pinnacle PCTV DVB-T", | 550 | .name = "Pinnacle PCTV DVB-T", |
515 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 551 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
516 | .tuner_type = TUNER_ABSENT, /* MT2060 */ | 552 | .tuner_type = TUNER_ABSENT, /* MT2060 */ |
553 | /* djh - I have serious doubts this is right... */ | ||
554 | .xclk = EM28XX_XCLK_IR_RC5_MODE | | ||
555 | EM28XX_XCLK_FREQUENCY_10MHZ, | ||
517 | }, | 556 | }, |
518 | [EM2870_BOARD_COMPRO_VIDEOMATE] = { | 557 | [EM2870_BOARD_COMPRO_VIDEOMATE] = { |
519 | .name = "Compro, VideoMate U3", | 558 | .name = "Compro, VideoMate U3", |
520 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 559 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
521 | .tuner_type = TUNER_ABSENT, /* MT2060 */ | 560 | .tuner_type = TUNER_ABSENT, /* MT2060 */ |
522 | }, | 561 | }, |
562 | |||
523 | [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = { | 563 | [EM2880_BOARD_TERRATEC_HYBRID_XS_FR] = { |
524 | .name = "Terratec Hybrid XS Secam", | 564 | .name = "Terratec Hybrid XS Secam", |
525 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 565 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
526 | .vchannels = 3, | ||
527 | .has_msp34xx = 1, | 566 | .has_msp34xx = 1, |
528 | .tuner_type = TUNER_XC2028, | 567 | .tuner_type = TUNER_XC2028, |
568 | .tuner_gpio = default_tuner_gpio, | ||
529 | .decoder = EM28XX_TVP5150, | 569 | .decoder = EM28XX_TVP5150, |
530 | .input = { { | 570 | .input = { { |
531 | .type = EM28XX_VMUX_TELEVISION, | 571 | .type = EM28XX_VMUX_TELEVISION, |
532 | .vmux = TVP5150_COMPOSITE0, | 572 | .vmux = TVP5150_COMPOSITE0, |
533 | .amux = 0, | 573 | .amux = EM28XX_AMUX_VIDEO, |
574 | .gpio = default_analog, | ||
534 | }, { | 575 | }, { |
535 | .type = EM28XX_VMUX_COMPOSITE1, | 576 | .type = EM28XX_VMUX_COMPOSITE1, |
536 | .vmux = TVP5150_COMPOSITE1, | 577 | .vmux = TVP5150_COMPOSITE1, |
537 | .amux = 1, | 578 | .amux = EM28XX_AMUX_LINE_IN, |
579 | .gpio = default_analog, | ||
538 | }, { | 580 | }, { |
539 | .type = EM28XX_VMUX_SVIDEO, | 581 | .type = EM28XX_VMUX_SVIDEO, |
540 | .vmux = TVP5150_SVIDEO, | 582 | .vmux = TVP5150_SVIDEO, |
541 | .amux = 1, | 583 | .amux = EM28XX_AMUX_LINE_IN, |
584 | .gpio = default_analog, | ||
542 | } }, | 585 | } }, |
543 | }, | 586 | }, |
544 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { | 587 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = { |
545 | .name = "Hauppauge WinTV HVR 900", | 588 | .name = "Hauppauge WinTV HVR 900", |
546 | .vchannels = 3, | ||
547 | .tda9887_conf = TDA9887_PRESENT, | 589 | .tda9887_conf = TDA9887_PRESENT, |
548 | .tuner_type = TUNER_XC2028, | 590 | .tuner_type = TUNER_XC2028, |
591 | .tuner_gpio = default_tuner_gpio, | ||
549 | .mts_firmware = 1, | 592 | .mts_firmware = 1, |
550 | .has_dvb = 1, | 593 | .has_dvb = 1, |
594 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
551 | .decoder = EM28XX_TVP5150, | 595 | .decoder = EM28XX_TVP5150, |
552 | .input = { { | 596 | .input = { { |
553 | .type = EM28XX_VMUX_TELEVISION, | 597 | .type = EM28XX_VMUX_TELEVISION, |
554 | .vmux = TVP5150_COMPOSITE0, | 598 | .vmux = TVP5150_COMPOSITE0, |
555 | .amux = 0, | 599 | .amux = EM28XX_AMUX_VIDEO, |
600 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
556 | }, { | 601 | }, { |
557 | .type = EM28XX_VMUX_COMPOSITE1, | 602 | .type = EM28XX_VMUX_COMPOSITE1, |
558 | .vmux = TVP5150_COMPOSITE1, | 603 | .vmux = TVP5150_COMPOSITE1, |
559 | .amux = 1, | 604 | .amux = EM28XX_AMUX_LINE_IN, |
605 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
560 | }, { | 606 | }, { |
561 | .type = EM28XX_VMUX_SVIDEO, | 607 | .type = EM28XX_VMUX_SVIDEO, |
562 | .vmux = TVP5150_SVIDEO, | 608 | .vmux = TVP5150_SVIDEO, |
563 | .amux = 1, | 609 | .amux = EM28XX_AMUX_LINE_IN, |
610 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
564 | } }, | 611 | } }, |
565 | }, | 612 | }, |
566 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = { | 613 | [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2] = { |
567 | .name = "Hauppauge WinTV HVR 900 (R2)", | 614 | .name = "Hauppauge WinTV HVR 900 (R2)", |
568 | .vchannels = 3, | ||
569 | .tda9887_conf = TDA9887_PRESENT, | 615 | .tda9887_conf = TDA9887_PRESENT, |
570 | .tuner_type = TUNER_XC2028, | 616 | .tuner_type = TUNER_XC2028, |
617 | .tuner_gpio = default_tuner_gpio, | ||
571 | .mts_firmware = 1, | 618 | .mts_firmware = 1, |
572 | .decoder = EM28XX_TVP5150, | 619 | .decoder = EM28XX_TVP5150, |
620 | .input = { { | ||
621 | .type = EM28XX_VMUX_TELEVISION, | ||
622 | .vmux = TVP5150_COMPOSITE0, | ||
623 | .amux = EM28XX_AMUX_VIDEO, | ||
624 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
625 | }, { | ||
626 | .type = EM28XX_VMUX_COMPOSITE1, | ||
627 | .vmux = TVP5150_COMPOSITE1, | ||
628 | .amux = EM28XX_AMUX_LINE_IN, | ||
629 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
630 | }, { | ||
631 | .type = EM28XX_VMUX_SVIDEO, | ||
632 | .vmux = TVP5150_SVIDEO, | ||
633 | .amux = EM28XX_AMUX_LINE_IN, | ||
634 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
635 | } }, | ||
636 | }, | ||
637 | [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850] = { | ||
638 | .name = "Hauppauge WinTV HVR 850", | ||
639 | .tuner_type = TUNER_XC2028, | ||
640 | .tuner_gpio = default_tuner_gpio, | ||
641 | .mts_firmware = 1, | ||
642 | .has_dvb = 1, | ||
643 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
644 | .ir_codes = ir_codes_hauppauge_new, | ||
645 | .decoder = EM28XX_TVP5150, | ||
573 | .input = { { | 646 | .input = { { |
574 | .type = EM28XX_VMUX_TELEVISION, | 647 | .type = EM28XX_VMUX_TELEVISION, |
575 | .vmux = TVP5150_COMPOSITE0, | 648 | .vmux = TVP5150_COMPOSITE0, |
576 | .amux = 0, | 649 | .amux = EM28XX_AMUX_VIDEO, |
650 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
577 | }, { | 651 | }, { |
578 | .type = EM28XX_VMUX_COMPOSITE1, | 652 | .type = EM28XX_VMUX_COMPOSITE1, |
579 | .vmux = TVP5150_COMPOSITE1, | 653 | .vmux = TVP5150_COMPOSITE1, |
580 | .amux = 3, | 654 | .amux = EM28XX_AMUX_LINE_IN, |
655 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
581 | }, { | 656 | }, { |
582 | .type = EM28XX_VMUX_SVIDEO, | 657 | .type = EM28XX_VMUX_SVIDEO, |
583 | .vmux = TVP5150_SVIDEO, | 658 | .vmux = TVP5150_SVIDEO, |
584 | .amux = 1, | 659 | .amux = EM28XX_AMUX_LINE_IN, |
660 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
585 | } }, | 661 | } }, |
586 | }, | 662 | }, |
587 | [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = { | 663 | [EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950] = { |
588 | .name = "Hauppauge WinTV HVR 950", | 664 | .name = "Hauppauge WinTV HVR 950", |
589 | .vchannels = 3, | ||
590 | .tda9887_conf = TDA9887_PRESENT, | ||
591 | .tuner_type = TUNER_XC2028, | 665 | .tuner_type = TUNER_XC2028, |
666 | .tuner_gpio = default_tuner_gpio, | ||
592 | .mts_firmware = 1, | 667 | .mts_firmware = 1, |
593 | .has_12mhz_i2s = 1, | ||
594 | .has_dvb = 1, | 668 | .has_dvb = 1, |
669 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
670 | .ir_codes = ir_codes_hauppauge_new, | ||
595 | .decoder = EM28XX_TVP5150, | 671 | .decoder = EM28XX_TVP5150, |
596 | .input = { { | 672 | .input = { { |
597 | .type = EM28XX_VMUX_TELEVISION, | 673 | .type = EM28XX_VMUX_TELEVISION, |
598 | .vmux = TVP5150_COMPOSITE0, | 674 | .vmux = TVP5150_COMPOSITE0, |
599 | .amux = 0, | 675 | .amux = EM28XX_AMUX_VIDEO, |
676 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
600 | }, { | 677 | }, { |
601 | .type = EM28XX_VMUX_COMPOSITE1, | 678 | .type = EM28XX_VMUX_COMPOSITE1, |
602 | .vmux = TVP5150_COMPOSITE1, | 679 | .vmux = TVP5150_COMPOSITE1, |
603 | .amux = 1, | 680 | .amux = EM28XX_AMUX_LINE_IN, |
681 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
604 | }, { | 682 | }, { |
605 | .type = EM28XX_VMUX_SVIDEO, | 683 | .type = EM28XX_VMUX_SVIDEO, |
606 | .vmux = TVP5150_SVIDEO, | 684 | .vmux = TVP5150_SVIDEO, |
607 | .amux = 1, | 685 | .amux = EM28XX_AMUX_LINE_IN, |
686 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
608 | } }, | 687 | } }, |
609 | }, | 688 | }, |
610 | [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = { | 689 | [EM2880_BOARD_PINNACLE_PCTV_HD_PRO] = { |
611 | .name = "Pinnacle PCTV HD Pro Stick", | 690 | .name = "Pinnacle PCTV HD Pro Stick", |
612 | .vchannels = 3, | ||
613 | .tda9887_conf = TDA9887_PRESENT, | ||
614 | .tuner_type = TUNER_XC2028, | 691 | .tuner_type = TUNER_XC2028, |
692 | .tuner_gpio = default_tuner_gpio, | ||
615 | .mts_firmware = 1, | 693 | .mts_firmware = 1, |
616 | .has_12mhz_i2s = 1, | ||
617 | .has_dvb = 1, | 694 | .has_dvb = 1, |
695 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
696 | .ir_codes = ir_codes_pinnacle_pctv_hd, | ||
618 | .decoder = EM28XX_TVP5150, | 697 | .decoder = EM28XX_TVP5150, |
619 | .input = { { | 698 | .input = { { |
620 | .type = EM28XX_VMUX_TELEVISION, | 699 | .type = EM28XX_VMUX_TELEVISION, |
621 | .vmux = TVP5150_COMPOSITE0, | 700 | .vmux = TVP5150_COMPOSITE0, |
622 | .amux = 0, | 701 | .amux = EM28XX_AMUX_VIDEO, |
702 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
623 | }, { | 703 | }, { |
624 | .type = EM28XX_VMUX_COMPOSITE1, | 704 | .type = EM28XX_VMUX_COMPOSITE1, |
625 | .vmux = TVP5150_COMPOSITE1, | 705 | .vmux = TVP5150_COMPOSITE1, |
626 | .amux = 1, | 706 | .amux = EM28XX_AMUX_LINE_IN, |
707 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
627 | }, { | 708 | }, { |
628 | .type = EM28XX_VMUX_SVIDEO, | 709 | .type = EM28XX_VMUX_SVIDEO, |
629 | .vmux = TVP5150_SVIDEO, | 710 | .vmux = TVP5150_SVIDEO, |
630 | .amux = 1, | 711 | .amux = EM28XX_AMUX_LINE_IN, |
712 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
631 | } }, | 713 | } }, |
632 | }, | 714 | }, |
633 | [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { | 715 | [EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600] = { |
634 | .name = "AMD ATI TV Wonder HD 600", | 716 | .name = "AMD ATI TV Wonder HD 600", |
635 | .vchannels = 3, | ||
636 | .tda9887_conf = TDA9887_PRESENT, | ||
637 | .tuner_type = TUNER_XC2028, | 717 | .tuner_type = TUNER_XC2028, |
718 | .tuner_gpio = default_tuner_gpio, | ||
638 | .mts_firmware = 1, | 719 | .mts_firmware = 1, |
639 | .has_12mhz_i2s = 1, | ||
640 | .has_dvb = 1, | 720 | .has_dvb = 1, |
721 | .dvb_gpio = hauppauge_wintv_hvr_900_digital, | ||
722 | .ir_codes = ir_codes_ati_tv_wonder_hd_600, | ||
641 | .decoder = EM28XX_TVP5150, | 723 | .decoder = EM28XX_TVP5150, |
642 | .input = { { | 724 | .input = { { |
643 | .type = EM28XX_VMUX_TELEVISION, | 725 | .type = EM28XX_VMUX_TELEVISION, |
644 | .vmux = TVP5150_COMPOSITE0, | 726 | .vmux = TVP5150_COMPOSITE0, |
645 | .amux = 0, | 727 | .amux = EM28XX_AMUX_VIDEO, |
728 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
646 | }, { | 729 | }, { |
647 | .type = EM28XX_VMUX_COMPOSITE1, | 730 | .type = EM28XX_VMUX_COMPOSITE1, |
648 | .vmux = TVP5150_COMPOSITE1, | 731 | .vmux = TVP5150_COMPOSITE1, |
649 | .amux = 1, | 732 | .amux = EM28XX_AMUX_LINE_IN, |
733 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
650 | }, { | 734 | }, { |
651 | .type = EM28XX_VMUX_SVIDEO, | 735 | .type = EM28XX_VMUX_SVIDEO, |
652 | .vmux = TVP5150_SVIDEO, | 736 | .vmux = TVP5150_SVIDEO, |
653 | .amux = 1, | 737 | .amux = EM28XX_AMUX_LINE_IN, |
738 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
654 | } }, | 739 | } }, |
655 | }, | 740 | }, |
656 | [EM2880_BOARD_TERRATEC_HYBRID_XS] = { | 741 | [EM2880_BOARD_TERRATEC_HYBRID_XS] = { |
657 | .name = "Terratec Hybrid XS", | 742 | .name = "Terratec Hybrid XS", |
658 | .vchannels = 3, | 743 | .tuner_type = TUNER_XC2028, |
659 | .tda9887_conf = TDA9887_PRESENT, | 744 | .tuner_gpio = default_tuner_gpio, |
660 | .tuner_type = TUNER_XC2028, | 745 | .decoder = EM28XX_TVP5150, |
661 | .decoder = EM28XX_TVP5150, | ||
662 | .has_dvb = 1, | 746 | .has_dvb = 1, |
747 | .dvb_gpio = default_analog, | ||
663 | .input = { { | 748 | .input = { { |
664 | .type = EM28XX_VMUX_TELEVISION, | 749 | .type = EM28XX_VMUX_TELEVISION, |
665 | .vmux = TVP5150_COMPOSITE0, | 750 | .vmux = TVP5150_COMPOSITE0, |
666 | .amux = 0, | 751 | .amux = EM28XX_AMUX_VIDEO, |
752 | .gpio = default_analog, | ||
667 | }, { | 753 | }, { |
668 | .type = EM28XX_VMUX_COMPOSITE1, | 754 | .type = EM28XX_VMUX_COMPOSITE1, |
669 | .vmux = TVP5150_COMPOSITE1, | 755 | .vmux = TVP5150_COMPOSITE1, |
670 | .amux = 1, | 756 | .amux = EM28XX_AMUX_LINE_IN, |
757 | .gpio = default_analog, | ||
671 | }, { | 758 | }, { |
672 | .type = EM28XX_VMUX_SVIDEO, | 759 | .type = EM28XX_VMUX_SVIDEO, |
673 | .vmux = TVP5150_SVIDEO, | 760 | .vmux = TVP5150_SVIDEO, |
674 | .amux = 1, | 761 | .amux = EM28XX_AMUX_LINE_IN, |
762 | .gpio = default_analog, | ||
675 | } }, | 763 | } }, |
676 | }, | 764 | }, |
677 | /* maybe there's a reason behind it why Terratec sells the Hybrid XS | 765 | /* maybe there's a reason behind it why Terratec sells the Hybrid XS |
@@ -679,172 +767,190 @@ struct em28xx_board em28xx_boards[] = { | |||
679 | maybe we'll need it lateron */ | 767 | maybe we'll need it lateron */ |
680 | [EM2880_BOARD_TERRATEC_PRODIGY_XS] = { | 768 | [EM2880_BOARD_TERRATEC_PRODIGY_XS] = { |
681 | .name = "Terratec Prodigy XS", | 769 | .name = "Terratec Prodigy XS", |
682 | .vchannels = 3, | ||
683 | .tda9887_conf = TDA9887_PRESENT, | ||
684 | .tuner_type = TUNER_XC2028, | 770 | .tuner_type = TUNER_XC2028, |
771 | .tuner_gpio = default_tuner_gpio, | ||
685 | .decoder = EM28XX_TVP5150, | 772 | .decoder = EM28XX_TVP5150, |
686 | .input = { { | 773 | .input = { { |
687 | .type = EM28XX_VMUX_TELEVISION, | 774 | .type = EM28XX_VMUX_TELEVISION, |
688 | .vmux = TVP5150_COMPOSITE0, | 775 | .vmux = TVP5150_COMPOSITE0, |
689 | .amux = 0, | 776 | .amux = EM28XX_AMUX_VIDEO, |
777 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
690 | }, { | 778 | }, { |
691 | .type = EM28XX_VMUX_COMPOSITE1, | 779 | .type = EM28XX_VMUX_COMPOSITE1, |
692 | .vmux = TVP5150_COMPOSITE1, | 780 | .vmux = TVP5150_COMPOSITE1, |
693 | .amux = 1, | 781 | .amux = EM28XX_AMUX_LINE_IN, |
782 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
694 | }, { | 783 | }, { |
695 | .type = EM28XX_VMUX_SVIDEO, | 784 | .type = EM28XX_VMUX_SVIDEO, |
696 | .vmux = TVP5150_SVIDEO, | 785 | .vmux = TVP5150_SVIDEO, |
697 | .amux = 1, | 786 | .amux = EM28XX_AMUX_LINE_IN, |
787 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
698 | } }, | 788 | } }, |
699 | }, | 789 | }, |
700 | [EM2820_BOARD_MSI_VOX_USB_2] = { | 790 | [EM2820_BOARD_MSI_VOX_USB_2] = { |
701 | .name = "MSI VOX USB 2.0", | 791 | .name = "MSI VOX USB 2.0", |
702 | .vchannels = 3, | ||
703 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | 792 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, |
704 | .tda9887_conf = TDA9887_PRESENT | | 793 | .tda9887_conf = TDA9887_PRESENT | |
705 | TDA9887_PORT1_ACTIVE | | 794 | TDA9887_PORT1_ACTIVE | |
706 | TDA9887_PORT2_ACTIVE, | 795 | TDA9887_PORT2_ACTIVE, |
707 | .max_range_640_480 = 1, | 796 | .max_range_640_480 = 1, |
708 | 797 | .decoder = EM28XX_SAA711X, | |
709 | .decoder = EM28XX_SAA7114, | ||
710 | .input = { { | 798 | .input = { { |
711 | .type = EM28XX_VMUX_TELEVISION, | 799 | .type = EM28XX_VMUX_TELEVISION, |
712 | .vmux = SAA7115_COMPOSITE4, | 800 | .vmux = SAA7115_COMPOSITE4, |
713 | .amux = 0, | 801 | .amux = EM28XX_AMUX_VIDEO, |
714 | }, { | 802 | }, { |
715 | .type = EM28XX_VMUX_COMPOSITE1, | 803 | .type = EM28XX_VMUX_COMPOSITE1, |
716 | .vmux = SAA7115_COMPOSITE0, | 804 | .vmux = SAA7115_COMPOSITE0, |
717 | .amux = 1, | 805 | .amux = EM28XX_AMUX_LINE_IN, |
718 | }, { | 806 | }, { |
719 | .type = EM28XX_VMUX_SVIDEO, | 807 | .type = EM28XX_VMUX_SVIDEO, |
720 | .vmux = SAA7115_SVIDEO3, | 808 | .vmux = SAA7115_SVIDEO3, |
721 | .amux = 1, | 809 | .amux = EM28XX_AMUX_LINE_IN, |
722 | } }, | 810 | } }, |
723 | }, | 811 | }, |
724 | [EM2800_BOARD_TERRATEC_CINERGY_200] = { | 812 | [EM2800_BOARD_TERRATEC_CINERGY_200] = { |
725 | .name = "Terratec Cinergy 200 USB", | 813 | .name = "Terratec Cinergy 200 USB", |
726 | .is_em2800 = 1, | 814 | .is_em2800 = 1, |
727 | .vchannels = 3, | ||
728 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | 815 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, |
729 | .tda9887_conf = TDA9887_PRESENT, | 816 | .tda9887_conf = TDA9887_PRESENT, |
730 | .decoder = EM28XX_SAA7113, | 817 | .decoder = EM28XX_SAA711X, |
731 | .input = { { | 818 | .input = { { |
732 | .type = EM28XX_VMUX_TELEVISION, | 819 | .type = EM28XX_VMUX_TELEVISION, |
733 | .vmux = SAA7115_COMPOSITE2, | 820 | .vmux = SAA7115_COMPOSITE2, |
734 | .amux = 0, | 821 | .amux = EM28XX_AMUX_VIDEO, |
735 | }, { | 822 | }, { |
736 | .type = EM28XX_VMUX_COMPOSITE1, | 823 | .type = EM28XX_VMUX_COMPOSITE1, |
737 | .vmux = SAA7115_COMPOSITE0, | 824 | .vmux = SAA7115_COMPOSITE0, |
738 | .amux = 1, | 825 | .amux = EM28XX_AMUX_LINE_IN, |
739 | }, { | 826 | }, { |
740 | .type = EM28XX_VMUX_SVIDEO, | 827 | .type = EM28XX_VMUX_SVIDEO, |
741 | .vmux = SAA7115_SVIDEO3, | 828 | .vmux = SAA7115_SVIDEO3, |
742 | .amux = 1, | 829 | .amux = EM28XX_AMUX_LINE_IN, |
743 | } }, | 830 | } }, |
744 | }, | 831 | }, |
745 | [EM2800_BOARD_GRABBEEX_USB2800] = { | 832 | [EM2800_BOARD_GRABBEEX_USB2800] = { |
746 | .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder", | 833 | .name = "eMPIA Technology, Inc. GrabBeeX+ Video Encoder", |
747 | .is_em2800 = 1, | 834 | .is_em2800 = 1, |
748 | .vchannels = 2, | 835 | .decoder = EM28XX_SAA711X, |
749 | .decoder = EM28XX_SAA7113, | 836 | .tuner_type = TUNER_ABSENT, /* capture only board */ |
750 | .input = { { | 837 | .input = { { |
751 | .type = EM28XX_VMUX_COMPOSITE1, | 838 | .type = EM28XX_VMUX_COMPOSITE1, |
752 | .vmux = SAA7115_COMPOSITE0, | 839 | .vmux = SAA7115_COMPOSITE0, |
753 | .amux = 1, | 840 | .amux = EM28XX_AMUX_LINE_IN, |
754 | }, { | 841 | }, { |
755 | .type = EM28XX_VMUX_SVIDEO, | 842 | .type = EM28XX_VMUX_SVIDEO, |
756 | .vmux = SAA7115_SVIDEO3, | 843 | .vmux = SAA7115_SVIDEO3, |
757 | .amux = 1, | 844 | .amux = EM28XX_AMUX_LINE_IN, |
758 | } }, | 845 | } }, |
759 | }, | 846 | }, |
760 | [EM2800_BOARD_LEADTEK_WINFAST_USBII] = { | 847 | [EM2800_BOARD_LEADTEK_WINFAST_USBII] = { |
761 | .name = "Leadtek Winfast USB II", | 848 | .name = "Leadtek Winfast USB II", |
762 | .is_em2800 = 1, | 849 | .is_em2800 = 1, |
763 | .vchannels = 3, | ||
764 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | 850 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, |
765 | .tda9887_conf = TDA9887_PRESENT, | 851 | .tda9887_conf = TDA9887_PRESENT, |
766 | .decoder = EM28XX_SAA7113, | 852 | .decoder = EM28XX_SAA711X, |
767 | .input = { { | 853 | .input = { { |
768 | .type = EM28XX_VMUX_TELEVISION, | 854 | .type = EM28XX_VMUX_TELEVISION, |
769 | .vmux = SAA7115_COMPOSITE2, | 855 | .vmux = SAA7115_COMPOSITE2, |
770 | .amux = 0, | 856 | .amux = EM28XX_AMUX_VIDEO, |
771 | }, { | 857 | }, { |
772 | .type = EM28XX_VMUX_COMPOSITE1, | 858 | .type = EM28XX_VMUX_COMPOSITE1, |
773 | .vmux = SAA7115_COMPOSITE0, | 859 | .vmux = SAA7115_COMPOSITE0, |
774 | .amux = 1, | 860 | .amux = EM28XX_AMUX_LINE_IN, |
775 | }, { | 861 | }, { |
776 | .type = EM28XX_VMUX_SVIDEO, | 862 | .type = EM28XX_VMUX_SVIDEO, |
777 | .vmux = SAA7115_SVIDEO3, | 863 | .vmux = SAA7115_SVIDEO3, |
778 | .amux = 1, | 864 | .amux = EM28XX_AMUX_LINE_IN, |
779 | } }, | 865 | } }, |
780 | }, | 866 | }, |
781 | [EM2800_BOARD_KWORLD_USB2800] = { | 867 | [EM2800_BOARD_KWORLD_USB2800] = { |
782 | .name = "Kworld USB2800", | 868 | .name = "Kworld USB2800", |
783 | .is_em2800 = 1, | 869 | .is_em2800 = 1, |
784 | .vchannels = 3, | ||
785 | .tuner_type = TUNER_PHILIPS_FCV1236D, | 870 | .tuner_type = TUNER_PHILIPS_FCV1236D, |
786 | .tda9887_conf = TDA9887_PRESENT, | 871 | .tda9887_conf = TDA9887_PRESENT, |
787 | .decoder = EM28XX_SAA7113, | 872 | .decoder = EM28XX_SAA711X, |
788 | .input = { { | 873 | .input = { { |
789 | .type = EM28XX_VMUX_TELEVISION, | 874 | .type = EM28XX_VMUX_TELEVISION, |
790 | .vmux = SAA7115_COMPOSITE2, | 875 | .vmux = SAA7115_COMPOSITE2, |
791 | .amux = 0, | 876 | .amux = EM28XX_AMUX_VIDEO, |
792 | }, { | 877 | }, { |
793 | .type = EM28XX_VMUX_COMPOSITE1, | 878 | .type = EM28XX_VMUX_COMPOSITE1, |
794 | .vmux = SAA7115_COMPOSITE0, | 879 | .vmux = SAA7115_COMPOSITE0, |
795 | .amux = 1, | 880 | .amux = EM28XX_AMUX_LINE_IN, |
796 | }, { | 881 | }, { |
797 | .type = EM28XX_VMUX_SVIDEO, | 882 | .type = EM28XX_VMUX_SVIDEO, |
798 | .vmux = SAA7115_SVIDEO3, | 883 | .vmux = SAA7115_SVIDEO3, |
799 | .amux = 1, | 884 | .amux = EM28XX_AMUX_LINE_IN, |
800 | } }, | 885 | } }, |
801 | }, | 886 | }, |
802 | [EM2820_BOARD_PINNACLE_DVC_90] = { | 887 | [EM2820_BOARD_PINNACLE_DVC_90] = { |
803 | .name = "Pinnacle Dazzle DVC 90/DVC 100", | 888 | .name = "Pinnacle Dazzle DVC 90/DVC 100", |
804 | .vchannels = 3, | 889 | .tuner_type = TUNER_ABSENT, /* capture only board */ |
805 | .tuner_type = TUNER_ABSENT, | 890 | .decoder = EM28XX_SAA711X, |
806 | .decoder = EM28XX_SAA7113, | 891 | .input = { { |
807 | .input = { { | ||
808 | .type = EM28XX_VMUX_COMPOSITE1, | 892 | .type = EM28XX_VMUX_COMPOSITE1, |
809 | .vmux = SAA7115_COMPOSITE0, | 893 | .vmux = SAA7115_COMPOSITE0, |
810 | .amux = 1, | 894 | .amux = EM28XX_AMUX_LINE_IN, |
811 | }, { | 895 | }, { |
812 | .type = EM28XX_VMUX_SVIDEO, | 896 | .type = EM28XX_VMUX_SVIDEO, |
813 | .vmux = SAA7115_SVIDEO3, | 897 | .vmux = SAA7115_SVIDEO3, |
814 | .amux = 1, | 898 | .amux = EM28XX_AMUX_LINE_IN, |
815 | } }, | 899 | } }, |
816 | }, | 900 | }, |
817 | [EM2800_BOARD_VGEAR_POCKETTV] = { | 901 | [EM2800_BOARD_VGEAR_POCKETTV] = { |
818 | .name = "V-Gear PocketTV", | 902 | .name = "V-Gear PocketTV", |
819 | .is_em2800 = 1, | 903 | .is_em2800 = 1, |
820 | .vchannels = 3, | ||
821 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | 904 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, |
822 | .tda9887_conf = TDA9887_PRESENT, | 905 | .tda9887_conf = TDA9887_PRESENT, |
823 | .decoder = EM28XX_SAA7113, | 906 | .decoder = EM28XX_SAA711X, |
824 | .input = { { | 907 | .input = { { |
825 | .type = EM28XX_VMUX_TELEVISION, | 908 | .type = EM28XX_VMUX_TELEVISION, |
826 | .vmux = SAA7115_COMPOSITE2, | 909 | .vmux = SAA7115_COMPOSITE2, |
827 | .amux = 0, | 910 | .amux = EM28XX_AMUX_VIDEO, |
828 | }, { | 911 | }, { |
829 | .type = EM28XX_VMUX_COMPOSITE1, | 912 | .type = EM28XX_VMUX_COMPOSITE1, |
830 | .vmux = SAA7115_COMPOSITE0, | 913 | .vmux = SAA7115_COMPOSITE0, |
831 | .amux = 1, | 914 | .amux = EM28XX_AMUX_LINE_IN, |
915 | }, { | ||
916 | .type = EM28XX_VMUX_SVIDEO, | ||
917 | .vmux = SAA7115_SVIDEO3, | ||
918 | .amux = EM28XX_AMUX_LINE_IN, | ||
919 | } }, | ||
920 | }, | ||
921 | [EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2] = { | ||
922 | .name = "Pixelview PlayTV Box 4 USB 2.0", | ||
923 | .tda9887_conf = TDA9887_PRESENT, | ||
924 | .tuner_type = TUNER_YMEC_TVF_5533MF, | ||
925 | .decoder = EM28XX_SAA711X, | ||
926 | .input = { { | ||
927 | .type = EM28XX_VMUX_TELEVISION, | ||
928 | .vmux = SAA7115_COMPOSITE2, | ||
929 | .amux = EM28XX_AMUX_VIDEO, | ||
930 | .aout = EM28XX_AOUT_MONO | /* I2S */ | ||
931 | EM28XX_AOUT_MASTER, /* Line out pin */ | ||
932 | }, { | ||
933 | .type = EM28XX_VMUX_COMPOSITE1, | ||
934 | .vmux = SAA7115_COMPOSITE0, | ||
935 | .amux = EM28XX_AMUX_LINE_IN, | ||
832 | }, { | 936 | }, { |
833 | .type = EM28XX_VMUX_SVIDEO, | 937 | .type = EM28XX_VMUX_SVIDEO, |
834 | .vmux = SAA7115_SVIDEO3, | 938 | .vmux = SAA7115_SVIDEO3, |
835 | .amux = 1, | 939 | .amux = EM28XX_AMUX_LINE_IN, |
836 | } }, | 940 | } }, |
837 | }, | 941 | }, |
838 | [EM2820_BOARD_PROLINK_PLAYTV_USB2] = { | 942 | [EM2820_BOARD_PROLINK_PLAYTV_USB2] = { |
839 | .name = "Pixelview Prolink PlayTV USB 2.0", | 943 | .name = "Pixelview Prolink PlayTV USB 2.0", |
840 | .vchannels = 3, | 944 | .has_snapshot_button = 1, |
841 | .tda9887_conf = TDA9887_PRESENT, | 945 | .tda9887_conf = TDA9887_PRESENT, |
842 | .tuner_type = TUNER_YMEC_TVF_5533MF, | 946 | .tuner_type = TUNER_YMEC_TVF_5533MF, |
843 | .decoder = EM28XX_SAA7113, | 947 | .decoder = EM28XX_SAA711X, |
844 | .input = { { | 948 | .input = { { |
845 | .type = EM28XX_VMUX_TELEVISION, | 949 | .type = EM28XX_VMUX_TELEVISION, |
846 | .vmux = SAA7115_COMPOSITE2, | 950 | .vmux = SAA7115_COMPOSITE2, |
847 | .amux = EM28XX_AMUX_LINE_IN, | 951 | .amux = EM28XX_AMUX_VIDEO, |
952 | .aout = EM28XX_AOUT_MONO | /* I2S */ | ||
953 | EM28XX_AOUT_MASTER, /* Line out pin */ | ||
848 | }, { | 954 | }, { |
849 | .type = EM28XX_VMUX_COMPOSITE1, | 955 | .type = EM28XX_VMUX_COMPOSITE1, |
850 | .vmux = SAA7115_COMPOSITE0, | 956 | .vmux = SAA7115_COMPOSITE0, |
@@ -856,228 +962,252 @@ struct em28xx_board em28xx_boards[] = { | |||
856 | } }, | 962 | } }, |
857 | }, | 963 | }, |
858 | [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = { | 964 | [EM2860_BOARD_POINTNIX_INTRAORAL_CAMERA] = { |
859 | .name = "PointNix Intra-Oral Camera", | 965 | .name = "PointNix Intra-Oral Camera", |
860 | .has_snapshot_button = 1, | 966 | .has_snapshot_button = 1, |
861 | .vchannels = 1, | 967 | .tda9887_conf = TDA9887_PRESENT, |
862 | .tda9887_conf = TDA9887_PRESENT, | 968 | .tuner_type = TUNER_ABSENT, |
863 | .tuner_type = TUNER_ABSENT, | 969 | .decoder = EM28XX_SAA711X, |
864 | .decoder = EM28XX_SAA7113, | 970 | .input = { { |
865 | .input = { { | ||
866 | .type = EM28XX_VMUX_SVIDEO, | 971 | .type = EM28XX_VMUX_SVIDEO, |
867 | .vmux = SAA7115_SVIDEO3, | 972 | .vmux = SAA7115_SVIDEO3, |
868 | .amux = 0, | 973 | .amux = EM28XX_AMUX_VIDEO, |
869 | } }, | 974 | } }, |
870 | }, | 975 | }, |
871 | [EM2880_BOARD_MSI_DIGIVOX_AD] = { | 976 | [EM2880_BOARD_MSI_DIGIVOX_AD] = { |
872 | .name = "MSI DigiVox A/D", | 977 | .name = "MSI DigiVox A/D", |
873 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 978 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
874 | .vchannels = 3, | ||
875 | .tuner_type = TUNER_XC2028, | 979 | .tuner_type = TUNER_XC2028, |
980 | .tuner_gpio = default_tuner_gpio, | ||
876 | .decoder = EM28XX_TVP5150, | 981 | .decoder = EM28XX_TVP5150, |
877 | .input = { { | 982 | .input = { { |
878 | .type = EM28XX_VMUX_TELEVISION, | 983 | .type = EM28XX_VMUX_TELEVISION, |
879 | .vmux = TVP5150_COMPOSITE0, | 984 | .vmux = TVP5150_COMPOSITE0, |
880 | .amux = 0, | 985 | .amux = EM28XX_AMUX_VIDEO, |
986 | .gpio = em2880_msi_digivox_ad_analog, | ||
881 | }, { | 987 | }, { |
882 | .type = EM28XX_VMUX_COMPOSITE1, | 988 | .type = EM28XX_VMUX_COMPOSITE1, |
883 | .vmux = TVP5150_COMPOSITE1, | 989 | .vmux = TVP5150_COMPOSITE1, |
884 | .amux = 1, | 990 | .amux = EM28XX_AMUX_LINE_IN, |
991 | .gpio = em2880_msi_digivox_ad_analog, | ||
885 | }, { | 992 | }, { |
886 | .type = EM28XX_VMUX_SVIDEO, | 993 | .type = EM28XX_VMUX_SVIDEO, |
887 | .vmux = TVP5150_SVIDEO, | 994 | .vmux = TVP5150_SVIDEO, |
888 | .amux = 1, | 995 | .amux = EM28XX_AMUX_LINE_IN, |
996 | .gpio = em2880_msi_digivox_ad_analog, | ||
889 | } }, | 997 | } }, |
890 | }, | 998 | }, |
891 | [EM2880_BOARD_MSI_DIGIVOX_AD_II] = { | 999 | [EM2880_BOARD_MSI_DIGIVOX_AD_II] = { |
892 | .name = "MSI DigiVox A/D II", | 1000 | .name = "MSI DigiVox A/D II", |
893 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 1001 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
894 | .vchannels = 3, | ||
895 | .tuner_type = TUNER_XC2028, | 1002 | .tuner_type = TUNER_XC2028, |
1003 | .tuner_gpio = default_tuner_gpio, | ||
896 | .decoder = EM28XX_TVP5150, | 1004 | .decoder = EM28XX_TVP5150, |
897 | .input = { { | 1005 | .input = { { |
898 | .type = EM28XX_VMUX_TELEVISION, | 1006 | .type = EM28XX_VMUX_TELEVISION, |
899 | .vmux = TVP5150_COMPOSITE0, | 1007 | .vmux = TVP5150_COMPOSITE0, |
900 | .amux = 0, | 1008 | .amux = EM28XX_AMUX_VIDEO, |
1009 | .gpio = em2880_msi_digivox_ad_analog, | ||
901 | }, { | 1010 | }, { |
902 | .type = EM28XX_VMUX_COMPOSITE1, | 1011 | .type = EM28XX_VMUX_COMPOSITE1, |
903 | .vmux = TVP5150_COMPOSITE1, | 1012 | .vmux = TVP5150_COMPOSITE1, |
904 | .amux = 1, | 1013 | .amux = EM28XX_AMUX_LINE_IN, |
1014 | .gpio = em2880_msi_digivox_ad_analog, | ||
905 | }, { | 1015 | }, { |
906 | .type = EM28XX_VMUX_SVIDEO, | 1016 | .type = EM28XX_VMUX_SVIDEO, |
907 | .vmux = TVP5150_SVIDEO, | 1017 | .vmux = TVP5150_SVIDEO, |
908 | .amux = 1, | 1018 | .amux = EM28XX_AMUX_LINE_IN, |
1019 | .gpio = em2880_msi_digivox_ad_analog, | ||
909 | } }, | 1020 | } }, |
910 | }, | 1021 | }, |
911 | [EM2880_BOARD_KWORLD_DVB_305U] = { | 1022 | [EM2880_BOARD_KWORLD_DVB_305U] = { |
912 | .name = "KWorld DVB-T 305U", | 1023 | .name = "KWorld DVB-T 305U", |
913 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 1024 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
914 | .vchannels = 3, | ||
915 | .tuner_type = TUNER_XC2028, | 1025 | .tuner_type = TUNER_XC2028, |
1026 | .tuner_gpio = default_tuner_gpio, | ||
916 | .decoder = EM28XX_TVP5150, | 1027 | .decoder = EM28XX_TVP5150, |
917 | .input = { { | 1028 | .input = { { |
918 | .type = EM28XX_VMUX_TELEVISION, | 1029 | .type = EM28XX_VMUX_TELEVISION, |
919 | .vmux = TVP5150_COMPOSITE0, | 1030 | .vmux = TVP5150_COMPOSITE0, |
920 | .amux = 0, | 1031 | .amux = EM28XX_AMUX_VIDEO, |
921 | }, { | 1032 | }, { |
922 | .type = EM28XX_VMUX_COMPOSITE1, | 1033 | .type = EM28XX_VMUX_COMPOSITE1, |
923 | .vmux = TVP5150_COMPOSITE1, | 1034 | .vmux = TVP5150_COMPOSITE1, |
924 | .amux = 1, | 1035 | .amux = EM28XX_AMUX_LINE_IN, |
925 | }, { | 1036 | }, { |
926 | .type = EM28XX_VMUX_SVIDEO, | 1037 | .type = EM28XX_VMUX_SVIDEO, |
927 | .vmux = TVP5150_SVIDEO, | 1038 | .vmux = TVP5150_SVIDEO, |
928 | .amux = 1, | 1039 | .amux = EM28XX_AMUX_LINE_IN, |
929 | } }, | 1040 | } }, |
930 | }, | 1041 | }, |
931 | [EM2880_BOARD_KWORLD_DVB_310U] = { | 1042 | [EM2880_BOARD_KWORLD_DVB_310U] = { |
932 | .name = "KWorld DVB-T 310U", | 1043 | .name = "KWorld DVB-T 310U", |
933 | .vchannels = 3, | ||
934 | .tuner_type = TUNER_XC2028, | 1044 | .tuner_type = TUNER_XC2028, |
1045 | .tuner_gpio = default_tuner_gpio, | ||
935 | .has_dvb = 1, | 1046 | .has_dvb = 1, |
1047 | .dvb_gpio = default_digital, | ||
936 | .mts_firmware = 1, | 1048 | .mts_firmware = 1, |
937 | .decoder = EM28XX_TVP5150, | 1049 | .decoder = EM28XX_TVP5150, |
938 | .input = { { | 1050 | .input = { { |
939 | .type = EM28XX_VMUX_TELEVISION, | 1051 | .type = EM28XX_VMUX_TELEVISION, |
940 | .vmux = TVP5150_COMPOSITE0, | 1052 | .vmux = TVP5150_COMPOSITE0, |
941 | .amux = EM28XX_AMUX_VIDEO, | 1053 | .amux = EM28XX_AMUX_VIDEO, |
1054 | .gpio = default_analog, | ||
942 | }, { | 1055 | }, { |
943 | .type = EM28XX_VMUX_COMPOSITE1, | 1056 | .type = EM28XX_VMUX_COMPOSITE1, |
944 | .vmux = TVP5150_COMPOSITE1, | 1057 | .vmux = TVP5150_COMPOSITE1, |
945 | .amux = EM28XX_AMUX_AC97_LINE_IN, | 1058 | .amux = EM28XX_AMUX_LINE_IN, |
1059 | .gpio = default_analog, | ||
946 | }, { /* S-video has not been tested yet */ | 1060 | }, { /* S-video has not been tested yet */ |
947 | .type = EM28XX_VMUX_SVIDEO, | 1061 | .type = EM28XX_VMUX_SVIDEO, |
948 | .vmux = TVP5150_SVIDEO, | 1062 | .vmux = TVP5150_SVIDEO, |
949 | .amux = EM28XX_AMUX_AC97_LINE_IN, | 1063 | .amux = EM28XX_AMUX_LINE_IN, |
1064 | .gpio = default_analog, | ||
950 | } }, | 1065 | } }, |
951 | }, | 1066 | }, |
952 | [EM2881_BOARD_DNT_DA2_HYBRID] = { | 1067 | [EM2881_BOARD_DNT_DA2_HYBRID] = { |
953 | .name = "DNT DA2 Hybrid", | 1068 | .name = "DNT DA2 Hybrid", |
954 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 1069 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
955 | .vchannels = 3, | ||
956 | .tuner_type = TUNER_XC2028, | 1070 | .tuner_type = TUNER_XC2028, |
1071 | .tuner_gpio = default_tuner_gpio, | ||
957 | .decoder = EM28XX_TVP5150, | 1072 | .decoder = EM28XX_TVP5150, |
958 | .input = { { | 1073 | .input = { { |
959 | .type = EM28XX_VMUX_TELEVISION, | 1074 | .type = EM28XX_VMUX_TELEVISION, |
960 | .vmux = TVP5150_COMPOSITE0, | 1075 | .vmux = TVP5150_COMPOSITE0, |
961 | .amux = 0, | 1076 | .amux = EM28XX_AMUX_VIDEO, |
1077 | .gpio = default_analog, | ||
962 | }, { | 1078 | }, { |
963 | .type = EM28XX_VMUX_COMPOSITE1, | 1079 | .type = EM28XX_VMUX_COMPOSITE1, |
964 | .vmux = TVP5150_COMPOSITE1, | 1080 | .vmux = TVP5150_COMPOSITE1, |
965 | .amux = 1, | 1081 | .amux = EM28XX_AMUX_LINE_IN, |
1082 | .gpio = default_analog, | ||
966 | }, { | 1083 | }, { |
967 | .type = EM28XX_VMUX_SVIDEO, | 1084 | .type = EM28XX_VMUX_SVIDEO, |
968 | .vmux = TVP5150_SVIDEO, | 1085 | .vmux = TVP5150_SVIDEO, |
969 | .amux = 1, | 1086 | .amux = EM28XX_AMUX_LINE_IN, |
1087 | .gpio = default_analog, | ||
970 | } }, | 1088 | } }, |
971 | }, | 1089 | }, |
972 | [EM2881_BOARD_PINNACLE_HYBRID_PRO] = { | 1090 | [EM2881_BOARD_PINNACLE_HYBRID_PRO] = { |
973 | .name = "Pinnacle Hybrid Pro", | 1091 | .name = "Pinnacle Hybrid Pro", |
974 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 1092 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
975 | .vchannels = 3, | ||
976 | .tuner_type = TUNER_XC2028, | 1093 | .tuner_type = TUNER_XC2028, |
1094 | .tuner_gpio = default_tuner_gpio, | ||
977 | .decoder = EM28XX_TVP5150, | 1095 | .decoder = EM28XX_TVP5150, |
978 | .input = { { | 1096 | .input = { { |
979 | .type = EM28XX_VMUX_TELEVISION, | 1097 | .type = EM28XX_VMUX_TELEVISION, |
980 | .vmux = TVP5150_COMPOSITE0, | 1098 | .vmux = TVP5150_COMPOSITE0, |
981 | .amux = 0, | 1099 | .amux = EM28XX_AMUX_VIDEO, |
1100 | .gpio = default_analog, | ||
982 | }, { | 1101 | }, { |
983 | .type = EM28XX_VMUX_COMPOSITE1, | 1102 | .type = EM28XX_VMUX_COMPOSITE1, |
984 | .vmux = TVP5150_COMPOSITE1, | 1103 | .vmux = TVP5150_COMPOSITE1, |
985 | .amux = 1, | 1104 | .amux = EM28XX_AMUX_LINE_IN, |
1105 | .gpio = default_analog, | ||
986 | }, { | 1106 | }, { |
987 | .type = EM28XX_VMUX_SVIDEO, | 1107 | .type = EM28XX_VMUX_SVIDEO, |
988 | .vmux = TVP5150_SVIDEO, | 1108 | .vmux = TVP5150_SVIDEO, |
989 | .amux = 1, | 1109 | .amux = EM28XX_AMUX_LINE_IN, |
1110 | .gpio = default_analog, | ||
990 | } }, | 1111 | } }, |
991 | }, | 1112 | }, |
992 | [EM2882_BOARD_PINNACLE_HYBRID_PRO] = { | 1113 | [EM2882_BOARD_PINNACLE_HYBRID_PRO] = { |
993 | .name = "Pinnacle Hybrid Pro (2)", | 1114 | .name = "Pinnacle Hybrid Pro (2)", |
994 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 1115 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
995 | .vchannels = 3, | ||
996 | .tuner_type = TUNER_XC2028, | 1116 | .tuner_type = TUNER_XC2028, |
1117 | .tuner_gpio = default_tuner_gpio, | ||
997 | .mts_firmware = 1, | 1118 | .mts_firmware = 1, |
998 | .decoder = EM28XX_TVP5150, | 1119 | .decoder = EM28XX_TVP5150, |
999 | .input = { { | 1120 | .input = { { |
1000 | .type = EM28XX_VMUX_TELEVISION, | 1121 | .type = EM28XX_VMUX_TELEVISION, |
1001 | .vmux = TVP5150_COMPOSITE0, | 1122 | .vmux = TVP5150_COMPOSITE0, |
1002 | .amux = 0, | 1123 | .amux = EM28XX_AMUX_VIDEO, |
1124 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1003 | }, { | 1125 | }, { |
1004 | .type = EM28XX_VMUX_COMPOSITE1, | 1126 | .type = EM28XX_VMUX_COMPOSITE1, |
1005 | .vmux = TVP5150_COMPOSITE1, | 1127 | .vmux = TVP5150_COMPOSITE1, |
1006 | .amux = 1, | 1128 | .amux = EM28XX_AMUX_LINE_IN, |
1129 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1007 | }, { | 1130 | }, { |
1008 | .type = EM28XX_VMUX_SVIDEO, | 1131 | .type = EM28XX_VMUX_SVIDEO, |
1009 | .vmux = TVP5150_SVIDEO, | 1132 | .vmux = TVP5150_SVIDEO, |
1010 | .amux = 1, | 1133 | .amux = EM28XX_AMUX_LINE_IN, |
1134 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1011 | } }, | 1135 | } }, |
1012 | }, | 1136 | }, |
1013 | [EM2882_BOARD_KWORLD_VS_DVBT] = { | 1137 | [EM2882_BOARD_KWORLD_VS_DVBT] = { |
1014 | .name = "Kworld VS-DVB-T 323UR", | 1138 | .name = "Kworld VS-DVB-T 323UR", |
1015 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 1139 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
1016 | .vchannels = 3, | ||
1017 | .tuner_type = TUNER_XC2028, | 1140 | .tuner_type = TUNER_XC2028, |
1141 | .tuner_gpio = default_tuner_gpio, | ||
1018 | .decoder = EM28XX_TVP5150, | 1142 | .decoder = EM28XX_TVP5150, |
1019 | .input = { { | 1143 | .input = { { |
1020 | .type = EM28XX_VMUX_TELEVISION, | 1144 | .type = EM28XX_VMUX_TELEVISION, |
1021 | .vmux = TVP5150_COMPOSITE0, | 1145 | .vmux = TVP5150_COMPOSITE0, |
1022 | .amux = 0, | 1146 | .amux = EM28XX_AMUX_VIDEO, |
1023 | }, { | 1147 | }, { |
1024 | .type = EM28XX_VMUX_COMPOSITE1, | 1148 | .type = EM28XX_VMUX_COMPOSITE1, |
1025 | .vmux = TVP5150_COMPOSITE1, | 1149 | .vmux = TVP5150_COMPOSITE1, |
1026 | .amux = 1, | 1150 | .amux = EM28XX_AMUX_LINE_IN, |
1027 | }, { | 1151 | }, { |
1028 | .type = EM28XX_VMUX_SVIDEO, | 1152 | .type = EM28XX_VMUX_SVIDEO, |
1029 | .vmux = TVP5150_SVIDEO, | 1153 | .vmux = TVP5150_SVIDEO, |
1030 | .amux = 1, | 1154 | .amux = EM28XX_AMUX_LINE_IN, |
1031 | } }, | 1155 | } }, |
1032 | }, | 1156 | }, |
1033 | [EM2882_BOARD_TERRATEC_HYBRID_XS] = { | 1157 | [EM2882_BOARD_TERRATEC_HYBRID_XS] = { |
1034 | .name = "Terratec Hybrid XS (em2882)", | 1158 | .name = "Terratec Hybrid XS (em2882)", |
1035 | .valid = EM28XX_BOARD_NOT_VALIDATED, | 1159 | .valid = EM28XX_BOARD_NOT_VALIDATED, |
1036 | .vchannels = 3, | ||
1037 | .tuner_type = TUNER_XC2028, | 1160 | .tuner_type = TUNER_XC2028, |
1161 | .tuner_gpio = default_tuner_gpio, | ||
1038 | .decoder = EM28XX_TVP5150, | 1162 | .decoder = EM28XX_TVP5150, |
1039 | .input = { { | 1163 | .input = { { |
1040 | .type = EM28XX_VMUX_TELEVISION, | 1164 | .type = EM28XX_VMUX_TELEVISION, |
1041 | .vmux = TVP5150_COMPOSITE0, | 1165 | .vmux = TVP5150_COMPOSITE0, |
1042 | .amux = 0, | 1166 | .amux = EM28XX_AMUX_VIDEO, |
1167 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1043 | }, { | 1168 | }, { |
1044 | .type = EM28XX_VMUX_COMPOSITE1, | 1169 | .type = EM28XX_VMUX_COMPOSITE1, |
1045 | .vmux = TVP5150_COMPOSITE1, | 1170 | .vmux = TVP5150_COMPOSITE1, |
1046 | .amux = 1, | 1171 | .amux = EM28XX_AMUX_LINE_IN, |
1172 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1047 | }, { | 1173 | }, { |
1048 | .type = EM28XX_VMUX_SVIDEO, | 1174 | .type = EM28XX_VMUX_SVIDEO, |
1049 | .vmux = TVP5150_SVIDEO, | 1175 | .vmux = TVP5150_SVIDEO, |
1050 | .amux = 1, | 1176 | .amux = EM28XX_AMUX_LINE_IN, |
1177 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1051 | } }, | 1178 | } }, |
1052 | }, | 1179 | }, |
1053 | [EM2883_BOARD_KWORLD_HYBRID_A316] = { | 1180 | [EM2883_BOARD_KWORLD_HYBRID_A316] = { |
1054 | .name = "Kworld PlusTV HD Hybrid 330", | 1181 | .name = "Kworld PlusTV HD Hybrid 330", |
1055 | .valid = EM28XX_BOARD_NOT_VALIDATED, | ||
1056 | .vchannels = 3, | ||
1057 | .is_em2800 = 0, | ||
1058 | .tuner_type = TUNER_XC2028, | 1182 | .tuner_type = TUNER_XC2028, |
1183 | .tuner_gpio = default_tuner_gpio, | ||
1059 | .decoder = EM28XX_TVP5150, | 1184 | .decoder = EM28XX_TVP5150, |
1060 | .input = { { | 1185 | .mts_firmware = 1, |
1186 | .has_dvb = 1, | ||
1187 | .dvb_gpio = default_digital, | ||
1188 | .input = { { | ||
1061 | .type = EM28XX_VMUX_TELEVISION, | 1189 | .type = EM28XX_VMUX_TELEVISION, |
1062 | .vmux = TVP5150_COMPOSITE0, | 1190 | .vmux = TVP5150_COMPOSITE0, |
1063 | .amux = 0, | 1191 | .amux = EM28XX_AMUX_VIDEO, |
1192 | .gpio = default_analog, | ||
1064 | }, { | 1193 | }, { |
1065 | .type = EM28XX_VMUX_COMPOSITE1, | 1194 | .type = EM28XX_VMUX_COMPOSITE1, |
1066 | .vmux = TVP5150_COMPOSITE1, | 1195 | .vmux = TVP5150_COMPOSITE1, |
1067 | .amux = 1, | 1196 | .amux = EM28XX_AMUX_LINE_IN, |
1197 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1068 | }, { | 1198 | }, { |
1069 | .type = EM28XX_VMUX_SVIDEO, | 1199 | .type = EM28XX_VMUX_SVIDEO, |
1070 | .vmux = TVP5150_SVIDEO, | 1200 | .vmux = TVP5150_SVIDEO, |
1071 | .amux = 1, | 1201 | .amux = EM28XX_AMUX_LINE_IN, |
1202 | .gpio = hauppauge_wintv_hvr_900_analog, | ||
1072 | } }, | 1203 | } }, |
1073 | }, | 1204 | }, |
1074 | [EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = { | 1205 | [EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = { |
1075 | .name = "Compro VideoMate ForYou/Stereo", | 1206 | .name = "Compro VideoMate ForYou/Stereo", |
1076 | .vchannels = 2, | ||
1077 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, | 1207 | .tuner_type = TUNER_LG_PAL_NEW_TAPC, |
1078 | .tda9887_conf = TDA9887_PRESENT, | 1208 | .tda9887_conf = TDA9887_PRESENT, |
1079 | .decoder = EM28XX_TVP5150, | 1209 | .decoder = EM28XX_TVP5150, |
1080 | .input = { { | 1210 | .input = { { |
1081 | .type = EM28XX_VMUX_TELEVISION, | 1211 | .type = EM28XX_VMUX_TELEVISION, |
1082 | .vmux = TVP5150_COMPOSITE0, | 1212 | .vmux = TVP5150_COMPOSITE0, |
1083 | .amux = EM28XX_AMUX_LINE_IN, | 1213 | .amux = EM28XX_AMUX_LINE_IN, |
@@ -1101,7 +1231,7 @@ struct usb_device_id em28xx_id_table [] = { | |||
1101 | { USB_DEVICE(0xeb1a, 0x2820), | 1231 | { USB_DEVICE(0xeb1a, 0x2820), |
1102 | .driver_info = EM2820_BOARD_UNKNOWN }, | 1232 | .driver_info = EM2820_BOARD_UNKNOWN }, |
1103 | { USB_DEVICE(0xeb1a, 0x2821), | 1233 | { USB_DEVICE(0xeb1a, 0x2821), |
1104 | .driver_info = EM2820_BOARD_PROLINK_PLAYTV_USB2 }, | 1234 | .driver_info = EM2820_BOARD_UNKNOWN }, |
1105 | { USB_DEVICE(0xeb1a, 0x2860), | 1235 | { USB_DEVICE(0xeb1a, 0x2860), |
1106 | .driver_info = EM2820_BOARD_UNKNOWN }, | 1236 | .driver_info = EM2820_BOARD_UNKNOWN }, |
1107 | { USB_DEVICE(0xeb1a, 0x2861), | 1237 | { USB_DEVICE(0xeb1a, 0x2861), |
@@ -1164,8 +1294,8 @@ struct usb_device_id em28xx_id_table [] = { | |||
1164 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, | 1294 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, |
1165 | { USB_DEVICE(0x2040, 0x651b), /* RP HVR-950 */ | 1295 | { USB_DEVICE(0x2040, 0x651b), /* RP HVR-950 */ |
1166 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, | 1296 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, |
1167 | { USB_DEVICE(0x2040, 0x651f), /* HCW HVR-850 */ | 1297 | { USB_DEVICE(0x2040, 0x651f), |
1168 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950 }, | 1298 | .driver_info = EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 }, |
1169 | { USB_DEVICE(0x0438, 0xb002), | 1299 | { USB_DEVICE(0x0438, 0xb002), |
1170 | .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, | 1300 | .driver_info = EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600 }, |
1171 | { USB_DEVICE(0x2001, 0xf112), | 1301 | { USB_DEVICE(0x2001, 0xf112), |
@@ -1189,78 +1319,12 @@ struct usb_device_id em28xx_id_table [] = { | |||
1189 | MODULE_DEVICE_TABLE(usb, em28xx_id_table); | 1319 | MODULE_DEVICE_TABLE(usb, em28xx_id_table); |
1190 | 1320 | ||
1191 | /* | 1321 | /* |
1192 | * Reset sequences for analog/digital modes | ||
1193 | */ | ||
1194 | |||
1195 | /* Reset for the most [analog] boards */ | ||
1196 | static struct em28xx_reg_seq default_analog[] = { | ||
1197 | {EM28XX_R08_GPIO, 0x6d, ~EM_GPIO_4, 10}, | ||
1198 | { -1, -1, -1, -1}, | ||
1199 | }; | ||
1200 | |||
1201 | /* Reset for the most [digital] boards */ | ||
1202 | static struct em28xx_reg_seq default_digital[] = { | ||
1203 | {EM28XX_R08_GPIO, 0x6e, ~EM_GPIO_4, 10}, | ||
1204 | { -1, -1, -1, -1}, | ||
1205 | }; | ||
1206 | |||
1207 | /* Board Hauppauge WinTV HVR 900 analog */ | ||
1208 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900_analog[] = { | ||
1209 | {EM28XX_R08_GPIO, 0x2d, ~EM_GPIO_4, 10}, | ||
1210 | {0x05, 0xff, 0x10, 10}, | ||
1211 | { -1, -1, -1, -1}, | ||
1212 | }; | ||
1213 | |||
1214 | /* Board Hauppauge WinTV HVR 900 digital */ | ||
1215 | static struct em28xx_reg_seq hauppauge_wintv_hvr_900_digital[] = { | ||
1216 | {EM28XX_R08_GPIO, 0x2e, ~EM_GPIO_4, 10}, | ||
1217 | {EM2880_R04_GPO, 0x04, 0x0f, 10}, | ||
1218 | {EM2880_R04_GPO, 0x0c, 0x0f, 10}, | ||
1219 | { -1, -1, -1, -1}, | ||
1220 | }; | ||
1221 | |||
1222 | /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ | ||
1223 | static struct em28xx_reg_seq em2880_msi_digivox_ad_analog[] = { | ||
1224 | {EM28XX_R08_GPIO, 0x69, ~EM_GPIO_4, 10}, | ||
1225 | { -1, -1, -1, -1}, | ||
1226 | }; | ||
1227 | |||
1228 | /* Boards - EM2880 MSI DIGIVOX AD and EM2880_BOARD_MSI_DIGIVOX_AD_II */ | ||
1229 | static struct em28xx_reg_seq em2880_msi_digivox_ad_digital[] = { | ||
1230 | {EM28XX_R08_GPIO, 0x6a, ~EM_GPIO_4, 10}, | ||
1231 | { -1, -1, -1, -1}, | ||
1232 | }; | ||
1233 | |||
1234 | /* Board - EM2870 Kworld 355u | ||
1235 | Analog - No input analog */ | ||
1236 | static struct em28xx_reg_seq em2870_kworld_355u_digital[] = { | ||
1237 | {EM2880_R04_GPO, 0x01, 0xff, 10}, | ||
1238 | { -1, -1, -1, -1}, | ||
1239 | }; | ||
1240 | |||
1241 | /* Callback for the most boards */ | ||
1242 | static struct em28xx_reg_seq default_callback[] = { | ||
1243 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, | ||
1244 | {EM28XX_R08_GPIO, 0, EM_GPIO_4, 10}, | ||
1245 | {EM28XX_R08_GPIO, EM_GPIO_4, EM_GPIO_4, 10}, | ||
1246 | { -1, -1, -1, -1}, | ||
1247 | }; | ||
1248 | |||
1249 | /* Callback for EM2882 TERRATEC HYBRID XS */ | ||
1250 | static struct em28xx_reg_seq em2882_terratec_hybrid_xs_digital[] = { | ||
1251 | {EM28XX_R08_GPIO, 0x2e, 0xff, 6}, | ||
1252 | {EM28XX_R08_GPIO, 0x3e, ~EM_GPIO_4, 6}, | ||
1253 | {EM2880_R04_GPO, 0x04, 0xff, 10}, | ||
1254 | {EM2880_R04_GPO, 0x0c, 0xff, 10}, | ||
1255 | { -1, -1, -1, -1}, | ||
1256 | }; | ||
1257 | |||
1258 | /* | ||
1259 | * EEPROM hash table for devices with generic USB IDs | 1322 | * EEPROM hash table for devices with generic USB IDs |
1260 | */ | 1323 | */ |
1261 | static struct em28xx_hash_table em28xx_eeprom_hash [] = { | 1324 | static struct em28xx_hash_table em28xx_eeprom_hash [] = { |
1262 | /* P/N: SA 60002070465 Tuner: TVF7533-MF */ | 1325 | /* P/N: SA 60002070465 Tuner: TVF7533-MF */ |
1263 | {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, | 1326 | {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF}, |
1327 | {0x72cc5a8b, EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2, TUNER_YMEC_TVF_5533MF}, | ||
1264 | {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, | 1328 | {0x966a0441, EM2880_BOARD_KWORLD_DVB_310U, TUNER_XC2028}, |
1265 | }; | 1329 | }; |
1266 | 1330 | ||
@@ -1282,27 +1346,26 @@ int em28xx_tuner_callback(void *ptr, int component, int command, int arg) | |||
1282 | if (command != XC2028_TUNER_RESET) | 1346 | if (command != XC2028_TUNER_RESET) |
1283 | return 0; | 1347 | return 0; |
1284 | 1348 | ||
1285 | if (dev->mode == EM28XX_ANALOG_MODE) | 1349 | rc = em28xx_gpio_set(dev, dev->board.tuner_gpio); |
1286 | rc = em28xx_gpio_set(dev, dev->tun_analog_gpio); | ||
1287 | else | ||
1288 | rc = em28xx_gpio_set(dev, dev->tun_digital_gpio); | ||
1289 | 1350 | ||
1290 | return rc; | 1351 | return rc; |
1291 | } | 1352 | } |
1292 | EXPORT_SYMBOL_GPL(em28xx_tuner_callback); | 1353 | EXPORT_SYMBOL_GPL(em28xx_tuner_callback); |
1293 | 1354 | ||
1294 | static void em28xx_set_model(struct em28xx *dev) | 1355 | static void inline em28xx_set_model(struct em28xx *dev) |
1295 | { | 1356 | { |
1296 | dev->is_em2800 = em28xx_boards[dev->model].is_em2800; | 1357 | memcpy(&dev->board, &em28xx_boards[dev->model], sizeof(dev->board)); |
1297 | dev->has_msp34xx = em28xx_boards[dev->model].has_msp34xx; | 1358 | |
1298 | dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf; | 1359 | /* Those are the default values for the majority of boards |
1299 | dev->decoder = em28xx_boards[dev->model].decoder; | 1360 | Use those values if not specified otherwise at boards entry |
1300 | dev->video_inputs = em28xx_boards[dev->model].vchannels; | 1361 | */ |
1301 | dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s; | 1362 | if (!dev->board.xclk) |
1302 | dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480; | 1363 | dev->board.xclk = EM28XX_XCLK_IR_RC5_MODE | |
1303 | dev->has_dvb = em28xx_boards[dev->model].has_dvb; | 1364 | EM28XX_XCLK_FREQUENCY_12MHZ; |
1304 | dev->has_snapshot_button = em28xx_boards[dev->model].has_snapshot_button; | 1365 | |
1305 | dev->valid = em28xx_boards[dev->model].valid; | 1366 | if (!dev->board.i2c_speed) |
1367 | dev->board.i2c_speed = EM28XX_I2C_CLK_WAIT_ENABLE | | ||
1368 | EM28XX_I2C_FREQ_100_KHZ; | ||
1306 | } | 1369 | } |
1307 | 1370 | ||
1308 | /* Since em28xx_pre_card_setup() requires a proper dev->model, | 1371 | /* Since em28xx_pre_card_setup() requires a proper dev->model, |
@@ -1312,205 +1375,126 @@ void em28xx_pre_card_setup(struct em28xx *dev) | |||
1312 | { | 1375 | { |
1313 | int rc; | 1376 | int rc; |
1314 | 1377 | ||
1315 | rc = em28xx_read_reg(dev, EM2880_R04_GPO); | 1378 | em28xx_set_model(dev); |
1316 | if (rc >= 0) | 1379 | |
1317 | dev->reg_gpo = rc; | 1380 | em28xx_info("Identified as %s (card=%d)\n", |
1381 | dev->board.name, dev->model); | ||
1382 | |||
1383 | /* Set the default GPO/GPIO for legacy devices */ | ||
1384 | dev->reg_gpo_num = EM2880_R04_GPO; | ||
1385 | dev->reg_gpio_num = EM28XX_R08_GPIO; | ||
1318 | 1386 | ||
1319 | dev->wait_after_write = 5; | 1387 | dev->wait_after_write = 5; |
1388 | |||
1389 | /* Based on the Chip ID, set the device configuration */ | ||
1320 | rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); | 1390 | rc = em28xx_read_reg(dev, EM28XX_R0A_CHIPID); |
1321 | if (rc > 0) { | 1391 | if (rc > 0) { |
1322 | switch (rc) { | 1392 | dev->chip_id = rc; |
1393 | |||
1394 | switch (dev->chip_id) { | ||
1395 | case CHIP_ID_EM2750: | ||
1396 | em28xx_info("chip ID is em2750\n"); | ||
1397 | break; | ||
1398 | case CHIP_ID_EM2820: | ||
1399 | em28xx_info("chip ID is em2820\n"); | ||
1400 | break; | ||
1401 | case CHIP_ID_EM2840: | ||
1402 | em28xx_info("chip ID is em2840\n"); | ||
1403 | break; | ||
1323 | case CHIP_ID_EM2860: | 1404 | case CHIP_ID_EM2860: |
1324 | em28xx_info("chip ID is em2860\n"); | 1405 | em28xx_info("chip ID is em2860\n"); |
1325 | break; | 1406 | break; |
1407 | case CHIP_ID_EM2870: | ||
1408 | em28xx_info("chip ID is em2870\n"); | ||
1409 | dev->wait_after_write = 0; | ||
1410 | break; | ||
1411 | case CHIP_ID_EM2874: | ||
1412 | em28xx_info("chip ID is em2874\n"); | ||
1413 | dev->reg_gpio_num = EM2874_R80_GPIO; | ||
1414 | dev->wait_after_write = 0; | ||
1415 | break; | ||
1326 | case CHIP_ID_EM2883: | 1416 | case CHIP_ID_EM2883: |
1327 | em28xx_info("chip ID is em2882/em2883\n"); | 1417 | em28xx_info("chip ID is em2882/em2883\n"); |
1328 | dev->wait_after_write = 0; | 1418 | dev->wait_after_write = 0; |
1329 | break; | 1419 | break; |
1330 | default: | 1420 | default: |
1331 | em28xx_info("em28xx chip ID = %d\n", rc); | 1421 | em28xx_info("em28xx chip ID = %d\n", dev->chip_id); |
1332 | } | 1422 | } |
1333 | } | 1423 | } |
1334 | em28xx_set_model(dev); | ||
1335 | |||
1336 | /* request some modules */ | ||
1337 | switch (dev->model) { | ||
1338 | case EM2880_BOARD_TERRATEC_PRODIGY_XS: | ||
1339 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
1340 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: | ||
1341 | case EM2860_BOARD_TERRATEC_HYBRID_XS: | ||
1342 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: | ||
1343 | case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: | ||
1344 | case EM2882_BOARD_PINNACLE_HYBRID_PRO: | ||
1345 | case EM2883_BOARD_KWORLD_HYBRID_A316: | ||
1346 | case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: | ||
1347 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); | ||
1348 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | ||
1349 | msleep(50); | ||
1350 | |||
1351 | /* Sets GPO/GPIO sequences for this device */ | ||
1352 | dev->analog_gpio = hauppauge_wintv_hvr_900_analog; | ||
1353 | dev->digital_gpio = hauppauge_wintv_hvr_900_digital; | ||
1354 | dev->tun_analog_gpio = default_callback; | ||
1355 | dev->tun_digital_gpio = default_callback; | ||
1356 | break; | ||
1357 | |||
1358 | case EM2882_BOARD_TERRATEC_HYBRID_XS: | ||
1359 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); | ||
1360 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | ||
1361 | msleep(50); | ||
1362 | |||
1363 | /* should be added ir_codes here */ | ||
1364 | |||
1365 | /* Sets GPO/GPIO sequences for this device */ | ||
1366 | dev->analog_gpio = hauppauge_wintv_hvr_900_analog; | ||
1367 | dev->digital_gpio = hauppauge_wintv_hvr_900_digital; | ||
1368 | dev->tun_analog_gpio = default_callback; | ||
1369 | dev->tun_digital_gpio = em2882_terratec_hybrid_xs_digital; | ||
1370 | break; | ||
1371 | |||
1372 | case EM2880_BOARD_TERRATEC_HYBRID_XS_FR: | ||
1373 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | ||
1374 | case EM2870_BOARD_TERRATEC_XS: | ||
1375 | case EM2881_BOARD_PINNACLE_HYBRID_PRO: | ||
1376 | case EM2880_BOARD_KWORLD_DVB_310U: | ||
1377 | case EM2870_BOARD_KWORLD_350U: | ||
1378 | case EM2881_BOARD_DNT_DA2_HYBRID: | ||
1379 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); | ||
1380 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | ||
1381 | msleep(50); | ||
1382 | |||
1383 | /* NOTE: EM2881_DNT_DA2_HYBRID spend 140 msleep for digital | ||
1384 | and analog commands. If this commands doesn't work, | ||
1385 | add this timer. */ | ||
1386 | |||
1387 | /* Sets GPO/GPIO sequences for this device */ | ||
1388 | dev->analog_gpio = default_analog; | ||
1389 | dev->digital_gpio = default_digital; | ||
1390 | dev->tun_analog_gpio = default_callback; | ||
1391 | dev->tun_digital_gpio = default_callback; | ||
1392 | break; | ||
1393 | 1424 | ||
1394 | case EM2880_BOARD_MSI_DIGIVOX_AD: | 1425 | /* Prepopulate cached GPO register content */ |
1395 | case EM2880_BOARD_MSI_DIGIVOX_AD_II: | 1426 | rc = em28xx_read_reg(dev, dev->reg_gpo_num); |
1396 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); | 1427 | if (rc >= 0) |
1397 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | 1428 | dev->reg_gpo = rc; |
1398 | msleep(50); | ||
1399 | |||
1400 | /* Sets GPO/GPIO sequences for this device */ | ||
1401 | dev->analog_gpio = em2880_msi_digivox_ad_analog; | ||
1402 | dev->digital_gpio = em2880_msi_digivox_ad_digital; | ||
1403 | dev->tun_analog_gpio = default_callback; | ||
1404 | dev->tun_digital_gpio = default_callback; | ||
1405 | break; | ||
1406 | 1429 | ||
1407 | case EM2750_BOARD_UNKNOWN: | 1430 | /* Set the initial XCLK and I2C clock values based on the board |
1408 | case EM2750_BOARD_DLCW_130: | 1431 | definition */ |
1409 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x0a", 1); | 1432 | em28xx_write_reg(dev, EM28XX_R0F_XCLK, dev->board.xclk & 0x7f); |
1410 | break; | 1433 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, dev->board.i2c_speed); |
1434 | msleep(50); | ||
1411 | 1435 | ||
1436 | /* request some modules */ | ||
1437 | switch (dev->model) { | ||
1412 | case EM2861_BOARD_PLEXTOR_PX_TV100U: | 1438 | case EM2861_BOARD_PLEXTOR_PX_TV100U: |
1413 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); | ||
1414 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | ||
1415 | /* FIXME guess */ | 1439 | /* FIXME guess */ |
1416 | /* Turn on analog audio output */ | 1440 | /* Turn on analog audio output */ |
1417 | em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1); | 1441 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); |
1418 | break; | 1442 | break; |
1419 | |||
1420 | case EM2861_BOARD_KWORLD_PVRTV_300U: | 1443 | case EM2861_BOARD_KWORLD_PVRTV_300U: |
1421 | case EM2880_BOARD_KWORLD_DVB_305U: | 1444 | case EM2880_BOARD_KWORLD_DVB_305U: |
1422 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); | 1445 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x6d); |
1423 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x4c", 1); | ||
1424 | msleep(10); | ||
1425 | em28xx_write_regs(dev, 0x08, "\x6d", 1); | ||
1426 | msleep(10); | 1446 | msleep(10); |
1427 | em28xx_write_regs(dev, 0x08, "\x7d", 1); | 1447 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0x7d); |
1428 | msleep(10); | 1448 | msleep(10); |
1429 | break; | 1449 | break; |
1430 | |||
1431 | case EM2870_BOARD_KWORLD_355U: | ||
1432 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); | ||
1433 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | ||
1434 | msleep(50); | ||
1435 | |||
1436 | /* Sets GPO/GPIO sequences for this device */ | ||
1437 | dev->digital_gpio = em2870_kworld_355u_digital; | ||
1438 | break; | ||
1439 | |||
1440 | case EM2870_BOARD_COMPRO_VIDEOMATE: | 1450 | case EM2870_BOARD_COMPRO_VIDEOMATE: |
1441 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); | ||
1442 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | ||
1443 | /* TODO: someone can do some cleanup here... | 1451 | /* TODO: someone can do some cleanup here... |
1444 | not everything's needed */ | 1452 | not everything's needed */ |
1445 | em28xx_write_regs(dev, 0x04, "\x00", 1); | 1453 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x00); |
1446 | msleep(10); | 1454 | msleep(10); |
1447 | em28xx_write_regs(dev, 0x04, "\x01", 1); | 1455 | em28xx_write_reg(dev, EM2880_R04_GPO, 0x01); |
1448 | msleep(10); | 1456 | msleep(10); |
1449 | em28xx_write_regs(dev, 0x08, "\xfd", 1); | 1457 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); |
1450 | mdelay(70); | 1458 | mdelay(70); |
1451 | em28xx_write_regs(dev, 0x08, "\xfc", 1); | 1459 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc); |
1452 | mdelay(70); | 1460 | mdelay(70); |
1453 | em28xx_write_regs(dev, 0x08, "\xdc", 1); | 1461 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xdc); |
1454 | mdelay(70); | 1462 | mdelay(70); |
1455 | em28xx_write_regs(dev, 0x08, "\xfc", 1); | 1463 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfc); |
1456 | mdelay(70); | 1464 | mdelay(70); |
1457 | break; | 1465 | break; |
1458 | |||
1459 | case EM2870_BOARD_TERRATEC_XS_MT2060: | 1466 | case EM2870_BOARD_TERRATEC_XS_MT2060: |
1460 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); | ||
1461 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | ||
1462 | /* this device needs some gpio writes to get the DVB-T | 1467 | /* this device needs some gpio writes to get the DVB-T |
1463 | demod work */ | 1468 | demod work */ |
1464 | em28xx_write_regs(dev, 0x08, "\xfe", 1); | 1469 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); |
1465 | mdelay(70); | 1470 | mdelay(70); |
1466 | em28xx_write_regs(dev, 0x08, "\xde", 1); | 1471 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde); |
1467 | mdelay(70); | 1472 | mdelay(70); |
1468 | dev->em28xx_write_regs(dev, 0x08, "\xfe", 1); | 1473 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); |
1469 | mdelay(70); | 1474 | mdelay(70); |
1470 | break; | 1475 | break; |
1471 | |||
1472 | case EM2870_BOARD_PINNACLE_PCTV_DVB: | 1476 | case EM2870_BOARD_PINNACLE_PCTV_DVB: |
1473 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | ||
1474 | /* this device needs some gpio writes to get the | 1477 | /* this device needs some gpio writes to get the |
1475 | DVB-T demod work */ | 1478 | DVB-T demod work */ |
1476 | em28xx_write_regs(dev, 0x08, "\xfe", 1); | 1479 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); |
1477 | mdelay(70); | 1480 | mdelay(70); |
1478 | em28xx_write_regs(dev, 0x08, "\xde", 1); | 1481 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xde); |
1479 | mdelay(70); | 1482 | mdelay(70); |
1480 | em28xx_write_regs(dev, 0x08, "\xfe", 1); | 1483 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfe); |
1481 | mdelay(70); | 1484 | mdelay(70); |
1482 | /* switch em2880 rc protocol */ | ||
1483 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x22", 1); | ||
1484 | /* should be added ir_codes here */ | ||
1485 | break; | 1485 | break; |
1486 | |||
1487 | case EM2820_BOARD_GADMEI_UTV310: | 1486 | case EM2820_BOARD_GADMEI_UTV310: |
1488 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); | ||
1489 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | ||
1490 | /* Turn on analog audio output */ | ||
1491 | em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1); | ||
1492 | break; | ||
1493 | |||
1494 | case EM2860_BOARD_GADMEI_UTV330: | ||
1495 | /* Turn on IR */ | ||
1496 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x07", 1); | ||
1497 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | ||
1498 | /* should be added ir_codes here */ | ||
1499 | break; | ||
1500 | |||
1501 | case EM2820_BOARD_MSI_VOX_USB_2: | 1487 | case EM2820_BOARD_MSI_VOX_USB_2: |
1502 | em28xx_write_regs(dev, EM28XX_R0F_XCLK, "\x27", 1); | 1488 | /* enables audio for that devices */ |
1503 | em28xx_write_regs(dev, EM28XX_R06_I2C_CLK, "\x40", 1); | 1489 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xfd); |
1504 | /* enables audio for that device */ | ||
1505 | em28xx_write_regs_req(dev, 0x00, 0x08, "\xfd", 1); | ||
1506 | break; | 1490 | break; |
1507 | } | 1491 | } |
1508 | 1492 | ||
1509 | em28xx_gpio_set(dev, dev->tun_analog_gpio); | 1493 | em28xx_gpio_set(dev, dev->board.tuner_gpio); |
1510 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); | 1494 | em28xx_set_mode(dev, EM28XX_ANALOG_MODE); |
1511 | 1495 | ||
1512 | /* Unlock device */ | 1496 | /* Unlock device */ |
1513 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | 1497 | em28xx_set_mode(dev, EM28XX_SUSPEND); |
1514 | } | 1498 | } |
1515 | 1499 | ||
1516 | static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) | 1500 | static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) |
@@ -1536,6 +1520,7 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl) | |||
1536 | ctl->demod = XC3028_FE_DEFAULT; | 1520 | ctl->demod = XC3028_FE_DEFAULT; |
1537 | ctl->fname = XC3028L_DEFAULT_FIRMWARE; | 1521 | ctl->fname = XC3028L_DEFAULT_FIRMWARE; |
1538 | break; | 1522 | break; |
1523 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: | ||
1539 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: | 1524 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: |
1540 | case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: | 1525 | case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: |
1541 | /* FIXME: Better to specify the needed IF */ | 1526 | /* FIXME: Better to specify the needed IF */ |
@@ -1712,12 +1697,15 @@ void em28xx_card_setup(struct em28xx *dev) | |||
1712 | em28xx_set_model(dev); | 1697 | em28xx_set_model(dev); |
1713 | 1698 | ||
1714 | dev->tuner_type = em28xx_boards[dev->model].tuner_type; | 1699 | dev->tuner_type = em28xx_boards[dev->model].tuner_type; |
1700 | if (em28xx_boards[dev->model].tuner_addr) | ||
1701 | dev->tuner_addr = em28xx_boards[dev->model].tuner_addr; | ||
1715 | 1702 | ||
1716 | /* request some modules */ | 1703 | /* request some modules */ |
1717 | switch (dev->model) { | 1704 | switch (dev->model) { |
1718 | case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: | 1705 | case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: |
1719 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | 1706 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: |
1720 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: | 1707 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: |
1708 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: | ||
1721 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: | 1709 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: |
1722 | { | 1710 | { |
1723 | struct tveeprom tv; | 1711 | struct tveeprom tv; |
@@ -1733,7 +1721,7 @@ void em28xx_card_setup(struct em28xx *dev) | |||
1733 | 1721 | ||
1734 | if (tv.audio_processor == V4L2_IDENT_MSPX4XX) { | 1722 | if (tv.audio_processor == V4L2_IDENT_MSPX4XX) { |
1735 | dev->i2s_speed = 2048000; | 1723 | dev->i2s_speed = 2048000; |
1736 | dev->has_msp34xx = 1; | 1724 | dev->board.has_msp34xx = 1; |
1737 | } | 1725 | } |
1738 | #ifdef CONFIG_MODULES | 1726 | #ifdef CONFIG_MODULES |
1739 | if (tv.has_ir) | 1727 | if (tv.has_ir) |
@@ -1743,7 +1731,7 @@ void em28xx_card_setup(struct em28xx *dev) | |||
1743 | } | 1731 | } |
1744 | case EM2820_BOARD_KWORLD_PVRTV2800RF: | 1732 | case EM2820_BOARD_KWORLD_PVRTV2800RF: |
1745 | /* GPIO enables sound on KWORLD PVR TV 2800RF */ | 1733 | /* GPIO enables sound on KWORLD PVR TV 2800RF */ |
1746 | em28xx_write_regs_req(dev, 0x00, 0x08, "\xf9", 1); | 1734 | em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf9); |
1747 | break; | 1735 | break; |
1748 | case EM2820_BOARD_UNKNOWN: | 1736 | case EM2820_BOARD_UNKNOWN: |
1749 | case EM2800_BOARD_UNKNOWN: | 1737 | case EM2800_BOARD_UNKNOWN: |
@@ -1766,10 +1754,10 @@ void em28xx_card_setup(struct em28xx *dev) | |||
1766 | break; | 1754 | break; |
1767 | } | 1755 | } |
1768 | 1756 | ||
1769 | if (dev->has_snapshot_button) | 1757 | if (dev->board.has_snapshot_button) |
1770 | em28xx_register_snapshot_button(dev); | 1758 | em28xx_register_snapshot_button(dev); |
1771 | 1759 | ||
1772 | if (dev->valid == EM28XX_BOARD_NOT_VALIDATED) { | 1760 | if (dev->board.valid == EM28XX_BOARD_NOT_VALIDATED) { |
1773 | em28xx_errdev("\n\n"); | 1761 | em28xx_errdev("\n\n"); |
1774 | em28xx_errdev("The support for this board weren't " | 1762 | em28xx_errdev("The support for this board weren't " |
1775 | "valid yet.\n"); | 1763 | "valid yet.\n"); |
@@ -1784,15 +1772,433 @@ void em28xx_card_setup(struct em28xx *dev) | |||
1784 | 1772 | ||
1785 | #ifdef CONFIG_MODULES | 1773 | #ifdef CONFIG_MODULES |
1786 | /* request some modules */ | 1774 | /* request some modules */ |
1787 | if (dev->has_msp34xx) | 1775 | if (dev->board.has_msp34xx) |
1788 | request_module("msp3400"); | 1776 | request_module("msp3400"); |
1789 | if (dev->decoder == EM28XX_SAA7113 || dev->decoder == EM28XX_SAA7114) | 1777 | if (dev->board.decoder == EM28XX_SAA711X) |
1790 | request_module("saa7115"); | 1778 | request_module("saa7115"); |
1791 | if (dev->decoder == EM28XX_TVP5150) | 1779 | if (dev->board.decoder == EM28XX_TVP5150) |
1792 | request_module("tvp5150"); | 1780 | request_module("tvp5150"); |
1793 | if (dev->tuner_type != TUNER_ABSENT) | 1781 | if (dev->board.tuner_type != TUNER_ABSENT) |
1794 | request_module("tuner"); | 1782 | request_module("tuner"); |
1795 | #endif | 1783 | #endif |
1796 | 1784 | ||
1797 | em28xx_config_tuner(dev); | 1785 | em28xx_config_tuner(dev); |
1786 | |||
1787 | em28xx_ir_init(dev); | ||
1788 | } | ||
1789 | |||
1790 | |||
1791 | #if defined(CONFIG_MODULES) && defined(MODULE) | ||
1792 | static void request_module_async(struct work_struct *work) | ||
1793 | { | ||
1794 | struct em28xx *dev = container_of(work, | ||
1795 | struct em28xx, request_module_wk); | ||
1796 | |||
1797 | if (dev->has_audio_class) | ||
1798 | request_module("snd-usb-audio"); | ||
1799 | else if (dev->has_alsa_audio) | ||
1800 | request_module("em28xx-alsa"); | ||
1801 | |||
1802 | if (dev->board.has_dvb) | ||
1803 | request_module("em28xx-dvb"); | ||
1804 | } | ||
1805 | |||
1806 | static void request_modules(struct em28xx *dev) | ||
1807 | { | ||
1808 | INIT_WORK(&dev->request_module_wk, request_module_async); | ||
1809 | schedule_work(&dev->request_module_wk); | ||
1810 | } | ||
1811 | #else | ||
1812 | #define request_modules(dev) | ||
1813 | #endif /* CONFIG_MODULES */ | ||
1814 | |||
1815 | /* | ||
1816 | * em28xx_realease_resources() | ||
1817 | * unregisters the v4l2,i2c and usb devices | ||
1818 | * called when the device gets disconected or at module unload | ||
1819 | */ | ||
1820 | void em28xx_release_resources(struct em28xx *dev) | ||
1821 | { | ||
1822 | if (dev->sbutton_input_dev) | ||
1823 | em28xx_deregister_snapshot_button(dev); | ||
1824 | |||
1825 | if (dev->ir) | ||
1826 | em28xx_ir_fini(dev); | ||
1827 | |||
1828 | /*FIXME: I2C IR should be disconnected */ | ||
1829 | |||
1830 | em28xx_release_analog_resources(dev); | ||
1831 | |||
1832 | em28xx_remove_from_devlist(dev); | ||
1833 | |||
1834 | em28xx_i2c_unregister(dev); | ||
1835 | usb_put_dev(dev->udev); | ||
1836 | |||
1837 | /* Mark device as unused */ | ||
1838 | em28xx_devused &= ~(1 << dev->devno); | ||
1839 | }; | ||
1840 | |||
1841 | /* | ||
1842 | * em28xx_init_dev() | ||
1843 | * allocates and inits the device structs, registers i2c bus and v4l device | ||
1844 | */ | ||
1845 | int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | ||
1846 | int minor) | ||
1847 | { | ||
1848 | struct em28xx *dev = *devhandle; | ||
1849 | int retval = -ENOMEM; | ||
1850 | int errCode; | ||
1851 | |||
1852 | dev->udev = udev; | ||
1853 | mutex_init(&dev->ctrl_urb_lock); | ||
1854 | spin_lock_init(&dev->slock); | ||
1855 | init_waitqueue_head(&dev->open); | ||
1856 | init_waitqueue_head(&dev->wait_frame); | ||
1857 | init_waitqueue_head(&dev->wait_stream); | ||
1858 | |||
1859 | dev->em28xx_write_regs = em28xx_write_regs; | ||
1860 | dev->em28xx_read_reg = em28xx_read_reg; | ||
1861 | dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len; | ||
1862 | dev->em28xx_write_regs_req = em28xx_write_regs_req; | ||
1863 | dev->em28xx_read_reg_req = em28xx_read_reg_req; | ||
1864 | dev->board.is_em2800 = em28xx_boards[dev->model].is_em2800; | ||
1865 | |||
1866 | em28xx_pre_card_setup(dev); | ||
1867 | |||
1868 | if (!dev->board.is_em2800) { | ||
1869 | /* Sets I2C speed to 100 KHz */ | ||
1870 | retval = em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); | ||
1871 | if (retval < 0) { | ||
1872 | em28xx_errdev("%s: em28xx_write_regs_req failed!" | ||
1873 | " retval [%d]\n", | ||
1874 | __func__, retval); | ||
1875 | return retval; | ||
1876 | } | ||
1877 | } | ||
1878 | |||
1879 | /* register i2c bus */ | ||
1880 | errCode = em28xx_i2c_register(dev); | ||
1881 | if (errCode < 0) { | ||
1882 | em28xx_errdev("%s: em28xx_i2c_register - errCode [%d]!\n", | ||
1883 | __func__, errCode); | ||
1884 | return errCode; | ||
1885 | } | ||
1886 | |||
1887 | /* Do board specific init and eeprom reading */ | ||
1888 | em28xx_card_setup(dev); | ||
1889 | |||
1890 | /* Configure audio */ | ||
1891 | errCode = em28xx_audio_setup(dev); | ||
1892 | if (errCode < 0) { | ||
1893 | em28xx_errdev("%s: Error while setting audio - errCode [%d]!\n", | ||
1894 | __func__, errCode); | ||
1895 | } | ||
1896 | |||
1897 | /* wake i2c devices */ | ||
1898 | em28xx_wake_i2c(dev); | ||
1899 | |||
1900 | /* init video dma queues */ | ||
1901 | INIT_LIST_HEAD(&dev->vidq.active); | ||
1902 | INIT_LIST_HEAD(&dev->vidq.queued); | ||
1903 | |||
1904 | |||
1905 | if (dev->board.has_msp34xx) { | ||
1906 | /* Send a reset to other chips via gpio */ | ||
1907 | errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xf7); | ||
1908 | if (errCode < 0) { | ||
1909 | em28xx_errdev("%s: em28xx_write_regs_req - " | ||
1910 | "msp34xx(1) failed! errCode [%d]\n", | ||
1911 | __func__, errCode); | ||
1912 | return errCode; | ||
1913 | } | ||
1914 | msleep(3); | ||
1915 | |||
1916 | errCode = em28xx_write_reg(dev, EM28XX_R08_GPIO, 0xff); | ||
1917 | if (errCode < 0) { | ||
1918 | em28xx_errdev("%s: em28xx_write_regs_req - " | ||
1919 | "msp34xx(2) failed! errCode [%d]\n", | ||
1920 | __func__, errCode); | ||
1921 | return errCode; | ||
1922 | } | ||
1923 | msleep(3); | ||
1924 | } | ||
1925 | |||
1926 | em28xx_add_into_devlist(dev); | ||
1927 | |||
1928 | retval = em28xx_register_analog_devices(dev); | ||
1929 | if (retval < 0) { | ||
1930 | em28xx_release_resources(dev); | ||
1931 | goto fail_reg_devices; | ||
1932 | } | ||
1933 | |||
1934 | em28xx_init_extension(dev); | ||
1935 | |||
1936 | /* Save some power by putting tuner to sleep */ | ||
1937 | em28xx_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL); | ||
1938 | |||
1939 | return 0; | ||
1940 | |||
1941 | fail_reg_devices: | ||
1942 | return retval; | ||
1943 | } | ||
1944 | |||
1945 | /* | ||
1946 | * em28xx_usb_probe() | ||
1947 | * checks for supported devices | ||
1948 | */ | ||
1949 | static int em28xx_usb_probe(struct usb_interface *interface, | ||
1950 | const struct usb_device_id *id) | ||
1951 | { | ||
1952 | const struct usb_endpoint_descriptor *endpoint; | ||
1953 | struct usb_device *udev; | ||
1954 | struct usb_interface *uif; | ||
1955 | struct em28xx *dev = NULL; | ||
1956 | int retval = -ENODEV; | ||
1957 | int i, nr, ifnum, isoc_pipe; | ||
1958 | char *speed; | ||
1959 | char descr[255] = ""; | ||
1960 | |||
1961 | udev = usb_get_dev(interface_to_usbdev(interface)); | ||
1962 | ifnum = interface->altsetting[0].desc.bInterfaceNumber; | ||
1963 | |||
1964 | /* Check to see next free device and mark as used */ | ||
1965 | nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS); | ||
1966 | em28xx_devused |= 1<<nr; | ||
1967 | |||
1968 | /* Don't register audio interfaces */ | ||
1969 | if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { | ||
1970 | em28xx_err(DRIVER_NAME " audio device (%04x:%04x): " | ||
1971 | "interface %i, class %i\n", | ||
1972 | le16_to_cpu(udev->descriptor.idVendor), | ||
1973 | le16_to_cpu(udev->descriptor.idProduct), | ||
1974 | ifnum, | ||
1975 | interface->altsetting[0].desc.bInterfaceClass); | ||
1976 | |||
1977 | em28xx_devused &= ~(1<<nr); | ||
1978 | return -ENODEV; | ||
1979 | } | ||
1980 | |||
1981 | endpoint = &interface->cur_altsetting->endpoint[0].desc; | ||
1982 | |||
1983 | /* check if the device has the iso in endpoint at the correct place */ | ||
1984 | if (usb_endpoint_xfer_isoc(endpoint) | ||
1985 | && | ||
1986 | (interface->altsetting[1].endpoint[0].desc.wMaxPacketSize == 940)) { | ||
1987 | /* It's a newer em2874/em2875 device */ | ||
1988 | isoc_pipe = 0; | ||
1989 | } else { | ||
1990 | int check_interface = 1; | ||
1991 | isoc_pipe = 1; | ||
1992 | endpoint = &interface->cur_altsetting->endpoint[1].desc; | ||
1993 | if (usb_endpoint_type(endpoint) != | ||
1994 | USB_ENDPOINT_XFER_ISOC) | ||
1995 | check_interface = 0; | ||
1996 | |||
1997 | if (usb_endpoint_dir_out(endpoint)) | ||
1998 | check_interface = 0; | ||
1999 | |||
2000 | if (!check_interface) { | ||
2001 | em28xx_err(DRIVER_NAME " video device (%04x:%04x): " | ||
2002 | "interface %i, class %i found.\n", | ||
2003 | le16_to_cpu(udev->descriptor.idVendor), | ||
2004 | le16_to_cpu(udev->descriptor.idProduct), | ||
2005 | ifnum, | ||
2006 | interface->altsetting[0].desc.bInterfaceClass); | ||
2007 | |||
2008 | em28xx_err(DRIVER_NAME " This is an anciliary " | ||
2009 | "interface not used by the driver\n"); | ||
2010 | |||
2011 | em28xx_devused &= ~(1<<nr); | ||
2012 | return -ENODEV; | ||
2013 | } | ||
2014 | } | ||
2015 | |||
2016 | switch (udev->speed) { | ||
2017 | case USB_SPEED_LOW: | ||
2018 | speed = "1.5"; | ||
2019 | break; | ||
2020 | case USB_SPEED_UNKNOWN: | ||
2021 | case USB_SPEED_FULL: | ||
2022 | speed = "12"; | ||
2023 | break; | ||
2024 | case USB_SPEED_HIGH: | ||
2025 | speed = "480"; | ||
2026 | break; | ||
2027 | default: | ||
2028 | speed = "unknown"; | ||
2029 | } | ||
2030 | |||
2031 | if (udev->manufacturer) | ||
2032 | strlcpy(descr, udev->manufacturer, sizeof(descr)); | ||
2033 | |||
2034 | if (udev->product) { | ||
2035 | if (*descr) | ||
2036 | strlcat(descr, " ", sizeof(descr)); | ||
2037 | strlcat(descr, udev->product, sizeof(descr)); | ||
2038 | } | ||
2039 | if (*descr) | ||
2040 | strlcat(descr, " ", sizeof(descr)); | ||
2041 | |||
2042 | printk(DRIVER_NAME ": New device %s@ %s Mbps " | ||
2043 | "(%04x:%04x, interface %d, class %d)\n", | ||
2044 | descr, | ||
2045 | speed, | ||
2046 | le16_to_cpu(udev->descriptor.idVendor), | ||
2047 | le16_to_cpu(udev->descriptor.idProduct), | ||
2048 | ifnum, | ||
2049 | interface->altsetting->desc.bInterfaceNumber); | ||
2050 | |||
2051 | if (nr >= EM28XX_MAXBOARDS) { | ||
2052 | printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", | ||
2053 | EM28XX_MAXBOARDS); | ||
2054 | em28xx_devused &= ~(1<<nr); | ||
2055 | return -ENOMEM; | ||
2056 | } | ||
2057 | |||
2058 | /* allocate memory for our device state and initialize it */ | ||
2059 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
2060 | if (dev == NULL) { | ||
2061 | em28xx_err(DRIVER_NAME ": out of memory!\n"); | ||
2062 | em28xx_devused &= ~(1<<nr); | ||
2063 | return -ENOMEM; | ||
2064 | } | ||
2065 | |||
2066 | snprintf(dev->name, 29, "em28xx #%d", nr); | ||
2067 | dev->devno = nr; | ||
2068 | dev->model = id->driver_info; | ||
2069 | dev->alt = -1; | ||
2070 | |||
2071 | /* Checks if audio is provided by some interface */ | ||
2072 | for (i = 0; i < udev->config->desc.bNumInterfaces; i++) { | ||
2073 | uif = udev->config->interface[i]; | ||
2074 | if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { | ||
2075 | dev->has_audio_class = 1; | ||
2076 | break; | ||
2077 | } | ||
2078 | } | ||
2079 | |||
2080 | /* compute alternate max packet sizes */ | ||
2081 | uif = udev->actconfig->interface[0]; | ||
2082 | |||
2083 | dev->num_alt = uif->num_altsetting; | ||
2084 | dev->alt_max_pkt_size = kmalloc(32 * dev->num_alt, GFP_KERNEL); | ||
2085 | |||
2086 | if (dev->alt_max_pkt_size == NULL) { | ||
2087 | em28xx_errdev("out of memory!\n"); | ||
2088 | em28xx_devused &= ~(1<<nr); | ||
2089 | kfree(dev); | ||
2090 | return -ENOMEM; | ||
2091 | } | ||
2092 | |||
2093 | for (i = 0; i < dev->num_alt ; i++) { | ||
2094 | u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[isoc_pipe].desc.wMaxPacketSize); | ||
2095 | dev->alt_max_pkt_size[i] = | ||
2096 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | ||
2097 | } | ||
2098 | |||
2099 | if ((card[nr] >= 0) && (card[nr] < em28xx_bcount)) | ||
2100 | dev->model = card[nr]; | ||
2101 | |||
2102 | /* allocate device struct */ | ||
2103 | mutex_init(&dev->lock); | ||
2104 | mutex_lock(&dev->lock); | ||
2105 | retval = em28xx_init_dev(&dev, udev, nr); | ||
2106 | if (retval) { | ||
2107 | em28xx_devused &= ~(1<<dev->devno); | ||
2108 | kfree(dev); | ||
2109 | |||
2110 | return retval; | ||
2111 | } | ||
2112 | |||
2113 | /* save our data pointer in this interface device */ | ||
2114 | usb_set_intfdata(interface, dev); | ||
2115 | |||
2116 | request_modules(dev); | ||
2117 | |||
2118 | /* Should be the last thing to do, to avoid newer udev's to | ||
2119 | open the device before fully initializing it | ||
2120 | */ | ||
2121 | mutex_unlock(&dev->lock); | ||
2122 | |||
2123 | return 0; | ||
2124 | } | ||
2125 | |||
2126 | /* | ||
2127 | * em28xx_usb_disconnect() | ||
2128 | * called when the device gets diconencted | ||
2129 | * video device will be unregistered on v4l2_close in case it is still open | ||
2130 | */ | ||
2131 | static void em28xx_usb_disconnect(struct usb_interface *interface) | ||
2132 | { | ||
2133 | struct em28xx *dev; | ||
2134 | |||
2135 | dev = usb_get_intfdata(interface); | ||
2136 | usb_set_intfdata(interface, NULL); | ||
2137 | |||
2138 | if (!dev) | ||
2139 | return; | ||
2140 | |||
2141 | em28xx_info("disconnecting %s\n", dev->vdev->name); | ||
2142 | |||
2143 | /* wait until all current v4l2 io is finished then deallocate | ||
2144 | resources */ | ||
2145 | mutex_lock(&dev->lock); | ||
2146 | |||
2147 | wake_up_interruptible_all(&dev->open); | ||
2148 | |||
2149 | if (dev->users) { | ||
2150 | em28xx_warn | ||
2151 | ("device /dev/video%d is open! Deregistration and memory " | ||
2152 | "deallocation are deferred on close.\n", | ||
2153 | dev->vdev->num); | ||
2154 | |||
2155 | dev->state |= DEV_MISCONFIGURED; | ||
2156 | em28xx_uninit_isoc(dev); | ||
2157 | dev->state |= DEV_DISCONNECTED; | ||
2158 | wake_up_interruptible(&dev->wait_frame); | ||
2159 | wake_up_interruptible(&dev->wait_stream); | ||
2160 | } else { | ||
2161 | dev->state |= DEV_DISCONNECTED; | ||
2162 | em28xx_release_resources(dev); | ||
2163 | } | ||
2164 | |||
2165 | em28xx_close_extension(dev); | ||
2166 | |||
2167 | mutex_unlock(&dev->lock); | ||
2168 | |||
2169 | if (!dev->users) { | ||
2170 | kfree(dev->alt_max_pkt_size); | ||
2171 | kfree(dev); | ||
2172 | } | ||
1798 | } | 2173 | } |
2174 | |||
2175 | static struct usb_driver em28xx_usb_driver = { | ||
2176 | .name = "em28xx", | ||
2177 | .probe = em28xx_usb_probe, | ||
2178 | .disconnect = em28xx_usb_disconnect, | ||
2179 | .id_table = em28xx_id_table, | ||
2180 | }; | ||
2181 | |||
2182 | static int __init em28xx_module_init(void) | ||
2183 | { | ||
2184 | int result; | ||
2185 | |||
2186 | /* register this driver with the USB subsystem */ | ||
2187 | result = usb_register(&em28xx_usb_driver); | ||
2188 | if (result) | ||
2189 | em28xx_err(DRIVER_NAME | ||
2190 | " usb_register failed. Error number %d.\n", result); | ||
2191 | |||
2192 | printk(KERN_INFO DRIVER_NAME " driver loaded\n"); | ||
2193 | |||
2194 | return result; | ||
2195 | } | ||
2196 | |||
2197 | static void __exit em28xx_module_exit(void) | ||
2198 | { | ||
2199 | /* deregister this driver with the USB subsystem */ | ||
2200 | usb_deregister(&em28xx_usb_driver); | ||
2201 | } | ||
2202 | |||
2203 | module_init(em28xx_module_init); | ||
2204 | module_exit(em28xx_module_exit); | ||
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c index 15e2b525310d..f8504518586a 100644 --- a/drivers/media/video/em28xx/em28xx-core.c +++ b/drivers/media/video/em28xx/em28xx-core.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/usb.h> | 27 | #include <linux/usb.h> |
28 | #include <linux/vmalloc.h> | 28 | #include <linux/vmalloc.h> |
29 | #include <media/v4l2-common.h> | ||
29 | 30 | ||
30 | #include "em28xx.h" | 31 | #include "em28xx.h" |
31 | 32 | ||
@@ -66,7 +67,8 @@ MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); | |||
66 | int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | 67 | int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, |
67 | char *buf, int len) | 68 | char *buf, int len) |
68 | { | 69 | { |
69 | int ret, byte; | 70 | int ret; |
71 | int pipe = usb_rcvctrlpipe(dev->udev, 0); | ||
70 | 72 | ||
71 | if (dev->state & DEV_DISCONNECTED) | 73 | if (dev->state & DEV_DISCONNECTED) |
72 | return -ENODEV; | 74 | return -ENODEV; |
@@ -74,10 +76,18 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | |||
74 | if (len > URB_MAX_CTRL_SIZE) | 76 | if (len > URB_MAX_CTRL_SIZE) |
75 | return -EINVAL; | 77 | return -EINVAL; |
76 | 78 | ||
77 | em28xx_regdbg("req=%02x, reg=%02x ", req, reg); | 79 | if (reg_debug) { |
80 | printk( KERN_DEBUG "(pipe 0x%08x): " | ||
81 | "IN: %02x %02x %02x %02x %02x %02x %02x %02x ", | ||
82 | pipe, | ||
83 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
84 | req, 0, 0, | ||
85 | reg & 0xff, reg >> 8, | ||
86 | len & 0xff, len >> 8); | ||
87 | } | ||
78 | 88 | ||
79 | mutex_lock(&dev->ctrl_urb_lock); | 89 | mutex_lock(&dev->ctrl_urb_lock); |
80 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, | 90 | ret = usb_control_msg(dev->udev, pipe, req, |
81 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 91 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
82 | 0x0000, reg, dev->urb_buf, len, HZ); | 92 | 0x0000, reg, dev->urb_buf, len, HZ); |
83 | if (ret < 0) { | 93 | if (ret < 0) { |
@@ -93,7 +103,9 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | |||
93 | mutex_unlock(&dev->ctrl_urb_lock); | 103 | mutex_unlock(&dev->ctrl_urb_lock); |
94 | 104 | ||
95 | if (reg_debug) { | 105 | if (reg_debug) { |
96 | printk("%02x values: ", ret); | 106 | int byte; |
107 | |||
108 | printk("<<<"); | ||
97 | for (byte = 0; byte < len; byte++) | 109 | for (byte = 0; byte < len; byte++) |
98 | printk(" %02x", (unsigned char)buf[byte]); | 110 | printk(" %02x", (unsigned char)buf[byte]); |
99 | printk("\n"); | 111 | printk("\n"); |
@@ -108,28 +120,12 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, | |||
108 | */ | 120 | */ |
109 | int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg) | 121 | int em28xx_read_reg_req(struct em28xx *dev, u8 req, u16 reg) |
110 | { | 122 | { |
111 | u8 val; | ||
112 | int ret; | 123 | int ret; |
124 | u8 val; | ||
113 | 125 | ||
114 | if (dev->state & DEV_DISCONNECTED) | 126 | ret = em28xx_read_reg_req_len(dev, req, reg, &val, 1); |
115 | return(-ENODEV); | 127 | if (ret < 0) |
116 | |||
117 | em28xx_regdbg("req=%02x, reg=%02x:", req, reg); | ||
118 | |||
119 | mutex_lock(&dev->ctrl_urb_lock); | ||
120 | ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), req, | ||
121 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
122 | 0x0000, reg, dev->urb_buf, 1, HZ); | ||
123 | val = dev->urb_buf[0]; | ||
124 | mutex_unlock(&dev->ctrl_urb_lock); | ||
125 | |||
126 | if (ret < 0) { | ||
127 | printk(" failed!\n"); | ||
128 | return ret; | 128 | return ret; |
129 | } | ||
130 | |||
131 | if (reg_debug) | ||
132 | printk("%02x\n", (unsigned char) val); | ||
133 | 129 | ||
134 | return val; | 130 | return val; |
135 | } | 131 | } |
@@ -147,6 +143,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
147 | int len) | 143 | int len) |
148 | { | 144 | { |
149 | int ret; | 145 | int ret; |
146 | int pipe = usb_sndctrlpipe(dev->udev, 0); | ||
150 | 147 | ||
151 | if (dev->state & DEV_DISCONNECTED) | 148 | if (dev->state & DEV_DISCONNECTED) |
152 | return -ENODEV; | 149 | return -ENODEV; |
@@ -154,17 +151,25 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | |||
154 | if ((len < 1) || (len > URB_MAX_CTRL_SIZE)) | 151 | if ((len < 1) || (len > URB_MAX_CTRL_SIZE)) |
155 | return -EINVAL; | 152 | return -EINVAL; |
156 | 153 | ||
157 | em28xx_regdbg("req=%02x reg=%02x:", req, reg); | ||
158 | if (reg_debug) { | 154 | if (reg_debug) { |
159 | int i; | 155 | int byte; |
160 | for (i = 0; i < len; ++i) | 156 | |
161 | printk(" %02x", (unsigned char)buf[i]); | 157 | printk( KERN_DEBUG "(pipe 0x%08x): " |
158 | "OUT: %02x %02x %02x %02x %02x %02x %02x %02x >>>", | ||
159 | pipe, | ||
160 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | ||
161 | req, 0, 0, | ||
162 | reg & 0xff, reg >> 8, | ||
163 | len & 0xff, len >> 8); | ||
164 | |||
165 | for (byte = 0; byte < len; byte++) | ||
166 | printk(" %02x", (unsigned char)buf[byte]); | ||
162 | printk("\n"); | 167 | printk("\n"); |
163 | } | 168 | } |
164 | 169 | ||
165 | mutex_lock(&dev->ctrl_urb_lock); | 170 | mutex_lock(&dev->ctrl_urb_lock); |
166 | memcpy(dev->urb_buf, buf, len); | 171 | memcpy(dev->urb_buf, buf, len); |
167 | ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), req, | 172 | ret = usb_control_msg(dev->udev, pipe, req, |
168 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, | 173 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
169 | 0x0000, reg, dev->urb_buf, len, HZ); | 174 | 0x0000, reg, dev->urb_buf, len, HZ); |
170 | mutex_unlock(&dev->ctrl_urb_lock); | 175 | mutex_unlock(&dev->ctrl_urb_lock); |
@@ -187,15 +192,21 @@ int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len) | |||
187 | Not sure what happens on reading GPO register. | 192 | Not sure what happens on reading GPO register. |
188 | */ | 193 | */ |
189 | if (rc >= 0) { | 194 | if (rc >= 0) { |
190 | if (reg == EM2880_R04_GPO) | 195 | if (reg == dev->reg_gpo_num) |
191 | dev->reg_gpo = buf[0]; | 196 | dev->reg_gpo = buf[0]; |
192 | else if (reg == EM28XX_R08_GPIO) | 197 | else if (reg == dev->reg_gpio_num) |
193 | dev->reg_gpio = buf[0]; | 198 | dev->reg_gpio = buf[0]; |
194 | } | 199 | } |
195 | 200 | ||
196 | return rc; | 201 | return rc; |
197 | } | 202 | } |
198 | 203 | ||
204 | /* Write a single register */ | ||
205 | int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val) | ||
206 | { | ||
207 | return em28xx_write_regs(dev, reg, &val, 1); | ||
208 | } | ||
209 | |||
199 | /* | 210 | /* |
200 | * em28xx_write_reg_bits() | 211 | * em28xx_write_reg_bits() |
201 | * sets only some bits (specified by bitmask) of a register, by first reading | 212 | * sets only some bits (specified by bitmask) of a register, by first reading |
@@ -208,9 +219,9 @@ static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, | |||
208 | u8 newval; | 219 | u8 newval; |
209 | 220 | ||
210 | /* Uses cache for gpo/gpio registers */ | 221 | /* Uses cache for gpo/gpio registers */ |
211 | if (reg == EM2880_R04_GPO) | 222 | if (reg == dev->reg_gpo_num) |
212 | oldval = dev->reg_gpo; | 223 | oldval = dev->reg_gpo; |
213 | else if (reg == EM28XX_R08_GPIO) | 224 | else if (reg == dev->reg_gpio_num) |
214 | oldval = dev->reg_gpio; | 225 | oldval = dev->reg_gpio; |
215 | else | 226 | else |
216 | oldval = em28xx_read_reg(dev, reg); | 227 | oldval = em28xx_read_reg(dev, reg); |
@@ -224,15 +235,70 @@ static int em28xx_write_reg_bits(struct em28xx *dev, u16 reg, u8 val, | |||
224 | } | 235 | } |
225 | 236 | ||
226 | /* | 237 | /* |
238 | * em28xx_is_ac97_ready() | ||
239 | * Checks if ac97 is ready | ||
240 | */ | ||
241 | static int em28xx_is_ac97_ready(struct em28xx *dev) | ||
242 | { | ||
243 | int ret, i; | ||
244 | |||
245 | /* Wait up to 50 ms for AC97 command to complete */ | ||
246 | for (i = 0; i < 10; i++, msleep(5)) { | ||
247 | ret = em28xx_read_reg(dev, EM28XX_R43_AC97BUSY); | ||
248 | if (ret < 0) | ||
249 | return ret; | ||
250 | |||
251 | if (!(ret & 0x01)) | ||
252 | return 0; | ||
253 | } | ||
254 | |||
255 | em28xx_warn("AC97 command still being executed: not handled properly!\n"); | ||
256 | return -EBUSY; | ||
257 | } | ||
258 | |||
259 | /* | ||
260 | * em28xx_read_ac97() | ||
261 | * write a 16 bit value to the specified AC97 address (LSB first!) | ||
262 | */ | ||
263 | int em28xx_read_ac97(struct em28xx *dev, u8 reg) | ||
264 | { | ||
265 | int ret; | ||
266 | u8 addr = (reg & 0x7f) | 0x80; | ||
267 | u16 val; | ||
268 | |||
269 | ret = em28xx_is_ac97_ready(dev); | ||
270 | if (ret < 0) | ||
271 | return ret; | ||
272 | |||
273 | ret = em28xx_write_regs(dev, EM28XX_R42_AC97ADDR, &addr, 1); | ||
274 | if (ret < 0) | ||
275 | return ret; | ||
276 | |||
277 | ret = dev->em28xx_read_reg_req_len(dev, 0, EM28XX_R40_AC97LSB, | ||
278 | (u8 *)&val, sizeof(val)); | ||
279 | |||
280 | if (ret < 0) | ||
281 | return ret; | ||
282 | return le16_to_cpu(val); | ||
283 | } | ||
284 | |||
285 | /* | ||
227 | * em28xx_write_ac97() | 286 | * em28xx_write_ac97() |
228 | * write a 16 bit value to the specified AC97 address (LSB first!) | 287 | * write a 16 bit value to the specified AC97 address (LSB first!) |
229 | */ | 288 | */ |
230 | static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val) | 289 | int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val) |
231 | { | 290 | { |
232 | int ret, i; | 291 | int ret; |
233 | u8 addr = reg & 0x7f; | 292 | u8 addr = reg & 0x7f; |
293 | __le16 value; | ||
234 | 294 | ||
235 | ret = em28xx_write_regs(dev, EM28XX_R40_AC97LSB, val, 2); | 295 | value = cpu_to_le16(val); |
296 | |||
297 | ret = em28xx_is_ac97_ready(dev); | ||
298 | if (ret < 0) | ||
299 | return ret; | ||
300 | |||
301 | ret = em28xx_write_regs(dev, EM28XX_R40_AC97LSB, (u8 *) &value, 2); | ||
236 | if (ret < 0) | 302 | if (ret < 0) |
237 | return ret; | 303 | return ret; |
238 | 304 | ||
@@ -240,58 +306,74 @@ static int em28xx_write_ac97(struct em28xx *dev, u8 reg, u8 *val) | |||
240 | if (ret < 0) | 306 | if (ret < 0) |
241 | return ret; | 307 | return ret; |
242 | 308 | ||
243 | /* Wait up to 50 ms for AC97 command to complete */ | 309 | return 0; |
244 | for (i = 0; i < 10; i++) { | 310 | } |
245 | ret = em28xx_read_reg(dev, EM28XX_R43_AC97BUSY); | ||
246 | if (ret < 0) | ||
247 | return ret; | ||
248 | 311 | ||
249 | if (!(ret & 0x01)) | 312 | struct em28xx_vol_table { |
250 | return 0; | 313 | enum em28xx_amux mux; |
251 | msleep(5); | 314 | u8 reg; |
315 | }; | ||
316 | |||
317 | static struct em28xx_vol_table inputs[] = { | ||
318 | { EM28XX_AMUX_VIDEO, AC97_VIDEO_VOL }, | ||
319 | { EM28XX_AMUX_LINE_IN, AC97_LINEIN_VOL }, | ||
320 | { EM28XX_AMUX_PHONE, AC97_PHONE_VOL }, | ||
321 | { EM28XX_AMUX_MIC, AC97_MIC_VOL }, | ||
322 | { EM28XX_AMUX_CD, AC97_CD_VOL }, | ||
323 | { EM28XX_AMUX_AUX, AC97_AUX_VOL }, | ||
324 | { EM28XX_AMUX_PCM_OUT, AC97_PCM_OUT_VOL }, | ||
325 | }; | ||
326 | |||
327 | static int set_ac97_input(struct em28xx *dev) | ||
328 | { | ||
329 | int ret, i; | ||
330 | enum em28xx_amux amux = dev->ctl_ainput; | ||
331 | |||
332 | /* EM28XX_AMUX_VIDEO2 is a special case used to indicate that | ||
333 | em28xx should point to LINE IN, while AC97 should use VIDEO | ||
334 | */ | ||
335 | if (amux == EM28XX_AMUX_VIDEO2) | ||
336 | amux = EM28XX_AMUX_VIDEO; | ||
337 | |||
338 | /* Mute all entres but the one that were selected */ | ||
339 | for (i = 0; i < ARRAY_SIZE(inputs); i++) { | ||
340 | if (amux == inputs[i].mux) | ||
341 | ret = em28xx_write_ac97(dev, inputs[i].reg, 0x0808); | ||
342 | else | ||
343 | ret = em28xx_write_ac97(dev, inputs[i].reg, 0x8000); | ||
344 | |||
345 | if (ret < 0) | ||
346 | em28xx_warn("couldn't setup AC97 register %d\n", | ||
347 | inputs[i].reg); | ||
252 | } | 348 | } |
253 | em28xx_warn("AC97 command still being executed: not handled properly!\n"); | ||
254 | return 0; | 349 | return 0; |
255 | } | 350 | } |
256 | 351 | ||
257 | static int em28xx_set_audio_source(struct em28xx *dev) | 352 | static int em28xx_set_audio_source(struct em28xx *dev) |
258 | { | 353 | { |
259 | static char *enable = "\x08\x08"; | ||
260 | static char *disable = "\x08\x88"; | ||
261 | char *video = enable, *line = disable; | ||
262 | int ret; | 354 | int ret; |
263 | u8 input; | 355 | u8 input; |
264 | 356 | ||
265 | if (dev->is_em2800) { | 357 | if (dev->board.is_em2800) { |
266 | if (dev->ctl_ainput) | 358 | if (dev->ctl_ainput == EM28XX_AMUX_VIDEO) |
267 | input = EM2800_AUDIO_SRC_LINE; | ||
268 | else | ||
269 | input = EM2800_AUDIO_SRC_TUNER; | 359 | input = EM2800_AUDIO_SRC_TUNER; |
360 | else | ||
361 | input = EM2800_AUDIO_SRC_LINE; | ||
270 | 362 | ||
271 | ret = em28xx_write_regs(dev, EM2800_R08_AUDIOSRC, &input, 1); | 363 | ret = em28xx_write_regs(dev, EM2800_R08_AUDIOSRC, &input, 1); |
272 | if (ret < 0) | 364 | if (ret < 0) |
273 | return ret; | 365 | return ret; |
274 | } | 366 | } |
275 | 367 | ||
276 | if (dev->has_msp34xx) | 368 | if (dev->board.has_msp34xx) |
277 | input = EM28XX_AUDIO_SRC_TUNER; | 369 | input = EM28XX_AUDIO_SRC_TUNER; |
278 | else { | 370 | else { |
279 | switch (dev->ctl_ainput) { | 371 | switch (dev->ctl_ainput) { |
280 | case EM28XX_AMUX_VIDEO: | 372 | case EM28XX_AMUX_VIDEO: |
281 | input = EM28XX_AUDIO_SRC_TUNER; | 373 | input = EM28XX_AUDIO_SRC_TUNER; |
282 | break; | 374 | break; |
283 | case EM28XX_AMUX_LINE_IN: | 375 | default: |
284 | input = EM28XX_AUDIO_SRC_LINE; | 376 | input = EM28XX_AUDIO_SRC_LINE; |
285 | video = disable; | ||
286 | line = enable; | ||
287 | break; | ||
288 | case EM28XX_AMUX_AC97_VIDEO: | ||
289 | input = EM28XX_AUDIO_SRC_LINE; | ||
290 | break; | ||
291 | case EM28XX_AMUX_AC97_LINE_IN: | ||
292 | input = EM28XX_AUDIO_SRC_LINE; | ||
293 | video = disable; | ||
294 | line = enable; | ||
295 | break; | 377 | break; |
296 | } | 378 | } |
297 | } | 379 | } |
@@ -301,41 +383,50 @@ static int em28xx_set_audio_source(struct em28xx *dev) | |||
301 | return ret; | 383 | return ret; |
302 | msleep(5); | 384 | msleep(5); |
303 | 385 | ||
304 | /* Sets AC97 mixer registers | 386 | switch (dev->audio_mode.ac97) { |
305 | This is seems to be needed, even for non-ac97 configs | 387 | case EM28XX_NO_AC97: |
306 | */ | 388 | break; |
307 | ret = em28xx_write_ac97(dev, EM28XX_R14_VIDEO_AC97, video); | 389 | default: |
308 | if (ret < 0) | 390 | ret = set_ac97_input(dev); |
309 | return ret; | 391 | } |
310 | |||
311 | ret = em28xx_write_ac97(dev, EM28XX_R10_LINE_IN_AC97, line); | ||
312 | 392 | ||
313 | return ret; | 393 | return ret; |
314 | } | 394 | } |
315 | 395 | ||
396 | struct em28xx_vol_table outputs[] = { | ||
397 | { EM28XX_AOUT_MASTER, AC97_MASTER_VOL }, | ||
398 | { EM28XX_AOUT_LINE, AC97_LINE_LEVEL_VOL }, | ||
399 | { EM28XX_AOUT_MONO, AC97_MASTER_MONO_VOL }, | ||
400 | { EM28XX_AOUT_LFE, AC97_LFE_MASTER_VOL }, | ||
401 | { EM28XX_AOUT_SURR, AC97_SURR_MASTER_VOL }, | ||
402 | }; | ||
403 | |||
316 | int em28xx_audio_analog_set(struct em28xx *dev) | 404 | int em28xx_audio_analog_set(struct em28xx *dev) |
317 | { | 405 | { |
318 | int ret; | 406 | int ret, i; |
319 | char s[2] = { 0x00, 0x00 }; | 407 | u8 xclk; |
320 | u8 xclk = 0x07; | ||
321 | |||
322 | s[0] |= 0x1f - dev->volume; | ||
323 | s[1] |= 0x1f - dev->volume; | ||
324 | |||
325 | /* Mute */ | ||
326 | s[1] |= 0x80; | ||
327 | ret = em28xx_write_ac97(dev, EM28XX_R02_MASTER_AC97, s); | ||
328 | 408 | ||
329 | if (ret < 0) | 409 | if (!dev->audio_mode.has_audio) |
330 | return ret; | 410 | return 0; |
331 | 411 | ||
332 | if (dev->has_12mhz_i2s) | 412 | /* It is assumed that all devices use master volume for output. |
333 | xclk |= 0x20; | 413 | It would be possible to use also line output. |
414 | */ | ||
415 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { | ||
416 | /* Mute all outputs */ | ||
417 | for (i = 0; i < ARRAY_SIZE(outputs); i++) { | ||
418 | ret = em28xx_write_ac97(dev, outputs[i].reg, 0x8000); | ||
419 | if (ret < 0) | ||
420 | em28xx_warn("couldn't setup AC97 register %d\n", | ||
421 | outputs[i].reg); | ||
422 | } | ||
423 | } | ||
334 | 424 | ||
425 | xclk = dev->board.xclk & 0x7f; | ||
335 | if (!dev->mute) | 426 | if (!dev->mute) |
336 | xclk |= 0x80; | 427 | xclk |= 0x80; |
337 | 428 | ||
338 | ret = em28xx_write_reg_bits(dev, EM28XX_R0F_XCLK, xclk, 0xa7); | 429 | ret = em28xx_write_reg(dev, EM28XX_R0F_XCLK, xclk); |
339 | if (ret < 0) | 430 | if (ret < 0) |
340 | return ret; | 431 | return ret; |
341 | msleep(10); | 432 | msleep(10); |
@@ -343,36 +434,169 @@ int em28xx_audio_analog_set(struct em28xx *dev) | |||
343 | /* Selects the proper audio input */ | 434 | /* Selects the proper audio input */ |
344 | ret = em28xx_set_audio_source(dev); | 435 | ret = em28xx_set_audio_source(dev); |
345 | 436 | ||
346 | /* Unmute device */ | 437 | /* Sets volume */ |
347 | if (!dev->mute) | 438 | if (dev->audio_mode.ac97 != EM28XX_NO_AC97) { |
348 | s[1] &= ~0x80; | 439 | int vol; |
349 | ret = em28xx_write_ac97(dev, EM28XX_R02_MASTER_AC97, s); | 440 | |
441 | /* LSB: left channel - both channels with the same level */ | ||
442 | vol = (0x1f - dev->volume) | ((0x1f - dev->volume) << 8); | ||
443 | |||
444 | /* Mute device, if needed */ | ||
445 | if (dev->mute) | ||
446 | vol |= 0x8000; | ||
447 | |||
448 | /* Sets volume */ | ||
449 | for (i = 0; i < ARRAY_SIZE(outputs); i++) { | ||
450 | if (dev->ctl_aoutput & outputs[i].mux) | ||
451 | ret = em28xx_write_ac97(dev, outputs[i].reg, | ||
452 | vol); | ||
453 | if (ret < 0) | ||
454 | em28xx_warn("couldn't setup AC97 register %d\n", | ||
455 | outputs[i].reg); | ||
456 | } | ||
457 | } | ||
350 | 458 | ||
351 | return ret; | 459 | return ret; |
352 | } | 460 | } |
353 | EXPORT_SYMBOL_GPL(em28xx_audio_analog_set); | 461 | EXPORT_SYMBOL_GPL(em28xx_audio_analog_set); |
354 | 462 | ||
355 | int em28xx_colorlevels_set_default(struct em28xx *dev) | 463 | int em28xx_audio_setup(struct em28xx *dev) |
356 | { | 464 | { |
357 | em28xx_write_regs(dev, EM28XX_R20_YGAIN, "\x10", 1); /* contrast */ | 465 | int vid1, vid2, feat, cfg; |
358 | em28xx_write_regs(dev, EM28XX_R21_YOFFSET, "\x00", 1); /* brightness */ | 466 | u32 vid; |
359 | em28xx_write_regs(dev, EM28XX_R22_UVGAIN, "\x10", 1); /* saturation */ | 467 | |
360 | em28xx_write_regs(dev, EM28XX_R23_UOFFSET, "\x00", 1); | 468 | if (dev->chip_id == CHIP_ID_EM2870 || dev->chip_id == CHIP_ID_EM2874) { |
361 | em28xx_write_regs(dev, EM28XX_R24_VOFFSET, "\x00", 1); | 469 | /* Digital only device - don't load any alsa module */ |
362 | em28xx_write_regs(dev, EM28XX_R25_SHARPNESS, "\x00", 1); | 470 | dev->audio_mode.has_audio = 0; |
471 | dev->has_audio_class = 0; | ||
472 | dev->has_alsa_audio = 0; | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | /* If device doesn't support Usb Audio Class, use vendor class */ | ||
477 | if (!dev->has_audio_class) | ||
478 | dev->has_alsa_audio = 1; | ||
479 | |||
480 | dev->audio_mode.has_audio = 1; | ||
363 | 481 | ||
364 | em28xx_write_regs(dev, EM28XX_R14_GAMMA, "\x20", 1); | 482 | /* See how this device is configured */ |
365 | em28xx_write_regs(dev, EM28XX_R15_RGAIN, "\x20", 1); | 483 | cfg = em28xx_read_reg(dev, EM28XX_R00_CHIPCFG); |
366 | em28xx_write_regs(dev, EM28XX_R16_GGAIN, "\x20", 1); | 484 | if (cfg < 0) |
367 | em28xx_write_regs(dev, EM28XX_R17_BGAIN, "\x20", 1); | 485 | cfg = EM28XX_CHIPCFG_AC97; /* Be conservative */ |
368 | em28xx_write_regs(dev, EM28XX_R18_ROFFSET, "\x00", 1); | 486 | else |
369 | em28xx_write_regs(dev, EM28XX_R19_GOFFSET, "\x00", 1); | 487 | em28xx_info("Config register raw data: 0x%02x\n", cfg); |
370 | return em28xx_write_regs(dev, EM28XX_R1A_BOFFSET, "\x00", 1); | 488 | |
489 | if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == | ||
490 | EM28XX_CHIPCFG_I2S_3_SAMPRATES) { | ||
491 | em28xx_info("I2S Audio (3 sample rates)\n"); | ||
492 | dev->audio_mode.i2s_3rates = 1; | ||
493 | } | ||
494 | if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) == | ||
495 | EM28XX_CHIPCFG_I2S_5_SAMPRATES) { | ||
496 | em28xx_info("I2S Audio (5 sample rates)\n"); | ||
497 | dev->audio_mode.i2s_5rates = 1; | ||
498 | } | ||
499 | |||
500 | if ((cfg & EM28XX_CHIPCFG_AUDIOMASK) != EM28XX_CHIPCFG_AC97) { | ||
501 | /* Skip the code that does AC97 vendor detection */ | ||
502 | dev->audio_mode.ac97 = EM28XX_NO_AC97; | ||
503 | goto init_audio; | ||
504 | } | ||
505 | |||
506 | dev->audio_mode.ac97 = EM28XX_AC97_OTHER; | ||
507 | |||
508 | vid1 = em28xx_read_ac97(dev, AC97_VENDOR_ID1); | ||
509 | if (vid1 < 0) { | ||
510 | /* Device likely doesn't support AC97 */ | ||
511 | em28xx_warn("AC97 chip type couldn't be determined\n"); | ||
512 | goto init_audio; | ||
513 | } | ||
514 | |||
515 | vid2 = em28xx_read_ac97(dev, AC97_VENDOR_ID2); | ||
516 | if (vid2 < 0) | ||
517 | goto init_audio; | ||
518 | |||
519 | vid = vid1 << 16 | vid2; | ||
520 | |||
521 | dev->audio_mode.ac97_vendor_id = vid; | ||
522 | em28xx_warn("AC97 vendor ID = 0x%08x\n", vid); | ||
523 | |||
524 | feat = em28xx_read_ac97(dev, AC97_RESET); | ||
525 | if (feat < 0) | ||
526 | goto init_audio; | ||
527 | |||
528 | dev->audio_mode.ac97_feat = feat; | ||
529 | em28xx_warn("AC97 features = 0x%04x\n", feat); | ||
530 | |||
531 | /* Try to identify what audio processor we have */ | ||
532 | if ((vid == 0xffffffff) && (feat == 0x6a90)) | ||
533 | dev->audio_mode.ac97 = EM28XX_AC97_EM202; | ||
534 | else if ((vid >> 8) == 0x838476) | ||
535 | dev->audio_mode.ac97 = EM28XX_AC97_SIGMATEL; | ||
536 | |||
537 | init_audio: | ||
538 | /* Reports detected AC97 processor */ | ||
539 | switch (dev->audio_mode.ac97) { | ||
540 | case EM28XX_NO_AC97: | ||
541 | em28xx_info("No AC97 audio processor\n"); | ||
542 | break; | ||
543 | case EM28XX_AC97_EM202: | ||
544 | em28xx_info("Empia 202 AC97 audio processor detected\n"); | ||
545 | break; | ||
546 | case EM28XX_AC97_SIGMATEL: | ||
547 | em28xx_info("Sigmatel audio processor detected(stac 97%02x)\n", | ||
548 | dev->audio_mode.ac97_vendor_id & 0xff); | ||
549 | break; | ||
550 | case EM28XX_AC97_OTHER: | ||
551 | em28xx_warn("Unknown AC97 audio processor detected!\n"); | ||
552 | break; | ||
553 | default: | ||
554 | break; | ||
555 | } | ||
556 | |||
557 | return em28xx_audio_analog_set(dev); | ||
558 | } | ||
559 | EXPORT_SYMBOL_GPL(em28xx_audio_setup); | ||
560 | |||
561 | int em28xx_colorlevels_set_default(struct em28xx *dev) | ||
562 | { | ||
563 | em28xx_write_reg(dev, EM28XX_R20_YGAIN, 0x10); /* contrast */ | ||
564 | em28xx_write_reg(dev, EM28XX_R21_YOFFSET, 0x00); /* brightness */ | ||
565 | em28xx_write_reg(dev, EM28XX_R22_UVGAIN, 0x10); /* saturation */ | ||
566 | em28xx_write_reg(dev, EM28XX_R23_UOFFSET, 0x00); | ||
567 | em28xx_write_reg(dev, EM28XX_R24_VOFFSET, 0x00); | ||
568 | em28xx_write_reg(dev, EM28XX_R25_SHARPNESS, 0x00); | ||
569 | |||
570 | em28xx_write_reg(dev, EM28XX_R14_GAMMA, 0x20); | ||
571 | em28xx_write_reg(dev, EM28XX_R15_RGAIN, 0x20); | ||
572 | em28xx_write_reg(dev, EM28XX_R16_GGAIN, 0x20); | ||
573 | em28xx_write_reg(dev, EM28XX_R17_BGAIN, 0x20); | ||
574 | em28xx_write_reg(dev, EM28XX_R18_ROFFSET, 0x00); | ||
575 | em28xx_write_reg(dev, EM28XX_R19_GOFFSET, 0x00); | ||
576 | return em28xx_write_reg(dev, EM28XX_R1A_BOFFSET, 0x00); | ||
371 | } | 577 | } |
372 | 578 | ||
373 | int em28xx_capture_start(struct em28xx *dev, int start) | 579 | int em28xx_capture_start(struct em28xx *dev, int start) |
374 | { | 580 | { |
375 | int rc; | 581 | int rc; |
582 | |||
583 | if (dev->chip_id == CHIP_ID_EM2874) { | ||
584 | /* The Transport Stream Enable Register moved in em2874 */ | ||
585 | if (!start) { | ||
586 | rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE, | ||
587 | 0x00, | ||
588 | EM2874_TS1_CAPTURE_ENABLE); | ||
589 | return rc; | ||
590 | } | ||
591 | |||
592 | /* Enable Transport Stream */ | ||
593 | rc = em28xx_write_reg_bits(dev, EM2874_R5F_TS_ENABLE, | ||
594 | EM2874_TS1_CAPTURE_ENABLE, | ||
595 | EM2874_TS1_CAPTURE_ENABLE); | ||
596 | return rc; | ||
597 | } | ||
598 | |||
599 | |||
376 | /* FIXME: which is the best order? */ | 600 | /* FIXME: which is the best order? */ |
377 | /* video registers are sampled by VREF */ | 601 | /* video registers are sampled by VREF */ |
378 | rc = em28xx_write_reg_bits(dev, EM28XX_R0C_USBSUSP, | 602 | rc = em28xx_write_reg_bits(dev, EM28XX_R0C_USBSUSP, |
@@ -382,28 +606,37 @@ int em28xx_capture_start(struct em28xx *dev, int start) | |||
382 | 606 | ||
383 | if (!start) { | 607 | if (!start) { |
384 | /* disable video capture */ | 608 | /* disable video capture */ |
385 | rc = em28xx_write_regs(dev, EM28XX_R12_VINENABLE, "\x27", 1); | 609 | rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x27); |
386 | return rc; | 610 | return rc; |
387 | } | 611 | } |
388 | 612 | ||
389 | /* enable video capture */ | 613 | /* enable video capture */ |
390 | rc = em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); | 614 | rc = em28xx_write_reg(dev, 0x48, 0x00); |
391 | 615 | ||
392 | if (dev->mode == EM28XX_ANALOG_MODE) | 616 | if (dev->mode == EM28XX_ANALOG_MODE) |
393 | rc = em28xx_write_regs(dev, EM28XX_R12_VINENABLE, "\x67", 1); | 617 | rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67); |
394 | else | 618 | else |
395 | rc = em28xx_write_regs(dev, EM28XX_R12_VINENABLE, "\x37", 1); | 619 | rc = em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); |
396 | 620 | ||
397 | msleep(6); | 621 | msleep(6); |
398 | 622 | ||
399 | return rc; | 623 | return rc; |
400 | } | 624 | } |
401 | 625 | ||
402 | int em28xx_outfmt_set_yuv422(struct em28xx *dev) | 626 | int em28xx_set_outfmt(struct em28xx *dev) |
403 | { | 627 | { |
404 | em28xx_write_regs(dev, EM28XX_R27_OUTFMT, "\x34", 1); | 628 | int ret; |
405 | em28xx_write_regs(dev, EM28XX_R10_VINMODE, "\x10", 1); | 629 | |
406 | return em28xx_write_regs(dev, EM28XX_R11_VINCTRL, "\x11", 1); | 630 | ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT, |
631 | dev->format->reg | 0x20, 0x3f); | ||
632 | if (ret < 0) | ||
633 | return ret; | ||
634 | |||
635 | ret = em28xx_write_reg(dev, EM28XX_R10_VINMODE, 0x10); | ||
636 | if (ret < 0) | ||
637 | return ret; | ||
638 | |||
639 | return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x11); | ||
407 | } | 640 | } |
408 | 641 | ||
409 | static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, | 642 | static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, |
@@ -440,7 +673,7 @@ static int em28xx_scaler_set(struct em28xx *dev, u16 h, u16 v) | |||
440 | { | 673 | { |
441 | u8 mode; | 674 | u8 mode; |
442 | /* the em2800 scaler only supports scaling down to 50% */ | 675 | /* the em2800 scaler only supports scaling down to 50% */ |
443 | if (dev->is_em2800) | 676 | if (dev->board.is_em2800) |
444 | mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); | 677 | mode = (v ? 0x20 : 0x00) | (h ? 0x10 : 0x00); |
445 | else { | 678 | else { |
446 | u8 buf[2]; | 679 | u8 buf[2]; |
@@ -464,7 +697,7 @@ int em28xx_resolution_set(struct em28xx *dev) | |||
464 | width = norm_maxw(dev); | 697 | width = norm_maxw(dev); |
465 | height = norm_maxh(dev) >> 1; | 698 | height = norm_maxh(dev) >> 1; |
466 | 699 | ||
467 | em28xx_outfmt_set_yuv422(dev); | 700 | em28xx_set_outfmt(dev); |
468 | em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); | 701 | em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); |
469 | em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2); | 702 | em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2); |
470 | return em28xx_scaler_set(dev, dev->hscale, dev->vscale); | 703 | return em28xx_scaler_set(dev, dev->hscale, dev->vscale); |
@@ -519,12 +752,14 @@ int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio) | |||
519 | if (!gpio) | 752 | if (!gpio) |
520 | return rc; | 753 | return rc; |
521 | 754 | ||
522 | dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1); | 755 | if (dev->mode != EM28XX_SUSPEND) { |
523 | if (dev->mode == EM28XX_ANALOG_MODE) | 756 | em28xx_write_reg(dev, 0x48, 0x00); |
524 | dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1); | 757 | if (dev->mode == EM28XX_ANALOG_MODE) |
525 | else | 758 | em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x67); |
526 | dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x37", 1); | 759 | else |
527 | msleep(6); | 760 | em28xx_write_reg(dev, EM28XX_R12_VINENABLE, 0x37); |
761 | msleep(6); | ||
762 | } | ||
528 | 763 | ||
529 | /* Send GPIO reset sequences specified at board entry */ | 764 | /* Send GPIO reset sequences specified at board entry */ |
530 | while (gpio->sleep >= 0) { | 765 | while (gpio->sleep >= 0) { |
@@ -549,17 +784,20 @@ int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode) | |||
549 | if (dev->mode == set_mode) | 784 | if (dev->mode == set_mode) |
550 | return 0; | 785 | return 0; |
551 | 786 | ||
552 | if (set_mode == EM28XX_MODE_UNDEFINED) { | 787 | if (set_mode == EM28XX_SUSPEND) { |
553 | dev->mode = set_mode; | 788 | dev->mode = set_mode; |
554 | return 0; | 789 | |
790 | /* FIXME: add suspend support for ac97 */ | ||
791 | |||
792 | return em28xx_gpio_set(dev, dev->board.suspend_gpio); | ||
555 | } | 793 | } |
556 | 794 | ||
557 | dev->mode = set_mode; | 795 | dev->mode = set_mode; |
558 | 796 | ||
559 | if (dev->mode == EM28XX_DIGITAL_MODE) | 797 | if (dev->mode == EM28XX_DIGITAL_MODE) |
560 | return em28xx_gpio_set(dev, dev->digital_gpio); | 798 | return em28xx_gpio_set(dev, dev->board.dvb_gpio); |
561 | else | 799 | else |
562 | return em28xx_gpio_set(dev, dev->analog_gpio); | 800 | return em28xx_gpio_set(dev, INPUT(dev->ctl_input)->gpio); |
563 | } | 801 | } |
564 | EXPORT_SYMBOL_GPL(em28xx_set_mode); | 802 | EXPORT_SYMBOL_GPL(em28xx_set_mode); |
565 | 803 | ||
@@ -738,3 +976,145 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, | |||
738 | return 0; | 976 | return 0; |
739 | } | 977 | } |
740 | EXPORT_SYMBOL_GPL(em28xx_init_isoc); | 978 | EXPORT_SYMBOL_GPL(em28xx_init_isoc); |
979 | |||
980 | /* | ||
981 | * em28xx_wake_i2c() | ||
982 | * configure i2c attached devices | ||
983 | */ | ||
984 | void em28xx_wake_i2c(struct em28xx *dev) | ||
985 | { | ||
986 | struct v4l2_routing route; | ||
987 | int zero = 0; | ||
988 | |||
989 | route.input = INPUT(dev->ctl_input)->vmux; | ||
990 | route.output = 0; | ||
991 | em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, &zero); | ||
992 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); | ||
993 | em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); | ||
994 | } | ||
995 | |||
996 | /* | ||
997 | * Device control list | ||
998 | */ | ||
999 | |||
1000 | static LIST_HEAD(em28xx_devlist); | ||
1001 | static DEFINE_MUTEX(em28xx_devlist_mutex); | ||
1002 | |||
1003 | struct em28xx *em28xx_get_device(struct inode *inode, | ||
1004 | enum v4l2_buf_type *fh_type, | ||
1005 | int *has_radio) | ||
1006 | { | ||
1007 | struct em28xx *h, *dev = NULL; | ||
1008 | int minor = iminor(inode); | ||
1009 | |||
1010 | *fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1011 | *has_radio = 0; | ||
1012 | |||
1013 | mutex_lock(&em28xx_devlist_mutex); | ||
1014 | list_for_each_entry(h, &em28xx_devlist, devlist) { | ||
1015 | if (h->vdev->minor == minor) | ||
1016 | dev = h; | ||
1017 | if (h->vbi_dev->minor == minor) { | ||
1018 | dev = h; | ||
1019 | *fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
1020 | } | ||
1021 | if (h->radio_dev && | ||
1022 | h->radio_dev->minor == minor) { | ||
1023 | dev = h; | ||
1024 | *has_radio = 1; | ||
1025 | } | ||
1026 | } | ||
1027 | mutex_unlock(&em28xx_devlist_mutex); | ||
1028 | |||
1029 | return dev; | ||
1030 | } | ||
1031 | |||
1032 | /* | ||
1033 | * em28xx_realease_resources() | ||
1034 | * unregisters the v4l2,i2c and usb devices | ||
1035 | * called when the device gets disconected or at module unload | ||
1036 | */ | ||
1037 | void em28xx_remove_from_devlist(struct em28xx *dev) | ||
1038 | { | ||
1039 | mutex_lock(&em28xx_devlist_mutex); | ||
1040 | list_del(&dev->devlist); | ||
1041 | mutex_unlock(&em28xx_devlist_mutex); | ||
1042 | }; | ||
1043 | |||
1044 | void em28xx_add_into_devlist(struct em28xx *dev) | ||
1045 | { | ||
1046 | mutex_lock(&em28xx_devlist_mutex); | ||
1047 | list_add_tail(&dev->devlist, &em28xx_devlist); | ||
1048 | mutex_unlock(&em28xx_devlist_mutex); | ||
1049 | }; | ||
1050 | |||
1051 | /* | ||
1052 | * Extension interface | ||
1053 | */ | ||
1054 | |||
1055 | static LIST_HEAD(em28xx_extension_devlist); | ||
1056 | static DEFINE_MUTEX(em28xx_extension_devlist_lock); | ||
1057 | |||
1058 | int em28xx_register_extension(struct em28xx_ops *ops) | ||
1059 | { | ||
1060 | struct em28xx *dev = NULL; | ||
1061 | |||
1062 | mutex_lock(&em28xx_devlist_mutex); | ||
1063 | mutex_lock(&em28xx_extension_devlist_lock); | ||
1064 | list_add_tail(&ops->next, &em28xx_extension_devlist); | ||
1065 | list_for_each_entry(dev, &em28xx_devlist, devlist) { | ||
1066 | if (dev) | ||
1067 | ops->init(dev); | ||
1068 | } | ||
1069 | printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); | ||
1070 | mutex_unlock(&em28xx_extension_devlist_lock); | ||
1071 | mutex_unlock(&em28xx_devlist_mutex); | ||
1072 | return 0; | ||
1073 | } | ||
1074 | EXPORT_SYMBOL(em28xx_register_extension); | ||
1075 | |||
1076 | void em28xx_unregister_extension(struct em28xx_ops *ops) | ||
1077 | { | ||
1078 | struct em28xx *dev = NULL; | ||
1079 | |||
1080 | mutex_lock(&em28xx_devlist_mutex); | ||
1081 | list_for_each_entry(dev, &em28xx_devlist, devlist) { | ||
1082 | if (dev) | ||
1083 | ops->fini(dev); | ||
1084 | } | ||
1085 | |||
1086 | mutex_lock(&em28xx_extension_devlist_lock); | ||
1087 | printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); | ||
1088 | list_del(&ops->next); | ||
1089 | mutex_unlock(&em28xx_extension_devlist_lock); | ||
1090 | mutex_unlock(&em28xx_devlist_mutex); | ||
1091 | } | ||
1092 | EXPORT_SYMBOL(em28xx_unregister_extension); | ||
1093 | |||
1094 | void em28xx_init_extension(struct em28xx *dev) | ||
1095 | { | ||
1096 | struct em28xx_ops *ops = NULL; | ||
1097 | |||
1098 | mutex_lock(&em28xx_extension_devlist_lock); | ||
1099 | if (!list_empty(&em28xx_extension_devlist)) { | ||
1100 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { | ||
1101 | if (ops->init) | ||
1102 | ops->init(dev); | ||
1103 | } | ||
1104 | } | ||
1105 | mutex_unlock(&em28xx_extension_devlist_lock); | ||
1106 | } | ||
1107 | |||
1108 | void em28xx_close_extension(struct em28xx *dev) | ||
1109 | { | ||
1110 | struct em28xx_ops *ops = NULL; | ||
1111 | |||
1112 | mutex_lock(&em28xx_extension_devlist_lock); | ||
1113 | if (!list_empty(&em28xx_extension_devlist)) { | ||
1114 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { | ||
1115 | if (ops->fini) | ||
1116 | ops->fini(dev); | ||
1117 | } | ||
1118 | } | ||
1119 | mutex_unlock(&em28xx_extension_devlist_lock); | ||
1120 | } | ||
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c index c99e2383b7ec..d38cb21834d9 100644 --- a/drivers/media/video/em28xx/em28xx-dvb.c +++ b/drivers/media/video/em28xx/em28xx-dvb.c | |||
@@ -161,7 +161,7 @@ static int stop_streaming(struct em28xx_dvb *dvb) | |||
161 | 161 | ||
162 | em28xx_uninit_isoc(dev); | 162 | em28xx_uninit_isoc(dev); |
163 | 163 | ||
164 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | 164 | em28xx_set_mode(dev, EM28XX_SUSPEND); |
165 | 165 | ||
166 | return 0; | 166 | return 0; |
167 | } | 167 | } |
@@ -215,7 +215,7 @@ static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) | |||
215 | if (acquire) | 215 | if (acquire) |
216 | return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | 216 | return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); |
217 | else | 217 | else |
218 | return em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | 218 | return em28xx_set_mode(dev, EM28XX_SUSPEND); |
219 | } | 219 | } |
220 | 220 | ||
221 | /* ------------------------------------------------------------------ */ | 221 | /* ------------------------------------------------------------------ */ |
@@ -393,7 +393,7 @@ static int dvb_init(struct em28xx *dev) | |||
393 | int result = 0; | 393 | int result = 0; |
394 | struct em28xx_dvb *dvb; | 394 | struct em28xx_dvb *dvb; |
395 | 395 | ||
396 | if (!dev->has_dvb) { | 396 | if (!dev->board.has_dvb) { |
397 | /* This device does not support the extension */ | 397 | /* This device does not support the extension */ |
398 | return 0; | 398 | return 0; |
399 | } | 399 | } |
@@ -409,8 +409,10 @@ static int dvb_init(struct em28xx *dev) | |||
409 | em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | 409 | em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); |
410 | /* init frontend */ | 410 | /* init frontend */ |
411 | switch (dev->model) { | 411 | switch (dev->model) { |
412 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: | ||
412 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: | 413 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: |
413 | case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: | 414 | case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: |
415 | case EM2883_BOARD_KWORLD_HYBRID_A316: | ||
414 | case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: | 416 | case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: |
415 | dvb->frontend = dvb_attach(lgdt330x_attach, | 417 | dvb->frontend = dvb_attach(lgdt330x_attach, |
416 | &em2880_lgdt3303_dev, | 418 | &em2880_lgdt3303_dev, |
@@ -466,12 +468,12 @@ static int dvb_init(struct em28xx *dev) | |||
466 | if (result < 0) | 468 | if (result < 0) |
467 | goto out_free; | 469 | goto out_free; |
468 | 470 | ||
469 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | 471 | em28xx_set_mode(dev, EM28XX_SUSPEND); |
470 | printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); | 472 | printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); |
471 | return 0; | 473 | return 0; |
472 | 474 | ||
473 | out_free: | 475 | out_free: |
474 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | 476 | em28xx_set_mode(dev, EM28XX_SUSPEND); |
475 | kfree(dvb); | 477 | kfree(dvb); |
476 | dev->dvb = NULL; | 478 | dev->dvb = NULL; |
477 | return result; | 479 | return result; |
@@ -479,7 +481,7 @@ out_free: | |||
479 | 481 | ||
480 | static int dvb_fini(struct em28xx *dev) | 482 | static int dvb_fini(struct em28xx *dev) |
481 | { | 483 | { |
482 | if (!dev->has_dvb) { | 484 | if (!dev->board.has_dvb) { |
483 | /* This device does not support the extension */ | 485 | /* This device does not support the extension */ |
484 | return 0; | 486 | return 0; |
485 | } | 487 | } |
diff --git a/drivers/media/video/em28xx/em28xx-i2c.c b/drivers/media/video/em28xx/em28xx-i2c.c index 2360c61ddca9..d69f0efcc9aa 100644 --- a/drivers/media/video/em28xx/em28xx-i2c.c +++ b/drivers/media/video/em28xx/em28xx-i2c.c | |||
@@ -250,7 +250,7 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
250 | (msgs[i].flags & I2C_M_RD) ? "read" : "write", | 250 | (msgs[i].flags & I2C_M_RD) ? "read" : "write", |
251 | i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); | 251 | i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); |
252 | if (!msgs[i].len) { /* no len: check only for device presence */ | 252 | if (!msgs[i].len) { /* no len: check only for device presence */ |
253 | if (dev->is_em2800) | 253 | if (dev->board.is_em2800) |
254 | rc = em2800_i2c_check_for_device(dev, addr); | 254 | rc = em2800_i2c_check_for_device(dev, addr); |
255 | else | 255 | else |
256 | rc = em28xx_i2c_check_for_device(dev, addr); | 256 | rc = em28xx_i2c_check_for_device(dev, addr); |
@@ -261,7 +261,7 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
261 | 261 | ||
262 | } else if (msgs[i].flags & I2C_M_RD) { | 262 | } else if (msgs[i].flags & I2C_M_RD) { |
263 | /* read bytes */ | 263 | /* read bytes */ |
264 | if (dev->is_em2800) | 264 | if (dev->board.is_em2800) |
265 | rc = em2800_i2c_recv_bytes(dev, addr, | 265 | rc = em2800_i2c_recv_bytes(dev, addr, |
266 | msgs[i].buf, | 266 | msgs[i].buf, |
267 | msgs[i].len); | 267 | msgs[i].len); |
@@ -279,7 +279,7 @@ static int em28xx_i2c_xfer(struct i2c_adapter *i2c_adap, | |||
279 | for (byte = 0; byte < msgs[i].len; byte++) | 279 | for (byte = 0; byte < msgs[i].len; byte++) |
280 | printk(" %02x", msgs[i].buf[byte]); | 280 | printk(" %02x", msgs[i].buf[byte]); |
281 | } | 281 | } |
282 | if (dev->is_em2800) | 282 | if (dev->board.is_em2800) |
283 | rc = em2800_i2c_send_bytes(dev, addr, | 283 | rc = em2800_i2c_send_bytes(dev, addr, |
284 | msgs[i].buf, | 284 | msgs[i].buf, |
285 | msgs[i].len); | 285 | msgs[i].len); |
@@ -332,6 +332,17 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) | |||
332 | struct em28xx_eeprom *em_eeprom = (void *)eedata; | 332 | struct em28xx_eeprom *em_eeprom = (void *)eedata; |
333 | int i, err, size = len, block; | 333 | int i, err, size = len, block; |
334 | 334 | ||
335 | if (dev->chip_id == CHIP_ID_EM2874) { | ||
336 | /* Empia switched to a 16-bit addressable eeprom in newer | ||
337 | devices. While we could certainly write a routine to read | ||
338 | the eeprom, there is nothing of use in there that cannot be | ||
339 | accessed through registers, and there is the risk that we | ||
340 | could corrupt the eeprom (since a 16-bit read call is | ||
341 | interpreted as a write call by 8-bit eeproms). | ||
342 | */ | ||
343 | return 0; | ||
344 | } | ||
345 | |||
335 | dev->i2c_client.addr = 0xa0 >> 1; | 346 | dev->i2c_client.addr = 0xa0 >> 1; |
336 | 347 | ||
337 | /* Check if board has eeprom */ | 348 | /* Check if board has eeprom */ |
@@ -377,47 +388,49 @@ static int em28xx_i2c_eeprom(struct em28xx *dev, unsigned char *eedata, int len) | |||
377 | if (em_eeprom->id == 0x9567eb1a) | 388 | if (em_eeprom->id == 0x9567eb1a) |
378 | dev->hash = em28xx_hash_mem(eedata, len, 32); | 389 | dev->hash = em28xx_hash_mem(eedata, len, 32); |
379 | 390 | ||
380 | printk(KERN_INFO "EEPROM ID= 0x%08x, hash = 0x%08lx\n", | 391 | printk(KERN_INFO "%s: EEPROM ID= 0x%08x, EEPROM hash = 0x%08lx\n", |
381 | em_eeprom->id, dev->hash); | 392 | dev->name, em_eeprom->id, dev->hash); |
382 | printk(KERN_INFO "Vendor/Product ID= %04x:%04x\n", em_eeprom->vendor_ID, | 393 | |
383 | em_eeprom->product_ID); | 394 | printk(KERN_INFO "%s: EEPROM info:\n", dev->name); |
384 | 395 | ||
385 | switch (em_eeprom->chip_conf >> 4 & 0x3) { | 396 | switch (em_eeprom->chip_conf >> 4 & 0x3) { |
386 | case 0: | 397 | case 0: |
387 | printk(KERN_INFO "No audio on board.\n"); | 398 | printk(KERN_INFO "%s:\tNo audio on board.\n", dev->name); |
388 | break; | 399 | break; |
389 | case 1: | 400 | case 1: |
390 | printk(KERN_INFO "AC97 audio (5 sample rates)\n"); | 401 | printk(KERN_INFO "%s:\tAC97 audio (5 sample rates)\n", |
402 | dev->name); | ||
391 | break; | 403 | break; |
392 | case 2: | 404 | case 2: |
393 | printk(KERN_INFO "I2S audio, sample rate=32k\n"); | 405 | printk(KERN_INFO "%s:\tI2S audio, sample rate=32k\n", dev->name); |
394 | break; | 406 | break; |
395 | case 3: | 407 | case 3: |
396 | printk(KERN_INFO "I2S audio, 3 sample rates\n"); | 408 | printk(KERN_INFO "%s:\tI2S audio, 3 sample rates\n", dev->name); |
397 | break; | 409 | break; |
398 | } | 410 | } |
399 | 411 | ||
400 | if (em_eeprom->chip_conf & 1 << 3) | 412 | if (em_eeprom->chip_conf & 1 << 3) |
401 | printk(KERN_INFO "USB Remote wakeup capable\n"); | 413 | printk(KERN_INFO "%s:\tUSB Remote wakeup capable\n", dev->name); |
402 | 414 | ||
403 | if (em_eeprom->chip_conf & 1 << 2) | 415 | if (em_eeprom->chip_conf & 1 << 2) |
404 | printk(KERN_INFO "USB Self power capable\n"); | 416 | printk(KERN_INFO "%s:\tUSB Self power capable\n", dev->name); |
405 | 417 | ||
406 | switch (em_eeprom->chip_conf & 0x3) { | 418 | switch (em_eeprom->chip_conf & 0x3) { |
407 | case 0: | 419 | case 0: |
408 | printk(KERN_INFO "500mA max power\n"); | 420 | printk(KERN_INFO "%s:\t500mA max power\n", dev->name); |
409 | break; | 421 | break; |
410 | case 1: | 422 | case 1: |
411 | printk(KERN_INFO "400mA max power\n"); | 423 | printk(KERN_INFO "%s:\t400mA max power\n", dev->name); |
412 | break; | 424 | break; |
413 | case 2: | 425 | case 2: |
414 | printk(KERN_INFO "300mA max power\n"); | 426 | printk(KERN_INFO "%s:\t300mA max power\n", dev->name); |
415 | break; | 427 | break; |
416 | case 3: | 428 | case 3: |
417 | printk(KERN_INFO "200mA max power\n"); | 429 | printk(KERN_INFO "%s:\t200mA max power\n", dev->name); |
418 | break; | 430 | break; |
419 | } | 431 | } |
420 | printk(KERN_INFO "Table at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", | 432 | printk(KERN_INFO "%s:\tTable at 0x%02x, strings=0x%04x, 0x%04x, 0x%04x\n", |
433 | dev->name, | ||
421 | em_eeprom->string_idx_table, | 434 | em_eeprom->string_idx_table, |
422 | em_eeprom->string1, | 435 | em_eeprom->string1, |
423 | em_eeprom->string2, | 436 | em_eeprom->string2, |
diff --git a/drivers/media/video/em28xx/em28xx-input.c b/drivers/media/video/em28xx/em28xx-input.c index eab3d9511af3..42bbaf64aceb 100644 --- a/drivers/media/video/em28xx/em28xx-input.c +++ b/drivers/media/video/em28xx/em28xx-input.c | |||
@@ -38,12 +38,48 @@ static unsigned int ir_debug; | |||
38 | module_param(ir_debug, int, 0644); | 38 | module_param(ir_debug, int, 0644); |
39 | MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); | 39 | MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]"); |
40 | 40 | ||
41 | #define dprintk(fmt, arg...) \ | 41 | #define i2cdprintk(fmt, arg...) \ |
42 | if (ir_debug) { \ | 42 | if (ir_debug) { \ |
43 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \ | 43 | printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \ |
44 | } | 44 | } |
45 | 45 | ||
46 | /* ----------------------------------------------------------------------- */ | 46 | #define dprintk(fmt, arg...) \ |
47 | if (ir_debug) { \ | ||
48 | printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ | ||
49 | } | ||
50 | |||
51 | /********************************************************** | ||
52 | Polling structure used by em28xx IR's | ||
53 | **********************************************************/ | ||
54 | |||
55 | struct em28xx_ir_poll_result { | ||
56 | unsigned int toggle_bit:1; | ||
57 | unsigned int read_count:7; | ||
58 | u8 rc_address; | ||
59 | u8 rc_data[4]; /* 1 byte on em2860/2880, 4 on em2874 */ | ||
60 | }; | ||
61 | |||
62 | struct em28xx_IR { | ||
63 | struct em28xx *dev; | ||
64 | struct input_dev *input; | ||
65 | struct ir_input_state ir; | ||
66 | char name[32]; | ||
67 | char phys[32]; | ||
68 | |||
69 | /* poll external decoder */ | ||
70 | int polling; | ||
71 | struct work_struct work; | ||
72 | struct timer_list timer; | ||
73 | unsigned int last_toggle:1; | ||
74 | unsigned int last_readcount; | ||
75 | unsigned int repeat_interval; | ||
76 | |||
77 | int (*get_key)(struct em28xx_IR *, struct em28xx_ir_poll_result *); | ||
78 | }; | ||
79 | |||
80 | /********************************************************** | ||
81 | I2C IR based get keycodes - should be used with ir-kbd-i2c | ||
82 | **********************************************************/ | ||
47 | 83 | ||
48 | int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 84 | int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
49 | { | 85 | { |
@@ -51,7 +87,7 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
51 | 87 | ||
52 | /* poll IR chip */ | 88 | /* poll IR chip */ |
53 | if (1 != i2c_master_recv(&ir->c, &b, 1)) { | 89 | if (1 != i2c_master_recv(&ir->c, &b, 1)) { |
54 | dprintk("read error\n"); | 90 | i2cdprintk("read error\n"); |
55 | return -EIO; | 91 | return -EIO; |
56 | } | 92 | } |
57 | 93 | ||
@@ -59,7 +95,7 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
59 | down, while 0xff indicates that no button is hold | 95 | down, while 0xff indicates that no button is hold |
60 | down. 0xfe sequences are sometimes interrupted by 0xFF */ | 96 | down. 0xfe sequences are sometimes interrupted by 0xFF */ |
61 | 97 | ||
62 | dprintk("key %02x\n", b); | 98 | i2cdprintk("key %02x\n", b); |
63 | 99 | ||
64 | if (b == 0xff) | 100 | if (b == 0xff) |
65 | return 0; | 101 | return 0; |
@@ -73,7 +109,6 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
73 | return 1; | 109 | return 1; |
74 | } | 110 | } |
75 | 111 | ||
76 | |||
77 | int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | 112 | int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) |
78 | { | 113 | { |
79 | unsigned char buf[2]; | 114 | unsigned char buf[2]; |
@@ -97,7 +132,7 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) | |||
97 | ((buf[0]&0x10)>>3) | /* 0000 0010 */ | 132 | ((buf[0]&0x10)>>3) | /* 0000 0010 */ |
98 | ((buf[0]&0x20)>>5); /* 0000 0001 */ | 133 | ((buf[0]&0x20)>>5); /* 0000 0001 */ |
99 | 134 | ||
100 | dprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n", | 135 | i2cdprintk("ir hauppauge (em2840): code=0x%02x (rcv=0x%02x)\n", |
101 | code, buf[0]); | 136 | code, buf[0]); |
102 | 137 | ||
103 | /* return key */ | 138 | /* return key */ |
@@ -114,11 +149,11 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, | |||
114 | /* poll IR chip */ | 149 | /* poll IR chip */ |
115 | 150 | ||
116 | if (3 != i2c_master_recv(&ir->c, buf, 3)) { | 151 | if (3 != i2c_master_recv(&ir->c, buf, 3)) { |
117 | dprintk("read error\n"); | 152 | i2cdprintk("read error\n"); |
118 | return -EIO; | 153 | return -EIO; |
119 | } | 154 | } |
120 | 155 | ||
121 | dprintk("key %02x\n", buf[2]&0x3f); | 156 | i2cdprintk("key %02x\n", buf[2]&0x3f); |
122 | if (buf[0] != 0x00) | 157 | if (buf[0] != 0x00) |
123 | return 0; | 158 | return 0; |
124 | 159 | ||
@@ -128,6 +163,260 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, | |||
128 | return 1; | 163 | return 1; |
129 | } | 164 | } |
130 | 165 | ||
166 | /********************************************************** | ||
167 | Poll based get keycode functions | ||
168 | **********************************************************/ | ||
169 | |||
170 | /* This is for the em2860/em2880 */ | ||
171 | static int default_polling_getkey(struct em28xx_IR *ir, | ||
172 | struct em28xx_ir_poll_result *poll_result) | ||
173 | { | ||
174 | struct em28xx *dev = ir->dev; | ||
175 | int rc; | ||
176 | u8 msg[3] = { 0, 0, 0 }; | ||
177 | |||
178 | /* Read key toggle, brand, and key code | ||
179 | on registers 0x45, 0x46 and 0x47 | ||
180 | */ | ||
181 | rc = dev->em28xx_read_reg_req_len(dev, 0, EM28XX_R45_IR, | ||
182 | msg, sizeof(msg)); | ||
183 | if (rc < 0) | ||
184 | return rc; | ||
185 | |||
186 | /* Infrared toggle (Reg 0x45[7]) */ | ||
187 | poll_result->toggle_bit = (msg[0] >> 7); | ||
188 | |||
189 | /* Infrared read count (Reg 0x45[6:0] */ | ||
190 | poll_result->read_count = (msg[0] & 0x7f); | ||
191 | |||
192 | /* Remote Control Address (Reg 0x46) */ | ||
193 | poll_result->rc_address = msg[1]; | ||
194 | |||
195 | /* Remote Control Data (Reg 0x47) */ | ||
196 | poll_result->rc_data[0] = msg[2]; | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | static int em2874_polling_getkey(struct em28xx_IR *ir, | ||
202 | struct em28xx_ir_poll_result *poll_result) | ||
203 | { | ||
204 | struct em28xx *dev = ir->dev; | ||
205 | int rc; | ||
206 | u8 msg[5] = { 0, 0, 0, 0, 0 }; | ||
207 | |||
208 | /* Read key toggle, brand, and key code | ||
209 | on registers 0x51-55 | ||
210 | */ | ||
211 | rc = dev->em28xx_read_reg_req_len(dev, 0, EM2874_R51_IR, | ||
212 | msg, sizeof(msg)); | ||
213 | if (rc < 0) | ||
214 | return rc; | ||
215 | |||
216 | /* Infrared toggle (Reg 0x51[7]) */ | ||
217 | poll_result->toggle_bit = (msg[0] >> 7); | ||
218 | |||
219 | /* Infrared read count (Reg 0x51[6:0] */ | ||
220 | poll_result->read_count = (msg[0] & 0x7f); | ||
221 | |||
222 | /* Remote Control Address (Reg 0x52) */ | ||
223 | poll_result->rc_address = msg[1]; | ||
224 | |||
225 | /* Remote Control Data (Reg 0x53-55) */ | ||
226 | poll_result->rc_data[0] = msg[2]; | ||
227 | poll_result->rc_data[1] = msg[3]; | ||
228 | poll_result->rc_data[2] = msg[4]; | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | /********************************************************** | ||
234 | Polling code for em28xx | ||
235 | **********************************************************/ | ||
236 | |||
237 | static void em28xx_ir_handle_key(struct em28xx_IR *ir) | ||
238 | { | ||
239 | int result; | ||
240 | int do_sendkey = 0; | ||
241 | struct em28xx_ir_poll_result poll_result; | ||
242 | |||
243 | /* read the registers containing the IR status */ | ||
244 | result = ir->get_key(ir, &poll_result); | ||
245 | if (result < 0) { | ||
246 | dprintk("ir->get_key() failed %d\n", result); | ||
247 | return; | ||
248 | } | ||
249 | |||
250 | dprintk("ir->get_key result tb=%02x rc=%02x lr=%02x data=%02x\n", | ||
251 | poll_result.toggle_bit, poll_result.read_count, | ||
252 | ir->last_readcount, poll_result.rc_data[0]); | ||
253 | |||
254 | if (ir->dev->chip_id == CHIP_ID_EM2874) { | ||
255 | /* The em2874 clears the readcount field every time the | ||
256 | register is read. The em2860/2880 datasheet says that it | ||
257 | is supposed to clear the readcount, but it doesn't. So with | ||
258 | the em2874, we are looking for a non-zero read count as | ||
259 | opposed to a readcount that is incrementing */ | ||
260 | ir->last_readcount = 0; | ||
261 | } | ||
262 | |||
263 | if (poll_result.read_count == 0) { | ||
264 | /* The button has not been pressed since the last read */ | ||
265 | } else if (ir->last_toggle != poll_result.toggle_bit) { | ||
266 | /* A button has been pressed */ | ||
267 | dprintk("button has been pressed\n"); | ||
268 | ir->last_toggle = poll_result.toggle_bit; | ||
269 | ir->repeat_interval = 0; | ||
270 | do_sendkey = 1; | ||
271 | } else if (poll_result.toggle_bit == ir->last_toggle && | ||
272 | poll_result.read_count > 0 && | ||
273 | poll_result.read_count != ir->last_readcount) { | ||
274 | /* The button is still being held down */ | ||
275 | dprintk("button being held down\n"); | ||
276 | |||
277 | /* Debouncer for first keypress */ | ||
278 | if (ir->repeat_interval++ > 9) { | ||
279 | /* Start repeating after 1 second */ | ||
280 | do_sendkey = 1; | ||
281 | } | ||
282 | } | ||
283 | |||
284 | if (do_sendkey) { | ||
285 | dprintk("sending keypress\n"); | ||
286 | ir_input_keydown(ir->input, &ir->ir, poll_result.rc_data[0], | ||
287 | poll_result.rc_data[0]); | ||
288 | ir_input_nokey(ir->input, &ir->ir); | ||
289 | } | ||
290 | |||
291 | ir->last_readcount = poll_result.read_count; | ||
292 | return; | ||
293 | } | ||
294 | |||
295 | static void ir_timer(unsigned long data) | ||
296 | { | ||
297 | struct em28xx_IR *ir = (struct em28xx_IR *)data; | ||
298 | |||
299 | schedule_work(&ir->work); | ||
300 | } | ||
301 | |||
302 | static void em28xx_ir_work(struct work_struct *work) | ||
303 | { | ||
304 | struct em28xx_IR *ir = container_of(work, struct em28xx_IR, work); | ||
305 | |||
306 | em28xx_ir_handle_key(ir); | ||
307 | mod_timer(&ir->timer, jiffies + msecs_to_jiffies(ir->polling)); | ||
308 | } | ||
309 | |||
310 | void em28xx_ir_start(struct em28xx_IR *ir) | ||
311 | { | ||
312 | setup_timer(&ir->timer, ir_timer, (unsigned long)ir); | ||
313 | INIT_WORK(&ir->work, em28xx_ir_work); | ||
314 | schedule_work(&ir->work); | ||
315 | } | ||
316 | |||
317 | static void em28xx_ir_stop(struct em28xx_IR *ir) | ||
318 | { | ||
319 | del_timer_sync(&ir->timer); | ||
320 | flush_scheduled_work(); | ||
321 | } | ||
322 | |||
323 | int em28xx_ir_init(struct em28xx *dev) | ||
324 | { | ||
325 | struct em28xx_IR *ir; | ||
326 | struct input_dev *input_dev; | ||
327 | u8 ir_config; | ||
328 | int err = -ENOMEM; | ||
329 | |||
330 | if (dev->board.ir_codes == NULL) { | ||
331 | /* No remote control support */ | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | ir = kzalloc(sizeof(*ir), GFP_KERNEL); | ||
336 | input_dev = input_allocate_device(); | ||
337 | if (!ir || !input_dev) | ||
338 | goto err_out_free; | ||
339 | |||
340 | ir->input = input_dev; | ||
341 | |||
342 | /* Setup the proper handler based on the chip */ | ||
343 | switch (dev->chip_id) { | ||
344 | case CHIP_ID_EM2860: | ||
345 | case CHIP_ID_EM2883: | ||
346 | ir->get_key = default_polling_getkey; | ||
347 | break; | ||
348 | case CHIP_ID_EM2874: | ||
349 | ir->get_key = em2874_polling_getkey; | ||
350 | /* For now we only support RC5, so enable it */ | ||
351 | ir_config = EM2874_IR_RC5; | ||
352 | em28xx_write_regs(dev, EM2874_R50_IR_CONFIG, &ir_config, 1); | ||
353 | break; | ||
354 | default: | ||
355 | printk("Unrecognized em28xx chip id: IR not supported\n"); | ||
356 | goto err_out_free; | ||
357 | } | ||
358 | |||
359 | /* This is how often we ask the chip for IR information */ | ||
360 | ir->polling = 100; /* ms */ | ||
361 | |||
362 | /* init input device */ | ||
363 | snprintf(ir->name, sizeof(ir->name), "em28xx IR (%s)", | ||
364 | dev->name); | ||
365 | |||
366 | usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); | ||
367 | strlcat(ir->phys, "/input0", sizeof(ir->phys)); | ||
368 | |||
369 | ir_input_init(input_dev, &ir->ir, IR_TYPE_OTHER, dev->board.ir_codes); | ||
370 | input_dev->name = ir->name; | ||
371 | input_dev->phys = ir->phys; | ||
372 | input_dev->id.bustype = BUS_USB; | ||
373 | input_dev->id.version = 1; | ||
374 | input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); | ||
375 | input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct); | ||
376 | |||
377 | input_dev->dev.parent = &dev->udev->dev; | ||
378 | /* record handles to ourself */ | ||
379 | ir->dev = dev; | ||
380 | dev->ir = ir; | ||
381 | |||
382 | em28xx_ir_start(ir); | ||
383 | |||
384 | /* all done */ | ||
385 | err = input_register_device(ir->input); | ||
386 | if (err) | ||
387 | goto err_out_stop; | ||
388 | |||
389 | return 0; | ||
390 | err_out_stop: | ||
391 | em28xx_ir_stop(ir); | ||
392 | dev->ir = NULL; | ||
393 | err_out_free: | ||
394 | input_free_device(input_dev); | ||
395 | kfree(ir); | ||
396 | return err; | ||
397 | } | ||
398 | |||
399 | int em28xx_ir_fini(struct em28xx *dev) | ||
400 | { | ||
401 | struct em28xx_IR *ir = dev->ir; | ||
402 | |||
403 | /* skip detach on non attached boards */ | ||
404 | if (!ir) | ||
405 | return 0; | ||
406 | |||
407 | em28xx_ir_stop(ir); | ||
408 | input_unregister_device(ir->input); | ||
409 | kfree(ir); | ||
410 | |||
411 | /* done */ | ||
412 | dev->ir = NULL; | ||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | /********************************************************** | ||
417 | Handle Webcam snapshot button | ||
418 | **********************************************************/ | ||
419 | |||
131 | static void em28xx_query_sbutton(struct work_struct *work) | 420 | static void em28xx_query_sbutton(struct work_struct *work) |
132 | { | 421 | { |
133 | /* Poll the register and see if the button is depressed */ | 422 | /* Poll the register and see if the button is depressed */ |
@@ -210,9 +499,3 @@ void em28xx_deregister_snapshot_button(struct em28xx *dev) | |||
210 | } | 499 | } |
211 | return; | 500 | return; |
212 | } | 501 | } |
213 | |||
214 | /* ---------------------------------------------------------------------- | ||
215 | * Local variables: | ||
216 | * c-basic-offset: 8 | ||
217 | * End: | ||
218 | */ | ||
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h index fac1ab23f621..65dcb91bdcc2 100644 --- a/drivers/media/video/em28xx/em28xx-reg.h +++ b/drivers/media/video/em28xx/em28xx-reg.h | |||
@@ -17,17 +17,58 @@ | |||
17 | 17 | ||
18 | /* em28xx registers */ | 18 | /* em28xx registers */ |
19 | 19 | ||
20 | #define EM28XX_R00_CHIPCFG 0x00 | ||
21 | |||
22 | /* em28xx Chip Configuration 0x00 */ | ||
23 | #define EM28XX_CHIPCFG_VENDOR_AUDIO 0x80 | ||
24 | #define EM28XX_CHIPCFG_I2S_VOLUME_CAPABLE 0x40 | ||
25 | #define EM28XX_CHIPCFG_I2S_5_SAMPRATES 0x30 | ||
26 | #define EM28XX_CHIPCFG_I2S_3_SAMPRATES 0x20 | ||
27 | #define EM28XX_CHIPCFG_AC97 0x10 | ||
28 | #define EM28XX_CHIPCFG_AUDIOMASK 0x30 | ||
29 | |||
20 | /* GPIO/GPO registers */ | 30 | /* GPIO/GPO registers */ |
21 | #define EM2880_R04_GPO 0x04 /* em2880-em2883 only */ | 31 | #define EM2880_R04_GPO 0x04 /* em2880-em2883 only */ |
22 | #define EM28XX_R08_GPIO 0x08 /* em2820 or upper */ | 32 | #define EM28XX_R08_GPIO 0x08 /* em2820 or upper */ |
23 | 33 | ||
24 | #define EM28XX_R06_I2C_CLK 0x06 | 34 | #define EM28XX_R06_I2C_CLK 0x06 |
35 | |||
36 | /* em28xx I2C Clock Register (0x06) */ | ||
37 | #define EM28XX_I2C_CLK_ACK_LAST_READ 0x80 | ||
38 | #define EM28XX_I2C_CLK_WAIT_ENABLE 0x40 | ||
39 | #define EM28XX_I2C_EEPROM_ON_BOARD 0x08 | ||
40 | #define EM28XX_I2C_EEPROM_KEY_VALID 0x04 | ||
41 | #define EM2874_I2C_SECONDARY_BUS_SELECT 0x04 /* em2874 has two i2c busses */ | ||
42 | #define EM28XX_I2C_FREQ_1_5_MHZ 0x03 /* bus frequency (bits [1-0]) */ | ||
43 | #define EM28XX_I2C_FREQ_25_KHZ 0x02 | ||
44 | #define EM28XX_I2C_FREQ_400_KHZ 0x01 | ||
45 | #define EM28XX_I2C_FREQ_100_KHZ 0x00 | ||
46 | |||
47 | |||
25 | #define EM28XX_R0A_CHIPID 0x0a | 48 | #define EM28XX_R0A_CHIPID 0x0a |
26 | #define EM28XX_R0C_USBSUSP 0x0c /* */ | 49 | #define EM28XX_R0C_USBSUSP 0x0c /* */ |
27 | 50 | ||
28 | #define EM28XX_R0E_AUDIOSRC 0x0e | 51 | #define EM28XX_R0E_AUDIOSRC 0x0e |
29 | #define EM28XX_R0F_XCLK 0x0f | 52 | #define EM28XX_R0F_XCLK 0x0f |
30 | 53 | ||
54 | /* em28xx XCLK Register (0x0f) */ | ||
55 | #define EM28XX_XCLK_AUDIO_UNMUTE 0x80 /* otherwise audio muted */ | ||
56 | #define EM28XX_XCLK_I2S_MSB_TIMING 0x40 /* otherwise standard timing */ | ||
57 | #define EM28XX_XCLK_IR_RC5_MODE 0x20 /* otherwise NEC mode */ | ||
58 | #define EM28XX_XCLK_IR_NEC_CHK_PARITY 0x10 | ||
59 | #define EM28XX_XCLK_FREQUENCY_30MHZ 0x00 /* Freq. select (bits [3-0]) */ | ||
60 | #define EM28XX_XCLK_FREQUENCY_15MHZ 0x01 | ||
61 | #define EM28XX_XCLK_FREQUENCY_10MHZ 0x02 | ||
62 | #define EM28XX_XCLK_FREQUENCY_7_5MHZ 0x03 | ||
63 | #define EM28XX_XCLK_FREQUENCY_6MHZ 0x04 | ||
64 | #define EM28XX_XCLK_FREQUENCY_5MHZ 0x05 | ||
65 | #define EM28XX_XCLK_FREQUENCY_4_3MHZ 0x06 | ||
66 | #define EM28XX_XCLK_FREQUENCY_12MHZ 0x07 | ||
67 | #define EM28XX_XCLK_FREQUENCY_20MHZ 0x08 | ||
68 | #define EM28XX_XCLK_FREQUENCY_20MHZ_2 0x09 | ||
69 | #define EM28XX_XCLK_FREQUENCY_48MHZ 0x0a | ||
70 | #define EM28XX_XCLK_FREQUENCY_24MHZ 0x0b | ||
71 | |||
31 | #define EM28XX_R10_VINMODE 0x10 | 72 | #define EM28XX_R10_VINMODE 0x10 |
32 | #define EM28XX_R11_VINCTRL 0x11 | 73 | #define EM28XX_R11_VINCTRL 0x11 |
33 | #define EM28XX_R12_VINENABLE 0x12 /* */ | 74 | #define EM28XX_R12_VINENABLE 0x12 /* */ |
@@ -56,6 +97,19 @@ | |||
56 | #define EM28XX_R26_COMPR 0x26 | 97 | #define EM28XX_R26_COMPR 0x26 |
57 | #define EM28XX_R27_OUTFMT 0x27 | 98 | #define EM28XX_R27_OUTFMT 0x27 |
58 | 99 | ||
100 | /* em28xx Output Format Register (0x27) */ | ||
101 | #define EM28XX_OUTFMT_RGB_8_RGRG 0x00 | ||
102 | #define EM28XX_OUTFMT_RGB_8_GRGR 0x01 | ||
103 | #define EM28XX_OUTFMT_RGB_8_GBGB 0x02 | ||
104 | #define EM28XX_OUTFMT_RGB_8_BGBG 0x03 | ||
105 | #define EM28XX_OUTFMT_RGB_16_656 0x04 | ||
106 | #define EM28XX_OUTFMT_RGB_8_BAYER 0x08 /* Pattern in Reg 0x10[1-0] */ | ||
107 | #define EM28XX_OUTFMT_YUV211 0x10 | ||
108 | #define EM28XX_OUTFMT_YUV422_Y0UY1V 0x14 | ||
109 | #define EM28XX_OUTFMT_YUV422_Y1UY0V 0x15 | ||
110 | #define EM28XX_OUTFMT_YUV411 0x18 | ||
111 | |||
112 | |||
59 | #define EM28XX_R28_XMIN 0x28 | 113 | #define EM28XX_R28_XMIN 0x28 |
60 | #define EM28XX_R29_XMAX 0x29 | 114 | #define EM28XX_R29_XMAX 0x29 |
61 | #define EM28XX_R2A_YMIN 0x2a | 115 | #define EM28XX_R2A_YMIN 0x2a |
@@ -71,10 +125,32 @@ | |||
71 | #define EM28XX_R42_AC97ADDR 0x42 | 125 | #define EM28XX_R42_AC97ADDR 0x42 |
72 | #define EM28XX_R43_AC97BUSY 0x43 | 126 | #define EM28XX_R43_AC97BUSY 0x43 |
73 | 127 | ||
74 | /* em202 registers */ | 128 | #define EM28XX_R45_IR 0x45 |
75 | #define EM28XX_R02_MASTER_AC97 0x02 | 129 | /* 0x45 bit 7 - parity bit |
76 | #define EM28XX_R10_LINE_IN_AC97 0x10 | 130 | bits 6-0 - count |
77 | #define EM28XX_R14_VIDEO_AC97 0x14 | 131 | 0x46 IR brand |
132 | 0x47 IR data | ||
133 | */ | ||
134 | |||
135 | /* em2874 registers */ | ||
136 | #define EM2874_R50_IR_CONFIG 0x50 | ||
137 | #define EM2874_R51_IR 0x51 | ||
138 | #define EM2874_R5F_TS_ENABLE 0x5f | ||
139 | #define EM2874_R80_GPIO 0x80 | ||
140 | |||
141 | /* em2874 IR config register (0x50) */ | ||
142 | #define EM2874_IR_NEC 0x00 | ||
143 | #define EM2874_IR_RC5 0x04 | ||
144 | #define EM2874_IR_RC5_MODE_0 0x08 | ||
145 | #define EM2874_IR_RC5_MODE_6A 0x0b | ||
146 | |||
147 | /* em2874 Transport Stream Enable Register (0x5f) */ | ||
148 | #define EM2874_TS1_CAPTURE_ENABLE (1 << 0) | ||
149 | #define EM2874_TS1_FILTER_ENABLE (1 << 1) | ||
150 | #define EM2874_TS1_NULL_DISCARD (1 << 2) | ||
151 | #define EM2874_TS2_CAPTURE_ENABLE (1 << 4) | ||
152 | #define EM2874_TS2_FILTER_ENABLE (1 << 5) | ||
153 | #define EM2874_TS2_NULL_DISCARD (1 << 6) | ||
78 | 154 | ||
79 | /* register settings */ | 155 | /* register settings */ |
80 | #define EM2800_AUDIO_SRC_TUNER 0x0d | 156 | #define EM2800_AUDIO_SRC_TUNER 0x0d |
@@ -84,6 +160,75 @@ | |||
84 | 160 | ||
85 | /* FIXME: Need to be populated with the other chip ID's */ | 161 | /* FIXME: Need to be populated with the other chip ID's */ |
86 | enum em28xx_chip_id { | 162 | enum em28xx_chip_id { |
163 | CHIP_ID_EM2820 = 18, | ||
164 | CHIP_ID_EM2840 = 20, | ||
165 | CHIP_ID_EM2750 = 33, | ||
87 | CHIP_ID_EM2860 = 34, | 166 | CHIP_ID_EM2860 = 34, |
167 | CHIP_ID_EM2870 = 35, | ||
88 | CHIP_ID_EM2883 = 36, | 168 | CHIP_ID_EM2883 = 36, |
169 | CHIP_ID_EM2874 = 65, | ||
89 | }; | 170 | }; |
171 | |||
172 | /* | ||
173 | * Registers used by em202 and other AC97 chips | ||
174 | */ | ||
175 | |||
176 | /* Standard AC97 registers */ | ||
177 | #define AC97_RESET 0x00 | ||
178 | |||
179 | /* Output volumes */ | ||
180 | #define AC97_MASTER_VOL 0x02 | ||
181 | #define AC97_LINE_LEVEL_VOL 0x04 /* Some devices use for headphones */ | ||
182 | #define AC97_MASTER_MONO_VOL 0x06 | ||
183 | |||
184 | /* Input volumes */ | ||
185 | #define AC97_PC_BEEP_VOL 0x0a | ||
186 | #define AC97_PHONE_VOL 0x0c | ||
187 | #define AC97_MIC_VOL 0x0e | ||
188 | #define AC97_LINEIN_VOL 0x10 | ||
189 | #define AC97_CD_VOL 0x12 | ||
190 | #define AC97_VIDEO_VOL 0x14 | ||
191 | #define AC97_AUX_VOL 0x16 | ||
192 | #define AC97_PCM_OUT_VOL 0x18 | ||
193 | |||
194 | /* capture registers */ | ||
195 | #define AC97_RECORD_SELECT 0x1a | ||
196 | #define AC97_RECORD_GAIN 0x1c | ||
197 | |||
198 | /* control registers */ | ||
199 | #define AC97_GENERAL_PURPOSE 0x20 | ||
200 | #define AC97_3D_CTRL 0x22 | ||
201 | #define AC97_AUD_INT_AND_PAG 0x24 | ||
202 | #define AC97_POWER_DOWN_CTRL 0x26 | ||
203 | #define AC97_EXT_AUD_ID 0x28 | ||
204 | #define AC97_EXT_AUD_CTRL 0x2a | ||
205 | |||
206 | /* Supported rate varies for each AC97 device | ||
207 | if write an unsupported value, it will return the closest one | ||
208 | */ | ||
209 | #define AC97_PCM_OUT_FRONT_SRATE 0x2c | ||
210 | #define AC97_PCM_OUT_SURR_SRATE 0x2e | ||
211 | #define AC97_PCM_OUT_LFE_SRATE 0x30 | ||
212 | #define AC97_PCM_IN_SRATE 0x32 | ||
213 | |||
214 | /* For devices with more than 2 channels, extra output volumes */ | ||
215 | #define AC97_LFE_MASTER_VOL 0x36 | ||
216 | #define AC97_SURR_MASTER_VOL 0x38 | ||
217 | |||
218 | /* Digital SPDIF output control */ | ||
219 | #define AC97_SPDIF_OUT_CTRL 0x3a | ||
220 | |||
221 | /* Vendor ID identifier */ | ||
222 | #define AC97_VENDOR_ID1 0x7c | ||
223 | #define AC97_VENDOR_ID2 0x7e | ||
224 | |||
225 | /* EMP202 vendor registers */ | ||
226 | #define EM202_EXT_MODEM_CTRL 0x3e | ||
227 | #define EM202_GPIO_CONF 0x4c | ||
228 | #define EM202_GPIO_POLARITY 0x4e | ||
229 | #define EM202_GPIO_STICKY 0x50 | ||
230 | #define EM202_GPIO_MASK 0x52 | ||
231 | #define EM202_GPIO_STATUS 0x54 | ||
232 | #define EM202_SPDIF_OUT_SEL 0x6a | ||
233 | #define EM202_ANTIPOP 0x72 | ||
234 | #define EM202_EAPD_GPIO_ACCESS 0x74 | ||
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 4ea1f1e04897..53527536481e 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include "em28xx.h" | 39 | #include "em28xx.h" |
40 | #include <media/v4l2-common.h> | 40 | #include <media/v4l2-common.h> |
41 | #include <media/v4l2-ioctl.h> | 41 | #include <media/v4l2-ioctl.h> |
42 | #include <media/v4l2-chip-ident.h> | ||
42 | #include <media/msp3400.h> | 43 | #include <media/msp3400.h> |
43 | #include <media/tuner.h> | 44 | #include <media/tuner.h> |
44 | 45 | ||
@@ -47,9 +48,8 @@ | |||
47 | "Mauro Carvalho Chehab <mchehab@infradead.org>, " \ | 48 | "Mauro Carvalho Chehab <mchehab@infradead.org>, " \ |
48 | "Sascha Sommer <saschasommer@freenet.de>" | 49 | "Sascha Sommer <saschasommer@freenet.de>" |
49 | 50 | ||
50 | #define DRIVER_NAME "em28xx" | ||
51 | #define DRIVER_DESC "Empia em28xx based USB video device driver" | 51 | #define DRIVER_DESC "Empia em28xx based USB video device driver" |
52 | #define EM28XX_VERSION_CODE KERNEL_VERSION(0, 1, 0) | 52 | #define EM28XX_VERSION_CODE KERNEL_VERSION(0, 1, 1) |
53 | 53 | ||
54 | #define em28xx_videodbg(fmt, arg...) do {\ | 54 | #define em28xx_videodbg(fmt, arg...) do {\ |
55 | if (video_debug) \ | 55 | if (video_debug) \ |
@@ -72,19 +72,13 @@ MODULE_AUTHOR(DRIVER_AUTHOR); | |||
72 | MODULE_DESCRIPTION(DRIVER_DESC); | 72 | MODULE_DESCRIPTION(DRIVER_DESC); |
73 | MODULE_LICENSE("GPL"); | 73 | MODULE_LICENSE("GPL"); |
74 | 74 | ||
75 | static LIST_HEAD(em28xx_devlist); | ||
76 | static DEFINE_MUTEX(em28xx_devlist_mutex); | ||
77 | |||
78 | static unsigned int card[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | ||
79 | static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | 75 | static unsigned int video_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; |
80 | static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | 76 | static unsigned int vbi_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; |
81 | static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; | 77 | static unsigned int radio_nr[] = {[0 ... (EM28XX_MAXBOARDS - 1)] = UNSET }; |
82 | 78 | ||
83 | module_param_array(card, int, NULL, 0444); | ||
84 | module_param_array(video_nr, int, NULL, 0444); | 79 | module_param_array(video_nr, int, NULL, 0444); |
85 | module_param_array(vbi_nr, int, NULL, 0444); | 80 | module_param_array(vbi_nr, int, NULL, 0444); |
86 | module_param_array(radio_nr, int, NULL, 0444); | 81 | module_param_array(radio_nr, int, NULL, 0444); |
87 | MODULE_PARM_DESC(card, "card type"); | ||
88 | MODULE_PARM_DESC(video_nr, "video device numbers"); | 82 | MODULE_PARM_DESC(video_nr, "video device numbers"); |
89 | MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); | 83 | MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); |
90 | MODULE_PARM_DESC(radio_nr, "radio device numbers"); | 84 | MODULE_PARM_DESC(radio_nr, "radio device numbers"); |
@@ -93,8 +87,15 @@ static unsigned int video_debug; | |||
93 | module_param(video_debug, int, 0644); | 87 | module_param(video_debug, int, 0644); |
94 | MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); | 88 | MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); |
95 | 89 | ||
96 | /* Bitmask marking allocated devices from 0 to EM28XX_MAXBOARDS */ | 90 | /* supported video standards */ |
97 | static unsigned long em28xx_devused; | 91 | static struct em28xx_fmt format[] = { |
92 | { | ||
93 | .name = "16bpp YUY2, 4:2:2, packed", | ||
94 | .fourcc = V4L2_PIX_FMT_YUYV, | ||
95 | .depth = 16, | ||
96 | .reg = EM28XX_OUTFMT_YUV422_Y0UY1V, | ||
97 | }, | ||
98 | }; | ||
98 | 99 | ||
99 | /* supported controls */ | 100 | /* supported controls */ |
100 | /* Common to all boards */ | 101 | /* Common to all boards */ |
@@ -120,8 +121,6 @@ static struct v4l2_queryctrl em28xx_qctrl[] = { | |||
120 | } | 121 | } |
121 | }; | 122 | }; |
122 | 123 | ||
123 | static struct usb_driver em28xx_usb_driver; | ||
124 | |||
125 | /* ------------------------------------------------------------------ | 124 | /* ------------------------------------------------------------------ |
126 | DMA and thread functions | 125 | DMA and thread functions |
127 | ------------------------------------------------------------------*/ | 126 | ------------------------------------------------------------------*/ |
@@ -386,16 +385,18 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) | |||
386 | struct em28xx *dev = fh->dev; | 385 | struct em28xx *dev = fh->dev; |
387 | struct v4l2_frequency f; | 386 | struct v4l2_frequency f; |
388 | 387 | ||
389 | *size = 16 * fh->dev->width * fh->dev->height >> 3; | 388 | *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3; |
389 | |||
390 | if (0 == *count) | 390 | if (0 == *count) |
391 | *count = EM28XX_DEF_BUF; | 391 | *count = EM28XX_DEF_BUF; |
392 | 392 | ||
393 | if (*count < EM28XX_MIN_BUF) | 393 | if (*count < EM28XX_MIN_BUF) |
394 | *count = EM28XX_MIN_BUF; | 394 | *count = EM28XX_MIN_BUF; |
395 | 395 | ||
396 | /* Ask tuner to go to analog mode */ | 396 | /* Ask tuner to go to analog or radio mode */ |
397 | memset(&f, 0, sizeof(f)); | 397 | memset(&f, 0, sizeof(f)); |
398 | f.frequency = dev->ctl_freq; | 398 | f.frequency = dev->ctl_freq; |
399 | f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
399 | 400 | ||
400 | em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f); | 401 | em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f); |
401 | 402 | ||
@@ -438,9 +439,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, | |||
438 | struct em28xx *dev = fh->dev; | 439 | struct em28xx *dev = fh->dev; |
439 | int rc = 0, urb_init = 0; | 440 | int rc = 0, urb_init = 0; |
440 | 441 | ||
441 | /* FIXME: It assumes depth = 16 */ | 442 | buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3; |
442 | /* The only currently supported format is 16 bits/pixel */ | ||
443 | buf->vb.size = 16 * dev->width * dev->height >> 3; | ||
444 | 443 | ||
445 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) | 444 | if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) |
446 | return -EINVAL; | 445 | return -EINVAL; |
@@ -508,56 +507,6 @@ static struct videobuf_queue_ops em28xx_video_qops = { | |||
508 | 507 | ||
509 | /********************* v4l2 interface **************************************/ | 508 | /********************* v4l2 interface **************************************/ |
510 | 509 | ||
511 | /* | ||
512 | * em28xx_config() | ||
513 | * inits registers with sane defaults | ||
514 | */ | ||
515 | static int em28xx_config(struct em28xx *dev) | ||
516 | { | ||
517 | int retval; | ||
518 | |||
519 | /* Sets I2C speed to 100 KHz */ | ||
520 | if (!dev->is_em2800) { | ||
521 | retval = em28xx_write_regs_req(dev, 0x00, 0x06, "\x40", 1); | ||
522 | if (retval < 0) { | ||
523 | em28xx_errdev("%s: em28xx_write_regs_req failed! retval [%d]\n", | ||
524 | __func__, retval); | ||
525 | return retval; | ||
526 | } | ||
527 | } | ||
528 | |||
529 | /* enable vbi capturing */ | ||
530 | |||
531 | /* em28xx_write_regs_req(dev, 0x00, 0x0e, "\xC0", 1); audio register */ | ||
532 | /* em28xx_write_regs_req(dev, 0x00, 0x0f, "\x80", 1); clk register */ | ||
533 | em28xx_write_regs_req(dev, 0x00, 0x11, "\x51", 1); | ||
534 | |||
535 | dev->mute = 1; /* maybe not the right place... */ | ||
536 | dev->volume = 0x1f; | ||
537 | |||
538 | em28xx_outfmt_set_yuv422(dev); | ||
539 | em28xx_colorlevels_set_default(dev); | ||
540 | em28xx_compression_disable(dev); | ||
541 | |||
542 | return 0; | ||
543 | } | ||
544 | |||
545 | /* | ||
546 | * em28xx_config_i2c() | ||
547 | * configure i2c attached devices | ||
548 | */ | ||
549 | static void em28xx_config_i2c(struct em28xx *dev) | ||
550 | { | ||
551 | struct v4l2_routing route; | ||
552 | int zero = 0; | ||
553 | |||
554 | route.input = INPUT(dev->ctl_input)->vmux; | ||
555 | route.output = 0; | ||
556 | em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, &zero); | ||
557 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); | ||
558 | em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL); | ||
559 | } | ||
560 | |||
561 | static void video_mux(struct em28xx *dev, int index) | 510 | static void video_mux(struct em28xx *dev, int index) |
562 | { | 511 | { |
563 | struct v4l2_routing route; | 512 | struct v4l2_routing route; |
@@ -566,10 +515,14 @@ static void video_mux(struct em28xx *dev, int index) | |||
566 | route.output = 0; | 515 | route.output = 0; |
567 | dev->ctl_input = index; | 516 | dev->ctl_input = index; |
568 | dev->ctl_ainput = INPUT(index)->amux; | 517 | dev->ctl_ainput = INPUT(index)->amux; |
518 | dev->ctl_aoutput = INPUT(index)->aout; | ||
519 | |||
520 | if (!dev->ctl_aoutput) | ||
521 | dev->ctl_aoutput = EM28XX_AOUT_MASTER; | ||
569 | 522 | ||
570 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); | 523 | em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route); |
571 | 524 | ||
572 | if (dev->has_msp34xx) { | 525 | if (dev->board.has_msp34xx) { |
573 | if (dev->i2s_speed) { | 526 | if (dev->i2s_speed) { |
574 | em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, | 527 | em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ, |
575 | &dev->i2s_speed); | 528 | &dev->i2s_speed); |
@@ -595,12 +548,10 @@ static int res_get(struct em28xx_fh *fh) | |||
595 | return rc; | 548 | return rc; |
596 | 549 | ||
597 | if (dev->stream_on) | 550 | if (dev->stream_on) |
598 | return -EINVAL; | 551 | return -EBUSY; |
599 | 552 | ||
600 | mutex_lock(&dev->lock); | ||
601 | dev->stream_on = 1; | 553 | dev->stream_on = 1; |
602 | fh->stream_on = 1; | 554 | fh->stream_on = 1; |
603 | mutex_unlock(&dev->lock); | ||
604 | return rc; | 555 | return rc; |
605 | } | 556 | } |
606 | 557 | ||
@@ -613,10 +564,8 @@ static void res_free(struct em28xx_fh *fh) | |||
613 | { | 564 | { |
614 | struct em28xx *dev = fh->dev; | 565 | struct em28xx *dev = fh->dev; |
615 | 566 | ||
616 | mutex_lock(&dev->lock); | ||
617 | fh->stream_on = 0; | 567 | fh->stream_on = 0; |
618 | dev->stream_on = 0; | 568 | dev->stream_on = 0; |
619 | mutex_unlock(&dev->lock); | ||
620 | } | 569 | } |
621 | 570 | ||
622 | /* | 571 | /* |
@@ -703,8 +652,8 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
703 | 652 | ||
704 | f->fmt.pix.width = dev->width; | 653 | f->fmt.pix.width = dev->width; |
705 | f->fmt.pix.height = dev->height; | 654 | f->fmt.pix.height = dev->height; |
706 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; | 655 | f->fmt.pix.pixelformat = dev->format->fourcc; |
707 | f->fmt.pix.bytesperline = dev->width * 2; | 656 | f->fmt.pix.bytesperline = (dev->width * dev->format->depth + 7) >> 3; |
708 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height; | 657 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * dev->height; |
709 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | 658 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
710 | 659 | ||
@@ -716,6 +665,17 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, | |||
716 | return 0; | 665 | return 0; |
717 | } | 666 | } |
718 | 667 | ||
668 | static struct em28xx_fmt *format_by_fourcc(unsigned int fourcc) | ||
669 | { | ||
670 | unsigned int i; | ||
671 | |||
672 | for (i = 0; i < ARRAY_SIZE(format); i++) | ||
673 | if (format[i].fourcc == fourcc) | ||
674 | return &format[i]; | ||
675 | |||
676 | return NULL; | ||
677 | } | ||
678 | |||
719 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | 679 | static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, |
720 | struct v4l2_format *f) | 680 | struct v4l2_format *f) |
721 | { | 681 | { |
@@ -726,24 +686,30 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
726 | unsigned int maxw = norm_maxw(dev); | 686 | unsigned int maxw = norm_maxw(dev); |
727 | unsigned int maxh = norm_maxh(dev); | 687 | unsigned int maxh = norm_maxh(dev); |
728 | unsigned int hscale, vscale; | 688 | unsigned int hscale, vscale; |
689 | struct em28xx_fmt *fmt; | ||
690 | |||
691 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | ||
692 | if (!fmt) { | ||
693 | em28xx_videodbg("Fourcc format (%08x) invalid.\n", | ||
694 | f->fmt.pix.pixelformat); | ||
695 | return -EINVAL; | ||
696 | } | ||
729 | 697 | ||
730 | /* width must even because of the YUYV format | 698 | /* width must even because of the YUYV format |
731 | height must be even because of interlacing */ | 699 | height must be even because of interlacing */ |
732 | height &= 0xfffe; | 700 | height &= 0xfffe; |
733 | width &= 0xfffe; | 701 | width &= 0xfffe; |
734 | 702 | ||
735 | if (height < 32) | 703 | if (unlikely(height < 32)) |
736 | height = 32; | 704 | height = 32; |
737 | if (height > maxh) | 705 | if (unlikely(height > maxh)) |
738 | height = maxh; | 706 | height = maxh; |
739 | if (width < 48) | 707 | if (unlikely(width < 48)) |
740 | width = 48; | 708 | width = 48; |
741 | if (width > maxw) | 709 | if (unlikely(width > maxw)) |
742 | width = maxw; | 710 | width = maxw; |
743 | 711 | ||
744 | mutex_lock(&dev->lock); | 712 | if (dev->board.is_em2800) { |
745 | |||
746 | if (dev->is_em2800) { | ||
747 | /* the em2800 can only scale down to 50% */ | 713 | /* the em2800 can only scale down to 50% */ |
748 | if (height % (maxh / 2)) | 714 | if (height % (maxh / 2)) |
749 | height = maxh; | 715 | height = maxh; |
@@ -766,13 +732,12 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, | |||
766 | 732 | ||
767 | f->fmt.pix.width = width; | 733 | f->fmt.pix.width = width; |
768 | f->fmt.pix.height = height; | 734 | f->fmt.pix.height = height; |
769 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; | 735 | f->fmt.pix.pixelformat = fmt->fourcc; |
770 | f->fmt.pix.bytesperline = width * 2; | 736 | f->fmt.pix.bytesperline = (dev->width * fmt->depth + 7) >> 3; |
771 | f->fmt.pix.sizeimage = width * 2 * height; | 737 | f->fmt.pix.sizeimage = f->fmt.pix.bytesperline * height; |
772 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; | 738 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
773 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; | 739 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; |
774 | 740 | ||
775 | mutex_unlock(&dev->lock); | ||
776 | return 0; | 741 | return 0; |
777 | } | 742 | } |
778 | 743 | ||
@@ -782,14 +747,21 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
782 | struct em28xx_fh *fh = priv; | 747 | struct em28xx_fh *fh = priv; |
783 | struct em28xx *dev = fh->dev; | 748 | struct em28xx *dev = fh->dev; |
784 | int rc; | 749 | int rc; |
750 | struct em28xx_fmt *fmt; | ||
785 | 751 | ||
786 | rc = check_dev(dev); | 752 | rc = check_dev(dev); |
787 | if (rc < 0) | 753 | if (rc < 0) |
788 | return rc; | 754 | return rc; |
789 | 755 | ||
756 | mutex_lock(&dev->lock); | ||
757 | |||
790 | vidioc_try_fmt_vid_cap(file, priv, f); | 758 | vidioc_try_fmt_vid_cap(file, priv, f); |
791 | 759 | ||
792 | mutex_lock(&dev->lock); | 760 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
761 | if (!fmt) { | ||
762 | rc = -EINVAL; | ||
763 | goto out; | ||
764 | } | ||
793 | 765 | ||
794 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { | 766 | if (videobuf_queue_is_busy(&fh->vb_vidq)) { |
795 | em28xx_errdev("%s queue busy\n", __func__); | 767 | em28xx_errdev("%s queue busy\n", __func__); |
@@ -806,6 +778,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
806 | /* set new image size */ | 778 | /* set new image size */ |
807 | dev->width = f->fmt.pix.width; | 779 | dev->width = f->fmt.pix.width; |
808 | dev->height = f->fmt.pix.height; | 780 | dev->height = f->fmt.pix.height; |
781 | dev->format = fmt; | ||
809 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); | 782 | get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale); |
810 | 783 | ||
811 | em28xx_set_alternate(dev); | 784 | em28xx_set_alternate(dev); |
@@ -831,15 +804,12 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * norm) | |||
831 | 804 | ||
832 | mutex_lock(&dev->lock); | 805 | mutex_lock(&dev->lock); |
833 | dev->norm = *norm; | 806 | dev->norm = *norm; |
834 | mutex_unlock(&dev->lock); | ||
835 | 807 | ||
836 | /* Adjusts width/height, if needed */ | 808 | /* Adjusts width/height, if needed */ |
837 | f.fmt.pix.width = dev->width; | 809 | f.fmt.pix.width = dev->width; |
838 | f.fmt.pix.height = dev->height; | 810 | f.fmt.pix.height = dev->height; |
839 | vidioc_try_fmt_vid_cap(file, priv, &f); | 811 | vidioc_try_fmt_vid_cap(file, priv, &f); |
840 | 812 | ||
841 | mutex_lock(&dev->lock); | ||
842 | |||
843 | /* set new image size */ | 813 | /* set new image size */ |
844 | dev->width = f.fmt.pix.width; | 814 | dev->width = f.fmt.pix.width; |
845 | dev->height = f.fmt.pix.height; | 815 | dev->height = f.fmt.pix.height; |
@@ -928,20 +898,38 @@ static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a) | |||
928 | { | 898 | { |
929 | struct em28xx_fh *fh = priv; | 899 | struct em28xx_fh *fh = priv; |
930 | struct em28xx *dev = fh->dev; | 900 | struct em28xx *dev = fh->dev; |
931 | unsigned int index = a->index; | ||
932 | |||
933 | if (a->index > 1) | ||
934 | return -EINVAL; | ||
935 | |||
936 | index = dev->ctl_ainput; | ||
937 | 901 | ||
938 | if (index == 0) | 902 | switch (a->index) { |
903 | case EM28XX_AMUX_VIDEO: | ||
939 | strcpy(a->name, "Television"); | 904 | strcpy(a->name, "Television"); |
940 | else | 905 | break; |
906 | case EM28XX_AMUX_LINE_IN: | ||
941 | strcpy(a->name, "Line In"); | 907 | strcpy(a->name, "Line In"); |
908 | break; | ||
909 | case EM28XX_AMUX_VIDEO2: | ||
910 | strcpy(a->name, "Television alt"); | ||
911 | break; | ||
912 | case EM28XX_AMUX_PHONE: | ||
913 | strcpy(a->name, "Phone"); | ||
914 | break; | ||
915 | case EM28XX_AMUX_MIC: | ||
916 | strcpy(a->name, "Mic"); | ||
917 | break; | ||
918 | case EM28XX_AMUX_CD: | ||
919 | strcpy(a->name, "CD"); | ||
920 | break; | ||
921 | case EM28XX_AMUX_AUX: | ||
922 | strcpy(a->name, "Aux"); | ||
923 | break; | ||
924 | case EM28XX_AMUX_PCM_OUT: | ||
925 | strcpy(a->name, "PCM"); | ||
926 | break; | ||
927 | default: | ||
928 | return -EINVAL; | ||
929 | } | ||
942 | 930 | ||
931 | a->index = dev->ctl_ainput; | ||
943 | a->capability = V4L2_AUDCAP_STEREO; | 932 | a->capability = V4L2_AUDCAP_STEREO; |
944 | a->index = index; | ||
945 | 933 | ||
946 | return 0; | 934 | return 0; |
947 | } | 935 | } |
@@ -951,9 +939,15 @@ static int vidioc_s_audio(struct file *file, void *priv, struct v4l2_audio *a) | |||
951 | struct em28xx_fh *fh = priv; | 939 | struct em28xx_fh *fh = priv; |
952 | struct em28xx *dev = fh->dev; | 940 | struct em28xx *dev = fh->dev; |
953 | 941 | ||
954 | if (a->index != dev->ctl_ainput) | 942 | mutex_lock(&dev->lock); |
955 | return -EINVAL; | 943 | |
944 | dev->ctl_ainput = INPUT(a->index)->amux; | ||
945 | dev->ctl_aoutput = INPUT(a->index)->aout; | ||
956 | 946 | ||
947 | if (!dev->ctl_aoutput) | ||
948 | dev->ctl_aoutput = EM28XX_AOUT_MASTER; | ||
949 | |||
950 | mutex_unlock(&dev->lock); | ||
957 | return 0; | 951 | return 0; |
958 | } | 952 | } |
959 | 953 | ||
@@ -974,7 +968,7 @@ static int vidioc_queryctrl(struct file *file, void *priv, | |||
974 | 968 | ||
975 | qc->id = id; | 969 | qc->id = id; |
976 | 970 | ||
977 | if (!dev->has_msp34xx) { | 971 | if (!dev->board.has_msp34xx) { |
978 | for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { | 972 | for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) { |
979 | if (qc->id && qc->id == em28xx_qctrl[i].id) { | 973 | if (qc->id && qc->id == em28xx_qctrl[i].id) { |
980 | memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc)); | 974 | memcpy(qc, &(em28xx_qctrl[i]), sizeof(*qc)); |
@@ -1002,17 +996,14 @@ static int vidioc_g_ctrl(struct file *file, void *priv, | |||
1002 | rc = check_dev(dev); | 996 | rc = check_dev(dev); |
1003 | if (rc < 0) | 997 | if (rc < 0) |
1004 | return rc; | 998 | return rc; |
1005 | mutex_lock(&dev->lock); | 999 | rc = 0; |
1006 | 1000 | ||
1007 | if (!dev->has_msp34xx) | 1001 | mutex_lock(&dev->lock); |
1008 | rc = em28xx_get_ctrl(dev, ctrl); | ||
1009 | else | ||
1010 | rc = -EINVAL; | ||
1011 | 1002 | ||
1012 | if (rc == -EINVAL) { | 1003 | if (dev->board.has_msp34xx) |
1013 | em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl); | 1004 | em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl); |
1014 | rc = 0; | 1005 | else |
1015 | } | 1006 | rc = em28xx_get_ctrl(dev, ctrl); |
1016 | 1007 | ||
1017 | mutex_unlock(&dev->lock); | 1008 | mutex_unlock(&dev->lock); |
1018 | return rc; | 1009 | return rc; |
@@ -1032,7 +1023,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
1032 | 1023 | ||
1033 | mutex_lock(&dev->lock); | 1024 | mutex_lock(&dev->lock); |
1034 | 1025 | ||
1035 | if (dev->has_msp34xx) | 1026 | if (dev->board.has_msp34xx) |
1036 | em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl); | 1027 | em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl); |
1037 | else { | 1028 | else { |
1038 | rc = 1; | 1029 | rc = 1; |
@@ -1112,8 +1103,10 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
1112 | struct em28xx_fh *fh = priv; | 1103 | struct em28xx_fh *fh = priv; |
1113 | struct em28xx *dev = fh->dev; | 1104 | struct em28xx *dev = fh->dev; |
1114 | 1105 | ||
1106 | mutex_lock(&dev->lock); | ||
1115 | f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1107 | f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; |
1116 | f->frequency = dev->ctl_freq; | 1108 | f->frequency = dev->ctl_freq; |
1109 | mutex_unlock(&dev->lock); | ||
1117 | 1110 | ||
1118 | return 0; | 1111 | return 0; |
1119 | } | 1112 | } |
@@ -1143,6 +1136,7 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
1143 | em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f); | 1136 | em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f); |
1144 | 1137 | ||
1145 | mutex_unlock(&dev->lock); | 1138 | mutex_unlock(&dev->lock); |
1139 | |||
1146 | return 0; | 1140 | return 0; |
1147 | } | 1141 | } |
1148 | 1142 | ||
@@ -1159,6 +1153,21 @@ static int em28xx_reg_len(int reg) | |||
1159 | } | 1153 | } |
1160 | } | 1154 | } |
1161 | 1155 | ||
1156 | static int vidioc_g_chip_ident(struct file *file, void *priv, | ||
1157 | struct v4l2_chip_ident *chip) | ||
1158 | { | ||
1159 | struct em28xx_fh *fh = priv; | ||
1160 | struct em28xx *dev = fh->dev; | ||
1161 | |||
1162 | chip->ident = V4L2_IDENT_NONE; | ||
1163 | chip->revision = 0; | ||
1164 | |||
1165 | em28xx_i2c_call_clients(dev, VIDIOC_G_CHIP_IDENT, chip); | ||
1166 | |||
1167 | return 0; | ||
1168 | } | ||
1169 | |||
1170 | |||
1162 | static int vidioc_g_register(struct file *file, void *priv, | 1171 | static int vidioc_g_register(struct file *file, void *priv, |
1163 | struct v4l2_register *reg) | 1172 | struct v4l2_register *reg) |
1164 | { | 1173 | { |
@@ -1166,19 +1175,43 @@ static int vidioc_g_register(struct file *file, void *priv, | |||
1166 | struct em28xx *dev = fh->dev; | 1175 | struct em28xx *dev = fh->dev; |
1167 | int ret; | 1176 | int ret; |
1168 | 1177 | ||
1169 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | 1178 | switch (reg->match_type) { |
1179 | case V4L2_CHIP_MATCH_AC97: | ||
1180 | mutex_lock(&dev->lock); | ||
1181 | ret = em28xx_read_ac97(dev, reg->reg); | ||
1182 | mutex_unlock(&dev->lock); | ||
1183 | if (ret < 0) | ||
1184 | return ret; | ||
1185 | |||
1186 | reg->val = ret; | ||
1187 | return 0; | ||
1188 | case V4L2_CHIP_MATCH_I2C_DRIVER: | ||
1189 | em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_REGISTER, reg); | ||
1190 | return 0; | ||
1191 | case V4L2_CHIP_MATCH_I2C_ADDR: | ||
1192 | /* Not supported yet */ | ||
1170 | return -EINVAL; | 1193 | return -EINVAL; |
1194 | default: | ||
1195 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | ||
1196 | return -EINVAL; | ||
1197 | } | ||
1171 | 1198 | ||
1199 | /* Match host */ | ||
1172 | if (em28xx_reg_len(reg->reg) == 1) { | 1200 | if (em28xx_reg_len(reg->reg) == 1) { |
1201 | mutex_lock(&dev->lock); | ||
1173 | ret = em28xx_read_reg(dev, reg->reg); | 1202 | ret = em28xx_read_reg(dev, reg->reg); |
1203 | mutex_unlock(&dev->lock); | ||
1204 | |||
1174 | if (ret < 0) | 1205 | if (ret < 0) |
1175 | return ret; | 1206 | return ret; |
1176 | 1207 | ||
1177 | reg->val = ret; | 1208 | reg->val = ret; |
1178 | } else { | 1209 | } else { |
1179 | __le64 val = 0; | 1210 | __le64 val = 0; |
1211 | mutex_lock(&dev->lock); | ||
1180 | ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, | 1212 | ret = em28xx_read_reg_req_len(dev, USB_REQ_GET_STATUS, |
1181 | reg->reg, (char *)&val, 2); | 1213 | reg->reg, (char *)&val, 2); |
1214 | mutex_unlock(&dev->lock); | ||
1182 | if (ret < 0) | 1215 | if (ret < 0) |
1183 | return ret; | 1216 | return ret; |
1184 | 1217 | ||
@@ -1194,11 +1227,35 @@ static int vidioc_s_register(struct file *file, void *priv, | |||
1194 | struct em28xx_fh *fh = priv; | 1227 | struct em28xx_fh *fh = priv; |
1195 | struct em28xx *dev = fh->dev; | 1228 | struct em28xx *dev = fh->dev; |
1196 | __le64 buf; | 1229 | __le64 buf; |
1230 | int rc; | ||
1197 | 1231 | ||
1232 | switch (reg->match_type) { | ||
1233 | case V4L2_CHIP_MATCH_AC97: | ||
1234 | mutex_lock(&dev->lock); | ||
1235 | rc = em28xx_write_ac97(dev, reg->reg, reg->val); | ||
1236 | mutex_unlock(&dev->lock); | ||
1237 | |||
1238 | return rc; | ||
1239 | case V4L2_CHIP_MATCH_I2C_DRIVER: | ||
1240 | em28xx_i2c_call_clients(dev, VIDIOC_DBG_S_REGISTER, reg); | ||
1241 | return 0; | ||
1242 | case V4L2_CHIP_MATCH_I2C_ADDR: | ||
1243 | /* Not supported yet */ | ||
1244 | return -EINVAL; | ||
1245 | default: | ||
1246 | if (!v4l2_chip_match_host(reg->match_type, reg->match_chip)) | ||
1247 | return -EINVAL; | ||
1248 | } | ||
1249 | |||
1250 | /* Match host */ | ||
1198 | buf = cpu_to_le64(reg->val); | 1251 | buf = cpu_to_le64(reg->val); |
1199 | 1252 | ||
1200 | return em28xx_write_regs(dev, reg->reg, (char *)&buf, | 1253 | mutex_lock(&dev->lock); |
1201 | em28xx_reg_len(reg->reg)); | 1254 | rc = em28xx_write_regs(dev, reg->reg, (char *)&buf, |
1255 | em28xx_reg_len(reg->reg)); | ||
1256 | mutex_unlock(&dev->lock); | ||
1257 | |||
1258 | return rc; | ||
1202 | } | 1259 | } |
1203 | #endif | 1260 | #endif |
1204 | 1261 | ||
@@ -1235,10 +1292,15 @@ static int vidioc_streamon(struct file *file, void *priv, | |||
1235 | return rc; | 1292 | return rc; |
1236 | 1293 | ||
1237 | 1294 | ||
1238 | if (unlikely(res_get(fh) < 0)) | 1295 | mutex_lock(&dev->lock); |
1239 | return -EBUSY; | 1296 | rc = res_get(fh); |
1297 | |||
1298 | if (likely(rc >= 0)) | ||
1299 | rc = videobuf_streamon(&fh->vb_vidq); | ||
1240 | 1300 | ||
1241 | return (videobuf_streamon(&fh->vb_vidq)); | 1301 | mutex_unlock(&dev->lock); |
1302 | |||
1303 | return rc; | ||
1242 | } | 1304 | } |
1243 | 1305 | ||
1244 | static int vidioc_streamoff(struct file *file, void *priv, | 1306 | static int vidioc_streamoff(struct file *file, void *priv, |
@@ -1257,9 +1319,13 @@ static int vidioc_streamoff(struct file *file, void *priv, | |||
1257 | if (type != fh->type) | 1319 | if (type != fh->type) |
1258 | return -EINVAL; | 1320 | return -EINVAL; |
1259 | 1321 | ||
1322 | mutex_lock(&dev->lock); | ||
1323 | |||
1260 | videobuf_streamoff(&fh->vb_vidq); | 1324 | videobuf_streamoff(&fh->vb_vidq); |
1261 | res_free(fh); | 1325 | res_free(fh); |
1262 | 1326 | ||
1327 | mutex_unlock(&dev->lock); | ||
1328 | |||
1263 | return 0; | 1329 | return 0; |
1264 | } | 1330 | } |
1265 | 1331 | ||
@@ -1271,7 +1337,7 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
1271 | 1337 | ||
1272 | strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); | 1338 | strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); |
1273 | strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); | 1339 | strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); |
1274 | strlcpy(cap->bus_info, dev->udev->dev.bus_id, sizeof(cap->bus_info)); | 1340 | strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); |
1275 | 1341 | ||
1276 | cap->version = EM28XX_VERSION_CODE; | 1342 | cap->version = EM28XX_VERSION_CODE; |
1277 | 1343 | ||
@@ -1288,15 +1354,13 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
1288 | } | 1354 | } |
1289 | 1355 | ||
1290 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, | 1356 | static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, |
1291 | struct v4l2_fmtdesc *fmtd) | 1357 | struct v4l2_fmtdesc *f) |
1292 | { | 1358 | { |
1293 | if (fmtd->index != 0) | 1359 | if (unlikely(f->index >= ARRAY_SIZE(format))) |
1294 | return -EINVAL; | 1360 | return -EINVAL; |
1295 | 1361 | ||
1296 | fmtd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 1362 | strlcpy(f->description, format[f->index].name, sizeof(f->description)); |
1297 | strcpy(fmtd->description, "Packed YUY2"); | 1363 | f->pixelformat = format[f->index].fourcc; |
1298 | fmtd->pixelformat = V4L2_PIX_FMT_YUYV; | ||
1299 | memset(fmtd->reserved, 0, sizeof(fmtd->reserved)); | ||
1300 | 1364 | ||
1301 | return 0; | 1365 | return 0; |
1302 | } | 1366 | } |
@@ -1424,7 +1488,7 @@ static int radio_querycap(struct file *file, void *priv, | |||
1424 | 1488 | ||
1425 | strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); | 1489 | strlcpy(cap->driver, "em28xx", sizeof(cap->driver)); |
1426 | strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); | 1490 | strlcpy(cap->card, em28xx_boards[dev->model].name, sizeof(cap->card)); |
1427 | strlcpy(cap->bus_info, dev->udev->dev.bus_id, sizeof(cap->bus_info)); | 1491 | strlcpy(cap->bus_info, dev_name(&dev->udev->dev), sizeof(cap->bus_info)); |
1428 | 1492 | ||
1429 | cap->version = EM28XX_VERSION_CODE; | 1493 | cap->version = EM28XX_VERSION_CODE; |
1430 | cap->capabilities = V4L2_CAP_TUNER; | 1494 | cap->capabilities = V4L2_CAP_TUNER; |
@@ -1442,7 +1506,10 @@ static int radio_g_tuner(struct file *file, void *priv, | |||
1442 | strcpy(t->name, "Radio"); | 1506 | strcpy(t->name, "Radio"); |
1443 | t->type = V4L2_TUNER_RADIO; | 1507 | t->type = V4L2_TUNER_RADIO; |
1444 | 1508 | ||
1509 | mutex_lock(&dev->lock); | ||
1445 | em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t); | 1510 | em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t); |
1511 | mutex_unlock(&dev->lock); | ||
1512 | |||
1446 | return 0; | 1513 | return 0; |
1447 | } | 1514 | } |
1448 | 1515 | ||
@@ -1474,7 +1541,9 @@ static int radio_s_tuner(struct file *file, void *priv, | |||
1474 | if (0 != t->index) | 1541 | if (0 != t->index) |
1475 | return -EINVAL; | 1542 | return -EINVAL; |
1476 | 1543 | ||
1544 | mutex_lock(&dev->lock); | ||
1477 | em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t); | 1545 | em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t); |
1546 | mutex_unlock(&dev->lock); | ||
1478 | 1547 | ||
1479 | return 0; | 1548 | return 0; |
1480 | } | 1549 | } |
@@ -1516,28 +1585,13 @@ static int radio_queryctrl(struct file *file, void *priv, | |||
1516 | static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | 1585 | static int em28xx_v4l2_open(struct inode *inode, struct file *filp) |
1517 | { | 1586 | { |
1518 | int minor = iminor(inode); | 1587 | int minor = iminor(inode); |
1519 | int errCode = 0, radio = 0; | 1588 | int errCode = 0, radio; |
1520 | struct em28xx *h, *dev = NULL; | 1589 | struct em28xx *dev; |
1590 | enum v4l2_buf_type fh_type; | ||
1521 | struct em28xx_fh *fh; | 1591 | struct em28xx_fh *fh; |
1522 | enum v4l2_buf_type fh_type = 0; | ||
1523 | 1592 | ||
1524 | mutex_lock(&em28xx_devlist_mutex); | 1593 | dev = em28xx_get_device(inode, &fh_type, &radio); |
1525 | list_for_each_entry(h, &em28xx_devlist, devlist) { | 1594 | |
1526 | if (h->vdev->minor == minor) { | ||
1527 | dev = h; | ||
1528 | fh_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | ||
1529 | } | ||
1530 | if (h->vbi_dev->minor == minor) { | ||
1531 | dev = h; | ||
1532 | fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; | ||
1533 | } | ||
1534 | if (h->radio_dev && | ||
1535 | h->radio_dev->minor == minor) { | ||
1536 | radio = 1; | ||
1537 | dev = h; | ||
1538 | } | ||
1539 | } | ||
1540 | mutex_unlock(&em28xx_devlist_mutex); | ||
1541 | if (NULL == dev) | 1595 | if (NULL == dev) |
1542 | return -ENODEV; | 1596 | return -ENODEV; |
1543 | 1597 | ||
@@ -1571,7 +1625,7 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1571 | /* Needed, since GPIO might have disabled power of | 1625 | /* Needed, since GPIO might have disabled power of |
1572 | some i2c device | 1626 | some i2c device |
1573 | */ | 1627 | */ |
1574 | em28xx_config_i2c(dev); | 1628 | em28xx_wake_i2c(dev); |
1575 | 1629 | ||
1576 | } | 1630 | } |
1577 | if (fh->radio) { | 1631 | if (fh->radio) { |
@@ -1595,16 +1649,11 @@ static int em28xx_v4l2_open(struct inode *inode, struct file *filp) | |||
1595 | * unregisters the v4l2,i2c and usb devices | 1649 | * unregisters the v4l2,i2c and usb devices |
1596 | * called when the device gets disconected or at module unload | 1650 | * called when the device gets disconected or at module unload |
1597 | */ | 1651 | */ |
1598 | static void em28xx_release_resources(struct em28xx *dev) | 1652 | void em28xx_release_analog_resources(struct em28xx *dev) |
1599 | { | 1653 | { |
1600 | 1654 | ||
1601 | /*FIXME: I2C IR should be disconnected */ | 1655 | /*FIXME: I2C IR should be disconnected */ |
1602 | 1656 | ||
1603 | em28xx_info("V4L2 devices /dev/video%d and /dev/vbi%d deregistered\n", | ||
1604 | dev->vdev->num, dev->vbi_dev->num); | ||
1605 | list_del(&dev->devlist); | ||
1606 | if (dev->sbutton_input_dev) | ||
1607 | em28xx_deregister_snapshot_button(dev); | ||
1608 | if (dev->radio_dev) { | 1657 | if (dev->radio_dev) { |
1609 | if (-1 != dev->radio_dev->minor) | 1658 | if (-1 != dev->radio_dev->minor) |
1610 | video_unregister_device(dev->radio_dev); | 1659 | video_unregister_device(dev->radio_dev); |
@@ -1613,6 +1662,8 @@ static void em28xx_release_resources(struct em28xx *dev) | |||
1613 | dev->radio_dev = NULL; | 1662 | dev->radio_dev = NULL; |
1614 | } | 1663 | } |
1615 | if (dev->vbi_dev) { | 1664 | if (dev->vbi_dev) { |
1665 | em28xx_info("V4L2 device /dev/vbi%d deregistered\n", | ||
1666 | dev->vbi_dev->num); | ||
1616 | if (-1 != dev->vbi_dev->minor) | 1667 | if (-1 != dev->vbi_dev->minor) |
1617 | video_unregister_device(dev->vbi_dev); | 1668 | video_unregister_device(dev->vbi_dev); |
1618 | else | 1669 | else |
@@ -1620,17 +1671,14 @@ static void em28xx_release_resources(struct em28xx *dev) | |||
1620 | dev->vbi_dev = NULL; | 1671 | dev->vbi_dev = NULL; |
1621 | } | 1672 | } |
1622 | if (dev->vdev) { | 1673 | if (dev->vdev) { |
1674 | em28xx_info("V4L2 device /dev/video%d deregistered\n", | ||
1675 | dev->vdev->num); | ||
1623 | if (-1 != dev->vdev->minor) | 1676 | if (-1 != dev->vdev->minor) |
1624 | video_unregister_device(dev->vdev); | 1677 | video_unregister_device(dev->vdev); |
1625 | else | 1678 | else |
1626 | video_device_release(dev->vdev); | 1679 | video_device_release(dev->vdev); |
1627 | dev->vdev = NULL; | 1680 | dev->vdev = NULL; |
1628 | } | 1681 | } |
1629 | em28xx_i2c_unregister(dev); | ||
1630 | usb_put_dev(dev->udev); | ||
1631 | |||
1632 | /* Mark device as unused */ | ||
1633 | em28xx_devused &= ~(1<<dev->devno); | ||
1634 | } | 1682 | } |
1635 | 1683 | ||
1636 | /* | 1684 | /* |
@@ -1647,11 +1695,10 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) | |||
1647 | em28xx_videodbg("users=%d\n", dev->users); | 1695 | em28xx_videodbg("users=%d\n", dev->users); |
1648 | 1696 | ||
1649 | 1697 | ||
1698 | mutex_lock(&dev->lock); | ||
1650 | if (res_check(fh)) | 1699 | if (res_check(fh)) |
1651 | res_free(fh); | 1700 | res_free(fh); |
1652 | 1701 | ||
1653 | mutex_lock(&dev->lock); | ||
1654 | |||
1655 | if (dev->users == 1) { | 1702 | if (dev->users == 1) { |
1656 | videobuf_stop(&fh->vb_vidq); | 1703 | videobuf_stop(&fh->vb_vidq); |
1657 | videobuf_mmap_free(&fh->vb_vidq); | 1704 | videobuf_mmap_free(&fh->vb_vidq); |
@@ -1665,9 +1712,12 @@ static int em28xx_v4l2_close(struct inode *inode, struct file *filp) | |||
1665 | return 0; | 1712 | return 0; |
1666 | } | 1713 | } |
1667 | 1714 | ||
1715 | /* Save some power by putting tuner to sleep */ | ||
1716 | em28xx_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL); | ||
1717 | |||
1668 | /* do this before setting alternate! */ | 1718 | /* do this before setting alternate! */ |
1669 | em28xx_uninit_isoc(dev); | 1719 | em28xx_uninit_isoc(dev); |
1670 | em28xx_set_mode(dev, EM28XX_MODE_UNDEFINED); | 1720 | em28xx_set_mode(dev, EM28XX_SUSPEND); |
1671 | 1721 | ||
1672 | /* set alternate 0 */ | 1722 | /* set alternate 0 */ |
1673 | dev->alt = 0; | 1723 | dev->alt = 0; |
@@ -1706,8 +1756,12 @@ em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count, | |||
1706 | */ | 1756 | */ |
1707 | 1757 | ||
1708 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { | 1758 | if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
1709 | if (unlikely(res_get(fh))) | 1759 | mutex_lock(&dev->lock); |
1710 | return -EBUSY; | 1760 | rc = res_get(fh); |
1761 | mutex_unlock(&dev->lock); | ||
1762 | |||
1763 | if (unlikely(rc < 0)) | ||
1764 | return rc; | ||
1711 | 1765 | ||
1712 | return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, | 1766 | return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, |
1713 | filp->f_flags & O_NONBLOCK); | 1767 | filp->f_flags & O_NONBLOCK); |
@@ -1729,7 +1783,11 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table * wait) | |||
1729 | if (rc < 0) | 1783 | if (rc < 0) |
1730 | return rc; | 1784 | return rc; |
1731 | 1785 | ||
1732 | if (unlikely(res_get(fh) < 0)) | 1786 | mutex_lock(&dev->lock); |
1787 | rc = res_get(fh); | ||
1788 | mutex_unlock(&dev->lock); | ||
1789 | |||
1790 | if (unlikely(rc < 0)) | ||
1733 | return POLLERR; | 1791 | return POLLERR; |
1734 | 1792 | ||
1735 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) | 1793 | if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) |
@@ -1747,13 +1805,17 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma) | |||
1747 | struct em28xx *dev = fh->dev; | 1805 | struct em28xx *dev = fh->dev; |
1748 | int rc; | 1806 | int rc; |
1749 | 1807 | ||
1750 | if (unlikely(res_get(fh) < 0)) | ||
1751 | return -EBUSY; | ||
1752 | |||
1753 | rc = check_dev(dev); | 1808 | rc = check_dev(dev); |
1754 | if (rc < 0) | 1809 | if (rc < 0) |
1755 | return rc; | 1810 | return rc; |
1756 | 1811 | ||
1812 | mutex_lock(&dev->lock); | ||
1813 | rc = res_get(fh); | ||
1814 | mutex_unlock(&dev->lock); | ||
1815 | |||
1816 | if (unlikely(rc < 0)) | ||
1817 | return rc; | ||
1818 | |||
1757 | rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); | 1819 | rc = videobuf_mmap_mapper(&fh->vb_vidq, vma); |
1758 | 1820 | ||
1759 | em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n", | 1821 | em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n", |
@@ -1810,6 +1872,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { | |||
1810 | #ifdef CONFIG_VIDEO_ADV_DEBUG | 1872 | #ifdef CONFIG_VIDEO_ADV_DEBUG |
1811 | .vidioc_g_register = vidioc_g_register, | 1873 | .vidioc_g_register = vidioc_g_register, |
1812 | .vidioc_s_register = vidioc_s_register, | 1874 | .vidioc_s_register = vidioc_s_register, |
1875 | .vidioc_g_chip_ident = vidioc_g_chip_ident, | ||
1813 | #endif | 1876 | #endif |
1814 | #ifdef CONFIG_VIDEO_V4L1_COMPAT | 1877 | #ifdef CONFIG_VIDEO_V4L1_COMPAT |
1815 | .vidiocgmbuf = vidiocgmbuf, | 1878 | .vidiocgmbuf = vidiocgmbuf, |
@@ -1865,44 +1928,6 @@ static struct video_device em28xx_radio_template = { | |||
1865 | /******************************** usb interface ******************************/ | 1928 | /******************************** usb interface ******************************/ |
1866 | 1929 | ||
1867 | 1930 | ||
1868 | static LIST_HEAD(em28xx_extension_devlist); | ||
1869 | static DEFINE_MUTEX(em28xx_extension_devlist_lock); | ||
1870 | |||
1871 | int em28xx_register_extension(struct em28xx_ops *ops) | ||
1872 | { | ||
1873 | struct em28xx *dev = NULL; | ||
1874 | |||
1875 | mutex_lock(&em28xx_devlist_mutex); | ||
1876 | mutex_lock(&em28xx_extension_devlist_lock); | ||
1877 | list_add_tail(&ops->next, &em28xx_extension_devlist); | ||
1878 | list_for_each_entry(dev, &em28xx_devlist, devlist) { | ||
1879 | if (dev) | ||
1880 | ops->init(dev); | ||
1881 | } | ||
1882 | printk(KERN_INFO "Em28xx: Initialized (%s) extension\n", ops->name); | ||
1883 | mutex_unlock(&em28xx_extension_devlist_lock); | ||
1884 | mutex_unlock(&em28xx_devlist_mutex); | ||
1885 | return 0; | ||
1886 | } | ||
1887 | EXPORT_SYMBOL(em28xx_register_extension); | ||
1888 | |||
1889 | void em28xx_unregister_extension(struct em28xx_ops *ops) | ||
1890 | { | ||
1891 | struct em28xx *dev = NULL; | ||
1892 | |||
1893 | mutex_lock(&em28xx_devlist_mutex); | ||
1894 | list_for_each_entry(dev, &em28xx_devlist, devlist) { | ||
1895 | if (dev) | ||
1896 | ops->fini(dev); | ||
1897 | } | ||
1898 | |||
1899 | mutex_lock(&em28xx_extension_devlist_lock); | ||
1900 | printk(KERN_INFO "Em28xx: Removed (%s) extension\n", ops->name); | ||
1901 | list_del(&ops->next); | ||
1902 | mutex_unlock(&em28xx_extension_devlist_lock); | ||
1903 | mutex_unlock(&em28xx_devlist_mutex); | ||
1904 | } | ||
1905 | EXPORT_SYMBOL(em28xx_unregister_extension); | ||
1906 | 1931 | ||
1907 | static struct video_device *em28xx_vdev_init(struct em28xx *dev, | 1932 | static struct video_device *em28xx_vdev_init(struct em28xx *dev, |
1908 | const struct video_device *template, | 1933 | const struct video_device *template, |
@@ -1925,11 +1950,43 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev, | |||
1925 | return vfd; | 1950 | return vfd; |
1926 | } | 1951 | } |
1927 | 1952 | ||
1928 | 1953 | int em28xx_register_analog_devices(struct em28xx *dev) | |
1929 | static int register_analog_devices(struct em28xx *dev) | ||
1930 | { | 1954 | { |
1931 | int ret; | 1955 | int ret; |
1932 | 1956 | ||
1957 | printk(KERN_INFO "%s: v4l2 driver version %d.%d.%d\n", | ||
1958 | dev->name, | ||
1959 | (EM28XX_VERSION_CODE >> 16) & 0xff, | ||
1960 | (EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff); | ||
1961 | |||
1962 | /* Analog specific initialization */ | ||
1963 | dev->format = &format[0]; | ||
1964 | video_mux(dev, 0); | ||
1965 | |||
1966 | /* enable vbi capturing */ | ||
1967 | |||
1968 | /* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */ | ||
1969 | /* em28xx_write_reg(dev, EM28XX_R0F_XCLK, 0x80); clk register */ | ||
1970 | em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51); | ||
1971 | |||
1972 | dev->mute = 1; /* maybe not the right place... */ | ||
1973 | dev->volume = 0x1f; | ||
1974 | |||
1975 | em28xx_set_outfmt(dev); | ||
1976 | em28xx_colorlevels_set_default(dev); | ||
1977 | em28xx_compression_disable(dev); | ||
1978 | |||
1979 | /* set default norm */ | ||
1980 | dev->norm = em28xx_video_template.current_norm; | ||
1981 | dev->width = norm_maxw(dev); | ||
1982 | dev->height = norm_maxh(dev); | ||
1983 | dev->interlaced = EM28XX_INTERLACED_DEFAULT; | ||
1984 | dev->hscale = 0; | ||
1985 | dev->vscale = 0; | ||
1986 | |||
1987 | /* FIXME: This is a very bad hack! Not all devices have TV on input 2 */ | ||
1988 | dev->ctl_input = 2; | ||
1989 | |||
1933 | /* allocate and fill video video_device struct */ | 1990 | /* allocate and fill video video_device struct */ |
1934 | dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); | 1991 | dev->vdev = em28xx_vdev_init(dev, &em28xx_video_template, "video"); |
1935 | if (!dev->vdev) { | 1992 | if (!dev->vdev) { |
@@ -1978,383 +2035,3 @@ static int register_analog_devices(struct em28xx *dev) | |||
1978 | 2035 | ||
1979 | return 0; | 2036 | return 0; |
1980 | } | 2037 | } |
1981 | |||
1982 | |||
1983 | /* | ||
1984 | * em28xx_init_dev() | ||
1985 | * allocates and inits the device structs, registers i2c bus and v4l device | ||
1986 | */ | ||
1987 | static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev, | ||
1988 | int minor) | ||
1989 | { | ||
1990 | struct em28xx_ops *ops = NULL; | ||
1991 | struct em28xx *dev = *devhandle; | ||
1992 | int retval = -ENOMEM; | ||
1993 | int errCode; | ||
1994 | unsigned int maxh, maxw; | ||
1995 | |||
1996 | dev->udev = udev; | ||
1997 | mutex_init(&dev->lock); | ||
1998 | mutex_init(&dev->ctrl_urb_lock); | ||
1999 | spin_lock_init(&dev->slock); | ||
2000 | init_waitqueue_head(&dev->open); | ||
2001 | init_waitqueue_head(&dev->wait_frame); | ||
2002 | init_waitqueue_head(&dev->wait_stream); | ||
2003 | |||
2004 | dev->em28xx_write_regs = em28xx_write_regs; | ||
2005 | dev->em28xx_read_reg = em28xx_read_reg; | ||
2006 | dev->em28xx_read_reg_req_len = em28xx_read_reg_req_len; | ||
2007 | dev->em28xx_write_regs_req = em28xx_write_regs_req; | ||
2008 | dev->em28xx_read_reg_req = em28xx_read_reg_req; | ||
2009 | dev->is_em2800 = em28xx_boards[dev->model].is_em2800; | ||
2010 | |||
2011 | em28xx_pre_card_setup(dev); | ||
2012 | |||
2013 | errCode = em28xx_config(dev); | ||
2014 | if (errCode) { | ||
2015 | em28xx_errdev("error configuring device\n"); | ||
2016 | return -ENOMEM; | ||
2017 | } | ||
2018 | |||
2019 | /* register i2c bus */ | ||
2020 | errCode = em28xx_i2c_register(dev); | ||
2021 | if (errCode < 0) { | ||
2022 | em28xx_errdev("%s: em28xx_i2c_register - errCode [%d]!\n", | ||
2023 | __func__, errCode); | ||
2024 | return errCode; | ||
2025 | } | ||
2026 | |||
2027 | /* Do board specific init and eeprom reading */ | ||
2028 | em28xx_card_setup(dev); | ||
2029 | |||
2030 | /* Configure audio */ | ||
2031 | errCode = em28xx_audio_analog_set(dev); | ||
2032 | if (errCode < 0) { | ||
2033 | em28xx_errdev("%s: em28xx_audio_analog_set - errCode [%d]!\n", | ||
2034 | __func__, errCode); | ||
2035 | return errCode; | ||
2036 | } | ||
2037 | |||
2038 | /* configure the device */ | ||
2039 | em28xx_config_i2c(dev); | ||
2040 | |||
2041 | /* set default norm */ | ||
2042 | dev->norm = em28xx_video_template.current_norm; | ||
2043 | |||
2044 | maxw = norm_maxw(dev); | ||
2045 | maxh = norm_maxh(dev); | ||
2046 | |||
2047 | /* set default image size */ | ||
2048 | dev->width = maxw; | ||
2049 | dev->height = maxh; | ||
2050 | dev->interlaced = EM28XX_INTERLACED_DEFAULT; | ||
2051 | dev->hscale = 0; | ||
2052 | dev->vscale = 0; | ||
2053 | dev->ctl_input = 2; | ||
2054 | |||
2055 | errCode = em28xx_config(dev); | ||
2056 | if (errCode < 0) { | ||
2057 | em28xx_errdev("%s: em28xx_config - errCode [%d]!\n", | ||
2058 | __func__, errCode); | ||
2059 | return errCode; | ||
2060 | } | ||
2061 | |||
2062 | /* init video dma queues */ | ||
2063 | INIT_LIST_HEAD(&dev->vidq.active); | ||
2064 | INIT_LIST_HEAD(&dev->vidq.queued); | ||
2065 | |||
2066 | |||
2067 | if (dev->has_msp34xx) { | ||
2068 | /* Send a reset to other chips via gpio */ | ||
2069 | errCode = em28xx_write_regs_req(dev, 0x00, 0x08, "\xf7", 1); | ||
2070 | if (errCode < 0) { | ||
2071 | em28xx_errdev("%s: em28xx_write_regs_req - msp34xx(1) failed! errCode [%d]\n", | ||
2072 | __func__, errCode); | ||
2073 | return errCode; | ||
2074 | } | ||
2075 | msleep(3); | ||
2076 | |||
2077 | errCode = em28xx_write_regs_req(dev, 0x00, 0x08, "\xff", 1); | ||
2078 | if (errCode < 0) { | ||
2079 | em28xx_errdev("%s: em28xx_write_regs_req - msp34xx(2) failed! errCode [%d]\n", | ||
2080 | __func__, errCode); | ||
2081 | return errCode; | ||
2082 | } | ||
2083 | msleep(3); | ||
2084 | } | ||
2085 | |||
2086 | video_mux(dev, 0); | ||
2087 | |||
2088 | mutex_lock(&em28xx_devlist_mutex); | ||
2089 | list_add_tail(&dev->devlist, &em28xx_devlist); | ||
2090 | retval = register_analog_devices(dev); | ||
2091 | if (retval < 0) { | ||
2092 | em28xx_release_resources(dev); | ||
2093 | mutex_unlock(&em28xx_devlist_mutex); | ||
2094 | goto fail_reg_devices; | ||
2095 | } | ||
2096 | |||
2097 | mutex_lock(&em28xx_extension_devlist_lock); | ||
2098 | if (!list_empty(&em28xx_extension_devlist)) { | ||
2099 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { | ||
2100 | if (ops->id) | ||
2101 | ops->init(dev); | ||
2102 | } | ||
2103 | } | ||
2104 | mutex_unlock(&em28xx_extension_devlist_lock); | ||
2105 | mutex_unlock(&em28xx_devlist_mutex); | ||
2106 | |||
2107 | return 0; | ||
2108 | |||
2109 | fail_reg_devices: | ||
2110 | mutex_unlock(&dev->lock); | ||
2111 | return retval; | ||
2112 | } | ||
2113 | |||
2114 | #if defined(CONFIG_MODULES) && defined(MODULE) | ||
2115 | static void request_module_async(struct work_struct *work) | ||
2116 | { | ||
2117 | struct em28xx *dev = container_of(work, | ||
2118 | struct em28xx, request_module_wk); | ||
2119 | |||
2120 | if (dev->has_audio_class) | ||
2121 | request_module("snd-usb-audio"); | ||
2122 | else | ||
2123 | request_module("em28xx-alsa"); | ||
2124 | |||
2125 | if (dev->has_dvb) | ||
2126 | request_module("em28xx-dvb"); | ||
2127 | } | ||
2128 | |||
2129 | static void request_modules(struct em28xx *dev) | ||
2130 | { | ||
2131 | INIT_WORK(&dev->request_module_wk, request_module_async); | ||
2132 | schedule_work(&dev->request_module_wk); | ||
2133 | } | ||
2134 | #else | ||
2135 | #define request_modules(dev) | ||
2136 | #endif /* CONFIG_MODULES */ | ||
2137 | |||
2138 | /* | ||
2139 | * em28xx_usb_probe() | ||
2140 | * checks for supported devices | ||
2141 | */ | ||
2142 | static int em28xx_usb_probe(struct usb_interface *interface, | ||
2143 | const struct usb_device_id *id) | ||
2144 | { | ||
2145 | const struct usb_endpoint_descriptor *endpoint; | ||
2146 | struct usb_device *udev; | ||
2147 | struct usb_interface *uif; | ||
2148 | struct em28xx *dev = NULL; | ||
2149 | int retval = -ENODEV; | ||
2150 | int i, nr, ifnum; | ||
2151 | |||
2152 | udev = usb_get_dev(interface_to_usbdev(interface)); | ||
2153 | ifnum = interface->altsetting[0].desc.bInterfaceNumber; | ||
2154 | |||
2155 | /* Check to see next free device and mark as used */ | ||
2156 | nr = find_first_zero_bit(&em28xx_devused, EM28XX_MAXBOARDS); | ||
2157 | em28xx_devused |= 1<<nr; | ||
2158 | |||
2159 | /* Don't register audio interfaces */ | ||
2160 | if (interface->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { | ||
2161 | em28xx_err(DRIVER_NAME " audio device (%04x:%04x): interface %i, class %i\n", | ||
2162 | udev->descriptor.idVendor, | ||
2163 | udev->descriptor.idProduct, | ||
2164 | ifnum, | ||
2165 | interface->altsetting[0].desc.bInterfaceClass); | ||
2166 | |||
2167 | em28xx_devused &= ~(1<<nr); | ||
2168 | return -ENODEV; | ||
2169 | } | ||
2170 | |||
2171 | em28xx_err(DRIVER_NAME " new video device (%04x:%04x): interface %i, class %i\n", | ||
2172 | udev->descriptor.idVendor, | ||
2173 | udev->descriptor.idProduct, | ||
2174 | ifnum, | ||
2175 | interface->altsetting[0].desc.bInterfaceClass); | ||
2176 | |||
2177 | endpoint = &interface->cur_altsetting->endpoint[1].desc; | ||
2178 | |||
2179 | /* check if the device has the iso in endpoint at the correct place */ | ||
2180 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != | ||
2181 | USB_ENDPOINT_XFER_ISOC) { | ||
2182 | em28xx_err(DRIVER_NAME " probing error: endpoint is non-ISO endpoint!\n"); | ||
2183 | em28xx_devused &= ~(1<<nr); | ||
2184 | return -ENODEV; | ||
2185 | } | ||
2186 | if ((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) { | ||
2187 | em28xx_err(DRIVER_NAME " probing error: endpoint is ISO OUT endpoint!\n"); | ||
2188 | em28xx_devused &= ~(1<<nr); | ||
2189 | return -ENODEV; | ||
2190 | } | ||
2191 | |||
2192 | if (nr >= EM28XX_MAXBOARDS) { | ||
2193 | printk(DRIVER_NAME ": Supports only %i em28xx boards.\n", | ||
2194 | EM28XX_MAXBOARDS); | ||
2195 | em28xx_devused &= ~(1<<nr); | ||
2196 | return -ENOMEM; | ||
2197 | } | ||
2198 | |||
2199 | /* allocate memory for our device state and initialize it */ | ||
2200 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
2201 | if (dev == NULL) { | ||
2202 | em28xx_err(DRIVER_NAME ": out of memory!\n"); | ||
2203 | em28xx_devused &= ~(1<<nr); | ||
2204 | return -ENOMEM; | ||
2205 | } | ||
2206 | |||
2207 | snprintf(dev->name, 29, "em28xx #%d", nr); | ||
2208 | dev->devno = nr; | ||
2209 | dev->model = id->driver_info; | ||
2210 | dev->alt = -1; | ||
2211 | |||
2212 | /* Checks if audio is provided by some interface */ | ||
2213 | for (i = 0; i < udev->config->desc.bNumInterfaces; i++) { | ||
2214 | uif = udev->config->interface[i]; | ||
2215 | if (uif->altsetting[0].desc.bInterfaceClass == USB_CLASS_AUDIO) { | ||
2216 | dev->has_audio_class = 1; | ||
2217 | break; | ||
2218 | } | ||
2219 | } | ||
2220 | |||
2221 | printk(KERN_INFO DRIVER_NAME " %s usb audio class\n", | ||
2222 | dev->has_audio_class ? "Has" : "Doesn't have"); | ||
2223 | |||
2224 | /* compute alternate max packet sizes */ | ||
2225 | uif = udev->actconfig->interface[0]; | ||
2226 | |||
2227 | dev->num_alt = uif->num_altsetting; | ||
2228 | em28xx_info("Alternate settings: %i\n", dev->num_alt); | ||
2229 | /* dev->alt_max_pkt_size = kmalloc(sizeof(*dev->alt_max_pkt_size)* */ | ||
2230 | dev->alt_max_pkt_size = kmalloc(32 * dev->num_alt, GFP_KERNEL); | ||
2231 | |||
2232 | if (dev->alt_max_pkt_size == NULL) { | ||
2233 | em28xx_errdev("out of memory!\n"); | ||
2234 | em28xx_devused &= ~(1<<nr); | ||
2235 | kfree(dev); | ||
2236 | return -ENOMEM; | ||
2237 | } | ||
2238 | |||
2239 | for (i = 0; i < dev->num_alt ; i++) { | ||
2240 | u16 tmp = le16_to_cpu(uif->altsetting[i].endpoint[1].desc. | ||
2241 | wMaxPacketSize); | ||
2242 | dev->alt_max_pkt_size[i] = | ||
2243 | (tmp & 0x07ff) * (((tmp & 0x1800) >> 11) + 1); | ||
2244 | em28xx_info("Alternate setting %i, max size= %i\n", i, | ||
2245 | dev->alt_max_pkt_size[i]); | ||
2246 | } | ||
2247 | |||
2248 | if ((card[nr] >= 0) && (card[nr] < em28xx_bcount)) | ||
2249 | dev->model = card[nr]; | ||
2250 | |||
2251 | /* allocate device struct */ | ||
2252 | retval = em28xx_init_dev(&dev, udev, nr); | ||
2253 | if (retval) { | ||
2254 | em28xx_devused &= ~(1<<dev->devno); | ||
2255 | kfree(dev); | ||
2256 | |||
2257 | return retval; | ||
2258 | } | ||
2259 | |||
2260 | em28xx_info("Found %s\n", em28xx_boards[dev->model].name); | ||
2261 | |||
2262 | /* save our data pointer in this interface device */ | ||
2263 | usb_set_intfdata(interface, dev); | ||
2264 | |||
2265 | request_modules(dev); | ||
2266 | |||
2267 | return 0; | ||
2268 | } | ||
2269 | |||
2270 | /* | ||
2271 | * em28xx_usb_disconnect() | ||
2272 | * called when the device gets diconencted | ||
2273 | * video device will be unregistered on v4l2_close in case it is still open | ||
2274 | */ | ||
2275 | static void em28xx_usb_disconnect(struct usb_interface *interface) | ||
2276 | { | ||
2277 | struct em28xx *dev; | ||
2278 | struct em28xx_ops *ops = NULL; | ||
2279 | |||
2280 | dev = usb_get_intfdata(interface); | ||
2281 | usb_set_intfdata(interface, NULL); | ||
2282 | |||
2283 | if (!dev) | ||
2284 | return; | ||
2285 | |||
2286 | em28xx_info("disconnecting %s\n", dev->vdev->name); | ||
2287 | |||
2288 | /* wait until all current v4l2 io is finished then deallocate | ||
2289 | resources */ | ||
2290 | mutex_lock(&dev->lock); | ||
2291 | |||
2292 | wake_up_interruptible_all(&dev->open); | ||
2293 | |||
2294 | if (dev->users) { | ||
2295 | em28xx_warn | ||
2296 | ("device /dev/video%d is open! Deregistration and memory " | ||
2297 | "deallocation are deferred on close.\n", | ||
2298 | dev->vdev->num); | ||
2299 | |||
2300 | dev->state |= DEV_MISCONFIGURED; | ||
2301 | em28xx_uninit_isoc(dev); | ||
2302 | dev->state |= DEV_DISCONNECTED; | ||
2303 | wake_up_interruptible(&dev->wait_frame); | ||
2304 | wake_up_interruptible(&dev->wait_stream); | ||
2305 | } else { | ||
2306 | dev->state |= DEV_DISCONNECTED; | ||
2307 | em28xx_release_resources(dev); | ||
2308 | } | ||
2309 | mutex_unlock(&dev->lock); | ||
2310 | |||
2311 | mutex_lock(&em28xx_extension_devlist_lock); | ||
2312 | if (!list_empty(&em28xx_extension_devlist)) { | ||
2313 | list_for_each_entry(ops, &em28xx_extension_devlist, next) { | ||
2314 | ops->fini(dev); | ||
2315 | } | ||
2316 | } | ||
2317 | mutex_unlock(&em28xx_extension_devlist_lock); | ||
2318 | |||
2319 | if (!dev->users) { | ||
2320 | kfree(dev->alt_max_pkt_size); | ||
2321 | kfree(dev); | ||
2322 | } | ||
2323 | } | ||
2324 | |||
2325 | static struct usb_driver em28xx_usb_driver = { | ||
2326 | .name = "em28xx", | ||
2327 | .probe = em28xx_usb_probe, | ||
2328 | .disconnect = em28xx_usb_disconnect, | ||
2329 | .id_table = em28xx_id_table, | ||
2330 | }; | ||
2331 | |||
2332 | static int __init em28xx_module_init(void) | ||
2333 | { | ||
2334 | int result; | ||
2335 | |||
2336 | printk(KERN_INFO DRIVER_NAME " v4l2 driver version %d.%d.%d loaded\n", | ||
2337 | (EM28XX_VERSION_CODE >> 16) & 0xff, | ||
2338 | (EM28XX_VERSION_CODE >> 8) & 0xff, EM28XX_VERSION_CODE & 0xff); | ||
2339 | #ifdef SNAPSHOT | ||
2340 | printk(KERN_INFO DRIVER_NAME " snapshot date %04d-%02d-%02d\n", | ||
2341 | SNAPSHOT / 10000, (SNAPSHOT / 100) % 100, SNAPSHOT % 100); | ||
2342 | #endif | ||
2343 | |||
2344 | /* register this driver with the USB subsystem */ | ||
2345 | result = usb_register(&em28xx_usb_driver); | ||
2346 | if (result) | ||
2347 | em28xx_err(DRIVER_NAME | ||
2348 | " usb_register failed. Error number %d.\n", result); | ||
2349 | |||
2350 | return result; | ||
2351 | } | ||
2352 | |||
2353 | static void __exit em28xx_module_exit(void) | ||
2354 | { | ||
2355 | /* deregister this driver with the USB subsystem */ | ||
2356 | usb_deregister(&em28xx_usb_driver); | ||
2357 | } | ||
2358 | |||
2359 | module_init(em28xx_module_init); | ||
2360 | module_exit(em28xx_module_exit); | ||
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h index 5956e9b3062f..b5eddc26388e 100644 --- a/drivers/media/video/em28xx/em28xx.h +++ b/drivers/media/video/em28xx/em28xx.h | |||
@@ -67,7 +67,6 @@ | |||
67 | #define EM2820_BOARD_HERCULES_SMART_TV_USB2 26 | 67 | #define EM2820_BOARD_HERCULES_SMART_TV_USB2 26 |
68 | #define EM2820_BOARD_PINNACLE_USB_2_FM1216ME 27 | 68 | #define EM2820_BOARD_PINNACLE_USB_2_FM1216ME 27 |
69 | #define EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE 28 | 69 | #define EM2820_BOARD_LEADTEK_WINFAST_USBII_DELUXE 28 |
70 | #define EM2820_BOARD_PINNACLE_DVC_100 29 | ||
71 | #define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30 | 70 | #define EM2820_BOARD_VIDEOLOGY_20K14XUSB 30 |
72 | #define EM2821_BOARD_USBGEAR_VD204 31 | 71 | #define EM2821_BOARD_USBGEAR_VD204 31 |
73 | #define EM2821_BOARD_SUPERCOMP_USB_2 32 | 72 | #define EM2821_BOARD_SUPERCOMP_USB_2 32 |
@@ -97,6 +96,8 @@ | |||
97 | #define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 | 96 | #define EM2882_BOARD_PINNACLE_HYBRID_PRO 56 |
98 | #define EM2883_BOARD_KWORLD_HYBRID_A316 57 | 97 | #define EM2883_BOARD_KWORLD_HYBRID_A316 57 |
99 | #define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58 | 98 | #define EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU 58 |
99 | #define EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850 60 | ||
100 | #define EM2820_BOARD_PROLINK_PLAYTV_BOX4_USB2 61 | ||
100 | 101 | ||
101 | /* Limits minimum and default number of buffers */ | 102 | /* Limits minimum and default number of buffers */ |
102 | #define EM28XX_MIN_BUF 4 | 103 | #define EM28XX_MIN_BUF 4 |
@@ -159,7 +160,7 @@ | |||
159 | #define EM2800_I2C_WRITE_TIMEOUT 20 | 160 | #define EM2800_I2C_WRITE_TIMEOUT 20 |
160 | 161 | ||
161 | enum em28xx_mode { | 162 | enum em28xx_mode { |
162 | EM28XX_MODE_UNDEFINED, | 163 | EM28XX_SUSPEND, |
163 | EM28XX_ANALOG_MODE, | 164 | EM28XX_ANALOG_MODE, |
164 | EM28XX_DIGITAL_MODE, | 165 | EM28XX_DIGITAL_MODE, |
165 | }; | 166 | }; |
@@ -207,9 +208,12 @@ struct em28xx_usb_isoc_ctl { | |||
207 | 208 | ||
208 | }; | 209 | }; |
209 | 210 | ||
211 | /* Struct to enumberate video formats */ | ||
210 | struct em28xx_fmt { | 212 | struct em28xx_fmt { |
211 | char *name; | 213 | char *name; |
212 | u32 fourcc; /* v4l2 format id */ | 214 | u32 fourcc; /* v4l2 format id */ |
215 | int depth; | ||
216 | int reg; | ||
213 | }; | 217 | }; |
214 | 218 | ||
215 | /* buffer for one video frame */ | 219 | /* buffer for one video frame */ |
@@ -255,54 +259,105 @@ enum enum28xx_itype { | |||
255 | EM28XX_RADIO, | 259 | EM28XX_RADIO, |
256 | }; | 260 | }; |
257 | 261 | ||
262 | enum em28xx_ac97_mode { | ||
263 | EM28XX_NO_AC97 = 0, | ||
264 | EM28XX_AC97_EM202, | ||
265 | EM28XX_AC97_SIGMATEL, | ||
266 | EM28XX_AC97_OTHER, | ||
267 | }; | ||
268 | |||
269 | struct em28xx_audio_mode { | ||
270 | enum em28xx_ac97_mode ac97; | ||
271 | |||
272 | u16 ac97_feat; | ||
273 | u32 ac97_vendor_id; | ||
274 | |||
275 | unsigned int has_audio:1; | ||
276 | |||
277 | unsigned int i2s_3rates:1; | ||
278 | unsigned int i2s_5rates:1; | ||
279 | }; | ||
280 | |||
281 | /* em28xx has two audio inputs: tuner and line in. | ||
282 | However, on most devices, an auxiliary AC97 codec device is used. | ||
283 | The AC97 device may have several different inputs and outputs, | ||
284 | depending on their model. So, it is possible to use AC97 mixer to | ||
285 | address more than two different entries. | ||
286 | */ | ||
258 | enum em28xx_amux { | 287 | enum em28xx_amux { |
259 | EM28XX_AMUX_VIDEO, | 288 | /* This is the only entry for em28xx tuner input */ |
260 | EM28XX_AMUX_LINE_IN, | 289 | EM28XX_AMUX_VIDEO, /* em28xx tuner, AC97 mixer Video */ |
261 | EM28XX_AMUX_AC97_VIDEO, | 290 | |
262 | EM28XX_AMUX_AC97_LINE_IN, | 291 | EM28XX_AMUX_LINE_IN, /* AC97 mixer Line In */ |
292 | |||
293 | /* Some less-common mixer setups */ | ||
294 | EM28XX_AMUX_VIDEO2, /* em28xx Line in, AC97 mixer Video */ | ||
295 | EM28XX_AMUX_PHONE, | ||
296 | EM28XX_AMUX_MIC, | ||
297 | EM28XX_AMUX_CD, | ||
298 | EM28XX_AMUX_AUX, | ||
299 | EM28XX_AMUX_PCM_OUT, | ||
300 | }; | ||
301 | |||
302 | enum em28xx_aout { | ||
303 | EM28XX_AOUT_MASTER = 1 << 0, | ||
304 | EM28XX_AOUT_LINE = 1 << 1, | ||
305 | EM28XX_AOUT_MONO = 1 << 2, | ||
306 | EM28XX_AOUT_LFE = 1 << 3, | ||
307 | EM28XX_AOUT_SURR = 1 << 4, | ||
308 | }; | ||
309 | |||
310 | struct em28xx_reg_seq { | ||
311 | int reg; | ||
312 | unsigned char val, mask; | ||
313 | int sleep; | ||
263 | }; | 314 | }; |
264 | 315 | ||
265 | struct em28xx_input { | 316 | struct em28xx_input { |
266 | enum enum28xx_itype type; | 317 | enum enum28xx_itype type; |
267 | unsigned int vmux; | 318 | unsigned int vmux; |
268 | enum em28xx_amux amux; | 319 | enum em28xx_amux amux; |
320 | enum em28xx_aout aout; | ||
321 | struct em28xx_reg_seq *gpio; | ||
269 | }; | 322 | }; |
270 | 323 | ||
271 | #define INPUT(nr) (&em28xx_boards[dev->model].input[nr]) | 324 | #define INPUT(nr) (&em28xx_boards[dev->model].input[nr]) |
272 | 325 | ||
273 | enum em28xx_decoder { | 326 | enum em28xx_decoder { |
327 | EM28XX_NODECODER, | ||
274 | EM28XX_TVP5150, | 328 | EM28XX_TVP5150, |
275 | EM28XX_SAA7113, | 329 | EM28XX_SAA711X, |
276 | EM28XX_SAA7114 | ||
277 | }; | ||
278 | |||
279 | struct em28xx_reg_seq { | ||
280 | int reg; | ||
281 | unsigned char val, mask; | ||
282 | int sleep; | ||
283 | }; | 330 | }; |
284 | 331 | ||
285 | struct em28xx_board { | 332 | struct em28xx_board { |
286 | char *name; | 333 | char *name; |
287 | int vchannels; | 334 | int vchannels; |
288 | int tuner_type; | 335 | int tuner_type; |
336 | int tuner_addr; | ||
289 | 337 | ||
290 | /* i2c flags */ | 338 | /* i2c flags */ |
291 | unsigned int tda9887_conf; | 339 | unsigned int tda9887_conf; |
292 | 340 | ||
341 | /* GPIO sequences */ | ||
342 | struct em28xx_reg_seq *dvb_gpio; | ||
343 | struct em28xx_reg_seq *suspend_gpio; | ||
344 | struct em28xx_reg_seq *tuner_gpio; | ||
345 | |||
293 | unsigned int is_em2800:1; | 346 | unsigned int is_em2800:1; |
294 | unsigned int has_msp34xx:1; | 347 | unsigned int has_msp34xx:1; |
295 | unsigned int mts_firmware:1; | 348 | unsigned int mts_firmware:1; |
296 | unsigned int has_12mhz_i2s:1; | ||
297 | unsigned int max_range_640_480:1; | 349 | unsigned int max_range_640_480:1; |
298 | unsigned int has_dvb:1; | 350 | unsigned int has_dvb:1; |
299 | unsigned int has_snapshot_button:1; | 351 | unsigned int has_snapshot_button:1; |
300 | unsigned int valid:1; | 352 | unsigned int valid:1; |
301 | 353 | ||
354 | unsigned char xclk, i2c_speed; | ||
355 | |||
302 | enum em28xx_decoder decoder; | 356 | enum em28xx_decoder decoder; |
303 | 357 | ||
304 | struct em28xx_input input[MAX_EM28XX_INPUT]; | 358 | struct em28xx_input input[MAX_EM28XX_INPUT]; |
305 | struct em28xx_input radio; | 359 | struct em28xx_input radio; |
360 | IR_KEYTAB_TYPE *ir_codes; | ||
306 | }; | 361 | }; |
307 | 362 | ||
308 | struct em28xx_eeprom { | 363 | struct em28xx_eeprom { |
@@ -369,32 +424,26 @@ struct em28xx { | |||
369 | char name[30]; /* name (including minor) of the device */ | 424 | char name[30]; /* name (including minor) of the device */ |
370 | int model; /* index in the device_data struct */ | 425 | int model; /* index in the device_data struct */ |
371 | int devno; /* marks the number of this device */ | 426 | int devno; /* marks the number of this device */ |
372 | unsigned int is_em2800:1; | 427 | enum em28xx_chip_id chip_id; |
373 | unsigned int has_msp34xx:1; | 428 | |
374 | unsigned int has_tda9887:1; | 429 | struct em28xx_board board; |
430 | |||
375 | unsigned int stream_on:1; /* Locks streams */ | 431 | unsigned int stream_on:1; /* Locks streams */ |
376 | unsigned int has_audio_class:1; | 432 | unsigned int has_audio_class:1; |
377 | unsigned int has_12mhz_i2s:1; | 433 | unsigned int has_alsa_audio:1; |
378 | unsigned int max_range_640_480:1; | ||
379 | unsigned int has_dvb:1; | ||
380 | unsigned int has_snapshot_button:1; | ||
381 | unsigned int valid:1; /* report for validated boards */ | ||
382 | 434 | ||
383 | /* Some older em28xx chips needs a waiting time after writing */ | 435 | struct em28xx_fmt *format; |
384 | unsigned int wait_after_write; | ||
385 | 436 | ||
386 | /* GPIO sequences for analog and digital mode */ | 437 | struct em28xx_IR *ir; |
387 | struct em28xx_reg_seq *analog_gpio, *digital_gpio; | ||
388 | 438 | ||
389 | /* GPIO sequences for tuner callbacks */ | 439 | /* Some older em28xx chips needs a waiting time after writing */ |
390 | struct em28xx_reg_seq *tun_analog_gpio, *tun_digital_gpio; | 440 | unsigned int wait_after_write; |
391 | 441 | ||
392 | int video_inputs; /* number of video inputs */ | ||
393 | struct list_head devlist; | 442 | struct list_head devlist; |
394 | 443 | ||
395 | u32 i2s_speed; /* I2S speed for audio digital stream */ | 444 | u32 i2s_speed; /* I2S speed for audio digital stream */ |
396 | 445 | ||
397 | enum em28xx_decoder decoder; | 446 | struct em28xx_audio_mode audio_mode; |
398 | 447 | ||
399 | int tuner_type; /* type of the tuner */ | 448 | int tuner_type; /* type of the tuner */ |
400 | int tuner_addr; /* tuner address */ | 449 | int tuner_addr; /* tuner address */ |
@@ -409,6 +458,7 @@ struct em28xx { | |||
409 | int ctl_freq; /* selected frequency */ | 458 | int ctl_freq; /* selected frequency */ |
410 | unsigned int ctl_input; /* selected input */ | 459 | unsigned int ctl_input; /* selected input */ |
411 | unsigned int ctl_ainput;/* selected audio input */ | 460 | unsigned int ctl_ainput;/* selected audio input */ |
461 | unsigned int ctl_aoutput;/* selected audio output */ | ||
412 | int mute; | 462 | int mute; |
413 | int volume; | 463 | int volume; |
414 | /* frame properties */ | 464 | /* frame properties */ |
@@ -469,6 +519,9 @@ struct em28xx { | |||
469 | 519 | ||
470 | enum em28xx_mode mode; | 520 | enum em28xx_mode mode; |
471 | 521 | ||
522 | /* register numbers for GPO/GPIO registers */ | ||
523 | u16 reg_gpo_num, reg_gpio_num; | ||
524 | |||
472 | /* Caches GPO and GPIO registers */ | 525 | /* Caches GPO and GPIO registers */ |
473 | unsigned char reg_gpo, reg_gpio; | 526 | unsigned char reg_gpo, reg_gpio; |
474 | 527 | ||
@@ -508,11 +561,17 @@ int em28xx_read_reg(struct em28xx *dev, u16 reg); | |||
508 | int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, | 561 | int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, |
509 | int len); | 562 | int len); |
510 | int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len); | 563 | int em28xx_write_regs(struct em28xx *dev, u16 reg, char *buf, int len); |
564 | int em28xx_write_reg(struct em28xx *dev, u16 reg, u8 val); | ||
565 | |||
566 | int em28xx_read_ac97(struct em28xx *dev, u8 reg); | ||
567 | int em28xx_write_ac97(struct em28xx *dev, u8 reg, u16 val); | ||
568 | |||
511 | int em28xx_audio_analog_set(struct em28xx *dev); | 569 | int em28xx_audio_analog_set(struct em28xx *dev); |
570 | int em28xx_audio_setup(struct em28xx *dev); | ||
512 | 571 | ||
513 | int em28xx_colorlevels_set_default(struct em28xx *dev); | 572 | int em28xx_colorlevels_set_default(struct em28xx *dev); |
514 | int em28xx_capture_start(struct em28xx *dev, int start); | 573 | int em28xx_capture_start(struct em28xx *dev, int start); |
515 | int em28xx_outfmt_set_yuv422(struct em28xx *dev); | 574 | int em28xx_set_outfmt(struct em28xx *dev); |
516 | int em28xx_resolution_set(struct em28xx *dev); | 575 | int em28xx_resolution_set(struct em28xx *dev); |
517 | int em28xx_set_alternate(struct em28xx *dev); | 576 | int em28xx_set_alternate(struct em28xx *dev); |
518 | int em28xx_init_isoc(struct em28xx *dev, int max_packets, | 577 | int em28xx_init_isoc(struct em28xx *dev, int max_packets, |
@@ -521,10 +580,20 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets, | |||
521 | void em28xx_uninit_isoc(struct em28xx *dev); | 580 | void em28xx_uninit_isoc(struct em28xx *dev); |
522 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); | 581 | int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode); |
523 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); | 582 | int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio); |
524 | 583 | void em28xx_wake_i2c(struct em28xx *dev); | |
525 | /* Provided by em28xx-video.c */ | 584 | void em28xx_remove_from_devlist(struct em28xx *dev); |
585 | void em28xx_add_into_devlist(struct em28xx *dev); | ||
586 | struct em28xx *em28xx_get_device(struct inode *inode, | ||
587 | enum v4l2_buf_type *fh_type, | ||
588 | int *has_radio); | ||
526 | int em28xx_register_extension(struct em28xx_ops *dev); | 589 | int em28xx_register_extension(struct em28xx_ops *dev); |
527 | void em28xx_unregister_extension(struct em28xx_ops *dev); | 590 | void em28xx_unregister_extension(struct em28xx_ops *dev); |
591 | void em28xx_init_extension(struct em28xx *dev); | ||
592 | void em28xx_close_extension(struct em28xx *dev); | ||
593 | |||
594 | /* Provided by em28xx-video.c */ | ||
595 | int em28xx_register_analog_devices(struct em28xx *dev); | ||
596 | void em28xx_release_analog_resources(struct em28xx *dev); | ||
528 | 597 | ||
529 | /* Provided by em28xx-cards.c */ | 598 | /* Provided by em28xx-cards.c */ |
530 | extern int em2800_variant_detect(struct usb_device *udev, int model); | 599 | extern int em2800_variant_detect(struct usb_device *udev, int model); |
@@ -535,9 +604,9 @@ extern struct usb_device_id em28xx_id_table[]; | |||
535 | extern const unsigned int em28xx_bcount; | 604 | extern const unsigned int em28xx_bcount; |
536 | void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir); | 605 | void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir); |
537 | int em28xx_tuner_callback(void *ptr, int component, int command, int arg); | 606 | int em28xx_tuner_callback(void *ptr, int component, int command, int arg); |
607 | void em28xx_release_resources(struct em28xx *dev); | ||
538 | 608 | ||
539 | /* Provided by em28xx-input.c */ | 609 | /* Provided by em28xx-input.c */ |
540 | /* TODO: Check if the standard get_key handlers on ir-common can be used */ | ||
541 | int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); | 610 | int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); |
542 | int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); | 611 | int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw); |
543 | int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, | 612 | int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, |
@@ -545,6 +614,9 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key, | |||
545 | void em28xx_register_snapshot_button(struct em28xx *dev); | 614 | void em28xx_register_snapshot_button(struct em28xx *dev); |
546 | void em28xx_deregister_snapshot_button(struct em28xx *dev); | 615 | void em28xx_deregister_snapshot_button(struct em28xx *dev); |
547 | 616 | ||
617 | int em28xx_ir_init(struct em28xx *dev); | ||
618 | int em28xx_ir_fini(struct em28xx *dev); | ||
619 | |||
548 | /* printk macros */ | 620 | /* printk macros */ |
549 | 621 | ||
550 | #define em28xx_err(fmt, arg...) do {\ | 622 | #define em28xx_err(fmt, arg...) do {\ |
@@ -564,7 +636,7 @@ void em28xx_deregister_snapshot_button(struct em28xx *dev); | |||
564 | static inline int em28xx_compression_disable(struct em28xx *dev) | 636 | static inline int em28xx_compression_disable(struct em28xx *dev) |
565 | { | 637 | { |
566 | /* side effect of disabling scaler and mixer */ | 638 | /* side effect of disabling scaler and mixer */ |
567 | return em28xx_write_regs(dev, EM28XX_R26_COMPR, "\x00", 1); | 639 | return em28xx_write_reg(dev, EM28XX_R26_COMPR, 0x00); |
568 | } | 640 | } |
569 | 641 | ||
570 | static inline int em28xx_contrast_get(struct em28xx *dev) | 642 | static inline int em28xx_contrast_get(struct em28xx *dev) |
@@ -636,7 +708,7 @@ static inline int em28xx_gamma_set(struct em28xx *dev, s32 val) | |||
636 | /*FIXME: maxw should be dependent of alt mode */ | 708 | /*FIXME: maxw should be dependent of alt mode */ |
637 | static inline unsigned int norm_maxw(struct em28xx *dev) | 709 | static inline unsigned int norm_maxw(struct em28xx *dev) |
638 | { | 710 | { |
639 | if (dev->max_range_640_480) | 711 | if (dev->board.max_range_640_480) |
640 | return 640; | 712 | return 640; |
641 | else | 713 | else |
642 | return 720; | 714 | return 720; |
@@ -644,7 +716,7 @@ static inline unsigned int norm_maxw(struct em28xx *dev) | |||
644 | 716 | ||
645 | static inline unsigned int norm_maxh(struct em28xx *dev) | 717 | static inline unsigned int norm_maxh(struct em28xx *dev) |
646 | { | 718 | { |
647 | if (dev->max_range_640_480) | 719 | if (dev->board.max_range_640_480) |
648 | return 480; | 720 | return 480; |
649 | else | 721 | else |
650 | return (dev->norm & V4L2_STD_625_50) ? 576 : 480; | 722 | return (dev->norm & V4L2_STD_625_50) ? 576 : 480; |