|
From: Adrian M. <zx8...@us...> - 2006-07-08 13:31:05
|
Update of /cvsroot/linuxsh/linux/sound/sh In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv23819/sound/sh Modified Files: aica.c aica.h Log Message: aica driver tidy up Index: aica.c =================================================================== RCS file: /cvsroot/linuxsh/linux/sound/sh/aica.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- aica.c 5 Jun 2006 15:29:08 -0000 1.2 +++ aica.c 8 Jul 2006 13:30:38 -0000 1.3 @@ -162,12 +162,11 @@ writel(regval, ARM_RESET_REGISTER); } -/* Halt the sound processor, - clear the memory, - load some default ARM7 code, - and then restart ARM7 +/* + * Halt the sound processor, clear the memory, + * load some default ARM7 code, and then restart ARM7 */ -static void spu_init(void) +static void spu_reset(void) { spu_disable(); spu_memset(0, 0, 0x200000 / 4); @@ -236,22 +235,48 @@ return err; } -static void more_spu_dma(void *sstream) +static void startup_aica(struct snd_card_aica *dreamcastcard) +{ + spu_memload(AICA_CHANNEL0_CONTROL_OFFSET, + (uint8_t *) dreamcastcard->channel, + sizeof(struct aica_channel)); + aica_chn_start(); +} + + +static void execute_spu_dma(void *sstream) { + int buffer_size; struct snd_pcm_substream *substream; struct snd_pcm_runtime *runtime; struct snd_card_aica *dreamcastcard; substream = sstream; dreamcastcard = substream->pcm->private_data; runtime = substream->runtime; - aica_dma_transfer(runtime->channels, + if (unlikely(dreamcastcard->dma_started == 0)) + { + buffer_size = frames_to_bytes(runtime, runtime->buffer_size); + if (runtime->channels > 1) + dreamcastcard->channel->flags |= 0x01; + aica_dma_transfer(runtime->channels, buffer_size, substream); + startup_aica(dreamcastcard); + dreamcastcard->clicks = + buffer_size / (AICA_PERIOD_SIZE * runtime->channels); + dreamcastcard->dma_started = 1; + } + else + { + aica_dma_transfer(runtime->channels, AICA_PERIOD_SIZE * runtime->channels, substream); - snd_pcm_period_elapsed(dreamcastcard->substream); - dreamcastcard->clicks++; - dreamcastcard->clicks %= AICA_PERIOD_NUMBER; - mod_timer(&dreamcastcard->timer, jiffies + 1); + snd_pcm_period_elapsed(dreamcastcard->substream); + dreamcastcard->clicks++; + dreamcastcard->clicks %= AICA_PERIOD_NUMBER; + mod_timer(&dreamcastcard->timer, jiffies+1); + } + } + static void aica_period_elapsed(unsigned long timer_var) { /*timer fuction - so cannot sleep */ @@ -270,13 +295,11 @@ AICA_PERIOD_SIZE; if (play_period == dreamcastcard->current_period) { /* reschedule the timer */ - dreamcastcard->timer.expires = jiffies + 1; - add_timer(&(dreamcastcard->timer)); + mod_timer(&dreamcastcard->timer, jiffies+1); return; } if (runtime->channels > 1) dreamcastcard->current_period = play_period; - PREPARE_WORK(&spu_dma_work, more_spu_dma, substream); queue_work(aica_queue, &spu_dma_work); } @@ -305,6 +328,7 @@ spu_enable(); dreamcastcard->clicks = 0; dreamcastcard->current_period = 0; + dreamcastcard->dma_started = 0; return 0; } @@ -345,31 +369,7 @@ return 0; } -static void startup_aica(struct snd_card_aica *dreamcastcard) -{ - spu_memload(AICA_CHANNEL0_CONTROL_OFFSET, - (uint8_t *) dreamcastcard->channel, - sizeof(struct aica_channel)); - aica_chn_start(); -} -static void start_spu_dma(void *sstream) -{ - int buffer_size; - struct snd_pcm_substream *substream; - struct snd_pcm_runtime *runtime; - struct snd_card_aica *dreamcastcard; - substream = sstream; - dreamcastcard = substream->pcm->private_data; - runtime = substream->runtime; - buffer_size = frames_to_bytes(runtime, runtime->buffer_size); - if (runtime->channels > 1) - dreamcastcard->channel->flags |= 0x01; - aica_dma_transfer(runtime->channels, buffer_size, substream); - startup_aica(dreamcastcard); - dreamcastcard->clicks = - buffer_size / (AICA_PERIOD_SIZE * runtime->channels); -} static void spu_begin_dma(struct snd_pcm_substream *substream) { @@ -379,13 +379,8 @@ runtime = substream->runtime; dreamcastcard = substream->pcm->private_data; /* Use queue to do the heavy lifting */ - INIT_WORK(&spu_dma_work, start_spu_dma, substream); + INIT_WORK(&spu_dma_work, execute_spu_dma, substream); queue_work(aica_queue, &spu_dma_work); - /* Timer may already be running */ - if (unlikely(dreamcastcard->timer.data)) { - mod_timer(&dreamcastcard->timer, jiffies + 4); - return; - } init_timer(&(dreamcastcard->timer)); dreamcastcard->timer.data = (unsigned long)substream; dreamcastcard->timer.function = aica_period_elapsed; @@ -438,7 +433,7 @@ int err; /* AICA has no capture ability */ err = - snd_pcm_new(dreamcastcard->card, "AICA PCM", pcm_index, 1, 0, &pcm) + snd_pcm_new(dreamcastcard->card, "AICA PCM", pcm_index, 1, 0, &pcm); if (unlikely(err < 0)) return err; pcm->private_data = dreamcastcard; @@ -542,35 +537,12 @@ .put = aica_pcmvolume_put }; -static int remove_dreamcastcard(struct device *dreamcast_device) -{ - struct snd_card_aica *dreamcastcard = dreamcast_device->driver_data; - snd_card_free(dreamcastcard->card); - kfree(dreamcastcard); - return 0; -} - -static struct device_driver aica_driver = { - .name = "AICA", - .bus = &platform_bus_type, - .remove = remove_dreamcastcard, -}; - -/* Fill up the members of the embedded device structure */ -static void populate_dreamcastaicadev(struct device *dev) -{ - dev->bus = &platform_bus_type; - dev->driver = &aica_driver; - driver_register(dev->driver); - device_bind_driver(dev); -} - static int load_aica_firmware(void) { int err; const struct firmware *fw_entry; err = 0; - spu_init(); + spu_reset(); err = request_firmware(&fw_entry, "aica_firmware.bin", &pd->dev); if (unlikely(err)) return err; @@ -599,44 +571,40 @@ return 0; } -static int __init aica_init(void) +static int snd_aica_remove(struct platform_device *devptr) +{ + snd_card_free(platform_get_drvdata(devptr)); + kfree(devptr->dev.driver_data); + platform_set_drvdata(devptr, NULL); + return 0; +} + +static int __init snd_aica_probe(struct platform_device *devptr) { int err; struct snd_card_aica *dreamcastcard; - /* Are we in a Dreamcast at all? */ - if (unlikely(!mach_is_dreamcast())) - return -ENODEV; + dreamcastcard = kmalloc(sizeof(struct snd_card_aica), GFP_KERNEL); if (unlikely(!dreamcastcard)) return -ENOMEM; - dreamcastcard->card = snd_card_new(index, "AICA", THIS_MODULE, 0); + dreamcastcard->card = + snd_card_new(index, SND_AICA_DRIVER, THIS_MODULE, 0); if (unlikely(!dreamcastcard->card)) { kfree(dreamcastcard); return -ENODEV; } strcpy(dreamcastcard->card->driver, "snd_aica"); - strcpy(dreamcastcard->card->shortname, "AICA"); + strcpy(dreamcastcard->card->shortname, SND_AICA_DRIVER); strcpy(dreamcastcard->card->longname, "Yamaha AICA Super Intelligent Sound Processor for SEGA Dreamcast"); /* Load the PCM 'chip' */ err = snd_aicapcmchip(dreamcastcard, 0); if (unlikely(err < 0)) goto freedreamcast; - pd = platform_device_register_simple(dreamcastcard->card->driver, - -1, aica_memory_space, 2); - if (unlikely(IS_ERR(pd))) { - err = PTR_ERR(pd); - goto freepcm; - } - populate_dreamcastaicadev(&pd->dev); - snd_card_set_dev(dreamcastcard->card, &pd->dev); - pd->dev.driver_data = dreamcastcard; + + snd_card_set_dev(dreamcastcard->card, &devptr->dev); dreamcastcard->timer.data = 0; dreamcastcard->channel = NULL; - /* Load the firmware */ - err = load_aica_firmware(); - if (unlikely(err < 0)) - goto freedreamcast; /* Add basic controls */ err = add_aicamixer_controls(dreamcastcard); if (unlikely(err < 0)) @@ -645,37 +613,61 @@ err = snd_card_register(dreamcastcard->card); if (unlikely(err < 0)) goto freedreamcast; + platform_set_drvdata(devptr, dreamcastcard->card); aica_queue = create_workqueue("aica"); if (unlikely(!aica_queue)) goto freedreamcast; snd_printk ("ALSA Driver for Yamaha AICA Super Intelligent Sound Processor\n"); return 0; - freepcm: freedreamcast: snd_card_free(dreamcastcard->card); - if (pd) { - struct device_driver *drv = (&pd->dev)->driver; - device_release_driver(&pd->dev); - driver_unregister(drv); - platform_device_unregister(pd); - pd = NULL; - } kfree(dreamcastcard); return err; } + + +static struct platform_driver snd_aica_driver = { + .probe = snd_aica_probe, + .remove = snd_aica_remove, + //.suspend = snd_aica_suspend, + //.resume = snd_aica_resume, + .driver = { + .name = SND_AICA_DRIVER + }, +}; + +static int __init aica_init(void) { + int err; + + err = platform_driver_register(&snd_aica_driver); + if (unlikely(err < 0)) + return err; + pd = platform_device_register_simple(SND_AICA_DRIVER, -1, + aica_memory_space, 2); + if (unlikely(IS_ERR(pd))) { + platform_driver_unregister(&snd_aica_driver); + return PTR_ERR(pd); + } + /* Load the firmware */ + err = load_aica_firmware(); + if (unlikely(err < 0)) return err; + + return 0; +} + static void __exit aica_exit(void) { - struct device_driver *drv = (&pd->dev)->driver; + /* Flush and destroy the aica kernel thread */ flush_workqueue(aica_queue); destroy_workqueue(aica_queue); - device_release_driver(&pd->dev); - driver_unregister(drv); platform_device_unregister(pd); + platform_driver_unregister(&snd_aica_driver); /* Kill any sound still playing and reset ARM7 to safe state */ - spu_init(); + spu_reset(); } module_init(aica_init); module_exit(aica_exit); + Index: aica.h =================================================================== RCS file: /cvsroot/linuxsh/linux/sound/sh/aica.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- aica.h 4 Jun 2006 12:13:05 -0000 1.1 +++ aica.h 8 Jul 2006 13:30:53 -0000 1.2 @@ -26,10 +26,7 @@ #define ARM_RESET_REGISTER 0xA0702C00 #define SPU_REGISTER_BASE 0xA0700000 - - /* AICA channels stuff */ - #define AICA_CONTROL_POINT 0xA0810000 #define AICA_CONTROL_CHANNEL_SAMPLE_NUMBER 0xA0810008 #define AICA_CHANNEL0_CONTROL_OFFSET 0x10004 @@ -58,6 +55,7 @@ #define AICA_DMA_CHANNEL 0 #define AICA_DMA_MODE 5 +#define SND_AICA_DRIVER "AICA" struct aica_channel { uint32_t cmd; /* Command ID */ @@ -70,7 +68,6 @@ uint32_t flags; /* Bit flags */ }; - struct snd_card_aica { struct snd_card *card; struct aica_channel *channel; @@ -79,9 +76,6 @@ int current_period; struct timer_list timer; int master_volume; - struct work_struct work; - struct work_struct work2; - struct workqueue_struct *workqueue; + int dma_started; + int wq_init; }; - - |