2009-12-02 21:57:10 -03:00
/*
Mantis PCI bridge driver
Copyright ( C ) 2005 , 2006 Manu Abraham ( abraham . manu @ gmail . com )
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include <linux/bitops.h>
# include "mantis_common.h"
# include "mantis_core.h"
# include "dmxdev.h"
# include "dvbdev.h"
# include "dvb_demux.h"
# include "dvb_frontend.h"
# include "mantis_vp1033.h"
# include "mantis_vp1034.h"
2009-12-04 04:43:04 -03:00
# include "mantis_vp1041.h"
2009-12-02 21:57:10 -03:00
# include "mantis_vp2033.h"
2009-12-04 04:42:22 -03:00
# include "mantis_vp2040.h"
2009-12-02 21:57:10 -03:00
# include "mantis_vp3030.h"
2009-12-04 05:33:56 -03:00
DVB_DEFINE_MOD_OPT_ADAPTER_NR ( adapter_nr ) ;
2009-12-02 21:57:10 -03:00
/* Tuner power supply control */
void mantis_fe_powerup ( struct mantis_pci * mantis )
{
dprintk ( verbose , MANTIS_DEBUG , 1 , " Frontend Power ON " ) ;
gpio_set_bits ( mantis , 0x0c , 1 ) ;
msleep_interruptible ( 100 ) ;
gpio_set_bits ( mantis , 0x0c , 1 ) ;
msleep_interruptible ( 100 ) ;
}
void mantis_fe_powerdown ( struct mantis_pci * mantis )
{
dprintk ( verbose , MANTIS_DEBUG , 1 , " Frontend Power OFF " ) ;
gpio_set_bits ( mantis , 0x0c , 0 ) ;
}
static int mantis_fe_reset ( struct dvb_frontend * fe )
{
struct mantis_pci * mantis = fe - > dvb - > priv ;
dprintk ( verbose , MANTIS_DEBUG , 1 , " Frontend Reset " ) ;
gpio_set_bits ( mantis , 13 , 0 ) ;
msleep_interruptible ( 100 ) ;
gpio_set_bits ( mantis , 13 , 0 ) ;
msleep_interruptible ( 100 ) ;
gpio_set_bits ( mantis , 13 , 1 ) ;
msleep_interruptible ( 100 ) ;
gpio_set_bits ( mantis , 13 , 1 ) ;
return 0 ;
}
static int mantis_frontend_reset ( struct mantis_pci * mantis )
{
dprintk ( verbose , MANTIS_DEBUG , 1 , " Frontend Reset " ) ;
gpio_set_bits ( mantis , 13 , 0 ) ;
msleep_interruptible ( 100 ) ;
gpio_set_bits ( mantis , 13 , 0 ) ;
msleep_interruptible ( 100 ) ;
gpio_set_bits ( mantis , 13 , 1 ) ;
msleep_interruptible ( 100 ) ;
gpio_set_bits ( mantis , 13 , 1 ) ;
return 0 ;
}
static int mantis_dvb_start_feed ( struct dvb_demux_feed * dvbdmxfeed )
{
struct dvb_demux * dvbdmx = dvbdmxfeed - > demux ;
struct mantis_pci * mantis = dvbdmx - > priv ;
dprintk ( verbose , MANTIS_DEBUG , 1 , " Mantis DVB Start feed " ) ;
if ( ! dvbdmx - > dmx . frontend ) {
dprintk ( verbose , MANTIS_DEBUG , 1 , " no frontend ? " ) ;
return - EINVAL ;
}
mantis - > feeds + + ;
dprintk ( verbose , MANTIS_DEBUG , 1 ,
" mantis start feed, feeds=%d " ,
mantis - > feeds ) ;
if ( mantis - > feeds = = 1 ) {
dprintk ( verbose , MANTIS_DEBUG , 1 , " mantis start feed & dma " ) ;
printk ( " mantis start feed & dma \n " ) ;
mantis_dma_start ( mantis ) ;
}
return mantis - > feeds ;
}
static int mantis_dvb_stop_feed ( struct dvb_demux_feed * dvbdmxfeed )
{
struct dvb_demux * dvbdmx = dvbdmxfeed - > demux ;
struct mantis_pci * mantis = dvbdmx - > priv ;
dprintk ( verbose , MANTIS_DEBUG , 1 , " Mantis DVB Stop feed " ) ;
if ( ! dvbdmx - > dmx . frontend ) {
dprintk ( verbose , MANTIS_DEBUG , 1 , " no frontend ? " ) ;
return - EINVAL ;
}
mantis - > feeds - - ;
if ( mantis - > feeds = = 0 ) {
dprintk ( verbose , MANTIS_DEBUG , 1 , " mantis stop feed and dma " ) ;
printk ( " mantis stop feed and dma \n " ) ;
mantis_dma_stop ( mantis ) ;
}
return 0 ;
}
int __devinit mantis_dvb_init ( struct mantis_pci * mantis )
{
int result ;
dprintk ( verbose , MANTIS_DEBUG , 1 , " dvb_register_adapter " ) ;
if ( dvb_register_adapter ( & mantis - > dvb_adapter ,
" Mantis dvb adapter " , THIS_MODULE ,
2009-12-04 05:33:56 -03:00
& mantis - > pdev - > dev ,
adapter_nr ) < 0 ) {
2009-12-02 21:57:10 -03:00
dprintk ( verbose , MANTIS_ERROR , 1 , " Error registering adapter " ) ;
return - ENODEV ;
}
mantis - > dvb_adapter . priv = mantis ;
mantis - > demux . dmx . capabilities = DMX_TS_FILTERING |
DMX_SECTION_FILTERING |
DMX_MEMORY_BASED_FILTERING ;
mantis - > demux . priv = mantis ;
mantis - > demux . filternum = 256 ;
mantis - > demux . feednum = 256 ;
mantis - > demux . start_feed = mantis_dvb_start_feed ;
mantis - > demux . stop_feed = mantis_dvb_stop_feed ;
mantis - > demux . write_to_decoder = NULL ;
dprintk ( verbose , MANTIS_DEBUG , 1 , " dvb_dmx_init " ) ;
if ( ( result = dvb_dmx_init ( & mantis - > demux ) ) < 0 ) {
dprintk ( verbose , MANTIS_ERROR , 1 ,
" dvb_dmx_init failed, ERROR=%d " , result ) ;
goto err0 ;
}
mantis - > dmxdev . filternum = 256 ;
mantis - > dmxdev . demux = & mantis - > demux . dmx ;
mantis - > dmxdev . capabilities = 0 ;
dprintk ( verbose , MANTIS_DEBUG , 1 , " dvb_dmxdev_init " ) ;
if ( ( result = dvb_dmxdev_init ( & mantis - > dmxdev ,
& mantis - > dvb_adapter ) ) < 0 ) {
dprintk ( verbose , MANTIS_ERROR , 1 ,
" dvb_dmxdev_init failed, ERROR=%d " , result ) ;
goto err1 ;
}
mantis - > fe_hw . source = DMX_FRONTEND_0 ;
if ( ( result = mantis - > demux . dmx . add_frontend ( & mantis - > demux . dmx ,
& mantis - > fe_hw ) ) < 0 ) {
dprintk ( verbose , MANTIS_ERROR , 1 ,
" dvb_dmx_init failed, ERROR=%d " , result ) ;
goto err2 ;
}
mantis - > fe_mem . source = DMX_MEMORY_FE ;
if ( ( result = mantis - > demux . dmx . add_frontend ( & mantis - > demux . dmx ,
& mantis - > fe_mem ) ) < 0 ) {
dprintk ( verbose , MANTIS_ERROR , 1 ,
" dvb_dmx_init failed, ERROR=%d " , result ) ;
goto err3 ;
}
if ( ( result = mantis - > demux . dmx . connect_frontend ( & mantis - > demux . dmx ,
& mantis - > fe_hw ) ) < 0 ) {
dprintk ( verbose , MANTIS_ERROR , 1 ,
" dvb_dmx_init failed, ERROR=%d " , result ) ;
goto err4 ;
}
dvb_net_init ( & mantis - > dvb_adapter , & mantis - > dvbnet , & mantis - > demux . dmx ) ;
tasklet_init ( & mantis - > tasklet , mantis_dma_xfer , ( unsigned long ) mantis ) ;
mantis_frontend_init ( mantis ) ;
2009-12-04 05:07:41 -03:00
mantis_ca_init ( mantis ) ;
2009-12-02 21:57:10 -03:00
return 0 ;
/* Error conditions .. */
err4 :
mantis - > demux . dmx . remove_frontend ( & mantis - > demux . dmx , & mantis - > fe_mem ) ;
err3 :
mantis - > demux . dmx . remove_frontend ( & mantis - > demux . dmx , & mantis - > fe_hw ) ;
err2 :
dvb_dmxdev_release ( & mantis - > dmxdev ) ;
err1 :
dvb_dmx_release ( & mantis - > demux ) ;
err0 :
dvb_unregister_adapter ( & mantis - > dvb_adapter ) ;
return result ;
}
int __devinit mantis_frontend_init ( struct mantis_pci * mantis )
{
dprintk ( verbose , MANTIS_DEBUG , 1 , " Mantis frontend Init " ) ;
mantis_fe_powerup ( mantis ) ;
mantis_frontend_reset ( mantis ) ;
2009-12-02 22:07:24 -03:00
dprintk ( verbose , MANTIS_DEBUG , 1 , " Device ID=%02x " , mantis - > subsystem_device ) ;
switch ( mantis - > subsystem_device ) {
2009-12-02 21:57:10 -03:00
case MANTIS_VP_1033_DVB_S : // VP-1033
dprintk ( verbose , MANTIS_ERROR , 1 , " Probing for STV0299 (DVB-S) " ) ;
mantis - > fe = stv0299_attach ( & lgtdqcs001f_config ,
& mantis - > adapter ) ;
if ( mantis - > fe ) {
mantis - > fe - > ops . tuner_ops . set_params = lgtdqcs001f_tuner_set ;
dprintk ( verbose , MANTIS_ERROR , 1 ,
" found STV0299 DVB-S frontend @ 0x%02x " ,
lgtdqcs001f_config . demod_address ) ;
dprintk ( verbose , MANTIS_ERROR , 1 ,
" Mantis DVB-S STV0299 frontend attach success " ) ;
}
break ;
case MANTIS_VP_1034_DVB_S : // VP-1034
dprintk ( verbose , MANTIS_ERROR , 1 , " Probing for MB86A16 (DVB-S/DSS) " ) ;
mantis - > fe = mb86a16_attach ( & vp1034_config , & mantis - > adapter ) ;
if ( mantis - > fe ) {
dprintk ( verbose , MANTIS_ERROR , 1 ,
" found MB86A16 DVB-S/DSS frontend @0x%02x " ,
vp1034_config . demod_address ) ;
}
break ;
2009-12-04 04:43:04 -03:00
case MANTIS_VP_1041_DVB_S2 :
2009-12-04 04:47:30 -03:00
case TECHNISAT_SKYSTAR_HD2 :
2009-12-04 04:43:04 -03:00
mantis - > fe = stb0899_attach ( & vp1041_config , & mantis - > adapter ) ;
if ( mantis - > fe ) {
dprintk ( verbose , MANTIS_ERROR , 1 ,
" found STB0899 DVB-S/DVB-S2 frontend @0x%02x " ,
vp1041_config . demod_address ) ;
if ( stb6100_attach ( mantis - > fe , & vp1041_stb6100_config , & mantis - > adapter ) ) {
if ( ! lnbp21_attach ( mantis - > fe , & mantis - > adapter , 0 , 0 ) ) {
printk ( " %s: No LNBP21 found! \n " , __FUNCTION__ ) ;
mantis - > fe = NULL ;
}
} else {
mantis - > fe = NULL ;
}
}
break ;
2009-12-02 21:57:10 -03:00
case MANTIS_VP_2033_DVB_C : // VP-2033
dprintk ( verbose , MANTIS_ERROR , 1 , " Probing for CU1216 (DVB-C) " ) ;
2009-12-04 04:39:14 -03:00
mantis - > fe = tda10021_attach ( & philips_cu1216_config , & mantis - > adapter , read_pwm ( mantis ) ) ;
2009-12-02 21:57:10 -03:00
if ( mantis - > fe ) {
mantis - > fe - > ops . tuner_ops . set_params = philips_cu1216_tuner_set ;
dprintk ( verbose , MANTIS_ERROR , 1 ,
2009-12-04 04:42:22 -03:00
" found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x " ,
2009-12-02 21:57:10 -03:00
philips_cu1216_config . demod_address ) ;
dprintk ( verbose , MANTIS_ERROR , 1 ,
" Mantis DVB-C Philips CU1216 frontend attach success " ) ;
}
break ;
2009-12-04 05:14:34 -03:00
case MANTIS_VP_2040_DVB_C : // VP-2040
2009-12-04 04:42:22 -03:00
case TERRATEC_CINERGY_C_PCI :
2009-12-04 05:32:30 -03:00
case TECHNISAT_CABLESTAR_HD2 :
2009-12-04 04:42:22 -03:00
dprintk ( verbose , MANTIS_ERROR , 1 , " Probing for CU1216 (DVB-C) " ) ;
mantis - > fe = tda10023_attach ( & tda10023_cu1216_config , & mantis - > adapter , read_pwm ( mantis ) ) ;
if ( mantis - > fe ) {
mantis - > fe - > ops . tuner_ops . set_params = philips_cu1216_tuner_set ;
dprintk ( verbose , MANTIS_ERROR , 1 ,
" found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x " ,
philips_cu1216_config . demod_address ) ;
dprintk ( verbose , MANTIS_ERROR , 1 ,
" Mantis DVB-C Philips CU1216 frontend attach success " ) ;
}
break ;
2009-12-02 21:57:10 -03:00
default :
dprintk ( verbose , MANTIS_DEBUG , 1 , " Unknown frontend:[0x%02x] " ,
mantis - > sub_device_id ) ;
return - ENODEV ;
}
if ( mantis - > fe = = NULL ) {
dprintk ( verbose , MANTIS_ERROR , 1 , " !!! NO Frontends found !!! " ) ;
return - ENODEV ;
} else {
if ( dvb_register_frontend ( & mantis - > dvb_adapter , mantis - > fe ) ) {
dprintk ( verbose , MANTIS_ERROR , 1 ,
" ERROR: Frontend registration failed " ) ;
if ( mantis - > fe - > ops . release )
mantis - > fe - > ops . release ( mantis - > fe ) ;
mantis - > fe = NULL ;
return - ENODEV ;
}
}
return 0 ;
}
int __devexit mantis_dvb_exit ( struct mantis_pci * mantis )
{
2009-12-04 05:08:25 -03:00
mantis_ca_exit ( mantis ) ;
2009-12-02 21:57:10 -03:00
tasklet_kill ( & mantis - > tasklet ) ;
dvb_net_release ( & mantis - > dvbnet ) ;
mantis - > demux . dmx . remove_frontend ( & mantis - > demux . dmx , & mantis - > fe_mem ) ;
mantis - > demux . dmx . remove_frontend ( & mantis - > demux . dmx , & mantis - > fe_hw ) ;
dvb_dmxdev_release ( & mantis - > dmxdev ) ;
dvb_dmx_release ( & mantis - > demux ) ;
if ( mantis - > fe )
dvb_unregister_frontend ( mantis - > fe ) ;
dprintk ( verbose , MANTIS_DEBUG , 1 , " dvb_unregister_adapter " ) ;
dvb_unregister_adapter ( & mantis - > dvb_adapter ) ;
return 0 ;
}