summaryrefslogtreecommitdiff
path: root/drivers/media/common/tuners/xc5000.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-09 19:50:49 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-09 19:50:49 -0800
commit3e7468313758913c5e4d372f35b271b96bad1298 (patch)
treeeb612d252a9e2349a1173451cd779beebd18a33e /drivers/media/common/tuners/xc5000.c
parent6825fbc4cb219f2c98bb7d157915d797cf5cb823 (diff)
parente97f4677961f68e29bd906022ebf60a6df7f530a (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (345 commits) V4L/DVB (13542): ir-keytable: Allow dynamic table change V4L/DVB (13541): atbm8830: replace 64-bit division and floating point usage V4L/DVB (13540): ir-common: Cleanup get key evdev code V4L/DVB (13539): ir-common: add __func__ for debug messages V4L/DVB (13538): ir-common: Use a dynamic keycode table V4L/DVB (13537): ir: Prepare the code for dynamic keycode table allocation V4L/DVB (13536): em28xx: Use the full RC5 code on HVR-950 Remote Controller V4L/DVB (13535): ir-common: Add a hauppauge new table with the complete RC5 code V4L/DVB (13534): ir-common: Remove some unused fields/structs V4L/DVB (13533): ir: use dynamic tables, instead of static ones V4L/DVB (13532): ir-common: Add infrastructure to use a dynamic keycode table V4L/DVB (13531): ir-common: rename the debug routine to allow exporting it V4L/DVB (13458): go7007: subdev conversion V4L/DVB (13457): s2250: subdev conversion V4L/DVB (13456): s2250: Change module structure V4L/DVB (13528): em28xx: add support for em2800 VC211A card em28xx: don't reduce scale to half size for em2800 em28xx: don't load audio modules when AC97 is mis-detected em28xx: em2800 chips support max width of 640 V4L/DVB (13523): dvb-bt8xx: fix compile warning ... Fix up trivial conflicts due to spelling fixes from the trivial tree in Documentation/video4linux/gspca.txt drivers/media/video/cx18/cx18-mailbox.h
Diffstat (limited to 'drivers/media/common/tuners/xc5000.c')
-rw-r--r--drivers/media/common/tuners/xc5000.c97
1 files changed, 91 insertions, 6 deletions
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index f4ffcdc9b848..432003dded7c 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -61,6 +61,7 @@ struct xc5000_priv {
u32 bandwidth;
u8 video_standard;
u8 rf_mode;
+ u8 radio_input;
};
/* Misc Defines */
@@ -632,8 +633,12 @@ static int xc5000_set_params(struct dvb_frontend *fe,
struct xc5000_priv *priv = fe->tuner_priv;
int ret;
- if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
- xc_load_fw_and_init_tuner(fe);
+ if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
+ if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
+ dprintk(1, "Unable to load firmware and init tuner\n");
+ return -EINVAL;
+ }
+ }
dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
@@ -739,15 +744,12 @@ static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
return ret;
}
-static int xc5000_set_analog_params(struct dvb_frontend *fe,
+static int xc5000_set_tv_freq(struct dvb_frontend *fe,
struct analog_parameters *params)
{
struct xc5000_priv *priv = fe->tuner_priv;
int ret;
- if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
- xc_load_fw_and_init_tuner(fe);
-
dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
__func__, params->frequency);
@@ -827,6 +829,86 @@ tune_channel:
return 0;
}
+static int xc5000_set_radio_freq(struct dvb_frontend *fe,
+ struct analog_parameters *params)
+{
+ struct xc5000_priv *priv = fe->tuner_priv;
+ int ret = -EINVAL;
+ u8 radio_input;
+
+ dprintk(1, "%s() frequency=%d (in units of khz)\n",
+ __func__, params->frequency);
+
+ if (priv->radio_input == XC5000_RADIO_NOT_CONFIGURED) {
+ dprintk(1, "%s() radio input not configured\n", __func__);
+ return -EINVAL;
+ }
+
+ if (priv->radio_input == XC5000_RADIO_FM1)
+ radio_input = FM_Radio_INPUT1;
+ else if (priv->radio_input == XC5000_RADIO_FM2)
+ radio_input = FM_Radio_INPUT2;
+ else {
+ dprintk(1, "%s() unknown radio input %d\n", __func__,
+ priv->radio_input);
+ return -EINVAL;
+ }
+
+ priv->freq_hz = params->frequency * 125 / 2;
+
+ priv->rf_mode = XC_RF_MODE_AIR;
+
+ ret = xc_SetTVStandard(priv, XC5000_Standard[radio_input].VideoMode,
+ XC5000_Standard[radio_input].AudioMode);
+
+ if (ret != XC_RESULT_SUCCESS) {
+ printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
+ return -EREMOTEIO;
+ }
+
+ ret = xc_SetSignalSource(priv, priv->rf_mode);
+ if (ret != XC_RESULT_SUCCESS) {
+ printk(KERN_ERR
+ "xc5000: xc_SetSignalSource(%d) failed\n",
+ priv->rf_mode);
+ return -EREMOTEIO;
+ }
+
+ xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
+
+ return 0;
+}
+
+static int xc5000_set_analog_params(struct dvb_frontend *fe,
+ struct analog_parameters *params)
+{
+ struct xc5000_priv *priv = fe->tuner_priv;
+ int ret = -EINVAL;
+
+ if (priv->i2c_props.adap == NULL)
+ return -EINVAL;
+
+ if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
+ if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
+ dprintk(1, "Unable to load firmware and init tuner\n");
+ return -EINVAL;
+ }
+ }
+
+ switch (params->mode) {
+ case V4L2_TUNER_RADIO:
+ ret = xc5000_set_radio_freq(fe, params);
+ break;
+ case V4L2_TUNER_ANALOG_TV:
+ case V4L2_TUNER_DIGITAL_TV:
+ ret = xc5000_set_tv_freq(fe, params);
+ break;
+ }
+
+ return ret;
+}
+
+
static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
{
struct xc5000_priv *priv = fe->tuner_priv;
@@ -1000,6 +1082,9 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
priv->if_khz = cfg->if_khz;
}
+ if (priv->radio_input == 0)
+ priv->radio_input = cfg->radio_input;
+
/* Check if firmware has been loaded. It is possible that another
instance of the driver has loaded the firmware.
*/