1c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter/* 2c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * pluto2.c - Satelco Easywatch Mobile Terrestrial Receiver [DVB-T] 3c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * 4c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * Copyright (C) 2005 Andreas Oberritter <obi@linuxtv.org> 5c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * 6c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * based on pluto2.c 1.10 - http://instinct-wp8.no-ip.org/pluto/ 7c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * by Dany Salman <salmandany@yahoo.fr> 8c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * Copyright (c) 2004 TDF 9c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * 10c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * This program is free software; you can redistribute it and/or modify 11c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * it under the terms of the GNU General Public License as published by 12c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * the Free Software Foundation; either version 2 of the License, or 13c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * (at your option) any later version. 14c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * 15c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * This program is distributed in the hope that it will be useful, 16c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * but WITHOUT ANY WARRANTY; without even the implied warranty of 17c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * GNU General Public License for more details. 19c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * 20c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * You should have received a copy of the GNU General Public License 21c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * along with this program; if not, write to the Free Software 22c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 23c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * 24c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter */ 25c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 26c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#include <linux/i2c.h> 27c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#include <linux/i2c-algo-bit.h> 28c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#include <linux/init.h> 29a6b7a407865aab9f849dd99a71072b7cd1175116Alexey Dobriyan#include <linux/interrupt.h> 30c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#include <linux/kernel.h> 31c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#include <linux/module.h> 32c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#include <linux/pci.h> 33c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#include <linux/dma-mapping.h> 345a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 35c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 36c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#include "demux.h" 37c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#include "dmxdev.h" 38c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#include "dvb_demux.h" 39c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#include "dvb_frontend.h" 40c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#include "dvb_net.h" 41c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#include "dvbdev.h" 42c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#include "tda1004x.h" 43c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 4478e92006f410a4044f8c1760c25ac9d11d259aa2Janne GrunauDVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 4578e92006f410a4044f8c1760c25ac9d11d259aa2Janne Grunau 46c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define DRIVER_NAME "pluto2" 47c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 48c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define REG_PIDn(n) ((n) << 2) /* PID n pattern registers */ 49c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define REG_PCAR 0x0020 /* PC address register */ 50c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define REG_TSCR 0x0024 /* TS ctrl & status */ 51c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define REG_MISC 0x0028 /* miscellaneous */ 52c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define REG_MMAC 0x002c /* MSB MAC address */ 53c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define REG_IMAC 0x0030 /* ISB MAC address */ 54c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define REG_LMAC 0x0034 /* LSB MAC address */ 55c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define REG_SPID 0x0038 /* SPI data */ 56c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define REG_SLCS 0x003c /* serial links ctrl/status */ 57c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 58c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define PID0_NOFIL (0x0001 << 16) 59c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define PIDn_ENP (0x0001 << 15) 60c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define PID0_END (0x0001 << 14) 61c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define PID0_AFIL (0x0001 << 13) 62c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define PIDn_PID (0x1fff << 0) 63c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 64c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define TSCR_NBPACKETS (0x00ff << 24) 65c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define TSCR_DEM (0x0001 << 17) 66c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define TSCR_DE (0x0001 << 16) 67c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define TSCR_RSTN (0x0001 << 15) 68c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define TSCR_MSKO (0x0001 << 14) 69c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define TSCR_MSKA (0x0001 << 13) 70c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define TSCR_MSKL (0x0001 << 12) 71c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define TSCR_OVR (0x0001 << 11) 72c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define TSCR_AFUL (0x0001 << 10) 73c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define TSCR_LOCK (0x0001 << 9) 74c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define TSCR_IACK (0x0001 << 8) 75c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define TSCR_ADEF (0x007f << 0) 76c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 77c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define MISC_DVR (0x0fff << 4) 78c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define MISC_ALED (0x0001 << 3) 79c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define MISC_FRST (0x0001 << 2) 80c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define MISC_LED1 (0x0001 << 1) 81c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define MISC_LED0 (0x0001 << 0) 82c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 83c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define SPID_SPIDR (0x00ff << 0) 84c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 85c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define SLCS_SCL (0x0001 << 7) 86c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define SLCS_SDA (0x0001 << 6) 87c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define SLCS_CSN (0x0001 << 2) 88c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define SLCS_OVR (0x0001 << 1) 89c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define SLCS_SWC (0x0001 << 0) 90c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 91c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define TS_DMA_PACKETS (8) 92c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define TS_DMA_BYTES (188 * TS_DMA_PACKETS) 93c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 94c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define I2C_ADDR_TDA10046 0x10 95c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define I2C_ADDR_TUA6034 0xc2 96c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define NHWFILTERS 8 97c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 98c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstruct pluto { 99c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* pci */ 100c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct pci_dev *pdev; 101c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter u8 __iomem *io_mem; 102c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 103c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* dvb */ 104c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct dmx_frontend hw_frontend; 105c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct dmx_frontend mem_frontend; 106c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct dmxdev dmxdev; 107c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct dvb_adapter dvb_adapter; 108c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct dvb_demux demux; 109c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct dvb_frontend *fe; 110c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct dvb_net dvbnet; 111c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter unsigned int full_ts_users; 112c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter unsigned int users; 113c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 114c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* i2c */ 115c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct i2c_algo_bit_data i2c_bit; 116c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct i2c_adapter i2c_adap; 117c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter unsigned int i2cbug; 118c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 119c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* irq */ 120c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter unsigned int overflow; 1210b61dca28909bc548581bec75e3b90faaa7f11fdAlan Cox unsigned int dead; 122c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 123c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* dma */ 124c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dma_addr_t dma_addr; 125c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter u8 dma_buf[TS_DMA_BYTES]; 126c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter u8 dummy[4096]; 127c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter}; 128c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 129c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic inline struct pluto *feed_to_pluto(struct dvb_demux_feed *feed) 130c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 131c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return container_of(feed->demux, struct pluto, demux); 132c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 133c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 134c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic inline struct pluto *frontend_to_pluto(struct dvb_frontend *fe) 135c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 136c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return container_of(fe->dvb, struct pluto, dvb_adapter); 137c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 138c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 139c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic inline u32 pluto_readreg(struct pluto *pluto, u32 reg) 140c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 141c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return readl(&pluto->io_mem[reg]); 142c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 143c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 144c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic inline void pluto_writereg(struct pluto *pluto, u32 reg, u32 val) 145c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 146c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter writel(val, &pluto->io_mem[reg]); 147c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 148c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 149c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic inline void pluto_rw(struct pluto *pluto, u32 reg, u32 mask, u32 bits) 150c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 151c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter u32 val = readl(&pluto->io_mem[reg]); 152c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter val &= ~mask; 153c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter val |= bits; 154c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter writel(val, &pluto->io_mem[reg]); 155c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 156c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 1571489f90a49f0603a393e1800d729050f6e332becAndreas Oberritterstatic void pluto_write_tscr(struct pluto *pluto, u32 val) 1581489f90a49f0603a393e1800d729050f6e332becAndreas Oberritter{ 1591489f90a49f0603a393e1800d729050f6e332becAndreas Oberritter /* set the number of packets */ 1601489f90a49f0603a393e1800d729050f6e332becAndreas Oberritter val &= ~TSCR_ADEF; 1611489f90a49f0603a393e1800d729050f6e332becAndreas Oberritter val |= TS_DMA_PACKETS / 2; 1621489f90a49f0603a393e1800d729050f6e332becAndreas Oberritter 1631489f90a49f0603a393e1800d729050f6e332becAndreas Oberritter pluto_writereg(pluto, REG_TSCR, val); 1641489f90a49f0603a393e1800d729050f6e332becAndreas Oberritter} 1651489f90a49f0603a393e1800d729050f6e332becAndreas Oberritter 166c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic void pluto_setsda(void *data, int state) 167c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 168c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct pluto *pluto = data; 169c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 170c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (state) 171c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_rw(pluto, REG_SLCS, SLCS_SDA, SLCS_SDA); 172c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter else 173c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_rw(pluto, REG_SLCS, SLCS_SDA, 0); 174c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 175c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 176c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic void pluto_setscl(void *data, int state) 177c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 178c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct pluto *pluto = data; 179c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 180c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (state) 181c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_rw(pluto, REG_SLCS, SLCS_SCL, SLCS_SCL); 182c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter else 183c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_rw(pluto, REG_SLCS, SLCS_SCL, 0); 184c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 185c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* try to detect i2c_inb() to workaround hardware bug: 186c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * reset SDA to high after SCL has been set to low */ 187c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if ((state) && (pluto->i2cbug == 0)) { 188c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->i2cbug = 1; 189c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } else { 190c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if ((!state) && (pluto->i2cbug == 1)) 191c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_setsda(pluto, 1); 192c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->i2cbug = 0; 193c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } 194c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 195c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 196c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic int pluto_getsda(void *data) 197c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 198c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct pluto *pluto = data; 199c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 200c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return pluto_readreg(pluto, REG_SLCS) & SLCS_SDA; 201c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 202c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 203c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic int pluto_getscl(void *data) 204c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 205c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct pluto *pluto = data; 206c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 207c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return pluto_readreg(pluto, REG_SLCS) & SLCS_SCL; 208c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 209c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 210c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic void pluto_reset_frontend(struct pluto *pluto, int reenable) 211c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 212c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter u32 val = pluto_readreg(pluto, REG_MISC); 213c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 214c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (val & MISC_FRST) { 215c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter val &= ~MISC_FRST; 216c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_writereg(pluto, REG_MISC, val); 217c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } 218c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (reenable) { 219c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter val |= MISC_FRST; 220c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_writereg(pluto, REG_MISC, val); 221c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } 222c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 223c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 224c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic void pluto_reset_ts(struct pluto *pluto, int reenable) 225c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 226c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter u32 val = pluto_readreg(pluto, REG_TSCR); 227c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 228c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (val & TSCR_RSTN) { 229c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter val &= ~TSCR_RSTN; 2301489f90a49f0603a393e1800d729050f6e332becAndreas Oberritter pluto_write_tscr(pluto, val); 231c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } 232c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (reenable) { 233c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter val |= TSCR_RSTN; 2341489f90a49f0603a393e1800d729050f6e332becAndreas Oberritter pluto_write_tscr(pluto, val); 235c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } 236c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 237c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 238c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic void pluto_set_dma_addr(struct pluto *pluto) 239c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 24067778b322780200ac14e95c8089a0bd679a467d9Al Viro pluto_writereg(pluto, REG_PCAR, pluto->dma_addr); 241c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 242c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 243c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic int __devinit pluto_dma_map(struct pluto *pluto) 244c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 245c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->dma_addr = pci_map_single(pluto->pdev, pluto->dma_buf, 246c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter TS_DMA_BYTES, PCI_DMA_FROMDEVICE); 247c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 2488d8bb39b9eba32dd70e87fd5ad5c5dd4ba118e06FUJITA Tomonori return pci_dma_mapping_error(pluto->pdev, pluto->dma_addr); 249c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 250c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 251c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic void pluto_dma_unmap(struct pluto *pluto) 252c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 253c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_unmap_single(pluto->pdev, pluto->dma_addr, 254c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter TS_DMA_BYTES, PCI_DMA_FROMDEVICE); 255c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 256c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 257c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic int pluto_start_feed(struct dvb_demux_feed *f) 258c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 259c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct pluto *pluto = feed_to_pluto(f); 260c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 261c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* enable PID filtering */ 262c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (pluto->users++ == 0) 263c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_rw(pluto, REG_PIDn(0), PID0_AFIL | PID0_NOFIL, 0); 264c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 265c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if ((f->pid < 0x2000) && (f->index < NHWFILTERS)) 266c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, PIDn_ENP | f->pid); 267c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter else if (pluto->full_ts_users++ == 0) 268c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, PID0_NOFIL); 269c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 270c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return 0; 271c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 272c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 273c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic int pluto_stop_feed(struct dvb_demux_feed *f) 274c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 275c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct pluto *pluto = feed_to_pluto(f); 276c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 277c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* disable PID filtering */ 278c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (--pluto->users == 0) 279c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_rw(pluto, REG_PIDn(0), PID0_AFIL, PID0_AFIL); 280c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 281c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if ((f->pid < 0x2000) && (f->index < NHWFILTERS)) 282c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_rw(pluto, REG_PIDn(f->index), PIDn_ENP | PIDn_PID, 0x1fff); 283c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter else if (--pluto->full_ts_users == 0) 284c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_rw(pluto, REG_PIDn(0), PID0_NOFIL, 0); 285c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 286c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return 0; 287c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 288c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 289c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic void pluto_dma_end(struct pluto *pluto, unsigned int nbpackets) 290c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 291c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* synchronize the DMA transfer with the CPU 292c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * first so that we see updated contents. */ 293c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_dma_sync_single_for_cpu(pluto->pdev, pluto->dma_addr, 294c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter TS_DMA_BYTES, PCI_DMA_FROMDEVICE); 295c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 296c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* Workaround for broken hardware: 297c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * [1] On startup NBPACKETS seems to contain an uninitialized value, 29825985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * but no packets have been transferred. 299c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * [2] Sometimes (actually very often) NBPACKETS stays at zero 30025985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * although one packet has been transferred. 3014d8451700171d6bbc254191880f86bfdeec2f74fholger@muscate-magnussen.de * [3] Sometimes (actually rarely), the card gets into an erroneous 3024d8451700171d6bbc254191880f86bfdeec2f74fholger@muscate-magnussen.de * mode where it continuously generates interrupts, claiming it 30325985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * has received nbpackets>TS_DMA_PACKETS packets, but no packet 30425985edcedea6396277003854657b5f3cb31a628Lucas De Marchi * has been transferred. Only a reset seems to solve this 305c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter */ 306c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if ((nbpackets == 0) || (nbpackets > TS_DMA_PACKETS)) { 3076573dd752d50730d44c550ad0467d15871963655Andreas Oberritter unsigned int i = 0; 308c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter while (pluto->dma_buf[i] == 0x47) 309c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter i += 188; 3106573dd752d50730d44c550ad0467d15871963655Andreas Oberritter nbpackets = i / 188; 3114d8451700171d6bbc254191880f86bfdeec2f74fholger@muscate-magnussen.de if (i == 0) { 3124d8451700171d6bbc254191880f86bfdeec2f74fholger@muscate-magnussen.de pluto_reset_ts(pluto, 1); 3134d8451700171d6bbc254191880f86bfdeec2f74fholger@muscate-magnussen.de dev_printk(KERN_DEBUG, &pluto->pdev->dev, "resetting TS because of invalid packet counter\n"); 3144d8451700171d6bbc254191880f86bfdeec2f74fholger@muscate-magnussen.de } 315c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } 316c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 317c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvb_dmx_swfilter_packets(&pluto->demux, pluto->dma_buf, nbpackets); 318c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 319c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* clear the dma buffer. this is needed to be able to identify 320c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter * new valid ts packets above */ 321c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter memset(pluto->dma_buf, 0, nbpackets * 188); 322c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 323c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* reset the dma address */ 324c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_set_dma_addr(pluto); 325c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 326c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* sync the buffer and give it back to the card */ 327c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_dma_sync_single_for_device(pluto->pdev, pluto->dma_addr, 328c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter TS_DMA_BYTES, PCI_DMA_FROMDEVICE); 329c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 330c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 3317d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellsstatic irqreturn_t pluto_irq(int irq, void *dev_id) 332c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 333c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct pluto *pluto = dev_id; 334c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter u32 tscr; 335c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 33625985edcedea6396277003854657b5f3cb31a628Lucas De Marchi /* check whether an interrupt occurred on this device */ 337c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter tscr = pluto_readreg(pluto, REG_TSCR); 338c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (!(tscr & (TSCR_DE | TSCR_OVR))) 339c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return IRQ_NONE; 340c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 341c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (tscr == 0xffffffff) { 3420b61dca28909bc548581bec75e3b90faaa7f11fdAlan Cox if (pluto->dead == 0) 3430b61dca28909bc548581bec75e3b90faaa7f11fdAlan Cox dev_err(&pluto->pdev->dev, "card has hung or been ejected.\n"); 3440b61dca28909bc548581bec75e3b90faaa7f11fdAlan Cox /* It's dead Jim */ 3450b61dca28909bc548581bec75e3b90faaa7f11fdAlan Cox pluto->dead = 1; 346c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return IRQ_HANDLED; 347c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } 348c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 349c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* dma end interrupt */ 350c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (tscr & TSCR_DE) { 351c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_dma_end(pluto, (tscr & TSCR_NBPACKETS) >> 24); 352c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* overflow interrupt */ 353c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (tscr & TSCR_OVR) 354c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->overflow++; 355c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (pluto->overflow) { 356c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dev_err(&pluto->pdev->dev, "overflow irq (%d)\n", 357c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->overflow); 358c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_reset_ts(pluto, 1); 359c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->overflow = 0; 360c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } 361c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } else if (tscr & TSCR_OVR) { 362c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->overflow++; 363c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } 364c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 365c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* ACK the interrupt */ 3661489f90a49f0603a393e1800d729050f6e332becAndreas Oberritter pluto_write_tscr(pluto, tscr | TSCR_IACK); 367c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 368c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return IRQ_HANDLED; 369c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 370c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 371c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic void __devinit pluto_enable_irqs(struct pluto *pluto) 372c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 373c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter u32 val = pluto_readreg(pluto, REG_TSCR); 374c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 375c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* disable AFUL and LOCK interrupts */ 376c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter val |= (TSCR_MSKA | TSCR_MSKL); 377c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* enable DMA and OVERFLOW interrupts */ 378c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter val &= ~(TSCR_DEM | TSCR_MSKO); 379c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* clear pending interrupts */ 380c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter val |= TSCR_IACK; 381c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 3821489f90a49f0603a393e1800d729050f6e332becAndreas Oberritter pluto_write_tscr(pluto, val); 383c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 384c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 385c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic void pluto_disable_irqs(struct pluto *pluto) 386c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 387c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter u32 val = pluto_readreg(pluto, REG_TSCR); 388c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 389c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* disable all interrupts */ 390c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter val |= (TSCR_DEM | TSCR_MSKO | TSCR_MSKA | TSCR_MSKL); 391c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* clear pending interrupts */ 392c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter val |= TSCR_IACK; 393c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 3941489f90a49f0603a393e1800d729050f6e332becAndreas Oberritter pluto_write_tscr(pluto, val); 395c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 396c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 397c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic int __devinit pluto_hw_init(struct pluto *pluto) 398c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 399c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_reset_frontend(pluto, 1); 400c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 401c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* set automatic LED control by FPGA */ 402c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_rw(pluto, REG_MISC, MISC_ALED, MISC_ALED); 403c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 404c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* set data endianess */ 405c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#ifdef __LITTLE_ENDIAN 406c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_rw(pluto, REG_PIDn(0), PID0_END, PID0_END); 407c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#else 408c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_rw(pluto, REG_PIDn(0), PID0_END, 0); 409c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#endif 410c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* map DMA and set address */ 411c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_dma_map(pluto); 412c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_set_dma_addr(pluto); 413c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 414c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* enable interrupts */ 415c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_enable_irqs(pluto); 416c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 417c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* reset TS logic */ 418c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_reset_ts(pluto, 1); 419c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 420c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return 0; 421c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 422c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 423c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic void pluto_hw_exit(struct pluto *pluto) 424c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 425c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* disable interrupts */ 426c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_disable_irqs(pluto); 427c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 428c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_reset_ts(pluto, 0); 429c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 430c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* LED: disable automatic control, enable yellow, disable green */ 431c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_rw(pluto, REG_MISC, MISC_ALED | MISC_LED1 | MISC_LED0, MISC_LED1); 432c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 433c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* unmap DMA */ 434c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_dma_unmap(pluto); 435c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 436c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_reset_frontend(pluto, 0); 437c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 438c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 439c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic inline u32 divide(u32 numerator, u32 denominator) 440c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 441c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (denominator == 0) 442c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return ~0; 443c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 44475b697f747b14b0c6afae48ee0f5e605abd2df4cJulia Lawall return DIV_ROUND_CLOSEST(numerator, denominator); 445c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 446c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 447c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter/* LG Innotek TDTE-E001P (Infineon TUA6034) */ 44814d24d148c7521b2b88b396652e36f55d061e195Mauro Carvalho Chehabstatic int lg_tdtpe001p_tuner_set_params(struct dvb_frontend *fe) 449c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 4502f786bbefc2f1cab6e9560476ea69003d19ee5cbMauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache; 451c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct pluto *pluto = frontend_to_pluto(fe); 452c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct i2c_msg msg; 453c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter int ret; 454c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter u8 buf[4]; 455c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter u32 div; 456c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 457c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter // Fref = 166.667 Hz 458c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter // Fref * 3 = 500.000 Hz 459c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter // IF = 36166667 460c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter // IF / Fref = 217 461c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter //div = divide(p->frequency + 36166667, 166667); 462c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter div = divide(p->frequency * 3, 500000) + 217; 463c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter buf[0] = (div >> 8) & 0x7f; 464c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter buf[1] = (div >> 0) & 0xff; 465c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 466c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (p->frequency < 611000000) 467c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter buf[2] = 0xb4; 468c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter else if (p->frequency < 811000000) 469c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter buf[2] = 0xbc; 470c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter else 471c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter buf[2] = 0xf4; 472c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 473c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter // VHF: 174-230 MHz 474c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter // center: 350 MHz 475c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter // UHF: 470-862 MHz 476c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (p->frequency < 350000000) 477c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter buf[3] = 0x02; 478c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter else 479c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter buf[3] = 0x04; 480c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 4812f786bbefc2f1cab6e9560476ea69003d19ee5cbMauro Carvalho Chehab if (p->bandwidth_hz == 8000000) 482c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter buf[3] |= 0x08; 483c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 484c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (sizeof(buf) == 6) { 485c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter buf[4] = buf[2]; 486c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter buf[4] &= ~0x1c; 487c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter buf[4] |= 0x18; 488c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 489c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter buf[5] = (0 << 7) | (2 << 4); 490c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } 491c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 492c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter msg.addr = I2C_ADDR_TUA6034 >> 1; 493c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter msg.flags = 0; 494c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter msg.buf = buf; 495c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter msg.len = sizeof(buf); 496c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 497dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher if (fe->ops.i2c_gate_ctrl) 498dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher fe->ops.i2c_gate_ctrl(fe, 1); 499c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter ret = i2c_transfer(&pluto->i2c_adap, &msg, 1); 500c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (ret < 0) 501c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return ret; 502c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter else if (ret == 0) 503c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return -EREMOTEIO; 504c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 505c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return 0; 506c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 507c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 508c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic int pluto2_request_firmware(struct dvb_frontend *fe, 509c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter const struct firmware **fw, char *name) 510c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 511c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct pluto *pluto = frontend_to_pluto(fe); 512c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 513c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return request_firmware(fw, name, &pluto->pdev->dev); 514c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 515c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 516c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic struct tda1004x_config pluto2_fe_config __devinitdata = { 517c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter .demod_address = I2C_ADDR_TDA10046 >> 1, 518c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter .invert = 1, 519c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter .invert_oclk = 0, 520c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter .xtal_freq = TDA10046_XTAL_16M, 521c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter .agc_config = TDA10046_AGC_DEFAULT, 522c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter .if_freq = TDA10046_FREQ_3617, 523c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter .request_firmware = pluto2_request_firmware, 524c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter}; 525c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 526c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic int __devinit frontend_init(struct pluto *pluto) 527c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 528c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter int ret; 529c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 530c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->fe = tda10046_attach(&pluto2_fe_config, &pluto->i2c_adap); 531c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (!pluto->fe) { 532c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dev_err(&pluto->pdev->dev, "could not attach frontend\n"); 533c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return -ENODEV; 534c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } 535dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher pluto->fe->ops.tuner_ops.set_params = lg_tdtpe001p_tuner_set_params; 536c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 537c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter ret = dvb_register_frontend(&pluto->dvb_adapter, pluto->fe); 538c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (ret < 0) { 539dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher if (pluto->fe->ops.release) 540dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher pluto->fe->ops.release(pluto->fe); 541c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return ret; 542c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } 543c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 544c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return 0; 545c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 546c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 547c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic void __devinit pluto_read_rev(struct pluto *pluto) 548c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 549c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter u32 val = pluto_readreg(pluto, REG_MISC) & MISC_DVR; 550c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dev_info(&pluto->pdev->dev, "board revision %d.%d\n", 551c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter (val >> 12) & 0x0f, (val >> 4) & 0xff); 552c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 553c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 554c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic void __devinit pluto_read_mac(struct pluto *pluto, u8 *mac) 555c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 556c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter u32 val = pluto_readreg(pluto, REG_MMAC); 557c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter mac[0] = (val >> 8) & 0xff; 558c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter mac[1] = (val >> 0) & 0xff; 559c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 560c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter val = pluto_readreg(pluto, REG_IMAC); 561c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter mac[2] = (val >> 8) & 0xff; 562c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter mac[3] = (val >> 0) & 0xff; 563c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 564c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter val = pluto_readreg(pluto, REG_LMAC); 565c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter mac[4] = (val >> 8) & 0xff; 566c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter mac[5] = (val >> 0) & 0xff; 567c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 5687c510e4b730a92cecf94ada45c989d8be0200d47Johannes Berg dev_info(&pluto->pdev->dev, "MAC %pM\n", mac); 569c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 570c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 571c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic int __devinit pluto_read_serial(struct pluto *pluto) 572c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 573c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct pci_dev *pdev = pluto->pdev; 574c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter unsigned int i, j; 575c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter u8 __iomem *cis; 576c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 577c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter cis = pci_iomap(pdev, 1, 0); 578c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (!cis) 579c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return -EIO; 580c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 581c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dev_info(&pdev->dev, "S/N "); 582c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 583c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter for (i = 0xe0; i < 0x100; i += 4) { 584c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter u32 val = readl(&cis[i]); 585c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter for (j = 0; j < 32; j += 8) { 586c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if ((val & 0xff) == 0xff) 587c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto out; 588c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter printk("%c", val & 0xff); 589c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter val >>= 8; 590c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } 591c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } 592c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterout: 593c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter printk("\n"); 594c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_iounmap(pdev, cis); 595c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 596c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return 0; 597c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 598c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 599c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic int __devinit pluto2_probe(struct pci_dev *pdev, 600c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter const struct pci_device_id *ent) 601c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 602c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct pluto *pluto; 603c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct dvb_adapter *dvb_adapter; 604c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct dvb_demux *dvbdemux; 605c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct dmx_demux *dmx; 606c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter int ret = -ENOMEM; 607c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 6087408187d223f63d46a13b6a35b8f96b032c2f623Panagiotis Issaris pluto = kzalloc(sizeof(struct pluto), GFP_KERNEL); 609c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (!pluto) 610c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto out; 611c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 612c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->pdev = pdev; 613c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 614c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter ret = pci_enable_device(pdev); 615c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (ret < 0) 616c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto err_kfree; 617c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 618c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* enable interrupts */ 619c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_write_config_dword(pdev, 0x6c, 0x8000); 620c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 621284901a90a9e0b812ca3f5f852cbbfb60d10249dYang Hongyang ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); 622c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (ret < 0) 623c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto err_pci_disable_device; 624c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 625c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_set_master(pdev); 626c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 627c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter ret = pci_request_regions(pdev, DRIVER_NAME); 628c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (ret < 0) 629c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto err_pci_disable_device; 630c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 631c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->io_mem = pci_iomap(pdev, 0, 0x40); 632c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (!pluto->io_mem) { 633c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter ret = -EIO; 634c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto err_pci_release_regions; 635c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter } 636c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 637c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_set_drvdata(pdev, pluto); 638c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 6398076fe32a7db9a6628589ffa372808e4ba25d222Thomas Gleixner ret = request_irq(pdev->irq, pluto_irq, IRQF_SHARED, DRIVER_NAME, pluto); 640c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (ret < 0) 641c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto err_pci_iounmap; 642c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 643c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter ret = pluto_hw_init(pluto); 644c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (ret < 0) 645c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto err_free_irq; 646c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 647c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* i2c */ 648c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter i2c_set_adapdata(&pluto->i2c_adap, pluto); 649c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter strcpy(pluto->i2c_adap.name, DRIVER_NAME); 650c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->i2c_adap.owner = THIS_MODULE; 651c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->i2c_adap.dev.parent = &pdev->dev; 652c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->i2c_adap.algo_data = &pluto->i2c_bit; 653c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->i2c_bit.data = pluto; 654c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->i2c_bit.setsda = pluto_setsda; 655c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->i2c_bit.setscl = pluto_setscl; 656c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->i2c_bit.getsda = pluto_getsda; 657c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->i2c_bit.getscl = pluto_getscl; 658c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->i2c_bit.udelay = 10; 659c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->i2c_bit.timeout = 10; 660c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 661c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* Raise SCL and SDA */ 662c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_setsda(pluto, 1); 663c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_setscl(pluto, 1); 664c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 665c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter ret = i2c_bit_add_bus(&pluto->i2c_adap); 666c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (ret < 0) 667c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto err_pluto_hw_exit; 668c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 669c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* dvb */ 67078e92006f410a4044f8c1760c25ac9d11d259aa2Janne Grunau ret = dvb_register_adapter(&pluto->dvb_adapter, DRIVER_NAME, 67178e92006f410a4044f8c1760c25ac9d11d259aa2Janne Grunau THIS_MODULE, &pdev->dev, adapter_nr); 672c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (ret < 0) 6733269711b76ba27b78862c48398b0d313ccaa99c2Jean Delvare goto err_i2c_del_adapter; 674c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 675c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvb_adapter = &pluto->dvb_adapter; 676c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 677c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_read_rev(pluto); 678c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_read_serial(pluto); 679c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_read_mac(pluto, dvb_adapter->proposed_mac); 680c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 681c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvbdemux = &pluto->demux; 682c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvbdemux->filternum = 256; 683c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvbdemux->feednum = 256; 684c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvbdemux->start_feed = pluto_start_feed; 685c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvbdemux->stop_feed = pluto_stop_feed; 686c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | 687c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); 688c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter ret = dvb_dmx_init(dvbdemux); 689c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (ret < 0) 690c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto err_dvb_unregister_adapter; 691c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 692c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dmx = &dvbdemux->dmx; 693c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 694c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->hw_frontend.source = DMX_FRONTEND_0; 695c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->mem_frontend.source = DMX_MEMORY_FE; 696c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->dmxdev.filternum = NHWFILTERS; 697c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto->dmxdev.demux = dmx; 698c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 699c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter ret = dvb_dmxdev_init(&pluto->dmxdev, dvb_adapter); 700c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (ret < 0) 701c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto err_dvb_dmx_release; 702c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 703c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter ret = dmx->add_frontend(dmx, &pluto->hw_frontend); 704c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (ret < 0) 705c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto err_dvb_dmxdev_release; 706c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 707c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter ret = dmx->add_frontend(dmx, &pluto->mem_frontend); 708c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (ret < 0) 709c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto err_remove_hw_frontend; 710c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 711c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter ret = dmx->connect_frontend(dmx, &pluto->hw_frontend); 712c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (ret < 0) 713c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto err_remove_mem_frontend; 714c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 715c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter ret = frontend_init(pluto); 716c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (ret < 0) 717c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto err_disconnect_frontend; 718c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 719c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvb_net_init(dvb_adapter, &pluto->dvbnet, dmx); 720c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterout: 721c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return ret; 722c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 723c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberrittererr_disconnect_frontend: 724c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dmx->disconnect_frontend(dmx); 725c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberrittererr_remove_mem_frontend: 726c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dmx->remove_frontend(dmx, &pluto->mem_frontend); 727c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberrittererr_remove_hw_frontend: 728c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dmx->remove_frontend(dmx, &pluto->hw_frontend); 729c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberrittererr_dvb_dmxdev_release: 730c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvb_dmxdev_release(&pluto->dmxdev); 731c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberrittererr_dvb_dmx_release: 732c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvb_dmx_release(dvbdemux); 733c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberrittererr_dvb_unregister_adapter: 734c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvb_unregister_adapter(dvb_adapter); 7353269711b76ba27b78862c48398b0d313ccaa99c2Jean Delvareerr_i2c_del_adapter: 7363269711b76ba27b78862c48398b0d313ccaa99c2Jean Delvare i2c_del_adapter(&pluto->i2c_adap); 737c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberrittererr_pluto_hw_exit: 738c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_hw_exit(pluto); 739c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberrittererr_free_irq: 740c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter free_irq(pdev->irq, pluto); 741c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberrittererr_pci_iounmap: 742c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_iounmap(pdev, pluto->io_mem); 743c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberrittererr_pci_release_regions: 744c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_release_regions(pdev); 745c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberrittererr_pci_disable_device: 746c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_disable_device(pdev); 747c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberrittererr_kfree: 748c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_set_drvdata(pdev, NULL); 749c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter kfree(pluto); 750c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter goto out; 751c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 752c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 753c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic void __devexit pluto2_remove(struct pci_dev *pdev) 754c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 755c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct pluto *pluto = pci_get_drvdata(pdev); 756c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct dvb_adapter *dvb_adapter = &pluto->dvb_adapter; 757c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct dvb_demux *dvbdemux = &pluto->demux; 758c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter struct dmx_demux *dmx = &dvbdemux->dmx; 759c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 760c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dmx->close(dmx); 761c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvb_net_release(&pluto->dvbnet); 762c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter if (pluto->fe) 763c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvb_unregister_frontend(pluto->fe); 764c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 765c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dmx->disconnect_frontend(dmx); 766c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dmx->remove_frontend(dmx, &pluto->mem_frontend); 767c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dmx->remove_frontend(dmx, &pluto->hw_frontend); 768c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvb_dmxdev_release(&pluto->dmxdev); 769c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvb_dmx_release(dvbdemux); 770c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter dvb_unregister_adapter(dvb_adapter); 7713269711b76ba27b78862c48398b0d313ccaa99c2Jean Delvare i2c_del_adapter(&pluto->i2c_adap); 772c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pluto_hw_exit(pluto); 773c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter free_irq(pdev->irq, pluto); 774c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_iounmap(pdev, pluto->io_mem); 775c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_release_regions(pdev); 776c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_disable_device(pdev); 777c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_set_drvdata(pdev, NULL); 778c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter kfree(pluto); 779c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 780c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 781c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#ifndef PCI_VENDOR_ID_SCM 782c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define PCI_VENDOR_ID_SCM 0x0432 783c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#endif 784c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#ifndef PCI_DEVICE_ID_PLUTO2 785c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#define PCI_DEVICE_ID_PLUTO2 0x0001 786c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter#endif 787c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 788c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic struct pci_device_id pluto2_id_table[] __devinitdata = { 789c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter { 790c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter .vendor = PCI_VENDOR_ID_SCM, 791c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter .device = PCI_DEVICE_ID_PLUTO2, 792c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter .subvendor = PCI_ANY_ID, 793c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter .subdevice = PCI_ANY_ID, 794c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter }, { 795c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter /* empty */ 796c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter }, 797c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter}; 798c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 799c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas OberritterMODULE_DEVICE_TABLE(pci, pluto2_id_table); 800c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 801c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic struct pci_driver pluto2_driver = { 802c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter .name = DRIVER_NAME, 803c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter .id_table = pluto2_id_table, 804c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter .probe = pluto2_probe, 805c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter .remove = __devexit_p(pluto2_remove), 806c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter}; 807c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 808c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic int __init pluto2_init(void) 809c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 810c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter return pci_register_driver(&pluto2_driver); 811c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 812c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 813c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritterstatic void __exit pluto2_exit(void) 814c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter{ 815c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter pci_unregister_driver(&pluto2_driver); 816c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter} 817c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 818c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberrittermodule_init(pluto2_init); 819c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberrittermodule_exit(pluto2_exit); 820c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas Oberritter 821c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas OberritterMODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>"); 822c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas OberritterMODULE_DESCRIPTION("Pluto2 driver"); 823c7cadb3a02b5803c2f251b5cd84fbdc8fbec05e9Andreas OberritterMODULE_LICENSE("GPL"); 824