aboutsummaryrefslogtreecommitdiff
path: root/drivers/media/video/pvrusb2
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/video/pvrusb2')
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c16
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c26
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c81
3 files changed, 93 insertions, 30 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index c80c26be6e4..848fb233d80 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -260,6 +260,22 @@ int pvr2_i2c_cx2584x_v4l_setup(struct pvr2_hdw *hdw,
sizeof(decoder_ops[0]))) - 1;
hdw->decoder_ctrl = &ctxt->ctrl;
cp->handler = &ctxt->handler;
+ {
+ /*
+ Mike Isely <isely@pobox.com> 19-Nov-2006 - This bit
+ of nuttiness for cx25840 causes that module to
+ correctly set up its video scaling. This is really
+ a problem in the cx25840 module itself, but we work
+ around it here. The problem has not been seen in
+ ivtv because there VBI is supported and set up. We
+ don't do VBI here (at least not yet) and thus we
+ never attempted to even set it up.
+ */
+ struct v4l2_format fmt;
+ memset(&fmt,0,sizeof(fmt));
+ fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
+ pvr2_i2c_client_cmd(ctxt->client,VIDIOC_S_FMT,&fmt);
+ }
pvr2_trace(PVR2_TRACE_CHIPS,"i2c 0x%x cx2584x V4L2 handler set up",
cp->client->addr);
return !0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 1f787333d18..d2004965187 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -356,28 +356,6 @@ static int ctrl_freq_set(struct pvr2_ctrl *cptr,int m,int v)
return 0;
}
-static int ctrl_hres_max_get(struct pvr2_ctrl *cptr,int *vp)
-{
- /* If we're dealing with a 24xxx device, force the horizontal
- maximum to be 720 no matter what, since we can't get the device
- to work properly with any other value. Otherwise just return
- the normal value. */
- *vp = cptr->info->def.type_int.max_value;
- if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) *vp = 720;
- return 0;
-}
-
-static int ctrl_hres_min_get(struct pvr2_ctrl *cptr,int *vp)
-{
- /* If we're dealing with a 24xxx device, force the horizontal
- minimum to be 720 no matter what, since we can't get the device
- to work properly with any other value. Otherwise just return
- the normal value. */
- *vp = cptr->info->def.type_int.min_value;
- if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) *vp = 720;
- return 0;
-}
-
static int ctrl_vres_max_get(struct pvr2_ctrl *cptr,int *vp)
{
/* Actual maximum depends on the video standard in effect. */
@@ -758,10 +736,6 @@ static const struct pvr2_ctl_info control_defs[] = {
.default_value = 720,
DEFREF(res_hor),
DEFINT(19,720),
- /* Hook in check for clamp on horizontal resolution in
- order to avoid unsolved problem involving cx25840. */
- .get_max_value = ctrl_hres_max_get,
- .get_min_value = ctrl_hres_min_get,
},{
.desc = "Vertical capture resolution",
.name = "resolution_ver",
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 3b9012f8e38..f9bb41d8f4f 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -185,6 +185,79 @@ static int pvr2_i2c_basic_op(struct pvr2_hdw *hdw,
}
}
+
+/* This is a special entry point for cases of I2C transaction attempts to
+ the IR receiver. The implementation here simulates the IR receiver by
+ issuing a command to the FX2 firmware and using that response to return
+ what the real I2C receiver would have returned. We use this for 24xxx
+ devices, where the IR receiver chip has been removed and replaced with
+ FX2 related logic. */
+static int i2c_24xxx_ir(struct pvr2_hdw *hdw,
+ u8 i2c_addr,u8 *wdata,u16 wlen,u8 *rdata,u16 rlen)
+{
+ u8 dat[4];
+ unsigned int stat;
+
+ if (!(rlen || wlen)) {
+ /* This is a probe attempt. Just let it succeed. */
+ return 0;
+ }
+
+ /* We don't understand this kind of transaction */
+ if ((wlen != 0) || (rlen == 0)) return -EIO;
+
+ if (rlen < 3) {
+ /* Mike Isely <isely@pobox.com> Appears to be a probe
+ attempt from lirc. Just fill in zeroes and return. If
+ we try instead to do the full transaction here, then bad
+ things seem to happen within the lirc driver module
+ (version 0.8.0-7 sources from Debian, when run under
+ vanilla 2.6.17.6 kernel) - and I don't have the patience
+ to chase it down. */
+ if (rlen > 0) rdata[0] = 0;
+ if (rlen > 1) rdata[1] = 0;
+ return 0;
+ }
+
+ /* Issue a command to the FX2 to read the IR receiver. */
+ LOCK_TAKE(hdw->ctl_lock); do {
+ hdw->cmd_buffer[0] = 0xec;
+ stat = pvr2_send_request(hdw,
+ hdw->cmd_buffer,1,
+ hdw->cmd_buffer,4);
+ dat[0] = hdw->cmd_buffer[0];
+ dat[1] = hdw->cmd_buffer[1];
+ dat[2] = hdw->cmd_buffer[2];
+ dat[3] = hdw->cmd_buffer[3];
+ } while (0); LOCK_GIVE(hdw->ctl_lock);
+
+ /* Give up if that operation failed. */
+ if (stat != 0) return stat;
+
+ /* Mangle the results into something that looks like the real IR
+ receiver. */
+ rdata[2] = 0xc1;
+ if (dat[0] != 1) {
+ /* No code received. */
+ rdata[0] = 0;
+ rdata[1] = 0;
+ } else {
+ u16 val;
+ /* Mash the FX2 firmware-provided IR code into something
+ that the normal i2c chip-level driver expects. */
+ val = dat[1];
+ val <<= 8;
+ val |= dat[2];
+ val >>= 1;
+ val &= ~0x0003;
+ val |= 0x8000;
+ rdata[0] = (val >> 8) & 0xffu;
+ rdata[1] = val & 0xffu;
+ }
+
+ return 0;
+}
+
/* This is a special entry point that is entered if an I2C operation is
attempted to a wm8775 chip on model 24xxx hardware. Autodetect of this
part doesn't work, but we know it is really there. So let's look for
@@ -887,17 +960,17 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
{
unsigned int idx;
- // The default action for all possible I2C addresses is just to do
- // the transfer normally.
+ /* The default action for all possible I2C addresses is just to do
+ the transfer normally. */
for (idx = 0; idx < PVR2_I2C_FUNC_CNT; idx++) {
hdw->i2c_func[idx] = pvr2_i2c_basic_op;
}
- // If however we're dealing with new hardware, insert some hacks in
- // the I2C transfer stack to let things work better.
+ /* However, deal with various special cases for 24xxx hardware. */
if (hdw->hdw_type == PVR2_HDW_TYPE_24XXX) {
hdw->i2c_func[0x1b] = i2c_hack_wm8775;
hdw->i2c_func[0x44] = i2c_hack_cx25840;
+ hdw->i2c_func[0x18] = i2c_24xxx_ir;
}
// Configure the adapter and set up everything else related to it.