summaryrefslogtreecommitdiff
path: root/v4l_experimental/pvrusb2/pvrusb2-tuner.c
diff options
context:
space:
mode:
Diffstat (limited to 'v4l_experimental/pvrusb2/pvrusb2-tuner.c')
-rw-r--r--v4l_experimental/pvrusb2/pvrusb2-tuner.c168
1 files changed, 61 insertions, 107 deletions
diff --git a/v4l_experimental/pvrusb2/pvrusb2-tuner.c b/v4l_experimental/pvrusb2/pvrusb2-tuner.c
index c84200ab6..232f083fd 100644
--- a/v4l_experimental/pvrusb2/pvrusb2-tuner.c
+++ b/v4l_experimental/pvrusb2/pvrusb2-tuner.c
@@ -1,6 +1,6 @@
/*
*
- * $Id: pvrusb2-tuner.c,v 1.6 2005/12/07 06:53:52 mcisely Exp $
+ * $Id: pvrusb2-tuner.c,v 1.7 2006/01/01 08:26:03 mcisely Exp $
*
* Copyright (C) 2005 Mike Isely <isely@pobox.com>
* Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
@@ -24,137 +24,91 @@
#include "pvrusb2-util.h"
#include "pvrusb2-tuner.h"
#include "pvrusb2-hdw-internal.h"
-#include "pvrusb2-i2c.h"
#include "pvrusb2-debug.h"
#include "compat.h"
#include <linux/videodev.h>
#include <media/tuner.h>
-#define PVR_STD_I2C_ADDR 0x43
-static int tuner[PVR_NUM] = { [0 ... PVR_NUM-1] = -1 };
-
-module_param_array(tuner, int, NULL, 0444);
-MODULE_PARM_DESC(tuner,"specify installed tuner type");
-
-static u32 pvr_tbl_standard[] = {
- [PVR2_CVAL_VIDEOSTANDARD_PAL_BG] = 0x00d47009, /* PVR_STD_PAL_BG */
- [PVR2_CVAL_VIDEOSTANDARD_PAL_I] = 0x00d4700a, /* PVR_STD_PAL_I */
- [PVR2_CVAL_VIDEOSTANDARD_PAL_DK] = 0x00d4700b, /* PVR_STD_PAL_DK */
- [PVR2_CVAL_VIDEOSTANDARD_SECAM_L] = 0x00c4100b, /* PVR_STD_SECAM */
- [PVR2_CVAL_VIDEOSTANDARD_NTSC_M] = 0x00163044, /* PVR_STD_NTSC */
- [PVR2_CVAL_VIDEOSTANDARD_PAL_M] = 0x00163044 /* PVR_STD_PAL_M */
+struct pvr2_tuner_handler {
+ struct pvr2_hdw *hdw;
+ struct pvr2_i2c_client *client;
+ struct pvr2_i2c_handler i2c_handler;
+ int type_update_fl;
};
-#define trace_tuner(...) pvr2_trace(PVR2_TRACE_TUNER,__VA_ARGS__)
-
-int pvr2_tuner_get_default_type(struct pvr2_hdw *hdw)
-{
- int unit_number = hdw->unit_number;
- int tp = -1;
- if ((unit_number >= 0) && (unit_number < PVR_NUM)) {
- tp = tuner[unit_number];
- }
- if (tp < 0) return -EINVAL;
- hdw->tuner_type = tp;
- return 0;
-}
-
-int pvr2_tuner_set_freq(struct pvr2_hdw *hdw)
-{
- int stat;
- struct v4l2_frequency freq;
- memset(&freq,0,sizeof(freq));
- freq.frequency = hdw->controls[PVR2_CID_FREQUENCY].value / 62500;
- freq.tuner = 0;
- freq.type = V4L2_TUNER_ANALOG_TV;
- trace_tuner("pvr2_tuner_set_freq(%d)",freq.frequency);
- stat = pvr2_i2c_tuner_cmd(hdw,VIDIOC_S_FREQUENCY,&freq);
- if (stat < 0) return stat;
- /* This kicks the audio controller... */
- stat = pvr2_i2c_msp3400_cmd(hdw,VIDIOCSFREQ,0);
- if (stat < 0) return stat;
- /* Smack around tda9887 as well, if it is lurking nearby */
- if (hdw->i2c_ifhandler_client) {
- pvr2_i2c_ifhandler_cmd(hdw,VIDIOC_S_FREQUENCY,&freq);
- }
- hdw->subsys_enabled_mask |= PVR2_SUBSYS_TUNER_CFG_FREQ;
- return 0;
-}
-int pvr2_tuner_set_type(struct pvr2_hdw *hdw)
+static void set_type(struct pvr2_tuner_handler *ctxt)
{
+ struct pvr2_hdw *hdw = ctxt->hdw;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
struct tuner_setup setup;
#endif
- trace_tuner("pvr2_tuner_set_type(%d)",hdw->tuner_type);
- if (((int)(hdw->tuner_type)) < 0) {
- trace_tuner("tuner type not set yet");
- return 0;
- }
+ pvr2_trace(PVR2_TRACE_CHIPS,"i2c tuner set_type(%d)",hdw->tuner_type);
+ if (((int)(hdw->tuner_type)) < 0) return;
+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 13)
setup.addr = ADDR_UNSET;
setup.type = hdw->tuner_type;
setup.mode_mask = T_RADIO | T_ANALOG_TV;
/* We may really want mode_mask to be T_ANALOG_TV for now */
- return pvr2_i2c_tuner_cmd(hdw,TUNER_SET_TYPE_ADDR,&setup);
+ pvr2_i2c_client_cmd(ctxt->client,TUNER_SET_TYPE_ADDR,&setup);
#else
- return pvr2_i2c_tuner_cmd(hdw,TUNER_SET_TYPE,&hdw->tuner_type);
+ pvr2_i2c_tuner_cmd(ctxt->client,TUNER_SET_TYPE,&hdw->tuner_type);
#endif
+ ctxt->type_update_fl = 0;
+}
+
+
+static int tuner_check(struct pvr2_tuner_handler *ctxt)
+{
+ struct pvr2_hdw *hdw = ctxt->hdw;
+ if (hdw->tuner_updated) ctxt->type_update_fl = !0;
+ return ctxt->type_update_fl != 0;
+}
+
+
+static void tuner_update(struct pvr2_tuner_handler *ctxt)
+{
+ if (ctxt->type_update_fl) set_type(ctxt);
}
-int pvr2_tuner_set_standard(struct pvr2_hdw *hdw)
+
+static void pvr2_tuner_detach(struct pvr2_tuner_handler *ctxt)
{
- struct i2c_msg msg[1];
- u8 buff [4];
- v4l2_std_id vs;
- int cvstd = hdw->controls[PVR2_CID_VIDEOSTANDARD].value;
-
- trace_tuner("pvr2_tuner_set_standard(%d)",
- hdw->controls[PVR2_CID_VIDEOSTANDARD].value);
-
- /* FIXME: Might be tuner dependant ? Need more hardware info... */
- /* MCI 15-May-2005: I have absolutely no idea what this is doing
- or who it is talking to. */
- PVR2_DECOMPOSE_BE(
- buff, 0,pvr_tbl_standard[cvstd]);
- msg[0].addr = PVR_STD_I2C_ADDR;
- msg[0].flags = 0;
- msg[0].len = sizeof(buff);
- msg[0].buf = buff;
- i2c_transfer(&hdw->i2c_adap,msg,sizeof(msg)/sizeof(msg[0]));
-
- /* Also tell tuner.ko about the video standard. */
- switch (cvstd) {
- default:
- case PVR2_CVAL_VIDEOSTANDARD_NTSC_M:
- vs = V4L2_STD_NTSC_M;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_SECAM_L:
- vs = V4L2_STD_SECAM;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_BG:
- vs = V4L2_STD_PAL_BG;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_I:
- vs = V4L2_STD_PAL_I;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_DK:
- vs = V4L2_STD_PAL_DK;
- break;
- case PVR2_CVAL_VIDEOSTANDARD_PAL_M:
- vs = V4L2_STD_PAL_M;
- break;
- }
- pvr2_i2c_tuner_cmd(hdw,VIDIOC_S_STD,&vs);
- if (hdw->i2c_ifhandler_client) {
- pvr2_i2c_ifhandler_cmd(hdw,VIDIOC_S_STD,&vs);
- }
-
- hdw->subsys_enabled_mask |= PVR2_SUBSYS_TUNER_CFG_STD;
- return 0;
+ ctxt->client->handler = 0;
+ kfree(ctxt);
}
+
+const static struct pvr2_i2c_handler_functions tuner_funcs = {
+ .detach = (void (*)(void *))pvr2_tuner_detach,
+ .check = (int (*)(void *))tuner_check,
+ .update = (void (*)(void *))tuner_update,
+};
+
+
+int pvr2_i2c_tuner_setup(struct pvr2_hdw *hdw,struct pvr2_i2c_client *cp)
+{
+ struct pvr2_tuner_handler *ctxt;
+ if (cp->handler) return 0;
+
+ ctxt = kmalloc(sizeof(*ctxt),GFP_KERNEL);
+ if (!ctxt) return 0;
+ memset(ctxt,0,sizeof(*ctxt));
+
+ ctxt->i2c_handler.func_data = ctxt;
+ ctxt->i2c_handler.func_table = &tuner_funcs;
+ ctxt->type_update_fl = !0;
+ ctxt->client = cp;
+ ctxt->hdw = hdw;
+ cp->handler = &ctxt->i2c_handler;
+ return !0;
+}
+
+
+
+
/*
Stuff for Emacs to see, in order to encourage consistent editing style:
*** Local Variables: ***