Skip to content

Commit

Permalink
V4L/DVB (4012): Fix cx24123 diseqc
Browse files Browse the repository at this point in the history
Rework diseqc support to be more in line with the other demod drivers.
Fix Nova-S-Plus/Nova-SE2 diseqc.
Cleanup API.

Signed-off-by: Andrew de Quincey <adq_dvb@lidskialf.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
  • Loading branch information
Andrew de Quincey authored and Mauro Carvalho Chehab committed Jun 25, 2006
1 parent 9a10655 commit cd20ca9
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 152 deletions.
184 changes: 48 additions & 136 deletions drivers/media/dvb/frontends/cx24123.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ struct cx24123_state

u32 lastber;
u16 snr;
u8 lnbreg;

/* Some PLL specifics for tuning */
u32 VCAarg;
Expand Down Expand Up @@ -249,29 +248,6 @@ static int cx24123_writereg(struct cx24123_state* state, int reg, int data)
return 0;
}

static int cx24123_writelnbreg(struct cx24123_state* state, int reg, int data)
{
u8 buf[] = { reg, data };
/* fixme: put the intersil addr int the config */
struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = buf, .len = 2 };
int err;

if (debug>1)
printk("cx24123: %s: writeln addr=0x08, reg 0x%02x, value 0x%02x\n",
__FUNCTION__,reg, data);

if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
printk("%s: writelnbreg error (err == %i, reg == 0x%02x,"
" data == 0x%02x)\n", __FUNCTION__, err, reg, data);
return -EREMOTEIO;
}

/* cache the write, no way to read back */
state->lnbreg = data;

return 0;
}

static int cx24123_readreg(struct cx24123_state* state, u8 reg)
{
int ret;
Expand All @@ -295,11 +271,6 @@ static int cx24123_readreg(struct cx24123_state* state, u8 reg)
return b1[0];
}

static int cx24123_readlnbreg(struct cx24123_state* state, u8 reg)
{
return state->lnbreg;
}

static int cx24123_set_inversion(struct cx24123_state* state, fe_spectral_inversion_t inversion)
{
u8 nom_reg = cx24123_readreg(state, 0x0e);
Expand Down Expand Up @@ -687,10 +658,6 @@ static int cx24123_initfe(struct dvb_frontend* fe)
for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++)
cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);

/* Configure the LNB for 14V */
if (state->config->use_isl6421)
cx24123_writelnbreg(state, 0x0, 0x2a);

return 0;
}

Expand All @@ -699,50 +666,18 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage
struct cx24123_state *state = fe->demodulator_priv;
u8 val;

switch (state->config->use_isl6421) {

case 1:
val = cx24123_readreg(state, 0x29) & ~0x40;

val = cx24123_readlnbreg(state, 0x0);

switch (voltage) {
case SEC_VOLTAGE_13:
dprintk("%s: isl6421 voltage = 13V\n",__FUNCTION__);
return cx24123_writelnbreg(state, 0x0, val & 0x32); /* V 13v */
case SEC_VOLTAGE_18:
dprintk("%s: isl6421 voltage = 18V\n",__FUNCTION__);
return cx24123_writelnbreg(state, 0x0, val | 0x04); /* H 18v */
case SEC_VOLTAGE_OFF:
dprintk("%s: isl5421 voltage off\n",__FUNCTION__);
return cx24123_writelnbreg(state, 0x0, val & 0x30);
default:
return -EINVAL;
};

case 0:

val = cx24123_readreg(state, 0x29);

switch (voltage) {
case SEC_VOLTAGE_13:
dprintk("%s: setting voltage 13V\n", __FUNCTION__);
if (state->config->enable_lnb_voltage)
state->config->enable_lnb_voltage(fe, 1);
return cx24123_writereg(state, 0x29, val | 0x80);
case SEC_VOLTAGE_18:
dprintk("%s: setting voltage 18V\n", __FUNCTION__);
if (state->config->enable_lnb_voltage)
state->config->enable_lnb_voltage(fe, 1);
return cx24123_writereg(state, 0x29, val & 0x7f);
case SEC_VOLTAGE_OFF:
dprintk("%s: setting voltage off\n", __FUNCTION__);
if (state->config->enable_lnb_voltage)
state->config->enable_lnb_voltage(fe, 0);
return 0;
default:
return -EINVAL;
};
}
switch (voltage) {
case SEC_VOLTAGE_13:
dprintk("%s: setting voltage 13V\n", __FUNCTION__);
return cx24123_writereg(state, 0x29, val | 0x80);
case SEC_VOLTAGE_18:
dprintk("%s: setting voltage 18V\n", __FUNCTION__);
return cx24123_writereg(state, 0x29, val & 0x7f);
default:
return -EINVAL;
};

return 0;
}
Expand All @@ -763,27 +698,20 @@ static void cx24123_wait_for_diseqc(struct cx24123_state *state)
static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
{
struct cx24123_state *state = fe->demodulator_priv;
int i, val;
int i, val, tone;

dprintk("%s:\n",__FUNCTION__);

/* check if continuous tone has been stopped */
if (state->config->use_isl6421)
val = cx24123_readlnbreg(state, 0x00) & 0x10;
else
val = cx24123_readreg(state, 0x29) & 0x10;


if (val) {
printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__);
return -ENOTSUPP;
}
/* stop continuous tone if enabled */
tone = cx24123_readreg(state, 0x29);
if (tone & 0x10)
cx24123_writereg(state, 0x29, tone & ~0x50);

/* wait for diseqc queue ready */
cx24123_wait_for_diseqc(state);

/* select tone mode */
cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xf8);
cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);

for (i = 0; i < cmd->msg_len; i++)
cx24123_writereg(state, 0x2C + i, cmd->msg[i]);
Expand All @@ -794,36 +722,33 @@ static int cx24123_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma
/* wait for diseqc message to finish sending */
cx24123_wait_for_diseqc(state);

/* restart continuous tone if enabled */
if (tone & 0x10) {
cx24123_writereg(state, 0x29, tone & ~0x40);
}

return 0;
}

static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
{
struct cx24123_state *state = fe->demodulator_priv;
int val;
int val, tone;

dprintk("%s:\n", __FUNCTION__);

/* check if continuous tone has been stoped */
if (state->config->use_isl6421)
val = cx24123_readlnbreg(state, 0x00) & 0x10;
else
val = cx24123_readreg(state, 0x29) & 0x10;


if (val) {
printk("%s: ERROR: attempt to send diseqc command before tone is off\n", __FUNCTION__);
return -ENOTSUPP;
}
/* stop continuous tone if enabled */
tone = cx24123_readreg(state, 0x29);
if (tone & 0x10)
cx24123_writereg(state, 0x29, tone & ~0x50);

/* wait for diseqc queue ready */
cx24123_wait_for_diseqc(state);

/* select tone mode */
val = cx24123_readreg(state, 0x2a) & 0xf8;
cx24123_writereg(state, 0x2a, val | 0x04);

cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) | 0x4);
msleep(30);
val = cx24123_readreg(state, 0x29);

if (burst == SEC_MINI_A)
cx24123_writereg(state, 0x29, ((val & 0x90) | 0x40 | 0x00));
else if (burst == SEC_MINI_B)
Expand All @@ -832,7 +757,12 @@ static int cx24123_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t
return -EINVAL;

cx24123_wait_for_diseqc(state);
cx24123_writereg(state, 0x2a, cx24123_readreg(state, 0x2a) & 0xfb);

/* restart continuous tone if enabled */
if (tone & 0x10) {
cx24123_writereg(state, 0x29, tone & ~0x40);
}
return 0;
}

Expand Down Expand Up @@ -973,38 +903,21 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
struct cx24123_state *state = fe->demodulator_priv;
u8 val;

switch (state->config->use_isl6421) {
case 1:

val = cx24123_readlnbreg(state, 0x0);

switch (tone) {
case SEC_TONE_ON:
dprintk("%s: isl6421 sec tone on\n",__FUNCTION__);
return cx24123_writelnbreg(state, 0x0, val | 0x10);
case SEC_TONE_OFF:
dprintk("%s: isl6421 sec tone off\n",__FUNCTION__);
return cx24123_writelnbreg(state, 0x0, val & 0x2f);
default:
printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
return -EINVAL;
}

case 0:
/* wait for diseqc queue ready */
cx24123_wait_for_diseqc(state);

val = cx24123_readreg(state, 0x29);
val = cx24123_readreg(state, 0x29) & ~0x40;

switch (tone) {
case SEC_TONE_ON:
dprintk("%s: setting tone on\n", __FUNCTION__);
return cx24123_writereg(state, 0x29, val | 0x10);
case SEC_TONE_OFF:
dprintk("%s: setting tone off\n",__FUNCTION__);
return cx24123_writereg(state, 0x29, val & 0xef);
default:
printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
return -EINVAL;
}
switch (tone) {
case SEC_TONE_ON:
dprintk("%s: setting tone on\n", __FUNCTION__);
return cx24123_writereg(state, 0x29, val | 0x10);
case SEC_TONE_OFF:
dprintk("%s: setting tone off\n",__FUNCTION__);
return cx24123_writereg(state, 0x29, val & 0xef);
default:
printk("%s: CASE reached default with tone=%d\n", __FUNCTION__, tone);
return -EINVAL;
}

return 0;
Expand Down Expand Up @@ -1040,7 +953,6 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
memcpy(&state->ops, &cx24123_ops, sizeof(struct dvb_frontend_ops));
state->lastber = 0;
state->snr = 0;
state->lnbreg = 0;
state->VCAarg = 0;
state->VGAarg = 0;
state->bandselectarg = 0;
Expand Down
9 changes: 0 additions & 9 deletions drivers/media/dvb/frontends/cx24123.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,8 @@ struct cx24123_config
/* the demodulator's i2c address */
u8 demod_address;

/*
cards like Hauppauge Nova-S Plus/Nova-SE2 use an Intersil ISL6421 chip
for LNB control, while KWorld DVB-S 100 use the LNBDC and LNBTone bits
from register 0x29 of the CX24123 demodulator
*/
int use_isl6421;

/* Need to set device param for start_dma */
int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);

void (*enable_lnb_voltage)(struct dvb_frontend* fe, int on);
};

extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
Expand Down
2 changes: 2 additions & 0 deletions drivers/media/video/cx88/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ config VIDEO_CX88_DVB_ALL_FRONTENDS
select DVB_LGDT330X
select DVB_NXT200X
select DVB_CX24123
select DVB_ISL6421
---help---
This builds cx88-dvb with all currently supported frontend
demodulators. If you wish to tweak your configuration, and
Expand Down Expand Up @@ -139,6 +140,7 @@ config VIDEO_CX88_DVB_CX24123
default y
depends on VIDEO_CX88_DVB && !VIDEO_CX88_DVB_ALL_FRONTENDS
select DVB_CX24123
select DVB_ISL6421
---help---
This adds DVB-S support for cards based on the
Connexant 2388x chip and the CX24123 demodulator.
24 changes: 17 additions & 7 deletions drivers/media/video/cx88/cx88-dvb.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#ifdef HAVE_CX24123
# include "cx24123.h"
#endif
#include "isl6421.h"

MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
Expand Down Expand Up @@ -479,28 +480,30 @@ static int cx24123_set_ts_param(struct dvb_frontend* fe,
return 0;
}

static void cx24123_enable_lnb_voltage(struct dvb_frontend* fe, int on)
static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
{
struct cx8802_dev *dev= fe->dvb->priv;
struct cx88_core *core = dev->core;

if (on)
cx_write(MO_GP0_IO, 0x000006f9);
else
if (voltage == SEC_VOLTAGE_OFF) {
cx_write(MO_GP0_IO, 0x000006fB);
} else {
cx_write(MO_GP0_IO, 0x000006f9);
}

if (core->prev_set_voltage)
return core->prev_set_voltage(fe, voltage);
return 0;
}

static struct cx24123_config hauppauge_novas_config = {
.demod_address = 0x55,
.use_isl6421 = 1,
.set_ts_params = cx24123_set_ts_param,
};

static struct cx24123_config kworld_dvbs_100_config = {
.demod_address = 0x15,
.use_isl6421 = 0,
.set_ts_params = cx24123_set_ts_param,
.enable_lnb_voltage = cx24123_enable_lnb_voltage,
};
#endif

Expand Down Expand Up @@ -710,10 +713,17 @@ static int dvb_register(struct cx8802_dev *dev)
case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config,
&dev->core->i2c_adap);
if (dev->dvb.frontend) {
isl6421_attach(dev->dvb.frontend, &dev->core->i2c_adap, 0x08, 0x00, 0x00);
}
break;
case CX88_BOARD_KWORLD_DVBS_100:
dev->dvb.frontend = cx24123_attach(&kworld_dvbs_100_config,
&dev->core->i2c_adap);
if (dev->dvb.frontend) {
dev->core->prev_set_voltage = dev->dvb.frontend->ops->set_voltage;
dev->dvb.frontend->ops->set_voltage = kworld_dvbs_100_set_voltage;
}
break;
#endif
default:
Expand Down
1 change: 1 addition & 0 deletions drivers/media/video/cx88/cx88.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ struct cx88_core {
/* config info -- dvb */
struct dvb_pll_desc *pll_desc;
unsigned int pll_addr;
int (*prev_set_voltage)(struct dvb_frontend* fe, fe_sec_voltage_t voltage);

/* state info */
struct task_struct *kthread;
Expand Down

0 comments on commit cd20ca9

Please sign in to comment.