diff options
author | Len Brown <len.brown@intel.com> | 2007-02-03 01:39:22 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2007-02-03 01:39:22 -0500 |
commit | 274ec7a8c07036bd02e8f2301456e443ef30b8a8 (patch) | |
tree | 1ed2159c6a9c18e78ac3d769f221fdb0f0237d59 | |
parent | 6b259707d53f0f25f0b24318a0774f1ae7e7e92c (diff) | |
parent | b03637b8863159a4518cb0a9ab90577460fe3417 (diff) | |
download | talos-op-linux-274ec7a8c07036bd02e8f2301456e443ef30b8a8.tar.gz talos-op-linux-274ec7a8c07036bd02e8f2301456e443ef30b8a8.zip |
Pull output-switch into test branch
-rw-r--r-- | Documentation/video-output.txt | 34 | ||||
-rw-r--r-- | drivers/video/output.c | 129 | ||||
-rw-r--r-- | include/linux/video_output.h | 42 |
3 files changed, 205 insertions, 0 deletions
diff --git a/Documentation/video-output.txt b/Documentation/video-output.txt new file mode 100644 index 000000000000..e517011be4f9 --- /dev/null +++ b/Documentation/video-output.txt @@ -0,0 +1,34 @@ + + Video Output Switcher Control + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 2006 luming.yu@intel.com + +The output sysfs class driver provides an abstract video output layer that +can be used to hook platform specific methods to enable/disable video output +device through common sysfs interface. For example, on my IBM ThinkPad T42 +laptop, The ACPI video driver registered its output devices and read/write +method for 'state' with output sysfs class. The user interface under sysfs is: + +linux:/sys/class/video_output # tree . +. +|-- CRT0 +| |-- device -> ../../../devices/pci0000:00/0000:00:01.0 +| |-- state +| |-- subsystem -> ../../../class/video_output +| `-- uevent +|-- DVI0 +| |-- device -> ../../../devices/pci0000:00/0000:00:01.0 +| |-- state +| |-- subsystem -> ../../../class/video_output +| `-- uevent +|-- LCD0 +| |-- device -> ../../../devices/pci0000:00/0000:00:01.0 +| |-- state +| |-- subsystem -> ../../../class/video_output +| `-- uevent +`-- TV0 + |-- device -> ../../../devices/pci0000:00/0000:00:01.0 + |-- state + |-- subsystem -> ../../../class/video_output + `-- uevent + diff --git a/drivers/video/output.c b/drivers/video/output.c new file mode 100644 index 000000000000..1473f2c892d2 --- /dev/null +++ b/drivers/video/output.c @@ -0,0 +1,129 @@ +/* + * output.c - Display Output Switch driver + * + * Copyright (C) 2006 Luming Yu <luming.yu@intel.com> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#include <linux/module.h> +#include <linux/video_output.h> +#include <linux/err.h> +#include <linux/ctype.h> + + +MODULE_DESCRIPTION("Display Output Switcher Lowlevel Control Abstraction"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Luming Yu <luming.yu@intel.com>"); + +static ssize_t video_output_show_state(struct class_device *dev,char *buf) +{ + ssize_t ret_size = 0; + struct output_device *od = to_output_device(dev); + if (od->props) + ret_size = sprintf(buf,"%.8x\n",od->props->get_status(od)); + return ret_size; +} + +static ssize_t video_output_store_state(struct class_device *dev, + const char *buf,size_t count) +{ + char *endp; + struct output_device *od = to_output_device(dev); + int request_state = simple_strtoul(buf,&endp,0); + size_t size = endp - buf; + + if (*endp && isspace(*endp)) + size++; + if (size != count) + return -EINVAL; + + if (od->props) { + od->request_state = request_state; + od->props->set_state(od); + } + return count; +} + +static void video_output_class_release(struct class_device *dev) +{ + struct output_device *od = to_output_device(dev); + kfree(od); +} + +static struct class_device_attribute video_output_attributes[] = { + __ATTR(state, 0644, video_output_show_state, video_output_store_state), + __ATTR_NULL, +}; + +static struct class video_output_class = { + .name = "video_output", + .release = video_output_class_release, + .class_dev_attrs = video_output_attributes, +}; + +struct output_device *video_output_register(const char *name, + struct device *dev, + void *devdata, + struct output_properties *op) +{ + struct output_device *new_dev; + int ret_code = 0; + + new_dev = kzalloc(sizeof(struct output_device),GFP_KERNEL); + if (!new_dev) { + ret_code = -ENOMEM; + goto error_return; + } + new_dev->props = op; + new_dev->class_dev.class = &video_output_class; + new_dev->class_dev.dev = dev; + strlcpy(new_dev->class_dev.class_id,name,KOBJ_NAME_LEN); + class_set_devdata(&new_dev->class_dev,devdata); + ret_code = class_device_register(&new_dev->class_dev); + if (ret_code) { + kfree(new_dev); + goto error_return; + } + return new_dev; + +error_return: + return ERR_PTR(ret_code); +} +EXPORT_SYMBOL(video_output_register); + +void video_output_unregister(struct output_device *dev) +{ + if (!dev) + return; + class_device_unregister(&dev->class_dev); +} +EXPORT_SYMBOL(video_output_unregister); + +static void __exit video_output_class_exit(void) +{ + class_unregister(&video_output_class); +} + +static int __init video_output_class_init(void) +{ + return class_register(&video_output_class); +} + +postcore_initcall(video_output_class_init); +module_exit(video_output_class_exit); diff --git a/include/linux/video_output.h b/include/linux/video_output.h new file mode 100644 index 000000000000..e63e0c03ee0d --- /dev/null +++ b/include/linux/video_output.h @@ -0,0 +1,42 @@ +/* + * + * Copyright (C) 2006 Luming Yu <luming.yu@intel.com> + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ +#ifndef _LINUX_VIDEO_OUTPUT_H +#define _LINUX_VIDEO_OUTPUT_H +#include <linux/device.h> +struct output_device; +struct output_properties { + int (*set_state)(struct output_device *); + int (*get_status)(struct output_device *); +}; +struct output_device { + int request_state; + struct output_properties *props; + struct class_device class_dev; +}; +#define to_output_device(obj) container_of(obj, struct output_device, class_dev) +struct output_device *video_output_register(const char *name, + struct device *dev, + void *devdata, + struct output_properties *op); +void video_output_unregister(struct output_device *dev); +#endif |