2 * Copyright (C) 2002 Steve Schmidtke
3 * Licensed under the GPL
6 #include "linux/config.h"
7 #include "linux/module.h"
8 #include "linux/version.h"
9 #include "linux/init.h"
10 #include "linux/slab.h"
12 #include "linux/sound.h"
13 #include "linux/soundcard.h"
14 #include "kern_util.h"
16 #include "hostaudio.h"
18 /* Only changed from linux_main at boot time */
19 char *dsp = HOSTAUDIO_DEV_DSP;
20 char *mixer = HOSTAUDIO_DEV_MIXER;
23 static int set_dsp(char *name, int *add)
25 dsp = uml_strdup(name);
29 __uml_setup("dsp=", set_dsp,
31 " This is used to specify the host dsp device to the hostaudio driver.\n"
32 " The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
35 static int set_mixer(char *name, int *add)
37 mixer = uml_strdup(name);
41 __uml_setup("mixer=", set_mixer,
42 "mixer=<mixer device>\n"
43 " This is used to specify the host mixer device to the hostaudio driver.\n"
44 " The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
48 /* /dev/dsp file operations */
50 static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count,
53 struct hostaudio_state *state = file->private_data;
56 printk("hostaudio: read called, count = %d\n", count);
59 return(hostaudio_read_user(state, buffer, count, ppos));
62 static ssize_t hostaudio_write(struct file *file, const char *buffer,
63 size_t count, loff_t *ppos)
65 struct hostaudio_state *state = file->private_data;
68 printk("hostaudio: write called, count = %d\n", count);
70 return(hostaudio_write_user(state, buffer, count, ppos));
73 static unsigned int hostaudio_poll(struct file *file,
74 struct poll_table_struct *wait)
76 unsigned int mask = 0;
79 printk("hostaudio: poll called (unimplemented)\n");
85 static int hostaudio_ioctl(struct inode *inode, struct file *file,
86 unsigned int cmd, unsigned long arg)
88 struct hostaudio_state *state = file->private_data;
91 printk("hostaudio: ioctl called, cmd = %u\n", cmd);
94 return(hostaudio_ioctl_user(state, cmd, arg));
97 static int hostaudio_open(struct inode *inode, struct file *file)
99 struct hostaudio_state *state;
104 printk("hostaudio: open called (host: %s)\n", dsp);
107 state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
108 if(state == NULL) return(-ENOMEM);
110 if(file->f_mode & FMODE_READ) r = 1;
111 if(file->f_mode & FMODE_WRITE) w = 1;
113 ret = hostaudio_open_user(state, r, w, dsp);
119 file->private_data = state;
123 static int hostaudio_release(struct inode *inode, struct file *file)
125 struct hostaudio_state *state = file->private_data;
129 printk("hostaudio: release called\n");
132 ret = hostaudio_release_user(state);
138 /* /dev/mixer file operations */
140 static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file,
141 unsigned int cmd, unsigned long arg)
143 struct hostmixer_state *state = file->private_data;
146 printk("hostmixer: ioctl called\n");
149 return(hostmixer_ioctl_mixdev_user(state, cmd, arg));
152 static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
154 struct hostmixer_state *state;
159 printk("hostmixer: open called (host: %s)\n", mixer);
162 state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL);
163 if(state == NULL) return(-ENOMEM);
165 if(file->f_mode & FMODE_READ) r = 1;
166 if(file->f_mode & FMODE_WRITE) w = 1;
168 ret = hostmixer_open_mixdev_user(state, r, w, mixer);
175 file->private_data = state;
179 static int hostmixer_release(struct inode *inode, struct file *file)
181 struct hostmixer_state *state = file->private_data;
185 printk("hostmixer: release called\n");
188 ret = hostmixer_release_mixdev_user(state);
195 /* kernel module operations */
197 static struct file_operations hostaudio_fops = {
198 .owner = THIS_MODULE,
200 .read = hostaudio_read,
201 .write = hostaudio_write,
202 .poll = hostaudio_poll,
203 .ioctl = hostaudio_ioctl,
205 .open = hostaudio_open,
206 .release = hostaudio_release,
209 static struct file_operations hostmixer_fops = {
210 .owner = THIS_MODULE,
212 .ioctl = hostmixer_ioctl_mixdev,
213 .open = hostmixer_open_mixdev,
214 .release = hostmixer_release,
222 MODULE_AUTHOR("Steve Schmidtke");
223 MODULE_DESCRIPTION("UML Audio Relay");
224 MODULE_LICENSE("GPL");
226 static int __init hostaudio_init_module(void)
228 printk(KERN_INFO "UML Audio Relay\n");
230 module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
231 if(module_data.dev_audio < 0){
232 printk(KERN_ERR "hostaudio: couldn't register DSP device!\n");
236 module_data.dev_mixer = register_sound_mixer(&hostmixer_fops, -1);
237 if(module_data.dev_mixer < 0){
238 printk(KERN_ERR "hostmixer: couldn't register mixer "
240 unregister_sound_dsp(module_data.dev_audio);
247 static void __exit hostaudio_cleanup_module (void)
249 unregister_sound_mixer(module_data.dev_mixer);
250 unregister_sound_dsp(module_data.dev_audio);
253 module_init(hostaudio_init_module);
254 module_exit(hostaudio_cleanup_module);
257 * Overrides for Emacs so that we follow Linus's tabbing style.
258 * Emacs will notice this stuff at the end of the file and automatically
259 * adjust the settings for this buffer only. This must remain at the end
261 * ---------------------------------------------------------------------------
263 * c-file-style: "linux"