Skip to content

Commit 88b6ffe

Browse files
Hans VerkuilMauro Carvalho Chehab
authored andcommitted
[media] cx231xx-417: convert to the control framework
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
1 parent b86d154 commit 88b6ffe

File tree

2 files changed

+86
-129
lines changed

2 files changed

+86
-129
lines changed

drivers/media/usb/cx231xx/cx231xx-417.c

Lines changed: 85 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <linux/vmalloc.h>
3535
#include <media/v4l2-common.h>
3636
#include <media/v4l2-ioctl.h>
37+
#include <media/v4l2-event.h>
3738
#include <media/cx2341x.h>
3839
#include <media/tuner.h>
3940
#include <linux/usb.h>
@@ -744,7 +745,7 @@ static int cx231xx_mbox_func(void *priv, u32 command, int in, int out,
744745
if (value != 0x12345678) {
745746
dprintk(3, "Firmware and/or mailbox pointer not initialized or corrupted, signature = 0x%x, cmd = %s\n",
746747
value, cmd_to_str(command));
747-
return -1;
748+
return -EIO;
748749
}
749750

750751
/* This read looks at 32 bits, but flag is only 8 bits.
@@ -754,7 +755,7 @@ static int cx231xx_mbox_func(void *priv, u32 command, int in, int out,
754755
if (flag) {
755756
dprintk(3, "ERROR: Mailbox appears to be in use (%x), cmd = %s\n",
756757
flag, cmd_to_str(command));
757-
return -1;
758+
return -EBUSY;
758759
}
759760

760761
flag |= 1; /* tell 'em we're working on it */
@@ -783,7 +784,7 @@ static int cx231xx_mbox_func(void *priv, u32 command, int in, int out,
783784
break;
784785
if (time_after(jiffies, timeout)) {
785786
dprintk(3, "ERROR: API Mailbox timeout\n");
786-
return -1;
787+
return -EIO;
787788
}
788789
udelay(10);
789790
}
@@ -800,7 +801,7 @@ static int cx231xx_mbox_func(void *priv, u32 command, int in, int out,
800801
flag = 0;
801802
mc417_memory_write(dev, dev->cx23417_mailbox, flag);
802803

803-
return retval;
804+
return 0;
804805
}
805806

806807
/* We don't need to call the API often, so using just one
@@ -829,6 +830,7 @@ static int cx231xx_api_cmd(struct cx231xx *dev, u32 command,
829830
return err;
830831
}
831832

833+
832834
static int cx231xx_find_mailbox(struct cx231xx *dev)
833835
{
834836
u32 signature[4] = {
@@ -1092,10 +1094,10 @@ static void cx231xx_codec_settings(struct cx231xx *dev)
10921094
cx231xx_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0,
10931095
dev->ts1.height, dev->ts1.width);
10941096

1095-
dev->mpeg_params.width = dev->ts1.width;
1096-
dev->mpeg_params.height = dev->ts1.height;
1097+
dev->mpeg_ctrl_handler.width = dev->ts1.width;
1098+
dev->mpeg_ctrl_handler.height = dev->ts1.height;
10971099

1098-
cx2341x_update(dev, cx231xx_mbox_func, NULL, &dev->mpeg_params);
1100+
cx2341x_handler_setup(&dev->mpeg_ctrl_handler);
10991101

11001102
cx231xx_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 3, 1);
11011103
cx231xx_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 4, 1);
@@ -1481,36 +1483,6 @@ static struct videobuf_queue_ops cx231xx_qops = {
14811483

14821484
/* ------------------------------------------------------------------ */
14831485

1484-
static const u32 *ctrl_classes[] = {
1485-
cx2341x_mpeg_ctrls,
1486-
NULL
1487-
};
1488-
1489-
static int cx231xx_queryctrl(struct cx231xx *dev,
1490-
struct v4l2_queryctrl *qctrl)
1491-
{
1492-
qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
1493-
if (qctrl->id == 0)
1494-
return -EINVAL;
1495-
1496-
/* MPEG V4L2 controls */
1497-
if (cx2341x_ctrl_query(&dev->mpeg_params, qctrl))
1498-
qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
1499-
1500-
return 0;
1501-
}
1502-
1503-
static int cx231xx_querymenu(struct cx231xx *dev,
1504-
struct v4l2_querymenu *qmenu)
1505-
{
1506-
struct v4l2_queryctrl qctrl;
1507-
1508-
qctrl.id = qmenu->id;
1509-
cx231xx_queryctrl(dev, &qctrl);
1510-
return v4l2_ctrl_query_menu(qmenu, &qctrl,
1511-
cx2341x_ctrl_get_menu(&dev->mpeg_params, qmenu->id));
1512-
}
1513-
15141486
static int vidioc_g_std(struct file *file, void *fh0, v4l2_std_id *norm)
15151487
{
15161488
struct cx231xx_fh *fh = file->private_data;
@@ -1537,12 +1509,12 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
15371509
dprintk(3, "encodernorm set to NTSC\n");
15381510
dev->norm = V4L2_STD_NTSC;
15391511
dev->ts1.height = 480;
1540-
dev->mpeg_params.is_50hz = 0;
1512+
cx2341x_handler_set_50hz(&dev->mpeg_ctrl_handler, false);
15411513
} else {
15421514
dprintk(3, "encodernorm set to PAL\n");
15431515
dev->norm = V4L2_STD_PAL_B;
15441516
dev->ts1.height = 576;
1545-
dev->mpeg_params.is_50hz = 1;
1517+
cx2341x_handler_set_50hz(&dev->mpeg_ctrl_handler, true);
15461518
}
15471519
call_all(dev, core, s_std, dev->norm);
15481520
/* do mode control overrides */
@@ -1680,92 +1652,13 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
16801652
return videobuf_streamoff(&fh->vidq);
16811653
}
16821654

1683-
static int vidioc_g_ext_ctrls(struct file *file, void *priv,
1684-
struct v4l2_ext_controls *f)
1685-
{
1686-
struct cx231xx_fh *fh = priv;
1687-
struct cx231xx *dev = fh->dev;
1688-
1689-
dprintk(3, "enter vidioc_g_ext_ctrls()\n");
1690-
if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
1691-
return -EINVAL;
1692-
dprintk(3, "exit vidioc_g_ext_ctrls()\n");
1693-
return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, VIDIOC_G_EXT_CTRLS);
1694-
}
1695-
1696-
static int vidioc_s_ext_ctrls(struct file *file, void *priv,
1697-
struct v4l2_ext_controls *f)
1698-
{
1699-
struct cx231xx_fh *fh = priv;
1700-
struct cx231xx *dev = fh->dev;
1701-
struct cx2341x_mpeg_params p;
1702-
int err;
1703-
1704-
dprintk(3, "enter vidioc_s_ext_ctrls()\n");
1705-
if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
1706-
return -EINVAL;
1707-
1708-
p = dev->mpeg_params;
1709-
err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS);
1710-
if (err == 0) {
1711-
err = cx2341x_update(dev, cx231xx_mbox_func,
1712-
&dev->mpeg_params, &p);
1713-
dev->mpeg_params = p;
1714-
}
1715-
1716-
return err;
1717-
}
1718-
1719-
static int vidioc_try_ext_ctrls(struct file *file, void *priv,
1720-
struct v4l2_ext_controls *f)
1721-
{
1722-
struct cx231xx_fh *fh = priv;
1723-
struct cx231xx *dev = fh->dev;
1724-
struct cx2341x_mpeg_params p;
1725-
int err;
1726-
1727-
dprintk(3, "enter vidioc_try_ext_ctrls()\n");
1728-
if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
1729-
return -EINVAL;
1730-
1731-
p = dev->mpeg_params;
1732-
err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS);
1733-
dprintk(3, "exit vidioc_try_ext_ctrls() err=%d\n", err);
1734-
return err;
1735-
}
1736-
17371655
static int vidioc_log_status(struct file *file, void *priv)
17381656
{
17391657
struct cx231xx_fh *fh = priv;
17401658
struct cx231xx *dev = fh->dev;
1741-
char name[32 + 2];
17421659

1743-
snprintf(name, sizeof(name), "%s/2", dev->name);
17441660
call_all(dev, core, log_status);
1745-
cx2341x_log_status(&dev->mpeg_params, name);
1746-
return 0;
1747-
}
1748-
1749-
static int vidioc_querymenu(struct file *file, void *priv,
1750-
struct v4l2_querymenu *a)
1751-
{
1752-
struct cx231xx_fh *fh = priv;
1753-
struct cx231xx *dev = fh->dev;
1754-
1755-
dprintk(3, "enter vidioc_querymenu()\n");
1756-
dprintk(3, "exit vidioc_querymenu()\n");
1757-
return cx231xx_querymenu(dev, a);
1758-
}
1759-
1760-
static int vidioc_queryctrl(struct file *file, void *priv,
1761-
struct v4l2_queryctrl *c)
1762-
{
1763-
struct cx231xx_fh *fh = priv;
1764-
struct cx231xx *dev = fh->dev;
1765-
1766-
dprintk(3, "enter vidioc_queryctrl()\n");
1767-
dprintk(3, "exit vidioc_queryctrl()\n");
1768-
return cx231xx_queryctrl(dev, c);
1661+
return v4l2_ctrl_log_status(file, priv);
17691662
}
17701663

17711664
static int mpeg_open(struct file *file)
@@ -1885,9 +1778,23 @@ static ssize_t mpeg_read(struct file *file, char __user *data,
18851778
static unsigned int mpeg_poll(struct file *file,
18861779
struct poll_table_struct *wait)
18871780
{
1781+
unsigned long req_events = poll_requested_events(wait);
18881782
struct cx231xx_fh *fh = file->private_data;
1783+
struct cx231xx *dev = fh->dev;
1784+
unsigned int res = 0;
18891785

1890-
return videobuf_poll_stream(file, &fh->vidq, wait);
1786+
if (v4l2_event_pending(&fh->fh))
1787+
res |= POLLPRI;
1788+
else
1789+
poll_wait(file, &fh->fh.wait, wait);
1790+
1791+
if (!(req_events & (POLLIN | POLLRDNORM)))
1792+
return res;
1793+
1794+
mutex_lock(&dev->lock);
1795+
res |= videobuf_poll_stream(file, &fh->vidq, wait);
1796+
mutex_unlock(&dev->lock);
1797+
return res;
18911798
}
18921799

18931800
static int mpeg_mmap(struct file *file, struct vm_area_struct *vma)
@@ -1932,25 +1839,22 @@ static const struct v4l2_ioctl_ops mpeg_ioctl_ops = {
19321839
.vidioc_dqbuf = vidioc_dqbuf,
19331840
.vidioc_streamon = vidioc_streamon,
19341841
.vidioc_streamoff = vidioc_streamoff,
1935-
.vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
1936-
.vidioc_s_ext_ctrls = vidioc_s_ext_ctrls,
1937-
.vidioc_try_ext_ctrls = vidioc_try_ext_ctrls,
19381842
.vidioc_log_status = vidioc_log_status,
1939-
.vidioc_querymenu = vidioc_querymenu,
1940-
.vidioc_queryctrl = vidioc_queryctrl,
19411843
.vidioc_g_chip_ident = cx231xx_g_chip_ident,
19421844
#ifdef CONFIG_VIDEO_ADV_DEBUG
19431845
.vidioc_g_register = cx231xx_g_register,
19441846
.vidioc_s_register = cx231xx_s_register,
19451847
#endif
1848+
.vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
1849+
.vidioc_unsubscribe_event = v4l2_event_unsubscribe,
19461850
};
19471851

19481852
static struct video_device cx231xx_mpeg_template = {
19491853
.name = "cx231xx",
19501854
.fops = &mpeg_fops,
19511855
.ioctl_ops = &mpeg_ioctl_ops,
19521856
.minor = -1,
1953-
.tvnorms = CX231xx_NORMS,
1857+
.tvnorms = V4L2_STD_ALL,
19541858
};
19551859

19561860
void cx231xx_417_unregister(struct cx231xx *dev)
@@ -1963,10 +1867,44 @@ void cx231xx_417_unregister(struct cx231xx *dev)
19631867
video_unregister_device(dev->v4l_device);
19641868
else
19651869
video_device_release(dev->v4l_device);
1870+
v4l2_ctrl_handler_free(&dev->mpeg_ctrl_handler.hdl);
19661871
dev->v4l_device = NULL;
19671872
}
19681873
}
19691874

1875+
static int cx231xx_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val)
1876+
{
1877+
struct cx231xx *dev = container_of(cxhdl, struct cx231xx, mpeg_ctrl_handler);
1878+
int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
1879+
struct v4l2_mbus_framefmt fmt;
1880+
1881+
/* fix videodecoder resolution */
1882+
fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1);
1883+
fmt.height = cxhdl->height;
1884+
fmt.code = V4L2_MBUS_FMT_FIXED;
1885+
v4l2_subdev_call(dev->sd_cx25840, video, s_mbus_fmt, &fmt);
1886+
return 0;
1887+
}
1888+
1889+
static int cx231xx_s_audio_sampling_freq(struct cx2341x_handler *cxhdl, u32 idx)
1890+
{
1891+
static const u32 freqs[3] = { 44100, 48000, 32000 };
1892+
struct cx231xx *dev = container_of(cxhdl, struct cx231xx, mpeg_ctrl_handler);
1893+
1894+
/* The audio clock of the digitizer must match the codec sample
1895+
rate otherwise you get some very strange effects. */
1896+
if (idx < ARRAY_SIZE(freqs))
1897+
call_all(dev, audio, s_clock_freq, freqs[idx]);
1898+
return 0;
1899+
}
1900+
1901+
static struct cx2341x_handler_ops cx231xx_ops = {
1902+
/* needed for the video clock freq */
1903+
.s_audio_sampling_freq = cx231xx_s_audio_sampling_freq,
1904+
/* needed for setting up the video resolution */
1905+
.s_video_encoding = cx231xx_s_video_encoding,
1906+
};
1907+
19701908
static struct video_device *cx231xx_video_dev_alloc(
19711909
struct cx231xx *dev,
19721910
struct usb_device *usbdev,
@@ -1987,6 +1925,7 @@ static struct video_device *cx231xx_video_dev_alloc(
19871925
vfd->lock = &dev->lock;
19881926
vfd->release = video_device_release;
19891927
set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
1928+
vfd->ctrl_handler = &dev->mpeg_ctrl_handler.hdl;
19901929
video_set_drvdata(vfd, dev);
19911930
if (dev->tuner_type == TUNER_ABSENT) {
19921931
v4l2_disable_ioctl(vfd, VIDIOC_G_FREQUENCY);
@@ -2016,10 +1955,27 @@ int cx231xx_417_register(struct cx231xx *dev)
20161955
tsport->height = 576;
20171956

20181957
tsport->width = 720;
2019-
cx2341x_fill_defaults(&dev->mpeg_params);
1958+
err = cx2341x_handler_init(&dev->mpeg_ctrl_handler, 50);
1959+
if (err) {
1960+
dprintk(3, "%s: can't init cx2341x controls\n", dev->name);
1961+
return err;
1962+
}
1963+
dev->mpeg_ctrl_handler.func = cx231xx_mbox_func;
1964+
dev->mpeg_ctrl_handler.priv = dev;
1965+
dev->mpeg_ctrl_handler.ops = &cx231xx_ops;
1966+
if (dev->sd_cx25840)
1967+
v4l2_ctrl_add_handler(&dev->mpeg_ctrl_handler.hdl,
1968+
dev->sd_cx25840->ctrl_handler, NULL);
1969+
if (dev->mpeg_ctrl_handler.hdl.error) {
1970+
err = dev->mpeg_ctrl_handler.hdl.error;
1971+
dprintk(3, "%s: can't add cx25840 controls\n", dev->name);
1972+
v4l2_ctrl_handler_free(&dev->mpeg_ctrl_handler.hdl);
1973+
return err;
1974+
}
20201975
dev->norm = V4L2_STD_NTSC;
20211976

2022-
dev->mpeg_params.port = CX2341X_PORT_SERIAL;
1977+
dev->mpeg_ctrl_handler.port = CX2341X_PORT_SERIAL;
1978+
cx2341x_handler_set_50hz(&dev->mpeg_ctrl_handler, false);
20231979

20241980
/* Allocate and initialize V4L video device */
20251981
dev->v4l_device = cx231xx_video_dev_alloc(dev,
@@ -2028,6 +1984,7 @@ int cx231xx_417_register(struct cx231xx *dev)
20281984
VFL_TYPE_GRABBER, -1);
20291985
if (err < 0) {
20301986
dprintk(3, "%s: can't register mpeg device\n", dev->name);
1987+
v4l2_ctrl_handler_free(&dev->mpeg_ctrl_handler.hdl);
20311988
return err;
20321989
}
20331990

drivers/media/usb/cx231xx/cx231xx.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,7 @@ struct cx231xx {
612612
struct v4l2_subdev *sd_tuner;
613613
struct v4l2_ctrl_handler ctrl_handler;
614614
struct v4l2_ctrl_handler radio_ctrl_handler;
615+
struct cx2341x_handler mpeg_ctrl_handler;
615616

616617
struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */
617618
atomic_t stream_started; /* stream should be running if true */
@@ -715,7 +716,6 @@ struct cx231xx {
715716
u8 USE_ISO;
716717
struct cx231xx_tvnorm encodernorm;
717718
struct cx231xx_tsport ts1, ts2;
718-
struct cx2341x_mpeg_params mpeg_params;
719719
struct video_device *v4l_device;
720720
atomic_t v4l_reader_count;
721721
u32 freq;

0 commit comments

Comments
 (0)