2 ioctl control functions
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "ivtv-driver.h"
22 #include "ivtv-ioctl.h"
23 #include "ivtv-controls.h"
24 #include "ivtv-mailbox.h"
26 static int ivtv_s_stream_vbi_fmt(struct cx2341x_handler
*cxhdl
, u32 fmt
)
28 struct ivtv
*itv
= container_of(cxhdl
, struct ivtv
, cxhdl
);
30 /* First try to allocate sliced VBI buffers if needed. */
31 if (fmt
&& itv
->vbi
.sliced_mpeg_data
[0] == NULL
) {
34 for (i
= 0; i
< IVTV_VBI_FRAMES
; i
++) {
35 /* Yuck, hardcoded. Needs to be a define */
36 itv
->vbi
.sliced_mpeg_data
[i
] = kmalloc(2049, GFP_KERNEL
);
37 if (itv
->vbi
.sliced_mpeg_data
[i
] == NULL
) {
39 kfree(itv
->vbi
.sliced_mpeg_data
[i
]);
40 itv
->vbi
.sliced_mpeg_data
[i
] = NULL
;
47 itv
->vbi
.insert_mpeg
= fmt
;
49 if (itv
->vbi
.insert_mpeg
== 0) {
52 /* Need sliced data for mpeg insertion */
53 if (ivtv_get_service_set(itv
->vbi
.sliced_in
) == 0) {
55 itv
->vbi
.sliced_in
->service_set
= V4L2_SLICED_CAPTION_525
;
57 itv
->vbi
.sliced_in
->service_set
= V4L2_SLICED_WSS_625
;
58 ivtv_expand_service_set(itv
->vbi
.sliced_in
, itv
->is_50hz
);
63 static int ivtv_s_video_encoding(struct cx2341x_handler
*cxhdl
, u32 val
)
65 struct ivtv
*itv
= container_of(cxhdl
, struct ivtv
, cxhdl
);
66 int is_mpeg1
= val
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
;
67 struct v4l2_subdev_format format
= {
68 .which
= V4L2_SUBDEV_FORMAT_ACTIVE
,
71 /* fix videodecoder resolution */
72 format
.format
.width
= cxhdl
->width
/ (is_mpeg1
? 2 : 1);
73 format
.format
.height
= cxhdl
->height
;
74 format
.format
.code
= MEDIA_BUS_FMT_FIXED
;
75 v4l2_subdev_call(itv
->sd_video
, pad
, set_fmt
, NULL
, &format
);
79 static int ivtv_s_audio_sampling_freq(struct cx2341x_handler
*cxhdl
, u32 idx
)
81 static const u32 freqs
[3] = { 44100, 48000, 32000 };
82 struct ivtv
*itv
= container_of(cxhdl
, struct ivtv
, cxhdl
);
84 /* The audio clock of the digitizer must match the codec sample
85 rate otherwise you get some very strange effects. */
86 if (idx
< ARRAY_SIZE(freqs
))
87 ivtv_call_all(itv
, audio
, s_clock_freq
, freqs
[idx
]);
91 static int ivtv_s_audio_mode(struct cx2341x_handler
*cxhdl
, u32 val
)
93 struct ivtv
*itv
= container_of(cxhdl
, struct ivtv
, cxhdl
);
95 itv
->dualwatch_stereo_mode
= val
;
99 const struct cx2341x_handler_ops ivtv_cxhdl_ops
= {
100 .s_audio_mode
= ivtv_s_audio_mode
,
101 .s_audio_sampling_freq
= ivtv_s_audio_sampling_freq
,
102 .s_video_encoding
= ivtv_s_video_encoding
,
103 .s_stream_vbi_fmt
= ivtv_s_stream_vbi_fmt
,
106 int ivtv_g_pts_frame(struct ivtv
*itv
, s64
*pts
, s64
*frame
)
108 u32 data
[CX2341X_MBOX_MAX_DATA
];
110 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS
, &itv
->i_flags
)) {
111 *pts
= (s64
)((u64
)itv
->last_dec_timing
[2] << 32) |
112 (u64
)itv
->last_dec_timing
[1];
113 *frame
= itv
->last_dec_timing
[0];
118 if (atomic_read(&itv
->decoding
)) {
119 if (ivtv_api(itv
, CX2341X_DEC_GET_TIMING_INFO
, 5, data
)) {
120 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
123 memcpy(itv
->last_dec_timing
, data
, sizeof(itv
->last_dec_timing
));
124 set_bit(IVTV_F_I_VALID_DEC_TIMINGS
, &itv
->i_flags
);
125 *pts
= (s64
)((u64
) data
[2] << 32) | (u64
) data
[1];
127 /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
132 static int ivtv_g_volatile_ctrl(struct v4l2_ctrl
*ctrl
)
134 struct ivtv
*itv
= container_of(ctrl
->handler
, struct ivtv
, cxhdl
.hdl
);
137 /* V4L2_CID_MPEG_VIDEO_DEC_PTS and V4L2_CID_MPEG_VIDEO_DEC_FRAME
139 case V4L2_CID_MPEG_VIDEO_DEC_PTS
:
140 return ivtv_g_pts_frame(itv
, itv
->ctrl_pts
->p_new
.p_s64
,
141 itv
->ctrl_frame
->p_new
.p_s64
);
146 static int ivtv_s_ctrl(struct v4l2_ctrl
*ctrl
)
148 struct ivtv
*itv
= container_of(ctrl
->handler
, struct ivtv
, cxhdl
.hdl
);
151 /* V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK and MULTILINGUAL_PLAYBACK
153 case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK
:
154 itv
->audio_stereo_mode
= itv
->ctrl_audio_playback
->val
- 1;
155 itv
->audio_bilingual_mode
= itv
->ctrl_audio_multilingual_playback
->val
- 1;
156 ivtv_vapi(itv
, CX2341X_DEC_SET_AUDIO_MODE
, 2, itv
->audio_bilingual_mode
, itv
->audio_stereo_mode
);
162 const struct v4l2_ctrl_ops ivtv_hdl_out_ops
= {
163 .s_ctrl
= ivtv_s_ctrl
,
164 .g_volatile_ctrl
= ivtv_g_volatile_ctrl
,