diff options
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-ioctl.c')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-ioctl.c | 119 |
1 files changed, 79 insertions, 40 deletions
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 99f3c39a118b..fa9f0d958f96 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <media/saa7127.h> | 35 | #include <media/saa7127.h> |
36 | #include <media/tveeprom.h> | 36 | #include <media/tveeprom.h> |
37 | #include <media/v4l2-chip-ident.h> | 37 | #include <media/v4l2-chip-ident.h> |
38 | #include <media/v4l2-event.h> | ||
38 | #include <linux/dvb/audio.h> | 39 | #include <linux/dvb/audio.h> |
39 | #include <linux/i2c-id.h> | 40 | #include <linux/i2c-id.h> |
40 | 41 | ||
@@ -391,7 +392,7 @@ static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo | |||
391 | return 0; | 392 | return 0; |
392 | } | 393 | } |
393 | 394 | ||
394 | v4l2_subdev_call(itv->sd_video, video, g_fmt, fmt); | 395 | v4l2_subdev_call(itv->sd_video, vbi, g_sliced_fmt, vbifmt); |
395 | vbifmt->service_set = ivtv_get_service_set(vbifmt); | 396 | vbifmt->service_set = ivtv_get_service_set(vbifmt); |
396 | return 0; | 397 | return 0; |
397 | } | 398 | } |
@@ -597,7 +598,7 @@ static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f | |||
597 | return -EBUSY; | 598 | return -EBUSY; |
598 | itv->vbi.sliced_in->service_set = 0; | 599 | itv->vbi.sliced_in->service_set = 0; |
599 | itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; | 600 | itv->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; |
600 | v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt); | 601 | v4l2_subdev_call(itv->sd_video, vbi, s_raw_fmt, &fmt->fmt.vbi); |
601 | return ivtv_g_fmt_vbi_cap(file, fh, fmt); | 602 | return ivtv_g_fmt_vbi_cap(file, fh, fmt); |
602 | } | 603 | } |
603 | 604 | ||
@@ -615,7 +616,7 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo | |||
615 | if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) | 616 | if (ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) |
616 | return -EBUSY; | 617 | return -EBUSY; |
617 | itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; | 618 | itv->vbi.in.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; |
618 | v4l2_subdev_call(itv->sd_video, video, s_fmt, fmt); | 619 | v4l2_subdev_call(itv->sd_video, vbi, s_sliced_fmt, vbifmt); |
619 | memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); | 620 | memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); |
620 | return 0; | 621 | return 0; |
621 | } | 622 | } |
@@ -1087,8 +1088,10 @@ static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std) | |||
1087 | 1088 | ||
1088 | int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) | 1089 | int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) |
1089 | { | 1090 | { |
1091 | DEFINE_WAIT(wait); | ||
1090 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | 1092 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
1091 | struct yuv_playback_info *yi = &itv->yuv_info; | 1093 | struct yuv_playback_info *yi = &itv->yuv_info; |
1094 | int f; | ||
1092 | 1095 | ||
1093 | if ((*std & V4L2_STD_ALL) == 0) | 1096 | if ((*std & V4L2_STD_ALL) == 0) |
1094 | return -EINVAL; | 1097 | return -EINVAL; |
@@ -1128,6 +1131,25 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) | |||
1128 | itv->is_out_60hz = itv->is_60hz; | 1131 | itv->is_out_60hz = itv->is_60hz; |
1129 | itv->is_out_50hz = itv->is_50hz; | 1132 | itv->is_out_50hz = itv->is_50hz; |
1130 | ivtv_call_all(itv, video, s_std_output, itv->std_out); | 1133 | ivtv_call_all(itv, video, s_std_output, itv->std_out); |
1134 | |||
1135 | /* | ||
1136 | * The next firmware call is time sensitive. Time it to | ||
1137 | * avoid risk of a hard lock, by trying to ensure the call | ||
1138 | * happens within the first 100 lines of the top field. | ||
1139 | * Make 4 attempts to sync to the decoder before giving up. | ||
1140 | */ | ||
1141 | for (f = 0; f < 4; f++) { | ||
1142 | prepare_to_wait(&itv->vsync_waitq, &wait, | ||
1143 | TASK_UNINTERRUPTIBLE); | ||
1144 | if ((read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16) < 100) | ||
1145 | break; | ||
1146 | schedule_timeout(msecs_to_jiffies(25)); | ||
1147 | } | ||
1148 | finish_wait(&itv->vsync_waitq, &wait); | ||
1149 | |||
1150 | if (f == 4) | ||
1151 | IVTV_WARN("Mode change failed to sync to decoder\n"); | ||
1152 | |||
1131 | ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz); | 1153 | ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz); |
1132 | itv->main_rect.left = itv->main_rect.top = 0; | 1154 | itv->main_rect.left = itv->main_rect.top = 0; |
1133 | itv->main_rect.width = 720; | 1155 | itv->main_rect.width = 720; |
@@ -1431,6 +1453,18 @@ static int ivtv_overlay(struct file *file, void *fh, unsigned int on) | |||
1431 | return 0; | 1453 | return 0; |
1432 | } | 1454 | } |
1433 | 1455 | ||
1456 | static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscription *sub) | ||
1457 | { | ||
1458 | switch (sub->type) { | ||
1459 | case V4L2_EVENT_VSYNC: | ||
1460 | case V4L2_EVENT_EOS: | ||
1461 | break; | ||
1462 | default: | ||
1463 | return -EINVAL; | ||
1464 | } | ||
1465 | return v4l2_event_subscribe(fh, sub); | ||
1466 | } | ||
1467 | |||
1434 | static int ivtv_log_status(struct file *file, void *fh) | 1468 | static int ivtv_log_status(struct file *file, void *fh) |
1435 | { | 1469 | { |
1436 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; | 1470 | struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; |
@@ -1539,10 +1573,11 @@ static int ivtv_log_status(struct file *file, void *fh) | |||
1539 | 1573 | ||
1540 | static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) | 1574 | static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) |
1541 | { | 1575 | { |
1542 | struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; | 1576 | struct ivtv_open_id *id = fh2id(filp->private_data); |
1543 | struct ivtv *itv = id->itv; | 1577 | struct ivtv *itv = id->itv; |
1544 | int nonblocking = filp->f_flags & O_NONBLOCK; | 1578 | int nonblocking = filp->f_flags & O_NONBLOCK; |
1545 | struct ivtv_stream *s = &itv->streams[id->type]; | 1579 | struct ivtv_stream *s = &itv->streams[id->type]; |
1580 | unsigned long iarg = (unsigned long)arg; | ||
1546 | 1581 | ||
1547 | switch (cmd) { | 1582 | switch (cmd) { |
1548 | case IVTV_IOC_DMA_FRAME: { | 1583 | case IVTV_IOC_DMA_FRAME: { |
@@ -1724,6 +1759,33 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg) | |||
1724 | break; | 1759 | break; |
1725 | } | 1760 | } |
1726 | 1761 | ||
1762 | case VIDEO_SELECT_SOURCE: | ||
1763 | IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n"); | ||
1764 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
1765 | return -EINVAL; | ||
1766 | return ivtv_passthrough_mode(itv, iarg == VIDEO_SOURCE_DEMUX); | ||
1767 | |||
1768 | case AUDIO_SET_MUTE: | ||
1769 | IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n"); | ||
1770 | itv->speed_mute_audio = iarg; | ||
1771 | return 0; | ||
1772 | |||
1773 | case AUDIO_CHANNEL_SELECT: | ||
1774 | IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n"); | ||
1775 | if (iarg > AUDIO_STEREO_SWAPPED) | ||
1776 | return -EINVAL; | ||
1777 | itv->audio_stereo_mode = iarg; | ||
1778 | ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); | ||
1779 | return 0; | ||
1780 | |||
1781 | case AUDIO_BILINGUAL_CHANNEL_SELECT: | ||
1782 | IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n"); | ||
1783 | if (iarg > AUDIO_STEREO_SWAPPED) | ||
1784 | return -EINVAL; | ||
1785 | itv->audio_bilingual_mode = iarg; | ||
1786 | ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); | ||
1787 | return 0; | ||
1788 | |||
1727 | default: | 1789 | default: |
1728 | return -EINVAL; | 1790 | return -EINVAL; |
1729 | } | 1791 | } |
@@ -1755,6 +1817,10 @@ static long ivtv_default(struct file *file, void *fh, int cmd, void *arg) | |||
1755 | case VIDEO_CONTINUE: | 1817 | case VIDEO_CONTINUE: |
1756 | case VIDEO_COMMAND: | 1818 | case VIDEO_COMMAND: |
1757 | case VIDEO_TRY_COMMAND: | 1819 | case VIDEO_TRY_COMMAND: |
1820 | case VIDEO_SELECT_SOURCE: | ||
1821 | case AUDIO_SET_MUTE: | ||
1822 | case AUDIO_CHANNEL_SELECT: | ||
1823 | case AUDIO_BILINGUAL_CHANNEL_SELECT: | ||
1758 | return ivtv_decoder_ioctls(file, cmd, (void *)arg); | 1824 | return ivtv_decoder_ioctls(file, cmd, (void *)arg); |
1759 | 1825 | ||
1760 | default: | 1826 | default: |
@@ -1767,42 +1833,9 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, | |||
1767 | unsigned int cmd, unsigned long arg) | 1833 | unsigned int cmd, unsigned long arg) |
1768 | { | 1834 | { |
1769 | struct video_device *vfd = video_devdata(filp); | 1835 | struct video_device *vfd = video_devdata(filp); |
1770 | struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; | 1836 | struct ivtv_open_id *id = fh2id(filp->private_data); |
1771 | long ret; | 1837 | long ret; |
1772 | 1838 | ||
1773 | /* Filter dvb ioctls that cannot be handled by the v4l ioctl framework */ | ||
1774 | switch (cmd) { | ||
1775 | case VIDEO_SELECT_SOURCE: | ||
1776 | IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n"); | ||
1777 | if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) | ||
1778 | return -EINVAL; | ||
1779 | return ivtv_passthrough_mode(itv, arg == VIDEO_SOURCE_DEMUX); | ||
1780 | |||
1781 | case AUDIO_SET_MUTE: | ||
1782 | IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n"); | ||
1783 | itv->speed_mute_audio = arg; | ||
1784 | return 0; | ||
1785 | |||
1786 | case AUDIO_CHANNEL_SELECT: | ||
1787 | IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n"); | ||
1788 | if (arg > AUDIO_STEREO_SWAPPED) | ||
1789 | return -EINVAL; | ||
1790 | itv->audio_stereo_mode = arg; | ||
1791 | ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); | ||
1792 | return 0; | ||
1793 | |||
1794 | case AUDIO_BILINGUAL_CHANNEL_SELECT: | ||
1795 | IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n"); | ||
1796 | if (arg > AUDIO_STEREO_SWAPPED) | ||
1797 | return -EINVAL; | ||
1798 | itv->audio_bilingual_mode = arg; | ||
1799 | ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); | ||
1800 | return 0; | ||
1801 | |||
1802 | default: | ||
1803 | break; | ||
1804 | } | ||
1805 | |||
1806 | /* check priority */ | 1839 | /* check priority */ |
1807 | switch (cmd) { | 1840 | switch (cmd) { |
1808 | case VIDIOC_S_CTRL: | 1841 | case VIDIOC_S_CTRL: |
@@ -1817,8 +1850,9 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, | |||
1817 | case VIDIOC_S_AUDOUT: | 1850 | case VIDIOC_S_AUDOUT: |
1818 | case VIDIOC_S_EXT_CTRLS: | 1851 | case VIDIOC_S_EXT_CTRLS: |
1819 | case VIDIOC_S_FBUF: | 1852 | case VIDIOC_S_FBUF: |
1853 | case VIDIOC_S_PRIORITY: | ||
1820 | case VIDIOC_OVERLAY: | 1854 | case VIDIOC_OVERLAY: |
1821 | ret = v4l2_prio_check(&itv->prio, &id->prio); | 1855 | ret = v4l2_prio_check(&itv->prio, id->prio); |
1822 | if (ret) | 1856 | if (ret) |
1823 | return ret; | 1857 | return ret; |
1824 | } | 1858 | } |
@@ -1832,10 +1866,13 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp, | |||
1832 | 1866 | ||
1833 | long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 1867 | long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
1834 | { | 1868 | { |
1835 | struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; | 1869 | struct ivtv_open_id *id = fh2id(filp->private_data); |
1836 | struct ivtv *itv = id->itv; | 1870 | struct ivtv *itv = id->itv; |
1837 | long res; | 1871 | long res; |
1838 | 1872 | ||
1873 | /* DQEVENT can block, so this should not run with the serialize lock */ | ||
1874 | if (cmd == VIDIOC_DQEVENT) | ||
1875 | return ivtv_serialized_ioctl(itv, filp, cmd, arg); | ||
1839 | mutex_lock(&itv->serialize_lock); | 1876 | mutex_lock(&itv->serialize_lock); |
1840 | res = ivtv_serialized_ioctl(itv, filp, cmd, arg); | 1877 | res = ivtv_serialized_ioctl(itv, filp, cmd, arg); |
1841 | mutex_unlock(&itv->serialize_lock); | 1878 | mutex_unlock(&itv->serialize_lock); |
@@ -1906,6 +1943,8 @@ static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { | |||
1906 | .vidioc_g_ext_ctrls = ivtv_g_ext_ctrls, | 1943 | .vidioc_g_ext_ctrls = ivtv_g_ext_ctrls, |
1907 | .vidioc_s_ext_ctrls = ivtv_s_ext_ctrls, | 1944 | .vidioc_s_ext_ctrls = ivtv_s_ext_ctrls, |
1908 | .vidioc_try_ext_ctrls = ivtv_try_ext_ctrls, | 1945 | .vidioc_try_ext_ctrls = ivtv_try_ext_ctrls, |
1946 | .vidioc_subscribe_event = ivtv_subscribe_event, | ||
1947 | .vidioc_unsubscribe_event = v4l2_event_unsubscribe, | ||
1909 | }; | 1948 | }; |
1910 | 1949 | ||
1911 | void ivtv_set_funcs(struct video_device *vdev) | 1950 | void ivtv_set_funcs(struct video_device *vdev) |