1150 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * rt715.c -- rt715 ALSA SoC audio driver4 *5 * Copyright(c) 2019 Realtek Semiconductor Corp.6 *7 * ALC715 ASoC Codec Driver based Intel Dummy SdW codec driver8 *9 */10 11#include <linux/module.h>12#include <linux/kernel.h>13#include <linux/init.h>14#include <linux/delay.h>15#include <linux/i2c.h>16#include <linux/pm_runtime.h>17#include <linux/pm.h>18#include <linux/soundwire/sdw.h>19#include <linux/regmap.h>20#include <linux/slab.h>21#include <linux/platform_device.h>22#include <linux/regulator/consumer.h>23#include <sound/core.h>24#include <sound/pcm.h>25#include <sound/pcm_params.h>26#include <sound/sdw.h>27#include <sound/soc.h>28#include <sound/soc-dapm.h>29#include <sound/initval.h>30#include <sound/tlv.h>31#include <sound/hda_verbs.h>32 33#include "rt715.h"34 35static int rt715_index_write(struct regmap *regmap, unsigned int reg,36 unsigned int value)37{38 int ret;39 unsigned int addr = ((RT715_PRIV_INDEX_W_H) << 8) | reg;40 41 ret = regmap_write(regmap, addr, value);42 if (ret < 0) {43 pr_err("%s: Failed to set private value: %08x <= %04x %d\n",44 __func__, addr, value, ret);45 }46 47 return ret;48}49 50static int rt715_index_write_nid(struct regmap *regmap,51 unsigned int nid, unsigned int reg, unsigned int value)52{53 int ret;54 unsigned int addr = ((RT715_PRIV_INDEX_W_H_2 | nid) << 8) | reg;55 56 ret = regmap_write(regmap, addr, value);57 if (ret < 0)58 pr_err("%s: Failed to set private value: %06x <= %04x ret=%d\n",59 __func__, addr, value, ret);60 61 return ret;62}63 64static int rt715_index_read_nid(struct regmap *regmap,65 unsigned int nid, unsigned int reg, unsigned int *value)66{67 int ret;68 unsigned int addr = ((RT715_PRIV_INDEX_W_H_2 | nid) << 8) | reg;69 70 *value = 0;71 ret = regmap_read(regmap, addr, value);72 if (ret < 0)73 pr_err("%s: Failed to get private value: %06x => %04x ret=%d\n",74 __func__, addr, *value, ret);75 76 return ret;77}78 79static int rt715_index_update_bits(struct regmap *regmap, unsigned int nid,80 unsigned int reg, unsigned int mask, unsigned int val)81{82 unsigned int tmp, orig;83 int ret;84 85 ret = rt715_index_read_nid(regmap, nid, reg, &orig);86 if (ret < 0)87 return ret;88 89 tmp = orig & ~mask;90 tmp |= val & mask;91 92 return rt715_index_write_nid(regmap, nid, reg, tmp);93}94 95static void rt715_reset(struct regmap *regmap)96{97 regmap_write(regmap, RT715_FUNC_RESET, 0);98 rt715_index_update_bits(regmap, RT715_VENDOR_REGISTERS,99 RT715_VD_CLEAR_CTRL, RT715_CLEAR_HIDDEN_REG,100 RT715_CLEAR_HIDDEN_REG);101}102 103 104static void rt715_get_gain(struct rt715_priv *rt715, unsigned int addr_h,105 unsigned int addr_l, unsigned int val_h,106 unsigned int *r_val, unsigned int *l_val)107{108 int ret;109 /* R Channel */110 *r_val = val_h << 8;111 ret = regmap_read(rt715->regmap, addr_l, r_val);112 if (ret < 0)113 pr_err("Failed to get R channel gain.\n");114 115 /* L Channel */116 val_h |= 0x20;117 *l_val = val_h << 8;118 ret = regmap_read(rt715->regmap, addr_h, l_val);119 if (ret < 0)120 pr_err("Failed to get L channel gain.\n");121}122 123/* For Verb-Set Amplifier Gain (Verb ID = 3h) */124static int rt715_set_amp_gain_put(struct snd_kcontrol *kcontrol,125 struct snd_ctl_elem_value *ucontrol)126{127 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);128 struct snd_soc_dapm_context *dapm =129 snd_soc_component_get_dapm(component);130 struct soc_mixer_control *mc =131 (struct soc_mixer_control *)kcontrol->private_value;132 struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);133 unsigned int addr_h, addr_l, val_h, val_ll, val_lr;134 unsigned int read_ll, read_rl, i;135 unsigned int k_vol_changed = 0;136 137 for (i = 0; i < 2; i++) {138 if (ucontrol->value.integer.value[i] != rt715->kctl_2ch_vol_ori[i]) {139 k_vol_changed = 1;140 break;141 }142 }143 144 /* Can't use update bit function, so read the original value first */145 addr_h = mc->reg;146 addr_l = mc->rreg;147 148 if (mc->shift == RT715_DIR_OUT_SFT) /* output */149 val_h = 0x80;150 else /* input */151 val_h = 0x0;152 153 rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll);154 155 if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)156 regmap_write(rt715->regmap,157 RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D0);158 159 /* L Channel */160 rt715->kctl_2ch_vol_ori[0] = ucontrol->value.integer.value[0];161 /* for gain */162 val_ll = ((ucontrol->value.integer.value[0]) & 0x7f);163 if (val_ll > mc->max)164 val_ll = mc->max;165 /* keep mute status */166 val_ll |= read_ll & 0x80;167 168 /* R Channel */169 rt715->kctl_2ch_vol_ori[1] = ucontrol->value.integer.value[1];170 /* for gain */171 val_lr = ((ucontrol->value.integer.value[1]) & 0x7f);172 if (val_lr > mc->max)173 val_lr = mc->max;174 /* keep mute status */175 val_lr |= read_rl & 0x80;176 177 for (i = 0; i < 3; i++) { /* retry 3 times at most */178 179 if (val_ll == val_lr) {180 /* Set both L/R channels at the same time */181 val_h = (1 << mc->shift) | (3 << 4);182 regmap_write(rt715->regmap, addr_h,183 (val_h << 8) | val_ll);184 regmap_write(rt715->regmap, addr_l,185 (val_h << 8) | val_ll);186 } else {187 /* Lch*/188 val_h = (1 << mc->shift) | (1 << 5);189 regmap_write(rt715->regmap, addr_h,190 (val_h << 8) | val_ll);191 /* Rch */192 val_h = (1 << mc->shift) | (1 << 4);193 regmap_write(rt715->regmap, addr_l,194 (val_h << 8) | val_lr);195 }196 /* check result */197 if (mc->shift == RT715_DIR_OUT_SFT) /* output */198 val_h = 0x80;199 else /* input */200 val_h = 0x0;201 202 rt715_get_gain(rt715, addr_h, addr_l, val_h,203 &read_rl, &read_ll);204 if (read_rl == val_lr && read_ll == val_ll)205 break;206 }207 208 /* D0:power on state, D3: power saving mode */209 if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)210 regmap_write(rt715->regmap,211 RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D3);212 return k_vol_changed;213}214 215static int rt715_set_amp_gain_get(struct snd_kcontrol *kcontrol,216 struct snd_ctl_elem_value *ucontrol)217{218 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);219 struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);220 struct soc_mixer_control *mc =221 (struct soc_mixer_control *)kcontrol->private_value;222 unsigned int addr_h, addr_l, val_h;223 unsigned int read_ll, read_rl;224 225 addr_h = mc->reg;226 addr_l = mc->rreg;227 if (mc->shift == RT715_DIR_OUT_SFT) /* output */228 val_h = 0x80;229 else /* input */230 val_h = 0x0;231 232 rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll);233 234 if (mc->invert) {235 /* for mute status */236 read_ll = !(read_ll & 0x80);237 read_rl = !(read_rl & 0x80);238 } else {239 /* for gain */240 read_ll = read_ll & 0x7f;241 read_rl = read_rl & 0x7f;242 }243 ucontrol->value.integer.value[0] = read_ll;244 ucontrol->value.integer.value[1] = read_rl;245 246 return 0;247}248 249static int rt715_set_main_switch_put(struct snd_kcontrol *kcontrol,250 struct snd_ctl_elem_value *ucontrol)251{252 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);253 struct snd_soc_dapm_context *dapm =254 snd_soc_component_get_dapm(component);255 struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);256 static const unsigned int capture_reg_H[] = {257 RT715_SET_GAIN_MIC_ADC_H, RT715_SET_GAIN_LINE_ADC_H,258 RT715_SET_GAIN_MIX_ADC_H, RT715_SET_GAIN_MIX_ADC2_H };259 static const unsigned int capture_reg_L[] = {260 RT715_SET_GAIN_MIC_ADC_L, RT715_SET_GAIN_LINE_ADC_L,261 RT715_SET_GAIN_MIX_ADC_L, RT715_SET_GAIN_MIX_ADC2_L };262 unsigned int addr_h, addr_l, val_h = 0x0, val_ll, val_lr;263 unsigned int k_shift = RT715_DIR_IN_SFT, k_changed = 0;264 unsigned int read_ll, read_rl, i, j, loop_cnt = 4;265 266 for (i = 0; i < 8; i++) {267 if (ucontrol->value.integer.value[i] != rt715->kctl_8ch_switch_ori[i])268 k_changed = 1;269 }270 271 for (j = 0; j < loop_cnt; j++) {272 /* Can't use update bit function, so read the original value first */273 addr_h = capture_reg_H[j];274 addr_l = capture_reg_L[j];275 rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll);276 277 if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)278 regmap_write(rt715->regmap,279 RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D0);280 281 /* L Channel */282 /* for mute */283 rt715->kctl_8ch_switch_ori[j * 2] =284 ucontrol->value.integer.value[j * 2];285 val_ll = (!ucontrol->value.integer.value[j * 2]) << 7;286 /* keep gain */287 val_ll |= read_ll & 0x7f;288 289 /* R Channel */290 /* for mute */291 rt715->kctl_8ch_switch_ori[j * 2 + 1] =292 ucontrol->value.integer.value[j * 2 + 1];293 val_lr = (!ucontrol->value.integer.value[j * 2 + 1]) << 7;294 /* keep gain */295 val_lr |= read_rl & 0x7f;296 297 for (i = 0; i < 3; i++) { /* retry 3 times at most */298 299 if (val_ll == val_lr) {300 /* Set both L/R channels at the same time */301 val_h = (1 << k_shift) | (3 << 4);302 regmap_write(rt715->regmap, addr_h,303 (val_h << 8) | val_ll);304 regmap_write(rt715->regmap, addr_l,305 (val_h << 8) | val_ll);306 } else {307 /* Lch*/308 val_h = (1 << k_shift) | (1 << 5);309 regmap_write(rt715->regmap, addr_h,310 (val_h << 8) | val_ll);311 /* Rch */312 val_h = (1 << k_shift) | (1 << 4);313 regmap_write(rt715->regmap, addr_l,314 (val_h << 8) | val_lr);315 }316 val_h = 0x0;317 rt715_get_gain(rt715, addr_h, addr_l, val_h,318 &read_rl, &read_ll);319 if (read_rl == val_lr && read_ll == val_ll)320 break;321 }322 }323 324 /* D0:power on state, D3: power saving mode */325 if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)326 regmap_write(rt715->regmap,327 RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D3);328 return k_changed;329}330 331static int rt715_set_main_switch_get(struct snd_kcontrol *kcontrol,332 struct snd_ctl_elem_value *ucontrol)333{334 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);335 struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);336 static const unsigned int capture_reg_H[] = {337 RT715_SET_GAIN_MIC_ADC_H, RT715_SET_GAIN_LINE_ADC_H,338 RT715_SET_GAIN_MIX_ADC_H, RT715_SET_GAIN_MIX_ADC2_H };339 static const unsigned int capture_reg_L[] = {340 RT715_SET_GAIN_MIC_ADC_L, RT715_SET_GAIN_LINE_ADC_L,341 RT715_SET_GAIN_MIX_ADC_L, RT715_SET_GAIN_MIX_ADC2_L };342 unsigned int addr_h, addr_l, val_h = 0x0, i, loop_cnt = 4;343 unsigned int read_ll, read_rl;344 345 for (i = 0; i < loop_cnt; i++) {346 addr_h = capture_reg_H[i];347 addr_l = capture_reg_L[i];348 rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll);349 350 ucontrol->value.integer.value[i * 2] = !(read_ll & 0x80);351 ucontrol->value.integer.value[i * 2 + 1] = !(read_rl & 0x80);352 }353 354 return 0;355}356 357static int rt715_set_main_vol_put(struct snd_kcontrol *kcontrol,358 struct snd_ctl_elem_value *ucontrol)359{360 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);361 struct snd_soc_dapm_context *dapm =362 snd_soc_component_get_dapm(component);363 struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);364 static const unsigned int capture_reg_H[] = {365 RT715_SET_GAIN_MIC_ADC_H, RT715_SET_GAIN_LINE_ADC_H,366 RT715_SET_GAIN_MIX_ADC_H, RT715_SET_GAIN_MIX_ADC2_H };367 static const unsigned int capture_reg_L[] = {368 RT715_SET_GAIN_MIC_ADC_L, RT715_SET_GAIN_LINE_ADC_L,369 RT715_SET_GAIN_MIX_ADC_L, RT715_SET_GAIN_MIX_ADC2_L};370 unsigned int addr_h, addr_l, val_h = 0x0, val_ll, val_lr;371 unsigned int read_ll, read_rl, i, j, loop_cnt = 4, k_changed = 0;372 unsigned int k_shift = RT715_DIR_IN_SFT, k_max = 0x3f;373 374 for (i = 0; i < 8; i++) {375 if (ucontrol->value.integer.value[i] != rt715->kctl_8ch_vol_ori[i])376 k_changed = 1;377 }378 379 for (j = 0; j < loop_cnt; j++) {380 addr_h = capture_reg_H[j];381 addr_l = capture_reg_L[j];382 rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll);383 384 if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)385 regmap_write(rt715->regmap,386 RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D0);387 388 /* L Channel */389 /* for gain */390 rt715->kctl_8ch_vol_ori[j * 2] = ucontrol->value.integer.value[j * 2];391 val_ll = ((ucontrol->value.integer.value[j * 2]) & 0x7f);392 if (val_ll > k_max)393 val_ll = k_max;394 /* keep mute status */395 val_ll |= read_ll & 0x80;396 397 /* R Channel */398 /* for gain */399 rt715->kctl_8ch_vol_ori[j * 2 + 1] =400 ucontrol->value.integer.value[j * 2 + 1];401 val_lr = ((ucontrol->value.integer.value[j * 2 + 1]) & 0x7f);402 if (val_lr > k_max)403 val_lr = k_max;404 /* keep mute status */405 val_lr |= read_rl & 0x80;406 407 for (i = 0; i < 3; i++) { /* retry 3 times at most */408 if (val_ll == val_lr) {409 /* Set both L/R channels at the same time */410 val_h = (1 << k_shift) | (3 << 4);411 regmap_write(rt715->regmap, addr_h,412 (val_h << 8) | val_ll);413 regmap_write(rt715->regmap, addr_l,414 (val_h << 8) | val_ll);415 } else {416 /* Lch*/417 val_h = (1 << k_shift) | (1 << 5);418 regmap_write(rt715->regmap, addr_h,419 (val_h << 8) | val_ll);420 /* Rch */421 val_h = (1 << k_shift) | (1 << 4);422 regmap_write(rt715->regmap, addr_l,423 (val_h << 8) | val_lr);424 }425 val_h = 0x0;426 rt715_get_gain(rt715, addr_h, addr_l, val_h,427 &read_rl, &read_ll);428 if (read_rl == val_lr && read_ll == val_ll)429 break;430 }431 }432 433 /* D0:power on state, D3: power saving mode */434 if (dapm->bias_level <= SND_SOC_BIAS_STANDBY)435 regmap_write(rt715->regmap,436 RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D3);437 return k_changed;438}439 440static int rt715_set_main_vol_get(struct snd_kcontrol *kcontrol,441 struct snd_ctl_elem_value *ucontrol)442{443 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);444 struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);445 static const unsigned int capture_reg_H[] = {446 RT715_SET_GAIN_MIC_ADC_H, RT715_SET_GAIN_LINE_ADC_H,447 RT715_SET_GAIN_MIX_ADC_H, RT715_SET_GAIN_MIX_ADC2_H };448 static const unsigned int capture_reg_L[] = {449 RT715_SET_GAIN_MIC_ADC_L, RT715_SET_GAIN_LINE_ADC_L,450 RT715_SET_GAIN_MIX_ADC_L, RT715_SET_GAIN_MIX_ADC2_L };451 unsigned int addr_h, addr_l, val_h = 0x0, i, loop_cnt = 4;452 unsigned int read_ll, read_rl;453 454 for (i = 0; i < loop_cnt; i++) {455 addr_h = capture_reg_H[i];456 addr_l = capture_reg_L[i];457 rt715_get_gain(rt715, addr_h, addr_l, val_h, &read_rl, &read_ll);458 459 ucontrol->value.integer.value[i * 2] = read_ll & 0x7f;460 ucontrol->value.integer.value[i * 2 + 1] = read_rl & 0x7f;461 }462 463 return 0;464}465 466static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -1725, 75, 0);467static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0);468 469static int rt715_switch_info(struct snd_kcontrol *kcontrol,470 struct snd_ctl_elem_info *uinfo)471{472 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;473 uinfo->count = 8;474 uinfo->value.integer.min = 0;475 uinfo->value.integer.max = 1;476 return 0;477}478 479static int rt715_vol_info(struct snd_kcontrol *kcontrol,480 struct snd_ctl_elem_info *uinfo)481{482 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;483 uinfo->count = 8;484 uinfo->value.integer.min = 0;485 uinfo->value.integer.max = 0x3f;486 return 0;487}488 489#define SOC_DOUBLE_R_EXT(xname, reg_left, reg_right, xshift, xmax, xinvert,\490 xhandler_get, xhandler_put) \491{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \492 .info = snd_soc_info_volsw, \493 .get = xhandler_get, .put = xhandler_put, \494 .private_value = SOC_DOUBLE_R_VALUE(reg_left, reg_right, xshift, \495 xmax, xinvert) }496 497#define RT715_MAIN_SWITCH_EXT(xname, xhandler_get, xhandler_put) \498{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \499 .info = rt715_switch_info, \500 .get = xhandler_get, .put = xhandler_put, \501}502 503#define RT715_MAIN_VOL_EXT_TLV(xname, xhandler_get, xhandler_put, tlv_array) \504{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \505 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \506 SNDRV_CTL_ELEM_ACCESS_READWRITE, \507 .tlv.p = (tlv_array), \508 .info = rt715_vol_info, \509 .get = xhandler_get, .put = xhandler_put, \510}511 512static const struct snd_kcontrol_new rt715_snd_controls[] = {513 /* Capture switch */514 RT715_MAIN_SWITCH_EXT("Capture Switch",515 rt715_set_main_switch_get, rt715_set_main_switch_put),516 /* Volume Control */517 RT715_MAIN_VOL_EXT_TLV("Capture Volume",518 rt715_set_main_vol_get, rt715_set_main_vol_put, in_vol_tlv),519 /* MIC Boost Control */520 SOC_DOUBLE_R_EXT_TLV("DMIC1 Boost", RT715_SET_GAIN_DMIC1_H,521 RT715_SET_GAIN_DMIC1_L, RT715_DIR_IN_SFT, 3, 0,522 rt715_set_amp_gain_get, rt715_set_amp_gain_put,523 mic_vol_tlv),524 SOC_DOUBLE_R_EXT_TLV("DMIC2 Boost", RT715_SET_GAIN_DMIC2_H,525 RT715_SET_GAIN_DMIC2_L, RT715_DIR_IN_SFT, 3, 0,526 rt715_set_amp_gain_get, rt715_set_amp_gain_put,527 mic_vol_tlv),528 SOC_DOUBLE_R_EXT_TLV("DMIC3 Boost", RT715_SET_GAIN_DMIC3_H,529 RT715_SET_GAIN_DMIC3_L, RT715_DIR_IN_SFT, 3, 0,530 rt715_set_amp_gain_get, rt715_set_amp_gain_put,531 mic_vol_tlv),532 SOC_DOUBLE_R_EXT_TLV("DMIC4 Boost", RT715_SET_GAIN_DMIC4_H,533 RT715_SET_GAIN_DMIC4_L, RT715_DIR_IN_SFT, 3, 0,534 rt715_set_amp_gain_get, rt715_set_amp_gain_put,535 mic_vol_tlv),536 SOC_DOUBLE_R_EXT_TLV("MIC1 Boost", RT715_SET_GAIN_MIC1_H,537 RT715_SET_GAIN_MIC1_L, RT715_DIR_IN_SFT, 3, 0,538 rt715_set_amp_gain_get, rt715_set_amp_gain_put,539 mic_vol_tlv),540 SOC_DOUBLE_R_EXT_TLV("MIC2 Boost", RT715_SET_GAIN_MIC2_H,541 RT715_SET_GAIN_MIC2_L, RT715_DIR_IN_SFT, 3, 0,542 rt715_set_amp_gain_get, rt715_set_amp_gain_put,543 mic_vol_tlv),544 SOC_DOUBLE_R_EXT_TLV("LINE1 Boost", RT715_SET_GAIN_LINE1_H,545 RT715_SET_GAIN_LINE1_L, RT715_DIR_IN_SFT, 3, 0,546 rt715_set_amp_gain_get, rt715_set_amp_gain_put,547 mic_vol_tlv),548 SOC_DOUBLE_R_EXT_TLV("LINE2 Boost", RT715_SET_GAIN_LINE2_H,549 RT715_SET_GAIN_LINE2_L, RT715_DIR_IN_SFT, 3, 0,550 rt715_set_amp_gain_get, rt715_set_amp_gain_put,551 mic_vol_tlv),552};553 554static int rt715_mux_get(struct snd_kcontrol *kcontrol,555 struct snd_ctl_elem_value *ucontrol)556{557 struct snd_soc_component *component =558 snd_soc_dapm_kcontrol_component(kcontrol);559 struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);560 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;561 unsigned int reg, val;562 int ret;563 564 /* nid = e->reg, vid = 0xf01 */565 reg = RT715_VERB_SET_CONNECT_SEL | e->reg;566 ret = regmap_read(rt715->regmap, reg, &val);567 if (ret < 0) {568 dev_err(component->dev, "%s: sdw read failed: %d\n",569 __func__, ret);570 return ret;571 }572 573 /*574 * The first two indices of ADC Mux 24/25 are routed to the same575 * hardware source. ie, ADC Mux 24 0/1 will both connect to MIC2.576 * To have a unique set of inputs, we skip the index1 of the muxes.577 */578 if ((e->reg == RT715_MUX_IN3 || e->reg == RT715_MUX_IN4) && (val > 0))579 val -= 1;580 ucontrol->value.enumerated.item[0] = val;581 582 return 0;583}584 585static int rt715_mux_put(struct snd_kcontrol *kcontrol,586 struct snd_ctl_elem_value *ucontrol)587{588 struct snd_soc_component *component =589 snd_soc_dapm_kcontrol_component(kcontrol);590 struct snd_soc_dapm_context *dapm =591 snd_soc_dapm_kcontrol_dapm(kcontrol);592 struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);593 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;594 unsigned int *item = ucontrol->value.enumerated.item;595 unsigned int val, val2 = 0, change, reg;596 int ret;597 598 if (item[0] >= e->items)599 return -EINVAL;600 601 /* Verb ID = 0x701h, nid = e->reg */602 val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;603 604 reg = RT715_VERB_SET_CONNECT_SEL | e->reg;605 ret = regmap_read(rt715->regmap, reg, &val2);606 if (ret < 0) {607 dev_err(component->dev, "%s: sdw read failed: %d\n",608 __func__, ret);609 return ret;610 }611 612 if (val == val2)613 change = 0;614 else615 change = 1;616 617 if (change) {618 reg = RT715_VERB_SET_CONNECT_SEL | e->reg;619 regmap_write(rt715->regmap, reg, val);620 }621 622 snd_soc_dapm_mux_update_power(dapm, kcontrol,623 item[0], e, NULL);624 625 return change;626}627 628static const char * const adc_22_23_mux_text[] = {629 "MIC1",630 "MIC2",631 "LINE1",632 "LINE2",633 "DMIC1",634 "DMIC2",635 "DMIC3",636 "DMIC4",637};638 639/*640 * Due to mux design for nid 24 (MUX_IN3)/25 (MUX_IN4), connection index 0 and641 * 1 will be connected to the same dmic source, therefore we skip index 1 to642 * avoid misunderstanding on usage of dapm routing.643 */644static const unsigned int rt715_adc_24_25_values[] = {645 0,646 2,647 3,648 4,649 5,650};651 652static const char * const adc_24_mux_text[] = {653 "MIC2",654 "DMIC1",655 "DMIC2",656 "DMIC3",657 "DMIC4",658};659 660static const char * const adc_25_mux_text[] = {661 "MIC1",662 "DMIC1",663 "DMIC2",664 "DMIC3",665 "DMIC4",666};667 668static SOC_ENUM_SINGLE_DECL(669 rt715_adc22_enum, RT715_MUX_IN1, 0, adc_22_23_mux_text);670 671static SOC_ENUM_SINGLE_DECL(672 rt715_adc23_enum, RT715_MUX_IN2, 0, adc_22_23_mux_text);673 674static SOC_VALUE_ENUM_SINGLE_DECL(rt715_adc24_enum,675 RT715_MUX_IN3, 0, 0xf,676 adc_24_mux_text, rt715_adc_24_25_values);677 678static SOC_VALUE_ENUM_SINGLE_DECL(rt715_adc25_enum,679 RT715_MUX_IN4, 0, 0xf,680 adc_25_mux_text, rt715_adc_24_25_values);681 682static const struct snd_kcontrol_new rt715_adc22_mux =683 SOC_DAPM_ENUM_EXT("ADC 22 Mux", rt715_adc22_enum,684 rt715_mux_get, rt715_mux_put);685 686static const struct snd_kcontrol_new rt715_adc23_mux =687 SOC_DAPM_ENUM_EXT("ADC 23 Mux", rt715_adc23_enum,688 rt715_mux_get, rt715_mux_put);689 690static const struct snd_kcontrol_new rt715_adc24_mux =691 SOC_DAPM_ENUM_EXT("ADC 24 Mux", rt715_adc24_enum,692 rt715_mux_get, rt715_mux_put);693 694static const struct snd_kcontrol_new rt715_adc25_mux =695 SOC_DAPM_ENUM_EXT("ADC 25 Mux", rt715_adc25_enum,696 rt715_mux_get, rt715_mux_put);697 698static const struct snd_soc_dapm_widget rt715_dapm_widgets[] = {699 SND_SOC_DAPM_INPUT("DMIC1"),700 SND_SOC_DAPM_INPUT("DMIC2"),701 SND_SOC_DAPM_INPUT("DMIC3"),702 SND_SOC_DAPM_INPUT("DMIC4"),703 SND_SOC_DAPM_INPUT("MIC1"),704 SND_SOC_DAPM_INPUT("MIC2"),705 SND_SOC_DAPM_INPUT("LINE1"),706 SND_SOC_DAPM_INPUT("LINE2"),707 SND_SOC_DAPM_ADC("ADC 07", NULL, RT715_SET_STREAMID_MIC_ADC, 4, 0),708 SND_SOC_DAPM_ADC("ADC 08", NULL, RT715_SET_STREAMID_LINE_ADC, 4, 0),709 SND_SOC_DAPM_ADC("ADC 09", NULL, RT715_SET_STREAMID_MIX_ADC, 4, 0),710 SND_SOC_DAPM_ADC("ADC 27", NULL, RT715_SET_STREAMID_MIX_ADC2, 4, 0),711 SND_SOC_DAPM_MUX("ADC 22 Mux", SND_SOC_NOPM, 0, 0,712 &rt715_adc22_mux),713 SND_SOC_DAPM_MUX("ADC 23 Mux", SND_SOC_NOPM, 0, 0,714 &rt715_adc23_mux),715 SND_SOC_DAPM_MUX("ADC 24 Mux", SND_SOC_NOPM, 0, 0,716 &rt715_adc24_mux),717 SND_SOC_DAPM_MUX("ADC 25 Mux", SND_SOC_NOPM, 0, 0,718 &rt715_adc25_mux),719 SND_SOC_DAPM_AIF_OUT("DP4TX", "DP4 Capture", 0, SND_SOC_NOPM, 0, 0),720 SND_SOC_DAPM_AIF_OUT("DP6TX", "DP6 Capture", 0, SND_SOC_NOPM, 0, 0),721};722 723static const struct snd_soc_dapm_route rt715_audio_map[] = {724 {"DP6TX", NULL, "ADC 09"},725 {"DP6TX", NULL, "ADC 08"},726 {"DP4TX", NULL, "ADC 07"},727 {"DP4TX", NULL, "ADC 27"},728 {"ADC 09", NULL, "ADC 22 Mux"},729 {"ADC 08", NULL, "ADC 23 Mux"},730 {"ADC 07", NULL, "ADC 24 Mux"},731 {"ADC 27", NULL, "ADC 25 Mux"},732 {"ADC 22 Mux", "MIC1", "MIC1"},733 {"ADC 22 Mux", "MIC2", "MIC2"},734 {"ADC 22 Mux", "LINE1", "LINE1"},735 {"ADC 22 Mux", "LINE2", "LINE2"},736 {"ADC 22 Mux", "DMIC1", "DMIC1"},737 {"ADC 22 Mux", "DMIC2", "DMIC2"},738 {"ADC 22 Mux", "DMIC3", "DMIC3"},739 {"ADC 22 Mux", "DMIC4", "DMIC4"},740 {"ADC 23 Mux", "MIC1", "MIC1"},741 {"ADC 23 Mux", "MIC2", "MIC2"},742 {"ADC 23 Mux", "LINE1", "LINE1"},743 {"ADC 23 Mux", "LINE2", "LINE2"},744 {"ADC 23 Mux", "DMIC1", "DMIC1"},745 {"ADC 23 Mux", "DMIC2", "DMIC2"},746 {"ADC 23 Mux", "DMIC3", "DMIC3"},747 {"ADC 23 Mux", "DMIC4", "DMIC4"},748 {"ADC 24 Mux", "MIC2", "MIC2"},749 {"ADC 24 Mux", "DMIC1", "DMIC1"},750 {"ADC 24 Mux", "DMIC2", "DMIC2"},751 {"ADC 24 Mux", "DMIC3", "DMIC3"},752 {"ADC 24 Mux", "DMIC4", "DMIC4"},753 {"ADC 25 Mux", "MIC1", "MIC1"},754 {"ADC 25 Mux", "DMIC1", "DMIC1"},755 {"ADC 25 Mux", "DMIC2", "DMIC2"},756 {"ADC 25 Mux", "DMIC3", "DMIC3"},757 {"ADC 25 Mux", "DMIC4", "DMIC4"},758};759 760static int rt715_set_bias_level(struct snd_soc_component *component,761 enum snd_soc_bias_level level)762{763 struct snd_soc_dapm_context *dapm =764 snd_soc_component_get_dapm(component);765 struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);766 767 switch (level) {768 case SND_SOC_BIAS_PREPARE:769 if (dapm->bias_level == SND_SOC_BIAS_STANDBY) {770 regmap_write(rt715->regmap,771 RT715_SET_AUDIO_POWER_STATE,772 AC_PWRST_D0);773 msleep(RT715_POWER_UP_DELAY_MS);774 }775 break;776 777 case SND_SOC_BIAS_STANDBY:778 regmap_write(rt715->regmap,779 RT715_SET_AUDIO_POWER_STATE,780 AC_PWRST_D3);781 break;782 783 default:784 break;785 }786 dapm->bias_level = level;787 return 0;788}789 790static int rt715_probe(struct snd_soc_component *component)791{792 struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);793 int ret;794 795 if (!rt715->first_hw_init)796 return 0;797 798 ret = pm_runtime_resume(component->dev);799 if (ret < 0 && ret != -EACCES)800 return ret;801 802 return 0;803}804 805static const struct snd_soc_component_driver soc_codec_dev_rt715 = {806 .probe = rt715_probe,807 .set_bias_level = rt715_set_bias_level,808 .controls = rt715_snd_controls,809 .num_controls = ARRAY_SIZE(rt715_snd_controls),810 .dapm_widgets = rt715_dapm_widgets,811 .num_dapm_widgets = ARRAY_SIZE(rt715_dapm_widgets),812 .dapm_routes = rt715_audio_map,813 .num_dapm_routes = ARRAY_SIZE(rt715_audio_map),814 .endianness = 1,815};816 817static int rt715_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream,818 int direction)819{820 821 snd_soc_dai_dma_data_set(dai, direction, sdw_stream);822 823 return 0;824}825 826static void rt715_shutdown(struct snd_pcm_substream *substream,827 struct snd_soc_dai *dai)828 829{830 snd_soc_dai_set_dma_data(dai, substream, NULL);831}832 833static int rt715_pcm_hw_params(struct snd_pcm_substream *substream,834 struct snd_pcm_hw_params *params,835 struct snd_soc_dai *dai)836{837 struct snd_soc_component *component = dai->component;838 struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);839 struct sdw_stream_config stream_config = {0};840 struct sdw_port_config port_config = {0};841 struct sdw_stream_runtime *sdw_stream;842 int retval;843 unsigned int val = 0;844 845 sdw_stream = snd_soc_dai_get_dma_data(dai, substream);846 847 if (!sdw_stream)848 return -EINVAL;849 850 if (!rt715->slave)851 return -EINVAL;852 853 snd_sdw_params_to_config(substream, params, &stream_config, &port_config);854 855 switch (dai->id) {856 case RT715_AIF1:857 port_config.num = 6;858 rt715_index_write(rt715->regmap, RT715_SDW_INPUT_SEL, 0xa500);859 break;860 case RT715_AIF2:861 port_config.num = 4;862 rt715_index_write(rt715->regmap, RT715_SDW_INPUT_SEL, 0xa000);863 break;864 default:865 dev_err(component->dev, "%s: Invalid DAI id %d\n", __func__, dai->id);866 return -EINVAL;867 }868 869 retval = sdw_stream_add_slave(rt715->slave, &stream_config,870 &port_config, 1, sdw_stream);871 if (retval) {872 dev_err(dai->dev, "%s: Unable to configure port\n", __func__);873 return retval;874 }875 876 switch (params_rate(params)) {877 /* bit 14 0:48K 1:44.1K */878 /* bit 15 Stream Type 0:PCM 1:Non-PCM, should always be PCM */879 case 44100:880 val |= 0x40 << 8;881 break;882 case 48000:883 val |= 0x0 << 8;884 break;885 default:886 dev_err(component->dev, "%s: Unsupported sample rate %d\n",887 __func__, params_rate(params));888 return -EINVAL;889 }890 891 if (params_channels(params) <= 16) {892 /* bit 3:0 Number of Channel */893 val |= (params_channels(params) - 1);894 } else {895 dev_err(component->dev, "%s: Unsupported channels %d\n",896 __func__, params_channels(params));897 return -EINVAL;898 }899 900 switch (params_width(params)) {901 /* bit 6:4 Bits per Sample */902 case 8:903 break;904 case 16:905 val |= (0x1 << 4);906 break;907 case 20:908 val |= (0x2 << 4);909 break;910 case 24:911 val |= (0x3 << 4);912 break;913 case 32:914 val |= (0x4 << 4);915 break;916 default:917 return -EINVAL;918 }919 920 regmap_write(rt715->regmap, RT715_MIC_ADC_FORMAT_H, val);921 regmap_write(rt715->regmap, RT715_MIC_LINE_FORMAT_H, val);922 regmap_write(rt715->regmap, RT715_MIX_ADC_FORMAT_H, val);923 regmap_write(rt715->regmap, RT715_MIX_ADC2_FORMAT_H, val);924 925 return retval;926}927 928static int rt715_pcm_hw_free(struct snd_pcm_substream *substream,929 struct snd_soc_dai *dai)930{931 struct snd_soc_component *component = dai->component;932 struct rt715_priv *rt715 = snd_soc_component_get_drvdata(component);933 struct sdw_stream_runtime *sdw_stream =934 snd_soc_dai_get_dma_data(dai, substream);935 936 if (!rt715->slave)937 return -EINVAL;938 939 sdw_stream_remove_slave(rt715->slave, sdw_stream);940 return 0;941}942 943#define RT715_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)944#define RT715_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \945 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8)946 947static const struct snd_soc_dai_ops rt715_ops = {948 .hw_params = rt715_pcm_hw_params,949 .hw_free = rt715_pcm_hw_free,950 .set_stream = rt715_set_sdw_stream,951 .shutdown = rt715_shutdown,952};953 954static struct snd_soc_dai_driver rt715_dai[] = {955 {956 .name = "rt715-aif1",957 .id = RT715_AIF1,958 .capture = {959 .stream_name = "DP6 Capture",960 .channels_min = 1,961 .channels_max = 2,962 .rates = RT715_STEREO_RATES,963 .formats = RT715_FORMATS,964 },965 .ops = &rt715_ops,966 },967 {968 .name = "rt715-aif2",969 .id = RT715_AIF2,970 .capture = {971 .stream_name = "DP4 Capture",972 .channels_min = 1,973 .channels_max = 2,974 .rates = RT715_STEREO_RATES,975 .formats = RT715_FORMATS,976 },977 .ops = &rt715_ops,978 },979};980 981/* Bus clock frequency */982#define RT715_CLK_FREQ_9600000HZ 9600000983#define RT715_CLK_FREQ_12000000HZ 12000000984#define RT715_CLK_FREQ_6000000HZ 6000000985#define RT715_CLK_FREQ_4800000HZ 4800000986#define RT715_CLK_FREQ_2400000HZ 2400000987#define RT715_CLK_FREQ_12288000HZ 12288000988 989int rt715_clock_config(struct device *dev)990{991 struct rt715_priv *rt715 = dev_get_drvdata(dev);992 unsigned int clk_freq, value;993 994 clk_freq = (rt715->params.curr_dr_freq >> 1);995 996 switch (clk_freq) {997 case RT715_CLK_FREQ_12000000HZ:998 value = 0x0;999 break;1000 case RT715_CLK_FREQ_6000000HZ:1001 value = 0x1;1002 break;1003 case RT715_CLK_FREQ_9600000HZ:1004 value = 0x2;1005 break;1006 case RT715_CLK_FREQ_4800000HZ:1007 value = 0x3;1008 break;1009 case RT715_CLK_FREQ_2400000HZ:1010 value = 0x4;1011 break;1012 case RT715_CLK_FREQ_12288000HZ:1013 value = 0x5;1014 break;1015 default:1016 return -EINVAL;1017 }1018 1019 regmap_write(rt715->regmap, 0xe0, value);1020 regmap_write(rt715->regmap, 0xf0, value);1021 1022 return 0;1023}1024 1025int rt715_init(struct device *dev, struct regmap *sdw_regmap,1026 struct regmap *regmap, struct sdw_slave *slave)1027{1028 struct rt715_priv *rt715;1029 int ret;1030 1031 rt715 = devm_kzalloc(dev, sizeof(*rt715), GFP_KERNEL);1032 if (!rt715)1033 return -ENOMEM;1034 1035 dev_set_drvdata(dev, rt715);1036 rt715->slave = slave;1037 rt715->regmap = regmap;1038 rt715->sdw_regmap = sdw_regmap;1039 1040 regcache_cache_only(rt715->regmap, true);1041 1042 /*1043 * Mark hw_init to false1044 * HW init will be performed when device reports present1045 */1046 rt715->hw_init = false;1047 rt715->first_hw_init = false;1048 1049 ret = devm_snd_soc_register_component(dev,1050 &soc_codec_dev_rt715,1051 rt715_dai,1052 ARRAY_SIZE(rt715_dai));1053 if (ret < 0)1054 return ret;1055 1056 /* set autosuspend parameters */1057 pm_runtime_set_autosuspend_delay(dev, 3000);1058 pm_runtime_use_autosuspend(dev);1059 1060 /* make sure the device does not suspend immediately */1061 pm_runtime_mark_last_busy(dev);1062 1063 pm_runtime_enable(dev);1064 1065 /* important note: the device is NOT tagged as 'active' and will remain1066 * 'suspended' until the hardware is enumerated/initialized. This is required1067 * to make sure the ASoC framework use of pm_runtime_get_sync() does not silently1068 * fail with -EACCESS because of race conditions between card creation and enumeration1069 */1070 1071 return 0;1072}1073 1074int rt715_io_init(struct device *dev, struct sdw_slave *slave)1075{1076 struct rt715_priv *rt715 = dev_get_drvdata(dev);1077 1078 if (rt715->hw_init)1079 return 0;1080 1081 regcache_cache_only(rt715->regmap, false);1082 1083 /*1084 * PM runtime status is marked as 'active' only when a Slave reports as Attached1085 */1086 if (!rt715->first_hw_init)1087 /* update count of parent 'active' children */1088 pm_runtime_set_active(&slave->dev);1089 1090 pm_runtime_get_noresume(&slave->dev);1091 1092 rt715_reset(rt715->regmap);1093 1094 /* Mute nid=08h/09h */1095 regmap_write(rt715->regmap, RT715_SET_GAIN_LINE_ADC_H, 0xb080);1096 regmap_write(rt715->regmap, RT715_SET_GAIN_MIX_ADC_H, 0xb080);1097 /* Mute nid=07h/27h */1098 regmap_write(rt715->regmap, RT715_SET_GAIN_MIC_ADC_H, 0xb080);1099 regmap_write(rt715->regmap, RT715_SET_GAIN_MIX_ADC2_H, 0xb080);1100 1101 /* Set Pin Widget */1102 regmap_write(rt715->regmap, RT715_SET_PIN_DMIC1, 0x20);1103 regmap_write(rt715->regmap, RT715_SET_PIN_DMIC2, 0x20);1104 regmap_write(rt715->regmap, RT715_SET_PIN_DMIC3, 0x20);1105 regmap_write(rt715->regmap, RT715_SET_PIN_DMIC4, 0x20);1106 /* Set Converter Stream */1107 regmap_write(rt715->regmap, RT715_SET_STREAMID_LINE_ADC, 0x10);1108 regmap_write(rt715->regmap, RT715_SET_STREAMID_MIX_ADC, 0x10);1109 regmap_write(rt715->regmap, RT715_SET_STREAMID_MIC_ADC, 0x10);1110 regmap_write(rt715->regmap, RT715_SET_STREAMID_MIX_ADC2, 0x10);1111 /* Set Configuration Default */1112 regmap_write(rt715->regmap, RT715_SET_DMIC1_CONFIG_DEFAULT1, 0xd0);1113 regmap_write(rt715->regmap, RT715_SET_DMIC1_CONFIG_DEFAULT2, 0x11);1114 regmap_write(rt715->regmap, RT715_SET_DMIC1_CONFIG_DEFAULT3, 0xa1);1115 regmap_write(rt715->regmap, RT715_SET_DMIC1_CONFIG_DEFAULT4, 0x81);1116 regmap_write(rt715->regmap, RT715_SET_DMIC2_CONFIG_DEFAULT1, 0xd1);1117 regmap_write(rt715->regmap, RT715_SET_DMIC2_CONFIG_DEFAULT2, 0x11);1118 regmap_write(rt715->regmap, RT715_SET_DMIC2_CONFIG_DEFAULT3, 0xa1);1119 regmap_write(rt715->regmap, RT715_SET_DMIC2_CONFIG_DEFAULT4, 0x81);1120 regmap_write(rt715->regmap, RT715_SET_DMIC3_CONFIG_DEFAULT1, 0xd0);1121 regmap_write(rt715->regmap, RT715_SET_DMIC3_CONFIG_DEFAULT2, 0x11);1122 regmap_write(rt715->regmap, RT715_SET_DMIC3_CONFIG_DEFAULT3, 0xa1);1123 regmap_write(rt715->regmap, RT715_SET_DMIC3_CONFIG_DEFAULT4, 0x81);1124 regmap_write(rt715->regmap, RT715_SET_DMIC4_CONFIG_DEFAULT1, 0xd1);1125 regmap_write(rt715->regmap, RT715_SET_DMIC4_CONFIG_DEFAULT2, 0x11);1126 regmap_write(rt715->regmap, RT715_SET_DMIC4_CONFIG_DEFAULT3, 0xa1);1127 regmap_write(rt715->regmap, RT715_SET_DMIC4_CONFIG_DEFAULT4, 0x81);1128 1129 /* Finish Initial Settings, set power to D3 */1130 regmap_write(rt715->regmap, RT715_SET_AUDIO_POWER_STATE, AC_PWRST_D3);1131 1132 if (rt715->first_hw_init)1133 regcache_mark_dirty(rt715->regmap);1134 else1135 rt715->first_hw_init = true;1136 1137 /* Mark Slave initialization complete */1138 rt715->hw_init = true;1139 1140 pm_runtime_mark_last_busy(&slave->dev);1141 pm_runtime_put_autosuspend(&slave->dev);1142 1143 return 0;1144}1145 1146MODULE_DESCRIPTION("ASoC rt715 driver");1147MODULE_DESCRIPTION("ASoC rt715 driver SDW");1148MODULE_AUTHOR("Jack Yu <jack.yu@realtek.com>");1149MODULE_LICENSE("GPL v2");1150