31 #include <linux/slab.h>
33 #include <linux/module.h>
44 MODULE_DESCRIPTION(
"Routines for control of CS4231(A)/CS4232/InterWave & compatible chips");
48 #define SNDRV_DEBUG_MCE
55 static unsigned char freq_bits[14] = {
72 static unsigned int rates[14] = {
73 5510, 6620, 8000, 9600, 11025, 16000, 18900, 22050,
74 27042, 32000, 33075, 37800, 44100, 48000
86 &hw_constraints_rates);
89 static unsigned char snd_wss_original_image[32] =
125 static unsigned char snd_opti93x_original_image[32] =
172 return inb(chip->
port + offset);
185 static void snd_wss_dout(
struct snd_wss *chip,
unsigned char reg,
202 #ifdef CONFIG_SND_DEBUG
205 "- reg = 0x%x, value = 0x%x\n", reg, value);
219 #ifdef CONFIG_SND_DEBUG
222 "- reg = 0x%x\n", reg);
265 static void snd_wss_debug(
struct snd_wss *chip)
268 "CS4231 REGS: INDEX = 0x%02x "
269 " STATUS = 0x%02x\n",
270 wss_inb(chip,
CS4231P(REGSEL)),
273 " 0x00: left input = 0x%02x "
274 " 0x10: alt 1 (CFIG 2) = 0x%02x\n",
278 " 0x01: right input = 0x%02x "
279 " 0x11: alt 2 (CFIG 3) = 0x%02x\n",
283 " 0x02: GF1 left input = 0x%02x "
284 " 0x12: left line in = 0x%02x\n",
288 " 0x03: GF1 right input = 0x%02x "
289 " 0x13: right line in = 0x%02x\n",
293 " 0x04: CD left input = 0x%02x "
294 " 0x14: timer low = 0x%02x\n",
298 " 0x05: CD right input = 0x%02x "
299 " 0x15: timer high = 0x%02x\n",
303 " 0x06: left output = 0x%02x "
304 " 0x16: left MIC (PnP) = 0x%02x\n",
308 " 0x07: right output = 0x%02x "
309 " 0x17: right MIC (PnP) = 0x%02x\n",
313 " 0x08: playback format = 0x%02x "
314 " 0x18: IRQ status = 0x%02x\n",
318 " 0x09: iface (CFIG 1) = 0x%02x "
319 " 0x19: left line out = 0x%02x\n",
323 " 0x0a: pin control = 0x%02x "
324 " 0x1a: mono control = 0x%02x\n",
328 " 0x0b: init & status = 0x%02x "
329 " 0x1b: right line out = 0x%02x\n",
333 " 0x0c: revision & mode = 0x%02x "
334 " 0x1c: record format = 0x%02x\n",
338 " 0x0d: loopback = 0x%02x "
339 " 0x1d: var freq (PnP) = 0x%02x\n",
343 " 0x0e: ply upr count = 0x%02x "
344 " 0x1e: ply lwr count = 0x%02x\n",
348 " 0x0f: rec upr count = 0x%02x "
349 " 0x1f: rec lwr count = 0x%02x\n",
360 static void snd_wss_busy_wait(
struct snd_wss *chip)
365 for (timeout = 5; timeout > 0; timeout--)
366 wss_inb(chip,
CS4231P(REGSEL));
368 for (timeout = 25000;
380 #ifdef CONFIG_SND_DEBUG
383 "mce_up - auto calibration time out (0)\n");
387 timeout = wss_inb(chip,
CS4231P(REGSEL));
390 "serious init problem - codec still busy\n",
393 wss_outb(chip,
CS4231P(REGSEL),
394 chip->
mce_bit | (timeout & 0x1f));
395 spin_unlock_irqrestore(&chip->
reg_lock, flags);
402 unsigned long end_time;
406 snd_wss_busy_wait(chip);
408 #ifdef CONFIG_SND_DEBUG
411 "auto calibration time out (0)\n",
416 timeout = wss_inb(chip,
CS4231P(REGSEL));
417 wss_outb(chip,
CS4231P(REGSEL), chip->
mce_bit | (timeout & 0x1f));
418 spin_unlock_irqrestore(&chip->
reg_lock, flags);
421 "serious init problem - codec still busy\n",
442 "auto calibration time out (2)\n");
452 while (wss_inb(chip,
CS4231P(REGSEL)) & CS4231_INIT) {
465 static unsigned int snd_wss_get_count(
unsigned char format,
unsigned int size)
467 switch (format & 0xe0) {
504 snd_pcm_trigger_done(s, substream);
507 snd_pcm_trigger_done(s, substream);
532 static unsigned char snd_wss_get_rate(
unsigned int rate)
537 if (rate == rates[i])
543 static unsigned char snd_wss_get_format(
struct snd_wss *chip,
547 unsigned char rformat;
565 static void snd_wss_calibrate_mute(
struct snd_wss *chip,
int mute)
569 mute = mute ? 0x80 : 0;
572 spin_unlock_irqrestore(&chip->
reg_lock, flags);
622 spin_unlock_irqrestore(&chip->
reg_lock, flags);
625 static void snd_wss_playback_format(
struct snd_wss *chip,
647 spin_unlock_irqrestore(&chip->
reg_lock, flags);
665 spin_unlock_irqrestore(&chip->
reg_lock, flags);
672 pdfr = (pdfr & 0xf0) |
678 spin_unlock_irqrestore(&chip->
reg_lock, flags);
686 static void snd_wss_capture_format(
struct snd_wss *chip,
707 spin_unlock_irqrestore(&chip->
reg_lock, flags);
725 spin_unlock_irqrestore(&chip->
reg_lock, flags);
738 spin_unlock_irqrestore(&chip->
reg_lock, flags);
747 spin_unlock_irqrestore(&chip->
reg_lock, flags);
757 static unsigned long snd_wss_timer_resolution(
struct snd_timer *
timer)
766 static int snd_wss_timer_start(
struct snd_timer *timer)
784 CS4231_TIMER_ENABLE);
786 spin_unlock_irqrestore(&chip->
reg_lock, flags);
790 static int snd_wss_timer_stop(
struct snd_timer *timer)
798 spin_unlock_irqrestore(&chip->
reg_lock, flags);
802 static void snd_wss_init(
struct snd_wss *chip)
806 snd_wss_calibrate_mute(chip, 1);
809 #ifdef SNDRV_DEBUG_MCE
821 spin_unlock_irqrestore(&chip->
reg_lock, flags);
824 #ifdef SNDRV_DEBUG_MCE
834 spin_unlock_irqrestore(&chip->
reg_lock, flags);
837 #ifdef SNDRV_DEBUG_MCE
845 spin_unlock_irqrestore(&chip->
reg_lock, flags);
851 spin_unlock_irqrestore(&chip->
reg_lock, flags);
854 #ifdef SNDRV_DEBUG_MCE
863 spin_unlock_irqrestore(&chip->
reg_lock, flags);
865 snd_wss_calibrate_mute(chip, 0);
867 #ifdef SNDRV_DEBUG_MCE
872 static int snd_wss_open(
struct snd_wss *chip,
unsigned int mode)
877 if ((chip->
mode & mode) ||
907 spin_unlock_irqrestore(&chip->
reg_lock, flags);
914 static void snd_wss_close(
struct snd_wss *chip,
unsigned int mode)
937 spin_unlock_irqrestore(&chip->
reg_lock, flags);
944 spin_unlock_irqrestore(&chip->
reg_lock, flags);
954 spin_unlock_irqrestore(&chip->
reg_lock, flags);
964 static int snd_wss_timer_open(
struct snd_timer *timer)
971 static int snd_wss_timer_close(
struct snd_timer *timer)
983 .open = snd_wss_timer_open,
984 .close = snd_wss_timer_close,
985 .c_resolution = snd_wss_timer_resolution,
986 .start = snd_wss_timer_start,
987 .stop = snd_wss_timer_stop,
998 unsigned char new_pdfr;
1003 new_pdfr = snd_wss_get_format(chip,
params_format(hw_params),
1019 unsigned long flags;
1020 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1021 unsigned int count = snd_pcm_lib_period_bytes(substream);
1030 spin_unlock_irqrestore(&chip->
reg_lock, flags);
1032 snd_wss_debug(chip);
1041 unsigned char new_cdfr;
1046 new_cdfr = snd_wss_get_format(chip,
params_format(hw_params),
1062 unsigned long flags;
1063 unsigned int size = snd_pcm_lib_buffer_bytes(substream);
1064 unsigned int count = snd_pcm_lib_period_bytes(substream);
1080 (
unsigned char) (count >> 8));
1084 (
unsigned char) (count >> 8));
1086 spin_unlock_irqrestore(&chip->
reg_lock, flags);
1092 unsigned long flags;
1097 spin_unlock_irqrestore(&chip->
reg_lock, flags);
1098 if (res & (0x08 | 0x02))
1162 return bytes_to_frames(substream->
runtime, ptr);
1173 return bytes_to_frames(substream->
runtime, ptr);
1180 static int snd_ad1848_probe(
struct snd_wss *chip)
1183 unsigned long flags;
1235 for (i = 0; i < 16; i++) {
1238 if ((r & 0xf) != 0xa)
1258 spin_unlock_irqrestore(&chip->
reg_lock, flags);
1262 static int snd_wss_probe(
struct snd_wss *chip)
1264 unsigned long flags;
1269 id = snd_ad1848_probe(chip);
1275 for (i = 0; i < 50; i++) {
1277 if (wss_inb(chip,
CS4231P(REGSEL)) & CS4231_INIT)
1284 spin_unlock_irqrestore(&chip->
reg_lock, flags);
1294 snd_printdd(
"CS4231: VERSION (I25) = 0x%x\n", rev);
1302 }
else if (rev == 0xa0) {
1304 }
else if (rev == 0xa2) {
1306 }
else if (rev == 0xb2) {
1308 }
else if (rev == 0x83) {
1310 }
else if (rev == 0x03) {
1314 "unknown CS chip with version 0x%x\n", rev);
1322 spin_unlock_irqrestore(&chip->
reg_lock, flags);
1354 ptr = (
unsigned char *) &chip->
image;
1358 for (i = 0; i < regnum; i++)
1360 spin_unlock_irqrestore(&chip->
reg_lock, flags);
1373 snd_printdd(
"CS4231: ext version; rev = 0x%x, id = 0x%x\n", rev,
id);
1374 if ((
id & 0x1f) == 0x1d) {
1383 "unknown CS4235 chip "
1384 "(enhanced version = 0x%x)\n",
1387 }
else if ((
id & 0x1f) == 0x0b) {
1397 "unknown CS4236 chip "
1398 "(enhanced version = 0x%x)\n",
1401 }
else if ((
id & 0x1f) == 0x08) {
1411 "unknown CS4237B chip "
1412 "(enhanced version = 0x%x)\n",
1415 }
else if ((
id & 0x1f) == 0x09) {
1424 "unknown CS4238B chip "
1425 "(enhanced version = 0x%x)\n",
1428 }
else if ((
id & 0x1f) == 0x1e) {
1437 "unknown CS4239 chip "
1438 "(enhanced version = 0x%x)\n",
1443 "unknown CS4236/CS423xB chip "
1444 "(enhanced version = 0x%x)\n",
id);
1467 .buffer_bytes_max = (128*1024),
1471 .periods_max = 1024,
1488 .buffer_bytes_max = (128*1024),
1492 .periods_max = 1024,
1506 runtime->
hw = snd_wss_playback;
1522 snd_pcm_limit_isa_dma_size(chip->
dma1, &runtime->
hw.buffer_bytes_max);
1523 snd_pcm_limit_isa_dma_size(chip->
dma1, &runtime->
hw.period_bytes_max);
1549 runtime->
hw = snd_wss_capture;
1563 snd_pcm_limit_isa_dma_size(chip->
dma2, &runtime->
hw.buffer_bytes_max);
1564 snd_pcm_limit_isa_dma_size(chip->
dma2, &runtime->
hw.period_bytes_max);
1602 static void snd_wss_thinkpad_twiddle(
struct snd_wss *chip,
int on)
1625 static void snd_wss_suspend(
struct snd_wss *chip)
1628 unsigned long flags;
1630 snd_pcm_suspend_all(chip->
pcm);
1632 for (reg = 0; reg < 32; reg++)
1634 spin_unlock_irqrestore(&chip->
reg_lock, flags);
1636 snd_wss_thinkpad_twiddle(chip, 0);
1640 static void snd_wss_resume(
struct snd_wss *chip)
1643 unsigned long flags;
1647 snd_wss_thinkpad_twiddle(chip, 1);
1650 for (reg = 0; reg < 32; reg++) {
1663 spin_unlock_irqrestore(&chip->
reg_lock, flags);
1671 snd_wss_busy_wait(chip);
1674 timeout = wss_inb(chip,
CS4231P(REGSEL));
1675 wss_outb(chip,
CS4231P(REGSEL), chip->
mce_bit | (timeout & 0x1f));
1676 spin_unlock_irqrestore(&chip->
reg_lock, flags);
1677 if (timeout == 0x80)
1679 "- codec still busy\n", chip->
port);
1684 snd_wss_busy_wait(chip);
1689 static int snd_wss_free(
struct snd_wss *chip)
1693 if (chip->
irq >= 0) {
1716 return snd_wss_free(chip);
1743 return "AMD InterWave";
1745 return chip->
card->shortname;
1757 return "CMI8330/C3D";
1765 unsigned short hardware,
1787 sizeof(snd_opti93x_original_image));
1790 sizeof(snd_wss_original_image));
1802 unsigned long cport,
1804 unsigned short hardware,
1805 unsigned short hwshare,
1814 err = snd_wss_new(card, hardware, hwshare, &chip);
1829 if ((
long)cport >= 0) {
1833 "wss: can't grab control port 0x%lx\n", cport);
1841 "WSS", (
void *) chip)) {
1859 if (dma1 == dma2 || dma2 < 0) {
1868 snd_wss_thinkpad_twiddle(chip, 1);
1872 if (snd_wss_probe(chip) < 0) {
1882 "not accessible\n");
1895 chip->suspend = snd_wss_suspend;
1896 chip->resume = snd_wss_resume;
1904 static struct snd_pcm_ops snd_wss_playback_ops = {
1905 .open = snd_wss_playback_open,
1906 .close = snd_wss_playback_close,
1908 .hw_params = snd_wss_playback_hw_params,
1909 .hw_free = snd_wss_playback_hw_free,
1910 .prepare = snd_wss_playback_prepare,
1911 .trigger = snd_wss_trigger,
1912 .pointer = snd_wss_playback_pointer,
1916 .open = snd_wss_capture_open,
1917 .close = snd_wss_capture_close,
1919 .hw_params = snd_wss_capture_hw_params,
1920 .hw_free = snd_wss_capture_hw_free,
1921 .prepare = snd_wss_capture_prepare,
1922 .trigger = snd_wss_trigger,
1923 .pointer = snd_wss_capture_pointer,
1949 64*1024, chip->
dma1 > 3 || chip->
dma2 > 3 ? 128*1024 : 64*1024);
1958 static void snd_wss_timer_free(
struct snd_timer *timer)
1981 timer->
hw = snd_wss_timer_table;
1993 static int snd_wss_info_mux(
struct snd_kcontrol *kcontrol,
1996 static char *texts[4] = {
1997 "Line",
"Aux",
"Mic",
"Mix"
1999 static char *opl3sa_texts[4] = {
2000 "Line",
"CD",
"Mic",
"Mix"
2002 static char *gusmax_texts[4] = {
2003 "Line",
"Synth",
"Mic",
"Mix"
2005 char **ptexts = texts;
2016 ptexts = gusmax_texts;
2019 ptexts = gusmax_texts;
2023 ptexts = opl3sa_texts;
2030 static int snd_wss_get_mux(
struct snd_kcontrol *kcontrol,
2034 unsigned long flags;
2039 spin_unlock_irqrestore(&chip->
reg_lock, flags);
2043 static int snd_wss_put_mux(
struct snd_kcontrol *kcontrol,
2047 unsigned long flags;
2051 if (ucontrol->
value.enumerated.item[0] > 3 ||
2052 ucontrol->
value.enumerated.item[1] > 3)
2054 left = ucontrol->
value.enumerated.item[0] << 6;
2055 right = ucontrol->
value.enumerated.item[1] << 6;
2063 spin_unlock_irqrestore(&chip->
reg_lock, flags);
2084 unsigned long flags;
2091 ucontrol->
value.integer.value[0] = (chip->
image[
reg] >> shift) & mask;
2092 spin_unlock_irqrestore(&chip->
reg_lock, flags);
2094 ucontrol->
value.integer.value[0] = mask - ucontrol->
value.integer.value[0];
2103 unsigned long flags;
2111 val = (ucontrol->
value.integer.value[0] &
mask);
2116 val = (chip->
image[
reg] & ~(mask << shift)) |
val;
2119 spin_unlock_irqrestore(&chip->
reg_lock, flags);
2141 unsigned long flags;
2150 ucontrol->
value.integer.value[0] = (chip->
image[left_reg] >> shift_left) & mask;
2152 spin_unlock_irqrestore(&chip->
reg_lock, flags);
2154 ucontrol->
value.integer.value[0] = mask - ucontrol->
value.integer.value[0];
2155 ucontrol->
value.integer.value[1] = mask - ucontrol->
value.integer.value[1];
2165 unsigned long flags;
2173 unsigned short val1, val2;
2175 val1 = ucontrol->
value.integer.value[0] &
mask;
2176 val2 = ucontrol->
value.integer.value[1] &
mask;
2181 val1 <<= shift_left;
2184 if (left_reg != right_reg) {
2185 val1 = (chip->
image[left_reg] & ~(mask << shift_left)) | val1;
2187 change = val1 != chip->
image[left_reg] ||
2188 val2 != chip->
image[right_reg];
2192 mask = (mask << shift_left) | (mask << shift_right);
2193 val1 = (chip->
image[left_reg] & ~mask) | val1 | val2;
2194 change = val1 != chip->
image[left_reg];
2197 spin_unlock_irqrestore(&chip->
reg_lock, flags);
2217 db_scale_5bit_12db_max),
2222 db_scale_5bit_12db_max),
2224 0, 0, 15, 0, db_scale_rec_gain),
2227 .name =
"Capture Source",
2228 .info = snd_wss_info_mux,
2229 .get = snd_wss_get_mux,
2230 .put = snd_wss_put_mux,
2242 db_scale_5bit_12db_max),
2275 for (idx = 0; idx <
count; idx++) {
2289 &snd_wss_playback_ops : &snd_wss_capture_ops;
2297 static int __init alsa_wss_init(
void)
2302 static void __exit alsa_wss_exit(
void)