aboutsummaryrefslogtreecommitdiffstats
path: root/hw/usb/vt82c686-uhci-pci.c
blob: 0bf2b72ff086cf5f505c0a7c1120c3a4144639d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include "qemu/osdep.h"
#include "hw/irq.h"
#include "hw/isa/vt82c686.h"
#include "hcd-uhci.h"

static void uhci_isa_set_irq(void *opaque, int irq_num, int level)
{
    UHCIState *s = opaque;
    uint8_t irq = pci_get_byte(s->dev.config + PCI_INTERRUPT_LINE);
    if (irq > 0 && irq < 15) {
        via_isa_set_irq(pci_get_function_0(&s->dev), irq, level);
    }
}

static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
{
    UHCIState *s = UHCI(dev);
    uint8_t *pci_conf = s->dev.config;

    /* USB misc control 1/2 */
    pci_set_long(pci_conf + 0x40, 0x00001000);
    /* PM capability */
    pci_set_long(pci_conf + 0x80, 0x00020001);
    /* USB legacy support  */
    pci_set_long(pci_conf + 0xc0, 0x00002000);

    usb_uhci_common_realize(dev, errp);
    object_unref(s->irq);
    s->irq = qemu_allocate_irq(uhci_isa_set_irq, s, 0);
}

static UHCIInfo uhci_info[] = {
    {
        .name      = "vt82c686b-usb-uhci",
        .vendor_id = PCI_VENDOR_ID_VIA,
        .device_id = PCI_DEVICE_ID_VIA_UHCI,
        .revision  = 0x01,
        .irq_pin   = 3,
        .realize   = usb_uhci_vt82c686b_realize,
        .unplug    = true,
        /* Reason: only works as USB function of VT82xx superio chips */
        .notuser   = true,
    }
};

static const TypeInfo vt82c686b_usb_uhci_type_info = {
    .parent         = TYPE_UHCI,
    .name           = "vt82c686b-usb-uhci",
    .class_init     = uhci_data_class_init,
    .class_data     = uhci_info,
};

static void vt82c686b_usb_uhci_register_types(void)
{
    type_register_static(&vt82c686b_usb_uhci_type_info);
}

type_init(vt82c686b_usb_uhci_register_types)