static int poseidon_read_status(struct dvb_frontend *fe, fe_status_t *stat) { struct poseidon *pd = fe->demodulator_priv; s32 ret = -1, cmd_status; struct tuner_dtv_sig_stat_s status = {}; if (in_hibernation(pd)) return -EBUSY; mutex_lock(&pd->lock); ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T, &status, &cmd_status, sizeof(status)); if (ret | cmd_status) { log("get tuner status error"); goto out; } if (debug_mode) log("P : %d, L %d, LB :%d", status.sig_present, status.sig_locked, status.sig_lock_busy); if (status.sig_lock_busy) { goto out; } else if (status.sig_present || status.sig_locked) { *stat |= FE_HAS_LOCK | FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC | FE_HAS_VITERBI; } else { if (fw_delay_overflow(&pd->dvb_data)) *stat |= FE_TIMEDOUT; } out: mutex_unlock(&pd->lock); return ret; }
static int tlg_fm_vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *vt) { struct tuner_fm_sig_stat_s fm_stat = {}; int ret, status, count = 5; struct poseidon *p = file->private_data; if (vt->index != 0) return -EINVAL; vt->type = V4L2_TUNER_RADIO; vt->capability = V4L2_TUNER_CAP_STEREO; vt->rangelow = TUNER_FREQ_MIN_FM / 62500; vt->rangehigh = TUNER_FREQ_MAX_FM / 62500; vt->rxsubchans = V4L2_TUNER_SUB_STEREO; vt->audmode = V4L2_TUNER_MODE_STEREO; vt->signal = 0; vt->afc = 0; mutex_lock(&p->lock); ret = send_get_req(p, TUNER_STATUS, TLG_MODE_FM_RADIO, &fm_stat, &status, sizeof(fm_stat)); while (fm_stat.sig_lock_busy && count-- && !ret) { set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ); ret = send_get_req(p, TUNER_STATUS, TLG_MODE_FM_RADIO, &fm_stat, &status, sizeof(fm_stat)); } mutex_unlock(&p->lock); if (ret || status) { vt->signal = 0; } else if ((fm_stat.sig_present || fm_stat.sig_locked) && fm_stat.sig_strength == 0) { vt->signal = 0xffff; } else vt->signal = (fm_stat.sig_strength * 255 / 10) << 8; return 0; }
static int poseidon_read_ber(struct dvb_frontend *fe, u32 *ber) { struct poseidon *pd = fe->demodulator_priv; struct tuner_ber_rate_s tlg_ber = {}; s32 ret = -1, cmd_status; mutex_lock(&pd->lock); ret = send_get_req(pd, TUNER_BER_RATE, 0, &tlg_ber, &cmd_status, sizeof(tlg_ber)); if (ret | cmd_status) goto out; *ber = tlg_ber.ber_rate; out: mutex_unlock(&pd->lock); return ret; }
static s32 poseidon_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { struct poseidon *pd = fe->demodulator_priv; struct tuner_dtv_sig_stat_s status = {}; s32 ret = 0, cmd_status; mutex_lock(&pd->lock); ret = send_get_req(pd, TUNER_STATUS, TLG_MODE_DVB_T, &status, &cmd_status, sizeof(status)); if (ret | cmd_status) goto out; if ((status.sig_present || status.sig_locked) && !status.sig_strength) *strength = 0xFFFF; else *strength = status.sig_strength; out: mutex_unlock(&pd->lock); return ret; }