aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/linux/firmware/cirrus/cs_dsp.h28
-rw-r--r--include/sound/soc.h17
-rw-r--r--sound/soc/codecs/ak4613.c10
-rw-r--r--sound/soc/codecs/ak4642.c8
-rw-r--r--sound/soc/codecs/alc5623.c24
-rw-r--r--sound/soc/codecs/alc5632.c20
-rw-r--r--sound/soc/codecs/max98088.c21
-rw-r--r--sound/soc/codecs/max98090.c23
-rw-r--r--sound/soc/codecs/max98095.c19
-rw-r--r--sound/soc/codecs/pcm186x-i2c.c24
-rw-r--r--sound/soc/codecs/tas2562.c25
-rw-r--r--sound/soc/codecs/tas571x.c11
-rw-r--r--sound/soc/codecs/tas5720.c21
-rw-r--r--sound/soc/codecs/tlv320adc3xxx.c21
-rw-r--r--sound/soc/codecs/tlv320aic31xx.c32
-rw-r--r--sound/soc/codecs/tlv320aic32x4-i2c.c11
-rw-r--r--sound/soc/codecs/tlv320aic3x-i2c.c25
-rw-r--r--sound/soc/fsl/fsl_asrc.c6
-rw-r--r--sound/soc/fsl/imx-hdmi.c3
-rw-r--r--sound/soc/img/img-i2s-in.c6
-rw-r--r--sound/soc/img/img-parallel-out.c6
-rw-r--r--sound/soc/img/img-spdif-in.c6
-rw-r--r--sound/soc/img/img-spdif-out.c6
-rw-r--r--sound/soc/intel/Kconfig5
-rw-r--r--sound/soc/qcom/sc7280.c10
-rw-r--r--sound/soc/sh/Kconfig2
-rw-r--r--sound/soc/sof/amd/renoir.c1
-rw-r--r--sound/soc/sof/core.c2
-rw-r--r--sound/soc/sof/imx/imx8.c2
-rw-r--r--sound/soc/sof/imx/imx8m.c1
-rw-r--r--sound/soc/sof/intel/bdw.c1
-rw-r--r--sound/soc/sof/intel/byt.c2
-rw-r--r--sound/soc/sof/intel/hda-common-ops.c1
-rw-r--r--sound/soc/sof/intel/pci-tng.c1
-rw-r--r--sound/soc/sof/ipc.c15
-rw-r--r--sound/soc/sof/ipc3.c306
-rw-r--r--sound/soc/sof/loader.c227
-rw-r--r--sound/soc/sof/mediatek/Kconfig9
-rw-r--r--sound/soc/sof/mediatek/Makefile1
-rw-r--r--sound/soc/sof/mediatek/adsp_helper.h8
-rw-r--r--sound/soc/sof/mediatek/mt8186/Makefile4
-rw-r--r--sound/soc/sof/mediatek/mt8186/mt8186-clk.c101
-rw-r--r--sound/soc/sof/mediatek/mt8186/mt8186-clk.h24
-rw-r--r--sound/soc/sof/mediatek/mt8186/mt8186-loader.c53
-rw-r--r--sound/soc/sof/mediatek/mt8186/mt8186.c413
-rw-r--r--sound/soc/sof/mediatek/mt8186/mt8186.h80
-rw-r--r--sound/soc/sof/sof-priv.h9
47 files changed, 1209 insertions, 442 deletions
diff --git a/include/linux/firmware/cirrus/cs_dsp.h b/include/linux/firmware/cirrus/cs_dsp.h
index 38b4da3ddfe4..30055706cce2 100644
--- a/include/linux/firmware/cirrus/cs_dsp.h
+++ b/include/linux/firmware/cirrus/cs_dsp.h
@@ -68,36 +68,36 @@ struct cs_dsp_alg_region {
/**
* struct cs_dsp_coeff_ctl - Describes a coefficient control
+ * @list: List node for internal use
+ * @dsp: DSP instance associated with this control
+ * @cache: Cached value of the control
* @fw_name: Name of the firmware
* @subname: Name of the control parsed from the WMFW
* @subname_len: Length of subname
- * @alg_region: Logical region associated with this control
- * @dsp: DSP instance associated with this control
- * @enabled: Flag indicating whether control is enabled
- * @list: List node for internal use
- * @cache: Cached value of the control
* @offset: Offset of control within alg_region in words
* @len: Length of the cached value in bytes
- * @set: Flag indicating the value has been written by the user
- * @flags: Bitfield of WMFW_CTL_FLAG_ control flags defined in wmfw.h
* @type: One of the WMFW_CTL_TYPE_ control types defined in wmfw.h
+ * @flags: Bitfield of WMFW_CTL_FLAG_ control flags defined in wmfw.h
+ * @set: Flag indicating the value has been written by the user
+ * @enabled: Flag indicating whether control is enabled
+ * @alg_region: Logical region associated with this control
* @priv: For use by the client
*/
struct cs_dsp_coeff_ctl {
+ struct list_head list;
+ struct cs_dsp *dsp;
+ void *cache;
const char *fw_name;
/* Subname is needed to match with firmware */
const char *subname;
unsigned int subname_len;
- struct cs_dsp_alg_region alg_region;
- struct cs_dsp *dsp;
- unsigned int enabled:1;
- struct list_head list;
- void *cache;
unsigned int offset;
size_t len;
- unsigned int set:1;
- unsigned int flags;
unsigned int type;
+ unsigned int flags;
+ unsigned int set:1;
+ unsigned int enabled:1;
+ struct cs_dsp_alg_region alg_region;
void *priv;
};
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 2d3261799d2c..f906e5a70830 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -282,6 +282,23 @@
.get = xhandler_get, .put = xhandler_put, \
.private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \
xmax, xinvert) }
+#define SOC_DOUBLE_R_S_EXT_TLV(xname, reg_left, reg_right, xshift, xmin, xmax, \
+ xsign_bit, xinvert, xhandler_get, xhandler_put, \
+ tlv_array) \
+{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
+ .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
+ SNDRV_CTL_ELEM_ACCESS_READWRITE, \
+ .tlv.p = (tlv_array), \
+ .info = snd_soc_info_volsw, \
+ .get = xhandler_get, .put = xhandler_put, \
+ .private_value = SOC_DOUBLE_R_S_VALUE(reg_left, reg_right, xshift, \
+ xmin, xmax, xsign_bit, xinvert) }
+#define SOC_SINGLE_S_EXT_TLV(xname, xreg, xshift, xmin, xmax, \
+ xsign_bit, xinvert, xhandler_get, xhandler_put, \
+ tlv_array) \
+ SOC_DOUBLE_R_S_EXT_TLV(xname, xreg, xreg, xshift, xmin, xmax, \
+ xsign_bit, xinvert, xhandler_get, xhandler_put, \
+ tlv_array)
#define SOC_SINGLE_BOOL_EXT(xname, xdata, xhandler_get, xhandler_put) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
.info = snd_soc_info_bool_ext, \
diff --git a/sound/soc/codecs/ak4613.c b/sound/soc/codecs/ak4613.c
index 03b829930769..55e773f92122 100644
--- a/sound/soc/codecs/ak4613.c
+++ b/sound/soc/codecs/ak4613.c
@@ -876,8 +876,7 @@ static void ak4613_parse_of(struct ak4613_priv *priv,
AK4613_CONFIG_SDTI_set(priv, sdti_num);
}
-static int ak4613_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int ak4613_i2c_probe(struct i2c_client *i2c)
{
struct device *dev = &i2c->dev;
struct device_node *np = dev->of_node;
@@ -888,8 +887,11 @@ static int ak4613_i2c_probe(struct i2c_client *i2c,
regmap_cfg = NULL;
if (np)
regmap_cfg = of_device_get_match_data(dev);
- else
+ else {
+ const struct i2c_device_id *id =
+ i2c_match_id(ak4613_i2c_id, i2c);
regmap_cfg = (const struct regmap_config *)id->driver_data;
+ }
if (!regmap_cfg)
return -EINVAL;
@@ -927,7 +929,7 @@ static struct i2c_driver ak4613_i2c_driver = {
.name = "ak4613-codec",
.of_match_table = ak4613_of_match,
},
- .probe = ak4613_i2c_probe,
+ .probe_new = ak4613_i2c_probe,
.remove = ak4613_i2c_remove,
.id_table = ak4613_i2c_id,
};
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
index c284dcc5af76..3c20ff5595eb 100644
--- a/sound/soc/codecs/ak4642.c
+++ b/sound/soc/codecs/ak4642.c
@@ -630,8 +630,8 @@ static struct clk *ak4642_of_parse_mcko(struct device *dev)
#endif
static const struct of_device_id ak4642_of_match[];
-static int ak4642_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static const struct i2c_device_id ak4642_i2c_id[];
+static int ak4642_i2c_probe(struct i2c_client *i2c)
{
struct device *dev = &i2c->dev;
struct device_node *np = dev->of_node;
@@ -651,6 +651,8 @@ static int ak4642_i2c_probe(struct i2c_client *i2c,
if (of_id)
drvdata = of_id->data;
} else {
+ const struct i2c_device_id *id =
+ i2c_match_id(ak4642_i2c_id, i2c);
drvdata = (const struct ak4642_drvdata *)id->driver_data;
}
@@ -697,7 +699,7 @@ static struct i2c_driver ak4642_i2c_driver = {
.name = "ak4642-codec",
.of_match_table = ak4642_of_match,
},
- .probe = ak4642_i2c_probe,
+ .probe_new = ak4642_i2c_probe,
.id_table = ak4642_i2c_id,
};
diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c
index b10357a6d655..8e6235d2c544 100644
--- a/sound/soc/codecs/alc5623.c
+++ b/sound/soc/codecs/alc5623.c
@@ -968,14 +968,21 @@ static const struct regmap_config alc5623_regmap = {
.cache_type = REGCACHE_RBTREE,
};
+static const struct i2c_device_id alc5623_i2c_table[] = {
+ {"alc5621", 0x21},
+ {"alc5622", 0x22},
+ {"alc5623", 0x23},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, alc5623_i2c_table);
+
/*
* ALC5623 2 wire address is determined by A1 pin
* state during powerup.
* low = 0x1a
* high = 0x1b
*/
-static int alc5623_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int alc5623_i2c_probe(struct i2c_client *client)
{
struct alc5623_platform_data *pdata;
struct alc5623_priv *alc5623;
@@ -983,6 +990,7 @@ static int alc5623_i2c_probe(struct i2c_client *client,
unsigned int vid1, vid2;
int ret;
u32 val32;
+ const struct i2c_device_id *id;
alc5623 = devm_kzalloc(&client->dev, sizeof(struct alc5623_priv),
GFP_KERNEL);
@@ -1009,6 +1017,8 @@ static int alc5623_i2c_probe(struct i2c_client *client,
}
vid2 >>= 8;
+ id = i2c_match_id(alc5623_i2c_table, client);
+
if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) {
dev_err(&client->dev, "unknown or wrong codec\n");
dev_err(&client->dev, "Expected %x:%lx, got %x:%x\n",
@@ -1060,14 +1070,6 @@ static int alc5623_i2c_probe(struct i2c_client *client,
return ret;
}
-static const struct i2c_device_id alc5623_i2c_table[] = {
- {"alc5621", 0x21},
- {"alc5622", 0x22},
- {"alc5623", 0x23},
- {}
-};
-MODULE_DEVICE_TABLE(i2c, alc5623_i2c_table);
-
#ifdef CONFIG_OF
static const struct of_device_id alc5623_of_match[] = {
{ .compatible = "realtek,alc5623", },
@@ -1082,7 +1084,7 @@ static struct i2c_driver alc5623_i2c_driver = {
.name = "alc562x-codec",
.of_match_table = of_match_ptr(alc5623_of_match),
},
- .probe = alc5623_i2c_probe,
+ .probe_new = alc5623_i2c_probe,
.id_table = alc5623_i2c_table,
};
diff --git a/sound/soc/codecs/alc5632.c b/sound/soc/codecs/alc5632.c
index 6d7af3736a91..641bdfddae16 100644
--- a/sound/soc/codecs/alc5632.c
+++ b/sound/soc/codecs/alc5632.c
@@ -1092,18 +1092,24 @@ static const struct regmap_config alc5632_regmap = {
.cache_type = REGCACHE_RBTREE,
};
+static const struct i2c_device_id alc5632_i2c_table[] = {
+ {"alc5632", 0x5c},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, alc5632_i2c_table);
+
/*
* alc5632 2 wire address is determined by A1 pin
* state during powerup.
* low = 0x1a
* high = 0x1b
*/
-static int alc5632_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int alc5632_i2c_probe(struct i2c_client *client)
{
struct alc5632_priv *alc5632;
int ret, ret1, ret2;
unsigned int vid1, vid2;
+ const struct i2c_device_id *id;
alc5632 = devm_kzalloc(&client->dev,
sizeof(struct alc5632_priv), GFP_KERNEL);
@@ -1129,6 +1135,8 @@ static int alc5632_i2c_probe(struct i2c_client *client,
vid2 >>= 8;
+ id = i2c_match_id(alc5632_i2c_table, client);
+
if ((vid1 != 0x10EC) || (vid2 != id->driver_data)) {
dev_err(&client->dev,
"Device is not a ALC5632: VID1=0x%x, VID2=0x%x\n", vid1, vid2);
@@ -1161,12 +1169,6 @@ static int alc5632_i2c_probe(struct i2c_client *client,
return ret;
}
-static const struct i2c_device_id alc5632_i2c_table[] = {
- {"alc5632", 0x5c},
- {}
-};
-MODULE_DEVICE_TABLE(i2c, alc5632_i2c_table);
-
#ifdef CONFIG_OF
static const struct of_device_id alc5632_of_match[] = {
{ .compatible = "realtek,alc5632", },
@@ -1181,7 +1183,7 @@ static struct i2c_driver alc5632_i2c_driver = {
.name = "alc5632",
.of_match_table = of_match_ptr(alc5632_of_match),
},
- .probe = alc5632_i2c_probe,
+ .probe_new = alc5632_i2c_probe,
.id_table = alc5632_i2c_table,
};
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c
index 429717d4ac5a..5ef2e1279ee7 100644
--- a/sound/soc/codecs/max98088.c
+++ b/sound/soc/codecs/max98088.c
@@ -1737,11 +1737,18 @@ static const struct snd_soc_component_driver soc_component_dev_max98088 = {
.non_legacy_dai_naming = 1,
};
-static int max98088_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static const struct i2c_device_id max98088_i2c_id[] = {
+ { "max98088", MAX98088 },
+ { "max98089", MAX98089 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, max98088_i2c_id);
+
+static int max98088_i2c_probe(struct i2c_client *i2c)
{
struct max98088_priv *max98088;
int ret;
+ const struct i2c_device_id *id;
max98088 = devm_kzalloc(&i2c->dev, sizeof(struct max98088_priv),
GFP_KERNEL);
@@ -1757,6 +1764,7 @@ static int max98088_i2c_probe(struct i2c_client *i2c,
if (PTR_ERR(max98088->mclk) == -EPROBE_DEFER)
return PTR_ERR(max98088->mclk);
+ id = i2c_match_id(max98088_i2c_id, i2c);
max98088->devtype = id->driver_data;
i2c_set_clientdata(i2c, max98088);
@@ -1767,13 +1775,6 @@ static int max98088_i2c_probe(struct i2c_client *i2c,
return ret;
}
-static const struct i2c_device_id max98088_i2c_id[] = {
- { "max98088", MAX98088 },
- { "max98089", MAX98089 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, max98088_i2c_id);
-
#if defined(CONFIG_OF)
static const struct of_device_id max98088_of_match[] = {
{ .compatible = "maxim,max98088" },
@@ -1788,7 +1789,7 @@ static struct i2c_driver max98088_i2c_driver = {
.name = "max98088",
.of_match_table = of_match_ptr(max98088_of_match),
},
- .probe = max98088_i2c_probe,
+ .probe_new = max98088_i2c_probe,
.id_table = max98088_i2c_id,
};
diff --git a/sound/soc/codecs/max98090.c b/sound/soc/codecs/max98090.c
index b45ec35cd63c..4058e147413c 100644
--- a/sound/soc/codecs/max98090.c
+++ b/sound/soc/codecs/max98090.c
@@ -2529,8 +2529,14 @@ static const struct regmap_config max98090_regmap = {
.cache_type = REGCACHE_RBTREE,
};
-static int max98090_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *i2c_id)
+static const struct i2c_device_id max98090_i2c_id[] = {
+ { "max98090", MAX98090 },
+ { "max98091", MAX98091 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, max98090_i2c_id);
+
+static int max98090_i2c_probe(struct i2c_client *i2c)
{
struct max98090_priv *max98090;
const struct acpi_device_id *acpi_id;
@@ -2552,7 +2558,9 @@ static int max98090_i2c_probe(struct i2c_client *i2c,
return -EINVAL;
}
driver_data = acpi_id->driver_data;
- } else if (i2c_id) {
+ } else {
+ const struct i2c_device_id *i2c_id =
+ i2c_match_id(max98090_i2c_id, i2c);
driver_data = i2c_id->driver_data;
}
@@ -2659,13 +2667,6 @@ static const struct dev_pm_ops max98090_pm = {
SET_SYSTEM_SLEEP_PM_OPS(NULL, max98090_resume)
};
-static const struct i2c_device_id max98090_i2c_id[] = {
- { "max98090", MAX98090 },
- { "max98091", MAX98091 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, max98090_i2c_id);
-
#ifdef CONFIG_OF
static const struct of_device_id max98090_of_match[] = {
{ .compatible = "maxim,max98090", },
@@ -2690,7 +2691,7 @@ static struct i2c_driver max98090_i2c_driver = {
.of_match_table = of_match_ptr(max98090_of_match),
.acpi_match_table = ACPI_PTR(max98090_acpi_match),
},
- .probe = max98090_i2c_probe,
+ .probe_new = max98090_i2c_probe,
.shutdown = max98090_i2c_shutdown,
.remove = max98090_i2c_remove,
.id_table = max98090_i2c_id,
diff --git a/sound/soc/codecs/max98095.c b/sound/soc/codecs/max98095.c
index 4977b00ddf5f..7bca99fa61b5 100644
--- a/sound/soc/codecs/max98095.c
+++ b/sound/soc/codecs/max98095.c
@@ -2106,11 +2106,17 @@ static const struct snd_soc_component_driver soc_component_dev_max98095 = {
.non_legacy_dai_naming = 1,
};
-static int max98095_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static const struct i2c_device_id max98095_i2c_id[] = {
+ { "max98095", MAX98095 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, max98095_i2c_id);
+
+static int max98095_i2c_probe(struct i2c_client *i2c)
{
struct max98095_priv *max98095;
int ret;
+ const struct i2c_device_id *id;
max98095 = devm_kzalloc(&i2c->dev, sizeof(struct max98095_priv),
GFP_KERNEL);
@@ -2126,6 +2132,7 @@ static int max98095_i2c_probe(struct i2c_client *i2c,
return ret;
}
+ id = i2c_match_id(max98095_i2c_id, i2c);
max98095->devtype = id->driver_data;
i2c_set_clientdata(i2c, max98095);
max98095->pdata = i2c->dev.platform_data;
@@ -2136,12 +2143,6 @@ static int max98095_i2c_probe(struct i2c_client *i2c,
return ret;
}
-static const struct i2c_device_id max98095_i2c_id[] = {
- { "max98095", MAX98095 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, max98095_i2c_id);
-
#ifdef CONFIG_OF
static const struct of_device_id max98095_of_match[] = {
{ .compatible = "maxim,max98095", },
@@ -2155,7 +2156,7 @@ static struct i2c_driver max98095_i2c_driver = {
.name = "max98095",
.of_match_table = of_match_ptr(max98095_of_match),
},
- .probe = max98095_i2c_probe,
+ .probe_new = max98095_i2c_probe,
.id_table = max98095_i2c_id,
};
diff --git a/sound/soc/codecs/pcm186x-i2c.c b/sound/soc/codecs/pcm186x-i2c.c
index f8382b74391d..932c8d41c3ea 100644
--- a/sound/soc/codecs/pcm186x-i2c.c
+++ b/sound/soc/codecs/pcm186x-i2c.c
@@ -22,9 +22,18 @@ static const struct of_device_id pcm186x_of_match[] = {
};
MODULE_DEVICE_TABLE(of, pcm186x_of_match);
-static int pcm186x_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static const struct i2c_device_id pcm186x_i2c_id[] = {
+ { "pcm1862", PCM1862 },
+ { "pcm1863", PCM1863 },
+ { "pcm1864", PCM1864 },
+ { "pcm1865", PCM1865 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, pcm186x_i2c_id);
+
+static int pcm186x_i2c_probe(struct i2c_client *i2c)
{
+ const struct i2c_device_id *id = i2c_match_id(pcm186x_i2c_id, i2c);
const enum pcm186x_type type = (enum pcm186x_type)id->driver_data;
int irq = i2c->irq;
struct regmap *regmap;
@@ -36,17 +45,8 @@ static int pcm186x_i2c_probe(struct i2c_client *i2c,
return pcm186x_probe(&i2c->dev, type, irq, regmap);
}
-static const struct i2c_device_id pcm186x_i2c_id[] = {
- { "pcm1862", PCM1862 },
- { "pcm1863", PCM1863 },
- { "pcm1864", PCM1864 },
- { "pcm1865", PCM1865 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, pcm186x_i2c_id);
-
static struct i2c_driver pcm186x_i2c_driver = {
- .probe = pcm186x_i2c_probe,
+ .probe_new = pcm186x_i2c_probe,
.id_table = pcm186x_i2c_id,
.driver = {
.name = "pcm186x",
diff --git a/sound/soc/codecs/tas2562.c b/sound/soc/codecs/tas2562.c
index 10302552195e..e62a3da16aed 100644
--- a/sound/soc/codecs/tas2562.c
+++ b/sound/soc/codecs/tas2562.c
@@ -754,17 +754,27 @@ static int tas2562_parse_dt(struct tas2562_data *tas2562)
return ret;
}
-static int tas2562_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static const struct i2c_device_id tas2562_id[] = {
+ { "tas2562", TAS2562 },
+ { "tas2563", TAS2563 },
+ { "tas2564", TAS2564 },
+ { "tas2110", TAS2110 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, tas2562_id);
+
+static int tas2562_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct tas2562_data *data;
int ret;
+ const struct i2c_device_id *id;
data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
+ id = i2c_match_id(tas2562_id, client);
data->client = client;
data->dev = &client->dev;
data->model_id = id->driver_data;
@@ -792,15 +802,6 @@ static int tas2562_probe(struct i2c_client *client,
}
-static const struct i2c_device_id tas2562_id[] = {
- { "tas2562", TAS2562 },
- { "tas2563", TAS2563 },
- { "tas2564", TAS2564 },
- { "tas2110", TAS2110 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tas2562_id);
-
#ifdef CONFIG_OF
static const struct of_device_id tas2562_of_match[] = {
{ .compatible = "ti,tas2562", },
@@ -817,7 +818,7 @@ static struct i2c_driver tas2562_i2c_driver = {
.name = "tas2562",
.of_match_table = of_match_ptr(tas2562_of_match),
},
- .probe = tas2562_probe,
+ .probe_new = tas2562_probe,
.id_table = tas2562_id,
};
diff --git a/sound/soc/codecs/tas571x.c b/sound/soc/codecs/tas571x.c
index a3e682376946..dd289774efb2 100644
--- a/sound/soc/codecs/tas571x.c
+++ b/sound/soc/codecs/tas571x.c
@@ -774,9 +774,9 @@ static struct snd_soc_dai_driver tas571x_dai = {
};
static const struct of_device_id tas571x_of_match[] __maybe_unused;
+static const struct i2c_device_id tas571x_i2c_id[];
-static int tas571x_i2c_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static int tas571x_i2c_probe(struct i2c_client *client)
{
struct tas571x_private *priv;
struct device *dev = &client->dev;
@@ -791,8 +791,11 @@ static int tas571x_i2c_probe(struct i2c_client *client,
of_id = of_match_device(tas571x_of_match, dev);
if (of_id)
priv->chip = of_id->data;
- else
+ else {
+ const struct i2c_device_id *id =
+ i2c_match_id(tas571x_i2c_id, client);
priv->chip = (void *) id->driver_data;
+ }
priv->mclk = devm_clk_get(dev, "mclk");
if (IS_ERR(priv->mclk) && PTR_ERR(priv->mclk) != -ENOENT) {
@@ -914,7 +917,7 @@ static struct i2c_driver tas571x_i2c_driver = {
.name = "tas571x",
.of_match_table = of_match_ptr(tas571x_of_match),
},
- .probe = tas571x_i2c_probe,
+ .probe_new = tas571x_i2c_probe,
.remove = tas571x_i2c_remove,
.id_table = tas571x_i2c_id,
};
diff --git a/sound/soc/codecs/tas5720.c b/sound/soc/codecs/tas5720.c
index 9ff644ddb470..17034abef568 100644
--- a/sound/soc/codecs/tas5720.c
+++ b/sound/soc/codecs/tas5720.c
@@ -633,12 +633,19 @@ static struct snd_soc_dai_driver tas5720_dai[] = {
},
};
-static int tas5720_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
+static const struct i2c_device_id tas5720_id[] = {
+ { "tas5720", TAS5720 },
+ { "tas5722", TAS5722 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, tas5720_id);
+
+static int tas5720_probe(struct i2c_client *client)
{
struct device *dev = &client->dev;
struct tas5720_data *data;
const struct regmap_config *regmap_config;
+ const struct i2c_device_id *id;
int ret;
int i;
@@ -646,6 +653,7 @@ static int tas5720_probe(struct i2c_client *client,
if (!data)
return -ENOMEM;
+ id = i2c_match_id(tas5720_id, client);
data->tas5720_client = client;
data->devtype = id->driver_data;
@@ -704,13 +712,6 @@ static int tas5720_probe(struct i2c_client *client,
return 0;
}
-static const struct i2c_device_id tas5720_id[] = {
- { "tas5720", TAS5720 },
- { "tas5722", TAS5722 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, tas5720_id);
-
#if IS_ENABLED(CONFIG_OF)
static const struct of_device_id tas5720_of_match[] = {
{ .compatible = "ti,tas5720", },
@@ -725,7 +726,7 @@ static struct i2c_driver tas5720_i2c_driver = {
.name = "tas5720",
.of_match_table = of_match_ptr(tas5720_of_match),
},
- .probe = tas5720_probe,
+ .probe_new = tas5720_probe,
.id_table = tas5720_id,
};
diff --git a/sound/soc/codecs/tlv320adc3xxx.c b/sound/soc/codecs/tlv320adc3xxx.c
index ae18982ac310..a5e9f80cfa32 100644
--- a/sound/soc/codecs/tlv320adc3xxx.c
+++ b/sound/soc/codecs/tlv320adc3xxx.c
@@ -1337,11 +1337,18 @@ static const struct snd_soc_component_driver soc_component_dev_adc3xxx = {
.num_dapm_routes = ARRAY_SIZE(adc3xxx_intercon),
};
-static int adc3xxx_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static const struct i2c_device_id adc3xxx_i2c_id[] = {
+ { "tlv320adc3001", ADC3001 },
+ { "tlv320adc3101", ADC3101 },
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, adc3xxx_i2c_id);
+
+static int adc3xxx_i2c_probe(struct i2c_client *i2c)
{
struct device *dev = &i2c->dev;
struct adc3xxx *adc3xxx = NULL;
+ const struct i2c_device_id *id;
int ret;
adc3xxx = devm_kzalloc(dev, sizeof(struct adc3xxx), GFP_KERNEL);
@@ -1394,6 +1401,7 @@ static int adc3xxx_i2c_probe(struct i2c_client *i2c,
i2c_set_clientdata(i2c, adc3xxx);
+ id = i2c_match_id(adc3xxx_i2c_id, i2c);
adc3xxx->type = id->driver_data;
/* Reset codec chip */
@@ -1436,19 +1444,12 @@ static const struct of_device_id tlv320adc3xxx_of_match[] = {
};
MODULE_DEVICE_TABLE(of, tlv320adc3xxx_of_match);
-static const struct i2c_device_id adc3xxx_i2c_id[] = {
- { "tlv320adc3001", ADC3001 },
- { "tlv320adc3101", ADC3101 },
- {}
-};
-MODULE_DEVICE_TABLE(i2c, adc3xxx_i2c_id);
-
static struct i2c_driver adc3xxx_i2c_driver = {
.driver = {
.name = "tlv320adc3xxx-codec",
.of_match_table = tlv320adc3xxx_of_match,
},
- .probe = adc3xxx_i2c_probe,
+ .probe_new = adc3xxx_i2c_probe,
.remove = adc3xxx_i2c_remove,
.id_table = adc3xxx_i2c_id,
};
diff --git a/sound/soc/codecs/tlv320aic31xx.c b/sound/soc/codecs/tlv320aic31xx.c
index 8331dc26bcd2..b2e59581c17a 100644
--- a/sound/soc/codecs/tlv320aic31xx.c
+++ b/sound/soc/codecs/tlv320aic31xx.c
@@ -1628,11 +1628,24 @@ static void aic31xx_configure_ocmv(struct aic31xx_priv *priv)
}
}
-static int aic31xx_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static const struct i2c_device_id aic31xx_i2c_id[] = {
+ { "tlv320aic310x", AIC3100 },
+ { "tlv320aic311x", AIC3110 },
+ { "tlv320aic3100", AIC3100 },
+ { "tlv320aic3110", AIC3110 },
+ { "tlv320aic3120", AIC3120 },
+ { "tlv320aic3111", AIC3111 },
+ { "tlv320dac3100", DAC3100 },
+ { "tlv320dac3101", DAC3101 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id);
+
+static int aic31xx_i2c_probe(struct i2c_client *i2c)
{
struct aic31xx_priv *aic31xx;
unsigned int micbias_value = MICBIAS_2_0V;
+ const struct i2c_device_id *id = i2c_match_id(aic31xx_i2c_id, i2c);
int i, ret;
dev_dbg(&i2c->dev, "## %s: %s codec_type = %d\n", __func__,
@@ -1729,26 +1742,13 @@ static int aic31xx_i2c_probe(struct i2c_client *i2c,
ARRAY_SIZE(aic31xx_dai_driver));
}
-static const struct i2c_device_id aic31xx_i2c_id[] = {
- { "tlv320aic310x", AIC3100 },
- { "tlv320aic311x", AIC3110 },
- { "tlv320aic3100", AIC3100 },
- { "tlv320aic3110", AIC3110 },
- { "tlv320aic3120", AIC3120 },
- { "tlv320aic3111", AIC3111 },
- { "tlv320dac3100", DAC3100 },
- { "tlv320dac3101", DAC3101 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, aic31xx_i2c_id);
-
static struct i2c_driver aic31xx_i2c_driver = {
.driver = {
.name = "tlv320aic31xx-codec",
.of_match_table = of_match_ptr(tlv320aic31xx_of_match),
.acpi_match_table = ACPI_PTR(aic31xx_acpi_match),
},
- .probe = aic31xx_i2c_probe,
+ .probe_new = aic31xx_i2c_probe,
.id_table = aic31xx_i2c_id,
};
module_i2c_driver(aic31xx_i2c_driver);
diff --git a/sound/soc/codecs/tlv320aic32x4-i2c.c b/sound/soc/codecs/tlv320aic32x4-i2c.c
index ed70e3d9baf2..0645239901b1 100644
--- a/sound/soc/codecs/tlv320aic32x4-i2c.c
+++ b/sound/soc/codecs/tlv320aic32x4-i2c.c
@@ -17,9 +17,9 @@
#include "tlv320aic32x4.h"
static const struct of_device_id aic32x4_of_id[];
+static const struct i2c_device_id aic32x4_i2c_id[];
-static int aic32x4_i2c_probe(struct i2c_client *i2c,
- const struct i2c_device_id *id)
+static int aic32x4_i2c_probe(struct i2c_client *i2c)
{
struct regmap *regmap;
struct regmap_config config;
@@ -35,7 +35,10 @@ static int aic32x4_i2c_probe(struct i2c_client *i2c,
oid = of_match_node(aic32x4_of_id, i2c->dev.of_node);
dev_set_drvdata(&i2c->dev, (void *)oid->data);
- } else if (id) {
+ } else {
+ const struct i2c_device_id *id;
+
+ id = i2c_match_id(aic32x4_i2c_id, i2c);
dev_set_drvdata(&i2c->dev, (void *)id->driver_data);
}
@@ -70,7 +73,7 @@ static struct i2c_driver aic32x4_i2c_driver = {
.name = "tlv320aic32x4",
.of_match_table = aic32x4_of_id,
},
- .probe = aic32x4_i2c_probe,
+ .probe_new = aic32x4_i2c_probe,
.remove = aic32x4_i2c_remove,
.id_table = aic32x4_i2c_id,
};
diff --git a/sound/soc/codecs/tlv320aic3x-i2c.c b/sound/soc/codecs/tlv320aic3x-i2c.c
index 2f272bc3f5da..7bd9ce08bb7b 100644
--- a/sound/soc/codecs/tlv320aic3x-i2c.c
+++ b/sound/soc/codecs/tlv320aic3x-i2c.c
@@ -17,10 +17,21 @@
#include "tlv320aic3x.h"
-static int aic3x_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+static const struct i2c_device_id aic3x_i2c_id[] = {
+ { "tlv320aic3x", AIC3X_MODEL_3X },
+ { "tlv320aic33", AIC3X_MODEL_33 },
+ { "tlv320aic3007", AIC3X_MODEL_3007 },
+ { "tlv320aic3104", AIC3X_MODEL_3104 },
+ { "tlv320aic3106", AIC3X_MODEL_3106 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
+
+static int aic3x_i2c_probe(struct i2c_client *i2c)
{
struct regmap *regmap;
struct regmap_config config;
+ const struct i2c_device_id *id = i2c_match_id(aic3x_i2c_id, i2c);
config = aic3x_regmap;
config.reg_bits = 8;
@@ -37,16 +48,6 @@ static int aic3x_i2c_remove(struct i2c_client *i2c)
return 0;
}
-static const struct i2c_device_id aic3x_i2c_id[] = {
- { "tlv320aic3x", AIC3X_MODEL_3X },
- { "tlv320aic33", AIC3X_MODEL_33 },
- { "tlv320aic3007", AIC3X_MODEL_3007 },
- { "tlv320aic3104", AIC3X_MODEL_3104 },
- { "tlv320aic3106", AIC3X_MODEL_3106 },
- { }
-};
-MODULE_DEVICE_TABLE(i2c, aic3x_i2c_id);
-
static const struct of_device_id aic3x_of_id[] = {
{ .compatible = "ti,tlv320aic3x", },
{ .compatible = "ti,tlv320aic33" },
@@ -62,7 +63,7 @@ static struct i2c_driver aic3x_i2c_driver = {
.name = "tlv320aic3x",
.of_match_table = aic3x_of_id,
},
- .probe = aic3x_i2c_probe,
+ .probe_new = aic3x_i2c_probe,
.remove = aic3x_i2c_remove,
.id_table = aic3x_i2c_id,
};
diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index ad4e6747b839..20a9f8e924b3 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -1211,11 +1211,9 @@ static int fsl_asrc_probe(struct platform_device *pdev)
goto err_pm_disable;
}
- ret = pm_runtime_get_sync(&pdev->dev);
- if (ret < 0) {
- pm_runtime_put_noidle(&pdev->dev);
+ ret = pm_runtime_resume_and_get(&pdev->dev);
+ if (ret < 0)
goto err_pm_get_sync;
- }
ret = fsl_asrc_init(asrc);
if (ret) {
diff --git a/sound/soc/fsl/imx-hdmi.c b/sound/soc/fsl/imx-hdmi.c
index e10136afa741..2ae1a889c68d 100644
--- a/sound/soc/fsl/imx-hdmi.c
+++ b/sound/soc/fsl/imx-hdmi.c
@@ -206,8 +206,7 @@ static int imx_hdmi_probe(struct platform_device *pdev)
}
fail:
- if (cpu_np)
- of_node_put(cpu_np);
+ of_node_put(cpu_np);
return ret;
}
diff --git a/sound/soc/img/img-i2s-in.c b/sound/soc/img/img-i2s-in.c
index f1f36f15a503..09d23b11621c 100644
--- a/sound/soc/img/img-i2s-in.c
+++ b/sound/soc/img/img-i2s-in.c
@@ -342,11 +342,9 @@ static int img_i2s_in_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
chan_control_mask = IMG_I2S_IN_CH_CTL_CLK_TRANS_MASK;
- ret = pm_runtime_get_sync(i2s->dev);
- if (ret < 0) {
- pm_runtime_put_noidle(i2s->dev);
+ ret = pm_runtime_resume_and_get(i2s->dev);
+ if (ret < 0)
return ret;
- }
for (i = 0; i < i2s->active_channels; i++)
img_i2s_in_ch_disable(i2s, i);
diff --git a/sound/soc/img/img-parallel-out.c b/sound/soc/img/img-parallel-out.c
index 800f247283cd..cd6a6a825741 100644
--- a/sound/soc/img/img-parallel-out.c
+++ b/sound/soc/img/img-parallel-out.c
@@ -162,11 +162,9 @@ static int img_prl_out_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
return -EINVAL;
}
- ret = pm_runtime_get_sync(prl->dev);
- if (ret < 0) {
- pm_runtime_put_noidle(prl->dev);
+ ret = pm_runtime_resume_and_get(prl->dev);
+ if (ret < 0)
return ret;
- }
reg = img_prl_out_readl(prl, IMG_PRL_OUT_CTL);
reg = (reg & ~IMG_PRL_OUT_CTL_EDGE_MASK) | control_set;
diff --git a/sound/soc/img/img-spdif-in.c b/sound/soc/img/img-spdif-in.c
index 95914d0612fe..a79d1ccaeec0 100644
--- a/sound/soc/img/img-spdif-in.c
+++ b/sound/soc/img/img-spdif-in.c
@@ -749,11 +749,9 @@ static int img_spdif_in_probe(struct platform_device *pdev)
if (ret)
goto err_pm_disable;
}
- ret = pm_runtime_get_sync(&pdev->dev);
- if (ret < 0) {
- pm_runtime_put_noidle(&pdev->dev);
+ ret = pm_runtime_resume_and_get(&pdev->dev);
+ if (ret < 0)
goto err_suspend;
- }
rst = devm_reset_control_get_exclusive(&pdev->dev, "rst");
if (IS_ERR(rst)) {
diff --git a/sound/soc/img/img-spdif-out.c b/sound/soc/img/img-spdif-out.c
index c3189d9ff72f..f7062eba2611 100644
--- a/sound/soc/img/img-spdif-out.c
+++ b/sound/soc/img/img-spdif-out.c
@@ -362,11 +362,9 @@ static int img_spdif_out_probe(struct platform_device *pdev)
if (ret)
goto err_pm_disable;
}
- ret = pm_runtime_get_sync(&pdev->dev);
- if (ret < 0) {
- pm_runtime_put_noidle(&pdev->dev);
+ ret = pm_runtime_resume_and_get(&pdev->dev);
+ if (ret < 0)
goto err_suspend;
- }
img_spdif_out_writel(spdif, IMG_SPDIF_OUT_CTL_FS_MASK,
IMG_SPDIF_OUT_CTL);
diff --git a/sound/soc/intel/Kconfig b/sound/soc/intel/Kconfig
index c364ddf22267..be42c4eff165 100644
--- a/sound/soc/intel/Kconfig
+++ b/sound/soc/intel/Kconfig
@@ -211,13 +211,14 @@ config SND_SOC_INTEL_KEEMBAY
config SND_SOC_INTEL_AVS
tristate "Intel AVS driver"
- depends on PCI && ACPI
+ depends on (X86 && ACPI) || COMPILE_TEST
+ depends on PCI
depends on COMMON_CLK
select SND_SOC_ACPI
select SND_SOC_TOPOLOGY
select SND_HDA_EXT_CORE
select SND_HDA_DSP_LOADER
- select SND_INTEL_NHLT
+ select SND_INTEL_DSP_CONFIG
help
Enable support for Intel(R) cAVS 1.5 platforms with DSP
capabilities. This includes Skylake, Kabylake, Amberlake and
diff --git a/sound/soc/qcom/sc7280.c b/sound/soc/qcom/sc7280.c
index 4ef4034ba6ee..dfcb7ed44331 100644
--- a/sound/soc/qcom/sc7280.c
+++ b/sound/soc/qcom/sc7280.c
@@ -21,7 +21,7 @@
#include "lpass.h"
#define DEFAULT_MCLK_RATE 19200000
-#define RT5682_PLL1_FREQ (48000 * 512)
+#define RT5682_PLL_FREQ (48000 * 512)
struct sc7280_snd_data {
struct snd_soc_card card;
@@ -137,15 +137,15 @@ static int sc7280_rt5682_init(struct snd_soc_pcm_runtime *rtd)
SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_I2S);
- ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL1, RT5682S_PLL_S_BCLK1,
- 1536000, RT5682_PLL1_FREQ);
+ ret = snd_soc_dai_set_pll(codec_dai, RT5682S_PLL2, RT5682S_PLL_S_MCLK,
+ DEFAULT_MCLK_RATE, RT5682_PLL_FREQ);
if (ret) {
dev_err(rtd->dev, "can't set codec pll: %d\n", ret);
return ret;
}
- ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL1,
- RT5682_PLL1_FREQ,
+ ret = snd_soc_dai_set_sysclk(codec_dai, RT5682S_SCLK_S_PLL2,
+ RT5682_PLL_FREQ,
SND_SOC_CLOCK_IN);
if (ret) {
diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig
index ae46f187cc2a..97916e3ca9dd 100644
--- a/sound/soc/sh/Kconfig
+++ b/sound/soc/sh/Kconfig
@@ -47,7 +47,7 @@ config SND_SOC_RCAR
config SND_SOC_RZ
tristate "RZ/G2L series SSIF-2 support"
- depends on ARCH_R9A07G044 || COMPILE_TEST
+ depends on ARCH_RZG2L || COMPILE_TEST
help
This option enables RZ/G2L SSIF-2 sound support.
diff --git a/sound/soc/sof/amd/renoir.c b/sound/soc/sof/amd/renoir.c
index 73f639fa16a4..275f266c5e4d 100644
--- a/sound/soc/sof/amd/renoir.c
+++ b/sound/soc/sof/amd/renoir.c
@@ -152,7 +152,6 @@ struct snd_sof_dsp_ops sof_renoir_ops = {
.ipc_msg_data = acp_sof_ipc_msg_data,
.get_mailbox_offset = acp_sof_ipc_get_mailbox_offset,
.irq_thread = acp_sof_ipc_irq_thread,
- .fw_ready = sof_fw_ready,
/* DAI drivers */
.drv = renoir_sof_dai,
diff --git a/sound/soc/sof/core.c b/sound/soc/sof/core.c
index 04b0cf3c822f..2d12e8bab769 100644
--- a/sound/soc/sof/core.c
+++ b/sound/soc/sof/core.c
@@ -374,7 +374,7 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)
if (!sof_ops(sdev) || !sof_ops(sdev)->probe || !sof_ops(sdev)->run ||
!sof_ops(sdev)->block_read || !sof_ops(sdev)->block_write ||
!sof_ops(sdev)->send_msg || !sof_ops(sdev)->load_firmware ||
- !sof_ops(sdev)->ipc_msg_data || !sof_ops(sdev)->fw_ready) {
+ !sof_ops(sdev)->ipc_msg_data) {
dev_err(dev, "error: missing mandatory ops\n");
return -EINVAL;
}
diff --git a/sound/soc/sof/imx/imx8.c b/sound/soc/sof/imx/imx8.c
index d3a60c8e42cc..ba2fbed93f1d 100644
--- a/sound/soc/sof/imx/imx8.c
+++ b/sound/soc/sof/imx/imx8.c
@@ -504,7 +504,6 @@ static struct snd_sof_dsp_ops sof_imx8_ops = {
/* ipc */
.send_msg = imx8_send_msg,
- .fw_ready = sof_fw_ready,
.get_mailbox_offset = imx8_get_mailbox_offset,
.get_window_offset = imx8_get_window_offset,
@@ -567,7 +566,6 @@ static struct snd_sof_dsp_ops sof_imx8x_ops = {
/* ipc */
.send_msg = imx8_send_msg,
- .fw_ready = sof_fw_ready,
.get_mailbox_offset = imx8_get_mailbox_offset,
.get_window_offset = imx8_get_window_offset,
diff --git a/sound/soc/sof/imx/imx8m.c b/sound/soc/sof/imx/imx8m.c
index 8e9ae08dc7b0..1e95f91a7b22 100644
--- a/sound/soc/sof/imx/imx8m.c
+++ b/sound/soc/sof/imx/imx8m.c
@@ -430,7 +430,6 @@ static struct snd_sof_dsp_ops sof_imx8m_ops = {
/* ipc */
.send_msg = imx8m_send_msg,
- .fw_ready = sof_fw_ready,
.get_mailbox_offset = imx8m_get_mailbox_offset,
.get_window_offset = imx8m_get_window_offset,
diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c
index 73a20172bf77..c0a1d4ae8c68 100644
--- a/sound/soc/sof/intel/bdw.c
+++ b/sound/soc/sof/intel/bdw.c
@@ -591,7 +591,6 @@ static struct snd_sof_dsp_ops sof_bdw_ops = {
/* ipc */
.send_msg = bdw_send_msg,
- .fw_ready = sof_fw_ready,
.get_mailbox_offset = bdw_get_mailbox_offset,
.get_window_offset = bdw_get_window_offset,
diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c
index 08376e8fdc61..0fd5edb1bdbc 100644
--- a/sound/soc/sof/intel/byt.c
+++ b/sound/soc/sof/intel/byt.c
@@ -245,7 +245,6 @@ static struct snd_sof_dsp_ops sof_byt_ops = {
/* ipc */
.send_msg = atom_send_msg,
- .fw_ready = sof_fw_ready,
.get_mailbox_offset = atom_get_mailbox_offset,
.get_window_offset = atom_get_window_offset,
@@ -328,7 +327,6 @@ static struct snd_sof_dsp_ops sof_cht_ops = {
/* ipc */
.send_msg = atom_send_msg,
- .fw_ready = sof_fw_ready,
.get_mailbox_offset = atom_get_mailbox_offset,
.get_window_offset = atom_get_window_offset,
diff --git a/sound/soc/sof/intel/hda-common-ops.c b/sound/soc/sof/intel/hda-common-ops.c
index 257eace4a563..b2326396c870 100644
--- a/sound/soc/sof/intel/hda-common-ops.c
+++ b/sound/soc/sof/intel/hda-common-ops.c
@@ -34,7 +34,6 @@ struct snd_sof_dsp_ops sof_hda_common_ops = {
.mailbox_write = sof_mailbox_write,
/* ipc */
- .fw_ready = sof_fw_ready,
.get_mailbox_offset = hda_dsp_ipc_get_mailbox_offset,
.get_window_offset = hda_dsp_ipc_get_window_offset,
diff --git a/sound/soc/sof/intel/pci-tng.c b/sound/soc/sof/intel/pci-tng.c
index 14f11528f069..f1aae9667834 100644
--- a/sound/soc/sof/intel/pci-tng.c
+++ b/sound/soc/sof/intel/pci-tng.c
@@ -164,7 +164,6 @@ struct snd_sof_dsp_ops sof_tng_ops = {
/* ipc */
.send_msg = atom_send_msg,
- .fw_ready = sof_fw_ready,
.get_mailbox_offset = atom_get_mailbox_offset,
.get_window_offset = atom_get_window_offset,
diff --git a/sound/soc/sof/ipc.c b/sound/soc/sof/ipc.c
index 6f8ac3fb195f..48ea58dbc998 100644
--- a/sound/soc/sof/ipc.c
+++ b/sound/soc/sof/ipc.c
@@ -188,21 +188,6 @@ int snd_sof_ipc_valid(struct snd_sof_dev *sdev)
}
EXPORT_SYMBOL(snd_sof_ipc_valid);
-int sof_ipc_init_msg_memory(struct snd_sof_dev *sdev)
-{
- struct snd_sof_ipc_msg *msg;
-
- msg = &sdev->ipc->msg;
-
- msg->reply_data = devm_kzalloc(sdev->dev, SOF_IPC_MSG_MAX_SIZE, GFP_KERNEL);
- if (!msg->reply_data)
- return -ENOMEM;
-
- sdev->ipc->max_payload_size = SOF_IPC_MSG_MAX_SIZE;
-
- return 0;
-}
-
struct snd_sof_ipc *snd_sof_ipc_init(struct snd_sof_dev *sdev)
{
struct snd_sof_ipc *ipc;
diff --git a/sound/soc/sof/ipc3.c b/sound/soc/sof/ipc3.c
index 8480a1b5733a..7d28bfa3d231 100644
--- a/sound/soc/sof/ipc3.c
+++ b/sound/soc/sof/ipc3.c
@@ -475,6 +475,310 @@ static int sof_ipc3_set_get_data(struct snd_sof_dev *sdev, void *data, size_t da
return ret;
}
+static int sof_ipc3_get_ext_windows(struct snd_sof_dev *sdev,
+ const struct sof_ipc_ext_data_hdr *ext_hdr)
+{
+ const struct sof_ipc_window *w =
+ container_of(ext_hdr, struct sof_ipc_window, ext_hdr);
+
+ if (w->num_windows == 0 || w->num_windows > SOF_IPC_MAX_ELEMS)
+ return -EINVAL;
+
+ if (sdev->info_window) {
+ if (memcmp(sdev->info_window, w, ext_hdr->hdr.size)) {
+ dev_err(sdev->dev, "mismatch between window descriptor from extended manifest and mailbox");
+ return -EINVAL;
+ }
+ return 0;
+ }
+
+ /* keep a local copy of the data */
+ sdev->info_window = devm_kmemdup(sdev->dev, w, ext_hdr->hdr.size, GFP_KERNEL);
+ if (!sdev->info_window)
+ return -ENOMEM;
+
+ return 0;
+}
+
+static int sof_ipc3_get_cc_info(struct snd_sof_dev *sdev,
+ const struct sof_ipc_ext_data_hdr *ext_hdr)
+{
+ int ret;
+
+ const struct sof_ipc_cc_version *cc =
+ container_of(ext_hdr, struct sof_ipc_cc_version, ext_hdr);
+
+ if (sdev->cc_version) {
+ if (memcmp(sdev->cc_version, cc, cc->ext_hdr.hdr.size)) {
+ dev_err(sdev->dev,
+ "Receive diverged cc_version descriptions");
+ return -EINVAL;
+ }
+ return 0;
+ }
+
+ dev_dbg(sdev->dev,
+ "Firmware info: used compiler %s %d:%d:%d%s used optimization flags %s\n",
+ cc->name, cc->major, cc->minor, cc->micro, cc->desc, cc->optim);
+
+ /* create read-only cc_version debugfs to store compiler version info */
+ /* use local copy of the cc_version to prevent data corruption */
+ if (sdev->first_boot) {
+ sdev->cc_version = devm_kmalloc(sdev->dev, cc->ext_hdr.hdr.size,
+ GFP_KERNEL);
+
+ if (!sdev->cc_version)
+ return -ENOMEM;
+
+ memcpy(sdev->cc_version, cc, cc->ext_hdr.hdr.size);
+ ret = snd_sof_debugfs_buf_item(sdev, sdev->cc_version,
+ cc->ext_hdr.hdr.size,
+ "cc_version", 0444);
+
+ /* errors are only due to memory allocation, not debugfs */
+ if (ret < 0) {
+ dev_err(sdev->dev, "snd_sof_debugfs_buf_item failed\n");
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+/* parse the extended FW boot data structures from FW boot message */
+static int ipc3_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 offset)
+{
+ struct sof_ipc_ext_data_hdr *ext_hdr;
+ void *ext_data;
+ int ret = 0;
+
+ ext_data = kzalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!ext_data)
+ return -ENOMEM;
+
+ /* get first header */
+ snd_sof_dsp_block_read(sdev, SOF_FW_BLK_TYPE_SRAM, offset, ext_data,
+ sizeof(*ext_hdr));
+ ext_hdr = ext_data;
+
+ while (ext_hdr->hdr.cmd == SOF_IPC_FW_READY) {
+ /* read in ext structure */
+ snd_sof_dsp_block_read(sdev, SOF_FW_BLK_TYPE_SRAM,
+ offset + sizeof(*ext_hdr),
+ (void *)((u8 *)ext_data + sizeof(*ext_hdr)),
+ ext_hdr->hdr.size - sizeof(*ext_hdr));
+
+ dev_dbg(sdev->dev, "found ext header type %d size 0x%x\n",
+ ext_hdr->type, ext_hdr->hdr.size);
+
+ /* process structure data */
+ switch (ext_hdr->type) {
+ case SOF_IPC_EXT_WINDOW:
+ ret = sof_ipc3_get_ext_windows(sdev, ext_hdr);
+ break;
+ case SOF_IPC_EXT_CC_INFO:
+ ret = sof_ipc3_get_cc_info(sdev, ext_hdr);
+ break;
+ case SOF_IPC_EXT_UNUSED:
+ case SOF_IPC_EXT_PROBE_INFO:
+ case SOF_IPC_EXT_USER_ABI_INFO:
+ /* They are supported but we don't do anything here */
+ break;
+ default:
+ dev_info(sdev->dev, "unknown ext header type %d size 0x%x\n",
+ ext_hdr->type, ext_hdr->hdr.size);
+ ret = 0;
+ break;
+ }
+
+ if (ret < 0) {
+ dev_err(sdev->dev, "Failed to parse ext data type %d\n",
+ ext_hdr->type);
+ break;
+ }
+
+ /* move to next header */
+ offset += ext_hdr->hdr.size;
+ snd_sof_dsp_block_read(sdev, SOF_FW_BLK_TYPE_SRAM, offset, ext_data,
+ sizeof(*ext_hdr));
+ ext_hdr = ext_data;
+ }
+
+ kfree(ext_data);
+ return ret;
+}
+
+static void ipc3_get_windows(struct snd_sof_dev *sdev)
+{
+ struct sof_ipc_window_elem *elem;
+ u32 outbox_offset = 0;
+ u32 stream_offset = 0;
+ u32 inbox_offset = 0;
+ u32 outbox_size = 0;
+ u32 stream_size = 0;
+ u32 inbox_size = 0;
+ u32 debug_size = 0;
+ u32 debug_offset = 0;
+ int window_offset;
+ int i;
+
+ if (!sdev->info_window) {
+ dev_err(sdev->dev, "%s: No window info present\n", __func__);
+ return;
+ }
+
+ for (i = 0; i < sdev->info_window->num_windows; i++) {
+ elem = &sdev->info_window->window[i];
+
+ window_offset = snd_sof_dsp_get_window_offset(sdev, elem->id);
+ if (window_offset < 0) {
+ dev_warn(sdev->dev, "No offset for window %d\n", elem->id);
+ continue;
+ }
+
+ switch (elem->type) {
+ case SOF_IPC_REGION_UPBOX:
+ inbox_offset = window_offset + elem->offset;
+ inbox_size = elem->size;
+ snd_sof_debugfs_add_region_item(sdev, SOF_FW_BLK_TYPE_SRAM,
+ inbox_offset,
+ elem->size, "inbox",
+ SOF_DEBUGFS_ACCESS_D0_ONLY);
+ break;
+ case SOF_IPC_REGION_DOWNBOX:
+ outbox_offset = window_offset + elem->offset;
+ outbox_size = elem->size;
+ snd_sof_debugfs_add_region_item(sdev, SOF_FW_BLK_TYPE_SRAM,
+ outbox_offset,
+ elem->size, "outbox",
+ SOF_DEBUGFS_ACCESS_D0_ONLY);
+ break;
+ case SOF_IPC_REGION_TRACE:
+ snd_sof_debugfs_add_region_item(sdev, SOF_FW_BLK_TYPE_SRAM,
+ window_offset + elem->offset,
+ elem->size, "etrace",
+ SOF_DEBUGFS_ACCESS_D0_ONLY);
+ break;
+ case SOF_IPC_REGION_DEBUG:
+ debug_offset = window_offset + elem->offset;
+ debug_size = elem->size;
+ snd_sof_debugfs_add_region_item(sdev, SOF_FW_BLK_TYPE_SRAM,
+ window_offset + elem->offset,
+ elem->size, "debug",
+ SOF_DEBUGFS_ACCESS_D0_ONLY);
+ break;
+ case SOF_IPC_REGION_STREAM:
+ stream_offset = window_offset + elem->offset;
+ stream_size = elem->size;
+ snd_sof_debugfs_add_region_item(sdev, SOF_FW_BLK_TYPE_SRAM,
+ stream_offset,
+ elem->size, "stream",
+ SOF_DEBUGFS_ACCESS_D0_ONLY);
+ break;
+ case SOF_IPC_REGION_REGS:
+ snd_sof_debugfs_add_region_item(sdev, SOF_FW_BLK_TYPE_SRAM,
+ window_offset + elem->offset,
+ elem->size, "regs",
+ SOF_DEBUGFS_ACCESS_D0_ONLY);
+ break;
+ case SOF_IPC_REGION_EXCEPTION:
+ sdev->dsp_oops_offset = window_offset + elem->offset;
+ snd_sof_debugfs_add_region_item(sdev, SOF_FW_BLK_TYPE_SRAM,
+ window_offset + elem->offset,
+ elem->size, "exception",
+ SOF_DEBUGFS_ACCESS_D0_ONLY);
+ break;
+ default:
+ dev_err(sdev->dev, "%s: Illegal window info: %u\n",
+ __func__, elem->type);
+ return;
+ }
+ }
+
+ if (outbox_size == 0 || inbox_size == 0) {
+ dev_err(sdev->dev, "%s: Illegal mailbox window\n", __func__);
+ return;
+ }
+
+ sdev->dsp_box.offset = inbox_offset;
+ sdev->dsp_box.size = inbox_size;
+
+ sdev->host_box.offset = outbox_offset;
+ sdev->host_box.size = outbox_size;
+
+ sdev->stream_box.offset = stream_offset;
+ sdev->stream_box.size = stream_size;
+
+ sdev->debug_box.offset = debug_offset;
+ sdev->debug_box.size = debug_size;
+
+ dev_dbg(sdev->dev, " mailbox upstream 0x%x - size 0x%x\n",
+ inbox_offset, inbox_size);
+ dev_dbg(sdev->dev, " mailbox downstream 0x%x - size 0x%x\n",
+ outbox_offset, outbox_size);
+ dev_dbg(sdev->dev, " stream region 0x%x - size 0x%x\n",
+ stream_offset, stream_size);
+ dev_dbg(sdev->dev, " debug region 0x%x - size 0x%x\n",
+ debug_offset, debug_size);
+}
+
+static int ipc3_init_reply_data_buffer(struct snd_sof_dev *sdev)
+{
+ struct snd_sof_ipc_msg *msg = &sdev->ipc->msg;
+
+ msg->reply_data = devm_kzalloc(sdev->dev, SOF_IPC_MSG_MAX_SIZE, GFP_KERNEL);
+ if (!msg->reply_data)
+ return -ENOMEM;
+
+ sdev->ipc->max_payload_size = SOF_IPC_MSG_MAX_SIZE;
+
+ return 0;
+}
+
+static int ipc3_fw_ready(struct snd_sof_dev *sdev, u32 cmd)
+{
+ struct sof_ipc_fw_ready *fw_ready = &sdev->fw_ready;
+ int offset;
+ int ret;
+
+ /* mailbox must be on 4k boundary */
+ offset = snd_sof_dsp_get_mailbox_offset(sdev);
+ if (offset < 0) {
+ dev_err(sdev->dev, "%s: no mailbox offset\n", __func__);
+ return offset;
+ }
+
+ dev_dbg(sdev->dev, "DSP is ready 0x%8.8x offset 0x%x\n", cmd, offset);
+
+ /* no need to re-check version/ABI for subsequent boots */
+ if (!sdev->first_boot)
+ return 0;
+
+ /*
+ * copy data from the DSP FW ready offset
+ * Subsequent error handling is not needed for BLK_TYPE_SRAM
+ */
+ ret = snd_sof_dsp_block_read(sdev, SOF_FW_BLK_TYPE_SRAM, offset, fw_ready,
+ sizeof(*fw_ready));
+ if (ret) {
+ dev_err(sdev->dev,
+ "Unable to read fw_ready, read from TYPE_SRAM failed\n");
+ return ret;
+ }
+
+ /* make sure ABI version is compatible */
+ ret = snd_sof_ipc_valid(sdev);
+ if (ret < 0)
+ return ret;
+
+ /* now check for extended data */
+ ipc3_fw_parse_ext_data(sdev, offset + sizeof(struct sof_ipc_fw_ready));
+
+ ipc3_get_windows(sdev);
+
+ return ipc3_init_reply_data_buffer(sdev);
+}
+
/* IPC stream position. */
static void ipc3_period_elapsed(struct snd_sof_dev *sdev, u32 msg_id)
{
@@ -633,7 +937,7 @@ static void sof_ipc3_rx_msg(struct snd_sof_dev *sdev)
case SOF_IPC_FW_READY:
/* check for FW boot completion */
if (sdev->fw_state == SOF_FW_BOOT_IN_PROGRESS) {
- err = sof_ops(sdev)->fw_ready(sdev, cmd);
+ err = ipc3_fw_ready(sdev, cmd);
if (err < 0)
sof_set_fw_state(sdev, SOF_FW_BOOT_READY_FAILED);
else
diff --git a/sound/soc/sof/loader.c b/sound/soc/sof/loader.c
index 697f03565a70..b0d192749734 100644
--- a/sound/soc/sof/loader.c
+++ b/sound/soc/sof/loader.c
@@ -86,69 +86,6 @@ static int get_cc_info(struct snd_sof_dev *sdev,
return 0;
}
-/* parse the extended FW boot data structures from FW boot message */
-static int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 offset)
-{
- struct sof_ipc_ext_data_hdr *ext_hdr;
- void *ext_data;
- int ret = 0;
-
- ext_data = kzalloc(PAGE_SIZE, GFP_KERNEL);
- if (!ext_data)
- return -ENOMEM;
-
- /* get first header */
- snd_sof_dsp_block_read(sdev, SOF_FW_BLK_TYPE_SRAM, offset, ext_data,
- sizeof(*ext_hdr));
- ext_hdr = ext_data;
-
- while (ext_hdr->hdr.cmd == SOF_IPC_FW_READY) {
- /* read in ext structure */
- snd_sof_dsp_block_read(sdev, SOF_FW_BLK_TYPE_SRAM,
- offset + sizeof(*ext_hdr),
- (void *)((u8 *)ext_data + sizeof(*ext_hdr)),
- ext_hdr->hdr.size - sizeof(*ext_hdr));
-
- dev_dbg(sdev->dev, "found ext header type %d size 0x%x\n",
- ext_hdr->type, ext_hdr->hdr.size);
-
- /* process structure data */
- switch (ext_hdr->type) {
- case SOF_IPC_EXT_WINDOW:
- ret = get_ext_windows(sdev, ext_hdr);
- break;
- case SOF_IPC_EXT_CC_INFO:
- ret = get_cc_info(sdev, ext_hdr);
- break;
- case SOF_IPC_EXT_UNUSED:
- case SOF_IPC_EXT_PROBE_INFO:
- case SOF_IPC_EXT_USER_ABI_INFO:
- /* They are supported but we don't do anything here */
- break;
- default:
- dev_info(sdev->dev, "unknown ext header type %d size 0x%x\n",
- ext_hdr->type, ext_hdr->hdr.size);
- ret = 0;
- break;
- }
-
- if (ret < 0) {
- dev_err(sdev->dev, "error: failed to parse ext data type %d\n",
- ext_hdr->type);
- break;
- }
-
- /* move to next header */
- offset += ext_hdr->hdr.size;
- snd_sof_dsp_block_read(sdev, SOF_FW_BLK_TYPE_SRAM, offset, ext_data,
- sizeof(*ext_hdr));
- ext_hdr = ext_data;
- }
-
- kfree(ext_data);
- return ret;
-}
-
static int ext_man_get_fw_version(struct snd_sof_dev *sdev,
const struct sof_ext_man_elem_header *hdr)
{
@@ -358,170 +295,6 @@ static int snd_sof_fw_ext_man_parse(struct snd_sof_dev *sdev,
return ext_man_size;
}
-/*
- * IPC Firmware ready.
- */
-static void sof_get_windows(struct snd_sof_dev *sdev)
-{
- struct sof_ipc_window_elem *elem;
- u32 outbox_offset = 0;
- u32 stream_offset = 0;
- u32 inbox_offset = 0;
- u32 outbox_size = 0;
- u32 stream_size = 0;
- u32 inbox_size = 0;
- u32 debug_size = 0;
- u32 debug_offset = 0;
- int window_offset;
- int i;
-
- if (!sdev->info_window) {
- dev_err(sdev->dev, "error: have no window info\n");
- return;
- }
-
- for (i = 0; i < sdev->info_window->num_windows; i++) {
- elem = &sdev->info_window->window[i];
-
- window_offset = snd_sof_dsp_get_window_offset(sdev, elem->id);
- if (window_offset < 0) {
- dev_warn(sdev->dev, "warn: no offset for window %d\n",
- elem->id);
- continue;
- }
-
- switch (elem->type) {
- case SOF_IPC_REGION_UPBOX:
- inbox_offset = window_offset + elem->offset;
- inbox_size = elem->size;
- snd_sof_debugfs_add_region_item(sdev, SOF_FW_BLK_TYPE_SRAM,
- inbox_offset,
- elem->size, "inbox",
- SOF_DEBUGFS_ACCESS_D0_ONLY);
- break;
- case SOF_IPC_REGION_DOWNBOX:
- outbox_offset = window_offset + elem->offset;
- outbox_size = elem->size;
- snd_sof_debugfs_add_region_item(sdev, SOF_FW_BLK_TYPE_SRAM,
- outbox_offset,
- elem->size, "outbox",
- SOF_DEBUGFS_ACCESS_D0_ONLY);
- break;
- case SOF_IPC_REGION_TRACE:
- snd_sof_debugfs_add_region_item(sdev, SOF_FW_BLK_TYPE_SRAM,
- window_offset + elem->offset,
- elem->size, "etrace",
- SOF_DEBUGFS_ACCESS_D0_ONLY);
- break;
- case SOF_IPC_REGION_DEBUG:
- debug_offset = window_offset + elem->offset;
- debug_size = elem->size;
- snd_sof_debugfs_add_region_item(sdev, SOF_FW_BLK_TYPE_SRAM,
- window_offset + elem->offset,
- elem->size, "debug",
- SOF_DEBUGFS_ACCESS_D0_ONLY);
- break;
- case SOF_IPC_REGION_STREAM:
- stream_offset = window_offset + elem->offset;
- stream_size = elem->size;
- snd_sof_debugfs_add_region_item(sdev, SOF_FW_BLK_TYPE_SRAM,
- stream_offset,
- elem->size, "stream",
- SOF_DEBUGFS_ACCESS_D0_ONLY);
- break;
- case SOF_IPC_REGION_REGS:
- snd_sof_debugfs_add_region_item(sdev, SOF_FW_BLK_TYPE_SRAM,
- window_offset + elem->offset,
- elem->size, "regs",
- SOF_DEBUGFS_ACCESS_D0_ONLY);
- break;
- case SOF_IPC_REGION_EXCEPTION:
- sdev->dsp_oops_offset = window_offset + elem->offset;
- snd_sof_debugfs_add_region_item(sdev, SOF_FW_BLK_TYPE_SRAM,
- window_offset + elem->offset,
- elem->size, "exception",
- SOF_DEBUGFS_ACCESS_D0_ONLY);
- break;
- default:
- dev_err(sdev->dev, "error: get illegal window info\n");
- return;
- }
- }
-
- if (outbox_size == 0 || inbox_size == 0) {
- dev_err(sdev->dev, "error: get illegal mailbox window\n");
- return;
- }
-
- sdev->dsp_box.offset = inbox_offset;
- sdev->dsp_box.size = inbox_size;
-
- sdev->host_box.offset = outbox_offset;
- sdev->host_box.size = outbox_size;
-
- sdev->stream_box.offset = stream_offset;
- sdev->stream_box.size = stream_size;
-
- sdev->debug_box.offset = debug_offset;
- sdev->debug_box.size = debug_size;
-
- dev_dbg(sdev->dev, " mailbox upstream 0x%x - size 0x%x\n",
- inbox_offset, inbox_size);
- dev_dbg(sdev->dev, " mailbox downstream 0x%x - size 0x%x\n",
- outbox_offset, outbox_size);
- dev_dbg(sdev->dev, " stream region 0x%x - size 0x%x\n",
- stream_offset, stream_size);
- dev_dbg(sdev->dev, " debug region 0x%x - size 0x%x\n",
- debug_offset, debug_size);
-}
-
-/* check for ABI compatibility and create memory windows on first boot */
-int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id)
-{
- struct sof_ipc_fw_ready *fw_ready = &sdev->fw_ready;
- int offset;
- int ret;
-
- /* mailbox must be on 4k boundary */
- offset = snd_sof_dsp_get_mailbox_offset(sdev);
- if (offset < 0) {
- dev_err(sdev->dev, "error: have no mailbox offset\n");
- return offset;
- }
-
- dev_dbg(sdev->dev, "ipc: DSP is ready 0x%8.8x offset 0x%x\n",
- msg_id, offset);
-
- /* no need to re-check version/ABI for subsequent boots */
- if (!sdev->first_boot)
- return 0;
-
- /*
- * copy data from the DSP FW ready offset
- * Subsequent error handling is not needed for BLK_TYPE_SRAM
- */
- ret = snd_sof_dsp_block_read(sdev, SOF_FW_BLK_TYPE_SRAM, offset, fw_ready,
- sizeof(*fw_ready));
- if (ret) {
- dev_err(sdev->dev,
- "error: unable to read fw_ready, read from TYPE_SRAM failed\n");
- return ret;
- }
-
- /* make sure ABI version is compatible */
- ret = snd_sof_ipc_valid(sdev);
- if (ret < 0)
- return ret;
-
- /* now check for extended data */
- snd_sof_fw_parse_ext_data(sdev, offset + sizeof(struct sof_ipc_fw_ready));
-
- sof_get_windows(sdev);
-
- return sof_ipc_init_msg_memory(sdev);
-}
-EXPORT_SYMBOL(sof_fw_ready);
-
/* generic module parser for mmaped DSPs */
int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev,
struct snd_sof_mod_hdr *module)
diff --git a/sound/soc/sof/mediatek/Kconfig b/sound/soc/sof/mediatek/Kconfig
index aeacf0e5bfbb..f79e76a6f3c6 100644
--- a/sound/soc/sof/mediatek/Kconfig
+++ b/sound/soc/sof/mediatek/Kconfig
@@ -21,6 +21,15 @@ config SND_SOC_SOF_MTK_COMMON
This option is not user-selectable but automagically handled by
'select' statements at a higher level
+config SND_SOC_SOF_MT8186
+ tristate "SOF support for MT8186 audio DSP"
+ select SND_SOC_SOF_MTK_COMMON
+ help
+ This adds support for Sound Open Firmware for Mediatek platforms
+ using the mt8186 processors.
+ Say Y if you have such a device.
+ If unsure select "N".
+
config SND_SOC_SOF_MT8195
tristate "SOF support for MT8195 audio DSP"
select SND_SOC_SOF_MTK_COMMON
diff --git a/sound/soc/sof/mediatek/Makefile b/sound/soc/sof/mediatek/Makefile
index e8ec6da981de..6ca8b8201ed1 100644
--- a/sound/soc/sof/mediatek/Makefile
+++ b/sound/soc/sof/mediatek/Makefile
@@ -1,2 +1,3 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
obj-$(CONFIG_SND_SOC_SOF_MT8195) += mt8195/
+obj-$(CONFIG_SND_SOC_SOF_MT8186) += mt8186/
diff --git a/sound/soc/sof/mediatek/adsp_helper.h b/sound/soc/sof/mediatek/adsp_helper.h
index 6734e2c0c6b1..f269a2b6c26a 100644
--- a/sound/soc/sof/mediatek/adsp_helper.h
+++ b/sound/soc/sof/mediatek/adsp_helper.h
@@ -29,6 +29,14 @@ struct mtk_adsp_chip_info {
void __iomem *shared_dram; /* part of va_dram */
phys_addr_t adsp_bootup_addr;
int dram_offset; /*dram offset between system and dsp view*/
+
+ phys_addr_t pa_secreg;
+ u32 secregsize;
+ void __iomem *va_secreg;
+
+ phys_addr_t pa_busreg;
+ u32 busregsize;
+ void __iomem *va_busreg;
};
struct adsp_priv {
diff --git a/sound/soc/sof/mediatek/mt8186/Makefile b/sound/soc/sof/mediatek/mt8186/Makefile
new file mode 100644
index 000000000000..c1f5fc4e2495
--- /dev/null
+++ b/sound/soc/sof/mediatek/mt8186/Makefile
@@ -0,0 +1,4 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+snd-sof-mt8186-objs := mt8186.o mt8186-clk.o mt8186-loader.o
+obj-$(CONFIG_SND_SOC_SOF_MT8186) += snd-sof-mt8186.o
+
diff --git a/sound/soc/sof/mediatek/mt8186/mt8186-clk.c b/sound/soc/sof/mediatek/mt8186/mt8186-clk.c
new file mode 100644
index 000000000000..5f805981b8e6
--- /dev/null
+++ b/sound/soc/sof/mediatek/mt8186/mt8186-clk.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// Copyright(c) 2022 Mediatek Corporation. All rights reserved.
+//
+// Author: Allen-KH Cheng <[email protected]>
+// Tinghan Shen <[email protected]>
+//
+// Hardware interface for mt8186 DSP clock
+
+#include <linux/clk.h>
+#include <linux/pm_runtime.h>
+#include <linux/io.h>
+
+#include "../../sof-audio.h"
+#include "../../ops.h"
+#include "../adsp_helper.h"
+#include "mt8186.h"
+#include "mt8186-clk.h"
+
+static const char *adsp_clks[ADSP_CLK_MAX] = {
+ [CLK_TOP_AUDIODSP] = "audiodsp_sel",
+ [CLK_TOP_ADSP_BUS] = "adsp_bus_sel",
+};
+
+int mt8186_adsp_init_clock(struct snd_sof_dev *sdev)
+{
+ struct adsp_priv *priv = sdev->pdata->hw_pdata;
+ struct device *dev = sdev->dev;
+ int i;
+
+ priv->clk = devm_kcalloc(dev, ADSP_CLK_MAX, sizeof(*priv->clk), GFP_KERNEL);
+ if (!priv->clk)
+ return -ENOMEM;
+
+ for (i = 0; i < ADSP_CLK_MAX; i++) {
+ priv->clk[i] = devm_clk_get(dev, adsp_clks[i]);
+
+ if (IS_ERR(priv->clk[i]))
+ return PTR_ERR(priv->clk[i]);
+ }
+
+ return 0;
+}
+
+static int adsp_enable_all_clock(struct snd_sof_dev *sdev)
+{
+ struct adsp_priv *priv = sdev->pdata->hw_pdata;
+ struct device *dev = sdev->dev;
+ int ret;
+
+ ret = clk_prepare_enable(priv->clk[CLK_TOP_AUDIODSP]);
+ if (ret) {
+ dev_err(dev, "%s clk_prepare_enable(audiodsp) fail %d\n",
+ __func__, ret);
+ return ret;
+ }
+
+ ret = clk_prepare_enable(priv->clk[CLK_TOP_ADSP_BUS]);
+ if (ret) {
+ dev_err(dev, "%s clk_prepare_enable(adsp_bus) fail %d\n",
+ __func__, ret);
+ clk_disable_unprepare(priv->clk[CLK_TOP_AUDIODSP]);
+ return ret;
+ }
+
+ return 0;
+}
+
+static void adsp_disable_all_clock(struct snd_sof_dev *sdev)
+{
+ struct adsp_priv *priv = sdev->pdata->hw_pdata;
+
+ clk_disable_unprepare(priv->clk[CLK_TOP_ADSP_BUS]);
+ clk_disable_unprepare(priv->clk[CLK_TOP_AUDIODSP]);
+}
+
+int adsp_clock_on(struct snd_sof_dev *sdev)
+{
+ struct device *dev = sdev->dev;
+ int ret;
+
+ ret = adsp_enable_all_clock(sdev);
+ if (ret) {
+ dev_err(dev, "failed to adsp_enable_clock: %d\n", ret);
+ return ret;
+ }
+ snd_sof_dsp_write(sdev, DSP_REG_BAR, ADSP_CK_EN,
+ UART_EN | DMA_EN | TIMER_EN | COREDBG_EN | CORE_CLK_EN);
+ snd_sof_dsp_write(sdev, DSP_REG_BAR, ADSP_UART_CTRL,
+ UART_BCLK_CG | UART_RSTN);
+
+ return 0;
+}
+
+void adsp_clock_off(struct snd_sof_dev *sdev)
+{
+ snd_sof_dsp_write(sdev, DSP_REG_BAR, ADSP_CK_EN, 0);
+ snd_sof_dsp_write(sdev, DSP_REG_BAR, ADSP_UART_CTRL, 0);
+ adsp_disable_all_clock(sdev);
+}
+
diff --git a/sound/soc/sof/mediatek/mt8186/mt8186-clk.h b/sound/soc/sof/mediatek/mt8186/mt8186-clk.h
new file mode 100644
index 000000000000..fa174dfceff0
--- /dev/null
+++ b/sound/soc/sof/mediatek/mt8186/mt8186-clk.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ *
+ * Header file for the mt8186 DSP clock definition
+ */
+
+#ifndef __MT8186_CLK_H
+#define __MT8186_CLK_H
+
+struct snd_sof_dev;
+
+/* DSP clock */
+enum adsp_clk_id {
+ CLK_TOP_AUDIODSP,
+ CLK_TOP_ADSP_BUS,
+ ADSP_CLK_MAX
+};
+
+int mt8186_adsp_init_clock(struct snd_sof_dev *sdev);
+int adsp_clock_on(struct snd_sof_dev *sdev);
+void adsp_clock_off(struct snd_sof_dev *sdev);
+#endif
diff --git a/sound/soc/sof/mediatek/mt8186/mt8186-loader.c b/sound/soc/sof/mediatek/mt8186/mt8186-loader.c
new file mode 100644
index 000000000000..6ab4921b1010
--- /dev/null
+++ b/sound/soc/sof/mediatek/mt8186/mt8186-loader.c
@@ -0,0 +1,53 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// Copyright (c) 2022 Mediatek Corporation. All rights reserved.
+//
+// Author: Allen-KH Cheng <[email protected]>
+// Tinghan Shen <[email protected]>
+//
+// Hardware interface for mt8186 DSP code loader
+
+#include <sound/sof.h>
+#include "mt8186.h"
+#include "../../ops.h"
+
+void sof_hifixdsp_boot_sequence(struct snd_sof_dev *sdev, u32 boot_addr)
+{
+ /* set RUNSTALL to stop core */
+ snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_HIFI_IO_CONFIG,
+ RUNSTALL, RUNSTALL);
+
+ /* set core boot address */
+ snd_sof_dsp_write(sdev, DSP_SECREG_BAR, ADSP_ALTVEC_C0, boot_addr);
+ snd_sof_dsp_write(sdev, DSP_SECREG_BAR, ADSP_ALTVECSEL, ADSP_ALTVECSEL_C0);
+
+ /* assert core reset */
+ snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_CFGREG_SW_RSTN,
+ SW_RSTN_C0 | SW_DBG_RSTN_C0,
+ SW_RSTN_C0 | SW_DBG_RSTN_C0);
+
+ /* hardware requirement */
+ udelay(1);
+
+ /* release core reset */
+ snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_CFGREG_SW_RSTN,
+ SW_RSTN_C0 | SW_DBG_RSTN_C0,
+ 0);
+
+ /* clear RUNSTALL (bit31) to start core */
+ snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_HIFI_IO_CONFIG,
+ RUNSTALL, 0);
+}
+
+void sof_hifixdsp_shutdown(struct snd_sof_dev *sdev)
+{
+ /* set RUNSTALL to stop core */
+ snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_HIFI_IO_CONFIG,
+ RUNSTALL, RUNSTALL);
+
+ /* assert core reset */
+ snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, ADSP_CFGREG_SW_RSTN,
+ SW_RSTN_C0 | SW_DBG_RSTN_C0,
+ SW_RSTN_C0 | SW_DBG_RSTN_C0);
+}
+
diff --git a/sound/soc/sof/mediatek/mt8186/mt8186.c b/sound/soc/sof/mediatek/mt8186/mt8186.c
new file mode 100644
index 000000000000..c8faa63497c6
--- /dev/null
+++ b/sound/soc/sof/mediatek/mt8186/mt8186.c
@@ -0,0 +1,413 @@
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
+//
+// Copyright(c) 2022 Mediatek Inc. All rights reserved.
+//
+// Author: Allen-KH Cheng <[email protected]>
+// Tinghan Shen <[email protected]>
+
+/*
+ * Hardware interface for audio DSP on mt8186
+ */
+
+#include <linux/delay.h>
+#include <linux/firmware.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/module.h>
+
+#include <sound/sof.h>
+#include <sound/sof/xtensa.h>
+#include "../../ops.h"
+#include "../../sof-of-dev.h"
+#include "../../sof-audio.h"
+#include "../adsp_helper.h"
+#include "mt8186.h"
+#include "mt8186-clk.h"
+
+static int platform_parse_resource(struct platform_device *pdev, void *data)
+{
+ struct resource *mmio;
+ struct resource res;
+ struct device_node *mem_region;
+ struct device *dev = &pdev->dev;
+ struct mtk_adsp_chip_info *adsp = data;
+ int ret;
+
+ mem_region = of_parse_phandle(dev->of_node, "memory-region", 0);
+ if (!mem_region) {
+ dev_err(dev, "no dma memory-region phandle\n");
+ return -ENODEV;
+ }
+
+ ret = of_address_to_resource(mem_region, 0, &res);
+ of_node_put(mem_region);
+ if (ret) {
+ dev_err(dev, "of_address_to_resource dma failed\n");
+ return ret;
+ }
+
+ dev_dbg(dev, "DMA %pR\n", &res);
+
+ ret = of_reserved_mem_device_init(dev);
+ if (ret) {
+ dev_err(dev, "of_reserved_mem_device_init failed\n");
+ return ret;
+ }
+
+ mem_region = of_parse_phandle(dev->of_node, "memory-region", 1);
+ if (!mem_region) {
+ dev_err(dev, "no memory-region sysmem phandle\n");
+ return -ENODEV;
+ }
+
+ ret = of_address_to_resource(mem_region, 0, &res);
+ of_node_put(mem_region);
+ if (ret) {
+ dev_err(dev, "of_address_to_resource sysmem failed\n");
+ return ret;
+ }
+
+ adsp->pa_dram = (phys_addr_t)res.start;
+ if (adsp->pa_dram & DRAM_REMAP_MASK) {
+ dev_err(dev, "adsp memory(%#x) is not 4K-aligned\n",
+ (u32)adsp->pa_dram);
+ return -EINVAL;
+ }
+
+ adsp->dramsize = resource_size(&res);
+ if (adsp->dramsize < TOTAL_SIZE_SHARED_DRAM_FROM_TAIL) {
+ dev_err(dev, "adsp memory(%#x) is not enough for share\n",
+ adsp->dramsize);
+ return -EINVAL;
+ }
+
+ dev_dbg(dev, "dram pbase=%pa size=%#x\n", &adsp->pa_dram, adsp->dramsize);
+
+ mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
+ if (!mmio) {
+ dev_err(dev, "no ADSP-CFG register resource\n");
+ return -ENXIO;
+ }
+
+ adsp->va_cfgreg = devm_ioremap_resource(dev, mmio);
+ if (IS_ERR(adsp->va_cfgreg))
+ return PTR_ERR(adsp->va_cfgreg);
+
+ adsp->pa_cfgreg = (phys_addr_t)mmio->start;
+ adsp->cfgregsize = resource_size(mmio);
+
+ dev_dbg(dev, "cfgreg pbase=%pa size=%#x\n", &adsp->pa_cfgreg, adsp->cfgregsize);
+
+ mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
+ if (!mmio) {
+ dev_err(dev, "no SRAM resource\n");
+ return -ENXIO;
+ }
+
+ adsp->pa_sram = (phys_addr_t)mmio->start;
+ adsp->sramsize = resource_size(mmio);
+
+ dev_dbg(dev, "sram pbase=%pa size=%#x\n", &adsp->pa_sram, adsp->sramsize);
+
+ mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sec");
+ if (!mmio) {
+ dev_err(dev, "no SEC register resource\n");
+ return -ENXIO;
+ }
+
+ adsp->va_secreg = devm_ioremap_resource(dev, mmio);
+ if (IS_ERR(adsp->va_secreg))
+ return PTR_ERR(adsp->va_secreg);
+
+ adsp->pa_secreg = (phys_addr_t)mmio->start;
+ adsp->secregsize = resource_size(mmio);
+
+ dev_dbg(dev, "secreg pbase=%pa size=%#x\n", &adsp->pa_secreg, adsp->secregsize);
+
+ mmio = platform_get_resource_byname(pdev, IORESOURCE_MEM, "bus");
+ if (!mmio) {
+ dev_err(dev, "no BUS register resource\n");
+ return -ENXIO;
+ }
+
+ adsp->va_busreg = devm_ioremap_resource(dev, mmio);
+ if (IS_ERR(adsp->va_busreg))
+ return PTR_ERR(adsp->va_busreg);
+
+ adsp->pa_busreg = (phys_addr_t)mmio->start;
+ adsp->busregsize = resource_size(mmio);
+
+ dev_dbg(dev, "busreg pbase=%pa size=%#x\n", &adsp->pa_busreg, adsp->busregsize);
+
+ return 0;
+}
+
+static void adsp_sram_power_on(struct snd_sof_dev *sdev)
+{
+ snd_sof_dsp_update_bits(sdev, DSP_BUSREG_BAR, ADSP_SRAM_POOL_CON,
+ DSP_SRAM_POOL_PD_MASK, 0);
+}
+
+static void adsp_sram_power_off(struct snd_sof_dev *sdev)
+{
+ snd_sof_dsp_update_bits(sdev, DSP_BUSREG_BAR, ADSP_SRAM_POOL_CON,
+ DSP_SRAM_POOL_PD_MASK, DSP_SRAM_POOL_PD_MASK);
+}
+
+/* Init the basic DSP DRAM address */
+static int adsp_memory_remap_init(struct snd_sof_dev *sdev, struct mtk_adsp_chip_info *adsp)
+{
+ u32 offset;
+
+ offset = adsp->pa_dram - DRAM_PHYS_BASE_FROM_DSP_VIEW;
+ adsp->dram_offset = offset;
+ offset >>= DRAM_REMAP_SHIFT;
+
+ dev_dbg(sdev->dev, "adsp->pa_dram %pa, offset %#x\n", &adsp->pa_dram, offset);
+
+ snd_sof_dsp_write(sdev, DSP_BUSREG_BAR, DSP_C0_EMI_MAP_ADDR, offset);
+ snd_sof_dsp_write(sdev, DSP_BUSREG_BAR, DSP_C0_DMAEMI_MAP_ADDR, offset);
+
+ if (offset != snd_sof_dsp_read(sdev, DSP_BUSREG_BAR, DSP_C0_EMI_MAP_ADDR) ||
+ offset != snd_sof_dsp_read(sdev, DSP_BUSREG_BAR, DSP_C0_DMAEMI_MAP_ADDR)) {
+ dev_err(sdev->dev, "emi remap fail\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int adsp_shared_base_ioremap(struct platform_device *pdev, void *data)
+{
+ struct device *dev = &pdev->dev;
+ struct mtk_adsp_chip_info *adsp = data;
+ u32 shared_size;
+
+ /* remap shared-dram base to be non-cachable */
+ shared_size = TOTAL_SIZE_SHARED_DRAM_FROM_TAIL;
+ adsp->pa_shared_dram = adsp->pa_dram + adsp->dramsize - shared_size;
+ if (adsp->va_dram) {
+ adsp->shared_dram = adsp->va_dram + DSP_DRAM_SIZE - shared_size;
+ } else {
+ adsp->shared_dram = devm_ioremap(dev, adsp->pa_shared_dram,
+ shared_size);
+ if (!adsp->shared_dram) {
+ dev_err(dev, "ioremap failed for shared DRAM\n");
+ return -ENOMEM;
+ }
+ }
+ dev_dbg(dev, "shared-dram vbase=%p, phy addr :%pa, size=%#x\n",
+ adsp->shared_dram, &adsp->pa_shared_dram, shared_size);
+
+ return 0;
+}
+
+static int mt8186_run(struct snd_sof_dev *sdev)
+{
+ u32 adsp_bootup_addr;
+
+ adsp_bootup_addr = SRAM_PHYS_BASE_FROM_DSP_VIEW;
+ dev_dbg(sdev->dev, "HIFIxDSP boot from base : 0x%08X\n", adsp_bootup_addr);
+ sof_hifixdsp_boot_sequence(sdev, adsp_bootup_addr);
+
+ return 0;
+}
+
+static int mt8186_dsp_probe(struct snd_sof_dev *sdev)
+{
+ struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev);
+ struct adsp_priv *priv;
+ int ret;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ sdev->pdata->hw_pdata = priv;
+ priv->dev = sdev->dev;
+ priv->sdev = sdev;
+
+ priv->adsp = devm_kzalloc(&pdev->dev, sizeof(struct mtk_adsp_chip_info), GFP_KERNEL);
+ if (!priv->adsp)
+ return -ENOMEM;
+
+ ret = platform_parse_resource(pdev, priv->adsp);
+ if (ret)
+ return ret;
+
+ sdev->bar[SOF_FW_BLK_TYPE_IRAM] = devm_ioremap(sdev->dev,
+ priv->adsp->pa_sram,
+ priv->adsp->sramsize);
+ if (!sdev->bar[SOF_FW_BLK_TYPE_IRAM]) {
+ dev_err(sdev->dev, "failed to ioremap base %pa size %#x\n",
+ &priv->adsp->pa_sram, priv->adsp->sramsize);
+ return -ENOMEM;
+ }
+
+ sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap_wc(sdev->dev,
+ priv->adsp->pa_dram,
+ priv->adsp->dramsize);
+ if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) {
+ dev_err(sdev->dev, "failed to ioremap base %pa size %#x\n",
+ &priv->adsp->pa_dram, priv->adsp->dramsize);
+ return -ENOMEM;
+ }
+
+ priv->adsp->va_dram = sdev->bar[SOF_FW_BLK_TYPE_SRAM];
+
+ ret = adsp_shared_base_ioremap(pdev, priv->adsp);
+ if (ret) {
+ dev_err(sdev->dev, "adsp_shared_base_ioremap fail!\n");
+ return ret;
+ }
+
+ sdev->bar[DSP_REG_BAR] = priv->adsp->va_cfgreg;
+ sdev->bar[DSP_SECREG_BAR] = priv->adsp->va_secreg;
+ sdev->bar[DSP_BUSREG_BAR] = priv->adsp->va_busreg;
+
+ sdev->mmio_bar = SOF_FW_BLK_TYPE_SRAM;
+ sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM;
+
+ ret = adsp_memory_remap_init(sdev, priv->adsp);
+ if (ret) {
+ dev_err(sdev->dev, "adsp_memory_remap_init fail!\n");
+ return ret;
+ }
+
+ /* enable adsp clock before touching registers */
+ ret = mt8186_adsp_init_clock(sdev);
+ if (ret) {
+ dev_err(sdev->dev, "mt8186_adsp_init_clock failed\n");
+ return ret;
+ }
+
+ ret = adsp_clock_on(sdev);
+ if (ret) {
+ dev_err(sdev->dev, "adsp_clock_on fail!\n");
+ return ret;
+ }
+
+ adsp_sram_power_on(sdev);
+
+ return 0;
+}
+
+static int mt8186_dsp_remove(struct snd_sof_dev *sdev)
+{
+ sof_hifixdsp_shutdown(sdev);
+ adsp_sram_power_off(sdev);
+ adsp_clock_off(sdev);
+
+ return 0;
+}
+
+static int mt8186_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state)
+{
+ sof_hifixdsp_shutdown(sdev);
+ adsp_sram_power_off(sdev);
+ adsp_clock_off(sdev);
+
+ return 0;
+}
+
+static int mt8186_dsp_resume(struct snd_sof_dev *sdev)
+{
+ int ret;
+
+ ret = adsp_clock_on(sdev);
+ if (ret) {
+ dev_err(sdev->dev, "adsp_clock_on fail!\n");
+ return ret;
+ }
+
+ adsp_sram_power_on(sdev);
+
+ return ret;
+}
+
+/* on mt8186 there is 1 to 1 match between type and BAR idx */
+static int mt8186_get_bar_index(struct snd_sof_dev *sdev, u32 type)
+{
+ return type;
+}
+
+/* mt8186 ops */
+static struct snd_sof_dsp_ops sof_mt8186_ops = {
+ /* probe and remove */
+ .probe = mt8186_dsp_probe,
+ .remove = mt8186_dsp_remove,
+
+ /* DSP core boot */
+ .run = mt8186_run,
+
+ /* Block IO */
+ .block_read = sof_block_read,
+ .block_write = sof_block_write,
+
+ /* Register IO */
+ .write = sof_io_write,
+ .read = sof_io_read,
+ .write64 = sof_io_write64,
+ .read64 = sof_io_read64,
+
+ /* misc */
+ .get_bar_index = mt8186_get_bar_index,
+
+ /* firmware loading */
+ .load_firmware = snd_sof_load_firmware_memcpy,
+
+ /* Firmware ops */
+ .dsp_arch_ops = &sof_xtensa_arch_ops,
+
+ /* PM */
+ .suspend = mt8186_dsp_suspend,
+ .resume = mt8186_dsp_resume,
+
+ /* ALSA HW info flags */
+ .hw_info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_MMAP_VALID |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_PAUSE |
+ SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
+};
+
+static const struct sof_dev_desc sof_of_mt8186_desc = {
+ .ipc_supported_mask = BIT(SOF_IPC),
+ .ipc_default = SOF_IPC,
+ .default_fw_path = {
+ [SOF_IPC] = "mediatek/sof",
+ },
+ .default_tplg_path = {
+ [SOF_IPC] = "mediatek/sof-tplg",
+ },
+ .default_fw_filename = {
+ [SOF_IPC] = "sof-mt8186.ri",
+ },
+ .nocodec_tplg_filename = "sof-mt8186-nocodec.tplg",
+ .ops = &sof_mt8186_ops,
+};
+
+static const struct of_device_id sof_of_mt8186_ids[] = {
+ { .compatible = "mediatek,mt8186-dsp", .data = &sof_of_mt8186_desc},
+ { }
+};
+MODULE_DEVICE_TABLE(of, sof_of_mt8186_ids);
+
+/* DT driver definition */
+static struct platform_driver snd_sof_of_mt8186_driver = {
+ .probe = sof_of_probe,
+ .remove = sof_of_remove,
+ .driver = {
+ .name = "sof-audio-of-mt8186",
+ .pm = &sof_of_pm,
+ .of_match_table = sof_of_mt8186_ids,
+ },
+};
+module_platform_driver(snd_sof_of_mt8186_driver);
+
+MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA);
+MODULE_IMPORT_NS(SND_SOC_SOF_MTK_COMMON);
+MODULE_LICENSE("Dual BSD/GPL");
diff --git a/sound/soc/sof/mediatek/mt8186/mt8186.h b/sound/soc/sof/mediatek/mt8186/mt8186.h
new file mode 100644
index 000000000000..df52ae9659e4
--- /dev/null
+++ b/sound/soc/sof/mediatek/mt8186/mt8186.h
@@ -0,0 +1,80 @@
+/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
+
+/*
+ * Copyright (c) 2022 MediaTek Corporation. All rights reserved.
+ *
+ * Header file for the mt8186 DSP register definition
+ */
+
+#ifndef __MT8186_H
+#define __MT8186_H
+
+struct mtk_adsp_chip_info;
+struct snd_sof_dev;
+
+#define DSP_REG_BAR 4
+#define DSP_SECREG_BAR 5
+#define DSP_BUSREG_BAR 6
+
+/*****************************************************************************
+ * R E G I S T E R TABLE
+ *****************************************************************************/
+/* dsp cfg */
+#define ADSP_CFGREG_SW_RSTN 0x0000
+#define SW_DBG_RSTN_C0 BIT(0)
+#define SW_RSTN_C0 BIT(4)
+#define ADSP_HIFI_IO_CONFIG 0x000C
+#define TRACEMEMREADY BIT(15)
+#define RUNSTALL BIT(31)
+#define ADSP_IRQ_MASK 0x0030
+#define ADSP_DVFSRC_REQ 0x0040
+#define ADSP_DDREN_REQ_0 0x0044
+#define ADSP_SEMAPHORE 0x0064
+#define ADSP_WDT_CON_C0 0x007C
+#define ADSP_MBOX_IRQ_EN 0x009C
+#define DSP_MBOX0_IRQ_EN BIT(0)
+#define DSP_MBOX1_IRQ_EN BIT(1)
+#define DSP_MBOX2_IRQ_EN BIT(2)
+#define DSP_MBOX3_IRQ_EN BIT(3)
+#define DSP_MBOX4_IRQ_EN BIT(4)
+#define DSP_PDEBUGPC 0x013C
+#define ADSP_CK_EN 0x1000
+#define CORE_CLK_EN BIT(0)
+#define COREDBG_EN BIT(1)
+#define TIMER_EN BIT(3)
+#define DMA_EN BIT(4)
+#define UART_EN BIT(5)
+#define ADSP_UART_CTRL 0x1010
+#define UART_BCLK_CG BIT(0)
+#define UART_RSTN BIT(3)
+
+/* dsp sec */
+#define ADSP_PRID 0x0
+#define ADSP_ALTVEC_C0 0x04
+#define ADSP_ALTVECSEL 0x0C
+#define ADSP_ALTVECSEL_C0 BIT(1)
+
+/* dsp bus */
+#define ADSP_SRAM_POOL_CON 0x190
+#define DSP_SRAM_POOL_PD_MASK 0xF00F /* [0:3] and [12:15] */
+#define DSP_C0_EMI_MAP_ADDR 0xA00 /* ADSP Core0 To EMI Address Remap */
+#define DSP_C0_DMAEMI_MAP_ADDR 0xA08 /* DMA0 To EMI Address Remap */
+
+/* DSP memories */
+#define MBOX_OFFSET 0x500000 /* DRAM */
+#define MBOX_SIZE 0x1000 /* consistent with which in memory.h of sof fw */
+#define DSP_DRAM_SIZE 0xA00000 /* 16M */
+
+/*remap dram between AP and DSP view, 4KB aligned*/
+#define SRAM_PHYS_BASE_FROM_DSP_VIEW 0x4E100000 /* MT8186 DSP view */
+#define DRAM_PHYS_BASE_FROM_DSP_VIEW 0x60000000 /* MT8186 DSP view */
+#define DRAM_REMAP_SHIFT 12
+#define DRAM_REMAP_MASK 0xFFF
+
+#define SIZE_SHARED_DRAM_DL 0x40000 /*Shared buffer for Downlink*/
+#define SIZE_SHARED_DRAM_UL 0x40000 /*Shared buffer for Uplink*/
+#define TOTAL_SIZE_SHARED_DRAM_FROM_TAIL (SIZE_SHARED_DRAM_DL + SIZE_SHARED_DRAM_UL)
+
+void sof_hifixdsp_boot_sequence(struct snd_sof_dev *sdev, u32 boot_addr);
+void sof_hifixdsp_shutdown(struct snd_sof_dev *sdev);
+#endif
diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h
index 6a09e5a73a50..382187e89e54 100644
--- a/sound/soc/sof/sof-priv.h
+++ b/sound/soc/sof/sof-priv.h
@@ -181,11 +181,6 @@ struct snd_sof_dsp_ops {
int (*load_firmware)(struct snd_sof_dev *sof_dev); /* mandatory */
int (*load_module)(struct snd_sof_dev *sof_dev,
struct snd_sof_mod_hdr *hdr); /* optional */
- /*
- * FW ready checks for ABI compatibility and creates
- * memory windows at first boot
- */
- int (*fw_ready)(struct snd_sof_dev *sdev, u32 msg_id); /* mandatory */
/* connect pcm substream to a host stream */
int (*pcm_open)(struct snd_sof_dev *sdev,
@@ -614,7 +609,7 @@ int sof_ipc_tx_message_no_pm(struct snd_sof_ipc *ipc, void *msg_data, size_t msg
void *reply_data, size_t reply_bytes);
int sof_ipc_send_msg(struct snd_sof_dev *sdev, void *msg_data, size_t msg_bytes,
size_t reply_bytes);
-int sof_ipc_init_msg_memory(struct snd_sof_dev *sdev);
+
static inline void snd_sof_ipc_process_reply(struct snd_sof_dev *sdev, u32 msg_id)
{
snd_sof_ipc_get_reply(sdev);
@@ -685,8 +680,6 @@ int sof_block_write(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type,
int sof_block_read(struct snd_sof_dev *sdev, enum snd_sof_fw_blk_type blk_type,
u32 offset, void *dest, size_t size);
-int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id);
-
int sof_ipc_msg_data(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream,
void *p, size_t sz);