summaryrefslogtreecommitdiff
path: root/sound/pci/cmipci.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/cmipci.c')
-rw-r--r--sound/pci/cmipci.c573
1 files changed, 228 insertions, 345 deletions
diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c
index a460cb63e971..0666be543474 100644
--- a/sound/pci/cmipci.c
+++ b/sound/pci/cmipci.c
@@ -1,20 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Driver for C-Media CMI8338 and 8738 PCI soundcards.
* Copyright (c) 2000 by Takashi Iwai <tiwai@suse.de>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Does not work. Warning may block system in capture mode */
@@ -43,10 +30,6 @@
MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>");
MODULE_DESCRIPTION("C-Media CMI8x38 PCI");
MODULE_LICENSE("GPL");
-MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8738},"
- "{C-Media,CMI8738B},"
- "{C-Media,CMI8338A},"
- "{C-Media,CMI8338B}}");
#if IS_REACHABLE(CONFIG_GAMEPORT)
#define SUPPORT_JOYSTICK 1
@@ -55,7 +38,7 @@ MODULE_SUPPORTED_DEVICE("{{C-Media,CMI8738},"
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable switches */
-static long mpu_port[SNDRV_CARDS];
+static long mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
static long fm_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1};
static bool soft_ac3[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)]=1};
#ifdef SUPPORT_JOYSTICK
@@ -315,7 +298,6 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address.");
#define CM_MICGAINZ 0x01 /* mic boost */
#define CM_MICGAINZ_SHIFT 0
-#define CM_REG_MIXER3 0x24
#define CM_REG_AUX_VOL 0x26
#define CM_VAUXL_MASK 0xf0
#define CM_VAUXR_MASK 0x0f
@@ -504,10 +486,8 @@ struct cmipci {
spinlock_t reg_lock;
-#ifdef CONFIG_PM_SLEEP
unsigned int saved_regs[0x20];
unsigned char saved_mixers[0x20];
-#endif
};
@@ -599,7 +579,7 @@ static int snd_cmipci_clear_bit_b(struct cmipci *cm, unsigned int cmd, unsigned
* calculate frequency
*/
-static unsigned int rates[] = { 5512, 11025, 22050, 44100, 8000, 16000, 32000, 48000 };
+static const unsigned int rates[] = { 5512, 11025, 22050, 44100, 8000, 16000, 32000, 48000 };
static unsigned int snd_cmipci_rate_freq(unsigned int rate)
{
@@ -679,27 +659,18 @@ static void snd_cmipci_set_pll(struct cmipci *cm, unsigned int rate, unsigned in
}
#endif /* USE_VAR48KRATE */
-static int snd_cmipci_hw_params(struct snd_pcm_substream *substream,
- struct snd_pcm_hw_params *hw_params)
-{
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
-}
-
static int snd_cmipci_playback2_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
struct cmipci *cm = snd_pcm_substream_chip(substream);
if (params_channels(hw_params) > 2) {
- mutex_lock(&cm->open_mutex);
- if (cm->opened[CM_CH_PLAY]) {
- mutex_unlock(&cm->open_mutex);
+ guard(mutex)(&cm->open_mutex);
+ if (cm->opened[CM_CH_PLAY])
return -EBUSY;
- }
/* reserve the channel A */
cm->opened[CM_CH_PLAY] = CM_OPEN_PLAYBACK_MULTI;
- mutex_unlock(&cm->open_mutex);
}
- return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params));
+ return 0;
}
static void snd_cmipci_ch_reset(struct cmipci *cm, int ch)
@@ -710,11 +681,6 @@ static void snd_cmipci_ch_reset(struct cmipci *cm, int ch)
udelay(10);
}
-static int snd_cmipci_hw_free(struct snd_pcm_substream *substream)
-{
- return snd_pcm_lib_free_pages(substream);
-}
-
/*
*/
@@ -746,7 +712,7 @@ static int set_dac_channels(struct cmipci *cm, struct cmipci_pcm *rec, int chann
}
if (cm->can_multi_ch) {
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
if (channels > 2) {
snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_NXCHG);
snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_XCHGDAC);
@@ -769,7 +735,6 @@ static int set_dac_channels(struct cmipci *cm, struct cmipci_pcm *rec, int chann
snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
else
snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_CHB3D);
- spin_unlock_irq(&cm->reg_lock);
}
return 0;
}
@@ -810,7 +775,7 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec,
period_size = (period_size * runtime->channels) / 2;
}
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
/* set buffer address */
reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1;
@@ -876,7 +841,6 @@ static int snd_cmipci_pcm_prepare(struct cmipci *cm, struct cmipci_pcm *rec,
}
rec->running = 0;
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
@@ -888,14 +852,13 @@ static int snd_cmipci_pcm_trigger(struct cmipci *cm, struct cmipci_pcm *rec,
int cmd)
{
unsigned int inthld, chen, reset, pause;
- int result = 0;
inthld = CM_CH0_INT_EN << rec->ch;
chen = CM_CHEN0 << rec->ch;
reset = CM_RST_CH0 << rec->ch;
pause = CM_PAUSE0 << rec->ch;
- spin_lock(&cm->reg_lock);
+ guard(spinlock)(&cm->reg_lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
rec->running = 1;
@@ -927,11 +890,9 @@ static int snd_cmipci_pcm_trigger(struct cmipci *cm, struct cmipci_pcm *rec,
snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
break;
default:
- result = -EINVAL;
- break;
+ return -EINVAL;
}
- spin_unlock(&cm->reg_lock);
- return result;
+ return 0;
}
/*
@@ -1021,10 +982,9 @@ static int snd_cmipci_spdif_default_get(struct snd_kcontrol *kcontrol,
struct cmipci *chip = snd_kcontrol_chip(kcontrol);
int i;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
for (i = 0; i < 4; i++)
ucontrol->value.iec958.status[i] = (chip->dig_status >> (i * 8)) & 0xff;
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -1036,12 +996,11 @@ static int snd_cmipci_spdif_default_put(struct snd_kcontrol *kcontrol,
unsigned int val;
val = 0;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
for (i = 0; i < 4; i++)
val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8);
change = val != chip->dig_status;
chip->dig_status = val;
- spin_unlock_irq(&chip->reg_lock);
return change;
}
@@ -1095,10 +1054,9 @@ static int snd_cmipci_spdif_stream_get(struct snd_kcontrol *kcontrol,
struct cmipci *chip = snd_kcontrol_chip(kcontrol);
int i;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
for (i = 0; i < 4; i++)
ucontrol->value.iec958.status[i] = (chip->dig_pcm_status >> (i * 8)) & 0xff;
- spin_unlock_irq(&chip->reg_lock);
return 0;
}
@@ -1110,12 +1068,11 @@ static int snd_cmipci_spdif_stream_put(struct snd_kcontrol *kcontrol,
unsigned int val;
val = 0;
- spin_lock_irq(&chip->reg_lock);
+ guard(spinlock_irq)(&chip->reg_lock);
for (i = 0; i < 4; i++)
val |= (unsigned int)ucontrol->value.iec958.status[i] << (i * 8);
change = val != chip->dig_pcm_status;
chip->dig_pcm_status = val;
- spin_unlock_irq(&chip->reg_lock);
return change;
}
@@ -1139,7 +1096,7 @@ static int save_mixer_state(struct cmipci *cm)
struct snd_ctl_elem_value *val;
unsigned int i;
- val = kmalloc(sizeof(*val), GFP_ATOMIC);
+ val = kmalloc(sizeof(*val), GFP_KERNEL);
if (!val)
return -ENOMEM;
for (i = 0; i < CM_SAVED_MIXERS; i++) {
@@ -1253,11 +1210,13 @@ static int setup_spdif_playback(struct cmipci *cm, struct snd_pcm_substream *sub
rate = subs->runtime->rate;
- if (up && do_ac3)
- if ((err = save_mixer_state(cm)) < 0)
+ if (up && do_ac3) {
+ err = save_mixer_state(cm);
+ if (err < 0)
return err;
+ }
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
cm->spdif_playback_avail = up;
if (up) {
/* they are controlled via "IEC958 Output Switch" */
@@ -1283,7 +1242,6 @@ static int setup_spdif_playback(struct cmipci *cm, struct snd_pcm_substream *sub
snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_PLAYBACK_SPDF);
setup_ac3(cm, subs, 0, 0);
}
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
@@ -1304,7 +1262,8 @@ static int snd_cmipci_playback_prepare(struct snd_pcm_substream *substream)
substream->runtime->channels == 2);
if (do_spdif && cm->can_ac3_hw)
do_ac3 = cm->dig_pcm_status & IEC958_AES0_NONAUDIO;
- if ((err = setup_spdif_playback(cm, substream, do_spdif, do_ac3)) < 0)
+ err = setup_spdif_playback(cm, substream, do_spdif, do_ac3);
+ if (err < 0)
return err;
return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_PLAY], substream);
}
@@ -1319,7 +1278,8 @@ static int snd_cmipci_playback_spdif_prepare(struct snd_pcm_substream *substream
do_ac3 = cm->dig_pcm_status & IEC958_AES0_NONAUDIO;
else
do_ac3 = 1; /* doesn't matter */
- if ((err = setup_spdif_playback(cm, substream, 1, do_ac3)) < 0)
+ err = setup_spdif_playback(cm, substream, 1, do_ac3);
+ if (err < 0)
return err;
return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_PLAY], substream);
}
@@ -1347,32 +1307,32 @@ static void snd_cmipci_silence_hack(struct cmipci *cm, struct cmipci_pcm *rec)
/* configure for 16 bits, 2 channels, 8 kHz */
if (runtime->channels > 2)
set_dac_channels(cm, rec, 2);
- spin_lock_irq(&cm->reg_lock);
- val = snd_cmipci_read(cm, CM_REG_FUNCTRL1);
- val &= ~(CM_ASFC_MASK << (rec->ch * 3));
- val |= (4 << CM_ASFC_SHIFT) << (rec->ch * 3);
- snd_cmipci_write(cm, CM_REG_FUNCTRL1, val);
- val = snd_cmipci_read(cm, CM_REG_CHFORMAT);
- val &= ~(CM_CH0FMT_MASK << (rec->ch * 2));
- val |= (3 << CM_CH0FMT_SHIFT) << (rec->ch * 2);
- if (cm->can_96k)
- val &= ~(CM_CH0_SRATE_MASK << (rec->ch * 2));
- snd_cmipci_write(cm, CM_REG_CHFORMAT, val);
+ scoped_guard(spinlock_irq, &cm->reg_lock) {
+ val = snd_cmipci_read(cm, CM_REG_FUNCTRL1);
+ val &= ~(CM_ASFC_MASK << (rec->ch * 3));
+ val |= (4 << CM_ASFC_SHIFT) << (rec->ch * 3);
+ snd_cmipci_write(cm, CM_REG_FUNCTRL1, val);
+ val = snd_cmipci_read(cm, CM_REG_CHFORMAT);
+ val &= ~(CM_CH0FMT_MASK << (rec->ch * 2));
+ val |= (3 << CM_CH0FMT_SHIFT) << (rec->ch * 2);
+ if (cm->can_96k)
+ val &= ~(CM_CH0_SRATE_MASK << (rec->ch * 2));
+ snd_cmipci_write(cm, CM_REG_CHFORMAT, val);
- /* start stream (we don't need interrupts) */
- cm->ctrl |= CM_CHEN0 << rec->ch;
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
- spin_unlock_irq(&cm->reg_lock);
+ /* start stream (we don't need interrupts) */
+ cm->ctrl |= CM_CHEN0 << rec->ch;
+ snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl);
+ }
msleep(1);
/* stop and reset stream */
- spin_lock_irq(&cm->reg_lock);
- cm->ctrl &= ~(CM_CHEN0 << rec->ch);
- val = CM_RST_CH0 << rec->ch;
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl | val);
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl & ~val);
- spin_unlock_irq(&cm->reg_lock);
+ scoped_guard(spinlock_irq, &cm->reg_lock) {
+ cm->ctrl &= ~(CM_CHEN0 << rec->ch);
+ val = CM_RST_CH0 << rec->ch;
+ snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl | val);
+ snd_cmipci_write(cm, CM_REG_FUNCTRL0, cm->ctrl & ~val);
+ }
rec->needs_silencing = 0;
}
@@ -1384,14 +1344,14 @@ static int snd_cmipci_playback_hw_free(struct snd_pcm_substream *substream)
setup_spdif_playback(cm, substream, 0, 0);
restore_mixer_state(cm);
snd_cmipci_silence_hack(cm, &cm->channel[0]);
- return snd_cmipci_hw_free(substream);
+ return 0;
}
static int snd_cmipci_playback2_hw_free(struct snd_pcm_substream *substream)
{
struct cmipci *cm = snd_pcm_substream_chip(substream);
snd_cmipci_silence_hack(cm, &cm->channel[1]);
- return snd_cmipci_hw_free(substream);
+ return 0;
}
/* capture */
@@ -1406,20 +1366,19 @@ static int snd_cmipci_capture_spdif_prepare(struct snd_pcm_substream *substream)
{
struct cmipci *cm = snd_pcm_substream_chip(substream);
- spin_lock_irq(&cm->reg_lock);
- snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF);
- if (cm->can_96k) {
- if (substream->runtime->rate > 48000)
- snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
+ scoped_guard(spinlock_irq, &cm->reg_lock) {
+ snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF);
+ if (cm->can_96k) {
+ if (substream->runtime->rate > 48000)
+ snd_cmipci_set_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
+ else
+ snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
+ }
+ if (snd_pcm_format_width(substream->runtime->format) > 16)
+ snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
else
- snd_cmipci_clear_bit(cm, CM_REG_CHFORMAT, CM_DBLSPDS);
+ snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
}
- if (snd_pcm_format_width(substream->runtime->format) > 16)
- snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
- else
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
-
- spin_unlock_irq(&cm->reg_lock);
return snd_cmipci_pcm_prepare(cm, &cm->channel[CM_CH_CAPT], substream);
}
@@ -1428,12 +1387,11 @@ static int snd_cmipci_capture_spdif_hw_free(struct snd_pcm_substream *subs)
{
struct cmipci *cm = snd_pcm_substream_chip(subs);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_CAPTURE_SPDF);
snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_SPD32SEL);
- spin_unlock_irq(&cm->reg_lock);
- return snd_cmipci_hw_free(subs);
+ return 0;
}
@@ -1451,14 +1409,14 @@ static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id)
return IRQ_NONE;
/* acknowledge interrupt */
- spin_lock(&cm->reg_lock);
- if (status & CM_CHINT0)
- mask |= CM_CH0_INT_EN;
- if (status & CM_CHINT1)
- mask |= CM_CH1_INT_EN;
- snd_cmipci_clear_bit(cm, CM_REG_INT_HLDCLR, mask);
- snd_cmipci_set_bit(cm, CM_REG_INT_HLDCLR, mask);
- spin_unlock(&cm->reg_lock);
+ scoped_guard(spinlock, &cm->reg_lock) {
+ if (status & CM_CHINT0)
+ mask |= CM_CH0_INT_EN;
+ if (status & CM_CHINT1)
+ mask |= CM_CH1_INT_EN;
+ snd_cmipci_clear_bit(cm, CM_REG_INT_HLDCLR, mask);
+ snd_cmipci_set_bit(cm, CM_REG_INT_HLDCLR, mask);
+ }
if (cm->rmidi && (status & CM_UARTINT))
snd_mpu401_uart_interrupt(irq, cm->rmidi->private_data);
@@ -1477,7 +1435,7 @@ static irqreturn_t snd_cmipci_interrupt(int irq, void *dev_id)
*/
/* playback on channel A */
-static struct snd_pcm_hardware snd_cmipci_playback =
+static const struct snd_pcm_hardware snd_cmipci_playback =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
@@ -1497,7 +1455,7 @@ static struct snd_pcm_hardware snd_cmipci_playback =
};
/* capture on channel B */
-static struct snd_pcm_hardware snd_cmipci_capture =
+static const struct snd_pcm_hardware snd_cmipci_capture =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
@@ -1517,7 +1475,7 @@ static struct snd_pcm_hardware snd_cmipci_capture =
};
/* playback on channel B - stereo 16bit only? */
-static struct snd_pcm_hardware snd_cmipci_playback2 =
+static const struct snd_pcm_hardware snd_cmipci_playback2 =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
@@ -1537,7 +1495,7 @@ static struct snd_pcm_hardware snd_cmipci_playback2 =
};
/* spdif playback on channel A */
-static struct snd_pcm_hardware snd_cmipci_playback_spdif =
+static const struct snd_pcm_hardware snd_cmipci_playback_spdif =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
@@ -1557,7 +1515,7 @@ static struct snd_pcm_hardware snd_cmipci_playback_spdif =
};
/* spdif playback on channel A (32bit, IEC958 subframes) */
-static struct snd_pcm_hardware snd_cmipci_playback_iec958_subframe =
+static const struct snd_pcm_hardware snd_cmipci_playback_iec958_subframe =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
@@ -1577,7 +1535,7 @@ static struct snd_pcm_hardware snd_cmipci_playback_iec958_subframe =
};
/* spdif capture on channel B */
-static struct snd_pcm_hardware snd_cmipci_capture_spdif =
+static const struct snd_pcm_hardware snd_cmipci_capture_spdif =
{
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_PAUSE |
@@ -1597,14 +1555,6 @@ static struct snd_pcm_hardware snd_cmipci_capture_spdif =
.fifo_size = 0,
};
-static const unsigned int rate_constraints[] = { 5512, 8000, 11025, 16000, 22050,
- 32000, 44100, 48000, 88200, 96000, 128000 };
-static const struct snd_pcm_hw_constraint_list hw_constraints_rates = {
- .count = ARRAY_SIZE(rate_constraints),
- .list = rate_constraints,
- .mask = 0,
-};
-
/*
* check device open/close
*/
@@ -1617,21 +1567,17 @@ static int open_device_check(struct cmipci *cm, int mode, struct snd_pcm_substre
* pcm framework doesn't pass file pointer before actually opened,
* we can't know whether blocking mode or not in open callback..
*/
- mutex_lock(&cm->open_mutex);
- if (cm->opened[ch]) {
- mutex_unlock(&cm->open_mutex);
+ guard(mutex)(&cm->open_mutex);
+ if (cm->opened[ch])
return -EBUSY;
- }
cm->opened[ch] = mode;
cm->channel[ch].substream = subs;
if (! (mode & CM_OPEN_DAC)) {
/* disable dual DAC mode */
cm->channel[ch].is_dac = 0;
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_ENDBDAC);
- spin_unlock_irq(&cm->reg_lock);
}
- mutex_unlock(&cm->open_mutex);
return 0;
}
@@ -1639,7 +1585,7 @@ static void close_device_check(struct cmipci *cm, int mode)
{
int ch = mode & CM_OPEN_CH_MASK;
- mutex_lock(&cm->open_mutex);
+ guard(mutex)(&cm->open_mutex);
if (cm->opened[ch] == mode) {
if (cm->channel[ch].substream) {
snd_cmipci_ch_reset(cm, ch);
@@ -1650,12 +1596,10 @@ static void close_device_check(struct cmipci *cm, int mode)
if (! cm->channel[ch].is_dac) {
/* enable dual DAC mode again */
cm->channel[ch].is_dac = 1;
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
snd_cmipci_set_bit(cm, CM_REG_MISC_CTRL, CM_ENDBDAC);
- spin_unlock_irq(&cm->reg_lock);
}
}
- mutex_unlock(&cm->open_mutex);
}
/*
@@ -1667,7 +1611,8 @@ static int snd_cmipci_playback_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- if ((err = open_device_check(cm, CM_OPEN_PLAYBACK, substream)) < 0)
+ err = open_device_check(cm, CM_OPEN_PLAYBACK, substream);
+ if (err < 0)
return err;
runtime->hw = snd_cmipci_playback;
if (cm->chip_version == 68) {
@@ -1675,11 +1620,9 @@ static int snd_cmipci_playback_open(struct snd_pcm_substream *substream)
SNDRV_PCM_RATE_96000;
runtime->hw.rate_max = 96000;
} else if (cm->chip_version == 55) {
- err = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
- if (err < 0)
- return err;
- runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
+ runtime->hw.rates |= SNDRV_PCM_RATE_88200 |
+ SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_128000;
runtime->hw.rate_max = 128000;
}
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);
@@ -1693,18 +1636,17 @@ static int snd_cmipci_capture_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- if ((err = open_device_check(cm, CM_OPEN_CAPTURE, substream)) < 0)
+ err = open_device_check(cm, CM_OPEN_CAPTURE, substream);
+ if (err < 0)
return err;
runtime->hw = snd_cmipci_capture;
if (cm->chip_version == 68) { // 8768 only supports 44k/48k recording
runtime->hw.rate_min = 41000;
runtime->hw.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000;
} else if (cm->chip_version == 55) {
- err = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
- if (err < 0)
- return err;
- runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
+ runtime->hw.rates |= SNDRV_PCM_RATE_88200 |
+ SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_128000;
runtime->hw.rate_max = 128000;
}
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);
@@ -1717,10 +1659,12 @@ static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- if ((err = open_device_check(cm, CM_OPEN_PLAYBACK2, substream)) < 0) /* use channel B */
+ /* use channel B */
+ err = open_device_check(cm, CM_OPEN_PLAYBACK2, substream);
+ if (err < 0)
return err;
runtime->hw = snd_cmipci_playback2;
- mutex_lock(&cm->open_mutex);
+ guard(mutex)(&cm->open_mutex);
if (! cm->opened[CM_CH_PLAY]) {
if (cm->can_multi_ch) {
runtime->hw.channels_max = cm->max_channels;
@@ -1732,17 +1676,14 @@ static int snd_cmipci_playback2_open(struct snd_pcm_substream *substream)
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels_8);
}
}
- mutex_unlock(&cm->open_mutex);
if (cm->chip_version == 68) {
runtime->hw.rates |= SNDRV_PCM_RATE_88200 |
SNDRV_PCM_RATE_96000;
runtime->hw.rate_max = 96000;
} else if (cm->chip_version == 55) {
- err = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
- if (err < 0)
- return err;
- runtime->hw.rates |= SNDRV_PCM_RATE_KNOT;
+ runtime->hw.rates |= SNDRV_PCM_RATE_88200 |
+ SNDRV_PCM_RATE_96000 |
+ SNDRV_PCM_RATE_128000;
runtime->hw.rate_max = 128000;
}
snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 0x10000);
@@ -1755,7 +1696,9 @@ static int snd_cmipci_playback_spdif_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- if ((err = open_device_check(cm, CM_OPEN_SPDIF_PLAYBACK, substream)) < 0) /* use channel A */
+ /* use channel A */
+ err = open_device_check(cm, CM_OPEN_SPDIF_PLAYBACK, substream);
+ if (err < 0)
return err;
if (cm->can_ac3_hw) {
runtime->hw = snd_cmipci_playback_spdif;
@@ -1782,7 +1725,9 @@ static int snd_cmipci_capture_spdif_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime;
int err;
- if ((err = open_device_check(cm, CM_OPEN_SPDIF_CAPTURE, substream)) < 0) /* use channel B */
+ /* use channel B */
+ err = open_device_check(cm, CM_OPEN_SPDIF_CAPTURE, substream);
+ if (err < 0)
return err;
runtime->hw = snd_cmipci_capture_spdif;
if (cm->can_96k && !(cm->chip_version == 68)) {
@@ -1841,8 +1786,6 @@ static int snd_cmipci_capture_spdif_close(struct snd_pcm_substream *substream)
static const struct snd_pcm_ops snd_cmipci_playback_ops = {
.open = snd_cmipci_playback_open,
.close = snd_cmipci_playback_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cmipci_hw_params,
.hw_free = snd_cmipci_playback_hw_free,
.prepare = snd_cmipci_playback_prepare,
.trigger = snd_cmipci_playback_trigger,
@@ -1852,9 +1795,6 @@ static const struct snd_pcm_ops snd_cmipci_playback_ops = {
static const struct snd_pcm_ops snd_cmipci_capture_ops = {
.open = snd_cmipci_capture_open,
.close = snd_cmipci_capture_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cmipci_hw_params,
- .hw_free = snd_cmipci_hw_free,
.prepare = snd_cmipci_capture_prepare,
.trigger = snd_cmipci_capture_trigger,
.pointer = snd_cmipci_capture_pointer,
@@ -1863,7 +1803,6 @@ static const struct snd_pcm_ops snd_cmipci_capture_ops = {
static const struct snd_pcm_ops snd_cmipci_playback2_ops = {
.open = snd_cmipci_playback2_open,
.close = snd_cmipci_playback2_close,
- .ioctl = snd_pcm_lib_ioctl,
.hw_params = snd_cmipci_playback2_hw_params,
.hw_free = snd_cmipci_playback2_hw_free,
.prepare = snd_cmipci_capture_prepare, /* channel B */
@@ -1874,8 +1813,6 @@ static const struct snd_pcm_ops snd_cmipci_playback2_ops = {
static const struct snd_pcm_ops snd_cmipci_playback_spdif_ops = {
.open = snd_cmipci_playback_spdif_open,
.close = snd_cmipci_playback_spdif_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cmipci_hw_params,
.hw_free = snd_cmipci_playback_hw_free,
.prepare = snd_cmipci_playback_spdif_prepare, /* set up rate */
.trigger = snd_cmipci_playback_trigger,
@@ -1885,8 +1822,6 @@ static const struct snd_pcm_ops snd_cmipci_playback_spdif_ops = {
static const struct snd_pcm_ops snd_cmipci_capture_spdif_ops = {
.open = snd_cmipci_capture_spdif_open,
.close = snd_cmipci_capture_spdif_close,
- .ioctl = snd_pcm_lib_ioctl,
- .hw_params = snd_cmipci_hw_params,
.hw_free = snd_cmipci_capture_spdif_hw_free,
.prepare = snd_cmipci_capture_spdif_prepare,
.trigger = snd_cmipci_capture_trigger,
@@ -1911,11 +1846,11 @@ static int snd_cmipci_pcm_new(struct cmipci *cm, int device)
pcm->private_data = cm;
pcm->info_flags = 0;
- strcpy(pcm->name, "C-Media PCI DAC/ADC");
+ strscpy(pcm->name, "C-Media PCI DAC/ADC");
cm->pcm = pcm;
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(cm->pci), 64*1024, 128*1024);
+ snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
+ &cm->pci->dev, 64*1024, 128*1024);
return 0;
}
@@ -1933,11 +1868,11 @@ static int snd_cmipci_pcm2_new(struct cmipci *cm, int device)
pcm->private_data = cm;
pcm->info_flags = 0;
- strcpy(pcm->name, "C-Media PCI 2nd DAC");
+ strscpy(pcm->name, "C-Media PCI 2nd DAC");
cm->pcm2 = pcm;
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(cm->pci), 64*1024, 128*1024);
+ snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
+ &cm->pci->dev, 64*1024, 128*1024);
return 0;
}
@@ -1956,11 +1891,11 @@ static int snd_cmipci_pcm_spdif_new(struct cmipci *cm, int device)
pcm->private_data = cm;
pcm->info_flags = 0;
- strcpy(pcm->name, "C-Media PCI IEC958");
+ strscpy(pcm->name, "C-Media PCI IEC958");
cm->pcm_spdif = pcm;
- snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
- snd_dma_pci_data(cm->pci), 64*1024, 128*1024);
+ snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV,
+ &cm->pci->dev, 64*1024, 128*1024);
err = snd_pcm_add_chmap_ctls(pcm, SNDRV_PCM_STREAM_PLAYBACK,
snd_pcm_alt_chmaps, cm->max_channels, 0,
@@ -2053,7 +1988,7 @@ static int snd_cmipci_get_volume(struct snd_kcontrol *kcontrol,
int val;
cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
val = (snd_cmipci_mixer_read(cm, reg.left_reg) >> reg.left_shift) & reg.mask;
if (reg.invert)
val = reg.mask - val;
@@ -2064,7 +1999,6 @@ static int snd_cmipci_get_volume(struct snd_kcontrol *kcontrol,
val = reg.mask - val;
ucontrol->value.integer.value[1] = val;
}
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
@@ -2088,7 +2022,7 @@ static int snd_cmipci_put_volume(struct snd_kcontrol *kcontrol,
right <<= reg.right_shift;
} else
right = 0;
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
oleft = snd_cmipci_mixer_read(cm, reg.left_reg);
left |= oleft & ~(reg.mask << reg.left_shift);
change = left != oleft;
@@ -2103,7 +2037,6 @@ static int snd_cmipci_put_volume(struct snd_kcontrol *kcontrol,
snd_cmipci_mixer_write(cm, reg.right_reg, right);
} else
snd_cmipci_mixer_write(cm, reg.left_reg, left);
- spin_unlock_irq(&cm->reg_lock);
return change;
}
@@ -2135,10 +2068,9 @@ static int snd_cmipci_get_input_sw(struct snd_kcontrol *kcontrol,
int val1, val2;
cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
val1 = snd_cmipci_mixer_read(cm, reg.left_reg);
val2 = snd_cmipci_mixer_read(cm, reg.right_reg);
- spin_unlock_irq(&cm->reg_lock);
ucontrol->value.integer.value[0] = (val1 >> reg.left_shift) & 1;
ucontrol->value.integer.value[1] = (val2 >> reg.left_shift) & 1;
ucontrol->value.integer.value[2] = (val1 >> reg.right_shift) & 1;
@@ -2155,7 +2087,7 @@ static int snd_cmipci_put_input_sw(struct snd_kcontrol *kcontrol,
int val1, val2, oval1, oval2;
cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
oval1 = snd_cmipci_mixer_read(cm, reg.left_reg);
oval2 = snd_cmipci_mixer_read(cm, reg.right_reg);
val1 = oval1 & ~((1 << reg.left_shift) | (1 << reg.right_shift));
@@ -2167,7 +2099,6 @@ static int snd_cmipci_put_input_sw(struct snd_kcontrol *kcontrol,
change = val1 != oval1 || val2 != oval2;
snd_cmipci_mixer_write(cm, reg.left_reg, val1);
snd_cmipci_mixer_write(cm, reg.right_reg, val2);
- spin_unlock_irq(&cm->reg_lock);
return change;
}
@@ -2225,7 +2156,7 @@ static int snd_cmipci_get_native_mixer(struct snd_kcontrol *kcontrol,
unsigned char oreg, val;
cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
oreg = inb(cm->iobase + reg.left_reg);
val = (oreg >> reg.left_shift) & reg.mask;
if (reg.invert)
@@ -2237,7 +2168,6 @@ static int snd_cmipci_get_native_mixer(struct snd_kcontrol *kcontrol,
val = reg.mask - val;
ucontrol->value.integer.value[1] = val;
}
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
@@ -2249,7 +2179,7 @@ static int snd_cmipci_put_native_mixer(struct snd_kcontrol *kcontrol,
unsigned char oreg, nreg, val;
cmipci_sb_reg_decode(&reg, kcontrol->private_value);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
oreg = inb(cm->iobase + reg.left_reg);
val = ucontrol->value.integer.value[0] & reg.mask;
if (reg.invert)
@@ -2264,7 +2194,6 @@ static int snd_cmipci_put_native_mixer(struct snd_kcontrol *kcontrol,
nreg |= (val << reg.right_shift);
}
outb(nreg, cm->iobase + reg.left_reg);
- spin_unlock_irq(&cm->reg_lock);
return (nreg != oreg);
}
@@ -2290,7 +2219,7 @@ static int snd_cmipci_put_native_mixer_sensitive(struct snd_kcontrol *kcontrol,
}
-static struct snd_kcontrol_new snd_cmipci_mixers[] = {
+static const struct snd_kcontrol_new snd_cmipci_mixers[] = {
CMIPCI_SB_VOL_STEREO("Master Playback Volume", SB_DSP4_MASTER_DEV, 3, 31),
CMIPCI_MIXER_SW_MONO("3D Control - Switch", CM_REG_MIXER1, CM_X3DEN_SHIFT, 0),
CMIPCI_SB_VOL_STEREO("PCM Playback Volume", SB_DSP4_PCM_DEV, 3, 31),
@@ -2351,10 +2280,9 @@ static int _snd_cmipci_uswitch_get(struct snd_kcontrol *kcontrol,
unsigned int val;
struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
if (args->ac3_sensitive && cm->mixer_insensitive) {
ucontrol->value.integer.value[0] = 0;
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
if (args->is_byte)
@@ -2362,7 +2290,6 @@ static int _snd_cmipci_uswitch_get(struct snd_kcontrol *kcontrol,
else
val = snd_cmipci_read(cm, args->reg);
ucontrol->value.integer.value[0] = ((val & args->mask) == args->mask_on) ? 1 : 0;
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
@@ -2384,10 +2311,9 @@ static int _snd_cmipci_uswitch_put(struct snd_kcontrol *kcontrol,
int change;
struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
if (args->ac3_sensitive && cm->mixer_insensitive) {
/* ignored */
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
if (args->is_byte)
@@ -2407,7 +2333,6 @@ static int _snd_cmipci_uswitch_put(struct snd_kcontrol *kcontrol,
else
snd_cmipci_write(cm, args->reg, val);
}
- spin_unlock_irq(&cm->reg_lock);
return change;
}
@@ -2540,9 +2465,8 @@ static int snd_cmipci_line_in_mode_get(struct snd_kcontrol *kcontrol,
{
struct cmipci *cm = snd_kcontrol_chip(kcontrol);
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
ucontrol->value.enumerated.item[0] = get_line_in_mode(cm);
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
@@ -2552,7 +2476,7 @@ static int snd_cmipci_line_in_mode_put(struct snd_kcontrol *kcontrol,
struct cmipci *cm = snd_kcontrol_chip(kcontrol);
int change;
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
if (ucontrol->value.enumerated.item[0] == 2)
change = snd_cmipci_set_bit(cm, CM_REG_LEGACY_CTRL, CM_CENTR2LIN | CM_BASE2LIN);
else
@@ -2561,7 +2485,6 @@ static int snd_cmipci_line_in_mode_put(struct snd_kcontrol *kcontrol,
change |= snd_cmipci_set_bit_b(cm, CM_REG_MIXER1, CM_REAR2LIN);
else
change |= snd_cmipci_clear_bit_b(cm, CM_REG_MIXER1, CM_REAR2LIN);
- spin_unlock_irq(&cm->reg_lock);
return change;
}
@@ -2577,11 +2500,11 @@ static int snd_cmipci_mic_in_mode_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct cmipci *cm = snd_kcontrol_chip(kcontrol);
+
/* same bit as spdi_phase */
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
ucontrol->value.enumerated.item[0] =
(snd_cmipci_read_b(cm, CM_REG_MISC) & CM_SPDIF_INVERSE) ? 1 : 0;
- spin_unlock_irq(&cm->reg_lock);
return 0;
}
@@ -2591,17 +2514,16 @@ static int snd_cmipci_mic_in_mode_put(struct snd_kcontrol *kcontrol,
struct cmipci *cm = snd_kcontrol_chip(kcontrol);
int change;
- spin_lock_irq(&cm->reg_lock);
+ guard(spinlock_irq)(&cm->reg_lock);
if (ucontrol->value.enumerated.item[0])
change = snd_cmipci_set_bit_b(cm, CM_REG_MISC, CM_SPDIF_INVERSE);
else
change = snd_cmipci_clear_bit_b(cm, CM_REG_MISC, CM_SPDIF_INVERSE);
- spin_unlock_irq(&cm->reg_lock);
return change;
}
/* both for CM8338/8738 */
-static struct snd_kcontrol_new snd_cmipci_mixer_switches[] = {
+static const struct snd_kcontrol_new snd_cmipci_mixer_switches[] = {
DEFINE_MIXER_SWITCH("Four Channel Mode", fourch),
{
.name = "Line-In Mode",
@@ -2613,11 +2535,11 @@ static struct snd_kcontrol_new snd_cmipci_mixer_switches[] = {
};
/* for non-multichannel chips */
-static struct snd_kcontrol_new snd_cmipci_nomulti_switch =
+static const struct snd_kcontrol_new snd_cmipci_nomulti_switch =
DEFINE_MIXER_SWITCH("Exchange DAC", exchange_dac);
/* only for CM8738 */
-static struct snd_kcontrol_new snd_cmipci_8738_mixer_switches[] = {
+static const struct snd_kcontrol_new snd_cmipci_8738_mixer_switches[] = {
#if 0 /* controlled in pcm device */
DEFINE_MIXER_SWITCH("IEC958 In Record", spdif_in),
DEFINE_MIXER_SWITCH("IEC958 Out", spdif_out),
@@ -2639,14 +2561,14 @@ static struct snd_kcontrol_new snd_cmipci_8738_mixer_switches[] = {
};
/* only for model 033/037 */
-static struct snd_kcontrol_new snd_cmipci_old_mixer_switches[] = {
+static const struct snd_kcontrol_new snd_cmipci_old_mixer_switches[] = {
DEFINE_MIXER_SWITCH("IEC958 Mix Analog", spdif_dac_out),
DEFINE_MIXER_SWITCH("IEC958 In Phase Inverse", spdi_phase),
DEFINE_MIXER_SWITCH("IEC958 In Select", spdif_in_sel1),
};
/* only for model 039 or later */
-static struct snd_kcontrol_new snd_cmipci_extra_mixer_switches[] = {
+static const struct snd_kcontrol_new snd_cmipci_extra_mixer_switches[] = {
DEFINE_MIXER_SWITCH("IEC958 In Select", spdif_in_sel2),
DEFINE_MIXER_SWITCH("IEC958 In Phase Inverse", spdi_phase2),
{
@@ -2659,14 +2581,14 @@ static struct snd_kcontrol_new snd_cmipci_extra_mixer_switches[] = {
};
/* card control switches */
-static struct snd_kcontrol_new snd_cmipci_modem_switch =
+static const struct snd_kcontrol_new snd_cmipci_modem_switch =
DEFINE_CARD_SWITCH("Modem", modem);
static int snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device)
{
struct snd_card *card;
- struct snd_kcontrol_new *sw;
+ const struct snd_kcontrol_new *sw;
struct snd_kcontrol *kctl;
unsigned int idx;
int err;
@@ -2676,11 +2598,11 @@ static int snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device)
card = cm->card;
- strcpy(card->mixername, "CMedia PCI");
+ strscpy(card->mixername, "CMedia PCI");
- spin_lock_irq(&cm->reg_lock);
- snd_cmipci_mixer_write(cm, 0x00, 0x00); /* mixer reset */
- spin_unlock_irq(&cm->reg_lock);
+ scoped_guard(spinlock_irq, &cm->reg_lock) {
+ snd_cmipci_mixer_write(cm, 0x00, 0x00); /* mixer reset */
+ }
for (idx = 0; idx < ARRAY_SIZE(snd_cmipci_mixers); idx++) {
if (cm->chip_version == 68) { // 8768 has no PCM volume
@@ -2688,7 +2610,8 @@ static int snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device)
"PCM Playback Volume"))
continue;
}
- if ((err = snd_ctl_add(card, snd_ctl_new1(&snd_cmipci_mixers[idx], cm))) < 0)
+ err = snd_ctl_add(card, snd_ctl_new1(&snd_cmipci_mixers[idx], cm));
+ if (err < 0)
return err;
}
@@ -2713,15 +2636,21 @@ static int snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device)
return err;
}
if (cm->can_ac3_hw) {
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_cmipci_spdif_default, cm))) < 0)
- return err;
+ kctl = snd_ctl_new1(&snd_cmipci_spdif_default, cm);
kctl->id.device = pcm_spdif_device;
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_cmipci_spdif_mask, cm))) < 0)
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
+ kctl = snd_ctl_new1(&snd_cmipci_spdif_mask, cm);
kctl->id.device = pcm_spdif_device;
- if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_cmipci_spdif_stream, cm))) < 0)
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
return err;
+ kctl = snd_ctl_new1(&snd_cmipci_spdif_stream, cm);
kctl->id.device = pcm_spdif_device;
+ err = snd_ctl_add(card, kctl);
+ if (err < 0)
+ return err;
}
if (cm->chip_version <= 37) {
sw = snd_cmipci_old_mixer_switches;
@@ -2754,12 +2683,8 @@ static int snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_device)
}
for (idx = 0; idx < CM_SAVED_MIXERS; idx++) {
- struct snd_ctl_elem_id elem_id;
struct snd_kcontrol *ctl;
- memset(&elem_id, 0, sizeof(elem_id));
- elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
- strcpy(elem_id.name, cm_saved_mixer[idx].name);
- ctl = snd_ctl_find_id(cm->card, &elem_id);
+ ctl = snd_ctl_find_id_mixer(cm->card, cm_saved_mixer[idx].name);
if (ctl)
cm->mixer_res_ctl[idx] = ctl;
}
@@ -2792,10 +2717,7 @@ static void snd_cmipci_proc_read(struct snd_info_entry *entry,
static void snd_cmipci_proc_init(struct cmipci *cm)
{
- struct snd_info_entry *entry;
-
- if (! snd_card_proc_new(cm->card, "cmipci", &entry))
- snd_info_set_text_ops(entry, cm, snd_cmipci_proc_read);
+ snd_card_ro_proc_new(cm->card, "cmipci", cm, snd_cmipci_proc_read);
}
static const struct pci_device_id snd_cmipci_ids[] = {
@@ -2863,7 +2785,7 @@ static void query_chip(struct cmipci *cm)
#ifdef SUPPORT_JOYSTICK
static int snd_cmipci_create_gameport(struct cmipci *cm, int dev)
{
- static int ports[] = { 0x201, 0x200, 0 }; /* FIXME: majority is 0x201? */
+ static const int ports[] = { 0x201, 0x200, 0 }; /* FIXME: majority is 0x201? */
struct gameport *gp;
struct resource *r = NULL;
int i, io_port = 0;
@@ -2874,13 +2796,15 @@ static int snd_cmipci_create_gameport(struct cmipci *cm, int dev)
if (joystick_port[dev] == 1) { /* auto-detect */
for (i = 0; ports[i]; i++) {
io_port = ports[i];
- r = request_region(io_port, 1, "CMIPCI gameport");
+ r = devm_request_region(&cm->pci->dev, io_port, 1,
+ "CMIPCI gameport");
if (r)
break;
}
} else {
io_port = joystick_port[dev];
- r = request_region(io_port, 1, "CMIPCI gameport");
+ r = devm_request_region(&cm->pci->dev, io_port, 1,
+ "CMIPCI gameport");
}
if (!r) {
@@ -2891,14 +2815,12 @@ static int snd_cmipci_create_gameport(struct cmipci *cm, int dev)
cm->gameport = gp = gameport_allocate_port();
if (!gp) {
dev_err(cm->card->dev, "cannot allocate memory for gameport\n");
- release_and_free_resource(r);
return -ENOMEM;
}
gameport_set_name(gp, "C-Media Gameport");
gameport_set_phys(gp, "pci%s/gameport0", pci_name(cm->pci));
gameport_set_dev_parent(gp, &cm->pci->dev);
gp->io = io_port;
- gameport_set_port_data(gp, r);
snd_cmipci_set_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
@@ -2910,13 +2832,10 @@ static int snd_cmipci_create_gameport(struct cmipci *cm, int dev)
static void snd_cmipci_free_gameport(struct cmipci *cm)
{
if (cm->gameport) {
- struct resource *r = gameport_get_port_data(cm->gameport);
-
gameport_unregister_port(cm->gameport);
cm->gameport = NULL;
snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
- release_and_free_resource(r);
}
}
#else
@@ -2924,34 +2843,22 @@ static inline int snd_cmipci_create_gameport(struct cmipci *cm, int dev) { retur
static inline void snd_cmipci_free_gameport(struct cmipci *cm) { }
#endif
-static int snd_cmipci_free(struct cmipci *cm)
+static void snd_cmipci_free(struct snd_card *card)
{
- if (cm->irq >= 0) {
- snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
- snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT);
- snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0); /* disable ints */
- snd_cmipci_ch_reset(cm, CM_CH_PLAY);
- snd_cmipci_ch_reset(cm, CM_CH_CAPT);
- snd_cmipci_write(cm, CM_REG_FUNCTRL0, 0); /* disable channels */
- snd_cmipci_write(cm, CM_REG_FUNCTRL1, 0);
+ struct cmipci *cm = card->private_data;
- /* reset mixer */
- snd_cmipci_mixer_write(cm, 0, 0);
+ snd_cmipci_clear_bit(cm, CM_REG_MISC_CTRL, CM_FM_EN);
+ snd_cmipci_clear_bit(cm, CM_REG_LEGACY_CTRL, CM_ENSPDOUT);
+ snd_cmipci_write(cm, CM_REG_INT_HLDCLR, 0); /* disable ints */
+ snd_cmipci_ch_reset(cm, CM_CH_PLAY);
+ snd_cmipci_ch_reset(cm, CM_CH_CAPT);
+ snd_cmipci_write(cm, CM_REG_FUNCTRL0, 0); /* disable channels */
+ snd_cmipci_write(cm, CM_REG_FUNCTRL1, 0);
- free_irq(cm->irq, cm);
- }
+ /* reset mixer */
+ snd_cmipci_mixer_write(cm, 0, 0);
snd_cmipci_free_gameport(cm);
- pci_release_regions(cm->pci);
- pci_disable_device(cm->pci);
- kfree(cm);
- return 0;
-}
-
-static int snd_cmipci_dev_free(struct snd_device *device)
-{
- struct cmipci *cm = device->device_data;
- return snd_cmipci_free(cm);
}
static int snd_cmipci_create_fm(struct cmipci *cm, long fm_port)
@@ -2996,7 +2903,8 @@ static int snd_cmipci_create_fm(struct cmipci *cm, long fm_port)
goto disable_fm;
}
}
- if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
+ err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
+ if (err < 0) {
dev_err(cm->card->dev, "cannot create OPL3 hwdep\n");
return err;
}
@@ -3009,13 +2917,10 @@ static int snd_cmipci_create_fm(struct cmipci *cm, long fm_port)
}
static int snd_cmipci_create(struct snd_card *card, struct pci_dev *pci,
- int dev, struct cmipci **rcmipci)
+ int dev)
{
- struct cmipci *cm;
+ struct cmipci *cm = card->private_data;
int err;
- static struct snd_device_ops ops = {
- .dev_free = snd_cmipci_dev_free,
- };
unsigned int val;
long iomidi = 0;
int integrated_midi = 0;
@@ -3026,17 +2931,10 @@ static int snd_cmipci_create(struct snd_card *card, struct pci_dev *pci,
{ },
};
- *rcmipci = NULL;
-
- if ((err = pci_enable_device(pci)) < 0)
+ err = pcim_enable_device(pci);
+ if (err < 0)
return err;
- cm = kzalloc(sizeof(*cm), GFP_KERNEL);
- if (cm == NULL) {
- pci_disable_device(pci);
- return -ENOMEM;
- }
-
spin_lock_init(&cm->reg_lock);
mutex_init(&cm->open_mutex);
cm->device = pci->device;
@@ -3047,20 +2945,19 @@ static int snd_cmipci_create(struct snd_card *card, struct pci_dev *pci,
cm->channel[1].ch = 1;
cm->channel[0].is_dac = cm->channel[1].is_dac = 1; /* dual DAC mode */
- if ((err = pci_request_regions(pci, card->driver)) < 0) {
- kfree(cm);
- pci_disable_device(pci);
+ err = pcim_request_all_regions(pci, card->driver);
+ if (err < 0)
return err;
- }
cm->iobase = pci_resource_start(pci, 0);
- if (request_irq(pci->irq, snd_cmipci_interrupt,
- IRQF_SHARED, KBUILD_MODNAME, cm)) {
+ if (devm_request_irq(&pci->dev, pci->irq, snd_cmipci_interrupt,
+ IRQF_SHARED, KBUILD_MODNAME, cm)) {
dev_err(card->dev, "unable to grab IRQ %d\n", pci->irq);
- snd_cmipci_free(cm);
return -EBUSY;
}
cm->irq = pci->irq;
+ card->sync_irq = cm->irq;
+ card->private_free = snd_cmipci_free;
pci_set_master(cm->pci);
@@ -3076,11 +2973,12 @@ static int snd_cmipci_create(struct snd_card *card, struct pci_dev *pci,
pci->device != PCI_DEVICE_ID_CMEDIA_CM8338B)
query_chip(cm);
/* added -MCx suffix for chip supporting multi-channels */
- if (cm->can_multi_ch)
- sprintf(cm->card->driver + strlen(cm->card->driver),
- "-MC%d", cm->max_channels);
- else if (cm->can_ac3_sw)
- strcpy(cm->card->driver + strlen(cm->card->driver), "-SWIEC");
+ if (cm->can_multi_ch) {
+ int l = strlen(cm->card->driver);
+ scnprintf(cm->card->driver + l, sizeof(cm->card->driver) - l,
+ "-MC%d", cm->max_channels);
+ } else if (cm->can_ac3_sw)
+ strlcat(cm->card->driver, "-SWIEC", sizeof(cm->card->driver));
cm->dig_status = SNDRV_PCM_DEFAULT_CON_SPDIF;
cm->dig_pcm_status = SNDRV_PCM_DEFAULT_CON_SPDIF;
@@ -3152,23 +3050,21 @@ static int snd_cmipci_create(struct snd_card *card, struct pci_dev *pci,
}
}
}
- sprintf(card->shortname, "C-Media CMI%d", val);
+ sprintf(card->shortname, "C-Media CMI%u", val);
if (cm->chip_version < 68)
- sprintf(modelstr, " (model %d)", cm->chip_version);
+ scnprintf(modelstr, sizeof(modelstr),
+ " (model %d)", cm->chip_version);
else
modelstr[0] = '\0';
- sprintf(card->longname, "%s%s at %#lx, irq %i",
- card->shortname, modelstr, cm->iobase, cm->irq);
-
- if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, cm, &ops)) < 0) {
- snd_cmipci_free(cm);
- return err;
- }
+ scnprintf(card->longname, sizeof(card->longname),
+ "%s%s at %#lx, irq %i",
+ card->shortname, modelstr, cm->iobase, cm->irq);
if (cm->chip_version >= 39) {
val = snd_cmipci_read_b(cm, CM_REG_MPU_PCI + 1);
if (val != 0x00 && val != 0xff) {
- iomidi = cm->iobase + CM_REG_MPU_PCI;
+ if (mpu_port[dev])
+ iomidi = cm->iobase + CM_REG_MPU_PCI;
integrated_midi = 1;
}
}
@@ -3211,32 +3107,36 @@ static int snd_cmipci_create(struct snd_card *card, struct pci_dev *pci,
/* create pcm devices */
pcm_index = pcm_spdif_index = 0;
- if ((err = snd_cmipci_pcm_new(cm, pcm_index)) < 0)
+ err = snd_cmipci_pcm_new(cm, pcm_index);
+ if (err < 0)
return err;
pcm_index++;
- if ((err = snd_cmipci_pcm2_new(cm, pcm_index)) < 0)
+ err = snd_cmipci_pcm2_new(cm, pcm_index);
+ if (err < 0)
return err;
pcm_index++;
if (cm->can_ac3_hw || cm->can_ac3_sw) {
pcm_spdif_index = pcm_index;
- if ((err = snd_cmipci_pcm_spdif_new(cm, pcm_index)) < 0)
+ err = snd_cmipci_pcm_spdif_new(cm, pcm_index);
+ if (err < 0)
return err;
}
/* create mixer interface & switches */
- if ((err = snd_cmipci_mixer_new(cm, pcm_spdif_index)) < 0)
+ err = snd_cmipci_mixer_new(cm, pcm_spdif_index);
+ if (err < 0)
return err;
if (iomidi > 0) {
- if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
- iomidi,
- (integrated_midi ?
- MPU401_INFO_INTEGRATED : 0) |
- MPU401_INFO_IRQ_HOOK,
- -1, &cm->rmidi)) < 0) {
+ err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI,
+ iomidi,
+ (integrated_midi ?
+ MPU401_INFO_INTEGRATED : 0) |
+ MPU401_INFO_IRQ_HOOK,
+ -1, &cm->rmidi);
+ if (err < 0)
dev_err(cm->card->dev,
"no UART401 device at 0x%lx\n", iomidi);
- }
}
#ifdef USE_VAR48KRATE
@@ -3252,7 +3152,6 @@ static int snd_cmipci_create(struct snd_card *card, struct pci_dev *pci,
if (snd_cmipci_create_gameport(cm, dev) < 0)
snd_cmipci_clear_bit(cm, CM_REG_FUNCTRL1, CM_JYSTK_EN);
- *rcmipci = cm;
return 0;
}
@@ -3266,7 +3165,6 @@ static int snd_cmipci_probe(struct pci_dev *pci,
{
static int dev;
struct snd_card *card;
- struct cmipci *cm;
int err;
if (dev >= SNDRV_CARDS)
@@ -3276,60 +3174,54 @@ static int snd_cmipci_probe(struct pci_dev *pci,
return -ENOENT;
}
- err = snd_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
- 0, &card);
+ err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE,
+ sizeof(struct cmipci), &card);
if (err < 0)
return err;
switch (pci->device) {
case PCI_DEVICE_ID_CMEDIA_CM8738:
case PCI_DEVICE_ID_CMEDIA_CM8738B:
- strcpy(card->driver, "CMI8738");
+ strscpy(card->driver, "CMI8738");
break;
case PCI_DEVICE_ID_CMEDIA_CM8338A:
case PCI_DEVICE_ID_CMEDIA_CM8338B:
- strcpy(card->driver, "CMI8338");
+ strscpy(card->driver, "CMI8338");
break;
default:
- strcpy(card->driver, "CMIPCI");
+ strscpy(card->driver, "CMIPCI");
break;
}
- if ((err = snd_cmipci_create(card, pci, dev, &cm)) < 0) {
- snd_card_free(card);
- return err;
- }
- card->private_data = cm;
+ err = snd_cmipci_create(card, pci, dev);
+ if (err < 0)
+ goto error;
+
+ err = snd_card_register(card);
+ if (err < 0)
+ goto error;
- if ((err = snd_card_register(card)) < 0) {
- snd_card_free(card);
- return err;
- }
pci_set_drvdata(pci, card);
dev++;
return 0;
+ error:
+ snd_card_free(card);
+ return err;
}
-static void snd_cmipci_remove(struct pci_dev *pci)
-{
- snd_card_free(pci_get_drvdata(pci));
-}
-
-
-#ifdef CONFIG_PM_SLEEP
/*
* power management
*/
-static unsigned char saved_regs[] = {
+static const unsigned char saved_regs[] = {
CM_REG_FUNCTRL1, CM_REG_CHFORMAT, CM_REG_LEGACY_CTRL, CM_REG_MISC_CTRL,
- CM_REG_MIXER0, CM_REG_MIXER1, CM_REG_MIXER2, CM_REG_MIXER3, CM_REG_PLL,
+ CM_REG_MIXER0, CM_REG_MIXER1, CM_REG_MIXER2, CM_REG_AUX_VOL, CM_REG_PLL,
CM_REG_CH0_FRAME1, CM_REG_CH0_FRAME2,
CM_REG_CH1_FRAME1, CM_REG_CH1_FRAME2, CM_REG_EXT_MISC,
CM_REG_INT_STATUS, CM_REG_INT_HLDCLR, CM_REG_FUNCTRL0,
};
-static unsigned char saved_mixers[] = {
+static const unsigned char saved_mixers[] = {
SB_DSP4_MASTER_DEV, SB_DSP4_MASTER_DEV + 1,
SB_DSP4_PCM_DEV, SB_DSP4_PCM_DEV + 1,
SB_DSP4_SYNTH_DEV, SB_DSP4_SYNTH_DEV + 1,
@@ -3348,10 +3240,6 @@ static int snd_cmipci_suspend(struct device *dev)
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
- snd_pcm_suspend_all(cm->pcm);
- snd_pcm_suspend_all(cm->pcm2);
- snd_pcm_suspend_all(cm->pcm_spdif);
-
/* save registers */
for (i = 0; i < ARRAY_SIZE(saved_regs); i++)
cm->saved_regs[i] = snd_cmipci_read(cm, saved_regs[i]);
@@ -3385,19 +3273,14 @@ static int snd_cmipci_resume(struct device *dev)
return 0;
}
-static SIMPLE_DEV_PM_OPS(snd_cmipci_pm, snd_cmipci_suspend, snd_cmipci_resume);
-#define SND_CMIPCI_PM_OPS &snd_cmipci_pm
-#else
-#define SND_CMIPCI_PM_OPS NULL
-#endif /* CONFIG_PM_SLEEP */
+static DEFINE_SIMPLE_DEV_PM_OPS(snd_cmipci_pm, snd_cmipci_suspend, snd_cmipci_resume);
static struct pci_driver cmipci_driver = {
.name = KBUILD_MODNAME,
.id_table = snd_cmipci_ids,
.probe = snd_cmipci_probe,
- .remove = snd_cmipci_remove,
.driver = {
- .pm = SND_CMIPCI_PM_OPS,
+ .pm = &snd_cmipci_pm,
},
};