Skip to contentSkip to conversation

: video output sysfs class and acpi video driver support

RFC PATCH In review Yu Luming 2 participants 2 messages Aug 30, 2006

Subsystems (2)
lore
Share & tools
lore

Yu Luming

author
#0 lore raw

RFC PATCH 1/1 : video output sysfs class and acpi video driver support

Hi,

This is a proposal for a unified sysfs interface to control video output device switch. The patch includes two parts:
1. output sysfs class. 2. acpi video driver support. Any comments are appreciated.

Thanks,
Luming

drivers/acpi/Kconfig +1 -1
diff -BruN 2.6/drivers/acpi/Kconfig edited/drivers/acpi/Kconfig
@@ -106,7 +106,7 @@
 
 config ACPI_VIDEO
 	tristate "Video"
-	depends on X86 && BACKLIGHT_DEVICE
+	depends on X86 && ( BACKLIGHT_CLASS_DEVICE || VIDEO_OUTPUT_CONTROL)
 	help
 	  This driver implement the ACPI Extensions For Display Adapters
 	  for integrated graphics devices on motherboard, as specified in
drivers/acpi/video.c +33 -0
diff -BruN 2.6/drivers/acpi/video.c edited/drivers/acpi/video.c
@@ -31,6 +31,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/backlight.h>
+#include <linux/output.h>
 
 #include <asm/uaccess.h>
 
@@ -163,6 +164,7 @@
 	struct acpi_video_bus *video;
 	struct acpi_device *dev;
 	struct acpi_video_device_brightness *brightness;
+	struct output_device *output_dev;
 };
 
 /* bus */
@@ -266,6 +268,10 @@
 /*backlight device sysfs support*/
 static int acpi_video_get_brightness(struct backlight_device *bd);
 static int acpi_video_set_brightness(struct backlight_device *bd);
+static int acpi_video_output_get(struct output_device *);
+static int acpi_video_output_set(struct output_device *);
+static int acpi_video_device_get_state(struct acpi_video_device *, unsigned long *);
+static int acpi_video_device_set_state(struct acpi_video_device *, int);
 
 static struct backlight_device *acpi_video_backlight;
 static struct acpi_video_device *backlight_acpi_device;
@@ -275,6 +281,10 @@
 	.get_brightness = acpi_video_get_brightness,
 	.update_status  = acpi_video_set_brightness,
 };
+static struct output_properties acpi_output_properties = {
+	.set_state = acpi_video_output_set,
+	.get_status = acpi_video_output_get,
+};
 static int acpi_video_get_brightness(struct backlight_device *bd)
 {
 	unsigned long cur_level;
@@ -289,6 +299,20 @@
 	return 0;
 }
 
+static int acpi_video_output_get(struct output_device *od)
+{
+	unsigned long state;
+	struct acpi_video_device *vd = (struct acpi_video_device *)class_get_devdata(&od->class_dev);
+	acpi_video_device_get_state(vd, &state);
+	return (int)state;
+}
+
+static int acpi_video_output_set(struct output_device *od)
+{
+	unsigned long state = od->request_state;
+	struct acpi_video_device *vd = (struct acpi_video_device *)class_get_devdata(&od->class_dev);
+	return acpi_video_device_set_state(vd, state);
+}
 
 /* --------------------------------------------------------------------------
                                Video Management
@@ -614,6 +638,13 @@
 		backlight_acpi_device = device;
 	}
 
+	if (device->cap._DCS && device->cap._DSS){
+		char name[16];
+		strcat(name, acpi_device_bid(device->dev->parent));
+		strcat(name, "_");
+		strcpy(name, acpi_device_bid(device->dev));
+		device->output_dev = video_output_register(name, device, &acpi_output_properties);
+	}
 	return;
 }
 
@@ -1617,6 +1648,8 @@
 	if (device == backlight_acpi_device)
 		backlight_device_unregister(acpi_video_backlight);
 
+	video_output_unregister(device->output_dev);
+
 	return 0;
 }
 
drivers/video/Kconfig +8 -0
diff -BruN 2.6/drivers/video/Kconfig edited/drivers/video/Kconfig
@@ -1616,5 +1616,13 @@
 	source "drivers/video/backlight/Kconfig"
 endif
 
+
+config VIDEO_OUTPUT_CONTROL
+	tristate "video output device switch control"
+	depends on SYSFS
+	---help---
+	  sysfs support for video output device switching.
+
+
 endmenu
 
drivers/video/Makefile +2 -1
diff -BruN 2.6/drivers/video/Makefile edited/drivers/video/Makefile
@@ -12,7 +12,7 @@
 
 obj-$(CONFIG_VT)		  += console/
 obj-$(CONFIG_LOGO)		  += logo/
-obj-$(CONFIG_SYSFS)		  += backlight/
+obj-$(CONFIG_SYSFS)		  += backlight/ 
 
 obj-$(CONFIG_FB_CFB_FILLRECT)  += cfbfillrect.o
 obj-$(CONFIG_FB_CFB_COPYAREA)  += cfbcopyarea.o
@@ -107,3 +107,4 @@
 
 # the test framebuffer is last
 obj-$(CONFIG_FB_VIRTUAL)          += vfb.o
+obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o
drivers/video/output.c +109 -0

109 lines not on this page · raw message

include/linux/output.h +23 -0
diff -BruN 2.6/include/linux/output.h edited/include/linux/output.h
@@ -0,0 +1,23 @@
+#ifndef _LINUX_OUTPUT_H
+#define _LINUX_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 *, void *, struct output_properties *);
+void video_output_unregister(struct output_device *);
+#endif
Signature · 2 lines
Thanks,
Luming
#1 lore raw
Quoted 6 lines · On Wed, 30 Aug 2006 15:42:15 +0800 Yu Luming wrote:

Hi,

This is a proposal for a unified sysfs interface to control video output device switch. The patch includes two parts:
1. output sysfs class. 2. acpi video driver support. Any comments are appreciated.

Could you be a bit more verbose in the description of the patch? (i.e., what it does) Both here and in the Kconfig help text....

drivers/acpi/Kconfig line 109

Quoted 12 lines

Thanks,
Luming

diff -BruN 2.6/drivers/acpi/Kconfig edited/drivers/acpi/Kconfig

drivers/acpi/Kconfig +1 -1
@@ -106,7 +106,7 @@
 
 config ACPI_VIDEO
 	tristate "Video"
-	depends on X86 && BACKLIGHT_DEVICE
+	depends on X86 && ( BACKLIGHT_CLASS_DEVICE || VIDEO_OUTPUT_CONTROL)

s/( /(/

drivers/acpi/Kconfig line 111

Quoted 2 lines
drivers/acpi/Kconfig +0 -0
 	help
 	  This driver implement the ACPI Extensions For Display Adapters

s/implement/implements/
(That entire help section needs help...)

Quoted 21 lines
drivers/acpi/Kconfig +0 -0
 	  for integrated graphics devices on motherboard, as specified in

diff -BruN 2.6/drivers/acpi/video.c edited/drivers/acpi/video.c

drivers/acpi/video.c +2 -0
@@ -31,6 +31,7 @@
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/backlight.h>
+#include <linux/output.h>
 
 #include <asm/uaccess.h>
 
@@ -163,6 +164,7 @@
 	struct acpi_video_bus *video;
 	struct acpi_device *dev;
 	struct acpi_video_device_brightness *brightness;
+	struct output_device *output_dev;
 };
 
 /* bus */

drivers/acpi/video.c line 274

Quoted 7 lines
drivers/acpi/video.c +4 -0
@@ -266,6 +268,10 @@
 /*backlight device sysfs support*/
 static int acpi_video_get_brightness(struct backlight_device *bd);
 static int acpi_video_set_brightness(struct backlight_device *bd);
+static int acpi_video_output_get(struct output_device *);
+static int acpi_video_output_set(struct output_device *);
+static int acpi_video_device_get_state(struct acpi_video_device *, unsigned long *);
+static int acpi_video_device_set_state(struct acpi_video_device *, int);

Don't put just parameter types, put a meaningful/useful identifier name with them also. (See the functions just above the new lines here.)

Quoted 36 lines
drivers/acpi/video.c +18 -0
 static struct backlight_device *acpi_video_backlight;
 static struct acpi_video_device *backlight_acpi_device;
@@ -275,6 +281,10 @@
 	.get_brightness = acpi_video_get_brightness,
 	.update_status  = acpi_video_set_brightness,
 };
+static struct output_properties acpi_output_properties = {
+	.set_state = acpi_video_output_set,
+	.get_status = acpi_video_output_get,
+};
 static int acpi_video_get_brightness(struct backlight_device *bd)
 {
 	unsigned long cur_level;
@@ -289,6 +299,20 @@
 	return 0;
 }
 
+static int acpi_video_output_get(struct output_device *od)
+{
+	unsigned long state;
+	struct acpi_video_device *vd = (struct acpi_video_device *)class_get_devdata(&od->class_dev);
+	acpi_video_device_get_state(vd, &state);
+	return (int)state;
+}
+
+static int acpi_video_output_set(struct output_device *od)
+{
+	unsigned long state = od->request_state;
+	struct acpi_video_device *vd = (struct acpi_video_device *)class_get_devdata(&od->class_dev);
+	return acpi_video_device_set_state(vd, state);
+}
 
 /* --------------------------------------------------------------------------
                                Video Management

drivers/acpi/video.c line 641

Quoted 4 lines
drivers/acpi/video.c +1 -0
@@ -614,6 +638,13 @@
 		backlight_acpi_device = device;
 	}
 
+	if (device->cap._DCS && device->cap._DSS){

) {

drivers/acpi/video.c line 645

Quoted 4 lines
drivers/acpi/video.c +4 -0
+		char name[16];
+		strcat(name, acpi_device_bid(device->dev->parent));
+		strcat(name, "_");
+		strcpy(name, acpi_device_bid(device->dev));

I would feel safer with some length-safe str* functions being used there.

Quoted 18 lines
drivers/acpi/video.c +4 -0
+		device->output_dev = video_output_register(name, device, &acpi_output_properties);
+	}
 	return;
 }
 
@@ -1617,6 +1648,8 @@
 	if (device == backlight_acpi_device)
 		backlight_device_unregister(acpi_video_backlight);
 
+	video_output_unregister(device->output_dev);
+
 	return 0;
 }
 

diff -BruN 2.6/drivers/video/Kconfig edited/drivers/video/Kconfig

drivers/video/Kconfig line 1624

Quoted 9 lines
drivers/video/Kconfig +6 -0
@@ -1616,5 +1616,13 @@
 	source "drivers/video/backlight/Kconfig"
 endif
 
+
+config VIDEO_OUTPUT_CONTROL
+	tristate "video output device switch control"
+	depends on SYSFS
+	---help---
+	  sysfs support for video output device switching.

This is only useful if someone already knows what it does. It doesn't help someone who is uninformed about it.

drivers/video/Makefile line 15

Quoted 13 lines
drivers/video/Kconfig +2 -0
+
+
 endmenu
 

diff -BruN 2.6/drivers/video/Makefile edited/drivers/video/Makefile

drivers/video/Makefile +1 -1
@@ -12,7 +12,7 @@
 
 obj-$(CONFIG_VT)		  += console/
 obj-$(CONFIG_LOGO)		  += logo/
-obj-$(CONFIG_SYSFS)		  += backlight/
+obj-$(CONFIG_SYSFS)		  += backlight/ 

Don't add whitespace at end of line (as above).

Quoted 17 lines
drivers/video/Makefile +1 -0
 obj-$(CONFIG_FB_CFB_FILLRECT)  += cfbfillrect.o
 obj-$(CONFIG_FB_CFB_COPYAREA)  += cfbcopyarea.o
@@ -107,3 +107,4 @@
 
 # the test framebuffer is last
 obj-$(CONFIG_FB_VIRTUAL)          += vfb.o
+obj-$(CONFIG_VIDEO_OUTPUT_CONTROL) += output.o

diff -BruN 2.6/drivers/video/output.c edited/drivers/video/output.c

drivers/video/output.c +5 -0
@@ -0,0 +1,109 @@
+/*
+ * Video output switch support
+ */
+
+#include <linux/module.h>

drivers/video/output.c line 15

Quoted 10 lines
drivers/video/output.c +10 -0
+#include <linux/output.h>
+#include <linux/err.h>
+#include <linux/ctype.h>
+
+
+MODULE_DESCRIPTION("Backlight Lowlevel Control Abstraction");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Luming Yu <[email protected]>");
+
+static ssize_t video_output_show_state (struct class_device *dev, char *buf)

func_name(...) // no space between func_name and '('

drivers/video/output.c line 20

Quoted 5 lines
drivers/video/output.c +5 -0
+{
+	ssize_t ret_size = 0;
+	struct output_device *od = to_output_device(dev);
+	
+	if(od->props)

if (

drivers/video/output.c line 26

Quoted 6 lines
drivers/video/output.c +6 -0
+		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)

no space after function name

drivers/video/output.c line 37

Quoted 11 lines
drivers/video/output.c +11 -0
+{
+	char *endp;
+	struct output_device *od = to_output_device(dev);
+	int request_state = simple_strtoul(buf, &endp, 0);
+	size_t size = endp -buf;
+	
+	printk("in video_output_store_state %.8x\n", request_state);
+        if (*endp && isspace(*endp))
+                size++;
+        if (size != count)
+                return -EINVAL;

There seems to be some off whitespace/tabs there.

drivers/video/output.c line 39

Quoted 2 lines
drivers/video/output.c +2 -0
+
+	if(od->props){

if (

Quoted 20 lines
drivers/video/output.c +20 -0
+		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,

drivers/video/output.c line 69

Quoted 10 lines
drivers/video/output.c +10 -0
+	.class_dev_attrs = video_output_attributes,
+};
+
+
+struct output_device *video_output_register(const char *name, void *devdata, struct output_properties *op)
+{
+	struct output_device *new_dev;
+	int	ret_code = 0;
+
+	new_dev = (struct output_device *) kzalloc( sizeof(struct output_device), GFP_KERNEL);

kzalloc(sizeof(...

drivers/video/output.c line 79

Quoted 10 lines
drivers/video/output.c +10 -0
+	if (!new_dev) {
+		ret_code = -ENOMEM;
+		goto error_return;
+	}
+	new_dev->props = op;
+	new_dev->class_dev.class = &video_output_class;
+	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){

) {

drivers/video/output.c line 80

Quoted 1 line
drivers/video/output.c +1 -0
+		kfree (new_dev);
		kfree(new_dev);
Quoted 46 lines
drivers/video/output.c +29 -0
+		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 -BruN 2.6/include/linux/output.h edited/include/linux/output.h

include/linux/output.h +13 -0
@@ -0,0 +1,23 @@
+#ifndef _LINUX_OUTPUT_H
+#define _LINUX_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 {

include/linux/output.h line 23

Quoted 10 lines
include/linux/output.h +10 -0
+	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 *, void *, struct output_properties *);
+void video_output_unregister(struct output_device *);
+#endif

---
~Randy