You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge remote-tracking branches 'asoc/topic/intel', 'asoc/topic/kirkwood', 'asoc/topic/max98090' and 'asoc/topic/mc13783' into asoc-next
This commit is contained in:
@@ -4,7 +4,7 @@ This device supports I2C only.
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible : "maxim,max98090".
|
||||
- compatible : "maxim,max98090" or "maxim,max98091".
|
||||
|
||||
- reg : The I2C address of the device.
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* platform_sst_audio.h: sst audio platform data header file
|
||||
*
|
||||
* Copyright (C) 2012-14 Intel Corporation
|
||||
* Author: Jeeja KP <jeeja.kp@intel.com>
|
||||
* Omair Mohammed Abdullah <omair.m.abdullah@intel.com>
|
||||
* Vinod Koul ,vinod.koul@intel.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; version 2
|
||||
* of the License.
|
||||
*/
|
||||
#ifndef _PLATFORM_SST_AUDIO_H_
|
||||
#define _PLATFORM_SST_AUDIO_H_
|
||||
|
||||
#include <linux/sfi.h>
|
||||
|
||||
enum sst_audio_task_id_mrfld {
|
||||
SST_TASK_ID_NONE = 0,
|
||||
SST_TASK_ID_SBA = 1,
|
||||
SST_TASK_ID_MEDIA = 3,
|
||||
SST_TASK_ID_MAX = SST_TASK_ID_MEDIA,
|
||||
};
|
||||
|
||||
/* Device IDs for Merrifield are Pipe IDs,
|
||||
* ref: DSP spec v0.75 */
|
||||
enum sst_audio_device_id_mrfld {
|
||||
/* Output pipeline IDs */
|
||||
PIPE_ID_OUT_START = 0x0,
|
||||
PIPE_CODEC_OUT0 = 0x2,
|
||||
PIPE_CODEC_OUT1 = 0x3,
|
||||
PIPE_SPROT_LOOP_OUT = 0x4,
|
||||
PIPE_MEDIA_LOOP1_OUT = 0x5,
|
||||
PIPE_MEDIA_LOOP2_OUT = 0x6,
|
||||
PIPE_VOIP_OUT = 0xC,
|
||||
PIPE_PCM0_OUT = 0xD,
|
||||
PIPE_PCM1_OUT = 0xE,
|
||||
PIPE_PCM2_OUT = 0xF,
|
||||
PIPE_MEDIA0_OUT = 0x12,
|
||||
PIPE_MEDIA1_OUT = 0x13,
|
||||
/* Input Pipeline IDs */
|
||||
PIPE_ID_IN_START = 0x80,
|
||||
PIPE_CODEC_IN0 = 0x82,
|
||||
PIPE_CODEC_IN1 = 0x83,
|
||||
PIPE_SPROT_LOOP_IN = 0x84,
|
||||
PIPE_MEDIA_LOOP1_IN = 0x85,
|
||||
PIPE_MEDIA_LOOP2_IN = 0x86,
|
||||
PIPE_VOIP_IN = 0x8C,
|
||||
PIPE_PCM0_IN = 0x8D,
|
||||
PIPE_PCM1_IN = 0x8E,
|
||||
PIPE_MEDIA0_IN = 0x8F,
|
||||
PIPE_MEDIA1_IN = 0x90,
|
||||
PIPE_MEDIA2_IN = 0x91,
|
||||
PIPE_RSVD = 0xFF,
|
||||
};
|
||||
|
||||
/* The stream map for each platform consists of an array of the below
|
||||
* stream map structure.
|
||||
*/
|
||||
struct sst_dev_stream_map {
|
||||
u8 dev_num; /* device id */
|
||||
u8 subdev_num; /* substream */
|
||||
u8 direction;
|
||||
u8 device_id; /* fw id */
|
||||
u8 task_id; /* fw task */
|
||||
u8 status;
|
||||
};
|
||||
|
||||
struct sst_platform_data {
|
||||
/* Intel software platform id*/
|
||||
struct sst_dev_stream_map *pdev_strm_map;
|
||||
unsigned int strm_map_size;
|
||||
};
|
||||
|
||||
int add_sst_platform_device(void);
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* linux/sound/rt286.h -- Platform data for RT286
|
||||
*
|
||||
* Copyright 2013 Realtek Microelectronics
|
||||
*
|
||||
* 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 __LINUX_SND_RT286_H
|
||||
#define __LINUX_SND_RT286_H
|
||||
|
||||
struct rt286_platform_data {
|
||||
bool cbj_en; /*combo jack enable*/
|
||||
bool gpio2_en; /*GPIO2 enable*/
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -75,6 +75,7 @@ config SND_SOC_ALL_CODECS
|
||||
select SND_SOC_PCM3008
|
||||
select SND_SOC_PCM512x_I2C if I2C
|
||||
select SND_SOC_PCM512x_SPI if SPI_MASTER
|
||||
select SND_SOC_RT286 if I2C
|
||||
select SND_SOC_RT5631 if I2C
|
||||
select SND_SOC_RT5640 if I2C
|
||||
select SND_SOC_RT5645 if I2C
|
||||
@@ -455,6 +456,9 @@ config SND_SOC_RL6231
|
||||
default m if SND_SOC_RT5645=m
|
||||
default m if SND_SOC_RT5651=m
|
||||
|
||||
config SND_SOC_RT286
|
||||
tristate
|
||||
|
||||
config SND_SOC_RT5631
|
||||
tristate
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ snd-soc-pcm512x-objs := pcm512x.o
|
||||
snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o
|
||||
snd-soc-pcm512x-spi-objs := pcm512x-spi.o
|
||||
snd-soc-rl6231-objs := rl6231.o
|
||||
snd-soc-rt286-objs := rt286.o
|
||||
snd-soc-rt5631-objs := rt5631.o
|
||||
snd-soc-rt5640-objs := rt5640.o
|
||||
snd-soc-rt5645-objs := rt5645.o
|
||||
@@ -237,6 +238,7 @@ obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o
|
||||
obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o
|
||||
obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o
|
||||
obj-$(CONFIG_SND_SOC_RL6231) += snd-soc-rl6231.o
|
||||
obj-$(CONFIG_SND_SOC_RT286) += snd-soc-rt286.o
|
||||
obj-$(CONFIG_SND_SOC_RT5631) += snd-soc-rt5631.o
|
||||
obj-$(CONFIG_SND_SOC_RT5640) += snd-soc-rt5640.o
|
||||
obj-$(CONFIG_SND_SOC_RT5645) += snd-soc-rt5645.o
|
||||
|
||||
+12
-30
@@ -26,10 +26,6 @@
|
||||
#include <sound/max98090.h>
|
||||
#include "max98090.h"
|
||||
|
||||
#define DEBUG
|
||||
#define EXTMIC_METHOD
|
||||
#define EXTMIC_METHOD_TEST
|
||||
|
||||
/* Allows for sparsely populated register maps */
|
||||
static struct reg_default max98090_reg[] = {
|
||||
{ 0x00, 0x00 }, /* 00 Software Reset */
|
||||
@@ -820,7 +816,6 @@ static int max98090_micinput_event(struct snd_soc_dapm_widget *w,
|
||||
else
|
||||
val = (val & M98090_MIC_PA2EN_MASK) >> M98090_MIC_PA2EN_SHIFT;
|
||||
|
||||
|
||||
if (val >= 1) {
|
||||
if (w->reg == M98090_REG_MIC1_INPUT_LEVEL) {
|
||||
max98090->pa1en = val - 1; /* Update for volatile */
|
||||
@@ -1140,7 +1135,6 @@ static const struct snd_kcontrol_new max98090_mixhprsel_mux =
|
||||
SOC_DAPM_ENUM("MIXHPRSEL Mux", mixhprsel_mux_enum);
|
||||
|
||||
static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = {
|
||||
|
||||
SND_SOC_DAPM_INPUT("MIC1"),
|
||||
SND_SOC_DAPM_INPUT("MIC2"),
|
||||
SND_SOC_DAPM_INPUT("DMICL"),
|
||||
@@ -1304,7 +1298,6 @@ static const struct snd_soc_dapm_widget max98090_dapm_widgets[] = {
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_widget max98091_dapm_widgets[] = {
|
||||
|
||||
SND_SOC_DAPM_INPUT("DMIC3"),
|
||||
SND_SOC_DAPM_INPUT("DMIC4"),
|
||||
|
||||
@@ -1315,7 +1308,6 @@ static const struct snd_soc_dapm_widget max98091_dapm_widgets[] = {
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route max98090_dapm_routes[] = {
|
||||
|
||||
{"MIC1 Input", NULL, "MIC1"},
|
||||
{"MIC2 Input", NULL, "MIC2"},
|
||||
|
||||
@@ -1493,17 +1485,14 @@ static const struct snd_soc_dapm_route max98090_dapm_routes[] = {
|
||||
{"SPKR", NULL, "SPK Right Out"},
|
||||
{"RCVL", NULL, "RCV Left Out"},
|
||||
{"RCVR", NULL, "RCV Right Out"},
|
||||
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route max98091_dapm_routes[] = {
|
||||
|
||||
/* DMIC inputs */
|
||||
{"DMIC3", NULL, "DMIC3_ENA"},
|
||||
{"DMIC4", NULL, "DMIC4_ENA"},
|
||||
{"DMIC3", NULL, "AHPF"},
|
||||
{"DMIC4", NULL, "AHPF"},
|
||||
|
||||
};
|
||||
|
||||
static int max98090_add_widgets(struct snd_soc_codec *codec)
|
||||
@@ -1531,7 +1520,6 @@ static int max98090_add_widgets(struct snd_soc_codec *codec)
|
||||
|
||||
snd_soc_dapm_add_routes(dapm, max98091_dapm_routes,
|
||||
ARRAY_SIZE(max98091_dapm_routes));
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -2212,22 +2200,11 @@ static struct snd_soc_dai_driver max98090_dai[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static void max98090_handle_pdata(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
|
||||
struct max98090_pdata *pdata = max98090->pdata;
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(codec->dev, "No platform data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static int max98090_probe(struct snd_soc_codec *codec)
|
||||
{
|
||||
struct max98090_priv *max98090 = snd_soc_codec_get_drvdata(codec);
|
||||
struct max98090_cdata *cdata;
|
||||
enum max98090_type devtype;
|
||||
int ret = 0;
|
||||
|
||||
dev_dbg(codec->dev, "max98090_probe\n");
|
||||
@@ -2263,16 +2240,21 @@ static int max98090_probe(struct snd_soc_codec *codec)
|
||||
}
|
||||
|
||||
if ((ret >= M98090_REVA) && (ret <= M98090_REVA + 0x0f)) {
|
||||
max98090->devtype = MAX98090;
|
||||
devtype = MAX98090;
|
||||
dev_info(codec->dev, "MAX98090 REVID=0x%02x\n", ret);
|
||||
} else if ((ret >= M98091_REVA) && (ret <= M98091_REVA + 0x0f)) {
|
||||
max98090->devtype = MAX98091;
|
||||
devtype = MAX98091;
|
||||
dev_info(codec->dev, "MAX98091 REVID=0x%02x\n", ret);
|
||||
} else {
|
||||
max98090->devtype = MAX98090;
|
||||
devtype = MAX98090;
|
||||
dev_err(codec->dev, "Unrecognized revision 0x%02x\n", ret);
|
||||
}
|
||||
|
||||
if (max98090->devtype != devtype) {
|
||||
dev_warn(codec->dev, "Mismatch in DT specified CODEC type.\n");
|
||||
max98090->devtype = devtype;
|
||||
}
|
||||
|
||||
max98090->jack_state = M98090_JACK_STATE_NO_HEADSET;
|
||||
|
||||
INIT_DELAYED_WORK(&max98090->jack_work, max98090_jack_work);
|
||||
@@ -2317,8 +2299,6 @@ static int max98090_probe(struct snd_soc_codec *codec)
|
||||
snd_soc_update_bits(codec, M98090_REG_MIC_BIAS_VOLTAGE,
|
||||
M98090_MBVSEL_MASK, M98090_MBVSEL_2V8);
|
||||
|
||||
max98090_handle_pdata(codec);
|
||||
|
||||
max98090_add_widgets(codec);
|
||||
|
||||
err_access:
|
||||
@@ -2428,7 +2408,7 @@ static int max98090_runtime_suspend(struct device *dev)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int max98090_resume(struct device *dev)
|
||||
{
|
||||
struct max98090_priv *max98090 = dev_get_drvdata(dev);
|
||||
@@ -2460,12 +2440,14 @@ static const struct dev_pm_ops max98090_pm = {
|
||||
|
||||
static const struct i2c_device_id max98090_i2c_id[] = {
|
||||
{ "max98090", MAX98090 },
|
||||
{ "max98091", MAX98091 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, max98090_i2c_id);
|
||||
|
||||
static const struct of_device_id max98090_of_match[] = {
|
||||
{ .compatible = "maxim,max98090", },
|
||||
{ .compatible = "maxim,max98091", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, max98090_of_match);
|
||||
|
||||
@@ -766,11 +766,11 @@ static int __init mc13783_codec_probe(struct platform_device *pdev)
|
||||
|
||||
ret = of_property_read_u32(np, "adc-port", &priv->adc_ssi_port);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out;
|
||||
|
||||
ret = of_property_read_u32(np, "dac-port", &priv->dac_ssi_port);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dev_set_drvdata(&pdev->dev, priv);
|
||||
@@ -783,6 +783,8 @@ static int __init mc13783_codec_probe(struct platform_device *pdev)
|
||||
ret = snd_soc_register_codec(&pdev->dev, &soc_codec_dev_mc13783,
|
||||
mc13783_dai_async, ARRAY_SIZE(mc13783_dai_async));
|
||||
|
||||
out:
|
||||
of_node_put(np);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* rt286.h -- RT286 ALSA SoC audio driver
|
||||
*
|
||||
* Copyright 2011 Realtek Microelectronics
|
||||
* Author: Johnny Hsu <johnnyhsu@realtek.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 __RT286_H__
|
||||
#define __RT286_H__
|
||||
|
||||
#define VERB_CMD(V, N, D) ((N << 20) | (V << 8) | D)
|
||||
|
||||
#define RT286_AUDIO_FUNCTION_GROUP 0x01
|
||||
#define RT286_DAC_OUT1 0x02
|
||||
#define RT286_DAC_OUT2 0x03
|
||||
#define RT286_ADC_IN1 0x09
|
||||
#define RT286_ADC_IN2 0x08
|
||||
#define RT286_MIXER_IN 0x0b
|
||||
#define RT286_MIXER_OUT1 0x0c
|
||||
#define RT286_MIXER_OUT2 0x0d
|
||||
#define RT286_DMIC1 0x12
|
||||
#define RT286_DMIC2 0x13
|
||||
#define RT286_SPK_OUT 0x14
|
||||
#define RT286_MIC1 0x18
|
||||
#define RT286_LINE1 0x1a
|
||||
#define RT286_BEEP 0x1d
|
||||
#define RT286_SPDIF 0x1e
|
||||
#define RT286_VENDOR_REGISTERS 0x20
|
||||
#define RT286_HP_OUT 0x21
|
||||
#define RT286_MIXER_IN1 0x22
|
||||
#define RT286_MIXER_IN2 0x23
|
||||
|
||||
#define RT286_SET_PIN_SFT 6
|
||||
#define RT286_SET_PIN_ENABLE 0x40
|
||||
#define RT286_SET_PIN_DISABLE 0
|
||||
#define RT286_SET_EAPD_HIGH 0x2
|
||||
#define RT286_SET_EAPD_LOW 0
|
||||
|
||||
#define RT286_MUTE_SFT 7
|
||||
|
||||
/* Verb commands */
|
||||
#define RT286_GET_PARAM(NID, PARAM) VERB_CMD(AC_VERB_PARAMETERS, NID, PARAM)
|
||||
#define RT286_SET_POWER(NID) VERB_CMD(AC_VERB_SET_POWER_STATE, NID, 0)
|
||||
#define RT286_SET_AUDIO_POWER RT286_SET_POWER(RT286_AUDIO_FUNCTION_GROUP)
|
||||
#define RT286_SET_HPO_POWER RT286_SET_POWER(RT286_HP_OUT)
|
||||
#define RT286_SET_SPK_POWER RT286_SET_POWER(RT286_SPK_OUT)
|
||||
#define RT286_SET_DMIC1_POWER RT286_SET_POWER(RT286_DMIC1)
|
||||
#define RT286_SPK_MUX\
|
||||
VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT286_SPK_OUT, 0)
|
||||
#define RT286_HPO_MUX\
|
||||
VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT286_HP_OUT, 0)
|
||||
#define RT286_ADC0_MUX\
|
||||
VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT286_MIXER_IN1, 0)
|
||||
#define RT286_ADC1_MUX\
|
||||
VERB_CMD(AC_VERB_SET_CONNECT_SEL, RT286_MIXER_IN2, 0)
|
||||
#define RT286_SET_MIC1\
|
||||
VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT286_MIC1, 0)
|
||||
#define RT286_SET_PIN_HPO\
|
||||
VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT286_HP_OUT, 0)
|
||||
#define RT286_SET_PIN_SPK\
|
||||
VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT286_SPK_OUT, 0)
|
||||
#define RT286_SET_PIN_DMIC1\
|
||||
VERB_CMD(AC_VERB_SET_PIN_WIDGET_CONTROL, RT286_DMIC1, 0)
|
||||
#define RT286_SPK_EAPD\
|
||||
VERB_CMD(AC_VERB_SET_EAPD_BTLENABLE, RT286_SPK_OUT, 0)
|
||||
#define RT286_SET_AMP_GAIN_HPO\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_HP_OUT, 0)
|
||||
#define RT286_SET_AMP_GAIN_ADC_IN1\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_ADC_IN1, 0)
|
||||
#define RT286_SET_AMP_GAIN_ADC_IN2\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_ADC_IN2, 0)
|
||||
#define RT286_GET_HP_SENSE\
|
||||
VERB_CMD(AC_VERB_GET_PIN_SENSE, RT286_HP_OUT, 0)
|
||||
#define RT286_GET_MIC1_SENSE\
|
||||
VERB_CMD(AC_VERB_GET_PIN_SENSE, RT286_MIC1, 0)
|
||||
#define RT286_SET_DMIC2_DEFAULT\
|
||||
VERB_CMD(AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, RT286_DMIC2, 0)
|
||||
#define RT286_DACL_GAIN\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_DAC_OUT1, 0xa000)
|
||||
#define RT286_DACR_GAIN\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_DAC_OUT1, 0x9000)
|
||||
#define RT286_ADCL_GAIN\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_ADC_IN1, 0x6000)
|
||||
#define RT286_ADCR_GAIN\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_ADC_IN1, 0x5000)
|
||||
#define RT286_MIC_GAIN\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_MIC1, 0x7000)
|
||||
#define RT286_SPOL_GAIN\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_SPK_OUT, 0xa000)
|
||||
#define RT286_SPOR_GAIN\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_SPK_OUT, 0x9000)
|
||||
#define RT286_HPOL_GAIN\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_HP_OUT, 0xa000)
|
||||
#define RT286_HPOR_GAIN\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_HP_OUT, 0x9000)
|
||||
#define RT286_F_DAC_SWITCH\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_MIXER_OUT1, 0x7000)
|
||||
#define RT286_F_RECMIX_SWITCH\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_MIXER_OUT1, 0x7100)
|
||||
#define RT286_REC_MIC_SWITCH\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_MIXER_IN, 0x7000)
|
||||
#define RT286_REC_I2S_SWITCH\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_MIXER_IN, 0x7100)
|
||||
#define RT286_REC_LINE_SWITCH\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_MIXER_IN, 0x7200)
|
||||
#define RT286_REC_BEEP_SWITCH\
|
||||
VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, RT286_MIXER_IN, 0x7300)
|
||||
#define RT286_DAC_FORMAT\
|
||||
VERB_CMD(AC_VERB_SET_STREAM_FORMAT, RT286_DAC_OUT1, 0)
|
||||
#define RT286_ADC_FORMAT\
|
||||
VERB_CMD(AC_VERB_SET_STREAM_FORMAT, RT286_ADC_IN1, 0)
|
||||
#define RT286_COEF_INDEX\
|
||||
VERB_CMD(AC_VERB_SET_COEF_INDEX, RT286_VENDOR_REGISTERS, 0)
|
||||
#define RT286_PROC_COEF\
|
||||
VERB_CMD(AC_VERB_SET_PROC_COEF, RT286_VENDOR_REGISTERS, 0)
|
||||
|
||||
/* Index registers */
|
||||
#define RT286_A_BIAS_CTRL1 0x01
|
||||
#define RT286_A_BIAS_CTRL2 0x02
|
||||
#define RT286_POWER_CTRL1 0x03
|
||||
#define RT286_A_BIAS_CTRL3 0x04
|
||||
#define RT286_POWER_CTRL2 0x08
|
||||
#define RT286_I2S_CTRL1 0x09
|
||||
#define RT286_I2S_CTRL2 0x0a
|
||||
#define RT286_CLK_DIV 0x0b
|
||||
#define RT286_DC_GAIN 0x0d
|
||||
#define RT286_POWER_CTRL3 0x0f
|
||||
#define RT286_MIC1_DET_CTRL 0x19
|
||||
#define RT286_MISC_CTRL1 0x20
|
||||
#define RT286_IRQ_CTRL 0x33
|
||||
#define RT286_PLL_CTRL1 0x49
|
||||
#define RT286_CBJ_CTRL1 0x4f
|
||||
#define RT286_CBJ_CTRL2 0x50
|
||||
#define RT286_PLL_CTRL 0x63
|
||||
#define RT286_DEPOP_CTRL1 0x66
|
||||
#define RT286_DEPOP_CTRL2 0x67
|
||||
#define RT286_DEPOP_CTRL3 0x68
|
||||
#define RT286_DEPOP_CTRL4 0x69
|
||||
|
||||
/* SPDIF (0x06) */
|
||||
#define RT286_SPDIF_SEL_SFT 0
|
||||
#define RT286_SPDIF_SEL_PCM0 0
|
||||
#define RT286_SPDIF_SEL_PCM1 1
|
||||
#define RT286_SPDIF_SEL_SPOUT 2
|
||||
#define RT286_SPDIF_SEL_PP 3
|
||||
|
||||
/* RECMIX (0x0b) */
|
||||
#define RT286_M_REC_BEEP_SFT 0
|
||||
#define RT286_M_REC_LINE1_SFT 1
|
||||
#define RT286_M_REC_MIC1_SFT 2
|
||||
#define RT286_M_REC_I2S_SFT 3
|
||||
|
||||
/* Front (0x0c) */
|
||||
#define RT286_M_FRONT_DAC_SFT 0
|
||||
#define RT286_M_FRONT_REC_SFT 1
|
||||
|
||||
/* SPK-OUT (0x14) */
|
||||
#define RT286_M_SPK_MUX_SFT 14
|
||||
#define RT286_SPK_SEL_MASK 0x1
|
||||
#define RT286_SPK_SEL_SFT 0
|
||||
#define RT286_SPK_SEL_F 0
|
||||
#define RT286_SPK_SEL_S 1
|
||||
|
||||
/* HP-OUT (0x21) */
|
||||
#define RT286_M_HP_MUX_SFT 14
|
||||
#define RT286_HP_SEL_MASK 0x1
|
||||
#define RT286_HP_SEL_SFT 0
|
||||
#define RT286_HP_SEL_F 0
|
||||
#define RT286_HP_SEL_S 1
|
||||
|
||||
/* ADC (0x22) (0x23) */
|
||||
#define RT286_ADC_SEL_MASK 0x7
|
||||
#define RT286_ADC_SEL_SFT 0
|
||||
#define RT286_ADC_SEL_SURR 0
|
||||
#define RT286_ADC_SEL_FRONT 1
|
||||
#define RT286_ADC_SEL_DMIC 2
|
||||
#define RT286_ADC_SEL_BEEP 4
|
||||
#define RT286_ADC_SEL_LINE1 5
|
||||
#define RT286_ADC_SEL_I2S 6
|
||||
#define RT286_ADC_SEL_MIC1 7
|
||||
|
||||
#define RT286_SCLK_S_MCLK 0
|
||||
#define RT286_SCLK_S_PLL 1
|
||||
|
||||
enum {
|
||||
RT286_AIF1,
|
||||
RT286_AIF2,
|
||||
RT286_AIFS,
|
||||
};
|
||||
|
||||
int rt286_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack);
|
||||
|
||||
#endif /* __RT286_H__ */
|
||||
|
||||
@@ -58,3 +58,15 @@ config SND_SOC_INTEL_BYT_MAX98090_MACH
|
||||
help
|
||||
This adds audio driver for Intel Baytrail platform based boards
|
||||
with the MAX98090 audio codec.
|
||||
|
||||
config SND_SOC_INTEL_BROADWELL_MACH
|
||||
tristate "ASoC Audio DSP support for Intel Broadwell Wildcatpoint"
|
||||
depends on SND_SOC_INTEL_SST && X86_INTEL_LPSS && DW_DMAC
|
||||
select SND_SOC_INTEL_HASWELL
|
||||
select SND_COMPRESS_OFFLOAD
|
||||
select SND_SOC_RT286
|
||||
help
|
||||
This adds support for the Wilcatpoint Audio DSP on Intel(R) Broadwell
|
||||
Ultrabook platforms.
|
||||
Say Y if you have such a device
|
||||
If unsure select "N".
|
||||
|
||||
@@ -24,7 +24,9 @@ obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += snd-soc-sst-baytrail-pcm.o
|
||||
snd-soc-sst-haswell-objs := haswell.o
|
||||
snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o
|
||||
snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o
|
||||
snd-soc-sst-broadwell-objs := broadwell.o
|
||||
|
||||
obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
|
||||
obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
|
||||
obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
|
||||
obj-$(CONFIG_SND_SOC_INTEL_BROADWELL_MACH) += snd-soc-sst-broadwell.o
|
||||
|
||||
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
* Intel Broadwell Wildcatpoint SST Audio
|
||||
*
|
||||
* Copyright (C) 2013, Intel Corporation. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <sound/core.h>
|
||||
#include <sound/pcm.h>
|
||||
#include <sound/soc.h>
|
||||
#include <sound/pcm_params.h>
|
||||
|
||||
#include "sst-dsp.h"
|
||||
#include "sst-haswell-ipc.h"
|
||||
|
||||
#include "../codecs/rt286.h"
|
||||
|
||||
static const struct snd_soc_dapm_widget broadwell_widgets[] = {
|
||||
SND_SOC_DAPM_HP("Headphones", NULL),
|
||||
SND_SOC_DAPM_SPK("Speaker", NULL),
|
||||
SND_SOC_DAPM_MIC("Mic Jack", NULL),
|
||||
SND_SOC_DAPM_MIC("DMIC1", NULL),
|
||||
SND_SOC_DAPM_MIC("DMIC2", NULL),
|
||||
SND_SOC_DAPM_LINE("Line Jack", NULL),
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route broadwell_rt286_map[] = {
|
||||
|
||||
/* speaker */
|
||||
{"Speaker", NULL, "SPOR"},
|
||||
{"Speaker", NULL, "SPOL"},
|
||||
|
||||
/* HP jack connectors - unknown if we have jack deteck */
|
||||
{"Headphones", NULL, "HPO Pin"},
|
||||
|
||||
/* other jacks */
|
||||
{"MIC1", NULL, "Mic Jack"},
|
||||
{"LINE1", NULL, "Line Jack"},
|
||||
|
||||
/* digital mics */
|
||||
{"DMIC1 Pin", NULL, "DMIC1"},
|
||||
{"DMIC2 Pin", NULL, "DMIC2"},
|
||||
|
||||
/* CODEC BE connections */
|
||||
{"SSP0 CODEC IN", NULL, "AIF1 Capture"},
|
||||
{"AIF1 Playback", NULL, "SSP0 CODEC OUT"},
|
||||
};
|
||||
|
||||
static int broadwell_ssp0_fixup(struct snd_soc_pcm_runtime *rtd,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_interval *rate = hw_param_interval(params,
|
||||
SNDRV_PCM_HW_PARAM_RATE);
|
||||
struct snd_interval *channels = hw_param_interval(params,
|
||||
SNDRV_PCM_HW_PARAM_CHANNELS);
|
||||
|
||||
/* The ADSP will covert the FE rate to 48k, stereo */
|
||||
rate->min = rate->max = 48000;
|
||||
channels->min = channels->max = 2;
|
||||
|
||||
/* set SSP0 to 16 bit */
|
||||
snd_mask_set(¶ms->masks[SNDRV_PCM_HW_PARAM_FORMAT -
|
||||
SNDRV_PCM_HW_PARAM_FIRST_MASK],
|
||||
SNDRV_PCM_FORMAT_S16_LE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int broadwell_rt286_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *params)
|
||||
{
|
||||
struct snd_soc_pcm_runtime *rtd = substream->private_data;
|
||||
struct snd_soc_dai *codec_dai = rtd->codec_dai;
|
||||
int ret;
|
||||
|
||||
ret = snd_soc_dai_set_sysclk(codec_dai, RT286_SCLK_S_PLL, 24000000,
|
||||
SND_SOC_CLOCK_IN);
|
||||
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "can't set codec sysclk configuration\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct snd_soc_ops broadwell_rt286_ops = {
|
||||
.hw_params = broadwell_rt286_hw_params,
|
||||
};
|
||||
|
||||
static int broadwell_rtd_init(struct snd_soc_pcm_runtime *rtd)
|
||||
{
|
||||
struct snd_soc_codec *codec = rtd->codec;
|
||||
struct snd_soc_dapm_context *dapm = &codec->dapm;
|
||||
struct sst_pdata *pdata = dev_get_platdata(rtd->platform->dev);
|
||||
struct sst_hsw *broadwell = pdata->dsp;
|
||||
int ret;
|
||||
|
||||
/* Set ADSP SSP port settings */
|
||||
ret = sst_hsw_device_set_config(broadwell, SST_HSW_DEVICE_SSP_0,
|
||||
SST_HSW_DEVICE_MCLK_FREQ_24_MHZ,
|
||||
SST_HSW_DEVICE_CLOCK_MASTER, 9);
|
||||
if (ret < 0) {
|
||||
dev_err(rtd->dev, "error: failed to set device config\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* always connected - check HP for jack detect */
|
||||
snd_soc_dapm_enable_pin(dapm, "Headphones");
|
||||
snd_soc_dapm_enable_pin(dapm, "Speaker");
|
||||
snd_soc_dapm_enable_pin(dapm, "Mic Jack");
|
||||
snd_soc_dapm_enable_pin(dapm, "Line Jack");
|
||||
snd_soc_dapm_enable_pin(dapm, "DMIC1");
|
||||
snd_soc_dapm_enable_pin(dapm, "DMIC2");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* broadwell digital audio interface glue - connects codec <--> CPU */
|
||||
static struct snd_soc_dai_link broadwell_rt286_dais[] = {
|
||||
/* Front End DAI links */
|
||||
{
|
||||
.name = "System PCM",
|
||||
.stream_name = "System Playback",
|
||||
.cpu_dai_name = "System Pin",
|
||||
.platform_name = "haswell-pcm-audio",
|
||||
.dynamic = 1,
|
||||
.codec_name = "snd-soc-dummy",
|
||||
.codec_dai_name = "snd-soc-dummy-dai",
|
||||
.init = broadwell_rtd_init,
|
||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
|
||||
.dpcm_playback = 1,
|
||||
},
|
||||
{
|
||||
.name = "Offload0",
|
||||
.stream_name = "Offload0 Playback",
|
||||
.cpu_dai_name = "Offload0 Pin",
|
||||
.platform_name = "haswell-pcm-audio",
|
||||
.dynamic = 1,
|
||||
.codec_name = "snd-soc-dummy",
|
||||
.codec_dai_name = "snd-soc-dummy-dai",
|
||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
|
||||
.dpcm_playback = 1,
|
||||
},
|
||||
{
|
||||
.name = "Offload1",
|
||||
.stream_name = "Offload1 Playback",
|
||||
.cpu_dai_name = "Offload1 Pin",
|
||||
.platform_name = "haswell-pcm-audio",
|
||||
.dynamic = 1,
|
||||
.codec_name = "snd-soc-dummy",
|
||||
.codec_dai_name = "snd-soc-dummy-dai",
|
||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
|
||||
.dpcm_playback = 1,
|
||||
},
|
||||
{
|
||||
.name = "Loopback PCM",
|
||||
.stream_name = "Loopback",
|
||||
.cpu_dai_name = "Loopback Pin",
|
||||
.platform_name = "haswell-pcm-audio",
|
||||
.dynamic = 0,
|
||||
.codec_name = "snd-soc-dummy",
|
||||
.codec_dai_name = "snd-soc-dummy-dai",
|
||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
|
||||
.dpcm_capture = 1,
|
||||
},
|
||||
{
|
||||
.name = "Capture PCM",
|
||||
.stream_name = "Capture",
|
||||
.cpu_dai_name = "Capture Pin",
|
||||
.platform_name = "haswell-pcm-audio",
|
||||
.dynamic = 1,
|
||||
.codec_name = "snd-soc-dummy",
|
||||
.codec_dai_name = "snd-soc-dummy-dai",
|
||||
.trigger = {SND_SOC_DPCM_TRIGGER_POST, SND_SOC_DPCM_TRIGGER_POST},
|
||||
.dpcm_capture = 1,
|
||||
},
|
||||
|
||||
/* Back End DAI links */
|
||||
{
|
||||
/* SSP0 - Codec */
|
||||
.name = "Codec",
|
||||
.be_id = 0,
|
||||
.cpu_dai_name = "snd-soc-dummy-dai",
|
||||
.platform_name = "snd-soc-dummy",
|
||||
.no_pcm = 1,
|
||||
.codec_name = "i2c-INT343A:00",
|
||||
.codec_dai_name = "rt286-aif1",
|
||||
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
|
||||
SND_SOC_DAIFMT_CBS_CFS,
|
||||
.ignore_suspend = 1,
|
||||
.ignore_pmdown_time = 1,
|
||||
.be_hw_params_fixup = broadwell_ssp0_fixup,
|
||||
.ops = &broadwell_rt286_ops,
|
||||
.dpcm_playback = 1,
|
||||
.dpcm_capture = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/* broadwell audio machine driver for WPT + RT286S */
|
||||
static struct snd_soc_card broadwell_rt286 = {
|
||||
.name = "broadwell-rt286",
|
||||
.owner = THIS_MODULE,
|
||||
.dai_link = broadwell_rt286_dais,
|
||||
.num_links = ARRAY_SIZE(broadwell_rt286_dais),
|
||||
.dapm_widgets = broadwell_widgets,
|
||||
.num_dapm_widgets = ARRAY_SIZE(broadwell_widgets),
|
||||
.dapm_routes = broadwell_rt286_map,
|
||||
.num_dapm_routes = ARRAY_SIZE(broadwell_rt286_map),
|
||||
.fully_routed = true,
|
||||
};
|
||||
|
||||
static int broadwell_audio_probe(struct platform_device *pdev)
|
||||
{
|
||||
broadwell_rt286.dev = &pdev->dev;
|
||||
|
||||
return snd_soc_register_card(&broadwell_rt286);
|
||||
}
|
||||
|
||||
static int broadwell_audio_remove(struct platform_device *pdev)
|
||||
{
|
||||
snd_soc_unregister_card(&broadwell_rt286);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver broadwell_audio = {
|
||||
.probe = broadwell_audio_probe,
|
||||
.remove = broadwell_audio_remove,
|
||||
.driver = {
|
||||
.name = "broadwell-audio",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(broadwell_audio)
|
||||
|
||||
/* Module information */
|
||||
MODULE_AUTHOR("Liam Girdwood, Xingchao Wang");
|
||||
MODULE_DESCRIPTION("Intel SST Audio for WPT/Broadwell");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_ALIAS("platform:broadwell-audio");
|
||||
@@ -63,14 +63,6 @@ static struct snd_soc_jack_pin hs_jack_pins[] = {
|
||||
.pin = "Headset Mic",
|
||||
.mask = SND_JACK_MICROPHONE,
|
||||
},
|
||||
{
|
||||
.pin = "Ext Spk",
|
||||
.mask = SND_JACK_LINEOUT,
|
||||
},
|
||||
{
|
||||
.pin = "Int Mic",
|
||||
.mask = SND_JACK_LINEIN,
|
||||
},
|
||||
};
|
||||
|
||||
static struct snd_soc_jack_gpio hs_jack_gpios[] = {
|
||||
|
||||
@@ -34,6 +34,7 @@ static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
|
||||
};
|
||||
|
||||
static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
|
||||
{"Headset Mic", NULL, "MICBIAS1"},
|
||||
{"IN2P", NULL, "Headset Mic"},
|
||||
{"IN2N", NULL, "Headset Mic"},
|
||||
{"DMIC1", NULL, "Internal Mic"},
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (C) 2013-14 Intel Corp
|
||||
* Author: Ramesh Babu <ramesh.babu.koul@intel.com>
|
||||
* Omair M Abdullah <omair.m.abdullah@intel.com>
|
||||
* Samreen Nilofer <samreen.nilofer@intel.com>
|
||||
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* 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 __SST_CONTROLS_V2_H__
|
||||
#define __SST_CONTROLS_V2_H__
|
||||
|
||||
enum {
|
||||
MERR_DPCM_AUDIO = 0,
|
||||
MERR_DPCM_COMPR,
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -122,6 +122,26 @@ struct sst_byt_tstamp {
|
||||
u32 channel_peak[8];
|
||||
} __packed;
|
||||
|
||||
struct sst_byt_fw_version {
|
||||
u8 build;
|
||||
u8 minor;
|
||||
u8 major;
|
||||
u8 type;
|
||||
} __packed;
|
||||
|
||||
struct sst_byt_fw_build_info {
|
||||
u8 date[16];
|
||||
u8 time[16];
|
||||
} __packed;
|
||||
|
||||
struct sst_byt_fw_init {
|
||||
struct sst_byt_fw_version fw_version;
|
||||
struct sst_byt_fw_build_info build_info;
|
||||
u16 result;
|
||||
u8 module_id;
|
||||
u8 debug_info;
|
||||
} __packed;
|
||||
|
||||
/* driver internal IPC message structure */
|
||||
struct ipc_message {
|
||||
struct list_head list;
|
||||
@@ -868,6 +888,7 @@ int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata)
|
||||
{
|
||||
struct sst_byt *byt;
|
||||
struct sst_fw *byt_sst_fw;
|
||||
struct sst_byt_fw_init init;
|
||||
int err;
|
||||
|
||||
dev_dbg(dev, "initialising Byt DSP IPC\n");
|
||||
@@ -929,6 +950,15 @@ int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata)
|
||||
goto boot_err;
|
||||
}
|
||||
|
||||
/* show firmware information */
|
||||
sst_dsp_inbox_read(byt->dsp, &init, sizeof(init));
|
||||
dev_info(byt->dev, "FW version: %02x.%02x.%02x.%02x\n",
|
||||
init.fw_version.major, init.fw_version.minor,
|
||||
init.fw_version.build, init.fw_version.type);
|
||||
dev_info(byt->dev, "Build type: %x\n", init.fw_version.type);
|
||||
dev_info(byt->dev, "Build date: %s %s\n",
|
||||
init.build_info.date, init.build_info.time);
|
||||
|
||||
pdata->dsp = byt;
|
||||
byt->fw = byt_sst_fw;
|
||||
|
||||
|
||||
@@ -224,19 +224,23 @@ EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits64);
|
||||
|
||||
void sst_dsp_dump(struct sst_dsp *sst)
|
||||
{
|
||||
sst->ops->dump(sst);
|
||||
if (sst->ops->dump)
|
||||
sst->ops->dump(sst);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sst_dsp_dump);
|
||||
|
||||
void sst_dsp_reset(struct sst_dsp *sst)
|
||||
{
|
||||
sst->ops->reset(sst);
|
||||
if (sst->ops->reset)
|
||||
sst->ops->reset(sst);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sst_dsp_reset);
|
||||
|
||||
int sst_dsp_boot(struct sst_dsp *sst)
|
||||
{
|
||||
sst->ops->boot(sst);
|
||||
if (sst->ops->boot)
|
||||
sst->ops->boot(sst);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sst_dsp_boot);
|
||||
|
||||
@@ -52,7 +52,11 @@
|
||||
#define SST_CLKCTL 0x78
|
||||
#define SST_CSR2 0x80
|
||||
#define SST_LTRC 0xE0
|
||||
#define SST_HDMC 0xE8
|
||||
#define SST_HMDC 0xE8
|
||||
|
||||
#define SST_SHIM_BEGIN SST_CSR
|
||||
#define SST_SHIM_END SST_HDMC
|
||||
|
||||
#define SST_DBGO 0xF0
|
||||
|
||||
#define SST_SHIM_SIZE 0x100
|
||||
@@ -73,6 +77,8 @@
|
||||
#define SST_CSR_S0IOCS (0x1 << 21)
|
||||
#define SST_CSR_S1IOCS (0x1 << 23)
|
||||
#define SST_CSR_LPCS (0x1 << 31)
|
||||
#define SST_CSR_24MHZ_LPCS (SST_CSR_SBCS0 | SST_CSR_SBCS1 | SST_CSR_LPCS)
|
||||
#define SST_CSR_24MHZ_NO_LPCS (SST_CSR_SBCS0 | SST_CSR_SBCS1)
|
||||
#define SST_BYT_CSR_RST (0x1 << 0)
|
||||
#define SST_BYT_CSR_VECTOR_SEL (0x1 << 1)
|
||||
#define SST_BYT_CSR_STALL (0x1 << 2)
|
||||
@@ -92,6 +98,14 @@
|
||||
#define SST_IMRX_DONE (0x1 << 0)
|
||||
#define SST_BYT_IMRX_REQUEST (0x1 << 1)
|
||||
|
||||
/* IMRD / IMD */
|
||||
#define SST_IMRD_DONE (0x1 << 0)
|
||||
#define SST_IMRD_BUSY (0x1 << 1)
|
||||
#define SST_IMRD_SSP0 (0x1 << 16)
|
||||
#define SST_IMRD_DMAC0 (0x1 << 21)
|
||||
#define SST_IMRD_DMAC1 (0x1 << 22)
|
||||
#define SST_IMRD_DMAC (SST_IMRD_DMAC0 | SST_IMRD_DMAC1)
|
||||
|
||||
/* IPCX / IPCC */
|
||||
#define SST_IPCX_DONE (0x1 << 30)
|
||||
#define SST_IPCX_BUSY (0x1 << 31)
|
||||
@@ -118,9 +132,21 @@
|
||||
/* LTRC */
|
||||
#define SST_LTRC_VAL(x) (x << 0)
|
||||
|
||||
/* HDMC */
|
||||
#define SST_HDMC_HDDA0(x) (x << 0)
|
||||
#define SST_HDMC_HDDA1(x) (x << 7)
|
||||
/* HMDC */
|
||||
#define SST_HMDC_HDDA0(x) (x << 0)
|
||||
#define SST_HMDC_HDDA1(x) (x << 7)
|
||||
#define SST_HMDC_HDDA_E0_CH0 1
|
||||
#define SST_HMDC_HDDA_E0_CH1 2
|
||||
#define SST_HMDC_HDDA_E0_CH2 4
|
||||
#define SST_HMDC_HDDA_E0_CH3 8
|
||||
#define SST_HMDC_HDDA_E1_CH0 SST_HMDC_HDDA1(SST_HMDC_HDDA_E0_CH0)
|
||||
#define SST_HMDC_HDDA_E1_CH1 SST_HMDC_HDDA1(SST_HMDC_HDDA_E0_CH1)
|
||||
#define SST_HMDC_HDDA_E1_CH2 SST_HMDC_HDDA1(SST_HMDC_HDDA_E0_CH2)
|
||||
#define SST_HMDC_HDDA_E1_CH3 SST_HMDC_HDDA1(SST_HMDC_HDDA_E0_CH3)
|
||||
#define SST_HMDC_HDDA_E0_ALLCH (SST_HMDC_HDDA_E0_CH0 | SST_HMDC_HDDA_E0_CH1 | \
|
||||
SST_HMDC_HDDA_E0_CH2 | SST_HMDC_HDDA_E0_CH3)
|
||||
#define SST_HMDC_HDDA_E1_ALLCH (SST_HMDC_HDDA_E1_CH0 | SST_HMDC_HDDA_E1_CH1 | \
|
||||
SST_HMDC_HDDA_E1_CH2 | SST_HMDC_HDDA_E1_CH3)
|
||||
|
||||
|
||||
/* SST Vendor Defined Registers and bits */
|
||||
@@ -130,11 +156,16 @@
|
||||
#define SST_VDRTCTL3 0xaC
|
||||
|
||||
/* VDRTCTL0 */
|
||||
#define SST_VDRTCL0_APLLSE_MASK 1
|
||||
#define SST_VDRTCL0_DSRAMPGE_SHIFT 16
|
||||
#define SST_VDRTCL0_DSRAMPGE_MASK (0xffff << SST_VDRTCL0_DSRAMPGE_SHIFT)
|
||||
#define SST_VDRTCL0_ISRAMPGE_SHIFT 6
|
||||
#define SST_VDRTCL0_ISRAMPGE_MASK (0x3ff << SST_VDRTCL0_ISRAMPGE_SHIFT)
|
||||
|
||||
/* PMCS */
|
||||
#define SST_PMCS 0x84
|
||||
#define SST_PMCS_PS_MASK 0x3
|
||||
|
||||
struct sst_dsp;
|
||||
|
||||
/*
|
||||
|
||||
@@ -28,9 +28,6 @@
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <linux/acpi.h>
|
||||
#include <acpi/acpi_bus.h>
|
||||
|
||||
#include "sst-dsp.h"
|
||||
#include "sst-dsp-priv.h"
|
||||
#include "sst-haswell-ipc.h"
|
||||
@@ -272,9 +269,9 @@ static void hsw_boot(struct sst_dsp *sst)
|
||||
SST_CSR2_SDFD_SSP1);
|
||||
|
||||
/* enable DMA engine 0,1 all channels to access host memory */
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_HDMC,
|
||||
SST_HDMC_HDDA1(0xff) | SST_HDMC_HDDA0(0xff),
|
||||
SST_HDMC_HDDA1(0xff) | SST_HDMC_HDDA0(0xff));
|
||||
sst_dsp_shim_update_bits_unlocked(sst, SST_HMDC,
|
||||
SST_HMDC_HDDA1(0xff) | SST_HMDC_HDDA0(0xff),
|
||||
SST_HMDC_HDDA1(0xff) | SST_HMDC_HDDA0(0xff));
|
||||
|
||||
/* disable all clock gating */
|
||||
writel(0x0, sst->addr.pci_cfg + SST_VDRTCTL2);
|
||||
@@ -313,9 +310,7 @@ static const struct sst_adsp_memregion lp_region[] = {
|
||||
|
||||
/* wild cat point ADSP mem regions */
|
||||
static const struct sst_adsp_memregion wpt_region[] = {
|
||||
{0x00000, 0x40000, 8, SST_MEM_DRAM}, /* D-SRAM0 - 8 * 32kB */
|
||||
{0x40000, 0x80000, 8, SST_MEM_DRAM}, /* D-SRAM1 - 8 * 32kB */
|
||||
{0x80000, 0xA0000, 4, SST_MEM_DRAM}, /* D-SRAM2 - 4 * 32kB */
|
||||
{0x00000, 0xA0000, 20, SST_MEM_DRAM}, /* D-SRAM0,D-SRAM1,D-SRAM2 - 20 * 32kB */
|
||||
{0xA0000, 0xF0000, 10, SST_MEM_IRAM}, /* I-SRAM - 10 * 32kB */
|
||||
};
|
||||
|
||||
@@ -339,21 +334,40 @@ static int hsw_acpi_resource_map(struct sst_dsp *sst, struct sst_pdata *pdata)
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct sst_sram_shift {
|
||||
u32 dev_id; /* SST Device IDs */
|
||||
u32 iram_shift;
|
||||
u32 dram_shift;
|
||||
};
|
||||
|
||||
static const struct sst_sram_shift sram_shift[] = {
|
||||
{SST_DEV_ID_LYNX_POINT, 6, 16}, /* lp */
|
||||
{SST_DEV_ID_WILDCAT_POINT, 2, 12}, /* wpt */
|
||||
};
|
||||
static u32 hsw_block_get_bit(struct sst_mem_block *block)
|
||||
{
|
||||
u32 bit = 0, shift = 0;
|
||||
u32 bit = 0, shift = 0, index;
|
||||
struct sst_dsp *sst = block->dsp;
|
||||
|
||||
switch (block->type) {
|
||||
case SST_MEM_DRAM:
|
||||
shift = 16;
|
||||
break;
|
||||
case SST_MEM_IRAM:
|
||||
shift = 6;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
for (index = 0; index < ARRAY_SIZE(sram_shift); index++) {
|
||||
if (sram_shift[index].dev_id == sst->id)
|
||||
break;
|
||||
}
|
||||
|
||||
if (index < ARRAY_SIZE(sram_shift)) {
|
||||
switch (block->type) {
|
||||
case SST_MEM_DRAM:
|
||||
shift = sram_shift[index].dram_shift;
|
||||
break;
|
||||
case SST_MEM_IRAM:
|
||||
shift = sram_shift[index].iram_shift;
|
||||
break;
|
||||
default:
|
||||
shift = 0;
|
||||
}
|
||||
} else
|
||||
shift = 0;
|
||||
|
||||
bit = 1 << (block->index + shift);
|
||||
|
||||
return bit;
|
||||
@@ -501,8 +515,9 @@ static int hsw_init(struct sst_dsp *sst, struct sst_pdata *pdata)
|
||||
}
|
||||
}
|
||||
|
||||
/* set default power gating mask */
|
||||
writel(0x0, sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
/* set default power gating control, enable power gating control for all blocks. that is,
|
||||
can't be accessed, please enable each block before accessing. */
|
||||
writel(0xffffffff, sst->addr.pci_cfg + SST_VDRTCTL0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ struct sst_hsw_ipc_fw_ready {
|
||||
u32 inbox_size;
|
||||
u32 outbox_size;
|
||||
u32 fw_info_size;
|
||||
u8 fw_info[1];
|
||||
u8 fw_info[IPC_MAX_MAILBOX_BYTES - 5 * sizeof(u32)];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct ipc_message {
|
||||
@@ -457,9 +457,10 @@ static void ipc_tx_msgs(struct kthread_work *work)
|
||||
return;
|
||||
}
|
||||
|
||||
/* if the DSP is busy we will TX messages after IRQ */
|
||||
/* if the DSP is busy, we will TX messages after IRQ.
|
||||
* also postpone if we are in the middle of procesing completion irq*/
|
||||
ipcx = sst_dsp_shim_read_unlocked(hsw->dsp, SST_IPCX);
|
||||
if (ipcx & SST_IPCX_BUSY) {
|
||||
if (ipcx & (SST_IPCX_BUSY | SST_IPCX_DONE)) {
|
||||
spin_unlock_irqrestore(&hsw->dsp->spinlock, flags);
|
||||
return;
|
||||
}
|
||||
@@ -502,6 +503,7 @@ static int tx_wait_done(struct sst_hsw *hsw, struct ipc_message *msg,
|
||||
ipc_shim_dbg(hsw, "message timeout");
|
||||
|
||||
trace_ipc_error("error message timeout for", msg->header);
|
||||
list_del(&msg->list);
|
||||
ret = -ETIMEDOUT;
|
||||
} else {
|
||||
|
||||
@@ -569,6 +571,9 @@ static void hsw_fw_ready(struct sst_hsw *hsw, u32 header)
|
||||
{
|
||||
struct sst_hsw_ipc_fw_ready fw_ready;
|
||||
u32 offset;
|
||||
u8 fw_info[IPC_MAX_MAILBOX_BYTES - 5 * sizeof(u32)];
|
||||
char *tmp[5], *pinfo;
|
||||
int i = 0;
|
||||
|
||||
offset = (header & 0x1FFFFFFF) << 3;
|
||||
|
||||
@@ -589,6 +594,19 @@ static void hsw_fw_ready(struct sst_hsw *hsw, u32 header)
|
||||
fw_ready.inbox_offset, fw_ready.inbox_size);
|
||||
dev_dbg(hsw->dev, " mailbox downstream 0x%x - size 0x%x\n",
|
||||
fw_ready.outbox_offset, fw_ready.outbox_size);
|
||||
if (fw_ready.fw_info_size < sizeof(fw_ready.fw_info)) {
|
||||
fw_ready.fw_info[fw_ready.fw_info_size] = 0;
|
||||
dev_dbg(hsw->dev, " Firmware info: %s \n", fw_ready.fw_info);
|
||||
|
||||
/* log the FW version info got from the mailbox here. */
|
||||
memcpy(fw_info, fw_ready.fw_info, fw_ready.fw_info_size);
|
||||
pinfo = &fw_info[0];
|
||||
for (i = 0; i < sizeof(tmp) / sizeof(char *); i++)
|
||||
tmp[i] = strsep(&pinfo, " ");
|
||||
dev_info(hsw->dev, "FW loaded, mailbox readback FW info: type %s, - "
|
||||
"version: %s.%s, build %s, source commit id: %s\n",
|
||||
tmp[0], tmp[1], tmp[2], tmp[3], tmp[4]);
|
||||
}
|
||||
}
|
||||
|
||||
static void hsw_notification_work(struct work_struct *work)
|
||||
@@ -671,7 +689,9 @@ static void hsw_stream_update(struct sst_hsw *hsw, struct ipc_message *msg)
|
||||
switch (stream_msg) {
|
||||
case IPC_STR_STAGE_MESSAGE:
|
||||
case IPC_STR_NOTIFICATION:
|
||||
break;
|
||||
case IPC_STR_RESET:
|
||||
trace_ipc_notification("stream reset", stream->reply.stream_hw_id);
|
||||
break;
|
||||
case IPC_STR_PAUSE:
|
||||
stream->running = false;
|
||||
@@ -762,7 +782,8 @@ static int hsw_process_reply(struct sst_hsw *hsw, u32 header)
|
||||
}
|
||||
|
||||
/* update any stream states */
|
||||
hsw_stream_update(hsw, msg);
|
||||
if (msg_get_global_type(header) == IPC_GLB_STREAM_MESSAGE)
|
||||
hsw_stream_update(hsw, msg);
|
||||
|
||||
/* wake up and return the error if we have waiters on this message ? */
|
||||
list_del(&msg->list);
|
||||
@@ -1628,7 +1649,7 @@ int sst_hsw_dx_set_state(struct sst_hsw *hsw,
|
||||
enum sst_hsw_dx_state state, struct sst_hsw_ipc_dx_reply *dx)
|
||||
{
|
||||
u32 header, state_;
|
||||
int ret;
|
||||
int ret, item;
|
||||
|
||||
header = IPC_GLB_TYPE(IPC_GLB_ENTER_DX_STATE);
|
||||
state_ = state;
|
||||
@@ -1642,6 +1663,13 @@ int sst_hsw_dx_set_state(struct sst_hsw *hsw,
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (item = 0; item < dx->entries_no; item++) {
|
||||
dev_dbg(hsw->dev,
|
||||
"Item[%d] offset[%x] - size[%x] - source[%x]\n",
|
||||
item, dx->mem_info[item].offset,
|
||||
dx->mem_info[item].size,
|
||||
dx->mem_info[item].source);
|
||||
}
|
||||
dev_dbg(hsw->dev, "ipc: got %d entry numbers for state %d\n",
|
||||
dx->entries_no, state);
|
||||
|
||||
@@ -1775,8 +1803,6 @@ int sst_hsw_dsp_init(struct device *dev, struct sst_pdata *pdata)
|
||||
|
||||
/* get the FW version */
|
||||
sst_hsw_fw_get_version(hsw, &version);
|
||||
dev_info(hsw->dev, "FW loaded: type %d - version: %d.%d build %d\n",
|
||||
version.type, version.major, version.minor, version.build);
|
||||
|
||||
/* get the globalmixer */
|
||||
ret = sst_hsw_mixer_get_info(hsw);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user