1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright 2019 Hans de Goede <hdegoede@redhat.com> 4 */ 5 6 #include <linux/dma-buf.h> 7 #include <linux/module.h> 8 #include <linux/usb.h> 9 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_managed.h> 23 #include <drm/drm_modeset_helper_vtables.h> 24 #include <drm/drm_probe_helper.h> 25 #include <drm/drm_simple_kms_helper.h> 26 27 static bool eco_mode; 28 module_param(eco_mode, bool, 0644); 29 MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)"); 30 31 #define DRIVER_NAME "gm12u320" 32 #define DRIVER_DESC "Grain Media GM12U320 USB projector display" 33 #define DRIVER_DATE "2019" 34 #define DRIVER_MAJOR 1 35 #define DRIVER_MINOR 0 36 37 /* 38 * The DLP has an actual width of 854 pixels, but that is not a multiple 39 * of 8, breaking things left and right, so we export a width of 848. 40 */ 41 #define GM12U320_USER_WIDTH 848 42 #define GM12U320_REAL_WIDTH 854 43 #define GM12U320_HEIGHT 480 44 45 #define GM12U320_BLOCK_COUNT 20 46 47 #define GM12U320_ERR(fmt, ...) \ 48 DRM_DEV_ERROR(gm12u320->dev.dev, fmt, ##__VA_ARGS__) 49 50 #define MISC_RCV_EPT 1 51 #define DATA_RCV_EPT 2 52 #define DATA_SND_EPT 3 53 #define MISC_SND_EPT 4 54 55 #define DATA_BLOCK_HEADER_SIZE 84 56 #define DATA_BLOCK_CONTENT_SIZE 64512 57 #define DATA_BLOCK_FOOTER_SIZE 20 58 #define DATA_BLOCK_SIZE (DATA_BLOCK_HEADER_SIZE + \ 59 DATA_BLOCK_CONTENT_SIZE + \ 60 DATA_BLOCK_FOOTER_SIZE) 61 #define DATA_LAST_BLOCK_CONTENT_SIZE 4032 62 #define DATA_LAST_BLOCK_SIZE (DATA_BLOCK_HEADER_SIZE + \ 63 DATA_LAST_BLOCK_CONTENT_SIZE + \ 64 DATA_BLOCK_FOOTER_SIZE) 65 66 #define CMD_SIZE 31 67 #define READ_STATUS_SIZE 13 68 #define MISC_VALUE_SIZE 4 69 70 #define CMD_TIMEOUT msecs_to_jiffies(200) 71 #define DATA_TIMEOUT msecs_to_jiffies(1000) 72 #define IDLE_TIMEOUT msecs_to_jiffies(2000) 73 #define FIRST_FRAME_TIMEOUT msecs_to_jiffies(2000) 74 75 #define MISC_REQ_GET_SET_ECO_A 0xff 76 #define MISC_REQ_GET_SET_ECO_B 0x35 77 /* Windows driver does once every second, with arg d = 1, other args 0 */ 78 #define MISC_REQ_UNKNOWN1_A 0xff 79 #define MISC_REQ_UNKNOWN1_B 0x38 80 /* Windows driver does this on init, with arg a, b = 0, c = 0xa0, d = 4 */ 81 #define MISC_REQ_UNKNOWN2_A 0xa5 82 #define MISC_REQ_UNKNOWN2_B 0x00 83 84 struct gm12u320_device { 85 struct drm_device dev; 86 struct drm_simple_display_pipe pipe; 87 struct drm_connector conn; 88 unsigned char *cmd_buf; 89 unsigned char *data_buf[GM12U320_BLOCK_COUNT]; 90 struct { 91 struct delayed_work work; 92 struct mutex lock; 93 struct drm_framebuffer *fb; 94 struct drm_rect rect; 95 int frame; 96 int draw_status_timeout; 97 } fb_update; 98 }; 99 100 #define to_gm12u320(__dev) container_of(__dev, struct gm12u320_device, dev) 101 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 107 }; 108 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 114 }; 115 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 121 }; 122 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 135 }; 136 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 149 }; 150 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 155 }; 156 157 static inline struct usb_device *gm12u320_to_usb_device(struct gm12u320_device *gm12u320) 158 { 159 return interface_to_usbdev(to_usb_interface(gm12u320->dev.dev)); 160 } 161 162 static int gm12u320_usb_alloc(struct gm12u320_device *gm12u320) 163 { 164 int i, block_size; 165 const char *hdr; 166 167 gm12u320->cmd_buf = drmm_kmalloc(&gm12u320->dev, CMD_SIZE, GFP_KERNEL); 168 if (!gm12u320->cmd_buf) 169 return -ENOMEM; 170 171 for (i = 0; i < GM12U320_BLOCK_COUNT; i++) { 172 if (i == GM12U320_BLOCK_COUNT - 1) { 173 block_size = DATA_LAST_BLOCK_SIZE; 174 hdr = data_last_block_header; 175 } else { 176 block_size = DATA_BLOCK_SIZE; 177 hdr = data_block_header; 178 } 179 180 gm12u320->data_buf[i] = drmm_kzalloc(&gm12u320->dev, 181 block_size, GFP_KERNEL); 182 if (!gm12u320->data_buf[i]) 183 return -ENOMEM; 184 185 memcpy(gm12u320->data_buf[i], hdr, DATA_BLOCK_HEADER_SIZE); 186 memcpy(gm12u320->data_buf[i] + 187 (block_size - DATA_BLOCK_FOOTER_SIZE), 188 data_block_footer, DATA_BLOCK_FOOTER_SIZE); 189 } 190 191 return 0; 192 } 193 194 static int gm12u320_misc_request(struct gm12u320_device *gm12u320, 195 u8 req_a, u8 req_b, 196 u8 arg_a, u8 arg_b, u8 arg_c, u8 arg_d) 197 { 198 struct usb_device *udev = gm12u320_to_usb_device(gm12u320); 199 int ret, len; 200 201 memcpy(gm12u320->cmd_buf, &cmd_misc, CMD_SIZE); 202 gm12u320->cmd_buf[20] = req_a; 203 gm12u320->cmd_buf[21] = req_b; 204 gm12u320->cmd_buf[22] = arg_a; 205 gm12u320->cmd_buf[23] = arg_b; 206 gm12u320->cmd_buf[24] = arg_c; 207 gm12u320->cmd_buf[25] = arg_d; 208 209 /* Send request */ 210 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, MISC_SND_EPT), 211 gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT); 212 if (ret || len != CMD_SIZE) { 213 GM12U320_ERR("Misc. req. error %d\n", ret); 214 return -EIO; 215 } 216 217 /* Read value */ 218 ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, MISC_RCV_EPT), 219 gm12u320->cmd_buf, MISC_VALUE_SIZE, &len, 220 DATA_TIMEOUT); 221 if (ret || len != MISC_VALUE_SIZE) { 222 GM12U320_ERR("Misc. value error %d\n", ret); 223 return -EIO; 224 } 225 /* cmd_buf[0] now contains the read value, which we don't use */ 226 227 /* Read status */ 228 ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, MISC_RCV_EPT), 229 gm12u320->cmd_buf, READ_STATUS_SIZE, &len, 230 CMD_TIMEOUT); 231 if (ret || len != READ_STATUS_SIZE) { 232 GM12U320_ERR("Misc. status error %d\n", ret); 233 return -EIO; 234 } 235 236 return 0; 237 } 238 239 static void gm12u320_32bpp_to_24bpp_packed(u8 *dst, u8 *src, int len) 240 { 241 while (len--) { 242 *dst++ = *src++; 243 *dst++ = *src++; 244 *dst++ = *src++; 245 src++; 246 } 247 } 248 249 static void gm12u320_copy_fb_to_blocks(struct gm12u320_device *gm12u320) 250 { 251 int block, dst_offset, len, remain, ret, x1, x2, y1, y2; 252 struct drm_framebuffer *fb; 253 struct dma_buf_map map; 254 void *vaddr; 255 u8 *src; 256 257 mutex_lock(&gm12u320->fb_update.lock); 258 259 if (!gm12u320->fb_update.fb) 260 goto unlock; 261 262 fb = gm12u320->fb_update.fb; 263 x1 = gm12u320->fb_update.rect.x1; 264 x2 = gm12u320->fb_update.rect.x2; 265 y1 = gm12u320->fb_update.rect.y1; 266 y2 = gm12u320->fb_update.rect.y2; 267 268 ret = drm_gem_shmem_vmap(fb->obj[0], &map); 269 if (ret) { 270 GM12U320_ERR("failed to vmap fb: %d\n", ret); 271 goto put_fb; 272 } 273 vaddr = map.vaddr; /* TODO: Use mapping abstraction properly */ 274 275 if (fb->obj[0]->import_attach) { 276 ret = dma_buf_begin_cpu_access( 277 fb->obj[0]->import_attach->dmabuf, DMA_FROM_DEVICE); 278 if (ret) { 279 GM12U320_ERR("dma_buf_begin_cpu_access err: %d\n", ret); 280 goto vunmap; 281 } 282 } 283 284 src = vaddr + y1 * fb->pitches[0] + x1 * 4; 285 286 x1 += (GM12U320_REAL_WIDTH - GM12U320_USER_WIDTH) / 2; 287 x2 += (GM12U320_REAL_WIDTH - GM12U320_USER_WIDTH) / 2; 288 289 for (; y1 < y2; y1++) { 290 remain = 0; 291 len = (x2 - x1) * 3; 292 dst_offset = (y1 * GM12U320_REAL_WIDTH + x1) * 3; 293 block = dst_offset / DATA_BLOCK_CONTENT_SIZE; 294 dst_offset %= DATA_BLOCK_CONTENT_SIZE; 295 296 if ((dst_offset + len) > DATA_BLOCK_CONTENT_SIZE) { 297 remain = dst_offset + len - DATA_BLOCK_CONTENT_SIZE; 298 len = DATA_BLOCK_CONTENT_SIZE - dst_offset; 299 } 300 301 dst_offset += DATA_BLOCK_HEADER_SIZE; 302 len /= 3; 303 304 gm12u320_32bpp_to_24bpp_packed( 305 gm12u320->data_buf[block] + dst_offset, 306 src, len); 307 308 if (remain) { 309 block++; 310 dst_offset = DATA_BLOCK_HEADER_SIZE; 311 gm12u320_32bpp_to_24bpp_packed( 312 gm12u320->data_buf[block] + dst_offset, 313 src + len * 4, remain / 3); 314 } 315 src += fb->pitches[0]; 316 } 317 318 if (fb->obj[0]->import_attach) { 319 ret = dma_buf_end_cpu_access(fb->obj[0]->import_attach->dmabuf, 320 DMA_FROM_DEVICE); 321 if (ret) 322 GM12U320_ERR("dma_buf_end_cpu_access err: %d\n", ret); 323 } 324 vunmap: 325 drm_gem_shmem_vunmap(fb->obj[0], &map); 326 put_fb: 327 drm_framebuffer_put(fb); 328 gm12u320->fb_update.fb = NULL; 329 unlock: 330 mutex_unlock(&gm12u320->fb_update.lock); 331 } 332 333 static void gm12u320_fb_update_work(struct work_struct *work) 334 { 335 struct gm12u320_device *gm12u320 = 336 container_of(to_delayed_work(work), struct gm12u320_device, 337 fb_update.work); 338 struct usb_device *udev = gm12u320_to_usb_device(gm12u320); 339 int block, block_size, len; 340 int ret = 0; 341 342 gm12u320_copy_fb_to_blocks(gm12u320); 343 344 for (block = 0; block < GM12U320_BLOCK_COUNT; block++) { 345 if (block == GM12U320_BLOCK_COUNT - 1) 346 block_size = DATA_LAST_BLOCK_SIZE; 347 else 348 block_size = DATA_BLOCK_SIZE; 349 350 /* Send data command to device */ 351 memcpy(gm12u320->cmd_buf, cmd_data, CMD_SIZE); 352 gm12u320->cmd_buf[8] = block_size & 0xff; 353 gm12u320->cmd_buf[9] = block_size >> 8; 354 gm12u320->cmd_buf[20] = 0xfc - block * 4; 355 gm12u320->cmd_buf[21] = 356 block | (gm12u320->fb_update.frame << 7); 357 358 ret = usb_bulk_msg(udev, 359 usb_sndbulkpipe(udev, DATA_SND_EPT), 360 gm12u320->cmd_buf, CMD_SIZE, &len, 361 CMD_TIMEOUT); 362 if (ret || len != CMD_SIZE) 363 goto err; 364 365 /* Send data block to device */ 366 ret = usb_bulk_msg(udev, 367 usb_sndbulkpipe(udev, DATA_SND_EPT), 368 gm12u320->data_buf[block], block_size, 369 &len, DATA_TIMEOUT); 370 if (ret || len != block_size) 371 goto err; 372 373 /* Read status */ 374 ret = usb_bulk_msg(udev, 375 usb_rcvbulkpipe(udev, DATA_RCV_EPT), 376 gm12u320->cmd_buf, READ_STATUS_SIZE, &len, 377 CMD_TIMEOUT); 378 if (ret || len != READ_STATUS_SIZE) 379 goto err; 380 } 381 382 /* Send draw command to device */ 383 memcpy(gm12u320->cmd_buf, cmd_draw, CMD_SIZE); 384 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, DATA_SND_EPT), 385 gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT); 386 if (ret || len != CMD_SIZE) 387 goto err; 388 389 /* Read status */ 390 ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, DATA_RCV_EPT), 391 gm12u320->cmd_buf, READ_STATUS_SIZE, &len, 392 gm12u320->fb_update.draw_status_timeout); 393 if (ret || len != READ_STATUS_SIZE) 394 goto err; 395 396 gm12u320->fb_update.draw_status_timeout = CMD_TIMEOUT; 397 gm12u320->fb_update.frame = !gm12u320->fb_update.frame; 398 399 /* 400 * We must draw a frame every 2s otherwise the projector 401 * switches back to showing its logo. 402 */ 403 queue_delayed_work(system_long_wq, &gm12u320->fb_update.work, 404 IDLE_TIMEOUT); 405 406 return; 407 err: 408 /* Do not log errors caused by module unload or device unplug */ 409 if (ret != -ENODEV && ret != -ECONNRESET && ret != -ESHUTDOWN) 410 GM12U320_ERR("Frame update error: %d\n", ret); 411 } 412 413 static void gm12u320_fb_mark_dirty(struct drm_framebuffer *fb, 414 struct drm_rect *dirty) 415 { 416 struct gm12u320_device *gm12u320 = to_gm12u320(fb->dev); 417 struct drm_framebuffer *old_fb = NULL; 418 bool wakeup = false; 419 420 mutex_lock(&gm12u320->fb_update.lock); 421 422 if (gm12u320->fb_update.fb != fb) { 423 old_fb = gm12u320->fb_update.fb; 424 drm_framebuffer_get(fb); 425 gm12u320->fb_update.fb = fb; 426 gm12u320->fb_update.rect = *dirty; 427 wakeup = true; 428 } else { 429 struct drm_rect *rect = &gm12u320->fb_update.rect; 430 431 rect->x1 = min(rect->x1, dirty->x1); 432 rect->y1 = min(rect->y1, dirty->y1); 433 rect->x2 = max(rect->x2, dirty->x2); 434 rect->y2 = max(rect->y2, dirty->y2); 435 } 436 437 mutex_unlock(&gm12u320->fb_update.lock); 438 439 if (wakeup) 440 mod_delayed_work(system_long_wq, &gm12u320->fb_update.work, 0); 441 442 if (old_fb) 443 drm_framebuffer_put(old_fb); 444 } 445 446 static void gm12u320_stop_fb_update(struct gm12u320_device *gm12u320) 447 { 448 struct drm_framebuffer *old_fb; 449 450 cancel_delayed_work_sync(&gm12u320->fb_update.work); 451 452 mutex_lock(&gm12u320->fb_update.lock); 453 old_fb = gm12u320->fb_update.fb; 454 gm12u320->fb_update.fb = NULL; 455 mutex_unlock(&gm12u320->fb_update.lock); 456 457 drm_framebuffer_put(old_fb); 458 } 459 460 static int gm12u320_set_ecomode(struct gm12u320_device *gm12u320) 461 { 462 return gm12u320_misc_request(gm12u320, MISC_REQ_GET_SET_ECO_A, 463 MISC_REQ_GET_SET_ECO_B, 0x01 /* set */, 464 eco_mode ? 0x01 : 0x00, 0x00, 0x01); 465 } 466 467 /* ------------------------------------------------------------------ */ 468 /* gm12u320 connector */ 469 470 /* 471 * We use fake EDID info so that userspace know that it is dealing with 472 * an Acer projector, rather then listing this as an "unknown" monitor. 473 * Note this assumes this driver is only ever used with the Acer C120, if we 474 * add support for other devices the vendor and model should be parameterized. 475 */ 476 static struct edid gm12u320_edid = { 477 .header = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }, 478 .mfg_id = { 0x04, 0x72 }, /* "ACR" */ 479 .prod_code = { 0x20, 0xc1 }, /* C120h */ 480 .serial = 0xaa55aa55, 481 .mfg_week = 1, 482 .mfg_year = 16, 483 .version = 1, /* EDID 1.3 */ 484 .revision = 3, /* EDID 1.3 */ 485 .input = 0x08, /* Analog input */ 486 .features = 0x0a, /* Pref timing in DTD 1 */ 487 .standard_timings = { { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 }, 488 { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 } }, 489 .detailed_timings = { { 490 .pixel_clock = 3383, 491 /* hactive = 848, hblank = 256 */ 492 .data.pixel_data.hactive_lo = 0x50, 493 .data.pixel_data.hblank_lo = 0x00, 494 .data.pixel_data.hactive_hblank_hi = 0x31, 495 /* vactive = 480, vblank = 28 */ 496 .data.pixel_data.vactive_lo = 0xe0, 497 .data.pixel_data.vblank_lo = 0x1c, 498 .data.pixel_data.vactive_vblank_hi = 0x10, 499 /* hsync offset 40 pw 128, vsync offset 1 pw 4 */ 500 .data.pixel_data.hsync_offset_lo = 0x28, 501 .data.pixel_data.hsync_pulse_width_lo = 0x80, 502 .data.pixel_data.vsync_offset_pulse_width_lo = 0x14, 503 .data.pixel_data.hsync_vsync_offset_pulse_width_hi = 0x00, 504 /* Digital separate syncs, hsync+, vsync+ */ 505 .data.pixel_data.misc = 0x1e, 506 }, { 507 .pixel_clock = 0, 508 .data.other_data.type = 0xfd, /* Monitor ranges */ 509 .data.other_data.data.range.min_vfreq = 59, 510 .data.other_data.data.range.max_vfreq = 61, 511 .data.other_data.data.range.min_hfreq_khz = 29, 512 .data.other_data.data.range.max_hfreq_khz = 32, 513 .data.other_data.data.range.pixel_clock_mhz = 4, /* 40 MHz */ 514 .data.other_data.data.range.flags = 0, 515 .data.other_data.data.range.formula.cvt = { 516 0xa0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 }, 517 }, { 518 .pixel_clock = 0, 519 .data.other_data.type = 0xfc, /* Model string */ 520 .data.other_data.data.str.str = { 521 'P', 'r', 'o', 'j', 'e', 'c', 't', 'o', 'r', '\n', 522 ' ', ' ', ' ' }, 523 }, { 524 .pixel_clock = 0, 525 .data.other_data.type = 0xfe, /* Unspecified text / padding */ 526 .data.other_data.data.str.str = { 527 '\n', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', 528 ' ', ' ', ' ' }, 529 } }, 530 .checksum = 0x13, 531 }; 532 533 static int gm12u320_conn_get_modes(struct drm_connector *connector) 534 { 535 drm_connector_update_edid_property(connector, &gm12u320_edid); 536 return drm_add_edid_modes(connector, &gm12u320_edid); 537 } 538 539 static const struct drm_connector_helper_funcs gm12u320_conn_helper_funcs = { 540 .get_modes = gm12u320_conn_get_modes, 541 }; 542 543 static const struct drm_connector_funcs gm12u320_conn_funcs = { 544 .fill_modes = drm_helper_probe_single_connector_modes, 545 .destroy = drm_connector_cleanup, 546 .reset = drm_atomic_helper_connector_reset, 547 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 548 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 549 }; 550 551 static int gm12u320_conn_init(struct gm12u320_device *gm12u320) 552 { 553 drm_connector_helper_add(&gm12u320->conn, &gm12u320_conn_helper_funcs); 554 return drm_connector_init(&gm12u320->dev, &gm12u320->conn, 555 &gm12u320_conn_funcs, DRM_MODE_CONNECTOR_VGA); 556 } 557 558 /* ------------------------------------------------------------------ */ 559 /* gm12u320 (simple) display pipe */ 560 561 static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe, 562 struct drm_crtc_state *crtc_state, 563 struct drm_plane_state *plane_state) 564 { 565 struct drm_rect rect = { 0, 0, GM12U320_USER_WIDTH, GM12U320_HEIGHT }; 566 struct gm12u320_device *gm12u320 = to_gm12u320(pipe->crtc.dev); 567 568 gm12u320->fb_update.draw_status_timeout = FIRST_FRAME_TIMEOUT; 569 gm12u320_fb_mark_dirty(plane_state->fb, &rect); 570 } 571 572 static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe) 573 { 574 struct gm12u320_device *gm12u320 = to_gm12u320(pipe->crtc.dev); 575 576 gm12u320_stop_fb_update(gm12u320); 577 } 578 579 static void gm12u320_pipe_update(struct drm_simple_display_pipe *pipe, 580 struct drm_plane_state *old_state) 581 { 582 struct drm_plane_state *state = pipe->plane.state; 583 struct drm_rect rect; 584 585 if (drm_atomic_helper_damage_merged(old_state, state, &rect)) 586 gm12u320_fb_mark_dirty(pipe->plane.state->fb, &rect); 587 } 588 589 static const struct drm_simple_display_pipe_funcs gm12u320_pipe_funcs = { 590 .enable = gm12u320_pipe_enable, 591 .disable = gm12u320_pipe_disable, 592 .update = gm12u320_pipe_update, 593 }; 594 595 static const uint32_t gm12u320_pipe_formats[] = { 596 DRM_FORMAT_XRGB8888, 597 }; 598 599 static const uint64_t gm12u320_pipe_modifiers[] = { 600 DRM_FORMAT_MOD_LINEAR, 601 DRM_FORMAT_MOD_INVALID 602 }; 603 604 DEFINE_DRM_GEM_FOPS(gm12u320_fops); 605 606 static const struct drm_driver gm12u320_drm_driver = { 607 .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC, 608 609 .name = DRIVER_NAME, 610 .desc = DRIVER_DESC, 611 .date = DRIVER_DATE, 612 .major = DRIVER_MAJOR, 613 .minor = DRIVER_MINOR, 614 615 .fops = &gm12u320_fops, 616 DRM_GEM_SHMEM_DRIVER_OPS, 617 }; 618 619 static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = { 620 .fb_create = drm_gem_fb_create_with_dirty, 621 .atomic_check = drm_atomic_helper_check, 622 .atomic_commit = drm_atomic_helper_commit, 623 }; 624 625 static int gm12u320_usb_probe(struct usb_interface *interface, 626 const struct usb_device_id *id) 627 { 628 struct gm12u320_device *gm12u320; 629 struct drm_device *dev; 630 int ret; 631 632 /* 633 * The gm12u320 presents itself to the system as 2 usb mass-storage 634 * interfaces, we only care about / need the first one. 635 */ 636 if (interface->cur_altsetting->desc.bInterfaceNumber != 0) 637 return -ENODEV; 638 639 gm12u320 = devm_drm_dev_alloc(&interface->dev, &gm12u320_drm_driver, 640 struct gm12u320_device, dev); 641 if (IS_ERR(gm12u320)) 642 return PTR_ERR(gm12u320); 643 644 INIT_DELAYED_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work); 645 mutex_init(&gm12u320->fb_update.lock); 646 647 dev = &gm12u320->dev; 648 649 ret = drmm_mode_config_init(dev); 650 if (ret) 651 return ret; 652 653 dev->mode_config.min_width = GM12U320_USER_WIDTH; 654 dev->mode_config.max_width = GM12U320_USER_WIDTH; 655 dev->mode_config.min_height = GM12U320_HEIGHT; 656 dev->mode_config.max_height = GM12U320_HEIGHT; 657 dev->mode_config.funcs = &gm12u320_mode_config_funcs; 658 659 ret = gm12u320_usb_alloc(gm12u320); 660 if (ret) 661 return ret; 662 663 ret = gm12u320_set_ecomode(gm12u320); 664 if (ret) 665 return ret; 666 667 ret = gm12u320_conn_init(gm12u320); 668 if (ret) 669 return ret; 670 671 ret = drm_simple_display_pipe_init(&gm12u320->dev, 672 &gm12u320->pipe, 673 &gm12u320_pipe_funcs, 674 gm12u320_pipe_formats, 675 ARRAY_SIZE(gm12u320_pipe_formats), 676 gm12u320_pipe_modifiers, 677 &gm12u320->conn); 678 if (ret) 679 return ret; 680 681 drm_mode_config_reset(dev); 682 683 usb_set_intfdata(interface, dev); 684 ret = drm_dev_register(dev, 0); 685 if (ret) 686 return ret; 687 688 drm_fbdev_generic_setup(dev, 0); 689 690 return 0; 691 } 692 693 static void gm12u320_usb_disconnect(struct usb_interface *interface) 694 { 695 struct drm_device *dev = usb_get_intfdata(interface); 696 697 drm_dev_unplug(dev); 698 drm_atomic_helper_shutdown(dev); 699 } 700 701 static __maybe_unused int gm12u320_suspend(struct usb_interface *interface, 702 pm_message_t message) 703 { 704 struct drm_device *dev = usb_get_intfdata(interface); 705 706 return drm_mode_config_helper_suspend(dev); 707 } 708 709 static __maybe_unused int gm12u320_resume(struct usb_interface *interface) 710 { 711 struct drm_device *dev = usb_get_intfdata(interface); 712 struct gm12u320_device *gm12u320 = to_gm12u320(dev); 713 714 gm12u320_set_ecomode(gm12u320); 715 716 return drm_mode_config_helper_resume(dev); 717 } 718 719 static const struct usb_device_id id_table[] = { 720 { USB_DEVICE(0x1de1, 0xc102) }, 721 {}, 722 }; 723 MODULE_DEVICE_TABLE(usb, id_table); 724 725 static struct usb_driver gm12u320_usb_driver = { 726 .name = "gm12u320", 727 .probe = gm12u320_usb_probe, 728 .disconnect = gm12u320_usb_disconnect, 729 .id_table = id_table, 730 #ifdef CONFIG_PM 731 .suspend = gm12u320_suspend, 732 .resume = gm12u320_resume, 733 .reset_resume = gm12u320_resume, 734 #endif 735 }; 736 737 module_usb_driver(gm12u320_usb_driver); 738 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 739 MODULE_LICENSE("GPL"); 740