Path: blob/master/drivers/media/dvb/mantis/mantis_core.c
15112 views
/*1Mantis PCI bridge driver23Copyright (C) Manu Abraham ([email protected])45This program is free software; you can redistribute it and/or modify6it under the terms of the GNU General Public License as published by7the Free Software Foundation; either version 2 of the License, or8(at your option) any later version.910This program is distributed in the hope that it will be useful,11but WITHOUT ANY WARRANTY; without even the implied warranty of12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13GNU General Public License for more details.1415You should have received a copy of the GNU General Public License16along with this program; if not, write to the Free Software17Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.18*/1920#include "mantis_common.h"21#include "mantis_core.h"22#include "mantis_vp1033.h"23#include "mantis_vp1034.h"24#include "mantis_vp1041.h"25#include "mantis_vp2033.h"26#include "mantis_vp2040.h"27#include "mantis_vp3030.h"2829static int read_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length)30{31int err;32struct i2c_msg msg[] = {33{34.addr = 0x50,35.flags = 0,36.buf = data,37.len = 138}, {39.addr = 0x50,40.flags = I2C_M_RD,41.buf = data,42.len = length43},44};4546err = i2c_transfer(&mantis->adapter, msg, 2);47if (err < 0) {48dprintk(verbose, MANTIS_ERROR, 1,49"ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >",50err, data[0], data[1]);5152return err;53}5455return 0;56}5758static int write_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length)59{60int err;6162struct i2c_msg msg = {63.addr = 0x50,64.flags = 0,65.buf = data,66.len = length67};6869err = i2c_transfer(&mantis->adapter, &msg, 1);70if (err < 0) {71dprintk(verbose, MANTIS_ERROR, 1,72"ERROR: i2c write: < err=%i length=0x%02x d0=0x%02x, d1=0x%02x >",73err, length, data[0], data[1]);7475return err;76}7778return 0;79}8081static int get_mac_address(struct mantis_pci *mantis)82{83int err;8485mantis->mac_address[0] = 0x08;86err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6);87if (err < 0) {88dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error");8990return err;91}92dprintk(verbose, MANTIS_ERROR, 0,93" MAC Address=[%pM]\n", mantis->mac_address);9495return 0;96}9798#define MANTIS_MODEL_UNKNOWN "UNKNOWN"99#define MANTIS_DEV_UNKNOWN "UNKNOWN"100101struct mantis_hwconfig unknown_device = {102.model_name = MANTIS_MODEL_UNKNOWN,103.dev_type = MANTIS_DEV_UNKNOWN,104};105106static void mantis_load_config(struct mantis_pci *mantis)107{108switch (mantis->subsystem_device) {109case MANTIS_VP_1033_DVB_S: /* VP-1033 */110mantis->hwconfig = &vp1033_mantis_config;111break;112case MANTIS_VP_1034_DVB_S: /* VP-1034 */113mantis->hwconfig = &vp1034_mantis_config;114break;115case MANTIS_VP_1041_DVB_S2: /* VP-1041 */116case TECHNISAT_SKYSTAR_HD2:117mantis->hwconfig = &vp1041_mantis_config;118break;119case MANTIS_VP_2033_DVB_C: /* VP-2033 */120mantis->hwconfig = &vp2033_mantis_config;121break;122case MANTIS_VP_2040_DVB_C: /* VP-2040 */123case TERRATEC_CINERGY_C_PCI: /* VP-2040 clone */124case TECHNISAT_CABLESTAR_HD2:125mantis->hwconfig = &vp2040_mantis_config;126break;127case MANTIS_VP_3030_DVB_T: /* VP-3030 */128mantis->hwconfig = &vp3030_mantis_config;129break;130default:131mantis->hwconfig = &unknown_device;132break;133}134}135136int mantis_core_init(struct mantis_pci *mantis)137{138int err = 0;139140mantis_load_config(mantis);141dprintk(verbose, MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n",142mantis->hwconfig->model_name, mantis->hwconfig->dev_type,143mantis->pdev->bus->number, PCI_SLOT(mantis->pdev->devfn), PCI_FUNC(mantis->pdev->devfn));144dprintk(verbose, MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ",145mantis->revision,146mantis->subsystem_vendor, mantis->subsystem_device);147dprintk(verbose, MANTIS_ERROR, 0,148"irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n",149mantis->pdev->irq, mantis->latency,150mantis->mantis_addr, mantis->mantis_mmio);151152err = mantis_i2c_init(mantis);153if (err < 0) {154dprintk(verbose, MANTIS_ERROR, 1, "Mantis I2C init failed");155return err;156}157err = get_mac_address(mantis);158if (err < 0) {159dprintk(verbose, MANTIS_ERROR, 1, "get MAC address failed");160return err;161}162err = mantis_dma_init(mantis);163if (err < 0) {164dprintk(verbose, MANTIS_ERROR, 1, "Mantis DMA init failed");165return err;166}167err = mantis_dvb_init(mantis);168if (err < 0) {169dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed");170return err;171}172err = mantis_uart_init(mantis);173if (err < 0) {174dprintk(verbose, MANTIS_DEBUG, 1, "Mantis UART init failed");175return err;176}177178return 0;179}180181int mantis_core_exit(struct mantis_pci *mantis)182{183mantis_dma_stop(mantis);184dprintk(verbose, MANTIS_ERROR, 1, "DMA engine stopping");185186mantis_uart_exit(mantis);187dprintk(verbose, MANTIS_ERROR, 1, "UART exit failed");188189if (mantis_dma_exit(mantis) < 0)190dprintk(verbose, MANTIS_ERROR, 1, "DMA exit failed");191if (mantis_dvb_exit(mantis) < 0)192dprintk(verbose, MANTIS_ERROR, 1, "DVB exit failed");193if (mantis_i2c_exit(mantis) < 0)194dprintk(verbose, MANTIS_ERROR, 1, "I2C adapter delete.. failed");195196return 0;197}198199/* Turn the given bit on or off. */200void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)201{202u32 cur;203204cur = mmread(MANTIS_GPIF_ADDR);205if (value)206mantis->gpio_status = cur | (1 << bitpos);207else208mantis->gpio_status = cur & (~(1 << bitpos));209210mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);211mmwrite(0x00, MANTIS_GPIF_DOUT);212udelay(100);213}214215/* direction = 0 , no CI passthrough ; 1 , CI passthrough */216void mantis_set_direction(struct mantis_pci *mantis, int direction)217{218u32 reg;219220reg = mmread(0x28);221dprintk(verbose, MANTIS_DEBUG, 1, "TS direction setup");222if (direction == 0x01) {223/* to CI */224reg |= 0x04;225mmwrite(reg, 0x28);226reg &= 0xff - 0x04;227mmwrite(reg, 0x28);228} else {229reg &= 0xff - 0x04;230mmwrite(reg, 0x28);231reg |= 0x04;232mmwrite(reg, 0x28);233}234}235236237