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> | |
d4f68a75 | 10 | #include <drm/drmP.h> |
760285e7 | 11 | #include <drm/drm_crtc_helper.h> |
5320918b DA |
12 | #include "udl_drv.h" |
13 | ||
915b4d11 DH |
14 | static int udl_driver_set_busid(struct drm_device *d, struct drm_master *m) |
15 | { | |
16 | return 0; | |
17 | } | |
18 | ||
737ba109 HS |
19 | static int udl_usb_suspend(struct usb_interface *interface, |
20 | pm_message_t message) | |
21 | { | |
22 | return 0; | |
23 | } | |
24 | ||
25 | static int udl_usb_resume(struct usb_interface *interface) | |
26 | { | |
27 | struct drm_device *dev = usb_get_intfdata(interface); | |
28 | ||
29 | udl_modeset_restore(dev); | |
30 | return 0; | |
31 | } | |
32 | ||
78b68556 | 33 | static const struct vm_operations_struct udl_gem_vm_ops = { |
5320918b DA |
34 | .fault = udl_gem_fault, |
35 | .open = drm_gem_vm_open, | |
36 | .close = drm_gem_vm_close, | |
37 | }; | |
38 | ||
39 | static const struct file_operations udl_driver_fops = { | |
40 | .owner = THIS_MODULE, | |
41 | .open = drm_open, | |
fa9e8550 | 42 | .mmap = udl_drm_gem_mmap, |
5320918b DA |
43 | .poll = drm_poll, |
44 | .read = drm_read, | |
45 | .unlocked_ioctl = drm_ioctl, | |
46 | .release = drm_release, | |
804d74ab KP |
47 | #ifdef CONFIG_COMPAT |
48 | .compat_ioctl = drm_compat_ioctl, | |
49 | #endif | |
5320918b DA |
50 | .llseek = noop_llseek, |
51 | }; | |
52 | ||
53 | static struct drm_driver driver = { | |
96503f59 | 54 | .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME, |
5320918b DA |
55 | .load = udl_driver_load, |
56 | .unload = udl_driver_unload, | |
915b4d11 | 57 | .set_busid = udl_driver_set_busid, |
5320918b DA |
58 | |
59 | /* gem hooks */ | |
5320918b DA |
60 | .gem_free_object = udl_gem_free_object, |
61 | .gem_vm_ops = &udl_gem_vm_ops, | |
62 | ||
63 | .dumb_create = udl_dumb_create, | |
64 | .dumb_map_offset = udl_gem_mmap, | |
43387b37 | 65 | .dumb_destroy = drm_gem_dumb_destroy, |
5320918b | 66 | .fops = &udl_driver_fops, |
96503f59 | 67 | |
ebfdd6d5 | 68 | .prime_handle_to_fd = drm_gem_prime_handle_to_fd, |
96503f59 | 69 | .prime_fd_to_handle = drm_gem_prime_fd_to_handle, |
ebfdd6d5 | 70 | .gem_prime_export = udl_gem_prime_export, |
96503f59 DA |
71 | .gem_prime_import = udl_gem_prime_import, |
72 | ||
5320918b DA |
73 | .name = DRIVER_NAME, |
74 | .desc = DRIVER_DESC, | |
75 | .date = DRIVER_DATE, | |
76 | .major = DRIVER_MAJOR, | |
77 | .minor = DRIVER_MINOR, | |
78 | .patchlevel = DRIVER_PATCHLEVEL, | |
79 | }; | |
80 | ||
d4f68a75 DH |
81 | static int udl_usb_probe(struct usb_interface *interface, |
82 | const struct usb_device_id *id) | |
83 | { | |
84 | struct usb_device *udev = interface_to_usbdev(interface); | |
85 | struct drm_device *dev; | |
86 | int r; | |
87 | ||
88 | dev = drm_dev_alloc(&driver, &interface->dev); | |
89 | if (!dev) | |
90 | return -ENOMEM; | |
91 | ||
92 | r = drm_dev_register(dev, (unsigned long)udev); | |
93 | if (r) | |
94 | goto err_free; | |
95 | ||
96 | usb_set_intfdata(interface, dev); | |
97 | DRM_INFO("Initialized udl on minor %d\n", dev->primary->index); | |
98 | ||
99 | return 0; | |
100 | ||
101 | err_free: | |
102 | drm_dev_unref(dev); | |
103 | return r; | |
104 | } | |
105 | ||
106 | static void udl_usb_disconnect(struct usb_interface *interface) | |
107 | { | |
108 | struct drm_device *dev = usb_get_intfdata(interface); | |
109 | ||
110 | drm_kms_helper_poll_disable(dev); | |
d4f68a75 DH |
111 | udl_fbdev_unplug(dev); |
112 | udl_drop_usb(dev); | |
113 | drm_unplug_dev(dev); | |
114 | } | |
115 | ||
116 | /* | |
117 | * There are many DisplayLink-based graphics products, all with unique PIDs. | |
118 | * So we match on DisplayLink's VID + Vendor-Defined Interface Class (0xff) | |
119 | * We also require a match on SubClass (0x00) and Protocol (0x00), | |
120 | * which is compatible with all known USB 2.0 era graphics chips and firmware, | |
121 | * but allows DisplayLink to increment those for any future incompatible chips | |
122 | */ | |
123 | static struct usb_device_id id_table[] = { | |
124 | {.idVendor = 0x17e9, .bInterfaceClass = 0xff, | |
125 | .bInterfaceSubClass = 0x00, | |
126 | .bInterfaceProtocol = 0x00, | |
127 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | | |
128 | USB_DEVICE_ID_MATCH_INT_CLASS | | |
129 | USB_DEVICE_ID_MATCH_INT_SUBCLASS | | |
130 | USB_DEVICE_ID_MATCH_INT_PROTOCOL,}, | |
131 | {}, | |
132 | }; | |
133 | MODULE_DEVICE_TABLE(usb, id_table); | |
134 | ||
5320918b DA |
135 | static struct usb_driver udl_driver = { |
136 | .name = "udl", | |
137 | .probe = udl_usb_probe, | |
138 | .disconnect = udl_usb_disconnect, | |
737ba109 HS |
139 | .suspend = udl_usb_suspend, |
140 | .resume = udl_usb_resume, | |
5320918b DA |
141 | .id_table = id_table, |
142 | }; | |
a6ddd2f1 | 143 | module_usb_driver(udl_driver); |
d4f68a75 | 144 | MODULE_LICENSE("GPL"); |