1 // SPDX-License-Identifier: GPL-2.0-only
3 * tegra30_ahub.c - Tegra30 AHUB driver
5 * Copyright (c) 2011,2012, NVIDIA CORPORATION. All rights reserved.
9 #include <linux/device.h>
11 #include <linux/module.h>
12 #include <linux/of_platform.h>
13 #include <linux/platform_device.h>
14 #include <linux/pm_runtime.h>
15 #include <linux/regmap.h>
16 #include <linux/reset.h>
17 #include <linux/slab.h>
18 #include <sound/soc.h>
19 #include "tegra30_ahub.h"
21 #define DRV_NAME "tegra30-ahub"
23 static struct tegra30_ahub
*ahub
;
25 static inline void tegra30_apbif_write(u32 reg
, u32 val
)
27 regmap_write(ahub
->regmap_apbif
, reg
, val
);
30 static inline u32
tegra30_apbif_read(u32 reg
)
34 regmap_read(ahub
->regmap_apbif
, reg
, &val
);
38 static inline void tegra30_audio_write(u32 reg
, u32 val
)
40 regmap_write(ahub
->regmap_ahub
, reg
, val
);
43 static __maybe_unused
int tegra30_ahub_runtime_suspend(struct device
*dev
)
45 regcache_cache_only(ahub
->regmap_apbif
, true);
46 regcache_cache_only(ahub
->regmap_ahub
, true);
48 clk_bulk_disable_unprepare(ahub
->nclocks
, ahub
->clocks
);
54 * clk_apbif isn't required for an I2S<->I2S configuration where no PCM data
55 * is read from or sent to memory. However, that's not something the rest of
56 * the driver supports right now, so we'll just treat the two clocks as one
59 * These functions should not be a plain ref-count. Instead, each active stream
60 * contributes some requirement to the minimum clock rate, so starting or
61 * stopping streams should dynamically adjust the clock as required. However,
62 * this is not yet implemented.
64 static __maybe_unused
int tegra30_ahub_runtime_resume(struct device
*dev
)
68 ret
= reset_control_bulk_assert(ahub
->nresets
, ahub
->resets
);
72 ret
= clk_bulk_prepare_enable(ahub
->nclocks
, ahub
->clocks
);
76 usleep_range(10, 100);
78 ret
= reset_control_bulk_deassert(ahub
->nresets
, ahub
->resets
);
82 regcache_cache_only(ahub
->regmap_apbif
, false);
83 regcache_cache_only(ahub
->regmap_ahub
, false);
84 regcache_mark_dirty(ahub
->regmap_apbif
);
85 regcache_mark_dirty(ahub
->regmap_ahub
);
87 ret
= regcache_sync(ahub
->regmap_apbif
);
91 ret
= regcache_sync(ahub
->regmap_ahub
);
98 clk_bulk_disable_unprepare(ahub
->nclocks
, ahub
->clocks
);
103 int tegra30_ahub_allocate_rx_fifo(enum tegra30_ahub_rxcif
*rxcif
,
104 char *dmachan
, int dmachan_len
,
109 struct tegra30_ahub_cif_conf cif_conf
;
111 channel
= find_first_zero_bit(ahub
->rx_usage
,
112 TEGRA30_AHUB_CHANNEL_CTRL_COUNT
);
113 if (channel
>= TEGRA30_AHUB_CHANNEL_CTRL_COUNT
)
116 __set_bit(channel
, ahub
->rx_usage
);
118 *rxcif
= TEGRA30_AHUB_RXCIF_APBIF_RX0
+ channel
;
119 snprintf(dmachan
, dmachan_len
, "rx%d", channel
);
120 *fiforeg
= ahub
->apbif_addr
+ TEGRA30_AHUB_CHANNEL_RXFIFO
+
121 (channel
* TEGRA30_AHUB_CHANNEL_RXFIFO_STRIDE
);
123 pm_runtime_get_sync(ahub
->dev
);
125 reg
= TEGRA30_AHUB_CHANNEL_CTRL
+
126 (channel
* TEGRA30_AHUB_CHANNEL_CTRL_STRIDE
);
127 val
= tegra30_apbif_read(reg
);
128 val
&= ~(TEGRA30_AHUB_CHANNEL_CTRL_RX_THRESHOLD_MASK
|
129 TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_MASK
);
130 val
|= (7 << TEGRA30_AHUB_CHANNEL_CTRL_RX_THRESHOLD_SHIFT
) |
131 TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_EN
|
132 TEGRA30_AHUB_CHANNEL_CTRL_RX_PACK_16
;
133 tegra30_apbif_write(reg
, val
);
135 cif_conf
.threshold
= 0;
136 cif_conf
.audio_channels
= 2;
137 cif_conf
.client_channels
= 2;
138 cif_conf
.audio_bits
= TEGRA30_AUDIOCIF_BITS_16
;
139 cif_conf
.client_bits
= TEGRA30_AUDIOCIF_BITS_16
;
141 cif_conf
.stereo_conv
= 0;
142 cif_conf
.replicate
= 0;
143 cif_conf
.direction
= TEGRA30_AUDIOCIF_DIRECTION_RX
;
144 cif_conf
.truncate
= 0;
145 cif_conf
.mono_conv
= 0;
147 reg
= TEGRA30_AHUB_CIF_RX_CTRL
+
148 (channel
* TEGRA30_AHUB_CIF_RX_CTRL_STRIDE
);
149 ahub
->soc_data
->set_audio_cif(ahub
->regmap_apbif
, reg
, &cif_conf
);
151 pm_runtime_put(ahub
->dev
);
155 EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_rx_fifo
);
157 int tegra30_ahub_enable_rx_fifo(enum tegra30_ahub_rxcif rxcif
)
159 int channel
= rxcif
- TEGRA30_AHUB_RXCIF_APBIF_RX0
;
162 pm_runtime_get_sync(ahub
->dev
);
164 reg
= TEGRA30_AHUB_CHANNEL_CTRL
+
165 (channel
* TEGRA30_AHUB_CHANNEL_CTRL_STRIDE
);
166 val
= tegra30_apbif_read(reg
);
167 val
|= TEGRA30_AHUB_CHANNEL_CTRL_RX_EN
;
168 tegra30_apbif_write(reg
, val
);
170 pm_runtime_put(ahub
->dev
);
174 EXPORT_SYMBOL_GPL(tegra30_ahub_enable_rx_fifo
);
176 int tegra30_ahub_disable_rx_fifo(enum tegra30_ahub_rxcif rxcif
)
178 int channel
= rxcif
- TEGRA30_AHUB_RXCIF_APBIF_RX0
;
181 pm_runtime_get_sync(ahub
->dev
);
183 reg
= TEGRA30_AHUB_CHANNEL_CTRL
+
184 (channel
* TEGRA30_AHUB_CHANNEL_CTRL_STRIDE
);
185 val
= tegra30_apbif_read(reg
);
186 val
&= ~TEGRA30_AHUB_CHANNEL_CTRL_RX_EN
;
187 tegra30_apbif_write(reg
, val
);
189 pm_runtime_put(ahub
->dev
);
193 EXPORT_SYMBOL_GPL(tegra30_ahub_disable_rx_fifo
);
195 int tegra30_ahub_free_rx_fifo(enum tegra30_ahub_rxcif rxcif
)
197 int channel
= rxcif
- TEGRA30_AHUB_RXCIF_APBIF_RX0
;
199 __clear_bit(channel
, ahub
->rx_usage
);
203 EXPORT_SYMBOL_GPL(tegra30_ahub_free_rx_fifo
);
205 int tegra30_ahub_allocate_tx_fifo(enum tegra30_ahub_txcif
*txcif
,
206 char *dmachan
, int dmachan_len
,
211 struct tegra30_ahub_cif_conf cif_conf
;
213 channel
= find_first_zero_bit(ahub
->tx_usage
,
214 TEGRA30_AHUB_CHANNEL_CTRL_COUNT
);
215 if (channel
>= TEGRA30_AHUB_CHANNEL_CTRL_COUNT
)
218 __set_bit(channel
, ahub
->tx_usage
);
220 *txcif
= TEGRA30_AHUB_TXCIF_APBIF_TX0
+ channel
;
221 snprintf(dmachan
, dmachan_len
, "tx%d", channel
);
222 *fiforeg
= ahub
->apbif_addr
+ TEGRA30_AHUB_CHANNEL_TXFIFO
+
223 (channel
* TEGRA30_AHUB_CHANNEL_TXFIFO_STRIDE
);
225 pm_runtime_get_sync(ahub
->dev
);
227 reg
= TEGRA30_AHUB_CHANNEL_CTRL
+
228 (channel
* TEGRA30_AHUB_CHANNEL_CTRL_STRIDE
);
229 val
= tegra30_apbif_read(reg
);
230 val
&= ~(TEGRA30_AHUB_CHANNEL_CTRL_TX_THRESHOLD_MASK
|
231 TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_MASK
);
232 val
|= (7 << TEGRA30_AHUB_CHANNEL_CTRL_TX_THRESHOLD_SHIFT
) |
233 TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_EN
|
234 TEGRA30_AHUB_CHANNEL_CTRL_TX_PACK_16
;
235 tegra30_apbif_write(reg
, val
);
237 cif_conf
.threshold
= 0;
238 cif_conf
.audio_channels
= 2;
239 cif_conf
.client_channels
= 2;
240 cif_conf
.audio_bits
= TEGRA30_AUDIOCIF_BITS_16
;
241 cif_conf
.client_bits
= TEGRA30_AUDIOCIF_BITS_16
;
243 cif_conf
.stereo_conv
= 0;
244 cif_conf
.replicate
= 0;
245 cif_conf
.direction
= TEGRA30_AUDIOCIF_DIRECTION_TX
;
246 cif_conf
.truncate
= 0;
247 cif_conf
.mono_conv
= 0;
249 reg
= TEGRA30_AHUB_CIF_TX_CTRL
+
250 (channel
* TEGRA30_AHUB_CIF_TX_CTRL_STRIDE
);
251 ahub
->soc_data
->set_audio_cif(ahub
->regmap_apbif
, reg
, &cif_conf
);
253 pm_runtime_put(ahub
->dev
);
257 EXPORT_SYMBOL_GPL(tegra30_ahub_allocate_tx_fifo
);
259 int tegra30_ahub_enable_tx_fifo(enum tegra30_ahub_txcif txcif
)
261 int channel
= txcif
- TEGRA30_AHUB_TXCIF_APBIF_TX0
;
264 pm_runtime_get_sync(ahub
->dev
);
266 reg
= TEGRA30_AHUB_CHANNEL_CTRL
+
267 (channel
* TEGRA30_AHUB_CHANNEL_CTRL_STRIDE
);
268 val
= tegra30_apbif_read(reg
);
269 val
|= TEGRA30_AHUB_CHANNEL_CTRL_TX_EN
;
270 tegra30_apbif_write(reg
, val
);
272 pm_runtime_put(ahub
->dev
);
276 EXPORT_SYMBOL_GPL(tegra30_ahub_enable_tx_fifo
);
278 int tegra30_ahub_disable_tx_fifo(enum tegra30_ahub_txcif txcif
)
280 int channel
= txcif
- TEGRA30_AHUB_TXCIF_APBIF_TX0
;
283 pm_runtime_get_sync(ahub
->dev
);
285 reg
= TEGRA30_AHUB_CHANNEL_CTRL
+
286 (channel
* TEGRA30_AHUB_CHANNEL_CTRL_STRIDE
);
287 val
= tegra30_apbif_read(reg
);
288 val
&= ~TEGRA30_AHUB_CHANNEL_CTRL_TX_EN
;
289 tegra30_apbif_write(reg
, val
);
291 pm_runtime_put(ahub
->dev
);
295 EXPORT_SYMBOL_GPL(tegra30_ahub_disable_tx_fifo
);
297 int tegra30_ahub_free_tx_fifo(enum tegra30_ahub_txcif txcif
)
299 int channel
= txcif
- TEGRA30_AHUB_TXCIF_APBIF_TX0
;
301 __clear_bit(channel
, ahub
->tx_usage
);
305 EXPORT_SYMBOL_GPL(tegra30_ahub_free_tx_fifo
);
307 int tegra30_ahub_set_rx_cif_source(enum tegra30_ahub_rxcif rxcif
,
308 enum tegra30_ahub_txcif txcif
)
310 int channel
= rxcif
- TEGRA30_AHUB_RXCIF_APBIF_RX0
;
313 pm_runtime_get_sync(ahub
->dev
);
315 reg
= TEGRA30_AHUB_AUDIO_RX
+
316 (channel
* TEGRA30_AHUB_AUDIO_RX_STRIDE
);
317 tegra30_audio_write(reg
, 1 << txcif
);
319 pm_runtime_put(ahub
->dev
);
323 EXPORT_SYMBOL_GPL(tegra30_ahub_set_rx_cif_source
);
325 int tegra30_ahub_unset_rx_cif_source(enum tegra30_ahub_rxcif rxcif
)
327 int channel
= rxcif
- TEGRA30_AHUB_RXCIF_APBIF_RX0
;
330 pm_runtime_get_sync(ahub
->dev
);
332 reg
= TEGRA30_AHUB_AUDIO_RX
+
333 (channel
* TEGRA30_AHUB_AUDIO_RX_STRIDE
);
334 tegra30_audio_write(reg
, 0);
336 pm_runtime_put(ahub
->dev
);
340 EXPORT_SYMBOL_GPL(tegra30_ahub_unset_rx_cif_source
);
342 static const struct reset_control_bulk_data tegra30_ahub_resets_data
[] = {
354 { "amx" }, /* Tegra114+ */
355 { "adx" }, /* Tegra114+ */
356 { "amx1" }, /* Tegra124 */
357 { "adx1" }, /* Tegra124 */
358 { "afc0" }, /* Tegra124 */
359 { "afc1" }, /* Tegra124 */
360 { "afc2" }, /* Tegra124 */
361 { "afc3" }, /* Tegra124 */
362 { "afc4" }, /* Tegra124 */
363 { "afc5" }, /* Tegra124 */
366 #define LAST_REG(name) \
367 (TEGRA30_AHUB_##name + \
368 (TEGRA30_AHUB_##name##_STRIDE * TEGRA30_AHUB_##name##_COUNT) - 4)
370 #define REG_IN_ARRAY(reg, name) \
371 ((reg >= TEGRA30_AHUB_##name) && \
372 (reg <= LAST_REG(name) && \
373 (!((reg - TEGRA30_AHUB_##name) % TEGRA30_AHUB_##name##_STRIDE))))
375 static bool tegra30_ahub_apbif_wr_rd_reg(struct device
*dev
, unsigned int reg
)
378 case TEGRA30_AHUB_CONFIG_LINK_CTRL
:
379 case TEGRA30_AHUB_MISC_CTRL
:
380 case TEGRA30_AHUB_APBDMA_LIVE_STATUS
:
381 case TEGRA30_AHUB_I2S_LIVE_STATUS
:
382 case TEGRA30_AHUB_SPDIF_LIVE_STATUS
:
383 case TEGRA30_AHUB_I2S_INT_MASK
:
384 case TEGRA30_AHUB_DAM_INT_MASK
:
385 case TEGRA30_AHUB_SPDIF_INT_MASK
:
386 case TEGRA30_AHUB_APBIF_INT_MASK
:
387 case TEGRA30_AHUB_I2S_INT_STATUS
:
388 case TEGRA30_AHUB_DAM_INT_STATUS
:
389 case TEGRA30_AHUB_SPDIF_INT_STATUS
:
390 case TEGRA30_AHUB_APBIF_INT_STATUS
:
391 case TEGRA30_AHUB_I2S_INT_SOURCE
:
392 case TEGRA30_AHUB_DAM_INT_SOURCE
:
393 case TEGRA30_AHUB_SPDIF_INT_SOURCE
:
394 case TEGRA30_AHUB_APBIF_INT_SOURCE
:
395 case TEGRA30_AHUB_I2S_INT_SET
:
396 case TEGRA30_AHUB_DAM_INT_SET
:
397 case TEGRA30_AHUB_SPDIF_INT_SET
:
398 case TEGRA30_AHUB_APBIF_INT_SET
:
404 if (REG_IN_ARRAY(reg
, CHANNEL_CTRL
) ||
405 REG_IN_ARRAY(reg
, CHANNEL_CLEAR
) ||
406 REG_IN_ARRAY(reg
, CHANNEL_STATUS
) ||
407 REG_IN_ARRAY(reg
, CHANNEL_TXFIFO
) ||
408 REG_IN_ARRAY(reg
, CHANNEL_RXFIFO
) ||
409 REG_IN_ARRAY(reg
, CIF_TX_CTRL
) ||
410 REG_IN_ARRAY(reg
, CIF_RX_CTRL
) ||
411 REG_IN_ARRAY(reg
, DAM_LIVE_STATUS
))
417 static bool tegra30_ahub_apbif_volatile_reg(struct device
*dev
,
421 case TEGRA30_AHUB_CONFIG_LINK_CTRL
:
422 case TEGRA30_AHUB_MISC_CTRL
:
423 case TEGRA30_AHUB_APBDMA_LIVE_STATUS
:
424 case TEGRA30_AHUB_I2S_LIVE_STATUS
:
425 case TEGRA30_AHUB_SPDIF_LIVE_STATUS
:
426 case TEGRA30_AHUB_I2S_INT_STATUS
:
427 case TEGRA30_AHUB_DAM_INT_STATUS
:
428 case TEGRA30_AHUB_SPDIF_INT_STATUS
:
429 case TEGRA30_AHUB_APBIF_INT_STATUS
:
430 case TEGRA30_AHUB_I2S_INT_SET
:
431 case TEGRA30_AHUB_DAM_INT_SET
:
432 case TEGRA30_AHUB_SPDIF_INT_SET
:
433 case TEGRA30_AHUB_APBIF_INT_SET
:
439 if (REG_IN_ARRAY(reg
, CHANNEL_CLEAR
) ||
440 REG_IN_ARRAY(reg
, CHANNEL_STATUS
) ||
441 REG_IN_ARRAY(reg
, CHANNEL_TXFIFO
) ||
442 REG_IN_ARRAY(reg
, CHANNEL_RXFIFO
) ||
443 REG_IN_ARRAY(reg
, DAM_LIVE_STATUS
))
449 static bool tegra30_ahub_apbif_precious_reg(struct device
*dev
,
452 if (REG_IN_ARRAY(reg
, CHANNEL_TXFIFO
) ||
453 REG_IN_ARRAY(reg
, CHANNEL_RXFIFO
))
459 static const struct regmap_config tegra30_ahub_apbif_regmap_config
= {
464 .max_register
= TEGRA30_AHUB_APBIF_INT_SET
,
465 .writeable_reg
= tegra30_ahub_apbif_wr_rd_reg
,
466 .readable_reg
= tegra30_ahub_apbif_wr_rd_reg
,
467 .volatile_reg
= tegra30_ahub_apbif_volatile_reg
,
468 .precious_reg
= tegra30_ahub_apbif_precious_reg
,
469 .cache_type
= REGCACHE_FLAT
,
472 static bool tegra30_ahub_ahub_wr_rd_reg(struct device
*dev
, unsigned int reg
)
474 if (REG_IN_ARRAY(reg
, AUDIO_RX
))
480 static const struct regmap_config tegra30_ahub_ahub_regmap_config
= {
485 .max_register
= LAST_REG(AUDIO_RX
),
486 .writeable_reg
= tegra30_ahub_ahub_wr_rd_reg
,
487 .readable_reg
= tegra30_ahub_ahub_wr_rd_reg
,
488 .cache_type
= REGCACHE_FLAT
,
491 static struct tegra30_ahub_soc_data soc_data_tegra30
= {
493 .set_audio_cif
= tegra30_ahub_set_cif
,
496 static struct tegra30_ahub_soc_data soc_data_tegra114
= {
498 .set_audio_cif
= tegra30_ahub_set_cif
,
501 static struct tegra30_ahub_soc_data soc_data_tegra124
= {
503 .set_audio_cif
= tegra124_ahub_set_cif
,
506 static const struct of_device_id tegra30_ahub_of_match
[] = {
507 { .compatible
= "nvidia,tegra124-ahub", .data
= &soc_data_tegra124
},
508 { .compatible
= "nvidia,tegra114-ahub", .data
= &soc_data_tegra114
},
509 { .compatible
= "nvidia,tegra30-ahub", .data
= &soc_data_tegra30
},
513 static int tegra30_ahub_probe(struct platform_device
*pdev
)
515 const struct tegra30_ahub_soc_data
*soc_data
;
516 struct resource
*res0
;
517 void __iomem
*regs_apbif
, *regs_ahub
;
520 soc_data
= of_device_get_match_data(&pdev
->dev
);
524 ahub
= devm_kzalloc(&pdev
->dev
, sizeof(struct tegra30_ahub
),
528 dev_set_drvdata(&pdev
->dev
, ahub
);
530 BUILD_BUG_ON(sizeof(ahub
->resets
) != sizeof(tegra30_ahub_resets_data
));
531 memcpy(ahub
->resets
, tegra30_ahub_resets_data
, sizeof(ahub
->resets
));
533 ahub
->nresets
= soc_data
->num_resets
;
534 ahub
->soc_data
= soc_data
;
535 ahub
->dev
= &pdev
->dev
;
537 ahub
->clocks
[ahub
->nclocks
++].id
= "apbif";
538 ahub
->clocks
[ahub
->nclocks
++].id
= "d_audio";
540 ret
= devm_clk_bulk_get(&pdev
->dev
, ahub
->nclocks
, ahub
->clocks
);
544 ret
= devm_reset_control_bulk_get_exclusive(&pdev
->dev
, ahub
->nresets
,
547 dev_err(&pdev
->dev
, "Can't get resets: %d\n", ret
);
551 regs_apbif
= devm_platform_get_and_ioremap_resource(pdev
, 0, &res0
);
552 if (IS_ERR(regs_apbif
)) {
553 ret
= PTR_ERR(regs_apbif
);
557 ahub
->apbif_addr
= res0
->start
;
559 ahub
->regmap_apbif
= devm_regmap_init_mmio(&pdev
->dev
, regs_apbif
,
560 &tegra30_ahub_apbif_regmap_config
);
561 if (IS_ERR(ahub
->regmap_apbif
)) {
562 dev_err(&pdev
->dev
, "apbif regmap init failed\n");
563 ret
= PTR_ERR(ahub
->regmap_apbif
);
566 regcache_cache_only(ahub
->regmap_apbif
, true);
568 regs_ahub
= devm_platform_ioremap_resource(pdev
, 1);
569 if (IS_ERR(regs_ahub
)) {
570 ret
= PTR_ERR(regs_ahub
);
574 ahub
->regmap_ahub
= devm_regmap_init_mmio(&pdev
->dev
, regs_ahub
,
575 &tegra30_ahub_ahub_regmap_config
);
576 if (IS_ERR(ahub
->regmap_ahub
)) {
577 dev_err(&pdev
->dev
, "ahub regmap init failed\n");
578 ret
= PTR_ERR(ahub
->regmap_ahub
);
581 regcache_cache_only(ahub
->regmap_ahub
, true);
583 pm_runtime_enable(&pdev
->dev
);
585 of_platform_populate(pdev
->dev
.of_node
, NULL
, NULL
, &pdev
->dev
);
595 static void tegra30_ahub_remove(struct platform_device
*pdev
)
597 pm_runtime_disable(&pdev
->dev
);
602 static const struct dev_pm_ops tegra30_ahub_pm_ops
= {
603 SET_RUNTIME_PM_OPS(tegra30_ahub_runtime_suspend
,
604 tegra30_ahub_runtime_resume
, NULL
)
605 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend
,
606 pm_runtime_force_resume
)
609 static struct platform_driver tegra30_ahub_driver
= {
610 .probe
= tegra30_ahub_probe
,
611 .remove
= tegra30_ahub_remove
,
614 .of_match_table
= tegra30_ahub_of_match
,
615 .pm
= &tegra30_ahub_pm_ops
,
618 module_platform_driver(tegra30_ahub_driver
);
620 void tegra30_ahub_set_cif(struct regmap
*regmap
, unsigned int reg
,
621 struct tegra30_ahub_cif_conf
*conf
)
625 value
= (conf
->threshold
<<
626 TEGRA30_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT
) |
627 ((conf
->audio_channels
- 1) <<
628 TEGRA30_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT
) |
629 ((conf
->client_channels
- 1) <<
630 TEGRA30_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT
) |
632 TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT
) |
633 (conf
->client_bits
<<
634 TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT
) |
636 TEGRA30_AUDIOCIF_CTRL_EXPAND_SHIFT
) |
637 (conf
->stereo_conv
<<
638 TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_SHIFT
) |
640 TEGRA30_AUDIOCIF_CTRL_REPLICATE_SHIFT
) |
642 TEGRA30_AUDIOCIF_CTRL_DIRECTION_SHIFT
) |
644 TEGRA30_AUDIOCIF_CTRL_TRUNCATE_SHIFT
) |
646 TEGRA30_AUDIOCIF_CTRL_MONO_CONV_SHIFT
);
648 regmap_write(regmap
, reg
, value
);
650 EXPORT_SYMBOL_GPL(tegra30_ahub_set_cif
);
652 void tegra124_ahub_set_cif(struct regmap
*regmap
, unsigned int reg
,
653 struct tegra30_ahub_cif_conf
*conf
)
657 value
= (conf
->threshold
<<
658 TEGRA124_AUDIOCIF_CTRL_FIFO_THRESHOLD_SHIFT
) |
659 ((conf
->audio_channels
- 1) <<
660 TEGRA124_AUDIOCIF_CTRL_AUDIO_CHANNELS_SHIFT
) |
661 ((conf
->client_channels
- 1) <<
662 TEGRA124_AUDIOCIF_CTRL_CLIENT_CHANNELS_SHIFT
) |
664 TEGRA30_AUDIOCIF_CTRL_AUDIO_BITS_SHIFT
) |
665 (conf
->client_bits
<<
666 TEGRA30_AUDIOCIF_CTRL_CLIENT_BITS_SHIFT
) |
668 TEGRA30_AUDIOCIF_CTRL_EXPAND_SHIFT
) |
669 (conf
->stereo_conv
<<
670 TEGRA30_AUDIOCIF_CTRL_STEREO_CONV_SHIFT
) |
672 TEGRA30_AUDIOCIF_CTRL_REPLICATE_SHIFT
) |
674 TEGRA30_AUDIOCIF_CTRL_DIRECTION_SHIFT
) |
676 TEGRA30_AUDIOCIF_CTRL_TRUNCATE_SHIFT
) |
678 TEGRA30_AUDIOCIF_CTRL_MONO_CONV_SHIFT
);
680 regmap_write(regmap
, reg
, value
);
682 EXPORT_SYMBOL_GPL(tegra124_ahub_set_cif
);
684 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
685 MODULE_DESCRIPTION("Tegra30 AHUB driver");
686 MODULE_LICENSE("GPL v2");
687 MODULE_ALIAS("platform:" DRV_NAME
);
688 MODULE_DEVICE_TABLE(of
, tegra30_ahub_of_match
);