diff options
author | Heiko Schocher <hs@denx.de> | 2011-01-26 02:21:30 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2011-03-22 04:17:14 -0400 |
commit | 4295f9bf74a885da390abc49a3b42a011c1bb890 (patch) | |
tree | 6ac387cbdcacd8708611acbaab72dad1b783c90e | |
parent | e6a049807105decf5aa7f0c510f5e5ec96c3548e (diff) |
video, sm501: add OF binding to support SM501
- add binding to OF, compatible name "smi,sm501"
Signed-off-by: Heiko Schocher <hs@denx.de>
cc: linux-fbdev@vger.kernel.org
cc: devicetree-discuss@ozlabs.org
cc: Ben Dooks <ben@simtec.co.uk>
cc: Vincent Sanders <vince@simtec.co.uk>
cc: Samuel Ortiz <sameo@linux.intel.com>
cc: linux-kernel@vger.kernel.org
cc: Randy Dunlap <rdunlap@xenotime.net>
cc: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
-rw-r--r-- | Documentation/powerpc/dts-bindings/sm501.txt | 34 | ||||
-rw-r--r-- | drivers/mfd/sm501.c | 9 | ||||
-rw-r--r-- | drivers/video/sm501fb.c | 42 |
3 files changed, 81 insertions, 4 deletions
diff --git a/Documentation/powerpc/dts-bindings/sm501.txt b/Documentation/powerpc/dts-bindings/sm501.txt new file mode 100644 index 000000000000..7d319fba9b5b --- /dev/null +++ b/Documentation/powerpc/dts-bindings/sm501.txt | |||
@@ -0,0 +1,34 @@ | |||
1 | * SM SM501 | ||
2 | |||
3 | The SM SM501 is a LCD controller, with proper hardware, it can also | ||
4 | drive DVI monitors. | ||
5 | |||
6 | Required properties: | ||
7 | - compatible : should be "smi,sm501". | ||
8 | - reg : contain two entries: | ||
9 | - First entry: System Configuration register | ||
10 | - Second entry: IO space (Display Controller register) | ||
11 | - interrupts : SMI interrupt to the cpu should be described here. | ||
12 | - interrupt-parent : the phandle for the interrupt controller that | ||
13 | services interrupts for this device. | ||
14 | |||
15 | Optional properties: | ||
16 | - mode : select a video mode: | ||
17 | <xres>x<yres>[-<bpp>][@<refresh>] | ||
18 | - edid : verbatim EDID data block describing attached display. | ||
19 | Data from the detailed timing descriptor will be used to | ||
20 | program the display controller. | ||
21 | - little-endian: availiable on big endian systems, to | ||
22 | set different foreign endian. | ||
23 | - big-endian: availiable on little endian systems, to | ||
24 | set different foreign endian. | ||
25 | |||
26 | Example for MPC5200: | ||
27 | display@1,0 { | ||
28 | compatible = "smi,sm501"; | ||
29 | reg = <1 0x00000000 0x00800000 | ||
30 | 1 0x03e00000 0x00200000>; | ||
31 | interrupts = <1 1 3>; | ||
32 | mode = "640x480-32@60"; | ||
33 | edid = [edid-data]; | ||
34 | }; | ||
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c index 558d5f3f6d02..df3702c1756d 100644 --- a/drivers/mfd/sm501.c +++ b/drivers/mfd/sm501.c | |||
@@ -1377,7 +1377,7 @@ static int __devinit sm501_init_dev(struct sm501_devdata *sm) | |||
1377 | sm501_register_gpio(sm); | 1377 | sm501_register_gpio(sm); |
1378 | } | 1378 | } |
1379 | 1379 | ||
1380 | if (pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) { | 1380 | if (pdata && pdata->gpio_i2c != NULL && pdata->gpio_i2c_nr > 0) { |
1381 | if (!sm501_gpio_isregistered(sm)) | 1381 | if (!sm501_gpio_isregistered(sm)) |
1382 | dev_err(sm->dev, "no gpio available for i2c gpio.\n"); | 1382 | dev_err(sm->dev, "no gpio available for i2c gpio.\n"); |
1383 | else | 1383 | else |
@@ -1422,6 +1422,7 @@ static int __devinit sm501_plat_probe(struct platform_device *dev) | |||
1422 | 1422 | ||
1423 | sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1); | 1423 | sm->io_res = platform_get_resource(dev, IORESOURCE_MEM, 1); |
1424 | sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0); | 1424 | sm->mem_res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
1425 | |||
1425 | if (sm->io_res == NULL || sm->mem_res == NULL) { | 1426 | if (sm->io_res == NULL || sm->mem_res == NULL) { |
1426 | dev_err(&dev->dev, "failed to get IO resource\n"); | 1427 | dev_err(&dev->dev, "failed to get IO resource\n"); |
1427 | ret = -ENOENT; | 1428 | ret = -ENOENT; |
@@ -1735,10 +1736,16 @@ static struct pci_driver sm501_pci_driver = { | |||
1735 | 1736 | ||
1736 | MODULE_ALIAS("platform:sm501"); | 1737 | MODULE_ALIAS("platform:sm501"); |
1737 | 1738 | ||
1739 | static struct of_device_id __devinitdata of_sm501_match_tbl[] = { | ||
1740 | { .compatible = "smi,sm501", }, | ||
1741 | { /* end */ } | ||
1742 | }; | ||
1743 | |||
1738 | static struct platform_driver sm501_plat_driver = { | 1744 | static struct platform_driver sm501_plat_driver = { |
1739 | .driver = { | 1745 | .driver = { |
1740 | .name = "sm501", | 1746 | .name = "sm501", |
1741 | .owner = THIS_MODULE, | 1747 | .owner = THIS_MODULE, |
1748 | .of_match_table = of_sm501_match_tbl, | ||
1742 | }, | 1749 | }, |
1743 | .probe = sm501_plat_probe, | 1750 | .probe = sm501_plat_probe, |
1744 | .remove = sm501_plat_remove, | 1751 | .remove = sm501_plat_remove, |
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index f31252ce8892..46d1a64fe80d 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c | |||
@@ -1729,6 +1729,15 @@ static int sm501fb_init_fb(struct fb_info *fb, | |||
1729 | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | | 1729 | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | |
1730 | FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; | 1730 | FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; |
1731 | 1731 | ||
1732 | #if defined(CONFIG_OF) | ||
1733 | #ifdef __BIG_ENDIAN | ||
1734 | if (of_get_property(info->dev->parent->of_node, "little-endian", NULL)) | ||
1735 | fb->flags |= FBINFO_FOREIGN_ENDIAN; | ||
1736 | #else | ||
1737 | if (of_get_property(info->dev->parent->of_node, "big-endian", NULL)) | ||
1738 | fb->flags |= FBINFO_FOREIGN_ENDIAN; | ||
1739 | #endif | ||
1740 | #endif | ||
1732 | /* fixed data */ | 1741 | /* fixed data */ |
1733 | 1742 | ||
1734 | fb->fix.type = FB_TYPE_PACKED_PIXELS; | 1743 | fb->fix.type = FB_TYPE_PACKED_PIXELS; |
@@ -1765,14 +1774,17 @@ static int sm501fb_init_fb(struct fb_info *fb, | |||
1765 | fb->var.xres_virtual = fb->var.xres; | 1774 | fb->var.xres_virtual = fb->var.xres; |
1766 | fb->var.yres_virtual = fb->var.yres; | 1775 | fb->var.yres_virtual = fb->var.yres; |
1767 | } else { | 1776 | } else { |
1768 | if (info->edid_data) | 1777 | if (info->edid_data) { |
1769 | ret = fb_find_mode(&fb->var, fb, fb_mode, | 1778 | ret = fb_find_mode(&fb->var, fb, fb_mode, |
1770 | fb->monspecs.modedb, | 1779 | fb->monspecs.modedb, |
1771 | fb->monspecs.modedb_len, | 1780 | fb->monspecs.modedb_len, |
1772 | &sm501_default_mode, default_bpp); | 1781 | &sm501_default_mode, default_bpp); |
1773 | else | 1782 | /* edid_data is no longer needed, free it */ |
1783 | kfree(info->edid_data); | ||
1784 | } else { | ||
1774 | ret = fb_find_mode(&fb->var, fb, | 1785 | ret = fb_find_mode(&fb->var, fb, |
1775 | NULL, NULL, 0, NULL, 8); | 1786 | NULL, NULL, 0, NULL, 8); |
1787 | } | ||
1776 | 1788 | ||
1777 | switch (ret) { | 1789 | switch (ret) { |
1778 | case 1: | 1790 | case 1: |
@@ -1933,8 +1945,32 @@ static int __devinit sm501fb_probe(struct platform_device *pdev) | |||
1933 | } | 1945 | } |
1934 | 1946 | ||
1935 | if (info->pdata == NULL) { | 1947 | if (info->pdata == NULL) { |
1936 | dev_info(dev, "using default configuration data\n"); | 1948 | int found = 0; |
1949 | #if defined(CONFIG_OF) | ||
1950 | struct device_node *np = pdev->dev.parent->of_node; | ||
1951 | const u8 *prop; | ||
1952 | const char *cp; | ||
1953 | int len; | ||
1954 | |||
1937 | info->pdata = &sm501fb_def_pdata; | 1955 | info->pdata = &sm501fb_def_pdata; |
1956 | if (np) { | ||
1957 | /* Get EDID */ | ||
1958 | cp = of_get_property(np, "mode", &len); | ||
1959 | if (cp) | ||
1960 | strcpy(fb_mode, cp); | ||
1961 | prop = of_get_property(np, "edid", &len); | ||
1962 | if (prop && len == EDID_LENGTH) { | ||
1963 | info->edid_data = kmemdup(prop, EDID_LENGTH, | ||
1964 | GFP_KERNEL); | ||
1965 | if (info->edid_data) | ||
1966 | found = 1; | ||
1967 | } | ||
1968 | } | ||
1969 | #endif | ||
1970 | if (!found) { | ||
1971 | dev_info(dev, "using default configuration data\n"); | ||
1972 | info->pdata = &sm501fb_def_pdata; | ||
1973 | } | ||
1938 | } | 1974 | } |
1939 | 1975 | ||
1940 | /* probe for the presence of each panel */ | 1976 | /* probe for the presence of each panel */ |