提交 4e25d30c 编写于 作者: T Takashi Iwai

Merge tag 'asoc-v4.11' of...

Merge tag 'asoc-v4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus

ASoC: Updates for v4.11

Another release that's mainly focused on drivers rather than core
changes, highlights include:

 - A huge batch of updates to the Intel drivers, mainly around
   DisplayPort and HDMI with some additional board support too.
 - Channel mapping support for HDMI.
 - Support for AllWinner A31 and A33, Everest Semiconductor ES8328,
   Nuvoton NAU8540.
......@@ -24,6 +24,8 @@ Optional properties:
this parameter to choose where the clock from.
- By default the clock is from TK pin, if the clock from RK pin, this
property is needed.
- #sound-dai-cells: Should contain <0>.
- This property makes the SSC into an automatically registered DAI.
Examples:
- PDC transfer:
......
......@@ -2,8 +2,7 @@ Devicetree bindings for the Axentia TSE-850 audio complex
Required properties:
- compatible: "axentia,tse850-pcm5142"
- axentia,ssc-controller: The phandle of the atmel SSC controller used as
cpu dai.
- axentia,cpu-dai: The phandle of the cpu dai.
- axentia,audio-codec: The phandle of the PCM5142 codec.
- axentia,add-gpios: gpio specifier that controls the mixer.
- axentia,loop1-gpios: gpio specifier that controls loop relays on channel 1.
......@@ -43,6 +42,12 @@ the PCM5142 codec.
Example:
&ssc0 {
#sound-dai-cells = <0>;
status = "okay";
};
&i2c {
codec: pcm5142@4c {
compatible = "ti,pcm5142";
......@@ -77,7 +82,7 @@ Example:
sound {
compatible = "axentia,tse850-pcm5142";
axentia,ssc-controller = <&ssc0>;
axentia,cpu-dai = <&ssc0>;
axentia,audio-codec = <&codec>;
axentia,add-gpios = <&pioA 8 GPIO_ACTIVE_LOW>;
......
......@@ -4,7 +4,7 @@ This device supports both I2C and SPI.
Required properties:
- compatible : "everest,es8328"
- compatible : Should be "everest,es8328" or "everest,es8388"
- DVDD-supply : Regulator providing digital core supply voltage 1.8 - 3.6V
- AVDD-supply : Regulator providing analog supply voltage 3.3V
- PVDD-supply : Regulator providing digital IO supply voltage 1.8 - 3.6V
......
......@@ -4,6 +4,7 @@ Required properties:
- compatible = "mediatek,mt2701-audio";
- reg: register location and size
- interrupts: Should contain AFE interrupt
- power-domains: should define the power domain
- clock-names: should have these clock names:
"infra_sys_audio_clk",
"top_audio_mux1_sel",
......@@ -58,6 +59,7 @@ Example:
<0 0x112A0000 0 0x20000>;
interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_LOW>,
<GIC_SPI 132 IRQ_TYPE_LEVEL_LOW>;
power-domains = <&scpsys MT2701_POWER_DOMAIN_IFR_MSC>;
clocks = <&infracfg CLK_INFRA_AUDIO>,
<&topckgen CLK_TOP_AUD_MUX1_SEL>,
<&topckgen CLK_TOP_AUD_MUX2_SEL>,
......
NAU85L40 audio CODEC
This device supports I2C only.
Required properties:
- compatible : "nuvoton,nau8540"
- reg : the I2C address of the device.
Example:
codec: nau8540@1c {
compatible = "nuvoton,nau8540";
reg = <0x1c>;
};
ROCKCHIP RK3288 with HDMI and analog audio
Required properties:
- compatible: "rockchip,rk3288-hdmi-analog"
- rockchip,model: The user-visible name of this sound complex
- rockchip,i2s-controller: The phandle of the Rockchip I2S controller that's
connected to the CODEC
- rockchip,audio-codec: The phandle of the analog audio codec.
- rockchip,routing: A list of the connections between audio components.
Each entry is a pair of strings, the first being the
connection's sink, the second being the connection's
source. For this driver the first string should always be
"Analog".
Optionnal properties:
- rockchip,hp-en-gpios = The phandle of the GPIO that power up/down the
headphone (when the analog output is an headphone).
- rockchip,hp-det-gpios = The phandle of the GPIO that detects the headphone
(when the analog output is an headphone).
- pinctrl-names, pinctrl-0: Please refer to pinctrl-bindings.txt
Example:
sound {
compatible = "rockchip,rockchip-audio-es8388";
rockchip,model = "Analog audio output";
rockchip,i2s-controller = <&i2s>;
rockchip,audio-codec = <&es8388>;
rockchip,routing = "Analog", "LOUT2",
"Analog", "ROUT2";
rockchip,hp-en-gpios = <&gpio8 0 GPIO_ACTIVE_HIGH>;
rockchip,hp-det-gpios = <&gpio7 7 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&headphone>;
};
......@@ -7,6 +7,7 @@ Required properties:
- compatible: should be one of the followings
- "allwinner,sun4i-a10-i2s"
- "allwinner,sun6i-a31-i2s"
- reg: physical base address of the controller and length of memory mapped
region.
- interrupts: should contain the I2S interrupt.
......@@ -19,6 +20,10 @@ Required properties:
- "mod" : module clock for the I2S controller
- #sound-dai-cells : Must be equal to 0
Required properties for the following compatibles:
- "allwinner,sun6i-a31-i2s"
- resets: phandle to the reset line for this codec
Example:
i2s0: i2s@01c22400 {
......
Allwinner SUN8I audio codec
------------------------------------
On Sun8i-A33 SoCs, the audio is separated in different parts:
- A DAI driver. It uses the "sun4i-i2s" driver which is
documented here:
Documentation/devicetree/bindings/sound/sun4i-i2s.txt
- An analog part of the codec which is handled as PRCM registers.
See Documentation/devicetree/bindings/sound/sun8i-codec-analog.txt
- An digital part of the codec which is documented in this current
binding documentation.
- And finally, an audio card which links all the above components.
The simple-audio card will be used.
See Documentation/devicetree/bindings/sound/simple-card.txt
This bindings documentation exposes Sun8i codec (digital part).
Required properties:
- compatible: must be "allwinner,sun8i-a33-codec"
- reg: must contain the registers location and length
- interrupts: must contain the codec interrupt
- clocks: a list of phandle + clock-specifer pairs, one for each entry
in clock-names.
- clock-names: should contain followings:
- "bus": the parent APB clock for this controller
- "mod": the parent module clock
Here is an example to add a sound card and the codec binding on sun8i SoCs that
are similar to A33 using simple-card:
sound {
compatible = "simple-audio-card";
simple-audio-card,name = "sun8i-a33-audio";
simple-audio-card,format = "i2s";
simple-audio-card,frame-master = <&link_codec>;
simple-audio-card,bitclock-master = <&link_codec>;
simple-audio-card,mclk-fs = <512>;
simple-audio-card,aux-devs = <&codec_analog>;
simple-audio-card,routing =
"Left DAC", "Digital Left DAC",
"Right DAC", "Digital Right DAC";
simple-audio-card,cpu {
sound-dai = <&dai>;
};
link_codec: simple-audio-card,codec {
sound-dai = <&codec>;
};
soc@01c00000 {
[...]
audio-codec@1c22e00 {
#sound-dai-cells = <0>;
compatible = "allwinner,sun8i-a33-codec";
reg = <0x01c22e00 0x400>;
interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
clock-names = "bus", "mod";
};
};
......@@ -10,6 +10,7 @@ Required properties:
- compatible : should be one of the following:
- "allwinner,sun4i-a10-spdif": for the Allwinner A10 SoC
- "allwinner,sun6i-a31-spdif": for the Allwinner A31 SoC
- "allwinner,sun8i-h3-spdif": for the Allwinner H3 SoC
- reg : Offset and length of the register set for the device.
......
ZTE ZX296702 I2S controller
Required properties:
- compatible : Must be "zte,zx296702-i2s"
- compatible : Must be one of:
"zte,zx296718-i2s", "zte,zx296702-i2s"
"zte,zx296702-i2s"
- reg : Must contain I2S core's registers location and length
- clocks : Pairs of phandle and specifier referencing the controller's clocks.
- clock-names: "tx" for the clock to the I2S interface.
- clock-names: "wclk" for the wclk, "pclk" for the pclk to the I2S interface.
- dmas: Pairs of phandle and specifier for the DMA channel that is used by
the core. The core expects two dma channels for transmit.
- dma-names : Must be "tx" and "rx"
......@@ -16,12 +18,12 @@ please check:
* dma/dma.txt
Example:
i2s0: i2s0@0b005000 {
i2s0: i2s@b005000 {
#sound-dai-cells = <0>;
compatible = "zte,zx296702-i2s";
compatible = "zte,zx296718-i2s", "zte,zx296702-i2s";
reg = <0x0b005000 0x1000>;
clocks = <&lsp0clk ZX296702_I2S0_DIV>;
clock-names = "tx";
clocks = <&audiocrm AUDIO_I2S0_WCLK>, <&audiocrm AUDIO_I2S0_PCLK>;
clock-names = "wclk", "pclk";
interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
dmas = <&dma 5>, <&dma 6>;
dma-names = "tx", "rx";
......
......@@ -106,9 +106,7 @@ static struct s3c_audio_pdata i2sv4_pdata = {
.dma_playback = DMACH_HSI_I2SV40_TX,
.dma_capture = DMACH_HSI_I2SV40_RX,
.type = {
.i2s = {
.quirks = QUIRK_PRI_6CHAN,
},
.quirks = QUIRK_PRI_6CHAN,
},
};
......
......@@ -20,6 +20,8 @@
#include <linux/of.h>
#include "../../sound/soc/atmel/atmel_ssc_dai.h"
/* Serialize access to ssc_list and user count */
static DEFINE_SPINLOCK(user_lock);
static LIST_HEAD(ssc_list);
......@@ -145,6 +147,49 @@ static inline const struct atmel_ssc_platform_data * __init
platform_get_device_id(pdev)->driver_data;
}
#ifdef CONFIG_SND_ATMEL_SOC_SSC
static int ssc_sound_dai_probe(struct ssc_device *ssc)
{
struct device_node *np = ssc->pdev->dev.of_node;
int ret;
int id;
ssc->sound_dai = false;
if (!of_property_read_bool(np, "#sound-dai-cells"))
return 0;
id = of_alias_get_id(np, "ssc");
if (id < 0)
return id;
ret = atmel_ssc_set_audio(id);
ssc->sound_dai = !ret;
return ret;
}
static void ssc_sound_dai_remove(struct ssc_device *ssc)
{
if (!ssc->sound_dai)
return;
atmel_ssc_put_audio(of_alias_get_id(ssc->pdev->dev.of_node, "ssc"));
}
#else
static inline int ssc_sound_dai_probe(struct ssc_device *ssc)
{
if (of_property_read_bool(ssc->pdev->dev.of_node, "#sound-dai-cells"))
return -ENOTSUPP;
return 0;
}
static inline void ssc_sound_dai_remove(struct ssc_device *ssc)
{
}
#endif
static int ssc_probe(struct platform_device *pdev)
{
struct resource *regs;
......@@ -204,6 +249,9 @@ static int ssc_probe(struct platform_device *pdev)
dev_info(&pdev->dev, "Atmel SSC device at 0x%p (irq %d)\n",
ssc->regs, ssc->irq);
if (ssc_sound_dai_probe(ssc))
dev_err(&pdev->dev, "failed to auto-setup ssc for audio\n");
return 0;
}
......@@ -211,6 +259,8 @@ static int ssc_remove(struct platform_device *pdev)
{
struct ssc_device *ssc = platform_get_drvdata(pdev);
ssc_sound_dai_remove(ssc);
spin_lock(&user_lock);
list_del(&ssc->list);
spin_unlock(&user_lock);
......
......@@ -248,6 +248,7 @@ struct detailed_timing {
# define DRM_ELD_AUD_SYNCH_DELAY_MAX 0xfa /* 500 ms */
#define DRM_ELD_SPEAKER 7
# define DRM_ELD_SPEAKER_MASK 0x7f
# define DRM_ELD_SPEAKER_RLRC (1 << 6)
# define DRM_ELD_SPEAKER_FLRC (1 << 5)
# define DRM_ELD_SPEAKER_RC (1 << 4)
......@@ -413,6 +414,18 @@ static inline int drm_eld_size(const uint8_t *eld)
return DRM_ELD_HEADER_BLOCK_SIZE + eld[DRM_ELD_BASELINE_ELD_LEN] * 4;
}
/**
* drm_eld_get_spk_alloc - Get speaker allocation
* @eld: pointer to an ELD memory structure
*
* The returned value is the speakers mask. User has to use %DRM_ELD_SPEAKER
* field definitions to identify speakers.
*/
static inline u8 drm_eld_get_spk_alloc(const uint8_t *eld)
{
return eld[DRM_ELD_SPEAKER] & DRM_ELD_SPEAKER_MASK;
}
/**
* drm_eld_get_conn_type - Get device type hdmi/dp connected
* @eld: pointer to an ELD memory structure
......
......@@ -20,6 +20,7 @@ struct ssc_device {
int user;
int irq;
bool clk_from_rk_pin;
bool sound_dai;
};
struct ssc_device * __must_check ssc_request(unsigned int ssc_num);
......
......@@ -18,7 +18,7 @@
extern void s3c64xx_ac97_setup_gpio(int);
struct samsung_i2s {
struct samsung_i2s_type {
/* If the Primary DAI has 5.1 Channels */
#define QUIRK_PRI_6CHAN (1 << 0)
/* If the I2S block has a Stereo Overlay Channel */
......@@ -47,7 +47,5 @@ struct s3c_audio_pdata {
void *dma_capture;
void *dma_play_sec;
void *dma_capture_mic;
union {
struct samsung_i2s i2s;
} type;
struct samsung_i2s_type type;
};
......@@ -71,6 +71,7 @@ struct dma_chan *snd_dmaengine_pcm_get_chan(struct snd_pcm_substream *substream)
* @slave_id: Slave requester id for the DMA channel.
* @filter_data: Custom DMA channel filter data, this will usually be used when
* requesting the DMA channel.
* @chan_name: Custom channel name to use when requesting DMA channel.
* @fifo_size: FIFO size of the DAI controller in bytes
* @flags: PCM_DAI flags, only SND_DMAENGINE_PCM_DAI_FLAG_PACK for now
*/
......@@ -80,6 +81,7 @@ struct snd_dmaengine_dai_dma_data {
u32 maxburst;
unsigned int slave_id;
void *filter_data;
const char *chan_name;
unsigned int fifo_size;
unsigned int flags;
};
......@@ -105,6 +107,10 @@ void snd_dmaengine_pcm_set_config_from_dai_data(
* playback.
*/
#define SND_DMAENGINE_PCM_FLAG_HALF_DUPLEX BIT(3)
/*
* The PCM streams have custom channel names specified.
*/
#define SND_DMAENGINE_PCM_FLAG_CUSTOM_CHANNEL_NAME BIT(4)
/**
* struct snd_dmaengine_pcm_config - Configuration data for dmaengine based PCM
......
......@@ -34,11 +34,12 @@ int asoc_simple_card_set_dailink_name(struct device *dev,
int asoc_simple_card_parse_card_name(struct snd_soc_card *card,
char *prefix);
#define asoc_simple_card_parse_clk_cpu(node, dai_link, simple_dai) \
asoc_simple_card_parse_clk(node, dai_link->cpu_of_node, simple_dai)
#define asoc_simple_card_parse_clk_codec(node, dai_link, simple_dai) \
asoc_simple_card_parse_clk(node, dai_link->codec_of_node, simple_dai)
int asoc_simple_card_parse_clk(struct device_node *node,
#define asoc_simple_card_parse_clk_cpu(dev, node, dai_link, simple_dai) \
asoc_simple_card_parse_clk(dev, node, dai_link->cpu_of_node, simple_dai)
#define asoc_simple_card_parse_clk_codec(dev, node, dai_link, simple_dai) \
asoc_simple_card_parse_clk(dev, node, dai_link->codec_of_node, simple_dai)
int asoc_simple_card_parse_clk(struct device *dev,
struct device_node *node,
struct device_node *dai_of_node,
struct asoc_simple_dai *simple_dai);
......
......@@ -256,6 +256,9 @@ struct snd_soc_dai_driver {
int (*resume)(struct snd_soc_dai *dai);
/* compress dai */
int (*compress_new)(struct snd_soc_pcm_runtime *rtd, int num);
/* Optional Callback used at pcm creation*/
int (*pcm_new)(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_dai *dai);
/* DAI is also used for the control bus */
bool bus_control;
......
......@@ -497,6 +497,8 @@ void snd_soc_runtime_deactivate(struct snd_soc_pcm_runtime *rtd, int stream);
int snd_soc_runtime_set_dai_fmt(struct snd_soc_pcm_runtime *rtd,
unsigned int dai_fmt);
int snd_soc_set_dmi_name(struct snd_soc_card *card, const char *flavour);
/* Utility functions to get clock rates from various things */
int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots);
int snd_soc_params_to_frame_size(struct snd_pcm_hw_params *params);
......@@ -507,9 +509,6 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *parms);
int snd_soc_set_runtime_hwparams(struct snd_pcm_substream *substream,
const struct snd_pcm_hardware *hw);
int snd_soc_platform_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_platform *platform);
int soc_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai);
......@@ -785,6 +784,10 @@ struct snd_soc_component_driver {
int (*suspend)(struct snd_soc_component *);
int (*resume)(struct snd_soc_component *);
/* pcm creation and destruction */
int (*pcm_new)(struct snd_soc_pcm_runtime *);
void (*pcm_free)(struct snd_pcm *);
/* DT */
int (*of_xlate_dai_name)(struct snd_soc_component *component,
struct of_phandle_args *args,
......@@ -859,6 +862,8 @@ struct snd_soc_component {
void (*remove)(struct snd_soc_component *);
int (*suspend)(struct snd_soc_component *);
int (*resume)(struct snd_soc_component *);
int (*pcm_new)(struct snd_soc_pcm_runtime *);
void (*pcm_free)(struct snd_pcm *);
/* machine specific init */
int (*init)(struct snd_soc_component *component);
......@@ -941,20 +946,11 @@ struct snd_soc_platform_driver {
int (*pcm_new)(struct snd_soc_pcm_runtime *);
void (*pcm_free)(struct snd_pcm *);
/*
* For platform caused delay reporting.
* Optional.
*/
snd_pcm_sframes_t (*delay)(struct snd_pcm_substream *,
struct snd_soc_dai *);
/* platform stream pcm ops */
const struct snd_pcm_ops *ops;
/* platform stream compress ops */
const struct snd_compr_ops *compr_ops;
int (*bespoke_trigger)(struct snd_pcm_substream *, int);
};
struct snd_soc_dai_link_component {
......@@ -1099,6 +1095,8 @@ struct snd_soc_card {
const char *name;
const char *long_name;
const char *driver_name;
char dmi_longname[80];
struct device *dev;
struct snd_card *snd_card;
struct module *owner;
......@@ -1647,37 +1645,21 @@ static inline struct snd_soc_platform *snd_soc_kcontrol_platform(
int snd_soc_util_init(void);
void snd_soc_util_exit(void);
#define snd_soc_of_parse_card_name(card, propname) \
snd_soc_of_parse_card_name_from_node(card, NULL, propname)
int snd_soc_of_parse_card_name_from_node(struct snd_soc_card *card,
struct device_node *np,
const char *propname);
#define snd_soc_of_parse_audio_simple_widgets(card, propname)\
snd_soc_of_parse_audio_simple_widgets_from_node(card, NULL, propname)
int snd_soc_of_parse_audio_simple_widgets_from_node(struct snd_soc_card *card,
struct device_node *np,
const char *propname);
int snd_soc_of_parse_card_name(struct snd_soc_card *card,
const char *propname);
int snd_soc_of_parse_audio_simple_widgets(struct snd_soc_card *card,
const char *propname);
int snd_soc_of_parse_tdm_slot(struct device_node *np,
unsigned int *tx_mask,
unsigned int *rx_mask,
unsigned int *slots,
unsigned int *slot_width);
#define snd_soc_of_parse_audio_prefix(card, codec_conf, of_node, propname) \
snd_soc_of_parse_audio_prefix_from_node(card, NULL, codec_conf, \
of_node, propname)
void snd_soc_of_parse_audio_prefix_from_node(struct snd_soc_card *card,
struct device_node *np,
void snd_soc_of_parse_audio_prefix(struct snd_soc_card *card,
struct snd_soc_codec_conf *codec_conf,
struct device_node *of_node,
const char *propname);
#define snd_soc_of_parse_audio_routing(card, propname) \
snd_soc_of_parse_audio_routing_from_node(card, NULL, propname)
int snd_soc_of_parse_audio_routing_from_node(struct snd_soc_card *card,
struct device_node *np,
const char *propname);
int snd_soc_of_parse_audio_routing(struct snd_soc_card *card,
const char *propname);
unsigned int snd_soc_of_parse_daifmt(struct device_node *np,
const char *prefix,
struct device_node **bitclkmaster,
......
......@@ -128,14 +128,17 @@ void snd_hdac_ext_stream_decouple(struct hdac_ext_bus *ebus,
{
struct hdac_stream *hstream = &stream->hstream;
struct hdac_bus *bus = &ebus->bus;
u32 val;
int mask = AZX_PPCTL_PROCEN(hstream->index);
spin_lock_irq(&bus->reg_lock);
if (decouple)
snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, 0,
AZX_PPCTL_PROCEN(hstream->index));
else
snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL,
AZX_PPCTL_PROCEN(hstream->index), 0);
val = readw(bus->ppcap + AZX_REG_PP_PPCTL) & mask;
if (decouple && !val)
snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, mask, mask);
else if (!decouple && val)
snd_hdac_updatel(bus->ppcap, AZX_REG_PP_PPCTL, mask, 0);
stream->decoupled = decouple;
spin_unlock_irq(&bus->reg_lock);
}
......
......@@ -670,13 +670,10 @@ static int acp_dma_hw_params(struct snd_pcm_substream *substream,
{
int status;
uint64_t size;
struct snd_dma_buffer *dma_buffer;
struct page *pg;
struct snd_pcm_runtime *runtime;
struct audio_substream_data *rtd;
dma_buffer = &substream->dma_buffer;
runtime = substream->runtime;
rtd = runtime->private_data;
......
......@@ -51,11 +51,7 @@
#include <sound/soc.h>
#include <sound/pcm_params.h>
#include "atmel_ssc_dai.h"
struct tse850_priv {
int ssc_id;
struct gpio_desc *add;
struct gpio_desc *loop1;
struct gpio_desc *loop2;
......@@ -329,23 +325,20 @@ static int tse850_dt_init(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct device_node *codec_np, *cpu_np;
struct snd_soc_card *card = &tse850_card;
struct snd_soc_dai_link *dailink = &tse850_dailink;
struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
if (!np) {
dev_err(&pdev->dev, "only device tree supported\n");
return -EINVAL;
}
cpu_np = of_parse_phandle(np, "axentia,ssc-controller", 0);
cpu_np = of_parse_phandle(np, "axentia,cpu-dai", 0);
if (!cpu_np) {
dev_err(&pdev->dev, "failed to get dai and pcm info\n");
dev_err(&pdev->dev, "failed to get cpu dai\n");
return -EINVAL;
}
dailink->cpu_of_node = cpu_np;
dailink->platform_of_node = cpu_np;
tse850->ssc_id = of_alias_get_id(cpu_np, "ssc");
of_node_put(cpu_np);
codec_np = of_parse_phandle(np, "axentia,audio-codec", 0);
......@@ -415,23 +408,14 @@ static int tse850_probe(struct platform_device *pdev)
return ret;
}
ret = atmel_ssc_set_audio(tse850->ssc_id);
if (ret != 0) {
dev_err(dev,
"failed to set SSC %d for audio\n", tse850->ssc_id);
goto err_disable_ana;
}
ret = snd_soc_register_card(card);
if (ret) {
dev_err(dev, "snd_soc_register_card failed\n");
goto err_put_audio;
goto err_disable_ana;
}
return 0;
err_put_audio:
atmel_ssc_put_audio(tse850->ssc_id);
err_disable_ana:
regulator_disable(tse850->ana);
return ret;
......@@ -443,7 +427,6 @@ static int tse850_remove(struct platform_device *pdev)
struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card);
snd_soc_unregister_card(card);
atmel_ssc_put_audio(tse850->ssc_id);
regulator_disable(tse850->ana);
return 0;
......
......@@ -45,7 +45,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_ALC5623 if I2C
select SND_SOC_ALC5632 if I2C
select SND_SOC_BT_SCO
select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC
select SND_SOC_CQ0093VC
select SND_SOC_CS35L32 if I2C
select SND_SOC_CS35L33 if I2C
select SND_SOC_CS35L34 if I2C
......@@ -95,6 +95,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_MAX9877 if I2C
select SND_SOC_MC13783 if MFD_MC13XXX
select SND_SOC_ML26124 if I2C
select SND_SOC_NAU8540 if I2C
select SND_SOC_NAU8810 if I2C
select SND_SOC_NAU8825 if I2C
select SND_SOC_HDMI_CODEC
......@@ -117,8 +118,8 @@ config SND_SOC_ALL_CODECS
select SND_SOC_RT5651 if I2C
select SND_SOC_RT5659 if I2C
select SND_SOC_RT5660 if I2C
select SND_SOC_RT5665 if I2C
select SND_SOC_RT5663 if I2C
select SND_SOC_RT5665 if I2C
select SND_SOC_RT5670 if I2C
select SND_SOC_RT5677 if I2C && SPI_MASTER
select SND_SOC_SGTL5000 if I2C
......@@ -525,14 +526,16 @@ config SND_SOC_HDMI_CODEC
select HDMI
config SND_SOC_ES8328
tristate "Everest Semi ES8328 CODEC"
tristate
config SND_SOC_ES8328_I2C
tristate
tristate "Everest Semi ES8328 CODEC (I2C)"
depends on I2C
select SND_SOC_ES8328
config SND_SOC_ES8328_SPI
tristate
tristate "Everest Semi ES8328 CODEC (SPI)"
depends on SPI_MASTER
select SND_SOC_ES8328
config SND_SOC_GTM601
......@@ -668,8 +671,8 @@ config SND_SOC_RL6231
default y if SND_SOC_RT5651=y
default y if SND_SOC_RT5659=y
default y if SND_SOC_RT5660=y
default y if SND_SOC_RT5665=y
default y if SND_SOC_RT5663=y
default y if SND_SOC_RT5665=y
default y if SND_SOC_RT5670=y
default y if SND_SOC_RT5677=y
default m if SND_SOC_RT5514=m
......@@ -679,8 +682,8 @@ config SND_SOC_RL6231
default m if SND_SOC_RT5651=m
default m if SND_SOC_RT5659=m
default m if SND_SOC_RT5660=m
default m if SND_SOC_RT5665=m
default m if SND_SOC_RT5663=m
default m if SND_SOC_RT5665=m
default m if SND_SOC_RT5670=m
default m if SND_SOC_RT5677=m
......@@ -728,10 +731,10 @@ config SND_SOC_RT5659
config SND_SOC_RT5660
tristate
config SND_SOC_RT5665
config SND_SOC_RT5663
tristate
config SND_SOC_RT5663
config SND_SOC_RT5665
tristate
config SND_SOC_RT5670
......@@ -1105,6 +1108,10 @@ config SND_SOC_MC13783
config SND_SOC_ML26124
tristate
config SND_SOC_NAU8540
tristate "Nuvoton Technology Corporation NAU85L40 CODEC"
depends on I2C
config SND_SOC_NAU8810
tristate "Nuvoton Technology Corporation NAU88C10 CODEC"
depends on I2C
......
......@@ -90,6 +90,7 @@ snd-soc-mc13783-objs := mc13783.o
snd-soc-ml26124-objs := ml26124.o
snd-soc-msm8916-analog-objs := msm8916-wcd-analog.o
snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o
snd-soc-nau8540-objs := nau8540.o
snd-soc-nau8810-objs := nau8810.o
snd-soc-nau8825-objs := nau8825.o
snd-soc-hdmi-codec-objs := hdmi-codec.o
......@@ -118,8 +119,8 @@ snd-soc-rt5645-objs := rt5645.o
snd-soc-rt5651-objs := rt5651.o
snd-soc-rt5659-objs := rt5659.o
snd-soc-rt5660-objs := rt5660.o
snd-soc-rt5665-objs := rt5665.o
snd-soc-rt5663-objs := rt5663.o
snd-soc-rt5665-objs := rt5665.o
snd-soc-rt5670-objs := rt5670.o
snd-soc-rt5677-objs := rt5677.o
snd-soc-rt5677-spi-objs := rt5677-spi.o
......@@ -318,6 +319,7 @@ obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
obj-$(CONFIG_SND_SOC_ML26124) += snd-soc-ml26124.o
obj-$(CONFIG_SND_SOC_MSM8916_WCD_ANALOG) +=snd-soc-msm8916-analog.o
obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o
obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o
obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o
obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o
obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o
......@@ -346,8 +348,8 @@ obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o
obj-$(CONFIG_SND_SOC_RT5651) += snd-soc-rt5651.o
obj-$(CONFIG_SND_SOC_RT5659) += snd-soc-rt5659.o
obj-$(CONFIG_SND_SOC_RT5660) += snd-soc-rt5660.o
obj-$(CONFIG_SND_SOC_RT5665) += snd-soc-rt5665.o
obj-$(CONFIG_SND_SOC_RT5663) += snd-soc-rt5663.o
obj-$(CONFIG_SND_SOC_RT5665) += snd-soc-rt5665.o
obj-$(CONFIG_SND_SOC_RT5670) += snd-soc-rt5670.o
obj-$(CONFIG_SND_SOC_RT5677) += snd-soc-rt5677.o
obj-$(CONFIG_SND_SOC_RT5677_SPI) += snd-soc-rt5677-spi.o
......
......@@ -65,7 +65,6 @@ static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
{
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
struct adau *adau = snd_soc_codec_get_drvdata(codec);
int ret;
if (SND_SOC_DAPM_EVENT_ON(event)) {
adau->pll_regs[5] = 1;
......@@ -78,7 +77,7 @@ static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,
}
/* The PLL register is 6 bytes long and can only be written at once. */
ret = regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL,
regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL,
adau->pll_regs, ARRAY_SIZE(adau->pll_regs));
if (SND_SOC_DAPM_EVENT_ON(event)) {
......
......@@ -189,7 +189,7 @@ static int ak4642_lout_event(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_POST_PMU:
case SND_SOC_DAPM_POST_PMD:
/* Power save mode OFF */
mdelay(300);
msleep(300);
snd_soc_update_bits(codec, SG_SL2, LOPS, 0);
break;
}
......
......@@ -192,6 +192,7 @@ extern unsigned int arizona_mixer_values[ARIZONA_NUM_MIXER_INPUTS];
#define ARIZONA_DSP_ROUTES(name) \
{ name, NULL, name " Preloader"}, \
{ name " Preloader", NULL, "SYSCLK" }, \
{ name " Preload", NULL, name " Preloader"}, \
{ name, NULL, name " Aux 1" }, \
{ name, NULL, name " Aux 2" }, \
{ name, NULL, name " Aux 3" }, \
......
......@@ -173,6 +173,9 @@ SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]),
SOC_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]),
SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1),
WM_ADSP2_PRELOAD_SWITCH("DSP2", 2),
WM_ADSP2_PRELOAD_SWITCH("DSP3", 3),
ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("DSP2R", ARIZONA_DSP2RMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("DSP3L", ARIZONA_DSP3LMIX_INPUT_1_SOURCE),
......@@ -1121,7 +1124,10 @@ static int cs47l24_codec_probe(struct snd_soc_codec *codec)
priv->core.arizona->dapm = dapm;
arizona_init_spk(codec);
ret = arizona_init_spk(codec);
if (ret < 0)
return ret;
arizona_init_gpio(codec);
arizona_init_mono(codec);
arizona_init_notifiers(codec);
......
......@@ -1634,7 +1634,8 @@ static const struct snd_soc_dapm_widget da7218_dapm_widgets[] = {
SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
/* DAI */
SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_OUT("DAIOUT", "Capture", 0, DA7218_DAI_TDM_CTRL,
DA7218_DAI_OE_SHIFT, DA7218_NO_INVERT),
SND_SOC_DAPM_AIF_IN("DAIIN", "Playback", 0, SND_SOC_NOPM, 0, 0),
/* Output Mixers */
......
......@@ -20,12 +20,14 @@
static const struct i2c_device_id es8328_id[] = {
{ "es8328", 0 },
{ "es8388", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, es8328_id);
static const struct of_device_id es8328_of_match[] = {
{ .compatible = "everest,es8328", },
{ .compatible = "everest,es8388", },
{ }
};
MODULE_DEVICE_TABLE(of, es8328_of_match);
......
......@@ -589,9 +589,21 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
u8 dac_mode = 0;
u8 adc_mode = 0;
/* set master/slave audio interface */
if ((fmt & SND_SOC_DAIFMT_MASTER_MASK) != SND_SOC_DAIFMT_CBM_CFM)
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM:
/* Master serial port mode, with BCLK generated automatically */
snd_soc_update_bits(codec, ES8328_MASTERMODE,
ES8328_MASTERMODE_MSC,
ES8328_MASTERMODE_MSC);
break;
case SND_SOC_DAIFMT_CBS_CFS:
/* Slave serial port mode */
snd_soc_update_bits(codec, ES8328_MASTERMODE,
ES8328_MASTERMODE_MSC, 0);
break;
default:
return -EINVAL;
}
/* interface format */
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
......@@ -620,10 +632,6 @@ static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,
snd_soc_update_bits(codec, ES8328_ADCCONTROL4,
ES8328_ADCCONTROL4_ADCFORMAT_MASK, adc_mode);
/* Master serial port mode, with BCLK generated automatically */
snd_soc_update_bits(codec, ES8328_MASTERMODE,
ES8328_MASTERMODE_MSC, ES8328_MASTERMODE_MSC);
return 0;
}
......
此差异已折叠。
#ifndef __HDAC_HDMI_H__
#define __HDAC_HDMI_H__
int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int pcm);
int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int pcm,
struct snd_soc_jack *jack);
int hdac_hdmi_jack_port_init(struct snd_soc_codec *codec,
struct snd_soc_dapm_context *dapm);
#endif /* __HDAC_HDMI_H__ */
......@@ -18,6 +18,7 @@
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include <sound/pcm_drm_eld.h>
#include <sound/hdmi-codec.h>
#include <sound/pcm_iec958.h>
......@@ -31,8 +32,261 @@ struct hdmi_device {
};
#define pos_to_hdmi_device(pos) container_of((pos), struct hdmi_device, list)
LIST_HEAD(hdmi_device_list);
static DEFINE_MUTEX(hdmi_mutex);
#define DAI_NAME_SIZE 16
#define HDMI_CODEC_CHMAP_IDX_UNKNOWN -1
struct hdmi_codec_channel_map_table {
unsigned char map; /* ALSA API channel map position */
unsigned long spk_mask; /* speaker position bit mask */
};
/*
* CEA speaker placement for HDMI 1.4:
*
* FL FLC FC FRC FR FRW
*
* LFE
*
* RL RLC RC RRC RR
*
* Speaker placement has to be extended to support HDMI 2.0
*/
enum hdmi_codec_cea_spk_placement {
FL = BIT(0), /* Front Left */
FC = BIT(1), /* Front Center */
FR = BIT(2), /* Front Right */
FLC = BIT(3), /* Front Left Center */
FRC = BIT(4), /* Front Right Center */
RL = BIT(5), /* Rear Left */
RC = BIT(6), /* Rear Center */
RR = BIT(7), /* Rear Right */
RLC = BIT(8), /* Rear Left Center */
RRC = BIT(9), /* Rear Right Center */
LFE = BIT(10), /* Low Frequency Effect */
};
/*
* cea Speaker allocation structure
*/
struct hdmi_codec_cea_spk_alloc {
const int ca_id;
unsigned int n_ch;
unsigned long mask;
};
/* Channel maps stereo HDMI */
const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = {
{ .channels = 2,
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
{ }
};
/* Channel maps for multi-channel playbacks, up to 8 n_ch */
const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = {
{ .channels = 2, /* CA_ID 0x00 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
{ .channels = 4, /* CA_ID 0x01 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA } },
{ .channels = 4, /* CA_ID 0x02 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC } },
{ .channels = 4, /* CA_ID 0x03 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC } },
{ .channels = 6, /* CA_ID 0x04 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 6, /* CA_ID 0x05 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 6, /* CA_ID 0x06 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 6, /* CA_ID 0x07 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 6, /* CA_ID 0x08 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
{ .channels = 6, /* CA_ID 0x09 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
{ .channels = 6, /* CA_ID 0x0A */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
{ .channels = 6, /* CA_ID 0x0B */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
{ .channels = 8, /* CA_ID 0x0C */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 8, /* CA_ID 0x0D */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 8, /* CA_ID 0x0E */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 8, /* CA_ID 0x0F */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
{ .channels = 8, /* CA_ID 0x10 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
{ .channels = 8, /* CA_ID 0x11 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
{ .channels = 8, /* CA_ID 0x12 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
{ .channels = 8, /* CA_ID 0x13 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
{ .channels = 8, /* CA_ID 0x14 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x15 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x16 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x17 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x18 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x19 */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x1A */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x1B */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x1C */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x1D */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x1E */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ .channels = 8, /* CA_ID 0x1F */
.map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
{ }
};
/*
* hdmi_codec_channel_alloc: speaker configuration available for CEA
*
* This is an ordered list that must match with hdmi_codec_8ch_chmaps struct
* The preceding ones have better chances to be selected by
* hdmi_codec_get_ch_alloc_table_idx().
*/
static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = {
{ .ca_id = 0x00, .n_ch = 2,
.mask = FL | FR},
/* 2.1 */
{ .ca_id = 0x01, .n_ch = 4,
.mask = FL | FR | LFE},
/* Dolby Surround */
{ .ca_id = 0x02, .n_ch = 4,
.mask = FL | FR | FC },
/* surround51 */
{ .ca_id = 0x0b, .n_ch = 6,
.mask = FL | FR | LFE | FC | RL | RR},
/* surround40 */
{ .ca_id = 0x08, .n_ch = 6,
.mask = FL | FR | RL | RR },
/* surround41 */
{ .ca_id = 0x09, .n_ch = 6,
.mask = FL | FR | LFE | RL | RR },
/* surround50 */
{ .ca_id = 0x0a, .n_ch = 6,
.mask = FL | FR | FC | RL | RR },
/* 6.1 */
{ .ca_id = 0x0f, .n_ch = 8,
.mask = FL | FR | LFE | FC | RL | RR | RC },
/* surround71 */
{ .ca_id = 0x13, .n_ch = 8,
.mask = FL | FR | LFE | FC | RL | RR | RLC | RRC },
/* others */
{ .ca_id = 0x03, .n_ch = 8,
.mask = FL | FR | LFE | FC },
{ .ca_id = 0x04, .n_ch = 8,
.mask = FL | FR | RC},
{ .ca_id = 0x05, .n_ch = 8,
.mask = FL | FR | LFE | RC },
{ .ca_id = 0x06, .n_ch = 8,
.mask = FL | FR | FC | RC },
{ .ca_id = 0x07, .n_ch = 8,
.mask = FL | FR | LFE | FC | RC },
{ .ca_id = 0x0c, .n_ch = 8,
.mask = FL | FR | RC | RL | RR },
{ .ca_id = 0x0d, .n_ch = 8,
.mask = FL | FR | LFE | RL | RR | RC },
{ .ca_id = 0x0e, .n_ch = 8,
.mask = FL | FR | FC | RL | RR | RC },
{ .ca_id = 0x10, .n_ch = 8,
.mask = FL | FR | RL | RR | RLC | RRC },
{ .ca_id = 0x11, .n_ch = 8,
.mask = FL | FR | LFE | RL | RR | RLC | RRC },
{ .ca_id = 0x12, .n_ch = 8,
.mask = FL | FR | FC | RL | RR | RLC | RRC },
{ .ca_id = 0x14, .n_ch = 8,
.mask = FL | FR | FLC | FRC },
{ .ca_id = 0x15, .n_ch = 8,
.mask = FL | FR | LFE | FLC | FRC },
{ .ca_id = 0x16, .n_ch = 8,
.mask = FL | FR | FC | FLC | FRC },
{ .ca_id = 0x17, .n_ch = 8,
.mask = FL | FR | LFE | FC | FLC | FRC },
{ .ca_id = 0x18, .n_ch = 8,
.mask = FL | FR | RC | FLC | FRC },
{ .ca_id = 0x19, .n_ch = 8,
.mask = FL | FR | LFE | RC | FLC | FRC },
{ .ca_id = 0x1a, .n_ch = 8,
.mask = FL | FR | RC | FC | FLC | FRC },
{ .ca_id = 0x1b, .n_ch = 8,
.mask = FL | FR | LFE | RC | FC | FLC | FRC },
{ .ca_id = 0x1c, .n_ch = 8,
.mask = FL | FR | RL | RR | FLC | FRC },
{ .ca_id = 0x1d, .n_ch = 8,
.mask = FL | FR | LFE | RL | RR | FLC | FRC },
{ .ca_id = 0x1e, .n_ch = 8,
.mask = FL | FR | FC | RL | RR | FLC | FRC },
{ .ca_id = 0x1f, .n_ch = 8,
.mask = FL | FR | LFE | FC | RL | RR | FLC | FRC },
};
struct hdmi_codec_priv {
struct hdmi_codec_pdata hcd;
struct snd_soc_dai_driver *daidrv;
......@@ -41,6 +295,8 @@ struct hdmi_codec_priv {
struct snd_pcm_substream *current_stream;
struct snd_pcm_hw_constraint_list ratec;
uint8_t eld[MAX_ELD_BYTES];
struct snd_pcm_chmap *chmap_info;
unsigned int chmap_idx;
};
static const struct snd_soc_dapm_widget hdmi_widgets[] = {
......@@ -79,6 +335,83 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
return 0;
}
static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc)
{
int i;
const unsigned long hdmi_codec_eld_spk_alloc_bits[] = {
[0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR,
[4] = RC, [5] = FLC | FRC, [6] = RLC | RRC,
};
unsigned long spk_mask = 0;
for (i = 0; i < ARRAY_SIZE(hdmi_codec_eld_spk_alloc_bits); i++) {
if (spk_alloc & (1 << i))
spk_mask |= hdmi_codec_eld_spk_alloc_bits[i];
}
return spk_mask;
}
void hdmi_codec_eld_chmap(struct hdmi_codec_priv *hcp)
{
u8 spk_alloc;
unsigned long spk_mask;
spk_alloc = drm_eld_get_spk_alloc(hcp->eld);
spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
/* Detect if only stereo supported, else return 8 channels mappings */
if ((spk_mask & ~(FL | FR)) && hcp->chmap_info->max_channels > 2)
hcp->chmap_info->chmap = hdmi_codec_8ch_chmaps;
else
hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps;
}
static int hdmi_codec_get_ch_alloc_table_idx(struct hdmi_codec_priv *hcp,
unsigned char channels)
{
int i;
u8 spk_alloc;
unsigned long spk_mask;
const struct hdmi_codec_cea_spk_alloc *cap = hdmi_codec_channel_alloc;
spk_alloc = drm_eld_get_spk_alloc(hcp->eld);
spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
for (i = 0; i < ARRAY_SIZE(hdmi_codec_channel_alloc); i++, cap++) {
/* If spk_alloc == 0, HDMI is unplugged return stereo config*/
if (!spk_alloc && cap->ca_id == 0)
return i;
if (cap->n_ch != channels)
continue;
if (!(cap->mask == (spk_mask & cap->mask)))
continue;
return i;
}
return -EINVAL;
}
static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
unsigned const char *map;
unsigned int i;
struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
struct hdmi_codec_priv *hcp = info->private_data;
map = info->chmap[hcp->chmap_idx].map;
for (i = 0; i < info->max_channels; i++) {
if (hcp->chmap_idx == HDMI_CODEC_CHMAP_IDX_UNKNOWN)
ucontrol->value.integer.value[i] = 0;
else
ucontrol->value.integer.value[i] = map[i];
}
return 0;
}
static const struct snd_kcontrol_new hdmi_controls[] = {
{
.access = SNDRV_CTL_ELEM_ACCESS_READ |
......@@ -140,6 +473,8 @@ static int hdmi_codec_startup(struct snd_pcm_substream *substream,
if (ret)
return ret;
}
/* Select chmap supported */
hdmi_codec_eld_chmap(hcp);
}
return 0;
}
......@@ -153,6 +488,7 @@ static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
WARN_ON(hcp->current_stream != substream);
hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
mutex_lock(&hcp->current_stream_lock);
......@@ -173,7 +509,7 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
.dig_subframe = { 0 },
}
};
int ret;
int ret, idx;
dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
params_width(params), params_rate(params),
......@@ -200,6 +536,17 @@ static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
hp.cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
hp.cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
/* Select a channel allocation that matches with ELD and pcm channels */
idx = hdmi_codec_get_ch_alloc_table_idx(hcp, hp.cea.channels);
if (idx < 0) {
dev_err(dai->dev, "Not able to map channels to speakers (%d)\n",
idx);
hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
return idx;
}
hp.cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id;
hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id;
hp.sample_width = params_width(params);
hp.sample_rate = params_rate(params);
hp.channels = params_channels(params);
......@@ -328,6 +675,32 @@ static const struct snd_soc_dai_ops hdmi_dai_ops = {
SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
struct snd_soc_dai *dai)
{
struct snd_soc_dai_driver *drv = dai->driver;
struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
int ret;
dev_dbg(dai->dev, "%s()\n", __func__);
ret = snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK,
NULL, drv->playback.channels_max, 0,
&hcp->chmap_info);
if (ret < 0)
return ret;
/* override handlers */
hcp->chmap_info->private_data = hcp;
hcp->chmap_info->kctl->get = hdmi_codec_chmap_ctl_get;
/* default chmap supported is stereo */
hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps;
hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
return 0;
}
static struct snd_soc_dai_driver hdmi_i2s_dai = {
.id = DAI_ID_I2S,
.playback = {
......@@ -339,6 +712,7 @@ static struct snd_soc_dai_driver hdmi_i2s_dai = {
.sig_bits = 24,
},
.ops = &hdmi_dai_ops,
.pcm_new = hdmi_codec_pcm_new,
};
static const struct snd_soc_dai_driver hdmi_spdif_dai = {
......@@ -351,6 +725,7 @@ static const struct snd_soc_dai_driver hdmi_spdif_dai = {
.formats = SPDIF_FORMATS,
},
.ops = &hdmi_dai_ops,
.pcm_new = hdmi_codec_pcm_new,
};
static char hdmi_dai_name[][DAI_NAME_SIZE] = {
......@@ -420,6 +795,7 @@ static int hdmi_codec_probe(struct platform_device *pdev)
return -ENOMEM;
hd = NULL;
mutex_lock(&hdmi_mutex);
list_for_each(pos, &hdmi_device_list) {
struct hdmi_device *tmp = pos_to_hdmi_device(pos);
......@@ -431,13 +807,16 @@ static int hdmi_codec_probe(struct platform_device *pdev)
if (!hd) {
hd = devm_kzalloc(dev, sizeof(*hd), GFP_KERNEL);
if (!hd)
if (!hd) {
mutex_unlock(&hdmi_mutex);
return -ENOMEM;
}
hd->dev = dev->parent;
list_add_tail(&hd->list, &hdmi_device_list);
}
mutex_unlock(&hdmi_mutex);
if (hd->cnt >= ARRAY_SIZE(hdmi_dai_name)) {
dev_err(dev, "too many hdmi codec are deteced\n");
......@@ -479,7 +858,25 @@ static int hdmi_codec_probe(struct platform_device *pdev)
static int hdmi_codec_remove(struct platform_device *pdev)
{
snd_soc_unregister_codec(&pdev->dev);
struct device *dev = &pdev->dev;
struct list_head *pos;
struct hdmi_codec_priv *hcp;
mutex_lock(&hdmi_mutex);
list_for_each(pos, &hdmi_device_list) {
struct hdmi_device *tmp = pos_to_hdmi_device(pos);
if (tmp->dev == dev->parent) {
list_del(pos);
break;
}
}
mutex_unlock(&hdmi_mutex);
hcp = dev_get_drvdata(dev);
kfree(hcp->chmap_info);
snd_soc_unregister_codec(dev);
return 0;
}
......
......@@ -2456,7 +2456,7 @@ static int max98090_probe(struct snd_soc_codec *codec)
if (err) {
micbias = M98090_MBVSEL_2V8;
dev_info(codec->dev, "use default 2.8v micbias\n");
} else if (micbias < M98090_MBVSEL_2V2 || micbias > M98090_MBVSEL_2V8) {
} else if (micbias > M98090_MBVSEL_2V8) {
dev_err(codec->dev, "micbias out of range 0x%x\n", micbias);
micbias = M98090_MBVSEL_2V8;
}
......
......@@ -309,7 +309,6 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
struct snd_soc_codec *codec = codec_dai->codec;
struct max9867_priv *max9867 = snd_soc_codec_get_drvdata(codec);
u8 iface1A = 0, iface1B = 0;
int ret;
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
case SND_SOC_DAIFMT_CBM_CFM:
......@@ -346,8 +345,8 @@ static int max9867_dai_set_fmt(struct snd_soc_dai *codec_dai,
return -EINVAL;
}
ret = regmap_write(max9867->regmap, MAX9867_IFC1A, iface1A);
ret = regmap_write(max9867->regmap, MAX9867_IFC1B, iface1B);
regmap_write(max9867->regmap, MAX9867_IFC1A, iface1A);
regmap_write(max9867->regmap, MAX9867_IFC1B, iface1B);
return 0;
}
......
此差异已折叠。
/*
* NAU85L40 ALSA SoC audio driver
*
* Copyright 2016 Nuvoton Technology Corp.
* Author: John Hsu <KCHSU0@nuvoton.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.
*/
#ifndef __NAU8540_H__
#define __NAU8540_H__
#define NAU8540_REG_SW_RESET 0x00
#define NAU8540_REG_POWER_MANAGEMENT 0x01
#define NAU8540_REG_CLOCK_CTRL 0x02
#define NAU8540_REG_CLOCK_SRC 0x03
#define NAU8540_REG_FLL1 0x04
#define NAU8540_REG_FLL2 0x05
#define NAU8540_REG_FLL3 0x06
#define NAU8540_REG_FLL4 0x07
#define NAU8540_REG_FLL5 0x08
#define NAU8540_REG_FLL6 0x09
#define NAU8540_REG_FLL_VCO_RSV 0x0A
#define NAU8540_REG_PCM_CTRL0 0x10
#define NAU8540_REG_PCM_CTRL1 0x11
#define NAU8540_REG_PCM_CTRL2 0x12
#define NAU8540_REG_PCM_CTRL3 0x13
#define NAU8540_REG_PCM_CTRL4 0x14
#define NAU8540_REG_ALC_CONTROL_1 0x20
#define NAU8540_REG_ALC_CONTROL_2 0x21
#define NAU8540_REG_ALC_CONTROL_3 0x22
#define NAU8540_REG_ALC_CONTROL_4 0x23
#define NAU8540_REG_ALC_CONTROL_5 0x24
#define NAU8540_REG_ALC_GAIN_CH12 0x2D
#define NAU8540_REG_ALC_GAIN_CH34 0x2E
#define NAU8540_REG_ALC_STATUS 0x2F
#define NAU8540_REG_NOTCH_FIL1_CH1 0x30
#define NAU8540_REG_NOTCH_FIL2_CH1 0x31
#define NAU8540_REG_NOTCH_FIL1_CH2 0x32
#define NAU8540_REG_NOTCH_FIL2_CH2 0x33
#define NAU8540_REG_NOTCH_FIL1_CH3 0x34
#define NAU8540_REG_NOTCH_FIL2_CH3 0x35
#define NAU8540_REG_NOTCH_FIL1_CH4 0x36
#define NAU8540_REG_NOTCH_FIL2_CH4 0x37
#define NAU8540_REG_HPF_FILTER_CH12 0x38
#define NAU8540_REG_HPF_FILTER_CH34 0x39
#define NAU8540_REG_ADC_SAMPLE_RATE 0x3A
#define NAU8540_REG_DIGITAL_GAIN_CH1 0x40
#define NAU8540_REG_DIGITAL_GAIN_CH2 0x41
#define NAU8540_REG_DIGITAL_GAIN_CH3 0x42
#define NAU8540_REG_DIGITAL_GAIN_CH4 0x43
#define NAU8540_REG_DIGITAL_MUX 0x44
#define NAU8540_REG_P2P_CH1 0x48
#define NAU8540_REG_P2P_CH2 0x49
#define NAU8540_REG_P2P_CH3 0x4A
#define NAU8540_REG_P2P_CH4 0x4B
#define NAU8540_REG_PEAK_CH1 0x4C
#define NAU8540_REG_PEAK_CH2 0x4D
#define NAU8540_REG_PEAK_CH3 0x4E
#define NAU8540_REG_PEAK_CH4 0x4F
#define NAU8540_REG_GPIO_CTRL 0x50
#define NAU8540_REG_MISC_CTRL 0x51
#define NAU8540_REG_I2C_CTRL 0x52
#define NAU8540_REG_I2C_DEVICE_ID 0x58
#define NAU8540_REG_RST 0x5A
#define NAU8540_REG_VMID_CTRL 0x60
#define NAU8540_REG_MUTE 0x61
#define NAU8540_REG_ANALOG_ADC1 0x64
#define NAU8540_REG_ANALOG_ADC2 0x65
#define NAU8540_REG_ANALOG_PWR 0x66
#define NAU8540_REG_MIC_BIAS 0x67
#define NAU8540_REG_REFERENCE 0x68
#define NAU8540_REG_FEPGA1 0x69
#define NAU8540_REG_FEPGA2 0x6A
#define NAU8540_REG_FEPGA3 0x6B
#define NAU8540_REG_FEPGA4 0x6C
#define NAU8540_REG_PWR 0x6D
#define NAU8540_REG_MAX NAU8540_REG_PWR
/* POWER_MANAGEMENT (0x01) */
#define NAU8540_ADC4_EN (0x1 << 3)
#define NAU8540_ADC3_EN (0x1 << 2)
#define NAU8540_ADC2_EN (0x1 << 1)
#define NAU8540_ADC1_EN 0x1
/* CLOCK_CTRL (0x02) */
#define NAU8540_CLK_ADC_EN (0x1 << 15)
#define NAU8540_CLK_I2S_EN (0x1 << 1)
/* CLOCK_SRC (0x03) */
#define NAU8540_CLK_SRC_SFT 15
#define NAU8540_CLK_SRC_MASK (1 << NAU8540_CLK_SRC_SFT)
#define NAU8540_CLK_SRC_VCO (1 << NAU8540_CLK_SRC_SFT)
#define NAU8540_CLK_SRC_MCLK (0 << NAU8540_CLK_SRC_SFT)
#define NAU8540_CLK_ADC_SRC_SFT 6
#define NAU8540_CLK_ADC_SRC_MASK (0x3 << NAU8540_CLK_ADC_SRC_SFT)
#define NAU8540_CLK_MCLK_SRC_MASK 0xf
/* FLL1 (0x04) */
#define NAU8540_FLL_RATIO_MASK 0x7f
/* FLL3 (0x06) */
#define NAU8540_FLL_CLK_SRC_SFT 10
#define NAU8540_FLL_CLK_SRC_MASK (0x3 << NAU8540_FLL_CLK_SRC_SFT)
#define NAU8540_FLL_CLK_SRC_MCLK (0 << NAU8540_FLL_CLK_SRC_SFT)
#define NAU8540_FLL_CLK_SRC_BLK (0x2 << NAU8540_FLL_CLK_SRC_SFT)
#define NAU8540_FLL_CLK_SRC_FS (0x3 << NAU8540_FLL_CLK_SRC_SFT)
#define NAU8540_FLL_INTEGER_MASK 0x3ff
/* FLL4 (0x07) */
#define NAU8540_FLL_REF_DIV_SFT 10
#define NAU8540_FLL_REF_DIV_MASK (0x3 << NAU8540_FLL_REF_DIV_SFT)
/* FLL5 (0x08) */
#define NAU8540_FLL_PDB_DAC_EN (0x1 << 15)
#define NAU8540_FLL_LOOP_FTR_EN (0x1 << 14)
#define NAU8540_FLL_CLK_SW_MASK (0x1 << 13)
#define NAU8540_FLL_CLK_SW_N2 (0x1 << 13)
#define NAU8540_FLL_CLK_SW_REF (0x0 << 13)
#define NAU8540_FLL_FTR_SW_MASK (0x1 << 12)
#define NAU8540_FLL_FTR_SW_ACCU (0x1 << 12)
#define NAU8540_FLL_FTR_SW_FILTER (0x0 << 12)
/* FLL6 (0x9) */
#define NAU8540_DCO_EN (0x1 << 15)
#define NAU8540_SDM_EN (0x1 << 14)
/* PCM_CTRL0 (0x10) */
#define NAU8540_I2S_BP_SFT 7
#define NAU8540_I2S_BP_INV (0x1 << NAU8540_I2S_BP_SFT)
#define NAU8540_I2S_PCMB_SFT 6
#define NAU8540_I2S_PCMB_EN (0x1 << NAU8540_I2S_PCMB_SFT)
#define NAU8540_I2S_DL_SFT 2
#define NAU8540_I2S_DL_MASK (0x3 << NAU8540_I2S_DL_SFT)
#define NAU8540_I2S_DL_16 (0 << NAU8540_I2S_DL_SFT)
#define NAU8540_I2S_DL_20 (0x1 << NAU8540_I2S_DL_SFT)
#define NAU8540_I2S_DL_24 (0x2 << NAU8540_I2S_DL_SFT)
#define NAU8540_I2S_DL_32 (0x3 << NAU8540_I2S_DL_SFT)
#define NAU8540_I2S_DF_MASK 0x3
#define NAU8540_I2S_DF_RIGTH 0
#define NAU8540_I2S_DF_LEFT 0x1
#define NAU8540_I2S_DF_I2S 0x2
#define NAU8540_I2S_DF_PCM_AB 0x3
/* PCM_CTRL1 (0x11) */
#define NAU8540_I2S_LRC_DIV_SFT 12
#define NAU8540_I2S_LRC_DIV_MASK (0x3 << NAU8540_I2S_LRC_DIV_SFT)
#define NAU8540_I2S_DO12_OE (0x1 << 4)
#define NAU8540_I2S_MS_SFT 3
#define NAU8540_I2S_MS_MASK (0x1 << NAU8540_I2S_MS_SFT)
#define NAU8540_I2S_MS_MASTER (0x1 << NAU8540_I2S_MS_SFT)
#define NAU8540_I2S_MS_SLAVE (0x0 << NAU8540_I2S_MS_SFT)
#define NAU8540_I2S_BLK_DIV_MASK 0x7
/* PCM_CTRL1 (0x12) */
#define NAU8540_I2S_DO34_OE (0x1 << 11)
#define NAU8540_I2S_TSLOT_L_MASK 0x3ff
/* PCM_CTRL4 (0x14) */
#define NAU8540_TDM_MODE (0x1 << 15)
#define NAU8540_TDM_OFFSET_EN (0x1 << 14)
#define NAU8540_TDM_TX_MASK 0xf
/* ADC_SAMPLE_RATE (0x3A) */
#define NAU8540_ADC_OSR_MASK 0x3
#define NAU8540_ADC_OSR_256 0x3
#define NAU8540_ADC_OSR_128 0x2
#define NAU8540_ADC_OSR_64 0x1
#define NAU8540_ADC_OSR_32 0x0
/* VMID_CTRL (0x60) */
#define NAU8540_VMID_EN (1 << 6)
#define NAU8540_VMID_SEL_SFT 4
#define NAU8540_VMID_SEL_MASK (0x3 << NAU8540_VMID_SEL_SFT)
/* MIC_BIAS (0x67) */
#define NAU8540_PU_PRE (0x1 << 8)
/* REFERENCE (0x68) */
#define NAU8540_PRECHARGE_DIS (0x1 << 13)
#define NAU8540_GLOBAL_BIAS_EN (0x1 << 12)
/* System Clock Source */
enum {
NAU8540_CLK_DIS,
NAU8540_CLK_MCLK,
NAU8540_CLK_INTERNAL,
NAU8540_CLK_FLL_MCLK,
NAU8540_CLK_FLL_BLK,
NAU8540_CLK_FLL_FS,
};
struct nau8540 {
struct device *dev;
struct regmap *regmap;
};
struct nau8540_fll {
int mclk_src;
int ratio;
int fll_frac;
int fll_int;
int clk_ref_div;
};
struct nau8540_fll_attr {
unsigned int param;
unsigned int val;
};
/* over sampling rate */
struct nau8540_osr_attr {
unsigned int osr;
unsigned int clk_src;
};
#endif /* __NAU8540_H__ */
......@@ -1231,7 +1231,7 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
{
struct snd_soc_codec *codec = dai->codec;
struct nau8825 *nau8825 = snd_soc_codec_get_drvdata(codec);
unsigned int val_len = 0, osr;
unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div;
nau8825_sema_acquire(nau8825, 3 * HZ);
......@@ -1261,6 +1261,24 @@ static int nau8825_hw_params(struct snd_pcm_substream *substream,
osr_adc_sel[osr].clk_src << NAU8825_CLK_ADC_SRC_SFT);
}
/* make BCLK and LRC divde configuration if the codec as master. */
regmap_read(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2, &ctrl_val);
if (ctrl_val & NAU8825_I2S_MS_MASTER) {
/* get the bclk and fs ratio */
bclk_fs = snd_soc_params_to_bclk(params) / params_rate(params);
if (bclk_fs <= 32)
bclk_div = 2;
else if (bclk_fs <= 64)
bclk_div = 1;
else if (bclk_fs <= 128)
bclk_div = 0;
else
return -EINVAL;
regmap_update_bits(nau8825->regmap, NAU8825_REG_I2S_PCM_CTRL2,
NAU8825_I2S_LRC_DIV_MASK | NAU8825_I2S_BLK_DIV_MASK,
((bclk_div + 1) << NAU8825_I2S_LRC_DIV_SFT) | bclk_div);
}
switch (params_width(params)) {
case 16:
val_len |= NAU8825_I2S_DL_16;
......
......@@ -402,10 +402,8 @@ static int pcm3168a_hw_params(struct snd_pcm_substream *substream,
u32 val, mask, shift, reg;
unsigned int rate, fmt, ratio, max_ratio;
int i, min_frame_size;
snd_pcm_format_t format;
rate = params_rate(params);
format = params_format(params);
ratio = pcm3168a->sysclk / rate;
......
......@@ -1163,6 +1163,13 @@ static const struct dmi_system_id force_combo_jack_table[] = {
DMI_MATCH(DMI_PRODUCT_NAME, "Broxton P")
}
},
{
.ident = "Intel Gemini Lake",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp"),
DMI_MATCH(DMI_PRODUCT_NAME, "Geminilake")
}
},
{ }
};
......
......@@ -21,7 +21,6 @@
#include <linux/gpio.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_qos.h>
#include <linux/sysfs.h>
......
......@@ -995,7 +995,7 @@ static int rt5640_hp_event(struct snd_soc_dapm_widget *w,
case SND_SOC_DAPM_PRE_PMD:
rt5640->hp_mute = 1;
usleep_range(70000, 75000);
msleep(70);
break;
default:
......@@ -1059,7 +1059,7 @@ static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w,
switch (event) {
case SND_SOC_DAPM_POST_PMU:
if (!rt5640->hp_mute)
usleep_range(80000, 85000);
msleep(80);
break;
......@@ -1227,6 +1227,10 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
RT5640_PWR_DAC_L1_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DAC R1 Power", RT5640_PWR_DIG1,
RT5640_PWR_DAC_R1_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DAC L2 Power", RT5640_PWR_DIG1,
RT5640_PWR_DAC_L2_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DAC R2 Power", RT5640_PWR_DIG1,
RT5640_PWR_DAC_R2_BIT, 0, NULL, 0),
/* SPK/OUT Mixer */
SND_SOC_DAPM_MIXER("SPK MIXL", RT5640_PWR_MIXER, RT5640_PWR_SM_L_BIT,
0, rt5640_spk_l_mix, ARRAY_SIZE(rt5640_spk_l_mix)),
......@@ -1322,10 +1326,6 @@ static const struct snd_soc_dapm_widget rt5640_specific_dapm_widgets[] = {
rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)),
SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1,
RT5640_PWR_MA_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DAC L2 Power", RT5640_PWR_DIG1,
RT5640_PWR_DAC_L2_BIT, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("DAC R2 Power", RT5640_PWR_DIG1,
RT5640_PWR_DAC_R2_BIT, 0, NULL, 0),
SND_SOC_DAPM_OUTPUT("MONOP"),
SND_SOC_DAPM_OUTPUT("MONON"),
......@@ -2313,6 +2313,7 @@ MODULE_DEVICE_TABLE(of, rt5640_of_match);
#ifdef CONFIG_ACPI
static const struct acpi_device_id rt5640_acpi_match[] = {
{ "INT33CA", 0 },
{ "10EC3276", 0 },
{ "10EC5640", 0 },
{ "10EC5642", 0 },
{ "INTCCFFD", 0 },
......
......@@ -3109,7 +3109,7 @@ static int rt5645_jack_detect(struct snd_soc_codec *codec, int jack_insert)
unsigned int val;
if (jack_insert) {
regmap_write(rt5645->regmap, RT5645_CHARGE_PUMP, 0x0006);
regmap_write(rt5645->regmap, RT5645_CHARGE_PUMP, 0x0e06);
/* for jack type detect */
snd_soc_dapm_force_enable_pin(dapm, "LDO2");
......@@ -3545,8 +3545,10 @@ MODULE_DEVICE_TABLE(i2c, rt5645_i2c_id);
#ifdef CONFIG_ACPI
static const struct acpi_device_id rt5645_acpi_match[] = {
{ "10EC5645", 0 },
{ "10EC5648", 0 },
{ "10EC5650", 0 },
{ "10EC5640", 0 },
{ "10EC3270", 0 },
{},
};
MODULE_DEVICE_TABLE(acpi, rt5645_acpi_match);
......@@ -3658,8 +3660,14 @@ static int rt5645_i2c_probe(struct i2c_client *i2c,
GPIOD_IN);
if (IS_ERR(rt5645->gpiod_hp_det)) {
dev_err(&i2c->dev, "failed to initialize gpiod\n");
return PTR_ERR(rt5645->gpiod_hp_det);
dev_info(&i2c->dev, "failed to initialize gpiod\n");
ret = PTR_ERR(rt5645->gpiod_hp_det);
/*
* Continue if optional gpiod is missing, bail for all other
* errors, including -EPROBE_DEFER
*/
if (ret != -ENOENT)
return ret;
}
for (i = 0; i < ARRAY_SIZE(rt5645->supplies); i++)
......
......@@ -1150,28 +1150,28 @@ static const char * const rt5659_data_select[] = {
"L/R", "R/L", "L/L", "R/R"
};
static const SOC_ENUM_SINGLE_DECL(rt5659_if1_01_adc_enum,
static SOC_ENUM_SINGLE_DECL(rt5659_if1_01_adc_enum,
RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT01_SFT, rt5659_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5659_if1_23_adc_enum,
static SOC_ENUM_SINGLE_DECL(rt5659_if1_23_adc_enum,
RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT23_SFT, rt5659_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5659_if1_45_adc_enum,
static SOC_ENUM_SINGLE_DECL(rt5659_if1_45_adc_enum,
RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT45_SFT, rt5659_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5659_if1_67_adc_enum,
static SOC_ENUM_SINGLE_DECL(rt5659_if1_67_adc_enum,
RT5659_TDM_CTRL_2, RT5659_DS_ADC_SLOT67_SFT, rt5659_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5659_if2_dac_enum,
static SOC_ENUM_SINGLE_DECL(rt5659_if2_dac_enum,
RT5659_DIG_INF23_DATA, RT5659_IF2_DAC_SEL_SFT, rt5659_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5659_if2_adc_enum,
static SOC_ENUM_SINGLE_DECL(rt5659_if2_adc_enum,
RT5659_DIG_INF23_DATA, RT5659_IF2_ADC_SEL_SFT, rt5659_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5659_if3_dac_enum,
static SOC_ENUM_SINGLE_DECL(rt5659_if3_dac_enum,
RT5659_DIG_INF23_DATA, RT5659_IF3_DAC_SEL_SFT, rt5659_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5659_if3_adc_enum,
static SOC_ENUM_SINGLE_DECL(rt5659_if3_adc_enum,
RT5659_DIG_INF23_DATA, RT5659_IF3_ADC_SEL_SFT, rt5659_data_select);
static const struct snd_kcontrol_new rt5659_if1_01_adc_swap_mux =
......@@ -1207,31 +1207,31 @@ static unsigned int rt5659_asrc_clk_map_values[] = {
0, 1, 2, 3, 5, 6,
};
static const SOC_VALUE_ENUM_SINGLE_DECL(
static SOC_VALUE_ENUM_SINGLE_DECL(
rt5659_da_sto_asrc_enum, RT5659_ASRC_2, RT5659_DA_STO_T_SFT, 0x7,
rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
static const SOC_VALUE_ENUM_SINGLE_DECL(
static SOC_VALUE_ENUM_SINGLE_DECL(
rt5659_da_monol_asrc_enum, RT5659_ASRC_2, RT5659_DA_MONO_L_T_SFT, 0x7,
rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
static const SOC_VALUE_ENUM_SINGLE_DECL(
static SOC_VALUE_ENUM_SINGLE_DECL(
rt5659_da_monor_asrc_enum, RT5659_ASRC_2, RT5659_DA_MONO_R_T_SFT, 0x7,
rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
static const SOC_VALUE_ENUM_SINGLE_DECL(
static SOC_VALUE_ENUM_SINGLE_DECL(
rt5659_ad_sto1_asrc_enum, RT5659_ASRC_2, RT5659_AD_STO1_T_SFT, 0x7,
rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
static const SOC_VALUE_ENUM_SINGLE_DECL(
static SOC_VALUE_ENUM_SINGLE_DECL(
rt5659_ad_sto2_asrc_enum, RT5659_ASRC_3, RT5659_AD_STO2_T_SFT, 0x7,
rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
static const SOC_VALUE_ENUM_SINGLE_DECL(
static SOC_VALUE_ENUM_SINGLE_DECL(
rt5659_ad_monol_asrc_enum, RT5659_ASRC_3, RT5659_AD_MONO_L_T_SFT, 0x7,
rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
static const SOC_VALUE_ENUM_SINGLE_DECL(
static SOC_VALUE_ENUM_SINGLE_DECL(
rt5659_ad_monor_asrc_enum, RT5659_ASRC_3, RT5659_AD_MONO_R_T_SFT, 0x7,
rt5659_asrc_clk_src, rt5659_asrc_clk_map_values);
......@@ -1930,14 +1930,14 @@ static const char * const rt5659_dac2_src[] = {
"IF1 DAC2", "IF2 DAC", "IF3 DAC", "Mono ADC MIX"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_dac_l2_enum, RT5659_DAC_CTRL,
RT5659_DAC_L2_SEL_SFT, rt5659_dac2_src);
static const struct snd_kcontrol_new rt5659_dac_l2_mux =
SOC_DAPM_ENUM("DAC L2 Source", rt5659_dac_l2_enum);
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_dac_r2_enum, RT5659_DAC_CTRL,
RT5659_DAC_R2_SEL_SFT, rt5659_dac2_src);
......@@ -1951,7 +1951,7 @@ static const char * const rt5659_sto1_adc1_src[] = {
"DAC MIX", "ADC"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_sto1_adc1_enum, RT5659_STO1_ADC_MIXER,
RT5659_STO1_ADC1_SRC_SFT, rt5659_sto1_adc1_src);
......@@ -1964,7 +1964,7 @@ static const char * const rt5659_sto1_adc_src[] = {
"ADC1", "ADC2"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_sto1_adc_enum, RT5659_STO1_ADC_MIXER,
RT5659_STO1_ADC_SRC_SFT, rt5659_sto1_adc_src);
......@@ -1977,7 +1977,7 @@ static const char * const rt5659_sto1_adc2_src[] = {
"DAC MIX", "DMIC"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_sto1_adc2_enum, RT5659_STO1_ADC_MIXER,
RT5659_STO1_ADC2_SRC_SFT, rt5659_sto1_adc2_src);
......@@ -1990,7 +1990,7 @@ static const char * const rt5659_sto1_dmic_src[] = {
"DMIC1", "DMIC2"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_sto1_dmic_enum, RT5659_STO1_ADC_MIXER,
RT5659_STO1_DMIC_SRC_SFT, rt5659_sto1_dmic_src);
......@@ -2004,7 +2004,7 @@ static const char * const rt5659_mono_adc_l2_src[] = {
"Mono DAC MIXL", "DMIC"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_mono_adc_l2_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_ADC_L2_SRC_SFT, rt5659_mono_adc_l2_src);
......@@ -2018,7 +2018,7 @@ static const char * const rt5659_mono_adc_l1_src[] = {
"Mono DAC MIXL", "ADC"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_mono_adc_l1_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_ADC_L1_SRC_SFT, rt5659_mono_adc_l1_src);
......@@ -2031,14 +2031,14 @@ static const char * const rt5659_mono_adc_src[] = {
"ADC1 L", "ADC1 R", "ADC2 L", "ADC2 R"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_mono_adc_l_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_ADC_L_SRC_SFT, rt5659_mono_adc_src);
static const struct snd_kcontrol_new rt5659_mono_adc_l_mux =
SOC_DAPM_ENUM("Mono ADC L Source", rt5659_mono_adc_l_enum);
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_mono_adcr_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_ADC_R_SRC_SFT, rt5659_mono_adc_src);
......@@ -2051,7 +2051,7 @@ static const char * const rt5659_mono_dmic_l_src[] = {
"DMIC1 L", "DMIC2 L"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_mono_dmic_l_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_DMIC_L_SRC_SFT, rt5659_mono_dmic_l_src);
......@@ -2064,7 +2064,7 @@ static const char * const rt5659_mono_adc_r2_src[] = {
"Mono DAC MIXR", "DMIC"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_mono_adc_r2_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_ADC_R2_SRC_SFT, rt5659_mono_adc_r2_src);
......@@ -2077,7 +2077,7 @@ static const char * const rt5659_mono_adc_r1_src[] = {
"Mono DAC MIXR", "ADC"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_mono_adc_r1_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_ADC_R1_SRC_SFT, rt5659_mono_adc_r1_src);
......@@ -2090,7 +2090,7 @@ static const char * const rt5659_mono_dmic_r_src[] = {
"DMIC1 R", "DMIC2 R"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_mono_dmic_r_enum, RT5659_MONO_ADC_MIXER,
RT5659_MONO_DMIC_R_SRC_SFT, rt5659_mono_dmic_r_src);
......@@ -2104,14 +2104,14 @@ static const char * const rt5659_dac1_src[] = {
"IF1 DAC1", "IF2 DAC", "IF3 DAC"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_dac_r1_enum, RT5659_AD_DA_MIXER,
RT5659_DAC1_R_SEL_SFT, rt5659_dac1_src);
static const struct snd_kcontrol_new rt5659_dac_r1_mux =
SOC_DAPM_ENUM("DAC R1 Source", rt5659_dac_r1_enum);
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_dac_l1_enum, RT5659_AD_DA_MIXER,
RT5659_DAC1_L_SEL_SFT, rt5659_dac1_src);
......@@ -2124,14 +2124,14 @@ static const char * const rt5659_dig_dac_mix_src[] = {
"Stereo DAC Mixer", "Mono DAC Mixer"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_dig_dac_mixl_enum, RT5659_DIG_MIXER,
RT5659_DAC_MIX_L_SFT, rt5659_dig_dac_mix_src);
static const struct snd_kcontrol_new rt5659_dig_dac_mixl_mux =
SOC_DAPM_ENUM("DAC Digital Mixer L Source", rt5659_dig_dac_mixl_enum);
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_dig_dac_mixr_enum, RT5659_DIG_MIXER,
RT5659_DAC_MIX_R_SFT, rt5659_dig_dac_mix_src);
......@@ -2144,14 +2144,14 @@ static const char * const rt5659_alg_dac1_src[] = {
"DAC", "Stereo DAC Mixer"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_alg_dac_l1_enum, RT5659_A_DAC_MUX,
RT5659_A_DACL1_SFT, rt5659_alg_dac1_src);
static const struct snd_kcontrol_new rt5659_alg_dac_l1_mux =
SOC_DAPM_ENUM("Analog DACL1 Source", rt5659_alg_dac_l1_enum);
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_alg_dac_r1_enum, RT5659_A_DAC_MUX,
RT5659_A_DACR1_SFT, rt5659_alg_dac1_src);
......@@ -2164,14 +2164,14 @@ static const char * const rt5659_alg_dac2_src[] = {
"Stereo DAC Mixer", "Mono DAC Mixer"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_alg_dac_l2_enum, RT5659_A_DAC_MUX,
RT5659_A_DACL2_SFT, rt5659_alg_dac2_src);
static const struct snd_kcontrol_new rt5659_alg_dac_l2_mux =
SOC_DAPM_ENUM("Analog DAC L2 Source", rt5659_alg_dac_l2_enum);
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_alg_dac_r2_enum, RT5659_A_DAC_MUX,
RT5659_A_DACR2_SFT, rt5659_alg_dac2_src);
......@@ -2184,7 +2184,7 @@ static const char * const rt5659_if2_adc_in_src[] = {
"IF_ADC1", "IF_ADC2", "DAC_REF", "IF_ADC3"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_if2_adc_in_enum, RT5659_DIG_INF23_DATA,
RT5659_IF2_ADC_IN_SFT, rt5659_if2_adc_in_src);
......@@ -2197,7 +2197,7 @@ static const char * const rt5659_if3_adc_in_src[] = {
"IF_ADC1", "IF_ADC2", "DAC_REF", "Stereo2_ADC_L/R"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_if3_adc_in_enum, RT5659_DIG_INF23_DATA,
RT5659_IF3_ADC_IN_SFT, rt5659_if3_adc_in_src);
......@@ -2210,14 +2210,14 @@ static const char * const rt5659_pdm_src[] = {
"Mono DAC", "Stereo DAC"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_pdm_l_enum, RT5659_PDM_OUT_CTRL,
RT5659_PDM1_L_SFT, rt5659_pdm_src);
static const struct snd_kcontrol_new rt5659_pdm_l_mux =
SOC_DAPM_ENUM("PDM L Source", rt5659_pdm_l_enum);
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_pdm_r_enum, RT5659_PDM_OUT_CTRL,
RT5659_PDM1_R_SFT, rt5659_pdm_src);
......@@ -2230,7 +2230,7 @@ static const char * const rt5659_spdif_src[] = {
"IF1_DAC1", "IF1_DAC2", "IF2_DAC", "IF3_DAC"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_spdif_enum, RT5659_SPDIF_CTRL,
RT5659_SPDIF_SEL_SFT, rt5659_spdif_src);
......@@ -2250,7 +2250,7 @@ static const char * const rt5659_rx_adc_data_src[] = {
"NUL:AD2:DAC:AD1", "NUL:DAC:DAC:AD2", "NUL:DAC:AD2:DAC"
};
static const SOC_ENUM_SINGLE_DECL(
static SOC_ENUM_SINGLE_DECL(
rt5659_rx_adc_data_enum, RT5659_TDM_CTRL_2,
RT5659_ADCDAT_SRC_SFT, rt5659_rx_adc_data_src);
......@@ -4018,7 +4018,7 @@ static int rt5659_i2c_probe(struct i2c_client *i2c,
GPIOD_OUT_HIGH);
/* Sleep for 300 ms miniumum */
usleep_range(300000, 350000);
msleep(300);
rt5659->regmap = devm_regmap_init_i2c(i2c, &rt5659_regmap);
if (IS_ERR(rt5659->regmap)) {
......@@ -4230,10 +4230,9 @@ static struct acpi_device_id rt5659_acpi_match[] = {
MODULE_DEVICE_TABLE(acpi, rt5659_acpi_match);
#endif
struct i2c_driver rt5659_i2c_driver = {
static struct i2c_driver rt5659_i2c_driver = {
.driver = {
.name = "rt5659",
.owner = THIS_MODULE,
.of_match_table = of_match_ptr(rt5659_of_match),
.acpi_match_table = ACPI_PTR(rt5659_acpi_match),
},
......
......@@ -526,10 +526,10 @@ static const char * const rt5660_data_select[] = {
"L/R", "R/L", "L/L", "R/R"
};
static const SOC_ENUM_SINGLE_DECL(rt5660_if1_dac_enum,
static SOC_ENUM_SINGLE_DECL(rt5660_if1_dac_enum,
RT5660_DIG_INF1_DATA, RT5660_IF1_DAC_IN_SFT, rt5660_data_select);
static const SOC_ENUM_SINGLE_DECL(rt5660_if1_adc_enum,
static SOC_ENUM_SINGLE_DECL(rt5660_if1_adc_enum,
RT5660_DIG_INF1_DATA, RT5660_IF1_ADC_IN_SFT, rt5660_data_select);
static const struct snd_kcontrol_new rt5660_if1_dac_swap_mux =
......@@ -1152,7 +1152,7 @@ static int rt5660_resume(struct snd_soc_codec *codec)
struct rt5660_priv *rt5660 = snd_soc_codec_get_drvdata(codec);
if (rt5660->pdata.poweroff_codec_in_suspend)
usleep_range(350000, 400000);
msleep(350);
regcache_cache_only(rt5660->regmap, false);
regcache_sync(rt5660->regmap);
......
......@@ -2814,6 +2814,7 @@ MODULE_DEVICE_TABLE(i2c, rt5670_i2c_id);
static const struct acpi_device_id rt5670_acpi_match[] = {
{ "10EC5670", 0},
{ "10EC5672", 0},
{ "10EC5640", 0}, /* quirk */
{ },
};
MODULE_DEVICE_TABLE(acpi, rt5670_acpi_match);
......
......@@ -21,7 +21,6 @@
#include <linux/gpio.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#include <linux/miscdevice.h>
#include <linux/regulator/consumer.h>
#include <linux/pm_qos.h>
#include <linux/sysfs.h>
......
......@@ -1393,6 +1393,12 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power)
snd_soc_write(codec, AIC3X_PLL_PROGC_REG, pll_c);
snd_soc_write(codec, AIC3X_PLL_PROGD_REG, pll_d);
}
/*
* Delay is needed to reduce pop-noise after syncing back the
* registers
*/
mdelay(50);
} else {
/*
* Do soft reset to this codec instance in order to clear
......
......@@ -21,7 +21,6 @@
#include <linux/firmware.h>
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/mutex.h>
......
......@@ -855,6 +855,8 @@ ARIZONA_LHPF_CONTROL("LHPF2 Coefficients", ARIZONA_HPLPF2_2),
ARIZONA_LHPF_CONTROL("LHPF3 Coefficients", ARIZONA_HPLPF3_2),
ARIZONA_LHPF_CONTROL("LHPF4 Coefficients", ARIZONA_HPLPF4_2),
WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE),
......@@ -1944,7 +1946,10 @@ static int wm5102_codec_probe(struct snd_soc_codec *codec)
if (ret)
goto err_adsp2_codec_probe;
arizona_init_spk(codec);
ret = arizona_init_spk(codec);
if (ret < 0)
return ret;
arizona_init_gpio(codec);
arizona_init_notifiers(codec);
......
......@@ -778,6 +778,11 @@ SOC_ENUM("ISRC2 FSH", arizona_isrc_fsh[1]),
SOC_ENUM("ISRC3 FSH", arizona_isrc_fsh[2]),
SOC_ENUM("ASRC RATE 1", arizona_asrc_rate1),
WM_ADSP2_PRELOAD_SWITCH("DSP1", 1),
WM_ADSP2_PRELOAD_SWITCH("DSP2", 2),
WM_ADSP2_PRELOAD_SWITCH("DSP3", 3),
WM_ADSP2_PRELOAD_SWITCH("DSP4", 4),
ARIZONA_MIXER_CONTROLS("DSP1L", ARIZONA_DSP1LMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("DSP1R", ARIZONA_DSP1RMIX_INPUT_1_SOURCE),
ARIZONA_MIXER_CONTROLS("DSP2L", ARIZONA_DSP2LMIX_INPUT_1_SOURCE),
......@@ -2279,7 +2284,10 @@ static int wm5110_codec_probe(struct snd_soc_codec *codec)
priv->core.arizona->dapm = dapm;
arizona_init_spk(codec);
ret = arizona_init_spk(codec);
if (ret < 0)
return ret;
arizona_init_gpio(codec);
arizona_init_mono(codec);
arizona_init_notifiers(codec);
......
......@@ -31,8 +31,8 @@
#define WM8731_CACHEREGNUM 10
#define WM8731_SYSCLK_MCLK 0
#define WM8731_SYSCLK_XTAL 1
#define WM8731_SYSCLK_MCLK 2
#define WM8731_DAI 0
......
......@@ -37,8 +37,6 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = {
"DVDD",
};
#define WM8741_NUM_RATES 6
/* codec private data */
struct wm8741_priv {
struct wm8741_platform_data pdata;
......
......@@ -280,6 +280,7 @@ static const DECLARE_TLV_DB_SCALE(voice_mix_tlv, -1200, 300, 0);
static const DECLARE_TLV_DB_SCALE(pga_tlv, -1725, 75, 0);
static const struct snd_kcontrol_new wm8753_snd_controls[] = {
SOC_SINGLE("Hi-Fi DAC Left/Right channel Swap", WM8753_HIFI, 5, 1, 0),
SOC_DOUBLE_R_TLV("PCM Volume", WM8753_LDAC, WM8753_RDAC, 0, 255, 0, dac_tlv),
SOC_DOUBLE_R_TLV("ADC Capture Volume", WM8753_LADC, WM8753_RADC, 0, 255, 0,
......@@ -1087,7 +1088,7 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_codec *codec,
{
u16 ioctl, hifi;
hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f;
hifi = snd_soc_read(codec, WM8753_HIFI) & 0x013f;
ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae;
/* set master/slave audio interface */
......
......@@ -1062,8 +1062,12 @@ static int wm8997_codec_probe(struct snd_soc_codec *codec)
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
struct wm8997_priv *priv = snd_soc_codec_get_drvdata(codec);
int ret;
ret = arizona_init_spk(codec);
if (ret < 0)
return ret;
arizona_init_spk(codec);
arizona_init_notifiers(codec);
snd_soc_component_disable_pin(component, "HAPTICS");
......
......@@ -1321,10 +1321,14 @@ static int wm8998_codec_probe(struct snd_soc_codec *codec)
struct wm8998_priv *priv = snd_soc_codec_get_drvdata(codec);
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
struct snd_soc_component *component = snd_soc_dapm_to_component(dapm);
int ret;
priv->core.arizona->dapm = dapm;
arizona_init_spk(codec);
ret = arizona_init_spk(codec);
if (ret < 0)
return ret;
arizona_init_gpio(codec);
arizona_init_notifiers(codec);
......
此差异已折叠。
......@@ -62,6 +62,7 @@ struct wm_adsp {
int fw;
int fw_ver;
bool preloaded;
bool booted;
bool running;
......@@ -86,7 +87,12 @@ struct wm_adsp {
SND_SOC_DAPM_PGA_E(wname, SND_SOC_NOPM, num, 0, NULL, 0, \
wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD)
#define WM_ADSP2_PRELOAD_SWITCH(wname, num) \
SOC_SINGLE_EXT(wname " Preload Switch", SND_SOC_NOPM, num, 1, 0, \
wm_adsp2_preloader_get, wm_adsp2_preloader_put)
#define WM_ADSP2(wname, num, event_fn) \
SND_SOC_DAPM_SPK(wname " Preload", NULL), \
{ .id = snd_soc_dapm_supply, .name = wname " Preloader", \
.reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \
.event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD, \
......@@ -110,6 +116,11 @@ int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
int wm_adsp2_event(struct snd_soc_dapm_widget *w,
struct snd_kcontrol *kcontrol, int event);
int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream);
int wm_adsp_compr_free(struct snd_compr_stream *stream);
int wm_adsp_compr_set_params(struct snd_compr_stream *stream,
......
......@@ -358,13 +358,20 @@ static struct snd_soc_card evm_soc_card = {
static int davinci_evm_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
const struct of_device_id *match =
of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev);
struct snd_soc_dai_link *dai = (struct snd_soc_dai_link *) match->data;
const struct of_device_id *match;
struct snd_soc_dai_link *dai;
struct snd_soc_card_drvdata_davinci *drvdata = NULL;
struct clk *mclk;
int ret = 0;
match = of_match_device(of_match_ptr(davinci_evm_dt_ids), &pdev->dev);
if (!match) {
dev_err(&pdev->dev, "Error: No device match found\n");
return -ENODEV;
}
dai = (struct snd_soc_dai_link *) match->data;
evm_soc_card.dai_link = dai;
dai->codec_of_node = of_parse_phandle(np, "ti,audio-codec", 0);
......
......@@ -121,9 +121,14 @@ static irqreturn_t i2s_irq_handler(int irq, void *dev_id)
irq_valid = true;
}
/* Data available. Record mode not supported in PIO mode */
if (isr[i] & ISR_RXDA)
/*
* Data available. Retrieve samples from FIFO
* NOTE: Only two channels supported
*/
if ((isr[i] & ISR_RXDA) && (i == 0) && dev->use_pio) {
dw_pcm_pop_rx(dev);
irq_valid = true;
}
/* Error Handling: TX */
if (isr[i] & ISR_TXFO) {
......
此差异已折叠。
......@@ -105,20 +105,27 @@ struct dw_i2s_dev {
struct i2s_clk_config_data config;
int (*i2s_clk_cfg)(struct i2s_clk_config_data *config);
/* data related to PIO transfers (TX) */
/* data related to PIO transfers */
bool use_pio;
struct snd_pcm_substream __rcu *tx_substream;
struct snd_pcm_substream __rcu *rx_substream;
unsigned int (*tx_fn)(struct dw_i2s_dev *dev,
struct snd_pcm_runtime *runtime, unsigned int tx_ptr,
bool *period_elapsed);
unsigned int (*rx_fn)(struct dw_i2s_dev *dev,
struct snd_pcm_runtime *runtime, unsigned int rx_ptr,
bool *period_elapsed);
unsigned int tx_ptr;
unsigned int rx_ptr;
};
#if IS_ENABLED(CONFIG_SND_DESIGNWARE_PCM)
void dw_pcm_push_tx(struct dw_i2s_dev *dev);
void dw_pcm_pop_rx(struct dw_i2s_dev *dev);
int dw_pcm_register(struct platform_device *pdev);
#else
void dw_pcm_push_tx(struct dw_i2s_dev *dev) { }
void dw_pcm_pop_rx(struct dw_i2s_dev *dev) { }
int dw_pcm_register(struct platform_device *pdev)
{
return -EINVAL;
......
......@@ -26,7 +26,6 @@
#include <sound/soc.h>
#include "mpc5200_dma.h"
#include "mpc5200_psc_ac97.h"
#define DRV_NAME "efika-audio-fabric"
......
......@@ -668,7 +668,7 @@ static struct snd_soc_dai_driver fsl_sai_dai = {
.playback = {
.stream_name = "CPU-Playback",
.channels_min = 1,
.channels_max = 2,
.channels_max = 32,
.rate_min = 8000,
.rate_max = 192000,
.rates = SNDRV_PCM_RATE_KNOT,
......@@ -677,7 +677,7 @@ static struct snd_soc_dai_driver fsl_sai_dai = {
.capture = {
.stream_name = "CPU-Capture",
.channels_min = 1,
.channels_max = 2,
.channels_max = 32,
.rate_min = 8000,
.rate_max = 192000,
.rates = SNDRV_PCM_RATE_KNOT,
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册