17 #include <linux/module.h>
18 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/string.h>
22 #include <linux/slab.h>
30 #include <linux/wait.h>
40 #define DRIVER_NAME "wm8505-fb"
42 #define to_wm8505fb_info(__info) container_of(__info, \
43 struct wm8505fb_info, fb)
58 for (i = 0; i < 0x200; i += 4)
86 static int wm8505fb_set_timing(
struct fb_info *
info)
90 int h_start = info->
var.left_margin;
91 int h_end = h_start + info->
var.xres;
92 int h_all = h_end + info->
var.right_margin;
93 int h_sync = info->
var.hsync_len;
95 int v_start = info->
var.upper_margin;
96 int v_end = v_start + info->
var.yres;
97 int v_all = v_end + info->
var.lower_margin;
98 int v_sync = info->
var.vsync_len;
125 if (info->
var.bits_per_pixel == 32) {
126 info->
var.red.offset = 16;
127 info->
var.red.length = 8;
128 info->
var.red.msb_right = 0;
129 info->
var.green.offset = 8;
130 info->
var.green.length = 8;
131 info->
var.green.msb_right = 0;
132 info->
var.blue.offset = 0;
133 info->
var.blue.length = 8;
134 info->
var.blue.msb_right = 0;
136 info->
fix.line_length = info->
var.xres_virtual << 2;
137 }
else if (info->
var.bits_per_pixel == 16) {
138 info->
var.red.offset = 11;
139 info->
var.red.length = 5;
140 info->
var.red.msb_right = 0;
141 info->
var.green.offset = 5;
142 info->
var.green.length = 6;
143 info->
var.green.msb_right = 0;
144 info->
var.blue.offset = 0;
145 info->
var.blue.length = 5;
146 info->
var.blue.msb_right = 0;
148 info->
fix.line_length = info->
var.xres_virtual << 1;
151 wm8505fb_set_timing(info);
180 wm8505fb_set_par(info);
191 return chan << bf->
offset;
194 static int wm8505fb_setcolreg(
unsigned regno,
unsigned red,
unsigned green,
203 if (info->
var.grayscale)
205 (19595 * red + 38470 * green + 7471 *
blue) >> 16;
207 switch (fbi->
fb.fix.visual) {
212 val = chan_to_field(red, &fbi->
fb.var.red);
213 val |= chan_to_field(green, &fbi->
fb.var.green);
214 val |= chan_to_field(blue, &fbi->
fb.var.blue);
235 static int wm8505fb_blank(
int blank,
struct fb_info *info)
241 wm8505fb_set_timing(info);
251 static struct fb_ops wm8505fb_ops = {
253 .fb_set_par = wm8505fb_set_par,
254 .fb_setcolreg = wm8505fb_setcolreg,
259 .fb_pan_display = wm8505fb_pan_display,
260 .fb_blank = wm8505fb_blank,
274 unsigned long fb_mem_len;
283 dev_err(&pdev->
dev,
"Failed to initialize framebuffer device\n");
291 fbi->
fb.fix.xpanstep = 1;
292 fbi->
fb.fix.ypanstep = 1;
293 fbi->
fb.fix.ywrapstep = 0;
296 fbi->
fb.fbops = &wm8505fb_ops;
308 fbi->
fb.pseudo_palette =
addr;
312 dev_err(&pdev->
dev,
"no I/O memory resource defined\n");
319 dev_err(&pdev->
dev,
"failed to request I/O memory\n");
326 dev_err(&pdev->
dev,
"failed to map I/O memory\n");
328 goto failed_free_res;
333 pr_err(
"%s: No display description in Device Tree\n", __func__);
335 goto failed_free_res;
343 ret |= of_property_read_u32(np,
"hactive", &of_mode.xres);
344 ret |= of_property_read_u32(np,
"vactive", &of_mode.yres);
345 ret |= of_property_read_u32(np,
"hback-porch", &of_mode.left_margin);
346 ret |= of_property_read_u32(np,
"hfront-porch", &of_mode.right_margin);
347 ret |= of_property_read_u32(np,
"hsync-len", &of_mode.hsync_len);
348 ret |= of_property_read_u32(np,
"vback-porch", &of_mode.upper_margin);
349 ret |= of_property_read_u32(np,
"vfront-porch", &of_mode.lower_margin);
350 ret |= of_property_read_u32(np,
"vsync-len", &of_mode.vsync_len);
351 ret |= of_property_read_u32(np,
"bpp", &bpp);
353 pr_err(
"%s: Unable to read display properties\n", __func__);
354 goto failed_free_res;
360 fbi->
fb.var.nonstd = 0;
363 fbi->
fb.var.height = -1;
364 fbi->
fb.var.width = -1;
367 fb_mem_len = of_mode.xres * of_mode.yres * 2 * (bpp / 8);
371 pr_err(
"%s: Failed to allocate framebuffer\n", __func__);
375 fbi->
fb.var.xres_virtual = of_mode.xres;
376 fbi->
fb.var.yres_virtual = of_mode.yres * 2;
377 fbi->
fb.var.bits_per_pixel =
bpp;
379 fbi->
fb.fix.smem_start = fb_mem_phys;
380 fbi->
fb.fix.smem_len = fb_mem_len;
381 fbi->
fb.screen_base = fb_mem_virt;
382 fbi->
fb.screen_size = fb_mem_len;
385 dev_err(&pdev->
dev,
"Failed to allocate color map\n");
390 wm8505fb_init_hw(&fbi->
fb);
393 ret = wm8505fb_set_par(&fbi->
fb);
395 dev_err(&pdev->
dev,
"Failed to set parameters\n");
396 goto failed_free_cmap;
399 platform_set_drvdata(pdev, fbi);
404 "Failed to register framebuffer device: %d\n", ret);
405 goto failed_free_cmap;
415 fbi->
fb.node, fbi->
fb.fix.id, fbi->
fb.fix.smem_start,
416 fbi->
fb.fix.smem_start + fbi->
fb.fix.smem_len - 1);
421 if (fbi->
fb.cmap.len)
428 platform_set_drvdata(pdev,
NULL);
445 if (fbi->
fb.cmap.len)
459 { .compatible =
"wm,wm8505-fb", },
464 .probe = wm8505fb_probe,