1 #include <linux/types.h>
\r
2 #include <linux/errno.h>
\r
3 #include <linux/string.h>
\r
4 #include <linux/module.h>
\r
5 #include <linux/kernel.h>
\r
6 #include <linux/init.h>
\r
7 #include <linux/slab.h>
\r
8 #include <linux/device.h>
\r
9 #include <linux/fs.h>
\r
10 #include <linux/cdev.h>
\r
11 #include <linux/mutex.h>
\r
13 #include "cmmb_class.h"
\r
17 #define DBGERR(fmt...) printk(KERN_DEBUG fmt)
\r
19 #define DBGERR(fmt...)
\r
23 #define DBG(fmt...) printk(KERN_DEBUG fmt)
\r
28 #define MAX_CMMB_ADAPTER 2
\r
29 #define MAX_CMMB_MINORS (MAX_CMMB_ADAPTER*4)
\r
32 struct cmmb_adapter CMMB_adapter;
\r
33 struct class * cmmb_class;
\r
35 static struct cdev cmmb_device_cdev;
\r
37 static int cmmb_device_open(struct inode *inode, struct file *file);
\r
39 static struct file_operations cmmb_device_fops =
\r
41 .owner = THIS_MODULE,
\r
42 .open = cmmb_device_open
\r
45 static struct cmmb_device* cmmb_find_device (int minor)
\r
48 struct cmmb_device *dev;
\r
49 DBG("[CMMB HW]:[class]:enter cmmb_find_device\n");
\r
51 list_for_each_entry(dev, &CMMB_adapter.device_list, list_head)
\r
52 if (dev->type == minor)
\r
58 static int cmmb_device_open(struct inode *inode, struct file *file)
\r
60 struct cmmb_device *cmmbdev;
\r
62 DBG("[CMMB HW]:[class]:enter cmmb_device_open\n");
\r
64 cmmbdev = cmmb_find_device (iminor(inode));
\r
66 DBG("[CMMB HW]:[class]:cmmbdev.type%d\n",cmmbdev->type);
\r
68 if (cmmbdev && cmmbdev->fops) {
\r
70 const struct file_operations *old_fops;
\r
72 file->private_data = cmmbdev;
\r
73 old_fops = file->f_op;
\r
74 file->f_op = fops_get(cmmbdev->fops);
\r
75 if(file->f_op->open)
\r
76 err = file->f_op->open(inode,file);
\r
78 fops_put(file->f_op);
\r
79 file->f_op = fops_get(old_fops);
\r
88 static int cmmb_register_adapter(const char *name, struct device *device)
\r
90 DBG("[CMMB HW]:[class]:cmmb_register_adapter\n");
\r
92 memset (&CMMB_adapter, 0, sizeof(struct cmmb_adapter));
\r
94 INIT_LIST_HEAD (&CMMB_adapter.device_list);
\r
96 CMMB_adapter.num = 0;
\r
97 CMMB_adapter.name = name;
\r
98 CMMB_adapter.device = device;
\r
104 static int cmmb_unregister_adapter(struct cmmb_adapter *adap)
\r
106 DBG("[CMMB HW]:[class]:cmmb_unregister_adapter\n");
\r
108 memset (&CMMB_adapter, 0, sizeof(struct cmmb_adapter));
\r
114 int cmmb_register_device(struct cmmb_adapter *adap, struct cmmb_device **pcmmbdev,
\r
115 struct file_operations *fops, void *priv, int type,char* name)
\r
117 struct cmmb_device *cmmbdev;
\r
118 struct file_operations *cmmbdevfops;
\r
119 struct device *clsdev;
\r
121 DBG("[CMMB HW]:[class]:cmmb_register_device\n");
\r
123 *pcmmbdev = cmmbdev = kmalloc(sizeof(struct cmmb_device), GFP_KERNEL);
\r
126 DBGERR("[CMMB HW]:[class]:[err]: cmmb register device cmmbdev malloc fail!!!\n");
\r
130 cmmbdevfops = kzalloc(sizeof(struct file_operations), GFP_KERNEL);
\r
133 DBGERR("[CMMB HW]:[class]:[err]: cmmb register device cmmbdevfops malloc fail!!!\n");
\r
138 cmmbdev->type = type;
\r
139 cmmbdev->adapter = adap;
\r
140 cmmbdev->priv = priv;
\r
141 cmmbdev->fops = cmmbdevfops;
\r
143 init_waitqueue_head (&cmmbdev->wait_queue);
\r
145 memcpy(cmmbdev->fops, fops, sizeof(struct file_operations));
\r
146 cmmbdev->fops->owner = THIS_MODULE;
\r
148 list_add_tail (&cmmbdev->list_head, &adap->device_list);
\r
150 clsdev = device_create(cmmb_class, adap->device,MKDEV(CMMB_MAJOR, type),NULL,name);
\r
151 if (IS_ERR(clsdev)) {
\r
152 DBGERR("[CMMB HW]:[class]:[err]: creat dev fail!!!\n");
\r
153 return PTR_ERR(clsdev);
\r
158 EXPORT_SYMBOL(cmmb_register_device);
\r
161 void cmmb_unregister_device(struct cmmb_device *cmmbdev)
\r
166 DBG("[CMMB HW]:[class]:cmmb_unregister_device\n");
\r
168 device_destroy(cmmb_class, MKDEV(CMMB_MAJOR, cmmbdev->type));
\r
170 list_del (&cmmbdev->list_head);
\r
171 kfree (cmmbdev->fops);
\r
174 EXPORT_SYMBOL(cmmb_unregister_device);
\r
177 ssize_t cmmb_class_show_name(struct class * class, char * buf, size_t count, loff_t off)
\r
179 #if defined(CONFIG_IFxxx_CMMB_Chip_Support)
\r
180 memcpy(buf,"inno",5);
\r
183 memcpy(buf,"siano",6);
\r
189 static CLASS_ATTR(name, 0660, cmmb_class_show_name, NULL);
\r
191 static int __init init_cmmbclass(void)
\r
194 struct cmmb_adapter* cmmbadapter;
\r
195 struct cmmb_device * tunerdev;
\r
196 dev_t dev = MKDEV(CMMB_MAJOR, 0);
\r
198 DBG("[CMMB HW]:[class]: init_cmmbclass\n");
\r
200 if ((retval = register_chrdev_region(dev, CMMB_MAJOR, "CMMB")) != 0){
\r
201 DBGERR("[CMMB HW]:[class]:[err]: register chrdev fail!!!\n");
\r
205 cdev_init(&cmmb_device_cdev, &cmmb_device_fops);
\r
206 if ((retval = cdev_add(&cmmb_device_cdev, dev, MAX_CMMB_MINORS)) != 0){
\r
207 DBGERR("[CMMB HW]:[class]:[err]: cedv add fail!!!\n");
\r
211 cmmb_class = class_create(THIS_MODULE, "cmmb");
\r
212 if (IS_ERR(cmmb_class)) {
\r
213 DBGERR("[CMMB HW]:[class]:[err]: class creat fail!!!\n");
\r
214 retval = PTR_ERR(cmmb_class);
\r
217 retval = class_create_file(cmmb_class, &class_attr_name);
\r
220 DBGERR("cmmb_class create attribute failed\n");
\r
222 cmmb_register_adapter("cmmb_adapter", NULL);
\r
227 cdev_del(&cmmb_device_cdev);
\r
228 unregister_chrdev_region(dev, MAX_CMMB_MINORS);
\r
233 static void __exit exit_cmmbclass(void)
\r
235 DBG("[CMMB HW]:[class]: exit_cmmbclass\n");
\r
237 cdev_del(&cmmb_device_cdev);
\r
238 cmmb_unregister_adapter(&CMMB_adapter);
\r
239 unregister_chrdev_region(MKDEV(CMMB_MAJOR, 0), MAX_CMMB_MINORS);
\r
240 class_remove_file(cmmb_class, &class_attr_name);
\r
241 class_destroy(cmmb_class);
\r
245 subsys_initcall(init_cmmbclass);
\r
246 module_exit(exit_cmmbclass);
\r
248 MODULE_DESCRIPTION("CMMB CORE");
\r
249 MODULE_AUTHOR("HT,HZB,HH,LW");
\r
250 MODULE_LICENSE("GPL");
\r