[media] xc4000: implemented analog TV and radio
authorIstvan Varga <istvan_v@mailbox.hu>
Sat, 4 Jun 2011 15:17:22 +0000 (12:17 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Wed, 27 Jul 2011 20:52:39 +0000 (17:52 -0300)
The following patch implements support for analog TV and FM radio.

Signed-off-by: Istvan Varga <istvan_v@mailbox.hu>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
drivers/media/common/tuners/xc4000.c

index 2a20d0e63da6108c95c1a7633dcbe9a4a16860ea..52375498257c457a7cba0f5a9d57d51acccbe042 100644 (file)
@@ -1283,69 +1283,150 @@ static int xc4000_set_analog_params(struct dvb_frontend *fe,
        struct analog_parameters *params)
 {
        struct xc4000_priv *priv = fe->tuner_priv;
+       unsigned int type = 0;
        int     ret = -EREMOTEIO;
 
+       if (params->mode == V4L2_TUNER_RADIO) {
+               dprintk(1, "%s() frequency=%d (in units of 62.5Hz)\n",
+                       __func__, params->frequency);
+
+               mutex_lock(&priv->lock);
+
+               params->std = 0;
+               priv->freq_hz = params->frequency * 125L / 2;
+
+               if (audio_std & XC4000_AUDIO_STD_INPUT1) {
+                       priv->video_standard = XC4000_FM_Radio_INPUT1;
+                       type = FM | INPUT1;
+               } else {
+                       priv->video_standard = XC4000_FM_Radio_INPUT2;
+                       type = FM | INPUT2;
+               }
+
+               goto tune_channel;
+       }
+
        dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
                __func__, params->frequency);
 
        mutex_lock(&priv->lock);
 
-       /* Fix me: it could be air. */
-       priv->rf_mode = params->mode;
-       if (params->mode > XC_RF_MODE_CABLE)
-               priv->rf_mode = XC_RF_MODE_CABLE;
-
        /* params->frequency is in units of 62.5khz */
        priv->freq_hz = params->frequency * 62500;
 
-       /* FIX ME: Some video standards may have several possible audio
-                  standards. We simply default to one of them here.
-        */
+       params->std &= V4L2_STD_ALL;
+       /* if std is not defined, choose one */
+       if (!params->std)
+               params->std = V4L2_STD_PAL_BG;
+
+       if (audio_std & XC4000_AUDIO_STD_MONO)
+               type = MONO;
+
        if (params->std & V4L2_STD_MN) {
-               /* default to BTSC audio standard */
-               priv->video_standard = XC4000_MN_NTSC_PAL_BTSC;
+               params->std = V4L2_STD_MN;
+               if (audio_std & XC4000_AUDIO_STD_MONO) {
+                       priv->video_standard = XC4000_MN_NTSC_PAL_Mono;
+               } else if (audio_std & XC4000_AUDIO_STD_A2) {
+                       params->std |= V4L2_STD_A2;
+                       priv->video_standard = XC4000_MN_NTSC_PAL_A2;
+               } else {
+                       params->std |= V4L2_STD_BTSC;
+                       priv->video_standard = XC4000_MN_NTSC_PAL_BTSC;
+               }
                goto tune_channel;
        }
 
        if (params->std & V4L2_STD_PAL_BG) {
-               /* default to NICAM audio standard */
-               priv->video_standard = XC4000_BG_PAL_NICAM;
+               params->std = V4L2_STD_PAL_BG;
+               if (audio_std & XC4000_AUDIO_STD_MONO) {
+                       priv->video_standard = XC4000_BG_PAL_MONO;
+               } else if (!(audio_std & XC4000_AUDIO_STD_A2)) {
+                       if (!(audio_std & XC4000_AUDIO_STD_B)) {
+                               params->std |= V4L2_STD_NICAM_A;
+                               priv->video_standard = XC4000_BG_PAL_NICAM;
+                       } else {
+                               params->std |= V4L2_STD_NICAM_B;
+                               priv->video_standard = XC4000_BG_PAL_NICAM;
+                       }
+               } else {
+                       if (!(audio_std & XC4000_AUDIO_STD_B)) {
+                               params->std |= V4L2_STD_A2_A;
+                               priv->video_standard = XC4000_BG_PAL_A2;
+                       } else {
+                               params->std |= V4L2_STD_A2_B;
+                               priv->video_standard = XC4000_BG_PAL_A2;
+                       }
+               }
                goto tune_channel;
        }
 
        if (params->std & V4L2_STD_PAL_I) {
                /* default to NICAM audio standard */
-               priv->video_standard = XC4000_I_PAL_NICAM;
+               params->std = V4L2_STD_PAL_I | V4L2_STD_NICAM;
+               if (audio_std & XC4000_AUDIO_STD_MONO) {
+                       priv->video_standard = XC4000_I_PAL_NICAM_MONO;
+               } else {
+                       priv->video_standard = XC4000_I_PAL_NICAM;
+               }
                goto tune_channel;
        }
 
        if (params->std & V4L2_STD_PAL_DK) {
-               /* default to NICAM audio standard */
-               priv->video_standard = XC4000_DK_PAL_NICAM;
+               params->std = V4L2_STD_PAL_DK;
+               if (audio_std & XC4000_AUDIO_STD_MONO) {
+                       priv->video_standard = XC4000_DK_PAL_MONO;
+               } else if (audio_std & XC4000_AUDIO_STD_A2) {
+                       params->std |= V4L2_STD_A2;
+                       priv->video_standard = XC4000_DK_PAL_A2;
+               } else {
+                       params->std |= V4L2_STD_NICAM;
+                       priv->video_standard = XC4000_DK_PAL_NICAM;
+               }
                goto tune_channel;
        }
 
        if (params->std & V4L2_STD_SECAM_DK) {
-               /* default to A2 DK1 audio standard */
-               priv->video_standard = XC4000_DK_SECAM_A2DK1;
+               /* default to A2 audio standard */
+               params->std = V4L2_STD_SECAM_DK | V4L2_STD_A2;
+               if (audio_std & XC4000_AUDIO_STD_L) {
+                       type = 0;
+                       priv->video_standard = XC4000_DK_SECAM_NICAM;
+               } else if (audio_std & XC4000_AUDIO_STD_MONO) {
+                       priv->video_standard = XC4000_DK_SECAM_A2MONO;
+               } else if (audio_std & XC4000_AUDIO_STD_K3) {
+                       params->std |= V4L2_STD_SECAM_K3;
+                       priv->video_standard = XC4000_DK_SECAM_A2LDK3;
+               } else {
+                       priv->video_standard = XC4000_DK_SECAM_A2DK1;
+               }
                goto tune_channel;
        }
 
        if (params->std & V4L2_STD_SECAM_L) {
+               /* default to NICAM audio standard */
+               type = 0;
+               params->std = V4L2_STD_SECAM_L | V4L2_STD_NICAM;
                priv->video_standard = XC4000_L_SECAM_NICAM;
                goto tune_channel;
        }
 
        if (params->std & V4L2_STD_SECAM_LC) {
+               /* default to NICAM audio standard */
+               type = 0;
+               params->std = V4L2_STD_SECAM_LC | V4L2_STD_NICAM;
                priv->video_standard = XC4000_LC_SECAM_NICAM;
                goto tune_channel;
        }
 
 tune_channel:
+       /* Fix me: it could be air. */
+       priv->rf_mode = XC_RF_MODE_CABLE;
 
-       /* FIXME - firmware type not being set properly */
-       if (check_firmware(fe, DTV8, 0, priv->if_khz) != XC_RESULT_SUCCESS)
+       if (check_firmware(fe, type, params->std,
+                          XC4000_Standard[priv->video_standard].int_freq)
+           != XC_RESULT_SUCCESS) {
                goto fail;
+       }
 
        ret = xc_SetSignalSource(priv, priv->rf_mode);
        if (ret != XC_RESULT_SUCCESS) {