Commit a45f1d43 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'regmap-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap

Pull regmap updates from Mark Brown:
 "This is quite a busy release for regmap with two substantial features
  being added:

    - Support for register maps Soundwire 1.2 multi-byte operations,
      allowing atomic support for registers larger than a single byte.

    - Support for relaxed I/O without barriers in MMIO regmaps, allowing
      them to be used efficiently on systems where default MMIO
      operations include barriers.

  There was also an addition and revert of use of the new Soundwire
  support for RT715 due to build issues with the driver built in, my
  tests only covered building it as a module, the patch wasn't just
  dropped as it had already been merged elsewhere"

* tag 'regmap-v5.11' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap:
  ASoC: rt715: Fix build
  regmap: sdw: add required header files
  regmap: Remove duplicate `type` field from regmap `regcache_sync` trace event
  regmap: Fix order of regmap write log
  regmap: mmio: add config option to allow relaxed MMIO accesses
parents 2cffa11e 4616c509
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
struct regmap_mmio_context { struct regmap_mmio_context {
void __iomem *regs; void __iomem *regs;
unsigned val_bytes; unsigned val_bytes;
bool relaxed_mmio;
bool attached_clk; bool attached_clk;
struct clk *clk; struct clk *clk;
...@@ -75,6 +76,13 @@ static void regmap_mmio_write8(struct regmap_mmio_context *ctx, ...@@ -75,6 +76,13 @@ static void regmap_mmio_write8(struct regmap_mmio_context *ctx,
writeb(val, ctx->regs + reg); writeb(val, ctx->regs + reg);
} }
static void regmap_mmio_write8_relaxed(struct regmap_mmio_context *ctx,
unsigned int reg,
unsigned int val)
{
writeb_relaxed(val, ctx->regs + reg);
}
static void regmap_mmio_write16le(struct regmap_mmio_context *ctx, static void regmap_mmio_write16le(struct regmap_mmio_context *ctx,
unsigned int reg, unsigned int reg,
unsigned int val) unsigned int val)
...@@ -82,6 +90,13 @@ static void regmap_mmio_write16le(struct regmap_mmio_context *ctx, ...@@ -82,6 +90,13 @@ static void regmap_mmio_write16le(struct regmap_mmio_context *ctx,
writew(val, ctx->regs + reg); writew(val, ctx->regs + reg);
} }
static void regmap_mmio_write16le_relaxed(struct regmap_mmio_context *ctx,
unsigned int reg,
unsigned int val)
{
writew_relaxed(val, ctx->regs + reg);
}
static void regmap_mmio_write16be(struct regmap_mmio_context *ctx, static void regmap_mmio_write16be(struct regmap_mmio_context *ctx,
unsigned int reg, unsigned int reg,
unsigned int val) unsigned int val)
...@@ -96,6 +111,13 @@ static void regmap_mmio_write32le(struct regmap_mmio_context *ctx, ...@@ -96,6 +111,13 @@ static void regmap_mmio_write32le(struct regmap_mmio_context *ctx,
writel(val, ctx->regs + reg); writel(val, ctx->regs + reg);
} }
static void regmap_mmio_write32le_relaxed(struct regmap_mmio_context *ctx,
unsigned int reg,
unsigned int val)
{
writel_relaxed(val, ctx->regs + reg);
}
static void regmap_mmio_write32be(struct regmap_mmio_context *ctx, static void regmap_mmio_write32be(struct regmap_mmio_context *ctx,
unsigned int reg, unsigned int reg,
unsigned int val) unsigned int val)
...@@ -110,6 +132,13 @@ static void regmap_mmio_write64le(struct regmap_mmio_context *ctx, ...@@ -110,6 +132,13 @@ static void regmap_mmio_write64le(struct regmap_mmio_context *ctx,
{ {
writeq(val, ctx->regs + reg); writeq(val, ctx->regs + reg);
} }
static void regmap_mmio_write64le_relaxed(struct regmap_mmio_context *ctx,
unsigned int reg,
unsigned int val)
{
writeq_relaxed(val, ctx->regs + reg);
}
#endif #endif
static int regmap_mmio_write(void *context, unsigned int reg, unsigned int val) static int regmap_mmio_write(void *context, unsigned int reg, unsigned int val)
...@@ -137,12 +166,24 @@ static unsigned int regmap_mmio_read8(struct regmap_mmio_context *ctx, ...@@ -137,12 +166,24 @@ static unsigned int regmap_mmio_read8(struct regmap_mmio_context *ctx,
return readb(ctx->regs + reg); return readb(ctx->regs + reg);
} }
static unsigned int regmap_mmio_read8_relaxed(struct regmap_mmio_context *ctx,
unsigned int reg)
{
return readb_relaxed(ctx->regs + reg);
}
static unsigned int regmap_mmio_read16le(struct regmap_mmio_context *ctx, static unsigned int regmap_mmio_read16le(struct regmap_mmio_context *ctx,
unsigned int reg) unsigned int reg)
{ {
return readw(ctx->regs + reg); return readw(ctx->regs + reg);
} }
static unsigned int regmap_mmio_read16le_relaxed(struct regmap_mmio_context *ctx,
unsigned int reg)
{
return readw_relaxed(ctx->regs + reg);
}
static unsigned int regmap_mmio_read16be(struct regmap_mmio_context *ctx, static unsigned int regmap_mmio_read16be(struct regmap_mmio_context *ctx,
unsigned int reg) unsigned int reg)
{ {
...@@ -155,6 +196,12 @@ static unsigned int regmap_mmio_read32le(struct regmap_mmio_context *ctx, ...@@ -155,6 +196,12 @@ static unsigned int regmap_mmio_read32le(struct regmap_mmio_context *ctx,
return readl(ctx->regs + reg); return readl(ctx->regs + reg);
} }
static unsigned int regmap_mmio_read32le_relaxed(struct regmap_mmio_context *ctx,
unsigned int reg)
{
return readl_relaxed(ctx->regs + reg);
}
static unsigned int regmap_mmio_read32be(struct regmap_mmio_context *ctx, static unsigned int regmap_mmio_read32be(struct regmap_mmio_context *ctx,
unsigned int reg) unsigned int reg)
{ {
...@@ -167,6 +214,12 @@ static unsigned int regmap_mmio_read64le(struct regmap_mmio_context *ctx, ...@@ -167,6 +214,12 @@ static unsigned int regmap_mmio_read64le(struct regmap_mmio_context *ctx,
{ {
return readq(ctx->regs + reg); return readq(ctx->regs + reg);
} }
static unsigned int regmap_mmio_read64le_relaxed(struct regmap_mmio_context *ctx,
unsigned int reg)
{
return readq_relaxed(ctx->regs + reg);
}
#endif #endif
static int regmap_mmio_read(void *context, unsigned int reg, unsigned int *val) static int regmap_mmio_read(void *context, unsigned int reg, unsigned int *val)
...@@ -237,6 +290,7 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, ...@@ -237,6 +290,7 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
ctx->regs = regs; ctx->regs = regs;
ctx->val_bytes = config->val_bits / 8; ctx->val_bytes = config->val_bits / 8;
ctx->relaxed_mmio = config->use_relaxed_mmio;
ctx->clk = ERR_PTR(-ENODEV); ctx->clk = ERR_PTR(-ENODEV);
switch (regmap_get_val_endian(dev, &regmap_mmio, config)) { switch (regmap_get_val_endian(dev, &regmap_mmio, config)) {
...@@ -247,21 +301,41 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev, ...@@ -247,21 +301,41 @@ static struct regmap_mmio_context *regmap_mmio_gen_context(struct device *dev,
#endif #endif
switch (config->val_bits) { switch (config->val_bits) {
case 8: case 8:
ctx->reg_read = regmap_mmio_read8; if (ctx->relaxed_mmio) {
ctx->reg_write = regmap_mmio_write8; ctx->reg_read = regmap_mmio_read8_relaxed;
ctx->reg_write = regmap_mmio_write8_relaxed;
} else {
ctx->reg_read = regmap_mmio_read8;
ctx->reg_write = regmap_mmio_write8;
}
break; break;
case 16: case 16:
ctx->reg_read = regmap_mmio_read16le; if (ctx->relaxed_mmio) {
ctx->reg_write = regmap_mmio_write16le; ctx->reg_read = regmap_mmio_read16le_relaxed;
ctx->reg_write = regmap_mmio_write16le_relaxed;
} else {
ctx->reg_read = regmap_mmio_read16le;
ctx->reg_write = regmap_mmio_write16le;
}
break; break;
case 32: case 32:
ctx->reg_read = regmap_mmio_read32le; if (ctx->relaxed_mmio) {
ctx->reg_write = regmap_mmio_write32le; ctx->reg_read = regmap_mmio_read32le_relaxed;
ctx->reg_write = regmap_mmio_write32le_relaxed;
} else {
ctx->reg_read = regmap_mmio_read32le;
ctx->reg_write = regmap_mmio_write32le;
}
break; break;
#ifdef CONFIG_64BIT #ifdef CONFIG_64BIT
case 64: case 64:
ctx->reg_read = regmap_mmio_read64le; if (ctx->relaxed_mmio) {
ctx->reg_write = regmap_mmio_write64le; ctx->reg_read = regmap_mmio_read64le_relaxed;
ctx->reg_write = regmap_mmio_write64le_relaxed;
} else {
ctx->reg_read = regmap_mmio_read64le;
ctx->reg_write = regmap_mmio_write64le;
}
break; break;
#endif #endif
default: default:
......
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
// Copyright(c) 2015-17 Intel Corporation. // Copyright(c) 2015-17 Intel Corporation.
#include <linux/device.h> #include <linux/device.h>
#include <linux/errno.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/regmap.h>
#include <linux/soundwire/sdw.h> #include <linux/soundwire/sdw.h>
#include "internal.h" #include "internal.h"
......
...@@ -1924,12 +1924,15 @@ int _regmap_write(struct regmap *map, unsigned int reg, ...@@ -1924,12 +1924,15 @@ int _regmap_write(struct regmap *map, unsigned int reg,
} }
} }
if (regmap_should_log(map)) ret = map->reg_write(context, reg, val);
dev_info(map->dev, "%x <= %x\n", reg, val); if (ret == 0) {
if (regmap_should_log(map))
dev_info(map->dev, "%x <= %x\n", reg, val);
trace_regmap_reg_write(map, reg, val); trace_regmap_reg_write(map, reg, val);
}
return map->reg_write(context, reg, val); return ret;
} }
/** /**
......
...@@ -126,7 +126,6 @@ TRACE_EVENT(regcache_sync, ...@@ -126,7 +126,6 @@ TRACE_EVENT(regcache_sync,
__string( name, regmap_name(map) ) __string( name, regmap_name(map) )
__string( status, status ) __string( status, status )
__string( type, type ) __string( type, type )
__field( int, type )
), ),
TP_fast_assign( TP_fast_assign(
......
...@@ -315,6 +315,10 @@ typedef void (*regmap_unlock)(void *); ...@@ -315,6 +315,10 @@ typedef void (*regmap_unlock)(void *);
* masks are used. * masks are used.
* @zero_flag_mask: If set, read_flag_mask and write_flag_mask are used even * @zero_flag_mask: If set, read_flag_mask and write_flag_mask are used even
* if they are both empty. * if they are both empty.
* @use_relaxed_mmio: If set, MMIO R/W operations will not use memory barriers.
* This can avoid load on devices which don't require strict
* orderings, but drivers should carefully add any explicit
* memory barriers when they may require them.
* @use_single_read: If set, converts the bulk read operation into a series of * @use_single_read: If set, converts the bulk read operation into a series of
* single read operations. This is useful for a device that * single read operations. This is useful for a device that
* does not support bulk read. * does not support bulk read.
...@@ -388,6 +392,7 @@ struct regmap_config { ...@@ -388,6 +392,7 @@ struct regmap_config {
bool use_single_read; bool use_single_read;
bool use_single_write; bool use_single_write;
bool use_relaxed_mmio;
bool can_multi_write; bool can_multi_write;
enum regmap_endian reg_format_endian; enum regmap_endian reg_format_endian;
......
...@@ -180,7 +180,6 @@ config SND_SOC_ALL_CODECS ...@@ -180,7 +180,6 @@ config SND_SOC_ALL_CODECS
imply SND_SOC_RT700_SDW imply SND_SOC_RT700_SDW
imply SND_SOC_RT711_SDW imply SND_SOC_RT711_SDW
imply SND_SOC_RT715_SDW imply SND_SOC_RT715_SDW
imply SND_SOC_RT715_SDCA_SDW
imply SND_SOC_RT1308_SDW imply SND_SOC_RT1308_SDW
imply SND_SOC_SGTL5000 imply SND_SOC_SGTL5000
imply SND_SOC_SI476X imply SND_SOC_SI476X
...@@ -1237,12 +1236,6 @@ config SND_SOC_RT715_SDW ...@@ -1237,12 +1236,6 @@ config SND_SOC_RT715_SDW
select SND_SOC_RT715 select SND_SOC_RT715
select REGMAP_SOUNDWIRE select REGMAP_SOUNDWIRE
config SND_SOC_RT715_SDCA_SDW
tristate "Realtek RT715 SDCA Codec - SDW"
depends on SOUNDWIRE
select REGMAP_SOUNDWIRE
select REGMAP_SOUNDWIRE_MBQ
#Freescale sgtl5000 codec #Freescale sgtl5000 codec
config SND_SOC_SGTL5000 config SND_SOC_SGTL5000
tristate "Freescale SGTL5000 CODEC" tristate "Freescale SGTL5000 CODEC"
......
...@@ -194,7 +194,6 @@ snd-soc-rt5682-i2c-objs := rt5682-i2c.o ...@@ -194,7 +194,6 @@ snd-soc-rt5682-i2c-objs := rt5682-i2c.o
snd-soc-rt700-objs := rt700.o rt700-sdw.o snd-soc-rt700-objs := rt700.o rt700-sdw.o
snd-soc-rt711-objs := rt711.o rt711-sdw.o snd-soc-rt711-objs := rt711.o rt711-sdw.o
snd-soc-rt715-objs := rt715.o rt715-sdw.o snd-soc-rt715-objs := rt715.o rt715-sdw.o
snd-soc-rt715-sdca-objs := rt715-sdca.o rt715-sdca-sdw.o
snd-soc-sgtl5000-objs := sgtl5000.o snd-soc-sgtl5000-objs := sgtl5000.o
snd-soc-alc5623-objs := alc5623.o snd-soc-alc5623-objs := alc5623.o
snd-soc-alc5632-objs := alc5632.o snd-soc-alc5632-objs := alc5632.o
...@@ -511,7 +510,6 @@ obj-$(CONFIG_SND_SOC_RT5682_SDW) += snd-soc-rt5682-sdw.o ...@@ -511,7 +510,6 @@ obj-$(CONFIG_SND_SOC_RT5682_SDW) += snd-soc-rt5682-sdw.o
obj-$(CONFIG_SND_SOC_RT700) += snd-soc-rt700.o obj-$(CONFIG_SND_SOC_RT700) += snd-soc-rt700.o
obj-$(CONFIG_SND_SOC_RT711) += snd-soc-rt711.o obj-$(CONFIG_SND_SOC_RT711) += snd-soc-rt711.o
obj-$(CONFIG_SND_SOC_RT715) += snd-soc-rt715.o obj-$(CONFIG_SND_SOC_RT715) += snd-soc-rt715.o
obj-$(CONFIG_SND_SOC_RT715_SDCA_SDW) += snd-soc-rt715-sdca.o
obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o
obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o
obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o
......
// SPDX-License-Identifier: GPL-2.0-only
//
// rt715-sdca-sdw.c -- rt715 ALSA SoC audio driver
//
// Copyright(c) 2020 Realtek Semiconductor Corp.
//
//
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/mod_devicetable.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_type.h>
#include <linux/soundwire/sdw_registers.h>
#include <linux/module.h>
#include <linux/regmap.h>
#include <sound/soc.h>
#include "rt715-sdca.h"
#include "rt715-sdca-sdw.h"
static bool rt715_sdca_readable_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case 0x201a ... 0x2027:
case 0x2029 ... 0x202a:
case 0x202d ... 0x2034:
case 0x2200 ... 0x2204:
case 0x2206 ... 0x2212:
case 0x2230 ... 0x2239:
case 0x2f5b:
case SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN,
RT715_SDCA_SMPU_TRIG_ST_CTRL, CH_00):
return true;
default:
return false;
}
}
static bool rt715_sdca_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case 0x201b:
case 0x201c:
case 0x201d:
case 0x201f:
case 0x2021:
case 0x2023:
case 0x2230:
case 0x202d ... 0x202f: /* BRA */
case 0x2200 ... 0x2212: /* i2c debug */
case 0x2f07:
case 0x2f1b ... 0x2f1e:
case 0x2f30 ... 0x2f34:
case 0x2f50 ... 0x2f51:
case 0x2f53 ... 0x2f59:
case 0x2f5c ... 0x2f5f:
case SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN,
RT715_SDCA_SMPU_TRIG_ST_CTRL, CH_00): /* VAD Searching status */
return true;
default:
return false;
}
}
static bool rt715_sdca_mbq_readable_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case 0x2000000:
case 0x200002b:
case 0x2000036:
case 0x2000037:
case 0x2000039:
case 0x6100000:
return true;
default:
return false;
}
}
static bool rt715_sdca_mbq_volatile_register(struct device *dev, unsigned int reg)
{
switch (reg) {
case 0x2000000:
return true;
default:
return false;
}
}
static const struct regmap_config rt715_sdca_regmap = {
.reg_bits = 32,
.val_bits = 8,
.readable_reg = rt715_sdca_readable_register,
.volatile_reg = rt715_sdca_volatile_register,
.max_register = 0x43ffffff,
.reg_defaults = rt715_reg_defaults_sdca,
.num_reg_defaults = ARRAY_SIZE(rt715_reg_defaults_sdca),
.cache_type = REGCACHE_RBTREE,
.use_single_read = true,
.use_single_write = true,
};
static const struct regmap_config rt715_sdca_mbq_regmap = {
.name = "sdw-mbq",
.reg_bits = 32,
.val_bits = 16,
.readable_reg = rt715_sdca_mbq_readable_register,
.volatile_reg = rt715_sdca_mbq_volatile_register,
.max_register = 0x43ffffff,
.reg_defaults = rt715_mbq_reg_defaults_sdca,
.num_reg_defaults = ARRAY_SIZE(rt715_mbq_reg_defaults_sdca),
.cache_type = REGCACHE_RBTREE,
.use_single_read = true,
.use_single_write = true,
};
static int rt715_update_status(struct sdw_slave *slave,
enum sdw_slave_status status)
{
struct rt715_sdca_priv *rt715 = dev_get_drvdata(&slave->dev);
/* Update the status */
rt715->status = status;
/*
* Perform initialization only if slave status is present and
* hw_init flag is false
*/
if (rt715->hw_init || rt715->status != SDW_SLAVE_ATTACHED)
return 0;
/* perform I/O transfers required for Slave initialization */
return rt715_io_init(&slave->dev, slave);
}
static int rt715_read_prop(struct sdw_slave *slave)
{
struct sdw_slave_prop *prop = &slave->prop;
int nval, i;
u32 bit;
unsigned long addr;
struct sdw_dpn_prop *dpn;
prop->paging_support = true;
/* first we need to allocate memory for set bits in port lists */
prop->source_ports = 0x50;/* BITMAP: 01010000 */
prop->sink_ports = 0x0; /* BITMAP: 00000000 */
nval = hweight32(prop->source_ports);
prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval,
sizeof(*prop->src_dpn_prop),
GFP_KERNEL);
if (!prop->src_dpn_prop)
return -ENOMEM;
dpn = prop->src_dpn_prop;
i = 0;
addr = prop->source_ports;
for_each_set_bit(bit, &addr, 32) {
dpn[i].num = bit;
dpn[i].simple_ch_prep_sm = true;
dpn[i].ch_prep_timeout = 10;
i++;
}
/* set the timeout values */
prop->clk_stop_timeout = 20;
return 0;
}
static struct sdw_slave_ops rt715_sdca_slave_ops = {
.read_prop = rt715_read_prop,
.update_status = rt715_update_status,
};
static int rt715_sdca_sdw_probe(struct sdw_slave *slave,
const struct sdw_device_id *id)
{
struct regmap *mbq_regmap, *regmap;
slave->ops = &rt715_sdca_slave_ops;
/* Regmap Initialization */
mbq_regmap = devm_regmap_init_sdw_mbq(slave, &rt715_sdca_mbq_regmap);
if (!mbq_regmap)
return -EINVAL;
regmap = devm_regmap_init_sdw(slave, &rt715_sdca_regmap);
if (!regmap)
return -EINVAL;
return rt715_init(&slave->dev, mbq_regmap, regmap, slave);
}
static const struct sdw_device_id rt715_sdca_id[] = {
SDW_SLAVE_ENTRY_EXT(0x025d, 0x715, 0x3, 0x1, 0),
SDW_SLAVE_ENTRY_EXT(0x025d, 0x714, 0x3, 0x1, 0),
{},
};
MODULE_DEVICE_TABLE(sdw, rt715_sdca_id);
static int __maybe_unused rt715_dev_suspend(struct device *dev)
{
struct rt715_sdca_priv *rt715 = dev_get_drvdata(dev);
if (!rt715->hw_init)
return 0;
regcache_cache_only(rt715->regmap, true);
regcache_mark_dirty(rt715->regmap);
regcache_cache_only(rt715->mbq_regmap, true);
regcache_mark_dirty(rt715->mbq_regmap);
return 0;
}
#define RT715_PROBE_TIMEOUT 2000
static int __maybe_unused rt715_dev_resume(struct device *dev)
{
struct sdw_slave *slave = dev_to_sdw_dev(dev);
struct rt715_sdca_priv *rt715 = dev_get_drvdata(dev);
unsigned long time;
if (!rt715->hw_init)
return 0;
if (!slave->unattach_request)
goto regmap_sync;
time = wait_for_completion_timeout(&slave->enumeration_complete,
msecs_to_jiffies(RT715_PROBE_TIMEOUT));
if (!time) {
dev_err(&slave->dev, "Enumeration not complete, timed out\n");
return -ETIMEDOUT;
}
regmap_sync:
slave->unattach_request = 0;
regcache_cache_only(rt715->regmap, false);
regcache_sync_region(rt715->regmap,
SDW_SDCA_CTL(FUN_JACK_CODEC, RT715_SDCA_ST_EN, RT715_SDCA_ST_CTRL,
CH_00),
SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN,
RT715_SDCA_SMPU_TRIG_ST_CTRL, CH_00));
regcache_cache_only(rt715->mbq_regmap, false);
regcache_sync_region(rt715->mbq_regmap, 0x2000000, 0x61020ff);
regcache_sync_region(rt715->mbq_regmap,
SDW_SDCA_CTL(FUN_JACK_CODEC, RT715_SDCA_ST_EN, RT715_SDCA_ST_CTRL,
CH_00),
SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN,
RT715_SDCA_SMPU_TRIG_ST_CTRL, CH_00));
return 0;
}
static const struct dev_pm_ops rt715_pm = {
SET_SYSTEM_SLEEP_PM_OPS(rt715_dev_suspend, rt715_dev_resume)
SET_RUNTIME_PM_OPS(rt715_dev_suspend, rt715_dev_resume, NULL)
};
static struct sdw_driver rt715_sdw_driver = {
.driver = {
.name = "rt715-sdca",
.owner = THIS_MODULE,
.pm = &rt715_pm,
},
.probe = rt715_sdca_sdw_probe,
.ops = &rt715_sdca_slave_ops,
.id_table = rt715_sdca_id,
};
module_sdw_driver(rt715_sdw_driver);
MODULE_DESCRIPTION("ASoC RT715 driver SDW SDCA");
MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>");
MODULE_LICENSE("GPL v2");
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* rt715-sdca-sdw.h -- RT715 ALSA SoC audio driver header
*
* Copyright(c) 2020 Realtek Semiconductor Corp.
*/
#ifndef __RT715_SDW_SDCA_H__
#define __RT715_SDW_SDCA_H__
#include <linux/soundwire/sdw_registers.h>
static const struct reg_default rt715_reg_defaults_sdca[] = {
{ 0x201a, 0x00 },
{ 0x201e, 0x00 },
{ 0x2020, 0x00 },
{ 0x2021, 0x00 },
{ 0x2022, 0x00 },
{ 0x2023, 0x00 },
{ 0x2024, 0x00 },
{ 0x2025, 0x01 },
{ 0x2026, 0x00 },
{ 0x2027, 0x00 },
{ 0x2029, 0x00 },
{ 0x202a, 0x00 },
{ 0x202d, 0x00 },
{ 0x202e, 0x00 },
{ 0x202f, 0x00 },
{ 0x2030, 0x00 },
{ 0x2031, 0x00 },
{ 0x2032, 0x00 },
{ 0x2033, 0x00 },
{ 0x2034, 0x00 },
{ 0x2230, 0x00 },
{ 0x2231, 0x2f },
{ 0x2232, 0x80 },
{ 0x2233, 0x00 },
{ 0x2234, 0x00 },
{ 0x2235, 0x00 },
{ 0x2236, 0x00 },
{ 0x2237, 0x00 },
{ 0x2238, 0x00 },
{ 0x2239, 0x00 },
{ 0x2f01, 0x00 },
{ 0x2f02, 0x09 },
{ 0x2f03, 0x0b },
{ 0x2f04, 0x00 },
{ 0x2f05, 0x0e },
{ 0x2f06, 0x01 },
{ 0x2f08, 0x00 },
{ 0x2f09, 0x00 },
{ 0x2f0a, 0x00 },
{ 0x2f0b, 0x00 },
{ 0x2f0c, 0x00 },
{ 0x2f0d, 0x00 },
{ 0x2f0e, 0x12 },
{ 0x2f0f, 0x00 },
{ 0x2f10, 0x00 },
{ 0x2f11, 0x00 },
{ 0x2f12, 0x00 },
{ 0x2f13, 0x00 },
{ 0x2f14, 0x00 },
{ 0x2f15, 0x00 },
{ 0x2f16, 0x00 },
{ 0x2f17, 0x00 },
{ 0x2f18, 0x00 },
{ 0x2f19, 0x03 },
{ 0x2f1a, 0x00 },
{ 0x2f1f, 0x10 },
{ 0x2f20, 0x00 },
{ 0x2f21, 0x00 },
{ 0x2f22, 0x00 },
{ 0x2f23, 0x00 },
{ 0x2f24, 0x00 },
{ 0x2f25, 0x00 },
{ 0x2f52, 0x01 },
{ 0x2f5a, 0x02 },
{ 0x2f5b, 0x05 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CX_CLK_SEL_EN,
RT715_SDCA_CX_CLK_SEL_CTRL, CH_00), 0x1 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
RT715_SDCA_FU_MUTE_CTRL, CH_01), 0x01 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
RT715_SDCA_FU_MUTE_CTRL, CH_02), 0x01 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
RT715_SDCA_FU_MUTE_CTRL, CH_03), 0x01 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
RT715_SDCA_FU_MUTE_CTRL, CH_04), 0x01 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
RT715_SDCA_FU_MUTE_CTRL, CH_01), 0x01 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
RT715_SDCA_FU_MUTE_CTRL, CH_02), 0x01 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
RT715_SDCA_FU_MUTE_CTRL, CH_03), 0x01 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
RT715_SDCA_FU_MUTE_CTRL, CH_04), 0x01 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
RT715_SDCA_FU_MUTE_CTRL, CH_01), 0x01 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
RT715_SDCA_FU_MUTE_CTRL, CH_02), 0x01 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN,
RT715_SDCA_SMPU_TRIG_EN_CTRL, CH_00), 0x02 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN,
RT715_SDCA_SMPU_TRIG_ST_CTRL, CH_00), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
RT715_SDCA_FU_MUTE_CTRL, CH_01), 0x01 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
RT715_SDCA_FU_MUTE_CTRL, CH_02), 0x01 },
};
static const struct reg_default rt715_mbq_reg_defaults_sdca[] = {
{ 0x200002b, 0x0420 },
{ 0x2000036, 0x0000 },
{ 0x2000037, 0x0000 },
{ 0x2000039, 0xaa81 },
{ 0x6100000, 0x0100 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
RT715_SDCA_FU_VOL_CTRL, CH_01), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
RT715_SDCA_FU_VOL_CTRL, CH_02), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
RT715_SDCA_FU_VOL_CTRL, CH_03), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
RT715_SDCA_FU_VOL_CTRL, CH_04), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
RT715_SDCA_FU_VOL_CTRL, CH_01), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
RT715_SDCA_FU_VOL_CTRL, CH_02), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
RT715_SDCA_FU_VOL_CTRL, CH_03), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
RT715_SDCA_FU_VOL_CTRL, CH_04), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
RT715_SDCA_FU_VOL_CTRL, CH_01), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
RT715_SDCA_FU_VOL_CTRL, CH_02), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_01), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_02), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_03), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_04), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_05), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_06), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_07), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_08), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_01), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_02), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_03), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_04), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_05), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_06), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_07), 0x00 },
{ SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_08), 0x00 },
};
#endif /* __RT715_SDW_SDCA_H__ */
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* rt715-sdca.h -- RT715 ALSA SoC audio driver header
*
* Copyright(c) 2020 Realtek Semiconductor Corp.
*/
#ifndef __RT715_SDCA_H__
#define __RT715_SDCA_H__
#include <linux/regmap.h>
#include <linux/soundwire/sdw.h>
#include <linux/soundwire/sdw_type.h>
#include <sound/soc.h>
#include <linux/workqueue.h>
#include <linux/device.h>
struct rt715_sdca_priv {
struct regmap *regmap;
struct regmap *mbq_regmap;
struct snd_soc_codec *codec;
struct sdw_slave *slave;
struct delayed_work adc_mute_work;
int dbg_nid;
int dbg_vid;
int dbg_payload;
enum sdw_slave_status status;
struct sdw_bus_params params;
bool hw_init;
bool first_init;
int l_is_unmute;
int r_is_unmute;
int hw_sdw_ver;
};
struct rt715_sdw_stream_data {
struct sdw_stream_runtime *sdw_stream;
};
/* MIPI Register */
#define RT715_INT_CTRL 0x005a
#define RT715_INT_MASK 0x005e
/* NID */
#define RT715_AUDIO_FUNCTION_GROUP 0x01
#define RT715_MIC_ADC 0x07
#define RT715_LINE_ADC 0x08
#define RT715_MIX_ADC 0x09
#define RT715_DMIC1 0x12
#define RT715_DMIC2 0x13
#define RT715_MIC1 0x18
#define RT715_MIC2 0x19
#define RT715_LINE1 0x1a
#define RT715_LINE2 0x1b
#define RT715_DMIC3 0x1d
#define RT715_DMIC4 0x29
#define RT715_VENDOR_REG 0x20
#define RT715_MUX_IN1 0x22
#define RT715_MUX_IN2 0x23
#define RT715_MUX_IN3 0x24
#define RT715_MUX_IN4 0x25
#define RT715_MIX_ADC2 0x27
#define RT715_INLINE_CMD 0x55
#define RT715_VENDOR_HDA_CTL 0x61
/* Index (NID:20h) */
#define RT715_PRODUCT_NUM 0x0
#define RT715_IRQ_CTRL 0x2b
#define RT715_AD_FUNC_EN 0x36
#define RT715_REV_1 0x37
#define RT715_SDW_INPUT_SEL 0x39
#define RT715_EXT_DMIC_CLK_CTRL2 0x54
/* Index (NID:61h) */
#define RT715_HDA_LEGACY_MUX_CTL1 0x00
/* SDCA (Function) */
#define FUN_JACK_CODEC 0x01
#define FUN_MIC_ARRAY 0x02
#define FUN_HID 0x03
/* SDCA (Entity) */
#define RT715_SDCA_ST_EN 0x00
#define RT715_SDCA_CS_FREQ_IND_EN 0x01
#define RT715_SDCA_FU_ADC8_9_VOL 0x02
#define RT715_SDCA_SMPU_TRIG_ST_EN 0x05
#define RT715_SDCA_FU_ADC10_11_VOL 0x06
#define RT715_SDCA_FU_ADC7_27_VOL 0x0a
#define RT715_SDCA_FU_AMIC_GAIN_EN 0x0c
#define RT715_SDCA_FU_DMIC_GAIN_EN 0x0e
#define RT715_SDCA_CX_CLK_SEL_EN 0x10
#define RT715_SDCA_CREQ_POW_EN 0x18
/* SDCA (Control) */
#define RT715_SDCA_ST_CTRL 0x00
#define RT715_SDCA_CX_CLK_SEL_CTRL 0x01
#define RT715_SDCA_REQ_POW_CTRL 0x01
#define RT715_SDCA_FU_MUTE_CTRL 0x01
#define RT715_SDCA_FU_VOL_CTRL 0x02
#define RT715_SDCA_FU_DMIC_GAIN_CTRL 0x0b
#define RT715_SDCA_FREQ_IND_CTRL 0x10
#define RT715_SDCA_SMPU_TRIG_EN_CTRL 0x10
#define RT715_SDCA_SMPU_TRIG_ST_CTRL 0x11
/* SDCA (Channel) */
#define CH_00 0x00
#define CH_01 0x01
#define CH_02 0x02
#define CH_03 0x03
#define CH_04 0x04
#define CH_05 0x05
#define CH_06 0x06
#define CH_07 0x07
#define CH_08 0x08
#define RT715_SDCA_DB_STEP 375
enum {
RT715_AIF1,
RT715_AIF2,
};
int rt715_io_init(struct device *dev, struct sdw_slave *slave);
int rt715_init(struct device *dev, struct regmap *mbq_regmap,
struct regmap *regmap, struct sdw_slave *slave);
#endif /* __RT715_SDCA_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment