1 // SPDX-License-Identifier: GPL-2.0-or-later
3 ioctl control functions
4 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
5 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
9 #include "ivtv-driver.h"
10 #include "ivtv-ioctl.h"
11 #include "ivtv-controls.h"
12 #include "ivtv-mailbox.h"
14 static int ivtv_s_stream_vbi_fmt(struct cx2341x_handler
*cxhdl
, u32 fmt
)
16 struct ivtv
*itv
= container_of(cxhdl
, struct ivtv
, cxhdl
);
18 /* First try to allocate sliced VBI buffers if needed. */
19 if (fmt
&& itv
->vbi
.sliced_mpeg_data
[0] == NULL
) {
22 for (i
= 0; i
< IVTV_VBI_FRAMES
; i
++) {
23 /* Yuck, hardcoded. Needs to be a define */
24 itv
->vbi
.sliced_mpeg_data
[i
] = kmalloc(2049, GFP_KERNEL
);
25 if (itv
->vbi
.sliced_mpeg_data
[i
] == NULL
) {
27 kfree(itv
->vbi
.sliced_mpeg_data
[i
]);
28 itv
->vbi
.sliced_mpeg_data
[i
] = NULL
;
35 itv
->vbi
.insert_mpeg
= fmt
;
37 if (itv
->vbi
.insert_mpeg
== 0) {
40 /* Need sliced data for mpeg insertion */
41 if (ivtv_get_service_set(itv
->vbi
.sliced_in
) == 0) {
43 itv
->vbi
.sliced_in
->service_set
= V4L2_SLICED_CAPTION_525
;
45 itv
->vbi
.sliced_in
->service_set
= V4L2_SLICED_WSS_625
;
46 ivtv_expand_service_set(itv
->vbi
.sliced_in
, itv
->is_50hz
);
51 static int ivtv_s_video_encoding(struct cx2341x_handler
*cxhdl
, u32 val
)
53 struct ivtv
*itv
= container_of(cxhdl
, struct ivtv
, cxhdl
);
54 int is_mpeg1
= val
== V4L2_MPEG_VIDEO_ENCODING_MPEG_1
;
55 struct v4l2_subdev_format format
= {
56 .which
= V4L2_SUBDEV_FORMAT_ACTIVE
,
59 /* fix videodecoder resolution */
60 format
.format
.width
= cxhdl
->width
/ (is_mpeg1
? 2 : 1);
61 format
.format
.height
= cxhdl
->height
;
62 format
.format
.code
= MEDIA_BUS_FMT_FIXED
;
63 v4l2_subdev_call(itv
->sd_video
, pad
, set_fmt
, NULL
, &format
);
67 static int ivtv_s_audio_sampling_freq(struct cx2341x_handler
*cxhdl
, u32 idx
)
69 static const u32 freqs
[3] = { 44100, 48000, 32000 };
70 struct ivtv
*itv
= container_of(cxhdl
, struct ivtv
, cxhdl
);
72 /* The audio clock of the digitizer must match the codec sample
73 rate otherwise you get some very strange effects. */
74 if (idx
< ARRAY_SIZE(freqs
))
75 ivtv_call_all(itv
, audio
, s_clock_freq
, freqs
[idx
]);
79 static int ivtv_s_audio_mode(struct cx2341x_handler
*cxhdl
, u32 val
)
81 struct ivtv
*itv
= container_of(cxhdl
, struct ivtv
, cxhdl
);
83 itv
->dualwatch_stereo_mode
= val
;
87 const struct cx2341x_handler_ops ivtv_cxhdl_ops
= {
88 .s_audio_mode
= ivtv_s_audio_mode
,
89 .s_audio_sampling_freq
= ivtv_s_audio_sampling_freq
,
90 .s_video_encoding
= ivtv_s_video_encoding
,
91 .s_stream_vbi_fmt
= ivtv_s_stream_vbi_fmt
,
94 int ivtv_g_pts_frame(struct ivtv
*itv
, s64
*pts
, s64
*frame
)
96 u32 data
[CX2341X_MBOX_MAX_DATA
];
98 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS
, &itv
->i_flags
)) {
99 *pts
= (s64
)((u64
)itv
->last_dec_timing
[2] << 32) |
100 (u64
)itv
->last_dec_timing
[1];
101 *frame
= itv
->last_dec_timing
[0];
106 if (atomic_read(&itv
->decoding
)) {
107 if (ivtv_api(itv
, CX2341X_DEC_GET_TIMING_INFO
, 5, data
)) {
108 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
111 memcpy(itv
->last_dec_timing
, data
, sizeof(itv
->last_dec_timing
));
112 set_bit(IVTV_F_I_VALID_DEC_TIMINGS
, &itv
->i_flags
);
113 *pts
= (s64
)((u64
) data
[2] << 32) | (u64
) data
[1];
115 /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
120 static int ivtv_g_volatile_ctrl(struct v4l2_ctrl
*ctrl
)
122 struct ivtv
*itv
= container_of(ctrl
->handler
, struct ivtv
, cxhdl
.hdl
);
125 /* V4L2_CID_MPEG_VIDEO_DEC_PTS and V4L2_CID_MPEG_VIDEO_DEC_FRAME
127 case V4L2_CID_MPEG_VIDEO_DEC_PTS
:
128 return ivtv_g_pts_frame(itv
, itv
->ctrl_pts
->p_new
.p_s64
,
129 itv
->ctrl_frame
->p_new
.p_s64
);
134 static int ivtv_s_ctrl(struct v4l2_ctrl
*ctrl
)
136 struct ivtv
*itv
= container_of(ctrl
->handler
, struct ivtv
, cxhdl
.hdl
);
139 /* V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK and MULTILINGUAL_PLAYBACK
141 case V4L2_CID_MPEG_AUDIO_DEC_PLAYBACK
:
142 itv
->audio_stereo_mode
= itv
->ctrl_audio_playback
->val
- 1;
143 itv
->audio_bilingual_mode
= itv
->ctrl_audio_multilingual_playback
->val
- 1;
144 ivtv_vapi(itv
, CX2341X_DEC_SET_AUDIO_MODE
, 2, itv
->audio_bilingual_mode
, itv
->audio_stereo_mode
);
150 const struct v4l2_ctrl_ops ivtv_hdl_out_ops
= {
151 .s_ctrl
= ivtv_s_ctrl
,
152 .g_volatile_ctrl
= ivtv_g_volatile_ctrl
,