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 26 struct routing_scheme_item { 27 int vid; 28 int aud; 29 }; 30 31 struct routing_scheme { 32 const struct routing_scheme_item *def; 33 unsigned int cnt; 34 }; 35 36 static 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 55 static const struct routing_scheme routing_def0 = { 56 .def = routing_scheme0, 57 .cnt = ARRAY_SIZE(routing_scheme0), 58 }; 59 60 /* Specific to gotview device */ 61 static 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 82 static const struct routing_scheme routing_defgv = { 83 .def = routing_schemegv, 84 .cnt = ARRAY_SIZE(routing_schemegv), 85 }; 86 87 /* Specific to grabster av400 device */ 88 static 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 99 static const struct routing_scheme routing_defav400 = { 100 .def = routing_schemeav400, 101 .cnt = ARRAY_SIZE(routing_schemeav400), 102 }; 103 104 static 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 123 static const struct routing_scheme routing_def160xxx = { 124 .def = routing_scheme160xxx, 125 .cnt = ARRAY_SIZE(routing_scheme160xxx), 126 }; 127 128 static 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 135 void 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