1d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely/*
2d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *
3d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *
4d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
5d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  Copyright (C) 2004 Aurelien Alleaume <slts@free.fr>
6d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *
7d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  This program is free software; you can redistribute it and/or modify
8d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  it under the terms of the GNU General Public License as published by
9d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  the Free Software Foundation; either version 2 of the License
10d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *
11d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  This program is distributed in the hope that it will be useful,
12d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  GNU General Public License for more details.
15d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *
16d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  You should have received a copy of the GNU General Public License
17d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  along with this program; if not, write to the Free Software
18d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *
20d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely */
21d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
22d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely/*
23d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
24d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely   This source file is specifically designed to interface with the
25d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely   cx2584x, in kernels 2.6.16 or newer.
26d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
27d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely*/
28d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
29d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#include "pvrusb2-cx2584x-v4l.h"
30d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#include "pvrusb2-video-v4l.h"
31d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
32d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
33d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#include "pvrusb2-hdw-internal.h"
34d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#include "pvrusb2-debug.h"
35d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#include <media/cx25840.h>
36d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#include <linux/videodev2.h>
37d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#include <media/v4l2-common.h>
38d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#include <linux/errno.h>
39d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
40d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
41f5174af201f2e22c101bb02d06343e4bc5f056deMike Iselystruct routing_scheme_item {
42f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely	int vid;
43f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely	int aud;
44f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely};
45f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely
46f5174af201f2e22c101bb02d06343e4bc5f056deMike Iselystruct routing_scheme {
47f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely	const struct routing_scheme_item *def;
48f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely	unsigned int cnt;
49f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely};
50f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely
51f5174af201f2e22c101bb02d06343e4bc5f056deMike Iselystatic const struct routing_scheme_item routing_scheme0[] = {
52f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely	[PVR2_CVAL_INPUT_TV] = {
53f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely		.vid = CX25840_COMPOSITE7,
54f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely		.aud = CX25840_AUDIO8,
55f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely	},
56f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely	[PVR2_CVAL_INPUT_RADIO] = { /* Treat the same as composite */
57f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely		.vid = CX25840_COMPOSITE3,
58f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely		.aud = CX25840_AUDIO_SERIAL,
59f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely	},
60f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely	[PVR2_CVAL_INPUT_COMPOSITE] = {
61f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely		.vid = CX25840_COMPOSITE3,
62f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely		.aud = CX25840_AUDIO_SERIAL,
63f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely	},
64f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely	[PVR2_CVAL_INPUT_SVIDEO] = {
65f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely		.vid = CX25840_SVIDEO1,
66f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely		.aud = CX25840_AUDIO_SERIAL,
67f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely	},
68f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely};
69f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely
7081e804c9c2e38431c1c01165d06076776c6fcbd6Mike Iselystatic const struct routing_scheme routing_def0 = {
7181e804c9c2e38431c1c01165d06076776c6fcbd6Mike Isely	.def = routing_scheme0,
7281e804c9c2e38431c1c01165d06076776c6fcbd6Mike Isely	.cnt = ARRAY_SIZE(routing_scheme0),
7381e804c9c2e38431c1c01165d06076776c6fcbd6Mike Isely};
7481e804c9c2e38431c1c01165d06076776c6fcbd6Mike Isely
759e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely/* Specific to gotview device */
769e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Iselystatic const struct routing_scheme_item routing_schemegv[] = {
779e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely	[PVR2_CVAL_INPUT_TV] = {
789e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely		.vid = CX25840_COMPOSITE2,
799e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely		.aud = CX25840_AUDIO5,
809e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely	},
811df59f0b908bfcdc35d1ea2319290ece272bf576Mike Isely	[PVR2_CVAL_INPUT_RADIO] = {
821df59f0b908bfcdc35d1ea2319290ece272bf576Mike Isely		/* line-in is used for radio and composite.  A GPIO is
831df59f0b908bfcdc35d1ea2319290ece272bf576Mike Isely		   used to switch between the two choices. */
849e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely		.vid = CX25840_COMPOSITE1,
859e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely		.aud = CX25840_AUDIO_SERIAL,
869e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely	},
879e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely	[PVR2_CVAL_INPUT_COMPOSITE] = {
889e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely		.vid = CX25840_COMPOSITE1,
899e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely		.aud = CX25840_AUDIO_SERIAL,
909e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely	},
919e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely	[PVR2_CVAL_INPUT_SVIDEO] = {
929e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely		.vid = (CX25840_SVIDEO_LUMA3|CX25840_SVIDEO_CHROMA4),
939e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely		.aud = CX25840_AUDIO_SERIAL,
949e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely	},
959e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely};
969e2e3aeb2d2c8bf64b04e1f5747f1d9842df43deMike Isely
9781e804c9c2e38431c1c01165d06076776c6fcbd6Mike Iselystatic const struct routing_scheme routing_defgv = {
9881e804c9c2e38431c1c01165d06076776c6fcbd6Mike Isely	.def = routing_schemegv,
9981e804c9c2e38431c1c01165d06076776c6fcbd6Mike Isely	.cnt = ARRAY_SIZE(routing_schemegv),
10081e804c9c2e38431c1c01165d06076776c6fcbd6Mike Isely};
10181e804c9c2e38431c1c01165d06076776c6fcbd6Mike Isely
10243823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely/* Specific to grabster av400 device */
10343823c02245a445b5669d43b1ec07b6d8ae710f5Mike Iselystatic const struct routing_scheme_item routing_schemeav400[] = {
10443823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely	[PVR2_CVAL_INPUT_COMPOSITE] = {
10543823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely		.vid = CX25840_COMPOSITE1,
10643823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely		.aud = CX25840_AUDIO_SERIAL,
10743823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely	},
10843823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely	[PVR2_CVAL_INPUT_SVIDEO] = {
10943823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely		.vid = (CX25840_SVIDEO_LUMA2|CX25840_SVIDEO_CHROMA4),
11043823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely		.aud = CX25840_AUDIO_SERIAL,
11143823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely	},
11243823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely};
11343823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely
11443823c02245a445b5669d43b1ec07b6d8ae710f5Mike Iselystatic const struct routing_scheme routing_defav400 = {
11543823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely	.def = routing_schemeav400,
11643823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely	.cnt = ARRAY_SIZE(routing_schemeav400),
11743823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely};
11843823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely
11981e804c9c2e38431c1c01165d06076776c6fcbd6Mike Iselystatic const struct routing_scheme *routing_schemes[] = {
12081e804c9c2e38431c1c01165d06076776c6fcbd6Mike Isely	[PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
12181e804c9c2e38431c1c01165d06076776c6fcbd6Mike Isely	[PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
12243823c02245a445b5669d43b1ec07b6d8ae710f5Mike Isely	[PVR2_ROUTING_SCHEME_AV400] = &routing_defav400,
123f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely};
124f5174af201f2e22c101bb02d06343e4bc5f056deMike Isely
125634ba268b965b57da1f60edbc57f14299a5326f6Mike Iselyvoid pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
126634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely{
1275e430ca5d25e99f99c055bc43f8f140722a643b8Mike Isely	pvr2_trace(PVR2_TRACE_CHIPS, "subdev cx2584x update...");
12827764726a8fa72a7e8a7cdccbe9e4425747a96faMike Isely	if (hdw->input_dirty || hdw->force_dirty) {
129634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely		enum cx25840_video_input vid_input;
130634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely		enum cx25840_audio_input aud_input;
131634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely		const struct routing_scheme *sp;
132634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely		unsigned int sid = hdw->hdw_desc->signal_routing_scheme;
133634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely
13490135c96869fa0ef3182282b2a661b57fcdb7230Mike Isely		sp = (sid < ARRAY_SIZE(routing_schemes)) ?
13590135c96869fa0ef3182282b2a661b57fcdb7230Mike Isely			routing_schemes[sid] : NULL;
13690135c96869fa0ef3182282b2a661b57fcdb7230Mike Isely		if ((sp == NULL) ||
13790135c96869fa0ef3182282b2a661b57fcdb7230Mike Isely		    (hdw->input_val < 0) ||
13890135c96869fa0ef3182282b2a661b57fcdb7230Mike Isely		    (hdw->input_val >= sp->cnt)) {
139634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely			pvr2_trace(PVR2_TRACE_ERROR_LEGS,
140634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely				   "*** WARNING *** subdev cx2584x set_input:"
141634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely				   " Invalid routing scheme (%u)"
142634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely				   " and/or input (%d)",
143634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely				   sid, hdw->input_val);
144634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely			return;
145634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely		}
14690135c96869fa0ef3182282b2a661b57fcdb7230Mike Isely		vid_input = sp->def[hdw->input_val].vid;
14790135c96869fa0ef3182282b2a661b57fcdb7230Mike Isely		aud_input = sp->def[hdw->input_val].aud;
148634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely		pvr2_trace(PVR2_TRACE_CHIPS,
1495e430ca5d25e99f99c055bc43f8f140722a643b8Mike Isely			   "subdev cx2584x set_input vid=0x%x aud=0x%x",
150634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely			   vid_input, aud_input);
1515325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil		sd->ops->video->s_routing(sd, (u32)vid_input, 0, 0);
1525325b4272a53b43f55b82cc369c310c2fcacdca1Hans Verkuil		sd->ops->audio->s_routing(sd, (u32)aud_input, 0, 0);
153634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely	}
154634ba268b965b57da1f60edbc57f14299a5326f6Mike Isely}
155d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
156d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
157acd92d40ccaf140d27e6bd5b83573294165ebbdfMike Isely
158d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely/*
159d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  Stuff for Emacs to see, in order to encourage consistent editing style:
160d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  *** Local Variables: ***
161d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  *** mode: c ***
162d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  *** fill-column: 70 ***
163d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  *** tab-width: 8 ***
164d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  *** c-basic-offset: 8 ***
165d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  *** End: ***
166d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  */
167