aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos/px-switch.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-exynos/px-switch.c')
-rw-r--r--arch/arm/mach-exynos/px-switch.c225
1 files changed, 208 insertions, 17 deletions
diff --git a/arch/arm/mach-exynos/px-switch.c b/arch/arm/mach-exynos/px-switch.c
index 90772ed..99f0e15 100644
--- a/arch/arm/mach-exynos/px-switch.c
+++ b/arch/arm/mach-exynos/px-switch.c
@@ -61,22 +61,45 @@ static ssize_t store_usb_sel(struct device *dev,
static ssize_t show_uart_sel(struct device *dev,
struct device_attribute *attr, char *buf)
{
+#ifdef CONFIG_MACH_P8LTE
+ /* 2 for LTE, 1 for AP, 0 for CP */
+ int val_sel1, val_sel2;
+ val_sel1 = gpio_get_value(GPIO_UART_SEL1);
+ val_sel2 = gpio_get_value(GPIO_UART_SEL2);
+ return sprintf(buf, "%d", val_sel1 << (1 - val_sel2));
+#else
int val_sel;
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ int val_sel2;
+#endif /* (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2) */
const char *mode;
val_sel = gpio_get_value(GPIO_UART_SEL);
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ val_sel2 = gpio_get_value(GPIO_UART_SEL2);
+#endif /* (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2) */
if (val_sel == 0) {
/* CP */
mode = "CP";
} else {
- /* AP */
- mode = "AP";
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ if (val_sel2 == 0) {
+#endif /* (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2) */
+ /* AP */
+ mode = "AP";
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ } else {
+ /* Keyboard DOCK */
+ mode = "DOCK";
+ }
+#endif /* (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2) */
}
pr_info("%s: %s\n", __func__, mode);
return sprintf(buf, "%s\n", mode);
+#endif /* CONFIG_MACH_P8LTE */
}
static ssize_t store_uart_sel(struct device *dev,
@@ -84,20 +107,63 @@ static ssize_t store_uart_sel(struct device *dev,
const char *buf, size_t count)
{
int uart_sel = -1;
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ int uart_sel2 = -1;
+#endif /* (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2) */
+
+#ifdef CONFIG_MACH_P8LTE
+ int set_val1, set_val2, ret = 0;
+#endif /* CONFIG_MACH_P8LTE */
pr_info("%s: %s\n", __func__, buf);
+#ifdef CONFIG_MACH_P8LTE
+ /* 2 for LTE, 1 for AP, 0 for CP */
+ ret = sscanf(buf, "%d", &uart_sel);
+
+ if (ret != 1)
+ return -EINVAL;
+
+ set_val1 = (uart_sel > 0) ? 1 : 0;
+ set_val2 = uart_sel & 0x0001;
+
+ gpio_set_value(GPIO_UART_SEL1, set_val1);
+ gpio_set_value(GPIO_UART_SEL2, set_val2);
+#else
+ uart_sel = gpio_get_value(GPIO_UART_SEL);
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ uart_sel2 = gpio_get_value(GPIO_UART_SEL2);
+#endif
if (!strncasecmp(buf, "AP", 2)) {
uart_sel = 1;
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ uart_sel2 = 0;
+#endif /* (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2) */
} else if (!strncasecmp(buf, "CP", 2)) {
uart_sel = 0;
} else {
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ if (!strncasecmp(buf, "DOCK", 4)) {
+ uart_sel = 1;
+ uart_sel2 = 1;
+ } else {
+#endif /* (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2) */
pr_err("%s: wrong uart_sel value(%s)!!\n", __func__, buf);
return -EINVAL;
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ }
+#endif /* (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2) */
}
/* 1 for AP, 0 for CP */
gpio_set_value(GPIO_UART_SEL, uart_sel);
+ pr_info("%s: uart_sel(%d)\n", __func__, uart_sel);
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ /* 1 for (AP)DOCK, 0 for (AP)FAC */
+ gpio_set_value(GPIO_UART_SEL2, uart_sel2);
+ pr_info("%s: uart_sel2(%d)\n", __func__, uart_sel2);
+#endif /* (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2) */
+#endif /* CONFIG_MACH_P8LTE */
return count;
}
@@ -210,10 +276,22 @@ static void usb_apply_path(enum usb_path_t path)
#else
gpio_set_value(GPIO_USB_SEL1, 0);
gpio_set_value(GPIO_USB_SEL2, 1);
+ /* don't care SEL3 */
+#if defined(CONFIG_MACH_P8LTE)
gpio_set_value(GPIO_USB_SEL3, 1);
-#endif
+#endif /* CONFIG_MACH_P8LTE */
+#endif /* CONFIG_MACH_P4NOTE */
+ goto out_nochange;
+ }
+
+#if defined(CONFIG_MACH_P4NOTE)
+ if (path & USB_PATH_TA) {
+ gpio_set_value(GPIO_USB_SEL0, 0);
+ gpio_set_value(GPIO_USB_SEL1, 0);
goto out_nochange;
}
+#endif /* CONFIG_MACH_P4NOTE */
+
if (path & USB_PATH_CP) {
pr_info("DEBUG: set USB path to CP\n");
#if defined(CONFIG_MACH_P4NOTE)
@@ -222,8 +300,11 @@ static void usb_apply_path(enum usb_path_t path)
#else
gpio_set_value(GPIO_USB_SEL1, 0);
gpio_set_value(GPIO_USB_SEL2, 0);
+ /* don't care SEL3 */
+#if defined(CONFIG_MACH_P8LTE)
gpio_set_value(GPIO_USB_SEL3, 1);
-#endif
+#endif /* CONFIG_MACH_P8LTE */
+#endif /* CONFIG_MACH_P4NOTE */
mdelay(3);
goto out_cp;
}
@@ -241,14 +322,14 @@ static void usb_apply_path(enum usb_path_t path)
goto out_ap;
}
if (path & USB_PATH_HOST) {
-#ifndef CONFIG_MACH_P8LTE
+#if !defined(CONFIG_MACH_P8LTE)
gpio_set_value(GPIO_USB_SEL1, 1);
-#endif
+#endif /* !CONFIG_MACH_P8LTE */
/* don't care SEL2 */
gpio_set_value(GPIO_USB_SEL3, 0);
goto out_ap;
}
-#endif
+#endif /* CONFIG_MACH_P4NOTE */
/* default */
#if defined(CONFIG_MACH_P4NOTE)
@@ -260,9 +341,9 @@ static void usb_apply_path(enum usb_path_t path)
gpio_set_value(GPIO_USB_SEL2, 1);
#else
gpio_set_value(GPIO_USB_SEL2, 0);
-#endif
+#endif /* CONFIG_MACH_P8LTE */
gpio_set_value(GPIO_USB_SEL3, 1);
-#endif
+#endif /* CONFIG_MACH_P4NOTE */
out_ap:
pr_info("%s: %x safeout2 off\n", __func__, path);
@@ -296,6 +377,13 @@ sysfs_noti:
...
usb_switch_unlock(); (this restores previous usb switch settings)
*/
+enum usb_path_t usb_switch_get_path(void)
+{
+ pr_info("%s: current path(%d)\n", __func__, current_path);
+
+ return current_path;
+}
+
void usb_switch_set_path(enum usb_path_t path)
{
pr_info("%s: %x current_path before changing\n",
@@ -332,6 +420,11 @@ void usb_switch_unlock(void)
#ifdef CONFIG_MACH_P4NOTE
static void init_gpio(void)
{
+ int uart_sel = -1;
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ int uart_sel2 = -1;
+#endif /* (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2) */
+
s3c_gpio_cfgpin(GPIO_USB_SEL0, S3C_GPIO_OUTPUT);
s3c_gpio_setpull(GPIO_USB_SEL0, S3C_GPIO_PULL_NONE);
@@ -343,66 +436,164 @@ static void init_gpio(void)
s3c_gpio_cfgpin(GPIO_UART_SEL, S3C_GPIO_OUTPUT);
s3c_gpio_setpull(GPIO_UART_SEL, S3C_GPIO_PULL_NONE);
+
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ s3c_gpio_cfgpin(GPIO_UART_SEL2, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_UART_SEL2, S3C_GPIO_PULL_NONE);
+#endif /* (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2) */
+
+ uart_sel = gpio_get_value(GPIO_UART_SEL);
+ pr_info("%s: uart_sel(%d)\n", __func__, uart_sel);
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ uart_sel2 = gpio_get_value(GPIO_UART_SEL2);
+ pr_info("%s: uart_sel2(%d)\n", __func__, uart_sel2);
+#endif /* (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2) */
+}
+#endif
+
+#ifdef CONFIG_TARGET_LOCALE_KOR
+#include <plat/devs.h>
+#include "../../../drivers/usb/gadget/s3c_udc.h"
+/* usb access control for SEC DM */
+struct device *usb_lock;
+static int is_usb_locked;
+
+int px_switch_get_usb_lock_state(void)
+{
+ return is_usb_locked;
+}
+EXPORT_SYMBOL(px_switch_get_usb_lock_state);
+
+static ssize_t px_switch_show_usb_lock(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (is_usb_locked)
+ return snprintf(buf, PAGE_SIZE, "USB_LOCK");
+ else
+ return snprintf(buf, PAGE_SIZE, "USB_UNLOCK");
+}
+
+static ssize_t px_switch_store_usb_lock(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int lock;
+ struct s3c_udc *udc = platform_get_drvdata(&s3c_device_usbgadget);
+
+ if (!strncmp(buf, "0", 1))
+ lock = 0;
+ else if (!strncmp(buf, "1", 1))
+ lock = 1;
+ else {
+ pr_warn("%s: Wrong command\n", __func__);
+ return count;
+ }
+
+ if (IS_ERR_OR_NULL(udc))
+ return count;
+
+ pr_info("%s: lock=%d\n", __func__, lock);
+
+ if (lock != is_usb_locked) {
+ is_usb_locked = lock;
+
+ if (lock) {
+ if (udc->udc_enabled)
+ usb_gadget_vbus_disconnect(&udc->gadget);
+ }
+ }
+
+ return count;
}
+
+static DEVICE_ATTR(enable, 0664,
+ px_switch_show_usb_lock, px_switch_store_usb_lock);
#endif
static int __init usb_switch_init(void)
{
int ret;
+/* USB_SEL gpio_request */
#if defined(CONFIG_MACH_P4NOTE)
gpio_request(GPIO_USB_SEL0, "GPIO_USB_SEL0");
gpio_request(GPIO_USB_SEL1, "GPIO_USB_SEL1");
gpio_request(GPIO_USB_SEL_CP, "GPIO_USB_SEL_CP");
- gpio_request(GPIO_UART_SEL, "GPIO_UART_SEL");
#else
gpio_request(GPIO_USB_SEL1, "GPIO_USB_SEL1");
gpio_request(GPIO_USB_SEL2, "GPIO_USB_SEL2");
gpio_request(GPIO_USB_SEL3, "GPIO_USB_SEL3");
+#endif /* CONFIG_MACH_P4NOTE */
+
+/* UART_SEL gpio_request */
#ifdef CONFIG_MACH_P8LTE
gpio_request(GPIO_UART_SEL1, "GPIO_UART_SEL1");
gpio_request(GPIO_UART_SEL2, "GPIO_UART_SEL2");
#else
gpio_request(GPIO_UART_SEL, "GPIO_UART_SEL");
-#endif
-#endif
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ gpio_request(GPIO_UART_SEL2, "GPIO_UART_SEL2");
+#endif /* (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2) */
+#endif /* CONFIG_MACH_P8LTE */
+/* USB_SEL gpio_export */
#if defined(CONFIG_MACH_P4NOTE)
gpio_export(GPIO_USB_SEL0, 1);
gpio_export(GPIO_USB_SEL1, 1);
gpio_export(GPIO_USB_SEL_CP, 1);
- gpio_export(GPIO_UART_SEL, 1);
#else
gpio_export(GPIO_USB_SEL1, 1);
gpio_export(GPIO_USB_SEL2, 1);
gpio_export(GPIO_USB_SEL3, 1);
+#endif /* CONFIG_MACH_P4NOTE */
+
+/* UART_SEL gpio_export */
#ifdef CONFIG_MACH_P8LTE
gpio_export(GPIO_UART_SEL1, 1);
gpio_export(GPIO_UART_SEL2, 1);
#else
gpio_export(GPIO_UART_SEL, 1);
-#endif
-#endif
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ gpio_export(GPIO_UART_SEL2, 1);
+#endif /* (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2) */
+#endif /* CONFIG_MACH_P8LTE */
BUG_ON(!sec_class);
sec_switch_dev = device_create(sec_class, NULL, 0, NULL, "switch");
BUG_ON(!sec_switch_dev);
+
+/* USB_SEL gpio_export_link */
#if defined(CONFIG_MACH_P4NOTE)
gpio_export_link(sec_switch_dev, "GPIO_USB_SEL0", GPIO_USB_SEL0);
gpio_export_link(sec_switch_dev, "GPIO_USB_SEL1", GPIO_USB_SEL1);
gpio_export_link(sec_switch_dev, "GPIO_USB_SEL_CP", GPIO_USB_SEL_CP);
- gpio_export_link(sec_switch_dev, "GPIO_UART_SEL", GPIO_UART_SEL);
#else
gpio_export_link(sec_switch_dev, "GPIO_USB_SEL1", GPIO_USB_SEL1);
gpio_export_link(sec_switch_dev, "GPIO_USB_SEL2", GPIO_USB_SEL2);
gpio_export_link(sec_switch_dev, "GPIO_USB_SEL3", GPIO_USB_SEL3);
+#endif /* CONFIG_MACH_P4NOTE */
+
+/* UART_SEL gpio_export_link */
#ifdef CONFIG_MACH_P8LTE
gpio_export_link(sec_switch_dev, "GPIO_UART_SEL1", GPIO_UART_SEL1);
gpio_export_link(sec_switch_dev, "GPIO_UART_SEL2", GPIO_UART_SEL2);
#else
gpio_export_link(sec_switch_dev, "GPIO_UART_SEL", GPIO_UART_SEL);
-#endif
+#if (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2)
+ gpio_export_link(sec_switch_dev, "GPIO_UART_SEL2", GPIO_UART_SEL2);
+#endif /* (CONFIG_SAMSUNG_ANALOG_UART_SWITCH == 2) */
+#endif /* CONFIG_MACH_P8LTE */
+
+#ifdef CONFIG_TARGET_LOCALE_KOR
+ usb_lock = device_create(sec_class, sec_switch_dev,
+ MKDEV(0, 0), NULL, ".usb_lock");
+
+ if (IS_ERR(usb_lock))
+ pr_err("Failed to create device (usb_lock)!\n");
+
+ if (device_create_file(usb_lock, &dev_attr_enable) < 0)
+ pr_err("Failed to create device file(.usblock/enable)!\n");
#endif
/*init_MUTEX(&usb_switch_sem);*/