2 * Copyright (C) 2012 Red Hat
3 * based in parts on udlfb.c:
4 * Copyright (C) 2009 Roberto De Ioris <roberto@unbit.it>
5 * Copyright (C) 2009 Jaya Kumar <jayakumar.lkml@gmail.com>
6 * Copyright (C) 2009 Bernie Thompson <bernie@plugable.com>
8 * This file is subject to the terms and conditions of the GNU General Public
9 * License v2. See the file COPYING in the main directory of this archive for
14 #include <drm/drm_crtc.h>
15 #include <drm/drm_edid.h>
16 #include <drm/drm_crtc_helper.h>
19 /* dummy connector to just get EDID,
20 all UDL appear to have a DVI-D */
22 static u8
*udl_get_edid(struct udl_device
*udl
)
28 block
= kmalloc(EDID_LENGTH
, GFP_KERNEL
);
32 rbuf
= kmalloc(2, GFP_KERNEL
);
36 for (i
= 0; i
< EDID_LENGTH
; i
++) {
37 ret
= usb_control_msg(udl
->udev
,
38 usb_rcvctrlpipe(udl
->udev
, 0), (0x02),
39 (0x80 | (0x02 << 5)), i
<< 8, 0xA1, rbuf
, 2,
42 DRM_ERROR("Read EDID byte %d failed err %x\n", i
, ret
);
57 static int udl_get_modes(struct drm_connector
*connector
)
59 struct udl_device
*udl
= connector
->dev
->dev_private
;
63 edid
= (struct edid
*)udl_get_edid(udl
);
65 drm_mode_connector_update_edid_property(connector
, NULL
);
70 * We only read the main block, but if the monitor reports extension
71 * blocks then the drm edid code expects them to be present, so patch
72 * the extension count to 0.
74 edid
->checksum
+= edid
->extensions
;
77 drm_mode_connector_update_edid_property(connector
, edid
);
78 ret
= drm_add_edid_modes(connector
, edid
);
83 static int udl_mode_valid(struct drm_connector
*connector
,
84 struct drm_display_mode
*mode
)
86 struct udl_device
*udl
= connector
->dev
->dev_private
;
87 if (!udl
->sku_pixel_limit
)
90 if (mode
->vdisplay
* mode
->hdisplay
> udl
->sku_pixel_limit
)
91 return MODE_VIRTUAL_Y
;
96 static enum drm_connector_status
97 udl_detect(struct drm_connector
*connector
, bool force
)
99 if (drm_device_is_unplugged(connector
->dev
))
100 return connector_status_disconnected
;
101 return connector_status_connected
;
104 static struct drm_encoder
*
105 udl_best_single_encoder(struct drm_connector
*connector
)
107 int enc_id
= connector
->encoder_ids
[0];
108 return drm_encoder_find(connector
->dev
, enc_id
);
111 static int udl_connector_set_property(struct drm_connector
*connector
,
112 struct drm_property
*property
,
118 static void udl_connector_destroy(struct drm_connector
*connector
)
120 drm_connector_unregister(connector
);
121 drm_connector_cleanup(connector
);
125 static const struct drm_connector_helper_funcs udl_connector_helper_funcs
= {
126 .get_modes
= udl_get_modes
,
127 .mode_valid
= udl_mode_valid
,
128 .best_encoder
= udl_best_single_encoder
,
131 static const struct drm_connector_funcs udl_connector_funcs
= {
132 .dpms
= drm_helper_connector_dpms
,
133 .detect
= udl_detect
,
134 .fill_modes
= drm_helper_probe_single_connector_modes
,
135 .destroy
= udl_connector_destroy
,
136 .set_property
= udl_connector_set_property
,
139 int udl_connector_init(struct drm_device
*dev
, struct drm_encoder
*encoder
)
141 struct drm_connector
*connector
;
143 connector
= kzalloc(sizeof(struct drm_connector
), GFP_KERNEL
);
147 drm_connector_init(dev
, connector
, &udl_connector_funcs
, DRM_MODE_CONNECTOR_DVII
);
148 drm_connector_helper_add(connector
, &udl_connector_helper_funcs
);
150 drm_connector_register(connector
);
151 drm_mode_connector_attach_encoder(connector
, encoder
);