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
nexedi
linux
Commits
6bcdbd55
Commit
6bcdbd55
authored
Dec 20, 2008
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/ca0106-resume' into topic/ca0106
parents
6a843641
72077aa3
Changes
3
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
456 additions
and
269 deletions
+456
-269
sound/pci/ca0106/ca0106.h
sound/pci/ca0106/ca0106.h
+14
-1
sound/pci/ca0106/ca0106_main.c
sound/pci/ca0106/ca0106_main.c
+312
-216
sound/pci/ca0106/ca0106_mixer.c
sound/pci/ca0106/ca0106_mixer.c
+130
-52
No files found.
sound/pci/ca0106/ca0106.h
View file @
6bcdbd55
...
...
@@ -690,7 +690,7 @@ struct snd_ca0106 {
spinlock_t
emu_lock
;
struct
snd_ac97
*
ac97
;
struct
snd_pcm
*
pcm
;
struct
snd_pcm
*
pcm
[
4
]
;
struct
snd_ca0106_channel
playback_channels
[
4
];
struct
snd_ca0106_channel
capture_channels
[
4
];
...
...
@@ -707,6 +707,11 @@ struct snd_ca0106 {
struct
snd_ca_midi
midi2
;
u16
spi_dac_reg
[
16
];
#ifdef CONFIG_PM
#define NUM_SAVED_VOLUMES 9
unsigned
int
saved_vol
[
NUM_SAVED_VOLUMES
];
#endif
};
int
snd_ca0106_mixer
(
struct
snd_ca0106
*
emu
);
...
...
@@ -725,3 +730,11 @@ int snd_ca0106_i2c_write(struct snd_ca0106 *emu, u32 reg, u32 value);
int
snd_ca0106_spi_write
(
struct
snd_ca0106
*
emu
,
unsigned
int
data
);
#ifdef CONFIG_PM
void
snd_ca0106_mixer_suspend
(
struct
snd_ca0106
*
chip
);
void
snd_ca0106_mixer_resume
(
struct
snd_ca0106
*
chip
);
#else
#define snd_ca0106_mixer_suspend(chip) do { } while (0)
#define snd_ca0106_mixer_resume(chip) do { } while (0)
#endif
sound/pci/ca0106/ca0106_main.c
View file @
6bcdbd55
This diff is collapsed.
Click to expand it.
sound/pci/ca0106/ca0106_mixer.c
View file @
6bcdbd55
...
...
@@ -75,6 +75,84 @@
#include "ca0106.h"
static
void
ca0106_spdif_enable
(
struct
snd_ca0106
*
emu
)
{
unsigned
int
val
;
if
(
emu
->
spdif_enable
)
{
/* Digital */
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT1
,
0
,
0xf
);
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT2
,
0
,
0x0b000000
);
val
=
snd_ca0106_ptr_read
(
emu
,
CAPTURE_CONTROL
,
0
)
&
~
0x1000
;
snd_ca0106_ptr_write
(
emu
,
CAPTURE_CONTROL
,
0
,
val
);
val
=
inl
(
emu
->
port
+
GPIO
)
&
~
0x101
;
outl
(
val
,
emu
->
port
+
GPIO
);
}
else
{
/* Analog */
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT1
,
0
,
0xf
);
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT2
,
0
,
0x000f0000
);
val
=
snd_ca0106_ptr_read
(
emu
,
CAPTURE_CONTROL
,
0
)
|
0x1000
;
snd_ca0106_ptr_write
(
emu
,
CAPTURE_CONTROL
,
0
,
val
);
val
=
inl
(
emu
->
port
+
GPIO
)
|
0x101
;
outl
(
val
,
emu
->
port
+
GPIO
);
}
}
static
void
ca0106_set_capture_source
(
struct
snd_ca0106
*
emu
)
{
unsigned
int
val
=
emu
->
capture_source
;
unsigned
int
source
,
mask
;
source
=
(
val
<<
28
)
|
(
val
<<
24
)
|
(
val
<<
20
)
|
(
val
<<
16
);
mask
=
snd_ca0106_ptr_read
(
emu
,
CAPTURE_SOURCE
,
0
)
&
0xffff
;
snd_ca0106_ptr_write
(
emu
,
CAPTURE_SOURCE
,
0
,
source
|
mask
);
}
static
void
ca0106_set_i2c_capture_source
(
struct
snd_ca0106
*
emu
,
unsigned
int
val
,
int
force
)
{
unsigned
int
ngain
,
ogain
;
u32
source
;
snd_ca0106_i2c_write
(
emu
,
ADC_MUX
,
0
);
/* Mute input */
ngain
=
emu
->
i2c_capture_volume
[
val
][
0
];
/* Left */
ogain
=
emu
->
i2c_capture_volume
[
emu
->
i2c_capture_source
][
0
];
/* Left */
if
(
force
||
ngain
!=
ogain
)
snd_ca0106_i2c_write
(
emu
,
ADC_ATTEN_ADCL
,
ngain
&
0xff
);
ngain
=
emu
->
i2c_capture_volume
[
val
][
1
];
/* Right */
ogain
=
emu
->
i2c_capture_volume
[
emu
->
i2c_capture_source
][
1
];
/* Right */
if
(
force
||
ngain
!=
ogain
)
snd_ca0106_i2c_write
(
emu
,
ADC_ATTEN_ADCR
,
ngain
&
0xff
);
source
=
1
<<
val
;
snd_ca0106_i2c_write
(
emu
,
ADC_MUX
,
source
);
/* Set source */
emu
->
i2c_capture_source
=
val
;
}
static
void
ca0106_set_capture_mic_line_in
(
struct
snd_ca0106
*
emu
)
{
u32
tmp
;
if
(
emu
->
capture_mic_line_in
)
{
/* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */
/* Mute input */
tmp
=
inl
(
emu
->
port
+
GPIO
)
&
~
0x400
;
tmp
=
tmp
|
0x400
;
outl
(
tmp
,
emu
->
port
+
GPIO
);
/* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC); */
}
else
{
/* snd_ca0106_i2c_write(emu, ADC_MUX, 0); */
/* Mute input */
tmp
=
inl
(
emu
->
port
+
GPIO
)
&
~
0x400
;
outl
(
tmp
,
emu
->
port
+
GPIO
);
/* snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN); */
}
}
static
void
ca0106_set_spdif_bits
(
struct
snd_ca0106
*
emu
,
int
idx
)
{
snd_ca0106_ptr_write
(
emu
,
SPCS0
+
idx
,
0
,
emu
->
spdif_bits
[
idx
]);
}
/*
*/
static
const
DECLARE_TLV_DB_SCALE
(
snd_ca0106_db_scale1
,
-
5175
,
25
,
1
);
static
const
DECLARE_TLV_DB_SCALE
(
snd_ca0106_db_scale2
,
-
10350
,
50
,
1
);
...
...
@@ -95,30 +173,12 @@ static int snd_ca0106_shared_spdif_put(struct snd_kcontrol *kcontrol,
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
val
;
int
change
=
0
;
u32
mask
;
val
=
!!
ucontrol
->
value
.
integer
.
value
[
0
];
change
=
(
emu
->
spdif_enable
!=
val
);
if
(
change
)
{
emu
->
spdif_enable
=
val
;
if
(
val
)
{
/* Digital */
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT1
,
0
,
0xf
);
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT2
,
0
,
0x0b000000
);
snd_ca0106_ptr_write
(
emu
,
CAPTURE_CONTROL
,
0
,
snd_ca0106_ptr_read
(
emu
,
CAPTURE_CONTROL
,
0
)
&
~
0x1000
);
mask
=
inl
(
emu
->
port
+
GPIO
)
&
~
0x101
;
outl
(
mask
,
emu
->
port
+
GPIO
);
}
else
{
/* Analog */
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT1
,
0
,
0xf
);
snd_ca0106_ptr_write
(
emu
,
SPDIF_SELECT2
,
0
,
0x000f0000
);
snd_ca0106_ptr_write
(
emu
,
CAPTURE_CONTROL
,
0
,
snd_ca0106_ptr_read
(
emu
,
CAPTURE_CONTROL
,
0
)
|
0x1000
);
mask
=
inl
(
emu
->
port
+
GPIO
)
|
0x101
;
outl
(
mask
,
emu
->
port
+
GPIO
);
}
ca0106_spdif_enable
(
emu
);
}
return
change
;
}
...
...
@@ -154,8 +214,6 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
val
;
int
change
=
0
;
u32
mask
;
u32
source
;
val
=
ucontrol
->
value
.
enumerated
.
item
[
0
]
;
if
(
val
>=
6
)
...
...
@@ -163,9 +221,7 @@ static int snd_ca0106_capture_source_put(struct snd_kcontrol *kcontrol,
change
=
(
emu
->
capture_source
!=
val
);
if
(
change
)
{
emu
->
capture_source
=
val
;
source
=
(
val
<<
28
)
|
(
val
<<
24
)
|
(
val
<<
20
)
|
(
val
<<
16
);
mask
=
snd_ca0106_ptr_read
(
emu
,
CAPTURE_SOURCE
,
0
)
&
0xffff
;
snd_ca0106_ptr_write
(
emu
,
CAPTURE_SOURCE
,
0
,
source
|
mask
);
ca0106_set_capture_source
(
emu
);
}
return
change
;
}
...
...
@@ -200,9 +256,7 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
{
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
source_id
;
unsigned
int
ngain
,
ogain
;
int
change
=
0
;
u32
source
;
/* If the capture source has changed,
* update the capture volume from the cached value
* for the particular source.
...
...
@@ -212,18 +266,7 @@ static int snd_ca0106_i2c_capture_source_put(struct snd_kcontrol *kcontrol,
return
-
EINVAL
;
change
=
(
emu
->
i2c_capture_source
!=
source_id
);
if
(
change
)
{
snd_ca0106_i2c_write
(
emu
,
ADC_MUX
,
0
);
/* Mute input */
ngain
=
emu
->
i2c_capture_volume
[
source_id
][
0
];
/* Left */
ogain
=
emu
->
i2c_capture_volume
[
emu
->
i2c_capture_source
][
0
];
/* Left */
if
(
ngain
!=
ogain
)
snd_ca0106_i2c_write
(
emu
,
ADC_ATTEN_ADCL
,
((
ngain
)
&
0xff
));
ngain
=
emu
->
i2c_capture_volume
[
source_id
][
1
];
/* Left */
ogain
=
emu
->
i2c_capture_volume
[
emu
->
i2c_capture_source
][
1
];
/* Left */
if
(
ngain
!=
ogain
)
snd_ca0106_i2c_write
(
emu
,
ADC_ATTEN_ADCR
,
((
ngain
)
&
0xff
));
source
=
1
<<
source_id
;
snd_ca0106_i2c_write
(
emu
,
ADC_MUX
,
source
);
/* Set source */
emu
->
i2c_capture_source
=
source_id
;
ca0106_set_i2c_capture_source
(
emu
,
source_id
,
0
);
}
return
change
;
}
...
...
@@ -271,7 +314,6 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
val
;
int
change
=
0
;
u32
tmp
;
val
=
ucontrol
->
value
.
enumerated
.
item
[
0
]
;
if
(
val
>
1
)
...
...
@@ -279,18 +321,7 @@ static int snd_ca0106_capture_mic_line_in_put(struct snd_kcontrol *kcontrol,
change
=
(
emu
->
capture_mic_line_in
!=
val
);
if
(
change
)
{
emu
->
capture_mic_line_in
=
val
;
if
(
val
)
{
//snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
tmp
=
inl
(
emu
->
port
+
GPIO
)
&
~
0x400
;
tmp
=
tmp
|
0x400
;
outl
(
tmp
,
emu
->
port
+
GPIO
);
//snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_MIC);
}
else
{
//snd_ca0106_i2c_write(emu, ADC_MUX, 0); /* Mute input */
tmp
=
inl
(
emu
->
port
+
GPIO
)
&
~
0x400
;
outl
(
tmp
,
emu
->
port
+
GPIO
);
//snd_ca0106_i2c_write(emu, ADC_MUX, ADC_MUX_LINEIN);
}
ca0106_set_capture_mic_line_in
(
emu
);
}
return
change
;
}
...
...
@@ -359,8 +390,8 @@ static int snd_ca0106_spdif_put(struct snd_kcontrol *kcontrol,
(
ucontrol
->
value
.
iec958
.
status
[
3
]
<<
24
);
change
=
val
!=
emu
->
spdif_bits
[
idx
];
if
(
change
)
{
snd_ca0106_ptr_write
(
emu
,
SPCS0
+
idx
,
0
,
val
);
emu
->
spdif_bits
[
idx
]
=
val
;
ca0106_set_spdif_bits
(
emu
,
idx
);
}
return
change
;
}
...
...
@@ -773,3 +804,50 @@ int __devinit snd_ca0106_mixer(struct snd_ca0106 *emu)
return
0
;
}
#ifdef CONFIG_PM
struct
ca0106_vol_tbl
{
unsigned
int
channel_id
;
unsigned
int
reg
;
};
static
struct
ca0106_vol_tbl
saved_volumes
[
NUM_SAVED_VOLUMES
]
=
{
{
CONTROL_FRONT_CHANNEL
,
PLAYBACK_VOLUME2
},
{
CONTROL_REAR_CHANNEL
,
PLAYBACK_VOLUME2
},
{
CONTROL_CENTER_LFE_CHANNEL
,
PLAYBACK_VOLUME2
},
{
CONTROL_UNKNOWN_CHANNEL
,
PLAYBACK_VOLUME2
},
{
CONTROL_FRONT_CHANNEL
,
PLAYBACK_VOLUME1
},
{
CONTROL_REAR_CHANNEL
,
PLAYBACK_VOLUME1
},
{
CONTROL_CENTER_LFE_CHANNEL
,
PLAYBACK_VOLUME1
},
{
CONTROL_UNKNOWN_CHANNEL
,
PLAYBACK_VOLUME1
},
{
1
,
CAPTURE_CONTROL
},
};
void
snd_ca0106_mixer_suspend
(
struct
snd_ca0106
*
chip
)
{
int
i
;
/* save volumes */
for
(
i
=
0
;
i
<
NUM_SAVED_VOLUMES
;
i
++
)
chip
->
saved_vol
[
i
]
=
snd_ca0106_ptr_read
(
chip
,
saved_volumes
[
i
].
reg
,
saved_volumes
[
i
].
channel_id
);
}
void
snd_ca0106_mixer_resume
(
struct
snd_ca0106
*
chip
)
{
int
i
;
for
(
i
=
0
;
i
<
NUM_SAVED_VOLUMES
;
i
++
)
snd_ca0106_ptr_write
(
chip
,
saved_volumes
[
i
].
reg
,
saved_volumes
[
i
].
channel_id
,
chip
->
saved_vol
[
i
]);
ca0106_spdif_enable
(
chip
);
ca0106_set_capture_source
(
chip
);
ca0106_set_i2c_capture_source
(
chip
,
chip
->
i2c_capture_source
,
1
);
for
(
i
=
0
;
i
<
4
;
i
++
)
ca0106_set_spdif_bits
(
chip
,
i
);
if
(
chip
->
details
->
i2c_adc
)
ca0106_set_capture_mic_line_in
(
chip
);
}
#endif
/* CONFIG_PM */
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