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 get_mac_address(struct mantis_pci *mantis) 60{ 61 int err; 62 63 mantis->mac_address[0] = 0x08; 64 err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6); 65 if (err < 0) { 66 dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error"); 67 68 return err; 69 } 70 dprintk(verbose, MANTIS_ERROR, 0, 71 " MAC Address=[%pM]\n", mantis->mac_address); 72 73 return 0; 74} 75 76#define MANTIS_MODEL_UNKNOWN "UNKNOWN" 77#define MANTIS_DEV_UNKNOWN "UNKNOWN" 78 79struct mantis_hwconfig unknown_device = { 80 .model_name = MANTIS_MODEL_UNKNOWN, 81 .dev_type = MANTIS_DEV_UNKNOWN, 82}; 83 84static void mantis_load_config(struct mantis_pci *mantis) 85{ 86 switch (mantis->subsystem_device) { 87 case MANTIS_VP_1033_DVB_S: /* VP-1033 */ 88 mantis->hwconfig = &vp1033_mantis_config; 89 break; 90 case MANTIS_VP_1034_DVB_S: /* VP-1034 */ 91 mantis->hwconfig = &vp1034_mantis_config; 92 break; 93 case MANTIS_VP_1041_DVB_S2: /* VP-1041 */ 94 case TECHNISAT_SKYSTAR_HD2: 95 mantis->hwconfig = &vp1041_mantis_config; 96 break; 97 case MANTIS_VP_2033_DVB_C: /* VP-2033 */ 98 mantis->hwconfig = &vp2033_mantis_config; 99 break; 100 case MANTIS_VP_2040_DVB_C: /* VP-2040 */ 101 case CINERGY_C: /* VP-2040 clone */ 102 case TECHNISAT_CABLESTAR_HD2: 103 mantis->hwconfig = &vp2040_mantis_config; 104 break; 105 case MANTIS_VP_3030_DVB_T: /* VP-3030 */ 106 mantis->hwconfig = &vp3030_mantis_config; 107 break; 108 default: 109 mantis->hwconfig = &unknown_device; 110 break; 111 } 112} 113 114int mantis_core_init(struct mantis_pci *mantis) 115{ 116 int err = 0; 117 118 mantis_load_config(mantis); 119 dprintk(verbose, MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n", 120 mantis->hwconfig->model_name, mantis->hwconfig->dev_type, 121 mantis->pdev->bus->number, PCI_SLOT(mantis->pdev->devfn), PCI_FUNC(mantis->pdev->devfn)); 122 dprintk(verbose, MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ", 123 mantis->revision, 124 mantis->subsystem_vendor, mantis->subsystem_device); 125 dprintk(verbose, MANTIS_ERROR, 0, 126 "irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n", 127 mantis->pdev->irq, mantis->latency, 128 mantis->mantis_addr, mantis->mantis_mmio); 129 130 err = mantis_i2c_init(mantis); 131 if (err < 0) { 132 dprintk(verbose, MANTIS_ERROR, 1, "Mantis I2C init failed"); 133 return err; 134 } 135 err = get_mac_address(mantis); 136 if (err < 0) { 137 dprintk(verbose, MANTIS_ERROR, 1, "get MAC address failed"); 138 return err; 139 } 140 err = mantis_dma_init(mantis); 141 if (err < 0) { 142 dprintk(verbose, MANTIS_ERROR, 1, "Mantis DMA init failed"); 143 return err; 144 } 145 err = mantis_dvb_init(mantis); 146 if (err < 0) { 147 dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed"); 148 return err; 149 } 150 err = mantis_uart_init(mantis); 151 if (err < 0) { 152 dprintk(verbose, MANTIS_DEBUG, 1, "Mantis UART init failed"); 153 return err; 154 } 155 156 return 0; 157} 158 159int mantis_core_exit(struct mantis_pci *mantis) 160{ 161 mantis_dma_stop(mantis); 162 dprintk(verbose, MANTIS_ERROR, 1, "DMA engine stopping"); 163 164 mantis_uart_exit(mantis); 165 dprintk(verbose, MANTIS_ERROR, 1, "UART exit failed"); 166 167 if (mantis_dma_exit(mantis) < 0) 168 dprintk(verbose, MANTIS_ERROR, 1, "DMA exit failed"); 169 if (mantis_dvb_exit(mantis) < 0) 170 dprintk(verbose, MANTIS_ERROR, 1, "DVB exit failed"); 171 if (mantis_i2c_exit(mantis) < 0) 172 dprintk(verbose, MANTIS_ERROR, 1, "I2C adapter delete.. failed"); 173 174 return 0; 175} 176 177/* Turn the given bit on or off. */ 178void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value) 179{ 180 u32 cur; 181 182 cur = mmread(MANTIS_GPIF_ADDR); 183 if (value) 184 mantis->gpio_status = cur | (1 << bitpos); 185 else 186 mantis->gpio_status = cur & (~(1 << bitpos)); 187 188 mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR); 189 mmwrite(0x00, MANTIS_GPIF_DOUT); 190 udelay(100); 191} 192 193/* direction = 0 , no CI passthrough ; 1 , CI passthrough */ 194void mantis_set_direction(struct mantis_pci *mantis, int direction) 195{ 196 u32 reg; 197 198 reg = mmread(0x28); 199 dprintk(verbose, MANTIS_DEBUG, 1, "TS direction setup"); 200 if (direction == 0x01) { 201 /* to CI */ 202 reg |= 0x04; 203 mmwrite(reg, 0x28); 204 reg &= 0xff - 0x04; 205 mmwrite(reg, 0x28); 206 } else { 207 reg &= 0xff - 0x04; 208 mmwrite(reg, 0x28); 209 reg |= 0x04; 210 mmwrite(reg, 0x28); 211 } 212} 213