aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/cs5535audio
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/cs5535audio')
-rw-r--r--sound/pci/cs5535audio/Makefile7
-rw-r--r--sound/pci/cs5535audio/cs5535audio.c24
-rw-r--r--sound/pci/cs5535audio/cs5535audio.h42
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pcm.c10
-rw-r--r--sound/pci/cs5535audio/cs5535audio_pm.c26
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
5snd-cs5535audio-objs := cs5535audio.o cs5535audio_pcm.o 5snd-cs5535audio-y := cs5535audio.o cs5535audio_pcm.o
6 6snd-cs5535audio-$(CONFIG_PM) += cs5535audio_pm.o
7ifeq ($(CONFIG_PM),y)
8snd-cs5535audio-objs += cs5535audio_pm.o
9endif
10 7
11# Toplevel Module Dependency 8# Toplevel Module Dependency
12obj-$(CONFIG_SND_CS5535AUDIO) += snd-cs5535audio.o 9obj-$(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)
206static irqreturn_t snd_cs5535audio_interrupt(int irq, void *dev_id) 206static 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
246static int snd_cs5535audio_hw_params(struct snd_pcm_substream *substream, 245static 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;