aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18/cx18-av-vbi.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2009-03-30 05:43:13 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:43:49 -0400
commit41c129a87014bb83efb3e0224bb44cfc54659f8f (patch)
tree8a0b6f5db17d95db0f586343e761abff23a7d272 /drivers/media/video/cx18/cx18-av-vbi.c
parentdf1d5ed8a81565b78d45fbdffb6561c75c75ec0d (diff)
V4L/DVB (11310): cx18: remove intermediate 'ioctl' step
The audio and vbi parts still used an 'ioctl'-like interface. Replace this with normal functions. Cc: Andy Walls <awalls@radix.net> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18/cx18-av-vbi.c')
-rw-r--r--drivers/media/video/cx18/cx18-av-vbi.c325
1 files changed, 159 insertions, 166 deletions
diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c
index 27699839b80d..23b31670bf1d 100644
--- a/drivers/media/video/cx18/cx18-av-vbi.c
+++ b/drivers/media/video/cx18/cx18-av-vbi.c
@@ -129,196 +129,189 @@ static int decode_vps(u8 *dst, u8 *p)
129 return err & 0xf0; 129 return err & 0xf0;
130} 130}
131 131
132int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) 132int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt)
133{ 133{
134 struct cx18_av_state *state = &cx->av_state; 134 struct cx18_av_state *state = &cx->av_state;
135 struct v4l2_format *fmt;
136 struct v4l2_sliced_vbi_format *svbi; 135 struct v4l2_sliced_vbi_format *svbi;
136 static const u16 lcr2vbi[] = {
137 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
138 0, V4L2_SLICED_WSS_625, 0, /* 4 */
139 V4L2_SLICED_CAPTION_525, /* 6 */
140 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
141 0, 0, 0, 0
142 };
143 int is_pal = !(state->std & V4L2_STD_525_60);
144 int i;
137 145
138 switch (cmd) { 146 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
139 case VIDIOC_G_FMT: 147 return -EINVAL;
140 { 148 svbi = &fmt->fmt.sliced;
141 static u16 lcr2vbi[] = { 149 memset(svbi, 0, sizeof(*svbi));
142 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ 150 /* we're done if raw VBI is active */
143 0, V4L2_SLICED_WSS_625, 0, /* 4 */ 151 if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
144 V4L2_SLICED_CAPTION_525, /* 6 */ 152 return 0;
145 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ 153
146 0, 0, 0, 0 154 if (is_pal) {
147 }; 155 for (i = 7; i <= 23; i++) {
148 int is_pal = !(state->std & V4L2_STD_525_60); 156 u8 v = cx18_av_read(cx, 0x424 + i - 7);
149 int i;
150
151 fmt = arg;
152 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
153 return -EINVAL;
154 svbi = &fmt->fmt.sliced;
155 memset(svbi, 0, sizeof(*svbi));
156 /* we're done if raw VBI is active */
157 if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
158 break;
159
160 if (is_pal) {
161 for (i = 7; i <= 23; i++) {
162 u8 v = cx18_av_read(cx, 0x424 + i - 7);
163
164 svbi->service_lines[0][i] = lcr2vbi[v >> 4];
165 svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
166 svbi->service_set |= svbi->service_lines[0][i] |
167 svbi->service_lines[1][i];
168 }
169 } else {
170 for (i = 10; i <= 21; i++) {
171 u8 v = cx18_av_read(cx, 0x424 + i - 10);
172
173 svbi->service_lines[0][i] = lcr2vbi[v >> 4];
174 svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
175 svbi->service_set |= svbi->service_lines[0][i] |
176 svbi->service_lines[1][i];
177 }
178 }
179 break;
180 }
181 157
182 case VIDIOC_S_FMT: 158 svbi->service_lines[0][i] = lcr2vbi[v >> 4];
183 { 159 svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
184 int is_pal = !(state->std & V4L2_STD_525_60); 160 svbi->service_set |= svbi->service_lines[0][i] |
185 int i, x; 161 svbi->service_lines[1][i];
186 u8 lcr[24];
187
188 fmt = arg;
189 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
190 fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
191 return -EINVAL;
192 svbi = &fmt->fmt.sliced;
193 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
194 /* raw VBI */
195 memset(svbi, 0, sizeof(*svbi));
196
197 /* Setup standard */
198 cx18_av_std_setup(cx);
199
200 /* VBI Offset */
201 cx18_av_write(cx, 0x47f, state->slicer_line_delay);
202 cx18_av_write(cx, 0x404, 0x2e);
203 break;
204 } 162 }
163 } else {
164 for (i = 10; i <= 21; i++) {
165 u8 v = cx18_av_read(cx, 0x424 + i - 10);
166
167 svbi->service_lines[0][i] = lcr2vbi[v >> 4];
168 svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
169 svbi->service_set |= svbi->service_lines[0][i] |
170 svbi->service_lines[1][i];
171 }
172 }
173 return 0;
174}
205 175
206 for (x = 0; x <= 23; x++) 176int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt)
207 lcr[x] = 0x00; 177{
178 struct cx18_av_state *state = &cx->av_state;
179 struct v4l2_sliced_vbi_format *svbi;
180 int is_pal = !(state->std & V4L2_STD_525_60);
181 int i, x;
182 u8 lcr[24];
183
184 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
185 fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
186 return -EINVAL;
187 svbi = &fmt->fmt.sliced;
188 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
189 /* raw VBI */
190 memset(svbi, 0, sizeof(*svbi));
208 191
209 /* Setup standard */ 192 /* Setup standard */
210 cx18_av_std_setup(cx); 193 cx18_av_std_setup(cx);
211 194
212 /* Sliced VBI */ 195 /* VBI Offset */
213 cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
214 cx18_av_write(cx, 0x406, 0x13);
215 cx18_av_write(cx, 0x47f, state->slicer_line_delay); 196 cx18_av_write(cx, 0x47f, state->slicer_line_delay);
197 cx18_av_write(cx, 0x404, 0x2e);
198 return 0;
199 }
216 200
217 /* Force impossible lines to 0 */ 201 for (x = 0; x <= 23; x++)
218 if (is_pal) { 202 lcr[x] = 0x00;
219 for (i = 0; i <= 6; i++) 203
220 svbi->service_lines[0][i] = 204 /* Setup standard */
221 svbi->service_lines[1][i] = 0; 205 cx18_av_std_setup(cx);
222 } else { 206
223 for (i = 0; i <= 9; i++) 207 /* Sliced VBI */
224 svbi->service_lines[0][i] = 208 cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
225 svbi->service_lines[1][i] = 0; 209 cx18_av_write(cx, 0x406, 0x13);
226 210 cx18_av_write(cx, 0x47f, state->slicer_line_delay);
227 for (i = 22; i <= 23; i++) 211
228 svbi->service_lines[0][i] = 212 /* Force impossible lines to 0 */
229 svbi->service_lines[1][i] = 0; 213 if (is_pal) {
230 } 214 for (i = 0; i <= 6; i++)
215 svbi->service_lines[0][i] =
216 svbi->service_lines[1][i] = 0;
217 } else {
218 for (i = 0; i <= 9; i++)
219 svbi->service_lines[0][i] =
220 svbi->service_lines[1][i] = 0;
221
222 for (i = 22; i <= 23; i++)
223 svbi->service_lines[0][i] =
224 svbi->service_lines[1][i] = 0;
225 }
231 226
232 /* Build register values for requested service lines */ 227 /* Build register values for requested service lines */
233 for (i = 7; i <= 23; i++) { 228 for (i = 7; i <= 23; i++) {
234 for (x = 0; x <= 1; x++) { 229 for (x = 0; x <= 1; x++) {
235 switch (svbi->service_lines[1-x][i]) { 230 switch (svbi->service_lines[1-x][i]) {
236 case V4L2_SLICED_TELETEXT_B: 231 case V4L2_SLICED_TELETEXT_B:
237 lcr[i] |= 1 << (4 * x); 232 lcr[i] |= 1 << (4 * x);
238 break; 233 break;
239 case V4L2_SLICED_WSS_625: 234 case V4L2_SLICED_WSS_625:
240 lcr[i] |= 4 << (4 * x); 235 lcr[i] |= 4 << (4 * x);
241 break; 236 break;
242 case V4L2_SLICED_CAPTION_525: 237 case V4L2_SLICED_CAPTION_525:
243 lcr[i] |= 6 << (4 * x); 238 lcr[i] |= 6 << (4 * x);
244 break; 239 break;
245 case V4L2_SLICED_VPS: 240 case V4L2_SLICED_VPS:
246 lcr[i] |= 9 << (4 * x); 241 lcr[i] |= 9 << (4 * x);
247 break; 242 break;
248 }
249 } 243 }
250 } 244 }
245 }
251 246
252 if (is_pal) { 247 if (is_pal) {
253 for (x = 1, i = 0x424; i <= 0x434; i++, x++) 248 for (x = 1, i = 0x424; i <= 0x434; i++, x++)
254 cx18_av_write(cx, i, lcr[6 + x]); 249 cx18_av_write(cx, i, lcr[6 + x]);
255 } else { 250 } else {
256 for (x = 1, i = 0x424; i <= 0x430; i++, x++) 251 for (x = 1, i = 0x424; i <= 0x430; i++, x++)
257 cx18_av_write(cx, i, lcr[9 + x]); 252 cx18_av_write(cx, i, lcr[9 + x]);
258 for (i = 0x431; i <= 0x434; i++) 253 for (i = 0x431; i <= 0x434; i++)
259 cx18_av_write(cx, i, 0); 254 cx18_av_write(cx, i, 0);
260 } 255 }
261 256
262 cx18_av_write(cx, 0x43c, 0x16); 257 cx18_av_write(cx, 0x43c, 0x16);
263 /* FIXME - should match vblank set in cx18_av_std_setup() */ 258 /* FIXME - should match vblank set in cx18_av_std_setup() */
264 cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26); 259 cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26);
265 break; 260 return 0;
261}
262
263int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
264 struct v4l2_decode_vbi_line *vbi)
265{
266 struct cx18 *cx = v4l2_get_subdevdata(sd);
267 struct cx18_av_state *state = &cx->av_state;
268 struct vbi_anc_data *anc = (struct vbi_anc_data *)vbi->p;
269 u8 *p;
270 int did, sdid, l, err = 0;
271
272 /*
273 * Check for the ancillary data header for sliced VBI
274 */
275 if (anc->preamble[0] ||
276 anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
277 (anc->did != sliced_vbi_did[0] &&
278 anc->did != sliced_vbi_did[1])) {
279 vbi->line = vbi->type = 0;
280 return 0;
266 } 281 }
267 282
268 case VIDIOC_INT_DECODE_VBI_LINE: 283 did = anc->did;
269 { 284 sdid = anc->sdid & 0xf;
270 struct v4l2_decode_vbi_line *vbi = arg; 285 l = anc->idid[0] & 0x3f;
271 u8 *p; 286 l += state->slicer_line_offset;
272 struct vbi_anc_data *anc = (struct vbi_anc_data *) vbi->p; 287 p = anc->payload;
273 int did, sdid, l, err = 0;
274
275 /*
276 * Check for the ancillary data header for sliced VBI
277 */
278 if (anc->preamble[0] ||
279 anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
280 (anc->did != sliced_vbi_did[0] &&
281 anc->did != sliced_vbi_did[1])) {
282 vbi->line = vbi->type = 0;
283 break;
284 }
285 288
286 did = anc->did; 289 /* Decode the SDID set by the slicer */
287 sdid = anc->sdid & 0xf; 290 switch (sdid) {
288 l = anc->idid[0] & 0x3f; 291 case 1:
289 l += state->slicer_line_offset; 292 sdid = V4L2_SLICED_TELETEXT_B;
290 p = anc->payload; 293 break;
291 294 case 4:
292 /* Decode the SDID set by the slicer */ 295 sdid = V4L2_SLICED_WSS_625;
293 switch (sdid) { 296 break;
294 case 1: 297 case 6:
295 sdid = V4L2_SLICED_TELETEXT_B; 298 sdid = V4L2_SLICED_CAPTION_525;
296 break; 299 err = !odd_parity(p[0]) || !odd_parity(p[1]);
297 case 4: 300 break;
298 sdid = V4L2_SLICED_WSS_625; 301 case 9:
299 break; 302 sdid = V4L2_SLICED_VPS;
300 case 6: 303 if (decode_vps(p, p) != 0)
301 sdid = V4L2_SLICED_CAPTION_525;
302 err = !odd_parity(p[0]) || !odd_parity(p[1]);
303 break;
304 case 9:
305 sdid = V4L2_SLICED_VPS;
306 if (decode_vps(p, p) != 0)
307 err = 1;
308 break;
309 default:
310 sdid = 0;
311 err = 1; 304 err = 1;
312 break;
313 }
314
315 vbi->type = err ? 0 : sdid;
316 vbi->line = err ? 0 : l;
317 vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
318 vbi->p = p;
319 break; 305 break;
320 } 306 default:
307 sdid = 0;
308 err = 1;
309 break;
321 } 310 }
322 311
312 vbi->type = err ? 0 : sdid;
313 vbi->line = err ? 0 : l;
314 vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
315 vbi->p = p;
323 return 0; 316 return 0;
324} 317}