@ -282,6 +282,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
/* Default PLL configuration after power up */
twl6040 - > pll = TWL6040_SYSCLK_SEL_LPPLL ;
twl6040 - > sysclk = 19200000 ;
twl6040 - > mclk = 32768 ;
} else {
/* already powered-down */
if ( ! twl6040 - > power_count ) {
@ -305,6 +306,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
twl6040_power_down ( twl6040 ) ;
}
twl6040 - > sysclk = 0 ;
twl6040 - > mclk = 0 ;
}
out :
@ -324,23 +326,38 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
hppllctl = twl6040_reg_read ( twl6040 , TWL6040_REG_HPPLLCTL ) ;
lppllctl = twl6040_reg_read ( twl6040 , TWL6040_REG_LPPLLCTL ) ;
/* Force full reconfiguration when switching between PLL */
if ( pll_id ! = twl6040 - > pll ) {
twl6040 - > sysclk = 0 ;
twl6040 - > mclk = 0 ;
}
switch ( pll_id ) {
case TWL6040_SYSCLK_SEL_LPPLL :
/* low-power PLL divider */
switch ( freq_out ) {
case 17640000 :
lppllctl | = TWL6040_LPLLFIN ;
break ;
case 19200000 :
lppllctl & = ~ TWL6040_LPLLFIN ;
break ;
default :
dev_err ( twl6040 - > dev ,
" freq_out %d not supported \n " , freq_out ) ;
ret = - EINVAL ;
goto pll_out ;
/* Change the sysclk configuration only if it has been canged */
if ( twl6040 - > sysclk ! = freq_out ) {
switch ( freq_out ) {
case 17640000 :
lppllctl | = TWL6040_LPLLFIN ;
break ;
case 19200000 :
lppllctl & = ~ TWL6040_LPLLFIN ;
break ;
default :
dev_err ( twl6040 - > dev ,
" freq_out %d not supported \n " ,
freq_out ) ;
ret = - EINVAL ;
goto pll_out ;
}
twl6040_reg_write ( twl6040 , TWL6040_REG_LPPLLCTL ,
lppllctl ) ;
}
twl6040_reg_write ( twl6040 , TWL6040_REG_LPPLLCTL , lppllctl ) ;
/* The PLL in use has not been change, we can exit */
if ( twl6040 - > pll = = pll_id )
break ;
switch ( freq_in ) {
case 32768 :
@ -371,48 +388,56 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
goto pll_out ;
}
hppllctl & = ~ TWL6040_MCLK_MSK ;
if ( twl6040 - > mclk ! = freq_in ) {
hppllctl & = ~ TWL6040_MCLK_MSK ;
switch ( freq_in ) {
case 12000000 :
/* PLL enabled, active mode */
hppllctl | = TWL6040_MCLK_12000KHZ |
TWL6040_HPLLENA ;
break ;
case 19200000 :
/*
* PLL disabled
* ( enable PLL if MCLK jitter quality
* doesn ' t meet specification )
*/
hppllctl | = TWL6040_MCLK_19200KHZ ;
break ;
case 26000000 :
/* PLL enabled, active mode */
hppllctl | = TWL6040_MCLK_26000KHZ |
TWL6040_HPLLENA ;
break ;
case 38400000 :
/* PLL enabled, active mode */
hppllctl | = TWL6040_MCLK_38400KHZ |
TWL6040_HPLLENA ;
break ;
default :
dev_err ( twl6040 - > dev ,
" freq_in %d not supported \n " , freq_in ) ;
ret = - EINVAL ;
goto pll_out ;
}
switch ( freq_in ) {
case 12000000 :
/* PLL enabled, active mode */
hppllctl | = TWL6040_MCLK_12000KHZ |
TWL6040_HPLLENA ;
break ;
case 19200000 :
/*
* PLL disabled
* ( enable PLL if MCLK jitter quality
* doesn ' t meet specification )
* enable clock slicer to ensure input waveform is
* square
*/
hppllctl | = TWL6040_MCLK_19200KHZ ;
break ;
case 26000000 :
/* PLL enabled, active mode */
hppllctl | = TWL6040_MCLK_26000KHZ |
TWL6040_HPLLENA ;
break ;
case 38400000 :
/* PLL enabled, active mode */
hppllctl | = TWL6040_MCLK_38400KHZ |
TWL6040_HPLLENA ;
break ;
default :
dev_err ( twl6040 - > dev ,
" freq_in %d not supported \n " , freq_in ) ;
ret = - EINVAL ;
goto pll_out ;
}
hppllctl | = TWL6040_HPLLSQRENA ;
/* enable clock slicer to ensure input waveform is square */
hppllctl | = TWL6040_HPLLSQRENA ;
twl6040_reg_write ( twl6040 , TWL6040_REG_HPPLLCTL , hppllctl ) ;
usleep_range ( 500 , 700 ) ;
lppllctl | = TWL6040_HPLLSEL ;
twl6040_reg_write ( twl6040 , TWL6040_REG_LPPLLCTL , lppllctl ) ;
lppllctl & = ~ TWL6040_LPLLENA ;
twl6040_reg_write ( twl6040 , TWL6040_REG_LPPLLCTL , lppllctl ) ;
twl6040_reg_write ( twl6040 , TWL6040_REG_HPPLLCTL ,
hppllctl ) ;
usleep_range ( 500 , 700 ) ;
lppllctl | = TWL6040_HPLLSEL ;
twl6040_reg_write ( twl6040 , TWL6040_REG_LPPLLCTL ,
lppllctl ) ;
lppllctl & = ~ TWL6040_LPLLENA ;
twl6040_reg_write ( twl6040 , TWL6040_REG_LPPLLCTL ,
lppllctl ) ;
}
break ;
default :
dev_err ( twl6040 - > dev , " unknown pll id %d \n " , pll_id ) ;
@ -421,6 +446,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
}
twl6040 - > sysclk = freq_out ;
twl6040 - > mclk = freq_in ;
twl6040 - > pll = pll_id ;
pll_out :