@@ -93,47 +93,36 @@ module_param(firmware_autostart, bool, 0444);
9393MODULE_PARM_DESC (firmware_autostart , "Allow automatic firmware download on boot"
9494 "(0=Disable, 1=Enable) (default=1); " );
9595
96+ static const char channel_name [3 ] = { 'L' , 'R' , 'C' };
97+
9698static const struct reg_sequence cs35l41_hda_config [] = {
9799 { CS35L41_PLL_CLK_CTRL , 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1
98100 { CS35L41_DSP_CLK_CTRL , 0x00000003 }, // DSP CLK EN
99101 { CS35L41_GLOBAL_CLK_CTRL , 0x00000003 }, // GLOBAL_FS = 48 kHz
100- { CS35L41_SP_ENABLES , 0x00010000 }, // ASP_RX1_EN = 1
101102 { CS35L41_SP_RATE_CTRL , 0x00000021 }, // ASP_BCLK_FREQ = 3.072 MHz
102103 { CS35L41_SP_FORMAT , 0x20200200 }, // 32 bits RX/TX slots, I2S, clk consumer
103- { CS35L41_SP_HIZ_CTRL , 0x00000002 }, // Hi-Z unused
104104 { CS35L41_SP_TX_WL , 0x00000018 }, // 24 cycles/slot
105105 { CS35L41_SP_RX_WL , 0x00000018 }, // 24 cycles/slot
106- { CS35L41_DAC_PCM1_SRC , 0x00000008 }, // DACPCM1_SRC = ASPRX1
107106 { CS35L41_ASP_TX1_SRC , 0x00000018 }, // ASPTX1 SRC = VMON
108107 { CS35L41_ASP_TX2_SRC , 0x00000019 }, // ASPTX2 SRC = IMON
109- { CS35L41_ASP_TX3_SRC , 0x00000032 }, // ASPTX3 SRC = ERRVOL
110- { CS35L41_ASP_TX4_SRC , 0x00000033 }, // ASPTX4 SRC = CLASSH_TGT
111- { CS35L41_DSP1_RX1_SRC , 0x00000008 }, // DSP1RX1 SRC = ASPRX1
112- { CS35L41_DSP1_RX2_SRC , 0x00000009 }, // DSP1RX2 SRC = ASPRX2
113108 { CS35L41_DSP1_RX3_SRC , 0x00000018 }, // DSP1RX3 SRC = VMON
114109 { CS35L41_DSP1_RX4_SRC , 0x00000019 }, // DSP1RX4 SRC = IMON
110+ };
111+
112+ static const struct reg_sequence cs35l41_hda_config_no_dsp [] = {
113+ { CS35L41_SP_HIZ_CTRL , 0x00000002 }, // Hi-Z unused
114+ { CS35L41_DAC_PCM1_SRC , 0x00000008 }, // DACPCM1_SRC = ASPRX1
115+ { CS35L41_ASP_TX3_SRC , 0x00000000 }, // ASPTX3 SRC = ZERO FILL
116+ { CS35L41_ASP_TX4_SRC , 0x00000000 }, // ASPTX4 SRC = ZERO FILL
115117 { CS35L41_DSP1_RX5_SRC , 0x00000020 }, // DSP1RX5 SRC = ERRVOL
118+ { CS35L41_DSP1_RX6_SRC , 0x00000021 }, // DSP1RX6 SRC = CLASSH_TGT
116119};
117120
118121static const struct reg_sequence cs35l41_hda_config_dsp [] = {
119- { CS35L41_PLL_CLK_CTRL , 0x00000430 }, // 3072000Hz, BCLK Input, PLL_REFCLK_EN = 1
120- { CS35L41_DSP_CLK_CTRL , 0x00000003 }, // DSP CLK EN
121- { CS35L41_GLOBAL_CLK_CTRL , 0x00000003 }, // GLOBAL_FS = 48 kHz
122- { CS35L41_SP_ENABLES , 0x00010001 }, // ASP_RX1_EN = 1, ASP_TX1_EN = 1
123- { CS35L41_SP_RATE_CTRL , 0x00000021 }, // ASP_BCLK_FREQ = 3.072 MHz
124- { CS35L41_SP_FORMAT , 0x20200200 }, // 32 bits RX/TX slots, I2S, clk consumer
125122 { CS35L41_SP_HIZ_CTRL , 0x00000003 }, // Hi-Z unused/disabled
126- { CS35L41_SP_TX_WL , 0x00000018 }, // 24 cycles/slot
127- { CS35L41_SP_RX_WL , 0x00000018 }, // 24 cycles/slot
128123 { CS35L41_DAC_PCM1_SRC , 0x00000032 }, // DACPCM1_SRC = DSP1TX1
129- { CS35L41_ASP_TX1_SRC , 0x00000018 }, // ASPTX1 SRC = VMON
130- { CS35L41_ASP_TX2_SRC , 0x00000019 }, // ASPTX2 SRC = IMON
131124 { CS35L41_ASP_TX3_SRC , 0x00000028 }, // ASPTX3 SRC = VPMON
132125 { CS35L41_ASP_TX4_SRC , 0x00000029 }, // ASPTX4 SRC = VBSTMON
133- { CS35L41_DSP1_RX1_SRC , 0x00000008 }, // DSP1RX1 SRC = ASPRX1
134- { CS35L41_DSP1_RX2_SRC , 0x00000008 }, // DSP1RX2 SRC = ASPRX1
135- { CS35L41_DSP1_RX3_SRC , 0x00000018 }, // DSP1RX3 SRC = VMON
136- { CS35L41_DSP1_RX4_SRC , 0x00000019 }, // DSP1RX4 SRC = IMON
137126 { CS35L41_DSP1_RX6_SRC , 0x00000029 }, // DSP1RX6 SRC = VBSTMON
138127};
139128
@@ -657,6 +646,41 @@ static void cs35l41_irq_release(struct cs35l41_hda *cs35l41)
657646 cs35l41 -> irq_errors = 0 ;
658647}
659648
649+ static void cs35l41_update_mixer (struct cs35l41_hda * cs35l41 )
650+ {
651+ struct regmap * reg = cs35l41 -> regmap ;
652+ unsigned int asp_en = 0 ;
653+ unsigned int dsp1rx2_src = 0 ;
654+
655+ regmap_multi_reg_write (reg , cs35l41_hda_config , ARRAY_SIZE (cs35l41_hda_config ));
656+
657+ if (cs35l41 -> cs_dsp .running ) {
658+ asp_en |= CS35L41_ASP_TX1_EN_MASK ; // ASP_TX1_EN = 1
659+ regmap_multi_reg_write (reg , cs35l41_hda_config_dsp ,
660+ ARRAY_SIZE (cs35l41_hda_config_dsp ));
661+ if (cs35l41 -> hw_cfg .bst_type == CS35L41_INT_BOOST )
662+ regmap_write (reg , CS35L41_DSP1_RX5_SRC , CS35L41_INPUT_SRC_VPMON );
663+ else
664+ regmap_write (reg , CS35L41_DSP1_RX5_SRC , CS35L41_INPUT_SRC_VBSTMON );
665+ } else {
666+ regmap_multi_reg_write (reg , cs35l41_hda_config_no_dsp ,
667+ ARRAY_SIZE (cs35l41_hda_config_no_dsp ));
668+ }
669+
670+ if (cs35l41 -> hw_cfg .spk_pos == CS35L41_CENTER ) {
671+ asp_en |= CS35L41_ASP_RX2_EN_MASK ; // ASP_RX2_EN = 1
672+ dsp1rx2_src = 0x00000009 ; // DSP1RX2 SRC = ASPRX2
673+ } else {
674+ dsp1rx2_src = 0x00000008 ; // DSP1RX2 SRC = ASPRX1
675+ }
676+
677+ asp_en |= CS35L41_ASP_RX1_EN_MASK ; // ASP_RX1_EN = 1
678+
679+ regmap_write (reg , CS35L41_SP_ENABLES , asp_en );
680+ regmap_write (reg , CS35L41_DSP1_RX1_SRC , 0x00000008 ); // DSP1RX1 SRC = ASPRX1
681+ regmap_write (reg , CS35L41_DSP1_RX2_SRC , dsp1rx2_src );
682+ }
683+
660684static void cs35l41_hda_play_start (struct device * dev )
661685{
662686 struct cs35l41_hda * cs35l41 = dev_get_drvdata (dev );
@@ -671,19 +695,13 @@ static void cs35l41_hda_play_start(struct device *dev)
671695
672696 cs35l41 -> playback_started = true;
673697
698+ cs35l41_update_mixer (cs35l41 );
699+
674700 if (cs35l41 -> cs_dsp .running ) {
675- regmap_multi_reg_write (reg , cs35l41_hda_config_dsp ,
676- ARRAY_SIZE (cs35l41_hda_config_dsp ));
677- if (cs35l41 -> hw_cfg .bst_type == CS35L41_INT_BOOST )
678- regmap_write (reg , CS35L41_DSP1_RX5_SRC , CS35L41_INPUT_SRC_VPMON );
679- else
680- regmap_write (reg , CS35L41_DSP1_RX5_SRC , CS35L41_INPUT_SRC_VBSTMON );
681701 regmap_update_bits (reg , CS35L41_PWR_CTRL2 ,
682702 CS35L41_VMON_EN_MASK | CS35L41_IMON_EN_MASK ,
683703 1 << CS35L41_VMON_EN_SHIFT | 1 << CS35L41_IMON_EN_SHIFT );
684704 cs35l41_set_cspl_mbox_cmd (cs35l41 -> dev , reg , CSPL_MBOX_CMD_RESUME );
685- } else {
686- regmap_multi_reg_write (reg , cs35l41_hda_config , ARRAY_SIZE (cs35l41_hda_config ));
687705 }
688706 regmap_update_bits (reg , CS35L41_PWR_CTRL2 , CS35L41_AMP_EN_MASK , 1 << CS35L41_AMP_EN_SHIFT );
689707 if (cs35l41 -> hw_cfg .bst_type == CS35L41_EXT_BOOST )
@@ -841,22 +859,31 @@ static void cs35l41_hda_post_playback_hook(struct device *dev, int action)
841859 }
842860}
843861
844- static int cs35l41_hda_channel_map (struct device * dev , unsigned int tx_num , unsigned int * tx_slot ,
845- unsigned int rx_num , unsigned int * rx_slot )
862+ static int cs35l41_hda_channel_map (struct cs35l41_hda * cs35l41 )
846863{
847- struct cs35l41_hda * cs35l41 = dev_get_drvdata (dev );
848- static const char * const channel_name [] = { "L" , "R" };
864+ unsigned int tx_num = 0 ;
865+ unsigned int * tx_slot = NULL ;
866+ unsigned int rx_num ;
867+ unsigned int * rx_slot ;
868+ unsigned int mono = 0 ;
849869
850870 if (!cs35l41 -> amp_name ) {
851- if (* rx_slot >= ARRAY_SIZE (channel_name ))
871+ if (cs35l41 -> hw_cfg . spk_pos >= ARRAY_SIZE (channel_name ))
852872 return - EINVAL ;
853873
854- cs35l41 -> amp_name = devm_kasprintf (cs35l41 -> dev , GFP_KERNEL , "%s%d" ,
855- channel_name [* rx_slot ], cs35l41 -> channel_index );
874+ cs35l41 -> amp_name = devm_kasprintf (cs35l41 -> dev , GFP_KERNEL , "%c%d" ,
875+ channel_name [cs35l41 -> hw_cfg .spk_pos ],
876+ cs35l41 -> channel_index );
856877 if (!cs35l41 -> amp_name )
857878 return - ENOMEM ;
858879 }
859880
881+ rx_num = 1 ;
882+ if (cs35l41 -> hw_cfg .spk_pos == CS35L41_CENTER )
883+ rx_slot = & mono ;
884+ else
885+ rx_slot = & cs35l41 -> hw_cfg .spk_pos ;
886+
860887 return cs35l41_set_channels (cs35l41 -> dev , cs35l41 -> regmap , tx_num , tx_slot , rx_num ,
861888 rx_slot );
862889}
@@ -1495,7 +1522,7 @@ static int cs35l41_hda_bind(struct device *dev, struct device *master, void *mas
14951522 "CS35L41 Bound - SSID: %s, BST: %d, VSPK: %d, CH: %c, FW EN: %d, SPKID: %d\n" ,
14961523 cs35l41 -> acpi_subsystem_id , cs35l41 -> hw_cfg .bst_type ,
14971524 cs35l41 -> hw_cfg .gpio1 .func == CS35l41_VSPK_SWITCH ,
1498- cs35l41 -> hw_cfg .spk_pos ? 'R' : 'L' ,
1525+ channel_name [ cs35l41 -> hw_cfg .spk_pos ] ,
14991526 cs35l41 -> cs_dsp .running , cs35l41 -> speaker_id );
15001527
15011528 return ret ;
@@ -1709,7 +1736,7 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41)
17091736 if (using_irq )
17101737 cs35l41_configure_interrupt (cs35l41 , irq_pol );
17111738
1712- return cs35l41_hda_channel_map (cs35l41 -> dev , 0 , NULL , 1 , & hw_cfg -> spk_pos );
1739+ return cs35l41_hda_channel_map (cs35l41 );
17131740}
17141741
17151742int cs35l41_get_speaker_id (struct device * dev , int amp_index , int num_amps , int fixed_gpio_id )
0 commit comments