| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2004 James Courtier-Dutton <James@superbug.demon.co.uk> |
|---|
| 3 | 4 | * Driver CA0106 chips. e.g. Sound Blaster Audigy LS and Live 24bit |
|---|
| .. | .. |
|---|
| 119 | 120 | * |
|---|
| 120 | 121 | * This code was initially based on code from ALSA's emu10k1x.c which is: |
|---|
| 121 | 122 | * Copyright (c) by Francisco Moraes <fmoraes@nc.rr.com> |
|---|
| 122 | | - * |
|---|
| 123 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 124 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 125 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 126 | | - * (at your option) any later version. |
|---|
| 127 | | - * |
|---|
| 128 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 129 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 130 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 131 | | - * GNU General Public License for more details. |
|---|
| 132 | | - * |
|---|
| 133 | | - * You should have received a copy of the GNU General Public License |
|---|
| 134 | | - * along with this program; if not, write to the Free Software |
|---|
| 135 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 136 | | - * |
|---|
| 137 | 123 | */ |
|---|
| 138 | 124 | #include <linux/delay.h> |
|---|
| 139 | 125 | #include <linux/init.h> |
|---|
| .. | .. |
|---|
| 170 | 156 | |
|---|
| 171 | 157 | #include "ca0106.h" |
|---|
| 172 | 158 | |
|---|
| 173 | | -static struct snd_ca0106_details ca0106_chip_details[] = { |
|---|
| 159 | +static const struct snd_ca0106_details ca0106_chip_details[] = { |
|---|
| 174 | 160 | /* Sound Blaster X-Fi Extreme Audio. This does not have an AC97. 53SB079000000 */ |
|---|
| 175 | 161 | /* It is really just a normal SB Live 24bit. */ |
|---|
| 176 | 162 | /* Tested: |
|---|
| .. | .. |
|---|
| 517 | 503 | } |
|---|
| 518 | 504 | |
|---|
| 519 | 505 | static int snd_ca0106_channel_dac(struct snd_ca0106 *chip, |
|---|
| 520 | | - struct snd_ca0106_details *details, |
|---|
| 506 | + const struct snd_ca0106_details *details, |
|---|
| 521 | 507 | int channel_id) |
|---|
| 522 | 508 | { |
|---|
| 523 | 509 | switch (channel_id) { |
|---|
| .. | .. |
|---|
| 720 | 706 | static int snd_ca0106_pcm_open_3_capture(struct snd_pcm_substream *substream) |
|---|
| 721 | 707 | { |
|---|
| 722 | 708 | return snd_ca0106_pcm_open_capture_channel(substream, 3); |
|---|
| 723 | | -} |
|---|
| 724 | | - |
|---|
| 725 | | -/* hw_params callback */ |
|---|
| 726 | | -static int snd_ca0106_pcm_hw_params_playback(struct snd_pcm_substream *substream, |
|---|
| 727 | | - struct snd_pcm_hw_params *hw_params) |
|---|
| 728 | | -{ |
|---|
| 729 | | - return snd_pcm_lib_malloc_pages(substream, |
|---|
| 730 | | - params_buffer_bytes(hw_params)); |
|---|
| 731 | | -} |
|---|
| 732 | | - |
|---|
| 733 | | -/* hw_free callback */ |
|---|
| 734 | | -static int snd_ca0106_pcm_hw_free_playback(struct snd_pcm_substream *substream) |
|---|
| 735 | | -{ |
|---|
| 736 | | - return snd_pcm_lib_free_pages(substream); |
|---|
| 737 | | -} |
|---|
| 738 | | - |
|---|
| 739 | | -/* hw_params callback */ |
|---|
| 740 | | -static int snd_ca0106_pcm_hw_params_capture(struct snd_pcm_substream *substream, |
|---|
| 741 | | - struct snd_pcm_hw_params *hw_params) |
|---|
| 742 | | -{ |
|---|
| 743 | | - return snd_pcm_lib_malloc_pages(substream, |
|---|
| 744 | | - params_buffer_bytes(hw_params)); |
|---|
| 745 | | -} |
|---|
| 746 | | - |
|---|
| 747 | | -/* hw_free callback */ |
|---|
| 748 | | -static int snd_ca0106_pcm_hw_free_capture(struct snd_pcm_substream *substream) |
|---|
| 749 | | -{ |
|---|
| 750 | | - return snd_pcm_lib_free_pages(substream); |
|---|
| 751 | 709 | } |
|---|
| 752 | 710 | |
|---|
| 753 | 711 | /* prepare playback callback */ |
|---|
| .. | .. |
|---|
| 1111 | 1069 | static const struct snd_pcm_ops snd_ca0106_playback_front_ops = { |
|---|
| 1112 | 1070 | .open = snd_ca0106_pcm_open_playback_front, |
|---|
| 1113 | 1071 | .close = snd_ca0106_pcm_close_playback, |
|---|
| 1114 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1115 | | - .hw_params = snd_ca0106_pcm_hw_params_playback, |
|---|
| 1116 | | - .hw_free = snd_ca0106_pcm_hw_free_playback, |
|---|
| 1117 | 1072 | .prepare = snd_ca0106_pcm_prepare_playback, |
|---|
| 1118 | 1073 | .trigger = snd_ca0106_pcm_trigger_playback, |
|---|
| 1119 | 1074 | .pointer = snd_ca0106_pcm_pointer_playback, |
|---|
| .. | .. |
|---|
| 1122 | 1077 | static const struct snd_pcm_ops snd_ca0106_capture_0_ops = { |
|---|
| 1123 | 1078 | .open = snd_ca0106_pcm_open_0_capture, |
|---|
| 1124 | 1079 | .close = snd_ca0106_pcm_close_capture, |
|---|
| 1125 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1126 | | - .hw_params = snd_ca0106_pcm_hw_params_capture, |
|---|
| 1127 | | - .hw_free = snd_ca0106_pcm_hw_free_capture, |
|---|
| 1128 | 1080 | .prepare = snd_ca0106_pcm_prepare_capture, |
|---|
| 1129 | 1081 | .trigger = snd_ca0106_pcm_trigger_capture, |
|---|
| 1130 | 1082 | .pointer = snd_ca0106_pcm_pointer_capture, |
|---|
| .. | .. |
|---|
| 1133 | 1085 | static const struct snd_pcm_ops snd_ca0106_capture_1_ops = { |
|---|
| 1134 | 1086 | .open = snd_ca0106_pcm_open_1_capture, |
|---|
| 1135 | 1087 | .close = snd_ca0106_pcm_close_capture, |
|---|
| 1136 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1137 | | - .hw_params = snd_ca0106_pcm_hw_params_capture, |
|---|
| 1138 | | - .hw_free = snd_ca0106_pcm_hw_free_capture, |
|---|
| 1139 | 1088 | .prepare = snd_ca0106_pcm_prepare_capture, |
|---|
| 1140 | 1089 | .trigger = snd_ca0106_pcm_trigger_capture, |
|---|
| 1141 | 1090 | .pointer = snd_ca0106_pcm_pointer_capture, |
|---|
| .. | .. |
|---|
| 1144 | 1093 | static const struct snd_pcm_ops snd_ca0106_capture_2_ops = { |
|---|
| 1145 | 1094 | .open = snd_ca0106_pcm_open_2_capture, |
|---|
| 1146 | 1095 | .close = snd_ca0106_pcm_close_capture, |
|---|
| 1147 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1148 | | - .hw_params = snd_ca0106_pcm_hw_params_capture, |
|---|
| 1149 | | - .hw_free = snd_ca0106_pcm_hw_free_capture, |
|---|
| 1150 | 1096 | .prepare = snd_ca0106_pcm_prepare_capture, |
|---|
| 1151 | 1097 | .trigger = snd_ca0106_pcm_trigger_capture, |
|---|
| 1152 | 1098 | .pointer = snd_ca0106_pcm_pointer_capture, |
|---|
| .. | .. |
|---|
| 1155 | 1101 | static const struct snd_pcm_ops snd_ca0106_capture_3_ops = { |
|---|
| 1156 | 1102 | .open = snd_ca0106_pcm_open_3_capture, |
|---|
| 1157 | 1103 | .close = snd_ca0106_pcm_close_capture, |
|---|
| 1158 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1159 | | - .hw_params = snd_ca0106_pcm_hw_params_capture, |
|---|
| 1160 | | - .hw_free = snd_ca0106_pcm_hw_free_capture, |
|---|
| 1161 | 1104 | .prepare = snd_ca0106_pcm_prepare_capture, |
|---|
| 1162 | 1105 | .trigger = snd_ca0106_pcm_trigger_capture, |
|---|
| 1163 | 1106 | .pointer = snd_ca0106_pcm_pointer_capture, |
|---|
| .. | .. |
|---|
| 1166 | 1109 | static const struct snd_pcm_ops snd_ca0106_playback_center_lfe_ops = { |
|---|
| 1167 | 1110 | .open = snd_ca0106_pcm_open_playback_center_lfe, |
|---|
| 1168 | 1111 | .close = snd_ca0106_pcm_close_playback, |
|---|
| 1169 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1170 | | - .hw_params = snd_ca0106_pcm_hw_params_playback, |
|---|
| 1171 | | - .hw_free = snd_ca0106_pcm_hw_free_playback, |
|---|
| 1172 | 1112 | .prepare = snd_ca0106_pcm_prepare_playback, |
|---|
| 1173 | 1113 | .trigger = snd_ca0106_pcm_trigger_playback, |
|---|
| 1174 | 1114 | .pointer = snd_ca0106_pcm_pointer_playback, |
|---|
| .. | .. |
|---|
| 1177 | 1117 | static const struct snd_pcm_ops snd_ca0106_playback_unknown_ops = { |
|---|
| 1178 | 1118 | .open = snd_ca0106_pcm_open_playback_unknown, |
|---|
| 1179 | 1119 | .close = snd_ca0106_pcm_close_playback, |
|---|
| 1180 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1181 | | - .hw_params = snd_ca0106_pcm_hw_params_playback, |
|---|
| 1182 | | - .hw_free = snd_ca0106_pcm_hw_free_playback, |
|---|
| 1183 | 1120 | .prepare = snd_ca0106_pcm_prepare_playback, |
|---|
| 1184 | 1121 | .trigger = snd_ca0106_pcm_trigger_playback, |
|---|
| 1185 | 1122 | .pointer = snd_ca0106_pcm_pointer_playback, |
|---|
| .. | .. |
|---|
| 1188 | 1125 | static const struct snd_pcm_ops snd_ca0106_playback_rear_ops = { |
|---|
| 1189 | 1126 | .open = snd_ca0106_pcm_open_playback_rear, |
|---|
| 1190 | 1127 | .close = snd_ca0106_pcm_close_playback, |
|---|
| 1191 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 1192 | | - .hw_params = snd_ca0106_pcm_hw_params_playback, |
|---|
| 1193 | | - .hw_free = snd_ca0106_pcm_hw_free_playback, |
|---|
| 1194 | 1128 | .prepare = snd_ca0106_pcm_prepare_playback, |
|---|
| 1195 | 1129 | .trigger = snd_ca0106_pcm_trigger_playback, |
|---|
| 1196 | 1130 | .pointer = snd_ca0106_pcm_pointer_playback, |
|---|
| .. | .. |
|---|
| 1228 | 1162 | struct snd_ac97_bus *pbus; |
|---|
| 1229 | 1163 | struct snd_ac97_template ac97; |
|---|
| 1230 | 1164 | int err; |
|---|
| 1231 | | - static struct snd_ac97_bus_ops ops = { |
|---|
| 1165 | + static const struct snd_ac97_bus_ops ops = { |
|---|
| 1232 | 1166 | .write = snd_ca0106_ac97_write, |
|---|
| 1233 | 1167 | .read = snd_ca0106_ac97_read, |
|---|
| 1234 | 1168 | }; |
|---|
| .. | .. |
|---|
| 1403 | 1337 | for(substream = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; |
|---|
| 1404 | 1338 | substream; |
|---|
| 1405 | 1339 | substream = substream->next) { |
|---|
| 1406 | | - if ((err = snd_pcm_lib_preallocate_pages(substream, |
|---|
| 1407 | | - SNDRV_DMA_TYPE_DEV, |
|---|
| 1408 | | - snd_dma_pci_data(emu->pci), |
|---|
| 1409 | | - 64*1024, 64*1024)) < 0) /* FIXME: 32*1024 for sound buffer, between 32and64 for Periods table. */ |
|---|
| 1410 | | - return err; |
|---|
| 1340 | + snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV, |
|---|
| 1341 | + &emu->pci->dev, |
|---|
| 1342 | + 64*1024, 64*1024); |
|---|
| 1411 | 1343 | } |
|---|
| 1412 | 1344 | |
|---|
| 1413 | 1345 | for (substream = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; |
|---|
| 1414 | 1346 | substream; |
|---|
| 1415 | 1347 | substream = substream->next) { |
|---|
| 1416 | | - if ((err = snd_pcm_lib_preallocate_pages(substream, |
|---|
| 1417 | | - SNDRV_DMA_TYPE_DEV, |
|---|
| 1418 | | - snd_dma_pci_data(emu->pci), |
|---|
| 1419 | | - 64*1024, 64*1024)) < 0) |
|---|
| 1420 | | - return err; |
|---|
| 1348 | + snd_pcm_set_managed_buffer(substream, SNDRV_DMA_TYPE_DEV, |
|---|
| 1349 | + &emu->pci->dev, |
|---|
| 1350 | + 64*1024, 64*1024); |
|---|
| 1421 | 1351 | } |
|---|
| 1422 | 1352 | |
|---|
| 1423 | 1353 | err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, map, 2, |
|---|
| .. | .. |
|---|
| 1431 | 1361 | } |
|---|
| 1432 | 1362 | |
|---|
| 1433 | 1363 | #define SPI_REG(reg, value) (((reg) << SPI_REG_SHIFT) | (value)) |
|---|
| 1434 | | -static unsigned int spi_dac_init[] = { |
|---|
| 1364 | +static const unsigned int spi_dac_init[] = { |
|---|
| 1435 | 1365 | SPI_REG(SPI_LDA1_REG, SPI_DA_BIT_0dB), /* 0dB dig. attenuation */ |
|---|
| 1436 | 1366 | SPI_REG(SPI_RDA1_REG, SPI_DA_BIT_0dB), |
|---|
| 1437 | 1367 | SPI_REG(SPI_PL_REG, SPI_PL_BIT_L_L | SPI_PL_BIT_R_R | SPI_IZD_BIT), |
|---|
| .. | .. |
|---|
| 1449 | 1379 | SPI_REG(SPI_DACD4_REG, SPI_DACD4_BIT), |
|---|
| 1450 | 1380 | }; |
|---|
| 1451 | 1381 | |
|---|
| 1452 | | -static unsigned int i2c_adc_init[][2] = { |
|---|
| 1382 | +static const unsigned int i2c_adc_init[][2] = { |
|---|
| 1453 | 1383 | { 0x17, 0x00 }, /* Reset */ |
|---|
| 1454 | 1384 | { 0x07, 0x00 }, /* Timeout */ |
|---|
| 1455 | 1385 | { 0x0b, 0x22 }, /* Interface control */ |
|---|
| .. | .. |
|---|
| 1664 | 1594 | struct snd_ca0106 **rchip) |
|---|
| 1665 | 1595 | { |
|---|
| 1666 | 1596 | struct snd_ca0106 *chip; |
|---|
| 1667 | | - struct snd_ca0106_details *c; |
|---|
| 1597 | + const struct snd_ca0106_details *c; |
|---|
| 1668 | 1598 | int err; |
|---|
| 1669 | | - static struct snd_device_ops ops = { |
|---|
| 1599 | + static const struct snd_device_ops ops = { |
|---|
| 1670 | 1600 | .dev_free = snd_ca0106_dev_free, |
|---|
| 1671 | 1601 | }; |
|---|
| 1672 | 1602 | |
|---|
| .. | .. |
|---|
| 1709 | 1639 | return -EBUSY; |
|---|
| 1710 | 1640 | } |
|---|
| 1711 | 1641 | chip->irq = pci->irq; |
|---|
| 1642 | + card->sync_irq = chip->irq; |
|---|
| 1712 | 1643 | |
|---|
| 1713 | 1644 | /* This stores the periods table. */ |
|---|
| 1714 | | - if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), |
|---|
| 1645 | + if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev, |
|---|
| 1715 | 1646 | 1024, &chip->buffer) < 0) { |
|---|
| 1716 | 1647 | snd_ca0106_free(chip); |
|---|
| 1717 | 1648 | return -ENOMEM; |
|---|
| .. | .. |
|---|
| 1911 | 1842 | { |
|---|
| 1912 | 1843 | struct snd_card *card = dev_get_drvdata(dev); |
|---|
| 1913 | 1844 | struct snd_ca0106 *chip = card->private_data; |
|---|
| 1914 | | - int i; |
|---|
| 1915 | 1845 | |
|---|
| 1916 | 1846 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
|---|
| 1917 | | - for (i = 0; i < 4; i++) |
|---|
| 1918 | | - snd_pcm_suspend_all(chip->pcm[i]); |
|---|
| 1919 | 1847 | if (chip->details->ac97) |
|---|
| 1920 | 1848 | snd_ac97_suspend(chip->ac97); |
|---|
| 1921 | 1849 | snd_ca0106_mixer_suspend(chip); |
|---|