linux/drivers/media/usb/pvrusb2/pvrusb2-cx2584x-v4l.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *
   4 *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
   5 *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
   6 */
   7
   8/*
   9
  10   This source file is specifically designed to interface with the
  11   cx2584x, in kernels 2.6.16 or newer.
  12
  13*/
  14
  15#include "pvrusb2-cx2584x-v4l.h"
  16
  17
  18#include "pvrusb2-hdw-internal.h"
  19#include "pvrusb2-debug.h"
  20#include <media/drv-intf/cx25840.h>
  21#include <linux/videodev2.h>
  22#include <media/v4l2-common.h>
  23#include <linux/errno.h>
  24
  25
  26struct routing_scheme_item {
  27        int vid;
  28        int aud;
  29};
  30
  31struct routing_scheme {
  32        const struct routing_scheme_item *def;
  33        unsigned int cnt;
  34};
  35
  36static const struct routing_scheme_item routing_scheme0[] = {
  37        [PVR2_CVAL_INPUT_TV] = {
  38                .vid = CX25840_COMPOSITE7,
  39                .aud = CX25840_AUDIO8,
  40        },
  41        [PVR2_CVAL_INPUT_RADIO] = { /* Treat the same as composite */
  42                .vid = CX25840_COMPOSITE3,
  43                .aud = CX25840_AUDIO_SERIAL,
  44        },
  45        [PVR2_CVAL_INPUT_COMPOSITE] = {
  46                .vid = CX25840_COMPOSITE3,
  47                .aud = CX25840_AUDIO_SERIAL,
  48        },
  49        [PVR2_CVAL_INPUT_SVIDEO] = {
  50                .vid = CX25840_SVIDEO1,
  51                .aud = CX25840_AUDIO_SERIAL,
  52        },
  53};
  54
  55static const struct routing_scheme routing_def0 = {
  56        .def = routing_scheme0,
  57        .cnt = ARRAY_SIZE(routing_scheme0),
  58};
  59
  60/* Specific to gotview device */
  61static const struct routing_scheme_item routing_schemegv[] = {
  62        [PVR2_CVAL_INPUT_TV] = {
  63                .vid = CX25840_COMPOSITE2,
  64                .aud = CX25840_AUDIO5,
  65        },
  66        [PVR2_CVAL_INPUT_RADIO] = {
  67                /* line-in is used for radio and composite.  A GPIO is
  68                   used to switch between the two choices. */
  69                .vid = CX25840_COMPOSITE1,
  70                .aud = CX25840_AUDIO_SERIAL,
  71        },
  72        [PVR2_CVAL_INPUT_COMPOSITE] = {
  73                .vid = CX25840_COMPOSITE1,
  74                .aud = CX25840_AUDIO_SERIAL,
  75        },
  76        [PVR2_CVAL_INPUT_SVIDEO] = {
  77                .vid = (CX25840_SVIDEO_LUMA3|CX25840_SVIDEO_CHROMA4),
  78                .aud = CX25840_AUDIO_SERIAL,
  79        },
  80};
  81
  82static const struct routing_scheme routing_defgv = {
  83        .def = routing_schemegv,
  84        .cnt = ARRAY_SIZE(routing_schemegv),
  85};
  86
  87/* Specific to grabster av400 device */
  88static const struct routing_scheme_item routing_schemeav400[] = {
  89        [PVR2_CVAL_INPUT_COMPOSITE] = {
  90                .vid = CX25840_COMPOSITE1,
  91                .aud = CX25840_AUDIO_SERIAL,
  92        },
  93        [PVR2_CVAL_INPUT_SVIDEO] = {
  94                .vid = (CX25840_SVIDEO_LUMA2|CX25840_SVIDEO_CHROMA4),
  95                .aud = CX25840_AUDIO_SERIAL,
  96        },
  97};
  98
  99static const struct routing_scheme routing_defav400 = {
 100        .def = routing_schemeav400,
 101        .cnt = ARRAY_SIZE(routing_schemeav400),
 102};
 103
 104static const struct routing_scheme_item routing_scheme160xxx[] = {
 105        [PVR2_CVAL_INPUT_TV] = {
 106                .vid = CX25840_COMPOSITE7,
 107                .aud = CX25840_AUDIO8,
 108        },
 109        [PVR2_CVAL_INPUT_RADIO] = {
 110                .vid = CX25840_COMPOSITE4,
 111                .aud = CX25840_AUDIO6,
 112        },
 113        [PVR2_CVAL_INPUT_COMPOSITE] = {
 114                .vid = CX25840_COMPOSITE3,
 115                .aud = CX25840_AUDIO_SERIAL,
 116        },
 117        [PVR2_CVAL_INPUT_SVIDEO] = {
 118                .vid = CX25840_SVIDEO1,
 119                .aud = CX25840_AUDIO_SERIAL,
 120        },
 121};
 122
 123static const struct routing_scheme routing_def160xxx = {
 124        .def = routing_scheme160xxx,
 125        .cnt = ARRAY_SIZE(routing_scheme160xxx),
 126};
 127
 128static const struct routing_scheme *routing_schemes[] = {
 129        [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
 130        [PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
 131        [PVR2_ROUTING_SCHEME_AV400] = &routing_defav400,
 132        [PVR2_ROUTING_SCHEME_HAUP160XXX] = &routing_def160xxx,
 133};
 134
 135void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
 136{
 137        pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update...");
 138        if (hdw->input_dirty || hdw->force_dirty) {
 139                enum cx25840_video_input vid_input;
 140                enum cx25840_audio_input aud_input;
 141                const struct routing_scheme *sp;
 142                unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
 143
 144                sp = (sid < ARRAY_SIZE(routing_schemes)) ?
 145                        routing_schemes[sid] : NULL;
 146                if ((sp == NULL) ||
 147                    (hdw->input_val < 0) ||
 148                    (hdw->input_val >= sp->cnt)) {
 149                        pvr2_trace(PVR2_TRACE_ERROR_LEGS,
 150                                   "*** WARNING *** subdev cx2584x set_input: Invalid routing scheme (%u) and/or input (%d)",
 151                                   sid, hdw->input_val);
 152                        return;
 153                }
 154                vid_input = sp->def[hdw->input_val].vid;
 155                aud_input = sp->def[hdw->input_val].aud;
 156                pvr2_trace(PVR2_TRACE_CHIPS,
 157                           "subdev cx2584x set_input vid=0x%x aud=0x%x",
 158                           vid_input, aud_input);
 159                sd->ops->video->s_routing(sd, (u32)vid_input, 0, 0);
 160                sd->ops->audio->s_routing(sd, (u32)aud_input, 0, 0);
 161        }
 162}
 163