xref: /linux/sound/soc/codecs/ssm3515.c (revision a1c613ae4c322ddd58d5a8539dbfba2a0380a8c0)
14ac690bbSMartin Povišer // SPDX-License-Identifier: GPL-2.0-only OR MIT
24ac690bbSMartin Povišer //
34ac690bbSMartin Povišer // Analog Devices' SSM3515 audio amp driver
44ac690bbSMartin Povišer //
54ac690bbSMartin Povišer // Copyright (C) The Asahi Linux Contributors
64ac690bbSMartin Povišer 
74ac690bbSMartin Povišer #include <linux/bits.h>
84ac690bbSMartin Povišer #include <linux/bitfield.h>
94ac690bbSMartin Povišer #include <linux/device.h>
104ac690bbSMartin Povišer #include <linux/i2c.h>
114ac690bbSMartin Povišer #include <linux/module.h>
124ac690bbSMartin Povišer #include <linux/of.h>
134ac690bbSMartin Povišer #include <linux/regmap.h>
144ac690bbSMartin Povišer 
154ac690bbSMartin Povišer #include <sound/pcm.h>
164ac690bbSMartin Povišer #include <sound/pcm_params.h>
174ac690bbSMartin Povišer #include <sound/soc.h>
184ac690bbSMartin Povišer #include <sound/tlv.h>
194ac690bbSMartin Povišer 
204ac690bbSMartin Povišer 
214ac690bbSMartin Povišer #define SSM3515_PWR		0x00
224ac690bbSMartin Povišer #define SSM3515_PWR_APWDN_EN	BIT(7)
234ac690bbSMartin Povišer #define SSM3515_PWR_BSNS_PWDN	BIT(6)
244ac690bbSMartin Povišer #define SSM3515_PWR_S_RST	BIT(1)
254ac690bbSMartin Povišer #define SSM3515_PWR_SPWDN	BIT(0)
264ac690bbSMartin Povišer 
274ac690bbSMartin Povišer #define SSM3515_GEC		0x01
284ac690bbSMartin Povišer #define SSM3515_GEC_EDGE	BIT(4)
294ac690bbSMartin Povišer #define SSM3515_GEC_EDGE_SHIFT	4
304ac690bbSMartin Povišer #define SSM3515_GEC_ANA_GAIN	GENMASK(1, 0)
314ac690bbSMartin Povišer 
324ac690bbSMartin Povišer #define SSM3515_DAC		0x02
334ac690bbSMartin Povišer #define SSM3515_DAC_HV		BIT(7)
344ac690bbSMartin Povišer #define SSM3515_DAC_MUTE	BIT(6)
354ac690bbSMartin Povišer #define SSM3515_DAC_HPF		BIT(5)
364ac690bbSMartin Povišer #define SSM3515_DAC_LPM		BIT(4)
374ac690bbSMartin Povišer #define SSM3515_DAC_FS		GENMASK(2, 0)
384ac690bbSMartin Povišer 
394ac690bbSMartin Povišer #define SSM3515_DAC_VOL		0x03
404ac690bbSMartin Povišer 
414ac690bbSMartin Povišer #define SSM3515_SAI1		0x04
424ac690bbSMartin Povišer #define SSM3515_SAI1_DAC_POL	BIT(7)
434ac690bbSMartin Povišer #define SSM3515_SAI1_BCLK_POL	BIT(6)
444ac690bbSMartin Povišer #define SSM3515_SAI1_TDM_BCLKS	GENMASK(5, 3)
454ac690bbSMartin Povišer #define SSM3515_SAI1_FSYNC_MODE	BIT(2)
464ac690bbSMartin Povišer #define SSM3515_SAI1_SDATA_FMT	BIT(1)
474ac690bbSMartin Povišer #define SSM3515_SAI1_SAI_MODE	BIT(0)
484ac690bbSMartin Povišer 
494ac690bbSMartin Povišer #define SSM3515_SAI2		0x05
504ac690bbSMartin Povišer #define SSM3515_SAI2_DATA_WIDTH	BIT(7)
514ac690bbSMartin Povišer #define SSM3515_SAI2_AUTO_SLOT	BIT(4)
524ac690bbSMartin Povišer #define SSM3515_SAI2_TDM_SLOT	GENMASK(3, 0)
534ac690bbSMartin Povišer 
544ac690bbSMartin Povišer #define SSM3515_VBAT_OUT	0x06
554ac690bbSMartin Povišer 
564ac690bbSMartin Povišer #define SSM3515_STATUS		0x0a
574ac690bbSMartin Povišer #define SSM3515_STATUS_UVLO_REG	BIT(6)
584ac690bbSMartin Povišer #define SSM3515_STATUS_LIM_EG	BIT(5)
594ac690bbSMartin Povišer #define SSM3515_STATUS_CLIP	BIT(4)
604ac690bbSMartin Povišer #define SSM3515_STATUS_AMP_OC	BIT(3)
614ac690bbSMartin Povišer #define SSM3515_STATUS_OTF	BIT(2)
624ac690bbSMartin Povišer #define SSM3515_STATUS_OTW	BIT(1)
634ac690bbSMartin Povišer #define SSM3515_STATUS_BAT_WARN	BIT(0)
644ac690bbSMartin Povišer 
ssm3515_volatile_reg(struct device * dev,unsigned int reg)654ac690bbSMartin Povišer static bool ssm3515_volatile_reg(struct device *dev, unsigned int reg)
664ac690bbSMartin Povišer {
674ac690bbSMartin Povišer 	switch (reg) {
684ac690bbSMartin Povišer 	case SSM3515_STATUS:
694ac690bbSMartin Povišer 	case SSM3515_VBAT_OUT:
704ac690bbSMartin Povišer 		return true;
714ac690bbSMartin Povišer 
724ac690bbSMartin Povišer 	default:
734ac690bbSMartin Povišer 		return false;
744ac690bbSMartin Povišer 	}
754ac690bbSMartin Povišer }
764ac690bbSMartin Povišer 
774ac690bbSMartin Povišer static const struct reg_default ssm3515_reg_defaults[] = {
784ac690bbSMartin Povišer 	{ SSM3515_PWR, 0x81 },
794ac690bbSMartin Povišer 	{ SSM3515_GEC, 0x01 },
804ac690bbSMartin Povišer 	{ SSM3515_DAC, 0x32 },
814ac690bbSMartin Povišer 	{ SSM3515_DAC_VOL, 0x40 },
824ac690bbSMartin Povišer 	{ SSM3515_SAI1, 0x11 },
834ac690bbSMartin Povišer 	{ SSM3515_SAI2, 0x00 },
844ac690bbSMartin Povišer };
854ac690bbSMartin Povišer 
864ac690bbSMartin Povišer static const struct regmap_config ssm3515_i2c_regmap = {
874ac690bbSMartin Povišer 	.reg_bits = 8,
884ac690bbSMartin Povišer 	.val_bits = 8,
894ac690bbSMartin Povišer 	.volatile_reg = ssm3515_volatile_reg,
904ac690bbSMartin Povišer 	.max_register = 0xb,
914ac690bbSMartin Povišer 	.reg_defaults = ssm3515_reg_defaults,
924ac690bbSMartin Povišer 	.num_reg_defaults = ARRAY_SIZE(ssm3515_reg_defaults),
934ac690bbSMartin Povišer 	.cache_type = REGCACHE_FLAT,
944ac690bbSMartin Povišer };
954ac690bbSMartin Povišer 
964ac690bbSMartin Povišer struct ssm3515_data {
974ac690bbSMartin Povišer 	struct device *dev;
984ac690bbSMartin Povišer 	struct regmap *regmap;
994ac690bbSMartin Povišer };
1004ac690bbSMartin Povišer 
1014ac690bbSMartin Povišer // The specced range is -71.25...24.00 dB with step size of 0.375 dB,
1024ac690bbSMartin Povišer // and a mute item below that. This is represented by -71.62...24.00 dB
1034ac690bbSMartin Povišer // with the mute item mapped onto the low end.
1044ac690bbSMartin Povišer static DECLARE_TLV_DB_MINMAX_MUTE(ssm3515_dac_volume, -7162, 2400);
1054ac690bbSMartin Povišer 
1064ac690bbSMartin Povišer static const char * const ssm3515_ana_gain_text[] = {
1074ac690bbSMartin Povišer 	"8.4 V Span", "12.6 V Span", "14 V Span", "15 V Span",
1084ac690bbSMartin Povišer };
1094ac690bbSMartin Povišer 
1104ac690bbSMartin Povišer static SOC_ENUM_SINGLE_DECL(ssm3515_ana_gain_enum, SSM3515_GEC,
1114ac690bbSMartin Povišer 			    __bf_shf(SSM3515_GEC_ANA_GAIN),
1124ac690bbSMartin Povišer 			    ssm3515_ana_gain_text);
1134ac690bbSMartin Povišer 
1144ac690bbSMartin Povišer static const struct snd_kcontrol_new ssm3515_snd_controls[] = {
1154ac690bbSMartin Povišer 	SOC_SINGLE_TLV("DAC Playback Volume", SSM3515_DAC_VOL,
1164ac690bbSMartin Povišer 		       0, 255, 1, ssm3515_dac_volume),
1174ac690bbSMartin Povišer 	SOC_SINGLE("Low EMI Mode Switch", SSM3515_GEC,
1184ac690bbSMartin Povišer 		   __bf_shf(SSM3515_GEC_EDGE), 1, 0),
1194ac690bbSMartin Povišer 	SOC_SINGLE("Soft Volume Ramping Switch", SSM3515_DAC,
1204ac690bbSMartin Povišer 		   __bf_shf(SSM3515_DAC_HV), 1, 1),
1214ac690bbSMartin Povišer 	SOC_SINGLE("HPF Switch", SSM3515_DAC,
1224ac690bbSMartin Povišer 		   __bf_shf(SSM3515_DAC_HPF), 1, 0),
1234ac690bbSMartin Povišer 	SOC_SINGLE("DAC Invert Switch", SSM3515_SAI1,
1244ac690bbSMartin Povišer 		   __bf_shf(SSM3515_SAI1_DAC_POL), 1, 0),
1254ac690bbSMartin Povišer 	SOC_ENUM("DAC Analog Gain Select", ssm3515_ana_gain_enum),
1264ac690bbSMartin Povišer };
1274ac690bbSMartin Povišer 
ssm3515_read_faults(struct snd_soc_component * component)1284ac690bbSMartin Povišer static void ssm3515_read_faults(struct snd_soc_component *component)
1294ac690bbSMartin Povišer {
1304ac690bbSMartin Povišer 	int ret;
1314ac690bbSMartin Povišer 
1324ac690bbSMartin Povišer 	ret = snd_soc_component_read(component, SSM3515_STATUS);
1334ac690bbSMartin Povišer 	if (ret <= 0) {
1344ac690bbSMartin Povišer 		/*
1354ac690bbSMartin Povišer 		 * If the read was erroneous, ASoC core has printed a message,
1364ac690bbSMartin Povišer 		 * and that's all that's appropriate in handling the error here.
1374ac690bbSMartin Povišer 		 */
1384ac690bbSMartin Povišer 		return;
1394ac690bbSMartin Povišer 	}
1404ac690bbSMartin Povišer 
1414ac690bbSMartin Povišer 	dev_err(component->dev, "device reports:%s%s%s%s%s%s%s\n",
1424ac690bbSMartin Povišer 		FIELD_GET(SSM3515_STATUS_UVLO_REG, ret) ? " voltage regulator fault" : "",
1434ac690bbSMartin Povišer 		FIELD_GET(SSM3515_STATUS_LIM_EG, ret)   ? " limiter engaged" : "",
1444ac690bbSMartin Povišer 		FIELD_GET(SSM3515_STATUS_CLIP, ret)     ? " clipping detected" : "",
1454ac690bbSMartin Povišer 		FIELD_GET(SSM3515_STATUS_AMP_OC, ret)   ? " amp over-current fault" : "",
1464ac690bbSMartin Povišer 		FIELD_GET(SSM3515_STATUS_OTF, ret)      ? " overtemperature fault" : "",
1474ac690bbSMartin Povišer 		FIELD_GET(SSM3515_STATUS_OTW, ret)      ? " overtemperature warning" : "",
1484ac690bbSMartin Povišer 		FIELD_GET(SSM3515_STATUS_BAT_WARN, ret) ? " bat voltage low warning" : "");
1494ac690bbSMartin Povišer }
1504ac690bbSMartin Povišer 
ssm3515_probe(struct snd_soc_component * component)1514ac690bbSMartin Povišer static int ssm3515_probe(struct snd_soc_component *component)
1524ac690bbSMartin Povišer {
1534ac690bbSMartin Povišer 	int ret;
1544ac690bbSMartin Povišer 
1554ac690bbSMartin Povišer 	/* Start out muted */
1564ac690bbSMartin Povišer 	ret = snd_soc_component_update_bits(component, SSM3515_DAC,
1574ac690bbSMartin Povišer 			SSM3515_DAC_MUTE, SSM3515_DAC_MUTE);
1584ac690bbSMartin Povišer 	if (ret < 0)
1594ac690bbSMartin Povišer 		return ret;
1604ac690bbSMartin Povišer 
1614ac690bbSMartin Povišer 	/* Disable the 'master power-down' */
1624ac690bbSMartin Povišer 	ret = snd_soc_component_update_bits(component, SSM3515_PWR,
1634ac690bbSMartin Povišer 			SSM3515_PWR_SPWDN, 0);
1644ac690bbSMartin Povišer 	if (ret < 0)
1654ac690bbSMartin Povišer 		return ret;
1664ac690bbSMartin Povišer 
1674ac690bbSMartin Povišer 	return 0;
1684ac690bbSMartin Povišer }
1694ac690bbSMartin Povišer 
ssm3515_mute(struct snd_soc_dai * dai,int mute,int direction)1704ac690bbSMartin Povišer static int ssm3515_mute(struct snd_soc_dai *dai, int mute, int direction)
1714ac690bbSMartin Povišer {
1724ac690bbSMartin Povišer 	int ret;
1734ac690bbSMartin Povišer 
1744ac690bbSMartin Povišer 	ret = snd_soc_component_update_bits(dai->component,
1754ac690bbSMartin Povišer 					    SSM3515_DAC,
1764ac690bbSMartin Povišer 					    SSM3515_DAC_MUTE,
1774ac690bbSMartin Povišer 					    FIELD_PREP(SSM3515_DAC_MUTE, mute));
1784ac690bbSMartin Povišer 	if (ret < 0)
1794ac690bbSMartin Povišer 		return ret;
1804ac690bbSMartin Povišer 	return 0;
1814ac690bbSMartin Povišer }
1824ac690bbSMartin Povišer 
ssm3515_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)1834ac690bbSMartin Povišer static int ssm3515_hw_params(struct snd_pcm_substream *substream,
1844ac690bbSMartin Povišer 			     struct snd_pcm_hw_params *params,
1854ac690bbSMartin Povišer 			     struct snd_soc_dai *dai)
1864ac690bbSMartin Povišer {
1874ac690bbSMartin Povišer 	struct snd_soc_component *component = dai->component;
1884ac690bbSMartin Povišer 	int ret, rateval;
1894ac690bbSMartin Povišer 
1904ac690bbSMartin Povišer 	switch (params_format(params)) {
1914ac690bbSMartin Povišer 	case SNDRV_PCM_FORMAT_S16:
1924ac690bbSMartin Povišer 	case SNDRV_PCM_FORMAT_S24:
1934ac690bbSMartin Povišer 		ret = snd_soc_component_update_bits(component,
1944ac690bbSMartin Povišer 				SSM3515_SAI2, SSM3515_SAI2_DATA_WIDTH,
1954ac690bbSMartin Povišer 				FIELD_PREP(SSM3515_SAI2_DATA_WIDTH,
1964ac690bbSMartin Povišer 					   params_width(params) == 16));
1974ac690bbSMartin Povišer 		if (ret < 0)
1984ac690bbSMartin Povišer 			return ret;
1994ac690bbSMartin Povišer 		break;
2004ac690bbSMartin Povišer 
2014ac690bbSMartin Povišer 	default:
2024ac690bbSMartin Povišer 		return -EINVAL;
2034ac690bbSMartin Povišer 	}
2044ac690bbSMartin Povišer 
2054ac690bbSMartin Povišer 	switch (params_rate(params)) {
2064ac690bbSMartin Povišer 	case 8000 ... 12000:
2074ac690bbSMartin Povišer 		rateval = 0;
2084ac690bbSMartin Povišer 		break;
2094ac690bbSMartin Povišer 	case 16000 ... 24000:
2104ac690bbSMartin Povišer 		rateval = 1;
2114ac690bbSMartin Povišer 		break;
2124ac690bbSMartin Povišer 	case 32000 ... 48000:
2134ac690bbSMartin Povišer 		rateval = 2;
2144ac690bbSMartin Povišer 		break;
2154ac690bbSMartin Povišer 	case 64000 ... 96000:
2164ac690bbSMartin Povišer 		rateval = 3;
2174ac690bbSMartin Povišer 		break;
2184ac690bbSMartin Povišer 	case 128000 ... 192000:
2194ac690bbSMartin Povišer 		rateval = 4;
2204ac690bbSMartin Povišer 		break;
2214ac690bbSMartin Povišer 	case 48001 ... 63999: /* this is ...72000 but overlaps */
2224ac690bbSMartin Povišer 		rateval = 5;
2234ac690bbSMartin Povišer 		break;
2244ac690bbSMartin Povišer 	default:
2254ac690bbSMartin Povišer 		return -EINVAL;
2264ac690bbSMartin Povišer 	}
2274ac690bbSMartin Povišer 
2284ac690bbSMartin Povišer 	ret = snd_soc_component_update_bits(component,
2294ac690bbSMartin Povišer 			SSM3515_DAC, SSM3515_DAC_FS,
2304ac690bbSMartin Povišer 			FIELD_PREP(SSM3515_DAC_FS, rateval));
2314ac690bbSMartin Povišer 	if (ret < 0)
2324ac690bbSMartin Povišer 		return ret;
2334ac690bbSMartin Povišer 
2344ac690bbSMartin Povišer 	return 0;
2354ac690bbSMartin Povišer }
2364ac690bbSMartin Povišer 
ssm3515_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)2374ac690bbSMartin Povišer static int ssm3515_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
2384ac690bbSMartin Povišer {
2394ac690bbSMartin Povišer 	struct snd_soc_component *component = dai->component;
2404ac690bbSMartin Povišer 	bool fpol_inv = false; /* non-inverted: frame starts with low-to-high FSYNC */
2414ac690bbSMartin Povišer 	int ret;
2424ac690bbSMartin Povišer 	u8 sai1 = 0;
2434ac690bbSMartin Povišer 
2444ac690bbSMartin Povišer 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2454ac690bbSMartin Povišer 	case SND_SOC_DAIFMT_IB_NF:
2464ac690bbSMartin Povišer 	case SND_SOC_DAIFMT_IB_IF:
2474ac690bbSMartin Povišer 		sai1 |= SSM3515_SAI1_BCLK_POL;
2484ac690bbSMartin Povišer 		break;
2494ac690bbSMartin Povišer 	}
2504ac690bbSMartin Povišer 
2514ac690bbSMartin Povišer 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
2524ac690bbSMartin Povišer 	case SND_SOC_DAIFMT_I2S:
2534ac690bbSMartin Povišer 		fpol_inv = 1;
2544ac690bbSMartin Povišer 		sai1 &= ~SSM3515_SAI1_SDATA_FMT; /* 1 bit start delay */
2554ac690bbSMartin Povišer 		break;
2564ac690bbSMartin Povišer 	case SND_SOC_DAIFMT_LEFT_J:
2574ac690bbSMartin Povišer 		fpol_inv = 0;
2584ac690bbSMartin Povišer 		sai1 |= SSM3515_SAI1_SDATA_FMT; /* no start delay */
2594ac690bbSMartin Povišer 		break;
2604ac690bbSMartin Povišer 	default:
2614ac690bbSMartin Povišer 		return -EINVAL;
2624ac690bbSMartin Povišer 	}
2634ac690bbSMartin Povišer 
2644ac690bbSMartin Povišer 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
2654ac690bbSMartin Povišer 	case SND_SOC_DAIFMT_NB_IF:
2664ac690bbSMartin Povišer 	case SND_SOC_DAIFMT_IB_IF:
2674ac690bbSMartin Povišer 		fpol_inv ^= 1;
2684ac690bbSMartin Povišer 		break;
2694ac690bbSMartin Povišer 	}
2704ac690bbSMartin Povišer 
2714ac690bbSMartin Povišer 	/* Set the serial input to 'TDM mode' */
2724ac690bbSMartin Povišer 	sai1 |= SSM3515_SAI1_SAI_MODE;
2734ac690bbSMartin Povišer 
2744ac690bbSMartin Povišer 	if (fpol_inv) {
2754ac690bbSMartin Povišer 		/*
2764ac690bbSMartin Povišer 		 * We configure the codec in a 'TDM mode', in which the
2774ac690bbSMartin Povišer 		 * FSYNC_MODE bit of SAI1 is supposed to select between
2784ac690bbSMartin Povišer 		 * what the datasheet calls 'Pulsed FSYNC mode' and '50%
2794ac690bbSMartin Povišer 		 * FSYNC mode'.
2804ac690bbSMartin Povišer 		 *
2814ac690bbSMartin Povišer 		 * Experiments suggest that this bit in fact simply selects
2824ac690bbSMartin Povišer 		 * the FSYNC polarity, so go with that.
2834ac690bbSMartin Povišer 		 */
2844ac690bbSMartin Povišer 		sai1 |= SSM3515_SAI1_FSYNC_MODE;
2854ac690bbSMartin Povišer 	}
2864ac690bbSMartin Povišer 
2874ac690bbSMartin Povišer 	ret = snd_soc_component_update_bits(component, SSM3515_SAI1,
2884ac690bbSMartin Povišer 			SSM3515_SAI1_BCLK_POL | SSM3515_SAI1_SDATA_FMT |
2894ac690bbSMartin Povišer 			SSM3515_SAI1_SAI_MODE | SSM3515_SAI1_FSYNC_MODE, sai1);
2904ac690bbSMartin Povišer 
2914ac690bbSMartin Povišer 	if (ret < 0)
2924ac690bbSMartin Povišer 		return ret;
2934ac690bbSMartin Povišer 	return 0;
2944ac690bbSMartin Povišer }
2954ac690bbSMartin Povišer 
ssm3515_set_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)2964ac690bbSMartin Povišer static int ssm3515_set_tdm_slot(struct snd_soc_dai *dai,
2974ac690bbSMartin Povišer 				unsigned int tx_mask,
2984ac690bbSMartin Povišer 				unsigned int rx_mask,
2994ac690bbSMartin Povišer 				int slots, int slot_width)
3004ac690bbSMartin Povišer {
3014ac690bbSMartin Povišer 	struct snd_soc_component *component = dai->component;
3024ac690bbSMartin Povišer 	int slot, tdm_bclks_val, ret;
3034ac690bbSMartin Povišer 
3044ac690bbSMartin Povišer 	if (tx_mask == 0 || rx_mask != 0)
3054ac690bbSMartin Povišer 		return -EINVAL;
3064ac690bbSMartin Povišer 
3074ac690bbSMartin Povišer 	slot = __ffs(tx_mask);
3084ac690bbSMartin Povišer 
3094ac690bbSMartin Povišer 	if (tx_mask & ~BIT(slot))
3104ac690bbSMartin Povišer 		return -EINVAL;
3114ac690bbSMartin Povišer 
3124ac690bbSMartin Povišer 	switch (slot_width) {
3134ac690bbSMartin Povišer 	case 16:
3144ac690bbSMartin Povišer 		tdm_bclks_val = 0;
3154ac690bbSMartin Povišer 		break;
3164ac690bbSMartin Povišer 	case 24:
3174ac690bbSMartin Povišer 		tdm_bclks_val = 1;
3184ac690bbSMartin Povišer 		break;
3194ac690bbSMartin Povišer 	case 32:
3204ac690bbSMartin Povišer 		tdm_bclks_val = 2;
3214ac690bbSMartin Povišer 		break;
3224ac690bbSMartin Povišer 	case 48:
3234ac690bbSMartin Povišer 		tdm_bclks_val = 3;
3244ac690bbSMartin Povišer 		break;
3254ac690bbSMartin Povišer 	case 64:
3264ac690bbSMartin Povišer 		tdm_bclks_val = 4;
3274ac690bbSMartin Povišer 		break;
3284ac690bbSMartin Povišer 	default:
3294ac690bbSMartin Povišer 		return -EINVAL;
3304ac690bbSMartin Povišer 	}
3314ac690bbSMartin Povišer 
3324ac690bbSMartin Povišer 	ret = snd_soc_component_update_bits(component, SSM3515_SAI1,
3334ac690bbSMartin Povišer 			SSM3515_SAI1_TDM_BCLKS,
3344ac690bbSMartin Povišer 			FIELD_PREP(SSM3515_SAI1_TDM_BCLKS, tdm_bclks_val));
3354ac690bbSMartin Povišer 	if (ret < 0)
3364ac690bbSMartin Povišer 		return ret;
3374ac690bbSMartin Povišer 
3384ac690bbSMartin Povišer 	ret = snd_soc_component_update_bits(component, SSM3515_SAI2,
3394ac690bbSMartin Povišer 			SSM3515_SAI2_TDM_SLOT,
3404ac690bbSMartin Povišer 			FIELD_PREP(SSM3515_SAI2_TDM_SLOT, slot));
3414ac690bbSMartin Povišer 	if (ret < 0)
3424ac690bbSMartin Povišer 		return ret;
3434ac690bbSMartin Povišer 
3444ac690bbSMartin Povišer 	return 0;
3454ac690bbSMartin Povišer }
3464ac690bbSMartin Povišer 
ssm3515_hw_free(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)3474ac690bbSMartin Povišer static int ssm3515_hw_free(struct snd_pcm_substream *substream,
3484ac690bbSMartin Povišer 			   struct snd_soc_dai *dai)
3494ac690bbSMartin Povišer {
3504ac690bbSMartin Povišer 	/*
3514ac690bbSMartin Povišer 	 * We don't get live notification of faults, so at least at
3524ac690bbSMartin Povišer 	 * this time, when playback is over, check if we have tripped
3534ac690bbSMartin Povišer 	 * over anything and if so, log it.
3544ac690bbSMartin Povišer 	 */
3554ac690bbSMartin Povišer 	ssm3515_read_faults(dai->component);
3564ac690bbSMartin Povišer 	return 0;
3574ac690bbSMartin Povišer }
3584ac690bbSMartin Povišer 
3594ac690bbSMartin Povišer static const struct snd_soc_dai_ops ssm3515_dai_ops = {
3604ac690bbSMartin Povišer 	.mute_stream	= ssm3515_mute,
3614ac690bbSMartin Povišer 	.hw_params	= ssm3515_hw_params,
3624ac690bbSMartin Povišer 	.set_fmt	= ssm3515_set_fmt,
3634ac690bbSMartin Povišer 	.set_tdm_slot	= ssm3515_set_tdm_slot,
3644ac690bbSMartin Povišer 	.hw_free	= ssm3515_hw_free,
3654ac690bbSMartin Povišer };
3664ac690bbSMartin Povišer 
3674ac690bbSMartin Povišer static struct snd_soc_dai_driver ssm3515_dai_driver = {
3684ac690bbSMartin Povišer 	.name = "SSM3515 SAI",
3694ac690bbSMartin Povišer 	.id = 0,
3704ac690bbSMartin Povišer 	.playback = {
3714ac690bbSMartin Povišer 		.stream_name = "Playback",
3724ac690bbSMartin Povišer 		.channels_min = 1,
3734ac690bbSMartin Povišer 		.channels_max = 1,
3744ac690bbSMartin Povišer 		.rates = SNDRV_PCM_RATE_CONTINUOUS,
3754ac690bbSMartin Povišer 		.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
3764ac690bbSMartin Povišer 	},
3774ac690bbSMartin Povišer 	.ops = &ssm3515_dai_ops,
3784ac690bbSMartin Povišer };
3794ac690bbSMartin Povišer 
3804ac690bbSMartin Povišer static const struct snd_soc_dapm_widget ssm3515_dapm_widgets[] = {
3814ac690bbSMartin Povišer 	SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
3824ac690bbSMartin Povišer 	SND_SOC_DAPM_OUTPUT("OUT"),
3834ac690bbSMartin Povišer };
3844ac690bbSMartin Povišer 
3854ac690bbSMartin Povišer static const struct snd_soc_dapm_route ssm3515_dapm_routes[] = {
3864ac690bbSMartin Povišer 	{"OUT", NULL, "DAC"},
3874ac690bbSMartin Povišer 	{"DAC", NULL, "Playback"},
3884ac690bbSMartin Povišer };
3894ac690bbSMartin Povišer 
3904ac690bbSMartin Povišer static const struct snd_soc_component_driver ssm3515_asoc_component = {
3914ac690bbSMartin Povišer 	.probe = ssm3515_probe,
3924ac690bbSMartin Povišer 	.controls = ssm3515_snd_controls,
3934ac690bbSMartin Povišer 	.num_controls = ARRAY_SIZE(ssm3515_snd_controls),
3944ac690bbSMartin Povišer 	.dapm_widgets = ssm3515_dapm_widgets,
3954ac690bbSMartin Povišer 	.num_dapm_widgets = ARRAY_SIZE(ssm3515_dapm_widgets),
3964ac690bbSMartin Povišer 	.dapm_routes = ssm3515_dapm_routes,
3974ac690bbSMartin Povišer 	.num_dapm_routes = ARRAY_SIZE(ssm3515_dapm_routes),
3984ac690bbSMartin Povišer 	.endianness = 1,
3994ac690bbSMartin Povišer };
4004ac690bbSMartin Povišer 
ssm3515_i2c_probe(struct i2c_client * client)4014ac690bbSMartin Povišer static int ssm3515_i2c_probe(struct i2c_client *client)
4024ac690bbSMartin Povišer {
4034ac690bbSMartin Povišer 	struct ssm3515_data *data;
4044ac690bbSMartin Povišer 	int ret;
4054ac690bbSMartin Povišer 
4064ac690bbSMartin Povišer 	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
4074ac690bbSMartin Povišer 	if (!data)
4084ac690bbSMartin Povišer 		return -ENOMEM;
4094ac690bbSMartin Povišer 
4104ac690bbSMartin Povišer 	data->dev = &client->dev;
4114ac690bbSMartin Povišer 	i2c_set_clientdata(client, data);
4124ac690bbSMartin Povišer 
4134ac690bbSMartin Povišer 	data->regmap = devm_regmap_init_i2c(client, &ssm3515_i2c_regmap);
4144ac690bbSMartin Povišer 	if (IS_ERR(data->regmap))
4154ac690bbSMartin Povišer 		return dev_err_probe(data->dev, PTR_ERR(data->regmap),
4164ac690bbSMartin Povišer 				     "initializing register map\n");
4174ac690bbSMartin Povišer 
4184ac690bbSMartin Povišer 	/* Perform a reset */
4194ac690bbSMartin Povišer 	ret = regmap_update_bits(data->regmap, SSM3515_PWR,
4204ac690bbSMartin Povišer 			SSM3515_PWR_S_RST, SSM3515_PWR_S_RST);
4214ac690bbSMartin Povišer 	if (ret < 0)
4224ac690bbSMartin Povišer 		return dev_err_probe(data->dev, ret,
4234ac690bbSMartin Povišer 				     "performing software reset\n");
4244ac690bbSMartin Povišer 	regmap_reinit_cache(data->regmap, &ssm3515_i2c_regmap);
4254ac690bbSMartin Povišer 
4264ac690bbSMartin Povišer 	return devm_snd_soc_register_component(data->dev,
4274ac690bbSMartin Povišer 			&ssm3515_asoc_component,
4284ac690bbSMartin Povišer 			&ssm3515_dai_driver, 1);
4294ac690bbSMartin Povišer }
4304ac690bbSMartin Povišer 
4314ac690bbSMartin Povišer static const struct of_device_id ssm3515_of_match[] = {
4324ac690bbSMartin Povišer 	{ .compatible = "adi,ssm3515" },
4334ac690bbSMartin Povišer 	{}
4344ac690bbSMartin Povišer };
4354ac690bbSMartin Povišer MODULE_DEVICE_TABLE(of, ssm3515_of_match);
4364ac690bbSMartin Povišer 
4374ac690bbSMartin Povišer static struct i2c_driver ssm3515_i2c_driver = {
4384ac690bbSMartin Povišer 	.driver = {
4394ac690bbSMartin Povišer 		.name = "ssm3515",
440*6136b6a2SRuan Jinjie 		.of_match_table = ssm3515_of_match,
4414ac690bbSMartin Povišer 	},
442947e3960SUwe Kleine-König 	.probe = ssm3515_i2c_probe,
4434ac690bbSMartin Povišer };
4444ac690bbSMartin Povišer module_i2c_driver(ssm3515_i2c_driver);
4454ac690bbSMartin Povišer 
4464ac690bbSMartin Povišer MODULE_AUTHOR("Martin Povišer <povik+lin@cutebit.org>");
4474ac690bbSMartin Povišer MODULE_DESCRIPTION("ASoC SSM3515 audio amp driver");
4484ac690bbSMartin Povišer MODULE_LICENSE("Dual MIT/GPL");
449