Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]

Diff markup

Differences between /linux/drivers/media/video/em28xx/em28xx-cards.c (Version 2.6.25.8) and /linux/drivers/media/video/em28xx/em28xx-cards.c (Version 2.6.25)


  1 /*                                                  1 /*
  2    em28xx-cards.c - driver for Empia EM2800/EM      2    em28xx-cards.c - driver for Empia EM2800/EM2820/2840 USB
  3                     video capture devices           3                     video capture devices
  4                                                     4 
  5    Copyright (C) 2005 Ludovico Cavedon <cavedo      5    Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it>
  6                       Markus Rechberger <mrech      6                       Markus Rechberger <mrechberger@gmail.com>
  7                       Mauro Carvalho Chehab <m      7                       Mauro Carvalho Chehab <mchehab@infradead.org>
  8                       Sascha Sommer <saschasom      8                       Sascha Sommer <saschasommer@freenet.de>
  9                                                     9 
 10    This program is free software; you can redi     10    This program is free software; you can redistribute it and/or modify
 11    it under the terms of the GNU General Publi     11    it under the terms of the GNU General Public License as published by
 12    the Free Software Foundation; either versio     12    the Free Software Foundation; either version 2 of the License, or
 13    (at your option) any later version.             13    (at your option) any later version.
 14                                                    14 
 15    This program is distributed in the hope tha     15    This program is distributed in the hope that it will be useful,
 16    but WITHOUT ANY WARRANTY; without even the      16    but WITHOUT ANY WARRANTY; without even the implied warranty of
 17    MERCHANTABILITY or FITNESS FOR A PARTICULAR     17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18    GNU General Public License for more details     18    GNU General Public License for more details.
 19                                                    19 
 20    You should have received a copy of the GNU      20    You should have received a copy of the GNU General Public License
 21    along with this program; if not, write to t     21    along with this program; if not, write to the Free Software
 22    Foundation, Inc., 675 Mass Ave, Cambridge,      22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 23  */                                                23  */
 24                                                    24 
 25 #include <linux/init.h>                            25 #include <linux/init.h>
 26 #include <linux/module.h>                          26 #include <linux/module.h>
 27 #include <linux/delay.h>                           27 #include <linux/delay.h>
 28 #include <linux/i2c.h>                             28 #include <linux/i2c.h>
 29 #include <linux/usb.h>                             29 #include <linux/usb.h>
 30 #include <media/tuner.h>                           30 #include <media/tuner.h>
 31 #include <media/msp3400.h>                         31 #include <media/msp3400.h>
 32 #include <media/saa7115.h>                         32 #include <media/saa7115.h>
 33 #include <media/tvp5150.h>                         33 #include <media/tvp5150.h>
 34 #include <media/tveeprom.h>                        34 #include <media/tveeprom.h>
 35 #include <media/audiochip.h>                       35 #include <media/audiochip.h>
 36 #include <media/v4l2-common.h>                     36 #include <media/v4l2-common.h>
 37                                                    37 
 38 #include "em28xx.h"                                38 #include "em28xx.h"
 39 #include "tuner-xc2028.h"                          39 #include "tuner-xc2028.h"
 40                                                    40 
 41 static int tuner = -1;                             41 static int tuner = -1;
 42 module_param(tuner, int, 0444);                    42 module_param(tuner, int, 0444);
 43 MODULE_PARM_DESC(tuner, "tuner type");             43 MODULE_PARM_DESC(tuner, "tuner type");
 44                                                    44 
 45 static unsigned int disable_ir;                    45 static unsigned int disable_ir;
 46 module_param(disable_ir, int, 0444);               46 module_param(disable_ir, int, 0444);
 47 MODULE_PARM_DESC(disable_ir, "disable infrared     47 MODULE_PARM_DESC(disable_ir, "disable infrared remote support");
 48                                                    48 
 49 struct em28xx_hash_table {                         49 struct em28xx_hash_table {
 50         unsigned long hash;                        50         unsigned long hash;
 51         unsigned int  model;                       51         unsigned int  model;
 52         unsigned int  tuner;                       52         unsigned int  tuner;
 53 };                                                 53 };
 54                                                    54 
 55 /* Boards supported by driver */                   55 /* Boards supported by driver */
 56                                                    56 
 57 #define EM2800_BOARD_UNKNOWN                       57 #define EM2800_BOARD_UNKNOWN                    0
 58 #define EM2820_BOARD_UNKNOWN                       58 #define EM2820_BOARD_UNKNOWN                    1
 59 #define EM2820_BOARD_TERRATEC_CINERGY_250          59 #define EM2820_BOARD_TERRATEC_CINERGY_250       2
 60 #define EM2820_BOARD_PINNACLE_USB_2                60 #define EM2820_BOARD_PINNACLE_USB_2             3
 61 #define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2         61 #define EM2820_BOARD_HAUPPAUGE_WINTV_USB_2      4
 62 #define EM2820_BOARD_MSI_VOX_USB_2                 62 #define EM2820_BOARD_MSI_VOX_USB_2              5
 63 #define EM2800_BOARD_TERRATEC_CINERGY_200          63 #define EM2800_BOARD_TERRATEC_CINERGY_200       6
 64 #define EM2800_BOARD_LEADTEK_WINFAST_USBII         64 #define EM2800_BOARD_LEADTEK_WINFAST_USBII      7
 65 #define EM2800_BOARD_KWORLD_USB2800                65 #define EM2800_BOARD_KWORLD_USB2800             8
 66 #define EM2820_BOARD_PINNACLE_DVC_90               66 #define EM2820_BOARD_PINNACLE_DVC_90            9
 67 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900       67 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900    10
 68 #define EM2880_BOARD_TERRATEC_HYBRID_XS            68 #define EM2880_BOARD_TERRATEC_HYBRID_XS         11
 69 #define EM2820_BOARD_KWORLD_PVRTV2800RF            69 #define EM2820_BOARD_KWORLD_PVRTV2800RF         12
 70 #define EM2880_BOARD_TERRATEC_PRODIGY_XS           70 #define EM2880_BOARD_TERRATEC_PRODIGY_XS        13
 71 #define EM2820_BOARD_PROLINK_PLAYTV_USB2           71 #define EM2820_BOARD_PROLINK_PLAYTV_USB2        14
 72 #define EM2800_BOARD_VGEAR_POCKETTV                72 #define EM2800_BOARD_VGEAR_POCKETTV             15
 73 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950       73 #define EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950    16
 74                                                    74 
 75 struct em28xx_board em28xx_boards[] = {            75 struct em28xx_board em28xx_boards[] = {
 76         [EM2800_BOARD_UNKNOWN] = {                 76         [EM2800_BOARD_UNKNOWN] = {
 77                 .name         = "Unknown EM280     77                 .name         = "Unknown EM2800 video grabber",
 78                 .is_em2800    = 1,                 78                 .is_em2800    = 1,
 79                 .vchannels    = 2,                 79                 .vchannels    = 2,
 80                 .tda9887_conf = TDA9887_PRESEN     80                 .tda9887_conf = TDA9887_PRESENT,
 81                 .decoder      = EM28XX_SAA7113     81                 .decoder      = EM28XX_SAA7113,
 82                 .input           = { {             82                 .input           = { {
 83                         .type     = EM28XX_VMU     83                         .type     = EM28XX_VMUX_COMPOSITE1,
 84                         .vmux     = SAA7115_CO     84                         .vmux     = SAA7115_COMPOSITE0,
 85                         .amux     = 1,             85                         .amux     = 1,
 86                 }, {                               86                 }, {
 87                         .type     = EM28XX_VMU     87                         .type     = EM28XX_VMUX_SVIDEO,
 88                         .vmux     = SAA7115_SV     88                         .vmux     = SAA7115_SVIDEO3,
 89                         .amux     = 1,             89                         .amux     = 1,
 90                 } },                               90                 } },
 91         },                                         91         },
 92         [EM2820_BOARD_UNKNOWN] = {                 92         [EM2820_BOARD_UNKNOWN] = {
 93                 .name         = "Unknown EM275     93                 .name         = "Unknown EM2750/28xx video grabber",
 94                 .is_em2800    = 0,                 94                 .is_em2800    = 0,
 95                 .tuner_type   = TUNER_ABSENT,      95                 .tuner_type   = TUNER_ABSENT,
 96         },                                         96         },
 97         [EM2820_BOARD_KWORLD_PVRTV2800RF] = {      97         [EM2820_BOARD_KWORLD_PVRTV2800RF] = {
 98                 .name         = "Kworld PVR TV     98                 .name         = "Kworld PVR TV 2800 RF",
 99                 .is_em2800    = 0,                 99                 .is_em2800    = 0,
100                 .vchannels    = 2,                100                 .vchannels    = 2,
101                 .tuner_type   = TUNER_TEMIC_PA    101                 .tuner_type   = TUNER_TEMIC_PAL,
102                 .tda9887_conf = TDA9887_PRESEN    102                 .tda9887_conf = TDA9887_PRESENT,
103                 .decoder      = EM28XX_SAA7113    103                 .decoder      = EM28XX_SAA7113,
104                 .input           = { {            104                 .input           = { {
105                         .type     = EM28XX_VMU    105                         .type     = EM28XX_VMUX_COMPOSITE1,
106                         .vmux     = SAA7115_CO    106                         .vmux     = SAA7115_COMPOSITE0,
107                         .amux     = 1,            107                         .amux     = 1,
108                 }, {                              108                 }, {
109                         .type     = EM28XX_VMU    109                         .type     = EM28XX_VMUX_SVIDEO,
110                         .vmux     = SAA7115_SV    110                         .vmux     = SAA7115_SVIDEO3,
111                         .amux     = 1,            111                         .amux     = 1,
112                 } },                              112                 } },
113         },                                        113         },
114         [EM2820_BOARD_TERRATEC_CINERGY_250] =     114         [EM2820_BOARD_TERRATEC_CINERGY_250] = {
115                 .name         = "Terratec Cine    115                 .name         = "Terratec Cinergy 250 USB",
116                 .vchannels    = 3,                116                 .vchannels    = 3,
117                 .tuner_type   = TUNER_LG_PAL_N    117                 .tuner_type   = TUNER_LG_PAL_NEW_TAPC,
118                 .tda9887_conf = TDA9887_PRESEN    118                 .tda9887_conf = TDA9887_PRESENT,
119                 .decoder      = EM28XX_SAA7113    119                 .decoder      = EM28XX_SAA7113,
120                 .input          = { {             120                 .input          = { {
121                         .type     = EM28XX_VMU    121                         .type     = EM28XX_VMUX_TELEVISION,
122                         .vmux     = SAA7115_CO    122                         .vmux     = SAA7115_COMPOSITE2,
123                         .amux     = 1,            123                         .amux     = 1,
124                 }, {                              124                 }, {
125                         .type     = EM28XX_VMU    125                         .type     = EM28XX_VMUX_COMPOSITE1,
126                         .vmux     = SAA7115_CO    126                         .vmux     = SAA7115_COMPOSITE0,
127                         .amux     = 1,            127                         .amux     = 1,
128                 }, {                              128                 }, {
129                         .type     = EM28XX_VMU    129                         .type     = EM28XX_VMUX_SVIDEO,
130                         .vmux     = SAA7115_SV    130                         .vmux     = SAA7115_SVIDEO3,
131                         .amux     = 1,            131                         .amux     = 1,
132                 } },                              132                 } },
133         },                                        133         },
134         [EM2820_BOARD_PINNACLE_USB_2] = {         134         [EM2820_BOARD_PINNACLE_USB_2] = {
135                 .name         = "Pinnacle PCTV    135                 .name         = "Pinnacle PCTV USB 2",
136                 .vchannels    = 3,                136                 .vchannels    = 3,
137                 .tuner_type   = TUNER_LG_PAL_N    137                 .tuner_type   = TUNER_LG_PAL_NEW_TAPC,
138                 .tda9887_conf = TDA9887_PRESEN    138                 .tda9887_conf = TDA9887_PRESENT,
139                 .decoder      = EM28XX_SAA7113    139                 .decoder      = EM28XX_SAA7113,
140                 .input          = { {             140                 .input          = { {
141                         .type     = EM28XX_VMU    141                         .type     = EM28XX_VMUX_TELEVISION,
142                         .vmux     = SAA7115_CO    142                         .vmux     = SAA7115_COMPOSITE2,
143                         .amux     = 0,            143                         .amux     = 0,
144                 }, {                              144                 }, {
145                         .type     = EM28XX_VMU    145                         .type     = EM28XX_VMUX_COMPOSITE1,
146                         .vmux     = SAA7115_CO    146                         .vmux     = SAA7115_COMPOSITE0,
147                         .amux     = 1,            147                         .amux     = 1,
148                 }, {                              148                 }, {
149                         .type     = EM28XX_VMU    149                         .type     = EM28XX_VMUX_SVIDEO,
150                         .vmux     = SAA7115_SV    150                         .vmux     = SAA7115_SVIDEO3,
151                         .amux     = 1,            151                         .amux     = 1,
152                 } },                              152                 } },
153         },                                        153         },
154         [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] =    154         [EM2820_BOARD_HAUPPAUGE_WINTV_USB_2] = {
155                 .name         = "Hauppauge Win    155                 .name         = "Hauppauge WinTV USB 2",
156                 .vchannels    = 3,                156                 .vchannels    = 3,
157                 .tuner_type   = TUNER_PHILIPS_    157                 .tuner_type   = TUNER_PHILIPS_FM1236_MK3,
158                 .tda9887_conf = TDA9887_PRESEN    158                 .tda9887_conf = TDA9887_PRESENT |
159                                 TDA9887_PORT1_    159                                 TDA9887_PORT1_ACTIVE|
160                                 TDA9887_PORT2_    160                                 TDA9887_PORT2_ACTIVE,
161                 .decoder      = EM28XX_TVP5150    161                 .decoder      = EM28XX_TVP5150,
162                 .has_msp34xx  = 1,                162                 .has_msp34xx  = 1,
163                 /*FIXME: S-Video not tested */    163                 /*FIXME: S-Video not tested */
164                 .input          = { {             164                 .input          = { {
165                         .type     = EM28XX_VMU    165                         .type     = EM28XX_VMUX_TELEVISION,
166                         .vmux     = TVP5150_CO    166                         .vmux     = TVP5150_COMPOSITE0,
167                         .amux     = MSP_INPUT_    167                         .amux     = MSP_INPUT_DEFAULT,
168                 }, {                              168                 }, {
169                         .type     = EM28XX_VMU    169                         .type     = EM28XX_VMUX_SVIDEO,
170                         .vmux     = TVP5150_SV    170                         .vmux     = TVP5150_SVIDEO,
171                         .amux     = MSP_INPUT(    171                         .amux     = MSP_INPUT(MSP_IN_SCART1, MSP_IN_TUNER1,
172                                         MSP_DS    172                                         MSP_DSP_IN_SCART, MSP_DSP_IN_SCART),
173                 } },                              173                 } },
174         },                                        174         },
175         [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900]    175         [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900] = {
176                 .name         = "Hauppauge Win    176                 .name         = "Hauppauge WinTV HVR 900",
177                 .vchannels    = 3,                177                 .vchannels    = 3,
178                 .tda9887_conf = TDA9887_PRESEN    178                 .tda9887_conf = TDA9887_PRESENT,
179                 .tuner_type   = TUNER_XC2028,     179                 .tuner_type   = TUNER_XC2028,
180                 .mts_firmware = 1,                180                 .mts_firmware = 1,
181                 .decoder      = EM28XX_TVP5150    181                 .decoder      = EM28XX_TVP5150,
182                 .input          = { {             182                 .input          = { {
183                         .type     = EM28XX_VMU    183                         .type     = EM28XX_VMUX_TELEVISION,
184                         .vmux     = TVP5150_CO    184                         .vmux     = TVP5150_COMPOSITE0,
185                         .amux     = 0,            185                         .amux     = 0,
186                 }, {                              186                 }, {
187                         .type     = EM28XX_VMU    187                         .type     = EM28XX_VMUX_COMPOSITE1,
188                         .vmux     = TVP5150_CO    188                         .vmux     = TVP5150_COMPOSITE1,
189                         .amux     = 1,            189                         .amux     = 1,
190                 }, {                              190                 }, {
191                         .type     = EM28XX_VMU    191                         .type     = EM28XX_VMUX_SVIDEO,
192                         .vmux     = TVP5150_SV    192                         .vmux     = TVP5150_SVIDEO,
193                         .amux     = 1,            193                         .amux     = 1,
194                 } },                              194                 } },
195         },                                        195         },
196         [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950]    196         [EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950] = {
197                 .name           = "Hauppauge W    197                 .name           = "Hauppauge WinTV HVR 950",
198                 .vchannels      = 3,              198                 .vchannels      = 3,
199                 .tda9887_conf   = TDA9887_PRES    199                 .tda9887_conf   = TDA9887_PRESENT,
200                 .tuner_type     = TUNER_XC2028    200                 .tuner_type     = TUNER_XC2028,
201                 .mts_firmware   = 1,              201                 .mts_firmware   = 1,
202                 .has_12mhz_i2s  = 1,              202                 .has_12mhz_i2s  = 1,
203                 .decoder        = EM28XX_TVP51    203                 .decoder        = EM28XX_TVP5150,
204                 .input          = { {             204                 .input          = { {
205                         .type     = EM28XX_VMU    205                         .type     = EM28XX_VMUX_TELEVISION,
206                         .vmux     = TVP5150_CO    206                         .vmux     = TVP5150_COMPOSITE0,
207                         .amux     = 0,            207                         .amux     = 0,
208                 }, {                              208                 }, {
209                         .type     = EM28XX_VMU    209                         .type     = EM28XX_VMUX_COMPOSITE1,
210                         .vmux     = TVP5150_CO    210                         .vmux     = TVP5150_COMPOSITE1,
211                         .amux     = 1,            211                         .amux     = 1,
212                 }, {                              212                 }, {
213                         .type     = EM28XX_VMU    213                         .type     = EM28XX_VMUX_SVIDEO,
214                         .vmux     = TVP5150_SV    214                         .vmux     = TVP5150_SVIDEO,
215                         .amux     = 1,            215                         .amux     = 1,
216                 } },                              216                 } },
217                                                   217 
218                 /* gpio's 4, 1, 0 */              218                 /* gpio's 4, 1, 0 */
219                 .analog_gpio = 0x003d2d,          219                 .analog_gpio = 0x003d2d,
220         },                                        220         },
221         [EM2880_BOARD_TERRATEC_HYBRID_XS] = {     221         [EM2880_BOARD_TERRATEC_HYBRID_XS] = {
222                 .name         = "Terratec Hybr    222                 .name         = "Terratec Hybrid XS",
223                 .vchannels    = 3,                223                 .vchannels    = 3,
224                 .tda9887_conf = TDA9887_PRESEN    224                 .tda9887_conf = TDA9887_PRESENT,
225                 .tuner_type   = TUNER_XC2028,     225                 .tuner_type   = TUNER_XC2028,
226                 .decoder      = EM28XX_TVP5150    226                 .decoder      = EM28XX_TVP5150,
227                 .input          = { {             227                 .input          = { {
228                         .type     = EM28XX_VMU    228                         .type     = EM28XX_VMUX_TELEVISION,
229                         .vmux     = TVP5150_CO    229                         .vmux     = TVP5150_COMPOSITE0,
230                         .amux     = 0,            230                         .amux     = 0,
231                 }, {                              231                 }, {
232                         .type     = EM28XX_VMU    232                         .type     = EM28XX_VMUX_COMPOSITE1,
233                         .vmux     = TVP5150_CO    233                         .vmux     = TVP5150_COMPOSITE1,
234                         .amux     = 1,            234                         .amux     = 1,
235                 }, {                              235                 }, {
236                         .type     = EM28XX_VMU    236                         .type     = EM28XX_VMUX_SVIDEO,
237                         .vmux     = TVP5150_SV    237                         .vmux     = TVP5150_SVIDEO,
238                         .amux     = 1,            238                         .amux     = 1,
239                 } },                              239                 } },
240         },                                        240         },
241         /* maybe there's a reason behind it wh    241         /* maybe there's a reason behind it why Terratec sells the Hybrid XS
242            as Prodigy XS with a different PID,    242            as Prodigy XS with a different PID, let's keep it separated for now
243            maybe we'll need it lateron */         243            maybe we'll need it lateron */
244         [EM2880_BOARD_TERRATEC_PRODIGY_XS] = {    244         [EM2880_BOARD_TERRATEC_PRODIGY_XS] = {
245                 .name         = "Terratec Prod    245                 .name         = "Terratec Prodigy XS",
246                 .vchannels    = 3,                246                 .vchannels    = 3,
247                 .tda9887_conf = TDA9887_PRESEN    247                 .tda9887_conf = TDA9887_PRESENT,
248                 .tuner_type   = TUNER_XC2028,     248                 .tuner_type   = TUNER_XC2028,
249                 .decoder      = EM28XX_TVP5150    249                 .decoder      = EM28XX_TVP5150,
250                 .input          = { {             250                 .input          = { {
251                         .type     = EM28XX_VMU    251                         .type     = EM28XX_VMUX_TELEVISION,
252                         .vmux     = TVP5150_CO    252                         .vmux     = TVP5150_COMPOSITE0,
253                         .amux     = 0,            253                         .amux     = 0,
254                 }, {                              254                 }, {
255                         .type     = EM28XX_VMU    255                         .type     = EM28XX_VMUX_COMPOSITE1,
256                         .vmux     = TVP5150_CO    256                         .vmux     = TVP5150_COMPOSITE1,
257                         .amux     = 1,            257                         .amux     = 1,
258                 }, {                              258                 }, {
259                         .type     = EM28XX_VMU    259                         .type     = EM28XX_VMUX_SVIDEO,
260                         .vmux     = TVP5150_SV    260                         .vmux     = TVP5150_SVIDEO,
261                         .amux     = 1,            261                         .amux     = 1,
262                 } },                              262                 } },
263         },                                        263         },
264         [EM2820_BOARD_MSI_VOX_USB_2] = {          264         [EM2820_BOARD_MSI_VOX_USB_2] = {
265                 .name              = "MSI VOX     265                 .name              = "MSI VOX USB 2.0",
266                 .vchannels         = 3,           266                 .vchannels         = 3,
267                 .tuner_type        = TUNER_LG_    267                 .tuner_type        = TUNER_LG_PAL_NEW_TAPC,
268                 .tda9887_conf      = TDA9887_P    268                 .tda9887_conf      = TDA9887_PRESENT      |
269                                      TDA9887_P    269                                      TDA9887_PORT1_ACTIVE |
270                                      TDA9887_P    270                                      TDA9887_PORT2_ACTIVE,
271                 .max_range_640_480 = 1,           271                 .max_range_640_480 = 1,
272                                                   272 
273                 .decoder           = EM28XX_SA    273                 .decoder           = EM28XX_SAA7114,
274                 .input             = { {          274                 .input             = { {
275                         .type      = EM28XX_VM    275                         .type      = EM28XX_VMUX_TELEVISION,
276                         .vmux      = SAA7115_C    276                         .vmux      = SAA7115_COMPOSITE4,
277                         .amux      = 0,           277                         .amux      = 0,
278                 }, {                              278                 }, {
279                         .type      = EM28XX_VM    279                         .type      = EM28XX_VMUX_COMPOSITE1,
280                         .vmux      = SAA7115_C    280                         .vmux      = SAA7115_COMPOSITE0,
281                         .amux      = 1,           281                         .amux      = 1,
282                 }, {                              282                 }, {
283                         .type      = EM28XX_VM    283                         .type      = EM28XX_VMUX_SVIDEO,
284                         .vmux      = SAA7115_S    284                         .vmux      = SAA7115_SVIDEO3,
285                         .amux      = 1,           285                         .amux      = 1,
286                 } },                              286                 } },
287         },                                        287         },
288         [EM2800_BOARD_TERRATEC_CINERGY_200] =     288         [EM2800_BOARD_TERRATEC_CINERGY_200] = {
289                 .name         = "Terratec Cine    289                 .name         = "Terratec Cinergy 200 USB",
290                 .is_em2800    = 1,                290                 .is_em2800    = 1,
291                 .vchannels    = 3,                291                 .vchannels    = 3,
292                 .tuner_type   = TUNER_LG_PAL_N    292                 .tuner_type   = TUNER_LG_PAL_NEW_TAPC,
293                 .tda9887_conf = TDA9887_PRESEN    293                 .tda9887_conf = TDA9887_PRESENT,
294                 .decoder      = EM28XX_SAA7113    294                 .decoder      = EM28XX_SAA7113,
295                 .input          = { {             295                 .input          = { {
296                         .type     = EM28XX_VMU    296                         .type     = EM28XX_VMUX_TELEVISION,
297                         .vmux     = SAA7115_CO    297                         .vmux     = SAA7115_COMPOSITE2,
298                         .amux     = 0,            298                         .amux     = 0,
299                 }, {                              299                 }, {
300                         .type     = EM28XX_VMU    300                         .type     = EM28XX_VMUX_COMPOSITE1,
301                         .vmux     = SAA7115_CO    301                         .vmux     = SAA7115_COMPOSITE0,
302                         .amux     = 1,            302                         .amux     = 1,
303                 }, {                              303                 }, {
304                         .type     = EM28XX_VMU    304                         .type     = EM28XX_VMUX_SVIDEO,
305                         .vmux     = SAA7115_SV    305                         .vmux     = SAA7115_SVIDEO3,
306                         .amux     = 1,            306                         .amux     = 1,
307                 } },                              307                 } },
308         },                                        308         },
309         [EM2800_BOARD_LEADTEK_WINFAST_USBII] =    309         [EM2800_BOARD_LEADTEK_WINFAST_USBII] = {
310                 .name         = "Leadtek Winfa    310                 .name         = "Leadtek Winfast USB II",
311                 .is_em2800    = 1,                311                 .is_em2800    = 1,
312                 .vchannels    = 3,                312                 .vchannels    = 3,
313                 .tuner_type   = TUNER_LG_PAL_N    313                 .tuner_type   = TUNER_LG_PAL_NEW_TAPC,
314                 .tda9887_conf = TDA9887_PRESEN    314                 .tda9887_conf = TDA9887_PRESENT,
315                 .decoder      = EM28XX_SAA7113    315                 .decoder      = EM28XX_SAA7113,
316                 .input          = { {             316                 .input          = { {
317                         .type     = EM28XX_VMU    317                         .type     = EM28XX_VMUX_TELEVISION,
318                         .vmux     = SAA7115_CO    318                         .vmux     = SAA7115_COMPOSITE2,
319                         .amux     = 0,            319                         .amux     = 0,
320                 }, {                              320                 }, {
321                         .type     = EM28XX_VMU    321                         .type     = EM28XX_VMUX_COMPOSITE1,
322                         .vmux     = SAA7115_CO    322                         .vmux     = SAA7115_COMPOSITE0,
323                         .amux     = 1,            323                         .amux     = 1,
324                 }, {                              324                 }, {
325                         .type     = EM28XX_VMU    325                         .type     = EM28XX_VMUX_SVIDEO,
326                         .vmux     = SAA7115_SV    326                         .vmux     = SAA7115_SVIDEO3,
327                         .amux     = 1,            327                         .amux     = 1,
328                 } },                              328                 } },
329         },                                        329         },
330         [EM2800_BOARD_KWORLD_USB2800] = {         330         [EM2800_BOARD_KWORLD_USB2800] = {
331                 .name         = "Kworld USB280    331                 .name         = "Kworld USB2800",
332                 .is_em2800    = 1,                332                 .is_em2800    = 1,
333                 .vchannels    = 3,                333                 .vchannels    = 3,
334                 .tuner_type   = TUNER_PHILIPS_    334                 .tuner_type   = TUNER_PHILIPS_ATSC,
335                 .tda9887_conf = TDA9887_PRESEN    335                 .tda9887_conf = TDA9887_PRESENT,
336                 .decoder      = EM28XX_SAA7113    336                 .decoder      = EM28XX_SAA7113,
337                 .input          = { {             337                 .input          = { {
338                         .type     = EM28XX_VMU    338                         .type     = EM28XX_VMUX_TELEVISION,
339                         .vmux     = SAA7115_CO    339                         .vmux     = SAA7115_COMPOSITE2,
340                         .amux     = 0,            340                         .amux     = 0,
341                 }, {                              341                 }, {
342                         .type     = EM28XX_VMU    342                         .type     = EM28XX_VMUX_COMPOSITE1,
343                         .vmux     = SAA7115_CO    343                         .vmux     = SAA7115_COMPOSITE0,
344                         .amux     = 1,            344                         .amux     = 1,
345                 }, {                              345                 }, {
346                         .type     = EM28XX_VMU    346                         .type     = EM28XX_VMUX_SVIDEO,
347                         .vmux     = SAA7115_SV    347                         .vmux     = SAA7115_SVIDEO3,
348                         .amux     = 1,            348                         .amux     = 1,
349                 } },                              349                 } },
350         },                                        350         },
351         [EM2820_BOARD_PINNACLE_DVC_90] = {        351         [EM2820_BOARD_PINNACLE_DVC_90] = {
352                 .name         = "Pinnacle Dazz    352                 .name         = "Pinnacle Dazzle DVC 90/DVC 100",
353                 .vchannels    = 3,                353                 .vchannels    = 3,
354                 .tuner_type   = TUNER_ABSENT,     354                 .tuner_type   = TUNER_ABSENT,
355                 .decoder      = EM28XX_SAA7113    355                 .decoder      = EM28XX_SAA7113,
356                 .input          = { {             356                 .input          = { {
357                         .type     = EM28XX_VMU    357                         .type     = EM28XX_VMUX_COMPOSITE1,
358                         .vmux     = SAA7115_CO    358                         .vmux     = SAA7115_COMPOSITE0,
359                         .amux     = 1,            359                         .amux     = 1,
360                 }, {                              360                 }, {
361                         .type     = EM28XX_VMU    361                         .type     = EM28XX_VMUX_SVIDEO,
362                         .vmux     = SAA7115_SV    362                         .vmux     = SAA7115_SVIDEO3,
363                         .amux     = 1,            363                         .amux     = 1,
364                 } },                              364                 } },
365         },                                        365         },
366         [EM2800_BOARD_VGEAR_POCKETTV] = {         366         [EM2800_BOARD_VGEAR_POCKETTV] = {
367                 .name         = "V-Gear Pocket    367                 .name         = "V-Gear PocketTV",
368                 .is_em2800    = 1,                368                 .is_em2800    = 1,
369                 .vchannels    = 3,                369                 .vchannels    = 3,
370                 .tuner_type   = TUNER_LG_PAL_N    370                 .tuner_type   = TUNER_LG_PAL_NEW_TAPC,
371                 .tda9887_conf = TDA9887_PRESEN    371                 .tda9887_conf = TDA9887_PRESENT,
372                 .decoder      = EM28XX_SAA7113    372                 .decoder      = EM28XX_SAA7113,
373                 .input          = { {             373                 .input          = { {
374                         .type     = EM28XX_VMU    374                         .type     = EM28XX_VMUX_TELEVISION,
375                         .vmux     = SAA7115_CO    375                         .vmux     = SAA7115_COMPOSITE2,
376                         .amux     = 0,            376                         .amux     = 0,
377                 }, {                              377                 }, {
378                         .type     = EM28XX_VMU    378                         .type     = EM28XX_VMUX_COMPOSITE1,
379                         .vmux     = SAA7115_CO    379                         .vmux     = SAA7115_COMPOSITE0,
380                         .amux     = 1,            380                         .amux     = 1,
381                 }, {                              381                 }, {
382                         .type     = EM28XX_VMU    382                         .type     = EM28XX_VMUX_SVIDEO,
383                         .vmux     = SAA7115_SV    383                         .vmux     = SAA7115_SVIDEO3,
384                         .amux     = 1,            384                         .amux     = 1,
385                 } },                              385                 } },
386         },                                        386         },
387         [EM2820_BOARD_PROLINK_PLAYTV_USB2] = {    387         [EM2820_BOARD_PROLINK_PLAYTV_USB2] = {
388                 .name         = "Pixelview Pro    388                 .name         = "Pixelview Prolink PlayTV USB 2.0",
389                 .vchannels    = 3,                389                 .vchannels    = 3,
390                 .tda9887_conf = TDA9887_PRESEN    390                 .tda9887_conf = TDA9887_PRESENT,
391                 .tuner_type   = TUNER_YMEC_TVF    391                 .tuner_type   = TUNER_YMEC_TVF_5533MF,
392                 .decoder      = EM28XX_SAA7113    392                 .decoder      = EM28XX_SAA7113,
393                 .input          = { {             393                 .input          = { {
394                         .type     = EM28XX_VMU    394                         .type     = EM28XX_VMUX_TELEVISION,
395                         .vmux     = SAA7115_CO    395                         .vmux     = SAA7115_COMPOSITE2,
396                         .amux     = EM28XX_AMU    396                         .amux     = EM28XX_AMUX_LINE_IN,
397                 }, {                              397                 }, {
398                         .type     = EM28XX_VMU    398                         .type     = EM28XX_VMUX_COMPOSITE1,
399                         .vmux     = SAA7115_CO    399                         .vmux     = SAA7115_COMPOSITE0,
400                         .amux     = EM28XX_AMU    400                         .amux     = EM28XX_AMUX_LINE_IN,
401                 }, {                              401                 }, {
402                         .type     = EM28XX_VMU    402                         .type     = EM28XX_VMUX_SVIDEO,
403                         .vmux     = SAA7115_SV    403                         .vmux     = SAA7115_SVIDEO3,
404                         .amux     = EM28XX_AMU    404                         .amux     = EM28XX_AMUX_LINE_IN,
405                 } },                              405                 } },
406         },                                        406         },
407 };                                                407 };
408 const unsigned int em28xx_bcount = ARRAY_SIZE(    408 const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
409                                                   409 
410 /* table of devices that work with this driver    410 /* table of devices that work with this driver */
411 struct usb_device_id em28xx_id_table [] = {       411 struct usb_device_id em28xx_id_table [] = {
412         { USB_DEVICE(0xeb1a, 0x2750),             412         { USB_DEVICE(0xeb1a, 0x2750),
413                         .driver_info = EM2820_    413                         .driver_info = EM2820_BOARD_UNKNOWN },
414         { USB_DEVICE(0xeb1a, 0x2800),             414         { USB_DEVICE(0xeb1a, 0x2800),
415                         .driver_info = EM2800_    415                         .driver_info = EM2800_BOARD_UNKNOWN },
416         { USB_DEVICE(0xeb1a, 0x2820),             416         { USB_DEVICE(0xeb1a, 0x2820),
417                         .driver_info = EM2820_    417                         .driver_info = EM2820_BOARD_UNKNOWN },
418         { USB_DEVICE(0xeb1a, 0x2821),             418         { USB_DEVICE(0xeb1a, 0x2821),
419                         .driver_info = EM2820_    419                         .driver_info = EM2820_BOARD_UNKNOWN },
420         { USB_DEVICE(0xeb1a, 0x2860),             420         { USB_DEVICE(0xeb1a, 0x2860),
421                         .driver_info = EM2820_    421                         .driver_info = EM2820_BOARD_UNKNOWN },
422         { USB_DEVICE(0xeb1a, 0x2861),             422         { USB_DEVICE(0xeb1a, 0x2861),
423                         .driver_info = EM2820_    423                         .driver_info = EM2820_BOARD_UNKNOWN },
424         { USB_DEVICE(0xeb1a, 0x2870),             424         { USB_DEVICE(0xeb1a, 0x2870),
425                         .driver_info = EM2820_    425                         .driver_info = EM2820_BOARD_UNKNOWN },
426         { USB_DEVICE(0xeb1a, 0x2881),             426         { USB_DEVICE(0xeb1a, 0x2881),
427                         .driver_info = EM2820_    427                         .driver_info = EM2820_BOARD_UNKNOWN },
428         { USB_DEVICE(0xeb1a, 0x2883),             428         { USB_DEVICE(0xeb1a, 0x2883),
429                         .driver_info = EM2820_    429                         .driver_info = EM2820_BOARD_UNKNOWN },
430         { USB_DEVICE(0x0ccd, 0x0036),             430         { USB_DEVICE(0x0ccd, 0x0036),
431                         .driver_info = EM2820_    431                         .driver_info = EM2820_BOARD_TERRATEC_CINERGY_250 },
432         { USB_DEVICE(0x2304, 0x0208),             432         { USB_DEVICE(0x2304, 0x0208),
433                         .driver_info = EM2820_    433                         .driver_info = EM2820_BOARD_PINNACLE_USB_2 },
434         { USB_DEVICE(0x2040, 0x4200),             434         { USB_DEVICE(0x2040, 0x4200),
435                         .driver_info = EM2820_    435                         .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
436         { USB_DEVICE(0x2040, 0x4201),             436         { USB_DEVICE(0x2040, 0x4201),
437                         .driver_info = EM2820_    437                         .driver_info = EM2820_BOARD_HAUPPAUGE_WINTV_USB_2 },
438         { USB_DEVICE(0x2304, 0x0207),             438         { USB_DEVICE(0x2304, 0x0207),
439                         .driver_info = EM2820_    439                         .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
440         { USB_DEVICE(0x2304, 0x021a),             440         { USB_DEVICE(0x2304, 0x021a),
441                         .driver_info = EM2820_    441                         .driver_info = EM2820_BOARD_PINNACLE_DVC_90 },
442         { USB_DEVICE(0x2040, 0x6500),             442         { USB_DEVICE(0x2040, 0x6500),
443                         .driver_info = EM2880_    443                         .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
444         { USB_DEVICE(0x2040, 0x6502),             444         { USB_DEVICE(0x2040, 0x6502),
445                         .driver_info = EM2880_    445                         .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900 },
446         { USB_DEVICE(0x2040, 0x6513),             446         { USB_DEVICE(0x2040, 0x6513),
447                         .driver_info = EM2880_    447                         .driver_info = EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950 },
448         { USB_DEVICE(0x0ccd, 0x0042),             448         { USB_DEVICE(0x0ccd, 0x0042),
449                         .driver_info = EM2880_    449                         .driver_info = EM2880_BOARD_TERRATEC_HYBRID_XS },
450         { USB_DEVICE(0x0ccd, 0x0047),             450         { USB_DEVICE(0x0ccd, 0x0047),
451                         .driver_info = EM2880_    451                         .driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS },
452         { },                                      452         { },
453 };                                                453 };
454 MODULE_DEVICE_TABLE(usb, em28xx_id_table);        454 MODULE_DEVICE_TABLE(usb, em28xx_id_table);
455                                                   455 
456 /* EEPROM hash table for devices with generic     456 /* EEPROM hash table for devices with generic USB IDs */
457 static struct em28xx_hash_table em28xx_eeprom_    457 static struct em28xx_hash_table em28xx_eeprom_hash [] = {
458         /* P/N: SA 60002070465 Tuner: TVF7533-    458         /* P/N: SA 60002070465 Tuner: TVF7533-MF */
459         {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAY    459         {0x6ce05a8f, EM2820_BOARD_PROLINK_PLAYTV_USB2, TUNER_YMEC_TVF_5533MF},
460 };                                                460 };
461                                                   461 
462 /* I2C devicelist hash table for devices with     462 /* I2C devicelist hash table for devices with generic USB IDs */
463 static struct em28xx_hash_table em28xx_i2c_has    463 static struct em28xx_hash_table em28xx_i2c_hash[] = {
464         {0xb06a32c3, EM2800_BOARD_TERRATEC_CIN    464         {0xb06a32c3, EM2800_BOARD_TERRATEC_CINERGY_200, TUNER_LG_PAL_NEW_TAPC},
465         {0xf51200e3, EM2800_BOARD_VGEAR_POCKET    465         {0xf51200e3, EM2800_BOARD_VGEAR_POCKETTV, TUNER_LG_PAL_NEW_TAPC},
466 };                                                466 };
467                                                   467 
468 /* Since em28xx_pre_card_setup() requires a pr    468 /* Since em28xx_pre_card_setup() requires a proper dev->model,
469  * this won't work for boards with generic PCI    469  * this won't work for boards with generic PCI IDs
470  */                                               470  */
471 void em28xx_pre_card_setup(struct em28xx *dev)    471 void em28xx_pre_card_setup(struct em28xx *dev)
472 {                                                 472 {
473         /* request some modules */                473         /* request some modules */
474         switch (dev->model) {                     474         switch (dev->model) {
475         case EM2880_BOARD_TERRATEC_PRODIGY_XS:    475         case EM2880_BOARD_TERRATEC_PRODIGY_XS:
476         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_    476         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
477         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_    477         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
478         case EM2880_BOARD_TERRATEC_HYBRID_XS:     478         case EM2880_BOARD_TERRATEC_HYBRID_XS:
479                 em28xx_write_regs(dev, XCLK_RE    479                 em28xx_write_regs(dev, XCLK_REG, "\x27", 1);
480                 em28xx_write_regs(dev, I2C_CLK    480                 em28xx_write_regs(dev, I2C_CLK_REG, "\x40", 1);
481                 em28xx_write_regs(dev, 0x08, "    481                 em28xx_write_regs(dev, 0x08, "\xff", 1);
482                 em28xx_write_regs(dev, 0x04, "    482                 em28xx_write_regs(dev, 0x04, "\x00", 1);
483                 msleep(100);                      483                 msleep(100);
484                 em28xx_write_regs(dev, 0x04, "    484                 em28xx_write_regs(dev, 0x04, "\x08", 1);
485                 msleep(100);                      485                 msleep(100);
486                 em28xx_write_regs(dev, 0x08, "    486                 em28xx_write_regs(dev, 0x08, "\xff", 1);
487                 msleep(50);                       487                 msleep(50);
488                 em28xx_write_regs(dev, 0x08, "    488                 em28xx_write_regs(dev, 0x08, "\x2d", 1);
489                 msleep(50);                       489                 msleep(50);
490                 em28xx_write_regs(dev, 0x08, "    490                 em28xx_write_regs(dev, 0x08, "\x3d", 1);
491                 break;                            491                 break;
492         }                                         492         }
493 }                                                 493 }
494                                                   494 
495 static int em28xx_tuner_callback(void *ptr, in    495 static int em28xx_tuner_callback(void *ptr, int command, int arg)
496 {                                                 496 {
497         int rc = 0;                               497         int rc = 0;
498         struct em28xx *dev = ptr;                 498         struct em28xx *dev = ptr;
499                                                   499 
500         if (dev->tuner_type != TUNER_XC2028)      500         if (dev->tuner_type != TUNER_XC2028)
501                 return 0;                         501                 return 0;
502                                                   502 
503         switch (command) {                        503         switch (command) {
504         case XC2028_TUNER_RESET:                  504         case XC2028_TUNER_RESET:
505         {                                         505         {
506                 /* GPIO and initialization cod    506                 /* GPIO and initialization codes for analog TV and radio
507                    This code should be complem    507                    This code should be complemented for DTV, since reset
508                    codes are different.           508                    codes are different.
509                  */                               509                  */
510                                                   510 
511                 dev->em28xx_write_regs_req(dev    511                 dev->em28xx_write_regs_req(dev, 0x00, 0x48, "\x00", 1);
512                 dev->em28xx_write_regs_req(dev    512                 dev->em28xx_write_regs_req(dev, 0x00, 0x12, "\x67", 1);
513                                                   513 
514                 if (dev->analog_gpio) {           514                 if (dev->analog_gpio) {
515                         char gpio0 = dev->anal    515                         char gpio0 = dev->analog_gpio & 0xff;
516                         char gpio1 = (dev->ana    516                         char gpio1 = (dev->analog_gpio >> 8) & 0xff;
517                         char gpio4 = dev->anal    517                         char gpio4 = dev->analog_gpio >> 24;
518                                                   518 
519                         if (gpio4) {              519                         if (gpio4) {
520                                 dev->em28xx_wr    520                                 dev->em28xx_write_regs(dev, 0x04, &gpio4, 1);
521                                 msleep(140);      521                                 msleep(140);
522                         }                         522                         }
523                                                   523 
524                         msleep(6);                524                         msleep(6);
525                         dev->em28xx_write_regs    525                         dev->em28xx_write_regs(dev, 0x08, &gpio0, 1);
526                         msleep(10);               526                         msleep(10);
527                         dev->em28xx_write_regs    527                         dev->em28xx_write_regs(dev, 0x08, &gpio1, 1);
528                         msleep(5);                528                         msleep(5);
529                 }                                 529                 }
530                                                   530 
531                 break;                            531                 break;
532         }                                         532         }
533         }                                         533         }
534         return rc;                                534         return rc;
535 }                                                 535 }
536                                                   536 
537 static void em28xx_config_tuner(struct em28xx     537 static void em28xx_config_tuner(struct em28xx *dev)
538 {                                                 538 {
539         struct v4l2_priv_tun_config  xc2028_cf    539         struct v4l2_priv_tun_config  xc2028_cfg;
540         struct xc2028_ctrl           ctl;         540         struct xc2028_ctrl           ctl;
541         struct tuner_setup           tun_setup    541         struct tuner_setup           tun_setup;
542         struct v4l2_frequency        f;           542         struct v4l2_frequency        f;
543                                                   543 
544         if (dev->tuner_type == TUNER_ABSENT)      544         if (dev->tuner_type == TUNER_ABSENT)
545                 return;                           545                 return;
546                                                   546 
547         tun_setup.mode_mask = T_ANALOG_TV | T_    547         tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
548         tun_setup.type = dev->tuner_type;         548         tun_setup.type = dev->tuner_type;
549         tun_setup.addr = dev->tuner_addr;         549         tun_setup.addr = dev->tuner_addr;
550         tun_setup.tuner_callback = em28xx_tune    550         tun_setup.tuner_callback = em28xx_tuner_callback;
551                                                   551 
552         em28xx_i2c_call_clients(dev, TUNER_SET    552         em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
553                                                   553 
554         if (dev->tuner_type == TUNER_XC2028) {    554         if (dev->tuner_type == TUNER_XC2028) {
555                 memset(&ctl, 0, sizeof(ctl));     555                 memset(&ctl, 0, sizeof(ctl));
556                                                   556 
557                 ctl.fname   = XC2028_DEFAULT_F    557                 ctl.fname   = XC2028_DEFAULT_FIRMWARE;
558                 ctl.max_len = 64;                 558                 ctl.max_len = 64;
559                 ctl.mts = em28xx_boards[dev->m    559                 ctl.mts = em28xx_boards[dev->model].mts_firmware;
560                                                   560 
561                 xc2028_cfg.tuner = TUNER_XC202    561                 xc2028_cfg.tuner = TUNER_XC2028;
562                 xc2028_cfg.priv  = &ctl;          562                 xc2028_cfg.priv  = &ctl;
563                                                   563 
564                 em28xx_i2c_call_clients(dev, T    564                 em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
565         }                                         565         }
566                                                   566 
567         /* configure tuner */                     567         /* configure tuner */
568         f.tuner = 0;                              568         f.tuner = 0;
569         f.type = V4L2_TUNER_ANALOG_TV;            569         f.type = V4L2_TUNER_ANALOG_TV;
570         f.frequency = 9076;     /* just a magi    570         f.frequency = 9076;     /* just a magic number */
571         dev->ctl_freq = f.frequency;              571         dev->ctl_freq = f.frequency;
572         em28xx_i2c_call_clients(dev, VIDIOC_S_    572         em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
573 }                                                 573 }
574                                                   574 
575 static int em28xx_hint_board(struct em28xx *de    575 static int em28xx_hint_board(struct em28xx *dev)
576 {                                                 576 {
577         int i;                                    577         int i;
578                                                   578 
579         /* HINT method: EEPROM                    579         /* HINT method: EEPROM
580          *                                        580          *
581          * This method works only for boards w    581          * This method works only for boards with eeprom.
582          * Uses a hash of all eeprom bytes. Th    582          * Uses a hash of all eeprom bytes. The hash should be
583          * unique for a vendor/tuner pair.        583          * unique for a vendor/tuner pair.
584          * There are a high chance that tuners    584          * There are a high chance that tuners for different
585          * video standards produce different h    585          * video standards produce different hashes.
586          */                                       586          */
587         for (i = 0; i < ARRAY_SIZE(em28xx_eepr    587         for (i = 0; i < ARRAY_SIZE(em28xx_eeprom_hash); i++) {
588                 if (dev->hash == em28xx_eeprom    588                 if (dev->hash == em28xx_eeprom_hash[i].hash) {
589                         dev->model = em28xx_ee    589                         dev->model = em28xx_eeprom_hash[i].model;
590                         dev->tuner_type = em28    590                         dev->tuner_type = em28xx_eeprom_hash[i].tuner;
591                                                   591 
592                         em28xx_errdev("Your bo    592                         em28xx_errdev("Your board has no unique USB ID.\n");
593                         em28xx_errdev("A hint     593                         em28xx_errdev("A hint were successfully done, "
594                                       "based o    594                                       "based on eeprom hash.\n");
595                         em28xx_errdev("This me    595                         em28xx_errdev("This method is not 100%% failproof.\n");
596                         em28xx_errdev("If the     596                         em28xx_errdev("If the board were missdetected, "
597                                       "please     597                                       "please email this log to:\n");
598                         em28xx_errdev("\tV4L M    598                         em28xx_errdev("\tV4L Mailing List "
599                                       " <video    599                                       " <video4linux-list@redhat.com>\n");
600                         em28xx_errdev("Board d    600                         em28xx_errdev("Board detected as %s\n",
601                                       em28xx_b    601                                       em28xx_boards[dev->model].name);
602                                                   602 
603                         return 0;                 603                         return 0;
604                 }                                 604                 }
605         }                                         605         }
606                                                   606 
607         /* HINT method: I2C attached devices      607         /* HINT method: I2C attached devices
608          *                                        608          *
609          * This method works for all boards.      609          * This method works for all boards.
610          * Uses a hash of i2c scanned devices.    610          * Uses a hash of i2c scanned devices.
611          * Devices with the same i2c attached     611          * Devices with the same i2c attached chips will
612          * be considered equal.                   612          * be considered equal.
613          * This method is less precise than th    613          * This method is less precise than the eeprom one.
614          */                                       614          */
615                                                   615 
616         /* user did not request i2c scanning =    616         /* user did not request i2c scanning => do it now */
617         if (!dev->i2c_hash)                       617         if (!dev->i2c_hash)
618                 em28xx_do_i2c_scan(dev);          618                 em28xx_do_i2c_scan(dev);
619                                                   619 
620         for (i = 0; i < ARRAY_SIZE(em28xx_i2c_    620         for (i = 0; i < ARRAY_SIZE(em28xx_i2c_hash); i++) {
621                 if (dev->i2c_hash == em28xx_i2    621                 if (dev->i2c_hash == em28xx_i2c_hash[i].hash) {
622                         dev->model = em28xx_i2    622                         dev->model = em28xx_i2c_hash[i].model;
623                         dev->tuner_type = em28    623                         dev->tuner_type = em28xx_i2c_hash[i].tuner;
624                         em28xx_errdev("Your bo    624                         em28xx_errdev("Your board has no unique USB ID.\n");
625                         em28xx_errdev("A hint     625                         em28xx_errdev("A hint were successfully done, "
626                                       "based o    626                                       "based on i2c devicelist hash.\n");
627                         em28xx_errdev("This me    627                         em28xx_errdev("This method is not 100%% failproof.\n");
628                         em28xx_errdev("If the     628                         em28xx_errdev("If the board were missdetected, "
629                                       "please     629                                       "please email this log to:\n");
630                         em28xx_errdev("\tV4L M    630                         em28xx_errdev("\tV4L Mailing List "
631                                       " <video    631                                       " <video4linux-list@redhat.com>\n");
632                         em28xx_errdev("Board d    632                         em28xx_errdev("Board detected as %s\n",
633                                       em28xx_b    633                                       em28xx_boards[dev->model].name);
634                                                   634 
635                         return 0;                 635                         return 0;
636                 }                                 636                 }
637         }                                         637         }
638                                                   638 
639         em28xx_errdev("Your board has no uniqu    639         em28xx_errdev("Your board has no unique USB ID and thus need a "
640                       "hint to be detected.\n"    640                       "hint to be detected.\n");
641         em28xx_errdev("You may try to use card    641         em28xx_errdev("You may try to use card=<n> insmod option to "
642                       "workaround that.\n");      642                       "workaround that.\n");
643         em28xx_errdev("Please send an email wi    643         em28xx_errdev("Please send an email with this log to:\n");
644         em28xx_errdev("\tV4L Mailing List <vid    644         em28xx_errdev("\tV4L Mailing List <video4linux-list@redhat.com>\n");
645         em28xx_errdev("Board eeprom hash is 0x    645         em28xx_errdev("Board eeprom hash is 0x%08lx\n", dev->hash);
646         em28xx_errdev("Board i2c devicelist ha    646         em28xx_errdev("Board i2c devicelist hash is 0x%08lx\n", dev->i2c_hash);
647                                                   647 
648         em28xx_errdev("Here is a list of valid    648         em28xx_errdev("Here is a list of valid choices for the card=<n>"
649                       " insmod option:\n");       649                       " insmod option:\n");
650         for (i = 0; i < em28xx_bcount; i++) {     650         for (i = 0; i < em28xx_bcount; i++) {
651                 em28xx_errdev("    card=%d ->     651                 em28xx_errdev("    card=%d -> %s\n",
652                                 i, em28xx_boar    652                                 i, em28xx_boards[i].name);
653         }                                         653         }
654         return -1;                                654         return -1;
655 }                                                 655 }
656                                                   656 
657                                                   657 
658 static void em28xx_set_model(struct em28xx *de    658 static void em28xx_set_model(struct em28xx *dev)
659 {                                                 659 {
660         dev->is_em2800 = em28xx_boards[dev->mo    660         dev->is_em2800 = em28xx_boards[dev->model].is_em2800;
661         dev->has_msp34xx = em28xx_boards[dev->    661         dev->has_msp34xx = em28xx_boards[dev->model].has_msp34xx;
662         dev->tda9887_conf = em28xx_boards[dev-    662         dev->tda9887_conf = em28xx_boards[dev->model].tda9887_conf;
663         dev->decoder = em28xx_boards[dev->mode    663         dev->decoder = em28xx_boards[dev->model].decoder;
664         dev->video_inputs = em28xx_boards[dev-    664         dev->video_inputs = em28xx_boards[dev->model].vchannels;
665         dev->analog_gpio = em28xx_boards[dev->    665         dev->analog_gpio = em28xx_boards[dev->model].analog_gpio;
666         dev->has_12mhz_i2s = em28xx_boards[dev    666         dev->has_12mhz_i2s = em28xx_boards[dev->model].has_12mhz_i2s;
667         dev->max_range_640_480 = em28xx_boards    667         dev->max_range_640_480 = em28xx_boards[dev->model].max_range_640_480;
668 }                                                 668 }
669                                                   669 
670 /* -------------------------------------------    670 /* ----------------------------------------------------------------------- */
671 void em28xx_set_ir(struct em28xx *dev, struct     671 void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
672 {                                                 672 {
673         if (disable_ir) {                         673         if (disable_ir) {
674                 ir->get_key = NULL;               674                 ir->get_key = NULL;
675                 return ;                          675                 return ;
676         }                                         676         }
677                                                   677 
678         /* detect & configure */                  678         /* detect & configure */
679         switch (dev->model) {                     679         switch (dev->model) {
680         case (EM2800_BOARD_UNKNOWN):              680         case (EM2800_BOARD_UNKNOWN):
681                 break;                            681                 break;
682         case (EM2820_BOARD_UNKNOWN):              682         case (EM2820_BOARD_UNKNOWN):
683                 break;                            683                 break;
684         case (EM2800_BOARD_TERRATEC_CINERGY_20    684         case (EM2800_BOARD_TERRATEC_CINERGY_200):
685         case (EM2820_BOARD_TERRATEC_CINERGY_25    685         case (EM2820_BOARD_TERRATEC_CINERGY_250):
686                 ir->ir_codes = ir_codes_em_ter    686                 ir->ir_codes = ir_codes_em_terratec;
687                 ir->get_key = em28xx_get_key_t    687                 ir->get_key = em28xx_get_key_terratec;
688                 snprintf(ir->c.name, sizeof(ir    688                 snprintf(ir->c.name, sizeof(ir->c.name),
689                          "i2c IR (EM28XX Terra    689                          "i2c IR (EM28XX Terratec)");
690                 break;                            690                 break;
691         case (EM2820_BOARD_PINNACLE_USB_2):       691         case (EM2820_BOARD_PINNACLE_USB_2):
692                 ir->ir_codes = ir_codes_pinnac    692                 ir->ir_codes = ir_codes_pinnacle_grey;
693                 ir->get_key = em28xx_get_key_p    693                 ir->get_key = em28xx_get_key_pinnacle_usb_grey;
694                 snprintf(ir->c.name, sizeof(ir    694                 snprintf(ir->c.name, sizeof(ir->c.name),
695                          "i2c IR (EM28XX Pinna    695                          "i2c IR (EM28XX Pinnacle PCTV)");
696                 break;                            696                 break;
697         case (EM2820_BOARD_HAUPPAUGE_WINTV_USB    697         case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
698                 ir->ir_codes = ir_codes_hauppa    698                 ir->ir_codes = ir_codes_hauppauge_new;
699                 ir->get_key = em28xx_get_key_e    699                 ir->get_key = em28xx_get_key_em_haup;
700                 snprintf(ir->c.name, sizeof(ir    700                 snprintf(ir->c.name, sizeof(ir->c.name),
701                          "i2c IR (EM2840 Haupp    701                          "i2c IR (EM2840 Hauppauge)");
702                 break;                            702                 break;
703         case (EM2820_BOARD_MSI_VOX_USB_2):        703         case (EM2820_BOARD_MSI_VOX_USB_2):
704                 break;                            704                 break;
705         case (EM2800_BOARD_LEADTEK_WINFAST_USB    705         case (EM2800_BOARD_LEADTEK_WINFAST_USBII):
706                 break;                            706                 break;
707         case (EM2800_BOARD_KWORLD_USB2800):       707         case (EM2800_BOARD_KWORLD_USB2800):
708                 break;                            708                 break;
709         }                                         709         }
710 }                                                 710 }
711                                                   711 
712 void em28xx_card_setup(struct em28xx *dev)        712 void em28xx_card_setup(struct em28xx *dev)
713 {                                                 713 {
714         em28xx_set_model(dev);                    714         em28xx_set_model(dev);
715                                                   715 
716         dev->tuner_type = em28xx_boards[dev->m    716         dev->tuner_type = em28xx_boards[dev->model].tuner_type;
717                                                   717 
718         /* request some modules */                718         /* request some modules */
719         switch (dev->model) {                     719         switch (dev->model) {
720         case EM2820_BOARD_HAUPPAUGE_WINTV_USB_    720         case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
721         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_    721         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900:
722         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_    722         case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_950:
723         {                                         723         {
724                 struct tveeprom tv;               724                 struct tveeprom tv;
725 #ifdef CONFIG_MODULES                             725 #ifdef CONFIG_MODULES
726                 request_module("tveeprom");       726                 request_module("tveeprom");
727 #endif                                            727 #endif
728                 /* Call first TVeeprom */         728                 /* Call first TVeeprom */
729                                                   729 
730                 dev->i2c_client.addr = 0xa0 >>    730                 dev->i2c_client.addr = 0xa0 >> 1;
731                 tveeprom_hauppauge_analog(&dev    731                 tveeprom_hauppauge_analog(&dev->i2c_client, &tv, dev->eedata);
732                                                   732 
733                 dev->tuner_type = tv.tuner_typ    733                 dev->tuner_type = tv.tuner_type;
734                                                   734 
735                 if (tv.audio_processor == AUDI    735                 if (tv.audio_processor == AUDIO_CHIP_MSP34XX) {
736                         dev->i2s_speed = 20480    736                         dev->i2s_speed = 2048000;
737                         dev->has_msp34xx = 1;     737                         dev->has_msp34xx = 1;
738                 }                                 738                 }
739 #ifdef CONFIG_MODULES                             739 #ifdef CONFIG_MODULES
740                 if (tv.has_ir)                    740                 if (tv.has_ir)
741                         request_module("ir-kbd    741                         request_module("ir-kbd-i2c");
742 #endif                                            742 #endif
743                 break;                            743                 break;
744         }                                         744         }
745         case EM2820_BOARD_KWORLD_PVRTV2800RF:     745         case EM2820_BOARD_KWORLD_PVRTV2800RF:
746                 /* GPIO enables sound on KWORL    746                 /* GPIO enables sound on KWORLD PVR TV 2800RF */
747                 em28xx_write_regs_req(dev, 0x0    747                 em28xx_write_regs_req(dev, 0x00, 0x08, "\xf9", 1);
748                 break;                            748                 break;
749         case EM2820_BOARD_UNKNOWN:                749         case EM2820_BOARD_UNKNOWN:
750         case EM2800_BOARD_UNKNOWN:                750         case EM2800_BOARD_UNKNOWN:
751                 if (!em28xx_hint_board(dev))      751                 if (!em28xx_hint_board(dev))
752                         em28xx_set_model(dev);    752                         em28xx_set_model(dev);
753         }                                         753         }
754                                                   754 
755         /* Allow override tuner type by a modu    755         /* Allow override tuner type by a module parameter */
756         if (tuner >= 0)                           756         if (tuner >= 0)
757                 dev->tuner_type = tuner;          757                 dev->tuner_type = tuner;
758                                                   758 
759 #ifdef CONFIG_MODULES                             759 #ifdef CONFIG_MODULES
760         /* request some modules */                760         /* request some modules */
761         if (dev->has_msp34xx)                     761         if (dev->has_msp34xx)
762                 request_module("msp3400");        762                 request_module("msp3400");
763         if (dev->decoder == EM28XX_SAA7113 ||     763         if (dev->decoder == EM28XX_SAA7113 || dev->decoder == EM28XX_SAA7114)
764                 request_module("saa7115");        764                 request_module("saa7115");
765         if (dev->decoder == EM28XX_TVP5150)       765         if (dev->decoder == EM28XX_TVP5150)
766                 request_module("tvp5150");        766                 request_module("tvp5150");
767         if (dev->tuner_type != TUNER_ABSENT)      767         if (dev->tuner_type != TUNER_ABSENT)
768                 request_module("tuner");          768                 request_module("tuner");
769 #endif                                            769 #endif
770                                                   770 
771         em28xx_config_tuner(dev);                 771         em28xx_config_tuner(dev);
772 }                                                 772 }
773                                                   773 
  This page was automatically generated by the LXR engine.