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 | ||
37 | static int udl_usb_probe(struct usb_interface *interface, | |
38 | const struct usb_device_id *id) | |
39 | { | |
40 | return drm_get_usb_dev(interface, id, &driver); | |
41 | } | |
42 | ||
43 | static void udl_usb_disconnect(struct usb_interface *interface) | |
44 | { | |
45 | struct drm_device *dev = usb_get_intfdata(interface); | |
46 | ||
47 | drm_kms_helper_poll_disable(dev); | |
48 | drm_connector_unplug_all(dev); | |
49 | udl_fbdev_unplug(dev); | |
50 | udl_drop_usb(dev); | |
51 | drm_unplug_dev(dev); | |
52 | } | |
53 | ||
78b68556 | 54 | static const struct vm_operations_struct udl_gem_vm_ops = { |
5320918b DA |
55 | .fault = udl_gem_fault, |
56 | .open = drm_gem_vm_open, | |
57 | .close = drm_gem_vm_close, | |
58 | }; | |
59 | ||
60 | static const struct file_operations udl_driver_fops = { | |
61 | .owner = THIS_MODULE, | |
62 | .open = drm_open, | |
fa9e8550 | 63 | .mmap = udl_drm_gem_mmap, |
5320918b DA |
64 | .poll = drm_poll, |
65 | .read = drm_read, | |
66 | .unlocked_ioctl = drm_ioctl, | |
67 | .release = drm_release, | |
804d74ab KP |
68 | #ifdef CONFIG_COMPAT |
69 | .compat_ioctl = drm_compat_ioctl, | |
70 | #endif | |
5320918b DA |
71 | .llseek = noop_llseek, |
72 | }; | |
73 | ||
74 | static struct drm_driver driver = { | |
96503f59 | 75 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, |
5320918b DA |
76 | .load = udl_driver_load, |
77 | .unload = udl_driver_unload, | |
78 | ||
79 | /* gem hooks */ | |
5320918b DA |
80 | .gem_free_object = udl_gem_free_object, |
81 | .gem_vm_ops = &udl_gem_vm_ops, | |
82 | ||
83 | .dumb_create = udl_dumb_create, | |
84 | .dumb_map_offset = udl_gem_mmap, | |
43387b37 | 85 | .dumb_destroy = drm_gem_dumb_destroy, |
5320918b | 86 | .fops = &udl_driver_fops, |
96503f59 DA |
87 | |
88 | .prime_fd_to_handle = drm_gem_prime_fd_to_handle, | |
89 | .gem_prime_import = udl_gem_prime_import, | |
90 | ||
5320918b DA |
91 | .name = DRIVER_NAME, |
92 | .desc = DRIVER_DESC, | |
93 | .date = DRIVER_DATE, | |
94 | .major = DRIVER_MAJOR, | |
95 | .minor = DRIVER_MINOR, | |
96 | .patchlevel = DRIVER_PATCHLEVEL, | |
97 | }; | |
98 | ||
99 | static struct usb_driver udl_driver = { | |
100 | .name = "udl", | |
101 | .probe = udl_usb_probe, | |
102 | .disconnect = udl_usb_disconnect, | |
103 | .id_table = id_table, | |
104 | }; | |
105 | ||
106 | static int __init udl_init(void) | |
107 | { | |
108 | return drm_usb_init(&driver, &udl_driver); | |
109 | } | |
110 | ||
111 | static void __exit udl_exit(void) | |
112 | { | |
113 | drm_usb_exit(&driver, &udl_driver); | |
114 | } | |
115 | ||
116 | module_init(udl_init); | |
117 | module_exit(udl_exit); |