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
515511a7
Commit
515511a7
authored
May 13, 2016
by
Mark Brown
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'asoc/topic/hdmi' into asoc-next
parents
180bc41a
8f658815
Changes
13
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
969 additions
and
41 deletions
+969
-41
include/sound/hdmi-codec.h
include/sound/hdmi-codec.h
+100
-0
include/sound/pcm_iec958.h
include/sound/pcm_iec958.h
+2
-0
sound/core/pcm_iec958.c
sound/core/pcm_iec958.c
+48
-17
sound/hda/local.h
sound/hda/local.h
+10
-0
sound/soc/codecs/Kconfig
sound/soc/codecs/Kconfig
+6
-0
sound/soc/codecs/Makefile
sound/soc/codecs/Makefile
+2
-0
sound/soc/codecs/hdac_hdmi.c
sound/soc/codecs/hdac_hdmi.c
+154
-9
sound/soc/codecs/hdmi-codec.c
sound/soc/codecs/hdmi-codec.c
+432
-0
sound/soc/intel/boards/skl_nau88l25_max98357a.c
sound/soc/intel/boards/skl_nau88l25_max98357a.c
+71
-3
sound/soc/intel/boards/skl_nau88l25_ssm4567.c
sound/soc/intel/boards/skl_nau88l25_ssm4567.c
+70
-3
sound/soc/intel/boards/skl_rt286.c
sound/soc/intel/boards/skl_rt286.c
+47
-1
sound/soc/intel/skylake/skl-pcm.c
sound/soc/intel/skylake/skl-pcm.c
+7
-7
sound/soc/intel/skylake/skl-topology.c
sound/soc/intel/skylake/skl-topology.c
+20
-1
No files found.
include/sound/hdmi-codec.h
0 → 100644
View file @
515511a7
/*
* hdmi-codec.h - HDMI Codec driver API
*
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com
*
* Author: Jyri Sarha <jsarha@ti.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#ifndef __HDMI_CODEC_H__
#define __HDMI_CODEC_H__
#include <linux/hdmi.h>
#include <drm/drm_edid.h>
#include <sound/asoundef.h>
#include <uapi/sound/asound.h>
/*
* Protocol between ASoC cpu-dai and HDMI-encoder
*/
struct
hdmi_codec_daifmt
{
enum
{
HDMI_I2S
,
HDMI_RIGHT_J
,
HDMI_LEFT_J
,
HDMI_DSP_A
,
HDMI_DSP_B
,
HDMI_AC97
,
HDMI_SPDIF
,
}
fmt
;
int
bit_clk_inv
:
1
;
int
frame_clk_inv
:
1
;
int
bit_clk_master
:
1
;
int
frame_clk_master
:
1
;
};
/*
* HDMI audio parameters
*/
struct
hdmi_codec_params
{
struct
hdmi_audio_infoframe
cea
;
struct
snd_aes_iec958
iec
;
int
sample_rate
;
int
sample_width
;
int
channels
;
};
struct
hdmi_codec_ops
{
/*
* Called when ASoC starts an audio stream setup.
* Optional
*/
int
(
*
audio_startup
)(
struct
device
*
dev
);
/*
* Configures HDMI-encoder for audio stream.
* Mandatory
*/
int
(
*
hw_params
)(
struct
device
*
dev
,
struct
hdmi_codec_daifmt
*
fmt
,
struct
hdmi_codec_params
*
hparms
);
/*
* Shuts down the audio stream.
* Mandatory
*/
void
(
*
audio_shutdown
)(
struct
device
*
dev
);
/*
* Mute/unmute HDMI audio stream.
* Optional
*/
int
(
*
digital_mute
)(
struct
device
*
dev
,
bool
enable
);
/*
* Provides EDID-Like-Data from connected HDMI device.
* Optional
*/
int
(
*
get_eld
)(
struct
device
*
dev
,
uint8_t
*
buf
,
size_t
len
);
};
/* HDMI codec initalization data */
struct
hdmi_codec_pdata
{
const
struct
hdmi_codec_ops
*
ops
;
uint
i2s
:
1
;
uint
spdif
:
1
;
int
max_i2s_channels
;
};
#define HDMI_CODEC_DRV_NAME "hdmi-audio-codec"
#endif
/* __HDMI_CODEC_H__ */
include/sound/pcm_iec958.h
View file @
515511a7
...
@@ -6,4 +6,6 @@
...
@@ -6,4 +6,6 @@
int
snd_pcm_create_iec958_consumer
(
struct
snd_pcm_runtime
*
runtime
,
u8
*
cs
,
int
snd_pcm_create_iec958_consumer
(
struct
snd_pcm_runtime
*
runtime
,
u8
*
cs
,
size_t
len
);
size_t
len
);
int
snd_pcm_create_iec958_consumer_hw_params
(
struct
snd_pcm_hw_params
*
params
,
u8
*
cs
,
size_t
len
);
#endif
#endif
sound/core/pcm_iec958.c
View file @
515511a7
...
@@ -9,30 +9,18 @@
...
@@ -9,30 +9,18 @@
#include <linux/types.h>
#include <linux/types.h>
#include <sound/asoundef.h>
#include <sound/asoundef.h>
#include <sound/pcm.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/pcm_iec958.h>
#include <sound/pcm_iec958.h>
/**
static
int
create_iec958_consumer
(
uint
rate
,
uint
sample_width
,
* snd_pcm_create_iec958_consumer - create consumer format IEC958 channel status
u8
*
cs
,
size_t
len
)
* @runtime: pcm runtime structure with ->rate filled in
* @cs: channel status buffer, at least four bytes
* @len: length of channel status buffer
*
* Create the consumer format channel status data in @cs of maximum size
* @len corresponding to the parameters of the PCM runtime @runtime.
*
* Drivers may wish to tweak the contents of the buffer after creation.
*
* Returns: length of buffer, or negative error code if something failed.
*/
int
snd_pcm_create_iec958_consumer
(
struct
snd_pcm_runtime
*
runtime
,
u8
*
cs
,
size_t
len
)
{
{
unsigned
int
fs
,
ws
;
unsigned
int
fs
,
ws
;
if
(
len
<
4
)
if
(
len
<
4
)
return
-
EINVAL
;
return
-
EINVAL
;
switch
(
r
untime
->
r
ate
)
{
switch
(
rate
)
{
case
32000
:
case
32000
:
fs
=
IEC958_AES3_CON_FS_32000
;
fs
=
IEC958_AES3_CON_FS_32000
;
break
;
break
;
...
@@ -59,7 +47,7 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
...
@@ -59,7 +47,7 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
}
}
if
(
len
>
4
)
{
if
(
len
>
4
)
{
switch
(
s
nd_pcm_format_width
(
runtime
->
format
)
)
{
switch
(
s
ample_width
)
{
case
16
:
case
16
:
ws
=
IEC958_AES4_CON_WORDLEN_20_16
;
ws
=
IEC958_AES4_CON_WORDLEN_20_16
;
break
;
break
;
...
@@ -71,6 +59,7 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
...
@@ -71,6 +59,7 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
IEC958_AES4_CON_MAX_WORDLEN_24
;
IEC958_AES4_CON_MAX_WORDLEN_24
;
break
;
break
;
case
24
:
case
24
:
case
32
:
/* Assume 24-bit width for 32-bit samples. */
ws
=
IEC958_AES4_CON_WORDLEN_24_20
|
ws
=
IEC958_AES4_CON_WORDLEN_24_20
|
IEC958_AES4_CON_MAX_WORDLEN_24
;
IEC958_AES4_CON_MAX_WORDLEN_24
;
break
;
break
;
...
@@ -92,4 +81,46 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
...
@@ -92,4 +81,46 @@ int snd_pcm_create_iec958_consumer(struct snd_pcm_runtime *runtime, u8 *cs,
return
len
;
return
len
;
}
}
/**
* snd_pcm_create_iec958_consumer - create consumer format IEC958 channel status
* @runtime: pcm runtime structure with ->rate filled in
* @cs: channel status buffer, at least four bytes
* @len: length of channel status buffer
*
* Create the consumer format channel status data in @cs of maximum size
* @len corresponding to the parameters of the PCM runtime @runtime.
*
* Drivers may wish to tweak the contents of the buffer after creation.
*
* Returns: length of buffer, or negative error code if something failed.
*/
int
snd_pcm_create_iec958_consumer
(
struct
snd_pcm_runtime
*
runtime
,
u8
*
cs
,
size_t
len
)
{
return
create_iec958_consumer
(
runtime
->
rate
,
snd_pcm_format_width
(
runtime
->
format
),
cs
,
len
);
}
EXPORT_SYMBOL
(
snd_pcm_create_iec958_consumer
);
EXPORT_SYMBOL
(
snd_pcm_create_iec958_consumer
);
/**
* snd_pcm_create_iec958_consumer_hw_params - create IEC958 channel status
* @hw_params: the hw_params instance for extracting rate and sample format
* @cs: channel status buffer, at least four bytes
* @len: length of channel status buffer
*
* Create the consumer format channel status data in @cs of maximum size
* @len corresponding to the parameters of the PCM runtime @runtime.
*
* Drivers may wish to tweak the contents of the buffer after creation.
*
* Returns: length of buffer, or negative error code if something failed.
*/
int
snd_pcm_create_iec958_consumer_hw_params
(
struct
snd_pcm_hw_params
*
params
,
u8
*
cs
,
size_t
len
)
{
return
create_iec958_consumer
(
params_rate
(
params
),
params_width
(
params
),
cs
,
len
);
}
EXPORT_SYMBOL
(
snd_pcm_create_iec958_consumer_hw_params
);
sound/hda/local.h
View file @
515511a7
...
@@ -16,6 +16,16 @@ static inline int get_wcaps_type(unsigned int wcaps)
...
@@ -16,6 +16,16 @@ static inline int get_wcaps_type(unsigned int wcaps)
return
(
wcaps
&
AC_WCAP_TYPE
)
>>
AC_WCAP_TYPE_SHIFT
;
return
(
wcaps
&
AC_WCAP_TYPE
)
>>
AC_WCAP_TYPE_SHIFT
;
}
}
static
inline
unsigned
int
get_wcaps_channels
(
u32
wcaps
)
{
unsigned
int
chans
;
chans
=
(
wcaps
&
AC_WCAP_CHAN_CNT_EXT
)
>>
13
;
chans
=
(
chans
+
1
)
*
2
;
return
chans
;
}
extern
const
struct
attribute_group
*
hdac_dev_attr_groups
[];
extern
const
struct
attribute_group
*
hdac_dev_attr_groups
[];
int
hda_widget_sysfs_init
(
struct
hdac_device
*
codec
);
int
hda_widget_sysfs_init
(
struct
hdac_device
*
codec
);
void
hda_widget_sysfs_exit
(
struct
hdac_device
*
codec
);
void
hda_widget_sysfs_exit
(
struct
hdac_device
*
codec
);
...
...
sound/soc/codecs/Kconfig
View file @
515511a7
...
@@ -88,6 +88,7 @@ config SND_SOC_ALL_CODECS
...
@@ -88,6 +88,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MC13783 if MFD_MC13XXX
select SND_SOC_MC13783 if MFD_MC13XXX
select SND_SOC_ML26124 if I2C
select SND_SOC_ML26124 if I2C
select SND_SOC_NAU8825 if I2C
select SND_SOC_NAU8825 if I2C
select SND_SOC_HDMI_CODEC
select SND_SOC_PCM1681 if I2C
select SND_SOC_PCM1681 if I2C
select SND_SOC_PCM179X_I2C if I2C
select SND_SOC_PCM179X_I2C if I2C
select SND_SOC_PCM179X_SPI if SPI_MASTER
select SND_SOC_PCM179X_SPI if SPI_MASTER
...
@@ -478,6 +479,11 @@ config SND_SOC_BT_SCO
...
@@ -478,6 +479,11 @@ config SND_SOC_BT_SCO
config SND_SOC_DMIC
config SND_SOC_DMIC
tristate
tristate
config SND_SOC_HDMI_CODEC
tristate
select SND_PCM_ELD
select SND_PCM_IEC958
config SND_SOC_ES8328
config SND_SOC_ES8328
tristate "Everest Semi ES8328 CODEC"
tristate "Everest Semi ES8328 CODEC"
...
...
sound/soc/codecs/Makefile
View file @
515511a7
...
@@ -81,6 +81,7 @@ snd-soc-max9850-objs := max9850.o
...
@@ -81,6 +81,7 @@ snd-soc-max9850-objs := max9850.o
snd-soc-mc13783-objs
:=
mc13783.o
snd-soc-mc13783-objs
:=
mc13783.o
snd-soc-ml26124-objs
:=
ml26124.o
snd-soc-ml26124-objs
:=
ml26124.o
snd-soc-nau8825-objs
:=
nau8825.o
snd-soc-nau8825-objs
:=
nau8825.o
snd-soc-hdmi-codec-objs
:=
hdmi-codec.o
snd-soc-pcm1681-objs
:=
pcm1681.o
snd-soc-pcm1681-objs
:=
pcm1681.o
snd-soc-pcm179x-codec-objs
:=
pcm179x.o
snd-soc-pcm179x-codec-objs
:=
pcm179x.o
snd-soc-pcm179x-i2c-objs
:=
pcm179x-i2c.o
snd-soc-pcm179x-i2c-objs
:=
pcm179x-i2c.o
...
@@ -291,6 +292,7 @@ obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
...
@@ -291,6 +292,7 @@ obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
obj-$(CONFIG_SND_SOC_MC13783)
+=
snd-soc-mc13783.o
obj-$(CONFIG_SND_SOC_MC13783)
+=
snd-soc-mc13783.o
obj-$(CONFIG_SND_SOC_ML26124)
+=
snd-soc-ml26124.o
obj-$(CONFIG_SND_SOC_ML26124)
+=
snd-soc-ml26124.o
obj-$(CONFIG_SND_SOC_NAU8825)
+=
snd-soc-nau8825.o
obj-$(CONFIG_SND_SOC_NAU8825)
+=
snd-soc-nau8825.o
obj-$(CONFIG_SND_SOC_HDMI_CODEC)
+=
snd-soc-hdmi-codec.o
obj-$(CONFIG_SND_SOC_PCM1681)
+=
snd-soc-pcm1681.o
obj-$(CONFIG_SND_SOC_PCM1681)
+=
snd-soc-pcm1681.o
obj-$(CONFIG_SND_SOC_PCM179X)
+=
snd-soc-pcm179x-codec.o
obj-$(CONFIG_SND_SOC_PCM179X)
+=
snd-soc-pcm179x-codec.o
obj-$(CONFIG_SND_SOC_PCM179X_I2C)
+=
snd-soc-pcm179x-i2c.o
obj-$(CONFIG_SND_SOC_PCM179X_I2C)
+=
snd-soc-pcm179x-i2c.o
...
...
sound/soc/codecs/hdac_hdmi.c
View file @
515511a7
...
@@ -29,6 +29,7 @@
...
@@ -29,6 +29,7 @@
#include <sound/hdaudio_ext.h>
#include <sound/hdaudio_ext.h>
#include <sound/hda_i915.h>
#include <sound/hda_i915.h>
#include <sound/pcm_drm_eld.h>
#include <sound/pcm_drm_eld.h>
#include <sound/hda_chmap.h>
#include "../../hda/local.h"
#include "../../hda/local.h"
#include "hdac_hdmi.h"
#include "hdac_hdmi.h"
...
@@ -60,11 +61,17 @@ struct hdac_hdmi_cvt {
...
@@ -60,11 +61,17 @@ struct hdac_hdmi_cvt {
struct
hdac_hdmi_cvt_params
params
;
struct
hdac_hdmi_cvt_params
params
;
};
};
/* Currently only spk_alloc, more to be added */
struct
hdac_hdmi_parsed_eld
{
u8
spk_alloc
;
};
struct
hdac_hdmi_eld
{
struct
hdac_hdmi_eld
{
bool
monitor_present
;
bool
monitor_present
;
bool
eld_valid
;
bool
eld_valid
;
int
eld_size
;
int
eld_size
;
char
eld_buffer
[
ELD_MAX_SIZE
];
char
eld_buffer
[
ELD_MAX_SIZE
];
struct
hdac_hdmi_parsed_eld
info
;
};
};
struct
hdac_hdmi_pin
{
struct
hdac_hdmi_pin
{
...
@@ -76,6 +83,10 @@ struct hdac_hdmi_pin {
...
@@ -76,6 +83,10 @@ struct hdac_hdmi_pin {
struct
hdac_ext_device
*
edev
;
struct
hdac_ext_device
*
edev
;
int
repoll_count
;
int
repoll_count
;
struct
delayed_work
work
;
struct
delayed_work
work
;
struct
mutex
lock
;
bool
chmap_set
;
unsigned
char
chmap
[
8
];
/* ALSA API channel-map */
int
channels
;
/* current number of channels */
};
};
struct
hdac_hdmi_pcm
{
struct
hdac_hdmi_pcm
{
...
@@ -100,8 +111,22 @@ struct hdac_hdmi_priv {
...
@@ -100,8 +111,22 @@ struct hdac_hdmi_priv {
int
num_pin
;
int
num_pin
;
int
num_cvt
;
int
num_cvt
;
struct
mutex
pin_mutex
;
struct
mutex
pin_mutex
;
struct
hdac_chmap
chmap
;
};
};
static
struct
hdac_hdmi_pcm
*
get_hdmi_pcm_from_id
(
struct
hdac_hdmi_priv
*
hdmi
,
int
pcm_idx
)
{
struct
hdac_hdmi_pcm
*
pcm
;
list_for_each_entry
(
pcm
,
&
hdmi
->
pcm_list
,
head
)
{
if
(
pcm
->
pcm_id
==
pcm_idx
)
return
pcm
;
}
return
NULL
;
}
static
inline
struct
hdac_ext_device
*
to_hda_ext_device
(
struct
device
*
dev
)
static
inline
struct
hdac_ext_device
*
to_hda_ext_device
(
struct
device
*
dev
)
{
{
struct
hdac_device
*
hdac
=
dev_to_hdac_dev
(
dev
);
struct
hdac_device
*
hdac
=
dev_to_hdac_dev
(
dev
);
...
@@ -278,26 +303,31 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
...
@@ -278,26 +303,31 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
int
i
;
int
i
;
const
u8
*
eld_buf
;
const
u8
*
eld_buf
;
u8
conn_type
;
u8
conn_type
;
int
channels
=
2
;
int
channels
,
ca
;
list_for_each_entry
(
pin
,
&
hdmi
->
pin_list
,
head
)
{
list_for_each_entry
(
pin
,
&
hdmi
->
pin_list
,
head
)
{
if
(
pin
->
nid
==
pin_nid
)
if
(
pin
->
nid
==
pin_nid
)
break
;
break
;
}
}
ca
=
snd_hdac_channel_allocation
(
&
hdac
->
hdac
,
pin
->
eld
.
info
.
spk_alloc
,
pin
->
channels
,
pin
->
chmap_set
,
true
,
pin
->
chmap
);
channels
=
snd_hdac_get_active_channels
(
ca
);
hdmi
->
chmap
.
ops
.
set_channel_count
(
&
hdac
->
hdac
,
cvt_nid
,
channels
);
snd_hdac_setup_channel_mapping
(
&
hdmi
->
chmap
,
pin
->
nid
,
false
,
ca
,
pin
->
channels
,
pin
->
chmap
,
pin
->
chmap_set
);
eld_buf
=
pin
->
eld
.
eld_buffer
;
eld_buf
=
pin
->
eld
.
eld_buffer
;
conn_type
=
drm_eld_get_conn_type
(
eld_buf
);
conn_type
=
drm_eld_get_conn_type
(
eld_buf
);
/* setup channel count */
snd_hdac_codec_write
(
&
hdac
->
hdac
,
cvt_nid
,
0
,
AC_VERB_SET_CVT_CHAN_COUNT
,
channels
-
1
);
switch
(
conn_type
)
{
switch
(
conn_type
)
{
case
DRM_ELD_CONN_TYPE_HDMI
:
case
DRM_ELD_CONN_TYPE_HDMI
:
hdmi_audio_infoframe_init
(
&
frame
);
hdmi_audio_infoframe_init
(
&
frame
);
/* Default stereo for now */
frame
.
channels
=
channels
;
frame
.
channels
=
channels
;
frame
.
channel_allocation
=
ca
;
ret
=
hdmi_audio_infoframe_pack
(
&
frame
,
buffer
,
sizeof
(
buffer
));
ret
=
hdmi_audio_infoframe_pack
(
&
frame
,
buffer
,
sizeof
(
buffer
));
if
(
ret
<
0
)
if
(
ret
<
0
)
...
@@ -311,7 +341,7 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
...
@@ -311,7 +341,7 @@ static int hdac_hdmi_setup_audio_infoframe(struct hdac_ext_device *hdac,
dp_ai
.
len
=
0x1b
;
dp_ai
.
len
=
0x1b
;
dp_ai
.
ver
=
0x11
<<
2
;
dp_ai
.
ver
=
0x11
<<
2
;
dp_ai
.
CC02_CT47
=
channels
-
1
;
dp_ai
.
CC02_CT47
=
channels
-
1
;
dp_ai
.
CA
=
0
;
dp_ai
.
CA
=
ca
;
dip
=
(
u8
*
)
&
dp_ai
;
dip
=
(
u8
*
)
&
dp_ai
;
break
;
break
;
...
@@ -370,17 +400,23 @@ static int hdac_hdmi_playback_prepare(struct snd_pcm_substream *substream,
...
@@ -370,17 +400,23 @@ static int hdac_hdmi_playback_prepare(struct snd_pcm_substream *substream,
struct
hdac_ext_device
*
hdac
=
snd_soc_dai_get_drvdata
(
dai
);
struct
hdac_ext_device
*
hdac
=
snd_soc_dai_get_drvdata
(
dai
);
struct
hdac_hdmi_priv
*
hdmi
=
hdac
->
private_data
;
struct
hdac_hdmi_priv
*
hdmi
=
hdac
->
private_data
;
struct
hdac_hdmi_dai_pin_map
*
dai_map
;
struct
hdac_hdmi_dai_pin_map
*
dai_map
;
struct
hdac_hdmi_pin
*
pin
;
struct
hdac_ext_dma_params
*
dd
;
struct
hdac_ext_dma_params
*
dd
;
int
ret
;
int
ret
;
dai_map
=
&
hdmi
->
dai_map
[
dai
->
id
];
dai_map
=
&
hdmi
->
dai_map
[
dai
->
id
];
pin
=
dai_map
->
pin
;
dd
=
(
struct
hdac_ext_dma_params
*
)
snd_soc_dai_get_dma_data
(
dai
,
substream
);
dd
=
(
struct
hdac_ext_dma_params
*
)
snd_soc_dai_get_dma_data
(
dai
,
substream
);
dev_dbg
(
&
hdac
->
hdac
.
dev
,
"stream tag from cpu dai %d format in cvt 0x%x
\n
"
,
dev_dbg
(
&
hdac
->
hdac
.
dev
,
"stream tag from cpu dai %d format in cvt 0x%x
\n
"
,
dd
->
stream_tag
,
dd
->
format
);
dd
->
stream_tag
,
dd
->
format
);
mutex_lock
(
&
pin
->
lock
);
pin
->
channels
=
substream
->
runtime
->
channels
;
ret
=
hdac_hdmi_setup_audio_infoframe
(
hdac
,
dai_map
->
cvt
->
nid
,
ret
=
hdac_hdmi_setup_audio_infoframe
(
hdac
,
dai_map
->
cvt
->
nid
,
dai_map
->
pin
->
nid
);
dai_map
->
pin
->
nid
);
mutex_unlock
(
&
pin
->
lock
);
if
(
ret
<
0
)
if
(
ret
<
0
)
return
ret
;
return
ret
;
...
@@ -640,6 +676,12 @@ static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
...
@@ -640,6 +676,12 @@ static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
snd_hdac_codec_write
(
&
hdac
->
hdac
,
dai_map
->
pin
->
nid
,
0
,
snd_hdac_codec_write
(
&
hdac
->
hdac
,
dai_map
->
pin
->
nid
,
0
,
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_OUT_MUTE
);
AC_VERB_SET_AMP_GAIN_MUTE
,
AMP_OUT_MUTE
);
mutex_lock
(
&
dai_map
->
pin
->
lock
);
dai_map
->
pin
->
chmap_set
=
false
;
memset
(
dai_map
->
pin
->
chmap
,
0
,
sizeof
(
dai_map
->
pin
->
chmap
));
dai_map
->
pin
->
channels
=
0
;
mutex_unlock
(
&
dai_map
->
pin
->
lock
);
dai_map
->
pin
=
NULL
;
dai_map
->
pin
=
NULL
;
}
}
}
}
...
@@ -647,10 +689,19 @@ static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
...
@@ -647,10 +689,19 @@ static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
static
int
static
int
hdac_hdmi_query_cvt_params
(
struct
hdac_device
*
hdac
,
struct
hdac_hdmi_cvt
*
cvt
)
hdac_hdmi_query_cvt_params
(
struct
hdac_device
*
hdac
,
struct
hdac_hdmi_cvt
*
cvt
)
{
{
unsigned
int
chans
;
struct
hdac_ext_device
*
edev
=
to_ehdac_device
(
hdac
);
struct
hdac_hdmi_priv
*
hdmi
=
edev
->
private_data
;
int
err
;
int
err
;
/* Only stereo supported as of now */
chans
=
get_wcaps
(
hdac
,
cvt
->
nid
);
cvt
->
params
.
channels_min
=
cvt
->
params
.
channels_max
=
2
;
chans
=
get_wcaps_channels
(
chans
);
cvt
->
params
.
channels_min
=
2
;
cvt
->
params
.
channels_max
=
chans
;
if
(
chans
>
hdmi
->
chmap
.
channels_max
)
hdmi
->
chmap
.
channels_max
=
chans
;
err
=
snd_hdac_query_supported_pcm
(
hdac
,
cvt
->
nid
,
err
=
snd_hdac_query_supported_pcm
(
hdac
,
cvt
->
nid
,
&
cvt
->
params
.
rates
,
&
cvt
->
params
.
rates
,
...
@@ -1008,6 +1059,12 @@ static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid)
...
@@ -1008,6 +1059,12 @@ static int hdac_hdmi_add_cvt(struct hdac_ext_device *edev, hda_nid_t nid)
return
hdac_hdmi_query_cvt_params
(
&
edev
->
hdac
,
cvt
);
return
hdac_hdmi_query_cvt_params
(
&
edev
->
hdac
,
cvt
);
}
}
static
void
hdac_hdmi_parse_eld
(
struct
hdac_ext_device
*
edev
,
struct
hdac_hdmi_pin
*
pin
)
{
pin
->
eld
.
info
.
spk_alloc
=
pin
->
eld
.
eld_buffer
[
DRM_ELD_SPEAKER
];
}
static
void
hdac_hdmi_present_sense
(
struct
hdac_hdmi_pin
*
pin
,
int
repoll
)
static
void
hdac_hdmi_present_sense
(
struct
hdac_hdmi_pin
*
pin
,
int
repoll
)
{
{
struct
hdac_ext_device
*
edev
=
pin
->
edev
;
struct
hdac_ext_device
*
edev
=
pin
->
edev
;
...
@@ -1065,6 +1122,7 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, int repoll)
...
@@ -1065,6 +1122,7 @@ static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin, int repoll)
snd_jack_report
(
pcm
->
jack
,
SND_JACK_AVOUT
);
snd_jack_report
(
pcm
->
jack
,
SND_JACK_AVOUT
);
}
}
hdac_hdmi_parse_eld
(
edev
,
pin
);
print_hex_dump_bytes
(
"ELD: "
,
DUMP_PREFIX_OFFSET
,
print_hex_dump_bytes
(
"ELD: "
,
DUMP_PREFIX_OFFSET
,
pin
->
eld
.
eld_buffer
,
pin
->
eld
.
eld_size
);
pin
->
eld
.
eld_buffer
,
pin
->
eld
.
eld_size
);
...
@@ -1123,6 +1181,7 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
...
@@ -1123,6 +1181,7 @@ static int hdac_hdmi_add_pin(struct hdac_ext_device *edev, hda_nid_t nid)
hdmi
->
num_pin
++
;
hdmi
->
num_pin
++
;
pin
->
edev
=
edev
;
pin
->
edev
=
edev
;
mutex_init
(
&
pin
->
lock
);
INIT_DELAYED_WORK
(
&
pin
->
work
,
hdac_hdmi_repoll_eld
);
INIT_DELAYED_WORK
(
&
pin
->
work
,
hdac_hdmi_repoll_eld
);
return
0
;
return
0
;
...
@@ -1342,6 +1401,19 @@ static struct i915_audio_component_audio_ops aops = {
...
@@ -1342,6 +1401,19 @@ static struct i915_audio_component_audio_ops aops = {
.
pin_eld_notify
=
hdac_hdmi_eld_notify_cb
,
.
pin_eld_notify
=
hdac_hdmi_eld_notify_cb
,
};
};
static
struct
snd_pcm
*
hdac_hdmi_get_pcm_from_id
(
struct
snd_soc_card
*
card
,
int
device
)
{
struct
snd_soc_pcm_runtime
*
rtd
;
list_for_each_entry
(
rtd
,
&
card
->
rtd_list
,
list
)
{
if
(
rtd
->
pcm
&&
(
rtd
->
pcm
->
device
==
device
))
return
rtd
->
pcm
;
}
return
NULL
;
}
int
hdac_hdmi_jack_init
(
struct
snd_soc_dai
*
dai
,
int
device
)
int
hdac_hdmi_jack_init
(
struct
snd_soc_dai
*
dai
,
int
device
)
{
{
char
jack_name
[
NAME_SIZE
];
char
jack_name
[
NAME_SIZE
];
...
@@ -1351,6 +1423,8 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device)
...
@@ -1351,6 +1423,8 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device)
snd_soc_component_get_dapm
(
&
codec
->
component
);
snd_soc_component_get_dapm
(
&
codec
->
component
);
struct
hdac_hdmi_priv
*
hdmi
=
edev
->
private_data
;
struct
hdac_hdmi_priv
*
hdmi
=
edev
->
private_data
;
struct
hdac_hdmi_pcm
*
pcm
;
struct
hdac_hdmi_pcm
*
pcm
;
struct
snd_pcm
*
snd_pcm
;
int
err
;
/*
/*
* this is a new PCM device, create new pcm and
* this is a new PCM device, create new pcm and
...
@@ -1362,6 +1436,18 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device)
...
@@ -1362,6 +1436,18 @@ int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device)
pcm
->
pcm_id
=
device
;
pcm
->
pcm_id
=
device
;
pcm
->
cvt
=
hdmi
->
dai_map
[
dai
->
id
].
cvt
;
pcm
->
cvt
=
hdmi
->
dai_map
[
dai
->
id
].
cvt
;
snd_pcm
=
hdac_hdmi_get_pcm_from_id
(
dai
->
component
->
card
,
device
);
if
(
snd_pcm
)
{
err
=
snd_hdac_add_chmap_ctls
(
snd_pcm
,
device
,
&
hdmi
->
chmap
);
if
(
err
<
0
)
{
dev_err
(
&
edev
->
hdac
.
dev
,
"chmap control add failed with err: %d for pcm: %d
\n
"
,
err
,
device
);
kfree
(
pcm
);
return
err
;
}
}
list_add_tail
(
&
pcm
->
head
,
&
hdmi
->
pcm_list
);
list_add_tail
(
&
pcm
->
head
,
&
hdmi
->
pcm_list
);
sprintf
(
jack_name
,
"HDMI/DP, pcm=%d Jack"
,
device
);
sprintf
(
jack_name
,
"HDMI/DP, pcm=%d Jack"
,
device
);
...
@@ -1483,6 +1569,60 @@ static struct snd_soc_codec_driver hdmi_hda_codec = {
...
@@ -1483,6 +1569,60 @@ static struct snd_soc_codec_driver hdmi_hda_codec = {
.
idle_bias_off
=
true
,
.
idle_bias_off
=
true
,
};
};
static
void
hdac_hdmi_get_chmap
(
struct
hdac_device
*
hdac
,
int
pcm_idx
,
unsigned
char
*
chmap
)
{
struct
hdac_ext_device
*
edev
=
to_ehdac_device
(
hdac
);
struct
hdac_hdmi_priv
*
hdmi
=
edev
->
private_data
;
struct
hdac_hdmi_pcm
*
pcm
=
get_hdmi_pcm_from_id
(
hdmi
,
pcm_idx
);
struct
hdac_hdmi_pin
*
pin
=
pcm
->
pin
;
/* chmap is already set to 0 in caller */
if
(
!
pin
)
return
;
memcpy
(
chmap
,
pin
->
chmap
,
ARRAY_SIZE
(
pin
->
chmap
));
}
static
void
hdac_hdmi_set_chmap
(
struct
hdac_device
*
hdac
,
int
pcm_idx
,
unsigned
char
*
chmap
,
int
prepared
)
{
struct
hdac_ext_device
*
edev
=
to_ehdac_device
(
hdac
);
struct
hdac_hdmi_priv
*
hdmi
=
edev
->
private_data
;
struct
hdac_hdmi_pcm
*
pcm
=
get_hdmi_pcm_from_id
(
hdmi
,
pcm_idx
);
struct
hdac_hdmi_pin
*
pin
=
pcm
->
pin
;
mutex_lock
(
&
pin
->
lock
);
pin
->
chmap_set
=
true
;
memcpy
(
pin
->
chmap
,
chmap
,
ARRAY_SIZE
(
pin
->
chmap
));
if
(
prepared
)
hdac_hdmi_setup_audio_infoframe
(
edev
,
pcm
->
cvt
->
nid
,
pin
->
nid
);
mutex_unlock
(
&
pin
->
lock
);
}
static
bool
is_hdac_hdmi_pcm_attached
(
struct
hdac_device
*
hdac
,
int
pcm_idx
)
{
struct
hdac_ext_device
*
edev
=
to_ehdac_device
(
hdac
);
struct
hdac_hdmi_priv
*
hdmi
=
edev
->
private_data
;
struct
hdac_hdmi_pcm
*
pcm
=
get_hdmi_pcm_from_id
(
hdmi
,
pcm_idx
);
struct
hdac_hdmi_pin
*
pin
=
pcm
->
pin
;
return
pin
?
true
:
false
;
}
static
int
hdac_hdmi_get_spk_alloc
(
struct
hdac_device
*
hdac
,
int
pcm_idx
)
{
struct
hdac_ext_device
*
edev
=
to_ehdac_device
(
hdac
);
struct
hdac_hdmi_priv
*
hdmi
=
edev
->
private_data
;
struct
hdac_hdmi_pcm
*
pcm
=
get_hdmi_pcm_from_id
(
hdmi
,
pcm_idx
);
struct
hdac_hdmi_pin
*
pin
=
pcm
->
pin
;
if
(
!
pin
||
!
pin
->
eld
.
eld_valid
)
return
0
;
return
pin
->
eld
.
info
.
spk_alloc
;
}
static
int
hdac_hdmi_dev_probe
(
struct
hdac_ext_device
*
edev
)
static
int
hdac_hdmi_dev_probe
(
struct
hdac_ext_device
*
edev
)
{
{
struct
hdac_device
*
codec
=
&
edev
->
hdac
;
struct
hdac_device
*
codec
=
&
edev
->
hdac
;
...
@@ -1501,6 +1641,11 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
...
@@ -1501,6 +1641,11 @@ static int hdac_hdmi_dev_probe(struct hdac_ext_device *edev)
return
-
ENOMEM
;
return
-
ENOMEM
;
edev
->
private_data
=
hdmi_priv
;
edev
->
private_data
=
hdmi_priv
;
snd_hdac_register_chmap_ops
(
codec
,
&
hdmi_priv
->
chmap
);
hdmi_priv
->
chmap
.
ops
.
get_chmap
=
hdac_hdmi_get_chmap
;
hdmi_priv
->
chmap
.
ops
.
set_chmap
=
hdac_hdmi_set_chmap
;
hdmi_priv
->
chmap
.
ops
.
is_pcm_attached
=
is_hdac_hdmi_pcm_attached
;
hdmi_priv
->
chmap
.
ops
.
get_spk_alloc
=
hdac_hdmi_get_spk_alloc
;
dev_set_drvdata
(
&
codec
->
dev
,
edev
);
dev_set_drvdata
(
&
codec
->
dev
,
edev
);
...
...
sound/soc/codecs/hdmi-codec.c
0 → 100644
View file @
515511a7
This diff is collapsed.
Click to expand it.
sound/soc/intel/boards/skl_nau88l25_max98357a.c
View file @
515511a7
...
@@ -30,6 +30,16 @@
...
@@ -30,6 +30,16 @@
static
struct
snd_soc_jack
skylake_headset
;
static
struct
snd_soc_jack
skylake_headset
;
static
struct
snd_soc_card
skylake_audio_card
;
static
struct
snd_soc_card
skylake_audio_card
;
struct
skl_hdmi_pcm
{
struct
list_head
head
;
struct
snd_soc_dai
*
codec_dai
;
int
device
;
};
struct
skl_nau8825_private
{
struct
list_head
hdmi_pcm_list
;
};
enum
{
enum
{
SKL_DPCM_AUDIO_PB
=
0
,
SKL_DPCM_AUDIO_PB
=
0
,
SKL_DPCM_AUDIO_CP
,
SKL_DPCM_AUDIO_CP
,
...
@@ -192,23 +202,56 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -192,23 +202,56 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
static
int
skylake_hdmi1_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
static
int
skylake_hdmi1_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
{
struct
skl_nau8825_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
struct
skl_hdmi_pcm
*
pcm
;
pcm
=
devm_kzalloc
(
rtd
->
card
->
dev
,
sizeof
(
*
pcm
),
GFP_KERNEL
);
if
(
!
pcm
)
return
-
ENOMEM
;
pcm
->
device
=
SKL_DPCM_AUDIO_HDMI1_PB
;
pcm
->
codec_dai
=
dai
;
return
hdac_hdmi_jack_init
(
dai
,
SKL_DPCM_AUDIO_HDMI1_PB
);
list_add_tail
(
&
pcm
->
head
,
&
ctx
->
hdmi_pcm_list
);
return
0
;
}
}
static
int
skylake_hdmi2_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
static
int
skylake_hdmi2_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
{
struct
skl_nau8825_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
struct
skl_hdmi_pcm
*
pcm
;
pcm
=
devm_kzalloc
(
rtd
->
card
->
dev
,
sizeof
(
*
pcm
),
GFP_KERNEL
);
if
(
!
pcm
)
return
-
ENOMEM
;
return
hdac_hdmi_jack_init
(
dai
,
SKL_DPCM_AUDIO_HDMI2_PB
);
pcm
->
device
=
SKL_DPCM_AUDIO_HDMI2_PB
;
pcm
->
codec_dai
=
dai
;
list_add_tail
(
&
pcm
->
head
,
&
ctx
->
hdmi_pcm_list
);
return
0
;
}
}
static
int
skylake_hdmi3_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
static
int
skylake_hdmi3_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
{
struct
skl_nau8825_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
struct
skl_hdmi_pcm
*
pcm
;
return
hdac_hdmi_jack_init
(
dai
,
SKL_DPCM_AUDIO_HDMI3_PB
);
pcm
=
devm_kzalloc
(
rtd
->
card
->
dev
,
sizeof
(
*
pcm
),
GFP_KERNEL
);
if
(
!
pcm
)
return
-
ENOMEM
;
pcm
->
device
=
SKL_DPCM_AUDIO_HDMI3_PB
;
pcm
->
codec_dai
=
dai
;
list_add_tail
(
&
pcm
->
head
,
&
ctx
->
hdmi_pcm_list
);
return
0
;
}
}
static
int
skylake_nau8825_fe_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
static
int
skylake_nau8825_fe_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
...
@@ -533,6 +576,21 @@ static struct snd_soc_dai_link skylake_dais[] = {
...
@@ -533,6 +576,21 @@ static struct snd_soc_dai_link skylake_dais[] = {
},
},
};
};
static
int
skylake_card_late_probe
(
struct
snd_soc_card
*
card
)
{
struct
skl_nau8825_private
*
ctx
=
snd_soc_card_get_drvdata
(
card
);
struct
skl_hdmi_pcm
*
pcm
;
int
err
;
list_for_each_entry
(
pcm
,
&
ctx
->
hdmi_pcm_list
,
head
)
{
err
=
hdac_hdmi_jack_init
(
pcm
->
codec_dai
,
pcm
->
device
);
if
(
err
<
0
)
return
err
;
}
return
0
;
}
/* skylake audio machine driver for SPT + NAU88L25 */
/* skylake audio machine driver for SPT + NAU88L25 */
static
struct
snd_soc_card
skylake_audio_card
=
{
static
struct
snd_soc_card
skylake_audio_card
=
{
.
name
=
"sklnau8825max"
,
.
name
=
"sklnau8825max"
,
...
@@ -546,11 +604,21 @@ static struct snd_soc_card skylake_audio_card = {
...
@@ -546,11 +604,21 @@ static struct snd_soc_card skylake_audio_card = {
.
dapm_routes
=
skylake_map
,
.
dapm_routes
=
skylake_map
,
.
num_dapm_routes
=
ARRAY_SIZE
(
skylake_map
),
.
num_dapm_routes
=
ARRAY_SIZE
(
skylake_map
),
.
fully_routed
=
true
,
.
fully_routed
=
true
,
.
late_probe
=
skylake_card_late_probe
,
};
};
static
int
skylake_audio_probe
(
struct
platform_device
*
pdev
)
static
int
skylake_audio_probe
(
struct
platform_device
*
pdev
)
{
{
struct
skl_nau8825_private
*
ctx
;
ctx
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
ctx
),
GFP_ATOMIC
);
if
(
!
ctx
)
return
-
ENOMEM
;
INIT_LIST_HEAD
(
&
ctx
->
hdmi_pcm_list
);
skylake_audio_card
.
dev
=
&
pdev
->
dev
;
skylake_audio_card
.
dev
=
&
pdev
->
dev
;
snd_soc_card_set_drvdata
(
&
skylake_audio_card
,
ctx
);
return
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
skylake_audio_card
);
return
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
skylake_audio_card
);
}
}
...
...
sound/soc/intel/boards/skl_nau88l25_ssm4567.c
View file @
515511a7
...
@@ -34,6 +34,15 @@
...
@@ -34,6 +34,15 @@
static
struct
snd_soc_jack
skylake_headset
;
static
struct
snd_soc_jack
skylake_headset
;
static
struct
snd_soc_card
skylake_audio_card
;
static
struct
snd_soc_card
skylake_audio_card
;
struct
skl_hdmi_pcm
{
struct
list_head
head
;
struct
snd_soc_dai
*
codec_dai
;
int
device
;
};
struct
skl_nau88125_private
{
struct
list_head
hdmi_pcm_list
;
};
enum
{
enum
{
SKL_DPCM_AUDIO_PB
=
0
,
SKL_DPCM_AUDIO_PB
=
0
,
SKL_DPCM_AUDIO_CP
,
SKL_DPCM_AUDIO_CP
,
...
@@ -222,24 +231,57 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -222,24 +231,57 @@ static int skylake_nau8825_codec_init(struct snd_soc_pcm_runtime *rtd)
static
int
skylake_hdmi1_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
static
int
skylake_hdmi1_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
{
struct
skl_nau88125_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
struct
skl_hdmi_pcm
*
pcm
;
pcm
=
devm_kzalloc
(
rtd
->
card
->
dev
,
sizeof
(
*
pcm
),
GFP_KERNEL
);
if
(
!
pcm
)
return
-
ENOMEM
;
pcm
->
device
=
SKL_DPCM_AUDIO_HDMI1_PB
;
pcm
->
codec_dai
=
dai
;
list_add_tail
(
&
pcm
->
head
,
&
ctx
->
hdmi_pcm_list
);
return
hdac_hdmi_jack_init
(
dai
,
SKL_DPCM_AUDIO_HDMI1_PB
)
;
return
0
;
}
}
static
int
skylake_hdmi2_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
static
int
skylake_hdmi2_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
{
struct
skl_nau88125_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
struct
skl_hdmi_pcm
*
pcm
;
pcm
=
devm_kzalloc
(
rtd
->
card
->
dev
,
sizeof
(
*
pcm
),
GFP_KERNEL
);
if
(
!
pcm
)
return
-
ENOMEM
;
pcm
->
device
=
SKL_DPCM_AUDIO_HDMI2_PB
;
pcm
->
codec_dai
=
dai
;
return
hdac_hdmi_jack_init
(
dai
,
SKL_DPCM_AUDIO_HDMI2_PB
);
list_add_tail
(
&
pcm
->
head
,
&
ctx
->
hdmi_pcm_list
);
return
0
;
}
}
static
int
skylake_hdmi3_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
static
int
skylake_hdmi3_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
{
struct
skl_nau88125_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
struct
skl_hdmi_pcm
*
pcm
;
pcm
=
devm_kzalloc
(
rtd
->
card
->
dev
,
sizeof
(
*
pcm
),
GFP_KERNEL
);
if
(
!
pcm
)
return
-
ENOMEM
;
return
hdac_hdmi_jack_init
(
dai
,
SKL_DPCM_AUDIO_HDMI3_PB
);
pcm
->
device
=
SKL_DPCM_AUDIO_HDMI3_PB
;
pcm
->
codec_dai
=
dai
;
list_add_tail
(
&
pcm
->
head
,
&
ctx
->
hdmi_pcm_list
);
return
0
;
}
}
static
int
skylake_nau8825_fe_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
static
int
skylake_nau8825_fe_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
...
@@ -584,6 +626,21 @@ static struct snd_soc_dai_link skylake_dais[] = {
...
@@ -584,6 +626,21 @@ static struct snd_soc_dai_link skylake_dais[] = {
},
},
};
};
static
int
skylake_card_late_probe
(
struct
snd_soc_card
*
card
)
{
struct
skl_nau88125_private
*
ctx
=
snd_soc_card_get_drvdata
(
card
);
struct
skl_hdmi_pcm
*
pcm
;
int
err
;
list_for_each_entry
(
pcm
,
&
ctx
->
hdmi_pcm_list
,
head
)
{
err
=
hdac_hdmi_jack_init
(
pcm
->
codec_dai
,
pcm
->
device
);
if
(
err
<
0
)
return
err
;
}
return
0
;
}
/* skylake audio machine driver for SPT + NAU88L25 */
/* skylake audio machine driver for SPT + NAU88L25 */
static
struct
snd_soc_card
skylake_audio_card
=
{
static
struct
snd_soc_card
skylake_audio_card
=
{
.
name
=
"sklnau8825adi"
,
.
name
=
"sklnau8825adi"
,
...
@@ -599,11 +656,21 @@ static struct snd_soc_card skylake_audio_card = {
...
@@ -599,11 +656,21 @@ static struct snd_soc_card skylake_audio_card = {
.
codec_conf
=
ssm4567_codec_conf
,
.
codec_conf
=
ssm4567_codec_conf
,
.
num_configs
=
ARRAY_SIZE
(
ssm4567_codec_conf
),
.
num_configs
=
ARRAY_SIZE
(
ssm4567_codec_conf
),
.
fully_routed
=
true
,
.
fully_routed
=
true
,
.
late_probe
=
skylake_card_late_probe
,
};
};
static
int
skylake_audio_probe
(
struct
platform_device
*
pdev
)
static
int
skylake_audio_probe
(
struct
platform_device
*
pdev
)
{
{
struct
skl_nau88125_private
*
ctx
;
ctx
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
ctx
),
GFP_ATOMIC
);
if
(
!
ctx
)
return
-
ENOMEM
;
INIT_LIST_HEAD
(
&
ctx
->
hdmi_pcm_list
);
skylake_audio_card
.
dev
=
&
pdev
->
dev
;
skylake_audio_card
.
dev
=
&
pdev
->
dev
;
snd_soc_card_set_drvdata
(
&
skylake_audio_card
,
ctx
);
return
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
skylake_audio_card
);
return
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
skylake_audio_card
);
}
}
...
...
sound/soc/intel/boards/skl_rt286.c
View file @
515511a7
...
@@ -30,6 +30,16 @@
...
@@ -30,6 +30,16 @@
static
struct
snd_soc_jack
skylake_headset
;
static
struct
snd_soc_jack
skylake_headset
;
struct
skl_hdmi_pcm
{
struct
list_head
head
;
struct
snd_soc_dai
*
codec_dai
;
int
device
;
};
struct
skl_rt286_private
{
struct
list_head
hdmi_pcm_list
;
};
enum
{
enum
{
SKL_DPCM_AUDIO_PB
=
0
,
SKL_DPCM_AUDIO_PB
=
0
,
SKL_DPCM_AUDIO_CP
,
SKL_DPCM_AUDIO_CP
,
...
@@ -142,9 +152,20 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
...
@@ -142,9 +152,20 @@ static int skylake_rt286_codec_init(struct snd_soc_pcm_runtime *rtd)
static
int
skylake_hdmi_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
static
int
skylake_hdmi_init
(
struct
snd_soc_pcm_runtime
*
rtd
)
{
{
struct
skl_rt286_private
*
ctx
=
snd_soc_card_get_drvdata
(
rtd
->
card
);
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
struct
snd_soc_dai
*
dai
=
rtd
->
codec_dai
;
struct
skl_hdmi_pcm
*
pcm
;
pcm
=
devm_kzalloc
(
rtd
->
card
->
dev
,
sizeof
(
*
pcm
),
GFP_KERNEL
);
if
(
!
pcm
)
return
-
ENOMEM
;
return
hdac_hdmi_jack_init
(
dai
,
SKL_DPCM_AUDIO_HDMI1_PB
+
dai
->
id
);
pcm
->
device
=
SKL_DPCM_AUDIO_HDMI1_PB
+
dai
->
id
;
pcm
->
codec_dai
=
dai
;
list_add_tail
(
&
pcm
->
head
,
&
ctx
->
hdmi_pcm_list
);
return
0
;
}
}
static
unsigned
int
rates
[]
=
{
static
unsigned
int
rates
[]
=
{
...
@@ -437,6 +458,21 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
...
@@ -437,6 +458,21 @@ static struct snd_soc_dai_link skylake_rt286_dais[] = {
},
},
};
};
static
int
skylake_card_late_probe
(
struct
snd_soc_card
*
card
)
{
struct
skl_rt286_private
*
ctx
=
snd_soc_card_get_drvdata
(
card
);
struct
skl_hdmi_pcm
*
pcm
;
int
err
;
list_for_each_entry
(
pcm
,
&
ctx
->
hdmi_pcm_list
,
head
)
{
err
=
hdac_hdmi_jack_init
(
pcm
->
codec_dai
,
pcm
->
device
);
if
(
err
<
0
)
return
err
;
}
return
0
;
}
/* skylake audio machine driver for SPT + RT286S */
/* skylake audio machine driver for SPT + RT286S */
static
struct
snd_soc_card
skylake_rt286
=
{
static
struct
snd_soc_card
skylake_rt286
=
{
.
name
=
"skylake-rt286"
,
.
name
=
"skylake-rt286"
,
...
@@ -450,11 +486,21 @@ static struct snd_soc_card skylake_rt286 = {
...
@@ -450,11 +486,21 @@ static struct snd_soc_card skylake_rt286 = {
.
dapm_routes
=
skylake_rt286_map
,
.
dapm_routes
=
skylake_rt286_map
,
.
num_dapm_routes
=
ARRAY_SIZE
(
skylake_rt286_map
),
.
num_dapm_routes
=
ARRAY_SIZE
(
skylake_rt286_map
),
.
fully_routed
=
true
,
.
fully_routed
=
true
,
.
late_probe
=
skylake_card_late_probe
,
};
};
static
int
skylake_audio_probe
(
struct
platform_device
*
pdev
)
static
int
skylake_audio_probe
(
struct
platform_device
*
pdev
)
{
{
struct
skl_rt286_private
*
ctx
;
ctx
=
devm_kzalloc
(
&
pdev
->
dev
,
sizeof
(
*
ctx
),
GFP_ATOMIC
);
if
(
!
ctx
)
return
-
ENOMEM
;
INIT_LIST_HEAD
(
&
ctx
->
hdmi_pcm_list
);
skylake_rt286
.
dev
=
&
pdev
->
dev
;
skylake_rt286
.
dev
=
&
pdev
->
dev
;
snd_soc_card_set_drvdata
(
&
skylake_rt286
,
ctx
);
return
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
skylake_rt286
);
return
devm_snd_soc_register_card
(
&
pdev
->
dev
,
&
skylake_rt286
);
}
}
...
...
sound/soc/intel/skylake/skl-pcm.c
View file @
515511a7
...
@@ -51,7 +51,7 @@ static struct snd_pcm_hardware azx_pcm_hw = {
...
@@ -51,7 +51,7 @@ static struct snd_pcm_hardware azx_pcm_hw = {
.
rate_min
=
8000
,
.
rate_min
=
8000
,
.
rate_max
=
48000
,
.
rate_max
=
48000
,
.
channels_min
=
1
,
.
channels_min
=
1
,
.
channels_max
=
HDA_QUAD
,
.
channels_max
=
8
,
.
buffer_bytes_max
=
AZX_MAX_BUF_SIZE
,
.
buffer_bytes_max
=
AZX_MAX_BUF_SIZE
,
.
period_bytes_min
=
128
,
.
period_bytes_min
=
128
,
.
period_bytes_max
=
AZX_MAX_BUF_SIZE
/
2
,
.
period_bytes_max
=
AZX_MAX_BUF_SIZE
/
2
,
...
@@ -691,7 +691,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
...
@@ -691,7 +691,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.
playback
=
{
.
playback
=
{
.
stream_name
=
"HDMI1 Playback"
,
.
stream_name
=
"HDMI1 Playback"
,
.
channels_min
=
HDA_STEREO
,
.
channels_min
=
HDA_STEREO
,
.
channels_max
=
HDA_STEREO
,
.
channels_max
=
8
,
.
rates
=
SNDRV_PCM_RATE_32000
|
SNDRV_PCM_RATE_44100
|
.
rates
=
SNDRV_PCM_RATE_32000
|
SNDRV_PCM_RATE_44100
|
SNDRV_PCM_RATE_48000
|
SNDRV_PCM_RATE_88200
|
SNDRV_PCM_RATE_48000
|
SNDRV_PCM_RATE_88200
|
SNDRV_PCM_RATE_96000
|
SNDRV_PCM_RATE_176400
|
SNDRV_PCM_RATE_96000
|
SNDRV_PCM_RATE_176400
|
...
@@ -706,7 +706,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
...
@@ -706,7 +706,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.
playback
=
{
.
playback
=
{
.
stream_name
=
"HDMI2 Playback"
,
.
stream_name
=
"HDMI2 Playback"
,
.
channels_min
=
HDA_STEREO
,
.
channels_min
=
HDA_STEREO
,
.
channels_max
=
HDA_STEREO
,
.
channels_max
=
8
,
.
rates
=
SNDRV_PCM_RATE_32000
|
SNDRV_PCM_RATE_44100
|
.
rates
=
SNDRV_PCM_RATE_32000
|
SNDRV_PCM_RATE_44100
|
SNDRV_PCM_RATE_48000
|
SNDRV_PCM_RATE_88200
|
SNDRV_PCM_RATE_48000
|
SNDRV_PCM_RATE_88200
|
SNDRV_PCM_RATE_96000
|
SNDRV_PCM_RATE_176400
|
SNDRV_PCM_RATE_96000
|
SNDRV_PCM_RATE_176400
|
...
@@ -721,7 +721,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
...
@@ -721,7 +721,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.
playback
=
{
.
playback
=
{
.
stream_name
=
"HDMI3 Playback"
,
.
stream_name
=
"HDMI3 Playback"
,
.
channels_min
=
HDA_STEREO
,
.
channels_min
=
HDA_STEREO
,
.
channels_max
=
HDA_STEREO
,
.
channels_max
=
8
,
.
rates
=
SNDRV_PCM_RATE_32000
|
SNDRV_PCM_RATE_44100
|
.
rates
=
SNDRV_PCM_RATE_32000
|
SNDRV_PCM_RATE_44100
|
SNDRV_PCM_RATE_48000
|
SNDRV_PCM_RATE_88200
|
SNDRV_PCM_RATE_48000
|
SNDRV_PCM_RATE_88200
|
SNDRV_PCM_RATE_96000
|
SNDRV_PCM_RATE_176400
|
SNDRV_PCM_RATE_96000
|
SNDRV_PCM_RATE_176400
|
...
@@ -846,7 +846,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
...
@@ -846,7 +846,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.
playback
=
{
.
playback
=
{
.
stream_name
=
"iDisp1 Tx"
,
.
stream_name
=
"iDisp1 Tx"
,
.
channels_min
=
HDA_STEREO
,
.
channels_min
=
HDA_STEREO
,
.
channels_max
=
HDA_STEREO
,
.
channels_max
=
8
,
.
rates
=
SNDRV_PCM_RATE_8000
|
SNDRV_PCM_RATE_16000
|
SNDRV_PCM_RATE_48000
,
.
rates
=
SNDRV_PCM_RATE_8000
|
SNDRV_PCM_RATE_16000
|
SNDRV_PCM_RATE_48000
,
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S32_LE
|
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S32_LE
|
SNDRV_PCM_FMTBIT_S24_LE
,
SNDRV_PCM_FMTBIT_S24_LE
,
...
@@ -858,7 +858,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
...
@@ -858,7 +858,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.
playback
=
{
.
playback
=
{
.
stream_name
=
"iDisp2 Tx"
,
.
stream_name
=
"iDisp2 Tx"
,
.
channels_min
=
HDA_STEREO
,
.
channels_min
=
HDA_STEREO
,
.
channels_max
=
HDA_STEREO
,
.
channels_max
=
8
,
.
rates
=
SNDRV_PCM_RATE_8000
|
SNDRV_PCM_RATE_16000
|
.
rates
=
SNDRV_PCM_RATE_8000
|
SNDRV_PCM_RATE_16000
|
SNDRV_PCM_RATE_48000
,
SNDRV_PCM_RATE_48000
,
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S32_LE
|
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S32_LE
|
...
@@ -871,7 +871,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
...
@@ -871,7 +871,7 @@ static struct snd_soc_dai_driver skl_platform_dai[] = {
.
playback
=
{
.
playback
=
{
.
stream_name
=
"iDisp3 Tx"
,
.
stream_name
=
"iDisp3 Tx"
,
.
channels_min
=
HDA_STEREO
,
.
channels_min
=
HDA_STEREO
,
.
channels_max
=
HDA_STEREO
,
.
channels_max
=
8
,
.
rates
=
SNDRV_PCM_RATE_8000
|
SNDRV_PCM_RATE_16000
|
.
rates
=
SNDRV_PCM_RATE_8000
|
SNDRV_PCM_RATE_16000
|
SNDRV_PCM_RATE_48000
,
SNDRV_PCM_RATE_48000
,
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S32_LE
|
.
formats
=
SNDRV_PCM_FMTBIT_S16_LE
|
SNDRV_PCM_FMTBIT_S32_LE
|
...
...
sound/soc/intel/skylake/skl-topology.c
View file @
515511a7
...
@@ -154,13 +154,32 @@ static void skl_dump_mconfig(struct skl_sst *ctx,
...
@@ -154,13 +154,32 @@ static void skl_dump_mconfig(struct skl_sst *ctx,
dev_dbg
(
ctx
->
dev
,
"ch_cfg = %d
\n
"
,
mcfg
->
out_fmt
[
0
].
ch_cfg
);
dev_dbg
(
ctx
->
dev
,
"ch_cfg = %d
\n
"
,
mcfg
->
out_fmt
[
0
].
ch_cfg
);
}
}
static
void
skl_tplg_update_chmap
(
struct
skl_module_fmt
*
fmt
,
int
chs
)
{
int
slot_map
=
0xFFFFFFFF
;
int
start_slot
=
0
;
int
i
;
for
(
i
=
0
;
i
<
chs
;
i
++
)
{
/*
* For 2 channels with starting slot as 0, slot map will
* look like 0xFFFFFF10.
*/
slot_map
&=
(
~
(
0xF
<<
(
4
*
i
))
|
(
start_slot
<<
(
4
*
i
)));
start_slot
++
;
}
fmt
->
ch_map
=
slot_map
;
}
static
void
skl_tplg_update_params
(
struct
skl_module_fmt
*
fmt
,
static
void
skl_tplg_update_params
(
struct
skl_module_fmt
*
fmt
,
struct
skl_pipe_params
*
params
,
int
fixup
)
struct
skl_pipe_params
*
params
,
int
fixup
)
{
{
if
(
fixup
&
SKL_RATE_FIXUP_MASK
)
if
(
fixup
&
SKL_RATE_FIXUP_MASK
)
fmt
->
s_freq
=
params
->
s_freq
;
fmt
->
s_freq
=
params
->
s_freq
;
if
(
fixup
&
SKL_CH_FIXUP_MASK
)
if
(
fixup
&
SKL_CH_FIXUP_MASK
)
{
fmt
->
channels
=
params
->
ch
;
fmt
->
channels
=
params
->
ch
;
skl_tplg_update_chmap
(
fmt
,
fmt
->
channels
);
}
if
(
fixup
&
SKL_FMT_FIXUP_MASK
)
{
if
(
fixup
&
SKL_FMT_FIXUP_MASK
)
{
fmt
->
valid_bit_depth
=
skl_get_bit_depth
(
params
->
s_fmt
);
fmt
->
valid_bit_depth
=
skl_get_bit_depth
(
params
->
s_fmt
);
...
...
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