0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/module.h>
0014 #include <linux/kernel.h>
0015 #include <linux/delay.h>
0016 #include <linux/gfp.h>
0017 #include <linux/pci.h>
0018 #include <linux/fb.h>
0019
0020 #include <asm/io.h>
0021
0022 #include "nv_type.h"
0023 #include "nv_local.h"
0024 #include "nv_proto.h"
0025
0026 #include "../edid.h"
0027
0028 int nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid)
0029 {
0030 struct nvidia_par *par = info->par;
0031 struct device_node *parent, *dp;
0032 const unsigned char *pedid = NULL;
0033 static char *propnames[] = {
0034 "DFP,EDID", "LCD,EDID", "EDID", "EDID1",
0035 "EDID,B", "EDID,A", NULL };
0036 int i;
0037
0038 parent = pci_device_to_OF_node(par->pci_dev);
0039 if (parent == NULL)
0040 return -1;
0041 if (par->twoHeads) {
0042 const char *pname;
0043 int len;
0044
0045 for_each_child_of_node(parent, dp) {
0046 pname = of_get_property(dp, "name", NULL);
0047 if (!pname)
0048 continue;
0049 len = strlen(pname);
0050 if ((pname[len-1] == 'A' && conn == 1) ||
0051 (pname[len-1] == 'B' && conn == 2)) {
0052 for (i = 0; propnames[i] != NULL; ++i) {
0053 pedid = of_get_property(dp,
0054 propnames[i], NULL);
0055 if (pedid != NULL)
0056 break;
0057 }
0058 of_node_put(dp);
0059 break;
0060 }
0061 }
0062 }
0063 if (pedid == NULL) {
0064 for (i = 0; propnames[i] != NULL; ++i) {
0065 pedid = of_get_property(parent, propnames[i], NULL);
0066 if (pedid != NULL)
0067 break;
0068 }
0069 }
0070 if (pedid) {
0071 *out_edid = kmemdup(pedid, EDID_LENGTH, GFP_KERNEL);
0072 if (*out_edid == NULL)
0073 return -1;
0074 printk(KERN_DEBUG "nvidiafb: Found OF EDID for head %d\n", conn);
0075 return 0;
0076 }
0077 return -1;
0078 }