1 // SPDX-License-Identifier: GPL-2.0-only
2 // SPDX-FileCopyrightText: Copyright (c) 2020-2025 NVIDIA CORPORATION & AFFILIATES.
3 // All rights reserved.
4 //
5 // tegra210_i2s.c - Tegra210 I2S driver
6
7 #include <linux/clk.h>
8 #include <linux/device.h>
9 #include <linux/module.h>
10 #include <linux/of_graph.h>
11 #include <linux/platform_device.h>
12 #include <linux/pm_runtime.h>
13 #include <linux/regmap.h>
14 #include <sound/core.h>
15 #include <sound/pcm_params.h>
16 #include <sound/simple_card_utils.h>
17 #include <sound/soc.h>
18 #include "tegra210_i2s.h"
19 #include "tegra_cif.h"
20
21 static const struct reg_default tegra210_i2s_reg_defaults[] = {
22 { TEGRA210_I2S_RX_INT_MASK, 0x00000003 },
23 { TEGRA210_I2S_RX_CIF_CTRL, 0x00007700 },
24 { TEGRA210_I2S_TX_INT_MASK, 0x00000003 },
25 { TEGRA210_I2S_TX_CIF_CTRL, 0x00007700 },
26 { TEGRA210_I2S_ENABLE, 0x0 },
27 { TEGRA210_I2S_CG, 0x1 },
28 { TEGRA210_I2S_TIMING, 0x0000001f },
29 /*
30 * Below update does not have any effect on Tegra186 and Tegra194.
31 * On Tegra210, I2S4 has "i2s4a" and "i2s4b" pins and below update
32 * is required to select i2s4b for it to be functional for I2S
33 * operation.
34 */
35 { TEGRA210_I2S_CYA, 0x1 },
36 };
37
38 static const struct reg_default tegra264_i2s_reg_defaults[] = {
39 { TEGRA210_I2S_RX_INT_MASK, 0x00000003 },
40 { TEGRA210_I2S_RX_CIF_CTRL, 0x00003f00 },
41 { TEGRA264_I2S_RX_FIFO_WR_ACCESS_MODE, 0x1 },
42 { TEGRA264_I2S_TX_INT_MASK, 0x00000003 },
43 { TEGRA264_I2S_TX_CIF_CTRL, 0x00003f00 },
44 { TEGRA264_I2S_TX_FIFO_RD_ACCESS_MODE, 0x1 },
45 { TEGRA264_I2S_ENABLE, 0x0 },
46 { TEGRA264_I2S_CG, 0x1 },
47 { TEGRA264_I2S_TIMING, 0x0000001f },
48 };
49
tegra210_i2s_set_slot_ctrl(struct tegra210_i2s * i2s,unsigned int total_slots,unsigned int tx_slot_mask,unsigned int rx_slot_mask)50 static void tegra210_i2s_set_slot_ctrl(struct tegra210_i2s *i2s,
51 unsigned int total_slots,
52 unsigned int tx_slot_mask,
53 unsigned int rx_slot_mask)
54 {
55 regmap_write(i2s->regmap, TEGRA210_I2S_SLOT_CTRL + i2s->soc_data->i2s_ctrl_offset,
56 total_slots - 1);
57 regmap_write(i2s->regmap, TEGRA210_I2S_TX_SLOT_CTRL + i2s->soc_data->tx_offset,
58 tx_slot_mask);
59 regmap_write(i2s->regmap, TEGRA210_I2S_RX_SLOT_CTRL, rx_slot_mask);
60 }
61
tegra210_i2s_set_clock_rate(struct device * dev,unsigned int clock_rate)62 static int tegra210_i2s_set_clock_rate(struct device *dev,
63 unsigned int clock_rate)
64 {
65 struct tegra210_i2s *i2s = dev_get_drvdata(dev);
66 unsigned int val;
67 int err;
68
69 regmap_read(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset, &val);
70
71 /* No need to set rates if I2S is being operated in slave */
72 if (!(val & I2S_CTRL_MASTER_EN))
73 return 0;
74
75 err = clk_set_rate(i2s->clk_i2s, clock_rate);
76 if (err) {
77 dev_err(dev, "can't set I2S bit clock rate %u, err: %d\n",
78 clock_rate, err);
79 return err;
80 }
81
82 if (!IS_ERR(i2s->clk_sync_input)) {
83 /*
84 * Other I/O modules in AHUB can use i2s bclk as reference
85 * clock. Below sets sync input clock rate as per bclk,
86 * which can be used as input to other I/O modules.
87 */
88 err = clk_set_rate(i2s->clk_sync_input, clock_rate);
89 if (err) {
90 dev_err(dev,
91 "can't set I2S sync input rate %u, err = %d\n",
92 clock_rate, err);
93 return err;
94 }
95 }
96
97 return 0;
98 }
99
tegra210_i2s_sw_reset(struct snd_soc_component * compnt,int stream)100 static int tegra210_i2s_sw_reset(struct snd_soc_component *compnt,
101 int stream)
102 {
103 struct device *dev = compnt->dev;
104 struct tegra210_i2s *i2s = dev_get_drvdata(dev);
105 unsigned int reset_mask = I2S_SOFT_RESET_MASK;
106 unsigned int reset_en = I2S_SOFT_RESET_EN;
107 unsigned int reset_reg, cif_reg, stream_reg;
108 unsigned int cif_ctrl, stream_ctrl, i2s_ctrl, val;
109 int err;
110
111 if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
112 reset_reg = TEGRA210_I2S_RX_SOFT_RESET;
113 cif_reg = TEGRA210_I2S_RX_CIF_CTRL;
114 stream_reg = TEGRA210_I2S_RX_CTRL;
115 } else {
116 reset_reg = TEGRA210_I2S_TX_SOFT_RESET + i2s->soc_data->tx_offset;
117 cif_reg = TEGRA210_I2S_TX_CIF_CTRL + i2s->soc_data->tx_offset;
118 stream_reg = TEGRA210_I2S_TX_CTRL + i2s->soc_data->tx_offset;
119 }
120
121 /* Store CIF and I2S control values */
122 regmap_read(i2s->regmap, cif_reg, &cif_ctrl);
123 regmap_read(i2s->regmap, stream_reg, &stream_ctrl);
124 regmap_read(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset, &i2s_ctrl);
125
126 /* Reset to make sure the previous transactions are clean */
127 regmap_update_bits(i2s->regmap, reset_reg, reset_mask, reset_en);
128
129 err = regmap_read_poll_timeout(i2s->regmap, reset_reg, val,
130 !(val & reset_mask & reset_en),
131 10, 10000);
132 if (err) {
133 dev_err(dev, "timeout: failed to reset I2S for %s\n",
134 snd_pcm_direction_name(stream));
135 return err;
136 }
137
138 /* Restore CIF and I2S control values */
139 regmap_write(i2s->regmap, cif_reg, cif_ctrl);
140 regmap_write(i2s->regmap, stream_reg, stream_ctrl);
141 regmap_write(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset, i2s_ctrl);
142
143 return 0;
144 }
145
tegra210_i2s_init(struct snd_soc_dapm_widget * w,struct snd_kcontrol * kcontrol,int event)146 static int tegra210_i2s_init(struct snd_soc_dapm_widget *w,
147 struct snd_kcontrol *kcontrol, int event)
148 {
149 struct snd_soc_component *compnt = snd_soc_dapm_to_component(w->dapm);
150 struct device *dev = compnt->dev;
151 struct tegra210_i2s *i2s = dev_get_drvdata(dev);
152 unsigned int val, status_reg;
153 int stream;
154 int err;
155
156 if (w->reg == TEGRA210_I2S_RX_ENABLE) {
157 stream = SNDRV_PCM_STREAM_PLAYBACK;
158 status_reg = TEGRA210_I2S_RX_STATUS;
159 } else if (w->reg == (TEGRA210_I2S_TX_ENABLE + i2s->soc_data->tx_offset)) {
160 stream = SNDRV_PCM_STREAM_CAPTURE;
161 status_reg = TEGRA210_I2S_TX_STATUS + i2s->soc_data->tx_offset;
162 } else {
163 dev_err(dev, "invalid I2S direction register 0x%x\n", w->reg);
164 return -EINVAL;
165 }
166
167 /* Ensure I2S is in disabled state before new session */
168 err = regmap_read_poll_timeout(i2s->regmap, status_reg, val,
169 !(val & I2S_EN_MASK & I2S_EN),
170 10, 10000);
171 if (err) {
172 dev_err(dev, "timeout: previous I2S %s is still active\n",
173 snd_pcm_direction_name(stream));
174 return err;
175 }
176
177 return tegra210_i2s_sw_reset(compnt, stream);
178 }
179
tegra210_i2s_runtime_suspend(struct device * dev)180 static int tegra210_i2s_runtime_suspend(struct device *dev)
181 {
182 struct tegra210_i2s *i2s = dev_get_drvdata(dev);
183
184 regcache_cache_only(i2s->regmap, true);
185 regcache_mark_dirty(i2s->regmap);
186
187 clk_disable_unprepare(i2s->clk_i2s);
188
189 return 0;
190 }
191
tegra210_i2s_runtime_resume(struct device * dev)192 static int tegra210_i2s_runtime_resume(struct device *dev)
193 {
194 struct tegra210_i2s *i2s = dev_get_drvdata(dev);
195 int err;
196
197 err = clk_prepare_enable(i2s->clk_i2s);
198 if (err) {
199 dev_err(dev, "failed to enable I2S bit clock, err: %d\n", err);
200 return err;
201 }
202
203 regcache_cache_only(i2s->regmap, false);
204 err = regcache_sync(i2s->regmap);
205 if (err)
206 goto err;
207
208 err = regmap_write(i2s->regmap, i2s->soc_data->enable_reg, I2S_EN);
209 if (err)
210 goto err;
211
212 return 0;
213
214 err:
215 regcache_cache_only(i2s->regmap, true);
216 clk_disable_unprepare(i2s->clk_i2s);
217
218 return err;
219 }
220
tegra210_i2s_set_data_offset(struct tegra210_i2s * i2s,unsigned int data_offset)221 static void tegra210_i2s_set_data_offset(struct tegra210_i2s *i2s,
222 unsigned int data_offset)
223 {
224 /* Capture path */
225 regmap_update_bits(i2s->regmap, TEGRA210_I2S_TX_CTRL + i2s->soc_data->tx_offset,
226 I2S_CTRL_DATA_OFFSET_MASK,
227 data_offset << I2S_DATA_SHIFT);
228
229 /* Playback path */
230 regmap_update_bits(i2s->regmap, TEGRA210_I2S_RX_CTRL,
231 I2S_CTRL_DATA_OFFSET_MASK,
232 data_offset << I2S_DATA_SHIFT);
233 }
234
tegra210_i2s_set_fmt(struct snd_soc_dai * dai,unsigned int fmt)235 static int tegra210_i2s_set_fmt(struct snd_soc_dai *dai,
236 unsigned int fmt)
237 {
238 struct tegra210_i2s *i2s = snd_soc_dai_get_drvdata(dai);
239 unsigned int mask, val;
240
241 mask = I2S_CTRL_MASTER_EN_MASK;
242 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
243 case SND_SOC_DAIFMT_BC_FC:
244 val = 0;
245 break;
246 case SND_SOC_DAIFMT_BP_FP:
247 val = I2S_CTRL_MASTER_EN;
248 break;
249 default:
250 dev_err(dai->dev, "invalid clock provider format 0x%x\n", fmt);
251 return -EINVAL;
252 }
253
254 mask |= I2S_CTRL_FRAME_FMT_MASK | I2S_CTRL_LRCK_POL_MASK;
255 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
256 case SND_SOC_DAIFMT_DSP_A:
257 val |= I2S_CTRL_FRAME_FMT_FSYNC_MODE;
258 val |= I2S_CTRL_LRCK_POL_HIGH;
259 tegra210_i2s_set_data_offset(i2s, 1);
260 break;
261 case SND_SOC_DAIFMT_DSP_B:
262 val |= I2S_CTRL_FRAME_FMT_FSYNC_MODE;
263 val |= I2S_CTRL_LRCK_POL_HIGH;
264 tegra210_i2s_set_data_offset(i2s, 0);
265 break;
266 /* I2S mode has data offset of 1 */
267 case SND_SOC_DAIFMT_I2S:
268 val |= I2S_CTRL_FRAME_FMT_LRCK_MODE;
269 val |= I2S_CTRL_LRCK_POL_LOW;
270 tegra210_i2s_set_data_offset(i2s, 1);
271 break;
272 /*
273 * For RJ mode data offset is dependent on the sample size
274 * and the bclk ratio, and so is set when hw_params is called.
275 */
276 case SND_SOC_DAIFMT_RIGHT_J:
277 val |= I2S_CTRL_FRAME_FMT_LRCK_MODE;
278 val |= I2S_CTRL_LRCK_POL_HIGH;
279 break;
280 case SND_SOC_DAIFMT_LEFT_J:
281 val |= I2S_CTRL_FRAME_FMT_LRCK_MODE;
282 val |= I2S_CTRL_LRCK_POL_HIGH;
283 tegra210_i2s_set_data_offset(i2s, 0);
284 break;
285 default:
286 dev_err(dai->dev, "invalid I2S frame format 0x%x\n", fmt);
287 return -EINVAL;
288 }
289
290 mask |= I2S_CTRL_EDGE_CTRL_MASK;
291 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
292 case SND_SOC_DAIFMT_NB_NF:
293 val |= I2S_CTRL_EDGE_CTRL_POS_EDGE;
294 break;
295 case SND_SOC_DAIFMT_NB_IF:
296 val |= I2S_CTRL_EDGE_CTRL_POS_EDGE;
297 val ^= I2S_CTRL_LRCK_POL_MASK;
298 break;
299 case SND_SOC_DAIFMT_IB_NF:
300 val |= I2S_CTRL_EDGE_CTRL_NEG_EDGE;
301 break;
302 case SND_SOC_DAIFMT_IB_IF:
303 val |= I2S_CTRL_EDGE_CTRL_NEG_EDGE;
304 val ^= I2S_CTRL_LRCK_POL_MASK;
305 break;
306 default:
307 dev_err(dai->dev, "invalid I2S clock inversion 0x%x\n", fmt);
308 return -EINVAL;
309 }
310
311 regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset,
312 mask, val);
313
314 i2s->dai_fmt = fmt & SND_SOC_DAIFMT_FORMAT_MASK;
315
316 return 0;
317 }
318
tegra210_i2s_set_tdm_slot(struct snd_soc_dai * dai,unsigned int tx_mask,unsigned int rx_mask,int slots,int slot_width)319 static int tegra210_i2s_set_tdm_slot(struct snd_soc_dai *dai,
320 unsigned int tx_mask, unsigned int rx_mask,
321 int slots, int slot_width)
322 {
323 struct tegra210_i2s *i2s = snd_soc_dai_get_drvdata(dai);
324
325 /* Copy the required tx and rx mask */
326 i2s->tx_mask = (tx_mask > i2s->soc_data->slot_mask) ?
327 i2s->soc_data->slot_mask : tx_mask;
328 i2s->rx_mask = (rx_mask > i2s->soc_data->slot_mask) ?
329 i2s->soc_data->slot_mask : rx_mask;
330
331 return 0;
332 }
333
tegra210_i2s_get_loopback(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)334 static int tegra210_i2s_get_loopback(struct snd_kcontrol *kcontrol,
335 struct snd_ctl_elem_value *ucontrol)
336 {
337 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
338 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
339
340 ucontrol->value.integer.value[0] = i2s->loopback;
341
342 return 0;
343 }
344
tegra210_i2s_put_loopback(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)345 static int tegra210_i2s_put_loopback(struct snd_kcontrol *kcontrol,
346 struct snd_ctl_elem_value *ucontrol)
347 {
348 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
349 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
350 int value = ucontrol->value.integer.value[0];
351
352 if (value == i2s->loopback)
353 return 0;
354
355 i2s->loopback = value;
356
357 regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset,
358 I2S_CTRL_LPBK_MASK, i2s->loopback << I2S_CTRL_LPBK_SHIFT);
359
360 return 1;
361 }
362
tegra210_i2s_get_fsync_width(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)363 static int tegra210_i2s_get_fsync_width(struct snd_kcontrol *kcontrol,
364 struct snd_ctl_elem_value *ucontrol)
365 {
366 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
367 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
368
369 ucontrol->value.integer.value[0] = i2s->fsync_width;
370
371 return 0;
372 }
373
tegra210_i2s_put_fsync_width(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)374 static int tegra210_i2s_put_fsync_width(struct snd_kcontrol *kcontrol,
375 struct snd_ctl_elem_value *ucontrol)
376 {
377 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
378 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
379 int value = ucontrol->value.integer.value[0];
380
381 if (value == i2s->fsync_width)
382 return 0;
383
384 i2s->fsync_width = value;
385
386 /*
387 * Frame sync width is used only for FSYNC modes and not
388 * applicable for LRCK modes. Reset value for this field is "0",
389 * which means the width is one bit clock wide.
390 * The width requirement may depend on the codec and in such
391 * cases mixer control is used to update custom values. A value
392 * of "N" here means, width is "N + 1" bit clock wide.
393 */
394 regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset,
395 i2s->soc_data->fsync_width_mask,
396 i2s->fsync_width << i2s->soc_data->fsync_width_shift);
397
398 return 1;
399 }
400
tegra210_i2s_cget_stereo_to_mono(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)401 static int tegra210_i2s_cget_stereo_to_mono(struct snd_kcontrol *kcontrol,
402 struct snd_ctl_elem_value *ucontrol)
403 {
404 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
405 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
406
407 ucontrol->value.enumerated.item[0] = i2s->stereo_to_mono[I2S_TX_PATH];
408
409 return 0;
410 }
411
tegra210_i2s_cput_stereo_to_mono(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)412 static int tegra210_i2s_cput_stereo_to_mono(struct snd_kcontrol *kcontrol,
413 struct snd_ctl_elem_value *ucontrol)
414 {
415 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
416 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
417 unsigned int value = ucontrol->value.enumerated.item[0];
418
419 if (value == i2s->stereo_to_mono[I2S_TX_PATH])
420 return 0;
421
422 i2s->stereo_to_mono[I2S_TX_PATH] = value;
423
424 return 1;
425 }
426
tegra210_i2s_cget_mono_to_stereo(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)427 static int tegra210_i2s_cget_mono_to_stereo(struct snd_kcontrol *kcontrol,
428 struct snd_ctl_elem_value *ucontrol)
429 {
430 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
431 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
432
433 ucontrol->value.enumerated.item[0] = i2s->mono_to_stereo[I2S_TX_PATH];
434
435 return 0;
436 }
437
tegra210_i2s_cput_mono_to_stereo(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)438 static int tegra210_i2s_cput_mono_to_stereo(struct snd_kcontrol *kcontrol,
439 struct snd_ctl_elem_value *ucontrol)
440 {
441 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
442 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
443 unsigned int value = ucontrol->value.enumerated.item[0];
444
445 if (value == i2s->mono_to_stereo[I2S_TX_PATH])
446 return 0;
447
448 i2s->mono_to_stereo[I2S_TX_PATH] = value;
449
450 return 1;
451 }
452
tegra210_i2s_pget_stereo_to_mono(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)453 static int tegra210_i2s_pget_stereo_to_mono(struct snd_kcontrol *kcontrol,
454 struct snd_ctl_elem_value *ucontrol)
455 {
456 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
457 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
458
459 ucontrol->value.enumerated.item[0] = i2s->stereo_to_mono[I2S_RX_PATH];
460
461 return 0;
462 }
463
tegra210_i2s_pput_stereo_to_mono(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)464 static int tegra210_i2s_pput_stereo_to_mono(struct snd_kcontrol *kcontrol,
465 struct snd_ctl_elem_value *ucontrol)
466 {
467 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
468 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
469 unsigned int value = ucontrol->value.enumerated.item[0];
470
471 if (value == i2s->stereo_to_mono[I2S_RX_PATH])
472 return 0;
473
474 i2s->stereo_to_mono[I2S_RX_PATH] = value;
475
476 return 1;
477 }
478
tegra210_i2s_pget_mono_to_stereo(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)479 static int tegra210_i2s_pget_mono_to_stereo(struct snd_kcontrol *kcontrol,
480 struct snd_ctl_elem_value *ucontrol)
481 {
482 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
483 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
484
485 ucontrol->value.enumerated.item[0] = i2s->mono_to_stereo[I2S_RX_PATH];
486
487 return 0;
488 }
489
tegra210_i2s_pput_mono_to_stereo(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)490 static int tegra210_i2s_pput_mono_to_stereo(struct snd_kcontrol *kcontrol,
491 struct snd_ctl_elem_value *ucontrol)
492 {
493 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
494 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
495 unsigned int value = ucontrol->value.enumerated.item[0];
496
497 if (value == i2s->mono_to_stereo[I2S_RX_PATH])
498 return 0;
499
500 i2s->mono_to_stereo[I2S_RX_PATH] = value;
501
502 return 1;
503 }
504
tegra210_i2s_pget_fifo_th(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)505 static int tegra210_i2s_pget_fifo_th(struct snd_kcontrol *kcontrol,
506 struct snd_ctl_elem_value *ucontrol)
507 {
508 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
509 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
510
511 ucontrol->value.integer.value[0] = i2s->rx_fifo_th;
512
513 return 0;
514 }
515
tegra210_i2s_pput_fifo_th(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)516 static int tegra210_i2s_pput_fifo_th(struct snd_kcontrol *kcontrol,
517 struct snd_ctl_elem_value *ucontrol)
518 {
519 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
520 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
521 int value = ucontrol->value.integer.value[0];
522
523 if (value == i2s->rx_fifo_th)
524 return 0;
525
526 i2s->rx_fifo_th = value;
527
528 return 1;
529 }
530
tegra210_i2s_get_bclk_ratio(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)531 static int tegra210_i2s_get_bclk_ratio(struct snd_kcontrol *kcontrol,
532 struct snd_ctl_elem_value *ucontrol)
533 {
534 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
535 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
536
537 ucontrol->value.integer.value[0] = i2s->bclk_ratio;
538
539 return 0;
540 }
541
tegra210_i2s_put_bclk_ratio(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)542 static int tegra210_i2s_put_bclk_ratio(struct snd_kcontrol *kcontrol,
543 struct snd_ctl_elem_value *ucontrol)
544 {
545 struct snd_soc_component *compnt = snd_kcontrol_chip(kcontrol);
546 struct tegra210_i2s *i2s = snd_soc_component_get_drvdata(compnt);
547 int value = ucontrol->value.integer.value[0];
548
549 if (value == i2s->bclk_ratio)
550 return 0;
551
552 i2s->bclk_ratio = value;
553
554 return 1;
555 }
556
tegra210_i2s_set_dai_bclk_ratio(struct snd_soc_dai * dai,unsigned int ratio)557 static int tegra210_i2s_set_dai_bclk_ratio(struct snd_soc_dai *dai,
558 unsigned int ratio)
559 {
560 struct tegra210_i2s *i2s = snd_soc_dai_get_drvdata(dai);
561
562 i2s->bclk_ratio = ratio;
563
564 return 0;
565 }
566
tegra210_i2s_set_timing_params(struct device * dev,unsigned int sample_size,unsigned int srate,unsigned int channels)567 static int tegra210_i2s_set_timing_params(struct device *dev,
568 unsigned int sample_size,
569 unsigned int srate,
570 unsigned int channels)
571 {
572 struct tegra210_i2s *i2s = dev_get_drvdata(dev);
573 unsigned int val, bit_count, bclk_rate, num_bclk = sample_size;
574 int err;
575
576 if (i2s->bclk_ratio)
577 num_bclk *= i2s->bclk_ratio;
578
579 if (i2s->dai_fmt == SND_SOC_DAIFMT_RIGHT_J)
580 tegra210_i2s_set_data_offset(i2s, num_bclk - sample_size);
581
582 /* I2S bit clock rate */
583 bclk_rate = srate * channels * num_bclk;
584
585 err = tegra210_i2s_set_clock_rate(dev, bclk_rate);
586 if (err) {
587 dev_err(dev, "can't set I2S bit clock rate %u, err: %d\n",
588 bclk_rate, err);
589 return err;
590 }
591
592 regmap_read(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset, &val);
593
594 /*
595 * For LRCK mode, channel bit count depends on number of bit clocks
596 * on the left channel, where as for FSYNC mode bit count depends on
597 * the number of bit clocks in both left and right channels for DSP
598 * mode or the number of bit clocks in one TDM frame.
599 *
600 */
601 switch (val & I2S_CTRL_FRAME_FMT_MASK) {
602 case I2S_CTRL_FRAME_FMT_LRCK_MODE:
603 bit_count = (bclk_rate / (srate * 2)) - 1;
604 break;
605 case I2S_CTRL_FRAME_FMT_FSYNC_MODE:
606 bit_count = (bclk_rate / srate) - 1;
607
608 tegra210_i2s_set_slot_ctrl(i2s, channels,
609 i2s->tx_mask, i2s->rx_mask);
610 break;
611 default:
612 dev_err(dev, "invalid I2S frame format\n");
613 return -EINVAL;
614 }
615
616 if (bit_count > I2S_TIMING_CH_BIT_CNT_MASK) {
617 dev_err(dev, "invalid I2S channel bit count %u\n", bit_count);
618 return -EINVAL;
619 }
620
621 regmap_write(i2s->regmap, TEGRA210_I2S_TIMING + i2s->soc_data->i2s_ctrl_offset,
622 bit_count << I2S_TIMING_CH_BIT_CNT_SHIFT);
623
624 return 0;
625 }
626
tegra210_i2s_hw_params(struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct snd_soc_dai * dai)627 static int tegra210_i2s_hw_params(struct snd_pcm_substream *substream,
628 struct snd_pcm_hw_params *params,
629 struct snd_soc_dai *dai)
630 {
631 struct device *dev = dai->dev;
632 struct tegra210_i2s *i2s = snd_soc_dai_get_drvdata(dai);
633 unsigned int sample_size, channels, srate, val, reg, path;
634 struct tegra_cif_conf cif_conf;
635 snd_pcm_format_t sample_format;
636
637 memset(&cif_conf, 0, sizeof(struct tegra_cif_conf));
638
639 channels = params_channels(params);
640 if (channels < 1) {
641 dev_err(dev, "invalid I2S %d channel configuration\n",
642 channels);
643 return -EINVAL;
644 }
645
646 cif_conf.audio_ch = channels;
647 cif_conf.client_ch = channels;
648 if (i2s->client_channels)
649 cif_conf.client_ch = i2s->client_channels;
650
651 /* AHUB CIF Audio bits configs */
652 switch (params_format(params)) {
653 case SNDRV_PCM_FORMAT_S8:
654 cif_conf.audio_bits = TEGRA_ACIF_BITS_8;
655 break;
656 case SNDRV_PCM_FORMAT_S16_LE:
657 cif_conf.audio_bits = TEGRA_ACIF_BITS_16;
658 break;
659 case SNDRV_PCM_FORMAT_S24_LE:
660 case SNDRV_PCM_FORMAT_S32_LE:
661 cif_conf.audio_bits = TEGRA_ACIF_BITS_32;
662 break;
663 default:
664 dev_err(dev, "unsupported params audio bit format!\n");
665 return -EOPNOTSUPP;
666 }
667
668 sample_format = params_format(params);
669 if (i2s->client_sample_format >= 0)
670 sample_format = (snd_pcm_format_t)i2s->client_sample_format;
671
672 /*
673 * Format of the I2S for sending/receiving the audio
674 * to/from external device.
675 */
676 switch (sample_format) {
677 case SNDRV_PCM_FORMAT_S8:
678 val = I2S_BITS_8;
679 sample_size = 8;
680 cif_conf.client_bits = TEGRA_ACIF_BITS_8;
681 break;
682 case SNDRV_PCM_FORMAT_S16_LE:
683 val = I2S_BITS_16;
684 sample_size = 16;
685 cif_conf.client_bits = TEGRA_ACIF_BITS_16;
686 break;
687 case SNDRV_PCM_FORMAT_S24_LE:
688 val = I2S_BITS_24;
689 sample_size = 32;
690 cif_conf.client_bits = TEGRA_ACIF_BITS_24;
691 break;
692 case SNDRV_PCM_FORMAT_S32_LE:
693 val = I2S_BITS_32;
694 sample_size = 32;
695 cif_conf.client_bits = TEGRA_ACIF_BITS_32;
696 break;
697 default:
698 dev_err(dev, "unsupported client bit format!\n");
699 return -EOPNOTSUPP;
700 }
701
702 /* Program sample size */
703 regmap_update_bits(i2s->regmap, TEGRA210_I2S_CTRL + i2s->soc_data->i2s_ctrl_offset,
704 I2S_CTRL_BIT_SIZE_MASK, val);
705
706 srate = params_rate(params);
707
708 /* For playback I2S RX-CIF and for capture TX-CIF is used */
709 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
710 path = I2S_RX_PATH;
711 else
712 path = I2S_TX_PATH;
713
714 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
715 unsigned int max_th;
716
717 /* FIFO threshold in terms of frames */
718 max_th = (I2S_RX_FIFO_DEPTH / cif_conf.audio_ch) - 1;
719
720 if (i2s->rx_fifo_th > max_th)
721 i2s->rx_fifo_th = max_th;
722
723 cif_conf.threshold = i2s->rx_fifo_th;
724
725 reg = TEGRA210_I2S_RX_CIF_CTRL;
726 } else {
727 reg = TEGRA210_I2S_TX_CIF_CTRL + i2s->soc_data->tx_offset;
728 }
729
730 cif_conf.mono_conv = i2s->mono_to_stereo[path];
731 cif_conf.stereo_conv = i2s->stereo_to_mono[path];
732
733 if (i2s->soc_data->max_ch == TEGRA264_I2S_MAX_CHANNEL)
734 tegra264_set_cif(i2s->regmap, reg, &cif_conf);
735 else
736 tegra_set_cif(i2s->regmap, reg, &cif_conf);
737
738 return tegra210_i2s_set_timing_params(dev, sample_size, srate,
739 cif_conf.client_ch);
740 }
741
742 static const struct snd_soc_dai_ops tegra210_i2s_dai_ops = {
743 .set_fmt = tegra210_i2s_set_fmt,
744 .hw_params = tegra210_i2s_hw_params,
745 .set_bclk_ratio = tegra210_i2s_set_dai_bclk_ratio,
746 .set_tdm_slot = tegra210_i2s_set_tdm_slot,
747 };
748
749 static struct snd_soc_dai_driver tegra210_i2s_dais[] = {
750 {
751 .name = "I2S-CIF",
752 .playback = {
753 .stream_name = "CIF-Playback",
754 .channels_min = 1,
755 .channels_max = 16,
756 .rates = SNDRV_PCM_RATE_8000_192000,
757 .formats = SNDRV_PCM_FMTBIT_S8 |
758 SNDRV_PCM_FMTBIT_S16_LE |
759 SNDRV_PCM_FMTBIT_S24_LE |
760 SNDRV_PCM_FMTBIT_S32_LE,
761 },
762 .capture = {
763 .stream_name = "CIF-Capture",
764 .channels_min = 1,
765 .channels_max = 16,
766 .rates = SNDRV_PCM_RATE_8000_192000,
767 .formats = SNDRV_PCM_FMTBIT_S8 |
768 SNDRV_PCM_FMTBIT_S16_LE |
769 SNDRV_PCM_FMTBIT_S24_LE |
770 SNDRV_PCM_FMTBIT_S32_LE,
771 },
772 },
773 {
774 .name = "I2S-DAP",
775 .playback = {
776 .stream_name = "DAP-Playback",
777 .channels_min = 1,
778 .channels_max = 16,
779 .rates = SNDRV_PCM_RATE_8000_192000,
780 .formats = SNDRV_PCM_FMTBIT_S8 |
781 SNDRV_PCM_FMTBIT_S16_LE |
782 SNDRV_PCM_FMTBIT_S24_LE |
783 SNDRV_PCM_FMTBIT_S32_LE,
784 },
785 .capture = {
786 .stream_name = "DAP-Capture",
787 .channels_min = 1,
788 .channels_max = 16,
789 .rates = SNDRV_PCM_RATE_8000_192000,
790 .formats = SNDRV_PCM_FMTBIT_S8 |
791 SNDRV_PCM_FMTBIT_S16_LE |
792 SNDRV_PCM_FMTBIT_S24_LE |
793 SNDRV_PCM_FMTBIT_S32_LE,
794 },
795 .ops = &tegra210_i2s_dai_ops,
796 .symmetric_rate = 1,
797 },
798 };
799
800 static const char * const tegra210_i2s_stereo_conv_text[] = {
801 "CH0", "CH1", "AVG",
802 };
803
804 static const char * const tegra210_i2s_mono_conv_text[] = {
805 "Zero", "Copy",
806 };
807
808 static const struct soc_enum tegra210_i2s_mono_conv_enum =
809 SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(tegra210_i2s_mono_conv_text),
810 tegra210_i2s_mono_conv_text);
811
812 static const struct soc_enum tegra210_i2s_stereo_conv_enum =
813 SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(tegra210_i2s_stereo_conv_text),
814 tegra210_i2s_stereo_conv_text);
815
816 static const struct snd_kcontrol_new tegra210_i2s_controls[] = {
817 SOC_SINGLE_EXT("Loopback", 0, 0, 1, 0, tegra210_i2s_get_loopback,
818 tegra210_i2s_put_loopback),
819 SOC_SINGLE_EXT("FSYNC Width", 0, 0, 255, 0,
820 tegra210_i2s_get_fsync_width,
821 tegra210_i2s_put_fsync_width),
822 SOC_ENUM_EXT("Capture Stereo To Mono", tegra210_i2s_stereo_conv_enum,
823 tegra210_i2s_cget_stereo_to_mono,
824 tegra210_i2s_cput_stereo_to_mono),
825 SOC_ENUM_EXT("Capture Mono To Stereo", tegra210_i2s_mono_conv_enum,
826 tegra210_i2s_cget_mono_to_stereo,
827 tegra210_i2s_cput_mono_to_stereo),
828 SOC_ENUM_EXT("Playback Stereo To Mono", tegra210_i2s_stereo_conv_enum,
829 tegra210_i2s_pget_mono_to_stereo,
830 tegra210_i2s_pput_mono_to_stereo),
831 SOC_ENUM_EXT("Playback Mono To Stereo", tegra210_i2s_mono_conv_enum,
832 tegra210_i2s_pget_stereo_to_mono,
833 tegra210_i2s_pput_stereo_to_mono),
834 SOC_SINGLE_EXT("Playback FIFO Threshold", 0, 0, I2S_RX_FIFO_DEPTH - 1,
835 0, tegra210_i2s_pget_fifo_th, tegra210_i2s_pput_fifo_th),
836 SOC_SINGLE_EXT("BCLK Ratio", 0, 0, INT_MAX, 0,
837 tegra210_i2s_get_bclk_ratio,
838 tegra210_i2s_put_bclk_ratio),
839 };
840
841 #define TEGRA_I2S_WIDGETS(tx_enable_reg) \
842 SND_SOC_DAPM_AIF_IN_E("RX", NULL, 0, TEGRA210_I2S_RX_ENABLE, \
843 0, 0, tegra210_i2s_init, SND_SOC_DAPM_PRE_PMU), \
844 SND_SOC_DAPM_AIF_OUT_E("TX", NULL, 0, tx_enable_reg, \
845 0, 0, tegra210_i2s_init, SND_SOC_DAPM_PRE_PMU), \
846 SND_SOC_DAPM_MIC("MIC", NULL), \
847 SND_SOC_DAPM_SPK("SPK", NULL),
848
849 static const struct snd_soc_dapm_widget tegra210_i2s_widgets[] = {
850 TEGRA_I2S_WIDGETS(TEGRA210_I2S_TX_ENABLE)
851 };
852
853 static const struct snd_soc_dapm_widget tegra264_i2s_widgets[] = {
854 TEGRA_I2S_WIDGETS(TEGRA264_I2S_TX_ENABLE)
855 };
856
857 static const struct snd_soc_dapm_route tegra210_i2s_routes[] = {
858 /* Playback route from XBAR */
859 { "XBAR-Playback", NULL, "XBAR-TX" },
860 { "CIF-Playback", NULL, "XBAR-Playback" },
861 { "RX", NULL, "CIF-Playback" },
862 { "DAP-Playback", NULL, "RX" },
863 { "SPK", NULL, "DAP-Playback" },
864 /* Capture route to XBAR */
865 { "XBAR-RX", NULL, "XBAR-Capture" },
866 { "XBAR-Capture", NULL, "CIF-Capture" },
867 { "CIF-Capture", NULL, "TX" },
868 { "TX", NULL, "DAP-Capture" },
869 { "DAP-Capture", NULL, "MIC" },
870 };
871
872 static const struct snd_soc_component_driver tegra210_i2s_cmpnt = {
873 .dapm_widgets = tegra210_i2s_widgets,
874 .num_dapm_widgets = ARRAY_SIZE(tegra210_i2s_widgets),
875 .dapm_routes = tegra210_i2s_routes,
876 .num_dapm_routes = ARRAY_SIZE(tegra210_i2s_routes),
877 .controls = tegra210_i2s_controls,
878 .num_controls = ARRAY_SIZE(tegra210_i2s_controls),
879 };
880
881 static const struct snd_soc_component_driver tegra264_i2s_cmpnt = {
882 .dapm_widgets = tegra264_i2s_widgets,
883 .num_dapm_widgets = ARRAY_SIZE(tegra264_i2s_widgets),
884 .dapm_routes = tegra210_i2s_routes,
885 .num_dapm_routes = ARRAY_SIZE(tegra210_i2s_routes),
886 .controls = tegra210_i2s_controls,
887 .num_controls = ARRAY_SIZE(tegra210_i2s_controls),
888 };
889
tegra210_i2s_wr_reg(struct device * dev,unsigned int reg)890 static bool tegra210_i2s_wr_reg(struct device *dev, unsigned int reg)
891 {
892 switch (reg) {
893 case TEGRA210_I2S_RX_ENABLE ... TEGRA210_I2S_RX_SOFT_RESET:
894 case TEGRA210_I2S_RX_INT_MASK ... TEGRA210_I2S_RX_CLK_TRIM:
895 case TEGRA210_I2S_TX_ENABLE ... TEGRA210_I2S_TX_SOFT_RESET:
896 case TEGRA210_I2S_TX_INT_MASK ... TEGRA210_I2S_TX_CLK_TRIM:
897 case TEGRA210_I2S_ENABLE ... TEGRA210_I2S_CG:
898 case TEGRA210_I2S_CTRL ... TEGRA210_I2S_CYA:
899 return true;
900 default:
901 return false;
902 }
903 }
904
tegra210_i2s_rd_reg(struct device * dev,unsigned int reg)905 static bool tegra210_i2s_rd_reg(struct device *dev, unsigned int reg)
906 {
907 if (tegra210_i2s_wr_reg(dev, reg))
908 return true;
909
910 switch (reg) {
911 case TEGRA210_I2S_RX_STATUS:
912 case TEGRA210_I2S_RX_INT_STATUS:
913 case TEGRA210_I2S_RX_CIF_FIFO_STATUS:
914 case TEGRA210_I2S_TX_STATUS:
915 case TEGRA210_I2S_TX_INT_STATUS:
916 case TEGRA210_I2S_TX_CIF_FIFO_STATUS:
917 case TEGRA210_I2S_STATUS:
918 case TEGRA210_I2S_INT_STATUS:
919 return true;
920 default:
921 return false;
922 }
923 }
924
tegra210_i2s_volatile_reg(struct device * dev,unsigned int reg)925 static bool tegra210_i2s_volatile_reg(struct device *dev, unsigned int reg)
926 {
927 switch (reg) {
928 case TEGRA210_I2S_RX_STATUS:
929 case TEGRA210_I2S_RX_INT_STATUS:
930 case TEGRA210_I2S_RX_CIF_FIFO_STATUS:
931 case TEGRA210_I2S_TX_STATUS:
932 case TEGRA210_I2S_TX_INT_STATUS:
933 case TEGRA210_I2S_TX_CIF_FIFO_STATUS:
934 case TEGRA210_I2S_STATUS:
935 case TEGRA210_I2S_INT_STATUS:
936 case TEGRA210_I2S_RX_SOFT_RESET:
937 case TEGRA210_I2S_TX_SOFT_RESET:
938 return true;
939 default:
940 return false;
941 }
942 }
943
tegra264_i2s_wr_reg(struct device * dev,unsigned int reg)944 static bool tegra264_i2s_wr_reg(struct device *dev, unsigned int reg)
945 {
946 switch (reg) {
947 case TEGRA210_I2S_RX_ENABLE ... TEGRA210_I2S_RX_SOFT_RESET:
948 case TEGRA210_I2S_RX_INT_MASK ... TEGRA264_I2S_RX_CYA:
949 case TEGRA264_I2S_TX_ENABLE ... TEGRA264_I2S_TX_SOFT_RESET:
950 case TEGRA264_I2S_TX_INT_MASK ... TEGRA264_I2S_TX_FIFO_RD_ACCESS_MODE:
951 case TEGRA264_I2S_TX_FIFO_THRESHOLD ... TEGRA264_I2S_TX_CYA:
952 case TEGRA264_I2S_ENABLE ... TEGRA264_I2S_CG:
953 case TEGRA264_I2S_INT_SET ... TEGRA264_I2S_INT_MASK:
954 case TEGRA264_I2S_CTRL ... TEGRA264_I2S_CYA:
955 return true;
956 default:
957 return false;
958 };
959 }
960
tegra264_i2s_rd_reg(struct device * dev,unsigned int reg)961 static bool tegra264_i2s_rd_reg(struct device *dev, unsigned int reg)
962 {
963 if (tegra264_i2s_wr_reg(dev, reg))
964 return true;
965
966 switch (reg) {
967 case TEGRA210_I2S_RX_STATUS:
968 case TEGRA210_I2S_RX_INT_STATUS:
969 case TEGRA264_I2S_RX_CIF_FIFO_STATUS:
970 case TEGRA264_I2S_TX_STATUS:
971 case TEGRA264_I2S_TX_INT_STATUS:
972 case TEGRA264_I2S_TX_FIFO_RD_DATA:
973 case TEGRA264_I2S_TX_CIF_FIFO_STATUS:
974 case TEGRA264_I2S_STATUS:
975 case TEGRA264_I2S_INT_STATUS:
976 case TEGRA264_I2S_PIO_MODE_ENABLE:
977 case TEGRA264_I2S_PAD_MACRO_STATUS:
978 return true;
979 default:
980 return false;
981 };
982 }
983
tegra264_i2s_volatile_reg(struct device * dev,unsigned int reg)984 static bool tegra264_i2s_volatile_reg(struct device *dev, unsigned int reg)
985 {
986 switch (reg) {
987 case TEGRA210_I2S_RX_SOFT_RESET:
988 case TEGRA210_I2S_RX_STATUS:
989 case TEGRA210_I2S_RX_INT_STATUS:
990 case TEGRA264_I2S_RX_CIF_FIFO_STATUS:
991 case TEGRA264_I2S_TX_STATUS:
992 case TEGRA264_I2S_TX_INT_STATUS:
993 case TEGRA264_I2S_TX_FIFO_RD_DATA:
994 case TEGRA264_I2S_TX_CIF_FIFO_STATUS:
995 case TEGRA264_I2S_STATUS:
996 case TEGRA264_I2S_INT_STATUS:
997 case TEGRA264_I2S_TX_SOFT_RESET:
998 case TEGRA264_I2S_PAD_MACRO_STATUS:
999 return true;
1000 default:
1001 return false;
1002 };
1003 }
1004
1005 static const struct regmap_config tegra210_regmap_conf = {
1006 .reg_bits = 32,
1007 .reg_stride = 4,
1008 .val_bits = 32,
1009 .max_register = TEGRA210_I2S_CYA,
1010 .writeable_reg = tegra210_i2s_wr_reg,
1011 .readable_reg = tegra210_i2s_rd_reg,
1012 .volatile_reg = tegra210_i2s_volatile_reg,
1013 .reg_defaults = tegra210_i2s_reg_defaults,
1014 .num_reg_defaults = ARRAY_SIZE(tegra210_i2s_reg_defaults),
1015 .reg_default_cb = regmap_default_zero_cb,
1016 .cache_type = REGCACHE_FLAT,
1017 };
1018
1019 /*
1020 * The AHUB HW modules are interconnected with CIF which are capable of
1021 * supporting Channel and Sample bit format conversion. This needs different
1022 * CIF Audio and client configuration. As one of the config comes from
1023 * params_channels() or params_format(), the extra configuration is passed from
1024 * CIF Port of DT I2S node which can help to perform this conversion.
1025 *
1026 * 4ch audio = 4ch client = 2ch 2ch
1027 * -----> ADMAIF -----------> CIF -------------> I2S ---->
1028 */
tegra210_parse_client_convert(struct device * dev)1029 static void tegra210_parse_client_convert(struct device *dev)
1030 {
1031 struct tegra210_i2s *i2s = dev_get_drvdata(dev);
1032 struct device_node *ports, *ep;
1033 struct simple_util_data data = {};
1034 int cif_port = 0;
1035
1036 ports = of_get_child_by_name(dev->of_node, "ports");
1037 if (ports) {
1038 ep = of_graph_get_endpoint_by_regs(ports, cif_port, -1);
1039 if (ep) {
1040 simple_util_parse_convert(ep, NULL, &data);
1041 of_node_put(ep);
1042 }
1043 of_node_put(ports);
1044 }
1045
1046 if (data.convert_channels)
1047 i2s->client_channels = data.convert_channels;
1048
1049 if (data.convert_sample_format)
1050 i2s->client_sample_format = simple_util_get_sample_fmt(&data);
1051 }
1052
1053 static const struct regmap_config tegra264_regmap_conf = {
1054 .reg_bits = 32,
1055 .reg_stride = 4,
1056 .val_bits = 32,
1057 .max_register = TEGRA264_I2S_PAD_MACRO_STATUS,
1058 .writeable_reg = tegra264_i2s_wr_reg,
1059 .readable_reg = tegra264_i2s_rd_reg,
1060 .volatile_reg = tegra264_i2s_volatile_reg,
1061 .reg_defaults = tegra264_i2s_reg_defaults,
1062 .num_reg_defaults = ARRAY_SIZE(tegra264_i2s_reg_defaults),
1063 .reg_default_cb = regmap_default_zero_cb,
1064 .cache_type = REGCACHE_FLAT,
1065 };
1066
tegra210_i2s_probe(struct platform_device * pdev)1067 static int tegra210_i2s_probe(struct platform_device *pdev)
1068 {
1069 struct device *dev = &pdev->dev;
1070 struct tegra210_i2s *i2s;
1071 void __iomem *regs;
1072 int err, id;
1073
1074 i2s = devm_kzalloc(dev, sizeof(*i2s), GFP_KERNEL);
1075 if (!i2s)
1076 return -ENOMEM;
1077
1078 i2s->soc_data = of_device_get_match_data(&pdev->dev);
1079 i2s->rx_fifo_th = DEFAULT_I2S_RX_FIFO_THRESHOLD;
1080 i2s->tx_mask = i2s->soc_data->slot_mask;
1081 i2s->rx_mask = i2s->soc_data->slot_mask;
1082 i2s->loopback = false;
1083 i2s->client_sample_format = -EINVAL;
1084
1085 dev_set_drvdata(dev, i2s);
1086
1087 i2s->clk_i2s = devm_clk_get(dev, "i2s");
1088 if (IS_ERR(i2s->clk_i2s))
1089 return dev_err_probe(dev, PTR_ERR(i2s->clk_i2s),
1090 "can't retrieve I2S bit clock\n");
1091
1092 /*
1093 * This clock is optional and is only needed when another I/O uses
1094 * the current I2S instance as its input clock, as configured in DT.
1095 */
1096 i2s->clk_sync_input = devm_clk_get_optional(dev, "sync_input");
1097 if (IS_ERR(i2s->clk_sync_input))
1098 return dev_err_probe(dev, PTR_ERR(i2s->clk_sync_input),
1099 "can't retrieve I2S sync input clock\n");
1100
1101 regs = devm_platform_ioremap_resource(pdev, 0);
1102 if (IS_ERR(regs))
1103 return PTR_ERR(regs);
1104
1105 i2s->regmap = devm_regmap_init_mmio(dev, regs,
1106 i2s->soc_data->regmap_conf);
1107 if (IS_ERR(i2s->regmap))
1108 return dev_err_probe(dev, PTR_ERR(i2s->regmap),
1109 "regmap init failed\n");
1110
1111 tegra210_parse_client_convert(dev);
1112
1113 regcache_cache_only(i2s->regmap, true);
1114
1115 /* Update the dais max channel as per soc */
1116 for (id = 0; id < ARRAY_SIZE(tegra210_i2s_dais); id++) {
1117 tegra210_i2s_dais[id].playback.channels_max = i2s->soc_data->max_ch;
1118 tegra210_i2s_dais[id].capture.channels_max = i2s->soc_data->max_ch;
1119 }
1120
1121 err = devm_snd_soc_register_component(dev, i2s->soc_data->i2s_cmpnt,
1122 tegra210_i2s_dais,
1123 ARRAY_SIZE(tegra210_i2s_dais));
1124 if (err)
1125 return dev_err_probe(dev, err,
1126 "can't register I2S component\n");
1127
1128 pm_runtime_enable(dev);
1129
1130 return 0;
1131 }
1132
tegra210_i2s_remove(struct platform_device * pdev)1133 static void tegra210_i2s_remove(struct platform_device *pdev)
1134 {
1135 pm_runtime_disable(&pdev->dev);
1136 }
1137
1138 static const struct dev_pm_ops tegra210_i2s_pm_ops = {
1139 RUNTIME_PM_OPS(tegra210_i2s_runtime_suspend,
1140 tegra210_i2s_runtime_resume, NULL)
1141 SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
1142 };
1143
1144 static const struct tegra_i2s_soc_data soc_data_tegra210 = {
1145 .regmap_conf = &tegra210_regmap_conf,
1146 .i2s_cmpnt = &tegra210_i2s_cmpnt,
1147 .max_ch = TEGRA210_I2S_MAX_CHANNEL,
1148 .enable_reg = TEGRA210_I2S_ENABLE,
1149 .tx_offset = TEGRA210_I2S_TX_OFFSET,
1150 .i2s_ctrl_offset = TEGRA210_I2S_CTRL_OFFSET,
1151 .fsync_width_mask = I2S_CTRL_FSYNC_WIDTH_MASK,
1152 .fsync_width_shift = I2S_FSYNC_WIDTH_SHIFT,
1153 .slot_mask = DEFAULT_I2S_SLOT_MASK,
1154 };
1155
1156 static const struct tegra_i2s_soc_data soc_data_tegra264 = {
1157 .regmap_conf = &tegra264_regmap_conf,
1158 .i2s_cmpnt = &tegra264_i2s_cmpnt,
1159 .max_ch = TEGRA264_I2S_MAX_CHANNEL,
1160 .enable_reg = TEGRA264_I2S_ENABLE,
1161 .tx_offset = TEGRA264_I2S_TX_OFFSET,
1162 .i2s_ctrl_offset = TEGRA264_I2S_CTRL_OFFSET,
1163 .fsync_width_mask = TEGRA264_I2S_CTRL_FSYNC_WIDTH_MASK,
1164 .fsync_width_shift = TEGRA264_I2S_FSYNC_WIDTH_SHIFT,
1165 .slot_mask = TEGRA264_DEFAULT_I2S_SLOT_MASK,
1166 };
1167
1168 static const struct of_device_id tegra210_i2s_of_match[] = {
1169 { .compatible = "nvidia,tegra210-i2s", .data = &soc_data_tegra210 },
1170 { .compatible = "nvidia,tegra264-i2s", .data = &soc_data_tegra264 },
1171 {},
1172 };
1173 MODULE_DEVICE_TABLE(of, tegra210_i2s_of_match);
1174
1175 static struct platform_driver tegra210_i2s_driver = {
1176 .driver = {
1177 .name = "tegra210-i2s",
1178 .of_match_table = tegra210_i2s_of_match,
1179 .pm = pm_ptr(&tegra210_i2s_pm_ops),
1180 },
1181 .probe = tegra210_i2s_probe,
1182 .remove = tegra210_i2s_remove,
1183 };
1184 module_platform_driver(tegra210_i2s_driver)
1185
1186 MODULE_AUTHOR("Songhee Baek <sbaek@nvidia.com>");
1187 MODULE_DESCRIPTION("Tegra210 ASoC I2S driver");
1188 MODULE_LICENSE("GPL v2");
1189