Merge branch 'mantis' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'mantis' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (117 commits) V4L/DVB (13851): Fix Input dependency for Mantis V4L/DVB(13824a): mantis: Fix __devexit bad annotations V4L/DVB (13808b): mantis: replace DMA_nnBIT_MASK to DMA_BIT_MASK(32) V4L/DVB (13808): [Mantis/Hopper] Build update for Mantis/Hopper based cards V4L/DVB(13808a): mantis: convert it to the new ir-core register/unregister functions V4L/DVB (13812): [Mantis/Hopper] Update Copyright header V4L/DVB (13811): [MB86A16] Update Copyright header V4L/DVB (13810): [MB86A16] Use DVB_* macros V4L/DVB (13809): Fix Checkpatch violations V4L/DVB (13807): Fix: Free device in the device registration failure case V4L/DVB (13806): Register and Initialize Remote control V4L/DVB (13805): Fix: Unregister the frontend before detaching V4L/DVB (13804): Remove unused I2C Adapter ID V4L/DVB (13803): Remove unused dependency on CU1216 V4L/DVB (13802): [Mantis/Hopper] Fix all build related warnings V4L/DVB (13801): [MB86A16] Use the search callback V4L/DVB (13800): [Mantis] I2C optimization. Required delay is much lesser than 1mS. V4L/DVB (13799): [Mantis] Unregister frontend V4L/DVB (13798): [Mantis] Enable power for all cards, use byte mode only on relevant devices V4L/DVB (13797): [Mantis/Hopper/TDA665x] Large overhaul, ...
This commit is contained in:
commit
2faae42233
|
@ -72,6 +72,10 @@ comment "Supported Earthsoft PT1 Adapters"
|
|||
depends on DVB_CORE && PCI && I2C
|
||||
source "drivers/media/dvb/pt1/Kconfig"
|
||||
|
||||
comment "Supported Mantis Adapters"
|
||||
depends on DVB_CORE && PCI && I2C
|
||||
source "drivers/media/dvb/mantis/Kconfig"
|
||||
|
||||
comment "Supported DVB Frontends"
|
||||
depends on DVB_CORE
|
||||
source "drivers/media/dvb/frontends/Kconfig"
|
||||
|
|
|
@ -2,6 +2,18 @@
|
|||
# Makefile for the kernel multimedia device drivers.
|
||||
#
|
||||
|
||||
obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ pt1/
|
||||
obj-y := dvb-core/ \
|
||||
frontends/ \
|
||||
ttpci/ \
|
||||
ttusb-dec/ \
|
||||
ttusb-budget/ \
|
||||
b2c2/ \
|
||||
bt8xx/ \
|
||||
dvb-usb/ \
|
||||
pluto2/ \
|
||||
siano/ \
|
||||
dm1105/ \
|
||||
pt1/ \
|
||||
mantis/
|
||||
|
||||
obj-$(CONFIG_DVB_FIREDTV) += firewire/
|
||||
|
|
|
@ -208,6 +208,14 @@ config DVB_DS3000
|
|||
help
|
||||
A DVB-S/S2 tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_MB86A16
|
||||
tristate "Fujitsu MB86A16 based"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
help
|
||||
A DVB-S/DSS Direct Conversion reveiver.
|
||||
Say Y when you want to support this frontend.
|
||||
|
||||
comment "DVB-T (terrestrial) frontends"
|
||||
depends on DVB_CORE
|
||||
|
||||
|
@ -587,6 +595,17 @@ config DVB_ATBM8830
|
|||
help
|
||||
A DMB-TH tuner module. Say Y when you want to support this frontend.
|
||||
|
||||
config DVB_TDA665x
|
||||
tristate "TDA665x tuner"
|
||||
depends on DVB_CORE && I2C
|
||||
default m if DVB_FE_CUSTOMISE
|
||||
help
|
||||
Support for tuner modules based on Philips TDA6650/TDA6651 chips.
|
||||
Say Y when you want to support this chip.
|
||||
|
||||
Currently supported tuners:
|
||||
* Panasonic ENV57H12D5 (ET-50DT)
|
||||
|
||||
comment "Tools to develop new frontends"
|
||||
|
||||
config DVB_DUMMY_FE
|
||||
|
|
|
@ -64,6 +64,7 @@ obj-$(CONFIG_DVB_TDA10048) += tda10048.o
|
|||
obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o
|
||||
obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
|
||||
obj-$(CONFIG_DVB_LGS8GL5) += lgs8gl5.o
|
||||
obj-$(CONFIG_DVB_TDA665x) += tda665x.o
|
||||
obj-$(CONFIG_DVB_LGS8GXX) += lgs8gxx.o
|
||||
obj-$(CONFIG_DVB_ATBM8830) += atbm8830.o
|
||||
obj-$(CONFIG_DVB_DUMMY_FE) += dvb_dummy_fe.o
|
||||
|
@ -80,3 +81,4 @@ obj-$(CONFIG_DVB_STV6110x) += stv6110x.o
|
|||
obj-$(CONFIG_DVB_ISL6423) += isl6423.o
|
||||
obj-$(CONFIG_DVB_EC100) += ec100.o
|
||||
obj-$(CONFIG_DVB_DS3000) += ds3000.o
|
||||
obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Fujitsu MB86A16 DVB-S/DSS DC Receiver driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MB86A16_H
|
||||
#define __MB86A16_H
|
||||
|
||||
#include <linux/dvb/frontend.h>
|
||||
#include "dvb_frontend.h"
|
||||
|
||||
|
||||
struct mb86a16_config {
|
||||
u8 demod_address;
|
||||
|
||||
int (*set_voltage)(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#if defined(CONFIG_DVB_MB86A16) || (defined(CONFIG_DVB_MB86A16_MODULE) && defined(MODULE))
|
||||
|
||||
extern struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config,
|
||||
struct i2c_adapter *i2c_adap);
|
||||
|
||||
#else
|
||||
|
||||
static inline struct dvb_frontend *mb86a16_attach(const struct mb86a16_config *config,
|
||||
struct i2c_adapter *i2c_adap)
|
||||
{
|
||||
printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DVB_MB86A16 */
|
||||
|
||||
#endif /* __MB86A16_H */
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
Fujitsu MB86A16 DVB-S/DSS DC Receiver driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MB86A16_PRIV_H
|
||||
#define __MB86A16_PRIV_H
|
||||
|
||||
#define MB86A16_TSOUT 0x00
|
||||
#define MB86A16_TSOUT_HIZSEL (0x01 << 5)
|
||||
#define MB86A16_TSOUT_HIZCNTI (0x01 << 4)
|
||||
#define MB86A16_TSOUT_MODE (0x01 << 3)
|
||||
#define MB86A16_TSOUT_ORDER (0x01 << 2)
|
||||
#define MB86A16_TSOUT_ERROR (0x01 << 1)
|
||||
#define Mb86A16_TSOUT_EDGE (0x01 << 0)
|
||||
|
||||
#define MB86A16_FEC 0x01
|
||||
#define MB86A16_FEC_FSYNC (0x01 << 5)
|
||||
#define MB86A16_FEC_PCKB8 (0x01 << 4)
|
||||
#define MB86A16_FEC_DVDS (0x01 << 3)
|
||||
#define MB86A16_FEC_EREN (0x01 << 2)
|
||||
#define Mb86A16_FEC_RSEN (0x01 << 1)
|
||||
#define MB86A16_FEC_DIEN (0x01 << 0)
|
||||
|
||||
#define MB86A16_AGC 0x02
|
||||
#define MB86A16_AGC_AGMD (0x01 << 6)
|
||||
#define MB86A16_AGC_AGCW (0x0f << 2)
|
||||
#define MB86A16_AGC_AGCP (0x01 << 1)
|
||||
#define MB86A16_AGC_AGCR (0x01 << 0)
|
||||
|
||||
#define MB86A16_SRATE1 0x03
|
||||
#define MB86A16_SRATE1_DECI (0x07 << 2)
|
||||
#define MB86A16_SRATE1_CSEL (0x01 << 1)
|
||||
#define MB86A16_SRATE1_RSEL (0x01 << 0)
|
||||
|
||||
#define MB86A16_SRATE2 0x04
|
||||
#define MB86A16_SRATE2_STOFSL (0xff << 0)
|
||||
|
||||
#define MB86A16_SRATE3 0x05
|
||||
#define MB86A16_SRATE2_STOFSH (0xff << 0)
|
||||
|
||||
#define MB86A16_VITERBI 0x06
|
||||
#define MB86A16_FRAMESYNC 0x07
|
||||
#define MB86A16_CRLFILTCOEF1 0x08
|
||||
#define MB86A16_CRLFILTCOEF2 0x09
|
||||
#define MB86A16_STRFILTCOEF1 0x0a
|
||||
#define MB86A16_STRFILTCOEF2 0x0b
|
||||
#define MB86A16_RESET 0x0c
|
||||
#define MB86A16_STATUS 0x0d
|
||||
#define MB86A16_AFCML 0x0e
|
||||
#define MB86A16_AFCMH 0x0f
|
||||
#define MB86A16_BERMON 0x10
|
||||
#define MB86A16_BERTAB 0x11
|
||||
#define MB86A16_BERLSB 0x12
|
||||
#define MB86A16_BERMID 0x13
|
||||
#define MB86A16_BERMSB 0x14
|
||||
#define MB86A16_AGCM 0x15
|
||||
|
||||
#define MB86A16_DCC1 0x16
|
||||
#define MB86A16_DCC1_DISTA (0x01 << 7)
|
||||
#define MB86A16_DCC1_PRTY (0x01 << 6)
|
||||
#define MB86A16_DCC1_CTOE (0x01 << 5)
|
||||
#define MB86A16_DCC1_TBEN (0x01 << 4)
|
||||
#define MB86A16_DCC1_TBO (0x01 << 3)
|
||||
#define MB86A16_DCC1_NUM (0x07 << 0)
|
||||
|
||||
#define MB86A16_DCC2 0x17
|
||||
#define MB86A16_DCC2_DCBST (0x01 << 0)
|
||||
|
||||
#define MB86A16_DCC3 0x18
|
||||
#define MB86A16_DCC3_CODE0 (0xff << 0)
|
||||
|
||||
#define MB86A16_DCC4 0x19
|
||||
#define MB86A16_DCC4_CODE1 (0xff << 0)
|
||||
|
||||
#define MB86A16_DCC5 0x1a
|
||||
#define MB86A16_DCC5_CODE2 (0xff << 0)
|
||||
|
||||
#define MB86A16_DCC6 0x1b
|
||||
#define MB86A16_DCC6_CODE3 (0xff << 0)
|
||||
|
||||
#define MB86A16_DCC7 0x1c
|
||||
#define MB86A16_DCC7_CODE4 (0xff << 0)
|
||||
|
||||
#define MB86A16_DCC8 0x1d
|
||||
#define MB86A16_DCC8_CODE5 (0xff << 0)
|
||||
|
||||
#define MB86A16_DCCOUT 0x1e
|
||||
#define MB86A16_DCCOUT_DISEN (0x01 << 0)
|
||||
|
||||
#define MB86A16_TONEOUT1 0x1f
|
||||
#define MB86A16_TONE_TDIVL (0xff << 0)
|
||||
|
||||
#define MB86A16_TONEOUT2 0x20
|
||||
#define MB86A16_TONE_TMD (0x03 << 2)
|
||||
#define MB86A16_TONE_TDIVH (0x03 << 0)
|
||||
|
||||
#define MB86A16_FREQ1 0x21
|
||||
#define MB86A16_FREQ2 0x22
|
||||
#define MB86A16_FREQ3 0x23
|
||||
#define MB86A16_FREQ4 0x24
|
||||
#define MB86A16_FREQSET 0x25
|
||||
#define MB86A16_CNM 0x26
|
||||
#define MB86A16_PORT0 0x27
|
||||
#define MB86A16_PORT1 0x28
|
||||
#define MB86A16_DRCFILT 0x29
|
||||
#define MB86A16_AFC 0x2a
|
||||
#define MB86A16_AFCEXL 0x2b
|
||||
#define MB86A16_AFCEXH 0x2c
|
||||
#define MB86A16_DAGC 0x2d
|
||||
#define MB86A16_SEQMODE 0x32
|
||||
#define MB86A16_S0S1T 0x33
|
||||
#define MB86A16_S2S3T 0x34
|
||||
#define MB86A16_S4S5T 0x35
|
||||
#define MB86A16_CNTMR 0x36
|
||||
#define MB86A16_SIG1 0x37
|
||||
#define MB86A16_SIG2 0x38
|
||||
#define MB86A16_VIMAG 0x39
|
||||
#define MB86A16_VISET1 0x3a
|
||||
#define MB86A16_VISET2 0x3b
|
||||
#define MB86A16_VISET3 0x3c
|
||||
#define MB86A16_FAGCS1 0x3d
|
||||
#define MB86A16_FAGCS2 0x3e
|
||||
#define MB86A16_FAGCS3 0x3f
|
||||
#define MB86A16_FAGCS4 0x40
|
||||
#define MB86A16_FAGCS5 0x41
|
||||
#define MB86A16_FAGCS6 0x42
|
||||
#define MB86A16_CRM 0x43
|
||||
#define MB86A16_STRM 0x44
|
||||
#define MB86A16_DAGCML 0x45
|
||||
#define MB86A16_DAGCMH 0x46
|
||||
#define MB86A16_QPSKTST 0x49
|
||||
#define MB86A16_DISTMON 0x52
|
||||
#define MB86A16_VERSION 0x7f
|
||||
|
||||
#endif /* __MB86A16_PRIV_H */
|
|
@ -426,6 +426,10 @@ struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
|
|||
id = tda10021_readreg(state, 0x1a);
|
||||
if ((id & 0xf0) != 0x70) goto error;
|
||||
|
||||
/* Don't claim TDA10023 */
|
||||
if (id == 0x7d)
|
||||
goto error;
|
||||
|
||||
printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n",
|
||||
state->config->demod_address, id);
|
||||
|
||||
|
|
|
@ -0,0 +1,257 @@
|
|||
/*
|
||||
TDA665x tuner driver
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
#include "tda665x.h"
|
||||
|
||||
struct tda665x_state {
|
||||
struct dvb_frontend *fe;
|
||||
struct i2c_adapter *i2c;
|
||||
const struct tda665x_config *config;
|
||||
|
||||
u32 frequency;
|
||||
u32 bandwidth;
|
||||
};
|
||||
|
||||
static int tda665x_read(struct tda665x_state *state, u8 *buf)
|
||||
{
|
||||
const struct tda665x_config *config = state->config;
|
||||
int err = 0;
|
||||
struct i2c_msg msg = { .addr = config->addr, .flags = I2C_M_RD, .buf = buf, .len = 2 };
|
||||
|
||||
err = i2c_transfer(state->i2c, &msg, 1);
|
||||
if (err != 1)
|
||||
goto exit;
|
||||
|
||||
return err;
|
||||
exit:
|
||||
printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tda665x_write(struct tda665x_state *state, u8 *buf, u8 length)
|
||||
{
|
||||
const struct tda665x_config *config = state->config;
|
||||
int err = 0;
|
||||
struct i2c_msg msg = { .addr = config->addr, .flags = 0, .buf = buf, .len = length };
|
||||
|
||||
err = i2c_transfer(state->i2c, &msg, 1);
|
||||
if (err != 1)
|
||||
goto exit;
|
||||
|
||||
return err;
|
||||
exit:
|
||||
printk(KERN_ERR "%s: I/O Error err=<%d>\n", __func__, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tda665x_get_state(struct dvb_frontend *fe,
|
||||
enum tuner_param param,
|
||||
struct tuner_state *tstate)
|
||||
{
|
||||
struct tda665x_state *state = fe->tuner_priv;
|
||||
int err = 0;
|
||||
|
||||
switch (param) {
|
||||
case DVBFE_TUNER_FREQUENCY:
|
||||
tstate->frequency = state->frequency;
|
||||
break;
|
||||
case DVBFE_TUNER_BANDWIDTH:
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param);
|
||||
err = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tda665x_get_status(struct dvb_frontend *fe, u32 *status)
|
||||
{
|
||||
struct tda665x_state *state = fe->tuner_priv;
|
||||
u8 result = 0;
|
||||
int err = 0;
|
||||
|
||||
*status = 0;
|
||||
|
||||
err = tda665x_read(state, &result);
|
||||
if (err < 0)
|
||||
goto exit;
|
||||
|
||||
if ((result >> 6) & 0x01) {
|
||||
printk(KERN_DEBUG "%s: Tuner Phase Locked\n", __func__);
|
||||
*status = 1;
|
||||
}
|
||||
|
||||
return err;
|
||||
exit:
|
||||
printk(KERN_ERR "%s: I/O Error\n", __func__);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tda665x_set_state(struct dvb_frontend *fe,
|
||||
enum tuner_param param,
|
||||
struct tuner_state *tstate)
|
||||
{
|
||||
struct tda665x_state *state = fe->tuner_priv;
|
||||
const struct tda665x_config *config = state->config;
|
||||
u32 frequency, status = 0;
|
||||
u8 buf[4];
|
||||
int err = 0;
|
||||
|
||||
if (param & DVBFE_TUNER_FREQUENCY) {
|
||||
|
||||
frequency = tstate->frequency;
|
||||
if ((frequency < config->frequency_max) || (frequency > config->frequency_min)) {
|
||||
printk(KERN_ERR "%s: Frequency beyond limits, frequency=%d\n", __func__, frequency);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
frequency += config->frequency_offst;
|
||||
frequency *= config->ref_multiplier;
|
||||
frequency += config->ref_divider >> 1;
|
||||
frequency /= config->ref_divider;
|
||||
|
||||
buf[0] = (u8) (frequency & 0x7f00) >> 8;
|
||||
buf[1] = (u8) (frequency & 0x00ff) >> 0;
|
||||
buf[2] = 0x80 | 0x40 | 0x02;
|
||||
buf[3] = 0x00;
|
||||
|
||||
/* restore frequency */
|
||||
frequency = tstate->frequency;
|
||||
|
||||
if (frequency < 153000000) {
|
||||
/* VHF-L */
|
||||
buf[3] |= 0x01; /* fc, Low Band, 47 - 153 MHz */
|
||||
if (frequency < 68000000)
|
||||
buf[3] |= 0x40; /* 83uA */
|
||||
if (frequency < 1040000000)
|
||||
buf[3] |= 0x60; /* 122uA */
|
||||
if (frequency < 1250000000)
|
||||
buf[3] |= 0x80; /* 163uA */
|
||||
else
|
||||
buf[3] |= 0xa0; /* 254uA */
|
||||
} else if (frequency < 438000000) {
|
||||
/* VHF-H */
|
||||
buf[3] |= 0x02; /* fc, Mid Band, 153 - 438 MHz */
|
||||
if (frequency < 230000000)
|
||||
buf[3] |= 0x40;
|
||||
if (frequency < 300000000)
|
||||
buf[3] |= 0x60;
|
||||
else
|
||||
buf[3] |= 0x80;
|
||||
} else {
|
||||
/* UHF */
|
||||
buf[3] |= 0x04; /* fc, High Band, 438 - 862 MHz */
|
||||
if (frequency < 470000000)
|
||||
buf[3] |= 0x60;
|
||||
if (frequency < 526000000)
|
||||
buf[3] |= 0x80;
|
||||
else
|
||||
buf[3] |= 0xa0;
|
||||
}
|
||||
|
||||
/* Set params */
|
||||
err = tda665x_write(state, buf, 5);
|
||||
if (err < 0)
|
||||
goto exit;
|
||||
|
||||
/* sleep for some time */
|
||||
printk(KERN_DEBUG "%s: Waiting to Phase LOCK\n", __func__);
|
||||
msleep(20);
|
||||
/* check status */
|
||||
err = tda665x_get_status(fe, &status);
|
||||
if (err < 0)
|
||||
goto exit;
|
||||
|
||||
if (status == 1) {
|
||||
printk(KERN_DEBUG "%s: Tuner Phase locked: status=%d\n", __func__, status);
|
||||
state->frequency = frequency; /* cache successful state */
|
||||
} else {
|
||||
printk(KERN_ERR "%s: No Phase lock: status=%d\n", __func__, status);
|
||||
}
|
||||
} else {
|
||||
printk(KERN_ERR "%s: Unknown parameter (param=%d)\n", __func__, param);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
exit:
|
||||
printk(KERN_ERR "%s: I/O Error\n", __func__);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int tda665x_release(struct dvb_frontend *fe)
|
||||
{
|
||||
struct tda665x_state *state = fe->tuner_priv;
|
||||
|
||||
fe->tuner_priv = NULL;
|
||||
kfree(state);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct dvb_tuner_ops tda665x_ops = {
|
||||
|
||||
.set_state = tda665x_set_state,
|
||||
.get_state = tda665x_get_state,
|
||||
.get_status = tda665x_get_status,
|
||||
.release = tda665x_release
|
||||
};
|
||||
|
||||
struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
|
||||
const struct tda665x_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
struct tda665x_state *state = NULL;
|
||||
struct dvb_tuner_info *info;
|
||||
|
||||
state = kzalloc(sizeof(struct tda665x_state), GFP_KERNEL);
|
||||
if (state == NULL)
|
||||
goto exit;
|
||||
|
||||
state->config = config;
|
||||
state->i2c = i2c;
|
||||
state->fe = fe;
|
||||
fe->tuner_priv = state;
|
||||
fe->ops.tuner_ops = tda665x_ops;
|
||||
info = &fe->ops.tuner_ops.info;
|
||||
|
||||
memcpy(info->name, config->name, sizeof(config->name));
|
||||
info->frequency_min = config->frequency_min;
|
||||
info->frequency_max = config->frequency_max;
|
||||
info->frequency_step = config->frequency_offst;
|
||||
|
||||
printk(KERN_DEBUG "%s: Attaching TDA665x (%s) tuner\n", __func__, info->name);
|
||||
|
||||
return fe;
|
||||
|
||||
exit:
|
||||
kfree(state);
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL(tda665x_attach);
|
||||
|
||||
MODULE_DESCRIPTION("TDA665x driver");
|
||||
MODULE_AUTHOR("Manu Abraham");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
TDA665x tuner driver
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __TDA665x_H
|
||||
#define __TDA665x_H
|
||||
|
||||
struct tda665x_config {
|
||||
char name[128];
|
||||
|
||||
u8 addr;
|
||||
u32 frequency_min;
|
||||
u32 frequency_max;
|
||||
u32 frequency_offst;
|
||||
u32 ref_multiplier;
|
||||
u32 ref_divider;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_DVB_TDA665x) || (defined(CONFIG_DVB_TDA665x_MODULE) && defined(MODULE))
|
||||
|
||||
extern struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
|
||||
const struct tda665x_config *config,
|
||||
struct i2c_adapter *i2c);
|
||||
|
||||
#else
|
||||
|
||||
static inline struct dvb_frontend *tda665x_attach(struct dvb_frontend *fe,
|
||||
const struct tda665x_config *config,
|
||||
struct i2c_adapter *i2c)
|
||||
{
|
||||
printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DVB_TDA665x */
|
||||
|
||||
#endif /* __TDA665x_H */
|
|
@ -0,0 +1,32 @@
|
|||
config MANTIS_CORE
|
||||
tristate "Mantis/Hopper PCI bridge based devices"
|
||||
depends on PCI && I2C && INPUT
|
||||
|
||||
help
|
||||
Support for PCI cards based on the Mantis and Hopper PCi bridge.
|
||||
|
||||
Say Y if you own such a device and want to use it.
|
||||
|
||||
config DVB_MANTIS
|
||||
tristate "MANTIS based cards"
|
||||
depends on MANTIS_CORE && DVB_CORE && PCI && I2C
|
||||
select DVB_MB86A16
|
||||
select DVB_ZL10353
|
||||
select DVB_STV0299
|
||||
select DVB_PLL
|
||||
help
|
||||
Support for PCI cards based on the Mantis PCI bridge.
|
||||
Say Y when you have a Mantis based DVB card and want to use it.
|
||||
|
||||
If unsure say N.
|
||||
|
||||
config DVB_HOPPER
|
||||
tristate "HOPPER based cards"
|
||||
depends on MANTIS_CORE && DVB_CORE && PCI && I2C
|
||||
select DVB_ZL10353
|
||||
select DVB_PLL
|
||||
help
|
||||
Support for PCI cards based on the Hopper PCI bridge.
|
||||
Say Y when you have a Hopper based DVB card and want to use it.
|
||||
|
||||
If unsure say N
|
|
@ -0,0 +1,28 @@
|
|||
mantis_core-objs := mantis_ioc.o \
|
||||
mantis_uart.o \
|
||||
mantis_dma.o \
|
||||
mantis_pci.o \
|
||||
mantis_i2c.o \
|
||||
mantis_dvb.o \
|
||||
mantis_evm.o \
|
||||
mantis_hif.o \
|
||||
mantis_ca.o \
|
||||
mantis_pcmcia.o \
|
||||
mantis_input.o
|
||||
|
||||
mantis-objs := mantis_cards.o \
|
||||
mantis_vp1033.o \
|
||||
mantis_vp1034.o \
|
||||
mantis_vp1041.o \
|
||||
mantis_vp2033.o \
|
||||
mantis_vp2040.o \
|
||||
mantis_vp3030.o
|
||||
|
||||
hopper-objs := hopper_cards.o \
|
||||
hopper_vp3028.o
|
||||
|
||||
obj-$(CONFIG_MANTIS_CORE) += mantis_core.o
|
||||
obj-$(CONFIG_DVB_MANTIS) += mantis.o
|
||||
obj-$(CONFIG_DVB_HOPPER) += hopper.o
|
||||
|
||||
EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
|
|
@ -0,0 +1,275 @@
|
|||
/*
|
||||
Hopper PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <asm/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "mantis_common.h"
|
||||
#include "hopper_vp3028.h"
|
||||
#include "mantis_dma.h"
|
||||
#include "mantis_dvb.h"
|
||||
#include "mantis_uart.h"
|
||||
#include "mantis_ioc.h"
|
||||
#include "mantis_pci.h"
|
||||
#include "mantis_i2c.h"
|
||||
#include "mantis_reg.h"
|
||||
|
||||
static unsigned int verbose;
|
||||
module_param(verbose, int, 0644);
|
||||
MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
|
||||
|
||||
#define DRIVER_NAME "Hopper"
|
||||
|
||||
static char *label[10] = {
|
||||
"DMA",
|
||||
"IRQ-0",
|
||||
"IRQ-1",
|
||||
"OCERR",
|
||||
"PABRT",
|
||||
"RIPRR",
|
||||
"PPERR",
|
||||
"FTRGT",
|
||||
"RISCI",
|
||||
"RACK"
|
||||
};
|
||||
|
||||
static int devs;
|
||||
|
||||
static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
u32 stat = 0, mask = 0, lstat = 0, mstat = 0;
|
||||
u32 rst_stat = 0, rst_mask = 0;
|
||||
|
||||
struct mantis_pci *mantis;
|
||||
struct mantis_ca *ca;
|
||||
|
||||
mantis = (struct mantis_pci *) dev_id;
|
||||
if (unlikely(mantis == NULL)) {
|
||||
dprintk(MANTIS_ERROR, 1, "Mantis == NULL");
|
||||
return IRQ_NONE;
|
||||
}
|
||||
ca = mantis->mantis_ca;
|
||||
|
||||
stat = mmread(MANTIS_INT_STAT);
|
||||
mask = mmread(MANTIS_INT_MASK);
|
||||
mstat = lstat = stat & ~MANTIS_INT_RISCSTAT;
|
||||
if (!(stat & mask))
|
||||
return IRQ_NONE;
|
||||
|
||||
rst_mask = MANTIS_GPIF_WRACK |
|
||||
MANTIS_GPIF_OTHERR |
|
||||
MANTIS_SBUF_WSTO |
|
||||
MANTIS_GPIF_EXTIRQ;
|
||||
|
||||
rst_stat = mmread(MANTIS_GPIF_STATUS);
|
||||
rst_stat &= rst_mask;
|
||||
mmwrite(rst_stat, MANTIS_GPIF_STATUS);
|
||||
|
||||
mantis->mantis_int_stat = stat;
|
||||
mantis->mantis_int_mask = mask;
|
||||
dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask);
|
||||
if (stat & MANTIS_INT_RISCEN) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]);
|
||||
}
|
||||
if (stat & MANTIS_INT_IRQ0) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]);
|
||||
mantis->gpif_status = rst_stat;
|
||||
wake_up(&ca->hif_write_wq);
|
||||
schedule_work(&ca->hif_evm_work);
|
||||
}
|
||||
if (stat & MANTIS_INT_IRQ1) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]);
|
||||
schedule_work(&mantis->uart_work);
|
||||
}
|
||||
if (stat & MANTIS_INT_OCERR) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]);
|
||||
}
|
||||
if (stat & MANTIS_INT_PABORT) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]);
|
||||
}
|
||||
if (stat & MANTIS_INT_RIPERR) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]);
|
||||
}
|
||||
if (stat & MANTIS_INT_PPERR) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]);
|
||||
}
|
||||
if (stat & MANTIS_INT_FTRGT) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]);
|
||||
}
|
||||
if (stat & MANTIS_INT_RISCI) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
|
||||
mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
|
||||
tasklet_schedule(&mantis->tasklet);
|
||||
}
|
||||
if (stat & MANTIS_INT_I2CDONE) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]);
|
||||
wake_up(&mantis->i2c_wq);
|
||||
}
|
||||
mmwrite(stat, MANTIS_INT_STAT);
|
||||
stat &= ~(MANTIS_INT_RISCEN | MANTIS_INT_I2CDONE |
|
||||
MANTIS_INT_I2CRACK | MANTIS_INT_PCMCIA7 |
|
||||
MANTIS_INT_PCMCIA6 | MANTIS_INT_PCMCIA5 |
|
||||
MANTIS_INT_PCMCIA4 | MANTIS_INT_PCMCIA3 |
|
||||
MANTIS_INT_PCMCIA2 | MANTIS_INT_PCMCIA1 |
|
||||
MANTIS_INT_PCMCIA0 | MANTIS_INT_IRQ1 |
|
||||
MANTIS_INT_IRQ0 | MANTIS_INT_OCERR |
|
||||
MANTIS_INT_PABORT | MANTIS_INT_RIPERR |
|
||||
MANTIS_INT_PPERR | MANTIS_INT_FTRGT |
|
||||
MANTIS_INT_RISCI);
|
||||
|
||||
if (stat)
|
||||
dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask);
|
||||
|
||||
dprintk(MANTIS_DEBUG, 0, "\n");
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int __devinit hopper_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
|
||||
{
|
||||
struct mantis_pci *mantis;
|
||||
struct mantis_hwconfig *config;
|
||||
int err = 0;
|
||||
|
||||
mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL);
|
||||
if (mantis == NULL) {
|
||||
printk(KERN_ERR "%s ERROR: Out of memory\n", __func__);
|
||||
err = -ENOMEM;
|
||||
goto fail0;
|
||||
}
|
||||
|
||||
mantis->num = devs;
|
||||
mantis->verbose = verbose;
|
||||
mantis->pdev = pdev;
|
||||
config = (struct mantis_hwconfig *) pci_id->driver_data;
|
||||
config->irq_handler = &hopper_irq_handler;
|
||||
mantis->hwconfig = config;
|
||||
|
||||
err = mantis_pci_init(mantis);
|
||||
if (err) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
err = mantis_stream_control(mantis, STREAM_TO_HIF);
|
||||
if (err < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
err = mantis_i2c_init(mantis);
|
||||
if (err < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err);
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
err = mantis_get_mac(mantis);
|
||||
if (err < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err);
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
err = mantis_dma_init(mantis);
|
||||
if (err < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
err = mantis_dvb_init(mantis);
|
||||
if (err < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err);
|
||||
goto fail4;
|
||||
}
|
||||
devs++;
|
||||
|
||||
return err;
|
||||
|
||||
fail4:
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err);
|
||||
mantis_dma_exit(mantis);
|
||||
|
||||
fail3:
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err);
|
||||
mantis_i2c_exit(mantis);
|
||||
|
||||
fail2:
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err);
|
||||
mantis_pci_exit(mantis);
|
||||
|
||||
fail1:
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err);
|
||||
kfree(mantis);
|
||||
|
||||
fail0:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __devexit hopper_pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct mantis_pci *mantis = pci_get_drvdata(pdev);
|
||||
|
||||
if (mantis) {
|
||||
mantis_dvb_exit(mantis);
|
||||
mantis_dma_exit(mantis);
|
||||
mantis_i2c_exit(mantis);
|
||||
mantis_pci_exit(mantis);
|
||||
kfree(mantis);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
static struct pci_device_id hopper_pci_table[] = {
|
||||
MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3028_DVB_T, &vp3028_config),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct pci_driver hopper_pci_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = hopper_pci_table,
|
||||
.probe = hopper_pci_probe,
|
||||
.remove = hopper_pci_remove,
|
||||
};
|
||||
|
||||
static int __devinit hopper_init(void)
|
||||
{
|
||||
return pci_register_driver(&hopper_pci_driver);
|
||||
}
|
||||
|
||||
static void __devexit hopper_exit(void)
|
||||
{
|
||||
return pci_unregister_driver(&hopper_pci_driver);
|
||||
}
|
||||
|
||||
module_init(hopper_init);
|
||||
module_exit(hopper_exit);
|
||||
|
||||
MODULE_DESCRIPTION("HOPPER driver");
|
||||
MODULE_AUTHOR("Manu Abraham");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Hopper VP-3028 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "zl10353.h"
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_ioc.h"
|
||||
#include "mantis_dvb.h"
|
||||
#include "hopper_vp3028.h"
|
||||
|
||||
struct zl10353_config hopper_vp3028_config = {
|
||||
.demod_address = 0x0f,
|
||||
};
|
||||
|
||||
#define MANTIS_MODEL_NAME "VP-3028"
|
||||
#define MANTIS_DEV_TYPE "DVB-T"
|
||||
|
||||
static int vp3028_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
|
||||
{
|
||||
struct i2c_adapter *adapter = &mantis->adapter;
|
||||
struct mantis_hwconfig *config = mantis->hwconfig;
|
||||
int err = 0;
|
||||
|
||||
gpio_set_bits(mantis, config->reset, 0);
|
||||
msleep(100);
|
||||
err = mantis_frontend_power(mantis, POWER_ON);
|
||||
msleep(100);
|
||||
gpio_set_bits(mantis, config->reset, 1);
|
||||
|
||||
err = mantis_frontend_power(mantis, POWER_ON);
|
||||
if (err == 0) {
|
||||
msleep(250);
|
||||
dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)");
|
||||
fe = zl10353_attach(&hopper_vp3028_config, adapter);
|
||||
|
||||
if (!fe)
|
||||
return -1;
|
||||
} else {
|
||||
dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
|
||||
adapter->name,
|
||||
err);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
dprintk(MANTIS_ERROR, 1, "Done!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mantis_hwconfig vp3028_config = {
|
||||
.model_name = MANTIS_MODEL_NAME,
|
||||
.dev_type = MANTIS_DEV_TYPE,
|
||||
.ts_size = MANTIS_TS_188,
|
||||
|
||||
.baud_rate = MANTIS_BAUD_9600,
|
||||
.parity = MANTIS_PARITY_NONE,
|
||||
.bytes = 0,
|
||||
|
||||
.frontend_init = vp3028_frontend_init,
|
||||
.power = GPIF_A00,
|
||||
.reset = GPIF_A03,
|
||||
};
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Hopper VP-3028 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_VP3028_H
|
||||
#define __MANTIS_VP3028_H
|
||||
|
||||
#include "mantis_common.h"
|
||||
|
||||
#define MANTIS_VP_3028_DVB_T 0x0028
|
||||
|
||||
extern struct mantis_hwconfig vp3028_config;
|
||||
|
||||
#endif /* __MANTIS_VP3028_H */
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_link.h"
|
||||
#include "mantis_hif.h"
|
||||
#include "mantis_reg.h"
|
||||
|
||||
#include "mantis_ca.h"
|
||||
|
||||
static int mantis_ca_read_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr)
|
||||
{
|
||||
struct mantis_ca *ca = en50221->data;
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Read", slot);
|
||||
|
||||
if (slot != 0)
|
||||
return -EINVAL;
|
||||
|
||||
return mantis_hif_read_mem(ca, addr);
|
||||
}
|
||||
|
||||
static int mantis_ca_write_attr_mem(struct dvb_ca_en50221 *en50221, int slot, int addr, u8 data)
|
||||
{
|
||||
struct mantis_ca *ca = en50221->data;
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request Attribute Mem Write", slot);
|
||||
|
||||
if (slot != 0)
|
||||
return -EINVAL;
|
||||
|
||||
return mantis_hif_write_mem(ca, addr, data);
|
||||
}
|
||||
|
||||
static int mantis_ca_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
|
||||
{
|
||||
struct mantis_ca *ca = en50221->data;
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Read", slot);
|
||||
|
||||
if (slot != 0)
|
||||
return -EINVAL;
|
||||
|
||||
return mantis_hif_read_iom(ca, addr);
|
||||
}
|
||||
|
||||
static int mantis_ca_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr, u8 data)
|
||||
{
|
||||
struct mantis_ca *ca = en50221->data;
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Slot(%d): Request CAM control Write", slot);
|
||||
|
||||
if (slot != 0)
|
||||
return -EINVAL;
|
||||
|
||||
return mantis_hif_write_iom(ca, addr, data);
|
||||
}
|
||||
|
||||
static int mantis_ca_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
|
||||
{
|
||||
struct mantis_ca *ca = en50221->data;
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot RESET", slot);
|
||||
udelay(500); /* Wait.. */
|
||||
mmwrite(0xda, MANTIS_PCMCIA_RESET); /* Leading edge assert */
|
||||
udelay(500);
|
||||
mmwrite(0x00, MANTIS_PCMCIA_RESET); /* Trailing edge deassert */
|
||||
msleep(1000);
|
||||
dvb_ca_en50221_camready_irq(&ca->en50221, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mantis_ca_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
|
||||
{
|
||||
struct mantis_ca *ca = en50221->data;
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot shutdown", slot);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mantis_ts_control(struct dvb_ca_en50221 *en50221, int slot)
|
||||
{
|
||||
struct mantis_ca *ca = en50221->data;
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Slot(%d): TS control", slot);
|
||||
/* mantis_set_direction(mantis, 1); */ /* Enable TS through CAM */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mantis_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open)
|
||||
{
|
||||
struct mantis_ca *ca = en50221->data;
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Slot(%d): Poll Slot status", slot);
|
||||
|
||||
if (ca->slot_state == MODULE_INSERTED) {
|
||||
dprintk(MANTIS_DEBUG, 1, "CA Module present and ready");
|
||||
return DVB_CA_EN50221_POLL_CAM_PRESENT | DVB_CA_EN50221_POLL_CAM_READY;
|
||||
} else {
|
||||
dprintk(MANTIS_DEBUG, 1, "CA Module not present or not ready");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mantis_ca_init(struct mantis_pci *mantis)
|
||||
{
|
||||
struct dvb_adapter *dvb_adapter = &mantis->dvb_adapter;
|
||||
struct mantis_ca *ca;
|
||||
int ca_flags = 0, result;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Initializing Mantis CA");
|
||||
ca = kzalloc(sizeof(struct mantis_ca), GFP_KERNEL);
|
||||
if (!ca) {
|
||||
dprintk(MANTIS_ERROR, 1, "Out of memory!, exiting ..");
|
||||
result = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ca->ca_priv = mantis;
|
||||
mantis->mantis_ca = ca;
|
||||
ca_flags = DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE;
|
||||
/* register CA interface */
|
||||
ca->en50221.owner = THIS_MODULE;
|
||||
ca->en50221.read_attribute_mem = mantis_ca_read_attr_mem;
|
||||
ca->en50221.write_attribute_mem = mantis_ca_write_attr_mem;
|
||||
ca->en50221.read_cam_control = mantis_ca_read_cam_ctl;
|
||||
ca->en50221.write_cam_control = mantis_ca_write_cam_ctl;
|
||||
ca->en50221.slot_reset = mantis_ca_slot_reset;
|
||||
ca->en50221.slot_shutdown = mantis_ca_slot_shutdown;
|
||||
ca->en50221.slot_ts_enable = mantis_ts_control;
|
||||
ca->en50221.poll_slot_status = mantis_slot_status;
|
||||
ca->en50221.data = ca;
|
||||
|
||||
mutex_init(&ca->ca_lock);
|
||||
|
||||
init_waitqueue_head(&ca->hif_data_wq);
|
||||
init_waitqueue_head(&ca->hif_opdone_wq);
|
||||
init_waitqueue_head(&ca->hif_write_wq);
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "Registering EN50221 device");
|
||||
result = dvb_ca_en50221_init(dvb_adapter, &ca->en50221, ca_flags, 1);
|
||||
if (result != 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "EN50221: Initialization failed <%d>", result);
|
||||
goto err;
|
||||
}
|
||||
dprintk(MANTIS_ERROR, 1, "Registered EN50221 device");
|
||||
mantis_evmgr_init(ca);
|
||||
return 0;
|
||||
err:
|
||||
kfree(ca);
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_ca_init);
|
||||
|
||||
void mantis_ca_exit(struct mantis_pci *mantis)
|
||||
{
|
||||
struct mantis_ca *ca = mantis->mantis_ca;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Mantis CA exit");
|
||||
|
||||
mantis_evmgr_exit(ca);
|
||||
dprintk(MANTIS_ERROR, 1, "Unregistering EN50221 device");
|
||||
if (ca)
|
||||
dvb_ca_en50221_release(&ca->en50221);
|
||||
|
||||
kfree(ca);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_ca_exit);
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_CA_H
|
||||
#define __MANTIS_CA_H
|
||||
|
||||
extern int mantis_ca_init(struct mantis_pci *mantis);
|
||||
extern void mantis_ca_exit(struct mantis_pci *mantis);
|
||||
|
||||
#endif /* __MANTIS_CA_H */
|
|
@ -0,0 +1,305 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/pci.h>
|
||||
#include <asm/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "mantis_common.h"
|
||||
|
||||
#include "mantis_vp1033.h"
|
||||
#include "mantis_vp1034.h"
|
||||
#include "mantis_vp1041.h"
|
||||
#include "mantis_vp2033.h"
|
||||
#include "mantis_vp2040.h"
|
||||
#include "mantis_vp3030.h"
|
||||
|
||||
#include "mantis_dma.h"
|
||||
#include "mantis_ca.h"
|
||||
#include "mantis_dvb.h"
|
||||
#include "mantis_uart.h"
|
||||
#include "mantis_ioc.h"
|
||||
#include "mantis_pci.h"
|
||||
#include "mantis_i2c.h"
|
||||
#include "mantis_reg.h"
|
||||
|
||||
static unsigned int verbose;
|
||||
module_param(verbose, int, 0644);
|
||||
MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)");
|
||||
|
||||
static int devs;
|
||||
|
||||
#define DRIVER_NAME "Mantis"
|
||||
|
||||
static char *label[10] = {
|
||||
"DMA",
|
||||
"IRQ-0",
|
||||
"IRQ-1",
|
||||
"OCERR",
|
||||
"PABRT",
|
||||
"RIPRR",
|
||||
"PPERR",
|
||||
"FTRGT",
|
||||
"RISCI",
|
||||
"RACK"
|
||||
};
|
||||
|
||||
static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
u32 stat = 0, mask = 0, lstat = 0, mstat = 0;
|
||||
u32 rst_stat = 0, rst_mask = 0;
|
||||
|
||||
struct mantis_pci *mantis;
|
||||
struct mantis_ca *ca;
|
||||
|
||||
mantis = (struct mantis_pci *) dev_id;
|
||||
if (unlikely(mantis == NULL)) {
|
||||
dprintk(MANTIS_ERROR, 1, "Mantis == NULL");
|
||||
return IRQ_NONE;
|
||||
}
|
||||
ca = mantis->mantis_ca;
|
||||
|
||||
stat = mmread(MANTIS_INT_STAT);
|
||||
mask = mmread(MANTIS_INT_MASK);
|
||||
mstat = lstat = stat & ~MANTIS_INT_RISCSTAT;
|
||||
if (!(stat & mask))
|
||||
return IRQ_NONE;
|
||||
|
||||
rst_mask = MANTIS_GPIF_WRACK |
|
||||
MANTIS_GPIF_OTHERR |
|
||||
MANTIS_SBUF_WSTO |
|
||||
MANTIS_GPIF_EXTIRQ;
|
||||
|
||||
rst_stat = mmread(MANTIS_GPIF_STATUS);
|
||||
rst_stat &= rst_mask;
|
||||
mmwrite(rst_stat, MANTIS_GPIF_STATUS);
|
||||
|
||||
mantis->mantis_int_stat = stat;
|
||||
mantis->mantis_int_mask = mask;
|
||||
dprintk(MANTIS_DEBUG, 0, "\n-- Stat=<%02x> Mask=<%02x> --", stat, mask);
|
||||
if (stat & MANTIS_INT_RISCEN) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[0]);
|
||||
}
|
||||
if (stat & MANTIS_INT_IRQ0) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[1]);
|
||||
mantis->gpif_status = rst_stat;
|
||||
wake_up(&ca->hif_write_wq);
|
||||
schedule_work(&ca->hif_evm_work);
|
||||
}
|
||||
if (stat & MANTIS_INT_IRQ1) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[2]);
|
||||
schedule_work(&mantis->uart_work);
|
||||
}
|
||||
if (stat & MANTIS_INT_OCERR) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[3]);
|
||||
}
|
||||
if (stat & MANTIS_INT_PABORT) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[4]);
|
||||
}
|
||||
if (stat & MANTIS_INT_RIPERR) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[5]);
|
||||
}
|
||||
if (stat & MANTIS_INT_PPERR) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[6]);
|
||||
}
|
||||
if (stat & MANTIS_INT_FTRGT) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[7]);
|
||||
}
|
||||
if (stat & MANTIS_INT_RISCI) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
|
||||
mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
|
||||
tasklet_schedule(&mantis->tasklet);
|
||||
}
|
||||
if (stat & MANTIS_INT_I2CDONE) {
|
||||
dprintk(MANTIS_DEBUG, 0, "<%s>", label[9]);
|
||||
wake_up(&mantis->i2c_wq);
|
||||
}
|
||||
mmwrite(stat, MANTIS_INT_STAT);
|
||||
stat &= ~(MANTIS_INT_RISCEN | MANTIS_INT_I2CDONE |
|
||||
MANTIS_INT_I2CRACK | MANTIS_INT_PCMCIA7 |
|
||||
MANTIS_INT_PCMCIA6 | MANTIS_INT_PCMCIA5 |
|
||||
MANTIS_INT_PCMCIA4 | MANTIS_INT_PCMCIA3 |
|
||||
MANTIS_INT_PCMCIA2 | MANTIS_INT_PCMCIA1 |
|
||||
MANTIS_INT_PCMCIA0 | MANTIS_INT_IRQ1 |
|
||||
MANTIS_INT_IRQ0 | MANTIS_INT_OCERR |
|
||||
MANTIS_INT_PABORT | MANTIS_INT_RIPERR |
|
||||
MANTIS_INT_PPERR | MANTIS_INT_FTRGT |
|
||||
MANTIS_INT_RISCI);
|
||||
|
||||
if (stat)
|
||||
dprintk(MANTIS_DEBUG, 0, "<Unknown> Stat=<%02x> Mask=<%02x>", stat, mask);
|
||||
|
||||
dprintk(MANTIS_DEBUG, 0, "\n");
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int __devinit mantis_pci_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id)
|
||||
{
|
||||
struct mantis_pci *mantis;
|
||||
struct mantis_hwconfig *config;
|
||||
int err = 0;
|
||||
|
||||
mantis = kzalloc(sizeof(struct mantis_pci), GFP_KERNEL);
|
||||
if (mantis == NULL) {
|
||||
printk(KERN_ERR "%s ERROR: Out of memory\n", __func__);
|
||||
err = -ENOMEM;
|
||||
goto fail0;
|
||||
}
|
||||
|
||||
mantis->num = devs;
|
||||
mantis->verbose = verbose;
|
||||
mantis->pdev = pdev;
|
||||
config = (struct mantis_hwconfig *) pci_id->driver_data;
|
||||
config->irq_handler = &mantis_irq_handler;
|
||||
mantis->hwconfig = config;
|
||||
|
||||
err = mantis_pci_init(mantis);
|
||||
if (err) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI initialization failed <%d>", err);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
err = mantis_stream_control(mantis, STREAM_TO_HIF);
|
||||
if (err < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis stream control failed <%d>", err);
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
err = mantis_i2c_init(mantis);
|
||||
if (err < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C initialization failed <%d>", err);
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
err = mantis_get_mac(mantis);
|
||||
if (err < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis MAC address read failed <%d>", err);
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
err = mantis_dma_init(mantis);
|
||||
if (err < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA initialization failed <%d>", err);
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
err = mantis_dvb_init(mantis);
|
||||
if (err < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DVB initialization failed <%d>", err);
|
||||
goto fail4;
|
||||
}
|
||||
err = mantis_uart_init(mantis);
|
||||
if (err < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART initialization failed <%d>", err);
|
||||
goto fail6;
|
||||
}
|
||||
|
||||
devs++;
|
||||
|
||||
return err;
|
||||
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis UART exit! <%d>", err);
|
||||
mantis_uart_exit(mantis);
|
||||
|
||||
fail6:
|
||||
fail4:
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis DMA exit! <%d>", err);
|
||||
mantis_dma_exit(mantis);
|
||||
|
||||
fail3:
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis I2C exit! <%d>", err);
|
||||
mantis_i2c_exit(mantis);
|
||||
|
||||
fail2:
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis PCI exit! <%d>", err);
|
||||
mantis_pci_exit(mantis);
|
||||
|
||||
fail1:
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis free! <%d>", err);
|
||||
kfree(mantis);
|
||||
|
||||
fail0:
|
||||
return err;
|
||||
}
|
||||
|
||||
static void __devexit mantis_pci_remove(struct pci_dev *pdev)
|
||||
{
|
||||
struct mantis_pci *mantis = pci_get_drvdata(pdev);
|
||||
|
||||
if (mantis) {
|
||||
|
||||
mantis_uart_exit(mantis);
|
||||
mantis_dvb_exit(mantis);
|
||||
mantis_dma_exit(mantis);
|
||||
mantis_i2c_exit(mantis);
|
||||
mantis_pci_exit(mantis);
|
||||
kfree(mantis);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static struct pci_device_id mantis_pci_table[] = {
|
||||
MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1033_DVB_S, &vp1033_config),
|
||||
MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1034_DVB_S, &vp1034_config),
|
||||
MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_1041_DVB_S2, &vp1041_config),
|
||||
MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_10, &vp1041_config),
|
||||
MAKE_ENTRY(TECHNISAT, SKYSTAR_HD2_20, &vp1041_config),
|
||||
MAKE_ENTRY(TERRATEC, CINERGY_S2_PCI_HD, &vp1041_config),
|
||||
MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2033_DVB_C, &vp2033_config),
|
||||
MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_2040_DVB_C, &vp2040_config),
|
||||
MAKE_ENTRY(TECHNISAT, CABLESTAR_HD2, &vp2040_config),
|
||||
MAKE_ENTRY(TERRATEC, CINERGY_C, &vp2033_config),
|
||||
MAKE_ENTRY(TWINHAN_TECHNOLOGIES, MANTIS_VP_3030_DVB_T, &vp3030_config),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct pci_driver mantis_pci_driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.id_table = mantis_pci_table,
|
||||
.probe = mantis_pci_probe,
|
||||
.remove = mantis_pci_remove,
|
||||
};
|
||||
|
||||
static int __devinit mantis_init(void)
|
||||
{
|
||||
return pci_register_driver(&mantis_pci_driver);
|
||||
}
|
||||
|
||||
static void __devexit mantis_exit(void)
|
||||
{
|
||||
return pci_unregister_driver(&mantis_pci_driver);
|
||||
}
|
||||
|
||||
module_init(mantis_init);
|
||||
module_exit(mantis_exit);
|
||||
|
||||
MODULE_DESCRIPTION("MANTIS driver");
|
||||
MODULE_AUTHOR("Manu Abraham");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_COMMON_H
|
||||
#define __MANTIS_COMMON_H
|
||||
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include "mantis_uart.h"
|
||||
|
||||
#include "mantis_link.h"
|
||||
|
||||
#define MANTIS_ERROR 0
|
||||
#define MANTIS_NOTICE 1
|
||||
#define MANTIS_INFO 2
|
||||
#define MANTIS_DEBUG 3
|
||||
#define MANTIS_TMG 9
|
||||
|
||||
#define dprintk(y, z, format, arg...) do { \
|
||||
if (z) { \
|
||||
if ((mantis->verbose > MANTIS_ERROR) && (mantis->verbose > y)) \
|
||||
printk(KERN_ERR "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \
|
||||
else if ((mantis->verbose > MANTIS_NOTICE) && (mantis->verbose > y)) \
|
||||
printk(KERN_NOTICE "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \
|
||||
else if ((mantis->verbose > MANTIS_INFO) && (mantis->verbose > y)) \
|
||||
printk(KERN_INFO "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \
|
||||
else if ((mantis->verbose > MANTIS_DEBUG) && (mantis->verbose > y)) \
|
||||
printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \
|
||||
else if ((mantis->verbose > MANTIS_TMG) && (mantis->verbose > y)) \
|
||||
printk(KERN_DEBUG "%s (%d): " format "\n" , __func__ , mantis->num , ##arg); \
|
||||
} else { \
|
||||
if (mantis->verbose > y) \
|
||||
printk(format , ##arg); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define mwrite(dat, addr) writel((dat), addr)
|
||||
#define mread(addr) readl(addr)
|
||||
|
||||
#define mmwrite(dat, addr) mwrite((dat), (mantis->mmio + (addr)))
|
||||
#define mmread(addr) mread(mantis->mmio + (addr))
|
||||
|
||||
#define MANTIS_TS_188 0
|
||||
#define MANTIS_TS_204 1
|
||||
|
||||
#define TWINHAN_TECHNOLOGIES 0x1822
|
||||
#define MANTIS 0x4e35
|
||||
|
||||
#define TECHNISAT 0x1ae4
|
||||
#define TERRATEC 0x153b
|
||||
|
||||
#define MAKE_ENTRY(__subven, __subdev, __configptr) { \
|
||||
.vendor = TWINHAN_TECHNOLOGIES, \
|
||||
.device = MANTIS, \
|
||||
.subvendor = (__subven), \
|
||||
.subdevice = (__subdev), \
|
||||
.driver_data = (unsigned long) (__configptr) \
|
||||
}
|
||||
|
||||
enum mantis_i2c_mode {
|
||||
MANTIS_PAGE_MODE = 0,
|
||||
MANTIS_BYTE_MODE,
|
||||
};
|
||||
|
||||
struct mantis_pci;
|
||||
|
||||
struct mantis_hwconfig {
|
||||
char *model_name;
|
||||
char *dev_type;
|
||||
u32 ts_size;
|
||||
|
||||
enum mantis_baud baud_rate;
|
||||
enum mantis_parity parity;
|
||||
u32 bytes;
|
||||
|
||||
irqreturn_t (*irq_handler)(int irq, void *dev_id);
|
||||
int (*frontend_init)(struct mantis_pci *mantis, struct dvb_frontend *fe);
|
||||
|
||||
u8 power;
|
||||
u8 reset;
|
||||
|
||||
enum mantis_i2c_mode i2c_mode;
|
||||
};
|
||||
|
||||
struct mantis_pci {
|
||||
unsigned int verbose;
|
||||
|
||||
/* PCI stuff */
|
||||
u16 vendor_id;
|
||||
u16 device_id;
|
||||
u16 subsystem_vendor;
|
||||
u16 subsystem_device;
|
||||
|
||||
u8 latency;
|
||||
|
||||
struct pci_dev *pdev;
|
||||
|
||||
unsigned long mantis_addr;
|
||||
void __iomem *mmio;
|
||||
|
||||
u8 irq;
|
||||
u8 revision;
|
||||
|
||||
unsigned int num;
|
||||
|
||||
/* RISC Core */
|
||||
u32 finished_block;
|
||||
u32 last_block;
|
||||
u32 line_bytes;
|
||||
u32 line_count;
|
||||
u32 risc_pos;
|
||||
u8 *buf_cpu;
|
||||
dma_addr_t buf_dma;
|
||||
u32 *risc_cpu;
|
||||
dma_addr_t risc_dma;
|
||||
|
||||
struct tasklet_struct tasklet;
|
||||
|
||||
struct i2c_adapter adapter;
|
||||
int i2c_rc;
|
||||
wait_queue_head_t i2c_wq;
|
||||
struct mutex i2c_lock;
|
||||
|
||||
/* DVB stuff */
|
||||
struct dvb_adapter dvb_adapter;
|
||||
struct dvb_frontend *fe;
|
||||
struct dvb_demux demux;
|
||||
struct dmxdev dmxdev;
|
||||
struct dmx_frontend fe_hw;
|
||||
struct dmx_frontend fe_mem;
|
||||
struct dvb_net dvbnet;
|
||||
|
||||
u8 feeds;
|
||||
|
||||
struct mantis_hwconfig *hwconfig;
|
||||
|
||||
u32 mantis_int_stat;
|
||||
u32 mantis_int_mask;
|
||||
|
||||
/* board specific */
|
||||
u8 mac_address[8];
|
||||
u32 sub_vendor_id;
|
||||
u32 sub_device_id;
|
||||
|
||||
/* A12 A13 A14 */
|
||||
u32 gpio_status;
|
||||
|
||||
u32 gpif_status;
|
||||
|
||||
struct mantis_ca *mantis_ca;
|
||||
|
||||
wait_queue_head_t uart_wq;
|
||||
struct work_struct uart_work;
|
||||
spinlock_t uart_lock;
|
||||
|
||||
struct input_dev *rc;
|
||||
};
|
||||
|
||||
#define MANTIS_HIF_STATUS (mantis->gpio_status)
|
||||
|
||||
#endif /* __MANTIS_COMMON_H */
|
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_core.h"
|
||||
#include "mantis_vp1033.h"
|
||||
#include "mantis_vp1034.h"
|
||||
#include "mantis_vp1041.h"
|
||||
#include "mantis_vp2033.h"
|
||||
#include "mantis_vp2040.h"
|
||||
#include "mantis_vp3030.h"
|
||||
|
||||
static int read_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length)
|
||||
{
|
||||
int err;
|
||||
struct i2c_msg msg[] = {
|
||||
{
|
||||
.addr = 0x50,
|
||||
.flags = 0,
|
||||
.buf = data,
|
||||
.len = 1
|
||||
}, {
|
||||
.addr = 0x50,
|
||||
.flags = I2C_M_RD,
|
||||
.buf = data,
|
||||
.len = length
|
||||
},
|
||||
};
|
||||
|
||||
err = i2c_transfer(&mantis->adapter, msg, 2);
|
||||
if (err < 0) {
|
||||
dprintk(verbose, MANTIS_ERROR, 1,
|
||||
"ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >",
|
||||
err, data[0], data[1]);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_eeprom_byte(struct mantis_pci *mantis, u8 *data, u8 length)
|
||||
{
|
||||
int err;
|
||||
|
||||
struct i2c_msg msg = {
|
||||
.addr = 0x50,
|
||||
.flags = 0,
|
||||
.buf = data,
|
||||
.len = length
|
||||
};
|
||||
|
||||
err = i2c_transfer(&mantis->adapter, &msg, 1);
|
||||
if (err < 0) {
|
||||
dprintk(verbose, MANTIS_ERROR, 1,
|
||||
"ERROR: i2c write: < err=%i length=0x%02x d0=0x%02x, d1=0x%02x >",
|
||||
err, length, data[0], data[1]);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_mac_address(struct mantis_pci *mantis)
|
||||
{
|
||||
int err;
|
||||
|
||||
mantis->mac_address[0] = 0x08;
|
||||
err = read_eeprom_byte(mantis, &mantis->mac_address[0], 6);
|
||||
if (err < 0) {
|
||||
dprintk(verbose, MANTIS_ERROR, 1, "Mantis EEPROM read error");
|
||||
|
||||
return err;
|
||||
}
|
||||
dprintk(verbose, MANTIS_ERROR, 0,
|
||||
" MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n",
|
||||
mantis->mac_address[0], mantis->mac_address[1],
|
||||
mantis->mac_address[2], mantis->mac_address[3],
|
||||
mantis->mac_address[4], mantis->mac_address[5]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MANTIS_MODEL_UNKNOWN "UNKNOWN"
|
||||
#define MANTIS_DEV_UNKNOWN "UNKNOWN"
|
||||
|
||||
struct mantis_hwconfig unknown_device = {
|
||||
.model_name = MANTIS_MODEL_UNKNOWN,
|
||||
.dev_type = MANTIS_DEV_UNKNOWN,
|
||||
};
|
||||
|
||||
static void mantis_load_config(struct mantis_pci *mantis)
|
||||
{
|
||||
switch (mantis->subsystem_device) {
|
||||
case MANTIS_VP_1033_DVB_S: /* VP-1033 */
|
||||
mantis->hwconfig = &vp1033_mantis_config;
|
||||
break;
|
||||
case MANTIS_VP_1034_DVB_S: /* VP-1034 */
|
||||
mantis->hwconfig = &vp1034_mantis_config;
|
||||
break;
|
||||
case MANTIS_VP_1041_DVB_S2: /* VP-1041 */
|
||||
case TECHNISAT_SKYSTAR_HD2:
|
||||
mantis->hwconfig = &vp1041_mantis_config;
|
||||
break;
|
||||
case MANTIS_VP_2033_DVB_C: /* VP-2033 */
|
||||
mantis->hwconfig = &vp2033_mantis_config;
|
||||
break;
|
||||
case MANTIS_VP_2040_DVB_C: /* VP-2040 */
|
||||
case TERRATEC_CINERGY_C_PCI: /* VP-2040 clone */
|
||||
case TECHNISAT_CABLESTAR_HD2:
|
||||
mantis->hwconfig = &vp2040_mantis_config;
|
||||
break;
|
||||
case MANTIS_VP_3030_DVB_T: /* VP-3030 */
|
||||
mantis->hwconfig = &vp3030_mantis_config;
|
||||
break;
|
||||
default:
|
||||
mantis->hwconfig = &unknown_device;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int mantis_core_init(struct mantis_pci *mantis)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
mantis_load_config(mantis);
|
||||
dprintk(verbose, MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n",
|
||||
mantis->hwconfig->model_name, mantis->hwconfig->dev_type,
|
||||
mantis->pdev->bus->number, PCI_SLOT(mantis->pdev->devfn), PCI_FUNC(mantis->pdev->devfn));
|
||||
dprintk(verbose, MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ",
|
||||
mantis->revision,
|
||||
mantis->subsystem_vendor, mantis->subsystem_device);
|
||||
dprintk(verbose, MANTIS_ERROR, 0,
|
||||
"irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n",
|
||||
mantis->pdev->irq, mantis->latency,
|
||||
mantis->mantis_addr, mantis->mantis_mmio);
|
||||
|
||||
err = mantis_i2c_init(mantis);
|
||||
if (err < 0) {
|
||||
dprintk(verbose, MANTIS_ERROR, 1, "Mantis I2C init failed");
|
||||
return err;
|
||||
}
|
||||
err = get_mac_address(mantis);
|
||||
if (err < 0) {
|
||||
dprintk(verbose, MANTIS_ERROR, 1, "get MAC address failed");
|
||||
return err;
|
||||
}
|
||||
err = mantis_dma_init(mantis);
|
||||
if (err < 0) {
|
||||
dprintk(verbose, MANTIS_ERROR, 1, "Mantis DMA init failed");
|
||||
return err;
|
||||
}
|
||||
err = mantis_dvb_init(mantis);
|
||||
if (err < 0) {
|
||||
dprintk(verbose, MANTIS_DEBUG, 1, "Mantis DVB init failed");
|
||||
return err;
|
||||
}
|
||||
err = mantis_uart_init(mantis);
|
||||
if (err < 0) {
|
||||
dprintk(verbose, MANTIS_DEBUG, 1, "Mantis UART init failed");
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mantis_core_exit(struct mantis_pci *mantis)
|
||||
{
|
||||
mantis_dma_stop(mantis);
|
||||
dprintk(verbose, MANTIS_ERROR, 1, "DMA engine stopping");
|
||||
|
||||
mantis_uart_exit(mantis);
|
||||
dprintk(verbose, MANTIS_ERROR, 1, "UART exit failed");
|
||||
|
||||
if (mantis_dma_exit(mantis) < 0)
|
||||
dprintk(verbose, MANTIS_ERROR, 1, "DMA exit failed");
|
||||
if (mantis_dvb_exit(mantis) < 0)
|
||||
dprintk(verbose, MANTIS_ERROR, 1, "DVB exit failed");
|
||||
if (mantis_i2c_exit(mantis) < 0)
|
||||
dprintk(verbose, MANTIS_ERROR, 1, "I2C adapter delete.. failed");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Turn the given bit on or off. */
|
||||
void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
|
||||
{
|
||||
u32 cur;
|
||||
|
||||
cur = mmread(MANTIS_GPIF_ADDR);
|
||||
if (value)
|
||||
mantis->gpio_status = cur | (1 << bitpos);
|
||||
else
|
||||
mantis->gpio_status = cur & (~(1 << bitpos));
|
||||
|
||||
mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);
|
||||
mmwrite(0x00, MANTIS_GPIF_DOUT);
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
/* direction = 0 , no CI passthrough ; 1 , CI passthrough */
|
||||
void mantis_set_direction(struct mantis_pci *mantis, int direction)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = mmread(0x28);
|
||||
dprintk(verbose, MANTIS_DEBUG, 1, "TS direction setup");
|
||||
if (direction == 0x01) {
|
||||
/* to CI */
|
||||
reg |= 0x04;
|
||||
mmwrite(reg, 0x28);
|
||||
reg &= 0xff - 0x04;
|
||||
mmwrite(reg, 0x28);
|
||||
} else {
|
||||
reg &= 0xff - 0x04;
|
||||
mmwrite(reg, 0x28);
|
||||
reg |= 0x04;
|
||||
mmwrite(reg, 0x28);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_CORE_H
|
||||
#define __MANTIS_CORE_H
|
||||
|
||||
#include "mantis_common.h"
|
||||
|
||||
|
||||
#define FE_TYPE_SAT 0
|
||||
#define FE_TYPE_CAB 1
|
||||
#define FE_TYPE_TER 2
|
||||
|
||||
#define FE_TYPE_TS204 0
|
||||
#define FE_TYPE_TS188 1
|
||||
|
||||
|
||||
struct vendorname {
|
||||
u8 *sub_vendor_name;
|
||||
u32 sub_vendor_id;
|
||||
};
|
||||
|
||||
struct devicetype {
|
||||
u8 *sub_device_name;
|
||||
u32 sub_device_id;
|
||||
u8 device_type;
|
||||
u32 type_flags;
|
||||
};
|
||||
|
||||
|
||||
extern int mantis_dma_init(struct mantis_pci *mantis);
|
||||
extern int mantis_dma_exit(struct mantis_pci *mantis);
|
||||
extern void mantis_dma_start(struct mantis_pci *mantis);
|
||||
extern void mantis_dma_stop(struct mantis_pci *mantis);
|
||||
extern int mantis_i2c_init(struct mantis_pci *mantis);
|
||||
extern int mantis_i2c_exit(struct mantis_pci *mantis);
|
||||
extern int mantis_core_init(struct mantis_pci *mantis);
|
||||
extern int mantis_core_exit(struct mantis_pci *mantis);
|
||||
|
||||
#endif /* __MANTIS_CORE_H */
|
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/page.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_reg.h"
|
||||
#include "mantis_dma.h"
|
||||
|
||||
#define RISC_WRITE (0x01 << 28)
|
||||
#define RISC_JUMP (0x07 << 28)
|
||||
#define RISC_IRQ (0x01 << 24)
|
||||
|
||||
#define RISC_STATUS(status) ((((~status) & 0x0f) << 20) | ((status & 0x0f) << 16))
|
||||
#define RISC_FLUSH() (mantis->risc_pos = 0)
|
||||
#define RISC_INSTR(opcode) (mantis->risc_cpu[mantis->risc_pos++] = cpu_to_le32(opcode))
|
||||
|
||||
#define MANTIS_BUF_SIZE (64 * 1024)
|
||||
#define MANTIS_BLOCK_BYTES (MANTIS_BUF_SIZE >> 4)
|
||||
#define MANTIS_BLOCK_COUNT (1 << 4)
|
||||
#define MANTIS_RISC_SIZE PAGE_SIZE
|
||||
|
||||
int mantis_dma_exit(struct mantis_pci *mantis)
|
||||
{
|
||||
if (mantis->buf_cpu) {
|
||||
dprintk(MANTIS_ERROR, 1,
|
||||
"DMA=0x%lx cpu=0x%p size=%d",
|
||||
(unsigned long) mantis->buf_dma,
|
||||
mantis->buf_cpu,
|
||||
MANTIS_BUF_SIZE);
|
||||
|
||||
pci_free_consistent(mantis->pdev, MANTIS_BUF_SIZE,
|
||||
mantis->buf_cpu, mantis->buf_dma);
|
||||
|
||||
mantis->buf_cpu = NULL;
|
||||
}
|
||||
if (mantis->risc_cpu) {
|
||||
dprintk(MANTIS_ERROR, 1,
|
||||
"RISC=0x%lx cpu=0x%p size=%lx",
|
||||
(unsigned long) mantis->risc_dma,
|
||||
mantis->risc_cpu,
|
||||
MANTIS_RISC_SIZE);
|
||||
|
||||
pci_free_consistent(mantis->pdev, MANTIS_RISC_SIZE,
|
||||
mantis->risc_cpu, mantis->risc_dma);
|
||||
|
||||
mantis->risc_cpu = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_dma_exit);
|
||||
|
||||
static inline int mantis_alloc_buffers(struct mantis_pci *mantis)
|
||||
{
|
||||
if (!mantis->buf_cpu) {
|
||||
mantis->buf_cpu = pci_alloc_consistent(mantis->pdev,
|
||||
MANTIS_BUF_SIZE,
|
||||
&mantis->buf_dma);
|
||||
if (!mantis->buf_cpu) {
|
||||
dprintk(MANTIS_ERROR, 1,
|
||||
"DMA buffer allocation failed");
|
||||
|
||||
goto err;
|
||||
}
|
||||
dprintk(MANTIS_ERROR, 1,
|
||||
"DMA=0x%lx cpu=0x%p size=%d",
|
||||
(unsigned long) mantis->buf_dma,
|
||||
mantis->buf_cpu, MANTIS_BUF_SIZE);
|
||||
}
|
||||
if (!mantis->risc_cpu) {
|
||||
mantis->risc_cpu = pci_alloc_consistent(mantis->pdev,
|
||||
MANTIS_RISC_SIZE,
|
||||
&mantis->risc_dma);
|
||||
|
||||
if (!mantis->risc_cpu) {
|
||||
dprintk(MANTIS_ERROR, 1,
|
||||
"RISC program allocation failed");
|
||||
|
||||
mantis_dma_exit(mantis);
|
||||
|
||||
goto err;
|
||||
}
|
||||
dprintk(MANTIS_ERROR, 1,
|
||||
"RISC=0x%lx cpu=0x%p size=%lx",
|
||||
(unsigned long) mantis->risc_dma,
|
||||
mantis->risc_cpu, MANTIS_RISC_SIZE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
dprintk(MANTIS_ERROR, 1, "Out of memory (?) .....");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static inline int mantis_calc_lines(struct mantis_pci *mantis)
|
||||
{
|
||||
mantis->line_bytes = MANTIS_BLOCK_BYTES;
|
||||
mantis->line_count = MANTIS_BLOCK_COUNT;
|
||||
|
||||
while (mantis->line_bytes > 4095) {
|
||||
mantis->line_bytes >>= 1;
|
||||
mantis->line_count <<= 1;
|
||||
}
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Mantis RISC block bytes=[%d], line bytes=[%d], line count=[%d]",
|
||||
MANTIS_BLOCK_BYTES, mantis->line_bytes, mantis->line_count);
|
||||
|
||||
if (mantis->line_count > 255) {
|
||||
dprintk(MANTIS_ERROR, 1, "Buffer size error");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mantis_dma_init(struct mantis_pci *mantis)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Mantis DMA init");
|
||||
if (mantis_alloc_buffers(mantis) < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "Error allocating DMA buffer");
|
||||
|
||||
/* Stop RISC Engine */
|
||||
mmwrite(0, MANTIS_DMA_CTL);
|
||||
|
||||
goto err;
|
||||
}
|
||||
err = mantis_calc_lines(mantis);
|
||||
if (err < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "Mantis calc lines failed");
|
||||
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_dma_init);
|
||||
|
||||
static inline void mantis_risc_program(struct mantis_pci *mantis)
|
||||
{
|
||||
u32 buf_pos = 0;
|
||||
u32 line;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Mantis create RISC program");
|
||||
RISC_FLUSH();
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u",
|
||||
mantis->line_count, mantis->line_bytes);
|
||||
|
||||
for (line = 0; line < mantis->line_count; line++) {
|
||||
dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d]", line);
|
||||
if (!(buf_pos % MANTIS_BLOCK_BYTES)) {
|
||||
RISC_INSTR(RISC_WRITE |
|
||||
RISC_IRQ |
|
||||
RISC_STATUS(((buf_pos / MANTIS_BLOCK_BYTES) +
|
||||
(MANTIS_BLOCK_COUNT - 1)) %
|
||||
MANTIS_BLOCK_COUNT) |
|
||||
mantis->line_bytes);
|
||||
} else {
|
||||
RISC_INSTR(RISC_WRITE | mantis->line_bytes);
|
||||
}
|
||||
RISC_INSTR(mantis->buf_dma + buf_pos);
|
||||
buf_pos += mantis->line_bytes;
|
||||
}
|
||||
RISC_INSTR(RISC_JUMP);
|
||||
RISC_INSTR(mantis->risc_dma);
|
||||
}
|
||||
|
||||
void mantis_dma_start(struct mantis_pci *mantis)
|
||||
{
|
||||
dprintk(MANTIS_DEBUG, 1, "Mantis Start DMA engine");
|
||||
|
||||
mantis_risc_program(mantis);
|
||||
mmwrite(mantis->risc_dma, MANTIS_RISC_START);
|
||||
mmwrite(mmread(MANTIS_GPIF_ADDR) | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
|
||||
|
||||
mmwrite(0, MANTIS_DMA_CTL);
|
||||
mantis->last_block = mantis->finished_block = 0;
|
||||
|
||||
mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_RISCI, MANTIS_INT_MASK);
|
||||
|
||||
mmwrite(MANTIS_FIFO_EN | MANTIS_DCAP_EN
|
||||
| MANTIS_RISC_EN, MANTIS_DMA_CTL);
|
||||
|
||||
}
|
||||
|
||||
void mantis_dma_stop(struct mantis_pci *mantis)
|
||||
{
|
||||
u32 stat = 0, mask = 0;
|
||||
|
||||
stat = mmread(MANTIS_INT_STAT);
|
||||
mask = mmread(MANTIS_INT_MASK);
|
||||
dprintk(MANTIS_DEBUG, 1, "Mantis Stop DMA engine");
|
||||
|
||||
mmwrite((mmread(MANTIS_GPIF_ADDR) & (~(MANTIS_GPIF_HIFRDWRN))), MANTIS_GPIF_ADDR);
|
||||
|
||||
mmwrite((mmread(MANTIS_DMA_CTL) & ~(MANTIS_FIFO_EN |
|
||||
MANTIS_DCAP_EN |
|
||||
MANTIS_RISC_EN)), MANTIS_DMA_CTL);
|
||||
|
||||
mmwrite(mmread(MANTIS_INT_STAT), MANTIS_INT_STAT);
|
||||
|
||||
mmwrite(mmread(MANTIS_INT_MASK) & ~(MANTIS_INT_RISCI |
|
||||
MANTIS_INT_RISCEN), MANTIS_INT_MASK);
|
||||
}
|
||||
|
||||
|
||||
void mantis_dma_xfer(unsigned long data)
|
||||
{
|
||||
struct mantis_pci *mantis = (struct mantis_pci *) data;
|
||||
struct mantis_hwconfig *config = mantis->hwconfig;
|
||||
|
||||
while (mantis->last_block != mantis->finished_block) {
|
||||
dprintk(MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]",
|
||||
mantis->last_block, mantis->finished_block);
|
||||
|
||||
(config->ts_size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter)
|
||||
(&mantis->demux, &mantis->buf_cpu[mantis->last_block * MANTIS_BLOCK_BYTES], MANTIS_BLOCK_BYTES);
|
||||
mantis->last_block = (mantis->last_block + 1) % MANTIS_BLOCK_COUNT;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_DMA_H
|
||||
#define __MANTIS_DMA_H
|
||||
|
||||
extern int mantis_dma_init(struct mantis_pci *mantis);
|
||||
extern int mantis_dma_exit(struct mantis_pci *mantis);
|
||||
extern void mantis_dma_start(struct mantis_pci *mantis);
|
||||
extern void mantis_dma_stop(struct mantis_pci *mantis);
|
||||
extern void mantis_dma_xfer(unsigned long data);
|
||||
|
||||
#endif /* __MANTIS_DMA_H */
|
|
@ -0,0 +1,296 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_dma.h"
|
||||
#include "mantis_ca.h"
|
||||
#include "mantis_ioc.h"
|
||||
#include "mantis_dvb.h"
|
||||
|
||||
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
|
||||
|
||||
int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power)
|
||||
{
|
||||
struct mantis_hwconfig *config = mantis->hwconfig;
|
||||
|
||||
switch (power) {
|
||||
case POWER_ON:
|
||||
dprintk(MANTIS_DEBUG, 1, "Power ON");
|
||||
gpio_set_bits(mantis, config->power, POWER_ON);
|
||||
msleep(100);
|
||||
gpio_set_bits(mantis, config->power, POWER_ON);
|
||||
msleep(100);
|
||||
break;
|
||||
|
||||
case POWER_OFF:
|
||||
dprintk(MANTIS_DEBUG, 1, "Power OFF");
|
||||
gpio_set_bits(mantis, config->power, POWER_OFF);
|
||||
msleep(100);
|
||||
break;
|
||||
|
||||
default:
|
||||
dprintk(MANTIS_DEBUG, 1, "Unknown state <%02x>", power);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_frontend_power);
|
||||
|
||||
void mantis_frontend_soft_reset(struct mantis_pci *mantis)
|
||||
{
|
||||
struct mantis_hwconfig *config = mantis->hwconfig;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Frontend RESET");
|
||||
gpio_set_bits(mantis, config->reset, 0);
|
||||
msleep(100);
|
||||
gpio_set_bits(mantis, config->reset, 0);
|
||||
msleep(100);
|
||||
gpio_set_bits(mantis, config->reset, 1);
|
||||
msleep(100);
|
||||
gpio_set_bits(mantis, config->reset, 1);
|
||||
msleep(100);
|
||||
|
||||
return;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_frontend_soft_reset);
|
||||
|
||||
static int mantis_frontend_shutdown(struct mantis_pci *mantis)
|
||||
{
|
||||
int err;
|
||||
|
||||
mantis_frontend_soft_reset(mantis);
|
||||
err = mantis_frontend_power(mantis, POWER_OFF);
|
||||
if (err != 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "Frontend POWER OFF failed! <%d>", err);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mantis_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
|
||||
{
|
||||
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
|
||||
struct mantis_pci *mantis = dvbdmx->priv;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Mantis DVB Start feed");
|
||||
if (!dvbdmx->dmx.frontend) {
|
||||
dprintk(MANTIS_DEBUG, 1, "no frontend ?");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mantis->feeds++;
|
||||
dprintk(MANTIS_DEBUG, 1, "mantis start feed, feeds=%d", mantis->feeds);
|
||||
|
||||
if (mantis->feeds == 1) {
|
||||
dprintk(MANTIS_DEBUG, 1, "mantis start feed & dma");
|
||||
mantis_dma_start(mantis);
|
||||
}
|
||||
|
||||
return mantis->feeds;
|
||||
}
|
||||
|
||||
static int mantis_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
|
||||
{
|
||||
struct dvb_demux *dvbdmx = dvbdmxfeed->demux;
|
||||
struct mantis_pci *mantis = dvbdmx->priv;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Mantis DVB Stop feed");
|
||||
if (!dvbdmx->dmx.frontend) {
|
||||
dprintk(MANTIS_DEBUG, 1, "no frontend ?");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mantis->feeds--;
|
||||
if (mantis->feeds == 0) {
|
||||
dprintk(MANTIS_DEBUG, 1, "mantis stop feed and dma");
|
||||
mantis_dma_stop(mantis);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __devinit mantis_dvb_init(struct mantis_pci *mantis)
|
||||
{
|
||||
struct mantis_hwconfig *config = mantis->hwconfig;
|
||||
int result = -1;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "dvb_register_adapter");
|
||||
|
||||
result = dvb_register_adapter(&mantis->dvb_adapter,
|
||||
"Mantis DVB adapter",
|
||||
THIS_MODULE,
|
||||
&mantis->pdev->dev,
|
||||
adapter_nr);
|
||||
|
||||
if (result < 0) {
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "Error registering adapter");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mantis->dvb_adapter.priv = mantis;
|
||||
mantis->demux.dmx.capabilities = DMX_TS_FILTERING |
|
||||
DMX_SECTION_FILTERING |
|
||||
DMX_MEMORY_BASED_FILTERING;
|
||||
|
||||
mantis->demux.priv = mantis;
|
||||
mantis->demux.filternum = 256;
|
||||
mantis->demux.feednum = 256;
|
||||
mantis->demux.start_feed = mantis_dvb_start_feed;
|
||||
mantis->demux.stop_feed = mantis_dvb_stop_feed;
|
||||
mantis->demux.write_to_decoder = NULL;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "dvb_dmx_init");
|
||||
result = dvb_dmx_init(&mantis->demux);
|
||||
if (result < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
|
||||
|
||||
goto err0;
|
||||
}
|
||||
|
||||
mantis->dmxdev.filternum = 256;
|
||||
mantis->dmxdev.demux = &mantis->demux.dmx;
|
||||
mantis->dmxdev.capabilities = 0;
|
||||
dprintk(MANTIS_DEBUG, 1, "dvb_dmxdev_init");
|
||||
|
||||
result = dvb_dmxdev_init(&mantis->dmxdev, &mantis->dvb_adapter);
|
||||
if (result < 0) {
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "dvb_dmxdev_init failed, ERROR=%d", result);
|
||||
goto err1;
|
||||
}
|
||||
|
||||
mantis->fe_hw.source = DMX_FRONTEND_0;
|
||||
result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_hw);
|
||||
if (result < 0) {
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
|
||||
goto err2;
|
||||
}
|
||||
|
||||
mantis->fe_mem.source = DMX_MEMORY_FE;
|
||||
result = mantis->demux.dmx.add_frontend(&mantis->demux.dmx, &mantis->fe_mem);
|
||||
if (result < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
|
||||
goto err3;
|
||||
}
|
||||
|
||||
result = mantis->demux.dmx.connect_frontend(&mantis->demux.dmx, &mantis->fe_hw);
|
||||
if (result < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "dvb_dmx_init failed, ERROR=%d", result);
|
||||
goto err4;
|
||||
}
|
||||
|
||||
dvb_net_init(&mantis->dvb_adapter, &mantis->dvbnet, &mantis->demux.dmx);
|
||||
tasklet_init(&mantis->tasklet, mantis_dma_xfer, (unsigned long) mantis);
|
||||
if (mantis->hwconfig) {
|
||||
result = config->frontend_init(mantis, mantis->fe);
|
||||
if (result < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "!!! NO Frontends found !!!");
|
||||
goto err5;
|
||||
} else {
|
||||
if (mantis->fe == NULL) {
|
||||
dprintk(MANTIS_ERROR, 1, "FE <NULL>");
|
||||
goto err5;
|
||||
}
|
||||
|
||||
if (dvb_register_frontend(&mantis->dvb_adapter, mantis->fe)) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Frontend registration failed");
|
||||
|
||||
if (mantis->fe->ops.release)
|
||||
mantis->fe->ops.release(mantis->fe);
|
||||
|
||||
mantis->fe = NULL;
|
||||
goto err5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
/* Error conditions .. */
|
||||
err5:
|
||||
tasklet_kill(&mantis->tasklet);
|
||||
dvb_net_release(&mantis->dvbnet);
|
||||
dvb_unregister_frontend(mantis->fe);
|
||||
dvb_frontend_detach(mantis->fe);
|
||||
err4:
|
||||
mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
|
||||
|
||||
err3:
|
||||
mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
|
||||
|
||||
err2:
|
||||
dvb_dmxdev_release(&mantis->dmxdev);
|
||||
|
||||
err1:
|
||||
dvb_dmx_release(&mantis->demux);
|
||||
|
||||
err0:
|
||||
dvb_unregister_adapter(&mantis->dvb_adapter);
|
||||
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_dvb_init);
|
||||
|
||||
int __devexit mantis_dvb_exit(struct mantis_pci *mantis)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (mantis->fe) {
|
||||
/* mantis_ca_exit(mantis); */
|
||||
err = mantis_frontend_shutdown(mantis);
|
||||
if (err != 0)
|
||||
dprintk(MANTIS_ERROR, 1, "Frontend exit while POWER ON! <%d>", err);
|
||||
dvb_unregister_frontend(mantis->fe);
|
||||
dvb_frontend_detach(mantis->fe);
|
||||
}
|
||||
|
||||
tasklet_kill(&mantis->tasklet);
|
||||
dvb_net_release(&mantis->dvbnet);
|
||||
|
||||
mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_mem);
|
||||
mantis->demux.dmx.remove_frontend(&mantis->demux.dmx, &mantis->fe_hw);
|
||||
|
||||
dvb_dmxdev_release(&mantis->dmxdev);
|
||||
dvb_dmx_release(&mantis->demux);
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "dvb_unregister_adapter");
|
||||
dvb_unregister_adapter(&mantis->dvb_adapter);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_dvb_exit);
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_DVB_H
|
||||
#define __MANTIS_DVB_H
|
||||
|
||||
enum mantis_power {
|
||||
POWER_OFF = 0,
|
||||
POWER_ON = 1
|
||||
};
|
||||
|
||||
extern int mantis_frontend_power(struct mantis_pci *mantis, enum mantis_power power);
|
||||
extern void mantis_frontend_soft_reset(struct mantis_pci *mantis);
|
||||
|
||||
extern int mantis_dvb_init(struct mantis_pci *mantis);
|
||||
extern int mantis_dvb_exit(struct mantis_pci *mantis);
|
||||
|
||||
#endif /* __MANTIS_DVB_H */
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_link.h"
|
||||
#include "mantis_hif.h"
|
||||
#include "mantis_reg.h"
|
||||
|
||||
static void mantis_hifevm_work(struct work_struct *work)
|
||||
{
|
||||
struct mantis_ca *ca = container_of(work, struct mantis_ca, hif_evm_work);
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
u32 gpif_stat, gpif_mask;
|
||||
|
||||
gpif_stat = mmread(MANTIS_GPIF_STATUS);
|
||||
gpif_mask = mmread(MANTIS_GPIF_IRQCFG);
|
||||
|
||||
if (gpif_stat & MANTIS_GPIF_DETSTAT) {
|
||||
if (gpif_stat & MANTIS_CARD_PLUGIN) {
|
||||
dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Plugin", mantis->num);
|
||||
mmwrite(0xdada0000, MANTIS_CARD_RESET);
|
||||
mantis_event_cam_plugin(ca);
|
||||
dvb_ca_en50221_camchange_irq(&ca->en50221,
|
||||
0,
|
||||
DVB_CA_EN50221_CAMCHANGE_INSERTED);
|
||||
}
|
||||
} else {
|
||||
if (gpif_stat & MANTIS_CARD_PLUGOUT) {
|
||||
dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): CAM Unplug", mantis->num);
|
||||
mmwrite(0xdada0000, MANTIS_CARD_RESET);
|
||||
mantis_event_cam_unplug(ca);
|
||||
dvb_ca_en50221_camchange_irq(&ca->en50221,
|
||||
0,
|
||||
DVB_CA_EN50221_CAMCHANGE_REMOVED);
|
||||
}
|
||||
}
|
||||
|
||||
if (mantis->gpif_status & MANTIS_GPIF_EXTIRQ)
|
||||
dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Ext IRQ", mantis->num);
|
||||
|
||||
if (mantis->gpif_status & MANTIS_SBUF_WSTO)
|
||||
dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Timeout", mantis->num);
|
||||
|
||||
if (mantis->gpif_status & MANTIS_GPIF_OTHERR)
|
||||
dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Alignment Error", mantis->num);
|
||||
|
||||
if (gpif_stat & MANTIS_SBUF_OVFLW)
|
||||
dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Overflow", mantis->num);
|
||||
|
||||
if (gpif_stat & MANTIS_GPIF_BRRDY)
|
||||
dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Read Ready", mantis->num);
|
||||
|
||||
if (gpif_stat & MANTIS_GPIF_INTSTAT)
|
||||
dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): GPIF IRQ", mantis->num);
|
||||
|
||||
if (gpif_stat & MANTIS_SBUF_EMPTY)
|
||||
dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Empty", mantis->num);
|
||||
|
||||
if (gpif_stat & MANTIS_SBUF_OPDONE) {
|
||||
dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer operation complete", mantis->num);
|
||||
ca->sbuf_status = MANTIS_SBUF_DATA_AVAIL;
|
||||
ca->hif_event = MANTIS_SBUF_OPDONE;
|
||||
wake_up(&ca->hif_opdone_wq);
|
||||
}
|
||||
}
|
||||
|
||||
int mantis_evmgr_init(struct mantis_ca *ca)
|
||||
{
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Initializing Mantis Host I/F Event manager");
|
||||
INIT_WORK(&ca->hif_evm_work, mantis_hifevm_work);
|
||||
mantis_pcmcia_init(ca);
|
||||
schedule_work(&ca->hif_evm_work);
|
||||
mantis_hif_init(ca);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mantis_evmgr_exit(struct mantis_ca *ca)
|
||||
{
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Mantis Host I/F Event manager exiting");
|
||||
flush_scheduled_work();
|
||||
mantis_hif_exit(ca);
|
||||
mantis_pcmcia_exit(ca);
|
||||
}
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "mantis_common.h"
|
||||
|
||||
#include "mantis_hif.h"
|
||||
#include "mantis_link.h" /* temporary due to physical layer stuff */
|
||||
|
||||
#include "mantis_reg.h"
|
||||
|
||||
|
||||
static int mantis_hif_sbuf_opdone_wait(struct mantis_ca *ca)
|
||||
{
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
int rc = 0;
|
||||
|
||||
if (wait_event_timeout(ca->hif_opdone_wq,
|
||||
ca->hif_event & MANTIS_SBUF_OPDONE,
|
||||
msecs_to_jiffies(500)) == -ERESTARTSYS) {
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Smart buffer operation timeout !", mantis->num);
|
||||
rc = -EREMOTEIO;
|
||||
}
|
||||
dprintk(MANTIS_DEBUG, 1, "Smart Buffer Operation complete");
|
||||
ca->hif_event &= ~MANTIS_SBUF_OPDONE;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int mantis_hif_write_wait(struct mantis_ca *ca)
|
||||
{
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
u32 opdone = 0, timeout = 0;
|
||||
int rc = 0;
|
||||
|
||||
if (wait_event_timeout(ca->hif_write_wq,
|
||||
mantis->gpif_status & MANTIS_GPIF_WRACK,
|
||||
msecs_to_jiffies(500)) == -ERESTARTSYS) {
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write ACK timed out !", mantis->num);
|
||||
rc = -EREMOTEIO;
|
||||
}
|
||||
dprintk(MANTIS_DEBUG, 1, "Write Acknowledged");
|
||||
mantis->gpif_status &= ~MANTIS_GPIF_WRACK;
|
||||
while (!opdone) {
|
||||
opdone = (mmread(MANTIS_GPIF_STATUS) & MANTIS_SBUF_OPDONE);
|
||||
udelay(500);
|
||||
timeout++;
|
||||
if (timeout > 100) {
|
||||
dprintk(MANTIS_ERROR, 1, "Adater(%d) Slot(0): Write operation timed out!", mantis->num);
|
||||
rc = -ETIMEDOUT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
dprintk(MANTIS_DEBUG, 1, "HIF Write success");
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr)
|
||||
{
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
u32 hif_addr = 0, data, count = 4;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Read", mantis->num);
|
||||
mutex_lock(&ca->ca_lock);
|
||||
hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
|
||||
hif_addr &= ~MANTIS_GPIF_PCMCIAIOM;
|
||||
hif_addr |= MANTIS_HIF_STATUS;
|
||||
hif_addr |= addr;
|
||||
|
||||
mmwrite(hif_addr, MANTIS_GPIF_BRADDR);
|
||||
mmwrite(count, MANTIS_GPIF_BRBYTES);
|
||||
udelay(20);
|
||||
mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
|
||||
|
||||
if (mantis_hif_sbuf_opdone_wait(ca) != 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): GPIF Smart Buffer operation failed", mantis->num);
|
||||
mutex_unlock(&ca->ca_lock);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
data = mmread(MANTIS_GPIF_DIN);
|
||||
mutex_unlock(&ca->ca_lock);
|
||||
dprintk(MANTIS_DEBUG, 1, "Mem Read: 0x%02x", data);
|
||||
return (data >> 24) & 0xff;
|
||||
}
|
||||
|
||||
int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data)
|
||||
{
|
||||
struct mantis_slot *slot = ca->slot;
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
u32 hif_addr = 0;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Write", mantis->num);
|
||||
mutex_lock(&ca->ca_lock);
|
||||
hif_addr &= ~MANTIS_GPIF_HIFRDWRN;
|
||||
hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
|
||||
hif_addr &= ~MANTIS_GPIF_PCMCIAIOM;
|
||||
hif_addr |= MANTIS_HIF_STATUS;
|
||||
hif_addr |= addr;
|
||||
|
||||
mmwrite(slot->slave_cfg, MANTIS_GPIF_CFGSLA); /* Slot0 alone for now */
|
||||
mmwrite(hif_addr, MANTIS_GPIF_ADDR);
|
||||
mmwrite(data, MANTIS_GPIF_DOUT);
|
||||
|
||||
if (mantis_hif_write_wait(ca) != 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num);
|
||||
mutex_unlock(&ca->ca_lock);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
dprintk(MANTIS_DEBUG, 1, "Mem Write: (0x%02x to 0x%02x)", data, addr);
|
||||
mutex_unlock(&ca->ca_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr)
|
||||
{
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
u32 data, hif_addr = 0;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Read", mantis->num);
|
||||
mutex_lock(&ca->ca_lock);
|
||||
hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
|
||||
hif_addr |= MANTIS_GPIF_PCMCIAIOM;
|
||||
hif_addr |= MANTIS_HIF_STATUS;
|
||||
hif_addr |= addr;
|
||||
|
||||
mmwrite(hif_addr, MANTIS_GPIF_BRADDR);
|
||||
mmwrite(1, MANTIS_GPIF_BRBYTES);
|
||||
udelay(20);
|
||||
mmwrite(hif_addr | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
|
||||
|
||||
if (mantis_hif_sbuf_opdone_wait(ca) != 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num);
|
||||
mutex_unlock(&ca->ca_lock);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
data = mmread(MANTIS_GPIF_DIN);
|
||||
dprintk(MANTIS_DEBUG, 1, "I/O Read: 0x%02x", data);
|
||||
udelay(50);
|
||||
mutex_unlock(&ca->ca_lock);
|
||||
|
||||
return (u8) data;
|
||||
}
|
||||
|
||||
int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data)
|
||||
{
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
u32 hif_addr = 0;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Write", mantis->num);
|
||||
mutex_lock(&ca->ca_lock);
|
||||
hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
|
||||
hif_addr &= ~MANTIS_GPIF_HIFRDWRN;
|
||||
hif_addr |= MANTIS_GPIF_PCMCIAIOM;
|
||||
hif_addr |= MANTIS_HIF_STATUS;
|
||||
hif_addr |= addr;
|
||||
|
||||
mmwrite(hif_addr, MANTIS_GPIF_ADDR);
|
||||
mmwrite(data, MANTIS_GPIF_DOUT);
|
||||
|
||||
if (mantis_hif_write_wait(ca) != 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): HIF Smart Buffer operation failed", mantis->num);
|
||||
mutex_unlock(&ca->ca_lock);
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
dprintk(MANTIS_DEBUG, 1, "I/O Write: (0x%02x to 0x%02x)", data, addr);
|
||||
mutex_unlock(&ca->ca_lock);
|
||||
udelay(50);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mantis_hif_init(struct mantis_ca *ca)
|
||||
{
|
||||
struct mantis_slot *slot = ca->slot;
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
u32 irqcfg;
|
||||
|
||||
slot[0].slave_cfg = 0x70773028;
|
||||
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Initializing Mantis Host Interface", mantis->num);
|
||||
|
||||
mutex_lock(&ca->ca_lock);
|
||||
irqcfg = mmread(MANTIS_GPIF_IRQCFG);
|
||||
irqcfg = MANTIS_MASK_BRRDY |
|
||||
MANTIS_MASK_WRACK |
|
||||
MANTIS_MASK_EXTIRQ |
|
||||
MANTIS_MASK_WSTO |
|
||||
MANTIS_MASK_OTHERR |
|
||||
MANTIS_MASK_OVFLW;
|
||||
|
||||
mmwrite(irqcfg, MANTIS_GPIF_IRQCFG);
|
||||
mutex_unlock(&ca->ca_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mantis_hif_exit(struct mantis_ca *ca)
|
||||
{
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
u32 irqcfg;
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Exiting Mantis Host Interface", mantis->num);
|
||||
mutex_lock(&ca->ca_lock);
|
||||
irqcfg = mmread(MANTIS_GPIF_IRQCFG);
|
||||
irqcfg &= ~MANTIS_MASK_BRRDY;
|
||||
mmwrite(irqcfg, MANTIS_GPIF_IRQCFG);
|
||||
mutex_unlock(&ca->ca_lock);
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_HIF_H
|
||||
#define __MANTIS_HIF_H
|
||||
|
||||
#define MANTIS_HIF_MEMRD 1
|
||||
#define MANTIS_HIF_MEMWR 2
|
||||
#define MANTIS_HIF_IOMRD 3
|
||||
#define MANTIS_HIF_IOMWR 4
|
||||
|
||||
#endif /* __MANTIS_HIF_H */
|
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_reg.h"
|
||||
#include "mantis_i2c.h"
|
||||
|
||||
#define TRIALS 10000
|
||||
|
||||
static int mantis_i2c_read(struct mantis_pci *mantis, const struct i2c_msg *msg)
|
||||
{
|
||||
u32 rxd, i, stat, trials;
|
||||
|
||||
dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <R>[ ",
|
||||
__func__, msg->addr);
|
||||
|
||||
for (i = 0; i < msg->len; i++) {
|
||||
rxd = (msg->addr << 25) | (1 << 24)
|
||||
| MANTIS_I2C_RATE_3
|
||||
| MANTIS_I2C_STOP
|
||||
| MANTIS_I2C_PGMODE;
|
||||
|
||||
if (i == (msg->len - 1))
|
||||
rxd &= ~MANTIS_I2C_STOP;
|
||||
|
||||
mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
|
||||
mmwrite(rxd, MANTIS_I2CDATA_CTL);
|
||||
|
||||
/* wait for xfer completion */
|
||||
for (trials = 0; trials < TRIALS; trials++) {
|
||||
stat = mmread(MANTIS_INT_STAT);
|
||||
if (stat & MANTIS_INT_I2CDONE)
|
||||
break;
|
||||
}
|
||||
|
||||
dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials);
|
||||
|
||||
/* wait for xfer completion */
|
||||
for (trials = 0; trials < TRIALS; trials++) {
|
||||
stat = mmread(MANTIS_INT_STAT);
|
||||
if (stat & MANTIS_INT_I2CRACK)
|
||||
break;
|
||||
}
|
||||
|
||||
dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials);
|
||||
|
||||
rxd = mmread(MANTIS_I2CDATA_CTL);
|
||||
msg->buf[i] = (u8)((rxd >> 8) & 0xFF);
|
||||
dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]);
|
||||
}
|
||||
dprintk(MANTIS_INFO, 0, "]\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mantis_i2c_write(struct mantis_pci *mantis, const struct i2c_msg *msg)
|
||||
{
|
||||
int i;
|
||||
u32 txd = 0, stat, trials;
|
||||
|
||||
dprintk(MANTIS_INFO, 0, " %s: Address=[0x%02x] <W>[ ",
|
||||
__func__, msg->addr);
|
||||
|
||||
for (i = 0; i < msg->len; i++) {
|
||||
dprintk(MANTIS_INFO, 0, "%02x ", msg->buf[i]);
|
||||
txd = (msg->addr << 25) | (msg->buf[i] << 8)
|
||||
| MANTIS_I2C_RATE_3
|
||||
| MANTIS_I2C_STOP
|
||||
| MANTIS_I2C_PGMODE;
|
||||
|
||||
if (i == (msg->len - 1))
|
||||
txd &= ~MANTIS_I2C_STOP;
|
||||
|
||||
mmwrite(MANTIS_INT_I2CDONE, MANTIS_INT_STAT);
|
||||
mmwrite(txd, MANTIS_I2CDATA_CTL);
|
||||
|
||||
/* wait for xfer completion */
|
||||
for (trials = 0; trials < TRIALS; trials++) {
|
||||
stat = mmread(MANTIS_INT_STAT);
|
||||
if (stat & MANTIS_INT_I2CDONE)
|
||||
break;
|
||||
}
|
||||
|
||||
dprintk(MANTIS_TMG, 0, "I2CDONE: trials=%d\n", trials);
|
||||
|
||||
/* wait for xfer completion */
|
||||
for (trials = 0; trials < TRIALS; trials++) {
|
||||
stat = mmread(MANTIS_INT_STAT);
|
||||
if (stat & MANTIS_INT_I2CRACK)
|
||||
break;
|
||||
}
|
||||
|
||||
dprintk(MANTIS_TMG, 0, "I2CRACK: trials=%d\n", trials);
|
||||
}
|
||||
dprintk(MANTIS_INFO, 0, "]\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mantis_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
|
||||
{
|
||||
int ret = 0, i = 0, trials;
|
||||
u32 stat, data, txd;
|
||||
struct mantis_pci *mantis;
|
||||
struct mantis_hwconfig *config;
|
||||
|
||||
mantis = i2c_get_adapdata(adapter);
|
||||
BUG_ON(!mantis);
|
||||
config = mantis->hwconfig;
|
||||
BUG_ON(!config);
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Messages:%d", num);
|
||||
mutex_lock(&mantis->i2c_lock);
|
||||
|
||||
while (i < num) {
|
||||
/* Byte MODE */
|
||||
if ((config->i2c_mode & MANTIS_BYTE_MODE) &&
|
||||
((i + 1) < num) &&
|
||||
(msgs[i].len < 2) &&
|
||||
(msgs[i + 1].len < 2) &&
|
||||
(msgs[i + 1].flags & I2C_M_RD)) {
|
||||
|
||||
dprintk(MANTIS_DEBUG, 0, " Byte MODE:\n");
|
||||
|
||||
/* Read operation */
|
||||
txd = msgs[i].addr << 25 | (0x1 << 24)
|
||||
| (msgs[i].buf[0] << 16)
|
||||
| MANTIS_I2C_RATE_3;
|
||||
|
||||
mmwrite(txd, MANTIS_I2CDATA_CTL);
|
||||
/* wait for xfer completion */
|
||||
for (trials = 0; trials < TRIALS; trials++) {
|
||||
stat = mmread(MANTIS_INT_STAT);
|
||||
if (stat & MANTIS_INT_I2CDONE)
|
||||
break;
|
||||
}
|
||||
|
||||
/* check for xfer completion */
|
||||
if (stat & MANTIS_INT_I2CDONE) {
|
||||
/* check xfer was acknowledged */
|
||||
if (stat & MANTIS_INT_I2CRACK) {
|
||||
data = mmread(MANTIS_I2CDATA_CTL);
|
||||
msgs[i + 1].buf[0] = (data >> 8) & 0xff;
|
||||
dprintk(MANTIS_DEBUG, 0, " Byte <%d> RXD=0x%02x [%02x]\n", 0x0, data, msgs[i + 1].buf[0]);
|
||||
} else {
|
||||
/* I/O error */
|
||||
dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__);
|
||||
ret = -EIO;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
/* I/O error */
|
||||
dprintk(MANTIS_ERROR, 1, " I/O error, LINE:%d", __LINE__);
|
||||
ret = -EIO;
|
||||
break;
|
||||
}
|
||||
i += 2; /* Write/Read operation in one go */
|
||||
}
|
||||
|
||||
if (i < num) {
|
||||
if (msgs[i].flags & I2C_M_RD)
|
||||
ret = mantis_i2c_read(mantis, &msgs[i]);
|
||||
else
|
||||
ret = mantis_i2c_write(mantis, &msgs[i]);
|
||||
|
||||
i++;
|
||||
if (ret < 0)
|
||||
goto bail_out;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
mutex_unlock(&mantis->i2c_lock);
|
||||
|
||||
return num;
|
||||
|
||||
bail_out:
|
||||
mutex_unlock(&mantis->i2c_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static u32 mantis_i2c_func(struct i2c_adapter *adapter)
|
||||
{
|
||||
return I2C_FUNC_SMBUS_EMUL;
|
||||
}
|
||||
|
||||
static struct i2c_algorithm mantis_algo = {
|
||||
.master_xfer = mantis_i2c_xfer,
|
||||
.functionality = mantis_i2c_func,
|
||||
};
|
||||
|
||||
int __devinit mantis_i2c_init(struct mantis_pci *mantis)
|
||||
{
|
||||
u32 intstat, intmask;
|
||||
struct i2c_adapter *i2c_adapter = &mantis->adapter;
|
||||
struct pci_dev *pdev = mantis->pdev;
|
||||
|
||||
init_waitqueue_head(&mantis->i2c_wq);
|
||||
mutex_init(&mantis->i2c_lock);
|
||||
strncpy(i2c_adapter->name, "Mantis I2C", sizeof(i2c_adapter->name));
|
||||
i2c_set_adapdata(i2c_adapter, mantis);
|
||||
|
||||
i2c_adapter->owner = THIS_MODULE;
|
||||
i2c_adapter->class = I2C_CLASS_TV_DIGITAL;
|
||||
i2c_adapter->algo = &mantis_algo;
|
||||
i2c_adapter->algo_data = NULL;
|
||||
i2c_adapter->timeout = 500;
|
||||
i2c_adapter->retries = 3;
|
||||
i2c_adapter->dev.parent = &pdev->dev;
|
||||
|
||||
mantis->i2c_rc = i2c_add_adapter(i2c_adapter);
|
||||
if (mantis->i2c_rc < 0)
|
||||
return mantis->i2c_rc;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Initializing I2C ..");
|
||||
|
||||
intstat = mmread(MANTIS_INT_STAT);
|
||||
intmask = mmread(MANTIS_INT_MASK);
|
||||
mmwrite(intstat, MANTIS_INT_STAT);
|
||||
dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
|
||||
intmask = mmread(MANTIS_INT_MASK);
|
||||
mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_i2c_init);
|
||||
|
||||
int mantis_i2c_exit(struct mantis_pci *mantis)
|
||||
{
|
||||
u32 intmask;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Disabling I2C interrupt");
|
||||
intmask = mmread(MANTIS_INT_MASK);
|
||||
mmwrite((intmask & ~MANTIS_INT_I2CDONE), MANTIS_INT_MASK);
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Removing I2C adapter");
|
||||
return i2c_del_adapter(&mantis->adapter);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_i2c_exit);
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_I2C_H
|
||||
#define __MANTIS_I2C_H
|
||||
|
||||
#define I2C_STOP (1 << 0)
|
||||
#define I2C_READ (1 << 1)
|
||||
|
||||
extern int mantis_i2c_init(struct mantis_pci *mantis);
|
||||
extern int mantis_i2c_exit(struct mantis_pci *mantis);
|
||||
|
||||
#endif /* __MANTIS_I2C_H */
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/input.h>
|
||||
#include <media/ir-common.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_reg.h"
|
||||
#include "mantis_uart.h"
|
||||
|
||||
static struct ir_scancode mantis_ir_table[] = {
|
||||
{ 0x29, KEY_POWER },
|
||||
{ 0x28, KEY_FAVORITES },
|
||||
{ 0x30, KEY_TEXT },
|
||||
{ 0x17, KEY_INFO }, /* Preview */
|
||||
{ 0x23, KEY_EPG },
|
||||
{ 0x3b, KEY_F22 }, /* Record List */
|
||||
{ 0x3c, KEY_1 },
|
||||
{ 0x3e, KEY_2 },
|
||||
{ 0x39, KEY_3 },
|
||||
{ 0x36, KEY_4 },
|
||||
{ 0x22, KEY_5 },
|
||||
{ 0x20, KEY_6 },
|
||||
{ 0x32, KEY_7 },
|
||||
{ 0x26, KEY_8 },
|
||||
{ 0x24, KEY_9 },
|
||||
{ 0x2a, KEY_0 },
|
||||
|
||||
{ 0x33, KEY_CANCEL },
|
||||
{ 0x2c, KEY_BACK },
|
||||
{ 0x15, KEY_CLEAR },
|
||||
{ 0x3f, KEY_TAB },
|
||||
{ 0x10, KEY_ENTER },
|
||||
{ 0x14, KEY_UP },
|
||||
{ 0x0d, KEY_RIGHT },
|
||||
{ 0x0e, KEY_DOWN },
|
||||
{ 0x11, KEY_LEFT },
|
||||
|
||||
{ 0x21, KEY_VOLUMEUP },
|
||||
{ 0x35, KEY_VOLUMEDOWN },
|
||||
{ 0x3d, KEY_CHANNELDOWN },
|
||||
{ 0x3a, KEY_CHANNELUP },
|
||||
{ 0x2e, KEY_RECORD },
|
||||
{ 0x2b, KEY_PLAY },
|
||||
{ 0x13, KEY_PAUSE },
|
||||
{ 0x25, KEY_STOP },
|
||||
|
||||
{ 0x1f, KEY_REWIND },
|
||||
{ 0x2d, KEY_FASTFORWARD },
|
||||
{ 0x1e, KEY_PREVIOUS }, /* Replay |< */
|
||||
{ 0x1d, KEY_NEXT }, /* Skip >| */
|
||||
|
||||
{ 0x0b, KEY_CAMERA }, /* Capture */
|
||||
{ 0x0f, KEY_LANGUAGE }, /* SAP */
|
||||
{ 0x18, KEY_MODE }, /* PIP */
|
||||
{ 0x12, KEY_ZOOM }, /* Full screen */
|
||||
{ 0x1c, KEY_SUBTITLE },
|
||||
{ 0x2f, KEY_MUTE },
|
||||
{ 0x16, KEY_F20 }, /* L/R */
|
||||
{ 0x38, KEY_F21 }, /* Hibernate */
|
||||
|
||||
{ 0x37, KEY_SWITCHVIDEOMODE }, /* A/V */
|
||||
{ 0x31, KEY_AGAIN }, /* Recall */
|
||||
{ 0x1a, KEY_KPPLUS }, /* Zoom+ */
|
||||
{ 0x19, KEY_KPMINUS }, /* Zoom- */
|
||||
{ 0x27, KEY_RED },
|
||||
{ 0x0C, KEY_GREEN },
|
||||
{ 0x01, KEY_YELLOW },
|
||||
{ 0x00, KEY_BLUE },
|
||||
};
|
||||
|
||||
struct ir_scancode_table ir_mantis = {
|
||||
.scan = mantis_ir_table,
|
||||
.size = ARRAY_SIZE(mantis_ir_table),
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ir_mantis);
|
||||
|
||||
int mantis_input_init(struct mantis_pci *mantis)
|
||||
{
|
||||
struct input_dev *rc;
|
||||
struct ir_input_state rc_state;
|
||||
char name[80], dev[80];
|
||||
int err;
|
||||
|
||||
rc = input_allocate_device();
|
||||
if (!rc) {
|
||||
dprintk(MANTIS_ERROR, 1, "Input device allocate failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
sprintf(name, "Mantis %s IR receiver", mantis->hwconfig->model_name);
|
||||
sprintf(dev, "pci-%s/ir0", pci_name(mantis->pdev));
|
||||
|
||||
rc->name = name;
|
||||
rc->phys = dev;
|
||||
|
||||
ir_input_init(rc, &rc_state, IR_TYPE_OTHER);
|
||||
|
||||
rc->id.bustype = BUS_PCI;
|
||||
rc->id.vendor = mantis->vendor_id;
|
||||
rc->id.product = mantis->device_id;
|
||||
rc->id.version = 1;
|
||||
rc->dev = mantis->pdev->dev;
|
||||
|
||||
err = ir_input_register(rc, &ir_mantis);
|
||||
if (err) {
|
||||
dprintk(MANTIS_ERROR, 1, "IR device registration failed, ret = %d", err);
|
||||
input_free_device(rc);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
mantis->rc = rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mantis_exit(struct mantis_pci *mantis)
|
||||
{
|
||||
struct input_dev *rc = mantis->rc;
|
||||
|
||||
ir_input_unregister(rc);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_reg.h"
|
||||
#include "mantis_ioc.h"
|
||||
|
||||
static int read_eeprom_bytes(struct mantis_pci *mantis, u8 reg, u8 *data, u8 length)
|
||||
{
|
||||
struct i2c_adapter *adapter = &mantis->adapter;
|
||||
int err;
|
||||
u8 buf = reg;
|
||||
|
||||
struct i2c_msg msg[] = {
|
||||
{ .addr = 0x50, .flags = 0, .buf = &buf, .len = 1 },
|
||||
{ .addr = 0x50, .flags = I2C_M_RD, .buf = data, .len = length },
|
||||
};
|
||||
|
||||
err = i2c_transfer(adapter, msg, 2);
|
||||
if (err < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: i2c read: < err=%i d0=0x%02x d1=0x%02x >",
|
||||
err, data[0], data[1]);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
int mantis_get_mac(struct mantis_pci *mantis)
|
||||
{
|
||||
int err;
|
||||
u8 mac_addr[6] = {0};
|
||||
|
||||
err = read_eeprom_bytes(mantis, 0x08, mac_addr, 6);
|
||||
if (err < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Mantis EEPROM read error <%d>", err);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
dprintk(MANTIS_ERROR, 0,
|
||||
" MAC Address=[%02x:%02x:%02x:%02x:%02x:%02x]\n",
|
||||
mac_addr[0],
|
||||
mac_addr[1],
|
||||
mac_addr[2],
|
||||
mac_addr[3],
|
||||
mac_addr[4],
|
||||
mac_addr[5]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_get_mac);
|
||||
|
||||
/* Turn the given bit on or off. */
|
||||
void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value)
|
||||
{
|
||||
u32 cur;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Set Bit <%d> to <%d>", bitpos, value);
|
||||
cur = mmread(MANTIS_GPIF_ADDR);
|
||||
if (value)
|
||||
mantis->gpio_status = cur | (1 << bitpos);
|
||||
else
|
||||
mantis->gpio_status = cur & (~(1 << bitpos));
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "GPIO Value <%02x>", mantis->gpio_status);
|
||||
mmwrite(mantis->gpio_status, MANTIS_GPIF_ADDR);
|
||||
mmwrite(0x00, MANTIS_GPIF_DOUT);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(gpio_set_bits);
|
||||
|
||||
int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = mmread(MANTIS_CONTROL);
|
||||
switch (stream_ctl) {
|
||||
case STREAM_TO_HIF:
|
||||
dprintk(MANTIS_DEBUG, 1, "Set stream to HIF");
|
||||
reg &= 0xff - MANTIS_BYPASS;
|
||||
mmwrite(reg, MANTIS_CONTROL);
|
||||
reg |= MANTIS_BYPASS;
|
||||
mmwrite(reg, MANTIS_CONTROL);
|
||||
break;
|
||||
|
||||
case STREAM_TO_CAM:
|
||||
dprintk(MANTIS_DEBUG, 1, "Set stream to CAM");
|
||||
reg |= MANTIS_BYPASS;
|
||||
mmwrite(reg, MANTIS_CONTROL);
|
||||
reg &= 0xff - MANTIS_BYPASS;
|
||||
mmwrite(reg, MANTIS_CONTROL);
|
||||
break;
|
||||
default:
|
||||
dprintk(MANTIS_ERROR, 1, "Unknown MODE <%02x>", stream_ctl);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_stream_control);
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_IOC_H
|
||||
#define __MANTIS_IOC_H
|
||||
|
||||
#define GPIF_A00 0x00
|
||||
#define GPIF_A01 0x01
|
||||
#define GPIF_A02 0x02
|
||||
#define GPIF_A03 0x03
|
||||
#define GPIF_A04 0x04
|
||||
#define GPIF_A05 0x05
|
||||
#define GPIF_A06 0x06
|
||||
#define GPIF_A07 0x07
|
||||
#define GPIF_A08 0x08
|
||||
#define GPIF_A09 0x09
|
||||
#define GPIF_A10 0x0a
|
||||
#define GPIF_A11 0x0b
|
||||
|
||||
#define GPIF_A12 0x0c
|
||||
#define GPIF_A13 0x0d
|
||||
#define GPIF_A14 0x0e
|
||||
|
||||
enum mantis_stream_control {
|
||||
STREAM_TO_HIF = 0,
|
||||
STREAM_TO_CAM
|
||||
};
|
||||
|
||||
extern int mantis_get_mac(struct mantis_pci *mantis);
|
||||
extern void gpio_set_bits(struct mantis_pci *mantis, u32 bitpos, u8 value);
|
||||
|
||||
extern int mantis_stream_control(struct mantis_pci *mantis, enum mantis_stream_control stream_ctl);
|
||||
|
||||
#endif /* __MANTIS_IOC_H */
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_LINK_H
|
||||
#define __MANTIS_LINK_H
|
||||
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include "dvb_ca_en50221.h"
|
||||
|
||||
enum mantis_sbuf_status {
|
||||
MANTIS_SBUF_DATA_AVAIL = 1,
|
||||
MANTIS_SBUF_DATA_EMPTY = 2,
|
||||
MANTIS_SBUF_DATA_OVFLW = 3
|
||||
};
|
||||
|
||||
struct mantis_slot {
|
||||
u32 timeout;
|
||||
u32 slave_cfg;
|
||||
u32 bar;
|
||||
};
|
||||
|
||||
/* Physical layer */
|
||||
enum mantis_slot_state {
|
||||
MODULE_INSERTED = 3,
|
||||
MODULE_XTRACTED = 4
|
||||
};
|
||||
|
||||
struct mantis_ca {
|
||||
struct mantis_slot slot[4];
|
||||
|
||||
struct work_struct hif_evm_work;
|
||||
|
||||
u32 hif_event;
|
||||
wait_queue_head_t hif_opdone_wq;
|
||||
wait_queue_head_t hif_brrdyw_wq;
|
||||
wait_queue_head_t hif_data_wq;
|
||||
wait_queue_head_t hif_write_wq; /* HIF Write op */
|
||||
|
||||
enum mantis_sbuf_status sbuf_status;
|
||||
|
||||
enum mantis_slot_state slot_state;
|
||||
|
||||
void *ca_priv;
|
||||
|
||||
struct dvb_ca_en50221 en50221;
|
||||
struct mutex ca_lock;
|
||||
};
|
||||
|
||||
/* CA */
|
||||
extern void mantis_event_cam_plugin(struct mantis_ca *ca);
|
||||
extern void mantis_event_cam_unplug(struct mantis_ca *ca);
|
||||
extern int mantis_pcmcia_init(struct mantis_ca *ca);
|
||||
extern void mantis_pcmcia_exit(struct mantis_ca *ca);
|
||||
extern int mantis_evmgr_init(struct mantis_ca *ca);
|
||||
extern void mantis_evmgr_exit(struct mantis_ca *ca);
|
||||
|
||||
/* HIF */
|
||||
extern int mantis_hif_init(struct mantis_ca *ca);
|
||||
extern void mantis_hif_exit(struct mantis_ca *ca);
|
||||
extern int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr);
|
||||
extern int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data);
|
||||
extern int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr);
|
||||
extern int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data);
|
||||
|
||||
#endif /* __MANTIS_LINK_H */
|
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/page.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include <asm/irq.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_reg.h"
|
||||
#include "mantis_pci.h"
|
||||
|
||||
#define DRIVER_NAME "Mantis Core"
|
||||
|
||||
int __devinit mantis_pci_init(struct mantis_pci *mantis)
|
||||
{
|
||||
u8 revision, latency;
|
||||
struct mantis_hwconfig *config = mantis->hwconfig;
|
||||
struct pci_dev *pdev = mantis->pdev;
|
||||
int err, ret = 0;
|
||||
|
||||
dprintk(MANTIS_ERROR, 0, "found a %s PCI %s device on (%02x:%02x.%x),\n",
|
||||
config->model_name,
|
||||
config->dev_type,
|
||||
mantis->pdev->bus->number,
|
||||
PCI_SLOT(mantis->pdev->devfn),
|
||||
PCI_FUNC(mantis->pdev->devfn));
|
||||
|
||||
err = pci_enable_device(pdev);
|
||||
if (err != 0) {
|
||||
ret = -ENODEV;
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: PCI enable failed <%i>", err);
|
||||
goto fail0;
|
||||
}
|
||||
|
||||
err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
|
||||
if (err != 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: Unable to obtain 32 bit DMA <%i>", err);
|
||||
ret = -ENOMEM;
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
pci_set_master(pdev);
|
||||
|
||||
if (!request_mem_region(pci_resource_start(pdev, 0),
|
||||
pci_resource_len(pdev, 0),
|
||||
DRIVER_NAME)) {
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 Request failed !");
|
||||
ret = -ENODEV;
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
mantis->mmio = ioremap(pci_resource_start(pdev, 0),
|
||||
pci_resource_len(pdev, 0));
|
||||
|
||||
if (!mantis->mmio) {
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: BAR0 remap failed !");
|
||||
ret = -ENODEV;
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency);
|
||||
pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
|
||||
mantis->latency = latency;
|
||||
mantis->revision = revision;
|
||||
|
||||
dprintk(MANTIS_ERROR, 0, " Mantis Rev %d [%04x:%04x], ",
|
||||
mantis->revision,
|
||||
mantis->pdev->subsystem_vendor,
|
||||
mantis->pdev->subsystem_device);
|
||||
|
||||
dprintk(MANTIS_ERROR, 0,
|
||||
"irq: %d, latency: %d\n memory: 0x%lx, mmio: 0x%p\n",
|
||||
mantis->pdev->irq,
|
||||
mantis->latency,
|
||||
mantis->mantis_addr,
|
||||
mantis->mmio);
|
||||
|
||||
err = request_irq(pdev->irq,
|
||||
config->irq_handler,
|
||||
IRQF_SHARED,
|
||||
DRIVER_NAME,
|
||||
mantis);
|
||||
|
||||
if (err != 0) {
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: IRQ registration failed ! <%d>", err);
|
||||
ret = -ENODEV;
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
pci_set_drvdata(pdev, mantis);
|
||||
return ret;
|
||||
|
||||
/* Error conditions */
|
||||
fail3:
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: <%d> I/O unmap", ret);
|
||||
if (mantis->mmio)
|
||||
iounmap(mantis->mmio);
|
||||
|
||||
fail2:
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: <%d> releasing regions", ret);
|
||||
release_mem_region(pci_resource_start(pdev, 0),
|
||||
pci_resource_len(pdev, 0));
|
||||
|
||||
fail1:
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: <%d> disabling device", ret);
|
||||
pci_disable_device(pdev);
|
||||
|
||||
fail0:
|
||||
dprintk(MANTIS_ERROR, 1, "ERROR: <%d> exiting", ret);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_pci_init);
|
||||
|
||||
void mantis_pci_exit(struct mantis_pci *mantis)
|
||||
{
|
||||
struct pci_dev *pdev = mantis->pdev;
|
||||
|
||||
dprintk(MANTIS_NOTICE, 1, " mem: 0x%p", mantis->mmio);
|
||||
free_irq(pdev->irq, mantis);
|
||||
if (mantis->mmio) {
|
||||
iounmap(mantis->mmio);
|
||||
release_mem_region(pci_resource_start(pdev, 0),
|
||||
pci_resource_len(pdev, 0));
|
||||
}
|
||||
|
||||
pci_disable_device(pdev);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_pci_exit);
|
||||
|
||||
MODULE_DESCRIPTION("Mantis PCI DTV bridge driver");
|
||||
MODULE_AUTHOR("Manu Abraham");
|
||||
MODULE_LICENSE("GPL");
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_PCI_H
|
||||
#define __MANTIS_PCI_H
|
||||
|
||||
extern int mantis_pci_init(struct mantis_pci *mantis);
|
||||
extern void mantis_pci_exit(struct mantis_pci *mantis);
|
||||
|
||||
#endif /* __MANTIS_PCI_H */
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_link.h" /* temporary due to physical layer stuff */
|
||||
#include "mantis_reg.h"
|
||||
|
||||
/*
|
||||
* If Slot state is already PLUG_IN event and we are called
|
||||
* again, definitely it is jitter alone
|
||||
*/
|
||||
void mantis_event_cam_plugin(struct mantis_ca *ca)
|
||||
{
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
u32 gpif_irqcfg;
|
||||
|
||||
if (ca->slot_state == MODULE_XTRACTED) {
|
||||
dprintk(MANTIS_DEBUG, 1, "Event: CAM Plugged IN: Adapter(%d) Slot(0)", mantis->num);
|
||||
udelay(50);
|
||||
mmwrite(0xda000000, MANTIS_CARD_RESET);
|
||||
gpif_irqcfg = mmread(MANTIS_GPIF_IRQCFG);
|
||||
gpif_irqcfg |= MANTIS_MASK_PLUGOUT;
|
||||
gpif_irqcfg &= ~MANTIS_MASK_PLUGIN;
|
||||
mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG);
|
||||
udelay(500);
|
||||
ca->slot_state = MODULE_INSERTED;
|
||||
}
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
/*
|
||||
* If Slot state is already UN_PLUG event and we are called
|
||||
* again, definitely it is jitter alone
|
||||
*/
|
||||
void mantis_event_cam_unplug(struct mantis_ca *ca)
|
||||
{
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
u32 gpif_irqcfg;
|
||||
|
||||
if (ca->slot_state == MODULE_INSERTED) {
|
||||
dprintk(MANTIS_DEBUG, 1, "Event: CAM Unplugged: Adapter(%d) Slot(0)", mantis->num);
|
||||
udelay(50);
|
||||
mmwrite(0x00da0000, MANTIS_CARD_RESET);
|
||||
gpif_irqcfg = mmread(MANTIS_GPIF_IRQCFG);
|
||||
gpif_irqcfg |= MANTIS_MASK_PLUGIN;
|
||||
gpif_irqcfg &= ~MANTIS_MASK_PLUGOUT;
|
||||
mmwrite(gpif_irqcfg, MANTIS_GPIF_IRQCFG);
|
||||
udelay(500);
|
||||
ca->slot_state = MODULE_XTRACTED;
|
||||
}
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
int mantis_pcmcia_init(struct mantis_ca *ca)
|
||||
{
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
u32 gpif_stat, card_stat;
|
||||
|
||||
mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_IRQ0, MANTIS_INT_MASK);
|
||||
gpif_stat = mmread(MANTIS_GPIF_STATUS);
|
||||
card_stat = mmread(MANTIS_GPIF_IRQCFG);
|
||||
|
||||
if (gpif_stat & MANTIS_GPIF_DETSTAT) {
|
||||
dprintk(MANTIS_DEBUG, 1, "CAM found on Adapter(%d) Slot(0)", mantis->num);
|
||||
mmwrite(card_stat | MANTIS_MASK_PLUGOUT, MANTIS_GPIF_IRQCFG);
|
||||
ca->slot_state = MODULE_INSERTED;
|
||||
dvb_ca_en50221_camchange_irq(&ca->en50221,
|
||||
0,
|
||||
DVB_CA_EN50221_CAMCHANGE_INSERTED);
|
||||
} else {
|
||||
dprintk(MANTIS_DEBUG, 1, "Empty Slot on Adapter(%d) Slot(0)", mantis->num);
|
||||
mmwrite(card_stat | MANTIS_MASK_PLUGIN, MANTIS_GPIF_IRQCFG);
|
||||
ca->slot_state = MODULE_XTRACTED;
|
||||
dvb_ca_en50221_camchange_irq(&ca->en50221,
|
||||
0,
|
||||
DVB_CA_EN50221_CAMCHANGE_REMOVED);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mantis_pcmcia_exit(struct mantis_ca *ca)
|
||||
{
|
||||
struct mantis_pci *mantis = ca->ca_priv;
|
||||
|
||||
mmwrite(mmread(MANTIS_GPIF_STATUS) & (~MANTIS_CARD_PLUGOUT | ~MANTIS_CARD_PLUGIN), MANTIS_GPIF_STATUS);
|
||||
mmwrite(mmread(MANTIS_INT_MASK) & ~MANTIS_INT_IRQ0, MANTIS_INT_MASK);
|
||||
}
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_REG_H
|
||||
#define __MANTIS_REG_H
|
||||
|
||||
/* Interrupts */
|
||||
#define MANTIS_INT_STAT 0x00
|
||||
#define MANTIS_INT_MASK 0x04
|
||||
|
||||
#define MANTIS_INT_RISCSTAT (0x0f << 28)
|
||||
#define MANTIS_INT_RISCEN (0x01 << 27)
|
||||
#define MANTIS_INT_I2CRACK (0x01 << 26)
|
||||
|
||||
/* #define MANTIS_INT_GPIF (0xff << 12) */
|
||||
|
||||
#define MANTIS_INT_PCMCIA7 (0x01 << 19)
|
||||
#define MANTIS_INT_PCMCIA6 (0x01 << 18)
|
||||
#define MANTIS_INT_PCMCIA5 (0x01 << 17)
|
||||
#define MANTIS_INT_PCMCIA4 (0x01 << 16)
|
||||
#define MANTIS_INT_PCMCIA3 (0x01 << 15)
|
||||
#define MANTIS_INT_PCMCIA2 (0x01 << 14)
|
||||
#define MANTIS_INT_PCMCIA1 (0x01 << 13)
|
||||
#define MANTIS_INT_PCMCIA0 (0x01 << 12)
|
||||
#define MANTIS_INT_IRQ1 (0x01 << 11)
|
||||
#define MANTIS_INT_IRQ0 (0x01 << 10)
|
||||
#define MANTIS_INT_OCERR (0x01 << 8)
|
||||
#define MANTIS_INT_PABORT (0x01 << 7)
|
||||
#define MANTIS_INT_RIPERR (0x01 << 6)
|
||||
#define MANTIS_INT_PPERR (0x01 << 5)
|
||||
#define MANTIS_INT_FTRGT (0x01 << 3)
|
||||
#define MANTIS_INT_RISCI (0x01 << 1)
|
||||
#define MANTIS_INT_I2CDONE (0x01 << 0)
|
||||
|
||||
/* DMA */
|
||||
#define MANTIS_DMA_CTL 0x08
|
||||
#define MANTIS_GPIF_RD (0xff << 24)
|
||||
#define MANTIS_GPIF_WR (0xff << 16)
|
||||
#define MANTIS_CPU_DO (0x01 << 10)
|
||||
#define MANTIS_DRV_DO (0x01 << 9)
|
||||
#define MANTIS_I2C_RD (0x01 << 7)
|
||||
#define MANTIS_I2C_WR (0x01 << 6)
|
||||
#define MANTIS_DCAP_MODE (0x01 << 5)
|
||||
#define MANTIS_FIFO_TP_4 (0x00 << 3)
|
||||
#define MANTIS_FIFO_TP_8 (0x01 << 3)
|
||||
#define MANTIS_FIFO_TP_16 (0x02 << 3)
|
||||
#define MANTIS_FIFO_EN (0x01 << 2)
|
||||
#define MANTIS_DCAP_EN (0x01 << 1)
|
||||
#define MANTIS_RISC_EN (0x01 << 0)
|
||||
|
||||
/* DEBUG */
|
||||
#define MANTIS_DEBUGREG 0x0c
|
||||
#define MANTIS_DATINV (0x0e << 7)
|
||||
#define MANTIS_TOP_DEBUGSEL (0x07 << 4)
|
||||
#define MANTIS_PCMCIA_DEBUGSEL (0x0f << 0)
|
||||
|
||||
#define MANTIS_RISC_START 0x10
|
||||
#define MANTIS_RISC_PC 0x14
|
||||
|
||||
/* I2C */
|
||||
#define MANTIS_I2CDATA_CTL 0x18
|
||||
#define MANTIS_I2C_RATE_1 (0x00 << 6)
|
||||
#define MANTIS_I2C_RATE_2 (0x01 << 6)
|
||||
#define MANTIS_I2C_RATE_3 (0x02 << 6)
|
||||
#define MANTIS_I2C_RATE_4 (0x03 << 6)
|
||||
#define MANTIS_I2C_STOP (0x01 << 5)
|
||||
#define MANTIS_I2C_PGMODE (0x01 << 3)
|
||||
|
||||
/* DATA */
|
||||
#define MANTIS_CMD_DATA_R1 0x20
|
||||
#define MANTIS_CMD_DATA_3 (0xff << 24)
|
||||
#define MANTIS_CMD_DATA_2 (0xff << 16)
|
||||
#define MANTIS_CMD_DATA_1 (0xff << 8)
|
||||
#define MANTIS_CMD_DATA_0 (0xff << 0)
|
||||
|
||||
#define MANTIS_CMD_DATA_R2 0x24
|
||||
#define MANTIS_CMD_DATA_7 (0xff << 24)
|
||||
#define MANTIS_CMD_DATA_6 (0xff << 16)
|
||||
#define MANTIS_CMD_DATA_5 (0xff << 8)
|
||||
#define MANTIS_CMD_DATA_4 (0xff << 0)
|
||||
|
||||
#define MANTIS_CONTROL 0x28
|
||||
#define MANTIS_DET (0x01 << 7)
|
||||
#define MANTIS_DAT_CF_EN (0x01 << 6)
|
||||
#define MANTIS_ACS (0x03 << 4)
|
||||
#define MANTIS_VCCEN (0x01 << 3)
|
||||
#define MANTIS_BYPASS (0x01 << 2)
|
||||
#define MANTIS_MRST (0x01 << 1)
|
||||
#define MANTIS_CRST_INT (0x01 << 0)
|
||||
|
||||
#define MANTIS_GPIF_CFGSLA 0x84
|
||||
#define MANTIS_GPIF_WAITSMPL (0x07 << 28)
|
||||
#define MANTIS_GPIF_BYTEADDRSUB (0x01 << 25)
|
||||
#define MANTIS_GPIF_WAITPOL (0x01 << 24)
|
||||
#define MANTIS_GPIF_NCDELAY (0x07 << 20)
|
||||
#define MANTIS_GPIF_RW2CSDELAY (0x07 << 16)
|
||||
#define MANTIS_GPIF_SLFTIMEDMODE (0x01 << 15)
|
||||
#define MANTIS_GPIF_SLFTIMEDDELY (0x7f << 8)
|
||||
#define MANTIS_GPIF_DEVTYPE (0x07 << 4)
|
||||
#define MANTIS_GPIF_BIGENDIAN (0x01 << 3)
|
||||
#define MANTIS_GPIF_FETCHCMD (0x03 << 1)
|
||||
#define MANTIS_GPIF_HWORDDEV (0x01 << 0)
|
||||
|
||||
#define MANTIS_GPIF_WSTOPER 0x90
|
||||
#define MANTIS_GPIF_WSTOPERWREN3 (0x01 << 31)
|
||||
#define MANTIS_GPIF_PARBOOTN (0x01 << 29)
|
||||
#define MANTIS_GPIF_WSTOPERSLID3 (0x1f << 24)
|
||||
#define MANTIS_GPIF_WSTOPERWREN2 (0x01 << 23)
|
||||
#define MANTIS_GPIF_WSTOPERSLID2 (0x1f << 16)
|
||||
#define MANTIS_GPIF_WSTOPERWREN1 (0x01 << 15)
|
||||
#define MANTIS_GPIF_WSTOPERSLID1 (0x1f << 8)
|
||||
#define MANTIS_GPIF_WSTOPERWREN0 (0x01 << 7)
|
||||
#define MANTIS_GPIF_WSTOPERSLID0 (0x1f << 0)
|
||||
|
||||
#define MANTIS_GPIF_CS2RW 0x94
|
||||
#define MANTIS_GPIF_CS2RWWREN3 (0x01 << 31)
|
||||
#define MANTIS_GPIF_CS2RWDELY3 (0x3f << 24)
|
||||
#define MANTIS_GPIF_CS2RWWREN2 (0x01 << 23)
|
||||
#define MANTIS_GPIF_CS2RWDELY2 (0x3f << 16)
|
||||
#define MANTIS_GPIF_CS2RWWREN1 (0x01 << 15)
|
||||
#define MANTIS_GPIF_CS2RWDELY1 (0x3f << 8)
|
||||
#define MANTIS_GPIF_CS2RWWREN0 (0x01 << 7)
|
||||
#define MANTIS_GPIF_CS2RWDELY0 (0x3f << 0)
|
||||
|
||||
#define MANTIS_GPIF_IRQCFG 0x98
|
||||
#define MANTIS_GPIF_IRQPOL (0x01 << 8)
|
||||
#define MANTIS_MASK_WRACK (0x01 << 7)
|
||||
#define MANTIS_MASK_BRRDY (0x01 << 6)
|
||||
#define MANTIS_MASK_OVFLW (0x01 << 5)
|
||||
#define MANTIS_MASK_OTHERR (0x01 << 4)
|
||||
#define MANTIS_MASK_WSTO (0x01 << 3)
|
||||
#define MANTIS_MASK_EXTIRQ (0x01 << 2)
|
||||
#define MANTIS_MASK_PLUGIN (0x01 << 1)
|
||||
#define MANTIS_MASK_PLUGOUT (0x01 << 0)
|
||||
|
||||
#define MANTIS_GPIF_STATUS 0x9c
|
||||
#define MANTIS_SBUF_KILLOP (0x01 << 15)
|
||||
#define MANTIS_SBUF_OPDONE (0x01 << 14)
|
||||
#define MANTIS_SBUF_EMPTY (0x01 << 13)
|
||||
#define MANTIS_GPIF_DETSTAT (0x01 << 9)
|
||||
#define MANTIS_GPIF_INTSTAT (0x01 << 8)
|
||||
#define MANTIS_GPIF_WRACK (0x01 << 7)
|
||||
#define MANTIS_GPIF_BRRDY (0x01 << 6)
|
||||
#define MANTIS_SBUF_OVFLW (0x01 << 5)
|
||||
#define MANTIS_GPIF_OTHERR (0x01 << 4)
|
||||
#define MANTIS_SBUF_WSTO (0x01 << 3)
|
||||
#define MANTIS_GPIF_EXTIRQ (0x01 << 2)
|
||||
#define MANTIS_CARD_PLUGIN (0x01 << 1)
|
||||
#define MANTIS_CARD_PLUGOUT (0x01 << 0)
|
||||
|
||||
#define MANTIS_GPIF_BRADDR 0xa0
|
||||
#define MANTIS_GPIF_PCMCIAREG (0x01 << 27)
|
||||
#define MANTIS_GPIF_PCMCIAIOM (0x01 << 26)
|
||||
#define MANTIS_GPIF_BR_ADDR (0xfffffff << 0)
|
||||
|
||||
#define MANTIS_GPIF_BRBYTES 0xa4
|
||||
#define MANTIS_GPIF_BRCNT (0xfff << 0)
|
||||
|
||||
#define MANTIS_PCMCIA_RESET 0xa8
|
||||
#define MANTIS_PCMCIA_RSTVAL (0xff << 0)
|
||||
|
||||
#define MANTIS_CARD_RESET 0xac
|
||||
|
||||
#define MANTIS_GPIF_ADDR 0xb0
|
||||
#define MANTIS_GPIF_HIFRDWRN (0x01 << 31)
|
||||
#define MANTIS_GPIF_PCMCIAREG (0x01 << 27)
|
||||
#define MANTIS_GPIF_PCMCIAIOM (0x01 << 26)
|
||||
#define MANTIS_GPIF_HIFADDR (0xfffffff << 0)
|
||||
|
||||
#define MANTIS_GPIF_DOUT 0xb4
|
||||
#define MANTIS_GPIF_HIFDOUT (0xfffffff << 0)
|
||||
|
||||
#define MANTIS_GPIF_DIN 0xb8
|
||||
#define MANTIS_GPIF_HIFDIN (0xfffffff << 0)
|
||||
|
||||
#define MANTIS_GPIF_SPARE 0xbc
|
||||
#define MANTIS_GPIF_LOGICRD (0xffff << 16)
|
||||
#define MANTIS_GPIF_LOGICRW (0xffff << 0)
|
||||
|
||||
#endif /* __MANTIS_REG_H */
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_reg.h"
|
||||
#include "mantis_uart.h"
|
||||
|
||||
struct mantis_uart_params {
|
||||
enum mantis_baud baud_rate;
|
||||
enum mantis_parity parity;
|
||||
};
|
||||
|
||||
static struct {
|
||||
char string[7];
|
||||
} rates[5] = {
|
||||
{ "9600" },
|
||||
{ "19200" },
|
||||
{ "38400" },
|
||||
{ "57600" },
|
||||
{ "115200" }
|
||||
};
|
||||
|
||||
static struct {
|
||||
char string[5];
|
||||
} parity[3] = {
|
||||
{ "NONE" },
|
||||
{ "ODD" },
|
||||
{ "EVEN" }
|
||||
};
|
||||
|
||||
#define UART_MAX_BUF 16
|
||||
|
||||
int mantis_uart_read(struct mantis_pci *mantis, u8 *data)
|
||||
{
|
||||
struct mantis_hwconfig *config = mantis->hwconfig;
|
||||
u32 stat = 0, i;
|
||||
|
||||
/* get data */
|
||||
for (i = 0; i < (config->bytes + 1); i++) {
|
||||
|
||||
stat = mmread(MANTIS_UART_STAT);
|
||||
|
||||
if (stat & MANTIS_UART_RXFIFO_FULL) {
|
||||
dprintk(MANTIS_ERROR, 1, "RX Fifo FULL");
|
||||
}
|
||||
data[i] = mmread(MANTIS_UART_RXD) & 0x3f;
|
||||
|
||||
dprintk(MANTIS_DEBUG, 1, "Reading ... <%02x>", data[i] & 0x3f);
|
||||
|
||||
if (data[i] & (1 << 7)) {
|
||||
dprintk(MANTIS_ERROR, 1, "UART framing error");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (data[i] & (1 << 6)) {
|
||||
dprintk(MANTIS_ERROR, 1, "UART parity error");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mantis_uart_work(struct work_struct *work)
|
||||
{
|
||||
struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work);
|
||||
struct mantis_hwconfig *config = mantis->hwconfig;
|
||||
u8 buf[16];
|
||||
int i;
|
||||
|
||||
mantis_uart_read(mantis, buf);
|
||||
|
||||
for (i = 0; i < (config->bytes + 1); i++)
|
||||
dprintk(MANTIS_INFO, 1, "UART BUF:%d <%02x> ", i, buf[i]);
|
||||
|
||||
dprintk(MANTIS_DEBUG, 0, "\n");
|
||||
}
|
||||
|
||||
static int mantis_uart_setup(struct mantis_pci *mantis,
|
||||
struct mantis_uart_params *params)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
mmwrite((mmread(MANTIS_UART_CTL) | (params->parity & 0x3)), MANTIS_UART_CTL);
|
||||
|
||||
reg = mmread(MANTIS_UART_BAUD);
|
||||
|
||||
switch (params->baud_rate) {
|
||||
case MANTIS_BAUD_9600:
|
||||
reg |= 0xd8;
|
||||
break;
|
||||
case MANTIS_BAUD_19200:
|
||||
reg |= 0x6c;
|
||||
break;
|
||||
case MANTIS_BAUD_38400:
|
||||
reg |= 0x36;
|
||||
break;
|
||||
case MANTIS_BAUD_57600:
|
||||
reg |= 0x23;
|
||||
break;
|
||||
case MANTIS_BAUD_115200:
|
||||
reg |= 0x11;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mmwrite(reg, MANTIS_UART_BAUD);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mantis_uart_init(struct mantis_pci *mantis)
|
||||
{
|
||||
struct mantis_hwconfig *config = mantis->hwconfig;
|
||||
struct mantis_uart_params params;
|
||||
|
||||
/* default parity: */
|
||||
params.baud_rate = config->baud_rate;
|
||||
params.parity = config->parity;
|
||||
dprintk(MANTIS_INFO, 1, "Initializing UART @ %sbps parity:%s",
|
||||
rates[params.baud_rate].string,
|
||||
parity[params.parity].string);
|
||||
|
||||
init_waitqueue_head(&mantis->uart_wq);
|
||||
spin_lock_init(&mantis->uart_lock);
|
||||
|
||||
INIT_WORK(&mantis->uart_work, mantis_uart_work);
|
||||
|
||||
/* disable interrupt */
|
||||
mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
|
||||
|
||||
mantis_uart_setup(mantis, ¶ms);
|
||||
|
||||
/* default 1 byte */
|
||||
mmwrite((mmread(MANTIS_UART_BAUD) | (config->bytes << 8)), MANTIS_UART_BAUD);
|
||||
|
||||
/* flush buffer */
|
||||
mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL);
|
||||
|
||||
/* enable interrupt */
|
||||
mmwrite(mmread(MANTIS_INT_MASK) | 0x800, MANTIS_INT_MASK);
|
||||
mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL);
|
||||
|
||||
schedule_work(&mantis->uart_work);
|
||||
dprintk(MANTIS_DEBUG, 1, "UART succesfully initialized");
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_uart_init);
|
||||
|
||||
void mantis_uart_exit(struct mantis_pci *mantis)
|
||||
{
|
||||
/* disable interrupt */
|
||||
mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(mantis_uart_exit);
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
Mantis PCI bridge driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_UART_H
|
||||
#define __MANTIS_UART_H
|
||||
|
||||
#define MANTIS_UART_CTL 0xe0
|
||||
#define MANTIS_UART_RXINT (1 << 4)
|
||||
#define MANTIS_UART_RXFLUSH (1 << 2)
|
||||
|
||||
#define MANTIS_UART_RXD 0xe8
|
||||
#define MANTIS_UART_BAUD 0xec
|
||||
|
||||
#define MANTIS_UART_STAT 0xf0
|
||||
#define MANTIS_UART_RXFIFO_DATA (1 << 7)
|
||||
#define MANTIS_UART_RXFIFO_EMPTY (1 << 6)
|
||||
#define MANTIS_UART_RXFIFO_FULL (1 << 3)
|
||||
#define MANTIS_UART_FRAME_ERR (1 << 2)
|
||||
#define MANTIS_UART_PARITY_ERR (1 << 1)
|
||||
#define MANTIS_UART_RXTHRESH_INT (1 << 0)
|
||||
|
||||
enum mantis_baud {
|
||||
MANTIS_BAUD_9600 = 0,
|
||||
MANTIS_BAUD_19200,
|
||||
MANTIS_BAUD_38400,
|
||||
MANTIS_BAUD_57600,
|
||||
MANTIS_BAUD_115200
|
||||
};
|
||||
|
||||
enum mantis_parity {
|
||||
MANTIS_PARITY_NONE = 0,
|
||||
MANTIS_PARITY_EVEN,
|
||||
MANTIS_PARITY_ODD,
|
||||
};
|
||||
|
||||
struct mantis_pci;
|
||||
|
||||
extern int mantis_uart_init(struct mantis_pci *mantis);
|
||||
extern void mantis_uart_exit(struct mantis_pci *mantis);
|
||||
|
||||
#endif /* __MANTIS_UART_H */
|
|
@ -0,0 +1,212 @@
|
|||
/*
|
||||
Mantis VP-1033 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "stv0299.h"
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_ioc.h"
|
||||
#include "mantis_dvb.h"
|
||||
#include "mantis_vp1033.h"
|
||||
#include "mantis_reg.h"
|
||||
|
||||
u8 lgtdqcs001f_inittab[] = {
|
||||
0x01, 0x15,
|
||||
0x02, 0x00,
|
||||
0x03, 0x00,
|
||||
0x04, 0x2a,
|
||||
0x05, 0x85,
|
||||
0x06, 0x02,
|
||||
0x07, 0x00,
|
||||
0x08, 0x00,
|
||||
0x0c, 0x01,
|
||||
0x0d, 0x81,
|
||||
0x0e, 0x44,
|
||||
0x0f, 0x94,
|
||||
0x10, 0x3c,
|
||||
0x11, 0x84,
|
||||
0x12, 0xb9,
|
||||
0x13, 0xb5,
|
||||
0x14, 0x4f,
|
||||
0x15, 0xc9,
|
||||
0x16, 0x80,
|
||||
0x17, 0x36,
|
||||
0x18, 0xfb,
|
||||
0x19, 0xcf,
|
||||
0x1a, 0xbc,
|
||||
0x1c, 0x2b,
|
||||
0x1d, 0x27,
|
||||
0x1e, 0x00,
|
||||
0x1f, 0x0b,
|
||||
0x20, 0xa1,
|
||||
0x21, 0x60,
|
||||
0x22, 0x00,
|
||||
0x23, 0x00,
|
||||
0x28, 0x00,
|
||||
0x29, 0x28,
|
||||
0x2a, 0x14,
|
||||
0x2b, 0x0f,
|
||||
0x2c, 0x09,
|
||||
0x2d, 0x05,
|
||||
0x31, 0x1f,
|
||||
0x32, 0x19,
|
||||
0x33, 0xfc,
|
||||
0x34, 0x13,
|
||||
0xff, 0xff,
|
||||
};
|
||||
|
||||
#define MANTIS_MODEL_NAME "VP-1033"
|
||||
#define MANTIS_DEV_TYPE "DVB-S/DSS"
|
||||
|
||||
int lgtdqcs001f_tuner_set(struct dvb_frontend *fe,
|
||||
struct dvb_frontend_parameters *params)
|
||||
{
|
||||
struct mantis_pci *mantis = fe->dvb->priv;
|
||||
struct i2c_adapter *adapter = &mantis->adapter;
|
||||
|
||||
u8 buf[4];
|
||||
u32 div;
|
||||
|
||||
|
||||
struct i2c_msg msg = {.addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf)};
|
||||
|
||||
div = params->frequency / 250;
|
||||
|
||||
buf[0] = (div >> 8) & 0x7f;
|
||||
buf[1] = div & 0xff;
|
||||
buf[2] = 0x83;
|
||||
buf[3] = 0xc0;
|
||||
|
||||
if (params->frequency < 1531000)
|
||||
buf[3] |= 0x04;
|
||||
else
|
||||
buf[3] &= ~0x04;
|
||||
if (i2c_transfer(adapter, &msg, 1) < 0) {
|
||||
dprintk(MANTIS_ERROR, 1, "Write: I2C Transfer failed");
|
||||
return -EIO;
|
||||
}
|
||||
msleep_interruptible(100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lgtdqcs001f_set_symbol_rate(struct dvb_frontend *fe,
|
||||
u32 srate, u32 ratio)
|
||||
{
|
||||
u8 aclk = 0;
|
||||
u8 bclk = 0;
|
||||
|
||||
if (srate < 1500000) {
|
||||
aclk = 0xb7;
|
||||
bclk = 0x47;
|
||||
} else if (srate < 3000000) {
|
||||
aclk = 0xb7;
|
||||
bclk = 0x4b;
|
||||
} else if (srate < 7000000) {
|
||||
aclk = 0xb7;
|
||||
bclk = 0x4f;
|
||||
} else if (srate < 14000000) {
|
||||
aclk = 0xb7;
|
||||
bclk = 0x53;
|
||||
} else if (srate < 30000000) {
|
||||
aclk = 0xb6;
|
||||
bclk = 0x53;
|
||||
} else if (srate < 45000000) {
|
||||
aclk = 0xb4;
|
||||
bclk = 0x51;
|
||||
}
|
||||
stv0299_writereg(fe, 0x13, aclk);
|
||||
stv0299_writereg(fe, 0x14, bclk);
|
||||
|
||||
stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
|
||||
stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
|
||||
stv0299_writereg(fe, 0x21, ratio & 0xf0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct stv0299_config lgtdqcs001f_config = {
|
||||
.demod_address = 0x68,
|
||||
.inittab = lgtdqcs001f_inittab,
|
||||
.mclk = 88000000UL,
|
||||
.invert = 0,
|
||||
.skip_reinit = 0,
|
||||
.volt13_op0_op1 = STV0299_VOLT13_OP0,
|
||||
.min_delay_ms = 100,
|
||||
.set_symbol_rate = lgtdqcs001f_set_symbol_rate,
|
||||
};
|
||||
|
||||
static int vp1033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
|
||||
{
|
||||
struct i2c_adapter *adapter = &mantis->adapter;
|
||||
|
||||
int err = 0;
|
||||
|
||||
err = mantis_frontend_power(mantis, POWER_ON);
|
||||
if (err == 0) {
|
||||
mantis_frontend_soft_reset(mantis);
|
||||
msleep(250);
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "Probing for STV0299 (DVB-S)");
|
||||
fe = stv0299_attach(&lgtdqcs001f_config, adapter);
|
||||
|
||||
if (fe) {
|
||||
fe->ops.tuner_ops.set_params = lgtdqcs001f_tuner_set;
|
||||
dprintk(MANTIS_ERROR, 1, "found STV0299 DVB-S frontend @ 0x%02x",
|
||||
lgtdqcs001f_config.demod_address);
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "Mantis DVB-S STV0299 frontend attach success");
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
|
||||
adapter->name,
|
||||
err);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
mantis->fe = fe;
|
||||
dprintk(MANTIS_ERROR, 1, "Done!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mantis_hwconfig vp1033_config = {
|
||||
.model_name = MANTIS_MODEL_NAME,
|
||||
.dev_type = MANTIS_DEV_TYPE,
|
||||
.ts_size = MANTIS_TS_204,
|
||||
|
||||
.baud_rate = MANTIS_BAUD_9600,
|
||||
.parity = MANTIS_PARITY_NONE,
|
||||
.bytes = 0,
|
||||
|
||||
.frontend_init = vp1033_frontend_init,
|
||||
.power = GPIF_A12,
|
||||
.reset = GPIF_A13,
|
||||
};
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Mantis VP-1033 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_VP1033_H
|
||||
#define __MANTIS_VP1033_H
|
||||
|
||||
#include "mantis_common.h"
|
||||
|
||||
#define MANTIS_VP_1033_DVB_S 0x0016
|
||||
|
||||
extern struct mantis_hwconfig vp1033_config;
|
||||
|
||||
#endif /* __MANTIS_VP1033_H */
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
Mantis VP-1034 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "mb86a16.h"
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_ioc.h"
|
||||
#include "mantis_dvb.h"
|
||||
#include "mantis_vp1034.h"
|
||||
#include "mantis_reg.h"
|
||||
|
||||
struct mb86a16_config vp1034_mb86a16_config = {
|
||||
.demod_address = 0x08,
|
||||
.set_voltage = vp1034_set_voltage,
|
||||
};
|
||||
|
||||
#define MANTIS_MODEL_NAME "VP-1034"
|
||||
#define MANTIS_DEV_TYPE "DVB-S/DSS"
|
||||
|
||||
int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
|
||||
{
|
||||
struct mantis_pci *mantis = fe->dvb->priv;
|
||||
|
||||
switch (voltage) {
|
||||
case SEC_VOLTAGE_13:
|
||||
dprintk(MANTIS_ERROR, 1, "Polarization=[13V]");
|
||||
gpio_set_bits(mantis, 13, 1);
|
||||
gpio_set_bits(mantis, 14, 0);
|
||||
break;
|
||||
case SEC_VOLTAGE_18:
|
||||
dprintk(MANTIS_ERROR, 1, "Polarization=[18V]");
|
||||
gpio_set_bits(mantis, 13, 1);
|
||||
gpio_set_bits(mantis, 14, 1);
|
||||
break;
|
||||
case SEC_VOLTAGE_OFF:
|
||||
dprintk(MANTIS_ERROR, 1, "Frontend (dummy) POWERDOWN");
|
||||
break;
|
||||
default:
|
||||
dprintk(MANTIS_ERROR, 1, "Invalid = (%d)", (u32) voltage);
|
||||
return -EINVAL;
|
||||
}
|
||||
mmwrite(0x00, MANTIS_GPIF_DOUT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vp1034_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
|
||||
{
|
||||
struct i2c_adapter *adapter = &mantis->adapter;
|
||||
|
||||
int err = 0;
|
||||
|
||||
err = mantis_frontend_power(mantis, POWER_ON);
|
||||
if (err == 0) {
|
||||
mantis_frontend_soft_reset(mantis);
|
||||
msleep(250);
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "Probing for MB86A16 (DVB-S/DSS)");
|
||||
fe = mb86a16_attach(&vp1034_mb86a16_config, adapter);
|
||||
if (fe) {
|
||||
dprintk(MANTIS_ERROR, 1,
|
||||
"found MB86A16 DVB-S/DSS frontend @0x%02x",
|
||||
vp1034_mb86a16_config.demod_address);
|
||||
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
|
||||
adapter->name,
|
||||
err);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
mantis->fe = fe;
|
||||
dprintk(MANTIS_ERROR, 1, "Done!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mantis_hwconfig vp1034_config = {
|
||||
.model_name = MANTIS_MODEL_NAME,
|
||||
.dev_type = MANTIS_DEV_TYPE,
|
||||
.ts_size = MANTIS_TS_204,
|
||||
|
||||
.baud_rate = MANTIS_BAUD_9600,
|
||||
.parity = MANTIS_PARITY_NONE,
|
||||
.bytes = 0,
|
||||
|
||||
.frontend_init = vp1034_frontend_init,
|
||||
.power = GPIF_A12,
|
||||
.reset = GPIF_A13,
|
||||
};
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Mantis VP-1034 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_VP1034_H
|
||||
#define __MANTIS_VP1034_H
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
#include "mantis_common.h"
|
||||
|
||||
|
||||
#define MANTIS_VP_1034_DVB_S 0x0014
|
||||
|
||||
extern struct mantis_hwconfig vp1034_config;
|
||||
extern int vp1034_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage);
|
||||
|
||||
#endif /* __MANTIS_VP1034_H */
|
|
@ -0,0 +1,358 @@
|
|||
/*
|
||||
Mantis VP-1041 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_ioc.h"
|
||||
#include "mantis_dvb.h"
|
||||
#include "mantis_vp1041.h"
|
||||
#include "stb0899_reg.h"
|
||||
#include "stb0899_drv.h"
|
||||
#include "stb0899_cfg.h"
|
||||
#include "stb6100_cfg.h"
|
||||
#include "stb6100.h"
|
||||
#include "lnbp21.h"
|
||||
|
||||
#define MANTIS_MODEL_NAME "VP-1041"
|
||||
#define MANTIS_DEV_TYPE "DSS/DVB-S/DVB-S2"
|
||||
|
||||
static const struct stb0899_s1_reg vp1041_stb0899_s1_init_1[] = {
|
||||
|
||||
/* 0x0000000b, *//* SYSREG */
|
||||
{ STB0899_DEV_ID , 0x30 },
|
||||
{ STB0899_DISCNTRL1 , 0x32 },
|
||||
{ STB0899_DISCNTRL2 , 0x80 },
|
||||
{ STB0899_DISRX_ST0 , 0x04 },
|
||||
{ STB0899_DISRX_ST1 , 0x00 },
|
||||
{ STB0899_DISPARITY , 0x00 },
|
||||
{ STB0899_DISFIFO , 0x00 },
|
||||
{ STB0899_DISSTATUS , 0x20 },
|
||||
{ STB0899_DISF22 , 0x99 },
|
||||
{ STB0899_DISF22RX , 0xa8 },
|
||||
/* SYSREG ? */
|
||||
{ STB0899_ACRPRESC , 0x11 },
|
||||
{ STB0899_ACRDIV1 , 0x0a },
|
||||
{ STB0899_ACRDIV2 , 0x05 },
|
||||
{ STB0899_DACR1 , 0x00 },
|
||||
{ STB0899_DACR2 , 0x00 },
|
||||
{ STB0899_OUTCFG , 0x00 },
|
||||
{ STB0899_MODECFG , 0x00 },
|
||||
{ STB0899_IRQSTATUS_3 , 0xfe },
|
||||
{ STB0899_IRQSTATUS_2 , 0x03 },
|
||||
{ STB0899_IRQSTATUS_1 , 0x7c },
|
||||
{ STB0899_IRQSTATUS_0 , 0xf4 },
|
||||
{ STB0899_IRQMSK_3 , 0xf3 },
|
||||
{ STB0899_IRQMSK_2 , 0xfc },
|
||||
{ STB0899_IRQMSK_1 , 0xff },
|
||||
{ STB0899_IRQMSK_0 , 0xff },
|
||||
{ STB0899_IRQCFG , 0x00 },
|
||||
{ STB0899_I2CCFG , 0x88 },
|
||||
{ STB0899_I2CRPT , 0x58 },
|
||||
{ STB0899_IOPVALUE5 , 0x00 },
|
||||
{ STB0899_IOPVALUE4 , 0x33 },
|
||||
{ STB0899_IOPVALUE3 , 0x6d },
|
||||
{ STB0899_IOPVALUE2 , 0x90 },
|
||||
{ STB0899_IOPVALUE1 , 0x60 },
|
||||
{ STB0899_IOPVALUE0 , 0x00 },
|
||||
{ STB0899_GPIO00CFG , 0x82 },
|
||||
{ STB0899_GPIO01CFG , 0x82 },
|
||||
{ STB0899_GPIO02CFG , 0x82 },
|
||||
{ STB0899_GPIO03CFG , 0x82 },
|
||||
{ STB0899_GPIO04CFG , 0x82 },
|
||||
{ STB0899_GPIO05CFG , 0x82 },
|
||||
{ STB0899_GPIO06CFG , 0x82 },
|
||||
{ STB0899_GPIO07CFG , 0x82 },
|
||||
{ STB0899_GPIO08CFG , 0x82 },
|
||||
{ STB0899_GPIO09CFG , 0x82 },
|
||||
{ STB0899_GPIO10CFG , 0x82 },
|
||||
{ STB0899_GPIO11CFG , 0x82 },
|
||||
{ STB0899_GPIO12CFG , 0x82 },
|
||||
{ STB0899_GPIO13CFG , 0x82 },
|
||||
{ STB0899_GPIO14CFG , 0x82 },
|
||||
{ STB0899_GPIO15CFG , 0x82 },
|
||||
{ STB0899_GPIO16CFG , 0x82 },
|
||||
{ STB0899_GPIO17CFG , 0x82 },
|
||||
{ STB0899_GPIO18CFG , 0x82 },
|
||||
{ STB0899_GPIO19CFG , 0x82 },
|
||||
{ STB0899_GPIO20CFG , 0x82 },
|
||||
{ STB0899_SDATCFG , 0xb8 },
|
||||
{ STB0899_SCLTCFG , 0xba },
|
||||
{ STB0899_AGCRFCFG , 0x1c }, /* 0x11 */
|
||||
{ STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
|
||||
{ STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
|
||||
{ STB0899_DIRCLKCFG , 0x82 },
|
||||
{ STB0899_CLKOUT27CFG , 0x7e },
|
||||
{ STB0899_STDBYCFG , 0x82 },
|
||||
{ STB0899_CS0CFG , 0x82 },
|
||||
{ STB0899_CS1CFG , 0x82 },
|
||||
{ STB0899_DISEQCOCFG , 0x20 },
|
||||
{ STB0899_GPIO32CFG , 0x82 },
|
||||
{ STB0899_GPIO33CFG , 0x82 },
|
||||
{ STB0899_GPIO34CFG , 0x82 },
|
||||
{ STB0899_GPIO35CFG , 0x82 },
|
||||
{ STB0899_GPIO36CFG , 0x82 },
|
||||
{ STB0899_GPIO37CFG , 0x82 },
|
||||
{ STB0899_GPIO38CFG , 0x82 },
|
||||
{ STB0899_GPIO39CFG , 0x82 },
|
||||
{ STB0899_NCOARSE , 0x17 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
|
||||
{ STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
|
||||
{ STB0899_FILTCTRL , 0x00 },
|
||||
{ STB0899_SYSCTRL , 0x01 },
|
||||
{ STB0899_STOPCLK1 , 0x20 },
|
||||
{ STB0899_STOPCLK2 , 0x00 },
|
||||
{ STB0899_INTBUFSTATUS , 0x00 },
|
||||
{ STB0899_INTBUFCTRL , 0x0a },
|
||||
{ 0xffff , 0xff },
|
||||
};
|
||||
|
||||
static const struct stb0899_s1_reg vp1041_stb0899_s1_init_3[] = {
|
||||
{ STB0899_DEMOD , 0x00 },
|
||||
{ STB0899_RCOMPC , 0xc9 },
|
||||
{ STB0899_AGC1CN , 0x01 },
|
||||
{ STB0899_AGC1REF , 0x10 },
|
||||
{ STB0899_RTC , 0x23 },
|
||||
{ STB0899_TMGCFG , 0x4e },
|
||||
{ STB0899_AGC2REF , 0x34 },
|
||||
{ STB0899_TLSR , 0x84 },
|
||||
{ STB0899_CFD , 0xf7 },
|
||||
{ STB0899_ACLC , 0x87 },
|
||||
{ STB0899_BCLC , 0x94 },
|
||||
{ STB0899_EQON , 0x41 },
|
||||
{ STB0899_LDT , 0xf1 },
|
||||
{ STB0899_LDT2 , 0xe3 },
|
||||
{ STB0899_EQUALREF , 0xb4 },
|
||||
{ STB0899_TMGRAMP , 0x10 },
|
||||
{ STB0899_TMGTHD , 0x30 },
|
||||
{ STB0899_IDCCOMP , 0xfd },
|
||||
{ STB0899_QDCCOMP , 0xff },
|
||||
{ STB0899_POWERI , 0x0c },
|
||||
{ STB0899_POWERQ , 0x0f },
|
||||
{ STB0899_RCOMP , 0x6c },
|
||||
{ STB0899_AGCIQIN , 0x80 },
|
||||
{ STB0899_AGC2I1 , 0x06 },
|
||||
{ STB0899_AGC2I2 , 0x00 },
|
||||
{ STB0899_TLIR , 0x30 },
|
||||
{ STB0899_RTF , 0x7f },
|
||||
{ STB0899_DSTATUS , 0x00 },
|
||||
{ STB0899_LDI , 0xbc },
|
||||
{ STB0899_CFRM , 0xea },
|
||||
{ STB0899_CFRL , 0x31 },
|
||||
{ STB0899_NIRM , 0x2b },
|
||||
{ STB0899_NIRL , 0x80 },
|
||||
{ STB0899_ISYMB , 0x1d },
|
||||
{ STB0899_QSYMB , 0xa6 },
|
||||
{ STB0899_SFRH , 0x2f },
|
||||
{ STB0899_SFRM , 0x68 },
|
||||
{ STB0899_SFRL , 0x40 },
|
||||
{ STB0899_SFRUPH , 0x2f },
|
||||
{ STB0899_SFRUPM , 0x68 },
|
||||
{ STB0899_SFRUPL , 0x40 },
|
||||
{ STB0899_EQUAI1 , 0x02 },
|
||||
{ STB0899_EQUAQ1 , 0xff },
|
||||
{ STB0899_EQUAI2 , 0x04 },
|
||||
{ STB0899_EQUAQ2 , 0x05 },
|
||||
{ STB0899_EQUAI3 , 0x02 },
|
||||
{ STB0899_EQUAQ3 , 0xfd },
|
||||
{ STB0899_EQUAI4 , 0x03 },
|
||||
{ STB0899_EQUAQ4 , 0x07 },
|
||||
{ STB0899_EQUAI5 , 0x08 },
|
||||
{ STB0899_EQUAQ5 , 0xf5 },
|
||||
{ STB0899_DSTATUS2 , 0x00 },
|
||||
{ STB0899_VSTATUS , 0x00 },
|
||||
{ STB0899_VERROR , 0x86 },
|
||||
{ STB0899_IQSWAP , 0x2a },
|
||||
{ STB0899_ECNT1M , 0x00 },
|
||||
{ STB0899_ECNT1L , 0x00 },
|
||||
{ STB0899_ECNT2M , 0x00 },
|
||||
{ STB0899_ECNT2L , 0x00 },
|
||||
{ STB0899_ECNT3M , 0x0a },
|
||||
{ STB0899_ECNT3L , 0xad },
|
||||
{ STB0899_FECAUTO1 , 0x06 },
|
||||
{ STB0899_FECM , 0x01 },
|
||||
{ STB0899_VTH12 , 0xb0 },
|
||||
{ STB0899_VTH23 , 0x7a },
|
||||
{ STB0899_VTH34 , 0x58 },
|
||||
{ STB0899_VTH56 , 0x38 },
|
||||
{ STB0899_VTH67 , 0x34 },
|
||||
{ STB0899_VTH78 , 0x24 },
|
||||
{ STB0899_PRVIT , 0xff },
|
||||
{ STB0899_VITSYNC , 0x19 },
|
||||
{ STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
|
||||
{ STB0899_TSULC , 0x42 },
|
||||
{ STB0899_RSLLC , 0x41 },
|
||||
{ STB0899_TSLPL , 0x12 },
|
||||
{ STB0899_TSCFGH , 0x0c },
|
||||
{ STB0899_TSCFGM , 0x00 },
|
||||
{ STB0899_TSCFGL , 0x00 },
|
||||
{ STB0899_TSOUT , 0x69 }, /* 0x0d for CAM */
|
||||
{ STB0899_RSSYNCDEL , 0x00 },
|
||||
{ STB0899_TSINHDELH , 0x02 },
|
||||
{ STB0899_TSINHDELM , 0x00 },
|
||||
{ STB0899_TSINHDELL , 0x00 },
|
||||
{ STB0899_TSLLSTKM , 0x1b },
|
||||
{ STB0899_TSLLSTKL , 0xb3 },
|
||||
{ STB0899_TSULSTKM , 0x00 },
|
||||
{ STB0899_TSULSTKL , 0x00 },
|
||||
{ STB0899_PCKLENUL , 0xbc },
|
||||
{ STB0899_PCKLENLL , 0xcc },
|
||||
{ STB0899_RSPCKLEN , 0xbd },
|
||||
{ STB0899_TSSTATUS , 0x90 },
|
||||
{ STB0899_ERRCTRL1 , 0xb6 },
|
||||
{ STB0899_ERRCTRL2 , 0x95 },
|
||||
{ STB0899_ERRCTRL3 , 0x8d },
|
||||
{ STB0899_DMONMSK1 , 0x27 },
|
||||
{ STB0899_DMONMSK0 , 0x03 },
|
||||
{ STB0899_DEMAPVIT , 0x5c },
|
||||
{ STB0899_PLPARM , 0x19 },
|
||||
{ STB0899_PDELCTRL , 0x48 },
|
||||
{ STB0899_PDELCTRL2 , 0x00 },
|
||||
{ STB0899_BBHCTRL1 , 0x00 },
|
||||
{ STB0899_BBHCTRL2 , 0x00 },
|
||||
{ STB0899_HYSTTHRESH , 0x77 },
|
||||
{ STB0899_MATCSTM , 0x00 },
|
||||
{ STB0899_MATCSTL , 0x00 },
|
||||
{ STB0899_UPLCSTM , 0x00 },
|
||||
{ STB0899_UPLCSTL , 0x00 },
|
||||
{ STB0899_DFLCSTM , 0x00 },
|
||||
{ STB0899_DFLCSTL , 0x00 },
|
||||
{ STB0899_SYNCCST , 0x00 },
|
||||
{ STB0899_SYNCDCSTM , 0x00 },
|
||||
{ STB0899_SYNCDCSTL , 0x00 },
|
||||
{ STB0899_ISI_ENTRY , 0x00 },
|
||||
{ STB0899_ISI_BIT_EN , 0x00 },
|
||||
{ STB0899_MATSTRM , 0xf0 },
|
||||
{ STB0899_MATSTRL , 0x02 },
|
||||
{ STB0899_UPLSTRM , 0x45 },
|
||||
{ STB0899_UPLSTRL , 0x60 },
|
||||
{ STB0899_DFLSTRM , 0xe3 },
|
||||
{ STB0899_DFLSTRL , 0x00 },
|
||||
{ STB0899_SYNCSTR , 0x47 },
|
||||
{ STB0899_SYNCDSTRM , 0x05 },
|
||||
{ STB0899_SYNCDSTRL , 0x18 },
|
||||
{ STB0899_CFGPDELSTATUS1 , 0x19 },
|
||||
{ STB0899_CFGPDELSTATUS2 , 0x2b },
|
||||
{ STB0899_BBFERRORM , 0x00 },
|
||||
{ STB0899_BBFERRORL , 0x01 },
|
||||
{ STB0899_UPKTERRORM , 0x00 },
|
||||
{ STB0899_UPKTERRORL , 0x00 },
|
||||
{ 0xffff , 0xff },
|
||||
};
|
||||
|
||||
struct stb0899_config vp1041_stb0899_config = {
|
||||
.init_dev = vp1041_stb0899_s1_init_1,
|
||||
.init_s2_demod = stb0899_s2_init_2,
|
||||
.init_s1_demod = vp1041_stb0899_s1_init_3,
|
||||
.init_s2_fec = stb0899_s2_init_4,
|
||||
.init_tst = stb0899_s1_init_5,
|
||||
|
||||
.demod_address = 0x68, /* 0xd0 >> 1 */
|
||||
|
||||
.xtal_freq = 27000000,
|
||||
.inversion = IQ_SWAP_ON, /* 1 */
|
||||
|
||||
.lo_clk = 76500000,
|
||||
.hi_clk = 99000000,
|
||||
|
||||
.esno_ave = STB0899_DVBS2_ESNO_AVE,
|
||||
.esno_quant = STB0899_DVBS2_ESNO_QUANT,
|
||||
.avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
|
||||
.avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
|
||||
.miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
|
||||
.uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
|
||||
.uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
|
||||
.uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
|
||||
.sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
|
||||
|
||||
.btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
|
||||
.btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
|
||||
.crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
|
||||
.ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
|
||||
|
||||
.tuner_get_frequency = stb6100_get_frequency,
|
||||
.tuner_set_frequency = stb6100_set_frequency,
|
||||
.tuner_set_bandwidth = stb6100_set_bandwidth,
|
||||
.tuner_get_bandwidth = stb6100_get_bandwidth,
|
||||
.tuner_set_rfsiggain = NULL,
|
||||
};
|
||||
|
||||
struct stb6100_config vp1041_stb6100_config = {
|
||||
.tuner_address = 0x60,
|
||||
.refclock = 27000000,
|
||||
};
|
||||
|
||||
static int vp1041_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
|
||||
{
|
||||
struct i2c_adapter *adapter = &mantis->adapter;
|
||||
|
||||
int err = 0;
|
||||
|
||||
err = mantis_frontend_power(mantis, POWER_ON);
|
||||
if (err == 0) {
|
||||
mantis_frontend_soft_reset(mantis);
|
||||
msleep(250);
|
||||
mantis->fe = stb0899_attach(&vp1041_stb0899_config, adapter);
|
||||
if (mantis->fe) {
|
||||
dprintk(MANTIS_ERROR, 1,
|
||||
"found STB0899 DVB-S/DVB-S2 frontend @0x%02x",
|
||||
vp1041_stb0899_config.demod_address);
|
||||
|
||||
if (stb6100_attach(mantis->fe, &vp1041_stb6100_config, adapter)) {
|
||||
if (!lnbp21_attach(mantis->fe, adapter, 0, 0))
|
||||
dprintk(MANTIS_ERROR, 1, "No LNBP21 found!");
|
||||
}
|
||||
} else {
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
} else {
|
||||
dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
|
||||
adapter->name,
|
||||
err);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "Done!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mantis_hwconfig vp1041_config = {
|
||||
.model_name = MANTIS_MODEL_NAME,
|
||||
.dev_type = MANTIS_DEV_TYPE,
|
||||
.ts_size = MANTIS_TS_188,
|
||||
|
||||
.baud_rate = MANTIS_BAUD_9600,
|
||||
.parity = MANTIS_PARITY_NONE,
|
||||
.bytes = 0,
|
||||
|
||||
.frontend_init = vp1041_frontend_init,
|
||||
.power = GPIF_A12,
|
||||
.reset = GPIF_A13,
|
||||
};
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Mantis VP-1041 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_VP1041_H
|
||||
#define __MANTIS_VP1041_H
|
||||
|
||||
#include "mantis_common.h"
|
||||
|
||||
#define MANTIS_VP_1041_DVB_S2 0x0031
|
||||
#define SKYSTAR_HD2_10 0x0001
|
||||
#define SKYSTAR_HD2_20 0x0003
|
||||
#define CINERGY_S2_PCI_HD 0x1179
|
||||
|
||||
extern struct mantis_hwconfig vp1041_config;
|
||||
|
||||
#endif /* __MANTIS_VP1041_H */
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
Mantis VP-2033 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "tda1002x.h"
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_ioc.h"
|
||||
#include "mantis_dvb.h"
|
||||
#include "mantis_vp2033.h"
|
||||
|
||||
#define MANTIS_MODEL_NAME "VP-2033"
|
||||
#define MANTIS_DEV_TYPE "DVB-C"
|
||||
|
||||
struct tda1002x_config vp2033_tda1002x_cu1216_config = {
|
||||
.demod_address = 0x18 >> 1,
|
||||
.invert = 1,
|
||||
};
|
||||
|
||||
struct tda10023_config vp2033_tda10023_cu1216_config = {
|
||||
.demod_address = 0x18 >> 1,
|
||||
.invert = 1,
|
||||
};
|
||||
|
||||
static u8 read_pwm(struct mantis_pci *mantis)
|
||||
{
|
||||
struct i2c_adapter *adapter = &mantis->adapter;
|
||||
|
||||
u8 b = 0xff;
|
||||
u8 pwm;
|
||||
struct i2c_msg msg[] = {
|
||||
{.addr = 0x50, .flags = 0, .buf = &b, .len = 1},
|
||||
{.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1}
|
||||
};
|
||||
|
||||
if ((i2c_transfer(adapter, msg, 2) != 2)
|
||||
|| (pwm == 0xff))
|
||||
pwm = 0x48;
|
||||
|
||||
return pwm;
|
||||
}
|
||||
|
||||
static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
|
||||
{
|
||||
struct mantis_pci *mantis = fe->dvb->priv;
|
||||
struct i2c_adapter *adapter = &mantis->adapter;
|
||||
|
||||
u8 buf[6];
|
||||
struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)};
|
||||
int i;
|
||||
|
||||
#define CU1216_IF 36125000
|
||||
#define TUNER_MUL 62500
|
||||
|
||||
u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
|
||||
|
||||
buf[0] = (div >> 8) & 0x7f;
|
||||
buf[1] = div & 0xff;
|
||||
buf[2] = 0xce;
|
||||
buf[3] = (params->frequency < 150000000 ? 0x01 :
|
||||
params->frequency < 445000000 ? 0x02 : 0x04);
|
||||
buf[4] = 0xde;
|
||||
buf[5] = 0x20;
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
|
||||
if (i2c_transfer(adapter, &msg, 1) != 1)
|
||||
return -EIO;
|
||||
|
||||
/* wait for the pll lock */
|
||||
msg.flags = I2C_M_RD;
|
||||
msg.len = 1;
|
||||
for (i = 0; i < 20; i++) {
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
|
||||
if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40))
|
||||
break;
|
||||
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
/* switch the charge pump to the lower current */
|
||||
msg.flags = 0;
|
||||
msg.len = 2;
|
||||
msg.buf = &buf[2];
|
||||
buf[2] &= ~0x40;
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
|
||||
if (i2c_transfer(adapter, &msg, 1) != 1)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vp2033_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
|
||||
{
|
||||
struct i2c_adapter *adapter = &mantis->adapter;
|
||||
|
||||
int err = 0;
|
||||
|
||||
err = mantis_frontend_power(mantis, POWER_ON);
|
||||
if (err == 0) {
|
||||
mantis_frontend_soft_reset(mantis);
|
||||
msleep(250);
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
|
||||
fe = tda10021_attach(&vp2033_tda1002x_cu1216_config,
|
||||
adapter,
|
||||
read_pwm(mantis));
|
||||
|
||||
if (fe) {
|
||||
dprintk(MANTIS_ERROR, 1,
|
||||
"found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
|
||||
vp2033_tda1002x_cu1216_config.demod_address);
|
||||
} else {
|
||||
fe = tda10023_attach(&vp2033_tda10023_cu1216_config,
|
||||
adapter,
|
||||
read_pwm(mantis));
|
||||
|
||||
if (fe) {
|
||||
dprintk(MANTIS_ERROR, 1,
|
||||
"found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x",
|
||||
vp2033_tda1002x_cu1216_config.demod_address);
|
||||
}
|
||||
}
|
||||
|
||||
if (fe) {
|
||||
fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set;
|
||||
dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success");
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
|
||||
adapter->name,
|
||||
err);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
mantis->fe = fe;
|
||||
dprintk(MANTIS_DEBUG, 1, "Done!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mantis_hwconfig vp2033_config = {
|
||||
.model_name = MANTIS_MODEL_NAME,
|
||||
.dev_type = MANTIS_DEV_TYPE,
|
||||
.ts_size = MANTIS_TS_204,
|
||||
|
||||
.baud_rate = MANTIS_BAUD_9600,
|
||||
.parity = MANTIS_PARITY_NONE,
|
||||
.bytes = 0,
|
||||
|
||||
.frontend_init = vp2033_frontend_init,
|
||||
.power = GPIF_A12,
|
||||
.reset = GPIF_A13,
|
||||
};
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Mantis VP-2033 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_VP2033_H
|
||||
#define __MANTIS_VP2033_H
|
||||
|
||||
#include "mantis_common.h"
|
||||
|
||||
#define MANTIS_VP_2033_DVB_C 0x0008
|
||||
|
||||
extern struct mantis_hwconfig vp2033_config;
|
||||
|
||||
#endif /* __MANTIS_VP2033_H */
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
Mantis VP-2040 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "tda1002x.h"
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_ioc.h"
|
||||
#include "mantis_dvb.h"
|
||||
#include "mantis_vp2040.h"
|
||||
|
||||
#define MANTIS_MODEL_NAME "VP-2040"
|
||||
#define MANTIS_DEV_TYPE "DVB-C"
|
||||
|
||||
struct tda1002x_config vp2040_tda1002x_cu1216_config = {
|
||||
.demod_address = 0x18 >> 1,
|
||||
.invert = 1,
|
||||
};
|
||||
|
||||
struct tda10023_config vp2040_tda10023_cu1216_config = {
|
||||
.demod_address = 0x18 >> 1,
|
||||
.invert = 1,
|
||||
};
|
||||
|
||||
static int tda1002x_cu1216_tuner_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
|
||||
{
|
||||
struct mantis_pci *mantis = fe->dvb->priv;
|
||||
struct i2c_adapter *adapter = &mantis->adapter;
|
||||
|
||||
u8 buf[6];
|
||||
struct i2c_msg msg = {.addr = 0x60, .flags = 0, .buf = buf, .len = sizeof(buf)};
|
||||
int i;
|
||||
|
||||
#define CU1216_IF 36125000
|
||||
#define TUNER_MUL 62500
|
||||
|
||||
u32 div = (params->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
|
||||
|
||||
buf[0] = (div >> 8) & 0x7f;
|
||||
buf[1] = div & 0xff;
|
||||
buf[2] = 0xce;
|
||||
buf[3] = (params->frequency < 150000000 ? 0x01 :
|
||||
params->frequency < 445000000 ? 0x02 : 0x04);
|
||||
buf[4] = 0xde;
|
||||
buf[5] = 0x20;
|
||||
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
|
||||
if (i2c_transfer(adapter, &msg, 1) != 1)
|
||||
return -EIO;
|
||||
|
||||
/* wait for the pll lock */
|
||||
msg.flags = I2C_M_RD;
|
||||
msg.len = 1;
|
||||
for (i = 0; i < 20; i++) {
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
|
||||
if (i2c_transfer(adapter, &msg, 1) == 1 && (buf[0] & 0x40))
|
||||
break;
|
||||
|
||||
msleep(10);
|
||||
}
|
||||
|
||||
/* switch the charge pump to the lower current */
|
||||
msg.flags = 0;
|
||||
msg.len = 2;
|
||||
msg.buf = &buf[2];
|
||||
buf[2] &= ~0x40;
|
||||
if (fe->ops.i2c_gate_ctrl)
|
||||
fe->ops.i2c_gate_ctrl(fe, 1);
|
||||
|
||||
if (i2c_transfer(adapter, &msg, 1) != 1)
|
||||
return -EIO;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static u8 read_pwm(struct mantis_pci *mantis)
|
||||
{
|
||||
struct i2c_adapter *adapter = &mantis->adapter;
|
||||
|
||||
u8 b = 0xff;
|
||||
u8 pwm;
|
||||
struct i2c_msg msg[] = {
|
||||
{.addr = 0x50, .flags = 0, .buf = &b, .len = 1},
|
||||
{.addr = 0x50, .flags = I2C_M_RD, .buf = &pwm, .len = 1}
|
||||
};
|
||||
|
||||
if ((i2c_transfer(adapter, msg, 2) != 2)
|
||||
|| (pwm == 0xff))
|
||||
pwm = 0x48;
|
||||
|
||||
return pwm;
|
||||
}
|
||||
|
||||
static int vp2040_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
|
||||
{
|
||||
struct i2c_adapter *adapter = &mantis->adapter;
|
||||
|
||||
int err = 0;
|
||||
|
||||
err = mantis_frontend_power(mantis, POWER_ON);
|
||||
if (err == 0) {
|
||||
mantis_frontend_soft_reset(mantis);
|
||||
msleep(250);
|
||||
|
||||
dprintk(MANTIS_ERROR, 1, "Probing for CU1216 (DVB-C)");
|
||||
fe = tda10021_attach(&vp2040_tda1002x_cu1216_config,
|
||||
adapter,
|
||||
read_pwm(mantis));
|
||||
|
||||
if (fe) {
|
||||
dprintk(MANTIS_ERROR, 1,
|
||||
"found Philips CU1216 DVB-C frontend (TDA10021) @ 0x%02x",
|
||||
vp2040_tda1002x_cu1216_config.demod_address);
|
||||
} else {
|
||||
fe = tda10023_attach(&vp2040_tda10023_cu1216_config,
|
||||
adapter,
|
||||
read_pwm(mantis));
|
||||
|
||||
if (fe) {
|
||||
dprintk(MANTIS_ERROR, 1,
|
||||
"found Philips CU1216 DVB-C frontend (TDA10023) @ 0x%02x",
|
||||
vp2040_tda1002x_cu1216_config.demod_address);
|
||||
}
|
||||
}
|
||||
|
||||
if (fe) {
|
||||
fe->ops.tuner_ops.set_params = tda1002x_cu1216_tuner_set;
|
||||
dprintk(MANTIS_ERROR, 1, "Mantis DVB-C Philips CU1216 frontend attach success");
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
|
||||
adapter->name,
|
||||
err);
|
||||
|
||||
return -EIO;
|
||||
}
|
||||
mantis->fe = fe;
|
||||
dprintk(MANTIS_DEBUG, 1, "Done!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mantis_hwconfig vp2040_config = {
|
||||
.model_name = MANTIS_MODEL_NAME,
|
||||
.dev_type = MANTIS_DEV_TYPE,
|
||||
.ts_size = MANTIS_TS_204,
|
||||
|
||||
.baud_rate = MANTIS_BAUD_9600,
|
||||
.parity = MANTIS_PARITY_NONE,
|
||||
.bytes = 0,
|
||||
|
||||
.frontend_init = vp2040_frontend_init,
|
||||
.power = GPIF_A12,
|
||||
.reset = GPIF_A13,
|
||||
};
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
Mantis VP-2040 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_VP2040_H
|
||||
#define __MANTIS_VP2040_H
|
||||
|
||||
#include "mantis_common.h"
|
||||
|
||||
#define MANTIS_VP_2040_DVB_C 0x0043
|
||||
#define CINERGY_C 0x1178
|
||||
#define CABLESTAR_HD2 0x0002
|
||||
|
||||
extern struct mantis_hwconfig vp2040_config;
|
||||
|
||||
#endif /* __MANTIS_VP2040_H */
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
Mantis VP-3028 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_vp3028.h"
|
||||
|
||||
struct zl10353_config mantis_vp3028_config = {
|
||||
.demod_address = 0x0f,
|
||||
};
|
||||
|
||||
#define MANTIS_MODEL_NAME "VP-3028"
|
||||
#define MANTIS_DEV_TYPE "DVB-T"
|
||||
|
||||
struct mantis_hwconfig vp3028_mantis_config = {
|
||||
.model_name = MANTIS_MODEL_NAME,
|
||||
.dev_type = MANTIS_DEV_TYPE,
|
||||
.ts_size = MANTIS_TS_188,
|
||||
.baud_rate = MANTIS_BAUD_9600,
|
||||
.parity = MANTIS_PARITY_NONE,
|
||||
.bytes = 0,
|
||||
};
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
Mantis VP-3028 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_VP3028_H
|
||||
#define __MANTIS_VP3028_H
|
||||
|
||||
#include "dvb_frontend.h"
|
||||
#include "mantis_common.h"
|
||||
#include "zl10353.h"
|
||||
|
||||
#define MANTIS_VP_3028_DVB_T 0x0028
|
||||
|
||||
extern struct zl10353_config mantis_vp3028_config;
|
||||
extern struct mantis_hwconfig vp3028_mantis_config;
|
||||
|
||||
#endif /* __MANTIS_VP3028_H */
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
Mantis VP-3030 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <linux/signal.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include "dmxdev.h"
|
||||
#include "dvbdev.h"
|
||||
#include "dvb_demux.h"
|
||||
#include "dvb_frontend.h"
|
||||
#include "dvb_net.h"
|
||||
|
||||
#include "zl10353.h"
|
||||
#include "tda665x.h"
|
||||
#include "mantis_common.h"
|
||||
#include "mantis_ioc.h"
|
||||
#include "mantis_dvb.h"
|
||||
#include "mantis_vp3030.h"
|
||||
|
||||
struct zl10353_config mantis_vp3030_config = {
|
||||
.demod_address = 0x0f,
|
||||
};
|
||||
|
||||
struct tda665x_config env57h12d5_config = {
|
||||
.name = "ENV57H12D5 (ET-50DT)",
|
||||
.addr = 0x60,
|
||||
.frequency_min = 47000000,
|
||||
.frequency_max = 862000000,
|
||||
.frequency_offst = 3616667,
|
||||
.ref_multiplier = 6, /* 1/6 MHz */
|
||||
.ref_divider = 100000, /* 1/6 MHz */
|
||||
};
|
||||
|
||||
#define MANTIS_MODEL_NAME "VP-3030"
|
||||
#define MANTIS_DEV_TYPE "DVB-T"
|
||||
|
||||
|
||||
static int vp3030_frontend_init(struct mantis_pci *mantis, struct dvb_frontend *fe)
|
||||
{
|
||||
struct i2c_adapter *adapter = &mantis->adapter;
|
||||
struct mantis_hwconfig *config = mantis->hwconfig;
|
||||
int err = 0;
|
||||
|
||||
gpio_set_bits(mantis, config->reset, 0);
|
||||
msleep(100);
|
||||
err = mantis_frontend_power(mantis, POWER_ON);
|
||||
msleep(100);
|
||||
gpio_set_bits(mantis, config->reset, 1);
|
||||
|
||||
if (err == 0) {
|
||||
msleep(250);
|
||||
dprintk(MANTIS_ERROR, 1, "Probing for 10353 (DVB-T)");
|
||||
fe = zl10353_attach(&mantis_vp3030_config, adapter);
|
||||
|
||||
if (!fe)
|
||||
return -1;
|
||||
|
||||
tda665x_attach(fe, &env57h12d5_config, adapter);
|
||||
} else {
|
||||
dprintk(MANTIS_ERROR, 1, "Frontend on <%s> POWER ON failed! <%d>",
|
||||
adapter->name,
|
||||
err);
|
||||
|
||||
return -EIO;
|
||||
|
||||
}
|
||||
mantis->fe = fe;
|
||||
dprintk(MANTIS_ERROR, 1, "Done!");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mantis_hwconfig vp3030_config = {
|
||||
.model_name = MANTIS_MODEL_NAME,
|
||||
.dev_type = MANTIS_DEV_TYPE,
|
||||
.ts_size = MANTIS_TS_188,
|
||||
|
||||
.baud_rate = MANTIS_BAUD_9600,
|
||||
.parity = MANTIS_PARITY_NONE,
|
||||
.bytes = 0,
|
||||
|
||||
.frontend_init = vp3030_frontend_init,
|
||||
.power = GPIF_A12,
|
||||
.reset = GPIF_A13,
|
||||
|
||||
.i2c_mode = MANTIS_BYTE_MODE
|
||||
};
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
Mantis VP-3030 driver
|
||||
|
||||
Copyright (C) Manu Abraham (abraham.manu@gmail.com)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __MANTIS_VP3030_H
|
||||
#define __MANTIS_VP3030_H
|
||||
|
||||
#include "mantis_common.h"
|
||||
|
||||
#define MANTIS_VP_3030_DVB_T 0x0024
|
||||
|
||||
extern struct mantis_hwconfig vp3030_config;
|
||||
|
||||
#endif /* __MANTIS_VP3030_H */
|
Loading…
Reference in New Issue