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 "mantis_common.h" 22#include "mantis_core.h" 23#include "mantis_vp1033.h" 24#include "mantis_vp1034.h" 25#include "mantis_vp1041.h" 26#include "mantis_vp2033.h" 27#include "mantis_vp2040.h" 28#include "mantis_vp3030.h" 29 30static int read_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length) 31{ 32 int err; 33 struct i2c_msg msg[] = { 34 { 35 .addr = 0x50, 36 .flags = 0, 37 .buf = data, 38 .len = 1 39 }, { 40 .addr = 0x50, 41 .flags = I2C_M_RD, 42 .buf = data, 43 .len = length 44 }, 45 }; 46 47 err = i2c_transfer(&mantis->adapter, msg, 2); 48 if (err < 0) { 49 dprintk(verbose, MANTIS_ERROR, 1, 50 "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >", 51 err, data[0], data[1]); 52 53 return err; 54 } 55 56 return 0; 57} 58 59static int write_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length) 60{ 61 int err; 62 63 struct i2c_msg msg = { 64 .addr = 0x50, 65 .flags = 0, 66 .buf = data, 67 .len = length 68 }; 69 70 err = i2c_transfer(&mantis->adapter, &msg, 1); 71 if (err < 0) { 72 dprintk(verbose, MANTIS_ERROR, 1, 73 "ERROR: i2c write: < err=%i length=0x%02x d0=0x%02x, d1=0x%02x >", 74 err, length, data[0], data[1]); 75 76 return err; 77 } 78 79 return 0; 80} 81 82static int get_mac_address(struct mantis_pci *mantis) 83{ 84 int err; 85 86 mantis->mac_address[0] = 0x08; 87 err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6); 88 if (err < 0) { 89 dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error"); 90 91 return err; 92 } 93 dprintk(verbose, MANTIS_ERROR, 0, 94 " MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n", 95 mantis->mac_address[0], mantis->mac_address[1], 96 mantis->mac_address[2], mantis->mac_address[3], 97 mantis->mac_address[4], mantis->mac_address[5]); 98 99 return 0; 100} 101 102#define MANTIS_MODEL_UNKNOWN "UNKNOWN" 103#define MANTIS_DEV_UNKNOWN "UNKNOWN" 104 105struct mantis_hwconfig unknown_device = { 106 .model_name = MANTIS_MODEL_UNKNOWN, 107 .dev_type = MANTIS_DEV_UNKNOWN, 108}; 109 110static void mantis_load_config(struct mantis_pci *mantis) 111{ 112 switch (mantis->subsystem_device) { 113 case MANTIS_VP_1033_DVB_S: /* VP-1033 */ 114 mantis->hwconfig = &vp1033_mantis_config; 115 break; 116 case MANTIS_VP_1034_DVB_S: /* VP-1034 */ 117 mantis->hwconfig = &vp1034_mantis_config; 118 break; 119 case MANTIS_VP_1041_DVB_S2: /* VP-1041 */ 120 case TECHNISAT_SKYSTAR_HD2: 121 mantis->hwconfig = &vp1041_mantis_config; 122 break; 123 case MANTIS_VP_2033_DVB_C: /* VP-2033 */ 124 mantis->hwconfig = &vp2033_mantis_config; 125 break; 126 case MANTIS_VP_2040_DVB_C: /* VP-2040 */ 127 case TERRATEC_CINERGY_C_PCI: /* VP-2040 clone */ 128 case TECHNISAT_CABLESTAR_HD2: 129 mantis->hwconfig = &vp2040_mantis_config; 130 break; 131 case MANTIS_VP_3030_DVB_T: /* VP-3030 */ 132 mantis->hwconfig = &vp3030_mantis_config; 133 break; 134 default: 135 mantis->hwconfig = &unknown_device; 136 break; 137 } 138} 139 140int mantis_core_init(struct mantis_pci *mantis) 141{ 142 int err = 0; 143 144 mantis_load_config(mantis); 145 dprintk(verbose, MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n", 146 mantis->hwconfig->model_name, mantis->hwconfig->dev_type, 147 mantis->pdev->bus->number, PCI_SLOT(mantis->pdev->devfn), PCI_FUNC(mantis->pdev->devfn)); 148 dprintk(verbose, MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ", 149 mantis->revision, 150 mantis->subsystem_vendor, mantis->subsystem_device); 151 dprintk(verbose, MANTIS_ERROR, 0, 152 "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n", 153 mantis->pdev->irq, mantis->latency, 154 mantis->mantis_addr, mantis->mantis_mmio); 155 156 err = mantis_i2c_init(mantis); 157 if (err < 0) { 158 dprintk(verbose, MANTIS_ERROR, 1, "Mantis I2C init failed"); 159 return err; 160 } 161 err = get_mac_address(mantis); 162 if (err < 0) { 163 dprintk(verbose, MANTIS_ERROR, 1, "get MAC address failed"); 164 return err; 165 } 166 err = mantis_dma_init(mantis); 167 if (err < 0) { 168 dprintk(verbose, MANTIS_ERROR, 1, "Mantis DMA init failed"); 169 return err; 170 } 171 err = mantis_dvb_init(mantis); 172 if (err < 0) { 173 dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed"); 174 return err; 175 } 176 err = mantis_uart_init(mantis); 177 if (err < 0) { 178 dprintk(verbose, MANTIS_DEBUG, 1, "Mantis UART init failed"); 179 return err; 180 } 181 182 return 0; 183} 184 185int mantis_core_exit(struct mantis_pci *mantis) 186{ 187 mantis_dma_stop(mantis); 188 dprintk(verbose, MANTIS_ERROR, 1, "DMA engine stopping"); 189 190 mantis_uart_exit(mantis); 191 dprintk(verbose, MANTIS_ERROR, 1, "UART exit failed"); 192 193 if (mantis_dma_exit(mantis) < 0) 194 dprintk(verbose, MANTIS_ERROR, 1, "DMA exit failed"); 195 if (mantis_dvb_exit(mantis) < 0) 196 dprintk(verbose, MANTIS_ERROR, 1, "DVB exit failed"); 197 if (mantis_i2c_exit(mantis) < 0) 198 dprintk(verbose, MANTIS_ERROR, 1, "I2C adapter delete.. failed"); 199 200 return 0; 201} 202 203/* Turn the given bit on or off. */ 204void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value) 205{ 206 u32 cur; 207 208 cur = mmread(MANTIS_GPIF_ADDR); 209 if (value) 210 mantis->gpio_status = cur | (1 << bitpos); 211 else 212 mantis->gpio_status = cur & (~(1 << bitpos)); 213 214 mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR); 215 mmwrite(0x00, MANTIS_GPIF_DOUT); 216 udelay(100); 217} 218 219/* direction = 0 , no CI passthrough ; 1 , CI passthrough */ 220void mantis_set_direction(struct mantis_pci *mantis, int direction) 221{ 222 u32 reg; 223 224 reg = mmread(0x28); 225 dprintk(verbose, MANTIS_DEBUG, 1, "TS direction setup"); 226 if (direction == 0x01) { 227 /* to CI */ 228 reg |= 0x04; 229 mmwrite(reg, 0x28); 230 reg &= 0xff - 0x04; 231 mmwrite(reg, 0x28); 232 } else { 233 reg &= 0xff - 0x04; 234 mmwrite(reg, 0x28); 235 reg |= 0x04; 236 mmwrite(reg, 0x28); 237 } 238} 239