aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos/u1-wimax.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-exynos/u1-wimax.c')
-rw-r--r--arch/arm/mach-exynos/u1-wimax.c327
1 files changed, 327 insertions, 0 deletions
diff --git a/arch/arm/mach-exynos/u1-wimax.c b/arch/arm/mach-exynos/u1-wimax.c
new file mode 100644
index 0000000..9743a6e
--- /dev/null
+++ b/arch/arm/mach-exynos/u1-wimax.c
@@ -0,0 +1,327 @@
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/skbuff.h>
+#include <linux/wimax/samsung/wimax732.h>
+
+#include <plat/devs.h>
+#include <plat/sdhci.h>
+#include <plat/gpio-cfg.h>
+#include <mach/regs-gpio.h>
+#include <mach/gpio.h>
+#include <mach/gpio-u1.h>
+#include <linux/wimax/samsung/max8893.h>
+
+#if defined(CONFIG_WIMAX_CMC) /* && defined(CONFIG_TARGET_LOCALE_NA)*/
+
+void wimax_on_pin_conf(int onoff)
+{
+ int gpio;
+ if (onoff) {
+
+ for (gpio = EXYNOS4_GPK3(0); gpio < EXYNOS4_GPK3(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+
+ for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(2));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+
+ } else {
+ for (gpio = EXYNOS4_GPK3(0); gpio < EXYNOS4_GPK3(2); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_DOWN);
+ }
+ for (gpio = EXYNOS4_GPK3(3); gpio <= EXYNOS4_GPK3(6); gpio++) {
+ s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0));
+ s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
+ }
+
+ }
+
+}
+
+static void wimax_deinit_gpios(void);
+static void wimax_wakeup_assert(int enable)
+{
+ gpio_set_value(GPIO_WIMAX_WAKEUP, !enable);
+}
+
+static int get_wimax_sleep_mode(void)
+{
+ return gpio_get_value(GPIO_WIMAX_IF_MODE1);
+}
+
+static int is_wimax_active(void)
+{
+ return gpio_get_value(GPIO_WIMAX_CON0);
+}
+
+static void signal_ap_active(int enable)
+{
+ gpio_set_value(GPIO_WIMAX_CON1, enable);
+}
+
+static void switch_eeprom_wimax(void)
+{
+ gpio_set_value(GPIO_WIMAX_I2C_CON, GPIO_LEVEL_LOW);
+ usleep_range(10000, 10000);
+}
+
+static void switch_usb_ap(void)
+{
+ gpio_set_value(GPIO_WIMAX_USB_EN, GPIO_LEVEL_LOW);
+#if defined(CONFIG_MACH_C1_REV02)
+ gpio_set_value(USB_SEL, GPIO_LEVEL_LOW);
+#endif /* CONFIG_MACH_C1_REV02 */
+ usleep_range(10000, 10000);
+}
+
+static void switch_usb_wimax(void)
+{
+ gpio_set_value(GPIO_WIMAX_USB_EN, GPIO_LEVEL_HIGH);
+#if defined(CONFIG_MACH_C1_REV02)
+ gpio_set_value(USB_SEL, GPIO_LEVEL_HIGH);
+#endif /* CONFIG_MACH_C1_REV02 */
+ usleep_range(10000, 10000);
+}
+
+#if defined(CONFIG_UART_SWITCH_AND_GPIO_DUMP_FOR_WIMAX)
+static void switch_uart_ap(void)
+{
+ gpio_set_value(GPIO_UART_SEL, GPIO_LEVEL_HIGH);
+}
+#endif
+
+#if 1
+static void switch_uart_wimax(void)
+{
+ gpio_set_value(GPIO_UART_SEL, GPIO_LEVEL_LOW);
+ gpio_set_value(GPIO_UART_SEL1, GPIO_LEVEL_HIGH);
+}
+#endif
+
+static void wimax_init_gpios(void)
+{
+ s3c_gpio_cfgpin(GPIO_WIMAX_INT, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_INT, S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(GPIO_WIMAX_CON0, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_CON0, S3C_GPIO_PULL_UP);
+ /* default idle */
+ gpio_set_value(GPIO_WIMAX_IF_MODE1, GPIO_LEVEL_HIGH);
+ /* active low interrupt */
+ gpio_set_value(GPIO_WIMAX_CON2, GPIO_LEVEL_HIGH);
+ gpio_set_value(GPIO_WIMAX_CON1, GPIO_LEVEL_HIGH);
+}
+
+static void wimax_hsmmc_presence_check(int card_present)
+{
+ mmc_force_presence_change(&s3c_device_hsmmc3);
+}
+
+#if defined(CONFIG_UART_SWITCH_AND_GPIO_DUMP_FOR_WIMAX)
+static void display_gpios(void)
+{
+ int val = 0;
+ val = gpio_get_value(GPIO_WIMAX_EN);
+ dump_debug("WIMAX_EN: %d", val);
+ val = gpio_get_value(GPIO_WIMAX_RESET_N);
+ dump_debug("WIMAX_RESET: %d", val);
+ val = gpio_get_value(GPIO_WIMAX_CON0);
+ dump_debug("WIMAX_CON0: %d", val);
+ val = gpio_get_value(GPIO_WIMAX_CON1);
+ dump_debug("WIMAX_CON1: %d", val);
+ val = gpio_get_value(GPIO_WIMAX_CON2);
+ dump_debug("WIMAX_CON2: %d", val);
+ val = gpio_get_value(GPIO_WIMAX_WAKEUP);
+ dump_debug("WIMAX_WAKEUP: %d", val);
+ val = gpio_get_value(GPIO_WIMAX_INT);
+ dump_debug("WIMAX_INT: %d", val);
+ val = gpio_get_value(GPIO_WIMAX_IF_MODE0);
+ dump_debug("WIMAX_IF_MODE0: %d", val);
+ val = gpio_get_value(GPIO_WIMAX_IF_MODE1);
+ dump_debug("WIMAX_IF_MODE1: %d", val);
+ val = gpio_get_value(GPIO_WIMAX_USB_EN);
+ dump_debug("WIMAX_USB_EN: %d", val);
+ val = gpio_get_value(GPIO_WIMAX_I2C_CON);
+ dump_debug("I2C_SEL: %d", val);
+#if defined(CONFIG_MACH_C1_REV02)
+ val = gpio_get_value(USB_SEL);
+ dump_debug("WIMAX_USB_SEL: %d", val);
+#endif /* CONFIG_MACH_C1_REV02 */
+ val = gpio_get_value(GPIO_UART_SEL);
+ dump_debug("UART_SEL1: %d", val);
+}
+#endif
+
+static void hw_set_wimax_mode(void);
+static void restore_uart_path(void);
+static void store_uart_path(void);
+static int gpio_wimax_power(int);
+
+static struct wimax732_platform_data wimax732_pdata = {
+ .power = gpio_wimax_power,
+ .detect = wimax_hsmmc_presence_check,
+ .set_mode = hw_set_wimax_mode,
+ .signal_ap_active = signal_ap_active,
+ .get_sleep_mode = get_wimax_sleep_mode,
+ .is_modem_awake = is_wimax_active,
+ .wakeup_assert = wimax_wakeup_assert,
+#if defined(CONFIG_UART_SWITCH_AND_GPIO_DUMP_FOR_WIMAX)
+ .uart_wimax = switch_uart_wimax,
+ .uart_ap = switch_uart_ap,
+ .gpio_display = display_gpios,
+#endif
+ .g_cfg = NULL,
+ .wimax_int = GPIO_WIMAX_INT,
+ .restore_uart_path = restore_uart_path,
+};
+
+static int gpio_wimax_power(int enable)
+{
+ if (!enable)
+ goto wimax_power_off;
+ pr_err("Wimax power ON");
+ if (wimax732_pdata.g_cfg->wimax_mode != SDIO_MODE) {
+ switch_usb_wimax();
+ s3c_bat_use_wimax(1);
+ }
+ if (wimax732_pdata.g_cfg->wimax_mode == WTM_MODE) {
+ store_uart_path();
+ switch_uart_wimax();
+ }
+ switch_eeprom_wimax();
+ wimax_on_pin_conf(1);
+ /*s3c_gpio_setpull(GPIO_WIMAX_EN, S3C_GPIO_PULL_UP);*/
+ gpio_set_value(GPIO_WIMAX_EN, GPIO_LEVEL_HIGH);
+
+ wimax_init_gpios();
+
+ s3c_gpio_cfgpin(EXYNOS4_GPB(2), S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(EXYNOS4_GPB(2), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(EXYNOS4_GPB(3), S3C_GPIO_SFN(3));
+ s3c_gpio_setpull(EXYNOS4_GPB(3), S3C_GPIO_PULL_UP);
+
+ wimax_pmic_set_voltage();
+ pr_err("RESET");
+ gpio_set_value(GPIO_WIMAX_RESET_N, GPIO_LEVEL_LOW);
+ mdelay(3);
+ gpio_set_value(GPIO_WIMAX_RESET_N, GPIO_LEVEL_HIGH);
+ return WIMAX_POWER_SUCCESS;
+ wimax_power_off:
+ wimax_deinit_gpios();
+ pr_err("Wimax power OFF");
+
+ if (wimax732_pdata.g_cfg->wimax_mode != SDIO_MODE)
+ s3c_bat_use_wimax(0);
+
+ wimax_on_pin_conf(0);
+
+ return WIMAX_POWER_SUCCESS;
+}
+
+static void wimax_deinit_gpios(void)
+{
+ s3c_gpio_cfgpin(GPIO_WIMAX_DBGEN_28V, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_DBGEN_28V, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WIMAX_DBGEN_28V, GPIO_LEVEL_LOW);
+ s3c_gpio_cfgpin(GPIO_WIMAX_I2C_CON, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_I2C_CON, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WIMAX_I2C_CON, GPIO_LEVEL_HIGH);
+
+ s3c_gpio_cfgpin(GPIO_WIMAX_WAKEUP, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_WAKEUP, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WIMAX_WAKEUP, GPIO_LEVEL_LOW);
+ s3c_gpio_cfgpin(GPIO_WIMAX_IF_MODE0, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_IF_MODE0, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WIMAX_IF_MODE0, GPIO_LEVEL_LOW);
+ s3c_gpio_cfgpin(GPIO_WIMAX_CON0, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_CON0, S3C_GPIO_PULL_DOWN);
+ s3c_gpio_cfgpin(GPIO_WIMAX_IF_MODE1, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_IF_MODE1, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WIMAX_IF_MODE1, GPIO_LEVEL_LOW);
+ s3c_gpio_cfgpin(GPIO_WIMAX_CON2, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_CON2, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WIMAX_CON2, GPIO_LEVEL_LOW);
+ s3c_gpio_cfgpin(GPIO_WIMAX_CON1, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_CON1, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WIMAX_CON1, GPIO_LEVEL_LOW);
+ s3c_gpio_cfgpin(GPIO_WIMAX_RESET_N, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_RESET_N, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WIMAX_RESET_N, GPIO_LEVEL_LOW);
+ s3c_gpio_cfgpin(GPIO_WIMAX_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WIMAX_EN, GPIO_LEVEL_LOW);
+ s3c_gpio_cfgpin(GPIO_WIMAX_USB_EN, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_USB_EN, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WIMAX_USB_EN, GPIO_LEVEL_LOW);
+#if defined(CONFIG_MACH_C1_REV02)
+ s3c_gpio_cfgpin(USB_SEL, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(USB_SEL, S3C_GPIO_PULL_NONE);
+#endif /* CONFIG_MACH_C1_REV02 */
+ s3c_gpio_cfgpin(GPIO_UART_SEL1, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_UART_SEL1, S3C_GPIO_PULL_NONE);
+ s3c_gpio_cfgpin(GPIO_UART_SEL, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_UART_SEL, S3C_GPIO_PULL_NONE);
+
+ s3c_gpio_cfgpin(GPIO_CMC_SCL_18V, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CMC_SCL_18V, S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(GPIO_CMC_SDA_18V, S3C_GPIO_INPUT);
+ s3c_gpio_setpull(GPIO_CMC_SDA_18V, S3C_GPIO_PULL_DOWN);
+
+ s3c_gpio_cfgpin(GPIO_WIMAX_INT, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_WIMAX_INT, S3C_GPIO_PULL_NONE);
+ gpio_set_value(GPIO_WIMAX_INT, GPIO_LEVEL_LOW);
+
+ switch_usb_ap();
+}
+
+static void store_uart_path(void)
+{
+ wimax732_pdata.uart_sel = gpio_get_value(GPIO_UART_SEL);
+ wimax732_pdata.uart_sel1 = gpio_get_value(GPIO_UART_SEL1);
+}
+
+static void restore_uart_path(void)
+{
+ gpio_set_value(GPIO_UART_SEL, wimax732_pdata.uart_sel);
+ gpio_set_value(GPIO_UART_SEL1, wimax732_pdata.uart_sel1);
+}
+
+static void hw_set_wimax_mode(void)
+{
+ switch (wimax732_pdata.g_cfg->wimax_mode) {
+ case SDIO_MODE:
+ pr_err("SDIO MODE");
+ gpio_set_value(GPIO_WIMAX_WAKEUP, GPIO_LEVEL_HIGH);
+ gpio_set_value(GPIO_WIMAX_IF_MODE0, GPIO_LEVEL_HIGH);
+ break;
+ case WTM_MODE:
+ case AUTH_MODE:
+ pr_err("WTM_MODE || AUTH_MODE");
+ gpio_set_value(GPIO_WIMAX_WAKEUP, GPIO_LEVEL_LOW);
+ gpio_set_value(GPIO_WIMAX_IF_MODE0, GPIO_LEVEL_LOW);
+ break;
+ case DM_MODE:
+ pr_err("DM MODE");
+ gpio_set_value(GPIO_WIMAX_WAKEUP, GPIO_LEVEL_HIGH);
+ gpio_set_value(GPIO_WIMAX_IF_MODE0, GPIO_LEVEL_LOW);
+ break;
+ case USB_MODE:
+ case USIM_RELAY_MODE:
+ pr_err("USB MODE");
+ gpio_set_value(GPIO_WIMAX_WAKEUP, GPIO_LEVEL_LOW);
+ gpio_set_value(GPIO_WIMAX_IF_MODE0, GPIO_LEVEL_HIGH);
+ break;
+ }
+}
+
+struct platform_device s3c_device_cmc732 = {
+ .name = "wimax732_driver",
+ .id = 1,
+ .dev.platform_data = &wimax732_pdata,
+};
+
+#endif