From 772967d2711cfdc432b2cea0c8df137edbf18bb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gwenol=C3=A9=20Beauchesne?= Date: Wed, 25 Aug 2004 08:53:14 +0000 Subject: Get EDID block from OF (kudzu) --- tools/ddcprobe/minifind.c | 77 ++++++++++++++++++++++++ tools/ddcprobe/minifind.h | 42 +++++++++++++ tools/ddcprobe/of.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 265 insertions(+) create mode 100644 tools/ddcprobe/minifind.c create mode 100644 tools/ddcprobe/minifind.h create mode 100644 tools/ddcprobe/of.c (limited to 'tools') diff --git a/tools/ddcprobe/minifind.c b/tools/ddcprobe/minifind.c new file mode 100644 index 000000000..f483055b4 --- /dev/null +++ b/tools/ddcprobe/minifind.c @@ -0,0 +1,77 @@ +/* minifind.c -- simple find library + * + * Copyright (c) 2002 Terra Soft Solutions, Inc. + * Written by Dan Burcaw + * + * This software may be freely redistributed under the terms of the GNU + * library public license. + * + * You should have received a copy of the GNU Library Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include "minifind.h" + +// insert a node at head of linked-list +void insert_node(struct pathNode *n, char *path) +{ + struct pathNode *new = (struct pathNode *) malloc(sizeof(struct pathNode)); + new->path = path; + new->next = n->next; + n->next = new; +} + +// return input strip less last character +char *stripLastChar(char *in) +{ + char *out = malloc(sizeof(char)*strlen(in)); + snprintf(out, strlen(in) - 1, "%s", in); + return out; +} + +// do the work +char *minifind(char *dir, char *search, struct findNode *list) +{ + char *d = NULL; + int n; + struct dirent **namelist; + struct stat buf; + + if (dir[strlen(dir)-1] == '/') + dir = stripLastChar(dir); + + // check is there is an exact filematch to dir + // when search is not specified + if (search == NULL) + { + if (lstat(dir, &buf) == 0) + insert_node(list->result, dir); + return 0; + } + + n = scandir(dir, &namelist, 0, alphasort); + if (n >= 0) + { + while (n--) + { + d = malloc(sizeof(char) * (strlen(dir) \ + + strlen(namelist[n]->d_name)+1)); + sprintf(d, "%s/%s", dir, namelist[n]->d_name); + if (strstr(namelist[n]->d_name, search)) + insert_node(list->result, d); + + if ((lstat(d, &buf) == 0) && S_ISDIR(buf.st_mode)) + { + if (strcmp(namelist[n]->d_name, ".") && + strcmp(namelist[n]->d_name, "..")) + d = minifind(d, search, list); + } + free(namelist[n]); + } + free(namelist); + return d; + } + return 0; +} diff --git a/tools/ddcprobe/minifind.h b/tools/ddcprobe/minifind.h new file mode 100644 index 000000000..4f725258c --- /dev/null +++ b/tools/ddcprobe/minifind.h @@ -0,0 +1,42 @@ +/* minifind.h + * + * Copyright (c) 2002 Terra Soft Solutions, Inc. + * Written by Dan Burcaw + * + * This software may be freely redistributed under the terms of the GNU + * library public license. + * + * You should have received a copy of the GNU Library Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef MINIFIND_H +#define MINIFIND_H + +#include +#include +#include +#include +#include +#include +#include + +struct pathNode +{ + char *path; + struct pathNode *next; +}; + +struct findNode +{ + struct pathNode *result; + struct pathNode *exclude; +}; + +void insert_node(struct pathNode *n, char *path); +char *stripLastChar(char *in); +char *minifind(char *dir, char *search, struct findNode *list); + +#endif /* MINIFIND_H */ diff --git a/tools/ddcprobe/of.c b/tools/ddcprobe/of.c new file mode 100644 index 000000000..5e8aefa3f --- /dev/null +++ b/tools/ddcprobe/of.c @@ -0,0 +1,146 @@ +#ifdef __powerpc__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "vbe.h" +#include "minifind.h" + +/* misnomer */ +struct vbe_info *vbe_get_vbe_info() +{ + struct vbe_info *ret = NULL; + struct fb_fix_screeninfo fix; + unsigned char *mem; + int rc = 0; + int fd, i; + + if (!rc && !(fd = open("/dev/fb0", O_RDONLY))) + { + rc = 1; + fprintf(stderr, "Unable to open /dev/fb0. Exiting.\n"); + } + + if ((!rc) && (ioctl(fd, FBIOGET_FSCREENINFO, &fix))) + { + rc = 1; + fprintf(stderr, "Framebuffer ioctl failed. Exiting.\n"); + } + + close(fd); + + if (!rc) + { + // Note: if OFfb, vram info is unreliable! + if (strcmp(fix.id, "OFfb")) + { + ret = malloc(sizeof(struct vbe_info)); + mem = strdup(fix.id); + while(((i = strlen(mem)) > 0) && isspace(mem[i - 1])) { + mem[i - 1] = '\0'; + } + ret->oem_name.string = mem; + ret->product_name.string = NULL; + ret->vendor_name.string = NULL; + ret->product_revision.string = NULL; + ret->memory_size = fix.smem_len/1024; + } + } + + return ret; +} + +int get_edid_supported() +{ + int ret = 0; + struct findNode *list; + struct pathNode *n; + + list = (struct findNode *) malloc(sizeof(struct findNode)); + list->result = (struct pathNode *) malloc(sizeof(struct pathNode)); + list->result->path = NULL; + list->result->next = list->result; + + minifind("/proc/device-tree", "EDID", list); + + /* Supported */ + for (n = list->result->next; n != list->result; n = n->next) + ret = 1; + + /* Clean up and return. */ + return ret; +} + +/* Get EDID info. */ +struct edid1_info *get_edid_info() +{ + unsigned char *mem; + struct edid1_info *ret = NULL; + struct pathNode *n; + struct findNode *list; + u_int16_t man; + unsigned char edid[0x80]; + FILE* edid_file = NULL; + char *path = NULL; + + list = (struct findNode *) malloc(sizeof(struct findNode)); + list->result = (struct pathNode *) malloc(sizeof(struct pathNode)); + list->result->path = NULL; + list->result->next = list->result; + + minifind("/proc/device-tree", "EDID", list); + + for (n = list->result->next; n != list->result; n = n->next) + { + path = n->path; + break; + } + + if (path) + edid_file = fopen(path, "rb" ); + + + if (!edid_file) + return NULL; + + if (fread(edid, sizeof(unsigned char), 0x80, edid_file) != 0x80) + return NULL; + + fclose(edid_file); + + mem = malloc(sizeof(struct edid1_info)); + if(mem == NULL) { + return NULL; + } + + memcpy(mem, edid, 0x80); + + + /* Get memory for return. */ + ret = malloc(sizeof(struct edid1_info)); + if(ret == NULL) { + free(mem); + return NULL; + } + + /* Copy the buffer for return. */ + memcpy(ret, mem, sizeof(struct edid1_info)); + + memcpy(&man, &ret->manufacturer_name, 2); + man = ntohs(man); + memcpy(&ret->manufacturer_name, &man, 2); + + free(mem); + return ret; +} + +#endif /* __powerpc__ */ -- cgit v1.2.1