brintos

brintos / linux-shallow public Read only

0
0
Text · 33.0 KiB · 287b274 Raw
1220 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * cs35l34.c -- CS35l34 ALSA SoC audio driver4 *5 * Copyright 2016 Cirrus Logic, Inc.6 *7 * Author: Paul Handrigan <Paul.Handrigan@cirrus.com>8 */9 10#include <linux/module.h>11#include <linux/moduleparam.h>12#include <linux/kernel.h>13#include <linux/init.h>14#include <linux/delay.h>15#include <linux/i2c.h>16#include <linux/slab.h>17#include <linux/workqueue.h>18#include <linux/platform_device.h>19#include <linux/regulator/consumer.h>20#include <linux/regulator/machine.h>21#include <linux/pm_runtime.h>22#include <linux/of.h>23#include <linux/of_irq.h>24#include <sound/core.h>25#include <sound/pcm.h>26#include <sound/pcm_params.h>27#include <sound/soc.h>28#include <sound/soc-dapm.h>29#include <linux/gpio/consumer.h>30#include <sound/initval.h>31#include <sound/tlv.h>32#include <sound/cs35l34.h>33 34#include "cs35l34.h"35#include "cirrus_legacy.h"36 37#define PDN_DONE_ATTEMPTS 1038#define CS35L34_START_DELAY 5039 40struct  cs35l34_private {41	struct snd_soc_component *component;42	struct cs35l34_platform_data pdata;43	struct regmap *regmap;44	struct regulator_bulk_data core_supplies[2];45	int num_core_supplies;46	int mclk_int;47	bool tdm_mode;48	struct gpio_desc *reset_gpio;	/* Active-low reset GPIO */49};50 51static const struct reg_default cs35l34_reg[] = {52	{CS35L34_PWRCTL1, 0x01},53	{CS35L34_PWRCTL2, 0x19},54	{CS35L34_PWRCTL3, 0x01},55	{CS35L34_ADSP_CLK_CTL, 0x08},56	{CS35L34_MCLK_CTL, 0x11},57	{CS35L34_AMP_INP_DRV_CTL, 0x01},58	{CS35L34_AMP_DIG_VOL_CTL, 0x12},59	{CS35L34_AMP_DIG_VOL, 0x00},60	{CS35L34_AMP_ANLG_GAIN_CTL, 0x0F},61	{CS35L34_PROTECT_CTL, 0x06},62	{CS35L34_AMP_KEEP_ALIVE_CTL, 0x04},63	{CS35L34_BST_CVTR_V_CTL, 0x00},64	{CS35L34_BST_PEAK_I, 0x10},65	{CS35L34_BST_RAMP_CTL, 0x87},66	{CS35L34_BST_CONV_COEF_1, 0x24},67	{CS35L34_BST_CONV_COEF_2, 0x24},68	{CS35L34_BST_CONV_SLOPE_COMP, 0x4E},69	{CS35L34_BST_CONV_SW_FREQ, 0x08},70	{CS35L34_CLASS_H_CTL, 0x0D},71	{CS35L34_CLASS_H_HEADRM_CTL, 0x0D},72	{CS35L34_CLASS_H_RELEASE_RATE, 0x08},73	{CS35L34_CLASS_H_FET_DRIVE_CTL, 0x41},74	{CS35L34_CLASS_H_STATUS, 0x05},75	{CS35L34_VPBR_CTL, 0x0A},76	{CS35L34_VPBR_VOL_CTL, 0x90},77	{CS35L34_VPBR_TIMING_CTL, 0x6A},78	{CS35L34_PRED_MAX_ATTEN_SPK_LOAD, 0x95},79	{CS35L34_PRED_BROWNOUT_THRESH, 0x1C},80	{CS35L34_PRED_BROWNOUT_VOL_CTL, 0x00},81	{CS35L34_PRED_BROWNOUT_RATE_CTL, 0x10},82	{CS35L34_PRED_WAIT_CTL, 0x10},83	{CS35L34_PRED_ZVP_INIT_IMP_CTL, 0x08},84	{CS35L34_PRED_MAN_SAFE_VPI_CTL, 0x80},85	{CS35L34_VPBR_ATTEN_STATUS, 0x00},86	{CS35L34_PRED_BRWNOUT_ATT_STATUS, 0x00},87	{CS35L34_SPKR_MON_CTL, 0xC6},88	{CS35L34_ADSP_I2S_CTL, 0x00},89	{CS35L34_ADSP_TDM_CTL, 0x00},90	{CS35L34_TDM_TX_CTL_1_VMON, 0x00},91	{CS35L34_TDM_TX_CTL_2_IMON, 0x04},92	{CS35L34_TDM_TX_CTL_3_VPMON, 0x03},93	{CS35L34_TDM_TX_CTL_4_VBSTMON, 0x07},94	{CS35L34_TDM_TX_CTL_5_FLAG1, 0x08},95	{CS35L34_TDM_TX_CTL_6_FLAG2, 0x09},96	{CS35L34_TDM_TX_SLOT_EN_1, 0x00},97	{CS35L34_TDM_TX_SLOT_EN_2, 0x00},98	{CS35L34_TDM_TX_SLOT_EN_3, 0x00},99	{CS35L34_TDM_TX_SLOT_EN_4, 0x00},100	{CS35L34_TDM_RX_CTL_1_AUDIN, 0x40},101	{CS35L34_TDM_RX_CTL_3_ALIVE, 0x04},102	{CS35L34_MULT_DEV_SYNCH1, 0x00},103	{CS35L34_MULT_DEV_SYNCH2, 0x80},104	{CS35L34_PROT_RELEASE_CTL, 0x00},105	{CS35L34_DIAG_MODE_REG_LOCK, 0x00},106	{CS35L34_DIAG_MODE_CTL_1, 0x00},107	{CS35L34_DIAG_MODE_CTL_2, 0x00},108	{CS35L34_INT_MASK_1, 0xFF},109	{CS35L34_INT_MASK_2, 0xFF},110	{CS35L34_INT_MASK_3, 0xFF},111	{CS35L34_INT_MASK_4, 0xFF},112	{CS35L34_INT_STATUS_1, 0x30},113	{CS35L34_INT_STATUS_2, 0x05},114	{CS35L34_INT_STATUS_3, 0x00},115	{CS35L34_INT_STATUS_4, 0x00},116	{CS35L34_OTP_TRIM_STATUS, 0x00},117};118 119static bool cs35l34_volatile_register(struct device *dev, unsigned int reg)120{121	switch (reg) {122	case CS35L34_DEVID_AB:123	case CS35L34_DEVID_CD:124	case CS35L34_DEVID_E:125	case CS35L34_FAB_ID:126	case CS35L34_REV_ID:127	case CS35L34_INT_STATUS_1:128	case CS35L34_INT_STATUS_2:129	case CS35L34_INT_STATUS_3:130	case CS35L34_INT_STATUS_4:131	case CS35L34_CLASS_H_STATUS:132	case CS35L34_VPBR_ATTEN_STATUS:133	case CS35L34_OTP_TRIM_STATUS:134		return true;135	default:136		return false;137	}138}139 140static bool cs35l34_readable_register(struct device *dev, unsigned int reg)141{142	switch (reg) {143	case	CS35L34_DEVID_AB:144	case	CS35L34_DEVID_CD:145	case	CS35L34_DEVID_E:146	case	CS35L34_FAB_ID:147	case	CS35L34_REV_ID:148	case	CS35L34_PWRCTL1:149	case	CS35L34_PWRCTL2:150	case	CS35L34_PWRCTL3:151	case	CS35L34_ADSP_CLK_CTL:152	case	CS35L34_MCLK_CTL:153	case	CS35L34_AMP_INP_DRV_CTL:154	case	CS35L34_AMP_DIG_VOL_CTL:155	case	CS35L34_AMP_DIG_VOL:156	case	CS35L34_AMP_ANLG_GAIN_CTL:157	case	CS35L34_PROTECT_CTL:158	case	CS35L34_AMP_KEEP_ALIVE_CTL:159	case	CS35L34_BST_CVTR_V_CTL:160	case	CS35L34_BST_PEAK_I:161	case	CS35L34_BST_RAMP_CTL:162	case	CS35L34_BST_CONV_COEF_1:163	case	CS35L34_BST_CONV_COEF_2:164	case	CS35L34_BST_CONV_SLOPE_COMP:165	case	CS35L34_BST_CONV_SW_FREQ:166	case	CS35L34_CLASS_H_CTL:167	case	CS35L34_CLASS_H_HEADRM_CTL:168	case	CS35L34_CLASS_H_RELEASE_RATE:169	case	CS35L34_CLASS_H_FET_DRIVE_CTL:170	case	CS35L34_CLASS_H_STATUS:171	case	CS35L34_VPBR_CTL:172	case	CS35L34_VPBR_VOL_CTL:173	case	CS35L34_VPBR_TIMING_CTL:174	case	CS35L34_PRED_MAX_ATTEN_SPK_LOAD:175	case	CS35L34_PRED_BROWNOUT_THRESH:176	case	CS35L34_PRED_BROWNOUT_VOL_CTL:177	case	CS35L34_PRED_BROWNOUT_RATE_CTL:178	case	CS35L34_PRED_WAIT_CTL:179	case	CS35L34_PRED_ZVP_INIT_IMP_CTL:180	case	CS35L34_PRED_MAN_SAFE_VPI_CTL:181	case	CS35L34_VPBR_ATTEN_STATUS:182	case	CS35L34_PRED_BRWNOUT_ATT_STATUS:183	case	CS35L34_SPKR_MON_CTL:184	case	CS35L34_ADSP_I2S_CTL:185	case	CS35L34_ADSP_TDM_CTL:186	case	CS35L34_TDM_TX_CTL_1_VMON:187	case	CS35L34_TDM_TX_CTL_2_IMON:188	case	CS35L34_TDM_TX_CTL_3_VPMON:189	case	CS35L34_TDM_TX_CTL_4_VBSTMON:190	case	CS35L34_TDM_TX_CTL_5_FLAG1:191	case	CS35L34_TDM_TX_CTL_6_FLAG2:192	case	CS35L34_TDM_TX_SLOT_EN_1:193	case	CS35L34_TDM_TX_SLOT_EN_2:194	case	CS35L34_TDM_TX_SLOT_EN_3:195	case	CS35L34_TDM_TX_SLOT_EN_4:196	case	CS35L34_TDM_RX_CTL_1_AUDIN:197	case	CS35L34_TDM_RX_CTL_3_ALIVE:198	case	CS35L34_MULT_DEV_SYNCH1:199	case	CS35L34_MULT_DEV_SYNCH2:200	case	CS35L34_PROT_RELEASE_CTL:201	case	CS35L34_DIAG_MODE_REG_LOCK:202	case	CS35L34_DIAG_MODE_CTL_1:203	case	CS35L34_DIAG_MODE_CTL_2:204	case	CS35L34_INT_MASK_1:205	case	CS35L34_INT_MASK_2:206	case	CS35L34_INT_MASK_3:207	case	CS35L34_INT_MASK_4:208	case	CS35L34_INT_STATUS_1:209	case	CS35L34_INT_STATUS_2:210	case	CS35L34_INT_STATUS_3:211	case	CS35L34_INT_STATUS_4:212	case	CS35L34_OTP_TRIM_STATUS:213		return true;214	default:215		return false;216	}217}218 219static bool cs35l34_precious_register(struct device *dev, unsigned int reg)220{221	switch (reg) {222	case CS35L34_INT_STATUS_1:223	case CS35L34_INT_STATUS_2:224	case CS35L34_INT_STATUS_3:225	case CS35L34_INT_STATUS_4:226		return true;227	default:228		return false;229	}230}231 232static int cs35l34_sdin_event(struct snd_soc_dapm_widget *w,233		struct snd_kcontrol *kcontrol, int event)234{235	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);236	struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);237	int ret;238 239	switch (event) {240	case SND_SOC_DAPM_PRE_PMU:241		if (priv->tdm_mode)242			regmap_update_bits(priv->regmap, CS35L34_PWRCTL3,243						CS35L34_PDN_TDM, 0x00);244 245		ret = regmap_update_bits(priv->regmap, CS35L34_PWRCTL1,246						CS35L34_PDN_ALL, 0);247		if (ret < 0) {248			dev_err(component->dev, "Cannot set Power bits %d\n", ret);249			return ret;250		}251		usleep_range(5000, 5100);252	break;253	case SND_SOC_DAPM_POST_PMD:254		if (priv->tdm_mode) {255			regmap_update_bits(priv->regmap, CS35L34_PWRCTL3,256					CS35L34_PDN_TDM, CS35L34_PDN_TDM);257		}258		ret = regmap_update_bits(priv->regmap, CS35L34_PWRCTL1,259					CS35L34_PDN_ALL, CS35L34_PDN_ALL);260	break;261	default:262		pr_err("Invalid event = 0x%x\n", event);263	}264	return 0;265}266 267static int cs35l34_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,268				unsigned int rx_mask, int slots, int slot_width)269{270	struct snd_soc_component *component = dai->component;271	struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);272	unsigned int reg, bit_pos;273	int slot, slot_num;274 275	if (slot_width != 8)276		return -EINVAL;277 278	priv->tdm_mode = true;279	/* scan rx_mask for aud slot */280	slot = ffs(rx_mask) - 1;281	if (slot >= 0)282		snd_soc_component_update_bits(component, CS35L34_TDM_RX_CTL_1_AUDIN,283					CS35L34_X_LOC, slot);284 285	/* scan tx_mask: vmon(2 slots); imon (2 slots); vpmon (1 slot)286	 * vbstmon (1 slot)287	 */288	slot = ffs(tx_mask) - 1;289	slot_num = 0;290 291	/* disable vpmon/vbstmon: enable later if set in tx_mask */292	snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_3_VPMON,293				CS35L34_X_STATE | CS35L34_X_LOC,294				CS35L34_X_STATE | CS35L34_X_LOC);295	snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_4_VBSTMON,296				CS35L34_X_STATE | CS35L34_X_LOC,297				CS35L34_X_STATE | CS35L34_X_LOC);298 299	/* disconnect {vp,vbst}_mon routes: eanble later if set in tx_mask*/300	while (slot >= 0) {301		/* configure VMON_TX_LOC */302		if (slot_num == 0)303			snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_1_VMON,304					CS35L34_X_STATE | CS35L34_X_LOC, slot);305 306		/* configure IMON_TX_LOC */307		if (slot_num == 4) {308			snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_2_IMON,309					CS35L34_X_STATE | CS35L34_X_LOC, slot);310		}311		/* configure VPMON_TX_LOC */312		if (slot_num == 3) {313			snd_soc_component_update_bits(component, CS35L34_TDM_TX_CTL_3_VPMON,314					CS35L34_X_STATE | CS35L34_X_LOC, slot);315		}316		/* configure VBSTMON_TX_LOC */317		if (slot_num == 7) {318			snd_soc_component_update_bits(component,319				CS35L34_TDM_TX_CTL_4_VBSTMON,320				CS35L34_X_STATE | CS35L34_X_LOC, slot);321		}322 323		/* Enable the relevant tx slot */324		reg = CS35L34_TDM_TX_SLOT_EN_4 - (slot/8);325		bit_pos = slot - ((slot / 8) * (8));326		snd_soc_component_update_bits(component, reg,327			1 << bit_pos, 1 << bit_pos);328 329		tx_mask &= ~(1 << slot);330		slot = ffs(tx_mask) - 1;331		slot_num++;332	}333 334	return 0;335}336 337static int cs35l34_main_amp_event(struct snd_soc_dapm_widget *w,338		struct snd_kcontrol *kcontrol, int event)339{340	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);341	struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);342 343	switch (event) {344	case SND_SOC_DAPM_POST_PMU:345		regmap_update_bits(priv->regmap, CS35L34_BST_CVTR_V_CTL,346				CS35L34_BST_CVTL_MASK, priv->pdata.boost_vtge);347		usleep_range(5000, 5100);348		regmap_update_bits(priv->regmap, CS35L34_PROTECT_CTL,349						CS35L34_MUTE, 0);350		break;351	case SND_SOC_DAPM_POST_PMD:352		regmap_update_bits(priv->regmap, CS35L34_BST_CVTR_V_CTL,353			CS35L34_BST_CVTL_MASK, 0);354		regmap_update_bits(priv->regmap, CS35L34_PROTECT_CTL,355			CS35L34_MUTE, CS35L34_MUTE);356		usleep_range(5000, 5100);357		break;358	default:359		pr_err("Invalid event = 0x%x\n", event);360	}361	return 0;362}363 364static DECLARE_TLV_DB_SCALE(dig_vol_tlv, -10200, 50, 0);365 366static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 300, 100, 0);367 368 369static const struct snd_kcontrol_new cs35l34_snd_controls[] = {370	SOC_SINGLE_SX_TLV("Digital Volume", CS35L34_AMP_DIG_VOL,371		      0, 0x34, 0xE4, dig_vol_tlv),372	SOC_SINGLE_TLV("Amp Gain Volume", CS35L34_AMP_ANLG_GAIN_CTL,373		      0, 0xF, 0, amp_gain_tlv),374};375 376 377static int cs35l34_mclk_event(struct snd_soc_dapm_widget *w,378		struct snd_kcontrol *kcontrol, int event)379{380	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);381	struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);382	int ret, i;383	unsigned int reg;384 385	switch (event) {386	case SND_SOC_DAPM_PRE_PMD:387		ret = regmap_read(priv->regmap, CS35L34_AMP_DIG_VOL_CTL,388			&reg);389		if (ret != 0) {390			pr_err("%s regmap read failure %d\n", __func__, ret);391			return ret;392		}393		if (reg & CS35L34_AMP_DIGSFT)394			msleep(40);395		else396			usleep_range(2000, 2100);397 398		for (i = 0; i < PDN_DONE_ATTEMPTS; i++) {399			ret = regmap_read(priv->regmap, CS35L34_INT_STATUS_2,400				&reg);401			if (ret != 0) {402				pr_err("%s regmap read failure %d\n",403					__func__, ret);404				return ret;405			}406			if (reg & CS35L34_PDN_DONE)407				break;408 409			usleep_range(5000, 5100);410		}411		if (i == PDN_DONE_ATTEMPTS)412			pr_err("%s Device did not power down properly\n",413				__func__);414		break;415	default:416		pr_err("Invalid event = 0x%x\n", event);417		break;418	}419	return 0;420}421 422static const struct snd_soc_dapm_widget cs35l34_dapm_widgets[] = {423	SND_SOC_DAPM_AIF_IN_E("SDIN", NULL, 0, CS35L34_PWRCTL3,424					1, 1, cs35l34_sdin_event,425					SND_SOC_DAPM_PRE_PMU |426					SND_SOC_DAPM_POST_PMD),427	SND_SOC_DAPM_AIF_OUT("SDOUT", NULL, 0, CS35L34_PWRCTL3, 2, 1),428 429	SND_SOC_DAPM_SUPPLY("EXTCLK", CS35L34_PWRCTL3, 7, 1,430		cs35l34_mclk_event, SND_SOC_DAPM_PRE_PMD),431 432	SND_SOC_DAPM_OUTPUT("SPK"),433 434	SND_SOC_DAPM_INPUT("VP"),435	SND_SOC_DAPM_INPUT("VPST"),436	SND_SOC_DAPM_INPUT("ISENSE"),437	SND_SOC_DAPM_INPUT("VSENSE"),438 439	SND_SOC_DAPM_ADC("VMON ADC", NULL, CS35L34_PWRCTL2, 7, 1),440	SND_SOC_DAPM_ADC("IMON ADC", NULL, CS35L34_PWRCTL2, 6, 1),441	SND_SOC_DAPM_ADC("VPMON ADC", NULL, CS35L34_PWRCTL3, 3, 1),442	SND_SOC_DAPM_ADC("VBSTMON ADC", NULL, CS35L34_PWRCTL3, 4, 1),443	SND_SOC_DAPM_ADC("CLASS H", NULL, CS35L34_PWRCTL2, 5, 1),444	SND_SOC_DAPM_ADC("BOOST", NULL, CS35L34_PWRCTL2, 2, 1),445 446	SND_SOC_DAPM_OUT_DRV_E("Main AMP", CS35L34_PWRCTL2, 0, 1, NULL, 0,447		cs35l34_main_amp_event, SND_SOC_DAPM_POST_PMU |448			SND_SOC_DAPM_POST_PMD),449};450 451static const struct snd_soc_dapm_route cs35l34_audio_map[] = {452	{"SDIN", NULL, "AMP Playback"},453	{"BOOST", NULL, "SDIN"},454	{"CLASS H", NULL, "BOOST"},455	{"Main AMP", NULL, "CLASS H"},456	{"SPK", NULL, "Main AMP"},457 458	{"VPMON ADC", NULL, "CLASS H"},459	{"VBSTMON ADC", NULL, "CLASS H"},460	{"SPK", NULL, "VPMON ADC"},461	{"SPK", NULL, "VBSTMON ADC"},462 463	{"IMON ADC", NULL, "ISENSE"},464	{"VMON ADC", NULL, "VSENSE"},465	{"SDOUT", NULL, "IMON ADC"},466	{"SDOUT", NULL, "VMON ADC"},467	{"AMP Capture", NULL, "SDOUT"},468 469	{"SDIN", NULL, "EXTCLK"},470	{"SDOUT", NULL, "EXTCLK"},471};472 473struct cs35l34_mclk_div {474	int mclk;475	int srate;476	u8 adsp_rate;477};478 479static struct cs35l34_mclk_div cs35l34_mclk_coeffs[] = {480 481	/* MCLK, Sample Rate, adsp_rate */482 483	{5644800, 11025, 0x1},484	{5644800, 22050, 0x4},485	{5644800, 44100, 0x7},486 487	{6000000,  8000, 0x0},488	{6000000, 11025, 0x1},489	{6000000, 12000, 0x2},490	{6000000, 16000, 0x3},491	{6000000, 22050, 0x4},492	{6000000, 24000, 0x5},493	{6000000, 32000, 0x6},494	{6000000, 44100, 0x7},495	{6000000, 48000, 0x8},496 497	{6144000,  8000, 0x0},498	{6144000, 11025, 0x1},499	{6144000, 12000, 0x2},500	{6144000, 16000, 0x3},501	{6144000, 22050, 0x4},502	{6144000, 24000, 0x5},503	{6144000, 32000, 0x6},504	{6144000, 44100, 0x7},505	{6144000, 48000, 0x8},506};507 508static int cs35l34_get_mclk_coeff(int mclk, int srate)509{510	int i;511 512	for (i = 0; i < ARRAY_SIZE(cs35l34_mclk_coeffs); i++) {513		if (cs35l34_mclk_coeffs[i].mclk == mclk &&514			cs35l34_mclk_coeffs[i].srate == srate)515			return i;516	}517	return -EINVAL;518}519 520static int cs35l34_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)521{522	struct snd_soc_component *component = codec_dai->component;523	struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);524 525	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {526	case SND_SOC_DAIFMT_CBM_CFM:527		regmap_update_bits(priv->regmap, CS35L34_ADSP_CLK_CTL,528				    0x80, 0x80);529		break;530	case SND_SOC_DAIFMT_CBS_CFS:531		regmap_update_bits(priv->regmap, CS35L34_ADSP_CLK_CTL,532				    0x80, 0x00);533		break;534	default:535		return -EINVAL;536	}537	return 0;538}539 540static int cs35l34_pcm_hw_params(struct snd_pcm_substream *substream,541				 struct snd_pcm_hw_params *params,542				 struct snd_soc_dai *dai)543{544	struct snd_soc_component *component = dai->component;545	struct cs35l34_private *priv = snd_soc_component_get_drvdata(component);546	int srate = params_rate(params);547	int ret;548 549	int coeff = cs35l34_get_mclk_coeff(priv->mclk_int, srate);550 551	if (coeff < 0) {552		dev_err(component->dev, "ERROR: Invalid mclk %d and/or srate %d\n",553			priv->mclk_int, srate);554		return coeff;555	}556 557	ret = regmap_update_bits(priv->regmap, CS35L34_ADSP_CLK_CTL,558		CS35L34_ADSP_RATE, cs35l34_mclk_coeffs[coeff].adsp_rate);559	if (ret != 0)560		dev_err(component->dev, "Failed to set clock state %d\n", ret);561 562	return ret;563}564 565static int cs35l34_set_tristate(struct snd_soc_dai *dai, int tristate)566{567 568	struct snd_soc_component *component = dai->component;569 570	if (tristate)571		snd_soc_component_update_bits(component, CS35L34_PWRCTL3,572					CS35L34_PDN_SDOUT, CS35L34_PDN_SDOUT);573	else574		snd_soc_component_update_bits(component, CS35L34_PWRCTL3,575					CS35L34_PDN_SDOUT, 0);576	return 0;577}578 579static int cs35l34_dai_set_sysclk(struct snd_soc_dai *dai,580				int clk_id, unsigned int freq, int dir)581{582	struct snd_soc_component *component = dai->component;583	struct cs35l34_private *cs35l34 = snd_soc_component_get_drvdata(component);584	unsigned int value;585 586	switch (freq) {587	case CS35L34_MCLK_5644:588		value = CS35L34_MCLK_RATE_5P6448;589		cs35l34->mclk_int = freq;590	break;591	case CS35L34_MCLK_6:592		value = CS35L34_MCLK_RATE_6P0000;593		cs35l34->mclk_int = freq;594	break;595	case CS35L34_MCLK_6144:596		value = CS35L34_MCLK_RATE_6P1440;597		cs35l34->mclk_int = freq;598	break;599	case CS35L34_MCLK_11289:600		value = CS35L34_MCLK_DIV | CS35L34_MCLK_RATE_5P6448;601		cs35l34->mclk_int = freq / 2;602	break;603	case CS35L34_MCLK_12:604		value = CS35L34_MCLK_DIV | CS35L34_MCLK_RATE_6P0000;605		cs35l34->mclk_int = freq / 2;606	break;607	case CS35L34_MCLK_12288:608		value = CS35L34_MCLK_DIV | CS35L34_MCLK_RATE_6P1440;609		cs35l34->mclk_int = freq / 2;610	break;611	default:612		dev_err(component->dev, "ERROR: Invalid Frequency %d\n", freq);613		cs35l34->mclk_int = 0;614		return -EINVAL;615	}616	regmap_update_bits(cs35l34->regmap, CS35L34_MCLK_CTL,617			CS35L34_MCLK_DIV | CS35L34_MCLK_RATE_MASK, value);618	return 0;619}620 621static const struct snd_soc_dai_ops cs35l34_ops = {622	.set_tristate = cs35l34_set_tristate,623	.set_fmt = cs35l34_set_dai_fmt,624	.hw_params = cs35l34_pcm_hw_params,625	.set_sysclk = cs35l34_dai_set_sysclk,626	.set_tdm_slot = cs35l34_set_tdm_slot,627};628 629static struct snd_soc_dai_driver cs35l34_dai = {630		.name = "cs35l34",631		.id = 0,632		.playback = {633			.stream_name = "AMP Playback",634			.channels_min = 1,635			.channels_max = 8,636			.rates = CS35L34_RATES,637			.formats = CS35L34_FORMATS,638		},639		.capture = {640			.stream_name = "AMP Capture",641			.channels_min = 1,642			.channels_max = 8,643			.rates = CS35L34_RATES,644			.formats = CS35L34_FORMATS,645		},646		.ops = &cs35l34_ops,647		.symmetric_rate = 1,648};649 650static int cs35l34_boost_inductor(struct cs35l34_private *cs35l34,651	unsigned int inductor)652{653	struct snd_soc_component *component = cs35l34->component;654 655	switch (inductor) {656	case 1000: /* 1 uH */657		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_1, 0x24);658		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_2, 0x24);659		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SLOPE_COMP,660			0x4E);661		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SW_FREQ, 0);662		break;663	case 1200: /* 1.2 uH */664		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_1, 0x20);665		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_2, 0x20);666		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SLOPE_COMP,667			0x47);668		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SW_FREQ, 1);669		break;670	case 1500: /* 1.5uH */671		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_1, 0x20);672		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_2, 0x20);673		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SLOPE_COMP,674			0x3C);675		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SW_FREQ, 2);676		break;677	case 2200: /* 2.2uH */678		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_1, 0x19);679		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_COEF_2, 0x25);680		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SLOPE_COMP,681			0x23);682		regmap_write(cs35l34->regmap, CS35L34_BST_CONV_SW_FREQ, 3);683		break;684	default:685		dev_err(component->dev, "%s Invalid Inductor Value %d uH\n",686			__func__, inductor);687		return -EINVAL;688	}689	return 0;690}691 692static int cs35l34_probe(struct snd_soc_component *component)693{694	int ret = 0;695	struct cs35l34_private *cs35l34 = snd_soc_component_get_drvdata(component);696 697	pm_runtime_get_sync(component->dev);698 699	/* Set over temperature warning attenuation to 6 dB */700	regmap_update_bits(cs35l34->regmap, CS35L34_PROTECT_CTL,701		 CS35L34_OTW_ATTN_MASK, 0x8);702 703	/* Set Power control registers 2 and 3 to have everything704	 * powered down at initialization705	 */706	regmap_write(cs35l34->regmap, CS35L34_PWRCTL2, 0xFD);707	regmap_write(cs35l34->regmap, CS35L34_PWRCTL3, 0x1F);708 709	/* Set mute bit at startup */710	regmap_update_bits(cs35l34->regmap, CS35L34_PROTECT_CTL,711				CS35L34_MUTE, CS35L34_MUTE);712 713	/* Set Platform Data */714	if (cs35l34->pdata.boost_peak)715		regmap_update_bits(cs35l34->regmap, CS35L34_BST_PEAK_I,716				CS35L34_BST_PEAK_MASK,717				cs35l34->pdata.boost_peak);718 719	if (cs35l34->pdata.gain_zc_disable)720		regmap_update_bits(cs35l34->regmap, CS35L34_PROTECT_CTL,721			CS35L34_GAIN_ZC_MASK, 0);722	else723		regmap_update_bits(cs35l34->regmap, CS35L34_PROTECT_CTL,724			CS35L34_GAIN_ZC_MASK, CS35L34_GAIN_ZC_MASK);725 726	if (cs35l34->pdata.aif_half_drv)727		regmap_update_bits(cs35l34->regmap, CS35L34_ADSP_CLK_CTL,728			CS35L34_ADSP_DRIVE, 0);729 730	if (cs35l34->pdata.digsft_disable)731		regmap_update_bits(cs35l34->regmap, CS35L34_AMP_DIG_VOL_CTL,732			CS35L34_AMP_DIGSFT, 0);733 734	if (cs35l34->pdata.amp_inv)735		regmap_update_bits(cs35l34->regmap, CS35L34_AMP_DIG_VOL_CTL,736			CS35L34_INV, CS35L34_INV);737 738	if (cs35l34->pdata.boost_ind)739		ret = cs35l34_boost_inductor(cs35l34, cs35l34->pdata.boost_ind);740 741	if (cs35l34->pdata.i2s_sdinloc)742		regmap_update_bits(cs35l34->regmap, CS35L34_ADSP_I2S_CTL,743			CS35L34_I2S_LOC_MASK,744			cs35l34->pdata.i2s_sdinloc << CS35L34_I2S_LOC_SHIFT);745 746	if (cs35l34->pdata.tdm_rising_edge)747		regmap_update_bits(cs35l34->regmap, CS35L34_ADSP_TDM_CTL,748			1, 1);749 750	pm_runtime_put_sync(component->dev);751 752	return ret;753}754 755 756static const struct snd_soc_component_driver soc_component_dev_cs35l34 = {757	.probe			= cs35l34_probe,758	.dapm_widgets		= cs35l34_dapm_widgets,759	.num_dapm_widgets	= ARRAY_SIZE(cs35l34_dapm_widgets),760	.dapm_routes		= cs35l34_audio_map,761	.num_dapm_routes	= ARRAY_SIZE(cs35l34_audio_map),762	.controls		= cs35l34_snd_controls,763	.num_controls		= ARRAY_SIZE(cs35l34_snd_controls),764	.idle_bias_on		= 1,765	.use_pmdown_time	= 1,766	.endianness		= 1,767};768 769static const struct regmap_config cs35l34_regmap = {770	.reg_bits = 8,771	.val_bits = 8,772 773	.max_register = CS35L34_MAX_REGISTER,774	.reg_defaults = cs35l34_reg,775	.num_reg_defaults = ARRAY_SIZE(cs35l34_reg),776	.volatile_reg = cs35l34_volatile_register,777	.readable_reg = cs35l34_readable_register,778	.precious_reg = cs35l34_precious_register,779	.cache_type = REGCACHE_MAPLE,780 781	.use_single_read = true,782	.use_single_write = true,783};784 785static int cs35l34_handle_of_data(struct i2c_client *i2c_client,786				struct cs35l34_platform_data *pdata)787{788	struct device_node *np = i2c_client->dev.of_node;789	unsigned int val;790 791	if (of_property_read_u32(np, "cirrus,boost-vtge-millivolt",792		&val) >= 0) {793		/* Boost Voltage has a maximum of 8V */794		if (val > 8000 || (val < 3300 && val > 0)) {795			dev_err(&i2c_client->dev,796				"Invalid Boost Voltage %d mV\n", val);797			return -EINVAL;798		}799		if (val == 0)800			pdata->boost_vtge = 0; /* Use VP */801		else802			pdata->boost_vtge = ((val - 3300)/100) + 1;803	} else {804		dev_warn(&i2c_client->dev,805			"Boost Voltage not specified. Using VP\n");806	}807 808	if (of_property_read_u32(np, "cirrus,boost-ind-nanohenry", &val) >= 0) {809		pdata->boost_ind = val;810	} else {811		dev_err(&i2c_client->dev, "Inductor not specified.\n");812		return -EINVAL;813	}814 815	if (of_property_read_u32(np, "cirrus,boost-peak-milliamp", &val) >= 0) {816		if (val > 3840 || val < 1200) {817			dev_err(&i2c_client->dev,818				"Invalid Boost Peak Current %d mA\n", val);819			return -EINVAL;820		}821		pdata->boost_peak = ((val - 1200)/80) + 1;822	}823 824	pdata->aif_half_drv = of_property_read_bool(np,825		"cirrus,aif-half-drv");826	pdata->digsft_disable = of_property_read_bool(np,827		"cirrus,digsft-disable");828 829	pdata->gain_zc_disable = of_property_read_bool(np,830		"cirrus,gain-zc-disable");831	pdata->amp_inv = of_property_read_bool(np, "cirrus,amp-inv");832 833	if (of_property_read_u32(np, "cirrus,i2s-sdinloc", &val) >= 0)834		pdata->i2s_sdinloc = val;835	if (of_property_read_u32(np, "cirrus,tdm-rising-edge", &val) >= 0)836		pdata->tdm_rising_edge = val;837 838	return 0;839}840 841static irqreturn_t cs35l34_irq_thread(int irq, void *data)842{843	struct cs35l34_private *cs35l34 = data;844	struct snd_soc_component *component = cs35l34->component;845	unsigned int sticky1, sticky2, sticky3, sticky4;846	unsigned int mask1, mask2, mask3, mask4, current1;847 848 849	/* ack the irq by reading all status registers */850	regmap_read(cs35l34->regmap, CS35L34_INT_STATUS_4, &sticky4);851	regmap_read(cs35l34->regmap, CS35L34_INT_STATUS_3, &sticky3);852	regmap_read(cs35l34->regmap, CS35L34_INT_STATUS_2, &sticky2);853	regmap_read(cs35l34->regmap, CS35L34_INT_STATUS_1, &sticky1);854 855	regmap_read(cs35l34->regmap, CS35L34_INT_MASK_4, &mask4);856	regmap_read(cs35l34->regmap, CS35L34_INT_MASK_3, &mask3);857	regmap_read(cs35l34->regmap, CS35L34_INT_MASK_2, &mask2);858	regmap_read(cs35l34->regmap, CS35L34_INT_MASK_1, &mask1);859 860	if (!(sticky1 & ~mask1) && !(sticky2 & ~mask2) && !(sticky3 & ~mask3)861		&& !(sticky4 & ~mask4))862		return IRQ_NONE;863 864	regmap_read(cs35l34->regmap, CS35L34_INT_STATUS_1, &current1);865 866	if (sticky1 & CS35L34_CAL_ERR) {867		dev_err(component->dev, "Cal error\n");868 869		/* error is no longer asserted; safe to reset */870		if (!(current1 & CS35L34_CAL_ERR)) {871			dev_dbg(component->dev, "Cal error release\n");872			regmap_update_bits(cs35l34->regmap,873					CS35L34_PROT_RELEASE_CTL,874					CS35L34_CAL_ERR_RLS, 0);875			regmap_update_bits(cs35l34->regmap,876					CS35L34_PROT_RELEASE_CTL,877					CS35L34_CAL_ERR_RLS,878					CS35L34_CAL_ERR_RLS);879			regmap_update_bits(cs35l34->regmap,880					CS35L34_PROT_RELEASE_CTL,881					CS35L34_CAL_ERR_RLS, 0);882			/* note: amp will re-calibrate on next resume */883		}884	}885 886	if (sticky1 & CS35L34_ALIVE_ERR)887		dev_err(component->dev, "Alive error\n");888 889	if (sticky1 & CS35L34_AMP_SHORT) {890		dev_crit(component->dev, "Amp short error\n");891 892		/* error is no longer asserted; safe to reset */893		if (!(current1 & CS35L34_AMP_SHORT)) {894			dev_dbg(component->dev,895				"Amp short error release\n");896			regmap_update_bits(cs35l34->regmap,897					CS35L34_PROT_RELEASE_CTL,898					CS35L34_SHORT_RLS, 0);899			regmap_update_bits(cs35l34->regmap,900					CS35L34_PROT_RELEASE_CTL,901					CS35L34_SHORT_RLS,902					CS35L34_SHORT_RLS);903			regmap_update_bits(cs35l34->regmap,904					CS35L34_PROT_RELEASE_CTL,905					CS35L34_SHORT_RLS, 0);906		}907	}908 909	if (sticky1 & CS35L34_OTW) {910		dev_crit(component->dev, "Over temperature warning\n");911 912		/* error is no longer asserted; safe to reset */913		if (!(current1 & CS35L34_OTW)) {914			dev_dbg(component->dev,915				"Over temperature warning release\n");916			regmap_update_bits(cs35l34->regmap,917					CS35L34_PROT_RELEASE_CTL,918					CS35L34_OTW_RLS, 0);919			regmap_update_bits(cs35l34->regmap,920					CS35L34_PROT_RELEASE_CTL,921					CS35L34_OTW_RLS,922					CS35L34_OTW_RLS);923			regmap_update_bits(cs35l34->regmap,924					CS35L34_PROT_RELEASE_CTL,925					CS35L34_OTW_RLS, 0);926		}927	}928 929	if (sticky1 & CS35L34_OTE) {930		dev_crit(component->dev, "Over temperature error\n");931 932		/* error is no longer asserted; safe to reset */933		if (!(current1 & CS35L34_OTE)) {934			dev_dbg(component->dev,935				"Over temperature error release\n");936			regmap_update_bits(cs35l34->regmap,937					CS35L34_PROT_RELEASE_CTL,938					CS35L34_OTE_RLS, 0);939			regmap_update_bits(cs35l34->regmap,940					CS35L34_PROT_RELEASE_CTL,941					CS35L34_OTE_RLS,942					CS35L34_OTE_RLS);943			regmap_update_bits(cs35l34->regmap,944					CS35L34_PROT_RELEASE_CTL,945					CS35L34_OTE_RLS, 0);946		}947	}948 949	if (sticky3 & CS35L34_BST_HIGH) {950		dev_crit(component->dev, "VBST too high error; powering off!\n");951		regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL2,952				CS35L34_PDN_AMP, CS35L34_PDN_AMP);953		regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL1,954				CS35L34_PDN_ALL, CS35L34_PDN_ALL);955	}956 957	if (sticky3 & CS35L34_LBST_SHORT) {958		dev_crit(component->dev, "LBST short error; powering off!\n");959		regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL2,960				CS35L34_PDN_AMP, CS35L34_PDN_AMP);961		regmap_update_bits(cs35l34->regmap, CS35L34_PWRCTL1,962				CS35L34_PDN_ALL, CS35L34_PDN_ALL);963	}964 965	return IRQ_HANDLED;966}967 968static const char * const cs35l34_core_supplies[] = {969	"VA",970	"VP",971};972 973static int cs35l34_i2c_probe(struct i2c_client *i2c_client)974{975	struct cs35l34_private *cs35l34;976	struct cs35l34_platform_data *pdata =977		dev_get_platdata(&i2c_client->dev);978	int i, devid;979	int ret;980	unsigned int reg;981 982	cs35l34 = devm_kzalloc(&i2c_client->dev, sizeof(*cs35l34), GFP_KERNEL);983	if (!cs35l34)984		return -ENOMEM;985 986	i2c_set_clientdata(i2c_client, cs35l34);987	cs35l34->regmap = devm_regmap_init_i2c(i2c_client, &cs35l34_regmap);988	if (IS_ERR(cs35l34->regmap)) {989		ret = PTR_ERR(cs35l34->regmap);990		dev_err(&i2c_client->dev, "regmap_init() failed: %d\n", ret);991		return ret;992	}993 994	cs35l34->num_core_supplies = ARRAY_SIZE(cs35l34_core_supplies);995	for (i = 0; i < ARRAY_SIZE(cs35l34_core_supplies); i++)996		cs35l34->core_supplies[i].supply = cs35l34_core_supplies[i];997 998	ret = devm_regulator_bulk_get(&i2c_client->dev,999		cs35l34->num_core_supplies,1000		cs35l34->core_supplies);1001	if (ret != 0) {1002		dev_err(&i2c_client->dev,1003			"Failed to request core supplies %d\n", ret);1004		return ret;1005	}1006 1007	ret = regulator_bulk_enable(cs35l34->num_core_supplies,1008					cs35l34->core_supplies);1009	if (ret != 0) {1010		dev_err(&i2c_client->dev,1011			"Failed to enable core supplies: %d\n", ret);1012		return ret;1013	}1014 1015	if (pdata) {1016		cs35l34->pdata = *pdata;1017	} else {1018		pdata = devm_kzalloc(&i2c_client->dev, sizeof(*pdata),1019				     GFP_KERNEL);1020		if (!pdata) {1021			ret = -ENOMEM;1022			goto err_regulator;1023		}1024 1025		if (i2c_client->dev.of_node) {1026			ret = cs35l34_handle_of_data(i2c_client, pdata);1027			if (ret != 0)1028				goto err_regulator;1029 1030		}1031		cs35l34->pdata = *pdata;1032	}1033 1034	ret = devm_request_threaded_irq(&i2c_client->dev, i2c_client->irq, NULL,1035			cs35l34_irq_thread, IRQF_ONESHOT | IRQF_TRIGGER_LOW,1036			"cs35l34", cs35l34);1037	if (ret != 0)1038		dev_err(&i2c_client->dev, "Failed to request IRQ: %d\n", ret);1039 1040	cs35l34->reset_gpio = devm_gpiod_get_optional(&i2c_client->dev,1041				"reset", GPIOD_OUT_LOW);1042	if (IS_ERR(cs35l34->reset_gpio)) {1043		ret = PTR_ERR(cs35l34->reset_gpio);1044		goto err_regulator;1045	}1046 1047	gpiod_set_value_cansleep(cs35l34->reset_gpio, 1);1048 1049	msleep(CS35L34_START_DELAY);1050 1051	devid = cirrus_read_device_id(cs35l34->regmap, CS35L34_DEVID_AB);1052	if (devid < 0) {1053		ret = devid;1054		dev_err(&i2c_client->dev, "Failed to read device ID: %d\n", ret);1055		goto err_reset;1056	}1057 1058	if (devid != CS35L34_CHIP_ID) {1059		dev_err(&i2c_client->dev,1060			"CS35l34 Device ID (%X). Expected ID %X\n",1061			devid, CS35L34_CHIP_ID);1062		ret = -ENODEV;1063		goto err_reset;1064	}1065 1066	ret = regmap_read(cs35l34->regmap, CS35L34_REV_ID, &reg);1067	if (ret < 0) {1068		dev_err(&i2c_client->dev, "Get Revision ID failed\n");1069		goto err_reset;1070	}1071 1072	dev_info(&i2c_client->dev,1073		 "Cirrus Logic CS35l34 (%x), Revision: %02X\n", devid,1074		reg & 0xFF);1075 1076	/* Unmask critical interrupts */1077	regmap_update_bits(cs35l34->regmap, CS35L34_INT_MASK_1,1078				CS35L34_M_CAL_ERR | CS35L34_M_ALIVE_ERR |1079				CS35L34_M_AMP_SHORT | CS35L34_M_OTW |1080				CS35L34_M_OTE, 0);1081	regmap_update_bits(cs35l34->regmap, CS35L34_INT_MASK_3,1082				CS35L34_M_BST_HIGH | CS35L34_M_LBST_SHORT, 0);1083 1084	pm_runtime_set_autosuspend_delay(&i2c_client->dev, 100);1085	pm_runtime_use_autosuspend(&i2c_client->dev);1086	pm_runtime_set_active(&i2c_client->dev);1087	pm_runtime_enable(&i2c_client->dev);1088 1089	ret = devm_snd_soc_register_component(&i2c_client->dev,1090			&soc_component_dev_cs35l34, &cs35l34_dai, 1);1091	if (ret < 0) {1092		dev_err(&i2c_client->dev,1093			"%s: Register component failed\n", __func__);1094		goto err_reset;1095	}1096 1097	return 0;1098 1099err_reset:1100	gpiod_set_value_cansleep(cs35l34->reset_gpio, 0);1101err_regulator:1102	regulator_bulk_disable(cs35l34->num_core_supplies,1103		cs35l34->core_supplies);1104 1105	return ret;1106}1107 1108static void cs35l34_i2c_remove(struct i2c_client *client)1109{1110	struct cs35l34_private *cs35l34 = i2c_get_clientdata(client);1111 1112	gpiod_set_value_cansleep(cs35l34->reset_gpio, 0);1113 1114	pm_runtime_disable(&client->dev);1115	regulator_bulk_disable(cs35l34->num_core_supplies,1116		cs35l34->core_supplies);1117}1118 1119static int __maybe_unused cs35l34_runtime_resume(struct device *dev)1120{1121	struct cs35l34_private *cs35l34 = dev_get_drvdata(dev);1122	int ret;1123 1124	ret = regulator_bulk_enable(cs35l34->num_core_supplies,1125		cs35l34->core_supplies);1126 1127	if (ret != 0) {1128		dev_err(dev, "Failed to enable core supplies: %d\n",1129			ret);1130		return ret;1131	}1132 1133	regcache_cache_only(cs35l34->regmap, false);1134 1135	gpiod_set_value_cansleep(cs35l34->reset_gpio, 1);1136	msleep(CS35L34_START_DELAY);1137 1138	ret = regcache_sync(cs35l34->regmap);1139	if (ret != 0) {1140		dev_err(dev, "Failed to restore register cache\n");1141		goto err;1142	}1143	return 0;1144err:1145	regcache_cache_only(cs35l34->regmap, true);1146	regulator_bulk_disable(cs35l34->num_core_supplies,1147		cs35l34->core_supplies);1148 1149	return ret;1150}1151 1152static int __maybe_unused cs35l34_runtime_suspend(struct device *dev)1153{1154	struct cs35l34_private *cs35l34 = dev_get_drvdata(dev);1155 1156	regcache_cache_only(cs35l34->regmap, true);1157	regcache_mark_dirty(cs35l34->regmap);1158 1159	gpiod_set_value_cansleep(cs35l34->reset_gpio, 0);1160 1161	regulator_bulk_disable(cs35l34->num_core_supplies,1162			cs35l34->core_supplies);1163 1164	return 0;1165}1166 1167static const struct dev_pm_ops cs35l34_pm_ops = {1168	SET_RUNTIME_PM_OPS(cs35l34_runtime_suspend,1169			   cs35l34_runtime_resume,1170			   NULL)1171};1172 1173static const struct of_device_id cs35l34_of_match[] = {1174	{.compatible = "cirrus,cs35l34"},1175	{},1176};1177MODULE_DEVICE_TABLE(of, cs35l34_of_match);1178 1179static const struct i2c_device_id cs35l34_id[] = {1180	{"cs35l34"},1181	{}1182};1183MODULE_DEVICE_TABLE(i2c, cs35l34_id);1184 1185static struct i2c_driver cs35l34_i2c_driver = {1186	.driver = {1187		.name = "cs35l34",1188		.pm = &cs35l34_pm_ops,1189		.of_match_table = cs35l34_of_match,1190 1191		},1192	.id_table = cs35l34_id,1193	.probe = cs35l34_i2c_probe,1194	.remove = cs35l34_i2c_remove,1195 1196};1197 1198static int __init cs35l34_modinit(void)1199{1200	int ret;1201 1202	ret = i2c_add_driver(&cs35l34_i2c_driver);1203	if (ret != 0) {1204		pr_err("Failed to register CS35l34 I2C driver: %d\n", ret);1205		return ret;1206	}1207	return 0;1208}1209module_init(cs35l34_modinit);1210 1211static void __exit cs35l34_exit(void)1212{1213	i2c_del_driver(&cs35l34_i2c_driver);1214}1215module_exit(cs35l34_exit);1216 1217MODULE_DESCRIPTION("ASoC CS35l34 driver");1218MODULE_AUTHOR("Paul Handrigan, Cirrus Logic Inc, <Paul.Handrigan@cirrus.com>");1219MODULE_LICENSE("GPL");1220