| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * The driver for the ForteMedia FM801 based soundcards |
|---|
| 3 | 4 | * Copyright (c) by Jaroslav Kysela <perex@perex.cz> |
|---|
| 4 | | - * |
|---|
| 5 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 6 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 7 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 8 | | - * (at your option) any later version. |
|---|
| 9 | | - * |
|---|
| 10 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 11 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 13 | | - * GNU General Public License for more details. |
|---|
| 14 | | - * |
|---|
| 15 | 5 | */ |
|---|
| 16 | 6 | |
|---|
| 17 | 7 | #include <linux/delay.h> |
|---|
| .. | .. |
|---|
| 154 | 144 | |
|---|
| 155 | 145 | /** |
|---|
| 156 | 146 | * struct fm801 - describes FM801 chip |
|---|
| 147 | + * @dev: device for this chio |
|---|
| 148 | + * @irq: irq number |
|---|
| 157 | 149 | * @port: I/O port number |
|---|
| 158 | 150 | * @multichannel: multichannel support |
|---|
| 159 | 151 | * @secondary: secondary codec |
|---|
| .. | .. |
|---|
| 161 | 153 | * @tea575x_tuner: tuner access method & flags |
|---|
| 162 | 154 | * @ply_ctrl: playback control |
|---|
| 163 | 155 | * @cap_ctrl: capture control |
|---|
| 156 | + * @ply_buffer: playback buffer |
|---|
| 157 | + * @ply_buf: playback buffer index |
|---|
| 158 | + * @ply_count: playback buffer count |
|---|
| 159 | + * @ply_size: playback buffer size |
|---|
| 160 | + * @ply_pos: playback position |
|---|
| 161 | + * @cap_buffer: capture buffer |
|---|
| 162 | + * @cap_buf: capture buffer index |
|---|
| 163 | + * @cap_count: capture buffer count |
|---|
| 164 | + * @cap_size: capture buffer size |
|---|
| 165 | + * @cap_pos: capture position |
|---|
| 166 | + * @ac97_bus: ac97 bus handle |
|---|
| 167 | + * @ac97: ac97 handle |
|---|
| 168 | + * @ac97_sec: ac97 secondary handle |
|---|
| 169 | + * @card: ALSA card |
|---|
| 170 | + * @pcm: PCM devices |
|---|
| 171 | + * @rmidi: rmidi device |
|---|
| 172 | + * @playback_substream: substream for playback |
|---|
| 173 | + * @capture_substream: substream for capture |
|---|
| 174 | + * @p_dma_size: playback DMA size |
|---|
| 175 | + * @c_dma_size: capture DMA size |
|---|
| 176 | + * @reg_lock: lock |
|---|
| 177 | + * @proc_entry: /proc entry |
|---|
| 178 | + * @v4l2_dev: v4l2 device |
|---|
| 179 | + * @tea: tea575a structure |
|---|
| 180 | + * @saved_regs: context saved during suspend |
|---|
| 164 | 181 | */ |
|---|
| 165 | 182 | struct fm801 { |
|---|
| 166 | 183 | struct device *dev; |
|---|
| .. | .. |
|---|
| 445 | 462 | return 0; |
|---|
| 446 | 463 | } |
|---|
| 447 | 464 | |
|---|
| 448 | | -static int snd_fm801_hw_params(struct snd_pcm_substream *substream, |
|---|
| 449 | | - struct snd_pcm_hw_params *hw_params) |
|---|
| 450 | | -{ |
|---|
| 451 | | - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); |
|---|
| 452 | | -} |
|---|
| 453 | | - |
|---|
| 454 | | -static int snd_fm801_hw_free(struct snd_pcm_substream *substream) |
|---|
| 455 | | -{ |
|---|
| 456 | | - return snd_pcm_lib_free_pages(substream); |
|---|
| 457 | | -} |
|---|
| 458 | | - |
|---|
| 459 | 465 | static int snd_fm801_playback_prepare(struct snd_pcm_substream *substream) |
|---|
| 460 | 466 | { |
|---|
| 461 | 467 | struct fm801 *chip = snd_pcm_substream_chip(substream); |
|---|
| .. | .. |
|---|
| 694 | 700 | static const struct snd_pcm_ops snd_fm801_playback_ops = { |
|---|
| 695 | 701 | .open = snd_fm801_playback_open, |
|---|
| 696 | 702 | .close = snd_fm801_playback_close, |
|---|
| 697 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 698 | | - .hw_params = snd_fm801_hw_params, |
|---|
| 699 | | - .hw_free = snd_fm801_hw_free, |
|---|
| 700 | 703 | .prepare = snd_fm801_playback_prepare, |
|---|
| 701 | 704 | .trigger = snd_fm801_playback_trigger, |
|---|
| 702 | 705 | .pointer = snd_fm801_playback_pointer, |
|---|
| .. | .. |
|---|
| 705 | 708 | static const struct snd_pcm_ops snd_fm801_capture_ops = { |
|---|
| 706 | 709 | .open = snd_fm801_capture_open, |
|---|
| 707 | 710 | .close = snd_fm801_capture_close, |
|---|
| 708 | | - .ioctl = snd_pcm_lib_ioctl, |
|---|
| 709 | | - .hw_params = snd_fm801_hw_params, |
|---|
| 710 | | - .hw_free = snd_fm801_hw_free, |
|---|
| 711 | 711 | .prepare = snd_fm801_capture_prepare, |
|---|
| 712 | 712 | .trigger = snd_fm801_capture_trigger, |
|---|
| 713 | 713 | .pointer = snd_fm801_capture_pointer, |
|---|
| .. | .. |
|---|
| 730 | 730 | strcpy(pcm->name, "FM801"); |
|---|
| 731 | 731 | chip->pcm = pcm; |
|---|
| 732 | 732 | |
|---|
| 733 | | - snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, |
|---|
| 734 | | - snd_dma_pci_data(pdev), |
|---|
| 735 | | - chip->multichannel ? 128*1024 : 64*1024, 128*1024); |
|---|
| 733 | + snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, &pdev->dev, |
|---|
| 734 | + chip->multichannel ? 128*1024 : 64*1024, 128*1024); |
|---|
| 736 | 735 | |
|---|
| 737 | 736 | return snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK, |
|---|
| 738 | 737 | snd_pcm_alt_chmaps, |
|---|
| .. | .. |
|---|
| 752 | 751 | char *name; |
|---|
| 753 | 752 | }; |
|---|
| 754 | 753 | |
|---|
| 755 | | -static struct snd_fm801_tea575x_gpio snd_fm801_tea575x_gpios[] = { |
|---|
| 754 | +static const struct snd_fm801_tea575x_gpio snd_fm801_tea575x_gpios[] = { |
|---|
| 756 | 755 | { .data = 1, .clk = 3, .wren = 2, .most = 0, .name = "SF256-PCS" }, |
|---|
| 757 | 756 | { .data = 1, .clk = 0, .wren = 2, .most = 3, .name = "SF256-PCP" }, |
|---|
| 758 | 757 | { .data = 2, .clk = 0, .wren = 1, .most = 3, .name = "SF64-PCR" }, |
|---|
| .. | .. |
|---|
| 997 | 996 | |
|---|
| 998 | 997 | #define FM801_CONTROLS ARRAY_SIZE(snd_fm801_controls) |
|---|
| 999 | 998 | |
|---|
| 1000 | | -static struct snd_kcontrol_new snd_fm801_controls[] = { |
|---|
| 999 | +static const struct snd_kcontrol_new snd_fm801_controls[] = { |
|---|
| 1001 | 1000 | FM801_DOUBLE_TLV("Wave Playback Volume", FM801_PCM_VOL, 0, 8, 31, 1, |
|---|
| 1002 | 1001 | db_scale_dsp), |
|---|
| 1003 | 1002 | FM801_SINGLE("Wave Playback Switch", FM801_PCM_VOL, 15, 1, 1), |
|---|
| .. | .. |
|---|
| 1018 | 1017 | |
|---|
| 1019 | 1018 | #define FM801_CONTROLS_MULTI ARRAY_SIZE(snd_fm801_controls_multi) |
|---|
| 1020 | 1019 | |
|---|
| 1021 | | -static struct snd_kcontrol_new snd_fm801_controls_multi[] = { |
|---|
| 1020 | +static const struct snd_kcontrol_new snd_fm801_controls_multi[] = { |
|---|
| 1022 | 1021 | FM801_SINGLE("AC97 2ch->4ch Copy Switch", FM801_CODEC_CTRL, 7, 1, 0), |
|---|
| 1023 | 1022 | FM801_SINGLE("AC97 18-bit Switch", FM801_CODEC_CTRL, 10, 1, 0), |
|---|
| 1024 | 1023 | FM801_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), FM801_I2S_MODE, 8, 1, 0), |
|---|
| .. | .. |
|---|
| 1048 | 1047 | struct snd_ac97_template ac97; |
|---|
| 1049 | 1048 | unsigned int i; |
|---|
| 1050 | 1049 | int err; |
|---|
| 1051 | | - static struct snd_ac97_bus_ops ops = { |
|---|
| 1050 | + static const struct snd_ac97_bus_ops ops = { |
|---|
| 1052 | 1051 | .write = snd_fm801_codec_write, |
|---|
| 1053 | 1052 | .read = snd_fm801_codec_read, |
|---|
| 1054 | 1053 | }; |
|---|
| .. | .. |
|---|
| 1211 | 1210 | { |
|---|
| 1212 | 1211 | struct fm801 *chip; |
|---|
| 1213 | 1212 | int err; |
|---|
| 1214 | | - static struct snd_device_ops ops = { |
|---|
| 1213 | + static const struct snd_device_ops ops = { |
|---|
| 1215 | 1214 | .dev_free = snd_fm801_dev_free, |
|---|
| 1216 | 1215 | }; |
|---|
| 1217 | 1216 | |
|---|
| .. | .. |
|---|
| 1251 | 1250 | return -EBUSY; |
|---|
| 1252 | 1251 | } |
|---|
| 1253 | 1252 | chip->irq = pci->irq; |
|---|
| 1253 | + card->sync_irq = chip->irq; |
|---|
| 1254 | 1254 | pci_set_master(pci); |
|---|
| 1255 | 1255 | } |
|---|
| 1256 | 1256 | |
|---|
| .. | .. |
|---|
| 1387 | 1387 | } |
|---|
| 1388 | 1388 | |
|---|
| 1389 | 1389 | #ifdef CONFIG_PM_SLEEP |
|---|
| 1390 | | -static unsigned char saved_regs[] = { |
|---|
| 1390 | +static const unsigned char saved_regs[] = { |
|---|
| 1391 | 1391 | FM801_PCM_VOL, FM801_I2S_VOL, FM801_FM_VOL, FM801_REC_SRC, |
|---|
| 1392 | 1392 | FM801_PLY_CTRL, FM801_PLY_COUNT, FM801_PLY_BUF1, FM801_PLY_BUF2, |
|---|
| 1393 | 1393 | FM801_CAP_CTRL, FM801_CAP_COUNT, FM801_CAP_BUF1, FM801_CAP_BUF2, |
|---|
| .. | .. |
|---|
| 1408 | 1408 | if (chip->tea575x_tuner & TUNER_ONLY) { |
|---|
| 1409 | 1409 | /* FIXME: tea575x suspend */ |
|---|
| 1410 | 1410 | } else { |
|---|
| 1411 | | - snd_pcm_suspend_all(chip->pcm); |
|---|
| 1412 | 1411 | snd_ac97_suspend(chip->ac97); |
|---|
| 1413 | 1412 | snd_ac97_suspend(chip->ac97_sec); |
|---|
| 1414 | 1413 | } |
|---|