Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
57648cd5
Commit
57648cd5
authored
Dec 04, 2009
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/misc' into for-linus
parents
79598324
fb716c0b
Changes
36
Show whitespace changes
Inline
Side-by-side
Showing
36 changed files
with
1463 additions
and
702 deletions
+1463
-702
drivers/media/radio/Kconfig
drivers/media/radio/Kconfig
+18
-0
drivers/media/radio/Makefile
drivers/media/radio/Makefile
+1
-0
drivers/media/radio/radio-miropcm20.c
drivers/media/radio/radio-miropcm20.c
+270
-0
include/sound/aci.h
include/sound/aci.h
+20
-3
include/sound/cs4231-regs.h
include/sound/cs4231-regs.h
+0
-1
include/sound/wss.h
include/sound/wss.h
+0
-1
sound/Kconfig
sound/Kconfig
+1
-1
sound/arm/aaci.c
sound/arm/aaci.c
+5
-14
sound/core/control.c
sound/core/control.c
+1
-1
sound/i2c/cs8427.c
sound/i2c/cs8427.c
+2
-13
sound/i2c/other/tea575x-tuner.c
sound/i2c/other/tea575x-tuner.c
+1
-1
sound/isa/cs423x/cs4236.c
sound/isa/cs423x/cs4236.c
+3
-10
sound/isa/cs423x/cs4236_lib.c
sound/isa/cs423x/cs4236_lib.c
+155
-86
sound/isa/es18xx.c
sound/isa/es18xx.c
+41
-50
sound/isa/opti9xx/miro.c
sound/isa/opti9xx/miro.c
+510
-273
sound/isa/opti9xx/opti92x-ad1848.c
sound/isa/opti9xx/opti92x-ad1848.c
+43
-67
sound/isa/wss/wss_lib.c
sound/isa/wss/wss_lib.c
+5
-6
sound/oss/audio.c
sound/oss/audio.c
+1
-1
sound/oss/midi_synth.c
sound/oss/midi_synth.c
+1
-1
sound/oss/mpu401.c
sound/oss/mpu401.c
+1
-1
sound/pci/Kconfig
sound/pci/Kconfig
+1
-0
sound/pci/fm801.c
sound/pci/fm801.c
+27
-13
sound/pci/ice1712/juli.c
sound/pci/ice1712/juli.c
+32
-0
sound/pci/intel8x0.c
sound/pci/intel8x0.c
+6
-0
sound/usb/usbaudio.c
sound/usb/usbaudio.c
+23
-15
sound/usb/usbaudio.h
sound/usb/usbaudio.h
+4
-3
sound/usb/usbmidi.c
sound/usb/usbmidi.c
+155
-53
sound/usb/usbmixer_maps.c
sound/usb/usbmixer_maps.c
+23
-0
sound/usb/usbquirks.h
sound/usb/usbquirks.h
+23
-0
sound/usb/usx2y/us122l.c
sound/usb/usx2y/us122l.c
+44
-46
sound/usb/usx2y/us122l.h
sound/usb/usx2y/us122l.h
+3
-1
sound/usb/usx2y/usX2Yhwdep.c
sound/usb/usx2y/usX2Yhwdep.c
+4
-4
sound/usb/usx2y/usbusx2y.c
sound/usb/usx2y/usbusx2y.c
+13
-15
sound/usb/usx2y/usbusx2y.h
sound/usb/usx2y/usbusx2y.h
+5
-1
sound/usb/usx2y/usbusx2yaudio.c
sound/usb/usx2y/usbusx2yaudio.c
+17
-17
sound/usb/usx2y/usx2yhwdeppcm.c
sound/usb/usx2y/usx2yhwdeppcm.c
+4
-4
No files found.
drivers/media/radio/Kconfig
View file @
57648cd5
...
...
@@ -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
...
...
drivers/media/radio/Makefile
View file @
57648cd5
...
...
@@ -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
...
...
drivers/media/radio/radio-miropcm20.c
0 → 100644
View file @
57648cd5
/* 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
);
sound/isa/opti9xx/miro
.h
→
include/sound/aci
.h
View file @
57648cd5
#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_ */
include/sound/cs4231-regs.h
View file @
57648cd5
...
...
@@ -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 */
...
...
include/sound/wss.h
View file @
57648cd5
...
...
@@ -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
);
...
...
sound/Kconfig
View file @
57648cd5
...
...
@@ -58,7 +58,7 @@ config SOUND_OSS_CORE_PRECLAIM
Please read Documentation/feature-removal-schedule.txt for
details.
If un
us
re, say Y.
If un
su
re, say Y.
source "sound/oss/dmasound/Kconfig"
...
...
sound/arm/aaci.c
View file @
57648cd5
...
...
@@ -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
);
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
);
...
...
sound/core/control.c
View file @
57648cd5
...
...
@@ -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
;
}
...
...
sound/i2c/cs8427.c
View file @
57648cd5
...
...
@@ -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
;
...
...
sound/i2c/other/tea575x-tuner.c
View file @
57648cd5
...
...
@@ -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
;
}
}
...
...
sound/isa/cs423x/cs4236.c
View file @
57648cd5
...
...
@@ -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
;
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
;
if
(
chip
->
hardware
&
WSS_HW_CS4236B_MASK
)
{
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
;
...
...
sound/isa/cs423x/cs4236_lib.c
View file @
57648cd5
...
...
@@ -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_print
k
(
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_print
d
(
"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,7 +351,8 @@ 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 */
snd_wss_out
(
chip
,
CS4231_LEFT_INPUT
,
0x40
);
...
...
@@ -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,11 +661,13 @@ 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
)
{
...
...
@@ -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
),
CS4236_DOUBLE1
(
"Master Mono Switch"
,
0
,
CS4231_MONO_CTRL
,
CS4236_RIGHT_MIX_CTRL
,
6
,
7
,
1
,
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
(
"
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
),
...
...
sound/isa/es18xx.c
View file @
57648cd5
...
...
@@ -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
);
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
;
}
...
...
sound/isa/opti9xx/miro.c
View file @
57648cd5
...
...
@@ -25,6 +25,7 @@
#include <linux/init.h>
#include <linux/err.h>
#include <linux/isa.h>
#include <linux/pnp.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/ioport.h>
...
...
@@ -40,7 +41,7 @@
#define SNDRV_LEGACY_FIND_FREE_IRQ
#define SNDRV_LEGACY_FIND_FREE_DMA
#include <sound/initval.h>
#include
"miro.h"
#include
<sound/aci.h>
MODULE_AUTHOR
(
"Martin Langer <martin-langer@gmx.de>"
);
MODULE_LICENSE
(
"GPL"
);
...
...
@@ -60,6 +61,9 @@ static int dma1 = SNDRV_DEFAULT_DMA1; /* 0,1,3 */
static
int
dma2
=
SNDRV_DEFAULT_DMA1
;
/* 0,1,3 */
static
int
wss
;
static
int
ide
;
#ifdef CONFIG_PNP
static
int
isapnp
=
1
;
/* Enable ISA PnP detection */
#endif
module_param
(
index
,
int
,
0444
);
MODULE_PARM_DESC
(
index
,
"Index value for miro soundcard."
);
...
...
@@ -83,6 +87,10 @@ module_param(wss, int, 0444);
MODULE_PARM_DESC
(
wss
,
"wss mode"
);
module_param
(
ide
,
int
,
0444
);
MODULE_PARM_DESC
(
ide
,
"enable ide port"
);
#ifdef CONFIG_PNP
module_param
(
isapnp
,
bool
,
0444
);
MODULE_PARM_DESC
(
isapnp
,
"Enable ISA PnP detection for specified soundcard."
);
#endif
#define OPTi9XX_HW_DETECT 0
#define OPTi9XX_HW_82C928 1
...
...
@@ -96,7 +104,6 @@ MODULE_PARM_DESC(ide, "enable ide port");
#define OPTi9XX_MC_REG(n) n
struct
snd_miro
{
unsigned
short
hardware
;
unsigned
char
password
;
...
...
@@ -110,7 +117,6 @@ struct snd_miro {
unsigned
long
pwd_reg
;
spinlock_t
lock
;
struct
snd_card
*
card
;
struct
snd_pcm
*
pcm
;
long
wss_base
;
...
...
@@ -118,23 +124,13 @@ struct snd_miro {
int
dma1
;
int
dma2
;
long
fm_port
;
long
mpu_port
;
int
mpu_irq
;
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
;
struct
snd_miro_aci
*
aci
;
};
static
void
snd_miro_proc_init
(
struct
snd_miro
*
miro
)
;
static
struct
snd_miro_aci
aci_device
;
static
char
*
snd_opti9xx_names
[]
=
{
"unkown"
,
...
...
@@ -143,17 +139,33 @@ static char * snd_opti9xx_names[] = {
"82C930"
,
"82C931"
,
"82C933"
};
static
int
snd_miro_pnp_is_probed
;
#ifdef CONFIG_PNP
static
struct
pnp_card_device_id
snd_miro_pnpids
[]
=
{
/* PCM20 and PCM12 in PnP mode */
{
.
id
=
"MIR0924"
,
.
devs
=
{
{
"MIR0000"
},
{
"MIR0002"
},
{
"MIR0005"
}
},
},
{
.
id
=
""
}
};
MODULE_DEVICE_TABLE
(
pnp_card
,
snd_miro_pnpids
);
#endif
/* CONFIG_PNP */
/*
* ACI control
*/
static
int
aci_busy_wait
(
struct
snd_miro
*
miro
)
static
int
aci_busy_wait
(
struct
snd_miro
_aci
*
aci
)
{
long
timeout
;
unsigned
char
byte
;
for
(
timeout
=
1
;
timeout
<=
ACI_MINTIME
+
30
;
timeout
++
)
{
if
(((
byte
=
inb
(
miro
->
aci_port
+
ACI_REG_BUSY
))
&
1
)
==
0
)
{
for
(
timeout
=
1
;
timeout
<=
ACI_MINTIME
+
30
;
timeout
++
)
{
byte
=
inb
(
aci
->
aci_port
+
ACI_REG_BUSY
);
if
((
byte
&
1
)
==
0
)
{
if
(
timeout
>=
ACI_MINTIME
)
snd_printd
(
"aci ready in round %ld.
\n
"
,
timeout
-
ACI_MINTIME
);
...
...
@@ -179,10 +191,10 @@ static int aci_busy_wait(struct snd_miro * miro)
return
-
EBUSY
;
}
static
inline
int
aci_write
(
struct
snd_miro
*
miro
,
unsigned
char
byte
)
static
inline
int
aci_write
(
struct
snd_miro
_aci
*
aci
,
unsigned
char
byte
)
{
if
(
aci_busy_wait
(
miro
)
>=
0
)
{
outb
(
byte
,
miro
->
aci_port
+
ACI_REG_COMMAND
);
if
(
aci_busy_wait
(
aci
)
>=
0
)
{
outb
(
byte
,
aci
->
aci_port
+
ACI_REG_COMMAND
);
return
0
;
}
else
{
snd_printk
(
KERN_ERR
"aci busy, aci_write(0x%x) stopped.
\n
"
,
byte
);
...
...
@@ -190,12 +202,12 @@ static inline int aci_write(struct snd_miro * miro, unsigned char byte)
}
}
static
inline
int
aci_read
(
struct
snd_miro
*
miro
)
static
inline
int
aci_read
(
struct
snd_miro
_aci
*
aci
)
{
unsigned
char
byte
;
if
(
aci_busy_wait
(
miro
)
>=
0
)
{
byte
=
inb
(
miro
->
aci_port
+
ACI_REG_STATUS
);
if
(
aci_busy_wait
(
aci
)
>=
0
)
{
byte
=
inb
(
aci
->
aci_port
+
ACI_REG_STATUS
);
return
byte
;
}
else
{
snd_printk
(
KERN_ERR
"aci busy, aci_read() stopped.
\n
"
);
...
...
@@ -203,40 +215,50 @@ static inline int aci_read(struct snd_miro * miro)
}
}
static
int
aci_cmd
(
struct
snd_miro
*
miro
,
int
write1
,
int
write2
,
int
write3
)
int
snd_aci_cmd
(
struct
snd_miro_aci
*
aci
,
int
write1
,
int
write2
,
int
write3
)
{
int
write
[]
=
{
write1
,
write2
,
write3
};
int
value
,
i
;
if
(
mutex_lock_interruptible
(
&
miro
->
aci_mutex
))
if
(
mutex_lock_interruptible
(
&
aci
->
aci_mutex
))
return
-
EINTR
;
for
(
i
=
0
;
i
<
3
;
i
++
)
{
if
(
write
[
i
]
<
0
||
write
[
i
]
>
255
)
break
;
else
{
value
=
aci_write
(
miro
,
write
[
i
]);
value
=
aci_write
(
aci
,
write
[
i
]);
if
(
value
<
0
)
goto
out
;
}
}
value
=
aci_read
(
miro
);
value
=
aci_read
(
aci
);
out:
mutex_unlock
(
&
miro
->
aci_mutex
);
out:
mutex_unlock
(
&
aci
->
aci_mutex
);
return
value
;
}
EXPORT_SYMBOL
(
snd_aci_cmd
);
static
int
aci_getvalue
(
struct
snd_miro
*
miro
,
unsigned
char
index
)
static
int
aci_getvalue
(
struct
snd_miro
_aci
*
aci
,
unsigned
char
index
)
{
return
aci_cmd
(
miro
,
ACI_STATUS
,
index
,
-
1
);
return
snd_aci_cmd
(
aci
,
ACI_STATUS
,
index
,
-
1
);
}
static
int
aci_setvalue
(
struct
snd_miro
*
miro
,
unsigned
char
index
,
int
value
)
static
int
aci_setvalue
(
struct
snd_miro_aci
*
aci
,
unsigned
char
index
,
int
value
)
{
return
aci_cmd
(
miro
,
index
,
value
,
-
1
);
return
snd_aci_cmd
(
aci
,
index
,
value
,
-
1
);
}
struct
snd_miro_aci
*
snd_aci_get_aci
(
void
)
{
if
(
aci_device
.
aci_port
==
0
)
return
NULL
;
return
&
aci_device
;
}
EXPORT_SYMBOL
(
snd_aci_get_aci
);
/*
* MIXER part
*/
...
...
@@ -249,8 +271,10 @@ static int snd_miro_get_capture(struct snd_kcontrol *kcontrol,
struct
snd_miro
*
miro
=
snd_kcontrol_chip
(
kcontrol
);
int
value
;
if
((
value
=
aci_getvalue
(
miro
,
ACI_S_GENERAL
))
<
0
)
{
snd_printk
(
KERN_ERR
"snd_miro_get_capture() failed: %d
\n
"
,
value
);
value
=
aci_getvalue
(
miro
->
aci
,
ACI_S_GENERAL
);
if
(
value
<
0
)
{
snd_printk
(
KERN_ERR
"snd_miro_get_capture() failed: %d
\n
"
,
value
);
return
value
;
}
...
...
@@ -267,13 +291,15 @@ static int snd_miro_put_capture(struct snd_kcontrol *kcontrol,
value
=
!
(
ucontrol
->
value
.
integer
.
value
[
0
]);
if
((
error
=
aci_setvalue
(
miro
,
ACI_SET_SOLOMODE
,
value
))
<
0
)
{
snd_printk
(
KERN_ERR
"snd_miro_put_capture() failed: %d
\n
"
,
error
);
error
=
aci_setvalue
(
miro
->
aci
,
ACI_SET_SOLOMODE
,
value
);
if
(
error
<
0
)
{
snd_printk
(
KERN_ERR
"snd_miro_put_capture() failed: %d
\n
"
,
error
);
return
error
;
}
change
=
(
value
!=
miro
->
aci_solomode
);
miro
->
aci_solomode
=
value
;
change
=
(
value
!=
miro
->
aci
->
aci
_solomode
);
miro
->
aci
->
aci
_solomode
=
value
;
return
change
;
}
...
...
@@ -295,7 +321,7 @@ static int snd_miro_get_preamp(struct snd_kcontrol *kcontrol,
struct
snd_miro
*
miro
=
snd_kcontrol_chip
(
kcontrol
);
int
value
;
if
(
miro
->
aci_version
<=
176
)
{
if
(
miro
->
aci
->
aci
_version
<=
176
)
{
/*
OSS says it's not readable with versions < 176.
...
...
@@ -303,12 +329,14 @@ static int snd_miro_get_preamp(struct snd_kcontrol *kcontrol,
which is a PCM12 with aci_version = 176.
*/
ucontrol
->
value
.
integer
.
value
[
0
]
=
miro
->
aci_preamp
;
ucontrol
->
value
.
integer
.
value
[
0
]
=
miro
->
aci
->
aci
_preamp
;
return
0
;
}
if
((
value
=
aci_getvalue
(
miro
,
ACI_GET_PREAMP
))
<
0
)
{
snd_printk
(
KERN_ERR
"snd_miro_get_preamp() failed: %d
\n
"
,
value
);
value
=
aci_getvalue
(
miro
->
aci
,
ACI_GET_PREAMP
);
if
(
value
<
0
)
{
snd_printk
(
KERN_ERR
"snd_miro_get_preamp() failed: %d
\n
"
,
value
);
return
value
;
}
...
...
@@ -325,13 +353,15 @@ static int snd_miro_put_preamp(struct snd_kcontrol *kcontrol,
value
=
ucontrol
->
value
.
integer
.
value
[
0
];
if
((
error
=
aci_setvalue
(
miro
,
ACI_SET_PREAMP
,
value
))
<
0
)
{
snd_printk
(
KERN_ERR
"snd_miro_put_preamp() failed: %d
\n
"
,
error
);
error
=
aci_setvalue
(
miro
->
aci
,
ACI_SET_PREAMP
,
value
);
if
(
error
<
0
)
{
snd_printk
(
KERN_ERR
"snd_miro_put_preamp() failed: %d
\n
"
,
error
);
return
error
;
}
change
=
(
value
!=
miro
->
aci_preamp
);
miro
->
aci_preamp
=
value
;
change
=
(
value
!=
miro
->
aci
->
aci
_preamp
);
miro
->
aci
->
aci
_preamp
=
value
;
return
change
;
}
...
...
@@ -342,7 +372,7 @@ static int snd_miro_get_amp(struct snd_kcontrol *kcontrol,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_miro
*
miro
=
snd_kcontrol_chip
(
kcontrol
);
ucontrol
->
value
.
integer
.
value
[
0
]
=
miro
->
aci_amp
;
ucontrol
->
value
.
integer
.
value
[
0
]
=
miro
->
aci
->
aci
_amp
;
return
0
;
}
...
...
@@ -355,13 +385,14 @@ static int snd_miro_put_amp(struct snd_kcontrol *kcontrol,
value
=
ucontrol
->
value
.
integer
.
value
[
0
];
if
((
error
=
aci_setvalue
(
miro
,
ACI_SET_POWERAMP
,
value
))
<
0
)
{
error
=
aci_setvalue
(
miro
->
aci
,
ACI_SET_POWERAMP
,
value
);
if
(
error
<
0
)
{
snd_printk
(
KERN_ERR
"snd_miro_put_amp() to %d failed: %d
\n
"
,
value
,
error
);
return
error
;
}
change
=
(
value
!=
miro
->
aci_amp
);
miro
->
aci_amp
=
value
;
change
=
(
value
!=
miro
->
aci
->
aci
_amp
);
miro
->
aci
->
aci
_amp
=
value
;
return
change
;
}
...
...
@@ -410,12 +441,14 @@ static int snd_miro_get_double(struct snd_kcontrol *kcontrol,
int
right_reg
=
kcontrol
->
private_value
&
0xff
;
int
left_reg
=
right_reg
+
1
;
if
((
right_val
=
aci_getvalue
(
miro
,
right_reg
))
<
0
)
{
right_val
=
aci_getvalue
(
miro
->
aci
,
right_reg
);
if
(
right_val
<
0
)
{
snd_printk
(
KERN_ERR
"aci_getvalue(%d) failed: %d
\n
"
,
right_reg
,
right_val
);
return
right_val
;
}
if
((
left_val
=
aci_getvalue
(
miro
,
left_reg
))
<
0
)
{
left_val
=
aci_getvalue
(
miro
->
aci
,
left_reg
);
if
(
left_val
<
0
)
{
snd_printk
(
KERN_ERR
"aci_getvalue(%d) failed: %d
\n
"
,
left_reg
,
left_val
);
return
left_val
;
}
...
...
@@ -451,6 +484,7 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_miro
*
miro
=
snd_kcontrol_chip
(
kcontrol
);
struct
snd_miro_aci
*
aci
=
miro
->
aci
;
int
left
,
right
,
left_old
,
right_old
;
int
setreg_left
,
setreg_right
,
getreg_left
,
getreg_right
;
int
change
,
error
;
...
...
@@ -459,21 +493,21 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
right
=
ucontrol
->
value
.
integer
.
value
[
1
];
setreg_right
=
(
kcontrol
->
private_value
>>
8
)
&
0xff
;
if
(
setreg_right
==
ACI_SET_MASTER
)
{
setreg_left
=
setreg_right
+
1
;
}
else
{
setreg_left
=
setreg_right
+
8
;
}
if
(
setreg_right
==
ACI_SET_MASTER
)
setreg_left
-=
7
;
getreg_right
=
kcontrol
->
private_value
&
0xff
;
getreg_left
=
getreg_right
+
1
;
if
((
left_old
=
aci_getvalue
(
miro
,
getreg_left
))
<
0
)
{
left_old
=
aci_getvalue
(
aci
,
getreg_left
);
if
(
left_old
<
0
)
{
snd_printk
(
KERN_ERR
"aci_getvalue(%d) failed: %d
\n
"
,
getreg_left
,
left_old
);
return
left_old
;
}
if
((
right_old
=
aci_getvalue
(
miro
,
getreg_right
))
<
0
)
{
right_old
=
aci_getvalue
(
aci
,
getreg_right
);
if
(
right_old
<
0
)
{
snd_printk
(
KERN_ERR
"aci_getvalue(%d) failed: %d
\n
"
,
getreg_right
,
right_old
);
return
right_old
;
}
...
...
@@ -492,13 +526,15 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
right_old
=
0x80
-
right_old
;
if
(
left
>=
0
)
{
if
((
error
=
aci_setvalue
(
miro
,
setreg_left
,
left
))
<
0
)
{
error
=
aci_setvalue
(
aci
,
setreg_left
,
left
);
if
(
error
<
0
)
{
snd_printk
(
KERN_ERR
"aci_setvalue(%d) failed: %d
\n
"
,
left
,
error
);
return
error
;
}
}
else
{
if
((
error
=
aci_setvalue
(
miro
,
setreg_left
,
0x80
-
left
))
<
0
)
{
error
=
aci_setvalue
(
aci
,
setreg_left
,
0x80
-
left
);
if
(
error
<
0
)
{
snd_printk
(
KERN_ERR
"aci_setvalue(%d) failed: %d
\n
"
,
0x80
-
left
,
error
);
return
error
;
...
...
@@ -506,13 +542,15 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
}
if
(
right
>=
0
)
{
if
((
error
=
aci_setvalue
(
miro
,
setreg_right
,
right
))
<
0
)
{
error
=
aci_setvalue
(
aci
,
setreg_right
,
right
);
if
(
error
<
0
)
{
snd_printk
(
KERN_ERR
"aci_setvalue(%d) failed: %d
\n
"
,
right
,
error
);
return
error
;
}
}
else
{
if
((
error
=
aci_setvalue
(
miro
,
setreg_right
,
0x80
-
right
))
<
0
)
{
error
=
aci_setvalue
(
aci
,
setreg_right
,
0x80
-
right
);
if
(
error
<
0
)
{
snd_printk
(
KERN_ERR
"aci_setvalue(%d) failed: %d
\n
"
,
0x80
-
right
,
error
);
return
error
;
...
...
@@ -530,12 +568,14 @@ static int snd_miro_put_double(struct snd_kcontrol *kcontrol,
left_old
=
0x20
-
left_old
;
right_old
=
0x20
-
right_old
;
if
((
error
=
aci_setvalue
(
miro
,
setreg_left
,
0x20
-
left
))
<
0
)
{
error
=
aci_setvalue
(
aci
,
setreg_left
,
0x20
-
left
);
if
(
error
<
0
)
{
snd_printk
(
KERN_ERR
"aci_setvalue(%d) failed: %d
\n
"
,
0x20
-
left
,
error
);
return
error
;
}
if
((
error
=
aci_setvalue
(
miro
,
setreg_right
,
0x20
-
right
))
<
0
)
{
error
=
aci_setvalue
(
aci
,
setreg_right
,
0x20
-
right
);
if
(
error
<
0
)
{
snd_printk
(
KERN_ERR
"aci_setvalue(%d) failed: %d
\n
"
,
0x20
-
right
,
error
);
return
error
;
...
...
@@ -633,11 +673,13 @@ static unsigned char aci_init_values[][2] __devinitdata = {
static
int
__devinit
snd_set_aci_init_values
(
struct
snd_miro
*
miro
)
{
int
idx
,
error
;
struct
snd_miro_aci
*
aci
=
miro
->
aci
;
/* enable WSS on PCM1 */
if
((
miro
->
aci_product
==
'A'
)
&&
wss
)
{
if
((
error
=
aci_setvalue
(
miro
,
ACI_SET_WSS
,
wss
))
<
0
)
{
if
((
aci
->
aci_product
==
'A'
)
&&
wss
)
{
error
=
aci_setvalue
(
aci
,
ACI_SET_WSS
,
wss
);
if
(
error
<
0
)
{
snd_printk
(
KERN_ERR
"enabling WSS mode failed
\n
"
);
return
error
;
}
...
...
@@ -646,7 +688,8 @@ static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
/* enable IDE port */
if
(
ide
)
{
if
((
error
=
aci_setvalue
(
miro
,
ACI_SET_IDE
,
ide
))
<
0
)
{
error
=
aci_setvalue
(
aci
,
ACI_SET_IDE
,
ide
);
if
(
error
<
0
)
{
snd_printk
(
KERN_ERR
"enabling IDE port failed
\n
"
);
return
error
;
}
...
...
@@ -654,32 +697,31 @@ static int __devinit snd_set_aci_init_values(struct snd_miro *miro)
/* set common aci values */
for
(
idx
=
0
;
idx
<
ARRAY_SIZE
(
aci_init_values
);
idx
++
)
if
((
error
=
aci_setvalue
(
miro
,
aci_init_values
[
idx
][
0
],
aci_init_values
[
idx
][
1
]))
<
0
)
{
for
(
idx
=
0
;
idx
<
ARRAY_SIZE
(
aci_init_values
);
idx
++
)
{
error
=
aci_setvalue
(
aci
,
aci_init_values
[
idx
][
0
],
aci_init_values
[
idx
][
1
]);
if
(
error
<
0
)
{
snd_printk
(
KERN_ERR
"aci_setvalue(%d) failed: %d
\n
"
,
aci_init_values
[
idx
][
0
],
error
);
return
error
;
}
miro
->
aci_amp
=
0
;
miro
->
aci_preamp
=
0
;
miro
->
aci_solomode
=
1
;
}
aci
->
aci_amp
=
0
;
aci
->
aci_preamp
=
0
;
aci
->
aci_solomode
=
1
;
return
0
;
}
static
int
__devinit
snd_miro_mixer
(
struct
snd_miro
*
miro
)
static
int
__devinit
snd_miro_mixer
(
struct
snd_card
*
card
,
struct
snd_miro
*
miro
)
{
struct
snd_card
*
card
;
unsigned
int
idx
;
int
err
;
if
(
snd_BUG_ON
(
!
miro
||
!
miro
->
card
))
if
(
snd_BUG_ON
(
!
miro
||
!
card
))
return
-
EINVAL
;
card
=
miro
->
card
;
switch
(
miro
->
hardware
)
{
case
OPTi9XX_HW_82C924
:
strcpy
(
card
->
mixername
,
"ACI & OPTi924"
);
...
...
@@ -697,7 +739,8 @@ static int __devinit snd_miro_mixer(struct snd_miro *miro)
return
err
;
}
if
((
miro
->
aci_product
==
'A'
)
||
(
miro
->
aci_product
==
'B'
))
{
if
((
miro
->
aci
->
aci_product
==
'A'
)
||
(
miro
->
aci
->
aci_product
==
'B'
))
{
/* PCM1/PCM12 with power-amp and Line 2 */
if
((
err
=
snd_ctl_add
(
card
,
snd_ctl_new1
(
&
snd_miro_line_control
[
0
],
miro
)))
<
0
)
return
err
;
...
...
@@ -705,16 +748,17 @@ static int __devinit snd_miro_mixer(struct snd_miro *miro)
return
err
;
}
if
((
miro
->
aci_product
==
'B'
)
||
(
miro
->
aci_product
==
'C'
))
{
if
((
miro
->
aci
->
aci_product
==
'B'
)
||
(
miro
->
aci
->
aci_product
==
'C'
))
{
/* PCM12/PCM20 with mic-preamp */
if
((
err
=
snd_ctl_add
(
card
,
snd_ctl_new1
(
&
snd_miro_preamp_control
[
0
],
miro
)))
<
0
)
return
err
;
if
(
miro
->
aci_version
>=
176
)
if
(
miro
->
aci
->
aci
_version
>=
176
)
if
((
err
=
snd_ctl_add
(
card
,
snd_ctl_new1
(
&
snd_miro_capture_control
[
0
],
miro
)))
<
0
)
return
err
;
}
if
(
miro
->
aci_product
==
'C'
)
{
if
(
miro
->
aci
->
aci
_product
==
'C'
)
{
/* PCM20 with radio and 7 band equalizer */
if
((
err
=
snd_ctl_add
(
card
,
snd_ctl_new1
(
&
snd_miro_radio_control
[
0
],
miro
)))
<
0
)
return
err
;
...
...
@@ -757,21 +801,26 @@ static int __devinit snd_miro_init(struct snd_miro *chip,
chip
->
irq
=
-
1
;
chip
->
dma1
=
-
1
;
chip
->
dma2
=
-
1
;
chip
->
fm_port
=
-
1
;
chip
->
mpu_port
=
-
1
;
chip
->
mpu_irq
=
-
1
;
chip
->
pwd_reg
=
3
;
#ifdef CONFIG_PNP
if
(
isapnp
&&
chip
->
mc_base
)
/* PnP resource gives the least 10 bits */
chip
->
mc_base
|=
0xc00
;
else
#endif
chip
->
mc_base
=
0xf8c
;
switch
(
hardware
)
{
case
OPTi9XX_HW_82C929
:
chip
->
mc_base
=
0xf8c
;
chip
->
password
=
0xe3
;
chip
->
pwd_reg
=
3
;
break
;
case
OPTi9XX_HW_82C924
:
chip
->
mc_base
=
0xf8c
;
chip
->
password
=
0xe5
;
chip
->
pwd_reg
=
3
;
break
;
default:
...
...
@@ -853,14 +902,15 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
struct
snd_info_buffer
*
buffer
)
{
struct
snd_miro
*
miro
=
(
struct
snd_miro
*
)
entry
->
private_data
;
struct
snd_miro_aci
*
aci
=
miro
->
aci
;
char
*
model
=
"unknown"
;
/* miroSOUND PCM1 pro, early PCM12 */
if
((
miro
->
hardware
==
OPTi9XX_HW_82C929
)
&&
(
miro
->
aci_vendor
==
'm'
)
&&
(
miro
->
aci_product
==
'A'
))
{
switch
(
miro
->
aci_version
)
{
(
aci
->
aci_vendor
==
'm'
)
&&
(
aci
->
aci_product
==
'A'
))
{
switch
(
aci
->
aci_version
)
{
case
3
:
model
=
"miroSOUND PCM1 pro"
;
break
;
...
...
@@ -873,9 +923,9 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
/* miroSOUND PCM12, PCM12 (Rev. E), PCM12 pnp */
if
((
miro
->
hardware
==
OPTi9XX_HW_82C924
)
&&
(
miro
->
aci_vendor
==
'm'
)
&&
(
miro
->
aci_product
==
'B'
))
{
switch
(
miro
->
aci_version
)
{
(
aci
->
aci_vendor
==
'm'
)
&&
(
aci
->
aci_product
==
'B'
))
{
switch
(
aci
->
aci_version
)
{
case
4
:
model
=
"miroSOUND PCM12"
;
break
;
...
...
@@ -891,9 +941,9 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
/* miroSOUND PCM20 radio */
if
((
miro
->
hardware
==
OPTi9XX_HW_82C924
)
&&
(
miro
->
aci_vendor
==
'm'
)
&&
(
miro
->
aci_product
==
'C'
))
{
switch
(
miro
->
aci_version
)
{
(
aci
->
aci_vendor
==
'm'
)
&&
(
aci
->
aci_product
==
'C'
))
{
switch
(
aci
->
aci_version
)
{
case
7
:
model
=
"miroSOUND PCM20 radio (Rev. E)"
;
break
;
...
...
@@ -917,17 +967,17 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
snd_iprintf
(
buffer
,
"ACI information:
\n
"
);
snd_iprintf
(
buffer
,
" vendor : "
);
switch
(
miro
->
aci_vendor
)
{
switch
(
aci
->
aci_vendor
)
{
case
'm'
:
snd_iprintf
(
buffer
,
"Miro
\n
"
);
break
;
default:
snd_iprintf
(
buffer
,
"unknown (0x%x)
\n
"
,
miro
->
aci_vendor
);
snd_iprintf
(
buffer
,
"unknown (0x%x)
\n
"
,
aci
->
aci_vendor
);
break
;
}
snd_iprintf
(
buffer
,
" product : "
);
switch
(
miro
->
aci_product
)
{
switch
(
aci
->
aci_product
)
{
case
'A'
:
snd_iprintf
(
buffer
,
"miroSOUND PCM1 pro / (early) PCM12
\n
"
);
break
;
...
...
@@ -938,26 +988,27 @@ static void snd_miro_proc_read(struct snd_info_entry * entry,
snd_iprintf
(
buffer
,
"miroSOUND PCM20 radio
\n
"
);
break
;
default:
snd_iprintf
(
buffer
,
"unknown (0x%x)
\n
"
,
miro
->
aci_product
);
snd_iprintf
(
buffer
,
"unknown (0x%x)
\n
"
,
aci
->
aci_product
);
break
;
}
snd_iprintf
(
buffer
,
" firmware: %d (0x%x)
\n
"
,
miro
->
aci_version
,
miro
->
aci_version
);
aci
->
aci_version
,
aci
->
aci_version
);
snd_iprintf
(
buffer
,
" port : 0x%lx-0x%lx
\n
"
,
miro
->
aci_port
,
miro
->
aci_port
+
2
);
aci
->
aci_port
,
aci
->
aci_port
+
2
);
snd_iprintf
(
buffer
,
" wss : 0x%x
\n
"
,
wss
);
snd_iprintf
(
buffer
,
" ide : 0x%x
\n
"
,
ide
);
snd_iprintf
(
buffer
,
" solomode: 0x%x
\n
"
,
miro
->
aci_solomode
);
snd_iprintf
(
buffer
,
" amp : 0x%x
\n
"
,
miro
->
aci_amp
);
snd_iprintf
(
buffer
,
" preamp : 0x%x
\n
"
,
miro
->
aci_preamp
);
snd_iprintf
(
buffer
,
" solomode: 0x%x
\n
"
,
aci
->
aci_solomode
);
snd_iprintf
(
buffer
,
" amp : 0x%x
\n
"
,
aci
->
aci_amp
);
snd_iprintf
(
buffer
,
" preamp : 0x%x
\n
"
,
aci
->
aci_preamp
);
}
static
void
__devinit
snd_miro_proc_init
(
struct
snd_miro
*
miro
)
static
void
__devinit
snd_miro_proc_init
(
struct
snd_card
*
card
,
struct
snd_miro
*
miro
)
{
struct
snd_info_entry
*
entry
;
if
(
!
snd_card_proc_new
(
miro
->
card
,
"miro"
,
&
entry
))
if
(
!
snd_card_proc_new
(
card
,
"miro"
,
&
entry
))
snd_info_set_text_ops
(
entry
,
miro
,
snd_miro_proc_read
);
}
...
...
@@ -974,37 +1025,40 @@ static int __devinit snd_miro_configure(struct snd_miro *chip)
unsigned
char
mpu_irq_bits
;
unsigned
long
flags
;
snd_miro_write_mask
(
chip
,
OPTi9XX_MC_REG
(
1
),
0x80
,
0x80
);
snd_miro_write_mask
(
chip
,
OPTi9XX_MC_REG
(
2
),
0x20
,
0x20
);
/* OPL4 */
snd_miro_write_mask
(
chip
,
OPTi9XX_MC_REG
(
5
),
0x02
,
0x02
);
switch
(
chip
->
hardware
)
{
case
OPTi9XX_HW_82C924
:
snd_miro_write_mask
(
chip
,
OPTi9XX_MC_REG
(
6
),
0x02
,
0x02
);
snd_miro_write_mask
(
chip
,
OPTi9XX_MC_REG
(
1
),
0x80
,
0x80
);
snd_miro_write_mask
(
chip
,
OPTi9XX_MC_REG
(
2
),
0x20
,
0x20
);
/* OPL4 */
snd_miro_write_mask
(
chip
,
OPTi9XX_MC_REG
(
3
),
0xf0
,
0xff
);
snd_miro_write_mask
(
chip
,
OPTi9XX_MC_REG
(
5
),
0x02
,
0x02
);
break
;
case
OPTi9XX_HW_82C929
:
/* untested init commands for OPTi929 */
snd_miro_write_mask
(
chip
,
OPTi9XX_MC_REG
(
1
),
0x80
,
0x80
);
snd_miro_write_mask
(
chip
,
OPTi9XX_MC_REG
(
2
),
0x20
,
0x20
);
/* OPL4 */
snd_miro_write_mask
(
chip
,
OPTi9XX_MC_REG
(
4
),
0x00
,
0x0c
);
snd_miro_write_mask
(
chip
,
OPTi9XX_MC_REG
(
5
),
0x02
,
0x02
);
break
;
default:
snd_printk
(
KERN_ERR
"chip %d not supported
\n
"
,
chip
->
hardware
);
return
-
EINVAL
;
}
switch
(
chip
->
wss_base
)
{
case
0x530
:
/* PnP resource says it decodes only 10 bits of address */
switch
(
chip
->
wss_base
&
0x3ff
)
{
case
0x130
:
chip
->
wss_base
=
0x530
;
wss_base_bits
=
0x00
;
break
;
case
0x604
:
case
0x204
:
chip
->
wss_base
=
0x604
;
wss_base_bits
=
0x03
;
break
;
case
0xe80
:
case
0x280
:
chip
->
wss_base
=
0xe80
;
wss_base_bits
=
0x01
;
break
;
case
0xf40
:
case
0x340
:
chip
->
wss_base
=
0xf40
;
wss_base_bits
=
0x02
;
break
;
default:
...
...
@@ -1122,75 +1176,92 @@ static int __devinit snd_miro_configure(struct snd_miro *chip)
return
0
;
}
static
int
__devinit
snd_miro_opti_check
(
struct
snd_miro
*
chip
)
{
unsigned
char
value
;
chip
->
res_mc_base
=
request_region
(
chip
->
mc_base
,
chip
->
mc_base_size
,
"OPTi9xx MC"
);
if
(
chip
->
res_mc_base
==
NULL
)
return
-
ENOMEM
;
value
=
snd_miro_read
(
chip
,
OPTi9XX_MC_REG
(
1
));
if
(
value
!=
0xff
&&
value
!=
inb
(
chip
->
mc_base
+
OPTi9XX_MC_REG
(
1
)))
if
(
value
==
snd_miro_read
(
chip
,
OPTi9XX_MC_REG
(
1
)))
return
0
;
release_and_free_resource
(
chip
->
res_mc_base
);
chip
->
res_mc_base
=
NULL
;
return
-
ENODEV
;
}
static
int
__devinit
snd_card_miro_detect
(
struct
snd_card
*
card
,
struct
snd_miro
*
chip
)
{
int
i
,
err
;
unsigned
char
value
;
for
(
i
=
OPTi9XX_HW_82C929
;
i
<=
OPTi9XX_HW_82C924
;
i
++
)
{
if
((
err
=
snd_miro_init
(
chip
,
i
))
<
0
)
return
err
;
if
((
chip
->
res_mc_base
=
request_region
(
chip
->
mc_base
,
chip
->
mc_base_size
,
"OPTi9xx MC"
))
==
NULL
)
continue
;
value
=
snd_miro_read
(
chip
,
OPTi9XX_MC_REG
(
1
));
if
((
value
!=
0xff
)
&&
(
value
!=
inb
(
chip
->
mc_base
+
1
)))
if
(
value
==
snd_miro_read
(
chip
,
OPTi9XX_MC_REG
(
1
)))
err
=
snd_miro_opti_check
(
chip
);
if
(
err
==
0
)
return
1
;
release_and_free_resource
(
chip
->
res_mc_base
);
chip
->
res_mc_base
=
NULL
;
}
return
-
ENODEV
;
}
static
int
__devinit
snd_card_miro_aci_detect
(
struct
snd_card
*
card
,
struct
snd_miro
*
miro
)
struct
snd_miro
*
miro
)
{
unsigned
char
regval
;
int
i
;
struct
snd_miro_aci
*
aci
=
&
aci_device
;
mutex_init
(
&
miro
->
aci_mutex
);
miro
->
aci
=
aci
;
mutex_init
(
&
aci
->
aci_mutex
);
/* get ACI port from OPTi9xx MC 4 */
miro
->
mc_base
=
0xf8c
;
regval
=
inb
(
miro
->
mc_base
+
4
);
miro
->
aci_port
=
(
regval
&
0x10
)
?
0x344
:
0x354
;
aci
->
aci_port
=
(
regval
&
0x10
)
?
0x344
:
0x354
;
if
((
miro
->
res_aci_port
=
request_region
(
miro
->
aci_port
,
3
,
"miro aci"
))
==
NULL
)
{
miro
->
res_aci_port
=
request_region
(
aci
->
aci_port
,
3
,
"miro aci"
);
if
(
miro
->
res_aci_port
==
NULL
)
{
snd_printk
(
KERN_ERR
"aci i/o area 0x%lx-0x%lx already used.
\n
"
,
miro
->
aci_port
,
miro
->
aci_port
+
2
);
aci
->
aci_port
,
aci
->
aci_port
+
2
);
return
-
ENOMEM
;
}
/* force ACI into a known state */
for
(
i
=
0
;
i
<
3
;
i
++
)
if
(
aci_cmd
(
miro
,
ACI_ERROR_OP
,
-
1
,
-
1
)
<
0
)
{
if
(
snd_aci_cmd
(
aci
,
ACI_ERROR_OP
,
-
1
,
-
1
)
<
0
)
{
snd_printk
(
KERN_ERR
"can't force aci into known state.
\n
"
);
return
-
ENXIO
;
}
if
((
miro
->
aci_vendor
=
aci_cmd
(
miro
,
ACI_READ_IDCODE
,
-
1
,
-
1
))
<
0
||
(
miro
->
aci_product
=
aci_cmd
(
miro
,
ACI_READ_IDCODE
,
-
1
,
-
1
))
<
0
)
{
snd_printk
(
KERN_ERR
"can't read aci id on 0x%lx.
\n
"
,
miro
->
aci_port
);
aci
->
aci_vendor
=
snd_aci_cmd
(
aci
,
ACI_READ_IDCODE
,
-
1
,
-
1
);
aci
->
aci_product
=
snd_aci_cmd
(
aci
,
ACI_READ_IDCODE
,
-
1
,
-
1
);
if
(
aci
->
aci_vendor
<
0
||
aci
->
aci_product
<
0
)
{
snd_printk
(
KERN_ERR
"can't read aci id on 0x%lx.
\n
"
,
aci
->
aci_port
);
return
-
ENXIO
;
}
if
((
miro
->
aci_version
=
aci_cmd
(
miro
,
ACI_READ_VERSION
,
-
1
,
-
1
))
<
0
)
{
aci
->
aci_version
=
snd_aci_cmd
(
aci
,
ACI_READ_VERSION
,
-
1
,
-
1
);
if
(
aci
->
aci_version
<
0
)
{
snd_printk
(
KERN_ERR
"can't read aci version on 0x%lx.
\n
"
,
miro
->
aci_port
);
aci
->
aci_port
);
return
-
ENXIO
;
}
if
(
aci_cmd
(
miro
,
ACI_INIT
,
-
1
,
-
1
)
<
0
||
aci_cmd
(
miro
,
ACI_ERROR_OP
,
ACI_ERROR_OP
,
ACI_ERROR_OP
)
<
0
||
aci_cmd
(
miro
,
ACI_ERROR_OP
,
ACI_ERROR_OP
,
ACI_ERROR_OP
)
<
0
)
{
if
(
snd_aci_cmd
(
aci
,
ACI_INIT
,
-
1
,
-
1
)
<
0
||
snd_aci_cmd
(
aci
,
ACI_ERROR_OP
,
ACI_ERROR_OP
,
ACI_ERROR_OP
)
<
0
||
snd_aci_cmd
(
aci
,
ACI_ERROR_OP
,
ACI_ERROR_OP
,
ACI_ERROR_OP
)
<
0
)
{
snd_printk
(
KERN_ERR
"can't initialize aci.
\n
"
);
return
-
ENXIO
;
}
...
...
@@ -1203,155 +1274,78 @@ static void snd_card_miro_free(struct snd_card *card)
struct
snd_miro
*
miro
=
card
->
private_data
;
release_and_free_resource
(
miro
->
res_aci_port
);
if
(
miro
->
aci
)
miro
->
aci
->
aci_port
=
0
;
release_and_free_resource
(
miro
->
res_mc_base
);
}
static
int
__devinit
snd_miro_
match
(
struct
device
*
devptr
,
unsigned
int
n
)
static
int
__devinit
snd_miro_
probe
(
struct
snd_card
*
card
)
{
return
1
;
}
static
int
__devinit
snd_miro_probe
(
struct
device
*
devptr
,
unsigned
int
n
)
{
static
long
possible_ports
[]
=
{
0x530
,
0xe80
,
0xf40
,
0x604
,
-
1
};
static
long
possible_mpu_ports
[]
=
{
0x330
,
0x300
,
0x310
,
0x320
,
-
1
};
static
int
possible_irqs
[]
=
{
11
,
9
,
10
,
7
,
-
1
};
static
int
possible_mpu_irqs
[]
=
{
10
,
5
,
9
,
7
,
-
1
};
static
int
possible_dma1s
[]
=
{
3
,
1
,
0
,
-
1
};
static
int
possible_dma2s
[][
2
]
=
{{
1
,
-
1
},
{
0
,
-
1
},
{
-
1
,
-
1
},
{
0
,
-
1
}};
int
error
;
struct
snd_miro
*
miro
;
struct
snd_miro
*
miro
=
card
->
private_data
;
struct
snd_wss
*
codec
;
struct
snd_timer
*
timer
;
struct
snd_card
*
card
;
struct
snd_pcm
*
pcm
;
struct
snd_rawmidi
*
rmidi
;
error
=
snd_card_create
(
index
,
id
,
THIS_MODULE
,
sizeof
(
struct
snd_miro
),
&
card
);
if
(
error
<
0
)
return
error
;
card
->
private_free
=
snd_card_miro_free
;
miro
=
card
->
private_data
;
miro
->
card
=
card
;
if
((
error
=
snd_card_miro_aci_detect
(
card
,
miro
))
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"unable to detect aci chip
\n
"
);
return
-
ENODEV
;
if
(
!
miro
->
res_mc_base
)
{
miro
->
res_mc_base
=
request_region
(
miro
->
mc_base
,
miro
->
mc_base_size
,
"miro (OPTi9xx MC)"
);
if
(
miro
->
res_mc_base
==
NULL
)
{
snd_printk
(
KERN_ERR
"request for OPTI9xx MC failed
\n
"
);
return
-
ENOMEM
;
}
/* init proc interface */
snd_miro_proc_init
(
miro
);
if
((
error
=
snd_card_miro_detect
(
card
,
miro
))
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"unable to detect OPTi9xx chip
\n
"
);
return
-
ENODEV
;
}
if
(
!
miro
->
res_mc_base
&&
(
miro
->
res_mc_base
=
request_region
(
miro
->
mc_base
,
miro
->
mc_base_size
,
"miro (OPTi9xx MC)"
))
==
NULL
)
{
error
=
snd_card_miro_aci_detect
(
card
,
miro
);
if
(
error
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"
request for OPTI9xx MC failed
\n
"
);
return
-
ENO
MEM
;
snd_printk
(
KERN_ERR
"
unable to detect aci chip
\n
"
);
return
-
ENO
DEV
;
}
miro
->
wss_base
=
port
;
miro
->
fm_port
=
fm_port
;
miro
->
mpu_port
=
mpu_port
;
miro
->
irq
=
irq
;
miro
->
mpu_irq
=
mpu_irq
;
miro
->
dma1
=
dma1
;
miro
->
dma2
=
dma2
;
if
(
miro
->
wss_base
==
SNDRV_AUTO_PORT
)
{
if
((
miro
->
wss_base
=
snd_legacy_find_free_ioport
(
possible_ports
,
4
))
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"unable to find a free WSS port
\n
"
);
return
-
EBUSY
;
}
}
if
(
miro
->
mpu_port
==
SNDRV_AUTO_PORT
)
{
if
((
miro
->
mpu_port
=
snd_legacy_find_free_ioport
(
possible_mpu_ports
,
2
))
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"unable to find a free MPU401 port
\n
"
);
return
-
EBUSY
;
}
}
if
(
miro
->
irq
==
SNDRV_AUTO_IRQ
)
{
if
((
miro
->
irq
=
snd_legacy_find_free_irq
(
possible_irqs
))
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"unable to find a free IRQ
\n
"
);
return
-
EBUSY
;
}
}
if
(
miro
->
mpu_irq
==
SNDRV_AUTO_IRQ
)
{
if
((
miro
->
mpu_irq
=
snd_legacy_find_free_irq
(
possible_mpu_irqs
))
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"unable to find a free MPU401 IRQ
\n
"
);
return
-
EBUSY
;
}
}
if
(
miro
->
dma1
==
SNDRV_AUTO_DMA
)
{
if
((
miro
->
dma1
=
snd_legacy_find_free_dma
(
possible_dma1s
))
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"unable to find a free DMA1
\n
"
);
return
-
EBUSY
;
}
}
if
(
miro
->
dma2
==
SNDRV_AUTO_DMA
)
{
if
((
miro
->
dma2
=
snd_legacy_find_free_dma
(
possible_dma2s
[
miro
->
dma1
%
4
]))
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"unable to find a free DMA2
\n
"
);
return
-
EBUSY
;
}
}
/* init proc interface */
snd_miro_proc_init
(
card
,
miro
);
error
=
snd_miro_configure
(
miro
);
if
(
error
)
{
snd_card_free
(
card
);
if
(
error
)
return
error
;
}
error
=
snd_wss_create
(
card
,
miro
->
wss_base
+
4
,
-
1
,
miro
->
irq
,
miro
->
dma1
,
miro
->
dma2
,
WSS_HW_AD1845
,
0
,
&
codec
);
if
(
error
<
0
)
{
snd_card_free
(
card
);
WSS_HW_DETECT
,
0
,
&
codec
);
if
(
error
<
0
)
return
error
;
}
error
=
snd_wss_pcm
(
codec
,
0
,
&
pcm
);
if
(
error
<
0
)
{
snd_card_free
(
card
);
if
(
error
<
0
)
return
error
;
}
error
=
snd_wss_mixer
(
codec
);
if
(
error
<
0
)
{
snd_card_free
(
card
);
if
(
error
<
0
)
return
error
;
}
error
=
snd_wss_timer
(
codec
,
0
,
&
timer
);
if
(
error
<
0
)
{
snd_card_free
(
card
);
if
(
error
<
0
)
return
error
;
}
miro
->
pcm
=
pcm
;
if
((
error
=
snd_miro_mixer
(
miro
))
<
0
)
{
snd_card_free
(
card
);
error
=
snd_miro_mixer
(
card
,
miro
);
if
(
error
<
0
)
return
error
;
}
if
(
miro
->
aci_vendor
==
'm'
)
{
if
(
miro
->
aci
->
aci
_vendor
==
'm'
)
{
/* It looks like a miro sound card. */
switch
(
miro
->
aci_product
)
{
switch
(
miro
->
aci
->
aci
_product
)
{
case
'A'
:
sprintf
(
card
->
shortname
,
"miroSOUND PCM1 pro / PCM12"
);
...
...
@@ -1380,30 +1374,131 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
card
->
shortname
,
miro
->
name
,
pcm
->
name
,
miro
->
wss_base
+
4
,
miro
->
irq
,
miro
->
dma1
,
miro
->
dma2
);
if
(
m
iro
->
mpu_port
<=
0
||
miro
->
mpu_port
==
SNDRV_AUTO_PORT
)
if
(
m
pu_port
<=
0
||
mpu_port
==
SNDRV_AUTO_PORT
)
rmidi
=
NULL
;
else
if
((
error
=
snd_mpu401_uart_new
(
card
,
0
,
MPU401_HW_MPU401
,
miro
->
mpu_port
,
0
,
miro
->
mpu_irq
,
IRQF_DISABLED
,
&
rmidi
)))
snd_printk
(
KERN_WARNING
"no MPU-401 device at 0x%lx?
\n
"
,
miro
->
mpu_port
);
else
{
error
=
snd_mpu401_uart_new
(
card
,
0
,
MPU401_HW_MPU401
,
mpu_port
,
0
,
miro
->
mpu_irq
,
IRQF_DISABLED
,
&
rmidi
);
if
(
error
<
0
)
snd_printk
(
KERN_WARNING
"no MPU-401 device at 0x%lx?
\n
"
,
mpu_port
);
}
if
(
miro
->
fm_port
>
0
&&
miro
->
fm_port
!=
SNDRV_AUTO_PORT
)
{
if
(
fm_port
>
0
&&
fm_port
!=
SNDRV_AUTO_PORT
)
{
struct
snd_opl3
*
opl3
=
NULL
;
struct
snd_opl4
*
opl4
;
if
(
snd_opl4_create
(
card
,
miro
->
fm_port
,
miro
->
fm_port
-
8
,
if
(
snd_opl4_create
(
card
,
fm_port
,
fm_port
-
8
,
2
,
&
opl3
,
&
opl4
)
<
0
)
snd_printk
(
KERN_WARNING
"no OPL4 device at 0x%lx
\n
"
,
miro
->
fm_port
);
snd_printk
(
KERN_WARNING
"no OPL4 device at 0x%lx
\n
"
,
fm_port
);
}
if
((
error
=
snd_set_aci_init_values
(
miro
))
<
0
)
{
snd_card_free
(
card
);
error
=
snd_set_aci_init_values
(
miro
);
if
(
error
<
0
)
return
error
;
return
snd_card_register
(
card
);
}
static
int
__devinit
snd_miro_isa_match
(
struct
device
*
devptr
,
unsigned
int
n
)
{
#ifdef CONFIG_PNP
if
(
snd_miro_pnp_is_probed
)
return
0
;
if
(
isapnp
)
return
0
;
#endif
return
1
;
}
static
int
__devinit
snd_miro_isa_probe
(
struct
device
*
devptr
,
unsigned
int
n
)
{
static
long
possible_ports
[]
=
{
0x530
,
0xe80
,
0xf40
,
0x604
,
-
1
};
static
long
possible_mpu_ports
[]
=
{
0x330
,
0x300
,
0x310
,
0x320
,
-
1
};
static
int
possible_irqs
[]
=
{
11
,
9
,
10
,
7
,
-
1
};
static
int
possible_mpu_irqs
[]
=
{
10
,
5
,
9
,
7
,
-
1
};
static
int
possible_dma1s
[]
=
{
3
,
1
,
0
,
-
1
};
static
int
possible_dma2s
[][
2
]
=
{
{
1
,
-
1
},
{
0
,
-
1
},
{
-
1
,
-
1
},
{
0
,
-
1
}
};
int
error
;
struct
snd_miro
*
miro
;
struct
snd_card
*
card
;
error
=
snd_card_create
(
index
,
id
,
THIS_MODULE
,
sizeof
(
struct
snd_miro
),
&
card
);
if
(
error
<
0
)
return
error
;
card
->
private_free
=
snd_card_miro_free
;
miro
=
card
->
private_data
;
error
=
snd_card_miro_detect
(
card
,
miro
);
if
(
error
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"unable to detect OPTi9xx chip
\n
"
);
return
-
ENODEV
;
}
if
(
port
==
SNDRV_AUTO_PORT
)
{
port
=
snd_legacy_find_free_ioport
(
possible_ports
,
4
);
if
(
port
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"unable to find a free WSS port
\n
"
);
return
-
EBUSY
;
}
}
if
(
mpu_port
==
SNDRV_AUTO_PORT
)
{
mpu_port
=
snd_legacy_find_free_ioport
(
possible_mpu_ports
,
2
);
if
(
mpu_port
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"unable to find a free MPU401 port
\n
"
);
return
-
EBUSY
;
}
}
if
(
irq
==
SNDRV_AUTO_IRQ
)
{
irq
=
snd_legacy_find_free_irq
(
possible_irqs
);
if
(
irq
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"unable to find a free IRQ
\n
"
);
return
-
EBUSY
;
}
}
if
(
mpu_irq
==
SNDRV_AUTO_IRQ
)
{
mpu_irq
=
snd_legacy_find_free_irq
(
possible_mpu_irqs
);
if
(
mpu_irq
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"unable to find a free MPU401 IRQ
\n
"
);
return
-
EBUSY
;
}
}
if
(
dma1
==
SNDRV_AUTO_DMA
)
{
dma1
=
snd_legacy_find_free_dma
(
possible_dma1s
);
if
(
dma1
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"unable to find a free DMA1
\n
"
);
return
-
EBUSY
;
}
}
if
(
dma2
==
SNDRV_AUTO_DMA
)
{
dma2
=
snd_legacy_find_free_dma
(
possible_dma2s
[
dma1
%
4
]);
if
(
dma2
<
0
)
{
snd_card_free
(
card
);
snd_printk
(
KERN_ERR
"unable to find a free DMA2
\n
"
);
return
-
EBUSY
;
}
}
snd_card_set_dev
(
card
,
devptr
);
if
((
error
=
snd_card_register
(
card
)))
{
error
=
snd_miro_probe
(
card
);
if
(
error
<
0
)
{
snd_card_free
(
card
);
return
error
;
}
...
...
@@ -1412,7 +1507,8 @@ static int __devinit snd_miro_probe(struct device *devptr, unsigned int n)
return
0
;
}
static
int
__devexit
snd_miro_remove
(
struct
device
*
devptr
,
unsigned
int
dev
)
static
int
__devexit
snd_miro_isa_remove
(
struct
device
*
devptr
,
unsigned
int
dev
)
{
snd_card_free
(
dev_get_drvdata
(
devptr
));
dev_set_drvdata
(
devptr
,
NULL
);
...
...
@@ -1422,23 +1518,164 @@ static int __devexit snd_miro_remove(struct device *devptr, unsigned int dev)
#define DEV_NAME "miro"
static
struct
isa_driver
snd_miro_driver
=
{
.
match
=
snd_miro_match
,
.
probe
=
snd_miro_probe
,
.
remove
=
__devexit_p
(
snd_miro_remove
),
.
match
=
snd_miro_
isa_
match
,
.
probe
=
snd_miro_
isa_
probe
,
.
remove
=
__devexit_p
(
snd_miro_
isa_
remove
),
/* FIXME: suspend/resume */
.
driver
=
{
.
name
=
DEV_NAME
},
};
#ifdef CONFIG_PNP
static
int
__devinit
snd_card_miro_pnp
(
struct
snd_miro
*
chip
,
struct
pnp_card_link
*
card
,
const
struct
pnp_card_device_id
*
pid
)
{
struct
pnp_dev
*
pdev
;
int
err
;
struct
pnp_dev
*
devmpu
;
struct
pnp_dev
*
devmc
;
pdev
=
pnp_request_card_device
(
card
,
pid
->
devs
[
0
].
id
,
NULL
);
if
(
pdev
==
NULL
)
return
-
EBUSY
;
devmpu
=
pnp_request_card_device
(
card
,
pid
->
devs
[
1
].
id
,
NULL
);
if
(
devmpu
==
NULL
)
return
-
EBUSY
;
devmc
=
pnp_request_card_device
(
card
,
pid
->
devs
[
2
].
id
,
NULL
);
if
(
devmc
==
NULL
)
return
-
EBUSY
;
err
=
pnp_activate_dev
(
pdev
);
if
(
err
<
0
)
{
snd_printk
(
KERN_ERR
"AUDIO pnp configure failure: %d
\n
"
,
err
);
return
err
;
}
err
=
pnp_activate_dev
(
devmc
);
if
(
err
<
0
)
{
snd_printk
(
KERN_ERR
"OPL syntg pnp configure failure: %d
\n
"
,
err
);
return
err
;
}
port
=
pnp_port_start
(
pdev
,
1
);
fm_port
=
pnp_port_start
(
pdev
,
2
)
+
8
;
/*
* The MC(0) is never accessed and the miroSOUND PCM20 card does not
* include it in the PnP resource range. OPTI93x include it.
*/
chip
->
mc_base
=
pnp_port_start
(
devmc
,
0
)
-
1
;
chip
->
mc_base_size
=
pnp_port_len
(
devmc
,
0
)
+
1
;
irq
=
pnp_irq
(
pdev
,
0
);
dma1
=
pnp_dma
(
pdev
,
0
);
dma2
=
pnp_dma
(
pdev
,
1
);
if
(
mpu_port
>
0
)
{
err
=
pnp_activate_dev
(
devmpu
);
if
(
err
<
0
)
{
snd_printk
(
KERN_ERR
"MPU401 pnp configure failure
\n
"
);
mpu_port
=
-
1
;
return
err
;
}
mpu_port
=
pnp_port_start
(
devmpu
,
0
);
mpu_irq
=
pnp_irq
(
devmpu
,
0
);
}
return
0
;
}
static
int
__devinit
snd_miro_pnp_probe
(
struct
pnp_card_link
*
pcard
,
const
struct
pnp_card_device_id
*
pid
)
{
struct
snd_card
*
card
;
int
err
;
struct
snd_miro
*
miro
;
if
(
snd_miro_pnp_is_probed
)
return
-
EBUSY
;
if
(
!
isapnp
)
return
-
ENODEV
;
err
=
snd_card_create
(
index
,
id
,
THIS_MODULE
,
sizeof
(
struct
snd_miro
),
&
card
);
if
(
err
<
0
)
return
err
;
card
->
private_free
=
snd_card_miro_free
;
miro
=
card
->
private_data
;
err
=
snd_card_miro_pnp
(
miro
,
pcard
,
pid
);
if
(
err
)
{
snd_card_free
(
card
);
return
err
;
}
/* only miroSOUND PCM20 and PCM12 == OPTi924 */
err
=
snd_miro_init
(
miro
,
OPTi9XX_HW_82C924
);
if
(
err
)
{
snd_card_free
(
card
);
return
err
;
}
err
=
snd_miro_opti_check
(
miro
);
if
(
err
)
{
snd_printk
(
KERN_ERR
"OPTI chip not found
\n
"
);
snd_card_free
(
card
);
return
err
;
}
snd_card_set_dev
(
card
,
&
pcard
->
card
->
dev
);
err
=
snd_miro_probe
(
card
);
if
(
err
<
0
)
{
snd_card_free
(
card
);
return
err
;
}
pnp_set_card_drvdata
(
pcard
,
card
);
snd_miro_pnp_is_probed
=
1
;
return
0
;
}
static
void
__devexit
snd_miro_pnp_remove
(
struct
pnp_card_link
*
pcard
)
{
snd_card_free
(
pnp_get_card_drvdata
(
pcard
));
pnp_set_card_drvdata
(
pcard
,
NULL
);
snd_miro_pnp_is_probed
=
0
;
}
static
struct
pnp_card_driver
miro_pnpc_driver
=
{
.
flags
=
PNP_DRIVER_RES_DISABLE
,
.
name
=
"miro"
,
.
id_table
=
snd_miro_pnpids
,
.
probe
=
snd_miro_pnp_probe
,
.
remove
=
__devexit_p
(
snd_miro_pnp_remove
),
};
#endif
static
int
__init
alsa_card_miro_init
(
void
)
{
#ifdef CONFIG_PNP
pnp_register_card_driver
(
&
miro_pnpc_driver
);
if
(
snd_miro_pnp_is_probed
)
return
0
;
pnp_unregister_card_driver
(
&
miro_pnpc_driver
);
#endif
return
isa_register_driver
(
&
snd_miro_driver
,
1
);
}
static
void
__exit
alsa_card_miro_exit
(
void
)
{
if
(
!
snd_miro_pnp_is_probed
)
{
isa_unregister_driver
(
&
snd_miro_driver
);
return
;
}
#ifdef CONFIG_PNP
pnp_unregister_card_driver
(
&
miro_pnpc_driver
);
#endif
}
module_init
(
alsa_card_miro_init
)
...
...
sound/isa/opti9xx/opti92x-ad1848.c
View file @
57648cd5
...
...
@@ -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 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
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 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
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 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
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 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip)
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
;
x
dma2
=
dma2
;
#else
chip
->
dma2
=
-
1
;
x
dma2
=
-
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
);
...
...
sound/isa/wss/wss_lib.c
View file @
57648cd5
...
...
@@ -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
),
};
...
...
sound/oss/audio.c
View file @
57648cd5
...
...
@@ -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
;
...
...
sound/oss/midi_synth.c
View file @
57648cd5
...
...
@@ -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
;
...
...
sound/oss/mpu401.c
View file @
57648cd5
...
...
@@ -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
];
...
...
sound/pci/Kconfig
View file @
57648cd5
...
...
@@ -570,6 +570,7 @@ config SND_ICE1712
tristate "ICEnsemble ICE1712 (Envy24)"
select SND_MPU401_UART
select SND_AC97_CODEC
select BITREVERSE
help
Say Y here to include support for soundcards based on the
ICE1712 (Envy24) chip.
...
...
sound/pci/fm801.c
View file @
57648cd5
...
...
@@ -55,7 +55,7 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card *
* 1 = MediaForte 256-PCS
* 2 = MediaForte 256-PCPR
* 3 = MediaForte 64-PCR
* 16 = setup tuner only (this is additional bit), i.e. SF
-
64-PCR FM card
* 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card
* High 16-bits are video (radio) device number + 1
*/
static
int
tea575x_tuner
[
SNDRV_CARDS
];
...
...
@@ -67,7 +67,10 @@ MODULE_PARM_DESC(id, "ID string for the FM801 soundcard.");
module_param_array
(
enable
,
bool
,
NULL
,
0444
);
MODULE_PARM_DESC
(
enable
,
"Enable FM801 soundcard."
);
module_param_array
(
tea575x_tuner
,
int
,
NULL
,
0444
);
MODULE_PARM_DESC
(
tea575x_tuner
,
"Enable TEA575x tuner."
);
MODULE_PARM_DESC
(
tea575x_tuner
,
"TEA575x tuner access method (1 = SF256-PCS, 2=SF256-PCPR, 3=SF64-PCR, +16=tuner-only)."
);
#define TUNER_ONLY (1<<4)
#define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF)
/*
* Direct registers
...
...
@@ -160,7 +163,7 @@ struct fm801 {
unsigned
int
multichannel
:
1
,
/* multichannel support */
secondary:
1
;
/* secondary codec */
unsigned
char
secondary_addr
;
/* address of the secondary codec */
unsigned
int
tea575x_tuner
;
/* tuner flags */
unsigned
int
tea575x_tuner
;
/* tuner
access method &
flags */
unsigned
short
ply_ctrl
;
/* playback control */
unsigned
short
cap_ctrl
;
/* capture control */
...
...
@@ -1287,7 +1290,7 @@ static int snd_fm801_chip_init(struct fm801 *chip, int resume)
{
unsigned
short
cmdw
;
if
(
chip
->
tea575x_tuner
&
0x0010
)
if
(
chip
->
tea575x_tuner
&
TUNER_ONLY
)
goto
__ac97_ok
;
/* codec cold reset + AC'97 warm reset */
...
...
@@ -1296,10 +1299,12 @@ static int snd_fm801_chip_init(struct fm801 *chip, int resume)
udelay
(
100
);
outw
(
0
,
FM801_REG
(
chip
,
CODEC_CTRL
));
if
(
wait_for_codec
(
chip
,
0
,
AC97_RESET
,
msecs_to_jiffies
(
750
))
<
0
)
{
snd_printk
(
KERN_ERR
"Primary AC'97 codec not found
\n
"
);
if
(
!
resume
)
return
-
EIO
;
if
(
wait_for_codec
(
chip
,
0
,
AC97_RESET
,
msecs_to_jiffies
(
750
))
<
0
)
if
(
!
resume
)
{
snd_printk
(
KERN_INFO
"Primary AC'97 codec not found, "
"assume SF64-PCR (tuner-only)
\n
"
);
chip
->
tea575x_tuner
=
3
|
TUNER_ONLY
;
goto
__ac97_ok
;
}
if
(
chip
->
multichannel
)
{
...
...
@@ -1414,7 +1419,7 @@ static int __devinit snd_fm801_create(struct snd_card *card,
return
err
;
}
chip
->
port
=
pci_resource_start
(
pci
,
0
);
if
((
tea575x_tuner
&
0x0010
)
==
0
)
{
if
((
tea575x_tuner
&
TUNER_ONLY
)
==
0
)
{
if
(
request_irq
(
pci
->
irq
,
snd_fm801_interrupt
,
IRQF_SHARED
,
"FM801"
,
chip
))
{
snd_printk
(
KERN_ERR
"unable to grab IRQ %d
\n
"
,
chip
->
irq
);
...
...
@@ -1429,6 +1434,14 @@ static int __devinit snd_fm801_create(struct snd_card *card,
chip
->
multichannel
=
1
;
snd_fm801_chip_init
(
chip
,
0
);
/* init might set tuner access method */
tea575x_tuner
=
chip
->
tea575x_tuner
;
if
(
chip
->
irq
>=
0
&&
(
tea575x_tuner
&
TUNER_ONLY
))
{
pci_clear_master
(
pci
);
free_irq
(
chip
->
irq
,
chip
);
chip
->
irq
=
-
1
;
}
if
((
err
=
snd_device_new
(
card
,
SNDRV_DEV_LOWLEVEL
,
chip
,
&
ops
))
<
0
)
{
snd_fm801_free
(
chip
);
...
...
@@ -1438,12 +1451,13 @@ static int __devinit snd_fm801_create(struct snd_card *card,
snd_card_set_dev
(
card
,
&
pci
->
dev
);
#ifdef TEA575X_RADIO
if
(
tea575x_tuner
>
0
&&
(
tea575x_tuner
&
0x000f
)
<
4
)
{
if
((
tea575x_tuner
&
TUNER_TYPE_MASK
)
>
0
&&
(
tea575x_tuner
&
TUNER_TYPE_MASK
)
<
4
)
{
chip
->
tea
.
dev_nr
=
tea575x_tuner
>>
16
;
chip
->
tea
.
card
=
card
;
chip
->
tea
.
freq_fixup
=
10700
;
chip
->
tea
.
private_data
=
chip
;
chip
->
tea
.
ops
=
&
snd_fm801_tea_ops
[(
tea575x_tuner
&
0x000f
)
-
1
];
chip
->
tea
.
ops
=
&
snd_fm801_tea_ops
[(
tea575x_tuner
&
TUNER_TYPE_MASK
)
-
1
];
snd_tea575x_init
(
&
chip
->
tea
);
}
#endif
...
...
@@ -1483,7 +1497,7 @@ static int __devinit snd_card_fm801_probe(struct pci_dev *pci,
sprintf
(
card
->
longname
,
"%s at 0x%lx, irq %i"
,
card
->
shortname
,
chip
->
port
,
chip
->
irq
);
if
(
tea575x_tuner
[
dev
]
&
0x0010
)
if
(
chip
->
tea575x_tuner
&
TUNER_ONLY
)
goto
__fm801_tuner_only
;
if
((
err
=
snd_fm801_pcm
(
chip
,
0
,
NULL
))
<
0
)
{
...
...
sound/pci/ice1712/juli.c
View file @
57648cd5
...
...
@@ -503,6 +503,31 @@ static int __devinit juli_add_controls(struct snd_ice1712 *ice)
return
0
;
}
/*
* suspend/resume
* */
#ifdef CONFIG_PM
static
int
juli_resume
(
struct
snd_ice1712
*
ice
)
{
struct
snd_akm4xxx
*
ak
=
ice
->
akm
;
struct
juli_spec
*
spec
=
ice
->
spec
;
/* akm4358 un-reset, un-mute */
snd_akm4xxx_reset
(
ak
,
0
);
/* reinit ak4114 */
snd_ak4114_reinit
(
spec
->
ak4114
);
return
0
;
}
static
int
juli_suspend
(
struct
snd_ice1712
*
ice
)
{
struct
snd_akm4xxx
*
ak
=
ice
->
akm
;
/* akm4358 reset and soft-mute */
snd_akm4xxx_reset
(
ak
,
1
);
return
0
;
}
#endif
/*
* initialize the chip
*/
...
...
@@ -646,6 +671,13 @@ static int __devinit juli_init(struct snd_ice1712 *ice)
ice
->
set_spdif_clock
=
juli_set_spdif_clock
;
ice
->
spdif
.
ops
.
open
=
juli_spdif_in_open
;
#ifdef CONFIG_PM
ice
->
pm_resume
=
juli_resume
;
ice
->
pm_suspend
=
juli_suspend
;
ice
->
pm_suspend_enabled
=
1
;
#endif
return
0
;
}
...
...
sound/pci/intel8x0.c
View file @
57648cd5
...
...
@@ -2062,6 +2062,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = {
.
name
=
"MSI P4 ATX 645 Ultra"
,
.
type
=
AC97_TUNE_HP_ONLY
},
{
.
subvendor
=
0x161f
,
.
subdevice
=
0x203a
,
.
name
=
"Gateway 4525GZ"
,
/* AD1981B */
.
type
=
AC97_TUNE_INV_EAPD
},
{
.
subvendor
=
0x1734
,
.
subdevice
=
0x0088
,
...
...
sound/usb/usbaudio.c
View file @
57648cd5
...
...
@@ -2893,7 +2893,9 @@ static int snd_usb_create_streams(struct snd_usb_audio *chip, int ctrlif)
if
((
altsd
->
bInterfaceClass
==
USB_CLASS_AUDIO
||
altsd
->
bInterfaceClass
==
USB_CLASS_VENDOR_SPEC
)
&&
altsd
->
bInterfaceSubClass
==
USB_SUBCLASS_MIDI_STREAMING
)
{
if
(
snd_usb_create_midi_interface
(
chip
,
iface
,
NULL
)
<
0
)
{
int
err
=
snd_usbmidi_create
(
chip
->
card
,
iface
,
&
chip
->
midi_list
,
NULL
);
if
(
err
<
0
)
{
snd_printk
(
KERN_ERR
"%d:%u:%d: cannot create sequencer device
\n
"
,
dev
->
devnum
,
ctrlif
,
j
);
continue
;
}
...
...
@@ -3038,12 +3040,11 @@ static int create_uaxx_quirk(struct snd_usb_audio *chip,
.
type
=
QUIRK_MIDI_FIXED_ENDPOINT
,
.
data
=
&
uaxx_ep
};
if
(
chip
->
usb_id
==
USB_ID
(
0x0582
,
0x002b
))
return
snd_usb_create_midi_interface
(
chip
,
iface
,
&
ua700_quirk
);
else
return
snd_usb_create_midi_interface
(
chip
,
iface
,
&
uaxx_quirk
);
const
struct
snd_usb_audio_quirk
*
quirk
=
chip
->
usb_id
==
USB_ID
(
0x0582
,
0x002b
)
?
&
ua700_quirk
:
&
uaxx_quirk
;
return
snd_usbmidi_create
(
chip
->
card
,
iface
,
&
chip
->
midi_list
,
quirk
);
}
if
(
altsd
->
bNumEndpoints
!=
1
)
...
...
@@ -3370,6 +3371,13 @@ static int audiophile_skip_setting_quirk(struct snd_usb_audio *chip,
return
0
;
/* keep this altsetting */
}
static
int
create_any_midi_quirk
(
struct
snd_usb_audio
*
chip
,
struct
usb_interface
*
intf
,
const
struct
snd_usb_audio_quirk
*
quirk
)
{
return
snd_usbmidi_create
(
chip
->
card
,
intf
,
&
chip
->
midi_list
,
quirk
);
}
/*
* audio-interface quirks
*
...
...
@@ -3387,14 +3395,14 @@ static int snd_usb_create_quirk(struct snd_usb_audio *chip,
static
const
quirk_func_t
quirk_funcs
[]
=
{
[
QUIRK_IGNORE_INTERFACE
]
=
ignore_interface_quirk
,
[
QUIRK_COMPOSITE
]
=
create_composite_quirk
,
[
QUIRK_MIDI_STANDARD_INTERFACE
]
=
snd_usb_create_midi_interface
,
[
QUIRK_MIDI_FIXED_ENDPOINT
]
=
snd_usb_create_midi_interface
,
[
QUIRK_MIDI_YAMAHA
]
=
snd_usb_create_midi_interface
,
[
QUIRK_MIDI_MIDIMAN
]
=
snd_usb_create_midi_interface
,
[
QUIRK_MIDI_NOVATION
]
=
snd_usb_create_midi_interface
,
[
QUIRK_MIDI_FASTLANE
]
=
snd_usb_create_midi_interface
,
[
QUIRK_MIDI_EMAGIC
]
=
snd_usb_create_midi_interface
,
[
QUIRK_MIDI_CME
]
=
snd_usb_create_midi_interface
,
[
QUIRK_MIDI_STANDARD_INTERFACE
]
=
create_any_midi_quirk
,
[
QUIRK_MIDI_FIXED_ENDPOINT
]
=
create_any_midi_quirk
,
[
QUIRK_MIDI_YAMAHA
]
=
create_any_midi_quirk
,
[
QUIRK_MIDI_MIDIMAN
]
=
create_any_midi_quirk
,
[
QUIRK_MIDI_NOVATION
]
=
create_any_midi_quirk
,
[
QUIRK_MIDI_FASTLANE
]
=
create_any_midi_quirk
,
[
QUIRK_MIDI_EMAGIC
]
=
create_any_midi_quirk
,
[
QUIRK_MIDI_CME
]
=
create_any_midi_quirk
,
[
QUIRK_AUDIO_STANDARD_INTERFACE
]
=
create_standard_audio_quirk
,
[
QUIRK_AUDIO_FIXED_ENDPOINT
]
=
create_fixed_stream_quirk
,
[
QUIRK_AUDIO_EDIROL_UA1000
]
=
create_ua1000_quirk
,
...
...
sound/usb/usbaudio.h
View file @
57648cd5
...
...
@@ -132,7 +132,6 @@ struct snd_usb_audio {
int
pcm_devs
;
struct
list_head
midi_list
;
/* list of midi interfaces */
int
next_midi_device
;
struct
list_head
mixer_list
;
/* list of mixer interfaces */
};
...
...
@@ -227,7 +226,9 @@ int snd_usb_create_mixer(struct snd_usb_audio *chip, int ctrlif,
int
ignore_error
);
void
snd_usb_mixer_disconnect
(
struct
list_head
*
p
);
int
snd_usb_create_midi_interface
(
struct
snd_usb_audio
*
chip
,
struct
usb_interface
*
iface
,
int
snd_usbmidi_create
(
struct
snd_card
*
card
,
struct
usb_interface
*
iface
,
struct
list_head
*
midi_list
,
const
struct
snd_usb_audio_quirk
*
quirk
);
void
snd_usbmidi_input_stop
(
struct
list_head
*
p
);
void
snd_usbmidi_input_start
(
struct
list_head
*
p
);
...
...
sound/usb/usbmidi.c
View file @
57648cd5
/*
* usbmidi.c - ALSA USB MIDI driver
*
* Copyright (c) 2002-200
7
Clemens Ladisch
* Copyright (c) 2002-200
9
Clemens Ladisch
* All rights reserved.
*
* Based on the OSS usb-midi driver by NAGANO Daisuke,
...
...
@@ -47,6 +47,7 @@
#include <linux/usb.h>
#include <linux/wait.h>
#include <sound/core.h>
#include <sound/control.h>
#include <sound/rawmidi.h>
#include <sound/asequencer.h>
#include "usbaudio.h"
...
...
@@ -101,7 +102,8 @@ struct usb_protocol_ops {
};
struct
snd_usb_midi
{
struct
snd_usb_audio
*
chip
;
struct
usb_device
*
dev
;
struct
snd_card
*
card
;
struct
usb_interface
*
iface
;
const
struct
snd_usb_audio_quirk
*
quirk
;
struct
snd_rawmidi
*
rmidi
;
...
...
@@ -109,13 +111,19 @@ struct snd_usb_midi {
struct
list_head
list
;
struct
timer_list
error_timer
;
spinlock_t
disc_lock
;
struct
mutex
mutex
;
u32
usb_id
;
int
next_midi_device
;
struct
snd_usb_midi_endpoint
{
struct
snd_usb_midi_out_endpoint
*
out
;
struct
snd_usb_midi_in_endpoint
*
in
;
}
endpoints
[
MIDI_MAX_ENDPOINTS
];
unsigned
long
input_triggered
;
unsigned
int
opened
;
unsigned
char
disconnected
;
struct
snd_kcontrol
*
roland_load_ctl
;
};
struct
snd_usb_midi_out_endpoint
{
...
...
@@ -255,7 +263,7 @@ static void snd_usbmidi_in_urb_complete(struct urb* urb)
}
}
urb
->
dev
=
ep
->
umidi
->
chip
->
dev
;
urb
->
dev
=
ep
->
umidi
->
dev
;
snd_usbmidi_submit_urb
(
urb
,
GFP_ATOMIC
);
}
...
...
@@ -296,7 +304,7 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep)
unsigned
long
flags
;
spin_lock_irqsave
(
&
ep
->
buffer_lock
,
flags
);
if
(
ep
->
umidi
->
chip
->
shutdown
)
{
if
(
ep
->
umidi
->
disconnected
)
{
spin_unlock_irqrestore
(
&
ep
->
buffer_lock
,
flags
);
return
;
}
...
...
@@ -312,7 +320,7 @@ static void snd_usbmidi_do_output(struct snd_usb_midi_out_endpoint* ep)
dump_urb
(
"sending"
,
urb
->
transfer_buffer
,
urb
->
transfer_buffer_length
);
urb
->
dev
=
ep
->
umidi
->
chip
->
dev
;
urb
->
dev
=
ep
->
umidi
->
dev
;
if
(
snd_usbmidi_submit_urb
(
urb
,
GFP_ATOMIC
)
<
0
)
break
;
ep
->
active_urbs
|=
1
<<
urb_index
;
...
...
@@ -349,7 +357,7 @@ static void snd_usbmidi_error_timer(unsigned long data)
if
(
in
&&
in
->
error_resubmit
)
{
in
->
error_resubmit
=
0
;
for
(
j
=
0
;
j
<
INPUT_URBS
;
++
j
)
{
in
->
urbs
[
j
]
->
dev
=
umidi
->
chip
->
dev
;
in
->
urbs
[
j
]
->
dev
=
umidi
->
dev
;
snd_usbmidi_submit_urb
(
in
->
urbs
[
j
],
GFP_ATOMIC
);
}
}
...
...
@@ -369,7 +377,7 @@ static int send_bulk_static_data(struct snd_usb_midi_out_endpoint* ep,
return
-
ENOMEM
;
dump_urb
(
"sending"
,
buf
,
len
);
if
(
ep
->
urbs
[
0
].
urb
)
err
=
usb_bulk_msg
(
ep
->
umidi
->
chip
->
dev
,
ep
->
urbs
[
0
].
urb
->
pipe
,
err
=
usb_bulk_msg
(
ep
->
umidi
->
dev
,
ep
->
urbs
[
0
].
urb
->
pipe
,
buf
,
len
,
NULL
,
250
);
kfree
(
buf
);
return
err
;
...
...
@@ -724,8 +732,7 @@ static void snd_usbmidi_us122l_output(struct snd_usb_midi_out_endpoint *ep,
if
(
!
ep
->
ports
[
0
].
active
)
return
;
count
=
snd_usb_get_speed
(
ep
->
umidi
->
chip
->
dev
)
==
USB_SPEED_HIGH
?
1
:
2
;
count
=
snd_usb_get_speed
(
ep
->
umidi
->
dev
)
==
USB_SPEED_HIGH
?
1
:
2
;
count
=
snd_rawmidi_transmit
(
ep
->
ports
[
0
].
substream
,
urb
->
transfer_buffer
,
count
);
...
...
@@ -879,6 +886,50 @@ static struct usb_protocol_ops snd_usbmidi_emagic_ops = {
};
static
void
update_roland_altsetting
(
struct
snd_usb_midi
*
umidi
)
{
struct
usb_interface
*
intf
;
struct
usb_host_interface
*
hostif
;
struct
usb_interface_descriptor
*
intfd
;
int
is_light_load
;
intf
=
umidi
->
iface
;
is_light_load
=
intf
->
cur_altsetting
!=
intf
->
altsetting
;
if
(
umidi
->
roland_load_ctl
->
private_value
==
is_light_load
)
return
;
hostif
=
&
intf
->
altsetting
[
umidi
->
roland_load_ctl
->
private_value
];
intfd
=
get_iface_desc
(
hostif
);
snd_usbmidi_input_stop
(
&
umidi
->
list
);
usb_set_interface
(
umidi
->
dev
,
intfd
->
bInterfaceNumber
,
intfd
->
bAlternateSetting
);
snd_usbmidi_input_start
(
&
umidi
->
list
);
}
static
void
substream_open
(
struct
snd_rawmidi_substream
*
substream
,
int
open
)
{
struct
snd_usb_midi
*
umidi
=
substream
->
rmidi
->
private_data
;
struct
snd_kcontrol
*
ctl
;
mutex_lock
(
&
umidi
->
mutex
);
if
(
open
)
{
if
(
umidi
->
opened
++
==
0
&&
umidi
->
roland_load_ctl
)
{
ctl
=
umidi
->
roland_load_ctl
;
ctl
->
vd
[
0
].
access
|=
SNDRV_CTL_ELEM_ACCESS_INACTIVE
;
snd_ctl_notify
(
umidi
->
card
,
SNDRV_CTL_EVENT_MASK_INFO
,
&
ctl
->
id
);
update_roland_altsetting
(
umidi
);
}
}
else
{
if
(
--
umidi
->
opened
==
0
&&
umidi
->
roland_load_ctl
)
{
ctl
=
umidi
->
roland_load_ctl
;
ctl
->
vd
[
0
].
access
&=
~
SNDRV_CTL_ELEM_ACCESS_INACTIVE
;
snd_ctl_notify
(
umidi
->
card
,
SNDRV_CTL_EVENT_MASK_INFO
,
&
ctl
->
id
);
}
}
mutex_unlock
(
&
umidi
->
mutex
);
}
static
int
snd_usbmidi_output_open
(
struct
snd_rawmidi_substream
*
substream
)
{
struct
snd_usb_midi
*
umidi
=
substream
->
rmidi
->
private_data
;
...
...
@@ -898,11 +949,13 @@ static int snd_usbmidi_output_open(struct snd_rawmidi_substream *substream)
}
substream
->
runtime
->
private_data
=
port
;
port
->
state
=
STATE_UNKNOWN
;
substream_open
(
substream
,
1
);
return
0
;
}
static
int
snd_usbmidi_output_close
(
struct
snd_rawmidi_substream
*
substream
)
{
substream_open
(
substream
,
0
);
return
0
;
}
...
...
@@ -912,7 +965,7 @@ static void snd_usbmidi_output_trigger(struct snd_rawmidi_substream *substream,
port
->
active
=
up
;
if
(
up
)
{
if
(
port
->
ep
->
umidi
->
chip
->
shutdown
)
{
if
(
port
->
ep
->
umidi
->
disconnected
)
{
/* gobble up remaining bytes to prevent wait in
* snd_rawmidi_drain_output */
while
(
!
snd_rawmidi_transmit_empty
(
substream
))
...
...
@@ -954,11 +1007,13 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
static
int
snd_usbmidi_input_open
(
struct
snd_rawmidi_substream
*
substream
)
{
substream_open
(
substream
,
1
);
return
0
;
}
static
int
snd_usbmidi_input_close
(
struct
snd_rawmidi_substream
*
substream
)
{
substream_open
(
substream
,
0
);
return
0
;
}
...
...
@@ -988,7 +1043,7 @@ static struct snd_rawmidi_ops snd_usbmidi_input_ops = {
static
void
free_urb_and_buffer
(
struct
snd_usb_midi
*
umidi
,
struct
urb
*
urb
,
unsigned
int
buffer_length
)
{
usb_buffer_free
(
umidi
->
chip
->
dev
,
buffer_length
,
usb_buffer_free
(
umidi
->
dev
,
buffer_length
,
urb
->
transfer_buffer
,
urb
->
transfer_dma
);
usb_free_urb
(
urb
);
}
...
...
@@ -1035,24 +1090,24 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
}
}
if
(
ep_info
->
in_interval
)
pipe
=
usb_rcvintpipe
(
umidi
->
chip
->
dev
,
ep_info
->
in_ep
);
pipe
=
usb_rcvintpipe
(
umidi
->
dev
,
ep_info
->
in_ep
);
else
pipe
=
usb_rcvbulkpipe
(
umidi
->
chip
->
dev
,
ep_info
->
in_ep
);
length
=
usb_maxpacket
(
umidi
->
chip
->
dev
,
pipe
,
0
);
pipe
=
usb_rcvbulkpipe
(
umidi
->
dev
,
ep_info
->
in_ep
);
length
=
usb_maxpacket
(
umidi
->
dev
,
pipe
,
0
);
for
(
i
=
0
;
i
<
INPUT_URBS
;
++
i
)
{
buffer
=
usb_buffer_alloc
(
umidi
->
chip
->
dev
,
length
,
GFP_KERNEL
,
buffer
=
usb_buffer_alloc
(
umidi
->
dev
,
length
,
GFP_KERNEL
,
&
ep
->
urbs
[
i
]
->
transfer_dma
);
if
(
!
buffer
)
{
snd_usbmidi_in_endpoint_delete
(
ep
);
return
-
ENOMEM
;
}
if
(
ep_info
->
in_interval
)
usb_fill_int_urb
(
ep
->
urbs
[
i
],
umidi
->
chip
->
dev
,
usb_fill_int_urb
(
ep
->
urbs
[
i
],
umidi
->
dev
,
pipe
,
buffer
,
length
,
snd_usbmidi_in_urb_complete
,
ep
,
ep_info
->
in_interval
);
else
usb_fill_bulk_urb
(
ep
->
urbs
[
i
],
umidi
->
chip
->
dev
,
usb_fill_bulk_urb
(
ep
->
urbs
[
i
],
umidi
->
dev
,
pipe
,
buffer
,
length
,
snd_usbmidi_in_urb_complete
,
ep
);
ep
->
urbs
[
i
]
->
transfer_flags
=
URB_NO_TRANSFER_DMA_MAP
;
...
...
@@ -1062,15 +1117,6 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
return
0
;
}
static
unsigned
int
snd_usbmidi_count_bits
(
unsigned
int
x
)
{
unsigned
int
bits
;
for
(
bits
=
0
;
x
;
++
bits
)
x
&=
x
-
1
;
return
bits
;
}
/*
* Frees an output endpoint.
* May be called when ep hasn't been initialized completely.
...
...
@@ -1113,15 +1159,15 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
ep
->
urbs
[
i
].
ep
=
ep
;
}
if
(
ep_info
->
out_interval
)
pipe
=
usb_sndintpipe
(
umidi
->
chip
->
dev
,
ep_info
->
out_ep
);
pipe
=
usb_sndintpipe
(
umidi
->
dev
,
ep_info
->
out_ep
);
else
pipe
=
usb_sndbulkpipe
(
umidi
->
chip
->
dev
,
ep_info
->
out_ep
);
if
(
umidi
->
chip
->
usb_id
==
USB_ID
(
0x0a92
,
0x1020
))
/* ESI M4U */
pipe
=
usb_sndbulkpipe
(
umidi
->
dev
,
ep_info
->
out_ep
);
if
(
umidi
->
usb_id
==
USB_ID
(
0x0a92
,
0x1020
))
/* ESI M4U */
ep
->
max_transfer
=
4
;
else
ep
->
max_transfer
=
usb_maxpacket
(
umidi
->
chip
->
dev
,
pipe
,
1
);
ep
->
max_transfer
=
usb_maxpacket
(
umidi
->
dev
,
pipe
,
1
);
for
(
i
=
0
;
i
<
OUTPUT_URBS
;
++
i
)
{
buffer
=
usb_buffer_alloc
(
umidi
->
chip
->
dev
,
buffer
=
usb_buffer_alloc
(
umidi
->
dev
,
ep
->
max_transfer
,
GFP_KERNEL
,
&
ep
->
urbs
[
i
].
urb
->
transfer_dma
);
if
(
!
buffer
)
{
...
...
@@ -1129,12 +1175,12 @@ static int snd_usbmidi_out_endpoint_create(struct snd_usb_midi* umidi,
return
-
ENOMEM
;
}
if
(
ep_info
->
out_interval
)
usb_fill_int_urb
(
ep
->
urbs
[
i
].
urb
,
umidi
->
chip
->
dev
,
usb_fill_int_urb
(
ep
->
urbs
[
i
].
urb
,
umidi
->
dev
,
pipe
,
buffer
,
ep
->
max_transfer
,
snd_usbmidi_out_urb_complete
,
&
ep
->
urbs
[
i
],
ep_info
->
out_interval
);
else
usb_fill_bulk_urb
(
ep
->
urbs
[
i
].
urb
,
umidi
->
chip
->
dev
,
usb_fill_bulk_urb
(
ep
->
urbs
[
i
].
urb
,
umidi
->
dev
,
pipe
,
buffer
,
ep
->
max_transfer
,
snd_usbmidi_out_urb_complete
,
&
ep
->
urbs
[
i
]);
...
...
@@ -1172,6 +1218,7 @@ static void snd_usbmidi_free(struct snd_usb_midi* umidi)
if
(
ep
->
in
)
snd_usbmidi_in_endpoint_delete
(
ep
->
in
);
}
mutex_destroy
(
&
umidi
->
mutex
);
kfree
(
umidi
);
}
...
...
@@ -1367,7 +1414,7 @@ static struct port_info *find_port_info(struct snd_usb_midi* umidi, int number)
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
snd_usbmidi_port_info
);
++
i
)
{
if
(
snd_usbmidi_port_info
[
i
].
id
==
umidi
->
chip
->
usb_id
&&
if
(
snd_usbmidi_port_info
[
i
].
id
==
umidi
->
usb_id
&&
snd_usbmidi_port_info
[
i
].
port
==
number
)
return
&
snd_usbmidi_port_info
[
i
];
}
...
...
@@ -1405,7 +1452,7 @@ static void snd_usbmidi_init_substream(struct snd_usb_midi* umidi,
port_info
=
find_port_info
(
umidi
,
number
);
name_format
=
port_info
?
port_info
->
name
:
"%s MIDI %d"
;
snprintf
(
substream
->
name
,
sizeof
(
substream
->
name
),
name_format
,
umidi
->
c
hip
->
c
ard
->
shortname
,
number
+
1
);
name_format
,
umidi
->
card
->
shortname
,
number
+
1
);
*
rsubstream
=
substream
;
}
...
...
@@ -1503,7 +1550,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
endpoints
[
epidx
].
out_ep
=
usb_endpoint_num
(
ep
);
if
(
usb_endpoint_xfer_int
(
ep
))
endpoints
[
epidx
].
out_interval
=
ep
->
bInterval
;
else
if
(
snd_usb_get_speed
(
umidi
->
chip
->
dev
)
==
USB_SPEED_LOW
)
else
if
(
snd_usb_get_speed
(
umidi
->
dev
)
==
USB_SPEED_LOW
)
/*
* Low speed bulk transfers don't exist, so
* force interrupt transfers for devices like
...
...
@@ -1523,7 +1570,7 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
endpoints
[
epidx
].
in_ep
=
usb_endpoint_num
(
ep
);
if
(
usb_endpoint_xfer_int
(
ep
))
endpoints
[
epidx
].
in_interval
=
ep
->
bInterval
;
else
if
(
snd_usb_get_speed
(
umidi
->
chip
->
dev
)
==
USB_SPEED_LOW
)
else
if
(
snd_usb_get_speed
(
umidi
->
dev
)
==
USB_SPEED_LOW
)
endpoints
[
epidx
].
in_interval
=
1
;
endpoints
[
epidx
].
in_cables
=
(
1
<<
ms_ep
->
bNumEmbMIDIJack
)
-
1
;
snd_printdd
(
KERN_INFO
"EP %02X: %d jack(s)
\n
"
,
...
...
@@ -1533,6 +1580,52 @@ static int snd_usbmidi_get_ms_info(struct snd_usb_midi* umidi,
return
0
;
}
static
int
roland_load_info
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_info
*
info
)
{
static
const
char
*
const
names
[]
=
{
"High Load"
,
"Light Load"
};
info
->
type
=
SNDRV_CTL_ELEM_TYPE_ENUMERATED
;
info
->
count
=
1
;
info
->
value
.
enumerated
.
items
=
2
;
if
(
info
->
value
.
enumerated
.
item
>
1
)
info
->
value
.
enumerated
.
item
=
1
;
strcpy
(
info
->
value
.
enumerated
.
name
,
names
[
info
->
value
.
enumerated
.
item
]);
return
0
;
}
static
int
roland_load_get
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
value
)
{
value
->
value
.
enumerated
.
item
[
0
]
=
kcontrol
->
private_value
;
return
0
;
}
static
int
roland_load_put
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
value
)
{
struct
snd_usb_midi
*
umidi
=
kcontrol
->
private_data
;
int
changed
;
if
(
value
->
value
.
enumerated
.
item
[
0
]
>
1
)
return
-
EINVAL
;
mutex_lock
(
&
umidi
->
mutex
);
changed
=
value
->
value
.
enumerated
.
item
[
0
]
!=
kcontrol
->
private_value
;
if
(
changed
)
kcontrol
->
private_value
=
value
->
value
.
enumerated
.
item
[
0
];
mutex_unlock
(
&
umidi
->
mutex
);
return
changed
;
}
static
struct
snd_kcontrol_new
roland_load_ctl
=
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_MIXER
,
.
name
=
"MIDI Input Mode"
,
.
info
=
roland_load_info
,
.
get
=
roland_load_get
,
.
put
=
roland_load_put
,
.
private_value
=
1
,
};
/*
* On Roland devices, use the second alternate setting to be able to use
* the interrupt input endpoint.
...
...
@@ -1556,8 +1649,12 @@ static void snd_usbmidi_switch_roland_altsetting(struct snd_usb_midi* umidi)
snd_printdd
(
KERN_INFO
"switching to altsetting %d with int ep
\n
"
,
intfd
->
bAlternateSetting
);
usb_set_interface
(
umidi
->
chip
->
dev
,
intfd
->
bInterfaceNumber
,
usb_set_interface
(
umidi
->
dev
,
intfd
->
bInterfaceNumber
,
intfd
->
bAlternateSetting
);
umidi
->
roland_load_ctl
=
snd_ctl_new1
(
&
roland_load_ctl
,
umidi
);
if
(
snd_ctl_add
(
umidi
->
card
,
umidi
->
roland_load_ctl
)
<
0
)
umidi
->
roland_load_ctl
=
NULL
;
}
/*
...
...
@@ -1573,7 +1670,7 @@ static int snd_usbmidi_detect_endpoints(struct snd_usb_midi* umidi,
struct
usb_endpoint_descriptor
*
epd
;
int
i
,
out_eps
=
0
,
in_eps
=
0
;
if
(
USB_ID_VENDOR
(
umidi
->
chip
->
usb_id
)
==
0x0582
)
if
(
USB_ID_VENDOR
(
umidi
->
usb_id
)
==
0x0582
)
snd_usbmidi_switch_roland_altsetting
(
umidi
);
if
(
endpoint
[
0
].
out_ep
||
endpoint
[
0
].
in_ep
)
...
...
@@ -1760,12 +1857,12 @@ static int snd_usbmidi_create_rawmidi(struct snd_usb_midi* umidi,
struct
snd_rawmidi
*
rmidi
;
int
err
;
err
=
snd_rawmidi_new
(
umidi
->
c
hip
->
c
ard
,
"USB MIDI"
,
umidi
->
chip
->
next_midi_device
++
,
err
=
snd_rawmidi_new
(
umidi
->
card
,
"USB MIDI"
,
umidi
->
next_midi_device
++
,
out_ports
,
in_ports
,
&
rmidi
);
if
(
err
<
0
)
return
err
;
strcpy
(
rmidi
->
name
,
umidi
->
c
hip
->
c
ard
->
shortname
);
strcpy
(
rmidi
->
name
,
umidi
->
card
->
shortname
);
rmidi
->
info_flags
=
SNDRV_RAWMIDI_INFO_OUTPUT
|
SNDRV_RAWMIDI_INFO_INPUT
|
SNDRV_RAWMIDI_INFO_DUPLEX
;
...
...
@@ -1804,7 +1901,7 @@ static void snd_usbmidi_input_start_ep(struct snd_usb_midi_in_endpoint* ep)
return
;
for
(
i
=
0
;
i
<
INPUT_URBS
;
++
i
)
{
struct
urb
*
urb
=
ep
->
urbs
[
i
];
urb
->
dev
=
ep
->
umidi
->
chip
->
dev
;
urb
->
dev
=
ep
->
umidi
->
dev
;
snd_usbmidi_submit_urb
(
urb
,
GFP_KERNEL
);
}
}
...
...
@@ -1825,8 +1922,9 @@ void snd_usbmidi_input_start(struct list_head* p)
/*
* Creates and registers everything needed for a MIDI streaming interface.
*/
int
snd_usb
_create_midi_interface
(
struct
snd_usb_audio
*
chip
,
int
snd_usb
midi_create
(
struct
snd_card
*
card
,
struct
usb_interface
*
iface
,
struct
list_head
*
midi_list
,
const
struct
snd_usb_audio_quirk
*
quirk
)
{
struct
snd_usb_midi
*
umidi
;
...
...
@@ -1837,12 +1935,16 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
umidi
=
kzalloc
(
sizeof
(
*
umidi
),
GFP_KERNEL
);
if
(
!
umidi
)
return
-
ENOMEM
;
umidi
->
chip
=
chip
;
umidi
->
dev
=
interface_to_usbdev
(
iface
);
umidi
->
card
=
card
;
umidi
->
iface
=
iface
;
umidi
->
quirk
=
quirk
;
umidi
->
usb_protocol_ops
=
&
snd_usbmidi_standard_ops
;
init_timer
(
&
umidi
->
error_timer
);
spin_lock_init
(
&
umidi
->
disc_lock
);
mutex_init
(
&
umidi
->
mutex
);
umidi
->
usb_id
=
USB_ID
(
le16_to_cpu
(
umidi
->
dev
->
descriptor
.
idVendor
),
le16_to_cpu
(
umidi
->
dev
->
descriptor
.
idProduct
));
umidi
->
error_timer
.
function
=
snd_usbmidi_error_timer
;
umidi
->
error_timer
.
data
=
(
unsigned
long
)
umidi
;
...
...
@@ -1851,7 +1953,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
switch
(
quirk
?
quirk
->
type
:
QUIRK_MIDI_STANDARD_INTERFACE
)
{
case
QUIRK_MIDI_STANDARD_INTERFACE
:
err
=
snd_usbmidi_get_ms_info
(
umidi
,
endpoints
);
if
(
chip
->
usb_id
==
USB_ID
(
0x0763
,
0x0150
))
/* M-Audio Uno */
if
(
umidi
->
usb_id
==
USB_ID
(
0x0763
,
0x0150
))
/* M-Audio Uno */
umidi
->
usb_protocol_ops
=
&
snd_usbmidi_maudio_broken_running_status_ops
;
break
;
...
...
@@ -1887,7 +1989,7 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
* interface 0, so we have to make sure that the USB core looks
* again at interface 0 by calling usb_set_interface() on it.
*/
usb_set_interface
(
umidi
->
chip
->
dev
,
0
,
0
);
usb_set_interface
(
umidi
->
dev
,
0
,
0
);
err
=
snd_usbmidi_detect_per_port_endpoints
(
umidi
,
endpoints
);
break
;
case
QUIRK_MIDI_EMAGIC
:
...
...
@@ -1914,8 +2016,8 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
out_ports
=
0
;
in_ports
=
0
;
for
(
i
=
0
;
i
<
MIDI_MAX_ENDPOINTS
;
++
i
)
{
out_ports
+=
snd_usbmidi_count_bits
(
endpoints
[
i
].
out_cables
);
in_ports
+=
snd_usbmidi_count_bits
(
endpoints
[
i
].
in_cables
);
out_ports
+=
hweight16
(
endpoints
[
i
].
out_cables
);
in_ports
+=
hweight16
(
endpoints
[
i
].
in_cables
);
}
err
=
snd_usbmidi_create_rawmidi
(
umidi
,
out_ports
,
in_ports
);
if
(
err
<
0
)
{
...
...
@@ -1933,14 +2035,14 @@ int snd_usb_create_midi_interface(struct snd_usb_audio* chip,
return
err
;
}
list_add
(
&
umidi
->
list
,
&
umidi
->
chip
->
midi_list
);
list_add
_tail
(
&
umidi
->
list
,
midi_list
);
for
(
i
=
0
;
i
<
MIDI_MAX_ENDPOINTS
;
++
i
)
snd_usbmidi_input_start_ep
(
umidi
->
endpoints
[
i
].
in
);
return
0
;
}
EXPORT_SYMBOL
(
snd_usb
_create_midi_interfac
e
);
EXPORT_SYMBOL
(
snd_usb
midi_creat
e
);
EXPORT_SYMBOL
(
snd_usbmidi_input_stop
);
EXPORT_SYMBOL
(
snd_usbmidi_input_start
);
EXPORT_SYMBOL
(
snd_usbmidi_disconnect
);
sound/usb/usbmixer_maps.c
View file @
57648cd5
...
...
@@ -277,6 +277,22 @@ static struct usbmix_name_map scratch_live_map[] = {
{
0
}
/* terminator */
};
/* "Gamesurround Muse Pocket LT" looks same like "Sound Blaster MP3+"
* most importand difference is SU[8], it should be set to "Capture Source"
* to make alsamixer and PA working properly.
* FIXME: or mp3plus_map should use "Capture Source" too,
* so this maps can be merget
*/
static
struct
usbmix_name_map
hercules_usb51_map
[]
=
{
{
8
,
"Capture Source"
},
/* SU, default "PCM Capture Source" */
{
9
,
"Master Playback"
},
/* FU, default "Speaker Playback" */
{
10
,
"Mic Boost"
,
7
},
/* FU, default "Auto Gain Input" */
{
11
,
"Line Capture"
},
/* FU, default "PCM Capture" */
{
13
,
"Mic Bypass Playback"
},
/* FU, default "Mic Playback" */
{
14
,
"Line Bypass Playback"
},
/* FU, default "Line Playback" */
{
0
}
/* terminator */
};
/*
* Control map entries
*/
...
...
@@ -315,6 +331,13 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = {
.
id
=
USB_ID
(
0x06f8
,
0xd002
),
.
ignore_ctl_error
=
1
,
},
{
/* Hercules Gamesurround Muse Pocket LT
* (USB 5.1 Channel Audio Adapter)
*/
.
id
=
USB_ID
(
0x06f8
,
0xc000
),
.
map
=
hercules_usb51_map
,
},
{
.
id
=
USB_ID
(
0x08bb
,
0x2702
),
.
map
=
linex_map
,
...
...
sound/usb/usbquirks.h
View file @
57648cd5
...
...
@@ -1563,6 +1563,29 @@ YAMAHA_DEVICE(0x7010, "UB99"),
}
}
},
{
/* has ID 0x00ea when not in Advanced Driver mode */
USB_DEVICE_VENDOR_SPEC
(
0x0582
,
0x00e9
),
.
driver_info
=
(
unsigned
long
)
&
(
const
struct
snd_usb_audio_quirk
)
{
/* .vendor_name = "Roland", */
/* .product_name = "UA-1G", */
.
ifnum
=
QUIRK_ANY_INTERFACE
,
.
type
=
QUIRK_COMPOSITE
,
.
data
=
(
const
struct
snd_usb_audio_quirk
[])
{
{
.
ifnum
=
0
,
.
type
=
QUIRK_AUDIO_STANDARD_INTERFACE
},
{
.
ifnum
=
1
,
.
type
=
QUIRK_AUDIO_STANDARD_INTERFACE
},
{
.
ifnum
=
-
1
}
}
}
},
/* Guillemot devices */
{
...
...
sound/usb/usx2y/us122l.c
View file @
57648cd5
...
...
@@ -59,11 +59,11 @@ static int us122l_create_usbmidi(struct snd_card *card)
.
type
=
QUIRK_MIDI_US122L
,
.
data
=
&
quirk_data
};
struct
usb_device
*
dev
=
US122L
(
card
)
->
chip
.
dev
;
struct
usb_device
*
dev
=
US122L
(
card
)
->
dev
;
struct
usb_interface
*
iface
=
usb_ifnum_to_if
(
dev
,
1
);
return
snd_usb
_create_midi_interface
(
&
US122L
(
card
)
->
chip
,
iface
,
&
quirk
);
return
snd_usb
midi_create
(
card
,
iface
,
&
US122L
(
card
)
->
midi_list
,
&
quirk
);
}
static
int
us144_create_usbmidi
(
struct
snd_card
*
card
)
...
...
@@ -81,11 +81,11 @@ static int us144_create_usbmidi(struct snd_card *card)
.
type
=
QUIRK_MIDI_US122L
,
.
data
=
&
quirk_data
};
struct
usb_device
*
dev
=
US122L
(
card
)
->
chip
.
dev
;
struct
usb_device
*
dev
=
US122L
(
card
)
->
dev
;
struct
usb_interface
*
iface
=
usb_ifnum_to_if
(
dev
,
0
);
return
snd_usb
_create_midi_interface
(
&
US122L
(
card
)
->
chip
,
iface
,
&
quirk
);
return
snd_usb
midi_create
(
card
,
iface
,
&
US122L
(
card
)
->
midi_list
,
&
quirk
);
}
/*
...
...
@@ -194,11 +194,11 @@ static int usb_stream_hwdep_open(struct snd_hwdep *hw, struct file *file)
if
(
!
us122l
->
first
)
us122l
->
first
=
file
;
if
(
us122l
->
chip
.
dev
->
descriptor
.
idProduct
==
USB_ID_US144
)
{
iface
=
usb_ifnum_to_if
(
us122l
->
chip
.
dev
,
0
);
if
(
us122l
->
dev
->
descriptor
.
idProduct
==
USB_ID_US144
)
{
iface
=
usb_ifnum_to_if
(
us122l
->
dev
,
0
);
usb_autopm_get_interface
(
iface
);
}
iface
=
usb_ifnum_to_if
(
us122l
->
chip
.
dev
,
1
);
iface
=
usb_ifnum_to_if
(
us122l
->
dev
,
1
);
usb_autopm_get_interface
(
iface
);
return
0
;
}
...
...
@@ -209,11 +209,11 @@ static int usb_stream_hwdep_release(struct snd_hwdep *hw, struct file *file)
struct
usb_interface
*
iface
;
snd_printdd
(
KERN_DEBUG
"%p %p
\n
"
,
hw
,
file
);
if
(
us122l
->
chip
.
dev
->
descriptor
.
idProduct
==
USB_ID_US144
)
{
iface
=
usb_ifnum_to_if
(
us122l
->
chip
.
dev
,
0
);
if
(
us122l
->
dev
->
descriptor
.
idProduct
==
USB_ID_US144
)
{
iface
=
usb_ifnum_to_if
(
us122l
->
dev
,
0
);
usb_autopm_put_interface
(
iface
);
}
iface
=
usb_ifnum_to_if
(
us122l
->
chip
.
dev
,
1
);
iface
=
usb_ifnum_to_if
(
us122l
->
dev
,
1
);
usb_autopm_put_interface
(
iface
);
if
(
us122l
->
first
==
file
)
us122l
->
first
=
NULL
;
...
...
@@ -297,7 +297,7 @@ static unsigned int usb_stream_hwdep_poll(struct snd_hwdep *hw,
static
void
us122l_stop
(
struct
us122l
*
us122l
)
{
struct
list_head
*
p
;
list_for_each
(
p
,
&
us122l
->
chip
.
midi_list
)
list_for_each
(
p
,
&
us122l
->
midi_list
)
snd_usbmidi_input_stop
(
p
);
usb_stream_stop
(
&
us122l
->
sk
);
...
...
@@ -330,7 +330,7 @@ static bool us122l_start(struct us122l *us122l,
unsigned
use_packsize
=
0
;
bool
success
=
false
;
if
(
us122l
->
chip
.
dev
->
speed
==
USB_SPEED_HIGH
)
{
if
(
us122l
->
dev
->
speed
==
USB_SPEED_HIGH
)
{
/* The us-122l's descriptor defaults to iso max_packsize 78,
which isn't needed for samplerates <= 48000.
Lets save some memory:
...
...
@@ -347,11 +347,11 @@ static bool us122l_start(struct us122l *us122l,
break
;
}
}
if
(
!
usb_stream_new
(
&
us122l
->
sk
,
us122l
->
chip
.
dev
,
1
,
2
,
if
(
!
usb_stream_new
(
&
us122l
->
sk
,
us122l
->
dev
,
1
,
2
,
rate
,
use_packsize
,
period_frames
,
6
))
goto
out
;
err
=
us122l_set_sample_rate
(
us122l
->
chip
.
dev
,
rate
);
err
=
us122l_set_sample_rate
(
us122l
->
dev
,
rate
);
if
(
err
<
0
)
{
us122l_stop
(
us122l
);
snd_printk
(
KERN_ERR
"us122l_set_sample_rate error
\n
"
);
...
...
@@ -363,7 +363,7 @@ static bool us122l_start(struct us122l *us122l,
snd_printk
(
KERN_ERR
"us122l_start error %i
\n
"
,
err
);
goto
out
;
}
list_for_each
(
p
,
&
us122l
->
chip
.
midi_list
)
list_for_each
(
p
,
&
us122l
->
midi_list
)
snd_usbmidi_input_start
(
p
);
success
=
true
;
out:
...
...
@@ -390,7 +390,7 @@ static int usb_stream_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
err
=
-
ENXIO
;
goto
free
;
}
high_speed
=
us122l
->
chip
.
dev
->
speed
==
USB_SPEED_HIGH
;
high_speed
=
us122l
->
dev
->
speed
==
USB_SPEED_HIGH
;
if
((
cfg
->
sample_rate
!=
44100
&&
cfg
->
sample_rate
!=
48000
&&
(
!
high_speed
||
(
cfg
->
sample_rate
!=
88200
&&
cfg
->
sample_rate
!=
96000
)))
||
...
...
@@ -450,7 +450,7 @@ static int usb_stream_hwdep_new(struct snd_card *card)
{
int
err
;
struct
snd_hwdep
*
hw
;
struct
usb_device
*
dev
=
US122L
(
card
)
->
chip
.
dev
;
struct
usb_device
*
dev
=
US122L
(
card
)
->
dev
;
err
=
snd_hwdep_new
(
card
,
SND_USB_STREAM_ID
,
0
,
&
hw
);
if
(
err
<
0
)
...
...
@@ -476,26 +476,26 @@ static bool us122l_create_card(struct snd_card *card)
int
err
;
struct
us122l
*
us122l
=
US122L
(
card
);
if
(
us122l
->
chip
.
dev
->
descriptor
.
idProduct
==
USB_ID_US144
)
{
err
=
usb_set_interface
(
us122l
->
chip
.
dev
,
0
,
1
);
if
(
us122l
->
dev
->
descriptor
.
idProduct
==
USB_ID_US144
)
{
err
=
usb_set_interface
(
us122l
->
dev
,
0
,
1
);
if
(
err
)
{
snd_printk
(
KERN_ERR
"usb_set_interface error
\n
"
);
return
false
;
}
}
err
=
usb_set_interface
(
us122l
->
chip
.
dev
,
1
,
1
);
err
=
usb_set_interface
(
us122l
->
dev
,
1
,
1
);
if
(
err
)
{
snd_printk
(
KERN_ERR
"usb_set_interface error
\n
"
);
return
false
;
}
pt_info_set
(
us122l
->
chip
.
dev
,
0x11
);
pt_info_set
(
us122l
->
chip
.
dev
,
0x10
);
pt_info_set
(
us122l
->
dev
,
0x11
);
pt_info_set
(
us122l
->
dev
,
0x10
);
if
(
!
us122l_start
(
us122l
,
44100
,
256
))
return
false
;
if
(
us122l
->
chip
.
dev
->
descriptor
.
idProduct
==
USB_ID_US144
)
if
(
us122l
->
dev
->
descriptor
.
idProduct
==
USB_ID_US144
)
err
=
us144_create_usbmidi
(
card
);
else
err
=
us122l_create_usbmidi
(
card
);
...
...
@@ -508,7 +508,7 @@ static bool us122l_create_card(struct snd_card *card)
if
(
err
<
0
)
{
/* release the midi resources */
struct
list_head
*
p
;
list_for_each
(
p
,
&
us122l
->
chip
.
midi_list
)
list_for_each
(
p
,
&
us122l
->
midi_list
)
snd_usbmidi_disconnect
(
p
);
us122l_stop
(
us122l
);
...
...
@@ -520,7 +520,7 @@ static bool us122l_create_card(struct snd_card *card)
static
void
snd_us122l_free
(
struct
snd_card
*
card
)
{
struct
us122l
*
us122l
=
US122L
(
card
);
int
index
=
us122l
->
c
hip
.
index
;
int
index
=
us122l
->
c
ard_
index
;
if
(
index
>=
0
&&
index
<
SNDRV_CARDS
)
snd_us122l_card_used
[
index
]
=
0
;
}
...
...
@@ -540,13 +540,12 @@ static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)
sizeof
(
struct
us122l
),
&
card
);
if
(
err
<
0
)
return
err
;
snd_us122l_card_used
[
US122L
(
card
)
->
c
hip
.
index
=
dev
]
=
1
;
snd_us122l_card_used
[
US122L
(
card
)
->
c
ard_
index
=
dev
]
=
1
;
card
->
private_free
=
snd_us122l_free
;
US122L
(
card
)
->
chip
.
dev
=
device
;
US122L
(
card
)
->
chip
.
card
=
card
;
US122L
(
card
)
->
dev
=
device
;
mutex_init
(
&
US122L
(
card
)
->
mutex
);
init_waitqueue_head
(
&
US122L
(
card
)
->
sk
.
sleep
);
INIT_LIST_HEAD
(
&
US122L
(
card
)
->
chip
.
midi_list
);
INIT_LIST_HEAD
(
&
US122L
(
card
)
->
midi_list
);
strcpy
(
card
->
driver
,
"USB "
NAME_ALLCAPS
""
);
sprintf
(
card
->
shortname
,
"TASCAM "
NAME_ALLCAPS
""
);
sprintf
(
card
->
longname
,
"%s (%x:%x if %d at %03d/%03d)"
,
...
...
@@ -554,8 +553,8 @@ static int usx2y_create_card(struct usb_device *device, struct snd_card **cardp)
le16_to_cpu
(
device
->
descriptor
.
idVendor
),
le16_to_cpu
(
device
->
descriptor
.
idProduct
),
0
,
US122L
(
card
)
->
chip
.
dev
->
bus
->
busnum
,
US122L
(
card
)
->
chip
.
dev
->
devnum
US122L
(
card
)
->
dev
->
bus
->
busnum
,
US122L
(
card
)
->
dev
->
devnum
);
*
cardp
=
card
;
return
0
;
...
...
@@ -635,16 +634,15 @@ static void snd_us122l_disconnect(struct usb_interface *intf)
mutex_lock
(
&
us122l
->
mutex
);
us122l_stop
(
us122l
);
mutex_unlock
(
&
us122l
->
mutex
);
us122l
->
chip
.
shutdown
=
1
;
/* release the midi resources */
list_for_each
(
p
,
&
us122l
->
chip
.
midi_list
)
{
list_for_each
(
p
,
&
us122l
->
midi_list
)
{
snd_usbmidi_disconnect
(
p
);
}
usb_put_intf
(
usb_ifnum_to_if
(
us122l
->
chip
.
dev
,
0
));
usb_put_intf
(
usb_ifnum_to_if
(
us122l
->
chip
.
dev
,
1
));
usb_put_dev
(
us122l
->
chip
.
dev
);
usb_put_intf
(
usb_ifnum_to_if
(
us122l
->
dev
,
0
));
usb_put_intf
(
usb_ifnum_to_if
(
us122l
->
dev
,
1
));
usb_put_dev
(
us122l
->
dev
);
while
(
atomic_read
(
&
us122l
->
mmap_count
))
msleep
(
500
);
...
...
@@ -667,7 +665,7 @@ static int snd_us122l_suspend(struct usb_interface *intf, pm_message_t message)
if
(
!
us122l
)
return
0
;
list_for_each
(
p
,
&
us122l
->
chip
.
midi_list
)
list_for_each
(
p
,
&
us122l
->
midi_list
)
snd_usbmidi_input_stop
(
p
);
mutex_lock
(
&
us122l
->
mutex
);
...
...
@@ -694,23 +692,23 @@ static int snd_us122l_resume(struct usb_interface *intf)
mutex_lock
(
&
us122l
->
mutex
);
/* needed, doesn't restart without: */
if
(
us122l
->
chip
.
dev
->
descriptor
.
idProduct
==
USB_ID_US144
)
{
err
=
usb_set_interface
(
us122l
->
chip
.
dev
,
0
,
1
);
if
(
us122l
->
dev
->
descriptor
.
idProduct
==
USB_ID_US144
)
{
err
=
usb_set_interface
(
us122l
->
dev
,
0
,
1
);
if
(
err
)
{
snd_printk
(
KERN_ERR
"usb_set_interface error
\n
"
);
goto
unlock
;
}
}
err
=
usb_set_interface
(
us122l
->
chip
.
dev
,
1
,
1
);
err
=
usb_set_interface
(
us122l
->
dev
,
1
,
1
);
if
(
err
)
{
snd_printk
(
KERN_ERR
"usb_set_interface error
\n
"
);
goto
unlock
;
}
pt_info_set
(
us122l
->
chip
.
dev
,
0x11
);
pt_info_set
(
us122l
->
chip
.
dev
,
0x10
);
pt_info_set
(
us122l
->
dev
,
0x11
);
pt_info_set
(
us122l
->
dev
,
0x10
);
err
=
us122l_set_sample_rate
(
us122l
->
chip
.
dev
,
err
=
us122l_set_sample_rate
(
us122l
->
dev
,
us122l
->
sk
.
s
->
cfg
.
sample_rate
);
if
(
err
<
0
)
{
snd_printk
(
KERN_ERR
"us122l_set_sample_rate error
\n
"
);
...
...
@@ -720,7 +718,7 @@ static int snd_us122l_resume(struct usb_interface *intf)
if
(
err
)
goto
unlock
;
list_for_each
(
p
,
&
us122l
->
chip
.
midi_list
)
list_for_each
(
p
,
&
us122l
->
midi_list
)
snd_usbmidi_input_start
(
p
);
unlock:
mutex_unlock
(
&
us122l
->
mutex
);
...
...
sound/usb/usx2y/us122l.h
View file @
57648cd5
...
...
@@ -3,7 +3,8 @@
struct
us122l
{
struct
snd_usb_audio
chip
;
struct
usb_device
*
dev
;
int
card_index
;
int
stride
;
struct
usb_stream_kernel
sk
;
...
...
@@ -12,6 +13,7 @@ struct us122l {
unsigned
second_periods_polled
;
struct
file
*
master
;
struct
file
*
slave
;
struct
list_head
midi_list
;
atomic_t
mmap_count
;
};
...
...
sound/usb/usx2y/usX2Yhwdep.c
View file @
57648cd5
...
...
@@ -114,7 +114,7 @@ static int snd_usX2Y_hwdep_dsp_status(struct snd_hwdep *hw,
struct
usX2Ydev
*
us428
=
hw
->
private_data
;
int
id
=
-
1
;
switch
(
le16_to_cpu
(
us428
->
chip
.
dev
->
descriptor
.
idProduct
))
{
switch
(
le16_to_cpu
(
us428
->
dev
->
descriptor
.
idProduct
))
{
case
USB_ID_US122
:
id
=
USX2Y_TYPE_122
;
break
;
...
...
@@ -164,14 +164,14 @@ static int usX2Y_create_usbmidi(struct snd_card *card)
.
type
=
QUIRK_MIDI_FIXED_ENDPOINT
,
.
data
=
&
quirk_data_2
};
struct
usb_device
*
dev
=
usX2Y
(
card
)
->
chip
.
dev
;
struct
usb_device
*
dev
=
usX2Y
(
card
)
->
dev
;
struct
usb_interface
*
iface
=
usb_ifnum_to_if
(
dev
,
0
);
struct
snd_usb_audio_quirk
*
quirk
=
le16_to_cpu
(
dev
->
descriptor
.
idProduct
)
==
USB_ID_US428
?
&
quirk_2
:
&
quirk_1
;
snd_printdd
(
"usX2Y_create_usbmidi
\n
"
);
return
snd_usb
_create_midi_interface
(
&
usX2Y
(
card
)
->
chip
,
iface
,
quirk
);
return
snd_usb
midi_create
(
card
,
iface
,
&
usX2Y
(
card
)
->
midi_list
,
quirk
);
}
static
int
usX2Y_create_alsa_devices
(
struct
snd_card
*
card
)
...
...
@@ -202,7 +202,7 @@ static int snd_usX2Y_hwdep_dsp_load(struct snd_hwdep *hw,
snd_printdd
(
"dsp_load %s
\n
"
,
dsp
->
name
);
if
(
access_ok
(
VERIFY_READ
,
dsp
->
image
,
dsp
->
length
))
{
struct
usb_device
*
dev
=
priv
->
chip
.
dev
;
struct
usb_device
*
dev
=
priv
->
dev
;
char
*
buf
;
buf
=
memdup_user
(
dsp
->
image
,
dsp
->
length
);
...
...
sound/usb/usx2y/usbusx2y.c
View file @
57648cd5
...
...
@@ -239,8 +239,8 @@ static void i_usX2Y_In04Int(struct urb *urb)
for
(
j
=
0
;
j
<
URBS_AsyncSeq
&&
!
err
;
++
j
)
if
(
0
==
usX2Y
->
AS04
.
urb
[
j
]
->
status
)
{
struct
us428_p4out
*
p4out
=
us428ctls
->
p4out
+
send
;
// FIXME if more than 1 p4out is new, 1 gets lost.
usb_fill_bulk_urb
(
usX2Y
->
AS04
.
urb
[
j
],
usX2Y
->
chip
.
dev
,
usb_sndbulkpipe
(
usX2Y
->
chip
.
dev
,
0x04
),
&
p4out
->
val
.
vol
,
usb_fill_bulk_urb
(
usX2Y
->
AS04
.
urb
[
j
],
usX2Y
->
dev
,
usb_sndbulkpipe
(
usX2Y
->
dev
,
0x04
),
&
p4out
->
val
.
vol
,
p4out
->
type
==
eLT_Light
?
sizeof
(
struct
us428_lights
)
:
5
,
i_usX2Y_Out04Int
,
usX2Y
);
err
=
usb_submit_urb
(
usX2Y
->
AS04
.
urb
[
j
],
GFP_ATOMIC
);
...
...
@@ -253,7 +253,7 @@ static void i_usX2Y_In04Int(struct urb *urb)
if
(
err
)
snd_printk
(
KERN_ERR
"In04Int() usb_submit_urb err=%i
\n
"
,
err
);
urb
->
dev
=
usX2Y
->
chip
.
dev
;
urb
->
dev
=
usX2Y
->
dev
;
usb_submit_urb
(
urb
,
GFP_ATOMIC
);
}
...
...
@@ -273,8 +273,8 @@ int usX2Y_AsyncSeq04_init(struct usX2Ydev *usX2Y)
err
=
-
ENOMEM
;
break
;
}
usb_fill_bulk_urb
(
usX2Y
->
AS04
.
urb
[
i
],
usX2Y
->
chip
.
dev
,
usb_sndbulkpipe
(
usX2Y
->
chip
.
dev
,
0x04
),
usb_fill_bulk_urb
(
usX2Y
->
AS04
.
urb
[
i
],
usX2Y
->
dev
,
usb_sndbulkpipe
(
usX2Y
->
dev
,
0x04
),
usX2Y
->
AS04
.
buffer
+
URB_DataLen_AsyncSeq
*
i
,
0
,
i_usX2Y_Out04Int
,
usX2Y
);
...
...
@@ -293,7 +293,7 @@ int usX2Y_In04_init(struct usX2Ydev *usX2Y)
}
init_waitqueue_head
(
&
usX2Y
->
In04WaitQueue
);
usb_fill_int_urb
(
usX2Y
->
In04urb
,
usX2Y
->
chip
.
dev
,
usb_rcvintpipe
(
usX2Y
->
chip
.
dev
,
0x4
),
usb_fill_int_urb
(
usX2Y
->
In04urb
,
usX2Y
->
dev
,
usb_rcvintpipe
(
usX2Y
->
dev
,
0x4
),
usX2Y
->
In04Buf
,
21
,
i_usX2Y_In04Int
,
usX2Y
,
10
);
...
...
@@ -348,13 +348,12 @@ static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp)
sizeof
(
struct
usX2Ydev
),
&
card
);
if
(
err
<
0
)
return
err
;
snd_usX2Y_card_used
[
usX2Y
(
card
)
->
c
hip
.
index
=
dev
]
=
1
;
snd_usX2Y_card_used
[
usX2Y
(
card
)
->
c
ard_
index
=
dev
]
=
1
;
card
->
private_free
=
snd_usX2Y_card_private_free
;
usX2Y
(
card
)
->
chip
.
dev
=
device
;
usX2Y
(
card
)
->
chip
.
card
=
card
;
usX2Y
(
card
)
->
dev
=
device
;
init_waitqueue_head
(
&
usX2Y
(
card
)
->
prepare_wait_queue
);
mutex_init
(
&
usX2Y
(
card
)
->
prepare_mutex
);
INIT_LIST_HEAD
(
&
usX2Y
(
card
)
->
chip
.
midi_list
);
INIT_LIST_HEAD
(
&
usX2Y
(
card
)
->
midi_list
);
strcpy
(
card
->
driver
,
"USB "
NAME_ALLCAPS
""
);
sprintf
(
card
->
shortname
,
"TASCAM "
NAME_ALLCAPS
""
);
sprintf
(
card
->
longname
,
"%s (%x:%x if %d at %03d/%03d)"
,
...
...
@@ -362,7 +361,7 @@ static int usX2Y_create_card(struct usb_device *device, struct snd_card **cardp)
le16_to_cpu
(
device
->
descriptor
.
idVendor
),
le16_to_cpu
(
device
->
descriptor
.
idProduct
),
0
,
//us428(card)->usbmidi.ifnum,
usX2Y
(
card
)
->
chip
.
dev
->
bus
->
busnum
,
usX2Y
(
card
)
->
chip
.
dev
->
devnum
usX2Y
(
card
)
->
dev
->
bus
->
busnum
,
usX2Y
(
card
)
->
dev
->
devnum
);
*
cardp
=
card
;
return
0
;
...
...
@@ -432,8 +431,8 @@ static void snd_usX2Y_card_private_free(struct snd_card *card)
usb_free_urb
(
usX2Y
(
card
)
->
In04urb
);
if
(
usX2Y
(
card
)
->
us428ctls_sharedmem
)
snd_free_pages
(
usX2Y
(
card
)
->
us428ctls_sharedmem
,
sizeof
(
*
usX2Y
(
card
)
->
us428ctls_sharedmem
));
if
(
usX2Y
(
card
)
->
c
hip
.
index
>=
0
&&
usX2Y
(
card
)
->
chip
.
index
<
SNDRV_CARDS
)
snd_usX2Y_card_used
[
usX2Y
(
card
)
->
c
hip
.
index
]
=
0
;
if
(
usX2Y
(
card
)
->
c
ard_index
>=
0
&&
usX2Y
(
card
)
->
card_
index
<
SNDRV_CARDS
)
snd_usX2Y_card_used
[
usX2Y
(
card
)
->
c
ard_
index
]
=
0
;
}
/*
...
...
@@ -445,13 +444,12 @@ static void usX2Y_usb_disconnect(struct usb_device *device, void* ptr)
struct
snd_card
*
card
=
ptr
;
struct
usX2Ydev
*
usX2Y
=
usX2Y
(
card
);
struct
list_head
*
p
;
usX2Y
->
chip
.
shutdown
=
1
;
usX2Y
->
chip_status
=
USX2Y_STAT_CHIP_HUP
;
usX2Y_unlinkSeq
(
&
usX2Y
->
AS04
);
usb_kill_urb
(
usX2Y
->
In04urb
);
snd_card_disconnect
(
card
);
/* release the midi resources */
list_for_each
(
p
,
&
usX2Y
->
chip
.
midi_list
)
{
list_for_each
(
p
,
&
usX2Y
->
midi_list
)
{
snd_usbmidi_disconnect
(
p
);
}
if
(
usX2Y
->
us428ctls_sharedmem
)
...
...
sound/usb/usx2y/usbusx2y.h
View file @
57648cd5
...
...
@@ -22,7 +22,8 @@ struct snd_usX2Y_urbSeq {
#include "usx2yhwdeppcm.h"
struct
usX2Ydev
{
struct
snd_usb_audio
chip
;
struct
usb_device
*
dev
;
int
card_index
;
int
stride
;
struct
urb
*
In04urb
;
void
*
In04Buf
;
...
...
@@ -42,6 +43,9 @@ struct usX2Ydev {
struct
snd_usX2Y_substream
*
subs
[
4
];
struct
snd_usX2Y_substream
*
volatile
prepare_subs
;
wait_queue_head_t
prepare_wait_queue
;
struct
list_head
midi_list
;
struct
list_head
pcm_list
;
int
pcm_devs
;
};
...
...
sound/usb/usx2y/usbusx2yaudio.c
View file @
57648cd5
...
...
@@ -199,7 +199,7 @@ static int usX2Y_urb_submit(struct snd_usX2Y_substream *subs, struct urb *urb, i
return
-
ENODEV
;
urb
->
start_frame
=
(
frame
+
NRURBS
*
nr_of_packs
());
// let hcd do rollover sanity checks
urb
->
hcpriv
=
NULL
;
urb
->
dev
=
subs
->
usX2Y
->
chip
.
dev
;
/* we need to set this at each time */
urb
->
dev
=
subs
->
usX2Y
->
dev
;
/* we need to set this at each time */
if
((
err
=
usb_submit_urb
(
urb
,
GFP_ATOMIC
))
<
0
)
{
snd_printk
(
KERN_ERR
"usb_submit_urb() returned %i
\n
"
,
err
);
return
err
;
...
...
@@ -300,7 +300,7 @@ static void usX2Y_error_sequence(struct usX2Ydev *usX2Y,
"Sequence Error!(hcd_frame=%i ep=%i%s;wait=%i,frame=%i).
\n
"
"Most propably some urb of usb-frame %i is still missing.
\n
"
"Cause could be too long delays in usb-hcd interrupt handling.
\n
"
,
usb_get_current_frame_number
(
usX2Y
->
chip
.
dev
),
usb_get_current_frame_number
(
usX2Y
->
dev
),
subs
->
endpoint
,
usb_pipein
(
urb
->
pipe
)
?
"in"
:
"out"
,
usX2Y
->
wait_iso_frame
,
urb
->
start_frame
,
usX2Y
->
wait_iso_frame
);
usX2Y_clients_stop
(
usX2Y
);
...
...
@@ -313,7 +313,7 @@ static void i_usX2Y_urb_complete(struct urb *urb)
if
(
unlikely
(
atomic_read
(
&
subs
->
state
)
<
state_PREPARED
))
{
snd_printdd
(
"hcd_frame=%i ep=%i%s status=%i start_frame=%i
\n
"
,
usb_get_current_frame_number
(
usX2Y
->
chip
.
dev
),
usb_get_current_frame_number
(
usX2Y
->
dev
),
subs
->
endpoint
,
usb_pipein
(
urb
->
pipe
)
?
"in"
:
"out"
,
urb
->
status
,
urb
->
start_frame
);
return
;
...
...
@@ -424,7 +424,7 @@ static int usX2Y_urbs_allocate(struct snd_usX2Y_substream *subs)
int
i
;
unsigned
int
pipe
;
int
is_playback
=
subs
==
subs
->
usX2Y
->
subs
[
SNDRV_PCM_STREAM_PLAYBACK
];
struct
usb_device
*
dev
=
subs
->
usX2Y
->
chip
.
dev
;
struct
usb_device
*
dev
=
subs
->
usX2Y
->
dev
;
pipe
=
is_playback
?
usb_sndisocpipe
(
dev
,
subs
->
endpoint
)
:
usb_rcvisocpipe
(
dev
,
subs
->
endpoint
);
...
...
@@ -500,7 +500,7 @@ static int usX2Y_urbs_start(struct snd_usX2Y_substream *subs)
unsigned
long
pack
;
if
(
0
==
i
)
atomic_set
(
&
subs
->
state
,
state_STARTING3
);
urb
->
dev
=
usX2Y
->
chip
.
dev
;
urb
->
dev
=
usX2Y
->
dev
;
urb
->
transfer_flags
=
URB_ISO_ASAP
;
for
(
pack
=
0
;
pack
<
nr_of_packs
();
pack
++
)
{
urb
->
iso_frame_desc
[
pack
].
offset
=
subs
->
maxpacksize
*
pack
;
...
...
@@ -692,7 +692,7 @@ static int usX2Y_rate_set(struct usX2Ydev *usX2Y, int rate)
}
((
char
*
)(
usbdata
+
i
))[
0
]
=
ra
[
i
].
c1
;
((
char
*
)(
usbdata
+
i
))[
1
]
=
ra
[
i
].
c2
;
usb_fill_bulk_urb
(
us
->
urb
[
i
],
usX2Y
->
chip
.
dev
,
usb_sndbulkpipe
(
usX2Y
->
chip
.
dev
,
4
),
usb_fill_bulk_urb
(
us
->
urb
[
i
],
usX2Y
->
dev
,
usb_sndbulkpipe
(
usX2Y
->
dev
,
4
),
usbdata
+
i
,
2
,
i_usX2Y_04Int
,
usX2Y
);
#ifdef OLD_USB
us
->
urb
[
i
]
->
transfer_flags
=
USB_QUEUE_BULK
;
...
...
@@ -740,17 +740,17 @@ static int usX2Y_format_set(struct usX2Ydev *usX2Y, snd_pcm_format_t format)
alternate
=
1
;
usX2Y
->
stride
=
4
;
}
list_for_each
(
p
,
&
usX2Y
->
chip
.
midi_list
)
{
list_for_each
(
p
,
&
usX2Y
->
midi_list
)
{
snd_usbmidi_input_stop
(
p
);
}
usb_kill_urb
(
usX2Y
->
In04urb
);
if
((
err
=
usb_set_interface
(
usX2Y
->
chip
.
dev
,
0
,
alternate
)))
{
if
((
err
=
usb_set_interface
(
usX2Y
->
dev
,
0
,
alternate
)))
{
snd_printk
(
KERN_ERR
"usb_set_interface error
\n
"
);
return
err
;
}
usX2Y
->
In04urb
->
dev
=
usX2Y
->
chip
.
dev
;
usX2Y
->
In04urb
->
dev
=
usX2Y
->
dev
;
err
=
usb_submit_urb
(
usX2Y
->
In04urb
,
GFP_KERNEL
);
list_for_each
(
p
,
&
usX2Y
->
chip
.
midi_list
)
{
list_for_each
(
p
,
&
usX2Y
->
midi_list
)
{
snd_usbmidi_input_start
(
p
);
}
usX2Y
->
format
=
format
;
...
...
@@ -955,7 +955,7 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint,
struct
snd_pcm
*
pcm
;
int
err
,
i
;
struct
snd_usX2Y_substream
**
usX2Y_substream
=
usX2Y
(
card
)
->
subs
+
2
*
usX2Y
(
card
)
->
chip
.
pcm_devs
;
usX2Y
(
card
)
->
subs
+
2
*
usX2Y
(
card
)
->
pcm_devs
;
for
(
i
=
playback_endpoint
?
SNDRV_PCM_STREAM_PLAYBACK
:
SNDRV_PCM_STREAM_CAPTURE
;
i
<=
SNDRV_PCM_STREAM_CAPTURE
;
++
i
)
{
...
...
@@ -971,7 +971,7 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint,
usX2Y_substream
[
SNDRV_PCM_STREAM_PLAYBACK
]
->
endpoint
=
playback_endpoint
;
usX2Y_substream
[
SNDRV_PCM_STREAM_CAPTURE
]
->
endpoint
=
capture_endpoint
;
err
=
snd_pcm_new
(
card
,
NAME_ALLCAPS
" Audio"
,
usX2Y
(
card
)
->
chip
.
pcm_devs
,
err
=
snd_pcm_new
(
card
,
NAME_ALLCAPS
" Audio"
,
usX2Y
(
card
)
->
pcm_devs
,
playback_endpoint
?
1
:
0
,
1
,
&
pcm
);
if
(
err
<
0
)
{
...
...
@@ -987,7 +987,7 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint,
pcm
->
private_free
=
snd_usX2Y_pcm_private_free
;
pcm
->
info_flags
=
0
;
sprintf
(
pcm
->
name
,
NAME_ALLCAPS
" Audio #%d"
,
usX2Y
(
card
)
->
chip
.
pcm_devs
);
sprintf
(
pcm
->
name
,
NAME_ALLCAPS
" Audio #%d"
,
usX2Y
(
card
)
->
pcm_devs
);
if
((
playback_endpoint
&&
0
>
(
err
=
snd_pcm_lib_preallocate_pages
(
pcm
->
streams
[
SNDRV_PCM_STREAM_PLAYBACK
].
substream
,
...
...
@@ -1001,7 +1001,7 @@ static int usX2Y_audio_stream_new(struct snd_card *card, int playback_endpoint,
snd_usX2Y_pcm_private_free
(
pcm
);
return
err
;
}
usX2Y
(
card
)
->
chip
.
pcm_devs
++
;
usX2Y
(
card
)
->
pcm_devs
++
;
return
0
;
}
...
...
@@ -1013,14 +1013,14 @@ int usX2Y_audio_create(struct snd_card *card)
{
int
err
=
0
;
INIT_LIST_HEAD
(
&
usX2Y
(
card
)
->
chip
.
pcm_list
);
INIT_LIST_HEAD
(
&
usX2Y
(
card
)
->
pcm_list
);
if
(
0
>
(
err
=
usX2Y_audio_stream_new
(
card
,
0xA
,
0x8
)))
return
err
;
if
(
le16_to_cpu
(
usX2Y
(
card
)
->
chip
.
dev
->
descriptor
.
idProduct
)
==
USB_ID_US428
)
if
(
le16_to_cpu
(
usX2Y
(
card
)
->
dev
->
descriptor
.
idProduct
)
==
USB_ID_US428
)
if
(
0
>
(
err
=
usX2Y_audio_stream_new
(
card
,
0
,
0xA
)))
return
err
;
if
(
le16_to_cpu
(
usX2Y
(
card
)
->
chip
.
dev
->
descriptor
.
idProduct
)
!=
USB_ID_US122
)
if
(
le16_to_cpu
(
usX2Y
(
card
)
->
dev
->
descriptor
.
idProduct
)
!=
USB_ID_US122
)
err
=
usX2Y_rate_set
(
usX2Y
(
card
),
44100
);
// Lets us428 recognize output-volume settings, disturbs us122.
return
err
;
}
sound/usb/usx2y/usx2yhwdeppcm.c
View file @
57648cd5
...
...
@@ -234,7 +234,7 @@ static void i_usX2Y_usbpcm_urb_complete(struct urb *urb)
if
(
unlikely
(
atomic_read
(
&
subs
->
state
)
<
state_PREPARED
))
{
snd_printdd
(
"hcd_frame=%i ep=%i%s status=%i start_frame=%i
\n
"
,
usb_get_current_frame_number
(
usX2Y
->
chip
.
dev
),
usb_get_current_frame_number
(
usX2Y
->
dev
),
subs
->
endpoint
,
usb_pipein
(
urb
->
pipe
)
?
"in"
:
"out"
,
urb
->
status
,
urb
->
start_frame
);
return
;
...
...
@@ -318,7 +318,7 @@ static int usX2Y_usbpcm_urbs_allocate(struct snd_usX2Y_substream *subs)
int
i
;
unsigned
int
pipe
;
int
is_playback
=
subs
==
subs
->
usX2Y
->
subs
[
SNDRV_PCM_STREAM_PLAYBACK
];
struct
usb_device
*
dev
=
subs
->
usX2Y
->
chip
.
dev
;
struct
usb_device
*
dev
=
subs
->
usX2Y
->
dev
;
pipe
=
is_playback
?
usb_sndisocpipe
(
dev
,
subs
->
endpoint
)
:
usb_rcvisocpipe
(
dev
,
subs
->
endpoint
);
...
...
@@ -441,7 +441,7 @@ static int usX2Y_usbpcm_urbs_start(struct snd_usX2Y_substream *subs)
unsigned
long
pack
;
if
(
0
==
u
)
atomic_set
(
&
subs
->
state
,
state_STARTING3
);
urb
->
dev
=
usX2Y
->
chip
.
dev
;
urb
->
dev
=
usX2Y
->
dev
;
urb
->
transfer_flags
=
URB_ISO_ASAP
;
for
(
pack
=
0
;
pack
<
nr_of_packs
();
pack
++
)
{
urb
->
iso_frame_desc
[
pack
].
offset
=
subs
->
maxpacksize
*
(
pack
+
u
*
nr_of_packs
());
...
...
@@ -741,7 +741,7 @@ int usX2Y_hwdep_pcm_new(struct snd_card *card)
int
err
;
struct
snd_hwdep
*
hw
;
struct
snd_pcm
*
pcm
;
struct
usb_device
*
dev
=
usX2Y
(
card
)
->
chip
.
dev
;
struct
usb_device
*
dev
=
usX2Y
(
card
)
->
dev
;
if
(
1
!=
nr_of_packs
())
return
0
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment