summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Boettcher <devnull@localhost>2004-09-05 20:13:07 +0000
committerPatrick Boettcher <devnull@localhost>2004-09-05 20:13:07 +0000
commit58a6c6dc6a1cea3ba3a6a1c7a4cc0e36640f87e5 (patch)
tree755c293a3fb40cd07e028085a6d7a85130029282
parent71f6ea3ca21cf22dbb9b12cdc154fc653c11d5bd (diff)
downloadmediapointer-dvb-s2-58a6c6dc6a1cea3ba3a6a1c7a4cc0e36640f87e5.tar.gz
mediapointer-dvb-s2-58a6c6dc6a1cea3ba3a6a1c7a4cc0e36640f87e5.tar.bz2
added some more ioctl calls, modified the SET_FRONTED behaviour.
-rw-r--r--linux/drivers/media/dvb/frontends/dib3000mb.c272
-rw-r--r--linux/drivers/media/dvb/frontends/dib3000mb.h6
2 files changed, 232 insertions, 46 deletions
diff --git a/linux/drivers/media/dvb/frontends/dib3000mb.c b/linux/drivers/media/dvb/frontends/dib3000mb.c
index 05adffa1d..5e2276ef2 100644
--- a/linux/drivers/media/dvb/frontends/dib3000mb.c
+++ b/linux/drivers/media/dvb/frontends/dib3000mb.c
@@ -57,7 +57,8 @@ static struct dvb_frontend_info dib3000mb_info = {
.frequency_min = 44250000,
.frequency_max = 867250000,
.frequency_stepsize = 62500,
- .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ .caps = FE_CAN_INVERSION_AUTO |
+ FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
FE_CAN_TRANSMISSION_MODE_AUTO |
@@ -138,13 +139,18 @@ struct dib3000mb_fe_param {
u16 cr;
u16 inv;
u16 seq;
- u8 qam_vit_auto;
+ u8 qam_vit_manual;
};
static int dib3000mb_fe_set_parameters(struct dib3000mb_state *state,
struct dib3000mb_fe_param *p)
{
struct i2c_client *i2c = state->i2c;
+
+ wr(DIB3000MB_REG_LOCK1_MASK,DIB3000MB_LOCK1_SEARCH_4);
+
+ dprintk("inversion: %d, seq: %d\n",p->inv,p->seq);
+
wr(DIB3000MB_REG_FFT,p->fft);
wr(DIB3000MB_REG_GUARD_TIME,p->guard);
wr(DIB3000MB_REG_DDS_INV,p->inv);
@@ -165,7 +171,7 @@ static int dib3000mb_fe_set_parameters(struct dib3000mb_state *state,
wr(DIB3000MB_REG_UNK_121,DIB3000MB_UNK_121_DEFAULT);
}
- if (p->qam_vit_auto) {
+ if (p->qam_vit_manual) {
wr(DIB3000MB_REG_QAM,p->qam);
wr(DIB3000MB_REG_VIT_ALPHA,p->alpha);
wr(DIB3000MB_REG_VIT_HRCH,p->hrch);
@@ -189,25 +195,6 @@ static int dib3000mb_fe_read_search_status(struct dib3000mb_state *state)
irq = rd(DIB3000MB_REG_AS_IRQ_PENDING);
if (irq & 0x02) {
- if (rd(DIB3000MB_REG_TPS_LOCK)) {
- p.qam = rd(DIB3000MB_REG_TPS_QAM);
- p.hrch = rd(DIB3000MB_REG_TPS_HRCH);
- p.alpha = rd(DIB3000MB_REG_TPS_VIT_ALPHA);
- p.hp = !p.hrch;
- p.cr = p.hp ? rd(DIB3000MB_REG_TPS_CODE_RATE_HP) :
- rd(DIB3000MB_REG_TPS_CODE_RATE_LP);
- p.guard = rd(DIB3000MB_REG_TPS_GUARD_TIME);
- p.fft = rd(DIB3000MB_REG_TPS_FFT);
- p.seq = 0;
- p.qam_vit_auto = 0;
- p.inv = 1;
-
-// dib3000mb_fe_set_parameters(state,&p);
-
-// wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_CTRL);
-// wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_OFF);
- }
-
dprintk("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n",
rd(DIB3000MB_REG_TPS_LOCK),
rd(DIB3000MB_REG_TPS_QAM),
@@ -219,11 +206,51 @@ static int dib3000mb_fe_read_search_status(struct dib3000mb_state *state)
rd(DIB3000MB_REG_TPS_FFT),
rd(DIB3000MB_REG_TPS_CELL_ID));
- if (rd(DIB3000MB_REG_LOCK2_VALUE))
+ if (rd(DIB3000MB_REG_TPS_LOCK) && rd(DIB3000MB_REG_LOCK2_VALUE)) {
+ int inv_test1,inv_test2;
+ u32 dds_val, threshold = 0x800000;
+
+ p.qam = rd(DIB3000MB_REG_TPS_QAM);
+ p.hrch = rd(DIB3000MB_REG_TPS_HRCH);
+ p.alpha = rd(DIB3000MB_REG_TPS_VIT_ALPHA);
+ p.hp = !p.hrch;
+ p.cr = p.hp ? rd(DIB3000MB_REG_TPS_CODE_RATE_HP) :
+ rd(DIB3000MB_REG_TPS_CODE_RATE_LP);
+ p.guard = rd(DIB3000MB_REG_TPS_GUARD_TIME);
+ p.fft = rd(DIB3000MB_REG_TPS_FFT);
+ p.seq = 0;
+ p.qam_vit_manual = 0;
+
+ dds_val = (rd(DIB3000MB_REG_DDS_VALUE_MSB & 0xff) << 16) + rd(DIB3000MB_REG_DDS_VALUE_LSB);
+ if (dds_val & threshold)
+ inv_test1 = 0;
+ else if (dds_val == threshold)
+ inv_test1 = 1;
+ else
+ inv_test1 = 2;
+
+ dds_val = (rd(DIB3000MB_REG_DDS_FREQ_MSB & 0xff) << 16) + rd(DIB3000MB_REG_DDS_FREQ_LSB);
+ if (dds_val & threshold)
+ inv_test2 = 0;
+ else if (dds_val == threshold)
+ inv_test2 = 1;
+ else
+ inv_test2 = 2;
+
+ p.inv = ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0))
+ ||
+ ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2));
+
+ dib3000mb_fe_set_parameters(state,&p);
+
+ wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_CTRL);
+ wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_OFF);
+
+ msleep(70);
+
return 1;
- else
+ } else
return 0;
-
} else if (irq & 0x01)
return 0;
@@ -238,16 +265,10 @@ static int dib3000mb_set_frontend(struct dib3000mb_state *state,
fe_code_rate_t fe_cr;
struct dib3000mb_fe_param par;
- par.seq = dib3000mb_seq
- [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO]
- [ofdm->guard_interval == GUARD_INTERVAL_AUTO]
- [1];
-
- dprintk("Auto search will be enabled? %d\n",par.seq);
-
wr(DIB3000MB_REG_TUNER,
DIB3000MB_ACTIVATE_TUNER_XFER( DIB3000MB_TUNER_ADDR_DEFAULT ) );
dib3000mb_tuner_thomson_cable_eu(state,fep->frequency);
+
/* wait for tuner */
msleep(1);
wr(DIB3000MB_REG_TUNER,
@@ -273,8 +294,6 @@ static int dib3000mb_set_frontend(struct dib3000mb_state *state,
break;
}
- wr(DIB3000MB_REG_LOCK1_MASK, DIB3000MB_LOCK1_SEARCH_4);
-
switch (ofdm->transmission_mode) {
case TRANSMISSION_MODE_2K:
par.fft = DIB3000MB_FFT_2K;
@@ -309,12 +328,18 @@ static int dib3000mb_set_frontend(struct dib3000mb_state *state,
return -EINVAL;
}
- par.inv = DIB3000MB_DDS_INV_OFF;
-
- par.qam_vit_auto = (ofdm->constellation != QAM_AUTO &&
- ofdm->hierarchy_information != HIERARCHY_AUTO &&
- ofdm->code_rate_HP != FEC_AUTO &&
- ofdm->code_rate_LP != FEC_AUTO);
+ switch (fep->inversion) {
+ case INVERSION_OFF:
+ par.inv = DIB3000MB_DDS_INV_OFF;
+ break;
+ case INVERSION_AUTO:
+ case INVERSION_ON:
+ par.inv = DIB3000MB_DDS_INV_ON;
+ break;
+ default:
+ return -EINVAL;
+ }
+
switch (ofdm->constellation) {
case QPSK:
par.qam = DIB3000MB_QAM_QPSK;
@@ -383,6 +408,18 @@ static int dib3000mb_set_frontend(struct dib3000mb_state *state,
default:
return -EINVAL;
}
+
+ par.seq = dib3000mb_seq
+ [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO]
+ [ofdm->guard_interval == GUARD_INTERVAL_AUTO]
+ [fep->inversion == INVERSION_AUTO];
+
+ par.qam_vit_manual = (ofdm->constellation != QAM_AUTO &&
+ ofdm->hierarchy_information != HIERARCHY_AUTO &&
+ ofdm->code_rate_HP != FEC_AUTO &&
+ ofdm->code_rate_LP != FEC_AUTO);
+
+ dprintk("auto search will be enabled? %d %d\n",par.seq,!par.qam_vit_manual);
dib3000mb_fe_set_parameters(state,&par);
@@ -393,23 +430,145 @@ static int dib3000mb_set_frontend(struct dib3000mb_state *state,
wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_AGC+DIB3000MB_RESTART_CTRL);
wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_OFF);
+ /* wait for AGC lock */
msleep(70);
wr_foreach(dib3000mb_reg_agc_bandwidth,dib3000mb_agc_bandwidth_low);
- wr(DIB3000MB_REG_ISI,DIB3000MB_ISI_INHIBIT);
- wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_AUTO_SEARCH);
- wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_OFF);
+ /* something has to be auto searched */
+ if (par.seq || !par.qam_vit_manual) {
+ wr(DIB3000MB_REG_ISI,DIB3000MB_ISI_INHIBIT);
+ wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_AUTO_SEARCH);
+ wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_OFF);
+ } else {
+ wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_CTRL);
+ wr(DIB3000MB_REG_RESTART,DIB3000MB_RESTART_OFF);
+ }
+ if (ofdm->constellation != QAM_AUTO &&
+ ofdm->transmission_mode != TRANSMISSION_MODE_AUTO &&
+ ofdm->guard_interval != GUARD_INTERVAL_AUTO &&
+ fep->inversion != INVERSION_AUTO) {
+ wr(DIB3000MB_REG_LOCK1_MASK,DIB3000MB_LOCK1_SEARCH_2048);
+ }
+
while (dib3000mb_fe_read_search_status(state) < 0);
return 0;
}
+
+static int dib3000mb_get_frontend(struct dib3000mb_state *state,
+ struct dvb_frontend_parameters *fep)
+{
+ struct i2c_client *i2c = state->i2c;
+ struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
+ fe_code_rate_t *cr;
+ u16 tps_val;
+
+ if (!rd(DIB3000MB_REG_TPS_LOCK))
+ return -EINVAL;
+
+ switch ((tps_val = rd(DIB3000MB_REG_TPS_QAM))) {
+ case DIB3000MB_QAM_QPSK:
+ ofdm->constellation = QPSK;
+ break;
+ case DIB3000MB_QAM_QAM16:
+ ofdm->constellation = QAM_16;
+ break;
+ case DIB3000MB_QAM_QAM64:
+ ofdm->constellation = QAM_64;
+ break;
+ default:
+ err("Unexpected constellation returned by TPS (%d)",tps_val);
+ break;
+ }
+
+ if (rd(DIB3000MB_REG_TPS_HRCH)) {
+ tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_LP);
+ cr = &ofdm->code_rate_LP;
+ ofdm->code_rate_HP = FEC_NONE;
+
+ switch ((tps_val = rd(DIB3000MB_REG_TPS_VIT_ALPHA))) {
+ case DIB3000MB_VIT_ALPHA_OFF:
+ ofdm->hierarchy_information = HIERARCHY_NONE;
+ break;
+ case DIB3000MB_VIT_ALPHA_1:
+ ofdm->hierarchy_information = HIERARCHY_1;
+ break;
+ case DIB3000MB_VIT_ALPHA_2:
+ ofdm->hierarchy_information = HIERARCHY_2;
+ break;
+ case DIB3000MB_VIT_ALPHA_4:
+ ofdm->hierarchy_information = HIERARCHY_4;
+ break;
+ default:
+ err("Unexpected ALPHA value returned by TPS (%d)",tps_val);
+ }
+ } else {
+ tps_val = rd(DIB3000MB_REG_TPS_CODE_RATE_HP);
+ cr = &ofdm->code_rate_HP;
+ ofdm->code_rate_LP = FEC_NONE;
+ ofdm->hierarchy_information = HIERARCHY_NONE;
+ }
+ switch (tps_val) {
+ case DIB3000MB_FEC_1_2:
+ *cr = FEC_1_2;
+ break;
+ case DIB3000MB_FEC_2_3:
+ *cr = FEC_2_3;
+ break;
+ case DIB3000MB_FEC_3_4:
+ *cr = FEC_3_4;
+ break;
+ case DIB3000MB_FEC_5_6:
+ *cr = FEC_4_5;
+ break;
+ case DIB3000MB_FEC_7_8:
+ *cr = FEC_7_8;
+ break;
+ default:
+ err("Unexpected FEC returned by TPS (%d)",tps_val);
+ break;
+ }
+
+ switch ((tps_val = rd(DIB3000MB_REG_TPS_GUARD_TIME))) {
+ case DIB3000MB_GUARD_TIME_1_32:
+ ofdm->guard_interval = GUARD_INTERVAL_1_32;
+ break;
+ case DIB3000MB_GUARD_TIME_1_16:
+ ofdm->guard_interval = GUARD_INTERVAL_1_16;
+ break;
+ case DIB3000MB_GUARD_TIME_1_8:
+ ofdm->guard_interval = GUARD_INTERVAL_1_8;
+ break;
+ case DIB3000MB_GUARD_TIME_1_4:
+ ofdm->guard_interval = GUARD_INTERVAL_1_4;
+ break;
+ default:
+ err("Unexpected Guard Time returned by TPS (%d)",tps_val);
+ break;
+ }
+
+ switch ((tps_val = rd(DIB3000MB_REG_TPS_FFT))) {
+ case DIB3000MB_FFT_2K:
+ ofdm->transmission_mode = TRANSMISSION_MODE_2K;
+ break;
+ case DIB3000MB_FFT_8K:
+ ofdm->transmission_mode = TRANSMISSION_MODE_8K;
+ break;
+ default:
+ err("unexpected transmission mode return by TPS (%d)",tps_val);
+ }
+ return 0;
+}
+
static int dib3000mb_fe_init(struct dib3000mb_state *state,int mobile_mode)
{
struct i2c_client *i2c = state->i2c;
+ wr(DIB3000MB_REG_POWER_CONTROL,DIB3000MB_POWER_UP);
+
wr(DIB3000MB_REG_RESTART, DIB3000MB_RESTART_AGC);
wr(DIB3000MB_REG_RESET_DEVICE,DIB3000MB_RESET_DEVICE);
@@ -511,6 +670,29 @@ static int dib3000mb_read_status(struct dib3000mb_state *state,fe_status_t *stat
return 0;
}
+static int dib3000mb_read_ber(struct dib3000mb_state *state,u32 *ber)
+{
+ struct i2c_client *i2c = state->i2c;
+ *ber =
+ (((rd(DIB3000MB_REG_BER_MSB) << 16) & 0x1f) | rd(DIB3000MB_REG_BER_LSB) ) /
+ 100000000;
+ return 0;
+}
+
+static int dib3000mb_signal_strength(struct dib3000mb_state *state, u16 *strength)
+{
+ struct i2c_client *i2c = state->i2c;
+// *stength = DIB3000MB_REG_SIGNAL_POWER
+ return 0;
+}
+
+static int dib3000mb_sleep(struct dib3000mb_state *state)
+{
+ struct i2c_client *i2c = state->i2c;
+ wr(DIB3000MB_REG_POWER_CONTROL,DIB3000MB_POWER_DOWN);
+ return 0;
+}
+
static int dib3000mb_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg)
{
struct dib3000mb_state *state = fe->data;
@@ -528,10 +710,12 @@ static int dib3000mb_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg
case FE_READ_BER:
dprintk("FE_READ_BER\n");
+ ret = dib3000mb_read_ber(state,(u32 *)arg);
break;
case FE_READ_SIGNAL_STRENGTH:
dprintk("FE_READ_SIG_STRENGTH\n");
+ ret = dib3000mb_signal_strength(state,(u16 *) arg);
break;
case FE_READ_SNR:
@@ -549,10 +733,12 @@ static int dib3000mb_ioctl (struct dvb_frontend *fe, unsigned int cmd, void *arg
case FE_GET_FRONTEND:
dprintk("FE_GET_FRONTEND\n");
+ ret = dib3000mb_get_frontend(state,(struct dvb_frontend_parameters *) arg);
break;
case FE_SLEEP:
dprintk("FE_SLEEP\n");
+ ret = dib3000mb_sleep(state);
break;
case FE_INIT:
diff --git a/linux/drivers/media/dvb/frontends/dib3000mb.h b/linux/drivers/media/dvb/frontends/dib3000mb.h
index e606ff7b7..5f81b6eb0 100644
--- a/linux/drivers/media/dvb/frontends/dib3000mb.h
+++ b/linux/drivers/media/dvb/frontends/dib3000mb.h
@@ -517,9 +517,9 @@ static u16 dib3000mb_filter_coeffs[] = {
#define DIB3000MB_CLOCK_DIVERSITY (0x92b0)
/* power down config */
-#define DIB3000MB_REG_POWER_DOWN ( 1028)
-#define DIB3000MB_POWER_DOWN ( 1)
-#define DIB3000MB_POWER_UP ( 0)
+#define DIB3000MB_REG_POWER_CONTROL ( 1028)
+#define DIB3000MB_POWER_DOWN ( 1)
+#define DIB3000MB_POWER_UP ( 0)
/* electrical output mode */
#define DIB3000MB_REG_ELECT_OUT_MODE ( 1029)