Merge tag 'rpmsg-v5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/andersson...
[linux-2.6-microblaze.git] / drivers / gpu / drm / gud / gud_connector.c
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright 2020 Noralf Trønnes
4  */
5
6 #include <linux/backlight.h>
7 #include <linux/workqueue.h>
8
9 #include <drm/drm_atomic.h>
10 #include <drm/drm_atomic_state_helper.h>
11 #include <drm/drm_connector.h>
12 #include <drm/drm_drv.h>
13 #include <drm/drm_encoder.h>
14 #include <drm/drm_file.h>
15 #include <drm/drm_modeset_helper_vtables.h>
16 #include <drm/drm_print.h>
17 #include <drm/drm_probe_helper.h>
18 #include <drm/drm_simple_kms_helper.h>
19 #include <drm/gud.h>
20
21 #include "gud_internal.h"
22
23 struct gud_connector {
24         struct drm_connector connector;
25         struct drm_encoder encoder;
26         struct backlight_device *backlight;
27         struct work_struct backlight_work;
28
29         /* Supported properties */
30         u16 *properties;
31         unsigned int num_properties;
32
33         /* Initial gadget tv state if applicable, applied on state reset */
34         struct drm_tv_connector_state initial_tv_state;
35
36         /*
37          * Initial gadget backlight brightness if applicable, applied on state reset.
38          * The value -ENODEV is used to signal no backlight.
39          */
40         int initial_brightness;
41 };
42
43 static inline struct gud_connector *to_gud_connector(struct drm_connector *connector)
44 {
45         return container_of(connector, struct gud_connector, connector);
46 }
47
48 static void gud_conn_err(struct drm_connector *connector, const char *msg, int ret)
49 {
50         dev_err(connector->dev->dev, "%s: %s (ret=%d)\n", connector->name, msg, ret);
51 }
52
53 /*
54  * Use a worker to avoid taking kms locks inside the backlight lock.
55  * Other display drivers use backlight within their kms locks.
56  * This avoids inconsistent locking rules, which would upset lockdep.
57  */
58 static void gud_connector_backlight_update_status_work(struct work_struct *work)
59 {
60         struct gud_connector *gconn = container_of(work, struct gud_connector, backlight_work);
61         struct drm_connector *connector = &gconn->connector;
62         struct drm_connector_state *connector_state;
63         struct drm_device *drm = connector->dev;
64         struct drm_modeset_acquire_ctx ctx;
65         struct drm_atomic_state *state;
66         int idx, ret;
67
68         if (!drm_dev_enter(drm, &idx))
69                 return;
70
71         state = drm_atomic_state_alloc(drm);
72         if (!state) {
73                 ret = -ENOMEM;
74                 goto exit;
75         }
76
77         drm_modeset_acquire_init(&ctx, 0);
78         state->acquire_ctx = &ctx;
79 retry:
80         connector_state = drm_atomic_get_connector_state(state, connector);
81         if (IS_ERR(connector_state)) {
82                 ret = PTR_ERR(connector_state);
83                 goto out;
84         }
85
86         /* Reuse tv.brightness to avoid having to subclass */
87         connector_state->tv.brightness = gconn->backlight->props.brightness;
88
89         ret = drm_atomic_commit(state);
90 out:
91         if (ret == -EDEADLK) {
92                 drm_atomic_state_clear(state);
93                 drm_modeset_backoff(&ctx);
94                 goto retry;
95         }
96
97         drm_atomic_state_put(state);
98
99         drm_modeset_drop_locks(&ctx);
100         drm_modeset_acquire_fini(&ctx);
101 exit:
102         drm_dev_exit(idx);
103
104         if (ret)
105                 dev_err(drm->dev, "Failed to update backlight, err=%d\n", ret);
106 }
107
108 static int gud_connector_backlight_update_status(struct backlight_device *bd)
109 {
110         struct drm_connector *connector = bl_get_data(bd);
111         struct gud_connector *gconn = to_gud_connector(connector);
112
113         /* The USB timeout is 5 seconds so use system_long_wq for worst case scenario */
114         queue_work(system_long_wq, &gconn->backlight_work);
115
116         return 0;
117 }
118
119 static const struct backlight_ops gud_connector_backlight_ops = {
120         .update_status  = gud_connector_backlight_update_status,
121 };
122
123 static int gud_connector_backlight_register(struct gud_connector *gconn)
124 {
125         struct drm_connector *connector = &gconn->connector;
126         struct backlight_device *bd;
127         const char *name;
128         const struct backlight_properties props = {
129                 .type = BACKLIGHT_RAW,
130                 .scale = BACKLIGHT_SCALE_NON_LINEAR,
131                 .max_brightness = 100,
132                 .brightness = gconn->initial_brightness,
133         };
134
135         name = kasprintf(GFP_KERNEL, "card%d-%s-backlight",
136                          connector->dev->primary->index, connector->name);
137         if (!name)
138                 return -ENOMEM;
139
140         bd = backlight_device_register(name, connector->kdev, connector,
141                                        &gud_connector_backlight_ops, &props);
142         kfree(name);
143         if (IS_ERR(bd))
144                 return PTR_ERR(bd);
145
146         gconn->backlight = bd;
147
148         return 0;
149 }
150
151 static int gud_connector_detect(struct drm_connector *connector,
152                                 struct drm_modeset_acquire_ctx *ctx, bool force)
153 {
154         struct gud_device *gdrm = to_gud_device(connector->dev);
155         int idx, ret;
156         u8 status;
157
158         if (!drm_dev_enter(connector->dev, &idx))
159                 return connector_status_disconnected;
160
161         if (force) {
162                 ret = gud_usb_set(gdrm, GUD_REQ_SET_CONNECTOR_FORCE_DETECT,
163                                   connector->index, NULL, 0);
164                 if (ret) {
165                         ret = connector_status_unknown;
166                         goto exit;
167                 }
168         }
169
170         ret = gud_usb_get_u8(gdrm, GUD_REQ_GET_CONNECTOR_STATUS, connector->index, &status);
171         if (ret) {
172                 ret = connector_status_unknown;
173                 goto exit;
174         }
175
176         switch (status & GUD_CONNECTOR_STATUS_CONNECTED_MASK) {
177         case GUD_CONNECTOR_STATUS_DISCONNECTED:
178                 ret = connector_status_disconnected;
179                 break;
180         case GUD_CONNECTOR_STATUS_CONNECTED:
181                 ret = connector_status_connected;
182                 break;
183         default:
184                 ret = connector_status_unknown;
185                 break;
186         }
187
188         if (status & GUD_CONNECTOR_STATUS_CHANGED)
189                 connector->epoch_counter += 1;
190 exit:
191         drm_dev_exit(idx);
192
193         return ret;
194 }
195
196 struct gud_connector_get_edid_ctx {
197         void *buf;
198         size_t len;
199         bool edid_override;
200 };
201
202 static int gud_connector_get_edid_block(void *data, u8 *buf, unsigned int block, size_t len)
203 {
204         struct gud_connector_get_edid_ctx *ctx = data;
205         size_t start = block * EDID_LENGTH;
206
207         ctx->edid_override = false;
208
209         if (start + len > ctx->len)
210                 return -1;
211
212         memcpy(buf, ctx->buf + start, len);
213
214         return 0;
215 }
216
217 static int gud_connector_get_modes(struct drm_connector *connector)
218 {
219         struct gud_device *gdrm = to_gud_device(connector->dev);
220         struct gud_display_mode_req *reqmodes = NULL;
221         struct gud_connector_get_edid_ctx edid_ctx;
222         unsigned int i, num_modes = 0;
223         struct edid *edid = NULL;
224         int idx, ret;
225
226         if (!drm_dev_enter(connector->dev, &idx))
227                 return 0;
228
229         edid_ctx.edid_override = true;
230         edid_ctx.buf = kmalloc(GUD_CONNECTOR_MAX_EDID_LEN, GFP_KERNEL);
231         if (!edid_ctx.buf)
232                 goto out;
233
234         ret = gud_usb_get(gdrm, GUD_REQ_GET_CONNECTOR_EDID, connector->index,
235                           edid_ctx.buf, GUD_CONNECTOR_MAX_EDID_LEN);
236         if (ret > 0 && ret % EDID_LENGTH) {
237                 gud_conn_err(connector, "Invalid EDID size", ret);
238         } else if (ret > 0) {
239                 edid_ctx.len = ret;
240                 edid = drm_do_get_edid(connector, gud_connector_get_edid_block, &edid_ctx);
241         }
242
243         kfree(edid_ctx.buf);
244         drm_connector_update_edid_property(connector, edid);
245
246         if (edid && edid_ctx.edid_override)
247                 goto out;
248
249         reqmodes = kmalloc_array(GUD_CONNECTOR_MAX_NUM_MODES, sizeof(*reqmodes), GFP_KERNEL);
250         if (!reqmodes)
251                 goto out;
252
253         ret = gud_usb_get(gdrm, GUD_REQ_GET_CONNECTOR_MODES, connector->index,
254                           reqmodes, GUD_CONNECTOR_MAX_NUM_MODES * sizeof(*reqmodes));
255         if (ret <= 0)
256                 goto out;
257         if (ret % sizeof(*reqmodes)) {
258                 gud_conn_err(connector, "Invalid display mode array size", ret);
259                 goto out;
260         }
261
262         num_modes = ret / sizeof(*reqmodes);
263
264         for (i = 0; i < num_modes; i++) {
265                 struct drm_display_mode *mode;
266
267                 mode = drm_mode_create(connector->dev);
268                 if (!mode) {
269                         num_modes = i;
270                         goto out;
271                 }
272
273                 gud_to_display_mode(mode, &reqmodes[i]);
274                 drm_mode_probed_add(connector, mode);
275         }
276 out:
277         if (!num_modes)
278                 num_modes = drm_add_edid_modes(connector, edid);
279
280         kfree(reqmodes);
281         kfree(edid);
282         drm_dev_exit(idx);
283
284         return num_modes;
285 }
286
287 static int gud_connector_atomic_check(struct drm_connector *connector,
288                                       struct drm_atomic_state *state)
289 {
290         struct drm_connector_state *new_state;
291         struct drm_crtc_state *new_crtc_state;
292         struct drm_connector_state *old_state;
293
294         new_state = drm_atomic_get_new_connector_state(state, connector);
295         if (!new_state->crtc)
296                 return 0;
297
298         old_state = drm_atomic_get_old_connector_state(state, connector);
299         new_crtc_state = drm_atomic_get_new_crtc_state(state, new_state->crtc);
300
301         if (old_state->tv.margins.left != new_state->tv.margins.left ||
302             old_state->tv.margins.right != new_state->tv.margins.right ||
303             old_state->tv.margins.top != new_state->tv.margins.top ||
304             old_state->tv.margins.bottom != new_state->tv.margins.bottom ||
305             old_state->tv.mode != new_state->tv.mode ||
306             old_state->tv.brightness != new_state->tv.brightness ||
307             old_state->tv.contrast != new_state->tv.contrast ||
308             old_state->tv.flicker_reduction != new_state->tv.flicker_reduction ||
309             old_state->tv.overscan != new_state->tv.overscan ||
310             old_state->tv.saturation != new_state->tv.saturation ||
311             old_state->tv.hue != new_state->tv.hue)
312                 new_crtc_state->connectors_changed = true;
313
314         return 0;
315 }
316
317 static const struct drm_connector_helper_funcs gud_connector_helper_funcs = {
318         .detect_ctx = gud_connector_detect,
319         .get_modes = gud_connector_get_modes,
320         .atomic_check = gud_connector_atomic_check,
321 };
322
323 static int gud_connector_late_register(struct drm_connector *connector)
324 {
325         struct gud_connector *gconn = to_gud_connector(connector);
326
327         if (gconn->initial_brightness < 0)
328                 return 0;
329
330         return gud_connector_backlight_register(gconn);
331 }
332
333 static void gud_connector_early_unregister(struct drm_connector *connector)
334 {
335         struct gud_connector *gconn = to_gud_connector(connector);
336
337         backlight_device_unregister(gconn->backlight);
338         cancel_work_sync(&gconn->backlight_work);
339 }
340
341 static void gud_connector_destroy(struct drm_connector *connector)
342 {
343         struct gud_connector *gconn = to_gud_connector(connector);
344
345         drm_connector_cleanup(connector);
346         kfree(gconn->properties);
347         kfree(gconn);
348 }
349
350 static void gud_connector_reset(struct drm_connector *connector)
351 {
352         struct gud_connector *gconn = to_gud_connector(connector);
353
354         drm_atomic_helper_connector_reset(connector);
355         connector->state->tv = gconn->initial_tv_state;
356         /* Set margins from command line */
357         drm_atomic_helper_connector_tv_reset(connector);
358         if (gconn->initial_brightness >= 0)
359                 connector->state->tv.brightness = gconn->initial_brightness;
360 }
361
362 static const struct drm_connector_funcs gud_connector_funcs = {
363         .fill_modes = drm_helper_probe_single_connector_modes,
364         .late_register = gud_connector_late_register,
365         .early_unregister = gud_connector_early_unregister,
366         .destroy = gud_connector_destroy,
367         .reset = gud_connector_reset,
368         .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
369         .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
370 };
371
372 /*
373  * The tv.mode property is shared among the connectors and its enum names are
374  * driver specific. This means that if more than one connector uses tv.mode,
375  * the enum names has to be the same.
376  */
377 static int gud_connector_add_tv_mode(struct gud_device *gdrm, struct drm_connector *connector)
378 {
379         size_t buf_len = GUD_CONNECTOR_TV_MODE_MAX_NUM * GUD_CONNECTOR_TV_MODE_NAME_LEN;
380         const char *modes[GUD_CONNECTOR_TV_MODE_MAX_NUM];
381         unsigned int i, num_modes;
382         char *buf;
383         int ret;
384
385         buf = kmalloc(buf_len, GFP_KERNEL);
386         if (!buf)
387                 return -ENOMEM;
388
389         ret = gud_usb_get(gdrm, GUD_REQ_GET_CONNECTOR_TV_MODE_VALUES,
390                           connector->index, buf, buf_len);
391         if (ret < 0)
392                 goto free;
393         if (!ret || ret % GUD_CONNECTOR_TV_MODE_NAME_LEN) {
394                 ret = -EIO;
395                 goto free;
396         }
397
398         num_modes = ret / GUD_CONNECTOR_TV_MODE_NAME_LEN;
399         for (i = 0; i < num_modes; i++)
400                 modes[i] = &buf[i * GUD_CONNECTOR_TV_MODE_NAME_LEN];
401
402         ret = drm_mode_create_tv_properties(connector->dev, num_modes, modes);
403 free:
404         kfree(buf);
405         if (ret < 0)
406                 gud_conn_err(connector, "Failed to add TV modes", ret);
407
408         return ret;
409 }
410
411 static struct drm_property *
412 gud_connector_property_lookup(struct drm_connector *connector, u16 prop)
413 {
414         struct drm_mode_config *config = &connector->dev->mode_config;
415
416         switch (prop) {
417         case GUD_PROPERTY_TV_LEFT_MARGIN:
418                 return config->tv_left_margin_property;
419         case GUD_PROPERTY_TV_RIGHT_MARGIN:
420                 return config->tv_right_margin_property;
421         case GUD_PROPERTY_TV_TOP_MARGIN:
422                 return config->tv_top_margin_property;
423         case GUD_PROPERTY_TV_BOTTOM_MARGIN:
424                 return config->tv_bottom_margin_property;
425         case GUD_PROPERTY_TV_MODE:
426                 return config->tv_mode_property;
427         case GUD_PROPERTY_TV_BRIGHTNESS:
428                 return config->tv_brightness_property;
429         case GUD_PROPERTY_TV_CONTRAST:
430                 return config->tv_contrast_property;
431         case GUD_PROPERTY_TV_FLICKER_REDUCTION:
432                 return config->tv_flicker_reduction_property;
433         case GUD_PROPERTY_TV_OVERSCAN:
434                 return config->tv_overscan_property;
435         case GUD_PROPERTY_TV_SATURATION:
436                 return config->tv_saturation_property;
437         case GUD_PROPERTY_TV_HUE:
438                 return config->tv_hue_property;
439         default:
440                 return ERR_PTR(-EINVAL);
441         }
442 }
443
444 static unsigned int *gud_connector_tv_state_val(u16 prop, struct drm_tv_connector_state *state)
445 {
446         switch (prop) {
447         case GUD_PROPERTY_TV_LEFT_MARGIN:
448                 return &state->margins.left;
449         case GUD_PROPERTY_TV_RIGHT_MARGIN:
450                 return &state->margins.right;
451         case GUD_PROPERTY_TV_TOP_MARGIN:
452                 return &state->margins.top;
453         case GUD_PROPERTY_TV_BOTTOM_MARGIN:
454                 return &state->margins.bottom;
455         case GUD_PROPERTY_TV_MODE:
456                 return &state->mode;
457         case GUD_PROPERTY_TV_BRIGHTNESS:
458                 return &state->brightness;
459         case GUD_PROPERTY_TV_CONTRAST:
460                 return &state->contrast;
461         case GUD_PROPERTY_TV_FLICKER_REDUCTION:
462                 return &state->flicker_reduction;
463         case GUD_PROPERTY_TV_OVERSCAN:
464                 return &state->overscan;
465         case GUD_PROPERTY_TV_SATURATION:
466                 return &state->saturation;
467         case GUD_PROPERTY_TV_HUE:
468                 return &state->hue;
469         default:
470                 return ERR_PTR(-EINVAL);
471         }
472 }
473
474 static int gud_connector_add_properties(struct gud_device *gdrm, struct gud_connector *gconn)
475 {
476         struct drm_connector *connector = &gconn->connector;
477         struct drm_device *drm = &gdrm->drm;
478         struct gud_property_req *properties;
479         unsigned int i, num_properties;
480         int ret;
481
482         properties = kcalloc(GUD_CONNECTOR_PROPERTIES_MAX_NUM, sizeof(*properties), GFP_KERNEL);
483         if (!properties)
484                 return -ENOMEM;
485
486         ret = gud_usb_get(gdrm, GUD_REQ_GET_CONNECTOR_PROPERTIES, connector->index,
487                           properties, GUD_CONNECTOR_PROPERTIES_MAX_NUM * sizeof(*properties));
488         if (ret <= 0)
489                 goto out;
490         if (ret % sizeof(*properties)) {
491                 ret = -EIO;
492                 goto out;
493         }
494
495         num_properties = ret / sizeof(*properties);
496         ret = 0;
497
498         gconn->properties = kcalloc(num_properties, sizeof(*gconn->properties), GFP_KERNEL);
499         if (!gconn->properties) {
500                 ret = -ENOMEM;
501                 goto out;
502         }
503
504         for (i = 0; i < num_properties; i++) {
505                 u16 prop = le16_to_cpu(properties[i].prop);
506                 u64 val = le64_to_cpu(properties[i].val);
507                 struct drm_property *property;
508                 unsigned int *state_val;
509
510                 drm_dbg(drm, "property: %u = %llu(0x%llx)\n", prop, val, val);
511
512                 switch (prop) {
513                 case GUD_PROPERTY_TV_LEFT_MARGIN:
514                         fallthrough;
515                 case GUD_PROPERTY_TV_RIGHT_MARGIN:
516                         fallthrough;
517                 case GUD_PROPERTY_TV_TOP_MARGIN:
518                         fallthrough;
519                 case GUD_PROPERTY_TV_BOTTOM_MARGIN:
520                         ret = drm_mode_create_tv_margin_properties(drm);
521                         if (ret)
522                                 goto out;
523                         break;
524                 case GUD_PROPERTY_TV_MODE:
525                         ret = gud_connector_add_tv_mode(gdrm, connector);
526                         if (ret)
527                                 goto out;
528                         break;
529                 case GUD_PROPERTY_TV_BRIGHTNESS:
530                         fallthrough;
531                 case GUD_PROPERTY_TV_CONTRAST:
532                         fallthrough;
533                 case GUD_PROPERTY_TV_FLICKER_REDUCTION:
534                         fallthrough;
535                 case GUD_PROPERTY_TV_OVERSCAN:
536                         fallthrough;
537                 case GUD_PROPERTY_TV_SATURATION:
538                         fallthrough;
539                 case GUD_PROPERTY_TV_HUE:
540                         /* This is a no-op if already added. */
541                         ret = drm_mode_create_tv_properties(drm, 0, NULL);
542                         if (ret)
543                                 goto out;
544                         break;
545                 case GUD_PROPERTY_BACKLIGHT_BRIGHTNESS:
546                         if (val > 100) {
547                                 ret = -EINVAL;
548                                 goto out;
549                         }
550                         gconn->initial_brightness = val;
551                         break;
552                 default:
553                         /* New ones might show up in future devices, skip those we don't know. */
554                         drm_dbg(drm, "Ignoring unknown property: %u\n", prop);
555                         continue;
556                 }
557
558                 gconn->properties[gconn->num_properties++] = prop;
559
560                 if (prop == GUD_PROPERTY_BACKLIGHT_BRIGHTNESS)
561                         continue; /* not a DRM property */
562
563                 property = gud_connector_property_lookup(connector, prop);
564                 if (WARN_ON(IS_ERR(property)))
565                         continue;
566
567                 state_val = gud_connector_tv_state_val(prop, &gconn->initial_tv_state);
568                 if (WARN_ON(IS_ERR(state_val)))
569                         continue;
570
571                 *state_val = val;
572                 drm_object_attach_property(&connector->base, property, 0);
573         }
574 out:
575         kfree(properties);
576
577         return ret;
578 }
579
580 int gud_connector_fill_properties(struct drm_connector_state *connector_state,
581                                   struct gud_property_req *properties)
582 {
583         struct gud_connector *gconn = to_gud_connector(connector_state->connector);
584         unsigned int i;
585
586         for (i = 0; i < gconn->num_properties; i++) {
587                 u16 prop = gconn->properties[i];
588                 u64 val;
589
590                 if (prop == GUD_PROPERTY_BACKLIGHT_BRIGHTNESS) {
591                         val = connector_state->tv.brightness;
592                 } else {
593                         unsigned int *state_val;
594
595                         state_val = gud_connector_tv_state_val(prop, &connector_state->tv);
596                         if (WARN_ON_ONCE(IS_ERR(state_val)))
597                                 return PTR_ERR(state_val);
598
599                         val = *state_val;
600                 }
601
602                 properties[i].prop = cpu_to_le16(prop);
603                 properties[i].val = cpu_to_le64(val);
604         }
605
606         return gconn->num_properties;
607 }
608
609 static int gud_connector_create(struct gud_device *gdrm, unsigned int index,
610                                 struct gud_connector_descriptor_req *desc)
611 {
612         struct drm_device *drm = &gdrm->drm;
613         struct gud_connector *gconn;
614         struct drm_connector *connector;
615         struct drm_encoder *encoder;
616         int ret, connector_type;
617         u32 flags;
618
619         gconn = kzalloc(sizeof(*gconn), GFP_KERNEL);
620         if (!gconn)
621                 return -ENOMEM;
622
623         INIT_WORK(&gconn->backlight_work, gud_connector_backlight_update_status_work);
624         gconn->initial_brightness = -ENODEV;
625         flags = le32_to_cpu(desc->flags);
626         connector = &gconn->connector;
627
628         drm_dbg(drm, "Connector: index=%u type=%u flags=0x%x\n", index, desc->connector_type, flags);
629
630         switch (desc->connector_type) {
631         case GUD_CONNECTOR_TYPE_PANEL:
632                 connector_type = DRM_MODE_CONNECTOR_USB;
633                 break;
634         case GUD_CONNECTOR_TYPE_VGA:
635                 connector_type = DRM_MODE_CONNECTOR_VGA;
636                 break;
637         case GUD_CONNECTOR_TYPE_DVI:
638                 connector_type = DRM_MODE_CONNECTOR_DVID;
639                 break;
640         case GUD_CONNECTOR_TYPE_COMPOSITE:
641                 connector_type = DRM_MODE_CONNECTOR_Composite;
642                 break;
643         case GUD_CONNECTOR_TYPE_SVIDEO:
644                 connector_type = DRM_MODE_CONNECTOR_SVIDEO;
645                 break;
646         case GUD_CONNECTOR_TYPE_COMPONENT:
647                 connector_type = DRM_MODE_CONNECTOR_Component;
648                 break;
649         case GUD_CONNECTOR_TYPE_DISPLAYPORT:
650                 connector_type = DRM_MODE_CONNECTOR_DisplayPort;
651                 break;
652         case GUD_CONNECTOR_TYPE_HDMI:
653                 connector_type = DRM_MODE_CONNECTOR_HDMIA;
654                 break;
655         default: /* future types */
656                 connector_type = DRM_MODE_CONNECTOR_USB;
657                 break;
658         }
659
660         drm_connector_helper_add(connector, &gud_connector_helper_funcs);
661         ret = drm_connector_init(drm, connector, &gud_connector_funcs, connector_type);
662         if (ret) {
663                 kfree(connector);
664                 return ret;
665         }
666
667         if (WARN_ON(connector->index != index))
668                 return -EINVAL;
669
670         if (flags & GUD_CONNECTOR_FLAGS_POLL_STATUS)
671                 connector->polled = (DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT);
672         if (flags & GUD_CONNECTOR_FLAGS_INTERLACE)
673                 connector->interlace_allowed = true;
674         if (flags & GUD_CONNECTOR_FLAGS_DOUBLESCAN)
675                 connector->doublescan_allowed = true;
676
677         ret = gud_connector_add_properties(gdrm, gconn);
678         if (ret) {
679                 gud_conn_err(connector, "Failed to add properties", ret);
680                 return ret;
681         }
682
683         /* The first connector is attached to the existing simple pipe encoder */
684         if (!connector->index) {
685                 encoder = &gdrm->pipe.encoder;
686         } else {
687                 encoder = &gconn->encoder;
688
689                 ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_NONE);
690                 if (ret)
691                         return ret;
692
693                 encoder->possible_crtcs = 1;
694         }
695
696         return drm_connector_attach_encoder(connector, encoder);
697 }
698
699 int gud_get_connectors(struct gud_device *gdrm)
700 {
701         struct gud_connector_descriptor_req *descs;
702         unsigned int i, num_connectors;
703         int ret;
704
705         descs = kmalloc_array(GUD_CONNECTORS_MAX_NUM, sizeof(*descs), GFP_KERNEL);
706         if (!descs)
707                 return -ENOMEM;
708
709         ret = gud_usb_get(gdrm, GUD_REQ_GET_CONNECTORS, 0,
710                           descs, GUD_CONNECTORS_MAX_NUM * sizeof(*descs));
711         if (ret < 0)
712                 goto free;
713         if (!ret || ret % sizeof(*descs)) {
714                 ret = -EIO;
715                 goto free;
716         }
717
718         num_connectors = ret / sizeof(*descs);
719
720         for (i = 0; i < num_connectors; i++) {
721                 ret = gud_connector_create(gdrm, i, &descs[i]);
722                 if (ret)
723                         goto free;
724         }
725 free:
726         kfree(descs);
727
728         return ret;
729 }