1/* 2 tm6000-dvb.c - dvb-t support for TM5600/TM6000/TM6010 USB video capture devices 3 4 Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation version 2 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 */ 19 20#include <linux/kernel.h> 21#include <linux/slab.h> 22#include <linux/usb.h> 23 24#include "tm6000.h" 25#include "tm6000-regs.h" 26 27#include "zl10353.h" 28 29#include <media/tuner.h> 30 31#include "tuner-xc2028.h" 32#include "xc5000.h" 33 34MODULE_DESCRIPTION("DVB driver extension module for tm5600/6000/6010 based TV cards"); 35MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); 36MODULE_LICENSE("GPL"); 37 38MODULE_SUPPORTED_DEVICE("{{Trident, tm5600}," 39 "{{Trident, tm6000}," 40 "{{Trident, tm6010}"); 41 42static int debug; 43 44module_param(debug, int, 0644); 45MODULE_PARM_DESC(debug, "enable debug message"); 46 47static inline void print_err_status(struct tm6000_core *dev, 48 int packet, int status) 49{ 50 char *errmsg = "Unknown"; 51 52 switch (status) { 53 case -ENOENT: 54 errmsg = "unlinked synchronuously"; 55 break; 56 case -ECONNRESET: 57 errmsg = "unlinked asynchronuously"; 58 break; 59 case -ENOSR: 60 errmsg = "Buffer error (overrun)"; 61 break; 62 case -EPIPE: 63 errmsg = "Stalled (device not responding)"; 64 break; 65 case -EOVERFLOW: 66 errmsg = "Babble (bad cable?)"; 67 break; 68 case -EPROTO: 69 errmsg = "Bit-stuff error (bad cable?)"; 70 break; 71 case -EILSEQ: 72 errmsg = "CRC/Timeout (could be anything)"; 73 break; 74 case -ETIME: 75 errmsg = "Device does not respond"; 76 break; 77 } 78 if (packet < 0) { 79 dprintk(dev, 1, "URB status %d [%s].\n", 80 status, errmsg); 81 } else { 82 dprintk(dev, 1, "URB packet %d, status %d [%s].\n", 83 packet, status, errmsg); 84 } 85} 86 87static void tm6000_urb_received(struct urb *urb) 88{ 89 int ret; 90 struct tm6000_core *dev = urb->context; 91 92 if (urb->status != 0) 93 print_err_status(dev, 0, urb->status); 94 else if (urb->actual_length > 0) 95 dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer, 96 urb->actual_length); 97 98 if (dev->dvb->streams > 0) { 99 ret = usb_submit_urb(urb, GFP_ATOMIC); 100 if (ret < 0) { 101 printk(KERN_ERR "tm6000: error %s\n", __FUNCTION__); 102 kfree(urb->transfer_buffer); 103 usb_free_urb(urb); 104 } 105 } 106} 107 108int tm6000_start_stream(struct tm6000_core *dev) 109{ 110 int ret; 111 unsigned int pipe, size; 112 struct tm6000_dvb *dvb = dev->dvb; 113 114 printk(KERN_INFO "tm6000: got start stream request %s\n", __FUNCTION__); 115 116 if (dev->mode != TM6000_MODE_DIGITAL) { 117 tm6000_init_digital_mode(dev); 118 dev->mode = TM6000_MODE_DIGITAL; 119 } 120 121 dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL); 122 if (dvb->bulk_urb == NULL) { 123 printk(KERN_ERR "tm6000: couldn't allocate urb\n"); 124 return -ENOMEM; 125 } 126 127 pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in.endp->desc.bEndpointAddress 128 & USB_ENDPOINT_NUMBER_MASK); 129 130 size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe)); 131 size = size * 15; /* 512 x 8 or 12 or 15 */ 132 133 dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL); 134 if (dvb->bulk_urb->transfer_buffer == NULL) { 135 usb_free_urb(dvb->bulk_urb); 136 printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n"); 137 return -ENOMEM; 138 } 139 140 usb_fill_bulk_urb(dvb->bulk_urb, dev->udev, pipe, 141 dvb->bulk_urb->transfer_buffer, 142 size, 143 tm6000_urb_received, dev); 144 145 ret = usb_clear_halt(dev->udev, pipe); 146 if (ret < 0) { 147 printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n", 148 ret, __FUNCTION__); 149 return ret; 150 } else 151 printk(KERN_ERR "tm6000: pipe resetted\n"); 152 153/* mutex_lock(&tm6000_driver.open_close_mutex); */ 154 ret = usb_submit_urb(dvb->bulk_urb, GFP_KERNEL); 155 156/* mutex_unlock(&tm6000_driver.open_close_mutex); */ 157 if (ret) { 158 printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n", 159 ret); 160 161 kfree(dvb->bulk_urb->transfer_buffer); 162 usb_free_urb(dvb->bulk_urb); 163 return ret; 164 } 165 166 return 0; 167} 168 169void tm6000_stop_stream(struct tm6000_core *dev) 170{ 171 struct tm6000_dvb *dvb = dev->dvb; 172 173 if (dvb->bulk_urb) { 174 printk(KERN_INFO "urb killing\n"); 175 usb_kill_urb(dvb->bulk_urb); 176 printk(KERN_INFO "urb buffer free\n"); 177 kfree(dvb->bulk_urb->transfer_buffer); 178 usb_free_urb(dvb->bulk_urb); 179 dvb->bulk_urb = NULL; 180 } 181} 182 183int tm6000_start_feed(struct dvb_demux_feed *feed) 184{ 185 struct dvb_demux *demux = feed->demux; 186 struct tm6000_core *dev = demux->priv; 187 struct tm6000_dvb *dvb = dev->dvb; 188 printk(KERN_INFO "tm6000: got start feed request %s\n", __FUNCTION__); 189 190 mutex_lock(&dvb->mutex); 191 if (dvb->streams == 0) { 192 dvb->streams = 1; 193/* mutex_init(&tm6000_dev->streming_mutex); */ 194 tm6000_start_stream(dev); 195 } else 196 ++(dvb->streams); 197 mutex_unlock(&dvb->mutex); 198 199 return 0; 200} 201 202int tm6000_stop_feed(struct dvb_demux_feed *feed) 203{ 204 struct dvb_demux *demux = feed->demux; 205 struct tm6000_core *dev = demux->priv; 206 struct tm6000_dvb *dvb = dev->dvb; 207 208 printk(KERN_INFO "tm6000: got stop feed request %s\n", __FUNCTION__); 209 210 mutex_lock(&dvb->mutex); 211 212 printk(KERN_INFO "stream %#x\n", dvb->streams); 213 --(dvb->streams); 214 if (dvb->streams == 0) { 215 printk(KERN_INFO "stop stream\n"); 216 tm6000_stop_stream(dev); 217/* mutex_destroy(&tm6000_dev->streaming_mutex); */ 218 } 219 mutex_unlock(&dvb->mutex); 220/* mutex_destroy(&tm6000_dev->streaming_mutex); */ 221 222 return 0; 223} 224 225int tm6000_dvb_attach_frontend(struct tm6000_core *dev) 226{ 227 struct tm6000_dvb *dvb = dev->dvb; 228 229 if (dev->caps.has_zl10353) { 230 struct zl10353_config config = { 231 .demod_address = dev->demod_addr, 232 .no_tuner = 1, 233 .parallel_ts = 1, 234 .if2 = 45700, 235 .disable_i2c_gate_ctrl = 1, 236 }; 237 238 dvb->frontend = dvb_attach(zl10353_attach, &config, 239 &dev->i2c_adap); 240 } else { 241 printk(KERN_ERR "tm6000: no frontend defined for the device!\n"); 242 return -1; 243 } 244 245 return (!dvb->frontend) ? -1 : 0; 246} 247 248DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 249 250int register_dvb(struct tm6000_core *dev) 251{ 252 int ret = -1; 253 struct tm6000_dvb *dvb = dev->dvb; 254 255 mutex_init(&dvb->mutex); 256 257 dvb->streams = 0; 258 259 /* attach the frontend */ 260 ret = tm6000_dvb_attach_frontend(dev); 261 if (ret < 0) { 262 printk(KERN_ERR "tm6000: couldn't attach the frontend!\n"); 263 goto err; 264 } 265 266 ret = dvb_register_adapter(&dvb->adapter, "Trident TVMaster 6000 DVB-T", 267 THIS_MODULE, &dev->udev->dev, adapter_nr); 268 dvb->adapter.priv = dev; 269 270 if (dvb->frontend) { 271 switch (dev->tuner_type) { 272 case TUNER_XC2028: { 273 struct xc2028_config cfg = { 274 .i2c_adap = &dev->i2c_adap, 275 .i2c_addr = dev->tuner_addr, 276 }; 277 278 dvb->frontend->callback = tm6000_tuner_callback; 279 ret = dvb_register_frontend(&dvb->adapter, dvb->frontend); 280 if (ret < 0) { 281 printk(KERN_ERR 282 "tm6000: couldn't register frontend\n"); 283 goto adapter_err; 284 } 285 286 if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) { 287 printk(KERN_ERR "tm6000: couldn't register " 288 "frontend (xc3028)\n"); 289 ret = -EINVAL; 290 goto frontend_err; 291 } 292 printk(KERN_INFO "tm6000: XC2028/3028 asked to be " 293 "attached to frontend!\n"); 294 break; 295 } 296 case TUNER_XC5000: { 297 struct xc5000_config cfg = { 298 .i2c_address = dev->tuner_addr, 299 }; 300 301 dvb->frontend->callback = tm6000_xc5000_callback; 302 ret = dvb_register_frontend(&dvb->adapter, dvb->frontend); 303 if (ret < 0) { 304 printk(KERN_ERR 305 "tm6000: couldn't register frontend\n"); 306 goto adapter_err; 307 } 308 309 if (!dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, &cfg)) { 310 printk(KERN_ERR "tm6000: couldn't register " 311 "frontend (xc5000)\n"); 312 ret = -EINVAL; 313 goto frontend_err; 314 } 315 printk(KERN_INFO "tm6000: XC5000 asked to be " 316 "attached to frontend!\n"); 317 break; 318 } 319 } 320 } else 321 printk(KERN_ERR "tm6000: no frontend found\n"); 322 323 dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING 324 | DMX_MEMORY_BASED_FILTERING; 325 dvb->demux.priv = dev; 326 dvb->demux.filternum = 8; 327 dvb->demux.feednum = 8; 328 dvb->demux.start_feed = tm6000_start_feed; 329 dvb->demux.stop_feed = tm6000_stop_feed; 330 dvb->demux.write_to_decoder = NULL; 331 ret = dvb_dmx_init(&dvb->demux); 332 if (ret < 0) { 333 printk("tm6000: dvb_dmx_init failed (errno = %d)\n", ret); 334 goto frontend_err; 335 } 336 337 dvb->dmxdev.filternum = dev->dvb->demux.filternum; 338 dvb->dmxdev.demux = &dev->dvb->demux.dmx; 339 dvb->dmxdev.capabilities = 0; 340 341 ret = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); 342 if (ret < 0) { 343 printk("tm6000: dvb_dmxdev_init failed (errno = %d)\n", ret); 344 goto dvb_dmx_err; 345 } 346 347 return 0; 348 349dvb_dmx_err: 350 dvb_dmx_release(&dvb->demux); 351frontend_err: 352 if (dvb->frontend) { 353 dvb_frontend_detach(dvb->frontend); 354 dvb_unregister_frontend(dvb->frontend); 355 } 356adapter_err: 357 dvb_unregister_adapter(&dvb->adapter); 358err: 359 return ret; 360} 361 362void unregister_dvb(struct tm6000_core *dev) 363{ 364 struct tm6000_dvb *dvb = dev->dvb; 365 366 if (dvb->bulk_urb != NULL) { 367 struct urb *bulk_urb = dvb->bulk_urb; 368 369 kfree(bulk_urb->transfer_buffer); 370 bulk_urb->transfer_buffer = NULL; 371 usb_unlink_urb(bulk_urb); 372 usb_free_urb(bulk_urb); 373 } 374 375/* mutex_lock(&tm6000_driver.open_close_mutex); */ 376 if (dvb->frontend) { 377 dvb_frontend_detach(dvb->frontend); 378 dvb_unregister_frontend(dvb->frontend); 379 } 380 381 dvb_dmxdev_release(&dvb->dmxdev); 382 dvb_dmx_release(&dvb->demux); 383 dvb_unregister_adapter(&dvb->adapter); 384 mutex_destroy(&dvb->mutex); 385/* mutex_unlock(&tm6000_driver.open_close_mutex); */ 386} 387 388static int dvb_init(struct tm6000_core *dev) 389{ 390 struct tm6000_dvb *dvb; 391 int rc; 392 393 if (!dev) 394 return 0; 395 396 if (!dev->caps.has_dvb) 397 return 0; 398 399 dvb = kzalloc(sizeof(struct tm6000_dvb), GFP_KERNEL); 400 if (!dvb) { 401 printk(KERN_INFO "Cannot allocate memory\n"); 402 return -ENOMEM; 403 } 404 405 dev->dvb = dvb; 406 407 rc = register_dvb(dev); 408 if (rc < 0) { 409 kfree(dvb); 410 dev->dvb = NULL; 411 return 0; 412 } 413 414 return 0; 415} 416 417static int dvb_fini(struct tm6000_core *dev) 418{ 419 if (!dev) 420 return 0; 421 422 if (!dev->caps.has_dvb) 423 return 0; 424 425 if (dev->dvb) { 426 unregister_dvb(dev); 427 kfree(dev->dvb); 428 dev->dvb = NULL; 429 } 430 431 return 0; 432} 433 434static struct tm6000_ops dvb_ops = { 435 .type = TM6000_DVB, 436 .name = "TM6000 dvb Extension", 437 .init = dvb_init, 438 .fini = dvb_fini, 439}; 440 441static int __init tm6000_dvb_register(void) 442{ 443 return tm6000_register_extension(&dvb_ops); 444} 445 446static void __exit tm6000_dvb_unregister(void) 447{ 448 tm6000_unregister_extension(&dvb_ops); 449} 450 451module_init(tm6000_dvb_register); 452module_exit(tm6000_dvb_unregister); 453