ddbridge-core.c revision e9013fb6eb397df9fd2e71d4f31a8bad4e65d046
1ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/* 2ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * ddbridge.c: Digital Devices PCIe bridge driver 3ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * 4ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * Copyright (C) 2010-2011 Digital Devices GmbH 5ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * 6ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * This program is free software; you can redistribute it and/or 7ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * modify it under the terms of the GNU General Public License 8ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * version 2 only, as published by the Free Software Foundation. 9ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * 10ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * 11ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * This program is distributed in the hope that it will be useful, 12ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * but WITHOUT ANY WARRANTY; without even the implied warranty of 13ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * GNU General Public License for more details. 15ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * 16ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * 17ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * You should have received a copy of the GNU General Public License 18ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * along with this program; if not, write to the Free Software 19ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 20ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * 02110-1301, USA 21ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler * Or, point your browser to http://www.gnu.org/copyleft/gpl.html 22ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler */ 23ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 24ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include <linux/module.h> 25ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include <linux/init.h> 26ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include <linux/interrupt.h> 27ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include <linux/delay.h> 28ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include <linux/slab.h> 29ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include <linux/poll.h> 3028d45a5d294e3f2beddd355b41fa50a66df726ccMauro Carvalho Chehab#include <linux/io.h> 31ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include <linux/pci.h> 32ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include <linux/pci_ids.h> 33ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include <linux/timer.h> 34ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include <linux/version.h> 35ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include <linux/i2c.h> 36ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include <linux/swab.h> 37ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include <linux/vmalloc.h> 38ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include "ddbridge.h" 39ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 40ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include "ddbridge-regs.h" 41ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 42ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include "tda18271c2dd.h" 43ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include "stv6110x.h" 44ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include "stv090x.h" 45ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include "lnbh24.h" 46ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#include "drxk.h" 47ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 48ccad04578fcbe2678084af0986ac010ab84a023dRalph MetzlerDVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 49ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 50ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/* MSI had problems with lost interrupts, fixed but needs testing */ 51ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#undef CONFIG_PCI_MSI 52ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 53ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 54ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 55ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int i2c_read(struct i2c_adapter *adapter, u8 adr, u8 *val) 56ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 57ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct i2c_msg msgs[1] = {{.addr = adr, .flags = I2C_M_RD, 584f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss .buf = val, .len = 1 } }; 59ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return (i2c_transfer(adapter, msgs, 1) == 1) ? 0 : -1; 60ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 61ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 62ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int i2c_read_reg(struct i2c_adapter *adapter, u8 adr, u8 reg, u8 *val) 63ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 64ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, 65ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .buf = ®, .len = 1 }, 66ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler {.addr = adr, .flags = I2C_M_RD, 674f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss .buf = val, .len = 1 } }; 68ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; 69ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 70ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 71ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int i2c_read_reg16(struct i2c_adapter *adapter, u8 adr, 72ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u16 reg, u8 *val) 73ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 74ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u8 msg[2] = {reg>>8, reg&0xff}; 75ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0, 76ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .buf = msg, .len = 2}, 77ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler {.addr = adr, .flags = I2C_M_RD, 784f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss .buf = val, .len = 1} }; 79ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return (i2c_transfer(adapter, msgs, 2) == 2) ? 0 : -1; 80ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 81ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 82ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int ddb_i2c_cmd(struct ddb_i2c *i2c, u32 adr, u32 cmd) 83ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 84ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = i2c->dev; 85ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int stat; 86ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u32 val; 87ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 88ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler i2c->done = 0; 89ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel((adr << 9) | cmd, i2c->regs + I2C_COMMAND); 90ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler stat = wait_event_timeout(i2c->wq, i2c->done == 1, HZ); 91ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (stat <= 0) { 924f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_ERR "I2C timeout\n"); 93ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler { /* MSI debugging*/ 94ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u32 istat = ddbreadl(INTERRUPT_STATUS); 954f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_ERR "IRS %08x\n", istat); 96ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(istat, INTERRUPT_ACK); 97ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 98ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -EIO; 99ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1004f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss val = ddbreadl(i2c->regs+I2C_COMMAND); 101ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (val & 0x70000) 102ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -EIO; 103ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 104ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 105ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 106ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int ddb_i2c_master_xfer(struct i2c_adapter *adapter, 107ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct i2c_msg msg[], int num) 108ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 109ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_i2c *i2c = (struct ddb_i2c *)i2c_get_adapdata(adapter); 110ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = i2c->dev; 1114f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss u8 addr = 0; 112ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 113ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (num) 114ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler addr = msg[0].addr; 115ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 116ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (num == 2 && msg[1].flags & I2C_M_RD && 117ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler !(msg[0].flags & I2C_M_RD)) { 118ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler memcpy_toio(dev->regs + I2C_TASKMEM_BASE + i2c->wbuf, 1194f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss msg[0].buf, msg[0].len); 120ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(msg[0].len|(msg[1].len << 16), 121ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler i2c->regs+I2C_TASKLENGTH); 122ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!ddb_i2c_cmd(i2c, addr, 1)) { 123ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler memcpy_fromio(msg[1].buf, 124ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dev->regs + I2C_TASKMEM_BASE + i2c->rbuf, 125ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler msg[1].len); 126ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return num; 127ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 128ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 129ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 130ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (num == 1 && !(msg[0].flags & I2C_M_RD)) { 1314f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss ddbcpyto(I2C_TASKMEM_BASE + i2c->wbuf, msg[0].buf, msg[0].len); 132ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(msg[0].len, i2c->regs + I2C_TASKLENGTH); 133ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!ddb_i2c_cmd(i2c, addr, 2)) 134ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return num; 135ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 136ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (num == 1 && (msg[0].flags & I2C_M_RD)) { 137ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(msg[0].len << 16, i2c->regs + I2C_TASKLENGTH); 138ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!ddb_i2c_cmd(i2c, addr, 3)) { 139ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbcpyfrom(msg[0].buf, 140ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler I2C_TASKMEM_BASE + i2c->rbuf, msg[0].len); 141ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return num; 142ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 143ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 144ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -EIO; 145ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 146ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 147ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 148ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic u32 ddb_i2c_functionality(struct i2c_adapter *adap) 149ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 150ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return I2C_FUNC_SMBUS_EMUL; 151ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 152ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 153ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstruct i2c_algorithm ddb_i2c_algo = { 154ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .master_xfer = ddb_i2c_master_xfer, 155ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .functionality = ddb_i2c_functionality, 156ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 157ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 158ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_i2c_release(struct ddb *dev) 159ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 160ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int i; 161ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_i2c *i2c; 162ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct i2c_adapter *adap; 163ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 164ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (i = 0; i < dev->info->port_num; i++) { 165ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler i2c = &dev->i2c[i]; 166ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler adap = &i2c->adap; 167ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler i2c_del_adapter(adap); 168ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 169ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 170ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 171ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int ddb_i2c_init(struct ddb *dev) 172ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 173ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int i, j, stat = 0; 174ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_i2c *i2c; 175ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct i2c_adapter *adap; 176ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 177ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (i = 0; i < dev->info->port_num; i++) { 178ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler i2c = &dev->i2c[i]; 179ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler i2c->dev = dev; 180ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler i2c->nr = i; 181ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler i2c->wbuf = i * (I2C_TASKMEM_SIZE / 4); 182ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler i2c->rbuf = i2c->wbuf + (I2C_TASKMEM_SIZE / 8); 183ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler i2c->regs = 0x80 + i * 0x20; 184ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(I2C_SPEED_100, i2c->regs + I2C_TIMING); 185ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel((i2c->rbuf << 16) | i2c->wbuf, 186ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler i2c->regs + I2C_TASKADDRESS); 187ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler init_waitqueue_head(&i2c->wq); 188ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 189ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler adap = &i2c->adap; 190ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler i2c_set_adapdata(adap, i2c); 191ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#ifdef I2C_ADAP_CLASS_TV_DIGITAL 192ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler adap->class = I2C_ADAP_CLASS_TV_DIGITAL|I2C_CLASS_TV_ANALOG; 193ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#else 194ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#ifdef I2C_CLASS_TV_ANALOG 195ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler adap->class = I2C_CLASS_TV_ANALOG; 196ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#endif 197ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#endif 198ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler strcpy(adap->name, "ddbridge"); 199ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler adap->algo = &ddb_i2c_algo; 200ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler adap->algo_data = (void *)i2c; 201ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler adap->dev.parent = &dev->pdev->dev; 202ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler stat = i2c_add_adapter(adap); 203ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (stat) 204ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 205ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 206ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (stat) 207ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (j = 0; j < i; j++) { 208ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler i2c = &dev->i2c[j]; 209ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler adap = &i2c->adap; 210ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler i2c_del_adapter(adap); 211ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 212ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return stat; 213ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 214ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 215ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 216ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 217ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 218ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 219ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 2204f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss#if 0 221ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void set_table(struct ddb *dev, u32 off, 222ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dma_addr_t *pbuf, u32 num) 223ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 224ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u32 i, base; 225ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u64 mem; 226ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 227ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler base = DMA_BASE_ADDRESS_TABLE + off; 228ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (i = 0; i < num; i++) { 229ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler mem = pbuf[i]; 230ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(mem & 0xffffffff, base + i * 8); 231ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(mem >> 32, base + i * 8 + 4); 232ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 233ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 2344f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss#endif 235ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 236ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_address_table(struct ddb *dev) 237ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 238ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u32 i, j, base; 239ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u64 mem; 240ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dma_addr_t *pbuf; 241ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 242ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (i = 0; i < dev->info->port_num * 2; i++) { 243ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler base = DMA_BASE_ADDRESS_TABLE + i * 0x100; 244ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler pbuf = dev->input[i].pbuf; 245ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (j = 0; j < dev->input[i].dma_buf_num; j++) { 246ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler mem = pbuf[j]; 247ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(mem & 0xffffffff, base + j * 8); 248ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(mem >> 32, base + j * 8 + 4); 249ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 250ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 251ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (i = 0; i < dev->info->port_num; i++) { 252ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler base = DMA_BASE_ADDRESS_TABLE + 0x800 + i * 0x100; 253ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler pbuf = dev->output[i].pbuf; 254ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (j = 0; j < dev->output[i].dma_buf_num; j++) { 255ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler mem = pbuf[j]; 256ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(mem & 0xffffffff, base + j * 8); 257ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(mem >> 32, base + j * 8 + 4); 258ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 259ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 260ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 261ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 262ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void io_free(struct pci_dev *pdev, u8 **vbuf, 263ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dma_addr_t *pbuf, u32 size, int num) 264ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 265ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int i; 266ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 267ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (i = 0; i < num; i++) { 268ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (vbuf[i]) { 269ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler pci_free_consistent(pdev, size, vbuf[i], pbuf[i]); 270ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler vbuf[i] = 0; 271ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 272ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 273ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 274ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 275ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int io_alloc(struct pci_dev *pdev, u8 **vbuf, 276ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dma_addr_t *pbuf, u32 size, int num) 277ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 278ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int i; 279ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 280ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (i = 0; i < num; i++) { 281ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler vbuf[i] = pci_alloc_consistent(pdev, size, &pbuf[i]); 282ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!vbuf[i]) 283ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENOMEM; 284ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 285ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 286ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 287ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 288ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int ddb_buffers_alloc(struct ddb *dev) 289ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 290ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int i; 291ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_port *port; 292ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 293ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (i = 0; i < dev->info->port_num; i++) { 294ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port = &dev->port[i]; 295ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler switch (port->class) { 296ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler case DDB_PORT_TUNER: 297ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (io_alloc(dev->pdev, port->input[0]->vbuf, 298ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[0]->pbuf, 299ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[0]->dma_buf_size, 300ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[0]->dma_buf_num) < 0) 301ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -1; 302ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (io_alloc(dev->pdev, port->input[1]->vbuf, 303ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[1]->pbuf, 304ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[1]->dma_buf_size, 305ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[1]->dma_buf_num) < 0) 306ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -1; 307ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 308ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler case DDB_PORT_CI: 309ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (io_alloc(dev->pdev, port->input[0]->vbuf, 310ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[0]->pbuf, 311ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[0]->dma_buf_size, 312ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[0]->dma_buf_num) < 0) 313ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -1; 314ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (io_alloc(dev->pdev, port->output->vbuf, 315ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->output->pbuf, 316ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->output->dma_buf_size, 317ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->output->dma_buf_num) < 0) 318ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -1; 319ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 320ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler default: 321ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 322ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 323ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 324ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_address_table(dev); 325ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 326ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 327ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 328ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_buffers_free(struct ddb *dev) 329ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 330ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int i; 331ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_port *port; 332ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 333ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (i = 0; i < dev->info->port_num; i++) { 334ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port = &dev->port[i]; 335ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler io_free(dev->pdev, port->input[0]->vbuf, 336ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[0]->pbuf, 337ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[0]->dma_buf_size, 338ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[0]->dma_buf_num); 339ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler io_free(dev->pdev, port->input[1]->vbuf, 340ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[1]->pbuf, 341ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[1]->dma_buf_size, 342ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[1]->dma_buf_num); 343ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler io_free(dev->pdev, port->output->vbuf, 344ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->output->pbuf, 345ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->output->dma_buf_size, 346ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->output->dma_buf_num); 347ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 348ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 349ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 350ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_input_start(struct ddb_input *input) 351ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 352ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = input->port->dev; 353ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 354ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler spin_lock_irq(&input->lock); 355ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->cbuf = 0; 356ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->coff = 0; 357ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 358ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler /* reset */ 359ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, TS_INPUT_CONTROL(input->nr)); 360ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(2, TS_INPUT_CONTROL(input->nr)); 361ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, TS_INPUT_CONTROL(input->nr)); 362ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 363ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel((1 << 16) | 364ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler (input->dma_buf_num << 11) | 365ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler (input->dma_buf_size >> 7), 366ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler DMA_BUFFER_SIZE(input->nr)); 367ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, DMA_BUFFER_ACK(input->nr)); 368ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 369ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(1, DMA_BASE_WRITE); 370ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(3, DMA_BUFFER_CONTROL(input->nr)); 371ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(9, TS_INPUT_CONTROL(input->nr)); 372ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->running = 1; 373ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler spin_unlock_irq(&input->lock); 374ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 375ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 376ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_input_stop(struct ddb_input *input) 377ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 378ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = input->port->dev; 379ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 380ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler spin_lock_irq(&input->lock); 381ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, TS_INPUT_CONTROL(input->nr)); 382ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, DMA_BUFFER_CONTROL(input->nr)); 383ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->running = 0; 384ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler spin_unlock_irq(&input->lock); 385ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 386ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 387ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_output_start(struct ddb_output *output) 388ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 389ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = output->port->dev; 390ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 391ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler spin_lock_irq(&output->lock); 392ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler output->cbuf = 0; 393ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler output->coff = 0; 394ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, TS_OUTPUT_CONTROL(output->nr)); 395ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(2, TS_OUTPUT_CONTROL(output->nr)); 396ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, TS_OUTPUT_CONTROL(output->nr)); 397ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0x3c, TS_OUTPUT_CONTROL(output->nr)); 398ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel((1 << 16) | 399ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler (output->dma_buf_num << 11) | 400ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler (output->dma_buf_size >> 7), 401ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler DMA_BUFFER_SIZE(output->nr + 8)); 402ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, DMA_BUFFER_ACK(output->nr + 8)); 403ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 404ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(1, DMA_BASE_READ); 405ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(3, DMA_BUFFER_CONTROL(output->nr + 8)); 4064f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss /* ddbwritel(0xbd, TS_OUTPUT_CONTROL(output->nr)); */ 407ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0x1d, TS_OUTPUT_CONTROL(output->nr)); 408ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler output->running = 1; 409ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler spin_unlock_irq(&output->lock); 410ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 411ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 412ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_output_stop(struct ddb_output *output) 413ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 414ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = output->port->dev; 415ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 416ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler spin_lock_irq(&output->lock); 417ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, TS_OUTPUT_CONTROL(output->nr)); 418ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, DMA_BUFFER_CONTROL(output->nr + 8)); 419ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler output->running = 0; 420ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler spin_unlock_irq(&output->lock); 421ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 422ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 423ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic u32 ddb_output_free(struct ddb_output *output) 424ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 425ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u32 idx, off, stat = output->stat; 426ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler s32 diff; 427ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 428ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler idx = (stat >> 11) & 0x1f; 429ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler off = (stat & 0x7ff) << 7; 430ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 431ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (output->cbuf != idx) { 432ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if ((((output->cbuf + 1) % output->dma_buf_num) == idx) && 433ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler (output->dma_buf_size - output->coff <= 188)) 434ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 435ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 188; 436ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 437ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler diff = off - output->coff; 438ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (diff <= 0 || diff > 188) 439ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 188; 440ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 441ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 442ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 4434f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endrissstatic ssize_t ddb_output_write(struct ddb_output *output, 444ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler const u8 *buf, size_t count) 445ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 446ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = output->port->dev; 447ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u32 idx, off, stat = output->stat; 448ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u32 left = count, len; 449ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 450ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler idx = (stat >> 11) & 0x1f; 451ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler off = (stat & 0x7ff) << 7; 452ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 453ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler while (left) { 454ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler len = output->dma_buf_size - output->coff; 455ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if ((((output->cbuf + 1) % output->dma_buf_num) == idx) && 456ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler (off == 0)) { 4574f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (len <= 188) 458ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 4594f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss len -= 188; 460ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 461ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (output->cbuf == idx) { 462ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (off > output->coff) { 463ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#if 1 464ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler len = off - output->coff; 465ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler len -= (len % 188); 466ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (len <= 188) 467ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 468ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#endif 469ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 470ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler len -= 188; 471ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 472ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 473ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (len > left) 474ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler len = left; 475ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (copy_from_user(output->vbuf[output->cbuf] + output->coff, 476ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler buf, len)) 477ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -EIO; 478ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler left -= len; 479ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler buf += len; 480ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler output->coff += len; 481ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (output->coff == output->dma_buf_size) { 482ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler output->coff = 0; 483ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler output->cbuf = ((output->cbuf + 1) % output->dma_buf_num); 484ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 485ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel((output->cbuf << 11) | (output->coff >> 7), 486ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler DMA_BUFFER_ACK(output->nr + 8)); 487ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 488ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return count - left; 489ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 490ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 491ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic u32 ddb_input_avail(struct ddb_input *input) 492ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 493ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = input->port->dev; 494ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u32 idx, off, stat = input->stat; 495ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u32 ctrl = ddbreadl(DMA_BUFFER_CONTROL(input->nr)); 496ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 497ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler idx = (stat >> 11) & 0x1f; 498ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler off = (stat & 0x7ff) << 7; 499ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 500ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (ctrl & 4) { 5014f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_ERR "IA %d %d %08x\n", idx, off, ctrl); 502ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(input->stat, DMA_BUFFER_ACK(input->nr)); 503ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 504ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 505ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (input->cbuf != idx) 506ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 188; 507ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 508ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 509ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 510ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic size_t ddb_input_read(struct ddb_input *input, u8 *buf, size_t count) 511ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 512ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = input->port->dev; 513ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u32 left = count; 514ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u32 idx, off, free, stat = input->stat; 515ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int ret; 516ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 517ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler idx = (stat >> 11) & 0x1f; 518ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler off = (stat & 0x7ff) << 7; 519ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 520ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler while (left) { 521ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (input->cbuf == idx) 522ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return count - left; 523ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler free = input->dma_buf_size - input->coff; 524ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (free > left) 525ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler free = left; 526ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ret = copy_to_user(buf, input->vbuf[input->cbuf] + 527ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->coff, free); 528ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->coff += free; 529ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (input->coff == input->dma_buf_size) { 530ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->coff = 0; 531ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->cbuf = (input->cbuf+1) % input->dma_buf_num; 532ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 533ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler left -= free; 534ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel((input->cbuf << 11) | (input->coff >> 7), 535ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler DMA_BUFFER_ACK(input->nr)); 536ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 537ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return count; 538ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 539ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 540ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 541ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 542ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 543ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 544ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#if 0 545ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic struct ddb_input *fe2input(struct ddb *dev, struct dvb_frontend *fe) 546ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 547ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int i; 548ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 549ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (i = 0; i < dev->info->port_num * 2; i++) { 5504f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (dev->input[i].fe == fe) 551ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return &dev->input[i]; 552ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 553ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return NULL; 554ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 555ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#endif 556ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 557ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) 558ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 559ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_input *input = fe->sec_priv; 560ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_port *port = input->port; 561ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int status; 562ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 563ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (enable) { 564ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler mutex_lock(&port->i2c_gate_lock); 565ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler status = input->gate_ctrl(fe, 1); 566ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } else { 567ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler status = input->gate_ctrl(fe, 0); 568ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler mutex_unlock(&port->i2c_gate_lock); 569ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 570ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return status; 571ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 572ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 573ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int demod_attach_drxk(struct ddb_input *input) 574ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 575ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct i2c_adapter *i2c = &input->port->i2c->adap; 576ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct dvb_frontend *fe; 5770fc55e81d3364e6535cacb10b5a579f8c62625b1Mauro Carvalho Chehab struct drxk_config config; 578ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 5790fc55e81d3364e6535cacb10b5a579f8c62625b1Mauro Carvalho Chehab memset(&config, 0, sizeof(config)); 5800fc55e81d3364e6535cacb10b5a579f8c62625b1Mauro Carvalho Chehab config.adr = 0x29 + (input->nr & 1); 5810fc55e81d3364e6535cacb10b5a579f8c62625b1Mauro Carvalho Chehab 5820fc55e81d3364e6535cacb10b5a579f8c62625b1Mauro Carvalho Chehab fe = input->fe = dvb_attach(drxk_attach, &config, i2c, &input->fe2); 583ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!input->fe) { 5844f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_ERR "No DRXK found!\n"); 585ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 586ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 587ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler fe->sec_priv = input; 588ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->gate_ctrl = fe->ops.i2c_gate_ctrl; 589ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; 590ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 591ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 592ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 593ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int tuner_attach_tda18271(struct ddb_input *input) 594ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 595ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct i2c_adapter *i2c = &input->port->i2c->adap; 596ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct dvb_frontend *fe; 597ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 598ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (input->fe->ops.i2c_gate_ctrl) 599ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->fe->ops.i2c_gate_ctrl(input->fe, 1); 600ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler fe = dvb_attach(tda18271c2dd_attach, input->fe, i2c, 0x60); 601ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!fe) { 6024f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_ERR "No TDA18271 found!\n"); 603ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 604ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 605ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (input->fe->ops.i2c_gate_ctrl) 606ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->fe->ops.i2c_gate_ctrl(input->fe, 0); 607ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 608ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 609ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 610ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 611ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 612ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 613ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 614ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic struct stv090x_config stv0900 = { 615ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .device = STV0900, 616ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .demod_mode = STV090x_DUAL, 617ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .clk_mode = STV090x_CLK_EXT, 618ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 619ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .xtal = 27000000, 620ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .address = 0x69, 621ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 622ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED, 623ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, 624ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 625ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .repeater_level = STV090x_RPTLEVEL_16, 626ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 627ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .adc1_range = STV090x_ADC_1Vpp, 628ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .adc2_range = STV090x_ADC_1Vpp, 629ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 630ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .diseqc_envelope_mode = true, 631ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 632ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 633ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic struct stv090x_config stv0900_aa = { 634ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .device = STV0900, 635ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .demod_mode = STV090x_DUAL, 636ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .clk_mode = STV090x_CLK_EXT, 637ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 638ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .xtal = 27000000, 639ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .address = 0x68, 640ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 641ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED, 642ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED, 643ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 644ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .repeater_level = STV090x_RPTLEVEL_16, 645ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 646ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .adc1_range = STV090x_ADC_1Vpp, 647ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .adc2_range = STV090x_ADC_1Vpp, 648ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 649ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .diseqc_envelope_mode = true, 650ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 651ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 652ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic struct stv6110x_config stv6110a = { 653ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .addr = 0x60, 654ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .refclk = 27000000, 655ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .clk_div = 1, 656ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 657ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 658ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic struct stv6110x_config stv6110b = { 659ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .addr = 0x63, 660ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .refclk = 27000000, 661ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .clk_div = 1, 662ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 663ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 664ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int demod_attach_stv0900(struct ddb_input *input, int type) 665ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 666ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct i2c_adapter *i2c = &input->port->i2c->adap; 667ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900; 668ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 6694f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss input->fe = dvb_attach(stv090x_attach, feconf, i2c, 6704f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss (input->nr & 1) ? STV090x_DEMODULATOR_1 6714f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss : STV090x_DEMODULATOR_0); 672ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!input->fe) { 6734f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_ERR "No STV0900 found!\n"); 674ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 675ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 676ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!dvb_attach(lnbh24_attach, input->fe, i2c, 0, 677ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 0, (input->nr & 1) ? 678ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler (0x09 - type) : (0x0b - type))) { 6794f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_ERR "No LNBH24 found!\n"); 680ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 681ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 682ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 683ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 684ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 685ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int tuner_attach_stv6110(struct ddb_input *input, int type) 686ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 687ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct i2c_adapter *i2c = &input->port->i2c->adap; 688ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct stv090x_config *feconf = type ? &stv0900_aa : &stv0900; 689ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct stv6110x_config *tunerconf = (input->nr & 1) ? 690ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler &stv6110b : &stv6110a; 691ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct stv6110x_devctl *ctl; 692ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 693ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ctl = dvb_attach(stv6110x_attach, input->fe, tunerconf, i2c); 694ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!ctl) { 6954f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_ERR "No STV6110X found!\n"); 696ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 697ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 6984f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_INFO "attach tuner input %d adr %02x\n", 6994f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss input->nr, tunerconf->addr); 700ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 701ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler feconf->tuner_init = ctl->tuner_init; 702ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler feconf->tuner_sleep = ctl->tuner_sleep; 703ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler feconf->tuner_set_mode = ctl->tuner_set_mode; 704ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler feconf->tuner_set_frequency = ctl->tuner_set_frequency; 705ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler feconf->tuner_get_frequency = ctl->tuner_get_frequency; 706ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler feconf->tuner_set_bandwidth = ctl->tuner_set_bandwidth; 707ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler feconf->tuner_get_bandwidth = ctl->tuner_get_bandwidth; 708ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler feconf->tuner_set_bbgain = ctl->tuner_set_bbgain; 709ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler feconf->tuner_get_bbgain = ctl->tuner_get_bbgain; 710ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler feconf->tuner_set_refclk = ctl->tuner_set_refclk; 711ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler feconf->tuner_get_status = ctl->tuner_get_status; 712ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 713ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 714ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 715ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 716805e68743460dd48971d5df2707eb445d980874cMauro Carvalho Chehabstatic int my_dvb_dmx_ts_card_init(struct dvb_demux *dvbdemux, char *id, 717ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int (*start_feed)(struct dvb_demux_feed *), 718ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int (*stop_feed)(struct dvb_demux_feed *), 719ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler void *priv) 720ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 721ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvbdemux->priv = priv; 722ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 723ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvbdemux->filternum = 256; 724ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvbdemux->feednum = 256; 725ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvbdemux->start_feed = start_feed; 726ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvbdemux->stop_feed = stop_feed; 727ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvbdemux->write_to_decoder = NULL; 728ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | 729ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler DMX_SECTION_FILTERING | 730ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler DMX_MEMORY_BASED_FILTERING); 731ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return dvb_dmx_init(dvbdemux); 732ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 733ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 734805e68743460dd48971d5df2707eb445d980874cMauro Carvalho Chehabstatic int my_dvb_dmxdev_ts_card_init(struct dmxdev *dmxdev, 735ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct dvb_demux *dvbdemux, 736ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct dmx_frontend *hw_frontend, 737ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct dmx_frontend *mem_frontend, 738ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct dvb_adapter *dvb_adapter) 739ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 740ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int ret; 741ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 742ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dmxdev->filternum = 256; 743ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dmxdev->demux = &dvbdemux->dmx; 744ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dmxdev->capabilities = 0; 745ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ret = dvb_dmxdev_init(dmxdev, dvb_adapter); 746ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (ret < 0) 747ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return ret; 748ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 749ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler hw_frontend->source = DMX_FRONTEND_0; 750ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvbdemux->dmx.add_frontend(&dvbdemux->dmx, hw_frontend); 751ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler mem_frontend->source = DMX_MEMORY_FE; 752ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvbdemux->dmx.add_frontend(&dvbdemux->dmx, mem_frontend); 753ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return dvbdemux->dmx.connect_frontend(&dvbdemux->dmx, hw_frontend); 754ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 755ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 756ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int start_feed(struct dvb_demux_feed *dvbdmxfeed) 757ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 758ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 759ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_input *input = dvbdmx->priv; 760ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 761ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!input->users) 762ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_input_start(input); 763ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 764ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return ++input->users; 765ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 766ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 767ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int stop_feed(struct dvb_demux_feed *dvbdmxfeed) 768ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 769ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct dvb_demux *dvbdmx = dvbdmxfeed->demux; 770ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_input *input = dvbdmx->priv; 771ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 772ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (--input->users) 773ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return input->users; 774ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 775ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_input_stop(input); 776ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 777ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 778ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 779ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 780ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void dvb_input_detach(struct ddb_input *input) 781ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 782ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct dvb_adapter *adap = &input->adap; 783ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct dvb_demux *dvbdemux = &input->demux; 784ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 785ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler switch (input->attached) { 786ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler case 5: 787ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (input->fe2) 788ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvb_unregister_frontend(input->fe2); 789ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (input->fe) { 790ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvb_unregister_frontend(input->fe); 791ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvb_frontend_detach(input->fe); 792ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->fe = NULL; 793ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 794ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler case 4: 795ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvb_net_release(&input->dvbnet); 796ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 797ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler case 3: 798ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvbdemux->dmx.close(&dvbdemux->dmx); 799ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, 800ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler &input->hw_frontend); 801ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, 802ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler &input->mem_frontend); 803ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvb_dmxdev_release(&input->dmxdev); 804ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 805ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler case 2: 806ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvb_dmx_release(&input->demux); 807ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 808ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler case 1: 809ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvb_unregister_adapter(adap); 810ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 811ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->attached = 0; 812ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 813ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 814ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int dvb_input_attach(struct ddb_input *input) 815ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 816ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int ret; 817ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_port *port = input->port; 818ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct dvb_adapter *adap = &input->adap; 819ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct dvb_demux *dvbdemux = &input->demux; 820ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 8214f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss ret = dvb_register_adapter(adap, "DDBridge", THIS_MODULE, 822ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler &input->port->dev->pdev->dev, 823ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler adapter_nr); 824ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (ret < 0) { 8254f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_ERR "ddbridge: Could not register adapter." 826ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler "Check if you enabled enough adapters in dvb-core!\n"); 827ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return ret; 828ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 829ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->attached = 1; 830ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 831ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", 832ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler start_feed, 833ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler stop_feed, input); 834ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (ret < 0) 835ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return ret; 836ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->attached = 2; 837ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 838ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ret = my_dvb_dmxdev_ts_card_init(&input->dmxdev, &input->demux, 839ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler &input->hw_frontend, 840ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler &input->mem_frontend, adap); 841ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (ret < 0) 842ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return ret; 843ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->attached = 3; 844ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 845ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ret = dvb_net_init(adap, &input->dvbnet, input->dmxdev.demux); 846ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (ret < 0) 847ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return ret; 848ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->attached = 4; 849ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 850ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->fe = 0; 851ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler switch (port->type) { 852ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler case DDB_TUNER_DVBS_ST: 853ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (demod_attach_stv0900(input, 0) < 0) 854ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 855ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (tuner_attach_stv6110(input, 0) < 0) 856ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 857ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (input->fe) { 858ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (dvb_register_frontend(adap, input->fe) < 0) 859ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 860ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 861ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 862ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler case DDB_TUNER_DVBS_ST_AA: 863ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (demod_attach_stv0900(input, 1) < 0) 864ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 865ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (tuner_attach_stv6110(input, 1) < 0) 866ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 867ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (input->fe) { 868ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (dvb_register_frontend(adap, input->fe) < 0) 869ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 870ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 871ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 872ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler case DDB_TUNER_DVBCT_TR: 873ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (demod_attach_drxk(input) < 0) 874ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 875ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (tuner_attach_tda18271(input) < 0) 876ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 877ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (input->fe) { 878ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (dvb_register_frontend(adap, input->fe) < 0) 879ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 880ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 881ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (input->fe2) { 882ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (dvb_register_frontend(adap, input->fe2) < 0) 883ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 8844f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss input->fe2->tuner_priv = input->fe->tuner_priv; 885ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler memcpy(&input->fe2->ops.tuner_ops, 886ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler &input->fe->ops.tuner_ops, 887ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler sizeof(struct dvb_tuner_ops)); 888ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 889ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 890ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 891ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->attached = 5; 892ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 893ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 894ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 895ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/****************************************************************************/ 896ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/****************************************************************************/ 897ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 898ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic ssize_t ts_write(struct file *file, const char *buf, 899ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler size_t count, loff_t *ppos) 900ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 901ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct dvb_device *dvbdev = file->private_data; 902ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_output *output = dvbdev->priv; 903ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler size_t left = count; 904ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int stat; 905ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 906ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler while (left) { 907ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (ddb_output_free(output) < 188) { 908ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (file->f_flags & O_NONBLOCK) 909ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 910ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (wait_event_interruptible( 911ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler output->wq, ddb_output_free(output) >= 188) < 0) 912ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 913ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 914ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler stat = ddb_output_write(output, buf, left); 915ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (stat < 0) 916ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 917ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler buf += stat; 918ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler left -= stat; 919ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 920ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return (left == count) ? -EAGAIN : (count - left); 921ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 922ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 923ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic ssize_t ts_read(struct file *file, char *buf, 924ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler size_t count, loff_t *ppos) 925ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 926ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct dvb_device *dvbdev = file->private_data; 927ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_output *output = dvbdev->priv; 928ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_input *input = output->port->input[0]; 929ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int left, read; 930ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 931ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler count -= count % 188; 932ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler left = count; 933ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler while (left) { 934ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (ddb_input_avail(input) < 188) { 935ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (file->f_flags & O_NONBLOCK) 936ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 937ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (wait_event_interruptible( 938ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->wq, ddb_input_avail(input) >= 188) < 0) 939ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 940ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 941ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler read = ddb_input_read(input, buf, left); 942ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler left -= read; 943ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler buf += read; 944ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 945ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return (left == count) ? -EAGAIN : (count - left); 946ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 947ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 948ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic unsigned int ts_poll(struct file *file, poll_table *wait) 949ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 9504f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss /* 951ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct dvb_device *dvbdev = file->private_data; 952ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_output *output = dvbdev->priv; 953ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_input *input = output->port->input[0]; 9544f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss */ 955ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler unsigned int mask = 0; 956ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 957ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#if 0 958ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (data_avail_to_read) 959ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler mask |= POLLIN | POLLRDNORM; 960ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (data_avail_to_write) 961ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler mask |= POLLOUT | POLLWRNORM; 962ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 963ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler poll_wait(file, &read_queue, wait); 964ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler poll_wait(file, &write_queue, wait); 965ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#endif 966ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return mask; 967ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 968ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 9694f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endrissstatic const struct file_operations ci_fops = { 970ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .owner = THIS_MODULE, 971ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .read = ts_read, 972ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .write = ts_write, 973ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .open = dvb_generic_open, 974ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .release = dvb_generic_release, 975ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .poll = ts_poll, 976ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .mmap = 0, 977ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 978ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 979ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic struct dvb_device dvbdev_ci = { 980ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .priv = 0, 981ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .readers = -1, 982ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .writers = -1, 983ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .users = -1, 984ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .fops = &ci_fops, 985ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 986ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 987ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/****************************************************************************/ 988ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/****************************************************************************/ 989ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/****************************************************************************/ 990ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 991ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void input_tasklet(unsigned long data) 992ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 993ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_input *input = (struct ddb_input *) data; 994ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = input->port->dev; 995ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 996ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler spin_lock(&input->lock); 997ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!input->running) { 998ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler spin_unlock(&input->lock); 999ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return; 1000ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1001ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr)); 1002ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1003ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (input->port->class == DDB_PORT_TUNER) { 1004ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr))) 10054f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_ERR "Overflow input %d\n", input->nr); 1006ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler while (input->cbuf != ((input->stat >> 11) & 0x1f) 1007ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler || (4&ddbreadl(DMA_BUFFER_CONTROL(input->nr)))) { 1008ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvb_dmx_swfilter_packets(&input->demux, 1009ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->vbuf[input->cbuf], 1010ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->dma_buf_size / 188); 1011ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1012ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->cbuf = (input->cbuf + 1) % input->dma_buf_num; 1013ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel((input->cbuf << 11), 1014ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler DMA_BUFFER_ACK(input->nr)); 1015ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->stat = ddbreadl(DMA_BUFFER_CURRENT(input->nr)); 1016ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1017ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1018ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (input->port->class == DDB_PORT_CI) 1019ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler wake_up(&input->wq); 1020ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler spin_unlock(&input->lock); 1021ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1022ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1023ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void output_tasklet(unsigned long data) 1024ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1025ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_output *output = (struct ddb_output *) data; 1026ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = output->port->dev; 1027ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1028ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler spin_lock(&output->lock); 1029ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!output->running) { 1030ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler spin_unlock(&output->lock); 1031ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return; 1032ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1033ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler output->stat = ddbreadl(DMA_BUFFER_CURRENT(output->nr + 8)); 1034ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler wake_up(&output->wq); 1035ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler spin_unlock(&output->lock); 1036ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1037ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1038ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1039ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstruct cxd2099_cfg cxd_cfg = { 1040ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .bitrate = 62000, 1041ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .adr = 0x40, 1042ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .polarity = 1, 1043ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .clock_mode = 1, 1044ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 1045ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1046ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int ddb_ci_attach(struct ddb_port *port) 1047ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1048ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int ret; 1049ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1050ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ret = dvb_register_adapter(&port->output->adap, 1051ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler "DDBridge", 1052ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler THIS_MODULE, 1053ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler &port->dev->pdev->dev, 1054ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler adapter_nr); 1055ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (ret < 0) 1056ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return ret; 1057ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->en = cxd2099_attach(&cxd_cfg, port, &port->i2c->adap); 1058ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!port->en) { 1059ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvb_unregister_adapter(&port->output->adap); 1060ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 1061ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1062ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_input_start(port->input[0]); 1063ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_output_start(port->output); 1064ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvb_ca_en50221_init(&port->output->adap, 1065ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->en, 0, 1); 10664f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss ret = dvb_register_device(&port->output->adap, &port->output->dev, 10674f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss &dvbdev_ci, (void *) port->output, 10684f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss DVB_DEVICE_SEC); 1069ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return ret; 1070ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1071ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1072ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int ddb_port_attach(struct ddb_port *port) 1073ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1074ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int ret = 0; 1075ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1076ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler switch (port->class) { 1077ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler case DDB_PORT_TUNER: 1078ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ret = dvb_input_attach(port->input[0]); 10794f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (ret < 0) 1080ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 1081ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ret = dvb_input_attach(port->input[1]); 1082ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 1083ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler case DDB_PORT_CI: 1084ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ret = ddb_ci_attach(port); 1085ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 1086ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler default: 1087ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 1088ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1089ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (ret < 0) 10904f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_ERR "port_attach on port %d failed\n", port->nr); 1091ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return ret; 1092ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1093ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1094ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int ddb_ports_attach(struct ddb *dev) 1095ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1096ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int i, ret = 0; 1097ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_port *port; 1098ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1099ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (i = 0; i < dev->info->port_num; i++) { 1100ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port = &dev->port[i]; 1101ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ret = ddb_port_attach(port); 1102ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (ret < 0) 1103ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 1104ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1105ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return ret; 1106ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1107ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1108ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_ports_detach(struct ddb *dev) 1109ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1110ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int i; 1111ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_port *port; 1112ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1113ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (i = 0; i < dev->info->port_num; i++) { 1114ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port = &dev->port[i]; 1115ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler switch (port->class) { 1116ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler case DDB_PORT_TUNER: 1117ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvb_input_detach(port->input[0]); 1118ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvb_input_detach(port->input[1]); 1119ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 1120ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler case DDB_PORT_CI: 1121ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (port->output->dev) 1122ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvb_unregister_device(port->output->dev); 1123ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (port->en) { 1124ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_input_stop(port->input[0]); 1125ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_output_stop(port->output); 1126ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvb_ca_en50221_release(port->en); 1127ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler kfree(port->en); 1128ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->en = 0; 1129ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dvb_unregister_adapter(&port->output->adap); 1130ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1131ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 1132ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1133ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1134ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1135ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1136ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/****************************************************************************/ 1137ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/****************************************************************************/ 1138ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1139ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int port_has_ci(struct ddb_port *port) 1140ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1141ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u8 val; 11424f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss return i2c_read_reg(&port->i2c->adap, 0x40, 0, &val) ? 0 : 1; 1143ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1144ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1145ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int port_has_stv0900(struct ddb_port *port) 1146ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1147ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u8 val; 1148ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (i2c_read_reg16(&port->i2c->adap, 0x69, 0xf100, &val) < 0) 1149ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 1150ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 1; 1151ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1152ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1153ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int port_has_stv0900_aa(struct ddb_port *port) 1154ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1155ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u8 val; 1156ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (i2c_read_reg16(&port->i2c->adap, 0x68, 0xf100, &val) < 0) 1157ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 1158ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 1; 1159ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1160ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1161ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int port_has_drxks(struct ddb_port *port) 1162ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1163ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u8 val; 1164ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (i2c_read(&port->i2c->adap, 0x29, &val) < 0) 1165ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 1166ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (i2c_read(&port->i2c->adap, 0x2a, &val) < 0) 1167ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 1168ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 1; 1169ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1170ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1171ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_port_probe(struct ddb_port *port) 1172ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1173ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = port->dev; 1174ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler char *modname = "NO MODULE"; 1175ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1176ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->class = DDB_PORT_NONE; 1177ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1178ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (port_has_ci(port)) { 1179ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler modname = "CI"; 1180ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->class = DDB_PORT_CI; 1181ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING); 1182ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } else if (port_has_stv0900(port)) { 1183ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler modname = "DUAL DVB-S2"; 1184ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->class = DDB_PORT_TUNER; 1185ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->type = DDB_TUNER_DVBS_ST; 1186ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING); 1187ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } else if (port_has_stv0900_aa(port)) { 1188ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler modname = "DUAL DVB-S2"; 1189ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->class = DDB_PORT_TUNER; 1190ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->type = DDB_TUNER_DVBS_ST_AA; 1191ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(I2C_SPEED_100, port->i2c->regs + I2C_TIMING); 1192ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } else if (port_has_drxks(port)) { 1193ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler modname = "DUAL DVB-C/T"; 1194ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->class = DDB_PORT_TUNER; 1195ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->type = DDB_TUNER_DVBCT_TR; 1196ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(I2C_SPEED_400, port->i2c->regs + I2C_TIMING); 1197ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 11984f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_INFO "Port %d (TAB %d): %s\n", 11994f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss port->nr, port->nr+1, modname); 1200ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1201ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1202ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_input_init(struct ddb_port *port, int nr) 1203ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1204ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = port->dev; 1205ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_input *input = &dev->input[nr]; 1206ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1207ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->nr = nr; 1208ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->port = port; 1209ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->dma_buf_num = INPUT_DMA_BUFS; 1210ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler input->dma_buf_size = INPUT_DMA_SIZE; 1211ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, TS_INPUT_CONTROL(nr)); 1212ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(2, TS_INPUT_CONTROL(nr)); 1213ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, TS_INPUT_CONTROL(nr)); 1214ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, DMA_BUFFER_ACK(nr)); 1215ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler tasklet_init(&input->tasklet, input_tasklet, (unsigned long) input); 1216ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler spin_lock_init(&input->lock); 1217ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler init_waitqueue_head(&input->wq); 1218ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1219ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1220ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_output_init(struct ddb_port *port, int nr) 1221ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1222ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = port->dev; 1223ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_output *output = &dev->output[nr]; 1224ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler output->nr = nr; 1225ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler output->port = port; 1226ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler output->dma_buf_num = OUTPUT_DMA_BUFS; 1227ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler output->dma_buf_size = OUTPUT_DMA_SIZE; 1228ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1229ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, TS_OUTPUT_CONTROL(nr)); 1230ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(2, TS_OUTPUT_CONTROL(nr)); 1231ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, TS_OUTPUT_CONTROL(nr)); 1232ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler tasklet_init(&output->tasklet, output_tasklet, (unsigned long) output); 1233ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler init_waitqueue_head(&output->wq); 1234ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1235ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1236ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_ports_init(struct ddb *dev) 1237ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1238ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int i; 1239ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_port *port; 1240ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1241ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (i = 0; i < dev->info->port_num; i++) { 1242ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port = &dev->port[i]; 1243ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->dev = dev; 1244ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->nr = i; 1245ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->i2c = &dev->i2c[i]; 1246ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[0] = &dev->input[2 * i]; 1247ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->input[1] = &dev->input[2 * i + 1]; 1248ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->output = &dev->output[i]; 1249ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1250ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler mutex_init(&port->i2c_gate_lock); 1251ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_port_probe(port); 1252ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_input_init(port, 2 * i); 1253ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_input_init(port, 2 * i + 1); 1254ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_output_init(port, i); 1255ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1256ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1257ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1258ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_ports_release(struct ddb *dev) 1259ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1260ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int i; 1261ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_port *port; 1262ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1263ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler for (i = 0; i < dev->info->port_num; i++) { 1264ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port = &dev->port[i]; 1265ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler port->dev = dev; 1266ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler tasklet_kill(&port->input[0]->tasklet); 1267ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler tasklet_kill(&port->input[1]->tasklet); 1268ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler tasklet_kill(&port->output->tasklet); 1269ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1270ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1271ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1272ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/****************************************************************************/ 1273ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/****************************************************************************/ 1274ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/****************************************************************************/ 1275ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1276ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void irq_handle_i2c(struct ddb *dev, int n) 1277ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1278ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_i2c *i2c = &dev->i2c[n]; 1279ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1280ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler i2c->done = 1; 1281ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler wake_up(&i2c->wq); 1282ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1283ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1284ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic irqreturn_t irq_handler(int irq, void *dev_id) 1285ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1286ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = (struct ddb *) dev_id; 1287ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u32 s = ddbreadl(INTERRUPT_STATUS); 1288ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1289ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!s) 1290ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return IRQ_NONE; 1291ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1292ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler do { 1293ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(s, INTERRUPT_ACK); 1294ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 12954f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00000001) 12964f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss irq_handle_i2c(dev, 0); 12974f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00000002) 12984f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss irq_handle_i2c(dev, 1); 12994f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00000004) 13004f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss irq_handle_i2c(dev, 2); 13014f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00000008) 13024f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss irq_handle_i2c(dev, 3); 13034f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss 13044f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00000100) 13054f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss tasklet_schedule(&dev->input[0].tasklet); 13064f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00000200) 13074f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss tasklet_schedule(&dev->input[1].tasklet); 13084f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00000400) 13094f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss tasklet_schedule(&dev->input[2].tasklet); 13104f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00000800) 13114f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss tasklet_schedule(&dev->input[3].tasklet); 13124f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00001000) 13134f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss tasklet_schedule(&dev->input[4].tasklet); 13144f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00002000) 13154f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss tasklet_schedule(&dev->input[5].tasklet); 13164f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00004000) 13174f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss tasklet_schedule(&dev->input[6].tasklet); 13184f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00008000) 13194f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss tasklet_schedule(&dev->input[7].tasklet); 13204f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss 13214f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00010000) 13224f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss tasklet_schedule(&dev->output[0].tasklet); 13234f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00020000) 13244f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss tasklet_schedule(&dev->output[1].tasklet); 13254f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00040000) 13264f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss tasklet_schedule(&dev->output[2].tasklet); 13274f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (s & 0x00080000) 13284f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss tasklet_schedule(&dev->output[3].tasklet); 13294f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss 13304f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss /* if (s & 0x000f0000) printk(KERN_DEBUG "%08x\n", istat); */ 1331ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } while ((s = ddbreadl(INTERRUPT_STATUS))); 1332ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1333ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return IRQ_HANDLED; 1334ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1335ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1336ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 1337ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 1338ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 1339ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1340ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int flashio(struct ddb *dev, u8 *wbuf, u32 wlen, u8 *rbuf, u32 rlen) 1341ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1342ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u32 data, shift; 1343ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1344ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (wlen > 4) 1345ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(1, SPI_CONTROL); 1346ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler while (wlen > 4) { 1347ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler /* FIXME: check for big-endian */ 1348ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler data = swab32(*(u32 *)wbuf); 1349ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler wbuf += 4; 1350ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler wlen -= 4; 1351ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(data, SPI_DATA); 13524f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss while (ddbreadl(SPI_CONTROL) & 0x0004) 13534f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss ; 1354ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1355ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1356ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (rlen) 1357ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0x0001 | ((wlen << (8 + 3)) & 0x1f00), SPI_CONTROL); 1358ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler else 1359ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0x0003 | ((wlen << (8 + 3)) & 0x1f00), SPI_CONTROL); 1360ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 13614f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss data = 0; 1362ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler shift = ((4 - wlen) * 8); 1363ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler while (wlen) { 1364ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler data <<= 8; 1365ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler data |= *wbuf; 1366ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler wlen--; 1367ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler wbuf++; 1368ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1369ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (shift) 1370ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler data <<= shift; 1371ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(data, SPI_DATA); 13724f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss while (ddbreadl(SPI_CONTROL) & 0x0004) 13734f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss ; 1374ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1375ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!rlen) { 1376ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, SPI_CONTROL); 1377ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 1378ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1379ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (rlen > 4) 1380ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(1, SPI_CONTROL); 1381ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1382ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler while (rlen > 4) { 1383ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0xffffffff, SPI_DATA); 13844f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss while (ddbreadl(SPI_CONTROL) & 0x0004) 13854f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss ; 1386ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler data = ddbreadl(SPI_DATA); 1387ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler *(u32 *) rbuf = swab32(data); 1388ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler rbuf += 4; 1389ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler rlen -= 4; 1390ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1391ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0x0003 | ((rlen << (8 + 3)) & 0x1F00), SPI_CONTROL); 1392ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0xffffffff, SPI_DATA); 13934f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss while (ddbreadl(SPI_CONTROL) & 0x0004) 13944f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss ; 1395ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1396ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler data = ddbreadl(SPI_DATA); 1397ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, SPI_CONTROL); 1398ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1399ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (rlen < 4) 1400ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler data <<= ((4 - rlen) * 8); 1401ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1402ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler while (rlen > 0) { 1403ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler *rbuf = ((data >> 24) & 0xff); 1404ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler data <<= 8; 1405ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler rbuf++; 1406ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler rlen--; 1407ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1408ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 1409ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1410ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1411ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#define DDB_MAGIC 'd' 1412ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1413ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstruct ddb_flashio { 1414ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler __u8 *write_buf; 1415ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler __u32 write_len; 1416ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler __u8 *read_buf; 1417ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler __u32 read_len; 1418ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 1419ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1420ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#define IOCTL_DDB_FLASHIO _IOWR(DDB_MAGIC, 0x00, struct ddb_flashio) 1421ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1422ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#define DDB_NAME "ddbridge" 1423ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1424ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic u32 ddb_num; 1425ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic struct ddb *ddbs[32]; 1426ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic struct class *ddb_class; 1427ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int ddb_major; 1428ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1429ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int ddb_open(struct inode *inode, struct file *file) 1430ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1431ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = ddbs[iminor(inode)]; 1432ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1433ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler file->private_data = dev; 1434ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 1435ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1436ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1437ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic long ddb_ioctl(struct file *file, unsigned int cmd, unsigned long arg) 1438ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1439ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = file->private_data; 1440ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler void *parg = (void *)arg; 1441e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter int res; 1442ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1443ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler switch (cmd) { 1444ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler case IOCTL_DDB_FLASHIO: 1445ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler { 1446ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb_flashio fio; 1447ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler u8 *rbuf, *wbuf; 1448ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1449ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (copy_from_user(&fio, parg, sizeof(fio))) 1450e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter return -EFAULT; 1451e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter 1452e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter if (fio.write_len > 1028 || fio.read_len > 1028) 1453e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter return -EINVAL; 1454e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter if (fio.write_len + fio.read_len > 1028) 1455e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter return -EINVAL; 1456e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter 1457ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler wbuf = &dev->iobuf[0]; 1458ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler rbuf = wbuf + fio.write_len; 1459e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter 1460e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter if (copy_from_user(wbuf, fio.write_buf, fio.write_len)) 1461e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter return -EFAULT; 1462e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter res = flashio(dev, wbuf, fio.write_len, rbuf, fio.read_len); 1463e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter if (res) 1464e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter return res; 1465ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (copy_to_user(fio.read_buf, rbuf, fio.read_len)) 1466e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter return -EFAULT; 1467ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler break; 1468ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1469ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler default: 1470e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter return -ENOTTY; 1471ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1472e9013fb6eb397df9fd2e71d4f31a8bad4e65d046Dan Carpenter return 0; 1473ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1474ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 14754f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endrissstatic const struct file_operations ddb_fops = { 1476ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .unlocked_ioctl = ddb_ioctl, 1477ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .open = ddb_open, 1478ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 1479ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1480ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic char *ddb_devnode(struct device *device, mode_t *mode) 1481ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1482ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = dev_get_drvdata(device); 1483ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1484ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return kasprintf(GFP_KERNEL, "ddbridge/card%d", dev->nr); 1485ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1486ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1487ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int ddb_class_create(void) 1488ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 14894f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss ddb_major = register_chrdev(0, DDB_NAME, &ddb_fops); 14904f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (ddb_major < 0) 1491ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return ddb_major; 1492ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1493ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_class = class_create(THIS_MODULE, DDB_NAME); 1494ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (IS_ERR(ddb_class)) { 1495ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler unregister_chrdev(ddb_major, DDB_NAME); 1496ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -1; 1497ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1498ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_class->devnode = ddb_devnode; 1499ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 1500ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1501ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1502ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_class_destroy(void) 1503ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1504ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler class_destroy(ddb_class); 1505ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler unregister_chrdev(ddb_major, DDB_NAME); 1506ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1507ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1508ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int ddb_device_create(struct ddb *dev) 1509ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1510ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dev->nr = ddb_num++; 1511ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dev->ddb_dev = device_create(ddb_class, NULL, 1512ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler MKDEV(ddb_major, dev->nr), 1513ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dev, "ddbridge%d", dev->nr); 1514ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbs[dev->nr] = dev; 1515ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (IS_ERR(dev->ddb_dev)) 1516ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -1; 1517ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 1518ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1519ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1520ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_device_destroy(struct ddb *dev) 1521ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1522ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_num--; 1523ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (IS_ERR(dev->ddb_dev)) 1524ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return; 1525ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler device_destroy(ddb_class, MKDEV(ddb_major, 0)); 1526ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1527ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1528ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1529ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/****************************************************************************/ 1530ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/****************************************************************************/ 1531ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/****************************************************************************/ 1532ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1533ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void ddb_unmap(struct ddb *dev) 1534ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1535ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (dev->regs) 1536ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler iounmap(dev->regs); 1537ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler vfree(dev); 1538ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1539ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1540ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1541ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic void __devexit ddb_remove(struct pci_dev *pdev) 1542ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1543ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev = (struct ddb *) pci_get_drvdata(pdev); 1544ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1545ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_ports_detach(dev); 1546ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_i2c_release(dev); 1547ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1548ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, INTERRUPT_ENABLE); 1549ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler free_irq(dev->pdev->irq, dev); 1550ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#ifdef CONFIG_PCI_MSI 1551ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (dev->msi) 1552ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler pci_disable_msi(dev->pdev); 1553ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#endif 1554ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_ports_release(dev); 1555ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_buffers_free(dev); 1556ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_device_destroy(dev); 1557ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1558ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_unmap(dev); 1559ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler pci_set_drvdata(pdev, 0); 1560ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler pci_disable_device(pdev); 1561ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1562ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1563ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1564ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic int __devinit ddb_probe(struct pci_dev *pdev, 1565ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler const struct pci_device_id *id) 1566ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1567ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler struct ddb *dev; 15684f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss int stat = 0; 1569ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler int irq_flag = IRQF_SHARED; 1570ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 15714f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (pci_enable_device(pdev) < 0) 1572ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENODEV; 1573ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1574ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dev = vmalloc(sizeof(struct ddb)); 1575ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (dev == NULL) 1576ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -ENOMEM; 1577ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler memset(dev, 0, sizeof(struct ddb)); 1578ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1579ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dev->pdev = pdev; 1580ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler pci_set_drvdata(pdev, dev); 1581ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dev->info = (struct ddb_info *) id->driver_data; 15824f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_INFO "DDBridge driver detected: %s\n", dev->info->name); 1583ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 15844f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss dev->regs = ioremap(pci_resource_start(dev->pdev, 0), 15854f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss pci_resource_len(dev->pdev, 0)); 1586ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (!dev->regs) { 1587ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler stat = -ENOMEM; 1588ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler goto fail; 1589ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 15904f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_INFO "HW %08x FW %08x\n", ddbreadl(0), ddbreadl(4)); 1591ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1592ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#ifdef CONFIG_PCI_MSI 1593ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (pci_msi_enabled()) 1594ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler stat = pci_enable_msi(dev->pdev); 1595ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (stat) { 1596ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler printk(KERN_INFO ": MSI not available.\n"); 1597ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } else { 1598ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler irq_flag = 0; 1599ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler dev->msi = 1; 1600ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1601ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#endif 16024f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss stat = request_irq(dev->pdev->irq, irq_handler, 16034f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss irq_flag, "DDBridge", (void *) dev); 16044f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss if (stat < 0) 1605ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler goto fail1; 1606ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, DMA_BASE_WRITE); 1607ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, DMA_BASE_READ); 1608ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0xffffffff, INTERRUPT_ACK); 1609ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0xfff0f, INTERRUPT_ENABLE); 1610ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddbwritel(0, MSI1_ENABLE); 1611ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1612ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (ddb_i2c_init(dev) < 0) 1613ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler goto fail1; 1614ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_ports_init(dev); 1615ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (ddb_buffers_alloc(dev) < 0) { 1616ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler printk(KERN_INFO ": Could not allocate buffer memory\n"); 1617ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler goto fail2; 1618ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler } 1619ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (ddb_ports_attach(dev) < 0) 1620ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler goto fail3; 1621ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_device_create(dev); 1622ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return 0; 1623ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1624ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerfail3: 1625ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_ports_detach(dev); 16264f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_ERR "fail3\n"); 1627ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_ports_release(dev); 1628ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerfail2: 16294f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_ERR "fail2\n"); 1630ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_buffers_free(dev); 1631ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerfail1: 16324f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_ERR "fail1\n"); 1633ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (dev->msi) 1634ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler pci_disable_msi(dev->pdev); 1635ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler free_irq(dev->pdev->irq, dev); 1636ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerfail: 16374f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_ERR "fail\n"); 1638ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_unmap(dev); 1639ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler pci_set_drvdata(pdev, 0); 1640ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler pci_disable_device(pdev); 1641ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -1; 1642ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1643ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1644ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 1645ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 1646ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler/******************************************************************************/ 1647ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1648ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic struct ddb_info ddb_none = { 1649ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .type = DDB_NONE, 1650ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .name = "Digital Devices PCIe bridge", 1651ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 1652ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1653ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic struct ddb_info ddb_octopus = { 1654ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .type = DDB_OCTOPUS, 1655ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .name = "Digital Devices Octopus DVB adapter", 1656ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .port_num = 4, 1657ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 1658ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1659ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic struct ddb_info ddb_octopus_le = { 1660ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .type = DDB_OCTOPUS, 1661ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .name = "Digital Devices Octopus LE DVB adapter", 1662ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .port_num = 2, 1663ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 1664ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1665ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic struct ddb_info ddb_v6 = { 1666ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .type = DDB_OCTOPUS, 1667ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .name = "Digital Devices Cine S2 V6 DVB adapter", 1668ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .port_num = 3, 1669ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 1670ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1671ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler#define DDVID 0xdd01 /* Digital Devices Vendor ID */ 1672ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 16734f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss#define DDB_ID(_vend, _dev, _subvend, _subdev, _driverdata) { \ 1674ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .vendor = _vend, .device = _dev, \ 1675ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .subvendor = _subvend, .subdevice = _subdev, \ 1676ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .driver_data = (unsigned long)&_driverdata } 1677ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1678ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic const struct pci_device_id ddb_id_tbl[] __devinitdata = { 1679ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler DDB_ID(DDVID, 0x0002, DDVID, 0x0001, ddb_octopus), 1680ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler DDB_ID(DDVID, 0x0003, DDVID, 0x0001, ddb_octopus), 1681ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler DDB_ID(DDVID, 0x0003, DDVID, 0x0002, ddb_octopus_le), 1682ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler DDB_ID(DDVID, 0x0003, DDVID, 0x0010, ddb_octopus), 1683ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler DDB_ID(DDVID, 0x0003, DDVID, 0x0020, ddb_v6), 1684ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler /* in case sub-ids got deleted in flash */ 1685ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler DDB_ID(DDVID, 0x0003, PCI_ANY_ID, PCI_ANY_ID, ddb_none), 1686ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler {0} 1687ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 1688ccad04578fcbe2678084af0986ac010ab84a023dRalph MetzlerMODULE_DEVICE_TABLE(pci, ddb_id_tbl); 1689ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1690ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1691ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic struct pci_driver ddb_pci_driver = { 1692ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .name = "DDBridge", 1693ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .id_table = ddb_id_tbl, 1694ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .probe = ddb_probe, 1695ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler .remove = ddb_remove, 1696ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler}; 1697ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1698ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic __init int module_init_ddbridge(void) 1699ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 17004f1f31078745b7af73e1a3a718004807cb1b7846Oliver Endriss printk(KERN_INFO "Digital Devices PCIE bridge driver, " 1701ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler "Copyright (C) 2010-11 Digital Devices GmbH\n"); 1702ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler if (ddb_class_create()) 1703ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return -1; 1704ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler return pci_register_driver(&ddb_pci_driver); 1705ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1706ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1707ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlerstatic __exit void module_exit_ddbridge(void) 1708ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler{ 1709ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler pci_unregister_driver(&ddb_pci_driver); 1710ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler ddb_class_destroy(); 1711ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler} 1712ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1713ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlermodule_init(module_init_ddbridge); 1714ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzlermodule_exit(module_exit_ddbridge); 1715ccad04578fcbe2678084af0986ac010ab84a023dRalph Metzler 1716ccad04578fcbe2678084af0986ac010ab84a023dRalph MetzlerMODULE_DESCRIPTION("Digital Devices PCIe Bridge"); 1717ccad04578fcbe2678084af0986ac010ab84a023dRalph MetzlerMODULE_AUTHOR("Ralph Metzler"); 1718ccad04578fcbe2678084af0986ac010ab84a023dRalph MetzlerMODULE_LICENSE("GPL"); 1719ccad04578fcbe2678084af0986ac010ab84a023dRalph MetzlerMODULE_VERSION("0.5"); 1720