Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: mfd: Avoid twl6040-codec PLL reconfiguration when not needed mfd: Store twl6040-codec mclk configuration
This commit is contained in:
commit
abaaf3e12c
|
@ -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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
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:
|
||||
|
|
|
@ -187,8 +187,10 @@ struct twl6040 {
|
|||
int rev;
|
||||
u8 vibra_ctrl_cache[2];
|
||||
|
||||
/* PLL configuration */
|
||||
int pll;
|
||||
unsigned int sysclk;
|
||||
unsigned int mclk;
|
||||
|
||||
unsigned int irq;
|
||||
unsigned int irq_base;
|
||||
|
|
Loading…
Reference in New Issue