#include "kylingpu-probe.h"
#include "../kylinlogger/kylinlogger_C/kylinlogger_c.h"

/* copy from Xorg */

static struct pci_slot_match xf86IsolateDevice = {
		PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY, 0
};

int xf86scanpci(void)
{
    int success;
    success	= ( pci_system_init() == 0 );
	if(!success)
	{
            logger_log(LOG_FATAL, "pci_system_init err\n\n");
			return -1;
	}
	return 0;
}

int
xf86VideoPtrToDriverList(struct pci_device *dev)
{
    int i;

    /* Add more entries here if we ever return more than 4 drivers for
       any device */
    const char *driverList[5] = { NULL, NULL, NULL, NULL, NULL };

    switch (dev->vendor_id) {
    case 0x0709:
        driverList[0] = "csmicro";
        break;
    case 0x16c3:
	//sietium = TRUE;
	break;
    case 0x0716:
	driverList[0] = "jari";
	break;
    case 0x3d00:
	driverList[0] = "zxe3k";
	break;
    case 0x0731:
        if (dev->device_id == 0x7200)
            driverList[0] = "mwv206";
        break;
        /* AMD Geode LX */
    case 0x1022:
        if (dev->device_id == 0x2081)
            driverList[0] = "geode";
        break;
        /* older Geode products acquired by AMD still carry an NSC vendor_id */
    case 0x100b:
        if (dev->device_id == 0x0030) {
            /* NSC Geode GX2 specifically */
            driverList[0] = "geode";
            /* GX2 support started its life in the NSC tree and was later
               forked by AMD for GEODE so we keep it as a backup */
            driverList[1] = "nsc";
        }
        else
            /* other NSC variant e.g. 0x0104 (SC1400), 0x0504 (SCx200) */
            driverList[0] = "nsc";
        break;
        /* Cyrix Geode GX1 */
    case 0x1078:
        if (dev->device_id == 0x0104)
            driverList[0] = "cyrix";
        break;
    case 0x1142:
        driverList[0] = "apm";
        break;
    case 0x1d17:
        switch (dev->device_id) {
        case 0x3a03:
        case 0x3a04:
            driverList[0] = "zx";
            break;
        default:
            driverList[0] = "zx";
            break;
        }
        break;
    case 0xedd8:
        driverList[0] = "ark";
        break;
    case 0x1a03:
        driverList[0] = "ast";
        break;
    case 0x1002:
        driverList[0] = "ati";
        break;
    case 0x102c:
        driverList[0] = "chips";
        break;
    case 0x1013:
        driverList[0] = "cirrus";
        break;
    case 0x3d3d:
        driverList[0] = "glint";
        break;
    case 0x105d:
        driverList[0] = "i128";
        break;
    case 0x8086:
	switch (dev->device_id)
	{
		/* Intel i740 */
		case 0x00d1:
		case 0x7800:
			driverList[0] = "i740";
			break;
		/* GMA500/Poulsbo */
		case 0x8108:
		case 0x8109:
			/* Try psb driver on Poulsbo - if available */
			driverList[0] = "psb";
			driverList[1] = "psb_drv";
			break;
		/* GMA600/Oaktrail */
		case 0x4100:
		case 0x4101:
		case 0x4102:
		case 0x4103:
		case 0x4104:
		case 0x4105:
		case 0x4106:
		case 0x4107:
		/* Atom E620/Oaktrail */
		case 0x4108:
		/* Medfield */
		case 0x0130:
		case 0x0131:
		case 0x0132:
		case 0x0133:
		case 0x0134:
		case 0x0135:
		case 0x0136:
		case 0x0137:
		/* GMA 3600/CDV */
		case 0x0be0:
		case 0x0be1:
		case 0x0be2:
		case 0x0be3:
		case 0x0be4:
		case 0x0be5:
		case 0x0be6:
		case 0x0be7:
		case 0x0be8:
		case 0x0be9:
		case 0x0bea:
		case 0x0beb:
		case 0x0bec:
		case 0x0bed:
		case 0x0bee:
		case 0x0bef:
			/* Use fbdev/vesa driver on Oaktrail, Medfield, CDV */
			break;
		/* Default to intel only on pre-gen4 chips */
		case 0x3577:
		case 0x2562:
		case 0x3582:
		case 0x358e:
		case 0x2572:
		case 0x2582:
		case 0x258a:
		case 0x2592:
		case 0x2772:
		case 0x27a2:
		case 0x27ae:
		case 0x29b2:
		case 0x29c2:
		case 0x29d2:
		case 0xa001:
		case 0xa011:
			driverList[0] = "intel";
			break;
        }
        break;
    case 0x102b:
        driverList[0] = "mga";
        break;
    case 0x10c8:
        driverList[0] = "neomagic";
        break;
    case 0x10de:
    case 0x12d2:
    {
		int idx = 0;
#if defined(__linux__) || defined(__NetBSD__)
        driverList[idx++] = "nouveau";
#else
        driverList[idx++] = "nv";
#endif
        break;
    }
    case 0x1106:
        driverList[0] = "openchrome";
        break;
    case 0x1b36:
        driverList[0] = "qxl";
        break;
    case 0x1163:
        driverList[0] = "rendition";
        break;
    case 0x5333:
        switch (dev->device_id) {
        case 0x88d0:
        case 0x88d1:
        case 0x88f0:
        case 0x8811:
        case 0x8812:
        case 0x8814:
        case 0x8901:
            driverList[0] = "s3";
            break;
        case 0x5631:
        case 0x883d:
        case 0x8a01:
        case 0x8a10:
        case 0x8c01:
        case 0x8c03:
        case 0x8904:
        case 0x8a13:
            driverList[0] = "s3virge";
            break;
        default:
            driverList[0] = "savage";
            break;
        }
        break;
    case 0x1039:
        driverList[0] = "sis";
        break;
    case 0x126f:
        driverList[0] = "siliconmotion";
        break;
    case 0x121a:
        if (dev->device_id < 0x0003)
            driverList[0] = "voodoo";
        else
            driverList[0] = "tdfx";
        break;
    case 0x1011:
        driverList[0] = "tga";
        break;
    case 0x1023:
        driverList[0] = "trident";
        break;
    case 0x100c:
        driverList[0] = "tseng";
        break;
    case 0x80ee:
        driverList[0] = "vboxvideo";
        break;
    case 0x15ad:
        driverList[0] = "vmware";
        break;
    case 0x18ca:
        if (dev->device_id == 0x47)
            driverList[0] = "xgixp";
        else
            driverList[0] = "xgi";
        break;
    default:
        break;
    }

    //for (i = 0; driverList[i] != NULL; i++) {
        //xf86AddMatchedDriver(md, driverList[i]);
    //}
	
	if(driverList[0] != NULL)
	{
        logger_log(LOG_NOTICE, "gpu vendor=%s\n",driverList[0]);
		return 0;
	}
	else
	{
        logger_log(LOG_NOTICE, "cant Identify gpu\n");
		return -1;
	}
}

int xf86PciProbe(void)
{
	struct pci_device *info;
    struct pci_device_iterator *iter;

	if( xf86scanpci() )
        return -1;

	iter = pci_slot_match_iterator_create(&xf86IsolateDevice);
	while ((info = pci_device_next(iter)) != NULL) {
			pci_device_probe(info);
			if (pci_device_is_boot_vga(info))
			{
                    logger_log(LOG_NOTICE, "get vga device vendor_id=%04x,device_id=%04x\n",info->vendor_id,info->device_id);
					return xf86VideoPtrToDriverList(info);
			}
	}
	return -1;
}

