em28xx-dvb.c revision d18e2fda7133287bf8a81809816e646cf17c332e
13aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab/* 23aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab DVB device driver for em28xx 33aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 43aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab (c) 2008 Mauro Carvalho Chehab <mchehab@infradead.org> 53aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 6bdfbf9520372daf2b4d6941474c92310848ccb27Devin Heitmueller (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> 7bdfbf9520372daf2b4d6941474c92310848ccb27Devin Heitmueller - Fixes for the driver to properly work with HVR-950 84fd305b2a2c4d16e8d4ebc95c84f946edd3385c5Devin Heitmueller - Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick 9e14b3658a7651ffd9b1f407eaf07f4dde17ef1e7Devin Heitmueller - Fixes for the driver to properly work with AMD ATI TV Wonder HD 600 10bdfbf9520372daf2b4d6941474c92310848ccb27Devin Heitmueller 113421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton (c) 2008 Aidan Thornton <makosoft@googlemail.com> 123421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 133421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton Based on cx88-dvb, saa7134-dvb and videobuf-dvb originally written by: 143aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> 153aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] 163aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 173aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab This program is free software; you can redistribute it and/or modify 183aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab it under the terms of the GNU General Public License as published by 193aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab the Free Software Foundation; either version 2 of the License. 203aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab */ 213aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 223aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab#include <linux/kernel.h> 233aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab#include <linux/usb.h> 243aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 253aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab#include "em28xx.h" 263aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab#include <media/v4l2-common.h> 273aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab#include <media/videobuf-vmalloc.h> 283aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 293aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab#include "lgdt330x.h" 307e6388a1b97cca57a1906df6104feb4001721576Aidan Thornton#include "zl10353.h" 316e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora#include "s5h1409.h" 323aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 333aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho ChehabMODULE_DESCRIPTION("driver for em28xx based DVB cards"); 343aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho ChehabMODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); 353aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho ChehabMODULE_LICENSE("GPL"); 363aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 373aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehabstatic unsigned int debug; 383aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehabmodule_param(debug, int, 0644); 393aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho ChehabMODULE_PARM_DESC(debug, "enable debug messages [dvb]"); 403aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 413aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho ChehabDVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 423aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 433aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab#define dprintk(level, fmt, arg...) do { \ 443aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehabif (debug >= level) \ 453421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \ 463aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab} while (0) 473aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 483421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton#define EM28XX_DVB_NUM_BUFS 5 493421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton#define EM28XX_DVB_MAX_PACKETS 64 503421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 513421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thorntonstruct em28xx_dvb { 523421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct dvb_frontend *frontend; 533421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 543421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton /* feed count management */ 553421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct mutex lock; 563421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton int nfeeds; 573421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 583421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton /* general boilerplate stuff */ 593421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct dvb_adapter adapter; 603421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct dvb_demux demux; 613421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct dmxdev dmxdev; 623421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct dmx_frontend fe_hw; 633421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct dmx_frontend fe_mem; 643421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct dvb_net net; 653421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton}; 663421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 673421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 683421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thorntonstatic inline void print_err_status(struct em28xx *dev, 693421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton int packet, int status) 703aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab{ 713421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton char *errmsg = "Unknown"; 723aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 733421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton switch (status) { 743421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton case -ENOENT: 753421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton errmsg = "unlinked synchronuously"; 763421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton break; 773421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton case -ECONNRESET: 783421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton errmsg = "unlinked asynchronuously"; 793421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton break; 803421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton case -ENOSR: 813421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton errmsg = "Buffer error (overrun)"; 823421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton break; 833421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton case -EPIPE: 843421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton errmsg = "Stalled (device not responding)"; 853421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton break; 863421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton case -EOVERFLOW: 873421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton errmsg = "Babble (bad cable?)"; 883421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton break; 893421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton case -EPROTO: 903421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton errmsg = "Bit-stuff error (bad cable?)"; 913421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton break; 923421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton case -EILSEQ: 933421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton errmsg = "CRC/Timeout (could be anything)"; 943421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton break; 953421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton case -ETIME: 963421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton errmsg = "Device does not respond"; 973421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton break; 983421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 993421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (packet < 0) { 1003421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dprintk(1, "URB status %d [%s].\n", status, errmsg); 1013421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } else { 1026ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgraf dprintk(1, "URB packet %d, status %d [%s].\n", 1036ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgraf packet, status, errmsg); 1043421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 1053421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton} 1063aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 1073421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thorntonstatic inline int dvb_isoc_copy(struct em28xx *dev, struct urb *urb) 1083421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton{ 1093421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton int i; 1103aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 1113421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (!dev) 1123421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton return 0; 1133aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 1143421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) 1153421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton return 0; 1163421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 1173421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (urb->status < 0) { 1183421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton print_err_status(dev, -1, urb->status); 1193421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (urb->status == -ENOENT) 1203421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton return 0; 1213421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 1223421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 1233421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton for (i = 0; i < urb->number_of_packets; i++) { 1243421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton int status = urb->iso_frame_desc[i].status; 1253421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 1263421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (status < 0) { 1273421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton print_err_status(dev, i, status); 1283421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (urb->iso_frame_desc[i].status != -EPROTO) 1293421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton continue; 1303421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 1313421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 1323421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer + 1333421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton urb->iso_frame_desc[i].offset, 1343421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton urb->iso_frame_desc[i].actual_length); 1353421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 1363421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 1373421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton return 0; 1383421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton} 1393421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 1406ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgrafstatic int start_streaming(struct em28xx_dvb *dvb) 1416ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgraf{ 142c67ec53f8f4e90ebd482789e2f6d121f41a0bd90Mauro Carvalho Chehab int rc; 1433421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct em28xx *dev = dvb->adapter.priv; 144d18e2fda7133287bf8a81809816e646cf17c332eDevin Heitmueller int max_dvb_packet_size; 1453421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 1463421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton usb_set_interface(dev->udev, 0, 1); 147c67ec53f8f4e90ebd482789e2f6d121f41a0bd90Mauro Carvalho Chehab rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 148c67ec53f8f4e90ebd482789e2f6d121f41a0bd90Mauro Carvalho Chehab if (rc < 0) 149c67ec53f8f4e90ebd482789e2f6d121f41a0bd90Mauro Carvalho Chehab return rc; 1503421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 151d18e2fda7133287bf8a81809816e646cf17c332eDevin Heitmueller max_dvb_packet_size = em28xx_isoc_dvb_max_packetsize(dev); 152d18e2fda7133287bf8a81809816e646cf17c332eDevin Heitmueller 1533421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS, 154d18e2fda7133287bf8a81809816e646cf17c332eDevin Heitmueller EM28XX_DVB_NUM_BUFS, max_dvb_packet_size, 155c67ec53f8f4e90ebd482789e2f6d121f41a0bd90Mauro Carvalho Chehab dvb_isoc_copy); 1563421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton} 1573421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 1586ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgrafstatic int stop_streaming(struct em28xx_dvb *dvb) 1596ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgraf{ 1603421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct em28xx *dev = dvb->adapter.priv; 1613421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 1623421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton em28xx_uninit_isoc(dev); 163c67ec53f8f4e90ebd482789e2f6d121f41a0bd90Mauro Carvalho Chehab 1642fe3e2ee72ef17daad1d3769321bb7dd69a003a9Mauro Carvalho Chehab em28xx_set_mode(dev, EM28XX_SUSPEND); 165c67ec53f8f4e90ebd482789e2f6d121f41a0bd90Mauro Carvalho Chehab 1663aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab return 0; 1673aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab} 1683aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 1693421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thorntonstatic int start_feed(struct dvb_demux_feed *feed) 1703421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton{ 1713421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct dvb_demux *demux = feed->demux; 1723421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct em28xx_dvb *dvb = demux->priv; 1733421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton int rc, ret; 1743421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 1753421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (!demux->dmx.frontend) 1763421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton return -EINVAL; 1773421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 1783421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton mutex_lock(&dvb->lock); 1793421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->nfeeds++; 1803421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton rc = dvb->nfeeds; 1813421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 1823421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (dvb->nfeeds == 1) { 1833421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton ret = start_streaming(dvb); 1846ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgraf if (ret < 0) 1856ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgraf rc = ret; 1863421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 1873421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 1883421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton mutex_unlock(&dvb->lock); 1893421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton return rc; 1903421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton} 1913421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 1923421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thorntonstatic int stop_feed(struct dvb_demux_feed *feed) 1933421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton{ 1943421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct dvb_demux *demux = feed->demux; 1953421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct em28xx_dvb *dvb = demux->priv; 1963421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton int err = 0; 1973421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 1983421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton mutex_lock(&dvb->lock); 1993421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->nfeeds--; 2006ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgraf 2016ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgraf if (0 == dvb->nfeeds) 2023421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton err = stop_streaming(dvb); 2036ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgraf 2043421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton mutex_unlock(&dvb->lock); 2053421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton return err; 2063421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton} 2073421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 2083421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 209e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehab 210e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehab/* ------------------------------------------------------------------ */ 211e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehabstatic int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) 212e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehab{ 213e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehab struct em28xx *dev = fe->dvb->priv; 214e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehab 215e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehab if (acquire) 216e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehab return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 217e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehab else 2182fe3e2ee72ef17daad1d3769321bb7dd69a003a9Mauro Carvalho Chehab return em28xx_set_mode(dev, EM28XX_SUSPEND); 219e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehab} 220e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehab 2213aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab/* ------------------------------------------------------------------ */ 2223aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 223227ad4ab9058ef2624934183e8083886cf64bf56Mauro Carvalho Chehabstatic struct lgdt330x_config em2880_lgdt3303_dev = { 224227ad4ab9058ef2624934183e8083886cf64bf56Mauro Carvalho Chehab .demod_address = 0x0e, 225227ad4ab9058ef2624934183e8083886cf64bf56Mauro Carvalho Chehab .demod_chip = LGDT3303, 226227ad4ab9058ef2624934183e8083886cf64bf56Mauro Carvalho Chehab}; 2273aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 2287e6388a1b97cca57a1906df6104feb4001721576Aidan Thorntonstatic struct zl10353_config em28xx_zl10353_with_xc3028 = { 2297e6388a1b97cca57a1906df6104feb4001721576Aidan Thornton .demod_address = (0x1e >> 1), 2307e6388a1b97cca57a1906df6104feb4001721576Aidan Thornton .no_tuner = 1, 2317e6388a1b97cca57a1906df6104feb4001721576Aidan Thornton .parallel_ts = 1, 2327e6388a1b97cca57a1906df6104feb4001721576Aidan Thornton .if2 = 45600, 2337e6388a1b97cca57a1906df6104feb4001721576Aidan Thornton}; 2347e6388a1b97cca57a1906df6104feb4001721576Aidan Thornton 2356e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakorastatic struct s5h1409_config em28xx_s5h1409_with_xc3028 = { 2366e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora .demod_address = 0x32 >> 1, 2376e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora .output_mode = S5H1409_PARALLEL_OUTPUT, 2386e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora .gpio = S5H1409_GPIO_OFF, 2396e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora .inversion = S5H1409_INVERSION_OFF, 2406e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora .status_mode = S5H1409_DEMODLOCKING, 2416e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 2426e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora}; 2436e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora 24417d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller#ifdef EM28XX_DRX397XD_SUPPORT 24517d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller/* [TODO] djh - not sure yet what the device config needs to contain */ 24617d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmuellerstatic struct drx397xD_config em28xx_drx397xD_with_xc3028 = { 24717d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller .demod_address = (0xe0 >> 1), 24817d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller}; 24917d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller#endif 25017d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller 2513aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab/* ------------------------------------------------------------------ */ 2523aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 2533aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehabstatic int attach_xc3028(u8 addr, struct em28xx *dev) 2543aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab{ 2553aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab struct dvb_frontend *fe; 2563ca9c09379e8f3be0744c47f72769457fa46e9f3Mauro Carvalho Chehab struct xc2028_config cfg; 2573ca9c09379e8f3be0744c47f72769457fa46e9f3Mauro Carvalho Chehab 2586ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgraf memset(&cfg, 0, sizeof(cfg)); 2593ca9c09379e8f3be0744c47f72769457fa46e9f3Mauro Carvalho Chehab cfg.i2c_adap = &dev->i2c_adap; 2603ca9c09379e8f3be0744c47f72769457fa46e9f3Mauro Carvalho Chehab cfg.i2c_addr = addr; 2613ca9c09379e8f3be0744c47f72769457fa46e9f3Mauro Carvalho Chehab 2623421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (!dev->dvb->frontend) { 2633aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab printk(KERN_ERR "%s/2: dvb frontend not attached. " 2643aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab "Can't attach xc3028\n", 2653aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab dev->name); 2663aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab return -EINVAL; 2673aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab } 2683aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 2693421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton fe = dvb_attach(xc2028_attach, dev->dvb->frontend, &cfg); 2703aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab if (!fe) { 2713aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab printk(KERN_ERR "%s/2: xc3028 attach failed\n", 2723aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab dev->name); 2733421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb_frontend_detach(dev->dvb->frontend); 2743421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dev->dvb->frontend = NULL; 2753aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab return -EINVAL; 2763aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab } 2773aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 2783aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab printk(KERN_INFO "%s/2: xc3028 attached\n", dev->name); 2793aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 2803aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab return 0; 2813aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab} 2823aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 2833421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton/* ------------------------------------------------------------------ */ 2843421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 285d45b9b8ab43c8973a9630ac54f4ede6c3e009f9eHans Verkuilstatic int register_dvb(struct em28xx_dvb *dvb, 2863421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct module *module, 2873421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct em28xx *dev, 2883421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct device *device) 2893aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab{ 2903421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton int result; 2913aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 2923421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton mutex_init(&dvb->lock); 2933aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 2943421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton /* register adapter */ 2953421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton result = dvb_register_adapter(&dvb->adapter, dev->name, module, device, 2963421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton adapter_nr); 2973421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (result < 0) { 2983421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", 2993421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dev->name, result); 3003421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton goto fail_adapter; 3013421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 302e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehab 303e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehab /* Ensure all frontends negotiate bus access */ 304e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehab dvb->frontend->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl; 305e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehab 3063421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->adapter.priv = dev; 3073421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 3083421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton /* register frontend */ 3093421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton result = dvb_register_frontend(&dvb->adapter, dvb->frontend); 3103421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (result < 0) { 3113421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", 3123421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dev->name, result); 3133421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton goto fail_frontend; 3143421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 3153421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 3163421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton /* register demux stuff */ 3173421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->demux.dmx.capabilities = 3183421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton DMX_TS_FILTERING | DMX_SECTION_FILTERING | 3193421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton DMX_MEMORY_BASED_FILTERING; 3203421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->demux.priv = dvb; 3213421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->demux.filternum = 256; 3223421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->demux.feednum = 256; 3233421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->demux.start_feed = start_feed; 3243421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->demux.stop_feed = stop_feed; 325e3569abc1c51d24f9c64b214f85477e490b156e3Mauro Carvalho Chehab 3263421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton result = dvb_dmx_init(&dvb->demux); 3273421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (result < 0) { 3283421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n", 3293421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dev->name, result); 3303421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton goto fail_dmx; 3313421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 3323421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 3333421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->dmxdev.filternum = 256; 3343421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->dmxdev.demux = &dvb->demux.dmx; 3353421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->dmxdev.capabilities = 0; 3363421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); 3373421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (result < 0) { 3383421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", 3393421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dev->name, result); 3403421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton goto fail_dmxdev; 3413421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 34252284c3e47bf502aaff72ab2ede509193b628b1bMauro Carvalho Chehab 3433421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->fe_hw.source = DMX_FRONTEND_0; 3443421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); 3453421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (result < 0) { 3463421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton printk(KERN_WARNING "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", 3473421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dev->name, result); 3483421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton goto fail_fe_hw; 3493421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 3503421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 3513421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->fe_mem.source = DMX_MEMORY_FE; 3523421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); 3533421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (result < 0) { 3543421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", 3553421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dev->name, result); 3563421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton goto fail_fe_mem; 3573421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 3583421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 3593421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); 3603421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (result < 0) { 3613421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n", 3623421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dev->name, result); 3633421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton goto fail_fe_conn; 3643421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 3653421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 3663421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton /* register network adapter */ 3673421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); 3683421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton return 0; 3693421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 3703421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thorntonfail_fe_conn: 3713421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); 3723421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thorntonfail_fe_mem: 3733421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); 3743421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thorntonfail_fe_hw: 3753421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb_dmxdev_release(&dvb->dmxdev); 3763421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thorntonfail_dmxdev: 3773421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb_dmx_release(&dvb->demux); 3783421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thorntonfail_dmx: 3793421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb_unregister_frontend(dvb->frontend); 3803421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thorntonfail_frontend: 3813421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb_frontend_detach(dvb->frontend); 3823421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb_unregister_adapter(&dvb->adapter); 3833421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thorntonfail_adapter: 3843421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton return result; 3853421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton} 3863421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 3873421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thorntonstatic void unregister_dvb(struct em28xx_dvb *dvb) 3883421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton{ 3893421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb_net_release(&dvb->net); 3903421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); 3913421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); 3923421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb_dmxdev_release(&dvb->dmxdev); 3933421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb_dmx_release(&dvb->demux); 3943421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb_unregister_frontend(dvb->frontend); 3953421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb_frontend_detach(dvb->frontend); 3963421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb_unregister_adapter(&dvb->adapter); 3973421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton} 3983421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 3993421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 4003421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thorntonstatic int dvb_init(struct em28xx *dev) 4013421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton{ 4023421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton int result = 0; 4033421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton struct em28xx_dvb *dvb; 4043421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 405505b6d0b774fa4475fedbd3cebf95199c17a0086Mauro Carvalho Chehab if (!dev->board.has_dvb) { 406df619181631217e3166bb6c7538f981e0272617fDevin Heitmueller /* This device does not support the extension */ 407df619181631217e3166bb6c7538f981e0272617fDevin Heitmueller return 0; 408df619181631217e3166bb6c7538f981e0272617fDevin Heitmueller } 409df619181631217e3166bb6c7538f981e0272617fDevin Heitmueller 4103421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); 4116ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgraf 4126ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgraf if (dvb == NULL) { 4136ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgraf printk(KERN_INFO "em28xx_dvb: memory allocation failed\n"); 4143421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton return -ENOMEM; 4153421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 4163421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dev->dvb = dvb; 4173aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 418c67ec53f8f4e90ebd482789e2f6d121f41a0bd90Mauro Carvalho Chehab em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); 4193aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab /* init frontend */ 4203aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab switch (dev->model) { 421f89bc32974a4376e8393001484af28d8c3350ab4Douglas Schilling Landgraf case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: 42210ac6603613d46a43a4544fbbe9581e50879bd45Mauro Carvalho Chehab case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: 4234fd305b2a2c4d16e8d4ebc95c84f946edd3385c5Devin Heitmueller case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: 424e14b3658a7651ffd9b1f407eaf07f4dde17ef1e7Devin Heitmueller case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: 4253421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->frontend = dvb_attach(lgdt330x_attach, 4263421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton &em2880_lgdt3303_dev, 4273421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton &dev->i2c_adap); 4283421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (attach_xc3028(0x61, dev) < 0) { 4293421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton result = -EINVAL; 4303421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton goto out_free; 4313421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 432227ad4ab9058ef2624934183e8083886cf64bf56Mauro Carvalho Chehab break; 4337e6388a1b97cca57a1906df6104feb4001721576Aidan Thornton case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: 43446510b56ca56a25ce973d6a6e8490c1109ff94efThierry MERLE case EM2880_BOARD_TERRATEC_HYBRID_XS: 43546510b56ca56a25ce973d6a6e8490c1109ff94efThierry MERLE case EM2880_BOARD_KWORLD_DVB_310U: 436e5db5d44432abc82b1250dd05bd0a4b011392d9dDouglas Schilling Landgraf case EM2880_BOARD_EMPIRE_DUAL_TV: 4373421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dvb->frontend = dvb_attach(zl10353_attach, 4383421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton &em28xx_zl10353_with_xc3028, 4393421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton &dev->i2c_adap); 4403421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (attach_xc3028(0x61, dev) < 0) { 4413421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton result = -EINVAL; 4423421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton goto out_free; 4433421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 4447e6388a1b97cca57a1906df6104feb4001721576Aidan Thornton break; 4456e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora case EM2883_BOARD_KWORLD_HYBRID_330U: 4466e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora dvb->frontend = dvb_attach(s5h1409_attach, 4476e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora &em28xx_s5h1409_with_xc3028, 4486e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora &dev->i2c_adap); 4496e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora if (attach_xc3028(0x61, dev) < 0) { 4506e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora result = -EINVAL; 4516e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora goto out_free; 4526e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora } 4536e7b9ea0937eeb75fa166ef7bd22b5f3bb5676d1Robert Krakora break; 45417d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: 45517d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller#ifdef EM28XX_DRX397XD_SUPPORT 45617d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller /* We don't have the config structure properly populated, so 45717d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller this is commented out for now */ 45817d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller dvb->frontend = dvb_attach(drx397xD_attach, 45917d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller &em28xx_drx397xD_with_xc3028, 46017d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller &dev->i2c_adap); 46117d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller if (attach_xc3028(0x61, dev) < 0) { 46217d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller result = -EINVAL; 46317d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller goto out_free; 46417d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller } 46517d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller break; 46617d9d558e818530cc7d210ffea575a36f48eaa1aDevin Heitmueller#endif 4673aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab default: 4683aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" 4693aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab " isn't supported yet\n", 4703aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab dev->name); 4713aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab break; 4723aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab } 4733421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (NULL == dvb->frontend) { 4743aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab printk(KERN_ERR 4753aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab "%s/2: frontend initialization failed\n", 4763aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab dev->name); 4773421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton result = -EINVAL; 4783421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton goto out_free; 4793aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab } 480d7cba043d7ec840d67bd5143779d1febe7d83407Michael Krufky /* define general-purpose callback pointer */ 481d7cba043d7ec840d67bd5143779d1febe7d83407Michael Krufky dvb->frontend->callback = em28xx_tuner_callback; 4823aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 4833aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab /* register everything */ 4843421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton result = register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); 4853421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 4866ea54d938b6f81baa0952a8b15d3e67e6c268b8fDouglas Schilling Landgraf if (result < 0) 4873421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton goto out_free; 4883421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 4892fe3e2ee72ef17daad1d3769321bb7dd69a003a9Mauro Carvalho Chehab em28xx_set_mode(dev, EM28XX_SUSPEND); 490102a0b0879a01a413ed5f667f7db9c2085ca8474Mauro Carvalho Chehab printk(KERN_INFO "Successfully loaded em28xx-dvb\n"); 4913421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton return 0; 4923421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton 4933421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thorntonout_free: 4942fe3e2ee72ef17daad1d3769321bb7dd69a003a9Mauro Carvalho Chehab em28xx_set_mode(dev, EM28XX_SUSPEND); 4953421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton kfree(dvb); 4963421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dev->dvb = NULL; 4973421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton return result; 4983aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab} 4993aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 5003aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehabstatic int dvb_fini(struct em28xx *dev) 5013aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab{ 502505b6d0b774fa4475fedbd3cebf95199c17a0086Mauro Carvalho Chehab if (!dev->board.has_dvb) { 503df619181631217e3166bb6c7538f981e0272617fDevin Heitmueller /* This device does not support the extension */ 504df619181631217e3166bb6c7538f981e0272617fDevin Heitmueller return 0; 505df619181631217e3166bb6c7538f981e0272617fDevin Heitmueller } 506df619181631217e3166bb6c7538f981e0272617fDevin Heitmueller 5073421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton if (dev->dvb) { 5083421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton unregister_dvb(dev->dvb); 5093421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton dev->dvb = NULL; 5103421b7787a2cf41ac5edce9b5766bddd1e1d9986Aidan Thornton } 5113aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 5123aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab return 0; 5133aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab} 5143aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 5153aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehabstatic struct em28xx_ops dvb_ops = { 5163aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab .id = EM28XX_DVB, 5173aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab .name = "Em28xx dvb Extension", 5183aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab .init = dvb_init, 5193aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab .fini = dvb_fini, 5203aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab}; 5213aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 5223aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehabstatic int __init em28xx_dvb_register(void) 5233aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab{ 5243aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab return em28xx_register_extension(&dvb_ops); 5253aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab} 5263aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 5273aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehabstatic void __exit em28xx_dvb_unregister(void) 5283aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab{ 5293aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab em28xx_unregister_extension(&dvb_ops); 5303aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab} 5313aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehab 5323aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehabmodule_init(em28xx_dvb_register); 5333aefb79af8d41c85e11da7109d62038849421bb6Mauro Carvalho Chehabmodule_exit(em28xx_dvb_unregister); 534