diff options
author | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-02-13 08:31:38 -0500 |
---|---|---|
committer | Tomi Valkeinen <tomi.valkeinen@ti.com> | 2014-04-17 01:10:19 -0400 |
commit | f7018c21350204c4cf628462f229d44d03545254 (patch) | |
tree | 408787177164cf51cc06f7aabdb04fcff8d2b6aa /drivers/video/fbdev/fbcmap.c | |
parent | c26ef3eb3c11274bad1b64498d0a134f85755250 (diff) |
video: move fbdev to drivers/video/fbdev
The drivers/video directory is a mess. It contains generic video related
files, directories for backlight, console, linux logo, lots of fbdev
device drivers, fbdev framework files.
Make some order into the chaos by creating drivers/video/fbdev
directory, and move all fbdev related files there.
No functionality is changed, although I guess it is possible that some
subtle Makefile build order related issue could be created by this
patch.
Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Acked-by: Rob Clark <robdclark@gmail.com>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/video/fbdev/fbcmap.c')
-rw-r--r-- | drivers/video/fbdev/fbcmap.c | 362 |
1 files changed, 362 insertions, 0 deletions
diff --git a/drivers/video/fbdev/fbcmap.c b/drivers/video/fbdev/fbcmap.c new file mode 100644 index 000000000000..f89245b8ba8e --- /dev/null +++ b/drivers/video/fbdev/fbcmap.c | |||
@@ -0,0 +1,362 @@ | |||
1 | /* | ||
2 | * linux/drivers/video/fbcmap.c -- Colormap handling for frame buffer devices | ||
3 | * | ||
4 | * Created 15 Jun 1997 by Geert Uytterhoeven | ||
5 | * | ||
6 | * 2001 - Documented with DocBook | ||
7 | * - Brad Douglas <brad@neruo.com> | ||
8 | * | ||
9 | * This file is subject to the terms and conditions of the GNU General Public | ||
10 | * License. See the file COPYING in the main directory of this archive for | ||
11 | * more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/string.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/fb.h> | ||
17 | #include <linux/slab.h> | ||
18 | #include <linux/uaccess.h> | ||
19 | |||
20 | static u16 red2[] __read_mostly = { | ||
21 | 0x0000, 0xaaaa | ||
22 | }; | ||
23 | static u16 green2[] __read_mostly = { | ||
24 | 0x0000, 0xaaaa | ||
25 | }; | ||
26 | static u16 blue2[] __read_mostly = { | ||
27 | 0x0000, 0xaaaa | ||
28 | }; | ||
29 | |||
30 | static u16 red4[] __read_mostly = { | ||
31 | 0x0000, 0xaaaa, 0x5555, 0xffff | ||
32 | }; | ||
33 | static u16 green4[] __read_mostly = { | ||
34 | 0x0000, 0xaaaa, 0x5555, 0xffff | ||
35 | }; | ||
36 | static u16 blue4[] __read_mostly = { | ||
37 | 0x0000, 0xaaaa, 0x5555, 0xffff | ||
38 | }; | ||
39 | |||
40 | static u16 red8[] __read_mostly = { | ||
41 | 0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa | ||
42 | }; | ||
43 | static u16 green8[] __read_mostly = { | ||
44 | 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa | ||
45 | }; | ||
46 | static u16 blue8[] __read_mostly = { | ||
47 | 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa | ||
48 | }; | ||
49 | |||
50 | static u16 red16[] __read_mostly = { | ||
51 | 0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa, | ||
52 | 0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff | ||
53 | }; | ||
54 | static u16 green16[] __read_mostly = { | ||
55 | 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa, | ||
56 | 0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff | ||
57 | }; | ||
58 | static u16 blue16[] __read_mostly = { | ||
59 | 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, | ||
60 | 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff, 0x5555, 0xffff | ||
61 | }; | ||
62 | |||
63 | static const struct fb_cmap default_2_colors = { | ||
64 | .len=2, .red=red2, .green=green2, .blue=blue2 | ||
65 | }; | ||
66 | static const struct fb_cmap default_8_colors = { | ||
67 | .len=8, .red=red8, .green=green8, .blue=blue8 | ||
68 | }; | ||
69 | static const struct fb_cmap default_4_colors = { | ||
70 | .len=4, .red=red4, .green=green4, .blue=blue4 | ||
71 | }; | ||
72 | static const struct fb_cmap default_16_colors = { | ||
73 | .len=16, .red=red16, .green=green16, .blue=blue16 | ||
74 | }; | ||
75 | |||
76 | |||
77 | |||
78 | /** | ||
79 | * fb_alloc_cmap - allocate a colormap | ||
80 | * @cmap: frame buffer colormap structure | ||
81 | * @len: length of @cmap | ||
82 | * @transp: boolean, 1 if there is transparency, 0 otherwise | ||
83 | * @flags: flags for kmalloc memory allocation | ||
84 | * | ||
85 | * Allocates memory for a colormap @cmap. @len is the | ||
86 | * number of entries in the palette. | ||
87 | * | ||
88 | * Returns negative errno on error, or zero on success. | ||
89 | * | ||
90 | */ | ||
91 | |||
92 | int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags) | ||
93 | { | ||
94 | int size = len * sizeof(u16); | ||
95 | int ret = -ENOMEM; | ||
96 | |||
97 | if (cmap->len != len) { | ||
98 | fb_dealloc_cmap(cmap); | ||
99 | if (!len) | ||
100 | return 0; | ||
101 | |||
102 | cmap->red = kmalloc(size, flags); | ||
103 | if (!cmap->red) | ||
104 | goto fail; | ||
105 | cmap->green = kmalloc(size, flags); | ||
106 | if (!cmap->green) | ||
107 | goto fail; | ||
108 | cmap->blue = kmalloc(size, flags); | ||
109 | if (!cmap->blue) | ||
110 | goto fail; | ||
111 | if (transp) { | ||
112 | cmap->transp = kmalloc(size, flags); | ||
113 | if (!cmap->transp) | ||
114 | goto fail; | ||
115 | } else { | ||
116 | cmap->transp = NULL; | ||
117 | } | ||
118 | } | ||
119 | cmap->start = 0; | ||
120 | cmap->len = len; | ||
121 | ret = fb_copy_cmap(fb_default_cmap(len), cmap); | ||
122 | if (ret) | ||
123 | goto fail; | ||
124 | return 0; | ||
125 | |||
126 | fail: | ||
127 | fb_dealloc_cmap(cmap); | ||
128 | return ret; | ||
129 | } | ||
130 | |||
131 | int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp) | ||
132 | { | ||
133 | return fb_alloc_cmap_gfp(cmap, len, transp, GFP_ATOMIC); | ||
134 | } | ||
135 | |||
136 | /** | ||
137 | * fb_dealloc_cmap - deallocate a colormap | ||
138 | * @cmap: frame buffer colormap structure | ||
139 | * | ||
140 | * Deallocates a colormap that was previously allocated with | ||
141 | * fb_alloc_cmap(). | ||
142 | * | ||
143 | */ | ||
144 | |||
145 | void fb_dealloc_cmap(struct fb_cmap *cmap) | ||
146 | { | ||
147 | kfree(cmap->red); | ||
148 | kfree(cmap->green); | ||
149 | kfree(cmap->blue); | ||
150 | kfree(cmap->transp); | ||
151 | |||
152 | cmap->red = cmap->green = cmap->blue = cmap->transp = NULL; | ||
153 | cmap->len = 0; | ||
154 | } | ||
155 | |||
156 | /** | ||
157 | * fb_copy_cmap - copy a colormap | ||
158 | * @from: frame buffer colormap structure | ||
159 | * @to: frame buffer colormap structure | ||
160 | * | ||
161 | * Copy contents of colormap from @from to @to. | ||
162 | */ | ||
163 | |||
164 | int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to) | ||
165 | { | ||
166 | int tooff = 0, fromoff = 0; | ||
167 | int size; | ||
168 | |||
169 | if (to->start > from->start) | ||
170 | fromoff = to->start - from->start; | ||
171 | else | ||
172 | tooff = from->start - to->start; | ||
173 | size = to->len - tooff; | ||
174 | if (size > (int) (from->len - fromoff)) | ||
175 | size = from->len - fromoff; | ||
176 | if (size <= 0) | ||
177 | return -EINVAL; | ||
178 | size *= sizeof(u16); | ||
179 | |||
180 | memcpy(to->red+tooff, from->red+fromoff, size); | ||
181 | memcpy(to->green+tooff, from->green+fromoff, size); | ||
182 | memcpy(to->blue+tooff, from->blue+fromoff, size); | ||
183 | if (from->transp && to->transp) | ||
184 | memcpy(to->transp+tooff, from->transp+fromoff, size); | ||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to) | ||
189 | { | ||
190 | int tooff = 0, fromoff = 0; | ||
191 | int size; | ||
192 | |||
193 | if (to->start > from->start) | ||
194 | fromoff = to->start - from->start; | ||
195 | else | ||
196 | tooff = from->start - to->start; | ||
197 | size = to->len - tooff; | ||
198 | if (size > (int) (from->len - fromoff)) | ||
199 | size = from->len - fromoff; | ||
200 | if (size <= 0) | ||
201 | return -EINVAL; | ||
202 | size *= sizeof(u16); | ||
203 | |||
204 | if (copy_to_user(to->red+tooff, from->red+fromoff, size)) | ||
205 | return -EFAULT; | ||
206 | if (copy_to_user(to->green+tooff, from->green+fromoff, size)) | ||
207 | return -EFAULT; | ||
208 | if (copy_to_user(to->blue+tooff, from->blue+fromoff, size)) | ||
209 | return -EFAULT; | ||
210 | if (from->transp && to->transp) | ||
211 | if (copy_to_user(to->transp+tooff, from->transp+fromoff, size)) | ||
212 | return -EFAULT; | ||
213 | return 0; | ||
214 | } | ||
215 | |||
216 | /** | ||
217 | * fb_set_cmap - set the colormap | ||
218 | * @cmap: frame buffer colormap structure | ||
219 | * @info: frame buffer info structure | ||
220 | * | ||
221 | * Sets the colormap @cmap for a screen of device @info. | ||
222 | * | ||
223 | * Returns negative errno on error, or zero on success. | ||
224 | * | ||
225 | */ | ||
226 | |||
227 | int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info) | ||
228 | { | ||
229 | int i, start, rc = 0; | ||
230 | u16 *red, *green, *blue, *transp; | ||
231 | u_int hred, hgreen, hblue, htransp = 0xffff; | ||
232 | |||
233 | red = cmap->red; | ||
234 | green = cmap->green; | ||
235 | blue = cmap->blue; | ||
236 | transp = cmap->transp; | ||
237 | start = cmap->start; | ||
238 | |||
239 | if (start < 0 || (!info->fbops->fb_setcolreg && | ||
240 | !info->fbops->fb_setcmap)) | ||
241 | return -EINVAL; | ||
242 | if (info->fbops->fb_setcmap) { | ||
243 | rc = info->fbops->fb_setcmap(cmap, info); | ||
244 | } else { | ||
245 | for (i = 0; i < cmap->len; i++) { | ||
246 | hred = *red++; | ||
247 | hgreen = *green++; | ||
248 | hblue = *blue++; | ||
249 | if (transp) | ||
250 | htransp = *transp++; | ||
251 | if (info->fbops->fb_setcolreg(start++, | ||
252 | hred, hgreen, hblue, | ||
253 | htransp, info)) | ||
254 | break; | ||
255 | } | ||
256 | } | ||
257 | if (rc == 0) | ||
258 | fb_copy_cmap(cmap, &info->cmap); | ||
259 | |||
260 | return rc; | ||
261 | } | ||
262 | |||
263 | int fb_set_user_cmap(struct fb_cmap_user *cmap, struct fb_info *info) | ||
264 | { | ||
265 | int rc, size = cmap->len * sizeof(u16); | ||
266 | struct fb_cmap umap; | ||
267 | |||
268 | if (size < 0 || size < cmap->len) | ||
269 | return -E2BIG; | ||
270 | |||
271 | memset(&umap, 0, sizeof(struct fb_cmap)); | ||
272 | rc = fb_alloc_cmap_gfp(&umap, cmap->len, cmap->transp != NULL, | ||
273 | GFP_KERNEL); | ||
274 | if (rc) | ||
275 | return rc; | ||
276 | if (copy_from_user(umap.red, cmap->red, size) || | ||
277 | copy_from_user(umap.green, cmap->green, size) || | ||
278 | copy_from_user(umap.blue, cmap->blue, size) || | ||
279 | (cmap->transp && copy_from_user(umap.transp, cmap->transp, size))) { | ||
280 | rc = -EFAULT; | ||
281 | goto out; | ||
282 | } | ||
283 | umap.start = cmap->start; | ||
284 | if (!lock_fb_info(info)) { | ||
285 | rc = -ENODEV; | ||
286 | goto out; | ||
287 | } | ||
288 | |||
289 | rc = fb_set_cmap(&umap, info); | ||
290 | unlock_fb_info(info); | ||
291 | out: | ||
292 | fb_dealloc_cmap(&umap); | ||
293 | return rc; | ||
294 | } | ||
295 | |||
296 | /** | ||
297 | * fb_default_cmap - get default colormap | ||
298 | * @len: size of palette for a depth | ||
299 | * | ||
300 | * Gets the default colormap for a specific screen depth. @len | ||
301 | * is the size of the palette for a particular screen depth. | ||
302 | * | ||
303 | * Returns pointer to a frame buffer colormap structure. | ||
304 | * | ||
305 | */ | ||
306 | |||
307 | const struct fb_cmap *fb_default_cmap(int len) | ||
308 | { | ||
309 | if (len <= 2) | ||
310 | return &default_2_colors; | ||
311 | if (len <= 4) | ||
312 | return &default_4_colors; | ||
313 | if (len <= 8) | ||
314 | return &default_8_colors; | ||
315 | return &default_16_colors; | ||
316 | } | ||
317 | |||
318 | |||
319 | /** | ||
320 | * fb_invert_cmaps - invert all defaults colormaps | ||
321 | * | ||
322 | * Invert all default colormaps. | ||
323 | * | ||
324 | */ | ||
325 | |||
326 | void fb_invert_cmaps(void) | ||
327 | { | ||
328 | u_int i; | ||
329 | |||
330 | for (i = 0; i < ARRAY_SIZE(red2); i++) { | ||
331 | red2[i] = ~red2[i]; | ||
332 | green2[i] = ~green2[i]; | ||
333 | blue2[i] = ~blue2[i]; | ||
334 | } | ||
335 | for (i = 0; i < ARRAY_SIZE(red4); i++) { | ||
336 | red4[i] = ~red4[i]; | ||
337 | green4[i] = ~green4[i]; | ||
338 | blue4[i] = ~blue4[i]; | ||
339 | } | ||
340 | for (i = 0; i < ARRAY_SIZE(red8); i++) { | ||
341 | red8[i] = ~red8[i]; | ||
342 | green8[i] = ~green8[i]; | ||
343 | blue8[i] = ~blue8[i]; | ||
344 | } | ||
345 | for (i = 0; i < ARRAY_SIZE(red16); i++) { | ||
346 | red16[i] = ~red16[i]; | ||
347 | green16[i] = ~green16[i]; | ||
348 | blue16[i] = ~blue16[i]; | ||
349 | } | ||
350 | } | ||
351 | |||
352 | |||
353 | /* | ||
354 | * Visible symbols for modules | ||
355 | */ | ||
356 | |||
357 | EXPORT_SYMBOL(fb_alloc_cmap); | ||
358 | EXPORT_SYMBOL(fb_dealloc_cmap); | ||
359 | EXPORT_SYMBOL(fb_copy_cmap); | ||
360 | EXPORT_SYMBOL(fb_set_cmap); | ||
361 | EXPORT_SYMBOL(fb_default_cmap); | ||
362 | EXPORT_SYMBOL(fb_invert_cmaps); | ||