Merge branch 'for-5.6' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[linux-2.6-microblaze.git] / sound / soc / codecs / tas2562.c
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // Driver for the Texas Instruments TAS2562 CODEC
4 // Copyright (C) 2019 Texas Instruments Inc.
5
6
7 #include <linux/module.h>
8 #include <linux/errno.h>
9 #include <linux/device.h>
10 #include <linux/i2c.h>
11 #include <linux/pm_runtime.h>
12 #include <linux/regmap.h>
13 #include <linux/slab.h>
14 #include <linux/gpio/consumer.h>
15 #include <linux/regulator/consumer.h>
16 #include <linux/delay.h>
17
18 #include <sound/pcm.h>
19 #include <sound/pcm_params.h>
20 #include <sound/soc.h>
21 #include <sound/soc-dapm.h>
22 #include <sound/tlv.h>
23
24 #include "tas2562.h"
25
26 #define TAS2562_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE |\
27                          SNDRV_PCM_FORMAT_S32_LE)
28
29 /* DVC equation involves floating point math
30  * round(10^(volume in dB/20)*2^30)
31  * so create a lookup table for 2dB step
32  */
33 static const unsigned int float_vol_db_lookup[] = {
34 0x00000d43, 0x000010b2, 0x00001505, 0x00001a67, 0x00002151,
35 0x000029f1, 0x000034cd, 0x00004279, 0x000053af, 0x0000695b,
36 0x0000695b, 0x0000a6fa, 0x0000d236, 0x000108a4, 0x00014d2a,
37 0x0001a36e, 0x00021008, 0x000298c0, 0x000344df, 0x00041d8f,
38 0x00052e5a, 0x000685c8, 0x00083621, 0x000a566d, 0x000d03a7,
39 0x0010624d, 0x0014a050, 0x0019f786, 0x0020b0bc, 0x0029279d,
40 0x0033cf8d, 0x004139d3, 0x00521d50, 0x00676044, 0x0082248a,
41 0x00a3d70a, 0x00ce4328, 0x0103ab3d, 0x0146e75d, 0x019b8c27,
42 0x02061b89, 0x028c423f, 0x03352529, 0x0409c2b0, 0x05156d68,
43 0x080e9f96, 0x0a24b062, 0x0cc509ab, 0x10137987, 0x143d1362,
44 0x197a967f, 0x2013739e, 0x28619ae9, 0x32d64617, 0x40000000
45 };
46
47 struct tas2562_data {
48         struct snd_soc_component *component;
49         struct gpio_desc *sdz_gpio;
50         struct regmap *regmap;
51         struct device *dev;
52         struct i2c_client *client;
53         int v_sense_slot;
54         int i_sense_slot;
55         int volume_lvl;
56 };
57
58 enum tas256x_model {
59         TAS2562,
60         TAS2563,
61 };
62
63 static int tas2562_set_bias_level(struct snd_soc_component *component,
64                                  enum snd_soc_bias_level level)
65 {
66         struct tas2562_data *tas2562 =
67                         snd_soc_component_get_drvdata(component);
68
69         switch (level) {
70         case SND_SOC_BIAS_ON:
71                 snd_soc_component_update_bits(component,
72                         TAS2562_PWR_CTRL,
73                         TAS2562_MODE_MASK, TAS2562_ACTIVE);
74                 break;
75         case SND_SOC_BIAS_STANDBY:
76         case SND_SOC_BIAS_PREPARE:
77                 snd_soc_component_update_bits(component,
78                         TAS2562_PWR_CTRL,
79                         TAS2562_MODE_MASK, TAS2562_MUTE);
80                 break;
81         case SND_SOC_BIAS_OFF:
82                 snd_soc_component_update_bits(component,
83                         TAS2562_PWR_CTRL,
84                         TAS2562_MODE_MASK, TAS2562_SHUTDOWN);
85                 break;
86
87         default:
88                 dev_err(tas2562->dev,
89                                 "wrong power level setting %d\n", level);
90                 return -EINVAL;
91         }
92
93         return 0;
94 }
95
96 static int tas2562_set_samplerate(struct tas2562_data *tas2562, int samplerate)
97 {
98         int samp_rate;
99         int ramp_rate;
100
101         switch (samplerate) {
102         case 7350:
103                 ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1;
104                 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_7305_8KHZ;
105                 break;
106         case 8000:
107                 ramp_rate = 0;
108                 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_7305_8KHZ;
109                 break;
110         case 14700:
111                 ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1;
112                 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_14_7_16KHZ;
113                 break;
114         case 16000:
115                 ramp_rate = 0;
116                 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_14_7_16KHZ;
117                 break;
118         case 22050:
119                 ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1;
120                 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_22_05_24KHZ;
121                 break;
122         case 24000:
123                 ramp_rate = 0;
124                 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_22_05_24KHZ;
125                 break;
126         case 29400:
127                 ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1;
128                 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_29_4_32KHZ;
129                 break;
130         case 32000:
131                 ramp_rate = 0;
132                 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_29_4_32KHZ;
133                 break;
134         case 44100:
135                 ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1;
136                 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_44_1_48KHZ;
137                 break;
138         case 48000:
139                 ramp_rate = 0;
140                 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_44_1_48KHZ;
141                 break;
142         case 88200:
143                 ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1;
144                 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_88_2_96KHZ;
145                 break;
146         case 96000:
147                 ramp_rate = 0;
148                 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_88_2_96KHZ;
149                 break;
150         case 176400:
151                 ramp_rate = TAS2562_TDM_CFG0_RAMPRATE_44_1;
152                 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_176_4_192KHZ;
153                 break;
154         case 192000:
155                 ramp_rate = 0;
156                 samp_rate = TAS2562_TDM_CFG0_SAMPRATE_176_4_192KHZ;
157                 break;
158         default:
159                 dev_info(tas2562->dev, "%s, unsupported sample rate, %d\n",
160                         __func__, samplerate);
161                 return -EINVAL;
162         }
163
164         snd_soc_component_update_bits(tas2562->component, TAS2562_TDM_CFG0,
165                 TAS2562_TDM_CFG0_RAMPRATE_MASK, ramp_rate);
166         snd_soc_component_update_bits(tas2562->component, TAS2562_TDM_CFG0,
167                 TAS2562_TDM_CFG0_SAMPRATE_MASK, samp_rate);
168
169         return 0;
170 }
171
172 static int tas2562_set_dai_tdm_slot(struct snd_soc_dai *dai,
173                 unsigned int tx_mask, unsigned int rx_mask,
174                 int slots, int slot_width)
175 {
176         struct snd_soc_component *component = dai->component;
177         struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
178         int ret = 0;
179
180         switch (slot_width) {
181         case 16:
182                 ret = snd_soc_component_update_bits(component,
183                                                     TAS2562_TDM_CFG2,
184                                                     TAS2562_TDM_CFG2_RXLEN_MASK,
185                                                     TAS2562_TDM_CFG2_RXLEN_16B);
186                 break;
187         case 24:
188                 ret = snd_soc_component_update_bits(component,
189                                                     TAS2562_TDM_CFG2,
190                                                     TAS2562_TDM_CFG2_RXLEN_MASK,
191                                                     TAS2562_TDM_CFG2_RXLEN_24B);
192                 break;
193         case 32:
194                 ret = snd_soc_component_update_bits(component,
195                                                     TAS2562_TDM_CFG2,
196                                                     TAS2562_TDM_CFG2_RXLEN_MASK,
197                                                     TAS2562_TDM_CFG2_RXLEN_32B);
198                 break;
199
200         case 0:
201                 /* Do not change slot width */
202                 break;
203         default:
204                 dev_err(tas2562->dev, "slot width not supported");
205                 ret = -EINVAL;
206         }
207
208         if (ret < 0)
209                 return ret;
210
211         return 0;
212 }
213
214 static int tas2562_set_bitwidth(struct tas2562_data *tas2562, int bitwidth)
215 {
216         int ret;
217
218         switch (bitwidth) {
219         case SNDRV_PCM_FORMAT_S16_LE:
220                 snd_soc_component_update_bits(tas2562->component,
221                                               TAS2562_TDM_CFG2,
222                                               TAS2562_TDM_CFG2_RXWLEN_MASK,
223                                               TAS2562_TDM_CFG2_RXWLEN_16B);
224                 tas2562->v_sense_slot = tas2562->i_sense_slot + 2;
225                 break;
226         case SNDRV_PCM_FORMAT_S24_LE:
227                 snd_soc_component_update_bits(tas2562->component,
228                                               TAS2562_TDM_CFG2,
229                                               TAS2562_TDM_CFG2_RXWLEN_MASK,
230                                               TAS2562_TDM_CFG2_RXWLEN_24B);
231                 tas2562->v_sense_slot = tas2562->i_sense_slot + 4;
232                 break;
233         case SNDRV_PCM_FORMAT_S32_LE:
234                 snd_soc_component_update_bits(tas2562->component,
235                                               TAS2562_TDM_CFG2,
236                                               TAS2562_TDM_CFG2_RXWLEN_MASK,
237                                               TAS2562_TDM_CFG2_RXWLEN_32B);
238                 tas2562->v_sense_slot = tas2562->i_sense_slot + 4;
239                 break;
240
241         default:
242                 dev_info(tas2562->dev, "Unsupported bitwidth format\n");
243                 return -EINVAL;
244         }
245
246         ret = snd_soc_component_update_bits(tas2562->component,
247                 TAS2562_TDM_CFG5,
248                 TAS2562_TDM_CFG5_VSNS_EN | TAS2562_TDM_CFG5_VSNS_SLOT_MASK,
249                 TAS2562_TDM_CFG5_VSNS_EN | tas2562->v_sense_slot);
250         if (ret < 0)
251                 return ret;
252
253         ret = snd_soc_component_update_bits(tas2562->component,
254                 TAS2562_TDM_CFG6,
255                 TAS2562_TDM_CFG6_ISNS_EN | TAS2562_TDM_CFG6_ISNS_SLOT_MASK,
256                 TAS2562_TDM_CFG6_ISNS_EN | tas2562->i_sense_slot);
257         if (ret < 0)
258                 return ret;
259
260         return 0;
261 }
262
263 static int tas2562_hw_params(struct snd_pcm_substream *substream,
264                              struct snd_pcm_hw_params *params,
265                              struct snd_soc_dai *dai)
266 {
267         struct snd_soc_component *component = dai->component;
268         struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
269         int ret;
270
271         ret = tas2562_set_bitwidth(tas2562, params_format(params));
272         if (ret) {
273                 dev_err(tas2562->dev, "set bitwidth failed, %d\n", ret);
274                 return ret;
275         }
276
277         ret = tas2562_set_samplerate(tas2562, params_rate(params));
278         if (ret)
279                 dev_err(tas2562->dev, "set sample rate failed, %d\n", ret);
280
281         return ret;
282 }
283
284 static int tas2562_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
285 {
286         struct snd_soc_component *component = dai->component;
287         struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
288         u8 tdm_rx_start_slot = 0, asi_cfg_1 = 0;
289         int ret;
290
291         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
292         case SND_SOC_DAIFMT_NB_NF:
293                 asi_cfg_1 = 0;
294                 break;
295         case SND_SOC_DAIFMT_IB_NF:
296                 asi_cfg_1 |= TAS2562_TDM_CFG1_RX_FALLING;
297                 break;
298         default:
299                 dev_err(tas2562->dev, "ASI format Inverse is not found\n");
300                 return -EINVAL;
301         }
302
303         ret = snd_soc_component_update_bits(component, TAS2562_TDM_CFG1,
304                                             TAS2562_TDM_CFG1_RX_EDGE_MASK,
305                                             asi_cfg_1);
306         if (ret < 0) {
307                 dev_err(tas2562->dev, "Failed to set RX edge\n");
308                 return ret;
309         }
310
311         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
312         case (SND_SOC_DAIFMT_I2S):
313         case (SND_SOC_DAIFMT_DSP_A):
314         case (SND_SOC_DAIFMT_DSP_B):
315                 tdm_rx_start_slot = BIT(1);
316                 break;
317         case (SND_SOC_DAIFMT_LEFT_J):
318                 tdm_rx_start_slot = 0;
319                 break;
320         default:
321                 dev_err(tas2562->dev, "DAI Format is not found, fmt=0x%x\n",
322                         fmt);
323                 ret = -EINVAL;
324                 break;
325         }
326
327         ret = snd_soc_component_update_bits(component, TAS2562_TDM_CFG1,
328                                             TAS2562_TDM_CFG1_RX_OFFSET_MASK,
329                                             tdm_rx_start_slot);
330
331         if (ret < 0)
332                 return ret;
333
334         return 0;
335 }
336
337 static int tas2562_mute(struct snd_soc_dai *dai, int mute)
338 {
339         struct snd_soc_component *component = dai->component;
340
341         return snd_soc_component_update_bits(component, TAS2562_PWR_CTRL,
342                                              TAS2562_MODE_MASK,
343                                              mute ? TAS2562_MUTE : 0);
344 }
345
346 static int tas2562_codec_probe(struct snd_soc_component *component)
347 {
348         struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
349         int ret;
350
351         tas2562->component = component;
352
353         if (tas2562->sdz_gpio)
354                 gpiod_set_value_cansleep(tas2562->sdz_gpio, 1);
355
356         ret = snd_soc_component_update_bits(component, TAS2562_PWR_CTRL,
357                                             TAS2562_MODE_MASK, TAS2562_MUTE);
358         if (ret < 0)
359                 return ret;
360
361         return 0;
362 }
363
364 #ifdef CONFIG_PM
365 static int tas2562_suspend(struct snd_soc_component *component)
366 {
367         struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
368
369         regcache_cache_only(tas2562->regmap, true);
370         regcache_mark_dirty(tas2562->regmap);
371
372         if (tas2562->sdz_gpio)
373                 gpiod_set_value_cansleep(tas2562->sdz_gpio, 0);
374
375         return 0;
376 }
377
378 static int tas2562_resume(struct snd_soc_component *component)
379 {
380         struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
381
382         if (tas2562->sdz_gpio)
383                 gpiod_set_value_cansleep(tas2562->sdz_gpio, 1);
384
385         regcache_cache_only(tas2562->regmap, false);
386
387         return regcache_sync(tas2562->regmap);
388 }
389 #else
390 #define tas2562_suspend NULL
391 #define tas2562_resume NULL
392 #endif
393
394 static const char * const tas2562_ASI1_src[] = {
395         "I2C offset", "Left", "Right", "LeftRightDiv2",
396 };
397
398 static SOC_ENUM_SINGLE_DECL(tas2562_ASI1_src_enum, TAS2562_TDM_CFG2, 4,
399                             tas2562_ASI1_src);
400
401 static const struct snd_kcontrol_new tas2562_asi1_mux =
402         SOC_DAPM_ENUM("ASI1 Source", tas2562_ASI1_src_enum);
403
404 static int tas2562_dac_event(struct snd_soc_dapm_widget *w,
405                              struct snd_kcontrol *kcontrol, int event)
406 {
407         struct snd_soc_component *component =
408                                         snd_soc_dapm_to_component(w->dapm);
409         struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
410         int ret;
411
412         switch (event) {
413         case SND_SOC_DAPM_POST_PMU:
414                 ret = snd_soc_component_update_bits(component,
415                         TAS2562_PWR_CTRL,
416                         TAS2562_MODE_MASK,
417                         TAS2562_MUTE);
418                 if (ret)
419                         goto end;
420                 break;
421         case SND_SOC_DAPM_PRE_PMD:
422                 ret = snd_soc_component_update_bits(component,
423                         TAS2562_PWR_CTRL,
424                         TAS2562_MODE_MASK,
425                         TAS2562_SHUTDOWN);
426                 if (ret)
427                         goto end;
428                 break;
429         default:
430                 dev_err(tas2562->dev, "Not supported evevt\n");
431                 return -EINVAL;
432         }
433
434 end:
435         if (ret < 0)
436                 return ret;
437
438         return 0;
439 }
440
441 static int tas2562_volume_control_get(struct snd_kcontrol *kcontrol,
442                                       struct snd_ctl_elem_value *ucontrol)
443 {
444         struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
445         struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
446
447         ucontrol->value.integer.value[0] = tas2562->volume_lvl;
448         return 0;
449 }
450
451 static int tas2562_volume_control_put(struct snd_kcontrol *kcontrol,
452                                       struct snd_ctl_elem_value *ucontrol)
453 {
454         struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
455         struct tas2562_data *tas2562 = snd_soc_component_get_drvdata(component);
456         int ret;
457         u32 reg_val;
458
459         reg_val = float_vol_db_lookup[ucontrol->value.integer.value[0]/2];
460         ret = snd_soc_component_write(component, TAS2562_DVC_CFG4,
461                                       (reg_val & 0xff));
462         if (ret)
463                 return ret;
464         ret = snd_soc_component_write(component, TAS2562_DVC_CFG3,
465                                       ((reg_val >> 8) & 0xff));
466         if (ret)
467                 return ret;
468         ret = snd_soc_component_write(component, TAS2562_DVC_CFG2,
469                                       ((reg_val >> 16) & 0xff));
470         if (ret)
471                 return ret;
472         ret = snd_soc_component_write(component, TAS2562_DVC_CFG1,
473                                       ((reg_val >> 24) & 0xff));
474         if (ret)
475                 return ret;
476
477         tas2562->volume_lvl = ucontrol->value.integer.value[0];
478
479         return ret;
480 }
481
482 /* Digital Volume Control. From 0 dB to -110 dB in 1 dB steps */
483 static const DECLARE_TLV_DB_SCALE(dvc_tlv, -11000, 100, 0);
484
485 static DECLARE_TLV_DB_SCALE(tas2562_dac_tlv, 850, 50, 0);
486
487 static const struct snd_kcontrol_new isense_switch =
488         SOC_DAPM_SINGLE("Switch", TAS2562_PWR_CTRL, TAS2562_ISENSE_POWER_EN,
489                         1, 1);
490
491 static const struct snd_kcontrol_new vsense_switch =
492         SOC_DAPM_SINGLE("Switch", TAS2562_PWR_CTRL, TAS2562_VSENSE_POWER_EN,
493                         1, 1);
494
495 static const struct snd_kcontrol_new tas2562_snd_controls[] = {
496         SOC_SINGLE_TLV("Amp Gain Volume", TAS2562_PB_CFG1, 0, 0x1c, 0,
497                        tas2562_dac_tlv),
498         {
499                 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
500                 .name = "Digital Volume Control",
501                 .index = 0,
502                 .tlv.p = dvc_tlv,
503                 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE,
504                 .info = snd_soc_info_volsw,
505                 .get = tas2562_volume_control_get,
506                 .put = tas2562_volume_control_put,
507                 .private_value = SOC_SINGLE_VALUE(TAS2562_DVC_CFG1, 0, 110, 0, 0) ,
508         },
509 };
510
511 static const struct snd_soc_dapm_widget tas2562_dapm_widgets[] = {
512         SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
513         SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2562_asi1_mux),
514         SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2562_dac_event,
515                            SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
516         SND_SOC_DAPM_SWITCH("ISENSE", TAS2562_PWR_CTRL, 3, 1, &isense_switch),
517         SND_SOC_DAPM_SWITCH("VSENSE", TAS2562_PWR_CTRL, 2, 1, &vsense_switch),
518         SND_SOC_DAPM_SIGGEN("VMON"),
519         SND_SOC_DAPM_SIGGEN("IMON"),
520         SND_SOC_DAPM_OUTPUT("OUT"),
521 };
522
523 static const struct snd_soc_dapm_route tas2562_audio_map[] = {
524         {"ASI1 Sel", "I2C offset", "ASI1"},
525         {"ASI1 Sel", "Left", "ASI1"},
526         {"ASI1 Sel", "Right", "ASI1"},
527         {"ASI1 Sel", "LeftRightDiv2", "ASI1"},
528         { "DAC", NULL, "ASI1 Sel" },
529         { "OUT", NULL, "DAC" },
530         {"ISENSE", "Switch", "IMON"},
531         {"VSENSE", "Switch", "VMON"},
532 };
533
534 static const struct snd_soc_component_driver soc_component_dev_tas2562 = {
535         .probe                  = tas2562_codec_probe,
536         .suspend                = tas2562_suspend,
537         .resume                 = tas2562_resume,
538         .set_bias_level         = tas2562_set_bias_level,
539         .controls               = tas2562_snd_controls,
540         .num_controls           = ARRAY_SIZE(tas2562_snd_controls),
541         .dapm_widgets           = tas2562_dapm_widgets,
542         .num_dapm_widgets       = ARRAY_SIZE(tas2562_dapm_widgets),
543         .dapm_routes            = tas2562_audio_map,
544         .num_dapm_routes        = ARRAY_SIZE(tas2562_audio_map),
545         .idle_bias_on           = 1,
546         .use_pmdown_time        = 1,
547         .endianness             = 1,
548         .non_legacy_dai_naming  = 1,
549 };
550
551 static const struct snd_soc_dai_ops tas2562_speaker_dai_ops = {
552         .hw_params      = tas2562_hw_params,
553         .set_fmt        = tas2562_set_dai_fmt,
554         .set_tdm_slot   = tas2562_set_dai_tdm_slot,
555         .digital_mute   = tas2562_mute,
556 };
557
558 static struct snd_soc_dai_driver tas2562_dai[] = {
559         {
560                 .name = "tas2562-amplifier",
561                 .id = 0,
562                 .playback = {
563                         .stream_name    = "ASI1 Playback",
564                         .channels_min   = 2,
565                         .channels_max   = 2,
566                         .rates      = SNDRV_PCM_RATE_8000_192000,
567                         .formats    = TAS2562_FORMATS,
568                 },
569                 .capture = {
570                         .stream_name    = "ASI1 Capture",
571                         .channels_min   = 0,
572                         .channels_max   = 2,
573                         .rates          = SNDRV_PCM_RATE_8000_192000,
574                         .formats        = TAS2562_FORMATS,
575                 },
576                 .ops = &tas2562_speaker_dai_ops,
577         },
578 };
579
580 static const struct regmap_range_cfg tas2562_ranges[] = {
581         {
582                 .range_min = 0,
583                 .range_max = 5 * 128,
584                 .selector_reg = TAS2562_PAGE_CTRL,
585                 .selector_mask = 0xff,
586                 .selector_shift = 0,
587                 .window_start = 0,
588                 .window_len = 128,
589         },
590 };
591
592 static const struct reg_default tas2562_reg_defaults[] = {
593         { TAS2562_PAGE_CTRL, 0x00 },
594         { TAS2562_SW_RESET, 0x00 },
595         { TAS2562_PWR_CTRL, 0x0e },
596         { TAS2562_PB_CFG1, 0x20 },
597         { TAS2562_TDM_CFG0, 0x09 },
598         { TAS2562_TDM_CFG1, 0x02 },
599         { TAS2562_DVC_CFG1, 0x40 },
600         { TAS2562_DVC_CFG2, 0x40 },
601         { TAS2562_DVC_CFG3, 0x00 },
602         { TAS2562_DVC_CFG4, 0x00 },
603 };
604
605 static const struct regmap_config tas2562_regmap_config = {
606         .reg_bits = 8,
607         .val_bits = 8,
608
609         .max_register = 5 * 128,
610         .cache_type = REGCACHE_RBTREE,
611         .reg_defaults = tas2562_reg_defaults,
612         .num_reg_defaults = ARRAY_SIZE(tas2562_reg_defaults),
613         .ranges = tas2562_ranges,
614         .num_ranges = ARRAY_SIZE(tas2562_ranges),
615 };
616
617 static int tas2562_parse_dt(struct tas2562_data *tas2562)
618 {
619         struct device *dev = tas2562->dev;
620         int ret = 0;
621
622         tas2562->sdz_gpio = devm_gpiod_get_optional(dev, "shut-down-gpio",
623                                                       GPIOD_OUT_HIGH);
624         if (IS_ERR(tas2562->sdz_gpio)) {
625                 if (PTR_ERR(tas2562->sdz_gpio) == -EPROBE_DEFER) {
626                         tas2562->sdz_gpio = NULL;
627                         return -EPROBE_DEFER;
628                 }
629         }
630
631         ret = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no",
632                         &tas2562->i_sense_slot);
633         if (ret)
634                 dev_err(dev, "Looking up %s property failed %d\n",
635                         "ti,imon-slot-no", ret);
636
637         return ret;
638 }
639
640 static int tas2562_probe(struct i2c_client *client,
641                          const struct i2c_device_id *id)
642 {
643         struct device *dev = &client->dev;
644         struct tas2562_data *data;
645         int ret;
646
647         data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
648         if (!data)
649                 return -ENOMEM;
650
651         data->client = client;
652         data->dev = &client->dev;
653
654         tas2562_parse_dt(data);
655
656         data->regmap = devm_regmap_init_i2c(client, &tas2562_regmap_config);
657         if (IS_ERR(data->regmap)) {
658                 ret = PTR_ERR(data->regmap);
659                 dev_err(dev, "failed to allocate register map: %d\n", ret);
660                 return ret;
661         }
662
663         dev_set_drvdata(&client->dev, data);
664
665         return devm_snd_soc_register_component(dev, &soc_component_dev_tas2562,
666                                                tas2562_dai,
667                                                ARRAY_SIZE(tas2562_dai));
668
669 }
670
671 static const struct i2c_device_id tas2562_id[] = {
672         { "tas2562", TAS2562 },
673         { "tas2563", TAS2563 },
674         { }
675 };
676 MODULE_DEVICE_TABLE(i2c, tas2562_id);
677
678 static const struct of_device_id tas2562_of_match[] = {
679         { .compatible = "ti,tas2562", },
680         { .compatible = "ti,tas2563", },
681         { },
682 };
683 MODULE_DEVICE_TABLE(of, tas2562_of_match);
684
685 static struct i2c_driver tas2562_i2c_driver = {
686         .driver = {
687                 .name = "tas2562",
688                 .of_match_table = of_match_ptr(tas2562_of_match),
689         },
690         .probe = tas2562_probe,
691         .id_table = tas2562_id,
692 };
693
694 module_i2c_driver(tas2562_i2c_driver);
695
696 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
697 MODULE_DESCRIPTION("TAS2562 Audio amplifier driver");
698 MODULE_LICENSE("GPL");