cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

via_aux_edid.c (1717B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
      4 */
      5/*
      6 * generic EDID driver
      7 */
      8
      9#include <linux/slab.h>
     10#include <linux/fb.h>
     11#include "via_aux.h"
     12#include "../edid.h"
     13
     14
     15static const char *name = "EDID";
     16
     17
     18static void query_edid(struct via_aux_drv *drv)
     19{
     20	struct fb_monspecs *spec = drv->data;
     21	unsigned char edid[EDID_LENGTH];
     22	bool valid = false;
     23
     24	if (spec) {
     25		fb_destroy_modedb(spec->modedb);
     26	} else {
     27		spec = kmalloc(sizeof(*spec), GFP_KERNEL);
     28		if (!spec)
     29			return;
     30	}
     31
     32	spec->version = spec->revision = 0;
     33	if (via_aux_read(drv, 0x00, edid, EDID_LENGTH)) {
     34		fb_edid_to_monspecs(edid, spec);
     35		valid = spec->version || spec->revision;
     36	}
     37
     38	if (!valid) {
     39		kfree(spec);
     40		spec = NULL;
     41	} else
     42		printk(KERN_DEBUG "EDID: %s %s\n", spec->manufacturer, spec->monitor);
     43
     44	drv->data = spec;
     45}
     46
     47static const struct fb_videomode *get_preferred_mode(struct via_aux_drv *drv)
     48{
     49	struct fb_monspecs *spec = drv->data;
     50	int i;
     51
     52	if (!spec || !spec->modedb || !(spec->misc & FB_MISC_1ST_DETAIL))
     53		return NULL;
     54
     55	for (i = 0; i < spec->modedb_len; i++) {
     56		if (spec->modedb[i].flag & FB_MODE_IS_FIRST &&
     57			spec->modedb[i].flag & FB_MODE_IS_DETAILED)
     58			return &spec->modedb[i];
     59	}
     60
     61	return NULL;
     62}
     63
     64static void cleanup(struct via_aux_drv *drv)
     65{
     66	struct fb_monspecs *spec = drv->data;
     67
     68	if (spec)
     69		fb_destroy_modedb(spec->modedb);
     70}
     71
     72void via_aux_edid_probe(struct via_aux_bus *bus)
     73{
     74	struct via_aux_drv drv = {
     75		.bus	=	bus,
     76		.addr	=	0x50,
     77		.name	=	name,
     78		.cleanup	=	cleanup,
     79		.get_preferred_mode	=	get_preferred_mode};
     80
     81	query_edid(&drv);
     82
     83	/* as EDID devices can be connected/disconnected just add the driver */
     84	via_aux_add(&drv);
     85}