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
2a557a86
Commit
2a557a86
authored
Mar 16, 2015
by
Takashi Iwai
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'topic/hda-unbind' into for-next
parents
8f88f025
b2a0bafa
Changes
24
Show whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
420 additions
and
464 deletions
+420
-464
include/sound/core.h
include/sound/core.h
+2
-1
sound/core/device.c
sound/core/device.c
+33
-10
sound/core/init.c
sound/core/init.c
+1
-4
sound/pci/hda/hda_beep.c
sound/pci/hda/hda_beep.c
+2
-2
sound/pci/hda/hda_bind.c
sound/pci/hda/hda_bind.c
+31
-10
sound/pci/hda/hda_codec.c
sound/pci/hda/hda_codec.c
+196
-249
sound/pci/hda/hda_codec.h
sound/pci/hda/hda_codec.h
+21
-9
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_controller.c
+27
-52
sound/pci/hda/hda_controller.h
sound/pci/hda/hda_controller.h
+0
-6
sound/pci/hda/hda_generic.c
sound/pci/hda/hda_generic.c
+16
-12
sound/pci/hda/hda_generic.h
sound/pci/hda/hda_generic.h
+1
-1
sound/pci/hda/hda_hwdep.c
sound/pci/hda/hda_hwdep.c
+1
-1
sound/pci/hda/hda_intel.c
sound/pci/hda/hda_intel.c
+18
-21
sound/pci/hda/hda_jack.c
sound/pci/hda/hda_jack.c
+4
-4
sound/pci/hda/hda_local.h
sound/pci/hda/hda_local.h
+1
-0
sound/pci/hda/hda_proc.c
sound/pci/hda/hda_proc.c
+4
-4
sound/pci/hda/hda_sysfs.c
sound/pci/hda/hda_sysfs.c
+1
-1
sound/pci/hda/hda_tegra.c
sound/pci/hda/hda_tegra.c
+13
-13
sound/pci/hda/hda_trace.h
sound/pci/hda/hda_trace.h
+2
-2
sound/pci/hda/patch_ca0132.c
sound/pci/hda/patch_ca0132.c
+15
-19
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_hdmi.c
+16
-28
sound/pci/hda/patch_realtek.c
sound/pci/hda/patch_realtek.c
+1
-1
sound/pci/hda/patch_si3054.c
sound/pci/hda/patch_si3054.c
+5
-6
sound/pci/hda/patch_via.c
sound/pci/hda/patch_via.c
+9
-8
No files found.
include/sound/core.h
View file @
2a557a86
...
@@ -278,7 +278,8 @@ int snd_device_new(struct snd_card *card, enum snd_device_type type,
...
@@ -278,7 +278,8 @@ int snd_device_new(struct snd_card *card, enum snd_device_type type,
void
*
device_data
,
struct
snd_device_ops
*
ops
);
void
*
device_data
,
struct
snd_device_ops
*
ops
);
int
snd_device_register
(
struct
snd_card
*
card
,
void
*
device_data
);
int
snd_device_register
(
struct
snd_card
*
card
,
void
*
device_data
);
int
snd_device_register_all
(
struct
snd_card
*
card
);
int
snd_device_register_all
(
struct
snd_card
*
card
);
int
snd_device_disconnect_all
(
struct
snd_card
*
card
);
void
snd_device_disconnect
(
struct
snd_card
*
card
,
void
*
device_data
);
void
snd_device_disconnect_all
(
struct
snd_card
*
card
);
void
snd_device_free
(
struct
snd_card
*
card
,
void
*
device_data
);
void
snd_device_free
(
struct
snd_card
*
card
,
void
*
device_data
);
void
snd_device_free_all
(
struct
snd_card
*
card
);
void
snd_device_free_all
(
struct
snd_card
*
card
);
...
...
sound/core/device.c
View file @
2a557a86
...
@@ -71,7 +71,7 @@ int snd_device_new(struct snd_card *card, enum snd_device_type type,
...
@@ -71,7 +71,7 @@ int snd_device_new(struct snd_card *card, enum snd_device_type type,
}
}
EXPORT_SYMBOL
(
snd_device_new
);
EXPORT_SYMBOL
(
snd_device_new
);
static
int
__snd_device_disconnect
(
struct
snd_device
*
dev
)
static
void
__snd_device_disconnect
(
struct
snd_device
*
dev
)
{
{
if
(
dev
->
state
==
SNDRV_DEV_REGISTERED
)
{
if
(
dev
->
state
==
SNDRV_DEV_REGISTERED
)
{
if
(
dev
->
ops
->
dev_disconnect
&&
if
(
dev
->
ops
->
dev_disconnect
&&
...
@@ -79,7 +79,6 @@ static int __snd_device_disconnect(struct snd_device *dev)
...
@@ -79,7 +79,6 @@ static int __snd_device_disconnect(struct snd_device *dev)
dev_err
(
dev
->
card
->
dev
,
"device disconnect failure
\n
"
);
dev_err
(
dev
->
card
->
dev
,
"device disconnect failure
\n
"
);
dev
->
state
=
SNDRV_DEV_DISCONNECTED
;
dev
->
state
=
SNDRV_DEV_DISCONNECTED
;
}
}
return
0
;
}
}
static
void
__snd_device_free
(
struct
snd_device
*
dev
)
static
void
__snd_device_free
(
struct
snd_device
*
dev
)
...
@@ -106,6 +105,34 @@ static struct snd_device *look_for_dev(struct snd_card *card, void *device_data)
...
@@ -106,6 +105,34 @@ static struct snd_device *look_for_dev(struct snd_card *card, void *device_data)
return
NULL
;
return
NULL
;
}
}
/**
* snd_device_disconnect - disconnect the device
* @card: the card instance
* @device_data: the data pointer to disconnect
*
* Turns the device into the disconnection state, invoking
* dev_disconnect callback, if the device was already registered.
*
* Usually called from snd_card_disconnect().
*
* Return: Zero if successful, or a negative error code on failure or if the
* device not found.
*/
void
snd_device_disconnect
(
struct
snd_card
*
card
,
void
*
device_data
)
{
struct
snd_device
*
dev
;
if
(
snd_BUG_ON
(
!
card
||
!
device_data
))
return
;
dev
=
look_for_dev
(
card
,
device_data
);
if
(
dev
)
__snd_device_disconnect
(
dev
);
else
dev_dbg
(
card
->
dev
,
"device disconnect %p (from %pF), not found
\n
"
,
device_data
,
__builtin_return_address
(
0
));
}
EXPORT_SYMBOL_GPL
(
snd_device_disconnect
);
/**
/**
* snd_device_free - release the device from the card
* snd_device_free - release the device from the card
* @card: the card instance
* @card: the card instance
...
@@ -193,18 +220,14 @@ int snd_device_register_all(struct snd_card *card)
...
@@ -193,18 +220,14 @@ int snd_device_register_all(struct snd_card *card)
* disconnect all the devices on the card.
* disconnect all the devices on the card.
* called from init.c
* called from init.c
*/
*/
int
snd_device_disconnect_all
(
struct
snd_card
*
card
)
void
snd_device_disconnect_all
(
struct
snd_card
*
card
)
{
{
struct
snd_device
*
dev
;
struct
snd_device
*
dev
;
int
err
=
0
;
if
(
snd_BUG_ON
(
!
card
))
if
(
snd_BUG_ON
(
!
card
))
return
-
ENXIO
;
return
;
list_for_each_entry_reverse
(
dev
,
&
card
->
devices
,
list
)
{
list_for_each_entry_reverse
(
dev
,
&
card
->
devices
,
list
)
if
(
__snd_device_disconnect
(
dev
)
<
0
)
__snd_device_disconnect
(
dev
);
err
=
-
ENXIO
;
}
return
err
;
}
}
/*
/*
...
...
sound/core/init.c
View file @
2a557a86
...
@@ -400,7 +400,6 @@ static const struct file_operations snd_shutdown_f_ops =
...
@@ -400,7 +400,6 @@ static const struct file_operations snd_shutdown_f_ops =
int
snd_card_disconnect
(
struct
snd_card
*
card
)
int
snd_card_disconnect
(
struct
snd_card
*
card
)
{
{
struct
snd_monitor_file
*
mfile
;
struct
snd_monitor_file
*
mfile
;
int
err
;
if
(
!
card
)
if
(
!
card
)
return
-
EINVAL
;
return
-
EINVAL
;
...
@@ -445,9 +444,7 @@ int snd_card_disconnect(struct snd_card *card)
...
@@ -445,9 +444,7 @@ int snd_card_disconnect(struct snd_card *card)
#endif
#endif
/* notify all devices that we are disconnected */
/* notify all devices that we are disconnected */
err
=
snd_device_disconnect_all
(
card
);
snd_device_disconnect_all
(
card
);
if
(
err
<
0
)
dev_err
(
card
->
dev
,
"not all devices for card %i can be disconnected
\n
"
,
card
->
number
);
snd_info_card_disconnect
(
card
);
snd_info_card_disconnect
(
card
);
if
(
card
->
registered
)
{
if
(
card
->
registered
)
{
...
...
sound/pci/hda/hda_beep.c
View file @
2a557a86
...
@@ -160,7 +160,7 @@ static int snd_hda_do_attach(struct hda_beep *beep)
...
@@ -160,7 +160,7 @@ static int snd_hda_do_attach(struct hda_beep *beep)
input_dev
->
name
=
"HDA Digital PCBeep"
;
input_dev
->
name
=
"HDA Digital PCBeep"
;
input_dev
->
phys
=
beep
->
phys
;
input_dev
->
phys
=
beep
->
phys
;
input_dev
->
id
.
bustype
=
BUS_PCI
;
input_dev
->
id
.
bustype
=
BUS_PCI
;
input_dev
->
dev
.
parent
=
&
codec
->
bus
->
card
->
card_dev
;
input_dev
->
dev
.
parent
=
&
codec
->
card
->
card_dev
;
input_dev
->
id
.
vendor
=
codec
->
vendor_id
>>
16
;
input_dev
->
id
.
vendor
=
codec
->
vendor_id
>>
16
;
input_dev
->
id
.
product
=
codec
->
vendor_id
&
0xffff
;
input_dev
->
id
.
product
=
codec
->
vendor_id
&
0xffff
;
...
@@ -224,7 +224,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
...
@@ -224,7 +224,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid)
if
(
beep
==
NULL
)
if
(
beep
==
NULL
)
return
-
ENOMEM
;
return
-
ENOMEM
;
snprintf
(
beep
->
phys
,
sizeof
(
beep
->
phys
),
snprintf
(
beep
->
phys
,
sizeof
(
beep
->
phys
),
"card%d/codec#%d/beep0"
,
codec
->
bus
->
card
->
number
,
codec
->
addr
);
"card%d/codec#%d/beep0"
,
codec
->
card
->
number
,
codec
->
addr
);
/* enable linear scale */
/* enable linear scale */
snd_hda_codec_write_cache
(
codec
,
nid
,
0
,
snd_hda_codec_write_cache
(
codec
,
nid
,
0
,
AC_VERB_SET_DIGI_CONVERT_2
,
0x01
);
AC_VERB_SET_DIGI_CONVERT_2
,
0x01
);
...
...
sound/pci/hda/hda_bind.c
View file @
2a557a86
...
@@ -9,6 +9,7 @@
...
@@ -9,6 +9,7 @@
#include <linux/module.h>
#include <linux/module.h>
#include <linux/export.h>
#include <linux/export.h>
#include <linux/pm.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <sound/core.h>
#include <sound/core.h>
#include "hda_codec.h"
#include "hda_codec.h"
#include "hda_local.h"
#include "hda_local.h"
...
@@ -106,16 +107,28 @@ static int hda_codec_driver_probe(struct device *dev)
...
@@ -106,16 +107,28 @@ static int hda_codec_driver_probe(struct device *dev)
}
}
err
=
codec
->
preset
->
patch
(
codec
);
err
=
codec
->
preset
->
patch
(
codec
);
if
(
err
<
0
)
{
if
(
err
<
0
)
module_put
(
owner
);
goto
error_module
;
goto
error
;
err
=
snd_hda_codec_build_pcms
(
codec
);
if
(
err
<
0
)
goto
error_module
;
err
=
snd_hda_codec_build_controls
(
codec
);
if
(
err
<
0
)
goto
error_module
;
if
(
codec
->
card
->
registered
)
{
err
=
snd_card_register
(
codec
->
card
);
if
(
err
<
0
)
goto
error_module
;
}
}
return
0
;
return
0
;
error_module:
module_put
(
owner
);
error:
error:
codec
->
preset
=
NULL
;
snd_hda_codec_cleanup_for_unbind
(
codec
);
memset
(
&
codec
->
patch_ops
,
0
,
sizeof
(
codec
->
patch_ops
));
return
err
;
return
err
;
}
}
...
@@ -125,12 +138,19 @@ static int hda_codec_driver_remove(struct device *dev)
...
@@ -125,12 +138,19 @@ static int hda_codec_driver_remove(struct device *dev)
if
(
codec
->
patch_ops
.
free
)
if
(
codec
->
patch_ops
.
free
)
codec
->
patch_ops
.
free
(
codec
);
codec
->
patch_ops
.
free
(
codec
);
codec
->
preset
=
NULL
;
snd_hda_codec_cleanup_for_unbind
(
codec
);
memset
(
&
codec
->
patch_ops
,
0
,
sizeof
(
codec
->
patch_ops
));
module_put
(
dev
->
driver
->
owner
);
module_put
(
dev
->
driver
->
owner
);
return
0
;
return
0
;
}
}
static
void
hda_codec_driver_shutdown
(
struct
device
*
dev
)
{
struct
hda_codec
*
codec
=
dev_to_hda_codec
(
dev
);
if
(
!
pm_runtime_suspended
(
dev
)
&&
codec
->
patch_ops
.
reboot_notify
)
codec
->
patch_ops
.
reboot_notify
(
codec
);
}
int
__hda_codec_driver_register
(
struct
hda_codec_driver
*
drv
,
const
char
*
name
,
int
__hda_codec_driver_register
(
struct
hda_codec_driver
*
drv
,
const
char
*
name
,
struct
module
*
owner
)
struct
module
*
owner
)
{
{
...
@@ -139,6 +159,7 @@ int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name,
...
@@ -139,6 +159,7 @@ int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name,
drv
->
driver
.
bus
=
&
snd_hda_bus_type
;
drv
->
driver
.
bus
=
&
snd_hda_bus_type
;
drv
->
driver
.
probe
=
hda_codec_driver_probe
;
drv
->
driver
.
probe
=
hda_codec_driver_probe
;
drv
->
driver
.
remove
=
hda_codec_driver_remove
;
drv
->
driver
.
remove
=
hda_codec_driver_remove
;
drv
->
driver
.
shutdown
=
hda_codec_driver_shutdown
;
drv
->
driver
.
pm
=
&
hda_codec_driver_pm
;
drv
->
driver
.
pm
=
&
hda_codec_driver_pm
;
return
driver_register
(
&
drv
->
driver
);
return
driver_register
(
&
drv
->
driver
);
}
}
...
@@ -287,9 +308,9 @@ int snd_hda_codec_configure(struct hda_codec *codec)
...
@@ -287,9 +308,9 @@ int snd_hda_codec_configure(struct hda_codec *codec)
}
}
/* audio codec should override the mixer name */
/* audio codec should override the mixer name */
if
(
codec
->
afg
||
!*
codec
->
bus
->
card
->
mixername
)
if
(
codec
->
afg
||
!*
codec
->
card
->
mixername
)
snprintf
(
codec
->
bus
->
card
->
mixername
,
snprintf
(
codec
->
card
->
mixername
,
sizeof
(
codec
->
bus
->
card
->
mixername
),
sizeof
(
codec
->
card
->
mixername
),
"%s %s"
,
codec
->
vendor_name
,
codec
->
chip_name
);
"%s %s"
,
codec
->
vendor_name
,
codec
->
chip_name
);
return
0
;
return
0
;
...
...
sound/pci/hda/hda_codec.c
View file @
2a557a86
...
@@ -681,7 +681,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
...
@@ -681,7 +681,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
struct
hda_bus_unsolicited
*
unsol
;
struct
hda_bus_unsolicited
*
unsol
;
unsigned
int
wp
;
unsigned
int
wp
;
if
(
!
bus
||
!
bus
->
workq
)
if
(
!
bus
)
return
0
;
return
0
;
trace_hda_unsol_event
(
bus
,
res
,
res_ex
);
trace_hda_unsol_event
(
bus
,
res
,
res_ex
);
...
@@ -693,7 +693,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
...
@@ -693,7 +693,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
unsol
->
queue
[
wp
]
=
res
;
unsol
->
queue
[
wp
]
=
res
;
unsol
->
queue
[
wp
+
1
]
=
res_ex
;
unsol
->
queue
[
wp
+
1
]
=
res_ex
;
queue_work
(
bus
->
workq
,
&
unsol
->
work
);
schedule_work
(
&
unsol
->
work
);
return
0
;
return
0
;
}
}
...
@@ -732,13 +732,9 @@ static void snd_hda_bus_free(struct hda_bus *bus)
...
@@ -732,13 +732,9 @@ static void snd_hda_bus_free(struct hda_bus *bus)
return
;
return
;
WARN_ON
(
!
list_empty
(
&
bus
->
codec_list
));
WARN_ON
(
!
list_empty
(
&
bus
->
codec_list
));
if
(
bus
->
workq
)
cancel_work_sync
(
&
bus
->
unsol
.
work
);
flush_workqueue
(
bus
->
workq
);
if
(
bus
->
ops
.
private_free
)
if
(
bus
->
ops
.
private_free
)
bus
->
ops
.
private_free
(
bus
);
bus
->
ops
.
private_free
(
bus
);
if
(
bus
->
workq
)
destroy_workqueue
(
bus
->
workq
);
kfree
(
bus
);
kfree
(
bus
);
}
}
...
@@ -776,10 +772,8 @@ int snd_hda_bus_new(struct snd_card *card,
...
@@ -776,10 +772,8 @@ int snd_hda_bus_new(struct snd_card *card,
*
busp
=
NULL
;
*
busp
=
NULL
;
bus
=
kzalloc
(
sizeof
(
*
bus
),
GFP_KERNEL
);
bus
=
kzalloc
(
sizeof
(
*
bus
),
GFP_KERNEL
);
if
(
bus
==
NULL
)
{
if
(
!
bus
)
dev_err
(
card
->
dev
,
"can't allocate struct hda_bus
\n
"
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
bus
->
card
=
card
;
bus
->
card
=
card
;
mutex_init
(
&
bus
->
cmd_mutex
);
mutex_init
(
&
bus
->
cmd_mutex
);
...
@@ -787,16 +781,6 @@ int snd_hda_bus_new(struct snd_card *card,
...
@@ -787,16 +781,6 @@ int snd_hda_bus_new(struct snd_card *card,
INIT_LIST_HEAD
(
&
bus
->
codec_list
);
INIT_LIST_HEAD
(
&
bus
->
codec_list
);
INIT_WORK
(
&
bus
->
unsol
.
work
,
process_unsol_events
);
INIT_WORK
(
&
bus
->
unsol
.
work
,
process_unsol_events
);
snprintf
(
bus
->
workq_name
,
sizeof
(
bus
->
workq_name
),
"hd-audio%d"
,
card
->
number
);
bus
->
workq
=
create_singlethread_workqueue
(
bus
->
workq_name
);
if
(
!
bus
->
workq
)
{
dev_err
(
card
->
dev
,
"cannot create workqueue %s
\n
"
,
bus
->
workq_name
);
kfree
(
bus
);
return
-
ENOMEM
;
}
err
=
snd_device_new
(
card
,
SNDRV_DEV_BUS
,
bus
,
&
dev_ops
);
err
=
snd_device_new
(
card
,
SNDRV_DEV_BUS
,
bus
,
&
dev_ops
);
if
(
err
<
0
)
{
if
(
err
<
0
)
{
snd_hda_bus_free
(
bus
);
snd_hda_bus_free
(
bus
);
...
@@ -1070,7 +1054,7 @@ static void hda_jackpoll_work(struct work_struct *work)
...
@@ -1070,7 +1054,7 @@ static void hda_jackpoll_work(struct work_struct *work)
if
(
!
codec
->
jackpoll_interval
)
if
(
!
codec
->
jackpoll_interval
)
return
;
return
;
queue_delayed_work
(
codec
->
bus
->
workq
,
&
codec
->
jackpoll_work
,
schedule_delayed_work
(
&
codec
->
jackpoll_work
,
codec
->
jackpoll_interval
);
codec
->
jackpoll_interval
);
}
}
...
@@ -1118,36 +1102,93 @@ get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid)
...
@@ -1118,36 +1102,93 @@ get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid)
return
p
;
return
p
;
}
}
/*
* PCM device
*/
static
void
release_pcm
(
struct
kref
*
kref
)
{
struct
hda_pcm
*
pcm
=
container_of
(
kref
,
struct
hda_pcm
,
kref
);
if
(
pcm
->
pcm
)
snd_device_free
(
pcm
->
codec
->
card
,
pcm
->
pcm
);
clear_bit
(
pcm
->
device
,
pcm
->
codec
->
bus
->
pcm_dev_bits
);
kfree
(
pcm
->
name
);
kfree
(
pcm
);
}
void
snd_hda_codec_pcm_put
(
struct
hda_pcm
*
pcm
)
{
kref_put
(
&
pcm
->
kref
,
release_pcm
);
}
EXPORT_SYMBOL_GPL
(
snd_hda_codec_pcm_put
);
struct
hda_pcm
*
snd_hda_codec_pcm_new
(
struct
hda_codec
*
codec
,
const
char
*
fmt
,
...)
{
struct
hda_pcm
*
pcm
;
va_list
args
;
va_start
(
args
,
fmt
);
pcm
=
kzalloc
(
sizeof
(
*
pcm
),
GFP_KERNEL
);
if
(
!
pcm
)
return
NULL
;
pcm
->
codec
=
codec
;
kref_init
(
&
pcm
->
kref
);
pcm
->
name
=
kvasprintf
(
GFP_KERNEL
,
fmt
,
args
);
if
(
!
pcm
->
name
)
{
kfree
(
pcm
);
return
NULL
;
}
list_add_tail
(
&
pcm
->
list
,
&
codec
->
pcm_list_head
);
return
pcm
;
}
EXPORT_SYMBOL_GPL
(
snd_hda_codec_pcm_new
);
/*
/*
* codec destructor
* codec destructor
*/
*/
static
void
snd_hda_codec_free
(
struct
hda_codec
*
codec
)
static
void
codec_release_pcms
(
struct
hda_codec
*
codec
)
{
struct
hda_pcm
*
pcm
,
*
n
;
list_for_each_entry_safe
(
pcm
,
n
,
&
codec
->
pcm_list_head
,
list
)
{
list_del_init
(
&
pcm
->
list
);
if
(
pcm
->
pcm
)
snd_device_disconnect
(
codec
->
card
,
pcm
->
pcm
);
snd_hda_codec_pcm_put
(
pcm
);
}
}
void
snd_hda_codec_cleanup_for_unbind
(
struct
hda_codec
*
codec
)
{
{
if
(
!
codec
)
return
;
cancel_delayed_work_sync
(
&
codec
->
jackpoll_work
);
cancel_delayed_work_sync
(
&
codec
->
jackpoll_work
);
if
(
device_is_registered
(
hda_codec_dev
(
codec
)))
if
(
!
codec
->
in_freeing
)
device_del
(
hda_codec_dev
(
codec
));
snd_hda_ctls_clear
(
codec
);
codec_release_pcms
(
codec
);
snd_hda_detach_beep_device
(
codec
);
memset
(
&
codec
->
patch_ops
,
0
,
sizeof
(
codec
->
patch_ops
));
snd_hda_jack_tbl_clear
(
codec
);
snd_hda_jack_tbl_clear
(
codec
);
free_init_pincfgs
(
codec
);
codec
->
proc_widget_hook
=
NULL
;
flush_workqueue
(
codec
->
bus
->
workq
);
codec
->
spec
=
NULL
;
list_del
(
&
codec
->
list
);
snd_array_free
(
&
codec
->
mixers
);
free_hda_cache
(
&
codec
->
amp_cache
);
snd_array_free
(
&
codec
->
nids
);
free_hda_cache
(
&
codec
->
cmd_cache
);
init_hda_cache
(
&
codec
->
amp_cache
,
sizeof
(
struct
hda_amp_info
));
init_hda_cache
(
&
codec
->
cmd_cache
,
sizeof
(
struct
hda_cache_head
));
/* free only driver_pins so that init_pins + user_pins are restored */
snd_array_free
(
&
codec
->
driver_pins
);
snd_array_free
(
&
codec
->
cvt_setups
);
snd_array_free
(
&
codec
->
cvt_setups
);
snd_array_free
(
&
codec
->
spdif_out
);
snd_array_free
(
&
codec
->
spdif_out
);
snd_array_free
(
&
codec
->
verbs
);
codec
->
preset
=
NULL
;
codec
->
slave_dig_outs
=
NULL
;
codec
->
spdif_status_reset
=
0
;
snd_array_free
(
&
codec
->
mixers
);
snd_array_free
(
&
codec
->
nids
);
remove_conn_list
(
codec
);
remove_conn_list
(
codec
);
codec
->
bus
->
caddr_tbl
[
codec
->
addr
]
=
NULL
;
clear_bit
(
codec
->
addr
,
&
codec
->
bus
->
codec_powered
);
snd_hda_sysfs_clear
(
codec
);
free_hda_cache
(
&
codec
->
amp_cache
);
free_hda_cache
(
&
codec
->
cmd_cache
);
kfree
(
codec
->
vendor_name
);
kfree
(
codec
->
chip_name
);
kfree
(
codec
->
modelname
);
kfree
(
codec
->
wcaps
);
codec
->
bus
->
num_codecs
--
;
put_device
(
hda_codec_dev
(
codec
));
}
}
static
bool
snd_hda_codec_get_supported_ps
(
struct
hda_codec
*
codec
,
static
bool
snd_hda_codec_get_supported_ps
(
struct
hda_codec
*
codec
,
...
@@ -1178,14 +1219,32 @@ static int snd_hda_codec_dev_disconnect(struct snd_device *device)
...
@@ -1178,14 +1219,32 @@ static int snd_hda_codec_dev_disconnect(struct snd_device *device)
static
int
snd_hda_codec_dev_free
(
struct
snd_device
*
device
)
static
int
snd_hda_codec_dev_free
(
struct
snd_device
*
device
)
{
{
snd_hda_codec_free
(
device
->
device_data
);
struct
hda_codec
*
codec
=
device
->
device_data
;
codec
->
in_freeing
=
1
;
if
(
device_is_registered
(
hda_codec_dev
(
codec
)))
device_del
(
hda_codec_dev
(
codec
));
put_device
(
hda_codec_dev
(
codec
));
return
0
;
return
0
;
}
}
/* just free the container */
static
void
snd_hda_codec_dev_release
(
struct
device
*
dev
)
static
void
snd_hda_codec_dev_release
(
struct
device
*
dev
)
{
{
kfree
(
dev_to_hda_codec
(
dev
));
struct
hda_codec
*
codec
=
dev_to_hda_codec
(
dev
);
free_init_pincfgs
(
codec
);
list_del
(
&
codec
->
list
);
codec
->
bus
->
caddr_tbl
[
codec
->
addr
]
=
NULL
;
clear_bit
(
codec
->
addr
,
&
codec
->
bus
->
codec_powered
);
snd_hda_sysfs_clear
(
codec
);
free_hda_cache
(
&
codec
->
amp_cache
);
free_hda_cache
(
&
codec
->
cmd_cache
);
kfree
(
codec
->
vendor_name
);
kfree
(
codec
->
chip_name
);
kfree
(
codec
->
modelname
);
kfree
(
codec
->
wcaps
);
codec
->
bus
->
num_codecs
--
;
kfree
(
codec
);
}
}
/**
/**
...
@@ -1196,9 +1255,8 @@ static void snd_hda_codec_dev_release(struct device *dev)
...
@@ -1196,9 +1255,8 @@ static void snd_hda_codec_dev_release(struct device *dev)
*
*
* Returns 0 if successful, or a negative error code.
* Returns 0 if successful, or a negative error code.
*/
*/
int
snd_hda_codec_new
(
struct
hda_bus
*
bus
,
int
snd_hda_codec_new
(
struct
hda_bus
*
bus
,
struct
snd_card
*
card
,
unsigned
int
codec_addr
,
unsigned
int
codec_addr
,
struct
hda_codec
**
codecp
)
struct
hda_codec
**
codecp
)
{
{
struct
hda_codec
*
codec
;
struct
hda_codec
*
codec
;
struct
device
*
dev
;
struct
device
*
dev
;
...
@@ -1217,29 +1275,28 @@ int snd_hda_codec_new(struct hda_bus *bus,
...
@@ -1217,29 +1275,28 @@ int snd_hda_codec_new(struct hda_bus *bus,
return
-
EINVAL
;
return
-
EINVAL
;
if
(
bus
->
caddr_tbl
[
codec_addr
])
{
if
(
bus
->
caddr_tbl
[
codec_addr
])
{
dev_err
(
bus
->
card
->
dev
,
dev_err
(
card
->
dev
,
"address 0x%x is already occupied
\n
"
,
"address 0x%x is already occupied
\n
"
,
codec_addr
);
codec_addr
);
return
-
EBUSY
;
return
-
EBUSY
;
}
}
codec
=
kzalloc
(
sizeof
(
*
codec
),
GFP_KERNEL
);
codec
=
kzalloc
(
sizeof
(
*
codec
),
GFP_KERNEL
);
if
(
codec
==
NULL
)
{
if
(
!
codec
)
dev_err
(
bus
->
card
->
dev
,
"can't allocate struct hda_codec
\n
"
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
dev
=
hda_codec_dev
(
codec
);
dev
=
hda_codec_dev
(
codec
);
device_initialize
(
dev
);
device_initialize
(
dev
);
dev
->
parent
=
bus
->
card
->
dev
;
dev
->
parent
=
card
->
dev
;
dev
->
bus
=
&
snd_hda_bus_type
;
dev
->
bus
=
&
snd_hda_bus_type
;
dev
->
release
=
snd_hda_codec_dev_release
;
dev
->
release
=
snd_hda_codec_dev_release
;
dev
->
groups
=
snd_hda_dev_attr_groups
;
dev
->
groups
=
snd_hda_dev_attr_groups
;
dev_set_name
(
dev
,
"hdaudioC%dD%d"
,
bus
->
card
->
number
,
codec_addr
);
dev_set_name
(
dev
,
"hdaudioC%dD%d"
,
card
->
number
,
codec_addr
);
dev_set_drvdata
(
dev
,
codec
);
/* for sysfs */
dev_set_drvdata
(
dev
,
codec
);
/* for sysfs */
device_enable_async_suspend
(
dev
);
device_enable_async_suspend
(
dev
);
codec
->
bus
=
bus
;
codec
->
bus
=
bus
;
codec
->
card
=
card
;
codec
->
addr
=
codec_addr
;
codec
->
addr
=
codec_addr
;
mutex_init
(
&
codec
->
spdif_mutex
);
mutex_init
(
&
codec
->
spdif_mutex
);
mutex_init
(
&
codec
->
control_mutex
);
mutex_init
(
&
codec
->
control_mutex
);
...
@@ -1255,6 +1312,7 @@ int snd_hda_codec_new(struct hda_bus *bus,
...
@@ -1255,6 +1312,7 @@ int snd_hda_codec_new(struct hda_bus *bus,
snd_array_init
(
&
codec
->
jacktbl
,
sizeof
(
struct
hda_jack_tbl
),
16
);
snd_array_init
(
&
codec
->
jacktbl
,
sizeof
(
struct
hda_jack_tbl
),
16
);
snd_array_init
(
&
codec
->
verbs
,
sizeof
(
struct
hda_verb
*
),
8
);
snd_array_init
(
&
codec
->
verbs
,
sizeof
(
struct
hda_verb
*
),
8
);
INIT_LIST_HEAD
(
&
codec
->
conn_list
);
INIT_LIST_HEAD
(
&
codec
->
conn_list
);
INIT_LIST_HEAD
(
&
codec
->
pcm_list_head
);
INIT_DELAYED_WORK
(
&
codec
->
jackpoll_work
,
hda_jackpoll_work
);
INIT_DELAYED_WORK
(
&
codec
->
jackpoll_work
,
hda_jackpoll_work
);
codec
->
depop_delay
=
-
1
;
codec
->
depop_delay
=
-
1
;
...
@@ -1300,17 +1358,15 @@ int snd_hda_codec_new(struct hda_bus *bus,
...
@@ -1300,17 +1358,15 @@ int snd_hda_codec_new(struct hda_bus *bus,
setup_fg_nodes
(
codec
);
setup_fg_nodes
(
codec
);
if
(
!
codec
->
afg
&&
!
codec
->
mfg
)
{
if
(
!
codec
->
afg
&&
!
codec
->
mfg
)
{
dev_err
(
bus
->
card
->
dev
,
"no AFG or MFG node found
\n
"
);
codec_err
(
codec
,
"no AFG or MFG node found
\n
"
);
err
=
-
ENODEV
;
err
=
-
ENODEV
;
goto
error
;
goto
error
;
}
}
fg
=
codec
->
afg
?
codec
->
afg
:
codec
->
mfg
;
fg
=
codec
->
afg
?
codec
->
afg
:
codec
->
mfg
;
err
=
read_widget_caps
(
codec
,
fg
);
err
=
read_widget_caps
(
codec
,
fg
);
if
(
err
<
0
)
{
if
(
err
<
0
)
dev_err
(
bus
->
card
->
dev
,
"cannot malloc
\n
"
);
goto
error
;
goto
error
;
}
err
=
read_pin_defaults
(
codec
);
err
=
read_pin_defaults
(
codec
);
if
(
err
<
0
)
if
(
err
<
0
)
goto
error
;
goto
error
;
...
@@ -1337,9 +1393,9 @@ int snd_hda_codec_new(struct hda_bus *bus,
...
@@ -1337,9 +1393,9 @@ int snd_hda_codec_new(struct hda_bus *bus,
sprintf
(
component
,
"HDA:%08x,%08x,%08x"
,
codec
->
vendor_id
,
sprintf
(
component
,
"HDA:%08x,%08x,%08x"
,
codec
->
vendor_id
,
codec
->
subsystem_id
,
codec
->
revision_id
);
codec
->
subsystem_id
,
codec
->
revision_id
);
snd_component_add
(
c
odec
->
bus
->
c
ard
,
component
);
snd_component_add
(
card
,
component
);
err
=
snd_device_new
(
bus
->
card
,
SNDRV_DEV_CODEC
,
codec
,
&
dev_ops
);
err
=
snd_device_new
(
card
,
SNDRV_DEV_CODEC
,
codec
,
&
dev_ops
);
if
(
err
<
0
)
if
(
err
<
0
)
goto
error
;
goto
error
;
...
@@ -1348,7 +1404,7 @@ int snd_hda_codec_new(struct hda_bus *bus,
...
@@ -1348,7 +1404,7 @@ int snd_hda_codec_new(struct hda_bus *bus,
return
0
;
return
0
;
error:
error:
snd_hda_codec_free
(
codec
);
put_device
(
hda_codec_dev
(
codec
)
);
return
err
;
return
err
;
}
}
EXPORT_SYMBOL_GPL
(
snd_hda_codec_new
);
EXPORT_SYMBOL_GPL
(
snd_hda_codec_new
);
...
@@ -1371,10 +1427,8 @@ int snd_hda_codec_update_widgets(struct hda_codec *codec)
...
@@ -1371,10 +1427,8 @@ int snd_hda_codec_update_widgets(struct hda_codec *codec)
kfree
(
codec
->
wcaps
);
kfree
(
codec
->
wcaps
);
fg
=
codec
->
afg
?
codec
->
afg
:
codec
->
mfg
;
fg
=
codec
->
afg
?
codec
->
afg
:
codec
->
mfg
;
err
=
read_widget_caps
(
codec
,
fg
);
err
=
read_widget_caps
(
codec
,
fg
);
if
(
err
<
0
)
{
if
(
err
<
0
)
codec_err
(
codec
,
"cannot malloc
\n
"
);
return
err
;
return
err
;
}
snd_array_free
(
&
codec
->
init_pins
);
snd_array_free
(
&
codec
->
init_pins
);
err
=
read_pin_defaults
(
codec
);
err
=
read_pin_defaults
(
codec
);
...
@@ -2237,7 +2291,7 @@ find_mixer_ctl(struct hda_codec *codec, const char *name, int dev, int idx)
...
@@ -2237,7 +2291,7 @@ find_mixer_ctl(struct hda_codec *codec, const char *name, int dev, int idx)
if
(
snd_BUG_ON
(
strlen
(
name
)
>=
sizeof
(
id
.
name
)))
if
(
snd_BUG_ON
(
strlen
(
name
)
>=
sizeof
(
id
.
name
)))
return
NULL
;
return
NULL
;
strcpy
(
id
.
name
,
name
);
strcpy
(
id
.
name
,
name
);
return
snd_ctl_find_id
(
codec
->
bus
->
card
,
&
id
);
return
snd_ctl_find_id
(
codec
->
card
,
&
id
);
}
}
/**
/**
...
@@ -2301,7 +2355,7 @@ int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
...
@@ -2301,7 +2355,7 @@ int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
nid
=
kctl
->
id
.
subdevice
&
0xffff
;
nid
=
kctl
->
id
.
subdevice
&
0xffff
;
if
(
kctl
->
id
.
subdevice
&
(
HDA_SUBDEV_NID_FLAG
|
HDA_SUBDEV_AMP_FLAG
))
if
(
kctl
->
id
.
subdevice
&
(
HDA_SUBDEV_NID_FLAG
|
HDA_SUBDEV_AMP_FLAG
))
kctl
->
id
.
subdevice
=
0
;
kctl
->
id
.
subdevice
=
0
;
err
=
snd_ctl_add
(
codec
->
bus
->
card
,
kctl
);
err
=
snd_ctl_add
(
codec
->
card
,
kctl
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
item
=
snd_array_new
(
&
codec
->
mixers
);
item
=
snd_array_new
(
&
codec
->
mixers
);
...
@@ -2354,7 +2408,7 @@ void snd_hda_ctls_clear(struct hda_codec *codec)
...
@@ -2354,7 +2408,7 @@ void snd_hda_ctls_clear(struct hda_codec *codec)
int
i
;
int
i
;
struct
hda_nid_item
*
items
=
codec
->
mixers
.
list
;
struct
hda_nid_item
*
items
=
codec
->
mixers
.
list
;
for
(
i
=
0
;
i
<
codec
->
mixers
.
used
;
i
++
)
for
(
i
=
0
;
i
<
codec
->
mixers
.
used
;
i
++
)
snd_ctl_remove
(
codec
->
bus
->
card
,
items
[
i
].
kctl
);
snd_ctl_remove
(
codec
->
card
,
items
[
i
].
kctl
);
snd_array_free
(
&
codec
->
mixers
);
snd_array_free
(
&
codec
->
mixers
);
snd_array_free
(
&
codec
->
nids
);
snd_array_free
(
&
codec
->
nids
);
}
}
...
@@ -2378,9 +2432,8 @@ int snd_hda_lock_devices(struct hda_bus *bus)
...
@@ -2378,9 +2432,8 @@ int snd_hda_lock_devices(struct hda_bus *bus)
goto
err_clear
;
goto
err_clear
;
list_for_each_entry
(
codec
,
&
bus
->
codec_list
,
list
)
{
list_for_each_entry
(
codec
,
&
bus
->
codec_list
,
list
)
{
int
pcm
;
struct
hda_pcm
*
cpcm
;
for
(
pcm
=
0
;
pcm
<
codec
->
num_pcms
;
pcm
++
)
{
list_for_each_entry
(
cpcm
,
&
codec
->
pcm_list_head
,
list
)
{
struct
hda_pcm
*
cpcm
=
&
codec
->
pcm_info
[
pcm
];
if
(
!
cpcm
->
pcm
)
if
(
!
cpcm
->
pcm
)
continue
;
continue
;
if
(
cpcm
->
pcm
->
streams
[
0
].
substream_opened
||
if
(
cpcm
->
pcm
->
streams
[
0
].
substream_opened
||
...
@@ -2407,7 +2460,6 @@ void snd_hda_unlock_devices(struct hda_bus *bus)
...
@@ -2407,7 +2460,6 @@ void snd_hda_unlock_devices(struct hda_bus *bus)
{
{
struct
snd_card
*
card
=
bus
->
card
;
struct
snd_card
*
card
=
bus
->
card
;
card
=
bus
->
card
;
spin_lock
(
&
card
->
files_lock
);
spin_lock
(
&
card
->
files_lock
);
card
->
shutdown
=
0
;
card
->
shutdown
=
0
;
spin_unlock
(
&
card
->
files_lock
);
spin_unlock
(
&
card
->
files_lock
);
...
@@ -2427,47 +2479,14 @@ EXPORT_SYMBOL_GPL(snd_hda_unlock_devices);
...
@@ -2427,47 +2479,14 @@ EXPORT_SYMBOL_GPL(snd_hda_unlock_devices);
int
snd_hda_codec_reset
(
struct
hda_codec
*
codec
)
int
snd_hda_codec_reset
(
struct
hda_codec
*
codec
)
{
{
struct
hda_bus
*
bus
=
codec
->
bus
;
struct
hda_bus
*
bus
=
codec
->
bus
;
struct
snd_card
*
card
=
bus
->
card
;
int
i
;
if
(
snd_hda_lock_devices
(
bus
)
<
0
)
if
(
snd_hda_lock_devices
(
bus
)
<
0
)
return
-
EBUSY
;
return
-
EBUSY
;
/* OK, let it free */
/* OK, let it free */
cancel_delayed_work_sync
(
&
codec
->
jackpoll_work
);
flush_workqueue
(
bus
->
workq
);
snd_hda_ctls_clear
(
codec
);
/* release PCMs */
for
(
i
=
0
;
i
<
codec
->
num_pcms
;
i
++
)
{
if
(
codec
->
pcm_info
[
i
].
pcm
)
{
snd_device_free
(
card
,
codec
->
pcm_info
[
i
].
pcm
);
clear_bit
(
codec
->
pcm_info
[
i
].
device
,
bus
->
pcm_dev_bits
);
}
}
snd_hda_detach_beep_device
(
codec
);
if
(
device_is_registered
(
hda_codec_dev
(
codec
)))
if
(
device_is_registered
(
hda_codec_dev
(
codec
)))
device_del
(
hda_codec_dev
(
codec
));
device_del
(
hda_codec_dev
(
codec
));
memset
(
&
codec
->
patch_ops
,
0
,
sizeof
(
codec
->
patch_ops
));
snd_hda_jack_tbl_clear
(
codec
);
codec
->
proc_widget_hook
=
NULL
;
codec
->
spec
=
NULL
;
free_hda_cache
(
&
codec
->
amp_cache
);
free_hda_cache
(
&
codec
->
cmd_cache
);
init_hda_cache
(
&
codec
->
amp_cache
,
sizeof
(
struct
hda_amp_info
));
init_hda_cache
(
&
codec
->
cmd_cache
,
sizeof
(
struct
hda_cache_head
));
/* free only driver_pins so that init_pins + user_pins are restored */
snd_array_free
(
&
codec
->
driver_pins
);
snd_array_free
(
&
codec
->
cvt_setups
);
snd_array_free
(
&
codec
->
spdif_out
);
snd_array_free
(
&
codec
->
verbs
);
codec
->
num_pcms
=
0
;
codec
->
pcm_info
=
NULL
;
codec
->
preset
=
NULL
;
codec
->
slave_dig_outs
=
NULL
;
codec
->
spdif_status_reset
=
0
;
/* allow device access again */
/* allow device access again */
snd_hda_unlock_devices
(
bus
);
snd_hda_unlock_devices
(
bus
);
return
0
;
return
0
;
...
@@ -3960,12 +3979,12 @@ static void hda_call_codec_resume(struct hda_codec *codec)
...
@@ -3960,12 +3979,12 @@ static void hda_call_codec_resume(struct hda_codec *codec)
static
int
hda_codec_runtime_suspend
(
struct
device
*
dev
)
static
int
hda_codec_runtime_suspend
(
struct
device
*
dev
)
{
{
struct
hda_codec
*
codec
=
dev_to_hda_codec
(
dev
);
struct
hda_codec
*
codec
=
dev_to_hda_codec
(
dev
);
struct
hda_pcm
*
pcm
;
unsigned
int
state
;
unsigned
int
state
;
int
i
;
cancel_delayed_work_sync
(
&
codec
->
jackpoll_work
);
cancel_delayed_work_sync
(
&
codec
->
jackpoll_work
);
for
(
i
=
0
;
i
<
codec
->
num_pcms
;
i
++
)
list_for_each_entry
(
pcm
,
&
codec
->
pcm_list_head
,
list
)
snd_pcm_suspend_all
(
codec
->
pcm_info
[
i
].
pcm
);
snd_pcm_suspend_all
(
pcm
->
pcm
);
state
=
hda_call_codec_suspend
(
codec
);
state
=
hda_call_codec_suspend
(
codec
);
if
(
codec
->
d3_stop_clk
&&
codec
->
epss
&&
(
state
&
AC_PWRST_CLK_STOP_OK
))
if
(
codec
->
d3_stop_clk
&&
codec
->
epss
&&
(
state
&
AC_PWRST_CLK_STOP_OK
))
clear_bit
(
codec
->
addr
,
&
codec
->
bus
->
codec_powered
);
clear_bit
(
codec
->
addr
,
&
codec
->
bus
->
codec_powered
);
...
@@ -3991,57 +4010,26 @@ const struct dev_pm_ops hda_codec_driver_pm = {
...
@@ -3991,57 +4010,26 @@ const struct dev_pm_ops hda_codec_driver_pm = {
NULL
)
NULL
)
};
};
/**
* snd_hda_build_controls - build mixer controls
* @bus: the BUS
*
* Creates mixer controls for each codec included in the bus.
*
* Returns 0 if successful, otherwise a negative error code.
*/
int
snd_hda_build_controls
(
struct
hda_bus
*
bus
)
{
struct
hda_codec
*
codec
;
list_for_each_entry
(
codec
,
&
bus
->
codec_list
,
list
)
{
int
err
=
snd_hda_codec_build_controls
(
codec
);
if
(
err
<
0
)
{
codec_err
(
codec
,
"cannot build controls for #%d (error %d)
\n
"
,
codec
->
addr
,
err
);
err
=
snd_hda_codec_reset
(
codec
);
if
(
err
<
0
)
{
codec_err
(
codec
,
"cannot revert codec
\n
"
);
return
err
;
}
}
}
return
0
;
}
EXPORT_SYMBOL_GPL
(
snd_hda_build_controls
);
/*
/*
* add standard channel maps if not specified
* add standard channel maps if not specified
*/
*/
static
int
add_std_chmaps
(
struct
hda_codec
*
codec
)
static
int
add_std_chmaps
(
struct
hda_codec
*
codec
)
{
{
int
i
,
str
,
err
;
struct
hda_pcm
*
pcm
;
int
str
,
err
;
for
(
i
=
0
;
i
<
codec
->
num_pcms
;
i
++
)
{
list_for_each_entry
(
pcm
,
&
codec
->
pcm_list_head
,
list
)
{
for
(
str
=
0
;
str
<
2
;
str
++
)
{
for
(
str
=
0
;
str
<
2
;
str
++
)
{
struct
snd_pcm
*
pcm
=
codec
->
pcm_info
[
i
].
pcm
;
struct
hda_pcm_stream
*
hinfo
=
&
pcm
->
stream
[
str
];
struct
hda_pcm_stream
*
hinfo
=
&
codec
->
pcm_info
[
i
].
stream
[
str
];
struct
snd_pcm_chmap
*
chmap
;
struct
snd_pcm_chmap
*
chmap
;
const
struct
snd_pcm_chmap_elem
*
elem
;
const
struct
snd_pcm_chmap_elem
*
elem
;
if
(
codec
->
pcm_info
[
i
].
own_chmap
)
if
(
pcm
->
own_chmap
)
continue
;
continue
;
if
(
!
pcm
||
!
hinfo
->
substreams
)
if
(
!
pcm
||
!
hinfo
->
substreams
)
continue
;
continue
;
elem
=
hinfo
->
chmap
?
hinfo
->
chmap
:
snd_pcm_std_chmaps
;
elem
=
hinfo
->
chmap
?
hinfo
->
chmap
:
snd_pcm_std_chmaps
;
err
=
snd_pcm_add_chmap_ctls
(
pcm
,
str
,
elem
,
err
=
snd_pcm_add_chmap_ctls
(
pcm
->
pcm
,
str
,
elem
,
hinfo
->
channels_max
,
hinfo
->
channels_max
,
0
,
&
chmap
);
0
,
&
chmap
);
if
(
err
<
0
)
if
(
err
<
0
)
...
@@ -4490,7 +4478,11 @@ int snd_hda_codec_prepare(struct hda_codec *codec,
...
@@ -4490,7 +4478,11 @@ int snd_hda_codec_prepare(struct hda_codec *codec,
{
{
int
ret
;
int
ret
;
mutex_lock
(
&
codec
->
bus
->
prepare_mutex
);
mutex_lock
(
&
codec
->
bus
->
prepare_mutex
);
ret
=
hinfo
->
ops
.
prepare
(
hinfo
,
codec
,
stream
,
format
,
substream
);
if
(
hinfo
->
ops
.
prepare
)
ret
=
hinfo
->
ops
.
prepare
(
hinfo
,
codec
,
stream
,
format
,
substream
);
else
ret
=
-
ENODEV
;
if
(
ret
>=
0
)
if
(
ret
>=
0
)
purify_inactive_streams
(
codec
);
purify_inactive_streams
(
codec
);
mutex_unlock
(
&
codec
->
bus
->
prepare_mutex
);
mutex_unlock
(
&
codec
->
bus
->
prepare_mutex
);
...
@@ -4511,6 +4503,7 @@ void snd_hda_codec_cleanup(struct hda_codec *codec,
...
@@ -4511,6 +4503,7 @@ void snd_hda_codec_cleanup(struct hda_codec *codec,
struct
snd_pcm_substream
*
substream
)
struct
snd_pcm_substream
*
substream
)
{
{
mutex_lock
(
&
codec
->
bus
->
prepare_mutex
);
mutex_lock
(
&
codec
->
bus
->
prepare_mutex
);
if
(
hinfo
->
ops
.
cleanup
)
hinfo
->
ops
.
cleanup
(
hinfo
,
codec
,
substream
);
hinfo
->
ops
.
cleanup
(
hinfo
,
codec
,
substream
);
mutex_unlock
(
&
codec
->
bus
->
prepare_mutex
);
mutex_unlock
(
&
codec
->
bus
->
prepare_mutex
);
}
}
...
@@ -4569,63 +4562,74 @@ static int get_empty_pcm_device(struct hda_bus *bus, unsigned int type)
...
@@ -4569,63 +4562,74 @@ static int get_empty_pcm_device(struct hda_bus *bus, unsigned int type)
return
-
EAGAIN
;
return
-
EAGAIN
;
}
}
/*
/* call build_pcms ops of the given codec and set up the default parameters */
* attach a new PCM stream
int
snd_hda_codec_parse_pcms
(
struct
hda_codec
*
codec
)
*/
static
int
snd_hda_attach_pcm
(
struct
hda_codec
*
codec
,
struct
hda_pcm
*
pcm
)
{
{
struct
hda_bus
*
bus
=
codec
->
bus
;
struct
hda_pcm
*
cpcm
;
struct
hda_pcm_stream
*
info
;
int
err
;
int
stream
,
err
;
if
(
!
list_empty
(
&
codec
->
pcm_list_head
))
return
0
;
/* already parsed */
if
(
!
codec
->
patch_ops
.
build_pcms
)
return
0
;
err
=
codec
->
patch_ops
.
build_pcms
(
codec
);
if
(
err
<
0
)
{
codec_err
(
codec
,
"cannot build PCMs for #%d (error %d)
\n
"
,
codec
->
addr
,
err
);
return
err
;
}
list_for_each_entry
(
cpcm
,
&
codec
->
pcm_list_head
,
list
)
{
int
stream
;
if
(
snd_BUG_ON
(
!
pcm
->
name
))
return
-
EINVAL
;
for
(
stream
=
0
;
stream
<
2
;
stream
++
)
{
for
(
stream
=
0
;
stream
<
2
;
stream
++
)
{
info
=
&
pcm
->
stream
[
stream
];
struct
hda_pcm_stream
*
info
=
&
cpcm
->
stream
[
stream
];
if
(
info
->
substreams
)
{
if
(
!
info
->
substreams
)
continue
;
err
=
set_pcm_default_values
(
codec
,
info
);
err
=
set_pcm_default_values
(
codec
,
info
);
if
(
err
<
0
)
if
(
err
<
0
)
{
codec_warn
(
codec
,
"fail to setup default for PCM %s
\n
"
,
cpcm
->
name
);
return
err
;
return
err
;
}
}
}
}
return
bus
->
ops
.
attach_pcm
(
bus
,
codec
,
pcm
);
}
return
0
;
}
}
/* assign all PCMs of the given codec */
/* assign all PCMs of the given codec */
int
snd_hda_codec_build_pcms
(
struct
hda_codec
*
codec
)
int
snd_hda_codec_build_pcms
(
struct
hda_codec
*
codec
)
{
{
unsigned
int
pcm
;
struct
hda_bus
*
bus
=
codec
->
bus
;
int
err
;
struct
hda_pcm
*
cpcm
;
int
dev
,
err
;
if
(
!
codec
->
num_pcms
)
{
if
(
snd_BUG_ON
(
!
bus
->
ops
.
attach_pcm
))
if
(
!
codec
->
patch_ops
.
build_pcms
)
return
-
EINVAL
;
return
0
;
err
=
codec
->
patch_ops
.
build_pcms
(
codec
);
err
=
snd_hda_codec_parse_pcms
(
codec
);
if
(
err
<
0
)
{
codec_err
(
codec
,
"cannot build PCMs for #%d (error %d)
\n
"
,
codec
->
addr
,
err
);
err
=
snd_hda_codec_reset
(
codec
);
if
(
err
<
0
)
{
if
(
err
<
0
)
{
codec_err
(
codec
,
snd_hda_codec_reset
(
codec
);
"cannot revert codec
\n
"
);
return
err
;
return
err
;
}
}
}
}
for
(
pcm
=
0
;
pcm
<
codec
->
num_pcms
;
pcm
++
)
{
struct
hda_pcm
*
cpcm
=
&
codec
->
pcm_info
[
pcm
];
int
dev
;
/* attach a new PCM streams */
list_for_each_entry
(
cpcm
,
&
codec
->
pcm_list_head
,
list
)
{
if
(
cpcm
->
pcm
)
continue
;
/* already attached */
if
(
!
cpcm
->
stream
[
0
].
substreams
&&
!
cpcm
->
stream
[
1
].
substreams
)
if
(
!
cpcm
->
stream
[
0
].
substreams
&&
!
cpcm
->
stream
[
1
].
substreams
)
continue
;
/* no substreams assigned */
continue
;
/* no substreams assigned */
if
(
!
cpcm
->
pcm
)
{
dev
=
get_empty_pcm_device
(
bus
,
cpcm
->
pcm_type
);
dev
=
get_empty_pcm_device
(
codec
->
bus
,
cpcm
->
pcm_type
);
if
(
dev
<
0
)
if
(
dev
<
0
)
continue
;
/* no fatal error */
continue
;
/* no fatal error */
cpcm
->
device
=
dev
;
cpcm
->
device
=
dev
;
err
=
snd_hda_attach_pcm
(
codec
,
cpcm
);
err
=
bus
->
ops
.
attach_pcm
(
bus
,
codec
,
cpcm
);
if
(
err
<
0
)
{
if
(
err
<
0
)
{
codec_err
(
codec
,
codec_err
(
codec
,
"cannot attach PCM stream %d for codec #%d
\n
"
,
"cannot attach PCM stream %d for codec #%d
\n
"
,
...
@@ -4633,48 +4637,9 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
...
@@ -4633,48 +4637,9 @@ int snd_hda_codec_build_pcms(struct hda_codec *codec)
continue
;
/* no fatal error */
continue
;
/* no fatal error */
}
}
}
}
}
return
0
;
}
/**
* snd_hda_build_pcms - build PCM information
* @bus: the BUS
*
* Create PCM information for each codec included in the bus.
*
* The build_pcms codec patch is requested to set up codec->num_pcms and
* codec->pcm_info properly. The array is referred by the top-level driver
* to create its PCM instances.
* The allocated codec->pcm_info should be released in codec->patch_ops.free
* callback.
*
* At least, substreams, channels_min and channels_max must be filled for
* each stream. substreams = 0 indicates that the stream doesn't exist.
* When rates and/or formats are zero, the supported values are queried
* from the given nid. The nid is used also by the default ops.prepare
* and ops.cleanup callbacks.
*
* The driver needs to call ops.open in its open callback. Similarly,
* ops.close is supposed to be called in the close callback.
* ops.prepare should be called in the prepare or hw_params callback
* with the proper parameters for set up.
* ops.cleanup should be called in hw_free for clean up of streams.
*
* This function returns 0 if successful, or a negative error code.
*/
int
snd_hda_build_pcms
(
struct
hda_bus
*
bus
)
{
struct
hda_codec
*
codec
;
list_for_each_entry
(
codec
,
&
bus
->
codec_list
,
list
)
{
int
err
=
snd_hda_codec_build_pcms
(
codec
);
if
(
err
<
0
)
return
err
;
}
return
0
;
return
0
;
}
}
EXPORT_SYMBOL_GPL
(
snd_hda_build_pcms
);
/**
/**
* snd_hda_add_new_ctls - create controls from the array
* snd_hda_add_new_ctls - create controls from the array
...
@@ -4976,24 +4941,6 @@ static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
...
@@ -4976,24 +4941,6 @@ static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
}
}
}
}
/**
* snd_hda_bus_reboot_notify - call the reboot notifier of each codec
* @bus: HD-audio bus
*/
void
snd_hda_bus_reboot_notify
(
struct
hda_bus
*
bus
)
{
struct
hda_codec
*
codec
;
if
(
!
bus
)
return
;
list_for_each_entry
(
codec
,
&
bus
->
codec_list
,
list
)
{
if
(
hda_codec_is_power_on
(
codec
)
&&
codec
->
patch_ops
.
reboot_notify
)
codec
->
patch_ops
.
reboot_notify
(
codec
);
}
}
EXPORT_SYMBOL_GPL
(
snd_hda_bus_reboot_notify
);
/**
/**
* snd_hda_multi_out_dig_open - open the digital out in the exclusive mode
* snd_hda_multi_out_dig_open - open the digital out in the exclusive mode
* @codec: the HDA codec
* @codec: the HDA codec
...
...
sound/pci/hda/hda_codec.h
View file @
2a557a86
...
@@ -21,6 +21,7 @@
...
@@ -21,6 +21,7 @@
#ifndef __SOUND_HDA_CODEC_H
#ifndef __SOUND_HDA_CODEC_H
#define __SOUND_HDA_CODEC_H
#define __SOUND_HDA_CODEC_H
#include <linux/kref.h>
#include <sound/info.h>
#include <sound/info.h>
#include <sound/control.h>
#include <sound/control.h>
#include <sound/pcm.h>
#include <sound/pcm.h>
...
@@ -131,8 +132,6 @@ struct hda_bus {
...
@@ -131,8 +132,6 @@ struct hda_bus {
/* unsolicited event queue */
/* unsolicited event queue */
struct
hda_bus_unsolicited
unsol
;
struct
hda_bus_unsolicited
unsol
;
char
workq_name
[
16
];
struct
workqueue_struct
*
workq
;
/* common workqueue for codecs */
/* assigned PCMs */
/* assigned PCMs */
DECLARE_BITMAP
(
pcm_dev_bits
,
SNDRV_PCM_DEVICES
);
DECLARE_BITMAP
(
pcm_dev_bits
,
SNDRV_PCM_DEVICES
);
...
@@ -268,12 +267,17 @@ struct hda_pcm {
...
@@ -268,12 +267,17 @@ struct hda_pcm {
int
device
;
/* device number to assign */
int
device
;
/* device number to assign */
struct
snd_pcm
*
pcm
;
/* assigned PCM instance */
struct
snd_pcm
*
pcm
;
/* assigned PCM instance */
bool
own_chmap
;
/* codec driver provides own channel maps */
bool
own_chmap
;
/* codec driver provides own channel maps */
/* private: */
struct
hda_codec
*
codec
;
struct
kref
kref
;
struct
list_head
list
;
};
};
/* codec information */
/* codec information */
struct
hda_codec
{
struct
hda_codec
{
struct
device
dev
;
struct
device
dev
;
struct
hda_bus
*
bus
;
struct
hda_bus
*
bus
;
struct
snd_card
*
card
;
unsigned
int
addr
;
/* codec addr*/
unsigned
int
addr
;
/* codec addr*/
struct
list_head
list
;
/* list point */
struct
list_head
list
;
/* list point */
...
@@ -300,8 +304,7 @@ struct hda_codec {
...
@@ -300,8 +304,7 @@ struct hda_codec {
struct
hda_codec_ops
patch_ops
;
struct
hda_codec_ops
patch_ops
;
/* PCM to create, set by patch_ops.build_pcms callback */
/* PCM to create, set by patch_ops.build_pcms callback */
unsigned
int
num_pcms
;
struct
list_head
pcm_list_head
;
struct
hda_pcm
*
pcm_info
;
/* codec specific info */
/* codec specific info */
void
*
spec
;
void
*
spec
;
...
@@ -345,6 +348,7 @@ struct hda_codec {
...
@@ -345,6 +348,7 @@ struct hda_codec {
#endif
#endif
/* misc flags */
/* misc flags */
unsigned
int
in_freeing
:
1
;
/* being released */
unsigned
int
spdif_status_reset
:
1
;
/* needs to toggle SPDIF for each
unsigned
int
spdif_status_reset
:
1
;
/* needs to toggle SPDIF for each
* status change
* status change
* (e.g. Realtek codecs)
* (e.g. Realtek codecs)
...
@@ -420,8 +424,8 @@ enum {
...
@@ -420,8 +424,8 @@ enum {
* constructors
* constructors
*/
*/
int
snd_hda_bus_new
(
struct
snd_card
*
card
,
struct
hda_bus
**
busp
);
int
snd_hda_bus_new
(
struct
snd_card
*
card
,
struct
hda_bus
**
busp
);
int
snd_hda_codec_new
(
struct
hda_bus
*
bus
,
unsigned
int
codec_addr
,
int
snd_hda_codec_new
(
struct
hda_bus
*
bus
,
struct
snd_card
*
card
,
struct
hda_codec
**
codecp
);
unsigned
int
codec_addr
,
struct
hda_codec
**
codecp
);
int
snd_hda_codec_configure
(
struct
hda_codec
*
codec
);
int
snd_hda_codec_configure
(
struct
hda_codec
*
codec
);
int
snd_hda_codec_update_widgets
(
struct
hda_codec
*
codec
);
int
snd_hda_codec_update_widgets
(
struct
hda_codec
*
codec
);
...
@@ -510,15 +514,24 @@ void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid);
...
@@ -510,15 +514,24 @@ void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid);
/*
/*
* Mixer
* Mixer
*/
*/
int
snd_hda_build_controls
(
struct
hda_bus
*
bus
);
int
snd_hda_codec_build_controls
(
struct
hda_codec
*
codec
);
int
snd_hda_codec_build_controls
(
struct
hda_codec
*
codec
);
/*
/*
* PCM
* PCM
*/
*/
int
snd_hda_
build_pcms
(
struct
hda_bus
*
bus
);
int
snd_hda_
codec_parse_pcms
(
struct
hda_codec
*
codec
);
int
snd_hda_codec_build_pcms
(
struct
hda_codec
*
codec
);
int
snd_hda_codec_build_pcms
(
struct
hda_codec
*
codec
);
__printf
(
2
,
3
)
struct
hda_pcm
*
snd_hda_codec_pcm_new
(
struct
hda_codec
*
codec
,
const
char
*
fmt
,
...);
static
inline
void
snd_hda_codec_pcm_get
(
struct
hda_pcm
*
pcm
)
{
kref_get
(
&
pcm
->
kref
);
}
void
snd_hda_codec_pcm_put
(
struct
hda_pcm
*
pcm
);
int
snd_hda_codec_prepare
(
struct
hda_codec
*
codec
,
int
snd_hda_codec_prepare
(
struct
hda_codec
*
codec
,
struct
hda_pcm_stream
*
hinfo
,
struct
hda_pcm_stream
*
hinfo
,
unsigned
int
stream
,
unsigned
int
stream
,
...
@@ -550,7 +563,6 @@ extern const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[];
...
@@ -550,7 +563,6 @@ extern const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[];
* Misc
* Misc
*/
*/
void
snd_hda_get_codec_name
(
struct
hda_codec
*
codec
,
char
*
name
,
int
namelen
);
void
snd_hda_get_codec_name
(
struct
hda_codec
*
codec
,
char
*
name
,
int
namelen
);
void
snd_hda_bus_reboot_notify
(
struct
hda_bus
*
bus
);
void
snd_hda_codec_set_power_to_all
(
struct
hda_codec
*
codec
,
hda_nid_t
fg
,
void
snd_hda_codec_set_power_to_all
(
struct
hda_codec
*
codec
,
hda_nid_t
fg
,
unsigned
int
power_state
);
unsigned
int
power_state
);
...
...
sound/pci/hda/hda_controller.c
View file @
2a557a86
...
@@ -27,7 +27,6 @@
...
@@ -27,7 +27,6 @@
#include <linux/module.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/slab.h>
#include <linux/reboot.h>
#include <sound/core.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <sound/initval.h>
#include "hda_controller.h"
#include "hda_controller.h"
...
@@ -416,9 +415,11 @@ static int azx_pcm_close(struct snd_pcm_substream *substream)
...
@@ -416,9 +415,11 @@ static int azx_pcm_close(struct snd_pcm_substream *substream)
azx_dev
->
running
=
0
;
azx_dev
->
running
=
0
;
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
spin_unlock_irqrestore
(
&
chip
->
reg_lock
,
flags
);
azx_release_device
(
azx_dev
);
azx_release_device
(
azx_dev
);
if
(
hinfo
->
ops
.
close
)
hinfo
->
ops
.
close
(
hinfo
,
apcm
->
codec
,
substream
);
hinfo
->
ops
.
close
(
hinfo
,
apcm
->
codec
,
substream
);
snd_hda_power_down
(
apcm
->
codec
);
snd_hda_power_down
(
apcm
->
codec
);
mutex_unlock
(
&
chip
->
open_mutex
);
mutex_unlock
(
&
chip
->
open_mutex
);
snd_hda_codec_pcm_put
(
apcm
->
info
);
return
0
;
return
0
;
}
}
...
@@ -805,11 +806,12 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
...
@@ -805,11 +806,12 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
int
err
;
int
err
;
int
buff_step
;
int
buff_step
;
snd_hda_codec_pcm_get
(
apcm
->
info
);
mutex_lock
(
&
chip
->
open_mutex
);
mutex_lock
(
&
chip
->
open_mutex
);
azx_dev
=
azx_assign_device
(
chip
,
substream
);
azx_dev
=
azx_assign_device
(
chip
,
substream
);
if
(
azx_dev
==
NULL
)
{
if
(
azx_dev
==
NULL
)
{
mutex_unlock
(
&
chip
->
open_mutex
)
;
err
=
-
EBUSY
;
return
-
EBUSY
;
goto
unlock
;
}
}
runtime
->
hw
=
azx_pcm_hw
;
runtime
->
hw
=
azx_pcm_hw
;
runtime
->
hw
.
channels_min
=
hinfo
->
channels_min
;
runtime
->
hw
.
channels_min
=
hinfo
->
channels_min
;
...
@@ -844,12 +846,13 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
...
@@ -844,12 +846,13 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
snd_pcm_hw_constraint_step
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_PERIOD_BYTES
,
snd_pcm_hw_constraint_step
(
runtime
,
0
,
SNDRV_PCM_HW_PARAM_PERIOD_BYTES
,
buff_step
);
buff_step
);
snd_hda_power_up
(
apcm
->
codec
);
snd_hda_power_up
(
apcm
->
codec
);
if
(
hinfo
->
ops
.
open
)
err
=
hinfo
->
ops
.
open
(
hinfo
,
apcm
->
codec
,
substream
);
err
=
hinfo
->
ops
.
open
(
hinfo
,
apcm
->
codec
,
substream
);
else
err
=
-
ENODEV
;
if
(
err
<
0
)
{
if
(
err
<
0
)
{
azx_release_device
(
azx_dev
);
azx_release_device
(
azx_dev
);
snd_hda_power_down
(
apcm
->
codec
);
goto
powerdown
;
mutex_unlock
(
&
chip
->
open_mutex
);
return
err
;
}
}
snd_pcm_limit_hw_rates
(
runtime
);
snd_pcm_limit_hw_rates
(
runtime
);
/* sanity check */
/* sanity check */
...
@@ -858,10 +861,10 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
...
@@ -858,10 +861,10 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
snd_BUG_ON
(
!
runtime
->
hw
.
formats
)
||
snd_BUG_ON
(
!
runtime
->
hw
.
formats
)
||
snd_BUG_ON
(
!
runtime
->
hw
.
rates
))
{
snd_BUG_ON
(
!
runtime
->
hw
.
rates
))
{
azx_release_device
(
azx_dev
);
azx_release_device
(
azx_dev
);
if
(
hinfo
->
ops
.
close
)
hinfo
->
ops
.
close
(
hinfo
,
apcm
->
codec
,
substream
);
hinfo
->
ops
.
close
(
hinfo
,
apcm
->
codec
,
substream
);
snd_hda_power_down
(
apcm
->
codec
);
err
=
-
EINVAL
;
mutex_unlock
(
&
chip
->
open_mutex
);
goto
powerdown
;
return
-
EINVAL
;
}
}
/* disable LINK_ATIME timestamps for capture streams
/* disable LINK_ATIME timestamps for capture streams
...
@@ -880,6 +883,13 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
...
@@ -880,6 +883,13 @@ static int azx_pcm_open(struct snd_pcm_substream *substream)
snd_pcm_set_sync
(
substream
);
snd_pcm_set_sync
(
substream
);
mutex_unlock
(
&
chip
->
open_mutex
);
mutex_unlock
(
&
chip
->
open_mutex
);
return
0
;
return
0
;
powerdown:
snd_hda_power_down
(
apcm
->
codec
);
unlock:
mutex_unlock
(
&
chip
->
open_mutex
);
snd_hda_codec_pcm_put
(
apcm
->
info
);
return
err
;
}
}
static
int
azx_pcm_mmap
(
struct
snd_pcm_substream
*
substream
,
static
int
azx_pcm_mmap
(
struct
snd_pcm_substream
*
substream
,
...
@@ -974,14 +984,9 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
...
@@ -974,14 +984,9 @@ static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec,
*/
*/
static
int
azx_alloc_cmd_io
(
struct
azx
*
chip
)
static
int
azx_alloc_cmd_io
(
struct
azx
*
chip
)
{
{
int
err
;
/* single page (at least 4096 bytes) must suffice for both ringbuffes */
/* single page (at least 4096 bytes) must suffice for both ringbuffes */
err
=
chip
->
ops
->
dma_alloc_pages
(
chip
,
SNDRV_DMA_TYPE_DEV
,
return
chip
->
ops
->
dma_alloc_pages
(
chip
,
SNDRV_DMA_TYPE_DEV
,
PAGE_SIZE
,
&
chip
->
rb
);
PAGE_SIZE
,
&
chip
->
rb
);
if
(
err
<
0
)
dev_err
(
chip
->
card
->
dev
,
"cannot allocate CORB/RIRB
\n
"
);
return
err
;
}
}
static
void
azx_init_cmd_io
(
struct
azx
*
chip
)
static
void
azx_init_cmd_io
(
struct
azx
*
chip
)
...
@@ -1467,7 +1472,6 @@ static void azx_load_dsp_cleanup(struct hda_bus *bus,
...
@@ -1467,7 +1472,6 @@ static void azx_load_dsp_cleanup(struct hda_bus *bus,
int
azx_alloc_stream_pages
(
struct
azx
*
chip
)
int
azx_alloc_stream_pages
(
struct
azx
*
chip
)
{
{
int
i
,
err
;
int
i
,
err
;
struct
snd_card
*
card
=
chip
->
card
;
for
(
i
=
0
;
i
<
chip
->
num_streams
;
i
++
)
{
for
(
i
=
0
;
i
<
chip
->
num_streams
;
i
++
)
{
dsp_lock_init
(
&
chip
->
azx_dev
[
i
]);
dsp_lock_init
(
&
chip
->
azx_dev
[
i
]);
...
@@ -1475,18 +1479,14 @@ int azx_alloc_stream_pages(struct azx *chip)
...
@@ -1475,18 +1479,14 @@ int azx_alloc_stream_pages(struct azx *chip)
err
=
chip
->
ops
->
dma_alloc_pages
(
chip
,
SNDRV_DMA_TYPE_DEV
,
err
=
chip
->
ops
->
dma_alloc_pages
(
chip
,
SNDRV_DMA_TYPE_DEV
,
BDL_SIZE
,
BDL_SIZE
,
&
chip
->
azx_dev
[
i
].
bdl
);
&
chip
->
azx_dev
[
i
].
bdl
);
if
(
err
<
0
)
{
if
(
err
<
0
)
dev_err
(
card
->
dev
,
"cannot allocate BDL
\n
"
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
}
/* allocate memory for the position buffer */
/* allocate memory for the position buffer */
err
=
chip
->
ops
->
dma_alloc_pages
(
chip
,
SNDRV_DMA_TYPE_DEV
,
err
=
chip
->
ops
->
dma_alloc_pages
(
chip
,
SNDRV_DMA_TYPE_DEV
,
chip
->
num_streams
*
8
,
&
chip
->
posbuf
);
chip
->
num_streams
*
8
,
&
chip
->
posbuf
);
if
(
err
<
0
)
{
if
(
err
<
0
)
dev_err
(
card
->
dev
,
"cannot allocate posbuf
\n
"
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
/* allocate CORB/RIRB */
/* allocate CORB/RIRB */
err
=
azx_alloc_cmd_io
(
chip
);
err
=
azx_alloc_cmd_io
(
chip
);
...
@@ -1893,7 +1893,7 @@ int azx_probe_codecs(struct azx *chip, unsigned int max_slots)
...
@@ -1893,7 +1893,7 @@ int azx_probe_codecs(struct azx *chip, unsigned int max_slots)
for
(
c
=
0
;
c
<
max_slots
;
c
++
)
{
for
(
c
=
0
;
c
<
max_slots
;
c
++
)
{
if
((
chip
->
codec_mask
&
(
1
<<
c
))
&
chip
->
codec_probe_mask
)
{
if
((
chip
->
codec_mask
&
(
1
<<
c
))
&
chip
->
codec_probe_mask
)
{
struct
hda_codec
*
codec
;
struct
hda_codec
*
codec
;
err
=
snd_hda_codec_new
(
bus
,
c
,
&
codec
);
err
=
snd_hda_codec_new
(
bus
,
bus
->
card
,
c
,
&
codec
);
if
(
err
<
0
)
if
(
err
<
0
)
continue
;
continue
;
codec
->
jackpoll_interval
=
get_jackpoll_interval
(
chip
);
codec
->
jackpoll_interval
=
get_jackpoll_interval
(
chip
);
...
@@ -1966,30 +1966,5 @@ int azx_init_stream(struct azx *chip)
...
@@ -1966,30 +1966,5 @@ int azx_init_stream(struct azx *chip)
}
}
EXPORT_SYMBOL_GPL
(
azx_init_stream
);
EXPORT_SYMBOL_GPL
(
azx_init_stream
);
/*
* reboot notifier for hang-up problem at power-down
*/
static
int
azx_halt
(
struct
notifier_block
*
nb
,
unsigned
long
event
,
void
*
buf
)
{
struct
azx
*
chip
=
container_of
(
nb
,
struct
azx
,
reboot_notifier
);
snd_hda_bus_reboot_notify
(
chip
->
bus
);
azx_stop_chip
(
chip
);
return
NOTIFY_OK
;
}
void
azx_notifier_register
(
struct
azx
*
chip
)
{
chip
->
reboot_notifier
.
notifier_call
=
azx_halt
;
register_reboot_notifier
(
&
chip
->
reboot_notifier
);
}
EXPORT_SYMBOL_GPL
(
azx_notifier_register
);
void
azx_notifier_unregister
(
struct
azx
*
chip
)
{
if
(
chip
->
reboot_notifier
.
notifier_call
)
unregister_reboot_notifier
(
&
chip
->
reboot_notifier
);
}
EXPORT_SYMBOL_GPL
(
azx_notifier_unregister
);
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Common HDA driver functions"
);
MODULE_DESCRIPTION
(
"Common HDA driver functions"
);
sound/pci/hda/hda_controller.h
View file @
2a557a86
...
@@ -362,9 +362,6 @@ struct azx {
...
@@ -362,9 +362,6 @@ struct azx {
/* for debugging */
/* for debugging */
unsigned
int
last_cmd
[
AZX_MAX_CODECS
];
unsigned
int
last_cmd
[
AZX_MAX_CODECS
];
/* reboot notifier (for mysterious hangup problem at power-down) */
struct
notifier_block
reboot_notifier
;
#ifdef CONFIG_SND_HDA_DSP_LOADER
#ifdef CONFIG_SND_HDA_DSP_LOADER
struct
azx_dev
saved_azx_dev
;
struct
azx_dev
saved_azx_dev
;
#endif
#endif
...
@@ -437,7 +434,4 @@ int azx_probe_codecs(struct azx *chip, unsigned int max_slots);
...
@@ -437,7 +434,4 @@ int azx_probe_codecs(struct azx *chip, unsigned int max_slots);
int
azx_codec_configure
(
struct
azx
*
chip
);
int
azx_codec_configure
(
struct
azx
*
chip
);
int
azx_init_stream
(
struct
azx
*
chip
);
int
azx_init_stream
(
struct
azx
*
chip
);
void
azx_notifier_register
(
struct
azx
*
chip
);
void
azx_notifier_unregister
(
struct
azx
*
chip
);
#endif
/* __SOUND_HDA_CONTROLLER_H */
#endif
/* __SOUND_HDA_CONTROLLER_H */
sound/pci/hda/hda_generic.c
View file @
2a557a86
...
@@ -4675,7 +4675,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
...
@@ -4675,7 +4675,7 @@ int snd_hda_gen_build_controls(struct hda_codec *codec)
err
=
snd_hda_create_dig_out_ctls
(
codec
,
err
=
snd_hda_create_dig_out_ctls
(
codec
,
spec
->
multiout
.
dig_out_nid
,
spec
->
multiout
.
dig_out_nid
,
spec
->
multiout
.
dig_out_nid
,
spec
->
multiout
.
dig_out_nid
,
spec
->
pcm_rec
[
1
]
.
pcm_type
);
spec
->
pcm_rec
[
1
]
->
pcm_type
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
if
(
!
spec
->
no_analog
)
{
if
(
!
spec
->
no_analog
)
{
...
@@ -5146,20 +5146,20 @@ static void fill_pcm_stream_name(char *str, size_t len, const char *sfx,
...
@@ -5146,20 +5146,20 @@ static void fill_pcm_stream_name(char *str, size_t len, const char *sfx,
int
snd_hda_gen_build_pcms
(
struct
hda_codec
*
codec
)
int
snd_hda_gen_build_pcms
(
struct
hda_codec
*
codec
)
{
{
struct
hda_gen_spec
*
spec
=
codec
->
spec
;
struct
hda_gen_spec
*
spec
=
codec
->
spec
;
struct
hda_pcm
*
info
=
spec
->
pcm_rec
;
struct
hda_pcm
*
info
;
const
struct
hda_pcm_stream
*
p
;
const
struct
hda_pcm_stream
*
p
;
bool
have_multi_adcs
;
bool
have_multi_adcs
;
codec
->
num_pcms
=
1
;
codec
->
pcm_info
=
info
;
if
(
spec
->
no_analog
)
if
(
spec
->
no_analog
)
goto
skip_analog
;
goto
skip_analog
;
fill_pcm_stream_name
(
spec
->
stream_name_analog
,
fill_pcm_stream_name
(
spec
->
stream_name_analog
,
sizeof
(
spec
->
stream_name_analog
),
sizeof
(
spec
->
stream_name_analog
),
" Analog"
,
codec
->
chip_name
);
" Analog"
,
codec
->
chip_name
);
info
->
name
=
spec
->
stream_name_analog
;
info
=
snd_hda_codec_pcm_new
(
codec
,
"%s"
,
spec
->
stream_name_analog
);
if
(
!
info
)
return
-
ENOMEM
;
spec
->
pcm_rec
[
0
]
=
info
;
if
(
spec
->
multiout
.
num_dacs
>
0
)
{
if
(
spec
->
multiout
.
num_dacs
>
0
)
{
p
=
spec
->
stream_analog_playback
;
p
=
spec
->
stream_analog_playback
;
...
@@ -5192,10 +5192,12 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
...
@@ -5192,10 +5192,12 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
fill_pcm_stream_name
(
spec
->
stream_name_digital
,
fill_pcm_stream_name
(
spec
->
stream_name_digital
,
sizeof
(
spec
->
stream_name_digital
),
sizeof
(
spec
->
stream_name_digital
),
" Digital"
,
codec
->
chip_name
);
" Digital"
,
codec
->
chip_name
);
codec
->
num_pcms
=
2
;
info
=
snd_hda_codec_pcm_new
(
codec
,
"%s"
,
spec
->
stream_name_digital
);
if
(
!
info
)
return
-
ENOMEM
;
codec
->
slave_dig_outs
=
spec
->
multiout
.
slave_dig_outs
;
codec
->
slave_dig_outs
=
spec
->
multiout
.
slave_dig_outs
;
info
=
spec
->
pcm_rec
+
1
;
spec
->
pcm_rec
[
1
]
=
info
;
info
->
name
=
spec
->
stream_name_digital
;
if
(
spec
->
dig_out_type
)
if
(
spec
->
dig_out_type
)
info
->
pcm_type
=
spec
->
dig_out_type
;
info
->
pcm_type
=
spec
->
dig_out_type
;
else
else
...
@@ -5229,9 +5231,11 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
...
@@ -5229,9 +5231,11 @@ int snd_hda_gen_build_pcms(struct hda_codec *codec)
fill_pcm_stream_name
(
spec
->
stream_name_alt_analog
,
fill_pcm_stream_name
(
spec
->
stream_name_alt_analog
,
sizeof
(
spec
->
stream_name_alt_analog
),
sizeof
(
spec
->
stream_name_alt_analog
),
" Alt Analog"
,
codec
->
chip_name
);
" Alt Analog"
,
codec
->
chip_name
);
codec
->
num_pcms
=
3
;
info
=
snd_hda_codec_pcm_new
(
codec
,
"%s"
,
info
=
spec
->
pcm_rec
+
2
;
spec
->
stream_name_alt_analog
);
info
->
name
=
spec
->
stream_name_alt_analog
;
if
(
!
info
)
return
-
ENOMEM
;
spec
->
pcm_rec
[
2
]
=
info
;
if
(
spec
->
alt_dac_nid
)
{
if
(
spec
->
alt_dac_nid
)
{
p
=
spec
->
stream_analog_alt_playback
;
p
=
spec
->
stream_analog_alt_playback
;
if
(
!
p
)
if
(
!
p
)
...
...
sound/pci/hda/hda_generic.h
View file @
2a557a86
...
@@ -144,7 +144,7 @@ struct hda_gen_spec {
...
@@ -144,7 +144,7 @@ struct hda_gen_spec {
int
const_channel_count
;
/* channel count for all */
int
const_channel_count
;
/* channel count for all */
/* PCM information */
/* PCM information */
struct
hda_pcm
pcm_rec
[
3
];
/* used in build_pcms() */
struct
hda_pcm
*
pcm_rec
[
3
];
/* used in build_pcms() */
/* dynamic controls, init_verbs and input_mux */
/* dynamic controls, init_verbs and input_mux */
struct
auto_pin_cfg
autocfg
;
struct
auto_pin_cfg
autocfg
;
...
...
sound/pci/hda/hda_hwdep.c
View file @
2a557a86
...
@@ -101,7 +101,7 @@ int snd_hda_create_hwdep(struct hda_codec *codec)
...
@@ -101,7 +101,7 @@ int snd_hda_create_hwdep(struct hda_codec *codec)
int
err
;
int
err
;
sprintf
(
hwname
,
"HDA Codec %d"
,
codec
->
addr
);
sprintf
(
hwname
,
"HDA Codec %d"
,
codec
->
addr
);
err
=
snd_hwdep_new
(
codec
->
bus
->
card
,
hwname
,
codec
->
addr
,
&
hwdep
);
err
=
snd_hwdep_new
(
codec
->
card
,
hwname
,
codec
->
addr
,
&
hwdep
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
codec
->
hwdep
=
hwdep
;
codec
->
hwdep
=
hwdep
;
...
...
sound/pci/hda/hda_intel.c
View file @
2a557a86
...
@@ -528,10 +528,10 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
...
@@ -528,10 +528,10 @@ static int azx_position_check(struct azx *chip, struct azx_dev *azx_dev)
if
(
ok
==
1
)
{
if
(
ok
==
1
)
{
azx_dev
->
irq_pending
=
0
;
azx_dev
->
irq_pending
=
0
;
return
ok
;
return
ok
;
}
else
if
(
ok
==
0
&&
chip
->
bus
&&
chip
->
bus
->
workq
)
{
}
else
if
(
ok
==
0
)
{
/* bogus IRQ, process it later */
/* bogus IRQ, process it later */
azx_dev
->
irq_pending
=
1
;
azx_dev
->
irq_pending
=
1
;
queue_work
(
chip
->
bus
->
workq
,
&
hda
->
irq_pending_work
);
schedule_work
(
&
hda
->
irq_pending_work
);
}
}
return
0
;
return
0
;
}
}
...
@@ -893,8 +893,8 @@ static int azx_runtime_resume(struct device *dev)
...
@@ -893,8 +893,8 @@ static int azx_runtime_resume(struct device *dev)
if
(
status
&&
bus
)
{
if
(
status
&&
bus
)
{
list_for_each_entry
(
codec
,
&
bus
->
codec_list
,
list
)
list_for_each_entry
(
codec
,
&
bus
->
codec_list
,
list
)
if
(
status
&
(
1
<<
codec
->
addr
))
if
(
status
&
(
1
<<
codec
->
addr
))
queue_delayed_work
(
codec
->
bus
->
workq
,
schedule_delayed_work
(
&
codec
->
jackpoll_work
,
&
codec
->
jackpoll_work
,
codec
->
jackpoll_interval
);
codec
->
jackpoll_interval
);
}
}
/* disable controller Wake Up event*/
/* disable controller Wake Up event*/
...
@@ -1066,8 +1066,6 @@ static int azx_free(struct azx *chip)
...
@@ -1066,8 +1066,6 @@ static int azx_free(struct azx *chip)
azx_del_card_list
(
chip
);
azx_del_card_list
(
chip
);
azx_notifier_unregister
(
chip
);
hda
->
init_failed
=
1
;
/* to be sure */
hda
->
init_failed
=
1
;
/* to be sure */
complete_all
(
&
hda
->
probe_wait
);
complete_all
(
&
hda
->
probe_wait
);
...
@@ -1383,7 +1381,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
...
@@ -1383,7 +1381,6 @@ static int azx_create(struct snd_card *card, struct pci_dev *pci,
hda
=
kzalloc
(
sizeof
(
*
hda
),
GFP_KERNEL
);
hda
=
kzalloc
(
sizeof
(
*
hda
),
GFP_KERNEL
);
if
(
!
hda
)
{
if
(
!
hda
)
{
dev_err
(
card
->
dev
,
"Cannot allocate hda
\n
"
);
pci_disable_device
(
pci
);
pci_disable_device
(
pci
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
}
...
@@ -1564,10 +1561,8 @@ static int azx_first_init(struct azx *chip)
...
@@ -1564,10 +1561,8 @@ static int azx_first_init(struct azx *chip)
chip
->
num_streams
=
chip
->
playback_streams
+
chip
->
capture_streams
;
chip
->
num_streams
=
chip
->
playback_streams
+
chip
->
capture_streams
;
chip
->
azx_dev
=
kcalloc
(
chip
->
num_streams
,
sizeof
(
*
chip
->
azx_dev
),
chip
->
azx_dev
=
kcalloc
(
chip
->
num_streams
,
sizeof
(
*
chip
->
azx_dev
),
GFP_KERNEL
);
GFP_KERNEL
);
if
(
!
chip
->
azx_dev
)
{
if
(
!
chip
->
azx_dev
)
dev_err
(
card
->
dev
,
"cannot malloc azx_dev
\n
"
);
return
-
ENOMEM
;
return
-
ENOMEM
;
}
err
=
azx_alloc_stream_pages
(
chip
);
err
=
azx_alloc_stream_pages
(
chip
);
if
(
err
<
0
)
if
(
err
<
0
)
...
@@ -1898,22 +1893,11 @@ static int azx_probe_continue(struct azx *chip)
...
@@ -1898,22 +1893,11 @@ static int azx_probe_continue(struct azx *chip)
goto
out_free
;
goto
out_free
;
}
}
/* create PCM streams */
err
=
snd_hda_build_pcms
(
chip
->
bus
);
if
(
err
<
0
)
goto
out_free
;
/* create mixer controls */
err
=
snd_hda_build_controls
(
chip
->
bus
);
if
(
err
<
0
)
goto
out_free
;
err
=
snd_card_register
(
chip
->
card
);
err
=
snd_card_register
(
chip
->
card
);
if
(
err
<
0
)
if
(
err
<
0
)
goto
out_free
;
goto
out_free
;
chip
->
running
=
1
;
chip
->
running
=
1
;
azx_notifier_register
(
chip
);
azx_add_card_list
(
chip
);
azx_add_card_list
(
chip
);
snd_hda_set_power_save
(
chip
->
bus
,
power_save
*
1000
);
snd_hda_set_power_save
(
chip
->
bus
,
power_save
*
1000
);
if
(
azx_has_pm_runtime
(
chip
)
||
hda
->
use_vga_switcheroo
)
if
(
azx_has_pm_runtime
(
chip
)
||
hda
->
use_vga_switcheroo
)
...
@@ -1934,6 +1918,18 @@ static void azx_remove(struct pci_dev *pci)
...
@@ -1934,6 +1918,18 @@ static void azx_remove(struct pci_dev *pci)
snd_card_free
(
card
);
snd_card_free
(
card
);
}
}
static
void
azx_shutdown
(
struct
pci_dev
*
pci
)
{
struct
snd_card
*
card
=
pci_get_drvdata
(
pci
);
struct
azx
*
chip
;
if
(
!
card
)
return
;
chip
=
card
->
private_data
;
if
(
chip
&&
chip
->
running
)
azx_stop_chip
(
chip
);
}
/* PCI IDs */
/* PCI IDs */
static
const
struct
pci_device_id
azx_ids
[]
=
{
static
const
struct
pci_device_id
azx_ids
[]
=
{
/* CPT */
/* CPT */
...
@@ -2156,6 +2152,7 @@ static struct pci_driver azx_driver = {
...
@@ -2156,6 +2152,7 @@ static struct pci_driver azx_driver = {
.
id_table
=
azx_ids
,
.
id_table
=
azx_ids
,
.
probe
=
azx_probe
,
.
probe
=
azx_probe
,
.
remove
=
azx_remove
,
.
remove
=
azx_remove
,
.
shutdown
=
azx_shutdown
,
.
driver
=
{
.
driver
=
{
.
pm
=
AZX_PM_OPS
,
.
pm
=
AZX_PM_OPS
,
},
},
...
...
sound/pci/hda/hda_jack.c
View file @
2a557a86
...
@@ -135,7 +135,7 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec)
...
@@ -135,7 +135,7 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec)
#ifdef CONFIG_SND_HDA_INPUT_JACK
#ifdef CONFIG_SND_HDA_INPUT_JACK
/* free jack instances manually when clearing/reconfiguring */
/* free jack instances manually when clearing/reconfiguring */
if
(
!
codec
->
bus
->
shutdown
&&
jack
->
jack
)
if
(
!
codec
->
bus
->
shutdown
&&
jack
->
jack
)
snd_device_free
(
codec
->
bus
->
card
,
jack
->
jack
);
snd_device_free
(
codec
->
card
,
jack
->
jack
);
#endif
#endif
for
(
cb
=
jack
->
callback
;
cb
;
cb
=
next
)
{
for
(
cb
=
jack
->
callback
;
cb
;
cb
=
next
)
{
next
=
cb
->
next
;
next
=
cb
->
next
;
...
@@ -340,7 +340,7 @@ void snd_hda_jack_report_sync(struct hda_codec *codec)
...
@@ -340,7 +340,7 @@ void snd_hda_jack_report_sync(struct hda_codec *codec)
if
(
!
jack
->
kctl
||
jack
->
block_report
)
if
(
!
jack
->
kctl
||
jack
->
block_report
)
continue
;
continue
;
state
=
get_jack_plug_state
(
jack
->
pin_sense
);
state
=
get_jack_plug_state
(
jack
->
pin_sense
);
snd_kctl_jack_report
(
codec
->
bus
->
card
,
jack
->
kctl
,
state
);
snd_kctl_jack_report
(
codec
->
card
,
jack
->
kctl
,
state
);
#ifdef CONFIG_SND_HDA_INPUT_JACK
#ifdef CONFIG_SND_HDA_INPUT_JACK
if
(
jack
->
jack
)
if
(
jack
->
jack
)
snd_jack_report
(
jack
->
jack
,
snd_jack_report
(
jack
->
jack
,
...
@@ -412,11 +412,11 @@ static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
...
@@ -412,11 +412,11 @@ static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid,
jack
->
phantom_jack
=
!!
phantom_jack
;
jack
->
phantom_jack
=
!!
phantom_jack
;
state
=
snd_hda_jack_detect
(
codec
,
nid
);
state
=
snd_hda_jack_detect
(
codec
,
nid
);
snd_kctl_jack_report
(
codec
->
bus
->
card
,
kctl
,
state
);
snd_kctl_jack_report
(
codec
->
card
,
kctl
,
state
);
#ifdef CONFIG_SND_HDA_INPUT_JACK
#ifdef CONFIG_SND_HDA_INPUT_JACK
if
(
!
phantom_jack
)
{
if
(
!
phantom_jack
)
{
jack
->
type
=
get_input_jack_type
(
codec
,
nid
);
jack
->
type
=
get_input_jack_type
(
codec
,
nid
);
err
=
snd_jack_new
(
codec
->
bus
->
card
,
name
,
jack
->
type
,
err
=
snd_jack_new
(
codec
->
card
,
name
,
jack
->
type
,
&
jack
->
jack
);
&
jack
->
jack
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
...
...
sound/pci/hda/hda_local.h
View file @
2a557a86
...
@@ -150,6 +150,7 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
...
@@ -150,6 +150,7 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
#define snd_hda_add_vmaster(codec, name, tlv, slaves, suffix) \
#define snd_hda_add_vmaster(codec, name, tlv, slaves, suffix) \
__snd_hda_add_vmaster(codec, name, tlv, slaves, suffix, true, NULL)
__snd_hda_add_vmaster(codec, name, tlv, slaves, suffix, true, NULL)
int
snd_hda_codec_reset
(
struct
hda_codec
*
codec
);
int
snd_hda_codec_reset
(
struct
hda_codec
*
codec
);
void
snd_hda_codec_cleanup_for_unbind
(
struct
hda_codec
*
codec
);
enum
{
enum
{
HDA_VMUTE_OFF
,
HDA_VMUTE_OFF
,
...
...
sound/pci/hda/hda_proc.c
View file @
2a557a86
...
@@ -99,10 +99,10 @@ static void print_nid_array(struct snd_info_buffer *buffer,
...
@@ -99,10 +99,10 @@ static void print_nid_array(struct snd_info_buffer *buffer,
static
void
print_nid_pcms
(
struct
snd_info_buffer
*
buffer
,
static
void
print_nid_pcms
(
struct
snd_info_buffer
*
buffer
,
struct
hda_codec
*
codec
,
hda_nid_t
nid
)
struct
hda_codec
*
codec
,
hda_nid_t
nid
)
{
{
int
pcm
,
type
;
int
type
;
struct
hda_pcm
*
cpcm
;
struct
hda_pcm
*
cpcm
;
for
(
pcm
=
0
;
pcm
<
codec
->
num_pcms
;
pcm
++
)
{
cpcm
=
&
codec
->
pcm_info
[
pcm
];
list_for_each_entry
(
cpcm
,
&
codec
->
pcm_list_head
,
list
)
{
for
(
type
=
0
;
type
<
2
;
type
++
)
{
for
(
type
=
0
;
type
<
2
;
type
++
)
{
if
(
cpcm
->
stream
[
type
].
nid
!=
nid
||
cpcm
->
pcm
==
NULL
)
if
(
cpcm
->
stream
[
type
].
nid
!=
nid
||
cpcm
->
pcm
==
NULL
)
continue
;
continue
;
...
@@ -861,7 +861,7 @@ int snd_hda_codec_proc_new(struct hda_codec *codec)
...
@@ -861,7 +861,7 @@ int snd_hda_codec_proc_new(struct hda_codec *codec)
int
err
;
int
err
;
snprintf
(
name
,
sizeof
(
name
),
"codec#%d"
,
codec
->
addr
);
snprintf
(
name
,
sizeof
(
name
),
"codec#%d"
,
codec
->
addr
);
err
=
snd_card_proc_new
(
codec
->
bus
->
card
,
name
,
&
entry
);
err
=
snd_card_proc_new
(
codec
->
card
,
name
,
&
entry
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
...
...
sound/pci/hda/hda_sysfs.c
View file @
2a557a86
...
@@ -149,7 +149,7 @@ static int reconfig_codec(struct hda_codec *codec)
...
@@ -149,7 +149,7 @@ static int reconfig_codec(struct hda_codec *codec)
err
=
snd_hda_codec_build_controls
(
codec
);
err
=
snd_hda_codec_build_controls
(
codec
);
if
(
err
<
0
)
if
(
err
<
0
)
goto
error
;
goto
error
;
err
=
snd_card_register
(
codec
->
bus
->
card
);
err
=
snd_card_register
(
codec
->
card
);
error:
error:
snd_hda_power_down
(
codec
);
snd_hda_power_down
(
codec
);
return
err
;
return
err
;
...
...
sound/pci/hda/hda_tegra.c
View file @
2a557a86
...
@@ -290,8 +290,6 @@ static int hda_tegra_dev_free(struct snd_device *device)
...
@@ -290,8 +290,6 @@ static int hda_tegra_dev_free(struct snd_device *device)
int
i
;
int
i
;
struct
azx
*
chip
=
device
->
device_data
;
struct
azx
*
chip
=
device
->
device_data
;
azx_notifier_unregister
(
chip
);
if
(
chip
->
initialized
)
{
if
(
chip
->
initialized
)
{
for
(
i
=
0
;
i
<
chip
->
num_streams
;
i
++
)
for
(
i
=
0
;
i
<
chip
->
num_streams
;
i
++
)
azx_stream_stop
(
chip
,
&
chip
->
azx_dev
[
i
]);
azx_stream_stop
(
chip
,
&
chip
->
azx_dev
[
i
]);
...
@@ -497,22 +495,11 @@ static int hda_tegra_probe(struct platform_device *pdev)
...
@@ -497,22 +495,11 @@ static int hda_tegra_probe(struct platform_device *pdev)
if
(
err
<
0
)
if
(
err
<
0
)
goto
out_free
;
goto
out_free
;
/* create PCM streams */
err
=
snd_hda_build_pcms
(
chip
->
bus
);
if
(
err
<
0
)
goto
out_free
;
/* create mixer controls */
err
=
snd_hda_build_controls
(
chip
->
bus
);
if
(
err
<
0
)
goto
out_free
;
err
=
snd_card_register
(
chip
->
card
);
err
=
snd_card_register
(
chip
->
card
);
if
(
err
<
0
)
if
(
err
<
0
)
goto
out_free
;
goto
out_free
;
chip
->
running
=
1
;
chip
->
running
=
1
;
azx_notifier_register
(
chip
);
snd_hda_set_power_save
(
chip
->
bus
,
power_save
*
1000
);
snd_hda_set_power_save
(
chip
->
bus
,
power_save
*
1000
);
return
0
;
return
0
;
...
@@ -527,6 +514,18 @@ static int hda_tegra_remove(struct platform_device *pdev)
...
@@ -527,6 +514,18 @@ static int hda_tegra_remove(struct platform_device *pdev)
return
snd_card_free
(
dev_get_drvdata
(
&
pdev
->
dev
));
return
snd_card_free
(
dev_get_drvdata
(
&
pdev
->
dev
));
}
}
static
void
hda_tegra_shutdown
(
struct
platform_device
*
pdev
)
{
struct
snd_card
*
card
=
dev_get_drvdata
(
&
pdev
->
dev
);
struct
azx
*
chip
;
if
(
!
card
)
return
;
chip
=
card
->
private_data
;
if
(
chip
&&
chip
->
running
)
azx_stop_chip
(
chip
);
}
static
struct
platform_driver
tegra_platform_hda
=
{
static
struct
platform_driver
tegra_platform_hda
=
{
.
driver
=
{
.
driver
=
{
.
name
=
"tegra-hda"
,
.
name
=
"tegra-hda"
,
...
@@ -535,6 +534,7 @@ static struct platform_driver tegra_platform_hda = {
...
@@ -535,6 +534,7 @@ static struct platform_driver tegra_platform_hda = {
},
},
.
probe
=
hda_tegra_probe
,
.
probe
=
hda_tegra_probe
,
.
remove
=
hda_tegra_remove
,
.
remove
=
hda_tegra_remove
,
.
shutdown
=
hda_tegra_shutdown
,
};
};
module_platform_driver
(
tegra_platform_hda
);
module_platform_driver
(
tegra_platform_hda
);
...
...
sound/pci/hda/hda_trace.h
View file @
2a557a86
...
@@ -23,7 +23,7 @@ DECLARE_EVENT_CLASS(hda_cmd,
...
@@ -23,7 +23,7 @@ DECLARE_EVENT_CLASS(hda_cmd,
),
),
TP_fast_assign
(
TP_fast_assign
(
__entry
->
card
=
(
codec
)
->
bus
->
card
->
number
;
__entry
->
card
=
(
codec
)
->
card
->
number
;
__entry
->
addr
=
(
codec
)
->
addr
;
__entry
->
addr
=
(
codec
)
->
addr
;
__entry
->
val
=
(
val
);
__entry
->
val
=
(
val
);
),
),
...
@@ -71,7 +71,7 @@ DECLARE_EVENT_CLASS(hda_power,
...
@@ -71,7 +71,7 @@ DECLARE_EVENT_CLASS(hda_power,
),
),
TP_fast_assign
(
TP_fast_assign
(
__entry
->
card
=
(
codec
)
->
bus
->
card
->
number
;
__entry
->
card
=
(
codec
)
->
card
->
number
;
__entry
->
addr
=
(
codec
)
->
addr
;
__entry
->
addr
=
(
codec
)
->
addr
;
),
),
...
...
sound/pci/hda/patch_ca0132.c
View file @
2a557a86
...
@@ -719,7 +719,6 @@ struct ca0132_spec {
...
@@ -719,7 +719,6 @@ struct ca0132_spec {
unsigned
int
num_inputs
;
unsigned
int
num_inputs
;
hda_nid_t
shared_mic_nid
;
hda_nid_t
shared_mic_nid
;
hda_nid_t
shared_out_nid
;
hda_nid_t
shared_out_nid
;
struct
hda_pcm
pcm_rec
[
5
];
/* PCM information */
/* chip access */
/* chip access */
struct
mutex
chipio_mutex
;
/* chip access mutex */
struct
mutex
chipio_mutex
;
/* chip access mutex */
...
@@ -4036,12 +4035,11 @@ static struct hda_pcm_stream ca0132_pcm_digital_capture = {
...
@@ -4036,12 +4035,11 @@ static struct hda_pcm_stream ca0132_pcm_digital_capture = {
static
int
ca0132_build_pcms
(
struct
hda_codec
*
codec
)
static
int
ca0132_build_pcms
(
struct
hda_codec
*
codec
)
{
{
struct
ca0132_spec
*
spec
=
codec
->
spec
;
struct
ca0132_spec
*
spec
=
codec
->
spec
;
struct
hda_pcm
*
info
=
spec
->
pcm_rec
;
struct
hda_pcm
*
info
;
codec
->
pcm_info
=
info
;
info
=
snd_hda_codec_pcm_new
(
codec
,
"CA0132 Analog"
);
codec
->
num_pcms
=
0
;
if
(
!
info
)
return
-
ENOMEM
;
info
->
name
=
"CA0132 Analog"
;
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
]
=
ca0132_pcm_analog_playback
;
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
]
=
ca0132_pcm_analog_playback
;
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
].
nid
=
spec
->
dacs
[
0
];
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
].
nid
=
spec
->
dacs
[
0
];
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
].
channels_max
=
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
].
channels_max
=
...
@@ -4049,27 +4047,27 @@ static int ca0132_build_pcms(struct hda_codec *codec)
...
@@ -4049,27 +4047,27 @@ static int ca0132_build_pcms(struct hda_codec *codec)
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
]
=
ca0132_pcm_analog_capture
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
]
=
ca0132_pcm_analog_capture
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
].
substreams
=
1
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
].
substreams
=
1
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
].
nid
=
spec
->
adcs
[
0
];
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
].
nid
=
spec
->
adcs
[
0
];
codec
->
num_pcms
++
;
info
++
;
info
=
snd_hda_codec_pcm_new
(
codec
,
"CA0132 Analog Mic-In2"
);
info
->
name
=
"CA0132 Analog Mic-In2"
;
if
(
!
info
)
return
-
ENOMEM
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
]
=
ca0132_pcm_analog_capture
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
]
=
ca0132_pcm_analog_capture
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
].
substreams
=
1
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
].
substreams
=
1
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
].
nid
=
spec
->
adcs
[
1
];
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
].
nid
=
spec
->
adcs
[
1
];
codec
->
num_pcms
++
;
info
++
;
info
=
snd_hda_codec_pcm_new
(
codec
,
"CA0132 What U Hear"
);
info
->
name
=
"CA0132 What U Hear"
;
if
(
!
info
)
return
-
ENOMEM
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
]
=
ca0132_pcm_analog_capture
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
]
=
ca0132_pcm_analog_capture
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
].
substreams
=
1
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
].
substreams
=
1
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
].
nid
=
spec
->
adcs
[
2
];
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
].
nid
=
spec
->
adcs
[
2
];
codec
->
num_pcms
++
;
if
(
!
spec
->
dig_out
&&
!
spec
->
dig_in
)
if
(
!
spec
->
dig_out
&&
!
spec
->
dig_in
)
return
0
;
return
0
;
info
++
;
info
=
snd_hda_codec_pcm_new
(
codec
,
"CA0132 Digital"
);
info
->
name
=
"CA0132 Digital"
;
if
(
!
info
)
return
-
ENOMEM
;
info
->
pcm_type
=
HDA_PCM_TYPE_SPDIF
;
info
->
pcm_type
=
HDA_PCM_TYPE_SPDIF
;
if
(
spec
->
dig_out
)
{
if
(
spec
->
dig_out
)
{
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
]
=
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
]
=
...
@@ -4081,7 +4079,6 @@ static int ca0132_build_pcms(struct hda_codec *codec)
...
@@ -4081,7 +4079,6 @@ static int ca0132_build_pcms(struct hda_codec *codec)
ca0132_pcm_digital_capture
;
ca0132_pcm_digital_capture
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
].
nid
=
spec
->
dig_in
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
].
nid
=
spec
->
dig_in
;
}
}
codec
->
num_pcms
++
;
return
0
;
return
0
;
}
}
...
@@ -4352,7 +4349,7 @@ static bool ca0132_download_dsp_images(struct hda_codec *codec)
...
@@ -4352,7 +4349,7 @@ static bool ca0132_download_dsp_images(struct hda_codec *codec)
const
struct
dsp_image_seg
*
dsp_os_image
;
const
struct
dsp_image_seg
*
dsp_os_image
;
const
struct
firmware
*
fw_entry
;
const
struct
firmware
*
fw_entry
;
if
(
request_firmware
(
&
fw_entry
,
EFX_FILE
,
codec
->
bus
->
card
->
dev
)
!=
0
)
if
(
request_firmware
(
&
fw_entry
,
EFX_FILE
,
codec
->
card
->
dev
)
!=
0
)
return
false
;
return
false
;
dsp_os_image
=
(
struct
dsp_image_seg
*
)(
fw_entry
->
data
);
dsp_os_image
=
(
struct
dsp_image_seg
*
)(
fw_entry
->
data
);
...
@@ -4413,8 +4410,7 @@ static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
...
@@ -4413,8 +4410,7 @@ static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
* state machine run.
* state machine run.
*/
*/
cancel_delayed_work_sync
(
&
spec
->
unsol_hp_work
);
cancel_delayed_work_sync
(
&
spec
->
unsol_hp_work
);
queue_delayed_work
(
codec
->
bus
->
workq
,
&
spec
->
unsol_hp_work
,
schedule_delayed_work
(
&
spec
->
unsol_hp_work
,
msecs_to_jiffies
(
500
));
msecs_to_jiffies
(
500
));
cb
->
tbl
->
block_report
=
1
;
cb
->
tbl
->
block_report
=
1
;
}
}
...
...
sound/pci/hda/patch_hdmi.c
View file @
2a557a86
...
@@ -86,7 +86,6 @@ struct hdmi_spec_per_pin {
...
@@ -86,7 +86,6 @@ struct hdmi_spec_per_pin {
bool
non_pcm
;
bool
non_pcm
;
bool
chmap_set
;
/* channel-map override by ALSA API? */
bool
chmap_set
;
/* channel-map override by ALSA API? */
unsigned
char
chmap
[
8
];
/* ALSA API channel-map */
unsigned
char
chmap
[
8
];
/* ALSA API channel-map */
char
pcm_name
[
8
];
/* filled in build_pcm callbacks */
#ifdef CONFIG_PROC_FS
#ifdef CONFIG_PROC_FS
struct
snd_info_entry
*
proc_entry
;
struct
snd_info_entry
*
proc_entry
;
#endif
#endif
...
@@ -132,7 +131,7 @@ struct hdmi_spec {
...
@@ -132,7 +131,7 @@ struct hdmi_spec {
int
num_pins
;
int
num_pins
;
struct
snd_array
pins
;
/* struct hdmi_spec_per_pin */
struct
snd_array
pins
;
/* struct hdmi_spec_per_pin */
struct
snd_array
pcm_rec
;
/* struct hda_pcm */
struct
hda_pcm
*
pcm_rec
[
16
];
unsigned
int
channels_max
;
/* max over all cvts */
unsigned
int
channels_max
;
/* max over all cvts */
struct
hdmi_eld
temp_eld
;
struct
hdmi_eld
temp_eld
;
...
@@ -355,8 +354,7 @@ static struct cea_channel_speaker_allocation channel_allocations[] = {
...
@@ -355,8 +354,7 @@ static struct cea_channel_speaker_allocation channel_allocations[] = {
((struct hdmi_spec_per_pin *)snd_array_elem(&spec->pins, idx))
((struct hdmi_spec_per_pin *)snd_array_elem(&spec->pins, idx))
#define get_cvt(spec, idx) \
#define get_cvt(spec, idx) \
((struct hdmi_spec_per_cvt *)snd_array_elem(&spec->cvts, idx))
((struct hdmi_spec_per_cvt *)snd_array_elem(&spec->cvts, idx))
#define get_pcm_rec(spec, idx) \
#define get_pcm_rec(spec, idx) ((spec)->pcm_rec[idx])
((struct hda_pcm *)snd_array_elem(&spec->pcm_rec, idx))
static
int
pin_nid_to_pin_index
(
struct
hda_codec
*
codec
,
hda_nid_t
pin_nid
)
static
int
pin_nid_to_pin_index
(
struct
hda_codec
*
codec
,
hda_nid_t
pin_nid
)
{
{
...
@@ -579,7 +577,7 @@ static int eld_proc_new(struct hdmi_spec_per_pin *per_pin, int index)
...
@@ -579,7 +577,7 @@ static int eld_proc_new(struct hdmi_spec_per_pin *per_pin, int index)
int
err
;
int
err
;
snprintf
(
name
,
sizeof
(
name
),
"eld#%d.%d"
,
codec
->
addr
,
index
);
snprintf
(
name
,
sizeof
(
name
),
"eld#%d.%d"
,
codec
->
addr
,
index
);
err
=
snd_card_proc_new
(
codec
->
bus
->
card
,
name
,
&
entry
);
err
=
snd_card_proc_new
(
codec
->
card
,
name
,
&
entry
);
if
(
err
<
0
)
if
(
err
<
0
)
return
err
;
return
err
;
...
@@ -594,7 +592,7 @@ static int eld_proc_new(struct hdmi_spec_per_pin *per_pin, int index)
...
@@ -594,7 +592,7 @@ static int eld_proc_new(struct hdmi_spec_per_pin *per_pin, int index)
static
void
eld_proc_free
(
struct
hdmi_spec_per_pin
*
per_pin
)
static
void
eld_proc_free
(
struct
hdmi_spec_per_pin
*
per_pin
)
{
{
if
(
!
per_pin
->
codec
->
bus
->
shutdown
&&
per_pin
->
proc_entry
)
{
if
(
!
per_pin
->
codec
->
bus
->
shutdown
&&
per_pin
->
proc_entry
)
{
snd_device_free
(
per_pin
->
codec
->
bus
->
card
,
per_pin
->
proc_entry
);
snd_device_free
(
per_pin
->
codec
->
card
,
per_pin
->
proc_entry
);
per_pin
->
proc_entry
=
NULL
;
per_pin
->
proc_entry
=
NULL
;
}
}
}
}
...
@@ -1578,8 +1576,7 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
...
@@ -1578,8 +1576,7 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
update_eld
=
true
;
update_eld
=
true
;
}
}
else
if
(
repoll
)
{
else
if
(
repoll
)
{
queue_delayed_work
(
codec
->
bus
->
workq
,
schedule_delayed_work
(
&
per_pin
->
work
,
&
per_pin
->
work
,
msecs_to_jiffies
(
300
));
msecs_to_jiffies
(
300
));
goto
unlock
;
goto
unlock
;
}
}
...
@@ -1624,7 +1621,7 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
...
@@ -1624,7 +1621,7 @@ static bool hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
}
}
if
(
eld_changed
)
if
(
eld_changed
)
snd_ctl_notify
(
codec
->
bus
->
card
,
snd_ctl_notify
(
codec
->
card
,
SNDRV_CTL_EVENT_MASK_VALUE
|
SNDRV_CTL_EVENT_MASK_INFO
,
SNDRV_CTL_EVENT_MASK_VALUE
|
SNDRV_CTL_EVENT_MASK_INFO
,
&
per_pin
->
eld_ctl
->
id
);
&
per_pin
->
eld_ctl
->
id
);
unlock:
unlock:
...
@@ -2056,11 +2053,10 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
...
@@ -2056,11 +2053,10 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
struct
hdmi_spec_per_pin
*
per_pin
;
struct
hdmi_spec_per_pin
*
per_pin
;
per_pin
=
get_pin
(
spec
,
pin_idx
);
per_pin
=
get_pin
(
spec
,
pin_idx
);
sprintf
(
per_pin
->
pcm_name
,
"HDMI %d"
,
pin_idx
);
info
=
snd_hda_codec_pcm_new
(
codec
,
"HDMI %d"
,
pin_idx
);
info
=
snd_array_new
(
&
spec
->
pcm_rec
);
if
(
!
info
)
if
(
!
info
)
return
-
ENOMEM
;
return
-
ENOMEM
;
info
->
name
=
per_pin
->
pcm_name
;
spec
->
pcm_rec
[
pin_idx
]
=
info
;
info
->
pcm_type
=
HDA_PCM_TYPE_HDMI
;
info
->
pcm_type
=
HDA_PCM_TYPE_HDMI
;
info
->
own_chmap
=
true
;
info
->
own_chmap
=
true
;
...
@@ -2070,9 +2066,6 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
...
@@ -2070,9 +2066,6 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
/* other pstr fields are set in open */
/* other pstr fields are set in open */
}
}
codec
->
num_pcms
=
spec
->
num_pins
;
codec
->
pcm_info
=
spec
->
pcm_rec
.
list
;
return
0
;
return
0
;
}
}
...
@@ -2125,13 +2118,15 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
...
@@ -2125,13 +2118,15 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
/* add channel maps */
/* add channel maps */
for
(
pin_idx
=
0
;
pin_idx
<
spec
->
num_pins
;
pin_idx
++
)
{
for
(
pin_idx
=
0
;
pin_idx
<
spec
->
num_pins
;
pin_idx
++
)
{
struct
hda_pcm
*
pcm
;
struct
snd_pcm_chmap
*
chmap
;
struct
snd_pcm_chmap
*
chmap
;
struct
snd_kcontrol
*
kctl
;
struct
snd_kcontrol
*
kctl
;
int
i
;
int
i
;
if
(
!
codec
->
pcm_info
[
pin_idx
].
pcm
)
pcm
=
spec
->
pcm_rec
[
pin_idx
];
if
(
!
pcm
||
!
pcm
->
pcm
)
break
;
break
;
err
=
snd_pcm_add_chmap_ctls
(
codec
->
pcm_info
[
pin_idx
].
pcm
,
err
=
snd_pcm_add_chmap_ctls
(
pcm
->
pcm
,
SNDRV_PCM_STREAM_PLAYBACK
,
SNDRV_PCM_STREAM_PLAYBACK
,
NULL
,
0
,
pin_idx
,
&
chmap
);
NULL
,
0
,
pin_idx
,
&
chmap
);
if
(
err
<
0
)
if
(
err
<
0
)
...
@@ -2186,14 +2181,12 @@ static void hdmi_array_init(struct hdmi_spec *spec, int nums)
...
@@ -2186,14 +2181,12 @@ static void hdmi_array_init(struct hdmi_spec *spec, int nums)
{
{
snd_array_init
(
&
spec
->
pins
,
sizeof
(
struct
hdmi_spec_per_pin
),
nums
);
snd_array_init
(
&
spec
->
pins
,
sizeof
(
struct
hdmi_spec_per_pin
),
nums
);
snd_array_init
(
&
spec
->
cvts
,
sizeof
(
struct
hdmi_spec_per_cvt
),
nums
);
snd_array_init
(
&
spec
->
cvts
,
sizeof
(
struct
hdmi_spec_per_cvt
),
nums
);
snd_array_init
(
&
spec
->
pcm_rec
,
sizeof
(
struct
hda_pcm
),
nums
);
}
}
static
void
hdmi_array_free
(
struct
hdmi_spec
*
spec
)
static
void
hdmi_array_free
(
struct
hdmi_spec
*
spec
)
{
{
snd_array_free
(
&
spec
->
pins
);
snd_array_free
(
&
spec
->
pins
);
snd_array_free
(
&
spec
->
cvts
);
snd_array_free
(
&
spec
->
cvts
);
snd_array_free
(
&
spec
->
pcm_rec
);
}
}
static
void
generic_hdmi_free
(
struct
hda_codec
*
codec
)
static
void
generic_hdmi_free
(
struct
hda_codec
*
codec
)
...
@@ -2204,11 +2197,10 @@ static void generic_hdmi_free(struct hda_codec *codec)
...
@@ -2204,11 +2197,10 @@ static void generic_hdmi_free(struct hda_codec *codec)
for
(
pin_idx
=
0
;
pin_idx
<
spec
->
num_pins
;
pin_idx
++
)
{
for
(
pin_idx
=
0
;
pin_idx
<
spec
->
num_pins
;
pin_idx
++
)
{
struct
hdmi_spec_per_pin
*
per_pin
=
get_pin
(
spec
,
pin_idx
);
struct
hdmi_spec_per_pin
*
per_pin
=
get_pin
(
spec
,
pin_idx
);
cancel_delayed_work
(
&
per_pin
->
work
);
cancel_delayed_work
_sync
(
&
per_pin
->
work
);
eld_proc_free
(
per_pin
);
eld_proc_free
(
per_pin
);
}
}
flush_workqueue
(
codec
->
bus
->
workq
);
hdmi_array_free
(
spec
);
hdmi_array_free
(
spec
);
kfree
(
spec
);
kfree
(
spec
);
}
}
...
@@ -2381,11 +2373,10 @@ static int simple_playback_build_pcms(struct hda_codec *codec)
...
@@ -2381,11 +2373,10 @@ static int simple_playback_build_pcms(struct hda_codec *codec)
chans
=
get_wcaps
(
codec
,
per_cvt
->
cvt_nid
);
chans
=
get_wcaps
(
codec
,
per_cvt
->
cvt_nid
);
chans
=
get_wcaps_channels
(
chans
);
chans
=
get_wcaps_channels
(
chans
);
info
=
snd_
array_new
(
&
spec
->
pcm_rec
);
info
=
snd_
hda_codec_pcm_new
(
codec
,
"HDMI 0"
);
if
(
!
info
)
if
(
!
info
)
return
-
ENOMEM
;
return
-
ENOMEM
;
info
->
name
=
get_pin
(
spec
,
0
)
->
pcm_name
;
spec
->
pcm_rec
[
0
]
=
info
;
sprintf
(
info
->
name
,
"HDMI 0"
);
info
->
pcm_type
=
HDA_PCM_TYPE_HDMI
;
info
->
pcm_type
=
HDA_PCM_TYPE_HDMI
;
pstr
=
&
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
];
pstr
=
&
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
];
*
pstr
=
spec
->
pcm_playback
;
*
pstr
=
spec
->
pcm_playback
;
...
@@ -2393,9 +2384,6 @@ static int simple_playback_build_pcms(struct hda_codec *codec)
...
@@ -2393,9 +2384,6 @@ static int simple_playback_build_pcms(struct hda_codec *codec)
if
(
pstr
->
channels_max
<=
2
&&
chans
&&
chans
<=
16
)
if
(
pstr
->
channels_max
<=
2
&&
chans
&&
chans
<=
16
)
pstr
->
channels_max
=
chans
;
pstr
->
channels_max
=
chans
;
codec
->
num_pcms
=
1
;
codec
->
pcm_info
=
info
;
return
0
;
return
0
;
}
}
...
...
sound/pci/hda/patch_realtek.c
View file @
2a557a86
...
@@ -5850,7 +5850,7 @@ static void alc_fixup_bass_chmap(struct hda_codec *codec,
...
@@ -5850,7 +5850,7 @@ static void alc_fixup_bass_chmap(struct hda_codec *codec,
{
{
if
(
action
==
HDA_FIXUP_ACT_BUILD
)
{
if
(
action
==
HDA_FIXUP_ACT_BUILD
)
{
struct
alc_spec
*
spec
=
codec
->
spec
;
struct
alc_spec
*
spec
=
codec
->
spec
;
spec
->
gen
.
pcm_rec
[
0
]
.
stream
[
0
].
chmap
=
asus_pcm_2_1_chmaps
;
spec
->
gen
.
pcm_rec
[
0
]
->
stream
[
0
].
chmap
=
asus_pcm_2_1_chmaps
;
}
}
}
}
...
...
sound/pci/hda/patch_si3054.c
View file @
2a557a86
...
@@ -83,7 +83,6 @@
...
@@ -83,7 +83,6 @@
struct
si3054_spec
{
struct
si3054_spec
{
unsigned
international
;
unsigned
international
;
struct
hda_pcm
pcm
;
};
};
...
@@ -199,11 +198,11 @@ static const struct hda_pcm_stream si3054_pcm = {
...
@@ -199,11 +198,11 @@ static const struct hda_pcm_stream si3054_pcm = {
static
int
si3054_build_pcms
(
struct
hda_codec
*
codec
)
static
int
si3054_build_pcms
(
struct
hda_codec
*
codec
)
{
{
struct
si3054_spec
*
spec
=
codec
->
spec
;
struct
hda_pcm
*
info
;
struct
hda_pcm
*
info
=
&
spec
->
pcm
;
codec
->
num_pcms
=
1
;
info
=
snd_hda_codec_pcm_new
(
codec
,
"Si3054 Modem"
)
;
codec
->
pcm_info
=
info
;
if
(
!
info
)
info
->
name
=
"Si3054 Modem"
;
return
-
ENOMEM
;
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
]
=
si3054_pcm
;
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
]
=
si3054_pcm
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
]
=
si3054_pcm
;
info
->
stream
[
SNDRV_PCM_STREAM_CAPTURE
]
=
si3054_pcm
;
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
].
nid
=
codec
->
mfg
;
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
].
nid
=
codec
->
mfg
;
...
...
sound/pci/hda/patch_via.c
View file @
2a557a86
...
@@ -222,8 +222,7 @@ static void vt1708_update_hp_work(struct hda_codec *codec)
...
@@ -222,8 +222,7 @@ static void vt1708_update_hp_work(struct hda_codec *codec)
if
(
!
spec
->
hp_work_active
)
{
if
(
!
spec
->
hp_work_active
)
{
codec
->
jackpoll_interval
=
msecs_to_jiffies
(
100
);
codec
->
jackpoll_interval
=
msecs_to_jiffies
(
100
);
snd_hda_codec_write
(
codec
,
0x1
,
0
,
0xf81
,
0
);
snd_hda_codec_write
(
codec
,
0x1
,
0
,
0xf81
,
0
);
queue_delayed_work
(
codec
->
bus
->
workq
,
schedule_delayed_work
(
&
codec
->
jackpoll_work
,
0
);
&
codec
->
jackpoll_work
,
0
);
spec
->
hp_work_active
=
true
;
spec
->
hp_work_active
=
true
;
}
}
}
else
if
(
!
hp_detect_with_aa
(
codec
))
}
else
if
(
!
hp_detect_with_aa
(
codec
))
...
@@ -683,8 +682,10 @@ static int vt1708_build_pcms(struct hda_codec *codec)
...
@@ -683,8 +682,10 @@ static int vt1708_build_pcms(struct hda_codec *codec)
* 24bit samples are used. Until any workaround is found,
* 24bit samples are used. Until any workaround is found,
* disable the 24bit format, so far.
* disable the 24bit format, so far.
*/
*/
for
(
i
=
0
;
i
<
codec
->
num_pcms
;
i
++
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
spec
->
gen
.
pcm_rec
);
i
++
)
{
struct
hda_pcm
*
info
=
&
spec
->
gen
.
pcm_rec
[
i
];
struct
hda_pcm
*
info
=
spec
->
gen
.
pcm_rec
[
i
];
if
(
!
info
)
continue
;
if
(
!
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
].
substreams
||
if
(
!
info
->
stream
[
SNDRV_PCM_STREAM_PLAYBACK
].
substreams
||
info
->
pcm_type
!=
HDA_PCM_TYPE_AUDIO
)
info
->
pcm_type
!=
HDA_PCM_TYPE_AUDIO
)
continue
;
continue
;
...
@@ -907,16 +908,16 @@ static int patch_vt1708S(struct hda_codec *codec)
...
@@ -907,16 +908,16 @@ static int patch_vt1708S(struct hda_codec *codec)
if
(
get_codec_type
(
codec
)
==
VT1708BCE
)
{
if
(
get_codec_type
(
codec
)
==
VT1708BCE
)
{
kfree
(
codec
->
chip_name
);
kfree
(
codec
->
chip_name
);
codec
->
chip_name
=
kstrdup
(
"VT1708BCE"
,
GFP_KERNEL
);
codec
->
chip_name
=
kstrdup
(
"VT1708BCE"
,
GFP_KERNEL
);
snprintf
(
codec
->
bus
->
card
->
mixername
,
snprintf
(
codec
->
card
->
mixername
,
sizeof
(
codec
->
bus
->
card
->
mixername
),
sizeof
(
codec
->
card
->
mixername
),
"%s %s"
,
codec
->
vendor_name
,
codec
->
chip_name
);
"%s %s"
,
codec
->
vendor_name
,
codec
->
chip_name
);
}
}
/* correct names for VT1705 */
/* correct names for VT1705 */
if
(
codec
->
vendor_id
==
0x11064397
)
{
if
(
codec
->
vendor_id
==
0x11064397
)
{
kfree
(
codec
->
chip_name
);
kfree
(
codec
->
chip_name
);
codec
->
chip_name
=
kstrdup
(
"VT1705"
,
GFP_KERNEL
);
codec
->
chip_name
=
kstrdup
(
"VT1705"
,
GFP_KERNEL
);
snprintf
(
codec
->
bus
->
card
->
mixername
,
snprintf
(
codec
->
card
->
mixername
,
sizeof
(
codec
->
bus
->
card
->
mixername
),
sizeof
(
codec
->
card
->
mixername
),
"%s %s"
,
codec
->
vendor_name
,
codec
->
chip_name
);
"%s %s"
,
codec
->
vendor_name
,
codec
->
chip_name
);
}
}
...
...
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