2 * Samsung TV Mixer driver
4 * Copyright (c) 2010 Samsung Electronics
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
15 #include "mixer_reg.h"
17 #include <media/videobuf2-cma.h>
19 /* FORMAT DEFINITIONS */
21 static const struct mxr_format mxr_fb_fmt_rgb565 = {
23 .fourcc = V4L2_PIX_FMT_RGB565,
26 { .pxWidth = 1, .pxHeight = 1, .bSize = 2 },
32 static const struct mxr_format mxr_fb_fmt_argb1555 = {
35 .fourcc = V4L2_PIX_FMT_RGB555,
37 { .pxWidth = 1, .pxHeight = 1, .bSize = 2 },
43 static const struct mxr_format mxr_fb_fmt_argb4444 = {
46 .fourcc = V4L2_PIX_FMT_RGB444,
48 { .pxWidth = 1, .pxHeight = 1, .bSize = 2 },
54 static const struct mxr_format mxr_fb_fmt_argb8888 = {
56 .fourcc = V4L2_PIX_FMT_BGR32,
59 { .pxWidth = 1, .pxHeight = 1, .bSize = 4 },
65 static const struct mxr_format *mxr_graph_format[] = {
72 /* AUXILIARY CALLBACKS */
74 static void mxr_graph_layer_release(struct mxr_layer *layer)
76 mxr_base_layer_unregister(layer);
77 mxr_base_layer_release(layer);
80 static void mxr_graph_buffer_set(struct mxr_layer *layer,
81 struct mxr_buffer *buf)
85 addr = vb2_cma_plane_paddr(&buf->vb, 0);
86 mxr_reg_graph_buffer(layer->mdev, layer->idx, addr);
89 static void mxr_graph_stream_set(struct mxr_layer *layer, int en)
91 mxr_reg_graph_layer_stream(layer->mdev, layer->idx, en);
94 static void mxr_graph_format_set(struct mxr_layer *layer)
96 mxr_reg_graph_format(layer->mdev, layer->idx,
97 layer->fmt, &layer->geo);
100 static void mxr_graph_fix_geometry(struct mxr_layer *layer)
102 struct mxr_geometry *geo = &layer->geo;
103 /* limit to boundary size */
104 geo->src.full_width = clamp_val(geo->src.full_width, 1, 32767);
105 geo->src.full_height = clamp_val(geo->src.full_height, 1, 2047);
106 geo->src.width = clamp_val(geo->src.width, 1, geo->src.full_width);
107 geo->src.width = min(geo->src.width, 2047U);
108 /* not possible to crop of Y axis */
109 geo->src.y_offset = min(geo->src.y_offset, geo->src.full_height - 1);
110 geo->src.height = geo->src.full_height - geo->src.y_offset;
111 /* limitting offset */
112 geo->src.x_offset = min(geo->src.x_offset,
113 geo->src.full_width - geo->src.width);
115 /* setting position in output */
116 geo->dst.width = min(geo->dst.width, geo->dst.full_width);
117 geo->dst.height = min(geo->dst.height, geo->dst.full_height);
119 /* Mixer supports only 1x and 2x scaling */
120 if (geo->dst.width >= 2 * geo->src.width) {
122 geo->dst.width = 2 * geo->src.width;
125 geo->dst.width = geo->src.width;
128 if (geo->dst.height >= 2 * geo->src.height) {
130 geo->dst.height = 2 * geo->src.height;
133 geo->dst.height = geo->src.height;
136 geo->dst.x_offset = min(geo->dst.x_offset,
137 geo->dst.full_width - geo->dst.width);
138 geo->dst.y_offset = min(geo->dst.y_offset,
139 geo->dst.full_height - geo->dst.height);
144 struct mxr_layer *mxr_graph_layer_create(struct mxr_device *mdev, int idx)
146 struct mxr_layer *layer;
147 struct device *dev = mdev->dev;
149 struct mxr_layer_ops ops = {
150 .release = mxr_graph_layer_release,
151 .buffer_set = mxr_graph_buffer_set,
152 .stream_set = mxr_graph_stream_set,
153 .format_set = mxr_graph_format_set,
154 .fix_geometry = mxr_graph_fix_geometry,
158 sprintf(name, "graph%d", idx);
160 layer = mxr_base_layer_create(mdev, idx, name, &ops);
162 dev_err(dev, "failed to initialize layer(%d) base\n", idx);
166 layer->fmt_array = mxr_graph_format;
167 layer->fmt_array_size = ARRAY_SIZE(mxr_graph_format);
169 ret = mxr_base_layer_register(layer);
176 mxr_base_layer_release(layer);