summaryrefslogtreecommitdiffstats
path: root/drivers/staging/csr/csr_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/csr/csr_util.c')
-rw-r--r--drivers/staging/csr/csr_util.c443
1 files changed, 443 insertions, 0 deletions
diff --git a/drivers/staging/csr/csr_util.c b/drivers/staging/csr/csr_util.c
new file mode 100644
index 000000000000..ee2d0475781b
--- /dev/null
+++ b/drivers/staging/csr/csr_util.c
@@ -0,0 +1,443 @@
+/*****************************************************************************
+
+ (c) Cambridge Silicon Radio Limited 2010
+ All rights reserved and confidential information of CSR
+
+ Refer to LICENSE.txt included with this source for details
+ on the license terms.
+
+*****************************************************************************/
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <stdarg.h>
+
+#include "csr_types.h"
+#include "csr_pmem.h"
+#include "csr_util.h"
+
+/*------------------------------------------------------------------*/
+/* Bits */
+/*------------------------------------------------------------------*/
+
+/* Time proportional with the number of 1's */
+CsrUint8 CsrBitCountSparse(CsrUint32 n)
+{
+ CsrUint8 count = 0;
+
+ while (n)
+ {
+ count++;
+ n &= (n - 1);
+ }
+
+ return count;
+}
+
+/* Time proportional with the number of 0's */
+CsrUint8 CsrBitCountDense(CsrUint32 n)
+{
+ CsrUint8 count = 8 * sizeof(CsrUint32);
+
+ n ^= (CsrUint32) (-1);
+
+ while (n)
+ {
+ count--;
+ n &= (n - 1);
+ }
+
+ return count;
+}
+
+/*------------------------------------------------------------------*/
+/* Base conversion */
+/*------------------------------------------------------------------*/
+CsrBool CsrHexStrToUint8(const CsrCharString *string, CsrUint8 *returnValue)
+{
+ CsrUint16 currentIndex = 0;
+ *returnValue = 0;
+ if ((string[currentIndex] == '0') && (CSR_TOUPPER(string[currentIndex + 1]) == 'X'))
+ {
+ string += 2;
+ }
+ if (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) || ((CSR_TOUPPER(string[currentIndex]) >= 'A') && (CSR_TOUPPER(string[currentIndex]) <= 'F')))
+ {
+ while (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) || ((CSR_TOUPPER(string[currentIndex]) >= 'A') && (CSR_TOUPPER(string[currentIndex]) <= 'F')))
+ {
+ *returnValue = (CsrUint8) (*returnValue * 16 + (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) ? string[currentIndex] - '0' : CSR_TOUPPER(string[currentIndex]) - 'A' + 10));
+ currentIndex++;
+ if (currentIndex >= 2)
+ {
+ break;
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+CsrBool CsrHexStrToUint16(const CsrCharString *string, CsrUint16 *returnValue)
+{
+ CsrUint16 currentIndex = 0;
+ *returnValue = 0;
+ if ((string[currentIndex] == '0') && (CSR_TOUPPER(string[currentIndex + 1]) == 'X'))
+ {
+ string += 2;
+ }
+ if (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) || ((CSR_TOUPPER(string[currentIndex]) >= 'A') && (CSR_TOUPPER(string[currentIndex]) <= 'F')))
+ {
+ while (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) || ((CSR_TOUPPER(string[currentIndex]) >= 'A') && (CSR_TOUPPER(string[currentIndex]) <= 'F')))
+ {
+ *returnValue = (CsrUint16) (*returnValue * 16 + (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) ? string[currentIndex] - '0' : CSR_TOUPPER(string[currentIndex]) - 'A' + 10));
+ currentIndex++;
+ if (currentIndex >= 4)
+ {
+ break;
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+CsrBool CsrHexStrToUint32(const CsrCharString *string, CsrUint32 *returnValue)
+{
+ CsrUint16 currentIndex = 0;
+ *returnValue = 0;
+ if ((string[currentIndex] == '0') && (CSR_TOUPPER(string[currentIndex + 1]) == 'X'))
+ {
+ string += 2;
+ }
+ if (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) || ((CSR_TOUPPER(string[currentIndex]) >= 'A') && (CSR_TOUPPER(string[currentIndex]) <= 'F')))
+ {
+ while (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) || ((CSR_TOUPPER(string[currentIndex]) >= 'A') && (CSR_TOUPPER(string[currentIndex]) <= 'F')))
+ {
+ *returnValue = *returnValue * 16 + (((string[currentIndex] >= '0') && (string[currentIndex] <= '9')) ? string[currentIndex] - '0' : CSR_TOUPPER(string[currentIndex]) - 'A' + 10);
+ currentIndex++;
+ if (currentIndex >= 8)
+ {
+ break;
+ }
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+CsrUint32 CsrPow(CsrUint32 base, CsrUint32 exponent)
+{
+ if (exponent == 0)
+ {
+ return 1;
+ }
+ else
+ {
+ CsrUint32 i, t = base;
+
+ for (i = 1; i < exponent; i++)
+ {
+ t = t * base;
+ }
+ return t;
+ }
+}
+
+/* Convert signed 32 bit (or less) integer to string */
+#define I2B10_MAX 12
+void CsrIntToBase10(CsrInt32 number, CsrCharString *str)
+{
+ CsrInt32 digit;
+ CsrUint8 index;
+ CsrCharString res[I2B10_MAX];
+ CsrBool foundDigit = FALSE;
+
+ for (digit = 0; digit < I2B10_MAX; digit++)
+ {
+ res[digit] = '\0';
+ }
+
+ /* Catch sign - and deal with positive numbers only afterwards */
+ index = 0;
+ if (number < 0)
+ {
+ res[index++] = '-';
+ number = -1 * number;
+ }
+
+ digit = 1000000000;
+ if (number > 0)
+ {
+ while ((index < I2B10_MAX - 1) && (digit > 0))
+ {
+ /* If the foundDigit flag is TRUE, this routine should be proceeded.
+ Otherwise the number which has '0' digit cannot be converted correctly */
+ if (((number / digit) > 0) || foundDigit)
+ {
+ foundDigit = TRUE; /* set foundDigit flag to TRUE*/
+ res[index++] = (char) ('0' + (number / digit));
+ number = number % digit;
+ }
+
+ digit = digit / 10;
+ }
+ }
+ else
+ {
+ res[index] = (char) '0';
+ }
+
+ CsrStrCpy(str, res);
+}
+
+void CsrUInt16ToHex(CsrUint16 number, CsrCharString *str)
+{
+ CsrUint16 index;
+ CsrUint16 currentValue;
+
+ for (index = 0; index < 4; index++)
+ {
+ currentValue = (CsrUint16) (number & 0x000F);
+ number >>= 4;
+ str[3 - index] = (char) (currentValue > 9 ? currentValue + 55 : currentValue + '0');
+ }
+ str[4] = '\0';
+}
+
+void CsrUInt32ToHex(CsrUint32 number, CsrCharString *str)
+{
+ CsrUint16 index;
+ CsrUint32 currentValue;
+
+ for (index = 0; index < 8; index++)
+ {
+ currentValue = (CsrUint32) (number & 0x0000000F);
+ number >>= 4;
+ str[7 - index] = (char) (currentValue > 9 ? currentValue + 55 : currentValue + '0');
+ }
+ str[8] = '\0';
+}
+
+/*------------------------------------------------------------------*/
+/* String */
+/*------------------------------------------------------------------*/
+#ifndef CSR_USE_STDC_LIB
+void *CsrMemCpy(void *dest, const void *src, CsrSize count)
+{
+ return memcpy(dest, src, count);
+}
+EXPORT_SYMBOL_GPL(CsrMemCpy);
+
+void *CsrMemSet(void *dest, CsrUint8 c, CsrSize count)
+{
+ return memset(dest, c, count);
+}
+EXPORT_SYMBOL_GPL(CsrMemSet);
+
+void *CsrMemMove(void *dest, const void *src, CsrSize count)
+{
+ return memmove(dest, src, count);
+}
+EXPORT_SYMBOL_GPL(CsrMemMove);
+
+CsrInt32 CsrMemCmp(const void *buf1, const void *buf2, CsrSize count)
+{
+ return memcmp(buf1, buf2, count);
+}
+EXPORT_SYMBOL_GPL(CsrMemCmp);
+
+void *CsrMemDup(const void *buf1, CsrSize count)
+{
+ void *buf2 = NULL;
+
+ if (buf1)
+ {
+ buf2 = CsrPmemAlloc(count);
+ CsrMemCpy(buf2, buf1, count);
+ }
+
+ return buf2;
+}
+#endif
+
+#ifndef CSR_USE_STDC_LIB
+CsrCharString *CsrStrCpy(CsrCharString *dest, const CsrCharString *src)
+{
+ return strcpy(dest, src);
+}
+
+CsrCharString *CsrStrNCpy(CsrCharString *dest, const CsrCharString *src, CsrSize count)
+{
+ return strncpy(dest, src, count);
+}
+
+CsrCharString *CsrStrCat(CsrCharString *dest, const CsrCharString *src)
+{
+ return strcat(dest, src);
+}
+
+CsrCharString *CsrStrNCat(CsrCharString *dest, const CsrCharString *src, CsrSize count)
+{
+ return strncat(dest, src, count);
+}
+
+CsrCharString *CsrStrStr(const CsrCharString *string1, const CsrCharString *string2)
+{
+ return strstr(string1, string2);
+}
+
+CsrSize CsrStrLen(const CsrCharString *string)
+{
+ return strlen(string);
+}
+EXPORT_SYMBOL_GPL(CsrStrLen);
+
+CsrInt32 CsrStrCmp(const CsrCharString *string1, const CsrCharString *string2)
+{
+ return strcmp(string1, string2);
+}
+
+CsrInt32 CsrStrNCmp(const CsrCharString *string1, const CsrCharString *string2, CsrSize count)
+{
+ return strncmp(string1, string2, count);
+}
+
+CsrCharString *CsrStrChr(const CsrCharString *string, CsrCharString c)
+{
+ return strchr(string, c);
+}
+#endif
+
+CsrInt32 CsrVsnprintf(CsrCharString *string, CsrSize count, const CsrCharString *format, va_list args)
+{
+ return vsnprintf(string, count, format, args);
+}
+EXPORT_SYMBOL_GPL(CsrVsnprintf);
+
+CsrCharString *CsrStrNCpyZero(CsrCharString *dest,
+ const CsrCharString *src,
+ CsrSize count)
+{
+ CsrStrNCpy(dest, src, count - 1);
+ dest[count - 1] = '\0';
+ return dest;
+}
+
+/* Convert string with base 10 to integer */
+CsrUint32 CsrStrToInt(const CsrCharString *str)
+{
+ CsrInt16 i;
+ CsrUint32 res;
+ CsrUint32 digit;
+
+ res = 0;
+ digit = 1;
+
+ /* Start from the string end */
+ for (i = (CsrUint16) (CsrStrLen(str) - 1); i >= 0; i--)
+ {
+ /* Only convert numbers */
+ if ((str[i] >= '0') && (str[i] <= '9'))
+ {
+ res += digit * (str[i] - '0');
+ digit = digit * 10;
+ }
+ }
+
+ return res;
+}
+
+CsrCharString *CsrStrDup(const CsrCharString *string)
+{
+ CsrCharString *copy;
+ CsrUint32 len;
+
+ copy = NULL;
+ if (string != NULL)
+ {
+ len = CsrStrLen(string) + 1;
+ copy = CsrPmemAlloc(len);
+ CsrMemCpy(copy, string, len);
+ }
+ return copy;
+}
+
+int CsrStrNICmp(const CsrCharString *string1,
+ const CsrCharString *string2,
+ CsrSize count)
+{
+ CsrUint32 index;
+ int returnValue = 0;
+
+ for (index = 0; index < count; index++)
+ {
+ if (CSR_TOUPPER(string1[index]) != CSR_TOUPPER(string2[index]))
+ {
+ if (CSR_TOUPPER(string1[index]) > CSR_TOUPPER(string2[index]))
+ {
+ returnValue = 1;
+ }
+ else
+ {
+ returnValue = -1;
+ }
+ break;
+ }
+ if (string1[index] == '\0')
+ {
+ break;
+ }
+ }
+ return returnValue;
+}
+
+const CsrCharString *CsrGetBaseName(const CsrCharString *file)
+{
+ const CsrCharString *pch;
+ static const CsrCharString dotDir[] = ".";
+
+ if (!file)
+ {
+ return NULL;
+ }
+
+ if (file[0] == '\0')
+ {
+ return dotDir;
+ }
+
+ pch = file + CsrStrLen(file) - 1;
+
+ while (*pch != '\\' && *pch != '/' && *pch != ':')
+ {
+ if (pch == file)
+ {
+ return pch;
+ }
+ --pch;
+ }
+
+ return ++pch;
+}
+
+/*------------------------------------------------------------------*/
+/* Misc */
+/*------------------------------------------------------------------*/
+CsrBool CsrIsSpace(CsrUint8 c)
+{
+ switch (c)
+ {
+ case '\t':
+ case '\n':
+ case '\f':
+ case '\r':
+ case ' ':
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+MODULE_DESCRIPTION("CSR Operating System Kernel Abstraction");
+MODULE_AUTHOR("Cambridge Silicon Radio Ltd.");
+MODULE_LICENSE("GPL and additional rights");