Loading drivers/media/dvb/frontends/tda1004x.c +125 −121 Original line number Diff line number Diff line Loading @@ -35,9 +35,10 @@ #include "dvb_frontend.h" #include "tda1004x.h" #define TDA1004X_DEMOD_TDA10045 0 #define TDA1004X_DEMOD_TDA10046 1 enum tda1004x_demod { TDA1004X_DEMOD_TDA10045, TDA1004X_DEMOD_TDA10046, }; struct tda1004x_state { struct i2c_adapter* i2c; Loading @@ -46,8 +47,8 @@ struct tda1004x_state { struct dvb_frontend frontend; /* private demod data */ u8 initialised:1; u8 demod_type; u8 initialised; enum tda1004x_demod demod_type; }; Loading Loading @@ -139,7 +140,7 @@ static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data) { int ret; u8 buf[] = { reg, data }; struct i2c_msg msg = { .addr=0, .flags=0, .buf=buf, .len=2 }; struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 }; dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data); Loading @@ -160,8 +161,8 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg) int ret; u8 b0[] = { reg }; u8 b1[] = { 0 }; struct i2c_msg msg[] = {{ .addr=0, .flags=0, .buf=b0, .len=1}, { .addr=0, .flags=I2C_M_RD, .buf=b1, .len = 1}}; struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 }, { .flags = I2C_M_RD, .buf = b1, .len = 1 }}; dprintk("%s: reg=0x%x\n", __FUNCTION__, reg); Loading Loading @@ -294,7 +295,7 @@ static int tda1004x_do_upload(struct tda1004x_state *state, u8 dspCodeCounterReg, u8 dspCodeInReg) { u8 buf[65]; struct i2c_msg fw_msg = {.addr = 0,.flags = 0,.buf = buf,.len = 0 }; struct i2c_msg fw_msg = { .flags = 0, .buf = buf, .len = 0 }; int tx_size; int pos = 0; Loading @@ -304,12 +305,10 @@ static int tda1004x_do_upload(struct tda1004x_state *state, buf[0] = dspCodeInReg; while (pos != len) { // work out how much to send this time tx_size = len - pos; if (tx_size > 0x10) { if (tx_size > 0x10) tx_size = 0x10; } // send the chunk memcpy(buf + 1, mem + pos, tx_size); Loading @@ -322,6 +321,7 @@ static int tda1004x_do_upload(struct tda1004x_state *state, dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos); } return 0; } Loading @@ -335,9 +335,8 @@ static int tda1004x_check_upload_ok(struct tda1004x_state *state, u8 dspVersion) data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1); data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2); if (data1 != 0x67 || data2 != dspVersion) { if ((data1 != 0x67) || (data2 != dspVersion)) return -EIO; } return 0; } Loading @@ -348,9 +347,9 @@ static int tda10045_fwupload(struct dvb_frontend* fe) int ret; const struct firmware *fw; /* don't re-upload unless necessary */ if (tda1004x_check_upload_ok(state, 0x2c) == 0) return 0; if (tda1004x_check_upload_ok(state, 0x2c) == 0) return 0; /* request the firmware, this will block until someone uploads it */ printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE); Loading Loading @@ -394,7 +393,8 @@ static int tda10046_fwupload(struct dvb_frontend* fe) msleep(100); /* don't re-upload unless necessary */ if (tda1004x_check_upload_ok(state, 0x20) == 0) return 0; if (tda1004x_check_upload_ok(state, 0x20) == 0) return 0; /* request the firmware, this will block until someone uploads it */ printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10046_DEFAULT_FIRMWARE); Loading Loading @@ -483,7 +483,8 @@ static int tda10045_init(struct dvb_frontend* fe) dprintk("%s\n", __FUNCTION__); if (state->initialised) return 0; if (state->initialised) return 0; if (tda10045_fwupload(fe)) { printk("tda1004x: firmware upload failed\n"); Loading Loading @@ -523,7 +524,8 @@ static int tda10046_init(struct dvb_frontend* fe) struct tda1004x_state* state = fe->demodulator_priv; dprintk("%s\n", __FUNCTION__); if (state->initialised) return 0; if (state->initialised) return 0; if (tda10046_fwupload(fe)) { printk("tda1004x: firmware upload failed\n"); Loading Loading @@ -621,12 +623,14 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, // set HP FEC tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP); if (tmp < 0) return tmp; if (tmp < 0) return tmp; tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp); // set LP FEC tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP); if (tmp < 0) return tmp; if (tmp < 0) return tmp; tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3); // set constellation Loading Loading @@ -683,7 +687,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, // set inversion inversion = fe_params->inversion; if (state->config->invert) inversion = inversion ? INVERSION_OFF : INVERSION_ON; if (state->config->invert) inversion = inversion ? INVERSION_OFF : INVERSION_ON; switch (inversion) { case INVERSION_OFF: tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0); Loading Loading @@ -754,15 +759,15 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, case TDA1004X_DEMOD_TDA10045: tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0); msleep(10); break; case TDA1004X_DEMOD_TDA10046: tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40); msleep(10); break; } msleep(10); return 0; } Loading @@ -773,10 +778,10 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete // inversion status fe_params->inversion = INVERSION_OFF; if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20) { if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20) fe_params->inversion = INVERSION_ON; } if (state->config->invert) fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON; if (state->config->invert) fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON; // bandwidth switch (state->demod_type) { Loading Loading @@ -830,9 +835,8 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete // transmission mode fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10) { if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10) fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; } // guard interval switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) { Loading Loading @@ -880,52 +884,57 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status // read status status = tda1004x_read_byte(state, TDA1004X_STATUS_CD); if (status == -1) { if (status == -1) return -EIO; } // decode *fe_status = 0; if (status & 4) *fe_status |= FE_HAS_SIGNAL; if (status & 2) *fe_status |= FE_HAS_CARRIER; if (status & 8) *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; if (status & 4) *fe_status |= FE_HAS_SIGNAL; if (status & 2) *fe_status |= FE_HAS_CARRIER; if (status & 8) *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi // is getting anything valid if (!(*fe_status & FE_HAS_VITERBI)) { // read the CBER cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB); if (cber == -1) return -EIO; if (cber == -1) return -EIO; status = tda1004x_read_byte(state, TDA1004X_CBER_MSB); if (status == -1) return -EIO; if (status == -1) return -EIO; cber |= (status << 8); tda1004x_read_byte(state, TDA1004X_CBER_RESET); if (cber != 65535) { if (cber != 65535) *fe_status |= FE_HAS_VITERBI; } } // if we DO have some valid VITERBI output, but don't already have SYNC // bytes (i.e. not LOCKED), see if the RS decoder is getting anything valid. if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) { // read the VBER vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB); if (vber == -1) return -EIO; if (vber == -1) return -EIO; status = tda1004x_read_byte(state, TDA1004X_VBER_MID); if (status == -1) return -EIO; if (status == -1) return -EIO; vber |= (status << 8); status = tda1004x_read_byte(state, TDA1004X_VBER_MSB); if (status == -1) return -EIO; if (status == -1) return -EIO; vber |= ((status << 16) & 0x0f); tda1004x_read_byte(state, TDA1004X_CVBER_LUT); // if RS has passed some valid TS packets, then we must be // getting some SYNC bytes if (vber < 16632) { if (vber < 16632) *fe_status |= FE_HAS_SYNC; } } // success dprintk("%s: fe_status=0x%x\n", __FUNCTION__, *fe_status); Loading Loading @@ -972,9 +981,8 @@ static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr) tmp = tda1004x_read_byte(state, TDA1004X_SNR); if (tmp < 0) return -EIO; if (tmp) { if (tmp) tmp = 255 - tmp; } *snr = ((tmp << 8) | tmp); dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr); Loading Loading @@ -1009,11 +1017,11 @@ static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) break; } if (tmp != 0x7f) { if (tmp != 0x7f) *ucblocks = tmp; } else { else *ucblocks = 0xffffffff; } dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks); return 0; } Loading @@ -1027,10 +1035,12 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber) // read it in tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB); if (tmp < 0) return -EIO; if (tmp < 0) return -EIO; *ber = tmp << 1; tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB); if (tmp < 0) return -EIO; if (tmp < 0) return -EIO; *ber |= (tmp << 9); tda1004x_read_byte(state, TDA1004X_CBER_RESET); Loading Loading @@ -1066,74 +1076,11 @@ static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronte static void tda1004x_release(struct dvb_frontend* fe) { struct tda1004x_state* state = (struct tda1004x_state*) fe->demodulator_priv; kfree(state); } static struct dvb_frontend_ops tda10045_ops; struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { struct tda1004x_state* state = NULL; /* allocate memory for the internal state */ state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); if (state == NULL) goto error; /* setup the state */ state->config = config; state->i2c = i2c; memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); state->initialised = 0; state->demod_type = TDA1004X_DEMOD_TDA10045; /* check if the demod is there */ if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) goto error; /* create dvb_frontend */ state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; error: struct tda1004x_state *state = fe->demodulator_priv; kfree(state); return NULL; } static struct dvb_frontend_ops tda10046_ops; struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { struct tda1004x_state* state = NULL; /* allocate memory for the internal state */ state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); if (state == NULL) goto error; /* setup the state */ state->config = config; state->i2c = i2c; memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); state->initialised = 0; state->demod_type = TDA1004X_DEMOD_TDA10046; /* check if the demod is there */ if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) goto error; /* create dvb_frontend */ state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; error: if (state) kfree(state); return NULL; } static struct dvb_frontend_ops tda10045_ops = { .info = { .name = "Philips TDA10045H DVB-T", .type = FE_OFDM, Loading Loading @@ -1163,8 +1110,36 @@ static struct dvb_frontend_ops tda10045_ops = { .read_ucblocks = tda1004x_read_ucblocks, }; static struct dvb_frontend_ops tda10046_ops = { struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { struct tda1004x_state *state; /* allocate memory for the internal state */ state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); if (!state) return NULL; /* setup the state */ state->config = config; state->i2c = i2c; memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); state->initialised = 0; state->demod_type = TDA1004X_DEMOD_TDA10045; /* check if the demod is there */ if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) { kfree(state); return NULL; } /* create dvb_frontend */ state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; } static struct dvb_frontend_ops tda10046_ops = { .info = { .name = "Philips TDA10046H DVB-T", .type = FE_OFDM, Loading Loading @@ -1194,6 +1169,35 @@ static struct dvb_frontend_ops tda10046_ops = { .read_ucblocks = tda1004x_read_ucblocks, }; struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { struct tda1004x_state *state; /* allocate memory for the internal state */ state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); if (!state) return NULL; /* setup the state */ state->config = config; state->i2c = i2c; memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); state->initialised = 0; state->demod_type = TDA1004X_DEMOD_TDA10046; /* check if the demod is there */ if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) { kfree(state); return NULL; } /* create dvb_frontend */ state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; } module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); Loading Loading
drivers/media/dvb/frontends/tda1004x.c +125 −121 Original line number Diff line number Diff line Loading @@ -35,9 +35,10 @@ #include "dvb_frontend.h" #include "tda1004x.h" #define TDA1004X_DEMOD_TDA10045 0 #define TDA1004X_DEMOD_TDA10046 1 enum tda1004x_demod { TDA1004X_DEMOD_TDA10045, TDA1004X_DEMOD_TDA10046, }; struct tda1004x_state { struct i2c_adapter* i2c; Loading @@ -46,8 +47,8 @@ struct tda1004x_state { struct dvb_frontend frontend; /* private demod data */ u8 initialised:1; u8 demod_type; u8 initialised; enum tda1004x_demod demod_type; }; Loading Loading @@ -139,7 +140,7 @@ static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data) { int ret; u8 buf[] = { reg, data }; struct i2c_msg msg = { .addr=0, .flags=0, .buf=buf, .len=2 }; struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 }; dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data); Loading @@ -160,8 +161,8 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg) int ret; u8 b0[] = { reg }; u8 b1[] = { 0 }; struct i2c_msg msg[] = {{ .addr=0, .flags=0, .buf=b0, .len=1}, { .addr=0, .flags=I2C_M_RD, .buf=b1, .len = 1}}; struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 }, { .flags = I2C_M_RD, .buf = b1, .len = 1 }}; dprintk("%s: reg=0x%x\n", __FUNCTION__, reg); Loading Loading @@ -294,7 +295,7 @@ static int tda1004x_do_upload(struct tda1004x_state *state, u8 dspCodeCounterReg, u8 dspCodeInReg) { u8 buf[65]; struct i2c_msg fw_msg = {.addr = 0,.flags = 0,.buf = buf,.len = 0 }; struct i2c_msg fw_msg = { .flags = 0, .buf = buf, .len = 0 }; int tx_size; int pos = 0; Loading @@ -304,12 +305,10 @@ static int tda1004x_do_upload(struct tda1004x_state *state, buf[0] = dspCodeInReg; while (pos != len) { // work out how much to send this time tx_size = len - pos; if (tx_size > 0x10) { if (tx_size > 0x10) tx_size = 0x10; } // send the chunk memcpy(buf + 1, mem + pos, tx_size); Loading @@ -322,6 +321,7 @@ static int tda1004x_do_upload(struct tda1004x_state *state, dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos); } return 0; } Loading @@ -335,9 +335,8 @@ static int tda1004x_check_upload_ok(struct tda1004x_state *state, u8 dspVersion) data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1); data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2); if (data1 != 0x67 || data2 != dspVersion) { if ((data1 != 0x67) || (data2 != dspVersion)) return -EIO; } return 0; } Loading @@ -348,9 +347,9 @@ static int tda10045_fwupload(struct dvb_frontend* fe) int ret; const struct firmware *fw; /* don't re-upload unless necessary */ if (tda1004x_check_upload_ok(state, 0x2c) == 0) return 0; if (tda1004x_check_upload_ok(state, 0x2c) == 0) return 0; /* request the firmware, this will block until someone uploads it */ printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE); Loading Loading @@ -394,7 +393,8 @@ static int tda10046_fwupload(struct dvb_frontend* fe) msleep(100); /* don't re-upload unless necessary */ if (tda1004x_check_upload_ok(state, 0x20) == 0) return 0; if (tda1004x_check_upload_ok(state, 0x20) == 0) return 0; /* request the firmware, this will block until someone uploads it */ printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10046_DEFAULT_FIRMWARE); Loading Loading @@ -483,7 +483,8 @@ static int tda10045_init(struct dvb_frontend* fe) dprintk("%s\n", __FUNCTION__); if (state->initialised) return 0; if (state->initialised) return 0; if (tda10045_fwupload(fe)) { printk("tda1004x: firmware upload failed\n"); Loading Loading @@ -523,7 +524,8 @@ static int tda10046_init(struct dvb_frontend* fe) struct tda1004x_state* state = fe->demodulator_priv; dprintk("%s\n", __FUNCTION__); if (state->initialised) return 0; if (state->initialised) return 0; if (tda10046_fwupload(fe)) { printk("tda1004x: firmware upload failed\n"); Loading Loading @@ -621,12 +623,14 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, // set HP FEC tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP); if (tmp < 0) return tmp; if (tmp < 0) return tmp; tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp); // set LP FEC tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP); if (tmp < 0) return tmp; if (tmp < 0) return tmp; tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3); // set constellation Loading Loading @@ -683,7 +687,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, // set inversion inversion = fe_params->inversion; if (state->config->invert) inversion = inversion ? INVERSION_OFF : INVERSION_ON; if (state->config->invert) inversion = inversion ? INVERSION_OFF : INVERSION_ON; switch (inversion) { case INVERSION_OFF: tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0); Loading Loading @@ -754,15 +759,15 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, case TDA1004X_DEMOD_TDA10045: tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0); msleep(10); break; case TDA1004X_DEMOD_TDA10046: tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40); msleep(10); break; } msleep(10); return 0; } Loading @@ -773,10 +778,10 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete // inversion status fe_params->inversion = INVERSION_OFF; if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20) { if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20) fe_params->inversion = INVERSION_ON; } if (state->config->invert) fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON; if (state->config->invert) fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON; // bandwidth switch (state->demod_type) { Loading Loading @@ -830,9 +835,8 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete // transmission mode fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10) { if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10) fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; } // guard interval switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) { Loading Loading @@ -880,52 +884,57 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status // read status status = tda1004x_read_byte(state, TDA1004X_STATUS_CD); if (status == -1) { if (status == -1) return -EIO; } // decode *fe_status = 0; if (status & 4) *fe_status |= FE_HAS_SIGNAL; if (status & 2) *fe_status |= FE_HAS_CARRIER; if (status & 8) *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; if (status & 4) *fe_status |= FE_HAS_SIGNAL; if (status & 2) *fe_status |= FE_HAS_CARRIER; if (status & 8) *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi // is getting anything valid if (!(*fe_status & FE_HAS_VITERBI)) { // read the CBER cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB); if (cber == -1) return -EIO; if (cber == -1) return -EIO; status = tda1004x_read_byte(state, TDA1004X_CBER_MSB); if (status == -1) return -EIO; if (status == -1) return -EIO; cber |= (status << 8); tda1004x_read_byte(state, TDA1004X_CBER_RESET); if (cber != 65535) { if (cber != 65535) *fe_status |= FE_HAS_VITERBI; } } // if we DO have some valid VITERBI output, but don't already have SYNC // bytes (i.e. not LOCKED), see if the RS decoder is getting anything valid. if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) { // read the VBER vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB); if (vber == -1) return -EIO; if (vber == -1) return -EIO; status = tda1004x_read_byte(state, TDA1004X_VBER_MID); if (status == -1) return -EIO; if (status == -1) return -EIO; vber |= (status << 8); status = tda1004x_read_byte(state, TDA1004X_VBER_MSB); if (status == -1) return -EIO; if (status == -1) return -EIO; vber |= ((status << 16) & 0x0f); tda1004x_read_byte(state, TDA1004X_CVBER_LUT); // if RS has passed some valid TS packets, then we must be // getting some SYNC bytes if (vber < 16632) { if (vber < 16632) *fe_status |= FE_HAS_SYNC; } } // success dprintk("%s: fe_status=0x%x\n", __FUNCTION__, *fe_status); Loading Loading @@ -972,9 +981,8 @@ static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr) tmp = tda1004x_read_byte(state, TDA1004X_SNR); if (tmp < 0) return -EIO; if (tmp) { if (tmp) tmp = 255 - tmp; } *snr = ((tmp << 8) | tmp); dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr); Loading Loading @@ -1009,11 +1017,11 @@ static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) break; } if (tmp != 0x7f) { if (tmp != 0x7f) *ucblocks = tmp; } else { else *ucblocks = 0xffffffff; } dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks); return 0; } Loading @@ -1027,10 +1035,12 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber) // read it in tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB); if (tmp < 0) return -EIO; if (tmp < 0) return -EIO; *ber = tmp << 1; tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB); if (tmp < 0) return -EIO; if (tmp < 0) return -EIO; *ber |= (tmp << 9); tda1004x_read_byte(state, TDA1004X_CBER_RESET); Loading Loading @@ -1066,74 +1076,11 @@ static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronte static void tda1004x_release(struct dvb_frontend* fe) { struct tda1004x_state* state = (struct tda1004x_state*) fe->demodulator_priv; kfree(state); } static struct dvb_frontend_ops tda10045_ops; struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { struct tda1004x_state* state = NULL; /* allocate memory for the internal state */ state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); if (state == NULL) goto error; /* setup the state */ state->config = config; state->i2c = i2c; memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); state->initialised = 0; state->demod_type = TDA1004X_DEMOD_TDA10045; /* check if the demod is there */ if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) goto error; /* create dvb_frontend */ state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; error: struct tda1004x_state *state = fe->demodulator_priv; kfree(state); return NULL; } static struct dvb_frontend_ops tda10046_ops; struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { struct tda1004x_state* state = NULL; /* allocate memory for the internal state */ state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); if (state == NULL) goto error; /* setup the state */ state->config = config; state->i2c = i2c; memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); state->initialised = 0; state->demod_type = TDA1004X_DEMOD_TDA10046; /* check if the demod is there */ if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) goto error; /* create dvb_frontend */ state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; error: if (state) kfree(state); return NULL; } static struct dvb_frontend_ops tda10045_ops = { .info = { .name = "Philips TDA10045H DVB-T", .type = FE_OFDM, Loading Loading @@ -1163,8 +1110,36 @@ static struct dvb_frontend_ops tda10045_ops = { .read_ucblocks = tda1004x_read_ucblocks, }; static struct dvb_frontend_ops tda10046_ops = { struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { struct tda1004x_state *state; /* allocate memory for the internal state */ state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); if (!state) return NULL; /* setup the state */ state->config = config; state->i2c = i2c; memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); state->initialised = 0; state->demod_type = TDA1004X_DEMOD_TDA10045; /* check if the demod is there */ if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) { kfree(state); return NULL; } /* create dvb_frontend */ state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; } static struct dvb_frontend_ops tda10046_ops = { .info = { .name = "Philips TDA10046H DVB-T", .type = FE_OFDM, Loading Loading @@ -1194,6 +1169,35 @@ static struct dvb_frontend_ops tda10046_ops = { .read_ucblocks = tda1004x_read_ucblocks, }; struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, struct i2c_adapter* i2c) { struct tda1004x_state *state; /* allocate memory for the internal state */ state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); if (!state) return NULL; /* setup the state */ state->config = config; state->i2c = i2c; memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); state->initialised = 0; state->demod_type = TDA1004X_DEMOD_TDA10046; /* check if the demod is there */ if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) { kfree(state); return NULL; } /* create dvb_frontend */ state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; return &state->frontend; } module_param(debug, int, 0644); MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); Loading