890 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * es8328.c -- ES8328 ALSA SoC Audio driver4 *5 * Copyright 2014 Sutajio Ko-Usagi PTE LTD6 *7 * Author: Sean Cross <xobs@kosagi.com>8 */9 10#include <linux/clk.h>11#include <linux/delay.h>12#include <linux/module.h>13#include <linux/pm.h>14#include <linux/regmap.h>15#include <linux/slab.h>16#include <linux/regulator/consumer.h>17#include <sound/core.h>18#include <sound/initval.h>19#include <sound/pcm.h>20#include <sound/pcm_params.h>21#include <sound/soc.h>22#include <sound/tlv.h>23#include "es8328.h"24 25static const unsigned int rates_12288[] = {26 8000, 12000, 16000, 24000, 32000, 48000, 96000,27};28 29static const int ratios_12288[] = {30 10, 7, 6, 4, 3, 2, 0,31};32 33static const struct snd_pcm_hw_constraint_list constraints_12288 = {34 .count = ARRAY_SIZE(rates_12288),35 .list = rates_12288,36};37 38static const unsigned int rates_11289[] = {39 8018, 11025, 22050, 44100, 88200,40};41 42static const int ratios_11289[] = {43 9, 7, 4, 2, 0,44};45 46static const struct snd_pcm_hw_constraint_list constraints_11289 = {47 .count = ARRAY_SIZE(rates_11289),48 .list = rates_11289,49};50 51/* regulator supplies for sgtl5000, VDDD is an optional external supply */52enum sgtl5000_regulator_supplies {53 DVDD,54 AVDD,55 PVDD,56 HPVDD,57 ES8328_SUPPLY_NUM58};59 60/* vddd is optional supply */61static const char * const supply_names[ES8328_SUPPLY_NUM] = {62 "DVDD",63 "AVDD",64 "PVDD",65 "HPVDD",66};67 68#define ES8328_RATES (SNDRV_PCM_RATE_192000 | \69 SNDRV_PCM_RATE_96000 | \70 SNDRV_PCM_RATE_88200 | \71 SNDRV_PCM_RATE_8000_48000)72#define ES8328_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \73 SNDRV_PCM_FMTBIT_S18_3LE | \74 SNDRV_PCM_FMTBIT_S20_3LE | \75 SNDRV_PCM_FMTBIT_S24_LE | \76 SNDRV_PCM_FMTBIT_S32_LE)77 78struct es8328_priv {79 struct regmap *regmap;80 struct clk *clk;81 int playback_fs;82 bool deemph;83 int mclkdiv2;84 const struct snd_pcm_hw_constraint_list *sysclk_constraints;85 const int *mclk_ratios;86 bool provider;87 struct regulator_bulk_data supplies[ES8328_SUPPLY_NUM];88};89 90/*91 * ES8328 Controls92 */93 94static const char * const adcpol_txt[] = {"Normal", "L Invert", "R Invert",95 "L + R Invert"};96static SOC_ENUM_SINGLE_DECL(adcpol,97 ES8328_ADCCONTROL6, 6, adcpol_txt);98 99static const DECLARE_TLV_DB_SCALE(play_tlv, -3000, 100, 0);100static const DECLARE_TLV_DB_SCALE(dac_adc_tlv, -9600, 50, 0);101static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0);102static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 300, 0);103 104static const struct {105 int rate;106 unsigned int val;107} deemph_settings[] = {108 { 0, ES8328_DACCONTROL6_DEEMPH_OFF },109 { 32000, ES8328_DACCONTROL6_DEEMPH_32k },110 { 44100, ES8328_DACCONTROL6_DEEMPH_44_1k },111 { 48000, ES8328_DACCONTROL6_DEEMPH_48k },112};113 114static int es8328_set_deemph(struct snd_soc_component *component)115{116 struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);117 int val, i, best;118 119 /*120 * If we're using deemphasis select the nearest available sample121 * rate.122 */123 if (es8328->deemph) {124 best = 0;125 for (i = 1; i < ARRAY_SIZE(deemph_settings); i++) {126 if (abs(deemph_settings[i].rate - es8328->playback_fs) <127 abs(deemph_settings[best].rate - es8328->playback_fs))128 best = i;129 }130 131 val = deemph_settings[best].val;132 } else {133 val = ES8328_DACCONTROL6_DEEMPH_OFF;134 }135 136 dev_dbg(component->dev, "Set deemphasis %d\n", val);137 138 return snd_soc_component_update_bits(component, ES8328_DACCONTROL6,139 ES8328_DACCONTROL6_DEEMPH_MASK, val);140}141 142static int es8328_get_deemph(struct snd_kcontrol *kcontrol,143 struct snd_ctl_elem_value *ucontrol)144{145 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);146 struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);147 148 ucontrol->value.integer.value[0] = es8328->deemph;149 return 0;150}151 152static int es8328_put_deemph(struct snd_kcontrol *kcontrol,153 struct snd_ctl_elem_value *ucontrol)154{155 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);156 struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);157 unsigned int deemph = ucontrol->value.integer.value[0];158 int ret;159 160 if (deemph > 1)161 return -EINVAL;162 163 if (es8328->deemph == deemph)164 return 0;165 166 ret = es8328_set_deemph(component);167 if (ret < 0)168 return ret;169 170 es8328->deemph = deemph;171 172 return 1;173}174 175 176 177static const struct snd_kcontrol_new es8328_snd_controls[] = {178 SOC_DOUBLE_R_TLV("Capture Digital Volume",179 ES8328_ADCCONTROL8, ES8328_ADCCONTROL9,180 0, 0xc0, 1, dac_adc_tlv),181 SOC_SINGLE("Capture ZC Switch", ES8328_ADCCONTROL7, 6, 1, 0),182 183 SOC_SINGLE_BOOL_EXT("DAC Deemphasis Switch", 0,184 es8328_get_deemph, es8328_put_deemph),185 186 SOC_ENUM("Capture Polarity", adcpol),187 188 SOC_SINGLE_TLV("Left Mixer Left Bypass Volume",189 ES8328_DACCONTROL17, 3, 7, 1, bypass_tlv),190 SOC_SINGLE_TLV("Left Mixer Right Bypass Volume",191 ES8328_DACCONTROL19, 3, 7, 1, bypass_tlv),192 SOC_SINGLE_TLV("Right Mixer Left Bypass Volume",193 ES8328_DACCONTROL18, 3, 7, 1, bypass_tlv),194 SOC_SINGLE_TLV("Right Mixer Right Bypass Volume",195 ES8328_DACCONTROL20, 3, 7, 1, bypass_tlv),196 197 SOC_DOUBLE_R_TLV("PCM Volume",198 ES8328_LDACVOL, ES8328_RDACVOL,199 0, ES8328_DACVOL_MAX, 1, dac_adc_tlv),200 201 SOC_DOUBLE_R_TLV("Output 1 Playback Volume",202 ES8328_LOUT1VOL, ES8328_ROUT1VOL,203 0, ES8328_OUT1VOL_MAX, 0, play_tlv),204 205 SOC_DOUBLE_R_TLV("Output 2 Playback Volume",206 ES8328_LOUT2VOL, ES8328_ROUT2VOL,207 0, ES8328_OUT2VOL_MAX, 0, play_tlv),208 209 SOC_DOUBLE_TLV("Mic PGA Volume", ES8328_ADCCONTROL1,210 4, 0, 8, 0, mic_tlv),211};212 213/*214 * DAPM Controls215 */216 217static const char * const es8328_line_texts[] = {218 "Line 1", "Line 2", "PGA", "Differential"};219 220static const struct soc_enum es8328_lline_enum =221 SOC_ENUM_SINGLE(ES8328_DACCONTROL16, 3,222 ARRAY_SIZE(es8328_line_texts),223 es8328_line_texts);224static const struct snd_kcontrol_new es8328_left_line_controls =225 SOC_DAPM_ENUM("Route", es8328_lline_enum);226 227static const struct soc_enum es8328_rline_enum =228 SOC_ENUM_SINGLE(ES8328_DACCONTROL16, 0,229 ARRAY_SIZE(es8328_line_texts),230 es8328_line_texts);231static const struct snd_kcontrol_new es8328_right_line_controls =232 SOC_DAPM_ENUM("Route", es8328_rline_enum);233 234/* Left Mixer */235static const struct snd_kcontrol_new es8328_left_mixer_controls[] = {236 SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL17, 7, 1, 0),237 SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL17, 6, 1, 0),238 SOC_DAPM_SINGLE("Right Playback Switch", ES8328_DACCONTROL18, 7, 1, 0),239 SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL18, 6, 1, 0),240};241 242/* Right Mixer */243static const struct snd_kcontrol_new es8328_right_mixer_controls[] = {244 SOC_DAPM_SINGLE("Left Playback Switch", ES8328_DACCONTROL19, 7, 1, 0),245 SOC_DAPM_SINGLE("Left Bypass Switch", ES8328_DACCONTROL19, 6, 1, 0),246 SOC_DAPM_SINGLE("Playback Switch", ES8328_DACCONTROL20, 7, 1, 0),247 SOC_DAPM_SINGLE("Right Bypass Switch", ES8328_DACCONTROL20, 6, 1, 0),248};249 250static const char * const es8328_pga_sel[] = {251 "Line 1", "Line 2", "Line 3", "Differential"};252 253/* Left PGA Mux */254static const struct soc_enum es8328_lpga_enum =255 SOC_ENUM_SINGLE(ES8328_ADCCONTROL2, 6,256 ARRAY_SIZE(es8328_pga_sel),257 es8328_pga_sel);258static const struct snd_kcontrol_new es8328_left_pga_controls =259 SOC_DAPM_ENUM("Route", es8328_lpga_enum);260 261/* Right PGA Mux */262static const struct soc_enum es8328_rpga_enum =263 SOC_ENUM_SINGLE(ES8328_ADCCONTROL2, 4,264 ARRAY_SIZE(es8328_pga_sel),265 es8328_pga_sel);266static const struct snd_kcontrol_new es8328_right_pga_controls =267 SOC_DAPM_ENUM("Route", es8328_rpga_enum);268 269/* Differential Mux */270static const char * const es8328_diff_sel[] = {"Line 1", "Line 2"};271static SOC_ENUM_SINGLE_DECL(diffmux,272 ES8328_ADCCONTROL3, 7, es8328_diff_sel);273static const struct snd_kcontrol_new es8328_diffmux_controls =274 SOC_DAPM_ENUM("Route", diffmux);275 276/* Mono ADC Mux */277static const char * const es8328_mono_mux[] = {"Stereo", "Mono (Left)",278 "Mono (Right)", "Digital Mono"};279static SOC_ENUM_SINGLE_DECL(monomux,280 ES8328_ADCCONTROL3, 3, es8328_mono_mux);281static const struct snd_kcontrol_new es8328_monomux_controls =282 SOC_DAPM_ENUM("Route", monomux);283 284static const struct snd_soc_dapm_widget es8328_dapm_widgets[] = {285 SND_SOC_DAPM_MUX("Differential Mux", SND_SOC_NOPM, 0, 0,286 &es8328_diffmux_controls),287 SND_SOC_DAPM_MUX("Left ADC Mux", SND_SOC_NOPM, 0, 0,288 &es8328_monomux_controls),289 SND_SOC_DAPM_MUX("Right ADC Mux", SND_SOC_NOPM, 0, 0,290 &es8328_monomux_controls),291 292 SND_SOC_DAPM_MUX("Left PGA Mux", ES8328_ADCPOWER,293 ES8328_ADCPOWER_AINL_OFF, 1,294 &es8328_left_pga_controls),295 SND_SOC_DAPM_MUX("Right PGA Mux", ES8328_ADCPOWER,296 ES8328_ADCPOWER_AINR_OFF, 1,297 &es8328_right_pga_controls),298 299 SND_SOC_DAPM_MUX("Left Line Mux", SND_SOC_NOPM, 0, 0,300 &es8328_left_line_controls),301 SND_SOC_DAPM_MUX("Right Line Mux", SND_SOC_NOPM, 0, 0,302 &es8328_right_line_controls),303 304 SND_SOC_DAPM_ADC("Right ADC", "Right Capture", ES8328_ADCPOWER,305 ES8328_ADCPOWER_ADCR_OFF, 1),306 SND_SOC_DAPM_ADC("Left ADC", "Left Capture", ES8328_ADCPOWER,307 ES8328_ADCPOWER_ADCL_OFF, 1),308 309 SND_SOC_DAPM_SUPPLY("Mic Bias", ES8328_ADCPOWER,310 ES8328_ADCPOWER_MIC_BIAS_OFF, 1, NULL, 0),311 SND_SOC_DAPM_SUPPLY("Mic Bias Gen", ES8328_ADCPOWER,312 ES8328_ADCPOWER_ADC_BIAS_GEN_OFF, 1, NULL, 0),313 314 SND_SOC_DAPM_SUPPLY("DAC STM", ES8328_CHIPPOWER,315 ES8328_CHIPPOWER_DACSTM_RESET, 1, NULL, 0),316 SND_SOC_DAPM_SUPPLY("ADC STM", ES8328_CHIPPOWER,317 ES8328_CHIPPOWER_ADCSTM_RESET, 1, NULL, 0),318 319 SND_SOC_DAPM_SUPPLY("DAC DIG", ES8328_CHIPPOWER,320 ES8328_CHIPPOWER_DACDIG_OFF, 1, NULL, 0),321 SND_SOC_DAPM_SUPPLY("ADC DIG", ES8328_CHIPPOWER,322 ES8328_CHIPPOWER_ADCDIG_OFF, 1, NULL, 0),323 324 SND_SOC_DAPM_SUPPLY("DAC DLL", ES8328_CHIPPOWER,325 ES8328_CHIPPOWER_DACDLL_OFF, 1, NULL, 0),326 SND_SOC_DAPM_SUPPLY("ADC DLL", ES8328_CHIPPOWER,327 ES8328_CHIPPOWER_ADCDLL_OFF, 1, NULL, 0),328 329 SND_SOC_DAPM_SUPPLY("ADC Vref", ES8328_CHIPPOWER,330 ES8328_CHIPPOWER_ADCVREF_OFF, 1, NULL, 0),331 SND_SOC_DAPM_SUPPLY("DAC Vref", ES8328_CHIPPOWER,332 ES8328_CHIPPOWER_DACVREF_OFF, 1, NULL, 0),333 334 SND_SOC_DAPM_DAC("Right DAC", "Right Playback", ES8328_DACPOWER,335 ES8328_DACPOWER_RDAC_OFF, 1),336 SND_SOC_DAPM_DAC("Left DAC", "Left Playback", ES8328_DACPOWER,337 ES8328_DACPOWER_LDAC_OFF, 1),338 339 SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0,340 &es8328_left_mixer_controls[0],341 ARRAY_SIZE(es8328_left_mixer_controls)),342 SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0,343 &es8328_right_mixer_controls[0],344 ARRAY_SIZE(es8328_right_mixer_controls)),345 346 SND_SOC_DAPM_PGA("Right Out 2", ES8328_DACPOWER,347 ES8328_DACPOWER_ROUT2_ON, 0, NULL, 0),348 SND_SOC_DAPM_PGA("Left Out 2", ES8328_DACPOWER,349 ES8328_DACPOWER_LOUT2_ON, 0, NULL, 0),350 SND_SOC_DAPM_PGA("Right Out 1", ES8328_DACPOWER,351 ES8328_DACPOWER_ROUT1_ON, 0, NULL, 0),352 SND_SOC_DAPM_PGA("Left Out 1", ES8328_DACPOWER,353 ES8328_DACPOWER_LOUT1_ON, 0, NULL, 0),354 355 SND_SOC_DAPM_OUTPUT("LOUT1"),356 SND_SOC_DAPM_OUTPUT("ROUT1"),357 SND_SOC_DAPM_OUTPUT("LOUT2"),358 SND_SOC_DAPM_OUTPUT("ROUT2"),359 360 SND_SOC_DAPM_INPUT("LINPUT1"),361 SND_SOC_DAPM_INPUT("LINPUT2"),362 SND_SOC_DAPM_INPUT("RINPUT1"),363 SND_SOC_DAPM_INPUT("RINPUT2"),364};365 366static const struct snd_soc_dapm_route es8328_dapm_routes[] = {367 368 { "Left Line Mux", "Line 1", "LINPUT1" },369 { "Left Line Mux", "Line 2", "LINPUT2" },370 { "Left Line Mux", "PGA", "Left PGA Mux" },371 { "Left Line Mux", "Differential", "Differential Mux" },372 373 { "Right Line Mux", "Line 1", "RINPUT1" },374 { "Right Line Mux", "Line 2", "RINPUT2" },375 { "Right Line Mux", "PGA", "Right PGA Mux" },376 { "Right Line Mux", "Differential", "Differential Mux" },377 378 { "Left PGA Mux", "Line 1", "LINPUT1" },379 { "Left PGA Mux", "Line 2", "LINPUT2" },380 { "Left PGA Mux", "Differential", "Differential Mux" },381 382 { "Right PGA Mux", "Line 1", "RINPUT1" },383 { "Right PGA Mux", "Line 2", "RINPUT2" },384 { "Right PGA Mux", "Differential", "Differential Mux" },385 386 { "Differential Mux", "Line 1", "LINPUT1" },387 { "Differential Mux", "Line 1", "RINPUT1" },388 { "Differential Mux", "Line 2", "LINPUT2" },389 { "Differential Mux", "Line 2", "RINPUT2" },390 391 { "Left ADC Mux", "Stereo", "Left PGA Mux" },392 { "Left ADC Mux", "Mono (Left)", "Left PGA Mux" },393 { "Left ADC Mux", "Digital Mono", "Left PGA Mux" },394 395 { "Right ADC Mux", "Stereo", "Right PGA Mux" },396 { "Right ADC Mux", "Mono (Right)", "Right PGA Mux" },397 { "Right ADC Mux", "Digital Mono", "Right PGA Mux" },398 399 { "Left ADC", NULL, "Left ADC Mux" },400 { "Right ADC", NULL, "Right ADC Mux" },401 402 { "ADC DIG", NULL, "ADC STM" },403 { "ADC DIG", NULL, "ADC Vref" },404 { "ADC DIG", NULL, "ADC DLL" },405 406 { "Left ADC", NULL, "ADC DIG" },407 { "Right ADC", NULL, "ADC DIG" },408 409 { "Mic Bias", NULL, "Mic Bias Gen" },410 411 { "Left Line Mux", "Line 1", "LINPUT1" },412 { "Left Line Mux", "Line 2", "LINPUT2" },413 { "Left Line Mux", "PGA", "Left PGA Mux" },414 { "Left Line Mux", "Differential", "Differential Mux" },415 416 { "Right Line Mux", "Line 1", "RINPUT1" },417 { "Right Line Mux", "Line 2", "RINPUT2" },418 { "Right Line Mux", "PGA", "Right PGA Mux" },419 { "Right Line Mux", "Differential", "Differential Mux" },420 421 { "Left Out 1", NULL, "Left DAC" },422 { "Right Out 1", NULL, "Right DAC" },423 { "Left Out 2", NULL, "Left DAC" },424 { "Right Out 2", NULL, "Right DAC" },425 426 { "Left Mixer", "Playback Switch", "Left DAC" },427 { "Left Mixer", "Left Bypass Switch", "Left Line Mux" },428 { "Left Mixer", "Right Playback Switch", "Right DAC" },429 { "Left Mixer", "Right Bypass Switch", "Right Line Mux" },430 431 { "Right Mixer", "Left Playback Switch", "Left DAC" },432 { "Right Mixer", "Left Bypass Switch", "Left Line Mux" },433 { "Right Mixer", "Playback Switch", "Right DAC" },434 { "Right Mixer", "Right Bypass Switch", "Right Line Mux" },435 436 { "DAC DIG", NULL, "DAC STM" },437 { "DAC DIG", NULL, "DAC Vref" },438 { "DAC DIG", NULL, "DAC DLL" },439 440 { "Left DAC", NULL, "DAC DIG" },441 { "Right DAC", NULL, "DAC DIG" },442 443 { "Left Out 1", NULL, "Left Mixer" },444 { "LOUT1", NULL, "Left Out 1" },445 { "Right Out 1", NULL, "Right Mixer" },446 { "ROUT1", NULL, "Right Out 1" },447 448 { "Left Out 2", NULL, "Left Mixer" },449 { "LOUT2", NULL, "Left Out 2" },450 { "Right Out 2", NULL, "Right Mixer" },451 { "ROUT2", NULL, "Right Out 2" },452};453 454static int es8328_mute(struct snd_soc_dai *dai, int mute, int direction)455{456 return snd_soc_component_update_bits(dai->component, ES8328_DACCONTROL3,457 ES8328_DACCONTROL3_DACMUTE,458 mute ? ES8328_DACCONTROL3_DACMUTE : 0);459}460 461static int es8328_startup(struct snd_pcm_substream *substream,462 struct snd_soc_dai *dai)463{464 struct snd_soc_component *component = dai->component;465 struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);466 467 if (es8328->provider && es8328->sysclk_constraints)468 snd_pcm_hw_constraint_list(substream->runtime, 0,469 SNDRV_PCM_HW_PARAM_RATE,470 es8328->sysclk_constraints);471 472 return 0;473}474 475static int es8328_hw_params(struct snd_pcm_substream *substream,476 struct snd_pcm_hw_params *params,477 struct snd_soc_dai *dai)478{479 struct snd_soc_component *component = dai->component;480 struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);481 int i;482 int reg;483 int wl;484 int ratio;485 486 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)487 reg = ES8328_DACCONTROL2;488 else489 reg = ES8328_ADCCONTROL5;490 491 if (es8328->provider) {492 if (!es8328->sysclk_constraints) {493 dev_err(component->dev, "No MCLK configured\n");494 return -EINVAL;495 }496 497 for (i = 0; i < es8328->sysclk_constraints->count; i++)498 if (es8328->sysclk_constraints->list[i] ==499 params_rate(params))500 break;501 502 if (i == es8328->sysclk_constraints->count) {503 dev_err(component->dev,504 "LRCLK %d unsupported with current clock\n",505 params_rate(params));506 return -EINVAL;507 }508 ratio = es8328->mclk_ratios[i];509 } else {510 ratio = 0;511 es8328->mclkdiv2 = 0;512 }513 514 snd_soc_component_update_bits(component, ES8328_MASTERMODE,515 ES8328_MASTERMODE_MCLKDIV2,516 es8328->mclkdiv2 ? ES8328_MASTERMODE_MCLKDIV2 : 0);517 518 switch (params_width(params)) {519 case 16:520 wl = 3;521 break;522 case 18:523 wl = 2;524 break;525 case 20:526 wl = 1;527 break;528 case 24:529 wl = 0;530 break;531 case 32:532 wl = 4;533 break;534 default:535 return -EINVAL;536 }537 538 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {539 snd_soc_component_update_bits(component, ES8328_DACCONTROL1,540 ES8328_DACCONTROL1_DACWL_MASK,541 wl << ES8328_DACCONTROL1_DACWL_SHIFT);542 543 es8328->playback_fs = params_rate(params);544 es8328_set_deemph(component);545 } else546 snd_soc_component_update_bits(component, ES8328_ADCCONTROL4,547 ES8328_ADCCONTROL4_ADCWL_MASK,548 wl << ES8328_ADCCONTROL4_ADCWL_SHIFT);549 550 return snd_soc_component_update_bits(component, reg, ES8328_RATEMASK, ratio);551}552 553static int es8328_set_sysclk(struct snd_soc_dai *codec_dai,554 int clk_id, unsigned int freq, int dir)555{556 struct snd_soc_component *component = codec_dai->component;557 struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);558 int mclkdiv2 = 0;559 unsigned int round_freq;560 561 /*562 * Allow a small tolerance for frequencies within 100hz. Note563 * this value is chosen arbitrarily.564 */565 round_freq = DIV_ROUND_CLOSEST(freq, 100) * 100;566 567 switch (round_freq) {568 case 0:569 es8328->sysclk_constraints = NULL;570 es8328->mclk_ratios = NULL;571 break;572 case 22579200:573 mclkdiv2 = 1;574 fallthrough;575 case 11289600:576 es8328->sysclk_constraints = &constraints_11289;577 es8328->mclk_ratios = ratios_11289;578 break;579 case 24576000:580 mclkdiv2 = 1;581 fallthrough;582 case 12288000:583 es8328->sysclk_constraints = &constraints_12288;584 es8328->mclk_ratios = ratios_12288;585 break;586 default:587 return -EINVAL;588 }589 590 es8328->mclkdiv2 = mclkdiv2;591 return 0;592}593 594static int es8328_set_dai_fmt(struct snd_soc_dai *codec_dai,595 unsigned int fmt)596{597 struct snd_soc_component *component = codec_dai->component;598 struct es8328_priv *es8328 = snd_soc_component_get_drvdata(component);599 u8 dac_mode = 0;600 u8 adc_mode = 0;601 602 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {603 case SND_SOC_DAIFMT_CBP_CFP:604 /* Master serial port mode, with BCLK generated automatically */605 snd_soc_component_update_bits(component, ES8328_MASTERMODE,606 ES8328_MASTERMODE_MSC,607 ES8328_MASTERMODE_MSC);608 es8328->provider = true;609 break;610 case SND_SOC_DAIFMT_CBC_CFC:611 /* Slave serial port mode */612 snd_soc_component_update_bits(component, ES8328_MASTERMODE,613 ES8328_MASTERMODE_MSC, 0);614 es8328->provider = false;615 break;616 default:617 return -EINVAL;618 }619 620 /* interface format */621 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {622 case SND_SOC_DAIFMT_I2S:623 dac_mode |= ES8328_DACCONTROL1_DACFORMAT_I2S;624 adc_mode |= ES8328_ADCCONTROL4_ADCFORMAT_I2S;625 break;626 case SND_SOC_DAIFMT_RIGHT_J:627 dac_mode |= ES8328_DACCONTROL1_DACFORMAT_RJUST;628 adc_mode |= ES8328_ADCCONTROL4_ADCFORMAT_RJUST;629 break;630 case SND_SOC_DAIFMT_LEFT_J:631 dac_mode |= ES8328_DACCONTROL1_DACFORMAT_LJUST;632 adc_mode |= ES8328_ADCCONTROL4_ADCFORMAT_LJUST;633 break;634 default:635 return -EINVAL;636 }637 638 /* clock inversion */639 if ((fmt & SND_SOC_DAIFMT_INV_MASK) != SND_SOC_DAIFMT_NB_NF)640 return -EINVAL;641 642 snd_soc_component_update_bits(component, ES8328_DACCONTROL1,643 ES8328_DACCONTROL1_DACFORMAT_MASK, dac_mode);644 snd_soc_component_update_bits(component, ES8328_ADCCONTROL4,645 ES8328_ADCCONTROL4_ADCFORMAT_MASK, adc_mode);646 647 return 0;648}649 650static int es8328_set_bias_level(struct snd_soc_component *component,651 enum snd_soc_bias_level level)652{653 switch (level) {654 case SND_SOC_BIAS_ON:655 break;656 657 case SND_SOC_BIAS_PREPARE:658 /* VREF, VMID=2x50k, digital enabled */659 snd_soc_component_write(component, ES8328_CHIPPOWER, 0);660 snd_soc_component_update_bits(component, ES8328_CONTROL1,661 ES8328_CONTROL1_VMIDSEL_MASK |662 ES8328_CONTROL1_ENREF,663 ES8328_CONTROL1_VMIDSEL_50k |664 ES8328_CONTROL1_ENREF);665 break;666 667 case SND_SOC_BIAS_STANDBY:668 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {669 snd_soc_component_update_bits(component, ES8328_CONTROL1,670 ES8328_CONTROL1_VMIDSEL_MASK |671 ES8328_CONTROL1_ENREF,672 ES8328_CONTROL1_VMIDSEL_5k |673 ES8328_CONTROL1_ENREF);674 675 /* Charge caps */676 msleep(100);677 }678 679 snd_soc_component_write(component, ES8328_CONTROL2,680 ES8328_CONTROL2_OVERCURRENT_ON |681 ES8328_CONTROL2_THERMAL_SHUTDOWN_ON);682 683 /* VREF, VMID=2*500k, digital stopped */684 snd_soc_component_update_bits(component, ES8328_CONTROL1,685 ES8328_CONTROL1_VMIDSEL_MASK |686 ES8328_CONTROL1_ENREF,687 ES8328_CONTROL1_VMIDSEL_500k |688 ES8328_CONTROL1_ENREF);689 break;690 691 case SND_SOC_BIAS_OFF:692 snd_soc_component_update_bits(component, ES8328_CONTROL1,693 ES8328_CONTROL1_VMIDSEL_MASK |694 ES8328_CONTROL1_ENREF,695 0);696 break;697 }698 return 0;699}700 701static const struct snd_soc_dai_ops es8328_dai_ops = {702 .startup = es8328_startup,703 .hw_params = es8328_hw_params,704 .mute_stream = es8328_mute,705 .set_sysclk = es8328_set_sysclk,706 .set_fmt = es8328_set_dai_fmt,707 .no_capture_mute = 1,708};709 710static struct snd_soc_dai_driver es8328_dai = {711 .name = "es8328-hifi-analog",712 .playback = {713 .stream_name = "Playback",714 .channels_min = 2,715 .channels_max = 2,716 .rates = ES8328_RATES,717 .formats = ES8328_FORMATS,718 },719 .capture = {720 .stream_name = "Capture",721 .channels_min = 2,722 .channels_max = 2,723 .rates = ES8328_RATES,724 .formats = ES8328_FORMATS,725 },726 .ops = &es8328_dai_ops,727 .symmetric_rate = 1,728};729 730static int es8328_suspend(struct snd_soc_component *component)731{732 struct es8328_priv *es8328;733 int ret;734 735 es8328 = snd_soc_component_get_drvdata(component);736 737 clk_disable_unprepare(es8328->clk);738 739 ret = regulator_bulk_disable(ARRAY_SIZE(es8328->supplies),740 es8328->supplies);741 if (ret) {742 dev_err(component->dev, "unable to disable regulators\n");743 return ret;744 }745 return 0;746}747 748static int es8328_resume(struct snd_soc_component *component)749{750 struct regmap *regmap = dev_get_regmap(component->dev, NULL);751 struct es8328_priv *es8328;752 int ret;753 754 es8328 = snd_soc_component_get_drvdata(component);755 756 ret = clk_prepare_enable(es8328->clk);757 if (ret) {758 dev_err(component->dev, "unable to enable clock\n");759 return ret;760 }761 762 ret = regulator_bulk_enable(ARRAY_SIZE(es8328->supplies),763 es8328->supplies);764 if (ret) {765 dev_err(component->dev, "unable to enable regulators\n");766 return ret;767 }768 769 regcache_mark_dirty(regmap);770 ret = regcache_sync(regmap);771 if (ret) {772 dev_err(component->dev, "unable to sync regcache\n");773 return ret;774 }775 776 return 0;777}778 779static int es8328_component_probe(struct snd_soc_component *component)780{781 struct es8328_priv *es8328;782 int ret;783 784 es8328 = snd_soc_component_get_drvdata(component);785 786 ret = regulator_bulk_enable(ARRAY_SIZE(es8328->supplies),787 es8328->supplies);788 if (ret) {789 dev_err(component->dev, "unable to enable regulators\n");790 return ret;791 }792 793 /* Setup clocks */794 es8328->clk = devm_clk_get(component->dev, NULL);795 if (IS_ERR(es8328->clk)) {796 dev_err(component->dev, "codec clock missing or invalid\n");797 ret = PTR_ERR(es8328->clk);798 goto clk_fail;799 }800 801 ret = clk_prepare_enable(es8328->clk);802 if (ret) {803 dev_err(component->dev, "unable to prepare codec clk\n");804 goto clk_fail;805 }806 807 return 0;808 809clk_fail:810 regulator_bulk_disable(ARRAY_SIZE(es8328->supplies),811 es8328->supplies);812 return ret;813}814 815static void es8328_remove(struct snd_soc_component *component)816{817 struct es8328_priv *es8328;818 819 es8328 = snd_soc_component_get_drvdata(component);820 821 clk_disable_unprepare(es8328->clk);822 823 regulator_bulk_disable(ARRAY_SIZE(es8328->supplies),824 es8328->supplies);825}826 827const struct regmap_config es8328_regmap_config = {828 .reg_bits = 8,829 .val_bits = 8,830 .max_register = ES8328_REG_MAX,831 .cache_type = REGCACHE_MAPLE,832 .use_single_read = true,833 .use_single_write = true,834};835EXPORT_SYMBOL_GPL(es8328_regmap_config);836 837static const struct snd_soc_component_driver es8328_component_driver = {838 .probe = es8328_component_probe,839 .remove = es8328_remove,840 .suspend = es8328_suspend,841 .resume = es8328_resume,842 .set_bias_level = es8328_set_bias_level,843 .controls = es8328_snd_controls,844 .num_controls = ARRAY_SIZE(es8328_snd_controls),845 .dapm_widgets = es8328_dapm_widgets,846 .num_dapm_widgets = ARRAY_SIZE(es8328_dapm_widgets),847 .dapm_routes = es8328_dapm_routes,848 .num_dapm_routes = ARRAY_SIZE(es8328_dapm_routes),849 .suspend_bias_off = 1,850 .idle_bias_on = 1,851 .use_pmdown_time = 1,852 .endianness = 1,853};854 855int es8328_probe(struct device *dev, struct regmap *regmap)856{857 struct es8328_priv *es8328;858 int ret;859 int i;860 861 if (IS_ERR(regmap))862 return PTR_ERR(regmap);863 864 es8328 = devm_kzalloc(dev, sizeof(*es8328), GFP_KERNEL);865 if (es8328 == NULL)866 return -ENOMEM;867 868 es8328->regmap = regmap;869 870 for (i = 0; i < ARRAY_SIZE(es8328->supplies); i++)871 es8328->supplies[i].supply = supply_names[i];872 873 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(es8328->supplies),874 es8328->supplies);875 if (ret) {876 dev_err(dev, "unable to get regulators\n");877 return ret;878 }879 880 dev_set_drvdata(dev, es8328);881 882 return devm_snd_soc_register_component(dev,883 &es8328_component_driver, &es8328_dai, 1);884}885EXPORT_SYMBOL_GPL(es8328_probe);886 887MODULE_DESCRIPTION("ASoC ES8328 driver");888MODULE_AUTHOR("Sean Cross <xobs@kosagi.com>");889MODULE_LICENSE("GPL");890