1/* 2 Mantis PCI bridge driver 3 4 Copyright (C) Manu Abraham (abraham.manu@gmail.com) 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19*/ 20 21#include <linux/kernel.h> 22#include <linux/signal.h> 23#include <linux/sched.h> 24 25#include <linux/interrupt.h> 26 27#include "dmxdev.h" 28#include "dvbdev.h" 29#include "dvb_demux.h" 30#include "dvb_frontend.h" 31#include "dvb_net.h" 32 33#include "mantis_common.h" 34 35#include "mantis_hif.h" 36#include "mantis_link.h" /* temporary due to physical layer stuff */ 37 38#include "mantis_reg.h" 39 40 41static int mantis_hif_sbuf_opdone_wait(struct mantis_ca *ca) 42{ 43 struct mantis_pci *mantis = ca->ca_priv; 44 int rc = 0; 45 46 if (wait_event_timeout(ca->hif_opdone_wq, 47 ca->hif_event & MANTIS_SBUF_OPDONE, 48 msecs_to_jiffies(500)) == -ERESTARTSYS) { 49 50 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Smart buffer operation timeout !", mantis->num); 51 rc = -EREMOTEIO; 52 } 53 dprintk(MANTIS_DEBUG, 1, "Smart Buffer Operation complete"); 54 ca->hif_event &= ~MANTIS_SBUF_OPDONE; 55 return rc; 56} 57 58static int mantis_hif_write_wait(struct mantis_ca *ca) 59{ 60 struct mantis_pci *mantis = ca->ca_priv; 61 u32 opdone = 0, timeout = 0; 62 int rc = 0; 63 64 if (wait_event_timeout(ca->hif_write_wq, 65 mantis->gpif_status & MANTIS_GPIF_WRACK, 66 msecs_to_jiffies(500)) == -ERESTARTSYS) { 67 68 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write ACK timed out !", mantis->num); 69 rc = -EREMOTEIO; 70 } 71 dprintk(MANTIS_DEBUG, 1, "Write Acknowledged"); 72 mantis->gpif_status &= ~MANTIS_GPIF_WRACK; 73 while (!opdone) { 74 opdone = (mmread(MANTIS_GPIF_STATUS) & MANTIS_SBUF_OPDONE); 75 udelay(500); 76 timeout++; 77 if (timeout > 100) { 78 dprintk(MANTIS_ERROR, 1, "Adater(%d) Slot(0): Write operation timed out!", mantis->num); 79 rc = -ETIMEDOUT; 80 break; 81 } 82 } 83 dprintk(MANTIS_DEBUG, 1, "HIF Write success"); 84 return rc; 85} 86 87 88int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr) 89{ 90 struct mantis_pci *mantis = ca->ca_priv; 91 u32 hif_addr = 0, data, count = 4; 92 93 dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Read", mantis->num); 94 mutex_lock(&ca->ca_lock); 95 hif_addr &= ~MANTIS_GPIF_PCMCIAREG; 96 hif_addr &= ~MANTIS_GPIF_PCMCIAIOM; 97 hif_addr |= MANTIS_HIF_STATUS; 98 hif_addr |= addr; 99 100 mmwrite(hif_addr, MANTIS_GPIF_BRADDR); 101 mmwrite(count, MANTIS_GPIF_BRBYTES); 102 udelay(20); 103 mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); 104 105 if (mantis_hif_sbuf_opdone_wait(ca) != 0) { 106 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): GPIF Smart Buffer operation failed", mantis->num); 107 mutex_unlock(&ca->ca_lock); 108 return -EREMOTEIO; 109 } 110 data = mmread(MANTIS_GPIF_DIN); 111 mutex_unlock(&ca->ca_lock); 112 dprintk(MANTIS_DEBUG, 1, "Mem Read: 0x%02x", data); 113 return (data >> 24) & 0xff; 114} 115 116int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data) 117{ 118 struct mantis_slot *slot = ca->slot; 119 struct mantis_pci *mantis = ca->ca_priv; 120 u32 hif_addr = 0; 121 122 dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Write", mantis->num); 123 mutex_lock(&ca->ca_lock); 124 hif_addr &= ~MANTIS_GPIF_HIFRDWRN; 125 hif_addr &= ~MANTIS_GPIF_PCMCIAREG; 126 hif_addr &= ~MANTIS_GPIF_PCMCIAIOM; 127 hif_addr |= MANTIS_HIF_STATUS; 128 hif_addr |= addr; 129 130 mmwrite(slot->slave_cfg, MANTIS_GPIF_CFGSLA); /* Slot0 alone for now */ 131 mmwrite(hif_addr, MANTIS_GPIF_ADDR); 132 mmwrite(data, MANTIS_GPIF_DOUT); 133 134 if (mantis_hif_write_wait(ca) != 0) { 135 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); 136 mutex_unlock(&ca->ca_lock); 137 return -EREMOTEIO; 138 } 139 dprintk(MANTIS_DEBUG, 1, "Mem Write: (0x%02x to 0x%02x)", data, addr); 140 mutex_unlock(&ca->ca_lock); 141 142 return 0; 143} 144 145int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr) 146{ 147 struct mantis_pci *mantis = ca->ca_priv; 148 u32 data, hif_addr = 0; 149 150 dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Read", mantis->num); 151 mutex_lock(&ca->ca_lock); 152 hif_addr &= ~MANTIS_GPIF_PCMCIAREG; 153 hif_addr |= MANTIS_GPIF_PCMCIAIOM; 154 hif_addr |= MANTIS_HIF_STATUS; 155 hif_addr |= addr; 156 157 mmwrite(hif_addr, MANTIS_GPIF_BRADDR); 158 mmwrite(1, MANTIS_GPIF_BRBYTES); 159 udelay(20); 160 mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); 161 162 if (mantis_hif_sbuf_opdone_wait(ca) != 0) { 163 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); 164 mutex_unlock(&ca->ca_lock); 165 return -EREMOTEIO; 166 } 167 data = mmread(MANTIS_GPIF_DIN); 168 dprintk(MANTIS_DEBUG, 1, "I/O Read: 0x%02x", data); 169 udelay(50); 170 mutex_unlock(&ca->ca_lock); 171 172 return (u8) data; 173} 174 175int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data) 176{ 177 struct mantis_pci *mantis = ca->ca_priv; 178 u32 hif_addr = 0; 179 180 dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Write", mantis->num); 181 mutex_lock(&ca->ca_lock); 182 hif_addr &= ~MANTIS_GPIF_PCMCIAREG; 183 hif_addr &= ~MANTIS_GPIF_HIFRDWRN; 184 hif_addr |= MANTIS_GPIF_PCMCIAIOM; 185 hif_addr |= MANTIS_HIF_STATUS; 186 hif_addr |= addr; 187 188 mmwrite(hif_addr, MANTIS_GPIF_ADDR); 189 mmwrite(data, MANTIS_GPIF_DOUT); 190 191 if (mantis_hif_write_wait(ca) != 0) { 192 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num); 193 mutex_unlock(&ca->ca_lock); 194 return -EREMOTEIO; 195 } 196 dprintk(MANTIS_DEBUG, 1, "I/O Write: (0x%02x to 0x%02x)", data, addr); 197 mutex_unlock(&ca->ca_lock); 198 udelay(50); 199 200 return 0; 201} 202 203int mantis_hif_init(struct mantis_ca *ca) 204{ 205 struct mantis_slot *slot = ca->slot; 206 struct mantis_pci *mantis = ca->ca_priv; 207 u32 irqcfg; 208 209 slot[0].slave_cfg = 0x70773028; 210 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Initializing Mantis Host Interface", mantis->num); 211 212 mutex_lock(&ca->ca_lock); 213 irqcfg = mmread(MANTIS_GPIF_IRQCFG); 214 irqcfg = MANTIS_MASK_BRRDY | 215 MANTIS_MASK_WRACK | 216 MANTIS_MASK_EXTIRQ | 217 MANTIS_MASK_WSTO | 218 MANTIS_MASK_OTHERR | 219 MANTIS_MASK_OVFLW; 220 221 mmwrite(irqcfg, MANTIS_GPIF_IRQCFG); 222 mutex_unlock(&ca->ca_lock); 223 224 return 0; 225} 226 227void mantis_hif_exit(struct mantis_ca *ca) 228{ 229 struct mantis_pci *mantis = ca->ca_priv; 230 u32 irqcfg; 231 232 dprintk(MANTIS_ERROR, 1, "Adapter(%d) Exiting Mantis Host Interface", mantis->num); 233 mutex_lock(&ca->ca_lock); 234 irqcfg = mmread(MANTIS_GPIF_IRQCFG); 235 irqcfg &= ~MANTIS_MASK_BRRDY; 236 mmwrite(irqcfg, MANTIS_GPIF_IRQCFG); 237 mutex_unlock(&ca->ca_lock); 238} 239