Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

+96 -1530
+82 -8
drivers/base/regmap/regmap-mmio.c
··· 16 16 struct regmap_mmio_context { 17 17 void __iomem *regs; 18 18 unsigned val_bytes; 19 + bool relaxed_mmio; 19 20 20 21 bool attached_clk; 21 22 struct clk *clk; ··· 76 75 writeb(val, ctx->regs + reg); 77 76 } 78 77 78 + static void regmap_mmio_write8_relaxed(struct regmap_mmio_context *ctx, 79 + unsigned int reg, 80 + unsigned int val) 81 + { 82 + writeb_relaxed(val, ctx->regs + reg); 83 + } 84 + 79 85 static void regmap_mmio_write16le(struct regmap_mmio_context *ctx, 80 86 unsigned int reg, 81 87 unsigned int val) 82 88 { 83 89 writew(val, ctx->regs + reg); 90 + } 91 + 92 + static void regmap_mmio_write16le_relaxed(struct regmap_mmio_context *ctx, 93 + unsigned int reg, 94 + unsigned int val) 95 + { 96 + writew_relaxed(val, ctx->regs + reg); 84 97 } 85 98 86 99 static void regmap_mmio_write16be(struct regmap_mmio_context *ctx, ··· 111 96 writel(val, ctx->regs + reg); 112 97 } 113 98 99 + static void regmap_mmio_write32le_relaxed(struct regmap_mmio_context *ctx, 100 + unsigned int reg, 101 + unsigned int val) 102 + { 103 + writel_relaxed(val, ctx->regs + reg); 104 + } 105 + 114 106 static void regmap_mmio_write32be(struct regmap_mmio_context *ctx, 115 107 unsigned int reg, 116 108 unsigned int val) ··· 131 109 unsigned int val) 132 110 { 133 111 writeq(val, ctx->regs + reg); 112 + } 113 + 114 + static void regmap_mmio_write64le_relaxed(struct regmap_mmio_context *ctx, 115 + unsigned int reg, 116 + unsigned int val) 117 + { 118 + writeq_relaxed(val, ctx->regs + reg); 134 119 } 135 120 #endif 136 121 ··· 166 137 return readb(ctx->regs + reg); 167 138 } 168 139 140 + static unsigned int regmap_mmio_read8_relaxed(struct regmap_mmio_context *ctx, 141 + unsigned int reg) 142 + { 143 + return readb_relaxed(ctx->regs + reg); 144 + } 145 + 169 146 static unsigned int regmap_mmio_read16le(struct regmap_mmio_context *ctx, 170 147 unsigned int reg) 171 148 { 172 149 return readw(ctx->regs + reg); 150 + } 151 + 152 + static unsigned int regmap_mmio_read16le_relaxed(struct regmap_mmio_context *ctx, 153 + unsigned int reg) 154 + { 155 + return readw_relaxed(ctx->regs + reg); 173 156 } 174 157 175 158 static unsigned int regmap_mmio_read16be(struct regmap_mmio_context *ctx, ··· 196 155 return readl(ctx->regs + reg); 197 156 } 198 157 158 + static unsigned int regmap_mmio_read32le_relaxed(struct regmap_mmio_context *ctx, 159 + unsigned int reg) 160 + { 161 + return readl_relaxed(ctx->regs + reg); 162 + } 163 + 199 164 static unsigned int regmap_mmio_read32be(struct regmap_mmio_context *ctx, 200 165 unsigned int reg) 201 166 { ··· 213 166 unsigned int reg) 214 167 { 215 168 return readq(ctx->regs + reg); 169 + } 170 + 171 + static unsigned int regmap_mmio_read64le_relaxed(struct regmap_mmio_context *ctx, 172 + unsigned int reg) 173 + { 174 + return readq_relaxed(ctx->regs + reg); 216 175 } 217 176 #endif 218 177 ··· 290 237 291 238 ctx->regs = regs; 292 239 ctx->val_bytes = config->val_bits / 8; 240 + ctx->relaxed_mmio = config->use_relaxed_mmio; 293 241 ctx->clk = ERR_PTR(-ENODEV); 294 242 295 243 switch (regmap_get_val_endian(dev, &regmap_mmio, config)) { ··· 301 247 #endif 302 248 switch (config->val_bits) { 303 249 case 8: 304 - ctx->reg_read = regmap_mmio_read8; 305 - ctx->reg_write = regmap_mmio_write8; 250 + if (ctx->relaxed_mmio) { 251 + ctx->reg_read = regmap_mmio_read8_relaxed; 252 + ctx->reg_write = regmap_mmio_write8_relaxed; 253 + } else { 254 + ctx->reg_read = regmap_mmio_read8; 255 + ctx->reg_write = regmap_mmio_write8; 256 + } 306 257 break; 307 258 case 16: 308 - ctx->reg_read = regmap_mmio_read16le; 309 - ctx->reg_write = regmap_mmio_write16le; 259 + if (ctx->relaxed_mmio) { 260 + ctx->reg_read = regmap_mmio_read16le_relaxed; 261 + ctx->reg_write = regmap_mmio_write16le_relaxed; 262 + } else { 263 + ctx->reg_read = regmap_mmio_read16le; 264 + ctx->reg_write = regmap_mmio_write16le; 265 + } 310 266 break; 311 267 case 32: 312 - ctx->reg_read = regmap_mmio_read32le; 313 - ctx->reg_write = regmap_mmio_write32le; 268 + if (ctx->relaxed_mmio) { 269 + ctx->reg_read = regmap_mmio_read32le_relaxed; 270 + ctx->reg_write = regmap_mmio_write32le_relaxed; 271 + } else { 272 + ctx->reg_read = regmap_mmio_read32le; 273 + ctx->reg_write = regmap_mmio_write32le; 274 + } 314 275 break; 315 276 #ifdef CONFIG_64BIT 316 277 case 64: 317 - ctx->reg_read = regmap_mmio_read64le; 318 - ctx->reg_write = regmap_mmio_write64le; 278 + if (ctx->relaxed_mmio) { 279 + ctx->reg_read = regmap_mmio_read64le_relaxed; 280 + ctx->reg_write = regmap_mmio_write64le_relaxed; 281 + } else { 282 + ctx->reg_read = regmap_mmio_read64le; 283 + ctx->reg_write = regmap_mmio_write64le; 284 + } 319 285 break; 320 286 #endif 321 287 default:
+2
drivers/base/regmap/regmap-sdw.c
··· 2 2 // Copyright(c) 2015-17 Intel Corporation. 3 3 4 4 #include <linux/device.h> 5 + #include <linux/errno.h> 5 6 #include <linux/module.h> 7 + #include <linux/regmap.h> 6 8 #include <linux/soundwire/sdw.h> 7 9 #include "internal.h" 8 10
+7 -4
drivers/base/regmap/regmap.c
··· 1924 1924 } 1925 1925 } 1926 1926 1927 - if (regmap_should_log(map)) 1928 - dev_info(map->dev, "%x <= %x\n", reg, val); 1927 + ret = map->reg_write(context, reg, val); 1928 + if (ret == 0) { 1929 + if (regmap_should_log(map)) 1930 + dev_info(map->dev, "%x <= %x\n", reg, val); 1929 1931 1930 - trace_regmap_reg_write(map, reg, val); 1932 + trace_regmap_reg_write(map, reg, val); 1933 + } 1931 1934 1932 - return map->reg_write(context, reg, val); 1935 + return ret; 1933 1936 } 1934 1937 1935 1938 /**
-1
drivers/base/regmap/trace.h
··· 126 126 __string( name, regmap_name(map) ) 127 127 __string( status, status ) 128 128 __string( type, type ) 129 - __field( int, type ) 130 129 ), 131 130 132 131 TP_fast_assign(
+5
include/linux/regmap.h
··· 315 315 * masks are used. 316 316 * @zero_flag_mask: If set, read_flag_mask and write_flag_mask are used even 317 317 * if they are both empty. 318 + * @use_relaxed_mmio: If set, MMIO R/W operations will not use memory barriers. 319 + * This can avoid load on devices which don't require strict 320 + * orderings, but drivers should carefully add any explicit 321 + * memory barriers when they may require them. 318 322 * @use_single_read: If set, converts the bulk read operation into a series of 319 323 * single read operations. This is useful for a device that 320 324 * does not support bulk read. ··· 392 388 393 389 bool use_single_read; 394 390 bool use_single_write; 391 + bool use_relaxed_mmio; 395 392 bool can_multi_write; 396 393 397 394 enum regmap_endian reg_format_endian;
-7
sound/soc/codecs/Kconfig
··· 180 180 imply SND_SOC_RT700_SDW 181 181 imply SND_SOC_RT711_SDW 182 182 imply SND_SOC_RT715_SDW 183 - imply SND_SOC_RT715_SDCA_SDW 184 183 imply SND_SOC_RT1308_SDW 185 184 imply SND_SOC_SGTL5000 186 185 imply SND_SOC_SI476X ··· 1235 1236 depends on SOUNDWIRE 1236 1237 select SND_SOC_RT715 1237 1238 select REGMAP_SOUNDWIRE 1238 - 1239 - config SND_SOC_RT715_SDCA_SDW 1240 - tristate "Realtek RT715 SDCA Codec - SDW" 1241 - depends on SOUNDWIRE 1242 - select REGMAP_SOUNDWIRE 1243 - select REGMAP_SOUNDWIRE_MBQ 1244 1239 1245 1240 #Freescale sgtl5000 codec 1246 1241 config SND_SOC_SGTL5000
-2
sound/soc/codecs/Makefile
··· 194 194 snd-soc-rt700-objs := rt700.o rt700-sdw.o 195 195 snd-soc-rt711-objs := rt711.o rt711-sdw.o 196 196 snd-soc-rt715-objs := rt715.o rt715-sdw.o 197 - snd-soc-rt715-sdca-objs := rt715-sdca.o rt715-sdca-sdw.o 198 197 snd-soc-sgtl5000-objs := sgtl5000.o 199 198 snd-soc-alc5623-objs := alc5623.o 200 199 snd-soc-alc5632-objs := alc5632.o ··· 510 511 obj-$(CONFIG_SND_SOC_RT700) += snd-soc-rt700.o 511 512 obj-$(CONFIG_SND_SOC_RT711) += snd-soc-rt711.o 512 513 obj-$(CONFIG_SND_SOC_RT715) += snd-soc-rt715.o 513 - obj-$(CONFIG_SND_SOC_RT715_SDCA_SDW) += snd-soc-rt715-sdca.o 514 514 obj-$(CONFIG_SND_SOC_SGTL5000) += snd-soc-sgtl5000.o 515 515 obj-$(CONFIG_SND_SOC_SIGMADSP) += snd-soc-sigmadsp.o 516 516 obj-$(CONFIG_SND_SOC_SIGMADSP_I2C) += snd-soc-sigmadsp-i2c.o
-278
sound/soc/codecs/rt715-sdca-sdw.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - // 3 - // rt715-sdca-sdw.c -- rt715 ALSA SoC audio driver 4 - // 5 - // Copyright(c) 2020 Realtek Semiconductor Corp. 6 - // 7 - // 8 - 9 - #include <linux/delay.h> 10 - #include <linux/device.h> 11 - #include <linux/mod_devicetable.h> 12 - #include <linux/soundwire/sdw.h> 13 - #include <linux/soundwire/sdw_type.h> 14 - #include <linux/soundwire/sdw_registers.h> 15 - #include <linux/module.h> 16 - #include <linux/regmap.h> 17 - #include <sound/soc.h> 18 - #include "rt715-sdca.h" 19 - #include "rt715-sdca-sdw.h" 20 - 21 - static bool rt715_sdca_readable_register(struct device *dev, unsigned int reg) 22 - { 23 - switch (reg) { 24 - case 0x201a ... 0x2027: 25 - case 0x2029 ... 0x202a: 26 - case 0x202d ... 0x2034: 27 - case 0x2200 ... 0x2204: 28 - case 0x2206 ... 0x2212: 29 - case 0x2230 ... 0x2239: 30 - case 0x2f5b: 31 - case SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN, 32 - RT715_SDCA_SMPU_TRIG_ST_CTRL, CH_00): 33 - return true; 34 - default: 35 - return false; 36 - } 37 - } 38 - 39 - static bool rt715_sdca_volatile_register(struct device *dev, unsigned int reg) 40 - { 41 - switch (reg) { 42 - case 0x201b: 43 - case 0x201c: 44 - case 0x201d: 45 - case 0x201f: 46 - case 0x2021: 47 - case 0x2023: 48 - case 0x2230: 49 - case 0x202d ... 0x202f: /* BRA */ 50 - case 0x2200 ... 0x2212: /* i2c debug */ 51 - case 0x2f07: 52 - case 0x2f1b ... 0x2f1e: 53 - case 0x2f30 ... 0x2f34: 54 - case 0x2f50 ... 0x2f51: 55 - case 0x2f53 ... 0x2f59: 56 - case 0x2f5c ... 0x2f5f: 57 - case SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN, 58 - RT715_SDCA_SMPU_TRIG_ST_CTRL, CH_00): /* VAD Searching status */ 59 - return true; 60 - default: 61 - return false; 62 - } 63 - } 64 - 65 - static bool rt715_sdca_mbq_readable_register(struct device *dev, unsigned int reg) 66 - { 67 - switch (reg) { 68 - case 0x2000000: 69 - case 0x200002b: 70 - case 0x2000036: 71 - case 0x2000037: 72 - case 0x2000039: 73 - case 0x6100000: 74 - return true; 75 - default: 76 - return false; 77 - } 78 - } 79 - 80 - static bool rt715_sdca_mbq_volatile_register(struct device *dev, unsigned int reg) 81 - { 82 - switch (reg) { 83 - case 0x2000000: 84 - return true; 85 - default: 86 - return false; 87 - } 88 - } 89 - 90 - static const struct regmap_config rt715_sdca_regmap = { 91 - .reg_bits = 32, 92 - .val_bits = 8, 93 - .readable_reg = rt715_sdca_readable_register, 94 - .volatile_reg = rt715_sdca_volatile_register, 95 - .max_register = 0x43ffffff, 96 - .reg_defaults = rt715_reg_defaults_sdca, 97 - .num_reg_defaults = ARRAY_SIZE(rt715_reg_defaults_sdca), 98 - .cache_type = REGCACHE_RBTREE, 99 - .use_single_read = true, 100 - .use_single_write = true, 101 - }; 102 - 103 - static const struct regmap_config rt715_sdca_mbq_regmap = { 104 - .name = "sdw-mbq", 105 - .reg_bits = 32, 106 - .val_bits = 16, 107 - .readable_reg = rt715_sdca_mbq_readable_register, 108 - .volatile_reg = rt715_sdca_mbq_volatile_register, 109 - .max_register = 0x43ffffff, 110 - .reg_defaults = rt715_mbq_reg_defaults_sdca, 111 - .num_reg_defaults = ARRAY_SIZE(rt715_mbq_reg_defaults_sdca), 112 - .cache_type = REGCACHE_RBTREE, 113 - .use_single_read = true, 114 - .use_single_write = true, 115 - }; 116 - 117 - static int rt715_update_status(struct sdw_slave *slave, 118 - enum sdw_slave_status status) 119 - { 120 - struct rt715_sdca_priv *rt715 = dev_get_drvdata(&slave->dev); 121 - 122 - /* Update the status */ 123 - rt715->status = status; 124 - 125 - /* 126 - * Perform initialization only if slave status is present and 127 - * hw_init flag is false 128 - */ 129 - if (rt715->hw_init || rt715->status != SDW_SLAVE_ATTACHED) 130 - return 0; 131 - 132 - /* perform I/O transfers required for Slave initialization */ 133 - return rt715_io_init(&slave->dev, slave); 134 - } 135 - 136 - static int rt715_read_prop(struct sdw_slave *slave) 137 - { 138 - struct sdw_slave_prop *prop = &slave->prop; 139 - int nval, i; 140 - u32 bit; 141 - unsigned long addr; 142 - struct sdw_dpn_prop *dpn; 143 - 144 - prop->paging_support = true; 145 - 146 - /* first we need to allocate memory for set bits in port lists */ 147 - prop->source_ports = 0x50;/* BITMAP: 01010000 */ 148 - prop->sink_ports = 0x0; /* BITMAP: 00000000 */ 149 - 150 - nval = hweight32(prop->source_ports); 151 - prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval, 152 - sizeof(*prop->src_dpn_prop), 153 - GFP_KERNEL); 154 - if (!prop->src_dpn_prop) 155 - return -ENOMEM; 156 - 157 - dpn = prop->src_dpn_prop; 158 - i = 0; 159 - addr = prop->source_ports; 160 - for_each_set_bit(bit, &addr, 32) { 161 - dpn[i].num = bit; 162 - dpn[i].simple_ch_prep_sm = true; 163 - dpn[i].ch_prep_timeout = 10; 164 - i++; 165 - } 166 - 167 - /* set the timeout values */ 168 - prop->clk_stop_timeout = 20; 169 - 170 - return 0; 171 - } 172 - 173 - static struct sdw_slave_ops rt715_sdca_slave_ops = { 174 - .read_prop = rt715_read_prop, 175 - .update_status = rt715_update_status, 176 - }; 177 - 178 - static int rt715_sdca_sdw_probe(struct sdw_slave *slave, 179 - const struct sdw_device_id *id) 180 - { 181 - struct regmap *mbq_regmap, *regmap; 182 - 183 - slave->ops = &rt715_sdca_slave_ops; 184 - 185 - /* Regmap Initialization */ 186 - mbq_regmap = devm_regmap_init_sdw_mbq(slave, &rt715_sdca_mbq_regmap); 187 - if (!mbq_regmap) 188 - return -EINVAL; 189 - 190 - regmap = devm_regmap_init_sdw(slave, &rt715_sdca_regmap); 191 - if (!regmap) 192 - return -EINVAL; 193 - 194 - return rt715_init(&slave->dev, mbq_regmap, regmap, slave); 195 - } 196 - 197 - static const struct sdw_device_id rt715_sdca_id[] = { 198 - SDW_SLAVE_ENTRY_EXT(0x025d, 0x715, 0x3, 0x1, 0), 199 - SDW_SLAVE_ENTRY_EXT(0x025d, 0x714, 0x3, 0x1, 0), 200 - {}, 201 - }; 202 - MODULE_DEVICE_TABLE(sdw, rt715_sdca_id); 203 - 204 - static int __maybe_unused rt715_dev_suspend(struct device *dev) 205 - { 206 - struct rt715_sdca_priv *rt715 = dev_get_drvdata(dev); 207 - 208 - if (!rt715->hw_init) 209 - return 0; 210 - 211 - regcache_cache_only(rt715->regmap, true); 212 - regcache_mark_dirty(rt715->regmap); 213 - regcache_cache_only(rt715->mbq_regmap, true); 214 - regcache_mark_dirty(rt715->mbq_regmap); 215 - 216 - return 0; 217 - } 218 - 219 - #define RT715_PROBE_TIMEOUT 2000 220 - 221 - static int __maybe_unused rt715_dev_resume(struct device *dev) 222 - { 223 - struct sdw_slave *slave = dev_to_sdw_dev(dev); 224 - struct rt715_sdca_priv *rt715 = dev_get_drvdata(dev); 225 - unsigned long time; 226 - 227 - if (!rt715->hw_init) 228 - return 0; 229 - 230 - if (!slave->unattach_request) 231 - goto regmap_sync; 232 - 233 - time = wait_for_completion_timeout(&slave->enumeration_complete, 234 - msecs_to_jiffies(RT715_PROBE_TIMEOUT)); 235 - if (!time) { 236 - dev_err(&slave->dev, "Enumeration not complete, timed out\n"); 237 - return -ETIMEDOUT; 238 - } 239 - 240 - regmap_sync: 241 - slave->unattach_request = 0; 242 - regcache_cache_only(rt715->regmap, false); 243 - regcache_sync_region(rt715->regmap, 244 - SDW_SDCA_CTL(FUN_JACK_CODEC, RT715_SDCA_ST_EN, RT715_SDCA_ST_CTRL, 245 - CH_00), 246 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN, 247 - RT715_SDCA_SMPU_TRIG_ST_CTRL, CH_00)); 248 - regcache_cache_only(rt715->mbq_regmap, false); 249 - regcache_sync_region(rt715->mbq_regmap, 0x2000000, 0x61020ff); 250 - regcache_sync_region(rt715->mbq_regmap, 251 - SDW_SDCA_CTL(FUN_JACK_CODEC, RT715_SDCA_ST_EN, RT715_SDCA_ST_CTRL, 252 - CH_00), 253 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN, 254 - RT715_SDCA_SMPU_TRIG_ST_CTRL, CH_00)); 255 - 256 - return 0; 257 - } 258 - 259 - static const struct dev_pm_ops rt715_pm = { 260 - SET_SYSTEM_SLEEP_PM_OPS(rt715_dev_suspend, rt715_dev_resume) 261 - SET_RUNTIME_PM_OPS(rt715_dev_suspend, rt715_dev_resume, NULL) 262 - }; 263 - 264 - static struct sdw_driver rt715_sdw_driver = { 265 - .driver = { 266 - .name = "rt715-sdca", 267 - .owner = THIS_MODULE, 268 - .pm = &rt715_pm, 269 - }, 270 - .probe = rt715_sdca_sdw_probe, 271 - .ops = &rt715_sdca_slave_ops, 272 - .id_table = rt715_sdca_id, 273 - }; 274 - module_sdw_driver(rt715_sdw_driver); 275 - 276 - MODULE_DESCRIPTION("ASoC RT715 driver SDW SDCA"); 277 - MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>"); 278 - MODULE_LICENSE("GPL v2");
-170
sound/soc/codecs/rt715-sdca-sdw.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * rt715-sdca-sdw.h -- RT715 ALSA SoC audio driver header 4 - * 5 - * Copyright(c) 2020 Realtek Semiconductor Corp. 6 - */ 7 - 8 - #ifndef __RT715_SDW_SDCA_H__ 9 - #define __RT715_SDW_SDCA_H__ 10 - 11 - #include <linux/soundwire/sdw_registers.h> 12 - 13 - static const struct reg_default rt715_reg_defaults_sdca[] = { 14 - { 0x201a, 0x00 }, 15 - { 0x201e, 0x00 }, 16 - { 0x2020, 0x00 }, 17 - { 0x2021, 0x00 }, 18 - { 0x2022, 0x00 }, 19 - { 0x2023, 0x00 }, 20 - { 0x2024, 0x00 }, 21 - { 0x2025, 0x01 }, 22 - { 0x2026, 0x00 }, 23 - { 0x2027, 0x00 }, 24 - { 0x2029, 0x00 }, 25 - { 0x202a, 0x00 }, 26 - { 0x202d, 0x00 }, 27 - { 0x202e, 0x00 }, 28 - { 0x202f, 0x00 }, 29 - { 0x2030, 0x00 }, 30 - { 0x2031, 0x00 }, 31 - { 0x2032, 0x00 }, 32 - { 0x2033, 0x00 }, 33 - { 0x2034, 0x00 }, 34 - { 0x2230, 0x00 }, 35 - { 0x2231, 0x2f }, 36 - { 0x2232, 0x80 }, 37 - { 0x2233, 0x00 }, 38 - { 0x2234, 0x00 }, 39 - { 0x2235, 0x00 }, 40 - { 0x2236, 0x00 }, 41 - { 0x2237, 0x00 }, 42 - { 0x2238, 0x00 }, 43 - { 0x2239, 0x00 }, 44 - { 0x2f01, 0x00 }, 45 - { 0x2f02, 0x09 }, 46 - { 0x2f03, 0x0b }, 47 - { 0x2f04, 0x00 }, 48 - { 0x2f05, 0x0e }, 49 - { 0x2f06, 0x01 }, 50 - { 0x2f08, 0x00 }, 51 - { 0x2f09, 0x00 }, 52 - { 0x2f0a, 0x00 }, 53 - { 0x2f0b, 0x00 }, 54 - { 0x2f0c, 0x00 }, 55 - { 0x2f0d, 0x00 }, 56 - { 0x2f0e, 0x12 }, 57 - { 0x2f0f, 0x00 }, 58 - { 0x2f10, 0x00 }, 59 - { 0x2f11, 0x00 }, 60 - { 0x2f12, 0x00 }, 61 - { 0x2f13, 0x00 }, 62 - { 0x2f14, 0x00 }, 63 - { 0x2f15, 0x00 }, 64 - { 0x2f16, 0x00 }, 65 - { 0x2f17, 0x00 }, 66 - { 0x2f18, 0x00 }, 67 - { 0x2f19, 0x03 }, 68 - { 0x2f1a, 0x00 }, 69 - { 0x2f1f, 0x10 }, 70 - { 0x2f20, 0x00 }, 71 - { 0x2f21, 0x00 }, 72 - { 0x2f22, 0x00 }, 73 - { 0x2f23, 0x00 }, 74 - { 0x2f24, 0x00 }, 75 - { 0x2f25, 0x00 }, 76 - { 0x2f52, 0x01 }, 77 - { 0x2f5a, 0x02 }, 78 - { 0x2f5b, 0x05 }, 79 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CX_CLK_SEL_EN, 80 - RT715_SDCA_CX_CLK_SEL_CTRL, CH_00), 0x1 }, 81 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 82 - RT715_SDCA_FU_MUTE_CTRL, CH_01), 0x01 }, 83 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 84 - RT715_SDCA_FU_MUTE_CTRL, CH_02), 0x01 }, 85 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 86 - RT715_SDCA_FU_MUTE_CTRL, CH_03), 0x01 }, 87 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 88 - RT715_SDCA_FU_MUTE_CTRL, CH_04), 0x01 }, 89 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 90 - RT715_SDCA_FU_MUTE_CTRL, CH_01), 0x01 }, 91 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 92 - RT715_SDCA_FU_MUTE_CTRL, CH_02), 0x01 }, 93 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 94 - RT715_SDCA_FU_MUTE_CTRL, CH_03), 0x01 }, 95 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 96 - RT715_SDCA_FU_MUTE_CTRL, CH_04), 0x01 }, 97 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL, 98 - RT715_SDCA_FU_MUTE_CTRL, CH_01), 0x01 }, 99 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL, 100 - RT715_SDCA_FU_MUTE_CTRL, CH_02), 0x01 }, 101 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN, 102 - RT715_SDCA_SMPU_TRIG_EN_CTRL, CH_00), 0x02 }, 103 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN, 104 - RT715_SDCA_SMPU_TRIG_ST_CTRL, CH_00), 0x00 }, 105 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL, 106 - RT715_SDCA_FU_MUTE_CTRL, CH_01), 0x01 }, 107 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL, 108 - RT715_SDCA_FU_MUTE_CTRL, CH_02), 0x01 }, 109 - }; 110 - 111 - static const struct reg_default rt715_mbq_reg_defaults_sdca[] = { 112 - { 0x200002b, 0x0420 }, 113 - { 0x2000036, 0x0000 }, 114 - { 0x2000037, 0x0000 }, 115 - { 0x2000039, 0xaa81 }, 116 - { 0x6100000, 0x0100 }, 117 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 118 - RT715_SDCA_FU_VOL_CTRL, CH_01), 0x00 }, 119 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 120 - RT715_SDCA_FU_VOL_CTRL, CH_02), 0x00 }, 121 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 122 - RT715_SDCA_FU_VOL_CTRL, CH_03), 0x00 }, 123 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 124 - RT715_SDCA_FU_VOL_CTRL, CH_04), 0x00 }, 125 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 126 - RT715_SDCA_FU_VOL_CTRL, CH_01), 0x00 }, 127 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 128 - RT715_SDCA_FU_VOL_CTRL, CH_02), 0x00 }, 129 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 130 - RT715_SDCA_FU_VOL_CTRL, CH_03), 0x00 }, 131 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 132 - RT715_SDCA_FU_VOL_CTRL, CH_04), 0x00 }, 133 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL, 134 - RT715_SDCA_FU_VOL_CTRL, CH_01), 0x00 }, 135 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL, 136 - RT715_SDCA_FU_VOL_CTRL, CH_02), 0x00 }, 137 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 138 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_01), 0x00 }, 139 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 140 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_02), 0x00 }, 141 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 142 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_03), 0x00 }, 143 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 144 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_04), 0x00 }, 145 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 146 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_05), 0x00 }, 147 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 148 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_06), 0x00 }, 149 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 150 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_07), 0x00 }, 151 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 152 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_08), 0x00 }, 153 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 154 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_01), 0x00 }, 155 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 156 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_02), 0x00 }, 157 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 158 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_03), 0x00 }, 159 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 160 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_04), 0x00 }, 161 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 162 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_05), 0x00 }, 163 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 164 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_06), 0x00 }, 165 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 166 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_07), 0x00 }, 167 - { SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 168 - RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_08), 0x00 }, 169 - }; 170 - #endif /* __RT715_SDW_SDCA_H__ */
-936
sound/soc/codecs/rt715-sdca.c
··· 1 - // SPDX-License-Identifier: GPL-2.0-only 2 - // 3 - // rt715-sdca.c -- rt715 ALSA SoC audio driver 4 - // 5 - // Copyright(c) 2020 Realtek Semiconductor Corp. 6 - // 7 - // 8 - // 9 - 10 - #include <linux/module.h> 11 - #include <linux/moduleparam.h> 12 - #include <linux/version.h> 13 - #include <linux/kernel.h> 14 - #include <linux/init.h> 15 - #include <linux/pm_runtime.h> 16 - #include <linux/pm.h> 17 - #include <linux/soundwire/sdw.h> 18 - #include <linux/regmap.h> 19 - #include <linux/slab.h> 20 - #include <linux/platform_device.h> 21 - #include <sound/core.h> 22 - #include <sound/pcm.h> 23 - #include <sound/pcm_params.h> 24 - #include <sound/soc.h> 25 - #include <sound/soc-dapm.h> 26 - #include <sound/initval.h> 27 - #include <sound/tlv.h> 28 - #include <linux/soundwire/sdw_registers.h> 29 - 30 - #include "rt715-sdca.h" 31 - 32 - static int rt715_index_write(struct rt715_sdca_priv *rt715, unsigned int nid, 33 - unsigned int reg, unsigned int value) 34 - { 35 - struct regmap *regmap = rt715->mbq_regmap; 36 - unsigned int addr; 37 - int ret; 38 - 39 - addr = (nid << 20) | reg; 40 - 41 - ret = regmap_write(regmap, addr, value); 42 - if (ret < 0) 43 - dev_err(&rt715->slave->dev, 44 - "Failed to set private value: %08x <= %04x %d\n", ret, addr, 45 - value); 46 - 47 - return ret; 48 - } 49 - 50 - static int rt715_index_read(struct rt715_sdca_priv *rt715, 51 - unsigned int nid, unsigned int reg, unsigned int *value) 52 - { 53 - struct regmap *regmap = rt715->mbq_regmap; 54 - unsigned int addr; 55 - int ret; 56 - 57 - addr = (nid << 20) | reg; 58 - 59 - ret = regmap_read(regmap, addr, value); 60 - if (ret < 0) 61 - dev_err(&rt715->slave->dev, 62 - "Failed to get private value: %06x => %04x ret=%d\n", 63 - addr, *value, ret); 64 - 65 - return ret; 66 - } 67 - 68 - static int rt715_index_update_bits(struct rt715_sdca_priv *rt715, 69 - unsigned int nid, unsigned int reg, unsigned int mask, unsigned int val) 70 - { 71 - unsigned int tmp; 72 - int ret; 73 - 74 - ret = rt715_index_read(rt715, nid, reg, &tmp); 75 - if (ret < 0) 76 - return ret; 77 - 78 - set_mask_bits(&tmp, mask, val); 79 - 80 - return rt715_index_write(rt715, nid, reg, tmp); 81 - } 82 - 83 - /* SDCA Volume/Boost control */ 84 - static int rt715_set_amp_gain_put_sdca(struct snd_kcontrol *kcontrol, 85 - struct snd_ctl_elem_value *ucontrol) 86 - { 87 - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 88 - struct soc_mixer_control *mc = 89 - (struct soc_mixer_control *)kcontrol->private_value; 90 - struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component); 91 - unsigned int val_l, val_r, gain_l_val, gain_r_val; 92 - int ret; 93 - 94 - /* control value to 2s complement */ 95 - /* L channel */ 96 - gain_l_val = ucontrol->value.integer.value[0]; 97 - if (gain_l_val > mc->max) 98 - gain_l_val = mc->max; 99 - val_l = gain_l_val; 100 - 101 - if (mc->shift == 8) { 102 - gain_l_val = (gain_l_val * 10) << mc->shift; 103 - } else { 104 - gain_l_val = 105 - ((abs(gain_l_val - mc->shift) * RT715_SDCA_DB_STEP) << 8) / 1000; 106 - if (val_l <= mc->shift) { 107 - gain_l_val = ~gain_l_val; 108 - gain_l_val += 1; 109 - } 110 - gain_l_val &= 0xffff; 111 - } 112 - 113 - /* R channel */ 114 - gain_r_val = ucontrol->value.integer.value[1]; 115 - if (gain_r_val > mc->max) 116 - gain_r_val = mc->max; 117 - val_r = gain_r_val; 118 - 119 - if (mc->shift == 8) { 120 - gain_r_val = (gain_r_val * 10) << mc->shift; 121 - } else { 122 - gain_r_val = 123 - ((abs(gain_r_val - mc->shift) * RT715_SDCA_DB_STEP) << 8) / 1000; 124 - if (val_r <= mc->shift) { 125 - gain_r_val = ~gain_r_val; 126 - gain_r_val += 1; 127 - } 128 - gain_r_val &= 0xffff; 129 - } 130 - 131 - /* Lch*/ 132 - ret = regmap_write(rt715->mbq_regmap, mc->reg, gain_l_val); 133 - if (ret != 0) { 134 - dev_err(component->dev, "Failed to write 0x%x=0x%x\n", mc->reg, 135 - gain_l_val); 136 - return ret; 137 - } 138 - /* Rch */ 139 - ret = regmap_write(rt715->mbq_regmap, mc->rreg, gain_r_val); 140 - if (ret != 0) { 141 - dev_err(component->dev, "Failed to write 0x%x=0x%x\n", mc->rreg, 142 - gain_r_val); 143 - return ret; 144 - } 145 - 146 - return 0; 147 - } 148 - 149 - static int rt715_set_amp_gain_get_sdca(struct snd_kcontrol *kcontrol, 150 - struct snd_ctl_elem_value *ucontrol) 151 - { 152 - struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 153 - struct soc_mixer_control *mc = 154 - (struct soc_mixer_control *)kcontrol->private_value; 155 - struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component); 156 - unsigned int val_l, val_r, ctl_l, ctl_r, neg_flag = 0; 157 - int ret; 158 - 159 - ret = regmap_read(rt715->mbq_regmap, mc->reg, &val_l); 160 - if (ret < 0) 161 - dev_err(component->dev, "Failed to read 0x%x, ret=%d\n", mc->reg, ret); 162 - ret = regmap_read(rt715->mbq_regmap, mc->rreg, &val_r); 163 - if (ret < 0) 164 - dev_err(component->dev, "Failed to read 0x%x, ret=%d\n", mc->rreg, 165 - ret); 166 - 167 - /* L channel */ 168 - if (mc->shift == 8) { 169 - ctl_l = (val_l >> mc->shift) / 10; 170 - } else { 171 - ctl_l = val_l; 172 - if (ctl_l & BIT(15)) { 173 - ctl_l = ~(val_l - 1) & 0xffff; 174 - neg_flag = 1; 175 - } 176 - ctl_l *= 1000; 177 - ctl_l >>= 8; 178 - if (neg_flag) 179 - ctl_l = mc->shift - ctl_l / RT715_SDCA_DB_STEP; 180 - else 181 - ctl_l = mc->shift + ctl_l / RT715_SDCA_DB_STEP; 182 - } 183 - 184 - neg_flag = 0; 185 - /* R channel */ 186 - if (mc->shift == 8) { 187 - ctl_r = (val_r >> mc->shift) / 10; 188 - } else { 189 - ctl_r = val_r; 190 - if (ctl_r & BIT(15)) { 191 - ctl_r = ~(val_r - 1) & 0xffff; 192 - neg_flag = 1; 193 - } 194 - ctl_r *= 1000; 195 - ctl_r >>= 8; 196 - if (neg_flag) 197 - ctl_r = mc->shift - ctl_r / RT715_SDCA_DB_STEP; 198 - else 199 - ctl_r = mc->shift + ctl_r / RT715_SDCA_DB_STEP; 200 - } 201 - 202 - ucontrol->value.integer.value[0] = ctl_l; 203 - ucontrol->value.integer.value[1] = ctl_r; 204 - 205 - return 0; 206 - } 207 - 208 - static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -17625, 375, 0); 209 - static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); 210 - 211 - #define SOC_DOUBLE_R_EXT(xname, reg_left, reg_right, xshift, xmax, xinvert,\ 212 - xhandler_get, xhandler_put) \ 213 - { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ 214 - .info = snd_soc_info_volsw, \ 215 - .get = xhandler_get, .put = xhandler_put, \ 216 - .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \ 217 - xmax, xinvert) } 218 - 219 - static const struct snd_kcontrol_new rt715_snd_controls_sdca[] = { 220 - /* Capture switch */ 221 - SOC_DOUBLE_R("FU0A Capture Switch", 222 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL, 223 - RT715_SDCA_FU_MUTE_CTRL, CH_01), 224 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL, 225 - RT715_SDCA_FU_MUTE_CTRL, CH_02), 226 - 0, 1, 1), 227 - SOC_DOUBLE_R("FU02 1_2 Capture Switch", 228 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 229 - RT715_SDCA_FU_MUTE_CTRL, CH_01), 230 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 231 - RT715_SDCA_FU_MUTE_CTRL, CH_02), 232 - 0, 1, 1), 233 - SOC_DOUBLE_R("FU02 3_4 Capture Switch", 234 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 235 - RT715_SDCA_FU_MUTE_CTRL, CH_03), 236 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 237 - RT715_SDCA_FU_MUTE_CTRL, CH_04), 238 - 0, 1, 1), 239 - SOC_DOUBLE_R("FU06 1_2 Capture Switch", 240 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 241 - RT715_SDCA_FU_MUTE_CTRL, CH_01), 242 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 243 - RT715_SDCA_FU_MUTE_CTRL, CH_02), 244 - 0, 1, 1), 245 - SOC_DOUBLE_R("FU06 3_4 Capture Switch", 246 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 247 - RT715_SDCA_FU_MUTE_CTRL, CH_03), 248 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 249 - RT715_SDCA_FU_MUTE_CTRL, CH_04), 250 - 0, 1, 1), 251 - /* Volume Control */ 252 - SOC_DOUBLE_R_EXT_TLV("FU0A Capture Volume", 253 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL, 254 - RT715_SDCA_FU_VOL_CTRL, CH_01), 255 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL, 256 - RT715_SDCA_FU_VOL_CTRL, CH_02), 257 - 0x2f, 0x7f, 0, 258 - rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca, 259 - in_vol_tlv), 260 - SOC_DOUBLE_R_EXT_TLV("FU02 1_2 Capture Volume", 261 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 262 - RT715_SDCA_FU_VOL_CTRL, CH_01), 263 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 264 - RT715_SDCA_FU_VOL_CTRL, CH_02), 265 - 0x2f, 0x7f, 0, 266 - rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca, 267 - in_vol_tlv), 268 - SOC_DOUBLE_R_EXT_TLV("FU02 3_4 Capture Volume", 269 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 270 - RT715_SDCA_FU_VOL_CTRL, 271 - CH_03), 272 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL, 273 - RT715_SDCA_FU_VOL_CTRL, 274 - CH_04), 0x2f, 0x7f, 0, 275 - rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca, 276 - in_vol_tlv), 277 - SOC_DOUBLE_R_EXT_TLV("FU06 1_2 Capture Volume", 278 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 279 - RT715_SDCA_FU_VOL_CTRL, 280 - CH_01), 281 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 282 - RT715_SDCA_FU_VOL_CTRL, 283 - CH_02), 0x2f, 0x7f, 0, 284 - rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca, 285 - in_vol_tlv), 286 - SOC_DOUBLE_R_EXT_TLV("FU06 3_4 Capture Volume", 287 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 288 - RT715_SDCA_FU_VOL_CTRL, 289 - CH_03), 290 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL, 291 - RT715_SDCA_FU_VOL_CTRL, 292 - CH_04), 0x2f, 0x7f, 0, 293 - rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca, 294 - in_vol_tlv), 295 - /* MIC Boost Control */ 296 - SOC_DOUBLE_R_EXT_TLV("FU0E 1_2 Boost", 297 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 298 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 299 - CH_01), 300 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 301 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 302 - CH_02), 8, 3, 0, 303 - rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca, 304 - mic_vol_tlv), 305 - SOC_DOUBLE_R_EXT_TLV("FU0E 3_4 Boost", 306 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 307 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 308 - CH_03), 309 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 310 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 311 - CH_04), 8, 3, 0, 312 - rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca, 313 - mic_vol_tlv), 314 - SOC_DOUBLE_R_EXT_TLV("FU0E 5_6 Boost", 315 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 316 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 317 - CH_05), 318 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 319 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 320 - CH_06), 8, 3, 0, 321 - rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca, 322 - mic_vol_tlv), 323 - SOC_DOUBLE_R_EXT_TLV("FU0E 7_8 Boost", 324 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 325 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 326 - CH_07), 327 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN, 328 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 329 - CH_08), 8, 3, 0, 330 - rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca, 331 - mic_vol_tlv), 332 - SOC_DOUBLE_R_EXT_TLV("FU0C 1_2 Boost", 333 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 334 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 335 - CH_01), 336 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 337 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 338 - CH_02), 8, 3, 0, 339 - rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca, 340 - mic_vol_tlv), 341 - SOC_DOUBLE_R_EXT_TLV("FU0C 3_4 Boost", 342 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 343 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 344 - CH_03), 345 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 346 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 347 - CH_04), 8, 3, 0, 348 - rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca, 349 - mic_vol_tlv), 350 - SOC_DOUBLE_R_EXT_TLV("FU0C 5_6 Boost", 351 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 352 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 353 - CH_05), 354 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 355 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 356 - CH_06), 8, 3, 0, 357 - rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca, 358 - mic_vol_tlv), 359 - SOC_DOUBLE_R_EXT_TLV("FU0C 7_8 Boost", 360 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 361 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 362 - CH_07), 363 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN, 364 - RT715_SDCA_FU_DMIC_GAIN_CTRL, 365 - CH_08), 8, 3, 0, 366 - rt715_set_amp_gain_get_sdca, rt715_set_amp_gain_put_sdca, 367 - mic_vol_tlv), 368 - }; 369 - 370 - static int rt715_mux_get(struct snd_kcontrol *kcontrol, 371 - struct snd_ctl_elem_value *ucontrol) 372 - { 373 - struct snd_soc_component *component = 374 - snd_soc_dapm_kcontrol_component(kcontrol); 375 - struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component); 376 - unsigned int val, mask_sft; 377 - 378 - if (strstr(ucontrol->id.name, "ADC 22 Mux")) 379 - mask_sft = 12; 380 - else if (strstr(ucontrol->id.name, "ADC 23 Mux")) 381 - mask_sft = 8; 382 - else if (strstr(ucontrol->id.name, "ADC 24 Mux")) 383 - mask_sft = 4; 384 - else if (strstr(ucontrol->id.name, "ADC 25 Mux")) 385 - mask_sft = 0; 386 - else 387 - return -EINVAL; 388 - 389 - rt715_index_read(rt715, RT715_VENDOR_HDA_CTL, 390 - RT715_HDA_LEGACY_MUX_CTL1, &val); 391 - val = (val >> mask_sft) & 0xf; 392 - 393 - /* 394 - * The first two indices of ADC Mux 24/25 are routed to the same 395 - * hardware source. ie, ADC Mux 24 0/1 will both connect to MIC2. 396 - * To have a unique set of inputs, we skip the index1 of the muxes. 397 - */ 398 - if ((strstr(ucontrol->id.name, "ADC 24 Mux") || 399 - strstr(ucontrol->id.name, "ADC 25 Mux")) && val > 0) 400 - val -= 1; 401 - ucontrol->value.enumerated.item[0] = val; 402 - 403 - return 0; 404 - } 405 - 406 - static int rt715_mux_put(struct snd_kcontrol *kcontrol, 407 - struct snd_ctl_elem_value *ucontrol) 408 - { 409 - struct snd_soc_component *component = 410 - snd_soc_dapm_kcontrol_component(kcontrol); 411 - struct snd_soc_dapm_context *dapm = 412 - snd_soc_dapm_kcontrol_dapm(kcontrol); 413 - struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component); 414 - struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 415 - unsigned int *item = ucontrol->value.enumerated.item; 416 - unsigned int val, val2 = 0, change, mask_sft; 417 - 418 - if (item[0] >= e->items) 419 - return -EINVAL; 420 - 421 - if (strstr(ucontrol->id.name, "ADC 22 Mux")) 422 - mask_sft = 12; 423 - else if (strstr(ucontrol->id.name, "ADC 23 Mux")) 424 - mask_sft = 8; 425 - else if (strstr(ucontrol->id.name, "ADC 24 Mux")) 426 - mask_sft = 4; 427 - else if (strstr(ucontrol->id.name, "ADC 25 Mux")) 428 - mask_sft = 0; 429 - else 430 - return -EINVAL; 431 - 432 - /* Verb ID = 0x701h, nid = e->reg */ 433 - val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l; 434 - 435 - rt715_index_read(rt715, RT715_VENDOR_HDA_CTL, 436 - RT715_HDA_LEGACY_MUX_CTL1, &val2); 437 - val2 = (val2 >> mask_sft) & 0xf; 438 - 439 - change = val != val2; 440 - 441 - if (change) 442 - rt715_index_update_bits(rt715, RT715_VENDOR_HDA_CTL, 443 - RT715_HDA_LEGACY_MUX_CTL1, 0xf << mask_sft, val << mask_sft); 444 - 445 - snd_soc_dapm_mux_update_power(dapm, kcontrol, item[0], e, NULL); 446 - 447 - return change; 448 - } 449 - 450 - static const char * const adc_22_23_mux_text[] = { 451 - "MIC1", 452 - "MIC2", 453 - "LINE1", 454 - "LINE2", 455 - "DMIC1", 456 - "DMIC2", 457 - "DMIC3", 458 - "DMIC4", 459 - }; 460 - 461 - /* 462 - * Due to mux design for nid 24 (MUX_IN3)/25 (MUX_IN4), connection index 0 and 463 - * 1 will be connected to the same dmic source, therefore we skip index 1 to 464 - * avoid misunderstanding on usage of dapm routing. 465 - */ 466 - static int rt715_adc_24_25_values[] = { 467 - 0, 468 - 2, 469 - 3, 470 - 4, 471 - 5, 472 - }; 473 - 474 - static const char * const adc_24_mux_text[] = { 475 - "MIC2", 476 - "DMIC1", 477 - "DMIC2", 478 - "DMIC3", 479 - "DMIC4", 480 - }; 481 - 482 - static const char * const adc_25_mux_text[] = { 483 - "MIC1", 484 - "DMIC1", 485 - "DMIC2", 486 - "DMIC3", 487 - "DMIC4", 488 - }; 489 - 490 - static SOC_ENUM_SINGLE_DECL(rt715_adc22_enum, SND_SOC_NOPM, 0, 491 - adc_22_23_mux_text); 492 - 493 - static SOC_ENUM_SINGLE_DECL(rt715_adc23_enum, SND_SOC_NOPM, 0, 494 - adc_22_23_mux_text); 495 - 496 - static SOC_VALUE_ENUM_SINGLE_DECL(rt715_adc24_enum, 497 - SND_SOC_NOPM, 0, 0xf, 498 - adc_24_mux_text, rt715_adc_24_25_values); 499 - static SOC_VALUE_ENUM_SINGLE_DECL(rt715_adc25_enum, 500 - SND_SOC_NOPM, 0, 0xf, 501 - adc_25_mux_text, rt715_adc_24_25_values); 502 - 503 - static const struct snd_kcontrol_new rt715_adc22_mux = 504 - SOC_DAPM_ENUM_EXT("ADC 22 Mux", rt715_adc22_enum, 505 - rt715_mux_get, rt715_mux_put); 506 - 507 - static const struct snd_kcontrol_new rt715_adc23_mux = 508 - SOC_DAPM_ENUM_EXT("ADC 23 Mux", rt715_adc23_enum, 509 - rt715_mux_get, rt715_mux_put); 510 - 511 - static const struct snd_kcontrol_new rt715_adc24_mux = 512 - SOC_DAPM_ENUM_EXT("ADC 24 Mux", rt715_adc24_enum, 513 - rt715_mux_get, rt715_mux_put); 514 - 515 - static const struct snd_kcontrol_new rt715_adc25_mux = 516 - SOC_DAPM_ENUM_EXT("ADC 25 Mux", rt715_adc25_enum, 517 - rt715_mux_get, rt715_mux_put); 518 - 519 - static int rt715_pde23_24_event(struct snd_soc_dapm_widget *w, 520 - struct snd_kcontrol *kcontrol, int event) 521 - { 522 - struct snd_soc_component *component = 523 - snd_soc_dapm_to_component(w->dapm); 524 - struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component); 525 - 526 - switch (event) { 527 - case SND_SOC_DAPM_POST_PMU: 528 - regmap_write(rt715->regmap, 529 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CREQ_POW_EN, 530 - RT715_SDCA_REQ_POW_CTRL, 531 - CH_00), 0x00); 532 - break; 533 - case SND_SOC_DAPM_PRE_PMD: 534 - regmap_write(rt715->regmap, 535 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CREQ_POW_EN, 536 - RT715_SDCA_REQ_POW_CTRL, 537 - CH_00), 0x03); 538 - break; 539 - } 540 - return 0; 541 - } 542 - 543 - static const struct snd_soc_dapm_widget rt715_dapm_widgets[] = { 544 - SND_SOC_DAPM_INPUT("DMIC1"), 545 - SND_SOC_DAPM_INPUT("DMIC2"), 546 - SND_SOC_DAPM_INPUT("DMIC3"), 547 - SND_SOC_DAPM_INPUT("DMIC4"), 548 - SND_SOC_DAPM_INPUT("MIC1"), 549 - SND_SOC_DAPM_INPUT("MIC2"), 550 - SND_SOC_DAPM_INPUT("LINE1"), 551 - SND_SOC_DAPM_INPUT("LINE2"), 552 - 553 - SND_SOC_DAPM_SUPPLY("PDE23_24", SND_SOC_NOPM, 0, 0, 554 - rt715_pde23_24_event, 555 - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 556 - 557 - SND_SOC_DAPM_ADC("ADC 07", NULL, SND_SOC_NOPM, 4, 0), 558 - SND_SOC_DAPM_ADC("ADC 08", NULL, SND_SOC_NOPM, 4, 0), 559 - SND_SOC_DAPM_ADC("ADC 09", NULL, SND_SOC_NOPM, 4, 0), 560 - SND_SOC_DAPM_ADC("ADC 27", NULL, SND_SOC_NOPM, 4, 0), 561 - SND_SOC_DAPM_MUX("ADC 22 Mux", SND_SOC_NOPM, 0, 0, 562 - &rt715_adc22_mux), 563 - SND_SOC_DAPM_MUX("ADC 23 Mux", SND_SOC_NOPM, 0, 0, 564 - &rt715_adc23_mux), 565 - SND_SOC_DAPM_MUX("ADC 24 Mux", SND_SOC_NOPM, 0, 0, 566 - &rt715_adc24_mux), 567 - SND_SOC_DAPM_MUX("ADC 25 Mux", SND_SOC_NOPM, 0, 0, 568 - &rt715_adc25_mux), 569 - SND_SOC_DAPM_AIF_OUT("DP4TX", "DP4 Capture", 0, SND_SOC_NOPM, 0, 0), 570 - SND_SOC_DAPM_AIF_OUT("DP6TX", "DP6 Capture", 0, SND_SOC_NOPM, 0, 0), 571 - }; 572 - 573 - static const struct snd_soc_dapm_route rt715_audio_map[] = { 574 - {"DP6TX", NULL, "ADC 09"}, 575 - {"DP6TX", NULL, "ADC 08"}, 576 - {"DP4TX", NULL, "ADC 07"}, 577 - {"DP4TX", NULL, "ADC 27"}, 578 - {"DP4TX", NULL, "ADC 09"}, 579 - {"DP4TX", NULL, "ADC 08"}, 580 - 581 - {"LINE1", NULL, "PDE23_24"}, 582 - {"LINE2", NULL, "PDE23_24"}, 583 - {"MIC1", NULL, "PDE23_24"}, 584 - {"MIC2", NULL, "PDE23_24"}, 585 - {"DMIC1", NULL, "PDE23_24"}, 586 - {"DMIC2", NULL, "PDE23_24"}, 587 - {"DMIC3", NULL, "PDE23_24"}, 588 - {"DMIC4", NULL, "PDE23_24"}, 589 - 590 - {"ADC 09", NULL, "ADC 22 Mux"}, 591 - {"ADC 08", NULL, "ADC 23 Mux"}, 592 - {"ADC 07", NULL, "ADC 24 Mux"}, 593 - {"ADC 27", NULL, "ADC 25 Mux"}, 594 - {"ADC 22 Mux", "MIC1", "MIC1"}, 595 - {"ADC 22 Mux", "MIC2", "MIC2"}, 596 - {"ADC 22 Mux", "LINE1", "LINE1"}, 597 - {"ADC 22 Mux", "LINE2", "LINE2"}, 598 - {"ADC 22 Mux", "DMIC1", "DMIC1"}, 599 - {"ADC 22 Mux", "DMIC2", "DMIC2"}, 600 - {"ADC 22 Mux", "DMIC3", "DMIC3"}, 601 - {"ADC 22 Mux", "DMIC4", "DMIC4"}, 602 - {"ADC 23 Mux", "MIC1", "MIC1"}, 603 - {"ADC 23 Mux", "MIC2", "MIC2"}, 604 - {"ADC 23 Mux", "LINE1", "LINE1"}, 605 - {"ADC 23 Mux", "LINE2", "LINE2"}, 606 - {"ADC 23 Mux", "DMIC1", "DMIC1"}, 607 - {"ADC 23 Mux", "DMIC2", "DMIC2"}, 608 - {"ADC 23 Mux", "DMIC3", "DMIC3"}, 609 - {"ADC 23 Mux", "DMIC4", "DMIC4"}, 610 - {"ADC 24 Mux", "MIC2", "MIC2"}, 611 - {"ADC 24 Mux", "DMIC1", "DMIC1"}, 612 - {"ADC 24 Mux", "DMIC2", "DMIC2"}, 613 - {"ADC 24 Mux", "DMIC3", "DMIC3"}, 614 - {"ADC 24 Mux", "DMIC4", "DMIC4"}, 615 - {"ADC 25 Mux", "MIC1", "MIC1"}, 616 - {"ADC 25 Mux", "DMIC1", "DMIC1"}, 617 - {"ADC 25 Mux", "DMIC2", "DMIC2"}, 618 - {"ADC 25 Mux", "DMIC3", "DMIC3"}, 619 - {"ADC 25 Mux", "DMIC4", "DMIC4"}, 620 - }; 621 - 622 - static const struct snd_soc_component_driver soc_codec_dev_rt715_sdca = { 623 - .controls = rt715_snd_controls_sdca, 624 - .num_controls = ARRAY_SIZE(rt715_snd_controls_sdca), 625 - .dapm_widgets = rt715_dapm_widgets, 626 - .num_dapm_widgets = ARRAY_SIZE(rt715_dapm_widgets), 627 - .dapm_routes = rt715_audio_map, 628 - .num_dapm_routes = ARRAY_SIZE(rt715_audio_map), 629 - }; 630 - 631 - static int rt715_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, 632 - int direction) 633 - { 634 - struct rt715_sdw_stream_data *stream; 635 - 636 - stream = kzalloc(sizeof(*stream), GFP_KERNEL); 637 - if (!stream) 638 - return -ENOMEM; 639 - 640 - stream->sdw_stream = sdw_stream; 641 - 642 - /* Use tx_mask or rx_mask to configure stream tag and set dma_data */ 643 - if (direction == SNDRV_PCM_STREAM_PLAYBACK) 644 - dai->playback_dma_data = stream; 645 - else 646 - dai->capture_dma_data = stream; 647 - 648 - return 0; 649 - } 650 - 651 - static void rt715_shutdown(struct snd_pcm_substream *substream, 652 - struct snd_soc_dai *dai) 653 - 654 - { 655 - struct rt715_sdw_stream_data *stream; 656 - 657 - stream = snd_soc_dai_get_dma_data(dai, substream); 658 - if (!stream) 659 - return; 660 - 661 - snd_soc_dai_set_dma_data(dai, substream, NULL); 662 - kfree(stream); 663 - } 664 - 665 - static int rt715_pcm_hw_params(struct snd_pcm_substream *substream, 666 - struct snd_pcm_hw_params *params, 667 - struct snd_soc_dai *dai) 668 - { 669 - struct snd_soc_component *component = dai->component; 670 - struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component); 671 - struct sdw_stream_config stream_config; 672 - struct sdw_port_config port_config; 673 - enum sdw_data_direction direction; 674 - struct rt715_sdw_stream_data *stream; 675 - int retval, port, num_channels; 676 - unsigned int val; 677 - 678 - stream = snd_soc_dai_get_dma_data(dai, substream); 679 - 680 - if (!stream) 681 - return -EINVAL; 682 - 683 - if (!rt715->slave) 684 - return -EINVAL; 685 - 686 - switch (dai->id) { 687 - case RT715_AIF1: 688 - direction = SDW_DATA_DIR_TX; 689 - port = 6; 690 - rt715_index_write(rt715, RT715_VENDOR_REG, RT715_SDW_INPUT_SEL, 691 - 0xa500); 692 - break; 693 - case RT715_AIF2: 694 - direction = SDW_DATA_DIR_TX; 695 - port = 4; 696 - rt715_index_write(rt715, RT715_VENDOR_REG, RT715_SDW_INPUT_SEL, 697 - 0xaf00); 698 - break; 699 - default: 700 - dev_err(component->dev, "Invalid DAI id %d\n", dai->id); 701 - return -EINVAL; 702 - } 703 - 704 - stream_config.frame_rate = params_rate(params); 705 - stream_config.ch_count = params_channels(params); 706 - stream_config.bps = snd_pcm_format_width(params_format(params)); 707 - stream_config.direction = direction; 708 - 709 - num_channels = params_channels(params); 710 - port_config.ch_mask = GENMASK(num_channels - 1, 0); 711 - port_config.num = port; 712 - 713 - retval = sdw_stream_add_slave(rt715->slave, &stream_config, 714 - &port_config, 1, stream->sdw_stream); 715 - if (retval) { 716 - dev_err(component->dev, "Unable to configure port, retval:%d\n", 717 - retval); 718 - return retval; 719 - } 720 - 721 - switch (params_rate(params)) { 722 - case 8000: 723 - val = 0x1; 724 - break; 725 - case 11025: 726 - val = 0x2; 727 - break; 728 - case 12000: 729 - val = 0x3; 730 - break; 731 - case 16000: 732 - val = 0x4; 733 - break; 734 - case 22050: 735 - val = 0x5; 736 - break; 737 - case 24000: 738 - val = 0x6; 739 - break; 740 - case 32000: 741 - val = 0x7; 742 - break; 743 - case 44100: 744 - val = 0x8; 745 - break; 746 - case 48000: 747 - val = 0x9; 748 - break; 749 - case 88200: 750 - val = 0xa; 751 - break; 752 - case 96000: 753 - val = 0xb; 754 - break; 755 - case 176400: 756 - val = 0xc; 757 - break; 758 - case 192000: 759 - val = 0xd; 760 - break; 761 - case 384000: 762 - val = 0xe; 763 - break; 764 - case 768000: 765 - val = 0xf; 766 - break; 767 - default: 768 - dev_err(component->dev, "Unsupported sample rate %d\n", 769 - params_rate(params)); 770 - return -EINVAL; 771 - } 772 - 773 - regmap_write(rt715->regmap, 774 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CS_FREQ_IND_EN, 775 - RT715_SDCA_FREQ_IND_CTRL, CH_00), val); 776 - 777 - return 0; 778 - } 779 - 780 - static int rt715_pcm_hw_free(struct snd_pcm_substream *substream, 781 - struct snd_soc_dai *dai) 782 - { 783 - struct snd_soc_component *component = dai->component; 784 - struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component); 785 - struct rt715_sdw_stream_data *stream = 786 - snd_soc_dai_get_dma_data(dai, substream); 787 - 788 - if (!rt715->slave) 789 - return -EINVAL; 790 - 791 - sdw_stream_remove_slave(rt715->slave, stream->sdw_stream); 792 - return 0; 793 - } 794 - 795 - #define RT715_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) 796 - #define RT715_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ 797 - SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) 798 - 799 - static struct snd_soc_dai_ops rt715_ops = { 800 - .hw_params = rt715_pcm_hw_params, 801 - .hw_free = rt715_pcm_hw_free, 802 - .set_sdw_stream = rt715_set_sdw_stream, 803 - .shutdown = rt715_shutdown, 804 - }; 805 - 806 - static struct snd_soc_dai_driver rt715_dai[] = { 807 - { 808 - .name = "rt715-aif1", 809 - .id = RT715_AIF1, 810 - .capture = { 811 - .stream_name = "DP6 Capture", 812 - .channels_min = 1, 813 - .channels_max = 2, 814 - .rates = RT715_STEREO_RATES, 815 - .formats = RT715_FORMATS, 816 - }, 817 - .ops = &rt715_ops, 818 - }, 819 - { 820 - .name = "rt715-aif2", 821 - .id = RT715_AIF2, 822 - .capture = { 823 - .stream_name = "DP4 Capture", 824 - .channels_min = 1, 825 - .channels_max = 2, 826 - .rates = RT715_STEREO_RATES, 827 - .formats = RT715_FORMATS, 828 - }, 829 - .ops = &rt715_ops, 830 - }, 831 - }; 832 - 833 - /* Bus clock frequency */ 834 - #define RT715_CLK_FREQ_9600000HZ 9600000 835 - #define RT715_CLK_FREQ_12000000HZ 12000000 836 - #define RT715_CLK_FREQ_6000000HZ 6000000 837 - #define RT715_CLK_FREQ_4800000HZ 4800000 838 - #define RT715_CLK_FREQ_2400000HZ 2400000 839 - #define RT715_CLK_FREQ_12288000HZ 12288000 840 - 841 - int rt715_init(struct device *dev, struct regmap *mbq_regmap, 842 - struct regmap *regmap, struct sdw_slave *slave) 843 - { 844 - struct rt715_sdca_priv *rt715; 845 - int ret; 846 - 847 - rt715 = devm_kzalloc(dev, sizeof(*rt715), GFP_KERNEL); 848 - if (!rt715) 849 - return -ENOMEM; 850 - 851 - dev_set_drvdata(dev, rt715); 852 - rt715->slave = slave; 853 - rt715->regmap = regmap; 854 - rt715->mbq_regmap = mbq_regmap; 855 - rt715->hw_sdw_ver = slave->id.sdw_version; 856 - /* 857 - * Mark hw_init to false 858 - * HW init will be performed when device reports present 859 - */ 860 - rt715->hw_init = false; 861 - rt715->first_init = false; 862 - 863 - ret = devm_snd_soc_register_component(dev, 864 - &soc_codec_dev_rt715_sdca, 865 - rt715_dai, 866 - ARRAY_SIZE(rt715_dai)); 867 - 868 - return ret; 869 - } 870 - 871 - int rt715_io_init(struct device *dev, struct sdw_slave *slave) 872 - { 873 - struct rt715_sdca_priv *rt715 = dev_get_drvdata(dev); 874 - unsigned int hw_ver; 875 - 876 - if (rt715->hw_init) 877 - return 0; 878 - 879 - /* 880 - * PM runtime is only enabled when a Slave reports as Attached 881 - */ 882 - if (!rt715->first_init) { 883 - /* set autosuspend parameters */ 884 - pm_runtime_set_autosuspend_delay(&slave->dev, 3000); 885 - pm_runtime_use_autosuspend(&slave->dev); 886 - 887 - /* update count of parent 'active' children */ 888 - pm_runtime_set_active(&slave->dev); 889 - 890 - /* make sure the device does not suspend immediately */ 891 - pm_runtime_mark_last_busy(&slave->dev); 892 - 893 - pm_runtime_enable(&slave->dev); 894 - 895 - rt715->first_init = true; 896 - } 897 - 898 - pm_runtime_get_noresume(&slave->dev); 899 - 900 - rt715_index_read(rt715, RT715_VENDOR_REG, 901 - RT715_PRODUCT_NUM, &hw_ver); 902 - hw_ver = hw_ver & 0x000f; 903 - 904 - /* set clock selector = external */ 905 - regmap_write(rt715->regmap, 906 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CX_CLK_SEL_EN, 907 - RT715_SDCA_CX_CLK_SEL_CTRL, CH_00), 0x1); 908 - /* set GPIO_4/5/6 to be 3rd/4th DMIC usage */ 909 - if (hw_ver == 0x0) 910 - rt715_index_update_bits(rt715, RT715_VENDOR_REG, 911 - RT715_AD_FUNC_EN, 0x54, 0x54); 912 - else if (hw_ver == 0x1) { 913 - rt715_index_update_bits(rt715, RT715_VENDOR_REG, 914 - RT715_AD_FUNC_EN, 0x55, 0x55); 915 - rt715_index_update_bits(rt715, RT715_VENDOR_REG, 916 - RT715_REV_1, 0x40, 0x40); 917 - } 918 - /* trigger mode = VAD enable */ 919 - regmap_write(rt715->regmap, 920 - SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN, 921 - RT715_SDCA_SMPU_TRIG_EN_CTRL, CH_00), 0x2); 922 - /* SMPU-1 interrupt enable mask */ 923 - regmap_update_bits(rt715->regmap, RT715_INT_MASK, 0x1, 0x1); 924 - 925 - /* Mark Slave initialization complete */ 926 - rt715->hw_init = true; 927 - 928 - pm_runtime_mark_last_busy(&slave->dev); 929 - pm_runtime_put_autosuspend(&slave->dev); 930 - 931 - return 0; 932 - } 933 - 934 - MODULE_DESCRIPTION("ASoC rt715 driver SDW SDCA"); 935 - MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>"); 936 - MODULE_LICENSE("GPL v2");
-124
sound/soc/codecs/rt715-sdca.h
··· 1 - /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* 3 - * rt715-sdca.h -- RT715 ALSA SoC audio driver header 4 - * 5 - * Copyright(c) 2020 Realtek Semiconductor Corp. 6 - */ 7 - 8 - #ifndef __RT715_SDCA_H__ 9 - #define __RT715_SDCA_H__ 10 - 11 - #include <linux/regmap.h> 12 - #include <linux/soundwire/sdw.h> 13 - #include <linux/soundwire/sdw_type.h> 14 - #include <sound/soc.h> 15 - #include <linux/workqueue.h> 16 - #include <linux/device.h> 17 - 18 - struct rt715_sdca_priv { 19 - struct regmap *regmap; 20 - struct regmap *mbq_regmap; 21 - struct snd_soc_codec *codec; 22 - struct sdw_slave *slave; 23 - struct delayed_work adc_mute_work; 24 - int dbg_nid; 25 - int dbg_vid; 26 - int dbg_payload; 27 - enum sdw_slave_status status; 28 - struct sdw_bus_params params; 29 - bool hw_init; 30 - bool first_init; 31 - int l_is_unmute; 32 - int r_is_unmute; 33 - int hw_sdw_ver; 34 - }; 35 - 36 - struct rt715_sdw_stream_data { 37 - struct sdw_stream_runtime *sdw_stream; 38 - }; 39 - 40 - /* MIPI Register */ 41 - #define RT715_INT_CTRL 0x005a 42 - #define RT715_INT_MASK 0x005e 43 - 44 - /* NID */ 45 - #define RT715_AUDIO_FUNCTION_GROUP 0x01 46 - #define RT715_MIC_ADC 0x07 47 - #define RT715_LINE_ADC 0x08 48 - #define RT715_MIX_ADC 0x09 49 - #define RT715_DMIC1 0x12 50 - #define RT715_DMIC2 0x13 51 - #define RT715_MIC1 0x18 52 - #define RT715_MIC2 0x19 53 - #define RT715_LINE1 0x1a 54 - #define RT715_LINE2 0x1b 55 - #define RT715_DMIC3 0x1d 56 - #define RT715_DMIC4 0x29 57 - #define RT715_VENDOR_REG 0x20 58 - #define RT715_MUX_IN1 0x22 59 - #define RT715_MUX_IN2 0x23 60 - #define RT715_MUX_IN3 0x24 61 - #define RT715_MUX_IN4 0x25 62 - #define RT715_MIX_ADC2 0x27 63 - #define RT715_INLINE_CMD 0x55 64 - #define RT715_VENDOR_HDA_CTL 0x61 65 - 66 - /* Index (NID:20h) */ 67 - #define RT715_PRODUCT_NUM 0x0 68 - #define RT715_IRQ_CTRL 0x2b 69 - #define RT715_AD_FUNC_EN 0x36 70 - #define RT715_REV_1 0x37 71 - #define RT715_SDW_INPUT_SEL 0x39 72 - #define RT715_EXT_DMIC_CLK_CTRL2 0x54 73 - 74 - /* Index (NID:61h) */ 75 - #define RT715_HDA_LEGACY_MUX_CTL1 0x00 76 - 77 - /* SDCA (Function) */ 78 - #define FUN_JACK_CODEC 0x01 79 - #define FUN_MIC_ARRAY 0x02 80 - #define FUN_HID 0x03 81 - /* SDCA (Entity) */ 82 - #define RT715_SDCA_ST_EN 0x00 83 - #define RT715_SDCA_CS_FREQ_IND_EN 0x01 84 - #define RT715_SDCA_FU_ADC8_9_VOL 0x02 85 - #define RT715_SDCA_SMPU_TRIG_ST_EN 0x05 86 - #define RT715_SDCA_FU_ADC10_11_VOL 0x06 87 - #define RT715_SDCA_FU_ADC7_27_VOL 0x0a 88 - #define RT715_SDCA_FU_AMIC_GAIN_EN 0x0c 89 - #define RT715_SDCA_FU_DMIC_GAIN_EN 0x0e 90 - #define RT715_SDCA_CX_CLK_SEL_EN 0x10 91 - #define RT715_SDCA_CREQ_POW_EN 0x18 92 - /* SDCA (Control) */ 93 - #define RT715_SDCA_ST_CTRL 0x00 94 - #define RT715_SDCA_CX_CLK_SEL_CTRL 0x01 95 - #define RT715_SDCA_REQ_POW_CTRL 0x01 96 - #define RT715_SDCA_FU_MUTE_CTRL 0x01 97 - #define RT715_SDCA_FU_VOL_CTRL 0x02 98 - #define RT715_SDCA_FU_DMIC_GAIN_CTRL 0x0b 99 - #define RT715_SDCA_FREQ_IND_CTRL 0x10 100 - #define RT715_SDCA_SMPU_TRIG_EN_CTRL 0x10 101 - #define RT715_SDCA_SMPU_TRIG_ST_CTRL 0x11 102 - /* SDCA (Channel) */ 103 - #define CH_00 0x00 104 - #define CH_01 0x01 105 - #define CH_02 0x02 106 - #define CH_03 0x03 107 - #define CH_04 0x04 108 - #define CH_05 0x05 109 - #define CH_06 0x06 110 - #define CH_07 0x07 111 - #define CH_08 0x08 112 - 113 - #define RT715_SDCA_DB_STEP 375 114 - 115 - enum { 116 - RT715_AIF1, 117 - RT715_AIF2, 118 - }; 119 - 120 - int rt715_io_init(struct device *dev, struct sdw_slave *slave); 121 - int rt715_init(struct device *dev, struct regmap *mbq_regmap, 122 - struct regmap *regmap, struct sdw_slave *slave); 123 - 124 - #endif /* __RT715_SDCA_H__ */