From 8928dee2d0ddef01bff38c0cbb7931487f66de39 Mon Sep 17 00:00:00 2001 From: Ramalingam C Date: Wed, 11 Jul 2012 14:47:48 +0530 Subject: arm: tegra: cardhu: IrDA support on UARTB Adds the IrDA support functions to the platform_data of UARTB on Verbier boards(E1198 and E1186). And also adds a config variable CONFIG_TEGRA_IRDA to control the IrDA support on Tegra. Bug 999895 Change-Id: Iab77c419004292190421d55fd02e249ff98c728e Signed-off-by: Ramalingam C Reviewed-on: http://git-master/r/114930 Reviewed-by: Simone Willett Tested-by: Simone Willett --- arch/arm/mach-tegra/Kconfig | 8 ++ arch/arm/mach-tegra/Makefile | 1 + arch/arm/mach-tegra/board-cardhu-irda.c | 178 ++++++++++++++++++++++++++++++++ arch/arm/mach-tegra/board-cardhu.c | 25 +++++ arch/arm/mach-tegra/board-cardhu.h | 2 + 5 files changed, 214 insertions(+) create mode 100644 arch/arm/mach-tegra/board-cardhu-irda.c diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index b84d32add5f8..b69f0dc6e24d 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -90,6 +90,14 @@ config TEGRA_PCI help Adds PCIe Host controller driver for tegra based systems +config TEGRA_IRDA + bool "IRDA on UARTB Port of Verbier" + select IRDA_CPLD + depends on ARCH_TEGRA_3x_SOC && MACH_CARDHU + help + Adds support for Vishay IrDA transceiver at UARTB port + of Verbier Boards(E1186 and E1198) with no ULPI rework done. + comment "Tegra board type" config MACH_HARMONY diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile index 6a563be1495a..cf51359c32e7 100644 --- a/arch/arm/mach-tegra/Makefile +++ b/arch/arm/mach-tegra/Makefile @@ -163,6 +163,7 @@ obj-${CONFIG_MACH_WHISTLER} += board-whistler-memory.o obj-${CONFIG_MACH_CARDHU} += board-cardhu.o obj-${CONFIG_MACH_CARDHU} += board-cardhu-kbc.o +obj-${CONFIG_MACH_CARDHU} += board-cardhu-irda.o obj-${CONFIG_MACH_CARDHU} += board-cardhu-panel.o obj-${CONFIG_MACH_CARDHU} += board-cardhu-pinmux.o obj-${CONFIG_MACH_CARDHU} += board-cardhu-power.o diff --git a/arch/arm/mach-tegra/board-cardhu-irda.c b/arch/arm/mach-tegra/board-cardhu-irda.c new file mode 100644 index 000000000000..489d473fc08f --- /dev/null +++ b/arch/arm/mach-tegra/board-cardhu-irda.c @@ -0,0 +1,178 @@ +/* + * arch/arm/mach-tegra/board-cardhu-irda.c + * + * Copyright (c) 2012, NVIDIA Corporation. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* This driver tested with tfdu6103 irda transceiver */ + +#include +#include +#include +#include + +#include "gpio-names.h" +#include "board-cardhu.h" +#include "board.h" +#include "devices.h" + +/* Uncomment the next line to get the function entry logs */ +/*#define DRV_FUNC 1*/ + +#undef FPRINT +#ifdef DRV_FUNC +#define FPRINT(fmt, args...) printk(KERN_INFO "IRDA: " fmt, ## args) +#else +#define FPRINT(fmt, args...) +#endif + +#define CARDHU_IRDA_SD TEGRA_GPIO_PJ6 +#define CARDHU_IRDA_TX TEGRA_GPIO_PC2 +#define CARDHU_IRDA_RX TEGRA_GPIO_PC3 + +#define IRDA_DELAY 1 + +#define SIR 1 +#define FIR 2 +#define VFIR 3 /* tfdu6108 doesn't support */ + + +static int irda_mode; + +/* If mode = SIR mode switch will be FIR -> SIR + If mode = FIR mode switch will be SIR ->FIR */ + +static int cardhu_irda_mode_switch(int mode) +{ + int ret = -1; + + FPRINT("Start of Func %s\n", __func__); + + if ((mode != SIR) && (mode != FIR)) { + pr_err("Unsupported irda mode\n"); + return ret; + } + + gpio_set_value(CARDHU_IRDA_SD, 1); + + udelay(IRDA_DELAY); + + ret = gpio_request(CARDHU_IRDA_TX, "irda_tx"); + if (ret < 0) { + pr_err("%s: cardhu_irda_tx gpio request failed %d\n", + __func__, ret); + gpio_set_value(CARDHU_IRDA_SD, 0); + return ret; + } + + if (mode == SIR) + ret = gpio_direction_output(CARDHU_IRDA_TX, 0); + else if (mode == FIR) + ret = gpio_direction_output(CARDHU_IRDA_TX, 1); + + if (ret) { + pr_err("%s: cardhu_irda_tx Direction configuration failed %d\n", + __func__, ret); + gpio_set_value(CARDHU_IRDA_SD, 0); + goto closure; + } + + udelay(IRDA_DELAY); + + gpio_set_value(CARDHU_IRDA_SD, 0); + + udelay(IRDA_DELAY); + + if (mode == FIR) { + gpio_set_value(CARDHU_IRDA_TX, 0); + irda_mode = FIR; + pr_info("IrDA Transceiver is switched to FIR mode\n"); + } else { + pr_info("IrDA Transceiver is switched to SIR mode\n"); + irda_mode = SIR; + } + + udelay(IRDA_DELAY); + +closure: + gpio_free(CARDHU_IRDA_TX); + return ret; +} + +static int SD_config(void) +{ + int ret = -1; + + FPRINT("Start of the Func %s\n", __func__); + /* Gpio enable for SD */ + ret = gpio_request(CARDHU_IRDA_SD, "irda_sd"); + if (ret < 0) { + pr_err("%s: cardhu_irda_sd gpio request failed %d\n", + __func__, ret); + return ret; + } + + ret = gpio_direction_output(CARDHU_IRDA_SD, 1); + if (ret) + pr_err("%s: cardhu_irda_sd Direction configuration failed %d\n", + __func__, ret); + return ret; +} + +static void cardhu_irda_start(void) +{ + FPRINT("Start of the Func %s\n", __func__); + pr_info("IrDA transceiver is enabled\n"); + gpio_set_value(CARDHU_IRDA_SD, 0); + irda_mode = SIR; +} + +static void cardhu_irda_shutdown(void) +{ + FPRINT("Start of the Func %s\n", __func__); + pr_info("IrDA transceiver is disabled\n"); + /* Setting the IrDA transceiver into shutdown mode*/ + gpio_set_value(CARDHU_IRDA_SD, 1); +} + +static int cardhu_irda_init(void) +{ + int ret = 0; + + FPRINT("Start of the Func %s\n", __func__); + if (SD_config() < 0) { + pr_err("%s: Error in IRDA_SD signal configuration\n", __func__); + ret = -1; + } + return ret; +} + +static void cardhu_irda_remove(void) +{ + FPRINT("Start of the Func %s\n", __func__); + gpio_free(CARDHU_IRDA_SD); +} + + +struct tegra_uart_platform_data cardhu_irda_pdata = { + .is_irda = true, + .irda_init = cardhu_irda_init, + .irda_start = cardhu_irda_start, + .irda_mode_switch = cardhu_irda_mode_switch, + .irda_shutdown = cardhu_irda_shutdown, + .irda_remove = cardhu_irda_remove, +}; diff --git a/arch/arm/mach-tegra/board-cardhu.c b/arch/arm/mach-tegra/board-cardhu.c index f8fb5c528cbd..80cab77df587 100644 --- a/arch/arm/mach-tegra/board-cardhu.c +++ b/arch/arm/mach-tegra/board-cardhu.c @@ -492,6 +492,16 @@ static void __init uart_debug_init(void) debug_port_id = 1; } +#ifdef CONFIG_TEGRA_IRDA + if ((board_info.board_id == BOARD_E1186) || + (board_info.board_id == BOARD_E1198)) { + if (debug_port_id == 1) { + cardhu_irda_pdata.is_irda = false; + pr_err("UARTB is not available for IrDA\n"); + } + } +#endif + switch (debug_port_id) { case 0: /* UARTA is the debug port. */ @@ -553,6 +563,9 @@ static void __init cardhu_uart_init(void) { struct clk *c; int i; + struct board_info board_info; + + tegra_get_board_info(&board_info); for (i = 0; i < ARRAY_SIZE(uart_parent_clk); ++i) { c = tegra_get_clock_by_name(uart_parent_clk[i].name); @@ -598,6 +611,18 @@ static void __init cardhu_uart_init(void) } } +#ifdef CONFIG_TEGRA_IRDA + if (((board_info.board_id == BOARD_E1186) || + (board_info.board_id == BOARD_E1198)) && + cardhu_irda_pdata.is_irda) { + cardhu_irda_pdata.parent_clk_list = uart_parent_clk; + cardhu_irda_pdata.parent_clk_count = + ARRAY_SIZE(uart_parent_clk); + + tegra_uartb_device.dev.platform_data = &cardhu_irda_pdata; + } +#endif + platform_add_devices(cardhu_uart_devices, ARRAY_SIZE(cardhu_uart_devices)); } diff --git a/arch/arm/mach-tegra/board-cardhu.h b/arch/arm/mach-tegra/board-cardhu.h index a8be32ec9cdd..7c6a132421f0 100644 --- a/arch/arm/mach-tegra/board-cardhu.h +++ b/arch/arm/mach-tegra/board-cardhu.h @@ -221,6 +221,8 @@ int cardhu_pm298_regulator_init(void); int cardhu_pm299_gpio_switch_regulator_init(void); int cardhu_pm299_regulator_init(void); +extern struct tegra_uart_platform_data cardhu_irda_pdata; + #define MPU_TYPE_MPU3050 1 #define MPU_TYPE_MPU6050 2 #define MPU_GYRO_TYPE MPU_TYPE_MPU3050 -- cgit v1.2.3