1b285192aSMauro Carvalho Chehab /* 2b285192aSMauro Carvalho Chehab * cx18 ioctl control functions 3b285192aSMauro Carvalho Chehab * 4b285192aSMauro Carvalho Chehab * Derived from ivtv-controls.c 5b285192aSMauro Carvalho Chehab * 6b285192aSMauro Carvalho Chehab * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> 7b285192aSMauro Carvalho Chehab * 8b285192aSMauro Carvalho Chehab * This program is free software; you can redistribute it and/or modify 9b285192aSMauro Carvalho Chehab * it under the terms of the GNU General Public License as published by 10b285192aSMauro Carvalho Chehab * the Free Software Foundation; either version 2 of the License, or 11b285192aSMauro Carvalho Chehab * (at your option) any later version. 12b285192aSMauro Carvalho Chehab * 13b285192aSMauro Carvalho Chehab * This program is distributed in the hope that it will be useful, 14b285192aSMauro Carvalho Chehab * but WITHOUT ANY WARRANTY; without even the implied warranty of 15b285192aSMauro Carvalho Chehab * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16b285192aSMauro Carvalho Chehab * GNU General Public License for more details. 17b285192aSMauro Carvalho Chehab * 18b285192aSMauro Carvalho Chehab * You should have received a copy of the GNU General Public License 19b285192aSMauro Carvalho Chehab * along with this program; if not, write to the Free Software 20b285192aSMauro Carvalho Chehab * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 21b285192aSMauro Carvalho Chehab * 02111-1307 USA 22b285192aSMauro Carvalho Chehab */ 23b285192aSMauro Carvalho Chehab #include <linux/kernel.h> 24b285192aSMauro Carvalho Chehab #include <linux/slab.h> 25b285192aSMauro Carvalho Chehab 26b285192aSMauro Carvalho Chehab #include "cx18-driver.h" 27b285192aSMauro Carvalho Chehab #include "cx18-cards.h" 28b285192aSMauro Carvalho Chehab #include "cx18-ioctl.h" 29b285192aSMauro Carvalho Chehab #include "cx18-audio.h" 30b285192aSMauro Carvalho Chehab #include "cx18-mailbox.h" 31b285192aSMauro Carvalho Chehab #include "cx18-controls.h" 32b285192aSMauro Carvalho Chehab 33b285192aSMauro Carvalho Chehab static int cx18_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt) 34b285192aSMauro Carvalho Chehab { 35b285192aSMauro Carvalho Chehab struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl); 36b285192aSMauro Carvalho Chehab int type = cxhdl->stream_type->val; 37b285192aSMauro Carvalho Chehab 38b285192aSMauro Carvalho Chehab if (atomic_read(&cx->ana_capturing) > 0) 39b285192aSMauro Carvalho Chehab return -EBUSY; 40b285192aSMauro Carvalho Chehab 41b285192aSMauro Carvalho Chehab if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV || 42b285192aSMauro Carvalho Chehab !(type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS || 43b285192aSMauro Carvalho Chehab type == V4L2_MPEG_STREAM_TYPE_MPEG2_DVD || 44b285192aSMauro Carvalho Chehab type == V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD)) { 45b285192aSMauro Carvalho Chehab /* Only IVTV fmt VBI insertion & only MPEG-2 PS type streams */ 46b285192aSMauro Carvalho Chehab cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE; 47b285192aSMauro Carvalho Chehab CX18_DEBUG_INFO("disabled insertion of sliced VBI data into " 48b285192aSMauro Carvalho Chehab "the MPEG stream\n"); 49b285192aSMauro Carvalho Chehab return 0; 50b285192aSMauro Carvalho Chehab } 51b285192aSMauro Carvalho Chehab 52b285192aSMauro Carvalho Chehab /* Allocate sliced VBI buffers if needed. */ 53b285192aSMauro Carvalho Chehab if (cx->vbi.sliced_mpeg_data[0] == NULL) { 54b285192aSMauro Carvalho Chehab int i; 55b285192aSMauro Carvalho Chehab 56b285192aSMauro Carvalho Chehab for (i = 0; i < CX18_VBI_FRAMES; i++) { 57b285192aSMauro Carvalho Chehab cx->vbi.sliced_mpeg_data[i] = 58b285192aSMauro Carvalho Chehab kmalloc(CX18_SLICED_MPEG_DATA_BUFSZ, GFP_KERNEL); 59b285192aSMauro Carvalho Chehab if (cx->vbi.sliced_mpeg_data[i] == NULL) { 60b285192aSMauro Carvalho Chehab while (--i >= 0) { 61b285192aSMauro Carvalho Chehab kfree(cx->vbi.sliced_mpeg_data[i]); 62b285192aSMauro Carvalho Chehab cx->vbi.sliced_mpeg_data[i] = NULL; 63b285192aSMauro Carvalho Chehab } 64b285192aSMauro Carvalho Chehab cx->vbi.insert_mpeg = 65b285192aSMauro Carvalho Chehab V4L2_MPEG_STREAM_VBI_FMT_NONE; 66b285192aSMauro Carvalho Chehab CX18_WARN("Unable to allocate buffers for " 67b285192aSMauro Carvalho Chehab "sliced VBI data insertion\n"); 68b285192aSMauro Carvalho Chehab return -ENOMEM; 69b285192aSMauro Carvalho Chehab } 70b285192aSMauro Carvalho Chehab } 71b285192aSMauro Carvalho Chehab } 72b285192aSMauro Carvalho Chehab 73b285192aSMauro Carvalho Chehab cx->vbi.insert_mpeg = fmt; 74b285192aSMauro Carvalho Chehab CX18_DEBUG_INFO("enabled insertion of sliced VBI data into the MPEG PS," 75b285192aSMauro Carvalho Chehab "when sliced VBI is enabled\n"); 76b285192aSMauro Carvalho Chehab 77b285192aSMauro Carvalho Chehab /* 78b285192aSMauro Carvalho Chehab * If our current settings have no lines set for capture, store a valid, 79b285192aSMauro Carvalho Chehab * default set of service lines to capture, in our current settings. 80b285192aSMauro Carvalho Chehab */ 81b285192aSMauro Carvalho Chehab if (cx18_get_service_set(cx->vbi.sliced_in) == 0) { 82b285192aSMauro Carvalho Chehab if (cx->is_60hz) 83b285192aSMauro Carvalho Chehab cx->vbi.sliced_in->service_set = 84b285192aSMauro Carvalho Chehab V4L2_SLICED_CAPTION_525; 85b285192aSMauro Carvalho Chehab else 86b285192aSMauro Carvalho Chehab cx->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625; 87b285192aSMauro Carvalho Chehab cx18_expand_service_set(cx->vbi.sliced_in, cx->is_50hz); 88b285192aSMauro Carvalho Chehab } 89b285192aSMauro Carvalho Chehab return 0; 90b285192aSMauro Carvalho Chehab } 91b285192aSMauro Carvalho Chehab 92b285192aSMauro Carvalho Chehab static int cx18_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val) 93b285192aSMauro Carvalho Chehab { 94b285192aSMauro Carvalho Chehab struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl); 95b285192aSMauro Carvalho Chehab int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1; 96ebf984bbSHans Verkuil struct v4l2_subdev_format format = { 97ebf984bbSHans Verkuil .which = V4L2_SUBDEV_FORMAT_ACTIVE, 98ebf984bbSHans Verkuil }; 99ebf984bbSHans Verkuil struct v4l2_mbus_framefmt *fmt = &format.format; 100b285192aSMauro Carvalho Chehab 101b285192aSMauro Carvalho Chehab /* fix videodecoder resolution */ 102ebf984bbSHans Verkuil fmt->width = cxhdl->width / (is_mpeg1 ? 2 : 1); 103ebf984bbSHans Verkuil fmt->height = cxhdl->height; 104ebf984bbSHans Verkuil fmt->code = MEDIA_BUS_FMT_FIXED; 105ebf984bbSHans Verkuil v4l2_subdev_call(cx->sd_av, pad, set_fmt, NULL, &format); 106b285192aSMauro Carvalho Chehab return 0; 107b285192aSMauro Carvalho Chehab } 108b285192aSMauro Carvalho Chehab 109b285192aSMauro Carvalho Chehab static int cx18_s_audio_sampling_freq(struct cx2341x_handler *cxhdl, u32 idx) 110b285192aSMauro Carvalho Chehab { 111b285192aSMauro Carvalho Chehab static const u32 freqs[3] = { 44100, 48000, 32000 }; 112b285192aSMauro Carvalho Chehab struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl); 113b285192aSMauro Carvalho Chehab 114b285192aSMauro Carvalho Chehab /* The audio clock of the digitizer must match the codec sample 115b285192aSMauro Carvalho Chehab rate otherwise you get some very strange effects. */ 116b285192aSMauro Carvalho Chehab if (idx < ARRAY_SIZE(freqs)) 117b285192aSMauro Carvalho Chehab cx18_call_all(cx, audio, s_clock_freq, freqs[idx]); 118b285192aSMauro Carvalho Chehab return 0; 119b285192aSMauro Carvalho Chehab } 120b285192aSMauro Carvalho Chehab 121b285192aSMauro Carvalho Chehab static int cx18_s_audio_mode(struct cx2341x_handler *cxhdl, u32 val) 122b285192aSMauro Carvalho Chehab { 123b285192aSMauro Carvalho Chehab struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl); 124b285192aSMauro Carvalho Chehab 125b285192aSMauro Carvalho Chehab cx->dualwatch_stereo_mode = val; 126b285192aSMauro Carvalho Chehab return 0; 127b285192aSMauro Carvalho Chehab } 128b285192aSMauro Carvalho Chehab 129b285192aSMauro Carvalho Chehab struct cx2341x_handler_ops cx18_cxhdl_ops = { 130b285192aSMauro Carvalho Chehab .s_audio_mode = cx18_s_audio_mode, 131b285192aSMauro Carvalho Chehab .s_audio_sampling_freq = cx18_s_audio_sampling_freq, 132b285192aSMauro Carvalho Chehab .s_video_encoding = cx18_s_video_encoding, 133b285192aSMauro Carvalho Chehab .s_stream_vbi_fmt = cx18_s_stream_vbi_fmt, 134b285192aSMauro Carvalho Chehab }; 135