summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/board-cardhu-irda.c
blob: 489d473fc08ff922f644dda1a225aabb7be5647e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
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 <linux/gpio.h>
#include <linux/delay.h>
#include <linux/serial_8250.h>
#include <linux/tegra_uart.h>

#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,
};