^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2005 Mike Isely <isely@pobox.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) This source file is specifically designed to interface with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) saa711x support that is available in the v4l available starting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) with linux 2.6.15.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "pvrusb2-video-v4l.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "pvrusb2-hdw-internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "pvrusb2-debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/videodev2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <media/v4l2-common.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <media/i2c/saa7115.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct routing_scheme {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) const int *def;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) unsigned int cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) static const int routing_scheme0[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) [PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* In radio mode, we mute the video, but point at one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) spot just to stay consistent */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) [PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) [PVR2_CVAL_INPUT_COMPOSITE] = SAA7115_COMPOSITE5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static const struct routing_scheme routing_def0 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) .def = routing_scheme0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) .cnt = ARRAY_SIZE(routing_scheme0),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static const int routing_scheme1[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) [PVR2_CVAL_INPUT_TV] = SAA7115_COMPOSITE4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) [PVR2_CVAL_INPUT_RADIO] = SAA7115_COMPOSITE5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) [PVR2_CVAL_INPUT_COMPOSITE] = SAA7115_COMPOSITE3,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) [PVR2_CVAL_INPUT_SVIDEO] = SAA7115_SVIDEO2, /* or SVIDEO0, it seems */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static const struct routing_scheme routing_def1 = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) .def = routing_scheme1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) .cnt = ARRAY_SIZE(routing_scheme1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static const struct routing_scheme *routing_schemes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) [PVR2_ROUTING_SCHEME_ONAIR] = &routing_def1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) void pvr2_saa7115_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) if (hdw->input_dirty || hdw->force_dirty) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) const struct routing_scheme *sp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) u32 input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) pvr2_trace(PVR2_TRACE_CHIPS, "subdev v4l2 set_input(%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) hdw->input_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) sp = (sid < ARRAY_SIZE(routing_schemes)) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) routing_schemes[sid] : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if ((sp == NULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) (hdw->input_val < 0) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) (hdw->input_val >= sp->cnt)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) pvr2_trace(PVR2_TRACE_ERROR_LEGS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) "*** WARNING *** subdev v4l2 set_input: Invalid routing scheme (%u) and/or input (%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) sid, hdw->input_val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) input = sp->def[hdw->input_val];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) sd->ops->video->s_routing(sd, input, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }