Commit f7b80e69 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

V4L/DVB: ivtv: convert to the new control framework

Signed-off-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 2fd78144
...@@ -17,163 +17,14 @@ ...@@ -17,163 +17,14 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <linux/kernel.h>
#include <linux/slab.h>
#include "ivtv-driver.h" #include "ivtv-driver.h"
#include "ivtv-cards.h"
#include "ivtv-ioctl.h" #include "ivtv-ioctl.h"
#include "ivtv-routing.h"
#include "ivtv-i2c.h"
#include "ivtv-mailbox.h"
#include "ivtv-controls.h" #include "ivtv-controls.h"
/* Must be sorted from low to high control ID! */ static int ivtv_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt)
static const u32 user_ctrls[] = {
V4L2_CID_USER_CLASS,
V4L2_CID_BRIGHTNESS,
V4L2_CID_CONTRAST,
V4L2_CID_SATURATION,
V4L2_CID_HUE,
V4L2_CID_AUDIO_VOLUME,
V4L2_CID_AUDIO_BALANCE,
V4L2_CID_AUDIO_BASS,
V4L2_CID_AUDIO_TREBLE,
V4L2_CID_AUDIO_MUTE,
V4L2_CID_AUDIO_LOUDNESS,
0
};
static const u32 *ctrl_classes[] = {
user_ctrls,
cx2341x_mpeg_ctrls,
NULL
};
int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
{
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
const char *name;
qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
if (qctrl->id == 0)
return -EINVAL;
switch (qctrl->id) {
/* Standard V4L2 controls */
case V4L2_CID_USER_CLASS:
return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
case V4L2_CID_BRIGHTNESS:
case V4L2_CID_HUE:
case V4L2_CID_SATURATION:
case V4L2_CID_CONTRAST:
if (v4l2_subdev_call(itv->sd_video, core, queryctrl, qctrl))
qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
return 0;
case V4L2_CID_AUDIO_VOLUME:
case V4L2_CID_AUDIO_MUTE:
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_LOUDNESS:
if (v4l2_subdev_call(itv->sd_audio, core, queryctrl, qctrl))
qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
return 0;
default:
if (cx2341x_ctrl_query(&itv->params, qctrl))
qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
return 0;
}
strncpy(qctrl->name, name, sizeof(qctrl->name) - 1);
qctrl->name[sizeof(qctrl->name) - 1] = 0;
return 0;
}
int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu)
{
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
struct v4l2_queryctrl qctrl;
qctrl.id = qmenu->id;
ivtv_queryctrl(file, fh, &qctrl);
return v4l2_ctrl_query_menu(qmenu, &qctrl,
cx2341x_ctrl_get_menu(&itv->params, qmenu->id));
}
static int ivtv_try_ctrl(struct file *file, void *fh,
struct v4l2_ext_control *vctrl)
{
struct v4l2_queryctrl qctrl;
const char **menu_items = NULL;
int err;
qctrl.id = vctrl->id;
err = ivtv_queryctrl(file, fh, &qctrl);
if (err)
return err;
if (qctrl.type == V4L2_CTRL_TYPE_MENU)
menu_items = v4l2_ctrl_get_menu(qctrl.id);
return v4l2_ctrl_check(vctrl, &qctrl, menu_items);
}
static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
{
switch (vctrl->id) {
/* Standard V4L2 controls */
case V4L2_CID_BRIGHTNESS:
case V4L2_CID_HUE:
case V4L2_CID_SATURATION:
case V4L2_CID_CONTRAST:
return v4l2_subdev_call(itv->sd_video, core, s_ctrl, vctrl);
case V4L2_CID_AUDIO_VOLUME:
case V4L2_CID_AUDIO_MUTE:
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_LOUDNESS:
return v4l2_subdev_call(itv->sd_audio, core, s_ctrl, vctrl);
default:
IVTV_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
return -EINVAL;
}
return 0;
}
static int ivtv_g_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
{ {
switch (vctrl->id) { struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl);
/* Standard V4L2 controls */
case V4L2_CID_BRIGHTNESS:
case V4L2_CID_HUE:
case V4L2_CID_SATURATION:
case V4L2_CID_CONTRAST:
return v4l2_subdev_call(itv->sd_video, core, g_ctrl, vctrl);
case V4L2_CID_AUDIO_VOLUME:
case V4L2_CID_AUDIO_MUTE:
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_LOUDNESS:
return v4l2_subdev_call(itv->sd_audio, core, g_ctrl, vctrl);
default:
IVTV_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
return -EINVAL;
}
return 0;
}
static int ivtv_setup_vbi_fmt(struct ivtv *itv, enum v4l2_mpeg_stream_vbi_fmt fmt)
{
if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE))
return -EINVAL;
if (atomic_read(&itv->capturing) > 0)
return -EBUSY;
/* First try to allocate sliced VBI buffers if needed. */ /* First try to allocate sliced VBI buffers if needed. */
if (fmt && itv->vbi.sliced_mpeg_data[0] == NULL) { if (fmt && itv->vbi.sliced_mpeg_data[0] == NULL) {
...@@ -208,106 +59,43 @@ static int ivtv_setup_vbi_fmt(struct ivtv *itv, enum v4l2_mpeg_stream_vbi_fmt fm ...@@ -208,106 +59,43 @@ static int ivtv_setup_vbi_fmt(struct ivtv *itv, enum v4l2_mpeg_stream_vbi_fmt fm
return 0; return 0;
} }
int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) static int ivtv_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val)
{ {
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl);
struct v4l2_control ctrl; int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
struct v4l2_mbus_framefmt fmt;
if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
int i; /* fix videodecoder resolution */
int err = 0; fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1);
fmt.height = cxhdl->height;
for (i = 0; i < c->count; i++) { fmt.code = V4L2_MBUS_FMT_FIXED;
ctrl.id = c->controls[i].id; v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &fmt);
ctrl.value = c->controls[i].value; return 0;
err = ivtv_g_ctrl(itv, &ctrl);
c->controls[i].value = ctrl.value;
if (err) {
c->error_idx = i;
break;
}
}
return err;
}
if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
return cx2341x_ext_ctrls(&itv->params, 0, c, VIDIOC_G_EXT_CTRLS);
return -EINVAL;
} }
int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) static int ivtv_s_audio_sampling_freq(struct cx2341x_handler *cxhdl, u32 idx)
{ {
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; static const u32 freqs[3] = { 44100, 48000, 32000 };
struct v4l2_control ctrl; struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl);
if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
int i;
int err = 0;
for (i = 0; i < c->count; i++) {
ctrl.id = c->controls[i].id;
ctrl.value = c->controls[i].value;
err = ivtv_s_ctrl(itv, &ctrl);
c->controls[i].value = ctrl.value;
if (err) {
c->error_idx = i;
break;
}
}
return err;
}
if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
static u32 freqs[3] = { 44100, 48000, 32000 };
struct cx2341x_mpeg_params p = itv->params;
int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), c, VIDIOC_S_EXT_CTRLS);
unsigned idx;
if (err)
return err;
if (p.video_encoding != itv->params.video_encoding) { /* The audio clock of the digitizer must match the codec sample
int is_mpeg1 = p.video_encoding == rate otherwise you get some very strange effects. */
V4L2_MPEG_VIDEO_ENCODING_MPEG_1; if (idx < ARRAY_SIZE(freqs))
struct v4l2_mbus_framefmt fmt; ivtv_call_all(itv, audio, s_clock_freq, freqs[idx]);
return 0;
/* fix videodecoder resolution */
fmt.width = itv->params.width / (is_mpeg1 ? 2 : 1);
fmt.height = itv->params.height;
fmt.code = V4L2_MBUS_FMT_FIXED;
v4l2_subdev_call(itv->sd_video, video, s_mbus_fmt, &fmt);
}
err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p);
if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt)
err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_fmt);
itv->params = p;
itv->dualwatch_stereo_mode = p.audio_properties & 0x0300;
idx = p.audio_properties & 0x03;
/* The audio clock of the digitizer must match the codec sample
rate otherwise you get some very strange effects. */
if (idx < ARRAY_SIZE(freqs))
ivtv_call_all(itv, audio, s_clock_freq, freqs[idx]);
return err;
}
return -EINVAL;
} }
int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) static int ivtv_s_audio_mode(struct cx2341x_handler *cxhdl, u32 val)
{ {
struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; struct ivtv *itv = container_of(cxhdl, struct ivtv, cxhdl);
if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { itv->dualwatch_stereo_mode = val;
int i; return 0;
int err = 0;
for (i = 0; i < c->count; i++) {
err = ivtv_try_ctrl(file, fh, &c->controls[i]);
if (err) {
c->error_idx = i;
break;
}
}
return err;
}
if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), c, VIDIOC_TRY_EXT_CTRLS);
return -EINVAL;
} }
struct cx2341x_handler_ops ivtv_cxhdl_ops = {
.s_audio_mode = ivtv_s_audio_mode,
.s_audio_sampling_freq = ivtv_s_audio_sampling_freq,
.s_video_encoding = ivtv_s_video_encoding,
.s_stream_vbi_fmt = ivtv_s_stream_vbi_fmt,
};
...@@ -21,10 +21,6 @@ ...@@ -21,10 +21,6 @@
#ifndef IVTV_CONTROLS_H #ifndef IVTV_CONTROLS_H
#define IVTV_CONTROLS_H #define IVTV_CONTROLS_H
int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a); extern struct cx2341x_handler_ops ivtv_cxhdl_ops;
int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a);
int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a);
int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a);
int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *a);
#endif #endif
...@@ -53,6 +53,7 @@ ...@@ -53,6 +53,7 @@
#include "ivtv-cards.h" #include "ivtv-cards.h"
#include "ivtv-vbi.h" #include "ivtv-vbi.h"
#include "ivtv-routing.h" #include "ivtv-routing.h"
#include "ivtv-controls.h"
#include "ivtv-gpio.h" #include "ivtv-gpio.h"
#include <media/tveeprom.h> #include <media/tveeprom.h>
...@@ -734,9 +735,8 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv) ...@@ -734,9 +735,8 @@ static int __devinit ivtv_init_struct1(struct ivtv *itv)
itv->open_id = 1; itv->open_id = 1;
/* Initial settings */ /* Initial settings */
cx2341x_fill_defaults(&itv->params); itv->cxhdl.port = CX2341X_PORT_MEMORY;
itv->params.port = CX2341X_PORT_MEMORY; itv->cxhdl.capabilities = CX2341X_CAP_HAS_SLICED_VBI;
itv->params.capabilities = CX2341X_CAP_HAS_SLICED_VBI;
init_waitqueue_head(&itv->eos_waitq); init_waitqueue_head(&itv->eos_waitq);
init_waitqueue_head(&itv->event_waitq); init_waitqueue_head(&itv->event_waitq);
init_waitqueue_head(&itv->vsync_waitq); init_waitqueue_head(&itv->vsync_waitq);
...@@ -1006,6 +1006,13 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, ...@@ -1006,6 +1006,13 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
retval = -ENOMEM; retval = -ENOMEM;
goto err; goto err;
} }
retval = cx2341x_handler_init(&itv->cxhdl, 50);
if (retval)
goto err;
itv->v4l2_dev.ctrl_handler = &itv->cxhdl.hdl;
itv->cxhdl.ops = &ivtv_cxhdl_ops;
itv->cxhdl.priv = itv;
itv->cxhdl.func = ivtv_api_func;
IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr); IVTV_DEBUG_INFO("base addr: 0x%08x\n", itv->base_addr);
...@@ -1127,7 +1134,7 @@ static int __devinit ivtv_probe(struct pci_dev *pdev, ...@@ -1127,7 +1134,7 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
itv->yuv_info.v4l2_src_w = itv->yuv_info.osd_full_w; itv->yuv_info.v4l2_src_w = itv->yuv_info.osd_full_w;
itv->yuv_info.v4l2_src_h = itv->yuv_info.osd_full_h; itv->yuv_info.v4l2_src_h = itv->yuv_info.osd_full_h;
itv->params.video_gop_size = itv->is_60hz ? 15 : 12; cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_MPG] = 0x08000; itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_MPG] = 0x08000;
itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_PCM] = 0x01200; itv->stream_buf_size[IVTV_ENC_STREAM_TYPE_PCM] = 0x01200;
...@@ -1322,6 +1329,8 @@ int ivtv_init_on_first_open(struct ivtv *itv) ...@@ -1322,6 +1329,8 @@ int ivtv_init_on_first_open(struct ivtv *itv)
/* For cards with video out, this call needs interrupts enabled */ /* For cards with video out, this call needs interrupts enabled */
ivtv_s_std(NULL, &fh, &itv->tuner_std); ivtv_s_std(NULL, &fh, &itv->tuner_std);
/* Setup initial controls */
cx2341x_handler_setup(&itv->cxhdl);
return 0; return 0;
} }
...@@ -1386,7 +1395,6 @@ static void ivtv_remove(struct pci_dev *pdev) ...@@ -1386,7 +1395,6 @@ static void ivtv_remove(struct pci_dev *pdev)
printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name); printk(KERN_INFO "ivtv: Removed %s\n", itv->card_name);
v4l2_device_unregister(&itv->v4l2_dev); v4l2_device_unregister(&itv->v4l2_dev);
v4l2_ctrl_handler_free(&itv->hdl_gpio);
kfree(itv); kfree(itv);
} }
......
...@@ -62,6 +62,7 @@ ...@@ -62,6 +62,7 @@
#include <linux/dvb/audio.h> #include <linux/dvb/audio.h>
#include <media/v4l2-common.h> #include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h> #include <media/v4l2-ioctl.h>
#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h> #include <media/v4l2-device.h>
#include <media/v4l2-fh.h> #include <media/v4l2-fh.h>
#include <media/tuner.h> #include <media/tuner.h>
...@@ -631,8 +632,9 @@ struct ivtv { ...@@ -631,8 +632,9 @@ struct ivtv {
struct ivtv_options options; /* user options */ struct ivtv_options options; /* user options */
struct v4l2_device v4l2_dev; struct v4l2_device v4l2_dev;
struct v4l2_subdev sd_gpio; /* GPIO sub-device */ struct cx2341x_handler cxhdl;
struct v4l2_ctrl_handler hdl_gpio; struct v4l2_ctrl_handler hdl_gpio;
struct v4l2_subdev sd_gpio; /* GPIO sub-device */
u16 instance; u16 instance;
/* High-level state info */ /* High-level state info */
...@@ -649,7 +651,6 @@ struct ivtv { ...@@ -649,7 +651,6 @@ struct ivtv {
v4l2_std_id std_out; /* current TV output standard */ v4l2_std_id std_out; /* current TV output standard */
u8 audio_stereo_mode; /* decoder setting how to handle stereo MPEG audio */ u8 audio_stereo_mode; /* decoder setting how to handle stereo MPEG audio */
u8 audio_bilingual_mode; /* decoder setting how to handle bilingual MPEG audio */ u8 audio_bilingual_mode; /* decoder setting how to handle bilingual MPEG audio */
struct cx2341x_mpeg_params params; /* current encoder parameters */
/* Locking */ /* Locking */
......
...@@ -150,12 +150,10 @@ void ivtv_release_stream(struct ivtv_stream *s) ...@@ -150,12 +150,10 @@ void ivtv_release_stream(struct ivtv_stream *s)
static void ivtv_dualwatch(struct ivtv *itv) static void ivtv_dualwatch(struct ivtv *itv)
{ {
struct v4l2_tuner vt; struct v4l2_tuner vt;
u32 new_bitmap;
u32 new_stereo_mode; u32 new_stereo_mode;
const u32 stereo_mask = 0x0300; const u32 dual = 0x02;
const u32 dual = 0x0200;
new_stereo_mode = itv->params.audio_properties & stereo_mask; new_stereo_mode = v4l2_ctrl_g_ctrl(itv->cxhdl.audio_mode);
memset(&vt, 0, sizeof(vt)); memset(&vt, 0, sizeof(vt));
ivtv_call_all(itv, tuner, g_tuner, &vt); ivtv_call_all(itv, tuner, g_tuner, &vt);
if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 && (vt.rxsubchans & V4L2_TUNER_SUB_LANG2)) if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 && (vt.rxsubchans & V4L2_TUNER_SUB_LANG2))
...@@ -164,16 +162,10 @@ static void ivtv_dualwatch(struct ivtv *itv) ...@@ -164,16 +162,10 @@ static void ivtv_dualwatch(struct ivtv *itv)
if (new_stereo_mode == itv->dualwatch_stereo_mode) if (new_stereo_mode == itv->dualwatch_stereo_mode)
return; return;
new_bitmap = new_stereo_mode | (itv->params.audio_properties & ~stereo_mask); IVTV_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n",
itv->dualwatch_stereo_mode, new_stereo_mode);
IVTV_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x. new audio_bitmask=0x%ux\n", if (v4l2_ctrl_s_ctrl(itv->cxhdl.audio_mode, new_stereo_mode))
itv->dualwatch_stereo_mode, new_stereo_mode, new_bitmap); IVTV_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
if (ivtv_vapi(itv, CX2341X_ENC_SET_AUDIO_PROPERTIES, 1, new_bitmap) == 0) {
itv->dualwatch_stereo_mode = new_stereo_mode;
return;
}
IVTV_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
} }
static void ivtv_update_pgm_info(struct ivtv *itv) static void ivtv_update_pgm_info(struct ivtv *itv)
...@@ -894,7 +886,8 @@ int ivtv_v4l2_close(struct file *filp) ...@@ -894,7 +886,8 @@ int ivtv_v4l2_close(struct file *filp)
if (atomic_read(&itv->capturing) > 0) { if (atomic_read(&itv->capturing) > 0) {
/* Undo video mute */ /* Undo video mute */
ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
itv->params.video_mute | (itv->params.video_mute_yuv << 8)); v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute) |
(v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8));
} }
/* Done! Unmute and continue. */ /* Done! Unmute and continue. */
ivtv_unmute(itv); ivtv_unmute(itv);
......
...@@ -248,9 +248,9 @@ void ivtv_init_mpeg_decoder(struct ivtv *itv) ...@@ -248,9 +248,9 @@ void ivtv_init_mpeg_decoder(struct ivtv *itv)
volatile u8 __iomem *mem_offset; volatile u8 __iomem *mem_offset;
data[0] = 0; data[0] = 0;
data[1] = itv->params.width; /* YUV source width */ data[1] = itv->cxhdl.width; /* YUV source width */
data[2] = itv->params.height; data[2] = itv->cxhdl.height;
data[3] = itv->params.audio_properties; /* Audio settings to use, data[3] = itv->cxhdl.audio_properties; /* Audio settings to use,
bitmap. see docs. */ bitmap. see docs. */
if (ivtv_api(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, data)) { if (ivtv_api(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, data)) {
IVTV_ERR("ivtv_init_mpeg_decoder failed to set decoder source\n"); IVTV_ERR("ivtv_init_mpeg_decoder failed to set decoder source\n");
......
...@@ -162,7 +162,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed) ...@@ -162,7 +162,7 @@ int ivtv_set_speed(struct ivtv *itv, int speed)
data[0] |= (speed > 1000 || speed < -1500) ? 0x40000000 : 0; data[0] |= (speed > 1000 || speed < -1500) ? 0x40000000 : 0;
data[1] = (speed < 0); data[1] = (speed < 0);
data[2] = speed < 0 ? 3 : 7; data[2] = speed < 0 ? 3 : 7;
data[3] = itv->params.video_b_frames; data[3] = v4l2_ctrl_g_ctrl(itv->cxhdl.video_b_frames);
data[4] = (speed == 1500 || speed == 500) ? itv->speed_mute_audio : 0; data[4] = (speed == 1500 || speed == 500) ? itv->speed_mute_audio : 0;
data[5] = 0; data[5] = 0;
data[6] = 0; data[6] = 0;
...@@ -339,8 +339,8 @@ static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f ...@@ -339,8 +339,8 @@ static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
struct ivtv *itv = id->itv; struct ivtv *itv = id->itv;
struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
pixfmt->width = itv->params.width; pixfmt->width = itv->cxhdl.width;
pixfmt->height = itv->params.height; pixfmt->height = itv->cxhdl.height;
pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
pixfmt->field = V4L2_FIELD_INTERLACED; pixfmt->field = V4L2_FIELD_INTERLACED;
pixfmt->priv = 0; pixfmt->priv = 0;
...@@ -568,7 +568,6 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f ...@@ -568,7 +568,6 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
{ {
struct ivtv_open_id *id = fh; struct ivtv_open_id *id = fh;
struct ivtv *itv = id->itv; struct ivtv *itv = id->itv;
struct cx2341x_mpeg_params *p = &itv->params;
struct v4l2_mbus_framefmt mbus_fmt; struct v4l2_mbus_framefmt mbus_fmt;
int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
int w = fmt->fmt.pix.width; int w = fmt->fmt.pix.width;
...@@ -577,15 +576,15 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f ...@@ -577,15 +576,15 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
if (ret) if (ret)
return ret; return ret;
if (p->width == w && p->height == h) if (itv->cxhdl.width == w && itv->cxhdl.height == h)
return 0; return 0;
if (atomic_read(&itv->capturing) > 0) if (atomic_read(&itv->capturing) > 0)
return -EBUSY; return -EBUSY;
p->width = w; itv->cxhdl.width = w;
p->height = h; itv->cxhdl.height = h;
if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) if (v4l2_ctrl_g_ctrl(itv->cxhdl.video_encoding) == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
fmt->fmt.pix.width /= 2; fmt->fmt.pix.width /= 2;
mbus_fmt.width = fmt->fmt.pix.width; mbus_fmt.width = fmt->fmt.pix.width;
mbus_fmt.height = h; mbus_fmt.height = h;
...@@ -1114,9 +1113,10 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) ...@@ -1114,9 +1113,10 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
itv->std = *std; itv->std = *std;
itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0; itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
itv->params.is_50hz = itv->is_50hz = !itv->is_60hz; itv->is_50hz = !itv->is_60hz;
itv->params.width = 720; cx2341x_handler_set_50hz(&itv->cxhdl, itv->is_50hz);
itv->params.height = itv->is_50hz ? 576 : 480; itv->cxhdl.width = 720;
itv->cxhdl.height = itv->is_50hz ? 576 : 480;
itv->vbi.count = itv->is_50hz ? 18 : 12; itv->vbi.count = itv->is_50hz ? 18 : 12;
itv->vbi.start[0] = itv->is_50hz ? 6 : 10; itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
itv->vbi.start[1] = itv->is_50hz ? 318 : 273; itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
...@@ -1157,7 +1157,7 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) ...@@ -1157,7 +1157,7 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz); ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
itv->main_rect.left = itv->main_rect.top = 0; itv->main_rect.left = itv->main_rect.top = 0;
itv->main_rect.width = 720; itv->main_rect.width = 720;
itv->main_rect.height = itv->params.height; itv->main_rect.height = itv->cxhdl.height;
ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
720, itv->main_rect.height, 0, 0); 720, itv->main_rect.height, 0, 0);
yi->main_rect = itv->main_rect; yi->main_rect = itv->main_rect;
...@@ -1554,7 +1554,7 @@ static int ivtv_log_status(struct file *file, void *fh) ...@@ -1554,7 +1554,7 @@ static int ivtv_log_status(struct file *file, void *fh)
} }
IVTV_INFO("Tuner: %s\n", IVTV_INFO("Tuner: %s\n",
test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
cx2341x_log_status(&itv->params, itv->v4l2_dev.name); v4l2_ctrl_handler_log_status(&itv->cxhdl.hdl, itv->v4l2_dev.name);
IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags); IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
for (i = 0; i < IVTV_MAX_STREAMS; i++) { for (i = 0; i < IVTV_MAX_STREAMS; i++) {
struct ivtv_stream *s = &itv->streams[i]; struct ivtv_stream *s = &itv->streams[i];
...@@ -1942,11 +1942,6 @@ static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { ...@@ -1942,11 +1942,6 @@ static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
.vidioc_s_register = ivtv_s_register, .vidioc_s_register = ivtv_s_register,
#endif #endif
.vidioc_default = ivtv_default, .vidioc_default = ivtv_default,
.vidioc_queryctrl = ivtv_queryctrl,
.vidioc_querymenu = ivtv_querymenu,
.vidioc_g_ext_ctrls = ivtv_g_ext_ctrls,
.vidioc_s_ext_ctrls = ivtv_s_ext_ctrls,
.vidioc_try_ext_ctrls = ivtv_try_ext_ctrls,
.vidioc_subscribe_event = ivtv_subscribe_event, .vidioc_subscribe_event = ivtv_subscribe_event,
.vidioc_unsubscribe_event = v4l2_event_unsubscribe, .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
}; };
......
...@@ -210,6 +210,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type) ...@@ -210,6 +210,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
s->vdev->num = num; s->vdev->num = num;
s->vdev->v4l2_dev = &itv->v4l2_dev; s->vdev->v4l2_dev = &itv->v4l2_dev;
s->vdev->ctrl_handler = itv->v4l2_dev.ctrl_handler;
s->vdev->fops = ivtv_stream_info[type].fops; s->vdev->fops = ivtv_stream_info[type].fops;
s->vdev->release = video_device_release; s->vdev->release = video_device_release;
s->vdev->tvnorms = V4L2_STD_ALL; s->vdev->tvnorms = V4L2_STD_ALL;
...@@ -451,7 +452,6 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) ...@@ -451,7 +452,6 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
{ {
u32 data[CX2341X_MBOX_MAX_DATA]; u32 data[CX2341X_MBOX_MAX_DATA];
struct ivtv *itv = s->itv; struct ivtv *itv = s->itv;
struct cx2341x_mpeg_params *p = &itv->params;
int captype = 0, subtype = 0; int captype = 0, subtype = 0;
int enable_passthrough = 0; int enable_passthrough = 0;
...@@ -472,7 +472,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) ...@@ -472,7 +472,7 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
} }
itv->mpg_data_received = itv->vbi_data_inserted = 0; itv->mpg_data_received = itv->vbi_data_inserted = 0;
itv->dualwatch_jiffies = jiffies; itv->dualwatch_jiffies = jiffies;
itv->dualwatch_stereo_mode = p->audio_properties & 0x0300; itv->dualwatch_stereo_mode = v4l2_ctrl_g_ctrl(itv->cxhdl.audio_mode);
itv->search_pack_header = 0; itv->search_pack_header = 0;
break; break;
...@@ -560,12 +560,12 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) ...@@ -560,12 +560,12 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
itv->pgm_info_offset, itv->pgm_info_num); itv->pgm_info_offset, itv->pgm_info_num);
/* Setup API for Stream */ /* Setup API for Stream */
cx2341x_update(itv, ivtv_api_func, NULL, p); cx2341x_handler_setup(&itv->cxhdl);
/* mute if capturing radio */ /* mute if capturing radio */
if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags))
ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1, ivtv_vapi(itv, CX2341X_ENC_MUTE_VIDEO, 1,
1 | (p->video_mute_yuv << 8)); 1 | (v4l2_ctrl_g_ctrl(itv->cxhdl.video_mute_yuv) << 8));
} }
/* Vsync Setup */ /* Vsync Setup */
...@@ -581,6 +581,8 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s) ...@@ -581,6 +581,8 @@ int ivtv_start_v4l2_encode_stream(struct ivtv_stream *s)
clear_bit(IVTV_F_I_EOS, &itv->i_flags); clear_bit(IVTV_F_I_EOS, &itv->i_flags);
cx2341x_handler_set_busy(&itv->cxhdl, 1);
/* Initialize Digitizer for Capture */ /* Initialize Digitizer for Capture */
/* Avoid tinny audio problem - ensure audio clocks are going */ /* Avoid tinny audio problem - ensure audio clocks are going */
v4l2_subdev_call(itv->sd_audio, audio, s_stream, 1); v4l2_subdev_call(itv->sd_audio, audio, s_stream, 1);
...@@ -617,7 +619,6 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) ...@@ -617,7 +619,6 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
{ {
u32 data[CX2341X_MBOX_MAX_DATA]; u32 data[CX2341X_MBOX_MAX_DATA];
struct ivtv *itv = s->itv; struct ivtv *itv = s->itv;
struct cx2341x_mpeg_params *p = &itv->params;
int datatype; int datatype;
u16 width; u16 width;
u16 height; u16 height;
...@@ -627,8 +628,8 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) ...@@ -627,8 +628,8 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
IVTV_DEBUG_INFO("Setting some initial decoder settings\n"); IVTV_DEBUG_INFO("Setting some initial decoder settings\n");
width = p->width; width = itv->cxhdl.width;
height = p->height; height = itv->cxhdl.height;
/* set audio mode to left/stereo for dual/stereo mode. */ /* set audio mode to left/stereo for dual/stereo mode. */
ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
...@@ -668,7 +669,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s) ...@@ -668,7 +669,7 @@ static int ivtv_setup_v4l2_decode_stream(struct ivtv_stream *s)
break; break;
} }
if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype, if (ivtv_vapi(itv, CX2341X_DEC_SET_DECODER_SOURCE, 4, datatype,
width, height, p->audio_properties)) { width, height, itv->cxhdl.audio_properties)) {
IVTV_DEBUG_WARN("Couldn't initialize decoder source\n"); IVTV_DEBUG_WARN("Couldn't initialize decoder source\n");
} }
...@@ -847,6 +848,8 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end) ...@@ -847,6 +848,8 @@ int ivtv_stop_v4l2_encode_stream(struct ivtv_stream *s, int gop_end)
return 0; return 0;
} }
cx2341x_handler_set_busy(&itv->cxhdl, 0);
/* Set the following Interrupt mask bits for capture */ /* Set the following Interrupt mask bits for capture */
ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE); ivtv_set_irq_mask(itv, IVTV_IRQ_MASK_CAPTURE);
del_timer(&itv->dma_timer); del_timer(&itv->dma_timer);
...@@ -967,7 +970,8 @@ int ivtv_passthrough_mode(struct ivtv *itv, int enable) ...@@ -967,7 +970,8 @@ int ivtv_passthrough_mode(struct ivtv *itv, int enable)
/* Setup capture if not already done */ /* Setup capture if not already done */
if (atomic_read(&itv->capturing) == 0) { if (atomic_read(&itv->capturing) == 0) {
cx2341x_update(itv, ivtv_api_func, NULL, &itv->params); cx2341x_handler_setup(&itv->cxhdl);
cx2341x_handler_set_busy(&itv->cxhdl, 1);
} }
/* Start Passthrough Mode */ /* Start Passthrough Mode */
...@@ -988,6 +992,8 @@ int ivtv_passthrough_mode(struct ivtv *itv, int enable) ...@@ -988,6 +992,8 @@ int ivtv_passthrough_mode(struct ivtv *itv, int enable)
clear_bit(IVTV_F_S_PASSTHROUGH, &dec_stream->s_flags); clear_bit(IVTV_F_S_PASSTHROUGH, &dec_stream->s_flags);
clear_bit(IVTV_F_S_STREAMING, &dec_stream->s_flags); clear_bit(IVTV_F_S_STREAMING, &dec_stream->s_flags);
itv->output_mode = OUT_NONE; itv->output_mode = OUT_NONE;
if (atomic_read(&itv->capturing) == 0)
cx2341x_handler_set_busy(&itv->cxhdl, 0);
return 0; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment