File Index
Files and directories
Sign in
FILE

rt715-sdca.c

File preview with syntax highlighting.

linux-6.19.14/sound/soc/codecs/rt715-sdca.c 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/kernel.h>
  13#include <linux/init.h>
  14#include <linux/pm_runtime.h>
  15#include <linux/pm.h>
  16#include <linux/soundwire/sdw.h>
  17#include <linux/regmap.h>
  18#include <linux/slab.h>
  19#include <linux/platform_device.h>
  20#include <sound/core.h>
  21#include <sound/pcm.h>
  22#include <sound/pcm_params.h>
  23#include <sound/sdw.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
  32static int rt715_sdca_index_write(struct rt715_sdca_priv *rt715,
  33		unsigned int nid, 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			"%s: Failed to set private value: %08x <= %04x %d\n",
  45			__func__, addr, value, ret);
  46
  47	return ret;
  48}
  49
  50static int rt715_sdca_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			"%s: Failed to get private value: %06x => %04x ret=%d\n",
  63			__func__, addr, *value, ret);
  64
  65	return ret;
  66}
  67
  68static int rt715_sdca_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_sdca_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_sdca_index_write(rt715, nid, reg, tmp);
  81}
  82
  83static inline unsigned int rt715_sdca_vol_gain(unsigned int u_ctrl_val,
  84		unsigned int vol_max, unsigned int vol_gain_sft)
  85{
  86	unsigned int val;
  87
  88	if (u_ctrl_val > vol_max)
  89		u_ctrl_val = vol_max;
  90	val = u_ctrl_val;
  91	u_ctrl_val =
  92		((abs(u_ctrl_val - vol_gain_sft) * RT715_SDCA_DB_STEP) << 8) / 1000;
  93	if (val <= vol_gain_sft) {
  94		u_ctrl_val = ~u_ctrl_val;
  95		u_ctrl_val += 1;
  96	}
  97	u_ctrl_val &= 0xffff;
  98
  99	return u_ctrl_val;
 100}
 101
 102static inline unsigned int rt715_sdca_boost_gain(unsigned int u_ctrl_val,
 103		unsigned int b_max, unsigned int b_gain_sft)
 104{
 105	if (u_ctrl_val > b_max)
 106		u_ctrl_val = b_max;
 107
 108	return (u_ctrl_val * 10) << b_gain_sft;
 109}
 110
 111static inline unsigned int rt715_sdca_get_gain(unsigned int reg_val,
 112		unsigned int gain_sft)
 113{
 114	unsigned int neg_flag = 0;
 115
 116	if (reg_val & BIT(15)) {
 117		reg_val = ~(reg_val - 1) & 0xffff;
 118		neg_flag = 1;
 119	}
 120	reg_val *= 1000;
 121	reg_val >>= 8;
 122	if (neg_flag)
 123		reg_val = gain_sft - reg_val / RT715_SDCA_DB_STEP;
 124	else
 125		reg_val = gain_sft + reg_val / RT715_SDCA_DB_STEP;
 126
 127	return reg_val;
 128}
 129
 130/* SDCA Volume/Boost control */
 131static int rt715_sdca_set_amp_gain_put(struct snd_kcontrol *kcontrol,
 132		struct snd_ctl_elem_value *ucontrol)
 133{
 134	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 135	struct soc_mixer_control *mc =
 136		(struct soc_mixer_control *)kcontrol->private_value;
 137	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
 138	unsigned int gain_val, i, k_changed = 0;
 139	int ret;
 140
 141	for (i = 0; i < 2; i++) {
 142		if (ucontrol->value.integer.value[i] != rt715->kctl_2ch_orig[i]) {
 143			k_changed = 1;
 144			break;
 145		}
 146	}
 147
 148	for (i = 0; i < 2; i++) {
 149		rt715->kctl_2ch_orig[i] = ucontrol->value.integer.value[i];
 150		gain_val =
 151			rt715_sdca_vol_gain(ucontrol->value.integer.value[i], mc->max,
 152				mc->shift);
 153		ret = regmap_write(rt715->mbq_regmap, mc->reg + i, gain_val);
 154		if (ret != 0) {
 155			dev_err(component->dev, "%s: Failed to write 0x%x=0x%x\n",
 156				__func__, mc->reg + i, gain_val);
 157			return ret;
 158		}
 159	}
 160
 161	return k_changed;
 162}
 163
 164static int rt715_sdca_set_amp_gain_4ch_put(struct snd_kcontrol *kcontrol,
 165		struct snd_ctl_elem_value *ucontrol)
 166{
 167	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 168	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
 169	struct rt715_sdca_kcontrol_private *p =
 170		(struct rt715_sdca_kcontrol_private *)kcontrol->private_value;
 171	unsigned int reg_base = p->reg_base, k_changed = 0;
 172	const unsigned int gain_sft = 0x2f;
 173	unsigned int gain_val, i;
 174	int ret;
 175
 176	for (i = 0; i < 4; i++) {
 177		if (ucontrol->value.integer.value[i] != rt715->kctl_4ch_orig[i]) {
 178			k_changed = 1;
 179			break;
 180		}
 181	}
 182
 183	for (i = 0; i < 4; i++) {
 184		rt715->kctl_4ch_orig[i] = ucontrol->value.integer.value[i];
 185		gain_val =
 186			rt715_sdca_vol_gain(ucontrol->value.integer.value[i], p->max,
 187				gain_sft);
 188		ret = regmap_write(rt715->mbq_regmap, reg_base + i,
 189				gain_val);
 190		if (ret != 0) {
 191			dev_err(component->dev, "%s: Failed to write 0x%x=0x%x\n",
 192				__func__, reg_base + i, gain_val);
 193			return ret;
 194		}
 195	}
 196
 197	return k_changed;
 198}
 199
 200static int rt715_sdca_set_amp_gain_8ch_put(struct snd_kcontrol *kcontrol,
 201		struct snd_ctl_elem_value *ucontrol)
 202{
 203	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 204	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
 205	struct rt715_sdca_kcontrol_private *p =
 206		(struct rt715_sdca_kcontrol_private *)kcontrol->private_value;
 207	unsigned int reg_base = p->reg_base, i, k_changed = 0;
 208	const unsigned int gain_sft = 8;
 209	unsigned int gain_val, reg;
 210	int ret;
 211
 212	for (i = 0; i < 8; i++) {
 213		if (ucontrol->value.integer.value[i] != rt715->kctl_8ch_orig[i]) {
 214			k_changed = 1;
 215			break;
 216		}
 217	}
 218
 219	for (i = 0; i < 8; i++) {
 220		rt715->kctl_8ch_orig[i] = ucontrol->value.integer.value[i];
 221		gain_val =
 222			rt715_sdca_boost_gain(ucontrol->value.integer.value[i], p->max,
 223				gain_sft);
 224		reg = i < 7 ? reg_base + i : (reg_base - 1) | BIT(15);
 225		ret = regmap_write(rt715->mbq_regmap, reg, gain_val);
 226		if (ret != 0) {
 227			dev_err(component->dev, "%s: Failed to write 0x%x=0x%x\n",
 228				__func__, reg, gain_val);
 229			return ret;
 230		}
 231	}
 232
 233	return k_changed;
 234}
 235
 236static int rt715_sdca_set_amp_gain_get(struct snd_kcontrol *kcontrol,
 237		struct snd_ctl_elem_value *ucontrol)
 238{
 239	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 240	struct soc_mixer_control *mc =
 241		(struct soc_mixer_control *)kcontrol->private_value;
 242	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
 243	unsigned int val, i;
 244	int ret;
 245
 246	for (i = 0; i < 2; i++) {
 247		ret = regmap_read(rt715->mbq_regmap, mc->reg + i, &val);
 248		if (ret < 0) {
 249			dev_err(component->dev, "%s: Failed to read 0x%x, ret=%d\n",
 250				__func__, mc->reg + i, ret);
 251			return ret;
 252		}
 253		ucontrol->value.integer.value[i] = rt715_sdca_get_gain(val, mc->shift);
 254	}
 255
 256	return 0;
 257}
 258
 259static int rt715_sdca_set_amp_gain_4ch_get(struct snd_kcontrol *kcontrol,
 260		struct snd_ctl_elem_value *ucontrol)
 261{
 262	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 263	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
 264	struct rt715_sdca_kcontrol_private *p =
 265		(struct rt715_sdca_kcontrol_private *)kcontrol->private_value;
 266	unsigned int reg_base = p->reg_base, i;
 267	const unsigned int gain_sft = 0x2f;
 268	unsigned int val;
 269	int ret;
 270
 271	for (i = 0; i < 4; i++) {
 272		ret = regmap_read(rt715->mbq_regmap, reg_base + i, &val);
 273		if (ret < 0) {
 274			dev_err(component->dev, "%s: Failed to read 0x%x, ret=%d\n",
 275				__func__, reg_base + i, ret);
 276			return ret;
 277		}
 278		ucontrol->value.integer.value[i] = rt715_sdca_get_gain(val, gain_sft);
 279	}
 280
 281	return 0;
 282}
 283
 284static int rt715_sdca_set_amp_gain_8ch_get(struct snd_kcontrol *kcontrol,
 285		struct snd_ctl_elem_value *ucontrol)
 286{
 287	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 288	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
 289	struct rt715_sdca_kcontrol_private *p =
 290		(struct rt715_sdca_kcontrol_private *)kcontrol->private_value;
 291	unsigned int reg_base = p->reg_base;
 292	const unsigned int gain_sft = 8;
 293	unsigned int val_l, val_r;
 294	unsigned int i, reg;
 295	int ret;
 296
 297	for (i = 0; i < 8; i += 2) {
 298		ret = regmap_read(rt715->mbq_regmap, reg_base + i, &val_l);
 299		if (ret < 0) {
 300			dev_err(component->dev, "%s: Failed to read 0x%x, ret=%d\n",
 301				__func__, reg_base + i, ret);
 302			return ret;
 303		}
 304		ucontrol->value.integer.value[i] = (val_l >> gain_sft) / 10;
 305
 306		reg = (i == 6) ? (reg_base - 1) | BIT(15) : reg_base + 1 + i;
 307		ret = regmap_read(rt715->mbq_regmap, reg, &val_r);
 308		if (ret < 0) {
 309			dev_err(component->dev, "%s: Failed to read 0x%x, ret=%d\n",
 310				__func__, reg, ret);
 311			return ret;
 312		}
 313		ucontrol->value.integer.value[i + 1] = (val_r >> gain_sft) / 10;
 314	}
 315
 316	return 0;
 317}
 318
 319static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1725, 75, 0);
 320static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);
 321
 322static int rt715_sdca_get_volsw(struct snd_kcontrol *kcontrol,
 323	struct snd_ctl_elem_value *ucontrol)
 324{
 325	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 326	struct rt715_sdca_kcontrol_private *p =
 327		(struct rt715_sdca_kcontrol_private *)kcontrol->private_value;
 328	unsigned int reg_base = p->reg_base;
 329	unsigned int invert = p->invert, i;
 330	int val;
 331
 332	for (i = 0; i < p->count; i += 2) {
 333		val = snd_soc_component_read(component, reg_base + i);
 334		if (val < 0)
 335			return -EINVAL;
 336		ucontrol->value.integer.value[i] = invert ? p->max - val : val;
 337
 338		val = snd_soc_component_read(component, reg_base + 1 + i);
 339		if (val < 0)
 340			return -EINVAL;
 341		ucontrol->value.integer.value[i + 1] =
 342			invert ? p->max - val : val;
 343	}
 344
 345	return 0;
 346}
 347
 348static int rt715_sdca_put_volsw(struct snd_kcontrol *kcontrol,
 349	struct snd_ctl_elem_value *ucontrol)
 350{
 351	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
 352	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
 353	struct rt715_sdca_kcontrol_private *p =
 354		(struct rt715_sdca_kcontrol_private *)kcontrol->private_value;
 355	unsigned int val[4] = {0}, val_mask, i, k_changed = 0;
 356	unsigned int reg = p->reg_base;
 357	unsigned int shift = p->shift;
 358	unsigned int max = p->max;
 359	unsigned int mask = (1 << fls(max)) - 1;
 360	unsigned int invert = p->invert;
 361	int err;
 362
 363	for (i = 0; i < 4; i++) {
 364		if (ucontrol->value.integer.value[i] != rt715->kctl_switch_orig[i]) {
 365			k_changed = 1;
 366			break;
 367		}
 368	}
 369
 370	for (i = 0; i < 2; i++) {
 371		rt715->kctl_switch_orig[i * 2] = ucontrol->value.integer.value[i * 2];
 372		val[i * 2] = ucontrol->value.integer.value[i * 2] & mask;
 373		if (invert)
 374			val[i * 2] = max - val[i * 2];
 375		val_mask = mask << shift;
 376		val[i * 2] <<= shift;
 377
 378		rt715->kctl_switch_orig[i * 2 + 1] =
 379			ucontrol->value.integer.value[i * 2 + 1];
 380		val[i * 2 + 1] =
 381			ucontrol->value.integer.value[i * 2 + 1] & mask;
 382		if (invert)
 383			val[i * 2 + 1] = max - val[i * 2 + 1];
 384
 385		val[i * 2 + 1] <<=  shift;
 386
 387		err = snd_soc_component_update_bits(component, reg + i * 2, val_mask,
 388				val[i * 2]);
 389		if (err < 0)
 390			return err;
 391
 392		err = snd_soc_component_update_bits(component, reg + 1 + i * 2,
 393			val_mask, val[i * 2 + 1]);
 394		if (err < 0)
 395			return err;
 396	}
 397
 398	return k_changed;
 399}
 400
 401static int rt715_sdca_fu_info(struct snd_kcontrol *kcontrol,
 402	struct snd_ctl_elem_info *uinfo)
 403{
 404	struct rt715_sdca_kcontrol_private *p =
 405		(struct rt715_sdca_kcontrol_private *)kcontrol->private_value;
 406
 407	if (p->max == 1)
 408		uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
 409	else
 410		uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
 411	uinfo->count = p->count;
 412	uinfo->value.integer.min = 0;
 413	uinfo->value.integer.max = p->max;
 414	return 0;
 415}
 416
 417#define RT715_SDCA_PR_VALUE(xreg_base, xcount, xmax, xshift, xinvert) \
 418	((unsigned long)&(struct rt715_sdca_kcontrol_private) \
 419		{.reg_base = xreg_base, .count = xcount, .max = xmax, \
 420		.shift = xshift, .invert = xinvert})
 421
 422#define RT715_SDCA_FU_CTRL(xname, reg_base, xshift, xmax, xinvert, xcount) \
 423{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
 424	.info = rt715_sdca_fu_info, \
 425	.get = rt715_sdca_get_volsw, \
 426	.put = rt715_sdca_put_volsw, \
 427	.private_value = RT715_SDCA_PR_VALUE(reg_base, xcount, xmax, \
 428					xshift, xinvert)}
 429
 430#define RT715_SDCA_EXT_TLV(xname, reg_base, xhandler_get,\
 431	 xhandler_put, tlv_array, xcount, xmax) \
 432{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
 433	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
 434		 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
 435	.tlv.p = (tlv_array), \
 436	.info = rt715_sdca_fu_info, \
 437	.get = xhandler_get, .put = xhandler_put, \
 438	.private_value = RT715_SDCA_PR_VALUE(reg_base, xcount, xmax, 0, 0) }
 439
 440#define RT715_SDCA_BOOST_EXT_TLV(xname, reg_base, xhandler_get,\
 441	 xhandler_put, tlv_array, xcount, xmax) \
 442{	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
 443	.access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
 444		 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
 445	.tlv.p = (tlv_array), \
 446	.info = rt715_sdca_fu_info, \
 447	.get = xhandler_get, .put = xhandler_put, \
 448	.private_value = RT715_SDCA_PR_VALUE(reg_base, xcount, xmax, 0, 0) }
 449
 450static const struct snd_kcontrol_new rt715_sdca_snd_controls[] = {
 451	/* Capture switch */
 452	SOC_DOUBLE_R("FU0A Capture Switch",
 453		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
 454			RT715_SDCA_FU_MUTE_CTRL, CH_01),
 455		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
 456			RT715_SDCA_FU_MUTE_CTRL, CH_02),
 457			0, 1, 1),
 458	RT715_SDCA_FU_CTRL("FU02 Capture Switch",
 459		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
 460			RT715_SDCA_FU_MUTE_CTRL, CH_01),
 461			0, 1, 1, 4),
 462	RT715_SDCA_FU_CTRL("FU06 Capture Switch",
 463		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
 464			RT715_SDCA_FU_MUTE_CTRL, CH_01),
 465			0, 1, 1, 4),
 466	/* Volume Control */
 467	SOC_DOUBLE_R_EXT_TLV("FU0A Capture Volume",
 468		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
 469			RT715_SDCA_FU_VOL_CTRL, CH_01),
 470		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC7_27_VOL,
 471			RT715_SDCA_FU_VOL_CTRL, CH_02),
 472			0x2f, 0x3f, 0,
 473		rt715_sdca_set_amp_gain_get, rt715_sdca_set_amp_gain_put,
 474		in_vol_tlv),
 475	RT715_SDCA_EXT_TLV("FU02 Capture Volume",
 476		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC8_9_VOL,
 477			RT715_SDCA_FU_VOL_CTRL, CH_01),
 478		rt715_sdca_set_amp_gain_4ch_get,
 479		rt715_sdca_set_amp_gain_4ch_put,
 480		in_vol_tlv, 4, 0x3f),
 481	RT715_SDCA_EXT_TLV("FU06 Capture Volume",
 482		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_ADC10_11_VOL,
 483			RT715_SDCA_FU_VOL_CTRL, CH_01),
 484		rt715_sdca_set_amp_gain_4ch_get,
 485		rt715_sdca_set_amp_gain_4ch_put,
 486		in_vol_tlv, 4, 0x3f),
 487	/* MIC Boost Control */
 488	RT715_SDCA_BOOST_EXT_TLV("FU0E Boost",
 489		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_DMIC_GAIN_EN,
 490			RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_01),
 491			rt715_sdca_set_amp_gain_8ch_get,
 492			rt715_sdca_set_amp_gain_8ch_put,
 493			mic_vol_tlv, 8, 3),
 494	RT715_SDCA_BOOST_EXT_TLV("FU0C Boost",
 495		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_FU_AMIC_GAIN_EN,
 496			RT715_SDCA_FU_DMIC_GAIN_CTRL, CH_01),
 497			rt715_sdca_set_amp_gain_8ch_get,
 498			rt715_sdca_set_amp_gain_8ch_put,
 499			mic_vol_tlv, 8, 3),
 500};
 501
 502static int rt715_sdca_mux_get(struct snd_kcontrol *kcontrol,
 503			struct snd_ctl_elem_value *ucontrol)
 504{
 505	struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol);
 506	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
 507	unsigned int val, mask_sft;
 508
 509	if (strstr(ucontrol->id.name, "ADC 22 Mux"))
 510		mask_sft = 12;
 511	else if (strstr(ucontrol->id.name, "ADC 23 Mux"))
 512		mask_sft = 8;
 513	else if (strstr(ucontrol->id.name, "ADC 24 Mux"))
 514		mask_sft = 4;
 515	else if (strstr(ucontrol->id.name, "ADC 25 Mux"))
 516		mask_sft = 0;
 517	else
 518		return -EINVAL;
 519
 520	rt715_sdca_index_read(rt715, RT715_VENDOR_HDA_CTL,
 521		RT715_HDA_LEGACY_MUX_CTL1, &val);
 522	val = (val >> mask_sft) & 0xf;
 523
 524	/*
 525	 * The first two indices of ADC Mux 24/25 are routed to the same
 526	 * hardware source. ie, ADC Mux 24 0/1 will both connect to MIC2.
 527	 * To have a unique set of inputs, we skip the index1 of the muxes.
 528	 */
 529	if ((strstr(ucontrol->id.name, "ADC 24 Mux") ||
 530		strstr(ucontrol->id.name, "ADC 25 Mux")) && val > 0)
 531		val -= 1;
 532	ucontrol->value.enumerated.item[0] = val;
 533
 534	return 0;
 535}
 536
 537static int rt715_sdca_mux_put(struct snd_kcontrol *kcontrol,
 538			struct snd_ctl_elem_value *ucontrol)
 539{
 540	struct snd_soc_component *component = snd_soc_dapm_kcontrol_to_component(kcontrol);
 541	struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_to_dapm(kcontrol);
 542	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
 543	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
 544	unsigned int *item = ucontrol->value.enumerated.item;
 545	unsigned int val, val2 = 0, change, mask_sft;
 546
 547	if (item[0] >= e->items)
 548		return -EINVAL;
 549
 550	if (strstr(ucontrol->id.name, "ADC 22 Mux"))
 551		mask_sft = 12;
 552	else if (strstr(ucontrol->id.name, "ADC 23 Mux"))
 553		mask_sft = 8;
 554	else if (strstr(ucontrol->id.name, "ADC 24 Mux"))
 555		mask_sft = 4;
 556	else if (strstr(ucontrol->id.name, "ADC 25 Mux"))
 557		mask_sft = 0;
 558	else
 559		return -EINVAL;
 560
 561	/* Verb ID = 0x701h, nid = e->reg */
 562	val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;
 563
 564	rt715_sdca_index_read(rt715, RT715_VENDOR_HDA_CTL,
 565		RT715_HDA_LEGACY_MUX_CTL1, &val2);
 566	val2 = (val2 >> mask_sft) & 0xf;
 567
 568	change = val != val2;
 569
 570	if (change)
 571		rt715_sdca_index_update_bits(rt715, RT715_VENDOR_HDA_CTL,
 572			RT715_HDA_LEGACY_MUX_CTL1, 0xf << mask_sft, val << mask_sft);
 573
 574	snd_soc_dapm_mux_update_power(dapm, kcontrol, item[0], e, NULL);
 575
 576	return change;
 577}
 578
 579static const char * const adc_22_23_mux_text[] = {
 580	"MIC1",
 581	"MIC2",
 582	"LINE1",
 583	"LINE2",
 584	"DMIC1",
 585	"DMIC2",
 586	"DMIC3",
 587	"DMIC4",
 588};
 589
 590/*
 591 * Due to mux design for nid 24 (MUX_IN3)/25 (MUX_IN4), connection index 0 and
 592 * 1 will be connected to the same dmic source, therefore we skip index 1 to
 593 * avoid misunderstanding on usage of dapm routing.
 594 */
 595static int rt715_adc_24_25_values[] = {
 596	0,
 597	2,
 598	3,
 599	4,
 600	5,
 601};
 602
 603static const char * const adc_24_mux_text[] = {
 604	"MIC2",
 605	"DMIC1",
 606	"DMIC2",
 607	"DMIC3",
 608	"DMIC4",
 609};
 610
 611static const char * const adc_25_mux_text[] = {
 612	"MIC1",
 613	"DMIC1",
 614	"DMIC2",
 615	"DMIC3",
 616	"DMIC4",
 617};
 618
 619static SOC_ENUM_SINGLE_DECL(rt715_adc22_enum, SND_SOC_NOPM, 0,
 620	adc_22_23_mux_text);
 621
 622static SOC_ENUM_SINGLE_DECL(rt715_adc23_enum, SND_SOC_NOPM, 0,
 623	adc_22_23_mux_text);
 624
 625static SOC_VALUE_ENUM_SINGLE_DECL(rt715_adc24_enum,
 626	SND_SOC_NOPM, 0, 0xf,
 627	adc_24_mux_text, rt715_adc_24_25_values);
 628static SOC_VALUE_ENUM_SINGLE_DECL(rt715_adc25_enum,
 629	SND_SOC_NOPM, 0, 0xf,
 630	adc_25_mux_text, rt715_adc_24_25_values);
 631
 632static const struct snd_kcontrol_new rt715_adc22_mux =
 633	SOC_DAPM_ENUM_EXT("ADC 22 Mux", rt715_adc22_enum,
 634			rt715_sdca_mux_get, rt715_sdca_mux_put);
 635
 636static const struct snd_kcontrol_new rt715_adc23_mux =
 637	SOC_DAPM_ENUM_EXT("ADC 23 Mux", rt715_adc23_enum,
 638			rt715_sdca_mux_get, rt715_sdca_mux_put);
 639
 640static const struct snd_kcontrol_new rt715_adc24_mux =
 641	SOC_DAPM_ENUM_EXT("ADC 24 Mux", rt715_adc24_enum,
 642			rt715_sdca_mux_get, rt715_sdca_mux_put);
 643
 644static const struct snd_kcontrol_new rt715_adc25_mux =
 645	SOC_DAPM_ENUM_EXT("ADC 25 Mux", rt715_adc25_enum,
 646			rt715_sdca_mux_get, rt715_sdca_mux_put);
 647
 648static int rt715_sdca_pde23_24_event(struct snd_soc_dapm_widget *w,
 649	struct snd_kcontrol *kcontrol, int event)
 650{
 651	struct snd_soc_component *component =
 652		snd_soc_dapm_to_component(w->dapm);
 653	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
 654
 655	switch (event) {
 656	case SND_SOC_DAPM_POST_PMU:
 657		regmap_write(rt715->regmap,
 658			SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CREQ_POW_EN,
 659				RT715_SDCA_REQ_POW_CTRL,
 660				CH_00), 0x00);
 661		break;
 662	case SND_SOC_DAPM_PRE_PMD:
 663		regmap_write(rt715->regmap,
 664			SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CREQ_POW_EN,
 665				RT715_SDCA_REQ_POW_CTRL,
 666				CH_00), 0x03);
 667		break;
 668	}
 669	return 0;
 670}
 671
 672static const struct snd_soc_dapm_widget rt715_sdca_dapm_widgets[] = {
 673	SND_SOC_DAPM_INPUT("DMIC1"),
 674	SND_SOC_DAPM_INPUT("DMIC2"),
 675	SND_SOC_DAPM_INPUT("DMIC3"),
 676	SND_SOC_DAPM_INPUT("DMIC4"),
 677	SND_SOC_DAPM_INPUT("MIC1"),
 678	SND_SOC_DAPM_INPUT("MIC2"),
 679	SND_SOC_DAPM_INPUT("LINE1"),
 680	SND_SOC_DAPM_INPUT("LINE2"),
 681
 682	SND_SOC_DAPM_SUPPLY("PDE23_24", SND_SOC_NOPM, 0, 0,
 683		rt715_sdca_pde23_24_event,
 684		SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
 685
 686	SND_SOC_DAPM_ADC("ADC 07", NULL, SND_SOC_NOPM, 4, 0),
 687	SND_SOC_DAPM_ADC("ADC 08", NULL, SND_SOC_NOPM, 4, 0),
 688	SND_SOC_DAPM_ADC("ADC 09", NULL, SND_SOC_NOPM, 4, 0),
 689	SND_SOC_DAPM_ADC("ADC 27", NULL, SND_SOC_NOPM, 4, 0),
 690	SND_SOC_DAPM_MUX("ADC 22 Mux", SND_SOC_NOPM, 0, 0,
 691		&rt715_adc22_mux),
 692	SND_SOC_DAPM_MUX("ADC 23 Mux", SND_SOC_NOPM, 0, 0,
 693		&rt715_adc23_mux),
 694	SND_SOC_DAPM_MUX("ADC 24 Mux", SND_SOC_NOPM, 0, 0,
 695		&rt715_adc24_mux),
 696	SND_SOC_DAPM_MUX("ADC 25 Mux", SND_SOC_NOPM, 0, 0,
 697		&rt715_adc25_mux),
 698	SND_SOC_DAPM_AIF_OUT("DP4TX", "DP4 Capture", 0, SND_SOC_NOPM, 0, 0),
 699	SND_SOC_DAPM_AIF_OUT("DP6TX", "DP6 Capture", 0, SND_SOC_NOPM, 0, 0),
 700};
 701
 702static const struct snd_soc_dapm_route rt715_sdca_audio_map[] = {
 703	{"DP6TX", NULL, "ADC 09"},
 704	{"DP6TX", NULL, "ADC 08"},
 705	{"DP4TX", NULL, "ADC 07"},
 706	{"DP4TX", NULL, "ADC 27"},
 707	{"DP4TX", NULL, "ADC 09"},
 708	{"DP4TX", NULL, "ADC 08"},
 709
 710	{"LINE1", NULL, "PDE23_24"},
 711	{"LINE2", NULL, "PDE23_24"},
 712	{"MIC1", NULL, "PDE23_24"},
 713	{"MIC2", NULL, "PDE23_24"},
 714	{"DMIC1", NULL, "PDE23_24"},
 715	{"DMIC2", NULL, "PDE23_24"},
 716	{"DMIC3", NULL, "PDE23_24"},
 717	{"DMIC4", NULL, "PDE23_24"},
 718
 719	{"ADC 09", NULL, "ADC 22 Mux"},
 720	{"ADC 08", NULL, "ADC 23 Mux"},
 721	{"ADC 07", NULL, "ADC 24 Mux"},
 722	{"ADC 27", NULL, "ADC 25 Mux"},
 723	{"ADC 22 Mux", "MIC1", "MIC1"},
 724	{"ADC 22 Mux", "MIC2", "MIC2"},
 725	{"ADC 22 Mux", "LINE1", "LINE1"},
 726	{"ADC 22 Mux", "LINE2", "LINE2"},
 727	{"ADC 22 Mux", "DMIC1", "DMIC1"},
 728	{"ADC 22 Mux", "DMIC2", "DMIC2"},
 729	{"ADC 22 Mux", "DMIC3", "DMIC3"},
 730	{"ADC 22 Mux", "DMIC4", "DMIC4"},
 731	{"ADC 23 Mux", "MIC1", "MIC1"},
 732	{"ADC 23 Mux", "MIC2", "MIC2"},
 733	{"ADC 23 Mux", "LINE1", "LINE1"},
 734	{"ADC 23 Mux", "LINE2", "LINE2"},
 735	{"ADC 23 Mux", "DMIC1", "DMIC1"},
 736	{"ADC 23 Mux", "DMIC2", "DMIC2"},
 737	{"ADC 23 Mux", "DMIC3", "DMIC3"},
 738	{"ADC 23 Mux", "DMIC4", "DMIC4"},
 739	{"ADC 24 Mux", "MIC2", "MIC2"},
 740	{"ADC 24 Mux", "DMIC1", "DMIC1"},
 741	{"ADC 24 Mux", "DMIC2", "DMIC2"},
 742	{"ADC 24 Mux", "DMIC3", "DMIC3"},
 743	{"ADC 24 Mux", "DMIC4", "DMIC4"},
 744	{"ADC 25 Mux", "MIC1", "MIC1"},
 745	{"ADC 25 Mux", "DMIC1", "DMIC1"},
 746	{"ADC 25 Mux", "DMIC2", "DMIC2"},
 747	{"ADC 25 Mux", "DMIC3", "DMIC3"},
 748	{"ADC 25 Mux", "DMIC4", "DMIC4"},
 749};
 750
 751static int rt715_sdca_probe(struct snd_soc_component *component)
 752{
 753	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
 754	int ret;
 755
 756	if (!rt715->first_hw_init)
 757		return 0;
 758
 759	ret = pm_runtime_resume(component->dev);
 760	if (ret < 0 && ret != -EACCES)
 761		return ret;
 762
 763	return 0;
 764}
 765
 766static const struct snd_soc_component_driver soc_codec_dev_rt715_sdca = {
 767	.probe = rt715_sdca_probe,
 768	.controls = rt715_sdca_snd_controls,
 769	.num_controls = ARRAY_SIZE(rt715_sdca_snd_controls),
 770	.dapm_widgets = rt715_sdca_dapm_widgets,
 771	.num_dapm_widgets = ARRAY_SIZE(rt715_sdca_dapm_widgets),
 772	.dapm_routes = rt715_sdca_audio_map,
 773	.num_dapm_routes = ARRAY_SIZE(rt715_sdca_audio_map),
 774	.endianness = 1,
 775};
 776
 777static int rt715_sdca_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,
 778				int direction)
 779{
 780	snd_soc_dai_dma_data_set(dai, direction, sdw_stream);
 781
 782	return 0;
 783}
 784
 785static void rt715_sdca_shutdown(struct snd_pcm_substream *substream,
 786				struct snd_soc_dai *dai)
 787
 788{
 789	snd_soc_dai_set_dma_data(dai, substream, NULL);
 790}
 791
 792static int rt715_sdca_pcm_hw_params(struct snd_pcm_substream *substream,
 793				struct snd_pcm_hw_params *params,
 794				struct snd_soc_dai *dai)
 795{
 796	struct snd_soc_component *component = dai->component;
 797	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
 798	struct sdw_stream_config stream_config = {0};
 799	struct sdw_port_config port_config = {0};
 800	struct sdw_stream_runtime *sdw_stream;
 801	int retval;
 802	unsigned int val;
 803
 804	sdw_stream = snd_soc_dai_get_dma_data(dai, substream);
 805
 806	if (!sdw_stream)
 807		return -EINVAL;
 808
 809	if (!rt715->slave)
 810		return -EINVAL;
 811
 812	snd_sdw_params_to_config(substream, params, &stream_config, &port_config);
 813
 814	switch (dai->id) {
 815	case RT715_AIF1:
 816		port_config.num = 6;
 817		rt715_sdca_index_write(rt715, RT715_VENDOR_REG, RT715_SDW_INPUT_SEL,
 818			0xa500);
 819		break;
 820	case RT715_AIF2:
 821		port_config.num = 4;
 822		rt715_sdca_index_write(rt715, RT715_VENDOR_REG, RT715_SDW_INPUT_SEL,
 823			0xaf00);
 824		break;
 825	default:
 826		dev_err(component->dev, "%s: Invalid DAI id %d\n", __func__, dai->id);
 827		return -EINVAL;
 828	}
 829
 830	retval = sdw_stream_add_slave(rt715->slave, &stream_config,
 831					&port_config, 1, sdw_stream);
 832	if (retval) {
 833		dev_err(component->dev, "%s: Unable to configure port, retval:%d\n",
 834			__func__, retval);
 835		return retval;
 836	}
 837
 838	switch (params_rate(params)) {
 839	case 8000:
 840		val = 0x1;
 841		break;
 842	case 11025:
 843		val = 0x2;
 844		break;
 845	case 12000:
 846		val = 0x3;
 847		break;
 848	case 16000:
 849		val = 0x4;
 850		break;
 851	case 22050:
 852		val = 0x5;
 853		break;
 854	case 24000:
 855		val = 0x6;
 856		break;
 857	case 32000:
 858		val = 0x7;
 859		break;
 860	case 44100:
 861		val = 0x8;
 862		break;
 863	case 48000:
 864		val = 0x9;
 865		break;
 866	case 88200:
 867		val = 0xa;
 868		break;
 869	case 96000:
 870		val = 0xb;
 871		break;
 872	case 176400:
 873		val = 0xc;
 874		break;
 875	case 192000:
 876		val = 0xd;
 877		break;
 878	case 384000:
 879		val = 0xe;
 880		break;
 881	case 768000:
 882		val = 0xf;
 883		break;
 884	default:
 885		dev_err(component->dev, "%s: Unsupported sample rate %d\n",
 886			__func__, params_rate(params));
 887		return -EINVAL;
 888	}
 889
 890	regmap_write(rt715->regmap,
 891		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CS_FREQ_IND_EN,
 892			RT715_SDCA_FREQ_IND_CTRL, CH_00), val);
 893
 894	return 0;
 895}
 896
 897static int rt715_sdca_pcm_hw_free(struct snd_pcm_substream *substream,
 898				struct snd_soc_dai *dai)
 899{
 900	struct snd_soc_component *component = dai->component;
 901	struct rt715_sdca_priv *rt715 = snd_soc_component_get_drvdata(component);
 902	struct sdw_stream_runtime *sdw_stream =
 903		snd_soc_dai_get_dma_data(dai, substream);
 904
 905	if (!rt715->slave)
 906		return -EINVAL;
 907
 908	sdw_stream_remove_slave(rt715->slave, sdw_stream);
 909	return 0;
 910}
 911
 912#define RT715_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
 913#define RT715_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \
 914			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)
 915
 916static const struct snd_soc_dai_ops rt715_sdca_ops = {
 917	.hw_params	= rt715_sdca_pcm_hw_params,
 918	.hw_free	= rt715_sdca_pcm_hw_free,
 919	.set_stream	= rt715_sdca_set_sdw_stream,
 920	.shutdown	= rt715_sdca_shutdown,
 921};
 922
 923static struct snd_soc_dai_driver rt715_sdca_dai[] = {
 924	{
 925		.name = "rt715-sdca-aif1",
 926		.id = RT715_AIF1,
 927		.capture = {
 928			.stream_name = "DP6 Capture",
 929			.channels_min = 1,
 930			.channels_max = 2,
 931			.rates = RT715_STEREO_RATES,
 932			.formats = RT715_FORMATS,
 933		},
 934		.ops = &rt715_sdca_ops,
 935	},
 936	{
 937		.name = "rt715-sdca-aif2",
 938		.id = RT715_AIF2,
 939		.capture = {
 940			.stream_name = "DP4 Capture",
 941			.channels_min = 1,
 942			.channels_max = 2,
 943			.rates = RT715_STEREO_RATES,
 944			.formats = RT715_FORMATS,
 945		},
 946		.ops = &rt715_sdca_ops,
 947	},
 948};
 949
 950/* Bus clock frequency */
 951#define RT715_CLK_FREQ_9600000HZ 9600000
 952#define RT715_CLK_FREQ_12000000HZ 12000000
 953#define RT715_CLK_FREQ_6000000HZ 6000000
 954#define RT715_CLK_FREQ_4800000HZ 4800000
 955#define RT715_CLK_FREQ_2400000HZ 2400000
 956#define RT715_CLK_FREQ_12288000HZ 12288000
 957
 958int rt715_sdca_init(struct device *dev, struct regmap *mbq_regmap,
 959	struct regmap *regmap, struct sdw_slave *slave)
 960{
 961	struct rt715_sdca_priv *rt715;
 962	int ret;
 963
 964	rt715 = devm_kzalloc(dev, sizeof(*rt715), GFP_KERNEL);
 965	if (!rt715)
 966		return -ENOMEM;
 967
 968	dev_set_drvdata(dev, rt715);
 969	rt715->slave = slave;
 970	rt715->regmap = regmap;
 971	rt715->mbq_regmap = mbq_regmap;
 972	rt715->hw_sdw_ver = slave->id.sdw_version;
 973
 974	regcache_cache_only(rt715->regmap, true);
 975	regcache_cache_only(rt715->mbq_regmap, true);
 976
 977	/*
 978	 * Mark hw_init to false
 979	 * HW init will be performed when device reports present
 980	 */
 981	rt715->hw_init = false;
 982	rt715->first_hw_init = false;
 983
 984	ret = devm_snd_soc_register_component(dev,
 985			&soc_codec_dev_rt715_sdca,
 986			rt715_sdca_dai,
 987			ARRAY_SIZE(rt715_sdca_dai));
 988	if (ret < 0)
 989		return ret;
 990
 991	/* set autosuspend parameters */
 992	pm_runtime_set_autosuspend_delay(dev, 3000);
 993	pm_runtime_use_autosuspend(dev);
 994
 995	/* make sure the device does not suspend immediately */
 996	pm_runtime_mark_last_busy(dev);
 997
 998	pm_runtime_enable(dev);
 999
1000	/* important note: the device is NOT tagged as 'active' and will remain
1001	 * 'suspended' until the hardware is enumerated/initialized. This is required
1002	 * to make sure the ASoC framework use of pm_runtime_get_sync() does not silently
1003	 * fail with -EACCESS because of race conditions between card creation and enumeration
1004	 */
1005
1006	dev_dbg(dev, "%s\n", __func__);
1007
1008	return ret;
1009}
1010
1011int rt715_sdca_io_init(struct device *dev, struct sdw_slave *slave)
1012{
1013	struct rt715_sdca_priv *rt715 = dev_get_drvdata(dev);
1014	unsigned int hw_ver;
1015
1016	if (rt715->hw_init)
1017		return 0;
1018
1019	regcache_cache_only(rt715->regmap, false);
1020	regcache_cache_only(rt715->mbq_regmap, false);
1021
1022	/*
1023	 * PM runtime status is marked as 'active' only when a Slave reports as Attached
1024	 */
1025	if (!rt715->first_hw_init) {
1026		/* update count of parent 'active' children */
1027		pm_runtime_set_active(&slave->dev);
1028
1029		rt715->first_hw_init = true;
1030	}
1031
1032	pm_runtime_get_noresume(&slave->dev);
1033
1034	rt715_sdca_index_read(rt715, RT715_VENDOR_REG,
1035		RT715_PRODUCT_NUM, &hw_ver);
1036	hw_ver = hw_ver & 0x000f;
1037
1038	/* set clock selector = external */
1039	regmap_write(rt715->regmap,
1040		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_CX_CLK_SEL_EN,
1041			RT715_SDCA_CX_CLK_SEL_CTRL, CH_00), 0x1);
1042	/* set GPIO_4/5/6 to be 3rd/4th DMIC usage */
1043	if (hw_ver == 0x0)
1044		rt715_sdca_index_update_bits(rt715, RT715_VENDOR_REG,
1045			RT715_AD_FUNC_EN, 0x54, 0x54);
1046	else if (hw_ver == 0x1) {
1047		rt715_sdca_index_update_bits(rt715, RT715_VENDOR_REG,
1048			RT715_AD_FUNC_EN, 0x55, 0x55);
1049		rt715_sdca_index_update_bits(rt715, RT715_VENDOR_REG,
1050			RT715_REV_1, 0x40, 0x40);
1051	}
1052	/* DFLL Calibration trigger */
1053	rt715_sdca_index_update_bits(rt715, RT715_VENDOR_REG,
1054			RT715_DFLL_VAD, 0x1, 0x1);
1055	/* trigger mode = VAD enable */
1056	regmap_write(rt715->regmap,
1057		SDW_SDCA_CTL(FUN_MIC_ARRAY, RT715_SDCA_SMPU_TRIG_ST_EN,
1058			RT715_SDCA_SMPU_TRIG_EN_CTRL, CH_00), 0x2);
1059	/* SMPU-1 interrupt enable mask */
1060	regmap_update_bits(rt715->regmap, RT715_INT_MASK, 0x1, 0x1);
1061
1062	/* Mark Slave initialization complete */
1063	rt715->hw_init = true;
1064
1065	pm_runtime_put_autosuspend(&slave->dev);
1066
1067	return 0;
1068}
1069
1070MODULE_DESCRIPTION("ASoC rt715 driver SDW SDCA");
1071MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>");
1072MODULE_LICENSE("GPL v2");
~/ Read-only file preview.