static int fdtv_ca_get_msg(struct firedtv *fdtv, void *arg) { struct firedtv_tuner_status stat; int err; switch (fdtv->ca_last_command) { case EN50221_TAG_APP_INFO_ENQUIRY: err = fdtv_ca_app_info(fdtv, arg); break; case EN50221_TAG_CA_INFO_ENQUIRY: err = fdtv_ca_info(fdtv, arg); break; default: err = avc_tuner_status(fdtv, &stat); if (err) break; if (stat.ca_mmi == 1) err = fdtv_ca_get_mmi(fdtv, arg); else { dev_info(fdtv->device, "unhandled CA message 0x%08x\n", fdtv->ca_last_command); err = -EACCES; } } fdtv->ca_last_command = 0; return err; }
static int fdtv_ca_ioctl(struct file *file, unsigned int cmd, void *arg) { struct dvb_device *dvbdev = file->private_data; struct firedtv *fdtv = dvbdev->priv; struct firedtv_tuner_status stat; int err; switch (cmd) { case CA_RESET: err = avc_ca_reset(fdtv); break; case CA_GET_CAP: err = fdtv_ca_get_caps(arg); break; case CA_GET_SLOT_INFO: err = fdtv_ca_get_slot_info(fdtv, arg); break; case CA_GET_MSG: err = fdtv_ca_get_msg(fdtv, arg); break; case CA_SEND_MSG: err = fdtv_ca_send_msg(fdtv, arg); break; default: dev_info(fdtv->device, "unhandled CA ioctl %u\n", cmd); err = -EOPNOTSUPP; } /* FIXME Is this necessary? */ avc_tuner_status(fdtv, &stat); return err; }
static int fdtv_read_signal_strength(struct dvb_frontend *fe, u16 *strength) { struct firedtv *fdtv = fe->sec_priv; struct firedtv_tuner_status stat; if (avc_tuner_status(fdtv, &stat)) return -EINVAL; *strength = stat.signal_strength << 8; return 0; }
static int fdtv_read_ber(struct dvb_frontend *fe, u32 *ber) { struct firedtv *fdtv = fe->sec_priv; struct firedtv_tuner_status stat; if (avc_tuner_status(fdtv, &stat)) return -EINVAL; *ber = stat.ber; return 0; }
static int fdtv_read_snr(struct dvb_frontend *fe, u16 *snr) { struct firedtv *fdtv = fe->sec_priv; struct firedtv_tuner_status stat; if (avc_tuner_status(fdtv, &stat)) return -EINVAL; /* C/N[dB] = -10 * log10(snr / 65535) */ *snr = stat.carrier_noise_ratio * 257; return 0; }
static int fdtv_ca_get_slot_info(struct firedtv *fdtv, void *arg) { struct firedtv_tuner_status stat; struct ca_slot_info *slot = arg; if (avc_tuner_status(fdtv, &stat)) return -EFAULT; if (slot->num != 0) return -EFAULT; slot->type = CA_CI; slot->flags = fdtv_get_ca_flags(&stat); return 0; }
static int fdtv_read_status(struct dvb_frontend *fe, fe_status_t *status) { struct firedtv *fdtv = fe->sec_priv; struct firedtv_tuner_status stat; if (avc_tuner_status(fdtv, &stat)) return -EINVAL; if (stat.no_rf) *status = 0; else *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; return 0; }
int fdtv_ca_register(struct firedtv *fdtv) { struct firedtv_tuner_status stat; int err; if (avc_tuner_status(fdtv, &stat)) return -EINVAL; if (!fdtv_ca_ready(&stat)) return -EFAULT; err = dvb_register_device(&fdtv->adapter, &fdtv->cadev, &fdtv_ca, fdtv, DVB_DEVICE_CA); if (stat.ca_application_info == 0) dev_err(fdtv->device, "CaApplicationInfo is not set\n"); if (stat.ca_date_time_request == 1) avc_ca_get_time_date(fdtv, &fdtv->ca_time_interval); return err; }