99#include <linux/io.h>
1010#include <linux/mod_devicetable.h>
1111#include <linux/module.h>
12+ #include <linux/of_device.h>
1213#include <linux/platform_device.h>
1314#include <linux/pm_runtime.h>
1415#include <linux/regmap.h>
@@ -32,21 +33,37 @@ static const struct reg_default tegra210_adx_reg_defaults[] = {
3233 { TEGRA210_ADX_CFG_RAM_CTRL , 0x00004000 },
3334};
3435
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+
3548static void tegra210_adx_write_map_ram (struct tegra210_adx * adx )
3649{
3750 int i ;
3851
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 ,
4054 TEGRA210_ADX_CFG_RAM_CTRL_SEQ_ACCESS_EN |
4155 TEGRA210_ADX_CFG_RAM_CTRL_ADDR_INIT_EN |
4256 TEGRA210_ADX_CFG_RAM_CTRL_RW_WRITE );
4357
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 ,
4661 adx -> map [i ]);
4762
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 ]);
5067}
5168
5269static 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,
117134
118135 memset (& cif_conf , 0 , sizeof (struct tegra_cif_conf ));
119136
120- if (channels < 1 || channels > 16 )
137+ if (channels < 1 || channels > adx -> soc_data -> max_ch )
121138 return - EINVAL ;
122139
123140 switch (format ) {
@@ -140,7 +157,10 @@ static int tegra210_adx_set_audio_cif(struct snd_soc_dai *dai,
140157 cif_conf .audio_bits = audio_bits ;
141158 cif_conf .client_bits = audio_bits ;
142159
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 );
144164
145165 return 0 ;
146166}
@@ -169,7 +189,7 @@ static int tegra210_adx_get_byte_map(struct snd_kcontrol *kcontrol,
169189 struct snd_soc_component * cmpnt = snd_soc_kcontrol_component (kcontrol );
170190 struct tegra210_adx * adx = snd_soc_component_get_drvdata (cmpnt );
171191 struct soc_mixer_control * mc ;
172- unsigned char * bytes_map = (unsigned char * )& adx -> map ;
192+ unsigned char * bytes_map = (unsigned char * )adx -> map ;
173193 int enabled ;
174194
175195 mc = (struct soc_mixer_control * )kcontrol -> private_value ;
@@ -198,7 +218,7 @@ static int tegra210_adx_put_byte_map(struct snd_kcontrol *kcontrol,
198218{
199219 struct snd_soc_component * cmpnt = snd_soc_kcontrol_component (kcontrol );
200220 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 ;
202222 int value = ucontrol -> value .integer .value [0 ];
203223 struct soc_mixer_control * mc =
204224 (struct soc_mixer_control * )kcontrol -> private_value ;
@@ -402,7 +422,90 @@ static struct snd_kcontrol_new tegra210_adx_controls[] = {
402422 TEGRA210_ADX_BYTE_MAP_CTRL (63 ),
403423};
404424
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+
405507static const struct snd_soc_component_driver tegra210_adx_cmpnt = {
508+ .probe = tegra210_adx_component_probe ,
406509 .dapm_widgets = tegra210_adx_widgets ,
407510 .num_dapm_widgets = ARRAY_SIZE (tegra210_adx_widgets ),
408511 .dapm_routes = tegra210_adx_routes ,
@@ -460,6 +563,58 @@ static bool tegra210_adx_volatile_reg(struct device *dev,
460563 return false;
461564}
462565
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+
463618static const struct regmap_config tegra210_adx_regmap_config = {
464619 .reg_bits = 32 ,
465620 .reg_stride = 4 ,
@@ -473,8 +628,40 @@ static const struct regmap_config tegra210_adx_regmap_config = {
473628 .cache_type = REGCACHE_FLAT ,
474629};
475630
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+
476662static 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 },
478665 {},
479666};
480667MODULE_DEVICE_TABLE (of , tegra210_adx_of_match );
@@ -483,28 +670,48 @@ static int tegra210_adx_platform_probe(struct platform_device *pdev)
483670{
484671 struct device * dev = & pdev -> dev ;
485672 struct tegra210_adx * adx ;
673+ const struct of_device_id * match ;
674+ struct tegra210_adx_soc_data * soc_data ;
486675 void __iomem * regs ;
487676 int err ;
488677
489678 adx = devm_kzalloc (dev , sizeof (* adx ), GFP_KERNEL );
490679 if (!adx )
491680 return - ENOMEM ;
492681
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+
493686 dev_set_drvdata (dev , adx );
494687
495688 regs = devm_platform_ioremap_resource (pdev , 0 );
496689 if (IS_ERR (regs ))
497690 return PTR_ERR (regs );
498691
499692 adx -> regmap = devm_regmap_init_mmio (dev , regs ,
500- & tegra210_adx_regmap_config );
693+ soc_data -> regmap_conf );
501694 if (IS_ERR (adx -> regmap )) {
502695 dev_err (dev , "regmap init failed\n" );
503696 return PTR_ERR (adx -> regmap );
504697 }
505698
506699 regcache_cache_only (adx -> regmap , true);
507700
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+
508715 err = devm_snd_soc_register_component (dev , & tegra210_adx_cmpnt ,
509716 tegra210_adx_dais ,
510717 ARRAY_SIZE (tegra210_adx_dais ));
0 commit comments