@ -897,10 +897,137 @@ static int __init lsp1_clocks_init(struct device_node *np)
return 0 ;
}
PNAME ( audio_wclk_common_p ) = {
" audio_99m " ,
" audio_24m " ,
} ;
PNAME ( audio_timer_p ) = {
" audio_24m " ,
" audio_32k " ,
} ;
static struct zx_clk_mux audio_mux_clk [ ] = {
MUX ( 0 , " i2s0_wclk_mux " , audio_wclk_common_p , AUDIO_I2S0_CLK , 0 , 1 ) ,
MUX ( 0 , " i2s1_wclk_mux " , audio_wclk_common_p , AUDIO_I2S1_CLK , 0 , 1 ) ,
MUX ( 0 , " i2s2_wclk_mux " , audio_wclk_common_p , AUDIO_I2S2_CLK , 0 , 1 ) ,
MUX ( 0 , " i2s3_wclk_mux " , audio_wclk_common_p , AUDIO_I2S3_CLK , 0 , 1 ) ,
MUX ( 0 , " i2c0_wclk_mux " , audio_wclk_common_p , AUDIO_I2C0_CLK , 0 , 1 ) ,
MUX ( 0 , " spdif0_wclk_mux " , audio_wclk_common_p , AUDIO_SPDIF0_CLK , 0 , 1 ) ,
MUX ( 0 , " spdif1_wclk_mux " , audio_wclk_common_p , AUDIO_SPDIF1_CLK , 0 , 1 ) ,
MUX ( 0 , " timer_wclk_mux " , audio_timer_p , AUDIO_TIMER_CLK , 0 , 1 ) ,
} ;
static struct clk_zx_audio_divider audio_adiv_clk [ ] = {
AUDIO_DIV ( 0 , " i2s0_wclk_div " , " i2s0_wclk_mux " , AUDIO_I2S0_DIV_CFG1 ) ,
AUDIO_DIV ( 0 , " i2s1_wclk_div " , " i2s1_wclk_mux " , AUDIO_I2S1_DIV_CFG1 ) ,
AUDIO_DIV ( 0 , " i2s2_wclk_div " , " i2s2_wclk_mux " , AUDIO_I2S2_DIV_CFG1 ) ,
AUDIO_DIV ( 0 , " i2s3_wclk_div " , " i2s3_wclk_mux " , AUDIO_I2S3_DIV_CFG1 ) ,
AUDIO_DIV ( 0 , " spdif0_wclk_div " , " spdif0_wclk_mux " , AUDIO_SPDIF0_DIV_CFG1 ) ,
AUDIO_DIV ( 0 , " spdif1_wclk_div " , " spdif1_wclk_mux " , AUDIO_SPDIF1_DIV_CFG1 ) ,
} ;
static struct zx_clk_div audio_div_clk [ ] = {
DIV_T ( 0 , " tdm_wclk_div " , " audio_16m384 " , AUDIO_TDM_CLK , 8 , 4 , 0 , common_div_table ) ,
} ;
static struct zx_clk_gate audio_gate_clk [ ] = {
GATE ( AUDIO_I2S0_WCLK , " i2s0_wclk " , " i2s0_wclk_div " , AUDIO_I2S0_CLK , 9 , CLK_SET_RATE_PARENT , 0 ) ,
GATE ( AUDIO_I2S1_WCLK , " i2s1_wclk " , " i2s1_wclk_div " , AUDIO_I2S1_CLK , 9 , CLK_SET_RATE_PARENT , 0 ) ,
GATE ( AUDIO_I2S2_WCLK , " i2s2_wclk " , " i2s2_wclk_div " , AUDIO_I2S2_CLK , 9 , CLK_SET_RATE_PARENT , 0 ) ,
GATE ( AUDIO_I2S3_WCLK , " i2s3_wclk " , " i2s3_wclk_div " , AUDIO_I2S3_CLK , 9 , CLK_SET_RATE_PARENT , 0 ) ,
GATE ( AUDIO_I2C0_WCLK , " i2c0_wclk " , " i2c0_wclk_mux " , AUDIO_I2C0_CLK , 9 , CLK_SET_RATE_PARENT , 0 ) ,
GATE ( AUDIO_SPDIF0_WCLK , " spdif0_wclk " , " spdif0_wclk_div " , AUDIO_SPDIF0_CLK , 9 , CLK_SET_RATE_PARENT , 0 ) ,
GATE ( AUDIO_SPDIF1_WCLK , " spdif1_wclk " , " spdif1_wclk_div " , AUDIO_SPDIF1_CLK , 9 , CLK_SET_RATE_PARENT , 0 ) ,
GATE ( AUDIO_TDM_WCLK , " tdm_wclk " , " tdm_wclk_div " , AUDIO_TDM_CLK , 17 , CLK_SET_RATE_PARENT , 0 ) ,
GATE ( AUDIO_TS_PCLK , " tempsensor_pclk " , " clk49m5 " , AUDIO_TS_CLK , 1 , 0 , 0 ) ,
} ;
static struct clk_hw_onecell_data audio_hw_onecell_data = {
. num = AUDIO_NR_CLKS ,
. hws = {
[ AUDIO_NR_CLKS - 1 ] = NULL ,
} ,
} ;
static int __init audio_clocks_init ( struct device_node * np )
{
void __iomem * reg_base ;
int i , ret ;
reg_base = of_iomap ( np , 0 ) ;
if ( ! reg_base ) {
pr_err ( " %s: Unable to map audio clk base \n " , __func__ ) ;
return - ENXIO ;
}
for ( i = 0 ; i < ARRAY_SIZE ( audio_mux_clk ) ; i + + ) {
if ( audio_mux_clk [ i ] . id )
audio_hw_onecell_data . hws [ audio_mux_clk [ i ] . id ] =
& audio_mux_clk [ i ] . mux . hw ;
audio_mux_clk [ i ] . mux . reg + = ( uintptr_t ) reg_base ;
ret = clk_hw_register ( NULL , & audio_mux_clk [ i ] . mux . hw ) ;
if ( ret ) {
pr_warn ( " audio clk %s init error! \n " ,
audio_mux_clk [ i ] . mux . hw . init - > name ) ;
}
}
for ( i = 0 ; i < ARRAY_SIZE ( audio_adiv_clk ) ; i + + ) {
if ( audio_adiv_clk [ i ] . id )
audio_hw_onecell_data . hws [ audio_adiv_clk [ i ] . id ] =
& audio_adiv_clk [ i ] . hw ;
audio_adiv_clk [ i ] . reg_base + = ( uintptr_t ) reg_base ;
ret = clk_hw_register ( NULL , & audio_adiv_clk [ i ] . hw ) ;
if ( ret ) {
pr_warn ( " audio clk %s init error! \n " ,
audio_adiv_clk [ i ] . hw . init - > name ) ;
}
}
for ( i = 0 ; i < ARRAY_SIZE ( audio_div_clk ) ; i + + ) {
if ( audio_div_clk [ i ] . id )
audio_hw_onecell_data . hws [ audio_div_clk [ i ] . id ] =
& audio_div_clk [ i ] . div . hw ;
audio_div_clk [ i ] . div . reg + = ( uintptr_t ) reg_base ;
ret = clk_hw_register ( NULL , & audio_div_clk [ i ] . div . hw ) ;
if ( ret ) {
pr_warn ( " audio clk %s init error! \n " ,
audio_div_clk [ i ] . div . hw . init - > name ) ;
}
}
for ( i = 0 ; i < ARRAY_SIZE ( audio_gate_clk ) ; i + + ) {
if ( audio_gate_clk [ i ] . id )
audio_hw_onecell_data . hws [ audio_gate_clk [ i ] . id ] =
& audio_gate_clk [ i ] . gate . hw ;
audio_gate_clk [ i ] . gate . reg + = ( uintptr_t ) reg_base ;
ret = clk_hw_register ( NULL , & audio_gate_clk [ i ] . gate . hw ) ;
if ( ret ) {
pr_warn ( " audio clk %s init error! \n " ,
audio_gate_clk [ i ] . gate . hw . init - > name ) ;
}
}
ret = of_clk_add_hw_provider ( np , of_clk_hw_onecell_get ,
& audio_hw_onecell_data ) ;
if ( ret ) {
pr_err ( " failed to register audio clk provider: %d \n " , ret ) ;
return ret ;
}
return 0 ;
}
static const struct of_device_id zx_clkc_match_table [ ] = {
{ . compatible = " zte,zx296718-topcrm " , . data = & top_clocks_init } ,
{ . compatible = " zte,zx296718-lsp0crm " , . data = & lsp0_clocks_init } ,
{ . compatible = " zte,zx296718-lsp1crm " , . data = & lsp1_clocks_init } ,
{ . compatible = " zte,zx296718-audiocrm " , . data = & audio_clocks_init } ,
{ }
} ;