2 * Samsung TV Mixer driver
4 * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
6 * Tomasz Stanislawski, <t.stanislaws@samsung.com>
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
14 #ifndef SAMSUNG_MIXER_H
15 #define SAMSUNG_MIXER_H
17 #ifdef CONFIG_VIDEO_SAMSUNG_S5P_MIXER_DEBUG
22 #include <linux/irqreturn.h>
23 #include <linux/kernel.h>
24 #include <linux/spinlock.h>
25 #include <linux/wait.h>
26 #include <media/v4l2-device.h>
27 #include <media/videobuf2-core.h>
29 #include "regs-mixer.h"
31 /** maximum number of output interfaces */
32 #define MXR_MAX_OUTPUTS 2
33 /** maximum number of input interfaces (layers) */
34 #define MXR_MAX_LAYERS 3
35 #define MXR_DRIVER_NAME "s5p-mixer"
36 /** maximal number of planes for every layer */
37 #define MXR_MAX_PLANES 2
42 /** description of a macroblock for packed formats */
44 /** vertical number of pixels in macroblock */
46 /** horizontal number of pixels in macroblock */
48 /** size of block in bytes */
52 /** description of supported format */
54 /** format name/mnemonic */
56 /** fourcc identifier */
58 /** colorspace identifier */
59 enum v4l2_colorspace colorspace
;
60 /** number of planes in image data */
62 /** description of block for each plane */
63 struct mxr_block plane
[MXR_MAX_PLANES
];
64 /** number of subframes in image data */
66 /** specifies to which subframe belong given plane */
67 int plane2subframe
[MXR_MAX_PLANES
];
68 /** internal code, driver dependant */
72 /** description of crop configuration for image */
74 /** width of layer in pixels */
75 unsigned int full_width
;
76 /** height of layer in pixels */
77 unsigned int full_height
;
78 /** horizontal offset of first pixel to be displayed */
79 unsigned int x_offset
;
80 /** vertical offset of first pixel to be displayed */
81 unsigned int y_offset
;
82 /** width of displayed data in pixels */
84 /** height of displayed data in pixels */
86 /** indicate which fields are present in buffer */
90 /** stages of geometry operations */
91 enum mxr_geometry_stage
{
98 /* flag indicating that offset should be 0 */
99 #define MXR_NO_OFFSET 0x80000000
101 /** description of transformation from source to destination image */
102 struct mxr_geometry
{
103 /** cropping for source image */
105 /** cropping for destination image */
107 /** layer-dependant description of horizontal scaling */
108 unsigned int x_ratio
;
109 /** layer-dependant description of vertical scaling */
110 unsigned int y_ratio
;
113 /** instance of a buffer */
115 /** common v4l buffer stuff -- must be first */
116 struct vb2_buffer vb
;
117 /** node for layer's lists */
118 struct list_head list
;
122 /** internal states of layer */
123 enum mxr_layer_state
{
124 /** layers is not shown */
126 /** layer is shown */
128 /** state before STREAMOFF is finished */
129 MXR_LAYER_STREAMING_FINISH
,
132 /** forward declarations */
136 /** callback for layers operation */
137 struct mxr_layer_ops
{
138 /* TODO: try to port it to subdev API */
139 /** handler for resource release function */
140 void (*release
)(struct mxr_layer
*);
141 /** setting buffer to HW */
142 void (*buffer_set
)(struct mxr_layer
*, struct mxr_buffer
*);
143 /** setting format and geometry in HW */
144 void (*format_set
)(struct mxr_layer
*);
145 /** streaming stop/start */
146 void (*stream_set
)(struct mxr_layer
*, int);
147 /** adjusting geometry */
148 void (*fix_geometry
)(struct mxr_layer
*,
149 enum mxr_geometry_stage
, unsigned long);
152 /** layer instance, a single window and content displayed on output */
154 /** parent mixer device */
155 struct mxr_device
*mdev
;
156 /** layer index (unique identifier) */
158 /** callbacks for layer methods */
159 struct mxr_layer_ops ops
;
161 const struct mxr_format
**fmt_array
;
162 /** size of format array */
163 unsigned long fmt_array_size
;
165 /** lock for protection of list and state fields */
166 spinlock_t enq_slock
;
167 /** list for enqueued buffers */
168 struct list_head enq_list
;
169 /** buffer currently owned by hardware in temporary registers */
170 struct mxr_buffer
*update_buf
;
171 /** buffer currently owned by hardware in shadow registers */
172 struct mxr_buffer
*shadow_buf
;
173 /** state of layer IDLE/STREAMING */
174 enum mxr_layer_state state
;
176 /** mutex for protection of fields below */
178 /** handler for video node */
179 struct video_device vfd
;
180 /** queue for output buffers */
181 struct vb2_queue vb_queue
;
182 /** current image format */
183 const struct mxr_format
*fmt
;
184 /** current geometry of image */
185 struct mxr_geometry geo
;
188 /** description of mixers output interface */
190 /** name of output */
193 struct v4l2_subdev
*sd
;
194 /** cookie used for configuration of registers */
198 /** specify source of output subdevs */
199 struct mxr_output_conf
{
200 /** name of output (connector) */
202 /** name of module that generates output subdev */
204 /** cookie need for mixer HW */
211 /** auxiliary resources used my mixer */
212 struct mxr_resources
{
213 /** interrupt index */
215 /** pointer to Mixer registers */
216 void __iomem
*mxr_regs
;
217 /** pointer to Video Processor registers */
218 void __iomem
*vp_regs
;
219 /** other resources, should used under mxr_device.mutex */
222 struct clk
*sclk_mixer
;
223 struct clk
*sclk_hdmi
;
224 struct clk
*sclk_dac
;
227 /* event flags used */
228 enum mxr_devide_flags
{
233 /** drivers instance */
237 /** state of each layer */
238 struct mxr_layer
*layer
[MXR_MAX_LAYERS
];
239 /** state of each output */
240 struct mxr_output
*output
[MXR_MAX_OUTPUTS
];
241 /** number of registered outputs */
244 /* video resources */
247 struct v4l2_device v4l2_dev
;
248 /** context of allocator */
250 /** event wait queue */
251 wait_queue_head_t event_queue
;
253 unsigned long event_flags
;
255 /** spinlock for protection of registers */
256 spinlock_t reg_slock
;
258 /** mutex for protection of fields below */
260 /** number of entities depndant on output configuration */
262 /** number of users that do streaming */
264 /** index of current output */
266 /** auxiliary resources used my mixer */
267 struct mxr_resources res
;
270 /** transform device structure into mixer device */
271 static inline struct mxr_device
*to_mdev(struct device
*dev
)
273 struct v4l2_device
*vdev
= dev_get_drvdata(dev
);
274 return container_of(vdev
, struct mxr_device
, v4l2_dev
);
277 /** get current output data, should be called under mdev's mutex */
278 static inline struct mxr_output
*to_output(struct mxr_device
*mdev
)
280 return mdev
->output
[mdev
->current_output
];
283 /** get current output subdev, should be called under mdev's mutex */
284 static inline struct v4l2_subdev
*to_outsd(struct mxr_device
*mdev
)
286 struct mxr_output
*out
= to_output(mdev
);
287 return out
? out
->sd
: NULL
;
290 /** forward declaration for mixer platform data */
291 struct mxr_platform_data
;
293 /** acquiring common video resources */
294 int mxr_acquire_video(struct mxr_device
*mdev
,
295 struct mxr_output_conf
*output_cont
, int output_count
);
297 /** releasing common video resources */
298 void mxr_release_video(struct mxr_device
*mdev
);
300 struct mxr_layer
*mxr_graph_layer_create(struct mxr_device
*mdev
, int idx
);
301 struct mxr_layer
*mxr_vp_layer_create(struct mxr_device
*mdev
, int idx
);
302 struct mxr_layer
*mxr_base_layer_create(struct mxr_device
*mdev
,
303 int idx
, char *name
, struct mxr_layer_ops
*ops
);
305 void mxr_base_layer_release(struct mxr_layer
*layer
);
306 void mxr_layer_release(struct mxr_layer
*layer
);
308 int mxr_base_layer_register(struct mxr_layer
*layer
);
309 void mxr_base_layer_unregister(struct mxr_layer
*layer
);
311 unsigned long mxr_get_plane_size(const struct mxr_block
*blk
,
312 unsigned int width
, unsigned int height
);
314 /** adds new consumer for mixer's power */
315 int __must_check
mxr_power_get(struct mxr_device
*mdev
);
316 /** removes consumer for mixer's power */
317 void mxr_power_put(struct mxr_device
*mdev
);
318 /** add new client for output configuration */
319 void mxr_output_get(struct mxr_device
*mdev
);
320 /** removes new client for output configuration */
321 void mxr_output_put(struct mxr_device
*mdev
);
322 /** add new client for streaming */
323 void mxr_streamer_get(struct mxr_device
*mdev
);
324 /** removes new client for streaming */
325 void mxr_streamer_put(struct mxr_device
*mdev
);
326 /** returns format of data delivared to current output */
327 void mxr_get_mbus_fmt(struct mxr_device
*mdev
,
328 struct v4l2_mbus_framefmt
*mbus_fmt
);
332 #define mxr_err(mdev, fmt, ...) dev_err(mdev->dev, fmt, ##__VA_ARGS__)
333 #define mxr_warn(mdev, fmt, ...) dev_warn(mdev->dev, fmt, ##__VA_ARGS__)
334 #define mxr_info(mdev, fmt, ...) dev_info(mdev->dev, fmt, ##__VA_ARGS__)
336 #ifdef CONFIG_VIDEO_SAMSUNG_S5P_MIXER_DEBUG
337 #define mxr_dbg(mdev, fmt, ...) dev_dbg(mdev->dev, fmt, ##__VA_ARGS__)
339 #define mxr_dbg(mdev, fmt, ...) do { (void) mdev; } while (0)
342 /* accessing Mixer's and Video Processor's registers */
344 void mxr_vsync_set_update(struct mxr_device
*mdev
, int en
);
345 void mxr_reg_reset(struct mxr_device
*mdev
);
346 irqreturn_t
mxr_irq_handler(int irq
, void *dev_data
);
347 void mxr_reg_s_output(struct mxr_device
*mdev
, int cookie
);
348 void mxr_reg_streamon(struct mxr_device
*mdev
);
349 void mxr_reg_streamoff(struct mxr_device
*mdev
);
350 int mxr_reg_wait4vsync(struct mxr_device
*mdev
);
351 void mxr_reg_set_mbus_fmt(struct mxr_device
*mdev
,
352 struct v4l2_mbus_framefmt
*fmt
);
353 void mxr_reg_graph_layer_stream(struct mxr_device
*mdev
, int idx
, int en
);
354 void mxr_reg_graph_buffer(struct mxr_device
*mdev
, int idx
, dma_addr_t addr
);
355 void mxr_reg_graph_format(struct mxr_device
*mdev
, int idx
,
356 const struct mxr_format
*fmt
, const struct mxr_geometry
*geo
);
358 void mxr_reg_vp_layer_stream(struct mxr_device
*mdev
, int en
);
359 void mxr_reg_vp_buffer(struct mxr_device
*mdev
,
360 dma_addr_t luma_addr
[2], dma_addr_t chroma_addr
[2]);
361 void mxr_reg_vp_format(struct mxr_device
*mdev
,
362 const struct mxr_format
*fmt
, const struct mxr_geometry
*geo
);
363 void mxr_reg_dump(struct mxr_device
*mdev
);
365 #endif /* SAMSUNG_MIXER_H */