brintos

brintos / linux-shallow public Read only

0
0
Text · 77.2 KiB · d0098b4 Raw
2474 lines · c
1// SPDX-License-Identifier: GPL-2.02//3// CS42L43 CODEC driver4//5// Copyright (C) 2022-2023 Cirrus Logic, Inc. and6//                         Cirrus Logic International Semiconductor Ltd.7 8#include <linux/bitops.h>9#include <linux/bits.h>10#include <linux/build_bug.h>11#include <linux/clk.h>12#include <linux/device.h>13#include <linux/err.h>14#include <linux/errno.h>15#include <linux/find.h>16#include <linux/gcd.h>17#include <linux/irq.h>18#include <linux/irqdomain.h>19#include <linux/jiffies.h>20#include <linux/mfd/cs42l43.h>21#include <linux/mfd/cs42l43-regs.h>22#include <linux/mod_devicetable.h>23#include <linux/module.h>24#include <linux/platform_device.h>25#include <linux/pm_runtime.h>26#include <linux/regmap.h>27#include <linux/string.h>28#include <linux/workqueue.h>29#include <sound/control.h>30#include <sound/cs42l43.h>31#include <sound/pcm.h>32#include <sound/pcm_params.h>33#include <sound/soc-component.h>34#include <sound/soc-dapm.h>35#include <sound/soc-dai.h>36#include <sound/soc.h>37#include <sound/tlv.h>38 39#include "cs42l43.h"40 41#define CS42L43_DECL_MUX(name, reg) \42static SOC_VALUE_ENUM_SINGLE_DECL(cs42l43_##name##_enum, reg, \43				  0, CS42L43_MIXER_SRC_MASK, \44				  cs42l43_mixer_texts, cs42l43_mixer_values); \45static const struct snd_kcontrol_new cs42l43_##name##_mux = \46		SOC_DAPM_ENUM("Route", cs42l43_##name##_enum)47 48#define CS42L43_DECL_MIXER(name, reg) \49	CS42L43_DECL_MUX(name##_in1, reg); \50	CS42L43_DECL_MUX(name##_in2, reg + 0x4); \51	CS42L43_DECL_MUX(name##_in3, reg + 0x8); \52	CS42L43_DECL_MUX(name##_in4, reg + 0xC)53 54#define CS42L43_DAPM_MUX(name_str, name) \55	SND_SOC_DAPM_MUX(name_str " Input", SND_SOC_NOPM, 0, 0, &cs42l43_##name##_mux)56 57#define CS42L43_DAPM_MIXER(name_str, name) \58	SND_SOC_DAPM_MUX(name_str " Input 1", SND_SOC_NOPM, 0, 0, &cs42l43_##name##_in1_mux), \59	SND_SOC_DAPM_MUX(name_str " Input 2", SND_SOC_NOPM, 0, 0, &cs42l43_##name##_in2_mux), \60	SND_SOC_DAPM_MUX(name_str " Input 3", SND_SOC_NOPM, 0, 0, &cs42l43_##name##_in3_mux), \61	SND_SOC_DAPM_MUX(name_str " Input 4", SND_SOC_NOPM, 0, 0, &cs42l43_##name##_in4_mux), \62	SND_SOC_DAPM_MIXER(name_str " Mixer", SND_SOC_NOPM, 0, 0, NULL, 0)63 64#define CS42L43_BASE_ROUTES(name_str) \65	{ name_str,		"Tone Generator 1",	"Tone 1" }, \66	{ name_str,		"Tone Generator 2",	"Tone 2" }, \67	{ name_str,		"Decimator 1",		"Decimator 1" }, \68	{ name_str,		"Decimator 2",		"Decimator 2" }, \69	{ name_str,		"Decimator 3",		"Decimator 3" }, \70	{ name_str,		"Decimator 4",		"Decimator 4" }, \71	{ name_str,		"ASPRX1",		"ASPRX1" }, \72	{ name_str,		"ASPRX2",		"ASPRX2" }, \73	{ name_str,		"ASPRX3",		"ASPRX3" }, \74	{ name_str,		"ASPRX4",		"ASPRX4" }, \75	{ name_str,		"ASPRX5",		"ASPRX5" }, \76	{ name_str,		"ASPRX6",		"ASPRX6" }, \77	{ name_str,		"DP5RX1",		"DP5RX1" }, \78	{ name_str,		"DP5RX2",		"DP5RX2" }, \79	{ name_str,		"DP6RX1",		"DP6RX1" }, \80	{ name_str,		"DP6RX2",		"DP6RX2" }, \81	{ name_str,		"DP7RX1",		"DP7RX1" }, \82	{ name_str,		"DP7RX2",		"DP7RX2" }, \83	{ name_str,		"ASRC INT1",		"ASRC_INT1" }, \84	{ name_str,		"ASRC INT2",		"ASRC_INT2" }, \85	{ name_str,		"ASRC INT3",		"ASRC_INT3" }, \86	{ name_str,		"ASRC INT4",		"ASRC_INT4" }, \87	{ name_str,		"ASRC DEC1",		"ASRC_DEC1" }, \88	{ name_str,		"ASRC DEC2",		"ASRC_DEC2" }, \89	{ name_str,		"ASRC DEC3",		"ASRC_DEC3" }, \90	{ name_str,		"ASRC DEC4",		"ASRC_DEC4" }, \91	{ name_str,		"ISRC1 INT1",		"ISRC1INT1" }, \92	{ name_str,		"ISRC1 INT2",		"ISRC1INT2" }, \93	{ name_str,		"ISRC1 DEC1",		"ISRC1DEC1" }, \94	{ name_str,		"ISRC1 DEC2",		"ISRC1DEC2" }, \95	{ name_str,		"ISRC2 INT1",		"ISRC2INT1" }, \96	{ name_str,		"ISRC2 INT2",		"ISRC2INT2" }, \97	{ name_str,		"ISRC2 DEC1",		"ISRC2DEC1" }, \98	{ name_str,		"ISRC2 DEC2",		"ISRC2DEC2" }, \99	{ name_str,		"EQ1",			"EQ" }, \100	{ name_str,		"EQ2",			"EQ" }101 102#define CS42L43_MUX_ROUTES(name_str, widget) \103	{ widget,		NULL,			name_str " Input" }, \104	{ name_str " Input",	NULL,			"Mixer Core" }, \105	CS42L43_BASE_ROUTES(name_str " Input")106 107#define CS42L43_MIXER_ROUTES(name_str, widget) \108	{ name_str " Mixer",	NULL,			name_str " Input 1" }, \109	{ name_str " Mixer",	NULL,			name_str " Input 2" }, \110	{ name_str " Mixer",	NULL,			name_str " Input 3" }, \111	{ name_str " Mixer",	NULL,			name_str " Input 4" }, \112	{ widget,		NULL,			name_str " Mixer" }, \113	{ name_str " Mixer",	NULL,			"Mixer Core" }, \114	CS42L43_BASE_ROUTES(name_str " Input 1"), \115	CS42L43_BASE_ROUTES(name_str " Input 2"), \116	CS42L43_BASE_ROUTES(name_str " Input 3"), \117	CS42L43_BASE_ROUTES(name_str " Input 4")118 119#define CS42L43_MIXER_VOLUMES(name_str, base) \120	SOC_SINGLE_RANGE_TLV(name_str " Input 1 Volume", base, \121			     CS42L43_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \122			     cs42l43_mixer_tlv), \123	SOC_SINGLE_RANGE_TLV(name_str " Input 2 Volume", base + 4, \124			     CS42L43_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \125			     cs42l43_mixer_tlv), \126	SOC_SINGLE_RANGE_TLV(name_str " Input 3 Volume", base + 8, \127			     CS42L43_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \128			     cs42l43_mixer_tlv), \129	SOC_SINGLE_RANGE_TLV(name_str " Input 4 Volume", base + 12, \130			     CS42L43_MIXER_VOL_SHIFT, 0x20, 0x50, 0, \131			     cs42l43_mixer_tlv)132 133#define CS42L43_IRQ_ERROR(name) \134static irqreturn_t cs42l43_##name(int irq, void *data) \135{ \136	struct cs42l43_codec *priv = data; \137	dev_err(priv->dev, "Error " #name " IRQ\n"); \138	return IRQ_HANDLED; \139}140 141CS42L43_IRQ_ERROR(pll_lost_lock)142CS42L43_IRQ_ERROR(spkr_clock_stop)143CS42L43_IRQ_ERROR(spkl_clock_stop)144CS42L43_IRQ_ERROR(spkr_brown_out)145CS42L43_IRQ_ERROR(spkl_brown_out)146CS42L43_IRQ_ERROR(spkr_therm_shutdown)147CS42L43_IRQ_ERROR(spkl_therm_shutdown)148CS42L43_IRQ_ERROR(spkr_therm_warm)149CS42L43_IRQ_ERROR(spkl_therm_warm)150CS42L43_IRQ_ERROR(spkr_sc_detect)151CS42L43_IRQ_ERROR(spkl_sc_detect)152 153static void cs42l43_hp_ilimit_clear_work(struct work_struct *work)154{155	struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,156						  hp_ilimit_clear_work.work);157	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(priv->component);158 159	snd_soc_dapm_mutex_lock(dapm);160 161	priv->hp_ilimit_count--;162 163	if (priv->hp_ilimit_count)164		queue_delayed_work(system_wq, &priv->hp_ilimit_clear_work,165				   msecs_to_jiffies(CS42L43_HP_ILIMIT_DECAY_MS));166 167	snd_soc_dapm_mutex_unlock(dapm);168}169 170static void cs42l43_hp_ilimit_work(struct work_struct *work)171{172	struct cs42l43_codec *priv = container_of(work, struct cs42l43_codec,173						  hp_ilimit_work);174	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(priv->component);175	struct cs42l43 *cs42l43 = priv->core;176 177	snd_soc_dapm_mutex_lock(dapm);178 179	if (priv->hp_ilimit_count < CS42L43_HP_ILIMIT_MAX_COUNT) {180		if (!priv->hp_ilimit_count)181			queue_delayed_work(system_wq, &priv->hp_ilimit_clear_work,182					   msecs_to_jiffies(CS42L43_HP_ILIMIT_DECAY_MS));183 184		priv->hp_ilimit_count++;185		snd_soc_dapm_mutex_unlock(dapm);186		return;187	}188 189	dev_err(priv->dev, "Disabling headphone for %dmS, due to frequent current limit\n",190		CS42L43_HP_ILIMIT_BACKOFF_MS);191 192	priv->hp_ilimited = true;193 194	// No need to wait for disable, as just disabling for a period of time195	regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,196			   CS42L43_HP_EN_MASK, 0);197 198	snd_soc_dapm_mutex_unlock(dapm);199 200	msleep(CS42L43_HP_ILIMIT_BACKOFF_MS);201 202	snd_soc_dapm_mutex_lock(dapm);203 204	if (priv->hp_ena && !priv->load_detect_running) {205		unsigned long time_left;206 207		reinit_completion(&priv->hp_startup);208 209		regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,210				   CS42L43_HP_EN_MASK, priv->hp_ena);211 212		time_left = wait_for_completion_timeout(&priv->hp_startup,213							msecs_to_jiffies(CS42L43_HP_TIMEOUT_MS));214		if (!time_left)215			dev_err(priv->dev, "ilimit HP restore timed out\n");216	}217 218	priv->hp_ilimited = false;219 220	snd_soc_dapm_mutex_unlock(dapm);221}222 223static irqreturn_t cs42l43_hp_ilimit(int irq, void *data)224{225	struct cs42l43_codec *priv = data;226 227	dev_dbg(priv->dev, "headphone ilimit IRQ\n");228 229	queue_work(system_long_wq, &priv->hp_ilimit_work);230 231	return IRQ_HANDLED;232}233 234#define CS42L43_IRQ_COMPLETE(name) \235static irqreturn_t cs42l43_##name(int irq, void *data) \236{ \237	struct cs42l43_codec *priv = data; \238	dev_dbg(priv->dev, #name " completed\n"); \239	complete(&priv->name); \240	return IRQ_HANDLED; \241}242 243CS42L43_IRQ_COMPLETE(pll_ready)244CS42L43_IRQ_COMPLETE(hp_startup)245CS42L43_IRQ_COMPLETE(hp_shutdown)246CS42L43_IRQ_COMPLETE(type_detect)247CS42L43_IRQ_COMPLETE(spkr_shutdown)248CS42L43_IRQ_COMPLETE(spkl_shutdown)249CS42L43_IRQ_COMPLETE(spkr_startup)250CS42L43_IRQ_COMPLETE(spkl_startup)251CS42L43_IRQ_COMPLETE(load_detect)252 253static irqreturn_t cs42l43_mic_shutter(int irq, void *data)254{255	struct cs42l43_codec *priv = data;256	struct snd_soc_component *component = priv->component;257	int i;258 259	dev_dbg(priv->dev, "Microphone shutter changed\n");260 261	if (!component)262		return IRQ_NONE;263 264	for (i = 1; i < ARRAY_SIZE(priv->kctl); i++) {265		if (!priv->kctl[i])266			return IRQ_NONE;267 268		snd_ctl_notify(component->card->snd_card,269			       SNDRV_CTL_EVENT_MASK_VALUE, &priv->kctl[i]->id);270	}271 272	return IRQ_HANDLED;273}274 275static irqreturn_t cs42l43_spk_shutter(int irq, void *data)276{277	struct cs42l43_codec *priv = data;278	struct snd_soc_component *component = priv->component;279 280	dev_dbg(priv->dev, "Speaker shutter changed\n");281 282	if (!component)283		return IRQ_NONE;284 285	if (!priv->kctl[0])286		return IRQ_NONE;287 288	snd_ctl_notify(component->card->snd_card,289		       SNDRV_CTL_EVENT_MASK_VALUE, &priv->kctl[0]->id);290 291	return IRQ_HANDLED;292}293 294static const unsigned int cs42l43_sample_rates[] = {295	8000, 16000, 24000, 32000, 44100, 48000, 96000, 192000,296};297 298#define CS42L43_CONSUMER_RATE_MASK 0xFF299#define CS42L43_PROVIDER_RATE_MASK 0xEF // 44.1k only supported as consumer300 301static const struct snd_pcm_hw_constraint_list cs42l43_constraint = {302	.count		= ARRAY_SIZE(cs42l43_sample_rates),303	.list		= cs42l43_sample_rates,304};305 306static int cs42l43_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai)307{308	struct snd_soc_component *component = dai->component;309	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);310	struct cs42l43 *cs42l43 = priv->core;311	int provider = !dai->id || !!regmap_test_bits(cs42l43->regmap,312						      CS42L43_ASP_CLK_CONFIG2,313						      CS42L43_ASP_MASTER_MODE_MASK);314 315	if (provider)316		priv->constraint.mask = CS42L43_PROVIDER_RATE_MASK;317	else318		priv->constraint.mask = CS42L43_CONSUMER_RATE_MASK;319 320	return snd_pcm_hw_constraint_list(substream->runtime, 0,321					  SNDRV_PCM_HW_PARAM_RATE,322					  &priv->constraint);323}324 325static int cs42l43_convert_sample_rate(unsigned int rate)326{327	switch (rate) {328	case 8000:329		return 0x11;330	case 16000:331		return 0x12;332	case 24000:333		return 0x02;334	case 32000:335		return 0x13;336	case 44100:337		return 0x0B;338	case 48000:339		return 0x03;340	case 96000:341		return 0x04;342	case 192000:343		return 0x05;344	default:345		return -EINVAL;346	}347}348 349static int cs42l43_set_sample_rate(struct snd_pcm_substream *substream,350				   struct snd_pcm_hw_params *params,351				   struct snd_soc_dai *dai)352{353	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(dai->component);354	struct cs42l43 *cs42l43 = priv->core;355	int ret;356 357	ret = cs42l43_convert_sample_rate(params_rate(params));358	if (ret < 0) {359		dev_err(priv->dev, "Failed to convert sample rate: %d\n", ret);360		return ret;361	}362 363	//FIXME: For now lets just set sample rate 1, this needs expanded in the future364	regmap_update_bits(cs42l43->regmap, CS42L43_SAMPLE_RATE1,365			   CS42L43_SAMPLE_RATE_MASK, ret);366 367	return 0;368}369 370static int cs42l43_asp_hw_params(struct snd_pcm_substream *substream,371				 struct snd_pcm_hw_params *params,372				 struct snd_soc_dai *dai)373{374	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(dai->component);375	struct cs42l43 *cs42l43 = priv->core;376	int dsp_mode = !!regmap_test_bits(cs42l43->regmap, CS42L43_ASP_CTRL,377					  CS42L43_ASP_FSYNC_MODE_MASK);378	int provider = !!regmap_test_bits(cs42l43->regmap, CS42L43_ASP_CLK_CONFIG2,379					  CS42L43_ASP_MASTER_MODE_MASK);380	int n_chans = params_channels(params);381	int data_width = params_width(params);382	int n_slots = n_chans;383	int slot_width = data_width;384	int frame, bclk_target, i;385	unsigned int reg;386	int *slots;387 388	if (priv->n_slots) {389		n_slots = priv->n_slots;390		slot_width = priv->slot_width;391	}392 393	if (!dsp_mode && (n_slots & 0x1)) {394		dev_dbg(priv->dev, "Forcing balanced channels on ASP\n");395		n_slots++;396	}397 398	frame = n_slots * slot_width;399	bclk_target = params_rate(params) * frame;400 401	if (provider) {402		unsigned int gcd_nm = gcd(bclk_target, CS42L43_INTERNAL_SYSCLK);403		int n = bclk_target / gcd_nm;404		int m = CS42L43_INTERNAL_SYSCLK / gcd_nm;405 406		if (n > (CS42L43_ASP_BCLK_N_MASK >> CS42L43_ASP_BCLK_N_SHIFT) ||407		    m > CS42L43_ASP_BCLK_M_MASK) {408			dev_err(priv->dev, "Can't produce %dHz bclk\n", bclk_target);409			return -EINVAL;410		}411 412		dev_dbg(priv->dev, "bclk %d/%d = %dHz, with %dx%d frame\n",413			n, m, bclk_target, n_slots, slot_width);414 415		regmap_update_bits(cs42l43->regmap, CS42L43_ASP_CLK_CONFIG1,416				   CS42L43_ASP_BCLK_N_MASK | CS42L43_ASP_BCLK_M_MASK,417				   n << CS42L43_ASP_BCLK_N_SHIFT |418				   m << CS42L43_ASP_BCLK_M_SHIFT);419		regmap_update_bits(cs42l43->regmap, CS42L43_ASP_FSYNC_CTRL1,420				   CS42L43_ASP_FSYNC_M_MASK, frame);421	}422 423	regmap_update_bits(cs42l43->regmap, CS42L43_ASP_FSYNC_CTRL4,424			   CS42L43_ASP_NUM_BCLKS_PER_FSYNC_MASK,425			   frame << CS42L43_ASP_NUM_BCLKS_PER_FSYNC_SHIFT);426 427	if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {428		reg = CS42L43_ASP_TX_CH1_CTRL;429		slots = priv->tx_slots;430	} else {431		reg = CS42L43_ASP_RX_CH1_CTRL;432		slots = priv->rx_slots;433	}434 435	for (i = 0; i < n_chans; i++, reg += 4) {436		int slot_phase = dsp_mode | (i & CS42L43_ASP_CH_SLOT_PHASE_MASK);437		int slot_pos;438 439		if (dsp_mode)440			slot_pos = slots[i] * slot_width;441		else442			slot_pos = (slots[i] / 2) * slot_width;443 444		dev_dbg(priv->dev, "Configure channel %d at slot %d (%d,%d)\n",445			i, slots[i], slot_pos, slot_phase);446 447		regmap_update_bits(cs42l43->regmap, reg,448				   CS42L43_ASP_CH_WIDTH_MASK |449				   CS42L43_ASP_CH_SLOT_MASK |450				   CS42L43_ASP_CH_SLOT_PHASE_MASK,451				   ((data_width - 1) << CS42L43_ASP_CH_WIDTH_SHIFT) |452				   (slot_pos << CS42L43_ASP_CH_SLOT_SHIFT) |453				   slot_phase);454	}455 456	return cs42l43_set_sample_rate(substream, params, dai);457}458 459static int cs42l43_asp_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)460{461	struct snd_soc_component *component = dai->component;462	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);463	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);464	struct cs42l43 *cs42l43 = priv->core;465	int provider = regmap_test_bits(cs42l43->regmap, CS42L43_ASP_CLK_CONFIG2,466					CS42L43_ASP_MASTER_MODE_MASK);467	struct snd_soc_dapm_route routes[] = {468		{ "BCLK", NULL, "FSYNC" },469	};470	unsigned int asp_ctrl = 0;471	unsigned int data_ctrl = 0;472	unsigned int fsync_ctrl = 0;473	unsigned int clk_config = 0;474 475	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {476	case SND_SOC_DAIFMT_DSP_A:477		data_ctrl |= 2 << CS42L43_ASP_FSYNC_FRAME_START_DLY_SHIFT;478		fallthrough;479	case SND_SOC_DAIFMT_DSP_B:480		asp_ctrl |= CS42L43_ASP_FSYNC_MODE_MASK;481		data_ctrl |= CS42L43_ASP_FSYNC_FRAME_START_PHASE_MASK;482		break;483	case SND_SOC_DAIFMT_I2S:484		data_ctrl |= 2 << CS42L43_ASP_FSYNC_FRAME_START_DLY_SHIFT;485		break;486	case SND_SOC_DAIFMT_LEFT_J:487		data_ctrl |= CS42L43_ASP_FSYNC_FRAME_START_PHASE_MASK;488		break;489	default:490		dev_err(priv->dev, "Unsupported DAI format 0x%x\n",491			fmt & SND_SOC_DAIFMT_FORMAT_MASK);492		return -EINVAL;493	}494 495	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {496	case SND_SOC_DAIFMT_CBC_CFC:497		if (provider)498			snd_soc_dapm_del_routes(dapm, routes, ARRAY_SIZE(routes));499		break;500	case SND_SOC_DAIFMT_CBP_CFP:501		if (!provider)502			snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes));503		clk_config |= CS42L43_ASP_MASTER_MODE_MASK;504		break;505	default:506		dev_err(priv->dev, "Unsupported ASP mode 0x%x\n",507			fmt & SND_SOC_DAIFMT_MASTER_MASK);508		return -EINVAL;509	}510 511	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {512	case SND_SOC_DAIFMT_NB_NF:513		clk_config |= CS42L43_ASP_BCLK_INV_MASK; /* Yes BCLK_INV = NB */514		break;515	case SND_SOC_DAIFMT_IB_NF:516		break;517	case SND_SOC_DAIFMT_NB_IF:518		clk_config |= CS42L43_ASP_BCLK_INV_MASK;519		fsync_ctrl |= CS42L43_ASP_FSYNC_IN_INV_MASK |520			      CS42L43_ASP_FSYNC_OUT_INV_MASK;521		break;522	case SND_SOC_DAIFMT_IB_IF:523		fsync_ctrl |= CS42L43_ASP_FSYNC_IN_INV_MASK |524			      CS42L43_ASP_FSYNC_OUT_INV_MASK;525		break;526	default:527		dev_err(priv->dev, "Unsupported invert mode 0x%x\n",528			fmt & SND_SOC_DAIFMT_INV_MASK);529		return -EINVAL;530	}531 532	regmap_update_bits(cs42l43->regmap, CS42L43_ASP_CTRL,533			   CS42L43_ASP_FSYNC_MODE_MASK,534			   asp_ctrl);535	regmap_update_bits(cs42l43->regmap, CS42L43_ASP_DATA_CTRL,536			   CS42L43_ASP_FSYNC_FRAME_START_DLY_MASK |537			   CS42L43_ASP_FSYNC_FRAME_START_PHASE_MASK,538			   data_ctrl);539	regmap_update_bits(cs42l43->regmap, CS42L43_ASP_CLK_CONFIG2,540			   CS42L43_ASP_MASTER_MODE_MASK |541			   CS42L43_ASP_BCLK_INV_MASK,542			   clk_config);543	regmap_update_bits(cs42l43->regmap, CS42L43_ASP_FSYNC_CTRL3,544			   CS42L43_ASP_FSYNC_IN_INV_MASK |545			   CS42L43_ASP_FSYNC_OUT_INV_MASK,546			   fsync_ctrl);547 548	return 0;549}550 551static void cs42l43_mask_to_slots(struct cs42l43_codec *priv, unsigned long mask,552				  int *slots, unsigned int nslots)553{554	int i = 0;555	int slot;556 557	for_each_set_bit(slot, &mask, BITS_PER_TYPE(mask)) {558		if (i == nslots) {559			dev_warn(priv->dev, "Too many channels in TDM mask: %lx\n",560				 mask);561			return;562		}563 564		slots[i++] = slot;565	}566 567}568 569static int cs42l43_asp_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,570				    unsigned int rx_mask, int slots, int slot_width)571{572	struct snd_soc_component *component = dai->component;573	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);574 575	priv->n_slots = slots;576	priv->slot_width = slot_width;577 578	if (!slots) {579		tx_mask = CS42L43_DEFAULT_SLOTS;580		rx_mask = CS42L43_DEFAULT_SLOTS;581	}582 583	cs42l43_mask_to_slots(priv, tx_mask, priv->tx_slots,584			      ARRAY_SIZE(priv->tx_slots));585	cs42l43_mask_to_slots(priv, rx_mask, priv->rx_slots,586			      ARRAY_SIZE(priv->rx_slots));587 588	return 0;589}590 591static int cs42l43_dai_probe(struct snd_soc_dai *dai)592{593	struct snd_soc_component *component = dai->component;594	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);595	static const char * const controls[] = {596		"Speaker Digital Switch",597		"Decimator 1 Switch",598		"Decimator 2 Switch",599		"Decimator 3 Switch",600		"Decimator 4 Switch",601	};602	int i;603 604	static_assert(ARRAY_SIZE(controls) == ARRAY_SIZE(priv->kctl));605 606	for (i = 0; i < ARRAY_SIZE(controls); i++) {607		if (priv->kctl[i])608			continue;609 610		priv->kctl[i] = snd_soc_component_get_kcontrol(component, controls[i]);611	}612 613	return 0;614}615 616static int cs42l43_dai_remove(struct snd_soc_dai *dai)617{618	struct snd_soc_component *component = dai->component;619	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);620	int i;621 622	for (i = 0; i < ARRAY_SIZE(priv->kctl); i++)623		priv->kctl[i] = NULL;624 625	return 0;626}627 628static const struct snd_soc_dai_ops cs42l43_asp_ops = {629	.probe		= cs42l43_dai_probe,630	.remove		= cs42l43_dai_remove,631	.startup	= cs42l43_startup,632	.hw_params	= cs42l43_asp_hw_params,633	.set_fmt	= cs42l43_asp_set_fmt,634	.set_tdm_slot	= cs42l43_asp_set_tdm_slot,635};636 637static int cs42l43_sdw_hw_params(struct snd_pcm_substream *substream,638				 struct snd_pcm_hw_params *params,639				 struct snd_soc_dai *dai)640{641	int ret;642 643	ret = cs42l43_sdw_add_peripheral(substream, params, dai);644	if (ret)645		return ret;646 647	return cs42l43_set_sample_rate(substream, params, dai);648}649 650static const struct snd_soc_dai_ops cs42l43_sdw_ops = {651	.probe		= cs42l43_dai_probe,652	.remove		= cs42l43_dai_remove,653	.startup	= cs42l43_startup,654	.set_stream	= cs42l43_sdw_set_stream,655	.hw_params	= cs42l43_sdw_hw_params,656	.hw_free	= cs42l43_sdw_remove_peripheral,657};658 659#define CS42L43_ASP_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \660			     SNDRV_PCM_FMTBIT_S32_LE)661#define CS42L43_SDW_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE)662 663static struct snd_soc_dai_driver cs42l43_dais[] = {664	{665		.name			= "cs42l43-asp",666		.ops			= &cs42l43_asp_ops,667		.symmetric_rate		= 1,668		.capture = {669			.stream_name	= "ASP Capture",670			.channels_min	= 1,671			.channels_max	= CS42L43_ASP_MAX_CHANNELS,672			.rates		= SNDRV_PCM_RATE_KNOT,673			.formats	= CS42L43_ASP_FORMATS,674		},675		.playback = {676			.stream_name	= "ASP Playback",677			.channels_min	= 1,678			.channels_max	= CS42L43_ASP_MAX_CHANNELS,679			.rates		= SNDRV_PCM_RATE_KNOT,680			.formats	= CS42L43_ASP_FORMATS,681		},682	},683	{684		.name			= "cs42l43-dp1",685		.id			= 1,686		.ops			= &cs42l43_sdw_ops,687		.capture = {688			.stream_name	= "DP1 Capture",689			.channels_min	= 1,690			.channels_max	= 4,691			.rates		= SNDRV_PCM_RATE_KNOT,692			.formats	= CS42L43_SDW_FORMATS,693		},694	},695	{696		.name			= "cs42l43-dp2",697		.id			= 2,698		.ops			= &cs42l43_sdw_ops,699		.capture = {700			.stream_name	= "DP2 Capture",701			.channels_min	= 1,702			.channels_max	= 2,703			.rates		= SNDRV_PCM_RATE_KNOT,704			.formats	= CS42L43_SDW_FORMATS,705		},706	},707	{708		.name			= "cs42l43-dp3",709		.id			= 3,710		.ops			= &cs42l43_sdw_ops,711		.capture = {712			.stream_name	= "DP3 Capture",713			.channels_min	= 1,714			.channels_max	= 2,715			.rates		= SNDRV_PCM_RATE_KNOT,716			.formats	= CS42L43_SDW_FORMATS,717		},718	},719	{720		.name			= "cs42l43-dp4",721		.id			= 4,722		.ops			= &cs42l43_sdw_ops,723		.capture = {724			.stream_name	= "DP4 Capture",725			.channels_min	= 1,726			.channels_max	= 2,727			.rates		= SNDRV_PCM_RATE_KNOT,728			.formats	= CS42L43_SDW_FORMATS,729		},730	},731	{732		.name			= "cs42l43-dp5",733		.id			= 5,734		.ops			= &cs42l43_sdw_ops,735		.playback = {736			.stream_name	= "DP5 Playback",737			.channels_min	= 1,738			.channels_max	= 2,739			.rates		= SNDRV_PCM_RATE_KNOT,740			.formats	= CS42L43_SDW_FORMATS,741		},742	},743	{744		.name			= "cs42l43-dp6",745		.id			= 6,746		.ops			= &cs42l43_sdw_ops,747		.playback = {748			.stream_name	= "DP6 Playback",749			.channels_min	= 1,750			.channels_max	= 2,751			.rates		= SNDRV_PCM_RATE_KNOT,752			.formats	= CS42L43_SDW_FORMATS,753		},754	},755	{756		.name			= "cs42l43-dp7",757		.id			= 7,758		.ops			= &cs42l43_sdw_ops,759		.playback = {760			.stream_name	= "DP7 Playback",761			.channels_min	= 1,762			.channels_max	= 2,763			.rates		= SNDRV_PCM_RATE_KNOT,764			.formats	= CS42L43_SDW_FORMATS,765		},766	},767};768 769static const DECLARE_TLV_DB_SCALE(cs42l43_mixer_tlv, -3200, 100, 0);770 771static const char * const cs42l43_ramp_text[] = {772	"0ms/6dB", "0.5ms/6dB", "1ms/6dB", "2ms/6dB", "4ms/6dB", "8ms/6dB",773	"15ms/6dB", "30ms/6dB",774};775 776static const char * const cs42l43_adc1_input_text[] = { "IN1", "IN2" };777 778static SOC_ENUM_SINGLE_DECL(cs42l43_adc1_input, CS42L43_ADC_B_CTRL1,779			    CS42L43_ADC_AIN_SEL_SHIFT,780			    cs42l43_adc1_input_text);781 782static const struct snd_kcontrol_new cs42l43_adc1_input_ctl =783	SOC_DAPM_ENUM("ADC1 Input", cs42l43_adc1_input);784 785static const char * const cs42l43_dec_mode_text[] = { "ADC", "PDM" };786 787static SOC_ENUM_SINGLE_VIRT_DECL(cs42l43_dec1_mode, cs42l43_dec_mode_text);788static SOC_ENUM_SINGLE_VIRT_DECL(cs42l43_dec2_mode, cs42l43_dec_mode_text);789 790static const struct snd_kcontrol_new cs42l43_dec_mode_ctl[] = {791	SOC_DAPM_ENUM("Decimator 1 Mode", cs42l43_dec1_mode),792	SOC_DAPM_ENUM("Decimator 2 Mode", cs42l43_dec2_mode),793};794 795static const char * const cs42l43_pdm_clk_text[] = {796	"3.072MHz", "1.536MHz", "768kHz",797};798 799static SOC_ENUM_SINGLE_DECL(cs42l43_pdm1_clk, CS42L43_PDM_CONTROL,800			    CS42L43_PDM1_CLK_DIV_SHIFT, cs42l43_pdm_clk_text);801static SOC_ENUM_SINGLE_DECL(cs42l43_pdm2_clk, CS42L43_PDM_CONTROL,802			    CS42L43_PDM2_CLK_DIV_SHIFT, cs42l43_pdm_clk_text);803 804static DECLARE_TLV_DB_SCALE(cs42l43_adc_tlv, -600, 600, 0);805static DECLARE_TLV_DB_SCALE(cs42l43_dec_tlv, -6400, 50, 0);806 807static const char * const cs42l43_wnf_corner_text[] = {808	"160Hz", "180Hz", "200Hz", "220Hz", "240Hz", "260Hz", "280Hz", "300Hz",809};810 811static SOC_ENUM_SINGLE_DECL(cs42l43_dec1_wnf_corner, CS42L43_DECIM_HPF_WNF_CTRL1,812			    CS42L43_DECIM_WNF_CF_SHIFT, cs42l43_wnf_corner_text);813static SOC_ENUM_SINGLE_DECL(cs42l43_dec2_wnf_corner, CS42L43_DECIM_HPF_WNF_CTRL2,814			    CS42L43_DECIM_WNF_CF_SHIFT, cs42l43_wnf_corner_text);815static SOC_ENUM_SINGLE_DECL(cs42l43_dec3_wnf_corner, CS42L43_DECIM_HPF_WNF_CTRL3,816			    CS42L43_DECIM_WNF_CF_SHIFT, cs42l43_wnf_corner_text);817static SOC_ENUM_SINGLE_DECL(cs42l43_dec4_wnf_corner, CS42L43_DECIM_HPF_WNF_CTRL4,818			    CS42L43_DECIM_WNF_CF_SHIFT, cs42l43_wnf_corner_text);819 820static const char * const cs42l43_hpf_corner_text[] = {821	"3Hz", "12Hz", "48Hz", "96Hz",822};823 824static SOC_ENUM_SINGLE_DECL(cs42l43_dec1_hpf_corner, CS42L43_DECIM_HPF_WNF_CTRL1,825			    CS42L43_DECIM_HPF_CF_SHIFT, cs42l43_hpf_corner_text);826static SOC_ENUM_SINGLE_DECL(cs42l43_dec2_hpf_corner, CS42L43_DECIM_HPF_WNF_CTRL2,827			    CS42L43_DECIM_HPF_CF_SHIFT, cs42l43_hpf_corner_text);828static SOC_ENUM_SINGLE_DECL(cs42l43_dec3_hpf_corner, CS42L43_DECIM_HPF_WNF_CTRL3,829			    CS42L43_DECIM_HPF_CF_SHIFT, cs42l43_hpf_corner_text);830static SOC_ENUM_SINGLE_DECL(cs42l43_dec4_hpf_corner, CS42L43_DECIM_HPF_WNF_CTRL4,831			    CS42L43_DECIM_HPF_CF_SHIFT, cs42l43_hpf_corner_text);832 833static SOC_ENUM_SINGLE_DECL(cs42l43_dec1_ramp_up, CS42L43_DECIM_VOL_CTRL_CH1_CH2,834			    CS42L43_DECIM1_VI_RAMP_SHIFT, cs42l43_ramp_text);835static SOC_ENUM_SINGLE_DECL(cs42l43_dec1_ramp_down, CS42L43_DECIM_VOL_CTRL_CH1_CH2,836			    CS42L43_DECIM1_VD_RAMP_SHIFT, cs42l43_ramp_text);837static SOC_ENUM_SINGLE_DECL(cs42l43_dec2_ramp_up, CS42L43_DECIM_VOL_CTRL_CH1_CH2,838			    CS42L43_DECIM2_VI_RAMP_SHIFT, cs42l43_ramp_text);839static SOC_ENUM_SINGLE_DECL(cs42l43_dec2_ramp_down, CS42L43_DECIM_VOL_CTRL_CH1_CH2,840			    CS42L43_DECIM2_VD_RAMP_SHIFT, cs42l43_ramp_text);841static SOC_ENUM_SINGLE_DECL(cs42l43_dec3_ramp_up, CS42L43_DECIM_VOL_CTRL_CH3_CH4,842			    CS42L43_DECIM3_VI_RAMP_SHIFT, cs42l43_ramp_text);843static SOC_ENUM_SINGLE_DECL(cs42l43_dec3_ramp_down, CS42L43_DECIM_VOL_CTRL_CH3_CH4,844			    CS42L43_DECIM3_VD_RAMP_SHIFT, cs42l43_ramp_text);845static SOC_ENUM_SINGLE_DECL(cs42l43_dec4_ramp_up, CS42L43_DECIM_VOL_CTRL_CH3_CH4,846			    CS42L43_DECIM4_VI_RAMP_SHIFT, cs42l43_ramp_text);847static SOC_ENUM_SINGLE_DECL(cs42l43_dec4_ramp_down, CS42L43_DECIM_VOL_CTRL_CH3_CH4,848			    CS42L43_DECIM4_VD_RAMP_SHIFT, cs42l43_ramp_text);849 850static DECLARE_TLV_DB_SCALE(cs42l43_speaker_tlv, -6400, 50, 0);851 852static SOC_ENUM_SINGLE_DECL(cs42l43_speaker_ramp_up, CS42L43_AMP1_2_VOL_RAMP,853			    CS42L43_AMP1_2_VI_RAMP_SHIFT, cs42l43_ramp_text);854 855static SOC_ENUM_SINGLE_DECL(cs42l43_speaker_ramp_down, CS42L43_AMP1_2_VOL_RAMP,856			    CS42L43_AMP1_2_VD_RAMP_SHIFT, cs42l43_ramp_text);857 858static DECLARE_TLV_DB_SCALE(cs42l43_headphone_tlv, -11450, 50, 1);859 860static const char * const cs42l43_headphone_ramp_text[] = {861	"1", "2", "4", "6", "8", "11", "12", "16", "22", "24", "33", "36", "44",862	"48", "66", "72",863};864 865static SOC_ENUM_SINGLE_DECL(cs42l43_headphone_ramp, CS42L43_PGAVOL,866			    CS42L43_HP_PATH_VOL_RAMP_SHIFT,867			    cs42l43_headphone_ramp_text);868 869static const char * const cs42l43_tone_freq_text[] = {870	"1kHz", "2kHz", "4kHz", "6kHz", "8kHz",871};872 873static SOC_ENUM_SINGLE_DECL(cs42l43_tone1_freq, CS42L43_TONE_CH1_CTRL,874			    CS42L43_TONE_FREQ_SHIFT, cs42l43_tone_freq_text);875 876static SOC_ENUM_SINGLE_DECL(cs42l43_tone2_freq, CS42L43_TONE_CH2_CTRL,877			    CS42L43_TONE_FREQ_SHIFT, cs42l43_tone_freq_text);878 879static const char * const cs42l43_mixer_texts[] = {880	"None",881	"Tone Generator 1", "Tone Generator 2",882	"Decimator 1", "Decimator 2", "Decimator 3", "Decimator 4",883	"ASPRX1", "ASPRX2", "ASPRX3", "ASPRX4", "ASPRX5", "ASPRX6",884	"DP5RX1", "DP5RX2", "DP6RX1", "DP6RX2", "DP7RX1", "DP7RX2",885	"ASRC INT1", "ASRC INT2", "ASRC INT3", "ASRC INT4",886	"ASRC DEC1", "ASRC DEC2", "ASRC DEC3", "ASRC DEC4",887	"ISRC1 INT1", "ISRC1 INT2",888	"ISRC1 DEC1", "ISRC1 DEC2",889	"ISRC2 INT1", "ISRC2 INT2",890	"ISRC2 DEC1", "ISRC2 DEC2",891	"EQ1", "EQ2",892};893 894static const unsigned int cs42l43_mixer_values[] = {895	0x00, // None896	0x04, 0x05, // Tone Generator 1, 2897	0x10, 0x11, 0x12, 0x13, // Decimator 1, 2, 3, 4898	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, // ASPRX1,2,3,4,5,6899	0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, // DP5, 6, 7RX1, 2900	0x40, 0x41, 0x42, 0x43, // ASRC INT1, 2, 3, 4901	0x44, 0x45, 0x46, 0x47, // ASRC DEC1, 2, 3, 4902	0x50, 0x51, // ISRC1 INT1, 2903	0x52, 0x53, // ISRC1 DEC1, 2904	0x54, 0x55, // ISRC2 INT1, 2905	0x56, 0x57, // ISRC2 DEC1, 2906	0x58, 0x59, // EQ1, 2907};908 909CS42L43_DECL_MUX(asptx1, CS42L43_ASPTX1_INPUT);910CS42L43_DECL_MUX(asptx2, CS42L43_ASPTX2_INPUT);911CS42L43_DECL_MUX(asptx3, CS42L43_ASPTX3_INPUT);912CS42L43_DECL_MUX(asptx4, CS42L43_ASPTX4_INPUT);913CS42L43_DECL_MUX(asptx5, CS42L43_ASPTX5_INPUT);914CS42L43_DECL_MUX(asptx6, CS42L43_ASPTX6_INPUT);915 916CS42L43_DECL_MUX(dp1tx1, CS42L43_SWIRE_DP1_CH1_INPUT);917CS42L43_DECL_MUX(dp1tx2, CS42L43_SWIRE_DP1_CH2_INPUT);918CS42L43_DECL_MUX(dp1tx3, CS42L43_SWIRE_DP1_CH3_INPUT);919CS42L43_DECL_MUX(dp1tx4, CS42L43_SWIRE_DP1_CH4_INPUT);920CS42L43_DECL_MUX(dp2tx1, CS42L43_SWIRE_DP2_CH1_INPUT);921CS42L43_DECL_MUX(dp2tx2, CS42L43_SWIRE_DP2_CH2_INPUT);922CS42L43_DECL_MUX(dp3tx1, CS42L43_SWIRE_DP3_CH1_INPUT);923CS42L43_DECL_MUX(dp3tx2, CS42L43_SWIRE_DP3_CH2_INPUT);924CS42L43_DECL_MUX(dp4tx1, CS42L43_SWIRE_DP4_CH1_INPUT);925CS42L43_DECL_MUX(dp4tx2, CS42L43_SWIRE_DP4_CH2_INPUT);926 927CS42L43_DECL_MUX(asrcint1, CS42L43_ASRC_INT1_INPUT1);928CS42L43_DECL_MUX(asrcint2, CS42L43_ASRC_INT2_INPUT1);929CS42L43_DECL_MUX(asrcint3, CS42L43_ASRC_INT3_INPUT1);930CS42L43_DECL_MUX(asrcint4, CS42L43_ASRC_INT4_INPUT1);931CS42L43_DECL_MUX(asrcdec1, CS42L43_ASRC_DEC1_INPUT1);932CS42L43_DECL_MUX(asrcdec2, CS42L43_ASRC_DEC2_INPUT1);933CS42L43_DECL_MUX(asrcdec3, CS42L43_ASRC_DEC3_INPUT1);934CS42L43_DECL_MUX(asrcdec4, CS42L43_ASRC_DEC4_INPUT1);935 936CS42L43_DECL_MUX(isrc1int1, CS42L43_ISRC1INT1_INPUT1);937CS42L43_DECL_MUX(isrc1int2, CS42L43_ISRC1INT2_INPUT1);938CS42L43_DECL_MUX(isrc1dec1, CS42L43_ISRC1DEC1_INPUT1);939CS42L43_DECL_MUX(isrc1dec2, CS42L43_ISRC1DEC2_INPUT1);940CS42L43_DECL_MUX(isrc2int1, CS42L43_ISRC2INT1_INPUT1);941CS42L43_DECL_MUX(isrc2int2, CS42L43_ISRC2INT2_INPUT1);942CS42L43_DECL_MUX(isrc2dec1, CS42L43_ISRC2DEC1_INPUT1);943CS42L43_DECL_MUX(isrc2dec2, CS42L43_ISRC2DEC2_INPUT1);944 945CS42L43_DECL_MUX(spdif1, CS42L43_SPDIF1_INPUT1);946CS42L43_DECL_MUX(spdif2, CS42L43_SPDIF2_INPUT1);947 948CS42L43_DECL_MIXER(eq1, CS42L43_EQ1MIX_INPUT1);949CS42L43_DECL_MIXER(eq2, CS42L43_EQ2MIX_INPUT1);950 951CS42L43_DECL_MIXER(amp1, CS42L43_AMP1MIX_INPUT1);952CS42L43_DECL_MIXER(amp2, CS42L43_AMP2MIX_INPUT1);953 954CS42L43_DECL_MIXER(amp3, CS42L43_AMP3MIX_INPUT1);955CS42L43_DECL_MIXER(amp4, CS42L43_AMP4MIX_INPUT1);956 957static int cs42l43_dapm_get_volsw(struct snd_kcontrol *kcontrol,958				  struct snd_ctl_elem_value *ucontrol)959{960	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);961	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);962	int ret;963 964	snd_soc_dapm_mutex_lock(dapm);965	ret = snd_soc_get_volsw(kcontrol, ucontrol);966	snd_soc_dapm_mutex_unlock(dapm);967 968	return ret;969}970 971static int cs42l43_dapm_put_volsw(struct snd_kcontrol *kcontrol,972				  struct snd_ctl_elem_value *ucontrol)973{974	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);975	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);976	int ret;977 978	snd_soc_dapm_mutex_lock(dapm);979	ret = snd_soc_put_volsw(kcontrol, ucontrol);980	snd_soc_dapm_mutex_unlock(dapm);981 982	return ret;983}984 985static int cs42l43_dapm_get_enum(struct snd_kcontrol *kcontrol,986				 struct snd_ctl_elem_value *ucontrol)987{988	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);989	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);990	int ret;991 992	snd_soc_dapm_mutex_lock(dapm);993	ret = snd_soc_get_enum_double(kcontrol, ucontrol);994	snd_soc_dapm_mutex_unlock(dapm);995 996	return ret;997}998 999static int cs42l43_dapm_put_enum(struct snd_kcontrol *kcontrol,1000				 struct snd_ctl_elem_value *ucontrol)1001{1002	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1003	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);1004	int ret;1005 1006	snd_soc_dapm_mutex_lock(dapm);1007	ret = snd_soc_put_enum_double(kcontrol, ucontrol);1008	snd_soc_dapm_mutex_unlock(dapm);1009 1010	return ret;1011}1012 1013static int cs42l43_eq_get(struct snd_kcontrol *kcontrol,1014			  struct snd_ctl_elem_value *ucontrol)1015{1016	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1017	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);1018 1019	memcpy(ucontrol->value.integer.value, priv->eq_coeffs, sizeof(priv->eq_coeffs));1020 1021	return 0;1022}1023 1024static int cs42l43_eq_put(struct snd_kcontrol *kcontrol,1025			  struct snd_ctl_elem_value *ucontrol)1026{1027	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1028	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);1029	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);1030 1031	snd_soc_dapm_mutex_lock(dapm);1032 1033	memcpy(priv->eq_coeffs, ucontrol->value.integer.value, sizeof(priv->eq_coeffs));1034 1035	snd_soc_dapm_mutex_unlock(dapm);1036 1037	return 0;1038}1039 1040static void cs42l43_spk_vu_sync(struct cs42l43_codec *priv)1041{1042	struct cs42l43 *cs42l43 = priv->core;1043 1044	mutex_lock(&priv->spk_vu_lock);1045 1046	regmap_update_bits(cs42l43->regmap, CS42L43_INTP_VOLUME_CTRL1,1047			   CS42L43_AMP1_2_VU_MASK, CS42L43_AMP1_2_VU_MASK);1048	regmap_update_bits(cs42l43->regmap, CS42L43_INTP_VOLUME_CTRL1,1049			   CS42L43_AMP1_2_VU_MASK, 0);1050 1051	mutex_unlock(&priv->spk_vu_lock);1052}1053 1054static int cs42l43_shutter_get(struct cs42l43_codec *priv, unsigned int shift)1055{1056	struct cs42l43 *cs42l43 = priv->core;1057	unsigned int val;1058	int ret;1059 1060	ret = pm_runtime_resume_and_get(priv->dev);1061	if (ret) {1062		dev_err(priv->dev, "Failed to resume for shutters: %d\n", ret);1063		return ret;1064	}1065 1066	/*1067	 * SHUTTER_CONTROL is a mix of volatile and non-volatile bits, so must1068	 * be cached for the non-volatiles, so drop it from the cache here so1069	 * we force a read.1070	 */1071	ret = regcache_drop_region(cs42l43->regmap, CS42L43_SHUTTER_CONTROL,1072				   CS42L43_SHUTTER_CONTROL);1073	if (ret) {1074		dev_err(priv->dev, "Failed to drop shutter from cache: %d\n", ret);1075		goto error;1076	}1077 1078	ret = regmap_read(cs42l43->regmap, CS42L43_SHUTTER_CONTROL, &val);1079	if (ret) {1080		dev_err(priv->dev, "Failed to check shutter status: %d\n", ret);1081		goto error;1082	}1083 1084	ret = !(val & BIT(shift));1085 1086	dev_dbg(priv->dev, "%s shutter is %s\n",1087		BIT(shift) == CS42L43_STATUS_MIC_SHUTTER_MUTE_MASK ? "Mic" : "Speaker",1088		ret ? "open" : "closed");1089 1090error:1091	pm_runtime_mark_last_busy(priv->dev);1092	pm_runtime_put_autosuspend(priv->dev);1093 1094	return ret;1095}1096 1097static int cs42l43_decim_get(struct snd_kcontrol *kcontrol,1098			     struct snd_ctl_elem_value *ucontrol)1099{1100	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1101	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);1102	int ret;1103 1104	ret = cs42l43_shutter_get(priv, CS42L43_STATUS_MIC_SHUTTER_MUTE_SHIFT);1105	if (ret > 0)1106		ret = cs42l43_dapm_get_volsw(kcontrol, ucontrol);1107	else if (!ret)1108		ucontrol->value.integer.value[0] = ret;1109 1110	return ret;1111}1112 1113static int cs42l43_spk_get(struct snd_kcontrol *kcontrol,1114			   struct snd_ctl_elem_value *ucontrol)1115{1116	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1117	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);1118	int ret;1119 1120	ret = cs42l43_shutter_get(priv, CS42L43_STATUS_SPK_SHUTTER_MUTE_SHIFT);1121	if (ret > 0)1122		ret = snd_soc_get_volsw(kcontrol, ucontrol);1123	else if (!ret)1124		ucontrol->value.integer.value[0] = ret;1125 1126	return ret;1127}1128 1129static int cs42l43_spk_put(struct snd_kcontrol *kcontrol,1130			   struct snd_ctl_elem_value *ucontrol)1131{1132	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1133	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);1134	int ret;1135 1136	ret = snd_soc_put_volsw(kcontrol, ucontrol);1137	if (ret > 0)1138		cs42l43_spk_vu_sync(priv);1139 1140	return ret;1141}1142 1143static const struct snd_kcontrol_new cs42l43_controls[] = {1144	SOC_ENUM_EXT("Jack Override", cs42l43_jack_enum,1145		     cs42l43_jack_get, cs42l43_jack_put),1146 1147	SOC_DOUBLE_R_SX_TLV("ADC Volume", CS42L43_ADC_B_CTRL1, CS42L43_ADC_B_CTRL2,1148			    CS42L43_ADC_PGA_GAIN_SHIFT,1149			    0xF, 5, cs42l43_adc_tlv),1150 1151	SOC_DOUBLE("PDM1 Invert Switch", CS42L43_DMIC_PDM_CTRL,1152		   CS42L43_PDM1L_INV_SHIFT, CS42L43_PDM1R_INV_SHIFT, 1, 0),1153	SOC_DOUBLE("PDM2 Invert Switch", CS42L43_DMIC_PDM_CTRL,1154		   CS42L43_PDM2L_INV_SHIFT, CS42L43_PDM2R_INV_SHIFT, 1, 0),1155	SOC_ENUM("PDM1 Clock", cs42l43_pdm1_clk),1156	SOC_ENUM("PDM2 Clock", cs42l43_pdm2_clk),1157 1158	SOC_SINGLE("Decimator 1 WNF Switch", CS42L43_DECIM_HPF_WNF_CTRL1,1159		   CS42L43_DECIM_WNF_EN_SHIFT, 1, 0),1160	SOC_SINGLE("Decimator 2 WNF Switch", CS42L43_DECIM_HPF_WNF_CTRL2,1161		   CS42L43_DECIM_WNF_EN_SHIFT, 1, 0),1162	SOC_SINGLE("Decimator 3 WNF Switch", CS42L43_DECIM_HPF_WNF_CTRL3,1163		   CS42L43_DECIM_WNF_EN_SHIFT, 1, 0),1164	SOC_SINGLE("Decimator 4 WNF Switch", CS42L43_DECIM_HPF_WNF_CTRL4,1165		   CS42L43_DECIM_WNF_EN_SHIFT, 1, 0),1166 1167	SOC_ENUM("Decimator 1 WNF Corner Frequency", cs42l43_dec1_wnf_corner),1168	SOC_ENUM("Decimator 2 WNF Corner Frequency", cs42l43_dec2_wnf_corner),1169	SOC_ENUM("Decimator 3 WNF Corner Frequency", cs42l43_dec3_wnf_corner),1170	SOC_ENUM("Decimator 4 WNF Corner Frequency", cs42l43_dec4_wnf_corner),1171 1172	SOC_SINGLE("Decimator 1 HPF Switch", CS42L43_DECIM_HPF_WNF_CTRL1,1173		   CS42L43_DECIM_HPF_EN_SHIFT, 1, 0),1174	SOC_SINGLE("Decimator 2 HPF Switch", CS42L43_DECIM_HPF_WNF_CTRL2,1175		   CS42L43_DECIM_HPF_EN_SHIFT, 1, 0),1176	SOC_SINGLE("Decimator 3 HPF Switch", CS42L43_DECIM_HPF_WNF_CTRL3,1177		   CS42L43_DECIM_HPF_EN_SHIFT, 1, 0),1178	SOC_SINGLE("Decimator 4 HPF Switch", CS42L43_DECIM_HPF_WNF_CTRL4,1179		   CS42L43_DECIM_HPF_EN_SHIFT, 1, 0),1180 1181	SOC_ENUM("Decimator 1 HPF Corner Frequency", cs42l43_dec1_hpf_corner),1182	SOC_ENUM("Decimator 2 HPF Corner Frequency", cs42l43_dec2_hpf_corner),1183	SOC_ENUM("Decimator 3 HPF Corner Frequency", cs42l43_dec3_hpf_corner),1184	SOC_ENUM("Decimator 4 HPF Corner Frequency", cs42l43_dec4_hpf_corner),1185 1186	SOC_SINGLE_TLV("Decimator 1 Volume", CS42L43_DECIM_VOL_CTRL_CH1_CH2,1187		       CS42L43_DECIM1_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),1188	SOC_SINGLE_EXT("Decimator 1 Switch", CS42L43_DECIM_VOL_CTRL_CH1_CH2,1189		       CS42L43_DECIM1_MUTE_SHIFT, 1, 1,1190		       cs42l43_decim_get, cs42l43_dapm_put_volsw),1191	SOC_SINGLE_TLV("Decimator 2 Volume", CS42L43_DECIM_VOL_CTRL_CH1_CH2,1192		       CS42L43_DECIM2_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),1193	SOC_SINGLE_EXT("Decimator 2 Switch", CS42L43_DECIM_VOL_CTRL_CH1_CH2,1194		       CS42L43_DECIM2_MUTE_SHIFT, 1, 1,1195		       cs42l43_decim_get, cs42l43_dapm_put_volsw),1196	SOC_SINGLE_TLV("Decimator 3 Volume", CS42L43_DECIM_VOL_CTRL_CH3_CH4,1197		       CS42L43_DECIM3_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),1198	SOC_SINGLE_EXT("Decimator 3 Switch", CS42L43_DECIM_VOL_CTRL_CH3_CH4,1199		       CS42L43_DECIM3_MUTE_SHIFT, 1, 1,1200		       cs42l43_decim_get, cs42l43_dapm_put_volsw),1201	SOC_SINGLE_TLV("Decimator 4 Volume", CS42L43_DECIM_VOL_CTRL_CH3_CH4,1202		       CS42L43_DECIM4_VOL_SHIFT, 0xBF, 0, cs42l43_dec_tlv),1203	SOC_SINGLE_EXT("Decimator 4 Switch", CS42L43_DECIM_VOL_CTRL_CH3_CH4,1204		       CS42L43_DECIM4_MUTE_SHIFT, 1, 1,1205		       cs42l43_decim_get, cs42l43_dapm_put_volsw),1206 1207	SOC_ENUM_EXT("Decimator 1 Ramp Up", cs42l43_dec1_ramp_up,1208		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),1209	SOC_ENUM_EXT("Decimator 1 Ramp Down", cs42l43_dec1_ramp_down,1210		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),1211	SOC_ENUM_EXT("Decimator 2 Ramp Up", cs42l43_dec2_ramp_up,1212		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),1213	SOC_ENUM_EXT("Decimator 2 Ramp Down", cs42l43_dec2_ramp_down,1214		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),1215	SOC_ENUM_EXT("Decimator 3 Ramp Up", cs42l43_dec3_ramp_up,1216		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),1217	SOC_ENUM_EXT("Decimator 3 Ramp Down", cs42l43_dec3_ramp_down,1218		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),1219	SOC_ENUM_EXT("Decimator 4 Ramp Up", cs42l43_dec4_ramp_up,1220		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),1221	SOC_ENUM_EXT("Decimator 4 Ramp Down", cs42l43_dec4_ramp_down,1222		     cs42l43_dapm_get_enum, cs42l43_dapm_put_enum),1223 1224	SOC_DOUBLE_R_EXT("Speaker Digital Switch",1225			 CS42L43_INTP_VOLUME_CTRL1, CS42L43_INTP_VOLUME_CTRL2,1226			 CS42L43_AMP_MUTE_SHIFT, 1, 1,1227			 cs42l43_spk_get, cs42l43_spk_put),1228 1229	SOC_DOUBLE_R_EXT_TLV("Speaker Digital Volume",1230			     CS42L43_INTP_VOLUME_CTRL1, CS42L43_INTP_VOLUME_CTRL2,1231			     CS42L43_AMP_VOL_SHIFT,1232			     0xBF, 0, snd_soc_get_volsw, cs42l43_spk_put,1233			     cs42l43_speaker_tlv),1234 1235	SOC_ENUM("Speaker Ramp Up", cs42l43_speaker_ramp_up),1236	SOC_ENUM("Speaker Ramp Down", cs42l43_speaker_ramp_down),1237 1238	CS42L43_MIXER_VOLUMES("Speaker L", CS42L43_AMP1MIX_INPUT1),1239	CS42L43_MIXER_VOLUMES("Speaker R", CS42L43_AMP2MIX_INPUT1),1240 1241	SOC_DOUBLE_SX_TLV("Headphone Digital Volume", CS42L43_HPPATHVOL,1242			  CS42L43_AMP3_PATH_VOL_SHIFT, CS42L43_AMP4_PATH_VOL_SHIFT,1243			  0x11B, 229, cs42l43_headphone_tlv),1244 1245	SOC_DOUBLE("Headphone Invert Switch", CS42L43_DACCNFG1,1246		   CS42L43_AMP3_INV_SHIFT, CS42L43_AMP4_INV_SHIFT, 1, 0),1247 1248	SOC_SINGLE("Headphone Zero Cross Switch", CS42L43_PGAVOL,1249		   CS42L43_HP_PATH_VOL_ZC_SHIFT, 1, 0),1250	SOC_SINGLE("Headphone Ramp Switch", CS42L43_PGAVOL,1251		   CS42L43_HP_PATH_VOL_SFT_SHIFT, 1, 0),1252	SOC_ENUM("Headphone Ramp Rate", cs42l43_headphone_ramp),1253 1254	CS42L43_MIXER_VOLUMES("Headphone L", CS42L43_AMP3MIX_INPUT1),1255	CS42L43_MIXER_VOLUMES("Headphone R", CS42L43_AMP4MIX_INPUT1),1256 1257	SOC_ENUM("Tone 1 Frequency", cs42l43_tone1_freq),1258	SOC_ENUM("Tone 2 Frequency", cs42l43_tone2_freq),1259 1260	SOC_DOUBLE_EXT("EQ Switch",1261		       CS42L43_MUTE_EQ_IN0, CS42L43_MUTE_EQ_CH1_SHIFT,1262		       CS42L43_MUTE_EQ_CH2_SHIFT, 1, 1,1263		       cs42l43_dapm_get_volsw, cs42l43_dapm_put_volsw),1264 1265	SND_SOC_BYTES_E("EQ Coefficients", 0, CS42L43_N_EQ_COEFFS,1266			cs42l43_eq_get, cs42l43_eq_put),1267 1268	CS42L43_MIXER_VOLUMES("EQ1", CS42L43_EQ1MIX_INPUT1),1269	CS42L43_MIXER_VOLUMES("EQ2", CS42L43_EQ2MIX_INPUT1),1270};1271 1272static int cs42l43_eq_ev(struct snd_soc_dapm_widget *w,1273			 struct snd_kcontrol *kcontrol, int event)1274{1275	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1276	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);1277	struct cs42l43 *cs42l43 = priv->core;1278	unsigned int val;1279	int i, ret;1280 1281	switch (event) {1282	case SND_SOC_DAPM_PRE_PMU:1283		regmap_update_bits(cs42l43->regmap, CS42L43_MUTE_EQ_IN0,1284				   CS42L43_MUTE_EQ_CH1_MASK | CS42L43_MUTE_EQ_CH2_MASK,1285				   CS42L43_MUTE_EQ_CH1_MASK | CS42L43_MUTE_EQ_CH2_MASK);1286 1287		regmap_update_bits(cs42l43->regmap, CS42L43_COEFF_RD_WR0,1288				   CS42L43_WRITE_MODE_MASK, CS42L43_WRITE_MODE_MASK);1289 1290		for (i = 0; i < CS42L43_N_EQ_COEFFS; i++)1291			regmap_write(cs42l43->regmap, CS42L43_COEFF_DATA_IN0,1292				     priv->eq_coeffs[i]);1293 1294		regmap_update_bits(cs42l43->regmap, CS42L43_COEFF_RD_WR0,1295				   CS42L43_WRITE_MODE_MASK, 0);1296 1297		return 0;1298	case SND_SOC_DAPM_POST_PMU:1299		ret = regmap_read_poll_timeout(cs42l43->regmap, CS42L43_INIT_DONE0,1300					       val, (val & CS42L43_INITIALIZE_DONE_MASK),1301					       2000, 10000);1302		if (ret)1303			dev_err(priv->dev, "Failed to start EQs: %d\n", ret);1304 1305		regmap_update_bits(cs42l43->regmap, CS42L43_MUTE_EQ_IN0,1306				   CS42L43_MUTE_EQ_CH1_MASK | CS42L43_MUTE_EQ_CH2_MASK, 0);1307		return ret;1308	default:1309		return 0;1310	}1311}1312 1313struct cs42l43_pll_config {1314	unsigned int freq;1315 1316	unsigned int div;1317	unsigned int mode;1318	unsigned int cal;1319};1320 1321static const struct cs42l43_pll_config cs42l43_pll_configs[] = {1322	{ 2400000, 0x50000000, 0x1, 0xA4 },1323	{ 3000000, 0x40000000, 0x1, 0x83 },1324	{ 3072000, 0x40000000, 0x3, 0x80 },1325};1326 1327static int cs42l43_set_pll(struct cs42l43_codec *priv, unsigned int src,1328			   unsigned int freq)1329{1330	struct cs42l43 *cs42l43 = priv->core;1331 1332	lockdep_assert_held(&cs42l43->pll_lock);1333 1334	if (priv->refclk_src == src && priv->refclk_freq == freq)1335		return 0;1336 1337	if (regmap_test_bits(cs42l43->regmap, CS42L43_CTRL_REG, CS42L43_PLL_EN_MASK)) {1338		dev_err(priv->dev, "PLL active, can't change configuration\n");1339		return -EBUSY;1340	}1341 1342	switch (src) {1343	case CS42L43_SYSCLK_MCLK:1344	case CS42L43_SYSCLK_SDW:1345		dev_dbg(priv->dev, "Source PLL from %s at %uHz\n",1346			src ? "SoundWire" : "MCLK", freq);1347 1348		priv->refclk_src = src;1349		priv->refclk_freq = freq;1350 1351		return 0;1352	default:1353		dev_err(priv->dev, "Invalid PLL source: 0x%x\n", src);1354		return -EINVAL;1355	}1356}1357 1358static int cs42l43_enable_pll(struct cs42l43_codec *priv)1359{1360	static const struct reg_sequence enable_seq[] = {1361		{ CS42L43_OSC_DIV_SEL, 0x0, },1362		{ CS42L43_MCLK_SRC_SEL, CS42L43_OSC_PLL_MCLK_SEL_MASK, 5, },1363	};1364	struct cs42l43 *cs42l43 = priv->core;1365	const struct cs42l43_pll_config *config = NULL;1366	unsigned int div = 0;1367	unsigned int freq = priv->refclk_freq;1368	unsigned long time_left;1369 1370	lockdep_assert_held(&cs42l43->pll_lock);1371 1372	if (priv->refclk_src == CS42L43_SYSCLK_SDW) {1373		if (!freq)1374			freq = cs42l43->sdw_freq;1375		else if (!cs42l43->sdw_freq)1376			cs42l43->sdw_freq = freq;1377	}1378 1379	dev_dbg(priv->dev, "Enabling PLL at %uHz\n", freq);1380 1381	div = fls(freq) -1382	      fls(cs42l43_pll_configs[ARRAY_SIZE(cs42l43_pll_configs) - 1].freq);1383	freq >>= div;1384 1385	if (div <= CS42L43_PLL_REFCLK_DIV_MASK) {1386		int i;1387 1388		for (i = 0; i < ARRAY_SIZE(cs42l43_pll_configs); i++) {1389			if (freq == cs42l43_pll_configs[i].freq) {1390				config = &cs42l43_pll_configs[i];1391				break;1392			}1393		}1394	}1395 1396	if (!config) {1397		dev_err(priv->dev, "No suitable PLL config: 0x%x, %uHz\n", div, freq);1398		return -EINVAL;1399	}1400 1401	regmap_update_bits(cs42l43->regmap, CS42L43_PLL_CONTROL,1402			   CS42L43_PLL_REFCLK_DIV_MASK | CS42L43_PLL_REFCLK_SRC_MASK,1403			   div << CS42L43_PLL_REFCLK_DIV_SHIFT |1404			   priv->refclk_src << CS42L43_PLL_REFCLK_SRC_SHIFT);1405	regmap_write(cs42l43->regmap, CS42L43_FDIV_FRAC, config->div);1406	regmap_update_bits(cs42l43->regmap, CS42L43_CTRL_REG,1407			   CS42L43_PLL_MODE_BYPASS_500_MASK |1408			   CS42L43_PLL_MODE_BYPASS_1029_MASK,1409			   config->mode << CS42L43_PLL_MODE_BYPASS_1029_SHIFT);1410	regmap_update_bits(cs42l43->regmap, CS42L43_CAL_RATIO,1411			   CS42L43_PLL_CAL_RATIO_MASK, config->cal);1412	regmap_update_bits(cs42l43->regmap, CS42L43_PLL_CONTROL,1413			   CS42L43_PLL_REFCLK_EN_MASK, CS42L43_PLL_REFCLK_EN_MASK);1414 1415	reinit_completion(&priv->pll_ready);1416 1417	regmap_update_bits(cs42l43->regmap, CS42L43_CTRL_REG,1418			   CS42L43_PLL_EN_MASK, CS42L43_PLL_EN_MASK);1419 1420	time_left = wait_for_completion_timeout(&priv->pll_ready,1421						msecs_to_jiffies(CS42L43_PLL_TIMEOUT_MS));1422	if (!time_left) {1423		regmap_update_bits(cs42l43->regmap, CS42L43_CTRL_REG,1424				   CS42L43_PLL_EN_MASK, 0);1425		regmap_update_bits(cs42l43->regmap, CS42L43_PLL_CONTROL,1426				   CS42L43_PLL_REFCLK_EN_MASK, 0);1427 1428		dev_err(priv->dev, "Timeout out waiting for PLL\n");1429		return -ETIMEDOUT;1430	}1431 1432	if (priv->refclk_src == CS42L43_SYSCLK_SDW)1433		cs42l43->sdw_pll_active = true;1434 1435	dev_dbg(priv->dev, "PLL locked in %ums\n", 200 - jiffies_to_msecs(time_left));1436 1437	/*1438	 * Reads are not allowed over Soundwire without OSC_DIV2_EN or the PLL,1439	 * but you can not change to PLL with OSC_DIV2_EN set. So ensure the whole1440	 * change over happens under the regmap lock to prevent any reads.1441	 */1442	regmap_multi_reg_write(cs42l43->regmap, enable_seq, ARRAY_SIZE(enable_seq));1443 1444	return 0;1445}1446 1447static int cs42l43_disable_pll(struct cs42l43_codec *priv)1448{1449	static const struct reg_sequence disable_seq[] = {1450		{ CS42L43_MCLK_SRC_SEL, 0x0, 5, },1451		{ CS42L43_OSC_DIV_SEL, CS42L43_OSC_DIV2_EN_MASK, },1452	};1453	struct cs42l43 *cs42l43 = priv->core;1454 1455	dev_dbg(priv->dev, "Disabling PLL\n");1456 1457	lockdep_assert_held(&cs42l43->pll_lock);1458 1459	regmap_multi_reg_write(cs42l43->regmap, disable_seq, ARRAY_SIZE(disable_seq));1460	regmap_update_bits(cs42l43->regmap, CS42L43_CTRL_REG, CS42L43_PLL_EN_MASK, 0);1461	regmap_update_bits(cs42l43->regmap, CS42L43_PLL_CONTROL,1462			   CS42L43_PLL_REFCLK_EN_MASK, 0);1463 1464	cs42l43->sdw_pll_active = false;1465 1466	return 0;1467}1468 1469static int cs42l43_pll_ev(struct snd_soc_dapm_widget *w,1470			  struct snd_kcontrol *kcontrol, int event)1471{1472	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1473	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);1474	struct cs42l43 *cs42l43 = priv->core;1475	int ret;1476 1477	mutex_lock(&cs42l43->pll_lock);1478 1479	switch (event) {1480	case SND_SOC_DAPM_PRE_PMU:1481		if (priv->refclk_src == CS42L43_SYSCLK_MCLK) {1482			ret = clk_prepare_enable(priv->mclk);1483			if (ret) {1484				dev_err(priv->dev, "Failed to enable MCLK: %d\n", ret);1485				break;1486			}1487		}1488 1489		ret = cs42l43_enable_pll(priv);1490		break;1491	case SND_SOC_DAPM_POST_PMD:1492		ret = cs42l43_disable_pll(priv);1493 1494		if (priv->refclk_src == CS42L43_SYSCLK_MCLK)1495			clk_disable_unprepare(priv->mclk);1496		break;1497	default:1498		ret = 0;1499		break;1500	}1501 1502	mutex_unlock(&cs42l43->pll_lock);1503 1504	return ret;1505}1506 1507static int cs42l43_dapm_wait_completion(struct completion *pmu, struct completion *pmd,1508					int event, int timeout_ms)1509{1510	unsigned long time_left;1511 1512	switch (event) {1513	case SND_SOC_DAPM_PRE_PMU:1514		reinit_completion(pmu);1515		return 0;1516	case SND_SOC_DAPM_PRE_PMD:1517		reinit_completion(pmd);1518		return 0;1519	case SND_SOC_DAPM_POST_PMU:1520		time_left = wait_for_completion_timeout(pmu, msecs_to_jiffies(timeout_ms));1521		break;1522	case SND_SOC_DAPM_POST_PMD:1523		time_left = wait_for_completion_timeout(pmd, msecs_to_jiffies(timeout_ms));1524		break;1525	default:1526		return 0;1527	}1528 1529	if (!time_left)1530		return -ETIMEDOUT;1531	else1532		return 0;1533}1534 1535static int cs42l43_spkr_ev(struct snd_soc_dapm_widget *w,1536			   struct snd_kcontrol *kcontrol, int event)1537{1538	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1539	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);1540 1541	return cs42l43_dapm_wait_completion(&priv->spkr_startup,1542					    &priv->spkr_shutdown, event,1543					    CS42L43_SPK_TIMEOUT_MS);1544}1545 1546static int cs42l43_spkl_ev(struct snd_soc_dapm_widget *w,1547			   struct snd_kcontrol *kcontrol, int event)1548{1549	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1550	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);1551 1552	return cs42l43_dapm_wait_completion(&priv->spkl_startup,1553					    &priv->spkl_shutdown, event,1554					    CS42L43_SPK_TIMEOUT_MS);1555}1556 1557static int cs42l43_hp_ev(struct snd_soc_dapm_widget *w,1558			 struct snd_kcontrol *kcontrol, int event)1559{1560	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1561	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);1562	struct cs42l43 *cs42l43 = priv->core;1563	unsigned int mask = 1 << w->shift;1564	unsigned int val = 0;1565	int ret;1566 1567	switch (event) {1568	case SND_SOC_DAPM_PRE_PMU:1569		val = mask;1570		fallthrough;1571	case SND_SOC_DAPM_PRE_PMD:1572		priv->hp_ena &= ~mask;1573		priv->hp_ena |= val;1574 1575		ret = cs42l43_dapm_wait_completion(&priv->hp_startup,1576						   &priv->hp_shutdown, event,1577						   CS42L43_HP_TIMEOUT_MS);1578		if (ret)1579			return ret;1580 1581		if (!priv->load_detect_running && !priv->hp_ilimited)1582			regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN8,1583					   mask, val);1584		break;1585	case SND_SOC_DAPM_POST_PMU:1586	case SND_SOC_DAPM_POST_PMD:1587		if (priv->load_detect_running || priv->hp_ilimited)1588			break;1589 1590		ret = cs42l43_dapm_wait_completion(&priv->hp_startup,1591						   &priv->hp_shutdown, event,1592						   CS42L43_HP_TIMEOUT_MS);1593		if (ret)1594			return ret;1595		break;1596	default:1597		break;1598	}1599 1600	return 0;1601}1602 1603static int cs42l43_mic_ev(struct snd_soc_dapm_widget *w,1604			  struct snd_kcontrol *kcontrol, int event)1605{1606	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1607	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);1608	struct cs42l43 *cs42l43 = priv->core;1609	unsigned int reg, ramp, mute;1610	unsigned int *val;1611	int ret;1612 1613	switch (w->shift) {1614	case CS42L43_ADC1_EN_SHIFT:1615	case CS42L43_PDM1_DIN_L_EN_SHIFT:1616		reg = CS42L43_DECIM_VOL_CTRL_CH1_CH2;1617		ramp = CS42L43_DECIM1_VD_RAMP_MASK;1618		mute = CS42L43_DECIM1_MUTE_MASK;1619		val = &priv->decim_cache[0];1620		break;1621	case CS42L43_ADC2_EN_SHIFT:1622	case CS42L43_PDM1_DIN_R_EN_SHIFT:1623		reg = CS42L43_DECIM_VOL_CTRL_CH1_CH2;1624		ramp = CS42L43_DECIM2_VD_RAMP_MASK;1625		mute = CS42L43_DECIM2_MUTE_MASK;1626		val = &priv->decim_cache[1];1627		break;1628	case CS42L43_PDM2_DIN_L_EN_SHIFT:1629		reg = CS42L43_DECIM_VOL_CTRL_CH3_CH4;1630		ramp  = CS42L43_DECIM3_VD_RAMP_MASK;1631		mute = CS42L43_DECIM3_MUTE_MASK;1632		val = &priv->decim_cache[2];1633		break;1634	case CS42L43_PDM2_DIN_R_EN_SHIFT:1635		reg = CS42L43_DECIM_VOL_CTRL_CH3_CH4;1636		ramp = CS42L43_DECIM4_VD_RAMP_MASK;1637		mute = CS42L43_DECIM4_MUTE_MASK;1638		val = &priv->decim_cache[3];1639		break;1640	default:1641		dev_err(priv->dev, "Invalid microphone shift: %d\n", w->shift);1642		return -EINVAL;1643	}1644 1645	switch (event) {1646	case SND_SOC_DAPM_PRE_PMU:1647		ret = regmap_read(cs42l43->regmap, reg, val);1648		if (ret) {1649			dev_err(priv->dev,1650				"Failed to cache decimator settings: %d\n",1651				ret);1652			return ret;1653		}1654 1655		regmap_update_bits(cs42l43->regmap, reg, mute | ramp, mute);1656		break;1657	case SND_SOC_DAPM_POST_PMU:1658		regmap_update_bits(cs42l43->regmap, reg, mute | ramp, *val);1659		break;1660	default:1661		break;1662	}1663 1664	return 0;1665}1666 1667static int cs42l43_adc_ev(struct snd_soc_dapm_widget *w,1668			  struct snd_kcontrol *kcontrol, int event)1669{1670	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1671	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);1672	struct cs42l43 *cs42l43 = priv->core;1673	unsigned int mask = 1 << w->shift;1674	unsigned int val = 0;1675	int ret;1676 1677	ret = cs42l43_mic_ev(w, kcontrol, event);1678	if (ret)1679		return ret;1680 1681	switch (event) {1682	case SND_SOC_DAPM_PRE_PMU:1683		val = mask;1684		fallthrough;1685	case SND_SOC_DAPM_PRE_PMD:1686		priv->adc_ena &= ~mask;1687		priv->adc_ena |= val;1688 1689		if (!priv->load_detect_running)1690			regmap_update_bits(cs42l43->regmap, CS42L43_BLOCK_EN3,1691					   mask, val);1692		fallthrough;1693	default:1694		return 0;1695	}1696}1697 1698static const struct snd_soc_dapm_widget cs42l43_widgets[] = {1699	SND_SOC_DAPM_SUPPLY("PLL", SND_SOC_NOPM, 0, 0, cs42l43_pll_ev,1700			    SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),1701 1702	SND_SOC_DAPM_INPUT("ADC1_IN1_P"),1703	SND_SOC_DAPM_INPUT("ADC1_IN1_N"),1704	SND_SOC_DAPM_INPUT("ADC1_IN2_P"),1705	SND_SOC_DAPM_INPUT("ADC1_IN2_N"),1706	SND_SOC_DAPM_INPUT("ADC2_IN_P"),1707	SND_SOC_DAPM_INPUT("ADC2_IN_N"),1708 1709	SND_SOC_DAPM_INPUT("PDM1_DIN"),1710	SND_SOC_DAPM_INPUT("PDM2_DIN"),1711 1712	SND_SOC_DAPM_MUX("ADC1 Input", SND_SOC_NOPM, 0, 0, &cs42l43_adc1_input_ctl),1713 1714	SND_SOC_DAPM_PGA_E("ADC1", SND_SOC_NOPM, CS42L43_ADC1_EN_SHIFT, 0, NULL, 0,1715			   cs42l43_adc_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |1716			   SND_SOC_DAPM_PRE_PMD),1717	SND_SOC_DAPM_PGA_E("ADC2", SND_SOC_NOPM, CS42L43_ADC2_EN_SHIFT, 0, NULL, 0,1718			   cs42l43_adc_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |1719			   SND_SOC_DAPM_PRE_PMD),1720 1721	SND_SOC_DAPM_PGA_E("PDM1L", CS42L43_BLOCK_EN3, CS42L43_PDM1_DIN_L_EN_SHIFT,1722			   0, NULL, 0, cs42l43_mic_ev,1723			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),1724	SND_SOC_DAPM_PGA_E("PDM1R", CS42L43_BLOCK_EN3, CS42L43_PDM1_DIN_R_EN_SHIFT,1725			   0, NULL, 0, cs42l43_mic_ev,1726			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),1727	SND_SOC_DAPM_PGA_E("PDM2L", CS42L43_BLOCK_EN3, CS42L43_PDM2_DIN_L_EN_SHIFT,1728			   0, NULL, 0, cs42l43_mic_ev,1729			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),1730	SND_SOC_DAPM_PGA_E("PDM2R", CS42L43_BLOCK_EN3, CS42L43_PDM2_DIN_R_EN_SHIFT,1731			   0, NULL, 0, cs42l43_mic_ev,1732			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),1733 1734	SND_SOC_DAPM_MUX("Decimator 1 Mode", SND_SOC_NOPM, 0, 0,1735			 &cs42l43_dec_mode_ctl[0]),1736	SND_SOC_DAPM_MUX("Decimator 2 Mode", SND_SOC_NOPM, 0, 0,1737			 &cs42l43_dec_mode_ctl[1]),1738 1739	SND_SOC_DAPM_PGA("Decimator 1", SND_SOC_NOPM, 0, 0, NULL, 0),1740	SND_SOC_DAPM_PGA("Decimator 2", SND_SOC_NOPM, 0, 0, NULL, 0),1741	SND_SOC_DAPM_PGA("Decimator 3", SND_SOC_NOPM, 0, 0, NULL, 0),1742	SND_SOC_DAPM_PGA("Decimator 4", SND_SOC_NOPM, 0, 0, NULL, 0),1743 1744	SND_SOC_DAPM_SUPPLY_S("FSYNC", 0, CS42L43_ASP_CTRL, CS42L43_ASP_FSYNC_EN_SHIFT,1745			      0, NULL, 0),1746	SND_SOC_DAPM_SUPPLY_S("BCLK", 1, CS42L43_ASP_CTRL, CS42L43_ASP_BCLK_EN_SHIFT,1747			      0, NULL, 0),1748 1749	SND_SOC_DAPM_AIF_OUT("ASPTX1", NULL, 0,1750			     CS42L43_ASP_TX_EN, CS42L43_ASP_TX_CH1_EN_SHIFT, 0),1751	SND_SOC_DAPM_AIF_OUT("ASPTX2", NULL, 1,1752			     CS42L43_ASP_TX_EN, CS42L43_ASP_TX_CH2_EN_SHIFT, 0),1753	SND_SOC_DAPM_AIF_OUT("ASPTX3", NULL, 2,1754			     CS42L43_ASP_TX_EN, CS42L43_ASP_TX_CH3_EN_SHIFT, 0),1755	SND_SOC_DAPM_AIF_OUT("ASPTX4", NULL, 3,1756			     CS42L43_ASP_TX_EN, CS42L43_ASP_TX_CH4_EN_SHIFT, 0),1757	SND_SOC_DAPM_AIF_OUT("ASPTX5", NULL, 4,1758			     CS42L43_ASP_TX_EN, CS42L43_ASP_TX_CH5_EN_SHIFT, 0),1759	SND_SOC_DAPM_AIF_OUT("ASPTX6", NULL, 5,1760			     CS42L43_ASP_TX_EN, CS42L43_ASP_TX_CH6_EN_SHIFT, 0),1761 1762	SND_SOC_DAPM_AIF_IN("ASPRX1", NULL, 0,1763			    CS42L43_ASP_RX_EN, CS42L43_ASP_RX_CH1_EN_SHIFT, 0),1764	SND_SOC_DAPM_AIF_IN("ASPRX2", NULL, 1,1765			    CS42L43_ASP_RX_EN, CS42L43_ASP_RX_CH2_EN_SHIFT, 0),1766	SND_SOC_DAPM_AIF_IN("ASPRX3", NULL, 2,1767			    CS42L43_ASP_RX_EN, CS42L43_ASP_RX_CH3_EN_SHIFT, 0),1768	SND_SOC_DAPM_AIF_IN("ASPRX4", NULL, 3,1769			    CS42L43_ASP_RX_EN, CS42L43_ASP_RX_CH4_EN_SHIFT, 0),1770	SND_SOC_DAPM_AIF_IN("ASPRX5", NULL, 4,1771			    CS42L43_ASP_RX_EN, CS42L43_ASP_RX_CH5_EN_SHIFT, 0),1772	SND_SOC_DAPM_AIF_IN("ASPRX6", NULL, 5,1773			    CS42L43_ASP_RX_EN, CS42L43_ASP_RX_CH6_EN_SHIFT, 0),1774 1775	SND_SOC_DAPM_AIF_OUT("DP1TX1", NULL, 0, SND_SOC_NOPM, 0, 0),1776	SND_SOC_DAPM_AIF_OUT("DP1TX2", NULL, 1, SND_SOC_NOPM, 0, 0),1777	SND_SOC_DAPM_AIF_OUT("DP1TX3", NULL, 2, SND_SOC_NOPM, 0, 0),1778	SND_SOC_DAPM_AIF_OUT("DP1TX4", NULL, 3, SND_SOC_NOPM, 0, 0),1779 1780	SND_SOC_DAPM_AIF_OUT("DP2TX1", NULL, 0, SND_SOC_NOPM, 0, 0),1781	SND_SOC_DAPM_AIF_OUT("DP2TX2", NULL, 1, SND_SOC_NOPM, 0, 0),1782 1783	SND_SOC_DAPM_AIF_OUT("DP3TX1", NULL, 0, SND_SOC_NOPM, 0, 0),1784	SND_SOC_DAPM_AIF_OUT("DP3TX2", NULL, 1, SND_SOC_NOPM, 0, 0),1785 1786	SND_SOC_DAPM_AIF_OUT("DP4TX1", NULL, 0, SND_SOC_NOPM, 0, 0),1787	SND_SOC_DAPM_AIF_OUT("DP4TX2", NULL, 1, SND_SOC_NOPM, 0, 0),1788 1789	SND_SOC_DAPM_AIF_IN("DP5RX1", NULL, 0, SND_SOC_NOPM, 0, 0),1790	SND_SOC_DAPM_AIF_IN("DP5RX2", NULL, 1, SND_SOC_NOPM, 0, 0),1791 1792	SND_SOC_DAPM_AIF_IN("DP6RX1", NULL, 0, SND_SOC_NOPM, 0, 0),1793	SND_SOC_DAPM_AIF_IN("DP6RX2", NULL, 1, SND_SOC_NOPM, 0, 0),1794 1795	SND_SOC_DAPM_AIF_IN("DP7RX1", NULL, 0, SND_SOC_NOPM, 0, 0),1796	SND_SOC_DAPM_AIF_IN("DP7RX2", NULL, 1, SND_SOC_NOPM, 0, 0),1797 1798	SND_SOC_DAPM_REGULATOR_SUPPLY("vdd-amp", 0, 0),1799 1800	SND_SOC_DAPM_PGA_E("AMP1", CS42L43_BLOCK_EN10, CS42L43_AMP1_EN_SHIFT, 0, NULL, 0,1801			   cs42l43_spkl_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |1802			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),1803	SND_SOC_DAPM_PGA_E("AMP2", CS42L43_BLOCK_EN10, CS42L43_AMP2_EN_SHIFT, 0, NULL, 0,1804			   cs42l43_spkr_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |1805			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),1806 1807	SND_SOC_DAPM_OUTPUT("AMP1_OUT_P"),1808	SND_SOC_DAPM_OUTPUT("AMP1_OUT_N"),1809	SND_SOC_DAPM_OUTPUT("AMP2_OUT_P"),1810	SND_SOC_DAPM_OUTPUT("AMP2_OUT_N"),1811 1812	SND_SOC_DAPM_PGA("SPDIF", CS42L43_BLOCK_EN11, CS42L43_SPDIF_EN_SHIFT,1813			 0, NULL, 0),1814	SND_SOC_DAPM_OUTPUT("SPDIF_TX"),1815 1816	SND_SOC_DAPM_PGA_E("HP", SND_SOC_NOPM, CS42L43_HP_EN_SHIFT, 0, NULL, 0,1817			   cs42l43_hp_ev, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |1818			   SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),1819	SND_SOC_DAPM_OUTPUT("AMP3_OUT"),1820	SND_SOC_DAPM_OUTPUT("AMP4_OUT"),1821 1822	SND_SOC_DAPM_SIGGEN("Tone"),1823	SND_SOC_DAPM_SUPPLY("Tone Generator", CS42L43_BLOCK_EN9, CS42L43_TONE_EN_SHIFT,1824			    0, NULL, 0),1825	SND_SOC_DAPM_REG(snd_soc_dapm_pga, "Tone 1", CS42L43_TONE_CH1_CTRL,1826			 CS42L43_TONE_SEL_SHIFT, CS42L43_TONE_SEL_MASK, 0xA, 0),1827	SND_SOC_DAPM_REG(snd_soc_dapm_pga, "Tone 2", CS42L43_TONE_CH2_CTRL,1828			 CS42L43_TONE_SEL_SHIFT, CS42L43_TONE_SEL_MASK, 0xA, 0),1829 1830	SND_SOC_DAPM_SUPPLY("ISRC1", CS42L43_BLOCK_EN5, CS42L43_ISRC1_BANK_EN_SHIFT,1831			    0, NULL, 0),1832	SND_SOC_DAPM_SUPPLY("ISRC2", CS42L43_BLOCK_EN5, CS42L43_ISRC2_BANK_EN_SHIFT,1833			    0, NULL, 0),1834 1835	SND_SOC_DAPM_PGA("ISRC1INT2", CS42L43_ISRC1_CTRL,1836			 CS42L43_ISRC_INT2_EN_SHIFT, 0, NULL, 0),1837	SND_SOC_DAPM_PGA("ISRC1INT1", CS42L43_ISRC1_CTRL,1838			 CS42L43_ISRC_INT1_EN_SHIFT, 0, NULL, 0),1839	SND_SOC_DAPM_PGA("ISRC1DEC2", CS42L43_ISRC1_CTRL,1840			 CS42L43_ISRC_DEC2_EN_SHIFT, 0, NULL, 0),1841	SND_SOC_DAPM_PGA("ISRC1DEC1", CS42L43_ISRC1_CTRL,1842			 CS42L43_ISRC_DEC1_EN_SHIFT, 0, NULL, 0),1843 1844	SND_SOC_DAPM_PGA("ISRC2INT2", CS42L43_ISRC2_CTRL,1845			 CS42L43_ISRC_INT2_EN_SHIFT, 0, NULL, 0),1846	SND_SOC_DAPM_PGA("ISRC2INT1", CS42L43_ISRC2_CTRL,1847			 CS42L43_ISRC_INT1_EN_SHIFT, 0, NULL, 0),1848	SND_SOC_DAPM_PGA("ISRC2DEC2", CS42L43_ISRC2_CTRL,1849			 CS42L43_ISRC_DEC2_EN_SHIFT, 0, NULL, 0),1850	SND_SOC_DAPM_PGA("ISRC2DEC1", CS42L43_ISRC2_CTRL,1851			 CS42L43_ISRC_DEC1_EN_SHIFT, 0, NULL, 0),1852 1853	SND_SOC_DAPM_SUPPLY("ASRC_INT", CS42L43_BLOCK_EN4,1854			    CS42L43_ASRC_INT_BANK_EN_SHIFT, 0, NULL, 0),1855	SND_SOC_DAPM_SUPPLY("ASRC_DEC", CS42L43_BLOCK_EN4,1856			    CS42L43_ASRC_DEC_BANK_EN_SHIFT, 0, NULL, 0),1857 1858	SND_SOC_DAPM_PGA("ASRC_INT1", CS42L43_ASRC_INT_ENABLES,1859			 CS42L43_ASRC_INT1_EN_SHIFT, 0, NULL, 0),1860	SND_SOC_DAPM_PGA("ASRC_INT2", CS42L43_ASRC_INT_ENABLES,1861			 CS42L43_ASRC_INT2_EN_SHIFT, 0, NULL, 0),1862	SND_SOC_DAPM_PGA("ASRC_INT3", CS42L43_ASRC_INT_ENABLES,1863			 CS42L43_ASRC_INT3_EN_SHIFT, 0, NULL, 0),1864	SND_SOC_DAPM_PGA("ASRC_INT4", CS42L43_ASRC_INT_ENABLES,1865			 CS42L43_ASRC_INT4_EN_SHIFT, 0, NULL, 0),1866	SND_SOC_DAPM_PGA("ASRC_DEC1", CS42L43_ASRC_DEC_ENABLES,1867			 CS42L43_ASRC_DEC1_EN_SHIFT, 0, NULL, 0),1868	SND_SOC_DAPM_PGA("ASRC_DEC2", CS42L43_ASRC_DEC_ENABLES,1869			 CS42L43_ASRC_DEC2_EN_SHIFT, 0, NULL, 0),1870	SND_SOC_DAPM_PGA("ASRC_DEC3", CS42L43_ASRC_DEC_ENABLES,1871			 CS42L43_ASRC_DEC3_EN_SHIFT, 0, NULL, 0),1872	SND_SOC_DAPM_PGA("ASRC_DEC4", CS42L43_ASRC_DEC_ENABLES,1873			 CS42L43_ASRC_DEC4_EN_SHIFT, 0, NULL, 0),1874 1875	SND_SOC_DAPM_SUPPLY("EQ Clock", CS42L43_BLOCK_EN7, CS42L43_EQ_EN_SHIFT,1876			    0, NULL, 0),1877	SND_SOC_DAPM_PGA_E("EQ", CS42L43_START_EQZ0, CS42L43_START_FILTER_SHIFT,1878			   0, NULL, 0, cs42l43_eq_ev,1879			   SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU),1880 1881	SND_SOC_DAPM_SUPPLY("Mixer Core", CS42L43_BLOCK_EN6, CS42L43_MIXER_EN_SHIFT,1882			    0, NULL, 0),1883	CS42L43_DAPM_MUX("ASPTX1", asptx1),1884	CS42L43_DAPM_MUX("ASPTX2", asptx2),1885	CS42L43_DAPM_MUX("ASPTX3", asptx3),1886	CS42L43_DAPM_MUX("ASPTX4", asptx4),1887	CS42L43_DAPM_MUX("ASPTX5", asptx5),1888	CS42L43_DAPM_MUX("ASPTX6", asptx6),1889 1890	CS42L43_DAPM_MUX("DP1TX1", dp1tx1),1891	CS42L43_DAPM_MUX("DP1TX2", dp1tx2),1892	CS42L43_DAPM_MUX("DP1TX3", dp1tx3),1893	CS42L43_DAPM_MUX("DP1TX4", dp1tx4),1894	CS42L43_DAPM_MUX("DP2TX1", dp2tx1),1895	CS42L43_DAPM_MUX("DP2TX2", dp2tx2),1896	CS42L43_DAPM_MUX("DP3TX1", dp3tx1),1897	CS42L43_DAPM_MUX("DP3TX2", dp3tx2),1898	CS42L43_DAPM_MUX("DP4TX1", dp4tx1),1899	CS42L43_DAPM_MUX("DP4TX2", dp4tx2),1900 1901	CS42L43_DAPM_MUX("ASRC INT1", asrcint1),1902	CS42L43_DAPM_MUX("ASRC INT2", asrcint2),1903	CS42L43_DAPM_MUX("ASRC INT3", asrcint3),1904	CS42L43_DAPM_MUX("ASRC INT4", asrcint4),1905	CS42L43_DAPM_MUX("ASRC DEC1", asrcdec1),1906	CS42L43_DAPM_MUX("ASRC DEC2", asrcdec2),1907	CS42L43_DAPM_MUX("ASRC DEC3", asrcdec3),1908	CS42L43_DAPM_MUX("ASRC DEC4", asrcdec4),1909 1910	CS42L43_DAPM_MUX("ISRC1INT1", isrc1int1),1911	CS42L43_DAPM_MUX("ISRC1INT2", isrc1int2),1912	CS42L43_DAPM_MUX("ISRC1DEC1", isrc1dec1),1913	CS42L43_DAPM_MUX("ISRC1DEC2", isrc1dec2),1914	CS42L43_DAPM_MUX("ISRC2INT1", isrc2int1),1915	CS42L43_DAPM_MUX("ISRC2INT2", isrc2int2),1916	CS42L43_DAPM_MUX("ISRC2DEC1", isrc2dec1),1917	CS42L43_DAPM_MUX("ISRC2DEC2", isrc2dec2),1918 1919	CS42L43_DAPM_MUX("SPDIF1", spdif1),1920	CS42L43_DAPM_MUX("SPDIF2", spdif2),1921 1922	CS42L43_DAPM_MIXER("EQ1", eq1),1923	CS42L43_DAPM_MIXER("EQ2", eq2),1924 1925	CS42L43_DAPM_MIXER("Speaker L", amp1),1926	CS42L43_DAPM_MIXER("Speaker R", amp2),1927 1928	CS42L43_DAPM_MIXER("Headphone L", amp3),1929	CS42L43_DAPM_MIXER("Headphone R", amp4),1930};1931 1932static const struct snd_soc_dapm_route cs42l43_routes[] = {1933	{ "ADC1_IN1_P",		NULL,	"PLL" },1934	{ "ADC1_IN1_N",		NULL,	"PLL" },1935	{ "ADC1_IN2_P",		NULL,	"PLL" },1936	{ "ADC1_IN2_N",		NULL,	"PLL" },1937	{ "ADC2_IN_P",		NULL,	"PLL" },1938	{ "ADC2_IN_N",		NULL,	"PLL" },1939	{ "PDM1_DIN",		NULL,	"PLL" },1940	{ "PDM2_DIN",		NULL,	"PLL" },1941	{ "AMP1_OUT_P",		NULL,	"PLL" },1942	{ "AMP1_OUT_N",		NULL,	"PLL" },1943	{ "AMP2_OUT_P",		NULL,	"PLL" },1944	{ "AMP2_OUT_N",		NULL,	"PLL" },1945	{ "SPDIF_TX",		NULL,	"PLL" },1946	{ "HP",			NULL,	"PLL" },1947	{ "AMP3_OUT",		NULL,	"PLL" },1948	{ "AMP4_OUT",		NULL,	"PLL" },1949	{ "Tone 1",		NULL,	"PLL" },1950	{ "Tone 2",		NULL,	"PLL" },1951	{ "ASP Playback",	NULL,	"PLL" },1952	{ "ASP Capture",	NULL,	"PLL" },1953	{ "DP1 Capture",	NULL,	"PLL" },1954	{ "DP2 Capture",	NULL,	"PLL" },1955	{ "DP3 Capture",	NULL,	"PLL" },1956	{ "DP4 Capture",	NULL,	"PLL" },1957	{ "DP5 Playback",	NULL,	"PLL" },1958	{ "DP6 Playback",	NULL,	"PLL" },1959	{ "DP7 Playback",	NULL,	"PLL" },1960 1961	{ "ADC1 Input",		"IN1",	"ADC1_IN1_P" },1962	{ "ADC1 Input",		"IN1",	"ADC1_IN1_N" },1963	{ "ADC1 Input",		"IN2",	"ADC1_IN2_P" },1964	{ "ADC1 Input",		"IN2",	"ADC1_IN2_N" },1965 1966	{ "ADC1",		NULL,	"ADC1 Input" },1967	{ "ADC2",		NULL,	"ADC2_IN_P" },1968	{ "ADC2",		NULL,	"ADC2_IN_N" },1969 1970	{ "PDM1L",		NULL,	"PDM1_DIN" },1971	{ "PDM1R",		NULL,	"PDM1_DIN" },1972	{ "PDM2L",		NULL,	"PDM2_DIN" },1973	{ "PDM2R",		NULL,	"PDM2_DIN" },1974 1975	{ "Decimator 1 Mode",	"PDM",	"PDM1L" },1976	{ "Decimator 1 Mode",	"ADC",	"ADC1" },1977	{ "Decimator 2 Mode",	"PDM",	"PDM1R" },1978	{ "Decimator 2 Mode",	"ADC",	"ADC2" },1979 1980	{ "Decimator 1",	NULL,	"Decimator 1 Mode" },1981	{ "Decimator 2",	NULL,	"Decimator 2 Mode" },1982	{ "Decimator 3",	NULL,	"PDM2L" },1983	{ "Decimator 4",	NULL,	"PDM2R" },1984 1985	{ "ASP Capture",	NULL,	"ASPTX1" },1986	{ "ASP Capture",	NULL,	"ASPTX2" },1987	{ "ASP Capture",	NULL,	"ASPTX3" },1988	{ "ASP Capture",	NULL,	"ASPTX4" },1989	{ "ASP Capture",	NULL,	"ASPTX5" },1990	{ "ASP Capture",	NULL,	"ASPTX6" },1991	{ "ASPTX1",		NULL,	"BCLK" },1992	{ "ASPTX2",		NULL,	"BCLK" },1993	{ "ASPTX3",		NULL,	"BCLK" },1994	{ "ASPTX4",		NULL,	"BCLK" },1995	{ "ASPTX5",		NULL,	"BCLK" },1996	{ "ASPTX6",		NULL,	"BCLK" },1997 1998	{ "ASPRX1",		NULL,	"ASP Playback" },1999	{ "ASPRX2",		NULL,	"ASP Playback" },2000	{ "ASPRX3",		NULL,	"ASP Playback" },2001	{ "ASPRX4",		NULL,	"ASP Playback" },2002	{ "ASPRX5",		NULL,	"ASP Playback" },2003	{ "ASPRX6",		NULL,	"ASP Playback" },2004	{ "ASPRX1",		NULL,	"BCLK" },2005	{ "ASPRX2",		NULL,	"BCLK" },2006	{ "ASPRX3",		NULL,	"BCLK" },2007	{ "ASPRX4",		NULL,	"BCLK" },2008	{ "ASPRX5",		NULL,	"BCLK" },2009	{ "ASPRX6",		NULL,	"BCLK" },2010 2011	{ "DP1 Capture",	NULL, "DP1TX1" },2012	{ "DP1 Capture",	NULL, "DP1TX2" },2013	{ "DP1 Capture",	NULL, "DP1TX3" },2014	{ "DP1 Capture",	NULL, "DP1TX4" },2015 2016	{ "DP2 Capture",	NULL, "DP2TX1" },2017	{ "DP2 Capture",	NULL, "DP2TX2" },2018 2019	{ "DP3 Capture",	NULL, "DP3TX1" },2020	{ "DP3 Capture",	NULL, "DP3TX2" },2021 2022	{ "DP4 Capture",	NULL, "DP4TX1" },2023	{ "DP4 Capture",	NULL, "DP4TX2" },2024 2025	{ "DP5RX1",		NULL, "DP5 Playback" },2026	{ "DP5RX2",		NULL, "DP5 Playback" },2027 2028	{ "DP6RX1",		NULL, "DP6 Playback" },2029	{ "DP6RX2",		NULL, "DP6 Playback" },2030 2031	{ "DP7RX1",		NULL, "DP7 Playback" },2032	{ "DP7RX2",		NULL, "DP7 Playback" },2033 2034	{ "AMP1",		NULL,	"vdd-amp" },2035	{ "AMP2",		NULL,	"vdd-amp" },2036 2037	{ "AMP1_OUT_P",		NULL,	"AMP1" },2038	{ "AMP1_OUT_N",		NULL,	"AMP1" },2039	{ "AMP2_OUT_P",		NULL,	"AMP2" },2040	{ "AMP2_OUT_N",		NULL,	"AMP2" },2041 2042	{ "SPDIF_TX",		NULL,	"SPDIF" },2043 2044	{ "AMP3_OUT",		NULL,	"HP" },2045	{ "AMP4_OUT",		NULL,	"HP" },2046 2047	{ "Tone 1",		NULL,	"Tone" },2048	{ "Tone 1",		NULL,	"Tone Generator" },2049	{ "Tone 2",		NULL,	"Tone" },2050	{ "Tone 2",		NULL,	"Tone Generator" },2051 2052	{ "ISRC1INT2",		NULL,	"ISRC1" },2053	{ "ISRC1INT1",		NULL,	"ISRC1" },2054	{ "ISRC1DEC2",		NULL,	"ISRC1" },2055	{ "ISRC1DEC1",		NULL,	"ISRC1" },2056 2057	{ "ISRC2INT2",		NULL,	"ISRC2" },2058	{ "ISRC2INT1",		NULL,	"ISRC2" },2059	{ "ISRC2DEC2",		NULL,	"ISRC2" },2060	{ "ISRC2DEC1",		NULL,	"ISRC2" },2061 2062	{ "ASRC_INT1",		NULL,	"ASRC_INT" },2063	{ "ASRC_INT2",		NULL,	"ASRC_INT" },2064	{ "ASRC_INT3",		NULL,	"ASRC_INT" },2065	{ "ASRC_INT4",		NULL,	"ASRC_INT" },2066	{ "ASRC_DEC1",		NULL,	"ASRC_DEC" },2067	{ "ASRC_DEC2",		NULL,	"ASRC_DEC" },2068	{ "ASRC_DEC3",		NULL,	"ASRC_DEC" },2069	{ "ASRC_DEC4",		NULL,	"ASRC_DEC" },2070 2071	{ "EQ",			NULL,	"EQ Clock" },2072 2073	CS42L43_MUX_ROUTES("ASPTX1", "ASPTX1"),2074	CS42L43_MUX_ROUTES("ASPTX2", "ASPTX2"),2075	CS42L43_MUX_ROUTES("ASPTX3", "ASPTX3"),2076	CS42L43_MUX_ROUTES("ASPTX4", "ASPTX4"),2077	CS42L43_MUX_ROUTES("ASPTX5", "ASPTX5"),2078	CS42L43_MUX_ROUTES("ASPTX6", "ASPTX6"),2079 2080	CS42L43_MUX_ROUTES("DP1TX1", "DP1TX1"),2081	CS42L43_MUX_ROUTES("DP1TX2", "DP1TX2"),2082	CS42L43_MUX_ROUTES("DP1TX3", "DP1TX3"),2083	CS42L43_MUX_ROUTES("DP1TX4", "DP1TX4"),2084	CS42L43_MUX_ROUTES("DP2TX1", "DP2TX1"),2085	CS42L43_MUX_ROUTES("DP2TX2", "DP2TX2"),2086	CS42L43_MUX_ROUTES("DP3TX1", "DP3TX1"),2087	CS42L43_MUX_ROUTES("DP3TX2", "DP3TX2"),2088	CS42L43_MUX_ROUTES("DP4TX1", "DP4TX1"),2089	CS42L43_MUX_ROUTES("DP4TX2", "DP4TX2"),2090 2091	CS42L43_MUX_ROUTES("ASRC INT1", "ASRC_INT1"),2092	CS42L43_MUX_ROUTES("ASRC INT2", "ASRC_INT2"),2093	CS42L43_MUX_ROUTES("ASRC INT3", "ASRC_INT3"),2094	CS42L43_MUX_ROUTES("ASRC INT4", "ASRC_INT4"),2095	CS42L43_MUX_ROUTES("ASRC DEC1", "ASRC_DEC1"),2096	CS42L43_MUX_ROUTES("ASRC DEC2", "ASRC_DEC2"),2097	CS42L43_MUX_ROUTES("ASRC DEC3", "ASRC_DEC3"),2098	CS42L43_MUX_ROUTES("ASRC DEC4", "ASRC_DEC4"),2099 2100	CS42L43_MUX_ROUTES("ISRC1INT1", "ISRC1INT1"),2101	CS42L43_MUX_ROUTES("ISRC1INT2", "ISRC1INT2"),2102	CS42L43_MUX_ROUTES("ISRC1DEC1", "ISRC1DEC1"),2103	CS42L43_MUX_ROUTES("ISRC1DEC2", "ISRC1DEC2"),2104	CS42L43_MUX_ROUTES("ISRC2INT1", "ISRC2INT1"),2105	CS42L43_MUX_ROUTES("ISRC2INT2", "ISRC2INT2"),2106	CS42L43_MUX_ROUTES("ISRC2DEC1", "ISRC2DEC1"),2107	CS42L43_MUX_ROUTES("ISRC2DEC2", "ISRC2DEC2"),2108 2109	CS42L43_MUX_ROUTES("SPDIF1", "SPDIF"),2110	CS42L43_MUX_ROUTES("SPDIF2", "SPDIF"),2111 2112	CS42L43_MIXER_ROUTES("EQ1", "EQ"),2113	CS42L43_MIXER_ROUTES("EQ2", "EQ"),2114 2115	CS42L43_MIXER_ROUTES("Speaker L", "AMP1"),2116	CS42L43_MIXER_ROUTES("Speaker R", "AMP2"),2117 2118	CS42L43_MIXER_ROUTES("Headphone L", "HP"),2119	CS42L43_MIXER_ROUTES("Headphone R", "HP"),2120};2121 2122static int cs42l43_set_sysclk(struct snd_soc_component *component, int clk_id,2123			      int src, unsigned int freq, int dir)2124{2125	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);2126	struct cs42l43 *cs42l43 = priv->core;2127	int ret;2128 2129	mutex_lock(&cs42l43->pll_lock);2130	ret = cs42l43_set_pll(priv, src, freq);2131	mutex_unlock(&cs42l43->pll_lock);2132 2133	return ret;2134}2135 2136static int cs42l43_component_probe(struct snd_soc_component *component)2137{2138	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);2139	struct cs42l43 *cs42l43 = priv->core;2140 2141	snd_soc_component_init_regmap(component, cs42l43->regmap);2142 2143	cs42l43_mask_to_slots(priv, CS42L43_DEFAULT_SLOTS, priv->tx_slots,2144			      ARRAY_SIZE(priv->tx_slots));2145	cs42l43_mask_to_slots(priv, CS42L43_DEFAULT_SLOTS, priv->rx_slots,2146			      ARRAY_SIZE(priv->rx_slots));2147 2148	priv->component = component;2149	priv->constraint = cs42l43_constraint;2150 2151	return 0;2152}2153 2154static void cs42l43_component_remove(struct snd_soc_component *component)2155{2156	struct cs42l43_codec *priv = snd_soc_component_get_drvdata(component);2157 2158	cs42l43_set_jack(priv->component, NULL, NULL);2159 2160	cancel_delayed_work_sync(&priv->bias_sense_timeout);2161	cancel_delayed_work_sync(&priv->tip_sense_work);2162	cancel_delayed_work_sync(&priv->button_press_work);2163	cancel_work_sync(&priv->button_release_work);2164 2165	cancel_work_sync(&priv->hp_ilimit_work);2166	cancel_delayed_work_sync(&priv->hp_ilimit_clear_work);2167 2168	priv->component = NULL;2169}2170 2171static const struct snd_soc_component_driver cs42l43_component_drv = {2172	.name			= "cs42l43-codec",2173 2174	.probe			= cs42l43_component_probe,2175	.remove			= cs42l43_component_remove,2176	.set_sysclk		= cs42l43_set_sysclk,2177	.set_jack		= cs42l43_set_jack,2178 2179	.endianness		= 1,2180 2181	.controls		= cs42l43_controls,2182	.num_controls		= ARRAY_SIZE(cs42l43_controls),2183	.dapm_widgets		= cs42l43_widgets,2184	.num_dapm_widgets	= ARRAY_SIZE(cs42l43_widgets),2185	.dapm_routes		= cs42l43_routes,2186	.num_dapm_routes	= ARRAY_SIZE(cs42l43_routes),2187};2188 2189struct cs42l43_irq {2190	unsigned int irq;2191	const char *name;2192	irq_handler_t handler;2193};2194 2195static const struct cs42l43_irq cs42l43_irqs[] = {2196	{ CS42L43_PLL_LOST_LOCK, "pll lost lock", cs42l43_pll_lost_lock },2197	{ CS42L43_PLL_READY, "pll ready", cs42l43_pll_ready },2198	{ CS42L43_HP_STARTUP_DONE, "hp startup", cs42l43_hp_startup },2199	{ CS42L43_HP_SHUTDOWN_DONE, "hp shutdown", cs42l43_hp_shutdown },2200	{ CS42L43_HSDET_DONE, "type detect", cs42l43_type_detect },2201	{ CS42L43_TIPSENSE_UNPLUG_PDET, "tip sense unplug", cs42l43_tip_sense },2202	{ CS42L43_TIPSENSE_PLUG_PDET, "tip sense plug", cs42l43_tip_sense },2203	{ CS42L43_DC_DETECT1_TRUE, "button press", cs42l43_button_press },2204	{ CS42L43_DC_DETECT1_FALSE, "button release", cs42l43_button_release },2205	{ CS42L43_HSBIAS_CLAMPED, "hsbias detect clamp", cs42l43_bias_detect_clamp },2206	{ CS42L43_AMP2_CLK_STOP_FAULT, "spkr clock stop", cs42l43_spkr_clock_stop },2207	{ CS42L43_AMP1_CLK_STOP_FAULT, "spkl clock stop", cs42l43_spkl_clock_stop },2208	{ CS42L43_AMP2_VDDSPK_FAULT, "spkr brown out", cs42l43_spkr_brown_out },2209	{ CS42L43_AMP1_VDDSPK_FAULT, "spkl brown out", cs42l43_spkl_brown_out },2210	{ CS42L43_AMP2_SHUTDOWN_DONE, "spkr shutdown", cs42l43_spkr_shutdown },2211	{ CS42L43_AMP1_SHUTDOWN_DONE, "spkl shutdown", cs42l43_spkl_shutdown },2212	{ CS42L43_AMP2_STARTUP_DONE, "spkr startup", cs42l43_spkr_startup },2213	{ CS42L43_AMP1_STARTUP_DONE, "spkl startup", cs42l43_spkl_startup },2214	{ CS42L43_AMP2_THERM_SHDN, "spkr thermal shutdown", cs42l43_spkr_therm_shutdown },2215	{ CS42L43_AMP1_THERM_SHDN, "spkl thermal shutdown", cs42l43_spkl_therm_shutdown },2216	{ CS42L43_AMP2_THERM_WARN, "spkr thermal warning", cs42l43_spkr_therm_warm },2217	{ CS42L43_AMP1_THERM_WARN, "spkl thermal warning", cs42l43_spkl_therm_warm },2218	{ CS42L43_AMP2_SCDET, "spkr short circuit", cs42l43_spkr_sc_detect },2219	{ CS42L43_AMP1_SCDET, "spkl short circuit", cs42l43_spkl_sc_detect },2220	{ CS42L43_HP_ILIMIT, "hp ilimit", cs42l43_hp_ilimit },2221	{ CS42L43_HP_LOADDET_DONE, "load detect done", cs42l43_load_detect },2222};2223 2224static int cs42l43_request_irq(struct cs42l43_codec *priv,2225			       struct irq_domain *dom, const char * const name,2226			       unsigned int irq, irq_handler_t handler,2227			       unsigned long flags)2228{2229	int ret;2230 2231	ret = irq_create_mapping(dom, irq);2232	if (ret < 0)2233		return dev_err_probe(priv->dev, ret, "Failed to map IRQ %s\n", name);2234 2235	dev_dbg(priv->dev, "Request IRQ %d for %s\n", ret, name);2236 2237	ret = devm_request_threaded_irq(priv->dev, ret, NULL, handler,2238					IRQF_ONESHOT | flags, name, priv);2239	if (ret)2240		return dev_err_probe(priv->dev, ret, "Failed to request IRQ %s\n", name);2241 2242	return 0;2243}2244 2245static int cs42l43_shutter_irq(struct cs42l43_codec *priv,2246			       struct irq_domain *dom, unsigned int shutter,2247			       const char * const open_name,2248			       const char * const close_name,2249			       irq_handler_t handler)2250{2251	unsigned int open_irq, close_irq;2252	int ret;2253 2254	switch (shutter) {2255	case 0x1:2256		dev_warn(priv->dev, "Manual shutters, notifications not available\n");2257		return 0;2258	case 0x2:2259		open_irq = CS42L43_GPIO1_RISE;2260		close_irq = CS42L43_GPIO1_FALL;2261		break;2262	case 0x4:2263		open_irq = CS42L43_GPIO2_RISE;2264		close_irq = CS42L43_GPIO2_FALL;2265		break;2266	case 0x8:2267		open_irq = CS42L43_GPIO3_RISE;2268		close_irq = CS42L43_GPIO3_FALL;2269		break;2270	default:2271		return 0;2272	}2273 2274	ret = cs42l43_request_irq(priv, dom, close_name, close_irq, handler, IRQF_SHARED);2275	if (ret)2276		return ret;2277 2278	return cs42l43_request_irq(priv, dom, open_name, open_irq, handler, IRQF_SHARED);2279}2280 2281static int cs42l43_codec_probe(struct platform_device *pdev)2282{2283	struct cs42l43 *cs42l43 = dev_get_drvdata(pdev->dev.parent);2284	struct cs42l43_codec *priv;2285	struct irq_domain *dom;2286	unsigned int val;2287	int i, ret;2288 2289	dom = irq_find_matching_fwnode(dev_fwnode(cs42l43->dev), DOMAIN_BUS_ANY);2290	if (!dom)2291		return -EPROBE_DEFER;2292 2293	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);2294	if (!priv)2295		return -ENOMEM;2296 2297	priv->dev = &pdev->dev;2298	priv->core = cs42l43;2299 2300	platform_set_drvdata(pdev, priv);2301 2302	mutex_init(&priv->jack_lock);2303	mutex_init(&priv->spk_vu_lock);2304 2305	init_completion(&priv->hp_startup);2306	init_completion(&priv->hp_shutdown);2307	init_completion(&priv->spkr_shutdown);2308	init_completion(&priv->spkl_shutdown);2309	init_completion(&priv->spkr_startup);2310	init_completion(&priv->spkl_startup);2311	init_completion(&priv->pll_ready);2312	init_completion(&priv->type_detect);2313	init_completion(&priv->load_detect);2314 2315	INIT_DELAYED_WORK(&priv->tip_sense_work, cs42l43_tip_sense_work);2316	INIT_DELAYED_WORK(&priv->bias_sense_timeout, cs42l43_bias_sense_timeout);2317	INIT_DELAYED_WORK(&priv->button_press_work, cs42l43_button_press_work);2318	INIT_DELAYED_WORK(&priv->hp_ilimit_clear_work, cs42l43_hp_ilimit_clear_work);2319	INIT_WORK(&priv->button_release_work, cs42l43_button_release_work);2320	INIT_WORK(&priv->hp_ilimit_work, cs42l43_hp_ilimit_work);2321 2322	pm_runtime_set_autosuspend_delay(priv->dev, 100);2323	pm_runtime_use_autosuspend(priv->dev);2324	pm_runtime_set_active(priv->dev);2325	pm_runtime_get_noresume(priv->dev);2326 2327	ret = devm_pm_runtime_enable(priv->dev);2328	if (ret)2329		goto err_pm;2330 2331	for (i = 0; i < ARRAY_SIZE(cs42l43_irqs); i++) {2332		ret = cs42l43_request_irq(priv, dom, cs42l43_irqs[i].name,2333					  cs42l43_irqs[i].irq,2334					  cs42l43_irqs[i].handler, 0);2335		if (ret)2336			goto err_pm;2337	}2338 2339	ret = regmap_read(cs42l43->regmap, CS42L43_SHUTTER_CONTROL, &val);2340	if (ret) {2341		dev_err(priv->dev, "Failed to check shutter source: %d\n", ret);2342		goto err_pm;2343	}2344 2345	ret = cs42l43_shutter_irq(priv, dom, val & CS42L43_MIC_SHUTTER_CFG_MASK,2346				  "mic shutter open", "mic shutter close",2347				  cs42l43_mic_shutter);2348	if (ret)2349		goto err_pm;2350 2351	ret = cs42l43_shutter_irq(priv, dom, (val & CS42L43_SPK_SHUTTER_CFG_MASK) >>2352				  CS42L43_SPK_SHUTTER_CFG_SHIFT,2353				  "spk shutter open", "spk shutter close",2354				  cs42l43_spk_shutter);2355	if (ret)2356		goto err_pm;2357 2358	// Don't use devm as we need to get against the MFD device2359	priv->mclk = clk_get_optional(cs42l43->dev, "mclk");2360	if (IS_ERR(priv->mclk)) {2361		ret = PTR_ERR(priv->mclk);2362		dev_err_probe(priv->dev, ret, "Failed to get mclk\n");2363		goto err_pm;2364	}2365 2366	ret = devm_snd_soc_register_component(priv->dev, &cs42l43_component_drv,2367					      cs42l43_dais, ARRAY_SIZE(cs42l43_dais));2368	if (ret) {2369		dev_err_probe(priv->dev, ret, "Failed to register component\n");2370		goto err_clk;2371	}2372 2373	pm_runtime_mark_last_busy(priv->dev);2374	pm_runtime_put_autosuspend(priv->dev);2375 2376	return 0;2377 2378err_clk:2379	clk_put(priv->mclk);2380err_pm:2381	pm_runtime_put_sync(priv->dev);2382 2383	return ret;2384}2385 2386static void cs42l43_codec_remove(struct platform_device *pdev)2387{2388	struct cs42l43_codec *priv = platform_get_drvdata(pdev);2389 2390	clk_put(priv->mclk);2391}2392 2393static int cs42l43_codec_runtime_resume(struct device *dev)2394{2395	struct cs42l43_codec *priv = dev_get_drvdata(dev);2396 2397	dev_dbg(priv->dev, "Runtime resume\n");2398 2399	// Toggle the speaker volume update incase the speaker volume was synced2400	cs42l43_spk_vu_sync(priv);2401 2402	return 0;2403}2404 2405static int cs42l43_codec_suspend(struct device *dev)2406{2407	struct cs42l43_codec *priv = dev_get_drvdata(dev);2408	struct cs42l43 *cs42l43 = priv->core;2409 2410	disable_irq(cs42l43->irq);2411 2412	return 0;2413}2414 2415static int cs42l43_codec_suspend_noirq(struct device *dev)2416{2417	struct cs42l43_codec *priv = dev_get_drvdata(dev);2418	struct cs42l43 *cs42l43 = priv->core;2419 2420	enable_irq(cs42l43->irq);2421 2422	return 0;2423}2424 2425static int cs42l43_codec_resume(struct device *dev)2426{2427	struct cs42l43_codec *priv = dev_get_drvdata(dev);2428	struct cs42l43 *cs42l43 = priv->core;2429 2430	enable_irq(cs42l43->irq);2431 2432	return 0;2433}2434 2435static int cs42l43_codec_resume_noirq(struct device *dev)2436{2437	struct cs42l43_codec *priv = dev_get_drvdata(dev);2438	struct cs42l43 *cs42l43 = priv->core;2439 2440	disable_irq(cs42l43->irq);2441 2442	return 0;2443}2444 2445static const struct dev_pm_ops cs42l43_codec_pm_ops = {2446	SYSTEM_SLEEP_PM_OPS(cs42l43_codec_suspend, cs42l43_codec_resume)2447	NOIRQ_SYSTEM_SLEEP_PM_OPS(cs42l43_codec_suspend_noirq, cs42l43_codec_resume_noirq)2448	RUNTIME_PM_OPS(NULL, cs42l43_codec_runtime_resume, NULL)2449};2450 2451static const struct platform_device_id cs42l43_codec_id_table[] = {2452	{ "cs42l43-codec", },2453	{}2454};2455MODULE_DEVICE_TABLE(platform, cs42l43_codec_id_table);2456 2457static struct platform_driver cs42l43_codec_driver = {2458	.driver = {2459		.name	= "cs42l43-codec",2460		.pm	= pm_ptr(&cs42l43_codec_pm_ops),2461	},2462 2463	.probe		= cs42l43_codec_probe,2464	.remove		= cs42l43_codec_remove,2465	.id_table	= cs42l43_codec_id_table,2466};2467module_platform_driver(cs42l43_codec_driver);2468 2469MODULE_IMPORT_NS(SND_SOC_CS42L43);2470 2471MODULE_DESCRIPTION("CS42L43 CODEC Driver");2472MODULE_AUTHOR("Charles Keepax <ckeepax@opensource.cirrus.com>");2473MODULE_LICENSE("GPL");2474