diff options
Diffstat (limited to 'sound/pci/es1968.c')
| -rw-r--r-- | sound/pci/es1968.c | 224 |
1 files changed, 84 insertions, 140 deletions
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 6a8a02a9ecf4..51aee2c4d461 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -473,9 +473,7 @@ struct esschan { /* linked list */ struct list_head list; -#ifdef CONFIG_PM_SLEEP u16 wc_map[4]; -#endif }; struct es1968 { @@ -526,9 +524,7 @@ struct es1968 { struct list_head substream_list; spinlock_t substream_lock; -#ifdef CONFIG_PM_SLEEP u16 apu_map[NR_APUS][NR_APU_REGS]; -#endif #ifdef SUPPORT_JOYSTICK struct gameport *gameport; @@ -578,10 +574,8 @@ static void __maestro_write(struct es1968 *chip, u16 reg, u16 data) static inline void maestro_write(struct es1968 *chip, u16 reg, u16 data) { - unsigned long flags; - spin_lock_irqsave(&chip->reg_lock, flags); + guard(spinlock_irqsave)(&chip->reg_lock); __maestro_write(chip, reg, data); - spin_unlock_irqrestore(&chip->reg_lock, flags); } /* no spinlock */ @@ -596,12 +590,8 @@ static u16 __maestro_read(struct es1968 *chip, u16 reg) static inline u16 maestro_read(struct es1968 *chip, u16 reg) { - unsigned long flags; - u16 result; - spin_lock_irqsave(&chip->reg_lock, flags); - result = __maestro_read(chip, reg); - spin_unlock_irqrestore(&chip->reg_lock, flags); - return result; + guard(spinlock_irqsave)(&chip->reg_lock); + return __maestro_read(chip, reg); } /* Wait for the codec bus to be free */ @@ -689,9 +679,7 @@ static void __apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 dat { if (snd_BUG_ON(channel >= NR_APUS)) return; -#ifdef CONFIG_PM_SLEEP chip->apu_map[channel][reg] = data; -#endif reg |= (channel << 4); apu_index_set(chip, reg); apu_data_set(chip, data); @@ -699,10 +687,8 @@ static void __apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 dat static void apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data) { - unsigned long flags; - spin_lock_irqsave(&chip->reg_lock, flags); + guard(spinlock_irqsave)(&chip->reg_lock); __apu_set_register(chip, channel, reg, data); - spin_unlock_irqrestore(&chip->reg_lock, flags); } static u16 __apu_get_register(struct es1968 *chip, u16 channel, u8 reg) @@ -716,62 +702,40 @@ static u16 __apu_get_register(struct es1968 *chip, u16 channel, u8 reg) static u16 apu_get_register(struct es1968 *chip, u16 channel, u8 reg) { - unsigned long flags; - u16 v; - spin_lock_irqsave(&chip->reg_lock, flags); - v = __apu_get_register(chip, channel, reg); - spin_unlock_irqrestore(&chip->reg_lock, flags); - return v; + guard(spinlock_irqsave)(&chip->reg_lock); + return __apu_get_register(chip, channel, reg); } #if 0 /* ASSP is not supported */ static void assp_set_register(struct es1968 *chip, u32 reg, u32 value) { - unsigned long flags; - - spin_lock_irqsave(&chip->reg_lock, flags); + guard(spinlock_irqsave),(&chip->reg_lock); outl(reg, chip->io_port + ASSP_INDEX); outl(value, chip->io_port + ASSP_DATA); - spin_unlock_irqrestore(&chip->reg_lock, flags); } static u32 assp_get_register(struct es1968 *chip, u32 reg) { - unsigned long flags; - u32 value; - - spin_lock_irqsave(&chip->reg_lock, flags); + guard(spinlock_irqsave)(&chip->reg_lock); outl(reg, chip->io_port + ASSP_INDEX); - value = inl(chip->io_port + ASSP_DATA); - spin_unlock_irqrestore(&chip->reg_lock, flags); - - return value; + return inl(chip->io_port + ASSP_DATA); } #endif static void wave_set_register(struct es1968 *chip, u16 reg, u16 value) { - unsigned long flags; - - spin_lock_irqsave(&chip->reg_lock, flags); + guard(spinlock_irqsave)(&chip->reg_lock); outw(reg, chip->io_port + WC_INDEX); outw(value, chip->io_port + WC_DATA); - spin_unlock_irqrestore(&chip->reg_lock, flags); } static u16 wave_get_register(struct es1968 *chip, u16 reg) { - unsigned long flags; - u16 value; - - spin_lock_irqsave(&chip->reg_lock, flags); + guard(spinlock_irqsave)(&chip->reg_lock); outw(reg, chip->io_port + WC_INDEX); - value = inw(chip->io_port + WC_DATA); - spin_unlock_irqrestore(&chip->reg_lock, flags); - - return value; + return inw(chip->io_port + WC_DATA); } /* ******************* @@ -930,7 +894,7 @@ static inline void snd_es1968_trigger_apu(struct es1968 *esm, int apu, int mode) static void snd_es1968_pcm_start(struct es1968 *chip, struct esschan *es) { - spin_lock(&chip->reg_lock); + guard(spinlock)(&chip->reg_lock); __apu_set_register(chip, es->apu[0], 5, es->base[0]); snd_es1968_trigger_apu(chip, es->apu[0], es->apu_mode[0]); if (es->mode == ESM_MODE_CAPTURE) { @@ -945,19 +909,17 @@ static void snd_es1968_pcm_start(struct es1968 *chip, struct esschan *es) snd_es1968_trigger_apu(chip, es->apu[3], es->apu_mode[3]); } } - spin_unlock(&chip->reg_lock); } static void snd_es1968_pcm_stop(struct es1968 *chip, struct esschan *es) { - spin_lock(&chip->reg_lock); + guard(spinlock)(&chip->reg_lock); snd_es1968_trigger_apu(chip, es->apu[0], 0); snd_es1968_trigger_apu(chip, es->apu[1], 0); if (es->mode == ESM_MODE_CAPTURE) { snd_es1968_trigger_apu(chip, es->apu[2], 0); snd_es1968_trigger_apu(chip, es->apu[3], 0); } - spin_unlock(&chip->reg_lock); } /* set the wavecache control reg */ @@ -976,9 +938,7 @@ static void snd_es1968_program_wavecache(struct es1968 *chip, struct esschan *es /* set the wavecache control reg */ wave_set_register(chip, es->apu[channel] << 3, tmpval); -#ifdef CONFIG_PM_SLEEP es->wc_map[channel] = tmpval; -#endif } @@ -989,7 +949,6 @@ static void snd_es1968_playback_setup(struct es1968 *chip, struct esschan *es, int high_apu = 0; int channel, apu; int i, size; - unsigned long flags; u32 freq; size = es->dma_size >> es->wav_shift; @@ -1059,12 +1018,12 @@ static void snd_es1968_playback_setup(struct es1968 *chip, struct esschan *es, apu_set_register(chip, apu, 10, 0x8F08); } - spin_lock_irqsave(&chip->reg_lock, flags); - /* clear WP interrupts */ - outw(1, chip->io_port + 0x04); - /* enable WP ints */ - outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ); - spin_unlock_irqrestore(&chip->reg_lock, flags); + scoped_guard(spinlock_irqsave, &chip->reg_lock) { + /* clear WP interrupts */ + outw(1, chip->io_port + 0x04); + /* enable WP ints */ + outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ); + } freq = runtime->rate; /* set frequency */ @@ -1135,7 +1094,6 @@ static void snd_es1968_capture_setup(struct es1968 *chip, struct esschan *es, { int size; u32 freq; - unsigned long flags; size = es->dma_size >> es->wav_shift; @@ -1187,12 +1145,11 @@ static void snd_es1968_capture_setup(struct es1968 *chip, struct esschan *es, snd_es1968_apu_set_freq(chip, es->apu[2], freq); snd_es1968_apu_set_freq(chip, es->apu[3], freq); - spin_lock_irqsave(&chip->reg_lock, flags); + guard(spinlock_irqsave)(&chip->reg_lock); /* clear WP interrupts */ outw(1, chip->io_port + 0x04); /* enable WP ints */ outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ); - spin_unlock_irqrestore(&chip->reg_lock, flags); } /******************* @@ -1236,7 +1193,7 @@ static int snd_es1968_pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct es1968 *chip = snd_pcm_substream_chip(substream); struct esschan *es = substream->runtime->private_data; - spin_lock(&chip->substream_lock); + guard(spinlock)(&chip->substream_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: @@ -1257,7 +1214,6 @@ static int snd_es1968_pcm_trigger(struct snd_pcm_substream *substream, int cmd) snd_es1968_bob_dec(chip); break; } - spin_unlock(&chip->substream_lock); return 0; } @@ -1326,12 +1282,11 @@ static int calc_available_memory_size(struct es1968 *chip) int max_size = 0; struct esm_memory *buf; - mutex_lock(&chip->memory_mutex); + guard(mutex)(&chip->memory_mutex); list_for_each_entry(buf, &chip->buf_list, list) { if (buf->empty && buf->buf.bytes > max_size) max_size = buf->buf.bytes; } - mutex_unlock(&chip->memory_mutex); if (max_size >= 128*1024) max_size = 127*1024; return max_size; @@ -1343,21 +1298,18 @@ static struct esm_memory *snd_es1968_new_memory(struct es1968 *chip, int size) struct esm_memory *buf; size = ALIGN(size, ESM_MEM_ALIGN); - mutex_lock(&chip->memory_mutex); + guard(mutex)(&chip->memory_mutex); list_for_each_entry(buf, &chip->buf_list, list) { if (buf->empty && buf->buf.bytes >= size) goto __found; } - mutex_unlock(&chip->memory_mutex); return NULL; __found: if (buf->buf.bytes > size) { struct esm_memory *chunk = kmalloc(sizeof(*chunk), GFP_KERNEL); - if (chunk == NULL) { - mutex_unlock(&chip->memory_mutex); + if (chunk == NULL) return NULL; - } chunk->buf = buf->buf; chunk->buf.bytes -= size; chunk->buf.area += size; @@ -1367,7 +1319,6 @@ __found: list_add(&chunk->list, &buf->list); } buf->empty = 0; - mutex_unlock(&chip->memory_mutex); return buf; } @@ -1376,7 +1327,7 @@ static void snd_es1968_free_memory(struct es1968 *chip, struct esm_memory *buf) { struct esm_memory *chunk; - mutex_lock(&chip->memory_mutex); + guard(mutex)(&chip->memory_mutex); buf->empty = 1; if (buf->list.prev != &chip->buf_list) { chunk = list_entry(buf->list.prev, struct esm_memory, list); @@ -1395,7 +1346,6 @@ static void snd_es1968_free_memory(struct es1968 *chip, struct esm_memory *buf) kfree(chunk); } } - mutex_unlock(&chip->memory_mutex); } static void snd_es1968_free_dmabuf(struct es1968 *chip) @@ -1557,9 +1507,8 @@ static int snd_es1968_playback_open(struct snd_pcm_substream *substream) runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = calc_available_memory_size(chip); - spin_lock_irq(&chip->substream_lock); + guard(spinlock_irq)(&chip->substream_lock); list_add(&es->list, &chip->substream_list); - spin_unlock_irq(&chip->substream_lock); return 0; } @@ -1569,7 +1518,7 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct es1968 *chip = snd_pcm_substream_chip(substream); struct esschan *es; - int apu1, apu2; + int err, apu1, apu2; apu1 = snd_es1968_alloc_apu_pair(chip, ESM_APU_PCM_CAPTURE); if (apu1 < 0) @@ -1613,11 +1562,12 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream) runtime->hw = snd_es1968_capture; runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */ - snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES); + err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES); + if (err < 0) + return err; - spin_lock_irq(&chip->substream_lock); + guard(spinlock_irq)(&chip->substream_lock); list_add(&es->list, &chip->substream_list); - spin_unlock_irq(&chip->substream_lock); return 0; } @@ -1630,9 +1580,9 @@ static int snd_es1968_playback_close(struct snd_pcm_substream *substream) if (substream->runtime->private_data == NULL) return 0; es = substream->runtime->private_data; - spin_lock_irq(&chip->substream_lock); - list_del(&es->list); - spin_unlock_irq(&chip->substream_lock); + scoped_guard(spinlock_irq, &chip->substream_lock) { + list_del(&es->list); + } snd_es1968_free_apu_pair(chip, es->apu[0]); kfree(es); @@ -1647,9 +1597,9 @@ static int snd_es1968_capture_close(struct snd_pcm_substream *substream) if (substream->runtime->private_data == NULL) return 0; es = substream->runtime->private_data; - spin_lock_irq(&chip->substream_lock); - list_del(&es->list); - spin_unlock_irq(&chip->substream_lock); + scoped_guard(spinlock_irq, &chip->substream_lock) { + list_del(&es->list); + } snd_es1968_free_memory(chip, es->mixbuf); snd_es1968_free_apu_pair(chip, es->apu[0]); snd_es1968_free_apu_pair(chip, es->apu[2]); @@ -1730,29 +1680,29 @@ static void es1968_measure_clock(struct es1968 *chip) apu_set_register(chip, apu, 9, 0xD000); apu_set_register(chip, apu, 10, 0x8F08); apu_set_register(chip, apu, 11, 0x0000); - spin_lock_irq(&chip->reg_lock); - outw(1, chip->io_port + 0x04); /* clear WP interrupts */ - outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ); /* enable WP ints */ - spin_unlock_irq(&chip->reg_lock); + scoped_guard(spinlock_irq, &chip->reg_lock) { + outw(1, chip->io_port + 0x04); /* clear WP interrupts */ + outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ); /* enable WP ints */ + } snd_es1968_apu_set_freq(chip, apu, ((unsigned int)48000 << 16) / chip->clock); /* 48000 Hz */ chip->in_measurement = 1; chip->measure_apu = apu; - spin_lock_irq(&chip->reg_lock); - snd_es1968_bob_inc(chip, ESM_BOB_FREQ); - __apu_set_register(chip, apu, 5, pa & 0xffff); - snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR); - start_time = ktime_get(); - spin_unlock_irq(&chip->reg_lock); + scoped_guard(spinlock_irq, &chip->reg_lock) { + snd_es1968_bob_inc(chip, ESM_BOB_FREQ); + __apu_set_register(chip, apu, 5, pa & 0xffff); + snd_es1968_trigger_apu(chip, apu, ESM_APU_16BITLINEAR); + start_time = ktime_get(); + } msleep(50); - spin_lock_irq(&chip->reg_lock); - offset = __apu_get_register(chip, apu, 5); - stop_time = ktime_get(); - snd_es1968_trigger_apu(chip, apu, 0); /* stop */ - snd_es1968_bob_dec(chip); - chip->in_measurement = 0; - spin_unlock_irq(&chip->reg_lock); + scoped_guard(spinlock_irq, &chip->reg_lock) { + offset = __apu_get_register(chip, apu, 5); + stop_time = ktime_get(); + snd_es1968_trigger_apu(chip, apu, 0); /* stop */ + snd_es1968_bob_dec(chip); + chip->in_measurement = 0; + } /* check the current position */ offset -= (pa & 0xffff); @@ -1818,7 +1768,7 @@ snd_es1968_pcm(struct es1968 *chip, int device) pcm->info_flags = 0; - strcpy(pcm->name, "ESS Maestro"); + strscpy(pcm->name, "ESS Maestro"); chip->pcm = pcm; @@ -1976,15 +1926,15 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id) if (event & ESM_SOUND_IRQ) { struct esschan *es; - spin_lock(&chip->substream_lock); - list_for_each_entry(es, &chip->substream_list, list) { - if (es->running) { - snd_es1968_update_pcm(chip, es); - if (es->fmt & ESS_FMT_STEREO) - snd_es1968_suppress_jitter(chip, es); + scoped_guard(spinlock, &chip->substream_lock) { + list_for_each_entry(es, &chip->substream_list, list) { + if (es->running) { + snd_es1968_update_pcm(chip, es); + if (es->fmt & ESS_FMT_STEREO) + snd_es1968_suppress_jitter(chip, es); + } } } - spin_unlock(&chip->substream_lock); if (chip->in_measurement) { unsigned int curp = __apu_get_register(chip, chip->measure_apu, 5); if (curp < chip->measure_lastpos) @@ -2005,9 +1955,6 @@ snd_es1968_mixer(struct es1968 *chip) { struct snd_ac97_bus *pbus; struct snd_ac97_template ac97; -#ifndef CONFIG_SND_ES1968_INPUT - struct snd_ctl_elem_id elem_id; -#endif int err; static const struct snd_ac97_bus_ops ops = { .write = snd_es1968_ac97_write, @@ -2027,14 +1974,10 @@ snd_es1968_mixer(struct es1968 *chip) #ifndef CONFIG_SND_ES1968_INPUT /* attach master switch / volumes for h/w volume control */ - memset(&elem_id, 0, sizeof(elem_id)); - elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; - strcpy(elem_id.name, "Master Playback Switch"); - chip->master_switch = snd_ctl_find_id(chip->card, &elem_id); - memset(&elem_id, 0, sizeof(elem_id)); - elem_id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; - strcpy(elem_id.name, "Master Playback Volume"); - chip->master_volume = snd_ctl_find_id(chip->card, &elem_id); + chip->master_switch = snd_ctl_find_id_mixer(chip->card, + "Master Playback Switch"); + chip->master_volume = snd_ctl_find_id_mixer(chip->card, + "Master Playback Volume"); #endif return 0; @@ -2363,7 +2306,6 @@ static void snd_es1968_start_irq(struct es1968 *chip) outw(w, chip->io_port + ESM_PORT_HOST_IRQ); } -#ifdef CONFIG_PM_SLEEP /* * PM support */ @@ -2425,11 +2367,7 @@ static int es1968_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(es1968_pm, es1968_suspend, es1968_resume); -#define ES1968_PM_OPS &es1968_pm -#else -#define ES1968_PM_OPS NULL -#endif /* CONFIG_PM_SLEEP */ +static DEFINE_SIMPLE_DEV_PM_OPS(es1968_pm, es1968_suspend, es1968_resume); #ifdef SUPPORT_JOYSTICK #define JOYSTICK_ADDR 0x200 @@ -2667,7 +2605,7 @@ static int snd_es1968_create(struct snd_card *card, chip->playback_streams = play_streams; chip->capture_streams = capt_streams; - err = pci_request_regions(pci, "ESS Maestro"); + err = pcim_request_all_regions(pci, "ESS Maestro"); if (err < 0) return err; chip->io_port = pci_resource_start(pci, 0); @@ -2741,8 +2679,8 @@ static int snd_es1968_create(struct snd_card *card, /* */ -static int snd_es1968_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) +static int __snd_es1968_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) { static int dev; struct snd_card *card; @@ -2779,16 +2717,16 @@ static int snd_es1968_probe(struct pci_dev *pci, switch (chip->type) { case TYPE_MAESTRO2E: - strcpy(card->driver, "ES1978"); - strcpy(card->shortname, "ESS ES1978 (Maestro 2E)"); + strscpy(card->driver, "ES1978"); + strscpy(card->shortname, "ESS ES1978 (Maestro 2E)"); break; case TYPE_MAESTRO2: - strcpy(card->driver, "ES1968"); - strcpy(card->shortname, "ESS ES1968 (Maestro 2)"); + strscpy(card->driver, "ES1968"); + strscpy(card->shortname, "ESS ES1968 (Maestro 2)"); break; case TYPE_MAESTRO: - strcpy(card->driver, "ESM1"); - strcpy(card->shortname, "ESS Maestro 1"); + strscpy(card->driver, "ESM1"); + strscpy(card->shortname, "ESS Maestro 1"); break; } @@ -2848,12 +2786,18 @@ static int snd_es1968_probe(struct pci_dev *pci, return 0; } +static int snd_es1968_probe(struct pci_dev *pci, + const struct pci_device_id *pci_id) +{ + return snd_card_free_on_error(&pci->dev, __snd_es1968_probe(pci, pci_id)); +} + static struct pci_driver es1968_driver = { .name = KBUILD_MODNAME, .id_table = snd_es1968_ids, .probe = snd_es1968_probe, .driver = { - .pm = ES1968_PM_OPS, + .pm = &es1968_pm, }, }; |
