1/* 2 * output.c - Display Output Switch driver 3 * 4 * Copyright (C) 2006 Luming Yu <luming.yu@intel.com> 5 * 6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or (at 11 * your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License along 19 * with this program; if not, write to the Free Software Foundation, Inc., 20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 21 * 22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 23 */ 24#include <linux/module.h> 25#include <linux/video_output.h> 26#include <linux/err.h> 27#include <linux/ctype.h> 28 29 30MODULE_DESCRIPTION("Display Output Switcher Lowlevel Control Abstraction"); 31MODULE_LICENSE("GPL"); 32MODULE_AUTHOR("Luming Yu <luming.yu@intel.com>"); 33 34static ssize_t video_output_show_state(struct class_device *dev,char *buf) 35{ 36 ssize_t ret_size = 0; 37 struct output_device *od = to_output_device(dev); 38 if (od->props) 39 ret_size = sprintf(buf,"%.8x\n",od->props->get_status(od)); 40 return ret_size; 41} 42 43static ssize_t video_output_store_state(struct class_device *dev, 44 const char *buf,size_t count) 45{ 46 char *endp; 47 struct output_device *od = to_output_device(dev); 48 int request_state = simple_strtoul(buf,&endp,0); 49 size_t size = endp - buf; 50 51 if (*endp && isspace(*endp)) 52 size++; 53 if (size != count) 54 return -EINVAL; 55 56 if (od->props) { 57 od->request_state = request_state; 58 od->props->set_state(od); 59 } 60 return count; 61} 62 63static void video_output_class_release(struct class_device *dev) 64{ 65 struct output_device *od = to_output_device(dev); 66 kfree(od); 67} 68 69static struct class_device_attribute video_output_attributes[] = { 70 __ATTR(state, 0644, video_output_show_state, video_output_store_state), 71 __ATTR_NULL, 72}; 73 74static struct class video_output_class = { 75 .name = "video_output", 76 .release = video_output_class_release, 77 .class_dev_attrs = video_output_attributes, 78}; 79 80struct output_device *video_output_register(const char *name, 81 struct device *dev, 82 void *devdata, 83 struct output_properties *op) 84{ 85 struct output_device *new_dev; 86 int ret_code = 0; 87 88 new_dev = kzalloc(sizeof(struct output_device),GFP_KERNEL); 89 if (!new_dev) { 90 ret_code = -ENOMEM; 91 goto error_return; 92 } 93 new_dev->props = op; 94 new_dev->class_dev.class = &video_output_class; 95 new_dev->class_dev.dev = dev; 96 strlcpy(new_dev->class_dev.class_id,name,KOBJ_NAME_LEN); 97 class_set_devdata(&new_dev->class_dev,devdata); 98 ret_code = class_device_register(&new_dev->class_dev); 99 if (ret_code) { 100 kfree(new_dev); 101 goto error_return; 102 } 103 return new_dev; 104 105error_return: 106 return ERR_PTR(ret_code); 107} 108EXPORT_SYMBOL(video_output_register); 109 110void video_output_unregister(struct output_device *dev) 111{ 112 if (!dev) 113 return; 114 class_device_unregister(&dev->class_dev); 115} 116EXPORT_SYMBOL(video_output_unregister); 117 118static void __exit video_output_class_exit(void) 119{ 120 class_unregister(&video_output_class); 121} 122 123static int __init video_output_class_init(void) 124{ 125 return class_register(&video_output_class); 126} 127 128postcore_initcall(video_output_class_init); 129module_exit(video_output_class_exit); 130