linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
<<
>>
Prefs
   1/*
   2 *
   3 *
   4 *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
   5 *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
   6 *
   7 *  This program is free software; you can redistribute it and/or modify
   8 *  it under the terms of the GNU General Public License as published by
   9 *  the Free Software Foundation; either version 2 of the License
  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19 *
  20 */
  21
  22#include <linux/kernel.h>
  23#include <linux/slab.h>
  24#include <linux/version.h>
  25#include "pvrusb2-context.h"
  26#include "pvrusb2-hdw.h"
  27#include "pvrusb2.h"
  28#include "pvrusb2-debug.h"
  29#include "pvrusb2-v4l2.h"
  30#include "pvrusb2-ioread.h"
  31#include <linux/videodev2.h>
  32#include <media/v4l2-dev.h>
  33#include <media/v4l2-common.h>
  34#include <media/v4l2-ioctl.h>
  35
  36struct pvr2_v4l2_dev;
  37struct pvr2_v4l2_fh;
  38struct pvr2_v4l2;
  39
  40struct pvr2_v4l2_dev {
  41        struct video_device devbase; /* MUST be first! */
  42        struct pvr2_v4l2 *v4lp;
  43        struct pvr2_context_stream *stream;
  44        /* Information about this device: */
  45        enum pvr2_config config; /* Expected stream format */
  46        int v4l_type; /* V4L defined type for this device node */
  47        enum pvr2_v4l_type minor_type; /* pvr2-understood minor device type */
  48};
  49
  50struct pvr2_v4l2_fh {
  51        struct pvr2_channel channel;
  52        struct pvr2_v4l2_dev *pdi;
  53        enum v4l2_priority prio;
  54        struct pvr2_ioread *rhp;
  55        struct file *file;
  56        struct pvr2_v4l2 *vhead;
  57        struct pvr2_v4l2_fh *vnext;
  58        struct pvr2_v4l2_fh *vprev;
  59        wait_queue_head_t wait_data;
  60        int fw_mode_flag;
  61        /* Map contiguous ordinal value to input id */
  62        unsigned char *input_map;
  63        unsigned int input_cnt;
  64};
  65
  66struct pvr2_v4l2 {
  67        struct pvr2_channel channel;
  68        struct pvr2_v4l2_fh *vfirst;
  69        struct pvr2_v4l2_fh *vlast;
  70
  71        struct v4l2_prio_state prio;
  72
  73        /* streams - Note that these must be separately, individually,
  74         * allocated pointers.  This is because the v4l core is going to
  75         * manage their deletion - separately, individually...  */
  76        struct pvr2_v4l2_dev *dev_video;
  77        struct pvr2_v4l2_dev *dev_radio;
  78};
  79
  80static int video_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
  81module_param_array(video_nr, int, NULL, 0444);
  82MODULE_PARM_DESC(video_nr, "Offset for device's video dev minor");
  83static int radio_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
  84module_param_array(radio_nr, int, NULL, 0444);
  85MODULE_PARM_DESC(radio_nr, "Offset for device's radio dev minor");
  86static int vbi_nr[PVR_NUM] = {[0 ... PVR_NUM-1] = -1};
  87module_param_array(vbi_nr, int, NULL, 0444);
  88MODULE_PARM_DESC(vbi_nr, "Offset for device's vbi dev minor");
  89
  90static struct v4l2_capability pvr_capability ={
  91        .driver         = "pvrusb2",
  92        .card           = "Hauppauge WinTV pvr-usb2",
  93        .bus_info       = "usb",
  94        .version        = KERNEL_VERSION(0, 9, 0),
  95        .capabilities   = (V4L2_CAP_VIDEO_CAPTURE |
  96                           V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
  97                           V4L2_CAP_READWRITE),
  98        .reserved       = {0,0,0,0}
  99};
 100
 101static struct v4l2_fmtdesc pvr_fmtdesc [] = {
 102        {
 103                .index          = 0,
 104                .type           = V4L2_BUF_TYPE_VIDEO_CAPTURE,
 105                .flags          = V4L2_FMT_FLAG_COMPRESSED,
 106                .description    = "MPEG1/2",
 107                // This should really be V4L2_PIX_FMT_MPEG, but xawtv
 108                // breaks when I do that.
 109                .pixelformat    = 0, // V4L2_PIX_FMT_MPEG,
 110                .reserved       = { 0, 0, 0, 0 }
 111        }
 112};
 113
 114#define PVR_FORMAT_PIX  0
 115#define PVR_FORMAT_VBI  1
 116
 117static struct v4l2_format pvr_format [] = {
 118        [PVR_FORMAT_PIX] = {
 119                .type   = V4L2_BUF_TYPE_VIDEO_CAPTURE,
 120                .fmt    = {
 121                        .pix        = {
 122                                .width          = 720,
 123                                .height             = 576,
 124                                // This should really be V4L2_PIX_FMT_MPEG,
 125                                // but xawtv breaks when I do that.
 126                                .pixelformat    = 0, // V4L2_PIX_FMT_MPEG,
 127                                .field          = V4L2_FIELD_INTERLACED,
 128                                .bytesperline   = 0,  // doesn't make sense
 129                                                      // here
 130                                //FIXME : Don't know what to put here...
 131                                .sizeimage          = (32*1024),
 132                                .colorspace     = 0, // doesn't make sense here
 133                                .priv           = 0
 134                        }
 135                }
 136        },
 137        [PVR_FORMAT_VBI] = {
 138                .type   = V4L2_BUF_TYPE_VBI_CAPTURE,
 139                .fmt    = {
 140                        .vbi        = {
 141                                .sampling_rate = 27000000,
 142                                .offset = 248,
 143                                .samples_per_line = 1443,
 144                                .sample_format = V4L2_PIX_FMT_GREY,
 145                                .start = { 0, 0 },
 146                                .count = { 0, 0 },
 147                                .flags = 0,
 148                                .reserved = { 0, 0 }
 149                        }
 150                }
 151        }
 152};
 153
 154
 155/*
 156 * pvr_ioctl()
 157 *
 158 * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
 159 *
 160 */
 161static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
 162{
 163        struct pvr2_v4l2_fh *fh = file->private_data;
 164        struct pvr2_v4l2 *vp = fh->vhead;
 165        struct pvr2_v4l2_dev *pdi = fh->pdi;
 166        struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
 167        long ret = -EINVAL;
 168
 169        if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
 170                v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),cmd);
 171        }
 172
 173        if (!pvr2_hdw_dev_ok(hdw)) {
 174                pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 175                           "ioctl failed - bad or no context");
 176                return -EFAULT;
 177        }
 178
 179        /* check priority */
 180        switch (cmd) {
 181        case VIDIOC_S_CTRL:
 182        case VIDIOC_S_STD:
 183        case VIDIOC_S_INPUT:
 184        case VIDIOC_S_TUNER:
 185        case VIDIOC_S_FREQUENCY:
 186                ret = v4l2_prio_check(&vp->prio, fh->prio);
 187                if (ret)
 188                        return ret;
 189        }
 190
 191        switch (cmd) {
 192        case VIDIOC_QUERYCAP:
 193        {
 194                struct v4l2_capability *cap = arg;
 195
 196                memcpy(cap, &pvr_capability, sizeof(struct v4l2_capability));
 197                strlcpy(cap->bus_info,pvr2_hdw_get_bus_info(hdw),
 198                        sizeof(cap->bus_info));
 199                strlcpy(cap->card,pvr2_hdw_get_desc(hdw),sizeof(cap->card));
 200
 201                ret = 0;
 202                break;
 203        }
 204
 205        case VIDIOC_G_PRIORITY:
 206        {
 207                enum v4l2_priority *p = arg;
 208
 209                *p = v4l2_prio_max(&vp->prio);
 210                ret = 0;
 211                break;
 212        }
 213
 214        case VIDIOC_S_PRIORITY:
 215        {
 216                enum v4l2_priority *prio = arg;
 217
 218                ret = v4l2_prio_change(&vp->prio, &fh->prio, *prio);
 219                break;
 220        }
 221
 222        case VIDIOC_ENUMSTD:
 223        {
 224                struct v4l2_standard *vs = (struct v4l2_standard *)arg;
 225                int idx = vs->index;
 226                ret = pvr2_hdw_get_stdenum_value(hdw,vs,idx+1);
 227                break;
 228        }
 229
 230        case VIDIOC_G_STD:
 231        {
 232                int val = 0;
 233                ret = pvr2_ctrl_get_value(
 234                        pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),&val);
 235                *(v4l2_std_id *)arg = val;
 236                break;
 237        }
 238
 239        case VIDIOC_S_STD:
 240        {
 241                ret = pvr2_ctrl_set_value(
 242                        pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_STDCUR),
 243                        *(v4l2_std_id *)arg);
 244                break;
 245        }
 246
 247        case VIDIOC_ENUMINPUT:
 248        {
 249                struct pvr2_ctrl *cptr;
 250                struct v4l2_input *vi = (struct v4l2_input *)arg;
 251                struct v4l2_input tmp;
 252                unsigned int cnt;
 253                int val;
 254
 255                cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
 256
 257                memset(&tmp,0,sizeof(tmp));
 258                tmp.index = vi->index;
 259                ret = 0;
 260                if (vi->index >= fh->input_cnt) {
 261                        ret = -EINVAL;
 262                        break;
 263                }
 264                val = fh->input_map[vi->index];
 265                switch (val) {
 266                case PVR2_CVAL_INPUT_TV:
 267                case PVR2_CVAL_INPUT_DTV:
 268                case PVR2_CVAL_INPUT_RADIO:
 269                        tmp.type = V4L2_INPUT_TYPE_TUNER;
 270                        break;
 271                case PVR2_CVAL_INPUT_SVIDEO:
 272                case PVR2_CVAL_INPUT_COMPOSITE:
 273                        tmp.type = V4L2_INPUT_TYPE_CAMERA;
 274                        break;
 275                default:
 276                        ret = -EINVAL;
 277                        break;
 278                }
 279                if (ret < 0) break;
 280
 281                cnt = 0;
 282                pvr2_ctrl_get_valname(cptr,val,
 283                                      tmp.name,sizeof(tmp.name)-1,&cnt);
 284                tmp.name[cnt] = 0;
 285
 286                /* Don't bother with audioset, since this driver currently
 287                   always switches the audio whenever the video is
 288                   switched. */
 289
 290                /* Handling std is a tougher problem.  It doesn't make
 291                   sense in cases where a device might be multi-standard.
 292                   We could just copy out the current value for the
 293                   standard, but it can change over time.  For now just
 294                   leave it zero. */
 295
 296                memcpy(vi, &tmp, sizeof(tmp));
 297
 298                ret = 0;
 299                break;
 300        }
 301
 302        case VIDIOC_G_INPUT:
 303        {
 304                unsigned int idx;
 305                struct pvr2_ctrl *cptr;
 306                struct v4l2_input *vi = (struct v4l2_input *)arg;
 307                int val;
 308                cptr = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
 309                val = 0;
 310                ret = pvr2_ctrl_get_value(cptr,&val);
 311                vi->index = 0;
 312                for (idx = 0; idx < fh->input_cnt; idx++) {
 313                        if (fh->input_map[idx] == val) {
 314                                vi->index = idx;
 315                                break;
 316                        }
 317                }
 318                break;
 319        }
 320
 321        case VIDIOC_S_INPUT:
 322        {
 323                struct v4l2_input *vi = (struct v4l2_input *)arg;
 324                if (vi->index >= fh->input_cnt) {
 325                        ret = -ERANGE;
 326                        break;
 327                }
 328                ret = pvr2_ctrl_set_value(
 329                        pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT),
 330                        fh->input_map[vi->index]);
 331                break;
 332        }
 333
 334        case VIDIOC_ENUMAUDIO:
 335        {
 336                /* pkt: FIXME: We are returning one "fake" input here
 337                   which could very well be called "whatever_we_like".
 338                   This is for apps that want to see an audio input
 339                   just to feel comfortable, as well as to test if
 340                   it can do stereo or sth. There is actually no guarantee
 341                   that the actual audio input cannot change behind the app's
 342                   back, but most applications should not mind that either.
 343
 344                   Hopefully, mplayer people will work with us on this (this
 345                   whole mess is to support mplayer pvr://), or Hans will come
 346                   up with a more standard way to say "we have inputs but we
 347                   don 't want you to change them independent of video" which
 348                   will sort this mess.
 349                 */
 350                struct v4l2_audio *vin = arg;
 351                ret = -EINVAL;
 352                if (vin->index > 0) break;
 353                strncpy(vin->name, "PVRUSB2 Audio",14);
 354                vin->capability = V4L2_AUDCAP_STEREO;
 355                ret = 0;
 356                break;
 357                break;
 358        }
 359
 360        case VIDIOC_G_AUDIO:
 361        {
 362                /* pkt: FIXME: see above comment (VIDIOC_ENUMAUDIO) */
 363                struct v4l2_audio *vin = arg;
 364                memset(vin,0,sizeof(*vin));
 365                vin->index = 0;
 366                strncpy(vin->name, "PVRUSB2 Audio",14);
 367                vin->capability = V4L2_AUDCAP_STEREO;
 368                ret = 0;
 369                break;
 370        }
 371
 372        case VIDIOC_S_AUDIO:
 373        {
 374                ret = -EINVAL;
 375                break;
 376        }
 377        case VIDIOC_G_TUNER:
 378        {
 379                struct v4l2_tuner *vt = (struct v4l2_tuner *)arg;
 380
 381                if (vt->index != 0) break; /* Only answer for the 1st tuner */
 382
 383                pvr2_hdw_execute_tuner_poll(hdw);
 384                ret = pvr2_hdw_get_tuner_status(hdw,vt);
 385                break;
 386        }
 387
 388        case VIDIOC_S_TUNER:
 389        {
 390                struct v4l2_tuner *vt=(struct v4l2_tuner *)arg;
 391
 392                if (vt->index != 0)
 393                        break;
 394
 395                ret = pvr2_ctrl_set_value(
 396                        pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_AUDIOMODE),
 397                        vt->audmode);
 398                break;
 399        }
 400
 401        case VIDIOC_S_FREQUENCY:
 402        {
 403                const struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
 404                unsigned long fv;
 405                struct v4l2_tuner vt;
 406                int cur_input;
 407                struct pvr2_ctrl *ctrlp;
 408                ret = pvr2_hdw_get_tuner_status(hdw,&vt);
 409                if (ret != 0) break;
 410                ctrlp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT);
 411                ret = pvr2_ctrl_get_value(ctrlp,&cur_input);
 412                if (ret != 0) break;
 413                if (vf->type == V4L2_TUNER_RADIO) {
 414                        if (cur_input != PVR2_CVAL_INPUT_RADIO) {
 415                                pvr2_ctrl_set_value(ctrlp,
 416                                                    PVR2_CVAL_INPUT_RADIO);
 417                        }
 418                } else {
 419                        if (cur_input == PVR2_CVAL_INPUT_RADIO) {
 420                                pvr2_ctrl_set_value(ctrlp,
 421                                                    PVR2_CVAL_INPUT_TV);
 422                        }
 423                }
 424                fv = vf->frequency;
 425                if (vt.capability & V4L2_TUNER_CAP_LOW) {
 426                        fv = (fv * 125) / 2;
 427                } else {
 428                        fv = fv * 62500;
 429                }
 430                ret = pvr2_ctrl_set_value(
 431                        pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),fv);
 432                break;
 433        }
 434
 435        case VIDIOC_G_FREQUENCY:
 436        {
 437                struct v4l2_frequency *vf = (struct v4l2_frequency *)arg;
 438                int val = 0;
 439                int cur_input;
 440                struct v4l2_tuner vt;
 441                ret = pvr2_hdw_get_tuner_status(hdw,&vt);
 442                if (ret != 0) break;
 443                ret = pvr2_ctrl_get_value(
 444                        pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_FREQUENCY),
 445                        &val);
 446                if (ret != 0) break;
 447                pvr2_ctrl_get_value(
 448                        pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_INPUT),
 449                        &cur_input);
 450                if (cur_input == PVR2_CVAL_INPUT_RADIO) {
 451                        vf->type = V4L2_TUNER_RADIO;
 452                } else {
 453                        vf->type = V4L2_TUNER_ANALOG_TV;
 454                }
 455                if (vt.capability & V4L2_TUNER_CAP_LOW) {
 456                        val = (val * 2) / 125;
 457                } else {
 458                        val /= 62500;
 459                }
 460                vf->frequency = val;
 461                break;
 462        }
 463
 464        case VIDIOC_ENUM_FMT:
 465        {
 466                struct v4l2_fmtdesc *fd = (struct v4l2_fmtdesc *)arg;
 467
 468                /* Only one format is supported : mpeg.*/
 469                if (fd->index != 0)
 470                        break;
 471
 472                memcpy(fd, pvr_fmtdesc, sizeof(struct v4l2_fmtdesc));
 473                ret = 0;
 474                break;
 475        }
 476
 477        case VIDIOC_G_FMT:
 478        {
 479                struct v4l2_format *vf = (struct v4l2_format *)arg;
 480                int val;
 481                switch(vf->type) {
 482                case V4L2_BUF_TYPE_VIDEO_CAPTURE:
 483                        memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
 484                               sizeof(struct v4l2_format));
 485                        val = 0;
 486                        pvr2_ctrl_get_value(
 487                                pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES),
 488                                &val);
 489                        vf->fmt.pix.width = val;
 490                        val = 0;
 491                        pvr2_ctrl_get_value(
 492                                pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES),
 493                                &val);
 494                        vf->fmt.pix.height = val;
 495                        ret = 0;
 496                        break;
 497                case V4L2_BUF_TYPE_VBI_CAPTURE:
 498                        // ????? Still need to figure out to do VBI correctly
 499                        ret = -EINVAL;
 500                        break;
 501                default:
 502                        ret = -EINVAL;
 503                        break;
 504                }
 505                break;
 506        }
 507
 508        case VIDIOC_TRY_FMT:
 509        case VIDIOC_S_FMT:
 510        {
 511                struct v4l2_format *vf = (struct v4l2_format *)arg;
 512
 513                ret = 0;
 514                switch(vf->type) {
 515                case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
 516                        int lmin,lmax,ldef;
 517                        struct pvr2_ctrl *hcp,*vcp;
 518                        int h = vf->fmt.pix.height;
 519                        int w = vf->fmt.pix.width;
 520                        hcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES);
 521                        vcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES);
 522
 523                        lmin = pvr2_ctrl_get_min(hcp);
 524                        lmax = pvr2_ctrl_get_max(hcp);
 525                        pvr2_ctrl_get_def(hcp, &ldef);
 526                        if (w == -1) {
 527                                w = ldef;
 528                        } else if (w < lmin) {
 529                                w = lmin;
 530                        } else if (w > lmax) {
 531                                w = lmax;
 532                        }
 533                        lmin = pvr2_ctrl_get_min(vcp);
 534                        lmax = pvr2_ctrl_get_max(vcp);
 535                        pvr2_ctrl_get_def(vcp, &ldef);
 536                        if (h == -1) {
 537                                h = ldef;
 538                        } else if (h < lmin) {
 539                                h = lmin;
 540                        } else if (h > lmax) {
 541                                h = lmax;
 542                        }
 543
 544                        memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
 545                               sizeof(struct v4l2_format));
 546                        vf->fmt.pix.width = w;
 547                        vf->fmt.pix.height = h;
 548
 549                        if (cmd == VIDIOC_S_FMT) {
 550                                pvr2_ctrl_set_value(hcp,vf->fmt.pix.width);
 551                                pvr2_ctrl_set_value(vcp,vf->fmt.pix.height);
 552                        }
 553                } break;
 554                case V4L2_BUF_TYPE_VBI_CAPTURE:
 555                        // ????? Still need to figure out to do VBI correctly
 556                        ret = -EINVAL;
 557                        break;
 558                default:
 559                        ret = -EINVAL;
 560                        break;
 561                }
 562                break;
 563        }
 564
 565        case VIDIOC_STREAMON:
 566        {
 567                if (!fh->pdi->stream) {
 568                        /* No stream defined for this node.  This means
 569                           that we're not currently allowed to stream from
 570                           this node. */
 571                        ret = -EPERM;
 572                        break;
 573                }
 574                ret = pvr2_hdw_set_stream_type(hdw,pdi->config);
 575                if (ret < 0) return ret;
 576                ret = pvr2_hdw_set_streaming(hdw,!0);
 577                break;
 578        }
 579
 580        case VIDIOC_STREAMOFF:
 581        {
 582                if (!fh->pdi->stream) {
 583                        /* No stream defined for this node.  This means
 584                           that we're not currently allowed to stream from
 585                           this node. */
 586                        ret = -EPERM;
 587                        break;
 588                }
 589                ret = pvr2_hdw_set_streaming(hdw,0);
 590                break;
 591        }
 592
 593        case VIDIOC_QUERYCTRL:
 594        {
 595                struct pvr2_ctrl *cptr;
 596                int val;
 597                struct v4l2_queryctrl *vc = (struct v4l2_queryctrl *)arg;
 598                ret = 0;
 599                if (vc->id & V4L2_CTRL_FLAG_NEXT_CTRL) {
 600                        cptr = pvr2_hdw_get_ctrl_nextv4l(
 601                                hdw,(vc->id & ~V4L2_CTRL_FLAG_NEXT_CTRL));
 602                        if (cptr) vc->id = pvr2_ctrl_get_v4lid(cptr);
 603                } else {
 604                        cptr = pvr2_hdw_get_ctrl_v4l(hdw,vc->id);
 605                }
 606                if (!cptr) {
 607                        pvr2_trace(PVR2_TRACE_V4LIOCTL,
 608                                   "QUERYCTRL id=0x%x not implemented here",
 609                                   vc->id);
 610                        ret = -EINVAL;
 611                        break;
 612                }
 613
 614                pvr2_trace(PVR2_TRACE_V4LIOCTL,
 615                           "QUERYCTRL id=0x%x mapping name=%s (%s)",
 616                           vc->id,pvr2_ctrl_get_name(cptr),
 617                           pvr2_ctrl_get_desc(cptr));
 618                strlcpy(vc->name,pvr2_ctrl_get_desc(cptr),sizeof(vc->name));
 619                vc->flags = pvr2_ctrl_get_v4lflags(cptr);
 620                pvr2_ctrl_get_def(cptr, &val);
 621                vc->default_value = val;
 622                switch (pvr2_ctrl_get_type(cptr)) {
 623                case pvr2_ctl_enum:
 624                        vc->type = V4L2_CTRL_TYPE_MENU;
 625                        vc->minimum = 0;
 626                        vc->maximum = pvr2_ctrl_get_cnt(cptr) - 1;
 627                        vc->step = 1;
 628                        break;
 629                case pvr2_ctl_bool:
 630                        vc->type = V4L2_CTRL_TYPE_BOOLEAN;
 631                        vc->minimum = 0;
 632                        vc->maximum = 1;
 633                        vc->step = 1;
 634                        break;
 635                case pvr2_ctl_int:
 636                        vc->type = V4L2_CTRL_TYPE_INTEGER;
 637                        vc->minimum = pvr2_ctrl_get_min(cptr);
 638                        vc->maximum = pvr2_ctrl_get_max(cptr);
 639                        vc->step = 1;
 640                        break;
 641                default:
 642                        pvr2_trace(PVR2_TRACE_V4LIOCTL,
 643                                   "QUERYCTRL id=0x%x name=%s not mappable",
 644                                   vc->id,pvr2_ctrl_get_name(cptr));
 645                        ret = -EINVAL;
 646                        break;
 647                }
 648                break;
 649        }
 650
 651        case VIDIOC_QUERYMENU:
 652        {
 653                struct v4l2_querymenu *vm = (struct v4l2_querymenu *)arg;
 654                unsigned int cnt = 0;
 655                ret = pvr2_ctrl_get_valname(pvr2_hdw_get_ctrl_v4l(hdw,vm->id),
 656                                            vm->index,
 657                                            vm->name,sizeof(vm->name)-1,
 658                                            &cnt);
 659                vm->name[cnt] = 0;
 660                break;
 661        }
 662
 663        case VIDIOC_G_CTRL:
 664        {
 665                struct v4l2_control *vc = (struct v4l2_control *)arg;
 666                int val = 0;
 667                ret = pvr2_ctrl_get_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id),
 668                                          &val);
 669                vc->value = val;
 670                break;
 671        }
 672
 673        case VIDIOC_S_CTRL:
 674        {
 675                struct v4l2_control *vc = (struct v4l2_control *)arg;
 676                ret = pvr2_ctrl_set_value(pvr2_hdw_get_ctrl_v4l(hdw,vc->id),
 677                                          vc->value);
 678                break;
 679        }
 680
 681        case VIDIOC_G_EXT_CTRLS:
 682        {
 683                struct v4l2_ext_controls *ctls =
 684                        (struct v4l2_ext_controls *)arg;
 685                struct v4l2_ext_control *ctrl;
 686                unsigned int idx;
 687                int val;
 688                ret = 0;
 689                for (idx = 0; idx < ctls->count; idx++) {
 690                        ctrl = ctls->controls + idx;
 691                        ret = pvr2_ctrl_get_value(
 692                                pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id),&val);
 693                        if (ret) {
 694                                ctls->error_idx = idx;
 695                                break;
 696                        }
 697                        /* Ensure that if read as a 64 bit value, the user
 698                           will still get a hopefully sane value */
 699                        ctrl->value64 = 0;
 700                        ctrl->value = val;
 701                }
 702                break;
 703        }
 704
 705        case VIDIOC_S_EXT_CTRLS:
 706        {
 707                struct v4l2_ext_controls *ctls =
 708                        (struct v4l2_ext_controls *)arg;
 709                struct v4l2_ext_control *ctrl;
 710                unsigned int idx;
 711                ret = 0;
 712                for (idx = 0; idx < ctls->count; idx++) {
 713                        ctrl = ctls->controls + idx;
 714                        ret = pvr2_ctrl_set_value(
 715                                pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id),
 716                                ctrl->value);
 717                        if (ret) {
 718                                ctls->error_idx = idx;
 719                                break;
 720                        }
 721                }
 722                break;
 723        }
 724
 725        case VIDIOC_TRY_EXT_CTRLS:
 726        {
 727                struct v4l2_ext_controls *ctls =
 728                        (struct v4l2_ext_controls *)arg;
 729                struct v4l2_ext_control *ctrl;
 730                struct pvr2_ctrl *pctl;
 731                unsigned int idx;
 732                /* For the moment just validate that the requested control
 733                   actually exists. */
 734                ret = 0;
 735                for (idx = 0; idx < ctls->count; idx++) {
 736                        ctrl = ctls->controls + idx;
 737                        pctl = pvr2_hdw_get_ctrl_v4l(hdw,ctrl->id);
 738                        if (!pctl) {
 739                                ret = -EINVAL;
 740                                ctls->error_idx = idx;
 741                                break;
 742                        }
 743                }
 744                break;
 745        }
 746
 747        case VIDIOC_CROPCAP:
 748        {
 749                struct v4l2_cropcap *cap = (struct v4l2_cropcap *)arg;
 750                if (cap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
 751                        ret = -EINVAL;
 752                        break;
 753                }
 754                ret = pvr2_hdw_get_cropcap(hdw, cap);
 755                cap->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* paranoia */
 756                break;
 757        }
 758        case VIDIOC_G_CROP:
 759        {
 760                struct v4l2_crop *crop = (struct v4l2_crop *)arg;
 761                int val = 0;
 762                if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
 763                        ret = -EINVAL;
 764                        break;
 765                }
 766                ret = pvr2_ctrl_get_value(
 767                        pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), &val);
 768                if (ret != 0) {
 769                        ret = -EINVAL;
 770                        break;
 771                }
 772                crop->c.left = val;
 773                ret = pvr2_ctrl_get_value(
 774                        pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT), &val);
 775                if (ret != 0) {
 776                        ret = -EINVAL;
 777                        break;
 778                }
 779                crop->c.top = val;
 780                ret = pvr2_ctrl_get_value(
 781                        pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW), &val);
 782                if (ret != 0) {
 783                        ret = -EINVAL;
 784                        break;
 785                }
 786                crop->c.width = val;
 787                ret = pvr2_ctrl_get_value(
 788                        pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH), &val);
 789                if (ret != 0) {
 790                        ret = -EINVAL;
 791                        break;
 792                }
 793                crop->c.height = val;
 794        }
 795        case VIDIOC_S_CROP:
 796        {
 797                struct v4l2_crop *crop = (struct v4l2_crop *)arg;
 798                struct v4l2_cropcap cap;
 799                if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
 800                        ret = -EINVAL;
 801                        break;
 802                }
 803                cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
 804                ret = pvr2_ctrl_set_value(
 805                        pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL),
 806                        crop->c.left);
 807                if (ret != 0) {
 808                        ret = -EINVAL;
 809                        break;
 810                }
 811                ret = pvr2_ctrl_set_value(
 812                        pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPT),
 813                        crop->c.top);
 814                if (ret != 0) {
 815                        ret = -EINVAL;
 816                        break;
 817                }
 818                ret = pvr2_ctrl_set_value(
 819                        pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPW),
 820                        crop->c.width);
 821                if (ret != 0) {
 822                        ret = -EINVAL;
 823                        break;
 824                }
 825                ret = pvr2_ctrl_set_value(
 826                        pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPH),
 827                        crop->c.height);
 828                if (ret != 0) {
 829                        ret = -EINVAL;
 830                        break;
 831                }
 832        }
 833        case VIDIOC_LOG_STATUS:
 834        {
 835                pvr2_hdw_trigger_module_log(hdw);
 836                ret = 0;
 837                break;
 838        }
 839#ifdef CONFIG_VIDEO_ADV_DEBUG
 840        case VIDIOC_DBG_S_REGISTER:
 841        case VIDIOC_DBG_G_REGISTER:
 842        {
 843                u64 val;
 844                struct v4l2_dbg_register *req = (struct v4l2_dbg_register *)arg;
 845                if (cmd == VIDIOC_DBG_S_REGISTER) val = req->val;
 846                ret = pvr2_hdw_register_access(
 847                        hdw, &req->match, req->reg,
 848                        cmd == VIDIOC_DBG_S_REGISTER, &val);
 849                if (cmd == VIDIOC_DBG_G_REGISTER) req->val = val;
 850                break;
 851        }
 852#endif
 853
 854        default :
 855                ret = -EINVAL;
 856                break;
 857        }
 858
 859        pvr2_hdw_commit_ctl(hdw);
 860
 861        if (ret < 0) {
 862                if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
 863                        pvr2_trace(PVR2_TRACE_V4LIOCTL,
 864                                   "pvr2_v4l2_do_ioctl failure, ret=%ld", ret);
 865                } else {
 866                        if (pvrusb2_debug & PVR2_TRACE_V4LIOCTL) {
 867                                pvr2_trace(PVR2_TRACE_V4LIOCTL,
 868                                           "pvr2_v4l2_do_ioctl failure, ret=%ld"
 869                                           " command was:", ret);
 870                                v4l_print_ioctl(pvr2_hdw_get_driver_name(hdw),
 871                                                cmd);
 872                        }
 873                }
 874        } else {
 875                pvr2_trace(PVR2_TRACE_V4LIOCTL,
 876                           "pvr2_v4l2_do_ioctl complete, ret=%ld (0x%lx)",
 877                           ret, ret);
 878        }
 879        return ret;
 880}
 881
 882static void pvr2_v4l2_dev_destroy(struct pvr2_v4l2_dev *dip)
 883{
 884        struct pvr2_hdw *hdw = dip->v4lp->channel.mc_head->hdw;
 885        enum pvr2_config cfg = dip->config;
 886        char msg[80];
 887        unsigned int mcnt;
 888
 889        /* Construct the unregistration message *before* we actually
 890           perform the unregistration step.  By doing it this way we don't
 891           have to worry about potentially touching deleted resources. */
 892        mcnt = scnprintf(msg, sizeof(msg) - 1,
 893                         "pvrusb2: unregistered device %s [%s]",
 894                         video_device_node_name(&dip->devbase),
 895                         pvr2_config_get_name(cfg));
 896        msg[mcnt] = 0;
 897
 898        pvr2_hdw_v4l_store_minor_number(hdw,dip->minor_type,-1);
 899
 900        /* Paranoia */
 901        dip->v4lp = NULL;
 902        dip->stream = NULL;
 903
 904        /* Actual deallocation happens later when all internal references
 905           are gone. */
 906        video_unregister_device(&dip->devbase);
 907
 908        printk(KERN_INFO "%s\n", msg);
 909
 910}
 911
 912
 913static void pvr2_v4l2_dev_disassociate_parent(struct pvr2_v4l2_dev *dip)
 914{
 915        if (!dip) return;
 916        if (!dip->devbase.parent) return;
 917        dip->devbase.parent = NULL;
 918        device_move(&dip->devbase.dev, NULL, DPM_ORDER_NONE);
 919}
 920
 921
 922static void pvr2_v4l2_destroy_no_lock(struct pvr2_v4l2 *vp)
 923{
 924        if (vp->dev_video) {
 925                pvr2_v4l2_dev_destroy(vp->dev_video);
 926                vp->dev_video = NULL;
 927        }
 928        if (vp->dev_radio) {
 929                pvr2_v4l2_dev_destroy(vp->dev_radio);
 930                vp->dev_radio = NULL;
 931        }
 932
 933        pvr2_trace(PVR2_TRACE_STRUCT,"Destroying pvr2_v4l2 id=%p",vp);
 934        pvr2_channel_done(&vp->channel);
 935        kfree(vp);
 936}
 937
 938
 939static void pvr2_video_device_release(struct video_device *vdev)
 940{
 941        struct pvr2_v4l2_dev *dev;
 942        dev = container_of(vdev,struct pvr2_v4l2_dev,devbase);
 943        kfree(dev);
 944}
 945
 946
 947static void pvr2_v4l2_internal_check(struct pvr2_channel *chp)
 948{
 949        struct pvr2_v4l2 *vp;
 950        vp = container_of(chp,struct pvr2_v4l2,channel);
 951        if (!vp->channel.mc_head->disconnect_flag) return;
 952        pvr2_v4l2_dev_disassociate_parent(vp->dev_video);
 953        pvr2_v4l2_dev_disassociate_parent(vp->dev_radio);
 954        if (vp->vfirst) return;
 955        pvr2_v4l2_destroy_no_lock(vp);
 956}
 957
 958
 959static long pvr2_v4l2_ioctl(struct file *file,
 960                           unsigned int cmd, unsigned long arg)
 961{
 962
 963        return video_usercopy(file, cmd, arg, pvr2_v4l2_do_ioctl);
 964}
 965
 966
 967static int pvr2_v4l2_release(struct file *file)
 968{
 969        struct pvr2_v4l2_fh *fhp = file->private_data;
 970        struct pvr2_v4l2 *vp = fhp->vhead;
 971        struct pvr2_hdw *hdw = fhp->channel.mc_head->hdw;
 972
 973        pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_release");
 974
 975        if (fhp->rhp) {
 976                struct pvr2_stream *sp;
 977                pvr2_hdw_set_streaming(hdw,0);
 978                sp = pvr2_ioread_get_stream(fhp->rhp);
 979                if (sp) pvr2_stream_set_callback(sp,NULL,NULL);
 980                pvr2_ioread_destroy(fhp->rhp);
 981                fhp->rhp = NULL;
 982        }
 983
 984        v4l2_prio_close(&vp->prio, fhp->prio);
 985        file->private_data = NULL;
 986
 987        if (fhp->vnext) {
 988                fhp->vnext->vprev = fhp->vprev;
 989        } else {
 990                vp->vlast = fhp->vprev;
 991        }
 992        if (fhp->vprev) {
 993                fhp->vprev->vnext = fhp->vnext;
 994        } else {
 995                vp->vfirst = fhp->vnext;
 996        }
 997        fhp->vnext = NULL;
 998        fhp->vprev = NULL;
 999        fhp->vhead = NULL;
1000        pvr2_channel_done(&fhp->channel);
1001        pvr2_trace(PVR2_TRACE_STRUCT,
1002                   "Destroying pvr_v4l2_fh id=%p",fhp);
1003        if (fhp->input_map) {
1004                kfree(fhp->input_map);
1005                fhp->input_map = NULL;
1006        }
1007        kfree(fhp);
1008        if (vp->channel.mc_head->disconnect_flag && !vp->vfirst) {
1009                pvr2_v4l2_destroy_no_lock(vp);
1010        }
1011        return 0;
1012}
1013
1014
1015static int pvr2_v4l2_open(struct file *file)
1016{
1017        struct pvr2_v4l2_dev *dip; /* Our own context pointer */
1018        struct pvr2_v4l2_fh *fhp;
1019        struct pvr2_v4l2 *vp;
1020        struct pvr2_hdw *hdw;
1021        unsigned int input_mask = 0;
1022        unsigned int input_cnt,idx;
1023        int ret = 0;
1024
1025        dip = container_of(video_devdata(file),struct pvr2_v4l2_dev,devbase);
1026
1027        vp = dip->v4lp;
1028        hdw = vp->channel.hdw;
1029
1030        pvr2_trace(PVR2_TRACE_OPEN_CLOSE,"pvr2_v4l2_open");
1031
1032        if (!pvr2_hdw_dev_ok(hdw)) {
1033                pvr2_trace(PVR2_TRACE_OPEN_CLOSE,
1034                           "pvr2_v4l2_open: hardware not ready");
1035                return -EIO;
1036        }
1037
1038        fhp = kzalloc(sizeof(*fhp),GFP_KERNEL);
1039        if (!fhp) {
1040                return -ENOMEM;
1041        }
1042
1043        init_waitqueue_head(&fhp->wait_data);
1044        fhp->pdi = dip;
1045
1046        pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr_v4l2_fh id=%p",fhp);
1047        pvr2_channel_init(&fhp->channel,vp->channel.mc_head);
1048
1049        if (dip->v4l_type == VFL_TYPE_RADIO) {
1050                /* Opening device as a radio, legal input selection subset
1051                   is just the radio. */
1052                input_mask = (1 << PVR2_CVAL_INPUT_RADIO);
1053        } else {
1054                /* Opening the main V4L device, legal input selection
1055                   subset includes all analog inputs. */
1056                input_mask = ((1 << PVR2_CVAL_INPUT_RADIO) |
1057                              (1 << PVR2_CVAL_INPUT_TV) |
1058                              (1 << PVR2_CVAL_INPUT_COMPOSITE) |
1059                              (1 << PVR2_CVAL_INPUT_SVIDEO));
1060        }
1061        ret = pvr2_channel_limit_inputs(&fhp->channel,input_mask);
1062        if (ret) {
1063                pvr2_channel_done(&fhp->channel);
1064                pvr2_trace(PVR2_TRACE_STRUCT,
1065                           "Destroying pvr_v4l2_fh id=%p (input mask error)",
1066                           fhp);
1067
1068                kfree(fhp);
1069                return ret;
1070        }
1071
1072        input_mask &= pvr2_hdw_get_input_available(hdw);
1073        input_cnt = 0;
1074        for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
1075                if (input_mask & (1 << idx)) input_cnt++;
1076        }
1077        fhp->input_cnt = input_cnt;
1078        fhp->input_map = kzalloc(input_cnt,GFP_KERNEL);
1079        if (!fhp->input_map) {
1080                pvr2_channel_done(&fhp->channel);
1081                pvr2_trace(PVR2_TRACE_STRUCT,
1082                           "Destroying pvr_v4l2_fh id=%p (input map failure)",
1083                           fhp);
1084                kfree(fhp);
1085                return -ENOMEM;
1086        }
1087        input_cnt = 0;
1088        for (idx = 0; idx < (sizeof(input_mask) << 3); idx++) {
1089                if (!(input_mask & (1 << idx))) continue;
1090                fhp->input_map[input_cnt++] = idx;
1091        }
1092
1093        fhp->vnext = NULL;
1094        fhp->vprev = vp->vlast;
1095        if (vp->vlast) {
1096                vp->vlast->vnext = fhp;
1097        } else {
1098                vp->vfirst = fhp;
1099        }
1100        vp->vlast = fhp;
1101        fhp->vhead = vp;
1102
1103        fhp->file = file;
1104        file->private_data = fhp;
1105        v4l2_prio_open(&vp->prio, &fhp->prio);
1106
1107        fhp->fw_mode_flag = pvr2_hdw_cpufw_get_enabled(hdw);
1108
1109        return 0;
1110}
1111
1112
1113static void pvr2_v4l2_notify(struct pvr2_v4l2_fh *fhp)
1114{
1115        wake_up(&fhp->wait_data);
1116}
1117
1118static int pvr2_v4l2_iosetup(struct pvr2_v4l2_fh *fh)
1119{
1120        int ret;
1121        struct pvr2_stream *sp;
1122        struct pvr2_hdw *hdw;
1123        if (fh->rhp) return 0;
1124
1125        if (!fh->pdi->stream) {
1126                /* No stream defined for this node.  This means that we're
1127                   not currently allowed to stream from this node. */
1128                return -EPERM;
1129        }
1130
1131        /* First read() attempt.  Try to claim the stream and start
1132           it... */
1133        if ((ret = pvr2_channel_claim_stream(&fh->channel,
1134                                             fh->pdi->stream)) != 0) {
1135                /* Someone else must already have it */
1136                return ret;
1137        }
1138
1139        fh->rhp = pvr2_channel_create_mpeg_stream(fh->pdi->stream);
1140        if (!fh->rhp) {
1141                pvr2_channel_claim_stream(&fh->channel,NULL);
1142                return -ENOMEM;
1143        }
1144
1145        hdw = fh->channel.mc_head->hdw;
1146        sp = fh->pdi->stream->stream;
1147        pvr2_stream_set_callback(sp,(pvr2_stream_callback)pvr2_v4l2_notify,fh);
1148        pvr2_hdw_set_stream_type(hdw,fh->pdi->config);
1149        if ((ret = pvr2_hdw_set_streaming(hdw,!0)) < 0) return ret;
1150        return pvr2_ioread_set_enabled(fh->rhp,!0);
1151}
1152
1153
1154static ssize_t pvr2_v4l2_read(struct file *file,
1155                              char __user *buff, size_t count, loff_t *ppos)
1156{
1157        struct pvr2_v4l2_fh *fh = file->private_data;
1158        int ret;
1159
1160        if (fh->fw_mode_flag) {
1161                struct pvr2_hdw *hdw = fh->channel.mc_head->hdw;
1162                char *tbuf;
1163                int c1,c2;
1164                int tcnt = 0;
1165                unsigned int offs = *ppos;
1166
1167                tbuf = kmalloc(PAGE_SIZE,GFP_KERNEL);
1168                if (!tbuf) return -ENOMEM;
1169
1170                while (count) {
1171                        c1 = count;
1172                        if (c1 > PAGE_SIZE) c1 = PAGE_SIZE;
1173                        c2 = pvr2_hdw_cpufw_get(hdw,offs,tbuf,c1);
1174                        if (c2 < 0) {
1175                                tcnt = c2;
1176                                break;
1177                        }
1178                        if (!c2) break;
1179                        if (copy_to_user(buff,tbuf,c2)) {
1180                                tcnt = -EFAULT;
1181                                break;
1182                        }
1183                        offs += c2;
1184                        tcnt += c2;
1185                        buff += c2;
1186                        count -= c2;
1187                        *ppos += c2;
1188                }
1189                kfree(tbuf);
1190                return tcnt;
1191        }
1192
1193        if (!fh->rhp) {
1194                ret = pvr2_v4l2_iosetup(fh);
1195                if (ret) {
1196                        return ret;
1197                }
1198        }
1199
1200        for (;;) {
1201                ret = pvr2_ioread_read(fh->rhp,buff,count);
1202                if (ret >= 0) break;
1203                if (ret != -EAGAIN) break;
1204                if (file->f_flags & O_NONBLOCK) break;
1205                /* Doing blocking I/O.  Wait here. */
1206                ret = wait_event_interruptible(
1207                        fh->wait_data,
1208                        pvr2_ioread_avail(fh->rhp) >= 0);
1209                if (ret < 0) break;
1210        }
1211
1212        return ret;
1213}
1214
1215
1216static unsigned int pvr2_v4l2_poll(struct file *file, poll_table *wait)
1217{
1218        unsigned int mask = 0;
1219        struct pvr2_v4l2_fh *fh = file->private_data;
1220        int ret;
1221
1222        if (fh->fw_mode_flag) {
1223                mask |= POLLIN | POLLRDNORM;
1224                return mask;
1225        }
1226
1227        if (!fh->rhp) {
1228                ret = pvr2_v4l2_iosetup(fh);
1229                if (ret) return POLLERR;
1230        }
1231
1232        poll_wait(file,&fh->wait_data,wait);
1233
1234        if (pvr2_ioread_avail(fh->rhp) >= 0) {
1235                mask |= POLLIN | POLLRDNORM;
1236        }
1237
1238        return mask;
1239}
1240
1241
1242static const struct v4l2_file_operations vdev_fops = {
1243        .owner      = THIS_MODULE,
1244        .open       = pvr2_v4l2_open,
1245        .release    = pvr2_v4l2_release,
1246        .read       = pvr2_v4l2_read,
1247        .ioctl      = pvr2_v4l2_ioctl,
1248        .poll       = pvr2_v4l2_poll,
1249};
1250
1251
1252static struct video_device vdev_template = {
1253        .fops       = &vdev_fops,
1254};
1255
1256
1257static void pvr2_v4l2_dev_init(struct pvr2_v4l2_dev *dip,
1258                               struct pvr2_v4l2 *vp,
1259                               int v4l_type)
1260{
1261        struct usb_device *usbdev;
1262        int mindevnum;
1263        int unit_number;
1264        int *nr_ptr = NULL;
1265        dip->v4lp = vp;
1266
1267        usbdev = pvr2_hdw_get_dev(vp->channel.mc_head->hdw);
1268        dip->v4l_type = v4l_type;
1269        switch (v4l_type) {
1270        case VFL_TYPE_GRABBER:
1271                dip->stream = &vp->channel.mc_head->video_stream;
1272                dip->config = pvr2_config_mpeg;
1273                dip->minor_type = pvr2_v4l_type_video;
1274                nr_ptr = video_nr;
1275                if (!dip->stream) {
1276                        pr_err(KBUILD_MODNAME
1277                                ": Failed to set up pvrusb2 v4l video dev"
1278                                " due to missing stream instance\n");
1279                        return;
1280                }
1281                break;
1282        case VFL_TYPE_VBI:
1283                dip->config = pvr2_config_vbi;
1284                dip->minor_type = pvr2_v4l_type_vbi;
1285                nr_ptr = vbi_nr;
1286                break;
1287        case VFL_TYPE_RADIO:
1288                dip->stream = &vp->channel.mc_head->video_stream;
1289                dip->config = pvr2_config_mpeg;
1290                dip->minor_type = pvr2_v4l_type_radio;
1291                nr_ptr = radio_nr;
1292                break;
1293        default:
1294                /* Bail out (this should be impossible) */
1295                pr_err(KBUILD_MODNAME ": Failed to set up pvrusb2 v4l dev"
1296                    " due to unrecognized config\n");
1297                return;
1298        }
1299
1300        memcpy(&dip->devbase,&vdev_template,sizeof(vdev_template));
1301        dip->devbase.release = pvr2_video_device_release;
1302
1303        mindevnum = -1;
1304        unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw);
1305        if (nr_ptr && (unit_number >= 0) && (unit_number < PVR_NUM)) {
1306                mindevnum = nr_ptr[unit_number];
1307        }
1308        dip->devbase.parent = &usbdev->dev;
1309        if ((video_register_device(&dip->devbase,
1310                                   dip->v4l_type, mindevnum) < 0) &&
1311            (video_register_device(&dip->devbase,
1312                                   dip->v4l_type, -1) < 0)) {
1313                pr_err(KBUILD_MODNAME
1314                        ": Failed to register pvrusb2 v4l device\n");
1315        }
1316
1317        printk(KERN_INFO "pvrusb2: registered device %s [%s]\n",
1318               video_device_node_name(&dip->devbase),
1319               pvr2_config_get_name(dip->config));
1320
1321        pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
1322                                        dip->minor_type,dip->devbase.minor);
1323}
1324
1325
1326struct pvr2_v4l2 *pvr2_v4l2_create(struct pvr2_context *mnp)
1327{
1328        struct pvr2_v4l2 *vp;
1329
1330        vp = kzalloc(sizeof(*vp),GFP_KERNEL);
1331        if (!vp) return vp;
1332        pvr2_channel_init(&vp->channel,mnp);
1333        pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
1334
1335        vp->channel.check_func = pvr2_v4l2_internal_check;
1336
1337        /* register streams */
1338        vp->dev_video = kzalloc(sizeof(*vp->dev_video),GFP_KERNEL);
1339        if (!vp->dev_video) goto fail;
1340        pvr2_v4l2_dev_init(vp->dev_video,vp,VFL_TYPE_GRABBER);
1341        if (pvr2_hdw_get_input_available(vp->channel.mc_head->hdw) &
1342            (1 << PVR2_CVAL_INPUT_RADIO)) {
1343                vp->dev_radio = kzalloc(sizeof(*vp->dev_radio),GFP_KERNEL);
1344                if (!vp->dev_radio) goto fail;
1345                pvr2_v4l2_dev_init(vp->dev_radio,vp,VFL_TYPE_RADIO);
1346        }
1347
1348        return vp;
1349 fail:
1350        pvr2_trace(PVR2_TRACE_STRUCT,"Failure creating pvr2_v4l2 id=%p",vp);
1351        pvr2_v4l2_destroy_no_lock(vp);
1352        return NULL;
1353}
1354
1355/*
1356  Stuff for Emacs to see, in order to encourage consistent editing style:
1357  *** Local Variables: ***
1358  *** mode: c ***
1359  *** fill-column: 75 ***
1360  *** tab-width: 8 ***
1361  *** c-basic-offset: 8 ***
1362  *** End: ***
1363  */
1364