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