Mention branches and keyring.
[releases.git] / codecs / tas2770.c
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // ALSA SoC Texas Instruments TAS2770 20-W Digital Input Mono Class-D
4 // Audio Amplifier with Speaker I/V Sense
5 //
6 // Copyright (C) 2016-2017 Texas Instruments Incorporated - https://www.ti.com/
7 //      Author: Tracy Yi <tracy-yi@ti.com>
8 //      Frank Shi <shifu0704@thundersoft.com>
9
10 #include <linux/module.h>
11 #include <linux/moduleparam.h>
12 #include <linux/err.h>
13 #include <linux/init.h>
14 #include <linux/delay.h>
15 #include <linux/pm.h>
16 #include <linux/i2c.h>
17 #include <linux/gpio.h>
18 #include <linux/gpio/consumer.h>
19 #include <linux/regulator/consumer.h>
20 #include <linux/firmware.h>
21 #include <linux/regmap.h>
22 #include <linux/of.h>
23 #include <linux/of_gpio.h>
24 #include <linux/slab.h>
25 #include <sound/soc.h>
26 #include <sound/pcm.h>
27 #include <sound/pcm_params.h>
28 #include <sound/initval.h>
29 #include <sound/tlv.h>
30
31 #include "tas2770.h"
32
33 #define TAS2770_MDELAY 0xFFFFFFFE
34
35 static void tas2770_reset(struct tas2770_priv *tas2770)
36 {
37         if (tas2770->reset_gpio) {
38                 gpiod_set_value_cansleep(tas2770->reset_gpio, 0);
39                 msleep(20);
40                 gpiod_set_value_cansleep(tas2770->reset_gpio, 1);
41                 usleep_range(1000, 2000);
42         }
43
44         snd_soc_component_write(tas2770->component, TAS2770_SW_RST,
45                 TAS2770_RST);
46         usleep_range(1000, 2000);
47 }
48
49 static int tas2770_update_pwr_ctrl(struct tas2770_priv *tas2770)
50 {
51         struct snd_soc_component *component = tas2770->component;
52         unsigned int val;
53         int ret;
54
55         if (tas2770->dac_powered)
56                 val = tas2770->unmuted ?
57                         TAS2770_PWR_CTRL_ACTIVE : TAS2770_PWR_CTRL_MUTE;
58         else
59                 val = TAS2770_PWR_CTRL_SHUTDOWN;
60
61         ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
62                                             TAS2770_PWR_CTRL_MASK, val);
63         if (ret < 0)
64                 return ret;
65
66         return 0;
67 }
68
69 #ifdef CONFIG_PM
70 static int tas2770_codec_suspend(struct snd_soc_component *component)
71 {
72         struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component);
73         int ret = 0;
74
75         regcache_cache_only(tas2770->regmap, true);
76         regcache_mark_dirty(tas2770->regmap);
77
78         if (tas2770->sdz_gpio) {
79                 gpiod_set_value_cansleep(tas2770->sdz_gpio, 0);
80         } else {
81                 ret = snd_soc_component_update_bits(component, TAS2770_PWR_CTRL,
82                                                     TAS2770_PWR_CTRL_MASK,
83                                                     TAS2770_PWR_CTRL_SHUTDOWN);
84                 if (ret < 0) {
85                         regcache_cache_only(tas2770->regmap, false);
86                         regcache_sync(tas2770->regmap);
87                         return ret;
88                 }
89
90                 ret = 0;
91         }
92
93         return ret;
94 }
95
96 static int tas2770_codec_resume(struct snd_soc_component *component)
97 {
98         struct tas2770_priv *tas2770 = snd_soc_component_get_drvdata(component);
99         int ret;
100
101         if (tas2770->sdz_gpio) {
102                 gpiod_set_value_cansleep(tas2770->sdz_gpio, 1);
103                 usleep_range(1000, 2000);
104         } else {
105                 ret = tas2770_update_pwr_ctrl(tas2770);
106                 if (ret < 0)
107                         return ret;
108         }
109
110         regcache_cache_only(tas2770->regmap, false);
111
112         return regcache_sync(tas2770->regmap);
113 }
114 #else
115 #define tas2770_codec_suspend NULL
116 #define tas2770_codec_resume NULL
117 #endif
118
119 static const char * const tas2770_ASI1_src[] = {
120         "I2C offset", "Left", "Right", "LeftRightDiv2",
121 };
122
123 static SOC_ENUM_SINGLE_DECL(
124         tas2770_ASI1_src_enum, TAS2770_TDM_CFG_REG2,
125         4, tas2770_ASI1_src);
126
127 static const struct snd_kcontrol_new tas2770_asi1_mux =
128         SOC_DAPM_ENUM("ASI1 Source", tas2770_ASI1_src_enum);
129
130 static int tas2770_dac_event(struct snd_soc_dapm_widget *w,
131                              struct snd_kcontrol *kcontrol, int event)
132 {
133         struct snd_soc_component *component =
134                         snd_soc_dapm_to_component(w->dapm);
135         struct tas2770_priv *tas2770 =
136                         snd_soc_component_get_drvdata(component);
137         int ret;
138
139         switch (event) {
140         case SND_SOC_DAPM_POST_PMU:
141                 tas2770->dac_powered = 1;
142                 ret = tas2770_update_pwr_ctrl(tas2770);
143                 break;
144         case SND_SOC_DAPM_PRE_PMD:
145                 tas2770->dac_powered = 0;
146                 ret = tas2770_update_pwr_ctrl(tas2770);
147                 break;
148         default:
149                 dev_err(tas2770->dev, "Not supported evevt\n");
150                 return -EINVAL;
151         }
152
153         return ret;
154 }
155
156 static const struct snd_kcontrol_new isense_switch =
157         SOC_DAPM_SINGLE("Switch", TAS2770_PWR_CTRL, 3, 1, 1);
158 static const struct snd_kcontrol_new vsense_switch =
159         SOC_DAPM_SINGLE("Switch", TAS2770_PWR_CTRL, 2, 1, 1);
160
161 static const struct snd_soc_dapm_widget tas2770_dapm_widgets[] = {
162         SND_SOC_DAPM_AIF_IN("ASI1", "ASI1 Playback", 0, SND_SOC_NOPM, 0, 0),
163         SND_SOC_DAPM_MUX("ASI1 Sel", SND_SOC_NOPM, 0, 0, &tas2770_asi1_mux),
164         SND_SOC_DAPM_SWITCH("ISENSE", TAS2770_PWR_CTRL, 3, 1, &isense_switch),
165         SND_SOC_DAPM_SWITCH("VSENSE", TAS2770_PWR_CTRL, 2, 1, &vsense_switch),
166         SND_SOC_DAPM_DAC_E("DAC", NULL, SND_SOC_NOPM, 0, 0, tas2770_dac_event,
167                            SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
168         SND_SOC_DAPM_OUTPUT("OUT"),
169         SND_SOC_DAPM_SIGGEN("VMON"),
170         SND_SOC_DAPM_SIGGEN("IMON")
171 };
172
173 static const struct snd_soc_dapm_route tas2770_audio_map[] = {
174         {"ASI1 Sel", "I2C offset", "ASI1"},
175         {"ASI1 Sel", "Left", "ASI1"},
176         {"ASI1 Sel", "Right", "ASI1"},
177         {"ASI1 Sel", "LeftRightDiv2", "ASI1"},
178         {"DAC", NULL, "ASI1 Sel"},
179         {"OUT", NULL, "DAC"},
180         {"ISENSE", "Switch", "IMON"},
181         {"VSENSE", "Switch", "VMON"},
182 };
183
184 static int tas2770_mute(struct snd_soc_dai *dai, int mute, int direction)
185 {
186         struct snd_soc_component *component = dai->component;
187         struct tas2770_priv *tas2770 =
188                         snd_soc_component_get_drvdata(component);
189
190         tas2770->unmuted = !mute;
191         return tas2770_update_pwr_ctrl(tas2770);
192 }
193
194 static int tas2770_set_bitwidth(struct tas2770_priv *tas2770, int bitwidth)
195 {
196         int ret;
197         struct snd_soc_component *component = tas2770->component;
198
199         switch (bitwidth) {
200         case SNDRV_PCM_FORMAT_S16_LE:
201                 ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG2,
202                                                     TAS2770_TDM_CFG_REG2_RXW_MASK,
203                                                     TAS2770_TDM_CFG_REG2_RXW_16BITS);
204                 tas2770->v_sense_slot = tas2770->i_sense_slot + 2;
205                 break;
206         case SNDRV_PCM_FORMAT_S24_LE:
207                 ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG2,
208                                                     TAS2770_TDM_CFG_REG2_RXW_MASK,
209                                                     TAS2770_TDM_CFG_REG2_RXW_24BITS);
210                 tas2770->v_sense_slot = tas2770->i_sense_slot + 4;
211                 break;
212         case SNDRV_PCM_FORMAT_S32_LE:
213                 ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG2,
214                                                     TAS2770_TDM_CFG_REG2_RXW_MASK,
215                                                     TAS2770_TDM_CFG_REG2_RXW_32BITS);
216                 tas2770->v_sense_slot = tas2770->i_sense_slot + 4;
217                 break;
218
219         default:
220                 return -EINVAL;
221         }
222
223         if (ret < 0)
224                 return ret;
225
226         ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG5,
227                                             TAS2770_TDM_CFG_REG5_VSNS_MASK |
228                                             TAS2770_TDM_CFG_REG5_50_MASK,
229                                             TAS2770_TDM_CFG_REG5_VSNS_ENABLE |
230                 tas2770->v_sense_slot);
231         if (ret < 0)
232                 return ret;
233
234         ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG6,
235                                             TAS2770_TDM_CFG_REG6_ISNS_MASK |
236                                             TAS2770_TDM_CFG_REG6_50_MASK,
237                                             TAS2770_TDM_CFG_REG6_ISNS_ENABLE |
238                                             tas2770->i_sense_slot);
239         if (ret < 0)
240                 return ret;
241
242         return 0;
243 }
244
245 static int tas2770_set_samplerate(struct tas2770_priv *tas2770, int samplerate)
246 {
247         struct snd_soc_component *component = tas2770->component;
248         int ramp_rate_val;
249         int ret;
250
251         switch (samplerate) {
252         case 48000:
253                 ramp_rate_val = TAS2770_TDM_CFG_REG0_SMP_48KHZ |
254                                 TAS2770_TDM_CFG_REG0_31_44_1_48KHZ;
255                 break;
256         case 44100:
257                 ramp_rate_val = TAS2770_TDM_CFG_REG0_SMP_44_1KHZ |
258                                 TAS2770_TDM_CFG_REG0_31_44_1_48KHZ;
259                 break;
260         case 96000:
261                 ramp_rate_val = TAS2770_TDM_CFG_REG0_SMP_48KHZ |
262                                 TAS2770_TDM_CFG_REG0_31_88_2_96KHZ;
263                 break;
264         case 88200:
265                 ramp_rate_val = TAS2770_TDM_CFG_REG0_SMP_44_1KHZ |
266                                 TAS2770_TDM_CFG_REG0_31_88_2_96KHZ;
267                 break;
268         case 192000:
269                 ramp_rate_val = TAS2770_TDM_CFG_REG0_SMP_48KHZ |
270                                 TAS2770_TDM_CFG_REG0_31_176_4_192KHZ;
271                 break;
272         case 176400:
273                 ramp_rate_val = TAS2770_TDM_CFG_REG0_SMP_44_1KHZ |
274                                 TAS2770_TDM_CFG_REG0_31_176_4_192KHZ;
275                 break;
276         default:
277                 return -EINVAL;
278         }
279
280         ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG0,
281                                             TAS2770_TDM_CFG_REG0_SMP_MASK |
282                                             TAS2770_TDM_CFG_REG0_31_MASK,
283                                             ramp_rate_val);
284         if (ret < 0)
285                 return ret;
286
287         return 0;
288 }
289
290 static int tas2770_hw_params(struct snd_pcm_substream *substream,
291                              struct snd_pcm_hw_params *params,
292                              struct snd_soc_dai *dai)
293 {
294         struct snd_soc_component *component = dai->component;
295         struct tas2770_priv *tas2770 =
296                         snd_soc_component_get_drvdata(component);
297         int ret;
298
299         ret = tas2770_set_bitwidth(tas2770, params_format(params));
300         if (ret)
301                 return ret;
302
303         return tas2770_set_samplerate(tas2770, params_rate(params));
304 }
305
306 static int tas2770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
307 {
308         struct snd_soc_component *component = dai->component;
309         struct tas2770_priv *tas2770 =
310                         snd_soc_component_get_drvdata(component);
311         u8 tdm_rx_start_slot = 0, invert_fpol = 0, fpol_preinv = 0, asi_cfg_1 = 0;
312         int ret;
313
314         switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
315         case SND_SOC_DAIFMT_CBC_CFC:
316                 break;
317         default:
318                 dev_err(tas2770->dev, "ASI invalid DAI clocking\n");
319                 return -EINVAL;
320         }
321
322         switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
323         case SND_SOC_DAIFMT_NB_IF:
324                 invert_fpol = 1;
325                 fallthrough;
326         case SND_SOC_DAIFMT_NB_NF:
327                 asi_cfg_1 |= TAS2770_TDM_CFG_REG1_RX_RSING;
328                 break;
329         case SND_SOC_DAIFMT_IB_IF:
330                 invert_fpol = 1;
331                 fallthrough;
332         case SND_SOC_DAIFMT_IB_NF:
333                 asi_cfg_1 |= TAS2770_TDM_CFG_REG1_RX_FALING;
334                 break;
335         default:
336                 dev_err(tas2770->dev, "ASI format Inverse is not found\n");
337                 return -EINVAL;
338         }
339
340         ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG1,
341                                             TAS2770_TDM_CFG_REG1_RX_MASK,
342                                             asi_cfg_1);
343         if (ret < 0)
344                 return ret;
345
346         switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
347         case SND_SOC_DAIFMT_I2S:
348                 tdm_rx_start_slot = 1;
349                 fpol_preinv = 0;
350                 break;
351         case SND_SOC_DAIFMT_DSP_A:
352                 tdm_rx_start_slot = 0;
353                 fpol_preinv = 1;
354                 break;
355         case SND_SOC_DAIFMT_DSP_B:
356                 tdm_rx_start_slot = 1;
357                 fpol_preinv = 1;
358                 break;
359         case SND_SOC_DAIFMT_LEFT_J:
360                 tdm_rx_start_slot = 0;
361                 fpol_preinv = 1;
362                 break;
363         default:
364                 dev_err(tas2770->dev,
365                         "DAI Format is not found, fmt=0x%x\n", fmt);
366                 return -EINVAL;
367         }
368
369         ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG1,
370                                             TAS2770_TDM_CFG_REG1_MASK,
371                                             (tdm_rx_start_slot << TAS2770_TDM_CFG_REG1_51_SHIFT));
372         if (ret < 0)
373                 return ret;
374
375         ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG0,
376                                             TAS2770_TDM_CFG_REG0_FPOL_MASK,
377                                             (fpol_preinv ^ invert_fpol)
378                                              ? TAS2770_TDM_CFG_REG0_FPOL_RSING
379                                              : TAS2770_TDM_CFG_REG0_FPOL_FALING);
380         if (ret < 0)
381                 return ret;
382
383         return 0;
384 }
385
386 static int tas2770_set_dai_tdm_slot(struct snd_soc_dai *dai,
387                                 unsigned int tx_mask,
388                                 unsigned int rx_mask,
389                                 int slots, int slot_width)
390 {
391         struct snd_soc_component *component = dai->component;
392         int left_slot, right_slot;
393         int ret;
394
395         if (tx_mask == 0 || rx_mask != 0)
396                 return -EINVAL;
397
398         left_slot = __ffs(tx_mask);
399         tx_mask &= ~(1 << left_slot);
400         if (tx_mask == 0) {
401                 right_slot = left_slot;
402         } else {
403                 right_slot = __ffs(tx_mask);
404                 tx_mask &= ~(1 << right_slot);
405         }
406
407         if (tx_mask != 0 || left_slot >= slots || right_slot >= slots)
408                 return -EINVAL;
409
410         ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG3,
411                                             TAS2770_TDM_CFG_REG3_30_MASK,
412                                             (left_slot << TAS2770_TDM_CFG_REG3_30_SHIFT));
413         if (ret < 0)
414                 return ret;
415         ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG3,
416                                             TAS2770_TDM_CFG_REG3_RXS_MASK,
417                                             (right_slot << TAS2770_TDM_CFG_REG3_RXS_SHIFT));
418         if (ret < 0)
419                 return ret;
420
421         switch (slot_width) {
422         case 16:
423                 ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG2,
424                                                     TAS2770_TDM_CFG_REG2_RXS_MASK,
425                                                     TAS2770_TDM_CFG_REG2_RXS_16BITS);
426                 break;
427         case 24:
428                 ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG2,
429                                                     TAS2770_TDM_CFG_REG2_RXS_MASK,
430                                                     TAS2770_TDM_CFG_REG2_RXS_24BITS);
431                 break;
432         case 32:
433                 ret = snd_soc_component_update_bits(component, TAS2770_TDM_CFG_REG2,
434                                                     TAS2770_TDM_CFG_REG2_RXS_MASK,
435                                                     TAS2770_TDM_CFG_REG2_RXS_32BITS);
436                 break;
437         case 0:
438                 /* Do not change slot width */
439                 ret = 0;
440                 break;
441         default:
442                 ret = -EINVAL;
443         }
444
445         if (ret < 0)
446                 return ret;
447
448         return 0;
449 }
450
451 static const struct snd_soc_dai_ops tas2770_dai_ops = {
452         .mute_stream = tas2770_mute,
453         .hw_params  = tas2770_hw_params,
454         .set_fmt    = tas2770_set_fmt,
455         .set_tdm_slot = tas2770_set_dai_tdm_slot,
456         .no_capture_mute = 1,
457 };
458
459 #define TAS2770_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
460                 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
461
462 #define TAS2770_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |\
463                                            SNDRV_PCM_RATE_96000 |\
464                                             SNDRV_PCM_RATE_192000\
465                                           )
466
467 static struct snd_soc_dai_driver tas2770_dai_driver[] = {
468         {
469                 .name = "tas2770 ASI1",
470                 .id = 0,
471                 .playback = {
472                         .stream_name    = "ASI1 Playback",
473                         .channels_min   = 1,
474                         .channels_max   = 2,
475                         .rates      = TAS2770_RATES,
476                         .formats    = TAS2770_FORMATS,
477                 },
478                 .capture = {
479                         .stream_name    = "ASI1 Capture",
480                         .channels_min   = 0,
481                         .channels_max   = 2,
482                         .rates          = TAS2770_RATES,
483                         .formats    = TAS2770_FORMATS,
484                 },
485                 .ops = &tas2770_dai_ops,
486                 .symmetric_rate = 1,
487         },
488 };
489
490 static const struct regmap_config tas2770_i2c_regmap;
491
492 static int tas2770_codec_probe(struct snd_soc_component *component)
493 {
494         struct tas2770_priv *tas2770 =
495                         snd_soc_component_get_drvdata(component);
496
497         tas2770->component = component;
498
499         if (tas2770->sdz_gpio) {
500                 gpiod_set_value_cansleep(tas2770->sdz_gpio, 1);
501                 usleep_range(1000, 2000);
502         }
503
504         tas2770_reset(tas2770);
505         regmap_reinit_cache(tas2770->regmap, &tas2770_i2c_regmap);
506
507         return 0;
508 }
509
510 static DECLARE_TLV_DB_SCALE(tas2770_digital_tlv, 1100, 50, 0);
511 static DECLARE_TLV_DB_SCALE(tas2770_playback_volume, -12750, 50, 0);
512
513 static const struct snd_kcontrol_new tas2770_snd_controls[] = {
514         SOC_SINGLE_TLV("Speaker Playback Volume", TAS2770_PLAY_CFG_REG2,
515                        0, TAS2770_PLAY_CFG_REG2_VMAX, 1, tas2770_playback_volume),
516         SOC_SINGLE_TLV("Amp Gain Volume", TAS2770_PLAY_CFG_REG0, 0, 0x14, 0,
517                        tas2770_digital_tlv),
518 };
519
520 static const struct snd_soc_component_driver soc_component_driver_tas2770 = {
521         .probe                  = tas2770_codec_probe,
522         .suspend                = tas2770_codec_suspend,
523         .resume                 = tas2770_codec_resume,
524         .controls               = tas2770_snd_controls,
525         .num_controls           = ARRAY_SIZE(tas2770_snd_controls),
526         .dapm_widgets           = tas2770_dapm_widgets,
527         .num_dapm_widgets       = ARRAY_SIZE(tas2770_dapm_widgets),
528         .dapm_routes            = tas2770_audio_map,
529         .num_dapm_routes        = ARRAY_SIZE(tas2770_audio_map),
530         .idle_bias_on           = 1,
531         .endianness             = 1,
532 };
533
534 static int tas2770_register_codec(struct tas2770_priv *tas2770)
535 {
536         return devm_snd_soc_register_component(tas2770->dev,
537                 &soc_component_driver_tas2770,
538                 tas2770_dai_driver, ARRAY_SIZE(tas2770_dai_driver));
539 }
540
541 static const struct reg_default tas2770_reg_defaults[] = {
542         { TAS2770_PAGE, 0x00 },
543         { TAS2770_SW_RST, 0x00 },
544         { TAS2770_PWR_CTRL, 0x0e },
545         { TAS2770_PLAY_CFG_REG0, 0x10 },
546         { TAS2770_PLAY_CFG_REG1, 0x01 },
547         { TAS2770_PLAY_CFG_REG2, 0x00 },
548         { TAS2770_MSC_CFG_REG0, 0x07 },
549         { TAS2770_TDM_CFG_REG1, 0x02 },
550         { TAS2770_TDM_CFG_REG2, 0x0a },
551         { TAS2770_TDM_CFG_REG3, 0x10 },
552         { TAS2770_INT_MASK_REG0, 0xfc },
553         { TAS2770_INT_MASK_REG1, 0xb1 },
554         { TAS2770_INT_CFG, 0x05 },
555         { TAS2770_MISC_IRQ, 0x81 },
556         { TAS2770_CLK_CGF, 0x0c },
557
558 };
559
560 static bool tas2770_volatile(struct device *dev, unsigned int reg)
561 {
562         switch (reg) {
563         case TAS2770_PAGE: /* regmap implementation requires this */
564         case TAS2770_SW_RST: /* always clears after write */
565         case TAS2770_BO_PRV_REG0:/* has a self clearing bit */
566         case TAS2770_LVE_INT_REG0:
567         case TAS2770_LVE_INT_REG1:
568         case TAS2770_LAT_INT_REG0:/* Sticky interrupt flags */
569         case TAS2770_LAT_INT_REG1:/* Sticky interrupt flags */
570         case TAS2770_VBAT_MSB:
571         case TAS2770_VBAT_LSB:
572         case TAS2770_TEMP_MSB:
573         case TAS2770_TEMP_LSB:
574                 return true;
575         }
576
577         return false;
578 }
579
580 static bool tas2770_writeable(struct device *dev, unsigned int reg)
581 {
582         switch (reg) {
583         case TAS2770_LVE_INT_REG0:
584         case TAS2770_LVE_INT_REG1:
585         case TAS2770_LAT_INT_REG0:
586         case TAS2770_LAT_INT_REG1:
587         case TAS2770_VBAT_MSB:
588         case TAS2770_VBAT_LSB:
589         case TAS2770_TEMP_MSB:
590         case TAS2770_TEMP_LSB:
591         case TAS2770_TDM_CLK_DETC:
592         case TAS2770_REV_AND_GPID:
593                 return false;
594         }
595
596         return true;
597 }
598
599 static const struct regmap_range_cfg tas2770_regmap_ranges[] = {
600         {
601                 .range_min = 0,
602                 .range_max = 1 * 128,
603                 .selector_reg = TAS2770_PAGE,
604                 .selector_mask = 0xff,
605                 .selector_shift = 0,
606                 .window_start = 0,
607                 .window_len = 128,
608         },
609 };
610
611 static const struct regmap_config tas2770_i2c_regmap = {
612         .reg_bits = 8,
613         .val_bits = 8,
614         .writeable_reg = tas2770_writeable,
615         .volatile_reg = tas2770_volatile,
616         .reg_defaults = tas2770_reg_defaults,
617         .num_reg_defaults = ARRAY_SIZE(tas2770_reg_defaults),
618         .cache_type = REGCACHE_RBTREE,
619         .ranges = tas2770_regmap_ranges,
620         .num_ranges = ARRAY_SIZE(tas2770_regmap_ranges),
621         .max_register = 1 * 128,
622 };
623
624 static int tas2770_parse_dt(struct device *dev, struct tas2770_priv *tas2770)
625 {
626         int rc = 0;
627
628         rc = fwnode_property_read_u32(dev->fwnode, "ti,imon-slot-no",
629                                       &tas2770->i_sense_slot);
630         if (rc) {
631                 dev_info(tas2770->dev, "Property %s is missing setting default slot\n",
632                          "ti,imon-slot-no");
633
634                 tas2770->i_sense_slot = 0;
635         }
636
637         rc = fwnode_property_read_u32(dev->fwnode, "ti,vmon-slot-no",
638                                       &tas2770->v_sense_slot);
639         if (rc) {
640                 dev_info(tas2770->dev, "Property %s is missing setting default slot\n",
641                          "ti,vmon-slot-no");
642
643                 tas2770->v_sense_slot = 2;
644         }
645
646         tas2770->sdz_gpio = devm_gpiod_get_optional(dev, "shutdown", GPIOD_OUT_HIGH);
647         if (IS_ERR(tas2770->sdz_gpio)) {
648                 if (PTR_ERR(tas2770->sdz_gpio) == -EPROBE_DEFER)
649                         return -EPROBE_DEFER;
650
651                 tas2770->sdz_gpio = NULL;
652         }
653
654         return 0;
655 }
656
657 static int tas2770_i2c_probe(struct i2c_client *client)
658 {
659         struct tas2770_priv *tas2770;
660         int result;
661
662         tas2770 = devm_kzalloc(&client->dev, sizeof(struct tas2770_priv),
663                                GFP_KERNEL);
664         if (!tas2770)
665                 return -ENOMEM;
666
667         tas2770->dev = &client->dev;
668         i2c_set_clientdata(client, tas2770);
669         dev_set_drvdata(&client->dev, tas2770);
670
671         tas2770->regmap = devm_regmap_init_i2c(client, &tas2770_i2c_regmap);
672         if (IS_ERR(tas2770->regmap)) {
673                 result = PTR_ERR(tas2770->regmap);
674                 dev_err(&client->dev, "Failed to allocate register map: %d\n",
675                         result);
676                 return result;
677         }
678
679         if (client->dev.of_node) {
680                 result = tas2770_parse_dt(&client->dev, tas2770);
681                 if (result) {
682                         dev_err(tas2770->dev, "%s: Failed to parse devicetree\n",
683                                 __func__);
684                         return result;
685                 }
686         }
687
688         tas2770->reset_gpio = devm_gpiod_get_optional(tas2770->dev, "reset",
689                                                       GPIOD_OUT_HIGH);
690         if (IS_ERR(tas2770->reset_gpio)) {
691                 if (PTR_ERR(tas2770->reset_gpio) == -EPROBE_DEFER) {
692                         tas2770->reset_gpio = NULL;
693                         return -EPROBE_DEFER;
694                 }
695         }
696
697         result = tas2770_register_codec(tas2770);
698         if (result)
699                 dev_err(tas2770->dev, "Register codec failed.\n");
700
701         return result;
702 }
703
704 static const struct i2c_device_id tas2770_i2c_id[] = {
705         { "tas2770", 0},
706         { }
707 };
708 MODULE_DEVICE_TABLE(i2c, tas2770_i2c_id);
709
710 #if defined(CONFIG_OF)
711 static const struct of_device_id tas2770_of_match[] = {
712         { .compatible = "ti,tas2770" },
713         {},
714 };
715 MODULE_DEVICE_TABLE(of, tas2770_of_match);
716 #endif
717
718 static struct i2c_driver tas2770_i2c_driver = {
719         .driver = {
720                 .name   = "tas2770",
721                 .of_match_table = of_match_ptr(tas2770_of_match),
722         },
723         .probe_new  = tas2770_i2c_probe,
724         .id_table   = tas2770_i2c_id,
725 };
726 module_i2c_driver(tas2770_i2c_driver);
727
728 MODULE_AUTHOR("Shi Fu <shifu0704@thundersoft.com>");
729 MODULE_DESCRIPTION("TAS2770 I2C Smart Amplifier driver");
730 MODULE_LICENSE("GPL v2");