/* * * dvb_sysfs.c -- interface to the sysfs filesystem * Copyright (C) 2004 Christian Gmeiner * Copyright (C) 2004 Eric Donohue * * 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 #include "dvb_sysfs.h" #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,46) #ifndef DVB_SYSFS_DIR #define DVB_SYSFS_DIR "dvb" //-> /sys/class/dvb/... #endif static struct class dvb_class = { .name = DVB_SYSFS_DIR }; static ssize_t show_name(struct class_device *cd, char *buf) { struct dvb_adapter *adap = container_of(cd, struct dvb_adapter, class_dev); sprintf(buf, "%s\n", adap->name); return strlen(buf) + 1; } static CLASS_DEVICE_ATTR(name, S_IRUGO, show_name, NULL); static ssize_t show_frontend(struct class_device *cd, char *buf) { struct dvb_adapter *adap = container_of(cd, struct dvb_adapter, class_dev); sprintf(buf, "%s\n", adap->frontend); return strlen(buf) + 1; } static CLASS_DEVICE_ATTR(frontend, S_IRUGO, show_frontend, NULL); static ssize_t show_devnum(struct class_device *cd, char *buf) { struct dvb_device *dvbdev = container_of(cd, struct dvb_device, class_dev); dev_t dev = MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num, dvbdev->type, dvbdev->id)); return print_dev_t(buf, dev); } static CLASS_DEVICE_ATTR(dev, S_IRUGO, show_devnum, NULL); static ssize_t show_adap(struct class_device *cd, char *buf) { struct dvb_device *dvbdev = container_of(cd, struct dvb_device, class_dev); sprintf(buf, "adapter%d\n", dvbdev->adapter->num); return strlen(buf) + 1; } static CLASS_DEVICE_ATTR(adap, S_IRUGO, show_adap, NULL); static struct class_device_attribute *dvb_adapter_attrs[] = { &class_device_attr_name, &class_device_attr_frontend, NULL }; static struct class_device_attribute *dvb_device_attrs[] = { &class_device_attr_dev, &class_device_attr_adap, NULL }; static void dvb_sysfs_register_adapter(struct dvb_adapter *adap) { char name[64] = ""; int i; adap->class_dev.class = &dvb_class; adap->class_dev.dev = NULL; adap->class_dev.class_data = adap; sprintf(name,"adapter%d", adap->num); strcpy(adap->class_dev.class_id, name); if(class_device_register(&adap->class_dev)) printk(KERN_ERR "Unable to register dvb class device\n"); for(i = 0; dvb_adapter_attrs[i]; i++) class_device_create_file(&(adap->class_dev), dvb_adapter_attrs[i]); } static void dvb_sysfs_unregister_adapter(struct dvb_adapter *adap) { class_device_unregister(&(adap->class_dev)); } static void dvb_sysfs_register_device(struct dvb_device *dvbdev) { int i; char name[64] = ""; struct class_device *class_dev = &(dvbdev->class_dev); sprintf(name,"%s%d", dnames[dvbdev->type], dvbdev->adapter->num); class_dev->class = &dvb_class; class_dev->class_data = dvbdev; strcpy(class_dev->class_id, name); kobject_init(&class_dev->kobj); strcpy(class_dev->kobj.name, name); class_dev->kobj.parent = &dvbdev->adapter->class_dev.kobj; class_dev->kobj.kset = dvbdev->adapter->class_dev.kobj.kset; class_dev->kobj.ktype = dvbdev->adapter->class_dev.kobj.ktype; class_dev->kobj.dentry = dvbdev->adapter->class_dev.kobj.dentry; kobject_register(&class_dev->kobj); for (i = 0; dvb_device_attrs[i]; i++) class_device_create_file(class_dev, dvb_device_attrs[i]); } static void dvb_sysfs_unregister_device(struct dvb_device *dvbdev) { kobject_unregister(&dvbdev->class_dev.kobj); } static int dvb_sysfs_init(void) { printk("DVB: Using sysfs funtions\n"); if (class_register(&dvb_class) != 0) { printk("DVB: adapter class failed to register properly"); return -1; } return 0; } static void dvb_sysfs_exit(void) { class_unregister(&dvb_class); } struct dvb_registrar_s dvb_sysfs_registrar = { .register_adapter = &dvb_sysfs_register_adapter, .unregister_adapter = &dvb_sysfs_unregister_adapter, .register_device = &dvb_sysfs_register_device, .unregister_device = &dvb_sysfs_unregister_device, .dvbdev_init = &dvb_sysfs_init, .dvbdev_exit = &dvb_sysfs_exit, }; #else /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,46) */ struct dvb_registrar_s dvb_sysfs_registrar = { .register_adapter = NULL, .unregister_adapter = NULL, .register_device = NULL, .unregister_device = NULL, .dvbdev_init = NULL, .dvbdev_exit = NULL, }; #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,46) */