diff options
author | Hans Verkuil <hverkuil@xs4all.nl> | 2009-03-30 05:43:13 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2009-03-30 11:43:49 -0400 |
commit | 41c129a87014bb83efb3e0224bb44cfc54659f8f (patch) | |
tree | 8a0b6f5db17d95db0f586343e761abff23a7d272 /drivers/media/video/cx18/cx18-av-vbi.c | |
parent | df1d5ed8a81565b78d45fbdffb6561c75c75ec0d (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.c | 325 |
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 | ||
132 | int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) | 132 | int 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++) | 176 | int 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 | |||
263 | int 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 | } |