1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
2 | /* |
3 | * TI OMAP4 ISS V4L2 Driver - Generic video node |
4 | * |
5 | * Copyright (C) 2012 Texas Instruments, Inc. |
6 | * |
7 | * Author: Sergio Aguirre <sergio.a.aguirre@gmail.com> |
8 | */ |
9 | |
10 | #ifndef OMAP4_ISS_VIDEO_H |
11 | #define OMAP4_ISS_VIDEO_H |
12 | |
13 | #include <linux/v4l2-mediabus.h> |
14 | #include <media/media-entity.h> |
15 | #include <media/v4l2-dev.h> |
16 | #include <media/v4l2-fh.h> |
17 | #include <media/videobuf2-v4l2.h> |
18 | #include <media/videobuf2-dma-contig.h> |
19 | |
20 | #define ISS_VIDEO_DRIVER_NAME "issvideo" |
21 | |
22 | struct iss_device; |
23 | struct iss_video; |
24 | struct v4l2_mbus_framefmt; |
25 | struct v4l2_pix_format; |
26 | |
27 | /* |
28 | * struct iss_format_info - ISS media bus format information |
29 | * @code: V4L2 media bus format code |
30 | * @truncated: V4L2 media bus format code for the same format truncated to 10 |
31 | * bits. Identical to @code if the format is 10 bits wide or less. |
32 | * @uncompressed: V4L2 media bus format code for the corresponding uncompressed |
33 | * format. Identical to @code if the format is not DPCM compressed. |
34 | * @flavor: V4L2 media bus format code for the same pixel layout but |
35 | * shifted to be 8 bits per pixel. =0 if format is not shiftable. |
36 | * @pixelformat: V4L2 pixel format FCC identifier |
37 | * @bpp: Bits per pixel |
38 | */ |
39 | struct iss_format_info { |
40 | u32 code; |
41 | u32 truncated; |
42 | u32 uncompressed; |
43 | u32 flavor; |
44 | u32 pixelformat; |
45 | unsigned int bpp; |
46 | }; |
47 | |
48 | enum iss_pipeline_stream_state { |
49 | ISS_PIPELINE_STREAM_STOPPED = 0, |
50 | ISS_PIPELINE_STREAM_CONTINUOUS = 1, |
51 | ISS_PIPELINE_STREAM_SINGLESHOT = 2, |
52 | }; |
53 | |
54 | enum iss_pipeline_state { |
55 | /* The stream has been started on the input video node. */ |
56 | ISS_PIPELINE_STREAM_INPUT = BIT(0), |
57 | /* The stream has been started on the output video node. */ |
58 | ISS_PIPELINE_STREAM_OUTPUT = BIT(1), |
59 | /* At least one buffer is queued on the input video node. */ |
60 | ISS_PIPELINE_QUEUE_INPUT = BIT(2), |
61 | /* At least one buffer is queued on the output video node. */ |
62 | ISS_PIPELINE_QUEUE_OUTPUT = BIT(3), |
63 | /* The input entity is idle, ready to be started. */ |
64 | ISS_PIPELINE_IDLE_INPUT = BIT(4), |
65 | /* The output entity is idle, ready to be started. */ |
66 | ISS_PIPELINE_IDLE_OUTPUT = BIT(5), |
67 | /* The pipeline is currently streaming. */ |
68 | ISS_PIPELINE_STREAM = BIT(6), |
69 | }; |
70 | |
71 | /* |
72 | * struct iss_pipeline - An OMAP4 ISS hardware pipeline |
73 | * @ent_enum: Entities in the pipeline |
74 | * @error: A hardware error occurred during capture |
75 | */ |
76 | struct iss_pipeline { |
77 | struct media_pipeline pipe; |
78 | spinlock_t lock; /* Pipeline state and queue flags */ |
79 | unsigned int state; |
80 | enum iss_pipeline_stream_state stream_state; |
81 | struct iss_video *input; |
82 | struct iss_video *output; |
83 | struct media_entity_enum ent_enum; |
84 | atomic_t frame_number; |
85 | bool do_propagation; /* of frame number */ |
86 | bool error; |
87 | struct v4l2_fract max_timeperframe; |
88 | struct v4l2_subdev *external; |
89 | unsigned int external_rate; |
90 | int external_bpp; |
91 | }; |
92 | |
93 | static inline struct iss_pipeline *to_iss_pipeline(struct media_entity *entity) |
94 | { |
95 | struct media_pipeline *pipe = media_entity_pipeline(entity); |
96 | |
97 | if (!pipe) |
98 | return NULL; |
99 | |
100 | return container_of(pipe, struct iss_pipeline, pipe); |
101 | } |
102 | |
103 | static inline int iss_pipeline_ready(struct iss_pipeline *pipe) |
104 | { |
105 | return pipe->state == (ISS_PIPELINE_STREAM_INPUT | |
106 | ISS_PIPELINE_STREAM_OUTPUT | |
107 | ISS_PIPELINE_QUEUE_INPUT | |
108 | ISS_PIPELINE_QUEUE_OUTPUT | |
109 | ISS_PIPELINE_IDLE_INPUT | |
110 | ISS_PIPELINE_IDLE_OUTPUT); |
111 | } |
112 | |
113 | /* |
114 | * struct iss_buffer - ISS buffer |
115 | * @buffer: ISS video buffer |
116 | * @iss_addr: Physical address of the buffer. |
117 | */ |
118 | struct iss_buffer { |
119 | /* common v4l buffer stuff -- must be first */ |
120 | struct vb2_v4l2_buffer vb; |
121 | struct list_head list; |
122 | dma_addr_t iss_addr; |
123 | }; |
124 | |
125 | #define to_iss_buffer(buf) container_of(buf, struct iss_buffer, vb) |
126 | |
127 | enum iss_video_dmaqueue_flags { |
128 | /* Set if DMA queue becomes empty when ISS_PIPELINE_STREAM_CONTINUOUS */ |
129 | ISS_VIDEO_DMAQUEUE_UNDERRUN = BIT(0), |
130 | /* Set when queuing buffer to an empty DMA queue */ |
131 | ISS_VIDEO_DMAQUEUE_QUEUED = BIT(1), |
132 | }; |
133 | |
134 | #define iss_video_dmaqueue_flags_clr(video) \ |
135 | ({ (video)->dmaqueue_flags = 0; }) |
136 | |
137 | /* |
138 | * struct iss_video_operations - ISS video operations |
139 | * @queue: Resume streaming when a buffer is queued. Called on VIDIOC_QBUF |
140 | * if there was no buffer previously queued. |
141 | */ |
142 | struct iss_video_operations { |
143 | int (*queue)(struct iss_video *video, struct iss_buffer *buffer); |
144 | }; |
145 | |
146 | struct iss_video { |
147 | struct video_device video; |
148 | enum v4l2_buf_type type; |
149 | struct media_pad pad; |
150 | |
151 | struct mutex mutex; /* format and crop settings */ |
152 | atomic_t active; |
153 | |
154 | struct iss_device *iss; |
155 | |
156 | unsigned int capture_mem; |
157 | unsigned int bpl_alignment; /* alignment value */ |
158 | unsigned int bpl_zero_padding; /* whether the alignment is optional */ |
159 | unsigned int bpl_max; /* maximum bytes per line value */ |
160 | unsigned int bpl_value; /* bytes per line value */ |
161 | unsigned int bpl_padding; /* padding at end of line */ |
162 | |
163 | /* Pipeline state */ |
164 | struct iss_pipeline pipe; |
165 | struct mutex stream_lock; /* pipeline and stream states */ |
166 | bool error; |
167 | |
168 | /* Video buffers queue */ |
169 | struct vb2_queue *queue; |
170 | spinlock_t qlock; /* protects dmaqueue and error */ |
171 | struct list_head dmaqueue; |
172 | enum iss_video_dmaqueue_flags dmaqueue_flags; |
173 | |
174 | const struct iss_video_operations *ops; |
175 | }; |
176 | |
177 | #define to_iss_video(vdev) container_of(vdev, struct iss_video, video) |
178 | |
179 | struct iss_video_fh { |
180 | struct v4l2_fh vfh; |
181 | struct iss_video *video; |
182 | struct vb2_queue queue; |
183 | struct v4l2_format format; |
184 | struct v4l2_fract timeperframe; |
185 | }; |
186 | |
187 | #define to_iss_video_fh(fh) container_of(fh, struct iss_video_fh, vfh) |
188 | #define iss_video_queue_to_iss_video_fh(q) \ |
189 | container_of(q, struct iss_video_fh, queue) |
190 | |
191 | int omap4iss_video_init(struct iss_video *video, const char *name); |
192 | void omap4iss_video_cleanup(struct iss_video *video); |
193 | int omap4iss_video_register(struct iss_video *video, |
194 | struct v4l2_device *vdev); |
195 | void omap4iss_video_unregister(struct iss_video *video); |
196 | struct iss_buffer *omap4iss_video_buffer_next(struct iss_video *video); |
197 | void omap4iss_video_cancel_stream(struct iss_video *video); |
198 | struct media_pad *omap4iss_video_remote_pad(struct iss_video *video); |
199 | |
200 | const struct iss_format_info * |
201 | omap4iss_video_format_info(u32 code); |
202 | |
203 | #endif /* OMAP4_ISS_VIDEO_H */ |
204 | |