예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
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;
}
예제 #5
0
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);
}
예제 #6
0
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;
}
예제 #7
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;
}
예제 #8
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;
}