diff options
-rw-r--r-- | Documentation/fb/sm501.txt | 10 | ||||
-rw-r--r-- | drivers/video/sm501fb.c | 65 |
2 files changed, 70 insertions, 5 deletions
diff --git a/Documentation/fb/sm501.txt b/Documentation/fb/sm501.txt new file mode 100644 index 00000000000..8d17aebd264 --- /dev/null +++ b/Documentation/fb/sm501.txt | |||
@@ -0,0 +1,10 @@ | |||
1 | Configuration: | ||
2 | |||
3 | You can pass the following kernel command line options to sm501 videoframebuffer: | ||
4 | |||
5 | sm501fb.bpp= SM501 Display driver: | ||
6 | Specifiy bits-per-pixel if not specified by 'mode' | ||
7 | |||
8 | sm501fb.mode= SM501 Display driver: | ||
9 | Specify resolution as | ||
10 | "<xres>x<yres>[-<bpp>][@<refresh>]" | ||
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index 5df406c87c5..f31252ce889 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c | |||
@@ -41,6 +41,26 @@ | |||
41 | #include <linux/sm501.h> | 41 | #include <linux/sm501.h> |
42 | #include <linux/sm501-regs.h> | 42 | #include <linux/sm501-regs.h> |
43 | 43 | ||
44 | #include "edid.h" | ||
45 | |||
46 | static char *fb_mode = "640x480-16@60"; | ||
47 | static unsigned long default_bpp = 16; | ||
48 | |||
49 | static struct fb_videomode __devinitdata sm501_default_mode = { | ||
50 | .refresh = 60, | ||
51 | .xres = 640, | ||
52 | .yres = 480, | ||
53 | .pixclock = 20833, | ||
54 | .left_margin = 142, | ||
55 | .right_margin = 13, | ||
56 | .upper_margin = 21, | ||
57 | .lower_margin = 1, | ||
58 | .hsync_len = 69, | ||
59 | .vsync_len = 3, | ||
60 | .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | ||
61 | .vmode = FB_VMODE_NONINTERLACED | ||
62 | }; | ||
63 | |||
44 | #define NR_PALETTE 256 | 64 | #define NR_PALETTE 256 |
45 | 65 | ||
46 | enum sm501_controller { | 66 | enum sm501_controller { |
@@ -77,6 +97,7 @@ struct sm501fb_info { | |||
77 | void __iomem *regs2d; /* 2d remapped registers */ | 97 | void __iomem *regs2d; /* 2d remapped registers */ |
78 | void __iomem *fbmem; /* remapped framebuffer */ | 98 | void __iomem *fbmem; /* remapped framebuffer */ |
79 | size_t fbmem_len; /* length of remapped region */ | 99 | size_t fbmem_len; /* length of remapped region */ |
100 | u8 *edid_data; | ||
80 | }; | 101 | }; |
81 | 102 | ||
82 | /* per-framebuffer private data */ | 103 | /* per-framebuffer private data */ |
@@ -1725,9 +1746,16 @@ static int sm501fb_init_fb(struct fb_info *fb, | |||
1725 | fb->var.vmode = FB_VMODE_NONINTERLACED; | 1746 | fb->var.vmode = FB_VMODE_NONINTERLACED; |
1726 | fb->var.bits_per_pixel = 16; | 1747 | fb->var.bits_per_pixel = 16; |
1727 | 1748 | ||
1749 | if (info->edid_data) { | ||
1750 | /* Now build modedb from EDID */ | ||
1751 | fb_edid_to_monspecs(info->edid_data, &fb->monspecs); | ||
1752 | fb_videomode_to_modelist(fb->monspecs.modedb, | ||
1753 | fb->monspecs.modedb_len, | ||
1754 | &fb->modelist); | ||
1755 | } | ||
1756 | |||
1728 | if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) { | 1757 | if (enable && (pd->flags & SM501FB_FLAG_USE_INIT_MODE) && 0) { |
1729 | /* TODO read the mode from the current display */ | 1758 | /* TODO read the mode from the current display */ |
1730 | |||
1731 | } else { | 1759 | } else { |
1732 | if (pd->def_mode) { | 1760 | if (pd->def_mode) { |
1733 | dev_info(info->dev, "using supplied mode\n"); | 1761 | dev_info(info->dev, "using supplied mode\n"); |
@@ -1737,12 +1765,34 @@ static int sm501fb_init_fb(struct fb_info *fb, | |||
1737 | fb->var.xres_virtual = fb->var.xres; | 1765 | fb->var.xres_virtual = fb->var.xres; |
1738 | fb->var.yres_virtual = fb->var.yres; | 1766 | fb->var.yres_virtual = fb->var.yres; |
1739 | } else { | 1767 | } else { |
1740 | ret = fb_find_mode(&fb->var, fb, | 1768 | if (info->edid_data) |
1769 | ret = fb_find_mode(&fb->var, fb, fb_mode, | ||
1770 | fb->monspecs.modedb, | ||
1771 | fb->monspecs.modedb_len, | ||
1772 | &sm501_default_mode, default_bpp); | ||
1773 | else | ||
1774 | ret = fb_find_mode(&fb->var, fb, | ||
1741 | NULL, NULL, 0, NULL, 8); | 1775 | NULL, NULL, 0, NULL, 8); |
1742 | 1776 | ||
1743 | if (ret == 0 || ret == 4) { | 1777 | switch (ret) { |
1744 | dev_err(info->dev, | 1778 | case 1: |
1745 | "failed to get initial mode\n"); | 1779 | dev_info(info->dev, "using mode specified in " |
1780 | "@mode\n"); | ||
1781 | break; | ||
1782 | case 2: | ||
1783 | dev_info(info->dev, "using mode specified in " | ||
1784 | "@mode with ignored refresh rate\n"); | ||
1785 | break; | ||
1786 | case 3: | ||
1787 | dev_info(info->dev, "using mode default " | ||
1788 | "mode\n"); | ||
1789 | break; | ||
1790 | case 4: | ||
1791 | dev_info(info->dev, "using mode from list\n"); | ||
1792 | break; | ||
1793 | default: | ||
1794 | dev_info(info->dev, "ret = %d\n", ret); | ||
1795 | dev_info(info->dev, "failed to find mode\n"); | ||
1746 | return -EINVAL; | 1796 | return -EINVAL; |
1747 | } | 1797 | } |
1748 | } | 1798 | } |
@@ -2157,6 +2207,11 @@ static void __exit sm501fb_cleanup(void) | |||
2157 | module_init(sm501fb_init); | 2207 | module_init(sm501fb_init); |
2158 | module_exit(sm501fb_cleanup); | 2208 | module_exit(sm501fb_cleanup); |
2159 | 2209 | ||
2210 | module_param_named(mode, fb_mode, charp, 0); | ||
2211 | MODULE_PARM_DESC(mode, | ||
2212 | "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); | ||
2213 | module_param_named(bpp, default_bpp, ulong, 0); | ||
2214 | MODULE_PARM_DESC(bpp, "Specify bit-per-pixel if not specified mode"); | ||
2160 | MODULE_AUTHOR("Ben Dooks, Vincent Sanders"); | 2215 | MODULE_AUTHOR("Ben Dooks, Vincent Sanders"); |
2161 | MODULE_DESCRIPTION("SM501 Framebuffer driver"); | 2216 | MODULE_DESCRIPTION("SM501 Framebuffer driver"); |
2162 | MODULE_LICENSE("GPL v2"); | 2217 | MODULE_LICENSE("GPL v2"); |