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