From: M. R. B. <mr...@us...> - 2002-10-29 16:35:31
|
Update of /cvsroot/linuxdc/linux-sh-dc/sound/oss In directory usw-pr-cvs1:/tmp/cvs-serv20086 Added Files: Tag: 1.1 microphone.c Log Message: Moved. --- NEW FILE: microphone.c --- /* * Microphone driver * for SEGA Dreamcast * Copyright (c) Adrian McMenamin, 2002 * * This code is licenced under the GPL v2 * No warranties of any kind offered * * * Based on existing Maple device coding * Copyright MR Brown, YAEGASHI Takeshi and others * * */ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/input.h> #include <linux/module.h> #include <linux/init.h> #include <linux/timer.h> #include <linux/maple.h> #include "sound_config.h" #define _DEBUG_ #ifdef _DEBUG_ #define DEBGM(fmt, args...) (printk(KERN_ERR fmt, ##args)) #else #define DEBGM(fmt, args...) ((void) 0) #endif /* Sound minor device number */ int mic_minor; struct dc_microphone { struct input_dev dev; struct maple_driver_data *data; unsigned char snd[1024]; int open; }; static struct dc_microphone *mic = NULL; static int length = 0; /* * Although this is a Maple * device, it has to connect * through to OSS driver to * be of any use to anybody * who uses standard sound * APIs */ static int mic_audio_open(struct inode *inode, struct file *file) { return 0; } static ssize_t mic_audio_read(struct file *filp, char *buf, size_t count, loff_t * f_pos) { /* Copy from maple generated buffer to OSS buffer and return */ int oldlength = length * 2; copy_to_user(buf, mic->snd, oldlength); length = 0; DEBGM("Length is...%i, count is...%i\n", oldlength, count); return oldlength + 2; } static int mic_audio_release(struct inode *inode, struct file *file) { return 0; } static int mic_audio_ioctl(struct inode *inode, struct file *filip, unsigned int cmd, unsigned long arg) { return -ENOTTY; } static int dc_microphone_open(struct input_dev *dev) { DEBGM("Microphone: open called by input susbsystem\n"); MOD_INC_USE_COUNT; return 0; } static void dc_microphone_release(struct input_dev *dev) { MOD_DEC_USE_COUNT; } static int dc_microphone_connect(struct maple_driver_data *d) { //unsigned long data = d->function_data; if (!(mic = kmalloc(sizeof(struct dc_microphone), GFP_KERNEL))) { DEBGM("Memory allocation failure\n"); return -ENOMEM; } memset(mic, 0, sizeof(struct dc_microphone)); mic->data = d; d->private_data = mic; mic->dev.private = mic; mic->dev.open = dc_microphone_open; mic->dev.close = dc_microphone_release; mic->dev.name = d->dev->product_name; mic->dev.event = NULL; mic->dev.idbus = BUS_MAPLE; /* input_register_device(&mic->dev); */ //printk("Connected...%s\n", mic->dev.name); return 0; } static void dc_microphone_disconnect(struct maple_driver_data *d) { struct dc_microphone *mic = d->private_data; /* input_unregister_device(&mic->dev); */ kfree(mic); } static void dc_microphone_callback(struct maple_driver_data *data) { //int x = 12; struct mapleq *mq = &data->mq; int res = mq->recvbuf[0]; printk ("Maple reply (%d, %d) cmd=%d => %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\n", mq->port, mq->unit, mq->command, res, mq->recvbuf[1], mq->recvbuf[2], mq->recvbuf[3], mq->recvbuf[4], mq->recvbuf[5], mq->recvbuf[6], mq->recvbuf[7], mq->recvbuf[8], mq->recvbuf[9], mq->recvbuf[10], mq->recvbuf[11]); //printk("Next round %d, %d, %d, %d, %d, %d, %d, %d\n", mq->recvbuf[12], mq->recvbuf[13], mq->recvbuf[14], mq->recvbuf[15], mq->recvbuf[16], mq->recvbuf[17], mq->recvbuf[18], mq->recvbuf[19]); //unsigned long tmp=*(unsigned long *)0xA05F80C4; //printk("Gunport data is %d\n", tmp); /* if (res == 8) */ /* { */ /* for (x = 8; x < 32; x++) */ /* { */ /* printk("%d,", mq->recvbuf[x]); */ /* } */ /* printk("\n"); */ /* } */ } static int firstup = 0; void dc_microphone_vblank_callback(struct maple_driver_data *data) { if (data->mq.done) { data->mq.command = 15; data->mq.length = 2; ((unsigned long *) (data->mq.recvbuf))[0] = cpu_to_be32(MAPLE_FUNC_MICROPHONE); if (firstup == 0) ((unsigned long *) (data->mq.recvbuf))[1] = 0x00000501; else if (firstup == 1) { data->mq.command = 15; data->mq.length = 2; ((unsigned long *) (data->mq.recvbuf))[1] = 0x00000102; } else{ data->mq.command = 15; data->mq.length = 3; ((unsigned long *) (data->mq.recvbuf))[1] = 0x01020104; ((unsigned long *) (data->mq.recvbuf))[2] = 0x0001; ; /*65295 */ } /*printk("Send buffer is %i, %i\n", ((unsigned long *)(data->mq.recvbuf))[0], ((unsigned long *)(data->mq.recvbuf))[1]); */ /* 0x00 generates a -3 response 0x01 generates an 0x08 response - volume? 0x0101 returns 0x00 0x00 0x00 0x10 0x00 0x01 0x00 0x00 0x0201 returns 0x00 0x00 0x00 0x10 0x00 0x02 0x00 0x00 0x0301 returns 0x00 0x00 0x00 0x10 0x00 0x03 0x00 0x00 and so until 0x2001 returns -3 0x02 generates an 0x07 response 0x0002 returns 0x00 0x00 0x00 0x10 0x00 0x00 0x00 0x00 from 0x01 0x0102 returns 0x00 0x00 0x00 0x10 0x02 0x00 0x00 0x00 from 0x01 0x0202 returns -3 0x03 generates an 0x07 response 0x0103 generates an 0x07 response and default from 0x01 0x0203 generates an 0x07 response and default from 0x01 0x0303 as above 0x0403 as above 0x0503 as above 0x04 generates an 0x07 repsonse - bit size? 0x0104 generates 0x00 0x00 0x00 0x10 0x08 0x00 0x00 0x00 from 0x01 0x0204 generates 0x00 0x00 0x00 0x10 0x10 0x00 0x00 0x00 from 0x01 0x0304 generates -3 0x05 generates a -3 response 0x08 generates a -3 response 0x09 generates a -3 response */ data->mq.sendbuf = data->mq.recvbuf; if (maple_add_packet(&data->mq) != 0) printk("Could not add packet\n"); firstup++; if (firstup > 7) firstup = 0; } } static struct maple_driver dc_microphone_driver = { function:MAPLE_FUNC_MICROPHONE, name:"SoundInputPeripheral (S.I.P.)", connect:dc_microphone_connect, disconnect:dc_microphone_disconnect, reply:dc_microphone_callback, vblank:dc_microphone_vblank_callback, }; /* * Handle sound (OSS) * initialisation */ static struct file_operations mic_audio_fops = { owner:THIS_MODULE, open:mic_audio_open, release:mic_audio_release, read:mic_audio_read, ioctl:mic_audio_ioctl, }; /* TODO: Mixer registration */ static int attach_microphone() { printk("Microphone driver for SEGA Dreamcast, v 0.1.1\n"); /* Register with OSS */ mic_minor = register_sound_dsp(&mic_audio_fops, -1); if (mic_minor < 0) { DEBGM ("Maple: Could not register microphone with sound system.\n"); return -ENODEV; } return 0; } static int unload_microphone() { unregister_sound_dsp(mic_minor); return 0; } static int __init dc_microphone_init(void) { maple_register_driver(&dc_microphone_driver); if (attach_microphone()) { DEBGM("Maple: Failed to attach microphone\n"); return -ENOMEM; } return 0; } static void __exit dc_microphone_exit(void) { maple_unregister_driver(&dc_microphone_driver); if (unload_microphone()) { DEBGM("Maple: Microphone did not unload cleanly\n"); } } module_init(dc_microphone_init); module_exit(dc_microphone_exit); MODULE_AUTHOR("Adrian McMenamin <ad...@mc...>"); MODULE_DESCRIPTION("SEGA Dreamcast microphone driver"); |