#include "cx88.h"
#include <media/v4l2-common.h>
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
/* Include V4L1 specific functions. Should be removed soon */
#include <linux/videodev.h>
-#endif
MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
.minimum = 0x00,
.maximum = 0xff,
.step = 1,
- .default_value = 0x7f,
+ .default_value = 0,
.type = V4L2_CTRL_TYPE_INTEGER,
},
.off = 128,
.minimum = 0,
.maximum = 0xff,
.step = 1,
- .default_value = 0x7f,
+ .default_value = 0,
.type = V4L2_CTRL_TYPE_INTEGER,
},
.off = 128,
.minimum = 0,
.maximum = 0x3f,
.step = 1,
- .default_value = 0x3f,
+ .default_value = 0x1f,
.type = V4L2_CTRL_TYPE_INTEGER,
},
.reg = AUD_VOL_CTL,
};
static const int CX8800_CTLS = ARRAY_SIZE(cx8800_ctls);
-const u32 cx88_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_MUTE,
- 0
-};
-EXPORT_SYMBOL(cx88_user_ctrls);
-
-static const u32 *ctrl_classes[] = {
- cx88_user_ctrls,
- NULL
-};
-
-int cx8800_ctrl_query(struct v4l2_queryctrl *qctrl)
-{
- int i;
-
- if (qctrl->id < V4L2_CID_BASE ||
- qctrl->id >= V4L2_CID_LASTP1)
- return -EINVAL;
- for (i = 0; i < CX8800_CTLS; i++)
- if (cx8800_ctls[i].v.id == qctrl->id)
- break;
- if (i == CX8800_CTLS) {
- *qctrl = no_ctl;
- return 0;
- }
- *qctrl = cx8800_ctls[i].v;
- return 0;
-}
-EXPORT_SYMBOL(cx8800_ctrl_query);
-
-static int cx88_queryctrl(struct v4l2_queryctrl *qctrl)
-{
- qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
- if (qctrl->id == 0)
- return -EINVAL;
- return cx8800_ctrl_query(qctrl);
-}
-
/* ------------------------------------------------------------------- */
/* resource management */
return 1;
/* is it free? */
- mutex_lock(&core->lock);
+ down(&core->lock);
if (dev->resources & bit) {
/* no, someone else uses it */
- mutex_unlock(&core->lock);
+ up(&core->lock);
return 0;
}
/* it's free, grab it */
fh->resources |= bit;
dev->resources |= bit;
dprintk(1,"res: get %d\n",bit);
- mutex_unlock(&core->lock);
+ up(&core->lock);
return 1;
}
void res_free(struct cx8800_dev *dev, struct cx8800_fh *fh, unsigned int bits)
{
struct cx88_core *core = dev->core;
- BUG_ON((fh->resources & bits) != bits);
+ if ((fh->resources & bits) != bits)
+ BUG();
- mutex_lock(&core->lock);
+ down(&core->lock);
fh->resources &= ~bits;
dev->resources &= ~bits;
dprintk(1,"res: put %d\n",bits);
- mutex_unlock(&core->lock);
+ up(&core->lock);
}
/* ------------------------------------------------------------------ */
return 0;
buf = list_entry(q->queued.next, struct cx88_buffer, vb.queue);
if (NULL == prev) {
- list_move_tail(&buf->vb.queue, &q->active);
+ list_del(&buf->vb.queue);
+ list_add_tail(&buf->vb.queue,&q->active);
start_video_dma(dev, q, buf);
buf->vb.state = STATE_ACTIVE;
buf->count = q->count++;
} else if (prev->vb.width == buf->vb.width &&
prev->vb.height == buf->vb.height &&
prev->fmt == buf->fmt) {
- list_move_tail(&buf->vb.queue, &q->active);
+ list_del(&buf->vb.queue);
+ list_add_tail(&buf->vb.queue,&q->active);
buf->vb.state = STATE_ACTIVE;
buf->count = q->count++;
prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
if (STATE_NEEDS_INIT == buf->vb.state) {
init_buffer = 1;
- if (0 != (rc = videobuf_iolock(q,&buf->vb,NULL)))
+ if (0 != (rc = videobuf_iolock(dev->pci,&buf->vb,NULL)))
goto fail;
}
return 0;
fail:
- cx88_free_buffer(q,buf);
+ cx88_free_buffer(dev->pci,buf);
return rc;
}
static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
{
struct cx88_buffer *buf = container_of(vb,struct cx88_buffer,vb);
+ struct cx8800_fh *fh = q->priv_data;
- cx88_free_buffer(q,buf);
+ cx88_free_buffer(fh->dev->pci,buf);
}
static struct videobuf_queue_ops cx8800_video_qops = {
value = c->sreg ? cx_sread(c->sreg) : cx_read(c->reg);
switch (ctl->id) {
case V4L2_CID_AUDIO_BALANCE:
- ctl->value = ((value & 0x7f) < 0x40) ? ((value & 0x7f) + 0x40)
- : (0x7f - (value & 0x7f));
+ ctl->value = (value & 0x40) ? (value & 0x3f) : (0x40 - (value & 0x3f));
break;
case V4L2_CID_AUDIO_VOLUME:
ctl->value = 0x3f - (value & 0x3f);
ctl->value = ((value + (c->off << c->shift)) & c->mask) >> c->shift;
break;
}
- dprintk(1,"get_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
- ctl->id, c->v.name, ctl->value, c->reg,
- value,c->mask, c->sreg ? " [shadowed]" : "");
+ printk("get_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
+ ctl->id, c->reg, ctl->value,
+ c->mask, c->sreg ? " [shadowed]" : "");
return 0;
}
mask=c->mask;
switch (ctl->id) {
case V4L2_CID_AUDIO_BALANCE:
- value = (ctl->value < 0x40) ? (0x7f - ctl->value) : (ctl->value - 0x40);
+ value = (ctl->value < 0x40) ? (0x40 - ctl->value) : ctl->value;
break;
case V4L2_CID_AUDIO_VOLUME:
value = 0x3f - (ctl->value & 0x3f);
value = ((ctl->value - c->off) << c->shift) & c->mask;
break;
}
- dprintk(1,"set_control id=0x%X(%s) ctrl=0x%02x, reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
- ctl->id, c->v.name, ctl->value, c->reg, value,
- mask, c->sreg ? " [shadowed]" : "");
+ printk("set_control id=0x%X reg=0x%02x val=0x%02x (mask 0x%02x)%s\n",
+ ctl->id, c->reg, value,
+ mask, c->sreg ? " [shadowed]" : "");
if (c->sreg) {
cx_sandor(c->sreg, c->reg, mask, value);
} else {
for (i = 0; i < CX8800_CTLS; i++) {
ctrl.id=cx8800_ctls[i].v.id;
- ctrl.value=cx8800_ctls[i].v.default_value;
+ ctrl.value=cx8800_ctls[i].v.default_value
+ +cx8800_ctls[i].off;
set_control(core, &ctrl);
}
}
V4L2_CAP_READWRITE |
V4L2_CAP_STREAMING |
V4L2_CAP_VBI_CAPTURE |
+ V4L2_CAP_VIDEO_OVERLAY |
0;
if (UNSET != core->tuner_type)
cap->capabilities |= V4L2_CAP_TUNER;
struct v4l2_format *f = arg;
return cx8800_try_fmt(dev,fh,f);
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
+#ifdef HAVE_V4L1
/* --- streaming capture ------------------------------------- */
case VIDIOCGMBUF:
{
{
int err;
- if (video_debug) {
- if (video_debug > 1) {
- if (_IOC_DIR(cmd) & _IOC_WRITE)
- v4l_printk_ioctl_arg("cx88(w)",cmd, arg);
- else if (!_IOC_DIR(cmd) & _IOC_READ) {
- v4l_print_ioctl("cx88", cmd);
- }
- } else
- v4l_print_ioctl(core->name,cmd);
-
- }
+ dprintk( 1, "CORE IOCTL: 0x%x\n", cmd );
+ if (video_debug > 1)
+ v4l_print_ioctl(core->name,cmd);
switch (cmd) {
/* ---------- tv norms ---------- */
if (i == ARRAY_SIZE(tvnorms))
return -EINVAL;
- mutex_lock(&core->lock);
+ down(&core->lock);
cx88_set_tvnorm(core,&tvnorms[i]);
- mutex_unlock(&core->lock);
+ up(&core->lock);
return 0;
}
if (*i >= 4)
return -EINVAL;
- mutex_lock(&core->lock);
+ down(&core->lock);
cx88_newstation(core);
video_mux(core,*i);
- mutex_unlock(&core->lock);
+ up(&core->lock);
return 0;
}
case VIDIOC_QUERYCTRL:
{
struct v4l2_queryctrl *c = arg;
+ int i;
- return cx88_queryctrl(c);
+ if (c->id < V4L2_CID_BASE ||
+ c->id >= V4L2_CID_LASTP1)
+ return -EINVAL;
+ for (i = 0; i < CX8800_CTLS; i++)
+ if (cx8800_ctls[i].v.id == c->id)
+ break;
+ if (i == CX8800_CTLS) {
+ *c = no_ctl;
+ return 0;
+ }
+ *c = cx8800_ctls[i].v;
+ return 0;
}
case VIDIOC_G_CTRL:
return get_control(core,arg);
return -EINVAL;
if (1 == radio && f->type != V4L2_TUNER_RADIO)
return -EINVAL;
- mutex_lock(&core->lock);
+ down(&core->lock);
core->freq = f->frequency;
cx88_newstation(core);
cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f);
msleep (10);
cx88_set_tvaudio(core);
- mutex_unlock(&core->lock);
+ up(&core->lock);
return 0;
}
static int video_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
- int retval;
-
- retval=video_usercopy(inode, file, cmd, arg, video_do_ioctl);
-
- if (video_debug > 1) {
- if (retval < 0) {
- v4l_print_ioctl("cx88(err)", cmd);
- printk(KERN_DEBUG "cx88(err): errcode=%d\n",retval);
- } else if (_IOC_DIR(cmd) & _IOC_READ)
- v4l_printk_ioctl_arg("cx88(r)",cmd, (void *)arg);
- }
-
- return retval;
+ return video_usercopy(inode, file, cmd, arg, video_do_ioctl);
}
/* ----------------------------------------------------------- */
*id = 0;
return 0;
}
-#ifdef CONFIG_VIDEO_V4L1_COMPAT
+#ifdef HAVE_V4L1
case VIDIOCSTUNER:
{
struct video_tuner *v = arg;
pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
- "latency: %d, mmio: 0x%llx\n", core->name,
+ "latency: %d, mmio: 0x%lx\n", core->name,
pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
- dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0));
+ dev->pci_lat,pci_resource_start(pci_dev,0));
pci_set_master(pci_dev);
if (!pci_dma_supported(pci_dev,0xffffffff)) {
/* get irq */
err = request_irq(pci_dev->irq, cx8800_irq,
- IRQF_SHARED | IRQF_DISABLED, core->name, dev);
+ SA_SHIRQ | SA_INTERRUPT, core->name, dev);
if (err < 0) {
printk(KERN_ERR "%s: can't get IRQ %d\n",
core->name,pci_dev->irq);
/* load and configure helper modules */
if (TUNER_ABSENT != core->tuner_type)
request_module("tuner");
+ if (core->tda9887_conf)
+ request_module("tda9887");
/* register v4l devices */
dev->video_dev = cx88_vdev_init(core,dev->pci,
pci_set_drvdata(pci_dev,dev);
/* initial device configuration */
- mutex_lock(&core->lock);
+ down(&core->lock);
cx88_set_tvnorm(core,tvnorms);
init_controls(core);
video_mux(core,0);
- mutex_unlock(&core->lock);
+ up(&core->lock);
/* start tvaudio thread */
if (core->tuner_type != TUNER_ABSENT)