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
ebef7cfc
Commit
ebef7cfc
authored
Dec 20, 2008
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/ca0106-spdif-stream' into topic/ca0106
parents
6bcdbd55
3d475829
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
90 additions
and
26 deletions
+90
-26
sound/pci/ca0106/ca0106.h
sound/pci/ca0106/ca0106.h
+2
-1
sound/pci/ca0106/ca0106_main.c
sound/pci/ca0106/ca0106_main.c
+22
-8
sound/pci/ca0106/ca0106_mixer.c
sound/pci/ca0106/ca0106_mixer.c
+66
-17
No files found.
sound/pci/ca0106/ca0106.h
View file @
ebef7cfc
...
...
@@ -694,7 +694,8 @@ struct snd_ca0106 {
struct
snd_ca0106_channel
playback_channels
[
4
];
struct
snd_ca0106_channel
capture_channels
[
4
];
u32
spdif_bits
[
4
];
/* s/pdif out setup */
u32
spdif_bits
[
4
];
/* s/pdif out default setup */
u32
spdif_str_bits
[
4
];
/* s/pdif out per-stream setup */
int
spdif_enable
;
int
capture_source
;
int
i2c_capture_source
;
...
...
sound/pci/ca0106/ca0106_main.c
View file @
ebef7cfc
...
...
@@ -485,6 +485,15 @@ static const int spi_dacd_bit[] = {
[
PCM_UNKNOWN_CHANNEL
]
=
SPI_DACD1_BIT
,
};
static
void
restore_spdif_bits
(
struct
snd_ca0106
*
chip
,
int
idx
)
{
if
(
chip
->
spdif_str_bits
[
idx
]
!=
chip
->
spdif_bits
[
idx
])
{
chip
->
spdif_str_bits
[
idx
]
=
chip
->
spdif_bits
[
idx
];
snd_ca0106_ptr_write
(
chip
,
SPCS0
+
idx
,
0
,
chip
->
spdif_str_bits
[
idx
]);
}
}
/* open_playback callback */
static
int
snd_ca0106_pcm_open_playback_channel
(
struct
snd_pcm_substream
*
substream
,
int
channel_id
)
...
...
@@ -530,6 +539,9 @@ static int snd_ca0106_pcm_open_playback_channel(struct snd_pcm_substream *substr
if
(
err
<
0
)
return
err
;
}
restore_spdif_bits
(
chip
,
channel_id
);
return
0
;
}
...
...
@@ -541,6 +553,8 @@ static int snd_ca0106_pcm_close_playback(struct snd_pcm_substream *substream)
struct
snd_ca0106_pcm
*
epcm
=
runtime
->
private_data
;
chip
->
playback_channels
[
epcm
->
channel_id
].
use
=
0
;
restore_spdif_bits
(
chip
,
epcm
->
channel_id
);
if
(
chip
->
details
->
spi_dac
&&
epcm
->
channel_id
!=
PCM_FRONT_CHANNEL
)
{
const
int
reg
=
spi_dacd_reg
[
epcm
->
channel_id
];
...
...
@@ -1336,16 +1350,16 @@ static void ca0106_init_chip(struct snd_ca0106 *chip, int resume)
SPCS_GENERATIONSTATUS
|
0x00001200
|
0x00000000
|
SPCS_EMPHASIS_NONE
|
SPCS_COPYRIGHT
;
if
(
!
resume
)
{
chip
->
spdif_bits
[
0
]
=
def_bits
;
chip
->
spdif_bits
[
1
]
=
def_bits
;
chip
->
spdif_bits
[
2
]
=
def_bits
;
chip
->
spdif_bits
[
3
]
=
def_bits
;
chip
->
spdif_
str_bits
[
0
]
=
chip
->
spdif_
bits
[
0
]
=
def_bits
;
chip
->
spdif_
str_bits
[
1
]
=
chip
->
spdif_
bits
[
1
]
=
def_bits
;
chip
->
spdif_
str_bits
[
2
]
=
chip
->
spdif_
bits
[
2
]
=
def_bits
;
chip
->
spdif_
str_bits
[
3
]
=
chip
->
spdif_
bits
[
3
]
=
def_bits
;
}
/* Only SPCS1 has been tested */
snd_ca0106_ptr_write
(
chip
,
SPCS1
,
0
,
chip
->
spdif_bits
[
1
]);
snd_ca0106_ptr_write
(
chip
,
SPCS0
,
0
,
chip
->
spdif_bits
[
0
]);
snd_ca0106_ptr_write
(
chip
,
SPCS2
,
0
,
chip
->
spdif_bits
[
2
]);
snd_ca0106_ptr_write
(
chip
,
SPCS3
,
0
,
chip
->
spdif_bits
[
3
]);
snd_ca0106_ptr_write
(
chip
,
SPCS1
,
0
,
chip
->
spdif_
str_
bits
[
1
]);
snd_ca0106_ptr_write
(
chip
,
SPCS0
,
0
,
chip
->
spdif_
str_
bits
[
0
]);
snd_ca0106_ptr_write
(
chip
,
SPCS2
,
0
,
chip
->
spdif_
str_
bits
[
2
]);
snd_ca0106_ptr_write
(
chip
,
SPCS3
,
0
,
chip
->
spdif_
str_
bits
[
3
]);
snd_ca0106_ptr_write
(
chip
,
PLAYBACK_MUTE
,
0
,
0x00fc0000
);
snd_ca0106_ptr_write
(
chip
,
CAPTURE_MUTE
,
0
,
0x00fc0000
);
...
...
sound/pci/ca0106/ca0106_mixer.c
View file @
ebef7cfc
...
...
@@ -148,7 +148,7 @@ static void ca0106_set_capture_mic_line_in(struct snd_ca0106 *emu)
static
void
ca0106_set_spdif_bits
(
struct
snd_ca0106
*
emu
,
int
idx
)
{
snd_ca0106_ptr_write
(
emu
,
SPCS0
+
idx
,
0
,
emu
->
spdif_bits
[
idx
]);
snd_ca0106_ptr_write
(
emu
,
SPCS0
+
idx
,
0
,
emu
->
spdif_
str_
bits
[
idx
]);
}
/*
...
...
@@ -353,16 +353,33 @@ static int snd_ca0106_spdif_info(struct snd_kcontrol *kcontrol,
return
0
;
}
static
int
snd_ca0106_spdif_get
(
struct
snd_kcontrol
*
kcontrol
,
static
void
decode_spdif_bits
(
unsigned
char
*
status
,
unsigned
int
bits
)
{
status
[
0
]
=
(
bits
>>
0
)
&
0xff
;
status
[
1
]
=
(
bits
>>
8
)
&
0xff
;
status
[
2
]
=
(
bits
>>
16
)
&
0xff
;
status
[
3
]
=
(
bits
>>
24
)
&
0xff
;
}
static
int
snd_ca0106_spdif_get_default
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
idx
=
snd_ctl_get_ioffidx
(
kcontrol
,
&
ucontrol
->
id
);
ucontrol
->
value
.
iec958
.
status
[
0
]
=
(
emu
->
spdif_bits
[
idx
]
>>
0
)
&
0xff
;
ucontrol
->
value
.
iec958
.
status
[
1
]
=
(
emu
->
spdif_bits
[
idx
]
>>
8
)
&
0xff
;
ucontrol
->
value
.
iec958
.
status
[
2
]
=
(
emu
->
spdif_bits
[
idx
]
>>
16
)
&
0xff
;
ucontrol
->
value
.
iec958
.
status
[
3
]
=
(
emu
->
spdif_bits
[
idx
]
>>
24
)
&
0xff
;
decode_spdif_bits
(
ucontrol
->
value
.
iec958
.
status
,
emu
->
spdif_bits
[
idx
]);
return
0
;
}
static
int
snd_ca0106_spdif_get_stream
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
idx
=
snd_ctl_get_ioffidx
(
kcontrol
,
&
ucontrol
->
id
);
decode_spdif_bits
(
ucontrol
->
value
.
iec958
.
status
,
emu
->
spdif_str_bits
[
idx
]);
return
0
;
}
...
...
@@ -376,24 +393,48 @@ static int snd_ca0106_spdif_get_mask(struct snd_kcontrol *kcontrol,
return
0
;
}
static
int
snd_ca0106_spdif_put
(
struct
snd_kcontrol
*
kcontrol
,
static
unsigned
int
encode_spdif_bits
(
unsigned
char
*
status
)
{
return
((
unsigned
int
)
status
[
0
]
<<
0
)
|
((
unsigned
int
)
status
[
1
]
<<
8
)
|
((
unsigned
int
)
status
[
2
]
<<
16
)
|
((
unsigned
int
)
status
[
3
]
<<
24
);
}
static
int
snd_ca0106_spdif_put_default
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
idx
=
snd_ctl_get_ioffidx
(
kcontrol
,
&
ucontrol
->
id
);
int
change
;
unsigned
int
val
;
val
=
(
ucontrol
->
value
.
iec958
.
status
[
0
]
<<
0
)
|
(
ucontrol
->
value
.
iec958
.
status
[
1
]
<<
8
)
|
(
ucontrol
->
value
.
iec958
.
status
[
2
]
<<
16
)
|
(
ucontrol
->
value
.
iec958
.
status
[
3
]
<<
24
);
change
=
val
!=
emu
->
spdif_bits
[
idx
];
if
(
change
)
{
val
=
encode_spdif_bits
(
ucontrol
->
value
.
iec958
.
status
);
if
(
val
!=
emu
->
spdif_bits
[
idx
])
{
emu
->
spdif_bits
[
idx
]
=
val
;
/* FIXME: this isn't safe, but needed to keep the compatibility
* with older alsa-lib config
*/
emu
->
spdif_str_bits
[
idx
]
=
val
;
ca0106_set_spdif_bits
(
emu
,
idx
);
return
1
;
}
return
change
;
return
0
;
}
static
int
snd_ca0106_spdif_put_stream
(
struct
snd_kcontrol
*
kcontrol
,
struct
snd_ctl_elem_value
*
ucontrol
)
{
struct
snd_ca0106
*
emu
=
snd_kcontrol_chip
(
kcontrol
);
unsigned
int
idx
=
snd_ctl_get_ioffidx
(
kcontrol
,
&
ucontrol
->
id
);
unsigned
int
val
;
val
=
encode_spdif_bits
(
ucontrol
->
value
.
iec958
.
status
);
if
(
val
!=
emu
->
spdif_str_bits
[
idx
])
{
emu
->
spdif_str_bits
[
idx
]
=
val
;
ca0106_set_spdif_bits
(
emu
,
idx
);
return
1
;
}
return
0
;
}
static
int
snd_ca0106_volume_info
(
struct
snd_kcontrol
*
kcontrol
,
...
...
@@ -604,8 +645,16 @@ static struct snd_kcontrol_new snd_ca0106_volume_ctls[] __devinitdata = {
.
name
=
SNDRV_CTL_NAME_IEC958
(
""
,
PLAYBACK
,
DEFAULT
),
.
count
=
4
,
.
info
=
snd_ca0106_spdif_info
,
.
get
=
snd_ca0106_spdif_get
,
.
put
=
snd_ca0106_spdif_put
.
get
=
snd_ca0106_spdif_get_default
,
.
put
=
snd_ca0106_spdif_put_default
},
{
.
iface
=
SNDRV_CTL_ELEM_IFACE_PCM
,
.
name
=
SNDRV_CTL_NAME_IEC958
(
""
,
PLAYBACK
,
PCM_STREAM
),
.
count
=
4
,
.
info
=
snd_ca0106_spdif_info
,
.
get
=
snd_ca0106_spdif_get_stream
,
.
put
=
snd_ca0106_spdif_put_stream
},
};
...
...
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