diff options
Diffstat (limited to 'drivers/media/platform/s5p-tv/mixer.h')
-rw-r--r-- | drivers/media/platform/s5p-tv/mixer.h | 365 |
1 files changed, 365 insertions, 0 deletions
diff --git a/drivers/media/platform/s5p-tv/mixer.h b/drivers/media/platform/s5p-tv/mixer.h new file mode 100644 index 000000000000..ddb422e23550 --- /dev/null +++ b/drivers/media/platform/s5p-tv/mixer.h | |||
@@ -0,0 +1,365 @@ | |||
1 | /* | ||
2 | * Samsung TV Mixer driver | ||
3 | * | ||
4 | * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd. | ||
5 | * | ||
6 | * Tomasz Stanislawski, <t.stanislaws@samsung.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published | ||
10 | * by the Free Software Foundiation. either version 2 of the License, | ||
11 | * or (at your option) any later version | ||
12 | */ | ||
13 | |||
14 | #ifndef SAMSUNG_MIXER_H | ||
15 | #define SAMSUNG_MIXER_H | ||
16 | |||
17 | #ifdef CONFIG_VIDEO_SAMSUNG_S5P_MIXER_DEBUG | ||
18 | #define DEBUG | ||
19 | #endif | ||
20 | |||
21 | #include <linux/fb.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/spinlock.h> | ||
24 | #include <linux/wait.h> | ||
25 | #include <media/v4l2-device.h> | ||
26 | #include <media/videobuf2-core.h> | ||
27 | |||
28 | #include "regs-mixer.h" | ||
29 | |||
30 | /** maximum number of output interfaces */ | ||
31 | #define MXR_MAX_OUTPUTS 2 | ||
32 | /** maximum number of input interfaces (layers) */ | ||
33 | #define MXR_MAX_LAYERS 3 | ||
34 | #define MXR_DRIVER_NAME "s5p-mixer" | ||
35 | /** maximal number of planes for every layer */ | ||
36 | #define MXR_MAX_PLANES 2 | ||
37 | |||
38 | #define MXR_ENABLE 1 | ||
39 | #define MXR_DISABLE 0 | ||
40 | |||
41 | /** description of a macroblock for packed formats */ | ||
42 | struct mxr_block { | ||
43 | /** vertical number of pixels in macroblock */ | ||
44 | unsigned int width; | ||
45 | /** horizontal number of pixels in macroblock */ | ||
46 | unsigned int height; | ||
47 | /** size of block in bytes */ | ||
48 | unsigned int size; | ||
49 | }; | ||
50 | |||
51 | /** description of supported format */ | ||
52 | struct mxr_format { | ||
53 | /** format name/mnemonic */ | ||
54 | const char *name; | ||
55 | /** fourcc identifier */ | ||
56 | u32 fourcc; | ||
57 | /** colorspace identifier */ | ||
58 | enum v4l2_colorspace colorspace; | ||
59 | /** number of planes in image data */ | ||
60 | int num_planes; | ||
61 | /** description of block for each plane */ | ||
62 | struct mxr_block plane[MXR_MAX_PLANES]; | ||
63 | /** number of subframes in image data */ | ||
64 | int num_subframes; | ||
65 | /** specifies to which subframe belong given plane */ | ||
66 | int plane2subframe[MXR_MAX_PLANES]; | ||
67 | /** internal code, driver dependant */ | ||
68 | unsigned long cookie; | ||
69 | }; | ||
70 | |||
71 | /** description of crop configuration for image */ | ||
72 | struct mxr_crop { | ||
73 | /** width of layer in pixels */ | ||
74 | unsigned int full_width; | ||
75 | /** height of layer in pixels */ | ||
76 | unsigned int full_height; | ||
77 | /** horizontal offset of first pixel to be displayed */ | ||
78 | unsigned int x_offset; | ||
79 | /** vertical offset of first pixel to be displayed */ | ||
80 | unsigned int y_offset; | ||
81 | /** width of displayed data in pixels */ | ||
82 | unsigned int width; | ||
83 | /** height of displayed data in pixels */ | ||
84 | unsigned int height; | ||
85 | /** indicate which fields are present in buffer */ | ||
86 | unsigned int field; | ||
87 | }; | ||
88 | |||
89 | /** stages of geometry operations */ | ||
90 | enum mxr_geometry_stage { | ||
91 | MXR_GEOMETRY_SINK, | ||
92 | MXR_GEOMETRY_COMPOSE, | ||
93 | MXR_GEOMETRY_CROP, | ||
94 | MXR_GEOMETRY_SOURCE, | ||
95 | }; | ||
96 | |||
97 | /* flag indicating that offset should be 0 */ | ||
98 | #define MXR_NO_OFFSET 0x80000000 | ||
99 | |||
100 | /** description of transformation from source to destination image */ | ||
101 | struct mxr_geometry { | ||
102 | /** cropping for source image */ | ||
103 | struct mxr_crop src; | ||
104 | /** cropping for destination image */ | ||
105 | struct mxr_crop dst; | ||
106 | /** layer-dependant description of horizontal scaling */ | ||
107 | unsigned int x_ratio; | ||
108 | /** layer-dependant description of vertical scaling */ | ||
109 | unsigned int y_ratio; | ||
110 | }; | ||
111 | |||
112 | /** instance of a buffer */ | ||
113 | struct mxr_buffer { | ||
114 | /** common v4l buffer stuff -- must be first */ | ||
115 | struct vb2_buffer vb; | ||
116 | /** node for layer's lists */ | ||
117 | struct list_head list; | ||
118 | }; | ||
119 | |||
120 | |||
121 | /** internal states of layer */ | ||
122 | enum mxr_layer_state { | ||
123 | /** layers is not shown */ | ||
124 | MXR_LAYER_IDLE = 0, | ||
125 | /** layer is shown */ | ||
126 | MXR_LAYER_STREAMING, | ||
127 | /** state before STREAMOFF is finished */ | ||
128 | MXR_LAYER_STREAMING_FINISH, | ||
129 | }; | ||
130 | |||
131 | /** forward declarations */ | ||
132 | struct mxr_device; | ||
133 | struct mxr_layer; | ||
134 | |||
135 | /** callback for layers operation */ | ||
136 | struct mxr_layer_ops { | ||
137 | /* TODO: try to port it to subdev API */ | ||
138 | /** handler for resource release function */ | ||
139 | void (*release)(struct mxr_layer *); | ||
140 | /** setting buffer to HW */ | ||
141 | void (*buffer_set)(struct mxr_layer *, struct mxr_buffer *); | ||
142 | /** setting format and geometry in HW */ | ||
143 | void (*format_set)(struct mxr_layer *); | ||
144 | /** streaming stop/start */ | ||
145 | void (*stream_set)(struct mxr_layer *, int); | ||
146 | /** adjusting geometry */ | ||
147 | void (*fix_geometry)(struct mxr_layer *, | ||
148 | enum mxr_geometry_stage, unsigned long); | ||
149 | }; | ||
150 | |||
151 | /** layer instance, a single window and content displayed on output */ | ||
152 | struct mxr_layer { | ||
153 | /** parent mixer device */ | ||
154 | struct mxr_device *mdev; | ||
155 | /** layer index (unique identifier) */ | ||
156 | int idx; | ||
157 | /** callbacks for layer methods */ | ||
158 | struct mxr_layer_ops ops; | ||
159 | /** format array */ | ||
160 | const struct mxr_format **fmt_array; | ||
161 | /** size of format array */ | ||
162 | unsigned long fmt_array_size; | ||
163 | |||
164 | /** lock for protection of list and state fields */ | ||
165 | spinlock_t enq_slock; | ||
166 | /** list for enqueued buffers */ | ||
167 | struct list_head enq_list; | ||
168 | /** buffer currently owned by hardware in temporary registers */ | ||
169 | struct mxr_buffer *update_buf; | ||
170 | /** buffer currently owned by hardware in shadow registers */ | ||
171 | struct mxr_buffer *shadow_buf; | ||
172 | /** state of layer IDLE/STREAMING */ | ||
173 | enum mxr_layer_state state; | ||
174 | |||
175 | /** mutex for protection of fields below */ | ||
176 | struct mutex mutex; | ||
177 | /** handler for video node */ | ||
178 | struct video_device vfd; | ||
179 | /** queue for output buffers */ | ||
180 | struct vb2_queue vb_queue; | ||
181 | /** current image format */ | ||
182 | const struct mxr_format *fmt; | ||
183 | /** current geometry of image */ | ||
184 | struct mxr_geometry geo; | ||
185 | }; | ||
186 | |||
187 | /** description of mixers output interface */ | ||
188 | struct mxr_output { | ||
189 | /** name of output */ | ||
190 | char name[32]; | ||
191 | /** output subdev */ | ||
192 | struct v4l2_subdev *sd; | ||
193 | /** cookie used for configuration of registers */ | ||
194 | int cookie; | ||
195 | }; | ||
196 | |||
197 | /** specify source of output subdevs */ | ||
198 | struct mxr_output_conf { | ||
199 | /** name of output (connector) */ | ||
200 | char *output_name; | ||
201 | /** name of module that generates output subdev */ | ||
202 | char *module_name; | ||
203 | /** cookie need for mixer HW */ | ||
204 | int cookie; | ||
205 | }; | ||
206 | |||
207 | struct clk; | ||
208 | struct regulator; | ||
209 | |||
210 | /** auxiliary resources used my mixer */ | ||
211 | struct mxr_resources { | ||
212 | /** interrupt index */ | ||
213 | int irq; | ||
214 | /** pointer to Mixer registers */ | ||
215 | void __iomem *mxr_regs; | ||
216 | /** pointer to Video Processor registers */ | ||
217 | void __iomem *vp_regs; | ||
218 | /** other resources, should used under mxr_device.mutex */ | ||
219 | struct clk *mixer; | ||
220 | struct clk *vp; | ||
221 | struct clk *sclk_mixer; | ||
222 | struct clk *sclk_hdmi; | ||
223 | struct clk *sclk_dac; | ||
224 | }; | ||
225 | |||
226 | /* event flags used */ | ||
227 | enum mxr_devide_flags { | ||
228 | MXR_EVENT_VSYNC = 0, | ||
229 | MXR_EVENT_TOP = 1, | ||
230 | }; | ||
231 | |||
232 | /** drivers instance */ | ||
233 | struct mxr_device { | ||
234 | /** master device */ | ||
235 | struct device *dev; | ||
236 | /** state of each layer */ | ||
237 | struct mxr_layer *layer[MXR_MAX_LAYERS]; | ||
238 | /** state of each output */ | ||
239 | struct mxr_output *output[MXR_MAX_OUTPUTS]; | ||
240 | /** number of registered outputs */ | ||
241 | int output_cnt; | ||
242 | |||
243 | /* video resources */ | ||
244 | |||
245 | /** V4L2 device */ | ||
246 | struct v4l2_device v4l2_dev; | ||
247 | /** context of allocator */ | ||
248 | void *alloc_ctx; | ||
249 | /** event wait queue */ | ||
250 | wait_queue_head_t event_queue; | ||
251 | /** state flags */ | ||
252 | unsigned long event_flags; | ||
253 | |||
254 | /** spinlock for protection of registers */ | ||
255 | spinlock_t reg_slock; | ||
256 | |||
257 | /** mutex for protection of fields below */ | ||
258 | struct mutex mutex; | ||
259 | /** number of entities depndant on output configuration */ | ||
260 | int n_output; | ||
261 | /** number of users that do streaming */ | ||
262 | int n_streamer; | ||
263 | /** index of current output */ | ||
264 | int current_output; | ||
265 | /** auxiliary resources used my mixer */ | ||
266 | struct mxr_resources res; | ||
267 | }; | ||
268 | |||
269 | /** transform device structure into mixer device */ | ||
270 | static inline struct mxr_device *to_mdev(struct device *dev) | ||
271 | { | ||
272 | struct v4l2_device *vdev = dev_get_drvdata(dev); | ||
273 | return container_of(vdev, struct mxr_device, v4l2_dev); | ||
274 | } | ||
275 | |||
276 | /** get current output data, should be called under mdev's mutex */ | ||
277 | static inline struct mxr_output *to_output(struct mxr_device *mdev) | ||
278 | { | ||
279 | return mdev->output[mdev->current_output]; | ||
280 | } | ||
281 | |||
282 | /** get current output subdev, should be called under mdev's mutex */ | ||
283 | static inline struct v4l2_subdev *to_outsd(struct mxr_device *mdev) | ||
284 | { | ||
285 | struct mxr_output *out = to_output(mdev); | ||
286 | return out ? out->sd : NULL; | ||
287 | } | ||
288 | |||
289 | /** forward declaration for mixer platform data */ | ||
290 | struct mxr_platform_data; | ||
291 | |||
292 | /** acquiring common video resources */ | ||
293 | int __devinit mxr_acquire_video(struct mxr_device *mdev, | ||
294 | struct mxr_output_conf *output_cont, int output_count); | ||
295 | |||
296 | /** releasing common video resources */ | ||
297 | void mxr_release_video(struct mxr_device *mdev); | ||
298 | |||
299 | struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx); | ||
300 | struct mxr_layer *mxr_vp_layer_create(struct mxr_device *mdev, int idx); | ||
301 | struct mxr_layer *mxr_base_layer_create(struct mxr_device *mdev, | ||
302 | int idx, char *name, struct mxr_layer_ops *ops); | ||
303 | |||
304 | void mxr_base_layer_release(struct mxr_layer *layer); | ||
305 | void mxr_layer_release(struct mxr_layer *layer); | ||
306 | |||
307 | int mxr_base_layer_register(struct mxr_layer *layer); | ||
308 | void mxr_base_layer_unregister(struct mxr_layer *layer); | ||
309 | |||
310 | unsigned long mxr_get_plane_size(const struct mxr_block *blk, | ||
311 | unsigned int width, unsigned int height); | ||
312 | |||
313 | /** adds new consumer for mixer's power */ | ||
314 | int __must_check mxr_power_get(struct mxr_device *mdev); | ||
315 | /** removes consumer for mixer's power */ | ||
316 | void mxr_power_put(struct mxr_device *mdev); | ||
317 | /** add new client for output configuration */ | ||
318 | void mxr_output_get(struct mxr_device *mdev); | ||
319 | /** removes new client for output configuration */ | ||
320 | void mxr_output_put(struct mxr_device *mdev); | ||
321 | /** add new client for streaming */ | ||
322 | void mxr_streamer_get(struct mxr_device *mdev); | ||
323 | /** removes new client for streaming */ | ||
324 | void mxr_streamer_put(struct mxr_device *mdev); | ||
325 | /** returns format of data delivared to current output */ | ||
326 | void mxr_get_mbus_fmt(struct mxr_device *mdev, | ||
327 | struct v4l2_mbus_framefmt *mbus_fmt); | ||
328 | |||
329 | /* Debug */ | ||
330 | |||
331 | #define mxr_err(mdev, fmt, ...) dev_err(mdev->dev, fmt, ##__VA_ARGS__) | ||
332 | #define mxr_warn(mdev, fmt, ...) dev_warn(mdev->dev, fmt, ##__VA_ARGS__) | ||
333 | #define mxr_info(mdev, fmt, ...) dev_info(mdev->dev, fmt, ##__VA_ARGS__) | ||
334 | |||
335 | #ifdef CONFIG_VIDEO_SAMSUNG_S5P_MIXER_DEBUG | ||
336 | #define mxr_dbg(mdev, fmt, ...) dev_dbg(mdev->dev, fmt, ##__VA_ARGS__) | ||
337 | #else | ||
338 | #define mxr_dbg(mdev, fmt, ...) do { (void) mdev; } while (0) | ||
339 | #endif | ||
340 | |||
341 | /* accessing Mixer's and Video Processor's registers */ | ||
342 | |||
343 | void mxr_vsync_set_update(struct mxr_device *mdev, int en); | ||
344 | void mxr_reg_reset(struct mxr_device *mdev); | ||
345 | irqreturn_t mxr_irq_handler(int irq, void *dev_data); | ||
346 | void mxr_reg_s_output(struct mxr_device *mdev, int cookie); | ||
347 | void mxr_reg_streamon(struct mxr_device *mdev); | ||
348 | void mxr_reg_streamoff(struct mxr_device *mdev); | ||
349 | int mxr_reg_wait4vsync(struct mxr_device *mdev); | ||
350 | void mxr_reg_set_mbus_fmt(struct mxr_device *mdev, | ||
351 | struct v4l2_mbus_framefmt *fmt); | ||
352 | void mxr_reg_graph_layer_stream(struct mxr_device *mdev, int idx, int en); | ||
353 | void mxr_reg_graph_buffer(struct mxr_device *mdev, int idx, dma_addr_t addr); | ||
354 | void mxr_reg_graph_format(struct mxr_device *mdev, int idx, | ||
355 | const struct mxr_format *fmt, const struct mxr_geometry *geo); | ||
356 | |||
357 | void mxr_reg_vp_layer_stream(struct mxr_device *mdev, int en); | ||
358 | void mxr_reg_vp_buffer(struct mxr_device *mdev, | ||
359 | dma_addr_t luma_addr[2], dma_addr_t chroma_addr[2]); | ||
360 | void mxr_reg_vp_format(struct mxr_device *mdev, | ||
361 | const struct mxr_format *fmt, const struct mxr_geometry *geo); | ||
362 | void mxr_reg_dump(struct mxr_device *mdev); | ||
363 | |||
364 | #endif /* SAMSUNG_MIXER_H */ | ||
365 | |||