883 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * ADAV80X Audio Codec driver supporting ADAV801, ADAV8034 *5 * Copyright 2011 Analog Devices Inc.6 * Author: Yi Li <yi.li@analog.com>7 * Author: Lars-Peter Clausen <lars@metafoo.de>8 */9 10#include <linux/module.h>11#include <linux/kernel.h>12#include <linux/regmap.h>13#include <linux/slab.h>14 15#include <sound/pcm.h>16#include <sound/pcm_params.h>17#include <sound/soc.h>18#include <sound/tlv.h>19 20#include "adav80x.h"21 22#define ADAV80X_PLAYBACK_CTRL 0x0423#define ADAV80X_AUX_IN_CTRL 0x0524#define ADAV80X_REC_CTRL 0x0625#define ADAV80X_AUX_OUT_CTRL 0x0726#define ADAV80X_DPATH_CTRL1 0x6227#define ADAV80X_DPATH_CTRL2 0x6328#define ADAV80X_DAC_CTRL1 0x6429#define ADAV80X_DAC_CTRL2 0x6530#define ADAV80X_DAC_CTRL3 0x6631#define ADAV80X_DAC_L_VOL 0x6832#define ADAV80X_DAC_R_VOL 0x6933#define ADAV80X_PGA_L_VOL 0x6c34#define ADAV80X_PGA_R_VOL 0x6d35#define ADAV80X_ADC_CTRL1 0x6e36#define ADAV80X_ADC_CTRL2 0x6f37#define ADAV80X_ADC_L_VOL 0x7038#define ADAV80X_ADC_R_VOL 0x7139#define ADAV80X_PLL_CTRL1 0x7440#define ADAV80X_PLL_CTRL2 0x7541#define ADAV80X_ICLK_CTRL1 0x7642#define ADAV80X_ICLK_CTRL2 0x7743#define ADAV80X_PLL_CLK_SRC 0x7844#define ADAV80X_PLL_OUTE 0x7a45 46#define ADAV80X_PLL_CLK_SRC_PLL_XIN(pll) 0x0047#define ADAV80X_PLL_CLK_SRC_PLL_MCLKI(pll) (0x40 << (pll))48#define ADAV80X_PLL_CLK_SRC_PLL_MASK(pll) (0x40 << (pll))49 50#define ADAV80X_ICLK_CTRL1_DAC_SRC(src) ((src) << 5)51#define ADAV80X_ICLK_CTRL1_ADC_SRC(src) ((src) << 2)52#define ADAV80X_ICLK_CTRL1_ICLK2_SRC(src) (src)53#define ADAV80X_ICLK_CTRL2_ICLK1_SRC(src) ((src) << 3)54 55#define ADAV80X_PLL_CTRL1_PLLDIV 0x1056#define ADAV80X_PLL_CTRL1_PLLPD(pll) (0x04 << (pll))57#define ADAV80X_PLL_CTRL1_XTLPD 0x0258 59#define ADAV80X_PLL_CTRL2_FIELD(pll, x) ((x) << ((pll) * 4))60 61#define ADAV80X_PLL_CTRL2_FS_48(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x00)62#define ADAV80X_PLL_CTRL2_FS_32(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x08)63#define ADAV80X_PLL_CTRL2_FS_44(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x0c)64 65#define ADAV80X_PLL_CTRL2_SEL(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x02)66#define ADAV80X_PLL_CTRL2_DOUB(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x01)67#define ADAV80X_PLL_CTRL2_PLL_MASK(pll) ADAV80X_PLL_CTRL2_FIELD((pll), 0x0f)68 69#define ADAV80X_ADC_CTRL1_MODULATOR_MASK 0x8070#define ADAV80X_ADC_CTRL1_MODULATOR_128FS 0x0071#define ADAV80X_ADC_CTRL1_MODULATOR_64FS 0x8072 73#define ADAV80X_DAC_CTRL1_PD 0x8074 75#define ADAV80X_DAC_CTRL2_DIV1 0x0076#define ADAV80X_DAC_CTRL2_DIV1_5 0x1077#define ADAV80X_DAC_CTRL2_DIV2 0x2078#define ADAV80X_DAC_CTRL2_DIV3 0x3079#define ADAV80X_DAC_CTRL2_DIV_MASK 0x3080 81#define ADAV80X_DAC_CTRL2_INTERPOL_256FS 0x0082#define ADAV80X_DAC_CTRL2_INTERPOL_128FS 0x4083#define ADAV80X_DAC_CTRL2_INTERPOL_64FS 0x8084#define ADAV80X_DAC_CTRL2_INTERPOL_MASK 0xc085 86#define ADAV80X_DAC_CTRL2_DEEMPH_NONE 0x0087#define ADAV80X_DAC_CTRL2_DEEMPH_44 0x0188#define ADAV80X_DAC_CTRL2_DEEMPH_32 0x0289#define ADAV80X_DAC_CTRL2_DEEMPH_48 0x0390#define ADAV80X_DAC_CTRL2_DEEMPH_MASK 0x0191 92#define ADAV80X_CAPTURE_MODE_MASTER 0x2093#define ADAV80X_CAPTURE_WORD_LEN24 0x0094#define ADAV80X_CAPTURE_WORD_LEN20 0x0495#define ADAV80X_CAPTRUE_WORD_LEN18 0x0896#define ADAV80X_CAPTURE_WORD_LEN16 0x0c97#define ADAV80X_CAPTURE_WORD_LEN_MASK 0x0c98 99#define ADAV80X_CAPTURE_MODE_LEFT_J 0x00100#define ADAV80X_CAPTURE_MODE_I2S 0x01101#define ADAV80X_CAPTURE_MODE_RIGHT_J 0x03102#define ADAV80X_CAPTURE_MODE_MASK 0x03103 104#define ADAV80X_PLAYBACK_MODE_MASTER 0x10105#define ADAV80X_PLAYBACK_MODE_LEFT_J 0x00106#define ADAV80X_PLAYBACK_MODE_I2S 0x01107#define ADAV80X_PLAYBACK_MODE_RIGHT_J_24 0x04108#define ADAV80X_PLAYBACK_MODE_RIGHT_J_20 0x05109#define ADAV80X_PLAYBACK_MODE_RIGHT_J_18 0x06110#define ADAV80X_PLAYBACK_MODE_RIGHT_J_16 0x07111#define ADAV80X_PLAYBACK_MODE_MASK 0x07112 113#define ADAV80X_PLL_OUTE_SYSCLKPD(x) BIT(2 - (x))114 115static const struct reg_default adav80x_reg_defaults[] = {116 { ADAV80X_PLAYBACK_CTRL, 0x01 },117 { ADAV80X_AUX_IN_CTRL, 0x01 },118 { ADAV80X_REC_CTRL, 0x02 },119 { ADAV80X_AUX_OUT_CTRL, 0x01 },120 { ADAV80X_DPATH_CTRL1, 0xc0 },121 { ADAV80X_DPATH_CTRL2, 0x11 },122 { ADAV80X_DAC_CTRL1, 0x00 },123 { ADAV80X_DAC_CTRL2, 0x00 },124 { ADAV80X_DAC_CTRL3, 0x00 },125 { ADAV80X_DAC_L_VOL, 0xff },126 { ADAV80X_DAC_R_VOL, 0xff },127 { ADAV80X_PGA_L_VOL, 0x00 },128 { ADAV80X_PGA_R_VOL, 0x00 },129 { ADAV80X_ADC_CTRL1, 0x00 },130 { ADAV80X_ADC_CTRL2, 0x00 },131 { ADAV80X_ADC_L_VOL, 0xff },132 { ADAV80X_ADC_R_VOL, 0xff },133 { ADAV80X_PLL_CTRL1, 0x00 },134 { ADAV80X_PLL_CTRL2, 0x00 },135 { ADAV80X_ICLK_CTRL1, 0x00 },136 { ADAV80X_ICLK_CTRL2, 0x00 },137 { ADAV80X_PLL_CLK_SRC, 0x00 },138 { ADAV80X_PLL_OUTE, 0x00 },139};140 141struct adav80x {142 struct regmap *regmap;143 144 enum adav80x_clk_src clk_src;145 unsigned int sysclk;146 enum adav80x_pll_src pll_src;147 148 unsigned int dai_fmt[2];149 unsigned int rate;150 bool deemph;151 bool sysclk_pd[3];152};153 154static const char *adav80x_mux_text[] = {155 "ADC",156 "Playback",157 "Aux Playback",158};159 160static const unsigned int adav80x_mux_values[] = {161 0, 2, 3,162};163 164#define ADAV80X_MUX_ENUM_DECL(name, reg, shift) \165 SOC_VALUE_ENUM_DOUBLE_DECL(name, reg, shift, 7, \166 ARRAY_SIZE(adav80x_mux_text), adav80x_mux_text, \167 adav80x_mux_values)168 169static ADAV80X_MUX_ENUM_DECL(adav80x_aux_capture_enum, ADAV80X_DPATH_CTRL1, 0);170static ADAV80X_MUX_ENUM_DECL(adav80x_capture_enum, ADAV80X_DPATH_CTRL1, 3);171static ADAV80X_MUX_ENUM_DECL(adav80x_dac_enum, ADAV80X_DPATH_CTRL2, 3);172 173static const struct snd_kcontrol_new adav80x_aux_capture_mux_ctrl =174 SOC_DAPM_ENUM("Route", adav80x_aux_capture_enum);175static const struct snd_kcontrol_new adav80x_capture_mux_ctrl =176 SOC_DAPM_ENUM("Route", adav80x_capture_enum);177static const struct snd_kcontrol_new adav80x_dac_mux_ctrl =178 SOC_DAPM_ENUM("Route", adav80x_dac_enum);179 180#define ADAV80X_MUX(name, ctrl) \181 SND_SOC_DAPM_MUX(name, SND_SOC_NOPM, 0, 0, ctrl)182 183static const struct snd_soc_dapm_widget adav80x_dapm_widgets[] = {184 SND_SOC_DAPM_DAC("DAC", NULL, ADAV80X_DAC_CTRL1, 7, 1),185 SND_SOC_DAPM_ADC("ADC", NULL, ADAV80X_ADC_CTRL1, 5, 1),186 187 SND_SOC_DAPM_PGA("Right PGA", ADAV80X_ADC_CTRL1, 0, 1, NULL, 0),188 SND_SOC_DAPM_PGA("Left PGA", ADAV80X_ADC_CTRL1, 1, 1, NULL, 0),189 190 SND_SOC_DAPM_AIF_OUT("AIFOUT", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0),191 SND_SOC_DAPM_AIF_IN("AIFIN", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),192 193 SND_SOC_DAPM_AIF_OUT("AIFAUXOUT", "Aux Capture", 0, SND_SOC_NOPM, 0, 0),194 SND_SOC_DAPM_AIF_IN("AIFAUXIN", "Aux Playback", 0, SND_SOC_NOPM, 0, 0),195 196 ADAV80X_MUX("Aux Capture Select", &adav80x_aux_capture_mux_ctrl),197 ADAV80X_MUX("Capture Select", &adav80x_capture_mux_ctrl),198 ADAV80X_MUX("DAC Select", &adav80x_dac_mux_ctrl),199 200 SND_SOC_DAPM_INPUT("VINR"),201 SND_SOC_DAPM_INPUT("VINL"),202 SND_SOC_DAPM_OUTPUT("VOUTR"),203 SND_SOC_DAPM_OUTPUT("VOUTL"),204 205 SND_SOC_DAPM_SUPPLY("SYSCLK", SND_SOC_NOPM, 0, 0, NULL, 0),206 SND_SOC_DAPM_SUPPLY("PLL1", ADAV80X_PLL_CTRL1, 2, 1, NULL, 0),207 SND_SOC_DAPM_SUPPLY("PLL2", ADAV80X_PLL_CTRL1, 3, 1, NULL, 0),208 SND_SOC_DAPM_SUPPLY("OSC", ADAV80X_PLL_CTRL1, 1, 1, NULL, 0),209};210 211static int adav80x_dapm_sysclk_check(struct snd_soc_dapm_widget *source,212 struct snd_soc_dapm_widget *sink)213{214 struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);215 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);216 const char *clk;217 218 switch (adav80x->clk_src) {219 case ADAV80X_CLK_PLL1:220 clk = "PLL1";221 break;222 case ADAV80X_CLK_PLL2:223 clk = "PLL2";224 break;225 case ADAV80X_CLK_XTAL:226 clk = "OSC";227 break;228 default:229 return 0;230 }231 232 return snd_soc_dapm_widget_name_cmp(source, clk) == 0;233}234 235static int adav80x_dapm_pll_check(struct snd_soc_dapm_widget *source,236 struct snd_soc_dapm_widget *sink)237{238 struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm);239 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);240 241 return adav80x->pll_src == ADAV80X_PLL_SRC_XTAL;242}243 244 245static const struct snd_soc_dapm_route adav80x_dapm_routes[] = {246 { "DAC Select", "ADC", "ADC" },247 { "DAC Select", "Playback", "AIFIN" },248 { "DAC Select", "Aux Playback", "AIFAUXIN" },249 { "DAC", NULL, "DAC Select" },250 251 { "Capture Select", "ADC", "ADC" },252 { "Capture Select", "Playback", "AIFIN" },253 { "Capture Select", "Aux Playback", "AIFAUXIN" },254 { "AIFOUT", NULL, "Capture Select" },255 256 { "Aux Capture Select", "ADC", "ADC" },257 { "Aux Capture Select", "Playback", "AIFIN" },258 { "Aux Capture Select", "Aux Playback", "AIFAUXIN" },259 { "AIFAUXOUT", NULL, "Aux Capture Select" },260 261 { "VOUTR", NULL, "DAC" },262 { "VOUTL", NULL, "DAC" },263 264 { "Left PGA", NULL, "VINL" },265 { "Right PGA", NULL, "VINR" },266 { "ADC", NULL, "Left PGA" },267 { "ADC", NULL, "Right PGA" },268 269 { "SYSCLK", NULL, "PLL1", adav80x_dapm_sysclk_check },270 { "SYSCLK", NULL, "PLL2", adav80x_dapm_sysclk_check },271 { "SYSCLK", NULL, "OSC", adav80x_dapm_sysclk_check },272 { "PLL1", NULL, "OSC", adav80x_dapm_pll_check },273 { "PLL2", NULL, "OSC", adav80x_dapm_pll_check },274 275 { "ADC", NULL, "SYSCLK" },276 { "DAC", NULL, "SYSCLK" },277 { "AIFOUT", NULL, "SYSCLK" },278 { "AIFAUXOUT", NULL, "SYSCLK" },279 { "AIFIN", NULL, "SYSCLK" },280 { "AIFAUXIN", NULL, "SYSCLK" },281};282 283static int adav80x_set_deemph(struct snd_soc_component *component)284{285 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);286 unsigned int val;287 288 if (adav80x->deemph) {289 switch (adav80x->rate) {290 case 32000:291 val = ADAV80X_DAC_CTRL2_DEEMPH_32;292 break;293 case 44100:294 val = ADAV80X_DAC_CTRL2_DEEMPH_44;295 break;296 case 48000:297 case 64000:298 case 88200:299 case 96000:300 val = ADAV80X_DAC_CTRL2_DEEMPH_48;301 break;302 default:303 val = ADAV80X_DAC_CTRL2_DEEMPH_NONE;304 break;305 }306 } else {307 val = ADAV80X_DAC_CTRL2_DEEMPH_NONE;308 }309 310 return regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL2,311 ADAV80X_DAC_CTRL2_DEEMPH_MASK, val);312}313 314static int adav80x_put_deemph(struct snd_kcontrol *kcontrol,315 struct snd_ctl_elem_value *ucontrol)316{317 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);318 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);319 unsigned int deemph = ucontrol->value.integer.value[0];320 321 if (deemph > 1)322 return -EINVAL;323 324 adav80x->deemph = deemph;325 326 return adav80x_set_deemph(component);327}328 329static int adav80x_get_deemph(struct snd_kcontrol *kcontrol,330 struct snd_ctl_elem_value *ucontrol)331{332 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);333 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);334 335 ucontrol->value.integer.value[0] = adav80x->deemph;336 return 0;337};338 339static const DECLARE_TLV_DB_SCALE(adav80x_inpga_tlv, 0, 50, 0);340static const DECLARE_TLV_DB_MINMAX(adav80x_digital_tlv, -9563, 0);341 342static const struct snd_kcontrol_new adav80x_controls[] = {343 SOC_DOUBLE_R_TLV("Master Playback Volume", ADAV80X_DAC_L_VOL,344 ADAV80X_DAC_R_VOL, 0, 0xff, 0, adav80x_digital_tlv),345 SOC_DOUBLE_R_TLV("Master Capture Volume", ADAV80X_ADC_L_VOL,346 ADAV80X_ADC_R_VOL, 0, 0xff, 0, adav80x_digital_tlv),347 348 SOC_DOUBLE_R_TLV("PGA Capture Volume", ADAV80X_PGA_L_VOL,349 ADAV80X_PGA_R_VOL, 0, 0x30, 0, adav80x_inpga_tlv),350 351 SOC_DOUBLE("Master Playback Switch", ADAV80X_DAC_CTRL1, 0, 1, 1, 0),352 SOC_DOUBLE("Master Capture Switch", ADAV80X_ADC_CTRL1, 2, 3, 1, 1),353 354 SOC_SINGLE("ADC High Pass Filter Switch", ADAV80X_ADC_CTRL1, 6, 1, 0),355 356 SOC_SINGLE_BOOL_EXT("Playback De-emphasis Switch", 0,357 adav80x_get_deemph, adav80x_put_deemph),358};359 360static unsigned int adav80x_port_ctrl_regs[2][2] = {361 { ADAV80X_REC_CTRL, ADAV80X_PLAYBACK_CTRL, },362 { ADAV80X_AUX_OUT_CTRL, ADAV80X_AUX_IN_CTRL },363};364 365static int adav80x_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)366{367 struct snd_soc_component *component = dai->component;368 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);369 unsigned int capture = 0x00;370 unsigned int playback = 0x00;371 372 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {373 case SND_SOC_DAIFMT_CBP_CFP:374 capture |= ADAV80X_CAPTURE_MODE_MASTER;375 playback |= ADAV80X_PLAYBACK_MODE_MASTER;376 break;377 case SND_SOC_DAIFMT_CBC_CFC:378 break;379 default:380 return -EINVAL;381 }382 383 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {384 case SND_SOC_DAIFMT_I2S:385 capture |= ADAV80X_CAPTURE_MODE_I2S;386 playback |= ADAV80X_PLAYBACK_MODE_I2S;387 break;388 case SND_SOC_DAIFMT_LEFT_J:389 capture |= ADAV80X_CAPTURE_MODE_LEFT_J;390 playback |= ADAV80X_PLAYBACK_MODE_LEFT_J;391 break;392 case SND_SOC_DAIFMT_RIGHT_J:393 capture |= ADAV80X_CAPTURE_MODE_RIGHT_J;394 playback |= ADAV80X_PLAYBACK_MODE_RIGHT_J_24;395 break;396 default:397 return -EINVAL;398 }399 400 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {401 case SND_SOC_DAIFMT_NB_NF:402 break;403 default:404 return -EINVAL;405 }406 407 regmap_update_bits(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][0],408 ADAV80X_CAPTURE_MODE_MASK | ADAV80X_CAPTURE_MODE_MASTER,409 capture);410 regmap_write(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][1],411 playback);412 413 adav80x->dai_fmt[dai->id] = fmt & SND_SOC_DAIFMT_FORMAT_MASK;414 415 return 0;416}417 418static int adav80x_set_adc_clock(struct snd_soc_component *component,419 unsigned int sample_rate)420{421 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);422 unsigned int val;423 424 if (sample_rate <= 48000)425 val = ADAV80X_ADC_CTRL1_MODULATOR_128FS;426 else427 val = ADAV80X_ADC_CTRL1_MODULATOR_64FS;428 429 regmap_update_bits(adav80x->regmap, ADAV80X_ADC_CTRL1,430 ADAV80X_ADC_CTRL1_MODULATOR_MASK, val);431 432 return 0;433}434 435static int adav80x_set_dac_clock(struct snd_soc_component *component,436 unsigned int sample_rate)437{438 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);439 unsigned int val;440 441 if (sample_rate <= 48000)442 val = ADAV80X_DAC_CTRL2_DIV1 | ADAV80X_DAC_CTRL2_INTERPOL_256FS;443 else444 val = ADAV80X_DAC_CTRL2_DIV2 | ADAV80X_DAC_CTRL2_INTERPOL_128FS;445 446 regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL2,447 ADAV80X_DAC_CTRL2_DIV_MASK | ADAV80X_DAC_CTRL2_INTERPOL_MASK,448 val);449 450 return 0;451}452 453static int adav80x_set_capture_pcm_format(struct snd_soc_component *component,454 struct snd_soc_dai *dai, struct snd_pcm_hw_params *params)455{456 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);457 unsigned int val;458 459 switch (params_width(params)) {460 case 16:461 val = ADAV80X_CAPTURE_WORD_LEN16;462 break;463 case 18:464 val = ADAV80X_CAPTRUE_WORD_LEN18;465 break;466 case 20:467 val = ADAV80X_CAPTURE_WORD_LEN20;468 break;469 case 24:470 val = ADAV80X_CAPTURE_WORD_LEN24;471 break;472 default:473 return -EINVAL;474 }475 476 regmap_update_bits(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][0],477 ADAV80X_CAPTURE_WORD_LEN_MASK, val);478 479 return 0;480}481 482static int adav80x_set_playback_pcm_format(struct snd_soc_component *component,483 struct snd_soc_dai *dai, struct snd_pcm_hw_params *params)484{485 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);486 unsigned int val;487 488 if (adav80x->dai_fmt[dai->id] != SND_SOC_DAIFMT_RIGHT_J)489 return 0;490 491 switch (params_width(params)) {492 case 16:493 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_16;494 break;495 case 18:496 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_18;497 break;498 case 20:499 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_20;500 break;501 case 24:502 val = ADAV80X_PLAYBACK_MODE_RIGHT_J_24;503 break;504 default:505 return -EINVAL;506 }507 508 regmap_update_bits(adav80x->regmap, adav80x_port_ctrl_regs[dai->id][1],509 ADAV80X_PLAYBACK_MODE_MASK, val);510 511 return 0;512}513 514static int adav80x_hw_params(struct snd_pcm_substream *substream,515 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)516{517 struct snd_soc_component *component = dai->component;518 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);519 unsigned int rate = params_rate(params);520 521 if (rate * 256 != adav80x->sysclk)522 return -EINVAL;523 524 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {525 adav80x_set_playback_pcm_format(component, dai, params);526 adav80x_set_dac_clock(component, rate);527 } else {528 adav80x_set_capture_pcm_format(component, dai, params);529 adav80x_set_adc_clock(component, rate);530 }531 adav80x->rate = rate;532 adav80x_set_deemph(component);533 534 return 0;535}536 537static int adav80x_set_sysclk(struct snd_soc_component *component,538 int clk_id, int source,539 unsigned int freq, int dir)540{541 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);542 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);543 544 if (dir == SND_SOC_CLOCK_IN) {545 switch (clk_id) {546 case ADAV80X_CLK_XIN:547 case ADAV80X_CLK_XTAL:548 case ADAV80X_CLK_MCLKI:549 case ADAV80X_CLK_PLL1:550 case ADAV80X_CLK_PLL2:551 break;552 default:553 return -EINVAL;554 }555 556 adav80x->sysclk = freq;557 558 if (adav80x->clk_src != clk_id) {559 unsigned int iclk_ctrl1, iclk_ctrl2;560 561 adav80x->clk_src = clk_id;562 if (clk_id == ADAV80X_CLK_XTAL)563 clk_id = ADAV80X_CLK_XIN;564 565 iclk_ctrl1 = ADAV80X_ICLK_CTRL1_DAC_SRC(clk_id) |566 ADAV80X_ICLK_CTRL1_ADC_SRC(clk_id) |567 ADAV80X_ICLK_CTRL1_ICLK2_SRC(clk_id);568 iclk_ctrl2 = ADAV80X_ICLK_CTRL2_ICLK1_SRC(clk_id);569 570 regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL1,571 iclk_ctrl1);572 regmap_write(adav80x->regmap, ADAV80X_ICLK_CTRL2,573 iclk_ctrl2);574 575 snd_soc_dapm_sync(dapm);576 }577 } else {578 unsigned int mask;579 580 switch (clk_id) {581 case ADAV80X_CLK_SYSCLK1:582 case ADAV80X_CLK_SYSCLK2:583 case ADAV80X_CLK_SYSCLK3:584 break;585 default:586 return -EINVAL;587 }588 589 clk_id -= ADAV80X_CLK_SYSCLK1;590 mask = ADAV80X_PLL_OUTE_SYSCLKPD(clk_id);591 592 if (freq == 0) {593 regmap_update_bits(adav80x->regmap, ADAV80X_PLL_OUTE,594 mask, mask);595 adav80x->sysclk_pd[clk_id] = true;596 } else {597 regmap_update_bits(adav80x->regmap, ADAV80X_PLL_OUTE,598 mask, 0);599 adav80x->sysclk_pd[clk_id] = false;600 }601 602 snd_soc_dapm_mutex_lock(dapm);603 604 if (adav80x->sysclk_pd[0])605 snd_soc_dapm_disable_pin_unlocked(dapm, "PLL1");606 else607 snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL1");608 609 if (adav80x->sysclk_pd[1] || adav80x->sysclk_pd[2])610 snd_soc_dapm_disable_pin_unlocked(dapm, "PLL2");611 else612 snd_soc_dapm_force_enable_pin_unlocked(dapm, "PLL2");613 614 snd_soc_dapm_sync_unlocked(dapm);615 616 snd_soc_dapm_mutex_unlock(dapm);617 }618 619 return 0;620}621 622static int adav80x_set_pll(struct snd_soc_component *component, int pll_id,623 int source, unsigned int freq_in, unsigned int freq_out)624{625 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);626 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);627 unsigned int pll_ctrl1 = 0;628 unsigned int pll_ctrl2 = 0;629 unsigned int pll_src;630 631 switch (source) {632 case ADAV80X_PLL_SRC_XTAL:633 case ADAV80X_PLL_SRC_XIN:634 case ADAV80X_PLL_SRC_MCLKI:635 break;636 default:637 return -EINVAL;638 }639 640 if (!freq_out)641 return 0;642 643 switch (freq_in) {644 case 27000000:645 break;646 case 54000000:647 if (source == ADAV80X_PLL_SRC_XIN) {648 pll_ctrl1 |= ADAV80X_PLL_CTRL1_PLLDIV;649 break;650 }651 fallthrough;652 default:653 return -EINVAL;654 }655 656 if (freq_out > 12288000) {657 pll_ctrl2 |= ADAV80X_PLL_CTRL2_DOUB(pll_id);658 freq_out /= 2;659 }660 661 /* freq_out = sample_rate * 256 */662 switch (freq_out) {663 case 8192000:664 pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_32(pll_id);665 break;666 case 11289600:667 pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_44(pll_id);668 break;669 case 12288000:670 pll_ctrl2 |= ADAV80X_PLL_CTRL2_FS_48(pll_id);671 break;672 default:673 return -EINVAL;674 }675 676 regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CTRL1,677 ADAV80X_PLL_CTRL1_PLLDIV, pll_ctrl1);678 regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CTRL2,679 ADAV80X_PLL_CTRL2_PLL_MASK(pll_id), pll_ctrl2);680 681 if (source != adav80x->pll_src) {682 if (source == ADAV80X_PLL_SRC_MCLKI)683 pll_src = ADAV80X_PLL_CLK_SRC_PLL_MCLKI(pll_id);684 else685 pll_src = ADAV80X_PLL_CLK_SRC_PLL_XIN(pll_id);686 687 regmap_update_bits(adav80x->regmap, ADAV80X_PLL_CLK_SRC,688 ADAV80X_PLL_CLK_SRC_PLL_MASK(pll_id), pll_src);689 690 adav80x->pll_src = source;691 692 snd_soc_dapm_sync(dapm);693 }694 695 return 0;696}697 698static int adav80x_set_bias_level(struct snd_soc_component *component,699 enum snd_soc_bias_level level)700{701 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);702 unsigned int mask = ADAV80X_DAC_CTRL1_PD;703 704 switch (level) {705 case SND_SOC_BIAS_ON:706 break;707 case SND_SOC_BIAS_PREPARE:708 break;709 case SND_SOC_BIAS_STANDBY:710 regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL1, mask,711 0x00);712 break;713 case SND_SOC_BIAS_OFF:714 regmap_update_bits(adav80x->regmap, ADAV80X_DAC_CTRL1, mask,715 mask);716 break;717 }718 719 return 0;720}721 722/* Enforce the same sample rate on all audio interfaces */723static int adav80x_dai_startup(struct snd_pcm_substream *substream,724 struct snd_soc_dai *dai)725{726 struct snd_soc_component *component = dai->component;727 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);728 729 if (!snd_soc_component_active(component) || !adav80x->rate)730 return 0;731 732 return snd_pcm_hw_constraint_single(substream->runtime,733 SNDRV_PCM_HW_PARAM_RATE, adav80x->rate);734}735 736static void adav80x_dai_shutdown(struct snd_pcm_substream *substream,737 struct snd_soc_dai *dai)738{739 struct snd_soc_component *component = dai->component;740 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);741 742 if (!snd_soc_component_active(component))743 adav80x->rate = 0;744}745 746static const struct snd_soc_dai_ops adav80x_dai_ops = {747 .set_fmt = adav80x_set_dai_fmt,748 .hw_params = adav80x_hw_params,749 .startup = adav80x_dai_startup,750 .shutdown = adav80x_dai_shutdown,751};752 753#define ADAV80X_PLAYBACK_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \754 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_64000 | SNDRV_PCM_RATE_88200 | \755 SNDRV_PCM_RATE_96000)756 757#define ADAV80X_CAPTURE_RATES (SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000)758 759#define ADAV80X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S18_3LE | \760 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE)761 762static struct snd_soc_dai_driver adav80x_dais[] = {763 {764 .name = "adav80x-hifi",765 .id = 0,766 .playback = {767 .stream_name = "HiFi Playback",768 .channels_min = 2,769 .channels_max = 2,770 .rates = ADAV80X_PLAYBACK_RATES,771 .formats = ADAV80X_FORMATS,772 },773 .capture = {774 .stream_name = "HiFi Capture",775 .channels_min = 2,776 .channels_max = 2,777 .rates = ADAV80X_CAPTURE_RATES,778 .formats = ADAV80X_FORMATS,779 },780 .ops = &adav80x_dai_ops,781 },782 {783 .name = "adav80x-aux",784 .id = 1,785 .playback = {786 .stream_name = "Aux Playback",787 .channels_min = 2,788 .channels_max = 2,789 .rates = ADAV80X_PLAYBACK_RATES,790 .formats = ADAV80X_FORMATS,791 },792 .capture = {793 .stream_name = "Aux Capture",794 .channels_min = 2,795 .channels_max = 2,796 .rates = ADAV80X_CAPTURE_RATES,797 .formats = ADAV80X_FORMATS,798 },799 .ops = &adav80x_dai_ops,800 },801};802 803static int adav80x_probe(struct snd_soc_component *component)804{805 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);806 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);807 808 /* Force PLLs on for SYSCLK output */809 snd_soc_dapm_force_enable_pin(dapm, "PLL1");810 snd_soc_dapm_force_enable_pin(dapm, "PLL2");811 812 /* Power down S/PDIF receiver, since it is currently not supported */813 regmap_write(adav80x->regmap, ADAV80X_PLL_OUTE, 0x20);814 /* Disable DAC zero flag */815 regmap_write(adav80x->regmap, ADAV80X_DAC_CTRL3, 0x6);816 817 return 0;818}819 820static int adav80x_resume(struct snd_soc_component *component)821{822 struct adav80x *adav80x = snd_soc_component_get_drvdata(component);823 824 regcache_sync(adav80x->regmap);825 826 return 0;827}828 829static const struct snd_soc_component_driver adav80x_component_driver = {830 .probe = adav80x_probe,831 .resume = adav80x_resume,832 .set_bias_level = adav80x_set_bias_level,833 .set_pll = adav80x_set_pll,834 .set_sysclk = adav80x_set_sysclk,835 .controls = adav80x_controls,836 .num_controls = ARRAY_SIZE(adav80x_controls),837 .dapm_widgets = adav80x_dapm_widgets,838 .num_dapm_widgets = ARRAY_SIZE(adav80x_dapm_widgets),839 .dapm_routes = adav80x_dapm_routes,840 .num_dapm_routes = ARRAY_SIZE(adav80x_dapm_routes),841 .suspend_bias_off = 1,842 .idle_bias_on = 1,843 .use_pmdown_time = 1,844 .endianness = 1,845};846 847int adav80x_bus_probe(struct device *dev, struct regmap *regmap)848{849 struct adav80x *adav80x;850 851 if (IS_ERR(regmap))852 return PTR_ERR(regmap);853 854 adav80x = devm_kzalloc(dev, sizeof(*adav80x), GFP_KERNEL);855 if (!adav80x)856 return -ENOMEM;857 858 dev_set_drvdata(dev, adav80x);859 adav80x->regmap = regmap;860 861 return devm_snd_soc_register_component(dev, &adav80x_component_driver,862 adav80x_dais, ARRAY_SIZE(adav80x_dais));863}864EXPORT_SYMBOL_GPL(adav80x_bus_probe);865 866const struct regmap_config adav80x_regmap_config = {867 .val_bits = 8,868 .pad_bits = 1,869 .reg_bits = 7,870 871 .max_register = ADAV80X_PLL_OUTE,872 873 .cache_type = REGCACHE_MAPLE,874 .reg_defaults = adav80x_reg_defaults,875 .num_reg_defaults = ARRAY_SIZE(adav80x_reg_defaults),876};877EXPORT_SYMBOL_GPL(adav80x_regmap_config);878 879MODULE_DESCRIPTION("ASoC ADAV80x driver");880MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");881MODULE_AUTHOR("Yi Li <yi.li@analog.com>>");882MODULE_LICENSE("GPL");883