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
16 #include "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 for (i
= 0; i
< EDID_LENGTH
; i
++) {
33 ret
= usb_control_msg(udl
->ddev
->usbdev
,
34 usb_rcvctrlpipe(udl
->ddev
->usbdev
, 0), (0x02),
35 (0x80 | (0x02 << 5)), i
<< 8, 0xA1, rbuf
, 2,
38 DRM_ERROR("Read EDID byte %d failed err %x\n", i
, ret
);
52 static int udl_get_modes(struct drm_connector
*connector
)
54 struct udl_device
*udl
= connector
->dev
->dev_private
;
58 edid
= (struct edid
*)udl_get_edid(udl
);
60 connector
->display_info
.raw_edid
= (char *)edid
;
62 drm_mode_connector_update_edid_property(connector
, edid
);
63 ret
= drm_add_edid_modes(connector
, edid
);
64 connector
->display_info
.raw_edid
= NULL
;
69 static int udl_mode_valid(struct drm_connector
*connector
,
70 struct drm_display_mode
*mode
)
72 struct udl_device
*udl
= connector
->dev
->dev_private
;
73 if (!udl
->sku_pixel_limit
)
76 if (mode
->vdisplay
* mode
->hdisplay
> udl
->sku_pixel_limit
)
77 return MODE_VIRTUAL_Y
;
82 static enum drm_connector_status
83 udl_detect(struct drm_connector
*connector
, bool force
)
85 if (drm_device_is_unplugged(connector
->dev
))
86 return connector_status_disconnected
;
87 return connector_status_connected
;
90 struct drm_encoder
*udl_best_single_encoder(struct drm_connector
*connector
)
92 int enc_id
= connector
->encoder_ids
[0];
93 struct drm_mode_object
*obj
;
94 struct drm_encoder
*encoder
;
96 obj
= drm_mode_object_find(connector
->dev
, enc_id
, DRM_MODE_OBJECT_ENCODER
);
99 encoder
= obj_to_encoder(obj
);
103 int udl_connector_set_property(struct drm_connector
*connector
, struct drm_property
*property
,
109 static void udl_connector_destroy(struct drm_connector
*connector
)
111 drm_sysfs_connector_remove(connector
);
112 drm_connector_cleanup(connector
);
116 struct drm_connector_helper_funcs udl_connector_helper_funcs
= {
117 .get_modes
= udl_get_modes
,
118 .mode_valid
= udl_mode_valid
,
119 .best_encoder
= udl_best_single_encoder
,
122 struct drm_connector_funcs udl_connector_funcs
= {
123 .dpms
= drm_helper_connector_dpms
,
124 .detect
= udl_detect
,
125 .fill_modes
= drm_helper_probe_single_connector_modes
,
126 .destroy
= udl_connector_destroy
,
127 .set_property
= udl_connector_set_property
,
130 int udl_connector_init(struct drm_device
*dev
, struct drm_encoder
*encoder
)
132 struct drm_connector
*connector
;
134 connector
= kzalloc(sizeof(struct drm_connector
), GFP_KERNEL
);
138 drm_connector_init(dev
, connector
, &udl_connector_funcs
, DRM_MODE_CONNECTOR_DVII
);
139 drm_connector_helper_add(connector
, &udl_connector_helper_funcs
);
141 drm_sysfs_connector_add(connector
);
142 drm_mode_connector_attach_encoder(connector
, encoder
);
144 drm_connector_attach_property(connector
,
145 dev
->mode_config
.dirty_info_property
,