summaryrefslogtreecommitdiff
path: root/drivers/mfd/rtsx_pcr.c
diff options
context:
space:
mode:
authorWei WANG <wei_wang@realsil.com.cn>2013-01-23 09:51:06 +0800
committerSamuel Ortiz <sameo@linux.intel.com>2013-01-27 01:30:20 +0100
commitab4e8f8b7bdfeff0c961fdbbdacb262d68f094c0 (patch)
tree543440d2656343141c14e565e795a655378a0f72 /drivers/mfd/rtsx_pcr.c
parentef85e736b1052d8c1e56990f0d08b6fce7cdbe41 (diff)
mfd: rtsx: Add clock divider hook
Add callback function conv_clk_and_div_n to convert between SSC clock and its divider N. For rtl8411, the formula to calculate SSC clock divider N is different with the other card reader models. Signed-off-by: Wei WANG <wei_wang@realsil.com.cn> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd/rtsx_pcr.c')
-rw-r--r--drivers/mfd/rtsx_pcr.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c
index f4e02d089271..910200e10fa0 100644
--- a/drivers/mfd/rtsx_pcr.c
+++ b/drivers/mfd/rtsx_pcr.c
@@ -630,7 +630,10 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
if (clk == pcr->cur_clock)
return 0;
- N = (u8)(clk - 2);
+ if (pcr->ops->conv_clk_and_div_n)
+ N = (u8)pcr->ops->conv_clk_and_div_n(clk, CLK_TO_DIV_N);
+ else
+ N = (u8)(clk - 2);
if ((clk <= 2) || (N > max_N))
return -EINVAL;
@@ -641,7 +644,14 @@ int rtsx_pci_switch_clock(struct rtsx_pcr *pcr, unsigned int card_clock,
/* Make sure that the SSC clock div_n is equal or greater than min_N */
div = CLK_DIV_1;
while ((N < min_N) && (div < max_div)) {
- N = (N + 2) * 2 - 2;
+ if (pcr->ops->conv_clk_and_div_n) {
+ int dbl_clk = pcr->ops->conv_clk_and_div_n(N,
+ DIV_N_TO_CLK) * 2;
+ N = (u8)pcr->ops->conv_clk_and_div_n(dbl_clk,
+ CLK_TO_DIV_N);
+ } else {
+ N = (N + 2) * 2 - 2;
+ }
div++;
}
dev_dbg(&(pcr->pci->dev), "N = %d, div = %d\n", N, div);