]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - sound/soc/codecs/ssm2518.c
Merge remote-tracking branch 'sound-current/for-linus'
[karo-tx-linux.git] / sound / soc / codecs / ssm2518.c
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 (snd_soc_codec_get_bias_level(codec) == 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         return ret;
522 }
523
524 static int ssm2518_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
525         unsigned int rx_mask, int slots, int width)
526 {
527         struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
528         unsigned int ctrl1, ctrl2;
529         int left_slot, right_slot;
530         int ret;
531
532         if (slots == 0)
533                 return regmap_update_bits(ssm2518->regmap,
534                         SSM2518_REG_SAI_CTRL1, SSM2518_SAI_CTRL1_SAI_MASK,
535                         SSM2518_SAI_CTRL1_SAI_I2S);
536
537         if (tx_mask == 0 || rx_mask != 0)
538                 return -EINVAL;
539
540         if (slots == 1) {
541                 if (tx_mask != 1)
542                         return -EINVAL;
543                 left_slot = 0;
544                 right_slot = 0;
545         } else {
546                 /* We assume the left channel < right channel */
547                 left_slot = __ffs(tx_mask);
548                 tx_mask &= ~(1 << left_slot);
549                 if (tx_mask == 0) {
550                         right_slot = left_slot;
551                 } else {
552                         right_slot = __ffs(tx_mask);
553                         tx_mask &= ~(1 << right_slot);
554                 }
555         }
556
557         if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
558                 return -EINVAL;
559
560         switch (width) {
561         case 16:
562                 ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_16;
563                 break;
564         case 24:
565                 ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_24;
566                 break;
567         case 32:
568                 ctrl2 = SSM2518_SAI_CTRL2_SLOT_WIDTH_32;
569                 break;
570         default:
571                 return -EINVAL;
572         }
573
574         switch (slots) {
575         case 1:
576                 ctrl1 = SSM2518_SAI_CTRL1_SAI_MONO;
577                 break;
578         case 2:
579                 ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_2;
580                 break;
581         case 4:
582                 ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_4;
583                 break;
584         case 8:
585                 ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_8;
586                 break;
587         case 16:
588                 ctrl1 = SSM2518_SAI_CTRL1_SAI_TDM_16;
589                 break;
590         default:
591                 return -EINVAL;
592         }
593
594         ret = regmap_write(ssm2518->regmap, SSM2518_REG_CHAN_MAP,
595                 (left_slot << SSM2518_CHAN_MAP_LEFT_SLOT_OFFSET) |
596                 (right_slot << SSM2518_CHAN_MAP_RIGHT_SLOT_OFFSET));
597         if (ret)
598                 return ret;
599
600         ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL1,
601                 SSM2518_SAI_CTRL1_SAI_MASK, ctrl1);
602         if (ret)
603                 return ret;
604
605         return regmap_update_bits(ssm2518->regmap, SSM2518_REG_SAI_CTRL2,
606                 SSM2518_SAI_CTRL2_SLOT_WIDTH_MASK, ctrl2);
607 }
608
609 static int ssm2518_startup(struct snd_pcm_substream *substream,
610         struct snd_soc_dai *dai)
611 {
612         struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(dai->codec);
613
614         if (ssm2518->constraints)
615                 snd_pcm_hw_constraint_list(substream->runtime, 0,
616                                 SNDRV_PCM_HW_PARAM_RATE, ssm2518->constraints);
617
618         return 0;
619 }
620
621 #define SSM2518_FORMATS (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | \
622                         SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32)
623
624 static const struct snd_soc_dai_ops ssm2518_dai_ops = {
625         .startup = ssm2518_startup,
626         .hw_params      = ssm2518_hw_params,
627         .digital_mute   = ssm2518_mute,
628         .set_fmt        = ssm2518_set_dai_fmt,
629         .set_tdm_slot   = ssm2518_set_tdm_slot,
630 };
631
632 static struct snd_soc_dai_driver ssm2518_dai = {
633         .name = "ssm2518-hifi",
634         .playback = {
635                 .stream_name = "Playback",
636                 .channels_min = 2,
637                 .channels_max = 2,
638                 .rates = SNDRV_PCM_RATE_8000_96000,
639                 .formats = SSM2518_FORMATS,
640         },
641         .ops = &ssm2518_dai_ops,
642 };
643
644 static int ssm2518_set_sysclk(struct snd_soc_codec *codec, int clk_id,
645         int source, unsigned int freq, int dir)
646 {
647         struct ssm2518 *ssm2518 = snd_soc_codec_get_drvdata(codec);
648         unsigned int val;
649
650         if (clk_id != SSM2518_SYSCLK)
651                 return -EINVAL;
652
653         switch (source) {
654         case SSM2518_SYSCLK_SRC_MCLK:
655                 val = 0;
656                 break;
657         case SSM2518_SYSCLK_SRC_BCLK:
658                 /* In this case the bitclock is used as the system clock, and
659                  * the bitclock signal needs to be connected to the MCLK pin and
660                  * the BCLK pin is left unconnected */
661                 val = SSM2518_POWER1_NO_BCLK;
662                 break;
663         default:
664                 return -EINVAL;
665         }
666
667         switch (freq) {
668         case 0:
669                 ssm2518->constraints = NULL;
670                 break;
671         case 2048000:
672         case 4096000:
673         case 8192000:
674         case 3200000:
675         case 6400000:
676         case 12800000:
677                 ssm2518->constraints = &ssm2518_constraints_2048000;
678                 break;
679         case 2822000:
680         case 5644800:
681         case 11289600:
682         case 16934400:
683         case 22579200:
684         case 33868800:
685         case 4410000:
686         case 8820000:
687         case 17640000:
688                 ssm2518->constraints = &ssm2518_constraints_2822000;
689                 break;
690         case 3072000:
691         case 6144000:
692         case 38864000:
693         case 4800000:
694         case 9600000:
695         case 19200000:
696                 ssm2518->constraints = &ssm2518_constraints_3072000;
697                 break;
698         case 12288000:
699         case 16384000:
700         case 24576000:
701                 ssm2518->constraints = &ssm2518_constraints_12288000;
702                 break;
703         default:
704                 return -EINVAL;
705         }
706
707         ssm2518->sysclk = freq;
708
709         return regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER1,
710                         SSM2518_POWER1_NO_BCLK, val);
711 }
712
713 static struct snd_soc_codec_driver ssm2518_codec_driver = {
714         .set_bias_level = ssm2518_set_bias_level,
715         .set_sysclk = ssm2518_set_sysclk,
716         .idle_bias_off = true,
717
718         .controls = ssm2518_snd_controls,
719         .num_controls = ARRAY_SIZE(ssm2518_snd_controls),
720         .dapm_widgets = ssm2518_dapm_widgets,
721         .num_dapm_widgets = ARRAY_SIZE(ssm2518_dapm_widgets),
722         .dapm_routes = ssm2518_routes,
723         .num_dapm_routes = ARRAY_SIZE(ssm2518_routes),
724 };
725
726 static const struct regmap_config ssm2518_regmap_config = {
727         .val_bits = 8,
728         .reg_bits = 8,
729
730         .max_register = SSM2518_REG_DRC_9,
731
732         .cache_type = REGCACHE_RBTREE,
733         .reg_defaults = ssm2518_reg_defaults,
734         .num_reg_defaults = ARRAY_SIZE(ssm2518_reg_defaults),
735 };
736
737 static int ssm2518_i2c_probe(struct i2c_client *i2c,
738         const struct i2c_device_id *id)
739 {
740         struct ssm2518_platform_data *pdata = i2c->dev.platform_data;
741         struct ssm2518 *ssm2518;
742         int ret;
743
744         ssm2518 = devm_kzalloc(&i2c->dev, sizeof(*ssm2518), GFP_KERNEL);
745         if (ssm2518 == NULL)
746                 return -ENOMEM;
747
748         if (pdata) {
749                 ssm2518->enable_gpio = pdata->enable_gpio;
750         } else if (i2c->dev.of_node) {
751                 ssm2518->enable_gpio = of_get_gpio(i2c->dev.of_node, 0);
752                 if (ssm2518->enable_gpio < 0 && ssm2518->enable_gpio != -ENOENT)
753                         return ssm2518->enable_gpio;
754         } else {
755                 ssm2518->enable_gpio = -1;
756         }
757
758         if (gpio_is_valid(ssm2518->enable_gpio)) {
759                 ret = devm_gpio_request_one(&i2c->dev, ssm2518->enable_gpio,
760                                 GPIOF_OUT_INIT_HIGH, "SSM2518 nSD");
761                 if (ret)
762                         return ret;
763         }
764
765         i2c_set_clientdata(i2c, ssm2518);
766
767         ssm2518->regmap = devm_regmap_init_i2c(i2c, &ssm2518_regmap_config);
768         if (IS_ERR(ssm2518->regmap))
769                 return PTR_ERR(ssm2518->regmap);
770
771         /*
772          * The reset bit is obviously volatile, but we need to be able to cache
773          * the other bits in the register, so we can't just mark the whole
774          * register as volatile. Since this is the only place where we'll ever
775          * touch the reset bit just bypass the cache for this operation.
776          */
777         regcache_cache_bypass(ssm2518->regmap, true);
778         ret = regmap_write(ssm2518->regmap, SSM2518_REG_POWER1,
779                         SSM2518_POWER1_RESET);
780         regcache_cache_bypass(ssm2518->regmap, false);
781         if (ret)
782                 return ret;
783
784         ret = regmap_update_bits(ssm2518->regmap, SSM2518_REG_POWER2,
785                                 SSM2518_POWER2_APWDN, 0x00);
786         if (ret)
787                 return ret;
788
789         ret = ssm2518_set_power(ssm2518, false);
790         if (ret)
791                 return ret;
792
793         return snd_soc_register_codec(&i2c->dev, &ssm2518_codec_driver,
794                         &ssm2518_dai, 1);
795 }
796
797 static int ssm2518_i2c_remove(struct i2c_client *client)
798 {
799         snd_soc_unregister_codec(&client->dev);
800         return 0;
801 }
802
803 #ifdef CONFIG_OF
804 static const struct of_device_id ssm2518_dt_ids[] = {
805         { .compatible = "adi,ssm2518", },
806         { }
807 };
808 MODULE_DEVICE_TABLE(of, ssm2518_dt_ids);
809 #endif
810
811 static const struct i2c_device_id ssm2518_i2c_ids[] = {
812         { "ssm2518", 0 },
813         { }
814 };
815 MODULE_DEVICE_TABLE(i2c, ssm2518_i2c_ids);
816
817 static struct i2c_driver ssm2518_driver = {
818         .driver = {
819                 .name = "ssm2518",
820                 .of_match_table = of_match_ptr(ssm2518_dt_ids),
821         },
822         .probe = ssm2518_i2c_probe,
823         .remove = ssm2518_i2c_remove,
824         .id_table = ssm2518_i2c_ids,
825 };
826 module_i2c_driver(ssm2518_driver);
827
828 MODULE_DESCRIPTION("ASoC SSM2518 driver");
829 MODULE_AUTHOR("Lars-Peter Clausen <lars@metafoo.de>");
830 MODULE_LICENSE("GPL");