1/* DVB USB library compliant Linux driver for the WideView/ Yakumo/ Hama/ 2 * Typhoon/ Yuan DVB-T USB2.0 receiver. 3 * 4 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.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 */ 17int dvb_usb_dtt200u_debug; 18module_param_named(debug,dvb_usb_dtt200u_debug, int, 0644); 19MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2 (or-able))." DVB_USB_DEBUG_STATUS); 20 21static int dtt200u_power_ctrl(struct dvb_usb_device *d, int onoff) 22{ 23 u8 b = SET_INIT; 24 25 if (onoff) 26 dvb_usb_generic_write(d,&b,2); 27 28 return 0; 29} 30 31static int dtt200u_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 32{ 33 u8 b_streaming[2] = { SET_STREAMING, onoff }; 34 u8 b_rst_pid = RESET_PID_FILTER; 35 36 dvb_usb_generic_write(adap->dev, b_streaming, 2); 37 38 if (onoff == 0) 39 dvb_usb_generic_write(adap->dev, &b_rst_pid, 1); 40 return 0; 41} 42 43static int dtt200u_pid_filter(struct dvb_usb_adapter *adap, int index, u16 pid, int onoff) 44{ 45 u8 b_pid[4]; 46 pid = onoff ? pid : 0; 47 48 b_pid[0] = SET_PID_FILTER; 49 b_pid[1] = index; 50 b_pid[2] = pid & 0xff; 51 b_pid[3] = (pid >> 8) & 0x1f; 52 53 return dvb_usb_generic_write(adap->dev, b_pid, 4); 54} 55 56/* remote control */ 57/* key list for the tiny remote control (Yakumo, don't know about the others) */ 58static struct dvb_usb_rc_key dtt200u_rc_keys[] = { 59 { 0x80, 0x01, KEY_MUTE }, 60 { 0x80, 0x02, KEY_CHANNELDOWN }, 61 { 0x80, 0x03, KEY_VOLUMEDOWN }, 62 { 0x80, 0x04, KEY_1 }, 63 { 0x80, 0x05, KEY_2 }, 64 { 0x80, 0x06, KEY_3 }, 65 { 0x80, 0x07, KEY_4 }, 66 { 0x80, 0x08, KEY_5 }, 67 { 0x80, 0x09, KEY_6 }, 68 { 0x80, 0x0a, KEY_7 }, 69 { 0x80, 0x0c, KEY_ZOOM }, 70 { 0x80, 0x0d, KEY_0 }, 71 { 0x80, 0x0e, KEY_SELECT }, 72 { 0x80, 0x12, KEY_POWER }, 73 { 0x80, 0x1a, KEY_CHANNELUP }, 74 { 0x80, 0x1b, KEY_8 }, 75 { 0x80, 0x1e, KEY_VOLUMEUP }, 76 { 0x80, 0x1f, KEY_9 }, 77}; 78 79static int dtt200u_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 80{ 81 u8 key[5],cmd = GET_RC_CODE; 82 dvb_usb_generic_rw(d,&cmd,1,key,5,0); 83 dvb_usb_nec_rc_key_to_event(d,key,event,state); 84 if (key[0] != 0) 85 deb_info("key: %x %x %x %x %x\n",key[0],key[1],key[2],key[3],key[4]); 86 return 0; 87} 88 89static int dtt200u_frontend_attach(struct dvb_usb_adapter *adap) 90{ 91 adap->fe = dtt200u_fe_attach(adap->dev); 92 return 0; 93} 94 95static struct dvb_usb_device_properties dtt200u_properties; 96static struct dvb_usb_device_properties wt220u_fc_properties; 97static struct dvb_usb_device_properties wt220u_properties; 98static struct dvb_usb_device_properties wt220u_zl0353_properties; 99 100static int dtt200u_usb_probe(struct usb_interface *intf, 101 const struct usb_device_id *id) 102{ 103 if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE,NULL) == 0 || 104 dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE,NULL) == 0 || 105 dvb_usb_device_init(intf,&wt220u_fc_properties,THIS_MODULE,NULL) == 0 || 106 dvb_usb_device_init(intf,&wt220u_zl0353_properties,THIS_MODULE,NULL) == 0) 107 return 0; 108 109 return -ENODEV; 110} 111 112static struct usb_device_id dtt200u_usb_table [] = { 113 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) }, 114 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) }, 115 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) }, 116 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) }, 117 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_COLD) }, 118 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZL0353_WARM) }, 119 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_COLD) }, 120 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_FC_WARM) }, 121 { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_ZAP250_COLD) }, 122 { 0 }, 123}; 124MODULE_DEVICE_TABLE(usb, dtt200u_usb_table); 125 126static struct dvb_usb_device_properties dtt200u_properties = { 127 .usb_ctrl = CYPRESS_FX2, 128 .firmware = "dvb-usb-dtt200u-01.fw", 129 130 .num_adapters = 1, 131 .adapter = { 132 { 133 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, 134 .pid_filter_count = 15, 135 136 .streaming_ctrl = dtt200u_streaming_ctrl, 137 .pid_filter = dtt200u_pid_filter, 138 .frontend_attach = dtt200u_frontend_attach, 139 /* parameter for the MPEG2-data transfer */ 140 .stream = { 141 .type = USB_BULK, 142 .count = 7, 143 .endpoint = 0x02, 144 .u = { 145 .bulk = { 146 .buffersize = 4096, 147 } 148 } 149 }, 150 } 151 }, 152 .power_ctrl = dtt200u_power_ctrl, 153 154 .rc_interval = 300, 155 .rc_key_map = dtt200u_rc_keys, 156 .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), 157 .rc_query = dtt200u_rc_query, 158 159 .generic_bulk_ctrl_endpoint = 0x01, 160 161 .num_device_descs = 1, 162 .devices = { 163 { .name = "WideView/Yuan/Yakumo/Hama/Typhoon DVB-T USB2.0 (WT-200U)", 164 .cold_ids = { &dtt200u_usb_table[0], NULL }, 165 .warm_ids = { &dtt200u_usb_table[1], NULL }, 166 }, 167 { NULL }, 168 } 169}; 170 171static struct dvb_usb_device_properties wt220u_properties = { 172 .usb_ctrl = CYPRESS_FX2, 173 .firmware = "dvb-usb-wt220u-02.fw", 174 175 .num_adapters = 1, 176 .adapter = { 177 { 178 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, 179 .pid_filter_count = 15, 180 181 .streaming_ctrl = dtt200u_streaming_ctrl, 182 .pid_filter = dtt200u_pid_filter, 183 .frontend_attach = dtt200u_frontend_attach, 184 /* parameter for the MPEG2-data transfer */ 185 .stream = { 186 .type = USB_BULK, 187 .count = 7, 188 .endpoint = 0x02, 189 .u = { 190 .bulk = { 191 .buffersize = 4096, 192 } 193 } 194 }, 195 } 196 }, 197 .power_ctrl = dtt200u_power_ctrl, 198 199 .rc_interval = 300, 200 .rc_key_map = dtt200u_rc_keys, 201 .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), 202 .rc_query = dtt200u_rc_query, 203 204 .generic_bulk_ctrl_endpoint = 0x01, 205 206 .num_device_descs = 1, 207 .devices = { 208 { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)", 209 .cold_ids = { &dtt200u_usb_table[2], &dtt200u_usb_table[8], NULL }, 210 .warm_ids = { &dtt200u_usb_table[3], NULL }, 211 }, 212 { NULL }, 213 } 214}; 215 216static struct dvb_usb_device_properties wt220u_fc_properties = { 217 .usb_ctrl = CYPRESS_FX2, 218 .firmware = "dvb-usb-wt220u-fc03.fw", 219 220 .num_adapters = 1, 221 .adapter = { 222 { 223 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, 224 .pid_filter_count = 15, 225 226 .streaming_ctrl = dtt200u_streaming_ctrl, 227 .pid_filter = dtt200u_pid_filter, 228 .frontend_attach = dtt200u_frontend_attach, 229 /* parameter for the MPEG2-data transfer */ 230 .stream = { 231 .type = USB_BULK, 232 .count = 7, 233 .endpoint = 0x06, 234 .u = { 235 .bulk = { 236 .buffersize = 4096, 237 } 238 } 239 }, 240 } 241 }, 242 .power_ctrl = dtt200u_power_ctrl, 243 244 .rc_interval = 300, 245 .rc_key_map = dtt200u_rc_keys, 246 .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), 247 .rc_query = dtt200u_rc_query, 248 249 .generic_bulk_ctrl_endpoint = 0x01, 250 251 .num_device_descs = 1, 252 .devices = { 253 { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)", 254 .cold_ids = { &dtt200u_usb_table[6], NULL }, 255 .warm_ids = { &dtt200u_usb_table[7], NULL }, 256 }, 257 { NULL }, 258 } 259}; 260 261static struct dvb_usb_device_properties wt220u_zl0353_properties = { 262 .usb_ctrl = CYPRESS_FX2, 263 .firmware = "dvb-usb-wt220u-zl0353-01.fw", 264 265 .num_adapters = 1, 266 .adapter = { 267 { 268 .caps = DVB_USB_ADAP_HAS_PID_FILTER | DVB_USB_ADAP_NEED_PID_FILTERING, 269 .pid_filter_count = 15, 270 271 .streaming_ctrl = dtt200u_streaming_ctrl, 272 .pid_filter = dtt200u_pid_filter, 273 .frontend_attach = dtt200u_frontend_attach, 274 /* parameter for the MPEG2-data transfer */ 275 .stream = { 276 .type = USB_BULK, 277 .count = 7, 278 .endpoint = 0x02, 279 .u = { 280 .bulk = { 281 .buffersize = 4096, 282 } 283 } 284 }, 285 } 286 }, 287 .power_ctrl = dtt200u_power_ctrl, 288 289 .rc_interval = 300, 290 .rc_key_map = dtt200u_rc_keys, 291 .rc_key_map_size = ARRAY_SIZE(dtt200u_rc_keys), 292 .rc_query = dtt200u_rc_query, 293 294 .generic_bulk_ctrl_endpoint = 0x01, 295 296 .num_device_descs = 1, 297 .devices = { 298 { .name = "WideView WT-220U PenType Receiver (based on ZL353)", 299 .cold_ids = { &dtt200u_usb_table[4], NULL }, 300 .warm_ids = { &dtt200u_usb_table[5], NULL }, 301 }, 302 { NULL }, 303 } 304}; 305 306/* usb specific object needed to register this driver with the usb subsystem */ 307static struct usb_driver dtt200u_usb_driver = { 308 .name = "dvb_usb_dtt200u", 309 .probe = dtt200u_usb_probe, 310 .disconnect = dvb_usb_device_exit, 311 .id_table = dtt200u_usb_table, 312}; 313 314/* module stuff */ 315static int __init dtt200u_usb_module_init(void) 316{ 317 int result; 318 if ((result = usb_register(&dtt200u_usb_driver))) { 319 err("usb_register failed. (%d)",result); 320 return result; 321 } 322 323 return 0; 324} 325 326static void __exit dtt200u_usb_module_exit(void) 327{ 328 /* deregister this driver from the USB subsystem */ 329 usb_deregister(&dtt200u_usb_driver); 330} 331 332module_init(dtt200u_usb_module_init); 333module_exit(dtt200u_usb_module_exit); 334 335MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); 336MODULE_DESCRIPTION("Driver for the WideView/Yakumo/Hama/Typhoon/Club3D DVB-T USB2.0 devices"); 337MODULE_VERSION("1.0"); 338MODULE_LICENSE("GPL"); 339