]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/dsp/dspgateway/dsp_ctl_core.c
DSP: Move dspgateway to drivers/dsp/dspgateway
[linux-2.6-omap-h63xx.git] / drivers / dsp / dspgateway / dsp_ctl_core.c
1 /*
2  * This file is part of OMAP DSP driver (DSP Gateway version 3.3.1)
3  *
4  * Copyright (C) 2004-2006 Nokia Corporation. All rights reserved.
5  *
6  * Contact: Toshihiro Kobayashi <toshihiro.kobayashi@nokia.com>
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * version 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20  * 02110-1301 USA
21  *
22  */
23
24 #include <linux/major.h>
25 #include <linux/fs.h>
26 #include <linux/device.h>
27 #include <linux/init.h>
28 #include "dsp.h"
29
30 #define CTL_MINOR       0
31 #define MEM_MINOR       1
32 #define TWCH_MINOR      2
33 #define ERR_MINOR       3
34
35 static struct class *dsp_ctl_class;
36 extern struct file_operations dsp_ctl_fops,
37                               dsp_mem_fops,
38                               dsp_twch_fops,
39                               dsp_err_fops;
40
41 static int dsp_ctl_core_open(struct inode *inode, struct file *file)
42 {
43         static DEFINE_MUTEX(open_lock);
44         int ret = 0;
45
46         if (mutex_lock_interruptible(&open_lock))
47                 return -EINTR;
48         if (omap_dsp->initialized == 0) {
49                 ret = dsp_late_init();
50                 if (ret != 0) {
51                         mutex_unlock(&open_lock);
52                         return ret;
53                 }
54                 omap_dsp->initialized = 1;
55         }
56         mutex_unlock(&open_lock);
57
58         switch (iminor(inode)) {
59         case CTL_MINOR:
60                 file->f_op = &dsp_ctl_fops;
61                 break;
62         case MEM_MINOR:
63                 file->f_op = &dsp_mem_fops;
64                 break;
65         case TWCH_MINOR:
66                 file->f_op = &dsp_twch_fops;
67                 break;
68         case ERR_MINOR:
69                 file->f_op = &dsp_err_fops;
70                 break;
71         default:
72                 return -ENXIO;
73         }
74         if (file->f_op && file->f_op->open)
75                 return file->f_op->open(inode, file);
76         return 0;
77 }
78
79 static struct file_operations dsp_ctl_core_fops = {
80         .owner = THIS_MODULE,
81         .open  = dsp_ctl_core_open,
82 };
83
84 static const struct dev_list {
85         unsigned int    minor;
86         char            *devname;
87         umode_t         mode;
88 } dev_list[] = {
89         {CTL_MINOR,  "dspctl",  S_IRUSR | S_IWUSR},
90         {MEM_MINOR,  "dspmem",  S_IRUSR | S_IWUSR | S_IRGRP},
91         {TWCH_MINOR, "dsptwch", S_IRUSR | S_IWUSR | S_IRGRP},
92         {ERR_MINOR,  "dsperr",  S_IRUSR | S_IRGRP},
93 };
94
95 int __init dsp_ctl_core_init(void)
96 {
97         int retval;
98         int i;
99
100         retval = register_chrdev(OMAP_DSP_CTL_MAJOR, "dspctl",
101                                  &dsp_ctl_core_fops);
102         if (retval < 0) {
103                 printk(KERN_ERR
104                        "omapdsp: failed to register dspctl device: %d\n",
105                        retval);
106                 return retval;
107         }
108
109         dsp_ctl_class = class_create(THIS_MODULE, "dspctl");
110         for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
111                 device_create(dsp_ctl_class, NULL,
112                                     MKDEV(OMAP_DSP_CTL_MAJOR,
113                                           dev_list[i].minor),
114                                     dev_list[i].devname);
115         }
116
117         return 0;
118 }
119
120 void dsp_ctl_core_exit(void)
121 {
122         int i;
123
124         for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
125                 device_destroy(dsp_ctl_class,
126                                 MKDEV(OMAP_DSP_CTL_MAJOR,
127                                         dev_list[i].minor));
128         }
129         class_destroy(dsp_ctl_class);
130
131         unregister_chrdev(OMAP_DSP_CTL_MAJOR, "dspctl");
132 }