1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Driver for Sound Core PDAudioCF soundcards
7 * Copyright (c) 2003 by Jaroslav Kysela <perex@perex.cz>
10 #include <linux/delay.h>
11 #include <sound/core.h>
12 #include <sound/asoundef.h>
13 #include "pdaudiocf.h"
17 * clear the SRAM contents
19 static int pdacf_pcm_clear_sram(struct snd_pdacf
*chip
)
21 int max_loop
= 64 * 1024;
23 while (inw(chip
->port
+ PDAUDIOCF_REG_RDP
) != inw(chip
->port
+ PDAUDIOCF_REG_WDP
)) {
26 inw(chip
->port
+ PDAUDIOCF_REG_MD
);
32 * pdacf_pcm_trigger - trigger callback for capture
34 static int pdacf_pcm_trigger(struct snd_pcm_substream
*subs
, int cmd
)
36 struct snd_pdacf
*chip
= snd_pcm_substream_chip(subs
);
37 struct snd_pcm_runtime
*runtime
= subs
->runtime
;
38 int inc
, ret
= 0, rate
;
39 unsigned short mask
, val
, tmp
;
41 if (chip
->chip_status
& PDAUDIOCF_STAT_IS_STALE
)
45 case SNDRV_PCM_TRIGGER_START
:
49 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE
:
50 case SNDRV_PCM_TRIGGER_RESUME
:
52 val
= PDAUDIOCF_RECORD
;
54 rate
= snd_ak4117_check_rate_and_errors(chip
->ak4117
, AK4117_CHECK_NO_STAT
|AK4117_CHECK_NO_RATE
);
56 case SNDRV_PCM_TRIGGER_STOP
:
57 case SNDRV_PCM_TRIGGER_PAUSE_PUSH
:
58 case SNDRV_PCM_TRIGGER_SUSPEND
:
59 mask
= PDAUDIOCF_RECORD
;
67 mutex_lock(&chip
->reg_lock
);
68 chip
->pcm_running
+= inc
;
69 tmp
= pdacf_reg_read(chip
, PDAUDIOCF_REG_SCR
);
70 if (chip
->pcm_running
) {
71 if ((chip
->ak4117
->rcs0
& AK4117_UNLCK
) || runtime
->rate
!= rate
) {
72 chip
->pcm_running
-= inc
;
79 pdacf_reg_write(chip
, PDAUDIOCF_REG_SCR
, tmp
);
81 mutex_unlock(&chip
->reg_lock
);
82 snd_ak4117_check_rate_and_errors(chip
->ak4117
, AK4117_CHECK_NO_RATE
);
87 * pdacf_pcm_prepare - prepare callback for playback and capture
89 static int pdacf_pcm_prepare(struct snd_pcm_substream
*subs
)
91 struct snd_pdacf
*chip
= snd_pcm_substream_chip(subs
);
92 struct snd_pcm_runtime
*runtime
= subs
->runtime
;
95 if (chip
->chip_status
& PDAUDIOCF_STAT_IS_STALE
)
98 chip
->pcm_channels
= runtime
->channels
;
100 chip
->pcm_little
= snd_pcm_format_little_endian(runtime
->format
) > 0;
101 #ifdef SNDRV_LITTLE_ENDIAN
102 chip
->pcm_swab
= snd_pcm_format_big_endian(runtime
->format
) > 0;
104 chip
->pcm_swab
= chip
->pcm_little
;
107 if (snd_pcm_format_unsigned(runtime
->format
))
108 chip
->pcm_xor
= 0x80008000;
110 if (pdacf_pcm_clear_sram(chip
) < 0)
113 val
= nval
= pdacf_reg_read(chip
, PDAUDIOCF_REG_SCR
);
114 nval
&= ~(PDAUDIOCF_DATAFMT0
|PDAUDIOCF_DATAFMT1
);
115 switch (runtime
->format
) {
116 case SNDRV_PCM_FORMAT_S16_LE
:
117 case SNDRV_PCM_FORMAT_S16_BE
:
119 default: /* 24-bit */
120 nval
|= PDAUDIOCF_DATAFMT0
| PDAUDIOCF_DATAFMT1
;
124 chip
->pcm_sample
= 4;
125 switch (runtime
->format
) {
126 case SNDRV_PCM_FORMAT_S16_LE
:
127 case SNDRV_PCM_FORMAT_S16_BE
:
128 aval
= AK4117_DIF_16R
;
130 chip
->pcm_sample
= 2;
132 case SNDRV_PCM_FORMAT_S24_3LE
:
133 case SNDRV_PCM_FORMAT_S24_3BE
:
134 chip
->pcm_sample
= 3;
136 default: /* 24-bit */
137 aval
= AK4117_DIF_24R
;
139 chip
->pcm_xor
&= 0xffff0000;
144 snd_ak4117_reg_write(chip
->ak4117
, AK4117_REG_IO
, AK4117_DIF2
|AK4117_DIF1
|AK4117_DIF0
, aval
);
145 pdacf_reg_write(chip
, PDAUDIOCF_REG_SCR
, nval
);
148 val
= pdacf_reg_read(chip
, PDAUDIOCF_REG_IER
);
149 val
&= ~(PDAUDIOCF_IRQLVLEN1
);
150 val
|= PDAUDIOCF_IRQLVLEN0
;
151 pdacf_reg_write(chip
, PDAUDIOCF_REG_IER
, val
);
153 chip
->pcm_size
= runtime
->buffer_size
;
154 chip
->pcm_period
= runtime
->period_size
;
155 chip
->pcm_area
= runtime
->dma_area
;
162 * capture hw information
165 static const struct snd_pcm_hardware pdacf_pcm_capture_hw
= {
166 .info
= (SNDRV_PCM_INFO_MMAP
| SNDRV_PCM_INFO_INTERLEAVED
|
167 SNDRV_PCM_INFO_PAUSE
| SNDRV_PCM_INFO_RESUME
|
168 SNDRV_PCM_INFO_MMAP_VALID
|
169 SNDRV_PCM_INFO_BATCH
),
170 .formats
= SNDRV_PCM_FMTBIT_S16_LE
| SNDRV_PCM_FMTBIT_S16_BE
|
171 SNDRV_PCM_FMTBIT_S24_3LE
| SNDRV_PCM_FMTBIT_S24_3BE
|
172 SNDRV_PCM_FMTBIT_S32_LE
| SNDRV_PCM_FMTBIT_S32_BE
,
173 .rates
= SNDRV_PCM_RATE_32000
|
174 SNDRV_PCM_RATE_44100
|
175 SNDRV_PCM_RATE_48000
|
176 SNDRV_PCM_RATE_88200
|
177 SNDRV_PCM_RATE_96000
|
178 SNDRV_PCM_RATE_176400
|
179 SNDRV_PCM_RATE_192000
,
184 .buffer_bytes_max
= (512*1024),
185 .period_bytes_min
= 8*1024,
186 .period_bytes_max
= (64*1024),
194 * pdacf_pcm_capture_open - open callback for capture
196 static int pdacf_pcm_capture_open(struct snd_pcm_substream
*subs
)
198 struct snd_pcm_runtime
*runtime
= subs
->runtime
;
199 struct snd_pdacf
*chip
= snd_pcm_substream_chip(subs
);
201 if (chip
->chip_status
& PDAUDIOCF_STAT_IS_STALE
)
204 runtime
->hw
= pdacf_pcm_capture_hw
;
205 runtime
->private_data
= chip
;
206 chip
->pcm_substream
= subs
;
212 * pdacf_pcm_capture_close - close callback for capture
214 static int pdacf_pcm_capture_close(struct snd_pcm_substream
*subs
)
216 struct snd_pdacf
*chip
= snd_pcm_substream_chip(subs
);
220 pdacf_reinit(chip
, 0);
221 chip
->pcm_substream
= NULL
;
227 * pdacf_pcm_capture_pointer - pointer callback for capture
229 static snd_pcm_uframes_t
pdacf_pcm_capture_pointer(struct snd_pcm_substream
*subs
)
231 struct snd_pdacf
*chip
= snd_pcm_substream_chip(subs
);
232 return chip
->pcm_hwptr
;
236 * operators for PCM capture
238 static const struct snd_pcm_ops pdacf_pcm_capture_ops
= {
239 .open
= pdacf_pcm_capture_open
,
240 .close
= pdacf_pcm_capture_close
,
241 .prepare
= pdacf_pcm_prepare
,
242 .trigger
= pdacf_pcm_trigger
,
243 .pointer
= pdacf_pcm_capture_pointer
,
248 * snd_pdacf_pcm_new - create and initialize a pcm
250 int snd_pdacf_pcm_new(struct snd_pdacf
*chip
)
255 err
= snd_pcm_new(chip
->card
, "PDAudioCF", 0, 0, 1, &pcm
);
259 snd_pcm_set_ops(pcm
, SNDRV_PCM_STREAM_CAPTURE
, &pdacf_pcm_capture_ops
);
260 snd_pcm_set_managed_buffer_all(pcm
, SNDRV_DMA_TYPE_VMALLOC
,
261 snd_dma_continuous_data(GFP_KERNEL
| GFP_DMA32
),
264 pcm
->private_data
= chip
;
266 pcm
->nonatomic
= true;
267 strcpy(pcm
->name
, chip
->card
->shortname
);
270 err
= snd_ak4117_build(chip
->ak4117
, pcm
->streams
[SNDRV_PCM_STREAM_CAPTURE
].substream
);