1d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely/*
2d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *
3d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *
4d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  Copyright (C) 2005 Mike Isely <isely@pobox.com>
5d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *
6d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  This program is free software; you can redistribute it and/or modify
7d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  it under the terms of the GNU General Public License as published by
8d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  the Free Software Foundation; either version 2 of the License
9d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *
10d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  This program is distributed in the hope that it will be useful,
11d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  GNU General Public License for more details.
14d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *
15d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  You should have received a copy of the GNU General Public License
16d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  along with this program; if not, write to the Free Software
17d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely *
19d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely */
20d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
21d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#include "pvrusb2-std.h"
22d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#include "pvrusb2-debug.h"
23b2bbaa93940627aec1d92191cf28a36e6048de6eMike Isely#include <asm/string.h>
24b2bbaa93940627aec1d92191cf28a36e6048de6eMike Isely#include <linux/slab.h>
25d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
26d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Iselystruct std_name {
27d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	const char *name;
28d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	v4l2_std_id id;
29d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely};
30d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
31d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
32d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define CSTD_PAL \
33d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	(V4L2_STD_PAL_B| \
34d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_PAL_B1| \
35d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_PAL_G| \
36d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_PAL_H| \
37d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_PAL_I| \
38d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_PAL_D| \
39d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_PAL_D1| \
40d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_PAL_K| \
41d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_PAL_M| \
42d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_PAL_N| \
43d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_PAL_Nc| \
44d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_PAL_60)
45d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
46d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define CSTD_NTSC \
47d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	(V4L2_STD_NTSC_M| \
48d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_NTSC_M_JP| \
49d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_NTSC_M_KR| \
50d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_NTSC_443)
51d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
529de982d3117a3f83e4e7b14016a1df25b4a693d6Mike Isely#define CSTD_ATSC \
539de982d3117a3f83e4e7b14016a1df25b4a693d6Mike Isely	(V4L2_STD_ATSC_8_VSB| \
549de982d3117a3f83e4e7b14016a1df25b4a693d6Mike Isely	 V4L2_STD_ATSC_16_VSB)
559de982d3117a3f83e4e7b14016a1df25b4a693d6Mike Isely
56d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define CSTD_SECAM \
57d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	(V4L2_STD_SECAM_B| \
58d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_SECAM_D| \
59d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_SECAM_G| \
60d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_SECAM_H| \
61d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_SECAM_K| \
62d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_SECAM_K1| \
63d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_SECAM_L| \
64d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	 V4L2_STD_SECAM_LC)
65d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
66d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define TSTD_B   (V4L2_STD_PAL_B|V4L2_STD_SECAM_B)
67d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define TSTD_B1  (V4L2_STD_PAL_B1)
68d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define TSTD_D   (V4L2_STD_PAL_D|V4L2_STD_SECAM_D)
69d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define TSTD_D1  (V4L2_STD_PAL_D1)
70d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define TSTD_G   (V4L2_STD_PAL_G|V4L2_STD_SECAM_G)
71d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define TSTD_H   (V4L2_STD_PAL_H|V4L2_STD_SECAM_H)
72d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define TSTD_I   (V4L2_STD_PAL_I)
73d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define TSTD_K   (V4L2_STD_PAL_K|V4L2_STD_SECAM_K)
74d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define TSTD_K1  (V4L2_STD_SECAM_K1)
75d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define TSTD_L   (V4L2_STD_SECAM_L)
76d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define TSTD_M   (V4L2_STD_PAL_M|V4L2_STD_NTSC_M)
77d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define TSTD_N   (V4L2_STD_PAL_N)
78d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define TSTD_Nc  (V4L2_STD_PAL_Nc)
79d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely#define TSTD_60  (V4L2_STD_PAL_60)
80d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
81ef7c37009225776e92979f464bfbf5d796d3a5eaMike Isely#define CSTD_ALL (CSTD_PAL|CSTD_NTSC|CSTD_ATSC|CSTD_SECAM)
82d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
83d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely/* Mapping of standard bits to color system */
84c5a69d57eb48e36f84c0737b5b24ec277d7dbfbaTobias Klauserstatic const struct std_name std_groups[] = {
85d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"PAL",CSTD_PAL},
86d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"NTSC",CSTD_NTSC},
87d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"SECAM",CSTD_SECAM},
889de982d3117a3f83e4e7b14016a1df25b4a693d6Mike Isely	{"ATSC",CSTD_ATSC},
89d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely};
90d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
91d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely/* Mapping of standard bits to modulation system */
92c5a69d57eb48e36f84c0737b5b24ec277d7dbfbaTobias Klauserstatic const struct std_name std_items[] = {
93d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"B",TSTD_B},
94d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"B1",TSTD_B1},
95d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"D",TSTD_D},
96d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"D1",TSTD_D1},
97d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"G",TSTD_G},
98d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"H",TSTD_H},
99d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"I",TSTD_I},
100d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"K",TSTD_K},
101d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"K1",TSTD_K1},
102d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"L",TSTD_L},
103d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"LC",V4L2_STD_SECAM_LC},
104d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"M",TSTD_M},
105d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"Mj",V4L2_STD_NTSC_M_JP},
106d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"443",V4L2_STD_NTSC_443},
107d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"Mk",V4L2_STD_NTSC_M_KR},
108d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"N",TSTD_N},
109d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"Nc",TSTD_Nc},
110d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{"60",TSTD_60},
1119de982d3117a3f83e4e7b14016a1df25b4a693d6Mike Isely	{"8VSB",V4L2_STD_ATSC_8_VSB},
1129de982d3117a3f83e4e7b14016a1df25b4a693d6Mike Isely	{"16VSB",V4L2_STD_ATSC_16_VSB},
113d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely};
114d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
115d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
116d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely// Search an array of std_name structures and return a pointer to the
117d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely// element with the matching name.
118d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Iselystatic const struct std_name *find_std_name(const struct std_name *arrPtr,
119d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely					    unsigned int arrSize,
120d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely					    const char *bufPtr,
121d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely					    unsigned int bufSize)
122d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely{
123d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	unsigned int idx;
124d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	const struct std_name *p;
125d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	for (idx = 0; idx < arrSize; idx++) {
126d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		p = arrPtr + idx;
127d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		if (strlen(p->name) != bufSize) continue;
128d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		if (!memcmp(bufPtr,p->name,bufSize)) return p;
129d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	}
130a0fd1cb171e8b17339a9a18ae7cf09c50022010fMike Isely	return NULL;
131d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely}
132d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
133d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
134d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Iselyint pvr2_std_str_to_id(v4l2_std_id *idPtr,const char *bufPtr,
135d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		       unsigned int bufSize)
136d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely{
137d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	v4l2_std_id id = 0;
138d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	v4l2_std_id cmsk = 0;
139d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	v4l2_std_id t;
140d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	int mMode = 0;
141d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	unsigned int cnt;
142d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	char ch;
143d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	const struct std_name *sp;
144d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
145d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	while (bufSize) {
146d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		if (!mMode) {
147d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			cnt = 0;
148d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			while ((cnt < bufSize) && (bufPtr[cnt] != '-')) cnt++;
149d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			if (cnt >= bufSize) return 0; // No more characters
150eca8ebfc11d1935a7dd4c59cb8defb5bdff44ecdAhmed S. Darwish			sp = find_std_name(std_groups, ARRAY_SIZE(std_groups),
151eca8ebfc11d1935a7dd4c59cb8defb5bdff44ecdAhmed S. Darwish					   bufPtr,cnt);
152d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			if (!sp) return 0; // Illegal color system name
153d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			cnt++;
154d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			bufPtr += cnt;
155d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			bufSize -= cnt;
156d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			mMode = !0;
157d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			cmsk = sp->id;
158d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			continue;
159d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		}
160d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		cnt = 0;
161d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		while (cnt < bufSize) {
162d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			ch = bufPtr[cnt];
163d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			if (ch == ';') {
164d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				mMode = 0;
165d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				break;
166d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			}
167d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			if (ch == '/') break;
168d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			cnt++;
169d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		}
170eca8ebfc11d1935a7dd4c59cb8defb5bdff44ecdAhmed S. Darwish		sp = find_std_name(std_items, ARRAY_SIZE(std_items),
171d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				   bufPtr,cnt);
172d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		if (!sp) return 0; // Illegal modulation system ID
173d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		t = sp->id & cmsk;
174d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		if (!t) return 0; // Specific color + modulation system illegal
175d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		id |= t;
176d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		if (cnt < bufSize) cnt++;
177d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		bufPtr += cnt;
178d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		bufSize -= cnt;
179d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	}
180d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
181d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	if (idPtr) *idPtr = id;
182d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	return !0;
183d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely}
184d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
185d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
186d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Iselyunsigned int pvr2_std_id_to_str(char *bufPtr, unsigned int bufSize,
187d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				v4l2_std_id id)
188d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely{
189d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	unsigned int idx1,idx2;
190d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	const struct std_name *ip,*gp;
191d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	int gfl,cfl;
192d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	unsigned int c1,c2;
193d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	cfl = 0;
194d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	c1 = 0;
195eca8ebfc11d1935a7dd4c59cb8defb5bdff44ecdAhmed S. Darwish	for (idx1 = 0; idx1 < ARRAY_SIZE(std_groups); idx1++) {
196d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		gp = std_groups + idx1;
197d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		gfl = 0;
198eca8ebfc11d1935a7dd4c59cb8defb5bdff44ecdAhmed S. Darwish		for (idx2 = 0; idx2 < ARRAY_SIZE(std_items); idx2++) {
199d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			ip = std_items + idx2;
200d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			if (!(gp->id & ip->id & id)) continue;
201d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			if (!gfl) {
202d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				if (cfl) {
203d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely					c2 = scnprintf(bufPtr,bufSize,";");
204d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely					c1 += c2;
205d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely					bufSize -= c2;
206d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely					bufPtr += c2;
207d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				}
208d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				cfl = !0;
209d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				c2 = scnprintf(bufPtr,bufSize,
210d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely					       "%s-",gp->name);
211d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				gfl = !0;
212d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			} else {
213d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				c2 = scnprintf(bufPtr,bufSize,"/");
214d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			}
215d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			c1 += c2;
216d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			bufSize -= c2;
217d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			bufPtr += c2;
218d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			c2 = scnprintf(bufPtr,bufSize,
219d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				       ip->name);
220d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			c1 += c2;
221d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			bufSize -= c2;
222d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			bufPtr += c2;
223d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		}
224d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	}
225d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	return c1;
226d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely}
227d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
228d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
229d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely// Template data for possible enumerated video standards.  Here we group
230d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely// standards which share common frame rates and resolution.
231d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Iselystatic struct v4l2_standard generic_standards[] = {
232d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	{
233d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.id             = (TSTD_B|TSTD_B1|
234d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				   TSTD_D|TSTD_D1|
235d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				   TSTD_G|
236d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				   TSTD_H|
237d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				   TSTD_I|
238d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				   TSTD_K|TSTD_K1|
239d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				   TSTD_L|
240d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				   V4L2_STD_SECAM_LC |
241d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				   TSTD_N|TSTD_Nc),
242d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.frameperiod    =
243d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		{
244d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			.numerator  = 1,
245d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			.denominator= 25
246d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		},
247d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.framelines     = 625,
248d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.reserved       = {0,0,0,0}
249d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	}, {
250d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.id             = (TSTD_M|
251d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				   V4L2_STD_NTSC_M_JP|
252d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely				   V4L2_STD_NTSC_M_KR),
253d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.frameperiod    =
254d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		{
255d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			.numerator  = 1001,
256d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			.denominator= 30000
257d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		},
258d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.framelines     = 525,
259d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.reserved       = {0,0,0,0}
260d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	}, { // This is a total wild guess
261d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.id             = (TSTD_60),
262d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.frameperiod    =
263d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		{
264d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			.numerator  = 1001,
265d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			.denominator= 30000
266d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		},
267d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.framelines     = 525,
268d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.reserved       = {0,0,0,0}
269d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	}, { // This is total wild guess
270d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.id             = V4L2_STD_NTSC_443,
271d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.frameperiod    =
272d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		{
273d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			.numerator  = 1001,
274d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			.denominator= 30000
275d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		},
276d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.framelines     = 525,
277d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		.reserved       = {0,0,0,0}
278d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	}
279d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely};
280d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
281d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Iselystatic struct v4l2_standard *match_std(v4l2_std_id id)
282d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely{
283d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	unsigned int idx;
28492f6ed71cafae8580bd481db66edb81c3d9d958cDan Carpenter	for (idx = 0; idx < ARRAY_SIZE(generic_standards); idx++) {
285d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		if (generic_standards[idx].id & id) {
286d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			return generic_standards + idx;
287d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		}
288d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	}
289a0fd1cb171e8b17339a9a18ae7cf09c50022010fMike Isely	return NULL;
290d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely}
291d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
292d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Iselystatic int pvr2_std_fill(struct v4l2_standard *std,v4l2_std_id id)
293d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely{
294d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	struct v4l2_standard *template;
295d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	int idx;
296d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	unsigned int bcnt;
297d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	template = match_std(id);
298d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	if (!template) return 0;
299d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	idx = std->index;
300d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	memcpy(std,template,sizeof(*template));
301d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	std->index = idx;
302d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	std->id = id;
303d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	bcnt = pvr2_std_id_to_str(std->name,sizeof(std->name)-1,id);
304d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	std->name[bcnt] = 0;
30556585386e297c54a65feef55810c13b4313bdf1eMike Isely	pvr2_trace(PVR2_TRACE_STD,"Set up standard idx=%u name=%s",
306d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		   std->index,std->name);
307d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	return !0;
308d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely}
309d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
310d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely/* These are special cases of combined standards that we should enumerate
311d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely   separately if the component pieces are present. */
312d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Iselystatic v4l2_std_id std_mixes[] = {
313d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	V4L2_STD_PAL_B | V4L2_STD_PAL_G,
314d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	V4L2_STD_PAL_D | V4L2_STD_PAL_K,
315d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	V4L2_STD_SECAM_B | V4L2_STD_SECAM_G,
316d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	V4L2_STD_SECAM_D | V4L2_STD_SECAM_K,
317d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely};
318d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
319d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Iselystruct v4l2_standard *pvr2_std_create_enum(unsigned int *countptr,
320d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely					   v4l2_std_id id)
321d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely{
322d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	unsigned int std_cnt = 0;
323d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	unsigned int idx,bcnt,idx2;
324d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	v4l2_std_id idmsk,cmsk,fmsk;
325d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	struct v4l2_standard *stddefs;
326d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
32756585386e297c54a65feef55810c13b4313bdf1eMike Isely	if (pvrusb2_debug & PVR2_TRACE_STD) {
328a00199fb3fe41c8190c38e548a178e965f582cdaMike Isely		char buf[100];
329d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		bcnt = pvr2_std_id_to_str(buf,sizeof(buf),id);
330d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		pvr2_trace(
33156585386e297c54a65feef55810c13b4313bdf1eMike Isely			PVR2_TRACE_STD,"Mapping standards mask=0x%x (%.*s)",
332d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			(int)id,bcnt,buf);
333d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	}
334d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
335d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	*countptr = 0;
336d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	std_cnt = 0;
337d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	fmsk = 0;
338d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	for (idmsk = 1, cmsk = id; cmsk; idmsk <<= 1) {
339d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		if (!(idmsk & cmsk)) continue;
340d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		cmsk &= ~idmsk;
341d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		if (match_std(idmsk)) {
342d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			std_cnt++;
343d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			continue;
344d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		}
345d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		fmsk |= idmsk;
346d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	}
347d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
348eca8ebfc11d1935a7dd4c59cb8defb5bdff44ecdAhmed S. Darwish	for (idx2 = 0; idx2 < ARRAY_SIZE(std_mixes); idx2++) {
349d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		if ((id & std_mixes[idx2]) == std_mixes[idx2]) std_cnt++;
350d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	}
351d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
352ef7c37009225776e92979f464bfbf5d796d3a5eaMike Isely	/* Don't complain about ATSC standard values */
353ef7c37009225776e92979f464bfbf5d796d3a5eaMike Isely	fmsk &= ~CSTD_ATSC;
354ef7c37009225776e92979f464bfbf5d796d3a5eaMike Isely
355d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	if (fmsk) {
356a00199fb3fe41c8190c38e548a178e965f582cdaMike Isely		char buf[100];
357d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		bcnt = pvr2_std_id_to_str(buf,sizeof(buf),fmsk);
358d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		pvr2_trace(
359d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			PVR2_TRACE_ERROR_LEGS,
360d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			"WARNING:"
361d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			" Failed to classify the following standard(s): %.*s",
362d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			bcnt,buf);
363d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	}
364d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
36556585386e297c54a65feef55810c13b4313bdf1eMike Isely	pvr2_trace(PVR2_TRACE_STD,"Setting up %u unique standard(s)",
366d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		   std_cnt);
367a0fd1cb171e8b17339a9a18ae7cf09c50022010fMike Isely	if (!std_cnt) return NULL; // paranoia
368d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
369ca545f7c39476c6c4c6e639452180a2b38342669Mike Isely	stddefs = kzalloc(sizeof(struct v4l2_standard) * std_cnt,
370d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely			  GFP_KERNEL);
3710cff593732fa5bdf07192be741a567b85a9c0cd3Dan Carpenter	if (!stddefs)
3720cff593732fa5bdf07192be741a567b85a9c0cd3Dan Carpenter		return NULL;
3730cff593732fa5bdf07192be741a567b85a9c0cd3Dan Carpenter
3740cff593732fa5bdf07192be741a567b85a9c0cd3Dan Carpenter	for (idx = 0; idx < std_cnt; idx++)
3750cff593732fa5bdf07192be741a567b85a9c0cd3Dan Carpenter		stddefs[idx].index = idx;
376d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
377d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	idx = 0;
378d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
379d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	/* Enumerate potential special cases */
380eca8ebfc11d1935a7dd4c59cb8defb5bdff44ecdAhmed S. Darwish	for (idx2 = 0; (idx2 < ARRAY_SIZE(std_mixes)) && (idx < std_cnt);
381eca8ebfc11d1935a7dd4c59cb8defb5bdff44ecdAhmed S. Darwish	     idx2++) {
382d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		if (!(id & std_mixes[idx2])) continue;
383d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		if (pvr2_std_fill(stddefs+idx,std_mixes[idx2])) idx++;
384d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	}
385d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	/* Now enumerate individual pieces */
386d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	for (idmsk = 1, cmsk = id; cmsk && (idx < std_cnt); idmsk <<= 1) {
387d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		if (!(idmsk & cmsk)) continue;
388d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		cmsk &= ~idmsk;
389d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		if (!pvr2_std_fill(stddefs+idx,idmsk)) continue;
390d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely		idx++;
391d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	}
392d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
393d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	*countptr = std_cnt;
394d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	return stddefs;
395d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely}
396d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
397d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Iselyv4l2_std_id pvr2_std_get_usable(void)
398d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely{
399d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely	return CSTD_ALL;
400d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely}
401d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
402d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely
403d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely/*
404d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  Stuff for Emacs to see, in order to encourage consistent editing style:
405d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  *** Local Variables: ***
406d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  *** mode: c ***
407d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  *** fill-column: 75 ***
408d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  *** tab-width: 8 ***
409d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  *** c-basic-offset: 8 ***
410d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  *** End: ***
411d855497edbfbf9e19a17f4a1154bca69cb4bd9baMike Isely  */
412