1 /* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/ 2 * Typhoon/ Yuan/ Miglia DVB-T USB2.0 receiver. 3 * 4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@posteo.de) 5 * 6 * Thanks to Steve Chang from WideView for providing support for the WT-220U. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the Free 10 * Software Foundation, version 2. 11 * 12 * see Documentation/dvb/README.dvb-usb for more information 13 */ 14 #include "dtt200u.h" 15 16 /* debug */ 17 int dvb_usb_dtt200u_debug; 18 module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644); 19 MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS); 20 21 DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 22 23 static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff) 24 { 25 u8 b = SET_INIT; 26 27 if (onoff) 28 dvb_usb_generic_write(d,&b,2); 29 30 return 0; 31 } 32 33 static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 34 { 35 u8 b_streaming[2] = { SET_STREAMING, onoff }; 36 u8 b_rst_pid = RESET_PID_FILTER; 37 38 dvb_usb_generic_write(adap->dev, b_streaming, 2); 39 40 if (onoff == 0) 41 dvb_usb_generic_write(adap->dev, &b_rst_pid, 1); 42 return 0; 43 } 44 45 static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff) 46 { 47 u8 b_pid[4]; 48 pid = onoff ? pid : 0; 49 50 b_pid[0] = SET_PID_FILTER; 51 b_pid[1] = index; 52 b_pid[2] = pid & 0xff; 53 b_pid[3] = (pid >> 8) & 0x1f; 54 55 return dvb_usb_generic_write(adap->dev, b_pid, 4); 56 } 57 58 static int dtt200u_rc_query(struct dvb_usb_device *d) 59 { 60 u8 key[5],cmd = GET_RC_CODE; 61 u32 scancode; 62 63 dvb_usb_generic_rw(d,&cmd,1,key,5,0); 64 if (key[0] == 1) { 65 scancode = key[1]; 66 if ((u8) ~key[1] != key[2]) { 67 /* Extended NEC */ 68 scancode = scancode << 8; 69 scancode |= key[2]; 70 } 71 scancode = scancode << 8; 72 scancode |= key[3]; 73 74 /* Check command checksum is ok */ 75 if ((u8) ~key[3] == key[4]) 76 rc_keydown(d->rc_dev, RC_TYPE_NEC, scancode, 0); 77 else 78 rc_keyup(d->rc_dev); 79 } else if (key[0] == 2) { 80 rc_repeat(d->rc_dev); 81 } else { 82 rc_keyup(d->rc_dev); 83 } 84 85 if (key[0] != 0) 86 deb_info("key: %*ph\n", 5, key); 87 88 return 0; 89 } 90 91 static int dtt200u_frontend_attach(struct dvb_usb_adapter *adap) 92 { 93 adap->fe_adap[0].fe = dtt200u_fe_attach(adap->dev); 94 return 0; 95 } 96 97 static struct dvb_usb_device_properties dtt200u_properties; 98 static struct dvb_usb_device_properties wt220u_fc_properties; 99 static struct dvb_usb_device_properties wt220u_properties; 100 static struct dvb_usb_device_properties wt220u_zl0353_properties; 101 static struct dvb_usb_device_properties wt220u_miglia_properties; 102 103 static int dtt200u_usb_probe(struct usb_interface *intf, 104 const struct usb_device_id *id) 105 { 106 if (0 == dvb_usb_device_init(intf, &dtt200u_properties, 107 THIS_MODULE, NULL, adapter_nr) || 108 0 == dvb_usb_device_init(intf, &wt220u_properties, 109 THIS_MODULE, NULL, adapter_nr) || 110 0 == dvb_usb_device_init(intf, &wt220u_fc_properties, 111 THIS_MODULE, NULL, adapter_nr) || 112 0 == dvb_usb_device_init(intf, &wt220u_zl0353_properties, 113 THIS_MODULE, NULL, adapter_nr) || 114 0 == dvb_usb_device_init(intf, &wt220u_miglia_properties, 115 THIS_MODULE, NULL, adapter_nr)) 116 return 0; 117 118 return -ENODEV; 119 } 120 121 static struct usb_device_id dtt200u_usb_table [] = { 122 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) }, 123 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) }, 124 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) }, 125 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) }, 126 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_COLD) }, 127 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_WARM) }, 128 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_COLD) }, 129 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_WARM) }, 130 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZAP250_COLD) }, 131 { USB_DEVICE(USB_VID_MIGLIA, USB_PID_WT220U_ZAP250_COLD) }, 132 { 0 }, 133 }; 134 MODULE_DEVICE_TABLE(usb, dtt200u_usb_table); 135 136 static struct dvb_usb_device_properties dtt200u_properties = { 137 .usb_ctrl = CYPRESS_FX2, 138 .firmware = "dvb-usb-dtt200u-01.fw", 139 140 .num_adapters = 1, 141 .adapter = { 142 { 143 .num_frontends = 1, 144 .fe = {{ 145 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, 146 .pid_filter_count = 15, 147 148 .streaming_ctrl = dtt200u_streaming_ctrl, 149 .pid_filter = dtt200u_pid_filter, 150 .frontend_attach = dtt200u_frontend_attach, 151 /* parameter for the MPEG2-data transfer */ 152 .stream = { 153 .type = USB_BULK, 154 .count = 7, 155 .endpoint = 0x02, 156 .u = { 157 .bulk = { 158 .buffersize = 4096, 159 } 160 } 161 }, 162 }}, 163 } 164 }, 165 .power_ctrl = dtt200u_power_ctrl, 166 167 .rc.core = { 168 .rc_interval = 300, 169 .rc_codes = RC_MAP_DTT200U, 170 .rc_query = dtt200u_rc_query, 171 .allowed_protos = RC_BIT_NEC, 172 }, 173 174 .generic_bulk_ctrl_endpoint = 0x01, 175 176 .num_device_descs = 1, 177 .devices = { 178 { .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)", 179 .cold_ids = { &dtt200u_usb_table[0], NULL }, 180 .warm_ids = { &dtt200u_usb_table[1], NULL }, 181 }, 182 { NULL }, 183 } 184 }; 185 186 static struct dvb_usb_device_properties wt220u_properties = { 187 .usb_ctrl = CYPRESS_FX2, 188 .firmware = "dvb-usb-wt220u-02.fw", 189 190 .num_adapters = 1, 191 .adapter = { 192 { 193 .num_frontends = 1, 194 .fe = {{ 195 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, 196 .pid_filter_count = 15, 197 198 .streaming_ctrl = dtt200u_streaming_ctrl, 199 .pid_filter = dtt200u_pid_filter, 200 .frontend_attach = dtt200u_frontend_attach, 201 /* parameter for the MPEG2-data transfer */ 202 .stream = { 203 .type = USB_BULK, 204 .count = 7, 205 .endpoint = 0x02, 206 .u = { 207 .bulk = { 208 .buffersize = 4096, 209 } 210 } 211 }, 212 }}, 213 } 214 }, 215 .power_ctrl = dtt200u_power_ctrl, 216 217 .rc.core = { 218 .rc_interval = 300, 219 .rc_codes = RC_MAP_DTT200U, 220 .rc_query = dtt200u_rc_query, 221 .allowed_protos = RC_BIT_NEC, 222 }, 223 224 .generic_bulk_ctrl_endpoint = 0x01, 225 226 .num_device_descs = 1, 227 .devices = { 228 { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)", 229 .cold_ids = { &dtt200u_usb_table[2], &dtt200u_usb_table[8], NULL }, 230 .warm_ids = { &dtt200u_usb_table[3], NULL }, 231 }, 232 { NULL }, 233 } 234 }; 235 236 static struct dvb_usb_device_properties wt220u_fc_properties = { 237 .usb_ctrl = CYPRESS_FX2, 238 .firmware = "dvb-usb-wt220u-fc03.fw", 239 240 .num_adapters = 1, 241 .adapter = { 242 { 243 .num_frontends = 1, 244 .fe = {{ 245 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, 246 .pid_filter_count = 15, 247 248 .streaming_ctrl = dtt200u_streaming_ctrl, 249 .pid_filter = dtt200u_pid_filter, 250 .frontend_attach = dtt200u_frontend_attach, 251 /* parameter for the MPEG2-data transfer */ 252 .stream = { 253 .type = USB_BULK, 254 .count = 7, 255 .endpoint = 0x06, 256 .u = { 257 .bulk = { 258 .buffersize = 4096, 259 } 260 } 261 }, 262 }}, 263 } 264 }, 265 .power_ctrl = dtt200u_power_ctrl, 266 267 .rc.core = { 268 .rc_interval = 300, 269 .rc_codes = RC_MAP_DTT200U, 270 .rc_query = dtt200u_rc_query, 271 .allowed_protos = RC_BIT_NEC, 272 }, 273 274 .generic_bulk_ctrl_endpoint = 0x01, 275 276 .num_device_descs = 1, 277 .devices = { 278 { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)", 279 .cold_ids = { &dtt200u_usb_table[6], NULL }, 280 .warm_ids = { &dtt200u_usb_table[7], NULL }, 281 }, 282 { NULL }, 283 } 284 }; 285 286 static struct dvb_usb_device_properties wt220u_zl0353_properties = { 287 .usb_ctrl = CYPRESS_FX2, 288 .firmware = "dvb-usb-wt220u-zl0353-01.fw", 289 290 .num_adapters = 1, 291 .adapter = { 292 { 293 .num_frontends = 1, 294 .fe = {{ 295 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, 296 .pid_filter_count = 15, 297 298 .streaming_ctrl = dtt200u_streaming_ctrl, 299 .pid_filter = dtt200u_pid_filter, 300 .frontend_attach = dtt200u_frontend_attach, 301 /* parameter for the MPEG2-data transfer */ 302 .stream = { 303 .type = USB_BULK, 304 .count = 7, 305 .endpoint = 0x02, 306 .u = { 307 .bulk = { 308 .buffersize = 4096, 309 } 310 } 311 }, 312 }}, 313 } 314 }, 315 .power_ctrl = dtt200u_power_ctrl, 316 317 .rc.core = { 318 .rc_interval = 300, 319 .rc_codes = RC_MAP_DTT200U, 320 .rc_query = dtt200u_rc_query, 321 .allowed_protos = RC_BIT_NEC, 322 }, 323 324 .generic_bulk_ctrl_endpoint = 0x01, 325 326 .num_device_descs = 1, 327 .devices = { 328 { .name = "WideView WT-220U PenType Receiver (based on ZL353)", 329 .cold_ids = { &dtt200u_usb_table[4], NULL }, 330 .warm_ids = { &dtt200u_usb_table[5], NULL }, 331 }, 332 { NULL }, 333 } 334 }; 335 336 static struct dvb_usb_device_properties wt220u_miglia_properties = { 337 .usb_ctrl = CYPRESS_FX2, 338 .firmware = "dvb-usb-wt220u-miglia-01.fw", 339 340 .num_adapters = 1, 341 .generic_bulk_ctrl_endpoint = 0x01, 342 343 .num_device_descs = 1, 344 .devices = { 345 { .name = "WideView WT-220U PenType Receiver (Miglia)", 346 .cold_ids = { &dtt200u_usb_table[9], NULL }, 347 /* This device turns into WT220U_ZL0353_WARM when fw 348 has been uploaded */ 349 .warm_ids = { NULL }, 350 }, 351 { NULL }, 352 } 353 }; 354 355 /* usb specific object needed to register this driver with the usb subsystem */ 356 static struct usb_driver dtt200u_usb_driver = { 357 .name = "dvb_usb_dtt200u", 358 .probe = dtt200u_usb_probe, 359 .disconnect = dvb_usb_device_exit, 360 .id_table = dtt200u_usb_table, 361 }; 362 363 module_usb_driver(dtt200u_usb_driver); 364 365 MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>"); 366 MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D/Miglia DVB-T USB2.0 devices"); 367 MODULE_VERSION("1.0"); 368 MODULE_LICENSE("GPL"); 369