Commit 5e8aa852 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'topic/misc' into for-linus

parents 7bd9db83 550a8b69
......@@ -227,6 +227,16 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
The power-management is supported.
Module snd-asihpi
-----------------
Module for AudioScience ASI soundcards
enable_hpi_hwdep - enable HPI hwdep for AudioScience soundcard
This module supports multiple cards.
The driver requires the firmware loader support on kernel.
Module snd-atiixp
-----------------
......@@ -622,28 +632,23 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed.
The power-management is supported.
Module snd-es968
----------------
Module for sound cards based on ESS ES968 chip (PnP only).
This module supports multiple cards, PnP and autoprobe.
The power-management is supported.
Module snd-es1688
-----------------
Module for ESS AudioDrive ES-1688 and ES-688 sound cards.
port - port # for ES-1688 chip (0x220,0x240,0x260)
fm_port - port # for OPL3 (option; share the same port as default)
isapnp - ISA PnP detection - 0 = disable, 1 = enable (default)
mpu_port - port # for MPU-401 port (0x300,0x310,0x320,0x330), -1 = disable (default)
irq - IRQ # for ES-1688 chip (5,7,9,10)
mpu_irq - IRQ # for MPU-401 port (5,7,9,10)
fm_port - port # for OPL3 (option; share the same port as default)
with isapnp=0, the following additional options are available:
port - port # for ES-1688 chip (0x220,0x240,0x260)
irq - IRQ # for ES-1688 chip (5,7,9,10)
dma8 - DMA # for ES-1688 chip (0,1,3)
This module supports multiple cards and autoprobe (without MPU-401 port).
This module supports multiple cards and autoprobe (without MPU-401 port)
and PnP with the ES968 chip.
Module snd-es18xx
-----------------
......
This diff is collapsed.
......@@ -13,6 +13,9 @@
* Comments below reference relevant sections of that document:
*
* http://www.usb.org/developers/devclass_docs/audio10.pdf
*
* Types and defines in this file are either specific to version 1.0 of
* this standard or common for newer versions.
*/
#ifndef __LINUX_USB_AUDIO_H
......@@ -20,14 +23,15 @@
#include <linux/types.h>
/* bInterfaceProtocol values to denote the version of the standard used */
#define UAC_VERSION_1 0x00
#define UAC_VERSION_2 0x20
/* A.2 Audio Interface Subclass Codes */
#define USB_SUBCLASS_AUDIOCONTROL 0x01
#define USB_SUBCLASS_AUDIOSTREAMING 0x02
#define USB_SUBCLASS_MIDISTREAMING 0x03
#define UAC_VERSION_1 0x00
#define UAC_VERSION_2 0x20
/* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */
#define UAC_HEADER 0x01
#define UAC_INPUT_TERMINAL 0x02
......@@ -38,15 +42,6 @@
#define UAC_PROCESSING_UNIT_V1 0x07
#define UAC_EXTENSION_UNIT_V1 0x08
/* UAC v2.0 types */
#define UAC_EFFECT_UNIT 0x07
#define UAC_PROCESSING_UNIT_V2 0x08
#define UAC_EXTENSION_UNIT_V2 0x09
#define UAC_CLOCK_SOURCE 0x0a
#define UAC_CLOCK_SELECTOR 0x0b
#define UAC_CLOCK_MULTIPLIER 0x0c
#define UAC_SAMPLE_RATE_CONVERTER 0x0d
/* A.6 Audio Class-Specific AS Interface Descriptor Subtypes */
#define UAC_AS_GENERAL 0x01
#define UAC_FORMAT_TYPE 0x02
......@@ -78,10 +73,6 @@
#define UAC_GET_STAT 0xff
/* Audio class v2.0 handles all the parameter calls differently */
#define UAC2_CS_CUR 0x01
#define UAC2_CS_RANGE 0x02
/* MIDI - A.1 MS Class-Specific Interface Descriptor Subtypes */
#define UAC_MS_HEADER 0x01
#define UAC_MIDI_IN_JACK 0x02
......@@ -190,6 +181,156 @@ struct uac_feature_unit_descriptor_##ch { \
__u8 iFeature; \
} __attribute__ ((packed))
/* 4.3.2.3 Mixer Unit Descriptor */
struct uac_mixer_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUnitID;
__u8 bNrInPins;
__u8 baSourceID[];
} __attribute__ ((packed));
static inline __u8 uac_mixer_unit_bNrChannels(struct uac_mixer_unit_descriptor *desc)
{
return desc->baSourceID[desc->bNrInPins];
}
static inline __u32 uac_mixer_unit_wChannelConfig(struct uac_mixer_unit_descriptor *desc,
int protocol)
{
if (protocol == UAC_VERSION_1)
return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
desc->baSourceID[desc->bNrInPins + 1];
else
return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
(desc->baSourceID[desc->bNrInPins + 3] << 16) |
(desc->baSourceID[desc->bNrInPins + 2] << 8) |
(desc->baSourceID[desc->bNrInPins + 1]);
}
static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor *desc,
int protocol)
{
return (protocol == UAC_VERSION_1) ?
desc->baSourceID[desc->bNrInPins + 3] :
desc->baSourceID[desc->bNrInPins + 5];
}
static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc,
int protocol)
{
return (protocol == UAC_VERSION_1) ?
&desc->baSourceID[desc->bNrInPins + 4] :
&desc->baSourceID[desc->bNrInPins + 6];
}
static inline __u8 uac_mixer_unit_iMixer(struct uac_mixer_unit_descriptor *desc)
{
__u8 *raw = (__u8 *) desc;
return raw[desc->bLength - 1];
}
/* 4.3.2.4 Selector Unit Descriptor */
struct uac_selector_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUintID;
__u8 bNrInPins;
__u8 baSourceID[];
} __attribute__ ((packed));
static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc)
{
__u8 *raw = (__u8 *) desc;
return raw[desc->bLength - 1];
}
/* 4.3.2.5 Feature Unit Descriptor */
struct uac_feature_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUnitID;
__u8 bSourceID;
__u8 bControlSize;
__u8 bmaControls[0]; /* variable length */
} __attribute__((packed));
static inline __u8 uac_feature_unit_iFeature(struct uac_feature_unit_descriptor *desc)
{
__u8 *raw = (__u8 *) desc;
return raw[desc->bLength - 1];
}
/* 4.3.2.6 Processing Unit Descriptors */
struct uac_processing_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUnitID;
__u16 wProcessType;
__u8 bNrInPins;
__u8 baSourceID[];
} __attribute__ ((packed));
static inline __u8 uac_processing_unit_bNrChannels(struct uac_processing_unit_descriptor *desc)
{
return desc->baSourceID[desc->bNrInPins];
}
static inline __u32 uac_processing_unit_wChannelConfig(struct uac_processing_unit_descriptor *desc,
int protocol)
{
if (protocol == UAC_VERSION_1)
return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
desc->baSourceID[desc->bNrInPins + 1];
else
return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
(desc->baSourceID[desc->bNrInPins + 3] << 16) |
(desc->baSourceID[desc->bNrInPins + 2] << 8) |
(desc->baSourceID[desc->bNrInPins + 1]);
}
static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_descriptor *desc,
int protocol)
{
return (protocol == UAC_VERSION_1) ?
desc->baSourceID[desc->bNrInPins + 3] :
desc->baSourceID[desc->bNrInPins + 5];
}
static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc,
int protocol)
{
return (protocol == UAC_VERSION_1) ?
desc->baSourceID[desc->bNrInPins + 4] :
desc->baSourceID[desc->bNrInPins + 6];
}
static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc,
int protocol)
{
return (protocol == UAC_VERSION_1) ?
&desc->baSourceID[desc->bNrInPins + 5] :
&desc->baSourceID[desc->bNrInPins + 7];
}
static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc,
int protocol)
{
__u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
return desc->baSourceID[desc->bNrInPins + control_size];
}
static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc,
int protocol)
{
__u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
return &desc->baSourceID[desc->bNrInPins + control_size + 1];
}
/* 4.5.2 Class-Specific AS Interface Descriptor */
struct uac_as_header_descriptor_v1 {
__u8 bLength; /* in bytes: 7 */
......@@ -200,19 +341,6 @@ struct uac_as_header_descriptor_v1 {
__le16 wFormatTag; /* The Audio Data Format */
} __attribute__ ((packed));
struct uac_as_header_descriptor_v2 {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bTerminalLink;
__u8 bmControls;
__u8 bFormatType;
__u32 bmFormats;
__u8 bNrChannels;
__u32 bmChannelConfig;
__u8 iChannelNames;
} __attribute__((packed));
#define UAC_DT_AS_HEADER_SIZE 7
/* Formats - A.1.1 Audio Data Format Type I Codes */
......@@ -277,7 +405,6 @@ struct uac_format_type_i_ext_descriptor {
__u8 bSideBandProtocol;
} __attribute__((packed));
/* Formats - Audio Data Format Type I Codes */
#define UAC_FORMAT_TYPE_II_MPEG 0x1001
......@@ -336,31 +463,8 @@ struct uac_iso_endpoint_descriptor {
#define UAC_EP_CS_ATTR_PITCH_CONTROL 0x02
#define UAC_EP_CS_ATTR_FILL_MAX 0x80
/* Audio class v2.0: CLOCK_SOURCE descriptor */
struct uac_clock_source_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bClockID;
__u8 bmAttributes;
__u8 bmControls;
__u8 bAssocTerminal;
__u8 iClockSource;
} __attribute__((packed));
/* A.10.2 Feature Unit Control Selectors */
struct uac_feature_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUnitID;
__u8 bSourceID;
__u8 bControlSize;
__u8 controls[0]; /* variable length */
} __attribute__((packed));
#define UAC_FU_CONTROL_UNDEFINED 0x00
#define UAC_MUTE_CONTROL 0x01
#define UAC_VOLUME_CONTROL 0x02
......
......@@ -574,7 +574,7 @@ enum {
#define SNDRV_TIMER_FLG_SLAVE (1<<0) /* cannot be controlled */
struct snd_timer_id {
int dev_class;
int dev_class;
int dev_sclass;
int card;
int device;
......@@ -762,7 +762,7 @@ struct snd_ctl_elem_id {
snd_ctl_elem_iface_t iface; /* interface identifier */
unsigned int device; /* device/client number */
unsigned int subdevice; /* subdevice (substream) number */
unsigned char name[44]; /* ASCII name of item */
unsigned char name[44]; /* ASCII name of item */
unsigned int index; /* index of item */
};
......@@ -809,7 +809,7 @@ struct snd_ctl_elem_info {
struct snd_ctl_elem_value {
struct snd_ctl_elem_id id; /* W: element ID */
unsigned int indirect: 1; /* W: indirect access - obsoleted */
union {
union {
union {
long value[128];
long *value_ptr; /* obsoleted */
......@@ -827,15 +827,15 @@ struct snd_ctl_elem_value {
unsigned char *data_ptr; /* obsoleted */
} bytes;
struct snd_aes_iec958 iec958;
} value; /* RO */
} value; /* RO */
struct timespec tstamp;
unsigned char reserved[128-sizeof(struct timespec)];
unsigned char reserved[128-sizeof(struct timespec)];
};
struct snd_ctl_tlv {
unsigned int numid; /* control element numeric identification */
unsigned int length; /* in bytes aligned to 4 */
unsigned int tlv[0]; /* first TLV */
unsigned int numid; /* control element numeric identification */
unsigned int length; /* in bytes aligned to 4 */
unsigned int tlv[0]; /* first TLV */
};
#define SNDRV_CTL_IOCTL_PVERSION _IOR('U', 0x00, int)
......@@ -886,8 +886,8 @@ struct snd_ctl_event {
unsigned int mask;
struct snd_ctl_elem_id id;
} elem;
unsigned char data8[60];
} data;
unsigned char data8[60];
} data;
};
/*
......
......@@ -44,7 +44,6 @@ struct snd_es1688 {
unsigned char pad;
unsigned int dma_size;
struct snd_card *card;
struct snd_pcm *pcm;
struct snd_pcm_substream *playback_substream;
struct snd_pcm_substream *capture_substream;
......@@ -108,14 +107,16 @@ struct snd_es1688 {
void snd_es1688_mixer_write(struct snd_es1688 *chip, unsigned char reg, unsigned char data);
int snd_es1688_create(struct snd_card *card,
struct snd_es1688 *chip,
unsigned long port,
unsigned long mpu_port,
int irq,
int mpu_irq,
int dma8,
unsigned short hardware,
struct snd_es1688 ** rchip);
int snd_es1688_pcm(struct snd_es1688 *chip, int device, struct snd_pcm ** rpcm);
int snd_es1688_mixer(struct snd_es1688 *chip);
unsigned short hardware);
int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip, int device,
struct snd_pcm **rpcm);
int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip);
int snd_es1688_reset(struct snd_es1688 *chip);
#endif /* __SOUND_ES1688_H */
/* include/version.h */
#define CONFIG_SND_VERSION "1.0.22.1"
#define CONFIG_SND_VERSION "1.0.23"
#define CONFIG_SND_DATE ""
......@@ -98,7 +98,8 @@ int snd_i2c_bus_create(struct snd_card *card, const char *name,
bus->master = master;
}
strlcpy(bus->name, name, sizeof(bus->name));
if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops)) < 0) {
err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops);
if (err < 0) {
snd_i2c_bus_free(bus);
return err;
}
......@@ -246,7 +247,8 @@ static int snd_i2c_bit_sendbyte(struct snd_i2c_bus *bus, unsigned char data)
for (i = 7; i >= 0; i--)
snd_i2c_bit_send(bus, !!(data & (1 << i)));
if ((err = snd_i2c_bit_ack(bus)) < 0)
err = snd_i2c_bit_ack(bus);
if (err < 0)
return err;
return 0;
}
......@@ -278,12 +280,14 @@ static int snd_i2c_bit_sendbytes(struct snd_i2c_device *device,
if (device->flags & SND_I2C_DEVICE_ADDRTEN)
return -EIO; /* not yet implemented */
snd_i2c_bit_start(bus);
if ((err = snd_i2c_bit_sendbyte(bus, device->addr << 1)) < 0) {
err = snd_i2c_bit_sendbyte(bus, device->addr << 1);
if (err < 0) {
snd_i2c_bit_hw_stop(bus);
return err;
}
while (count-- > 0) {
if ((err = snd_i2c_bit_sendbyte(bus, *bytes++)) < 0) {
err = snd_i2c_bit_sendbyte(bus, *bytes++);
if (err < 0) {
snd_i2c_bit_hw_stop(bus);
return err;
}
......@@ -302,12 +306,14 @@ static int snd_i2c_bit_readbytes(struct snd_i2c_device *device,
if (device->flags & SND_I2C_DEVICE_ADDRTEN)
return -EIO; /* not yet implemented */
snd_i2c_bit_start(bus);
if ((err = snd_i2c_bit_sendbyte(bus, (device->addr << 1) | 1)) < 0) {
err = snd_i2c_bit_sendbyte(bus, (device->addr << 1) | 1);
if (err < 0) {
snd_i2c_bit_hw_stop(bus);
return err;
}
while (count-- > 0) {
if ((err = snd_i2c_bit_readbyte(bus, count == 0)) < 0) {
err = snd_i2c_bit_readbyte(bus, count == 0);
if (err < 0) {
snd_i2c_bit_hw_stop(bus);
return err;
}
......
......@@ -128,26 +128,14 @@ config SND_CS4236
To compile this driver as a module, choose M here: the module
will be called snd-cs4236.
config SND_ES968
tristate "Generic ESS ES968 driver"
depends on PNP
select ISAPNP
select SND_MPU401_UART
select SND_SB8_DSP
help
Say Y here to include support for ESS AudioDrive ES968 chips.
To compile this driver as a module, choose M here: the module
will be called snd-es968.
config SND_ES1688
tristate "Generic ESS ES688/ES1688 driver"
tristate "Generic ESS ES688/ES1688 and ES968 PnP driver"
select SND_OPL3_LIB
select SND_MPU401_UART
select SND_PCM
help
Say Y here to include support for ESS AudioDrive ES688 or
ES1688 chips.
ES1688 chips. Also, this module support cards with ES968 PnP chip.
To compile this driver as a module, choose M here: the module
will be called snd-es1688.
......
......@@ -22,6 +22,7 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/isa.h>
#include <linux/isapnp.h>
#include <linux/time.h>
#include <linux/wait.h>
#include <linux/moduleparam.h>
......@@ -45,8 +46,13 @@ MODULE_SUPPORTED_DEVICE("{{ESS,ES688 PnP AudioDrive,pnp:ESS0100},"
"{ESS,ES688 AudioDrive,pnp:ESS6881},"
"{ESS,ES1688 AudioDrive,pnp:ESS1681}}");
MODULE_ALIAS("snd_es968");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
#ifdef CONFIG_PNP
static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
#endif
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260 */
static long fm_port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* Usually 0x388 */
......@@ -60,6 +66,10 @@ MODULE_PARM_DESC(index, "Index value for " CRD_NAME " soundcard.");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for " CRD_NAME " soundcard.");
module_param_array(enable, bool, NULL, 0444);
#ifdef CONFIG_PNP
module_param_array(isapnp, bool, NULL, 0444);
MODULE_PARM_DESC(isapnp, "PnP detection for specified soundcard.");
#endif
MODULE_PARM_DESC(enable, "Enable " CRD_NAME " soundcard.");
module_param_array(port, long, NULL, 0444);
MODULE_PARM_DESC(port, "Port # for " CRD_NAME " driver.");
......@@ -74,14 +84,21 @@ MODULE_PARM_DESC(mpu_irq, "MPU-401 IRQ # for " CRD_NAME " driver.");
module_param_array(dma8, int, NULL, 0444);
MODULE_PARM_DESC(dma8, "8-bit DMA # for " CRD_NAME " driver.");
#ifdef CONFIG_PNP
#define is_isapnp_selected(dev) isapnp[dev]
#else
#define is_isapnp_selected(dev) 0
#endif
static int __devinit snd_es1688_match(struct device *dev, unsigned int n)
{
return enable[n];
return enable[n] && !is_isapnp_selected(n);
}
static int __devinit snd_es1688_legacy_create(struct snd_card *card,
struct device *dev, unsigned int n, struct snd_es1688 **rchip)
static int __devinit snd_es1688_legacy_create(struct snd_card *card,
struct device *dev, unsigned int n)
{
struct snd_es1688 *chip = card->private_data;
static long possible_ports[] = {0x220, 0x240, 0x260};
static int possible_irqs[] = {5, 9, 10, 7, -1};
static int possible_dmas[] = {1, 3, 0, -1};
......@@ -104,47 +121,39 @@ static int __devinit snd_es1688_legacy_create(struct snd_card *card,
}
if (port[n] != SNDRV_AUTO_PORT)
return snd_es1688_create(card, port[n], mpu_port[n], irq[n],
mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip);
return snd_es1688_create(card, chip, port[n], mpu_port[n],
irq[n], mpu_irq[n], dma8[n], ES1688_HW_AUTO);
i = 0;
do {
port[n] = possible_ports[i];
error = snd_es1688_create(card, port[n], mpu_port[n], irq[n],
mpu_irq[n], dma8[n], ES1688_HW_AUTO, rchip);
error = snd_es1688_create(card, chip, port[n], mpu_port[n],
irq[n], mpu_irq[n], dma8[n], ES1688_HW_AUTO);
} while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
return error;
}
static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
static int __devinit snd_es1688_probe(struct snd_card *card, unsigned int n)
{
struct snd_card *card;
struct snd_es1688 *chip;
struct snd_es1688 *chip = card->private_data;
struct snd_opl3 *opl3;
struct snd_pcm *pcm;
int error;
error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card);
error = snd_es1688_pcm(card, chip, 0, &pcm);
if (error < 0)
return error;
error = snd_es1688_legacy_create(card, dev, n, &chip);
if (error < 0)
goto out;
error = snd_es1688_pcm(chip, 0, &pcm);
error = snd_es1688_mixer(card, chip);
if (error < 0)
goto out;
error = snd_es1688_mixer(chip);
if (error < 0)
goto out;
return error;
strcpy(card->driver, "ES1688");
strcpy(card->shortname, pcm->name);
sprintf(card->longname, "%s at 0x%lx, irq %i, dma %i", pcm->name,
chip->port, chip->irq, chip->dma8);
strlcpy(card->driver, "ES1688", sizeof(card->driver));
strlcpy(card->shortname, pcm->name, sizeof(card->shortname));
snprintf(card->longname, sizeof(card->longname),
"%s at 0x%lx, irq %i, dma %i", pcm->name, chip->port,
chip->irq, chip->dma8);
if (fm_port[n] == SNDRV_AUTO_PORT)
fm_port[n] = port[n]; /* share the same port */
......@@ -152,12 +161,12 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
if (fm_port[n] > 0) {
if (snd_opl3_create(card, fm_port[n], fm_port[n] + 2,
OPL3_HW_OPL3, 0, &opl3) < 0)
dev_warn(dev,
dev_warn(card->dev,
"opl3 not detected at 0x%lx\n", fm_port[n]);
else {
error = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
if (error < 0)
goto out;
return error;
}
}
......@@ -167,23 +176,41 @@ static int __devinit snd_es1688_probe(struct device *dev, unsigned int n)
chip->mpu_port, 0,
mpu_irq[n], IRQF_DISABLED, NULL);
if (error < 0)
goto out;
return error;
}
return snd_card_register(card);
}
static int __devinit snd_es1688_isa_probe(struct device *dev, unsigned int n)
{
struct snd_card *card;
int error;
error = snd_card_create(index[n], id[n], THIS_MODULE,
sizeof(struct snd_es1688), &card);
if (error < 0)
return error;
error = snd_es1688_legacy_create(card, dev, n);
if (error < 0)
goto out;
snd_card_set_dev(card, dev);
error = snd_card_register(card);
error = snd_es1688_probe(card, n);
if (error < 0)
goto out;
dev_set_drvdata(dev, card);
return 0;
out: snd_card_free(card);
return 0;
out:
snd_card_free(card);
return error;
}
static int __devexit snd_es1688_remove(struct device *dev, unsigned int n)
static int __devexit snd_es1688_isa_remove(struct device *dev, unsigned int n)
{
snd_card_free(dev_get_drvdata(dev));
dev_set_drvdata(dev, NULL);
......@@ -192,8 +219,8 @@ static int __devexit snd_es1688_remove(struct device *dev, unsigned int n)
static struct isa_driver snd_es1688_driver = {
.match = snd_es1688_match,
.probe = snd_es1688_probe,
.remove = __devexit_p(snd_es1688_remove),
.probe = snd_es1688_isa_probe,
.remove = __devexit_p(snd_es1688_isa_remove),
#if 0 /* FIXME */
.suspend = snd_es1688_suspend,
.resume = snd_es1688_resume,
......@@ -203,14 +230,142 @@ static struct isa_driver snd_es1688_driver = {
}
};
static int snd_es968_pnp_is_probed;
#ifdef CONFIG_PNP
static int __devinit snd_card_es968_pnp(struct snd_card *card, unsigned int n,
struct pnp_card_link *pcard,
const struct pnp_card_device_id *pid)
{
struct snd_es1688 *chip = card->private_data;
struct pnp_dev *pdev;
int error;
pdev = pnp_request_card_device(pcard, pid->devs[0].id, NULL);
if (pdev == NULL)
return -ENODEV;
error = pnp_activate_dev(pdev);
if (error < 0) {
snd_printk(KERN_ERR "ES968 pnp configure failure\n");
return error;
}
port[n] = pnp_port_start(pdev, 0);
dma8[n] = pnp_dma(pdev, 0);
irq[n] = pnp_irq(pdev, 0);
return snd_es1688_create(card, chip, port[n], mpu_port[n], irq[n],
mpu_irq[n], dma8[n], ES1688_HW_AUTO);
}
static int __devinit snd_es968_pnp_detect(struct pnp_card_link *pcard,
const struct pnp_card_device_id *pid)
{
struct snd_card *card;
static unsigned int dev;
int error;
struct snd_es1688 *chip;
if (snd_es968_pnp_is_probed)
return -EBUSY;
for ( ; dev < SNDRV_CARDS; dev++) {
if (enable[dev] && isapnp[dev])
break;
}
if (dev == SNDRV_CARDS)
return -ENODEV;
error = snd_card_create(index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_es1688), &card);
if (error < 0)
return error;
chip = card->private_data;
error = snd_card_es968_pnp(card, dev, pcard, pid);
if (error < 0) {
snd_card_free(card);
return error;
}
snd_card_set_dev(card, &pcard->card->dev);
error = snd_es1688_probe(card, dev);
if (error < 0)
return error;
pnp_set_card_drvdata(pcard, card);
snd_es968_pnp_is_probed = 1;
return 0;
}
static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
snd_es968_pnp_is_probed = 0;
}
#ifdef CONFIG_PM
static int snd_es968_pnp_suspend(struct pnp_card_link *pcard,
pm_message_t state)
{
struct snd_card *card = pnp_get_card_drvdata(pcard);
struct snd_es1688 *chip = card->private_data;
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
snd_pcm_suspend_all(chip->pcm);
return 0;
}
static int snd_es968_pnp_resume(struct pnp_card_link *pcard)
{
struct snd_card *card = pnp_get_card_drvdata(pcard);
struct snd_es1688 *chip = card->private_data;
snd_es1688_reset(chip);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
}
#endif
static struct pnp_card_device_id snd_es968_pnpids[] = {
{ .id = "ESS0968", .devs = { { "@@@0968" }, } },
{ .id = "ESS0968", .devs = { { "ESS0968" }, } },
{ .id = "", } /* end */
};
MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids);
static struct pnp_card_driver es968_pnpc_driver = {
.flags = PNP_DRIVER_RES_DISABLE,
.name = DEV_NAME " PnP",
.id_table = snd_es968_pnpids,
.probe = snd_es968_pnp_detect,
.remove = __devexit_p(snd_es968_pnp_remove),
#ifdef CONFIG_PM
.suspend = snd_es968_pnp_suspend,
.resume = snd_es968_pnp_resume,
#endif
};
#endif
static int __init alsa_card_es1688_init(void)
{
#ifdef CONFIG_PNP
pnp_register_card_driver(&es968_pnpc_driver);
if (snd_es968_pnp_is_probed)
return 0;
pnp_unregister_card_driver(&es968_pnpc_driver);
#endif
return isa_register_driver(&snd_es1688_driver, SNDRV_CARDS);
}
static void __exit alsa_card_es1688_exit(void)
{
isa_unregister_driver(&snd_es1688_driver);
if (!snd_es968_pnp_is_probed) {
isa_unregister_driver(&snd_es1688_driver);
return;
}
#ifdef CONFIG_PNP
pnp_unregister_card_driver(&es968_pnpc_driver);
#endif
}
module_init(alsa_card_es1688_init);
......
......@@ -99,7 +99,7 @@ static unsigned char snd_es1688_mixer_read(struct snd_es1688 *chip, unsigned cha
return result;
}
static int snd_es1688_reset(struct snd_es1688 *chip)
int snd_es1688_reset(struct snd_es1688 *chip)
{
int i;
......@@ -115,6 +115,7 @@ static int snd_es1688_reset(struct snd_es1688 *chip)
snd_es1688_dsp_command(chip, 0xc6); /* enable extended mode */
return 0;
}
EXPORT_SYMBOL(snd_es1688_reset);
static int snd_es1688_probe(struct snd_es1688 *chip)
{
......@@ -620,7 +621,6 @@ static int snd_es1688_free(struct snd_es1688 *chip)
disable_dma(chip->dma8);
free_dma(chip->dma8);
}
kfree(chip);
return 0;
}
......@@ -638,23 +638,20 @@ static const char *snd_es1688_chip_id(struct snd_es1688 *chip)
}
int snd_es1688_create(struct snd_card *card,
struct snd_es1688 *chip,
unsigned long port,
unsigned long mpu_port,
int irq,
int mpu_irq,
int dma8,
unsigned short hardware,
struct snd_es1688 **rchip)
unsigned short hardware)
{
static struct snd_device_ops ops = {
.dev_free = snd_es1688_dev_free,
};
struct snd_es1688 *chip;
int err;
*rchip = NULL;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (chip == NULL)
return -ENOMEM;
chip->irq = -1;
......@@ -662,25 +659,21 @@ int snd_es1688_create(struct snd_card *card,
if ((chip->res_port = request_region(port + 4, 12, "ES1688")) == NULL) {
snd_printk(KERN_ERR "es1688: can't grab port 0x%lx\n", port + 4);
snd_es1688_free(chip);
return -EBUSY;
}
if (request_irq(irq, snd_es1688_interrupt, IRQF_DISABLED, "ES1688", (void *) chip)) {
snd_printk(KERN_ERR "es1688: can't grab IRQ %d\n", irq);
snd_es1688_free(chip);
return -EBUSY;
}
chip->irq = irq;
if (request_dma(dma8, "ES1688")) {
snd_printk(KERN_ERR "es1688: can't grab DMA8 %d\n", dma8);
snd_es1688_free(chip);
return -EBUSY;
}
chip->dma8 = dma8;
spin_lock_init(&chip->reg_lock);
spin_lock_init(&chip->mixer_lock);
chip->card = card;
chip->port = port;
mpu_port &= ~0x000f;
if (mpu_port < 0x300 || mpu_port > 0x330)
......@@ -689,23 +682,16 @@ int snd_es1688_create(struct snd_card *card,
chip->mpu_irq = mpu_irq;
chip->hardware = hardware;
if ((err = snd_es1688_probe(chip)) < 0) {
snd_es1688_free(chip);
err = snd_es1688_probe(chip);
if (err < 0)
return err;
}
if ((err = snd_es1688_init(chip, 1)) < 0) {
snd_es1688_free(chip);
return err;
}
/* Register device */
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) {
snd_es1688_free(chip);
err = snd_es1688_init(chip, 1);
if (err < 0)
return err;
}
*rchip = chip;
return 0;
/* Register device */
return snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
}
static struct snd_pcm_ops snd_es1688_playback_ops = {
......@@ -730,12 +716,14 @@ static struct snd_pcm_ops snd_es1688_capture_ops = {
.pointer = snd_es1688_capture_pointer,
};
int snd_es1688_pcm(struct snd_es1688 * chip, int device, struct snd_pcm ** rpcm)
int snd_es1688_pcm(struct snd_card *card, struct snd_es1688 *chip,
int device, struct snd_pcm **rpcm)
{
struct snd_pcm *pcm;
int err;
if ((err = snd_pcm_new(chip->card, "ESx688", device, 1, 1, &pcm)) < 0)
err = snd_pcm_new(card, "ESx688", device, 1, 1, &pcm);
if (err < 0)
return err;
snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_es1688_playback_ops);
......@@ -1009,18 +997,15 @@ static unsigned char snd_es1688_init_table[][2] = {
{ ES1688_REC_DEV, 0x17 }
};
int snd_es1688_mixer(struct snd_es1688 *chip)
int snd_es1688_mixer(struct snd_card *card, struct snd_es1688 *chip)
{
struct snd_card *card;
unsigned int idx;
int err;
unsigned char reg, val;
if (snd_BUG_ON(!chip || !chip->card))
if (snd_BUG_ON(!chip || !card))
return -EINVAL;
card = chip->card;
strcpy(card->mixername, snd_es1688_chip_id(chip));
for (idx = 0; idx < ARRAY_SIZE(snd_es1688_controls); idx++) {
......
......@@ -95,7 +95,7 @@ static int __devinit snd_gusextreme_match(struct device *dev, unsigned int n)
}
static int __devinit snd_gusextreme_es1688_create(struct snd_card *card,
struct device *dev, unsigned int n, struct snd_es1688 **rchip)
struct snd_es1688 *chip, struct device *dev, unsigned int n)
{
static long possible_ports[] = {0x220, 0x240, 0x260};
static int possible_irqs[] = {5, 9, 10, 7, -1};
......@@ -119,14 +119,14 @@ static int __devinit snd_gusextreme_es1688_create(struct snd_card *card,
}
if (port[n] != SNDRV_AUTO_PORT)
return snd_es1688_create(card, port[n], mpu_port[n], irq[n],
mpu_irq[n], dma8[n], ES1688_HW_1688, rchip);
return snd_es1688_create(card, chip, port[n], mpu_port[n],
irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688);
i = 0;
do {
port[n] = possible_ports[i];
error = snd_es1688_create(card, port[n], mpu_port[n], irq[n],
mpu_irq[n], dma8[n], ES1688_HW_1688, rchip);
error = snd_es1688_create(card, chip, port[n], mpu_port[n],
irq[n], mpu_irq[n], dma8[n], ES1688_HW_1688);
} while (error < 0 && ++i < ARRAY_SIZE(possible_ports));
return error;
......@@ -206,9 +206,8 @@ static int __devinit snd_gusextreme_detect(struct snd_gus_card *gus,
return 0;
}
static int __devinit snd_gusextreme_mixer(struct snd_es1688 *chip)
static int __devinit snd_gusextreme_mixer(struct snd_card *card)
{
struct snd_card *card = chip->card;
struct snd_ctl_elem_id id1, id2;
int error;
......@@ -241,17 +240,20 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
struct snd_opl3 *opl3;
int error;
error = snd_card_create(index[n], id[n], THIS_MODULE, 0, &card);
error = snd_card_create(index[n], id[n], THIS_MODULE,
sizeof(struct snd_es1688), &card);
if (error < 0)
return error;
es1688 = card->private_data;
if (mpu_port[n] == SNDRV_AUTO_PORT)
mpu_port[n] = 0;
if (mpu_irq[n] > 15)
mpu_irq[n] = -1;
error = snd_gusextreme_es1688_create(card, dev, n, &es1688);
error = snd_gusextreme_es1688_create(card, es1688, dev, n);
if (error < 0)
goto out;
......@@ -280,11 +282,11 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
}
gus->codec_flag = 1;
error = snd_es1688_pcm(es1688, 0, NULL);
error = snd_es1688_pcm(card, es1688, 0, NULL);
if (error < 0)
goto out;
error = snd_es1688_mixer(es1688);
error = snd_es1688_mixer(card, es1688);
if (error < 0)
goto out;
......@@ -300,7 +302,7 @@ static int __devinit snd_gusextreme_probe(struct device *dev, unsigned int n)
if (error < 0)
goto out;
error = snd_gusextreme_mixer(es1688);
error = snd_gusextreme_mixer(card);
if (error < 0)
goto out;
......
......@@ -11,7 +11,6 @@ snd-sb8-objs := sb8.o
snd-sb16-objs := sb16.o
snd-sbawe-objs := sbawe.o emu8000.o
snd-emu8000-synth-objs := emu8000_synth.o emu8000_callback.o emu8000_patch.o emu8000_pcm.o
snd-es968-objs := es968.o
snd-jazz16-objs := jazz16.o
# Toplevel Module Dependency
......@@ -21,7 +20,6 @@ obj-$(CONFIG_SND_SB8_DSP) += snd-sb8-dsp.o
obj-$(CONFIG_SND_SB8) += snd-sb8.o
obj-$(CONFIG_SND_SB16) += snd-sb16.o
obj-$(CONFIG_SND_SBAWE) += snd-sbawe.o
obj-$(CONFIG_SND_ES968) += snd-es968.o
obj-$(CONFIG_SND_JAZZ16) += snd-jazz16.o
ifeq ($(CONFIG_SND_SB16_CSP),y)
obj-$(CONFIG_SND_SB16) += snd-sb16-csp.o
......
/*
card-es968.c - driver for ESS AudioDrive ES968 based soundcards.
Copyright (C) 1999 by Massimo Piccioni <dafastidio@libero.it>
Thanks to Pierfrancesco 'qM2' Passerini.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/init.h>
#include <linux/time.h>
#include <linux/pnp.h>
#include <linux/moduleparam.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/sb.h>
#define PFX "es968: "
MODULE_AUTHOR("Massimo Piccioni <dafastidio@libero.it>");
MODULE_DESCRIPTION("ESS AudioDrive ES968");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{ESS,AudioDrive ES968}}");
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* PnP setup */
static int irq[SNDRV_CARDS] = SNDRV_DEFAULT_IRQ; /* Pnp setup */
static int dma8[SNDRV_CARDS] = SNDRV_DEFAULT_DMA; /* PnP setup */
module_param_array(index, int, NULL, 0444);
MODULE_PARM_DESC(index, "Index value for es968 based soundcard.");
module_param_array(id, charp, NULL, 0444);
MODULE_PARM_DESC(id, "ID string for es968 based soundcard.");
module_param_array(enable, bool, NULL, 0444);
MODULE_PARM_DESC(enable, "Enable es968 based soundcard.");
struct snd_card_es968 {
struct pnp_dev *dev;
struct snd_sb *chip;
};
static struct pnp_card_device_id snd_es968_pnpids[] = {
{ .id = "ESS0968", .devs = { { "@@@0968" }, } },
{ .id = "", } /* end */
};
MODULE_DEVICE_TABLE(pnp_card, snd_es968_pnpids);
#define DRIVER_NAME "snd-card-es968"
static irqreturn_t snd_card_es968_interrupt(int irq, void *dev_id)
{
struct snd_sb *chip = dev_id;
if (chip->open & SB_OPEN_PCM) {
return snd_sb8dsp_interrupt(chip);
} else {
return snd_sb8dsp_midi_interrupt(chip);
}
}
static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard,
struct pnp_card_link *card,
const struct pnp_card_device_id *id)
{
struct pnp_dev *pdev;
int err;
acard->dev = pnp_request_card_device(card, id->devs[0].id, NULL);
if (acard->dev == NULL)
return -ENODEV;
pdev = acard->dev;
err = pnp_activate_dev(pdev);
if (err < 0) {
snd_printk(KERN_ERR PFX "AUDIO pnp configure failure\n");
return err;
}
port[dev] = pnp_port_start(pdev, 0);
dma8[dev] = pnp_dma(pdev, 0);
irq[dev] = pnp_irq(pdev, 0);
return 0;
}
static int __devinit snd_card_es968_probe(int dev,
struct pnp_card_link *pcard,
const struct pnp_card_device_id *pid)
{
int error;
struct snd_sb *chip;
struct snd_card *card;
struct snd_card_es968 *acard;
error = snd_card_create(index[dev], id[dev], THIS_MODULE,
sizeof(struct snd_card_es968), &card);
if (error < 0)
return error;
acard = card->private_data;
if ((error = snd_card_es968_pnp(dev, acard, pcard, pid))) {
snd_card_free(card);
return error;
}
snd_card_set_dev(card, &pcard->card->dev);
if ((error = snd_sbdsp_create(card, port[dev],
irq[dev],
snd_card_es968_interrupt,
dma8[dev],
-1,
SB_HW_AUTO, &chip)) < 0) {
snd_card_free(card);
return error;
}
acard->chip = chip;
if ((error = snd_sb8dsp_pcm(chip, 0, NULL)) < 0) {
snd_card_free(card);
return error;
}
if ((error = snd_sbmixer_new(chip)) < 0) {
snd_card_free(card);
return error;
}
if ((error = snd_sb8dsp_midi(chip, 0, NULL)) < 0) {
snd_card_free(card);
return error;
}
strcpy(card->driver, "ES968");
strcpy(card->shortname, "ESS ES968");
sprintf(card->longname, "%s soundcard, %s at 0x%lx, irq %d, dma %d",
card->shortname, chip->name, chip->port, irq[dev], dma8[dev]);
if ((error = snd_card_register(card)) < 0) {
snd_card_free(card);
return error;
}
pnp_set_card_drvdata(pcard, card);
return 0;
}
static unsigned int __devinitdata es968_devices;
static int __devinit snd_es968_pnp_detect(struct pnp_card_link *card,
const struct pnp_card_device_id *id)
{
static int dev;
int res;
for ( ; dev < SNDRV_CARDS; dev++) {
if (!enable[dev])
continue;
res = snd_card_es968_probe(dev, card, id);
if (res < 0)
return res;
dev++;
es968_devices++;
return 0;
}
return -ENODEV;
}
static void __devexit snd_es968_pnp_remove(struct pnp_card_link * pcard)
{
snd_card_free(pnp_get_card_drvdata(pcard));
pnp_set_card_drvdata(pcard, NULL);
}
#ifdef CONFIG_PM
static int snd_es968_pnp_suspend(struct pnp_card_link *pcard, pm_message_t state)
{
struct snd_card *card = pnp_get_card_drvdata(pcard);
struct snd_card_es968 *acard = card->private_data;
struct snd_sb *chip = acard->chip;
snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
snd_pcm_suspend_all(chip->pcm);
snd_sbmixer_suspend(chip);
return 0;
}
static int snd_es968_pnp_resume(struct pnp_card_link *pcard)
{
struct snd_card *card = pnp_get_card_drvdata(pcard);
struct snd_card_es968 *acard = card->private_data;
struct snd_sb *chip = acard->chip;
snd_sbdsp_reset(chip);
snd_sbmixer_resume(chip);
snd_power_change_state(card, SNDRV_CTL_POWER_D0);
return 0;
}
#endif
static struct pnp_card_driver es968_pnpc_driver = {
.flags = PNP_DRIVER_RES_DISABLE,
.name = "es968",
.id_table = snd_es968_pnpids,
.probe = snd_es968_pnp_detect,
.remove = __devexit_p(snd_es968_pnp_remove),
#ifdef CONFIG_PM
.suspend = snd_es968_pnp_suspend,
.resume = snd_es968_pnp_resume,
#endif
};
static int __init alsa_card_es968_init(void)
{
int err = pnp_register_card_driver(&es968_pnpc_driver);
if (err)
return err;
if (!es968_devices) {
pnp_unregister_card_driver(&es968_pnpc_driver);
#ifdef MODULE
snd_printk(KERN_ERR "no ES968 based soundcards found\n");
#endif
return -ENODEV;
}
return 0;
}
static void __exit alsa_card_es968_exit(void)
{
pnp_unregister_card_driver(&es968_pnpc_driver);
}
module_init(alsa_card_es968_init)
module_exit(alsa_card_es968_exit)
......@@ -58,6 +58,18 @@ config SND_ALI5451
To compile this driver as a module, choose M here: the module
will be called snd-ali5451.
config SND_ASIHPI
tristate "AudioScience ASIxxxx"
depends on X86
select FW_LOADER
select SND_PCM
select SND_HWDEP
help
Say Y here to include support for AudioScience ASI sound cards.
To compile this driver as a module, choose M here: the module
will be called snd-asihpi.
config SND_ATIIXP
tristate "ATI IXP AC97 Controller"
select SND_AC97_CODEC
......@@ -501,6 +513,16 @@ config SND_ES1968
To compile this driver as a module, choose M here: the module
will be called snd-es1968.
config SND_ES1968_INPUT
bool "Enable input device for es1968 volume buttons"
depends on SND_ES1968
depends on INPUT=y || INPUT=SND_ES1968
help
If you say Y here, you will get an input device which reports
keypresses for the volume buttons connected to the es1968 chip.
If you say N the buttons will directly control the master volume.
It is recommended to say Y.
config SND_FM801
tristate "ForteMedia FM801"
select SND_OPL3_LIB
......@@ -655,6 +677,16 @@ config SND_MAESTRO3
To compile this driver as a module, choose M here: the module
will be called snd-maestro3.
config SND_MAESTRO3_INPUT
bool "Enable input device for maestro3 volume buttons"
depends on SND_MAESTRO3
depends on INPUT=y || INPUT=SND_MAESTRO3
help
If you say Y here, you will get an input device which reports
keypresses for the volume buttons connected to the maestro3 chip.
If you say N the buttons will directly control the master volume.
It is recommended to say Y.
config SND_MIXART
tristate "Digigram miXart"
select SND_HWDEP
......
......@@ -57,6 +57,7 @@ obj-$(CONFIG_SND_VIA82XX_MODEM) += snd-via82xx-modem.o
obj-$(CONFIG_SND) += \
ac97/ \
ali5451/ \
asihpi/ \
au88x0/ \
aw2/ \
ctxfi/ \
......
snd-asihpi-objs := asihpi.o hpioctl.o hpimsginit.o\
hpicmn.o hpifunc.o hpidebug.o hpidspcd.o\
hpios.o hpi6000.o hpi6205.o hpimsgx.o
obj-$(CONFIG_SND_ASIHPI) += snd-asihpi.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*****************************************************************************
AudioScience HPI driver
Copyright (C) 1997-2010 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
published by the Free Software Foundation;
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Public declarations for DSP Proramming Interface to TI C6701
Shared between hpi6000.c and DSP code
(C) Copyright AudioScience Inc. 1998-2003
******************************************************************************/
#ifndef _HPI6000_H_
#define _HPI6000_H_
#define HPI_NMIXER_CONTROLS 200
/*
* Control caching is always supported in the HPI code.
* The DSP should make sure that dwControlCacheSizeInBytes is initialized to 0
* during boot to make it in-active.
*/
struct hpi_hif_6000 {
u32 host_cmd;
u32 dsp_ack;
u32 address;
u32 length;
u32 message_buffer_address;
u32 response_buffer_address;
u32 dsp_number;
u32 adapter_info;
u32 control_cache_is_dirty;
u32 control_cache_address;
u32 control_cache_size_in_bytes;
u32 control_cache_count;
};
#define HPI_HIF_PACK_ADAPTER_INFO(adapter, version_major, version_minor) \
((adapter << 16) | (version_major << 8) | version_minor)
#define HPI_HIF_ADAPTER_INFO_EXTRACT_ADAPTER(adapterinfo) \
((adapterinfo >> 16) & 0xffff)
#define HPI_HIF_ADAPTER_INFO_EXTRACT_HWVERSION_MAJOR(adapterinfo) \
((adapterinfo >> 8) & 0xff)
#define HPI_HIF_ADAPTER_INFO_EXTRACT_HWVERSION_MINOR(adapterinfo) \
(adapterinfo & 0xff)
/* Command/status exchanged between host and DSP */
#define HPI_HIF_IDLE 0
#define HPI_HIF_SEND_MSG 1
#define HPI_HIF_GET_RESP 2
#define HPI_HIF_DATA_MASK 0x10
#define HPI_HIF_SEND_DATA 0x13
#define HPI_HIF_GET_DATA 0x14
#define HPI_HIF_SEND_DONE 5
#define HPI_HIF_RESET 9
#endif /* _HPI6000_H_ */
This diff is collapsed.
/*****************************************************************************
AudioScience HPI driver
Copyright (C) 1997-2010 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
published by the Free Software Foundation;
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Host Interface module for an ASI6205 based
bus mastering PCI adapter.
Copyright AudioScience, Inc., 2003
******************************************************************************/
#ifndef _HPI6205_H_
#define _HPI6205_H_
/* transitional conditional compile shared between host and DSP */
/* #define HPI6205_NO_HSR_POLL */
#include "hpi_internal.h"
/***********************************************************
Defines used for basic messaging
************************************************************/
#define H620_HIF_RESET 0
#define H620_HIF_IDLE 1
#define H620_HIF_GET_RESP 2
#define H620_HIF_DATA_DONE 3
#define H620_HIF_DATA_MASK 0x10
#define H620_HIF_SEND_DATA 0x14
#define H620_HIF_GET_DATA 0x15
#define H620_HIF_UNKNOWN 0x0000ffff
/***********************************************************
Types used for mixer control caching
************************************************************/
#define H620_MAX_ISTREAMS 32
#define H620_MAX_OSTREAMS 32
#define HPI_NMIXER_CONTROLS 2048
/*********************************************************************
This is used for dynamic control cache allocation
**********************************************************************/
struct controlcache_6205 {
u32 number_of_controls;
u32 physical_address32;
u32 size_in_bytes;
};
/*********************************************************************
This is used for dynamic allocation of async event array
**********************************************************************/
struct async_event_buffer_6205 {
u32 physical_address32;
u32 spare;
struct hpi_fifo_buffer b;
};
/***********************************************************
The Host located memory buffer that the 6205 will bus master
in and out of.
************************************************************/
#define HPI6205_SIZEOF_DATA (16*1024)
struct bus_master_interface {
u32 host_cmd;
u32 dsp_ack;
u32 transfer_size_in_bytes;
union {
struct hpi_message message_buffer;
struct hpi_response response_buffer;
u8 b_data[HPI6205_SIZEOF_DATA];
} u;
struct controlcache_6205 control_cache;
struct async_event_buffer_6205 async_buffer;
struct hpi_hostbuffer_status
instream_host_buffer_status[H620_MAX_ISTREAMS];
struct hpi_hostbuffer_status
outstream_host_buffer_status[H620_MAX_OSTREAMS];
};
#endif
This diff is collapsed.
This diff is collapsed.
/**
AudioScience HPI driver
Copyright (C) 1997-2010 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
published by the Free Software Foundation;
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
struct hpi_adapter_obj {
struct hpi_pci pci; /* PCI info - bus#,dev#,address etc */
u16 adapter_type; /* ASI6701 etc */
u16 index; /* */
u16 open; /* =1 when adapter open */
u16 mixer_open;
struct hpios_spinlock dsp_lock;
u16 dsp_crashed;
u16 has_control_cache;
void *priv;
};
struct hpi_control_cache {
u32 init; /**< indicates whether the
structures are initialized */
u32 control_count;
u32 cache_size_in_bytes;
struct hpi_control_cache_info
**p_info; /**< pointer to allocated memory of
lookup pointers. */
struct hpi_control_cache_single
*p_cache; /**< pointer to DSP's control cache. */
};
struct hpi_adapter_obj *hpi_find_adapter(u16 adapter_index);
u16 hpi_add_adapter(struct hpi_adapter_obj *pao);
void hpi_delete_adapter(struct hpi_adapter_obj *pao);
short hpi_check_control_cache(struct hpi_control_cache *pC,
struct hpi_message *phm, struct hpi_response *phr);
struct hpi_control_cache *hpi_alloc_control_cache(const u32
number_of_controls, const u32 size_in_bytes,
struct hpi_control_cache_info
*pDSP_control_buffer);
void hpi_free_control_cache(struct hpi_control_cache *p_cache);
void hpi_sync_control_cache(struct hpi_control_cache *pC,
struct hpi_message *phm, struct hpi_response *phr);
u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr);
short hpi_check_buffer_mapping(struct hpi_control_cache *p_cache,
struct hpi_message *phm, void **p, unsigned int *pN);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/******************************************************************************
AudioScience HPI driver
Copyright (C) 1997-2010 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
published by the Free Software Foundation;
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Hardware Programming Interface (HPI) Utility functions
(C) Copyright AudioScience Inc. 2007
*******************************************************************************/
/* Initialise response headers, or msg/response pairs.
Note that it is valid to just init a response e.g. when a lower level is preparing
a response to a message.
However, when sending a message, a matching response buffer always must be prepared
*/
void hpi_init_response(struct hpi_response *phr, u16 object, u16 function,
u16 error);
void hpi_init_message_response(struct hpi_message *phm,
struct hpi_response *phr, u16 object, u16 function);
void hpi_init_responseV1(struct hpi_response_header *phr, u16 size,
u16 object, u16 function);
void hpi_init_message_responseV1(struct hpi_message_header *phm, u16 msg_size,
struct hpi_response_header *phr, u16 res_size, u16 object,
u16 function);
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -22,8 +22,7 @@ config SND_USB_AUDIO
will be called snd-usb-audio.
config SND_USB_UA101
tristate "Edirol UA-101/UA-1000 driver (EXPERIMENTAL)"
depends on EXPERIMENTAL
tristate "Edirol UA-101/UA-1000 driver"
select SND_PCM
select SND_RAWMIDI
help
......
This diff is collapsed.
......@@ -16,6 +16,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/usb.h>
#include <linux/usb/input.h>
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment