mantis_dvb.c revision f5ae4f6f482191c531ea9e50ac91d9bd2ffca171
1/* 2 Mantis PCI bridge driver 3 Copyright (C) 2005, 2006 Manu Abraham (abraham.manu@gmail.com) 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 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/bitops.h> 22 23#include <linux/signal.h> 24#include <linux/sched.h> 25#include <linux/interrupt.h> 26#include <linux/pci.h> 27#include <linux/i2c.h> 28 29#include "dmxdev.h" 30#include "dvbdev.h" 31#include "dvb_demux.h" 32#include "dvb_frontend.h" 33#include "dvb_net.h" 34 35#include "mantis_common.h" 36#include "mantis_dma.h" 37#include "mantis_ca.h" 38#include "mantis_ioc.h" 39#include "mantis_dvb.h" 40 41DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 42 43int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power) 44{ 45 struct mantis_hwconfig *config = mantis->hwconfig; 46 47 switch (power) { 48 case POWER_ON: 49 dprintk(MANTIS_DEBUG, 1, "Power ON"); 50 gpio_set_bits(mantis, config->power, POWER_ON); 51 msleep(100); 52 gpio_set_bits(mantis, config->power, POWER_ON); 53 msleep(100); 54 break; 55 56 case POWER_OFF: 57 dprintk(MANTIS_DEBUG, 1, "Power OFF"); 58 gpio_set_bits(mantis, config->power, POWER_OFF); 59 msleep(100); 60 break; 61 62 default: 63 dprintk(MANTIS_DEBUG, 1, "Unknown state <%02x>", power); 64 return -1; 65 } 66 67 return 0; 68} 69EXPORT_SYMBOL_GPL(mantis_frontend_power); 70 71void mantis_frontend_soft_reset(struct mantis_pci *mantis) 72{ 73 struct mantis_hwconfig *config = mantis->hwconfig; 74 75 dprintk(MANTIS_DEBUG, 1, "Frontend RESET"); 76 gpio_set_bits(mantis, config->reset, 0); 77 msleep(100); 78 gpio_set_bits(mantis, config->reset, 0); 79 msleep(100); 80 gpio_set_bits(mantis, config->reset, 1); 81 msleep(100); 82 gpio_set_bits(mantis, config->reset, 1); 83 msleep(100); 84 85 return; 86} 87EXPORT_SYMBOL_GPL(mantis_frontend_soft_reset); 88 89static int mantis_frontend_shutdown(struct mantis_pci *mantis) 90{ 91 int err; 92 93 mantis_frontend_soft_reset(mantis); 94 err = mantis_frontend_power(mantis, POWER_OFF); 95 if (err != 0) { 96 dprintk(MANTIS_ERROR, 1, "Frontend POWER OFF failed! <%d>", err); 97 return 1; 98 } 99 100 return 0; 101} 102 103static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) 104{ 105 struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 106 struct mantis_pci *mantis = dvbdmx->priv; 107 108 dprintk(MANTIS_DEBUG, 1, "Mantis DVB Start feed"); 109 if (!dvbdmx->dmx.frontend) { 110 dprintk(MANTIS_DEBUG, 1, "no frontend ?"); 111 return -EINVAL; 112 } 113 114 mantis->feeds++; 115 dprintk(MANTIS_DEBUG, 1, "mantis start feed, feeds=%d", mantis->feeds); 116 117 if (mantis->feeds == 1) { 118 dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma"); 119 mantis_dma_start(mantis); 120 } 121 122 return mantis->feeds; 123} 124 125static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) 126{ 127 struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 128 struct mantis_pci *mantis = dvbdmx->priv; 129 130 dprintk(MANTIS_DEBUG, 1, "Mantis DVB Stop feed"); 131 if (!dvbdmx->dmx.frontend) { 132 dprintk(MANTIS_DEBUG, 1, "no frontend ?"); 133 return -EINVAL; 134 } 135 136 mantis->feeds--; 137 if (mantis->feeds == 0) { 138 dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma"); 139 mantis_dma_stop(mantis); 140 } 141 142 return 0; 143} 144 145int __devinit mantis_dvb_init(struct mantis_pci *mantis) 146{ 147 struct mantis_hwconfig *config = mantis->hwconfig; 148 int result = -1; 149 150 dprintk(MANTIS_DEBUG, 1, "dvb_register_adapter"); 151 152 result = dvb_register_adapter(&mantis->dvb_adapter, 153 "Mantis DVB adapter", 154 THIS_MODULE, 155 &mantis->pdev->dev, 156 adapter_nr); 157 158 if (result < 0) { 159 160 dprintk(MANTIS_ERROR, 1, "Error registering adapter"); 161 return -ENODEV; 162 } 163 164 mantis->dvb_adapter.priv = mantis; 165 mantis->demux.dmx.capabilities = DMX_TS_FILTERING | 166 DMX_SECTION_FILTERING | 167 DMX_MEMORY_BASED_FILTERING; 168 169 mantis->demux.priv = mantis; 170 mantis->demux.filternum = 256; 171 mantis->demux.feednum = 256; 172 mantis->demux.start_feed = mantis_dvb_start_feed; 173 mantis->demux.stop_feed = mantis_dvb_stop_feed; 174 mantis->demux.write_to_decoder = NULL; 175 176 dprintk(MANTIS_DEBUG, 1, "dvb_dmx_init"); 177 result = dvb_dmx_init(&mantis->demux); 178 if (result < 0) { 179 dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); 180 181 goto err0; 182 } 183 184 mantis->dmxdev.filternum = 256; 185 mantis->dmxdev.demux = &mantis->demux.dmx; 186 mantis->dmxdev.capabilities = 0; 187 dprintk(MANTIS_DEBUG, 1, "dvb_dmxdev_init"); 188 189 result = dvb_dmxdev_init(&mantis->dmxdev, &mantis->dvb_adapter); 190 if (result < 0) { 191 192 dprintk(MANTIS_ERROR, 1, "dvb_dmxdev_init failed, ERROR=%d", result); 193 goto err1; 194 } 195 196 mantis->fe_hw.source = DMX_FRONTEND_0; 197 result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_hw); 198 if (result < 0) { 199 200 dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); 201 goto err2; 202 } 203 204 mantis->fe_mem.source = DMX_MEMORY_FE; 205 result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_mem); 206 if (result < 0) { 207 dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); 208 goto err3; 209 } 210 211 result = mantis->demux.dmx.connect_frontend(&mantis->demux.dmx, &mantis->fe_hw); 212 if (result < 0) { 213 dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result); 214 goto err4; 215 } 216 217 dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx); 218 tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis); 219 if (mantis->hwconfig) { 220 result = config->frontend_init(mantis, mantis->fe); 221 if (result < 0) { 222 dprintk(MANTIS_ERROR, 1, "!!! NO Frontends found !!!"); 223 goto err5; 224 } else { 225 if (mantis->fe == NULL) { 226 dprintk(MANTIS_ERROR, 1, "FE <NULL>"); 227 goto err5; 228 } 229 230 if (dvb_register_frontend(&mantis->dvb_adapter, mantis->fe)) { 231 dprintk(MANTIS_ERROR, 1, "ERROR: Frontend registration failed"); 232 233 if (mantis->fe->ops.release) 234 mantis->fe->ops.release(mantis->fe); 235 236 mantis->fe = NULL; 237 goto err5; 238 } 239 } 240 } 241 242 return 0; 243 244 /* Error conditions .. */ 245err5: 246 tasklet_kill(&mantis->tasklet); 247 dvb_net_release(&mantis->dvbnet); 248 dvb_unregister_frontend(mantis->fe); 249 dvb_frontend_detach(mantis->fe); 250err4: 251 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); 252 253err3: 254 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw); 255 256err2: 257 dvb_dmxdev_release(&mantis->dmxdev); 258 259err1: 260 dvb_dmx_release(&mantis->demux); 261 262err0: 263 dvb_unregister_adapter(&mantis->dvb_adapter); 264 265 return result; 266} 267EXPORT_SYMBOL_GPL(mantis_dvb_init); 268 269int __devexit mantis_dvb_exit(struct mantis_pci *mantis) 270{ 271 int err; 272 273 if (mantis->fe) { 274 /* mantis_ca_exit(mantis); */ 275 err = mantis_frontend_shutdown(mantis); 276 if (err != 0) 277 dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err); 278 dvb_unregister_frontend(mantis->fe); 279 dvb_frontend_detach(mantis->fe); 280 } 281 282 tasklet_kill(&mantis->tasklet); 283 dvb_net_release(&mantis->dvbnet); 284 285 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem); 286 mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw); 287 288 dvb_dmxdev_release(&mantis->dmxdev); 289 dvb_dmx_release(&mantis->demux); 290 291 dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter"); 292 dvb_unregister_adapter(&mantis->dvb_adapter); 293 294 return 0; 295} 296EXPORT_SYMBOL_GPL(mantis_dvb_exit); 297