1124 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Common code for ADAU1X61 and ADAU1X81 codecs4 *5 * Copyright 2011-2014 Analog Devices Inc.6 * Author: Lars-Peter Clausen <lars@metafoo.de>7 */8 9#include <linux/module.h>10#include <linux/init.h>11#include <linux/clk.h>12#include <linux/delay.h>13#include <linux/slab.h>14#include <sound/core.h>15#include <sound/pcm.h>16#include <sound/pcm_params.h>17#include <sound/soc.h>18#include <sound/tlv.h>19#include <linux/i2c.h>20#include <linux/spi/spi.h>21#include <linux/regmap.h>22#include <linux/unaligned.h>23 24#include "sigmadsp.h"25#include "adau17x1.h"26#include "adau-utils.h"27 28#define ADAU17X1_SAFELOAD_TARGET_ADDRESS 0x000629#define ADAU17X1_SAFELOAD_TRIGGER 0x000730#define ADAU17X1_SAFELOAD_DATA 0x000131#define ADAU17X1_SAFELOAD_DATA_SIZE 2032#define ADAU17X1_WORD_SIZE 433 34static const char * const adau17x1_capture_mixer_boost_text[] = {35 "Normal operation", "Boost Level 1", "Boost Level 2", "Boost Level 3",36};37 38static SOC_ENUM_SINGLE_DECL(adau17x1_capture_boost_enum,39 ADAU17X1_REC_POWER_MGMT, 5, adau17x1_capture_mixer_boost_text);40 41static const char * const adau17x1_mic_bias_mode_text[] = {42 "Normal operation", "High performance",43};44 45static SOC_ENUM_SINGLE_DECL(adau17x1_mic_bias_mode_enum,46 ADAU17X1_MICBIAS, 3, adau17x1_mic_bias_mode_text);47 48static const DECLARE_TLV_DB_MINMAX(adau17x1_digital_tlv, -9563, 0);49 50static const struct snd_kcontrol_new adau17x1_controls[] = {51 SOC_DOUBLE_R_TLV("Digital Capture Volume",52 ADAU17X1_LEFT_INPUT_DIGITAL_VOL,53 ADAU17X1_RIGHT_INPUT_DIGITAL_VOL,54 0, 0xff, 1, adau17x1_digital_tlv),55 SOC_DOUBLE_R_TLV("Digital Playback Volume", ADAU17X1_DAC_CONTROL1,56 ADAU17X1_DAC_CONTROL2, 0, 0xff, 1, adau17x1_digital_tlv),57 58 SOC_SINGLE("ADC High Pass Filter Switch", ADAU17X1_ADC_CONTROL,59 5, 1, 0),60 SOC_SINGLE("Playback De-emphasis Switch", ADAU17X1_DAC_CONTROL0,61 2, 1, 0),62 63 SOC_ENUM("Capture Boost", adau17x1_capture_boost_enum),64 65 SOC_ENUM("Mic Bias Mode", adau17x1_mic_bias_mode_enum),66};67 68static int adau17x1_setup_firmware(struct snd_soc_component *component,69 unsigned int rate);70 71static int adau17x1_pll_event(struct snd_soc_dapm_widget *w,72 struct snd_kcontrol *kcontrol, int event)73{74 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);75 struct adau *adau = snd_soc_component_get_drvdata(component);76 77 if (SND_SOC_DAPM_EVENT_ON(event)) {78 adau->pll_regs[5] = 1;79 } else {80 adau->pll_regs[5] = 0;81 /* Bypass the PLL when disabled, otherwise registers will become82 * inaccessible. */83 regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,84 ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL, 0);85 }86 87 /* The PLL register is 6 bytes long and can only be written at once. */88 regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL,89 adau->pll_regs, ARRAY_SIZE(adau->pll_regs));90 91 if (SND_SOC_DAPM_EVENT_ON(event)) {92 mdelay(5);93 regmap_update_bits(adau->regmap, ADAU17X1_CLOCK_CONTROL,94 ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL,95 ADAU17X1_CLOCK_CONTROL_CORECLK_SRC_PLL);96 }97 98 return 0;99}100 101static int adau17x1_adc_fixup(struct snd_soc_dapm_widget *w,102 struct snd_kcontrol *kcontrol, int event)103{104 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);105 struct adau *adau = snd_soc_component_get_drvdata(component);106 107 /*108 * If we are capturing, toggle the ADOSR bit in Converter Control 0 to109 * avoid losing SNR (workaround from ADI). This must be done after110 * the ADC(s) have been enabled. According to the data sheet, it is111 * normally illegal to set this bit when the sampling rate is 96 kHz,112 * but according to ADI it is acceptable for this workaround.113 */114 regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0,115 ADAU17X1_CONVERTER0_ADOSR, ADAU17X1_CONVERTER0_ADOSR);116 regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0,117 ADAU17X1_CONVERTER0_ADOSR, 0);118 119 return 0;120}121 122static const char * const adau17x1_mono_stereo_text[] = {123 "Stereo",124 "Mono Left Channel (L+R)",125 "Mono Right Channel (L+R)",126 "Mono (L+R)",127};128 129static SOC_ENUM_SINGLE_DECL(adau17x1_dac_mode_enum,130 ADAU17X1_DAC_CONTROL0, 6, adau17x1_mono_stereo_text);131 132static const struct snd_kcontrol_new adau17x1_dac_mode_mux =133 SOC_DAPM_ENUM("DAC Mono-Stereo-Mode", adau17x1_dac_mode_enum);134 135static const struct snd_soc_dapm_widget adau17x1_dapm_widgets[] = {136 SND_SOC_DAPM_SUPPLY_S("PLL", 3, SND_SOC_NOPM, 0, 0, adau17x1_pll_event,137 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),138 139 SND_SOC_DAPM_SUPPLY("AIFCLK", SND_SOC_NOPM, 0, 0, NULL, 0),140 141 SND_SOC_DAPM_SUPPLY("MICBIAS", ADAU17X1_MICBIAS, 0, 0, NULL, 0),142 143 SND_SOC_DAPM_SUPPLY("Left Playback Enable", ADAU17X1_PLAY_POWER_MGMT,144 0, 0, NULL, 0),145 SND_SOC_DAPM_SUPPLY("Right Playback Enable", ADAU17X1_PLAY_POWER_MGMT,146 1, 0, NULL, 0),147 148 SND_SOC_DAPM_MUX("Left DAC Mode Mux", SND_SOC_NOPM, 0, 0,149 &adau17x1_dac_mode_mux),150 SND_SOC_DAPM_MUX("Right DAC Mode Mux", SND_SOC_NOPM, 0, 0,151 &adau17x1_dac_mode_mux),152 153 SND_SOC_DAPM_ADC_E("Left Decimator", NULL, ADAU17X1_ADC_CONTROL, 0, 0,154 adau17x1_adc_fixup, SND_SOC_DAPM_POST_PMU),155 SND_SOC_DAPM_ADC("Right Decimator", NULL, ADAU17X1_ADC_CONTROL, 1, 0),156 SND_SOC_DAPM_DAC("Left DAC", NULL, ADAU17X1_DAC_CONTROL0, 0, 0),157 SND_SOC_DAPM_DAC("Right DAC", NULL, ADAU17X1_DAC_CONTROL0, 1, 0),158};159 160static const struct snd_soc_dapm_route adau17x1_dapm_routes[] = {161 { "Left Decimator", NULL, "SYSCLK" },162 { "Right Decimator", NULL, "SYSCLK" },163 { "Left DAC", NULL, "SYSCLK" },164 { "Right DAC", NULL, "SYSCLK" },165 { "Capture", NULL, "SYSCLK" },166 { "Playback", NULL, "SYSCLK" },167 168 { "Left DAC", NULL, "Left DAC Mode Mux" },169 { "Right DAC", NULL, "Right DAC Mode Mux" },170 171 { "Capture", NULL, "AIFCLK" },172 { "Playback", NULL, "AIFCLK" },173};174 175static const struct snd_soc_dapm_route adau17x1_dapm_pll_route = {176 "SYSCLK", NULL, "PLL",177};178 179/*180 * The MUX register for the Capture and Playback MUXs selects either DSP as181 * source/destination or one of the TDM slots. The TDM slot is selected via182 * snd_soc_dai_set_tdm_slot(), so we only expose whether to go to the DSP or183 * directly to the DAI interface with this control.184 */185static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,186 struct snd_ctl_elem_value *ucontrol)187{188 struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);189 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);190 struct adau *adau = snd_soc_component_get_drvdata(component);191 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;192 struct snd_soc_dapm_update update = {};193 unsigned int stream = e->shift_l;194 unsigned int val, change;195 int reg;196 197 if (ucontrol->value.enumerated.item[0] >= e->items)198 return -EINVAL;199 200 switch (ucontrol->value.enumerated.item[0]) {201 case 0:202 val = 0;203 adau->dsp_bypass[stream] = false;204 break;205 default:206 val = (adau->tdm_slot[stream] * 2) + 1;207 adau->dsp_bypass[stream] = true;208 break;209 }210 211 if (stream == SNDRV_PCM_STREAM_PLAYBACK)212 reg = ADAU17X1_SERIAL_INPUT_ROUTE;213 else214 reg = ADAU17X1_SERIAL_OUTPUT_ROUTE;215 216 change = snd_soc_component_test_bits(component, reg, 0xff, val);217 if (change) {218 update.kcontrol = kcontrol;219 update.mask = 0xff;220 update.reg = reg;221 update.val = val;222 223 snd_soc_dapm_mux_update_power(dapm, kcontrol,224 ucontrol->value.enumerated.item[0], e, &update);225 }226 227 return change;228}229 230static int adau17x1_dsp_mux_enum_get(struct snd_kcontrol *kcontrol,231 struct snd_ctl_elem_value *ucontrol)232{233 struct snd_soc_component *component = snd_soc_dapm_kcontrol_component(kcontrol);234 struct adau *adau = snd_soc_component_get_drvdata(component);235 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;236 unsigned int stream = e->shift_l;237 unsigned int reg, val;238 int ret;239 240 if (stream == SNDRV_PCM_STREAM_PLAYBACK)241 reg = ADAU17X1_SERIAL_INPUT_ROUTE;242 else243 reg = ADAU17X1_SERIAL_OUTPUT_ROUTE;244 245 ret = regmap_read(adau->regmap, reg, &val);246 if (ret)247 return ret;248 249 if (val != 0)250 val = 1;251 ucontrol->value.enumerated.item[0] = val;252 253 return 0;254}255 256#define DECLARE_ADAU17X1_DSP_MUX_CTRL(_name, _label, _stream, _text) \257 const struct snd_kcontrol_new _name = \258 SOC_DAPM_ENUM_EXT(_label, (const struct soc_enum)\259 SOC_ENUM_SINGLE(SND_SOC_NOPM, _stream, \260 ARRAY_SIZE(_text), _text), \261 adau17x1_dsp_mux_enum_get, adau17x1_dsp_mux_enum_put)262 263static const char * const adau17x1_dac_mux_text[] = {264 "DSP",265 "AIFIN",266};267 268static const char * const adau17x1_capture_mux_text[] = {269 "DSP",270 "Decimator",271};272 273static DECLARE_ADAU17X1_DSP_MUX_CTRL(adau17x1_dac_mux, "DAC Playback Mux",274 SNDRV_PCM_STREAM_PLAYBACK, adau17x1_dac_mux_text);275 276static DECLARE_ADAU17X1_DSP_MUX_CTRL(adau17x1_capture_mux, "Capture Mux",277 SNDRV_PCM_STREAM_CAPTURE, adau17x1_capture_mux_text);278 279static const struct snd_soc_dapm_widget adau17x1_dsp_dapm_widgets[] = {280 SND_SOC_DAPM_PGA("DSP", ADAU17X1_DSP_RUN, 0, 0, NULL, 0),281 SND_SOC_DAPM_SIGGEN("DSP Siggen"),282 283 SND_SOC_DAPM_MUX("DAC Playback Mux", SND_SOC_NOPM, 0, 0,284 &adau17x1_dac_mux),285 SND_SOC_DAPM_MUX("Capture Mux", SND_SOC_NOPM, 0, 0,286 &adau17x1_capture_mux),287};288 289static const struct snd_soc_dapm_route adau17x1_dsp_dapm_routes[] = {290 { "DAC Playback Mux", "DSP", "DSP" },291 { "DAC Playback Mux", "AIFIN", "Playback" },292 293 { "Left DAC Mode Mux", "Stereo", "DAC Playback Mux" },294 { "Left DAC Mode Mux", "Mono (L+R)", "DAC Playback Mux" },295 { "Left DAC Mode Mux", "Mono Left Channel (L+R)", "DAC Playback Mux" },296 { "Right DAC Mode Mux", "Stereo", "DAC Playback Mux" },297 { "Right DAC Mode Mux", "Mono (L+R)", "DAC Playback Mux" },298 { "Right DAC Mode Mux", "Mono Right Channel (L+R)", "DAC Playback Mux" },299 300 { "Capture Mux", "DSP", "DSP" },301 { "Capture Mux", "Decimator", "Left Decimator" },302 { "Capture Mux", "Decimator", "Right Decimator" },303 304 { "Capture", NULL, "Capture Mux" },305 306 { "DSP", NULL, "DSP Siggen" },307 308 { "DSP", NULL, "Left Decimator" },309 { "DSP", NULL, "Right Decimator" },310 { "DSP", NULL, "Playback" },311};312 313static const struct snd_soc_dapm_route adau17x1_no_dsp_dapm_routes[] = {314 { "Left DAC Mode Mux", "Stereo", "Playback" },315 { "Left DAC Mode Mux", "Mono (L+R)", "Playback" },316 { "Left DAC Mode Mux", "Mono Left Channel (L+R)", "Playback" },317 { "Right DAC Mode Mux", "Stereo", "Playback" },318 { "Right DAC Mode Mux", "Mono (L+R)", "Playback" },319 { "Right DAC Mode Mux", "Mono Right Channel (L+R)", "Playback" },320 { "Capture", NULL, "Left Decimator" },321 { "Capture", NULL, "Right Decimator" },322};323 324static bool adau17x1_has_dsp(struct adau *adau)325{326 switch (adau->type) {327 case ADAU1761:328 case ADAU1381:329 case ADAU1781:330 return true;331 default:332 return false;333 }334}335 336/* Chip has a DSP but we're pretending it doesn't. */337static bool adau17x1_has_disused_dsp(struct adau *adau)338{339 switch (adau->type) {340 case ADAU1761_AS_1361:341 return true;342 default:343 return false;344 }345}346 347static bool adau17x1_has_safeload(struct adau *adau)348{349 switch (adau->type) {350 case ADAU1761:351 case ADAU1781:352 return true;353 default:354 return false;355 }356}357 358static int adau17x1_set_dai_pll(struct snd_soc_dai *dai, int pll_id,359 int source, unsigned int freq_in, unsigned int freq_out)360{361 struct snd_soc_component *component = dai->component;362 struct adau *adau = snd_soc_component_get_drvdata(component);363 int ret;364 365 if (freq_in < 8000000 || freq_in > 27000000)366 return -EINVAL;367 368 ret = adau_calc_pll_cfg(freq_in, freq_out, adau->pll_regs);369 if (ret < 0)370 return ret;371 372 /* The PLL register is 6 bytes long and can only be written at once. */373 ret = regmap_raw_write(adau->regmap, ADAU17X1_PLL_CONTROL,374 adau->pll_regs, ARRAY_SIZE(adau->pll_regs));375 if (ret)376 return ret;377 378 adau->pll_freq = freq_out;379 380 return 0;381}382 383static int adau17x1_set_dai_sysclk(struct snd_soc_dai *dai,384 int clk_id, unsigned int freq, int dir)385{386 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(dai->component);387 struct adau *adau = snd_soc_component_get_drvdata(dai->component);388 bool is_pll;389 bool was_pll;390 391 switch (clk_id) {392 case ADAU17X1_CLK_SRC_MCLK:393 is_pll = false;394 break;395 case ADAU17X1_CLK_SRC_PLL_AUTO:396 if (!adau->mclk)397 return -EINVAL;398 fallthrough;399 case ADAU17X1_CLK_SRC_PLL:400 is_pll = true;401 break;402 default:403 return -EINVAL;404 }405 406 switch (adau->clk_src) {407 case ADAU17X1_CLK_SRC_MCLK:408 was_pll = false;409 break;410 case ADAU17X1_CLK_SRC_PLL:411 case ADAU17X1_CLK_SRC_PLL_AUTO:412 was_pll = true;413 break;414 default:415 return -EINVAL;416 }417 418 adau->sysclk = freq;419 420 if (is_pll != was_pll) {421 if (is_pll) {422 snd_soc_dapm_add_routes(dapm,423 &adau17x1_dapm_pll_route, 1);424 } else {425 snd_soc_dapm_del_routes(dapm,426 &adau17x1_dapm_pll_route, 1);427 }428 }429 430 adau->clk_src = clk_id;431 432 return 0;433}434 435static int adau17x1_auto_pll(struct snd_soc_dai *dai,436 struct snd_pcm_hw_params *params)437{438 struct adau *adau = snd_soc_dai_get_drvdata(dai);439 unsigned int pll_rate;440 441 switch (params_rate(params)) {442 case 48000:443 case 8000:444 case 12000:445 case 16000:446 case 24000:447 case 32000:448 case 96000:449 pll_rate = 48000 * 1024;450 break;451 case 44100:452 case 7350:453 case 11025:454 case 14700:455 case 22050:456 case 29400:457 case 88200:458 pll_rate = 44100 * 1024;459 break;460 default:461 return -EINVAL;462 }463 464 return adau17x1_set_dai_pll(dai, ADAU17X1_PLL, ADAU17X1_PLL_SRC_MCLK,465 clk_get_rate(adau->mclk), pll_rate);466}467 468static int adau17x1_hw_params(struct snd_pcm_substream *substream,469 struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)470{471 struct snd_soc_component *component = dai->component;472 struct adau *adau = snd_soc_component_get_drvdata(component);473 unsigned int val, div, dsp_div;474 unsigned int freq;475 int ret;476 477 switch (adau->clk_src) {478 case ADAU17X1_CLK_SRC_PLL_AUTO:479 ret = adau17x1_auto_pll(dai, params);480 if (ret)481 return ret;482 fallthrough;483 case ADAU17X1_CLK_SRC_PLL:484 freq = adau->pll_freq;485 break;486 default:487 freq = adau->sysclk;488 break;489 }490 491 if (freq % params_rate(params) != 0)492 return -EINVAL;493 494 switch (freq / params_rate(params)) {495 case 1024: /* fs */496 div = 0;497 dsp_div = 1;498 break;499 case 6144: /* fs / 6 */500 div = 1;501 dsp_div = 6;502 break;503 case 4096: /* fs / 4 */504 div = 2;505 dsp_div = 5;506 break;507 case 3072: /* fs / 3 */508 div = 3;509 dsp_div = 4;510 break;511 case 2048: /* fs / 2 */512 div = 4;513 dsp_div = 3;514 break;515 case 1536: /* fs / 1.5 */516 div = 5;517 dsp_div = 2;518 break;519 case 512: /* fs / 0.5 */520 div = 6;521 dsp_div = 0;522 break;523 default:524 return -EINVAL;525 }526 527 regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0,528 ADAU17X1_CONVERTER0_CONVSR_MASK, div);529 530 if (adau17x1_has_dsp(adau) || adau17x1_has_disused_dsp(adau))531 regmap_write(adau->regmap, ADAU17X1_SERIAL_SAMPLING_RATE, div);532 if (adau17x1_has_dsp(adau))533 regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dsp_div);534 535 if (adau->sigmadsp) {536 ret = adau17x1_setup_firmware(component, params_rate(params));537 if (ret < 0)538 return ret;539 }540 541 if (adau->dai_fmt != SND_SOC_DAIFMT_RIGHT_J)542 return 0;543 544 switch (params_width(params)) {545 case 16:546 val = ADAU17X1_SERIAL_PORT1_DELAY16;547 break;548 case 24:549 val = ADAU17X1_SERIAL_PORT1_DELAY8;550 break;551 case 32:552 val = ADAU17X1_SERIAL_PORT1_DELAY0;553 break;554 default:555 return -EINVAL;556 }557 558 return regmap_update_bits(adau->regmap, ADAU17X1_SERIAL_PORT1,559 ADAU17X1_SERIAL_PORT1_DELAY_MASK, val);560}561 562static int adau17x1_set_dai_fmt(struct snd_soc_dai *dai,563 unsigned int fmt)564{565 struct adau *adau = snd_soc_component_get_drvdata(dai->component);566 unsigned int ctrl0, ctrl1;567 unsigned int ctrl0_mask;568 int lrclk_pol;569 570 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {571 case SND_SOC_DAIFMT_CBP_CFP:572 ctrl0 = ADAU17X1_SERIAL_PORT0_MASTER;573 adau->master = true;574 break;575 case SND_SOC_DAIFMT_CBC_CFC:576 ctrl0 = 0;577 adau->master = false;578 break;579 default:580 return -EINVAL;581 }582 583 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {584 case SND_SOC_DAIFMT_I2S:585 lrclk_pol = 0;586 ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY1;587 break;588 case SND_SOC_DAIFMT_LEFT_J:589 case SND_SOC_DAIFMT_RIGHT_J:590 lrclk_pol = 1;591 ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY0;592 break;593 case SND_SOC_DAIFMT_DSP_A:594 lrclk_pol = 1;595 ctrl0 |= ADAU17X1_SERIAL_PORT0_PULSE_MODE;596 ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY1;597 break;598 case SND_SOC_DAIFMT_DSP_B:599 lrclk_pol = 1;600 ctrl0 |= ADAU17X1_SERIAL_PORT0_PULSE_MODE;601 ctrl1 = ADAU17X1_SERIAL_PORT1_DELAY0;602 break;603 default:604 return -EINVAL;605 }606 607 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {608 case SND_SOC_DAIFMT_NB_NF:609 break;610 case SND_SOC_DAIFMT_IB_NF:611 ctrl0 |= ADAU17X1_SERIAL_PORT0_BCLK_POL;612 break;613 case SND_SOC_DAIFMT_NB_IF:614 lrclk_pol = !lrclk_pol;615 break;616 case SND_SOC_DAIFMT_IB_IF:617 ctrl0 |= ADAU17X1_SERIAL_PORT0_BCLK_POL;618 lrclk_pol = !lrclk_pol;619 break;620 default:621 return -EINVAL;622 }623 624 if (lrclk_pol)625 ctrl0 |= ADAU17X1_SERIAL_PORT0_LRCLK_POL;626 627 /* Set the mask to update all relevant bits in ADAU17X1_SERIAL_PORT0 */628 ctrl0_mask = ADAU17X1_SERIAL_PORT0_MASTER |629 ADAU17X1_SERIAL_PORT0_LRCLK_POL |630 ADAU17X1_SERIAL_PORT0_BCLK_POL |631 ADAU17X1_SERIAL_PORT0_PULSE_MODE;632 633 regmap_update_bits(adau->regmap, ADAU17X1_SERIAL_PORT0, ctrl0_mask,634 ctrl0);635 regmap_update_bits(adau->regmap, ADAU17X1_SERIAL_PORT1,636 ADAU17X1_SERIAL_PORT1_DELAY_MASK, ctrl1);637 638 adau->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;639 640 return 0;641}642 643static int adau17x1_set_dai_tdm_slot(struct snd_soc_dai *dai,644 unsigned int tx_mask, unsigned int rx_mask, int slots, int slot_width)645{646 struct adau *adau = snd_soc_component_get_drvdata(dai->component);647 unsigned int ser_ctrl0, ser_ctrl1;648 unsigned int conv_ctrl0, conv_ctrl1;649 650 /* I2S mode */651 if (slots == 0) {652 slots = 2;653 rx_mask = 3;654 tx_mask = 3;655 slot_width = 32;656 }657 658 switch (slots) {659 case 2:660 ser_ctrl0 = ADAU17X1_SERIAL_PORT0_STEREO;661 break;662 case 4:663 ser_ctrl0 = ADAU17X1_SERIAL_PORT0_TDM4;664 break;665 case 8:666 if (adau->type == ADAU1361)667 return -EINVAL;668 669 ser_ctrl0 = ADAU17X1_SERIAL_PORT0_TDM8;670 break;671 default:672 return -EINVAL;673 }674 675 switch (slot_width * slots) {676 case 32:677 if (adau->type == ADAU1761 || adau->type == ADAU1761_AS_1361)678 return -EINVAL;679 680 ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK32;681 break;682 case 64:683 ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK64;684 break;685 case 48:686 ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK48;687 break;688 case 128:689 ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK128;690 break;691 case 256:692 if (adau->type == ADAU1361)693 return -EINVAL;694 695 ser_ctrl1 = ADAU17X1_SERIAL_PORT1_BCLK256;696 break;697 default:698 return -EINVAL;699 }700 701 switch (rx_mask) {702 case 0x03:703 conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(1);704 adau->tdm_slot[SNDRV_PCM_STREAM_CAPTURE] = 0;705 break;706 case 0x0c:707 conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(2);708 adau->tdm_slot[SNDRV_PCM_STREAM_CAPTURE] = 1;709 break;710 case 0x30:711 conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(3);712 adau->tdm_slot[SNDRV_PCM_STREAM_CAPTURE] = 2;713 break;714 case 0xc0:715 conv_ctrl1 = ADAU17X1_CONVERTER1_ADC_PAIR(4);716 adau->tdm_slot[SNDRV_PCM_STREAM_CAPTURE] = 3;717 break;718 default:719 return -EINVAL;720 }721 722 switch (tx_mask) {723 case 0x03:724 conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(1);725 adau->tdm_slot[SNDRV_PCM_STREAM_PLAYBACK] = 0;726 break;727 case 0x0c:728 conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(2);729 adau->tdm_slot[SNDRV_PCM_STREAM_PLAYBACK] = 1;730 break;731 case 0x30:732 conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(3);733 adau->tdm_slot[SNDRV_PCM_STREAM_PLAYBACK] = 2;734 break;735 case 0xc0:736 conv_ctrl0 = ADAU17X1_CONVERTER0_DAC_PAIR(4);737 adau->tdm_slot[SNDRV_PCM_STREAM_PLAYBACK] = 3;738 break;739 default:740 return -EINVAL;741 }742 743 regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER0,744 ADAU17X1_CONVERTER0_DAC_PAIR_MASK, conv_ctrl0);745 regmap_update_bits(adau->regmap, ADAU17X1_CONVERTER1,746 ADAU17X1_CONVERTER1_ADC_PAIR_MASK, conv_ctrl1);747 regmap_update_bits(adau->regmap, ADAU17X1_SERIAL_PORT0,748 ADAU17X1_SERIAL_PORT0_TDM_MASK, ser_ctrl0);749 regmap_update_bits(adau->regmap, ADAU17X1_SERIAL_PORT1,750 ADAU17X1_SERIAL_PORT1_BCLK_MASK, ser_ctrl1);751 752 if (!adau17x1_has_dsp(adau) && !adau17x1_has_disused_dsp(adau))753 return 0;754 755 if (adau->dsp_bypass[SNDRV_PCM_STREAM_PLAYBACK]) {756 regmap_write(adau->regmap, ADAU17X1_SERIAL_INPUT_ROUTE,757 (adau->tdm_slot[SNDRV_PCM_STREAM_PLAYBACK] * 2) + 1);758 }759 760 if (adau->dsp_bypass[SNDRV_PCM_STREAM_CAPTURE]) {761 regmap_write(adau->regmap, ADAU17X1_SERIAL_OUTPUT_ROUTE,762 (adau->tdm_slot[SNDRV_PCM_STREAM_CAPTURE] * 2) + 1);763 }764 765 return 0;766}767 768static int adau17x1_startup(struct snd_pcm_substream *substream,769 struct snd_soc_dai *dai)770{771 struct adau *adau = snd_soc_component_get_drvdata(dai->component);772 773 if (adau->sigmadsp)774 return sigmadsp_restrict_params(adau->sigmadsp, substream);775 776 return 0;777}778 779const struct snd_soc_dai_ops adau17x1_dai_ops = {780 .hw_params = adau17x1_hw_params,781 .set_sysclk = adau17x1_set_dai_sysclk,782 .set_fmt = adau17x1_set_dai_fmt,783 .set_pll = adau17x1_set_dai_pll,784 .set_tdm_slot = adau17x1_set_dai_tdm_slot,785 .startup = adau17x1_startup,786};787EXPORT_SYMBOL_GPL(adau17x1_dai_ops);788 789int adau17x1_set_micbias_voltage(struct snd_soc_component *component,790 enum adau17x1_micbias_voltage micbias)791{792 struct adau *adau = snd_soc_component_get_drvdata(component);793 794 switch (micbias) {795 case ADAU17X1_MICBIAS_0_90_AVDD:796 case ADAU17X1_MICBIAS_0_65_AVDD:797 break;798 default:799 return -EINVAL;800 }801 802 return regmap_write(adau->regmap, ADAU17X1_MICBIAS, micbias << 2);803}804EXPORT_SYMBOL_GPL(adau17x1_set_micbias_voltage);805 806bool adau17x1_precious_register(struct device *dev, unsigned int reg)807{808 /* SigmaDSP parameter memory */809 if (reg < 0x400)810 return true;811 812 return false;813}814EXPORT_SYMBOL_GPL(adau17x1_precious_register);815 816bool adau17x1_readable_register(struct device *dev, unsigned int reg)817{818 /* SigmaDSP parameter memory */819 if (reg < 0x400)820 return true;821 822 switch (reg) {823 case ADAU17X1_CLOCK_CONTROL:824 case ADAU17X1_PLL_CONTROL:825 case ADAU17X1_REC_POWER_MGMT:826 case ADAU17X1_MICBIAS:827 case ADAU17X1_SERIAL_PORT0:828 case ADAU17X1_SERIAL_PORT1:829 case ADAU17X1_CONVERTER0:830 case ADAU17X1_CONVERTER1:831 case ADAU17X1_LEFT_INPUT_DIGITAL_VOL:832 case ADAU17X1_RIGHT_INPUT_DIGITAL_VOL:833 case ADAU17X1_ADC_CONTROL:834 case ADAU17X1_PLAY_POWER_MGMT:835 case ADAU17X1_DAC_CONTROL0:836 case ADAU17X1_DAC_CONTROL1:837 case ADAU17X1_DAC_CONTROL2:838 case ADAU17X1_SERIAL_PORT_PAD:839 case ADAU17X1_CONTROL_PORT_PAD0:840 case ADAU17X1_CONTROL_PORT_PAD1:841 case ADAU17X1_DSP_SAMPLING_RATE:842 case ADAU17X1_SERIAL_INPUT_ROUTE:843 case ADAU17X1_SERIAL_OUTPUT_ROUTE:844 case ADAU17X1_DSP_ENABLE:845 case ADAU17X1_DSP_RUN:846 case ADAU17X1_SERIAL_SAMPLING_RATE:847 return true;848 default:849 break;850 }851 return false;852}853EXPORT_SYMBOL_GPL(adau17x1_readable_register);854 855bool adau17x1_volatile_register(struct device *dev, unsigned int reg)856{857 /* SigmaDSP parameter and program memory */858 if (reg < 0x4000)859 return true;860 861 switch (reg) {862 /* The PLL register is 6 bytes long */863 case ADAU17X1_PLL_CONTROL:864 case ADAU17X1_PLL_CONTROL + 1:865 case ADAU17X1_PLL_CONTROL + 2:866 case ADAU17X1_PLL_CONTROL + 3:867 case ADAU17X1_PLL_CONTROL + 4:868 case ADAU17X1_PLL_CONTROL + 5:869 return true;870 default:871 break;872 }873 874 return false;875}876EXPORT_SYMBOL_GPL(adau17x1_volatile_register);877 878static int adau17x1_setup_firmware(struct snd_soc_component *component,879 unsigned int rate)880{881 int ret;882 int dspsr, dsp_run;883 struct adau *adau = snd_soc_component_get_drvdata(component);884 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);885 886 /* Check if sample rate is the same as before. If it is there is no887 * point in performing the below steps as the call to888 * sigmadsp_setup(...) will return directly when it finds the sample889 * rate to be the same as before. By checking this we can prevent an890 * audiable popping noise which occours when toggling DSP_RUN.891 */892 if (adau->sigmadsp->current_samplerate == rate)893 return 0;894 895 snd_soc_dapm_mutex_lock(dapm);896 897 ret = regmap_read(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, &dspsr);898 if (ret)899 goto err;900 901 ret = regmap_read(adau->regmap, ADAU17X1_DSP_RUN, &dsp_run);902 if (ret)903 goto err;904 905 regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 1);906 regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, 0xf);907 regmap_write(adau->regmap, ADAU17X1_DSP_RUN, 0);908 909 ret = sigmadsp_setup(adau->sigmadsp, rate);910 if (ret) {911 regmap_write(adau->regmap, ADAU17X1_DSP_ENABLE, 0);912 goto err;913 }914 regmap_write(adau->regmap, ADAU17X1_DSP_SAMPLING_RATE, dspsr);915 regmap_write(adau->regmap, ADAU17X1_DSP_RUN, dsp_run);916 917err:918 snd_soc_dapm_mutex_unlock(dapm);919 920 return ret;921}922 923int adau17x1_add_widgets(struct snd_soc_component *component)924{925 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);926 struct adau *adau = snd_soc_component_get_drvdata(component);927 int ret;928 929 ret = snd_soc_add_component_controls(component, adau17x1_controls,930 ARRAY_SIZE(adau17x1_controls));931 if (ret)932 return ret;933 ret = snd_soc_dapm_new_controls(dapm, adau17x1_dapm_widgets,934 ARRAY_SIZE(adau17x1_dapm_widgets));935 if (ret)936 return ret;937 938 if (adau17x1_has_dsp(adau)) {939 ret = snd_soc_dapm_new_controls(dapm, adau17x1_dsp_dapm_widgets,940 ARRAY_SIZE(adau17x1_dsp_dapm_widgets));941 if (ret)942 return ret;943 944 if (!adau->sigmadsp)945 return 0;946 947 ret = sigmadsp_attach(adau->sigmadsp, component);948 if (ret) {949 dev_err(component->dev, "Failed to attach firmware: %d\n",950 ret);951 return ret;952 }953 }954 955 return 0;956}957EXPORT_SYMBOL_GPL(adau17x1_add_widgets);958 959int adau17x1_add_routes(struct snd_soc_component *component)960{961 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);962 struct adau *adau = snd_soc_component_get_drvdata(component);963 int ret;964 965 ret = snd_soc_dapm_add_routes(dapm, adau17x1_dapm_routes,966 ARRAY_SIZE(adau17x1_dapm_routes));967 if (ret)968 return ret;969 970 if (adau17x1_has_dsp(adau)) {971 ret = snd_soc_dapm_add_routes(dapm, adau17x1_dsp_dapm_routes,972 ARRAY_SIZE(adau17x1_dsp_dapm_routes));973 } else {974 ret = snd_soc_dapm_add_routes(dapm, adau17x1_no_dsp_dapm_routes,975 ARRAY_SIZE(adau17x1_no_dsp_dapm_routes));976 }977 978 if (adau->clk_src != ADAU17X1_CLK_SRC_MCLK)979 snd_soc_dapm_add_routes(dapm, &adau17x1_dapm_pll_route, 1);980 981 return ret;982}983EXPORT_SYMBOL_GPL(adau17x1_add_routes);984 985int adau17x1_resume(struct snd_soc_component *component)986{987 struct adau *adau = snd_soc_component_get_drvdata(component);988 989 if (adau->switch_mode)990 adau->switch_mode(component->dev);991 992 regcache_sync(adau->regmap);993 994 return 0;995}996EXPORT_SYMBOL_GPL(adau17x1_resume);997 998static int adau17x1_safeload(struct sigmadsp *sigmadsp, unsigned int addr,999 const uint8_t bytes[], size_t len)1000{1001 uint8_t buf[ADAU17X1_WORD_SIZE];1002 uint8_t data[ADAU17X1_SAFELOAD_DATA_SIZE];1003 unsigned int addr_offset;1004 unsigned int nbr_words;1005 int ret;1006 1007 /* write data to safeload addresses. Check if len is not a multiple of1008 * 4 bytes, if so we need to zero pad.1009 */1010 nbr_words = len / ADAU17X1_WORD_SIZE;1011 if ((len - nbr_words * ADAU17X1_WORD_SIZE) == 0) {1012 ret = regmap_raw_write(sigmadsp->control_data,1013 ADAU17X1_SAFELOAD_DATA, bytes, len);1014 } else {1015 nbr_words++;1016 memset(data, 0, ADAU17X1_SAFELOAD_DATA_SIZE);1017 memcpy(data, bytes, len);1018 ret = regmap_raw_write(sigmadsp->control_data,1019 ADAU17X1_SAFELOAD_DATA, data,1020 nbr_words * ADAU17X1_WORD_SIZE);1021 }1022 1023 if (ret < 0)1024 return ret;1025 1026 /* Write target address, target address is offset by 1 */1027 addr_offset = addr - 1;1028 put_unaligned_be32(addr_offset, buf);1029 ret = regmap_raw_write(sigmadsp->control_data,1030 ADAU17X1_SAFELOAD_TARGET_ADDRESS, buf, ADAU17X1_WORD_SIZE);1031 if (ret < 0)1032 return ret;1033 1034 /* write nbr of words to trigger address */1035 put_unaligned_be32(nbr_words, buf);1036 ret = regmap_raw_write(sigmadsp->control_data,1037 ADAU17X1_SAFELOAD_TRIGGER, buf, ADAU17X1_WORD_SIZE);1038 if (ret < 0)1039 return ret;1040 1041 return 0;1042}1043 1044static const struct sigmadsp_ops adau17x1_sigmadsp_ops = {1045 .safeload = adau17x1_safeload,1046};1047 1048int adau17x1_probe(struct device *dev, struct regmap *regmap,1049 enum adau17x1_type type, void (*switch_mode)(struct device *dev),1050 const char *firmware_name)1051{1052 struct adau *adau;1053 int ret;1054 1055 if (IS_ERR(regmap))1056 return PTR_ERR(regmap);1057 1058 adau = devm_kzalloc(dev, sizeof(*adau), GFP_KERNEL);1059 if (!adau)1060 return -ENOMEM;1061 1062 /* Clock is optional (for the driver) */1063 adau->mclk = devm_clk_get_optional(dev, "mclk");1064 if (IS_ERR(adau->mclk))1065 return PTR_ERR(adau->mclk);1066 1067 if (adau->mclk) {1068 adau->clk_src = ADAU17X1_CLK_SRC_PLL_AUTO;1069 1070 /*1071 * Any valid PLL output rate will work at this point, use one1072 * that is likely to be chosen later as well. The register will1073 * be written when the PLL is powered up for the first time.1074 */1075 ret = adau_calc_pll_cfg(clk_get_rate(adau->mclk), 48000 * 1024,1076 adau->pll_regs);1077 if (ret < 0)1078 return ret;1079 1080 ret = clk_prepare_enable(adau->mclk);1081 if (ret)1082 return ret;1083 }1084 1085 adau->regmap = regmap;1086 adau->switch_mode = switch_mode;1087 adau->type = type;1088 1089 dev_set_drvdata(dev, adau);1090 1091 if (firmware_name) {1092 if (adau17x1_has_safeload(adau)) {1093 adau->sigmadsp = devm_sigmadsp_init_regmap(dev, regmap,1094 &adau17x1_sigmadsp_ops, firmware_name);1095 } else {1096 adau->sigmadsp = devm_sigmadsp_init_regmap(dev, regmap,1097 NULL, firmware_name);1098 }1099 if (IS_ERR(adau->sigmadsp)) {1100 dev_warn(dev, "Could not find firmware file: %ld\n",1101 PTR_ERR(adau->sigmadsp));1102 adau->sigmadsp = NULL;1103 }1104 }1105 1106 if (switch_mode)1107 switch_mode(dev);1108 1109 return 0;1110}1111EXPORT_SYMBOL_GPL(adau17x1_probe);1112 1113void adau17x1_remove(struct device *dev)1114{1115 struct adau *adau = dev_get_drvdata(dev);1116 1117 clk_disable_unprepare(adau->mclk);1118}1119EXPORT_SYMBOL_GPL(adau17x1_remove);1120 1121MODULE_DESCRIPTION("ASoC ADAU1X61/ADAU1X81 common code");1122MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");1123MODULE_LICENSE("GPL");1124