1 | /* |
2 | * Copyright (c) 2013,2016 Lubomir Rintel |
3 | * All rights reserved. |
4 | * |
5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions |
7 | * are met: |
8 | * 1. Redistributions of source code must retain the above copyright |
9 | * notice, this list of conditions, and the following disclaimer, |
10 | * without modification. |
11 | * 2. The name of the author may not be used to endorse or promote products |
12 | * derived from this software without specific prior written permission. |
13 | * |
14 | * Alternatively, this software may be distributed under the terms of the |
15 | * GNU General Public License ("GPL"). |
16 | * |
17 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
18 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
19 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
20 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
21 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
22 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
23 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
24 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
25 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | */ |
29 | /* |
30 | * Fushicai USBTV007 Audio-Video Grabber Driver |
31 | * |
32 | * Product web site: |
33 | * http://www.fushicai.com/products_detail/&productId=d05449ee-b690-42f9-a661-aa7353894bed.html |
34 | * |
35 | * Following LWN articles were very useful in construction of this driver: |
36 | * Video4Linux2 API series: http://lwn.net/Articles/203924/ |
37 | * videobuf2 API explanation: http://lwn.net/Articles/447435/ |
38 | * Thanks go to Jonathan Corbet for providing this quality documentation. |
39 | * He is awesome. |
40 | * |
41 | * No physical hardware was harmed running Windows during the |
42 | * reverse-engineering activity |
43 | */ |
44 | |
45 | #include <media/v4l2-ioctl.h> |
46 | #include <media/videobuf2-v4l2.h> |
47 | |
48 | #include "usbtv.h" |
49 | |
50 | static const struct usbtv_norm_params norm_params[] = { |
51 | { |
52 | .norm = V4L2_STD_525_60, |
53 | .cap_width = 720, |
54 | .cap_height = 480, |
55 | }, |
56 | { |
57 | .norm = V4L2_STD_625_50, |
58 | .cap_width = 720, |
59 | .cap_height = 576, |
60 | } |
61 | }; |
62 | |
63 | static int usbtv_configure_for_norm(struct usbtv *usbtv, v4l2_std_id norm) |
64 | { |
65 | int i, ret = 0; |
66 | const struct usbtv_norm_params *params = NULL; |
67 | |
68 | for (i = 0; i < ARRAY_SIZE(norm_params); i++) { |
69 | if (norm_params[i].norm & norm) { |
70 | params = &norm_params[i]; |
71 | break; |
72 | } |
73 | } |
74 | |
75 | if (params) { |
76 | usbtv->width = params->cap_width; |
77 | usbtv->height = params->cap_height; |
78 | usbtv->n_chunks = usbtv->width * usbtv->height |
79 | / 4 / USBTV_CHUNK; |
80 | usbtv->norm = norm; |
81 | } else |
82 | ret = -EINVAL; |
83 | |
84 | return ret; |
85 | } |
86 | |
87 | static int usbtv_select_input(struct usbtv *usbtv, int input) |
88 | { |
89 | int ret; |
90 | |
91 | static const u16 composite[][2] = { |
92 | { USBTV_BASE + 0x0105, 0x0060 }, |
93 | { USBTV_BASE + 0x011f, 0x00f2 }, |
94 | { USBTV_BASE + 0x0127, 0x0060 }, |
95 | { USBTV_BASE + 0x00ae, 0x0010 }, |
96 | { USBTV_BASE + 0x0239, 0x0060 }, |
97 | }; |
98 | |
99 | static const u16 svideo[][2] = { |
100 | { USBTV_BASE + 0x0105, 0x0010 }, |
101 | { USBTV_BASE + 0x011f, 0x00ff }, |
102 | { USBTV_BASE + 0x0127, 0x0060 }, |
103 | { USBTV_BASE + 0x00ae, 0x0030 }, |
104 | { USBTV_BASE + 0x0239, 0x0060 }, |
105 | }; |
106 | |
107 | switch (input) { |
108 | case USBTV_COMPOSITE_INPUT: |
109 | ret = usbtv_set_regs(usbtv, regs: composite, ARRAY_SIZE(composite)); |
110 | break; |
111 | case USBTV_SVIDEO_INPUT: |
112 | ret = usbtv_set_regs(usbtv, regs: svideo, ARRAY_SIZE(svideo)); |
113 | break; |
114 | default: |
115 | ret = -EINVAL; |
116 | } |
117 | |
118 | if (!ret) |
119 | usbtv->input = input; |
120 | |
121 | return ret; |
122 | } |
123 | |
124 | static uint16_t usbtv_norm_to_16f_reg(v4l2_std_id norm) |
125 | { |
126 | /* NTSC M/M-JP/M-KR */ |
127 | if (norm & V4L2_STD_NTSC) |
128 | return 0x00b8; |
129 | /* PAL BG/DK/H/I */ |
130 | if (norm & V4L2_STD_PAL) |
131 | return 0x00ee; |
132 | /* SECAM B/D/G/H/K/K1/L/Lc */ |
133 | if (norm & V4L2_STD_SECAM) |
134 | return 0x00ff; |
135 | if (norm & V4L2_STD_NTSC_443) |
136 | return 0x00a8; |
137 | if (norm & (V4L2_STD_PAL_M | V4L2_STD_PAL_60)) |
138 | return 0x00bc; |
139 | if (norm & V4L2_STD_PAL_Nc) |
140 | return 0x00fe; |
141 | /* Fallback to automatic detection for other standards */ |
142 | return 0x0000; |
143 | } |
144 | |
145 | static int usbtv_select_norm(struct usbtv *usbtv, v4l2_std_id norm) |
146 | { |
147 | int ret; |
148 | /* These are the series of register values used to configure the |
149 | * decoder for a specific standard. |
150 | * The first 21 register writes are copied from the |
151 | * Settings\DecoderDefaults registry keys present in the Windows driver |
152 | * .INF file, and control various image tuning parameters (color |
153 | * correction, sharpness, ...). |
154 | */ |
155 | static const u16 pal[][2] = { |
156 | /* "AVPAL" tuning sequence from .INF file */ |
157 | { USBTV_BASE + 0x0003, 0x0004 }, |
158 | { USBTV_BASE + 0x001a, 0x0068 }, |
159 | { USBTV_BASE + 0x0100, 0x00d3 }, |
160 | { USBTV_BASE + 0x010e, 0x0072 }, |
161 | { USBTV_BASE + 0x010f, 0x00a2 }, |
162 | { USBTV_BASE + 0x0112, 0x00b0 }, |
163 | { USBTV_BASE + 0x0115, 0x0015 }, |
164 | { USBTV_BASE + 0x0117, 0x0001 }, |
165 | { USBTV_BASE + 0x0118, 0x002c }, |
166 | { USBTV_BASE + 0x012d, 0x0010 }, |
167 | { USBTV_BASE + 0x012f, 0x0020 }, |
168 | { USBTV_BASE + 0x0220, 0x002e }, |
169 | { USBTV_BASE + 0x0225, 0x0008 }, |
170 | { USBTV_BASE + 0x024e, 0x0002 }, |
171 | { USBTV_BASE + 0x024f, 0x0002 }, |
172 | { USBTV_BASE + 0x0254, 0x0059 }, |
173 | { USBTV_BASE + 0x025a, 0x0016 }, |
174 | { USBTV_BASE + 0x025b, 0x0035 }, |
175 | { USBTV_BASE + 0x0263, 0x0017 }, |
176 | { USBTV_BASE + 0x0266, 0x0016 }, |
177 | { USBTV_BASE + 0x0267, 0x0036 }, |
178 | /* End image tuning */ |
179 | { USBTV_BASE + 0x024e, 0x0002 }, |
180 | { USBTV_BASE + 0x024f, 0x0002 }, |
181 | }; |
182 | |
183 | static const u16 ntsc[][2] = { |
184 | /* "AVNTSC" tuning sequence from .INF file */ |
185 | { USBTV_BASE + 0x0003, 0x0004 }, |
186 | { USBTV_BASE + 0x001a, 0x0079 }, |
187 | { USBTV_BASE + 0x0100, 0x00d3 }, |
188 | { USBTV_BASE + 0x010e, 0x0068 }, |
189 | { USBTV_BASE + 0x010f, 0x009c }, |
190 | { USBTV_BASE + 0x0112, 0x00f0 }, |
191 | { USBTV_BASE + 0x0115, 0x0015 }, |
192 | { USBTV_BASE + 0x0117, 0x0000 }, |
193 | { USBTV_BASE + 0x0118, 0x00fc }, |
194 | { USBTV_BASE + 0x012d, 0x0004 }, |
195 | { USBTV_BASE + 0x012f, 0x0008 }, |
196 | { USBTV_BASE + 0x0220, 0x002e }, |
197 | { USBTV_BASE + 0x0225, 0x0008 }, |
198 | { USBTV_BASE + 0x024e, 0x0002 }, |
199 | { USBTV_BASE + 0x024f, 0x0001 }, |
200 | { USBTV_BASE + 0x0254, 0x005f }, |
201 | { USBTV_BASE + 0x025a, 0x0012 }, |
202 | { USBTV_BASE + 0x025b, 0x0001 }, |
203 | { USBTV_BASE + 0x0263, 0x001c }, |
204 | { USBTV_BASE + 0x0266, 0x0011 }, |
205 | { USBTV_BASE + 0x0267, 0x0005 }, |
206 | /* End image tuning */ |
207 | { USBTV_BASE + 0x024e, 0x0002 }, |
208 | { USBTV_BASE + 0x024f, 0x0002 }, |
209 | }; |
210 | |
211 | static const u16 secam[][2] = { |
212 | /* "AVSECAM" tuning sequence from .INF file */ |
213 | { USBTV_BASE + 0x0003, 0x0004 }, |
214 | { USBTV_BASE + 0x001a, 0x0073 }, |
215 | { USBTV_BASE + 0x0100, 0x00dc }, |
216 | { USBTV_BASE + 0x010e, 0x0072 }, |
217 | { USBTV_BASE + 0x010f, 0x00a2 }, |
218 | { USBTV_BASE + 0x0112, 0x0090 }, |
219 | { USBTV_BASE + 0x0115, 0x0035 }, |
220 | { USBTV_BASE + 0x0117, 0x0001 }, |
221 | { USBTV_BASE + 0x0118, 0x0030 }, |
222 | { USBTV_BASE + 0x012d, 0x0004 }, |
223 | { USBTV_BASE + 0x012f, 0x0008 }, |
224 | { USBTV_BASE + 0x0220, 0x002d }, |
225 | { USBTV_BASE + 0x0225, 0x0028 }, |
226 | { USBTV_BASE + 0x024e, 0x0008 }, |
227 | { USBTV_BASE + 0x024f, 0x0002 }, |
228 | { USBTV_BASE + 0x0254, 0x0069 }, |
229 | { USBTV_BASE + 0x025a, 0x0016 }, |
230 | { USBTV_BASE + 0x025b, 0x0035 }, |
231 | { USBTV_BASE + 0x0263, 0x0021 }, |
232 | { USBTV_BASE + 0x0266, 0x0016 }, |
233 | { USBTV_BASE + 0x0267, 0x0036 }, |
234 | /* End image tuning */ |
235 | { USBTV_BASE + 0x024e, 0x0002 }, |
236 | { USBTV_BASE + 0x024f, 0x0002 }, |
237 | }; |
238 | |
239 | ret = usbtv_configure_for_norm(usbtv, norm); |
240 | |
241 | if (!ret) { |
242 | /* Masks for norms using a NTSC or PAL color encoding. */ |
243 | static const v4l2_std_id ntsc_mask = |
244 | V4L2_STD_NTSC | V4L2_STD_NTSC_443; |
245 | static const v4l2_std_id pal_mask = |
246 | V4L2_STD_PAL | V4L2_STD_PAL_60 | V4L2_STD_PAL_M | |
247 | V4L2_STD_PAL_Nc; |
248 | |
249 | if (norm & ntsc_mask) |
250 | ret = usbtv_set_regs(usbtv, regs: ntsc, ARRAY_SIZE(ntsc)); |
251 | else if (norm & pal_mask) |
252 | ret = usbtv_set_regs(usbtv, regs: pal, ARRAY_SIZE(pal)); |
253 | else if (norm & V4L2_STD_SECAM) |
254 | ret = usbtv_set_regs(usbtv, regs: secam, ARRAY_SIZE(secam)); |
255 | else |
256 | ret = -EINVAL; |
257 | } |
258 | |
259 | if (!ret) { |
260 | /* Configure the decoder for the color standard */ |
261 | const u16 cfg[][2] = { |
262 | { USBTV_BASE + 0x016f, usbtv_norm_to_16f_reg(norm) } |
263 | }; |
264 | ret = usbtv_set_regs(usbtv, regs: cfg, ARRAY_SIZE(cfg)); |
265 | } |
266 | |
267 | return ret; |
268 | } |
269 | |
270 | static int usbtv_setup_capture(struct usbtv *usbtv) |
271 | { |
272 | int ret; |
273 | static const u16 setup[][2] = { |
274 | /* These seem to enable the device. */ |
275 | { USBTV_BASE + 0x0008, 0x0001 }, |
276 | { USBTV_BASE + 0x01d0, 0x00ff }, |
277 | { USBTV_BASE + 0x01d9, 0x0002 }, |
278 | |
279 | /* These seem to influence color parameters, such as |
280 | * brightness, etc. */ |
281 | { USBTV_BASE + 0x0239, 0x0040 }, |
282 | { USBTV_BASE + 0x0240, 0x0000 }, |
283 | { USBTV_BASE + 0x0241, 0x0000 }, |
284 | { USBTV_BASE + 0x0242, 0x0002 }, |
285 | { USBTV_BASE + 0x0243, 0x0080 }, |
286 | { USBTV_BASE + 0x0244, 0x0012 }, |
287 | { USBTV_BASE + 0x0245, 0x0090 }, |
288 | { USBTV_BASE + 0x0246, 0x0000 }, |
289 | |
290 | { USBTV_BASE + 0x0278, 0x002d }, |
291 | { USBTV_BASE + 0x0279, 0x000a }, |
292 | { USBTV_BASE + 0x027a, 0x0032 }, |
293 | { 0xf890, 0x000c }, |
294 | { 0xf894, 0x0086 }, |
295 | |
296 | { USBTV_BASE + 0x00ac, 0x00c0 }, |
297 | { USBTV_BASE + 0x00ad, 0x0000 }, |
298 | { USBTV_BASE + 0x00a2, 0x0012 }, |
299 | { USBTV_BASE + 0x00a3, 0x00e0 }, |
300 | { USBTV_BASE + 0x00a4, 0x0028 }, |
301 | { USBTV_BASE + 0x00a5, 0x0082 }, |
302 | { USBTV_BASE + 0x00a7, 0x0080 }, |
303 | { USBTV_BASE + 0x0000, 0x0014 }, |
304 | { USBTV_BASE + 0x0006, 0x0003 }, |
305 | { USBTV_BASE + 0x0090, 0x0099 }, |
306 | { USBTV_BASE + 0x0091, 0x0090 }, |
307 | { USBTV_BASE + 0x0094, 0x0068 }, |
308 | { USBTV_BASE + 0x0095, 0x0070 }, |
309 | { USBTV_BASE + 0x009c, 0x0030 }, |
310 | { USBTV_BASE + 0x009d, 0x00c0 }, |
311 | { USBTV_BASE + 0x009e, 0x00e0 }, |
312 | { USBTV_BASE + 0x0019, 0x0006 }, |
313 | { USBTV_BASE + 0x008c, 0x00ba }, |
314 | { USBTV_BASE + 0x0101, 0x00ff }, |
315 | { USBTV_BASE + 0x010c, 0x00b3 }, |
316 | { USBTV_BASE + 0x01b2, 0x0080 }, |
317 | { USBTV_BASE + 0x01b4, 0x00a0 }, |
318 | { USBTV_BASE + 0x014c, 0x00ff }, |
319 | { USBTV_BASE + 0x014d, 0x00ca }, |
320 | { USBTV_BASE + 0x0113, 0x0053 }, |
321 | { USBTV_BASE + 0x0119, 0x008a }, |
322 | { USBTV_BASE + 0x013c, 0x0003 }, |
323 | { USBTV_BASE + 0x0150, 0x009c }, |
324 | { USBTV_BASE + 0x0151, 0x0071 }, |
325 | { USBTV_BASE + 0x0152, 0x00c6 }, |
326 | { USBTV_BASE + 0x0153, 0x0084 }, |
327 | { USBTV_BASE + 0x0154, 0x00bc }, |
328 | { USBTV_BASE + 0x0155, 0x00a0 }, |
329 | { USBTV_BASE + 0x0156, 0x00a0 }, |
330 | { USBTV_BASE + 0x0157, 0x009c }, |
331 | { USBTV_BASE + 0x0158, 0x001f }, |
332 | { USBTV_BASE + 0x0159, 0x0006 }, |
333 | { USBTV_BASE + 0x015d, 0x0000 }, |
334 | }; |
335 | |
336 | ret = usbtv_set_regs(usbtv, regs: setup, ARRAY_SIZE(setup)); |
337 | if (ret) |
338 | return ret; |
339 | |
340 | ret = usbtv_select_norm(usbtv, norm: usbtv->norm); |
341 | if (ret) |
342 | return ret; |
343 | |
344 | ret = usbtv_select_input(usbtv, input: usbtv->input); |
345 | if (ret) |
346 | return ret; |
347 | |
348 | ret = v4l2_ctrl_handler_setup(hdl: &usbtv->ctrl); |
349 | if (ret) |
350 | return ret; |
351 | |
352 | return 0; |
353 | } |
354 | |
355 | /* Copy data from chunk into a frame buffer, deinterlacing the data |
356 | * into every second line. Unfortunately, they don't align nicely into |
357 | * 720 pixel lines, as the chunk is 240 words long, which is 480 pixels. |
358 | * Therefore, we break down the chunk into two halves before copying, |
359 | * so that we can interleave a line if needed. |
360 | * |
361 | * Each "chunk" is 240 words; a word in this context equals 4 bytes. |
362 | * Image format is YUYV/YUV 4:2:2, consisting of Y Cr Y Cb, defining two |
363 | * pixels, the Cr and Cb shared between the two pixels, but each having |
364 | * separate Y values. Thus, the 240 words equal 480 pixels. It therefore, |
365 | * takes 1.5 chunks to make a 720 pixel-wide line for the frame. |
366 | * The image is interlaced, so there is a "scan" of odd lines, followed |
367 | * by "scan" of even numbered lines. |
368 | * |
369 | * Following code is writing the chunks in correct sequence, skipping |
370 | * the rows based on "odd" value. |
371 | * line 1: chunk[0][ 0..479] chunk[0][480..959] chunk[1][ 0..479] |
372 | * line 3: chunk[1][480..959] chunk[2][ 0..479] chunk[2][480..959] |
373 | * ...etc. |
374 | */ |
375 | static void usbtv_chunk_to_vbuf(u32 *frame, __be32 *src, int chunk_no, int odd) |
376 | { |
377 | int half; |
378 | |
379 | for (half = 0; half < 2; half++) { |
380 | int part_no = chunk_no * 2 + half; |
381 | int line = part_no / 3; |
382 | int part_index = (line * 2 + !odd) * 3 + (part_no % 3); |
383 | |
384 | u32 *dst = &frame[part_index * USBTV_CHUNK/2]; |
385 | |
386 | memcpy(dst, src, USBTV_CHUNK/2 * sizeof(*src)); |
387 | src += USBTV_CHUNK/2; |
388 | } |
389 | } |
390 | |
391 | /* Called for each 256-byte image chunk. |
392 | * First word identifies the chunk, followed by 240 words of image |
393 | * data and padding. */ |
394 | static void usbtv_image_chunk(struct usbtv *usbtv, __be32 *chunk) |
395 | { |
396 | int frame_id, odd, chunk_no; |
397 | u32 *frame; |
398 | struct usbtv_buf *buf; |
399 | unsigned long flags; |
400 | |
401 | /* Ignore corrupted lines. */ |
402 | if (!USBTV_MAGIC_OK(chunk)) |
403 | return; |
404 | frame_id = USBTV_FRAME_ID(chunk); |
405 | odd = USBTV_ODD(chunk); |
406 | chunk_no = USBTV_CHUNK_NO(chunk); |
407 | if (chunk_no >= usbtv->n_chunks) |
408 | return; |
409 | |
410 | /* Beginning of a frame. */ |
411 | if (chunk_no == 0) { |
412 | usbtv->frame_id = frame_id; |
413 | usbtv->chunks_done = 0; |
414 | } |
415 | |
416 | if (usbtv->frame_id != frame_id) |
417 | return; |
418 | |
419 | spin_lock_irqsave(&usbtv->buflock, flags); |
420 | if (list_empty(head: &usbtv->bufs)) { |
421 | /* No free buffers. Userspace likely too slow. */ |
422 | spin_unlock_irqrestore(lock: &usbtv->buflock, flags); |
423 | return; |
424 | } |
425 | |
426 | /* First available buffer. */ |
427 | buf = list_first_entry(&usbtv->bufs, struct usbtv_buf, list); |
428 | frame = vb2_plane_vaddr(vb: &buf->vb.vb2_buf, plane_no: 0); |
429 | |
430 | /* Copy the chunk data. */ |
431 | usbtv_chunk_to_vbuf(frame, src: &chunk[1], chunk_no, odd); |
432 | usbtv->chunks_done++; |
433 | |
434 | /* Last chunk in a field */ |
435 | if (chunk_no == usbtv->n_chunks-1) { |
436 | /* Last chunk in a frame, signalling an end */ |
437 | if (odd && !usbtv->last_odd) { |
438 | int size = vb2_plane_size(vb: &buf->vb.vb2_buf, plane_no: 0); |
439 | enum vb2_buffer_state state = usbtv->chunks_done == |
440 | usbtv->n_chunks ? |
441 | VB2_BUF_STATE_DONE : |
442 | VB2_BUF_STATE_ERROR; |
443 | |
444 | buf->vb.field = V4L2_FIELD_INTERLACED; |
445 | buf->vb.sequence = usbtv->sequence++; |
446 | buf->vb.vb2_buf.timestamp = ktime_get_ns(); |
447 | vb2_set_plane_payload(vb: &buf->vb.vb2_buf, plane_no: 0, size); |
448 | vb2_buffer_done(vb: &buf->vb.vb2_buf, state); |
449 | list_del(entry: &buf->list); |
450 | } |
451 | usbtv->last_odd = odd; |
452 | } |
453 | |
454 | spin_unlock_irqrestore(lock: &usbtv->buflock, flags); |
455 | } |
456 | |
457 | /* Got image data. Each packet contains a number of 256-word chunks we |
458 | * compose the image from. */ |
459 | static void usbtv_iso_cb(struct urb *ip) |
460 | { |
461 | int ret; |
462 | int i; |
463 | struct usbtv *usbtv = (struct usbtv *)ip->context; |
464 | |
465 | switch (ip->status) { |
466 | /* All fine. */ |
467 | case 0: |
468 | break; |
469 | /* Device disconnected or capture stopped? */ |
470 | case -ENODEV: |
471 | case -ENOENT: |
472 | case -ECONNRESET: |
473 | case -ESHUTDOWN: |
474 | return; |
475 | /* Unknown error. Retry. */ |
476 | default: |
477 | dev_warn(usbtv->dev, "Bad response for ISO request.\n" ); |
478 | goto resubmit; |
479 | } |
480 | |
481 | for (i = 0; i < ip->number_of_packets; i++) { |
482 | int size = ip->iso_frame_desc[i].actual_length; |
483 | unsigned char *data = ip->transfer_buffer + |
484 | ip->iso_frame_desc[i].offset; |
485 | int offset; |
486 | |
487 | for (offset = 0; USBTV_CHUNK_SIZE * offset < size; offset++) |
488 | usbtv_image_chunk(usbtv, |
489 | chunk: (__be32 *)&data[USBTV_CHUNK_SIZE * offset]); |
490 | } |
491 | |
492 | resubmit: |
493 | ret = usb_submit_urb(urb: ip, GFP_ATOMIC); |
494 | if (ret < 0) |
495 | dev_warn(usbtv->dev, "Could not resubmit ISO URB\n" ); |
496 | } |
497 | |
498 | static struct urb *usbtv_setup_iso_transfer(struct usbtv *usbtv) |
499 | { |
500 | struct urb *ip; |
501 | int size = usbtv->iso_size; |
502 | int i; |
503 | |
504 | ip = usb_alloc_urb(USBTV_ISOC_PACKETS, GFP_KERNEL); |
505 | if (ip == NULL) |
506 | return NULL; |
507 | |
508 | ip->dev = usbtv->udev; |
509 | ip->context = usbtv; |
510 | ip->pipe = usb_rcvisocpipe(usbtv->udev, USBTV_VIDEO_ENDP); |
511 | ip->interval = 1; |
512 | ip->transfer_flags = URB_ISO_ASAP; |
513 | ip->transfer_buffer = kcalloc(USBTV_ISOC_PACKETS, size, |
514 | GFP_KERNEL); |
515 | if (!ip->transfer_buffer) { |
516 | usb_free_urb(urb: ip); |
517 | return NULL; |
518 | } |
519 | ip->complete = usbtv_iso_cb; |
520 | ip->number_of_packets = USBTV_ISOC_PACKETS; |
521 | ip->transfer_buffer_length = size * USBTV_ISOC_PACKETS; |
522 | for (i = 0; i < USBTV_ISOC_PACKETS; i++) { |
523 | ip->iso_frame_desc[i].offset = size * i; |
524 | ip->iso_frame_desc[i].length = size; |
525 | } |
526 | |
527 | return ip; |
528 | } |
529 | |
530 | static void usbtv_stop(struct usbtv *usbtv) |
531 | { |
532 | int i; |
533 | unsigned long flags; |
534 | |
535 | /* Cancel running transfers. */ |
536 | for (i = 0; i < USBTV_ISOC_TRANSFERS; i++) { |
537 | struct urb *ip = usbtv->isoc_urbs[i]; |
538 | |
539 | if (ip == NULL) |
540 | continue; |
541 | usb_kill_urb(urb: ip); |
542 | kfree(objp: ip->transfer_buffer); |
543 | usb_free_urb(urb: ip); |
544 | usbtv->isoc_urbs[i] = NULL; |
545 | } |
546 | |
547 | /* Return buffers to userspace. */ |
548 | spin_lock_irqsave(&usbtv->buflock, flags); |
549 | while (!list_empty(head: &usbtv->bufs)) { |
550 | struct usbtv_buf *buf = list_first_entry(&usbtv->bufs, |
551 | struct usbtv_buf, list); |
552 | vb2_buffer_done(vb: &buf->vb.vb2_buf, state: VB2_BUF_STATE_ERROR); |
553 | list_del(entry: &buf->list); |
554 | } |
555 | spin_unlock_irqrestore(lock: &usbtv->buflock, flags); |
556 | } |
557 | |
558 | static int usbtv_start(struct usbtv *usbtv) |
559 | { |
560 | int i; |
561 | int ret; |
562 | |
563 | usbtv_audio_suspend(usbtv); |
564 | |
565 | ret = usb_set_interface(dev: usbtv->udev, ifnum: 0, alternate: 0); |
566 | if (ret < 0) |
567 | return ret; |
568 | |
569 | ret = usbtv_setup_capture(usbtv); |
570 | if (ret < 0) |
571 | return ret; |
572 | |
573 | ret = usb_set_interface(dev: usbtv->udev, ifnum: 0, alternate: 1); |
574 | if (ret < 0) |
575 | return ret; |
576 | |
577 | usbtv_audio_resume(usbtv); |
578 | |
579 | for (i = 0; i < USBTV_ISOC_TRANSFERS; i++) { |
580 | struct urb *ip; |
581 | |
582 | ip = usbtv_setup_iso_transfer(usbtv); |
583 | if (ip == NULL) { |
584 | ret = -ENOMEM; |
585 | goto start_fail; |
586 | } |
587 | usbtv->isoc_urbs[i] = ip; |
588 | |
589 | ret = usb_submit_urb(urb: ip, GFP_KERNEL); |
590 | if (ret < 0) |
591 | goto start_fail; |
592 | } |
593 | |
594 | return 0; |
595 | |
596 | start_fail: |
597 | usbtv_stop(usbtv); |
598 | return ret; |
599 | } |
600 | |
601 | static int usbtv_querycap(struct file *file, void *priv, |
602 | struct v4l2_capability *cap) |
603 | { |
604 | struct usbtv *dev = video_drvdata(file); |
605 | |
606 | strscpy(cap->driver, "usbtv" , sizeof(cap->driver)); |
607 | strscpy(cap->card, "usbtv" , sizeof(cap->card)); |
608 | usb_make_path(dev: dev->udev, buf: cap->bus_info, size: sizeof(cap->bus_info)); |
609 | return 0; |
610 | } |
611 | |
612 | static int usbtv_enum_input(struct file *file, void *priv, |
613 | struct v4l2_input *i) |
614 | { |
615 | struct usbtv *dev = video_drvdata(file); |
616 | |
617 | switch (i->index) { |
618 | case USBTV_COMPOSITE_INPUT: |
619 | strscpy(i->name, "Composite" , sizeof(i->name)); |
620 | break; |
621 | case USBTV_SVIDEO_INPUT: |
622 | strscpy(i->name, "S-Video" , sizeof(i->name)); |
623 | break; |
624 | default: |
625 | return -EINVAL; |
626 | } |
627 | |
628 | i->type = V4L2_INPUT_TYPE_CAMERA; |
629 | i->std = dev->vdev.tvnorms; |
630 | return 0; |
631 | } |
632 | |
633 | static int usbtv_enum_fmt_vid_cap(struct file *file, void *priv, |
634 | struct v4l2_fmtdesc *f) |
635 | { |
636 | if (f->index > 0) |
637 | return -EINVAL; |
638 | |
639 | f->pixelformat = V4L2_PIX_FMT_YUYV; |
640 | return 0; |
641 | } |
642 | |
643 | static int usbtv_fmt_vid_cap(struct file *file, void *priv, |
644 | struct v4l2_format *f) |
645 | { |
646 | struct usbtv *usbtv = video_drvdata(file); |
647 | |
648 | f->fmt.pix.width = usbtv->width; |
649 | f->fmt.pix.height = usbtv->height; |
650 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; |
651 | f->fmt.pix.field = V4L2_FIELD_INTERLACED; |
652 | f->fmt.pix.bytesperline = usbtv->width * 2; |
653 | f->fmt.pix.sizeimage = (f->fmt.pix.bytesperline * f->fmt.pix.height); |
654 | f->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M; |
655 | |
656 | return 0; |
657 | } |
658 | |
659 | static int usbtv_g_std(struct file *file, void *priv, v4l2_std_id *norm) |
660 | { |
661 | struct usbtv *usbtv = video_drvdata(file); |
662 | *norm = usbtv->norm; |
663 | return 0; |
664 | } |
665 | |
666 | static int usbtv_s_std(struct file *file, void *priv, v4l2_std_id norm) |
667 | { |
668 | int ret = -EINVAL; |
669 | struct usbtv *usbtv = video_drvdata(file); |
670 | |
671 | if (norm & USBTV_TV_STD) |
672 | ret = usbtv_select_norm(usbtv, norm); |
673 | |
674 | return ret; |
675 | } |
676 | |
677 | static int usbtv_g_input(struct file *file, void *priv, unsigned int *i) |
678 | { |
679 | struct usbtv *usbtv = video_drvdata(file); |
680 | *i = usbtv->input; |
681 | return 0; |
682 | } |
683 | |
684 | static int usbtv_s_input(struct file *file, void *priv, unsigned int i) |
685 | { |
686 | struct usbtv *usbtv = video_drvdata(file); |
687 | |
688 | return usbtv_select_input(usbtv, input: i); |
689 | } |
690 | |
691 | static const struct v4l2_ioctl_ops usbtv_ioctl_ops = { |
692 | .vidioc_querycap = usbtv_querycap, |
693 | .vidioc_enum_input = usbtv_enum_input, |
694 | .vidioc_enum_fmt_vid_cap = usbtv_enum_fmt_vid_cap, |
695 | .vidioc_g_fmt_vid_cap = usbtv_fmt_vid_cap, |
696 | .vidioc_try_fmt_vid_cap = usbtv_fmt_vid_cap, |
697 | .vidioc_s_fmt_vid_cap = usbtv_fmt_vid_cap, |
698 | .vidioc_g_std = usbtv_g_std, |
699 | .vidioc_s_std = usbtv_s_std, |
700 | .vidioc_g_input = usbtv_g_input, |
701 | .vidioc_s_input = usbtv_s_input, |
702 | |
703 | .vidioc_reqbufs = vb2_ioctl_reqbufs, |
704 | .vidioc_prepare_buf = vb2_ioctl_prepare_buf, |
705 | .vidioc_querybuf = vb2_ioctl_querybuf, |
706 | .vidioc_create_bufs = vb2_ioctl_create_bufs, |
707 | .vidioc_qbuf = vb2_ioctl_qbuf, |
708 | .vidioc_dqbuf = vb2_ioctl_dqbuf, |
709 | .vidioc_streamon = vb2_ioctl_streamon, |
710 | .vidioc_streamoff = vb2_ioctl_streamoff, |
711 | }; |
712 | |
713 | static const struct v4l2_file_operations usbtv_fops = { |
714 | .owner = THIS_MODULE, |
715 | .unlocked_ioctl = video_ioctl2, |
716 | .mmap = vb2_fop_mmap, |
717 | .open = v4l2_fh_open, |
718 | .release = vb2_fop_release, |
719 | .read = vb2_fop_read, |
720 | .poll = vb2_fop_poll, |
721 | }; |
722 | |
723 | static int usbtv_queue_setup(struct vb2_queue *vq, |
724 | unsigned int *nbuffers, |
725 | unsigned int *nplanes, unsigned int sizes[], struct device *alloc_devs[]) |
726 | { |
727 | struct usbtv *usbtv = vb2_get_drv_priv(q: vq); |
728 | unsigned size = USBTV_CHUNK * usbtv->n_chunks * 2 * sizeof(u32); |
729 | unsigned int q_num_bufs = vb2_get_num_buffers(q: vq); |
730 | |
731 | if (q_num_bufs + *nbuffers < 2) |
732 | *nbuffers = 2 - q_num_bufs; |
733 | if (*nplanes) |
734 | return sizes[0] < size ? -EINVAL : 0; |
735 | *nplanes = 1; |
736 | sizes[0] = size; |
737 | |
738 | return 0; |
739 | } |
740 | |
741 | static void usbtv_buf_queue(struct vb2_buffer *vb) |
742 | { |
743 | struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb); |
744 | struct usbtv *usbtv = vb2_get_drv_priv(q: vb->vb2_queue); |
745 | struct usbtv_buf *buf = container_of(vbuf, struct usbtv_buf, vb); |
746 | unsigned long flags; |
747 | |
748 | if (usbtv->udev == NULL) { |
749 | vb2_buffer_done(vb, state: VB2_BUF_STATE_ERROR); |
750 | return; |
751 | } |
752 | |
753 | spin_lock_irqsave(&usbtv->buflock, flags); |
754 | list_add_tail(new: &buf->list, head: &usbtv->bufs); |
755 | spin_unlock_irqrestore(lock: &usbtv->buflock, flags); |
756 | } |
757 | |
758 | static int usbtv_start_streaming(struct vb2_queue *vq, unsigned int count) |
759 | { |
760 | struct usbtv *usbtv = vb2_get_drv_priv(q: vq); |
761 | |
762 | if (usbtv->udev == NULL) |
763 | return -ENODEV; |
764 | |
765 | usbtv->last_odd = 1; |
766 | usbtv->sequence = 0; |
767 | return usbtv_start(usbtv); |
768 | } |
769 | |
770 | static void usbtv_stop_streaming(struct vb2_queue *vq) |
771 | { |
772 | struct usbtv *usbtv = vb2_get_drv_priv(q: vq); |
773 | |
774 | if (usbtv->udev) |
775 | usbtv_stop(usbtv); |
776 | } |
777 | |
778 | static const struct vb2_ops usbtv_vb2_ops = { |
779 | .queue_setup = usbtv_queue_setup, |
780 | .buf_queue = usbtv_buf_queue, |
781 | .start_streaming = usbtv_start_streaming, |
782 | .stop_streaming = usbtv_stop_streaming, |
783 | .wait_prepare = vb2_ops_wait_prepare, |
784 | .wait_finish = vb2_ops_wait_finish, |
785 | }; |
786 | |
787 | static int usbtv_s_ctrl(struct v4l2_ctrl *ctrl) |
788 | { |
789 | struct usbtv *usbtv = container_of(ctrl->handler, struct usbtv, |
790 | ctrl); |
791 | u8 *data; |
792 | u16 index, size; |
793 | int ret; |
794 | |
795 | data = kmalloc(size: 3, GFP_KERNEL); |
796 | if (!data) |
797 | return -ENOMEM; |
798 | |
799 | /* |
800 | * Read in the current brightness/contrast registers. We need them |
801 | * both, because the values are for some reason interleaved. |
802 | */ |
803 | if (ctrl->id == V4L2_CID_BRIGHTNESS || ctrl->id == V4L2_CID_CONTRAST) { |
804 | ret = usb_control_msg(dev: usbtv->udev, |
805 | usb_rcvctrlpipe(usbtv->udev, 0), USBTV_CONTROL_REG, |
806 | USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
807 | value: 0, USBTV_BASE + 0x0244, data: (void *)data, size: 3, |
808 | USB_CTRL_GET_TIMEOUT); |
809 | if (ret < 0) |
810 | goto error; |
811 | } |
812 | |
813 | switch (ctrl->id) { |
814 | case V4L2_CID_BRIGHTNESS: |
815 | index = USBTV_BASE + 0x0244; |
816 | size = 3; |
817 | data[0] &= 0xf0; |
818 | data[0] |= (ctrl->val >> 8) & 0xf; |
819 | data[2] = ctrl->val & 0xff; |
820 | break; |
821 | case V4L2_CID_CONTRAST: |
822 | index = USBTV_BASE + 0x0244; |
823 | size = 3; |
824 | data[0] &= 0x0f; |
825 | data[0] |= (ctrl->val >> 4) & 0xf0; |
826 | data[1] = ctrl->val & 0xff; |
827 | break; |
828 | case V4L2_CID_SATURATION: |
829 | index = USBTV_BASE + 0x0242; |
830 | data[0] = ctrl->val >> 8; |
831 | data[1] = ctrl->val & 0xff; |
832 | size = 2; |
833 | break; |
834 | case V4L2_CID_HUE: |
835 | index = USBTV_BASE + 0x0240; |
836 | size = 2; |
837 | if (ctrl->val > 0) { |
838 | data[0] = 0x92 + (ctrl->val >> 8); |
839 | data[1] = ctrl->val & 0xff; |
840 | } else { |
841 | data[0] = 0x82 + (-ctrl->val >> 8); |
842 | data[1] = -ctrl->val & 0xff; |
843 | } |
844 | break; |
845 | case V4L2_CID_SHARPNESS: |
846 | index = USBTV_BASE + 0x0239; |
847 | data[0] = 0; |
848 | data[1] = ctrl->val; |
849 | size = 2; |
850 | break; |
851 | default: |
852 | kfree(objp: data); |
853 | return -EINVAL; |
854 | } |
855 | |
856 | ret = usb_control_msg(dev: usbtv->udev, usb_sndctrlpipe(usbtv->udev, 0), |
857 | USBTV_CONTROL_REG, |
858 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
859 | value: 0, index, data: (void *)data, size, USB_CTRL_SET_TIMEOUT); |
860 | |
861 | error: |
862 | if (ret < 0) |
863 | dev_warn(usbtv->dev, "Failed to submit a control request.\n" ); |
864 | |
865 | kfree(objp: data); |
866 | return ret; |
867 | } |
868 | |
869 | static const struct v4l2_ctrl_ops usbtv_ctrl_ops = { |
870 | .s_ctrl = usbtv_s_ctrl, |
871 | }; |
872 | |
873 | static void usbtv_release(struct v4l2_device *v4l2_dev) |
874 | { |
875 | struct usbtv *usbtv = container_of(v4l2_dev, struct usbtv, v4l2_dev); |
876 | |
877 | v4l2_device_unregister(v4l2_dev: &usbtv->v4l2_dev); |
878 | v4l2_ctrl_handler_free(hdl: &usbtv->ctrl); |
879 | kfree(objp: usbtv); |
880 | } |
881 | |
882 | int usbtv_video_init(struct usbtv *usbtv) |
883 | { |
884 | int ret; |
885 | |
886 | (void)usbtv_configure_for_norm(usbtv, V4L2_STD_525_60); |
887 | |
888 | spin_lock_init(&usbtv->buflock); |
889 | mutex_init(&usbtv->v4l2_lock); |
890 | mutex_init(&usbtv->vb2q_lock); |
891 | INIT_LIST_HEAD(list: &usbtv->bufs); |
892 | |
893 | /* videobuf2 structure */ |
894 | usbtv->vb2q.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
895 | usbtv->vb2q.io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ; |
896 | usbtv->vb2q.drv_priv = usbtv; |
897 | usbtv->vb2q.buf_struct_size = sizeof(struct usbtv_buf); |
898 | usbtv->vb2q.ops = &usbtv_vb2_ops; |
899 | usbtv->vb2q.mem_ops = &vb2_vmalloc_memops; |
900 | usbtv->vb2q.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC; |
901 | usbtv->vb2q.lock = &usbtv->vb2q_lock; |
902 | ret = vb2_queue_init(q: &usbtv->vb2q); |
903 | if (ret < 0) { |
904 | dev_warn(usbtv->dev, "Could not initialize videobuf2 queue\n" ); |
905 | return ret; |
906 | } |
907 | |
908 | /* controls */ |
909 | v4l2_ctrl_handler_init(&usbtv->ctrl, 4); |
910 | v4l2_ctrl_new_std(hdl: &usbtv->ctrl, ops: &usbtv_ctrl_ops, |
911 | V4L2_CID_CONTRAST, min: 0, max: 0x3ff, step: 1, def: 0x1d0); |
912 | v4l2_ctrl_new_std(hdl: &usbtv->ctrl, ops: &usbtv_ctrl_ops, |
913 | V4L2_CID_BRIGHTNESS, min: 0, max: 0x3ff, step: 1, def: 0x1c0); |
914 | v4l2_ctrl_new_std(hdl: &usbtv->ctrl, ops: &usbtv_ctrl_ops, |
915 | V4L2_CID_SATURATION, min: 0, max: 0x3ff, step: 1, def: 0x200); |
916 | v4l2_ctrl_new_std(hdl: &usbtv->ctrl, ops: &usbtv_ctrl_ops, |
917 | V4L2_CID_HUE, min: -0xdff, max: 0xdff, step: 1, def: 0x000); |
918 | v4l2_ctrl_new_std(hdl: &usbtv->ctrl, ops: &usbtv_ctrl_ops, |
919 | V4L2_CID_SHARPNESS, min: 0x0, max: 0xff, step: 1, def: 0x60); |
920 | ret = usbtv->ctrl.error; |
921 | if (ret < 0) { |
922 | dev_warn(usbtv->dev, "Could not initialize controls\n" ); |
923 | goto ctrl_fail; |
924 | } |
925 | |
926 | /* v4l2 structure */ |
927 | usbtv->v4l2_dev.ctrl_handler = &usbtv->ctrl; |
928 | usbtv->v4l2_dev.release = usbtv_release; |
929 | ret = v4l2_device_register(dev: usbtv->dev, v4l2_dev: &usbtv->v4l2_dev); |
930 | if (ret < 0) { |
931 | dev_warn(usbtv->dev, "Could not register v4l2 device\n" ); |
932 | goto v4l2_fail; |
933 | } |
934 | |
935 | /* Video structure */ |
936 | strscpy(usbtv->vdev.name, "usbtv" , sizeof(usbtv->vdev.name)); |
937 | usbtv->vdev.v4l2_dev = &usbtv->v4l2_dev; |
938 | usbtv->vdev.release = video_device_release_empty; |
939 | usbtv->vdev.fops = &usbtv_fops; |
940 | usbtv->vdev.ioctl_ops = &usbtv_ioctl_ops; |
941 | usbtv->vdev.tvnorms = USBTV_TV_STD; |
942 | usbtv->vdev.queue = &usbtv->vb2q; |
943 | usbtv->vdev.lock = &usbtv->v4l2_lock; |
944 | usbtv->vdev.device_caps = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | |
945 | V4L2_CAP_STREAMING; |
946 | video_set_drvdata(vdev: &usbtv->vdev, data: usbtv); |
947 | ret = video_register_device(vdev: &usbtv->vdev, type: VFL_TYPE_VIDEO, nr: -1); |
948 | if (ret < 0) { |
949 | dev_warn(usbtv->dev, "Could not register video device\n" ); |
950 | goto vdev_fail; |
951 | } |
952 | |
953 | return 0; |
954 | |
955 | vdev_fail: |
956 | v4l2_device_unregister(v4l2_dev: &usbtv->v4l2_dev); |
957 | v4l2_fail: |
958 | ctrl_fail: |
959 | v4l2_ctrl_handler_free(hdl: &usbtv->ctrl); |
960 | |
961 | return ret; |
962 | } |
963 | |
964 | void usbtv_video_free(struct usbtv *usbtv) |
965 | { |
966 | vb2_video_unregister_device(vdev: &usbtv->vdev); |
967 | v4l2_device_disconnect(v4l2_dev: &usbtv->v4l2_dev); |
968 | |
969 | v4l2_device_put(v4l2_dev: &usbtv->v4l2_dev); |
970 | } |
971 | |