Initial Contribution
msm-2.6.38: tag AU_LINUX_ANDROID_GINGERBREAD.02.03.04.00.142
Signed-off-by: Bryan Huntsman <bryanh@codeaurora.org>
diff --git a/arch/arm/mach-msm/btpintest.c b/arch/arm/mach-msm/btpintest.c
new file mode 100644
index 0000000..0abe09b
--- /dev/null
+++ b/arch/arm/mach-msm/btpintest.c
@@ -0,0 +1,234 @@
+/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/uaccess.h>
+#include <linux/version.h>
+#include <linux/debugfs.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <mach/gpio.h>
+#include <mach/vreg.h>
+#include "gpiomux.h"
+
+#define VERSION "1.0"
+struct dentry *pin_debugfs_dent;
+
+/* UART GPIO lines for 8660 */
+enum uartpins {
+ UARTDM_TX = 53,
+ UARTDM_RX = 54,
+ UARTDM_CTS = 55,
+ UARTDM_RFR = 56
+};
+
+/* Aux PCM GPIO lines for 8660 */
+enum auxpcmpins {
+ AUX_PCM_CLK = 114,
+ AUX_PCM_SYNC = 113,
+ AUX_PCM_DIN = 112,
+ AUX_PCM_DOUT = 111
+};
+/*Number of UART and PCM pins */
+#define PIN_COUNT 8
+
+static struct gpiomux_setting pin_test_config = {
+ .func = GPIOMUX_FUNC_GPIO,
+ .drv = GPIOMUX_DRV_2MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+/* Static array to intialise the return config */
+static struct gpiomux_setting currentconfig[2*PIN_COUNT];
+
+static struct msm_gpiomux_config pin_test_configs[] = {
+ {
+ .gpio = AUX_PCM_DOUT,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &pin_test_config,
+ [GPIOMUX_SUSPENDED] = &pin_test_config,
+ },
+ },
+ {
+ .gpio = AUX_PCM_DIN,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &pin_test_config,
+ [GPIOMUX_SUSPENDED] = &pin_test_config,
+ },
+ },
+ {
+ .gpio = AUX_PCM_SYNC,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &pin_test_config,
+ [GPIOMUX_SUSPENDED] = &pin_test_config,
+ },
+ },
+ {
+ .gpio = AUX_PCM_CLK,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &pin_test_config,
+ [GPIOMUX_SUSPENDED] = &pin_test_config,
+ },
+ },
+ {
+ .gpio = UARTDM_TX,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &pin_test_config,
+ [GPIOMUX_SUSPENDED] = &pin_test_config,
+ },
+ },
+ {
+ .gpio = UARTDM_RX,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &pin_test_config,
+ [GPIOMUX_SUSPENDED] = &pin_test_config,
+ },
+ },
+ {
+ .gpio = UARTDM_CTS,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &pin_test_config,
+ [GPIOMUX_SUSPENDED] = &pin_test_config,
+ },
+ },
+ {
+ .gpio = UARTDM_RFR,
+ .settings = {
+ [GPIOMUX_ACTIVE] = &pin_test_config,
+ [GPIOMUX_SUSPENDED] = &pin_test_config,
+ },
+ },
+};
+static struct msm_gpiomux_config pin_config[PIN_COUNT];
+
+static int pintest_open(struct inode *inode, struct file *file)
+{
+ /* non-seekable */
+ file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
+ return 0;
+}
+
+static int pintest_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static int configure_pins(struct msm_gpiomux_config *config,
+ struct msm_gpiomux_config *oldconfig,
+ unsigned int num_configs)
+{
+ int rc = 0, j, i;
+ for (i = 0; i < num_configs; i++) {
+ for (j = 0; j < GPIOMUX_NSETTINGS; j++) {
+ (oldconfig + i)->gpio = (config + i)->gpio;
+ rc = msm_gpiomux_write((config + i)->gpio,
+ j,
+ (config + i)->settings[j],
+ (oldconfig + i)->settings[j]);
+ if (rc < 0)
+ break;
+ }
+
+ }
+ return rc;
+}
+
+static void init_current_config_pointers(void)
+{
+ int i = 0, j = 0;
+ /* The current config variables will hold the current configuration
+ * which is getting overwritten during a msm_gpiomux_write call
+ */
+ for (i = 0, j = 0; i < PIN_COUNT; i += 1, j += 2) {
+ pin_config[i].settings[GPIOMUX_ACTIVE] = ¤tconfig[j];
+ pin_config[i].settings[GPIOMUX_SUSPENDED] =
+ ¤tconfig[j + 1];
+ }
+
+}
+
+static ssize_t pintest_write(
+ struct file *file,
+ const char __user *buff,
+ size_t count,
+ loff_t *ppos)
+{
+ char mode;
+ int rc = 0;
+
+ if (count < 1)
+ return -EINVAL;
+
+ if (buff == NULL)
+ return -EINVAL;
+
+ if (copy_from_user(&mode, buff, count))
+ return -EFAULT;
+ mode = mode - '0';
+
+ init_current_config_pointers();
+
+ if (mode) {
+ /* Configure all pin test gpios for the custom settings */
+ rc = configure_pins(pin_test_configs, pin_config,
+ ARRAY_SIZE(pin_test_configs));
+ if (rc < 0)
+ return rc;
+ } else {
+ /* Configure all pin test gpios for the original settings */
+ rc = configure_pins(pin_config, pin_test_configs,
+ ARRAY_SIZE(pin_test_configs));
+ if (rc < 0)
+ return rc;
+ }
+ return rc;
+}
+
+static const struct file_operations pintest_debugfs_fops = {
+ .open = pintest_open,
+ .release = pintest_release,
+ .write = pintest_write,
+};
+
+static int __init bluepintest_init(void)
+{
+ pin_debugfs_dent = debugfs_create_dir("btpintest", NULL);
+
+ if (IS_ERR(pin_debugfs_dent)) {
+ printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n",
+ __FILE__, __LINE__, PTR_ERR(pin_debugfs_dent));
+ return -ENOMEM;
+ }
+
+ if (debugfs_create_file("enable", 0644, pin_debugfs_dent,
+ 0, &pintest_debugfs_fops) == NULL) {
+ printk(KERN_ERR "%s(%d): debugfs_create_file: index fail\n",
+ __FILE__, __LINE__);
+ return -ENOMEM;
+ }
+ return 0;
+}
+
+static void __exit bluepintest_exit(void)
+{
+ debugfs_remove_recursive(pin_debugfs_dent);
+}
+
+module_init(bluepintest_init);
+module_exit(bluepintest_exit);
+
+MODULE_DESCRIPTION("Bluetooth Pin Connectivty Test Driver ver %s " VERSION);
+MODULE_LICENSE("GPL v2");