1 // SPDX-License-Identifier: GPL-2.0+
6 #include <linux/dma-buf.h>
7 #include <linux/module.h>
10 #include <drm/drm_atomic_helper.h>
11 #include <drm/drm_atomic_state_helper.h>
12 #include <drm/drm_connector.h>
13 #include <drm/drm_damage_helper.h>
14 #include <drm/drm_drv.h>
15 #include <drm/drm_fb_helper.h>
16 #include <drm/drm_file.h>
17 #include <drm/drm_format_helper.h>
18 #include <drm/drm_fourcc.h>
19 #include <drm/drm_gem_shmem_helper.h>
20 #include <drm/drm_gem_framebuffer_helper.h>
21 #include <drm/drm_ioctl.h>
22 #include <drm/drm_modeset_helper_vtables.h>
23 #include <drm/drm_probe_helper.h>
24 #include <drm/drm_simple_kms_helper.h>
27 module_param(eco_mode, bool, 0644);
28 MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)");
30 #define DRIVER_NAME "gm12u320"
31 #define DRIVER_DESC "Grain Media GM12U320 USB projector display"
32 #define DRIVER_DATE "2019"
33 #define DRIVER_MAJOR 1
34 #define DRIVER_MINOR 0
37 * The DLP has an actual width of 854 pixels, but that is not a multiple
38 * of 8, breaking things left and right, so we export a width of 848.
40 #define GM12U320_USER_WIDTH 848
41 #define GM12U320_REAL_WIDTH 854
42 #define GM12U320_HEIGHT 480
44 #define GM12U320_BLOCK_COUNT 20
46 #define GM12U320_ERR(fmt, ...) \
47 DRM_DEV_ERROR(&gm12u320->udev->dev, fmt, ##__VA_ARGS__)
49 #define MISC_RCV_EPT 1
50 #define DATA_RCV_EPT 2
51 #define DATA_SND_EPT 3
52 #define MISC_SND_EPT 4
54 #define DATA_BLOCK_HEADER_SIZE 84
55 #define DATA_BLOCK_CONTENT_SIZE 64512
56 #define DATA_BLOCK_FOOTER_SIZE 20
57 #define DATA_BLOCK_SIZE (DATA_BLOCK_HEADER_SIZE + \
58 DATA_BLOCK_CONTENT_SIZE + \
59 DATA_BLOCK_FOOTER_SIZE)
60 #define DATA_LAST_BLOCK_CONTENT_SIZE 4032
61 #define DATA_LAST_BLOCK_SIZE (DATA_BLOCK_HEADER_SIZE + \
62 DATA_LAST_BLOCK_CONTENT_SIZE + \
63 DATA_BLOCK_FOOTER_SIZE)
66 #define READ_STATUS_SIZE 13
67 #define MISC_VALUE_SIZE 4
69 #define CMD_TIMEOUT msecs_to_jiffies(200)
70 #define DATA_TIMEOUT msecs_to_jiffies(1000)
71 #define IDLE_TIMEOUT msecs_to_jiffies(2000)
72 #define FIRST_FRAME_TIMEOUT msecs_to_jiffies(2000)
74 #define MISC_REQ_GET_SET_ECO_A 0xff
75 #define MISC_REQ_GET_SET_ECO_B 0x35
76 /* Windows driver does once every second, with arg d = 1, other args 0 */
77 #define MISC_REQ_UNKNOWN1_A 0xff
78 #define MISC_REQ_UNKNOWN1_B 0x38
79 /* Windows driver does this on init, with arg a, b = 0, c = 0xa0, d = 4 */
80 #define MISC_REQ_UNKNOWN2_A 0xa5
81 #define MISC_REQ_UNKNOWN2_B 0x00
83 struct gm12u320_device {
84 struct drm_device dev;
85 struct drm_simple_display_pipe pipe;
86 struct drm_connector conn;
87 struct usb_device *udev;
88 unsigned char *cmd_buf;
89 unsigned char *data_buf[GM12U320_BLOCK_COUNT];
93 struct workqueue_struct *workq;
94 struct work_struct work;
95 wait_queue_head_t waitq;
97 struct drm_framebuffer *fb;
102 static const char cmd_data[CMD_SIZE] = {
103 0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
104 0x68, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff,
105 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x80, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
109 static const char cmd_draw[CMD_SIZE] = {
110 0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xfe,
112 0x00, 0x00, 0x00, 0xc0, 0xd1, 0x05, 0x00, 0x40,
113 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
116 static const char cmd_misc[CMD_SIZE] = {
117 0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
118 0x04, 0x00, 0x00, 0x00, 0x80, 0x01, 0x10, 0xfd,
119 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
120 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
123 static const char data_block_header[DATA_BLOCK_HEADER_SIZE] = {
124 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
125 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
127 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
129 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
131 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
132 0xfb, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
133 0x00, 0x04, 0x15, 0x00, 0x00, 0xfc, 0x00, 0x00,
134 0x01, 0x00, 0x00, 0xdb
137 static const char data_last_block_header[DATA_BLOCK_HEADER_SIZE] = {
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
141 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
142 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
143 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
144 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
146 0xfb, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
147 0x2a, 0x00, 0x20, 0x00, 0xc0, 0x0f, 0x00, 0x00,
148 0x01, 0x00, 0x00, 0xd7
151 static const char data_block_footer[DATA_BLOCK_FOOTER_SIZE] = {
152 0xfb, 0x14, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
153 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
154 0x80, 0x00, 0x00, 0x4f
157 static int gm12u320_usb_alloc(struct gm12u320_device *gm12u320)
162 gm12u320->cmd_buf = kmalloc(CMD_SIZE, GFP_KERNEL);
163 if (!gm12u320->cmd_buf)
166 for (i = 0; i < GM12U320_BLOCK_COUNT; i++) {
167 if (i == GM12U320_BLOCK_COUNT - 1) {
168 block_size = DATA_LAST_BLOCK_SIZE;
169 hdr = data_last_block_header;
171 block_size = DATA_BLOCK_SIZE;
172 hdr = data_block_header;
175 gm12u320->data_buf[i] = kzalloc(block_size, GFP_KERNEL);
176 if (!gm12u320->data_buf[i])
179 memcpy(gm12u320->data_buf[i], hdr, DATA_BLOCK_HEADER_SIZE);
180 memcpy(gm12u320->data_buf[i] +
181 (block_size - DATA_BLOCK_FOOTER_SIZE),
182 data_block_footer, DATA_BLOCK_FOOTER_SIZE);
185 gm12u320->fb_update.workq = create_singlethread_workqueue(DRIVER_NAME);
186 if (!gm12u320->fb_update.workq)
192 static void gm12u320_usb_free(struct gm12u320_device *gm12u320)
196 if (gm12u320->fb_update.workq)
197 destroy_workqueue(gm12u320->fb_update.workq);
199 for (i = 0; i < GM12U320_BLOCK_COUNT; i++)
200 kfree(gm12u320->data_buf[i]);
202 kfree(gm12u320->cmd_buf);
205 static int gm12u320_misc_request(struct gm12u320_device *gm12u320,
207 u8 arg_a, u8 arg_b, u8 arg_c, u8 arg_d)
211 memcpy(gm12u320->cmd_buf, &cmd_misc, CMD_SIZE);
212 gm12u320->cmd_buf[20] = req_a;
213 gm12u320->cmd_buf[21] = req_b;
214 gm12u320->cmd_buf[22] = arg_a;
215 gm12u320->cmd_buf[23] = arg_b;
216 gm12u320->cmd_buf[24] = arg_c;
217 gm12u320->cmd_buf[25] = arg_d;
220 ret = usb_bulk_msg(gm12u320->udev,
221 usb_sndbulkpipe(gm12u320->udev, MISC_SND_EPT),
222 gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT);
223 if (ret || len != CMD_SIZE) {
224 GM12U320_ERR("Misc. req. error %d\n", ret);
229 ret = usb_bulk_msg(gm12u320->udev,
230 usb_rcvbulkpipe(gm12u320->udev, MISC_RCV_EPT),
231 gm12u320->cmd_buf, MISC_VALUE_SIZE, &len,
233 if (ret || len != MISC_VALUE_SIZE) {
234 GM12U320_ERR("Misc. value error %d\n", ret);
237 /* cmd_buf[0] now contains the read value, which we don't use */
240 ret = usb_bulk_msg(gm12u320->udev,
241 usb_rcvbulkpipe(gm12u320->udev, MISC_RCV_EPT),
242 gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
244 if (ret || len != READ_STATUS_SIZE) {
245 GM12U320_ERR("Misc. status error %d\n", ret);
252 static void gm12u320_32bpp_to_24bpp_packed(u8 *dst, u8 *src, int len)
262 static void gm12u320_copy_fb_to_blocks(struct gm12u320_device *gm12u320)
264 int block, dst_offset, len, remain, ret, x1, x2, y1, y2;
265 struct drm_framebuffer *fb;
269 mutex_lock(&gm12u320->fb_update.lock);
271 if (!gm12u320->fb_update.fb)
274 fb = gm12u320->fb_update.fb;
275 x1 = gm12u320->fb_update.rect.x1;
276 x2 = gm12u320->fb_update.rect.x2;
277 y1 = gm12u320->fb_update.rect.y1;
278 y2 = gm12u320->fb_update.rect.y2;
280 vaddr = drm_gem_shmem_vmap(fb->obj[0]);
282 GM12U320_ERR("failed to vmap fb: %ld\n", PTR_ERR(vaddr));
286 if (fb->obj[0]->import_attach) {
287 ret = dma_buf_begin_cpu_access(
288 fb->obj[0]->import_attach->dmabuf, DMA_FROM_DEVICE);
290 GM12U320_ERR("dma_buf_begin_cpu_access err: %d\n", ret);
295 src = vaddr + y1 * fb->pitches[0] + x1 * 4;
297 x1 += (GM12U320_REAL_WIDTH - GM12U320_USER_WIDTH) / 2;
298 x2 += (GM12U320_REAL_WIDTH - GM12U320_USER_WIDTH) / 2;
300 for (; y1 < y2; y1++) {
303 dst_offset = (y1 * GM12U320_REAL_WIDTH + x1) * 3;
304 block = dst_offset / DATA_BLOCK_CONTENT_SIZE;
305 dst_offset %= DATA_BLOCK_CONTENT_SIZE;
307 if ((dst_offset + len) > DATA_BLOCK_CONTENT_SIZE) {
308 remain = dst_offset + len - DATA_BLOCK_CONTENT_SIZE;
309 len = DATA_BLOCK_CONTENT_SIZE - dst_offset;
312 dst_offset += DATA_BLOCK_HEADER_SIZE;
315 gm12u320_32bpp_to_24bpp_packed(
316 gm12u320->data_buf[block] + dst_offset,
321 dst_offset = DATA_BLOCK_HEADER_SIZE;
322 gm12u320_32bpp_to_24bpp_packed(
323 gm12u320->data_buf[block] + dst_offset,
324 src + len * 4, remain / 3);
326 src += fb->pitches[0];
329 if (fb->obj[0]->import_attach) {
330 ret = dma_buf_end_cpu_access(fb->obj[0]->import_attach->dmabuf,
333 GM12U320_ERR("dma_buf_end_cpu_access err: %d\n", ret);
336 drm_gem_shmem_vunmap(fb->obj[0], vaddr);
338 drm_framebuffer_put(fb);
339 gm12u320->fb_update.fb = NULL;
341 mutex_unlock(&gm12u320->fb_update.lock);
344 static void gm12u320_fb_update_work(struct work_struct *work)
346 struct gm12u320_device *gm12u320 =
347 container_of(work, struct gm12u320_device, fb_update.work);
348 int draw_status_timeout = FIRST_FRAME_TIMEOUT;
349 int block, block_size, len;
353 while (gm12u320->fb_update.run) {
354 gm12u320_copy_fb_to_blocks(gm12u320);
356 for (block = 0; block < GM12U320_BLOCK_COUNT; block++) {
357 if (block == GM12U320_BLOCK_COUNT - 1)
358 block_size = DATA_LAST_BLOCK_SIZE;
360 block_size = DATA_BLOCK_SIZE;
362 /* Send data command to device */
363 memcpy(gm12u320->cmd_buf, cmd_data, CMD_SIZE);
364 gm12u320->cmd_buf[8] = block_size & 0xff;
365 gm12u320->cmd_buf[9] = block_size >> 8;
366 gm12u320->cmd_buf[20] = 0xfc - block * 4;
367 gm12u320->cmd_buf[21] = block | (frame << 7);
369 ret = usb_bulk_msg(gm12u320->udev,
370 usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
371 gm12u320->cmd_buf, CMD_SIZE, &len,
373 if (ret || len != CMD_SIZE)
376 /* Send data block to device */
377 ret = usb_bulk_msg(gm12u320->udev,
378 usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
379 gm12u320->data_buf[block], block_size,
381 if (ret || len != block_size)
385 ret = usb_bulk_msg(gm12u320->udev,
386 usb_rcvbulkpipe(gm12u320->udev, DATA_RCV_EPT),
387 gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
389 if (ret || len != READ_STATUS_SIZE)
393 /* Send draw command to device */
394 memcpy(gm12u320->cmd_buf, cmd_draw, CMD_SIZE);
395 ret = usb_bulk_msg(gm12u320->udev,
396 usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
397 gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT);
398 if (ret || len != CMD_SIZE)
402 ret = usb_bulk_msg(gm12u320->udev,
403 usb_rcvbulkpipe(gm12u320->udev, DATA_RCV_EPT),
404 gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
405 draw_status_timeout);
406 if (ret || len != READ_STATUS_SIZE)
409 draw_status_timeout = CMD_TIMEOUT;
413 * We must draw a frame every 2s otherwise the projector
414 * switches back to showing its logo.
416 wait_event_timeout(gm12u320->fb_update.waitq,
417 !gm12u320->fb_update.run ||
418 gm12u320->fb_update.fb != NULL,
423 /* Do not log errors caused by module unload or device unplug */
424 if (ret != -ENODEV && ret != -ECONNRESET && ret != -ESHUTDOWN)
425 GM12U320_ERR("Frame update error: %d\n", ret);
428 static void gm12u320_fb_mark_dirty(struct drm_framebuffer *fb,
429 struct drm_rect *dirty)
431 struct gm12u320_device *gm12u320 = fb->dev->dev_private;
432 struct drm_framebuffer *old_fb = NULL;
435 mutex_lock(&gm12u320->fb_update.lock);
437 if (gm12u320->fb_update.fb != fb) {
438 old_fb = gm12u320->fb_update.fb;
439 drm_framebuffer_get(fb);
440 gm12u320->fb_update.fb = fb;
441 gm12u320->fb_update.rect = *dirty;
444 struct drm_rect *rect = &gm12u320->fb_update.rect;
446 rect->x1 = min(rect->x1, dirty->x1);
447 rect->y1 = min(rect->y1, dirty->y1);
448 rect->x2 = max(rect->x2, dirty->x2);
449 rect->y2 = max(rect->y2, dirty->y2);
452 mutex_unlock(&gm12u320->fb_update.lock);
455 wake_up(&gm12u320->fb_update.waitq);
458 drm_framebuffer_put(old_fb);
461 static void gm12u320_start_fb_update(struct gm12u320_device *gm12u320)
463 mutex_lock(&gm12u320->fb_update.lock);
464 gm12u320->fb_update.run = true;
465 mutex_unlock(&gm12u320->fb_update.lock);
467 queue_work(gm12u320->fb_update.workq, &gm12u320->fb_update.work);
470 static void gm12u320_stop_fb_update(struct gm12u320_device *gm12u320)
472 mutex_lock(&gm12u320->fb_update.lock);
473 gm12u320->fb_update.run = false;
474 mutex_unlock(&gm12u320->fb_update.lock);
476 wake_up(&gm12u320->fb_update.waitq);
477 cancel_work_sync(&gm12u320->fb_update.work);
479 mutex_lock(&gm12u320->fb_update.lock);
480 if (gm12u320->fb_update.fb) {
481 drm_framebuffer_put(gm12u320->fb_update.fb);
482 gm12u320->fb_update.fb = NULL;
484 mutex_unlock(&gm12u320->fb_update.lock);
487 static int gm12u320_set_ecomode(struct gm12u320_device *gm12u320)
489 return gm12u320_misc_request(gm12u320, MISC_REQ_GET_SET_ECO_A,
490 MISC_REQ_GET_SET_ECO_B, 0x01 /* set */,
491 eco_mode ? 0x01 : 0x00, 0x00, 0x01);
494 /* ------------------------------------------------------------------ */
495 /* gm12u320 connector */
498 *Â We use fake EDID info so that userspace know that it is dealing with
499 * an Acer projector, rather then listing this as an "unknown" monitor.
500 * Note this assumes this driver is only ever used with the Acer C120, if we
501 * add support for other devices the vendor and model should be parameterized.
503 static struct edid gm12u320_edid = {
504 .header = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 },
505 .mfg_id = { 0x04, 0x72 }, /* "ACR" */
506 .prod_code = { 0x20, 0xc1 }, /* C120h */
507 .serial = 0xaa55aa55,
510 .version = 1, /* EDID 1.3 */
511 .revision = 3, /* EDID 1.3 */
512 .input = 0x08, /* Analog input */
513 .features = 0x0a, /* Pref timing in DTD 1 */
514 .standard_timings = { { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 },
515 { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 } },
516 .detailed_timings = { {
518 /* hactive = 848, hblank = 256 */
519 .data.pixel_data.hactive_lo = 0x50,
520 .data.pixel_data.hblank_lo = 0x00,
521 .data.pixel_data.hactive_hblank_hi = 0x31,
522 /* vactive = 480, vblank = 28 */
523 .data.pixel_data.vactive_lo = 0xe0,
524 .data.pixel_data.vblank_lo = 0x1c,
525 .data.pixel_data.vactive_vblank_hi = 0x10,
526 /* hsync offset 40 pw 128, vsync offset 1 pw 4 */
527 .data.pixel_data.hsync_offset_lo = 0x28,
528 .data.pixel_data.hsync_pulse_width_lo = 0x80,
529 .data.pixel_data.vsync_offset_pulse_width_lo = 0x14,
530 .data.pixel_data.hsync_vsync_offset_pulse_width_hi = 0x00,
531 /* Digital separate syncs, hsync+, vsync+ */
532 .data.pixel_data.misc = 0x1e,
535 .data.other_data.type = 0xfd, /* Monitor ranges */
536 .data.other_data.data.range.min_vfreq = 59,
537 .data.other_data.data.range.max_vfreq = 61,
538 .data.other_data.data.range.min_hfreq_khz = 29,
539 .data.other_data.data.range.max_hfreq_khz = 32,
540 .data.other_data.data.range.pixel_clock_mhz = 4, /* 40 MHz */
541 .data.other_data.data.range.flags = 0,
542 .data.other_data.data.range.formula.cvt = {
543 0xa0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 },
546 .data.other_data.type = 0xfc, /* Model string */
547 .data.other_data.data.str.str = {
548 'P', 'r', 'o', 'j', 'e', 'c', 't', 'o', 'r', '\n',
552 .data.other_data.type = 0xfe, /* Unspecified text / padding */
553 .data.other_data.data.str.str = {
554 '\n', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
560 static int gm12u320_conn_get_modes(struct drm_connector *connector)
562 drm_connector_update_edid_property(connector, &gm12u320_edid);
563 return drm_add_edid_modes(connector, &gm12u320_edid);
566 static const struct drm_connector_helper_funcs gm12u320_conn_helper_funcs = {
567 .get_modes = gm12u320_conn_get_modes,
570 static const struct drm_connector_funcs gm12u320_conn_funcs = {
571 .fill_modes = drm_helper_probe_single_connector_modes,
572 .destroy = drm_connector_cleanup,
573 .reset = drm_atomic_helper_connector_reset,
574 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
575 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
578 static int gm12u320_conn_init(struct gm12u320_device *gm12u320)
580 drm_connector_helper_add(&gm12u320->conn, &gm12u320_conn_helper_funcs);
581 return drm_connector_init(&gm12u320->dev, &gm12u320->conn,
582 &gm12u320_conn_funcs, DRM_MODE_CONNECTOR_VGA);
585 /* ------------------------------------------------------------------ */
586 /* gm12u320 (simple) display pipe */
588 static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe,
589 struct drm_crtc_state *crtc_state,
590 struct drm_plane_state *plane_state)
592 struct gm12u320_device *gm12u320 = pipe->crtc.dev->dev_private;
593 struct drm_rect rect = { 0, 0, GM12U320_USER_WIDTH, GM12U320_HEIGHT };
595 gm12u320_fb_mark_dirty(plane_state->fb, &rect);
596 gm12u320_start_fb_update(gm12u320);
597 gm12u320->pipe_enabled = true;
600 static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe)
602 struct gm12u320_device *gm12u320 = pipe->crtc.dev->dev_private;
604 gm12u320_stop_fb_update(gm12u320);
605 gm12u320->pipe_enabled = false;
608 static void gm12u320_pipe_update(struct drm_simple_display_pipe *pipe,
609 struct drm_plane_state *old_state)
611 struct drm_plane_state *state = pipe->plane.state;
612 struct drm_rect rect;
614 if (drm_atomic_helper_damage_merged(old_state, state, &rect))
615 gm12u320_fb_mark_dirty(pipe->plane.state->fb, &rect);
618 static const struct drm_simple_display_pipe_funcs gm12u320_pipe_funcs = {
619 .enable = gm12u320_pipe_enable,
620 .disable = gm12u320_pipe_disable,
621 .update = gm12u320_pipe_update,
624 static const uint32_t gm12u320_pipe_formats[] = {
628 static const uint64_t gm12u320_pipe_modifiers[] = {
629 DRM_FORMAT_MOD_LINEAR,
630 DRM_FORMAT_MOD_INVALID
633 static void gm12u320_driver_release(struct drm_device *dev)
635 struct gm12u320_device *gm12u320 = dev->dev_private;
637 gm12u320_usb_free(gm12u320);
638 drm_mode_config_cleanup(dev);
643 DEFINE_DRM_GEM_FOPS(gm12u320_fops);
645 static struct drm_driver gm12u320_drm_driver = {
646 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
651 .major = DRIVER_MAJOR,
652 .minor = DRIVER_MINOR,
654 .release = gm12u320_driver_release,
655 .fops = &gm12u320_fops,
656 DRM_GEM_SHMEM_DRIVER_OPS,
659 static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = {
660 .fb_create = drm_gem_fb_create_with_dirty,
661 .atomic_check = drm_atomic_helper_check,
662 .atomic_commit = drm_atomic_helper_commit,
665 static int gm12u320_usb_probe(struct usb_interface *interface,
666 const struct usb_device_id *id)
668 struct gm12u320_device *gm12u320;
669 struct drm_device *dev;
673 * The gm12u320 presents itself to the system as 2 usb mass-storage
674 * interfaces, we only care about / need the first one.
676 if (interface->cur_altsetting->desc.bInterfaceNumber != 0)
679 gm12u320 = kzalloc(sizeof(*gm12u320), GFP_KERNEL);
680 if (gm12u320 == NULL)
683 gm12u320->udev = interface_to_usbdev(interface);
684 INIT_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work);
685 mutex_init(&gm12u320->fb_update.lock);
686 init_waitqueue_head(&gm12u320->fb_update.waitq);
688 dev = &gm12u320->dev;
689 ret = drm_dev_init(dev, &gm12u320_drm_driver, &interface->dev);
694 dev->dev_private = gm12u320;
696 drm_mode_config_init(dev);
697 dev->mode_config.min_width = GM12U320_USER_WIDTH;
698 dev->mode_config.max_width = GM12U320_USER_WIDTH;
699 dev->mode_config.min_height = GM12U320_HEIGHT;
700 dev->mode_config.max_height = GM12U320_HEIGHT;
701 dev->mode_config.funcs = &gm12u320_mode_config_funcs;
703 ret = gm12u320_usb_alloc(gm12u320);
707 ret = gm12u320_set_ecomode(gm12u320);
711 ret = gm12u320_conn_init(gm12u320);
715 ret = drm_simple_display_pipe_init(&gm12u320->dev,
717 &gm12u320_pipe_funcs,
718 gm12u320_pipe_formats,
719 ARRAY_SIZE(gm12u320_pipe_formats),
720 gm12u320_pipe_modifiers,
725 drm_mode_config_reset(dev);
727 usb_set_intfdata(interface, dev);
728 ret = drm_dev_register(dev, 0);
732 drm_fbdev_generic_setup(dev, 0);
741 static void gm12u320_usb_disconnect(struct usb_interface *interface)
743 struct drm_device *dev = usb_get_intfdata(interface);
744 struct gm12u320_device *gm12u320 = dev->dev_private;
746 gm12u320_stop_fb_update(gm12u320);
751 static __maybe_unused int gm12u320_suspend(struct usb_interface *interface,
752 pm_message_t message)
754 struct drm_device *dev = usb_get_intfdata(interface);
755 struct gm12u320_device *gm12u320 = dev->dev_private;
757 if (gm12u320->pipe_enabled)
758 gm12u320_stop_fb_update(gm12u320);
763 static __maybe_unused int gm12u320_resume(struct usb_interface *interface)
765 struct drm_device *dev = usb_get_intfdata(interface);
766 struct gm12u320_device *gm12u320 = dev->dev_private;
768 gm12u320_set_ecomode(gm12u320);
769 if (gm12u320->pipe_enabled)
770 gm12u320_start_fb_update(gm12u320);
775 static const struct usb_device_id id_table[] = {
776 { USB_DEVICE(0x1de1, 0xc102) },
779 MODULE_DEVICE_TABLE(usb, id_table);
781 static struct usb_driver gm12u320_usb_driver = {
783 .probe = gm12u320_usb_probe,
784 .disconnect = gm12u320_usb_disconnect,
785 .id_table = id_table,
787 .suspend = gm12u320_suspend,
788 .resume = gm12u320_resume,
789 .reset_resume = gm12u320_resume,
793 module_usb_driver(gm12u320_usb_driver);
795 MODULE_LICENSE("GPL");