linux/drivers/media/video/cx2341x.c
<<
>>
Prefs
   1/*
   2 * cx2341x - generic code for cx23415/6 based devices
   3 *
   4 * Copyright (C) 2006 Hans Verkuil <hverkuil@xs4all.nl>
   5 *
   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.
  10 *
  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.
  15 *
  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., 675 Mass Ave, Cambridge, MA 02139, USA.
  19 */
  20
  21
  22#include <linux/module.h>
  23#include <linux/errno.h>
  24#include <linux/kernel.h>
  25#include <linux/init.h>
  26#include <linux/types.h>
  27#include <linux/videodev2.h>
  28
  29#include <media/tuner.h>
  30#include <media/cx2341x.h>
  31#include <media/v4l2-common.h>
  32
  33MODULE_DESCRIPTION("cx23415/6 driver");
  34MODULE_AUTHOR("Hans Verkuil");
  35MODULE_LICENSE("GPL");
  36
  37static int debug = 0;
  38module_param(debug, int, 0644);
  39MODULE_PARM_DESC(debug, "Debug level (0-1)");
  40
  41const u32 cx2341x_mpeg_ctrls[] = {
  42        V4L2_CID_MPEG_CLASS,
  43        V4L2_CID_MPEG_STREAM_TYPE,
  44        V4L2_CID_MPEG_STREAM_VBI_FMT,
  45        V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
  46        V4L2_CID_MPEG_AUDIO_ENCODING,
  47        V4L2_CID_MPEG_AUDIO_L2_BITRATE,
  48        V4L2_CID_MPEG_AUDIO_MODE,
  49        V4L2_CID_MPEG_AUDIO_MODE_EXTENSION,
  50        V4L2_CID_MPEG_AUDIO_EMPHASIS,
  51        V4L2_CID_MPEG_AUDIO_CRC,
  52        V4L2_CID_MPEG_AUDIO_MUTE,
  53        V4L2_CID_MPEG_VIDEO_ENCODING,
  54        V4L2_CID_MPEG_VIDEO_ASPECT,
  55        V4L2_CID_MPEG_VIDEO_B_FRAMES,
  56        V4L2_CID_MPEG_VIDEO_GOP_SIZE,
  57        V4L2_CID_MPEG_VIDEO_GOP_CLOSURE,
  58        V4L2_CID_MPEG_VIDEO_BITRATE_MODE,
  59        V4L2_CID_MPEG_VIDEO_BITRATE,
  60        V4L2_CID_MPEG_VIDEO_BITRATE_PEAK,
  61        V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION,
  62        V4L2_CID_MPEG_VIDEO_MUTE,
  63        V4L2_CID_MPEG_VIDEO_MUTE_YUV,
  64        V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE,
  65        V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER,
  66        V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE,
  67        V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE,
  68        V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE,
  69        V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER,
  70        V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE,
  71        V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM,
  72        V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP,
  73        V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM,
  74        V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP,
  75        V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS,
  76        0
  77};
  78
  79
  80/* Map the control ID to the correct field in the cx2341x_mpeg_params
  81   struct. Return -EINVAL if the ID is unknown, else return 0. */
  82static int cx2341x_get_ctrl(struct cx2341x_mpeg_params *params,
  83                struct v4l2_ext_control *ctrl)
  84{
  85        switch (ctrl->id) {
  86        case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
  87                ctrl->value = params->audio_sampling_freq;
  88                break;
  89        case V4L2_CID_MPEG_AUDIO_ENCODING:
  90                ctrl->value = params->audio_encoding;
  91                break;
  92        case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
  93                ctrl->value = params->audio_l2_bitrate;
  94                break;
  95        case V4L2_CID_MPEG_AUDIO_MODE:
  96                ctrl->value = params->audio_mode;
  97                break;
  98        case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
  99                ctrl->value = params->audio_mode_extension;
 100                break;
 101        case V4L2_CID_MPEG_AUDIO_EMPHASIS:
 102                ctrl->value = params->audio_emphasis;
 103                break;
 104        case V4L2_CID_MPEG_AUDIO_CRC:
 105                ctrl->value = params->audio_crc;
 106                break;
 107        case V4L2_CID_MPEG_AUDIO_MUTE:
 108                ctrl->value = params->audio_mute;
 109                break;
 110        case V4L2_CID_MPEG_VIDEO_ENCODING:
 111                ctrl->value = params->video_encoding;
 112                break;
 113        case V4L2_CID_MPEG_VIDEO_ASPECT:
 114                ctrl->value = params->video_aspect;
 115                break;
 116        case V4L2_CID_MPEG_VIDEO_B_FRAMES:
 117                ctrl->value = params->video_b_frames;
 118                break;
 119        case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
 120                ctrl->value = params->video_gop_size;
 121                break;
 122        case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
 123                ctrl->value = params->video_gop_closure;
 124                break;
 125        case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
 126                ctrl->value = params->video_bitrate_mode;
 127                break;
 128        case V4L2_CID_MPEG_VIDEO_BITRATE:
 129                ctrl->value = params->video_bitrate;
 130                break;
 131        case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
 132                ctrl->value = params->video_bitrate_peak;
 133                break;
 134        case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
 135                ctrl->value = params->video_temporal_decimation;
 136                break;
 137        case V4L2_CID_MPEG_VIDEO_MUTE:
 138                ctrl->value = params->video_mute;
 139                break;
 140        case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
 141                ctrl->value = params->video_mute_yuv;
 142                break;
 143        case V4L2_CID_MPEG_STREAM_TYPE:
 144                ctrl->value = params->stream_type;
 145                break;
 146        case V4L2_CID_MPEG_STREAM_VBI_FMT:
 147                ctrl->value = params->stream_vbi_fmt;
 148                break;
 149        case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
 150                ctrl->value = params->video_spatial_filter_mode;
 151                break;
 152        case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
 153                ctrl->value = params->video_spatial_filter;
 154                break;
 155        case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
 156                ctrl->value = params->video_luma_spatial_filter_type;
 157                break;
 158        case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
 159                ctrl->value = params->video_chroma_spatial_filter_type;
 160                break;
 161        case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
 162                ctrl->value = params->video_temporal_filter_mode;
 163                break;
 164        case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
 165                ctrl->value = params->video_temporal_filter;
 166                break;
 167        case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
 168                ctrl->value = params->video_median_filter_type;
 169                break;
 170        case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
 171                ctrl->value = params->video_luma_median_filter_top;
 172                break;
 173        case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
 174                ctrl->value = params->video_luma_median_filter_bottom;
 175                break;
 176        case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
 177                ctrl->value = params->video_chroma_median_filter_top;
 178                break;
 179        case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
 180                ctrl->value = params->video_chroma_median_filter_bottom;
 181                break;
 182        case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
 183                ctrl->value = params->stream_insert_nav_packets;
 184                break;
 185        default:
 186                return -EINVAL;
 187        }
 188        return 0;
 189}
 190
 191/* Map the control ID to the correct field in the cx2341x_mpeg_params
 192   struct. Return -EINVAL if the ID is unknown, else return 0. */
 193static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
 194                struct v4l2_ext_control *ctrl)
 195{
 196        switch (ctrl->id) {
 197        case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
 198                if (busy)
 199                        return -EBUSY;
 200                params->audio_sampling_freq = ctrl->value;
 201                break;
 202        case V4L2_CID_MPEG_AUDIO_ENCODING:
 203                params->audio_encoding = ctrl->value;
 204                break;
 205        case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
 206                if (busy)
 207                        return -EBUSY;
 208                params->audio_l2_bitrate = ctrl->value;
 209                break;
 210        case V4L2_CID_MPEG_AUDIO_MODE:
 211                params->audio_mode = ctrl->value;
 212                break;
 213        case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
 214                params->audio_mode_extension = ctrl->value;
 215                break;
 216        case V4L2_CID_MPEG_AUDIO_EMPHASIS:
 217                params->audio_emphasis = ctrl->value;
 218                break;
 219        case V4L2_CID_MPEG_AUDIO_CRC:
 220                params->audio_crc = ctrl->value;
 221                break;
 222        case V4L2_CID_MPEG_AUDIO_MUTE:
 223                params->audio_mute = ctrl->value;
 224                break;
 225        case V4L2_CID_MPEG_VIDEO_ASPECT:
 226                params->video_aspect = ctrl->value;
 227                break;
 228        case V4L2_CID_MPEG_VIDEO_B_FRAMES: {
 229                int b = ctrl->value + 1;
 230                int gop = params->video_gop_size;
 231                params->video_b_frames = ctrl->value;
 232                params->video_gop_size = b * ((gop + b - 1) / b);
 233                /* Max GOP size = 34 */
 234                while (params->video_gop_size > 34)
 235                        params->video_gop_size -= b;
 236                break;
 237        }
 238        case V4L2_CID_MPEG_VIDEO_GOP_SIZE: {
 239                int b = params->video_b_frames + 1;
 240                int gop = ctrl->value;
 241                params->video_gop_size = b * ((gop + b - 1) / b);
 242                /* Max GOP size = 34 */
 243                while (params->video_gop_size > 34)
 244                        params->video_gop_size -= b;
 245                ctrl->value = params->video_gop_size;
 246                break;
 247        }
 248        case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
 249                params->video_gop_closure = ctrl->value;
 250                break;
 251        case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
 252                if (busy)
 253                        return -EBUSY;
 254                /* MPEG-1 only allows CBR */
 255                if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1 &&
 256                    ctrl->value != V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
 257                        return -EINVAL;
 258                params->video_bitrate_mode = ctrl->value;
 259                break;
 260        case V4L2_CID_MPEG_VIDEO_BITRATE:
 261                if (busy)
 262                        return -EBUSY;
 263                params->video_bitrate = ctrl->value;
 264                break;
 265        case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
 266                if (busy)
 267                        return -EBUSY;
 268                params->video_bitrate_peak = ctrl->value;
 269                break;
 270        case V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION:
 271                params->video_temporal_decimation = ctrl->value;
 272                break;
 273        case V4L2_CID_MPEG_VIDEO_MUTE:
 274                params->video_mute = (ctrl->value != 0);
 275                break;
 276        case V4L2_CID_MPEG_VIDEO_MUTE_YUV:
 277                params->video_mute_yuv = ctrl->value;
 278                break;
 279        case V4L2_CID_MPEG_STREAM_TYPE:
 280                if (busy)
 281                        return -EBUSY;
 282                params->stream_type = ctrl->value;
 283                params->video_encoding =
 284                        (params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_SS ||
 285                         params->stream_type == V4L2_MPEG_STREAM_TYPE_MPEG1_VCD) ?
 286                        V4L2_MPEG_VIDEO_ENCODING_MPEG_1 : V4L2_MPEG_VIDEO_ENCODING_MPEG_2;
 287                if (params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
 288                        /* MPEG-1 implies CBR */
 289                        params->video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_CBR;
 290                }
 291                break;
 292        case V4L2_CID_MPEG_STREAM_VBI_FMT:
 293                params->stream_vbi_fmt = ctrl->value;
 294                break;
 295        case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
 296                params->video_spatial_filter_mode = ctrl->value;
 297                break;
 298        case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
 299                params->video_spatial_filter = ctrl->value;
 300                break;
 301        case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
 302                params->video_luma_spatial_filter_type = ctrl->value;
 303                break;
 304        case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
 305                params->video_chroma_spatial_filter_type = ctrl->value;
 306                break;
 307        case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
 308                params->video_temporal_filter_mode = ctrl->value;
 309                break;
 310        case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
 311                params->video_temporal_filter = ctrl->value;
 312                break;
 313        case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
 314                params->video_median_filter_type = ctrl->value;
 315                break;
 316        case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
 317                params->video_luma_median_filter_top = ctrl->value;
 318                break;
 319        case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
 320                params->video_luma_median_filter_bottom = ctrl->value;
 321                break;
 322        case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
 323                params->video_chroma_median_filter_top = ctrl->value;
 324                break;
 325        case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
 326                params->video_chroma_median_filter_bottom = ctrl->value;
 327                break;
 328        case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
 329                params->stream_insert_nav_packets = ctrl->value;
 330                break;
 331        default:
 332                return -EINVAL;
 333        }
 334        return 0;
 335}
 336
 337static int cx2341x_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 step, s32 def)
 338{
 339        const char *name;
 340
 341        qctrl->flags = 0;
 342        switch (qctrl->id) {
 343        /* MPEG controls */
 344        case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
 345                name = "Spatial Filter Mode";
 346                break;
 347        case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
 348                name = "Spatial Filter";
 349                break;
 350        case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
 351                name = "Spatial Luma Filter Type";
 352                break;
 353        case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
 354                name = "Spatial Chroma Filter Type";
 355                break;
 356        case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
 357                name = "Temporal Filter Mode";
 358                break;
 359        case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
 360                name = "Temporal Filter";
 361                break;
 362        case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
 363                name = "Median Filter Type";
 364                break;
 365        case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
 366                name = "Median Luma Filter Maximum";
 367                break;
 368        case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
 369                name = "Median Luma Filter Minimum";
 370                break;
 371        case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
 372                name = "Median Chroma Filter Maximum";
 373                break;
 374        case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
 375                name = "Median Chroma Filter Minimum";
 376                break;
 377        case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
 378                name = "Insert Navigation Packets";
 379                break;
 380
 381        default:
 382                return v4l2_ctrl_query_fill(qctrl, min, max, step, def);
 383        }
 384        switch (qctrl->id) {
 385        case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
 386        case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
 387        case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
 388        case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
 389        case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
 390                qctrl->type = V4L2_CTRL_TYPE_MENU;
 391                min = 0;
 392                step = 1;
 393                break;
 394        case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
 395                qctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
 396                min = 0;
 397                max = 1;
 398                step = 1;
 399                break;
 400        default:
 401                qctrl->type = V4L2_CTRL_TYPE_INTEGER;
 402                break;
 403        }
 404        switch (qctrl->id) {
 405        case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
 406        case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
 407        case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
 408                qctrl->flags |= V4L2_CTRL_FLAG_UPDATE;
 409                break;
 410        }
 411        qctrl->minimum = min;
 412        qctrl->maximum = max;
 413        qctrl->step = step;
 414        qctrl->default_value = def;
 415        qctrl->reserved[0] = qctrl->reserved[1] = 0;
 416        snprintf(qctrl->name, sizeof(qctrl->name), name);
 417        return 0;
 418}
 419
 420int cx2341x_ctrl_query(struct cx2341x_mpeg_params *params, struct v4l2_queryctrl *qctrl)
 421{
 422        int err;
 423
 424        switch (qctrl->id) {
 425        case V4L2_CID_MPEG_AUDIO_ENCODING:
 426                return v4l2_ctrl_query_fill(qctrl,
 427                                V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
 428                                V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 1,
 429                                V4L2_MPEG_AUDIO_ENCODING_LAYER_2);
 430
 431        case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
 432                return v4l2_ctrl_query_fill(qctrl,
 433                                V4L2_MPEG_AUDIO_L2_BITRATE_192K,
 434                                V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
 435                                V4L2_MPEG_AUDIO_L2_BITRATE_224K);
 436
 437        case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
 438        case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
 439                return -EINVAL;
 440
 441        case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
 442                err = v4l2_ctrl_query_fill_std(qctrl);
 443                if (err == 0 && params->audio_mode != V4L2_MPEG_AUDIO_MODE_JOINT_STEREO)
 444                        qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 445                return err;
 446
 447        case V4L2_CID_MPEG_VIDEO_ENCODING:
 448                /* this setting is read-only for the cx2341x since the
 449                   V4L2_CID_MPEG_STREAM_TYPE really determines the
 450                   MPEG-1/2 setting */
 451                err = v4l2_ctrl_query_fill_std(qctrl);
 452                if (err == 0)
 453                        qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
 454                return err;
 455
 456        case V4L2_CID_MPEG_VIDEO_BITRATE_MODE:
 457                err = v4l2_ctrl_query_fill_std(qctrl);
 458                if (err == 0 && params->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
 459                        qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 460                return err;
 461
 462        case V4L2_CID_MPEG_VIDEO_BITRATE_PEAK:
 463                err = v4l2_ctrl_query_fill_std(qctrl);
 464                if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_CBR)
 465                        qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 466                return err;
 467
 468        case V4L2_CID_MPEG_STREAM_VBI_FMT:
 469                if (params->capabilities & CX2341X_CAP_HAS_SLICED_VBI)
 470                        return v4l2_ctrl_query_fill_std(qctrl);
 471                return cx2341x_ctrl_query_fill(qctrl,
 472                                V4L2_MPEG_STREAM_VBI_FMT_NONE,
 473                                V4L2_MPEG_STREAM_VBI_FMT_NONE, 1,
 474                                V4L2_MPEG_STREAM_VBI_FMT_NONE);
 475
 476        /* CX23415/6 specific */
 477        case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
 478                return cx2341x_ctrl_query_fill(qctrl,
 479                                V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
 480                                V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO, 1,
 481                                V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL);
 482
 483        case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER:
 484                cx2341x_ctrl_query_fill(qctrl, 0, 15, 1, 0);
 485                qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
 486                if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
 487                       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 488                return 0;
 489
 490        case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
 491                cx2341x_ctrl_query_fill(qctrl,
 492                                V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF,
 493                                V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE, 1,
 494                                V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF);
 495                if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
 496                       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 497                return 0;
 498
 499        case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
 500                cx2341x_ctrl_query_fill(qctrl,
 501                                V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF,
 502                                V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR, 1,
 503                                V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF);
 504                if (params->video_spatial_filter_mode == V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO)
 505                       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 506                return 0;
 507
 508        case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
 509                return cx2341x_ctrl_query_fill(qctrl,
 510                                V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
 511                                V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO, 1,
 512                                V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL);
 513
 514        case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER:
 515                cx2341x_ctrl_query_fill(qctrl, 0, 31, 1, 0);
 516                qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
 517                if (params->video_temporal_filter_mode == V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO)
 518                       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 519                return 0;
 520
 521        case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
 522                return cx2341x_ctrl_query_fill(qctrl,
 523                                V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
 524                                V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG, 1,
 525                                V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF);
 526
 527        case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP:
 528                cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255);
 529                qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
 530                if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
 531                       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 532                return 0;
 533
 534        case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM:
 535                cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
 536                qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
 537                if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
 538                       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 539                return 0;
 540
 541        case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP:
 542                cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 255);
 543                qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
 544                if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
 545                       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 546                return 0;
 547
 548        case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM:
 549                cx2341x_ctrl_query_fill(qctrl, 0, 255, 1, 0);
 550                qctrl->flags |= V4L2_CTRL_FLAG_SLIDER;
 551                if (params->video_median_filter_type == V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF)
 552                       qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
 553                return 0;
 554
 555        case V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS:
 556                return cx2341x_ctrl_query_fill(qctrl, 0, 1, 1, 0);
 557
 558        default:
 559                return v4l2_ctrl_query_fill_std(qctrl);
 560
 561        }
 562}
 563
 564const char **cx2341x_ctrl_get_menu(u32 id)
 565{
 566        static const char *mpeg_stream_type[] = {
 567                "MPEG-2 Program Stream",
 568                "",
 569                "MPEG-1 System Stream",
 570                "MPEG-2 DVD-compatible Stream",
 571                "MPEG-1 VCD-compatible Stream",
 572                "MPEG-2 SVCD-compatible Stream",
 573                NULL
 574        };
 575
 576        static const char *cx2341x_video_spatial_filter_mode_menu[] = {
 577                "Manual",
 578                "Auto",
 579                NULL
 580        };
 581
 582        static const char *cx2341x_video_luma_spatial_filter_type_menu[] = {
 583                "Off",
 584                "1D Horizontal",
 585                "1D Vertical",
 586                "2D H/V Separable",
 587                "2D Symmetric non-separable",
 588                NULL
 589        };
 590
 591        static const char *cx2341x_video_chroma_spatial_filter_type_menu[] = {
 592                "Off",
 593                "1D Horizontal",
 594                NULL
 595        };
 596
 597        static const char *cx2341x_video_temporal_filter_mode_menu[] = {
 598                "Manual",
 599                "Auto",
 600                NULL
 601        };
 602
 603        static const char *cx2341x_video_median_filter_type_menu[] = {
 604                "Off",
 605                "Horizontal",
 606                "Vertical",
 607                "Horizontal/Vertical",
 608                "Diagonal",
 609                NULL
 610        };
 611
 612        switch (id) {
 613        case V4L2_CID_MPEG_STREAM_TYPE:
 614                return mpeg_stream_type;
 615        case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
 616        case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
 617                return NULL;
 618        case V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE:
 619                return cx2341x_video_spatial_filter_mode_menu;
 620        case V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE:
 621                return cx2341x_video_luma_spatial_filter_type_menu;
 622        case V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE:
 623                return cx2341x_video_chroma_spatial_filter_type_menu;
 624        case V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE:
 625                return cx2341x_video_temporal_filter_mode_menu;
 626        case V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE:
 627                return cx2341x_video_median_filter_type_menu;
 628        default:
 629                return v4l2_ctrl_get_menu(id);
 630        }
 631}
 632
 633static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
 634{
 635        params->audio_properties = (params->audio_sampling_freq << 0) |
 636                ((3 - params->audio_encoding) << 2) |
 637                ((1 + params->audio_l2_bitrate) << 4) |
 638                (params->audio_mode << 8) |
 639                (params->audio_mode_extension << 10) |
 640                (((params->audio_emphasis == V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17) ?
 641                  3 :
 642                  params->audio_emphasis) << 12) |
 643                (params->audio_crc << 14);
 644}
 645
 646int cx2341x_ext_ctrls(struct cx2341x_mpeg_params *params, int busy,
 647                  struct v4l2_ext_controls *ctrls, unsigned int cmd)
 648{
 649        int err = 0;
 650        int i;
 651
 652        if (cmd == VIDIOC_G_EXT_CTRLS) {
 653                for (i = 0; i < ctrls->count; i++) {
 654                        struct v4l2_ext_control *ctrl = ctrls->controls + i;
 655
 656                        err = cx2341x_get_ctrl(params, ctrl);
 657                        if (err) {
 658                                ctrls->error_idx = i;
 659                                break;
 660                        }
 661                }
 662                return err;
 663        }
 664        for (i = 0; i < ctrls->count; i++) {
 665                struct v4l2_ext_control *ctrl = ctrls->controls + i;
 666                struct v4l2_queryctrl qctrl;
 667                const char **menu_items = NULL;
 668
 669                qctrl.id = ctrl->id;
 670                err = cx2341x_ctrl_query(params, &qctrl);
 671                if (err)
 672                        break;
 673                if (qctrl.type == V4L2_CTRL_TYPE_MENU)
 674                        menu_items = cx2341x_ctrl_get_menu(qctrl.id);
 675                err = v4l2_ctrl_check(ctrl, &qctrl, menu_items);
 676                if (err)
 677                        break;
 678                err = cx2341x_set_ctrl(params, busy, ctrl);
 679                if (err)
 680                        break;
 681        }
 682        if (err == 0 && params->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR &&
 683                        params->video_bitrate_peak < params->video_bitrate) {
 684                err = -ERANGE;
 685                ctrls->error_idx = ctrls->count;
 686        }
 687        if (err) {
 688                ctrls->error_idx = i;
 689        }
 690        else {
 691                cx2341x_calc_audio_properties(params);
 692        }
 693        return err;
 694}
 695
 696void cx2341x_fill_defaults(struct cx2341x_mpeg_params *p)
 697{
 698        static struct cx2341x_mpeg_params default_params = {
 699        /* misc */
 700        .capabilities = 0,
 701        .port = CX2341X_PORT_MEMORY,
 702        .width = 720,
 703        .height = 480,
 704        .is_50hz = 0,
 705
 706        /* stream */
 707        .stream_type = V4L2_MPEG_STREAM_TYPE_MPEG2_PS,
 708        .stream_vbi_fmt = V4L2_MPEG_STREAM_VBI_FMT_NONE,
 709        .stream_insert_nav_packets = 0,
 710
 711        /* audio */
 712        .audio_sampling_freq = V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000,
 713        .audio_encoding = V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
 714        .audio_l2_bitrate = V4L2_MPEG_AUDIO_L2_BITRATE_224K,
 715        .audio_mode = V4L2_MPEG_AUDIO_MODE_STEREO,
 716        .audio_mode_extension = V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4,
 717        .audio_emphasis = V4L2_MPEG_AUDIO_EMPHASIS_NONE,
 718        .audio_crc = V4L2_MPEG_AUDIO_CRC_NONE,
 719        .audio_mute = 0,
 720
 721        /* video */
 722        .video_encoding = V4L2_MPEG_VIDEO_ENCODING_MPEG_2,
 723        .video_aspect = V4L2_MPEG_VIDEO_ASPECT_4x3,
 724        .video_b_frames = 2,
 725        .video_gop_size = 12,
 726        .video_gop_closure = 1,
 727        .video_bitrate_mode = V4L2_MPEG_VIDEO_BITRATE_MODE_VBR,
 728        .video_bitrate = 6000000,
 729        .video_bitrate_peak = 8000000,
 730        .video_temporal_decimation = 0,
 731        .video_mute = 0,
 732        .video_mute_yuv = 0x008080,  /* YCbCr value for black */
 733
 734        /* encoding filters */
 735        .video_spatial_filter_mode = V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL,
 736        .video_spatial_filter = 0,
 737        .video_luma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR,
 738        .video_chroma_spatial_filter_type = V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR,
 739        .video_temporal_filter_mode = V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL,
 740        .video_temporal_filter = 8,
 741        .video_median_filter_type = V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF,
 742        .video_luma_median_filter_top = 255,
 743        .video_luma_median_filter_bottom = 0,
 744        .video_chroma_median_filter_top = 255,
 745        .video_chroma_median_filter_bottom = 0,
 746        };
 747
 748        *p = default_params;
 749        cx2341x_calc_audio_properties(p);
 750}
 751
 752static int cx2341x_api(void *priv, cx2341x_mbox_func func, int cmd, int args, ...)
 753{
 754        u32 data[CX2341X_MBOX_MAX_DATA];
 755        va_list vargs;
 756        int i;
 757
 758        va_start(vargs, args);
 759
 760        for (i = 0; i < args; i++) {
 761                data[i] = va_arg(vargs, int);
 762        }
 763        va_end(vargs);
 764        return func(priv, cmd, args, 0, data);
 765}
 766
 767int cx2341x_update(void *priv, cx2341x_mbox_func func,
 768                const struct cx2341x_mpeg_params *old, const struct cx2341x_mpeg_params *new)
 769{
 770        static int mpeg_stream_type[] = {
 771                0,      /* MPEG-2 PS */
 772                1,      /* MPEG-2 TS */
 773                2,      /* MPEG-1 SS */
 774                14,     /* DVD */
 775                11,     /* VCD */
 776                12,     /* SVCD */
 777        };
 778
 779        int err = 0;
 780        u16 temporal = new->video_temporal_filter;
 781
 782        cx2341x_api(priv, func, CX2341X_ENC_SET_OUTPUT_PORT, 2, new->port, 0);
 783
 784        if (old == NULL || old->is_50hz != new->is_50hz) {
 785                err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_RATE, 1, new->is_50hz);
 786                if (err) return err;
 787        }
 788
 789        if (old == NULL || old->width != new->width || old->height != new->height ||
 790                        old->video_encoding != new->video_encoding) {
 791                u16 w = new->width;
 792                u16 h = new->height;
 793
 794                if (new->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1) {
 795                        w /= 2;
 796                        h /= 2;
 797                }
 798                err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_SIZE, 2, h, w);
 799                if (err) return err;
 800        }
 801
 802        if (new->width != 720 || new->height != (new->is_50hz ? 576 : 480)) {
 803                /* Adjust temporal filter if necessary. The problem with the temporal
 804                   filter is that it works well with full resolution capturing, but
 805                   not when the capture window is scaled (the filter introduces
 806                   a ghosting effect). So if the capture window is scaled, then
 807                   force the filter to 0.
 808
 809                   For full resolution the filter really improves the video
 810                   quality, especially if the original video quality is suboptimal. */
 811                temporal = 0;
 812        }
 813
 814        if (old == NULL || old->stream_type != new->stream_type) {
 815                err = cx2341x_api(priv, func, CX2341X_ENC_SET_STREAM_TYPE, 1, mpeg_stream_type[new->stream_type]);
 816                if (err) return err;
 817        }
 818        if (old == NULL || old->video_aspect != new->video_aspect) {
 819                err = cx2341x_api(priv, func, CX2341X_ENC_SET_ASPECT_RATIO, 1, 1 + new->video_aspect);
 820                if (err) return err;
 821        }
 822        if (old == NULL || old->video_b_frames != new->video_b_frames ||
 823                old->video_gop_size != new->video_gop_size) {
 824                err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_PROPERTIES, 2,
 825                                new->video_gop_size, new->video_b_frames + 1);
 826                if (err) return err;
 827        }
 828        if (old == NULL || old->video_gop_closure != new->video_gop_closure) {
 829                err = cx2341x_api(priv, func, CX2341X_ENC_SET_GOP_CLOSURE, 1, new->video_gop_closure);
 830                if (err) return err;
 831        }
 832        if (old == NULL || old->audio_properties != new->audio_properties) {
 833                err = cx2341x_api(priv, func, CX2341X_ENC_SET_AUDIO_PROPERTIES, 1, new->audio_properties);
 834                if (err) return err;
 835        }
 836        if (old == NULL || old->audio_mute != new->audio_mute) {
 837                err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_AUDIO, 1, new->audio_mute);
 838                if (err) return err;
 839        }
 840        if (old == NULL || old->video_bitrate_mode != new->video_bitrate_mode ||
 841                old->video_bitrate != new->video_bitrate ||
 842                old->video_bitrate_peak != new->video_bitrate_peak) {
 843                err = cx2341x_api(priv, func, CX2341X_ENC_SET_BIT_RATE, 5,
 844                                new->video_bitrate_mode, new->video_bitrate,
 845                                new->video_bitrate_peak / 400, 0, 0);
 846                if (err) return err;
 847        }
 848        if (old == NULL || old->video_spatial_filter_mode != new->video_spatial_filter_mode ||
 849                old->video_temporal_filter_mode != new->video_temporal_filter_mode ||
 850                old->video_median_filter_type != new->video_median_filter_type) {
 851                err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_MODE, 2,
 852                                new->video_spatial_filter_mode | (new->video_temporal_filter_mode << 1),
 853                                new->video_median_filter_type);
 854                if (err) return err;
 855        }
 856        if (old == NULL ||
 857                old->video_luma_median_filter_bottom != new->video_luma_median_filter_bottom ||
 858                old->video_luma_median_filter_top != new->video_luma_median_filter_top ||
 859                old->video_chroma_median_filter_bottom != new->video_chroma_median_filter_bottom ||
 860                old->video_chroma_median_filter_top != new->video_chroma_median_filter_top) {
 861                err = cx2341x_api(priv, func, CX2341X_ENC_SET_CORING_LEVELS, 4,
 862                                new->video_luma_median_filter_bottom,
 863                                new->video_luma_median_filter_top,
 864                                new->video_chroma_median_filter_bottom,
 865                                new->video_chroma_median_filter_top);
 866                if (err) return err;
 867        }
 868        if (old == NULL ||
 869                old->video_luma_spatial_filter_type != new->video_luma_spatial_filter_type ||
 870                old->video_chroma_spatial_filter_type != new->video_chroma_spatial_filter_type) {
 871                err = cx2341x_api(priv, func, CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 2,
 872                        new->video_luma_spatial_filter_type, new->video_chroma_spatial_filter_type);
 873                if (err) return err;
 874        }
 875        if (old == NULL ||
 876                old->video_spatial_filter != new->video_spatial_filter ||
 877                old->video_temporal_filter != temporal) {
 878                err = cx2341x_api(priv, func, CX2341X_ENC_SET_DNR_FILTER_PROPS, 2,
 879                        new->video_spatial_filter, temporal);
 880                if (err) return err;
 881        }
 882        if (old == NULL || old->video_temporal_decimation != new->video_temporal_decimation) {
 883                err = cx2341x_api(priv, func, CX2341X_ENC_SET_FRAME_DROP_RATE, 1,
 884                        new->video_temporal_decimation);
 885                if (err) return err;
 886        }
 887        if (old == NULL || old->video_mute != new->video_mute ||
 888                        (new->video_mute && old->video_mute_yuv != new->video_mute_yuv)) {
 889                err = cx2341x_api(priv, func, CX2341X_ENC_MUTE_VIDEO, 1, new->video_mute | (new->video_mute_yuv << 8));
 890                if (err) return err;
 891        }
 892        if (old == NULL || old->stream_insert_nav_packets != new->stream_insert_nav_packets) {
 893                err = cx2341x_api(priv, func, CX2341X_ENC_MISC, 2, 7, new->stream_insert_nav_packets);
 894                if (err) return err;
 895        }
 896        return 0;
 897}
 898
 899static const char *cx2341x_menu_item(struct cx2341x_mpeg_params *p, u32 id)
 900{
 901        const char **menu = cx2341x_ctrl_get_menu(id);
 902        struct v4l2_ext_control ctrl;
 903
 904        if (menu == NULL)
 905                goto invalid;
 906        ctrl.id = id;
 907        if (cx2341x_get_ctrl(p, &ctrl))
 908                goto invalid;
 909        while (ctrl.value-- && *menu) menu++;
 910        if (*menu == NULL)
 911                goto invalid;
 912        return *menu;
 913
 914invalid:
 915        return "<invalid>";
 916}
 917
 918void cx2341x_log_status(struct cx2341x_mpeg_params *p, const char *prefix)
 919{
 920        int is_mpeg1 = p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
 921        int temporal = p->video_temporal_filter;
 922
 923        /* Stream */
 924        printk(KERN_INFO "%s: Stream: %s",
 925                prefix,
 926                cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_TYPE));
 927        if (p->stream_insert_nav_packets)
 928                printk(" (with navigation packets)");
 929        printk("\n");
 930        printk(KERN_INFO "%s: VBI Format: %s\n",
 931                prefix,
 932                cx2341x_menu_item(p, V4L2_CID_MPEG_STREAM_VBI_FMT));
 933
 934        /* Video */
 935        printk(KERN_INFO "%s: Video:  %dx%d, %d fps%s\n",
 936                prefix,
 937                p->width / (is_mpeg1 ? 2 : 1), p->height / (is_mpeg1 ? 2 : 1),
 938                p->is_50hz ? 25 : 30,
 939                (p->video_mute) ? " (muted)" : "");
 940        printk(KERN_INFO "%s: Video:  %s, %s, %s, %d",
 941                prefix,
 942                cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ENCODING),
 943                cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_ASPECT),
 944                cx2341x_menu_item(p, V4L2_CID_MPEG_VIDEO_BITRATE_MODE),
 945                p->video_bitrate);
 946        if (p->video_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) {
 947                printk(", Peak %d", p->video_bitrate_peak);
 948        }
 949        printk("\n");
 950        printk(KERN_INFO "%s: Video:  GOP Size %d, %d B-Frames, %sGOP Closure\n",
 951                prefix,
 952                p->video_gop_size, p->video_b_frames,
 953                p->video_gop_closure ? "" : "No ");
 954        if (p->video_temporal_decimation) {
 955                printk(KERN_INFO "%s: Video: Temporal Decimation %d\n",
 956                        prefix, p->video_temporal_decimation);
 957        }
 958
 959        /* Audio */
 960        printk(KERN_INFO "%s: Audio:  %s, %s, %s, %s%s",
 961                prefix,
 962                cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ),
 963                cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_ENCODING),
 964                cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_L2_BITRATE),
 965                cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE),
 966                p->audio_mute ? " (muted)" : "");
 967        if (p->audio_mode == V4L2_MPEG_AUDIO_MODE_JOINT_STEREO) {
 968                printk(", %s",
 969                        cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_MODE_EXTENSION));
 970        }
 971        printk(", %s, %s\n",
 972                cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_EMPHASIS),
 973                cx2341x_menu_item(p, V4L2_CID_MPEG_AUDIO_CRC));
 974
 975        /* Encoding filters */
 976        printk(KERN_INFO "%s: Spatial Filter:  %s, Luma %s, Chroma %s, %d\n",
 977                prefix,
 978                cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE),
 979                cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE),
 980                cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE),
 981                p->video_spatial_filter);
 982        if (p->width != 720 || p->height != (p->is_50hz ? 576 : 480)) {
 983                temporal = 0;
 984        }
 985        printk(KERN_INFO "%s: Temporal Filter: %s, %d\n",
 986                prefix,
 987                cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE),
 988                temporal);
 989        printk(KERN_INFO "%s: Median Filter:   %s, Luma [%d, %d], Chroma [%d, %d]\n",
 990                prefix,
 991                cx2341x_menu_item(p, V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE),
 992                p->video_luma_median_filter_bottom,
 993                p->video_luma_median_filter_top,
 994                p->video_chroma_median_filter_bottom,
 995                p->video_chroma_median_filter_top);
 996}
 997
 998EXPORT_SYMBOL(cx2341x_fill_defaults);
 999EXPORT_SYMBOL(cx2341x_ctrl_query);
1000EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
1001EXPORT_SYMBOL(cx2341x_ext_ctrls);
1002EXPORT_SYMBOL(cx2341x_update);
1003EXPORT_SYMBOL(cx2341x_log_status);
1004EXPORT_SYMBOL(cx2341x_mpeg_ctrls);
1005
1006/*
1007 * Local variables:
1008 * c-basic-offset: 8
1009 * End:
1010 */
1011
1012