9
9
#include <linux/io.h>
10
10
#include <linux/mod_devicetable.h>
11
11
#include <linux/module.h>
12
+ #include <linux/of_device.h>
12
13
#include <linux/platform_device.h>
13
14
#include <linux/pm_runtime.h>
14
15
#include <linux/regmap.h>
@@ -32,21 +33,37 @@ static const struct reg_default tegra210_adx_reg_defaults[] = {
32
33
{ TEGRA210_ADX_CFG_RAM_CTRL , 0x00004000 },
33
34
};
34
35
36
+ static const struct reg_default tegra264_adx_reg_defaults [] = {
37
+ { TEGRA210_ADX_RX_INT_MASK , 0x00000001 },
38
+ { TEGRA210_ADX_RX_CIF_CTRL , 0x00003800 },
39
+ { TEGRA210_ADX_TX_INT_MASK , 0x0000000f },
40
+ { TEGRA210_ADX_TX1_CIF_CTRL , 0x00003800 },
41
+ { TEGRA210_ADX_TX2_CIF_CTRL , 0x00003800 },
42
+ { TEGRA210_ADX_TX3_CIF_CTRL , 0x00003800 },
43
+ { TEGRA210_ADX_TX4_CIF_CTRL , 0x00003800 },
44
+ { TEGRA210_ADX_CG , 0x1 },
45
+ { TEGRA264_ADX_CFG_RAM_CTRL , 0x00004000 },
46
+ };
47
+
35
48
static void tegra210_adx_write_map_ram (struct tegra210_adx * adx )
36
49
{
37
50
int i ;
38
51
39
- regmap_write (adx -> regmap , TEGRA210_ADX_CFG_RAM_CTRL ,
52
+ regmap_write (adx -> regmap , TEGRA210_ADX_CFG_RAM_CTRL +
53
+ adx -> soc_data -> cya_offset ,
40
54
TEGRA210_ADX_CFG_RAM_CTRL_SEQ_ACCESS_EN |
41
55
TEGRA210_ADX_CFG_RAM_CTRL_ADDR_INIT_EN |
42
56
TEGRA210_ADX_CFG_RAM_CTRL_RW_WRITE );
43
57
44
- for (i = 0 ; i < TEGRA210_ADX_RAM_DEPTH ; i ++ )
45
- regmap_write (adx -> regmap , TEGRA210_ADX_CFG_RAM_DATA ,
58
+ for (i = 0 ; i < adx -> soc_data -> ram_depth ; i ++ )
59
+ regmap_write (adx -> regmap , TEGRA210_ADX_CFG_RAM_DATA +
60
+ adx -> soc_data -> cya_offset ,
46
61
adx -> map [i ]);
47
62
48
- regmap_write (adx -> regmap , TEGRA210_ADX_IN_BYTE_EN0 , adx -> byte_mask [0 ]);
49
- regmap_write (adx -> regmap , TEGRA210_ADX_IN_BYTE_EN1 , adx -> byte_mask [1 ]);
63
+ for (i = 0 ; i < adx -> soc_data -> byte_mask_size ; i ++ )
64
+ regmap_write (adx -> regmap ,
65
+ TEGRA210_ADX_IN_BYTE_EN0 + (i * TEGRA210_ADX_AUDIOCIF_CH_STRIDE ),
66
+ adx -> byte_mask [i ]);
50
67
}
51
68
52
69
static int tegra210_adx_startup (struct snd_pcm_substream * substream ,
@@ -117,7 +134,7 @@ static int tegra210_adx_set_audio_cif(struct snd_soc_dai *dai,
117
134
118
135
memset (& cif_conf , 0 , sizeof (struct tegra_cif_conf ));
119
136
120
- if (channels < 1 || channels > 16 )
137
+ if (channels < 1 || channels > adx -> soc_data -> max_ch )
121
138
return - EINVAL ;
122
139
123
140
switch (format ) {
@@ -140,7 +157,10 @@ static int tegra210_adx_set_audio_cif(struct snd_soc_dai *dai,
140
157
cif_conf .audio_bits = audio_bits ;
141
158
cif_conf .client_bits = audio_bits ;
142
159
143
- tegra_set_cif (adx -> regmap , reg , & cif_conf );
160
+ if (adx -> soc_data -> max_ch == 32 )
161
+ tegra264_set_cif (adx -> regmap , reg , & cif_conf );
162
+ else
163
+ tegra_set_cif (adx -> regmap , reg , & cif_conf );
144
164
145
165
return 0 ;
146
166
}
@@ -169,7 +189,7 @@ static int tegra210_adx_get_byte_map(struct snd_kcontrol *kcontrol,
169
189
struct snd_soc_component * cmpnt = snd_soc_kcontrol_component (kcontrol );
170
190
struct tegra210_adx * adx = snd_soc_component_get_drvdata (cmpnt );
171
191
struct soc_mixer_control * mc ;
172
- unsigned char * bytes_map = (unsigned char * )& adx -> map ;
192
+ unsigned char * bytes_map = (unsigned char * )adx -> map ;
173
193
int enabled ;
174
194
175
195
mc = (struct soc_mixer_control * )kcontrol -> private_value ;
@@ -198,7 +218,7 @@ static int tegra210_adx_put_byte_map(struct snd_kcontrol *kcontrol,
198
218
{
199
219
struct snd_soc_component * cmpnt = snd_soc_kcontrol_component (kcontrol );
200
220
struct tegra210_adx * adx = snd_soc_component_get_drvdata (cmpnt );
201
- unsigned char * bytes_map = (unsigned char * )& adx -> map ;
221
+ unsigned char * bytes_map = (unsigned char * )adx -> map ;
202
222
int value = ucontrol -> value .integer .value [0 ];
203
223
struct soc_mixer_control * mc =
204
224
(struct soc_mixer_control * )kcontrol -> private_value ;
@@ -402,7 +422,90 @@ static struct snd_kcontrol_new tegra210_adx_controls[] = {
402
422
TEGRA210_ADX_BYTE_MAP_CTRL (63 ),
403
423
};
404
424
425
+ static struct snd_kcontrol_new tegra264_adx_controls [] = {
426
+ TEGRA210_ADX_BYTE_MAP_CTRL (64 ),
427
+ TEGRA210_ADX_BYTE_MAP_CTRL (65 ),
428
+ TEGRA210_ADX_BYTE_MAP_CTRL (66 ),
429
+ TEGRA210_ADX_BYTE_MAP_CTRL (67 ),
430
+ TEGRA210_ADX_BYTE_MAP_CTRL (68 ),
431
+ TEGRA210_ADX_BYTE_MAP_CTRL (69 ),
432
+ TEGRA210_ADX_BYTE_MAP_CTRL (70 ),
433
+ TEGRA210_ADX_BYTE_MAP_CTRL (71 ),
434
+ TEGRA210_ADX_BYTE_MAP_CTRL (72 ),
435
+ TEGRA210_ADX_BYTE_MAP_CTRL (73 ),
436
+ TEGRA210_ADX_BYTE_MAP_CTRL (74 ),
437
+ TEGRA210_ADX_BYTE_MAP_CTRL (75 ),
438
+ TEGRA210_ADX_BYTE_MAP_CTRL (76 ),
439
+ TEGRA210_ADX_BYTE_MAP_CTRL (77 ),
440
+ TEGRA210_ADX_BYTE_MAP_CTRL (78 ),
441
+ TEGRA210_ADX_BYTE_MAP_CTRL (79 ),
442
+ TEGRA210_ADX_BYTE_MAP_CTRL (80 ),
443
+ TEGRA210_ADX_BYTE_MAP_CTRL (81 ),
444
+ TEGRA210_ADX_BYTE_MAP_CTRL (82 ),
445
+ TEGRA210_ADX_BYTE_MAP_CTRL (83 ),
446
+ TEGRA210_ADX_BYTE_MAP_CTRL (84 ),
447
+ TEGRA210_ADX_BYTE_MAP_CTRL (85 ),
448
+ TEGRA210_ADX_BYTE_MAP_CTRL (86 ),
449
+ TEGRA210_ADX_BYTE_MAP_CTRL (87 ),
450
+ TEGRA210_ADX_BYTE_MAP_CTRL (88 ),
451
+ TEGRA210_ADX_BYTE_MAP_CTRL (89 ),
452
+ TEGRA210_ADX_BYTE_MAP_CTRL (90 ),
453
+ TEGRA210_ADX_BYTE_MAP_CTRL (91 ),
454
+ TEGRA210_ADX_BYTE_MAP_CTRL (92 ),
455
+ TEGRA210_ADX_BYTE_MAP_CTRL (93 ),
456
+ TEGRA210_ADX_BYTE_MAP_CTRL (94 ),
457
+ TEGRA210_ADX_BYTE_MAP_CTRL (95 ),
458
+ TEGRA210_ADX_BYTE_MAP_CTRL (96 ),
459
+ TEGRA210_ADX_BYTE_MAP_CTRL (97 ),
460
+ TEGRA210_ADX_BYTE_MAP_CTRL (98 ),
461
+ TEGRA210_ADX_BYTE_MAP_CTRL (99 ),
462
+ TEGRA210_ADX_BYTE_MAP_CTRL (100 ),
463
+ TEGRA210_ADX_BYTE_MAP_CTRL (101 ),
464
+ TEGRA210_ADX_BYTE_MAP_CTRL (102 ),
465
+ TEGRA210_ADX_BYTE_MAP_CTRL (103 ),
466
+ TEGRA210_ADX_BYTE_MAP_CTRL (104 ),
467
+ TEGRA210_ADX_BYTE_MAP_CTRL (105 ),
468
+ TEGRA210_ADX_BYTE_MAP_CTRL (106 ),
469
+ TEGRA210_ADX_BYTE_MAP_CTRL (107 ),
470
+ TEGRA210_ADX_BYTE_MAP_CTRL (108 ),
471
+ TEGRA210_ADX_BYTE_MAP_CTRL (109 ),
472
+ TEGRA210_ADX_BYTE_MAP_CTRL (110 ),
473
+ TEGRA210_ADX_BYTE_MAP_CTRL (111 ),
474
+ TEGRA210_ADX_BYTE_MAP_CTRL (112 ),
475
+ TEGRA210_ADX_BYTE_MAP_CTRL (113 ),
476
+ TEGRA210_ADX_BYTE_MAP_CTRL (114 ),
477
+ TEGRA210_ADX_BYTE_MAP_CTRL (115 ),
478
+ TEGRA210_ADX_BYTE_MAP_CTRL (116 ),
479
+ TEGRA210_ADX_BYTE_MAP_CTRL (117 ),
480
+ TEGRA210_ADX_BYTE_MAP_CTRL (118 ),
481
+ TEGRA210_ADX_BYTE_MAP_CTRL (119 ),
482
+ TEGRA210_ADX_BYTE_MAP_CTRL (120 ),
483
+ TEGRA210_ADX_BYTE_MAP_CTRL (121 ),
484
+ TEGRA210_ADX_BYTE_MAP_CTRL (122 ),
485
+ TEGRA210_ADX_BYTE_MAP_CTRL (123 ),
486
+ TEGRA210_ADX_BYTE_MAP_CTRL (124 ),
487
+ TEGRA210_ADX_BYTE_MAP_CTRL (125 ),
488
+ TEGRA210_ADX_BYTE_MAP_CTRL (126 ),
489
+ TEGRA210_ADX_BYTE_MAP_CTRL (127 ),
490
+ };
491
+
492
+ static int tegra210_adx_component_probe (struct snd_soc_component * component )
493
+ {
494
+ struct tegra210_adx * adx = snd_soc_component_get_drvdata (component );
495
+ int err = 0 ;
496
+
497
+ if (adx -> soc_data -> num_controls ) {
498
+ err = snd_soc_add_component_controls (component , adx -> soc_data -> controls ,
499
+ adx -> soc_data -> num_controls );
500
+ if (err )
501
+ dev_err (component -> dev , "can't add ADX controls, err: %d\n" , err );
502
+ }
503
+
504
+ return err ;
505
+ }
506
+
405
507
static const struct snd_soc_component_driver tegra210_adx_cmpnt = {
508
+ .probe = tegra210_adx_component_probe ,
406
509
.dapm_widgets = tegra210_adx_widgets ,
407
510
.num_dapm_widgets = ARRAY_SIZE (tegra210_adx_widgets ),
408
511
.dapm_routes = tegra210_adx_routes ,
@@ -460,6 +563,58 @@ static bool tegra210_adx_volatile_reg(struct device *dev,
460
563
return false;
461
564
}
462
565
566
+ static bool tegra264_adx_wr_reg (struct device * dev ,
567
+ unsigned int reg )
568
+ {
569
+ switch (reg ) {
570
+ case TEGRA210_ADX_TX_INT_MASK ... TEGRA210_ADX_TX4_CIF_CTRL :
571
+ case TEGRA210_ADX_RX_INT_MASK ... TEGRA210_ADX_RX_CIF_CTRL :
572
+ case TEGRA210_ADX_ENABLE ... TEGRA210_ADX_CG :
573
+ case TEGRA210_ADX_CTRL ... TEGRA264_ADX_CYA :
574
+ case TEGRA264_ADX_CFG_RAM_CTRL ... TEGRA264_ADX_CFG_RAM_DATA :
575
+ return true;
576
+ default :
577
+ return false;
578
+ }
579
+ }
580
+
581
+ static bool tegra264_adx_rd_reg (struct device * dev ,
582
+ unsigned int reg )
583
+ {
584
+ switch (reg ) {
585
+ case TEGRA210_ADX_RX_STATUS ... TEGRA210_ADX_RX_CIF_CTRL :
586
+ case TEGRA210_ADX_TX_STATUS ... TEGRA210_ADX_TX4_CIF_CTRL :
587
+ case TEGRA210_ADX_ENABLE ... TEGRA210_ADX_INT_STATUS :
588
+ case TEGRA210_ADX_CTRL ... TEGRA264_ADX_CFG_RAM_DATA :
589
+ return true;
590
+ default :
591
+ return false;
592
+ }
593
+ }
594
+
595
+ static bool tegra264_adx_volatile_reg (struct device * dev ,
596
+ unsigned int reg )
597
+ {
598
+ switch (reg ) {
599
+ case TEGRA210_ADX_RX_STATUS :
600
+ case TEGRA210_ADX_RX_INT_STATUS :
601
+ case TEGRA210_ADX_RX_INT_SET :
602
+ case TEGRA210_ADX_TX_STATUS :
603
+ case TEGRA210_ADX_TX_INT_STATUS :
604
+ case TEGRA210_ADX_TX_INT_SET :
605
+ case TEGRA210_ADX_SOFT_RESET :
606
+ case TEGRA210_ADX_STATUS :
607
+ case TEGRA210_ADX_INT_STATUS :
608
+ case TEGRA264_ADX_CFG_RAM_CTRL :
609
+ case TEGRA264_ADX_CFG_RAM_DATA :
610
+ return true;
611
+ default :
612
+ break ;
613
+ }
614
+
615
+ return false;
616
+ }
617
+
463
618
static const struct regmap_config tegra210_adx_regmap_config = {
464
619
.reg_bits = 32 ,
465
620
.reg_stride = 4 ,
@@ -473,8 +628,40 @@ static const struct regmap_config tegra210_adx_regmap_config = {
473
628
.cache_type = REGCACHE_FLAT ,
474
629
};
475
630
631
+ static const struct regmap_config tegra264_adx_regmap_config = {
632
+ .reg_bits = 32 ,
633
+ .reg_stride = 4 ,
634
+ .val_bits = 32 ,
635
+ .max_register = TEGRA264_ADX_CFG_RAM_DATA ,
636
+ .writeable_reg = tegra264_adx_wr_reg ,
637
+ .readable_reg = tegra264_adx_rd_reg ,
638
+ .volatile_reg = tegra264_adx_volatile_reg ,
639
+ .reg_defaults = tegra264_adx_reg_defaults ,
640
+ .num_reg_defaults = ARRAY_SIZE (tegra264_adx_reg_defaults ),
641
+ .cache_type = REGCACHE_FLAT ,
642
+ };
643
+
644
+ static const struct tegra210_adx_soc_data soc_data_tegra210 = {
645
+ .regmap_conf = & tegra210_adx_regmap_config ,
646
+ .max_ch = TEGRA210_ADX_MAX_CHANNEL ,
647
+ .ram_depth = TEGRA210_ADX_RAM_DEPTH ,
648
+ .byte_mask_size = TEGRA210_ADX_BYTE_MASK_COUNT ,
649
+ .cya_offset = TEGRA210_ADX_CYA_OFFSET ,
650
+ };
651
+
652
+ static const struct tegra210_adx_soc_data soc_data_tegra264 = {
653
+ .regmap_conf = & tegra264_adx_regmap_config ,
654
+ .max_ch = TEGRA264_ADX_MAX_CHANNEL ,
655
+ .ram_depth = TEGRA264_ADX_RAM_DEPTH ,
656
+ .byte_mask_size = TEGRA264_ADX_BYTE_MASK_COUNT ,
657
+ .cya_offset = TEGRA264_ADX_CYA_OFFSET ,
658
+ .controls = tegra264_adx_controls ,
659
+ .num_controls = ARRAY_SIZE (tegra264_adx_controls ),
660
+ };
661
+
476
662
static const struct of_device_id tegra210_adx_of_match [] = {
477
- { .compatible = "nvidia,tegra210-adx" },
663
+ { .compatible = "nvidia,tegra210-adx" , .data = & soc_data_tegra210 },
664
+ { .compatible = "nvidia,tegra264-adx" , .data = & soc_data_tegra264 },
478
665
{},
479
666
};
480
667
MODULE_DEVICE_TABLE (of , tegra210_adx_of_match );
@@ -483,28 +670,48 @@ static int tegra210_adx_platform_probe(struct platform_device *pdev)
483
670
{
484
671
struct device * dev = & pdev -> dev ;
485
672
struct tegra210_adx * adx ;
673
+ const struct of_device_id * match ;
674
+ struct tegra210_adx_soc_data * soc_data ;
486
675
void __iomem * regs ;
487
676
int err ;
488
677
489
678
adx = devm_kzalloc (dev , sizeof (* adx ), GFP_KERNEL );
490
679
if (!adx )
491
680
return - ENOMEM ;
492
681
682
+ match = of_match_device (tegra210_adx_of_match , dev );
683
+ soc_data = (struct tegra210_adx_soc_data * )match -> data ;
684
+ adx -> soc_data = soc_data ;
685
+
493
686
dev_set_drvdata (dev , adx );
494
687
495
688
regs = devm_platform_ioremap_resource (pdev , 0 );
496
689
if (IS_ERR (regs ))
497
690
return PTR_ERR (regs );
498
691
499
692
adx -> regmap = devm_regmap_init_mmio (dev , regs ,
500
- & tegra210_adx_regmap_config );
693
+ soc_data -> regmap_conf );
501
694
if (IS_ERR (adx -> regmap )) {
502
695
dev_err (dev , "regmap init failed\n" );
503
696
return PTR_ERR (adx -> regmap );
504
697
}
505
698
506
699
regcache_cache_only (adx -> regmap , true);
507
700
701
+ adx -> map = devm_kzalloc (dev , soc_data -> ram_depth * sizeof (* adx -> map ),
702
+ GFP_KERNEL );
703
+ if (!adx -> map )
704
+ return - ENOMEM ;
705
+
706
+ adx -> byte_mask = devm_kzalloc (dev ,
707
+ soc_data -> byte_mask_size * sizeof (* adx -> byte_mask ),
708
+ GFP_KERNEL );
709
+ if (!adx -> byte_mask )
710
+ return - ENOMEM ;
711
+
712
+ tegra210_adx_dais [TEGRA_ADX_IN_DAI_ID ].playback .channels_max =
713
+ adx -> soc_data -> max_ch ;
714
+
508
715
err = devm_snd_soc_register_component (dev , & tegra210_adx_cmpnt ,
509
716
tegra210_adx_dais ,
510
717
ARRAY_SIZE (tegra210_adx_dais ));
0 commit comments