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 *routing_schemes[] = { 105 [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0, 106 [PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv, 107 [PVR2_ROUTING_SCHEME_AV400] = &routing_defav400, 108 }; 109 110 void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) 111 { 112 pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update..."); 113 if (hdw->input_dirty || hdw->force_dirty) { 114 enum cx25840_video_input vid_input; 115 enum cx25840_audio_input aud_input; 116 const struct routing_scheme *sp; 117 unsigned int sid = hdw->hdw_desc->signal_routing_scheme; 118 119 sp = (sid < ARRAY_SIZE(routing_schemes)) ? 120 routing_schemes[sid] : NULL; 121 if ((sp == NULL) || 122 (hdw->input_val < 0) || 123 (hdw->input_val >= sp->cnt)) { 124 pvr2_trace(PVR2_TRACE_ERROR_LEGS, 125 "*** WARNING *** subdev cx2584x set_input: Invalid routing scheme (%u) and/or input (%d)", 126 sid, hdw->input_val); 127 return; 128 } 129 vid_input = sp->def[hdw->input_val].vid; 130 aud_input = sp->def[hdw->input_val].aud; 131 pvr2_trace(PVR2_TRACE_CHIPS, 132 "subdev cx2584x set_input vid=0x%x aud=0x%x", 133 vid_input, aud_input); 134 sd->ops->video->s_routing(sd, (u32)vid_input, 0, 0); 135 sd->ops->audio->s_routing(sd, (u32)aud_input, 0, 0); 136 } 137 } 138