diff options
Diffstat (limited to 'Documentation/video4linux')
-rw-r--r-- | Documentation/video4linux/pxa_camera.txt | 125 | ||||
-rw-r--r-- | Documentation/video4linux/v4l2-framework.txt | 21 |
2 files changed, 129 insertions, 17 deletions
diff --git a/Documentation/video4linux/pxa_camera.txt b/Documentation/video4linux/pxa_camera.txt new file mode 100644 index 000000000000..b1137f9a53eb --- /dev/null +++ b/Documentation/video4linux/pxa_camera.txt | |||
@@ -0,0 +1,125 @@ | |||
1 | PXA-Camera Host Driver | ||
2 | ====================== | ||
3 | |||
4 | Constraints | ||
5 | ----------- | ||
6 | a) Image size for YUV422P format | ||
7 | All YUV422P images are enforced to have width x height % 16 = 0. | ||
8 | This is due to DMA constraints, which transfers only planes of 8 byte | ||
9 | multiples. | ||
10 | |||
11 | |||
12 | Global video workflow | ||
13 | --------------------- | ||
14 | a) QCI stopped | ||
15 | Initialy, the QCI interface is stopped. | ||
16 | When a buffer is queued (pxa_videobuf_ops->buf_queue), the QCI starts. | ||
17 | |||
18 | b) QCI started | ||
19 | More buffers can be queued while the QCI is started without halting the | ||
20 | capture. The new buffers are "appended" at the tail of the DMA chain, and | ||
21 | smoothly captured one frame after the other. | ||
22 | |||
23 | Once a buffer is filled in the QCI interface, it is marked as "DONE" and | ||
24 | removed from the active buffers list. It can be then requeud or dequeued by | ||
25 | userland application. | ||
26 | |||
27 | Once the last buffer is filled in, the QCI interface stops. | ||
28 | |||
29 | |||
30 | DMA usage | ||
31 | --------- | ||
32 | a) DMA flow | ||
33 | - first buffer queued for capture | ||
34 | Once a first buffer is queued for capture, the QCI is started, but data | ||
35 | transfer is not started. On "End Of Frame" interrupt, the irq handler | ||
36 | starts the DMA chain. | ||
37 | - capture of one videobuffer | ||
38 | The DMA chain starts transfering data into videobuffer RAM pages. | ||
39 | When all pages are transfered, the DMA irq is raised on "ENDINTR" status | ||
40 | - finishing one videobuffer | ||
41 | The DMA irq handler marks the videobuffer as "done", and removes it from | ||
42 | the active running queue | ||
43 | Meanwhile, the next videobuffer (if there is one), is transfered by DMA | ||
44 | - finishing the last videobuffer | ||
45 | On the DMA irq of the last videobuffer, the QCI is stopped. | ||
46 | |||
47 | b) DMA prepared buffer will have this structure | ||
48 | |||
49 | +------------+-----+---------------+-----------------+ | ||
50 | | desc-sg[0] | ... | desc-sg[last] | finisher/linker | | ||
51 | +------------+-----+---------------+-----------------+ | ||
52 | |||
53 | This structure is pointed by dma->sg_cpu. | ||
54 | The descriptors are used as follows : | ||
55 | - desc-sg[i]: i-th descriptor, transfering the i-th sg | ||
56 | element to the video buffer scatter gather | ||
57 | - finisher: has ddadr=DADDR_STOP, dcmd=ENDIRQEN | ||
58 | - linker: has ddadr= desc-sg[0] of next video buffer, dcmd=0 | ||
59 | |||
60 | For the next schema, let's assume d0=desc-sg[0] .. dN=desc-sg[N], | ||
61 | "f" stands for finisher and "l" for linker. | ||
62 | A typical running chain is : | ||
63 | |||
64 | Videobuffer 1 Videobuffer 2 | ||
65 | +---------+----+---+ +----+----+----+---+ | ||
66 | | d0 | .. | dN | l | | d0 | .. | dN | f | | ||
67 | +---------+----+-|-+ ^----+----+----+---+ | ||
68 | | | | ||
69 | +----+ | ||
70 | |||
71 | After the chaining is finished, the chain looks like : | ||
72 | |||
73 | Videobuffer 1 Videobuffer 2 Videobuffer 3 | ||
74 | +---------+----+---+ +----+----+----+---+ +----+----+----+---+ | ||
75 | | d0 | .. | dN | l | | d0 | .. | dN | l | | d0 | .. | dN | f | | ||
76 | +---------+----+-|-+ ^----+----+----+-|-+ ^----+----+----+---+ | ||
77 | | | | | | ||
78 | +----+ +----+ | ||
79 | new_link | ||
80 | |||
81 | c) DMA hot chaining timeslice issue | ||
82 | |||
83 | As DMA chaining is done while DMA _is_ running, the linking may be done | ||
84 | while the DMA jumps from one Videobuffer to another. On the schema, that | ||
85 | would be a problem if the following sequence is encountered : | ||
86 | |||
87 | - DMA chain is Videobuffer1 + Videobuffer2 | ||
88 | - pxa_videobuf_queue() is called to queue Videobuffer3 | ||
89 | - DMA controller finishes Videobuffer2, and DMA stops | ||
90 | => | ||
91 | Videobuffer 1 Videobuffer 2 | ||
92 | +---------+----+---+ +----+----+----+---+ | ||
93 | | d0 | .. | dN | l | | d0 | .. | dN | f | | ||
94 | +---------+----+-|-+ ^----+----+----+-^-+ | ||
95 | | | | | ||
96 | +----+ +-- DMA DDADR loads DDADR_STOP | ||
97 | |||
98 | - pxa_dma_add_tail_buf() is called, the Videobuffer2 "finisher" is | ||
99 | replaced by a "linker" to Videobuffer3 (creation of new_link) | ||
100 | - pxa_videobuf_queue() finishes | ||
101 | - the DMA irq handler is called, which terminates Videobuffer2 | ||
102 | - Videobuffer3 capture is not scheduled on DMA chain (as it stopped !!!) | ||
103 | |||
104 | Videobuffer 1 Videobuffer 2 Videobuffer 3 | ||
105 | +---------+----+---+ +----+----+----+---+ +----+----+----+---+ | ||
106 | | d0 | .. | dN | l | | d0 | .. | dN | l | | d0 | .. | dN | f | | ||
107 | +---------+----+-|-+ ^----+----+----+-|-+ ^----+----+----+---+ | ||
108 | | | | | | ||
109 | +----+ +----+ | ||
110 | new_link | ||
111 | DMA DDADR still is DDADR_STOP | ||
112 | |||
113 | - pxa_camera_check_link_miss() is called | ||
114 | This checks if the DMA is finished and a buffer is still on the | ||
115 | pcdev->capture list. If that's the case, the capture will be restarted, | ||
116 | and Videobuffer3 is scheduled on DMA chain. | ||
117 | - the DMA irq handler finishes | ||
118 | |||
119 | Note: if DMA stops just after pxa_camera_check_link_miss() reads DDADR() | ||
120 | value, we have the guarantee that the DMA irq handler will be called back | ||
121 | when the DMA will finish the buffer, and pxa_camera_check_link_miss() will | ||
122 | be called again, to reschedule Videobuffer3. | ||
123 | |||
124 | -- | ||
125 | Author: Robert Jarzmik <robert.jarzmik@free.fr> | ||
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt index a31177390e55..854808b67fae 100644 --- a/Documentation/video4linux/v4l2-framework.txt +++ b/Documentation/video4linux/v4l2-framework.txt | |||
@@ -90,7 +90,7 @@ up before calling v4l2_device_register then it will be untouched. If dev is | |||
90 | NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register. | 90 | NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register. |
91 | 91 | ||
92 | The first 'dev' argument is normally the struct device pointer of a pci_dev, | 92 | The first 'dev' argument is normally the struct device pointer of a pci_dev, |
93 | usb_device or platform_device. It is rare for dev to be NULL, but it happens | 93 | usb_interface or platform_device. It is rare for dev to be NULL, but it happens |
94 | with ISA devices or when one device creates multiple PCI devices, thus making | 94 | with ISA devices or when one device creates multiple PCI devices, thus making |
95 | it impossible to associate v4l2_dev with a particular parent. | 95 | it impossible to associate v4l2_dev with a particular parent. |
96 | 96 | ||
@@ -351,17 +351,6 @@ And this to go from an i2c_client to a v4l2_subdev struct: | |||
351 | 351 | ||
352 | struct v4l2_subdev *sd = i2c_get_clientdata(client); | 352 | struct v4l2_subdev *sd = i2c_get_clientdata(client); |
353 | 353 | ||
354 | Finally you need to make a command function to make driver->command() | ||
355 | call the right subdev_ops functions: | ||
356 | |||
357 | static int subdev_command(struct i2c_client *client, unsigned cmd, void *arg) | ||
358 | { | ||
359 | return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg); | ||
360 | } | ||
361 | |||
362 | If driver->command is never used then you can leave this out. Eventually the | ||
363 | driver->command usage should be removed from v4l. | ||
364 | |||
365 | Make sure to call v4l2_device_unregister_subdev(sd) when the remove() callback | 354 | Make sure to call v4l2_device_unregister_subdev(sd) when the remove() callback |
366 | is called. This will unregister the sub-device from the bridge driver. It is | 355 | is called. This will unregister the sub-device from the bridge driver. It is |
367 | safe to call this even if the sub-device was never registered. | 356 | safe to call this even if the sub-device was never registered. |
@@ -375,14 +364,12 @@ from the remove() callback ensures that this is always done correctly. | |||
375 | 364 | ||
376 | The bridge driver also has some helper functions it can use: | 365 | The bridge driver also has some helper functions it can use: |
377 | 366 | ||
378 | struct v4l2_subdev *sd = v4l2_i2c_new_subdev(adapter, "module_foo", "chipid", 0x36); | 367 | struct v4l2_subdev *sd = v4l2_i2c_new_subdev(v4l2_dev, adapter, |
368 | "module_foo", "chipid", 0x36); | ||
379 | 369 | ||
380 | This loads the given module (can be NULL if no module needs to be loaded) and | 370 | This loads the given module (can be NULL if no module needs to be loaded) and |
381 | calls i2c_new_device() with the given i2c_adapter and chip/address arguments. | 371 | calls i2c_new_device() with the given i2c_adapter and chip/address arguments. |
382 | If all goes well, then it registers the subdev with the v4l2_device. It gets | 372 | If all goes well, then it registers the subdev with the v4l2_device. |
383 | the v4l2_device by calling i2c_get_adapdata(adapter), so you should make sure | ||
384 | to call i2c_set_adapdata(adapter, v4l2_device) when you setup the i2c_adapter | ||
385 | in your driver. | ||
386 | 373 | ||
387 | You can also use v4l2_i2c_new_probed_subdev() which is very similar to | 374 | You can also use v4l2_i2c_new_probed_subdev() which is very similar to |
388 | v4l2_i2c_new_subdev(), except that it has an array of possible I2C addresses | 375 | v4l2_i2c_new_subdev(), except that it has an array of possible I2C addresses |