1*2504ba9fSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
20c0d06caSMauro Carvalho Chehab /*
30c0d06caSMauro Carvalho Chehab *
40c0d06caSMauro Carvalho Chehab * Copyright (C) 2005 Mike Isely <isely@pobox.com>
50c0d06caSMauro Carvalho Chehab * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
60c0d06caSMauro Carvalho Chehab */
70c0d06caSMauro Carvalho Chehab
80c0d06caSMauro Carvalho Chehab /*
90c0d06caSMauro Carvalho Chehab
100c0d06caSMauro Carvalho Chehab This source file is specifically designed to interface with the
110c0d06caSMauro Carvalho Chehab saa711x support that is available in the v4l available starting
120c0d06caSMauro Carvalho Chehab with linux 2.6.15.
130c0d06caSMauro Carvalho Chehab
140c0d06caSMauro Carvalho Chehab */
150c0d06caSMauro Carvalho Chehab
160c0d06caSMauro Carvalho Chehab #include "pvrusb2-video-v4l.h"
170c0d06caSMauro Carvalho Chehab
180c0d06caSMauro Carvalho Chehab
190c0d06caSMauro Carvalho Chehab
200c0d06caSMauro Carvalho Chehab #include "pvrusb2-hdw-internal.h"
210c0d06caSMauro Carvalho Chehab #include "pvrusb2-debug.h"
220c0d06caSMauro Carvalho Chehab #include <linux/videodev2.h>
230c0d06caSMauro Carvalho Chehab #include <media/v4l2-common.h>
24b5dcee22SMauro Carvalho Chehab #include <media/i2c/saa7115.h>
250c0d06caSMauro Carvalho Chehab #include <linux/errno.h>
260c0d06caSMauro Carvalho Chehab
270c0d06caSMauro Carvalho Chehab struct routing_scheme {
280c0d06caSMauro Carvalho Chehab const int *def;
290c0d06caSMauro Carvalho Chehab unsigned int cnt;
300c0d06caSMauro Carvalho Chehab };
310c0d06caSMauro Carvalho Chehab
320c0d06caSMauro Carvalho Chehab
330c0d06caSMauro Carvalho Chehab static const int routing_scheme0[] = {
340c0d06caSMauro Carvalho Chehab [PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4,
350c0d06caSMauro Carvalho Chehab /* In radio mode, we mute the video, but point at one
360c0d06caSMauro Carvalho Chehab spot just to stay consistent */
370c0d06caSMauro Carvalho Chehab [PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5,
380c0d06caSMauro Carvalho Chehab [PVR2_CVAL_INPUT_COMPOSITE] = SAA7115_COMPOSITE5,
390c0d06caSMauro Carvalho Chehab [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2,
400c0d06caSMauro Carvalho Chehab };
410c0d06caSMauro Carvalho Chehab
420c0d06caSMauro Carvalho Chehab static const struct routing_scheme routing_def0 = {
430c0d06caSMauro Carvalho Chehab .def = routing_scheme0,
440c0d06caSMauro Carvalho Chehab .cnt = ARRAY_SIZE(routing_scheme0),
450c0d06caSMauro Carvalho Chehab };
460c0d06caSMauro Carvalho Chehab
470c0d06caSMauro Carvalho Chehab static const int routing_scheme1[] = {
480c0d06caSMauro Carvalho Chehab [PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4,
490c0d06caSMauro Carvalho Chehab [PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5,
500c0d06caSMauro Carvalho Chehab [PVR2_CVAL_INPUT_COMPOSITE] = SAA7115_COMPOSITE3,
510c0d06caSMauro Carvalho Chehab [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2, /* or SVIDEO0, it seems */
520c0d06caSMauro Carvalho Chehab };
530c0d06caSMauro Carvalho Chehab
540c0d06caSMauro Carvalho Chehab static const struct routing_scheme routing_def1 = {
550c0d06caSMauro Carvalho Chehab .def = routing_scheme1,
560c0d06caSMauro Carvalho Chehab .cnt = ARRAY_SIZE(routing_scheme1),
570c0d06caSMauro Carvalho Chehab };
580c0d06caSMauro Carvalho Chehab
590c0d06caSMauro Carvalho Chehab static const struct routing_scheme *routing_schemes[] = {
600c0d06caSMauro Carvalho Chehab [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
610c0d06caSMauro Carvalho Chehab [PVR2_ROUTING_SCHEME_ONAIR] = &routing_def1,
620c0d06caSMauro Carvalho Chehab };
630c0d06caSMauro Carvalho Chehab
pvr2_saa7115_subdev_update(struct pvr2_hdw * hdw,struct v4l2_subdev * sd)640c0d06caSMauro Carvalho Chehab void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
650c0d06caSMauro Carvalho Chehab {
660c0d06caSMauro Carvalho Chehab if (hdw->input_dirty || hdw->force_dirty) {
670c0d06caSMauro Carvalho Chehab const struct routing_scheme *sp;
680c0d06caSMauro Carvalho Chehab unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
690c0d06caSMauro Carvalho Chehab u32 input;
700c0d06caSMauro Carvalho Chehab
710c0d06caSMauro Carvalho Chehab pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
720c0d06caSMauro Carvalho Chehab hdw->input_val);
730c0d06caSMauro Carvalho Chehab
740c0d06caSMauro Carvalho Chehab sp = (sid < ARRAY_SIZE(routing_schemes)) ?
750c0d06caSMauro Carvalho Chehab routing_schemes[sid] : NULL;
760c0d06caSMauro Carvalho Chehab if ((sp == NULL) ||
770c0d06caSMauro Carvalho Chehab (hdw->input_val < 0) ||
780c0d06caSMauro Carvalho Chehab (hdw->input_val >= sp->cnt)) {
790c0d06caSMauro Carvalho Chehab pvr2_trace(PVR2_TRACE_ERROR_LEGS,
8096292c89SMauro Carvalho Chehab "*** WARNING *** subdev v4l2 set_input: Invalid routing scheme (%u) and/or input (%d)",
810c0d06caSMauro Carvalho Chehab sid, hdw->input_val);
820c0d06caSMauro Carvalho Chehab return;
830c0d06caSMauro Carvalho Chehab }
840c0d06caSMauro Carvalho Chehab input = sp->def[hdw->input_val];
850c0d06caSMauro Carvalho Chehab sd->ops->video->s_routing(sd, input, 0, 0);
860c0d06caSMauro Carvalho Chehab }
870c0d06caSMauro Carvalho Chehab }
88