Merge branch 'topic/misc' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6 into devel

This commit is contained in:
Jaroslav Kysela 2010-02-16 11:25:03 +01:00
commit b8f1f5983f
124 changed files with 3446 additions and 1330 deletions

View file

@ -482,6 +482,9 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
reference_rate - reference sample rate, 44100 or 48000 (default)
multiple - multiple to ref. sample rate, 1 or 2 (default)
subsystem - override the PCI SSID for probing; the value
consists of SSVID << 16 | SSDID. The default is
zero, which means no override.
This module supports multiple cards.
@ -1123,6 +1126,21 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
This module supports multiple cards, autoprobe and ISA PnP.
Module snd-jazz16
-------------------
Module for Media Vision Jazz16 chipset. The chipset consists of 3 chips:
MVD1216 + MVA416 + MVA514.
port - port # for SB DSP chip (0x210,0x220,0x230,0x240,0x250,0x260)
irq - IRQ # for SB DSP chip (3,5,7,9,10,15)
dma8 - DMA # for SB DSP chip (1,3)
dma16 - DMA # for SB DSP chip (5,7)
mpu_port - MPU-401 port # (0x300,0x310,0x320,0x330)
mpu_irq - MPU-401 irq # (2,3,5,7)
This module supports multiple cards.
Module snd-korg1212
-------------------
@ -1791,6 +1809,13 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
The power-management is supported.
Module snd-ua101
----------------
Module for the Edirol UA-101 audio/MIDI interface.
This module supports multiple devices, autoprobe and hotplugging.
Module snd-usb-audio
--------------------

View file

@ -458,5 +458,8 @@ struct snd_pci_quirk {
const struct snd_pci_quirk *
snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list);
const struct snd_pci_quirk *
snd_pci_quirk_lookup_id(u16 vendor, u16 device,
const struct snd_pci_quirk *list);
#endif /* __SOUND_CORE_H */

View file

@ -118,9 +118,11 @@ struct dsp_scb_descriptor {
struct snd_info_entry *proc_info;
int ref_count;
spinlock_t lock;
int deleted;
u16 volume[2];
unsigned int deleted :1;
unsigned int updated :1;
unsigned int volume_set :1;
};
struct dsp_task_descriptor {

View file

@ -915,6 +915,44 @@ int snd_pcm_lib_preallocate_pages_for_all(struct snd_pcm *pcm,
int snd_pcm_lib_malloc_pages(struct snd_pcm_substream *substream, size_t size);
int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream);
int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream,
size_t size, gfp_t gfp_flags);
int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream);
struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream,
unsigned long offset);
#if 0 /* for kernel-doc */
/**
* snd_pcm_lib_alloc_vmalloc_buffer - allocate virtual DMA buffer
* @substream: the substream to allocate the buffer to
* @size: the requested buffer size, in bytes
*
* Allocates the PCM substream buffer using vmalloc(), i.e., the memory is
* contiguous in kernel virtual space, but not in physical memory. Use this
* if the buffer is accessed by kernel code but not by device DMA.
*
* Returns 1 if the buffer was changed, 0 if not changed, or a negative error
* code.
*/
static int snd_pcm_lib_alloc_vmalloc_buffer
(struct snd_pcm_substream *substream, size_t size);
/**
* snd_pcm_lib_alloc_vmalloc_32_buffer - allocate 32-bit-addressable buffer
* @substream: the substream to allocate the buffer to
* @size: the requested buffer size, in bytes
*
* This function works like snd_pcm_lib_alloc_vmalloc_buffer(), but uses
* vmalloc_32(), i.e., the pages are allocated from 32-bit-addressable memory.
*/
static int snd_pcm_lib_alloc_vmalloc_32_buffer
(struct snd_pcm_substream *substream, size_t size);
#endif
#define snd_pcm_lib_alloc_vmalloc_buffer(subs, size) \
_snd_pcm_lib_alloc_vmalloc_buffer \
(subs, size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO)
#define snd_pcm_lib_alloc_vmalloc_32_buffer(subs, size) \
_snd_pcm_lib_alloc_vmalloc_buffer \
(subs, size, GFP_KERNEL | GFP_DMA32 | __GFP_ZERO)
#ifdef CONFIG_SND_DMA_SGBUF
/*
* SG-buffer handling
@ -985,6 +1023,10 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s
#define snd_pcm_lib_mmap_iomem NULL
#endif
int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream,
struct vm_area_struct *area);
#define snd_pcm_lib_mmap_vmalloc snd_pcm_lib_mmap_noncached
static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max)
{
*max = dma < 4 ? 64 * 1024 : 128 * 1024;

View file

@ -33,6 +33,7 @@ enum sb_hw_type {
SB_HW_20,
SB_HW_201,
SB_HW_PRO,
SB_HW_JAZZ16, /* Media Vision Jazz16 */
SB_HW_16,
SB_HW_16CSP, /* SB16 with CSP chip */
SB_HW_ALS100, /* Avance Logic ALS100 chip */

View file

@ -100,6 +100,35 @@ EXPORT_SYMBOL_GPL(__snd_printk);
#ifdef CONFIG_PCI
#include <linux/pci.h>
/**
* snd_pci_quirk_lookup_id - look up a PCI SSID quirk list
* @vendor: PCI SSV id
* @device: PCI SSD id
* @list: quirk list, terminated by a null entry
*
* Look through the given quirk list and finds a matching entry
* with the same PCI SSID. When subdevice is 0, all subdevice
* values may match.
*
* Returns the matched entry pointer, or NULL if nothing matched.
*/
const struct snd_pci_quirk *
snd_pci_quirk_lookup_id(u16 vendor, u16 device,
const struct snd_pci_quirk *list)
{
const struct snd_pci_quirk *q;
for (q = list; q->subvendor; q++) {
if (q->subvendor != vendor)
continue;
if (!q->subdevice ||
(device & q->subdevice_mask) == q->subdevice)
return q;
}
return NULL;
}
EXPORT_SYMBOL(snd_pci_quirk_lookup_id);
/**
* snd_pci_quirk_lookup - look up a PCI SSID quirk list
* @pci: pci_dev handle
@ -114,16 +143,9 @@ EXPORT_SYMBOL_GPL(__snd_printk);
const struct snd_pci_quirk *
snd_pci_quirk_lookup(struct pci_dev *pci, const struct snd_pci_quirk *list)
{
const struct snd_pci_quirk *q;
for (q = list; q->subvendor; q++) {
if (q->subvendor != pci->subsystem_vendor)
continue;
if (!q->subdevice ||
(pci->subsystem_device & q->subdevice_mask) == q->subdevice)
return q;
}
return NULL;
return snd_pci_quirk_lookup_id(pci->subsystem_vendor,
pci->subsystem_device,
list);
}
EXPORT_SYMBOL(snd_pci_quirk_lookup);
#endif

View file

@ -766,10 +766,13 @@ int snd_interval_ratnum(struct snd_interval *i,
unsigned int rats_count, struct snd_ratnum *rats,
unsigned int *nump, unsigned int *denp)
{
unsigned int best_num, best_diff, best_den;
unsigned int best_num, best_den;
int best_diff;
unsigned int k;
struct snd_interval t;
int err;
unsigned int result_num, result_den;
int result_diff;
best_num = best_den = best_diff = 0;
for (k = 0; k < rats_count; ++k) {
@ -791,6 +794,8 @@ int snd_interval_ratnum(struct snd_interval *i,
den -= r;
}
diff = num - q * den;
if (diff < 0)
diff = -diff;
if (best_num == 0 ||
diff * best_den < best_diff * den) {
best_diff = diff;
@ -805,6 +810,9 @@ int snd_interval_ratnum(struct snd_interval *i,
t.min = div_down(best_num, best_den);
t.openmin = !!(best_num % best_den);
result_num = best_num;
result_diff = best_diff;
result_den = best_den;
best_num = best_den = best_diff = 0;
for (k = 0; k < rats_count; ++k) {
unsigned int num = rats[k].num;
@ -827,6 +835,8 @@ int snd_interval_ratnum(struct snd_interval *i,
den += rats[k].den_step - r;
}
diff = q * den - num;
if (diff < 0)
diff = -diff;
if (best_num == 0 ||
diff * best_den < best_diff * den) {
best_diff = diff;
@ -846,10 +856,14 @@ int snd_interval_ratnum(struct snd_interval *i,
return err;
if (snd_interval_single(i)) {
if (best_diff * result_den < result_diff * best_den) {
result_num = best_num;
result_den = best_den;
}
if (nump)
*nump = best_num;
*nump = result_num;
if (denp)
*denp = best_den;
*denp = result_den;
}
return err;
}

View file

@ -23,6 +23,7 @@
#include <linux/time.h>
#include <linux/init.h>
#include <linux/moduleparam.h>
#include <linux/vmalloc.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/info.h>
@ -434,3 +435,57 @@ int snd_pcm_lib_free_pages(struct snd_pcm_substream *substream)
}
EXPORT_SYMBOL(snd_pcm_lib_free_pages);
int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream,
size_t size, gfp_t gfp_flags)
{
struct snd_pcm_runtime *runtime;
if (PCM_RUNTIME_CHECK(substream))
return -EINVAL;
runtime = substream->runtime;
if (runtime->dma_area) {
if (runtime->dma_bytes >= size)
return 0; /* already large enough */
vfree(runtime->dma_area);
}
runtime->dma_area = __vmalloc(size, gfp_flags, PAGE_KERNEL);
if (!runtime->dma_area)
return -ENOMEM;
runtime->dma_bytes = size;
return 1;
}
EXPORT_SYMBOL(_snd_pcm_lib_alloc_vmalloc_buffer);
/**
* snd_pcm_lib_free_vmalloc_buffer - free vmalloc buffer
* @substream: the substream with a buffer allocated by
* snd_pcm_lib_alloc_vmalloc_buffer()
*/
int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream)
{
struct snd_pcm_runtime *runtime;
if (PCM_RUNTIME_CHECK(substream))
return -EINVAL;
runtime = substream->runtime;
vfree(runtime->dma_area);
runtime->dma_area = NULL;
return 0;
}
EXPORT_SYMBOL(snd_pcm_lib_free_vmalloc_buffer);
/**
* snd_pcm_lib_get_vmalloc_page - map vmalloc buffer offset to page struct
* @substream: the substream with a buffer allocated by
* snd_pcm_lib_alloc_vmalloc_buffer()
* @offset: offset in the buffer
*
* This function is to be used as the page callback in the PCM ops.
*/
struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream,
unsigned long offset)
{
return vmalloc_to_page(substream->runtime->dma_area + offset);
}
EXPORT_SYMBOL(snd_pcm_lib_get_vmalloc_page);

View file

@ -3200,9 +3200,7 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
long size;
unsigned long offset;
#ifdef pgprot_noncached
area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
#endif
area->vm_flags |= VM_IO;
size = area->vm_end - area->vm_start;
offset = area->vm_pgoff << PAGE_SHIFT;
@ -3216,6 +3214,15 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
EXPORT_SYMBOL(snd_pcm_lib_mmap_iomem);
#endif /* SNDRV_PCM_INFO_MMAP */
/* mmap callback with pgprot_noncached */
int snd_pcm_lib_mmap_noncached(struct snd_pcm_substream *substream,
struct vm_area_struct *area)
{
area->vm_page_prot = pgprot_noncached(area->vm_page_prot);
return snd_pcm_default_mmap(substream, area);
}
EXPORT_SYMBOL(snd_pcm_lib_mmap_noncached);
/*
* mmap DMA buffer
*/

View file

@ -2190,7 +2190,7 @@ static int snd_seq_do_ioctl(struct snd_seq_client *client, unsigned int cmd,
if (p->cmd == cmd)
return p->func(client, arg);
}
snd_printd("seq unknown ioctl() 0x%x (type='%c', number=0x%2x)\n",
snd_printd("seq unknown ioctl() 0x%x (type='%c', number=0x%02x)\n",
cmd, _IOC_TYPE(cmd), _IOC_NR(cmd));
return -ENOTTY;
}

View file

@ -46,7 +46,6 @@
*/
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <sound/core.h>
#include <sound/asoundef.h>
@ -55,55 +54,6 @@
#include "vx_cmd.h"
/*
* we use a vmalloc'ed (sg-)buffer
*/
/* get the physical page pointer on the given offset */
static struct page *snd_pcm_get_vmalloc_page(struct snd_pcm_substream *subs,
unsigned long offset)
{
void *pageptr = subs->runtime->dma_area + offset;
return vmalloc_to_page(pageptr);
}
/*
* allocate a buffer via vmalloc_32().
* called from hw_params
* NOTE: this may be called not only once per pcm open!
*/
static int snd_pcm_alloc_vmalloc_buffer(struct snd_pcm_substream *subs, size_t size)
{
struct snd_pcm_runtime *runtime = subs->runtime;
if (runtime->dma_area) {
/* already allocated */
if (runtime->dma_bytes >= size)
return 0; /* already enough large */
vfree(runtime->dma_area);
}
runtime->dma_area = vmalloc_32(size);
if (! runtime->dma_area)
return -ENOMEM;
memset(runtime->dma_area, 0, size);
runtime->dma_bytes = size;
return 1; /* changed */
}
/*
* free the buffer.
* called from hw_free callback
* NOTE: this may be called not only once per pcm open!
*/
static int snd_pcm_free_vmalloc_buffer(struct snd_pcm_substream *subs)
{
struct snd_pcm_runtime *runtime = subs->runtime;
vfree(runtime->dma_area);
runtime->dma_area = NULL;
return 0;
}
/*
* read three pending pcm bytes via inb()
*/
@ -865,7 +815,8 @@ static snd_pcm_uframes_t vx_pcm_playback_pointer(struct snd_pcm_substream *subs)
static int vx_pcm_hw_params(struct snd_pcm_substream *subs,
struct snd_pcm_hw_params *hw_params)
{
return snd_pcm_alloc_vmalloc_buffer(subs, params_buffer_bytes(hw_params));
return snd_pcm_lib_alloc_vmalloc_32_buffer
(subs, params_buffer_bytes(hw_params));
}
/*
@ -873,7 +824,7 @@ static int vx_pcm_hw_params(struct snd_pcm_substream *subs,
*/
static int vx_pcm_hw_free(struct snd_pcm_substream *subs)
{
return snd_pcm_free_vmalloc_buffer(subs);
return snd_pcm_lib_free_vmalloc_buffer(subs);
}
/*
@ -953,7 +904,8 @@ static struct snd_pcm_ops vx_pcm_playback_ops = {
.prepare = vx_pcm_prepare,
.trigger = vx_pcm_trigger,
.pointer = vx_pcm_playback_pointer,
.page = snd_pcm_get_vmalloc_page,
.page = snd_pcm_lib_get_vmalloc_page,
.mmap = snd_pcm_lib_mmap_vmalloc,
};
@ -1173,7 +1125,8 @@ static struct snd_pcm_ops vx_pcm_capture_ops = {
.prepare = vx_pcm_prepare,
.trigger = vx_pcm_trigger,
.pointer = vx_pcm_capture_pointer,
.page = snd_pcm_get_vmalloc_page,
.page = snd_pcm_lib_get_vmalloc_page,
.mmap = snd_pcm_lib_mmap_vmalloc,
};

View file

@ -63,15 +63,16 @@ config SND_AD1848
will be called snd-ad1848.
config SND_ALS100
tristate "Avance Logic ALS100/ALS120"
tristate "Diamond Tech. DT-019x and Avance Logic ALSxxx"
depends on PNP
select ISAPNP
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_SB16_DSP
help
Say Y here to include support for soundcards based on Avance
Logic ALS100, ALS110, ALS120 and ALS200 chips.
Say Y here to include support for soundcards based on the
Diamond Technologies DT-019X or Avance Logic chips: ALS007,
ALS100, ALS110, ALS120 and ALS200 chips.
To compile this driver as a module, choose M here: the module
will be called snd-als100.
@ -127,20 +128,6 @@ config SND_CS4236
To compile this driver as a module, choose M here: the module
will be called snd-cs4236.
config SND_DT019X
tristate "Diamond Technologies DT-019X, Avance Logic ALS-007"
depends on PNP
select ISAPNP
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_SB16_DSP
help
Say Y here to include support for soundcards based on the
Diamond Technologies DT-019X or Avance Logic ALS-007 chips.
To compile this driver as a module, choose M here: the module
will be called snd-dt019x.
config SND_ES968
tristate "Generic ESS ES968 driver"
depends on PNP
@ -252,6 +239,22 @@ config SND_INTERWAVE_STB
To compile this driver as a module, choose M here: the module
will be called snd-interwave-stb.
config SND_JAZZ16
tristate "Media Vision Jazz16 card and compatibles"
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_SB8_DSP
help
Say Y here to include support for soundcards based on the
Media Vision Jazz16 chipset: digital chip MVD1216 (Jazz16),
codec MVA416 (CS4216) and mixer MVA514 (ICS2514).
Media Vision's Jazz16 cards were sold under names Pro Sonic 16,
Premium 3-D and Pro 3-D. There were also OEMs cards with the
Jazz16 chipset.
To compile this driver as a module, choose M here: the module
will be called snd-jazz16.
config SND_OPL3SA2
tristate "Yamaha OPL3-SA2/SA3"
select SND_OPL3_LIB

View file

@ -7,7 +7,6 @@ snd-adlib-objs := adlib.o
snd-als100-objs := als100.o
snd-azt2320-objs := azt2320.o
snd-cmi8330-objs := cmi8330.o
snd-dt019x-objs := dt019x.o
snd-es18xx-objs := es18xx.o
snd-opl3sa2-objs := opl3sa2.o
snd-sc6000-objs := sc6000.o
@ -19,7 +18,6 @@ obj-$(CONFIG_SND_ADLIB) += snd-adlib.o
obj-$(CONFIG_SND_ALS100) += snd-als100.o
obj-$(CONFIG_SND_AZT2320) += snd-azt2320.o
obj-$(CONFIG_SND_CMI8330) += snd-cmi8330.o
obj-$(CONFIG_SND_DT019X) += snd-dt019x.o
obj-$(CONFIG_SND_ES18XX) += snd-es18xx.o
obj-$(CONFIG_SND_OPL3SA2) += snd-opl3sa2.o
obj-$(CONFIG_SND_SC6000) += snd-sc6000.o

View file

@ -2,9 +2,13 @@
/*
card-als100.c - driver for Avance Logic ALS100 based soundcards.
Copyright (C) 1999-2000 by Massimo Piccioni <dafastidio@libero.it>
Copyright (C) 1999-2002 by Massimo Piccioni <dafastidio@libero.it>
Thanks to Pierfrancesco 'qM2' Passerini.
Generalised for soundcards based on DT-0196 and ALS-007 chips
by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>: June 2002.
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
@ -33,10 +37,10 @@
#define PFX "als100: "
MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
MODULE_DESCRIPTION("Avance Logic ALS1X0");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS100 - PRO16PNP},"
MODULE_DESCRIPTION("Avance Logic ALS007/ALS1X0");
MODULE_SUPPORTED_DEVICE("{{Diamond Technologies DT-019X},"
"{Avance Logic ALS-007}}"
"{{Avance Logic,ALS100 - PRO16PNP},"
"{Avance Logic,ALS110},"
"{Avance Logic,ALS120},"
"{Avance Logic,ALS200},"
@ -45,9 +49,12 @@ MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS100 - PRO16PNP},"
"{Avance Logic,ALS120},"
"{RTL,RTL3000}}");
MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
MODULE_LICENSE("GPL");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
@ -57,14 +64,15 @@ static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for als100 based soundcard.");
MODULE_PARM_DESC(index, "Index value for Avance Logic based soundcard.");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for als100 based soundcard.");
MODULE_PARM_DESC(id, "ID string for Avance Logic based soundcard.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable als100 based soundcard.");
MODULE_PARM_DESC(enable, "Enable Avance Logic based soundcard.");
MODULE_ALIAS("snd-dt019x");
struct snd_card_als100 {
int dev_no;
struct pnp_dev *dev;
struct pnp_dev *devmpu;
struct pnp_dev *devopl;
@ -72,25 +80,43 @@ struct snd_card_als100 {
};
static struct pnp_card_device_id snd_als100_pnpids[] = {
/* DT197A30 */
{ .id = "RWB1688",
.devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
.driver_data = SB_HW_DT019X },
/* DT0196 / ALS-007 */
{ .id = "ALS0007",
.devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
.driver_data = SB_HW_DT019X },
/* ALS100 - PRO16PNP */
{ .id = "ALS0001", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } } },
{ .id = "ALS0001",
.devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" } },
.driver_data = SB_HW_ALS100 },
/* ALS110 - MF1000 - Digimate 3D Sound */
{ .id = "ALS0110", .devs = { { "@@@1001" }, { "@X@1001" }, { "@H@1001" } } },
{ .id = "ALS0110",
.devs = { { "@@@1001" }, { "@X@1001" }, { "@H@1001" } },
.driver_data = SB_HW_ALS100 },
/* ALS120 */
{ .id = "ALS0120", .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } } },
{ .id = "ALS0120",
.devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } },
.driver_data = SB_HW_ALS100 },
/* ALS200 */
{ .id = "ALS0200", .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0001" } } },
{ .id = "ALS0200",
.devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0001" } },
.driver_data = SB_HW_ALS100 },
/* ALS200 OEM */
{ .id = "ALS0200", .devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0020" } } },
{ .id = "ALS0200",
.devs = { { "@@@0020" }, { "@X@0020" }, { "@H@0020" } },
.driver_data = SB_HW_ALS100 },
/* RTL3000 */
{ .id = "RTL3000", .devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } } },
{ .id = "", } /* end */
{ .id = "RTL3000",
.devs = { { "@@@2001" }, { "@X@2001" }, { "@H@2001" } },
.driver_data = SB_HW_ALS100 },
{ .id = "" } /* end */
};
MODULE_DEVICE_TABLE(pnp_card, snd_als100_pnpids);
#define DRIVER_NAME "snd-card-als100"
static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard,
struct pnp_card_link *card,
const struct pnp_card_device_id *id)
@ -113,8 +139,12 @@ static int __devinit snd_card_als100_pnp(int dev, struct snd_card_als100 *acard,
return err;
}
port[dev] = pnp_port_start(pdev, 0);
dma8[dev] = pnp_dma(pdev, 1);
dma16[dev] = pnp_dma(pdev, 0);
if (id->driver_data == SB_HW_DT019X)
dma8[dev] = pnp_dma(pdev, 0);
else {
dma8[dev] = pnp_dma(pdev, 1);
dma16[dev] = pnp_dma(pdev, 0);
}
irq[dev] = pnp_irq(pdev, 0);
pdev = acard->devmpu;
@ -175,22 +205,33 @@ static int __devinit snd_card_als100_probe(int dev,
}
snd_card_set_dev(card, &pcard->card->dev);
if ((error = snd_sbdsp_create(card, port[dev],
irq[dev],
snd_sb16dsp_interrupt,
dma8[dev],
dma16[dev],
SB_HW_ALS100, &chip)) < 0) {
if (pid->driver_data == SB_HW_DT019X)
dma16[dev] = -1;
error = snd_sbdsp_create(card, port[dev], irq[dev],
snd_sb16dsp_interrupt,
dma8[dev], dma16[dev],
pid->driver_data,
&chip);
if (error < 0) {
snd_card_free(card);
return error;
}
acard->chip = chip;
strcpy(card->driver, "ALS100");
strcpy(card->shortname, "Avance Logic ALS100");
sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
card->shortname, chip->name, chip->port,
irq[dev], dma8[dev], dma16[dev]);
if (pid->driver_data == SB_HW_DT019X) {
strcpy(card->driver, "DT-019X");
strcpy(card->shortname, "Diamond Tech. DT-019X");
sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
card->shortname, chip->name, chip->port,
irq[dev], dma8[dev]);
} else {
strcpy(card->driver, "ALS100");
strcpy(card->shortname, "Avance Logic ALS100");
sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
card->shortname, chip->name, chip->port,
irq[dev], dma8[dev], dma16[dev]);
}
if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) {
snd_card_free(card);
@ -203,9 +244,19 @@ static int __devinit snd_card_als100_probe(int dev,
}
if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
if (snd_mpu401_uart_new(card, 0, MPU401_HW_ALS100,
int mpu_type = MPU401_HW_ALS100;
if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
mpu_irq[dev] = -1;
if (pid->driver_data == SB_HW_DT019X)
mpu_type = MPU401_HW_MPU401;
if (snd_mpu401_uart_new(card, 0,
mpu_type,
mpu_port[dev], 0,
mpu_irq[dev], IRQF_DISABLED,
mpu_irq[dev],
mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
NULL) < 0)
snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx\n", mpu_port[dev]);
}
@ -291,7 +342,7 @@ static int snd_als100_pnp_resume(struct pnp_card_link *pcard)
static struct pnp_card_driver als100_pnpc_driver = {
.flags = PNP_DRIVER_RES_DISABLE,
.name = "als100",
.name = "als100",
.id_table = snd_als100_pnpids,
.probe = snd_als100_pnp_detect,
.remove = __devexit_p(snd_als100_pnp_remove),
@ -312,7 +363,7 @@ static int __init alsa_card_als100_init(void)
if (!als100_devices) {
pnp_unregister_card_driver(&als100_pnpc_driver);
#ifdef MODULE
snd_printk(KERN_ERR "no ALS100 based soundcards found\n");
snd_printk(KERN_ERR "no Avance Logic based soundcards found\n");
#endif
return -ENODEV;
}

View file

@ -1,321 +0,0 @@
/*
dt019x.c - driver for Diamond Technologies DT-0197H based soundcards.
Copyright (C) 1999, 2002 by Massimo Piccioni <dafastidio@libero.it>
Generalised for soundcards based on DT-0196 and ALS-007 chips
by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>: June 2002.
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
*/
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/pnp.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/mpu401.h>
#include <sound/opl3.h>
#include <sound/sb.h>
#define PFX "dt019x: "
MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
MODULE_DESCRIPTION("Diamond Technologies DT-019X / Avance Logic ALS-007");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Diamond Technologies DT-019X},"
"{Avance Logic ALS-007}}");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* PnP setup */
static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* PnP setup */
static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for DT-019X based soundcard.");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for DT-019X based soundcard.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable DT-019X based soundcard.");
struct snd_card_dt019x {
struct pnp_dev *dev;
struct pnp_dev *devmpu;
struct pnp_dev *devopl;
struct snd_sb *chip;
};
static struct pnp_card_device_id snd_dt019x_pnpids[] = {
/* DT197A30 */
{ .id = "RWB1688", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" }, } },
/* DT0196 / ALS-007 */
{ .id = "ALS0007", .devs = { { "@@@0001" }, { "@X@0001" }, { "@H@0001" }, } },
{ .id = "", }
};
MODULE_DEVICE_TABLE(pnp_card, snd_dt019x_pnpids);
#define DRIVER_NAME "snd-card-dt019x"
static int __devinit snd_card_dt019x_pnp(int dev, struct snd_card_dt019x *acard,
struct pnp_card_link *card,
const struct pnp_card_device_id *pid)
{
struct pnp_dev *pdev;
int err;
acard->dev = pnp_request_card_device(card, pid->devs[0].id, NULL);
if (acard->dev == NULL)
return -ENODEV;
acard->devmpu = pnp_request_card_device(card, pid->devs[1].id, NULL);
acard->devopl = pnp_request_card_device(card, pid->devs[2].id, NULL);
pdev = acard->dev;
err = pnp_activate_dev(pdev);
if (err < 0) {
snd_printk(KERN_ERR PFX "DT-019X AUDIO pnp configure failure\n");
return err;
}
port[dev] = pnp_port_start(pdev, 0);
dma8[dev] = pnp_dma(pdev, 0);
irq[dev] = pnp_irq(pdev, 0);
snd_printdd("dt019x: found audio interface: port=0x%lx, irq=0x%x, dma=0x%x\n",
port[dev],irq[dev],dma8[dev]);
pdev = acard->devmpu;
if (pdev != NULL) {
err = pnp_activate_dev(pdev);
if (err < 0) {
pnp_release_card_device(pdev);
snd_printk(KERN_ERR PFX "DT-019X MPU401 pnp configure failure, skipping\n");
goto __mpu_error;
}
mpu_port[dev] = pnp_port_start(pdev, 0);
mpu_irq[dev] = pnp_irq(pdev, 0);
snd_printdd("dt019x: found MPU-401: port=0x%lx, irq=0x%x\n",
mpu_port[dev],mpu_irq[dev]);
} else {
__mpu_error:
acard->devmpu = NULL;
mpu_port[dev] = -1;
}
pdev = acard->devopl;
if (pdev != NULL) {
err = pnp_activate_dev(pdev);
if (err < 0) {
pnp_release_card_device(pdev);
snd_printk(KERN_ERR PFX "DT-019X OPL3 pnp configure failure, skipping\n");
goto __fm_error;
}
fm_port[dev] = pnp_port_start(pdev, 0);
snd_printdd("dt019x: found OPL3 synth: port=0x%lx\n",fm_port[dev]);
} else {
__fm_error:
acard->devopl = NULL;
fm_port[dev] = -1;
}
return 0;
}
static int __devinit snd_card_dt019x_probe(int dev, struct pnp_card_link *pcard, const struct pnp_card_device_id *pid)
{
int error;
struct snd_sb *chip;
struct snd_card *card;
struct snd_card_dt019x *acard;
struct snd_opl3 *opl3;
error = snd_card_create(index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_dt019x), &card);
if (error < 0)
return error;
acard = card->private_data;
snd_card_set_dev(card, &pcard->card->dev);
if ((error = snd_card_dt019x_pnp(dev, acard, pcard, pid))) {
snd_card_free(card);
return error;
}
if ((error = snd_sbdsp_create(card, port[dev],
irq[dev],
snd_sb16dsp_interrupt,
dma8[dev],
-1,
SB_HW_DT019X,
&chip)) < 0) {
snd_card_free(card);
return error;
}
acard->chip = chip;
strcpy(card->driver, "DT-019X");
strcpy(card->shortname, "Diamond Tech. DT-019X");
sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
card->shortname, chip->name, chip->port,
irq[dev], dma8[dev]);
if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) {
snd_card_free(card);
return error;
}
if ((error = snd_sbmixer_new(chip)) < 0) {
snd_card_free(card);
return error;
}
if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
mpu_irq[dev] = -1;
if (snd_mpu401_uart_new(card, 0,
/* MPU401_HW_SB,*/
MPU401_HW_MPU401,
mpu_port[dev], 0,
mpu_irq[dev],
mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
NULL) < 0)
snd_printk(KERN_ERR PFX "no MPU-401 device at 0x%lx ?\n", mpu_port[dev]);
}
if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
if (snd_opl3_create(card,
fm_port[dev],
fm_port[dev] + 2,
OPL3_HW_AUTO, 0, &opl3) < 0) {
snd_printk(KERN_ERR PFX "no OPL device at 0x%lx-0x%lx ?\n",
fm_port[dev], fm_port[dev] + 2);
} else {
if ((error = snd_opl3_timer_new(opl3, 0, 1)) < 0) {
snd_card_free(card);
return error;
}
if ((error = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) {
snd_card_free(card);
return error;
}
}
}
if ((error = snd_card_register(card)) < 0) {
snd_card_free(card);
return error;
}
pnp_set_card_drvdata(pcard, card);
return 0;
}
static unsigned int __devinitdata dt019x_devices;
static int __devinit snd_dt019x_pnp_probe(struct pnp_card_link *card,
const struct pnp_card_device_id *pid)
{
static int dev;
int res;
for ( ; dev < SNDRV_CARDS; dev++) {
if (!enable[dev])
continue;
res = snd_card_dt019x_probe(dev, card, pid);
if (res < 0)
return res;
dev++;
dt019x_devices++;
return 0;
}
return -ENODEV;
}
static void __devexit snd_dt019x_pnp_remove(struct pnp_card_link * pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
}
#ifdef CONFIG_PM
static int snd_dt019x_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
{
struct snd_card *card = pnp_get_card_drvdata(pcard);
struct snd_card_dt019x *acard = card->private_data;
struct snd_sb *chip = acard->chip;
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
snd_pcm_suspend_all(chip->pcm);
snd_sbmixer_suspend(chip);
return 0;
}
static int snd_dt019x_pnp_resume(struct pnp_card_link *pcard)
{
struct snd_card *card = pnp_get_card_drvdata(pcard);
struct snd_card_dt019x *acard = card->private_data;
struct snd_sb *chip = acard->chip;
snd_sbdsp_reset(chip);
snd_sbmixer_resume(chip);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
}
#endif
static struct pnp_card_driver dt019x_pnpc_driver = {
.flags = PNP_DRIVER_RES_DISABLE,
.name = "dt019x",
.id_table = snd_dt019x_pnpids,
.probe = snd_dt019x_pnp_probe,
.remove = __devexit_p(snd_dt019x_pnp_remove),
#ifdef CONFIG_PM
.suspend = snd_dt019x_pnp_suspend,
.resume = snd_dt019x_pnp_resume,
#endif
};
static int __init alsa_card_dt019x_init(void)
{
int err;
err = pnp_register_card_driver(&dt019x_pnpc_driver);
if (err)
return err;
if (!dt019x_devices) {
pnp_unregister_card_driver(&dt019x_pnpc_driver);
#ifdef MODULE
snd_printk(KERN_ERR "no DT-019X / ALS-007 based soundcards found\n");
#endif
return -ENODEV;
}
return 0;
}
static void __exit alsa_card_dt019x_exit(void)
{
pnp_unregister_card_driver(&dt019x_pnpc_driver);
}
module_init(alsa_card_dt019x_init)
module_exit(alsa_card_dt019x_exit)

View file

@ -33,6 +33,7 @@
#include <asm/io.h>
#include <asm/dma.h>
#include <sound/core.h>
#include <sound/tlv.h>
#include <sound/wss.h>
#include <sound/mpu401.h>
#include <sound/opl3.h>
@ -546,6 +547,93 @@ __skip_mpu:
#ifdef OPTi93X
static const DECLARE_TLV_DB_SCALE(db_scale_5bit_3db_step, -9300, 300, 0);
static const DECLARE_TLV_DB_SCALE(db_scale_5bit, -4650, 150, 0);
static const DECLARE_TLV_DB_SCALE(db_scale_4bit_12db_max, -3300, 300, 0);
static struct snd_kcontrol_new snd_opti93x_controls[] = {
WSS_DOUBLE("Master Playback Switch", 0,
OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
WSS_DOUBLE_TLV("Master Playback Volume", 0,
OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1,
db_scale_5bit_3db_step),
WSS_DOUBLE_TLV("PCM Playback Volume", 0,
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1,
db_scale_5bit),
WSS_DOUBLE_TLV("FM Playback Volume", 0,
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1,
db_scale_4bit_12db_max),
WSS_DOUBLE("Line Playback Switch", 0,
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
WSS_DOUBLE_TLV("Line Playback Volume", 0,
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1,
db_scale_4bit_12db_max),
WSS_DOUBLE("Mic Playback Switch", 0,
OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
WSS_DOUBLE_TLV("Mic Playback Volume", 0,
OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1,
db_scale_4bit_12db_max),
WSS_DOUBLE_TLV("CD Playback Volume", 0,
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1,
db_scale_4bit_12db_max),
WSS_DOUBLE("Aux Playback Switch", 0,
OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
WSS_DOUBLE_TLV("Aux Playback Volume", 0,
OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1,
db_scale_4bit_12db_max),
};
static int __devinit snd_opti93x_mixer(struct snd_wss *chip)
{
struct snd_card *card;
unsigned int idx;
struct snd_ctl_elem_id id1, id2;
int err;
if (snd_BUG_ON(!chip || !chip->pcm))
return -EINVAL;
card = chip->card;
strcpy(card->mixername, chip->pcm->name);
memset(&id1, 0, sizeof(id1));
memset(&id2, 0, sizeof(id2));
id1.iface = id2.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
/* reassign AUX0 switch to CD */
strcpy(id1.name, "Aux Playback Switch");
strcpy(id2.name, "CD Playback Switch");
err = snd_ctl_rename_id(card, &id1, &id2);
if (err < 0) {
snd_printk(KERN_ERR "Cannot rename opti93x control\n");
return err;
}
/* reassign AUX1 switch to FM */
strcpy(id1.name, "Aux Playback Switch"); id1.index = 1;
strcpy(id2.name, "FM Playback Switch");
err = snd_ctl_rename_id(card, &id1, &id2);
if (err < 0) {
snd_printk(KERN_ERR "Cannot rename opti93x control\n");
return err;
}
/* remove AUX1 volume */
strcpy(id1.name, "Aux Playback Volume"); id1.index = 1;
snd_ctl_remove_id(card, &id1);
/* Replace WSS volume controls with OPTi93x volume controls */
id1.index = 0;
for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
strcpy(id1.name, snd_opti93x_controls[idx].name);
snd_ctl_remove_id(card, &id1);
err = snd_ctl_add(card,
snd_ctl_new1(&snd_opti93x_controls[idx], chip));
if (err < 0)
return err;
}
return 0;
}
static irqreturn_t snd_opti93x_interrupt(int irq, void *dev_id)
{
struct snd_opti9xx *chip = dev_id;
@ -754,6 +842,11 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
error = snd_wss_mixer(codec);
if (error < 0)
return error;
#ifdef OPTi93X
error = snd_opti93x_mixer(codec);
if (error < 0)
return error;
#endif
#ifdef CS4231
error = snd_wss_timer(codec, 0, &timer);
if (error < 0)

View file

@ -12,6 +12,7 @@ snd-sb16-objs := sb16.o
snd-sbawe-objs := sbawe.o emu8000.o
snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o
snd-es968-objs := es968.o
snd-jazz16-objs := jazz16.o
# Toplevel Module Dependency
obj-$(CONFIG_SND_SB_COMMON) += snd-sb-common.o
@ -21,6 +22,7 @@ obj-$(CONFIG_SND_SB8) += snd-sb8.o
obj-$(CONFIG_SND_SB16) += snd-sb16.o
obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o
obj-$(CONFIG_SND_ES968) += snd-es968.o
obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o
ifeq ($(CONFIG_SND_SB16_CSP),y)
obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o
obj-$(CONFIG_SND_SBAWE) += snd-sb16-csp.o

404
sound/isa/sb/jazz16.c Normal file
View file

@ -0,0 +1,404 @@
/*
* jazz16.c - driver for Media Vision Jazz16 based soundcards.
* Copyright (C) 2009 Krzysztof Helt <krzysztof.h1@wp.pl>
* Based on patches posted by Rask Ingemann Lambertsen and Rene Herman.
* Based on OSS Sound Blaster driver.
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/io.h>
#include <asm/dma.h>
#include <linux/isa.h>
#include <sound/core.h>
#include <sound/mpu401.h>
#include <sound/opl3.h>
#include <sound/sb.h>
#define SNDRV_LEGACY_FIND_FREE_IRQ
#define SNDRV_LEGACY_FIND_FREE_DMA
#include <sound/initval.h>
#define PFX "jazz16: "
MODULE_DESCRIPTION("Media Vision Jazz16");
MODULE_SUPPORTED_DEVICE("{{Media Vision ??? },"
"{RTL,RTL3000}}");
MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>");
MODULE_LICENSE("GPL");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static unsigned long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
static unsigned long mpu_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT;
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
static int mpu_irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ;
static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
static int dma16[SNDRV_CARDS] = SNDRV_DEFAULT_DMA;
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Media Vision Jazz16 based soundcard.");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for Media Vision Jazz16 based soundcard.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable Media Vision Jazz16 based soundcard.");
module_param_array(port, long, NULL, 0444);
MODULE_PARM_DESC(port, "Port # for jazz16 driver.");
module_param_array(mpu_port, long, NULL, 0444);
MODULE_PARM_DESC(mpu_port, "MPU-401 port # for jazz16 driver.");
module_param_array(irq, int, NULL, 0444);
MODULE_PARM_DESC(irq, "IRQ # for jazz16 driver.");
module_param_array(mpu_irq, int, NULL, 0444);
MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for jazz16 driver.");
module_param_array(dma8, int, NULL, 0444);
MODULE_PARM_DESC(dma8, "DMA8 # for jazz16 driver.");
module_param_array(dma16, int, NULL, 0444);
MODULE_PARM_DESC(dma16, "DMA16 # for jazz16 driver.");
#define SB_JAZZ16_WAKEUP 0xaf
#define SB_JAZZ16_SET_PORTS 0x50
#define SB_DSP_GET_JAZZ_BRD_REV 0xfa
#define SB_JAZZ16_SET_DMAINTR 0xfb
#define SB_DSP_GET_JAZZ_MODEL 0xfe
struct snd_card_jazz16 {
struct snd_sb *chip;
};
static irqreturn_t jazz16_interrupt(int irq, void *chip)
{
return snd_sb8dsp_interrupt(chip);
}
static int __devinit jazz16_configure_ports(unsigned long port,
unsigned long mpu_port, int idx)
{
unsigned char val;
if (!request_region(0x201, 1, "jazz16 config")) {
snd_printk(KERN_ERR "config port region is already in use.\n");
return -EBUSY;
}
outb(SB_JAZZ16_WAKEUP - idx, 0x201);
udelay(100);
outb(SB_JAZZ16_SET_PORTS + idx, 0x201);
udelay(100);
val = port & 0x70;
val |= (mpu_port & 0x30) >> 4;
outb(val, 0x201);
release_region(0x201, 1);
return 0;
}
static int __devinit jazz16_detect_board(unsigned long port,
unsigned long mpu_port)
{
int err;
int val;
struct snd_sb chip;
if (!request_region(port, 0x10, "jazz16")) {
snd_printk(KERN_ERR "I/O port region is already in use.\n");
return -EBUSY;
}
/* just to call snd_sbdsp_command/reset/get_byte() */
chip.port = port;
err = snd_sbdsp_reset(&chip);
if (err < 0)
for (val = 0; val < 4; val++) {
err = jazz16_configure_ports(port, mpu_port, val);
if (err < 0)
break;
err = snd_sbdsp_reset(&chip);
if (!err)
break;
}
if (err < 0) {
err = -ENODEV;
goto err_unmap;
}
if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_BRD_REV)) {
err = -EBUSY;
goto err_unmap;
}
val = snd_sbdsp_get_byte(&chip);
if (val >= 0x30)
snd_sbdsp_get_byte(&chip);
if ((val & 0xf0) != 0x10) {
err = -ENODEV;
goto err_unmap;
}
if (!snd_sbdsp_command(&chip, SB_DSP_GET_JAZZ_MODEL)) {
err = -EBUSY;
goto err_unmap;
}
snd_sbdsp_get_byte(&chip);
err = snd_sbdsp_get_byte(&chip);
snd_printd("Media Vision Jazz16 board detected: rev 0x%x, model 0x%x\n",
val, err);
err = 0;
err_unmap:
release_region(port, 0x10);
return err;
}
static int __devinit jazz16_configure_board(struct snd_sb *chip, int mpu_irq)
{
static unsigned char jazz_irq_bits[] = { 0, 0, 2, 3, 0, 1, 0, 4,
0, 2, 5, 0, 0, 0, 0, 6 };
static unsigned char jazz_dma_bits[] = { 0, 1, 0, 2, 0, 3, 0, 4 };
if (jazz_dma_bits[chip->dma8] == 0 ||
jazz_dma_bits[chip->dma16] == 0 ||
jazz_irq_bits[chip->irq] == 0)
return -EINVAL;
if (!snd_sbdsp_command(chip, SB_JAZZ16_SET_DMAINTR))
return -EBUSY;
if (!snd_sbdsp_command(chip,
jazz_dma_bits[chip->dma8] |
(jazz_dma_bits[chip->dma16] << 4)))
return -EBUSY;
if (!snd_sbdsp_command(chip,
jazz_irq_bits[chip->irq] |
(jazz_irq_bits[mpu_irq] << 4)))
return -EBUSY;
return 0;
}
static int __devinit snd_jazz16_match(struct device *devptr, unsigned int dev)
{
if (!enable[dev])
return 0;
if (port[dev] == SNDRV_AUTO_PORT) {
snd_printk(KERN_ERR "please specify port\n");
return 0;
} else if (port[dev] == 0x200 || (port[dev] & ~0x270)) {
snd_printk(KERN_ERR "incorrect port specified\n");
return 0;
}
if (dma8[dev] != SNDRV_AUTO_DMA &&
dma8[dev] != 1 && dma8[dev] != 3) {
snd_printk(KERN_ERR "dma8 must be 1 or 3\n");
return 0;
}
if (dma16[dev] != SNDRV_AUTO_DMA &&
dma16[dev] != 5 && dma16[dev] != 7) {
snd_printk(KERN_ERR "dma16 must be 5 or 7\n");
return 0;
}
if (mpu_port[dev] != SNDRV_AUTO_PORT &&
(mpu_port[dev] & ~0x030) != 0x300) {
snd_printk(KERN_ERR "incorrect mpu_port specified\n");
return 0;
}
if (mpu_irq[dev] != SNDRV_AUTO_DMA &&
mpu_irq[dev] != 2 && mpu_irq[dev] != 3 &&
mpu_irq[dev] != 5 && mpu_irq[dev] != 7) {
snd_printk(KERN_ERR "mpu_irq must be 2, 3, 5 or 7\n");
return 0;
}
return 1;
}
static int __devinit snd_jazz16_probe(struct device *devptr, unsigned int dev)
{
struct snd_card *card;
struct snd_card_jazz16 *jazz16;
struct snd_sb *chip;
struct snd_opl3 *opl3;
static int possible_irqs[] = {2, 3, 5, 7, 9, 10, 15, -1};
static int possible_dmas8[] = {1, 3, -1};
static int possible_dmas16[] = {5, 7, -1};
int err, xirq, xdma8, xdma16, xmpu_port, xmpu_irq;
err = snd_card_create(index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_jazz16), &card);
if (err < 0)
return err;
jazz16 = card->private_data;
xirq = irq[dev];
if (xirq == SNDRV_AUTO_IRQ) {
xirq = snd_legacy_find_free_irq(possible_irqs);
if (xirq < 0) {
snd_printk(KERN_ERR "unable to find a free IRQ\n");
err = -EBUSY;
goto err_free;
}
}
xdma8 = dma8[dev];
if (xdma8 == SNDRV_AUTO_DMA) {
xdma8 = snd_legacy_find_free_dma(possible_dmas8);
if (xdma8 < 0) {
snd_printk(KERN_ERR "unable to find a free DMA8\n");
err = -EBUSY;
goto err_free;
}
}
xdma16 = dma16[dev];
if (xdma16 == SNDRV_AUTO_DMA) {
xdma16 = snd_legacy_find_free_dma(possible_dmas16);
if (xdma16 < 0) {
snd_printk(KERN_ERR "unable to find a free DMA16\n");
err = -EBUSY;
goto err_free;
}
}
xmpu_port = mpu_port[dev];
if (xmpu_port == SNDRV_AUTO_PORT)
xmpu_port = 0;
err = jazz16_detect_board(port[dev], xmpu_port);
if (err < 0) {
printk(KERN_ERR "Media Vision Jazz16 board not detected\n");
goto err_free;
}
err = snd_sbdsp_create(card, port[dev], irq[dev],
jazz16_interrupt,
dma8[dev], dma16[dev],
SB_HW_JAZZ16,
&chip);
if (err < 0)
goto err_free;
xmpu_irq = mpu_irq[dev];
if (xmpu_irq == SNDRV_AUTO_IRQ || mpu_port[dev] == SNDRV_AUTO_PORT)
xmpu_irq = 0;
err = jazz16_configure_board(chip, xmpu_irq);
if (err < 0) {
printk(KERN_ERR "Media Vision Jazz16 configuration failed\n");
goto err_free;
}
jazz16->chip = chip;
strcpy(card->driver, "jazz16");
strcpy(card->shortname, "Media Vision Jazz16");
sprintf(card->longname,
"Media Vision Jazz16 at 0x%lx, irq %d, dma8 %d, dma16 %d",
port[dev], xirq, xdma8, xdma16);
err = snd_sb8dsp_pcm(chip, 0, NULL);
if (err < 0)
goto err_free;
err = snd_sbmixer_new(chip);
if (err < 0)
goto err_free;
err = snd_opl3_create(card, chip->port, chip->port + 2,
OPL3_HW_AUTO, 1, &opl3);
if (err < 0)
snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n",
chip->port, chip->port + 2);
else {
err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
if (err < 0)
goto err_free;
}
if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
if (mpu_irq[dev] == SNDRV_AUTO_IRQ)
mpu_irq[dev] = -1;
if (snd_mpu401_uart_new(card, 0,
MPU401_HW_MPU401,
mpu_port[dev], 0,
mpu_irq[dev],
mpu_irq[dev] >= 0 ? IRQF_DISABLED : 0,
NULL) < 0)
snd_printk(KERN_ERR "no MPU-401 device at 0x%lx\n",
mpu_port[dev]);
}
snd_card_set_dev(card, devptr);
err = snd_card_register(card);
if (err < 0)
goto err_free;
dev_set_drvdata(devptr, card);
return 0;
err_free:
snd_card_free(card);
return err;
}
static int __devexit snd_jazz16_remove(struct device *devptr, unsigned int dev)
{
struct snd_card *card = dev_get_drvdata(devptr);
dev_set_drvdata(devptr, NULL);
snd_card_free(card);
return 0;
}
#ifdef CONFIG_PM
static int snd_jazz16_suspend(struct device *pdev, unsigned int n,
pm_message_t state)
{
struct snd_card *card = dev_get_drvdata(pdev);
struct snd_card_jazz16 *acard = card->private_data;
struct snd_sb *chip = acard->chip;
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
snd_pcm_suspend_all(chip->pcm);
snd_sbmixer_suspend(chip);
return 0;
}
static int snd_jazz16_resume(struct device *pdev, unsigned int n)
{
struct snd_card *card = dev_get_drvdata(pdev);
struct snd_card_jazz16 *acard = card->private_data;
struct snd_sb *chip = acard->chip;
snd_sbdsp_reset(chip);
snd_sbmixer_resume(chip);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
}
#endif
static struct isa_driver snd_jazz16_driver = {
.match = snd_jazz16_match,
.probe = snd_jazz16_probe,
.remove = __devexit_p(snd_jazz16_remove),
#ifdef CONFIG_PM
.suspend = snd_jazz16_suspend,
.resume = snd_jazz16_resume,
#endif
.driver = {
.name = "jazz16"
},
};
static int __init alsa_card_jazz16_init(void)
{
return isa_register_driver(&snd_jazz16_driver, SNDRV_CARDS);
}
static void __exit alsa_card_jazz16_exit(void)
{
isa_unregister_driver(&snd_jazz16_driver);
}
module_init(alsa_card_jazz16_init)
module_exit(alsa_card_jazz16_exit)

View file

@ -106,9 +106,21 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
struct snd_sb *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned int mixreg, rate, size, count;
unsigned char format;
unsigned char stereo = runtime->channels > 1;
int dma;
rate = runtime->rate;
switch (chip->hardware) {
case SB_HW_JAZZ16:
if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
if (chip->mode & SB_MODE_CAPTURE_16)
return -EBUSY;
else
chip->mode |= SB_MODE_PLAYBACK_16;
}
chip->playback_format = SB_DSP_LO_OUTPUT_AUTO;
break;
case SB_HW_PRO:
if (runtime->channels > 1) {
if (snd_BUG_ON(rate != SB8_RATE(11025) &&
@ -133,11 +145,21 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
default:
return -EINVAL;
}
if (chip->mode & SB_MODE_PLAYBACK_16) {
format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
dma = chip->dma16;
} else {
format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
chip->mode |= SB_MODE_PLAYBACK_8;
dma = chip->dma8;
}
size = chip->p_dma_size = snd_pcm_lib_buffer_bytes(substream);
count = chip->p_period_size = snd_pcm_lib_period_bytes(substream);
spin_lock_irqsave(&chip->reg_lock, flags);
snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON);
if (runtime->channels > 1) {
if (chip->hardware == SB_HW_JAZZ16)
snd_sbdsp_command(chip, format);
else if (stereo) {
/* set playback stereo mode */
spin_lock(&chip->mixer_lock);
mixreg = snd_sbmixer_read(chip, SB_DSP_STEREO_SW);
@ -147,15 +169,14 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
/* Soundblaster hardware programming reference guide, 3-23 */
snd_sbdsp_command(chip, SB_DSP_DMA8_EXIT);
runtime->dma_area[0] = 0x80;
snd_dma_program(chip->dma8, runtime->dma_addr, 1, DMA_MODE_WRITE);
snd_dma_program(dma, runtime->dma_addr, 1, DMA_MODE_WRITE);
/* force interrupt */
chip->mode = SB_MODE_HALT;
snd_sbdsp_command(chip, SB_DSP_OUTPUT);
snd_sbdsp_command(chip, 0);
snd_sbdsp_command(chip, 0);
}
snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
if (runtime->channels > 1) {
if (stereo) {
snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
spin_lock(&chip->mixer_lock);
/* save output filter status and turn it off */
@ -168,13 +189,15 @@ static int snd_sb8_playback_prepare(struct snd_pcm_substream *substream)
snd_sbdsp_command(chip, 256 - runtime->rate_den);
}
if (chip->playback_format != SB_DSP_OUTPUT) {
if (chip->mode & SB_MODE_PLAYBACK_16)
count /= 2;
count--;
snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
snd_sbdsp_command(chip, count & 0xff);
snd_sbdsp_command(chip, count >> 8);
}
spin_unlock_irqrestore(&chip->reg_lock, flags);
snd_dma_program(chip->dma8, runtime->dma_addr,
snd_dma_program(dma, runtime->dma_addr,
size, DMA_MODE_WRITE | DMA_AUTOINIT);
return 0;
}
@ -212,7 +235,6 @@ static int snd_sb8_playback_trigger(struct snd_pcm_substream *substream,
snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
}
spin_unlock_irqrestore(&chip->reg_lock, flags);
chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_PLAYBACK_8 : SB_MODE_HALT;
return 0;
}
@ -234,9 +256,21 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
struct snd_sb *chip = snd_pcm_substream_chip(substream);
struct snd_pcm_runtime *runtime = substream->runtime;
unsigned int mixreg, rate, size, count;
unsigned char format;
unsigned char stereo = runtime->channels > 1;
int dma;
rate = runtime->rate;
switch (chip->hardware) {
case SB_HW_JAZZ16:
if (runtime->format == SNDRV_PCM_FORMAT_S16_LE) {
if (chip->mode & SB_MODE_PLAYBACK_16)
return -EBUSY;
else
chip->mode |= SB_MODE_CAPTURE_16;
}
chip->capture_format = SB_DSP_LO_INPUT_AUTO;
break;
case SB_HW_PRO:
if (runtime->channels > 1) {
if (snd_BUG_ON(rate != SB8_RATE(11025) &&
@ -262,14 +296,24 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
default:
return -EINVAL;
}
if (chip->mode & SB_MODE_CAPTURE_16) {
format = stereo ? SB_DSP_STEREO_16BIT : SB_DSP_MONO_16BIT;
dma = chip->dma16;
} else {
format = stereo ? SB_DSP_STEREO_8BIT : SB_DSP_MONO_8BIT;
chip->mode |= SB_MODE_CAPTURE_8;
dma = chip->dma8;
}
size = chip->c_dma_size = snd_pcm_lib_buffer_bytes(substream);
count = chip->c_period_size = snd_pcm_lib_period_bytes(substream);
spin_lock_irqsave(&chip->reg_lock, flags);
snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
if (runtime->channels > 1)
if (chip->hardware == SB_HW_JAZZ16)
snd_sbdsp_command(chip, format);
else if (stereo)
snd_sbdsp_command(chip, SB_DSP_STEREO_8BIT);
snd_sbdsp_command(chip, SB_DSP_SAMPLE_RATE);
if (runtime->channels > 1) {
if (stereo) {
snd_sbdsp_command(chip, 256 - runtime->rate_den / 2);
spin_lock(&chip->mixer_lock);
/* save input filter status and turn it off */
@ -282,13 +326,15 @@ static int snd_sb8_capture_prepare(struct snd_pcm_substream *substream)
snd_sbdsp_command(chip, 256 - runtime->rate_den);
}
if (chip->capture_format != SB_DSP_INPUT) {
if (chip->mode & SB_MODE_PLAYBACK_16)
count /= 2;
count--;
snd_sbdsp_command(chip, SB_DSP_BLOCK_SIZE);
snd_sbdsp_command(chip, count & 0xff);
snd_sbdsp_command(chip, count >> 8);
}
spin_unlock_irqrestore(&chip->reg_lock, flags);
snd_dma_program(chip->dma8, runtime->dma_addr,
snd_dma_program(dma, runtime->dma_addr,
size, DMA_MODE_READ | DMA_AUTOINIT);
return 0;
}
@ -328,7 +374,6 @@ static int snd_sb8_capture_trigger(struct snd_pcm_substream *substream,
snd_sbdsp_command(chip, SB_DSP_SPEAKER_OFF);
}
spin_unlock_irqrestore(&chip->reg_lock, flags);
chip->mode = (cmd == SNDRV_PCM_TRIGGER_START) ? SB_MODE_CAPTURE_8 : SB_MODE_HALT;
return 0;
}
@ -339,13 +384,21 @@ irqreturn_t snd_sb8dsp_interrupt(struct snd_sb *chip)
snd_sb_ack_8bit(chip);
switch (chip->mode) {
case SB_MODE_PLAYBACK_8: /* ok.. playback is active */
case SB_MODE_PLAYBACK_16: /* ok.. playback is active */
if (chip->hardware != SB_HW_JAZZ16)
break;
/* fallthru */
case SB_MODE_PLAYBACK_8:
substream = chip->playback_substream;
runtime = substream->runtime;
if (chip->playback_format == SB_DSP_OUTPUT)
snd_sb8_playback_trigger(substream, SNDRV_PCM_TRIGGER_START);
snd_pcm_period_elapsed(substream);
break;
case SB_MODE_CAPTURE_16:
if (chip->hardware != SB_HW_JAZZ16)
break;
/* fallthru */
case SB_MODE_CAPTURE_8:
substream = chip->capture_substream;
runtime = substream->runtime;
@ -361,10 +414,15 @@ static snd_pcm_uframes_t snd_sb8_playback_pointer(struct snd_pcm_substream *subs
{
struct snd_sb *chip = snd_pcm_substream_chip(substream);
size_t ptr;
int dma;
if (chip->mode != SB_MODE_PLAYBACK_8)
if (chip->mode & SB_MODE_PLAYBACK_8)
dma = chip->dma8;
else if (chip->mode & SB_MODE_PLAYBACK_16)
dma = chip->dma16;
else
return 0;
ptr = snd_dma_pointer(chip->dma8, chip->p_dma_size);
ptr = snd_dma_pointer(dma, chip->p_dma_size);
return bytes_to_frames(substream->runtime, ptr);
}
@ -372,10 +430,15 @@ static snd_pcm_uframes_t snd_sb8_capture_pointer(struct snd_pcm_substream *subst
{
struct snd_sb *chip = snd_pcm_substream_chip(substream);
size_t ptr;
int dma;
if (chip->mode != SB_MODE_CAPTURE_8)
if (chip->mode & SB_MODE_CAPTURE_8)
dma = chip->dma8;
else if (chip->mode & SB_MODE_CAPTURE_16)
dma = chip->dma16;
else
return 0;
ptr = snd_dma_pointer(chip->dma8, chip->c_dma_size);
ptr = snd_dma_pointer(dma, chip->c_dma_size);
return bytes_to_frames(substream->runtime, ptr);
}
@ -446,6 +509,14 @@ static int snd_sb8_open(struct snd_pcm_substream *substream)
runtime->hw = snd_sb8_capture;
}
switch (chip->hardware) {
case SB_HW_JAZZ16:
if (chip->dma16 == 5 || chip->dma16 == 7)
runtime->hw.formats |= SNDRV_PCM_FMTBIT_S16_LE;
runtime->hw.rates |= SNDRV_PCM_RATE_8000_48000;
runtime->hw.rate_min = 4000;
runtime->hw.rate_max = 50000;
runtime->hw.channels_max = 2;
break;
case SB_HW_PRO:
runtime->hw.rate_max = 44100;
runtime->hw.channels_max = 2;
@ -468,6 +539,14 @@ static int snd_sb8_open(struct snd_pcm_substream *substream)
}
snd_pcm_hw_constraint_ratnums(runtime, 0, SNDRV_PCM_HW_PARAM_RATE,
&hw_constraints_clock);
if (chip->dma8 > 3 || chip->dma16 >= 0) {
snd_pcm_hw_constraint_step(runtime, 0,
SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 2);
snd_pcm_hw_constraint_step(runtime, 0,
SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 2);
runtime->hw.buffer_bytes_max = 128 * 1024 * 1024;
runtime->hw.period_bytes_max = 128 * 1024 * 1024;
}
return 0;
}
@ -480,6 +559,10 @@ static int snd_sb8_close(struct snd_pcm_substream *substream)
chip->capture_substream = NULL;
spin_lock_irqsave(&chip->open_lock, flags);
chip->open &= ~SB_OPEN_PCM;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
chip->mode &= ~SB_MODE_PLAYBACK;
else
chip->mode &= ~SB_MODE_CAPTURE;
spin_unlock_irqrestore(&chip->open_lock, flags);
return 0;
}
@ -515,6 +598,7 @@ int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm)
struct snd_card *card = chip->card;
struct snd_pcm *pcm;
int err;
size_t max_prealloc = 64 * 1024;
if (rpcm)
*rpcm = NULL;
@ -527,9 +611,11 @@ int snd_sb8dsp_pcm(struct snd_sb *chip, int device, struct snd_pcm ** rpcm)
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sb8_playback_ops);
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sb8_capture_ops);
if (chip->dma8 > 3 || chip->dma16 >= 0)
max_prealloc = 128 * 1024;
snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
snd_dma_isa_data(),
64*1024, 64*1024);
64*1024, max_prealloc);
if (rpcm)
*rpcm = pcm;

View file

@ -170,6 +170,9 @@ static int snd_sbdsp_probe(struct snd_sb * chip)
case SB_HW_CS5530:
str = "16 (CS5530)";
break;
case SB_HW_JAZZ16:
str = "Pro (Jazz16)";
break;
default:
return -ENODEV;
}

View file

@ -528,20 +528,11 @@ int snd_sbmixer_add_ctl(struct snd_sb *chip, const char *name, int index, int ty
* SB 2.0 specific mixer elements
*/
static struct sbmix_elem snd_sb20_ctl_master_play_vol =
SB_SINGLE("Master Playback Volume", SB_DSP20_MASTER_DEV, 1, 7);
static struct sbmix_elem snd_sb20_ctl_pcm_play_vol =
SB_SINGLE("PCM Playback Volume", SB_DSP20_PCM_DEV, 1, 3);
static struct sbmix_elem snd_sb20_ctl_synth_play_vol =
SB_SINGLE("Synth Playback Volume", SB_DSP20_FM_DEV, 1, 7);
static struct sbmix_elem snd_sb20_ctl_cd_play_vol =
SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7);
static struct sbmix_elem *snd_sb20_controls[] = {
&snd_sb20_ctl_master_play_vol,
&snd_sb20_ctl_pcm_play_vol,
&snd_sb20_ctl_synth_play_vol,
&snd_sb20_ctl_cd_play_vol
static struct sbmix_elem snd_sb20_controls[] = {
SB_SINGLE("Master Playback Volume", SB_DSP20_MASTER_DEV, 1, 7),
SB_SINGLE("PCM Playback Volume", SB_DSP20_PCM_DEV, 1, 3),
SB_SINGLE("Synth Playback Volume", SB_DSP20_FM_DEV, 1, 7),
SB_SINGLE("CD Playback Volume", SB_DSP20_CD_DEV, 1, 7)
};
static unsigned char snd_sb20_init_values[][2] = {
@ -552,41 +543,24 @@ static unsigned char snd_sb20_init_values[][2] = {
/*
* SB Pro specific mixer elements
*/
static struct sbmix_elem snd_sbpro_ctl_master_play_vol =
SB_DOUBLE("Master Playback Volume", SB_DSP_MASTER_DEV, SB_DSP_MASTER_DEV, 5, 1, 7);
static struct sbmix_elem snd_sbpro_ctl_pcm_play_vol =
SB_DOUBLE("PCM Playback Volume", SB_DSP_PCM_DEV, SB_DSP_PCM_DEV, 5, 1, 7);
static struct sbmix_elem snd_sbpro_ctl_pcm_play_filter =
SB_SINGLE("PCM Playback Filter", SB_DSP_PLAYBACK_FILT, 5, 1);
static struct sbmix_elem snd_sbpro_ctl_synth_play_vol =
SB_DOUBLE("Synth Playback Volume", SB_DSP_FM_DEV, SB_DSP_FM_DEV, 5, 1, 7);
static struct sbmix_elem snd_sbpro_ctl_cd_play_vol =
SB_DOUBLE("CD Playback Volume", SB_DSP_CD_DEV, SB_DSP_CD_DEV, 5, 1, 7);
static struct sbmix_elem snd_sbpro_ctl_line_play_vol =
SB_DOUBLE("Line Playback Volume", SB_DSP_LINE_DEV, SB_DSP_LINE_DEV, 5, 1, 7);
static struct sbmix_elem snd_sbpro_ctl_mic_play_vol =
SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3);
static struct sbmix_elem snd_sbpro_ctl_capture_source =
static struct sbmix_elem snd_sbpro_controls[] = {
SB_DOUBLE("Master Playback Volume",
SB_DSP_MASTER_DEV, SB_DSP_MASTER_DEV, 5, 1, 7),
SB_DOUBLE("PCM Playback Volume",
SB_DSP_PCM_DEV, SB_DSP_PCM_DEV, 5, 1, 7),
SB_SINGLE("PCM Playback Filter", SB_DSP_PLAYBACK_FILT, 5, 1),
SB_DOUBLE("Synth Playback Volume",
SB_DSP_FM_DEV, SB_DSP_FM_DEV, 5, 1, 7),
SB_DOUBLE("CD Playback Volume", SB_DSP_CD_DEV, SB_DSP_CD_DEV, 5, 1, 7),
SB_DOUBLE("Line Playback Volume",
SB_DSP_LINE_DEV, SB_DSP_LINE_DEV, 5, 1, 7),
SB_SINGLE("Mic Playback Volume", SB_DSP_MIC_DEV, 1, 3),
{
.name = "Capture Source",
.type = SB_MIX_CAPTURE_PRO
};
static struct sbmix_elem snd_sbpro_ctl_capture_filter =
SB_SINGLE("Capture Filter", SB_DSP_CAPTURE_FILT, 5, 1);
static struct sbmix_elem snd_sbpro_ctl_capture_low_filter =
SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1);
static struct sbmix_elem *snd_sbpro_controls[] = {
&snd_sbpro_ctl_master_play_vol,
&snd_sbpro_ctl_pcm_play_vol,
&snd_sbpro_ctl_pcm_play_filter,
&snd_sbpro_ctl_synth_play_vol,
&snd_sbpro_ctl_cd_play_vol,
&snd_sbpro_ctl_line_play_vol,
&snd_sbpro_ctl_mic_play_vol,
&snd_sbpro_ctl_capture_source,
&snd_sbpro_ctl_capture_filter,
&snd_sbpro_ctl_capture_low_filter
},
SB_SINGLE("Capture Filter", SB_DSP_CAPTURE_FILT, 5, 1),
SB_SINGLE("Capture Low-Pass Filter", SB_DSP_CAPTURE_FILT, 3, 1)
};
static unsigned char snd_sbpro_init_values[][2] = {
@ -598,68 +572,42 @@ static unsigned char snd_sbpro_init_values[][2] = {
/*
* SB16 specific mixer elements
*/
static struct sbmix_elem snd_sb16_ctl_master_play_vol =
SB_DOUBLE("Master Playback Volume", SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31);
static struct sbmix_elem snd_sb16_ctl_3d_enhance_switch =
SB_SINGLE("3D Enhancement Switch", SB_DSP4_3DSE, 0, 1);
static struct sbmix_elem snd_sb16_ctl_tone_bass =
SB_DOUBLE("Tone Control - Bass", SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15);
static struct sbmix_elem snd_sb16_ctl_tone_treble =
SB_DOUBLE("Tone Control - Treble", SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15);
static struct sbmix_elem snd_sb16_ctl_pcm_play_vol =
SB_DOUBLE("PCM Playback Volume", SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31);
static struct sbmix_elem snd_sb16_ctl_synth_capture_route =
SB16_INPUT_SW("Synth Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 6, 5);
static struct sbmix_elem snd_sb16_ctl_synth_play_vol =
SB_DOUBLE("Synth Playback Volume", SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31);
static struct sbmix_elem snd_sb16_ctl_cd_capture_route =
SB16_INPUT_SW("CD Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 2, 1);
static struct sbmix_elem snd_sb16_ctl_cd_play_switch =
SB_DOUBLE("CD Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1);
static struct sbmix_elem snd_sb16_ctl_cd_play_vol =
SB_DOUBLE("CD Playback Volume", SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31);
static struct sbmix_elem snd_sb16_ctl_line_capture_route =
SB16_INPUT_SW("Line Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 4, 3);
static struct sbmix_elem snd_sb16_ctl_line_play_switch =
SB_DOUBLE("Line Playback Switch", SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1);
static struct sbmix_elem snd_sb16_ctl_line_play_vol =
SB_DOUBLE("Line Playback Volume", SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31);
static struct sbmix_elem snd_sb16_ctl_mic_capture_route =
SB16_INPUT_SW("Mic Capture Route", SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0);
static struct sbmix_elem snd_sb16_ctl_mic_play_switch =
SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1);
static struct sbmix_elem snd_sb16_ctl_mic_play_vol =
SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31);
static struct sbmix_elem snd_sb16_ctl_pc_speaker_vol =
SB_SINGLE("Beep Volume", SB_DSP4_SPEAKER_DEV, 6, 3);
static struct sbmix_elem snd_sb16_ctl_capture_vol =
SB_DOUBLE("Capture Volume", SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3);
static struct sbmix_elem snd_sb16_ctl_play_vol =
SB_DOUBLE("Playback Volume", SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3);
static struct sbmix_elem snd_sb16_ctl_auto_mic_gain =
SB_SINGLE("Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1);
static struct sbmix_elem *snd_sb16_controls[] = {
&snd_sb16_ctl_master_play_vol,
&snd_sb16_ctl_3d_enhance_switch,
&snd_sb16_ctl_tone_bass,
&snd_sb16_ctl_tone_treble,
&snd_sb16_ctl_pcm_play_vol,
&snd_sb16_ctl_synth_capture_route,
&snd_sb16_ctl_synth_play_vol,
&snd_sb16_ctl_cd_capture_route,
&snd_sb16_ctl_cd_play_switch,
&snd_sb16_ctl_cd_play_vol,
&snd_sb16_ctl_line_capture_route,
&snd_sb16_ctl_line_play_switch,
&snd_sb16_ctl_line_play_vol,
&snd_sb16_ctl_mic_capture_route,
&snd_sb16_ctl_mic_play_switch,
&snd_sb16_ctl_mic_play_vol,
&snd_sb16_ctl_pc_speaker_vol,
&snd_sb16_ctl_capture_vol,
&snd_sb16_ctl_play_vol,
&snd_sb16_ctl_auto_mic_gain
static struct sbmix_elem snd_sb16_controls[] = {
SB_DOUBLE("Master Playback Volume",
SB_DSP4_MASTER_DEV, (SB_DSP4_MASTER_DEV + 1), 3, 3, 31),
SB_DOUBLE("PCM Playback Volume",
SB_DSP4_PCM_DEV, (SB_DSP4_PCM_DEV + 1), 3, 3, 31),
SB16_INPUT_SW("Synth Capture Route",
SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 6, 5),
SB_DOUBLE("Synth Playback Volume",
SB_DSP4_SYNTH_DEV, (SB_DSP4_SYNTH_DEV + 1), 3, 3, 31),
SB16_INPUT_SW("CD Capture Route",
SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 2, 1),
SB_DOUBLE("CD Playback Switch",
SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1),
SB_DOUBLE("CD Playback Volume",
SB_DSP4_CD_DEV, (SB_DSP4_CD_DEV + 1), 3, 3, 31),
SB16_INPUT_SW("Mic Capture Route",
SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 0, 0),
SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1),
SB_SINGLE("Mic Playback Volume", SB_DSP4_MIC_DEV, 3, 31),
SB_SINGLE("Beep Volume", SB_DSP4_SPEAKER_DEV, 6, 3),
SB_DOUBLE("Capture Volume",
SB_DSP4_IGAIN_DEV, (SB_DSP4_IGAIN_DEV + 1), 6, 6, 3),
SB_DOUBLE("Playback Volume",
SB_DSP4_OGAIN_DEV, (SB_DSP4_OGAIN_DEV + 1), 6, 6, 3),
SB16_INPUT_SW("Line Capture Route",
SB_DSP4_INPUT_LEFT, SB_DSP4_INPUT_RIGHT, 4, 3),
SB_DOUBLE("Line Playback Switch",
SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1),
SB_DOUBLE("Line Playback Volume",
SB_DSP4_LINE_DEV, (SB_DSP4_LINE_DEV + 1), 3, 3, 31),
SB_SINGLE("Mic Auto Gain", SB_DSP4_MIC_AGC, 0, 1),
SB_SINGLE("3D Enhancement Switch", SB_DSP4_3DSE, 0, 1),
SB_DOUBLE("Tone Control - Bass",
SB_DSP4_BASS_DEV, (SB_DSP4_BASS_DEV + 1), 4, 4, 15),
SB_DOUBLE("Tone Control - Treble",
SB_DSP4_TREBLE_DEV, (SB_DSP4_TREBLE_DEV + 1), 4, 4, 15)
};
static unsigned char snd_sb16_init_values[][2] = {
@ -678,46 +626,34 @@ static unsigned char snd_sb16_init_values[][2] = {
/*
* DT019x specific mixer elements
*/
static struct sbmix_elem snd_dt019x_ctl_master_play_vol =
SB_DOUBLE("Master Playback Volume", SB_DT019X_MASTER_DEV, SB_DT019X_MASTER_DEV, 4,0, 15);
static struct sbmix_elem snd_dt019x_ctl_pcm_play_vol =
SB_DOUBLE("PCM Playback Volume", SB_DT019X_PCM_DEV, SB_DT019X_PCM_DEV, 4,0, 15);
static struct sbmix_elem snd_dt019x_ctl_synth_play_vol =
SB_DOUBLE("Synth Playback Volume", SB_DT019X_SYNTH_DEV, SB_DT019X_SYNTH_DEV, 4,0, 15);
static struct sbmix_elem snd_dt019x_ctl_cd_play_vol =
SB_DOUBLE("CD Playback Volume", SB_DT019X_CD_DEV, SB_DT019X_CD_DEV, 4,0, 15);
static struct sbmix_elem snd_dt019x_ctl_mic_play_vol =
SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7);
static struct sbmix_elem snd_dt019x_ctl_pc_speaker_vol =
SB_SINGLE("Beep Volume", SB_DT019X_SPKR_DEV, 0, 7);
static struct sbmix_elem snd_dt019x_ctl_line_play_vol =
SB_DOUBLE("Line Playback Volume", SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4,0, 15);
static struct sbmix_elem snd_dt019x_ctl_pcm_play_switch =
SB_DOUBLE("PCM Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2,1, 1);
static struct sbmix_elem snd_dt019x_ctl_synth_play_switch =
SB_DOUBLE("Synth Playback Switch", SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4,3, 1);
static struct sbmix_elem snd_dt019x_ctl_capture_source =
static struct sbmix_elem snd_dt019x_controls[] = {
/* ALS4000 below has some parts which we might be lacking,
* e.g. snd_als4000_ctl_mono_playback_switch - check it! */
SB_DOUBLE("Master Playback Volume",
SB_DT019X_MASTER_DEV, SB_DT019X_MASTER_DEV, 4, 0, 15),
SB_DOUBLE("PCM Playback Switch",
SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2, 1, 1),
SB_DOUBLE("PCM Playback Volume",
SB_DT019X_PCM_DEV, SB_DT019X_PCM_DEV, 4, 0, 15),
SB_DOUBLE("Synth Playback Switch",
SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4, 3, 1),
SB_DOUBLE("Synth Playback Volume",
SB_DT019X_SYNTH_DEV, SB_DT019X_SYNTH_DEV, 4, 0, 15),
SB_DOUBLE("CD Playback Switch",
SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 2, 1, 1),
SB_DOUBLE("CD Playback Volume",
SB_DT019X_CD_DEV, SB_DT019X_CD_DEV, 4, 0, 15),
SB_SINGLE("Mic Playback Switch", SB_DSP4_OUTPUT_SW, 0, 1),
SB_SINGLE("Mic Playback Volume", SB_DT019X_MIC_DEV, 4, 7),
SB_SINGLE("Beep Volume", SB_DT019X_SPKR_DEV, 0, 7),
SB_DOUBLE("Line Playback Switch",
SB_DSP4_OUTPUT_SW, SB_DSP4_OUTPUT_SW, 4, 3, 1),
SB_DOUBLE("Line Playback Volume",
SB_DT019X_LINE_DEV, SB_DT019X_LINE_DEV, 4, 0, 15),
{
.name = "Capture Source",
.type = SB_MIX_CAPTURE_DT019X
};
static struct sbmix_elem *snd_dt019x_controls[] = {
/* ALS4000 below has some parts which we might be lacking,
* e.g. snd_als4000_ctl_mono_playback_switch - check it! */
&snd_dt019x_ctl_master_play_vol,
&snd_dt019x_ctl_pcm_play_vol,
&snd_dt019x_ctl_synth_play_vol,
&snd_dt019x_ctl_cd_play_vol,
&snd_dt019x_ctl_mic_play_vol,
&snd_dt019x_ctl_pc_speaker_vol,
&snd_dt019x_ctl_line_play_vol,
&snd_sb16_ctl_mic_play_switch,
&snd_sb16_ctl_cd_play_switch,
&snd_sb16_ctl_line_play_switch,
&snd_dt019x_ctl_pcm_play_switch,
&snd_dt019x_ctl_synth_play_switch,
&snd_dt019x_ctl_capture_source
}
};
static unsigned char snd_dt019x_init_values[][2] = {
@ -735,82 +671,37 @@ static unsigned char snd_dt019x_init_values[][2] = {
/*
* ALS4000 specific mixer elements
*/
static struct sbmix_elem snd_als4000_ctl_master_mono_playback_switch =
SB_SINGLE("Master Mono Playback Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1);
static struct sbmix_elem snd_als4k_ctl_master_mono_capture_route = {
static struct sbmix_elem snd_als4000_controls[] = {
SB_DOUBLE("PCM Playback Switch",
SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 2, 1, 1),
SB_DOUBLE("Synth Playback Switch",
SB_DT019X_OUTPUT_SW2, SB_DT019X_OUTPUT_SW2, 4, 3, 1),
SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03),
SB_SINGLE("Master Mono Playback Switch", SB_ALS4000_MONO_IO_CTRL, 5, 1),
{
.name = "Master Mono Capture Route",
.type = SB_MIX_MONO_CAPTURE_ALS4K
};
static struct sbmix_elem snd_als4000_ctl_mono_playback_switch =
SB_SINGLE("Mono Playback Switch", SB_DT019X_OUTPUT_SW2, 0, 1);
static struct sbmix_elem snd_als4000_ctl_mic_20db_boost =
SB_SINGLE("Mic Boost (+20dB)", SB_ALS4000_MIC_IN_GAIN, 0, 0x03);
static struct sbmix_elem snd_als4000_ctl_mixer_analog_loopback =
SB_SINGLE("Analog Loopback Switch", SB_ALS4000_MIC_IN_GAIN, 7, 0x01);
static struct sbmix_elem snd_als4000_ctl_mixer_digital_loopback =
},
SB_SINGLE("Mono Playback Switch", SB_DT019X_OUTPUT_SW2, 0, 1),
SB_SINGLE("Analog Loopback Switch", SB_ALS4000_MIC_IN_GAIN, 7, 0x01),
SB_SINGLE("3D Control - Switch", SB_ALS4000_3D_SND_FX, 6, 0x01),
SB_SINGLE("Digital Loopback Switch",
SB_ALS4000_CR3_CONFIGURATION, 7, 0x01);
/* FIXME: functionality of 3D controls might be swapped, I didn't find
* a description of how to identify what is supposed to be what */
static struct sbmix_elem snd_als4000_3d_control_switch =
SB_SINGLE("3D Control - Switch", SB_ALS4000_3D_SND_FX, 6, 0x01);
static struct sbmix_elem snd_als4000_3d_control_ratio =
SB_SINGLE("3D Control - Level", SB_ALS4000_3D_SND_FX, 0, 0x07);
static struct sbmix_elem snd_als4000_3d_control_freq =
SB_ALS4000_CR3_CONFIGURATION, 7, 0x01),
/* FIXME: functionality of 3D controls might be swapped, I didn't find
* a description of how to identify what is supposed to be what */
SB_SINGLE("3D Control - Level", SB_ALS4000_3D_SND_FX, 0, 0x07),
/* FIXME: maybe there's actually some standard 3D ctrl name for it?? */
SB_SINGLE("3D Control - Freq", SB_ALS4000_3D_SND_FX, 4, 0x03);
static struct sbmix_elem snd_als4000_3d_control_delay =
SB_SINGLE("3D Control - Freq", SB_ALS4000_3D_SND_FX, 4, 0x03),
/* FIXME: ALS4000a.pdf mentions BBD (Bucket Brigade Device) time delay,
* but what ALSA 3D attribute is that actually? "Center", "Depth",
* "Wide" or "Space" or even "Level"? Assuming "Wide" for now... */
SB_SINGLE("3D Control - Wide", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f);
static struct sbmix_elem snd_als4000_3d_control_poweroff_switch =
SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01);
static struct sbmix_elem snd_als4000_ctl_3db_freq_control_switch =
SB_SINGLE("3D Control - Wide", SB_ALS4000_3D_TIME_DELAY, 0, 0x0f),
SB_SINGLE("3D PowerOff Switch", SB_ALS4000_3D_TIME_DELAY, 4, 0x01),
SB_SINGLE("Master Playback 8kHz / 20kHz LPF Switch",
SB_ALS4000_FMDAC, 5, 0x01);
SB_ALS4000_FMDAC, 5, 0x01),
#ifdef NOT_AVAILABLE
static struct sbmix_elem snd_als4000_ctl_fmdac =
SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01);
static struct sbmix_elem snd_als4000_ctl_qsound =
SB_SINGLE("QSound Mode", SB_ALS4000_QSOUND, 1, 0x1f);
#endif
static struct sbmix_elem *snd_als4000_controls[] = {
/* ALS4000a.PDF regs page */
&snd_sb16_ctl_master_play_vol, /* MX30/31 12 */
&snd_dt019x_ctl_pcm_play_switch, /* MX4C 16 */
&snd_sb16_ctl_pcm_play_vol, /* MX32/33 12 */
&snd_sb16_ctl_synth_capture_route, /* MX3D/3E 14 */
&snd_dt019x_ctl_synth_play_switch, /* MX4C 16 */
&snd_sb16_ctl_synth_play_vol, /* MX34/35 12/13 */
&snd_sb16_ctl_cd_capture_route, /* MX3D/3E 14 */
&snd_sb16_ctl_cd_play_switch, /* MX3C 14 */
&snd_sb16_ctl_cd_play_vol, /* MX36/37 13 */
&snd_sb16_ctl_line_capture_route, /* MX3D/3E 14 */
&snd_sb16_ctl_line_play_switch, /* MX3C 14 */
&snd_sb16_ctl_line_play_vol, /* MX38/39 13 */
&snd_sb16_ctl_mic_capture_route, /* MX3D/3E 14 */
&snd_als4000_ctl_mic_20db_boost, /* MX4D 16 */
&snd_sb16_ctl_mic_play_switch, /* MX3C 14 */
&snd_sb16_ctl_mic_play_vol, /* MX3A 13 */
&snd_sb16_ctl_pc_speaker_vol, /* MX3B 14 */
&snd_sb16_ctl_capture_vol, /* MX3F/40 15 */
&snd_sb16_ctl_play_vol, /* MX41/42 15 */
&snd_als4000_ctl_master_mono_playback_switch, /* MX4C 16 */
&snd_als4k_ctl_master_mono_capture_route, /* MX4B 16 */
&snd_als4000_ctl_mono_playback_switch, /* MX4C 16 */
&snd_als4000_ctl_mixer_analog_loopback, /* MX4D 16 */
&snd_als4000_ctl_mixer_digital_loopback, /* CR3 21 */
&snd_als4000_3d_control_switch, /* MX50 17 */
&snd_als4000_3d_control_ratio, /* MX50 17 */
&snd_als4000_3d_control_freq, /* MX50 17 */
&snd_als4000_3d_control_delay, /* MX51 18 */
&snd_als4000_3d_control_poweroff_switch, /* MX51 18 */
&snd_als4000_ctl_3db_freq_control_switch, /* MX4F 17 */
#ifdef NOT_AVAILABLE
&snd_als4000_ctl_fmdac,
&snd_als4000_ctl_qsound,
SB_SINGLE("FMDAC Switch (Option ?)", SB_ALS4000_FMDAC, 0, 0x01),
SB_SINGLE("QSound Mode", SB_ALS4000_QSOUND, 1, 0x1f),
#endif
};
@ -829,11 +720,10 @@ static unsigned char snd_als4000_init_values[][2] = {
{ SB_ALS4000_MIC_IN_GAIN, 0 },
};
/*
*/
static int snd_sbmixer_init(struct snd_sb *chip,
struct sbmix_elem **controls,
struct sbmix_elem *controls,
int controls_count,
unsigned char map[][2],
int map_count,
@ -856,7 +746,8 @@ static int snd_sbmixer_init(struct snd_sb *chip,
}
for (idx = 0; idx < controls_count; idx++) {
if ((err = snd_sbmixer_add_ctl_elem(chip, controls[idx])) < 0)
err = snd_sbmixer_add_ctl_elem(chip, &controls[idx]);
if (err < 0)
return err;
}
snd_component_add(card, name);
@ -888,6 +779,7 @@ int snd_sbmixer_new(struct snd_sb *chip)
return err;
break;
case SB_HW_PRO:
case SB_HW_JAZZ16:
if ((err = snd_sbmixer_init(chip,
snd_sbpro_controls,
ARRAY_SIZE(snd_sbpro_controls),
@ -908,6 +800,15 @@ int snd_sbmixer_new(struct snd_sb *chip)
return err;
break;
case SB_HW_ALS4000:
/* use only the first 16 controls from SB16 */
err = snd_sbmixer_init(chip,
snd_sb16_controls,
16,
snd_sb16_init_values,
ARRAY_SIZE(snd_sb16_init_values),
"ALS4000");
if (err < 0)
return err;
if ((err = snd_sbmixer_init(chip,
snd_als4000_controls,
ARRAY_SIZE(snd_als4000_controls),
@ -1029,6 +930,7 @@ void snd_sbmixer_suspend(struct snd_sb *chip)
save_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs));
break;
case SB_HW_PRO:
case SB_HW_JAZZ16:
save_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs));
break;
case SB_HW_16:
@ -1055,6 +957,7 @@ void snd_sbmixer_resume(struct snd_sb *chip)
restore_mixer(chip, sb20_saved_regs, ARRAY_SIZE(sb20_saved_regs));
break;
case SB_HW_PRO:
case SB_HW_JAZZ16:
restore_mixer(chip, sbpro_saved_regs, ARRAY_SIZE(sbpro_saved_regs));
break;
case SB_HW_16:

View file

@ -2014,6 +2014,7 @@ static int snd_wss_info_mux(struct snd_kcontrol *kcontrol,
case WSS_HW_INTERWAVE:
ptexts = gusmax_texts;
break;
case WSS_HW_OPTI93X:
case WSS_HW_OPL3SA2:
ptexts = opl3sa_texts;
break;
@ -2246,54 +2247,12 @@ WSS_SINGLE("Beep Bypass Playback Switch", 0,
CS4231_MONO_CTRL, 5, 1, 0),
};
static struct snd_kcontrol_new snd_opti93x_controls[] = {
WSS_DOUBLE("Master Playback Switch", 0,
OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 7, 7, 1, 1),
WSS_DOUBLE_TLV("Master Playback Volume", 0,
OPTi93X_OUT_LEFT, OPTi93X_OUT_RIGHT, 1, 1, 31, 1,
db_scale_6bit),
WSS_DOUBLE("PCM Playback Switch", 0,
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
WSS_DOUBLE("PCM Playback Volume", 0,
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 31, 1),
WSS_DOUBLE("FM Playback Switch", 0,
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
WSS_DOUBLE("FM Playback Volume", 0,
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 1, 1, 15, 1),
WSS_DOUBLE("Line Playback Switch", 0,
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
WSS_DOUBLE("Line Playback Volume", 0,
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 15, 1),
WSS_DOUBLE("Mic Playback Switch", 0,
OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 7, 7, 1, 1),
WSS_DOUBLE("Mic Playback Volume", 0,
OPTi93X_MIC_LEFT_INPUT, OPTi93X_MIC_RIGHT_INPUT, 1, 1, 15, 1),
WSS_DOUBLE("Mic Boost", 0,
CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
WSS_DOUBLE("CD Playback Switch", 0,
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
WSS_DOUBLE("CD Playback Volume", 0,
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 1, 1, 15, 1),
WSS_DOUBLE("Aux Playback Switch", 0,
OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 7, 7, 1, 1),
WSS_DOUBLE("Aux Playback Volume", 0,
OPTi931_AUX_LEFT_INPUT, OPTi931_AUX_RIGHT_INPUT, 1, 1, 15, 1),
WSS_DOUBLE("Capture Volume", 0,
CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
{
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
.name = "Capture Source",
.info = snd_wss_info_mux,
.get = snd_wss_get_mux,
.put = snd_wss_put_mux,
}
};
int snd_wss_mixer(struct snd_wss *chip)
{
struct snd_card *card;
unsigned int idx;
int err;
int count = ARRAY_SIZE(snd_wss_controls);
if (snd_BUG_ON(!chip || !chip->pcm))
return -EINVAL;
@ -2302,28 +2261,19 @@ int snd_wss_mixer(struct snd_wss *chip)
strcpy(card->mixername, chip->pcm->name);
if (chip->hardware == WSS_HW_OPTI93X)
for (idx = 0; idx < ARRAY_SIZE(snd_opti93x_controls); idx++) {
err = snd_ctl_add(card,
snd_ctl_new1(&snd_opti93x_controls[idx],
chip));
if (err < 0)
return err;
}
else {
int count = ARRAY_SIZE(snd_wss_controls);
/* Use only the first 11 entries on AD1848 */
if (chip->hardware & WSS_HW_AD1848_MASK)
count = 11;
/* There is no loopback on OPTI93X */
else if (chip->hardware == WSS_HW_OPTI93X)
count = 9;
/* Use only the first 11 entries on AD1848 */
if (chip->hardware & WSS_HW_AD1848_MASK)
count = 11;
for (idx = 0; idx < count; idx++) {
err = snd_ctl_add(card,
snd_ctl_new1(&snd_wss_controls[idx],
chip));
if (err < 0)
return err;
}
for (idx = 0; idx < count; idx++) {
err = snd_ctl_add(card,
snd_ctl_new1(&snd_wss_controls[idx],
chip));
if (err < 0)
return err;
}
return 0;
}

View file

@ -26,7 +26,6 @@
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/gfp.h>
#include <linux/vmalloc.h>
#include <linux/interrupt.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
@ -603,25 +602,14 @@ static int snd_sgio2audio_pcm_close(struct snd_pcm_substream *substream)
static int snd_sgio2audio_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
struct snd_pcm_runtime *runtime = substream->runtime;
int size = params_buffer_bytes(hw_params);
/* alloc virtual 'dma' area */
if (runtime->dma_area)
vfree(runtime->dma_area);
runtime->dma_area = vmalloc_user(size);
if (runtime->dma_area == NULL)
return -ENOMEM;
runtime->dma_bytes = size;
return 0;
return snd_pcm_lib_alloc_vmalloc_buffer(substream,
params_buffer_bytes(hw_params));
}
/* hw_free callback */
static int snd_sgio2audio_pcm_hw_free(struct snd_pcm_substream *substream)
{
vfree(substream->runtime->dma_area);
substream->runtime->dma_area = NULL;
return 0;
return snd_pcm_lib_free_vmalloc_buffer(substream);
}
/* prepare callback */
@ -692,13 +680,6 @@ snd_sgio2audio_pcm_pointer(struct snd_pcm_substream *substream)
chip->channel[chan->idx].pos);
}
/* get the physical page pointer on the given offset */
static struct page *snd_sgio2audio_page(struct snd_pcm_substream *substream,
unsigned long offset)
{
return vmalloc_to_page(substream->runtime->dma_area + offset);
}
/* operators */
static struct snd_pcm_ops snd_sgio2audio_playback1_ops = {
.open = snd_sgio2audio_playback1_open,
@ -709,7 +690,8 @@ static struct snd_pcm_ops snd_sgio2audio_playback1_ops = {
.prepare = snd_sgio2audio_pcm_prepare,
.trigger = snd_sgio2audio_pcm_trigger,
.pointer = snd_sgio2audio_pcm_pointer,
.page = snd_sgio2audio_page,
.page = snd_pcm_lib_get_vmalloc_page,
.mmap = snd_pcm_lib_mmap_vmalloc,
};
static struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
@ -721,7 +703,8 @@ static struct snd_pcm_ops snd_sgio2audio_playback2_ops = {
.prepare = snd_sgio2audio_pcm_prepare,
.trigger = snd_sgio2audio_pcm_trigger,
.pointer = snd_sgio2audio_pcm_pointer,
.page = snd_sgio2audio_page,
.page = snd_pcm_lib_get_vmalloc_page,
.mmap = snd_pcm_lib_mmap_vmalloc,
};
static struct snd_pcm_ops snd_sgio2audio_capture_ops = {
@ -733,7 +716,8 @@ static struct snd_pcm_ops snd_sgio2audio_capture_ops = {
.prepare = snd_sgio2audio_pcm_prepare,
.trigger = snd_sgio2audio_pcm_trigger,
.pointer = snd_sgio2audio_pcm_pointer,
.page = snd_sgio2audio_page,
.page = snd_pcm_lib_get_vmalloc_page,
.mmap = snd_pcm_lib_mmap_vmalloc,
};
/*

View file

@ -198,7 +198,7 @@ MODULE_LICENSE("GPL");
* 5530 only. The 5510/5520 decode is different.
*/
static struct pci_device_id id_tbl[] = {
static DEFINE_PCI_DEVICE_TABLE(id_tbl) = {
{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO), 0 },
{ }
};

View file

@ -328,11 +328,11 @@ static int sound_mixer_ioctl(int mixdev, unsigned int cmd, void __user *arg)
return mixer_devs[mixdev]->ioctl(mixdev, cmd, arg);
}
static int sound_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
static long sound_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
int len = 0, dtype;
int dev = iminor(inode);
int dev = iminor(file->f_dentry->d_inode);
long ret = -EINVAL;
void __user *p = (void __user *)arg;
if (_SIOC_DIR(cmd) != _SIOC_NONE && _SIOC_DIR(cmd) != 0) {
@ -353,6 +353,7 @@ static int sound_ioctl(struct inode *inode, struct file *file,
if (cmd == OSS_GETVERSION)
return __put_user(SOUND_VERSION, (int __user *)p);
lock_kernel();
if (_IOC_TYPE(cmd) == 'M' && num_mixers > 0 && /* Mixer ioctl */
(dev & 0x0f) != SND_DEV_CTL) {
dtype = dev & 0x0f;
@ -360,24 +361,31 @@ static int sound_ioctl(struct inode *inode, struct file *file,
case SND_DEV_DSP:
case SND_DEV_DSP16:
case SND_DEV_AUDIO:
return sound_mixer_ioctl(audio_devs[dev >> 4]->mixer_dev,
ret = sound_mixer_ioctl(audio_devs[dev >> 4]->mixer_dev,
cmd, p);
break;
default:
return sound_mixer_ioctl(dev >> 4, cmd, p);
ret = sound_mixer_ioctl(dev >> 4, cmd, p);
break;
}
unlock_kernel();
return ret;
}
switch (dev & 0x0f) {
case SND_DEV_CTL:
if (cmd == SOUND_MIXER_GETLEVELS)
return get_mixer_levels(p);
if (cmd == SOUND_MIXER_SETLEVELS)
return set_mixer_levels(p);
return sound_mixer_ioctl(dev >> 4, cmd, p);
ret = get_mixer_levels(p);
else if (cmd == SOUND_MIXER_SETLEVELS)
ret = set_mixer_levels(p);
else
ret = sound_mixer_ioctl(dev >> 4, cmd, p);
break;
case SND_DEV_SEQ:
case SND_DEV_SEQ2:
return sequencer_ioctl(dev, file, cmd, p);
ret = sequencer_ioctl(dev, file, cmd, p);
break;
case SND_DEV_DSP:
case SND_DEV_DSP16:
@ -390,7 +398,8 @@ static int sound_ioctl(struct inode *inode, struct file *file,
break;
}
return -EINVAL;
unlock_kernel();
return ret;
}
static unsigned int sound_poll(struct file *file, poll_table * wait)
@ -490,7 +499,7 @@ const struct file_operations oss_sound_fops = {
.read = sound_read,
.write = sound_write,
.poll = sound_poll,
.ioctl = sound_ioctl,
.unlocked_ioctl = sound_ioctl,
.mmap = sound_mmap,
.open = sound_open,
.release = sound_release,

View file

@ -1048,7 +1048,7 @@ snd_ad1889_remove(struct pci_dev *pci)
pci_set_drvdata(pci, NULL);
}
static struct pci_device_id snd_ad1889_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_ad1889_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_ANALOG_DEVICES, PCI_DEVICE_ID_AD1889JS) },
{ 0, },
};

View file

@ -275,7 +275,7 @@ struct snd_ali {
#endif
};
static struct pci_device_id snd_ali_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_ali_ids) = {
{PCI_DEVICE(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M5451), 0, 0, 0},
{0, }
};

View file

@ -145,7 +145,7 @@ struct snd_als300_substream_data {
int block_counter_register;
};
static struct pci_device_id snd_als300_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_als300_ids) = {
{ 0x4005, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300 },
{ 0x4005, 0x0308, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_ALS300_PLUS },
{ 0, }

View file

@ -117,7 +117,7 @@ struct snd_card_als4000 {
#endif
};
static struct pci_device_id snd_als4000_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_als4000_ids) = {
{ 0x4005, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* ALS4000 */
{ 0, }
};

View file

@ -286,7 +286,7 @@ struct atiixp {
/*
*/
static struct pci_device_id snd_atiixp_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_atiixp_ids) = {
{ PCI_VDEVICE(ATI, 0x4341), 0 }, /* SB200 */
{ PCI_VDEVICE(ATI, 0x4361), 0 }, /* SB300 */
{ PCI_VDEVICE(ATI, 0x4370), 0 }, /* SB400 */

View file

@ -261,7 +261,7 @@ struct atiixp_modem {
/*
*/
static struct pci_device_id snd_atiixp_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_atiixp_ids) = {
{ PCI_VDEVICE(ATI, 0x434d), 0 }, /* SB200 */
{ PCI_VDEVICE(ATI, 0x4378), 0 }, /* SB400 */
{ 0, }

View file

@ -1,6 +1,6 @@
#include "au8810.h"
#include "au88x0.h"
static struct pci_device_id snd_vortex_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_vortex_ids) = {
{PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_ADVANTAGE), 1,},
{0,}
};

View file

@ -1,6 +1,6 @@
#include "au8820.h"
#include "au88x0.h"
static struct pci_device_id snd_vortex_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_vortex_ids) = {
{PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_1), 0,},
{0,}
};

View file

@ -1,6 +1,6 @@
#include "au8830.h"
#include "au88x0.h"
static struct pci_device_id snd_vortex_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_vortex_ids) = {
{PCI_VDEVICE(AUREAL, PCI_DEVICE_ID_AUREAL_VORTEX_2), 0,},
{0,}
};

View file

@ -164,7 +164,7 @@ MODULE_PARM_DESC(id, "ID string for the Audiowerk2 soundcard.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard.");
static struct pci_device_id snd_aw2_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_aw2_ids) = {
{PCI_VENDOR_ID_SAA7146, PCI_DEVICE_ID_SAA7146, 0, 0,
0, 0, 0},
{0}

View file

@ -350,7 +350,7 @@ struct snd_azf3328 {
#endif
};
static const struct pci_device_id snd_azf3328_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_azf3328_ids) = {
{ 0x122D, 0x50DC, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* PCI168/3328 */
{ 0x122D, 0x80DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* 3328 */
{ 0, }

View file

@ -795,7 +795,7 @@ fail:
.driver_data = SND_BT87X_BOARD_ ## id }
/* driver_data is the card id for that device */
static struct pci_device_id snd_bt87x_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_bt87x_ids) = {
/* Hauppauge WinTV series */
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0x13eb, GENERIC),
/* Hauppauge WinTV series */
@ -964,7 +964,7 @@ static void __devexit snd_bt87x_remove(struct pci_dev *pci)
/* default entries for all Bt87x cards - it's not exported */
/* driver_data is set to 0 to call detection */
static struct pci_device_id snd_bt87x_default_ids[] __devinitdata = {
static DEFINE_PCI_DEVICE_TABLE(snd_bt87x_default_ids) = {
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN),
BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, PCI_ANY_ID, PCI_ANY_ID, UNKNOWN),
{ }

View file

@ -1875,7 +1875,7 @@ static int snd_ca0106_resume(struct pci_dev *pci)
#endif
// PCI IDs
static struct pci_device_id snd_ca0106_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_ca0106_ids) = {
{ PCI_VDEVICE(CREATIVE, 0x0007), 0 }, /* Audigy LS or Live 24bit */
{ 0, }
};

View file

@ -2796,7 +2796,7 @@ static inline void snd_cmipci_proc_init(struct cmipci *cm) {}
#endif
static struct pci_device_id snd_cmipci_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_cmipci_ids) = {
{PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338A), 0},
{PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8338B), 0},
{PCI_VDEVICE(CMEDIA, PCI_DEVICE_ID_CMEDIA_CM8738), 0},
@ -3018,7 +3018,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
int integrated_midi = 0;
char modelstr[16];
int pcm_index, pcm_spdif_index;
static struct pci_device_id intel_82437vx[] = {
static DEFINE_PCI_DEVICE_TABLE(intel_82437vx) = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437VX) },
{ },
};

View file

@ -494,7 +494,7 @@ struct cs4281 {
static irqreturn_t snd_cs4281_interrupt(int irq, void *dev_id);
static struct pci_device_id snd_cs4281_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_cs4281_ids) = {
{ PCI_VDEVICE(CIRRUS, 0x6005), 0, }, /* CS4281 */
{ 0, }
};

View file

@ -64,7 +64,7 @@ MODULE_PARM_DESC(thinkpad, "Force to enable Thinkpad's CLKRUN control.");
module_param_array(mmap_valid, bool, NULL, 0444);
MODULE_PARM_DESC(mmap_valid, "Support OSS mmap.");
static struct pci_device_id snd_cs46xx_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_cs46xx_ids) = {
{ PCI_VDEVICE(CIRRUS, 0x6001), 0, }, /* CS4280 */
{ PCI_VDEVICE(CIRRUS, 0x6003), 0, }, /* CS4612 */
{ PCI_VDEVICE(CIRRUS, 0x6004), 0, }, /* CS4615 */

View file

@ -3597,7 +3597,7 @@ static struct cs_card_type __devinitdata cards[] = {
#ifdef CONFIG_PM
static unsigned int saved_regs[] = {
BA0_ACOSV,
BA0_ASER_FADDR,
/*BA0_ASER_FADDR,*/
BA0_ASER_MASTER,
BA1_PVOL,
BA1_CVOL,
@ -3644,6 +3644,7 @@ int snd_cs46xx_resume(struct pci_dev *pci)
#ifdef CONFIG_SND_CS46XX_NEW_DSP
int i;
#endif
unsigned int tmp;
pci_set_power_state(pci, PCI_D0);
pci_restore_state(pci);
@ -3685,6 +3686,15 @@ int snd_cs46xx_resume(struct pci_dev *pci)
snd_ac97_resume(chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]);
snd_ac97_resume(chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]);
/*
* Stop capture DMA.
*/
tmp = snd_cs46xx_peek(chip, BA1_CCTL);
chip->capt.ctl = tmp & 0x0000ffff;
snd_cs46xx_poke(chip, BA1_CCTL, tmp & 0xffff0000);
mdelay(5);
/* reset playback/capture */
snd_cs46xx_set_play_sample_rate(chip, 8000);
snd_cs46xx_set_capture_sample_rate(chip, 8000);

View file

@ -298,6 +298,9 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip)
if (ins->scbs[i].deleted) continue;
cs46xx_dsp_proc_free_scb_desc ( (ins->scbs + i) );
#ifdef CONFIG_PM
kfree(ins->scbs[i].data);
#endif
}
kfree(ins->code.data);
@ -974,13 +977,11 @@ static struct dsp_scb_descriptor * _map_scb (struct snd_cs46xx *chip, char * nam
index = find_free_scb_index (ins);
memset(&ins->scbs[index], 0, sizeof(ins->scbs[index]));
strcpy(ins->scbs[index].scb_name, name);
ins->scbs[index].address = dest;
ins->scbs[index].index = index;
ins->scbs[index].proc_info = NULL;
ins->scbs[index].ref_count = 1;
ins->scbs[index].deleted = 0;
spin_lock_init(&ins->scbs[index].lock);
desc = (ins->scbs + index);
ins->scbs[index].scb_symbol = add_symbol (chip, name, dest, SYMBOL_PARAMETER);
@ -1022,17 +1023,29 @@ _map_task_tree (struct snd_cs46xx *chip, char * name, u32 dest, u32 size)
return desc;
}
#define SCB_BYTES (0x10 * 4)
struct dsp_scb_descriptor *
cs46xx_dsp_create_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u32 dest)
{
struct dsp_scb_descriptor * desc;
#ifdef CONFIG_PM
/* copy the data for resume */
scb_data = kmemdup(scb_data, SCB_BYTES, GFP_KERNEL);
if (!scb_data)
return NULL;
#endif
desc = _map_scb (chip,name,dest);
if (desc) {
desc->data = scb_data;
_dsp_create_scb(chip,scb_data,dest);
} else {
snd_printk(KERN_ERR "dsp_spos: failed to map SCB\n");
#ifdef CONFIG_PM
kfree(scb_data);
#endif
}
return desc;
@ -1988,7 +2001,28 @@ int cs46xx_dsp_resume(struct snd_cs46xx * chip)
continue;
_dsp_create_scb(chip, s->data, s->address);
}
for (i = 0; i < ins->nscb; i++) {
struct dsp_scb_descriptor *s = &ins->scbs[i];
if (s->deleted)
continue;
if (s->updated)
cs46xx_dsp_spos_update_scb(chip, s);
if (s->volume_set)
cs46xx_dsp_scb_set_volume(chip, s,
s->volume[0], s->volume[1]);
}
if (ins->spdif_status_out & DSP_SPDIF_STATUS_HW_ENABLED) {
cs46xx_dsp_enable_spdif_hw(chip);
snd_cs46xx_poke(chip, (ins->ref_snoop_scb->address + 2) << 2,
(OUTPUT_SNOOP_BUFFER + 0x10) << 0x10);
if (ins->spdif_status_out & DSP_SPDIF_STATUS_PLAYBACK_OPEN)
cs46xx_poke_via_dsp(chip, SP_SPDOUT_CSUV,
ins->spdif_csuv_stream);
}
if (chip->dsp_spos_instance->spdif_status_in) {
cs46xx_poke_via_dsp(chip, SP_ASER_COUNTDOWN, 0x80000005);
cs46xx_poke_via_dsp(chip, SP_SPDIN_CONTROL, 0x800003ff);
}
return 0;
}
#endif

View file

@ -212,6 +212,7 @@ static inline void cs46xx_dsp_spos_update_scb (struct snd_cs46xx * chip,
(scb->address + SCBsubListPtr) << 2,
(scb->sub_list_ptr->address << 0x10) |
(scb->next_scb_ptr->address));
scb->updated = 1;
}
static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip,
@ -222,6 +223,9 @@ static inline void cs46xx_dsp_scb_set_volume (struct snd_cs46xx * chip,
snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl) << 2, val);
snd_cs46xx_poke(chip, (scb->address + SCBVolumeCtrl + 1) << 2, val);
scb->volume_set = 1;
scb->volume[0] = left;
scb->volume[1] = right;
}
#endif /* __DSP_SPOS_H__ */
#endif /* CONFIG_SND_CS46XX_NEW_DSP */

View file

@ -115,7 +115,6 @@ static void cs46xx_dsp_proc_scb_info_read (struct snd_info_entry *entry,
static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * scb)
{
struct dsp_spos_instance * ins = chip->dsp_spos_instance;
unsigned long flags;
if ( scb->parent_scb_ptr ) {
/* unlink parent SCB */
@ -153,8 +152,6 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor
scb->next_scb_ptr = ins->the_null_scb;
}
spin_lock_irqsave(&chip->reg_lock, flags);
/* update parent first entry in DSP RAM */
cs46xx_dsp_spos_update_scb(chip,scb->parent_scb_ptr);
@ -162,7 +159,6 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor
cs46xx_dsp_spos_update_scb(chip,scb);
scb->parent_scb_ptr = NULL;
spin_unlock_irqrestore(&chip->reg_lock, flags);
}
}
@ -197,9 +193,9 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor *
goto _end;
#endif
spin_lock_irqsave(&scb->lock, flags);
spin_lock_irqsave(&chip->reg_lock, flags);
_dsp_unlink_scb (chip,scb);
spin_unlock_irqrestore(&scb->lock, flags);
spin_unlock_irqrestore(&chip->reg_lock, flags);
cs46xx_dsp_proc_free_scb_desc(scb);
if (snd_BUG_ON(!scb->scb_symbol))
@ -207,6 +203,10 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor *
remove_symbol (chip,scb->scb_symbol);
ins->scbs[scb->index].deleted = 1;
#ifdef CONFIG_PM
kfree(ins->scbs[scb->index].data);
ins->scbs[scb->index].data = NULL;
#endif
if (scb->index < ins->scb_highest_frag_index)
ins->scb_highest_frag_index = scb->index;
@ -1508,20 +1508,17 @@ int cs46xx_dsp_pcm_unlink (struct snd_cs46xx * chip,
chip->dsp_spos_instance->npcm_channels <= 0))
return -EIO;
spin_lock(&pcm_channel->src_scb->lock);
spin_lock_irqsave(&chip->reg_lock, flags);
if (pcm_channel->unlinked) {
spin_unlock(&pcm_channel->src_scb->lock);
spin_unlock_irqrestore(&chip->reg_lock, flags);
return -EIO;
}
spin_lock_irqsave(&chip->reg_lock, flags);
pcm_channel->unlinked = 1;
spin_unlock_irqrestore(&chip->reg_lock, flags);
_dsp_unlink_scb (chip,pcm_channel->pcm_reader_scb);
spin_unlock_irqrestore(&chip->reg_lock, flags);
spin_unlock(&pcm_channel->src_scb->lock);
return 0;
}
@ -1533,10 +1530,10 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
struct dsp_scb_descriptor * src_scb = pcm_channel->src_scb;
unsigned long flags;
spin_lock(&pcm_channel->src_scb->lock);
spin_lock_irqsave(&chip->reg_lock, flags);
if (pcm_channel->unlinked == 0) {
spin_unlock(&pcm_channel->src_scb->lock);
spin_unlock_irqrestore(&chip->reg_lock, flags);
return -EIO;
}
@ -1552,8 +1549,6 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
snd_BUG_ON(pcm_channel->pcm_reader_scb->parent_scb_ptr);
pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb;
spin_lock_irqsave(&chip->reg_lock, flags);
/* update SCB entry in DSP RAM */
cs46xx_dsp_spos_update_scb(chip,pcm_channel->pcm_reader_scb);
@ -1562,8 +1557,6 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip,
pcm_channel->unlinked = 0;
spin_unlock_irqrestore(&chip->reg_lock, flags);
spin_unlock(&pcm_channel->src_scb->lock);
return 0;
}
@ -1596,13 +1589,17 @@ cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * s
int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src)
{
unsigned long flags;
if (snd_BUG_ON(!src->parent_scb_ptr))
return -EINVAL;
/* mute SCB */
cs46xx_dsp_scb_set_volume (chip,src,0,0);
spin_lock_irqsave(&chip->reg_lock, flags);
_dsp_unlink_scb (chip,src);
spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0;
}

View file

@ -58,7 +58,7 @@ struct snd_cs5530 {
unsigned long pci_base;
};
static struct pci_device_id snd_cs5530_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_cs5530_ids) = {
{PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_AUDIO, PCI_ANY_ID,
PCI_ANY_ID, 0, 0},
{0,}

View file

@ -66,7 +66,7 @@ MODULE_PARM_DESC(id, "ID string for " DRIVER_NAME);
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable " DRIVER_NAME);
static struct pci_device_id snd_cs5535audio_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_cs5535audio_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_AUDIO) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_AUDIO) },
{}

View file

@ -1214,10 +1214,11 @@ static int atc_dev_free(struct snd_device *dev)
return ct_atc_destroy(atc);
}
static int __devinit atc_identify_card(struct ct_atc *atc)
static int __devinit atc_identify_card(struct ct_atc *atc, unsigned int ssid)
{
const struct snd_pci_quirk *p;
const struct snd_pci_quirk *list;
u16 vendor_id, device_id;
switch (atc->chip_type) {
case ATC20K1:
@ -1231,13 +1232,19 @@ static int __devinit atc_identify_card(struct ct_atc *atc)
default:
return -ENOENT;
}
p = snd_pci_quirk_lookup(atc->pci, list);
if (ssid) {
vendor_id = ssid >> 16;
device_id = ssid & 0xffff;
} else {
vendor_id = atc->pci->subsystem_vendor;
device_id = atc->pci->subsystem_device;
}
p = snd_pci_quirk_lookup_id(vendor_id, device_id, list);
if (p) {
if (p->value < 0) {
printk(KERN_ERR "ctxfi: "
"Device %04x:%04x is black-listed\n",
atc->pci->subsystem_vendor,
atc->pci->subsystem_device);
vendor_id, device_id);
return -ENOENT;
}
atc->model = p->value;
@ -1250,8 +1257,7 @@ static int __devinit atc_identify_card(struct ct_atc *atc)
atc->model_name = ct_subsys_name[atc->model];
snd_printd("ctxfi: chip %s model %s (%04x:%04x) is found\n",
atc->chip_name, atc->model_name,
atc->pci->subsystem_vendor,
atc->pci->subsystem_device);
vendor_id, device_id);
return 0;
}
@ -1625,7 +1631,8 @@ static struct ct_atc atc_preset __devinitdata = {
int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
unsigned int rsr, unsigned int msr,
int chip_type, struct ct_atc **ratc)
int chip_type, unsigned int ssid,
struct ct_atc **ratc)
{
struct ct_atc *atc;
static struct snd_device_ops ops = {
@ -1651,7 +1658,7 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
mutex_init(&atc->atc_mutex);
/* Find card model */
err = atc_identify_card(atc);
err = atc_identify_card(atc, ssid);
if (err < 0) {
printk(KERN_ERR "ctatc: Card not recognised\n");
goto error1;

View file

@ -148,7 +148,7 @@ struct ct_atc {
int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci,
unsigned int rsr, unsigned int msr, int chip_type,
struct ct_atc **ratc);
unsigned int subsysid, struct ct_atc **ratc);
int __devinit ct_atc_create_alsa_devs(struct ct_atc *atc);
#endif /* CTATC_H */

View file

@ -32,6 +32,7 @@ module_param(multiple, uint, S_IRUGO);
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
static unsigned int subsystem[SNDRV_CARDS];
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for Creative X-Fi driver");
@ -39,8 +40,10 @@ module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for Creative X-Fi driver");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable Creative X-Fi driver");
module_param_array(subsystem, int, NULL, 0444);
MODULE_PARM_DESC(subsystem, "Override subsystem ID for Creative X-Fi driver");
static struct pci_device_id ct_pci_dev_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(ct_pci_dev_ids) = {
/* only X-Fi is supported, so... */
{ PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_20K1),
.driver_data = ATC20K1,
@ -85,7 +88,7 @@ ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
multiple = 2;
}
err = ct_atc_create(card, pci, reference_rate, multiple,
pci_id->driver_data, &atc);
pci_id->driver_data, subsystem[dev], &atc);
if (err < 0)
goto error;

View file

@ -63,7 +63,7 @@ static const struct firmware card_fw[] = {
{0, "darla20_dsp.fw"}
};
static struct pci_device_id snd_echo_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
{0x1057, 0x1801, 0xECC0, 0x0010, 0, 0, 0}, /* DSP 56301 Darla20 rev.0 */
{0,}
};

View file

@ -45,7 +45,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->device_id = device_id;
chip->subdevice_id = subdevice_id;
chip->bad_board = TRUE;
chip->dsp_code_to_load = &card_fw[FW_DARLA20_DSP];
chip->dsp_code_to_load = FW_DARLA20_DSP;
chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
chip->clock_state = GD_CLOCK_UNDEF;
/* Since this card has no ASIC, mark it as loaded so everything
@ -57,15 +57,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
return err;
chip->bad_board = FALSE;
if ((err = init_line_levels(chip)) < 0)
return err;
DE_INIT(("init_hw done\n"));
return err;
}
static int set_mixer_defaults(struct echoaudio *chip)
{
return init_line_levels(chip);
}
/* The Darla20 has no external clock sources */
static u32 detect_input_clocks(const struct echoaudio *chip)
{

View file

@ -67,7 +67,7 @@ static const struct firmware card_fw[] = {
{0, "darla24_dsp.fw"}
};
static struct pci_device_id snd_echo_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
{0x1057, 0x1801, 0xECC0, 0x0040, 0, 0, 0}, /* DSP 56301 Darla24 rev.0 */
{0x1057, 0x1801, 0xECC0, 0x0041, 0, 0, 0}, /* DSP 56301 Darla24 rev.1 */
{0,}

View file

@ -45,7 +45,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->device_id = device_id;
chip->subdevice_id = subdevice_id;
chip->bad_board = TRUE;
chip->dsp_code_to_load = &card_fw[FW_DARLA24_DSP];
chip->dsp_code_to_load = FW_DARLA24_DSP;
/* Since this card has no ASIC, mark it as loaded so everything
works OK */
chip->asic_loaded = TRUE;
@ -56,15 +56,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
return err;
chip->bad_board = FALSE;
if ((err = init_line_levels(chip)) < 0)
return err;
DE_INIT(("init_hw done\n"));
return err;
}
static int set_mixer_defaults(struct echoaudio *chip)
{
return init_line_levels(chip);
}
static u32 detect_input_clocks(const struct echoaudio *chip)
{
u32 clocks_from_dsp, clock_bits;

View file

@ -81,7 +81,7 @@ static const struct firmware card_fw[] = {
{0, "3g_asic.fw"}
};
static struct pci_device_id snd_echo_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
{0x1057, 0x3410, 0xECC0, 0x0100, 0, 0, 0}, /* Echo 3G */
{0,}
};

View file

@ -61,7 +61,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->subdevice_id = subdevice_id;
chip->bad_board = TRUE;
chip->has_midi = TRUE;
chip->dsp_code_to_load = &card_fw[FW_ECHO3G_DSP];
chip->dsp_code_to_load = FW_ECHO3G_DSP;
/* Load the DSP code and the ASIC on the PCI card and get
what type of external box is attached */
@ -97,20 +97,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->digital_modes = ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
chip->professional_spdif = FALSE;
chip->non_audio_spdif = FALSE;
chip->bad_board = FALSE;
if ((err = init_line_levels(chip)) < 0)
return err;
err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
if (err < 0)
return err;
err = set_phantom_power(chip, 0);
if (err < 0)
return err;
err = set_professional_spdif(chip, TRUE);
DE_INIT(("init_hw done\n"));
return err;
@ -118,6 +104,18 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
static int set_mixer_defaults(struct echoaudio *chip)
{
chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
chip->professional_spdif = FALSE;
chip->non_audio_spdif = FALSE;
chip->bad_board = FALSE;
chip->phantom_power = FALSE;
return init_line_levels(chip);
}
static int set_phantom_power(struct echoaudio *chip, char on)
{
u32 control_reg = le32_to_cpu(chip->comm_page->control_register);

View file

@ -36,22 +36,61 @@ MODULE_PARM_DESC(enable, "Enable " ECHOCARD_NAME " soundcard.");
static unsigned int channels_list[10] = {1, 2, 4, 6, 8, 10, 12, 14, 16, 999999};
static const DECLARE_TLV_DB_SCALE(db_scale_output_gain, -12800, 100, 1);
static int get_firmware(const struct firmware **fw_entry,
const struct firmware *frm, struct echoaudio *chip)
struct echoaudio *chip, const short fw_index)
{
int err;
char name[30];
DE_ACT(("firmware requested: %s\n", frm->data));
snprintf(name, sizeof(name), "ea/%s", frm->data);
if ((err = request_firmware(fw_entry, name, pci_device(chip))) < 0)
#ifdef CONFIG_PM
if (chip->fw_cache[fw_index]) {
DE_ACT(("firmware requested: %s is cached\n", card_fw[fw_index].data));
*fw_entry = chip->fw_cache[fw_index];
return 0;
}
#endif
DE_ACT(("firmware requested: %s\n", card_fw[fw_index].data));
snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data);
err = request_firmware(fw_entry, name, pci_device(chip));
if (err < 0)
snd_printk(KERN_ERR "get_firmware(): Firmware not available (%d)\n", err);
#ifdef CONFIG_PM
else
chip->fw_cache[fw_index] = *fw_entry;
#endif
return err;
}
static void free_firmware(const struct firmware *fw_entry)
{
#ifdef CONFIG_PM
DE_ACT(("firmware not released (kept in cache)\n"));
#else
release_firmware(fw_entry);
DE_ACT(("firmware released\n"));
#endif
}
static void free_firmware_cache(struct echoaudio *chip)
{
#ifdef CONFIG_PM
int i;
for (i = 0; i < 8 ; i++)
if (chip->fw_cache[i]) {
release_firmware(chip->fw_cache[i]);
DE_ACT(("release_firmware(%d)\n", i));
}
DE_ACT(("firmware_cache released\n"));
#endif
}
@ -714,6 +753,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
spin_lock(&chip->lock);
switch (cmd) {
case SNDRV_PCM_TRIGGER_RESUME:
DE_ACT(("pcm_trigger resume\n"));
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
DE_ACT(("pcm_trigger start\n"));
@ -737,6 +778,8 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd)
err = start_transport(chip, channelmask,
chip->pipe_cyclic_mask);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
DE_ACT(("pcm_trigger suspend\n"));
case SNDRV_PCM_TRIGGER_STOP:
DE_ACT(("pcm_trigger stop\n"));
for (i = 0; i < DSP_MAXPIPES; i++) {
@ -1874,6 +1917,7 @@ static int snd_echo_free(struct echoaudio *chip)
pci_disable_device(chip->pci);
/* release chip data */
free_firmware_cache(chip);
kfree(chip);
DE_INIT(("Chip freed.\n"));
return 0;
@ -1911,18 +1955,27 @@ static __devinit int snd_echo_create(struct snd_card *card,
return err;
pci_set_master(pci);
/* allocate a chip-specific data */
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (!chip) {
pci_disable_device(pci);
return -ENOMEM;
/* Allocate chip if needed */
if (!*rchip) {
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (!chip) {
pci_disable_device(pci);
return -ENOMEM;
}
DE_INIT(("chip=%p\n", chip));
spin_lock_init(&chip->lock);
chip->card = card;
chip->pci = pci;
chip->irq = -1;
atomic_set(&chip->opencount, 0);
mutex_init(&chip->mode_mutex);
chip->can_set_rate = 1;
} else {
/* If this was called from the resume function, chip is
* already allocated and it contains current card settings.
*/
chip = *rchip;
}
DE_INIT(("chip=%p\n", chip));
spin_lock_init(&chip->lock);
chip->card = card;
chip->pci = pci;
chip->irq = -1;
/* PCI resource allocation */
chip->dsp_registers_phys = pci_resource_start(pci, 0);
@ -1962,7 +2015,9 @@ static __devinit int snd_echo_create(struct snd_card *card,
chip->comm_page = (struct comm_page *)chip->commpage_dma_buf.area;
err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
if (err) {
if (err >= 0)
err = set_mixer_defaults(chip);
if (err < 0) {
DE_INIT(("init_hw err=%d\n", err));
snd_echo_free(chip);
return err;
@ -1973,9 +2028,6 @@ static __devinit int snd_echo_create(struct snd_card *card,
snd_echo_free(chip);
return err;
}
atomic_set(&chip->opencount, 0);
mutex_init(&chip->mode_mutex);
chip->can_set_rate = 1;
*rchip = chip;
/* Init done ! */
return 0;
@ -2008,6 +2060,7 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
snd_card_set_dev(card, &pci->dev);
chip = NULL; /* Tells snd_echo_create to allocate chip */
if ((err = snd_echo_create(card, pci, &chip)) < 0) {
snd_card_free(card);
return err;
@ -2147,6 +2200,112 @@ ctl_error:
#if defined(CONFIG_PM)
static int snd_echo_suspend(struct pci_dev *pci, pm_message_t state)
{
struct echoaudio *chip = pci_get_drvdata(pci);
DE_INIT(("suspend start\n"));
snd_pcm_suspend_all(chip->analog_pcm);
snd_pcm_suspend_all(chip->digital_pcm);
#ifdef ECHOCARD_HAS_MIDI
/* This call can sleep */
if (chip->midi_out)
snd_echo_midi_output_trigger(chip->midi_out, 0);
#endif
spin_lock_irq(&chip->lock);
if (wait_handshake(chip)) {
spin_unlock_irq(&chip->lock);
return -EIO;
}
clear_handshake(chip);
if (send_vector(chip, DSP_VC_GO_COMATOSE) < 0) {
spin_unlock_irq(&chip->lock);
return -EIO;
}
spin_unlock_irq(&chip->lock);
chip->dsp_code = NULL;
free_irq(chip->irq, chip);
chip->irq = -1;
pci_save_state(pci);
pci_disable_device(pci);
DE_INIT(("suspend done\n"));
return 0;
}
static int snd_echo_resume(struct pci_dev *pci)
{
struct echoaudio *chip = pci_get_drvdata(pci);
struct comm_page *commpage, *commpage_bak;
u32 pipe_alloc_mask;
int err;
DE_INIT(("resume start\n"));
pci_restore_state(pci);
commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL);
commpage = chip->comm_page;
memcpy(commpage_bak, commpage, sizeof(struct comm_page));
err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
if (err < 0) {
kfree(commpage_bak);
DE_INIT(("resume init_hw err=%d\n", err));
snd_echo_free(chip);
return err;
}
DE_INIT(("resume init OK\n"));
/* Temporarily set chip->pipe_alloc_mask=0 otherwise
* restore_dsp_settings() fails.
*/
pipe_alloc_mask = chip->pipe_alloc_mask;
chip->pipe_alloc_mask = 0;
err = restore_dsp_rettings(chip);
chip->pipe_alloc_mask = pipe_alloc_mask;
if (err < 0) {
kfree(commpage_bak);
return err;
}
DE_INIT(("resume restore OK\n"));
memcpy(&commpage->audio_format, &commpage_bak->audio_format,
sizeof(commpage->audio_format));
memcpy(&commpage->sglist_addr, &commpage_bak->sglist_addr,
sizeof(commpage->sglist_addr));
memcpy(&commpage->midi_output, &commpage_bak->midi_output,
sizeof(commpage->midi_output));
kfree(commpage_bak);
if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
ECHOCARD_NAME, chip)) {
snd_echo_free(chip);
snd_printk(KERN_ERR "cannot grab irq\n");
return -EBUSY;
}
chip->irq = pci->irq;
DE_INIT(("resume irq=%d\n", chip->irq));
#ifdef ECHOCARD_HAS_MIDI
if (chip->midi_input_enabled)
enable_midi_input(chip, TRUE);
if (chip->midi_out)
snd_echo_midi_output_trigger(chip->midi_out, 1);
#endif
DE_INIT(("resume done\n"));
return 0;
}
#endif /* CONFIG_PM */
static void __devexit snd_echo_remove(struct pci_dev *pci)
{
struct echoaudio *chip;
@ -2169,6 +2328,10 @@ static struct pci_driver driver = {
.id_table = snd_echo_ids,
.probe = snd_echo_probe,
.remove = __devexit_p(snd_echo_remove),
#ifdef CONFIG_PM
.suspend = snd_echo_suspend,
.resume = snd_echo_resume,
#endif /* CONFIG_PM */
};

View file

@ -442,13 +442,16 @@ struct echoaudio {
u16 device_id, subdevice_id;
u16 *dsp_code; /* Current DSP code loaded,
* NULL if nothing loaded */
const struct firmware *dsp_code_to_load;/* DSP code to load */
const struct firmware *asic_code; /* Current ASIC code */
short dsp_code_to_load; /* DSP code to load */
short asic_code; /* Current ASIC code */
u32 comm_page_phys; /* Physical address of the
* memory seen by DSP */
volatile u32 __iomem *dsp_registers; /* DSP's register base */
u32 active_mask; /* Chs. active mask or
* punks out */
#ifdef CONFIG_PM
const struct firmware *fw_cache[8]; /* Cached firmwares */
#endif
#ifdef ECHOCARD_HAS_MIDI
u16 mtc_state; /* State for MIDI input parsing state machine */
@ -464,11 +467,13 @@ static int load_firmware(struct echoaudio *chip);
static int wait_handshake(struct echoaudio *chip);
static int send_vector(struct echoaudio *chip, u32 command);
static int get_firmware(const struct firmware **fw_entry,
const struct firmware *frm, struct echoaudio *chip);
struct echoaudio *chip, const short fw_index);
static void free_firmware(const struct firmware *fw_entry);
#ifdef ECHOCARD_HAS_MIDI
static int enable_midi_input(struct echoaudio *chip, char enable);
static void snd_echo_midi_output_trigger(
struct snd_rawmidi_substream *substream, int up);
static int midi_service_irq(struct echoaudio *chip);
static int __devinit snd_echo_midi_create(struct snd_card *card,
struct echoaudio *chip);

View file

@ -227,12 +227,11 @@ static int load_asic(struct echoaudio *chip)
/* Give the DSP a few milliseconds to settle down */
mdelay(2);
err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC,
&card_fw[FW_3G_ASIC]);
err = load_asic_generic(chip, DSP_FNC_LOAD_3G_ASIC, FW_3G_ASIC);
if (err < 0)
return err;
chip->asic_code = &card_fw[FW_3G_ASIC];
chip->asic_code = FW_3G_ASIC;
/* Now give the new ASIC some time to set up */
msleep(1000);

View file

@ -175,15 +175,15 @@ static inline int check_asic_status(struct echoaudio *chip)
#ifdef ECHOCARD_HAS_ASIC
/* Load ASIC code - done after the DSP is loaded */
static int load_asic_generic(struct echoaudio *chip, u32 cmd,
const struct firmware *asic)
static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic)
{
const struct firmware *fw;
int err;
u32 i, size;
u8 *code;
if ((err = get_firmware(&fw, asic, chip)) < 0) {
err = get_firmware(&fw, chip, asic);
if (err < 0) {
snd_printk(KERN_WARNING "Firmware not found !\n");
return err;
}
@ -245,7 +245,8 @@ static int install_resident_loader(struct echoaudio *chip)
return 0;
}
if ((i = get_firmware(&fw, &card_fw[FW_361_LOADER], chip)) < 0) {
i = get_firmware(&fw, chip, FW_361_LOADER);
if (i < 0) {
snd_printk(KERN_WARNING "Firmware not found !\n");
return i;
}
@ -485,7 +486,8 @@ static int load_firmware(struct echoaudio *chip)
chip->dsp_code = NULL;
}
if ((err = get_firmware(&fw, chip->dsp_code_to_load, chip)) < 0)
err = get_firmware(&fw, chip, chip->dsp_code_to_load);
if (err < 0)
return err;
err = load_dsp(chip, (u16 *)fw->data);
free_firmware(fw);
@ -495,9 +497,6 @@ static int load_firmware(struct echoaudio *chip)
if ((box_type = load_asic(chip)) < 0)
return box_type; /* error */
if ((err = restore_dsp_rettings(chip)) < 0)
return err;
return box_type;
}
@ -657,25 +656,89 @@ static void get_audio_meters(struct echoaudio *chip, long *meters)
static int restore_dsp_rettings(struct echoaudio *chip)
{
int err;
int i, o, err;
DE_INIT(("restore_dsp_settings\n"));
if ((err = check_asic_status(chip)) < 0)
return err;
/* @ Gina20/Darla20 only. Should be harmless for other cards. */
/* Gina20/Darla20 only. Should be harmless for other cards. */
chip->comm_page->gd_clock_state = GD_CLOCK_UNDEF;
chip->comm_page->gd_spdif_status = GD_SPDIF_STATUS_UNDEF;
chip->comm_page->handshake = 0xffffffff;
if ((err = set_sample_rate(chip, chip->sample_rate)) < 0)
/* Restore output busses */
for (i = 0; i < num_busses_out(chip); i++) {
err = set_output_gain(chip, i, chip->output_gain[i]);
if (err < 0)
return err;
}
#ifdef ECHOCARD_HAS_VMIXER
for (i = 0; i < num_pipes_out(chip); i++)
for (o = 0; o < num_busses_out(chip); o++) {
err = set_vmixer_gain(chip, o, i,
chip->vmixer_gain[o][i]);
if (err < 0)
return err;
}
if (update_vmixer_level(chip) < 0)
return -EIO;
#endif /* ECHOCARD_HAS_VMIXER */
#ifdef ECHOCARD_HAS_MONITOR
for (o = 0; o < num_busses_out(chip); o++)
for (i = 0; i < num_busses_in(chip); i++) {
err = set_monitor_gain(chip, o, i,
chip->monitor_gain[o][i]);
if (err < 0)
return err;
}
#endif /* ECHOCARD_HAS_MONITOR */
#ifdef ECHOCARD_HAS_INPUT_GAIN
for (i = 0; i < num_busses_in(chip); i++) {
err = set_input_gain(chip, i, chip->input_gain[i]);
if (err < 0)
return err;
}
#endif /* ECHOCARD_HAS_INPUT_GAIN */
err = update_output_line_level(chip);
if (err < 0)
return err;
if (chip->meters_enabled)
if (send_vector(chip, DSP_VC_METERS_ON) < 0)
return -EIO;
err = update_input_line_level(chip);
if (err < 0)
return err;
err = set_sample_rate(chip, chip->sample_rate);
if (err < 0)
return err;
if (chip->meters_enabled) {
err = send_vector(chip, DSP_VC_METERS_ON);
if (err < 0)
return err;
}
#ifdef ECHOCARD_HAS_DIGITAL_MODE_SWITCH
if (set_digital_mode(chip, chip->digital_mode) < 0)
return -EIO;
#endif
#ifdef ECHOCARD_HAS_DIGITAL_IO
if (set_professional_spdif(chip, chip->professional_spdif) < 0)
return -EIO;
#endif
#ifdef ECHOCARD_HAS_PHANTOM_POWER
if (set_phantom_power(chip, chip->phantom_power) < 0)
return -EIO;
#endif
#ifdef ECHOCARD_HAS_EXTERNAL_CLOCK
/* set_input_clock() also restores automute setting */
if (set_input_clock(chip, chip->input_clock) < 0)
return -EIO;
#endif
@ -685,23 +748,14 @@ static int restore_dsp_rettings(struct echoaudio *chip)
return -EIO;
#endif
if (update_output_line_level(chip) < 0)
return -EIO;
if (update_input_line_level(chip) < 0)
return -EIO;
#ifdef ECHOCARD_HAS_VMIXER
if (update_vmixer_level(chip) < 0)
return -EIO;
#endif
if (wait_handshake(chip) < 0)
return -EIO;
clear_handshake(chip);
if (send_vector(chip, DSP_VC_UPDATE_FLAGS) < 0)
return -EIO;
DE_INIT(("restore_dsp_rettings done\n"));
return send_vector(chip, DSP_VC_UPDATE_FLAGS);
return 0;
}
@ -918,9 +972,6 @@ static int init_dsp_comm_page(struct echoaudio *chip)
chip->card_name = ECHOCARD_NAME;
chip->bad_board = TRUE; /* Set TRUE until DSP loaded */
chip->dsp_code = NULL; /* Current DSP code not loaded */
chip->digital_mode = DIGITAL_MODE_NONE;
chip->input_clock = ECHO_CLOCK_INTERNAL;
chip->output_clock = ECHO_CLOCK_WORD;
chip->asic_loaded = FALSE;
memset(chip->comm_page, 0, sizeof(struct comm_page));
@ -931,7 +982,6 @@ static int init_dsp_comm_page(struct echoaudio *chip)
chip->comm_page->midi_out_free_count =
cpu_to_le32(DSP_MIDI_OUT_FIFO_SIZE);
chip->comm_page->sample_rate = cpu_to_le32(44100);
chip->sample_rate = 44100;
/* Set line levels so we don't blast any inputs on startup */
memset(chip->comm_page->monitors, ECHOGAIN_MUTED, MONITOR_ARRAY_SIZE);
@ -942,50 +992,21 @@ static int init_dsp_comm_page(struct echoaudio *chip)
/* This function initializes the several volume controls for busses and pipes.
This MUST be called after the DSP is up and running ! */
/* This function initializes the chip structure with default values, ie. all
* muted and internal clock source. Then it copies the settings to the DSP.
* This MUST be called after the DSP is up and running !
*/
static int init_line_levels(struct echoaudio *chip)
{
int st, i, o;
DE_INIT(("init_line_levels\n"));
/* Mute output busses */
for (i = 0; i < num_busses_out(chip); i++)
if ((st = set_output_gain(chip, i, ECHOGAIN_MUTED)))
return st;
if ((st = update_output_line_level(chip)))
return st;
#ifdef ECHOCARD_HAS_VMIXER
/* Mute the Vmixer */
for (i = 0; i < num_pipes_out(chip); i++)
for (o = 0; o < num_busses_out(chip); o++)
if ((st = set_vmixer_gain(chip, o, i, ECHOGAIN_MUTED)))
return st;
if ((st = update_vmixer_level(chip)))
return st;
#endif /* ECHOCARD_HAS_VMIXER */
#ifdef ECHOCARD_HAS_MONITOR
/* Mute the monitor mixer */
for (o = 0; o < num_busses_out(chip); o++)
for (i = 0; i < num_busses_in(chip); i++)
if ((st = set_monitor_gain(chip, o, i, ECHOGAIN_MUTED)))
return st;
if ((st = update_output_line_level(chip)))
return st;
#endif /* ECHOCARD_HAS_MONITOR */
#ifdef ECHOCARD_HAS_INPUT_GAIN
for (i = 0; i < num_busses_in(chip); i++)
if ((st = set_input_gain(chip, i, ECHOGAIN_MUTED)))
return st;
if ((st = update_input_line_level(chip)))
return st;
#endif /* ECHOCARD_HAS_INPUT_GAIN */
return 0;
memset(chip->output_gain, ECHOGAIN_MUTED, sizeof(chip->output_gain));
memset(chip->input_gain, ECHOGAIN_MUTED, sizeof(chip->input_gain));
memset(chip->monitor_gain, ECHOGAIN_MUTED, sizeof(chip->monitor_gain));
memset(chip->vmixer_gain, ECHOGAIN_MUTED, sizeof(chip->vmixer_gain));
chip->input_clock = ECHO_CLOCK_INTERNAL;
chip->output_clock = ECHO_CLOCK_WORD;
chip->sample_rate = 44100;
return restore_dsp_rettings(chip);
}

View file

@ -67,7 +67,7 @@ static const struct firmware card_fw[] = {
{0, "gina20_dsp.fw"}
};
static struct pci_device_id snd_echo_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
{0x1057, 0x1801, 0xECC0, 0x0020, 0, 0, 0}, /* DSP 56301 Gina20 rev.0 */
{0,}
};

View file

@ -49,7 +49,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->device_id = device_id;
chip->subdevice_id = subdevice_id;
chip->bad_board = TRUE;
chip->dsp_code_to_load = &card_fw[FW_GINA20_DSP];
chip->dsp_code_to_load = FW_GINA20_DSP;
chip->spdif_status = GD_SPDIF_STATUS_UNDEF;
chip->clock_state = GD_CLOCK_UNDEF;
/* Since this card has no ASIC, mark it as loaded so everything
@ -62,17 +62,20 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
return err;
chip->bad_board = FALSE;
if ((err = init_line_levels(chip)) < 0)
return err;
err = set_professional_spdif(chip, TRUE);
DE_INIT(("init_hw done\n"));
return err;
}
static int set_mixer_defaults(struct echoaudio *chip)
{
chip->professional_spdif = FALSE;
return init_line_levels(chip);
}
static u32 detect_input_clocks(const struct echoaudio *chip)
{
u32 clocks_from_dsp, clock_bits;

View file

@ -85,7 +85,7 @@ static const struct firmware card_fw[] = {
{0, "gina24_361_asic.fw"}
};
static struct pci_device_id snd_echo_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
{0x1057, 0x1801, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56301 Gina24 rev.0 */
{0x1057, 0x1801, 0xECC0, 0x0051, 0, 0, 0}, /* DSP 56301 Gina24 rev.1 */
{0x1057, 0x3410, 0xECC0, 0x0050, 0, 0, 0}, /* DSP 56361 Gina24 rev.0 */

View file

@ -33,8 +33,7 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force);
static int set_input_clock(struct echoaudio *chip, u16 clock);
static int set_professional_spdif(struct echoaudio *chip, char prof);
static int set_digital_mode(struct echoaudio *chip, u8 mode);
static int load_asic_generic(struct echoaudio *chip, u32 cmd,
const struct firmware *asic);
static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
static int check_asic_status(struct echoaudio *chip);
@ -58,19 +57,16 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
ECHO_CLOCK_BIT_ESYNC | ECHO_CLOCK_BIT_ESYNC96 |
ECHO_CLOCK_BIT_ADAT;
chip->professional_spdif = FALSE;
chip->digital_in_automute = TRUE;
chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
/* Gina24 comes in both '301 and '361 flavors */
if (chip->device_id == DEVICE_ID_56361) {
chip->dsp_code_to_load = &card_fw[FW_GINA24_361_DSP];
chip->dsp_code_to_load = FW_GINA24_361_DSP;
chip->digital_modes =
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
} else {
chip->dsp_code_to_load = &card_fw[FW_GINA24_301_DSP];
chip->dsp_code_to_load = FW_GINA24_301_DSP;
chip->digital_modes =
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
@ -82,19 +78,22 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
return err;
chip->bad_board = FALSE;
if ((err = init_line_levels(chip)) < 0)
return err;
err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
if (err < 0)
return err;
err = set_professional_spdif(chip, TRUE);
DE_INIT(("init_hw done\n"));
return err;
}
static int set_mixer_defaults(struct echoaudio *chip)
{
chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
chip->professional_spdif = FALSE;
chip->digital_in_automute = TRUE;
return init_line_levels(chip);
}
static u32 detect_input_clocks(const struct echoaudio *chip)
{
u32 clocks_from_dsp, clock_bits;
@ -125,7 +124,7 @@ static int load_asic(struct echoaudio *chip)
{
u32 control_reg;
int err;
const struct firmware *fw;
short asic;
if (chip->asic_loaded)
return 1;
@ -135,14 +134,15 @@ static int load_asic(struct echoaudio *chip)
/* Pick the correct ASIC for '301 or '361 Gina24 */
if (chip->device_id == DEVICE_ID_56361)
fw = &card_fw[FW_GINA24_361_ASIC];
asic = FW_GINA24_361_ASIC;
else
fw = &card_fw[FW_GINA24_301_ASIC];
asic = FW_GINA24_301_ASIC;
if ((err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, fw)) < 0)
err = load_asic_generic(chip, DSP_FNC_LOAD_GINA24_ASIC, asic);
if (err < 0)
return err;
chip->asic_code = fw;
chip->asic_code = asic;
/* Now give the new ASIC a little time to set up */
mdelay(10);

View file

@ -68,7 +68,7 @@ static const struct firmware card_fw[] = {
{0, "indigo_dsp.fw"}
};
static struct pci_device_id snd_echo_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
{0x1057, 0x3410, 0xECC0, 0x0090, 0, 0, 0}, /* Indigo */
{0,}
};

View file

@ -50,7 +50,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->device_id = device_id;
chip->subdevice_id = subdevice_id;
chip->bad_board = TRUE;
chip->dsp_code_to_load = &card_fw[FW_INDIGO_DSP];
chip->dsp_code_to_load = FW_INDIGO_DSP;
/* Since this card has no ASIC, mark it as loaded so everything
works OK */
chip->asic_loaded = TRUE;
@ -60,15 +60,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
return err;
chip->bad_board = FALSE;
if ((err = init_line_levels(chip)) < 0)
return err;
DE_INIT(("init_hw done\n"));
return err;
}
static int set_mixer_defaults(struct echoaudio *chip)
{
return init_line_levels(chip);
}
static u32 detect_input_clocks(const struct echoaudio *chip)
{
return ECHO_CLOCK_BIT_INTERNAL;

View file

@ -61,6 +61,7 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
control_reg |= clock;
if (control_reg != old_control_reg) {
DE_ACT(("set_sample_rate: %d clock %d\n", rate, clock));
chip->comm_page->control_register = cpu_to_le32(control_reg);
chip->sample_rate = rate;
clear_handshake(chip);

View file

@ -68,7 +68,7 @@ static const struct firmware card_fw[] = {
{0, "indigo_dj_dsp.fw"}
};
static struct pci_device_id snd_echo_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
{0x1057, 0x3410, 0xECC0, 0x00B0, 0, 0, 0}, /* Indigo DJ*/
{0,}
};

View file

@ -50,7 +50,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->device_id = device_id;
chip->subdevice_id = subdevice_id;
chip->bad_board = TRUE;
chip->dsp_code_to_load = &card_fw[FW_INDIGO_DJ_DSP];
chip->dsp_code_to_load = FW_INDIGO_DJ_DSP;
/* Since this card has no ASIC, mark it as loaded so everything
works OK */
chip->asic_loaded = TRUE;
@ -60,15 +60,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
return err;
chip->bad_board = FALSE;
if ((err = init_line_levels(chip)) < 0)
return err;
DE_INIT(("init_hw done\n"));
return err;
}
static int set_mixer_defaults(struct echoaudio *chip)
{
return init_line_levels(chip);
}
static u32 detect_input_clocks(const struct echoaudio *chip)
{
return ECHO_CLOCK_BIT_INTERNAL;

View file

@ -68,7 +68,7 @@ static const struct firmware card_fw[] = {
{0, "indigo_djx_dsp.fw"}
};
static struct pci_device_id snd_echo_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
{0x1057, 0x3410, 0xECC0, 0x00E0, 0, 0, 0}, /* Indigo DJx*/
{0,}
};

View file

@ -48,7 +48,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->device_id = device_id;
chip->subdevice_id = subdevice_id;
chip->bad_board = TRUE;
chip->dsp_code_to_load = &card_fw[FW_INDIGO_DJX_DSP];
chip->dsp_code_to_load = FW_INDIGO_DJX_DSP;
/* Since this card has no ASIC, mark it as loaded so everything
works OK */
chip->asic_loaded = TRUE;
@ -59,10 +59,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
return err;
chip->bad_board = FALSE;
err = init_line_levels(chip);
if (err < 0)
return err;
DE_INIT(("init_hw done\n"));
return err;
}
static int set_mixer_defaults(struct echoaudio *chip)
{
return init_line_levels(chip);
}

View file

@ -69,7 +69,7 @@ static const struct firmware card_fw[] = {
{0, "indigo_io_dsp.fw"}
};
static struct pci_device_id snd_echo_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
{0x1057, 0x3410, 0xECC0, 0x00A0, 0, 0, 0}, /* Indigo IO*/
{0,}
};

View file

@ -50,7 +50,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->device_id = device_id;
chip->subdevice_id = subdevice_id;
chip->bad_board = TRUE;
chip->dsp_code_to_load = &card_fw[FW_INDIGO_IO_DSP];
chip->dsp_code_to_load = FW_INDIGO_IO_DSP;
/* Since this card has no ASIC, mark it as loaded so everything
works OK */
chip->asic_loaded = TRUE;
@ -60,15 +60,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
return err;
chip->bad_board = FALSE;
if ((err = init_line_levels(chip)) < 0)
return err;
DE_INIT(("init_hw done\n"));
return err;
}
static int set_mixer_defaults(struct echoaudio *chip)
{
return init_line_levels(chip);
}
static u32 detect_input_clocks(const struct echoaudio *chip)
{
return ECHO_CLOCK_BIT_INTERNAL;

View file

@ -69,7 +69,7 @@ static const struct firmware card_fw[] = {
{0, "indigo_iox_dsp.fw"}
};
static struct pci_device_id snd_echo_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
{0x1057, 0x3410, 0xECC0, 0x00D0, 0, 0, 0}, /* Indigo IOx */
{0,}
};

View file

@ -48,7 +48,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->device_id = device_id;
chip->subdevice_id = subdevice_id;
chip->bad_board = TRUE;
chip->dsp_code_to_load = &card_fw[FW_INDIGO_IOX_DSP];
chip->dsp_code_to_load = FW_INDIGO_IOX_DSP;
/* Since this card has no ASIC, mark it as loaded so everything
works OK */
chip->asic_loaded = TRUE;
@ -59,10 +59,13 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
return err;
chip->bad_board = FALSE;
err = init_line_levels(chip);
if (err < 0)
return err;
DE_INIT(("init_hw done\n"));
return err;
}
static int set_mixer_defaults(struct echoaudio *chip)
{
return init_line_levels(chip);
}

View file

@ -76,7 +76,7 @@ static const struct firmware card_fw[] = {
{0, "layla20_asic.fw"}
};
static struct pci_device_id snd_echo_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
{0x1057, 0x1801, 0xECC0, 0x0030, 0, 0, 0}, /* DSP 56301 Layla20 rev.0 */
{0x1057, 0x1801, 0xECC0, 0x0031, 0, 0, 0}, /* DSP 56301 Layla20 rev.1 */
{0,}

View file

@ -31,8 +31,7 @@
static int read_dsp(struct echoaudio *chip, u32 *data);
static int set_professional_spdif(struct echoaudio *chip, char prof);
static int load_asic_generic(struct echoaudio *chip, u32 cmd,
const struct firmware *asic);
static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
static int check_asic_status(struct echoaudio *chip);
static int update_flags(struct echoaudio *chip);
@ -54,7 +53,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->subdevice_id = subdevice_id;
chip->bad_board = TRUE;
chip->has_midi = TRUE;
chip->dsp_code_to_load = &card_fw[FW_LAYLA20_DSP];
chip->dsp_code_to_load = FW_LAYLA20_DSP;
chip->input_clock_types =
ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_SUPER;
@ -65,17 +64,20 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
return err;
chip->bad_board = FALSE;
if ((err = init_line_levels(chip)) < 0)
return err;
err = set_professional_spdif(chip, TRUE);
DE_INIT(("init_hw done\n"));
return err;
}
static int set_mixer_defaults(struct echoaudio *chip)
{
chip->professional_spdif = FALSE;
return init_line_levels(chip);
}
static u32 detect_input_clocks(const struct echoaudio *chip)
{
u32 clocks_from_dsp, clock_bits;
@ -144,7 +146,7 @@ static int load_asic(struct echoaudio *chip)
return 0;
err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA_ASIC,
&card_fw[FW_LAYLA20_ASIC]);
FW_LAYLA20_ASIC);
if (err < 0)
return err;

View file

@ -87,7 +87,7 @@ static const struct firmware card_fw[] = {
{0, "layla24_2S_asic.fw"}
};
static struct pci_device_id snd_echo_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
{0x1057, 0x3410, 0xECC0, 0x0060, 0, 0, 0}, /* DSP 56361 Layla24 rev.0 */
{0,}
};

View file

@ -32,8 +32,7 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force);
static int set_input_clock(struct echoaudio *chip, u16 clock);
static int set_professional_spdif(struct echoaudio *chip, char prof);
static int set_digital_mode(struct echoaudio *chip, u8 mode);
static int load_asic_generic(struct echoaudio *chip, u32 cmd,
const struct firmware *asic);
static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
static int check_asic_status(struct echoaudio *chip);
@ -54,7 +53,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->subdevice_id = subdevice_id;
chip->bad_board = TRUE;
chip->has_midi = TRUE;
chip->dsp_code_to_load = &card_fw[FW_LAYLA24_DSP];
chip->dsp_code_to_load = FW_LAYLA24_DSP;
chip->input_clock_types =
ECHO_CLOCK_BIT_INTERNAL | ECHO_CLOCK_BIT_SPDIF |
ECHO_CLOCK_BIT_WORD | ECHO_CLOCK_BIT_ADAT;
@ -62,9 +61,6 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_RCA |
ECHOCAPS_HAS_DIGITAL_MODE_SPDIF_OPTICAL |
ECHOCAPS_HAS_DIGITAL_MODE_ADAT;
chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
chip->professional_spdif = FALSE;
chip->digital_in_automute = TRUE;
if ((err = load_firmware(chip)) < 0)
return err;
@ -73,17 +69,22 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
if ((err = init_line_levels(chip)) < 0)
return err;
err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
if (err < 0)
return err;
err = set_professional_spdif(chip, TRUE);
DE_INIT(("init_hw done\n"));
return err;
}
static int set_mixer_defaults(struct echoaudio *chip)
{
chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
chip->professional_spdif = FALSE;
chip->digital_in_automute = TRUE;
return init_line_levels(chip);
}
static u32 detect_input_clocks(const struct echoaudio *chip)
{
u32 clocks_from_dsp, clock_bits;
@ -123,18 +124,18 @@ static int load_asic(struct echoaudio *chip)
/* Load the ASIC for the PCI card */
err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_PCI_CARD_ASIC,
&card_fw[FW_LAYLA24_1_ASIC]);
FW_LAYLA24_1_ASIC);
if (err < 0)
return err;
chip->asic_code = &card_fw[FW_LAYLA24_2S_ASIC];
chip->asic_code = FW_LAYLA24_2S_ASIC;
/* Now give the new ASIC a little time to set up */
mdelay(10);
/* Do the external one */
err = load_asic_generic(chip, DSP_FNC_LOAD_LAYLA24_EXTERNAL_ASIC,
&card_fw[FW_LAYLA24_2S_ASIC]);
FW_LAYLA24_2S_ASIC);
if (err < 0)
return FALSE;
@ -299,7 +300,7 @@ static int set_input_clock(struct echoaudio *chip, u16 clock)
/* Depending on what digital mode you want, Layla24 needs different ASICs
loaded. This function checks the ASIC needed for the new mode and sees
if it matches the one already loaded. */
static int switch_asic(struct echoaudio *chip, const struct firmware *asic)
static int switch_asic(struct echoaudio *chip, short asic)
{
s8 *monitors;
@ -335,7 +336,7 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
{
u32 control_reg;
int err, incompatible_clock;
const struct firmware *asic;
short asic;
/* Set clock to "internal" if it's not compatible with the new mode */
incompatible_clock = FALSE;
@ -344,12 +345,12 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
case DIGITAL_MODE_SPDIF_RCA:
if (chip->input_clock == ECHO_CLOCK_ADAT)
incompatible_clock = TRUE;
asic = &card_fw[FW_LAYLA24_2S_ASIC];
asic = FW_LAYLA24_2S_ASIC;
break;
case DIGITAL_MODE_ADAT:
if (chip->input_clock == ECHO_CLOCK_SPDIF)
incompatible_clock = TRUE;
asic = &card_fw[FW_LAYLA24_2A_ASIC];
asic = FW_LAYLA24_2A_ASIC;
break;
default:
DE_ACT(("Digital mode not supported: %d\n", mode));

View file

@ -77,7 +77,7 @@ static const struct firmware card_fw[] = {
{0, "mia_dsp.fw"}
};
static struct pci_device_id snd_echo_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
{0x1057, 0x3410, 0xECC0, 0x0080, 0, 0, 0}, /* DSP 56361 Mia rev.0 */
{0x1057, 0x3410, 0xECC0, 0x0081, 0, 0, 0}, /* DSP 56361 Mia rev.1 */
{0,}

View file

@ -53,7 +53,7 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
chip->device_id = device_id;
chip->subdevice_id = subdevice_id;
chip->bad_board = TRUE;
chip->dsp_code_to_load = &card_fw[FW_MIA_DSP];
chip->dsp_code_to_load = FW_MIA_DSP;
/* Since this card has no ASIC, mark it as loaded so everything
works OK */
chip->asic_loaded = TRUE;
@ -66,15 +66,19 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
return err;
chip->bad_board = FALSE;
if ((err = init_line_levels(chip)))
return err;
DE_INIT(("init_hw done\n"));
return err;
}
static int set_mixer_defaults(struct echoaudio *chip)
{
return init_line_levels(chip);
}
static u32 detect_input_clocks(const struct echoaudio *chip)
{
u32 clocks_from_dsp, clock_bits;

View file

@ -92,7 +92,7 @@ static const struct firmware card_fw[] = {
{0, "mona_2_asic.fw"}
};
static struct pci_device_id snd_echo_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_echo_ids) = {
{0x1057, 0x1801, 0xECC0, 0x0070, 0, 0, 0}, /* DSP 56301 Mona rev.0 */
{0x1057, 0x1801, 0xECC0, 0x0071, 0, 0, 0}, /* DSP 56301 Mona rev.1 */
{0x1057, 0x1801, 0xECC0, 0x0072, 0, 0, 0}, /* DSP 56301 Mona rev.2 */

View file

@ -33,8 +33,7 @@ static int write_control_reg(struct echoaudio *chip, u32 value, char force);
static int set_input_clock(struct echoaudio *chip, u16 clock);
static int set_professional_spdif(struct echoaudio *chip, char prof);
static int set_digital_mode(struct echoaudio *chip, u8 mode);
static int load_asic_generic(struct echoaudio *chip, u32 cmd,
const struct firmware *asic);
static int load_asic_generic(struct echoaudio *chip, u32 cmd, short asic);
static int check_asic_status(struct echoaudio *chip);
@ -64,32 +63,30 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id)
/* Mona comes in both '301 and '361 flavors */
if (chip->device_id == DEVICE_ID_56361)
chip->dsp_code_to_load = &card_fw[FW_MONA_361_DSP];
chip->dsp_code_to_load = FW_MONA_361_DSP;
else
chip->dsp_code_to_load = &card_fw[FW_MONA_301_DSP];
chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
chip->professional_spdif = FALSE;
chip->digital_in_automute = TRUE;
chip->dsp_code_to_load = FW_MONA_301_DSP;
if ((err = load_firmware(chip)) < 0)
return err;
chip->bad_board = FALSE;
if ((err = init_line_levels(chip)) < 0)
return err;
err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA);
if (err < 0)
return err;
err = set_professional_spdif(chip, TRUE);
DE_INIT(("init_hw done\n"));
return err;
}
static int set_mixer_defaults(struct echoaudio *chip)
{
chip->digital_mode = DIGITAL_MODE_SPDIF_RCA;
chip->professional_spdif = FALSE;
chip->digital_in_automute = TRUE;
return init_line_levels(chip);
}
static u32 detect_input_clocks(const struct echoaudio *chip)
{
u32 clocks_from_dsp, clock_bits;
@ -120,7 +117,7 @@ static int load_asic(struct echoaudio *chip)
{
u32 control_reg;
int err;
const struct firmware *asic;
short asic;
if (chip->asic_loaded)
return 0;
@ -128,9 +125,9 @@ static int load_asic(struct echoaudio *chip)
mdelay(10);
if (chip->device_id == DEVICE_ID_56361)
asic = &card_fw[FW_MONA_361_1_ASIC48];
asic = FW_MONA_361_1_ASIC48;
else
asic = &card_fw[FW_MONA_301_1_ASIC48];
asic = FW_MONA_301_1_ASIC48;
err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_PCI_CARD_ASIC, asic);
if (err < 0)
@ -141,7 +138,7 @@ static int load_asic(struct echoaudio *chip)
/* Do the external one */
err = load_asic_generic(chip, DSP_FNC_LOAD_MONA_EXTERNAL_ASIC,
&card_fw[FW_MONA_2_ASIC]);
FW_MONA_2_ASIC);
if (err < 0)
return err;
@ -165,22 +162,22 @@ loaded. This function checks the ASIC needed for the new mode and sees
if it matches the one already loaded. */
static int switch_asic(struct echoaudio *chip, char double_speed)
{
const struct firmware *asic;
int err;
short asic;
/* Check the clock detect bits to see if this is
a single-speed clock or a double-speed clock; load
a new ASIC if necessary. */
if (chip->device_id == DEVICE_ID_56361) {
if (double_speed)
asic = &card_fw[FW_MONA_361_1_ASIC96];
asic = FW_MONA_361_1_ASIC96;
else
asic = &card_fw[FW_MONA_361_1_ASIC48];
asic = FW_MONA_361_1_ASIC48;
} else {
if (double_speed)
asic = &card_fw[FW_MONA_301_1_ASIC96];
asic = FW_MONA_301_1_ASIC96;
else
asic = &card_fw[FW_MONA_301_1_ASIC48];
asic = FW_MONA_301_1_ASIC48;
}
if (asic != chip->asic_code) {
@ -200,7 +197,7 @@ static int switch_asic(struct echoaudio *chip, char double_speed)
static int set_sample_rate(struct echoaudio *chip, u32 rate)
{
u32 control_reg, clock;
const struct firmware *asic;
short asic;
char force_write;
/* Only set the clock for internal mode. */
@ -218,14 +215,14 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate)
if (chip->digital_mode == DIGITAL_MODE_ADAT)
return -EINVAL;
if (chip->device_id == DEVICE_ID_56361)
asic = &card_fw[FW_MONA_361_1_ASIC96];
asic = FW_MONA_361_1_ASIC96;
else
asic = &card_fw[FW_MONA_301_1_ASIC96];
asic = FW_MONA_301_1_ASIC96;
} else {
if (chip->device_id == DEVICE_ID_56361)
asic = &card_fw[FW_MONA_361_1_ASIC48];
asic = FW_MONA_361_1_ASIC48;
else
asic = &card_fw[FW_MONA_301_1_ASIC48];
asic = FW_MONA_301_1_ASIC48;
}
force_write = 0;
@ -410,8 +407,8 @@ static int dsp_set_digital_mode(struct echoaudio *chip, u8 mode)
case DIGITAL_MODE_ADAT:
/* If the current ASIC is the 96KHz ASIC, switch the ASIC
and set to 48 KHz */
if (chip->asic_code == &card_fw[FW_MONA_361_1_ASIC96] ||
chip->asic_code == &card_fw[FW_MONA_301_1_ASIC96]) {
if (chip->asic_code == FW_MONA_361_1_ASIC96 ||
chip->asic_code == FW_MONA_301_1_ASIC96) {
set_sample_rate(chip, 48000);
}
control_reg |= GML_ADAT_MODE;

View file

@ -76,7 +76,7 @@ MODULE_PARM_DESC(subsystem, "Force card subsystem model.");
/*
* Class 0401: 1102:0008 (rev 00) Subsystem: 1102:1001 -> Audigy2 Value Model:SB0400
*/
static struct pci_device_id snd_emu10k1_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_emu10k1_ids) = {
{ PCI_VDEVICE(CREATIVE, 0x0002), 0 }, /* EMU10K1 */
{ PCI_VDEVICE(CREATIVE, 0x0004), 1 }, /* Audigy */
{ PCI_VDEVICE(CREATIVE, 0x0008), 1 }, /* Audigy 2 Value SB0400 */

View file

@ -1605,7 +1605,7 @@ static void __devexit snd_emu10k1x_remove(struct pci_dev *pci)
}
// PCI IDs
static struct pci_device_id snd_emu10k1x_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_emu10k1x_ids) = {
{ PCI_VDEVICE(CREATIVE, 0x0006), 0 }, /* Dell OEM version (EMU10K1) */
{ 0, }
};

View file

@ -443,7 +443,7 @@ struct ensoniq {
static irqreturn_t snd_audiopci_interrupt(int irq, void *dev_id);
static struct pci_device_id snd_audiopci_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_audiopci_ids) = {
#ifdef CHIP1370
{ PCI_VDEVICE(ENSONIQ, 0x5000), 0, }, /* ES1370 */
#endif

View file

@ -243,7 +243,7 @@ struct es1938 {
static irqreturn_t snd_es1938_interrupt(int irq, void *dev_id);
static struct pci_device_id snd_es1938_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_es1938_ids) = {
{ PCI_VDEVICE(ESS, 0x1969), 0, }, /* Solo-1 */
{ 0, }
};

View file

@ -551,7 +551,7 @@ struct es1968 {
static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id);
static struct pci_device_id snd_es1968_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_es1968_ids) = {
/* Maestro 1 */
{ 0x1285, 0x0100, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, TYPE_MAESTRO },
/* Maestro 2 */

View file

@ -205,7 +205,7 @@ struct fm801 {
#endif
};
static struct pci_device_id snd_fm801_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_fm801_ids) = {
{ 0x1319, 0x0801, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* FM801 */
{ 0x5213, 0x0510, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0, }, /* Gallant Odyssey Sound 4 */
{ 0, }

View file

@ -2664,7 +2664,7 @@ static void __devexit azx_remove(struct pci_dev *pci)
}
/* PCI IDs */
static struct pci_device_id azx_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(azx_ids) = {
/* ICH 6..10 */
{ PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH },
{ PCI_DEVICE(0x8086, 0x27d8), .driver_data = AZX_DRIVER_ICH },

View file

@ -106,7 +106,7 @@ module_param_array(dxr_enable, int, NULL, 0444);
MODULE_PARM_DESC(dxr_enable, "Enable DXR support for Terratec DMX6FIRE.");
static const struct pci_device_id snd_ice1712_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_ice1712_ids) = {
{ PCI_VDEVICE(ICE, PCI_DEVICE_ID_ICE_1712), 0 }, /* ICE1712 */
{ 0, }
};
@ -1180,6 +1180,10 @@ static int snd_ice1712_playback_pro_open(struct snd_pcm_substream *substream)
snd_pcm_set_sync(substream);
snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
if (is_pro_rate_locked(ice)) {
runtime->hw.rate_min = PRO_RATE_DEFAULT;
runtime->hw.rate_max = PRO_RATE_DEFAULT;
}
if (ice->spdif.ops.open)
ice->spdif.ops.open(ice, substream);
@ -1197,6 +1201,11 @@ static int snd_ice1712_capture_pro_open(struct snd_pcm_substream *substream)
snd_pcm_set_sync(substream);
snd_pcm_hw_constraint_msbits(runtime, 0, 32, 24);
snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, &hw_constraints_rates);
if (is_pro_rate_locked(ice)) {
runtime->hw.rate_min = PRO_RATE_DEFAULT;
runtime->hw.rate_max = PRO_RATE_DEFAULT;
}
return 0;
}

View file

@ -94,7 +94,7 @@ MODULE_PARM_DESC(model, "Use the given board model.");
/* Both VT1720 and VT1724 have the same PCI IDs */
static const struct pci_device_id snd_vt1724_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_vt1724_ids) = {
{ PCI_VDEVICE(ICE, PCI_DEVICE_ID_VT1724), 0 },
{ 0, }
};

View file

@ -420,7 +420,7 @@ struct intel8x0 {
u32 int_sta_mask; /* interrupt status mask */
};
static struct pci_device_id snd_intel8x0_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0_ids) = {
{ PCI_VDEVICE(INTEL, 0x2415), DEVICE_INTEL }, /* 82801AA */
{ PCI_VDEVICE(INTEL, 0x2425), DEVICE_INTEL }, /* 82901AB */
{ PCI_VDEVICE(INTEL, 0x2445), DEVICE_INTEL }, /* 82801BA */

View file

@ -219,7 +219,7 @@ struct intel8x0m {
unsigned int pcm_pos_shift;
};
static struct pci_device_id snd_intel8x0m_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0m_ids) = {
{ PCI_VDEVICE(INTEL, 0x2416), DEVICE_INTEL }, /* 82801AA */
{ PCI_VDEVICE(INTEL, 0x2426), DEVICE_INTEL }, /* 82901AB */
{ PCI_VDEVICE(INTEL, 0x2446), DEVICE_INTEL }, /* 82801BA */

View file

@ -418,7 +418,7 @@ module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable Korg 1212 soundcard.");
MODULE_AUTHOR("Haroldo Gamal <gamal@alternex.com.br>");
static struct pci_device_id snd_korg1212_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_korg1212_ids) = {
{
.vendor = 0x10b5,
.device = 0x906d,

View file

@ -55,7 +55,7 @@ static const char card_name[] = "LX6464ES";
#define PCI_DEVICE_ID_PLX_LX6464ES PCI_DEVICE_ID_PLX_9056
static struct pci_device_id snd_lx6464es_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_lx6464es_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_LX6464ES),
.subvendor = PCI_VENDOR_ID_DIGIGRAM,
.subdevice = PCI_SUBDEVICE_ID_DIGIGRAM_LX6464ES_SERIAL_SUBSYSTEM

View file

@ -861,7 +861,7 @@ struct snd_m3 {
/*
* pci ids
*/
static struct pci_device_id snd_m3_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_m3_ids) = {
{PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO_1, PCI_ANY_ID, PCI_ANY_ID,
PCI_CLASS_MULTIMEDIA_AUDIO << 8, 0xffff00, 0},
{PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ALLEGRO, PCI_ANY_ID, PCI_ANY_ID,

View file

@ -60,7 +60,7 @@ MODULE_PARM_DESC(enable, "Enable Digigram " CARD_NAME " soundcard.");
/*
*/
static struct pci_device_id snd_mixart_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_mixart_ids) = {
{ PCI_VDEVICE(MOTOROLA, 0x0003), 0, }, /* MC8240 */
{ 0, }
};

View file

@ -262,7 +262,7 @@ struct nm256 {
/*
* PCI ids
*/
static struct pci_device_id snd_nm256_ids[] = {
static DEFINE_PCI_DEVICE_TABLE(snd_nm256_ids) = {
{PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO), 0},
{PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO), 0},
{PCI_VDEVICE(NEOMAGIC, PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO), 0},

View file

@ -48,7 +48,7 @@ MODULE_PARM_DESC(id, "ID string");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "enable card");
static struct pci_device_id hifier_ids[] __devinitdata = {
static DEFINE_PCI_DEVICE_TABLE(hifier_ids) = {
{ OXYGEN_PCI_SUBID(0x14c3, 0x1710) },
{ OXYGEN_PCI_SUBID(0x14c3, 0x1711) },
{ OXYGEN_PCI_SUBID_BROKEN_EEPROM },

Some files were not shown because too many files have changed in this diff Show more