brintos

brintos / linux-shallow public Read only

0
0
Text · 74.0 KiB · f8e2fb6 Raw
2783 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * cs43130.c  --  CS43130 ALSA Soc Audio driver4 *5 * Copyright 2017 Cirrus Logic, Inc.6 *7 * Authors: Li Xu <li.xu@cirrus.com>8 */9#include <linux/module.h>10#include <linux/moduleparam.h>11#include <linux/kernel.h>12#include <linux/init.h>13#include <linux/delay.h>14#include <linux/gpio/consumer.h>15#include <linux/platform_device.h>16#include <linux/pm.h>17#include <linux/i2c.h>18#include <linux/property.h>19#include <linux/regmap.h>20#include <linux/slab.h>21#include <sound/core.h>22#include <sound/pcm.h>23#include <sound/pcm_params.h>24#include <sound/soc.h>25#include <sound/soc-dapm.h>26#include <sound/initval.h>27#include <sound/tlv.h>28#include <linux/regulator/consumer.h>29#include <linux/pm_runtime.h>30#include <linux/completion.h>31#include <linux/mutex.h>32#include <linux/workqueue.h>33#include <sound/jack.h>34 35#include "cs43130.h"36#include "cirrus_legacy.h"37 38static const struct reg_default cs43130_reg_defaults[] = {39	{CS43130_SYS_CLK_CTL_1, 0x06},40	{CS43130_SP_SRATE, 0x01},41	{CS43130_SP_BITSIZE, 0x05},42	{CS43130_PAD_INT_CFG, 0x03},43	{CS43130_PWDN_CTL, 0xFE},44	{CS43130_CRYSTAL_SET, 0x04},45	{CS43130_PLL_SET_1, 0x00},46	{CS43130_PLL_SET_2, 0x00},47	{CS43130_PLL_SET_3, 0x00},48	{CS43130_PLL_SET_4, 0x00},49	{CS43130_PLL_SET_5, 0x40},50	{CS43130_PLL_SET_6, 0x10},51	{CS43130_PLL_SET_7, 0x80},52	{CS43130_PLL_SET_8, 0x03},53	{CS43130_PLL_SET_9, 0x02},54	{CS43130_PLL_SET_10, 0x02},55	{CS43130_CLKOUT_CTL, 0x00},56	{CS43130_ASP_NUM_1, 0x01},57	{CS43130_ASP_NUM_2, 0x00},58	{CS43130_ASP_DEN_1, 0x08},59	{CS43130_ASP_DEN_2, 0x00},60	{CS43130_ASP_LRCK_HI_TIME_1, 0x1F},61	{CS43130_ASP_LRCK_HI_TIME_2, 0x00},62	{CS43130_ASP_LRCK_PERIOD_1, 0x3F},63	{CS43130_ASP_LRCK_PERIOD_2, 0x00},64	{CS43130_ASP_CLOCK_CONF, 0x0C},65	{CS43130_ASP_FRAME_CONF, 0x0A},66	{CS43130_XSP_NUM_1, 0x01},67	{CS43130_XSP_NUM_2, 0x00},68	{CS43130_XSP_DEN_1, 0x02},69	{CS43130_XSP_DEN_2, 0x00},70	{CS43130_XSP_LRCK_HI_TIME_1, 0x1F},71	{CS43130_XSP_LRCK_HI_TIME_2, 0x00},72	{CS43130_XSP_LRCK_PERIOD_1, 0x3F},73	{CS43130_XSP_LRCK_PERIOD_2, 0x00},74	{CS43130_XSP_CLOCK_CONF, 0x0C},75	{CS43130_XSP_FRAME_CONF, 0x0A},76	{CS43130_ASP_CH_1_LOC, 0x00},77	{CS43130_ASP_CH_2_LOC, 0x00},78	{CS43130_ASP_CH_1_SZ_EN, 0x06},79	{CS43130_ASP_CH_2_SZ_EN, 0x0E},80	{CS43130_XSP_CH_1_LOC, 0x00},81	{CS43130_XSP_CH_2_LOC, 0x00},82	{CS43130_XSP_CH_1_SZ_EN, 0x06},83	{CS43130_XSP_CH_2_SZ_EN, 0x0E},84	{CS43130_DSD_VOL_B, 0x78},85	{CS43130_DSD_VOL_A, 0x78},86	{CS43130_DSD_PATH_CTL_1, 0xA8},87	{CS43130_DSD_INT_CFG, 0x00},88	{CS43130_DSD_PATH_CTL_2, 0x02},89	{CS43130_DSD_PCM_MIX_CTL, 0x00},90	{CS43130_DSD_PATH_CTL_3, 0x40},91	{CS43130_HP_OUT_CTL_1, 0x30},92	{CS43130_PCM_FILT_OPT, 0x02},93	{CS43130_PCM_VOL_B, 0x78},94	{CS43130_PCM_VOL_A, 0x78},95	{CS43130_PCM_PATH_CTL_1, 0xA8},96	{CS43130_PCM_PATH_CTL_2, 0x00},97	{CS43130_CLASS_H_CTL, 0x1E},98	{CS43130_HP_DETECT, 0x04},99	{CS43130_HP_LOAD_1, 0x00},100	{CS43130_HP_MEAS_LOAD_1, 0x00},101	{CS43130_HP_MEAS_LOAD_2, 0x00},102	{CS43130_INT_MASK_1, 0xFF},103	{CS43130_INT_MASK_2, 0xFF},104	{CS43130_INT_MASK_3, 0xFF},105	{CS43130_INT_MASK_4, 0xFF},106	{CS43130_INT_MASK_5, 0xFF},107};108 109static bool cs43130_volatile_register(struct device *dev, unsigned int reg)110{111	switch (reg) {112	case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5:113	case CS43130_HP_DC_STAT_1 ... CS43130_HP_DC_STAT_2:114	case CS43130_HP_AC_STAT_1 ... CS43130_HP_AC_STAT_2:115		return true;116	default:117		return false;118	}119}120 121static bool cs43130_readable_register(struct device *dev, unsigned int reg)122{123	switch (reg) {124	case CS43130_DEVID_AB ... CS43130_SYS_CLK_CTL_1:125	case CS43130_SP_SRATE ... CS43130_PAD_INT_CFG:126	case CS43130_PWDN_CTL:127	case CS43130_CRYSTAL_SET:128	case CS43130_PLL_SET_1 ... CS43130_PLL_SET_5:129	case CS43130_PLL_SET_6:130	case CS43130_PLL_SET_7:131	case CS43130_PLL_SET_8:132	case CS43130_PLL_SET_9:133	case CS43130_PLL_SET_10:134	case CS43130_CLKOUT_CTL:135	case CS43130_ASP_NUM_1 ... CS43130_ASP_FRAME_CONF:136	case CS43130_XSP_NUM_1 ... CS43130_XSP_FRAME_CONF:137	case CS43130_ASP_CH_1_LOC:138	case CS43130_ASP_CH_2_LOC:139	case CS43130_ASP_CH_1_SZ_EN:140	case CS43130_ASP_CH_2_SZ_EN:141	case CS43130_XSP_CH_1_LOC:142	case CS43130_XSP_CH_2_LOC:143	case CS43130_XSP_CH_1_SZ_EN:144	case CS43130_XSP_CH_2_SZ_EN:145	case CS43130_DSD_VOL_B ... CS43130_DSD_PATH_CTL_3:146	case CS43130_HP_OUT_CTL_1:147	case CS43130_PCM_FILT_OPT ... CS43130_PCM_PATH_CTL_2:148	case CS43130_CLASS_H_CTL:149	case CS43130_HP_DETECT:150	case CS43130_HP_STATUS:151	case CS43130_HP_LOAD_1:152	case CS43130_HP_MEAS_LOAD_1:153	case CS43130_HP_MEAS_LOAD_2:154	case CS43130_HP_DC_STAT_1:155	case CS43130_HP_DC_STAT_2:156	case CS43130_HP_AC_STAT_1:157	case CS43130_HP_AC_STAT_2:158	case CS43130_HP_LOAD_STAT:159	case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5:160	case CS43130_INT_MASK_1 ... CS43130_INT_MASK_5:161		return true;162	default:163		return false;164	}165}166 167static bool cs43130_precious_register(struct device *dev, unsigned int reg)168{169	switch (reg) {170	case CS43130_INT_STATUS_1 ... CS43130_INT_STATUS_5:171		return true;172	default:173		return false;174	}175}176 177struct cs43130_pll_params {178	unsigned int pll_in;179	u8 sclk_prediv;180	u8 pll_div_int;181	u32 pll_div_frac;182	u8 pll_mode;183	u8 pll_divout;184	unsigned int pll_out;185	u8 pll_cal_ratio;186};187 188static const struct cs43130_pll_params pll_ratio_table[] = {189	{9600000, 0x02, 0x49, 0x800000, 0x00, 0x08, 22579200, 151},190	{9600000, 0x02, 0x50, 0x000000, 0x00, 0x08, 24576000, 164},191 192	{11289600, 0x02, 0X40, 0, 0x01, 0x08, 22579200, 128},193	{11289600, 0x02, 0x44, 0x06F700, 0x0, 0x08, 24576000, 139},194 195	{12000000, 0x02, 0x49, 0x800000, 0x00, 0x0A, 22579200, 120},196	{12000000, 0x02, 0x40, 0x000000, 0x00, 0x08, 24576000, 131},197 198	{12288000, 0x02, 0x49, 0x800000, 0x01, 0x0A, 22579200, 118},199	{12288000, 0x02, 0x40, 0x000000, 0x01, 0x08, 24576000, 128},200 201	{13000000, 0x02, 0x45, 0x797680, 0x01, 0x0A, 22579200, 111},202	{13000000, 0x02, 0x3C, 0x7EA940, 0x01, 0x08, 24576000, 121},203 204	{19200000, 0x03, 0x49, 0x800000, 0x00, 0x08, 22579200, 151},205	{19200000, 0x03, 0x50, 0x000000, 0x00, 0x08, 24576000, 164},206 207	{22579200, 0, 0, 0, 0, 0, 22579200, 0},208	{22579200, 0x03, 0x44, 0x06F700, 0x00, 0x08, 24576000, 139},209 210	{24000000, 0x03, 0x49, 0x800000, 0x00, 0x0A, 22579200, 120},211	{24000000, 0x03, 0x40, 0x000000, 0x00, 0x08, 24576000, 131},212 213	{24576000, 0x03, 0x49, 0x800000, 0x01, 0x0A, 22579200, 118},214	{24576000, 0, 0, 0, 0, 0, 24576000, 0},215 216	{26000000, 0x03, 0x45, 0x797680, 0x01, 0x0A, 22579200, 111},217	{26000000, 0x03, 0x3C, 0x7EA940, 0x01, 0x08, 24576000, 121},218};219 220static const struct cs43130_pll_params *cs43130_get_pll_table(221		unsigned int freq_in, unsigned int freq_out)222{223	int i;224 225	for (i = 0; i < ARRAY_SIZE(pll_ratio_table); i++) {226		if (pll_ratio_table[i].pll_in == freq_in &&227		    pll_ratio_table[i].pll_out == freq_out)228			return &pll_ratio_table[i];229	}230 231	return NULL;232}233 234static int cs43130_pll_config(struct snd_soc_component *component)235{236	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);237	const struct cs43130_pll_params *pll_entry;238 239	dev_dbg(cs43130->dev, "cs43130->mclk = %u, cs43130->mclk_int = %u\n",240		cs43130->mclk, cs43130->mclk_int);241 242	pll_entry = cs43130_get_pll_table(cs43130->mclk, cs43130->mclk_int);243	if (!pll_entry)244		return -EINVAL;245 246	if (pll_entry->pll_cal_ratio == 0) {247		regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_1,248				   CS43130_PLL_START_MASK, 0);249 250		cs43130->pll_bypass = true;251		return 0;252	}253 254	cs43130->pll_bypass = false;255 256	regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_2,257			   CS43130_PLL_DIV_DATA_MASK,258			   pll_entry->pll_div_frac >>259			   CS43130_PLL_DIV_FRAC_0_DATA_SHIFT);260	regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_3,261			   CS43130_PLL_DIV_DATA_MASK,262			   pll_entry->pll_div_frac >>263			   CS43130_PLL_DIV_FRAC_1_DATA_SHIFT);264	regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_4,265			   CS43130_PLL_DIV_DATA_MASK,266			   pll_entry->pll_div_frac >>267			   CS43130_PLL_DIV_FRAC_2_DATA_SHIFT);268	regmap_write(cs43130->regmap, CS43130_PLL_SET_5,269		     pll_entry->pll_div_int);270	regmap_write(cs43130->regmap, CS43130_PLL_SET_6, pll_entry->pll_divout);271	regmap_write(cs43130->regmap, CS43130_PLL_SET_7,272		     pll_entry->pll_cal_ratio);273	regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_8,274			   CS43130_PLL_MODE_MASK,275			   pll_entry->pll_mode << CS43130_PLL_MODE_SHIFT);276	regmap_write(cs43130->regmap, CS43130_PLL_SET_9,277		     pll_entry->sclk_prediv);278	regmap_update_bits(cs43130->regmap, CS43130_PLL_SET_1,279			   CS43130_PLL_START_MASK, 1);280 281	return 0;282}283 284static int cs43130_set_pll(struct snd_soc_component *component, int pll_id, int source,285			   unsigned int freq_in, unsigned int freq_out)286{287	int ret = 0;288	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);289 290	switch (freq_in) {291	case 9600000:292	case 11289600:293	case 12000000:294	case 12288000:295	case 13000000:296	case 19200000:297	case 22579200:298	case 24000000:299	case 24576000:300	case 26000000:301		cs43130->mclk = freq_in;302		break;303	default:304		dev_err(cs43130->dev,305			"unsupported pll input reference clock:%d\n", freq_in);306		return -EINVAL;307	}308 309	switch (freq_out) {310	case 22579200:311		cs43130->mclk_int = freq_out;312		break;313	case 24576000:314		cs43130->mclk_int = freq_out;315		break;316	default:317		dev_err(cs43130->dev,318			"unsupported pll output ref clock: %u\n", freq_out);319		return -EINVAL;320	}321 322	ret = cs43130_pll_config(component);323	dev_dbg(cs43130->dev, "cs43130->pll_bypass = %d", cs43130->pll_bypass);324	return ret;325}326 327static int cs43130_wait_for_completion(struct cs43130_private *cs43130, struct completion *to_poll,328					int time)329{330	int stickies, offset, flag, ret;331 332	if (cs43130->has_irq_line) {333		ret = wait_for_completion_timeout(to_poll, msecs_to_jiffies(time));334		if (ret == 0)335			return -ETIMEDOUT;336		else337			return 0; // Discard number of jiffies left till timeout and return success338	}339 340	if (to_poll == &cs43130->xtal_rdy) {341		offset = 0;342		flag = CS43130_XTAL_RDY_INT;343	} else if (to_poll == &cs43130->pll_rdy) {344		offset = 0;345		flag = CS43130_PLL_RDY_INT;346	} else {347		return -EINVAL;348	}349 350	return regmap_read_poll_timeout(cs43130->regmap, CS43130_INT_STATUS_1 + offset,351					stickies, (stickies & flag),352					1000, time * 1000);353}354 355static int cs43130_change_clksrc(struct snd_soc_component *component,356				 enum cs43130_mclk_src_sel src)357{358	int ret;359	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);360	int mclk_int_decoded;361 362	if (src == cs43130->mclk_int_src) {363		/* clk source has not changed */364		return 0;365	}366 367	switch (cs43130->mclk_int) {368	case CS43130_MCLK_22M:369		mclk_int_decoded = CS43130_MCLK_22P5;370		break;371	case CS43130_MCLK_24M:372		mclk_int_decoded = CS43130_MCLK_24P5;373		break;374	default:375		dev_err(cs43130->dev, "Invalid MCLK INT freq: %u\n", cs43130->mclk_int);376		return -EINVAL;377	}378 379	switch (src) {380	case CS43130_MCLK_SRC_EXT:381		cs43130->pll_bypass = true;382		cs43130->mclk_int_src = CS43130_MCLK_SRC_EXT;383		if (cs43130->xtal_ibias == CS43130_XTAL_UNUSED) {384			regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,385					   CS43130_PDN_XTAL_MASK,386					   1 << CS43130_PDN_XTAL_SHIFT);387		} else {388			reinit_completion(&cs43130->xtal_rdy);389			regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,390					   CS43130_XTAL_RDY_INT_MASK, 0);391			regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,392					   CS43130_PDN_XTAL_MASK, 0);393			ret = cs43130_wait_for_completion(cs43130, &cs43130->xtal_rdy, 100);394			regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,395					   CS43130_XTAL_RDY_INT_MASK,396					   1 << CS43130_XTAL_RDY_INT_SHIFT);397			if (ret) {398				dev_err(cs43130->dev, "Error waiting for XTAL_READY interrupt: %d\n", ret);399				return ret;400			}401		}402 403		regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,404				   CS43130_MCLK_SRC_SEL_MASK,405				   src << CS43130_MCLK_SRC_SEL_SHIFT);406		regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,407				   CS43130_MCLK_INT_MASK,408				   mclk_int_decoded << CS43130_MCLK_INT_SHIFT);409		usleep_range(150, 200);410 411		regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,412				   CS43130_PDN_PLL_MASK,413				   1 << CS43130_PDN_PLL_SHIFT);414		break;415	case CS43130_MCLK_SRC_PLL:416		cs43130->pll_bypass = false;417		cs43130->mclk_int_src = CS43130_MCLK_SRC_PLL;418		if (cs43130->xtal_ibias == CS43130_XTAL_UNUSED) {419			regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,420					   CS43130_PDN_XTAL_MASK,421					   1 << CS43130_PDN_XTAL_SHIFT);422		} else {423			reinit_completion(&cs43130->xtal_rdy);424			regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,425					   CS43130_XTAL_RDY_INT_MASK, 0);426			regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,427					   CS43130_PDN_XTAL_MASK, 0);428			ret = cs43130_wait_for_completion(cs43130, &cs43130->xtal_rdy, 100);429			regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,430					   CS43130_XTAL_RDY_INT_MASK,431					   1 << CS43130_XTAL_RDY_INT_SHIFT);432			if (ret) {433				dev_err(cs43130->dev, "Error waiting for XTAL_READY interrupt: %d\n", ret);434				return ret;435			}436		}437 438		reinit_completion(&cs43130->pll_rdy);439		regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,440				   CS43130_PLL_RDY_INT_MASK, 0);441		regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,442				   CS43130_PDN_PLL_MASK, 0);443		ret = cs43130_wait_for_completion(cs43130, &cs43130->pll_rdy, 100);444		regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,445				   CS43130_PLL_RDY_INT_MASK,446				   1 << CS43130_PLL_RDY_INT_SHIFT);447		if (ret) {448			dev_err(cs43130->dev, "Error waiting for PLL_READY interrupt: %d\n", ret);449			return ret;450		}451 452		regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,453				   CS43130_MCLK_SRC_SEL_MASK,454				   src << CS43130_MCLK_SRC_SEL_SHIFT);455		regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,456				   CS43130_MCLK_INT_MASK,457				   mclk_int_decoded << CS43130_MCLK_INT_SHIFT);458		usleep_range(150, 200);459		break;460	case CS43130_MCLK_SRC_RCO:461		cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO;462 463		regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,464				   CS43130_MCLK_SRC_SEL_MASK,465				   src << CS43130_MCLK_SRC_SEL_SHIFT);466		regmap_update_bits(cs43130->regmap, CS43130_SYS_CLK_CTL_1,467				   CS43130_MCLK_INT_MASK,468				   CS43130_MCLK_22P5 << CS43130_MCLK_INT_SHIFT);469		usleep_range(150, 200);470 471		regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,472				   CS43130_PDN_XTAL_MASK,473				   1 << CS43130_PDN_XTAL_SHIFT);474		regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL,475				   CS43130_PDN_PLL_MASK,476				   1 << CS43130_PDN_PLL_SHIFT);477		break;478	default:479		dev_err(cs43130->dev, "Invalid MCLK source value\n");480		return -EINVAL;481	}482 483	return 0;484}485 486static const struct cs43130_bitwidth_map cs43130_bitwidth_table[] = {487	{8,	CS43130_SP_BIT_SIZE_8,	CS43130_CH_BIT_SIZE_8},488	{16,	CS43130_SP_BIT_SIZE_16, CS43130_CH_BIT_SIZE_16},489	{24,	CS43130_SP_BIT_SIZE_24, CS43130_CH_BIT_SIZE_24},490	{32,	CS43130_SP_BIT_SIZE_32, CS43130_CH_BIT_SIZE_32},491};492 493static const struct cs43130_bitwidth_map *cs43130_get_bitwidth_table(494				unsigned int bitwidth)495{496	int i;497 498	for (i = 0; i < ARRAY_SIZE(cs43130_bitwidth_table); i++) {499		if (cs43130_bitwidth_table[i].bitwidth == bitwidth)500			return &cs43130_bitwidth_table[i];501	}502 503	return NULL;504}505 506static int cs43130_set_bitwidth(int dai_id, unsigned int bitwidth_dai,507			  struct regmap *regmap)508{509	const struct cs43130_bitwidth_map *bw_map;510 511	bw_map = cs43130_get_bitwidth_table(bitwidth_dai);512	if (!bw_map)513		return -EINVAL;514 515	switch (dai_id) {516	case CS43130_ASP_PCM_DAI:517	case CS43130_ASP_DOP_DAI:518		regmap_update_bits(regmap, CS43130_ASP_CH_1_SZ_EN,519				   CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);520		regmap_update_bits(regmap, CS43130_ASP_CH_2_SZ_EN,521				   CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);522		regmap_update_bits(regmap, CS43130_SP_BITSIZE,523				   CS43130_ASP_BITSIZE_MASK, bw_map->sp_bit);524		break;525	case CS43130_XSP_DOP_DAI:526		regmap_update_bits(regmap, CS43130_XSP_CH_1_SZ_EN,527				   CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);528		regmap_update_bits(regmap, CS43130_XSP_CH_2_SZ_EN,529				   CS43130_CH_BITSIZE_MASK, bw_map->ch_bit);530		regmap_update_bits(regmap, CS43130_SP_BITSIZE,531				   CS43130_XSP_BITSIZE_MASK, bw_map->sp_bit <<532				   CS43130_XSP_BITSIZE_SHIFT);533		break;534	default:535		return -EINVAL;536	}537 538	return 0;539}540 541static const struct cs43130_rate_map cs43130_rate_table[] = {542	{32000,		CS43130_ASP_SPRATE_32K},543	{44100,		CS43130_ASP_SPRATE_44_1K},544	{48000,		CS43130_ASP_SPRATE_48K},545	{88200,		CS43130_ASP_SPRATE_88_2K},546	{96000,		CS43130_ASP_SPRATE_96K},547	{176400,	CS43130_ASP_SPRATE_176_4K},548	{192000,	CS43130_ASP_SPRATE_192K},549	{352800,	CS43130_ASP_SPRATE_352_8K},550	{384000,	CS43130_ASP_SPRATE_384K},551};552 553static const struct cs43130_rate_map *cs43130_get_rate_table(int fs)554{555	int i;556 557	for (i = 0; i < ARRAY_SIZE(cs43130_rate_table); i++) {558		if (cs43130_rate_table[i].fs == fs)559			return &cs43130_rate_table[i];560	}561 562	return NULL;563}564 565static const struct cs43130_clk_gen *cs43130_get_clk_gen(int mclk_int, int fs,566		const struct cs43130_clk_gen *clk_gen_table, int len_clk_gen_table)567{568	int i;569 570	for (i = 0; i < len_clk_gen_table; i++) {571		if (clk_gen_table[i].mclk_int == mclk_int &&572		    clk_gen_table[i].fs == fs)573			return &clk_gen_table[i];574	}575 576	return NULL;577}578 579static int cs43130_set_sp_fmt(int dai_id, unsigned int bitwidth_sclk,580			      struct snd_pcm_hw_params *params,581			      struct cs43130_private *cs43130)582{583	u16 frm_size;584	u16 hi_size;585	u8 frm_delay;586	u8 frm_phase;587	u8 frm_data;588	u8 sclk_edge;589	u8 lrck_edge;590	u8 clk_data;591	u8 loc_ch1;592	u8 loc_ch2;593	u8 dai_mode_val;594	const struct cs43130_clk_gen *clk_gen;595 596	switch (cs43130->dais[dai_id].dai_format) {597	case SND_SOC_DAIFMT_I2S:598		hi_size = bitwidth_sclk;599		frm_delay = 2;600		frm_phase = 0;601		break;602	case SND_SOC_DAIFMT_LEFT_J:603		hi_size = bitwidth_sclk;604		frm_delay = 0;605		frm_phase = 1;606		break;607	case SND_SOC_DAIFMT_DSP_A:608		hi_size = 1;609		frm_delay = 2;610		frm_phase = 1;611		break;612	case SND_SOC_DAIFMT_DSP_B:613		hi_size = 1;614		frm_delay = 0;615		frm_phase = 1;616		break;617	default:618		return -EINVAL;619	}620 621	switch (cs43130->dais[dai_id].dai_invert) {622	case SND_SOC_DAIFMT_NB_NF:623		sclk_edge = 1;624		lrck_edge = 0;625		break;626	case SND_SOC_DAIFMT_IB_NF:627		sclk_edge = 0;628		lrck_edge = 0;629		break;630	case SND_SOC_DAIFMT_NB_IF:631		sclk_edge = 1;632		lrck_edge = 1;633		break;634	case SND_SOC_DAIFMT_IB_IF:635		sclk_edge = 0;636		lrck_edge = 1;637		break;638	default:639		return -EINVAL;640	}641 642	switch (cs43130->dais[dai_id].dai_mode) {643	case SND_SOC_DAIFMT_CBS_CFS:644		dai_mode_val = 0;645		break;646	case SND_SOC_DAIFMT_CBM_CFM:647		dai_mode_val = 1;648		break;649	default:650		return -EINVAL;651	}652 653	frm_size = bitwidth_sclk * params_channels(params);654	loc_ch1 = 0;655	loc_ch2 = bitwidth_sclk * (params_channels(params) - 1);656 657	frm_data = frm_delay & CS43130_SP_FSD_MASK;658	frm_data |= (frm_phase << CS43130_SP_STP_SHIFT) & CS43130_SP_STP_MASK;659 660	clk_data = lrck_edge & CS43130_SP_LCPOL_IN_MASK;661	clk_data |= (lrck_edge << CS43130_SP_LCPOL_OUT_SHIFT) &662		    CS43130_SP_LCPOL_OUT_MASK;663	clk_data |= (sclk_edge << CS43130_SP_SCPOL_IN_SHIFT) &664		    CS43130_SP_SCPOL_IN_MASK;665	clk_data |= (sclk_edge << CS43130_SP_SCPOL_OUT_SHIFT) &666		    CS43130_SP_SCPOL_OUT_MASK;667	clk_data |= (dai_mode_val << CS43130_SP_MODE_SHIFT) &668		    CS43130_SP_MODE_MASK;669 670	switch (dai_id) {671	case CS43130_ASP_PCM_DAI:672	case CS43130_ASP_DOP_DAI:673		regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_1,674			CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>675			CS43130_SP_LCPR_LSB_DATA_SHIFT);676		regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_PERIOD_2,677			CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>678			CS43130_SP_LCPR_MSB_DATA_SHIFT);679		regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_1,680			CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>681			CS43130_SP_LCHI_LSB_DATA_SHIFT);682		regmap_update_bits(cs43130->regmap, CS43130_ASP_LRCK_HI_TIME_2,683			CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>684			CS43130_SP_LCHI_MSB_DATA_SHIFT);685		regmap_write(cs43130->regmap, CS43130_ASP_FRAME_CONF, frm_data);686		regmap_write(cs43130->regmap, CS43130_ASP_CH_1_LOC, loc_ch1);687		regmap_write(cs43130->regmap, CS43130_ASP_CH_2_LOC, loc_ch2);688		regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_1_SZ_EN,689			CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);690		regmap_update_bits(cs43130->regmap, CS43130_ASP_CH_2_SZ_EN,691			CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);692		regmap_write(cs43130->regmap, CS43130_ASP_CLOCK_CONF, clk_data);693		break;694	case CS43130_XSP_DOP_DAI:695		regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_1,696			CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>697			CS43130_SP_LCPR_LSB_DATA_SHIFT);698		regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_PERIOD_2,699			CS43130_SP_LCPR_DATA_MASK, (frm_size - 1) >>700			CS43130_SP_LCPR_MSB_DATA_SHIFT);701		regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_1,702			CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>703			CS43130_SP_LCHI_LSB_DATA_SHIFT);704		regmap_update_bits(cs43130->regmap, CS43130_XSP_LRCK_HI_TIME_2,705			CS43130_SP_LCHI_DATA_MASK, (hi_size - 1) >>706			CS43130_SP_LCHI_MSB_DATA_SHIFT);707		regmap_write(cs43130->regmap, CS43130_XSP_FRAME_CONF, frm_data);708		regmap_write(cs43130->regmap, CS43130_XSP_CH_1_LOC, loc_ch1);709		regmap_write(cs43130->regmap, CS43130_XSP_CH_2_LOC, loc_ch2);710		regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_1_SZ_EN,711			CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);712		regmap_update_bits(cs43130->regmap, CS43130_XSP_CH_2_SZ_EN,713			CS43130_CH_EN_MASK, 1 << CS43130_CH_EN_SHIFT);714		regmap_write(cs43130->regmap, CS43130_XSP_CLOCK_CONF, clk_data);715		break;716	default:717		return -EINVAL;718	}719 720	switch (frm_size) {721	case 16:722		clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,723					      params_rate(params),724					      cs43130_16_clk_gen,725					      ARRAY_SIZE(cs43130_16_clk_gen));726		break;727	case 32:728		clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,729					      params_rate(params),730					      cs43130_32_clk_gen,731					      ARRAY_SIZE(cs43130_32_clk_gen));732		break;733	case 48:734		clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,735					      params_rate(params),736					      cs43130_48_clk_gen,737					      ARRAY_SIZE(cs43130_48_clk_gen));738		break;739	case 64:740		clk_gen = cs43130_get_clk_gen(cs43130->mclk_int,741					      params_rate(params),742					      cs43130_64_clk_gen,743					      ARRAY_SIZE(cs43130_64_clk_gen));744		break;745	default:746		return -EINVAL;747	}748 749	if (!clk_gen)750		return -EINVAL;751 752	switch (dai_id) {753	case CS43130_ASP_PCM_DAI:754	case CS43130_ASP_DOP_DAI:755		regmap_write(cs43130->regmap, CS43130_ASP_DEN_1,756			     (clk_gen->v.denominator & CS43130_SP_M_LSB_DATA_MASK) >>757			     CS43130_SP_M_LSB_DATA_SHIFT);758		regmap_write(cs43130->regmap, CS43130_ASP_DEN_2,759			     (clk_gen->v.denominator & CS43130_SP_M_MSB_DATA_MASK) >>760			     CS43130_SP_M_MSB_DATA_SHIFT);761		regmap_write(cs43130->regmap, CS43130_ASP_NUM_1,762			     (clk_gen->v.numerator & CS43130_SP_N_LSB_DATA_MASK) >>763			     CS43130_SP_N_LSB_DATA_SHIFT);764		regmap_write(cs43130->regmap, CS43130_ASP_NUM_2,765			     (clk_gen->v.numerator & CS43130_SP_N_MSB_DATA_MASK) >>766			     CS43130_SP_N_MSB_DATA_SHIFT);767		break;768	case CS43130_XSP_DOP_DAI:769		regmap_write(cs43130->regmap, CS43130_XSP_DEN_1,770			     (clk_gen->v.denominator & CS43130_SP_M_LSB_DATA_MASK) >>771			     CS43130_SP_M_LSB_DATA_SHIFT);772		regmap_write(cs43130->regmap, CS43130_XSP_DEN_2,773			     (clk_gen->v.denominator & CS43130_SP_M_MSB_DATA_MASK) >>774			     CS43130_SP_M_MSB_DATA_SHIFT);775		regmap_write(cs43130->regmap, CS43130_XSP_NUM_1,776			     (clk_gen->v.numerator & CS43130_SP_N_LSB_DATA_MASK) >>777			     CS43130_SP_N_LSB_DATA_SHIFT);778		regmap_write(cs43130->regmap, CS43130_XSP_NUM_2,779			     (clk_gen->v.numerator & CS43130_SP_N_MSB_DATA_MASK) >>780			     CS43130_SP_N_MSB_DATA_SHIFT);781		break;782	default:783		return -EINVAL;784	}785 786	return 0;787}788 789static int cs43130_pcm_dsd_mix(bool en, struct regmap *regmap)790{791	if (en) {792		regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL,793				   CS43130_MIX_PCM_PREP_MASK,794				   1 << CS43130_MIX_PCM_PREP_SHIFT);795		usleep_range(6000, 6050);796		regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL,797				   CS43130_MIX_PCM_DSD_MASK,798				   1 << CS43130_MIX_PCM_DSD_SHIFT);799	} else {800		regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL,801				   CS43130_MIX_PCM_DSD_MASK,802				   0 << CS43130_MIX_PCM_DSD_SHIFT);803		usleep_range(1600, 1650);804		regmap_update_bits(regmap, CS43130_DSD_PCM_MIX_CTL,805				   CS43130_MIX_PCM_PREP_MASK,806				   0 << CS43130_MIX_PCM_PREP_SHIFT);807	}808 809	return 0;810}811 812static int cs43130_dsd_hw_params(struct snd_pcm_substream *substream,813				 struct snd_pcm_hw_params *params,814				 struct snd_soc_dai *dai)815{816	struct snd_soc_component *component = dai->component;817	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);818	unsigned int required_clk;819	u8 dsd_speed;820 821	mutex_lock(&cs43130->clk_mutex);822	if (!cs43130->clk_req) {823		/* no DAI is currently using clk */824		if (!(CS43130_MCLK_22M % params_rate(params)))825			required_clk = CS43130_MCLK_22M;826		else827			required_clk = CS43130_MCLK_24M;828 829		cs43130_set_pll(component, 0, 0, cs43130->mclk, required_clk);830		if (cs43130->pll_bypass)831			cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT);832		else833			cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL);834	}835 836	cs43130->clk_req++;837	if (cs43130->clk_req == 2)838		cs43130_pcm_dsd_mix(true, cs43130->regmap);839	mutex_unlock(&cs43130->clk_mutex);840 841	switch (params_rate(params)) {842	case 176400:843		dsd_speed = 0;844		break;845	case 352800:846		dsd_speed = 1;847		break;848	default:849		dev_err(cs43130->dev, "Rate(%u) not supported\n",850			params_rate(params));851		return -EINVAL;852	}853 854	if (cs43130->dais[dai->id].dai_mode == SND_SOC_DAIFMT_CBM_CFM)855		regmap_update_bits(cs43130->regmap, CS43130_DSD_INT_CFG,856				   CS43130_DSD_MASTER, CS43130_DSD_MASTER);857	else858		regmap_update_bits(cs43130->regmap, CS43130_DSD_INT_CFG,859				   CS43130_DSD_MASTER, 0);860 861	regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,862			   CS43130_DSD_SPEED_MASK,863			   dsd_speed << CS43130_DSD_SPEED_SHIFT);864	regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,865			   CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_DSD <<866			   CS43130_DSD_SRC_SHIFT);867 868	return 0;869}870 871static int cs43130_hw_params(struct snd_pcm_substream *substream,872				 struct snd_pcm_hw_params *params,873				 struct snd_soc_dai *dai)874{875	struct snd_soc_component *component = dai->component;876	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);877	const struct cs43130_rate_map *rate_map;878	unsigned int sclk = cs43130->dais[dai->id].sclk;879	unsigned int bitwidth_sclk;880	unsigned int bitwidth_dai = (unsigned int)(params_width(params));881	unsigned int required_clk;882	u8 dsd_speed;883 884	mutex_lock(&cs43130->clk_mutex);885	if (!cs43130->clk_req) {886		/* no DAI is currently using clk */887		if (!(CS43130_MCLK_22M % params_rate(params)))888			required_clk = CS43130_MCLK_22M;889		else890			required_clk = CS43130_MCLK_24M;891 892		cs43130_set_pll(component, 0, 0, cs43130->mclk, required_clk);893		if (cs43130->pll_bypass)894			cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT);895		else896			cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL);897	}898 899	cs43130->clk_req++;900	if (cs43130->clk_req == 2)901		cs43130_pcm_dsd_mix(true, cs43130->regmap);902	mutex_unlock(&cs43130->clk_mutex);903 904	switch (dai->id) {905	case CS43130_ASP_DOP_DAI:906	case CS43130_XSP_DOP_DAI:907		/* DoP bitwidth is always 24-bit */908		bitwidth_dai = 24;909		sclk = params_rate(params) * bitwidth_dai *910		       params_channels(params);911 912		switch (params_rate(params)) {913		case 176400:914			dsd_speed = 0;915			break;916		case 352800:917			dsd_speed = 1;918			break;919		default:920			dev_err(cs43130->dev, "Rate(%u) not supported\n",921				params_rate(params));922			return -EINVAL;923		}924 925		regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,926				   CS43130_DSD_SPEED_MASK,927				   dsd_speed << CS43130_DSD_SPEED_SHIFT);928		break;929	case CS43130_ASP_PCM_DAI:930		rate_map = cs43130_get_rate_table(params_rate(params));931		if (!rate_map)932			return -EINVAL;933 934		regmap_write(cs43130->regmap, CS43130_SP_SRATE, rate_map->val);935		break;936	default:937		dev_err(cs43130->dev, "Invalid DAI (%d)\n", dai->id);938		return -EINVAL;939	}940 941	switch (dai->id) {942	case CS43130_ASP_DOP_DAI:943		regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,944				   CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_ASP <<945				   CS43130_DSD_SRC_SHIFT);946		break;947	case CS43130_XSP_DOP_DAI:948		regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_2,949				   CS43130_DSD_SRC_MASK, CS43130_DSD_SRC_XSP <<950				   CS43130_DSD_SRC_SHIFT);951		break;952	}953 954	if (!sclk && cs43130->dais[dai->id].dai_mode == SND_SOC_DAIFMT_CBM_CFM)955		/* Calculate SCLK in master mode if unassigned */956		sclk = params_rate(params) * bitwidth_dai *957		       params_channels(params);958 959	if (!sclk) {960		/* at this point, SCLK must be set */961		dev_err(cs43130->dev, "SCLK freq is not set\n");962		return -EINVAL;963	}964 965	bitwidth_sclk = (sclk / params_rate(params)) / params_channels(params);966	if (bitwidth_sclk < bitwidth_dai) {967		dev_err(cs43130->dev, "Format not supported: SCLK freq is too low\n");968		return -EINVAL;969	}970 971	dev_dbg(cs43130->dev,972		"sclk = %u, fs = %d, bitwidth_dai = %u\n",973		sclk, params_rate(params), bitwidth_dai);974 975	dev_dbg(cs43130->dev,976		"bitwidth_sclk = %u, num_ch = %u\n",977		bitwidth_sclk, params_channels(params));978 979	cs43130_set_bitwidth(dai->id, bitwidth_dai, cs43130->regmap);980	cs43130_set_sp_fmt(dai->id, bitwidth_sclk, params, cs43130);981 982	return 0;983}984 985static int cs43130_hw_free(struct snd_pcm_substream *substream,986			   struct snd_soc_dai *dai)987{988	struct snd_soc_component *component = dai->component;989	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);990 991	mutex_lock(&cs43130->clk_mutex);992	cs43130->clk_req--;993	if (!cs43130->clk_req) {994		/* no DAI is currently using clk */995		cs43130_change_clksrc(component, CS43130_MCLK_SRC_RCO);996		cs43130_pcm_dsd_mix(false, cs43130->regmap);997	}998	mutex_unlock(&cs43130->clk_mutex);999 1000	return 0;1001}1002 1003static const DECLARE_TLV_DB_SCALE(pcm_vol_tlv, -12750, 50, 1);1004 1005static const char * const pcm_ch_text[] = {1006	"Left-Right Ch",1007	"Left-Left Ch",1008	"Right-Left Ch",1009	"Right-Right Ch",1010};1011 1012static const struct reg_sequence pcm_ch_en_seq[] = {1013	{CS43130_DXD1, 0x99},1014	{0x180005, 0x8C},1015	{0x180007, 0xAB},1016	{0x180015, 0x31},1017	{0x180017, 0xB2},1018	{0x180025, 0x30},1019	{0x180027, 0x84},1020	{0x180035, 0x9C},1021	{0x180037, 0xAE},1022	{0x18000D, 0x24},1023	{0x18000F, 0xA3},1024	{0x18001D, 0x05},1025	{0x18001F, 0xD4},1026	{0x18002D, 0x0B},1027	{0x18002F, 0xC7},1028	{0x18003D, 0x71},1029	{0x18003F, 0xE7},1030	{CS43130_DXD1, 0},1031};1032 1033static const struct reg_sequence pcm_ch_dis_seq[] = {1034	{CS43130_DXD1, 0x99},1035	{0x180005, 0x24},1036	{0x180007, 0xA3},1037	{0x180015, 0x05},1038	{0x180017, 0xD4},1039	{0x180025, 0x0B},1040	{0x180027, 0xC7},1041	{0x180035, 0x71},1042	{0x180037, 0xE7},1043	{0x18000D, 0x8C},1044	{0x18000F, 0xAB},1045	{0x18001D, 0x31},1046	{0x18001F, 0xB2},1047	{0x18002D, 0x30},1048	{0x18002F, 0x84},1049	{0x18003D, 0x9C},1050	{0x18003F, 0xAE},1051	{CS43130_DXD1, 0},1052};1053 1054static int cs43130_pcm_ch_get(struct snd_kcontrol *kcontrol,1055			      struct snd_ctl_elem_value *ucontrol)1056{1057	return snd_soc_get_enum_double(kcontrol, ucontrol);1058}1059 1060static int cs43130_pcm_ch_put(struct snd_kcontrol *kcontrol,1061			      struct snd_ctl_elem_value *ucontrol)1062{1063	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;1064	unsigned int *item = ucontrol->value.enumerated.item;1065	struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);1066	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);1067	unsigned int val;1068 1069	if (item[0] >= e->items)1070		return -EINVAL;1071	val = snd_soc_enum_item_to_val(e, item[0]) << e->shift_l;1072 1073	switch (cs43130->dev_id) {1074	case CS43131_CHIP_ID:1075	case CS43198_CHIP_ID:1076		if (val >= 2)1077			regmap_multi_reg_write(cs43130->regmap, pcm_ch_en_seq,1078					       ARRAY_SIZE(pcm_ch_en_seq));1079		else1080			regmap_multi_reg_write(cs43130->regmap, pcm_ch_dis_seq,1081					       ARRAY_SIZE(pcm_ch_dis_seq));1082		break;1083	}1084 1085	return snd_soc_put_enum_double(kcontrol, ucontrol);1086}1087 1088static SOC_ENUM_SINGLE_DECL(pcm_ch_enum, CS43130_PCM_PATH_CTL_2, 0,1089			    pcm_ch_text);1090 1091static const char * const pcm_spd_texts[] = {1092	"Fast",1093	"Slow",1094};1095 1096static SOC_ENUM_SINGLE_DECL(pcm_spd_enum, CS43130_PCM_FILT_OPT, 7,1097			    pcm_spd_texts);1098 1099static const char * const dsd_texts[] = {1100	"Off",1101	"BCKA Mode",1102	"BCKD Mode",1103};1104 1105static const unsigned int dsd_values[] = {1106	CS43130_DSD_SRC_DSD,1107	CS43130_DSD_SRC_ASP,1108	CS43130_DSD_SRC_XSP,1109};1110 1111static SOC_VALUE_ENUM_SINGLE_DECL(dsd_enum, CS43130_DSD_INT_CFG, 0, 0x03,1112				  dsd_texts, dsd_values);1113 1114static const struct snd_kcontrol_new cs43130_snd_controls[] = {1115	SOC_DOUBLE_R_TLV("Master Playback Volume",1116			 CS43130_PCM_VOL_A, CS43130_PCM_VOL_B, 0, 0xFF, 1,1117			 pcm_vol_tlv),1118	SOC_DOUBLE_R_TLV("Master DSD Playback Volume",1119			 CS43130_DSD_VOL_A, CS43130_DSD_VOL_B, 0, 0xFF, 1,1120			 pcm_vol_tlv),1121	SOC_ENUM_EXT("PCM Ch Select", pcm_ch_enum, cs43130_pcm_ch_get,1122		     cs43130_pcm_ch_put),1123	SOC_ENUM("PCM Filter Speed", pcm_spd_enum),1124	SOC_SINGLE("PCM Phase Compensation", CS43130_PCM_FILT_OPT, 6, 1, 0),1125	SOC_SINGLE("PCM Nonoversample Emulate", CS43130_PCM_FILT_OPT, 5, 1, 0),1126	SOC_SINGLE("PCM High-pass Filter", CS43130_PCM_FILT_OPT, 1, 1, 0),1127	SOC_SINGLE("PCM De-emphasis Filter", CS43130_PCM_FILT_OPT, 0, 1, 0),1128	SOC_ENUM("DSD Phase Modulation", dsd_enum),1129};1130 1131static const struct reg_sequence pcm_seq[] = {1132	{CS43130_DXD1, 0x99},1133	{CS43130_DXD7, 0x01},1134	{CS43130_DXD8, 0},1135	{CS43130_DXD9, 0x01},1136	{CS43130_DXD3, 0x12},1137	{CS43130_DXD4, 0},1138	{CS43130_DXD10, 0x28},1139	{CS43130_DXD11, 0x28},1140	{CS43130_DXD1, 0},1141};1142 1143static const struct reg_sequence dsd_seq[] = {1144	{CS43130_DXD1, 0x99},1145	{CS43130_DXD7, 0x01},1146	{CS43130_DXD8, 0},1147	{CS43130_DXD9, 0x01},1148	{CS43130_DXD3, 0x12},1149	{CS43130_DXD4, 0},1150	{CS43130_DXD10, 0x1E},1151	{CS43130_DXD11, 0x20},1152	{CS43130_DXD1, 0},1153};1154 1155static const struct reg_sequence pop_free_seq[] = {1156	{CS43130_DXD1, 0x99},1157	{CS43130_DXD12, 0x0A},1158	{CS43130_DXD1, 0},1159};1160 1161static const struct reg_sequence pop_free_seq2[] = {1162	{CS43130_DXD1, 0x99},1163	{CS43130_DXD13, 0x20},1164	{CS43130_DXD1, 0},1165};1166 1167static const struct reg_sequence mute_seq[] = {1168	{CS43130_DXD1, 0x99},1169	{CS43130_DXD3, 0x12},1170	{CS43130_DXD5, 0x02},1171	{CS43130_DXD4, 0x12},1172	{CS43130_DXD1, 0},1173};1174 1175static const struct reg_sequence unmute_seq[] = {1176	{CS43130_DXD1, 0x99},1177	{CS43130_DXD3, 0x10},1178	{CS43130_DXD5, 0},1179	{CS43130_DXD4, 0x16},1180	{CS43130_DXD1, 0},1181};1182 1183static int cs43130_dsd_event(struct snd_soc_dapm_widget *w,1184			      struct snd_kcontrol *kcontrol, int event)1185{1186	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1187	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);1188 1189	switch (event) {1190	case SND_SOC_DAPM_PRE_PMU:1191		switch (cs43130->dev_id) {1192		case CS43130_CHIP_ID:1193		case CS4399_CHIP_ID:1194			regmap_multi_reg_write(cs43130->regmap, dsd_seq,1195					       ARRAY_SIZE(dsd_seq));1196			break;1197		}1198		break;1199	case SND_SOC_DAPM_POST_PMU:1200		regmap_update_bits(cs43130->regmap, CS43130_DSD_PATH_CTL_1,1201				   CS43130_MUTE_MASK, 0);1202		switch (cs43130->dev_id) {1203		case CS43130_CHIP_ID:1204		case CS4399_CHIP_ID:1205			regmap_multi_reg_write(cs43130->regmap, unmute_seq,1206					       ARRAY_SIZE(unmute_seq));1207			break;1208		}1209		break;1210	case SND_SOC_DAPM_PRE_PMD:1211		switch (cs43130->dev_id) {1212		case CS43130_CHIP_ID:1213		case CS4399_CHIP_ID:1214			regmap_multi_reg_write(cs43130->regmap, mute_seq,1215					       ARRAY_SIZE(mute_seq));1216			regmap_update_bits(cs43130->regmap,1217					   CS43130_DSD_PATH_CTL_1,1218					   CS43130_MUTE_MASK, CS43130_MUTE_EN);1219			/*1220			 * DSD Power Down Sequence1221			 * According to Design, 130ms is preferred.1222			 */1223			msleep(130);1224			break;1225		case CS43131_CHIP_ID:1226		case CS43198_CHIP_ID:1227			regmap_update_bits(cs43130->regmap,1228					   CS43130_DSD_PATH_CTL_1,1229					   CS43130_MUTE_MASK, CS43130_MUTE_EN);1230			break;1231		}1232		break;1233	default:1234		dev_err(cs43130->dev, "Invalid event = 0x%x\n", event);1235		return -EINVAL;1236	}1237	return 0;1238}1239 1240static int cs43130_pcm_event(struct snd_soc_dapm_widget *w,1241			      struct snd_kcontrol *kcontrol, int event)1242{1243	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1244	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);1245 1246	switch (event) {1247	case SND_SOC_DAPM_PRE_PMU:1248		switch (cs43130->dev_id) {1249		case CS43130_CHIP_ID:1250		case CS4399_CHIP_ID:1251			regmap_multi_reg_write(cs43130->regmap, pcm_seq,1252					       ARRAY_SIZE(pcm_seq));1253			break;1254		}1255		break;1256	case SND_SOC_DAPM_POST_PMU:1257		regmap_update_bits(cs43130->regmap, CS43130_PCM_PATH_CTL_1,1258				   CS43130_MUTE_MASK, 0);1259		switch (cs43130->dev_id) {1260		case CS43130_CHIP_ID:1261		case CS4399_CHIP_ID:1262			regmap_multi_reg_write(cs43130->regmap, unmute_seq,1263					       ARRAY_SIZE(unmute_seq));1264			break;1265		}1266		break;1267	case SND_SOC_DAPM_PRE_PMD:1268		switch (cs43130->dev_id) {1269		case CS43130_CHIP_ID:1270		case CS4399_CHIP_ID:1271			regmap_multi_reg_write(cs43130->regmap, mute_seq,1272					       ARRAY_SIZE(mute_seq));1273			regmap_update_bits(cs43130->regmap,1274					   CS43130_PCM_PATH_CTL_1,1275					   CS43130_MUTE_MASK, CS43130_MUTE_EN);1276			/*1277			 * PCM Power Down Sequence1278			 * According to Design, 130ms is preferred.1279			 */1280			msleep(130);1281			break;1282		case CS43131_CHIP_ID:1283		case CS43198_CHIP_ID:1284			regmap_update_bits(cs43130->regmap,1285					   CS43130_PCM_PATH_CTL_1,1286					   CS43130_MUTE_MASK, CS43130_MUTE_EN);1287			break;1288		}1289		break;1290	default:1291		dev_err(cs43130->dev, "Invalid event = 0x%x\n", event);1292		return -EINVAL;1293	}1294	return 0;1295}1296 1297static const struct reg_sequence dac_postpmu_seq[] = {1298	{CS43130_DXD9, 0x0C},1299	{CS43130_DXD3, 0x10},1300	{CS43130_DXD4, 0x20},1301};1302 1303static const struct reg_sequence dac_postpmd_seq[] = {1304	{CS43130_DXD1, 0x99},1305	{CS43130_DXD6, 0x01},1306	{CS43130_DXD1, 0},1307};1308 1309static int cs43130_dac_event(struct snd_soc_dapm_widget *w,1310			     struct snd_kcontrol *kcontrol, int event)1311{1312	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1313	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);1314 1315	switch (event) {1316	case SND_SOC_DAPM_PRE_PMU:1317		switch (cs43130->dev_id) {1318		case CS43130_CHIP_ID:1319		case CS4399_CHIP_ID:1320			regmap_multi_reg_write(cs43130->regmap, pop_free_seq,1321					       ARRAY_SIZE(pop_free_seq));1322			break;1323		case CS43131_CHIP_ID:1324		case CS43198_CHIP_ID:1325			regmap_multi_reg_write(cs43130->regmap, pop_free_seq2,1326					       ARRAY_SIZE(pop_free_seq2));1327			break;1328		}1329		break;1330	case SND_SOC_DAPM_POST_PMU:1331		usleep_range(10000, 10050);1332 1333		regmap_write(cs43130->regmap, CS43130_DXD1, 0x99);1334 1335		switch (cs43130->dev_id) {1336		case CS43130_CHIP_ID:1337		case CS4399_CHIP_ID:1338			regmap_multi_reg_write(cs43130->regmap, dac_postpmu_seq,1339					       ARRAY_SIZE(dac_postpmu_seq));1340			/*1341			 * Per datasheet, Sec. PCM Power-Up Sequence.1342			 * According to Design, CS43130_DXD12 must be 0 to meet1343			 * THDN and Dynamic Range spec.1344			 */1345			msleep(1000);1346			regmap_write(cs43130->regmap, CS43130_DXD12, 0);1347			break;1348		case CS43131_CHIP_ID:1349		case CS43198_CHIP_ID:1350			usleep_range(12000, 12010);1351			regmap_write(cs43130->regmap, CS43130_DXD13, 0);1352			break;1353		}1354 1355		regmap_write(cs43130->regmap, CS43130_DXD1, 0);1356		break;1357	case SND_SOC_DAPM_POST_PMD:1358		switch (cs43130->dev_id) {1359		case CS43130_CHIP_ID:1360		case CS4399_CHIP_ID:1361			regmap_multi_reg_write(cs43130->regmap, dac_postpmd_seq,1362					       ARRAY_SIZE(dac_postpmd_seq));1363			break;1364		}1365		break;1366	default:1367		dev_err(cs43130->dev, "Invalid DAC event = 0x%x\n", event);1368		return -EINVAL;1369	}1370	return 0;1371}1372 1373static const struct reg_sequence hpin_prepmd_seq[] = {1374	{CS43130_DXD1, 0x99},1375	{CS43130_DXD15, 0x64},1376	{CS43130_DXD14, 0},1377	{CS43130_DXD2, 0},1378	{CS43130_DXD1, 0},1379};1380 1381static const struct reg_sequence hpin_postpmu_seq[] = {1382	{CS43130_DXD1, 0x99},1383	{CS43130_DXD2, 1},1384	{CS43130_DXD14, 0xDC},1385	{CS43130_DXD15, 0xE4},1386	{CS43130_DXD1, 0},1387};1388 1389static int cs43130_hpin_event(struct snd_soc_dapm_widget *w,1390			      struct snd_kcontrol *kcontrol, int event)1391{1392	struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);1393	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);1394 1395	switch (event) {1396	case SND_SOC_DAPM_POST_PMD:1397		regmap_multi_reg_write(cs43130->regmap, hpin_prepmd_seq,1398				       ARRAY_SIZE(hpin_prepmd_seq));1399		break;1400	case SND_SOC_DAPM_PRE_PMU:1401		regmap_multi_reg_write(cs43130->regmap, hpin_postpmu_seq,1402				       ARRAY_SIZE(hpin_postpmu_seq));1403		break;1404	default:1405		dev_err(cs43130->dev, "Invalid HPIN event = 0x%x\n", event);1406		return -EINVAL;1407	}1408	return 0;1409}1410 1411static const char * const bypass_mux_text[] = {1412	"Internal",1413	"Alternative",1414};1415static SOC_ENUM_SINGLE_DECL(bypass_enum, SND_SOC_NOPM, 0, bypass_mux_text);1416static const struct snd_kcontrol_new bypass_ctrl = SOC_DAPM_ENUM("Switch", bypass_enum);1417 1418static const struct snd_soc_dapm_widget hp_widgets[] = {1419	SND_SOC_DAPM_MUX("Bypass Switch", SND_SOC_NOPM, 0, 0, &bypass_ctrl),1420	SND_SOC_DAPM_OUTPUT("HPOUTA"),1421	SND_SOC_DAPM_OUTPUT("HPOUTB"),1422 1423	SND_SOC_DAPM_AIF_IN_E("ASPIN PCM", NULL, 0, CS43130_PWDN_CTL,1424			      CS43130_PDN_ASP_SHIFT, 1, cs43130_pcm_event,1425			      (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |1426			       SND_SOC_DAPM_PRE_PMD)),1427 1428	SND_SOC_DAPM_AIF_IN_E("ASPIN DoP", NULL, 0, CS43130_PWDN_CTL,1429			      CS43130_PDN_ASP_SHIFT, 1, cs43130_dsd_event,1430			      (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |1431			       SND_SOC_DAPM_PRE_PMD)),1432 1433	SND_SOC_DAPM_AIF_IN_E("XSPIN DoP", NULL, 0, CS43130_PWDN_CTL,1434			      CS43130_PDN_XSP_SHIFT, 1, cs43130_dsd_event,1435			      (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |1436			       SND_SOC_DAPM_PRE_PMD)),1437 1438	SND_SOC_DAPM_AIF_IN_E("XSPIN DSD", NULL, 0, CS43130_PWDN_CTL,1439			      CS43130_PDN_DSDIF_SHIFT, 1, cs43130_dsd_event,1440			      (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |1441			       SND_SOC_DAPM_PRE_PMD)),1442 1443	SND_SOC_DAPM_DAC("DSD", NULL, CS43130_DSD_PATH_CTL_2,1444			 CS43130_DSD_EN_SHIFT, 0),1445 1446	SND_SOC_DAPM_DAC_E("HiFi DAC", NULL, CS43130_PWDN_CTL,1447			   CS43130_PDN_HP_SHIFT, 1, cs43130_dac_event,1448			   (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |1449			    SND_SOC_DAPM_POST_PMD)),1450 1451/* Some devices have some extra analog widgets */1452#define NUM_ANALOG_WIDGETS	11453 1454	SND_SOC_DAPM_DAC_E("Analog Playback", NULL, CS43130_HP_OUT_CTL_1,1455			   CS43130_HP_IN_EN_SHIFT, 0, cs43130_hpin_event,1456			   (SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD)),1457};1458 1459static const struct snd_soc_dapm_route hp_routes[] = {1460	{"ASPIN PCM", NULL, "ASP PCM Playback"},1461	{"ASPIN DoP", NULL, "ASP DoP Playback"},1462	{"XSPIN DoP", NULL, "XSP DoP Playback"},1463	{"XSPIN DSD", NULL, "XSP DSD Playback"},1464	{"DSD", NULL, "ASPIN DoP"},1465	{"DSD", NULL, "XSPIN DoP"},1466	{"DSD", NULL, "XSPIN DSD"},1467	{"HiFi DAC", NULL, "ASPIN PCM"},1468	{"HiFi DAC", NULL, "DSD"},1469	{"Bypass Switch", "Internal", "HiFi DAC"},1470	{"HPOUTA", NULL, "Bypass Switch"},1471	{"HPOUTB", NULL, "Bypass Switch"},1472 1473/* Some devices have some extra analog routes */1474#define NUM_ANALOG_ROUTES	11475	{"Bypass Switch", "Alternative", "Analog Playback"},1476};1477 1478 1479static const unsigned int cs43130_asp_src_rates[] = {1480	32000, 44100, 48000, 88200, 96000, 176400, 192000, 352800, 3840001481};1482 1483static const struct snd_pcm_hw_constraint_list cs43130_asp_constraints = {1484	.count	= ARRAY_SIZE(cs43130_asp_src_rates),1485	.list	= cs43130_asp_src_rates,1486};1487 1488static int cs43130_pcm_startup(struct snd_pcm_substream *substream,1489			       struct snd_soc_dai *dai)1490{1491	return snd_pcm_hw_constraint_list(substream->runtime, 0,1492					  SNDRV_PCM_HW_PARAM_RATE,1493					  &cs43130_asp_constraints);1494}1495 1496static const unsigned int cs43130_dop_src_rates[] = {1497	176400, 352800,1498};1499 1500static const struct snd_pcm_hw_constraint_list cs43130_dop_constraints = {1501	.count	= ARRAY_SIZE(cs43130_dop_src_rates),1502	.list	= cs43130_dop_src_rates,1503};1504 1505static int cs43130_dop_startup(struct snd_pcm_substream *substream,1506			       struct snd_soc_dai *dai)1507{1508	return snd_pcm_hw_constraint_list(substream->runtime, 0,1509					  SNDRV_PCM_HW_PARAM_RATE,1510					  &cs43130_dop_constraints);1511}1512 1513static int cs43130_pcm_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)1514{1515	struct snd_soc_component *component = codec_dai->component;1516	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);1517 1518	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {1519	case SND_SOC_DAIFMT_CBS_CFS:1520		cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBS_CFS;1521		break;1522	case SND_SOC_DAIFMT_CBM_CFM:1523		cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM;1524		break;1525	default:1526		dev_err(cs43130->dev, "unsupported mode\n");1527		return -EINVAL;1528	}1529 1530	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {1531	case SND_SOC_DAIFMT_NB_NF:1532		cs43130->dais[codec_dai->id].dai_invert = SND_SOC_DAIFMT_NB_NF;1533		break;1534	case SND_SOC_DAIFMT_IB_NF:1535		cs43130->dais[codec_dai->id].dai_invert = SND_SOC_DAIFMT_IB_NF;1536		break;1537	case SND_SOC_DAIFMT_NB_IF:1538		cs43130->dais[codec_dai->id].dai_invert = SND_SOC_DAIFMT_NB_IF;1539		break;1540	case SND_SOC_DAIFMT_IB_IF:1541		cs43130->dais[codec_dai->id].dai_invert = SND_SOC_DAIFMT_IB_IF;1542		break;1543	default:1544		dev_err(cs43130->dev, "Unsupported invert mode 0x%x\n",1545			fmt & SND_SOC_DAIFMT_INV_MASK);1546		return -EINVAL;1547	}1548 1549	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {1550	case SND_SOC_DAIFMT_I2S:1551		cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_I2S;1552		break;1553	case SND_SOC_DAIFMT_LEFT_J:1554		cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_LEFT_J;1555		break;1556	case SND_SOC_DAIFMT_DSP_A:1557		cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_DSP_A;1558		break;1559	case SND_SOC_DAIFMT_DSP_B:1560		cs43130->dais[codec_dai->id].dai_format = SND_SOC_DAIFMT_DSP_B;1561		break;1562	default:1563		dev_err(cs43130->dev,1564			"unsupported audio format\n");1565		return -EINVAL;1566	}1567 1568	dev_dbg(cs43130->dev, "dai_id = %d,  dai_mode = %u, dai_format = %u\n",1569		codec_dai->id,1570		cs43130->dais[codec_dai->id].dai_mode,1571		cs43130->dais[codec_dai->id].dai_format);1572 1573	return 0;1574}1575 1576static int cs43130_dsd_set_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt)1577{1578	struct snd_soc_component *component = codec_dai->component;1579	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);1580 1581	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {1582	case SND_SOC_DAIFMT_CBS_CFS:1583		cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBS_CFS;1584		break;1585	case SND_SOC_DAIFMT_CBM_CFM:1586		cs43130->dais[codec_dai->id].dai_mode = SND_SOC_DAIFMT_CBM_CFM;1587		break;1588	default:1589		dev_err(cs43130->dev, "Unsupported DAI format.\n");1590		return -EINVAL;1591	}1592 1593	dev_dbg(cs43130->dev, "dai_mode = 0x%x\n",1594		cs43130->dais[codec_dai->id].dai_mode);1595 1596	return 0;1597}1598 1599static int cs43130_set_sysclk(struct snd_soc_dai *codec_dai,1600				  int clk_id, unsigned int freq, int dir)1601{1602	struct snd_soc_component *component = codec_dai->component;1603	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);1604 1605	cs43130->dais[codec_dai->id].sclk = freq;1606	dev_dbg(cs43130->dev, "dai_id = %d,  sclk = %u\n", codec_dai->id,1607		cs43130->dais[codec_dai->id].sclk);1608 1609	return 0;1610}1611 1612static const struct snd_soc_dai_ops cs43130_pcm_ops = {1613	.startup	= cs43130_pcm_startup,1614	.hw_params	= cs43130_hw_params,1615	.hw_free	= cs43130_hw_free,1616	.set_sysclk	= cs43130_set_sysclk,1617	.set_fmt	= cs43130_pcm_set_fmt,1618};1619 1620static const struct snd_soc_dai_ops cs43130_dop_ops = {1621	.startup	= cs43130_dop_startup,1622	.hw_params	= cs43130_hw_params,1623	.hw_free	= cs43130_hw_free,1624	.set_sysclk	= cs43130_set_sysclk,1625	.set_fmt	= cs43130_pcm_set_fmt,1626};1627 1628static const struct snd_soc_dai_ops cs43130_dsd_ops = {1629	.startup        = cs43130_dop_startup,1630	.hw_params	= cs43130_dsd_hw_params,1631	.hw_free	= cs43130_hw_free,1632	.set_fmt	= cs43130_dsd_set_fmt,1633};1634 1635static struct snd_soc_dai_driver cs43130_dai[] = {1636	{1637		.name = "cs43130-asp-pcm",1638		.id = CS43130_ASP_PCM_DAI,1639		.playback = {1640			.stream_name = "ASP PCM Playback",1641			.channels_min = 1,1642			.channels_max = 2,1643			.rates = SNDRV_PCM_RATE_KNOT,1644			.formats = CS43130_PCM_FORMATS,1645		},1646		.ops = &cs43130_pcm_ops,1647		.symmetric_rate = 1,1648	},1649	{1650		.name = "cs43130-asp-dop",1651		.id = CS43130_ASP_DOP_DAI,1652		.playback = {1653			.stream_name = "ASP DoP Playback",1654			.channels_min = 1,1655			.channels_max = 2,1656			.rates = SNDRV_PCM_RATE_KNOT,1657			.formats = CS43130_DOP_FORMATS,1658		},1659		.ops = &cs43130_dop_ops,1660		.symmetric_rate = 1,1661	},1662	{1663		.name = "cs43130-xsp-dop",1664		.id = CS43130_XSP_DOP_DAI,1665		.playback = {1666			.stream_name = "XSP DoP Playback",1667			.channels_min = 1,1668			.channels_max = 2,1669			.rates = SNDRV_PCM_RATE_KNOT,1670			.formats = CS43130_DOP_FORMATS,1671		},1672		.ops = &cs43130_dop_ops,1673		.symmetric_rate = 1,1674	},1675	{1676		.name = "cs43130-xsp-dsd",1677		.id = CS43130_XSP_DSD_DAI,1678		.playback = {1679			.stream_name = "XSP DSD Playback",1680			.channels_min = 1,1681			.channels_max = 2,1682			.rates = SNDRV_PCM_RATE_KNOT,1683			.formats = CS43130_DOP_FORMATS,1684		},1685		.ops = &cs43130_dsd_ops,1686	},1687 1688};1689 1690static int cs43130_component_set_sysclk(struct snd_soc_component *component,1691				    int clk_id, int source, unsigned int freq,1692				    int dir)1693{1694	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);1695 1696	dev_dbg(cs43130->dev, "clk_id = %d, source = %d, freq = %d, dir = %d\n",1697		clk_id, source, freq, dir);1698 1699	switch (freq) {1700	case CS43130_MCLK_22M:1701	case CS43130_MCLK_24M:1702		cs43130->mclk = freq;1703		break;1704	default:1705		dev_err(cs43130->dev, "Invalid MCLK INT freq: %u\n", freq);1706		return -EINVAL;1707	}1708 1709	if (source == CS43130_MCLK_SRC_EXT) {1710		cs43130->pll_bypass = true;1711	} else {1712		dev_err(cs43130->dev, "Invalid MCLK source\n");1713		return -EINVAL;1714	}1715 1716	return 0;1717}1718 1719static inline u16 cs43130_get_ac_reg_val(u16 ac_freq)1720{1721	/* AC freq is counted in 5.94Hz step. */1722	return ac_freq / 6;1723}1724 1725static int cs43130_show_dc(struct device *dev, char *buf, u8 ch)1726{1727	struct i2c_client *client = to_i2c_client(dev);1728	struct cs43130_private *cs43130 = i2c_get_clientdata(client);1729 1730	if (!cs43130->hpload_done)1731		return sysfs_emit(buf, "NO_HPLOAD\n");1732	else1733		return sysfs_emit(buf, "%u\n", cs43130->hpload_dc[ch]);1734}1735 1736static ssize_t hpload_dc_l_show(struct device *dev,1737				struct device_attribute *attr, char *buf)1738{1739	return cs43130_show_dc(dev, buf, HP_LEFT);1740}1741 1742static ssize_t hpload_dc_r_show(struct device *dev,1743				struct device_attribute *attr, char *buf)1744{1745	return cs43130_show_dc(dev, buf, HP_RIGHT);1746}1747 1748static const u16 cs43130_ac_freq[CS43130_AC_FREQ] = {1749	24,1750	43,1751	93,1752	200,1753	431,1754	928,1755	2000,1756	4309,1757	9283,1758	20000,1759};1760 1761static int cs43130_show_ac(struct device *dev, char *buf, u8 ch)1762{1763	int i, j = 0, tmp;1764	struct i2c_client *client = to_i2c_client(dev);1765	struct cs43130_private *cs43130 = i2c_get_clientdata(client);1766 1767	if (cs43130->hpload_done && cs43130->ac_meas) {1768		for (i = 0; i < ARRAY_SIZE(cs43130_ac_freq); i++) {1769			tmp = sysfs_emit_at(buf, j, "%u\n",1770					    cs43130->hpload_ac[i][ch]);1771			if (!tmp)1772				break;1773 1774			j += tmp;1775		}1776 1777		return j;1778	} else {1779		return sysfs_emit(buf, "NO_HPLOAD\n");1780	}1781}1782 1783static ssize_t hpload_ac_l_show(struct device *dev,1784				struct device_attribute *attr, char *buf)1785{1786	return cs43130_show_ac(dev, buf, HP_LEFT);1787}1788 1789static ssize_t hpload_ac_r_show(struct device *dev,1790				struct device_attribute *attr, char *buf)1791{1792	return cs43130_show_ac(dev, buf, HP_RIGHT);1793}1794 1795static DEVICE_ATTR_RO(hpload_dc_l);1796static DEVICE_ATTR_RO(hpload_dc_r);1797static DEVICE_ATTR_RO(hpload_ac_l);1798static DEVICE_ATTR_RO(hpload_ac_r);1799 1800static struct attribute *hpload_attrs[] = {1801	&dev_attr_hpload_dc_l.attr,1802	&dev_attr_hpload_dc_r.attr,1803	&dev_attr_hpload_ac_l.attr,1804	&dev_attr_hpload_ac_r.attr,1805};1806ATTRIBUTE_GROUPS(hpload);1807 1808static const struct reg_sequence hp_en_cal_seq[] = {1809	{CS43130_INT_MASK_4, CS43130_INT_MASK_ALL},1810	{CS43130_HP_MEAS_LOAD_1, 0},1811	{CS43130_HP_MEAS_LOAD_2, 0},1812	{CS43130_INT_MASK_4, 0},1813	{CS43130_DXD1, 0x99},1814	{CS43130_DXD16, 0xBB},1815	{CS43130_DXD12, 0x01},1816	{CS43130_DXD19, 0xCB},1817	{CS43130_DXD17, 0x95},1818	{CS43130_DXD18, 0x0B},1819	{CS43130_DXD1, 0},1820	{CS43130_HP_LOAD_1, 0x80},1821};1822 1823static const struct reg_sequence hp_en_cal_seq2[] = {1824	{CS43130_INT_MASK_4, CS43130_INT_MASK_ALL},1825	{CS43130_HP_MEAS_LOAD_1, 0},1826	{CS43130_HP_MEAS_LOAD_2, 0},1827	{CS43130_INT_MASK_4, 0},1828	{CS43130_HP_LOAD_1, 0x80},1829};1830 1831static const struct reg_sequence hp_dis_cal_seq[] = {1832	{CS43130_HP_LOAD_1, 0x80},1833	{CS43130_DXD1, 0x99},1834	{CS43130_DXD12, 0},1835	{CS43130_DXD1, 0},1836	{CS43130_HP_LOAD_1, 0},1837};1838 1839static const struct reg_sequence hp_dis_cal_seq2[] = {1840	{CS43130_HP_LOAD_1, 0x80},1841	{CS43130_HP_LOAD_1, 0},1842};1843 1844static const struct reg_sequence hp_dc_ch_l_seq[] = {1845	{CS43130_DXD1, 0x99},1846	{CS43130_DXD19, 0x0A},1847	{CS43130_DXD17, 0x93},1848	{CS43130_DXD18, 0x0A},1849	{CS43130_DXD1, 0},1850	{CS43130_HP_LOAD_1, 0x80},1851	{CS43130_HP_LOAD_1, 0x81},1852};1853 1854static const struct reg_sequence hp_dc_ch_l_seq2[] = {1855	{CS43130_HP_LOAD_1, 0x80},1856	{CS43130_HP_LOAD_1, 0x81},1857};1858 1859static const struct reg_sequence hp_dc_ch_r_seq[] = {1860	{CS43130_DXD1, 0x99},1861	{CS43130_DXD19, 0x8A},1862	{CS43130_DXD17, 0x15},1863	{CS43130_DXD18, 0x06},1864	{CS43130_DXD1, 0},1865	{CS43130_HP_LOAD_1, 0x90},1866	{CS43130_HP_LOAD_1, 0x91},1867};1868 1869static const struct reg_sequence hp_dc_ch_r_seq2[] = {1870	{CS43130_HP_LOAD_1, 0x90},1871	{CS43130_HP_LOAD_1, 0x91},1872};1873 1874static const struct reg_sequence hp_ac_ch_l_seq[] = {1875	{CS43130_DXD1, 0x99},1876	{CS43130_DXD19, 0x0A},1877	{CS43130_DXD17, 0x93},1878	{CS43130_DXD18, 0x0A},1879	{CS43130_DXD1, 0},1880	{CS43130_HP_LOAD_1, 0x80},1881	{CS43130_HP_LOAD_1, 0x82},1882};1883 1884static const struct reg_sequence hp_ac_ch_l_seq2[] = {1885	{CS43130_HP_LOAD_1, 0x80},1886	{CS43130_HP_LOAD_1, 0x82},1887};1888 1889static const struct reg_sequence hp_ac_ch_r_seq[] = {1890	{CS43130_DXD1, 0x99},1891	{CS43130_DXD19, 0x8A},1892	{CS43130_DXD17, 0x15},1893	{CS43130_DXD18, 0x06},1894	{CS43130_DXD1, 0},1895	{CS43130_HP_LOAD_1, 0x90},1896	{CS43130_HP_LOAD_1, 0x92},1897};1898 1899static const struct reg_sequence hp_ac_ch_r_seq2[] = {1900	{CS43130_HP_LOAD_1, 0x90},1901	{CS43130_HP_LOAD_1, 0x92},1902};1903 1904static const struct reg_sequence hp_cln_seq[] = {1905	{CS43130_INT_MASK_4, CS43130_INT_MASK_ALL},1906	{CS43130_HP_MEAS_LOAD_1, 0},1907	{CS43130_HP_MEAS_LOAD_2, 0},1908};1909 1910struct reg_sequences {1911	const struct reg_sequence	*seq;1912	int				size;1913	unsigned int			msk;1914};1915 1916static const struct reg_sequences hpload_seq1[] = {1917	{1918		.seq	= hp_en_cal_seq,1919		.size	= ARRAY_SIZE(hp_en_cal_seq),1920		.msk	= CS43130_HPLOAD_ON_INT,1921	},1922	{1923		.seq	= hp_dc_ch_l_seq,1924		.size	= ARRAY_SIZE(hp_dc_ch_l_seq),1925		.msk	= CS43130_HPLOAD_DC_INT,1926	},1927	{1928		.seq	= hp_ac_ch_l_seq,1929		.size	= ARRAY_SIZE(hp_ac_ch_l_seq),1930		.msk	= CS43130_HPLOAD_AC_INT,1931	},1932	{1933		.seq	= hp_dis_cal_seq,1934		.size	= ARRAY_SIZE(hp_dis_cal_seq),1935		.msk	= CS43130_HPLOAD_OFF_INT,1936	},1937	{1938		.seq	= hp_en_cal_seq,1939		.size	= ARRAY_SIZE(hp_en_cal_seq),1940		.msk	= CS43130_HPLOAD_ON_INT,1941	},1942	{1943		.seq	= hp_dc_ch_r_seq,1944		.size	= ARRAY_SIZE(hp_dc_ch_r_seq),1945		.msk	= CS43130_HPLOAD_DC_INT,1946	},1947	{1948		.seq	= hp_ac_ch_r_seq,1949		.size	= ARRAY_SIZE(hp_ac_ch_r_seq),1950		.msk	= CS43130_HPLOAD_AC_INT,1951	},1952};1953 1954static const struct reg_sequences hpload_seq2[] = {1955	{1956		.seq	= hp_en_cal_seq2,1957		.size	= ARRAY_SIZE(hp_en_cal_seq2),1958		.msk	= CS43130_HPLOAD_ON_INT,1959	},1960	{1961		.seq	= hp_dc_ch_l_seq2,1962		.size	= ARRAY_SIZE(hp_dc_ch_l_seq2),1963		.msk	= CS43130_HPLOAD_DC_INT,1964	},1965	{1966		.seq	= hp_ac_ch_l_seq2,1967		.size	= ARRAY_SIZE(hp_ac_ch_l_seq2),1968		.msk	= CS43130_HPLOAD_AC_INT,1969	},1970	{1971		.seq	= hp_dis_cal_seq2,1972		.size	= ARRAY_SIZE(hp_dis_cal_seq2),1973		.msk	= CS43130_HPLOAD_OFF_INT,1974	},1975	{1976		.seq	= hp_en_cal_seq2,1977		.size	= ARRAY_SIZE(hp_en_cal_seq2),1978		.msk	= CS43130_HPLOAD_ON_INT,1979	},1980	{1981		.seq	= hp_dc_ch_r_seq2,1982		.size	= ARRAY_SIZE(hp_dc_ch_r_seq2),1983		.msk	= CS43130_HPLOAD_DC_INT,1984	},1985	{1986		.seq	= hp_ac_ch_r_seq2,1987		.size	= ARRAY_SIZE(hp_ac_ch_r_seq2),1988		.msk	= CS43130_HPLOAD_AC_INT,1989	},1990};1991 1992static int cs43130_update_hpload(unsigned int msk, int ac_idx,1993				 struct cs43130_private *cs43130)1994{1995	bool left_ch = true;1996	unsigned int reg;1997	u32 addr;1998	u16 impedance;1999 2000	switch (msk) {2001	case CS43130_HPLOAD_DC_INT:2002	case CS43130_HPLOAD_AC_INT:2003		break;2004	default:2005		return 0;2006	}2007 2008	regmap_read(cs43130->regmap, CS43130_HP_LOAD_1, &reg);2009	if (reg & CS43130_HPLOAD_CHN_SEL)2010		left_ch = false;2011 2012	if (msk == CS43130_HPLOAD_DC_INT)2013		addr = CS43130_HP_DC_STAT_1;2014	else2015		addr = CS43130_HP_AC_STAT_1;2016 2017	regmap_read(cs43130->regmap, addr, &reg);2018	impedance = reg >> 3;2019	regmap_read(cs43130->regmap, addr + 1, &reg);2020	impedance |= reg << 5;2021 2022	if (msk == CS43130_HPLOAD_DC_INT) {2023		if (left_ch)2024			cs43130->hpload_dc[HP_LEFT] = impedance;2025		else2026			cs43130->hpload_dc[HP_RIGHT] = impedance;2027 2028		dev_dbg(cs43130->dev, "HP DC impedance (Ch %u): %u\n", !left_ch,2029			impedance);2030	} else {2031		if (left_ch)2032			cs43130->hpload_ac[ac_idx][HP_LEFT] = impedance;2033		else2034			cs43130->hpload_ac[ac_idx][HP_RIGHT] = impedance;2035 2036		dev_dbg(cs43130->dev, "HP AC (%u Hz) impedance (Ch %u): %u\n",2037			cs43130->ac_freq[ac_idx], !left_ch, impedance);2038	}2039 2040	return 0;2041}2042 2043static int cs43130_hpload_proc(struct cs43130_private *cs43130,2044			       const struct reg_sequence *seq, int seq_size,2045			       unsigned int rslt_msk, int ac_idx)2046{2047	int ret;2048	unsigned int msk;2049	u16 ac_reg_val;2050 2051	reinit_completion(&cs43130->hpload_evt);2052 2053	if (rslt_msk == CS43130_HPLOAD_AC_INT) {2054		ac_reg_val = cs43130_get_ac_reg_val(cs43130->ac_freq[ac_idx]);2055		regmap_update_bits(cs43130->regmap, CS43130_HP_LOAD_1,2056				   CS43130_HPLOAD_AC_START, 0);2057		regmap_update_bits(cs43130->regmap, CS43130_HP_MEAS_LOAD_1,2058				   CS43130_HP_MEAS_LOAD_MASK,2059				   ac_reg_val >> CS43130_HP_MEAS_LOAD_1_SHIFT);2060		regmap_update_bits(cs43130->regmap, CS43130_HP_MEAS_LOAD_2,2061				   CS43130_HP_MEAS_LOAD_MASK,2062				   ac_reg_val >> CS43130_HP_MEAS_LOAD_2_SHIFT);2063	}2064 2065	regmap_multi_reg_write(cs43130->regmap, seq,2066			       seq_size);2067 2068	ret = wait_for_completion_timeout(&cs43130->hpload_evt,2069					  msecs_to_jiffies(1000));2070	regmap_read(cs43130->regmap, CS43130_INT_MASK_4, &msk);2071	if (!ret) {2072		dev_err(cs43130->dev, "Timeout waiting for HPLOAD interrupt\n");2073		return -ETIMEDOUT;2074	}2075 2076	dev_dbg(cs43130->dev, "HP load stat: %x, INT_MASK_4: %x\n",2077		cs43130->hpload_stat, msk);2078	if ((cs43130->hpload_stat & (CS43130_HPLOAD_NO_DC_INT |2079				     CS43130_HPLOAD_UNPLUG_INT |2080				     CS43130_HPLOAD_OOR_INT)) ||2081	    !(cs43130->hpload_stat & rslt_msk)) {2082		dev_dbg(cs43130->dev, "HP load measure failed\n");2083		return -1;2084	}2085 2086	return 0;2087}2088 2089static const struct reg_sequence hv_seq[][2] = {2090	{2091		{CS43130_CLASS_H_CTL, 0x1C},2092		{CS43130_HP_OUT_CTL_1, 0x10},2093	},2094	{2095		{CS43130_CLASS_H_CTL, 0x1E},2096		{CS43130_HP_OUT_CTL_1, 0x20},2097	},2098	{2099		{CS43130_CLASS_H_CTL, 0x1E},2100		{CS43130_HP_OUT_CTL_1, 0x30},2101	},2102};2103 2104static int cs43130_set_hv(struct regmap *regmap, u16 hpload_dc,2105			  const u16 *dc_threshold)2106{2107	int i;2108 2109	for (i = 0; i < CS43130_DC_THRESHOLD; i++) {2110		if (hpload_dc <= dc_threshold[i])2111			break;2112	}2113 2114	regmap_multi_reg_write(regmap, hv_seq[i], ARRAY_SIZE(hv_seq[i]));2115 2116	return 0;2117}2118 2119static void cs43130_imp_meas(struct work_struct *wk)2120{2121	unsigned int reg, seq_size;2122	int i, ret, ac_idx;2123	struct cs43130_private *cs43130;2124	struct snd_soc_component *component;2125	const struct reg_sequences *hpload_seq;2126 2127	cs43130 = container_of(wk, struct cs43130_private, work);2128	component = cs43130->component;2129 2130	if (!cs43130->mclk)2131		return;2132 2133	cs43130->hpload_done = false;2134 2135	mutex_lock(&cs43130->clk_mutex);2136	if (!cs43130->clk_req) {2137		/* clk not in use */2138		cs43130_set_pll(component, 0, 0, cs43130->mclk, CS43130_MCLK_22M);2139		if (cs43130->pll_bypass)2140			cs43130_change_clksrc(component, CS43130_MCLK_SRC_EXT);2141		else2142			cs43130_change_clksrc(component, CS43130_MCLK_SRC_PLL);2143	}2144 2145	cs43130->clk_req++;2146	mutex_unlock(&cs43130->clk_mutex);2147 2148	regmap_read(cs43130->regmap, CS43130_INT_STATUS_4, &reg);2149 2150	switch (cs43130->dev_id) {2151	case CS43130_CHIP_ID:2152		hpload_seq = hpload_seq1;2153		seq_size = ARRAY_SIZE(hpload_seq1);2154		break;2155	case CS43131_CHIP_ID:2156		hpload_seq = hpload_seq2;2157		seq_size = ARRAY_SIZE(hpload_seq2);2158		break;2159	default:2160		WARN(1, "Invalid dev_id for meas: %d", cs43130->dev_id);2161		return;2162	}2163 2164	i = 0;2165	ac_idx = 0;2166	while (i < seq_size) {2167		ret = cs43130_hpload_proc(cs43130, hpload_seq[i].seq,2168					  hpload_seq[i].size,2169					  hpload_seq[i].msk, ac_idx);2170		if (ret < 0)2171			goto exit;2172 2173		cs43130_update_hpload(hpload_seq[i].msk, ac_idx, cs43130);2174 2175		if (cs43130->ac_meas &&2176		    hpload_seq[i].msk == CS43130_HPLOAD_AC_INT &&2177		    ac_idx < CS43130_AC_FREQ - 1) {2178			ac_idx++;2179		} else {2180			ac_idx = 0;2181			i++;2182		}2183	}2184	cs43130->hpload_done = true;2185 2186	if (cs43130->hpload_dc[HP_LEFT] >= CS43130_LINEOUT_LOAD)2187		snd_soc_jack_report(&cs43130->jack, CS43130_JACK_LINEOUT,2188				    CS43130_JACK_MASK);2189	else2190		snd_soc_jack_report(&cs43130->jack, CS43130_JACK_HEADPHONE,2191				    CS43130_JACK_MASK);2192 2193	dev_dbg(cs43130->dev, "Set HP output control. DC threshold\n");2194	for (i = 0; i < CS43130_DC_THRESHOLD; i++)2195		dev_dbg(cs43130->dev, "DC threshold[%d]: %u.\n", i,2196			cs43130->dc_threshold[i]);2197 2198	cs43130_set_hv(cs43130->regmap, cs43130->hpload_dc[HP_LEFT],2199		       cs43130->dc_threshold);2200 2201exit:2202	switch (cs43130->dev_id) {2203	case CS43130_CHIP_ID:2204		cs43130_hpload_proc(cs43130, hp_dis_cal_seq,2205				    ARRAY_SIZE(hp_dis_cal_seq),2206				    CS43130_HPLOAD_OFF_INT, ac_idx);2207		break;2208	case CS43131_CHIP_ID:2209		cs43130_hpload_proc(cs43130, hp_dis_cal_seq2,2210				    ARRAY_SIZE(hp_dis_cal_seq2),2211				    CS43130_HPLOAD_OFF_INT, ac_idx);2212		break;2213	}2214 2215	regmap_multi_reg_write(cs43130->regmap, hp_cln_seq,2216			       ARRAY_SIZE(hp_cln_seq));2217 2218	mutex_lock(&cs43130->clk_mutex);2219	cs43130->clk_req--;2220	/* clk not in use */2221	if (!cs43130->clk_req)2222		cs43130_change_clksrc(component, CS43130_MCLK_SRC_RCO);2223	mutex_unlock(&cs43130->clk_mutex);2224}2225 2226static irqreturn_t cs43130_irq_thread(int irq, void *data)2227{2228	struct cs43130_private *cs43130 = (struct cs43130_private *)data;2229	unsigned int stickies[CS43130_NUM_INT];2230	unsigned int irq_occurrence = 0;2231	unsigned int masks[CS43130_NUM_INT];2232	int i, j;2233 2234	for (i = 0; i < ARRAY_SIZE(stickies); i++) {2235		regmap_read(cs43130->regmap, CS43130_INT_STATUS_1 + i,2236			    &stickies[i]);2237		regmap_read(cs43130->regmap, CS43130_INT_MASK_1 + i,2238			    &masks[i]);2239	}2240 2241	for (i = 0; i < ARRAY_SIZE(stickies); i++) {2242		stickies[i] = stickies[i] & (~masks[i]);2243		for (j = 0; j < 8; j++)2244			irq_occurrence += (stickies[i] >> j) & 1;2245	}2246 2247	if (!irq_occurrence)2248		return IRQ_NONE;2249 2250	if (stickies[0] & CS43130_XTAL_RDY_INT) {2251		complete(&cs43130->xtal_rdy);2252		return IRQ_HANDLED;2253	}2254 2255	if (stickies[0] & CS43130_PLL_RDY_INT) {2256		complete(&cs43130->pll_rdy);2257		return IRQ_HANDLED;2258	}2259 2260	if (stickies[3] & CS43130_HPLOAD_NO_DC_INT) {2261		cs43130->hpload_stat = stickies[3];2262		dev_err(cs43130->dev,2263			"DC load has not completed before AC load (%x)\n",2264			cs43130->hpload_stat);2265		complete(&cs43130->hpload_evt);2266		return IRQ_HANDLED;2267	}2268 2269	if (stickies[3] & CS43130_HPLOAD_UNPLUG_INT) {2270		cs43130->hpload_stat = stickies[3];2271		dev_err(cs43130->dev, "HP unplugged during measurement (%x)\n",2272			cs43130->hpload_stat);2273		complete(&cs43130->hpload_evt);2274		return IRQ_HANDLED;2275	}2276 2277	if (stickies[3] & CS43130_HPLOAD_OOR_INT) {2278		cs43130->hpload_stat = stickies[3];2279		dev_err(cs43130->dev, "HP load out of range (%x)\n",2280			cs43130->hpload_stat);2281		complete(&cs43130->hpload_evt);2282		return IRQ_HANDLED;2283	}2284 2285	if (stickies[3] & CS43130_HPLOAD_AC_INT) {2286		cs43130->hpload_stat = stickies[3];2287		dev_dbg(cs43130->dev, "HP AC load measurement done (%x)\n",2288			cs43130->hpload_stat);2289		complete(&cs43130->hpload_evt);2290		return IRQ_HANDLED;2291	}2292 2293	if (stickies[3] & CS43130_HPLOAD_DC_INT) {2294		cs43130->hpload_stat = stickies[3];2295		dev_dbg(cs43130->dev, "HP DC load measurement done (%x)\n",2296			cs43130->hpload_stat);2297		complete(&cs43130->hpload_evt);2298		return IRQ_HANDLED;2299	}2300 2301	if (stickies[3] & CS43130_HPLOAD_ON_INT) {2302		cs43130->hpload_stat = stickies[3];2303		dev_dbg(cs43130->dev, "HP load state machine on done (%x)\n",2304			cs43130->hpload_stat);2305		complete(&cs43130->hpload_evt);2306		return IRQ_HANDLED;2307	}2308 2309	if (stickies[3] & CS43130_HPLOAD_OFF_INT) {2310		cs43130->hpload_stat = stickies[3];2311		dev_dbg(cs43130->dev, "HP load state machine off done (%x)\n",2312			cs43130->hpload_stat);2313		complete(&cs43130->hpload_evt);2314		return IRQ_HANDLED;2315	}2316 2317	if (stickies[0] & CS43130_XTAL_ERR_INT) {2318		dev_err(cs43130->dev, "Crystal err: clock is not running\n");2319		return IRQ_HANDLED;2320	}2321 2322	if (stickies[0] & CS43130_HP_UNPLUG_INT) {2323		dev_dbg(cs43130->dev, "HP unplugged\n");2324		cs43130->hpload_done = false;2325		snd_soc_jack_report(&cs43130->jack, 0, CS43130_JACK_MASK);2326		return IRQ_HANDLED;2327	}2328 2329	if (stickies[0] & CS43130_HP_PLUG_INT) {2330		if (cs43130->dc_meas && !cs43130->hpload_done &&2331		    !work_busy(&cs43130->work)) {2332			dev_dbg(cs43130->dev, "HP load queue work\n");2333			queue_work(cs43130->wq, &cs43130->work);2334		}2335 2336		snd_soc_jack_report(&cs43130->jack, SND_JACK_MECHANICAL,2337				    CS43130_JACK_MASK);2338		return IRQ_HANDLED;2339	}2340 2341	return IRQ_NONE;2342}2343 2344static int cs43130_probe(struct snd_soc_component *component)2345{2346	int ret;2347	struct cs43130_private *cs43130 = snd_soc_component_get_drvdata(component);2348	struct snd_soc_card *card = component->card;2349	unsigned int reg;2350 2351	cs43130->component = component;2352 2353	if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED) {2354		regmap_update_bits(cs43130->regmap, CS43130_CRYSTAL_SET,2355				   CS43130_XTAL_IBIAS_MASK,2356				   cs43130->xtal_ibias);2357		regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,2358				   CS43130_XTAL_ERR_INT, 0);2359	}2360 2361	ret = snd_soc_card_jack_new(card, "Headphone", CS43130_JACK_MASK,2362				    &cs43130->jack);2363	if (ret < 0) {2364		dev_err(cs43130->dev, "Cannot create jack\n");2365		return ret;2366	}2367 2368	cs43130->hpload_done = false;2369	if (cs43130->dc_meas) {2370		ret = sysfs_create_groups(&cs43130->dev->kobj, hpload_groups);2371		if (ret)2372			return ret;2373 2374		cs43130->wq = create_singlethread_workqueue("cs43130_hp");2375		if (!cs43130->wq) {2376			sysfs_remove_groups(&cs43130->dev->kobj, hpload_groups);2377			return -ENOMEM;2378		}2379		INIT_WORK(&cs43130->work, cs43130_imp_meas);2380	}2381 2382	regmap_read(cs43130->regmap, CS43130_INT_STATUS_1, &reg);2383	regmap_read(cs43130->regmap, CS43130_HP_STATUS, &reg);2384	regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,2385			   CS43130_HP_PLUG_INT | CS43130_HP_UNPLUG_INT, 0);2386	regmap_update_bits(cs43130->regmap, CS43130_HP_DETECT,2387			   CS43130_HP_DETECT_CTRL_MASK, 0);2388	regmap_update_bits(cs43130->regmap, CS43130_HP_DETECT,2389			   CS43130_HP_DETECT_CTRL_MASK,2390			   CS43130_HP_DETECT_CTRL_MASK);2391 2392	return 0;2393}2394 2395static const struct snd_soc_component_driver soc_component_dev_cs43130_digital = {2396	.probe			= cs43130_probe,2397	.controls		= cs43130_snd_controls,2398	.num_controls		= ARRAY_SIZE(cs43130_snd_controls),2399	.set_sysclk		= cs43130_component_set_sysclk,2400	.set_pll		= cs43130_set_pll,2401	.idle_bias_on		= 1,2402	.use_pmdown_time	= 1,2403	.endianness		= 1,2404	/* Don't take into account the ending analog widgets and routes */2405	.dapm_widgets		= hp_widgets,2406	.num_dapm_widgets	= ARRAY_SIZE(hp_widgets) - NUM_ANALOG_WIDGETS,2407	.dapm_routes		= hp_routes,2408	.num_dapm_routes	= ARRAY_SIZE(hp_routes) - NUM_ANALOG_ROUTES,2409};2410 2411static const struct snd_soc_component_driver soc_component_dev_cs43130_analog = {2412	.probe			= cs43130_probe,2413	.controls		= cs43130_snd_controls,2414	.num_controls		= ARRAY_SIZE(cs43130_snd_controls),2415	.set_sysclk		= cs43130_component_set_sysclk,2416	.set_pll		= cs43130_set_pll,2417	.idle_bias_on		= 1,2418	.use_pmdown_time	= 1,2419	.endianness		= 1,2420	.dapm_widgets		= hp_widgets,2421	.num_dapm_widgets	= ARRAY_SIZE(hp_widgets),2422	.dapm_routes		= hp_routes,2423	.num_dapm_routes	= ARRAY_SIZE(hp_routes),2424};2425 2426static const struct regmap_config cs43130_regmap = {2427	.reg_bits		= 24,2428	.pad_bits		= 8,2429	.val_bits		= 8,2430 2431	.max_register		= CS43130_LASTREG,2432	.reg_defaults		= cs43130_reg_defaults,2433	.num_reg_defaults	= ARRAY_SIZE(cs43130_reg_defaults),2434	.readable_reg		= cs43130_readable_register,2435	.precious_reg		= cs43130_precious_register,2436	.volatile_reg		= cs43130_volatile_register,2437	.cache_type		= REGCACHE_MAPLE,2438	/* needed for regcache_sync */2439	.use_single_read	= true,2440	.use_single_write	= true,2441};2442 2443static const u16 cs43130_dc_threshold[CS43130_DC_THRESHOLD] = {2444	50,2445	120,2446};2447 2448static int cs43130_handle_device_data(struct cs43130_private *cs43130)2449{2450	unsigned int val;2451	int i;2452 2453	if (device_property_read_u32(cs43130->dev, "cirrus,xtal-ibias", &val) < 0) {2454		/* Crystal is unused. System clock is used for external MCLK */2455		cs43130->xtal_ibias = CS43130_XTAL_UNUSED;2456		return 0;2457	}2458 2459	switch (val) {2460	case 1:2461		cs43130->xtal_ibias = CS43130_XTAL_IBIAS_7_5UA;2462		break;2463	case 2:2464		cs43130->xtal_ibias = CS43130_XTAL_IBIAS_12_5UA;2465		break;2466	case 3:2467		cs43130->xtal_ibias = CS43130_XTAL_IBIAS_15UA;2468		break;2469	default:2470		dev_err(cs43130->dev,2471			"Invalid cirrus,xtal-ibias value: %d\n", val);2472		return -EINVAL;2473	}2474 2475	cs43130->dc_meas = device_property_read_bool(cs43130->dev, "cirrus,dc-measure");2476	cs43130->ac_meas = device_property_read_bool(cs43130->dev, "cirrus,ac-measure");2477 2478	if (!device_property_read_u16_array(cs43130->dev, "cirrus,ac-freq", cs43130->ac_freq,2479					CS43130_AC_FREQ)) {2480		for (i = 0; i < CS43130_AC_FREQ; i++)2481			cs43130->ac_freq[i] = cs43130_ac_freq[i];2482	}2483 2484	if (!device_property_read_u16_array(cs43130->dev, "cirrus,dc-threshold",2485				       cs43130->dc_threshold,2486				       CS43130_DC_THRESHOLD)) {2487		for (i = 0; i < CS43130_DC_THRESHOLD; i++)2488			cs43130->dc_threshold[i] = cs43130_dc_threshold[i];2489	}2490 2491	return 0;2492}2493 2494static int cs43130_i2c_probe(struct i2c_client *client)2495{2496	const struct snd_soc_component_driver *component_driver;2497	struct cs43130_private *cs43130;2498	int ret;2499	unsigned int reg;2500	int i, devid;2501 2502	cs43130 = devm_kzalloc(&client->dev, sizeof(*cs43130), GFP_KERNEL);2503	if (!cs43130)2504		return -ENOMEM;2505 2506	cs43130->dev = &client->dev;2507 2508	i2c_set_clientdata(client, cs43130);2509 2510	cs43130->regmap = devm_regmap_init_i2c(client, &cs43130_regmap);2511	if (IS_ERR(cs43130->regmap)) {2512		ret = PTR_ERR(cs43130->regmap);2513		return ret;2514	}2515 2516	if (dev_fwnode(cs43130->dev)) {2517		ret = cs43130_handle_device_data(cs43130);2518		if (ret != 0)2519			return ret;2520	}2521 2522	for (i = 0; i < ARRAY_SIZE(cs43130->supplies); i++)2523		cs43130->supplies[i].supply = cs43130_supply_names[i];2524 2525	ret = devm_regulator_bulk_get(cs43130->dev,2526				      ARRAY_SIZE(cs43130->supplies),2527				      cs43130->supplies);2528	if (ret != 0) {2529		dev_err(cs43130->dev, "Failed to request supplies: %d\n", ret);2530		return ret;2531	}2532	ret = regulator_bulk_enable(ARRAY_SIZE(cs43130->supplies),2533				    cs43130->supplies);2534	if (ret != 0) {2535		dev_err(cs43130->dev, "Failed to enable supplies: %d\n", ret);2536		return ret;2537	}2538 2539	cs43130->reset_gpio = devm_gpiod_get_optional(cs43130->dev,2540						      "reset", GPIOD_OUT_LOW);2541	if (IS_ERR(cs43130->reset_gpio)) {2542		ret = PTR_ERR(cs43130->reset_gpio);2543		goto err_supplies;2544	}2545 2546	gpiod_set_value_cansleep(cs43130->reset_gpio, 1);2547 2548	usleep_range(2000, 2050);2549 2550	devid = cirrus_read_device_id(cs43130->regmap, CS43130_DEVID_AB);2551	if (devid < 0) {2552		ret = devid;2553		dev_err(cs43130->dev, "Failed to read device ID: %d\n", ret);2554		goto err;2555	}2556 2557	switch (devid) {2558	case CS43130_CHIP_ID:2559	case CS4399_CHIP_ID:2560	case CS43131_CHIP_ID:2561	case CS43198_CHIP_ID:2562		break;2563	default:2564		dev_err(cs43130->dev,2565			"CS43130 Device ID %X. Expected ID %X, %X, %X or %X\n",2566			devid, CS43130_CHIP_ID, CS4399_CHIP_ID,2567			CS43131_CHIP_ID, CS43198_CHIP_ID);2568		ret = -ENODEV;2569		goto err;2570	}2571 2572	cs43130->dev_id = devid;2573	ret = regmap_read(cs43130->regmap, CS43130_REV_ID, &reg);2574	if (ret < 0) {2575		dev_err(cs43130->dev, "Get Revision ID failed\n");2576		goto err;2577	}2578 2579	dev_info(cs43130->dev,2580		 "Cirrus Logic CS43130 (%x), Revision: %02X\n", devid,2581		 reg & 0xFF);2582 2583	mutex_init(&cs43130->clk_mutex);2584 2585	init_completion(&cs43130->xtal_rdy);2586	init_completion(&cs43130->pll_rdy);2587	init_completion(&cs43130->hpload_evt);2588 2589	if (!client->irq) {2590		dev_dbg(cs43130->dev, "IRQ not found, will poll instead\n");2591		cs43130->has_irq_line = 0;2592	} else {2593		ret = devm_request_threaded_irq(cs43130->dev, client->irq,2594						NULL, cs43130_irq_thread,2595						IRQF_ONESHOT | IRQF_TRIGGER_LOW,2596						"cs43130", cs43130);2597		if (ret != 0) {2598			dev_err(cs43130->dev, "Failed to request IRQ: %d\n", ret);2599			goto err;2600		}2601		cs43130->has_irq_line = 1;2602	}2603 2604	cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO;2605 2606	pm_runtime_set_autosuspend_delay(cs43130->dev, 100);2607	pm_runtime_use_autosuspend(cs43130->dev);2608	pm_runtime_set_active(cs43130->dev);2609	pm_runtime_enable(cs43130->dev);2610 2611	switch (cs43130->dev_id) {2612	case CS43130_CHIP_ID:2613	case CS43131_CHIP_ID:2614		component_driver = &soc_component_dev_cs43130_analog;2615		break;2616	case CS43198_CHIP_ID:2617	case CS4399_CHIP_ID:2618		component_driver = &soc_component_dev_cs43130_digital;2619		break;2620	}2621 2622	ret = devm_snd_soc_register_component(cs43130->dev, component_driver,2623				     cs43130_dai, ARRAY_SIZE(cs43130_dai));2624	if (ret < 0) {2625		dev_err(cs43130->dev,2626			"snd_soc_register_component failed with ret = %d\n", ret);2627		goto err;2628	}2629 2630	regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG,2631			   CS43130_ASP_3ST_MASK, 0);2632	regmap_update_bits(cs43130->regmap, CS43130_PAD_INT_CFG,2633			   CS43130_XSP_3ST_MASK, 0);2634 2635	return 0;2636 2637err:2638	gpiod_set_value_cansleep(cs43130->reset_gpio, 0);2639err_supplies:2640	regulator_bulk_disable(ARRAY_SIZE(cs43130->supplies),2641			       cs43130->supplies);2642 2643	return ret;2644}2645 2646static void cs43130_i2c_remove(struct i2c_client *client)2647{2648	struct cs43130_private *cs43130 = i2c_get_clientdata(client);2649 2650	if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED)2651		regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,2652				   CS43130_XTAL_ERR_INT,2653				   1 << CS43130_XTAL_ERR_INT_SHIFT);2654 2655	regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,2656			   CS43130_HP_PLUG_INT | CS43130_HP_UNPLUG_INT,2657			   CS43130_HP_PLUG_INT | CS43130_HP_UNPLUG_INT);2658 2659	if (cs43130->dc_meas) {2660		cancel_work_sync(&cs43130->work);2661		flush_workqueue(cs43130->wq);2662 2663		device_remove_file(cs43130->dev, &dev_attr_hpload_dc_l);2664		device_remove_file(cs43130->dev, &dev_attr_hpload_dc_r);2665		device_remove_file(cs43130->dev, &dev_attr_hpload_ac_l);2666		device_remove_file(cs43130->dev, &dev_attr_hpload_ac_r);2667	}2668 2669	gpiod_set_value_cansleep(cs43130->reset_gpio, 0);2670 2671	pm_runtime_disable(cs43130->dev);2672	regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies);2673}2674 2675static int __maybe_unused cs43130_runtime_suspend(struct device *dev)2676{2677	struct cs43130_private *cs43130 = dev_get_drvdata(dev);2678 2679	if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED)2680		regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,2681				   CS43130_XTAL_ERR_INT,2682				   1 << CS43130_XTAL_ERR_INT_SHIFT);2683 2684	regcache_cache_only(cs43130->regmap, true);2685	regcache_mark_dirty(cs43130->regmap);2686 2687	gpiod_set_value_cansleep(cs43130->reset_gpio, 0);2688 2689	regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies);2690 2691	return 0;2692}2693 2694static int __maybe_unused cs43130_runtime_resume(struct device *dev)2695{2696	struct cs43130_private *cs43130 = dev_get_drvdata(dev);2697	int ret;2698 2699	ret = regulator_bulk_enable(CS43130_NUM_SUPPLIES, cs43130->supplies);2700	if (ret != 0) {2701		dev_err(dev, "Failed to enable supplies: %d\n", ret);2702		return ret;2703	}2704 2705	regcache_cache_only(cs43130->regmap, false);2706 2707	gpiod_set_value_cansleep(cs43130->reset_gpio, 1);2708 2709	usleep_range(2000, 2050);2710 2711	ret = regcache_sync(cs43130->regmap);2712	if (ret != 0) {2713		dev_err(dev, "Failed to restore register cache\n");2714		goto err;2715	}2716 2717	if (cs43130->xtal_ibias != CS43130_XTAL_UNUSED)2718		regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1,2719				   CS43130_XTAL_ERR_INT, 0);2720 2721	return 0;2722err:2723	regcache_cache_only(cs43130->regmap, true);2724	regulator_bulk_disable(CS43130_NUM_SUPPLIES, cs43130->supplies);2725 2726	return ret;2727}2728 2729static const struct dev_pm_ops cs43130_runtime_pm = {2730	SET_RUNTIME_PM_OPS(cs43130_runtime_suspend, cs43130_runtime_resume,2731			   NULL)2732};2733 2734#if IS_ENABLED(CONFIG_OF)2735static const struct of_device_id cs43130_of_match[] = {2736	{.compatible = "cirrus,cs43130",},2737	{.compatible = "cirrus,cs4399",},2738	{.compatible = "cirrus,cs43131",},2739	{.compatible = "cirrus,cs43198",},2740	{},2741};2742 2743MODULE_DEVICE_TABLE(of, cs43130_of_match);2744#endif2745 2746#if IS_ENABLED(CONFIG_ACPI)2747static const struct acpi_device_id cs43130_acpi_match[] = {2748	{ "CSC4399", 0 },2749	{}2750};2751 2752MODULE_DEVICE_TABLE(acpi, cs43130_acpi_match);2753#endif2754 2755 2756static const struct i2c_device_id cs43130_i2c_id[] = {2757	{"cs43130"},2758	{"cs4399"},2759	{"cs43131"},2760	{"cs43198"},2761	{}2762};2763 2764MODULE_DEVICE_TABLE(i2c, cs43130_i2c_id);2765 2766static struct i2c_driver cs43130_i2c_driver = {2767	.driver = {2768		.name			= "cs43130",2769		.of_match_table		= of_match_ptr(cs43130_of_match),2770		.acpi_match_table	= ACPI_PTR(cs43130_acpi_match),2771		.pm			= &cs43130_runtime_pm,2772	},2773	.id_table	= cs43130_i2c_id,2774	.probe		= cs43130_i2c_probe,2775	.remove		= cs43130_i2c_remove,2776};2777 2778module_i2c_driver(cs43130_i2c_driver);2779 2780MODULE_AUTHOR("Li Xu <li.xu@cirrus.com>");2781MODULE_DESCRIPTION("Cirrus Logic CS43130 ALSA SoC Codec Driver");2782MODULE_LICENSE("GPL");2783