static int poseidon_check_mode_radio(struct poseidon *p) { int ret; u32 status; set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ/2); ret = usb_set_interface(p->udev, 0, BULK_ALTERNATE_IFACE); if (ret < 0) goto out; ret = set_tuner_mode(p, TLG_MODE_FM_RADIO); if (ret != 0) goto out; ret = send_set_req(p, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &status); ret = send_set_req(p, TUNER_AUD_ANA_STD, p->radio_data.pre_emphasis, &status); ret |= send_set_req(p, TUNER_AUD_MODE, TLG_TUNE_TVAUDIO_MODE_STEREO, &status); ret |= send_set_req(p, AUDIO_SAMPLE_RATE_SEL, ATV_AUDIO_RATE_48K, &status); ret |= send_set_req(p, TUNE_FREQ_SELECT, TUNER_FREQ_MIN_FM, &status); out: return ret; }
static int set_frequency(struct poseidon *p, __u32 frequency) { __u32 freq ; int ret, status; mutex_lock(&p->lock); ret = send_set_req(p, TUNER_AUD_ANA_STD, p->radio_data.pre_emphasis, &status); freq = (frequency * 125) * 500 / 1000;/* kHZ */ if (freq < TUNER_FREQ_MIN_FM/1000 || freq > TUNER_FREQ_MAX_FM/1000) { ret = -EINVAL; goto error; } ret = send_set_req(p, TUNE_FREQ_SELECT, freq, &status); if (ret < 0) goto error ; ret = send_set_req(p, TAKE_REQUEST, 0, &status); set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ/4); if (!p->radio_data.is_radio_streaming) { ret = send_set_req(p, TAKE_REQUEST, 0, &status); ret = send_set_req(p, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_START, &status); p->radio_data.is_radio_streaming = 1; } p->radio_data.fm_freq = frequency; error: mutex_unlock(&p->lock); return ret; }
static int tlg_fm_vidioc_s_exts_ctrl(struct file *file, void *fh, struct v4l2_ext_controls *ctrls) { int i; if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX) return -EINVAL; for (i = 0; i < ctrls->count; i++) { struct v4l2_ext_control *ctrl = ctrls->controls + i; if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS) continue; if (ctrl->value >= 0 && ctrl->value < MAX_PREEMPHASIS) { struct poseidon *p = file->private_data; int pre_emphasis = preemphasis[ctrl->value]; u32 status; send_set_req(p, TUNER_AUD_ANA_STD, pre_emphasis, &status); p->radio_data.pre_emphasis = pre_emphasis; } } return 0; }
static int poseidon_set_fe(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) { s32 ret = 0, cmd_status = 0; s32 i, bandwidth = -1; struct poseidon *pd = fe->demodulator_priv; struct pd_dvb_adapter *pd_dvb = &pd->dvb_data; if (in_hibernation(pd)) return -EBUSY; mutex_lock(&pd->lock); for (i = 0; i < dvb_bandwidth_length; i++) if (fep->u.ofdm.bandwidth == dvb_bandwidth[i][1]) bandwidth = dvb_bandwidth[i][0]; if (check_scan_ok(fep->frequency, bandwidth, pd_dvb)) { ret = send_set_req(pd, TUNE_FREQ_SELECT, fep->frequency / 1000, &cmd_status); if (ret | cmd_status) { log("error line"); goto front_out; } ret = send_set_req(pd, DVBT_BANDW_SEL, bandwidth, &cmd_status); if (ret | cmd_status) { log("error line"); goto front_out; } ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status); if (ret | cmd_status) { log("error line"); goto front_out; } /* save the context for future */ memcpy(&pd_dvb->fe_param, fep, sizeof(*fep)); pd_dvb->bandwidth = bandwidth; pd_dvb->prev_freq = fep->frequency; pd_dvb->last_jiffies = jiffies; } front_out: mutex_unlock(&pd->lock); return ret; }
void dvb_stop_streaming(struct pd_dvb_adapter *pd_dvb) { struct poseidon *pd = pd_dvb->pd_device; mutex_lock(&pd->lock); if (pd_dvb->is_streaming) { s32 i, ret, cmd_status = 0; pd_dvb->is_streaming = 0; for (i = 0; i < DVB_SBUF_NUM; i++) if (pd_dvb->urb_array[i]) usb_kill_urb(pd_dvb->urb_array[i]); ret = send_set_req(pd, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP, &cmd_status); if (ret | cmd_status) log("error"); } mutex_unlock(&pd->lock); }
static int poseidon_check_mode_dvbt(struct poseidon *pd) { s32 ret = 0, cmd_status = 0; set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(HZ/4); ret = usb_set_interface(pd->udev, 0, BULK_ALTERNATE_IFACE); if (ret != 0) return ret; ret = set_tuner_mode(pd, TLG_MODE_CAPS_DVB_T); if (ret) return ret; /* signal source */ ret = send_set_req(pd, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &cmd_status); if (ret|cmd_status) return ret; return 0; }
static int poseidon_fm_close(struct file *filp) { struct poseidon *p = filp->private_data; struct radio_data *fm = &p->radio_data; uint32_t status; mutex_lock(&p->lock); fm->users--; if (0 == fm->users) p->state &= ~POSEIDON_STATE_FM; if (fm->is_radio_streaming && filp == p->file_for_stream) { fm->is_radio_streaming = 0; send_set_req(p, PLAY_SERVICE, TLG_TUNE_PLAY_SVC_STOP, &status); } usb_autopm_put_interface(p->interface); mutex_unlock(&p->lock); kref_put(&p->kref, poseidon_delete); filp->private_data = NULL; return 0; }
static s32 dvb_start_streaming(struct pd_dvb_adapter *pd_dvb) { struct poseidon *pd = pd_dvb->pd_device; int ret = 0; if (pd->state & POSEIDON_STATE_DISCONNECT) return -ENODEV; mutex_lock(&pd->lock); if (!pd_dvb->is_streaming) { s32 i, cmd_status = 0; /* * Once upon a time, there was a difficult bug lying here. * ret = send_set_req(pd, TAKE_REQUEST, 0, &cmd_status); */ ret = send_set_req(pd, PLAY_SERVICE, 1, &cmd_status); if (ret | cmd_status) goto out; ret = dvb_urb_init(pd_dvb); if (ret < 0) goto out; pd_dvb->is_streaming = 1; for (i = 0; i < DVB_SBUF_NUM; i++) { ret = usb_submit_urb(pd_dvb->urb_array[i], GFP_KERNEL); if (ret) { log(" submit urb error %d", ret); goto out; } } } out: mutex_unlock(&pd->lock); return ret; }