3091 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * wm8996.c - WM8996 audio codec interface4 *5 * Copyright 2011-2 Wolfson Microelectronics PLC.6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>7 */8 9#include <linux/module.h>10#include <linux/moduleparam.h>11#include <linux/init.h>12#include <linux/completion.h>13#include <linux/delay.h>14#include <linux/pm.h>15#include <linux/gcd.h>16#include <linux/gpio/driver.h>17#include <linux/gpio/consumer.h>18#include <linux/i2c.h>19#include <linux/regmap.h>20#include <linux/regulator/consumer.h>21#include <linux/slab.h>22#include <linux/workqueue.h>23#include <sound/core.h>24#include <sound/jack.h>25#include <sound/pcm.h>26#include <sound/pcm_params.h>27#include <sound/soc.h>28#include <sound/initval.h>29#include <sound/tlv.h>30#include <trace/events/asoc.h>31 32#include <sound/wm8996.h>33#include "wm8996.h"34 35#define WM8996_AIFS 236 37#define HPOUT1L 138#define HPOUT1R 239#define HPOUT2L 440#define HPOUT2R 841 42#define WM8996_NUM_SUPPLIES 343static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = {44 "DBVDD",45 "AVDD1",46 "AVDD2",47};48 49struct wm8996_priv {50 struct device *dev;51 struct regmap *regmap;52 struct snd_soc_component *component;53 54 struct gpio_desc *ldo_ena;55 56 int sysclk;57 int sysclk_src;58 59 int fll_src;60 int fll_fref;61 int fll_fout;62 63 struct completion fll_lock;64 65 u16 dcs_pending;66 struct completion dcs_done;67 68 u16 hpout_ena;69 u16 hpout_pending;70 71 struct regulator_bulk_data supplies[WM8996_NUM_SUPPLIES];72 struct notifier_block disable_nb[WM8996_NUM_SUPPLIES];73 int bg_ena;74 75 struct wm8996_pdata pdata;76 77 int rx_rate[WM8996_AIFS];78 int bclk_rate[WM8996_AIFS];79 80 /* Platform dependant ReTune mobile configuration */81 int num_retune_mobile_texts;82 const char **retune_mobile_texts;83 int retune_mobile_cfg[2];84 struct soc_enum retune_mobile_enum;85 86 struct snd_soc_jack *jack;87 bool detecting;88 bool jack_mic;89 int jack_flips;90 wm8996_polarity_fn polarity_cb;91 92#ifdef CONFIG_GPIOLIB93 struct gpio_chip gpio_chip;94#endif95};96 97/* We can't use the same notifier block for more than one supply and98 * there's no way I can see to get from a callback to the caller99 * except container_of().100 */101#define WM8996_REGULATOR_EVENT(n) \102static int wm8996_regulator_event_##n(struct notifier_block *nb, \103 unsigned long event, void *data) \104{ \105 struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \106 disable_nb[n]); \107 if (event & REGULATOR_EVENT_DISABLE) { \108 regcache_mark_dirty(wm8996->regmap); \109 } \110 return 0; \111}112 113WM8996_REGULATOR_EVENT(0)114WM8996_REGULATOR_EVENT(1)115WM8996_REGULATOR_EVENT(2)116 117static const struct reg_default wm8996_reg[] = {118 { WM8996_POWER_MANAGEMENT_1, 0x0 },119 { WM8996_POWER_MANAGEMENT_2, 0x0 },120 { WM8996_POWER_MANAGEMENT_3, 0x0 },121 { WM8996_POWER_MANAGEMENT_4, 0x0 },122 { WM8996_POWER_MANAGEMENT_5, 0x0 },123 { WM8996_POWER_MANAGEMENT_6, 0x0 },124 { WM8996_POWER_MANAGEMENT_7, 0x10 },125 { WM8996_POWER_MANAGEMENT_8, 0x0 },126 { WM8996_LEFT_LINE_INPUT_VOLUME, 0x0 },127 { WM8996_RIGHT_LINE_INPUT_VOLUME, 0x0 },128 { WM8996_LINE_INPUT_CONTROL, 0x0 },129 { WM8996_DAC1_HPOUT1_VOLUME, 0x88 },130 { WM8996_DAC2_HPOUT2_VOLUME, 0x88 },131 { WM8996_DAC1_LEFT_VOLUME, 0x2c0 },132 { WM8996_DAC1_RIGHT_VOLUME, 0x2c0 },133 { WM8996_DAC2_LEFT_VOLUME, 0x2c0 },134 { WM8996_DAC2_RIGHT_VOLUME, 0x2c0 },135 { WM8996_OUTPUT1_LEFT_VOLUME, 0x80 },136 { WM8996_OUTPUT1_RIGHT_VOLUME, 0x80 },137 { WM8996_OUTPUT2_LEFT_VOLUME, 0x80 },138 { WM8996_OUTPUT2_RIGHT_VOLUME, 0x80 },139 { WM8996_MICBIAS_1, 0x39 },140 { WM8996_MICBIAS_2, 0x39 },141 { WM8996_LDO_1, 0x3 },142 { WM8996_LDO_2, 0x13 },143 { WM8996_ACCESSORY_DETECT_MODE_1, 0x4 },144 { WM8996_ACCESSORY_DETECT_MODE_2, 0x0 },145 { WM8996_HEADPHONE_DETECT_1, 0x20 },146 { WM8996_HEADPHONE_DETECT_2, 0x0 },147 { WM8996_MIC_DETECT_1, 0x7600 },148 { WM8996_MIC_DETECT_2, 0xbf },149 { WM8996_CHARGE_PUMP_1, 0x1f25 },150 { WM8996_CHARGE_PUMP_2, 0xab19 },151 { WM8996_DC_SERVO_1, 0x0 },152 { WM8996_DC_SERVO_3, 0x0 },153 { WM8996_DC_SERVO_5, 0x2a2a },154 { WM8996_DC_SERVO_6, 0x0 },155 { WM8996_DC_SERVO_7, 0x0 },156 { WM8996_ANALOGUE_HP_1, 0x0 },157 { WM8996_ANALOGUE_HP_2, 0x0 },158 { WM8996_CONTROL_INTERFACE_1, 0x8004 },159 { WM8996_WRITE_SEQUENCER_CTRL_1, 0x0 },160 { WM8996_WRITE_SEQUENCER_CTRL_2, 0x0 },161 { WM8996_AIF_CLOCKING_1, 0x0 },162 { WM8996_AIF_CLOCKING_2, 0x0 },163 { WM8996_CLOCKING_1, 0x10 },164 { WM8996_CLOCKING_2, 0x0 },165 { WM8996_AIF_RATE, 0x83 },166 { WM8996_FLL_CONTROL_1, 0x0 },167 { WM8996_FLL_CONTROL_2, 0x0 },168 { WM8996_FLL_CONTROL_3, 0x0 },169 { WM8996_FLL_CONTROL_4, 0x5dc0 },170 { WM8996_FLL_CONTROL_5, 0xc84 },171 { WM8996_FLL_EFS_1, 0x0 },172 { WM8996_FLL_EFS_2, 0x2 },173 { WM8996_AIF1_CONTROL, 0x0 },174 { WM8996_AIF1_BCLK, 0x0 },175 { WM8996_AIF1_TX_LRCLK_1, 0x80 },176 { WM8996_AIF1_TX_LRCLK_2, 0x8 },177 { WM8996_AIF1_RX_LRCLK_1, 0x80 },178 { WM8996_AIF1_RX_LRCLK_2, 0x0 },179 { WM8996_AIF1TX_DATA_CONFIGURATION_1, 0x1818 },180 { WM8996_AIF1TX_DATA_CONFIGURATION_2, 0 },181 { WM8996_AIF1RX_DATA_CONFIGURATION, 0x1818 },182 { WM8996_AIF1TX_CHANNEL_0_CONFIGURATION, 0x0 },183 { WM8996_AIF1TX_CHANNEL_1_CONFIGURATION, 0x0 },184 { WM8996_AIF1TX_CHANNEL_2_CONFIGURATION, 0x0 },185 { WM8996_AIF1TX_CHANNEL_3_CONFIGURATION, 0x0 },186 { WM8996_AIF1TX_CHANNEL_4_CONFIGURATION, 0x0 },187 { WM8996_AIF1TX_CHANNEL_5_CONFIGURATION, 0x0 },188 { WM8996_AIF1RX_CHANNEL_0_CONFIGURATION, 0x0 },189 { WM8996_AIF1RX_CHANNEL_1_CONFIGURATION, 0x0 },190 { WM8996_AIF1RX_CHANNEL_2_CONFIGURATION, 0x0 },191 { WM8996_AIF1RX_CHANNEL_3_CONFIGURATION, 0x0 },192 { WM8996_AIF1RX_CHANNEL_4_CONFIGURATION, 0x0 },193 { WM8996_AIF1RX_CHANNEL_5_CONFIGURATION, 0x0 },194 { WM8996_AIF1RX_MONO_CONFIGURATION, 0x0 },195 { WM8996_AIF1TX_TEST, 0x7 },196 { WM8996_AIF2_CONTROL, 0x0 },197 { WM8996_AIF2_BCLK, 0x0 },198 { WM8996_AIF2_TX_LRCLK_1, 0x80 },199 { WM8996_AIF2_TX_LRCLK_2, 0x8 },200 { WM8996_AIF2_RX_LRCLK_1, 0x80 },201 { WM8996_AIF2_RX_LRCLK_2, 0x0 },202 { WM8996_AIF2TX_DATA_CONFIGURATION_1, 0x1818 },203 { WM8996_AIF2RX_DATA_CONFIGURATION, 0x1818 },204 { WM8996_AIF2RX_DATA_CONFIGURATION, 0x0 },205 { WM8996_AIF2TX_CHANNEL_0_CONFIGURATION, 0x0 },206 { WM8996_AIF2TX_CHANNEL_1_CONFIGURATION, 0x0 },207 { WM8996_AIF2RX_CHANNEL_0_CONFIGURATION, 0x0 },208 { WM8996_AIF2RX_CHANNEL_1_CONFIGURATION, 0x0 },209 { WM8996_AIF2RX_MONO_CONFIGURATION, 0x0 },210 { WM8996_AIF2TX_TEST, 0x1 },211 { WM8996_DSP1_TX_LEFT_VOLUME, 0xc0 },212 { WM8996_DSP1_TX_RIGHT_VOLUME, 0xc0 },213 { WM8996_DSP1_RX_LEFT_VOLUME, 0xc0 },214 { WM8996_DSP1_RX_RIGHT_VOLUME, 0xc0 },215 { WM8996_DSP1_TX_FILTERS, 0x2000 },216 { WM8996_DSP1_RX_FILTERS_1, 0x200 },217 { WM8996_DSP1_RX_FILTERS_2, 0x10 },218 { WM8996_DSP1_DRC_1, 0x98 },219 { WM8996_DSP1_DRC_2, 0x845 },220 { WM8996_DSP1_RX_EQ_GAINS_1, 0x6318 },221 { WM8996_DSP1_RX_EQ_GAINS_2, 0x6300 },222 { WM8996_DSP1_RX_EQ_BAND_1_A, 0xfca },223 { WM8996_DSP1_RX_EQ_BAND_1_B, 0x400 },224 { WM8996_DSP1_RX_EQ_BAND_1_PG, 0xd8 },225 { WM8996_DSP1_RX_EQ_BAND_2_A, 0x1eb5 },226 { WM8996_DSP1_RX_EQ_BAND_2_B, 0xf145 },227 { WM8996_DSP1_RX_EQ_BAND_2_C, 0xb75 },228 { WM8996_DSP1_RX_EQ_BAND_2_PG, 0x1c5 },229 { WM8996_DSP1_RX_EQ_BAND_3_A, 0x1c58 },230 { WM8996_DSP1_RX_EQ_BAND_3_B, 0xf373 },231 { WM8996_DSP1_RX_EQ_BAND_3_C, 0xa54 },232 { WM8996_DSP1_RX_EQ_BAND_3_PG, 0x558 },233 { WM8996_DSP1_RX_EQ_BAND_4_A, 0x168e },234 { WM8996_DSP1_RX_EQ_BAND_4_B, 0xf829 },235 { WM8996_DSP1_RX_EQ_BAND_4_C, 0x7ad },236 { WM8996_DSP1_RX_EQ_BAND_4_PG, 0x1103 },237 { WM8996_DSP1_RX_EQ_BAND_5_A, 0x564 },238 { WM8996_DSP1_RX_EQ_BAND_5_B, 0x559 },239 { WM8996_DSP1_RX_EQ_BAND_5_PG, 0x4000 },240 { WM8996_DSP2_TX_LEFT_VOLUME, 0xc0 },241 { WM8996_DSP2_TX_RIGHT_VOLUME, 0xc0 },242 { WM8996_DSP2_RX_LEFT_VOLUME, 0xc0 },243 { WM8996_DSP2_RX_RIGHT_VOLUME, 0xc0 },244 { WM8996_DSP2_TX_FILTERS, 0x2000 },245 { WM8996_DSP2_RX_FILTERS_1, 0x200 },246 { WM8996_DSP2_RX_FILTERS_2, 0x10 },247 { WM8996_DSP2_DRC_1, 0x98 },248 { WM8996_DSP2_DRC_2, 0x845 },249 { WM8996_DSP2_RX_EQ_GAINS_1, 0x6318 },250 { WM8996_DSP2_RX_EQ_GAINS_2, 0x6300 },251 { WM8996_DSP2_RX_EQ_BAND_1_A, 0xfca },252 { WM8996_DSP2_RX_EQ_BAND_1_B, 0x400 },253 { WM8996_DSP2_RX_EQ_BAND_1_PG, 0xd8 },254 { WM8996_DSP2_RX_EQ_BAND_2_A, 0x1eb5 },255 { WM8996_DSP2_RX_EQ_BAND_2_B, 0xf145 },256 { WM8996_DSP2_RX_EQ_BAND_2_C, 0xb75 },257 { WM8996_DSP2_RX_EQ_BAND_2_PG, 0x1c5 },258 { WM8996_DSP2_RX_EQ_BAND_3_A, 0x1c58 },259 { WM8996_DSP2_RX_EQ_BAND_3_B, 0xf373 },260 { WM8996_DSP2_RX_EQ_BAND_3_C, 0xa54 },261 { WM8996_DSP2_RX_EQ_BAND_3_PG, 0x558 },262 { WM8996_DSP2_RX_EQ_BAND_4_A, 0x168e },263 { WM8996_DSP2_RX_EQ_BAND_4_B, 0xf829 },264 { WM8996_DSP2_RX_EQ_BAND_4_C, 0x7ad },265 { WM8996_DSP2_RX_EQ_BAND_4_PG, 0x1103 },266 { WM8996_DSP2_RX_EQ_BAND_5_A, 0x564 },267 { WM8996_DSP2_RX_EQ_BAND_5_B, 0x559 },268 { WM8996_DSP2_RX_EQ_BAND_5_PG, 0x4000 },269 { WM8996_DAC1_MIXER_VOLUMES, 0x0 },270 { WM8996_DAC1_LEFT_MIXER_ROUTING, 0x0 },271 { WM8996_DAC1_RIGHT_MIXER_ROUTING, 0x0 },272 { WM8996_DAC2_MIXER_VOLUMES, 0x0 },273 { WM8996_DAC2_LEFT_MIXER_ROUTING, 0x0 },274 { WM8996_DAC2_RIGHT_MIXER_ROUTING, 0x0 },275 { WM8996_DSP1_TX_LEFT_MIXER_ROUTING, 0x0 },276 { WM8996_DSP1_TX_RIGHT_MIXER_ROUTING, 0x0 },277 { WM8996_DSP2_TX_LEFT_MIXER_ROUTING, 0x0 },278 { WM8996_DSP2_TX_RIGHT_MIXER_ROUTING, 0x0 },279 { WM8996_DSP_TX_MIXER_SELECT, 0x0 },280 { WM8996_DAC_SOFTMUTE, 0x0 },281 { WM8996_OVERSAMPLING, 0xd },282 { WM8996_SIDETONE, 0x1040 },283 { WM8996_GPIO_1, 0xa101 },284 { WM8996_GPIO_2, 0xa101 },285 { WM8996_GPIO_3, 0xa101 },286 { WM8996_GPIO_4, 0xa101 },287 { WM8996_GPIO_5, 0xa101 },288 { WM8996_PULL_CONTROL_1, 0x0 },289 { WM8996_PULL_CONTROL_2, 0x140 },290 { WM8996_INTERRUPT_STATUS_1_MASK, 0x1f },291 { WM8996_INTERRUPT_STATUS_2_MASK, 0x1ecf },292 { WM8996_LEFT_PDM_SPEAKER, 0x0 },293 { WM8996_RIGHT_PDM_SPEAKER, 0x1 },294 { WM8996_PDM_SPEAKER_MUTE_SEQUENCE, 0x69 },295 { WM8996_PDM_SPEAKER_VOLUME, 0x66 },296};297 298static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0);299static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0);300static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);301static const DECLARE_TLV_DB_SCALE(out_digital_tlv, -1200, 150, 0);302static const DECLARE_TLV_DB_SCALE(out_tlv, -900, 75, 0);303static const DECLARE_TLV_DB_SCALE(spk_tlv, -900, 150, 0);304static const DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);305static const DECLARE_TLV_DB_SCALE(threedstereo_tlv, -1600, 183, 1);306 307static const char *sidetone_hpf_text[] = {308 "2.9kHz", "1.5kHz", "735Hz", "403Hz", "196Hz", "98Hz", "49Hz"309};310 311static SOC_ENUM_SINGLE_DECL(sidetone_hpf,312 WM8996_SIDETONE, 7, sidetone_hpf_text);313 314static const char *hpf_mode_text[] = {315 "HiFi", "Custom", "Voice"316};317 318static SOC_ENUM_SINGLE_DECL(dsp1tx_hpf_mode,319 WM8996_DSP1_TX_FILTERS, 3, hpf_mode_text);320 321static SOC_ENUM_SINGLE_DECL(dsp2tx_hpf_mode,322 WM8996_DSP2_TX_FILTERS, 3, hpf_mode_text);323 324static const char *hpf_cutoff_text[] = {325 "50Hz", "75Hz", "100Hz", "150Hz", "200Hz", "300Hz", "400Hz"326};327 328static SOC_ENUM_SINGLE_DECL(dsp1tx_hpf_cutoff,329 WM8996_DSP1_TX_FILTERS, 0, hpf_cutoff_text);330 331static SOC_ENUM_SINGLE_DECL(dsp2tx_hpf_cutoff,332 WM8996_DSP2_TX_FILTERS, 0, hpf_cutoff_text);333 334static void wm8996_set_retune_mobile(struct snd_soc_component *component, int block)335{336 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);337 struct wm8996_pdata *pdata = &wm8996->pdata;338 int base, best, best_val, save, i, cfg, iface;339 340 if (!wm8996->num_retune_mobile_texts)341 return;342 343 switch (block) {344 case 0:345 base = WM8996_DSP1_RX_EQ_GAINS_1;346 if (snd_soc_component_read(component, WM8996_POWER_MANAGEMENT_8) &347 WM8996_DSP1RX_SRC)348 iface = 1;349 else350 iface = 0;351 break;352 case 1:353 base = WM8996_DSP1_RX_EQ_GAINS_2;354 if (snd_soc_component_read(component, WM8996_POWER_MANAGEMENT_8) &355 WM8996_DSP2RX_SRC)356 iface = 1;357 else358 iface = 0;359 break;360 default:361 return;362 }363 364 /* Find the version of the currently selected configuration365 * with the nearest sample rate. */366 cfg = wm8996->retune_mobile_cfg[block];367 best = 0;368 best_val = INT_MAX;369 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {370 if (strcmp(pdata->retune_mobile_cfgs[i].name,371 wm8996->retune_mobile_texts[cfg]) == 0 &&372 abs(pdata->retune_mobile_cfgs[i].rate373 - wm8996->rx_rate[iface]) < best_val) {374 best = i;375 best_val = abs(pdata->retune_mobile_cfgs[i].rate376 - wm8996->rx_rate[iface]);377 }378 }379 380 dev_dbg(component->dev, "ReTune Mobile %d %s/%dHz for %dHz sample rate\n",381 block,382 pdata->retune_mobile_cfgs[best].name,383 pdata->retune_mobile_cfgs[best].rate,384 wm8996->rx_rate[iface]);385 386 /* The EQ will be disabled while reconfiguring it, remember the387 * current configuration. 388 */389 save = snd_soc_component_read(component, base);390 save &= WM8996_DSP1RX_EQ_ENA;391 392 for (i = 0; i < ARRAY_SIZE(pdata->retune_mobile_cfgs[best].regs); i++)393 snd_soc_component_update_bits(component, base + i, 0xffff,394 pdata->retune_mobile_cfgs[best].regs[i]);395 396 snd_soc_component_update_bits(component, base, WM8996_DSP1RX_EQ_ENA, save);397}398 399/* Icky as hell but saves code duplication */400static int wm8996_get_retune_mobile_block(const char *name)401{402 if (strcmp(name, "DSP1 EQ Mode") == 0)403 return 0;404 if (strcmp(name, "DSP2 EQ Mode") == 0)405 return 1;406 return -EINVAL;407}408 409static int wm8996_put_retune_mobile_enum(struct snd_kcontrol *kcontrol,410 struct snd_ctl_elem_value *ucontrol)411{412 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);413 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);414 struct wm8996_pdata *pdata = &wm8996->pdata;415 int block = wm8996_get_retune_mobile_block(kcontrol->id.name);416 int value = ucontrol->value.enumerated.item[0];417 418 if (block < 0)419 return block;420 421 if (value >= pdata->num_retune_mobile_cfgs)422 return -EINVAL;423 424 wm8996->retune_mobile_cfg[block] = value;425 426 wm8996_set_retune_mobile(component, block);427 428 return 0;429}430 431static int wm8996_get_retune_mobile_enum(struct snd_kcontrol *kcontrol,432 struct snd_ctl_elem_value *ucontrol)433{434 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);435 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);436 int block = wm8996_get_retune_mobile_block(kcontrol->id.name);437 438 if (block < 0)439 return block;440 ucontrol->value.enumerated.item[0] = wm8996->retune_mobile_cfg[block];441 442 return 0;443}444 445static const struct snd_kcontrol_new wm8996_snd_controls[] = {446SOC_DOUBLE_R_TLV("Capture Volume", WM8996_LEFT_LINE_INPUT_VOLUME,447 WM8996_RIGHT_LINE_INPUT_VOLUME, 0, 31, 0, inpga_tlv),448SOC_DOUBLE_R("Capture ZC Switch", WM8996_LEFT_LINE_INPUT_VOLUME,449 WM8996_RIGHT_LINE_INPUT_VOLUME, 5, 1, 0),450 451SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8996_DAC1_MIXER_VOLUMES,452 0, 5, 24, 0, sidetone_tlv),453SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8996_DAC2_MIXER_VOLUMES,454 0, 5, 24, 0, sidetone_tlv),455SOC_SINGLE("Sidetone LPF Switch", WM8996_SIDETONE, 12, 1, 0),456SOC_ENUM("Sidetone HPF Cut-off", sidetone_hpf),457SOC_SINGLE("Sidetone HPF Switch", WM8996_SIDETONE, 6, 1, 0),458 459SOC_DOUBLE_R_TLV("DSP1 Capture Volume", WM8996_DSP1_TX_LEFT_VOLUME,460 WM8996_DSP1_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),461SOC_DOUBLE_R_TLV("DSP2 Capture Volume", WM8996_DSP2_TX_LEFT_VOLUME,462 WM8996_DSP2_TX_RIGHT_VOLUME, 1, 96, 0, digital_tlv),463 464SOC_SINGLE("DSP1 Capture Notch Filter Switch", WM8996_DSP1_TX_FILTERS,465 13, 1, 0),466SOC_DOUBLE("DSP1 Capture HPF Switch", WM8996_DSP1_TX_FILTERS, 12, 11, 1, 0),467SOC_ENUM("DSP1 Capture HPF Mode", dsp1tx_hpf_mode),468SOC_ENUM("DSP1 Capture HPF Cutoff", dsp1tx_hpf_cutoff),469 470SOC_SINGLE("DSP2 Capture Notch Filter Switch", WM8996_DSP2_TX_FILTERS,471 13, 1, 0),472SOC_DOUBLE("DSP2 Capture HPF Switch", WM8996_DSP2_TX_FILTERS, 12, 11, 1, 0),473SOC_ENUM("DSP2 Capture HPF Mode", dsp2tx_hpf_mode),474SOC_ENUM("DSP2 Capture HPF Cutoff", dsp2tx_hpf_cutoff),475 476SOC_DOUBLE_R_TLV("DSP1 Playback Volume", WM8996_DSP1_RX_LEFT_VOLUME,477 WM8996_DSP1_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),478SOC_SINGLE("DSP1 Playback Switch", WM8996_DSP1_RX_FILTERS_1, 9, 1, 1),479 480SOC_DOUBLE_R_TLV("DSP2 Playback Volume", WM8996_DSP2_RX_LEFT_VOLUME,481 WM8996_DSP2_RX_RIGHT_VOLUME, 1, 112, 0, digital_tlv),482SOC_SINGLE("DSP2 Playback Switch", WM8996_DSP2_RX_FILTERS_1, 9, 1, 1),483 484SOC_DOUBLE_R_TLV("DAC1 Volume", WM8996_DAC1_LEFT_VOLUME,485 WM8996_DAC1_RIGHT_VOLUME, 1, 112, 0, digital_tlv),486SOC_DOUBLE_R("DAC1 Switch", WM8996_DAC1_LEFT_VOLUME,487 WM8996_DAC1_RIGHT_VOLUME, 9, 1, 1),488 489SOC_DOUBLE_R_TLV("DAC2 Volume", WM8996_DAC2_LEFT_VOLUME,490 WM8996_DAC2_RIGHT_VOLUME, 1, 112, 0, digital_tlv),491SOC_DOUBLE_R("DAC2 Switch", WM8996_DAC2_LEFT_VOLUME,492 WM8996_DAC2_RIGHT_VOLUME, 9, 1, 1),493 494SOC_SINGLE("Speaker High Performance Switch", WM8996_OVERSAMPLING, 3, 1, 0),495SOC_SINGLE("DMIC High Performance Switch", WM8996_OVERSAMPLING, 2, 1, 0),496SOC_SINGLE("ADC High Performance Switch", WM8996_OVERSAMPLING, 1, 1, 0),497SOC_SINGLE("DAC High Performance Switch", WM8996_OVERSAMPLING, 0, 1, 0),498 499SOC_SINGLE("DAC Soft Mute Switch", WM8996_DAC_SOFTMUTE, 1, 1, 0),500SOC_SINGLE("DAC Slow Soft Mute Switch", WM8996_DAC_SOFTMUTE, 0, 1, 0),501 502SOC_SINGLE("DSP1 3D Stereo Switch", WM8996_DSP1_RX_FILTERS_2, 8, 1, 0),503SOC_SINGLE("DSP2 3D Stereo Switch", WM8996_DSP2_RX_FILTERS_2, 8, 1, 0),504 505SOC_SINGLE_TLV("DSP1 3D Stereo Volume", WM8996_DSP1_RX_FILTERS_2, 10, 15,506 0, threedstereo_tlv),507SOC_SINGLE_TLV("DSP2 3D Stereo Volume", WM8996_DSP2_RX_FILTERS_2, 10, 15,508 0, threedstereo_tlv),509 510SOC_DOUBLE_TLV("Digital Output 1 Volume", WM8996_DAC1_HPOUT1_VOLUME, 0, 4,511 8, 0, out_digital_tlv),512SOC_DOUBLE_TLV("Digital Output 2 Volume", WM8996_DAC2_HPOUT2_VOLUME, 0, 4,513 8, 0, out_digital_tlv),514 515SOC_DOUBLE_R_TLV("Output 1 Volume", WM8996_OUTPUT1_LEFT_VOLUME,516 WM8996_OUTPUT1_RIGHT_VOLUME, 0, 12, 0, out_tlv),517SOC_DOUBLE_R("Output 1 ZC Switch", WM8996_OUTPUT1_LEFT_VOLUME,518 WM8996_OUTPUT1_RIGHT_VOLUME, 7, 1, 0),519 520SOC_DOUBLE_R_TLV("Output 2 Volume", WM8996_OUTPUT2_LEFT_VOLUME,521 WM8996_OUTPUT2_RIGHT_VOLUME, 0, 12, 0, out_tlv),522SOC_DOUBLE_R("Output 2 ZC Switch", WM8996_OUTPUT2_LEFT_VOLUME,523 WM8996_OUTPUT2_RIGHT_VOLUME, 7, 1, 0),524 525SOC_DOUBLE_TLV("Speaker Volume", WM8996_PDM_SPEAKER_VOLUME, 0, 4, 8, 0,526 spk_tlv),527SOC_DOUBLE_R("Speaker Switch", WM8996_LEFT_PDM_SPEAKER,528 WM8996_RIGHT_PDM_SPEAKER, 3, 1, 1),529SOC_DOUBLE_R("Speaker ZC Switch", WM8996_LEFT_PDM_SPEAKER,530 WM8996_RIGHT_PDM_SPEAKER, 2, 1, 0),531 532SOC_SINGLE("DSP1 EQ Switch", WM8996_DSP1_RX_EQ_GAINS_1, 0, 1, 0),533SOC_SINGLE("DSP2 EQ Switch", WM8996_DSP2_RX_EQ_GAINS_1, 0, 1, 0),534 535SOC_SINGLE("DSP1 DRC TXL Switch", WM8996_DSP1_DRC_1, 0, 1, 0),536SOC_SINGLE("DSP1 DRC TXR Switch", WM8996_DSP1_DRC_1, 1, 1, 0),537SOC_SINGLE("DSP1 DRC RX Switch", WM8996_DSP1_DRC_1, 2, 1, 0),538SND_SOC_BYTES_MASK("DSP1 DRC", WM8996_DSP1_DRC_1, 5,539 WM8996_DSP1RX_DRC_ENA | WM8996_DSP1TXL_DRC_ENA |540 WM8996_DSP1TXR_DRC_ENA),541 542SOC_SINGLE("DSP2 DRC TXL Switch", WM8996_DSP2_DRC_1, 0, 1, 0),543SOC_SINGLE("DSP2 DRC TXR Switch", WM8996_DSP2_DRC_1, 1, 1, 0),544SOC_SINGLE("DSP2 DRC RX Switch", WM8996_DSP2_DRC_1, 2, 1, 0),545SND_SOC_BYTES_MASK("DSP2 DRC", WM8996_DSP2_DRC_1, 5,546 WM8996_DSP2RX_DRC_ENA | WM8996_DSP2TXL_DRC_ENA |547 WM8996_DSP2TXR_DRC_ENA),548};549 550static const struct snd_kcontrol_new wm8996_eq_controls[] = {551SOC_SINGLE_TLV("DSP1 EQ B1 Volume", WM8996_DSP1_RX_EQ_GAINS_1, 11, 31, 0,552 eq_tlv),553SOC_SINGLE_TLV("DSP1 EQ B2 Volume", WM8996_DSP1_RX_EQ_GAINS_1, 6, 31, 0,554 eq_tlv),555SOC_SINGLE_TLV("DSP1 EQ B3 Volume", WM8996_DSP1_RX_EQ_GAINS_1, 1, 31, 0,556 eq_tlv),557SOC_SINGLE_TLV("DSP1 EQ B4 Volume", WM8996_DSP1_RX_EQ_GAINS_2, 11, 31, 0,558 eq_tlv),559SOC_SINGLE_TLV("DSP1 EQ B5 Volume", WM8996_DSP1_RX_EQ_GAINS_2, 6, 31, 0,560 eq_tlv),561 562SOC_SINGLE_TLV("DSP2 EQ B1 Volume", WM8996_DSP2_RX_EQ_GAINS_1, 11, 31, 0,563 eq_tlv),564SOC_SINGLE_TLV("DSP2 EQ B2 Volume", WM8996_DSP2_RX_EQ_GAINS_1, 6, 31, 0,565 eq_tlv),566SOC_SINGLE_TLV("DSP2 EQ B3 Volume", WM8996_DSP2_RX_EQ_GAINS_1, 1, 31, 0,567 eq_tlv),568SOC_SINGLE_TLV("DSP2 EQ B4 Volume", WM8996_DSP2_RX_EQ_GAINS_2, 11, 31, 0,569 eq_tlv),570SOC_SINGLE_TLV("DSP2 EQ B5 Volume", WM8996_DSP2_RX_EQ_GAINS_2, 6, 31, 0,571 eq_tlv),572};573 574static void wm8996_bg_enable(struct snd_soc_component *component)575{576 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);577 578 wm8996->bg_ena++;579 if (wm8996->bg_ena == 1) {580 snd_soc_component_update_bits(component, WM8996_POWER_MANAGEMENT_1,581 WM8996_BG_ENA, WM8996_BG_ENA);582 msleep(2);583 }584}585 586static void wm8996_bg_disable(struct snd_soc_component *component)587{588 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);589 590 wm8996->bg_ena--;591 if (!wm8996->bg_ena)592 snd_soc_component_update_bits(component, WM8996_POWER_MANAGEMENT_1,593 WM8996_BG_ENA, 0);594}595 596static int bg_event(struct snd_soc_dapm_widget *w,597 struct snd_kcontrol *kcontrol, int event)598{599 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);600 int ret = 0;601 602 switch (event) {603 case SND_SOC_DAPM_PRE_PMU:604 wm8996_bg_enable(component);605 break;606 case SND_SOC_DAPM_POST_PMD:607 wm8996_bg_disable(component);608 break;609 default:610 WARN(1, "Invalid event %d\n", event);611 ret = -EINVAL;612 }613 614 return ret;615}616 617static int cp_event(struct snd_soc_dapm_widget *w,618 struct snd_kcontrol *kcontrol, int event)619{620 switch (event) {621 case SND_SOC_DAPM_POST_PMU:622 msleep(5);623 break;624 default:625 WARN(1, "Invalid event %d\n", event);626 }627 628 return 0;629}630 631static int rmv_short_event(struct snd_soc_dapm_widget *w,632 struct snd_kcontrol *kcontrol, int event)633{634 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);635 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);636 637 /* Record which outputs we enabled */638 switch (event) {639 case SND_SOC_DAPM_PRE_PMD:640 wm8996->hpout_pending &= ~w->shift;641 break;642 case SND_SOC_DAPM_PRE_PMU:643 wm8996->hpout_pending |= w->shift;644 break;645 default:646 WARN(1, "Invalid event %d\n", event);647 return -EINVAL;648 }649 650 return 0;651}652 653static void wait_for_dc_servo(struct snd_soc_component *component, u16 mask)654{655 struct i2c_client *i2c = to_i2c_client(component->dev);656 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);657 int ret;658 unsigned long time_left = 200;659 660 snd_soc_component_write(component, WM8996_DC_SERVO_2, mask);661 662 /* Use the interrupt if possible */663 do {664 if (i2c->irq) {665 time_left = wait_for_completion_timeout(&wm8996->dcs_done,666 msecs_to_jiffies(200));667 if (time_left == 0)668 dev_err(component->dev, "DC servo timed out\n");669 670 } else {671 msleep(1);672 time_left--;673 }674 675 ret = snd_soc_component_read(component, WM8996_DC_SERVO_2);676 dev_dbg(component->dev, "DC servo state: %x\n", ret);677 } while (time_left && ret & mask);678 679 if (time_left == 0)680 dev_err(component->dev, "DC servo timed out for %x\n", mask);681 else682 dev_dbg(component->dev, "DC servo complete for %x\n", mask);683}684 685static void wm8996_seq_notifier(struct snd_soc_component *component,686 enum snd_soc_dapm_type event, int subseq)687{688 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);689 u16 val, mask;690 691 /* Complete any pending DC servo starts */692 if (wm8996->dcs_pending) {693 dev_dbg(component->dev, "Starting DC servo for %x\n",694 wm8996->dcs_pending);695 696 /* Trigger a startup sequence */697 wait_for_dc_servo(component, wm8996->dcs_pending698 << WM8996_DCS_TRIG_STARTUP_0_SHIFT);699 700 wm8996->dcs_pending = 0;701 }702 703 if (wm8996->hpout_pending != wm8996->hpout_ena) {704 dev_dbg(component->dev, "Applying RMV_SHORTs %x->%x\n",705 wm8996->hpout_ena, wm8996->hpout_pending);706 707 val = 0;708 mask = 0;709 if (wm8996->hpout_pending & HPOUT1L) {710 val |= WM8996_HPOUT1L_RMV_SHORT | WM8996_HPOUT1L_OUTP;711 mask |= WM8996_HPOUT1L_RMV_SHORT | WM8996_HPOUT1L_OUTP;712 } else {713 mask |= WM8996_HPOUT1L_RMV_SHORT |714 WM8996_HPOUT1L_OUTP |715 WM8996_HPOUT1L_DLY;716 }717 718 if (wm8996->hpout_pending & HPOUT1R) {719 val |= WM8996_HPOUT1R_RMV_SHORT | WM8996_HPOUT1R_OUTP;720 mask |= WM8996_HPOUT1R_RMV_SHORT | WM8996_HPOUT1R_OUTP;721 } else {722 mask |= WM8996_HPOUT1R_RMV_SHORT |723 WM8996_HPOUT1R_OUTP |724 WM8996_HPOUT1R_DLY;725 }726 727 snd_soc_component_update_bits(component, WM8996_ANALOGUE_HP_1, mask, val);728 729 val = 0;730 mask = 0;731 if (wm8996->hpout_pending & HPOUT2L) {732 val |= WM8996_HPOUT2L_RMV_SHORT | WM8996_HPOUT2L_OUTP;733 mask |= WM8996_HPOUT2L_RMV_SHORT | WM8996_HPOUT2L_OUTP;734 } else {735 mask |= WM8996_HPOUT2L_RMV_SHORT |736 WM8996_HPOUT2L_OUTP |737 WM8996_HPOUT2L_DLY;738 }739 740 if (wm8996->hpout_pending & HPOUT2R) {741 val |= WM8996_HPOUT2R_RMV_SHORT | WM8996_HPOUT2R_OUTP;742 mask |= WM8996_HPOUT2R_RMV_SHORT | WM8996_HPOUT2R_OUTP;743 } else {744 mask |= WM8996_HPOUT2R_RMV_SHORT |745 WM8996_HPOUT2R_OUTP |746 WM8996_HPOUT2R_DLY;747 }748 749 snd_soc_component_update_bits(component, WM8996_ANALOGUE_HP_2, mask, val);750 751 wm8996->hpout_ena = wm8996->hpout_pending;752 }753}754 755static int dcs_start(struct snd_soc_dapm_widget *w,756 struct snd_kcontrol *kcontrol, int event)757{758 struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);759 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);760 761 switch (event) {762 case SND_SOC_DAPM_POST_PMU:763 wm8996->dcs_pending |= 1 << w->shift;764 break;765 default:766 WARN(1, "Invalid event %d\n", event);767 return -EINVAL;768 }769 770 return 0;771}772 773static const char *sidetone_text[] = {774 "IN1", "IN2",775};776 777static SOC_ENUM_SINGLE_DECL(left_sidetone_enum,778 WM8996_SIDETONE, 0, sidetone_text);779 780static const struct snd_kcontrol_new left_sidetone =781 SOC_DAPM_ENUM("Left Sidetone", left_sidetone_enum);782 783static SOC_ENUM_SINGLE_DECL(right_sidetone_enum,784 WM8996_SIDETONE, 1, sidetone_text);785 786static const struct snd_kcontrol_new right_sidetone =787 SOC_DAPM_ENUM("Right Sidetone", right_sidetone_enum);788 789static const char *spk_text[] = {790 "DAC1L", "DAC1R", "DAC2L", "DAC2R"791};792 793static SOC_ENUM_SINGLE_DECL(spkl_enum,794 WM8996_LEFT_PDM_SPEAKER, 0, spk_text);795 796static const struct snd_kcontrol_new spkl_mux =797 SOC_DAPM_ENUM("SPKL", spkl_enum);798 799static SOC_ENUM_SINGLE_DECL(spkr_enum,800 WM8996_RIGHT_PDM_SPEAKER, 0, spk_text);801 802static const struct snd_kcontrol_new spkr_mux =803 SOC_DAPM_ENUM("SPKR", spkr_enum);804 805static const char *dsp1rx_text[] = {806 "AIF1", "AIF2"807};808 809static SOC_ENUM_SINGLE_DECL(dsp1rx_enum,810 WM8996_POWER_MANAGEMENT_8, 0, dsp1rx_text);811 812static const struct snd_kcontrol_new dsp1rx =813 SOC_DAPM_ENUM("DSP1RX", dsp1rx_enum);814 815static const char *dsp2rx_text[] = {816 "AIF2", "AIF1"817};818 819static SOC_ENUM_SINGLE_DECL(dsp2rx_enum,820 WM8996_POWER_MANAGEMENT_8, 4, dsp2rx_text);821 822static const struct snd_kcontrol_new dsp2rx =823 SOC_DAPM_ENUM("DSP2RX", dsp2rx_enum);824 825static const char *aif2tx_text[] = {826 "DSP2", "DSP1", "AIF1"827};828 829static SOC_ENUM_SINGLE_DECL(aif2tx_enum,830 WM8996_POWER_MANAGEMENT_8, 6, aif2tx_text);831 832static const struct snd_kcontrol_new aif2tx =833 SOC_DAPM_ENUM("AIF2TX", aif2tx_enum);834 835static const char *inmux_text[] = {836 "ADC", "DMIC1", "DMIC2"837};838 839static SOC_ENUM_SINGLE_DECL(in1_enum,840 WM8996_POWER_MANAGEMENT_7, 0, inmux_text);841 842static const struct snd_kcontrol_new in1_mux =843 SOC_DAPM_ENUM("IN1 Mux", in1_enum);844 845static SOC_ENUM_SINGLE_DECL(in2_enum,846 WM8996_POWER_MANAGEMENT_7, 4, inmux_text);847 848static const struct snd_kcontrol_new in2_mux =849 SOC_DAPM_ENUM("IN2 Mux", in2_enum);850 851static const struct snd_kcontrol_new dac2r_mix[] = {852SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING,853 5, 1, 0),854SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING,855 4, 1, 0),856SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING, 1, 1, 0),857SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC2_RIGHT_MIXER_ROUTING, 0, 1, 0),858};859 860static const struct snd_kcontrol_new dac2l_mix[] = {861SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC2_LEFT_MIXER_ROUTING,862 5, 1, 0),863SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC2_LEFT_MIXER_ROUTING,864 4, 1, 0),865SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC2_LEFT_MIXER_ROUTING, 1, 1, 0),866SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC2_LEFT_MIXER_ROUTING, 0, 1, 0),867};868 869static const struct snd_kcontrol_new dac1r_mix[] = {870SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING,871 5, 1, 0),872SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING,873 4, 1, 0),874SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING, 1, 1, 0),875SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC1_RIGHT_MIXER_ROUTING, 0, 1, 0),876};877 878static const struct snd_kcontrol_new dac1l_mix[] = {879SOC_DAPM_SINGLE("Right Sidetone Switch", WM8996_DAC1_LEFT_MIXER_ROUTING,880 5, 1, 0),881SOC_DAPM_SINGLE("Left Sidetone Switch", WM8996_DAC1_LEFT_MIXER_ROUTING,882 4, 1, 0),883SOC_DAPM_SINGLE("DSP2 Switch", WM8996_DAC1_LEFT_MIXER_ROUTING, 1, 1, 0),884SOC_DAPM_SINGLE("DSP1 Switch", WM8996_DAC1_LEFT_MIXER_ROUTING, 0, 1, 0),885};886 887static const struct snd_kcontrol_new dsp1txl[] = {888SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP1_TX_LEFT_MIXER_ROUTING,889 1, 1, 0),890SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP1_TX_LEFT_MIXER_ROUTING,891 0, 1, 0),892};893 894static const struct snd_kcontrol_new dsp1txr[] = {895SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP1_TX_RIGHT_MIXER_ROUTING,896 1, 1, 0),897SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP1_TX_RIGHT_MIXER_ROUTING,898 0, 1, 0),899};900 901static const struct snd_kcontrol_new dsp2txl[] = {902SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP2_TX_LEFT_MIXER_ROUTING,903 1, 1, 0),904SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP2_TX_LEFT_MIXER_ROUTING,905 0, 1, 0),906};907 908static const struct snd_kcontrol_new dsp2txr[] = {909SOC_DAPM_SINGLE("IN1 Switch", WM8996_DSP2_TX_RIGHT_MIXER_ROUTING,910 1, 1, 0),911SOC_DAPM_SINGLE("DAC Switch", WM8996_DSP2_TX_RIGHT_MIXER_ROUTING,912 0, 1, 0),913};914 915 916static const struct snd_soc_dapm_widget wm8996_dapm_widgets[] = {917SND_SOC_DAPM_INPUT("IN1LN"),918SND_SOC_DAPM_INPUT("IN1LP"),919SND_SOC_DAPM_INPUT("IN1RN"),920SND_SOC_DAPM_INPUT("IN1RP"),921 922SND_SOC_DAPM_INPUT("IN2LN"),923SND_SOC_DAPM_INPUT("IN2LP"),924SND_SOC_DAPM_INPUT("IN2RN"),925SND_SOC_DAPM_INPUT("IN2RP"),926 927SND_SOC_DAPM_INPUT("DMIC1DAT"),928SND_SOC_DAPM_INPUT("DMIC2DAT"),929 930SND_SOC_DAPM_REGULATOR_SUPPLY("CPVDD", 20, 0),931SND_SOC_DAPM_SUPPLY_S("SYSCLK", 1, WM8996_AIF_CLOCKING_1, 0, 0, NULL, 0),932SND_SOC_DAPM_SUPPLY_S("SYSDSPCLK", 2, WM8996_CLOCKING_1, 1, 0, NULL, 0),933SND_SOC_DAPM_SUPPLY_S("AIFCLK", 2, WM8996_CLOCKING_1, 2, 0, NULL, 0),934SND_SOC_DAPM_SUPPLY_S("Charge Pump", 2, WM8996_CHARGE_PUMP_1, 15, 0, cp_event,935 SND_SOC_DAPM_POST_PMU),936SND_SOC_DAPM_SUPPLY("Bandgap", SND_SOC_NOPM, 0, 0, bg_event,937 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),938SND_SOC_DAPM_SUPPLY("LDO2", WM8996_POWER_MANAGEMENT_2, 1, 0, NULL, 0),939SND_SOC_DAPM_SUPPLY("MICB1 Audio", WM8996_MICBIAS_1, 4, 1, NULL, 0),940SND_SOC_DAPM_SUPPLY("MICB2 Audio", WM8996_MICBIAS_2, 4, 1, NULL, 0),941SND_SOC_DAPM_MICBIAS("MICB2", WM8996_POWER_MANAGEMENT_1, 9, 0),942SND_SOC_DAPM_MICBIAS("MICB1", WM8996_POWER_MANAGEMENT_1, 8, 0),943 944SND_SOC_DAPM_PGA("IN1L PGA", WM8996_POWER_MANAGEMENT_2, 5, 0, NULL, 0),945SND_SOC_DAPM_PGA("IN1R PGA", WM8996_POWER_MANAGEMENT_2, 4, 0, NULL, 0),946 947SND_SOC_DAPM_MUX("IN1L Mux", WM8996_POWER_MANAGEMENT_7, 2, 0, &in1_mux),948SND_SOC_DAPM_MUX("IN1R Mux", WM8996_POWER_MANAGEMENT_7, 3, 0, &in1_mux),949SND_SOC_DAPM_MUX("IN2L Mux", WM8996_POWER_MANAGEMENT_7, 6, 0, &in2_mux),950SND_SOC_DAPM_MUX("IN2R Mux", WM8996_POWER_MANAGEMENT_7, 7, 0, &in2_mux),951 952SND_SOC_DAPM_SUPPLY("DMIC2", WM8996_POWER_MANAGEMENT_7, 9, 0, NULL, 0),953SND_SOC_DAPM_SUPPLY("DMIC1", WM8996_POWER_MANAGEMENT_7, 8, 0, NULL, 0),954 955SND_SOC_DAPM_ADC("DMIC2L", NULL, WM8996_POWER_MANAGEMENT_3, 5, 0),956SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8996_POWER_MANAGEMENT_3, 4, 0),957SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8996_POWER_MANAGEMENT_3, 3, 0),958SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8996_POWER_MANAGEMENT_3, 2, 0),959 960SND_SOC_DAPM_ADC("ADCL", NULL, WM8996_POWER_MANAGEMENT_3, 1, 0),961SND_SOC_DAPM_ADC("ADCR", NULL, WM8996_POWER_MANAGEMENT_3, 0, 0),962 963SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &left_sidetone),964SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &right_sidetone),965 966SND_SOC_DAPM_AIF_IN("DSP2RXL", NULL, 0, WM8996_POWER_MANAGEMENT_3, 11, 0),967SND_SOC_DAPM_AIF_IN("DSP2RXR", NULL, 1, WM8996_POWER_MANAGEMENT_3, 10, 0),968SND_SOC_DAPM_AIF_IN("DSP1RXL", NULL, 0, WM8996_POWER_MANAGEMENT_3, 9, 0),969SND_SOC_DAPM_AIF_IN("DSP1RXR", NULL, 1, WM8996_POWER_MANAGEMENT_3, 8, 0),970 971SND_SOC_DAPM_MIXER("DSP2TXL", WM8996_POWER_MANAGEMENT_5, 11, 0,972 dsp2txl, ARRAY_SIZE(dsp2txl)),973SND_SOC_DAPM_MIXER("DSP2TXR", WM8996_POWER_MANAGEMENT_5, 10, 0,974 dsp2txr, ARRAY_SIZE(dsp2txr)),975SND_SOC_DAPM_MIXER("DSP1TXL", WM8996_POWER_MANAGEMENT_5, 9, 0,976 dsp1txl, ARRAY_SIZE(dsp1txl)),977SND_SOC_DAPM_MIXER("DSP1TXR", WM8996_POWER_MANAGEMENT_5, 8, 0,978 dsp1txr, ARRAY_SIZE(dsp1txr)),979 980SND_SOC_DAPM_MIXER("DAC2L Mixer", SND_SOC_NOPM, 0, 0,981 dac2l_mix, ARRAY_SIZE(dac2l_mix)),982SND_SOC_DAPM_MIXER("DAC2R Mixer", SND_SOC_NOPM, 0, 0,983 dac2r_mix, ARRAY_SIZE(dac2r_mix)),984SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0,985 dac1l_mix, ARRAY_SIZE(dac1l_mix)),986SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0,987 dac1r_mix, ARRAY_SIZE(dac1r_mix)),988 989SND_SOC_DAPM_DAC("DAC2L", NULL, WM8996_POWER_MANAGEMENT_5, 3, 0),990SND_SOC_DAPM_DAC("DAC2R", NULL, WM8996_POWER_MANAGEMENT_5, 2, 0),991SND_SOC_DAPM_DAC("DAC1L", NULL, WM8996_POWER_MANAGEMENT_5, 1, 0),992SND_SOC_DAPM_DAC("DAC1R", NULL, WM8996_POWER_MANAGEMENT_5, 0, 0),993 994SND_SOC_DAPM_AIF_IN("AIF2RX1", NULL, 0, WM8996_POWER_MANAGEMENT_4, 9, 0),995SND_SOC_DAPM_AIF_IN("AIF2RX0", NULL, 1, WM8996_POWER_MANAGEMENT_4, 8, 0),996 997SND_SOC_DAPM_AIF_OUT("AIF2TX1", NULL, 0, WM8996_POWER_MANAGEMENT_6, 9, 0),998SND_SOC_DAPM_AIF_OUT("AIF2TX0", NULL, 1, WM8996_POWER_MANAGEMENT_6, 8, 0),999 1000SND_SOC_DAPM_AIF_IN("AIF1RX5", NULL, 5, WM8996_POWER_MANAGEMENT_4, 5, 0),1001SND_SOC_DAPM_AIF_IN("AIF1RX4", NULL, 4, WM8996_POWER_MANAGEMENT_4, 4, 0),1002SND_SOC_DAPM_AIF_IN("AIF1RX3", NULL, 3, WM8996_POWER_MANAGEMENT_4, 3, 0),1003SND_SOC_DAPM_AIF_IN("AIF1RX2", NULL, 2, WM8996_POWER_MANAGEMENT_4, 2, 0),1004SND_SOC_DAPM_AIF_IN("AIF1RX1", NULL, 1, WM8996_POWER_MANAGEMENT_4, 1, 0),1005SND_SOC_DAPM_AIF_IN("AIF1RX0", NULL, 0, WM8996_POWER_MANAGEMENT_4, 0, 0),1006 1007SND_SOC_DAPM_AIF_OUT("AIF1TX5", NULL, 5, WM8996_POWER_MANAGEMENT_6, 5, 0),1008SND_SOC_DAPM_AIF_OUT("AIF1TX4", NULL, 4, WM8996_POWER_MANAGEMENT_6, 4, 0),1009SND_SOC_DAPM_AIF_OUT("AIF1TX3", NULL, 3, WM8996_POWER_MANAGEMENT_6, 3, 0),1010SND_SOC_DAPM_AIF_OUT("AIF1TX2", NULL, 2, WM8996_POWER_MANAGEMENT_6, 2, 0),1011SND_SOC_DAPM_AIF_OUT("AIF1TX1", NULL, 1, WM8996_POWER_MANAGEMENT_6, 1, 0),1012SND_SOC_DAPM_AIF_OUT("AIF1TX0", NULL, 0, WM8996_POWER_MANAGEMENT_6, 0, 0),1013 1014/* We route as stereo pairs so define some dummy widgets to squash1015 * things down for now. RXA = 0,1, RXB = 2,3 and so on */1016SND_SOC_DAPM_PGA("AIF1RXA", SND_SOC_NOPM, 0, 0, NULL, 0),1017SND_SOC_DAPM_PGA("AIF1RXB", SND_SOC_NOPM, 0, 0, NULL, 0),1018SND_SOC_DAPM_PGA("AIF1RXC", SND_SOC_NOPM, 0, 0, NULL, 0),1019SND_SOC_DAPM_PGA("AIF2RX", SND_SOC_NOPM, 0, 0, NULL, 0),1020SND_SOC_DAPM_PGA("DSP2TX", SND_SOC_NOPM, 0, 0, NULL, 0),1021 1022SND_SOC_DAPM_MUX("DSP1RX", SND_SOC_NOPM, 0, 0, &dsp1rx),1023SND_SOC_DAPM_MUX("DSP2RX", SND_SOC_NOPM, 0, 0, &dsp2rx),1024SND_SOC_DAPM_MUX("AIF2TX", SND_SOC_NOPM, 0, 0, &aif2tx),1025 1026SND_SOC_DAPM_MUX("SPKL", SND_SOC_NOPM, 0, 0, &spkl_mux),1027SND_SOC_DAPM_MUX("SPKR", SND_SOC_NOPM, 0, 0, &spkr_mux),1028SND_SOC_DAPM_PGA("SPKL PGA", WM8996_LEFT_PDM_SPEAKER, 4, 0, NULL, 0),1029SND_SOC_DAPM_PGA("SPKR PGA", WM8996_RIGHT_PDM_SPEAKER, 4, 0, NULL, 0),1030 1031SND_SOC_DAPM_PGA_S("HPOUT2L PGA", 0, WM8996_POWER_MANAGEMENT_1, 7, 0, NULL, 0),1032SND_SOC_DAPM_PGA_S("HPOUT2L_DLY", 1, WM8996_ANALOGUE_HP_2, 5, 0, NULL, 0),1033SND_SOC_DAPM_PGA_S("HPOUT2L_DCS", 2, WM8996_DC_SERVO_1, 2, 0, dcs_start,1034 SND_SOC_DAPM_POST_PMU),1035SND_SOC_DAPM_PGA_S("HPOUT2L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2L, 0,1036 rmv_short_event,1037 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),1038 1039SND_SOC_DAPM_PGA_S("HPOUT2R PGA", 0, WM8996_POWER_MANAGEMENT_1, 6, 0,NULL, 0),1040SND_SOC_DAPM_PGA_S("HPOUT2R_DLY", 1, WM8996_ANALOGUE_HP_2, 1, 0, NULL, 0),1041SND_SOC_DAPM_PGA_S("HPOUT2R_DCS", 2, WM8996_DC_SERVO_1, 3, 0, dcs_start,1042 SND_SOC_DAPM_POST_PMU),1043SND_SOC_DAPM_PGA_S("HPOUT2R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT2R, 0,1044 rmv_short_event,1045 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),1046 1047SND_SOC_DAPM_PGA_S("HPOUT1L PGA", 0, WM8996_POWER_MANAGEMENT_1, 5, 0, NULL, 0),1048SND_SOC_DAPM_PGA_S("HPOUT1L_DLY", 1, WM8996_ANALOGUE_HP_1, 5, 0, NULL, 0),1049SND_SOC_DAPM_PGA_S("HPOUT1L_DCS", 2, WM8996_DC_SERVO_1, 0, 0, dcs_start,1050 SND_SOC_DAPM_POST_PMU),1051SND_SOC_DAPM_PGA_S("HPOUT1L_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1L, 0,1052 rmv_short_event,1053 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),1054 1055SND_SOC_DAPM_PGA_S("HPOUT1R PGA", 0, WM8996_POWER_MANAGEMENT_1, 4, 0, NULL, 0),1056SND_SOC_DAPM_PGA_S("HPOUT1R_DLY", 1, WM8996_ANALOGUE_HP_1, 1, 0, NULL, 0),1057SND_SOC_DAPM_PGA_S("HPOUT1R_DCS", 2, WM8996_DC_SERVO_1, 1, 0, dcs_start,1058 SND_SOC_DAPM_POST_PMU),1059SND_SOC_DAPM_PGA_S("HPOUT1R_RMV_SHORT", 3, SND_SOC_NOPM, HPOUT1R, 0,1060 rmv_short_event,1061 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD),1062 1063SND_SOC_DAPM_OUTPUT("HPOUT1L"),1064SND_SOC_DAPM_OUTPUT("HPOUT1R"),1065SND_SOC_DAPM_OUTPUT("HPOUT2L"),1066SND_SOC_DAPM_OUTPUT("HPOUT2R"),1067SND_SOC_DAPM_OUTPUT("SPKDAT"),1068};1069 1070static const struct snd_soc_dapm_route wm8996_dapm_routes[] = {1071 { "AIFCLK", NULL, "SYSCLK" },1072 { "SYSDSPCLK", NULL, "SYSCLK" },1073 { "Charge Pump", NULL, "SYSCLK" },1074 { "Charge Pump", NULL, "CPVDD" },1075 1076 { "MICB1", NULL, "LDO2" },1077 { "MICB1", NULL, "MICB1 Audio" },1078 { "MICB1", NULL, "Bandgap" },1079 { "MICB2", NULL, "LDO2" },1080 { "MICB2", NULL, "MICB2 Audio" },1081 { "MICB2", NULL, "Bandgap" },1082 1083 { "AIF1RX0", NULL, "AIF1 Playback" },1084 { "AIF1RX1", NULL, "AIF1 Playback" },1085 { "AIF1RX2", NULL, "AIF1 Playback" },1086 { "AIF1RX3", NULL, "AIF1 Playback" },1087 { "AIF1RX4", NULL, "AIF1 Playback" },1088 { "AIF1RX5", NULL, "AIF1 Playback" },1089 1090 { "AIF2RX0", NULL, "AIF2 Playback" },1091 { "AIF2RX1", NULL, "AIF2 Playback" },1092 1093 { "AIF1 Capture", NULL, "AIF1TX0" },1094 { "AIF1 Capture", NULL, "AIF1TX1" },1095 { "AIF1 Capture", NULL, "AIF1TX2" },1096 { "AIF1 Capture", NULL, "AIF1TX3" },1097 { "AIF1 Capture", NULL, "AIF1TX4" },1098 { "AIF1 Capture", NULL, "AIF1TX5" },1099 1100 { "AIF2 Capture", NULL, "AIF2TX0" },1101 { "AIF2 Capture", NULL, "AIF2TX1" },1102 1103 { "IN1L PGA", NULL, "IN2LN" },1104 { "IN1L PGA", NULL, "IN2LP" },1105 { "IN1L PGA", NULL, "IN1LN" },1106 { "IN1L PGA", NULL, "IN1LP" },1107 { "IN1L PGA", NULL, "Bandgap" },1108 1109 { "IN1R PGA", NULL, "IN2RN" },1110 { "IN1R PGA", NULL, "IN2RP" },1111 { "IN1R PGA", NULL, "IN1RN" },1112 { "IN1R PGA", NULL, "IN1RP" },1113 { "IN1R PGA", NULL, "Bandgap" },1114 1115 { "ADCL", NULL, "IN1L PGA" },1116 1117 { "ADCR", NULL, "IN1R PGA" },1118 1119 { "DMIC1L", NULL, "DMIC1DAT" },1120 { "DMIC1R", NULL, "DMIC1DAT" },1121 { "DMIC2L", NULL, "DMIC2DAT" },1122 { "DMIC2R", NULL, "DMIC2DAT" },1123 1124 { "DMIC2L", NULL, "DMIC2" },1125 { "DMIC2R", NULL, "DMIC2" },1126 { "DMIC1L", NULL, "DMIC1" },1127 { "DMIC1R", NULL, "DMIC1" },1128 1129 { "IN1L Mux", "ADC", "ADCL" },1130 { "IN1L Mux", "DMIC1", "DMIC1L" },1131 { "IN1L Mux", "DMIC2", "DMIC2L" },1132 1133 { "IN1R Mux", "ADC", "ADCR" },1134 { "IN1R Mux", "DMIC1", "DMIC1R" },1135 { "IN1R Mux", "DMIC2", "DMIC2R" },1136 1137 { "IN2L Mux", "ADC", "ADCL" },1138 { "IN2L Mux", "DMIC1", "DMIC1L" },1139 { "IN2L Mux", "DMIC2", "DMIC2L" },1140 1141 { "IN2R Mux", "ADC", "ADCR" },1142 { "IN2R Mux", "DMIC1", "DMIC1R" },1143 { "IN2R Mux", "DMIC2", "DMIC2R" },1144 1145 { "Left Sidetone", "IN1", "IN1L Mux" },1146 { "Left Sidetone", "IN2", "IN2L Mux" },1147 1148 { "Right Sidetone", "IN1", "IN1R Mux" },1149 { "Right Sidetone", "IN2", "IN2R Mux" },1150 1151 { "DSP1TXL", "IN1 Switch", "IN1L Mux" },1152 { "DSP1TXR", "IN1 Switch", "IN1R Mux" },1153 1154 { "DSP2TXL", "IN1 Switch", "IN2L Mux" },1155 { "DSP2TXR", "IN1 Switch", "IN2R Mux" },1156 1157 { "AIF1TX0", NULL, "DSP1TXL" },1158 { "AIF1TX1", NULL, "DSP1TXR" },1159 { "AIF1TX2", NULL, "DSP2TXL" },1160 { "AIF1TX3", NULL, "DSP2TXR" },1161 { "AIF1TX4", NULL, "AIF2RX0" },1162 { "AIF1TX5", NULL, "AIF2RX1" },1163 1164 { "AIF1RX0", NULL, "AIFCLK" },1165 { "AIF1RX1", NULL, "AIFCLK" },1166 { "AIF1RX2", NULL, "AIFCLK" },1167 { "AIF1RX3", NULL, "AIFCLK" },1168 { "AIF1RX4", NULL, "AIFCLK" },1169 { "AIF1RX5", NULL, "AIFCLK" },1170 1171 { "AIF2RX0", NULL, "AIFCLK" },1172 { "AIF2RX1", NULL, "AIFCLK" },1173 1174 { "AIF1TX0", NULL, "AIFCLK" },1175 { "AIF1TX1", NULL, "AIFCLK" },1176 { "AIF1TX2", NULL, "AIFCLK" },1177 { "AIF1TX3", NULL, "AIFCLK" },1178 { "AIF1TX4", NULL, "AIFCLK" },1179 { "AIF1TX5", NULL, "AIFCLK" },1180 1181 { "AIF2TX0", NULL, "AIFCLK" },1182 { "AIF2TX1", NULL, "AIFCLK" },1183 1184 { "DSP1RXL", NULL, "SYSDSPCLK" },1185 { "DSP1RXR", NULL, "SYSDSPCLK" },1186 { "DSP2RXL", NULL, "SYSDSPCLK" },1187 { "DSP2RXR", NULL, "SYSDSPCLK" },1188 { "DSP1TXL", NULL, "SYSDSPCLK" },1189 { "DSP1TXR", NULL, "SYSDSPCLK" },1190 { "DSP2TXL", NULL, "SYSDSPCLK" },1191 { "DSP2TXR", NULL, "SYSDSPCLK" },1192 1193 { "AIF1RXA", NULL, "AIF1RX0" },1194 { "AIF1RXA", NULL, "AIF1RX1" },1195 { "AIF1RXB", NULL, "AIF1RX2" },1196 { "AIF1RXB", NULL, "AIF1RX3" },1197 { "AIF1RXC", NULL, "AIF1RX4" },1198 { "AIF1RXC", NULL, "AIF1RX5" },1199 1200 { "AIF2RX", NULL, "AIF2RX0" },1201 { "AIF2RX", NULL, "AIF2RX1" },1202 1203 { "AIF2TX", "DSP2", "DSP2TX" },1204 { "AIF2TX", "DSP1", "DSP1RX" },1205 { "AIF2TX", "AIF1", "AIF1RXC" },1206 1207 { "DSP1RXL", NULL, "DSP1RX" },1208 { "DSP1RXR", NULL, "DSP1RX" },1209 { "DSP2RXL", NULL, "DSP2RX" },1210 { "DSP2RXR", NULL, "DSP2RX" },1211 1212 { "DSP2TX", NULL, "DSP2TXL" },1213 { "DSP2TX", NULL, "DSP2TXR" },1214 1215 { "DSP1RX", "AIF1", "AIF1RXA" },1216 { "DSP1RX", "AIF2", "AIF2RX" },1217 1218 { "DSP2RX", "AIF1", "AIF1RXB" },1219 { "DSP2RX", "AIF2", "AIF2RX" },1220 1221 { "DAC2L Mixer", "DSP2 Switch", "DSP2RXL" },1222 { "DAC2L Mixer", "DSP1 Switch", "DSP1RXL" },1223 { "DAC2L Mixer", "Right Sidetone Switch", "Right Sidetone" },1224 { "DAC2L Mixer", "Left Sidetone Switch", "Left Sidetone" },1225 1226 { "DAC2R Mixer", "DSP2 Switch", "DSP2RXR" },1227 { "DAC2R Mixer", "DSP1 Switch", "DSP1RXR" },1228 { "DAC2R Mixer", "Right Sidetone Switch", "Right Sidetone" },1229 { "DAC2R Mixer", "Left Sidetone Switch", "Left Sidetone" },1230 1231 { "DAC1L Mixer", "DSP2 Switch", "DSP2RXL" },1232 { "DAC1L Mixer", "DSP1 Switch", "DSP1RXL" },1233 { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" },1234 { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" },1235 1236 { "DAC1R Mixer", "DSP2 Switch", "DSP2RXR" },1237 { "DAC1R Mixer", "DSP1 Switch", "DSP1RXR" },1238 { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" },1239 { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" },1240 1241 { "DAC1L", NULL, "DAC1L Mixer" },1242 { "DAC1R", NULL, "DAC1R Mixer" },1243 { "DAC2L", NULL, "DAC2L Mixer" },1244 { "DAC2R", NULL, "DAC2R Mixer" },1245 1246 { "HPOUT2L PGA", NULL, "Charge Pump" },1247 { "HPOUT2L PGA", NULL, "Bandgap" },1248 { "HPOUT2L PGA", NULL, "DAC2L" },1249 { "HPOUT2L_DLY", NULL, "HPOUT2L PGA" },1250 { "HPOUT2L_DCS", NULL, "HPOUT2L_DLY" },1251 { "HPOUT2L_RMV_SHORT", NULL, "HPOUT2L_DCS" },1252 1253 { "HPOUT2R PGA", NULL, "Charge Pump" },1254 { "HPOUT2R PGA", NULL, "Bandgap" },1255 { "HPOUT2R PGA", NULL, "DAC2R" },1256 { "HPOUT2R_DLY", NULL, "HPOUT2R PGA" },1257 { "HPOUT2R_DCS", NULL, "HPOUT2R_DLY" },1258 { "HPOUT2R_RMV_SHORT", NULL, "HPOUT2R_DCS" },1259 1260 { "HPOUT1L PGA", NULL, "Charge Pump" },1261 { "HPOUT1L PGA", NULL, "Bandgap" },1262 { "HPOUT1L PGA", NULL, "DAC1L" },1263 { "HPOUT1L_DLY", NULL, "HPOUT1L PGA" },1264 { "HPOUT1L_DCS", NULL, "HPOUT1L_DLY" },1265 { "HPOUT1L_RMV_SHORT", NULL, "HPOUT1L_DCS" },1266 1267 { "HPOUT1R PGA", NULL, "Charge Pump" },1268 { "HPOUT1R PGA", NULL, "Bandgap" },1269 { "HPOUT1R PGA", NULL, "DAC1R" },1270 { "HPOUT1R_DLY", NULL, "HPOUT1R PGA" },1271 { "HPOUT1R_DCS", NULL, "HPOUT1R_DLY" },1272 { "HPOUT1R_RMV_SHORT", NULL, "HPOUT1R_DCS" },1273 1274 { "HPOUT2L", NULL, "HPOUT2L_RMV_SHORT" },1275 { "HPOUT2R", NULL, "HPOUT2R_RMV_SHORT" },1276 { "HPOUT1L", NULL, "HPOUT1L_RMV_SHORT" },1277 { "HPOUT1R", NULL, "HPOUT1R_RMV_SHORT" },1278 1279 { "SPKL", "DAC1L", "DAC1L" },1280 { "SPKL", "DAC1R", "DAC1R" },1281 { "SPKL", "DAC2L", "DAC2L" },1282 { "SPKL", "DAC2R", "DAC2R" },1283 1284 { "SPKR", "DAC1L", "DAC1L" },1285 { "SPKR", "DAC1R", "DAC1R" },1286 { "SPKR", "DAC2L", "DAC2L" },1287 { "SPKR", "DAC2R", "DAC2R" },1288 1289 { "SPKL PGA", NULL, "SPKL" },1290 { "SPKR PGA", NULL, "SPKR" },1291 1292 { "SPKDAT", NULL, "SPKL PGA" },1293 { "SPKDAT", NULL, "SPKR PGA" },1294};1295 1296static bool wm8996_readable_register(struct device *dev, unsigned int reg)1297{1298 /* Due to the sparseness of the register map the compiler1299 * output from an explicit switch statement ends up being much1300 * more efficient than a table.1301 */1302 switch (reg) {1303 case WM8996_SOFTWARE_RESET:1304 case WM8996_POWER_MANAGEMENT_1:1305 case WM8996_POWER_MANAGEMENT_2:1306 case WM8996_POWER_MANAGEMENT_3:1307 case WM8996_POWER_MANAGEMENT_4:1308 case WM8996_POWER_MANAGEMENT_5:1309 case WM8996_POWER_MANAGEMENT_6:1310 case WM8996_POWER_MANAGEMENT_7:1311 case WM8996_POWER_MANAGEMENT_8:1312 case WM8996_LEFT_LINE_INPUT_VOLUME:1313 case WM8996_RIGHT_LINE_INPUT_VOLUME:1314 case WM8996_LINE_INPUT_CONTROL:1315 case WM8996_DAC1_HPOUT1_VOLUME:1316 case WM8996_DAC2_HPOUT2_VOLUME:1317 case WM8996_DAC1_LEFT_VOLUME:1318 case WM8996_DAC1_RIGHT_VOLUME:1319 case WM8996_DAC2_LEFT_VOLUME:1320 case WM8996_DAC2_RIGHT_VOLUME:1321 case WM8996_OUTPUT1_LEFT_VOLUME:1322 case WM8996_OUTPUT1_RIGHT_VOLUME:1323 case WM8996_OUTPUT2_LEFT_VOLUME:1324 case WM8996_OUTPUT2_RIGHT_VOLUME:1325 case WM8996_MICBIAS_1:1326 case WM8996_MICBIAS_2:1327 case WM8996_LDO_1:1328 case WM8996_LDO_2:1329 case WM8996_ACCESSORY_DETECT_MODE_1:1330 case WM8996_ACCESSORY_DETECT_MODE_2:1331 case WM8996_HEADPHONE_DETECT_1:1332 case WM8996_HEADPHONE_DETECT_2:1333 case WM8996_MIC_DETECT_1:1334 case WM8996_MIC_DETECT_2:1335 case WM8996_MIC_DETECT_3:1336 case WM8996_CHARGE_PUMP_1:1337 case WM8996_CHARGE_PUMP_2:1338 case WM8996_DC_SERVO_1:1339 case WM8996_DC_SERVO_2:1340 case WM8996_DC_SERVO_3:1341 case WM8996_DC_SERVO_5:1342 case WM8996_DC_SERVO_6:1343 case WM8996_DC_SERVO_7:1344 case WM8996_DC_SERVO_READBACK_0:1345 case WM8996_ANALOGUE_HP_1:1346 case WM8996_ANALOGUE_HP_2:1347 case WM8996_CHIP_REVISION:1348 case WM8996_CONTROL_INTERFACE_1:1349 case WM8996_WRITE_SEQUENCER_CTRL_1:1350 case WM8996_WRITE_SEQUENCER_CTRL_2:1351 case WM8996_AIF_CLOCKING_1:1352 case WM8996_AIF_CLOCKING_2:1353 case WM8996_CLOCKING_1:1354 case WM8996_CLOCKING_2:1355 case WM8996_AIF_RATE:1356 case WM8996_FLL_CONTROL_1:1357 case WM8996_FLL_CONTROL_2:1358 case WM8996_FLL_CONTROL_3:1359 case WM8996_FLL_CONTROL_4:1360 case WM8996_FLL_CONTROL_5:1361 case WM8996_FLL_CONTROL_6:1362 case WM8996_FLL_EFS_1:1363 case WM8996_FLL_EFS_2:1364 case WM8996_AIF1_CONTROL:1365 case WM8996_AIF1_BCLK:1366 case WM8996_AIF1_TX_LRCLK_1:1367 case WM8996_AIF1_TX_LRCLK_2:1368 case WM8996_AIF1_RX_LRCLK_1:1369 case WM8996_AIF1_RX_LRCLK_2:1370 case WM8996_AIF1TX_DATA_CONFIGURATION_1:1371 case WM8996_AIF1TX_DATA_CONFIGURATION_2:1372 case WM8996_AIF1RX_DATA_CONFIGURATION:1373 case WM8996_AIF1TX_CHANNEL_0_CONFIGURATION:1374 case WM8996_AIF1TX_CHANNEL_1_CONFIGURATION:1375 case WM8996_AIF1TX_CHANNEL_2_CONFIGURATION:1376 case WM8996_AIF1TX_CHANNEL_3_CONFIGURATION:1377 case WM8996_AIF1TX_CHANNEL_4_CONFIGURATION:1378 case WM8996_AIF1TX_CHANNEL_5_CONFIGURATION:1379 case WM8996_AIF1RX_CHANNEL_0_CONFIGURATION:1380 case WM8996_AIF1RX_CHANNEL_1_CONFIGURATION:1381 case WM8996_AIF1RX_CHANNEL_2_CONFIGURATION:1382 case WM8996_AIF1RX_CHANNEL_3_CONFIGURATION:1383 case WM8996_AIF1RX_CHANNEL_4_CONFIGURATION:1384 case WM8996_AIF1RX_CHANNEL_5_CONFIGURATION:1385 case WM8996_AIF1RX_MONO_CONFIGURATION:1386 case WM8996_AIF1TX_TEST:1387 case WM8996_AIF2_CONTROL:1388 case WM8996_AIF2_BCLK:1389 case WM8996_AIF2_TX_LRCLK_1:1390 case WM8996_AIF2_TX_LRCLK_2:1391 case WM8996_AIF2_RX_LRCLK_1:1392 case WM8996_AIF2_RX_LRCLK_2:1393 case WM8996_AIF2TX_DATA_CONFIGURATION_1:1394 case WM8996_AIF2TX_DATA_CONFIGURATION_2:1395 case WM8996_AIF2RX_DATA_CONFIGURATION:1396 case WM8996_AIF2TX_CHANNEL_0_CONFIGURATION:1397 case WM8996_AIF2TX_CHANNEL_1_CONFIGURATION:1398 case WM8996_AIF2RX_CHANNEL_0_CONFIGURATION:1399 case WM8996_AIF2RX_CHANNEL_1_CONFIGURATION:1400 case WM8996_AIF2RX_MONO_CONFIGURATION:1401 case WM8996_AIF2TX_TEST:1402 case WM8996_DSP1_TX_LEFT_VOLUME:1403 case WM8996_DSP1_TX_RIGHT_VOLUME:1404 case WM8996_DSP1_RX_LEFT_VOLUME:1405 case WM8996_DSP1_RX_RIGHT_VOLUME:1406 case WM8996_DSP1_TX_FILTERS:1407 case WM8996_DSP1_RX_FILTERS_1:1408 case WM8996_DSP1_RX_FILTERS_2:1409 case WM8996_DSP1_DRC_1:1410 case WM8996_DSP1_DRC_2:1411 case WM8996_DSP1_DRC_3:1412 case WM8996_DSP1_DRC_4:1413 case WM8996_DSP1_DRC_5:1414 case WM8996_DSP1_RX_EQ_GAINS_1:1415 case WM8996_DSP1_RX_EQ_GAINS_2:1416 case WM8996_DSP1_RX_EQ_BAND_1_A:1417 case WM8996_DSP1_RX_EQ_BAND_1_B:1418 case WM8996_DSP1_RX_EQ_BAND_1_PG:1419 case WM8996_DSP1_RX_EQ_BAND_2_A:1420 case WM8996_DSP1_RX_EQ_BAND_2_B:1421 case WM8996_DSP1_RX_EQ_BAND_2_C:1422 case WM8996_DSP1_RX_EQ_BAND_2_PG:1423 case WM8996_DSP1_RX_EQ_BAND_3_A:1424 case WM8996_DSP1_RX_EQ_BAND_3_B:1425 case WM8996_DSP1_RX_EQ_BAND_3_C:1426 case WM8996_DSP1_RX_EQ_BAND_3_PG:1427 case WM8996_DSP1_RX_EQ_BAND_4_A:1428 case WM8996_DSP1_RX_EQ_BAND_4_B:1429 case WM8996_DSP1_RX_EQ_BAND_4_C:1430 case WM8996_DSP1_RX_EQ_BAND_4_PG:1431 case WM8996_DSP1_RX_EQ_BAND_5_A:1432 case WM8996_DSP1_RX_EQ_BAND_5_B:1433 case WM8996_DSP1_RX_EQ_BAND_5_PG:1434 case WM8996_DSP2_TX_LEFT_VOLUME:1435 case WM8996_DSP2_TX_RIGHT_VOLUME:1436 case WM8996_DSP2_RX_LEFT_VOLUME:1437 case WM8996_DSP2_RX_RIGHT_VOLUME:1438 case WM8996_DSP2_TX_FILTERS:1439 case WM8996_DSP2_RX_FILTERS_1:1440 case WM8996_DSP2_RX_FILTERS_2:1441 case WM8996_DSP2_DRC_1:1442 case WM8996_DSP2_DRC_2:1443 case WM8996_DSP2_DRC_3:1444 case WM8996_DSP2_DRC_4:1445 case WM8996_DSP2_DRC_5:1446 case WM8996_DSP2_RX_EQ_GAINS_1:1447 case WM8996_DSP2_RX_EQ_GAINS_2:1448 case WM8996_DSP2_RX_EQ_BAND_1_A:1449 case WM8996_DSP2_RX_EQ_BAND_1_B:1450 case WM8996_DSP2_RX_EQ_BAND_1_PG:1451 case WM8996_DSP2_RX_EQ_BAND_2_A:1452 case WM8996_DSP2_RX_EQ_BAND_2_B:1453 case WM8996_DSP2_RX_EQ_BAND_2_C:1454 case WM8996_DSP2_RX_EQ_BAND_2_PG:1455 case WM8996_DSP2_RX_EQ_BAND_3_A:1456 case WM8996_DSP2_RX_EQ_BAND_3_B:1457 case WM8996_DSP2_RX_EQ_BAND_3_C:1458 case WM8996_DSP2_RX_EQ_BAND_3_PG:1459 case WM8996_DSP2_RX_EQ_BAND_4_A:1460 case WM8996_DSP2_RX_EQ_BAND_4_B:1461 case WM8996_DSP2_RX_EQ_BAND_4_C:1462 case WM8996_DSP2_RX_EQ_BAND_4_PG:1463 case WM8996_DSP2_RX_EQ_BAND_5_A:1464 case WM8996_DSP2_RX_EQ_BAND_5_B:1465 case WM8996_DSP2_RX_EQ_BAND_5_PG:1466 case WM8996_DAC1_MIXER_VOLUMES:1467 case WM8996_DAC1_LEFT_MIXER_ROUTING:1468 case WM8996_DAC1_RIGHT_MIXER_ROUTING:1469 case WM8996_DAC2_MIXER_VOLUMES:1470 case WM8996_DAC2_LEFT_MIXER_ROUTING:1471 case WM8996_DAC2_RIGHT_MIXER_ROUTING:1472 case WM8996_DSP1_TX_LEFT_MIXER_ROUTING:1473 case WM8996_DSP1_TX_RIGHT_MIXER_ROUTING:1474 case WM8996_DSP2_TX_LEFT_MIXER_ROUTING:1475 case WM8996_DSP2_TX_RIGHT_MIXER_ROUTING:1476 case WM8996_DSP_TX_MIXER_SELECT:1477 case WM8996_DAC_SOFTMUTE:1478 case WM8996_OVERSAMPLING:1479 case WM8996_SIDETONE:1480 case WM8996_GPIO_1:1481 case WM8996_GPIO_2:1482 case WM8996_GPIO_3:1483 case WM8996_GPIO_4:1484 case WM8996_GPIO_5:1485 case WM8996_PULL_CONTROL_1:1486 case WM8996_PULL_CONTROL_2:1487 case WM8996_INTERRUPT_STATUS_1:1488 case WM8996_INTERRUPT_STATUS_2:1489 case WM8996_INTERRUPT_RAW_STATUS_2:1490 case WM8996_INTERRUPT_STATUS_1_MASK:1491 case WM8996_INTERRUPT_STATUS_2_MASK:1492 case WM8996_INTERRUPT_CONTROL:1493 case WM8996_LEFT_PDM_SPEAKER:1494 case WM8996_RIGHT_PDM_SPEAKER:1495 case WM8996_PDM_SPEAKER_MUTE_SEQUENCE:1496 case WM8996_PDM_SPEAKER_VOLUME:1497 return true;1498 default:1499 return false;1500 }1501}1502 1503static bool wm8996_volatile_register(struct device *dev, unsigned int reg)1504{1505 switch (reg) {1506 case WM8996_SOFTWARE_RESET:1507 case WM8996_CHIP_REVISION:1508 case WM8996_LDO_1:1509 case WM8996_LDO_2:1510 case WM8996_INTERRUPT_STATUS_1:1511 case WM8996_INTERRUPT_STATUS_2:1512 case WM8996_INTERRUPT_RAW_STATUS_2:1513 case WM8996_DC_SERVO_READBACK_0:1514 case WM8996_DC_SERVO_2:1515 case WM8996_DC_SERVO_6:1516 case WM8996_DC_SERVO_7:1517 case WM8996_FLL_CONTROL_6:1518 case WM8996_MIC_DETECT_3:1519 case WM8996_HEADPHONE_DETECT_1:1520 case WM8996_HEADPHONE_DETECT_2:1521 return true;1522 default:1523 return false;1524 }1525}1526 1527static const int bclk_divs[] = {1528 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 961529};1530 1531static void wm8996_update_bclk(struct snd_soc_component *component)1532{1533 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);1534 int aif, best, cur_val, bclk_rate, bclk_reg, i;1535 1536 /* Don't bother if we're in a low frequency idle mode that1537 * can't support audio.1538 */1539 if (wm8996->sysclk < 64000)1540 return;1541 1542 for (aif = 0; aif < WM8996_AIFS; aif++) {1543 switch (aif) {1544 case 0:1545 bclk_reg = WM8996_AIF1_BCLK;1546 break;1547 case 1:1548 bclk_reg = WM8996_AIF2_BCLK;1549 break;1550 }1551 1552 bclk_rate = wm8996->bclk_rate[aif];1553 1554 /* Pick a divisor for BCLK as close as we can get to ideal */1555 best = 0;1556 for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) {1557 cur_val = (wm8996->sysclk / bclk_divs[i]) - bclk_rate;1558 if (cur_val < 0) /* BCLK table is sorted */1559 break;1560 best = i;1561 }1562 bclk_rate = wm8996->sysclk / bclk_divs[best];1563 dev_dbg(component->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n",1564 bclk_divs[best], bclk_rate);1565 1566 snd_soc_component_update_bits(component, bclk_reg,1567 WM8996_AIF1_BCLK_DIV_MASK, best);1568 }1569}1570 1571static int wm8996_set_bias_level(struct snd_soc_component *component,1572 enum snd_soc_bias_level level)1573{1574 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);1575 int ret;1576 1577 switch (level) {1578 case SND_SOC_BIAS_ON:1579 break;1580 case SND_SOC_BIAS_PREPARE:1581 /* Put the MICBIASes into regulating mode */1582 snd_soc_component_update_bits(component, WM8996_MICBIAS_1,1583 WM8996_MICB1_MODE, 0);1584 snd_soc_component_update_bits(component, WM8996_MICBIAS_2,1585 WM8996_MICB2_MODE, 0);1586 break;1587 1588 case SND_SOC_BIAS_STANDBY:1589 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) {1590 ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),1591 wm8996->supplies);1592 if (ret != 0) {1593 dev_err(component->dev,1594 "Failed to enable supplies: %d\n",1595 ret);1596 return ret;1597 }1598 1599 if (wm8996->ldo_ena) {1600 gpiod_set_value_cansleep(wm8996->ldo_ena,1601 1);1602 msleep(5);1603 }1604 1605 regcache_cache_only(wm8996->regmap, false);1606 regcache_sync(wm8996->regmap);1607 }1608 1609 /* Bypass the MICBIASes for lowest power */1610 snd_soc_component_update_bits(component, WM8996_MICBIAS_1,1611 WM8996_MICB1_MODE, WM8996_MICB1_MODE);1612 snd_soc_component_update_bits(component, WM8996_MICBIAS_2,1613 WM8996_MICB2_MODE, WM8996_MICB2_MODE);1614 break;1615 1616 case SND_SOC_BIAS_OFF:1617 regcache_cache_only(wm8996->regmap, true);1618 if (wm8996->ldo_ena) {1619 gpiod_set_value_cansleep(wm8996->ldo_ena, 0);1620 regcache_cache_only(wm8996->regmap, true);1621 }1622 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies),1623 wm8996->supplies);1624 break;1625 }1626 1627 return 0;1628}1629 1630static int wm8996_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)1631{1632 struct snd_soc_component *component = dai->component;1633 int aifctrl = 0;1634 int bclk = 0;1635 int lrclk_tx = 0;1636 int lrclk_rx = 0;1637 int aifctrl_reg, bclk_reg, lrclk_tx_reg, lrclk_rx_reg;1638 1639 switch (dai->id) {1640 case 0:1641 aifctrl_reg = WM8996_AIF1_CONTROL;1642 bclk_reg = WM8996_AIF1_BCLK;1643 lrclk_tx_reg = WM8996_AIF1_TX_LRCLK_2;1644 lrclk_rx_reg = WM8996_AIF1_RX_LRCLK_2;1645 break;1646 case 1:1647 aifctrl_reg = WM8996_AIF2_CONTROL;1648 bclk_reg = WM8996_AIF2_BCLK;1649 lrclk_tx_reg = WM8996_AIF2_TX_LRCLK_2;1650 lrclk_rx_reg = WM8996_AIF2_RX_LRCLK_2;1651 break;1652 default:1653 WARN(1, "Invalid dai id %d\n", dai->id);1654 return -EINVAL;1655 }1656 1657 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {1658 case SND_SOC_DAIFMT_NB_NF:1659 break;1660 case SND_SOC_DAIFMT_IB_NF:1661 bclk |= WM8996_AIF1_BCLK_INV;1662 break;1663 case SND_SOC_DAIFMT_NB_IF:1664 lrclk_tx |= WM8996_AIF1TX_LRCLK_INV;1665 lrclk_rx |= WM8996_AIF1RX_LRCLK_INV;1666 break;1667 case SND_SOC_DAIFMT_IB_IF:1668 bclk |= WM8996_AIF1_BCLK_INV;1669 lrclk_tx |= WM8996_AIF1TX_LRCLK_INV;1670 lrclk_rx |= WM8996_AIF1RX_LRCLK_INV;1671 break;1672 }1673 1674 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {1675 case SND_SOC_DAIFMT_CBS_CFS:1676 break;1677 case SND_SOC_DAIFMT_CBS_CFM:1678 lrclk_tx |= WM8996_AIF1TX_LRCLK_MSTR;1679 lrclk_rx |= WM8996_AIF1RX_LRCLK_MSTR;1680 break;1681 case SND_SOC_DAIFMT_CBM_CFS:1682 bclk |= WM8996_AIF1_BCLK_MSTR;1683 break;1684 case SND_SOC_DAIFMT_CBM_CFM:1685 bclk |= WM8996_AIF1_BCLK_MSTR;1686 lrclk_tx |= WM8996_AIF1TX_LRCLK_MSTR;1687 lrclk_rx |= WM8996_AIF1RX_LRCLK_MSTR;1688 break;1689 default:1690 return -EINVAL;1691 }1692 1693 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {1694 case SND_SOC_DAIFMT_DSP_A:1695 break;1696 case SND_SOC_DAIFMT_DSP_B:1697 aifctrl |= 1;1698 break;1699 case SND_SOC_DAIFMT_I2S:1700 aifctrl |= 2;1701 break;1702 case SND_SOC_DAIFMT_LEFT_J:1703 aifctrl |= 3;1704 break;1705 default:1706 return -EINVAL;1707 }1708 1709 snd_soc_component_update_bits(component, aifctrl_reg, WM8996_AIF1_FMT_MASK, aifctrl);1710 snd_soc_component_update_bits(component, bclk_reg,1711 WM8996_AIF1_BCLK_INV | WM8996_AIF1_BCLK_MSTR,1712 bclk);1713 snd_soc_component_update_bits(component, lrclk_tx_reg,1714 WM8996_AIF1TX_LRCLK_INV |1715 WM8996_AIF1TX_LRCLK_MSTR,1716 lrclk_tx);1717 snd_soc_component_update_bits(component, lrclk_rx_reg,1718 WM8996_AIF1RX_LRCLK_INV |1719 WM8996_AIF1RX_LRCLK_MSTR,1720 lrclk_rx);1721 1722 return 0;1723}1724 1725static const int dsp_divs[] = {1726 48000, 32000, 16000, 80001727};1728 1729static int wm8996_hw_params(struct snd_pcm_substream *substream,1730 struct snd_pcm_hw_params *params,1731 struct snd_soc_dai *dai)1732{1733 struct snd_soc_component *component = dai->component;1734 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);1735 int bits, i, bclk_rate, best;1736 int aifdata = 0;1737 int lrclk = 0;1738 int dsp = 0;1739 int aifdata_reg, lrclk_reg, dsp_shift;1740 1741 switch (dai->id) {1742 case 0:1743 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||1744 (snd_soc_component_read(component, WM8996_GPIO_1)) & WM8996_GP1_FN_MASK) {1745 aifdata_reg = WM8996_AIF1RX_DATA_CONFIGURATION;1746 lrclk_reg = WM8996_AIF1_RX_LRCLK_1;1747 } else {1748 aifdata_reg = WM8996_AIF1TX_DATA_CONFIGURATION_1;1749 lrclk_reg = WM8996_AIF1_TX_LRCLK_1;1750 }1751 dsp_shift = 0;1752 break;1753 case 1:1754 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK ||1755 (snd_soc_component_read(component, WM8996_GPIO_2)) & WM8996_GP2_FN_MASK) {1756 aifdata_reg = WM8996_AIF2RX_DATA_CONFIGURATION;1757 lrclk_reg = WM8996_AIF2_RX_LRCLK_1;1758 } else {1759 aifdata_reg = WM8996_AIF2TX_DATA_CONFIGURATION_1;1760 lrclk_reg = WM8996_AIF2_TX_LRCLK_1;1761 }1762 dsp_shift = WM8996_DSP2_DIV_SHIFT;1763 break;1764 default:1765 WARN(1, "Invalid dai id %d\n", dai->id);1766 return -EINVAL;1767 }1768 1769 bclk_rate = snd_soc_params_to_bclk(params);1770 if (bclk_rate < 0) {1771 dev_err(component->dev, "Unsupported BCLK rate: %d\n", bclk_rate);1772 return bclk_rate;1773 }1774 1775 wm8996->bclk_rate[dai->id] = bclk_rate;1776 wm8996->rx_rate[dai->id] = params_rate(params);1777 1778 /* Needs looking at for TDM */1779 bits = params_width(params);1780 if (bits < 0)1781 return bits;1782 aifdata |= (bits << WM8996_AIF1TX_WL_SHIFT) | bits;1783 1784 best = 0;1785 for (i = 0; i < ARRAY_SIZE(dsp_divs); i++) {1786 if (abs(dsp_divs[i] - params_rate(params)) <1787 abs(dsp_divs[best] - params_rate(params)))1788 best = i;1789 }1790 dsp |= i << dsp_shift;1791 1792 wm8996_update_bclk(component);1793 1794 lrclk = bclk_rate / params_rate(params);1795 dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n",1796 lrclk, bclk_rate / lrclk);1797 1798 snd_soc_component_update_bits(component, aifdata_reg,1799 WM8996_AIF1TX_WL_MASK |1800 WM8996_AIF1TX_SLOT_LEN_MASK,1801 aifdata);1802 snd_soc_component_update_bits(component, lrclk_reg, WM8996_AIF1RX_RATE_MASK,1803 lrclk);1804 snd_soc_component_update_bits(component, WM8996_AIF_CLOCKING_2,1805 WM8996_DSP1_DIV_MASK << dsp_shift, dsp);1806 1807 return 0;1808}1809 1810static int wm8996_set_sysclk(struct snd_soc_dai *dai,1811 int clk_id, unsigned int freq, int dir)1812{1813 struct snd_soc_component *component = dai->component;1814 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);1815 int lfclk = 0;1816 int ratediv = 0;1817 int sync = WM8996_REG_SYNC;1818 int src;1819 int old;1820 1821 if (freq == wm8996->sysclk && clk_id == wm8996->sysclk_src)1822 return 0;1823 1824 /* Disable SYSCLK while we reconfigure */1825 old = snd_soc_component_read(component, WM8996_AIF_CLOCKING_1) & WM8996_SYSCLK_ENA;1826 snd_soc_component_update_bits(component, WM8996_AIF_CLOCKING_1,1827 WM8996_SYSCLK_ENA, 0);1828 1829 switch (clk_id) {1830 case WM8996_SYSCLK_MCLK1:1831 wm8996->sysclk = freq;1832 src = 0;1833 break;1834 case WM8996_SYSCLK_MCLK2:1835 wm8996->sysclk = freq;1836 src = 1;1837 break;1838 case WM8996_SYSCLK_FLL:1839 wm8996->sysclk = freq;1840 src = 2;1841 break;1842 default:1843 dev_err(component->dev, "Unsupported clock source %d\n", clk_id);1844 return -EINVAL;1845 }1846 1847 switch (wm8996->sysclk) {1848 case 5644800:1849 case 6144000:1850 snd_soc_component_update_bits(component, WM8996_AIF_RATE,1851 WM8996_SYSCLK_RATE, 0);1852 break;1853 case 22579200:1854 case 24576000:1855 ratediv = WM8996_SYSCLK_DIV;1856 wm8996->sysclk /= 2;1857 fallthrough;1858 case 11289600:1859 case 12288000:1860 snd_soc_component_update_bits(component, WM8996_AIF_RATE,1861 WM8996_SYSCLK_RATE, WM8996_SYSCLK_RATE);1862 break;1863 case 32000:1864 case 32768:1865 lfclk = WM8996_LFCLK_ENA;1866 sync = 0;1867 break;1868 default:1869 dev_warn(component->dev, "Unsupported clock rate %dHz\n",1870 wm8996->sysclk);1871 return -EINVAL;1872 }1873 1874 wm8996_update_bclk(component);1875 1876 snd_soc_component_update_bits(component, WM8996_AIF_CLOCKING_1,1877 WM8996_SYSCLK_SRC_MASK | WM8996_SYSCLK_DIV_MASK,1878 src << WM8996_SYSCLK_SRC_SHIFT | ratediv);1879 snd_soc_component_update_bits(component, WM8996_CLOCKING_1, WM8996_LFCLK_ENA, lfclk);1880 snd_soc_component_update_bits(component, WM8996_CONTROL_INTERFACE_1,1881 WM8996_REG_SYNC, sync);1882 snd_soc_component_update_bits(component, WM8996_AIF_CLOCKING_1,1883 WM8996_SYSCLK_ENA, old);1884 1885 wm8996->sysclk_src = clk_id;1886 1887 return 0;1888}1889 1890struct _fll_div {1891 u16 fll_fratio;1892 u16 fll_outdiv;1893 u16 fll_refclk_div;1894 u16 fll_loop_gain;1895 u16 fll_ref_freq;1896 u16 n;1897 u16 theta;1898 u16 lambda;1899};1900 1901static struct {1902 unsigned int min;1903 unsigned int max;1904 u16 fll_fratio;1905 int ratio;1906} fll_fratios[] = {1907 { 0, 64000, 4, 16 },1908 { 64000, 128000, 3, 8 },1909 { 128000, 256000, 2, 4 },1910 { 256000, 1000000, 1, 2 },1911 { 1000000, 13500000, 0, 1 },1912};1913 1914static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,1915 unsigned int Fout)1916{1917 unsigned int target;1918 unsigned int div;1919 unsigned int fratio, gcd_fll;1920 int i;1921 1922 /* Fref must be <=13.5MHz */1923 div = 1;1924 fll_div->fll_refclk_div = 0;1925 while ((Fref / div) > 13500000) {1926 div *= 2;1927 fll_div->fll_refclk_div++;1928 1929 if (div > 8) {1930 pr_err("Can't scale %dMHz input down to <=13.5MHz\n",1931 Fref);1932 return -EINVAL;1933 }1934 }1935 1936 pr_debug("FLL Fref=%u Fout=%u\n", Fref, Fout);1937 1938 /* Apply the division for our remaining calculations */1939 Fref /= div;1940 1941 if (Fref >= 3000000)1942 fll_div->fll_loop_gain = 5;1943 else1944 fll_div->fll_loop_gain = 0;1945 1946 if (Fref >= 48000)1947 fll_div->fll_ref_freq = 0;1948 else1949 fll_div->fll_ref_freq = 1;1950 1951 /* Fvco should be 90-100MHz; don't check the upper bound */1952 div = 2;1953 while (Fout * div < 90000000) {1954 div++;1955 if (div > 64) {1956 pr_err("Unable to find FLL_OUTDIV for Fout=%uHz\n",1957 Fout);1958 return -EINVAL;1959 }1960 }1961 target = Fout * div;1962 fll_div->fll_outdiv = div - 1;1963 1964 pr_debug("FLL Fvco=%dHz\n", target);1965 1966 /* Find an appropraite FLL_FRATIO and factor it out of the target */1967 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {1968 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {1969 fll_div->fll_fratio = fll_fratios[i].fll_fratio;1970 fratio = fll_fratios[i].ratio;1971 break;1972 }1973 }1974 if (i == ARRAY_SIZE(fll_fratios)) {1975 pr_err("Unable to find FLL_FRATIO for Fref=%uHz\n", Fref);1976 return -EINVAL;1977 }1978 1979 fll_div->n = target / (fratio * Fref);1980 1981 if (target % Fref == 0) {1982 fll_div->theta = 0;1983 fll_div->lambda = 0;1984 } else {1985 gcd_fll = gcd(target, fratio * Fref);1986 1987 fll_div->theta = (target - (fll_div->n * fratio * Fref))1988 / gcd_fll;1989 fll_div->lambda = (fratio * Fref) / gcd_fll;1990 }1991 1992 pr_debug("FLL N=%x THETA=%x LAMBDA=%x\n",1993 fll_div->n, fll_div->theta, fll_div->lambda);1994 pr_debug("FLL_FRATIO=%x FLL_OUTDIV=%x FLL_REFCLK_DIV=%x\n",1995 fll_div->fll_fratio, fll_div->fll_outdiv,1996 fll_div->fll_refclk_div);1997 1998 return 0;1999}2000 2001static int wm8996_set_fll(struct snd_soc_component *component, int fll_id, int source,2002 unsigned int Fref, unsigned int Fout)2003{2004 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);2005 struct i2c_client *i2c = to_i2c_client(component->dev);2006 struct _fll_div fll_div;2007 unsigned long timeout, time_left;2008 int ret, reg, retry;2009 2010 /* Any change? */2011 if (source == wm8996->fll_src && Fref == wm8996->fll_fref &&2012 Fout == wm8996->fll_fout)2013 return 0;2014 2015 if (Fout == 0) {2016 dev_dbg(component->dev, "FLL disabled\n");2017 2018 wm8996->fll_fref = 0;2019 wm8996->fll_fout = 0;2020 2021 snd_soc_component_update_bits(component, WM8996_FLL_CONTROL_1,2022 WM8996_FLL_ENA, 0);2023 2024 wm8996_bg_disable(component);2025 2026 return 0;2027 }2028 2029 ret = fll_factors(&fll_div, Fref, Fout);2030 if (ret != 0)2031 return ret;2032 2033 switch (source) {2034 case WM8996_FLL_MCLK1:2035 reg = 0;2036 break;2037 case WM8996_FLL_MCLK2:2038 reg = 1;2039 break;2040 case WM8996_FLL_DACLRCLK1:2041 reg = 2;2042 break;2043 case WM8996_FLL_BCLK1:2044 reg = 3;2045 break;2046 default:2047 dev_err(component->dev, "Unknown FLL source %d\n", ret);2048 return -EINVAL;2049 }2050 2051 reg |= fll_div.fll_refclk_div << WM8996_FLL_REFCLK_DIV_SHIFT;2052 reg |= fll_div.fll_ref_freq << WM8996_FLL_REF_FREQ_SHIFT;2053 2054 snd_soc_component_update_bits(component, WM8996_FLL_CONTROL_5,2055 WM8996_FLL_REFCLK_DIV_MASK | WM8996_FLL_REF_FREQ |2056 WM8996_FLL_REFCLK_SRC_MASK, reg);2057 2058 reg = 0;2059 if (fll_div.theta || fll_div.lambda)2060 reg |= WM8996_FLL_EFS_ENA | (3 << WM8996_FLL_LFSR_SEL_SHIFT);2061 else2062 reg |= 1 << WM8996_FLL_LFSR_SEL_SHIFT;2063 snd_soc_component_write(component, WM8996_FLL_EFS_2, reg);2064 2065 snd_soc_component_update_bits(component, WM8996_FLL_CONTROL_2,2066 WM8996_FLL_OUTDIV_MASK |2067 WM8996_FLL_FRATIO_MASK,2068 (fll_div.fll_outdiv << WM8996_FLL_OUTDIV_SHIFT) |2069 (fll_div.fll_fratio));2070 2071 snd_soc_component_write(component, WM8996_FLL_CONTROL_3, fll_div.theta);2072 2073 snd_soc_component_update_bits(component, WM8996_FLL_CONTROL_4,2074 WM8996_FLL_N_MASK | WM8996_FLL_LOOP_GAIN_MASK,2075 (fll_div.n << WM8996_FLL_N_SHIFT) |2076 fll_div.fll_loop_gain);2077 2078 snd_soc_component_write(component, WM8996_FLL_EFS_1, fll_div.lambda);2079 2080 /* Enable the bandgap if it's not already enabled */2081 ret = snd_soc_component_read(component, WM8996_FLL_CONTROL_1);2082 if (!(ret & WM8996_FLL_ENA))2083 wm8996_bg_enable(component);2084 2085 /* Clear any pending completions (eg, from failed startups) */2086 try_wait_for_completion(&wm8996->fll_lock);2087 2088 snd_soc_component_update_bits(component, WM8996_FLL_CONTROL_1,2089 WM8996_FLL_ENA, WM8996_FLL_ENA);2090 2091 /* The FLL supports live reconfiguration - kick that in case we were2092 * already enabled.2093 */2094 snd_soc_component_write(component, WM8996_FLL_CONTROL_6, WM8996_FLL_SWITCH_CLK);2095 2096 /* Wait for the FLL to lock, using the interrupt if possible */2097 if (Fref > 1000000)2098 timeout = usecs_to_jiffies(300);2099 else2100 timeout = msecs_to_jiffies(2);2101 2102 /* Allow substantially longer if we've actually got the IRQ, poll2103 * at a slightly higher rate if we don't.2104 */2105 if (i2c->irq)2106 timeout *= 10;2107 else2108 /* ensure timeout of atleast 1 jiffies */2109 timeout = (timeout/2) ? : 1;2110 2111 for (retry = 0; retry < 10; retry++) {2112 time_left = wait_for_completion_timeout(&wm8996->fll_lock,2113 timeout);2114 if (time_left != 0) {2115 WARN_ON(!i2c->irq);2116 ret = 1;2117 break;2118 }2119 2120 ret = snd_soc_component_read(component, WM8996_INTERRUPT_RAW_STATUS_2);2121 if (ret & WM8996_FLL_LOCK_STS)2122 break;2123 }2124 if (retry == 10) {2125 dev_err(component->dev, "Timed out waiting for FLL\n");2126 ret = -ETIMEDOUT;2127 }2128 2129 dev_dbg(component->dev, "FLL configured for %dHz->%dHz\n", Fref, Fout);2130 2131 wm8996->fll_fref = Fref;2132 wm8996->fll_fout = Fout;2133 wm8996->fll_src = source;2134 2135 return ret;2136}2137 2138#ifdef CONFIG_GPIOLIB2139static void wm8996_gpio_set(struct gpio_chip *chip, unsigned offset, int value)2140{2141 struct wm8996_priv *wm8996 = gpiochip_get_data(chip);2142 2143 regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset,2144 WM8996_GP1_LVL, !!value << WM8996_GP1_LVL_SHIFT);2145}2146 2147static int wm8996_gpio_direction_out(struct gpio_chip *chip,2148 unsigned offset, int value)2149{2150 struct wm8996_priv *wm8996 = gpiochip_get_data(chip);2151 int val;2152 2153 val = (1 << WM8996_GP1_FN_SHIFT) | (!!value << WM8996_GP1_LVL_SHIFT);2154 2155 return regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset,2156 WM8996_GP1_FN_MASK | WM8996_GP1_DIR |2157 WM8996_GP1_LVL, val);2158}2159 2160static int wm8996_gpio_get(struct gpio_chip *chip, unsigned offset)2161{2162 struct wm8996_priv *wm8996 = gpiochip_get_data(chip);2163 unsigned int reg;2164 int ret;2165 2166 ret = regmap_read(wm8996->regmap, WM8996_GPIO_1 + offset, ®);2167 if (ret < 0)2168 return ret;2169 2170 return (reg & WM8996_GP1_LVL) != 0;2171}2172 2173static int wm8996_gpio_direction_in(struct gpio_chip *chip, unsigned offset)2174{2175 struct wm8996_priv *wm8996 = gpiochip_get_data(chip);2176 2177 return regmap_update_bits(wm8996->regmap, WM8996_GPIO_1 + offset,2178 WM8996_GP1_FN_MASK | WM8996_GP1_DIR,2179 (1 << WM8996_GP1_FN_SHIFT) |2180 (1 << WM8996_GP1_DIR_SHIFT));2181}2182 2183static const struct gpio_chip wm8996_template_chip = {2184 .label = "wm8996",2185 .owner = THIS_MODULE,2186 .direction_output = wm8996_gpio_direction_out,2187 .set = wm8996_gpio_set,2188 .direction_input = wm8996_gpio_direction_in,2189 .get = wm8996_gpio_get,2190 .can_sleep = 1,2191 .ngpio = 5,2192 .base = -1,2193};2194 2195static void wm8996_init_gpio(struct wm8996_priv *wm8996)2196{2197 int ret;2198 2199 wm8996->gpio_chip = wm8996_template_chip;2200 wm8996->gpio_chip.parent = wm8996->dev;2201 2202 ret = gpiochip_add_data(&wm8996->gpio_chip, wm8996);2203 if (ret != 0)2204 dev_err(wm8996->dev, "Failed to add GPIOs: %d\n", ret);2205}2206 2207static void wm8996_free_gpio(struct wm8996_priv *wm8996)2208{2209 gpiochip_remove(&wm8996->gpio_chip);2210}2211#else2212static void wm8996_init_gpio(struct wm8996_priv *wm8996)2213{2214}2215 2216static void wm8996_free_gpio(struct wm8996_priv *wm8996)2217{2218}2219#endif2220 2221/**2222 * wm8996_detect - Enable default WM8996 jack detection2223 * @component: ASoC component2224 * @jack: jack pointer2225 * @polarity_cb: polarity callback2226 *2227 * The WM8996 has advanced accessory detection support for headsets.2228 * This function provides a default implementation which integrates2229 * the majority of this functionality with minimal user configuration.2230 *2231 * This will detect headset, headphone and short circuit button and2232 * will also detect inverted microphone ground connections and update2233 * the polarity of the connections.2234 */2235int wm8996_detect(struct snd_soc_component *component, struct snd_soc_jack *jack,2236 wm8996_polarity_fn polarity_cb)2237{2238 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);2239 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);2240 2241 wm8996->jack = jack;2242 wm8996->detecting = true;2243 wm8996->polarity_cb = polarity_cb;2244 wm8996->jack_flips = 0;2245 2246 if (wm8996->polarity_cb)2247 wm8996->polarity_cb(component, 0);2248 2249 /* Clear discarge to avoid noise during detection */2250 snd_soc_component_update_bits(component, WM8996_MICBIAS_1,2251 WM8996_MICB1_DISCH, 0);2252 snd_soc_component_update_bits(component, WM8996_MICBIAS_2,2253 WM8996_MICB2_DISCH, 0);2254 2255 /* LDO2 powers the microphones, SYSCLK clocks detection */2256 snd_soc_dapm_mutex_lock(dapm);2257 2258 snd_soc_dapm_force_enable_pin_unlocked(dapm, "LDO2");2259 snd_soc_dapm_force_enable_pin_unlocked(dapm, "SYSCLK");2260 2261 snd_soc_dapm_mutex_unlock(dapm);2262 2263 /* We start off just enabling microphone detection - even a2264 * plain headphone will trigger detection.2265 */2266 snd_soc_component_update_bits(component, WM8996_MIC_DETECT_1,2267 WM8996_MICD_ENA, WM8996_MICD_ENA);2268 2269 /* Slowest detection rate, gives debounce for initial detection */2270 snd_soc_component_update_bits(component, WM8996_MIC_DETECT_1,2271 WM8996_MICD_RATE_MASK,2272 WM8996_MICD_RATE_MASK);2273 2274 /* Enable interrupts and we're off */2275 snd_soc_component_update_bits(component, WM8996_INTERRUPT_STATUS_2_MASK,2276 WM8996_IM_MICD_EINT | WM8996_HP_DONE_EINT, 0);2277 2278 return 0;2279}2280EXPORT_SYMBOL_GPL(wm8996_detect);2281 2282static void wm8996_hpdet_irq(struct snd_soc_component *component)2283{2284 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);2285 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);2286 int val, reg, report;2287 2288 /* Assume headphone in error conditions; we need to report2289 * something or we stall our state machine.2290 */2291 report = SND_JACK_HEADPHONE;2292 2293 reg = snd_soc_component_read(component, WM8996_HEADPHONE_DETECT_2);2294 if (reg < 0) {2295 dev_err(component->dev, "Failed to read HPDET status\n");2296 goto out;2297 }2298 2299 if (!(reg & WM8996_HP_DONE)) {2300 dev_err(component->dev, "Got HPDET IRQ but HPDET is busy\n");2301 goto out;2302 }2303 2304 val = reg & WM8996_HP_LVL_MASK;2305 2306 dev_dbg(component->dev, "HPDET measured %d ohms\n", val);2307 2308 /* If we've got high enough impedence then report as line,2309 * otherwise assume headphone.2310 */2311 if (val >= 126)2312 report = SND_JACK_LINEOUT;2313 else2314 report = SND_JACK_HEADPHONE;2315 2316out:2317 if (wm8996->jack_mic)2318 report |= SND_JACK_MICROPHONE;2319 2320 snd_soc_jack_report(wm8996->jack, report,2321 SND_JACK_LINEOUT | SND_JACK_HEADSET);2322 2323 wm8996->detecting = false;2324 2325 /* If the output isn't running re-clamp it */2326 if (!(snd_soc_component_read(component, WM8996_POWER_MANAGEMENT_1) &2327 (WM8996_HPOUT1L_ENA | WM8996_HPOUT1R_RMV_SHORT)))2328 snd_soc_component_update_bits(component, WM8996_ANALOGUE_HP_1,2329 WM8996_HPOUT1L_RMV_SHORT |2330 WM8996_HPOUT1R_RMV_SHORT, 0);2331 2332 /* Go back to looking at the microphone */2333 snd_soc_component_update_bits(component, WM8996_ACCESSORY_DETECT_MODE_1,2334 WM8996_JD_MODE_MASK, 0);2335 snd_soc_component_update_bits(component, WM8996_MIC_DETECT_1, WM8996_MICD_ENA,2336 WM8996_MICD_ENA);2337 2338 snd_soc_dapm_disable_pin(dapm, "Bandgap");2339 snd_soc_dapm_sync(dapm);2340}2341 2342static void wm8996_hpdet_start(struct snd_soc_component *component)2343{2344 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);2345 2346 /* Unclamp the output, we can't measure while we're shorting it */2347 snd_soc_component_update_bits(component, WM8996_ANALOGUE_HP_1,2348 WM8996_HPOUT1L_RMV_SHORT |2349 WM8996_HPOUT1R_RMV_SHORT,2350 WM8996_HPOUT1L_RMV_SHORT |2351 WM8996_HPOUT1R_RMV_SHORT);2352 2353 /* We need bandgap for HPDET */2354 snd_soc_dapm_force_enable_pin(dapm, "Bandgap");2355 snd_soc_dapm_sync(dapm);2356 2357 /* Go into headphone detect left mode */2358 snd_soc_component_update_bits(component, WM8996_MIC_DETECT_1, WM8996_MICD_ENA, 0);2359 snd_soc_component_update_bits(component, WM8996_ACCESSORY_DETECT_MODE_1,2360 WM8996_JD_MODE_MASK, 1);2361 2362 /* Trigger a measurement */2363 snd_soc_component_update_bits(component, WM8996_HEADPHONE_DETECT_1,2364 WM8996_HP_POLL, WM8996_HP_POLL);2365}2366 2367static void wm8996_report_headphone(struct snd_soc_component *component)2368{2369 dev_dbg(component->dev, "Headphone detected\n");2370 wm8996_hpdet_start(component);2371 2372 /* Increase the detection rate a bit for responsiveness. */2373 snd_soc_component_update_bits(component, WM8996_MIC_DETECT_1,2374 WM8996_MICD_RATE_MASK |2375 WM8996_MICD_BIAS_STARTTIME_MASK,2376 7 << WM8996_MICD_RATE_SHIFT |2377 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);2378}2379 2380static void wm8996_micd(struct snd_soc_component *component)2381{2382 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);2383 int val, reg;2384 2385 val = snd_soc_component_read(component, WM8996_MIC_DETECT_3);2386 2387 dev_dbg(component->dev, "Microphone event: %x\n", val);2388 2389 if (!(val & WM8996_MICD_VALID)) {2390 dev_warn(component->dev, "Microphone detection state invalid\n");2391 return;2392 }2393 2394 /* No accessory, reset everything and report removal */2395 if (!(val & WM8996_MICD_STS)) {2396 dev_dbg(component->dev, "Jack removal detected\n");2397 wm8996->jack_mic = false;2398 wm8996->detecting = true;2399 wm8996->jack_flips = 0;2400 snd_soc_jack_report(wm8996->jack, 0,2401 SND_JACK_LINEOUT | SND_JACK_HEADSET |2402 SND_JACK_BTN_0);2403 2404 snd_soc_component_update_bits(component, WM8996_MIC_DETECT_1,2405 WM8996_MICD_RATE_MASK |2406 WM8996_MICD_BIAS_STARTTIME_MASK,2407 WM8996_MICD_RATE_MASK |2408 9 << WM8996_MICD_BIAS_STARTTIME_SHIFT);2409 return;2410 }2411 2412 /* If the measurement is very high we've got a microphone,2413 * either we just detected one or if we already reported then2414 * we've got a button release event.2415 */2416 if (val & 0x400) {2417 if (wm8996->detecting) {2418 dev_dbg(component->dev, "Microphone detected\n");2419 wm8996->jack_mic = true;2420 wm8996_hpdet_start(component);2421 2422 /* Increase poll rate to give better responsiveness2423 * for buttons */2424 snd_soc_component_update_bits(component, WM8996_MIC_DETECT_1,2425 WM8996_MICD_RATE_MASK |2426 WM8996_MICD_BIAS_STARTTIME_MASK,2427 5 << WM8996_MICD_RATE_SHIFT |2428 7 << WM8996_MICD_BIAS_STARTTIME_SHIFT);2429 } else {2430 dev_dbg(component->dev, "Mic button up\n");2431 snd_soc_jack_report(wm8996->jack, 0, SND_JACK_BTN_0);2432 }2433 2434 return;2435 }2436 2437 /* If we detected a lower impedence during initial startup2438 * then we probably have the wrong polarity, flip it. Don't2439 * do this for the lowest impedences to speed up detection of2440 * plain headphones. If both polarities report a low2441 * impedence then give up and report headphones.2442 */2443 if (wm8996->detecting && (val & 0x3f0)) {2444 wm8996->jack_flips++;2445 2446 if (wm8996->jack_flips > 1) {2447 wm8996_report_headphone(component);2448 return;2449 }2450 2451 reg = snd_soc_component_read(component, WM8996_ACCESSORY_DETECT_MODE_2);2452 reg ^= WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC |2453 WM8996_MICD_BIAS_SRC;2454 snd_soc_component_update_bits(component, WM8996_ACCESSORY_DETECT_MODE_2,2455 WM8996_HPOUT1FB_SRC | WM8996_MICD_SRC |2456 WM8996_MICD_BIAS_SRC, reg);2457 2458 if (wm8996->polarity_cb)2459 wm8996->polarity_cb(component,2460 (reg & WM8996_MICD_SRC) != 0);2461 2462 dev_dbg(component->dev, "Set microphone polarity to %d\n",2463 (reg & WM8996_MICD_SRC) != 0);2464 2465 return;2466 }2467 2468 /* Don't distinguish between buttons, just report any low2469 * impedence as BTN_0.2470 */2471 if (val & 0x3fc) {2472 if (wm8996->jack_mic) {2473 dev_dbg(component->dev, "Mic button detected\n");2474 snd_soc_jack_report(wm8996->jack, SND_JACK_BTN_0,2475 SND_JACK_BTN_0);2476 } else if (wm8996->detecting) {2477 wm8996_report_headphone(component);2478 }2479 }2480}2481 2482static irqreturn_t wm8996_irq(int irq, void *data)2483{2484 struct snd_soc_component *component = data;2485 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);2486 int irq_val;2487 2488 irq_val = snd_soc_component_read(component, WM8996_INTERRUPT_STATUS_2);2489 if (irq_val < 0) {2490 dev_err(component->dev, "Failed to read IRQ status: %d\n",2491 irq_val);2492 return IRQ_NONE;2493 }2494 irq_val &= ~snd_soc_component_read(component, WM8996_INTERRUPT_STATUS_2_MASK);2495 2496 if (!irq_val)2497 return IRQ_NONE;2498 2499 snd_soc_component_write(component, WM8996_INTERRUPT_STATUS_2, irq_val);2500 2501 if (irq_val & (WM8996_DCS_DONE_01_EINT | WM8996_DCS_DONE_23_EINT)) {2502 dev_dbg(component->dev, "DC servo IRQ\n");2503 complete(&wm8996->dcs_done);2504 }2505 2506 if (irq_val & WM8996_FIFOS_ERR_EINT)2507 dev_err(component->dev, "Digital core FIFO error\n");2508 2509 if (irq_val & WM8996_FLL_LOCK_EINT) {2510 dev_dbg(component->dev, "FLL locked\n");2511 complete(&wm8996->fll_lock);2512 }2513 2514 if (irq_val & WM8996_MICD_EINT)2515 wm8996_micd(component);2516 2517 if (irq_val & WM8996_HP_DONE_EINT)2518 wm8996_hpdet_irq(component);2519 2520 return IRQ_HANDLED;2521}2522 2523static irqreturn_t wm8996_edge_irq(int irq, void *data)2524{2525 irqreturn_t ret = IRQ_NONE;2526 irqreturn_t val;2527 2528 do {2529 val = wm8996_irq(irq, data);2530 if (val != IRQ_NONE)2531 ret = val;2532 } while (val != IRQ_NONE);2533 2534 return ret;2535}2536 2537static void wm8996_retune_mobile_pdata(struct snd_soc_component *component)2538{2539 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);2540 struct wm8996_pdata *pdata = &wm8996->pdata;2541 2542 struct snd_kcontrol_new controls[] = {2543 SOC_ENUM_EXT("DSP1 EQ Mode",2544 wm8996->retune_mobile_enum,2545 wm8996_get_retune_mobile_enum,2546 wm8996_put_retune_mobile_enum),2547 SOC_ENUM_EXT("DSP2 EQ Mode",2548 wm8996->retune_mobile_enum,2549 wm8996_get_retune_mobile_enum,2550 wm8996_put_retune_mobile_enum),2551 };2552 int ret, i, j;2553 const char **t;2554 2555 /* We need an array of texts for the enum API but the number2556 * of texts is likely to be less than the number of2557 * configurations due to the sample rate dependency of the2558 * configurations. */2559 wm8996->num_retune_mobile_texts = 0;2560 wm8996->retune_mobile_texts = NULL;2561 for (i = 0; i < pdata->num_retune_mobile_cfgs; i++) {2562 for (j = 0; j < wm8996->num_retune_mobile_texts; j++) {2563 if (strcmp(pdata->retune_mobile_cfgs[i].name,2564 wm8996->retune_mobile_texts[j]) == 0)2565 break;2566 }2567 2568 if (j != wm8996->num_retune_mobile_texts)2569 continue;2570 2571 /* Expand the array... */2572 t = krealloc(wm8996->retune_mobile_texts,2573 sizeof(char *) * 2574 (wm8996->num_retune_mobile_texts + 1),2575 GFP_KERNEL);2576 if (t == NULL)2577 continue;2578 2579 /* ...store the new entry... */2580 t[wm8996->num_retune_mobile_texts] = 2581 pdata->retune_mobile_cfgs[i].name;2582 2583 /* ...and remember the new version. */2584 wm8996->num_retune_mobile_texts++;2585 wm8996->retune_mobile_texts = t;2586 }2587 2588 dev_dbg(component->dev, "Allocated %d unique ReTune Mobile names\n",2589 wm8996->num_retune_mobile_texts);2590 2591 wm8996->retune_mobile_enum.items = wm8996->num_retune_mobile_texts;2592 wm8996->retune_mobile_enum.texts = wm8996->retune_mobile_texts;2593 2594 ret = snd_soc_add_component_controls(component, controls, ARRAY_SIZE(controls));2595 if (ret != 0)2596 dev_err(component->dev,2597 "Failed to add ReTune Mobile controls: %d\n", ret);2598}2599 2600static const struct regmap_config wm8996_regmap = {2601 .reg_bits = 16,2602 .val_bits = 16,2603 2604 .max_register = WM8996_MAX_REGISTER,2605 .reg_defaults = wm8996_reg,2606 .num_reg_defaults = ARRAY_SIZE(wm8996_reg),2607 .volatile_reg = wm8996_volatile_register,2608 .readable_reg = wm8996_readable_register,2609 .cache_type = REGCACHE_MAPLE,2610};2611 2612static int wm8996_probe(struct snd_soc_component *component)2613{2614 int ret;2615 struct wm8996_priv *wm8996 = snd_soc_component_get_drvdata(component);2616 struct i2c_client *i2c = to_i2c_client(component->dev);2617 int irq_flags;2618 2619 wm8996->component = component;2620 2621 init_completion(&wm8996->dcs_done);2622 init_completion(&wm8996->fll_lock);2623 2624 if (wm8996->pdata.num_retune_mobile_cfgs)2625 wm8996_retune_mobile_pdata(component);2626 else2627 snd_soc_add_component_controls(component, wm8996_eq_controls,2628 ARRAY_SIZE(wm8996_eq_controls));2629 2630 if (i2c->irq) {2631 if (wm8996->pdata.irq_flags)2632 irq_flags = wm8996->pdata.irq_flags;2633 else2634 irq_flags = IRQF_TRIGGER_LOW;2635 2636 irq_flags |= IRQF_ONESHOT;2637 2638 if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING))2639 ret = request_threaded_irq(i2c->irq, NULL,2640 wm8996_edge_irq,2641 irq_flags, "wm8996", component);2642 else2643 ret = request_threaded_irq(i2c->irq, NULL, wm8996_irq,2644 irq_flags, "wm8996", component);2645 2646 if (ret == 0) {2647 /* Unmask the interrupt */2648 snd_soc_component_update_bits(component, WM8996_INTERRUPT_CONTROL,2649 WM8996_IM_IRQ, 0);2650 2651 /* Enable error reporting and DC servo status */2652 snd_soc_component_update_bits(component,2653 WM8996_INTERRUPT_STATUS_2_MASK,2654 WM8996_IM_DCS_DONE_23_EINT |2655 WM8996_IM_DCS_DONE_01_EINT |2656 WM8996_IM_FLL_LOCK_EINT |2657 WM8996_IM_FIFOS_ERR_EINT,2658 0);2659 } else {2660 dev_err(component->dev, "Failed to request IRQ: %d\n",2661 ret);2662 return ret;2663 }2664 }2665 2666 return 0;2667}2668 2669static void wm8996_remove(struct snd_soc_component *component)2670{2671 struct i2c_client *i2c = to_i2c_client(component->dev);2672 2673 snd_soc_component_update_bits(component, WM8996_INTERRUPT_CONTROL,2674 WM8996_IM_IRQ, WM8996_IM_IRQ);2675 2676 if (i2c->irq)2677 free_irq(i2c->irq, component);2678}2679 2680static const struct snd_soc_component_driver soc_component_dev_wm8996 = {2681 .probe = wm8996_probe,2682 .remove = wm8996_remove,2683 .set_bias_level = wm8996_set_bias_level,2684 .seq_notifier = wm8996_seq_notifier,2685 .controls = wm8996_snd_controls,2686 .num_controls = ARRAY_SIZE(wm8996_snd_controls),2687 .dapm_widgets = wm8996_dapm_widgets,2688 .num_dapm_widgets = ARRAY_SIZE(wm8996_dapm_widgets),2689 .dapm_routes = wm8996_dapm_routes,2690 .num_dapm_routes = ARRAY_SIZE(wm8996_dapm_routes),2691 .set_pll = wm8996_set_fll,2692 .use_pmdown_time = 1,2693 .endianness = 1,2694};2695 2696#define WM8996_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_16000 |\2697 SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\2698 SNDRV_PCM_RATE_48000)2699#define WM8996_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\2700 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE |\2701 SNDRV_PCM_FMTBIT_S32_LE)2702 2703static const struct snd_soc_dai_ops wm8996_dai_ops = {2704 .set_fmt = wm8996_set_fmt,2705 .hw_params = wm8996_hw_params,2706 .set_sysclk = wm8996_set_sysclk,2707};2708 2709static struct snd_soc_dai_driver wm8996_dai[] = {2710 {2711 .name = "wm8996-aif1",2712 .playback = {2713 .stream_name = "AIF1 Playback",2714 .channels_min = 1,2715 .channels_max = 6,2716 .rates = WM8996_RATES,2717 .formats = WM8996_FORMATS,2718 .sig_bits = 24,2719 },2720 .capture = {2721 .stream_name = "AIF1 Capture",2722 .channels_min = 1,2723 .channels_max = 6,2724 .rates = WM8996_RATES,2725 .formats = WM8996_FORMATS,2726 .sig_bits = 24,2727 },2728 .ops = &wm8996_dai_ops,2729 },2730 {2731 .name = "wm8996-aif2",2732 .playback = {2733 .stream_name = "AIF2 Playback",2734 .channels_min = 1,2735 .channels_max = 2,2736 .rates = WM8996_RATES,2737 .formats = WM8996_FORMATS,2738 .sig_bits = 24,2739 },2740 .capture = {2741 .stream_name = "AIF2 Capture",2742 .channels_min = 1,2743 .channels_max = 2,2744 .rates = WM8996_RATES,2745 .formats = WM8996_FORMATS,2746 .sig_bits = 24,2747 },2748 .ops = &wm8996_dai_ops,2749 },2750};2751 2752static int wm8996_i2c_probe(struct i2c_client *i2c)2753{2754 struct wm8996_priv *wm8996;2755 int ret, i;2756 unsigned int reg;2757 2758 wm8996 = devm_kzalloc(&i2c->dev, sizeof(struct wm8996_priv),2759 GFP_KERNEL);2760 if (wm8996 == NULL)2761 return -ENOMEM;2762 2763 i2c_set_clientdata(i2c, wm8996);2764 wm8996->dev = &i2c->dev;2765 2766 if (dev_get_platdata(&i2c->dev))2767 memcpy(&wm8996->pdata, dev_get_platdata(&i2c->dev),2768 sizeof(wm8996->pdata));2769 2770 wm8996->ldo_ena = devm_gpiod_get_optional(&i2c->dev, "wlf,ldo1ena",2771 GPIOD_OUT_LOW);2772 if (IS_ERR(wm8996->ldo_ena)) {2773 ret = PTR_ERR(wm8996->ldo_ena);2774 dev_err(&i2c->dev, "Failed to request LDO ENA GPIO: %d\n",2775 ret);2776 goto err;2777 }2778 gpiod_set_consumer_name(wm8996->ldo_ena, "WM8996 ENA");2779 2780 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)2781 wm8996->supplies[i].supply = wm8996_supply_names[i];2782 2783 ret = devm_regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies),2784 wm8996->supplies);2785 if (ret != 0) {2786 dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);2787 goto err_gpio;2788 }2789 2790 wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0;2791 wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;2792 wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;2793 2794 /* This should really be moved into the regulator core */2795 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {2796 ret = devm_regulator_register_notifier(2797 wm8996->supplies[i].consumer,2798 &wm8996->disable_nb[i]);2799 if (ret != 0) {2800 dev_err(&i2c->dev,2801 "Failed to register regulator notifier: %d\n",2802 ret);2803 }2804 }2805 2806 ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),2807 wm8996->supplies);2808 if (ret != 0) {2809 dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);2810 goto err_gpio;2811 }2812 2813 if (wm8996->ldo_ena) {2814 gpiod_set_value_cansleep(wm8996->ldo_ena, 1);2815 msleep(5);2816 }2817 2818 wm8996->regmap = devm_regmap_init_i2c(i2c, &wm8996_regmap);2819 if (IS_ERR(wm8996->regmap)) {2820 ret = PTR_ERR(wm8996->regmap);2821 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);2822 goto err_enable;2823 }2824 2825 ret = regmap_read(wm8996->regmap, WM8996_SOFTWARE_RESET, ®);2826 if (ret < 0) {2827 dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);2828 goto err_regmap;2829 }2830 if (reg != 0x8915) {2831 dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", reg);2832 ret = -EINVAL;2833 goto err_regmap;2834 }2835 2836 ret = regmap_read(wm8996->regmap, WM8996_CHIP_REVISION, ®);2837 if (ret < 0) {2838 dev_err(&i2c->dev, "Failed to read device revision: %d\n",2839 ret);2840 goto err_regmap;2841 }2842 2843 dev_info(&i2c->dev, "revision %c\n",2844 (reg & WM8996_CHIP_REV_MASK) + 'A');2845 2846 if (wm8996->ldo_ena) {2847 gpiod_set_value_cansleep(wm8996->ldo_ena, 0);2848 regcache_cache_only(wm8996->regmap, true);2849 } else {2850 ret = regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET,2851 0x8915);2852 if (ret != 0) {2853 dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);2854 goto err_regmap;2855 }2856 }2857 2858 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);2859 2860 /* Apply platform data settings */2861 regmap_update_bits(wm8996->regmap, WM8996_LINE_INPUT_CONTROL,2862 WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK,2863 wm8996->pdata.inl_mode << WM8996_INL_MODE_SHIFT |2864 wm8996->pdata.inr_mode);2865 2866 for (i = 0; i < ARRAY_SIZE(wm8996->pdata.gpio_default); i++) {2867 if (!wm8996->pdata.gpio_default[i])2868 continue;2869 2870 regmap_write(wm8996->regmap, WM8996_GPIO_1 + i,2871 wm8996->pdata.gpio_default[i] & 0xffff);2872 }2873 2874 if (wm8996->pdata.spkmute_seq)2875 regmap_update_bits(wm8996->regmap,2876 WM8996_PDM_SPEAKER_MUTE_SEQUENCE,2877 WM8996_SPK_MUTE_ENDIAN |2878 WM8996_SPK_MUTE_SEQ1_MASK,2879 wm8996->pdata.spkmute_seq);2880 2881 regmap_update_bits(wm8996->regmap, WM8996_ACCESSORY_DETECT_MODE_2,2882 WM8996_MICD_BIAS_SRC | WM8996_HPOUT1FB_SRC |2883 WM8996_MICD_SRC, wm8996->pdata.micdet_def);2884 2885 /* Latch volume update bits */2886 regmap_update_bits(wm8996->regmap, WM8996_LEFT_LINE_INPUT_VOLUME,2887 WM8996_IN1_VU, WM8996_IN1_VU);2888 regmap_update_bits(wm8996->regmap, WM8996_RIGHT_LINE_INPUT_VOLUME,2889 WM8996_IN1_VU, WM8996_IN1_VU);2890 2891 regmap_update_bits(wm8996->regmap, WM8996_DAC1_LEFT_VOLUME,2892 WM8996_DAC1_VU, WM8996_DAC1_VU);2893 regmap_update_bits(wm8996->regmap, WM8996_DAC1_RIGHT_VOLUME,2894 WM8996_DAC1_VU, WM8996_DAC1_VU);2895 regmap_update_bits(wm8996->regmap, WM8996_DAC2_LEFT_VOLUME,2896 WM8996_DAC2_VU, WM8996_DAC2_VU);2897 regmap_update_bits(wm8996->regmap, WM8996_DAC2_RIGHT_VOLUME,2898 WM8996_DAC2_VU, WM8996_DAC2_VU);2899 2900 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT1_LEFT_VOLUME,2901 WM8996_DAC1_VU, WM8996_DAC1_VU);2902 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT1_RIGHT_VOLUME,2903 WM8996_DAC1_VU, WM8996_DAC1_VU);2904 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT2_LEFT_VOLUME,2905 WM8996_DAC2_VU, WM8996_DAC2_VU);2906 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT2_RIGHT_VOLUME,2907 WM8996_DAC2_VU, WM8996_DAC2_VU);2908 2909 regmap_update_bits(wm8996->regmap, WM8996_DSP1_TX_LEFT_VOLUME,2910 WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);2911 regmap_update_bits(wm8996->regmap, WM8996_DSP1_TX_RIGHT_VOLUME,2912 WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);2913 regmap_update_bits(wm8996->regmap, WM8996_DSP2_TX_LEFT_VOLUME,2914 WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);2915 regmap_update_bits(wm8996->regmap, WM8996_DSP2_TX_RIGHT_VOLUME,2916 WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);2917 2918 regmap_update_bits(wm8996->regmap, WM8996_DSP1_RX_LEFT_VOLUME,2919 WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);2920 regmap_update_bits(wm8996->regmap, WM8996_DSP1_RX_RIGHT_VOLUME,2921 WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);2922 regmap_update_bits(wm8996->regmap, WM8996_DSP2_RX_LEFT_VOLUME,2923 WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);2924 regmap_update_bits(wm8996->regmap, WM8996_DSP2_RX_RIGHT_VOLUME,2925 WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);2926 2927 /* No support currently for the underclocked TDM modes and2928 * pick a default TDM layout with each channel pair working with2929 * slots 0 and 1. */2930 regmap_update_bits(wm8996->regmap,2931 WM8996_AIF1RX_CHANNEL_0_CONFIGURATION,2932 WM8996_AIF1RX_CHAN0_SLOTS_MASK |2933 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,2934 1 << WM8996_AIF1RX_CHAN0_SLOTS_SHIFT | 0);2935 regmap_update_bits(wm8996->regmap,2936 WM8996_AIF1RX_CHANNEL_1_CONFIGURATION,2937 WM8996_AIF1RX_CHAN1_SLOTS_MASK |2938 WM8996_AIF1RX_CHAN1_START_SLOT_MASK,2939 1 << WM8996_AIF1RX_CHAN1_SLOTS_SHIFT | 1);2940 regmap_update_bits(wm8996->regmap,2941 WM8996_AIF1RX_CHANNEL_2_CONFIGURATION,2942 WM8996_AIF1RX_CHAN2_SLOTS_MASK |2943 WM8996_AIF1RX_CHAN2_START_SLOT_MASK,2944 1 << WM8996_AIF1RX_CHAN2_SLOTS_SHIFT | 0);2945 regmap_update_bits(wm8996->regmap,2946 WM8996_AIF1RX_CHANNEL_3_CONFIGURATION,2947 WM8996_AIF1RX_CHAN3_SLOTS_MASK |2948 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,2949 1 << WM8996_AIF1RX_CHAN3_SLOTS_SHIFT | 1);2950 regmap_update_bits(wm8996->regmap,2951 WM8996_AIF1RX_CHANNEL_4_CONFIGURATION,2952 WM8996_AIF1RX_CHAN4_SLOTS_MASK |2953 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,2954 1 << WM8996_AIF1RX_CHAN4_SLOTS_SHIFT | 0);2955 regmap_update_bits(wm8996->regmap,2956 WM8996_AIF1RX_CHANNEL_5_CONFIGURATION,2957 WM8996_AIF1RX_CHAN5_SLOTS_MASK |2958 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,2959 1 << WM8996_AIF1RX_CHAN5_SLOTS_SHIFT | 1);2960 2961 regmap_update_bits(wm8996->regmap,2962 WM8996_AIF2RX_CHANNEL_0_CONFIGURATION,2963 WM8996_AIF2RX_CHAN0_SLOTS_MASK |2964 WM8996_AIF2RX_CHAN0_START_SLOT_MASK,2965 1 << WM8996_AIF2RX_CHAN0_SLOTS_SHIFT | 0);2966 regmap_update_bits(wm8996->regmap,2967 WM8996_AIF2RX_CHANNEL_1_CONFIGURATION,2968 WM8996_AIF2RX_CHAN1_SLOTS_MASK |2969 WM8996_AIF2RX_CHAN1_START_SLOT_MASK,2970 1 << WM8996_AIF2RX_CHAN1_SLOTS_SHIFT | 1);2971 2972 regmap_update_bits(wm8996->regmap,2973 WM8996_AIF1TX_CHANNEL_0_CONFIGURATION,2974 WM8996_AIF1TX_CHAN0_SLOTS_MASK |2975 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,2976 1 << WM8996_AIF1TX_CHAN0_SLOTS_SHIFT | 0);2977 regmap_update_bits(wm8996->regmap,2978 WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,2979 WM8996_AIF1TX_CHAN1_SLOTS_MASK |2980 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,2981 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);2982 regmap_update_bits(wm8996->regmap,2983 WM8996_AIF1TX_CHANNEL_2_CONFIGURATION,2984 WM8996_AIF1TX_CHAN2_SLOTS_MASK |2985 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,2986 1 << WM8996_AIF1TX_CHAN2_SLOTS_SHIFT | 0);2987 regmap_update_bits(wm8996->regmap,2988 WM8996_AIF1TX_CHANNEL_3_CONFIGURATION,2989 WM8996_AIF1TX_CHAN3_SLOTS_MASK |2990 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,2991 1 << WM8996_AIF1TX_CHAN3_SLOTS_SHIFT | 1);2992 regmap_update_bits(wm8996->regmap,2993 WM8996_AIF1TX_CHANNEL_4_CONFIGURATION,2994 WM8996_AIF1TX_CHAN4_SLOTS_MASK |2995 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,2996 1 << WM8996_AIF1TX_CHAN4_SLOTS_SHIFT | 0);2997 regmap_update_bits(wm8996->regmap,2998 WM8996_AIF1TX_CHANNEL_5_CONFIGURATION,2999 WM8996_AIF1TX_CHAN5_SLOTS_MASK |3000 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,3001 1 << WM8996_AIF1TX_CHAN5_SLOTS_SHIFT | 1);3002 3003 regmap_update_bits(wm8996->regmap,3004 WM8996_AIF2TX_CHANNEL_0_CONFIGURATION,3005 WM8996_AIF2TX_CHAN0_SLOTS_MASK |3006 WM8996_AIF2TX_CHAN0_START_SLOT_MASK,3007 1 << WM8996_AIF2TX_CHAN0_SLOTS_SHIFT | 0);3008 regmap_update_bits(wm8996->regmap,3009 WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,3010 WM8996_AIF2TX_CHAN1_SLOTS_MASK |3011 WM8996_AIF2TX_CHAN1_START_SLOT_MASK,3012 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);3013 3014 /* If the TX LRCLK pins are not in LRCLK mode configure the3015 * AIFs to source their clocks from the RX LRCLKs.3016 */3017 ret = regmap_read(wm8996->regmap, WM8996_GPIO_1, ®);3018 if (ret != 0) {3019 dev_err(&i2c->dev, "Failed to read GPIO1: %d\n", ret);3020 goto err_regmap;3021 }3022 3023 if (reg & WM8996_GP1_FN_MASK)3024 regmap_update_bits(wm8996->regmap, WM8996_AIF1_TX_LRCLK_2,3025 WM8996_AIF1TX_LRCLK_MODE,3026 WM8996_AIF1TX_LRCLK_MODE);3027 3028 ret = regmap_read(wm8996->regmap, WM8996_GPIO_2, ®);3029 if (ret != 0) {3030 dev_err(&i2c->dev, "Failed to read GPIO2: %d\n", ret);3031 goto err_regmap;3032 }3033 3034 if (reg & WM8996_GP2_FN_MASK)3035 regmap_update_bits(wm8996->regmap, WM8996_AIF2_TX_LRCLK_2,3036 WM8996_AIF2TX_LRCLK_MODE,3037 WM8996_AIF2TX_LRCLK_MODE);3038 3039 wm8996_init_gpio(wm8996);3040 3041 ret = devm_snd_soc_register_component(&i2c->dev,3042 &soc_component_dev_wm8996, wm8996_dai,3043 ARRAY_SIZE(wm8996_dai));3044 if (ret < 0)3045 goto err_gpiolib;3046 3047 return ret;3048 3049err_gpiolib:3050 wm8996_free_gpio(wm8996);3051err_regmap:3052err_enable:3053 if (wm8996->ldo_ena)3054 gpiod_set_value_cansleep(wm8996->ldo_ena, 0);3055 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);3056err_gpio:3057err:3058 3059 return ret;3060}3061 3062static void wm8996_i2c_remove(struct i2c_client *client)3063{3064 struct wm8996_priv *wm8996 = i2c_get_clientdata(client);3065 3066 wm8996_free_gpio(wm8996);3067 if (wm8996->ldo_ena)3068 gpiod_set_value_cansleep(wm8996->ldo_ena, 0);3069}3070 3071static const struct i2c_device_id wm8996_i2c_id[] = {3072 { "wm8996" },3073 { }3074};3075MODULE_DEVICE_TABLE(i2c, wm8996_i2c_id);3076 3077static struct i2c_driver wm8996_i2c_driver = {3078 .driver = {3079 .name = "wm8996",3080 },3081 .probe = wm8996_i2c_probe,3082 .remove = wm8996_i2c_remove,3083 .id_table = wm8996_i2c_id,3084};3085 3086module_i2c_driver(wm8996_i2c_driver);3087 3088MODULE_DESCRIPTION("ASoC WM8996 driver");3089MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");3090MODULE_LICENSE("GPL");3091