diff options
Diffstat (limited to 'sound/pci/cs5535audio')
-rw-r--r-- | sound/pci/cs5535audio/Makefile | 7 | ||||
-rw-r--r-- | sound/pci/cs5535audio/cs5535audio.c | 24 | ||||
-rw-r--r-- | sound/pci/cs5535audio/cs5535audio.h | 42 | ||||
-rw-r--r-- | sound/pci/cs5535audio/cs5535audio_pcm.c | 10 | ||||
-rw-r--r-- | sound/pci/cs5535audio/cs5535audio_pm.c | 26 |
5 files changed, 31 insertions, 78 deletions
diff --git a/sound/pci/cs5535audio/Makefile b/sound/pci/cs5535audio/Makefile index ad947b4c04cc..bb3d57e6a3cb 100644 --- a/sound/pci/cs5535audio/Makefile +++ b/sound/pci/cs5535audio/Makefile | |||
@@ -2,11 +2,8 @@ | |||
2 | # Makefile for cs5535audio | 2 | # Makefile for cs5535audio |
3 | # | 3 | # |
4 | 4 | ||
5 | snd-cs5535audio-objs := cs5535audio.o cs5535audio_pcm.o | 5 | snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o |
6 | 6 | snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o | |
7 | ifeq ($(CONFIG_PM),y) | ||
8 | snd-cs5535audio-objs += cs5535audio_pm.o | ||
9 | endif | ||
10 | 7 | ||
11 | # Toplevel Module Dependency | 8 | # Toplevel Module Dependency |
12 | obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o | 9 | obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o |
diff --git a/sound/pci/cs5535audio/cs5535audio.c b/sound/pci/cs5535audio/cs5535audio.c index b8e75ef9c1e6..2b35889787be 100644 --- a/sound/pci/cs5535audio/cs5535audio.c +++ b/sound/pci/cs5535audio/cs5535audio.c | |||
@@ -206,7 +206,6 @@ static void process_bm1_irq(struct cs5535audio *cs5535au) | |||
206 | static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id) | 206 | static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id) |
207 | { | 207 | { |
208 | u16 acc_irq_stat; | 208 | u16 acc_irq_stat; |
209 | u8 bm_stat; | ||
210 | unsigned char count; | 209 | unsigned char count; |
211 | struct cs5535audio *cs5535au = dev_id; | 210 | struct cs5535audio *cs5535au = dev_id; |
212 | 211 | ||
@@ -217,7 +216,7 @@ static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id) | |||
217 | 216 | ||
218 | if (!acc_irq_stat) | 217 | if (!acc_irq_stat) |
219 | return IRQ_NONE; | 218 | return IRQ_NONE; |
220 | for (count = 0; count < 10; count++) { | 219 | for (count = 0; count < 4; count++) { |
221 | if (acc_irq_stat & (1 << count)) { | 220 | if (acc_irq_stat & (1 << count)) { |
222 | switch (count) { | 221 | switch (count) { |
223 | case IRQ_STS: | 222 | case IRQ_STS: |
@@ -232,26 +231,9 @@ static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id) | |||
232 | case BM1_IRQ_STS: | 231 | case BM1_IRQ_STS: |
233 | process_bm1_irq(cs5535au); | 232 | process_bm1_irq(cs5535au); |
234 | break; | 233 | break; |
235 | case BM2_IRQ_STS: | ||
236 | bm_stat = cs_readb(cs5535au, ACC_BM2_STATUS); | ||
237 | break; | ||
238 | case BM3_IRQ_STS: | ||
239 | bm_stat = cs_readb(cs5535au, ACC_BM3_STATUS); | ||
240 | break; | ||
241 | case BM4_IRQ_STS: | ||
242 | bm_stat = cs_readb(cs5535au, ACC_BM4_STATUS); | ||
243 | break; | ||
244 | case BM5_IRQ_STS: | ||
245 | bm_stat = cs_readb(cs5535au, ACC_BM5_STATUS); | ||
246 | break; | ||
247 | case BM6_IRQ_STS: | ||
248 | bm_stat = cs_readb(cs5535au, ACC_BM6_STATUS); | ||
249 | break; | ||
250 | case BM7_IRQ_STS: | ||
251 | bm_stat = cs_readb(cs5535au, ACC_BM7_STATUS); | ||
252 | break; | ||
253 | default: | 234 | default: |
254 | snd_printk(KERN_ERR "Unexpected irq src\n"); | 235 | snd_printk(KERN_ERR "Unexpected irq src: " |
236 | "0x%x\n", acc_irq_stat); | ||
255 | break; | 237 | break; |
256 | } | 238 | } |
257 | } | 239 | } |
diff --git a/sound/pci/cs5535audio/cs5535audio.h b/sound/pci/cs5535audio/cs5535audio.h index 4fd1f31a6cf9..66bae7664193 100644 --- a/sound/pci/cs5535audio/cs5535audio.h +++ b/sound/pci/cs5535audio/cs5535audio.h | |||
@@ -16,57 +16,28 @@ | |||
16 | #define ACC_IRQ_STATUS 0x12 | 16 | #define ACC_IRQ_STATUS 0x12 |
17 | #define ACC_BM0_CMD 0x20 | 17 | #define ACC_BM0_CMD 0x20 |
18 | #define ACC_BM1_CMD 0x28 | 18 | #define ACC_BM1_CMD 0x28 |
19 | #define ACC_BM2_CMD 0x30 | ||
20 | #define ACC_BM3_CMD 0x38 | ||
21 | #define ACC_BM4_CMD 0x40 | ||
22 | #define ACC_BM5_CMD 0x48 | ||
23 | #define ACC_BM6_CMD 0x50 | ||
24 | #define ACC_BM7_CMD 0x58 | ||
25 | #define ACC_BM0_PRD 0x24 | 19 | #define ACC_BM0_PRD 0x24 |
26 | #define ACC_BM1_PRD 0x2C | 20 | #define ACC_BM1_PRD 0x2C |
27 | #define ACC_BM2_PRD 0x34 | ||
28 | #define ACC_BM3_PRD 0x3C | ||
29 | #define ACC_BM4_PRD 0x44 | ||
30 | #define ACC_BM5_PRD 0x4C | ||
31 | #define ACC_BM6_PRD 0x54 | ||
32 | #define ACC_BM7_PRD 0x5C | ||
33 | #define ACC_BM0_STATUS 0x21 | 21 | #define ACC_BM0_STATUS 0x21 |
34 | #define ACC_BM1_STATUS 0x29 | 22 | #define ACC_BM1_STATUS 0x29 |
35 | #define ACC_BM2_STATUS 0x31 | ||
36 | #define ACC_BM3_STATUS 0x39 | ||
37 | #define ACC_BM4_STATUS 0x41 | ||
38 | #define ACC_BM5_STATUS 0x49 | ||
39 | #define ACC_BM6_STATUS 0x51 | ||
40 | #define ACC_BM7_STATUS 0x59 | ||
41 | #define ACC_BM0_PNTR 0x60 | 23 | #define ACC_BM0_PNTR 0x60 |
42 | #define ACC_BM1_PNTR 0x64 | 24 | #define ACC_BM1_PNTR 0x64 |
43 | #define ACC_BM2_PNTR 0x68 | 25 | |
44 | #define ACC_BM3_PNTR 0x6C | ||
45 | #define ACC_BM4_PNTR 0x70 | ||
46 | #define ACC_BM5_PNTR 0x74 | ||
47 | #define ACC_BM6_PNTR 0x78 | ||
48 | #define ACC_BM7_PNTR 0x7C | ||
49 | /* acc_codec bar0 reg bits */ | 26 | /* acc_codec bar0 reg bits */ |
50 | /* ACC_IRQ_STATUS */ | 27 | /* ACC_IRQ_STATUS */ |
51 | #define IRQ_STS 0 | 28 | #define IRQ_STS 0 |
52 | #define WU_IRQ_STS 1 | 29 | #define WU_IRQ_STS 1 |
53 | #define BM0_IRQ_STS 2 | 30 | #define BM0_IRQ_STS 2 |
54 | #define BM1_IRQ_STS 3 | 31 | #define BM1_IRQ_STS 3 |
55 | #define BM2_IRQ_STS 4 | ||
56 | #define BM3_IRQ_STS 5 | ||
57 | #define BM4_IRQ_STS 6 | ||
58 | #define BM5_IRQ_STS 7 | ||
59 | #define BM6_IRQ_STS 8 | ||
60 | #define BM7_IRQ_STS 9 | ||
61 | /* ACC_BMX_STATUS */ | 32 | /* ACC_BMX_STATUS */ |
62 | #define EOP (1<<0) | 33 | #define EOP (1<<0) |
63 | #define BM_EOP_ERR (1<<1) | 34 | #define BM_EOP_ERR (1<<1) |
64 | /* ACC_BMX_CTL */ | 35 | /* ACC_BMX_CTL */ |
65 | #define BM_CTL_EN 0x00000001 | 36 | #define BM_CTL_EN 0x01 |
66 | #define BM_CTL_PAUSE 0x00000011 | 37 | #define BM_CTL_PAUSE 0x03 |
67 | #define BM_CTL_DIS 0x00000000 | 38 | #define BM_CTL_DIS 0x00 |
68 | #define BM_CTL_BYTE_ORD_LE 0x00000000 | 39 | #define BM_CTL_BYTE_ORD_LE 0x00 |
69 | #define BM_CTL_BYTE_ORD_BE 0x00000100 | 40 | #define BM_CTL_BYTE_ORD_BE 0x04 |
70 | /* cs5535 specific ac97 codec register defines */ | 41 | /* cs5535 specific ac97 codec register defines */ |
71 | #define CMD_MASK 0xFF00FFFF | 42 | #define CMD_MASK 0xFF00FFFF |
72 | #define CMD_NEW 0x00010000 | 43 | #define CMD_NEW 0x00010000 |
@@ -106,7 +77,6 @@ struct cs5535audio_dma { | |||
106 | struct snd_pcm_substream *substream; | 77 | struct snd_pcm_substream *substream; |
107 | unsigned int buf_addr, buf_bytes; | 78 | unsigned int buf_addr, buf_bytes; |
108 | unsigned int period_bytes, periods; | 79 | unsigned int period_bytes, periods; |
109 | int suspended; | ||
110 | u32 saved_prd; | 80 | u32 saved_prd; |
111 | }; | 81 | }; |
112 | 82 | ||
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c index 5450a9e8f133..21df0634af32 100644 --- a/sound/pci/cs5535audio/cs5535audio_pcm.c +++ b/sound/pci/cs5535audio/cs5535audio_pcm.c | |||
@@ -43,7 +43,6 @@ static struct snd_pcm_hardware snd_cs5535audio_playback = | |||
43 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 43 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
44 | SNDRV_PCM_INFO_MMAP_VALID | | 44 | SNDRV_PCM_INFO_MMAP_VALID | |
45 | SNDRV_PCM_INFO_PAUSE | | 45 | SNDRV_PCM_INFO_PAUSE | |
46 | SNDRV_PCM_INFO_SYNC_START | | ||
47 | SNDRV_PCM_INFO_RESUME | 46 | SNDRV_PCM_INFO_RESUME |
48 | ), | 47 | ), |
49 | .formats = ( | 48 | .formats = ( |
@@ -71,8 +70,7 @@ static struct snd_pcm_hardware snd_cs5535audio_capture = | |||
71 | SNDRV_PCM_INFO_MMAP | | 70 | SNDRV_PCM_INFO_MMAP | |
72 | SNDRV_PCM_INFO_INTERLEAVED | | 71 | SNDRV_PCM_INFO_INTERLEAVED | |
73 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 72 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
74 | SNDRV_PCM_INFO_MMAP_VALID | | 73 | SNDRV_PCM_INFO_MMAP_VALID |
75 | SNDRV_PCM_INFO_SYNC_START | ||
76 | ), | 74 | ), |
77 | .formats = ( | 75 | .formats = ( |
78 | SNDRV_PCM_FMTBIT_S16_LE | 76 | SNDRV_PCM_FMTBIT_S16_LE |
@@ -102,7 +100,6 @@ static int snd_cs5535audio_playback_open(struct snd_pcm_substream *substream) | |||
102 | runtime->hw = snd_cs5535audio_playback; | 100 | runtime->hw = snd_cs5535audio_playback; |
103 | cs5535au->playback_substream = substream; | 101 | cs5535au->playback_substream = substream; |
104 | runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_PLAYBACK]); | 102 | runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_PLAYBACK]); |
105 | snd_pcm_set_sync(substream); | ||
106 | if ((err = snd_pcm_hw_constraint_integer(runtime, | 103 | if ((err = snd_pcm_hw_constraint_integer(runtime, |
107 | SNDRV_PCM_HW_PARAM_PERIODS)) < 0) | 104 | SNDRV_PCM_HW_PARAM_PERIODS)) < 0) |
108 | return err; | 105 | return err; |
@@ -164,6 +161,7 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au, | |||
164 | jmpprd_addr = cpu_to_le32(lastdesc->addr + | 161 | jmpprd_addr = cpu_to_le32(lastdesc->addr + |
165 | (sizeof(struct cs5535audio_dma_desc)*periods)); | 162 | (sizeof(struct cs5535audio_dma_desc)*periods)); |
166 | 163 | ||
164 | dma->substream = substream; | ||
167 | dma->period_bytes = period_bytes; | 165 | dma->period_bytes = period_bytes; |
168 | dma->periods = periods; | 166 | dma->periods = periods; |
169 | spin_lock_irq(&cs5535au->reg_lock); | 167 | spin_lock_irq(&cs5535au->reg_lock); |
@@ -241,6 +239,7 @@ static void cs5535audio_clear_dma_packets(struct cs5535audio *cs5535au, | |||
241 | { | 239 | { |
242 | snd_dma_free_pages(&dma->desc_buf); | 240 | snd_dma_free_pages(&dma->desc_buf); |
243 | dma->desc_buf.area = NULL; | 241 | dma->desc_buf.area = NULL; |
242 | dma->substream = NULL; | ||
244 | } | 243 | } |
245 | 244 | ||
246 | static int snd_cs5535audio_hw_params(struct snd_pcm_substream *substream, | 245 | static int snd_cs5535audio_hw_params(struct snd_pcm_substream *substream, |
@@ -298,14 +297,12 @@ static int snd_cs5535audio_trigger(struct snd_pcm_substream *substream, int cmd) | |||
298 | break; | 297 | break; |
299 | case SNDRV_PCM_TRIGGER_RESUME: | 298 | case SNDRV_PCM_TRIGGER_RESUME: |
300 | dma->ops->enable_dma(cs5535au); | 299 | dma->ops->enable_dma(cs5535au); |
301 | dma->suspended = 0; | ||
302 | break; | 300 | break; |
303 | case SNDRV_PCM_TRIGGER_STOP: | 301 | case SNDRV_PCM_TRIGGER_STOP: |
304 | dma->ops->disable_dma(cs5535au); | 302 | dma->ops->disable_dma(cs5535au); |
305 | break; | 303 | break; |
306 | case SNDRV_PCM_TRIGGER_SUSPEND: | 304 | case SNDRV_PCM_TRIGGER_SUSPEND: |
307 | dma->ops->disable_dma(cs5535au); | 305 | dma->ops->disable_dma(cs5535au); |
308 | dma->suspended = 1; | ||
309 | break; | 306 | break; |
310 | default: | 307 | default: |
311 | snd_printk(KERN_ERR "unhandled trigger\n"); | 308 | snd_printk(KERN_ERR "unhandled trigger\n"); |
@@ -348,7 +345,6 @@ static int snd_cs5535audio_capture_open(struct snd_pcm_substream *substream) | |||
348 | runtime->hw = snd_cs5535audio_capture; | 345 | runtime->hw = snd_cs5535audio_capture; |
349 | cs5535au->capture_substream = substream; | 346 | cs5535au->capture_substream = substream; |
350 | runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_CAPTURE]); | 347 | runtime->private_data = &(cs5535au->dmas[CS5535AUDIO_DMA_CAPTURE]); |
351 | snd_pcm_set_sync(substream); | ||
352 | if ((err = snd_pcm_hw_constraint_integer(runtime, | 348 | if ((err = snd_pcm_hw_constraint_integer(runtime, |
353 | SNDRV_PCM_HW_PARAM_PERIODS)) < 0) | 349 | SNDRV_PCM_HW_PARAM_PERIODS)) < 0) |
354 | return err; | 350 | return err; |
diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c index 3e4d198a4502..838708f6d45e 100644 --- a/sound/pci/cs5535audio/cs5535audio_pm.c +++ b/sound/pci/cs5535audio/cs5535audio_pm.c | |||
@@ -64,18 +64,21 @@ int snd_cs5535audio_suspend(struct pci_dev *pci, pm_message_t state) | |||
64 | int i; | 64 | int i; |
65 | 65 | ||
66 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 66 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
67 | snd_pcm_suspend_all(cs5535au->pcm); | ||
68 | snd_ac97_suspend(cs5535au->ac97); | ||
67 | for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) { | 69 | for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) { |
68 | struct cs5535audio_dma *dma = &cs5535au->dmas[i]; | 70 | struct cs5535audio_dma *dma = &cs5535au->dmas[i]; |
69 | if (dma && dma->substream && !dma->suspended) | 71 | if (dma && dma->substream) |
70 | dma->saved_prd = dma->ops->read_prd(cs5535au); | 72 | dma->saved_prd = dma->ops->read_prd(cs5535au); |
71 | } | 73 | } |
72 | snd_pcm_suspend_all(cs5535au->pcm); | ||
73 | snd_ac97_suspend(cs5535au->ac97); | ||
74 | /* save important regs, then disable aclink in hw */ | 74 | /* save important regs, then disable aclink in hw */ |
75 | snd_cs5535audio_stop_hardware(cs5535au); | 75 | snd_cs5535audio_stop_hardware(cs5535au); |
76 | 76 | ||
77 | if (pci_save_state(pci)) { | ||
78 | printk(KERN_ERR "cs5535audio: pci_save_state failed!\n"); | ||
79 | return -EIO; | ||
80 | } | ||
77 | pci_disable_device(pci); | 81 | pci_disable_device(pci); |
78 | pci_save_state(pci); | ||
79 | pci_set_power_state(pci, pci_choose_state(pci, state)); | 82 | pci_set_power_state(pci, pci_choose_state(pci, state)); |
80 | return 0; | 83 | return 0; |
81 | } | 84 | } |
@@ -89,7 +92,12 @@ int snd_cs5535audio_resume(struct pci_dev *pci) | |||
89 | int i; | 92 | int i; |
90 | 93 | ||
91 | pci_set_power_state(pci, PCI_D0); | 94 | pci_set_power_state(pci, PCI_D0); |
92 | pci_restore_state(pci); | 95 | if (pci_restore_state(pci) < 0) { |
96 | printk(KERN_ERR "cs5535audio: pci_restore_state failed, " | ||
97 | "disabling device\n"); | ||
98 | snd_card_disconnect(card); | ||
99 | return -EIO; | ||
100 | } | ||
93 | if (pci_enable_device(pci) < 0) { | 101 | if (pci_enable_device(pci) < 0) { |
94 | printk(KERN_ERR "cs5535audio: pci_enable_device failed, " | 102 | printk(KERN_ERR "cs5535audio: pci_enable_device failed, " |
95 | "disabling device\n"); | 103 | "disabling device\n"); |
@@ -112,17 +120,17 @@ int snd_cs5535audio_resume(struct pci_dev *pci) | |||
112 | if (!timeout) | 120 | if (!timeout) |
113 | snd_printk(KERN_ERR "Failure getting AC Link ready\n"); | 121 | snd_printk(KERN_ERR "Failure getting AC Link ready\n"); |
114 | 122 | ||
115 | /* we depend on ac97 to perform the codec power up */ | ||
116 | snd_ac97_resume(cs5535au->ac97); | ||
117 | /* set up rate regs, dma. actual initiation is done in trig */ | 123 | /* set up rate regs, dma. actual initiation is done in trig */ |
118 | for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) { | 124 | for (i = 0; i < NUM_CS5535AUDIO_DMAS; i++) { |
119 | struct cs5535audio_dma *dma = &cs5535au->dmas[i]; | 125 | struct cs5535audio_dma *dma = &cs5535au->dmas[i]; |
120 | if (dma && dma->substream && dma->suspended) { | 126 | if (dma && dma->substream) { |
121 | dma->substream->ops->prepare(dma->substream); | 127 | dma->substream->ops->prepare(dma->substream); |
122 | dma->ops->setup_prd(cs5535au, dma->saved_prd); | 128 | dma->ops->setup_prd(cs5535au, dma->saved_prd); |
123 | } | 129 | } |
124 | } | 130 | } |
125 | 131 | ||
132 | /* we depend on ac97 to perform the codec power up */ | ||
133 | snd_ac97_resume(cs5535au->ac97); | ||
126 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 134 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
127 | 135 | ||
128 | return 0; | 136 | return 0; |