Commit abaaf3e1 authored by Linus Torvalds's avatar Linus Torvalds

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
parents 71ea4efe 2bd05db7
...@@ -282,6 +282,7 @@ int twl6040_power(struct twl6040 *twl6040, int on) ...@@ -282,6 +282,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
/* Default PLL configuration after power up */ /* Default PLL configuration after power up */
twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL; twl6040->pll = TWL6040_SYSCLK_SEL_LPPLL;
twl6040->sysclk = 19200000; twl6040->sysclk = 19200000;
twl6040->mclk = 32768;
} else { } else {
/* already powered-down */ /* already powered-down */
if (!twl6040->power_count) { if (!twl6040->power_count) {
...@@ -305,6 +306,7 @@ int twl6040_power(struct twl6040 *twl6040, int on) ...@@ -305,6 +306,7 @@ int twl6040_power(struct twl6040 *twl6040, int on)
twl6040_power_down(twl6040); twl6040_power_down(twl6040);
} }
twl6040->sysclk = 0; twl6040->sysclk = 0;
twl6040->mclk = 0;
} }
out: out:
...@@ -324,9 +326,17 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, ...@@ -324,9 +326,17 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
hppllctl = twl6040_reg_read(twl6040, TWL6040_REG_HPPLLCTL); hppllctl = twl6040_reg_read(twl6040, TWL6040_REG_HPPLLCTL);
lppllctl = twl6040_reg_read(twl6040, TWL6040_REG_LPPLLCTL); 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) { switch (pll_id) {
case TWL6040_SYSCLK_SEL_LPPLL: case TWL6040_SYSCLK_SEL_LPPLL:
/* low-power PLL divider */ /* low-power PLL divider */
/* Change the sysclk configuration only if it has been canged */
if (twl6040->sysclk != freq_out) {
switch (freq_out) { switch (freq_out) {
case 17640000: case 17640000:
lppllctl |= TWL6040_LPLLFIN; lppllctl |= TWL6040_LPLLFIN;
...@@ -336,11 +346,18 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, ...@@ -336,11 +346,18 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
break; break;
default: default:
dev_err(twl6040->dev, dev_err(twl6040->dev,
"freq_out %d not supported\n", freq_out); "freq_out %d not supported\n",
freq_out);
ret = -EINVAL; ret = -EINVAL;
goto pll_out; 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) { switch (freq_in) {
case 32768: case 32768:
...@@ -371,6 +388,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, ...@@ -371,6 +388,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
goto pll_out; goto pll_out;
} }
if (twl6040->mclk != freq_in) {
hppllctl &= ~TWL6040_MCLK_MSK; hppllctl &= ~TWL6040_MCLK_MSK;
switch (freq_in) { switch (freq_in) {
...@@ -404,15 +422,22 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id, ...@@ -404,15 +422,22 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
goto pll_out; goto pll_out;
} }
/* enable clock slicer to ensure input waveform is square */ /*
* enable clock slicer to ensure input waveform is
* square
*/
hppllctl |= TWL6040_HPLLSQRENA; hppllctl |= TWL6040_HPLLSQRENA;
twl6040_reg_write(twl6040, TWL6040_REG_HPPLLCTL, hppllctl); twl6040_reg_write(twl6040, TWL6040_REG_HPPLLCTL,
hppllctl);
usleep_range(500, 700); usleep_range(500, 700);
lppllctl |= TWL6040_HPLLSEL; lppllctl |= TWL6040_HPLLSEL;
twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl); twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL,
lppllctl);
lppllctl &= ~TWL6040_LPLLENA; lppllctl &= ~TWL6040_LPLLENA;
twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL, lppllctl); twl6040_reg_write(twl6040, TWL6040_REG_LPPLLCTL,
lppllctl);
}
break; break;
default: default:
dev_err(twl6040->dev, "unknown pll id %d\n", pll_id); 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, ...@@ -421,6 +446,7 @@ int twl6040_set_pll(struct twl6040 *twl6040, int pll_id,
} }
twl6040->sysclk = freq_out; twl6040->sysclk = freq_out;
twl6040->mclk = freq_in;
twl6040->pll = pll_id; twl6040->pll = pll_id;
pll_out: pll_out:
......
...@@ -187,8 +187,10 @@ struct twl6040 { ...@@ -187,8 +187,10 @@ struct twl6040 {
int rev; int rev;
u8 vibra_ctrl_cache[2]; u8 vibra_ctrl_cache[2];
/* PLL configuration */
int pll; int pll;
unsigned int sysclk; unsigned int sysclk;
unsigned int mclk;
unsigned int irq; unsigned int irq;
unsigned int irq_base; unsigned int irq_base;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment