mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-17 17:53:56 +08:00
V4L/DVB (3325): WSS output interface for av7110
- Implemented v4l2 api for sliced vbi data output to pass WSS data from userspace to the av7110 Signed-off-by: Oliver Endriss <o.endriss@gmx.de> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
This commit is contained in:
parent
d312a46e53
commit
5b0fa4fff1
@ -253,7 +253,10 @@ static int fops_open(struct inode *inode, struct file *file)
|
||||
|
||||
if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
|
||||
DEB_S(("initializing vbi...\n"));
|
||||
result = saa7146_vbi_uops.open(dev,file);
|
||||
if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
|
||||
result = saa7146_vbi_uops.open(dev,file);
|
||||
if (dev->ext_vv_data->vbi_fops.open)
|
||||
dev->ext_vv_data->vbi_fops.open(inode, file);
|
||||
} else {
|
||||
DEB_S(("initializing video...\n"));
|
||||
result = saa7146_video_uops.open(dev,file);
|
||||
@ -289,7 +292,10 @@ static int fops_release(struct inode *inode, struct file *file)
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if( fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
|
||||
saa7146_vbi_uops.release(dev,file);
|
||||
if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
|
||||
saa7146_vbi_uops.release(dev,file);
|
||||
if (dev->ext_vv_data->vbi_fops.release)
|
||||
dev->ext_vv_data->vbi_fops.release(inode, file);
|
||||
} else {
|
||||
saa7146_video_uops.release(dev,file);
|
||||
}
|
||||
@ -382,7 +388,10 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof
|
||||
}
|
||||
case V4L2_BUF_TYPE_VBI_CAPTURE: {
|
||||
// DEB_EE(("V4L2_BUF_TYPE_VBI_CAPTURE: file:%p, data:%p, count:%lu\n", file, data, (unsigned long)count));
|
||||
return saa7146_vbi_uops.read(file,data,count,ppos);
|
||||
if (fh->dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
|
||||
return saa7146_vbi_uops.read(file,data,count,ppos);
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -391,12 +400,31 @@ static ssize_t fops_read(struct file *file, char __user *data, size_t count, lof
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t fops_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct saa7146_fh *fh = file->private_data;
|
||||
|
||||
switch (fh->type) {
|
||||
case V4L2_BUF_TYPE_VIDEO_CAPTURE:
|
||||
return -EINVAL;
|
||||
case V4L2_BUF_TYPE_VBI_CAPTURE:
|
||||
if (fh->dev->ext_vv_data->vbi_fops.write)
|
||||
return fh->dev->ext_vv_data->vbi_fops.write(file, data, count, ppos);
|
||||
else
|
||||
return -EINVAL;
|
||||
default:
|
||||
BUG();
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static struct file_operations video_fops =
|
||||
{
|
||||
.owner = THIS_MODULE,
|
||||
.open = fops_open,
|
||||
.release = fops_release,
|
||||
.read = fops_read,
|
||||
.write = fops_write,
|
||||
.poll = fops_poll,
|
||||
.mmap = fops_mmap,
|
||||
.ioctl = fops_ioctl,
|
||||
@ -468,7 +496,8 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv)
|
||||
memset(vv->d_clipping.cpu_addr, 0x0, SAA7146_CLIPPING_MEM);
|
||||
|
||||
saa7146_video_uops.init(dev,vv);
|
||||
saa7146_vbi_uops.init(dev,vv);
|
||||
if (dev->ext_vv_data->capabilities & V4L2_CAP_VBI_CAPTURE)
|
||||
saa7146_vbi_uops.init(dev,vv);
|
||||
|
||||
dev->vv_data = vv;
|
||||
dev->vv_callback = &vv_callback;
|
||||
|
@ -229,6 +229,9 @@ struct av7110 {
|
||||
struct dvb_video_events video_events;
|
||||
video_size_t video_size;
|
||||
|
||||
u16 wssMode;
|
||||
u16 wssData;
|
||||
|
||||
u32 ir_config;
|
||||
u32 ir_command;
|
||||
void (*ir_handler)(struct av7110 *av7110, u32 ircom);
|
||||
|
@ -167,7 +167,8 @@ enum av7110_encoder_command {
|
||||
LoadVidCode,
|
||||
SetMonitorType,
|
||||
SetPanScanType,
|
||||
SetFreezeMode
|
||||
SetFreezeMode,
|
||||
SetWSSConfig
|
||||
};
|
||||
|
||||
enum av7110_rec_play_state {
|
||||
|
@ -490,6 +490,58 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
|
||||
dprintk(2, "VIDIOC_S_AUDIO: %d\n", a->index);
|
||||
break;
|
||||
}
|
||||
case VIDIOC_G_SLICED_VBI_CAP:
|
||||
{
|
||||
struct v4l2_sliced_vbi_cap *cap = arg;
|
||||
dprintk(2, "VIDIOC_G_SLICED_VBI_CAP\n");
|
||||
memset(cap, 0, sizeof *cap);
|
||||
if (FW_VERSION(av7110->arm_app) >= 0x2623) {
|
||||
cap->service_set = V4L2_SLICED_WSS_625;
|
||||
cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VIDIOC_G_FMT:
|
||||
{
|
||||
struct v4l2_format *f = arg;
|
||||
dprintk(2, "VIDIOC_G_FMT:\n");
|
||||
if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
|
||||
FW_VERSION(av7110->arm_app) < 0x2623)
|
||||
return -EAGAIN; /* handled by core driver */
|
||||
memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
|
||||
if (av7110->wssMode) {
|
||||
f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
|
||||
f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
|
||||
f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case VIDIOC_S_FMT:
|
||||
{
|
||||
struct v4l2_format *f = arg;
|
||||
dprintk(2, "VIDIOC_S_FMT\n");
|
||||
if (f->type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT ||
|
||||
FW_VERSION(av7110->arm_app) < 0x2623)
|
||||
return -EAGAIN; /* handled by core driver */
|
||||
if (f->fmt.sliced.service_set != V4L2_SLICED_WSS_625 &&
|
||||
f->fmt.sliced.service_lines[0][23] != V4L2_SLICED_WSS_625) {
|
||||
memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
|
||||
/* WSS controlled by firmware */
|
||||
av7110->wssMode = 0;
|
||||
av7110->wssData = 0;
|
||||
return av7110_fw_cmd(av7110, COMTYPE_ENCODER,
|
||||
SetWSSConfig, 1, 0);
|
||||
} else {
|
||||
memset(&f->fmt.sliced, 0, sizeof f->fmt.sliced);
|
||||
f->fmt.sliced.service_set = V4L2_SLICED_WSS_625;
|
||||
f->fmt.sliced.service_lines[0][23] = V4L2_SLICED_WSS_625;
|
||||
f->fmt.sliced.io_size = sizeof (struct v4l2_sliced_vbi_data);
|
||||
/* WSS controlled by userspace */
|
||||
av7110->wssMode = 1;
|
||||
av7110->wssData = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printk("no such ioctl\n");
|
||||
return -ENOIOCTLCMD;
|
||||
@ -497,6 +549,46 @@ static int av7110_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int av7110_vbi_reset(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct saa7146_fh *fh = file->private_data;
|
||||
struct saa7146_dev *dev = fh->dev;
|
||||
struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
|
||||
|
||||
dprintk(2, "%s\n", __FUNCTION__);
|
||||
av7110->wssMode = 0;
|
||||
av7110->wssData = 0;
|
||||
if (FW_VERSION(av7110->arm_app) < 0x2623)
|
||||
return 0;
|
||||
else
|
||||
return av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0);
|
||||
}
|
||||
|
||||
static ssize_t av7110_vbi_write(struct file *file, const char __user *data, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct saa7146_fh *fh = file->private_data;
|
||||
struct saa7146_dev *dev = fh->dev;
|
||||
struct av7110 *av7110 = (struct av7110*) dev->ext_priv;
|
||||
struct v4l2_sliced_vbi_data d;
|
||||
int rc;
|
||||
|
||||
dprintk(2, "%s\n", __FUNCTION__);
|
||||
if (FW_VERSION(av7110->arm_app) < 0x2623 || !av7110->wssMode || count != sizeof d)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(&d, data, count))
|
||||
return -EFAULT;
|
||||
if ((d.id != 0 && d.id != V4L2_SLICED_WSS_625) || d.field != 0 || d.line != 23)
|
||||
return -EINVAL;
|
||||
if (d.id) {
|
||||
av7110->wssData = ((d.data[1] << 8) & 0x3f00) | d.data[0];
|
||||
rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig,
|
||||
2, 1, av7110->wssData);
|
||||
} else {
|
||||
av7110->wssData = 0;
|
||||
rc = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetWSSConfig, 1, 0);
|
||||
}
|
||||
return (rc < 0) ? rc : count;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* INITIALIZATION
|
||||
@ -512,6 +604,9 @@ static struct saa7146_extension_ioctls ioctls[] = {
|
||||
{ VIDIOC_S_TUNER, SAA7146_EXCLUSIVE },
|
||||
{ VIDIOC_G_AUDIO, SAA7146_EXCLUSIVE },
|
||||
{ VIDIOC_S_AUDIO, SAA7146_EXCLUSIVE },
|
||||
{ VIDIOC_G_SLICED_VBI_CAP, SAA7146_EXCLUSIVE },
|
||||
{ VIDIOC_G_FMT, SAA7146_BEFORE },
|
||||
{ VIDIOC_S_FMT, SAA7146_BEFORE },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
@ -692,12 +787,11 @@ int av7110_init_v4l(struct av7110 *av7110)
|
||||
saa7146_vv_release(dev);
|
||||
return -ENODEV;
|
||||
}
|
||||
if (av7110->analog_tuner_flags) {
|
||||
if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {
|
||||
ERR(("cannot register vbi v4l2 device. skipping.\n"));
|
||||
} else {
|
||||
if (saa7146_register_device(&av7110->vbi_dev, dev, "av7110", VFL_TYPE_VBI)) {
|
||||
ERR(("cannot register vbi v4l2 device. skipping.\n"));
|
||||
} else {
|
||||
if (av7110->analog_tuner_flags)
|
||||
av7110->analog_tuner_flags |= ANALOG_TUNER_VBI;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -778,7 +872,7 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
|
||||
static struct saa7146_ext_vv av7110_vv_data_st = {
|
||||
.inputs = 1,
|
||||
.audios = 1,
|
||||
.capabilities = 0,
|
||||
.capabilities = V4L2_CAP_SLICED_VBI_OUTPUT,
|
||||
.flags = 0,
|
||||
|
||||
.stds = &standard[0],
|
||||
@ -787,12 +881,16 @@ static struct saa7146_ext_vv av7110_vv_data_st = {
|
||||
|
||||
.ioctls = &ioctls[0],
|
||||
.ioctl = av7110_ioctl,
|
||||
|
||||
.vbi_fops.open = av7110_vbi_reset,
|
||||
.vbi_fops.release = av7110_vbi_reset,
|
||||
.vbi_fops.write = av7110_vbi_write,
|
||||
};
|
||||
|
||||
static struct saa7146_ext_vv av7110_vv_data_c = {
|
||||
.inputs = 1,
|
||||
.audios = 1,
|
||||
.capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
|
||||
.capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_OUTPUT,
|
||||
.flags = SAA7146_USE_PORT_B_FOR_VBI,
|
||||
|
||||
.stds = &standard[0],
|
||||
@ -801,5 +899,9 @@ static struct saa7146_ext_vv av7110_vv_data_c = {
|
||||
|
||||
.ioctls = &ioctls[0],
|
||||
.ioctl = av7110_ioctl,
|
||||
|
||||
.vbi_fops.open = av7110_vbi_reset,
|
||||
.vbi_fops.release = av7110_vbi_reset,
|
||||
.vbi_fops.write = av7110_vbi_write,
|
||||
};
|
||||
|
||||
|
@ -178,6 +178,8 @@ struct saa7146_ext_vv
|
||||
|
||||
struct saa7146_extension_ioctls *ioctls;
|
||||
int (*ioctl)(struct saa7146_fh*, unsigned int cmd, void *arg);
|
||||
|
||||
struct file_operations vbi_fops;
|
||||
};
|
||||
|
||||
struct saa7146_use_ops {
|
||||
|
Loading…
Reference in New Issue
Block a user