Commit | Line | Data |
---|---|---|
5320918b DA |
1 | /* |
2 | * Copyright (C) 2012 Red Hat | |
3 | * | |
4 | * This file is subject to the terms and conditions of the GNU General Public | |
5 | * License v2. See the file COPYING in the main directory of this archive for | |
6 | * more details. | |
7 | */ | |
8 | ||
9 | #include <linux/module.h> | |
760285e7 DH |
10 | #include <drm/drm_usb.h> |
11 | #include <drm/drm_crtc_helper.h> | |
5320918b DA |
12 | #include "udl_drv.h" |
13 | ||
14 | static struct drm_driver driver; | |
15 | ||
e5a867a5 DA |
16 | /* |
17 | * There are many DisplayLink-based graphics products, all with unique PIDs. | |
18 | * So we match on DisplayLink's VID + Vendor-Defined Interface Class (0xff) | |
19 | * We also require a match on SubClass (0x00) and Protocol (0x00), | |
20 | * which is compatible with all known USB 2.0 era graphics chips and firmware, | |
21 | * but allows DisplayLink to increment those for any future incompatible chips | |
22 | */ | |
5320918b | 23 | static struct usb_device_id id_table[] = { |
e5a867a5 DA |
24 | {.idVendor = 0x17e9, .bInterfaceClass = 0xff, |
25 | .bInterfaceSubClass = 0x00, | |
26 | .bInterfaceProtocol = 0x00, | |
27 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | | |
28 | USB_DEVICE_ID_MATCH_INT_CLASS | | |
29 | USB_DEVICE_ID_MATCH_INT_SUBCLASS | | |
30 | USB_DEVICE_ID_MATCH_INT_PROTOCOL,}, | |
5320918b DA |
31 | {}, |
32 | }; | |
33 | MODULE_DEVICE_TABLE(usb, id_table); | |
34 | ||
35 | MODULE_LICENSE("GPL"); | |
36 | ||
915b4d11 DH |
37 | static int udl_driver_set_busid(struct drm_device *d, struct drm_master *m) |
38 | { | |
39 | return 0; | |
40 | } | |
41 | ||
5320918b DA |
42 | static int udl_usb_probe(struct usb_interface *interface, |
43 | const struct usb_device_id *id) | |
44 | { | |
45 | return drm_get_usb_dev(interface, id, &driver); | |
46 | } | |
47 | ||
48 | static void udl_usb_disconnect(struct usb_interface *interface) | |
49 | { | |
50 | struct drm_device *dev = usb_get_intfdata(interface); | |
51 | ||
52 | drm_kms_helper_poll_disable(dev); | |
53 | drm_connector_unplug_all(dev); | |
54 | udl_fbdev_unplug(dev); | |
55 | udl_drop_usb(dev); | |
56 | drm_unplug_dev(dev); | |
57 | } | |
58 | ||
78b68556 | 59 | static const struct vm_operations_struct udl_gem_vm_ops = { |
5320918b DA |
60 | .fault = udl_gem_fault, |
61 | .open = drm_gem_vm_open, | |
62 | .close = drm_gem_vm_close, | |
63 | }; | |
64 | ||
65 | static const struct file_operations udl_driver_fops = { | |
66 | .owner = THIS_MODULE, | |
67 | .open = drm_open, | |
fa9e8550 | 68 | .mmap = udl_drm_gem_mmap, |
5320918b DA |
69 | .poll = drm_poll, |
70 | .read = drm_read, | |
71 | .unlocked_ioctl = drm_ioctl, | |
72 | .release = drm_release, | |
804d74ab KP |
73 | #ifdef CONFIG_COMPAT |
74 | .compat_ioctl = drm_compat_ioctl, | |
75 | #endif | |
5320918b DA |
76 | .llseek = noop_llseek, |
77 | }; | |
78 | ||
79 | static struct drm_driver driver = { | |
96503f59 | 80 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, |
5320918b DA |
81 | .load = udl_driver_load, |
82 | .unload = udl_driver_unload, | |
915b4d11 | 83 | .set_busid = udl_driver_set_busid, |
5320918b DA |
84 | |
85 | /* gem hooks */ | |
5320918b DA |
86 | .gem_free_object = udl_gem_free_object, |
87 | .gem_vm_ops = &udl_gem_vm_ops, | |
88 | ||
89 | .dumb_create = udl_dumb_create, | |
90 | .dumb_map_offset = udl_gem_mmap, | |
43387b37 | 91 | .dumb_destroy = drm_gem_dumb_destroy, |
5320918b | 92 | .fops = &udl_driver_fops, |
96503f59 DA |
93 | |
94 | .prime_fd_to_handle = drm_gem_prime_fd_to_handle, | |
95 | .gem_prime_import = udl_gem_prime_import, | |
96 | ||
5320918b DA |
97 | .name = DRIVER_NAME, |
98 | .desc = DRIVER_DESC, | |
99 | .date = DRIVER_DATE, | |
100 | .major = DRIVER_MAJOR, | |
101 | .minor = DRIVER_MINOR, | |
102 | .patchlevel = DRIVER_PATCHLEVEL, | |
103 | }; | |
104 | ||
105 | static struct usb_driver udl_driver = { | |
106 | .name = "udl", | |
107 | .probe = udl_usb_probe, | |
108 | .disconnect = udl_usb_disconnect, | |
109 | .id_table = id_table, | |
110 | }; | |
111 | ||
112 | static int __init udl_init(void) | |
113 | { | |
114 | return drm_usb_init(&driver, &udl_driver); | |
115 | } | |
116 | ||
117 | static void __exit udl_exit(void) | |
118 | { | |
119 | drm_usb_exit(&driver, &udl_driver); | |
120 | } | |
121 | ||
122 | module_init(udl_init); | |
123 | module_exit(udl_exit); |