return 0;
}
-
static int cx24110_readreg (struct cx24110_state* state, u8 reg)
{
int ret;
return 0;
}
-
static int cx24110_set_fec (struct cx24110_state* state, fe_code_rate_t fec)
{
/* fixme (low): error handling */
return 0;
}
-
static fe_code_rate_t cx24110_get_fec (struct cx24110_state* state)
{
int i;
}
}
-
static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
{
/* fixme (low): add error handling */
}
-
-
-
-
-
-
-
-
-
-
-
int cx24110_pll_write (struct dvb_frontend* fe, u32 data)
{
- struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+ struct cx24110_state *state = fe->demodulator_priv;
/* tuner data is 21 bits long, must be left-aligned in data */
/* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */
return 0;
}
-
-
static int cx24110_initfe(struct dvb_frontend* fe)
{
- struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+ struct cx24110_state *state = fe->demodulator_priv;
/* fixme (low): error handling */
int i;
return 0;
}
-
static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
{
- struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+ struct cx24110_state *state = fe->demodulator_priv;
switch (voltage) {
case SEC_VOLTAGE_13:
};
}
+static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst)
+{
+ int rv, bit, i;
+ struct cx24110_state *state = fe->demodulator_priv;
+
+ if (burst == SEC_MINI_A)
+ bit = 0x00;
+ else if (burst == SEC_MINI_B)
+ bit = 0x08;
+ else
+ return -EINVAL;
+
+ rv = cx24110_readreg(state, 0x77);
+ cx24110_writereg(state, 0x77, rv|0x04);
+
+ rv = cx24110_readreg(state, 0x76);
+ cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40 | bit));
+ for (i = 500; i-- > 0 && !(cx24110_readreg(state,0x76)&0x40) ; )
+ ; /* wait for LNB ready */
+
+ return 0;
+}
+
static int cx24110_send_diseqc_msg(struct dvb_frontend* fe,
- struct dvb_diseqc_master_cmd *cmd)
+ struct dvb_diseqc_master_cmd *cmd)
{
int i, rv;
- struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+ struct cx24110_state *state = fe->demodulator_priv;
for (i = 0; i < cmd->msg_len; i++)
cx24110_writereg(state, 0x79 + i, cmd->msg[i]);
+ rv = cx24110_readreg(state, 0x77);
+ cx24110_writereg(state, 0x77, rv|0x04);
+
rv = cx24110_readreg(state, 0x76);
cx24110_writereg(state, 0x76, ((rv & 0x90) | 0x40) | ((cmd->msg_len-3) & 3));
static int cx24110_read_status(struct dvb_frontend* fe, fe_status_t* status)
{
- struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+ struct cx24110_state *state = fe->demodulator_priv;
int sync = cx24110_readreg (state, 0x55);
- *status = 0;
+ *status = 0;
- if (sync & 0x10)
- *status |= FE_HAS_SIGNAL;
+ if (sync & 0x10)
+ *status |= FE_HAS_SIGNAL;
- if (sync & 0x08)
- *status |= FE_HAS_CARRIER;
+ if (sync & 0x08)
+ *status |= FE_HAS_CARRIER;
sync = cx24110_readreg (state, 0x08);
- if (sync & 0x40)
- *status |= FE_HAS_VITERBI;
+ if (sync & 0x40)
+ *status |= FE_HAS_VITERBI;
- if (sync & 0x20)
- *status |= FE_HAS_SYNC;
+ if (sync & 0x20)
+ *status |= FE_HAS_SYNC;
- if ((sync & 0x60) == 0x60)
- *status |= FE_HAS_LOCK;
+ if ((sync & 0x60) == 0x60)
+ *status |= FE_HAS_LOCK;
return 0;
- }
+}
static int cx24110_read_ber(struct dvb_frontend* fe, u32* ber)
- {
- struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+{
+ struct cx24110_state *state = fe->demodulator_priv;
-/* fixme (maybe): value range is 16 bit. Scale? */
+ /* fixme (maybe): value range is 16 bit. Scale? */
if(cx24110_readreg(state,0x24)&0x10) {
/* the Viterbi error counter has finished one counting window */
cx24110_writereg(state,0x24,0x04); /* select the ber reg */
*ber = state->lastber;
return 0;
- }
+}
static int cx24110_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
- {
- struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+{
+ struct cx24110_state *state = fe->demodulator_priv;
/* no provision in hardware. Read the frontend AGC accumulator. No idea how to scale this, but I know it is 2s complement */
u8 signal = cx24110_readreg (state, 0x27)+128;
*signal_strength = (signal << 8) | signal;
return 0;
- }
+}
static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr)
- {
- struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+{
+ struct cx24110_state *state = fe->demodulator_priv;
-/* no provision in hardware. Can be computed from the Es/N0 estimator, but I don't know how. */
+ /* no provision in hardware. Can be computed from the Es/N0 estimator, but I don't know how. */
if(cx24110_readreg(state,0x6a)&0x80) {
/* the Es/N0 error counter has finished one counting window */
state->lastesn0=cx24110_readreg(state,0x69)|
*snr = state->lastesn0;
return 0;
- }
+}
static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
- {
- struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+{
+ struct cx24110_state *state = fe->demodulator_priv;
u32 lastbyer;
if(cx24110_readreg(state,0x10)&0x40) {
}
static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
- {
- struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+{
+ struct cx24110_state *state = fe->demodulator_priv;
state->config->pll_set(fe, p);
cx24110_set_inversion (state, p->inversion);
cx24110_writereg(state,0x04,0x05); /* start aquisition */
return 0;
- }
+}
static int cx24110_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
- {
- struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
- s32 afc; unsigned sclk;
+{
+ struct cx24110_state *state = fe->demodulator_priv;
+ s32 afc; unsigned sclk;
/* cannot read back tuner settings (freq). Need to have some private storage */
sclk = cx24110_readreg (state, 0x07) & 0x03;
/* ok, real AFC (FEDR) freq. is afc/2^24*fsamp, fsamp=45/60/80/90MHz.
* Need 64 bit arithmetic. Is thiss possible in the kernel? */
- if (sclk==0) sclk=90999000L/2L;
- else if (sclk==1) sclk=60666000L;
- else if (sclk==2) sclk=80888000L;
- else sclk=90999000L;
- sclk>>=8;
+ if (sclk==0) sclk=90999000L/2L;
+ else if (sclk==1) sclk=60666000L;
+ else if (sclk==2) sclk=80888000L;
+ else sclk=90999000L;
+ sclk>>=8;
afc = sclk*(cx24110_readreg (state, 0x44)&0x1f)+
((sclk*cx24110_readreg (state, 0x45))>>8)+
((sclk*cx24110_readreg (state, 0x46))>>16);
- p->frequency += afc;
+ p->frequency += afc;
p->inversion = (cx24110_readreg (state, 0x22) & 0x10) ?
- INVERSION_ON : INVERSION_OFF;
+ INVERSION_ON : INVERSION_OFF;
p->u.qpsk.fec_inner = cx24110_get_fec (state);
- return 0;
+ return 0;
}
static int cx24110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
{
- struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv;
+ struct cx24110_state *state = fe->demodulator_priv;
return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&~0x10)|(((tone==SEC_TONE_ON))?0x10:0));
}
static void cx24110_release(struct dvb_frontend* fe)
{
- struct cx24110_state* state = (struct cx24110_state*) fe->demodulator_priv;
- kfree(state);
+ struct cx24110_state* state = fe->demodulator_priv;
+ kfree(state);
}
static struct dvb_frontend_ops cx24110_ops;
int ret;
/* allocate memory for the internal state */
- state = (struct cx24110_state*) kmalloc(sizeof(struct cx24110_state), GFP_KERNEL);
+ state = kmalloc(sizeof(struct cx24110_state), GFP_KERNEL);
if (state == NULL) goto error;
/* setup the state */
memcpy(&state->ops, &cx24110_ops, sizeof(struct dvb_frontend_ops));
state->lastber = 0;
state->lastbler = 0;
- state->lastesn0 = 0;
+ state->lastesn0 = 0;
/* check if the demod is there */
ret = cx24110_readreg(state, 0x00);
return &state->frontend;
error:
- if (state) kfree(state);
+ kfree(state);
return NULL;
}
.diseqc_send_master_cmd = cx24110_send_diseqc_msg,
.set_tone = cx24110_set_tone,
.set_voltage = cx24110_set_voltage,
+ .diseqc_send_burst = cx24110_diseqc_send_burst,
};
module_param(debug, int, 0644);