150472Speter/* 27130Srgrimes * linux/drivers/video/nvidia/nv_of.c 350203Srgrimes * 450203Srgrimes * Copyright 2004 Antonino A. Daplas <adaplas @pol.net> 57130Srgrimes * 639161Sobrien * Based on rivafb-i2c.c 78571Srgrimes * 88571Srgrimes * This file is subject to the terms and conditions of the GNU General Public 97130Srgrimes * License. See the file COPYING in the main directory of this archive 1039250Sgibbs * for more details. 1139250Sgibbs */ 1239250Sgibbs 1339250Sgibbs#include <linux/module.h> 1456583Sn_hibma#include <linux/kernel.h> 1560724Speter#include <linux/delay.h> 1660724Speter#include <linux/gfp.h> 1756583Sn_hibma#include <linux/pci.h> 1856583Sn_hibma#include <linux/fb.h> 1956583Sn_hibma 208571Srgrimes#include <asm/io.h> 2123271Sbde 2223271Sbde#include "nv_type.h" 237130Srgrimes#include "nv_local.h" 2426453Sache#include "nv_proto.h" 2526453Sache 2626453Sache#include "../edid.h" 2726453Sache 2826453Sacheint nvidia_probe_of_connector(struct fb_info *info, int conn, u8 **out_edid) 2926453Sache{ 3026453Sache struct nvidia_par *par = info->par; 3126453Sache struct device_node *parent, *dp; 3226453Sache const unsigned char *pedid = NULL; 3326453Sache static char *propnames[] = { 3426453Sache "DFP,EDID", "LCD,EDID", "EDID", "EDID1", 3526453Sache "EDID,B", "EDID,A", NULL }; 3639271Sphk int i; 3739271Sphk 3852419Sjulian parent = pci_device_to_OF_node(par->pci_dev); 3952419Sjulian if (parent == NULL) 4026453Sache return -1; 4126453Sache if (par->twoHeads) { 4252905Sjlemon const char *pname; 4352905Sjlemon int len; 4426453Sache 4526453Sache for_each_child_of_node(parent, dp) { 4626453Sache pname = of_get_property(dp, "name", NULL); 4726453Sache if (!pname) 4852228Sbp continue; 4952228Sbp len = strlen(pname); 5026453Sache if ((pname[len-1] == 'A' && conn == 1) || 5126453Sache (pname[len-1] == 'B' && conn == 2)) { 5226453Sache for (i = 0; propnames[i] != NULL; ++i) { 5326453Sache pedid = of_get_property(dp, 5454091Ssemenu propnames[i], NULL); 5554091Ssemenu if (pedid != NULL) 5652228Sbp break; 5752228Sbp } 588571Srgrimes of_node_put(dp); 597130Srgrimes break; 6055097Skris } 6155097Skris } 6226453Sache } 6326453Sache if (pedid == NULL) { 6434030Sdufault for (i = 0; propnames[i] != NULL; ++i) { 6534030Sdufault pedid = of_get_property(parent, propnames[i], NULL); 668571Srgrimes if (pedid != NULL) 677130Srgrimes break; 688571Srgrimes } 697130Srgrimes } 708571Srgrimes if (pedid) { 717130Srgrimes *out_edid = kmemdup(pedid, EDID_LENGTH, GFP_KERNEL); 728571Srgrimes if (*out_edid == NULL) 737130Srgrimes return -1; 7441230Sjdp printk(KERN_DEBUG "nvidiafb: Found OF EDID for head %d\n", conn); 7541230Sjdp return 0; 768571Srgrimes } 777130Srgrimes return -1; 7826453Sache} 7926453Sache