diff options
Diffstat (limited to 'sound/arm/sa11xx-uda1341.c')
-rw-r--r-- | sound/arm/sa11xx-uda1341.c | 209 |
1 files changed, 121 insertions, 88 deletions
diff --git a/sound/arm/sa11xx-uda1341.c b/sound/arm/sa11xx-uda1341.c index 6ee912259cc5..13057d92f08a 100644 --- a/sound/arm/sa11xx-uda1341.c +++ b/sound/arm/sa11xx-uda1341.c | |||
@@ -21,7 +21,7 @@ | |||
21 | * merged HAL layer (patches from Brian) | 21 | * merged HAL layer (patches from Brian) |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /* $Id: sa11xx-uda1341.c,v 1.23 2005/09/09 13:22:34 tiwai Exp $ */ | 24 | /* $Id: sa11xx-uda1341.c,v 1.27 2005/12/07 09:13:42 cladisch Exp $ */ |
25 | 25 | ||
26 | /*************************************************************************************************** | 26 | /*************************************************************************************************** |
27 | * | 27 | * |
@@ -64,6 +64,8 @@ | |||
64 | #include <linux/module.h> | 64 | #include <linux/module.h> |
65 | #include <linux/moduleparam.h> | 65 | #include <linux/moduleparam.h> |
66 | #include <linux/init.h> | 66 | #include <linux/init.h> |
67 | #include <linux/err.h> | ||
68 | #include <linux/platform_device.h> | ||
67 | #include <linux/errno.h> | 69 | #include <linux/errno.h> |
68 | #include <linux/ioctl.h> | 70 | #include <linux/ioctl.h> |
69 | #include <linux/delay.h> | 71 | #include <linux/delay.h> |
@@ -115,7 +117,7 @@ static char *id = NULL; /* ID for this card */ | |||
115 | module_param(id, charp, 0444); | 117 | module_param(id, charp, 0444); |
116 | MODULE_PARM_DESC(id, "ID string for SA1100/SA1111 + UDA1341TS soundcard."); | 118 | MODULE_PARM_DESC(id, "ID string for SA1100/SA1111 + UDA1341TS soundcard."); |
117 | 119 | ||
118 | typedef struct audio_stream { | 120 | struct audio_stream { |
119 | char *id; /* identification string */ | 121 | char *id; /* identification string */ |
120 | int stream_id; /* numeric identification */ | 122 | int stream_id; /* numeric identification */ |
121 | dma_device_t dma_dev; /* device identifier for DMA */ | 123 | dma_device_t dma_dev; /* device identifier for DMA */ |
@@ -130,18 +132,16 @@ typedef struct audio_stream { | |||
130 | int tx_spin; /* are we recoding - flag used to do DMA trans. for sync */ | 132 | int tx_spin; /* are we recoding - flag used to do DMA trans. for sync */ |
131 | unsigned int old_offset; | 133 | unsigned int old_offset; |
132 | spinlock_t dma_lock; /* for locking in DMA operations (see dma-sa1100.c in the kernel) */ | 134 | spinlock_t dma_lock; /* for locking in DMA operations (see dma-sa1100.c in the kernel) */ |
133 | snd_pcm_substream_t *stream; | 135 | struct snd_pcm_substream *stream; |
134 | }audio_stream_t; | 136 | }; |
135 | 137 | ||
136 | typedef struct snd_card_sa11xx_uda1341 { | 138 | struct sa11xx_uda1341 { |
137 | snd_card_t *card; | 139 | struct snd_card *card; |
138 | struct l3_client *uda1341; | 140 | struct l3_client *uda1341; |
139 | snd_pcm_t *pcm; | 141 | struct snd_pcm *pcm; |
140 | long samplerate; | 142 | long samplerate; |
141 | audio_stream_t s[2]; /* playback & capture */ | 143 | struct audio_stream s[2]; /* playback & capture */ |
142 | } sa11xx_uda1341_t; | 144 | }; |
143 | |||
144 | static struct snd_card_sa11xx_uda1341 *sa11xx_uda1341 = NULL; | ||
145 | 145 | ||
146 | static unsigned int rates[] = { | 146 | static unsigned int rates[] = { |
147 | 8000, 10666, 10985, 14647, | 147 | 8000, 10666, 10985, 14647, |
@@ -149,12 +149,14 @@ static unsigned int rates[] = { | |||
149 | 29400, 32000, 44100, 48000, | 149 | 29400, 32000, 44100, 48000, |
150 | }; | 150 | }; |
151 | 151 | ||
152 | static snd_pcm_hw_constraint_list_t hw_constraints_rates = { | 152 | static struct snd_pcm_hw_constraint_list hw_constraints_rates = { |
153 | .count = ARRAY_SIZE(rates), | 153 | .count = ARRAY_SIZE(rates), |
154 | .list = rates, | 154 | .list = rates, |
155 | .mask = 0, | 155 | .mask = 0, |
156 | }; | 156 | }; |
157 | 157 | ||
158 | static struct platform_device *device; | ||
159 | |||
158 | /* }}} */ | 160 | /* }}} */ |
159 | 161 | ||
160 | /* {{{ Clock and sample rate stuff */ | 162 | /* {{{ Clock and sample rate stuff */ |
@@ -195,7 +197,7 @@ static void sa11xx_uda1341_set_audio_clock(long val) | |||
195 | } | 197 | } |
196 | } | 198 | } |
197 | 199 | ||
198 | static void sa11xx_uda1341_set_samplerate(sa11xx_uda1341_t *sa11xx_uda1341, long rate) | 200 | static void sa11xx_uda1341_set_samplerate(struct sa11xx_uda1341 *sa11xx_uda1341, long rate) |
199 | { | 201 | { |
200 | int clk_div = 0; | 202 | int clk_div = 0; |
201 | int clk=0; | 203 | int clk=0; |
@@ -280,7 +282,7 @@ static void sa11xx_uda1341_set_samplerate(sa11xx_uda1341_t *sa11xx_uda1341, long | |||
280 | 282 | ||
281 | /* {{{ HW init and shutdown */ | 283 | /* {{{ HW init and shutdown */ |
282 | 284 | ||
283 | static void sa11xx_uda1341_audio_init(sa11xx_uda1341_t *sa11xx_uda1341) | 285 | static void sa11xx_uda1341_audio_init(struct sa11xx_uda1341 *sa11xx_uda1341) |
284 | { | 286 | { |
285 | unsigned long flags; | 287 | unsigned long flags; |
286 | 288 | ||
@@ -337,7 +339,7 @@ static void sa11xx_uda1341_audio_init(sa11xx_uda1341_t *sa11xx_uda1341) | |||
337 | #endif | 339 | #endif |
338 | } | 340 | } |
339 | 341 | ||
340 | static void sa11xx_uda1341_audio_shutdown(sa11xx_uda1341_t *sa11xx_uda1341) | 342 | static void sa11xx_uda1341_audio_shutdown(struct sa11xx_uda1341 *sa11xx_uda1341) |
341 | { | 343 | { |
342 | /* mute on */ | 344 | /* mute on */ |
343 | #ifdef CONFIG_H3600_HAL | 345 | #ifdef CONFIG_H3600_HAL |
@@ -378,7 +380,7 @@ static void sa11xx_uda1341_audio_shutdown(sa11xx_uda1341_t *sa11xx_uda1341) | |||
378 | 380 | ||
379 | #ifdef HH_VERSION | 381 | #ifdef HH_VERSION |
380 | 382 | ||
381 | static int audio_dma_request(audio_stream_t *s, void (*callback)(void *, int)) | 383 | static int audio_dma_request(struct audio_stream *s, void (*callback)(void *, int)) |
382 | { | 384 | { |
383 | int ret; | 385 | int ret; |
384 | 386 | ||
@@ -391,7 +393,7 @@ static int audio_dma_request(audio_stream_t *s, void (*callback)(void *, int)) | |||
391 | return 0; | 393 | return 0; |
392 | } | 394 | } |
393 | 395 | ||
394 | static inline void audio_dma_free(audio_stream_t *s) | 396 | static inline void audio_dma_free(struct audio_stream *s) |
395 | { | 397 | { |
396 | sa1100_free_dma(s->dmach); | 398 | sa1100_free_dma(s->dmach); |
397 | s->dmach = -1; | 399 | s->dmach = -1; |
@@ -399,7 +401,7 @@ static inline void audio_dma_free(audio_stream_t *s) | |||
399 | 401 | ||
400 | #else | 402 | #else |
401 | 403 | ||
402 | static int audio_dma_request(audio_stream_t *s, void (*callback)(void *)) | 404 | static int audio_dma_request(struct audio_stream *s, void (*callback)(void *)) |
403 | { | 405 | { |
404 | int ret; | 406 | int ret; |
405 | 407 | ||
@@ -409,18 +411,18 @@ static int audio_dma_request(audio_stream_t *s, void (*callback)(void *)) | |||
409 | return ret; | 411 | return ret; |
410 | } | 412 | } |
411 | 413 | ||
412 | static void audio_dma_free(audio_stream_t *s) | 414 | static void audio_dma_free(struct audio_stream *s) |
413 | { | 415 | { |
414 | sa1100_free_dma((s)->dma_regs); | 416 | sa1100_free_dma(s->dma_regs); |
415 | (s)->dma_regs = 0; | 417 | s->dma_regs = 0; |
416 | } | 418 | } |
417 | 419 | ||
418 | #endif | 420 | #endif |
419 | 421 | ||
420 | static u_int audio_get_dma_pos(audio_stream_t *s) | 422 | static u_int audio_get_dma_pos(struct audio_stream *s) |
421 | { | 423 | { |
422 | snd_pcm_substream_t * substream = s->stream; | 424 | struct snd_pcm_substream *substream = s->stream; |
423 | snd_pcm_runtime_t *runtime = substream->runtime; | 425 | struct snd_pcm_runtime *runtime = substream->runtime; |
424 | unsigned int offset; | 426 | unsigned int offset; |
425 | unsigned long flags; | 427 | unsigned long flags; |
426 | dma_addr_t addr; | 428 | dma_addr_t addr; |
@@ -445,7 +447,7 @@ static u_int audio_get_dma_pos(audio_stream_t *s) | |||
445 | /* | 447 | /* |
446 | * this stops the dma and clears the dma ptrs | 448 | * this stops the dma and clears the dma ptrs |
447 | */ | 449 | */ |
448 | static void audio_stop_dma(audio_stream_t *s) | 450 | static void audio_stop_dma(struct audio_stream *s) |
449 | { | 451 | { |
450 | unsigned long flags; | 452 | unsigned long flags; |
451 | 453 | ||
@@ -461,10 +463,10 @@ static void audio_stop_dma(audio_stream_t *s) | |||
461 | spin_unlock_irqrestore(&s->dma_lock, flags); | 463 | spin_unlock_irqrestore(&s->dma_lock, flags); |
462 | } | 464 | } |
463 | 465 | ||
464 | static void audio_process_dma(audio_stream_t *s) | 466 | static void audio_process_dma(struct audio_stream *s) |
465 | { | 467 | { |
466 | snd_pcm_substream_t *substream = s->stream; | 468 | struct snd_pcm_substream *substream = s->stream; |
467 | snd_pcm_runtime_t *runtime; | 469 | struct snd_pcm_runtime *runtime; |
468 | unsigned int dma_size; | 470 | unsigned int dma_size; |
469 | unsigned int offset; | 471 | unsigned int offset; |
470 | int ret; | 472 | int ret; |
@@ -527,7 +529,7 @@ static void audio_dma_callback(void *data, int size) | |||
527 | static void audio_dma_callback(void *data) | 529 | static void audio_dma_callback(void *data) |
528 | #endif | 530 | #endif |
529 | { | 531 | { |
530 | audio_stream_t *s = data; | 532 | struct audio_stream *s = data; |
531 | 533 | ||
532 | /* | 534 | /* |
533 | * If we are getting a callback for an active stream then we inform | 535 | * If we are getting a callback for an active stream then we inform |
@@ -549,12 +551,12 @@ static void audio_dma_callback(void *data) | |||
549 | 551 | ||
550 | /* {{{ trigger & timer */ | 552 | /* {{{ trigger & timer */ |
551 | 553 | ||
552 | static int snd_sa11xx_uda1341_trigger(snd_pcm_substream_t * substream, int cmd) | 554 | static int snd_sa11xx_uda1341_trigger(struct snd_pcm_substream *substream, int cmd) |
553 | { | 555 | { |
554 | sa11xx_uda1341_t *chip = snd_pcm_substream_chip(substream); | 556 | struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream); |
555 | int stream_id = substream->pstr->stream; | 557 | int stream_id = substream->pstr->stream; |
556 | audio_stream_t *s = &chip->s[stream_id]; | 558 | struct audio_stream *s = &chip->s[stream_id]; |
557 | audio_stream_t *s1 = &chip->s[stream_id ^ 1]; | 559 | struct audio_stream *s1 = &chip->s[stream_id ^ 1]; |
558 | int err = 0; | 560 | int err = 0; |
559 | 561 | ||
560 | /* note local interrupts are already disabled in the midlevel code */ | 562 | /* note local interrupts are already disabled in the midlevel code */ |
@@ -683,11 +685,11 @@ static int snd_sa11xx_uda1341_trigger(snd_pcm_substream_t * substream, int cmd) | |||
683 | return err; | 685 | return err; |
684 | } | 686 | } |
685 | 687 | ||
686 | static int snd_sa11xx_uda1341_prepare(snd_pcm_substream_t * substream) | 688 | static int snd_sa11xx_uda1341_prepare(struct snd_pcm_substream *substream) |
687 | { | 689 | { |
688 | sa11xx_uda1341_t *chip = snd_pcm_substream_chip(substream); | 690 | struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream); |
689 | snd_pcm_runtime_t *runtime = substream->runtime; | 691 | struct snd_pcm_runtime *runtime = substream->runtime; |
690 | audio_stream_t *s = &chip->s[substream->pstr->stream]; | 692 | struct audio_stream *s = &chip->s[substream->pstr->stream]; |
691 | 693 | ||
692 | /* set requested samplerate */ | 694 | /* set requested samplerate */ |
693 | sa11xx_uda1341_set_samplerate(chip, runtime->rate); | 695 | sa11xx_uda1341_set_samplerate(chip, runtime->rate); |
@@ -701,15 +703,15 @@ static int snd_sa11xx_uda1341_prepare(snd_pcm_substream_t * substream) | |||
701 | return 0; | 703 | return 0; |
702 | } | 704 | } |
703 | 705 | ||
704 | static snd_pcm_uframes_t snd_sa11xx_uda1341_pointer(snd_pcm_substream_t * substream) | 706 | static snd_pcm_uframes_t snd_sa11xx_uda1341_pointer(struct snd_pcm_substream *substream) |
705 | { | 707 | { |
706 | sa11xx_uda1341_t *chip = snd_pcm_substream_chip(substream); | 708 | struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream); |
707 | return audio_get_dma_pos(&chip->s[substream->pstr->stream]); | 709 | return audio_get_dma_pos(&chip->s[substream->pstr->stream]); |
708 | } | 710 | } |
709 | 711 | ||
710 | /* }}} */ | 712 | /* }}} */ |
711 | 713 | ||
712 | static snd_pcm_hardware_t snd_sa11xx_uda1341_capture = | 714 | static struct snd_pcm_hardware snd_sa11xx_uda1341_capture = |
713 | { | 715 | { |
714 | .info = (SNDRV_PCM_INFO_INTERLEAVED | | 716 | .info = (SNDRV_PCM_INFO_INTERLEAVED | |
715 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 717 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
@@ -732,7 +734,7 @@ static snd_pcm_hardware_t snd_sa11xx_uda1341_capture = | |||
732 | .fifo_size = 0, | 734 | .fifo_size = 0, |
733 | }; | 735 | }; |
734 | 736 | ||
735 | static snd_pcm_hardware_t snd_sa11xx_uda1341_playback = | 737 | static struct snd_pcm_hardware snd_sa11xx_uda1341_playback = |
736 | { | 738 | { |
737 | .info = (SNDRV_PCM_INFO_INTERLEAVED | | 739 | .info = (SNDRV_PCM_INFO_INTERLEAVED | |
738 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 740 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
@@ -755,10 +757,10 @@ static snd_pcm_hardware_t snd_sa11xx_uda1341_playback = | |||
755 | .fifo_size = 0, | 757 | .fifo_size = 0, |
756 | }; | 758 | }; |
757 | 759 | ||
758 | static int snd_card_sa11xx_uda1341_open(snd_pcm_substream_t * substream) | 760 | static int snd_card_sa11xx_uda1341_open(struct snd_pcm_substream *substream) |
759 | { | 761 | { |
760 | sa11xx_uda1341_t *chip = snd_pcm_substream_chip(substream); | 762 | struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream); |
761 | snd_pcm_runtime_t *runtime = substream->runtime; | 763 | struct snd_pcm_runtime *runtime = substream->runtime; |
762 | int stream_id = substream->pstr->stream; | 764 | int stream_id = substream->pstr->stream; |
763 | int err; | 765 | int err; |
764 | 766 | ||
@@ -776,9 +778,9 @@ static int snd_card_sa11xx_uda1341_open(snd_pcm_substream_t * substream) | |||
776 | return 0; | 778 | return 0; |
777 | } | 779 | } |
778 | 780 | ||
779 | static int snd_card_sa11xx_uda1341_close(snd_pcm_substream_t * substream) | 781 | static int snd_card_sa11xx_uda1341_close(struct snd_pcm_substream *substream) |
780 | { | 782 | { |
781 | sa11xx_uda1341_t *chip = snd_pcm_substream_chip(substream); | 783 | struct sa11xx_uda1341 *chip = snd_pcm_substream_chip(substream); |
782 | 784 | ||
783 | chip->s[substream->pstr->stream].stream = NULL; | 785 | chip->s[substream->pstr->stream].stream = NULL; |
784 | return 0; | 786 | return 0; |
@@ -786,21 +788,21 @@ static int snd_card_sa11xx_uda1341_close(snd_pcm_substream_t * substream) | |||
786 | 788 | ||
787 | /* {{{ HW params & free */ | 789 | /* {{{ HW params & free */ |
788 | 790 | ||
789 | static int snd_sa11xx_uda1341_hw_params(snd_pcm_substream_t * substream, | 791 | static int snd_sa11xx_uda1341_hw_params(struct snd_pcm_substream *substream, |
790 | snd_pcm_hw_params_t * hw_params) | 792 | struct snd_pcm_hw_params *hw_params) |
791 | { | 793 | { |
792 | 794 | ||
793 | return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); | 795 | return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); |
794 | } | 796 | } |
795 | 797 | ||
796 | static int snd_sa11xx_uda1341_hw_free(snd_pcm_substream_t * substream) | 798 | static int snd_sa11xx_uda1341_hw_free(struct snd_pcm_substream *substream) |
797 | { | 799 | { |
798 | return snd_pcm_lib_free_pages(substream); | 800 | return snd_pcm_lib_free_pages(substream); |
799 | } | 801 | } |
800 | 802 | ||
801 | /* }}} */ | 803 | /* }}} */ |
802 | 804 | ||
803 | static snd_pcm_ops_t snd_card_sa11xx_uda1341_playback_ops = { | 805 | static struct snd_pcm_ops snd_card_sa11xx_uda1341_playback_ops = { |
804 | .open = snd_card_sa11xx_uda1341_open, | 806 | .open = snd_card_sa11xx_uda1341_open, |
805 | .close = snd_card_sa11xx_uda1341_close, | 807 | .close = snd_card_sa11xx_uda1341_close, |
806 | .ioctl = snd_pcm_lib_ioctl, | 808 | .ioctl = snd_pcm_lib_ioctl, |
@@ -811,7 +813,7 @@ static snd_pcm_ops_t snd_card_sa11xx_uda1341_playback_ops = { | |||
811 | .pointer = snd_sa11xx_uda1341_pointer, | 813 | .pointer = snd_sa11xx_uda1341_pointer, |
812 | }; | 814 | }; |
813 | 815 | ||
814 | static snd_pcm_ops_t snd_card_sa11xx_uda1341_capture_ops = { | 816 | static struct snd_pcm_ops snd_card_sa11xx_uda1341_capture_ops = { |
815 | .open = snd_card_sa11xx_uda1341_open, | 817 | .open = snd_card_sa11xx_uda1341_open, |
816 | .close = snd_card_sa11xx_uda1341_close, | 818 | .close = snd_card_sa11xx_uda1341_close, |
817 | .ioctl = snd_pcm_lib_ioctl, | 819 | .ioctl = snd_pcm_lib_ioctl, |
@@ -822,9 +824,9 @@ static snd_pcm_ops_t snd_card_sa11xx_uda1341_capture_ops = { | |||
822 | .pointer = snd_sa11xx_uda1341_pointer, | 824 | .pointer = snd_sa11xx_uda1341_pointer, |
823 | }; | 825 | }; |
824 | 826 | ||
825 | static int __init snd_card_sa11xx_uda1341_pcm(sa11xx_uda1341_t *sa11xx_uda1341, int device) | 827 | static int __init snd_card_sa11xx_uda1341_pcm(struct sa11xx_uda1341 *sa11xx_uda1341, int device) |
826 | { | 828 | { |
827 | snd_pcm_t *pcm; | 829 | struct snd_pcm *pcm; |
828 | int err; | 830 | int err; |
829 | 831 | ||
830 | if ((err = snd_pcm_new(sa11xx_uda1341->card, "UDA1341 PCM", device, 1, 1, &pcm)) < 0) | 832 | if ((err = snd_pcm_new(sa11xx_uda1341->card, "UDA1341 PCM", device, 1, 1, &pcm)) < 0) |
@@ -835,8 +837,8 @@ static int __init snd_card_sa11xx_uda1341_pcm(sa11xx_uda1341_t *sa11xx_uda1341, | |||
835 | * isa works but I'm not sure why (or if) it's the right choice | 837 | * isa works but I'm not sure why (or if) it's the right choice |
836 | * this may be too large, trying it for now | 838 | * this may be too large, trying it for now |
837 | */ | 839 | */ |
838 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_ISA, | 840 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
839 | snd_pcm_dma_flags(0), | 841 | snd_dma_isa_data(), |
840 | 64*1024, 64*1024); | 842 | 64*1024, 64*1024); |
841 | 843 | ||
842 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_sa11xx_uda1341_playback_ops); | 844 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_sa11xx_uda1341_playback_ops); |
@@ -862,12 +864,15 @@ static int __init snd_card_sa11xx_uda1341_pcm(sa11xx_uda1341_t *sa11xx_uda1341, | |||
862 | 864 | ||
863 | #ifdef CONFIG_PM | 865 | #ifdef CONFIG_PM |
864 | 866 | ||
865 | static int snd_sa11xx_uda1341_suspend(snd_card_t *card, pm_message_t state) | 867 | static int snd_sa11xx_uda1341_suspend(struct platform_device *devptr, |
868 | pm_message_t state) | ||
866 | { | 869 | { |
867 | sa11xx_uda1341_t *chip = card->pm_private_data; | 870 | struct snd_card *card = platform_get_drvdata(devptr); |
871 | struct sa11xx_uda1341 *chip = card->private_data; | ||
868 | 872 | ||
873 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | ||
869 | snd_pcm_suspend_all(chip->pcm); | 874 | snd_pcm_suspend_all(chip->pcm); |
870 | #ifdef HH_VERSION | 875 | #ifdef HH_VERSION |
871 | sa1100_dma_sleep(chip->s[SNDRV_PCM_STREAM_PLAYBACK].dmach); | 876 | sa1100_dma_sleep(chip->s[SNDRV_PCM_STREAM_PLAYBACK].dmach); |
872 | sa1100_dma_sleep(chip->s[SNDRV_PCM_STREAM_CAPTURE].dmach); | 877 | sa1100_dma_sleep(chip->s[SNDRV_PCM_STREAM_CAPTURE].dmach); |
873 | #else | 878 | #else |
@@ -875,12 +880,14 @@ static int snd_sa11xx_uda1341_suspend(snd_card_t *card, pm_message_t state) | |||
875 | #endif | 880 | #endif |
876 | l3_command(chip->uda1341, CMD_SUSPEND, NULL); | 881 | l3_command(chip->uda1341, CMD_SUSPEND, NULL); |
877 | sa11xx_uda1341_audio_shutdown(chip); | 882 | sa11xx_uda1341_audio_shutdown(chip); |
883 | |||
878 | return 0; | 884 | return 0; |
879 | } | 885 | } |
880 | 886 | ||
881 | static int snd_sa11xx_uda1341_resume(snd_card_t *card) | 887 | static int snd_sa11xx_uda1341_resume(struct platform_device *devptr) |
882 | { | 888 | { |
883 | sa11xx_uda1341_t *chip = card->pm_private_data; | 889 | struct snd_card *card = platform_get_drvdata(devptr); |
890 | struct sa11xx_uda1341 *chip = card->private_data; | ||
884 | 891 | ||
885 | sa11xx_uda1341_audio_init(chip); | 892 | sa11xx_uda1341_audio_init(chip); |
886 | l3_command(chip->uda1341, CMD_RESUME, NULL); | 893 | l3_command(chip->uda1341, CMD_RESUME, NULL); |
@@ -890,67 +897,55 @@ static int snd_sa11xx_uda1341_resume(snd_card_t *card) | |||
890 | #else | 897 | #else |
891 | //FIXME | 898 | //FIXME |
892 | #endif | 899 | #endif |
900 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | ||
893 | return 0; | 901 | return 0; |
894 | } | 902 | } |
895 | #endif /* COMFIG_PM */ | 903 | #endif /* COMFIG_PM */ |
896 | 904 | ||
897 | void snd_sa11xx_uda1341_free(snd_card_t *card) | 905 | void snd_sa11xx_uda1341_free(struct snd_card *card) |
898 | { | 906 | { |
899 | sa11xx_uda1341_t *chip = card->private_data; | 907 | struct sa11xx_uda1341 *chip = card->private_data; |
900 | 908 | ||
901 | audio_dma_free(&chip->s[SNDRV_PCM_STREAM_PLAYBACK]); | 909 | audio_dma_free(&chip->s[SNDRV_PCM_STREAM_PLAYBACK]); |
902 | audio_dma_free(&chip->s[SNDRV_PCM_STREAM_CAPTURE]); | 910 | audio_dma_free(&chip->s[SNDRV_PCM_STREAM_CAPTURE]); |
903 | sa11xx_uda1341 = NULL; | ||
904 | card->private_data = NULL; | ||
905 | kfree(chip); | ||
906 | } | 911 | } |
907 | 912 | ||
908 | static int __init sa11xx_uda1341_init(void) | 913 | static int __init sa11xx_uda1341_probe(struct platform_device *devptr) |
909 | { | 914 | { |
910 | int err; | 915 | int err; |
911 | snd_card_t *card; | 916 | struct snd_card *card; |
912 | 917 | struct sa11xx_uda1341 *chip; | |
913 | if (!machine_is_h3xxx()) | ||
914 | return -ENODEV; | ||
915 | 918 | ||
916 | /* register the soundcard */ | 919 | /* register the soundcard */ |
917 | card = snd_card_new(-1, id, THIS_MODULE, sizeof(sa11xx_uda1341_t)); | 920 | card = snd_card_new(-1, id, THIS_MODULE, sizeof(struct sa11xx_uda1341)); |
918 | if (card == NULL) | 921 | if (card == NULL) |
919 | return -ENOMEM; | 922 | return -ENOMEM; |
920 | 923 | ||
921 | sa11xx_uda1341 = kzalloc(sizeof(*sa11xx_uda1341), GFP_KERNEL); | 924 | chip = card->private_data; |
922 | if (sa11xx_uda1341 == NULL) | ||
923 | return -ENOMEM; | ||
924 | spin_lock_init(&chip->s[0].dma_lock); | 925 | spin_lock_init(&chip->s[0].dma_lock); |
925 | spin_lock_init(&chip->s[1].dma_lock); | 926 | spin_lock_init(&chip->s[1].dma_lock); |
926 | |||
927 | card->private_data = (void *)sa11xx_uda1341; | ||
928 | card->private_free = snd_sa11xx_uda1341_free; | ||
929 | 927 | ||
930 | sa11xx_uda1341->card = card; | 928 | card->private_free = snd_sa11xx_uda1341_free; |
931 | sa11xx_uda1341->samplerate = AUDIO_RATE_DEFAULT; | 929 | chip->card = card; |
930 | chip->samplerate = AUDIO_RATE_DEFAULT; | ||
932 | 931 | ||
933 | // mixer | 932 | // mixer |
934 | if ((err = snd_chip_uda1341_mixer_new(sa11xx_uda1341->card, &sa11xx_uda1341->uda1341))) | 933 | if ((err = snd_chip_uda1341_mixer_new(card, &chip->uda1341))) |
935 | goto nodev; | 934 | goto nodev; |
936 | 935 | ||
937 | // PCM | 936 | // PCM |
938 | if ((err = snd_card_sa11xx_uda1341_pcm(sa11xx_uda1341, 0)) < 0) | 937 | if ((err = snd_card_sa11xx_uda1341_pcm(chip, 0)) < 0) |
939 | goto nodev; | 938 | goto nodev; |
940 | 939 | ||
941 | snd_card_set_generic_pm_callback(card, | ||
942 | snd_sa11xx_uda1341_suspend, snd_sa11_uda1341_resume, | ||
943 | sa11xx_uda1341); | ||
944 | |||
945 | strcpy(card->driver, "UDA1341"); | 940 | strcpy(card->driver, "UDA1341"); |
946 | strcpy(card->shortname, "H3600 UDA1341TS"); | 941 | strcpy(card->shortname, "H3600 UDA1341TS"); |
947 | sprintf(card->longname, "Compaq iPAQ H3600 with Philips UDA1341TS"); | 942 | sprintf(card->longname, "Compaq iPAQ H3600 with Philips UDA1341TS"); |
948 | 943 | ||
949 | if ((err = snd_card_set_generic_dev(card)) < 0) | 944 | snd_card_set_dev(card, &devptr->dev); |
950 | goto nodev; | ||
951 | 945 | ||
952 | if ((err = snd_card_register(card)) == 0) { | 946 | if ((err = snd_card_register(card)) == 0) { |
953 | printk( KERN_INFO "iPAQ audio support initialized\n" ); | 947 | printk( KERN_INFO "iPAQ audio support initialized\n" ); |
948 | platform_set_drvdata(devptr, card); | ||
954 | return 0; | 949 | return 0; |
955 | } | 950 | } |
956 | 951 | ||
@@ -959,9 +954,47 @@ static int __init sa11xx_uda1341_init(void) | |||
959 | return err; | 954 | return err; |
960 | } | 955 | } |
961 | 956 | ||
957 | static int __devexit sa11xx_uda1341_remove(struct platform_device *devptr) | ||
958 | { | ||
959 | snd_card_free(platform_get_drvdata(devptr)); | ||
960 | platform_set_drvdata(devptr, NULL); | ||
961 | return 0; | ||
962 | } | ||
963 | |||
964 | #define SA11XX_UDA1341_DRIVER "sa11xx_uda1341" | ||
965 | |||
966 | static struct platform_driver sa11xx_uda1341_driver = { | ||
967 | .probe = sa11xx_uda1341_probe, | ||
968 | .remove = __devexit_p(sa11xx_uda1341_remove), | ||
969 | #ifdef CONFIG_PM | ||
970 | .suspend = snd_sa11xx_uda1341_suspend, | ||
971 | .resume = snd_sa11xx_uda1341_resume, | ||
972 | #endif | ||
973 | .driver = { | ||
974 | .name = SA11XX_UDA1341_DRIVER, | ||
975 | }, | ||
976 | }; | ||
977 | |||
978 | static int __init sa11xx_uda1341_init(void) | ||
979 | { | ||
980 | int err; | ||
981 | |||
982 | if (!machine_is_h3xxx()) | ||
983 | return -ENODEV; | ||
984 | if ((err = platform_driver_register(&sa11xx_uda1341_driver)) < 0) | ||
985 | return err; | ||
986 | device = platform_device_register_simple(SA11XX_UDA1341_DRIVER, -1, NULL, 0); | ||
987 | if (IS_ERR(device)) { | ||
988 | platform_driver_unregister(&sa11xx_uda1341_driver); | ||
989 | return PTR_ERR(device); | ||
990 | } | ||
991 | return 0; | ||
992 | } | ||
993 | |||
962 | static void __exit sa11xx_uda1341_exit(void) | 994 | static void __exit sa11xx_uda1341_exit(void) |
963 | { | 995 | { |
964 | snd_card_free(sa11xx_uda1341->card); | 996 | platform_device_unregister(device); |
997 | platform_driver_unregister(&sa11xx_uda1341_driver); | ||
965 | } | 998 | } |
966 | 999 | ||
967 | module_init(sa11xx_uda1341_init); | 1000 | module_init(sa11xx_uda1341_init); |