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
16 #include <media/videobuf2-dma-contig.h>
18 /* FORMAT DEFINITIONS */
20 static const struct mxr_format mxr_fb_fmt_rgb565 = {
22 .fourcc = V4L2_PIX_FMT_RGB565,
23 .colorspace = V4L2_COLORSPACE_SRGB,
26 { .width = 1, .height = 1, .size = 2 },
32 static const struct mxr_format mxr_fb_fmt_argb1555 = {
35 .fourcc = V4L2_PIX_FMT_RGB555,
36 .colorspace = V4L2_COLORSPACE_SRGB,
38 { .width = 1, .height = 1, .size = 2 },
44 static const struct mxr_format mxr_fb_fmt_argb4444 = {
47 .fourcc = V4L2_PIX_FMT_RGB444,
48 .colorspace = V4L2_COLORSPACE_SRGB,
50 { .width = 1, .height = 1, .size = 2 },
56 static const struct mxr_format mxr_fb_fmt_argb8888 = {
58 .fourcc = V4L2_PIX_FMT_BGR32,
59 .colorspace = V4L2_COLORSPACE_SRGB,
62 { .width = 1, .height = 1, .size = 4 },
68 static const struct mxr_format *mxr_graph_format[] = {
75 /* AUXILIARY CALLBACKS */
77 static void mxr_graph_layer_release(struct mxr_layer *layer)
79 mxr_base_layer_unregister(layer);
80 mxr_base_layer_release(layer);
83 static void mxr_graph_buffer_set(struct mxr_layer *layer,
84 struct mxr_buffer *buf)
89 addr = vb2_dma_contig_plane_dma_addr(&buf->vb, 0);
90 mxr_reg_graph_buffer(layer->mdev, layer->idx, addr);
93 static void mxr_graph_stream_set(struct mxr_layer *layer, int en)
95 mxr_reg_graph_layer_stream(layer->mdev, layer->idx, en);
98 static void mxr_graph_format_set(struct mxr_layer *layer)
100 mxr_reg_graph_format(layer->mdev, layer->idx,
101 layer->fmt, &layer->geo);
104 static void mxr_graph_fix_geometry(struct mxr_layer *layer)
106 struct mxr_geometry *geo = &layer->geo;
108 /* limit to boundary size */
109 geo->src.full_width = clamp_val(geo->src.full_width, 1, 32767);
110 geo->src.full_height = clamp_val(geo->src.full_height, 1, 2047);
111 geo->src.width = clamp_val(geo->src.width, 1, geo->src.full_width);
112 geo->src.width = min(geo->src.width, 2047U);
113 /* not possible to crop of Y axis */
114 geo->src.y_offset = min(geo->src.y_offset, geo->src.full_height - 1);
115 geo->src.height = geo->src.full_height - geo->src.y_offset;
116 /* limitting offset */
117 geo->src.x_offset = min(geo->src.x_offset,
118 geo->src.full_width - geo->src.width);
120 /* setting position in output */
121 geo->dst.width = min(geo->dst.width, geo->dst.full_width);
122 geo->dst.height = min(geo->dst.height, geo->dst.full_height);
124 /* Mixer supports only 1x and 2x scaling */
125 if (geo->dst.width >= 2 * geo->src.width) {
127 geo->dst.width = 2 * geo->src.width;
130 geo->dst.width = geo->src.width;
133 if (geo->dst.height >= 2 * geo->src.height) {
135 geo->dst.height = 2 * geo->src.height;
138 geo->dst.height = geo->src.height;
141 geo->dst.x_offset = min(geo->dst.x_offset,
142 geo->dst.full_width - geo->dst.width);
143 geo->dst.y_offset = min(geo->dst.y_offset,
144 geo->dst.full_height - geo->dst.height);
149 struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx)
151 struct mxr_layer *layer;
153 struct mxr_layer_ops ops = {
154 .release = mxr_graph_layer_release,
155 .buffer_set = mxr_graph_buffer_set,
156 .stream_set = mxr_graph_stream_set,
157 .format_set = mxr_graph_format_set,
158 .fix_geometry = mxr_graph_fix_geometry,
162 sprintf(name, "graph%d", idx);
164 layer = mxr_base_layer_create(mdev, idx, name, &ops);
166 mxr_err(mdev, "failed to initialize layer(%d) base\n", idx);
170 layer->fmt_array = mxr_graph_format;
171 layer->fmt_array_size = ARRAY_SIZE(mxr_graph_format);
173 ret = mxr_base_layer_register(layer);
180 mxr_base_layer_release(layer);