aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/sysdev/qe_lib/qe.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/sysdev/qe_lib/qe.c')
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe.c46
1 files changed, 41 insertions, 5 deletions
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index 3d57d3835b04..21e01061aca9 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -167,19 +167,20 @@ unsigned int get_brg_clk(void)
/* Program the BRG to the given sampling rate and multiplier
*
- * @brg: the BRG, 1-16
+ * @brg: the BRG, QE_BRG1 - QE_BRG16
* @rate: the desired sampling rate
* @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or
* GUMR_L[TDCR]. E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01,
* then 'multiplier' should be 8.
- *
- * Also note that the value programmed into the BRGC register must be even.
*/
-void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier)
+int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
{
u32 divisor, tempval;
u32 div16 = 0;
+ if ((brg < QE_BRG1) || (brg > QE_BRG16))
+ return -EINVAL;
+
divisor = get_brg_clk() / (rate * multiplier);
if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
@@ -196,8 +197,43 @@ void qe_setbrg(unsigned int brg, unsigned int rate, unsigned int multiplier)
tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
QE_BRGC_ENABLE | div16;
- out_be32(&qe_immr->brg.brgc[brg - 1], tempval);
+ out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval);
+
+ return 0;
+}
+EXPORT_SYMBOL(qe_setbrg);
+
+/* Convert a string to a QE clock source enum
+ *
+ * This function takes a string, typically from a property in the device
+ * tree, and returns the corresponding "enum qe_clock" value.
+*/
+enum qe_clock qe_clock_source(const char *source)
+{
+ unsigned int i;
+
+ if (strcasecmp(source, "none") == 0)
+ return QE_CLK_NONE;
+
+ if (strncasecmp(source, "brg", 3) == 0) {
+ i = simple_strtoul(source + 3, NULL, 10);
+ if ((i >= 1) && (i <= 16))
+ return (QE_BRG1 - 1) + i;
+ else
+ return QE_CLK_DUMMY;
+ }
+
+ if (strncasecmp(source, "clk", 3) == 0) {
+ i = simple_strtoul(source + 3, NULL, 10);
+ if ((i >= 1) && (i <= 24))
+ return (QE_CLK1 - 1) + i;
+ else
+ return QE_CLK_DUMMY;
+ }
+
+ return QE_CLK_DUMMY;
}
+EXPORT_SYMBOL(qe_clock_source);
/* Initialize SNUMs (thread serial numbers) according to
* QE Module Control chapter, SNUM table