aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/platform/ti-vpe/csc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-31 12:31:14 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-31 12:31:14 -0500
commitb399c46ea0070671f3abbe1915d26076101a42f2 (patch)
tree8945606976fc46c3446c09f8a9e0d4f45f6c408e /drivers/media/platform/ti-vpe/csc.c
parentb890eb4ecc718907223a3b7b7b069b59b33f28ef (diff)
parent6c3df5da67f1f53df78c7e20cd53a481dc28eade (diff)
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
Pull media updates from Mauro Carvalho Chehab: - a new jpeg codec driver for Samsung Exynos (jpeg-hw-exynos4) - a new dvb frontend for ds2103 chipset (m88ds2103) - a new sensor driver for Samsung S5K5BAF UXGA (s5k5baf) - new drivers for R-Car VSP1 - a new radio driver: radio-raremono - a new tuner driver for ts2022 chipset (m88ts2022) - the analog part of em28xx is now a separate module that only load/runs if the device is not a pure digital TV device - added a staging driver for bcm2048 radio devices - the omap 2 video driver (omap24xx) was moved to staging. This driver is for an old hardware and uses a deprecated Kernel internal API. If nobody cares enough to fix it, it would be removed on a couple Kernel releases - the sn9c102 driver was moved to staging. This driver was replaced by gspca, and disabled on some distros, as almost all devices are known to work properly with gspca. It should be removed from kernel on a couple Kernel releases - lots of driver fixes, improvements and cleanups * 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (421 commits) [media] media: v4l2-dev: fix video device index assignment [media] rc-core: reuse device numbers [media] em28xx-cards: properly initialize the device bitmap [media] Staging: media: Fix line length exceeding 80 characters in as102_drv.c [media] Staging: media: Fix line length exceeding 80 characters in as102_fe.c [media] Staging: media: Fix quoted string split across line in as102_fe.c [media] media: st-rc: Add reset support [media] m2m-deinterlace: fix allocated struct type [media] radio-usb-si4713: fix sparse non static symbol warnings [media] em28xx-audio: remove needless check before usb_free_coherent() [media] au0828: Fix sparse non static symbol warning Revert "[media] go7007-usb: only use go->dev after allocated" [media] em28xx-audio: provide an error code when URB submit fails [media] em28xx: fix check for audio only usb interfaces when changing the usb alternate setting [media] em28xx: fix usb alternate setting for analog and digital video endpoints > 0 [media] em28xx: make 'em28xx_ctrl_ops' static em28xx-alsa: Fix error patch for init/fini [media] em28xx-audio: flush work at .fini [media] drxk: remove the option to load firmware asynchronously [media] em28xx: adjust period size at runtime ...
Diffstat (limited to 'drivers/media/platform/ti-vpe/csc.c')
-rw-r--r--drivers/media/platform/ti-vpe/csc.c196
1 files changed, 196 insertions, 0 deletions
diff --git a/drivers/media/platform/ti-vpe/csc.c b/drivers/media/platform/ti-vpe/csc.c
new file mode 100644
index 000000000000..acfea500710e
--- /dev/null
+++ b/drivers/media/platform/ti-vpe/csc.c
@@ -0,0 +1,196 @@
1/*
2 * Color space converter library
3 *
4 * Copyright (c) 2013 Texas Instruments Inc.
5 *
6 * David Griego, <dagriego@biglakesoftware.com>
7 * Dale Farnsworth, <dale@farnsworth.org>
8 * Archit Taneja, <archit@ti.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation.
13 */
14
15#include <linux/err.h>
16#include <linux/io.h>
17#include <linux/platform_device.h>
18#include <linux/slab.h>
19#include <linux/videodev2.h>
20
21#include "csc.h"
22
23/*
24 * 16 coefficients in the order:
25 * a0, b0, c0, a1, b1, c1, a2, b2, c2, d0, d1, d2
26 * (we may need to pass non-default values from user space later on, we might
27 * need to make the coefficient struct more easy to populate)
28 */
29struct colorspace_coeffs {
30 u16 sd[12];
31 u16 hd[12];
32};
33
34/* VIDEO_RANGE: limited range, GRAPHICS_RANGE: full range */
35#define CSC_COEFFS_VIDEO_RANGE_Y2R 0
36#define CSC_COEFFS_GRAPHICS_RANGE_Y2R 1
37#define CSC_COEFFS_VIDEO_RANGE_R2Y 2
38#define CSC_COEFFS_GRAPHICS_RANGE_R2Y 3
39
40/* default colorspace coefficients */
41static struct colorspace_coeffs colorspace_coeffs[4] = {
42 [CSC_COEFFS_VIDEO_RANGE_Y2R] = {
43 {
44 /* SDTV */
45 0x0400, 0x0000, 0x057D, 0x0400, 0x1EA7, 0x1D35,
46 0x0400, 0x06EF, 0x1FFE, 0x0D40, 0x0210, 0x0C88,
47 },
48 {
49 /* HDTV */
50 0x0400, 0x0000, 0x0629, 0x0400, 0x1F45, 0x1E2B,
51 0x0400, 0x0742, 0x0000, 0x0CEC, 0x0148, 0x0C60,
52 },
53 },
54 [CSC_COEFFS_GRAPHICS_RANGE_Y2R] = {
55 {
56 /* SDTV */
57 0x04A8, 0x1FFE, 0x0662, 0x04A8, 0x1E6F, 0x1CBF,
58 0x04A8, 0x0812, 0x1FFF, 0x0C84, 0x0220, 0x0BAC,
59 },
60 {
61 /* HDTV */
62 0x04A8, 0x0000, 0x072C, 0x04A8, 0x1F26, 0x1DDE,
63 0x04A8, 0x0873, 0x0000, 0x0C20, 0x0134, 0x0B7C,
64 },
65 },
66 [CSC_COEFFS_VIDEO_RANGE_R2Y] = {
67 {
68 /* SDTV */
69 0x0132, 0x0259, 0x0075, 0x1F50, 0x1EA5, 0x020B,
70 0x020B, 0x1E4A, 0x1FAB, 0x0000, 0x0200, 0x0200,
71 },
72 {
73 /* HDTV */
74 0x00DA, 0x02DC, 0x004A, 0x1F88, 0x1E6C, 0x020C,
75 0x020C, 0x1E24, 0x1FD0, 0x0000, 0x0200, 0x0200,
76 },
77 },
78 [CSC_COEFFS_GRAPHICS_RANGE_R2Y] = {
79 {
80 /* SDTV */
81 0x0107, 0x0204, 0x0064, 0x1F68, 0x1ED6, 0x01C2,
82 0x01C2, 0x1E87, 0x1FB7, 0x0040, 0x0200, 0x0200,
83 },
84 {
85 /* HDTV */
86 0x04A8, 0x0000, 0x072C, 0x04A8, 0x1F26, 0x1DDE,
87 0x04A8, 0x0873, 0x0000, 0x0C20, 0x0134, 0x0B7C,
88 },
89 },
90};
91
92void csc_dump_regs(struct csc_data *csc)
93{
94 struct device *dev = &csc->pdev->dev;
95
96 u32 read_reg(struct csc_data *csc, int offset)
97 {
98 return ioread32(csc->base + offset);
99 }
100
101#define DUMPREG(r) dev_dbg(dev, "%-35s %08x\n", #r, read_reg(csc, CSC_##r))
102
103 DUMPREG(CSC00);
104 DUMPREG(CSC01);
105 DUMPREG(CSC02);
106 DUMPREG(CSC03);
107 DUMPREG(CSC04);
108 DUMPREG(CSC05);
109
110#undef DUMPREG
111}
112
113void csc_set_coeff_bypass(struct csc_data *csc, u32 *csc_reg5)
114{
115 *csc_reg5 |= CSC_BYPASS;
116}
117
118/*
119 * set the color space converter coefficient shadow register values
120 */
121void csc_set_coeff(struct csc_data *csc, u32 *csc_reg0,
122 enum v4l2_colorspace src_colorspace,
123 enum v4l2_colorspace dst_colorspace)
124{
125 u32 *csc_reg5 = csc_reg0 + 5;
126 u32 *shadow_csc = csc_reg0;
127 struct colorspace_coeffs *sd_hd_coeffs;
128 u16 *coeff, *end_coeff;
129 enum v4l2_colorspace yuv_colorspace;
130 int sel = 0;
131
132 /*
133 * support only graphics data range(full range) for now, a control ioctl
134 * would be nice here
135 */
136 /* Y2R */
137 if (dst_colorspace == V4L2_COLORSPACE_SRGB &&
138 (src_colorspace == V4L2_COLORSPACE_SMPTE170M ||
139 src_colorspace == V4L2_COLORSPACE_REC709)) {
140 /* Y2R */
141 sel = 1;
142 yuv_colorspace = src_colorspace;
143 } else if ((dst_colorspace == V4L2_COLORSPACE_SMPTE170M ||
144 dst_colorspace == V4L2_COLORSPACE_REC709) &&
145 src_colorspace == V4L2_COLORSPACE_SRGB) {
146 /* R2Y */
147 sel = 3;
148 yuv_colorspace = dst_colorspace;
149 } else {
150 *csc_reg5 |= CSC_BYPASS;
151 return;
152 }
153
154 sd_hd_coeffs = &colorspace_coeffs[sel];
155
156 /* select between SD or HD coefficients */
157 if (yuv_colorspace == V4L2_COLORSPACE_SMPTE170M)
158 coeff = sd_hd_coeffs->sd;
159 else
160 coeff = sd_hd_coeffs->hd;
161
162 end_coeff = coeff + 12;
163
164 for (; coeff < end_coeff; coeff += 2)
165 *shadow_csc++ = (*(coeff + 1) << 16) | *coeff;
166}
167
168struct csc_data *csc_create(struct platform_device *pdev)
169{
170 struct csc_data *csc;
171
172 dev_dbg(&pdev->dev, "csc_create\n");
173
174 csc = devm_kzalloc(&pdev->dev, sizeof(*csc), GFP_KERNEL);
175 if (!csc) {
176 dev_err(&pdev->dev, "couldn't alloc csc_data\n");
177 return ERR_PTR(-ENOMEM);
178 }
179
180 csc->pdev = pdev;
181
182 csc->res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
183 "vpe_csc");
184 if (csc->res == NULL) {
185 dev_err(&pdev->dev, "missing platform resources data\n");
186 return ERR_PTR(-ENODEV);
187 }
188
189 csc->base = devm_ioremap_resource(&pdev->dev, csc->res);
190 if (!csc->base) {
191 dev_err(&pdev->dev, "failed to ioremap\n");
192 return ERR_PTR(-ENOMEM);
193 }
194
195 return csc;
196}