xref: /openbmc/linux/sound/soc/codecs/ssm2518.c (revision 9abcd240)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * SSM2518 amplifier audio driver
4  *
5  * Copyright 2013 Analog Devices Inc.
6  *  Author: Lars-Peter Clausen <lars@metafoo.de>
7  */
8 
9 #include <linux/err.h>
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/i2c.h>
13 #include <linux/regmap.h>
14 #include <linux/slab.h>
15 #include <linux/gpio/consumer.h>
16 #include <sound/core.h>
17 #include <sound/pcm.h>
18 #include <sound/pcm_params.h>
19 #include <sound/soc.h>
20 #include <sound/initval.h>
21 #include <sound/tlv.h>
22 
23 #include "ssm2518.h"
24 
25 #define SSM2518_REG_POWER1		0x00
26 #define SSM2518_REG_CLOCK		0x01
27 #define SSM2518_REG_SAI_CTRL1		0x02
28 #define SSM2518_REG_SAI_CTRL2		0x03
29 #define SSM2518_REG_CHAN_MAP		0x04
30 #define SSM2518_REG_LEFT_VOL		0x05
31 #define SSM2518_REG_RIGHT_VOL		0x06
32 #define SSM2518_REG_MUTE_CTRL		0x07
33 #define SSM2518_REG_FAULT_CTRL		0x08
34 #define SSM2518_REG_POWER2		0x09
35 #define SSM2518_REG_DRC_1		0x0a
36 #define SSM2518_REG_DRC_2		0x0b
37 #define SSM2518_REG_DRC_3		0x0c
38 #define SSM2518_REG_DRC_4		0x0d
39 #define SSM2518_REG_DRC_5		0x0e
40 #define SSM2518_REG_DRC_6		0x0f
41 #define SSM2518_REG_DRC_7		0x10
42 #define SSM2518_REG_DRC_8		0x11
43 #define SSM2518_REG_DRC_9		0x12
44 
45 #define SSM2518_POWER1_RESET			BIT(7)
46 #define SSM2518_POWER1_NO_BCLK			BIT(5)
47 #define SSM2518_POWER1_MCS_MASK			(0xf << 1)
48 #define SSM2518_POWER1_MCS_64FS			(0x0 << 1)
49 #define SSM2518_POWER1_MCS_128FS		(0x1 << 1)
50 #define SSM2518_POWER1_MCS_256FS		(0x2 << 1)
51 #define SSM2518_POWER1_MCS_384FS		(0x3 << 1)
52 #define SSM2518_POWER1_MCS_512FS		(0x4 << 1)
53 #define SSM2518_POWER1_MCS_768FS		(0x5 << 1)
54 #define SSM2518_POWER1_MCS_100FS		(0x6 << 1)
55 #define SSM2518_POWER1_MCS_200FS		(0x7 << 1)
56 #define SSM2518_POWER1_MCS_400FS		(0x8 << 1)
57 #define SSM2518_POWER1_SPWDN			BIT(0)
58 
59 #define SSM2518_CLOCK_ASR			BIT(0)
60 
61 #define SSM2518_SAI_CTRL1_FMT_MASK		(0x3 << 5)
62 #define SSM2518_SAI_CTRL1_FMT_I2S		(0x0 << 5)
63 #define SSM2518_SAI_CTRL1_FMT_LJ		(0x1 << 5)
64 #define SSM2518_SAI_CTRL1_FMT_RJ_24BIT		(0x2 << 5)
65 #define SSM2518_SAI_CTRL1_FMT_RJ_16BIT		(0x3 << 5)
66 
67 #define SSM2518_SAI_CTRL1_SAI_MASK		(0x7 << 2)
68 #define SSM2518_SAI_CTRL1_SAI_I2S		(0x0 << 2)
69 #define SSM2518_SAI_CTRL1_SAI_TDM_2		(0x1 << 2)
70 #define SSM2518_SAI_CTRL1_SAI_TDM_4		(0x2 << 2)
71 #define SSM2518_SAI_CTRL1_SAI_TDM_8		(0x3 << 2)
72 #define SSM2518_SAI_CTRL1_SAI_TDM_16		(0x4 << 2)
73 #define SSM2518_SAI_CTRL1_SAI_MONO		(0x5 << 2)
74 
75 #define SSM2518_SAI_CTRL1_FS_MASK		(0x3)
76 #define SSM2518_SAI_CTRL1_FS_8000_12000		(0x0)
77 #define SSM2518_SAI_CTRL1_FS_16000_24000	(0x1)
78 #define SSM2518_SAI_CTRL1_FS_32000_48000	(0x2)
79 #define SSM2518_SAI_CTRL1_FS_64000_96000	(0x3)
80 
81 #define SSM2518_SAI_CTRL2_BCLK_INTERAL		BIT(7)
82 #define SSM2518_SAI_CTRL2_LRCLK_PULSE		BIT(6)
83 #define SSM2518_SAI_CTRL2_LRCLK_INVERT		BIT(5)
84 #define SSM2518_SAI_CTRL2_MSB			BIT(4)
85 #define SSM2518_SAI_CTRL2_SLOT_WIDTH_MASK	(0x3 << 2)
86 #define SSM2518_SAI_CTRL2_SLOT_WIDTH_32		(0x0 << 2)
87 #define SSM2518_SAI_CTRL2_SLOT_WIDTH_24		(0x1 << 2)
88 #define SSM2518_SAI_CTRL2_SLOT_WIDTH_16		(0x2 << 2)
89 #define SSM2518_SAI_CTRL2_BCLK_INVERT		BIT(1)
90 
91 #define SSM2518_CHAN_MAP_RIGHT_SLOT_OFFSET	4
92 #define SSM2518_CHAN_MAP_RIGHT_SLOT_MASK	0xf0
93 #define SSM2518_CHAN_MAP_LEFT_SLOT_OFFSET	0
94 #define SSM2518_CHAN_MAP_LEFT_SLOT_MASK		0x0f
95 
96 #define SSM2518_MUTE_CTRL_ANA_GAIN		BIT(5)
97 #define SSM2518_MUTE_CTRL_MUTE_MASTER		BIT(0)
98 
99 #define SSM2518_POWER2_APWDN			BIT(0)
100 
101 #define SSM2518_DAC_MUTE			BIT(6)
102 #define SSM2518_DAC_FS_MASK			0x07
103 #define SSM2518_DAC_FS_8000			0x00
104 #define SSM2518_DAC_FS_16000			0x01
105 #define SSM2518_DAC_FS_32000			0x02
106 #define SSM2518_DAC_FS_64000			0x03
107 #define SSM2518_DAC_FS_128000			0x04
108 
109 struct ssm2518 {
110 	struct regmap *regmap;
111 	bool right_j;
112 
113 	unsigned int sysclk;
114 	const struct snd_pcm_hw_constraint_list *constraints;
115 
116 	struct gpio_desc *enable_gpio;
117 };
118 
119 static const struct reg_default ssm2518_reg_defaults[] = {
120 	{ 0x00, 0x05 },
121 	{ 0x01, 0x00 },
122 	{ 0x02, 0x02 },
123 	{ 0x03, 0x00 },
124 	{ 0x04, 0x10 },
125 	{ 0x05, 0x40 },
126 	{ 0x06, 0x40 },
127 	{ 0x07, 0x81 },
128 	{ 0x08, 0x0c },
129 	{ 0x09, 0x99 },
130 	{ 0x0a, 0x7c },
131 	{ 0x0b, 0x5b },
132 	{ 0x0c, 0x57 },
133 	{ 0x0d, 0x89 },
134 	{ 0x0e, 0x8c },
135 	{ 0x0f, 0x77 },
136 	{ 0x10, 0x26 },
137 	{ 0x11, 0x1c },
138 	{ 0x12, 0x97 },
139 };
140 
141 static const DECLARE_TLV_DB_MINMAX_MUTE(ssm2518_vol_tlv, -7125, 2400);
142 static const DECLARE_TLV_DB_SCALE(ssm2518_compressor_tlv, -3400, 200, 0);
143 static const DECLARE_TLV_DB_SCALE(ssm2518_expander_tlv, -8100, 300, 0);
144 static const DECLARE_TLV_DB_SCALE(ssm2518_noise_gate_tlv, -9600, 300, 0);
145 static const DECLARE_TLV_DB_SCALE(ssm2518_post_drc_tlv, -2400, 300, 0);
146 
147 static const DECLARE_TLV_DB_RANGE(ssm2518_limiter_tlv,
148 	0, 7, TLV_DB_SCALE_ITEM(-2200, 200, 0),
149 	7, 15, TLV_DB_SCALE_ITEM(-800, 100, 0),
150 );
151 
152 static const char * const ssm2518_drc_peak_detector_attack_time_text[] = {
153 	"0 ms", "0.1 ms", "0.19 ms", "0.37 ms", "0.75 ms", "1.5 ms", "3 ms",
154 	"6 ms", "12 ms", "24 ms", "48 ms", "96 ms", "192 ms", "384 ms",
155 	"768 ms", "1536 ms",
156 };
157 
158 static const char * const ssm2518_drc_peak_detector_release_time_text[] = {
159 	"0 ms", "1.5 ms", "3 ms", "6 ms", "12 ms", "24 ms", "48 ms", "96 ms",
160 	"192 ms", "384 ms", "768 ms", "1536 ms", "3072 ms", "6144 ms",
161 	"12288 ms", "24576 ms"
162 };
163 
164 static const char * const ssm2518_drc_hold_time_text[] = {
165 	"0 ms", "0.67 ms", "1.33 ms", "2.67 ms", "5.33 ms", "10.66 ms",
166 	"21.32 ms", "42.64 ms", "85.28 ms", "170.56 ms", "341.12 ms",
167 	"682.24 ms", "1364 ms",
168 };
169 
170 static SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_attack_time_enum,
171 	SSM2518_REG_DRC_2, 4, ssm2518_drc_peak_detector_attack_time_text);
172 static SOC_ENUM_SINGLE_DECL(ssm2518_drc_peak_detector_release_time_enum,
173 	SSM2518_REG_DRC_2, 0, ssm2518_drc_peak_detector_release_time_text);
174 static SOC_ENUM_SINGLE_DECL(ssm2518_drc_attack_time_enum,
175 	SSM2518_REG_DRC_6, 4, ssm2518_drc_peak_detector_attack_time_text);
176 static SOC_ENUM_SINGLE_DECL(ssm2518_drc_decay_time_enum,
177 	SSM2518_REG_DRC_6, 0, ssm2518_drc_peak_detector_release_time_text);
178 static SOC_ENUM_SINGLE_DECL(ssm2518_drc_hold_time_enum,
179 	SSM2518_REG_DRC_7, 4, ssm2518_drc_hold_time_text);
180 static SOC_ENUM_SINGLE_DECL(ssm2518_drc_noise_gate_hold_time_enum,
181 	SSM2518_REG_DRC_7, 0, ssm2518_drc_hold_time_text);
182 static SOC_ENUM_SINGLE_DECL(ssm2518_drc_rms_averaging_time_enum,
183 	SSM2518_REG_DRC_9, 0, ssm2518_drc_peak_detector_release_time_text);
184 
185 static const struct snd_kcontrol_new ssm2518_snd_controls[] = {
186 	SOC_SINGLE("Playback De-emphasis Switch", SSM2518_REG_MUTE_CTRL,
187 			4, 1, 0),
188 	SOC_DOUBLE_R_TLV("Master Playback Volume", SSM2518_REG_LEFT_VOL,
189 			SSM2518_REG_RIGHT_VOL, 0, 0xff, 1, ssm2518_vol_tlv),
190 	SOC_DOUBLE("Master Playback Switch", SSM2518_REG_MUTE_CTRL, 2, 1, 1, 1),
191 
192 	SOC_SINGLE("Amp Low Power Mode Switch", SSM2518_REG_POWER2, 4, 1, 0),
193 	SOC_SINGLE("DAC Low Power Mode Switch", SSM2518_REG_POWER2, 3, 1, 0),
194 
195 	SOC_SINGLE("DRC Limiter Switch", SSM2518_REG_DRC_1, 5, 1, 0),
196 	SOC_SINGLE("DRC Compressor Switch", SSM2518_REG_DRC_1, 4, 1, 0),
197 	SOC_SINGLE("DRC Expander Switch", SSM2518_REG_DRC_1, 3, 1, 0),
198 	SOC_SINGLE("DRC Noise Gate Switch", SSM2518_REG_DRC_1, 2, 1, 0),
199 	SOC_DOUBLE("DRC Switch", SSM2518_REG_DRC_1, 0, 1, 1, 0),
200 
201 	SOC_SINGLE_TLV("DRC Limiter Threshold Volume",
202 			SSM2518_REG_DRC_3, 4, 15, 1, ssm2518_limiter_tlv),
203 	SOC_SINGLE_TLV("DRC Compressor Lower Threshold Volume",
204 			SSM2518_REG_DRC_3, 0, 15, 1, ssm2518_compressor_tlv),
205 	SOC_SINGLE_TLV("DRC Expander Upper Threshold Volume", SSM2518_REG_DRC_4,
206 			4, 15, 1, ssm2518_expander_tlv),
207 	SOC_SINGLE_TLV("DRC Noise Gate Threshold Volume",
208 			SSM2518_REG_DRC_4, 0, 15, 1, ssm2518_noise_gate_tlv),
209 	SOC_SINGLE_TLV("DRC Upper Output Threshold Volume",
210 			SSM2518_REG_DRC_5, 4, 15, 1, ssm2518_limiter_tlv),
211 	SOC_SINGLE_TLV("DRC Lower Output Threshold Volume",
212 			SSM2518_REG_DRC_5, 0, 15, 1, ssm2518_noise_gate_tlv),
213 	SOC_SINGLE_TLV("DRC Post Volume", SSM2518_REG_DRC_8,
214 			2, 15, 1, ssm2518_post_drc_tlv),
215 
216 	SOC_ENUM("DRC Peak Detector Attack Time",
217 		ssm2518_drc_peak_detector_attack_time_enum),
218 	SOC_ENUM("DRC Peak Detector Release Time",
219 		ssm2518_drc_peak_detector_release_time_enum),
220 	SOC_ENUM("DRC Attack Time", ssm2518_drc_attack_time_enum),
221 	SOC_ENUM("DRC Decay Time", ssm2518_drc_decay_time_enum),
222 	SOC_ENUM("DRC Hold Time", ssm2518_drc_hold_time_enum),
223 	SOC_ENUM("DRC Noise Gate Hold Time",
224 		ssm2518_drc_noise_gate_hold_time_enum),
225 	SOC_ENUM("DRC RMS Averaging Time", ssm2518_drc_rms_averaging_time_enum),
226 };
227 
228 static const struct snd_soc_dapm_widget ssm2518_dapm_widgets[] = {
229 	SND_SOC_DAPM_DAC("DACL", "HiFi Playback", SSM2518_REG_POWER2, 1, 1),
230 	SND_SOC_DAPM_DAC("DACR", "HiFi Playback", SSM2518_REG_POWER2, 2, 1),
231 
232 	SND_SOC_DAPM_OUTPUT("OUTL"),
233 	SND_SOC_DAPM_OUTPUT("OUTR"),
234 };
235 
236 static const struct snd_soc_dapm_route ssm2518_routes[] = {
237 	{ "OUTL", NULL, "DACL" },
238 	{ "OUTR", NULL, "DACR" },
239 };
240 
241 struct ssm2518_mcs_lut {
242 	unsigned int rate;
243 	const unsigned int *sysclks;
244 };
245 
246 static const unsigned int ssm2518_sysclks_2048000[] = {
247 	2048000, 4096000, 8192000, 12288000, 16384000, 24576000,
248 	3200000, 6400000, 12800000, 0
249 };
250 
251 static const unsigned int ssm2518_sysclks_2822000[] = {
252 	2822000, 5644800, 11289600, 16934400, 22579200, 33868800,
253 	4410000, 8820000, 17640000, 0
254 };
255 
256 static const unsigned int ssm2518_sysclks_3072000[] = {
257 	3072000, 6144000, 12288000, 16384000, 24576000, 38864000,
258 	4800000, 9600000, 19200000, 0
259 };
260 
261 static const struct ssm2518_mcs_lut ssm2518_mcs_lut[] = {
262 	{ 8000,  ssm2518_sysclks_2048000, },
263 	{ 11025, ssm2518_sysclks_2822000, },
264 	{ 12000, ssm2518_sysclks_3072000, },
265 	{ 16000, ssm2518_sysclks_2048000, },
266 	{ 24000, ssm2518_sysclks_3072000, },
267 	{ 22050, ssm2518_sysclks_2822000, },
268 	{ 32000, ssm2518_sysclks_2048000, },
269 	{ 44100, ssm2518_sysclks_2822000, },
270 	{ 48000, ssm2518_sysclks_3072000, },
271 	{ 96000, ssm2518_sysclks_3072000, },
272 };
273 
274 static const unsigned int ssm2518_rates_2048000[] = {
275 	8000, 16000, 32000,
276 };
277 
278 static const struct snd_pcm_hw_constraint_list ssm2518_constraints_2048000 = {
279 	.list = ssm2518_rates_2048000,
280 	.count = ARRAY_SIZE(ssm2518_rates_2048000),
281 };
282 
283 static const unsigned int ssm2518_rates_2822000[] = {
284 	11025, 22050, 44100,
285 };
286 
287 static const struct snd_pcm_hw_constraint_list ssm2518_constraints_2822000 = {
288 	.list = ssm2518_rates_2822000,
289 	.count = ARRAY_SIZE(ssm2518_rates_2822000),
290 };
291 
292 static const unsigned int ssm2518_rates_3072000[] = {
293 	12000, 24000, 48000, 96000,
294 };
295 
296 static const struct snd_pcm_hw_constraint_list ssm2518_constraints_3072000 = {
297 	.list = ssm2518_rates_3072000,
298 	.count = ARRAY_SIZE(ssm2518_rates_3072000),
299 };
300 
301 static const unsigned int ssm2518_rates_12288000[] = {
302 	8000, 12000, 16000, 24000, 32000, 48000, 96000,
303 };
304 
305 static const struct snd_pcm_hw_constraint_list ssm2518_constraints_12288000 = {
306 	.list = ssm2518_rates_12288000,
307 	.count = ARRAY_SIZE(ssm2518_rates_12288000),
308 };
309 
ssm2518_lookup_mcs(struct ssm2518 * ssm2518,unsigned int rate)310 static int ssm2518_lookup_mcs(struct ssm2518 *ssm2518,
311 	unsigned int rate)
312 {
313 	const unsigned int *sysclks = NULL;
314 	int i;
315 
316 	for (i = 0; i < ARRAY_SIZE(ssm2518_mcs_lut); i++) {
317 		if (ssm2518_mcs_lut[i].rate == rate) {
318 			sysclks = ssm2518_mcs_lut[i].sysclks;
319 			break;
320 		}
321 	}
322 
323 	if (!sysclks)
324 		return -EINVAL;
325 
326 	for (i = 0; sysclks[i]; i++) {
327 		if (sysclks[i] == ssm2518->sysclk)
328 			return i;
329 	}
330 
331 	return -EINVAL;
332 }
333 
ssm2518_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)334 static int ssm2518_hw_params(struct snd_pcm_substream *substream,
335 	struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
336 {
337 	struct snd_soc_component *component = dai->component;
338 	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
339 	unsigned int rate = params_rate(params);
340 	unsigned int ctrl1, ctrl1_mask;
341 	int mcs;
342 	int ret;
343 
344 	mcs = ssm2518_lookup_mcs(ssm2518, rate);
345 	if (mcs < 0)
346 		return mcs;
347 
348 	ctrl1_mask = SSM2518_SAI_CTRL1_FS_MASK;
349 
350 	if (rate >= 8000 && rate <= 12000)
351 		ctrl1 = SSM2518_SAI_CTRL1_FS_8000_12000;
352 	else if (rate >= 16000 && rate <= 24000)
353 		ctrl1 = SSM2518_SAI_CTRL1_FS_16000_24000;
354 	else if (rate >= 32000 && rate <= 48000)
355 		ctrl1 = SSM2518_SAI_CTRL1_FS_32000_48000;
356 	else if (rate >= 64000 && rate <= 96000)
357 		ctrl1 = SSM2518_SAI_CTRL1_FS_64000_96000;
358 	else
359 		return -EINVAL;
360 
361 	if (ssm2518->right_j) {
362 		switch (params_width(params)) {
363 		case 16:
364 			ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_16BIT;
365 			break;
366 		case 24:
367 			ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_24BIT;
368 			break;
369 		default:
370 			return -EINVAL;
371 		}
372 		ctrl1_mask |= SSM2518_SAI_CTRL1_FMT_MASK;
373 	}
374 
375 	/* Disable auto samplerate detection */
376 	ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_CLOCK,
377 				SSM2518_CLOCK_ASR, SSM2518_CLOCK_ASR);
378 	if (ret < 0)
379 		return ret;
380 
381 	ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL1,
382 				ctrl1_mask, ctrl1);
383 	if (ret < 0)
384 		return ret;
385 
386 	return regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
387 				SSM2518_POWER1_MCS_MASK, mcs << 1);
388 }
389 
ssm2518_mute(struct snd_soc_dai * dai,int mute,int direction)390 static int ssm2518_mute(struct snd_soc_dai *dai, int mute, int direction)
391 {
392 	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
393 	unsigned int val;
394 
395 	if (mute)
396 		val = SSM2518_MUTE_CTRL_MUTE_MASTER;
397 	else
398 		val = 0;
399 
400 	return regmap_update_bits(ssm2518->regmap, SSM2518_REG_MUTE_CTRL,
401 			SSM2518_MUTE_CTRL_MUTE_MASTER, val);
402 }
403 
ssm2518_set_dai_fmt(struct snd_soc_dai * dai,unsigned int fmt)404 static int ssm2518_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
405 {
406 	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
407 	unsigned int ctrl1 = 0, ctrl2 = 0;
408 	bool invert_fclk;
409 	int ret;
410 
411 	switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
412 	case SND_SOC_DAIFMT_CBC_CFC:
413 		break;
414 	default:
415 		return -EINVAL;
416 	}
417 
418 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
419 	case SND_SOC_DAIFMT_NB_NF:
420 		invert_fclk = false;
421 		break;
422 	case SND_SOC_DAIFMT_IB_NF:
423 		ctrl2 |= SSM2518_SAI_CTRL2_BCLK_INVERT;
424 		invert_fclk = false;
425 		break;
426 	case SND_SOC_DAIFMT_NB_IF:
427 		invert_fclk = true;
428 		break;
429 	case SND_SOC_DAIFMT_IB_IF:
430 		ctrl2 |= SSM2518_SAI_CTRL2_BCLK_INVERT;
431 		invert_fclk = true;
432 		break;
433 	default:
434 		return -EINVAL;
435 	}
436 
437 	ssm2518->right_j = false;
438 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
439 	case SND_SOC_DAIFMT_I2S:
440 		ctrl1 |= SSM2518_SAI_CTRL1_FMT_I2S;
441 		break;
442 	case SND_SOC_DAIFMT_LEFT_J:
443 		ctrl1 |= SSM2518_SAI_CTRL1_FMT_LJ;
444 		invert_fclk = !invert_fclk;
445 		break;
446 	case SND_SOC_DAIFMT_RIGHT_J:
447 		ctrl1 |= SSM2518_SAI_CTRL1_FMT_RJ_24BIT;
448 		ssm2518->right_j = true;
449 		invert_fclk = !invert_fclk;
450 		break;
451 	case SND_SOC_DAIFMT_DSP_A:
452 		ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_PULSE;
453 		ctrl1 |= SSM2518_SAI_CTRL1_FMT_I2S;
454 		invert_fclk = false;
455 		break;
456 	case SND_SOC_DAIFMT_DSP_B:
457 		ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_PULSE;
458 		ctrl1 |= SSM2518_SAI_CTRL1_FMT_LJ;
459 		invert_fclk = false;
460 		break;
461 	default:
462 		return -EINVAL;
463 	}
464 
465 	if (invert_fclk)
466 		ctrl2 |= SSM2518_SAI_CTRL2_LRCLK_INVERT;
467 
468 	ret = regmap_write(ssm2518->regmap, SSM2518_REG_SAI_CTRL1, ctrl1);
469 	if (ret)
470 		return ret;
471 
472 	return regmap_write(ssm2518->regmap, SSM2518_REG_SAI_CTRL2, ctrl2);
473 }
474 
ssm2518_set_power(struct ssm2518 * ssm2518,bool enable)475 static int ssm2518_set_power(struct ssm2518 *ssm2518, bool enable)
476 {
477 	int ret = 0;
478 
479 	if (!enable) {
480 		ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
481 			SSM2518_POWER1_SPWDN, SSM2518_POWER1_SPWDN);
482 		regcache_mark_dirty(ssm2518->regmap);
483 	}
484 
485 	if (ssm2518->enable_gpio)
486 		gpiod_set_value_cansleep(ssm2518->enable_gpio, enable);
487 
488 	regcache_cache_only(ssm2518->regmap, !enable);
489 
490 	if (enable) {
491 		ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
492 			SSM2518_POWER1_SPWDN | SSM2518_POWER1_RESET, 0x00);
493 		regcache_sync(ssm2518->regmap);
494 	}
495 
496 	return ret;
497 }
498 
ssm2518_set_bias_level(struct snd_soc_component * component,enum snd_soc_bias_level level)499 static int ssm2518_set_bias_level(struct snd_soc_component *component,
500 	enum snd_soc_bias_level level)
501 {
502 	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
503 	int ret = 0;
504 
505 	switch (level) {
506 	case SND_SOC_BIAS_ON:
507 		break;
508 	case SND_SOC_BIAS_PREPARE:
509 		break;
510 	case SND_SOC_BIAS_STANDBY:
511 		if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF)
512 			ret = ssm2518_set_power(ssm2518, true);
513 		break;
514 	case SND_SOC_BIAS_OFF:
515 		ret = ssm2518_set_power(ssm2518, false);
516 		break;
517 	}
518 
519 	return ret;
520 }
521 
ssm2518_set_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int width)522 static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
523 	unsigned int rx_mask, int slots, int width)
524 {
525 	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
526 	unsigned int ctrl1, ctrl2;
527 	int left_slot, right_slot;
528 	int ret;
529 
530 	if (slots == 0)
531 		return regmap_update_bits(ssm2518->regmap,
532 			SSM2518_REG_SAI_CTRL1, SSM2518_SAI_CTRL1_SAI_MASK,
533 			SSM2518_SAI_CTRL1_SAI_I2S);
534 
535 	if (tx_mask == 0 || rx_mask != 0)
536 		return -EINVAL;
537 
538 	if (slots == 1) {
539 		if (tx_mask != 1)
540 			return -EINVAL;
541 		left_slot = 0;
542 		right_slot = 0;
543 	} else {
544 		/* We assume the left channel < right channel */
545 		left_slot = __ffs(tx_mask);
546 		tx_mask &= ~(1 << left_slot);
547 		if (tx_mask == 0) {
548 			right_slot = left_slot;
549 		} else {
550 			right_slot = __ffs(tx_mask);
551 			tx_mask &= ~(1 << right_slot);
552 		}
553 	}
554 
555 	if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
556 		return -EINVAL;
557 
558 	switch (width) {
559 	case 16:
560 		ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_16;
561 		break;
562 	case 24:
563 		ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_24;
564 		break;
565 	case 32:
566 		ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_32;
567 		break;
568 	default:
569 		return -EINVAL;
570 	}
571 
572 	switch (slots) {
573 	case 1:
574 		ctrl1 = SSM2518_SAI_CTRL1_SAI_MONO;
575 		break;
576 	case 2:
577 		ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_2;
578 		break;
579 	case 4:
580 		ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_4;
581 		break;
582 	case 8:
583 		ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_8;
584 		break;
585 	case 16:
586 		ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_16;
587 		break;
588 	default:
589 		return -EINVAL;
590 	}
591 
592 	ret = regmap_write(ssm2518->regmap, SSM2518_REG_CHAN_MAP,
593 		(left_slot << SSM2518_CHAN_MAP_LEFT_SLOT_OFFSET) |
594 		(right_slot << SSM2518_CHAN_MAP_RIGHT_SLOT_OFFSET));
595 	if (ret)
596 		return ret;
597 
598 	ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL1,
599 		SSM2518_SAI_CTRL1_SAI_MASK, ctrl1);
600 	if (ret)
601 		return ret;
602 
603 	return regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL2,
604 		SSM2518_SAI_CTRL2_SLOT_WIDTH_MASK, ctrl2);
605 }
606 
ssm2518_startup(struct snd_pcm_substream * substream,struct snd_soc_dai * dai)607 static int ssm2518_startup(struct snd_pcm_substream *substream,
608 	struct snd_soc_dai *dai)
609 {
610 	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(dai->component);
611 
612 	if (ssm2518->constraints)
613 		snd_pcm_hw_constraint_list(substream->runtime, 0,
614 				SNDRV_PCM_HW_PARAM_RATE, ssm2518->constraints);
615 
616 	return 0;
617 }
618 
619 #define SSM2518_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
620 			SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32)
621 
622 static const struct snd_soc_dai_ops ssm2518_dai_ops = {
623 	.startup = ssm2518_startup,
624 	.hw_params	= ssm2518_hw_params,
625 	.mute_stream	= ssm2518_mute,
626 	.set_fmt	= ssm2518_set_dai_fmt,
627 	.set_tdm_slot	= ssm2518_set_tdm_slot,
628 	.no_capture_mute = 1,
629 };
630 
631 static struct snd_soc_dai_driver ssm2518_dai = {
632 	.name = "ssm2518-hifi",
633 	.playback = {
634 		.stream_name = "Playback",
635 		.channels_min = 2,
636 		.channels_max = 2,
637 		.rates = SNDRV_PCM_RATE_8000_96000,
638 		.formats = SSM2518_FORMATS,
639 	},
640 	.ops = &ssm2518_dai_ops,
641 };
642 
ssm2518_set_sysclk(struct snd_soc_component * component,int clk_id,int source,unsigned int freq,int dir)643 static int ssm2518_set_sysclk(struct snd_soc_component *component, int clk_id,
644 	int source, unsigned int freq, int dir)
645 {
646 	struct ssm2518 *ssm2518 = snd_soc_component_get_drvdata(component);
647 	unsigned int val;
648 
649 	if (clk_id != SSM2518_SYSCLK)
650 		return -EINVAL;
651 
652 	switch (source) {
653 	case SSM2518_SYSCLK_SRC_MCLK:
654 		val = 0;
655 		break;
656 	case SSM2518_SYSCLK_SRC_BCLK:
657 		/* In this case the bitclock is used as the system clock, and
658 		 * the bitclock signal needs to be connected to the MCLK pin and
659 		 * the BCLK pin is left unconnected */
660 		val = SSM2518_POWER1_NO_BCLK;
661 		break;
662 	default:
663 		return -EINVAL;
664 	}
665 
666 	switch (freq) {
667 	case 0:
668 		ssm2518->constraints = NULL;
669 		break;
670 	case 2048000:
671 	case 4096000:
672 	case 8192000:
673 	case 3200000:
674 	case 6400000:
675 	case 12800000:
676 		ssm2518->constraints = &ssm2518_constraints_2048000;
677 		break;
678 	case 2822000:
679 	case 5644800:
680 	case 11289600:
681 	case 16934400:
682 	case 22579200:
683 	case 33868800:
684 	case 4410000:
685 	case 8820000:
686 	case 17640000:
687 		ssm2518->constraints = &ssm2518_constraints_2822000;
688 		break;
689 	case 3072000:
690 	case 6144000:
691 	case 38864000:
692 	case 4800000:
693 	case 9600000:
694 	case 19200000:
695 		ssm2518->constraints = &ssm2518_constraints_3072000;
696 		break;
697 	case 12288000:
698 	case 16384000:
699 	case 24576000:
700 		ssm2518->constraints = &ssm2518_constraints_12288000;
701 		break;
702 	default:
703 		return -EINVAL;
704 	}
705 
706 	ssm2518->sysclk = freq;
707 
708 	return regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
709 			SSM2518_POWER1_NO_BCLK, val);
710 }
711 
712 static const struct snd_soc_component_driver ssm2518_component_driver = {
713 	.set_bias_level		= ssm2518_set_bias_level,
714 	.set_sysclk		= ssm2518_set_sysclk,
715 	.controls		= ssm2518_snd_controls,
716 	.num_controls		= ARRAY_SIZE(ssm2518_snd_controls),
717 	.dapm_widgets		= ssm2518_dapm_widgets,
718 	.num_dapm_widgets	= ARRAY_SIZE(ssm2518_dapm_widgets),
719 	.dapm_routes		= ssm2518_routes,
720 	.num_dapm_routes	= ARRAY_SIZE(ssm2518_routes),
721 	.use_pmdown_time	= 1,
722 	.endianness		= 1,
723 };
724 
725 static const struct regmap_config ssm2518_regmap_config = {
726 	.val_bits = 8,
727 	.reg_bits = 8,
728 
729 	.max_register = SSM2518_REG_DRC_9,
730 
731 	.cache_type = REGCACHE_RBTREE,
732 	.reg_defaults = ssm2518_reg_defaults,
733 	.num_reg_defaults = ARRAY_SIZE(ssm2518_reg_defaults),
734 };
735 
ssm2518_i2c_probe(struct i2c_client * i2c)736 static int ssm2518_i2c_probe(struct i2c_client *i2c)
737 {
738 	struct ssm2518 *ssm2518;
739 	int ret;
740 
741 	ssm2518 = devm_kzalloc(&i2c->dev, sizeof(*ssm2518), GFP_KERNEL);
742 	if (ssm2518 == NULL)
743 		return -ENOMEM;
744 
745 	/* Start with enabling the chip */
746 	ssm2518->enable_gpio = devm_gpiod_get_optional(&i2c->dev, NULL,
747 						       GPIOD_OUT_HIGH);
748 	ret = PTR_ERR_OR_ZERO(ssm2518->enable_gpio);
749 	if (ret)
750 		return ret;
751 
752 	gpiod_set_consumer_name(ssm2518->enable_gpio, "SSM2518 nSD");
753 
754 	i2c_set_clientdata(i2c, ssm2518);
755 
756 	ssm2518->regmap = devm_regmap_init_i2c(i2c, &ssm2518_regmap_config);
757 	if (IS_ERR(ssm2518->regmap))
758 		return PTR_ERR(ssm2518->regmap);
759 
760 	/*
761 	 * The reset bit is obviously volatile, but we need to be able to cache
762 	 * the other bits in the register, so we can't just mark the whole
763 	 * register as volatile. Since this is the only place where we'll ever
764 	 * touch the reset bit just bypass the cache for this operation.
765 	 */
766 	regcache_cache_bypass(ssm2518->regmap, true);
767 	ret = regmap_write(ssm2518->regmap, SSM2518_REG_POWER1,
768 			SSM2518_POWER1_RESET);
769 	regcache_cache_bypass(ssm2518->regmap, false);
770 	if (ret)
771 		return ret;
772 
773 	ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER2,
774 				SSM2518_POWER2_APWDN, 0x00);
775 	if (ret)
776 		return ret;
777 
778 	ret = ssm2518_set_power(ssm2518, false);
779 	if (ret)
780 		return ret;
781 
782 	return devm_snd_soc_register_component(&i2c->dev,
783 			&ssm2518_component_driver,
784 			&ssm2518_dai, 1);
785 }
786 
787 #ifdef CONFIG_OF
788 static const struct of_device_id ssm2518_dt_ids[] = {
789 	{ .compatible = "adi,ssm2518", },
790 	{ }
791 };
792 MODULE_DEVICE_TABLE(of, ssm2518_dt_ids);
793 #endif
794 
795 static const struct i2c_device_id ssm2518_i2c_ids[] = {
796 	{ "ssm2518", 0 },
797 	{ }
798 };
799 MODULE_DEVICE_TABLE(i2c, ssm2518_i2c_ids);
800 
801 static struct i2c_driver ssm2518_driver = {
802 	.driver = {
803 		.name = "ssm2518",
804 		.of_match_table = of_match_ptr(ssm2518_dt_ids),
805 	},
806 	.probe = ssm2518_i2c_probe,
807 	.id_table = ssm2518_i2c_ids,
808 };
809 module_i2c_driver(ssm2518_driver);
810 
811 MODULE_DESCRIPTION("ASoC SSM2518 driver");
812 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
813 MODULE_LICENSE("GPL");
814