forked from Minki/linux
Merge branch 'topic/misc' into for-linus
This commit is contained in:
commit
7d339ae997
@ -1164,7 +1164,7 @@
|
||||
}
|
||||
chip->port = pci_resource_start(pci, 0);
|
||||
if (request_irq(pci->irq, snd_mychip_interrupt,
|
||||
IRQF_SHARED, "My Chip", chip)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, chip)) {
|
||||
printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
|
||||
snd_mychip_free(chip);
|
||||
return -EBUSY;
|
||||
@ -1197,7 +1197,7 @@
|
||||
|
||||
/* pci_driver definition */
|
||||
static struct pci_driver driver = {
|
||||
.name = "My Own Chip",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_mychip_ids,
|
||||
.probe = snd_mychip_probe,
|
||||
.remove = __devexit_p(snd_mychip_remove),
|
||||
@ -1340,7 +1340,7 @@
|
||||
<programlisting>
|
||||
<![CDATA[
|
||||
if (request_irq(pci->irq, snd_mychip_interrupt,
|
||||
IRQF_SHARED, "My Chip", chip)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, chip)) {
|
||||
printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
|
||||
snd_mychip_free(chip);
|
||||
return -EBUSY;
|
||||
@ -1616,7 +1616,7 @@
|
||||
<programlisting>
|
||||
<![CDATA[
|
||||
static struct pci_driver driver = {
|
||||
.name = "My Own Chip",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_mychip_ids,
|
||||
.probe = snd_mychip_probe,
|
||||
.remove = __devexit_p(snd_mychip_remove),
|
||||
@ -5816,7 +5816,7 @@ struct _snd_pcm_runtime {
|
||||
<programlisting>
|
||||
<![CDATA[
|
||||
static struct pci_driver driver = {
|
||||
.name = "My Chip",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_my_ids,
|
||||
.probe = snd_my_probe,
|
||||
.remove = __devexit_p(snd_my_remove),
|
||||
|
@ -1308,6 +1308,7 @@
|
||||
#define PCI_SUBDEVICE_ID_CREATIVE_SB08801 0x0041
|
||||
#define PCI_SUBDEVICE_ID_CREATIVE_SB08802 0x0042
|
||||
#define PCI_SUBDEVICE_ID_CREATIVE_SB08803 0x0043
|
||||
#define PCI_SUBDEVICE_ID_CREATIVE_SB1270 0x0062
|
||||
#define PCI_SUBDEVICE_ID_CREATIVE_HENDRIX 0x6000
|
||||
|
||||
#define PCI_VENDOR_ID_ECTIVA 0x1102 /* duplicate: CREATIVE */
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#if defined(CONFIG_SND_SEQUENCER) || defined(CONFIG_SND_SEQUENCER_MODULE)
|
||||
#include "seq_device.h"
|
||||
@ -63,6 +64,7 @@ struct snd_rawmidi_global_ops {
|
||||
};
|
||||
|
||||
struct snd_rawmidi_runtime {
|
||||
struct snd_rawmidi_substream *substream;
|
||||
unsigned int drain: 1, /* drain stage */
|
||||
oss: 1; /* OSS compatible mode */
|
||||
/* midi stream buffer */
|
||||
@ -79,7 +81,7 @@ struct snd_rawmidi_runtime {
|
||||
/* event handler (new bytes, input only) */
|
||||
void (*event)(struct snd_rawmidi_substream *substream);
|
||||
/* defers calls to event [input] or ops->trigger [output] */
|
||||
struct tasklet_struct tasklet;
|
||||
struct work_struct event_work;
|
||||
/* private data */
|
||||
void *private_data;
|
||||
void (*private_free)(struct snd_rawmidi_substream *substream);
|
||||
|
@ -92,16 +92,12 @@ static inline int snd_rawmidi_ready_append(struct snd_rawmidi_substream *substre
|
||||
(!substream->append || runtime->avail >= count);
|
||||
}
|
||||
|
||||
static void snd_rawmidi_input_event_tasklet(unsigned long data)
|
||||
static void snd_rawmidi_input_event_work(struct work_struct *work)
|
||||
{
|
||||
struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
|
||||
substream->runtime->event(substream);
|
||||
}
|
||||
|
||||
static void snd_rawmidi_output_trigger_tasklet(unsigned long data)
|
||||
{
|
||||
struct snd_rawmidi_substream *substream = (struct snd_rawmidi_substream *)data;
|
||||
substream->ops->trigger(substream, 1);
|
||||
struct snd_rawmidi_runtime *runtime =
|
||||
container_of(work, struct snd_rawmidi_runtime, event_work);
|
||||
if (runtime->event)
|
||||
runtime->event(runtime->substream);
|
||||
}
|
||||
|
||||
static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
|
||||
@ -110,16 +106,10 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
|
||||
|
||||
if ((runtime = kzalloc(sizeof(*runtime), GFP_KERNEL)) == NULL)
|
||||
return -ENOMEM;
|
||||
runtime->substream = substream;
|
||||
spin_lock_init(&runtime->lock);
|
||||
init_waitqueue_head(&runtime->sleep);
|
||||
if (substream->stream == SNDRV_RAWMIDI_STREAM_INPUT)
|
||||
tasklet_init(&runtime->tasklet,
|
||||
snd_rawmidi_input_event_tasklet,
|
||||
(unsigned long)substream);
|
||||
else
|
||||
tasklet_init(&runtime->tasklet,
|
||||
snd_rawmidi_output_trigger_tasklet,
|
||||
(unsigned long)substream);
|
||||
INIT_WORK(&runtime->event_work, snd_rawmidi_input_event_work);
|
||||
runtime->event = NULL;
|
||||
runtime->buffer_size = PAGE_SIZE;
|
||||
runtime->avail_min = 1;
|
||||
@ -150,12 +140,7 @@ static inline void snd_rawmidi_output_trigger(struct snd_rawmidi_substream *subs
|
||||
{
|
||||
if (!substream->opened)
|
||||
return;
|
||||
if (up) {
|
||||
tasklet_schedule(&substream->runtime->tasklet);
|
||||
} else {
|
||||
tasklet_kill(&substream->runtime->tasklet);
|
||||
substream->ops->trigger(substream, 0);
|
||||
}
|
||||
substream->ops->trigger(substream, up);
|
||||
}
|
||||
|
||||
static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, int up)
|
||||
@ -163,8 +148,8 @@ static void snd_rawmidi_input_trigger(struct snd_rawmidi_substream *substream, i
|
||||
if (!substream->opened)
|
||||
return;
|
||||
substream->ops->trigger(substream, up);
|
||||
if (!up && substream->runtime->event)
|
||||
tasklet_kill(&substream->runtime->tasklet);
|
||||
if (!up)
|
||||
cancel_work_sync(&substream->runtime->event_work);
|
||||
}
|
||||
|
||||
int snd_rawmidi_drop_output(struct snd_rawmidi_substream *substream)
|
||||
@ -641,10 +626,10 @@ int snd_rawmidi_output_params(struct snd_rawmidi_substream *substream,
|
||||
return -EINVAL;
|
||||
}
|
||||
if (params->buffer_size != runtime->buffer_size) {
|
||||
newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
|
||||
newbuf = krealloc(runtime->buffer, params->buffer_size,
|
||||
GFP_KERNEL);
|
||||
if (!newbuf)
|
||||
return -ENOMEM;
|
||||
kfree(runtime->buffer);
|
||||
runtime->buffer = newbuf;
|
||||
runtime->buffer_size = params->buffer_size;
|
||||
runtime->avail = runtime->buffer_size;
|
||||
@ -668,10 +653,10 @@ int snd_rawmidi_input_params(struct snd_rawmidi_substream *substream,
|
||||
return -EINVAL;
|
||||
}
|
||||
if (params->buffer_size != runtime->buffer_size) {
|
||||
newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
|
||||
newbuf = krealloc(runtime->buffer, params->buffer_size,
|
||||
GFP_KERNEL);
|
||||
if (!newbuf)
|
||||
return -ENOMEM;
|
||||
kfree(runtime->buffer);
|
||||
runtime->buffer = newbuf;
|
||||
runtime->buffer_size = params->buffer_size;
|
||||
}
|
||||
@ -926,7 +911,7 @@ int snd_rawmidi_receive(struct snd_rawmidi_substream *substream,
|
||||
}
|
||||
if (result > 0) {
|
||||
if (runtime->event)
|
||||
tasklet_schedule(&runtime->tasklet);
|
||||
schedule_work(&runtime->event_work);
|
||||
else if (snd_rawmidi_ready(substream))
|
||||
wake_up(&runtime->sleep);
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ static int fwspk_open(struct snd_pcm_substream *substream)
|
||||
|
||||
err = snd_pcm_hw_constraint_minmax(runtime,
|
||||
SNDRV_PCM_HW_PARAM_PERIOD_TIME,
|
||||
5000, 8192000);
|
||||
5000, UINT_MAX);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
|
@ -944,7 +944,7 @@ snd_ad1889_create(struct snd_card *card,
|
||||
spin_lock_init(&chip->lock); /* only now can we call ad1889_free */
|
||||
|
||||
if (request_irq(pci->irq, snd_ad1889_interrupt,
|
||||
IRQF_SHARED, card->driver, chip)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, chip)) {
|
||||
printk(KERN_ERR PFX "cannot obtain IRQ %d\n", pci->irq);
|
||||
snd_ad1889_free(chip);
|
||||
return -EBUSY;
|
||||
@ -1055,7 +1055,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_ad1889_ids) = {
|
||||
MODULE_DEVICE_TABLE(pci, snd_ad1889_ids);
|
||||
|
||||
static struct pci_driver ad1889_pci_driver = {
|
||||
.name = "AD1889 Audio",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_ad1889_ids,
|
||||
.probe = snd_ad1889_probe,
|
||||
.remove = __devexit_p(snd_ad1889_remove),
|
||||
|
@ -2090,7 +2090,7 @@ static int __devinit snd_ali_resources(struct snd_ali *codec)
|
||||
codec->port = pci_resource_start(codec->pci, 0);
|
||||
|
||||
if (request_irq(codec->pci->irq, snd_ali_card_interrupt,
|
||||
IRQF_SHARED, "ALI 5451", codec)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, codec)) {
|
||||
snd_printk(KERN_ERR "Unable to request irq.\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
@ -2295,7 +2295,7 @@ static void __devexit snd_ali_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "ALI 5451",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_ali_ids,
|
||||
.probe = snd_ali_probe,
|
||||
.remove = __devexit_p(snd_ali_remove),
|
||||
|
@ -722,7 +722,7 @@ static int __devinit snd_als300_create(struct snd_card *card,
|
||||
irq_handler = snd_als300_interrupt;
|
||||
|
||||
if (request_irq(pci->irq, irq_handler, IRQF_SHARED,
|
||||
card->shortname, chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_als300_free(chip);
|
||||
return -EBUSY;
|
||||
@ -846,7 +846,7 @@ static int __devinit snd_als300_probe(struct pci_dev *pci,
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "ALS300",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_als300_ids,
|
||||
.probe = snd_als300_probe,
|
||||
.remove = __devexit_p(snd_als300_remove),
|
||||
|
@ -1036,7 +1036,7 @@ static int snd_als4000_resume(struct pci_dev *pci)
|
||||
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "ALS4000",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_als4000_ids,
|
||||
.probe = snd_card_als4000_probe,
|
||||
.remove = __devexit_p(snd_card_als4000_remove),
|
||||
|
@ -49,19 +49,21 @@ MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
|
||||
#if defined CONFIG_SND_DEBUG
|
||||
/* copied from pcm_lib.c, hope later patch will make that version public
|
||||
and this copy can be removed */
|
||||
static void pcm_debug_name(struct snd_pcm_substream *substream,
|
||||
char *name, size_t len)
|
||||
static inline void
|
||||
snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size)
|
||||
{
|
||||
snprintf(name, len, "pcmC%dD%d%c:%d",
|
||||
snprintf(buf, size, "pcmC%dD%d%c:%d",
|
||||
substream->pcm->card->number,
|
||||
substream->pcm->device,
|
||||
substream->stream ? 'c' : 'p',
|
||||
substream->number);
|
||||
}
|
||||
#define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name))
|
||||
#else
|
||||
#define pcm_debug_name(s, n, l) do { } while (0)
|
||||
#define DEBUG_NAME(name, substream) do { } while (0)
|
||||
static inline void
|
||||
snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size)
|
||||
{
|
||||
*buf = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined CONFIG_SND_DEBUG_VERBOSE
|
||||
@ -304,7 +306,8 @@ static u16 handle_error(u16 err, int line, char *filename)
|
||||
static void print_hwparams(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *p)
|
||||
{
|
||||
DEBUG_NAME(substream, name);
|
||||
char name[16];
|
||||
snd_pcm_debug_name(substream, name, sizeof(name));
|
||||
snd_printd("%s HWPARAMS\n", name);
|
||||
snd_printd(" samplerate %d Hz\n", params_rate(p));
|
||||
snd_printd(" channels %d\n", params_channels(p));
|
||||
@ -576,8 +579,9 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream,
|
||||
struct snd_card_asihpi *card = snd_pcm_substream_chip(substream);
|
||||
struct snd_pcm_substream *s;
|
||||
u16 e;
|
||||
DEBUG_NAME(substream, name);
|
||||
char name[16];
|
||||
|
||||
snd_pcm_debug_name(substream, name, sizeof(name));
|
||||
snd_printdd("%s trigger\n", name);
|
||||
|
||||
switch (cmd) {
|
||||
@ -741,7 +745,9 @@ static void snd_card_asihpi_timer_function(unsigned long data)
|
||||
int loops = 0;
|
||||
u16 state;
|
||||
u32 buffer_size, bytes_avail, samples_played, on_card_bytes;
|
||||
DEBUG_NAME(substream, name);
|
||||
char name[16];
|
||||
|
||||
snd_pcm_debug_name(substream, name, sizeof(name));
|
||||
|
||||
snd_printdd("%s snd_card_asihpi_timer_function\n", name);
|
||||
|
||||
@ -1323,10 +1329,12 @@ static const char * const asihpi_src_names[] = {
|
||||
"RF",
|
||||
"Clock",
|
||||
"Bitstream",
|
||||
"Microphone",
|
||||
"Cobranet",
|
||||
"Mic",
|
||||
"Net",
|
||||
"Analog",
|
||||
"Adapter",
|
||||
"RTP",
|
||||
"GPI",
|
||||
};
|
||||
|
||||
compile_time_assert(
|
||||
@ -1341,8 +1349,10 @@ static const char * const asihpi_dst_names[] = {
|
||||
"Digital",
|
||||
"RF",
|
||||
"Speaker",
|
||||
"Cobranet Out",
|
||||
"Analog"
|
||||
"Net",
|
||||
"Analog",
|
||||
"RTP",
|
||||
"GPO",
|
||||
};
|
||||
|
||||
compile_time_assert(
|
||||
@ -1476,11 +1486,40 @@ static int snd_asihpi_volume_put(struct snd_kcontrol *kcontrol,
|
||||
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_100, -10000, VOL_STEP_mB, 0);
|
||||
|
||||
#define snd_asihpi_volume_mute_info snd_ctl_boolean_mono_info
|
||||
|
||||
static int snd_asihpi_volume_mute_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
u32 h_control = kcontrol->private_value;
|
||||
u32 mute;
|
||||
|
||||
hpi_handle_error(hpi_volume_get_mute(h_control, &mute));
|
||||
ucontrol->value.integer.value[0] = mute ? 0 : 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_asihpi_volume_mute_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
u32 h_control = kcontrol->private_value;
|
||||
int change = 1;
|
||||
/* HPI currently only supports all or none muting of multichannel volume
|
||||
ALSA Switch element has opposite sense to HPI mute: on==unmuted, off=muted
|
||||
*/
|
||||
int mute = ucontrol->value.integer.value[0] ? 0 : HPI_BITMASK_ALL_CHANNELS;
|
||||
hpi_handle_error(hpi_volume_set_mute(h_control, mute));
|
||||
return change;
|
||||
}
|
||||
|
||||
static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
|
||||
struct hpi_control *hpi_ctl)
|
||||
{
|
||||
struct snd_card *card = asihpi->card;
|
||||
struct snd_kcontrol_new snd_control;
|
||||
int err;
|
||||
u32 mute;
|
||||
|
||||
asihpi_ctl_init(&snd_control, hpi_ctl, "Volume");
|
||||
snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
|
||||
@ -1490,7 +1529,19 @@ static int __devinit snd_asihpi_volume_add(struct snd_card_asihpi *asihpi,
|
||||
snd_control.put = snd_asihpi_volume_put;
|
||||
snd_control.tlv.p = db_scale_100;
|
||||
|
||||
return ctl_add(card, &snd_control, asihpi);
|
||||
err = ctl_add(card, &snd_control, asihpi);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (hpi_volume_get_mute(hpi_ctl->h_control, &mute) == 0) {
|
||||
asihpi_ctl_init(&snd_control, hpi_ctl, "Switch");
|
||||
snd_control.access = SNDRV_CTL_ELEM_ACCESS_READWRITE;
|
||||
snd_control.info = snd_asihpi_volume_mute_info;
|
||||
snd_control.get = snd_asihpi_volume_mute_get;
|
||||
snd_control.put = snd_asihpi_volume_mute_put;
|
||||
err = ctl_add(card, &snd_control, asihpi);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------
|
||||
@ -2923,7 +2974,7 @@ static DEFINE_PCI_DEVICE_TABLE(asihpi_pci_tbl) = {
|
||||
MODULE_DEVICE_TABLE(pci, asihpi_pci_tbl);
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "asihpi",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = asihpi_pci_tbl,
|
||||
.probe = snd_asihpi_probe,
|
||||
.remove = __devexit_p(snd_asihpi_remove),
|
||||
|
@ -1,7 +1,7 @@
|
||||
/******************************************************************************
|
||||
|
||||
AudioScience HPI driver
|
||||
Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
|
||||
Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of version 2 of the GNU General Public License as
|
||||
@ -42,12 +42,11 @@ i.e 3.05.02 is a development version
|
||||
#define HPI_VER_MINOR(v) ((int)((v >> 8) & 0xFF))
|
||||
#define HPI_VER_RELEASE(v) ((int)(v & 0xFF))
|
||||
|
||||
/* Use single digits for versions less that 10 to avoid octal. */
|
||||
#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 6, 0)
|
||||
#define HPI_VER_STRING "4.06.00"
|
||||
#define HPI_VER HPI_VERSION_CONSTRUCTOR(4L, 8, 0)
|
||||
#define HPI_VER_STRING "4.08.00"
|
||||
|
||||
/* Library version as documented in hpi-api-versions.txt */
|
||||
#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(9, 0, 0)
|
||||
#define HPI_LIB_VER HPI_VERSION_CONSTRUCTOR(10, 0, 0)
|
||||
|
||||
#include <linux/types.h>
|
||||
#define HPI_BUILD_EXCLUDE_DEPRECATED
|
||||
@ -211,8 +210,12 @@ enum HPI_SOURCENODES {
|
||||
HPI_SOURCENODE_COBRANET = 109,
|
||||
HPI_SOURCENODE_ANALOG = 110, /**< analog input node. */
|
||||
HPI_SOURCENODE_ADAPTER = 111, /**< adapter node. */
|
||||
/** RTP stream input node - This node is a destination for
|
||||
packets of RTP audio samples from other devices. */
|
||||
HPI_SOURCENODE_RTP_DESTINATION = 112,
|
||||
HPI_SOURCENODE_GP_IN = 113, /**< general purpose input. */
|
||||
/* !!!Update this AND hpidebug.h if you add a new sourcenode type!!! */
|
||||
HPI_SOURCENODE_LAST_INDEX = 111 /**< largest ID */
|
||||
HPI_SOURCENODE_LAST_INDEX = 113 /**< largest ID */
|
||||
/* AX6 max sourcenode types = 15 */
|
||||
};
|
||||
|
||||
@ -228,7 +231,7 @@ enum HPI_DESTNODES {
|
||||
HPI_DESTNODE_NONE = 200,
|
||||
/** In Stream (Record) node. */
|
||||
HPI_DESTNODE_ISTREAM = 201,
|
||||
HPI_DESTNODE_LINEOUT = 202, /**< line out node. */
|
||||
HPI_DESTNODE_LINEOUT = 202, /**< line out node. */
|
||||
HPI_DESTNODE_AESEBU_OUT = 203, /**< AES/EBU output node. */
|
||||
HPI_DESTNODE_RF = 204, /**< RF output node. */
|
||||
HPI_DESTNODE_SPEAKER = 205, /**< speaker output node. */
|
||||
@ -236,9 +239,12 @@ enum HPI_DESTNODES {
|
||||
Audio samples from the device are sent out on the Cobranet network.*/
|
||||
HPI_DESTNODE_COBRANET = 206,
|
||||
HPI_DESTNODE_ANALOG = 207, /**< analog output node. */
|
||||
|
||||
/** RTP stream output node - This node is a source for
|
||||
packets of RTP audio samples that are sent to other devices. */
|
||||
HPI_DESTNODE_RTP_SOURCE = 208,
|
||||
HPI_DESTNODE_GP_OUT = 209, /**< general purpose output node. */
|
||||
/* !!!Update this AND hpidebug.h if you add a new destnode type!!! */
|
||||
HPI_DESTNODE_LAST_INDEX = 207 /**< largest ID */
|
||||
HPI_DESTNODE_LAST_INDEX = 209 /**< largest ID */
|
||||
/* AX6 max destnode types = 15 */
|
||||
};
|
||||
|
||||
|
@ -359,7 +359,7 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr)
|
||||
HPI_ERROR_PROCESSING_MESSAGE);
|
||||
|
||||
switch (phm->type) {
|
||||
case HPI_TYPE_MESSAGE:
|
||||
case HPI_TYPE_REQUEST:
|
||||
switch (phm->object) {
|
||||
case HPI_OBJ_SUBSYSTEM:
|
||||
subsys_message(phm, phr);
|
||||
@ -538,7 +538,7 @@ static short create_adapter_obj(struct hpi_adapter_obj *pao,
|
||||
|
||||
HPI_DEBUG_LOG(VERBOSE, "send ADAPTER_GET_INFO\n");
|
||||
memset(&hm, 0, sizeof(hm));
|
||||
hm.type = HPI_TYPE_MESSAGE;
|
||||
hm.type = HPI_TYPE_REQUEST;
|
||||
hm.size = sizeof(struct hpi_message);
|
||||
hm.object = HPI_OBJ_ADAPTER;
|
||||
hm.function = HPI_ADAPTER_GET_INFO;
|
||||
@ -946,11 +946,8 @@ static short hpi6000_adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
|
||||
}
|
||||
|
||||
/* write the DSP code down into the DSPs memory */
|
||||
/*HpiDspCode_Open(nBootLoadFamily,&DspCode,pdwOsErrorCode); */
|
||||
dsp_code.ps_dev = pao->pci.pci_dev;
|
||||
|
||||
error = hpi_dsp_code_open(boot_load_family, &dsp_code,
|
||||
pos_error_code);
|
||||
error = hpi_dsp_code_open(boot_load_family, pao->pci.pci_dev,
|
||||
&dsp_code, pos_error_code);
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
@ -373,6 +373,7 @@ static void instream_message(struct hpi_adapter_obj *pao,
|
||||
/** Entry point to this HPI backend
|
||||
* All calls to the HPI start here
|
||||
*/
|
||||
static
|
||||
void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
|
||||
struct hpi_response *phr)
|
||||
{
|
||||
@ -392,7 +393,7 @@ void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
|
||||
|
||||
HPI_DEBUG_LOG(VERBOSE, "start of switch\n");
|
||||
switch (phm->type) {
|
||||
case HPI_TYPE_MESSAGE:
|
||||
case HPI_TYPE_REQUEST:
|
||||
switch (phm->object) {
|
||||
case HPI_OBJ_SUBSYSTEM:
|
||||
subsys_message(pao, phm, phr);
|
||||
@ -402,7 +403,6 @@ void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm,
|
||||
adapter_message(pao, phm, phr);
|
||||
break;
|
||||
|
||||
case HPI_OBJ_CONTROLEX:
|
||||
case HPI_OBJ_CONTROL:
|
||||
control_message(pao, phm, phr);
|
||||
break;
|
||||
@ -634,11 +634,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
|
||||
|
||||
HPI_DEBUG_LOG(VERBOSE, "init ADAPTER_GET_INFO\n");
|
||||
memset(&hm, 0, sizeof(hm));
|
||||
hm.type = HPI_TYPE_MESSAGE;
|
||||
/* wAdapterIndex == version == 0 */
|
||||
hm.type = HPI_TYPE_REQUEST;
|
||||
hm.size = sizeof(hm);
|
||||
hm.object = HPI_OBJ_ADAPTER;
|
||||
hm.function = HPI_ADAPTER_GET_INFO;
|
||||
hm.adapter_index = 0;
|
||||
|
||||
memset(&hr, 0, sizeof(hr));
|
||||
hr.size = sizeof(hr);
|
||||
|
||||
@ -658,9 +659,6 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao,
|
||||
hr.u.ax.info.num_outstreams +
|
||||
hr.u.ax.info.num_instreams;
|
||||
|
||||
hpios_locked_mem_prepare((max_streams * 6) / 10, max_streams,
|
||||
65536, pao->pci.pci_dev);
|
||||
|
||||
HPI_DEBUG_LOG(VERBOSE,
|
||||
"got adapter info type %x index %d serial %d\n",
|
||||
hr.u.ax.info.adapter_type, hr.u.ax.info.adapter_index,
|
||||
@ -709,9 +707,6 @@ static void delete_adapter_obj(struct hpi_adapter_obj *pao)
|
||||
[i]);
|
||||
phw->outstream_host_buffer_size[i] = 0;
|
||||
}
|
||||
|
||||
hpios_locked_mem_unprepare(pao->pci.pci_dev);
|
||||
|
||||
kfree(phw);
|
||||
}
|
||||
|
||||
@ -1371,9 +1366,8 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao,
|
||||
return err;
|
||||
|
||||
/* write the DSP code down into the DSPs memory */
|
||||
dsp_code.ps_dev = pao->pci.pci_dev;
|
||||
err = hpi_dsp_code_open(boot_code_id[dsp], &dsp_code,
|
||||
pos_error_code);
|
||||
err = hpi_dsp_code_open(boot_code_id[dsp], pao->pci.pci_dev,
|
||||
&dsp_code, pos_error_code);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@ -2084,13 +2078,13 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
|
||||
u16 err = 0;
|
||||
|
||||
message_count++;
|
||||
if (phm->size > sizeof(interface->u)) {
|
||||
if (phm->size > sizeof(interface->u.message_buffer)) {
|
||||
phr->error = HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL;
|
||||
phr->specific_error = sizeof(interface->u);
|
||||
phr->specific_error = sizeof(interface->u.message_buffer);
|
||||
phr->size = sizeof(struct hpi_response_header);
|
||||
HPI_DEBUG_LOG(ERROR,
|
||||
"message len %d too big for buffer %zd \n", phm->size,
|
||||
sizeof(interface->u));
|
||||
sizeof(interface->u.message_buffer));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2122,18 +2116,19 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao,
|
||||
|
||||
/* read the result */
|
||||
if (time_out) {
|
||||
if (interface->u.response_buffer.size <= phr->size)
|
||||
if (interface->u.response_buffer.response.size <= phr->size)
|
||||
memcpy(phr, &interface->u.response_buffer,
|
||||
interface->u.response_buffer.size);
|
||||
interface->u.response_buffer.response.size);
|
||||
else {
|
||||
HPI_DEBUG_LOG(ERROR,
|
||||
"response len %d too big for buffer %d\n",
|
||||
interface->u.response_buffer.size, phr->size);
|
||||
interface->u.response_buffer.response.size,
|
||||
phr->size);
|
||||
memcpy(phr, &interface->u.response_buffer,
|
||||
sizeof(struct hpi_response_header));
|
||||
phr->error = HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
|
||||
phr->specific_error =
|
||||
interface->u.response_buffer.size;
|
||||
interface->u.response_buffer.response.size;
|
||||
phr->size = sizeof(struct hpi_response_header);
|
||||
}
|
||||
}
|
||||
@ -2202,23 +2197,6 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
|
||||
phm->u.d.u.data.data_size, H620_HIF_GET_DATA);
|
||||
break;
|
||||
|
||||
case HPI_CONTROL_SET_STATE:
|
||||
if (phm->object == HPI_OBJ_CONTROLEX
|
||||
&& phm->u.cx.attribute == HPI_COBRANET_SET_DATA)
|
||||
err = hpi6205_transfer_data(pao,
|
||||
phm->u.cx.u.cobranet_bigdata.pb_data,
|
||||
phm->u.cx.u.cobranet_bigdata.byte_count,
|
||||
H620_HIF_SEND_DATA);
|
||||
break;
|
||||
|
||||
case HPI_CONTROL_GET_STATE:
|
||||
if (phm->object == HPI_OBJ_CONTROLEX
|
||||
&& phm->u.cx.attribute == HPI_COBRANET_GET_DATA)
|
||||
err = hpi6205_transfer_data(pao,
|
||||
phm->u.cx.u.cobranet_bigdata.pb_data,
|
||||
phr->u.cx.u.cobranet_data.byte_count,
|
||||
H620_HIF_GET_DATA);
|
||||
break;
|
||||
}
|
||||
phr->error = err;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*****************************************************************************
|
||||
|
||||
AudioScience HPI driver
|
||||
Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
|
||||
Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of version 2 of the GNU General Public License as
|
||||
@ -70,15 +70,28 @@ The Host located memory buffer that the 6205 will bus master
|
||||
in and out of.
|
||||
************************************************************/
|
||||
#define HPI6205_SIZEOF_DATA (16*1024)
|
||||
|
||||
struct message_buffer_6205 {
|
||||
struct hpi_message message;
|
||||
char data[256];
|
||||
};
|
||||
|
||||
struct response_buffer_6205 {
|
||||
struct hpi_response response;
|
||||
char data[256];
|
||||
};
|
||||
|
||||
union buffer_6205 {
|
||||
struct message_buffer_6205 message_buffer;
|
||||
struct response_buffer_6205 response_buffer;
|
||||
u8 b_data[HPI6205_SIZEOF_DATA];
|
||||
};
|
||||
|
||||
struct bus_master_interface {
|
||||
u32 host_cmd;
|
||||
u32 dsp_ack;
|
||||
u32 transfer_size_in_bytes;
|
||||
union {
|
||||
struct hpi_message_header message_buffer;
|
||||
struct hpi_response_header response_buffer;
|
||||
u8 b_data[HPI6205_SIZEOF_DATA];
|
||||
} u;
|
||||
union buffer_6205 u;
|
||||
struct controlcache_6205 control_cache;
|
||||
struct async_event_buffer_6205 async_buffer;
|
||||
struct hpi_hostbuffer_status
|
||||
|
@ -1,7 +1,7 @@
|
||||
/******************************************************************************
|
||||
|
||||
AudioScience HPI driver
|
||||
Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
|
||||
Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of version 2 of the GNU General Public License as
|
||||
@ -32,12 +32,6 @@ HPI internal definitions
|
||||
#include "hpios.h"
|
||||
|
||||
/* physical memory allocation */
|
||||
void hpios_locked_mem_init(void
|
||||
);
|
||||
void hpios_locked_mem_free_all(void
|
||||
);
|
||||
#define hpios_locked_mem_prepare(a, b, c, d);
|
||||
#define hpios_locked_mem_unprepare(a)
|
||||
|
||||
/** Allocate and map an area of locked memory for bus master DMA operations.
|
||||
|
||||
@ -226,8 +220,8 @@ enum HPI_CONTROL_ATTRIBUTES {
|
||||
|
||||
HPI_COBRANET_SET = HPI_CTL_ATTR(COBRANET, 1),
|
||||
HPI_COBRANET_GET = HPI_CTL_ATTR(COBRANET, 2),
|
||||
HPI_COBRANET_SET_DATA = HPI_CTL_ATTR(COBRANET, 3),
|
||||
HPI_COBRANET_GET_DATA = HPI_CTL_ATTR(COBRANET, 4),
|
||||
/*HPI_COBRANET_SET_DATA = HPI_CTL_ATTR(COBRANET, 3), */
|
||||
/*HPI_COBRANET_GET_DATA = HPI_CTL_ATTR(COBRANET, 4), */
|
||||
HPI_COBRANET_GET_STATUS = HPI_CTL_ATTR(COBRANET, 5),
|
||||
HPI_COBRANET_SEND_PACKET = HPI_CTL_ATTR(COBRANET, 6),
|
||||
HPI_COBRANET_GET_PACKET = HPI_CTL_ATTR(COBRANET, 7),
|
||||
@ -364,10 +358,12 @@ Used in DLL to indicate device not present
|
||||
#define HPI_ADAPTER_ASI(f) (f)
|
||||
|
||||
enum HPI_MESSAGE_TYPES {
|
||||
HPI_TYPE_MESSAGE = 1,
|
||||
HPI_TYPE_REQUEST = 1,
|
||||
HPI_TYPE_RESPONSE = 2,
|
||||
HPI_TYPE_DATA = 3,
|
||||
HPI_TYPE_SSX2BYPASS_MESSAGE = 4
|
||||
HPI_TYPE_SSX2BYPASS_MESSAGE = 4,
|
||||
HPI_TYPE_COMMAND = 5,
|
||||
HPI_TYPE_NOTIFICATION = 6
|
||||
};
|
||||
|
||||
enum HPI_OBJECT_TYPES {
|
||||
@ -383,7 +379,7 @@ enum HPI_OBJECT_TYPES {
|
||||
HPI_OBJ_WATCHDOG = 10,
|
||||
HPI_OBJ_CLOCK = 11,
|
||||
HPI_OBJ_PROFILE = 12,
|
||||
HPI_OBJ_CONTROLEX = 13,
|
||||
/* HPI_ OBJ_ CONTROLEX = 13, */
|
||||
HPI_OBJ_ASYNCEVENT = 14
|
||||
#define HPI_OBJ_MAXINDEX 14
|
||||
};
|
||||
@ -608,7 +604,7 @@ struct hpi_data_compat32 {
|
||||
#endif
|
||||
|
||||
struct hpi_buffer {
|
||||
/** placehoder for backward compatibility (see dwBufferSize) */
|
||||
/** placeholder for backward compatibility (see dwBufferSize) */
|
||||
struct hpi_msg_format reserved;
|
||||
u32 command; /**< HPI_BUFFER_CMD_xxx*/
|
||||
u32 pci_address; /**< PCI physical address of buffer for DSP DMA */
|
||||
@ -912,95 +908,13 @@ union hpi_control_union_res {
|
||||
u32 remaining_chars;
|
||||
} chars8;
|
||||
char c_data12[12];
|
||||
};
|
||||
|
||||
/* HPI_CONTROLX_STRUCTURES */
|
||||
|
||||
/* Message */
|
||||
|
||||
/** Used for all HMI variables where max length <= 8 bytes
|
||||
*/
|
||||
struct hpi_controlx_msg_cobranet_data {
|
||||
u32 hmi_address;
|
||||
u32 byte_count;
|
||||
u32 data[2];
|
||||
};
|
||||
|
||||
/** Used for string data, and for packet bridge
|
||||
*/
|
||||
struct hpi_controlx_msg_cobranet_bigdata {
|
||||
u32 hmi_address;
|
||||
u32 byte_count;
|
||||
u8 *pb_data;
|
||||
#ifndef HPI64BIT
|
||||
u32 padding;
|
||||
#endif
|
||||
};
|
||||
|
||||
/** Used for PADS control reading of string fields.
|
||||
*/
|
||||
struct hpi_controlx_msg_pad_data {
|
||||
u32 field;
|
||||
u32 byte_count;
|
||||
u8 *pb_data;
|
||||
#ifndef HPI64BIT
|
||||
u32 padding;
|
||||
#endif
|
||||
};
|
||||
|
||||
/** Used for generic data
|
||||
*/
|
||||
|
||||
struct hpi_controlx_msg_generic {
|
||||
u32 param1;
|
||||
u32 param2;
|
||||
};
|
||||
|
||||
struct hpi_controlx_msg {
|
||||
u16 attribute; /* control attribute or property */
|
||||
u16 saved_index;
|
||||
union {
|
||||
struct hpi_controlx_msg_cobranet_data cobranet_data;
|
||||
struct hpi_controlx_msg_cobranet_bigdata cobranet_bigdata;
|
||||
struct hpi_controlx_msg_generic generic;
|
||||
struct hpi_controlx_msg_pad_data pad_data;
|
||||
/*struct param_value universal_value; */
|
||||
/* nothing extra to send for status read */
|
||||
} u;
|
||||
};
|
||||
|
||||
/* Response */
|
||||
/**
|
||||
*/
|
||||
struct hpi_controlx_res_cobranet_data {
|
||||
u32 byte_count;
|
||||
u32 data[2];
|
||||
};
|
||||
|
||||
struct hpi_controlx_res_cobranet_bigdata {
|
||||
u32 byte_count;
|
||||
};
|
||||
|
||||
struct hpi_controlx_res_cobranet_status {
|
||||
u32 status;
|
||||
u32 readable_size;
|
||||
u32 writeable_size;
|
||||
};
|
||||
|
||||
struct hpi_controlx_res_generic {
|
||||
u32 param1;
|
||||
u32 param2;
|
||||
};
|
||||
|
||||
struct hpi_controlx_res {
|
||||
union {
|
||||
struct hpi_controlx_res_cobranet_bigdata cobranet_bigdata;
|
||||
struct hpi_controlx_res_cobranet_data cobranet_data;
|
||||
struct hpi_controlx_res_cobranet_status cobranet_status;
|
||||
struct hpi_controlx_res_generic generic;
|
||||
/*struct param_info universal_info; */
|
||||
/*struct param_value universal_value; */
|
||||
} u;
|
||||
struct {
|
||||
u32 status;
|
||||
u32 readable_size;
|
||||
u32 writeable_size;
|
||||
} status;
|
||||
} cobranet;
|
||||
};
|
||||
|
||||
struct hpi_nvmemory_msg {
|
||||
@ -1126,7 +1040,6 @@ struct hpi_message {
|
||||
/* identical to struct hpi_control_msg,
|
||||
but field naming is improved */
|
||||
struct hpi_control_union_msg cu;
|
||||
struct hpi_controlx_msg cx; /* extended mixer control; */
|
||||
struct hpi_nvmemory_msg n;
|
||||
struct hpi_gpio_msg l; /* digital i/o */
|
||||
struct hpi_watchdog_msg w;
|
||||
@ -1151,7 +1064,7 @@ struct hpi_message {
|
||||
sizeof(struct hpi_message_header) + sizeof(struct hpi_watchdog_msg),\
|
||||
sizeof(struct hpi_message_header) + sizeof(struct hpi_clock_msg),\
|
||||
sizeof(struct hpi_message_header) + sizeof(struct hpi_profile_msg),\
|
||||
sizeof(struct hpi_message_header) + sizeof(struct hpi_controlx_msg),\
|
||||
sizeof(struct hpi_message_header), /* controlx obj removed */ \
|
||||
sizeof(struct hpi_message_header) + sizeof(struct hpi_async_msg) \
|
||||
}
|
||||
|
||||
@ -1188,7 +1101,6 @@ struct hpi_response {
|
||||
struct hpi_control_res c; /* mixer control; */
|
||||
/* identical to hpi_control_res, but field naming is improved */
|
||||
union hpi_control_union_res cu;
|
||||
struct hpi_controlx_res cx; /* extended mixer control; */
|
||||
struct hpi_nvmemory_res n;
|
||||
struct hpi_gpio_res l; /* digital i/o */
|
||||
struct hpi_watchdog_res w;
|
||||
@ -1213,7 +1125,7 @@ struct hpi_response {
|
||||
sizeof(struct hpi_response_header) + sizeof(struct hpi_watchdog_res),\
|
||||
sizeof(struct hpi_response_header) + sizeof(struct hpi_clock_res),\
|
||||
sizeof(struct hpi_response_header) + sizeof(struct hpi_profile_res),\
|
||||
sizeof(struct hpi_response_header) + sizeof(struct hpi_controlx_res),\
|
||||
sizeof(struct hpi_response_header), /* controlx obj removed */ \
|
||||
sizeof(struct hpi_response_header) + sizeof(struct hpi_async_res) \
|
||||
}
|
||||
|
||||
@ -1308,6 +1220,30 @@ struct hpi_res_adapter_debug_read {
|
||||
u8 bytes[256];
|
||||
};
|
||||
|
||||
struct hpi_msg_cobranet_hmi {
|
||||
u16 attribute;
|
||||
u16 padding;
|
||||
u32 hmi_address;
|
||||
u32 byte_count;
|
||||
};
|
||||
|
||||
struct hpi_msg_cobranet_hmiwrite {
|
||||
struct hpi_message_header h;
|
||||
struct hpi_msg_cobranet_hmi p;
|
||||
u8 bytes[256];
|
||||
};
|
||||
|
||||
struct hpi_msg_cobranet_hmiread {
|
||||
struct hpi_message_header h;
|
||||
struct hpi_msg_cobranet_hmi p;
|
||||
};
|
||||
|
||||
struct hpi_res_cobranet_hmiread {
|
||||
struct hpi_response_header h;
|
||||
u32 byte_count;
|
||||
u8 bytes[256];
|
||||
};
|
||||
|
||||
#if 1
|
||||
#define hpi_message_header_v1 hpi_message_header
|
||||
#define hpi_response_header_v1 hpi_response_header
|
||||
@ -1338,7 +1274,6 @@ struct hpi_msg_payload_v0 {
|
||||
union hpi_mixerx_msg mx;
|
||||
struct hpi_control_msg c;
|
||||
struct hpi_control_union_msg cu;
|
||||
struct hpi_controlx_msg cx;
|
||||
struct hpi_nvmemory_msg n;
|
||||
struct hpi_gpio_msg l;
|
||||
struct hpi_watchdog_msg w;
|
||||
@ -1358,7 +1293,6 @@ struct hpi_res_payload_v0 {
|
||||
union hpi_mixerx_res mx;
|
||||
struct hpi_control_res c;
|
||||
union hpi_control_union_res cu;
|
||||
struct hpi_controlx_res cx;
|
||||
struct hpi_nvmemory_res n;
|
||||
struct hpi_gpio_res l;
|
||||
struct hpi_watchdog_res w;
|
||||
@ -1493,12 +1427,6 @@ struct hpi_control_cache_microphone {
|
||||
char temp_padding[6];
|
||||
};
|
||||
|
||||
struct hpi_control_cache_generic {
|
||||
struct hpi_control_cache_info i;
|
||||
u32 dw1;
|
||||
u32 dw2;
|
||||
};
|
||||
|
||||
struct hpi_control_cache_single {
|
||||
union {
|
||||
struct hpi_control_cache_info i;
|
||||
@ -1514,7 +1442,6 @@ struct hpi_control_cache_single {
|
||||
struct hpi_control_cache_silencedetector silence;
|
||||
struct hpi_control_cache_sampleclock clk;
|
||||
struct hpi_control_cache_microphone microphone;
|
||||
struct hpi_control_cache_generic generic;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
@ -57,7 +57,7 @@ u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr)
|
||||
}
|
||||
|
||||
if (phr->function != phm->function) {
|
||||
HPI_DEBUG_LOG(ERROR, "header type %d invalid\n",
|
||||
HPI_DEBUG_LOG(ERROR, "header function %d invalid\n",
|
||||
phr->function);
|
||||
return HPI_ERROR_INVALID_RESPONSE;
|
||||
}
|
||||
@ -315,8 +315,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
|
||||
short found = 1;
|
||||
struct hpi_control_cache_info *pI;
|
||||
struct hpi_control_cache_single *pC;
|
||||
struct hpi_control_cache_pad *p_pad;
|
||||
|
||||
size_t response_size;
|
||||
if (!find_control(phm->obj_index, p_cache, &pI)) {
|
||||
HPI_DEBUG_LOG(VERBOSE,
|
||||
"HPICMN find_control() failed for adap %d\n",
|
||||
@ -326,11 +325,15 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
|
||||
|
||||
phr->error = 0;
|
||||
|
||||
/* set the default response size */
|
||||
response_size =
|
||||
sizeof(struct hpi_response_header) +
|
||||
sizeof(struct hpi_control_res);
|
||||
|
||||
/* pC is the default cached control strucure. May be cast to
|
||||
something else in the following switch statement.
|
||||
*/
|
||||
pC = (struct hpi_control_cache_single *)pI;
|
||||
p_pad = (struct hpi_control_cache_pad *)pI;
|
||||
|
||||
switch (pI->control_type) {
|
||||
|
||||
@ -529,9 +532,7 @@ short hpi_check_control_cache(struct hpi_control_cache *p_cache,
|
||||
pI->control_index, pI->control_type, phm->u.c.attribute);
|
||||
|
||||
if (found)
|
||||
phr->size =
|
||||
sizeof(struct hpi_response_header) +
|
||||
sizeof(struct hpi_control_res);
|
||||
phr->size = (u16)response_size;
|
||||
|
||||
return found;
|
||||
}
|
||||
@ -682,7 +683,7 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr)
|
||||
void HPI_COMMON(struct hpi_message *phm, struct hpi_response *phr)
|
||||
{
|
||||
switch (phm->type) {
|
||||
case HPI_TYPE_MESSAGE:
|
||||
case HPI_TYPE_REQUEST:
|
||||
switch (phm->object) {
|
||||
case HPI_OBJ_SUBSYSTEM:
|
||||
subsys_message(phm, phr);
|
||||
|
@ -1,8 +1,8 @@
|
||||
/***********************************************************************/
|
||||
/*!
|
||||
/**
|
||||
|
||||
AudioScience HPI driver
|
||||
Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
|
||||
Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of version 2 of the GNU General Public License as
|
||||
@ -18,90 +18,59 @@
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
\file
|
||||
Functions for reading DSP code to load into DSP
|
||||
|
||||
(Linux only:) If DSPCODE_FIRMWARE_LOADER is defined, code is read using
|
||||
Functions for reading DSP code using
|
||||
hotplug firmware loader from individual dsp code files
|
||||
|
||||
If neither of the above is defined, code is read from linked arrays.
|
||||
DSPCODE_ARRAY is defined.
|
||||
|
||||
HPI_INCLUDE_**** must be defined
|
||||
and the appropriate hzz?????.c or hex?????.c linked in
|
||||
|
||||
*/
|
||||
*/
|
||||
/***********************************************************************/
|
||||
#define SOURCEFILE_NAME "hpidspcd.c"
|
||||
#include "hpidspcd.h"
|
||||
#include "hpidebug.h"
|
||||
|
||||
/**
|
||||
Header structure for binary dsp code file (see asidsp.doc)
|
||||
This structure must match that used in s2bin.c for generation of asidsp.bin
|
||||
*/
|
||||
|
||||
#ifndef DISABLE_PRAGMA_PACK1
|
||||
#pragma pack(push, 1)
|
||||
#endif
|
||||
|
||||
struct code_header {
|
||||
u32 size;
|
||||
char type[4];
|
||||
u32 adapter;
|
||||
u32 version;
|
||||
u32 crc;
|
||||
struct dsp_code_private {
|
||||
/** Firmware descriptor */
|
||||
const struct firmware *firmware;
|
||||
struct pci_dev *dev;
|
||||
};
|
||||
|
||||
#ifndef DISABLE_PRAGMA_PACK1
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
|
||||
HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
|
||||
|
||||
/***********************************************************************/
|
||||
#include <linux/pci.h>
|
||||
/*-------------------------------------------------------------------*/
|
||||
short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code,
|
||||
u32 *pos_error_code)
|
||||
short hpi_dsp_code_open(u32 adapter, void *os_data, struct dsp_code *dsp_code,
|
||||
u32 *os_error_code)
|
||||
{
|
||||
const struct firmware *ps_firmware = ps_dsp_code->ps_firmware;
|
||||
const struct firmware *firmware;
|
||||
struct pci_dev *dev = os_data;
|
||||
struct code_header header;
|
||||
char fw_name[20];
|
||||
int err;
|
||||
|
||||
sprintf(fw_name, "asihpi/dsp%04x.bin", adapter);
|
||||
|
||||
err = request_firmware(&ps_firmware, fw_name,
|
||||
&ps_dsp_code->ps_dev->dev);
|
||||
err = request_firmware(&firmware, fw_name, &dev->dev);
|
||||
|
||||
if (err != 0) {
|
||||
dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
|
||||
if (err || !firmware) {
|
||||
dev_printk(KERN_ERR, &dev->dev,
|
||||
"%d, request_firmware failed for %s\n", err,
|
||||
fw_name);
|
||||
goto error1;
|
||||
}
|
||||
if (ps_firmware->size < sizeof(header)) {
|
||||
dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
|
||||
"Header size too small %s\n", fw_name);
|
||||
if (firmware->size < sizeof(header)) {
|
||||
dev_printk(KERN_ERR, &dev->dev, "Header size too small %s\n",
|
||||
fw_name);
|
||||
goto error2;
|
||||
}
|
||||
memcpy(&header, ps_firmware->data, sizeof(header));
|
||||
if (header.adapter != adapter) {
|
||||
dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
|
||||
"Adapter type incorrect %4x != %4x\n", header.adapter,
|
||||
adapter);
|
||||
goto error2;
|
||||
}
|
||||
if (header.size != ps_firmware->size) {
|
||||
dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
|
||||
"Code size wrong %d != %ld\n", header.size,
|
||||
(unsigned long)ps_firmware->size);
|
||||
memcpy(&header, firmware->data, sizeof(header));
|
||||
|
||||
if ((header.type != 0x45444F43) || /* "CODE" */
|
||||
(header.adapter != adapter)
|
||||
|| (header.size != firmware->size)) {
|
||||
dev_printk(KERN_ERR, &dev->dev, "Invalid firmware file\n");
|
||||
goto error2;
|
||||
}
|
||||
|
||||
if (header.version / 100 != HPI_VER_DECIMAL / 100) {
|
||||
dev_printk(KERN_ERR, &ps_dsp_code->ps_dev->dev,
|
||||
if ((header.version / 100 & ~1) != (HPI_VER_DECIMAL / 100 & ~1)) {
|
||||
dev_printk(KERN_ERR, &dev->dev,
|
||||
"Incompatible firmware version "
|
||||
"DSP image %d != Driver %d\n", header.version,
|
||||
HPI_VER_DECIMAL);
|
||||
@ -109,67 +78,70 @@ short hpi_dsp_code_open(u32 adapter, struct dsp_code *ps_dsp_code,
|
||||
}
|
||||
|
||||
if (header.version != HPI_VER_DECIMAL) {
|
||||
dev_printk(KERN_WARNING, &ps_dsp_code->ps_dev->dev,
|
||||
dev_printk(KERN_WARNING, &dev->dev,
|
||||
"Firmware: release version mismatch DSP image %d != Driver %d\n",
|
||||
header.version, HPI_VER_DECIMAL);
|
||||
}
|
||||
|
||||
HPI_DEBUG_LOG(DEBUG, "dsp code %s opened\n", fw_name);
|
||||
ps_dsp_code->ps_firmware = ps_firmware;
|
||||
ps_dsp_code->block_length = header.size / sizeof(u32);
|
||||
ps_dsp_code->word_count = sizeof(header) / sizeof(u32);
|
||||
ps_dsp_code->version = header.version;
|
||||
ps_dsp_code->crc = header.crc;
|
||||
dsp_code->pvt = kmalloc(sizeof(*dsp_code->pvt), GFP_KERNEL);
|
||||
if (!dsp_code->pvt)
|
||||
return HPI_ERROR_MEMORY_ALLOC;
|
||||
|
||||
dsp_code->pvt->dev = dev;
|
||||
dsp_code->pvt->firmware = firmware;
|
||||
dsp_code->header = header;
|
||||
dsp_code->block_length = header.size / sizeof(u32);
|
||||
dsp_code->word_count = sizeof(header) / sizeof(u32);
|
||||
return 0;
|
||||
|
||||
error2:
|
||||
release_firmware(ps_firmware);
|
||||
release_firmware(firmware);
|
||||
error1:
|
||||
ps_dsp_code->ps_firmware = NULL;
|
||||
ps_dsp_code->block_length = 0;
|
||||
dsp_code->block_length = 0;
|
||||
return HPI_ERROR_DSP_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
void hpi_dsp_code_close(struct dsp_code *ps_dsp_code)
|
||||
void hpi_dsp_code_close(struct dsp_code *dsp_code)
|
||||
{
|
||||
if (ps_dsp_code->ps_firmware != NULL) {
|
||||
if (dsp_code->pvt->firmware) {
|
||||
HPI_DEBUG_LOG(DEBUG, "dsp code closed\n");
|
||||
release_firmware(ps_dsp_code->ps_firmware);
|
||||
ps_dsp_code->ps_firmware = NULL;
|
||||
release_firmware(dsp_code->pvt->firmware);
|
||||
dsp_code->pvt->firmware = NULL;
|
||||
}
|
||||
kfree(dsp_code->pvt);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
void hpi_dsp_code_rewind(struct dsp_code *ps_dsp_code)
|
||||
void hpi_dsp_code_rewind(struct dsp_code *dsp_code)
|
||||
{
|
||||
/* Go back to start of data, after header */
|
||||
ps_dsp_code->word_count = sizeof(struct code_header) / sizeof(u32);
|
||||
dsp_code->word_count = sizeof(struct code_header) / sizeof(u32);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
short hpi_dsp_code_read_word(struct dsp_code *ps_dsp_code, u32 *pword)
|
||||
short hpi_dsp_code_read_word(struct dsp_code *dsp_code, u32 *pword)
|
||||
{
|
||||
if (ps_dsp_code->word_count + 1 > ps_dsp_code->block_length)
|
||||
if (dsp_code->word_count + 1 > dsp_code->block_length)
|
||||
return HPI_ERROR_DSP_FILE_FORMAT;
|
||||
|
||||
*pword = ((u32 *)(ps_dsp_code->ps_firmware->data))[ps_dsp_code->
|
||||
*pword = ((u32 *)(dsp_code->pvt->firmware->data))[dsp_code->
|
||||
word_count];
|
||||
ps_dsp_code->word_count++;
|
||||
dsp_code->word_count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
short hpi_dsp_code_read_block(size_t words_requested,
|
||||
struct dsp_code *ps_dsp_code, u32 **ppblock)
|
||||
struct dsp_code *dsp_code, u32 **ppblock)
|
||||
{
|
||||
if (ps_dsp_code->word_count + words_requested >
|
||||
ps_dsp_code->block_length)
|
||||
if (dsp_code->word_count + words_requested > dsp_code->block_length)
|
||||
return HPI_ERROR_DSP_FILE_FORMAT;
|
||||
|
||||
*ppblock =
|
||||
((u32 *)(ps_dsp_code->ps_firmware->data)) +
|
||||
ps_dsp_code->word_count;
|
||||
ps_dsp_code->word_count += words_requested;
|
||||
((u32 *)(dsp_code->pvt->firmware->data)) +
|
||||
dsp_code->word_count;
|
||||
dsp_code->word_count += words_requested;
|
||||
return 0;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
/**
|
||||
|
||||
AudioScience HPI driver
|
||||
Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
|
||||
Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of version 2 of the GNU General Public License as
|
||||
@ -20,19 +20,6 @@
|
||||
\file
|
||||
Functions for reading DSP code to load into DSP
|
||||
|
||||
hpi_dspcode_defines HPI DSP code loading method
|
||||
Define exactly one of these to select how the DSP code is supplied to
|
||||
the adapter.
|
||||
|
||||
End users writing applications that use the HPI interface do not have to
|
||||
use any of the below defines; they are only necessary for building drivers
|
||||
|
||||
HPI_DSPCODE_FILE:
|
||||
DSP code is supplied as a file that is opened and read from by the driver.
|
||||
|
||||
HPI_DSPCODE_FIRMWARE:
|
||||
DSP code is read using the hotplug firmware loader module.
|
||||
Only valid when compiling the HPI kernel driver under Linux.
|
||||
*/
|
||||
/***********************************************************************/
|
||||
#ifndef _HPIDSPCD_H_
|
||||
@ -40,37 +27,56 @@ DSP code is read using the hotplug firmware loader module.
|
||||
|
||||
#include "hpi_internal.h"
|
||||
|
||||
#ifndef DISABLE_PRAGMA_PACK1
|
||||
#pragma pack(push, 1)
|
||||
#endif
|
||||
/** Code header version is decimal encoded e.g. 4.06.10 is 40601 */
|
||||
#define HPI_VER_DECIMAL ((int)(HPI_VER_MAJOR(HPI_VER) * 10000 + \
|
||||
HPI_VER_MINOR(HPI_VER) * 100 + HPI_VER_RELEASE(HPI_VER)))
|
||||
|
||||
/** Header structure for dsp firmware file
|
||||
This structure must match that used in s2bin.c for generation of asidsp.bin
|
||||
*/
|
||||
/*#ifndef DISABLE_PRAGMA_PACK1 */
|
||||
/*#pragma pack(push, 1) */
|
||||
/*#endif */
|
||||
struct code_header {
|
||||
/** Size in bytes including header */
|
||||
u32 size;
|
||||
/** File type tag "CODE" == 0x45444F43 */
|
||||
u32 type;
|
||||
/** Adapter model number */
|
||||
u32 adapter;
|
||||
/** Firmware version*/
|
||||
u32 version;
|
||||
/** Data checksum */
|
||||
u32 checksum;
|
||||
};
|
||||
/*#ifndef DISABLE_PRAGMA_PACK1 */
|
||||
/*#pragma pack(pop) */
|
||||
/*#endif */
|
||||
|
||||
/*? Don't need the pragmas? */
|
||||
compile_time_assert((sizeof(struct code_header) == 20), code_header_size);
|
||||
|
||||
/** Descriptor for dspcode from firmware loader */
|
||||
struct dsp_code {
|
||||
/** Firmware descriptor */
|
||||
const struct firmware *ps_firmware;
|
||||
struct pci_dev *ps_dev;
|
||||
/** copy of file header */
|
||||
struct code_header header;
|
||||
/** Expected number of words in the whole dsp code,INCL header */
|
||||
long int block_length;
|
||||
u32 block_length;
|
||||
/** Number of words read so far */
|
||||
long int word_count;
|
||||
/** Version read from dsp code file */
|
||||
u32 version;
|
||||
/** CRC read from dsp code file */
|
||||
u32 crc;
|
||||
u32 word_count;
|
||||
|
||||
/** internal state of DSP code reader */
|
||||
struct dsp_code_private *pvt;
|
||||
};
|
||||
|
||||
#ifndef DISABLE_PRAGMA_PACK1
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
/** Prepare *psDspCode to refer to the requuested adapter.
|
||||
Searches the file, or selects the appropriate linked array
|
||||
/** Prepare *psDspCode to refer to the requested adapter's firmware.
|
||||
Code file name is obtained from HpiOs_GetDspCodePath
|
||||
|
||||
\return 0 for success, or error code if requested code is not available
|
||||
*/
|
||||
short hpi_dsp_code_open(
|
||||
/** Code identifier, usually adapter family */
|
||||
u32 adapter,
|
||||
u32 adapter, void *pci_dev,
|
||||
/** Pointer to DSP code control structure */
|
||||
struct dsp_code *ps_dsp_code,
|
||||
/** Pointer to dword to receive OS specific error code */
|
||||
|
@ -1663,68 +1663,64 @@ u16 hpi_channel_mode_get(u32 h_control, u16 *mode)
|
||||
u16 hpi_cobranet_hmi_write(u32 h_control, u32 hmi_address, u32 byte_count,
|
||||
u8 *pb_data)
|
||||
{
|
||||
struct hpi_message hm;
|
||||
struct hpi_response hr;
|
||||
struct hpi_msg_cobranet_hmiwrite hm;
|
||||
struct hpi_response_header hr;
|
||||
|
||||
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
|
||||
HPI_CONTROL_SET_STATE);
|
||||
if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
|
||||
hpi_init_message_responseV1(&hm.h, sizeof(hm), &hr, sizeof(hr),
|
||||
HPI_OBJ_CONTROL, HPI_CONTROL_SET_STATE);
|
||||
|
||||
if (hpi_handle_indexes(h_control, &hm.h.adapter_index,
|
||||
&hm.h.obj_index))
|
||||
return HPI_ERROR_INVALID_HANDLE;
|
||||
|
||||
hm.u.cx.u.cobranet_data.byte_count = byte_count;
|
||||
hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
|
||||
if (byte_count > sizeof(hm.bytes))
|
||||
return HPI_ERROR_MESSAGE_BUFFER_TOO_SMALL;
|
||||
|
||||
if (byte_count <= 8) {
|
||||
memcpy(hm.u.cx.u.cobranet_data.data, pb_data, byte_count);
|
||||
hm.u.cx.attribute = HPI_COBRANET_SET;
|
||||
} else {
|
||||
hm.u.cx.u.cobranet_bigdata.pb_data = pb_data;
|
||||
hm.u.cx.attribute = HPI_COBRANET_SET_DATA;
|
||||
}
|
||||
|
||||
hpi_send_recv(&hm, &hr);
|
||||
hm.p.attribute = HPI_COBRANET_SET;
|
||||
hm.p.byte_count = byte_count;
|
||||
hm.p.hmi_address = hmi_address;
|
||||
memcpy(hm.bytes, pb_data, byte_count);
|
||||
hm.h.size = (u16)(sizeof(hm.h) + sizeof(hm.p) + byte_count);
|
||||
|
||||
hpi_send_recvV1(&hm.h, &hr);
|
||||
return hr.error;
|
||||
}
|
||||
|
||||
u16 hpi_cobranet_hmi_read(u32 h_control, u32 hmi_address, u32 max_byte_count,
|
||||
u32 *pbyte_count, u8 *pb_data)
|
||||
{
|
||||
struct hpi_message hm;
|
||||
struct hpi_response hr;
|
||||
struct hpi_msg_cobranet_hmiread hm;
|
||||
struct hpi_res_cobranet_hmiread hr;
|
||||
|
||||
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
|
||||
HPI_CONTROL_GET_STATE);
|
||||
if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
|
||||
hpi_init_message_responseV1(&hm.h, sizeof(hm), &hr.h, sizeof(hr),
|
||||
HPI_OBJ_CONTROL, HPI_CONTROL_GET_STATE);
|
||||
|
||||
if (hpi_handle_indexes(h_control, &hm.h.adapter_index,
|
||||
&hm.h.obj_index))
|
||||
return HPI_ERROR_INVALID_HANDLE;
|
||||
|
||||
hm.u.cx.u.cobranet_data.byte_count = max_byte_count;
|
||||
hm.u.cx.u.cobranet_data.hmi_address = hmi_address;
|
||||
if (max_byte_count > sizeof(hr.bytes))
|
||||
return HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
|
||||
|
||||
if (max_byte_count <= 8) {
|
||||
hm.u.cx.attribute = HPI_COBRANET_GET;
|
||||
} else {
|
||||
hm.u.cx.u.cobranet_bigdata.pb_data = pb_data;
|
||||
hm.u.cx.attribute = HPI_COBRANET_GET_DATA;
|
||||
}
|
||||
hm.p.attribute = HPI_COBRANET_GET;
|
||||
hm.p.byte_count = max_byte_count;
|
||||
hm.p.hmi_address = hmi_address;
|
||||
|
||||
hpi_send_recv(&hm, &hr);
|
||||
if (!hr.error && pb_data) {
|
||||
hpi_send_recvV1(&hm.h, &hr.h);
|
||||
|
||||
*pbyte_count = hr.u.cx.u.cobranet_data.byte_count;
|
||||
if (!hr.h.error && pb_data) {
|
||||
if (hr.byte_count > sizeof(hr.bytes))
|
||||
|
||||
if (*pbyte_count < max_byte_count)
|
||||
return HPI_ERROR_RESPONSE_BUFFER_TOO_SMALL;
|
||||
|
||||
*pbyte_count = hr.byte_count;
|
||||
|
||||
if (hr.byte_count < max_byte_count)
|
||||
max_byte_count = *pbyte_count;
|
||||
|
||||
if (hm.u.cx.attribute == HPI_COBRANET_GET) {
|
||||
memcpy(pb_data, hr.u.cx.u.cobranet_data.data,
|
||||
max_byte_count);
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
memcpy(pb_data, hr.bytes, max_byte_count);
|
||||
}
|
||||
return hr.error;
|
||||
return hr.h.error;
|
||||
}
|
||||
|
||||
u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus,
|
||||
@ -1733,23 +1729,23 @@ u16 hpi_cobranet_hmi_get_status(u32 h_control, u32 *pstatus,
|
||||
struct hpi_message hm;
|
||||
struct hpi_response hr;
|
||||
|
||||
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROLEX,
|
||||
hpi_init_message_response(&hm, &hr, HPI_OBJ_CONTROL,
|
||||
HPI_CONTROL_GET_STATE);
|
||||
if (hpi_handle_indexes(h_control, &hm.adapter_index, &hm.obj_index))
|
||||
return HPI_ERROR_INVALID_HANDLE;
|
||||
|
||||
hm.u.cx.attribute = HPI_COBRANET_GET_STATUS;
|
||||
hm.u.c.attribute = HPI_COBRANET_GET_STATUS;
|
||||
|
||||
hpi_send_recv(&hm, &hr);
|
||||
if (!hr.error) {
|
||||
if (pstatus)
|
||||
*pstatus = hr.u.cx.u.cobranet_status.status;
|
||||
*pstatus = hr.u.cu.cobranet.status.status;
|
||||
if (preadable_size)
|
||||
*preadable_size =
|
||||
hr.u.cx.u.cobranet_status.readable_size;
|
||||
hr.u.cu.cobranet.status.readable_size;
|
||||
if (pwriteable_size)
|
||||
*pwriteable_size =
|
||||
hr.u.cx.u.cobranet_status.writeable_size;
|
||||
hr.u.cu.cobranet.status.writeable_size;
|
||||
}
|
||||
return hr.error;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ static void hpi_init_message(struct hpi_message *phm, u16 object,
|
||||
if (gwSSX2_bypass)
|
||||
phm->type = HPI_TYPE_SSX2BYPASS_MESSAGE;
|
||||
else
|
||||
phm->type = HPI_TYPE_MESSAGE;
|
||||
phm->type = HPI_TYPE_REQUEST;
|
||||
phm->object = object;
|
||||
phm->function = function;
|
||||
phm->version = 0;
|
||||
@ -89,7 +89,7 @@ static void hpi_init_messageV1(struct hpi_message_header *phm, u16 size,
|
||||
memset(phm, 0, sizeof(*phm));
|
||||
if ((object > 0) && (object <= HPI_OBJ_MAXINDEX)) {
|
||||
phm->size = size;
|
||||
phm->type = HPI_TYPE_MESSAGE;
|
||||
phm->type = HPI_TYPE_REQUEST;
|
||||
phm->object = object;
|
||||
phm->function = function;
|
||||
phm->version = 1;
|
||||
|
@ -16,7 +16,7 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Extended Message Function With Response Cacheing
|
||||
Extended Message Function With Response Caching
|
||||
|
||||
(C) Copyright AudioScience Inc. 2002
|
||||
*****************************************************************************/
|
||||
@ -186,7 +186,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
|
||||
/* Initialize this module's internal state */
|
||||
hpios_msgxlock_init(&msgx_lock);
|
||||
memset(&hpi_entry_points, 0, sizeof(hpi_entry_points));
|
||||
hpios_locked_mem_init();
|
||||
/* Init subsys_findadapters response to no-adapters */
|
||||
HPIMSGX__reset(HPIMSGX_ALLADAPTERS);
|
||||
hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
|
||||
@ -197,7 +196,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr,
|
||||
case HPI_SUBSYS_DRIVER_UNLOAD:
|
||||
HPI_COMMON(phm, phr);
|
||||
HPIMSGX__cleanup(HPIMSGX_ALLADAPTERS, h_owner);
|
||||
hpios_locked_mem_free_all();
|
||||
hpi_init_response(phr, HPI_OBJ_SUBSYSTEM,
|
||||
HPI_SUBSYS_DRIVER_UNLOAD, 0);
|
||||
return;
|
||||
@ -315,7 +313,7 @@ void hpi_send_recv_ex(struct hpi_message *phm, struct hpi_response *phr,
|
||||
{
|
||||
HPI_DEBUG_MESSAGE(DEBUG, phm);
|
||||
|
||||
if (phm->type != HPI_TYPE_MESSAGE) {
|
||||
if (phm->type != HPI_TYPE_REQUEST) {
|
||||
hpi_init_response(phr, phm->object, phm->function,
|
||||
HPI_ERROR_INVALID_TYPE);
|
||||
return;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/*******************************************************************************
|
||||
|
||||
AudioScience HPI driver
|
||||
Copyright (C) 1997-2010 AudioScience Inc. <support@audioscience.com>
|
||||
Copyright (C) 1997-2011 AudioScience Inc. <support@audioscience.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of version 2 of the GNU General Public License as
|
||||
@ -157,11 +157,6 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hm->h.adapter_index >= HPI_MAX_ADAPTERS) {
|
||||
err = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (hm->h.function) {
|
||||
case HPI_SUBSYS_CREATE_ADAPTER:
|
||||
case HPI_ADAPTER_DELETE:
|
||||
@ -187,7 +182,6 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
/* -1=no data 0=read from user mem, 1=write to user mem */
|
||||
int wrflag = -1;
|
||||
u32 adapter = hm->h.adapter_index;
|
||||
pa = &adapters[adapter];
|
||||
|
||||
if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) {
|
||||
hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER,
|
||||
@ -203,6 +197,8 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
|
||||
goto out;
|
||||
}
|
||||
|
||||
pa = &adapters[adapter];
|
||||
|
||||
if (mutex_lock_interruptible(&adapters[adapter].mutex)) {
|
||||
err = -EINTR;
|
||||
goto out;
|
||||
|
@ -39,10 +39,6 @@ void hpios_delay_micro_seconds(u32 num_micro_sec)
|
||||
|
||||
}
|
||||
|
||||
void hpios_locked_mem_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
/** Allocated an area of locked memory for bus master DMA operations.
|
||||
|
||||
On error, return -ENOMEM, and *pMemArea.size = 0
|
||||
@ -85,7 +81,3 @@ u16 hpios_locked_mem_free(struct consistent_dma_area *p_mem_area)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
void hpios_locked_mem_free_all(void)
|
||||
{
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ HPI Operating System Specific macros for Linux Kernel driver
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/mutex.h>
|
||||
|
||||
#define HPI_NO_OS_FILE_OPS
|
||||
|
||||
|
@ -1624,7 +1624,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card,
|
||||
}
|
||||
|
||||
if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
|
||||
card->shortname, chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_atiixp_free(chip);
|
||||
return -EBUSY;
|
||||
@ -1701,7 +1701,7 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "ATI IXP AC97 controller",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_atiixp_ids,
|
||||
.probe = snd_atiixp_probe,
|
||||
.remove = __devexit_p(snd_atiixp_remove),
|
||||
|
@ -1260,7 +1260,7 @@ static int __devinit snd_atiixp_create(struct snd_card *card,
|
||||
}
|
||||
|
||||
if (request_irq(pci->irq, snd_atiixp_interrupt, IRQF_SHARED,
|
||||
card->shortname, chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_atiixp_free(chip);
|
||||
return -EBUSY;
|
||||
@ -1332,7 +1332,7 @@ static void __devexit snd_atiixp_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "ATI IXP MC97 controller",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_atiixp_ids,
|
||||
.probe = snd_atiixp_probe,
|
||||
.remove = __devexit_p(snd_atiixp_remove),
|
||||
|
@ -196,7 +196,7 @@ snd_vortex_create(struct snd_card *card, struct pci_dev *pci, vortex_t ** rchip)
|
||||
}
|
||||
|
||||
if ((err = request_irq(pci->irq, vortex_interrupt,
|
||||
IRQF_SHARED, CARD_NAME_SHORT,
|
||||
IRQF_SHARED, KBUILD_MODNAME,
|
||||
chip)) != 0) {
|
||||
printk(KERN_ERR "cannot grab irq\n");
|
||||
goto irq_out;
|
||||
@ -375,7 +375,7 @@ static void __devexit snd_vortex_remove(struct pci_dev *pci)
|
||||
|
||||
// pci_driver definition
|
||||
static struct pci_driver driver = {
|
||||
.name = CARD_NAME_SHORT,
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_vortex_ids,
|
||||
.probe = snd_vortex_probe,
|
||||
.remove = __devexit_p(snd_vortex_remove),
|
||||
|
@ -171,7 +171,7 @@ MODULE_DEVICE_TABLE(pci, snd_aw2_ids);
|
||||
|
||||
/* pci_driver definition */
|
||||
static struct pci_driver driver = {
|
||||
.name = "Emagic Audiowerk 2",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_aw2_ids,
|
||||
.probe = snd_aw2_probe,
|
||||
.remove = __devexit_p(snd_aw2_remove),
|
||||
@ -317,7 +317,7 @@ static int __devinit snd_aw2_create(struct snd_card *card,
|
||||
snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt);
|
||||
|
||||
if (request_irq(pci->irq, snd_aw2_saa7146_interrupt,
|
||||
IRQF_SHARED, "Audiowerk2", chip)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, chip)) {
|
||||
printk(KERN_ERR "aw2: Cannot grab irq %d\n", pci->irq);
|
||||
|
||||
iounmap(chip->iobase_virt);
|
||||
|
@ -2559,7 +2559,7 @@ snd_azf3328_create(struct snd_card *card,
|
||||
codec_setup->name = "I2S_OUT";
|
||||
|
||||
if (request_irq(pci->irq, snd_azf3328_interrupt,
|
||||
IRQF_SHARED, card->shortname, chip)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
err = -EBUSY;
|
||||
goto out_err;
|
||||
@ -2860,7 +2860,7 @@ snd_azf3328_resume(struct pci_dev *pci)
|
||||
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "AZF3328",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_azf3328_ids,
|
||||
.probe = snd_azf3328_probe,
|
||||
.remove = __devexit_p(snd_azf3328_remove),
|
||||
|
@ -760,7 +760,7 @@ static int __devinit snd_bt87x_create(struct snd_card *card,
|
||||
snd_bt87x_writel(chip, REG_INT_STAT, MY_INTERRUPTS);
|
||||
|
||||
err = request_irq(pci->irq, snd_bt87x_interrupt, IRQF_SHARED,
|
||||
"Bt87x audio", chip);
|
||||
KBUILD_MODNAME, chip);
|
||||
if (err < 0) {
|
||||
snd_printk(KERN_ERR "cannot grab irq %d\n", pci->irq);
|
||||
goto fail;
|
||||
@ -965,7 +965,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_bt87x_default_ids) = {
|
||||
};
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "Bt87x",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_bt87x_ids,
|
||||
.probe = snd_bt87x_probe,
|
||||
.remove = __devexit_p(snd_bt87x_remove),
|
||||
|
@ -1666,7 +1666,7 @@ static int __devinit snd_ca0106_create(int dev, struct snd_card *card,
|
||||
}
|
||||
|
||||
if (request_irq(pci->irq, snd_ca0106_interrupt,
|
||||
IRQF_SHARED, "snd_ca0106", chip)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, chip)) {
|
||||
snd_ca0106_free(chip);
|
||||
printk(KERN_ERR "cannot grab irq\n");
|
||||
return -EBUSY;
|
||||
@ -1933,7 +1933,7 @@ MODULE_DEVICE_TABLE(pci, snd_ca0106_ids);
|
||||
|
||||
// pci_driver definition
|
||||
static struct pci_driver driver = {
|
||||
.name = "CA0106",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_ca0106_ids,
|
||||
.probe = snd_ca0106_probe,
|
||||
.remove = __devexit_p(snd_ca0106_remove),
|
||||
|
@ -3053,7 +3053,7 @@ static int __devinit snd_cmipci_create(struct snd_card *card, struct pci_dev *pc
|
||||
cm->iobase = pci_resource_start(pci, 0);
|
||||
|
||||
if (request_irq(pci->irq, snd_cmipci_interrupt,
|
||||
IRQF_SHARED, card->driver, cm)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, cm)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_cmipci_free(cm);
|
||||
return -EBUSY;
|
||||
@ -3398,7 +3398,7 @@ static int snd_cmipci_resume(struct pci_dev *pci)
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "C-Media PCI",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_cmipci_ids,
|
||||
.probe = snd_cmipci_probe,
|
||||
.remove = __devexit_p(snd_cmipci_remove),
|
||||
|
@ -1382,7 +1382,7 @@ static int __devinit snd_cs4281_create(struct snd_card *card,
|
||||
}
|
||||
|
||||
if (request_irq(pci->irq, snd_cs4281_interrupt, IRQF_SHARED,
|
||||
"CS4281", chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_cs4281_free(chip);
|
||||
return -ENOMEM;
|
||||
@ -2085,7 +2085,7 @@ static int cs4281_resume(struct pci_dev *pci)
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "CS4281",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_cs4281_ids,
|
||||
.probe = snd_cs4281_probe,
|
||||
.remove = __devexit_p(snd_cs4281_remove),
|
||||
|
@ -162,7 +162,7 @@ static void __devexit snd_card_cs46xx_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "Sound Fusion CS46xx",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_cs46xx_ids,
|
||||
.probe = snd_card_cs46xx_probe,
|
||||
.remove = __devexit_p(snd_card_cs46xx_remove),
|
||||
|
@ -3835,7 +3835,7 @@ int __devinit snd_cs46xx_create(struct snd_card *card,
|
||||
}
|
||||
|
||||
if (request_irq(pci->irq, snd_cs46xx_interrupt, IRQF_SHARED,
|
||||
"CS46XX", chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_cs46xx_free(chip);
|
||||
return -EBUSY;
|
||||
|
@ -285,7 +285,7 @@ static int __devinit snd_cs5530_probe(struct pci_dev *pci,
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "CS5530_Audio",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_cs5530_ids,
|
||||
.probe = snd_cs5530_probe,
|
||||
.remove = __devexit_p(snd_cs5530_remove),
|
||||
|
@ -311,7 +311,7 @@ static int __devinit snd_cs5535audio_create(struct snd_card *card,
|
||||
cs5535au->port = pci_resource_start(pci, 0);
|
||||
|
||||
if (request_irq(pci->irq, snd_cs5535audio_interrupt,
|
||||
IRQF_SHARED, "CS5535 Audio", cs5535au)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, cs5535au)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
err = -EBUSY;
|
||||
goto sndfail;
|
||||
@ -395,7 +395,7 @@ static void __devexit snd_cs5535audio_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_cs5535audio_ids,
|
||||
.probe = snd_cs5535audio_probe,
|
||||
.remove = __devexit_p(snd_cs5535audio_remove),
|
||||
|
@ -55,6 +55,7 @@
|
||||
/* GPIO Registers */
|
||||
#define GPIO_DATA 0x1B7020
|
||||
#define GPIO_CTRL 0x1B7024
|
||||
#define GPIO_EXT_DATA 0x1B70A0
|
||||
|
||||
/* Virtual memory registers */
|
||||
#define VMEM_PTPAL 0x1C6300 /* 0x1C6300 + (16 * Chn) */
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "ctatc.h"
|
||||
#include "ctpcm.h"
|
||||
#include "ctmixer.h"
|
||||
#include "cthardware.h"
|
||||
#include "ctsrc.h"
|
||||
#include "ctamixer.h"
|
||||
#include "ctdaio.h"
|
||||
@ -30,7 +29,6 @@
|
||||
#include <sound/asoundef.h>
|
||||
|
||||
#define MONO_SUM_SCALE 0x19a8 /* 2^(-0.5) in 14-bit floating format */
|
||||
#define DAIONUM 7
|
||||
#define MAX_MULTI_CHN 8
|
||||
|
||||
#define IEC958_DEFAULT_CON ((IEC958_AES0_NONAUDIO \
|
||||
@ -53,6 +51,8 @@ static struct snd_pci_quirk __devinitdata subsys_20k1_list[] = {
|
||||
static struct snd_pci_quirk __devinitdata subsys_20k2_list[] = {
|
||||
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB0760,
|
||||
"SB0760", CTSB0760),
|
||||
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB1270,
|
||||
"SB1270", CTSB1270),
|
||||
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08801,
|
||||
"SB0880", CTSB0880),
|
||||
SND_PCI_QUIRK(PCI_VENDOR_ID_CREATIVE, PCI_SUBDEVICE_ID_CREATIVE_SB08802,
|
||||
@ -75,6 +75,7 @@ static const char *ct_subsys_name[NUM_CTCARDS] = {
|
||||
[CTSB0760] = "SB076x",
|
||||
[CTHENDRIX] = "Hendrix",
|
||||
[CTSB0880] = "SB0880",
|
||||
[CTSB1270] = "SB1270",
|
||||
[CT20K2_UNKNOWN] = "Unknown",
|
||||
};
|
||||
|
||||
@ -459,12 +460,12 @@ static void setup_src_node_conf(struct ct_atc *atc, struct ct_atc_pcm *apcm,
|
||||
apcm->substream->runtime->rate);
|
||||
*n_srcc = 0;
|
||||
|
||||
if (1 == atc->msr) {
|
||||
if (1 == atc->msr) { /* FIXME: do we really need SRC here if pitch==1 */
|
||||
*n_srcc = apcm->substream->runtime->channels;
|
||||
conf[0].pitch = pitch;
|
||||
conf[0].mix_msr = conf[0].imp_msr = conf[0].msr = 1;
|
||||
conf[0].vo = 1;
|
||||
} else if (2 == atc->msr) {
|
||||
} else if (2 <= atc->msr) {
|
||||
if (0x8000000 < pitch) {
|
||||
/* Need two-stage SRCs, SRCIMPs and
|
||||
* AMIXERs for converting format */
|
||||
@ -970,11 +971,39 @@ static int atc_select_mic_in(struct ct_atc *atc)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int atc_have_digit_io_switch(struct ct_atc *atc)
|
||||
static struct capabilities atc_capabilities(struct ct_atc *atc)
|
||||
{
|
||||
struct hw *hw = atc->hw;
|
||||
|
||||
return hw->have_digit_io_switch(hw);
|
||||
return hw->capabilities(hw);
|
||||
}
|
||||
|
||||
static int atc_output_switch_get(struct ct_atc *atc)
|
||||
{
|
||||
struct hw *hw = atc->hw;
|
||||
|
||||
return hw->output_switch_get(hw);
|
||||
}
|
||||
|
||||
static int atc_output_switch_put(struct ct_atc *atc, int position)
|
||||
{
|
||||
struct hw *hw = atc->hw;
|
||||
|
||||
return hw->output_switch_put(hw, position);
|
||||
}
|
||||
|
||||
static int atc_mic_source_switch_get(struct ct_atc *atc)
|
||||
{
|
||||
struct hw *hw = atc->hw;
|
||||
|
||||
return hw->mic_source_switch_get(hw);
|
||||
}
|
||||
|
||||
static int atc_mic_source_switch_put(struct ct_atc *atc, int position)
|
||||
{
|
||||
struct hw *hw = atc->hw;
|
||||
|
||||
return hw->mic_source_switch_put(hw, position);
|
||||
}
|
||||
|
||||
static int atc_select_digit_io(struct ct_atc *atc)
|
||||
@ -1045,6 +1074,11 @@ static int atc_line_in_unmute(struct ct_atc *atc, unsigned char state)
|
||||
return atc_daio_unmute(atc, state, LINEIM);
|
||||
}
|
||||
|
||||
static int atc_mic_unmute(struct ct_atc *atc, unsigned char state)
|
||||
{
|
||||
return atc_daio_unmute(atc, state, MIC);
|
||||
}
|
||||
|
||||
static int atc_spdif_out_unmute(struct ct_atc *atc, unsigned char state)
|
||||
{
|
||||
return atc_daio_unmute(atc, state, SPDIFOO);
|
||||
@ -1331,17 +1365,20 @@ static int atc_get_resources(struct ct_atc *atc)
|
||||
struct srcimp_mgr *srcimp_mgr;
|
||||
struct sum_desc sum_dsc = {0};
|
||||
struct sum_mgr *sum_mgr;
|
||||
int err, i;
|
||||
int err, i, num_srcs, num_daios;
|
||||
|
||||
atc->daios = kzalloc(sizeof(void *)*(DAIONUM), GFP_KERNEL);
|
||||
num_daios = ((atc->model == CTSB1270) ? 8 : 7);
|
||||
num_srcs = ((atc->model == CTSB1270) ? 6 : 4);
|
||||
|
||||
atc->daios = kzalloc(sizeof(void *)*num_daios, GFP_KERNEL);
|
||||
if (!atc->daios)
|
||||
return -ENOMEM;
|
||||
|
||||
atc->srcs = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
|
||||
atc->srcs = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL);
|
||||
if (!atc->srcs)
|
||||
return -ENOMEM;
|
||||
|
||||
atc->srcimps = kzalloc(sizeof(void *)*(2*2), GFP_KERNEL);
|
||||
atc->srcimps = kzalloc(sizeof(void *)*num_srcs, GFP_KERNEL);
|
||||
if (!atc->srcimps)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1351,8 +1388,9 @@ static int atc_get_resources(struct ct_atc *atc)
|
||||
|
||||
daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO];
|
||||
da_desc.msr = atc->msr;
|
||||
for (i = 0, atc->n_daio = 0; i < DAIONUM-1; i++) {
|
||||
da_desc.type = i;
|
||||
for (i = 0, atc->n_daio = 0; i < num_daios; i++) {
|
||||
da_desc.type = (atc->model != CTSB073X) ? i :
|
||||
((i == SPDIFIO) ? SPDIFI1 : i);
|
||||
err = daio_mgr->get_daio(daio_mgr, &da_desc,
|
||||
(struct daio **)&atc->daios[i]);
|
||||
if (err) {
|
||||
@ -1362,23 +1400,12 @@ static int atc_get_resources(struct ct_atc *atc)
|
||||
}
|
||||
atc->n_daio++;
|
||||
}
|
||||
if (atc->model == CTSB073X)
|
||||
da_desc.type = SPDIFI1;
|
||||
else
|
||||
da_desc.type = SPDIFIO;
|
||||
err = daio_mgr->get_daio(daio_mgr, &da_desc,
|
||||
(struct daio **)&atc->daios[i]);
|
||||
if (err) {
|
||||
printk(KERN_ERR "ctxfi: Failed to get S/PDIF-in resource!!!\n");
|
||||
return err;
|
||||
}
|
||||
atc->n_daio++;
|
||||
|
||||
src_mgr = atc->rsc_mgrs[SRC];
|
||||
src_dsc.multi = 1;
|
||||
src_dsc.msr = atc->msr;
|
||||
src_dsc.mode = ARCRW;
|
||||
for (i = 0, atc->n_src = 0; i < (2*2); i++) {
|
||||
for (i = 0, atc->n_src = 0; i < num_srcs; i++) {
|
||||
err = src_mgr->get_src(src_mgr, &src_dsc,
|
||||
(struct src **)&atc->srcs[i]);
|
||||
if (err)
|
||||
@ -1388,8 +1415,8 @@ static int atc_get_resources(struct ct_atc *atc)
|
||||
}
|
||||
|
||||
srcimp_mgr = atc->rsc_mgrs[SRCIMP];
|
||||
srcimp_dsc.msr = 8; /* SRCIMPs for S/PDIFIn SRT */
|
||||
for (i = 0, atc->n_srcimp = 0; i < (2*1); i++) {
|
||||
srcimp_dsc.msr = 8;
|
||||
for (i = 0, atc->n_srcimp = 0; i < num_srcs; i++) {
|
||||
err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
|
||||
(struct srcimp **)&atc->srcimps[i]);
|
||||
if (err)
|
||||
@ -1397,15 +1424,6 @@ static int atc_get_resources(struct ct_atc *atc)
|
||||
|
||||
atc->n_srcimp++;
|
||||
}
|
||||
srcimp_dsc.msr = 8; /* SRCIMPs for LINE/MICIn SRT */
|
||||
for (i = 0; i < (2*1); i++) {
|
||||
err = srcimp_mgr->get_srcimp(srcimp_mgr, &srcimp_dsc,
|
||||
(struct srcimp **)&atc->srcimps[2*1+i]);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
atc->n_srcimp++;
|
||||
}
|
||||
|
||||
sum_mgr = atc->rsc_mgrs[SUM];
|
||||
sum_dsc.msr = atc->msr;
|
||||
@ -1488,6 +1506,18 @@ static void atc_connect_resources(struct ct_atc *atc)
|
||||
src = atc->srcs[3];
|
||||
mixer->set_input_right(mixer, MIX_LINE_IN, &src->rsc);
|
||||
|
||||
if (atc->model == CTSB1270) {
|
||||
/* Titanium HD has a dedicated ADC for the Mic. */
|
||||
dai = container_of(atc->daios[MIC], struct dai, daio);
|
||||
atc_connect_dai(atc->rsc_mgrs[SRC], dai,
|
||||
(struct src **)&atc->srcs[4],
|
||||
(struct srcimp **)&atc->srcimps[4]);
|
||||
src = atc->srcs[4];
|
||||
mixer->set_input_left(mixer, MIX_MIC_IN, &src->rsc);
|
||||
src = atc->srcs[5];
|
||||
mixer->set_input_right(mixer, MIX_MIC_IN, &src->rsc);
|
||||
}
|
||||
|
||||
dai = container_of(atc->daios[SPDIFIO], struct dai, daio);
|
||||
atc_connect_dai(atc->rsc_mgrs[SRC], dai,
|
||||
(struct src **)&atc->srcs[0],
|
||||
@ -1606,12 +1636,17 @@ static struct ct_atc atc_preset __devinitdata = {
|
||||
.line_clfe_unmute = atc_line_clfe_unmute,
|
||||
.line_rear_unmute = atc_line_rear_unmute,
|
||||
.line_in_unmute = atc_line_in_unmute,
|
||||
.mic_unmute = atc_mic_unmute,
|
||||
.spdif_out_unmute = atc_spdif_out_unmute,
|
||||
.spdif_in_unmute = atc_spdif_in_unmute,
|
||||
.spdif_out_get_status = atc_spdif_out_get_status,
|
||||
.spdif_out_set_status = atc_spdif_out_set_status,
|
||||
.spdif_out_passthru = atc_spdif_out_passthru,
|
||||
.have_digit_io_switch = atc_have_digit_io_switch,
|
||||
.capabilities = atc_capabilities,
|
||||
.output_switch_get = atc_output_switch_get,
|
||||
.output_switch_put = atc_output_switch_put,
|
||||
.mic_source_switch_get = atc_mic_source_switch_get,
|
||||
.mic_source_switch_put = atc_mic_source_switch_put,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = atc_suspend,
|
||||
.resume = atc_resume,
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <sound/core.h>
|
||||
|
||||
#include "ctvmem.h"
|
||||
#include "cthardware.h"
|
||||
#include "ctresource.h"
|
||||
|
||||
enum CTALSADEVS { /* Types of alsa devices */
|
||||
@ -115,12 +116,17 @@ struct ct_atc {
|
||||
int (*line_clfe_unmute)(struct ct_atc *atc, unsigned char state);
|
||||
int (*line_rear_unmute)(struct ct_atc *atc, unsigned char state);
|
||||
int (*line_in_unmute)(struct ct_atc *atc, unsigned char state);
|
||||
int (*mic_unmute)(struct ct_atc *atc, unsigned char state);
|
||||
int (*spdif_out_unmute)(struct ct_atc *atc, unsigned char state);
|
||||
int (*spdif_in_unmute)(struct ct_atc *atc, unsigned char state);
|
||||
int (*spdif_out_get_status)(struct ct_atc *atc, unsigned int *status);
|
||||
int (*spdif_out_set_status)(struct ct_atc *atc, unsigned int status);
|
||||
int (*spdif_out_passthru)(struct ct_atc *atc, unsigned char state);
|
||||
int (*have_digit_io_switch)(struct ct_atc *atc);
|
||||
struct capabilities (*capabilities)(struct ct_atc *atc);
|
||||
int (*output_switch_get)(struct ct_atc *atc);
|
||||
int (*output_switch_put)(struct ct_atc *atc, int position);
|
||||
int (*mic_source_switch_get)(struct ct_atc *atc);
|
||||
int (*mic_source_switch_put)(struct ct_atc *atc, int position);
|
||||
|
||||
/* Don't touch! Used for internal object. */
|
||||
void *rsc_mgrs[NUM_RSCTYP]; /* chip resource managers */
|
||||
|
@ -22,20 +22,9 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#define DAIO_RESOURCE_NUM NUM_DAIOTYP
|
||||
#define DAIO_OUT_MAX SPDIFOO
|
||||
|
||||
union daio_usage {
|
||||
struct {
|
||||
unsigned short lineo1:1;
|
||||
unsigned short lineo2:1;
|
||||
unsigned short lineo3:1;
|
||||
unsigned short lineo4:1;
|
||||
unsigned short spdifoo:1;
|
||||
unsigned short lineim:1;
|
||||
unsigned short spdifio:1;
|
||||
unsigned short spdifi1:1;
|
||||
} bf;
|
||||
struct daio_usage {
|
||||
unsigned short data;
|
||||
};
|
||||
|
||||
@ -61,6 +50,7 @@ struct daio_rsc_idx idx_20k2[NUM_DAIOTYP] = {
|
||||
[LINEO3] = {.left = 0x50, .right = 0x51},
|
||||
[LINEO4] = {.left = 0x70, .right = 0x71},
|
||||
[LINEIM] = {.left = 0x45, .right = 0xc5},
|
||||
[MIC] = {.left = 0x55, .right = 0xd5},
|
||||
[SPDIFOO] = {.left = 0x00, .right = 0x01},
|
||||
[SPDIFIO] = {.left = 0x05, .right = 0x85},
|
||||
};
|
||||
@ -138,6 +128,7 @@ static unsigned int daio_device_index(enum DAIOTYP type, struct hw *hw)
|
||||
case LINEO3: return 5;
|
||||
case LINEO4: return 6;
|
||||
case LINEIM: return 4;
|
||||
case MIC: return 5;
|
||||
default: return -EINVAL;
|
||||
}
|
||||
default:
|
||||
@ -519,17 +510,17 @@ static int dai_rsc_uninit(struct dai *dai)
|
||||
|
||||
static int daio_mgr_get_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
|
||||
{
|
||||
if (((union daio_usage *)mgr->rscs)->data & (0x1 << type))
|
||||
if (((struct daio_usage *)mgr->rscs)->data & (0x1 << type))
|
||||
return -ENOENT;
|
||||
|
||||
((union daio_usage *)mgr->rscs)->data |= (0x1 << type);
|
||||
((struct daio_usage *)mgr->rscs)->data |= (0x1 << type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int daio_mgr_put_rsc(struct rsc_mgr *mgr, enum DAIOTYP type)
|
||||
{
|
||||
((union daio_usage *)mgr->rscs)->data &= ~(0x1 << type);
|
||||
((struct daio_usage *)mgr->rscs)->data &= ~(0x1 << type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -712,7 +703,7 @@ int daio_mgr_create(void *hw, struct daio_mgr **rdaio_mgr)
|
||||
if (!daio_mgr)
|
||||
return -ENOMEM;
|
||||
|
||||
err = rsc_mgr_init(&daio_mgr->mgr, DAIO, DAIO_RESOURCE_NUM, hw);
|
||||
err = rsc_mgr_init(&daio_mgr->mgr, DAIO, NUM_DAIOTYP, hw);
|
||||
if (err)
|
||||
goto error1;
|
||||
|
||||
|
@ -33,6 +33,7 @@ enum DAIOTYP {
|
||||
SPDIFOO, /* S/PDIF Out (Flexijack/Optical) */
|
||||
LINEIM,
|
||||
SPDIFIO, /* S/PDIF In (Flexijack/Optical) on the card */
|
||||
MIC, /* Dedicated mic on Titanium HD */
|
||||
SPDIFI1, /* S/PDIF In on internal Drive Bay */
|
||||
NUM_DAIOTYP
|
||||
};
|
||||
|
@ -39,6 +39,7 @@ enum CTCARDS {
|
||||
CT20K2_MODEL_FIRST = CTSB0760,
|
||||
CTHENDRIX,
|
||||
CTSB0880,
|
||||
CTSB1270,
|
||||
CT20K2_UNKNOWN,
|
||||
NUM_CTCARDS /* This should always be the last */
|
||||
};
|
||||
@ -60,6 +61,13 @@ struct card_conf {
|
||||
unsigned int msr; /* master sample rate in rsrs */
|
||||
};
|
||||
|
||||
struct capabilities {
|
||||
unsigned int digit_io_switch:1;
|
||||
unsigned int dedicated_mic:1;
|
||||
unsigned int output_switch:1;
|
||||
unsigned int mic_source_switch:1;
|
||||
};
|
||||
|
||||
struct hw {
|
||||
int (*card_init)(struct hw *hw, struct card_conf *info);
|
||||
int (*card_stop)(struct hw *hw);
|
||||
@ -70,7 +78,11 @@ struct hw {
|
||||
#endif
|
||||
int (*is_adc_source_selected)(struct hw *hw, enum ADCSRC source);
|
||||
int (*select_adc_source)(struct hw *hw, enum ADCSRC source);
|
||||
int (*have_digit_io_switch)(struct hw *hw);
|
||||
struct capabilities (*capabilities)(struct hw *hw);
|
||||
int (*output_switch_get)(struct hw *hw);
|
||||
int (*output_switch_put)(struct hw *hw, int position);
|
||||
int (*mic_source_switch_get)(struct hw *hw);
|
||||
int (*mic_source_switch_put)(struct hw *hw, int position);
|
||||
|
||||
/* SRC operations */
|
||||
int (*src_rsc_get_ctrl_blk)(void **rblk);
|
||||
|
@ -1777,10 +1777,17 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
|
||||
return adc_init_SBx(hw, info->input, info->mic20db);
|
||||
}
|
||||
|
||||
static int hw_have_digit_io_switch(struct hw *hw)
|
||||
static struct capabilities hw_capabilities(struct hw *hw)
|
||||
{
|
||||
struct capabilities cap;
|
||||
|
||||
/* SB073x and Vista compatible cards have no digit IO switch */
|
||||
return !(hw->model == CTSB073X || hw->model == CTUAA);
|
||||
cap.digit_io_switch = !(hw->model == CTSB073X || hw->model == CTUAA);
|
||||
cap.dedicated_mic = 0;
|
||||
cap.output_switch = 0;
|
||||
cap.mic_source_switch = 0;
|
||||
|
||||
return cap;
|
||||
}
|
||||
|
||||
#define CTLBITS(a, b, c, d) (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
|
||||
@ -1933,7 +1940,7 @@ static int hw_card_start(struct hw *hw)
|
||||
|
||||
if (hw->irq < 0) {
|
||||
err = request_irq(pci->irq, ct_20k1_interrupt, IRQF_SHARED,
|
||||
"ctxfi", hw);
|
||||
KBUILD_MODNAME, hw);
|
||||
if (err < 0) {
|
||||
printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
|
||||
goto error2;
|
||||
@ -2172,7 +2179,7 @@ static struct hw ct20k1_preset __devinitdata = {
|
||||
.pll_init = hw_pll_init,
|
||||
.is_adc_source_selected = hw_is_adc_input_selected,
|
||||
.select_adc_source = hw_adc_input_select,
|
||||
.have_digit_io_switch = hw_have_digit_io_switch,
|
||||
.capabilities = hw_capabilities,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = hw_suspend,
|
||||
.resume = hw_resume,
|
||||
|
@ -8,7 +8,7 @@
|
||||
* @File cthw20k2.c
|
||||
*
|
||||
* @Brief
|
||||
* This file contains the implementation of hardware access methord for 20k2.
|
||||
* This file contains the implementation of hardware access method for 20k2.
|
||||
*
|
||||
* @Author Liu Chun
|
||||
* @Date May 14 2008
|
||||
@ -38,6 +38,8 @@ struct hw20k2 {
|
||||
unsigned char dev_id;
|
||||
unsigned char addr_size;
|
||||
unsigned char data_size;
|
||||
|
||||
int mic_source;
|
||||
};
|
||||
|
||||
static u32 hw_read_20kx(struct hw *hw, u32 reg);
|
||||
@ -1163,7 +1165,12 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
|
||||
hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x01010101);
|
||||
hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
|
||||
} else if (2 == info->msr) {
|
||||
hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11111111);
|
||||
if (hw->model != CTSB1270) {
|
||||
hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11111111);
|
||||
} else {
|
||||
/* PCM4220 on Titanium HD is different. */
|
||||
hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11011111);
|
||||
}
|
||||
/* Specify all playing 96khz
|
||||
* EA [0] - Enabled
|
||||
* RTA [4:5] - 96kHz
|
||||
@ -1175,6 +1182,10 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
|
||||
* RTD [28:29] - 96kHz */
|
||||
hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x11111111);
|
||||
hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
|
||||
} else if ((4 == info->msr) && (hw->model == CTSB1270)) {
|
||||
hw_write_20kx(hw, AUDIO_IO_MCLK, 0x21011111);
|
||||
hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x21212121);
|
||||
hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
|
||||
} else {
|
||||
printk(KERN_ALERT "ctxfi: ERROR!!! Invalid sampling rate!!!\n");
|
||||
return -EINVAL;
|
||||
@ -1182,6 +1193,8 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (i <= 3) {
|
||||
/* This comment looks wrong since loop is over 4 */
|
||||
/* channels and emu20k2 supports 4 spdif IOs. */
|
||||
/* 1st 3 channels are SPDIFs (SB0960) */
|
||||
if (i == 3)
|
||||
data = 0x1001001;
|
||||
@ -1206,12 +1219,16 @@ static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
|
||||
|
||||
hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_H+(0x40*i), 0x0B);
|
||||
} else {
|
||||
/* Again, loop is over 4 channels not 5. */
|
||||
/* Next 5 channels are I2S (SB0960) */
|
||||
data = 0x11;
|
||||
hw_write_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i), data);
|
||||
if (2 == info->msr) {
|
||||
/* Four channels per sample period */
|
||||
data |= 0x1000;
|
||||
} else if (4 == info->msr) {
|
||||
/* FIXME: check this against the chip spec */
|
||||
data |= 0x2000;
|
||||
}
|
||||
hw_write_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i), data);
|
||||
}
|
||||
@ -1299,21 +1316,18 @@ static int hw_pll_init(struct hw *hw, unsigned int rsr)
|
||||
|
||||
pllenb = 0xB;
|
||||
hw_write_20kx(hw, PLL_ENB, pllenb);
|
||||
pllctl = 0x20D00000;
|
||||
set_field(&pllctl, PLLCTL_FD, 16 - 4);
|
||||
hw_write_20kx(hw, PLL_CTL, pllctl);
|
||||
mdelay(40);
|
||||
pllctl = hw_read_20kx(hw, PLL_CTL);
|
||||
pllctl = 0x20C00000;
|
||||
set_field(&pllctl, PLLCTL_B, 0);
|
||||
if (48000 == rsr) {
|
||||
set_field(&pllctl, PLLCTL_FD, 16 - 2);
|
||||
set_field(&pllctl, PLLCTL_RD, 1 - 1); /* 3000*16/1 = 48000 */
|
||||
} else { /* 44100 */
|
||||
set_field(&pllctl, PLLCTL_FD, 147 - 2);
|
||||
set_field(&pllctl, PLLCTL_RD, 10 - 1); /* 3000*147/10 = 44100 */
|
||||
}
|
||||
set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 4 : 147 - 4);
|
||||
set_field(&pllctl, PLLCTL_RD, 48000 == rsr ? 1 - 1 : 10 - 1);
|
||||
hw_write_20kx(hw, PLL_CTL, pllctl);
|
||||
mdelay(40);
|
||||
|
||||
pllctl = hw_read_20kx(hw, PLL_CTL);
|
||||
set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 2 : 147 - 2);
|
||||
hw_write_20kx(hw, PLL_CTL, pllctl);
|
||||
mdelay(40);
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
pllstat = hw_read_20kx(hw, PLL_STAT);
|
||||
if (get_field(pllstat, PLLSTAT_PD))
|
||||
@ -1557,7 +1571,7 @@ static int hw20k2_i2c_write(struct hw *hw, u16 addr, u32 data)
|
||||
|
||||
hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
|
||||
hw20k2_i2c_wait_data_ready(hw);
|
||||
/* Dummy write to trigger the write oprtation */
|
||||
/* Dummy write to trigger the write operation */
|
||||
hw_write_20kx(hw, I2C_IF_WDATA, 0);
|
||||
hw20k2_i2c_wait_data_ready(hw);
|
||||
|
||||
@ -1568,6 +1582,30 @@ static int hw20k2_i2c_write(struct hw *hw, u16 addr, u32 data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hw_dac_stop(struct hw *hw)
|
||||
{
|
||||
u32 data;
|
||||
data = hw_read_20kx(hw, GPIO_DATA);
|
||||
data &= 0xFFFFFFFD;
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
mdelay(10);
|
||||
}
|
||||
|
||||
static void hw_dac_start(struct hw *hw)
|
||||
{
|
||||
u32 data;
|
||||
data = hw_read_20kx(hw, GPIO_DATA);
|
||||
data |= 0x2;
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
mdelay(50);
|
||||
}
|
||||
|
||||
static void hw_dac_reset(struct hw *hw)
|
||||
{
|
||||
hw_dac_stop(hw);
|
||||
hw_dac_start(hw);
|
||||
}
|
||||
|
||||
static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
|
||||
{
|
||||
int err;
|
||||
@ -1594,6 +1632,21 @@ static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
|
||||
0x00000000 /* Vol Control B4 */
|
||||
};
|
||||
|
||||
if (hw->model == CTSB1270) {
|
||||
hw_dac_stop(hw);
|
||||
data = hw_read_20kx(hw, GPIO_DATA);
|
||||
data &= ~0x0600;
|
||||
if (1 == info->msr)
|
||||
data |= 0x0000; /* Single Speed Mode 0-50kHz */
|
||||
else if (2 == info->msr)
|
||||
data |= 0x0200; /* Double Speed Mode 50-100kHz */
|
||||
else
|
||||
data |= 0x0600; /* Quad Speed Mode 100-200kHz */
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
hw_dac_start(hw);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set DAC reset bit as output */
|
||||
data = hw_read_20kx(hw, GPIO_CTRL);
|
||||
data |= 0x02;
|
||||
@ -1606,22 +1659,8 @@ static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
|
||||
for (i = 0; i < 2; i++) {
|
||||
/* Reset DAC twice just in-case the chip
|
||||
* didn't initialized properly */
|
||||
data = hw_read_20kx(hw, GPIO_DATA);
|
||||
/* GPIO data bit 1 */
|
||||
data &= 0xFFFFFFFD;
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
mdelay(10);
|
||||
data |= 0x2;
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
mdelay(50);
|
||||
|
||||
/* Reset the 2nd time */
|
||||
data &= 0xFFFFFFFD;
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
mdelay(10);
|
||||
data |= 0x2;
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
mdelay(50);
|
||||
hw_dac_reset(hw);
|
||||
hw_dac_reset(hw);
|
||||
|
||||
if (hw20k2_i2c_read(hw, CS4382_MC1, &cs_read.mode_control_1))
|
||||
continue;
|
||||
@ -1725,7 +1764,11 @@ End:
|
||||
static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
|
||||
{
|
||||
u32 data;
|
||||
|
||||
if (hw->model == CTSB1270) {
|
||||
/* Titanium HD has two ADC chips, one for line in and one */
|
||||
/* for MIC. We don't need to switch the ADC input. */
|
||||
return 1;
|
||||
}
|
||||
data = hw_read_20kx(hw, GPIO_DATA);
|
||||
switch (type) {
|
||||
case ADC_MICIN:
|
||||
@ -1742,35 +1785,47 @@ static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
|
||||
|
||||
#define MIC_BOOST_0DB 0xCF
|
||||
#define MIC_BOOST_STEPS_PER_DB 2
|
||||
#define MIC_BOOST_20DB (MIC_BOOST_0DB + 20 * MIC_BOOST_STEPS_PER_DB)
|
||||
|
||||
static void hw_wm8775_input_select(struct hw *hw, u8 input, s8 gain_in_db)
|
||||
{
|
||||
u32 adcmc, gain;
|
||||
|
||||
if (input > 3)
|
||||
input = 3;
|
||||
|
||||
adcmc = ((u32)1 << input) | 0x100; /* Link L+R gain... */
|
||||
|
||||
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, adcmc),
|
||||
MAKE_WM8775_DATA(adcmc));
|
||||
|
||||
if (gain_in_db < -103)
|
||||
gain_in_db = -103;
|
||||
if (gain_in_db > 24)
|
||||
gain_in_db = 24;
|
||||
|
||||
gain = gain_in_db * MIC_BOOST_STEPS_PER_DB + MIC_BOOST_0DB;
|
||||
|
||||
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, gain),
|
||||
MAKE_WM8775_DATA(gain));
|
||||
/* ...so there should be no need for the following. */
|
||||
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, gain),
|
||||
MAKE_WM8775_DATA(gain));
|
||||
}
|
||||
|
||||
static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
|
||||
{
|
||||
u32 data;
|
||||
|
||||
data = hw_read_20kx(hw, GPIO_DATA);
|
||||
switch (type) {
|
||||
case ADC_MICIN:
|
||||
data |= (0x1 << 14);
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101),
|
||||
MAKE_WM8775_DATA(0x101)); /* Mic-in */
|
||||
hw20k2_i2c_write(hw,
|
||||
MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB),
|
||||
MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
|
||||
hw20k2_i2c_write(hw,
|
||||
MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB),
|
||||
MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
|
||||
hw_wm8775_input_select(hw, 0, 20); /* Mic, 20dB */
|
||||
break;
|
||||
case ADC_LINEIN:
|
||||
data &= ~(0x1 << 14);
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x102),
|
||||
MAKE_WM8775_DATA(0x102)); /* Line-in */
|
||||
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xCF),
|
||||
MAKE_WM8775_DATA(0xCF)); /* No boost */
|
||||
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xCF),
|
||||
MAKE_WM8775_DATA(0xCF)); /* No boost */
|
||||
hw_wm8775_input_select(hw, 1, 0); /* Line-in, 0dB */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -1782,7 +1837,7 @@ static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
|
||||
static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
|
||||
{
|
||||
int err;
|
||||
u32 mux = 2, data, ctl;
|
||||
u32 data, ctl;
|
||||
|
||||
/* Set ADC reset bit as output */
|
||||
data = hw_read_20kx(hw, GPIO_CTRL);
|
||||
@ -1796,19 +1851,42 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Make ADC in normal operation */
|
||||
/* Reset the ADC (reset is active low). */
|
||||
data = hw_read_20kx(hw, GPIO_DATA);
|
||||
data &= ~(0x1 << 15);
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
|
||||
if (hw->model == CTSB1270) {
|
||||
/* Set up the PCM4220 ADC on Titanium HD */
|
||||
data &= ~0x0C;
|
||||
if (1 == info->msr)
|
||||
data |= 0x00; /* Single Speed Mode 32-50kHz */
|
||||
else if (2 == info->msr)
|
||||
data |= 0x08; /* Double Speed Mode 50-108kHz */
|
||||
else
|
||||
data |= 0x04; /* Quad Speed Mode 108kHz-216kHz */
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
}
|
||||
|
||||
mdelay(10);
|
||||
/* Return the ADC to normal operation. */
|
||||
data |= (0x1 << 15);
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
mdelay(50);
|
||||
|
||||
/* I2C write to register offset 0x0B to set ADC LRCLK polarity */
|
||||
/* invert bit, interface format to I2S, word length to 24-bit, */
|
||||
/* enable ADC high pass filter. Fixes bug 5323? */
|
||||
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_IC, 0x26),
|
||||
MAKE_WM8775_DATA(0x26));
|
||||
|
||||
/* Set the master mode (256fs) */
|
||||
if (1 == info->msr) {
|
||||
/* slave mode, 128x oversampling 256fs */
|
||||
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x02),
|
||||
MAKE_WM8775_DATA(0x02));
|
||||
} else if (2 == info->msr) {
|
||||
} else if ((2 == info->msr) || (4 == info->msr)) {
|
||||
/* slave mode, 64x oversampling, 256fs */
|
||||
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x0A),
|
||||
MAKE_WM8775_DATA(0x0A));
|
||||
} else {
|
||||
@ -1818,55 +1896,113 @@ static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Configure GPIO bit 14 change to line-in/mic-in */
|
||||
ctl = hw_read_20kx(hw, GPIO_CTRL);
|
||||
ctl |= 0x1 << 14;
|
||||
hw_write_20kx(hw, GPIO_CTRL, ctl);
|
||||
|
||||
/* Check using Mic-in or Line-in */
|
||||
data = hw_read_20kx(hw, GPIO_DATA);
|
||||
|
||||
if (mux == 1) {
|
||||
/* Configures GPIO data to select Mic-in */
|
||||
data |= 0x1 << 14;
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
|
||||
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101),
|
||||
MAKE_WM8775_DATA(0x101)); /* Mic-in */
|
||||
hw20k2_i2c_write(hw,
|
||||
MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB),
|
||||
MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
|
||||
hw20k2_i2c_write(hw,
|
||||
MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB),
|
||||
MAKE_WM8775_DATA(MIC_BOOST_20DB)); /* +20dB */
|
||||
} else if (mux == 2) {
|
||||
/* Configures GPIO data to select Line-in */
|
||||
data &= ~(0x1 << 14);
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
|
||||
/* Setup ADC */
|
||||
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x102),
|
||||
MAKE_WM8775_DATA(0x102)); /* Line-in */
|
||||
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xCF),
|
||||
MAKE_WM8775_DATA(0xCF)); /* No boost */
|
||||
hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xCF),
|
||||
MAKE_WM8775_DATA(0xCF)); /* No boost */
|
||||
if (hw->model != CTSB1270) {
|
||||
/* Configure GPIO bit 14 change to line-in/mic-in */
|
||||
ctl = hw_read_20kx(hw, GPIO_CTRL);
|
||||
ctl |= 0x1 << 14;
|
||||
hw_write_20kx(hw, GPIO_CTRL, ctl);
|
||||
hw_adc_input_select(hw, ADC_LINEIN);
|
||||
} else {
|
||||
printk(KERN_ALERT "ctxfi: ERROR!!! Invalid input mux!!!\n");
|
||||
err = -EINVAL;
|
||||
goto error;
|
||||
hw_wm8775_input_select(hw, 0, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
hw20k2_i2c_uninit(hw);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int hw_have_digit_io_switch(struct hw *hw)
|
||||
static struct capabilities hw_capabilities(struct hw *hw)
|
||||
{
|
||||
return 0;
|
||||
struct capabilities cap;
|
||||
|
||||
cap.digit_io_switch = 0;
|
||||
cap.dedicated_mic = hw->model == CTSB1270;
|
||||
cap.output_switch = hw->model == CTSB1270;
|
||||
cap.mic_source_switch = hw->model == CTSB1270;
|
||||
|
||||
return cap;
|
||||
}
|
||||
|
||||
static int hw_output_switch_get(struct hw *hw)
|
||||
{
|
||||
u32 data = hw_read_20kx(hw, GPIO_EXT_DATA);
|
||||
|
||||
switch (data & 0x30) {
|
||||
case 0x00:
|
||||
return 0;
|
||||
case 0x10:
|
||||
return 1;
|
||||
case 0x20:
|
||||
return 2;
|
||||
default:
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
static int hw_output_switch_put(struct hw *hw, int position)
|
||||
{
|
||||
u32 data;
|
||||
|
||||
if (position == hw_output_switch_get(hw))
|
||||
return 0;
|
||||
|
||||
/* Mute line and headphones (intended for anti-pop). */
|
||||
data = hw_read_20kx(hw, GPIO_DATA);
|
||||
data |= (0x03 << 11);
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
|
||||
data = hw_read_20kx(hw, GPIO_EXT_DATA) & ~0x30;
|
||||
switch (position) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
data |= 0x10;
|
||||
break;
|
||||
default:
|
||||
data |= 0x20;
|
||||
}
|
||||
hw_write_20kx(hw, GPIO_EXT_DATA, data);
|
||||
|
||||
/* Unmute line and headphones. */
|
||||
data = hw_read_20kx(hw, GPIO_DATA);
|
||||
data &= ~(0x03 << 11);
|
||||
hw_write_20kx(hw, GPIO_DATA, data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int hw_mic_source_switch_get(struct hw *hw)
|
||||
{
|
||||
struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
|
||||
|
||||
return hw20k2->mic_source;
|
||||
}
|
||||
|
||||
static int hw_mic_source_switch_put(struct hw *hw, int position)
|
||||
{
|
||||
struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
|
||||
|
||||
if (position == hw20k2->mic_source)
|
||||
return 0;
|
||||
|
||||
switch (position) {
|
||||
case 0:
|
||||
hw_wm8775_input_select(hw, 0, 0); /* Mic, 0dB */
|
||||
break;
|
||||
case 1:
|
||||
hw_wm8775_input_select(hw, 1, 0); /* FP Mic, 0dB */
|
||||
break;
|
||||
case 2:
|
||||
hw_wm8775_input_select(hw, 3, 0); /* Aux Ext, 0dB */
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
hw20k2->mic_source = position;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static irqreturn_t ct_20k2_interrupt(int irq, void *dev_id)
|
||||
@ -1925,7 +2061,7 @@ static int hw_card_start(struct hw *hw)
|
||||
|
||||
if (hw->irq < 0) {
|
||||
err = request_irq(pci->irq, ct_20k2_interrupt, IRQF_SHARED,
|
||||
"ctxfi", hw);
|
||||
KBUILD_MODNAME, hw);
|
||||
if (err < 0) {
|
||||
printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
|
||||
goto error2;
|
||||
@ -2023,13 +2159,16 @@ static int hw_card_init(struct hw *hw, struct card_conf *info)
|
||||
/* Reset all SRC pending interrupts */
|
||||
hw_write_20kx(hw, SRC_IP, 0);
|
||||
|
||||
/* TODO: detect the card ID and configure GPIO accordingly. */
|
||||
/* Configures GPIO (0xD802 0x98028) */
|
||||
/*hw_write_20kx(hw, GPIO_CTRL, 0x7F07);*/
|
||||
/* Configures GPIO (SB0880) */
|
||||
/*hw_write_20kx(hw, GPIO_CTRL, 0xFF07);*/
|
||||
hw_write_20kx(hw, GPIO_CTRL, 0xD802);
|
||||
|
||||
if (hw->model != CTSB1270) {
|
||||
/* TODO: detect the card ID and configure GPIO accordingly. */
|
||||
/* Configures GPIO (0xD802 0x98028) */
|
||||
/*hw_write_20kx(hw, GPIO_CTRL, 0x7F07);*/
|
||||
/* Configures GPIO (SB0880) */
|
||||
/*hw_write_20kx(hw, GPIO_CTRL, 0xFF07);*/
|
||||
hw_write_20kx(hw, GPIO_CTRL, 0xD802);
|
||||
} else {
|
||||
hw_write_20kx(hw, GPIO_CTRL, 0x9E5F);
|
||||
}
|
||||
/* Enable audio ring */
|
||||
hw_write_20kx(hw, MIXER_AR_ENABLE, 0x01);
|
||||
|
||||
@ -2106,7 +2245,11 @@ static struct hw ct20k2_preset __devinitdata = {
|
||||
.pll_init = hw_pll_init,
|
||||
.is_adc_source_selected = hw_is_adc_input_selected,
|
||||
.select_adc_source = hw_adc_input_select,
|
||||
.have_digit_io_switch = hw_have_digit_io_switch,
|
||||
.capabilities = hw_capabilities,
|
||||
.output_switch_get = hw_output_switch_get,
|
||||
.output_switch_put = hw_output_switch_put,
|
||||
.mic_source_switch_get = hw_mic_source_switch_get,
|
||||
.mic_source_switch_put = hw_mic_source_switch_put,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = hw_suspend,
|
||||
.resume = hw_resume,
|
||||
|
@ -86,9 +86,7 @@ enum CTALSA_MIXER_CTL {
|
||||
MIXER_LINEIN_C_S,
|
||||
MIXER_MIC_C_S,
|
||||
MIXER_SPDIFI_C_S,
|
||||
MIXER_LINEIN_P_S,
|
||||
MIXER_SPDIFO_P_S,
|
||||
MIXER_SPDIFI_P_S,
|
||||
MIXER_WAVEF_P_S,
|
||||
MIXER_WAVER_P_S,
|
||||
MIXER_WAVEC_P_S,
|
||||
@ -137,11 +135,11 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
|
||||
},
|
||||
[MIXER_LINEIN_P] = {
|
||||
.ctl = 1,
|
||||
.name = "Line-in Playback Volume",
|
||||
.name = "Line Playback Volume",
|
||||
},
|
||||
[MIXER_LINEIN_C] = {
|
||||
.ctl = 1,
|
||||
.name = "Line-in Capture Volume",
|
||||
.name = "Line Capture Volume",
|
||||
},
|
||||
[MIXER_MIC_P] = {
|
||||
.ctl = 1,
|
||||
@ -153,15 +151,15 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
|
||||
},
|
||||
[MIXER_SPDIFI_P] = {
|
||||
.ctl = 1,
|
||||
.name = "S/PDIF-in Playback Volume",
|
||||
.name = "IEC958 Playback Volume",
|
||||
},
|
||||
[MIXER_SPDIFI_C] = {
|
||||
.ctl = 1,
|
||||
.name = "S/PDIF-in Capture Volume",
|
||||
.name = "IEC958 Capture Volume",
|
||||
},
|
||||
[MIXER_SPDIFO_P] = {
|
||||
.ctl = 1,
|
||||
.name = "S/PDIF-out Playback Volume",
|
||||
.name = "Digital Playback Volume",
|
||||
},
|
||||
[MIXER_WAVEF_P] = {
|
||||
.ctl = 1,
|
||||
@ -179,14 +177,13 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
|
||||
.ctl = 1,
|
||||
.name = "Surround Playback Volume",
|
||||
},
|
||||
|
||||
[MIXER_PCM_C_S] = {
|
||||
.ctl = 1,
|
||||
.name = "PCM Capture Switch",
|
||||
},
|
||||
[MIXER_LINEIN_C_S] = {
|
||||
.ctl = 1,
|
||||
.name = "Line-in Capture Switch",
|
||||
.name = "Line Capture Switch",
|
||||
},
|
||||
[MIXER_MIC_C_S] = {
|
||||
.ctl = 1,
|
||||
@ -194,19 +191,11 @@ ct_kcontrol_init_table[NUM_CTALSA_MIXERS] = {
|
||||
},
|
||||
[MIXER_SPDIFI_C_S] = {
|
||||
.ctl = 1,
|
||||
.name = "S/PDIF-in Capture Switch",
|
||||
},
|
||||
[MIXER_LINEIN_P_S] = {
|
||||
.ctl = 1,
|
||||
.name = "Line-in Playback Switch",
|
||||
.name = "IEC958 Capture Switch",
|
||||
},
|
||||
[MIXER_SPDIFO_P_S] = {
|
||||
.ctl = 1,
|
||||
.name = "S/PDIF-out Playback Switch",
|
||||
},
|
||||
[MIXER_SPDIFI_P_S] = {
|
||||
.ctl = 1,
|
||||
.name = "S/PDIF-in Playback Switch",
|
||||
.name = "Digital Playback Switch",
|
||||
},
|
||||
[MIXER_WAVEF_P_S] = {
|
||||
.ctl = 1,
|
||||
@ -236,6 +225,8 @@ ct_mixer_recording_select(struct ct_mixer *mixer, enum CT_AMIXER_CTL type);
|
||||
static void
|
||||
ct_mixer_recording_unselect(struct ct_mixer *mixer, enum CT_AMIXER_CTL type);
|
||||
|
||||
/* FIXME: this static looks like it would fail if more than one card was */
|
||||
/* installed. */
|
||||
static struct snd_kcontrol *kctls[2] = {NULL};
|
||||
|
||||
static enum CT_AMIXER_CTL get_amixer_index(enum CTALSA_MIXER_CTL alsa_index)
|
||||
@ -420,6 +411,77 @@ static struct snd_kcontrol_new vol_ctl = {
|
||||
.tlv = { .p = ct_vol_db_scale },
|
||||
};
|
||||
|
||||
static int output_switch_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *info)
|
||||
{
|
||||
static const char *const names[3] = {
|
||||
"FP Headphones", "Headphones", "Speakers"
|
||||
};
|
||||
|
||||
return snd_ctl_enum_info(info, 1, 3, names);
|
||||
}
|
||||
|
||||
static int output_switch_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
|
||||
ucontrol->value.enumerated.item[0] = atc->output_switch_get(atc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int output_switch_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
|
||||
if (ucontrol->value.enumerated.item[0] > 2)
|
||||
return -EINVAL;
|
||||
return atc->output_switch_put(atc, ucontrol->value.enumerated.item[0]);
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new output_ctl = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Analog Output Playback Enum",
|
||||
.info = output_switch_info,
|
||||
.get = output_switch_get,
|
||||
.put = output_switch_put,
|
||||
};
|
||||
|
||||
static int mic_source_switch_info(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_info *info)
|
||||
{
|
||||
static const char *const names[3] = {
|
||||
"Mic", "FP Mic", "Aux"
|
||||
};
|
||||
|
||||
return snd_ctl_enum_info(info, 1, 3, names);
|
||||
}
|
||||
|
||||
static int mic_source_switch_get(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
|
||||
ucontrol->value.enumerated.item[0] = atc->mic_source_switch_get(atc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mic_source_switch_put(struct snd_kcontrol *kcontrol,
|
||||
struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct ct_atc *atc = snd_kcontrol_chip(kcontrol);
|
||||
if (ucontrol->value.enumerated.item[0] > 2)
|
||||
return -EINVAL;
|
||||
return atc->mic_source_switch_put(atc,
|
||||
ucontrol->value.enumerated.item[0]);
|
||||
}
|
||||
|
||||
static struct snd_kcontrol_new mic_source_ctl = {
|
||||
.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
|
||||
.name = "Mic Source Capture Enum",
|
||||
.info = mic_source_switch_info,
|
||||
.get = mic_source_switch_get,
|
||||
.put = mic_source_switch_put,
|
||||
};
|
||||
|
||||
static void
|
||||
do_line_mic_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type)
|
||||
{
|
||||
@ -465,6 +527,7 @@ do_digit_io_switch(struct ct_atc *atc, int state)
|
||||
static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
|
||||
{
|
||||
struct ct_mixer *mixer = atc->mixer;
|
||||
struct capabilities cap = atc->capabilities(atc);
|
||||
|
||||
/* Do changes in mixer. */
|
||||
if ((SWH_CAPTURE_START <= type) && (SWH_CAPTURE_END >= type)) {
|
||||
@ -477,8 +540,17 @@ static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
|
||||
}
|
||||
}
|
||||
/* Do changes out of mixer. */
|
||||
if (state && (MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type))
|
||||
do_line_mic_switch(atc, type);
|
||||
if (!cap.dedicated_mic &&
|
||||
(MIXER_LINEIN_C_S == type || MIXER_MIC_C_S == type)) {
|
||||
if (state)
|
||||
do_line_mic_switch(atc, type);
|
||||
atc->line_in_unmute(atc, state);
|
||||
} else if (cap.dedicated_mic && (MIXER_LINEIN_C_S == type))
|
||||
atc->line_in_unmute(atc, state);
|
||||
else if (cap.dedicated_mic && (MIXER_MIC_C_S == type))
|
||||
atc->mic_unmute(atc, state);
|
||||
else if (MIXER_SPDIFI_C_S == type)
|
||||
atc->spdif_in_unmute(atc, state);
|
||||
else if (MIXER_WAVEF_P_S == type)
|
||||
atc->line_front_unmute(atc, state);
|
||||
else if (MIXER_WAVES_P_S == type)
|
||||
@ -487,12 +559,8 @@ static void do_switch(struct ct_atc *atc, enum CTALSA_MIXER_CTL type, int state)
|
||||
atc->line_clfe_unmute(atc, state);
|
||||
else if (MIXER_WAVER_P_S == type)
|
||||
atc->line_rear_unmute(atc, state);
|
||||
else if (MIXER_LINEIN_P_S == type)
|
||||
atc->line_in_unmute(atc, state);
|
||||
else if (MIXER_SPDIFO_P_S == type)
|
||||
atc->spdif_out_unmute(atc, state);
|
||||
else if (MIXER_SPDIFI_P_S == type)
|
||||
atc->spdif_in_unmute(atc, state);
|
||||
else if (MIXER_DIGITAL_IO_S == type)
|
||||
do_digit_io_switch(atc, state);
|
||||
|
||||
@ -671,6 +739,7 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
|
||||
{
|
||||
enum CTALSA_MIXER_CTL type;
|
||||
struct ct_atc *atc = mixer->atc;
|
||||
struct capabilities cap = atc->capabilities(atc);
|
||||
int err;
|
||||
|
||||
/* Create snd kcontrol instances on demand */
|
||||
@ -684,8 +753,8 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
|
||||
}
|
||||
}
|
||||
|
||||
ct_kcontrol_init_table[MIXER_DIGITAL_IO_S].ctl =
|
||||
atc->have_digit_io_switch(atc);
|
||||
ct_kcontrol_init_table[MIXER_DIGITAL_IO_S].ctl = cap.digit_io_switch;
|
||||
|
||||
for (type = SWH_MIXER_START; type <= SWH_MIXER_END; type++) {
|
||||
if (ct_kcontrol_init_table[type].ctl) {
|
||||
swh_ctl.name = ct_kcontrol_init_table[type].name;
|
||||
@ -708,6 +777,17 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (cap.output_switch) {
|
||||
err = ct_mixer_kcontrol_new(mixer, &output_ctl);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (cap.mic_source_switch) {
|
||||
err = ct_mixer_kcontrol_new(mixer, &mic_source_ctl);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
atc->line_front_unmute(atc, 1);
|
||||
set_switch_state(mixer, MIXER_WAVEF_P_S, 1);
|
||||
atc->line_surround_unmute(atc, 0);
|
||||
@ -719,13 +799,12 @@ static int ct_mixer_kcontrols_create(struct ct_mixer *mixer)
|
||||
atc->spdif_out_unmute(atc, 0);
|
||||
set_switch_state(mixer, MIXER_SPDIFO_P_S, 0);
|
||||
atc->line_in_unmute(atc, 0);
|
||||
set_switch_state(mixer, MIXER_LINEIN_P_S, 0);
|
||||
if (cap.dedicated_mic)
|
||||
atc->mic_unmute(atc, 0);
|
||||
atc->spdif_in_unmute(atc, 0);
|
||||
set_switch_state(mixer, MIXER_SPDIFI_P_S, 0);
|
||||
|
||||
set_switch_state(mixer, MIXER_PCM_C_S, 1);
|
||||
set_switch_state(mixer, MIXER_LINEIN_C_S, 1);
|
||||
set_switch_state(mixer, MIXER_SPDIFI_C_S, 1);
|
||||
set_switch_state(mixer, MIXER_PCM_C_S, 0);
|
||||
set_switch_state(mixer, MIXER_LINEIN_C_S, 0);
|
||||
set_switch_state(mixer, MIXER_SPDIFI_C_S, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -80,11 +80,11 @@ ct_card_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
|
||||
"are 48000 and 44100, Value 48000 is assumed.\n");
|
||||
reference_rate = 48000;
|
||||
}
|
||||
if ((multiple != 1) && (multiple != 2)) {
|
||||
if ((multiple != 1) && (multiple != 2) && (multiple != 4)) {
|
||||
printk(KERN_ERR "ctxfi: Invalid multiple value %u!!!\n",
|
||||
multiple);
|
||||
printk(KERN_ERR "ctxfi: The valid values for multiple are "
|
||||
"1 and 2, Value 2 is assumed.\n");
|
||||
"1, 2 and 4, Value 2 is assumed.\n");
|
||||
multiple = 2;
|
||||
}
|
||||
err = ct_atc_create(card, pci, reference_rate, multiple,
|
||||
@ -143,7 +143,7 @@ static int ct_card_resume(struct pci_dev *pci)
|
||||
#endif
|
||||
|
||||
static struct pci_driver ct_driver = {
|
||||
.name = "SB-XFi",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = ct_pci_dev_ids,
|
||||
.probe = ct_card_probe,
|
||||
.remove = __devexit_p(ct_card_remove),
|
||||
|
@ -1995,7 +1995,7 @@ static __devinit int snd_echo_create(struct snd_card *card,
|
||||
ioremap_nocache(chip->dsp_registers_phys, sz);
|
||||
|
||||
if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
|
||||
ECHOCARD_NAME, chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_echo_free(chip);
|
||||
snd_printk(KERN_ERR "cannot grab irq\n");
|
||||
return -EBUSY;
|
||||
@ -2286,7 +2286,7 @@ static int snd_echo_resume(struct pci_dev *pci)
|
||||
kfree(commpage_bak);
|
||||
|
||||
if (request_irq(pci->irq, snd_echo_interrupt, IRQF_SHARED,
|
||||
ECHOCARD_NAME, chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_echo_free(chip);
|
||||
snd_printk(KERN_ERR "cannot grab irq\n");
|
||||
return -EBUSY;
|
||||
@ -2327,7 +2327,7 @@ static void __devexit snd_echo_remove(struct pci_dev *pci)
|
||||
|
||||
/* pci_driver definition */
|
||||
static struct pci_driver driver = {
|
||||
.name = "Echoaudio " ECHOCARD_NAME,
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_echo_ids,
|
||||
.probe = snd_echo_probe,
|
||||
.remove = __devexit_p(snd_echo_remove),
|
||||
|
@ -264,7 +264,7 @@ static int snd_emu10k1_resume(struct pci_dev *pci)
|
||||
#endif
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "EMU10K1_Audigy",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_emu10k1_ids,
|
||||
.probe = snd_card_emu10k1_probe,
|
||||
.remove = __devexit_p(snd_card_emu10k1_remove),
|
||||
|
@ -1912,7 +1912,7 @@ int __devinit snd_emu10k1_create(struct snd_card *card,
|
||||
|
||||
/* irq handler must be registered after I/O ports are activated */
|
||||
if (request_irq(pci->irq, snd_emu10k1_interrupt, IRQF_SHARED,
|
||||
"EMU10K1", emu)) {
|
||||
KBUILD_MODNAME, emu)) {
|
||||
err = -EBUSY;
|
||||
goto error;
|
||||
}
|
||||
|
@ -925,7 +925,7 @@ static int __devinit snd_emu10k1x_create(struct snd_card *card,
|
||||
}
|
||||
|
||||
if (request_irq(pci->irq, snd_emu10k1x_interrupt,
|
||||
IRQF_SHARED, "EMU10K1X", chip)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "emu10k1x: cannot grab irq %d\n", pci->irq);
|
||||
snd_emu10k1x_free(chip);
|
||||
return -EBUSY;
|
||||
@ -1613,7 +1613,7 @@ MODULE_DEVICE_TABLE(pci, snd_emu10k1x_ids);
|
||||
|
||||
// pci_driver definition
|
||||
static struct pci_driver driver = {
|
||||
.name = "EMU10K1X",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_emu10k1x_ids,
|
||||
.probe = snd_emu10k1x_probe,
|
||||
.remove = __devexit_p(snd_emu10k1x_remove),
|
||||
|
@ -2120,7 +2120,7 @@ static int __devinit snd_ensoniq_create(struct snd_card *card,
|
||||
}
|
||||
ensoniq->port = pci_resource_start(pci, 0);
|
||||
if (request_irq(pci->irq, snd_audiopci_interrupt, IRQF_SHARED,
|
||||
"Ensoniq AudioPCI", ensoniq)) {
|
||||
KBUILD_MODNAME, ensoniq)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_ensoniq_free(ensoniq);
|
||||
return -EBUSY;
|
||||
@ -2489,7 +2489,7 @@ static void __devexit snd_audiopci_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = DRIVER_NAME,
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_audiopci_ids,
|
||||
.probe = snd_audiopci_probe,
|
||||
.remove = __devexit_p(snd_audiopci_remove),
|
||||
|
@ -1514,7 +1514,7 @@ static int es1938_resume(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
if (request_irq(pci->irq, snd_es1938_interrupt,
|
||||
IRQF_SHARED, "ES1938", chip)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, chip)) {
|
||||
printk(KERN_ERR "es1938: unable to grab IRQ %d, "
|
||||
"disabling device\n", pci->irq);
|
||||
snd_card_disconnect(card);
|
||||
@ -1636,7 +1636,7 @@ static int __devinit snd_es1938_create(struct snd_card *card,
|
||||
chip->mpu_port = pci_resource_start(pci, 3);
|
||||
chip->game_port = pci_resource_start(pci, 4);
|
||||
if (request_irq(pci->irq, snd_es1938_interrupt, IRQF_SHARED,
|
||||
"ES1938", chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_es1938_free(chip);
|
||||
return -EBUSY;
|
||||
@ -1882,7 +1882,7 @@ static void __devexit snd_es1938_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "ESS ES1938 (Solo-1)",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_es1938_ids,
|
||||
.probe = snd_es1938_probe,
|
||||
.remove = __devexit_p(snd_es1938_remove),
|
||||
|
@ -554,9 +554,8 @@ struct es1968 {
|
||||
#else
|
||||
struct snd_kcontrol *master_switch; /* for h/w volume control */
|
||||
struct snd_kcontrol *master_volume;
|
||||
spinlock_t ac97_lock;
|
||||
struct tasklet_struct hwvol_tq;
|
||||
#endif
|
||||
struct work_struct hwvol_work;
|
||||
|
||||
#ifdef CONFIG_SND_ES1968_RADIO
|
||||
struct snd_tea575x tea;
|
||||
@ -646,38 +645,23 @@ static int snd_es1968_ac97_wait_poll(struct es1968 *chip)
|
||||
static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
|
||||
{
|
||||
struct es1968 *chip = ac97->private_data;
|
||||
#ifndef CONFIG_SND_ES1968_INPUT
|
||||
unsigned long flags;
|
||||
#endif
|
||||
|
||||
snd_es1968_ac97_wait(chip);
|
||||
|
||||
/* Write the bus */
|
||||
#ifndef CONFIG_SND_ES1968_INPUT
|
||||
spin_lock_irqsave(&chip->ac97_lock, flags);
|
||||
#endif
|
||||
outw(val, chip->io_port + ESM_AC97_DATA);
|
||||
/*msleep(1);*/
|
||||
outb(reg, chip->io_port + ESM_AC97_INDEX);
|
||||
/*msleep(1);*/
|
||||
#ifndef CONFIG_SND_ES1968_INPUT
|
||||
spin_unlock_irqrestore(&chip->ac97_lock, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
|
||||
{
|
||||
u16 data = 0;
|
||||
struct es1968 *chip = ac97->private_data;
|
||||
#ifndef CONFIG_SND_ES1968_INPUT
|
||||
unsigned long flags;
|
||||
#endif
|
||||
|
||||
snd_es1968_ac97_wait(chip);
|
||||
|
||||
#ifndef CONFIG_SND_ES1968_INPUT
|
||||
spin_lock_irqsave(&chip->ac97_lock, flags);
|
||||
#endif
|
||||
outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
|
||||
/*msleep(1);*/
|
||||
|
||||
@ -685,9 +669,6 @@ static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short
|
||||
data = inw(chip->io_port + ESM_AC97_DATA);
|
||||
/*msleep(1);*/
|
||||
}
|
||||
#ifndef CONFIG_SND_ES1968_INPUT
|
||||
spin_unlock_irqrestore(&chip->ac97_lock, flags);
|
||||
#endif
|
||||
|
||||
return data;
|
||||
}
|
||||
@ -1904,13 +1885,10 @@ static void snd_es1968_update_pcm(struct es1968 *chip, struct esschan *es)
|
||||
(without wrap around) in response to volume button presses and then
|
||||
generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
|
||||
of a byte wide register. The meaning of bits 0 and 4 is unknown. */
|
||||
static void es1968_update_hw_volume(unsigned long private_data)
|
||||
static void es1968_update_hw_volume(struct work_struct *work)
|
||||
{
|
||||
struct es1968 *chip = (struct es1968 *) private_data;
|
||||
struct es1968 *chip = container_of(work, struct es1968, hwvol_work);
|
||||
int x, val;
|
||||
#ifndef CONFIG_SND_ES1968_INPUT
|
||||
unsigned long flags;
|
||||
#endif
|
||||
|
||||
/* Figure out which volume control button was pushed,
|
||||
based on differences from the default register
|
||||
@ -1929,18 +1907,11 @@ static void es1968_update_hw_volume(unsigned long private_data)
|
||||
if (! chip->master_switch || ! chip->master_volume)
|
||||
return;
|
||||
|
||||
/* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */
|
||||
spin_lock_irqsave(&chip->ac97_lock, flags);
|
||||
val = chip->ac97->regs[AC97_MASTER];
|
||||
val = snd_ac97_read(chip->ac97, AC97_MASTER);
|
||||
switch (x) {
|
||||
case 0x88:
|
||||
/* mute */
|
||||
val ^= 0x8000;
|
||||
chip->ac97->regs[AC97_MASTER] = val;
|
||||
outw(val, chip->io_port + ESM_AC97_DATA);
|
||||
outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&chip->master_switch->id);
|
||||
break;
|
||||
case 0xaa:
|
||||
/* volume up */
|
||||
@ -1948,11 +1919,6 @@ static void es1968_update_hw_volume(unsigned long private_data)
|
||||
val--;
|
||||
if ((val & 0x7f00) > 0)
|
||||
val -= 0x0100;
|
||||
chip->ac97->regs[AC97_MASTER] = val;
|
||||
outw(val, chip->io_port + ESM_AC97_DATA);
|
||||
outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&chip->master_volume->id);
|
||||
break;
|
||||
case 0x66:
|
||||
/* volume down */
|
||||
@ -1960,14 +1926,11 @@ static void es1968_update_hw_volume(unsigned long private_data)
|
||||
val++;
|
||||
if ((val & 0x7f00) < 0x1f00)
|
||||
val += 0x0100;
|
||||
chip->ac97->regs[AC97_MASTER] = val;
|
||||
outw(val, chip->io_port + ESM_AC97_DATA);
|
||||
outb(AC97_MASTER, chip->io_port + ESM_AC97_INDEX);
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&chip->master_volume->id);
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&chip->ac97_lock, flags);
|
||||
if (snd_ac97_update(chip->ac97, AC97_MASTER, val))
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&chip->master_volume->id);
|
||||
#else
|
||||
if (!chip->input_dev)
|
||||
return;
|
||||
@ -2013,11 +1976,7 @@ static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id)
|
||||
outw(inw(chip->io_port + 4) & 1, chip->io_port + 4);
|
||||
|
||||
if (event & ESM_HWVOL_IRQ)
|
||||
#ifdef CONFIG_SND_ES1968_INPUT
|
||||
es1968_update_hw_volume((unsigned long)chip);
|
||||
#else
|
||||
tasklet_schedule(&chip->hwvol_tq); /* we'll do this later */
|
||||
#endif
|
||||
schedule_work(&chip->hwvol_work);
|
||||
|
||||
/* else ack 'em all, i imagine */
|
||||
outb(0xFF, chip->io_port + 0x1A);
|
||||
@ -2426,6 +2385,7 @@ static int es1968_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
return 0;
|
||||
|
||||
chip->in_suspend = 1;
|
||||
cancel_work_sync(&chip->hwvol_work);
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
|
||||
snd_pcm_suspend_all(chip->pcm);
|
||||
snd_ac97_suspend(chip->ac97);
|
||||
@ -2638,6 +2598,7 @@ static struct snd_tea575x_ops snd_es1968_tea_ops = {
|
||||
|
||||
static int snd_es1968_free(struct es1968 *chip)
|
||||
{
|
||||
cancel_work_sync(&chip->hwvol_work);
|
||||
#ifdef CONFIG_SND_ES1968_INPUT
|
||||
if (chip->input_dev)
|
||||
input_unregister_device(chip->input_dev);
|
||||
@ -2728,10 +2689,7 @@ static int __devinit snd_es1968_create(struct snd_card *card,
|
||||
INIT_LIST_HEAD(&chip->buf_list);
|
||||
INIT_LIST_HEAD(&chip->substream_list);
|
||||
mutex_init(&chip->memory_mutex);
|
||||
#ifndef CONFIG_SND_ES1968_INPUT
|
||||
spin_lock_init(&chip->ac97_lock);
|
||||
tasklet_init(&chip->hwvol_tq, es1968_update_hw_volume, (unsigned long)chip);
|
||||
#endif
|
||||
INIT_WORK(&chip->hwvol_work, es1968_update_hw_volume);
|
||||
chip->card = card;
|
||||
chip->pci = pci;
|
||||
chip->irq = -1;
|
||||
@ -2746,7 +2704,7 @@ static int __devinit snd_es1968_create(struct snd_card *card,
|
||||
}
|
||||
chip->io_port = pci_resource_start(pci, 0);
|
||||
if (request_irq(pci->irq, snd_es1968_interrupt, IRQF_SHARED,
|
||||
"ESS Maestro", chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_es1968_free(chip);
|
||||
return -EBUSY;
|
||||
@ -2925,7 +2883,7 @@ static void __devexit snd_es1968_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "ES1968 (ESS Maestro)",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_es1968_ids,
|
||||
.probe = snd_es1968_probe,
|
||||
.remove = __devexit_p(snd_es1968_remove),
|
||||
|
@ -1199,7 +1199,7 @@ static int __devinit snd_fm801_create(struct snd_card *card,
|
||||
chip->port = pci_resource_start(pci, 0);
|
||||
if ((tea575x_tuner & TUNER_ONLY) == 0) {
|
||||
if (request_irq(pci->irq, snd_fm801_interrupt, IRQF_SHARED,
|
||||
"FM801", chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->irq);
|
||||
snd_fm801_free(chip);
|
||||
return -EBUSY;
|
||||
@ -1394,7 +1394,7 @@ static int snd_fm801_resume(struct pci_dev *pci)
|
||||
#endif
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "FM801",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_fm801_ids,
|
||||
.probe = snd_card_fm801_probe,
|
||||
.remove = __devexit_p(snd_card_fm801_remove),
|
||||
|
@ -4957,17 +4957,15 @@ void *snd_array_new(struct snd_array *array)
|
||||
{
|
||||
if (array->used >= array->alloced) {
|
||||
int num = array->alloced + array->alloc_align;
|
||||
int size = (num + 1) * array->elem_size;
|
||||
int oldsize = array->alloced * array->elem_size;
|
||||
void *nlist;
|
||||
if (snd_BUG_ON(num >= 4096))
|
||||
return NULL;
|
||||
nlist = kcalloc(num + 1, array->elem_size, GFP_KERNEL);
|
||||
nlist = krealloc(array->list, size, GFP_KERNEL);
|
||||
if (!nlist)
|
||||
return NULL;
|
||||
if (array->list) {
|
||||
memcpy(nlist, array->list,
|
||||
array->elem_size * array->alloced);
|
||||
kfree(array->list);
|
||||
}
|
||||
memset(nlist + oldsize, 0, size - oldsize);
|
||||
array->list = nlist;
|
||||
array->alloced = num;
|
||||
}
|
||||
|
@ -2149,7 +2149,7 @@ static int azx_acquire_irq(struct azx *chip, int do_disconnect)
|
||||
{
|
||||
if (request_irq(chip->pci->irq, azx_interrupt,
|
||||
chip->msi ? 0 : IRQF_SHARED,
|
||||
"hda_intel", chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
printk(KERN_ERR "hda-intel: unable to grab IRQ %d, "
|
||||
"disabling device\n", chip->pci->irq);
|
||||
if (do_disconnect)
|
||||
@ -2908,7 +2908,7 @@ MODULE_DEVICE_TABLE(pci, azx_ids);
|
||||
|
||||
/* pci_driver definition */
|
||||
static struct pci_driver driver = {
|
||||
.name = "HDA Intel",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = azx_ids,
|
||||
.probe = azx_probe,
|
||||
.remove = __devexit_p(azx_remove),
|
||||
|
@ -2607,7 +2607,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card,
|
||||
ice->profi_port = pci_resource_start(pci, 3);
|
||||
|
||||
if (request_irq(pci->irq, snd_ice1712_interrupt, IRQF_SHARED,
|
||||
"ICE1712", ice)) {
|
||||
KBUILD_MODNAME, ice)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_ice1712_free(ice);
|
||||
return -EIO;
|
||||
@ -2802,7 +2802,7 @@ static void __devexit snd_ice1712_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "ICE1712",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_ice1712_ids,
|
||||
.probe = snd_ice1712_probe,
|
||||
.remove = __devexit_p(snd_ice1712_remove),
|
||||
|
@ -2509,7 +2509,7 @@ static int __devinit snd_vt1724_create(struct snd_card *card,
|
||||
ice->profi_port = pci_resource_start(pci, 1);
|
||||
|
||||
if (request_irq(pci->irq, snd_vt1724_interrupt,
|
||||
IRQF_SHARED, "ICE1724", ice)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, ice)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_vt1724_free(ice);
|
||||
return -EIO;
|
||||
@ -2802,7 +2802,7 @@ static int snd_vt1724_resume(struct pci_dev *pci)
|
||||
#endif
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "ICE1724",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_vt1724_ids,
|
||||
.probe = snd_vt1724_probe,
|
||||
.remove = __devexit_p(snd_vt1724_remove),
|
||||
|
@ -1882,6 +1882,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
|
||||
.name = "Dell Inspiron 6000",
|
||||
.type = AC97_TUNE_HP_MUTE_LED /* cf. Malone #41015 */
|
||||
},
|
||||
{
|
||||
.subvendor = 0x1028,
|
||||
.subdevice = 0x0189,
|
||||
.name = "Dell Inspiron 9300",
|
||||
.type = AC97_TUNE_HP_MUTE_LED
|
||||
},
|
||||
{
|
||||
.subvendor = 0x1028,
|
||||
.subdevice = 0x0191,
|
||||
@ -2647,7 +2653,7 @@ static int intel8x0_resume(struct pci_dev *pci)
|
||||
pci_set_master(pci);
|
||||
snd_intel8x0_chip_init(chip, 0);
|
||||
if (request_irq(pci->irq, snd_intel8x0_interrupt,
|
||||
IRQF_SHARED, card->shortname, chip)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, chip)) {
|
||||
printk(KERN_ERR "intel8x0: unable to grab IRQ %d, "
|
||||
"disabling device\n", pci->irq);
|
||||
snd_card_disconnect(card);
|
||||
@ -3106,7 +3112,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card,
|
||||
|
||||
/* request irq after initializaing int_sta_mask, etc */
|
||||
if (request_irq(pci->irq, snd_intel8x0_interrupt,
|
||||
IRQF_SHARED, card->shortname, chip)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_intel8x0_free(chip);
|
||||
return -EBUSY;
|
||||
@ -3266,7 +3272,7 @@ static void __devexit snd_intel8x0_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "Intel ICH",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_intel8x0_ids,
|
||||
.probe = snd_intel8x0_probe,
|
||||
.remove = __devexit_p(snd_intel8x0_remove),
|
||||
|
@ -1047,7 +1047,7 @@ static int intel8x0m_resume(struct pci_dev *pci)
|
||||
}
|
||||
pci_set_master(pci);
|
||||
if (request_irq(pci->irq, snd_intel8x0m_interrupt,
|
||||
IRQF_SHARED, card->shortname, chip)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, chip)) {
|
||||
printk(KERN_ERR "intel8x0m: unable to grab IRQ %d, "
|
||||
"disabling device\n", pci->irq);
|
||||
snd_card_disconnect(card);
|
||||
@ -1174,7 +1174,7 @@ static int __devinit snd_intel8x0m_create(struct snd_card *card,
|
||||
|
||||
port_inited:
|
||||
if (request_irq(pci->irq, snd_intel8x0m_interrupt, IRQF_SHARED,
|
||||
card->shortname, chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_intel8x0m_free(chip);
|
||||
return -EBUSY;
|
||||
@ -1325,7 +1325,7 @@ static void __devexit snd_intel8x0m_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "Intel ICH Modem",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_intel8x0m_ids,
|
||||
.probe = snd_intel8x0m_probe,
|
||||
.remove = __devexit_p(snd_intel8x0m_remove),
|
||||
|
@ -2241,7 +2241,7 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev *
|
||||
|
||||
err = request_irq(pci->irq, snd_korg1212_interrupt,
|
||||
IRQF_SHARED,
|
||||
"korg1212", korg1212);
|
||||
KBUILD_MODNAME, korg1212);
|
||||
|
||||
if (err) {
|
||||
snd_printk(KERN_ERR "korg1212: unable to grab IRQ %d\n", pci->irq);
|
||||
@ -2477,7 +2477,7 @@ static void __devexit snd_korg1212_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "korg1212",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_korg1212_ids,
|
||||
.probe = snd_korg1212_probe,
|
||||
.remove = __devexit_p(snd_korg1212_remove),
|
||||
|
@ -648,7 +648,7 @@ static int __devinit lola_create(struct snd_card *card, struct pci_dev *pci,
|
||||
goto errout;
|
||||
|
||||
if (request_irq(pci->irq, lola_interrupt, IRQF_SHARED,
|
||||
DRVNAME, chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq);
|
||||
err = -EBUSY;
|
||||
goto errout;
|
||||
@ -771,7 +771,7 @@ MODULE_DEVICE_TABLE(pci, lola_ids);
|
||||
|
||||
/* pci_driver definition */
|
||||
static struct pci_driver driver = {
|
||||
.name = DRVNAME,
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = lola_ids,
|
||||
.probe = lola_probe,
|
||||
.remove = __devexit_p(lola_remove),
|
||||
|
@ -480,7 +480,7 @@ struct lola {
|
||||
|
||||
/* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */
|
||||
#define LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(res) ((res >> 2) & 0x1f)
|
||||
#define LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(res) ((res >> 7) & 0x1f)
|
||||
#define LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(res) ((res >> 7) & 0x1f)
|
||||
|
||||
int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb,
|
||||
unsigned int data, unsigned int extdata);
|
||||
|
@ -144,40 +144,61 @@ int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
|
||||
chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams;
|
||||
chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins;
|
||||
|
||||
/* mixer matrix can have unused areas between PhysIn and
|
||||
/* mixer matrix may have unused areas between PhysIn and
|
||||
* Play or Record and PhysOut zones
|
||||
*/
|
||||
chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins +
|
||||
LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val);
|
||||
chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins +
|
||||
LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(val);
|
||||
LOLA_MIXER_DEST_REC_OUTPUT_SEPARATION(val);
|
||||
|
||||
/* example : MixerMatrix of LoLa881
|
||||
* 0-------8------16-------8------16
|
||||
* | | | | |
|
||||
* | INPUT | | INPUT | |
|
||||
* | -> |unused | -> |unused |
|
||||
* | RECORD| | OUTPUT| |
|
||||
* | | | | |
|
||||
* 8--------------------------------
|
||||
* | | | | |
|
||||
* | | | | |
|
||||
* |unused |unused |unused |unused |
|
||||
* | | | | |
|
||||
* | | | | |
|
||||
* 16-------------------------------
|
||||
* | | | | |
|
||||
* | PLAY | | PLAY | |
|
||||
* | -> |unused | -> |unused |
|
||||
* | RECORD| | OUTPUT| |
|
||||
* | | | | |
|
||||
* 8--------------------------------
|
||||
* | | | | |
|
||||
* | | | | |
|
||||
* |unused |unused |unused |unused |
|
||||
* | | | | |
|
||||
* | | | | |
|
||||
* 16-------------------------------
|
||||
/* example : MixerMatrix of LoLa881 (LoLa16161 uses unused zones)
|
||||
* +-+ 0-------8------16-------8------16
|
||||
* | | | | | | |
|
||||
* |s| | INPUT | | INPUT | |
|
||||
* | |->| -> |unused | -> |unused |
|
||||
* |r| |CAPTURE| | OUTPUT| |
|
||||
* | | | MIX | | MIX | |
|
||||
* |c| 8--------------------------------
|
||||
* | | | | | | |
|
||||
* | | | | | | |
|
||||
* |g| |unused |unused |unused |unused |
|
||||
* | | | | | | |
|
||||
* |a| | | | | |
|
||||
* | | 16-------------------------------
|
||||
* |i| | | | | |
|
||||
* | | | PLAYBK| | PLAYBK| |
|
||||
* |n|->| -> |unused | -> |unused |
|
||||
* | | |CAPTURE| | OUTPUT| |
|
||||
* | | | MIX | | MIX | |
|
||||
* |a| 8--------------------------------
|
||||
* |r| | | | | |
|
||||
* |r| | | | | |
|
||||
* |a| |unused |unused |unused |unused |
|
||||
* |y| | | | | |
|
||||
* | | | | | | |
|
||||
* +++ 16--|---------------|------------
|
||||
* +---V---------------V-----------+
|
||||
* | dest_mix_gain_enable array |
|
||||
* +-------------------------------+
|
||||
*/
|
||||
/* example : MixerMatrix of LoLa280
|
||||
* +-+ 0-------8-2
|
||||
* | | | | |
|
||||
* |s| | INPUT | | INPUT
|
||||
* |r|->| -> | | ->
|
||||
* |c| |CAPTURE| | <- OUTPUT
|
||||
* | | | MIX | | MIX
|
||||
* |g| 8----------
|
||||
* |a| | | |
|
||||
* |i| | PLAYBK| | PLAYBACK
|
||||
* |n|->| -> | | ->
|
||||
* | | |CAPTURE| | <- OUTPUT
|
||||
* |a| | MIX | | MIX
|
||||
* |r| 8---|----|-
|
||||
* |r| +---V----V-------------------+
|
||||
* |a| | dest_mix_gain_enable array |
|
||||
* |y| +----------------------------+
|
||||
*/
|
||||
if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT ||
|
||||
chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) {
|
||||
@ -192,6 +213,9 @@ int __devinit lola_init_mixer_widget(struct lola *chip, int nid)
|
||||
(((1U << chip->mixer.dest_phys_outs) - 1)
|
||||
<< chip->mixer.dest_phys_out_ofs);
|
||||
|
||||
snd_printdd("Mixer src_mask=%x, dest_mask=%x\n",
|
||||
chip->mixer.src_mask, chip->mixer.dest_mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -202,12 +226,19 @@ static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id,
|
||||
|
||||
if (!(chip->mixer.src_mask & (1 << id)))
|
||||
return -EINVAL;
|
||||
writew(gain, &chip->mixer.array->src_gain[id]);
|
||||
oldval = val = readl(&chip->mixer.array->src_gain_enable);
|
||||
if (on)
|
||||
val |= (1 << id);
|
||||
else
|
||||
val &= ~(1 << id);
|
||||
/* test if values unchanged */
|
||||
if ((val == oldval) &&
|
||||
(gain == readw(&chip->mixer.array->src_gain[id])))
|
||||
return 0;
|
||||
|
||||
snd_printdd("lola_mixer_set_src_gain (id=%d, gain=%d) enable=%x\n",
|
||||
id, gain, val);
|
||||
writew(gain, &chip->mixer.array->src_gain[id]);
|
||||
writel(val, &chip->mixer.array->src_gain_enable);
|
||||
lola_codec_flush(chip);
|
||||
/* inform micro-controller about the new source gain */
|
||||
@ -269,6 +300,7 @@ static int lola_mixer_set_mapping_gain(struct lola *chip,
|
||||
src, dest);
|
||||
}
|
||||
|
||||
#if 0 /* not used */
|
||||
static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
|
||||
unsigned int mask, unsigned short *gains)
|
||||
{
|
||||
@ -289,6 +321,7 @@ static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id,
|
||||
return lola_codec_write(chip, chip->mixer.nid,
|
||||
LOLA_VERB_SET_DESTINATION_GAIN, id, 0);
|
||||
}
|
||||
#endif /* not used */
|
||||
|
||||
/*
|
||||
*/
|
||||
@ -376,6 +409,8 @@ static int set_analog_volume(struct lola *chip, int dir,
|
||||
return 0;
|
||||
if (external_call)
|
||||
lola_codec_flush(chip);
|
||||
snd_printdd("set_analog_volume (dir=%d idx=%d, volume=%d)\n",
|
||||
dir, idx, val);
|
||||
err = lola_codec_write(chip, pin->nid,
|
||||
LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0);
|
||||
if (err < 0)
|
||||
@ -427,23 +462,40 @@ static int init_mixer_values(struct lola *chip)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* all src on */
|
||||
/* all sample rate converters on */
|
||||
lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false);
|
||||
|
||||
/* clear all matrix */
|
||||
/* clear all mixer matrix settings */
|
||||
memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array));
|
||||
/* set src gain to 0dB */
|
||||
/* inform firmware about all updated matrix columns - capture part */
|
||||
for (i = 0; i < chip->mixer.dest_stream_ins; i++)
|
||||
lola_codec_write(chip, chip->mixer.nid,
|
||||
LOLA_VERB_SET_DESTINATION_GAIN,
|
||||
i, 0);
|
||||
/* inform firmware about all updated matrix columns - output part */
|
||||
for (i = 0; i < chip->mixer.dest_phys_outs; i++)
|
||||
lola_codec_write(chip, chip->mixer.nid,
|
||||
LOLA_VERB_SET_DESTINATION_GAIN,
|
||||
chip->mixer.dest_phys_out_ofs + i, 0);
|
||||
|
||||
/* set all digital input source (master) gains to 0dB */
|
||||
for (i = 0; i < chip->mixer.src_phys_ins; i++)
|
||||
lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */
|
||||
|
||||
/* set all digital playback source (master) gains to 0dB */
|
||||
for (i = 0; i < chip->mixer.src_stream_outs; i++)
|
||||
lola_mixer_set_src_gain(chip,
|
||||
i + chip->mixer.src_stream_out_ofs,
|
||||
336, true); /* 0dB */
|
||||
/* set 1:1 dest gain */
|
||||
/* set gain value 0dB diagonally in matrix - part INPUT -> CAPTURE */
|
||||
for (i = 0; i < chip->mixer.dest_stream_ins; i++) {
|
||||
int src = i % chip->mixer.src_phys_ins;
|
||||
lola_mixer_set_mapping_gain(chip, src, i, 336, true);
|
||||
}
|
||||
/* set gain value 0dB diagonally in matrix , part PLAYBACK -> OUTPUT
|
||||
* (LoLa280 : playback channel 0,2,4,6 linked to output channel 0)
|
||||
* (LoLa280 : playback channel 1,3,5,7 linked to output channel 1)
|
||||
*/
|
||||
for (i = 0; i < chip->mixer.src_stream_outs; i++) {
|
||||
int src = chip->mixer.src_stream_out_ofs + i;
|
||||
int dst = chip->mixer.dest_phys_out_ofs +
|
||||
@ -693,6 +745,7 @@ static int __devinit create_src_gain_mixer(struct lola *chip,
|
||||
snd_ctl_new1(&lola_src_gain_mixer, chip));
|
||||
}
|
||||
|
||||
#if 0 /* not used */
|
||||
/*
|
||||
* destination gain (matrix-like) mixer
|
||||
*/
|
||||
@ -781,6 +834,7 @@ static int __devinit create_dest_gain_mixer(struct lola *chip,
|
||||
return snd_ctl_add(chip->card,
|
||||
snd_ctl_new1(&lola_dest_gain_mixer, chip));
|
||||
}
|
||||
#endif /* not used */
|
||||
|
||||
/*
|
||||
*/
|
||||
@ -798,14 +852,16 @@ int __devinit lola_create_mixer(struct lola *chip)
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0,
|
||||
"Line Source Gain Volume");
|
||||
"Digital Capture Volume");
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs,
|
||||
chip->mixer.src_stream_out_ofs,
|
||||
"Stream Source Gain Volume");
|
||||
"Digital Playback Volume");
|
||||
if (err < 0)
|
||||
return err;
|
||||
#if 0
|
||||
/* FIXME: buggy mixer matrix handling */
|
||||
err = create_dest_gain_mixer(chip,
|
||||
chip->mixer.src_phys_ins, 0,
|
||||
chip->mixer.dest_stream_ins, 0,
|
||||
@ -834,6 +890,6 @@ int __devinit lola_create_mixer(struct lola *chip)
|
||||
"Stream Playback Volume");
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
#endif /* FIXME */
|
||||
return init_mixer_values(chip);
|
||||
}
|
||||
|
@ -762,7 +762,6 @@ static int lx_set_granularity(struct lx6464es *chip, u32 gran)
|
||||
static int __devinit lx_init_dsp(struct lx6464es *chip)
|
||||
{
|
||||
int err;
|
||||
u8 mac_address[6];
|
||||
int i;
|
||||
|
||||
snd_printdd("->lx_init_dsp\n");
|
||||
@ -787,11 +786,11 @@ static int __devinit lx_init_dsp(struct lx6464es *chip)
|
||||
/** \todo the mac address should be ready by not, but it isn't,
|
||||
* so we wait for it */
|
||||
for (i = 0; i != 1000; ++i) {
|
||||
err = lx_dsp_get_mac(chip, mac_address);
|
||||
err = lx_dsp_get_mac(chip);
|
||||
if (err)
|
||||
return err;
|
||||
if (mac_address[0] || mac_address[1] || mac_address[2] ||
|
||||
mac_address[3] || mac_address[4] || mac_address[5])
|
||||
if (chip->mac_address[0] || chip->mac_address[1] || chip->mac_address[2] ||
|
||||
chip->mac_address[3] || chip->mac_address[4] || chip->mac_address[5])
|
||||
goto mac_ready;
|
||||
msleep(1);
|
||||
}
|
||||
@ -800,8 +799,8 @@ static int __devinit lx_init_dsp(struct lx6464es *chip)
|
||||
mac_ready:
|
||||
snd_printd(LXP "mac address ready read after: %dms\n", i);
|
||||
snd_printk(LXP "mac address: %02X.%02X.%02X.%02X.%02X.%02X\n",
|
||||
mac_address[0], mac_address[1], mac_address[2],
|
||||
mac_address[3], mac_address[4], mac_address[5]);
|
||||
chip->mac_address[0], chip->mac_address[1], chip->mac_address[2],
|
||||
chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
|
||||
|
||||
err = lx_init_get_version_features(chip);
|
||||
if (err)
|
||||
@ -1031,7 +1030,7 @@ static int __devinit snd_lx6464es_create(struct snd_card *card,
|
||||
chip->port_dsp_bar = pci_ioremap_bar(pci, 2);
|
||||
|
||||
err = request_irq(pci->irq, lx_interrupt, IRQF_SHARED,
|
||||
card_name, chip);
|
||||
KBUILD_MODNAME, chip);
|
||||
if (err) {
|
||||
snd_printk(KERN_ERR LXP "unable to grab IRQ %d\n", pci->irq);
|
||||
goto request_irq_failed;
|
||||
@ -1108,8 +1107,14 @@ static int __devinit snd_lx6464es_probe(struct pci_dev *pci,
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
strcpy(card->driver, "lx6464es");
|
||||
strcpy(card->shortname, "Digigram LX6464ES");
|
||||
strcpy(card->driver, "LX6464ES");
|
||||
sprintf(card->id, "LX6464ES_%02X%02X%02X",
|
||||
chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
|
||||
|
||||
sprintf(card->shortname, "LX6464ES %02X.%02X.%02X.%02X.%02X.%02X",
|
||||
chip->mac_address[0], chip->mac_address[1], chip->mac_address[2],
|
||||
chip->mac_address[3], chip->mac_address[4], chip->mac_address[5]);
|
||||
|
||||
sprintf(card->longname, "%s at 0x%lx, 0x%p, irq %i",
|
||||
card->shortname, chip->port_plx,
|
||||
chip->port_dsp_bar, chip->irq);
|
||||
@ -1137,7 +1142,7 @@ static void __devexit snd_lx6464es_remove(struct pci_dev *pci)
|
||||
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "Digigram LX6464ES",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_lx6464es_ids,
|
||||
.probe = snd_lx6464es_probe,
|
||||
.remove = __devexit_p(snd_lx6464es_remove),
|
||||
|
@ -69,6 +69,8 @@ struct lx6464es {
|
||||
struct pci_dev *pci;
|
||||
int irq;
|
||||
|
||||
u8 mac_address[6];
|
||||
|
||||
spinlock_t lock; /* interrupt spinlock */
|
||||
struct mutex setup_mutex; /* mutex used in hw_params, open
|
||||
* and close */
|
||||
|
@ -424,7 +424,7 @@ int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq)
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address)
|
||||
int lx_dsp_get_mac(struct lx6464es *chip)
|
||||
{
|
||||
u32 macmsb, maclsb;
|
||||
|
||||
@ -432,12 +432,12 @@ int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address)
|
||||
maclsb = lx_dsp_reg_read(chip, eReg_ADMACESLSB) & 0x00FFFFFF;
|
||||
|
||||
/* todo: endianess handling */
|
||||
mac_address[5] = ((u8 *)(&maclsb))[0];
|
||||
mac_address[4] = ((u8 *)(&maclsb))[1];
|
||||
mac_address[3] = ((u8 *)(&maclsb))[2];
|
||||
mac_address[2] = ((u8 *)(&macmsb))[0];
|
||||
mac_address[1] = ((u8 *)(&macmsb))[1];
|
||||
mac_address[0] = ((u8 *)(&macmsb))[2];
|
||||
chip->mac_address[5] = ((u8 *)(&maclsb))[0];
|
||||
chip->mac_address[4] = ((u8 *)(&maclsb))[1];
|
||||
chip->mac_address[3] = ((u8 *)(&maclsb))[2];
|
||||
chip->mac_address[2] = ((u8 *)(&macmsb))[0];
|
||||
chip->mac_address[1] = ((u8 *)(&macmsb))[1];
|
||||
chip->mac_address[0] = ((u8 *)(&macmsb))[2];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ int __devinit lx_dsp_get_version(struct lx6464es *chip, u32 *rdsp_version);
|
||||
int lx_dsp_get_clock_frequency(struct lx6464es *chip, u32 *rfreq);
|
||||
int lx_dsp_set_granularity(struct lx6464es *chip, u32 gran);
|
||||
int lx_dsp_read_async_events(struct lx6464es *chip, u32 *data);
|
||||
int lx_dsp_get_mac(struct lx6464es *chip, u8 *mac_address);
|
||||
int lx_dsp_get_mac(struct lx6464es *chip);
|
||||
|
||||
|
||||
/* low-level pipe handling */
|
||||
|
@ -850,11 +850,10 @@ struct snd_m3 {
|
||||
struct input_dev *input_dev;
|
||||
char phys[64]; /* physical device path */
|
||||
#else
|
||||
spinlock_t ac97_lock;
|
||||
struct snd_kcontrol *master_switch;
|
||||
struct snd_kcontrol *master_volume;
|
||||
struct tasklet_struct hwvol_tq;
|
||||
#endif
|
||||
struct work_struct hwvol_work;
|
||||
|
||||
unsigned int in_suspend;
|
||||
|
||||
@ -1609,13 +1608,10 @@ static void snd_m3_update_ptr(struct snd_m3 *chip, struct m3_dma *s)
|
||||
(without wrap around) in response to volume button presses and then
|
||||
generating an interrupt. The pair of counters is stored in bits 1-3 and 5-7
|
||||
of a byte wide register. The meaning of bits 0 and 4 is unknown. */
|
||||
static void snd_m3_update_hw_volume(unsigned long private_data)
|
||||
static void snd_m3_update_hw_volume(struct work_struct *work)
|
||||
{
|
||||
struct snd_m3 *chip = (struct snd_m3 *) private_data;
|
||||
struct snd_m3 *chip = container_of(work, struct snd_m3, hwvol_work);
|
||||
int x, val;
|
||||
#ifndef CONFIG_SND_MAESTRO3_INPUT
|
||||
unsigned long flags;
|
||||
#endif
|
||||
|
||||
/* Figure out which volume control button was pushed,
|
||||
based on differences from the default register
|
||||
@ -1645,21 +1641,13 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
|
||||
if (!chip->master_switch || !chip->master_volume)
|
||||
return;
|
||||
|
||||
/* FIXME: we can't call snd_ac97_* functions since here is in tasklet. */
|
||||
spin_lock_irqsave(&chip->ac97_lock, flags);
|
||||
|
||||
val = chip->ac97->regs[AC97_MASTER_VOL];
|
||||
val = snd_ac97_read(chip->ac97, AC97_MASTER);
|
||||
switch (x) {
|
||||
case 0x88:
|
||||
/* The counters have not changed, yet we've received a HV
|
||||
interrupt. According to tests run by various people this
|
||||
happens when pressing the mute button. */
|
||||
val ^= 0x8000;
|
||||
chip->ac97->regs[AC97_MASTER_VOL] = val;
|
||||
outw(val, chip->iobase + CODEC_DATA);
|
||||
outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND);
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&chip->master_switch->id);
|
||||
break;
|
||||
case 0xaa:
|
||||
/* counters increased by 1 -> volume up */
|
||||
@ -1667,11 +1655,6 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
|
||||
val--;
|
||||
if ((val & 0x7f00) > 0)
|
||||
val -= 0x0100;
|
||||
chip->ac97->regs[AC97_MASTER_VOL] = val;
|
||||
outw(val, chip->iobase + CODEC_DATA);
|
||||
outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND);
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&chip->master_volume->id);
|
||||
break;
|
||||
case 0x66:
|
||||
/* counters decreased by 1 -> volume down */
|
||||
@ -1679,14 +1662,11 @@ static void snd_m3_update_hw_volume(unsigned long private_data)
|
||||
val++;
|
||||
if ((val & 0x7f00) < 0x1f00)
|
||||
val += 0x0100;
|
||||
chip->ac97->regs[AC97_MASTER_VOL] = val;
|
||||
outw(val, chip->iobase + CODEC_DATA);
|
||||
outb(AC97_MASTER_VOL, chip->iobase + CODEC_COMMAND);
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&chip->master_volume->id);
|
||||
break;
|
||||
}
|
||||
spin_unlock_irqrestore(&chip->ac97_lock, flags);
|
||||
if (snd_ac97_update(chip->ac97, AC97_MASTER, val))
|
||||
snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE,
|
||||
&chip->master_switch->id);
|
||||
#else
|
||||
if (!chip->input_dev)
|
||||
return;
|
||||
@ -1730,11 +1710,7 @@ static irqreturn_t snd_m3_interrupt(int irq, void *dev_id)
|
||||
return IRQ_NONE;
|
||||
|
||||
if (status & HV_INT_PENDING)
|
||||
#ifdef CONFIG_SND_MAESTRO3_INPUT
|
||||
snd_m3_update_hw_volume((unsigned long)chip);
|
||||
#else
|
||||
tasklet_schedule(&chip->hwvol_tq);
|
||||
#endif
|
||||
schedule_work(&chip->hwvol_work);
|
||||
|
||||
/*
|
||||
* ack an assp int if its running
|
||||
@ -2000,24 +1976,14 @@ static unsigned short
|
||||
snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
|
||||
{
|
||||
struct snd_m3 *chip = ac97->private_data;
|
||||
#ifndef CONFIG_SND_MAESTRO3_INPUT
|
||||
unsigned long flags;
|
||||
#endif
|
||||
unsigned short data = 0xffff;
|
||||
|
||||
if (snd_m3_ac97_wait(chip))
|
||||
goto fail;
|
||||
#ifndef CONFIG_SND_MAESTRO3_INPUT
|
||||
spin_lock_irqsave(&chip->ac97_lock, flags);
|
||||
#endif
|
||||
snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND);
|
||||
if (snd_m3_ac97_wait(chip))
|
||||
goto fail_unlock;
|
||||
goto fail;
|
||||
data = snd_m3_inw(chip, CODEC_DATA);
|
||||
fail_unlock:
|
||||
#ifndef CONFIG_SND_MAESTRO3_INPUT
|
||||
spin_unlock_irqrestore(&chip->ac97_lock, flags);
|
||||
#endif
|
||||
fail:
|
||||
return data;
|
||||
}
|
||||
@ -2026,20 +1992,11 @@ static void
|
||||
snd_m3_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
|
||||
{
|
||||
struct snd_m3 *chip = ac97->private_data;
|
||||
#ifndef CONFIG_SND_MAESTRO3_INPUT
|
||||
unsigned long flags;
|
||||
#endif
|
||||
|
||||
if (snd_m3_ac97_wait(chip))
|
||||
return;
|
||||
#ifndef CONFIG_SND_MAESTRO3_INPUT
|
||||
spin_lock_irqsave(&chip->ac97_lock, flags);
|
||||
#endif
|
||||
snd_m3_outw(chip, val, CODEC_DATA);
|
||||
snd_m3_outb(chip, reg & 0x7f, CODEC_COMMAND);
|
||||
#ifndef CONFIG_SND_MAESTRO3_INPUT
|
||||
spin_unlock_irqrestore(&chip->ac97_lock, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -2458,6 +2415,7 @@ static int snd_m3_free(struct snd_m3 *chip)
|
||||
struct m3_dma *s;
|
||||
int i;
|
||||
|
||||
cancel_work_sync(&chip->hwvol_work);
|
||||
#ifdef CONFIG_SND_MAESTRO3_INPUT
|
||||
if (chip->input_dev)
|
||||
input_unregister_device(chip->input_dev);
|
||||
@ -2511,6 +2469,7 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state)
|
||||
return 0;
|
||||
|
||||
chip->in_suspend = 1;
|
||||
cancel_work_sync(&chip->hwvol_work);
|
||||
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
|
||||
snd_pcm_suspend_all(chip->pcm);
|
||||
snd_ac97_suspend(chip->ac97);
|
||||
@ -2667,9 +2626,6 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
|
||||
}
|
||||
|
||||
spin_lock_init(&chip->reg_lock);
|
||||
#ifndef CONFIG_SND_MAESTRO3_INPUT
|
||||
spin_lock_init(&chip->ac97_lock);
|
||||
#endif
|
||||
|
||||
switch (pci->device) {
|
||||
case PCI_DEVICE_ID_ESS_ALLEGRO:
|
||||
@ -2683,6 +2639,7 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
|
||||
chip->card = card;
|
||||
chip->pci = pci;
|
||||
chip->irq = -1;
|
||||
INIT_WORK(&chip->hwvol_work, snd_m3_update_hw_volume);
|
||||
|
||||
chip->external_amp = enable_amp;
|
||||
if (amp_gpio >= 0 && amp_gpio <= 0x0f)
|
||||
@ -2752,12 +2709,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
|
||||
|
||||
snd_m3_hv_init(chip);
|
||||
|
||||
#ifndef CONFIG_SND_MAESTRO3_INPUT
|
||||
tasklet_init(&chip->hwvol_tq, snd_m3_update_hw_volume, (unsigned long)chip);
|
||||
#endif
|
||||
|
||||
if (request_irq(pci->irq, snd_m3_interrupt, IRQF_SHARED,
|
||||
card->driver, chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_m3_free(chip);
|
||||
return -ENOMEM;
|
||||
@ -2885,7 +2838,7 @@ static void __devexit snd_m3_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "Maestro3",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_m3_ids,
|
||||
.probe = snd_m3_probe,
|
||||
.remove = __devexit_p(snd_m3_remove),
|
||||
|
@ -1268,7 +1268,7 @@ static int __devinit snd_mixart_probe(struct pci_dev *pci,
|
||||
}
|
||||
|
||||
if (request_irq(pci->irq, snd_mixart_interrupt, IRQF_SHARED,
|
||||
CARD_NAME, mgr)) {
|
||||
KBUILD_MODNAME, mgr)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_mixart_free(mgr);
|
||||
return -EBUSY;
|
||||
@ -1381,7 +1381,7 @@ static void __devexit snd_mixart_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "Digigram miXart",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_mixart_ids,
|
||||
.probe = snd_mixart_probe,
|
||||
.remove = __devexit_p(snd_mixart_remove),
|
||||
|
@ -465,7 +465,7 @@ static int snd_nm256_acquire_irq(struct nm256 *chip)
|
||||
mutex_lock(&chip->irq_mutex);
|
||||
if (chip->irq < 0) {
|
||||
if (request_irq(chip->pci->irq, chip->interrupt, IRQF_SHARED,
|
||||
chip->card->driver, chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", chip->pci->irq);
|
||||
mutex_unlock(&chip->irq_mutex);
|
||||
return -EBUSY;
|
||||
@ -1743,7 +1743,7 @@ static void __devexit snd_nm256_remove(struct pci_dev *pci)
|
||||
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "NeoMagic 256",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_nm256_ids,
|
||||
.probe = snd_nm256_probe,
|
||||
.remove = __devexit_p(snd_nm256_remove),
|
||||
|
@ -859,7 +859,7 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci,
|
||||
}
|
||||
|
||||
static struct pci_driver oxygen_driver = {
|
||||
.name = "CMI8788",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = oxygen_ids,
|
||||
.probe = generic_oxygen_probe,
|
||||
.remove = __devexit_p(oxygen_pci_remove),
|
||||
|
@ -655,7 +655,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id,
|
||||
chip->model.init(chip);
|
||||
|
||||
err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED,
|
||||
DRIVER, chip);
|
||||
KBUILD_MODNAME, chip);
|
||||
if (err < 0) {
|
||||
snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq);
|
||||
goto err_card;
|
||||
|
@ -168,12 +168,6 @@ static int oxygen_open(struct snd_pcm_substream *substream,
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
if (channel == PCM_MULTICH) {
|
||||
err = snd_pcm_hw_constraint_minmax
|
||||
(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, 0, 8192000);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
snd_pcm_set_sync(substream);
|
||||
chip->streams[channel] = substream;
|
||||
|
||||
|
@ -88,7 +88,7 @@ static int __devinit xonar_probe(struct pci_dev *pci,
|
||||
}
|
||||
|
||||
static struct pci_driver xonar_driver = {
|
||||
.name = "AV200",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = xonar_ids,
|
||||
.probe = xonar_probe,
|
||||
.remove = __devexit_p(oxygen_pci_remove),
|
||||
|
@ -327,8 +327,10 @@ static void pcm1796_init(struct oxygen *chip)
|
||||
{
|
||||
struct xonar_pcm179x *data = chip->model_data;
|
||||
|
||||
data->pcm1796_regs[0][18 - PCM1796_REG_BASE] = PCM1796_MUTE |
|
||||
data->pcm1796_regs[0][18 - PCM1796_REG_BASE] =
|
||||
PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
|
||||
if (!data->broken_i2c)
|
||||
data->pcm1796_regs[0][18 - PCM1796_REG_BASE] |= PCM1796_MUTE;
|
||||
data->pcm1796_regs[0][19 - PCM1796_REG_BASE] =
|
||||
PCM1796_FLT_SHARP | PCM1796_ATS_1;
|
||||
data->pcm1796_regs[0][20 - PCM1796_REG_BASE] =
|
||||
@ -1123,6 +1125,7 @@ int __devinit get_xonar_pcm179x_model(struct oxygen *chip,
|
||||
chip->model.control_filter = xonar_st_h6_control_filter;
|
||||
chip->model.dac_channels_pcm = 8;
|
||||
chip->model.dac_channels_mixer = 8;
|
||||
chip->model.dac_volume_min = 255;
|
||||
chip->model.dac_mclks = OXYGEN_MCLKS(256, 128, 128);
|
||||
break;
|
||||
}
|
||||
|
@ -1501,7 +1501,7 @@ static int __devinit pcxhr_probe(struct pci_dev *pci,
|
||||
mgr->irq = -1;
|
||||
|
||||
if (request_irq(pci->irq, pcxhr_interrupt, IRQF_SHARED,
|
||||
card_name, mgr)) {
|
||||
KBUILD_MODNAME, mgr)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
pcxhr_free(mgr);
|
||||
return -EBUSY;
|
||||
@ -1608,7 +1608,7 @@ static void __devexit pcxhr_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "Digigram pcxhr",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = pcxhr_ids,
|
||||
.probe = pcxhr_probe,
|
||||
.remove = __devexit_p(pcxhr_remove),
|
||||
|
@ -1890,7 +1890,7 @@ snd_riptide_create(struct snd_card *card, struct pci_dev *pci,
|
||||
UNSET_AIE(hwport);
|
||||
|
||||
if (request_irq(pci->irq, snd_riptide_interrupt, IRQF_SHARED,
|
||||
"RIPTIDE", chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "Riptide: unable to grab IRQ %d\n",
|
||||
pci->irq);
|
||||
snd_riptide_free(chip);
|
||||
@ -2176,7 +2176,7 @@ static void __devexit snd_card_riptide_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "RIPTIDE",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_riptide_ids,
|
||||
.probe = snd_card_riptide_probe,
|
||||
.remove = __devexit_p(snd_card_riptide_remove),
|
||||
@ -2188,7 +2188,7 @@ static struct pci_driver driver = {
|
||||
|
||||
#ifdef SUPPORT_JOYSTICK
|
||||
static struct pci_driver joystick_driver = {
|
||||
.name = "Riptide Joystick",
|
||||
.name = KBUILD_MODNAME "-joystick",
|
||||
.id_table = snd_riptide_joystick_ids,
|
||||
.probe = snd_riptide_joystick_probe,
|
||||
.remove = __devexit_p(snd_riptide_joystick_remove),
|
||||
|
@ -1355,7 +1355,7 @@ static int __devinit snd_rme32_create(struct rme32 * rme32)
|
||||
}
|
||||
|
||||
if (request_irq(pci->irq, snd_rme32_interrupt, IRQF_SHARED,
|
||||
"RME32", rme32)) {
|
||||
KBUILD_MODNAME, rme32)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
return -EBUSY;
|
||||
}
|
||||
@ -1985,7 +1985,7 @@ static void __devexit snd_rme32_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "RME Digi32",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_rme32_ids,
|
||||
.probe = snd_rme32_probe,
|
||||
.remove = __devexit_p(snd_rme32_remove),
|
||||
|
@ -1561,7 +1561,7 @@ snd_rme96_create(struct rme96 *rme96)
|
||||
}
|
||||
|
||||
if (request_irq(pci->irq, snd_rme96_interrupt, IRQF_SHARED,
|
||||
"RME96", rme96)) {
|
||||
KBUILD_MODNAME, rme96)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
return -EBUSY;
|
||||
}
|
||||
@ -2396,7 +2396,7 @@ static void __devexit snd_rme96_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "RME Digi96",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_rme96_ids,
|
||||
.probe = snd_rme96_probe,
|
||||
.remove = __devexit_p(snd_rme96_remove),
|
||||
|
@ -5482,7 +5482,7 @@ static int __devinit snd_hdsp_create(struct snd_card *card,
|
||||
}
|
||||
|
||||
if (request_irq(pci->irq, snd_hdsp_interrupt, IRQF_SHARED,
|
||||
"hdsp", hdsp)) {
|
||||
KBUILD_MODNAME, hdsp)) {
|
||||
snd_printk(KERN_ERR "Hammerfall-DSP: unable to use IRQ %d\n", pci->irq);
|
||||
return -EBUSY;
|
||||
}
|
||||
@ -5637,7 +5637,7 @@ static void __devexit snd_hdsp_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "RME Hammerfall DSP",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_hdsp_ids,
|
||||
.probe = snd_hdsp_probe,
|
||||
.remove = __devexit_p(snd_hdsp_remove),
|
||||
|
@ -6441,7 +6441,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card,
|
||||
hdspm->port + io_extent - 1);
|
||||
|
||||
if (request_irq(pci->irq, snd_hdspm_interrupt,
|
||||
IRQF_SHARED, "hdspm", hdspm)) {
|
||||
IRQF_SHARED, KBUILD_MODNAME, hdspm)) {
|
||||
snd_printk(KERN_ERR "HDSPM: unable to use IRQ %d\n", pci->irq);
|
||||
return -EBUSY;
|
||||
}
|
||||
@ -6779,7 +6779,7 @@ static void __devexit snd_hdspm_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "RME Hammerfall DSP MADI",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_hdspm_ids,
|
||||
.probe = snd_hdspm_probe,
|
||||
.remove = __devexit_p(snd_hdspm_remove),
|
||||
|
@ -2479,7 +2479,7 @@ static int __devinit snd_rme9652_create(struct snd_card *card,
|
||||
}
|
||||
|
||||
if (request_irq(pci->irq, snd_rme9652_interrupt, IRQF_SHARED,
|
||||
"rme9652", rme9652)) {
|
||||
KBUILD_MODNAME, rme9652)) {
|
||||
snd_printk(KERN_ERR "unable to request IRQ %d\n", pci->irq);
|
||||
return -EBUSY;
|
||||
}
|
||||
@ -2632,7 +2632,7 @@ static void __devexit snd_rme9652_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "RME Digi9652 (Hammerfall)",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_rme9652_ids,
|
||||
.probe = snd_rme9652_probe,
|
||||
.remove = __devexit_p(snd_rme9652_remove),
|
||||
|
@ -1235,7 +1235,7 @@ static int sis_resume(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED,
|
||||
card->shortname, sis)) {
|
||||
KBUILD_MODNAME, sis)) {
|
||||
printk(KERN_ERR "sis7019: unable to regain IRQ %d\n", pci->irq);
|
||||
goto error;
|
||||
}
|
||||
@ -1341,7 +1341,7 @@ static int __devinit sis_chip_create(struct snd_card *card,
|
||||
goto error_out_cleanup;
|
||||
|
||||
if (request_irq(pci->irq, sis_interrupt, IRQF_DISABLED|IRQF_SHARED,
|
||||
card->shortname, sis)) {
|
||||
KBUILD_MODNAME, sis)) {
|
||||
printk(KERN_ERR "unable to allocate irq %d\n", sis->irq);
|
||||
goto error_out_cleanup;
|
||||
}
|
||||
@ -1436,7 +1436,7 @@ static void __devexit snd_sis7019_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver sis7019_driver = {
|
||||
.name = "SiS7019",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_sis7019_ids,
|
||||
.probe = snd_sis7019_probe,
|
||||
.remove = __devexit_p(snd_sis7019_remove),
|
||||
|
@ -1294,7 +1294,7 @@ static int __devinit snd_sonicvibes_create(struct snd_card *card,
|
||||
sonic->game_port = pci_resource_start(pci, 4);
|
||||
|
||||
if (request_irq(pci->irq, snd_sonicvibes_interrupt, IRQF_SHARED,
|
||||
"S3 SonicVibes", sonic)) {
|
||||
KBUILD_MODNAME, sonic)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_sonicvibes_free(sonic);
|
||||
return -EBUSY;
|
||||
@ -1530,7 +1530,7 @@ static void __devexit snd_sonic_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "S3 SonicVibes",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_sonic_ids,
|
||||
.probe = snd_sonic_probe,
|
||||
.remove = __devexit_p(snd_sonic_remove),
|
||||
|
@ -172,7 +172,7 @@ static void __devexit snd_trident_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "Trident4DWaveAudio",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_trident_ids,
|
||||
.probe = snd_trident_probe,
|
||||
.remove = __devexit_p(snd_trident_remove),
|
||||
|
@ -3598,7 +3598,7 @@ int __devinit snd_trident_create(struct snd_card *card,
|
||||
trident->port = pci_resource_start(pci, 0);
|
||||
|
||||
if (request_irq(pci->irq, snd_trident_interrupt, IRQF_SHARED,
|
||||
"Trident Audio", trident)) {
|
||||
KBUILD_MODNAME, trident)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_trident_free(trident);
|
||||
return -EBUSY;
|
||||
|
@ -2377,7 +2377,7 @@ static int __devinit snd_via82xx_create(struct snd_card *card,
|
||||
chip_type == TYPE_VIA8233 ?
|
||||
snd_via8233_interrupt : snd_via686_interrupt,
|
||||
IRQF_SHARED,
|
||||
card->driver, chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_via82xx_free(chip);
|
||||
return -EBUSY;
|
||||
@ -2611,7 +2611,7 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "VIA 82xx Audio",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_via82xx_ids,
|
||||
.probe = snd_via82xx_probe,
|
||||
.remove = __devexit_p(snd_via82xx_remove),
|
||||
|
@ -1129,7 +1129,7 @@ static int __devinit snd_via82xx_create(struct snd_card *card,
|
||||
}
|
||||
chip->port = pci_resource_start(pci, 0);
|
||||
if (request_irq(pci->irq, snd_via82xx_interrupt, IRQF_SHARED,
|
||||
card->driver, chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_via82xx_free(chip);
|
||||
return -EBUSY;
|
||||
@ -1224,7 +1224,7 @@ static void __devexit snd_via82xx_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "VIA 82xx Modem",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_via82xx_modem_ids,
|
||||
.probe = snd_via82xx_probe,
|
||||
.remove = __devexit_p(snd_via82xx_remove),
|
||||
|
@ -169,7 +169,7 @@ static int __devinit snd_vx222_create(struct snd_card *card, struct pci_dev *pci
|
||||
vx->port[i] = pci_resource_start(pci, i + 1);
|
||||
|
||||
if (request_irq(pci->irq, snd_vx_irq_handler, IRQF_SHARED,
|
||||
CARD_NAME, chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_vx222_free(chip);
|
||||
return -EBUSY;
|
||||
@ -290,7 +290,7 @@ static int snd_vx222_resume(struct pci_dev *pci)
|
||||
#endif
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "Digigram VX222",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_vx222_ids,
|
||||
.probe = snd_vx222_probe,
|
||||
.remove = __devexit_p(snd_vx222_remove),
|
||||
|
@ -345,7 +345,7 @@ static void __devexit snd_card_ymfpci_remove(struct pci_dev *pci)
|
||||
}
|
||||
|
||||
static struct pci_driver driver = {
|
||||
.name = "Yamaha DS-1 PCI",
|
||||
.name = KBUILD_MODNAME,
|
||||
.id_table = snd_ymfpci_ids,
|
||||
.probe = snd_card_ymfpci_probe,
|
||||
.remove = __devexit_p(snd_card_ymfpci_remove),
|
||||
|
@ -2380,7 +2380,7 @@ int __devinit snd_ymfpci_create(struct snd_card *card,
|
||||
return -EBUSY;
|
||||
}
|
||||
if (request_irq(pci->irq, snd_ymfpci_interrupt, IRQF_SHARED,
|
||||
"YMFPCI", chip)) {
|
||||
KBUILD_MODNAME, chip)) {
|
||||
snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq);
|
||||
snd_ymfpci_free(chip);
|
||||
return -EBUSY;
|
||||
|
@ -223,7 +223,7 @@ static int pdacf_config(struct pcmcia_device *link)
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_exclusive_irq(link, pdacf_interrupt);
|
||||
ret = pcmcia_request_irq(link, pdacf_interrupt);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
|
@ -229,7 +229,7 @@ static int vxpocket_config(struct pcmcia_device *link)
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_exclusive_irq(link, snd_vx_irq_handler);
|
||||
ret = pcmcia_request_irq(link, snd_vx_irq_handler);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
|
@ -433,9 +433,10 @@ static int snd_usb_audio_create(struct usb_device *dev, int idx,
|
||||
* only at the first time. the successive calls of this function will
|
||||
* append the pcm interface to the corresponding card.
|
||||
*/
|
||||
static void *snd_usb_audio_probe(struct usb_device *dev,
|
||||
struct usb_interface *intf,
|
||||
const struct usb_device_id *usb_id)
|
||||
static struct snd_usb_audio *
|
||||
snd_usb_audio_probe(struct usb_device *dev,
|
||||
struct usb_interface *intf,
|
||||
const struct usb_device_id *usb_id)
|
||||
{
|
||||
const struct snd_usb_audio_quirk *quirk = (const struct snd_usb_audio_quirk *)usb_id->driver_info;
|
||||
int i, err;
|
||||
@ -540,16 +541,15 @@ static void *snd_usb_audio_probe(struct usb_device *dev,
|
||||
* we need to take care of counter, since disconnection can be called also
|
||||
* many times as well as usb_audio_probe().
|
||||
*/
|
||||
static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
|
||||
static void snd_usb_audio_disconnect(struct usb_device *dev,
|
||||
struct snd_usb_audio *chip)
|
||||
{
|
||||
struct snd_usb_audio *chip;
|
||||
struct snd_card *card;
|
||||
struct list_head *p;
|
||||
|
||||
if (ptr == (void *)-1L)
|
||||
if (chip == (void *)-1L)
|
||||
return;
|
||||
|
||||
chip = ptr;
|
||||
card = chip->card;
|
||||
mutex_lock(®ister_mutex);
|
||||
mutex_lock(&chip->shutdown_mutex);
|
||||
@ -585,7 +585,7 @@ static void snd_usb_audio_disconnect(struct usb_device *dev, void *ptr)
|
||||
static int usb_audio_probe(struct usb_interface *intf,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
void *chip;
|
||||
struct snd_usb_audio *chip;
|
||||
chip = snd_usb_audio_probe(interface_to_usbdev(intf), intf, id);
|
||||
if (chip) {
|
||||
usb_set_intfdata(intf, chip);
|
||||
|
@ -408,6 +408,8 @@ int snd_usb_parse_audio_endpoints(struct snd_usb_audio *chip, int iface_no)
|
||||
/* doesn't set the sample rate attribute, but supports it */
|
||||
fp->attributes |= UAC_EP_CS_ATTR_SAMPLE_RATE;
|
||||
break;
|
||||
case USB_ID(0x0763, 0x2001): /* M-Audio Quattro USB */
|
||||
case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */
|
||||
case USB_ID(0x047f, 0x0ca1): /* plantronics headset */
|
||||
case USB_ID(0x077d, 0x07af): /* Griffin iMic (note that there is
|
||||
an older model 77d:223) */
|
||||
|
@ -645,7 +645,7 @@ static int set_stream_hw(struct ua101 *ua, struct snd_pcm_substream *substream,
|
||||
err = snd_pcm_hw_constraint_minmax(substream->runtime,
|
||||
SNDRV_PCM_HW_PARAM_PERIOD_TIME,
|
||||
1500000 / ua->packets_per_second,
|
||||
8192000);
|
||||
UINT_MAX);
|
||||
if (err < 0)
|
||||
return err;
|
||||
err = snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24);
|
||||
|
@ -1677,6 +1677,36 @@ YAMAHA_DEVICE(0x7010, "UB99"),
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
USB_DEVICE(0x0582, 0x011e),
|
||||
.driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {
|
||||
/* .vendor_name = "BOSS", */
|
||||
/* .product_name = "BR-800", */
|
||||
.ifnum = QUIRK_ANY_INTERFACE,
|
||||
.type = QUIRK_COMPOSITE,
|
||||
.data = (const struct snd_usb_audio_quirk[]) {
|
||||
{
|
||||
.ifnum = 0,
|
||||
.type = QUIRK_AUDIO_STANDARD_INTERFACE
|
||||
},
|
||||
{
|
||||
.ifnum = 1,
|
||||
.type = QUIRK_AUDIO_STANDARD_INTERFACE
|
||||
},
|
||||
{
|
||||
.ifnum = 2,
|
||||
.type = QUIRK_MIDI_FIXED_ENDPOINT,
|
||||
.data = & (const struct snd_usb_midi_endpoint_info) {
|
||||
.out_cables = 0x0001,
|
||||
.in_cables = 0x0001
|
||||
}
|
||||
},
|
||||
{
|
||||
.ifnum = -1
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/* Guillemot devices */
|
||||
{
|
||||
|
@ -369,6 +369,30 @@ static int snd_usb_audigy2nx_boot_quirk(struct usb_device *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int snd_usb_fasttrackpro_boot_quirk(struct usb_device *dev)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (dev->actconfig->desc.bConfigurationValue == 1) {
|
||||
snd_printk(KERN_INFO "usb-audio: "
|
||||
"Fast Track Pro switching to config #2\n");
|
||||
/* This function has to be available by the usb core module.
|
||||
* if it is not avialable the boot quirk has to be left out
|
||||
* and the configuration has to be set by udev or hotplug
|
||||
* rules
|
||||
*/
|
||||
err = usb_driver_set_configuration(dev, 2);
|
||||
if (err < 0) {
|
||||
snd_printdd("error usb_driver_set_configuration: %d\n",
|
||||
err);
|
||||
return -ENODEV;
|
||||
}
|
||||
} else
|
||||
snd_printk(KERN_INFO "usb-audio: Fast Track Pro config OK\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* C-Media CM106/CM106+ have four 16-bit internal registers that are nicely
|
||||
* documented in the device's data sheet.
|
||||
@ -471,16 +495,49 @@ static int snd_usb_nativeinstruments_boot_quirk(struct usb_device *dev)
|
||||
/*
|
||||
* Setup quirks
|
||||
*/
|
||||
#define AUDIOPHILE_SET 0x01 /* if set, parse device_setup */
|
||||
#define AUDIOPHILE_SET_DTS 0x02 /* if set, enable DTS Digital Output */
|
||||
#define AUDIOPHILE_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
|
||||
#define AUDIOPHILE_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
|
||||
#define AUDIOPHILE_SET_DI 0x10 /* if set, enable Digital Input */
|
||||
#define AUDIOPHILE_SET_MASK 0x1F /* bit mask for setup value */
|
||||
#define AUDIOPHILE_SET_24B_48K_DI 0x19 /* value for 24bits+48KHz+Digital Input */
|
||||
#define AUDIOPHILE_SET_24B_48K_NOTDI 0x09 /* value for 24bits+48KHz+No Digital Input */
|
||||
#define AUDIOPHILE_SET_16B_48K_DI 0x11 /* value for 16bits+48KHz+Digital Input */
|
||||
#define AUDIOPHILE_SET_16B_48K_NOTDI 0x01 /* value for 16bits+48KHz+No Digital Input */
|
||||
#define MAUDIO_SET 0x01 /* parse device_setup */
|
||||
#define MAUDIO_SET_COMPATIBLE 0x80 /* use only "win-compatible" interfaces */
|
||||
#define MAUDIO_SET_DTS 0x02 /* enable DTS Digital Output */
|
||||
#define MAUDIO_SET_96K 0x04 /* 48-96KHz rate if set, 8-48KHz otherwise */
|
||||
#define MAUDIO_SET_24B 0x08 /* 24bits sample if set, 16bits otherwise */
|
||||
#define MAUDIO_SET_DI 0x10 /* enable Digital Input */
|
||||
#define MAUDIO_SET_MASK 0x1f /* bit mask for setup value */
|
||||
#define MAUDIO_SET_24B_48K_DI 0x19 /* 24bits+48KHz+Digital Input */
|
||||
#define MAUDIO_SET_24B_48K_NOTDI 0x09 /* 24bits+48KHz+No Digital Input */
|
||||
#define MAUDIO_SET_16B_48K_DI 0x11 /* 16bits+48KHz+Digital Input */
|
||||
#define MAUDIO_SET_16B_48K_NOTDI 0x01 /* 16bits+48KHz+No Digital Input */
|
||||
|
||||
static int quattro_skip_setting_quirk(struct snd_usb_audio *chip,
|
||||
int iface, int altno)
|
||||
{
|
||||
/* Reset ALL ifaces to 0 altsetting.
|
||||
* Call it for every possible altsetting of every interface.
|
||||
*/
|
||||
usb_set_interface(chip->dev, iface, 0);
|
||||
if (chip->setup & MAUDIO_SET) {
|
||||
if (chip->setup & MAUDIO_SET_COMPATIBLE) {
|
||||
if (iface != 1 && iface != 2)
|
||||
return 1; /* skip all interfaces but 1 and 2 */
|
||||
} else {
|
||||
unsigned int mask;
|
||||
if (iface == 1 || iface == 2)
|
||||
return 1; /* skip interfaces 1 and 2 */
|
||||
if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
|
||||
return 1; /* skip this altsetting */
|
||||
mask = chip->setup & MAUDIO_SET_MASK;
|
||||
if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
|
||||
return 1; /* skip this altsetting */
|
||||
if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
|
||||
return 1; /* skip this altsetting */
|
||||
if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 4)
|
||||
return 1; /* skip this altsetting */
|
||||
}
|
||||
}
|
||||
snd_printdd(KERN_INFO
|
||||
"using altsetting %d for interface %d config %d\n",
|
||||
altno, iface, chip->setup);
|
||||
return 0; /* keep this altsetting */
|
||||
}
|
||||
|
||||
static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
|
||||
int iface,
|
||||
@ -491,30 +548,65 @@ static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
|
||||
*/
|
||||
usb_set_interface(chip->dev, iface, 0);
|
||||
|
||||
if (chip->setup & AUDIOPHILE_SET) {
|
||||
if ((chip->setup & AUDIOPHILE_SET_DTS)
|
||||
&& altno != 6)
|
||||
if (chip->setup & MAUDIO_SET) {
|
||||
unsigned int mask;
|
||||
if ((chip->setup & MAUDIO_SET_DTS) && altno != 6)
|
||||
return 1; /* skip this altsetting */
|
||||
if ((chip->setup & AUDIOPHILE_SET_96K)
|
||||
&& altno != 1)
|
||||
if ((chip->setup & MAUDIO_SET_96K) && altno != 1)
|
||||
return 1; /* skip this altsetting */
|
||||
if ((chip->setup & AUDIOPHILE_SET_MASK) ==
|
||||
AUDIOPHILE_SET_24B_48K_DI && altno != 2)
|
||||
mask = chip->setup & MAUDIO_SET_MASK;
|
||||
if (mask == MAUDIO_SET_24B_48K_DI && altno != 2)
|
||||
return 1; /* skip this altsetting */
|
||||
if ((chip->setup & AUDIOPHILE_SET_MASK) ==
|
||||
AUDIOPHILE_SET_24B_48K_NOTDI && altno != 3)
|
||||
if (mask == MAUDIO_SET_24B_48K_NOTDI && altno != 3)
|
||||
return 1; /* skip this altsetting */
|
||||
if ((chip->setup & AUDIOPHILE_SET_MASK) ==
|
||||
AUDIOPHILE_SET_16B_48K_DI && altno != 4)
|
||||
if (mask == MAUDIO_SET_16B_48K_DI && altno != 4)
|
||||
return 1; /* skip this altsetting */
|
||||
if ((chip->setup & AUDIOPHILE_SET_MASK) ==
|
||||
AUDIOPHILE_SET_16B_48K_NOTDI && altno != 5)
|
||||
if (mask == MAUDIO_SET_16B_48K_NOTDI && altno != 5)
|
||||
return 1; /* skip this altsetting */
|
||||
}
|
||||
|
||||
return 0; /* keep this altsetting */
|
||||
}
|
||||
|
||||
|
||||
static int fasttrackpro_skip_setting_quirk(struct snd_usb_audio *chip,
|
||||
int iface, int altno)
|
||||
{
|
||||
/* Reset ALL ifaces to 0 altsetting.
|
||||
* Call it for every possible altsetting of every interface.
|
||||
*/
|
||||
usb_set_interface(chip->dev, iface, 0);
|
||||
|
||||
/* possible configuration where both inputs and only one output is
|
||||
*used is not supported by the current setup
|
||||
*/
|
||||
if (chip->setup & (MAUDIO_SET | MAUDIO_SET_24B)) {
|
||||
if (chip->setup & MAUDIO_SET_96K) {
|
||||
if (altno != 3 && altno != 6)
|
||||
return 1;
|
||||
} else if (chip->setup & MAUDIO_SET_DI) {
|
||||
if (iface == 4)
|
||||
return 1; /* no analog input */
|
||||
if (altno != 2 && altno != 5)
|
||||
return 1; /* enable only altsets 2 and 5 */
|
||||
} else {
|
||||
if (iface == 5)
|
||||
return 1; /* disable digialt input */
|
||||
if (altno != 2 && altno != 5)
|
||||
return 1; /* enalbe only altsets 2 and 5 */
|
||||
}
|
||||
} else {
|
||||
/* keep only 16-Bit mode */
|
||||
if (altno != 1)
|
||||
return 1;
|
||||
}
|
||||
|
||||
snd_printdd(KERN_INFO
|
||||
"using altsetting %d for interface %d config %d\n",
|
||||
altno, iface, chip->setup);
|
||||
return 0; /* keep this altsetting */
|
||||
}
|
||||
|
||||
int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
|
||||
int iface,
|
||||
int altno)
|
||||
@ -522,6 +614,12 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip,
|
||||
/* audiophile usb: skip altsets incompatible with device_setup */
|
||||
if (chip->usb_id == USB_ID(0x0763, 0x2003))
|
||||
return audiophile_skip_setting_quirk(chip, iface, altno);
|
||||
/* quattro usb: skip altsets incompatible with device_setup */
|
||||
if (chip->usb_id == USB_ID(0x0763, 0x2001))
|
||||
return quattro_skip_setting_quirk(chip, iface, altno);
|
||||
/* fasttrackpro usb: skip altsets incompatible with device_setup */
|
||||
if (chip->usb_id == USB_ID(0x0763, 0x2012))
|
||||
return fasttrackpro_skip_setting_quirk(chip, iface, altno);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -560,6 +658,8 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
|
||||
case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */
|
||||
case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */
|
||||
return snd_usb_nativeinstruments_boot_quirk(dev);
|
||||
case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro USB */
|
||||
return snd_usb_fasttrackpro_boot_quirk(dev);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -570,15 +670,24 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev,
|
||||
*/
|
||||
int snd_usb_is_big_endian_format(struct snd_usb_audio *chip, struct audioformat *fp)
|
||||
{
|
||||
/* it depends on altsetting wether the device is big-endian or not */
|
||||
switch (chip->usb_id) {
|
||||
case USB_ID(0x0763, 0x2001): /* M-Audio Quattro: captured data only */
|
||||
if (fp->endpoint & USB_DIR_IN)
|
||||
if (fp->altsetting == 2 || fp->altsetting == 3 ||
|
||||
fp->altsetting == 5 || fp->altsetting == 6)
|
||||
return 1;
|
||||
break;
|
||||
case USB_ID(0x0763, 0x2003): /* M-Audio Audiophile USB */
|
||||
if (chip->setup == 0x00 ||
|
||||
fp->altsetting==1 || fp->altsetting==2 || fp->altsetting==3)
|
||||
fp->altsetting == 1 || fp->altsetting == 2 ||
|
||||
fp->altsetting == 3)
|
||||
return 1;
|
||||
break;
|
||||
case USB_ID(0x0763, 0x2012): /* M-Audio Fast Track Pro */
|
||||
if (fp->altsetting == 2 || fp->altsetting == 3 ||
|
||||
fp->altsetting == 5 || fp->altsetting == 6)
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user