Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 293799
b: refs/heads/master
c: 5320918
h: refs/heads/master
i:
  293797: 34540fb
  293795: fb08450
  293791: abaad28
v: v3
  • Loading branch information
Dave Airlie authored and Dave Airlie committed Mar 15, 2012
1 parent 6fee277 commit 9f79d55
Show file tree
Hide file tree
Showing 14 changed files with 2,325 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 2c07a21d6fb0be47fda696a618b726ea258ed1dd
refs/heads/master: 5320918b9a87865223fd6b228e530bf30bc64d9d
1 change: 1 addition & 0 deletions trunk/drivers/gpu/drm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,4 @@ source "drivers/gpu/drm/vmwgfx/Kconfig"

source "drivers/gpu/drm/gma500/Kconfig"

source "drivers/gpu/drm/udl/Kconfig"
1 change: 1 addition & 0 deletions trunk/drivers/gpu/drm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ obj-$(CONFIG_DRM_VIA) +=via/
obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/
obj-$(CONFIG_DRM_EXYNOS) +=exynos/
obj-$(CONFIG_DRM_GMA500) += gma500/
obj-$(CONFIG_DRM_UDL) += udl/
obj-y += i2c/
12 changes: 12 additions & 0 deletions trunk/drivers/gpu/drm/udl/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
config DRM_UDL
tristate "DisplayLink"
depends on DRM && EXPERIMENTAL
select USB
select FB_SYS_FILLRECT
select FB_SYS_COPYAREA
select FB_SYS_IMAGEBLIT
select FB_DEFERRED_IO
select DRM_KMS_HELPER
help
This is a KMS driver for the USB displaylink video adapters.
Say M/Y to add support for these devices via drm/kms interfaces.
6 changes: 6 additions & 0 deletions trunk/drivers/gpu/drm/udl/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

ccflags-y := -Iinclude/drm

udl-y := udl_drv.o udl_modeset.o udl_connector.o udl_encoder.o udl_main.o udl_fb.o udl_transfer.o udl_gem.o

obj-$(CONFIG_DRM_UDL) := udl.o
141 changes: 141 additions & 0 deletions trunk/drivers/gpu/drm/udl/udl_connector.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* Copyright (C) 2012 Red Hat
* based in parts on udlfb.c:
* Copyright (C) 2009 Roberto De Ioris <roberto@unbit.it>
* Copyright (C) 2009 Jaya Kumar <jayakumar.lkml@gmail.com>
* Copyright (C) 2009 Bernie Thompson <bernie@plugable.com>
*
* This file is subject to the terms and conditions of the GNU General Public
* License v2. See the file COPYING in the main directory of this archive for
* more details.
*/

#include "drmP.h"
#include "drm_crtc.h"
#include "drm_edid.h"
#include "drm_crtc_helper.h"
#include "udl_drv.h"

/* dummy connector to just get EDID,
all UDL appear to have a DVI-D */

static u8 *udl_get_edid(struct udl_device *udl)
{
u8 *block;
char rbuf[3];
int ret, i;

block = kmalloc(EDID_LENGTH, GFP_KERNEL);
if (block == NULL)
return NULL;

for (i = 0; i < EDID_LENGTH; i++) {
ret = usb_control_msg(udl->ddev->usbdev,
usb_rcvctrlpipe(udl->ddev->usbdev, 0), (0x02),
(0x80 | (0x02 << 5)), i << 8, 0xA1, rbuf, 2,
HZ);
if (ret < 1) {
DRM_ERROR("Read EDID byte %d failed err %x\n", i, ret);
i--;
goto error;
}
block[i] = rbuf[1];
}

return block;

error:
kfree(block);
return NULL;
}

static int udl_get_modes(struct drm_connector *connector)
{
struct udl_device *udl = connector->dev->dev_private;
struct edid *edid;
int ret;

edid = (struct edid *)udl_get_edid(udl);

connector->display_info.raw_edid = (char *)edid;

drm_mode_connector_update_edid_property(connector, edid);
ret = drm_add_edid_modes(connector, edid);
connector->display_info.raw_edid = NULL;
kfree(edid);
return ret;
}

static int udl_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
return 0;
}

static enum drm_connector_status
udl_detect(struct drm_connector *connector, bool force)
{
if (drm_device_is_unplugged(connector->dev))
return connector_status_disconnected;
return connector_status_connected;
}

struct drm_encoder *udl_best_single_encoder(struct drm_connector *connector)
{
int enc_id = connector->encoder_ids[0];
struct drm_mode_object *obj;
struct drm_encoder *encoder;

obj = drm_mode_object_find(connector->dev, enc_id, DRM_MODE_OBJECT_ENCODER);
if (!obj)
return NULL;
encoder = obj_to_encoder(obj);
return encoder;
}

int udl_connector_set_property(struct drm_connector *connector, struct drm_property *property,
uint64_t val)
{
return 0;
}

static void udl_connector_destroy(struct drm_connector *connector)
{
drm_sysfs_connector_remove(connector);
drm_connector_cleanup(connector);
kfree(connector);
}

struct drm_connector_helper_funcs udl_connector_helper_funcs = {
.get_modes = udl_get_modes,
.mode_valid = udl_mode_valid,
.best_encoder = udl_best_single_encoder,
};

struct drm_connector_funcs udl_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.detect = udl_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = udl_connector_destroy,
.set_property = udl_connector_set_property,
};

int udl_connector_init(struct drm_device *dev, struct drm_encoder *encoder)
{
struct drm_connector *connector;

connector = kzalloc(sizeof(struct drm_connector), GFP_KERNEL);
if (!connector)
return -ENOMEM;

drm_connector_init(dev, connector, &udl_connector_funcs, DRM_MODE_CONNECTOR_DVII);
drm_connector_helper_add(connector, &udl_connector_helper_funcs);

drm_sysfs_connector_add(connector);
drm_mode_connector_attach_encoder(connector, encoder);

drm_connector_attach_property(connector,
dev->mode_config.dirty_info_property,
1);
return 0;
}
99 changes: 99 additions & 0 deletions trunk/drivers/gpu/drm/udl/udl_drv.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
* Copyright (C) 2012 Red Hat
*
* This file is subject to the terms and conditions of the GNU General Public
* License v2. See the file COPYING in the main directory of this archive for
* more details.
*/

#include <linux/module.h>
#include "drm_usb.h"
#include "drm_crtc_helper.h"
#include "udl_drv.h"

static struct drm_driver driver;

static struct usb_device_id id_table[] = {
{.idVendor = 0x17e9, .match_flags = USB_DEVICE_ID_MATCH_VENDOR,},
{},
};
MODULE_DEVICE_TABLE(usb, id_table);

MODULE_LICENSE("GPL");

static int udl_usb_probe(struct usb_interface *interface,
const struct usb_device_id *id)
{
return drm_get_usb_dev(interface, id, &driver);
}

static void udl_usb_disconnect(struct usb_interface *interface)
{
struct drm_device *dev = usb_get_intfdata(interface);

drm_kms_helper_poll_disable(dev);
drm_connector_unplug_all(dev);
udl_fbdev_unplug(dev);
udl_drop_usb(dev);
drm_unplug_dev(dev);
}

static struct vm_operations_struct udl_gem_vm_ops = {
.fault = udl_gem_fault,
.open = drm_gem_vm_open,
.close = drm_gem_vm_close,
};

static const struct file_operations udl_driver_fops = {
.owner = THIS_MODULE,
.open = drm_open,
.mmap = drm_gem_mmap,
.poll = drm_poll,
.read = drm_read,
.unlocked_ioctl = drm_ioctl,
.release = drm_release,
.fasync = drm_fasync,
.llseek = noop_llseek,
};

static struct drm_driver driver = {
.driver_features = DRIVER_MODESET | DRIVER_GEM,
.load = udl_driver_load,
.unload = udl_driver_unload,

/* gem hooks */
.gem_init_object = udl_gem_init_object,
.gem_free_object = udl_gem_free_object,
.gem_vm_ops = &udl_gem_vm_ops,

.dumb_create = udl_dumb_create,
.dumb_map_offset = udl_gem_mmap,
.dumb_destroy = udl_dumb_destroy,
.fops = &udl_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
.date = DRIVER_DATE,
.major = DRIVER_MAJOR,
.minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL,
};

static struct usb_driver udl_driver = {
.name = "udl",
.probe = udl_usb_probe,
.disconnect = udl_usb_disconnect,
.id_table = id_table,
};

static int __init udl_init(void)
{
return drm_usb_init(&driver, &udl_driver);
}

static void __exit udl_exit(void)
{
drm_usb_exit(&driver, &udl_driver);
}

module_init(udl_init);
module_exit(udl_exit);
Loading

0 comments on commit 9f79d55

Please sign in to comment.