| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Asihpi soundcard |
|---|
| 3 | 4 | * Copyright (c) by AudioScience Inc <support@audioscience.com> |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 6 | | - * it under the terms of version 2 of the GNU General Public License as |
|---|
| 7 | | - * published by the Free Software Foundation; |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 10 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 11 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 12 | | - * GNU General Public License for more details. |
|---|
| 13 | | - * |
|---|
| 14 | | - * You should have received a copy of the GNU General Public License |
|---|
| 15 | | - * along with this program; if not, write to the Free Software |
|---|
| 16 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 17 | | - * |
|---|
| 18 | 5 | * |
|---|
| 19 | 6 | * The following is not a condition of use, merely a request: |
|---|
| 20 | 7 | * If you modify this program, particularly if you fix errors, AudioScience Inc |
|---|
| .. | .. |
|---|
| 130 | 117 | * snd_card_asihpi_timer_function(). |
|---|
| 131 | 118 | */ |
|---|
| 132 | 119 | struct snd_card_asihpi_pcm *llmode_streampriv; |
|---|
| 133 | | - struct tasklet_struct t; |
|---|
| 134 | 120 | void (*pcm_start)(struct snd_pcm_substream *substream); |
|---|
| 135 | 121 | void (*pcm_stop)(struct snd_pcm_substream *substream); |
|---|
| 136 | 122 | |
|---|
| .. | .. |
|---|
| 271 | 257 | return hpi_instream_group_reset(h_stream); |
|---|
| 272 | 258 | } |
|---|
| 273 | 259 | |
|---|
| 274 | | -static inline u16 hpi_stream_group_get_map( |
|---|
| 275 | | - u32 h_stream, u32 *mo, u32 *mi) |
|---|
| 276 | | -{ |
|---|
| 277 | | - if (hpi_handle_object(h_stream) == HPI_OBJ_OSTREAM) |
|---|
| 278 | | - return hpi_outstream_group_get_map(h_stream, mo, mi); |
|---|
| 279 | | - else |
|---|
| 280 | | - return hpi_instream_group_get_map(h_stream, mo, mi); |
|---|
| 281 | | -} |
|---|
| 282 | | - |
|---|
| 283 | 260 | static u16 handle_error(u16 err, int line, char *filename) |
|---|
| 284 | 261 | { |
|---|
| 285 | 262 | if (err) |
|---|
| .. | .. |
|---|
| 313 | 290 | |
|---|
| 314 | 291 | #define INVALID_FORMAT (__force snd_pcm_format_t)(-1) |
|---|
| 315 | 292 | |
|---|
| 316 | | -static snd_pcm_format_t hpi_to_alsa_formats[] = { |
|---|
| 293 | +static const snd_pcm_format_t hpi_to_alsa_formats[] = { |
|---|
| 317 | 294 | INVALID_FORMAT, /* INVALID */ |
|---|
| 318 | 295 | SNDRV_PCM_FORMAT_U8, /* HPI_FORMAT_PCM8_UNSIGNED 1 */ |
|---|
| 319 | 296 | SNDRV_PCM_FORMAT_S16, /* HPI_FORMAT_PCM16_SIGNED 2 */ |
|---|
| .. | .. |
|---|
| 462 | 439 | unsigned int bytes_per_sec; |
|---|
| 463 | 440 | |
|---|
| 464 | 441 | print_hwparams(substream, params); |
|---|
| 465 | | - err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); |
|---|
| 466 | | - if (err < 0) |
|---|
| 467 | | - return err; |
|---|
| 468 | 442 | err = snd_card_asihpi_format_alsa2hpi(params_format(params), &format); |
|---|
| 469 | 443 | if (err) |
|---|
| 470 | 444 | return err; |
|---|
| .. | .. |
|---|
| 522 | 496 | if (dpcm->hpi_buffer_attached) |
|---|
| 523 | 497 | hpi_stream_host_buffer_detach(dpcm->h_stream); |
|---|
| 524 | 498 | |
|---|
| 525 | | - snd_pcm_lib_free_pages(substream); |
|---|
| 526 | 499 | return 0; |
|---|
| 527 | 500 | } |
|---|
| 528 | 501 | |
|---|
| .. | .. |
|---|
| 564 | 537 | card = snd_pcm_substream_chip(substream); |
|---|
| 565 | 538 | |
|---|
| 566 | 539 | WARN_ON(in_interrupt()); |
|---|
| 567 | | - tasklet_disable(&card->t); |
|---|
| 568 | 540 | card->llmode_streampriv = dpcm; |
|---|
| 569 | | - tasklet_enable(&card->t); |
|---|
| 570 | 541 | |
|---|
| 571 | 542 | hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index, |
|---|
| 572 | 543 | HPI_ADAPTER_PROPERTY_IRQ_RATE, |
|---|
| .. | .. |
|---|
| 582 | 553 | hpi_handle_error(hpi_adapter_set_property(card->hpi->adapter->index, |
|---|
| 583 | 554 | HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0)); |
|---|
| 584 | 555 | |
|---|
| 585 | | - if (in_interrupt()) |
|---|
| 586 | | - card->llmode_streampriv = NULL; |
|---|
| 587 | | - else { |
|---|
| 588 | | - tasklet_disable(&card->t); |
|---|
| 589 | | - card->llmode_streampriv = NULL; |
|---|
| 590 | | - tasklet_enable(&card->t); |
|---|
| 591 | | - } |
|---|
| 556 | + card->llmode_streampriv = NULL; |
|---|
| 592 | 557 | } |
|---|
| 593 | 558 | |
|---|
| 594 | 559 | static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, |
|---|
| .. | .. |
|---|
| 938 | 903 | add_timer(&dpcm->timer); |
|---|
| 939 | 904 | } |
|---|
| 940 | 905 | |
|---|
| 941 | | -static void snd_card_asihpi_int_task(unsigned long data) |
|---|
| 906 | +static void snd_card_asihpi_isr(struct hpi_adapter *a) |
|---|
| 942 | 907 | { |
|---|
| 943 | | - struct hpi_adapter *a = (struct hpi_adapter *)data; |
|---|
| 944 | 908 | struct snd_card_asihpi *asihpi; |
|---|
| 945 | 909 | |
|---|
| 946 | 910 | WARN_ON(!a || !a->snd_card || !a->snd_card->private_data); |
|---|
| .. | .. |
|---|
| 950 | 914 | &asihpi->llmode_streampriv->timer); |
|---|
| 951 | 915 | } |
|---|
| 952 | 916 | |
|---|
| 953 | | -static void snd_card_asihpi_isr(struct hpi_adapter *a) |
|---|
| 954 | | -{ |
|---|
| 955 | | - struct snd_card_asihpi *asihpi; |
|---|
| 956 | | - |
|---|
| 957 | | - WARN_ON(!a || !a->snd_card || !a->snd_card->private_data); |
|---|
| 958 | | - asihpi = (struct snd_card_asihpi *)a->snd_card->private_data; |
|---|
| 959 | | - tasklet_schedule(&asihpi->t); |
|---|
| 960 | | -} |
|---|
| 961 | | - |
|---|
| 962 | 917 | /***************************** PLAYBACK OPS ****************/ |
|---|
| 963 | | -static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, |
|---|
| 964 | | - unsigned int cmd, void *arg) |
|---|
| 965 | | -{ |
|---|
| 966 | | - char name[16]; |
|---|
| 967 | | - snd_pcm_debug_name(substream, name, sizeof(name)); |
|---|
| 968 | | - snd_printddd(KERN_INFO "%s ioctl %d\n", name, cmd); |
|---|
| 969 | | - return snd_pcm_lib_ioctl(substream, cmd, arg); |
|---|
| 970 | | -} |
|---|
| 971 | | - |
|---|
| 972 | 918 | static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream * |
|---|
| 973 | 919 | substream) |
|---|
| 974 | 920 | { |
|---|
| .. | .. |
|---|
| 1135 | 1081 | static const struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = { |
|---|
| 1136 | 1082 | .open = snd_card_asihpi_playback_open, |
|---|
| 1137 | 1083 | .close = snd_card_asihpi_playback_close, |
|---|
| 1138 | | - .ioctl = snd_card_asihpi_playback_ioctl, |
|---|
| 1139 | 1084 | .hw_params = snd_card_asihpi_pcm_hw_params, |
|---|
| 1140 | 1085 | .hw_free = snd_card_asihpi_hw_free, |
|---|
| 1141 | 1086 | .prepare = snd_card_asihpi_playback_prepare, |
|---|
| .. | .. |
|---|
| 1160 | 1105 | return bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); |
|---|
| 1161 | 1106 | } |
|---|
| 1162 | 1107 | |
|---|
| 1163 | | -static int snd_card_asihpi_capture_ioctl(struct snd_pcm_substream *substream, |
|---|
| 1164 | | - unsigned int cmd, void *arg) |
|---|
| 1165 | | -{ |
|---|
| 1166 | | - return snd_pcm_lib_ioctl(substream, cmd, arg); |
|---|
| 1167 | | -} |
|---|
| 1168 | | - |
|---|
| 1169 | 1108 | static int snd_card_asihpi_capture_prepare(struct snd_pcm_substream *substream) |
|---|
| 1170 | 1109 | { |
|---|
| 1171 | 1110 | struct snd_pcm_runtime *runtime = substream->runtime; |
|---|
| .. | .. |
|---|
| 1183 | 1122 | static u64 snd_card_asihpi_capture_formats(struct snd_card_asihpi *asihpi, |
|---|
| 1184 | 1123 | u32 h_stream) |
|---|
| 1185 | 1124 | { |
|---|
| 1186 | | - struct hpi_format hpi_format; |
|---|
| 1125 | + struct hpi_format hpi_format; |
|---|
| 1187 | 1126 | u16 format; |
|---|
| 1188 | 1127 | u16 err; |
|---|
| 1189 | 1128 | u32 h_control; |
|---|
| .. | .. |
|---|
| 1301 | 1240 | static const struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = { |
|---|
| 1302 | 1241 | .open = snd_card_asihpi_capture_open, |
|---|
| 1303 | 1242 | .close = snd_card_asihpi_capture_close, |
|---|
| 1304 | | - .ioctl = snd_card_asihpi_capture_ioctl, |
|---|
| 1305 | 1243 | .hw_params = snd_card_asihpi_pcm_hw_params, |
|---|
| 1306 | 1244 | .hw_free = snd_card_asihpi_hw_free, |
|---|
| 1307 | 1245 | .prepare = snd_card_asihpi_capture_prepare, |
|---|
| .. | .. |
|---|
| 1337 | 1275 | |
|---|
| 1338 | 1276 | /*? do we want to emulate MMAP for non-BBM cards? |
|---|
| 1339 | 1277 | Jack doesn't work with ALSAs MMAP emulation - WHY NOT? */ |
|---|
| 1340 | | - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
|---|
| 1341 | | - snd_dma_pci_data(asihpi->pci), |
|---|
| 1342 | | - 64*1024, BUFFER_BYTES_MAX); |
|---|
| 1278 | + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, |
|---|
| 1279 | + &asihpi->pci->dev, |
|---|
| 1280 | + 64*1024, BUFFER_BYTES_MAX); |
|---|
| 1343 | 1281 | |
|---|
| 1344 | 1282 | return 0; |
|---|
| 1345 | 1283 | } |
|---|
| .. | .. |
|---|
| 1532 | 1470 | static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol, |
|---|
| 1533 | 1471 | struct snd_ctl_elem_value *ucontrol) |
|---|
| 1534 | 1472 | { |
|---|
| 1535 | | - int change; |
|---|
| 1536 | 1473 | u32 h_control = kcontrol->private_value; |
|---|
| 1537 | 1474 | short an_gain_mB[HPI_MAX_CHANNELS]; |
|---|
| 1538 | 1475 | |
|---|
| .. | .. |
|---|
| 1543 | 1480 | /* change = asihpi->mixer_volume[addr][0] != left || |
|---|
| 1544 | 1481 | asihpi->mixer_volume[addr][1] != right; |
|---|
| 1545 | 1482 | */ |
|---|
| 1546 | | - change = 1; |
|---|
| 1547 | 1483 | hpi_handle_error(hpi_volume_set_gain(h_control, an_gain_mB)); |
|---|
| 1548 | | - return change; |
|---|
| 1484 | + return 1; |
|---|
| 1549 | 1485 | } |
|---|
| 1550 | 1486 | |
|---|
| 1551 | 1487 | static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0); |
|---|
| .. | .. |
|---|
| 1568 | 1504 | struct snd_ctl_elem_value *ucontrol) |
|---|
| 1569 | 1505 | { |
|---|
| 1570 | 1506 | u32 h_control = kcontrol->private_value; |
|---|
| 1571 | | - int change = 1; |
|---|
| 1572 | 1507 | /* HPI currently only supports all or none muting of multichannel volume |
|---|
| 1573 | 1508 | ALSA Switch element has opposite sense to HPI mute: on==unmuted, off=muted |
|---|
| 1574 | 1509 | */ |
|---|
| 1575 | 1510 | int mute = ucontrol->value.integer.value[0] ? 0 : HPI_BITMASK_ALL_CHANNELS; |
|---|
| 1576 | 1511 | hpi_handle_error(hpi_volume_set_mute(h_control, mute)); |
|---|
| 1577 | | - return change; |
|---|
| 1512 | + return 1; |
|---|
| 1578 | 1513 | } |
|---|
| 1579 | 1514 | |
|---|
| 1580 | 1515 | static int snd_asihpi_volume_add(struct snd_card_asihpi *asihpi, |
|---|
| .. | .. |
|---|
| 1941 | 1876 | */ |
|---|
| 1942 | 1877 | u16 band, idx; |
|---|
| 1943 | 1878 | u16 tuner_bands[HPI_TUNER_BAND_LAST]; |
|---|
| 1944 | | - u32 num_bands = 0; |
|---|
| 1879 | + __always_unused u32 num_bands; |
|---|
| 1945 | 1880 | |
|---|
| 1946 | 1881 | num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands, |
|---|
| 1947 | 1882 | HPI_TUNER_BAND_LAST); |
|---|
| .. | .. |
|---|
| 1968 | 1903 | unsigned int idx; |
|---|
| 1969 | 1904 | u16 band; |
|---|
| 1970 | 1905 | u16 tuner_bands[HPI_TUNER_BAND_LAST]; |
|---|
| 1971 | | - u32 num_bands = 0; |
|---|
| 1906 | + __always_unused u32 num_bands; |
|---|
| 1972 | 1907 | |
|---|
| 1973 | 1908 | num_bands = asihpi_tuner_band_query(kcontrol, tuner_bands, |
|---|
| 1974 | 1909 | HPI_TUNER_BAND_LAST); |
|---|
| .. | .. |
|---|
| 2110 | 2045 | } |
|---|
| 2111 | 2046 | |
|---|
| 2112 | 2047 | /* linear values for 10dB steps */ |
|---|
| 2113 | | -static int log2lin[] = { |
|---|
| 2048 | +static const int log2lin[] = { |
|---|
| 2114 | 2049 | 0x7FFFFFFF, /* 0dB */ |
|---|
| 2115 | 2050 | 679093956, |
|---|
| 2116 | 2051 | 214748365, |
|---|
| .. | .. |
|---|
| 2198 | 2133 | static int snd_asihpi_mux_info(struct snd_kcontrol *kcontrol, |
|---|
| 2199 | 2134 | struct snd_ctl_elem_info *uinfo) |
|---|
| 2200 | 2135 | { |
|---|
| 2201 | | - int err; |
|---|
| 2202 | 2136 | u16 src_node_type, src_node_index; |
|---|
| 2203 | 2137 | u32 h_control = kcontrol->private_value; |
|---|
| 2204 | 2138 | |
|---|
| .. | .. |
|---|
| 2211 | 2145 | uinfo->value.enumerated.item = |
|---|
| 2212 | 2146 | uinfo->value.enumerated.items - 1; |
|---|
| 2213 | 2147 | |
|---|
| 2214 | | - err = |
|---|
| 2215 | | - hpi_multiplexer_query_source(h_control, |
|---|
| 2216 | | - uinfo->value.enumerated.item, |
|---|
| 2217 | | - &src_node_type, &src_node_index); |
|---|
| 2148 | + hpi_multiplexer_query_source(h_control, |
|---|
| 2149 | + uinfo->value.enumerated.item, |
|---|
| 2150 | + &src_node_type, &src_node_index); |
|---|
| 2218 | 2151 | |
|---|
| 2219 | 2152 | sprintf(uinfo->value.enumerated.name, "%s %d", |
|---|
| 2220 | 2153 | asihpi_src_names[src_node_type - HPI_SOURCENODE_NONE], |
|---|
| .. | .. |
|---|
| 2782 | 2715 | |
|---|
| 2783 | 2716 | static void snd_asihpi_proc_init(struct snd_card_asihpi *asihpi) |
|---|
| 2784 | 2717 | { |
|---|
| 2785 | | - struct snd_info_entry *entry; |
|---|
| 2786 | | - |
|---|
| 2787 | | - if (!snd_card_proc_new(asihpi->card, "info", &entry)) |
|---|
| 2788 | | - snd_info_set_text_ops(entry, asihpi, snd_asihpi_proc_read); |
|---|
| 2718 | + snd_card_ro_proc_new(asihpi->card, "info", asihpi, |
|---|
| 2719 | + snd_asihpi_proc_read); |
|---|
| 2789 | 2720 | } |
|---|
| 2790 | 2721 | |
|---|
| 2791 | 2722 | /*------------------------------------------------------------ |
|---|
| .. | .. |
|---|
| 2912 | 2843 | if (hpi->interrupt_mode) { |
|---|
| 2913 | 2844 | asihpi->pcm_start = snd_card_asihpi_pcm_int_start; |
|---|
| 2914 | 2845 | asihpi->pcm_stop = snd_card_asihpi_pcm_int_stop; |
|---|
| 2915 | | - tasklet_init(&asihpi->t, snd_card_asihpi_int_task, |
|---|
| 2916 | | - (unsigned long)hpi); |
|---|
| 2917 | 2846 | hpi->interrupt_callback = snd_card_asihpi_isr; |
|---|
| 2918 | 2847 | } else { |
|---|
| 2919 | 2848 | asihpi->pcm_start = snd_card_asihpi_pcm_timer_start; |
|---|
| .. | .. |
|---|
| 3002 | 2931 | static void snd_asihpi_remove(struct pci_dev *pci_dev) |
|---|
| 3003 | 2932 | { |
|---|
| 3004 | 2933 | struct hpi_adapter *hpi = pci_get_drvdata(pci_dev); |
|---|
| 3005 | | - struct snd_card_asihpi *asihpi = hpi->snd_card->private_data; |
|---|
| 3006 | 2934 | |
|---|
| 3007 | 2935 | /* Stop interrupts */ |
|---|
| 3008 | 2936 | if (hpi->interrupt_mode) { |
|---|
| 3009 | 2937 | hpi->interrupt_callback = NULL; |
|---|
| 3010 | 2938 | hpi_handle_error(hpi_adapter_set_property(hpi->adapter->index, |
|---|
| 3011 | 2939 | HPI_ADAPTER_PROPERTY_IRQ_RATE, 0, 0)); |
|---|
| 3012 | | - tasklet_kill(&asihpi->t); |
|---|
| 3013 | 2940 | } |
|---|
| 3014 | 2941 | |
|---|
| 3015 | 2942 | snd_card_free(hpi->snd_card); |
|---|