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:
commit
b8f1f5983f
124 changed files with 3446 additions and 1330 deletions
|
@ -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
|
||||
--------------------
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
|
@ -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)
|
||||
|
|
|
@ -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
404
sound/isa/sb/jazz16.c
Normal 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)
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 },
|
||||
{ }
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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, },
|
||||
};
|
||||
|
|
|
@ -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, }
|
||||
};
|
||||
|
|
|
@ -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, }
|
||||
|
|
|
@ -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, }
|
||||
};
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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, }
|
||||
|
|
|
@ -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,}
|
||||
};
|
||||
|
|
|
@ -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,}
|
||||
};
|
||||
|
|
|
@ -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,}
|
||||
};
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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, }
|
||||
|
|
|
@ -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),
|
||||
{ }
|
||||
|
|
|
@ -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, }
|
||||
};
|
||||
|
|
|
@ -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) },
|
||||
{ },
|
||||
};
|
||||
|
|
|
@ -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, }
|
||||
};
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,}
|
||||
|
|
|
@ -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) },
|
||||
{}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,}
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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,}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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,}
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,}
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,}
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,}
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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,}
|
||||
};
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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,}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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, }
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, }
|
||||
};
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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, }
|
||||
|
|
|
@ -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 },
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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, }
|
||||
};
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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, }
|
||||
};
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue