linux/drivers/media/pci/cx18/cx18-ioctl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/*
   3 *  cx18 ioctl system call
   4 *
   5 *  Derived from ivtv-ioctl.c
   6 *
   7 *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
   8 *  Copyright (C) 2008  Andy Walls <awalls@md.metrocast.net>
   9 */
  10
  11#include "cx18-driver.h"
  12#include "cx18-io.h"
  13#include "cx18-version.h"
  14#include "cx18-mailbox.h"
  15#include "cx18-i2c.h"
  16#include "cx18-queue.h"
  17#include "cx18-fileops.h"
  18#include "cx18-vbi.h"
  19#include "cx18-audio.h"
  20#include "cx18-video.h"
  21#include "cx18-streams.h"
  22#include "cx18-ioctl.h"
  23#include "cx18-gpio.h"
  24#include "cx18-controls.h"
  25#include "cx18-cards.h"
  26#include "cx18-av-core.h"
  27#include <media/tveeprom.h>
  28#include <media/v4l2-event.h>
  29
  30u16 cx18_service2vbi(int type)
  31{
  32        switch (type) {
  33        case V4L2_SLICED_TELETEXT_B:
  34                return CX18_SLICED_TYPE_TELETEXT_B;
  35        case V4L2_SLICED_CAPTION_525:
  36                return CX18_SLICED_TYPE_CAPTION_525;
  37        case V4L2_SLICED_WSS_625:
  38                return CX18_SLICED_TYPE_WSS_625;
  39        case V4L2_SLICED_VPS:
  40                return CX18_SLICED_TYPE_VPS;
  41        default:
  42                return 0;
  43        }
  44}
  45
  46/* Check if VBI services are allowed on the (field, line) for the video std */
  47static int valid_service_line(int field, int line, int is_pal)
  48{
  49        return (is_pal && line >= 6 &&
  50                ((field == 0 && line <= 23) || (field == 1 && line <= 22))) ||
  51               (!is_pal && line >= 10 && line < 22);
  52}
  53
  54/*
  55 * For a (field, line, std) and inbound potential set of services for that line,
  56 * return the first valid service of those passed in the incoming set for that
  57 * line in priority order:
  58 * CC, VPS, or WSS over TELETEXT for well known lines
  59 * TELETEXT, before VPS, before CC, before WSS, for other lines
  60 */
  61static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
  62{
  63        u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
  64        int i;
  65
  66        set = set & valid_set;
  67        if (set == 0 || !valid_service_line(field, line, is_pal))
  68                return 0;
  69        if (!is_pal) {
  70                if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
  71                        return V4L2_SLICED_CAPTION_525;
  72        } else {
  73                if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
  74                        return V4L2_SLICED_VPS;
  75                if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
  76                        return V4L2_SLICED_WSS_625;
  77                if (line == 23)
  78                        return 0;
  79        }
  80        for (i = 0; i < 32; i++) {
  81                if ((1 << i) & set)
  82                        return 1 << i;
  83        }
  84        return 0;
  85}
  86
  87/*
  88 * Expand the service_set of *fmt into valid service_lines for the std,
  89 * and clear the passed in fmt->service_set
  90 */
  91void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
  92{
  93        u16 set = fmt->service_set;
  94        int f, l;
  95
  96        fmt->service_set = 0;
  97        for (f = 0; f < 2; f++) {
  98                for (l = 0; l < 24; l++)
  99                        fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
 100        }
 101}
 102
 103/*
 104 * Sanitize the service_lines in *fmt per the video std, and return 1
 105 * if any service_line is left as valid after santization
 106 */
 107static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
 108{
 109        int f, l;
 110        u16 set = 0;
 111
 112        for (f = 0; f < 2; f++) {
 113                for (l = 0; l < 24; l++) {
 114                        fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
 115                        set |= fmt->service_lines[f][l];
 116                }
 117        }
 118        return set != 0;
 119}
 120
 121/* Compute the service_set from the assumed valid service_lines of *fmt */
 122u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
 123{
 124        int f, l;
 125        u16 set = 0;
 126
 127        for (f = 0; f < 2; f++) {
 128                for (l = 0; l < 24; l++)
 129                        set |= fmt->service_lines[f][l];
 130        }
 131        return set;
 132}
 133
 134static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
 135                                struct v4l2_format *fmt)
 136{
 137        struct cx18_open_id *id = fh2id(fh);
 138        struct cx18 *cx = id->cx;
 139        struct cx18_stream *s = &cx->streams[id->type];
 140        struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
 141
 142        pixfmt->width = cx->cxhdl.width;
 143        pixfmt->height = cx->cxhdl.height;
 144        pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
 145        pixfmt->field = V4L2_FIELD_INTERLACED;
 146        if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
 147                pixfmt->pixelformat = s->pixelformat;
 148                pixfmt->sizeimage = s->vb_bytes_per_frame;
 149                pixfmt->bytesperline = s->vb_bytes_per_line;
 150        } else {
 151                pixfmt->pixelformat = V4L2_PIX_FMT_MPEG;
 152                pixfmt->sizeimage = 128 * 1024;
 153                pixfmt->bytesperline = 0;
 154        }
 155        return 0;
 156}
 157
 158static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
 159                                struct v4l2_format *fmt)
 160{
 161        struct cx18 *cx = fh2id(fh)->cx;
 162        struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
 163
 164        vbifmt->sampling_rate = 27000000;
 165        vbifmt->offset = 248; /* FIXME - slightly wrong for both 50 & 60 Hz */
 166        vbifmt->samples_per_line = VBI_ACTIVE_SAMPLES - 4;
 167        vbifmt->sample_format = V4L2_PIX_FMT_GREY;
 168        vbifmt->start[0] = cx->vbi.start[0];
 169        vbifmt->start[1] = cx->vbi.start[1];
 170        vbifmt->count[0] = vbifmt->count[1] = cx->vbi.count;
 171        vbifmt->flags = 0;
 172        vbifmt->reserved[0] = 0;
 173        vbifmt->reserved[1] = 0;
 174        return 0;
 175}
 176
 177static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
 178                                        struct v4l2_format *fmt)
 179{
 180        struct cx18 *cx = fh2id(fh)->cx;
 181        struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
 182
 183        /* sane, V4L2 spec compliant, defaults */
 184        vbifmt->reserved[0] = 0;
 185        vbifmt->reserved[1] = 0;
 186        vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
 187        memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
 188        vbifmt->service_set = 0;
 189
 190        /*
 191         * Fetch the configured service_lines and total service_set from the
 192         * digitizer/slicer.  Note, cx18_av_vbi() wipes the passed in
 193         * fmt->fmt.sliced under valid calling conditions
 194         */
 195        if (v4l2_subdev_call(cx->sd_av, vbi, g_sliced_fmt, &fmt->fmt.sliced))
 196                return -EINVAL;
 197
 198        vbifmt->service_set = cx18_get_service_set(vbifmt);
 199        return 0;
 200}
 201
 202static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
 203                                struct v4l2_format *fmt)
 204{
 205        struct cx18_open_id *id = fh2id(fh);
 206        struct cx18 *cx = id->cx;
 207        int w = fmt->fmt.pix.width;
 208        int h = fmt->fmt.pix.height;
 209        int min_h = 2;
 210
 211        w = min(w, 720);
 212        w = max(w, 2);
 213        if (id->type == CX18_ENC_STREAM_TYPE_YUV) {
 214                /* YUV height must be a multiple of 32 */
 215                h &= ~0x1f;
 216                min_h = 32;
 217        }
 218        h = min(h, cx->is_50hz ? 576 : 480);
 219        h = max(h, min_h);
 220
 221        fmt->fmt.pix.width = w;
 222        fmt->fmt.pix.height = h;
 223        return 0;
 224}
 225
 226static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
 227                                struct v4l2_format *fmt)
 228{
 229        return cx18_g_fmt_vbi_cap(file, fh, fmt);
 230}
 231
 232static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
 233                                        struct v4l2_format *fmt)
 234{
 235        struct cx18 *cx = fh2id(fh)->cx;
 236        struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
 237
 238        vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
 239        vbifmt->reserved[0] = 0;
 240        vbifmt->reserved[1] = 0;
 241
 242        /* If given a service set, expand it validly & clear passed in set */
 243        if (vbifmt->service_set)
 244                cx18_expand_service_set(vbifmt, cx->is_50hz);
 245        /* Sanitize the service_lines, and compute the new set if any valid */
 246        if (check_service_set(vbifmt, cx->is_50hz))
 247                vbifmt->service_set = cx18_get_service_set(vbifmt);
 248        return 0;
 249}
 250
 251static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
 252                                struct v4l2_format *fmt)
 253{
 254        struct cx18_open_id *id = fh2id(fh);
 255        struct cx18 *cx = id->cx;
 256        struct v4l2_subdev_format format = {
 257                .which = V4L2_SUBDEV_FORMAT_ACTIVE,
 258        };
 259        struct cx18_stream *s = &cx->streams[id->type];
 260        int ret;
 261        int w, h;
 262
 263        ret = cx18_try_fmt_vid_cap(file, fh, fmt);
 264        if (ret)
 265                return ret;
 266        w = fmt->fmt.pix.width;
 267        h = fmt->fmt.pix.height;
 268
 269        if (cx->cxhdl.width == w && cx->cxhdl.height == h &&
 270            s->pixelformat == fmt->fmt.pix.pixelformat)
 271                return 0;
 272
 273        if (atomic_read(&cx->ana_capturing) > 0)
 274                return -EBUSY;
 275
 276        s->pixelformat = fmt->fmt.pix.pixelformat;
 277        /* HM12 YUV size is (Y=(h*720) + UV=(h*(720/2)))
 278           UYUV YUV size is (Y=(h*720) + UV=(h*(720))) */
 279        if (s->pixelformat == V4L2_PIX_FMT_HM12) {
 280                s->vb_bytes_per_frame = h * 720 * 3 / 2;
 281                s->vb_bytes_per_line = 720; /* First plane */
 282        } else {
 283                s->vb_bytes_per_frame = h * 720 * 2;
 284                s->vb_bytes_per_line = 1440; /* Packed */
 285        }
 286
 287        format.format.width = cx->cxhdl.width = w;
 288        format.format.height = cx->cxhdl.height = h;
 289        format.format.code = MEDIA_BUS_FMT_FIXED;
 290        v4l2_subdev_call(cx->sd_av, pad, set_fmt, NULL, &format);
 291        return cx18_g_fmt_vid_cap(file, fh, fmt);
 292}
 293
 294static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
 295                                struct v4l2_format *fmt)
 296{
 297        struct cx18_open_id *id = fh2id(fh);
 298        struct cx18 *cx = id->cx;
 299        int ret;
 300
 301        /*
 302         * Changing the Encoder's Raw VBI parameters won't have any effect
 303         * if any analog capture is ongoing
 304         */
 305        if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
 306                return -EBUSY;
 307
 308        /*
 309         * Set the digitizer registers for raw active VBI.
 310         * Note cx18_av_vbi_wipes out a lot of the passed in fmt under valid
 311         * calling conditions
 312         */
 313        ret = v4l2_subdev_call(cx->sd_av, vbi, s_raw_fmt, &fmt->fmt.vbi);
 314        if (ret)
 315                return ret;
 316
 317        /* Store our new v4l2 (non-)sliced VBI state */
 318        cx->vbi.sliced_in->service_set = 0;
 319        cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE;
 320
 321        return cx18_g_fmt_vbi_cap(file, fh, fmt);
 322}
 323
 324static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
 325                                        struct v4l2_format *fmt)
 326{
 327        struct cx18_open_id *id = fh2id(fh);
 328        struct cx18 *cx = id->cx;
 329        int ret;
 330        struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
 331
 332        cx18_try_fmt_sliced_vbi_cap(file, fh, fmt);
 333
 334        /*
 335         * Changing the Encoder's Raw VBI parameters won't have any effect
 336         * if any analog capture is ongoing
 337         */
 338        if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
 339                return -EBUSY;
 340
 341        /*
 342         * Set the service_lines requested in the digitizer/slicer registers.
 343         * Note, cx18_av_vbi() wipes some "impossible" service lines in the
 344         * passed in fmt->fmt.sliced under valid calling conditions
 345         */
 346        ret = v4l2_subdev_call(cx->sd_av, vbi, s_sliced_fmt, &fmt->fmt.sliced);
 347        if (ret)
 348                return ret;
 349        /* Store our current v4l2 sliced VBI settings */
 350        cx->vbi.in.type =  V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
 351        memcpy(cx->vbi.sliced_in, vbifmt, sizeof(*cx->vbi.sliced_in));
 352        return 0;
 353}
 354
 355#ifdef CONFIG_VIDEO_ADV_DEBUG
 356static int cx18_g_register(struct file *file, void *fh,
 357                                struct v4l2_dbg_register *reg)
 358{
 359        struct cx18 *cx = fh2id(fh)->cx;
 360
 361        if (reg->reg & 0x3)
 362                return -EINVAL;
 363        if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
 364                return -EINVAL;
 365        reg->size = 4;
 366        reg->val = cx18_read_enc(cx, reg->reg);
 367        return 0;
 368}
 369
 370static int cx18_s_register(struct file *file, void *fh,
 371                                const struct v4l2_dbg_register *reg)
 372{
 373        struct cx18 *cx = fh2id(fh)->cx;
 374
 375        if (reg->reg & 0x3)
 376                return -EINVAL;
 377        if (reg->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE)
 378                return -EINVAL;
 379        cx18_write_enc(cx, reg->val, reg->reg);
 380        return 0;
 381}
 382#endif
 383
 384static int cx18_querycap(struct file *file, void *fh,
 385                                struct v4l2_capability *vcap)
 386{
 387        struct cx18_open_id *id = fh2id(fh);
 388        struct cx18 *cx = id->cx;
 389
 390        strscpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
 391        strscpy(vcap->card, cx->card_name, sizeof(vcap->card));
 392        snprintf(vcap->bus_info, sizeof(vcap->bus_info),
 393                 "PCI:%s", pci_name(cx->pci_dev));
 394        vcap->capabilities = cx->v4l2_cap | V4L2_CAP_DEVICE_CAPS;
 395        return 0;
 396}
 397
 398static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
 399{
 400        struct cx18 *cx = fh2id(fh)->cx;
 401
 402        return cx18_get_audio_input(cx, vin->index, vin);
 403}
 404
 405static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
 406{
 407        struct cx18 *cx = fh2id(fh)->cx;
 408
 409        vin->index = cx->audio_input;
 410        return cx18_get_audio_input(cx, vin->index, vin);
 411}
 412
 413static int cx18_s_audio(struct file *file, void *fh, const struct v4l2_audio *vout)
 414{
 415        struct cx18 *cx = fh2id(fh)->cx;
 416
 417        if (vout->index >= cx->nof_audio_inputs)
 418                return -EINVAL;
 419        cx->audio_input = vout->index;
 420        cx18_audio_set_io(cx);
 421        return 0;
 422}
 423
 424static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
 425{
 426        struct cx18 *cx = fh2id(fh)->cx;
 427
 428        /* set it to defaults from our table */
 429        return cx18_get_input(cx, vin->index, vin);
 430}
 431
 432static int cx18_g_pixelaspect(struct file *file, void *fh,
 433                              int type, struct v4l2_fract *f)
 434{
 435        struct cx18 *cx = fh2id(fh)->cx;
 436
 437        if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 438                return -EINVAL;
 439
 440        f->numerator = cx->is_50hz ? 54 : 11;
 441        f->denominator = cx->is_50hz ? 59 : 10;
 442        return 0;
 443}
 444
 445static int cx18_g_selection(struct file *file, void *fh,
 446                            struct v4l2_selection *sel)
 447{
 448        struct cx18 *cx = fh2id(fh)->cx;
 449
 450        if (sel->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
 451                return -EINVAL;
 452        switch (sel->target) {
 453        case V4L2_SEL_TGT_CROP_BOUNDS:
 454        case V4L2_SEL_TGT_CROP_DEFAULT:
 455                sel->r.top = sel->r.left = 0;
 456                sel->r.width = 720;
 457                sel->r.height = cx->is_50hz ? 576 : 480;
 458                break;
 459        default:
 460                return -EINVAL;
 461        }
 462        return 0;
 463}
 464
 465static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
 466                                        struct v4l2_fmtdesc *fmt)
 467{
 468        static const struct v4l2_fmtdesc formats[] = {
 469                { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
 470                  "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 }
 471                },
 472                { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED,
 473                  "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 }
 474                },
 475                { 2, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
 476                  "UYVY 4:2:2", V4L2_PIX_FMT_UYVY, { 0, 0, 0, 0 }
 477                },
 478        };
 479
 480        if (fmt->index > ARRAY_SIZE(formats) - 1)
 481                return -EINVAL;
 482        *fmt = formats[fmt->index];
 483        return 0;
 484}
 485
 486static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
 487{
 488        struct cx18 *cx = fh2id(fh)->cx;
 489
 490        *i = cx->active_input;
 491        return 0;
 492}
 493
 494int cx18_s_input(struct file *file, void *fh, unsigned int inp)
 495{
 496        struct cx18_open_id *id = fh2id(fh);
 497        struct cx18 *cx = id->cx;
 498        v4l2_std_id std = V4L2_STD_ALL;
 499        const struct cx18_card_video_input *card_input =
 500                                cx->card->video_inputs + inp;
 501
 502        if (inp >= cx->nof_inputs)
 503                return -EINVAL;
 504
 505        if (inp == cx->active_input) {
 506                CX18_DEBUG_INFO("Input unchanged\n");
 507                return 0;
 508        }
 509
 510        CX18_DEBUG_INFO("Changing input from %d to %d\n",
 511                        cx->active_input, inp);
 512
 513        cx->active_input = inp;
 514        /* Set the audio input to whatever is appropriate for the input type. */
 515        cx->audio_input = cx->card->video_inputs[inp].audio_index;
 516        if (card_input->video_type == V4L2_INPUT_TYPE_TUNER)
 517                std = cx->tuner_std;
 518        cx->streams[CX18_ENC_STREAM_TYPE_MPG].video_dev.tvnorms = std;
 519        cx->streams[CX18_ENC_STREAM_TYPE_YUV].video_dev.tvnorms = std;
 520        cx->streams[CX18_ENC_STREAM_TYPE_VBI].video_dev.tvnorms = std;
 521
 522        /* prevent others from messing with the streams until
 523           we're finished changing inputs. */
 524        cx18_mute(cx);
 525        cx18_video_set_io(cx);
 526        cx18_audio_set_io(cx);
 527        cx18_unmute(cx);
 528        return 0;
 529}
 530
 531static int cx18_g_frequency(struct file *file, void *fh,
 532                                struct v4l2_frequency *vf)
 533{
 534        struct cx18 *cx = fh2id(fh)->cx;
 535
 536        if (vf->tuner != 0)
 537                return -EINVAL;
 538
 539        cx18_call_all(cx, tuner, g_frequency, vf);
 540        return 0;
 541}
 542
 543int cx18_s_frequency(struct file *file, void *fh, const struct v4l2_frequency *vf)
 544{
 545        struct cx18_open_id *id = fh2id(fh);
 546        struct cx18 *cx = id->cx;
 547
 548        if (vf->tuner != 0)
 549                return -EINVAL;
 550
 551        cx18_mute(cx);
 552        CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
 553        cx18_call_all(cx, tuner, s_frequency, vf);
 554        cx18_unmute(cx);
 555        return 0;
 556}
 557
 558static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
 559{
 560        struct cx18 *cx = fh2id(fh)->cx;
 561
 562        *std = cx->std;
 563        return 0;
 564}
 565
 566int cx18_s_std(struct file *file, void *fh, v4l2_std_id std)
 567{
 568        struct cx18_open_id *id = fh2id(fh);
 569        struct cx18 *cx = id->cx;
 570
 571        if ((std & V4L2_STD_ALL) == 0)
 572                return -EINVAL;
 573
 574        if (std == cx->std)
 575                return 0;
 576
 577        if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ||
 578            atomic_read(&cx->ana_capturing) > 0) {
 579                /* Switching standard would turn off the radio or mess
 580                   with already running streams, prevent that by
 581                   returning EBUSY. */
 582                return -EBUSY;
 583        }
 584
 585        cx->std = std;
 586        cx->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
 587        cx->is_50hz = !cx->is_60hz;
 588        cx2341x_handler_set_50hz(&cx->cxhdl, cx->is_50hz);
 589        cx->cxhdl.width = 720;
 590        cx->cxhdl.height = cx->is_50hz ? 576 : 480;
 591        cx->vbi.count = cx->is_50hz ? 18 : 12;
 592        cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
 593        cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
 594        CX18_DEBUG_INFO("Switching standard to %llx.\n",
 595                        (unsigned long long) cx->std);
 596
 597        /* Tuner */
 598        cx18_call_all(cx, video, s_std, cx->std);
 599        return 0;
 600}
 601
 602static int cx18_s_tuner(struct file *file, void *fh, const struct v4l2_tuner *vt)
 603{
 604        struct cx18_open_id *id = fh2id(fh);
 605        struct cx18 *cx = id->cx;
 606
 607        if (vt->index != 0)
 608                return -EINVAL;
 609
 610        cx18_call_all(cx, tuner, s_tuner, vt);
 611        return 0;
 612}
 613
 614static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
 615{
 616        struct cx18 *cx = fh2id(fh)->cx;
 617
 618        if (vt->index != 0)
 619                return -EINVAL;
 620
 621        cx18_call_all(cx, tuner, g_tuner, vt);
 622
 623        if (vt->type == V4L2_TUNER_RADIO)
 624                strscpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name));
 625        else
 626                strscpy(vt->name, "cx18 TV Tuner", sizeof(vt->name));
 627        return 0;
 628}
 629
 630static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
 631                                        struct v4l2_sliced_vbi_cap *cap)
 632{
 633        struct cx18 *cx = fh2id(fh)->cx;
 634        int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
 635        int f, l;
 636
 637        if (cap->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
 638                return -EINVAL;
 639
 640        cap->service_set = 0;
 641        for (f = 0; f < 2; f++) {
 642                for (l = 0; l < 24; l++) {
 643                        if (valid_service_line(f, l, cx->is_50hz)) {
 644                                /*
 645                                 * We can find all v4l2 supported vbi services
 646                                 * for the standard, on a valid line for the std
 647                                 */
 648                                cap->service_lines[f][l] = set;
 649                                cap->service_set |= set;
 650                        } else
 651                                cap->service_lines[f][l] = 0;
 652                }
 653        }
 654        for (f = 0; f < 3; f++)
 655                cap->reserved[f] = 0;
 656        return 0;
 657}
 658
 659static int _cx18_process_idx_data(struct cx18_buffer *buf,
 660                                  struct v4l2_enc_idx *idx)
 661{
 662        int consumed, remaining;
 663        struct v4l2_enc_idx_entry *e_idx;
 664        struct cx18_enc_idx_entry *e_buf;
 665
 666        /* Frame type lookup: 1=I, 2=P, 4=B */
 667        const int mapping[8] = {
 668                -1, V4L2_ENC_IDX_FRAME_I, V4L2_ENC_IDX_FRAME_P,
 669                -1, V4L2_ENC_IDX_FRAME_B, -1, -1, -1
 670        };
 671
 672        /*
 673         * Assumption here is that a buf holds an integral number of
 674         * struct cx18_enc_idx_entry objects and is properly aligned.
 675         * This is enforced by the module options on IDX buffer sizes.
 676         */
 677        remaining = buf->bytesused - buf->readpos;
 678        consumed = 0;
 679        e_idx = &idx->entry[idx->entries];
 680        e_buf = (struct cx18_enc_idx_entry *) &buf->buf[buf->readpos];
 681
 682        while (remaining >= sizeof(struct cx18_enc_idx_entry) &&
 683               idx->entries < V4L2_ENC_IDX_ENTRIES) {
 684
 685                e_idx->offset = (((u64) le32_to_cpu(e_buf->offset_high)) << 32)
 686                                | le32_to_cpu(e_buf->offset_low);
 687
 688                e_idx->pts = (((u64) (le32_to_cpu(e_buf->pts_high) & 1)) << 32)
 689                             | le32_to_cpu(e_buf->pts_low);
 690
 691                e_idx->length = le32_to_cpu(e_buf->length);
 692
 693                e_idx->flags = mapping[le32_to_cpu(e_buf->flags) & 0x7];
 694
 695                e_idx->reserved[0] = 0;
 696                e_idx->reserved[1] = 0;
 697
 698                idx->entries++;
 699                e_idx = &idx->entry[idx->entries];
 700                e_buf++;
 701
 702                remaining -= sizeof(struct cx18_enc_idx_entry);
 703                consumed += sizeof(struct cx18_enc_idx_entry);
 704        }
 705
 706        /* Swallow any partial entries at the end, if there are any */
 707        if (remaining > 0 && remaining < sizeof(struct cx18_enc_idx_entry))
 708                consumed += remaining;
 709
 710        buf->readpos += consumed;
 711        return consumed;
 712}
 713
 714static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl,
 715                                 struct v4l2_enc_idx *idx)
 716{
 717        if (s->type != CX18_ENC_STREAM_TYPE_IDX)
 718                return -EINVAL;
 719
 720        if (mdl->curr_buf == NULL)
 721                mdl->curr_buf = list_first_entry(&mdl->buf_list,
 722                                                 struct cx18_buffer, list);
 723
 724        if (list_entry_is_past_end(mdl->curr_buf, &mdl->buf_list, list)) {
 725                /*
 726                 * For some reason we've exhausted the buffers, but the MDL
 727                 * object still said some data was unread.
 728                 * Fix that and bail out.
 729                 */
 730                mdl->readpos = mdl->bytesused;
 731                return 0;
 732        }
 733
 734        list_for_each_entry_from(mdl->curr_buf, &mdl->buf_list, list) {
 735
 736                /* Skip any empty buffers in the MDL */
 737                if (mdl->curr_buf->readpos >= mdl->curr_buf->bytesused)
 738                        continue;
 739
 740                mdl->readpos += _cx18_process_idx_data(mdl->curr_buf, idx);
 741
 742                /* exit when MDL drained or request satisfied */
 743                if (idx->entries >= V4L2_ENC_IDX_ENTRIES ||
 744                    mdl->curr_buf->readpos < mdl->curr_buf->bytesused ||
 745                    mdl->readpos >= mdl->bytesused)
 746                        break;
 747        }
 748        return 0;
 749}
 750
 751static int cx18_g_enc_index(struct file *file, void *fh,
 752                                struct v4l2_enc_idx *idx)
 753{
 754        struct cx18 *cx = fh2id(fh)->cx;
 755        struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
 756        s32 tmp;
 757        struct cx18_mdl *mdl;
 758
 759        if (!cx18_stream_enabled(s)) /* Module options inhibited IDX stream */
 760                return -EINVAL;
 761
 762        /* Compute the best case number of entries we can buffer */
 763        tmp = s->buffers -
 764                          s->bufs_per_mdl * CX18_ENC_STREAM_TYPE_IDX_FW_MDL_MIN;
 765        if (tmp <= 0)
 766                tmp = 1;
 767        tmp = tmp * s->buf_size / sizeof(struct cx18_enc_idx_entry);
 768
 769        /* Fill out the header of the return structure */
 770        idx->entries = 0;
 771        idx->entries_cap = tmp;
 772        memset(idx->reserved, 0, sizeof(idx->reserved));
 773
 774        /* Pull IDX MDLs and buffers from q_full and populate the entries */
 775        do {
 776                mdl = cx18_dequeue(s, &s->q_full);
 777                if (mdl == NULL) /* No more IDX data right now */
 778                        break;
 779
 780                /* Extract the Index entry data from the MDL and buffers */
 781                cx18_process_idx_data(s, mdl, idx);
 782                if (mdl->readpos < mdl->bytesused) {
 783                        /* We finished with data remaining, push the MDL back */
 784                        cx18_push(s, mdl, &s->q_full);
 785                        break;
 786                }
 787
 788                /* We drained this MDL, schedule it to go to the firmware */
 789                cx18_enqueue(s, mdl, &s->q_free);
 790
 791        } while (idx->entries < V4L2_ENC_IDX_ENTRIES);
 792
 793        /* Tell the work handler to send free IDX MDLs to the firmware */
 794        cx18_stream_load_fw_queue(s);
 795        return 0;
 796}
 797
 798static struct videobuf_queue *cx18_vb_queue(struct cx18_open_id *id)
 799{
 800        struct videobuf_queue *q = NULL;
 801        struct cx18 *cx = id->cx;
 802        struct cx18_stream *s = &cx->streams[id->type];
 803
 804        switch (s->vb_type) {
 805        case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 806                q = &s->vbuf_q;
 807                break;
 808        case V4L2_BUF_TYPE_VBI_CAPTURE:
 809                break;
 810        default:
 811                break;
 812        }
 813        return q;
 814}
 815
 816static int cx18_streamon(struct file *file, void *priv,
 817        enum v4l2_buf_type type)
 818{
 819        struct cx18_open_id *id = file->private_data;
 820        struct cx18 *cx = id->cx;
 821        struct cx18_stream *s = &cx->streams[id->type];
 822
 823        /* Start the hardware only if we're the video device */
 824        if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 825                (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
 826                return -EINVAL;
 827
 828        if (id->type != CX18_ENC_STREAM_TYPE_YUV)
 829                return -EINVAL;
 830
 831        /* Establish a buffer timeout */
 832        mod_timer(&s->vb_timeout, msecs_to_jiffies(2000) + jiffies);
 833
 834        return videobuf_streamon(cx18_vb_queue(id));
 835}
 836
 837static int cx18_streamoff(struct file *file, void *priv,
 838        enum v4l2_buf_type type)
 839{
 840        struct cx18_open_id *id = file->private_data;
 841        struct cx18 *cx = id->cx;
 842        struct cx18_stream *s = &cx->streams[id->type];
 843
 844        /* Start the hardware only if we're the video device */
 845        if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 846                (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
 847                return -EINVAL;
 848
 849        if (id->type != CX18_ENC_STREAM_TYPE_YUV)
 850                return -EINVAL;
 851
 852        return videobuf_streamoff(cx18_vb_queue(id));
 853}
 854
 855static int cx18_reqbufs(struct file *file, void *priv,
 856        struct v4l2_requestbuffers *rb)
 857{
 858        struct cx18_open_id *id = file->private_data;
 859        struct cx18 *cx = id->cx;
 860        struct cx18_stream *s = &cx->streams[id->type];
 861
 862        if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 863                (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
 864                return -EINVAL;
 865
 866        return videobuf_reqbufs(cx18_vb_queue(id), rb);
 867}
 868
 869static int cx18_querybuf(struct file *file, void *priv,
 870        struct v4l2_buffer *b)
 871{
 872        struct cx18_open_id *id = file->private_data;
 873        struct cx18 *cx = id->cx;
 874        struct cx18_stream *s = &cx->streams[id->type];
 875
 876        if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 877                (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
 878                return -EINVAL;
 879
 880        return videobuf_querybuf(cx18_vb_queue(id), b);
 881}
 882
 883static int cx18_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
 884{
 885        struct cx18_open_id *id = file->private_data;
 886        struct cx18 *cx = id->cx;
 887        struct cx18_stream *s = &cx->streams[id->type];
 888
 889        if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 890                (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
 891                return -EINVAL;
 892
 893        return videobuf_qbuf(cx18_vb_queue(id), b);
 894}
 895
 896static int cx18_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
 897{
 898        struct cx18_open_id *id = file->private_data;
 899        struct cx18 *cx = id->cx;
 900        struct cx18_stream *s = &cx->streams[id->type];
 901
 902        if ((s->vb_type != V4L2_BUF_TYPE_VIDEO_CAPTURE) &&
 903                (s->vb_type != V4L2_BUF_TYPE_VBI_CAPTURE))
 904                return -EINVAL;
 905
 906        return videobuf_dqbuf(cx18_vb_queue(id), b, file->f_flags & O_NONBLOCK);
 907}
 908
 909static int cx18_encoder_cmd(struct file *file, void *fh,
 910                                struct v4l2_encoder_cmd *enc)
 911{
 912        struct cx18_open_id *id = fh2id(fh);
 913        struct cx18 *cx = id->cx;
 914        u32 h;
 915
 916        switch (enc->cmd) {
 917        case V4L2_ENC_CMD_START:
 918                CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
 919                enc->flags = 0;
 920                return cx18_start_capture(id);
 921
 922        case V4L2_ENC_CMD_STOP:
 923                CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
 924                enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
 925                cx18_stop_capture(id,
 926                                  enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
 927                break;
 928
 929        case V4L2_ENC_CMD_PAUSE:
 930                CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
 931                enc->flags = 0;
 932                if (!atomic_read(&cx->ana_capturing))
 933                        return -EPERM;
 934                if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
 935                        return 0;
 936                h = cx18_find_handle(cx);
 937                if (h == CX18_INVALID_TASK_HANDLE) {
 938                        CX18_ERR("Can't find valid task handle for V4L2_ENC_CMD_PAUSE\n");
 939                        return -EBADFD;
 940                }
 941                cx18_mute(cx);
 942                cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h);
 943                break;
 944
 945        case V4L2_ENC_CMD_RESUME:
 946                CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
 947                enc->flags = 0;
 948                if (!atomic_read(&cx->ana_capturing))
 949                        return -EPERM;
 950                if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
 951                        return 0;
 952                h = cx18_find_handle(cx);
 953                if (h == CX18_INVALID_TASK_HANDLE) {
 954                        CX18_ERR("Can't find valid task handle for V4L2_ENC_CMD_RESUME\n");
 955                        return -EBADFD;
 956                }
 957                cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h);
 958                cx18_unmute(cx);
 959                break;
 960
 961        default:
 962                CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
 963                return -EINVAL;
 964        }
 965        return 0;
 966}
 967
 968static int cx18_try_encoder_cmd(struct file *file, void *fh,
 969                                struct v4l2_encoder_cmd *enc)
 970{
 971        struct cx18 *cx = fh2id(fh)->cx;
 972
 973        switch (enc->cmd) {
 974        case V4L2_ENC_CMD_START:
 975                CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
 976                enc->flags = 0;
 977                break;
 978
 979        case V4L2_ENC_CMD_STOP:
 980                CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
 981                enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
 982                break;
 983
 984        case V4L2_ENC_CMD_PAUSE:
 985                CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
 986                enc->flags = 0;
 987                break;
 988
 989        case V4L2_ENC_CMD_RESUME:
 990                CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
 991                enc->flags = 0;
 992                break;
 993
 994        default:
 995                CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
 996                return -EINVAL;
 997        }
 998        return 0;
 999}
1000
1001static int cx18_log_status(struct file *file, void *fh)
1002{
1003        struct cx18 *cx = fh2id(fh)->cx;
1004        struct v4l2_input vidin;
1005        struct v4l2_audio audin;
1006        int i;
1007
1008        CX18_INFO("Version: %s  Card: %s\n", CX18_VERSION, cx->card_name);
1009        if (cx->hw_flags & CX18_HW_TVEEPROM) {
1010                struct tveeprom tv;
1011
1012                cx18_read_eeprom(cx, &tv);
1013        }
1014        cx18_call_all(cx, core, log_status);
1015        cx18_get_input(cx, cx->active_input, &vidin);
1016        cx18_get_audio_input(cx, cx->audio_input, &audin);
1017        CX18_INFO("Video Input: %s\n", vidin.name);
1018        CX18_INFO("Audio Input: %s\n", audin.name);
1019        mutex_lock(&cx->gpio_lock);
1020        CX18_INFO("GPIO:  direction 0x%08x, value 0x%08x\n",
1021                cx->gpio_dir, cx->gpio_val);
1022        mutex_unlock(&cx->gpio_lock);
1023        CX18_INFO("Tuner: %s\n",
1024                test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ?  "Radio" : "TV");
1025        v4l2_ctrl_handler_log_status(&cx->cxhdl.hdl, cx->v4l2_dev.name);
1026        CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
1027        for (i = 0; i < CX18_MAX_STREAMS; i++) {
1028                struct cx18_stream *s = &cx->streams[i];
1029
1030                if (s->video_dev.v4l2_dev == NULL || s->buffers == 0)
1031                        continue;
1032                CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n",
1033                          s->name, s->s_flags,
1034                          atomic_read(&s->q_full.depth) * s->bufs_per_mdl * 100
1035                           / s->buffers,
1036                          (s->buffers * s->buf_size) / 1024, s->buffers);
1037        }
1038        CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n",
1039                        (long long)cx->mpg_data_received,
1040                        (long long)cx->vbi_data_inserted);
1041        return 0;
1042}
1043
1044static long cx18_default(struct file *file, void *fh, bool valid_prio,
1045                         unsigned int cmd, void *arg)
1046{
1047        struct cx18 *cx = fh2id(fh)->cx;
1048
1049        switch (cmd) {
1050        case VIDIOC_INT_RESET: {
1051                u32 val = *(u32 *)arg;
1052
1053                if ((val == 0) || (val & 0x01))
1054                        cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, core, reset,
1055                                     (u32) CX18_GPIO_RESET_Z8F0811);
1056                break;
1057        }
1058
1059        default:
1060                return -ENOTTY;
1061        }
1062        return 0;
1063}
1064
1065static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
1066        .vidioc_querycap                = cx18_querycap,
1067        .vidioc_s_audio                 = cx18_s_audio,
1068        .vidioc_g_audio                 = cx18_g_audio,
1069        .vidioc_enumaudio               = cx18_enumaudio,
1070        .vidioc_enum_input              = cx18_enum_input,
1071        .vidioc_g_pixelaspect           = cx18_g_pixelaspect,
1072        .vidioc_g_selection             = cx18_g_selection,
1073        .vidioc_g_input                 = cx18_g_input,
1074        .vidioc_s_input                 = cx18_s_input,
1075        .vidioc_g_frequency             = cx18_g_frequency,
1076        .vidioc_s_frequency             = cx18_s_frequency,
1077        .vidioc_s_tuner                 = cx18_s_tuner,
1078        .vidioc_g_tuner                 = cx18_g_tuner,
1079        .vidioc_g_enc_index             = cx18_g_enc_index,
1080        .vidioc_g_std                   = cx18_g_std,
1081        .vidioc_s_std                   = cx18_s_std,
1082        .vidioc_log_status              = cx18_log_status,
1083        .vidioc_enum_fmt_vid_cap        = cx18_enum_fmt_vid_cap,
1084        .vidioc_encoder_cmd             = cx18_encoder_cmd,
1085        .vidioc_try_encoder_cmd         = cx18_try_encoder_cmd,
1086        .vidioc_g_fmt_vid_cap           = cx18_g_fmt_vid_cap,
1087        .vidioc_g_fmt_vbi_cap           = cx18_g_fmt_vbi_cap,
1088        .vidioc_g_fmt_sliced_vbi_cap    = cx18_g_fmt_sliced_vbi_cap,
1089        .vidioc_s_fmt_vid_cap           = cx18_s_fmt_vid_cap,
1090        .vidioc_s_fmt_vbi_cap           = cx18_s_fmt_vbi_cap,
1091        .vidioc_s_fmt_sliced_vbi_cap    = cx18_s_fmt_sliced_vbi_cap,
1092        .vidioc_try_fmt_vid_cap         = cx18_try_fmt_vid_cap,
1093        .vidioc_try_fmt_vbi_cap         = cx18_try_fmt_vbi_cap,
1094        .vidioc_try_fmt_sliced_vbi_cap  = cx18_try_fmt_sliced_vbi_cap,
1095        .vidioc_g_sliced_vbi_cap        = cx18_g_sliced_vbi_cap,
1096#ifdef CONFIG_VIDEO_ADV_DEBUG
1097        .vidioc_g_register              = cx18_g_register,
1098        .vidioc_s_register              = cx18_s_register,
1099#endif
1100        .vidioc_default                 = cx18_default,
1101        .vidioc_streamon                = cx18_streamon,
1102        .vidioc_streamoff               = cx18_streamoff,
1103        .vidioc_reqbufs                 = cx18_reqbufs,
1104        .vidioc_querybuf                = cx18_querybuf,
1105        .vidioc_qbuf                    = cx18_qbuf,
1106        .vidioc_dqbuf                   = cx18_dqbuf,
1107        .vidioc_subscribe_event         = v4l2_ctrl_subscribe_event,
1108        .vidioc_unsubscribe_event       = v4l2_event_unsubscribe,
1109};
1110
1111void cx18_set_funcs(struct video_device *vdev)
1112{
1113        vdev->ioctl_ops = &cx18_ioctl_ops;
1114}
1115