diff options
Diffstat (limited to 'arch/arm/mach-exynos/px-switch.c')
-rw-r--r-- | arch/arm/mach-exynos/px-switch.c | 225 |
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);*/ |