You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge branch 'topic/misc' into for-linus
This commit is contained in:
@@ -195,6 +195,24 @@ config RADIO_MAESTRO
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called radio-maestro.
|
||||
|
||||
config RADIO_MIROPCM20
|
||||
tristate "miroSOUND PCM20 radio"
|
||||
depends on ISA && VIDEO_V4L2
|
||||
select SND_MIRO
|
||||
---help---
|
||||
Choose Y here if you have this FM radio card. You also need to enable
|
||||
the ALSA sound system. This choice automatically selects the ALSA
|
||||
sound card driver "Miro miroSOUND PCM1pro/PCM12/PCM20radio" as this
|
||||
is required for the radio-miropcm20.
|
||||
|
||||
In order to control your radio card, you will need to use programs
|
||||
that are compatible with the Video For Linux API. Information on
|
||||
this API and pointers to "v4l" programs may be found at
|
||||
<file:Documentation/video4linux/API.html>.
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called radio-miropcm20.
|
||||
|
||||
config RADIO_SF16FMI
|
||||
tristate "SF16FMI Radio"
|
||||
depends on ISA && VIDEO_V4L2
|
||||
|
||||
@@ -18,6 +18,7 @@ obj-$(CONFIG_RADIO_TRUST) += radio-trust.o
|
||||
obj-$(CONFIG_I2C_SI4713) += si4713-i2c.o
|
||||
obj-$(CONFIG_RADIO_SI4713) += radio-si4713.o
|
||||
obj-$(CONFIG_RADIO_MAESTRO) += radio-maestro.o
|
||||
obj-$(CONFIG_RADIO_MIROPCM20) += radio-miropcm20.o
|
||||
obj-$(CONFIG_USB_DSBR) += dsbr100.o
|
||||
obj-$(CONFIG_RADIO_SI470X) += si470x/
|
||||
obj-$(CONFIG_USB_MR800) += radio-mr800.o
|
||||
|
||||
@@ -0,0 +1,270 @@
|
||||
/* Miro PCM20 radio driver for Linux radio support
|
||||
* (c) 1998 Ruurd Reitsma <R.A.Reitsma@wbmt.tudelft.nl>
|
||||
* Thanks to Norberto Pellici for the ACI device interface specification
|
||||
* The API part is based on the radiotrack driver by M. Kirkwood
|
||||
* This driver relies on the aci mixer provided by the snd-miro
|
||||
* ALSA driver.
|
||||
* Look there for further info...
|
||||
*/
|
||||
|
||||
/* What ever you think about the ACI, version 0x07 is not very well!
|
||||
* I can't get frequency, 'tuner status', 'tuner flags' or mute/mono
|
||||
* conditions... Robert
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/videodev2.h>
|
||||
#include <media/v4l2-device.h>
|
||||
#include <media/v4l2-ioctl.h>
|
||||
#include <sound/aci.h>
|
||||
|
||||
static int radio_nr = -1;
|
||||
module_param(radio_nr, int, 0);
|
||||
MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");
|
||||
|
||||
static int mono;
|
||||
module_param(mono, bool, 0);
|
||||
MODULE_PARM_DESC(mono, "Force tuner into mono mode.");
|
||||
|
||||
struct pcm20 {
|
||||
struct v4l2_device v4l2_dev;
|
||||
struct video_device vdev;
|
||||
unsigned long freq;
|
||||
int muted;
|
||||
struct snd_miro_aci *aci;
|
||||
};
|
||||
|
||||
static struct pcm20 pcm20_card = {
|
||||
.freq = 87*16000,
|
||||
.muted = 1,
|
||||
};
|
||||
|
||||
static int pcm20_mute(struct pcm20 *dev, unsigned char mute)
|
||||
{
|
||||
dev->muted = mute;
|
||||
return snd_aci_cmd(dev->aci, ACI_SET_TUNERMUTE, mute, -1);
|
||||
}
|
||||
|
||||
static int pcm20_stereo(struct pcm20 *dev, unsigned char stereo)
|
||||
{
|
||||
return snd_aci_cmd(dev->aci, ACI_SET_TUNERMONO, !stereo, -1);
|
||||
}
|
||||
|
||||
static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq)
|
||||
{
|
||||
unsigned char freql;
|
||||
unsigned char freqh;
|
||||
struct snd_miro_aci *aci = dev->aci;
|
||||
|
||||
dev->freq = freq;
|
||||
|
||||
freq /= 160;
|
||||
if (!(aci->aci_version == 0x07 || aci->aci_version >= 0xb0))
|
||||
freq /= 10; /* I don't know exactly which version
|
||||
* needs this hack */
|
||||
freql = freq & 0xff;
|
||||
freqh = freq >> 8;
|
||||
|
||||
pcm20_stereo(dev, !mono);
|
||||
return snd_aci_cmd(aci, ACI_WRITE_TUNE, freql, freqh);
|
||||
}
|
||||
|
||||
static const struct v4l2_file_operations pcm20_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.ioctl = video_ioctl2,
|
||||
};
|
||||
|
||||
static int vidioc_querycap(struct file *file, void *priv,
|
||||
struct v4l2_capability *v)
|
||||
{
|
||||
strlcpy(v->driver, "Miro PCM20", sizeof(v->driver));
|
||||
strlcpy(v->card, "Miro PCM20", sizeof(v->card));
|
||||
strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
|
||||
v->version = 0x1;
|
||||
v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_g_tuner(struct file *file, void *priv,
|
||||
struct v4l2_tuner *v)
|
||||
{
|
||||
if (v->index) /* Only 1 tuner */
|
||||
return -EINVAL;
|
||||
strlcpy(v->name, "FM", sizeof(v->name));
|
||||
v->type = V4L2_TUNER_RADIO;
|
||||
v->rangelow = 87*16000;
|
||||
v->rangehigh = 108*16000;
|
||||
v->signal = 0xffff;
|
||||
v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
|
||||
v->capability = V4L2_TUNER_CAP_LOW;
|
||||
v->audmode = V4L2_TUNER_MODE_MONO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_s_tuner(struct file *file, void *priv,
|
||||
struct v4l2_tuner *v)
|
||||
{
|
||||
return v->index ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
static int vidioc_g_frequency(struct file *file, void *priv,
|
||||
struct v4l2_frequency *f)
|
||||
{
|
||||
struct pcm20 *dev = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0)
|
||||
return -EINVAL;
|
||||
|
||||
f->type = V4L2_TUNER_RADIO;
|
||||
f->frequency = dev->freq;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int vidioc_s_frequency(struct file *file, void *priv,
|
||||
struct v4l2_frequency *f)
|
||||
{
|
||||
struct pcm20 *dev = video_drvdata(file);
|
||||
|
||||
if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO)
|
||||
return -EINVAL;
|
||||
|
||||
dev->freq = f->frequency;
|
||||
pcm20_setfreq(dev, f->frequency);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_queryctrl(struct file *file, void *priv,
|
||||
struct v4l2_queryctrl *qc)
|
||||
{
|
||||
switch (qc->id) {
|
||||
case V4L2_CID_AUDIO_MUTE:
|
||||
return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int vidioc_g_ctrl(struct file *file, void *priv,
|
||||
struct v4l2_control *ctrl)
|
||||
{
|
||||
struct pcm20 *dev = video_drvdata(file);
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_AUDIO_MUTE:
|
||||
ctrl->value = dev->muted;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_s_ctrl(struct file *file, void *priv,
|
||||
struct v4l2_control *ctrl)
|
||||
{
|
||||
struct pcm20 *dev = video_drvdata(file);
|
||||
|
||||
switch (ctrl->id) {
|
||||
case V4L2_CID_AUDIO_MUTE:
|
||||
pcm20_mute(dev, ctrl->value);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
|
||||
{
|
||||
*i = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
|
||||
{
|
||||
return i ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
static int vidioc_g_audio(struct file *file, void *priv,
|
||||
struct v4l2_audio *a)
|
||||
{
|
||||
a->index = 0;
|
||||
strlcpy(a->name, "Radio", sizeof(a->name));
|
||||
a->capability = V4L2_AUDCAP_STEREO;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vidioc_s_audio(struct file *file, void *priv,
|
||||
struct v4l2_audio *a)
|
||||
{
|
||||
return a->index ? -EINVAL : 0;
|
||||
}
|
||||
|
||||
static const struct v4l2_ioctl_ops pcm20_ioctl_ops = {
|
||||
.vidioc_querycap = vidioc_querycap,
|
||||
.vidioc_g_tuner = vidioc_g_tuner,
|
||||
.vidioc_s_tuner = vidioc_s_tuner,
|
||||
.vidioc_g_frequency = vidioc_g_frequency,
|
||||
.vidioc_s_frequency = vidioc_s_frequency,
|
||||
.vidioc_queryctrl = vidioc_queryctrl,
|
||||
.vidioc_g_ctrl = vidioc_g_ctrl,
|
||||
.vidioc_s_ctrl = vidioc_s_ctrl,
|
||||
.vidioc_g_audio = vidioc_g_audio,
|
||||
.vidioc_s_audio = vidioc_s_audio,
|
||||
.vidioc_g_input = vidioc_g_input,
|
||||
.vidioc_s_input = vidioc_s_input,
|
||||
};
|
||||
|
||||
static int __init pcm20_init(void)
|
||||
{
|
||||
struct pcm20 *dev = &pcm20_card;
|
||||
struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
|
||||
int res;
|
||||
|
||||
dev->aci = snd_aci_get_aci();
|
||||
if (dev->aci == NULL) {
|
||||
v4l2_err(v4l2_dev,
|
||||
"you must load the snd-miro driver first!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name));
|
||||
|
||||
|
||||
res = v4l2_device_register(NULL, v4l2_dev);
|
||||
if (res < 0) {
|
||||
v4l2_err(v4l2_dev, "could not register v4l2_device\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
|
||||
dev->vdev.v4l2_dev = v4l2_dev;
|
||||
dev->vdev.fops = &pcm20_fops;
|
||||
dev->vdev.ioctl_ops = &pcm20_ioctl_ops;
|
||||
dev->vdev.release = video_device_release_empty;
|
||||
video_set_drvdata(&dev->vdev, dev);
|
||||
|
||||
if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0)
|
||||
goto fail;
|
||||
|
||||
v4l2_info(v4l2_dev, "Mirosound PCM20 Radio tuner\n");
|
||||
return 0;
|
||||
fail:
|
||||
v4l2_device_unregister(v4l2_dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
MODULE_AUTHOR("Ruurd Reitsma, Krzysztof Helt");
|
||||
MODULE_DESCRIPTION("A driver for the Miro PCM20 radio card.");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
static void __exit pcm20_cleanup(void)
|
||||
{
|
||||
struct pcm20 *dev = &pcm20_card;
|
||||
|
||||
video_unregister_device(&dev->vdev);
|
||||
v4l2_device_unregister(&dev->v4l2_dev);
|
||||
}
|
||||
|
||||
module_init(pcm20_init);
|
||||
module_exit(pcm20_cleanup);
|
||||
@@ -1,5 +1,5 @@
|
||||
#ifndef _MIRO_H_
|
||||
#define _MIRO_H_
|
||||
#ifndef _ACI_H_
|
||||
#define _ACI_H_
|
||||
|
||||
#define ACI_REG_COMMAND 0 /* write register offset */
|
||||
#define ACI_REG_STATUS 1 /* read register offset */
|
||||
@@ -70,4 +70,21 @@
|
||||
#define ACI_SET_EQ6 0x45
|
||||
#define ACI_SET_EQ7 0x46 /* ... to Treble */
|
||||
|
||||
#endif /* _MIRO_H_ */
|
||||
struct snd_miro_aci {
|
||||
unsigned long aci_port;
|
||||
int aci_vendor;
|
||||
int aci_product;
|
||||
int aci_version;
|
||||
int aci_amp;
|
||||
int aci_preamp;
|
||||
int aci_solomode;
|
||||
|
||||
struct mutex aci_mutex;
|
||||
};
|
||||
|
||||
int snd_aci_cmd(struct snd_miro_aci *aci, int write1, int write2, int write3);
|
||||
|
||||
struct snd_miro_aci *snd_aci_get_aci(void);
|
||||
|
||||
#endif /* _ACI_H_ */
|
||||
|
||||
@@ -70,7 +70,6 @@
|
||||
#define AD1845_PWR_DOWN 0x1b /* power down control */
|
||||
#define CS4235_LEFT_MASTER 0x1b /* left master output control */
|
||||
#define CS4231_REC_FORMAT 0x1c /* clock and data format - record - bits 7-0 MCE */
|
||||
#define CS4231_PLY_VAR_FREQ 0x1d /* playback variable frequency */
|
||||
#define AD1845_CLOCK 0x1d /* crystal clock select and total power down */
|
||||
#define CS4235_RIGHT_MASTER 0x1d /* right master output control */
|
||||
#define CS4231_REC_UPR_CNT 0x1e /* record upper count */
|
||||
|
||||
@@ -154,7 +154,6 @@ int snd_wss_create(struct snd_card *card,
|
||||
unsigned short hardware,
|
||||
unsigned short hwshare,
|
||||
struct snd_wss **rchip);
|
||||
int snd_wss_free(struct snd_wss *chip);
|
||||
int snd_wss_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm);
|
||||
int snd_wss_timer(struct snd_wss *chip, int device, struct snd_timer **rtimer);
|
||||
int snd_wss_mixer(struct snd_wss *chip);
|
||||
|
||||
+1
-1
@@ -58,7 +58,7 @@ config SOUND_OSS_CORE_PRECLAIM
|
||||
Please read Documentation/feature-removal-schedule.txt for
|
||||
details.
|
||||
|
||||
If unusre, say Y.
|
||||
If unsure, say Y.
|
||||
|
||||
source "sound/oss/dmasound/Kconfig"
|
||||
|
||||
|
||||
+5
-14
@@ -18,10 +18,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/amba/bus.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/sizes.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <sound/core.h>
|
||||
#include <sound/initval.h>
|
||||
@@ -513,15 +510,9 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
|
||||
err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
|
||||
params_channels(params),
|
||||
aacirun->pcm->r[0].slots);
|
||||
else
|
||||
err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
|
||||
params_channels(params),
|
||||
aacirun->pcm->r[0].slots);
|
||||
|
||||
err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
|
||||
params_channels(params),
|
||||
aacirun->pcm->r[0].slots);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
@@ -537,7 +528,7 @@ static int aaci_pcm_prepare(struct snd_pcm_substream *substream)
|
||||
struct aaci_runtime *aacirun = runtime->private_data;
|
||||
|
||||
aacirun->start = (void *)runtime->dma_area;
|
||||
aacirun->end = aacirun->start + runtime->dma_bytes;
|
||||
aacirun->end = aacirun->start + snd_pcm_lib_buffer_bytes(substream);
|
||||
aacirun->ptr = aacirun->start;
|
||||
aacirun->period =
|
||||
aacirun->bytes = frames_to_bytes(runtime, runtime->period_size);
|
||||
|
||||
@@ -1119,7 +1119,7 @@ static int snd_ctl_tlv_ioctl(struct snd_ctl_file *file,
|
||||
goto __kctl_end;
|
||||
}
|
||||
if (vd->access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
|
||||
if (file && vd->owner != NULL && vd->owner != file) {
|
||||
if (vd->owner != NULL && vd->owner != file) {
|
||||
err = -EPERM;
|
||||
goto __kctl_end;
|
||||
}
|
||||
|
||||
+2
-13
@@ -23,6 +23,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/bitrev.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/control.h>
|
||||
@@ -55,18 +56,6 @@ struct cs8427 {
|
||||
struct cs8427_stream capture;
|
||||
};
|
||||
|
||||
static unsigned char swapbits(unsigned char val)
|
||||
{
|
||||
int bit;
|
||||
unsigned char res = 0;
|
||||
for (bit = 0; bit < 8; bit++) {
|
||||
res <<= 1;
|
||||
res |= val & 1;
|
||||
val >>= 1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int snd_cs8427_reg_write(struct snd_i2c_device *device, unsigned char reg,
|
||||
unsigned char val)
|
||||
{
|
||||
@@ -149,7 +138,7 @@ static int snd_cs8427_send_corudata(struct snd_i2c_device *device,
|
||||
}
|
||||
data[0] = CS8427_REG_AUTOINC | CS8427_REG_CORU_DATABUF;
|
||||
for (idx = 0; idx < count; idx++)
|
||||
data[idx + 1] = swapbits(ndata[idx]);
|
||||
data[idx + 1] = bitrev8(ndata[idx]);
|
||||
if (snd_i2c_sendbytes(device, data, count + 1) != count + 1)
|
||||
return -EIO;
|
||||
return 1;
|
||||
|
||||
@@ -225,7 +225,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
|
||||
case V4L2_CID_AUDIO_MUTE:
|
||||
if (tea->ops->mute) {
|
||||
tea->ops->mute(tea, ctrl->value);
|
||||
tea->mute = 1;
|
||||
tea->mute = ctrl->value;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -394,21 +394,15 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
err = snd_wss_create(card, port[dev], cport[dev],
|
||||
err = snd_cs4236_create(card, port[dev], cport[dev],
|
||||
irq[dev],
|
||||
dma1[dev], dma2[dev],
|
||||
WSS_HW_DETECT3, 0, &chip);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
acard->chip = chip;
|
||||
if (chip->hardware & WSS_HW_CS4236B_MASK) {
|
||||
snd_wss_free(chip);
|
||||
err = snd_cs4236_create(card,
|
||||
port[dev], cport[dev],
|
||||
irq[dev], dma1[dev], dma2[dev],
|
||||
WSS_HW_DETECT, 0, &chip);
|
||||
if (err < 0)
|
||||
return err;
|
||||
acard->chip = chip;
|
||||
|
||||
err = snd_cs4236_pcm(chip, 0, &pcm);
|
||||
if (err < 0)
|
||||
@@ -418,7 +412,6 @@ static int __devinit snd_cs423x_probe(struct snd_card *card, int dev)
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else {
|
||||
acard->chip = chip;
|
||||
err = snd_wss_pcm(chip, 0, &pcm);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
+155
-86
@@ -87,6 +87,8 @@
|
||||
#include <sound/core.h>
|
||||
#include <sound/wss.h>
|
||||
#include <sound/asoundef.h>
|
||||
#include <sound/initval.h>
|
||||
#include <sound/tlv.h>
|
||||
|
||||
/*
|
||||
*
|
||||
@@ -264,7 +266,10 @@ static void snd_cs4236_resume(struct snd_wss *chip)
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
/*
|
||||
* This function does no fail if the chip is not CS4236B or compatible.
|
||||
* It just an equivalent to the snd_wss_create() then.
|
||||
*/
|
||||
int snd_cs4236_create(struct snd_card *card,
|
||||
unsigned long port,
|
||||
unsigned long cport,
|
||||
@@ -281,21 +286,17 @@ int snd_cs4236_create(struct snd_card *card,
|
||||
*rchip = NULL;
|
||||
if (hardware == WSS_HW_DETECT)
|
||||
hardware = WSS_HW_DETECT3;
|
||||
if (cport < 0x100) {
|
||||
snd_printk(KERN_ERR "please, specify control port "
|
||||
"for CS4236+ chips\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
err = snd_wss_create(card, port, cport,
|
||||
irq, dma1, dma2, hardware, hwshare, &chip);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (!(chip->hardware & WSS_HW_CS4236B_MASK)) {
|
||||
snd_printk(KERN_ERR "CS4236+: MODE3 and extended registers "
|
||||
"not available, hardware=0x%x\n", chip->hardware);
|
||||
snd_device_free(card, chip);
|
||||
return -ENODEV;
|
||||
if ((chip->hardware & WSS_HW_CS4236B_MASK) == 0) {
|
||||
snd_printd("chip is not CS4236+, hardware=0x%x\n",
|
||||
chip->hardware);
|
||||
*rchip = chip;
|
||||
return 0;
|
||||
}
|
||||
#if 0
|
||||
{
|
||||
@@ -308,9 +309,16 @@ int snd_cs4236_create(struct snd_card *card,
|
||||
idx, snd_cs4236_ctrl_in(chip, idx));
|
||||
}
|
||||
#endif
|
||||
if (cport < 0x100 || cport == SNDRV_AUTO_PORT) {
|
||||
snd_printk(KERN_ERR "please, specify control port "
|
||||
"for CS4236+ chips\n");
|
||||
snd_device_free(card, chip);
|
||||
return -ENODEV;
|
||||
}
|
||||
ver1 = snd_cs4236_ctrl_in(chip, 1);
|
||||
ver2 = snd_cs4236_ext_in(chip, CS4236_VERSION);
|
||||
snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n", cport, ver1, ver2);
|
||||
snd_printdd("CS4236: [0x%lx] C1 (version) = 0x%x, ext = 0x%x\n",
|
||||
cport, ver1, ver2);
|
||||
if (ver1 != ver2) {
|
||||
snd_printk(KERN_ERR "CS4236+ chip detected, but "
|
||||
"control port 0x%lx is not valid\n", cport);
|
||||
@@ -321,13 +329,17 @@ int snd_cs4236_create(struct snd_card *card,
|
||||
snd_cs4236_ctrl_out(chip, 2, 0xff);
|
||||
snd_cs4236_ctrl_out(chip, 3, 0x00);
|
||||
snd_cs4236_ctrl_out(chip, 4, 0x80);
|
||||
snd_cs4236_ctrl_out(chip, 5, ((IEC958_AES1_CON_PCM_CODER & 3) << 6) | IEC958_AES0_CON_EMPHASIS_NONE);
|
||||
reg = ((IEC958_AES1_CON_PCM_CODER & 3) << 6) |
|
||||
IEC958_AES0_CON_EMPHASIS_NONE;
|
||||
snd_cs4236_ctrl_out(chip, 5, reg);
|
||||
snd_cs4236_ctrl_out(chip, 6, IEC958_AES1_CON_PCM_CODER >> 2);
|
||||
snd_cs4236_ctrl_out(chip, 7, 0x00);
|
||||
/* 0x8c for C8 is valid for Turtle Beach Malibu - the IEC-958 output */
|
||||
/* is working with this setup, other hardware should have */
|
||||
/* different signal paths and this value should be selectable */
|
||||
/* in the future */
|
||||
/*
|
||||
* 0x8c for C8 is valid for Turtle Beach Malibu - the IEC-958
|
||||
* output is working with this setup, other hardware should
|
||||
* have different signal paths and this value should be
|
||||
* selectable in the future
|
||||
*/
|
||||
snd_cs4236_ctrl_out(chip, 8, 0x8c);
|
||||
chip->rate_constraint = snd_cs4236_xrate;
|
||||
chip->set_playback_format = snd_cs4236_playback_format;
|
||||
@@ -339,9 +351,10 @@ int snd_cs4236_create(struct snd_card *card,
|
||||
|
||||
/* initialize extended registers */
|
||||
for (reg = 0; reg < sizeof(snd_cs4236_ext_map); reg++)
|
||||
snd_cs4236_ext_out(chip, CS4236_I23VAL(reg), snd_cs4236_ext_map[reg]);
|
||||
snd_cs4236_ext_out(chip, CS4236_I23VAL(reg),
|
||||
snd_cs4236_ext_map[reg]);
|
||||
|
||||
/* initialize compatible but more featured registers */
|
||||
/* initialize compatible but more featured registers */
|
||||
snd_wss_out(chip, CS4231_LEFT_INPUT, 0x40);
|
||||
snd_wss_out(chip, CS4231_RIGHT_INPUT, 0x40);
|
||||
snd_wss_out(chip, CS4231_AUX1_LEFT_INPUT, 0xff);
|
||||
@@ -387,6 +400,14 @@ int snd_cs4236_pcm(struct snd_wss *chip, int device, struct snd_pcm **rpcm)
|
||||
.get = snd_cs4236_get_single, .put = snd_cs4236_put_single, \
|
||||
.private_value = reg | (shift << 8) | (mask << 16) | (invert << 24) }
|
||||
|
||||
#define CS4236_SINGLE_TLV(xname, xindex, reg, shift, mask, invert, xtlv) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
|
||||
.info = snd_cs4236_info_single, \
|
||||
.get = snd_cs4236_get_single, .put = snd_cs4236_put_single, \
|
||||
.private_value = reg | (shift << 8) | (mask << 16) | (invert << 24), \
|
||||
.tlv = { .p = (xtlv) } }
|
||||
|
||||
static int snd_cs4236_info_single(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
int mask = (kcontrol->private_value >> 16) & 0xff;
|
||||
@@ -490,6 +511,16 @@ static int snd_cs4236_put_singlec(struct snd_kcontrol *kcontrol, struct snd_ctl_
|
||||
.get = snd_cs4236_get_double, .put = snd_cs4236_put_double, \
|
||||
.private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
|
||||
|
||||
#define CS4236_DOUBLE_TLV(xname, xindex, left_reg, right_reg, shift_left, \
|
||||
shift_right, mask, invert, xtlv) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
|
||||
.info = snd_cs4236_info_double, \
|
||||
.get = snd_cs4236_get_double, .put = snd_cs4236_put_double, \
|
||||
.private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
|
||||
(shift_right << 19) | (mask << 24) | (invert << 22), \
|
||||
.tlv = { .p = (xtlv) } }
|
||||
|
||||
static int snd_cs4236_info_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
int mask = (kcontrol->private_value >> 24) & 0xff;
|
||||
@@ -560,12 +591,23 @@ static int snd_cs4236_put_double(struct snd_kcontrol *kcontrol, struct snd_ctl_e
|
||||
return change;
|
||||
}
|
||||
|
||||
#define CS4236_DOUBLE1(xname, xindex, left_reg, right_reg, shift_left, shift_right, mask, invert) \
|
||||
#define CS4236_DOUBLE1(xname, xindex, left_reg, right_reg, shift_left, \
|
||||
shift_right, mask, invert) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
|
||||
.info = snd_cs4236_info_double, \
|
||||
.get = snd_cs4236_get_double1, .put = snd_cs4236_put_double1, \
|
||||
.private_value = left_reg | (right_reg << 8) | (shift_left << 16) | (shift_right << 19) | (mask << 24) | (invert << 22) }
|
||||
|
||||
#define CS4236_DOUBLE1_TLV(xname, xindex, left_reg, right_reg, shift_left, \
|
||||
shift_right, mask, invert, xtlv) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
|
||||
.info = snd_cs4236_info_double, \
|
||||
.get = snd_cs4236_get_double1, .put = snd_cs4236_put_double1, \
|
||||
.private_value = left_reg | (right_reg << 8) | (shift_left << 16) | \
|
||||
(shift_right << 19) | (mask << 24) | (invert << 22), \
|
||||
.tlv = { .p = (xtlv) } }
|
||||
|
||||
static int snd_cs4236_get_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
struct snd_wss *chip = snd_kcontrol_chip(kcontrol);
|
||||
@@ -619,16 +661,18 @@ static int snd_cs4236_put_double1(struct snd_kcontrol *kcontrol, struct snd_ctl_
|
||||
return change;
|
||||
}
|
||||
|
||||
#define CS4236_MASTER_DIGITAL(xname, xindex) \
|
||||
#define CS4236_MASTER_DIGITAL(xname, xindex, xtlv) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
|
||||
.info = snd_cs4236_info_double, \
|
||||
.get = snd_cs4236_get_master_digital, .put = snd_cs4236_put_master_digital, \
|
||||
.private_value = 71 << 24 }
|
||||
.private_value = 71 << 24, \
|
||||
.tlv = { .p = (xtlv) } }
|
||||
|
||||
static inline int snd_cs4236_mixer_master_digital_invert_volume(int vol)
|
||||
{
|
||||
return (vol < 64) ? 63 - vol : 64 + (71 - vol);
|
||||
}
|
||||
}
|
||||
|
||||
static int snd_cs4236_get_master_digital(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
|
||||
{
|
||||
@@ -661,11 +705,13 @@ static int snd_cs4236_put_master_digital(struct snd_kcontrol *kcontrol, struct s
|
||||
return change;
|
||||
}
|
||||
|
||||
#define CS4235_OUTPUT_ACCU(xname, xindex) \
|
||||
#define CS4235_OUTPUT_ACCU(xname, xindex, xtlv) \
|
||||
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xindex, \
|
||||
.access = SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ, \
|
||||
.info = snd_cs4236_info_double, \
|
||||
.get = snd_cs4235_get_output_accu, .put = snd_cs4235_put_output_accu, \
|
||||
.private_value = 3 << 24 }
|
||||
.private_value = 3 << 24, \
|
||||
.tlv = { .p = (xtlv) } }
|
||||
|
||||
static inline int snd_cs4235_mixer_output_accu_get_volume(int vol)
|
||||
{
|
||||
@@ -720,41 +766,56 @@ static int snd_cs4235_put_output_accu(struct snd_kcontrol *kcontrol, struct snd_
|
||||
return change;
|
||||
}
|
||||
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_7bit, -9450, 150, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_6bit, -9450, 150, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_6bit_12db_max, -8250, 150, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_5bit_12db_max, -3450, 150, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_5bit_22db_max, -2400, 150, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_4bit, -4500, 300, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_2bit, -1800, 600, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_rec_gain, 0, 150, 0);
|
||||
|
||||
static struct snd_kcontrol_new snd_cs4236_controls[] = {
|
||||
|
||||
CS4236_DOUBLE("Master Digital Playback Switch", 0,
|
||||
CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1),
|
||||
CS4236_DOUBLE("Master Digital Capture Switch", 0,
|
||||
CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
|
||||
CS4236_MASTER_DIGITAL("Master Digital Volume", 0),
|
||||
CS4236_MASTER_DIGITAL("Master Digital Volume", 0, db_scale_7bit),
|
||||
|
||||
CS4236_DOUBLE("Capture Boost Volume", 0,
|
||||
CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1),
|
||||
CS4236_DOUBLE_TLV("Capture Boost Volume", 0,
|
||||
CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1,
|
||||
db_scale_2bit),
|
||||
|
||||
WSS_DOUBLE("PCM Playback Switch", 0,
|
||||
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("PCM Playback Volume", 0,
|
||||
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
|
||||
WSS_DOUBLE_TLV("PCM Playback Volume", 0,
|
||||
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
|
||||
db_scale_6bit),
|
||||
|
||||
CS4236_DOUBLE("DSP Playback Switch", 0,
|
||||
CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1),
|
||||
CS4236_DOUBLE("DSP Playback Volume", 0,
|
||||
CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 0, 0, 63, 1),
|
||||
CS4236_DOUBLE_TLV("DSP Playback Volume", 0,
|
||||
CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 0, 0, 63, 1,
|
||||
db_scale_6bit),
|
||||
|
||||
CS4236_DOUBLE("FM Playback Switch", 0,
|
||||
CS4236_LEFT_FM, CS4236_RIGHT_FM, 7, 7, 1, 1),
|
||||
CS4236_DOUBLE("FM Playback Volume", 0,
|
||||
CS4236_LEFT_FM, CS4236_RIGHT_FM, 0, 0, 63, 1),
|
||||
CS4236_DOUBLE_TLV("FM Playback Volume", 0,
|
||||
CS4236_LEFT_FM, CS4236_RIGHT_FM, 0, 0, 63, 1,
|
||||
db_scale_6bit),
|
||||
|
||||
CS4236_DOUBLE("Wavetable Playback Switch", 0,
|
||||
CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 7, 7, 1, 1),
|
||||
CS4236_DOUBLE("Wavetable Playback Volume", 0,
|
||||
CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 0, 0, 63, 1),
|
||||
CS4236_DOUBLE_TLV("Wavetable Playback Volume", 0,
|
||||
CS4236_LEFT_WAVE, CS4236_RIGHT_WAVE, 0, 0, 63, 1,
|
||||
db_scale_6bit_12db_max),
|
||||
|
||||
WSS_DOUBLE("Synth Playback Switch", 0,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("Synth Volume", 0,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1),
|
||||
WSS_DOUBLE_TLV("Synth Volume", 0,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
|
||||
db_scale_5bit_12db_max),
|
||||
WSS_DOUBLE("Synth Capture Switch", 0,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1),
|
||||
WSS_DOUBLE("Synth Capture Bypass", 0,
|
||||
@@ -764,14 +825,16 @@ CS4236_DOUBLE("Mic Playback Switch", 0,
|
||||
CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1),
|
||||
CS4236_DOUBLE("Mic Capture Switch", 0,
|
||||
CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1),
|
||||
CS4236_DOUBLE("Mic Volume", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 0, 0, 31, 1),
|
||||
CS4236_DOUBLE("Mic Playback Boost", 0,
|
||||
CS4236_DOUBLE_TLV("Mic Volume", 0, CS4236_LEFT_MIC, CS4236_RIGHT_MIC,
|
||||
0, 0, 31, 1, db_scale_5bit_22db_max),
|
||||
CS4236_DOUBLE("Mic Playback Boost (+20dB)", 0,
|
||||
CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 5, 5, 1, 0),
|
||||
|
||||
WSS_DOUBLE("Line Playback Switch", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("Line Volume", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1),
|
||||
WSS_DOUBLE_TLV("Line Volume", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
|
||||
db_scale_5bit_12db_max),
|
||||
WSS_DOUBLE("Line Capture Switch", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1),
|
||||
WSS_DOUBLE("Line Capture Bypass", 0,
|
||||
@@ -779,57 +842,63 @@ WSS_DOUBLE("Line Capture Bypass", 0,
|
||||
|
||||
WSS_DOUBLE("CD Playback Switch", 0,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("CD Volume", 0,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
|
||||
WSS_DOUBLE_TLV("CD Volume", 0,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
|
||||
db_scale_5bit_12db_max),
|
||||
WSS_DOUBLE("CD Capture Switch", 0,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1),
|
||||
|
||||
CS4236_DOUBLE1("Mono Output Playback Switch", 0,
|
||||
CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1),
|
||||
CS4236_DOUBLE1("Mono Playback Switch", 0,
|
||||
CS4236_DOUBLE1("Beep Playback Switch", 0,
|
||||
CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1),
|
||||
WSS_SINGLE("Mono Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
|
||||
WSS_SINGLE("Mono Playback Bypass", 0, CS4231_MONO_CTRL, 5, 1, 0),
|
||||
WSS_SINGLE_TLV("Beep Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1,
|
||||
db_scale_4bit),
|
||||
WSS_SINGLE("Beep Bypass Playback Switch", 0, CS4231_MONO_CTRL, 5, 1, 0),
|
||||
|
||||
WSS_DOUBLE("Capture Volume", 0,
|
||||
CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 0, 0, 15, 0),
|
||||
WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
|
||||
0, 0, 15, 0, db_scale_rec_gain),
|
||||
WSS_DOUBLE("Analog Loopback Capture Switch", 0,
|
||||
CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0),
|
||||
|
||||
WSS_SINGLE("Digital Loopback Playback Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
|
||||
CS4236_DOUBLE1("Digital Loopback Playback Volume", 0,
|
||||
CS4231_LOOPBACK, CS4236_RIGHT_LOOPBACK, 2, 0, 63, 1)
|
||||
WSS_SINGLE("Loopback Digital Playback Switch", 0, CS4231_LOOPBACK, 0, 1, 0),
|
||||
CS4236_DOUBLE1_TLV("Loopback Digital Playback Volume", 0,
|
||||
CS4231_LOOPBACK, CS4236_RIGHT_LOOPBACK, 2, 0, 63, 1,
|
||||
db_scale_6bit),
|
||||
};
|
||||
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_5bit_6db_max, -5600, 200, 0);
|
||||
static const DECLARE_TLV_DB_SCALE(db_scale_2bit_16db_max, -2400, 800, 0);
|
||||
|
||||
static struct snd_kcontrol_new snd_cs4235_controls[] = {
|
||||
|
||||
WSS_DOUBLE("Master Switch", 0,
|
||||
WSS_DOUBLE("Master Playback Switch", 0,
|
||||
CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("Master Volume", 0,
|
||||
CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 0, 0, 31, 1),
|
||||
WSS_DOUBLE_TLV("Master Playback Volume", 0,
|
||||
CS4235_LEFT_MASTER, CS4235_RIGHT_MASTER, 0, 0, 31, 1,
|
||||
db_scale_5bit_6db_max),
|
||||
|
||||
CS4235_OUTPUT_ACCU("Playback Volume", 0),
|
||||
CS4235_OUTPUT_ACCU("Playback Volume", 0, db_scale_2bit_16db_max),
|
||||
|
||||
CS4236_DOUBLE("Master Digital Playback Switch", 0,
|
||||
CS4236_LEFT_MASTER, CS4236_RIGHT_MASTER, 7, 7, 1, 1),
|
||||
CS4236_DOUBLE("Master Digital Capture Switch", 0,
|
||||
CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
|
||||
CS4236_MASTER_DIGITAL("Master Digital Volume", 0),
|
||||
|
||||
WSS_DOUBLE("Master Digital Playback Switch", 1,
|
||||
WSS_DOUBLE("Synth Playback Switch", 1,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("Master Digital Capture Switch", 1,
|
||||
WSS_DOUBLE("Synth Capture Switch", 1,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 6, 6, 1, 1),
|
||||
WSS_DOUBLE("Master Digital Volume", 1,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1),
|
||||
WSS_DOUBLE_TLV("Synth Volume", 1,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
|
||||
db_scale_5bit_12db_max),
|
||||
|
||||
CS4236_DOUBLE("Capture Volume", 0,
|
||||
CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1),
|
||||
CS4236_DOUBLE_TLV("Capture Volume", 0,
|
||||
CS4236_LEFT_MIX_CTRL, CS4236_RIGHT_MIX_CTRL, 5, 5, 3, 1,
|
||||
db_scale_2bit),
|
||||
|
||||
WSS_DOUBLE("PCM Switch", 0,
|
||||
WSS_DOUBLE("PCM Playback Switch", 0,
|
||||
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("PCM Volume", 0,
|
||||
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1),
|
||||
WSS_DOUBLE("PCM Capture Switch", 0,
|
||||
CS4236_DAC_MUTE, CS4236_DAC_MUTE, 7, 6, 1, 1),
|
||||
WSS_DOUBLE_TLV("PCM Volume", 0,
|
||||
CS4231_LEFT_OUTPUT, CS4231_RIGHT_OUTPUT, 0, 0, 63, 1,
|
||||
db_scale_6bit),
|
||||
|
||||
CS4236_DOUBLE("DSP Switch", 0, CS4236_LEFT_DSP, CS4236_RIGHT_DSP, 7, 7, 1, 1),
|
||||
|
||||
@@ -842,29 +911,29 @@ CS4236_DOUBLE("Mic Capture Switch", 0,
|
||||
CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 7, 7, 1, 1),
|
||||
CS4236_DOUBLE("Mic Playback Switch", 0,
|
||||
CS4236_LEFT_MIC, CS4236_RIGHT_MIC, 6, 6, 1, 1),
|
||||
CS4236_SINGLE("Mic Volume", 0, CS4236_LEFT_MIC, 0, 31, 1),
|
||||
CS4236_SINGLE("Mic Playback Boost", 0, CS4236_LEFT_MIC, 5, 1, 0),
|
||||
CS4236_SINGLE_TLV("Mic Volume", 0, CS4236_LEFT_MIC, 0, 31, 1,
|
||||
db_scale_5bit_22db_max),
|
||||
CS4236_SINGLE("Mic Boost (+20dB)", 0, CS4236_LEFT_MIC, 5, 1, 0),
|
||||
|
||||
WSS_DOUBLE("Aux Playback Switch", 0,
|
||||
WSS_DOUBLE("Line Playback Switch", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("Aux Capture Switch", 0,
|
||||
WSS_DOUBLE("Line Capture Switch", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 6, 6, 1, 1),
|
||||
WSS_DOUBLE("Aux Volume", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1),
|
||||
WSS_DOUBLE_TLV("Line Volume", 0,
|
||||
CS4231_AUX1_LEFT_INPUT, CS4231_AUX1_RIGHT_INPUT, 0, 0, 31, 1,
|
||||
db_scale_5bit_12db_max),
|
||||
|
||||
WSS_DOUBLE("Aux Playback Switch", 1,
|
||||
WSS_DOUBLE("CD Playback Switch", 1,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 7, 7, 1, 1),
|
||||
WSS_DOUBLE("Aux Capture Switch", 1,
|
||||
WSS_DOUBLE("CD Capture Switch", 1,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 6, 6, 1, 1),
|
||||
WSS_DOUBLE("Aux Volume", 1,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1),
|
||||
WSS_DOUBLE_TLV("CD Volume", 1,
|
||||
CS4231_AUX2_LEFT_INPUT, CS4231_AUX2_RIGHT_INPUT, 0, 0, 31, 1,
|
||||
db_scale_5bit_12db_max),
|
||||
|
||||
CS4236_DOUBLE1("Master Mono Switch", 0,
|
||||
CS4231_MONO_CTRL, CS4236_RIGHT_MIX_CTRL, 6, 7, 1, 1),
|
||||
|
||||
CS4236_DOUBLE1("Mono Switch", 0,
|
||||
CS4236_DOUBLE1("Beep Playback Switch", 0,
|
||||
CS4231_MONO_CTRL, CS4236_LEFT_MIX_CTRL, 7, 7, 1, 1),
|
||||
WSS_SINGLE("Mono Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
|
||||
WSS_SINGLE("Beep Playback Volume", 0, CS4231_MONO_CTRL, 0, 15, 1),
|
||||
|
||||
WSS_DOUBLE("Analog Loopback Switch", 0,
|
||||
CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 7, 7, 1, 0),
|
||||
|
||||
+41
-50
@@ -102,8 +102,6 @@
|
||||
|
||||
struct snd_es18xx {
|
||||
unsigned long port; /* port of ESS chip */
|
||||
unsigned long mpu_port; /* MPU-401 port of ESS chip */
|
||||
unsigned long fm_port; /* FM port */
|
||||
unsigned long ctrl_port; /* Control port of ESS chip */
|
||||
struct resource *res_port;
|
||||
struct resource *res_mpu_port;
|
||||
@@ -116,8 +114,6 @@ struct snd_es18xx {
|
||||
unsigned short audio2_vol; /* volume level of audio2 */
|
||||
|
||||
unsigned short active; /* active channel mask */
|
||||
unsigned int dma1_size;
|
||||
unsigned int dma2_size;
|
||||
unsigned int dma1_shift;
|
||||
unsigned int dma2_shift;
|
||||
|
||||
@@ -135,7 +131,6 @@ struct snd_es18xx {
|
||||
|
||||
spinlock_t reg_lock;
|
||||
spinlock_t mixer_lock;
|
||||
spinlock_t ctrl_lock;
|
||||
#ifdef CONFIG_PM
|
||||
unsigned char pm_reg;
|
||||
#endif
|
||||
@@ -354,7 +349,7 @@ static inline int snd_es18xx_mixer_writable(struct snd_es18xx *chip, unsigned ch
|
||||
}
|
||||
|
||||
|
||||
static int snd_es18xx_reset(struct snd_es18xx *chip)
|
||||
static int __devinit snd_es18xx_reset(struct snd_es18xx *chip)
|
||||
{
|
||||
int i;
|
||||
outb(0x03, chip->port + 0x06);
|
||||
@@ -490,8 +485,6 @@ static int snd_es18xx_playback1_prepare(struct snd_es18xx *chip,
|
||||
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
|
||||
unsigned int count = snd_pcm_lib_period_bytes(substream);
|
||||
|
||||
chip->dma2_size = size;
|
||||
|
||||
snd_es18xx_rate_set(chip, substream, DAC2);
|
||||
|
||||
/* Transfer Count Reload */
|
||||
@@ -591,8 +584,6 @@ static int snd_es18xx_capture_prepare(struct snd_pcm_substream *substream)
|
||||
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
|
||||
unsigned int count = snd_pcm_lib_period_bytes(substream);
|
||||
|
||||
chip->dma1_size = size;
|
||||
|
||||
snd_es18xx_reset_fifo(chip);
|
||||
|
||||
/* Set stereo/mono */
|
||||
@@ -659,8 +650,6 @@ static int snd_es18xx_playback2_prepare(struct snd_es18xx *chip,
|
||||
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
|
||||
unsigned int count = snd_pcm_lib_period_bytes(substream);
|
||||
|
||||
chip->dma1_size = size;
|
||||
|
||||
snd_es18xx_reset_fifo(chip);
|
||||
|
||||
/* Set stereo/mono */
|
||||
@@ -821,17 +810,18 @@ static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id)
|
||||
static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
|
||||
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
|
||||
int pos;
|
||||
|
||||
if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) {
|
||||
if (!(chip->active & DAC2))
|
||||
return 0;
|
||||
pos = snd_dma_pointer(chip->dma2, chip->dma2_size);
|
||||
pos = snd_dma_pointer(chip->dma2, size);
|
||||
return pos >> chip->dma2_shift;
|
||||
} else {
|
||||
if (!(chip->active & DAC1))
|
||||
return 0;
|
||||
pos = snd_dma_pointer(chip->dma1, chip->dma1_size);
|
||||
pos = snd_dma_pointer(chip->dma1, size);
|
||||
return pos >> chip->dma1_shift;
|
||||
}
|
||||
}
|
||||
@@ -839,11 +829,12 @@ static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *s
|
||||
static snd_pcm_uframes_t snd_es18xx_capture_pointer(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_es18xx *chip = snd_pcm_substream_chip(substream);
|
||||
unsigned int size = snd_pcm_lib_buffer_bytes(substream);
|
||||
int pos;
|
||||
|
||||
if (!(chip->active & ADC1))
|
||||
return 0;
|
||||
pos = snd_dma_pointer(chip->dma1, chip->dma1_size);
|
||||
pos = snd_dma_pointer(chip->dma1, size);
|
||||
return pos >> chip->dma1_shift;
|
||||
}
|
||||
|
||||
@@ -974,9 +965,6 @@ static int snd_es18xx_capture_close(struct snd_pcm_substream *substream)
|
||||
|
||||
static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
|
||||
{
|
||||
static char *texts4Source[4] = {
|
||||
"Mic", "CD", "Line", "Master"
|
||||
};
|
||||
static char *texts5Source[5] = {
|
||||
"Mic", "CD", "Line", "Master", "Mix"
|
||||
};
|
||||
@@ -994,7 +982,8 @@ static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_ele
|
||||
uinfo->value.enumerated.items = 4;
|
||||
if (uinfo->value.enumerated.item > 3)
|
||||
uinfo->value.enumerated.item = 3;
|
||||
strcpy(uinfo->value.enumerated.name, texts4Source[uinfo->value.enumerated.item]);
|
||||
strcpy(uinfo->value.enumerated.name,
|
||||
texts5Source[uinfo->value.enumerated.item]);
|
||||
break;
|
||||
case 0x1887:
|
||||
case 0x1888:
|
||||
@@ -1378,11 +1367,9 @@ ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0),
|
||||
static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg)
|
||||
{
|
||||
int data;
|
||||
unsigned long flags;
|
||||
spin_lock_irqsave(&chip->ctrl_lock, flags);
|
||||
|
||||
outb(reg, chip->ctrl_port);
|
||||
data = inb(chip->ctrl_port + 1);
|
||||
spin_unlock_irqrestore(&chip->ctrl_lock, flags);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -1398,7 +1385,9 @@ static void __devinit snd_es18xx_config_write(struct snd_es18xx *chip,
|
||||
#endif
|
||||
}
|
||||
|
||||
static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip)
|
||||
static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip,
|
||||
unsigned long mpu_port,
|
||||
unsigned long fm_port)
|
||||
{
|
||||
int mask = 0;
|
||||
|
||||
@@ -1412,15 +1401,15 @@ static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip)
|
||||
if (chip->caps & ES18XX_CONTROL) {
|
||||
/* Hardware volume IRQ */
|
||||
snd_es18xx_config_write(chip, 0x27, chip->irq);
|
||||
if (chip->fm_port > 0 && chip->fm_port != SNDRV_AUTO_PORT) {
|
||||
if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
|
||||
/* FM I/O */
|
||||
snd_es18xx_config_write(chip, 0x62, chip->fm_port >> 8);
|
||||
snd_es18xx_config_write(chip, 0x63, chip->fm_port & 0xff);
|
||||
snd_es18xx_config_write(chip, 0x62, fm_port >> 8);
|
||||
snd_es18xx_config_write(chip, 0x63, fm_port & 0xff);
|
||||
}
|
||||
if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) {
|
||||
if (mpu_port > 0 && mpu_port != SNDRV_AUTO_PORT) {
|
||||
/* MPU-401 I/O */
|
||||
snd_es18xx_config_write(chip, 0x64, chip->mpu_port >> 8);
|
||||
snd_es18xx_config_write(chip, 0x65, chip->mpu_port & 0xff);
|
||||
snd_es18xx_config_write(chip, 0x64, mpu_port >> 8);
|
||||
snd_es18xx_config_write(chip, 0x65, mpu_port & 0xff);
|
||||
/* MPU-401 IRQ */
|
||||
snd_es18xx_config_write(chip, 0x28, chip->irq);
|
||||
}
|
||||
@@ -1507,11 +1496,12 @@ static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip)
|
||||
snd_es18xx_mixer_write(chip, 0x7A, 0x68);
|
||||
/* Enable and set hardware volume interrupt */
|
||||
snd_es18xx_mixer_write(chip, 0x64, 0x06);
|
||||
if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) {
|
||||
if (mpu_port > 0 && mpu_port != SNDRV_AUTO_PORT) {
|
||||
/* MPU401 share irq with audio
|
||||
Joystick enabled
|
||||
FM enabled */
|
||||
snd_es18xx_mixer_write(chip, 0x40, 0x43 | (chip->mpu_port & 0xf0) >> 1);
|
||||
snd_es18xx_mixer_write(chip, 0x40,
|
||||
0x43 | (mpu_port & 0xf0) >> 1);
|
||||
}
|
||||
snd_es18xx_mixer_write(chip, 0x7f, ((irqmask + 1) << 1) | 0x01);
|
||||
}
|
||||
@@ -1629,7 +1619,9 @@ static int __devinit snd_es18xx_identify(struct snd_es18xx *chip)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __devinit snd_es18xx_probe(struct snd_es18xx *chip)
|
||||
static int __devinit snd_es18xx_probe(struct snd_es18xx *chip,
|
||||
unsigned long mpu_port,
|
||||
unsigned long fm_port)
|
||||
{
|
||||
if (snd_es18xx_identify(chip) < 0) {
|
||||
snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port);
|
||||
@@ -1650,8 +1642,6 @@ static int __devinit snd_es18xx_probe(struct snd_es18xx *chip)
|
||||
chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV;
|
||||
break;
|
||||
case 0x1887:
|
||||
chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME;
|
||||
break;
|
||||
case 0x1888:
|
||||
chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME;
|
||||
break;
|
||||
@@ -1666,7 +1656,7 @@ static int __devinit snd_es18xx_probe(struct snd_es18xx *chip)
|
||||
if (chip->dma1 == chip->dma2)
|
||||
chip->caps &= ~(ES18XX_PCM2 | ES18XX_DUPLEX_SAME);
|
||||
|
||||
return snd_es18xx_initialize(chip);
|
||||
return snd_es18xx_initialize(chip, mpu_port, fm_port);
|
||||
}
|
||||
|
||||
static struct snd_pcm_ops snd_es18xx_playback_ops = {
|
||||
@@ -1802,10 +1792,7 @@ static int __devinit snd_es18xx_new_device(struct snd_card *card,
|
||||
|
||||
spin_lock_init(&chip->reg_lock);
|
||||
spin_lock_init(&chip->mixer_lock);
|
||||
spin_lock_init(&chip->ctrl_lock);
|
||||
chip->port = port;
|
||||
chip->mpu_port = mpu_port;
|
||||
chip->fm_port = fm_port;
|
||||
chip->irq = -1;
|
||||
chip->dma1 = -1;
|
||||
chip->dma2 = -1;
|
||||
@@ -1841,11 +1828,11 @@ static int __devinit snd_es18xx_new_device(struct snd_card *card,
|
||||
}
|
||||
chip->dma2 = dma2;
|
||||
|
||||
if (snd_es18xx_probe(chip) < 0) {
|
||||
if (snd_es18xx_probe(chip, mpu_port, fm_port) < 0) {
|
||||
snd_es18xx_free(card);
|
||||
return -ENODEV;
|
||||
}
|
||||
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, NULL, &ops);
|
||||
return -ENODEV;
|
||||
}
|
||||
err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops);
|
||||
if (err < 0) {
|
||||
snd_es18xx_free(card);
|
||||
return err;
|
||||
@@ -1980,7 +1967,7 @@ 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 */
|
||||
#ifdef CONFIG_PNP
|
||||
static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1};
|
||||
static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP;
|
||||
#endif
|
||||
static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */
|
||||
#ifndef CONFIG_PNP
|
||||
@@ -2160,19 +2147,23 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev)
|
||||
return err;
|
||||
|
||||
if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) {
|
||||
if (snd_opl3_create(card, chip->fm_port, chip->fm_port + 2, OPL3_HW_OPL3, 0, &opl3) < 0) {
|
||||
snd_printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->fm_port);
|
||||
if (snd_opl3_create(card, fm_port[dev], fm_port[dev] + 2,
|
||||
OPL3_HW_OPL3, 0, &opl3) < 0) {
|
||||
snd_printk(KERN_WARNING PFX
|
||||
"opl3 not detected at 0x%lx\n",
|
||||
fm_port[dev]);
|
||||
} else {
|
||||
if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0)
|
||||
err = snd_opl3_hwdep_new(opl3, 0, 1, NULL);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) {
|
||||
if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX,
|
||||
chip->mpu_port, 0,
|
||||
irq[dev], 0,
|
||||
&chip->rmidi)) < 0)
|
||||
err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX,
|
||||
mpu_port[dev], 0,
|
||||
irq[dev], 0, &chip->rmidi);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
+514
-277
File diff suppressed because it is too large
Load Diff
@@ -141,15 +141,7 @@ struct snd_opti9xx {
|
||||
|
||||
spinlock_t lock;
|
||||
|
||||
long wss_base;
|
||||
int irq;
|
||||
int dma1;
|
||||
int dma2;
|
||||
|
||||
long fm_port;
|
||||
|
||||
long mpu_port;
|
||||
int mpu_irq;
|
||||
|
||||
#ifdef CONFIG_PNP
|
||||
struct pnp_dev *dev;
|
||||
@@ -216,13 +208,7 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip,
|
||||
|
||||
spin_lock_init(&chip->lock);
|
||||
|
||||
chip->wss_base = -1;
|
||||
chip->irq = -1;
|
||||
chip->dma1 = -1;
|
||||
chip->dma2 = -1;
|
||||
chip->fm_port = -1;
|
||||
chip->mpu_port = -1;
|
||||
chip->mpu_irq = -1;
|
||||
|
||||
switch (hardware) {
|
||||
#ifndef OPTi93X
|
||||
@@ -348,7 +334,10 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg,
|
||||
(snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask)))
|
||||
|
||||
|
||||
static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
|
||||
static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip,
|
||||
long wss_base,
|
||||
int irq, int dma1, int dma2,
|
||||
long mpu_port, int mpu_irq)
|
||||
{
|
||||
unsigned char wss_base_bits;
|
||||
unsigned char irq_bits;
|
||||
@@ -416,7 +405,7 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (chip->wss_base) {
|
||||
switch (wss_base) {
|
||||
case 0x530:
|
||||
wss_base_bits = 0x00;
|
||||
break;
|
||||
@@ -430,14 +419,13 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
|
||||
wss_base_bits = 0x02;
|
||||
break;
|
||||
default:
|
||||
snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n",
|
||||
chip->wss_base);
|
||||
snd_printk(KERN_WARNING "WSS port 0x%lx not valid\n", wss_base);
|
||||
goto __skip_base;
|
||||
}
|
||||
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(1), wss_base_bits << 4, 0x30);
|
||||
|
||||
__skip_base:
|
||||
switch (chip->irq) {
|
||||
switch (irq) {
|
||||
//#ifdef OPTi93X
|
||||
case 5:
|
||||
irq_bits = 0x05;
|
||||
@@ -456,11 +444,11 @@ __skip_base:
|
||||
irq_bits = 0x04;
|
||||
break;
|
||||
default:
|
||||
snd_printk(KERN_WARNING "WSS irq # %d not valid\n", chip->irq);
|
||||
snd_printk(KERN_WARNING "WSS irq # %d not valid\n", irq);
|
||||
goto __skip_resources;
|
||||
}
|
||||
|
||||
switch (chip->dma1) {
|
||||
switch (dma1) {
|
||||
case 0:
|
||||
dma_bits = 0x01;
|
||||
break;
|
||||
@@ -471,38 +459,36 @@ __skip_base:
|
||||
dma_bits = 0x03;
|
||||
break;
|
||||
default:
|
||||
snd_printk(KERN_WARNING "WSS dma1 # %d not valid\n",
|
||||
chip->dma1);
|
||||
snd_printk(KERN_WARNING "WSS dma1 # %d not valid\n", dma1);
|
||||
goto __skip_resources;
|
||||
}
|
||||
|
||||
#if defined(CS4231) || defined(OPTi93X)
|
||||
if (chip->dma1 == chip->dma2) {
|
||||
if (dma1 == dma2) {
|
||||
snd_printk(KERN_ERR "don't want to share dmas\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
switch (chip->dma2) {
|
||||
switch (dma2) {
|
||||
case 0:
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
snd_printk(KERN_WARNING "WSS dma2 # %d not valid\n",
|
||||
chip->dma2);
|
||||
snd_printk(KERN_WARNING "WSS dma2 # %d not valid\n", dma2);
|
||||
goto __skip_resources;
|
||||
}
|
||||
dma_bits |= 0x04;
|
||||
#endif /* CS4231 || OPTi93X */
|
||||
|
||||
#ifndef OPTi93X
|
||||
outb(irq_bits << 3 | dma_bits, chip->wss_base);
|
||||
outb(irq_bits << 3 | dma_bits, wss_base);
|
||||
#else /* OPTi93X */
|
||||
snd_opti9xx_write(chip, OPTi9XX_MC_REG(3), (irq_bits << 3 | dma_bits));
|
||||
#endif /* OPTi93X */
|
||||
|
||||
__skip_resources:
|
||||
if (chip->hardware > OPTi9XX_HW_82C928) {
|
||||
switch (chip->mpu_port) {
|
||||
switch (mpu_port) {
|
||||
case 0:
|
||||
case -1:
|
||||
break;
|
||||
@@ -520,12 +506,11 @@ __skip_resources:
|
||||
break;
|
||||
default:
|
||||
snd_printk(KERN_WARNING
|
||||
"MPU-401 port 0x%lx not valid\n",
|
||||
chip->mpu_port);
|
||||
"MPU-401 port 0x%lx not valid\n", mpu_port);
|
||||
goto __skip_mpu;
|
||||
}
|
||||
|
||||
switch (chip->mpu_irq) {
|
||||
switch (mpu_irq) {
|
||||
case 5:
|
||||
mpu_irq_bits = 0x02;
|
||||
break;
|
||||
@@ -540,12 +525,12 @@ __skip_resources:
|
||||
break;
|
||||
default:
|
||||
snd_printk(KERN_WARNING "MPU-401 irq # %d not valid\n",
|
||||
chip->mpu_irq);
|
||||
mpu_irq);
|
||||
goto __skip_mpu;
|
||||
}
|
||||
|
||||
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(6),
|
||||
(chip->mpu_port <= 0) ? 0x00 :
|
||||
(mpu_port <= 0) ? 0x00 :
|
||||
0x80 | mpu_port_bits << 5 | mpu_irq_bits << 3,
|
||||
0xf8);
|
||||
}
|
||||
@@ -701,6 +686,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
|
||||
{
|
||||
static long possible_ports[] = {0x530, 0xe80, 0xf40, 0x604, -1};
|
||||
int error;
|
||||
int xdma2;
|
||||
struct snd_opti9xx *chip = card->private_data;
|
||||
struct snd_wss *codec;
|
||||
#ifdef CS4231
|
||||
@@ -715,31 +701,25 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
|
||||
"OPTi9xx MC")) == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
chip->wss_base = port;
|
||||
chip->fm_port = fm_port;
|
||||
chip->mpu_port = mpu_port;
|
||||
chip->irq = irq;
|
||||
chip->mpu_irq = mpu_irq;
|
||||
chip->dma1 = dma1;
|
||||
#if defined(CS4231) || defined(OPTi93X)
|
||||
chip->dma2 = dma2;
|
||||
xdma2 = dma2;
|
||||
#else
|
||||
chip->dma2 = -1;
|
||||
xdma2 = -1;
|
||||
#endif
|
||||
|
||||
if (chip->wss_base == SNDRV_AUTO_PORT) {
|
||||
chip->wss_base = snd_legacy_find_free_ioport(possible_ports, 4);
|
||||
if (chip->wss_base < 0) {
|
||||
if (port == SNDRV_AUTO_PORT) {
|
||||
port = snd_legacy_find_free_ioport(possible_ports, 4);
|
||||
if (port < 0) {
|
||||
snd_printk(KERN_ERR "unable to find a free WSS port\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
error = snd_opti9xx_configure(chip);
|
||||
error = snd_opti9xx_configure(chip, port, irq, dma1, xdma2,
|
||||
mpu_port, mpu_irq);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = snd_wss_create(card, chip->wss_base + 4, -1,
|
||||
chip->irq, chip->dma1, chip->dma2,
|
||||
error = snd_wss_create(card, port + 4, -1, irq, dma1, xdma2,
|
||||
#ifdef OPTi93X
|
||||
WSS_HW_OPTI93X, WSS_HWSHARE_IRQ,
|
||||
#else
|
||||
@@ -763,35 +743,35 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
|
||||
return error;
|
||||
#endif
|
||||
#ifdef OPTi93X
|
||||
error = request_irq(chip->irq, snd_opti93x_interrupt,
|
||||
error = request_irq(irq, snd_opti93x_interrupt,
|
||||
IRQF_DISABLED, DEV_NAME" - WSS", codec);
|
||||
if (error < 0) {
|
||||
snd_printk(KERN_ERR "opti9xx: can't grab IRQ %d\n", chip->irq);
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
chip->irq = irq;
|
||||
strcpy(card->driver, chip->name);
|
||||
sprintf(card->shortname, "OPTi %s", card->driver);
|
||||
#if defined(CS4231) || defined(OPTi93X)
|
||||
sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d&%d",
|
||||
card->shortname, pcm->name, chip->wss_base + 4,
|
||||
chip->irq, chip->dma1, chip->dma2);
|
||||
card->shortname, pcm->name, port + 4, irq, dma1, xdma2);
|
||||
#else
|
||||
sprintf(card->longname, "%s, %s at 0x%lx, irq %d, dma %d",
|
||||
card->shortname, pcm->name, chip->wss_base + 4,
|
||||
chip->irq, chip->dma1);
|
||||
card->shortname, pcm->name, port + 4, irq, dma1);
|
||||
#endif /* CS4231 || OPTi93X */
|
||||
|
||||
if (chip->mpu_port <= 0 || chip->mpu_port == SNDRV_AUTO_PORT)
|
||||
if (mpu_port <= 0 || mpu_port == SNDRV_AUTO_PORT)
|
||||
rmidi = NULL;
|
||||
else
|
||||
if ((error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
|
||||
chip->mpu_port, 0, chip->mpu_irq, IRQF_DISABLED,
|
||||
&rmidi)))
|
||||
else {
|
||||
error = snd_mpu401_uart_new(card, 0, MPU401_HW_MPU401,
|
||||
mpu_port, 0, mpu_irq, IRQF_DISABLED, &rmidi);
|
||||
if (error)
|
||||
snd_printk(KERN_WARNING "no MPU-401 device at 0x%lx?\n",
|
||||
chip->mpu_port);
|
||||
mpu_port);
|
||||
}
|
||||
|
||||
if (chip->fm_port > 0 && chip->fm_port != SNDRV_AUTO_PORT) {
|
||||
if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) {
|
||||
struct snd_opl3 *opl3 = NULL;
|
||||
#ifndef OPTi93X
|
||||
if (chip->hardware == OPTi9XX_HW_82C928 ||
|
||||
@@ -801,9 +781,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
|
||||
/* assume we have an OPL4 */
|
||||
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
|
||||
0x20, 0x20);
|
||||
if (snd_opl4_create(card,
|
||||
chip->fm_port,
|
||||
chip->fm_port - 8,
|
||||
if (snd_opl4_create(card, fm_port, fm_port - 8,
|
||||
2, &opl3, &opl4) < 0) {
|
||||
/* no luck, use OPL3 instead */
|
||||
snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(2),
|
||||
@@ -811,12 +789,10 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card)
|
||||
}
|
||||
}
|
||||
#endif /* !OPTi93X */
|
||||
if (!opl3 && snd_opl3_create(card,
|
||||
chip->fm_port,
|
||||
chip->fm_port + 2,
|
||||
if (!opl3 && snd_opl3_create(card, fm_port, fm_port + 2,
|
||||
OPL3_HW_AUTO, 0, &opl3) < 0) {
|
||||
snd_printk(KERN_WARNING "no OPL device at 0x%lx-0x%lx\n",
|
||||
chip->fm_port, chip->fm_port + 4 - 1);
|
||||
fm_port, fm_port + 4 - 1);
|
||||
}
|
||||
if (opl3) {
|
||||
error = snd_opl3_hwdep_new(opl3, 0, 1, &synth);
|
||||
|
||||
@@ -1682,7 +1682,7 @@ static void snd_wss_resume(struct snd_wss *chip)
|
||||
}
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
int snd_wss_free(struct snd_wss *chip)
|
||||
static int snd_wss_free(struct snd_wss *chip)
|
||||
{
|
||||
release_and_free_resource(chip->res_port);
|
||||
release_and_free_resource(chip->res_cport);
|
||||
@@ -1705,7 +1705,6 @@ int snd_wss_free(struct snd_wss *chip)
|
||||
kfree(chip);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(snd_wss_free);
|
||||
|
||||
static int snd_wss_dev_free(struct snd_device *device)
|
||||
{
|
||||
@@ -2225,7 +2224,7 @@ WSS_DOUBLE_TLV("Capture Volume", 0, CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT,
|
||||
.get = snd_wss_get_mux,
|
||||
.put = snd_wss_put_mux,
|
||||
},
|
||||
WSS_DOUBLE("Mic Boost", 0,
|
||||
WSS_DOUBLE("Mic Boost (+20dB)", 0,
|
||||
CS4231_LEFT_INPUT, CS4231_RIGHT_INPUT, 5, 5, 1, 0),
|
||||
WSS_SINGLE("Loopback Capture Switch", 0,
|
||||
CS4231_LOOPBACK, 0, 1, 0),
|
||||
@@ -2236,14 +2235,14 @@ WSS_DOUBLE("Line Playback Switch", 0,
|
||||
WSS_DOUBLE_TLV("Line Playback Volume", 0,
|
||||
CS4231_LEFT_LINE_IN, CS4231_RIGHT_LINE_IN, 0, 0, 31, 1,
|
||||
db_scale_5bit_12db_max),
|
||||
WSS_SINGLE("Mono Playback Switch", 0,
|
||||
WSS_SINGLE("Beep Playback Switch", 0,
|
||||
CS4231_MONO_CTRL, 7, 1, 1),
|
||||
WSS_SINGLE_TLV("Mono Playback Volume", 0,
|
||||
WSS_SINGLE_TLV("Beep Playback Volume", 0,
|
||||
CS4231_MONO_CTRL, 0, 15, 1,
|
||||
db_scale_4bit),
|
||||
WSS_SINGLE("Mono Output Playback Switch", 0,
|
||||
CS4231_MONO_CTRL, 6, 1, 1),
|
||||
WSS_SINGLE("Mono Output Playback Bypass", 0,
|
||||
WSS_SINGLE("Beep Bypass Playback Switch", 0,
|
||||
CS4231_MONO_CTRL, 5, 1, 0),
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -838,7 +838,7 @@ static int dma_ioctl(int dev, unsigned int cmd, void __user *arg)
|
||||
if ((err = audio_devs[dev]->d->prepare_for_input(dev,
|
||||
dmap_in->fragment_size, dmap_in->nbufs)) < 0) {
|
||||
spin_unlock_irqrestore(&dmap_in->lock,flags);
|
||||
return -err;
|
||||
return err;
|
||||
}
|
||||
dmap_in->dma_mode = DMODE_INPUT;
|
||||
audio_devs[dev]->enable_bits |= PCM_ENABLE_INPUT;
|
||||
|
||||
@@ -426,7 +426,7 @@ midi_synth_open(int dev, int mode)
|
||||
int err;
|
||||
struct midi_input_info *inc;
|
||||
|
||||
if (orig_dev < 0 || orig_dev > num_midis || midi_devs[orig_dev] == NULL)
|
||||
if (orig_dev < 0 || orig_dev >= num_midis || midi_devs[orig_dev] == NULL)
|
||||
return -ENXIO;
|
||||
|
||||
midi2synth[orig_dev] = dev;
|
||||
|
||||
+1
-1
@@ -770,7 +770,7 @@ static int mpu_synth_ioctl(int dev, unsigned int cmd, void __user *arg)
|
||||
|
||||
midi_dev = synth_devs[dev]->midi_dev;
|
||||
|
||||
if (midi_dev < 0 || midi_dev > num_midis || midi_devs[midi_dev] == NULL)
|
||||
if (midi_dev < 0 || midi_dev >= num_midis || midi_devs[midi_dev] == NULL)
|
||||
return -ENXIO;
|
||||
|
||||
devc = &dev_conf[midi_dev];
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user