]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - drivers/media/video/tlg2300/pd-radio.c
V4L/DVB: tlg2300: remove the country code for analog tv and radio
[mirror_ubuntu-bionic-kernel.git] / drivers / media / video / tlg2300 / pd-radio.c
index bdbb0c11b3a900b6a3301d4774aa54fbfb0328ed..755766b15157119440e12b5ac7cefae4ff2b3dc6 100644 (file)
@@ -22,9 +22,16 @@ static int poseidon_fm_open(struct file *filp);
 #define TUNER_FREQ_MIN_FM 76000000
 #define TUNER_FREQ_MAX_FM 108000000
 
+#define MAX_PREEMPHASIS (V4L2_PREEMPHASIS_75_uS + 1)
+static int preemphasis[MAX_PREEMPHASIS] = {
+       TLG_TUNE_ASTD_NONE,   /* V4L2_PREEMPHASIS_DISABLED */
+       TLG_TUNE_ASTD_FM_EUR, /* V4L2_PREEMPHASIS_50_uS    */
+       TLG_TUNE_ASTD_FM_US,  /* V4L2_PREEMPHASIS_75_uS    */
+};
+
 static int poseidon_check_mode_radio(struct poseidon *p)
 {
-       int ret, radiomode;
+       int ret;
        u32 status;
 
        set_current_state(TASK_INTERRUPTIBLE);
@@ -38,8 +45,8 @@ static int poseidon_check_mode_radio(struct poseidon *p)
                goto out;
 
        ret = send_set_req(p, SGNL_SRC_SEL, TLG_SIG_SRC_ANTENNA, &status);
-       radiomode = get_audio_std(TLG_MODE_FM_RADIO, p->country_code);
-       ret = send_set_req(p, TUNER_AUD_ANA_STD, radiomode, &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,
@@ -91,7 +98,9 @@ static int poseidon_fm_open(struct file *filp)
 
        usb_autopm_get_interface(p->interface);
        if (0 == p->state) {
-               p->country_code = country_code;
+               /* default pre-emphasis */
+               if (p->radio_data.pre_emphasis == 0)
+                       p->radio_data.pre_emphasis = TLG_TUNE_ASTD_FM_EUR;
                set_debug_mode(vfd, debug_mode);
 
                ret = poseidon_check_mode_radio(p);
@@ -205,13 +214,12 @@ int fm_get_freq(struct file *file, void *priv, struct v4l2_frequency *argp)
 static int set_frequency(struct poseidon *p, __u32 frequency)
 {
        __u32 freq ;
-       int ret, status, radiomode;
+       int ret, status;
 
        mutex_lock(&p->lock);
 
-       radiomode = get_audio_std(TLG_MODE_FM_RADIO, p->country_code);
-       /*NTSC 8,PAL 2 */
-       ret = send_set_req(p, TUNER_AUD_ANA_STD, radiomode, &status);
+       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) {
@@ -253,27 +261,86 @@ int fm_set_freq(struct file *file, void *priv, struct v4l2_frequency *argp)
 int tlg_fm_vidioc_g_ctrl(struct file *file, void *priv,
                struct v4l2_control *arg)
 {
-    return 0;
+       return 0;
+}
+
+int tlg_fm_vidioc_g_exts_ctrl(struct file *file, void *fh,
+                               struct v4l2_ext_controls *ctrls)
+{
+       struct poseidon *p = file->private_data;
+       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 (i < MAX_PREEMPHASIS)
+                       ctrl->value = p->radio_data.pre_emphasis;
+       }
+       return 0;
 }
 
-int tlg_fm_vidioc_exts_ctrl(struct file *file, void *fh,
-               struct v4l2_ext_controls *a)
+int tlg_fm_vidioc_s_exts_ctrl(struct file *file, void *fh,
+                       struct v4l2_ext_controls *ctrls)
 {
-    return 0;
+       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;
 }
 
 int tlg_fm_vidioc_s_ctrl(struct file *file, void *priv,
-               struct v4l2_control *arg)
+               struct v4l2_control *ctrl)
 {
-    return 0;
+       return 0;
 }
 
 int tlg_fm_vidioc_queryctrl(struct file *file, void *priv,
-               struct v4l2_queryctrl *arg)
+               struct v4l2_queryctrl *ctrl)
 {
-       arg->minimum = 0;
-       arg->maximum = 65535;
-       return 0;
+       if (!(ctrl->id & V4L2_CTRL_FLAG_NEXT_CTRL))
+               return -EINVAL;
+
+       ctrl->id &= ~V4L2_CTRL_FLAG_NEXT_CTRL;
+       if (ctrl->id != V4L2_CID_TUNE_PREEMPHASIS) {
+               /* return the next supported control */
+               ctrl->id = V4L2_CID_TUNE_PREEMPHASIS;
+               v4l2_ctrl_query_fill(ctrl, V4L2_PREEMPHASIS_DISABLED,
+                                       V4L2_PREEMPHASIS_75_uS, 1,
+                                       V4L2_PREEMPHASIS_50_uS);
+               ctrl->flags = V4L2_CTRL_FLAG_UPDATE;
+               return 0;
+       }
+       return -EINVAL;
+}
+
+int tlg_fm_vidioc_querymenu(struct file *file, void *fh,
+                               struct v4l2_querymenu *qmenu)
+{
+       return v4l2_ctrl_query_menu(qmenu, NULL, NULL);
 }
 
 static int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *vt)
@@ -311,9 +378,11 @@ static const struct v4l2_ioctl_ops poseidon_fm_ioctl_ops = {
        .vidioc_g_input     = vidioc_g_input,
        .vidioc_s_input     = vidioc_s_input,
        .vidioc_queryctrl   = tlg_fm_vidioc_queryctrl,
+       .vidioc_querymenu   = tlg_fm_vidioc_querymenu,
        .vidioc_g_ctrl      = tlg_fm_vidioc_g_ctrl,
        .vidioc_s_ctrl      = tlg_fm_vidioc_s_ctrl,
-       .vidioc_s_ext_ctrls = tlg_fm_vidioc_exts_ctrl,
+       .vidioc_s_ext_ctrls = tlg_fm_vidioc_s_exts_ctrl,
+       .vidioc_g_ext_ctrls = tlg_fm_vidioc_g_exts_ctrl,
        .vidioc_s_tuner     = vidioc_s_tuner,
        .vidioc_g_tuner     = tlg_fm_vidioc_g_tuner,
        .vidioc_g_frequency = fm_get_freq,