aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/board-kai-sensors.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/board-kai-sensors.c')
-rw-r--r--arch/arm/mach-tegra/board-kai-sensors.c259
1 files changed, 259 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-kai-sensors.c b/arch/arm/mach-tegra/board-kai-sensors.c
new file mode 100644
index 00000000000..82784ebd973
--- /dev/null
+++ b/arch/arm/mach-tegra/board-kai-sensors.c
@@ -0,0 +1,259 @@
1
2/*
3 * arch/arm/mach-tegra/board-kai-sensors.c
4 *
5 * Copyright (c) 2012, NVIDIA Corporation.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include <linux/delay.h>
22#include <linux/err.h>
23#include <linux/i2c.h>
24#include <linux/cm3217.h>
25#include <linux/mpu.h>
26#include <linux/regulator/consumer.h>
27#include <asm/mach-types.h>
28#include <mach/gpio.h>
29#include <media/ov2710.h>
30#include "board.h"
31#include "board-kai.h"
32#include "cpu-tegra.h"
33
34static struct regulator *kai_1v8_cam3;
35static struct regulator *kai_vdd_cam3;
36
37static struct cm3217_platform_data kai_cm3217_pdata = {
38 .levels = {10, 160, 225, 320, 640, 1280, 2600, 5800, 8000, 10240},
39 .golden_adc = 0,
40 .power = 0,
41};
42
43static struct i2c_board_info kai_i2c0_cm3217_board_info[] = {
44 {
45 I2C_BOARD_INFO("cm3217", 0x10),
46 .platform_data = &kai_cm3217_pdata,
47 },
48};
49
50static int kai_camera_init(void)
51{
52 int ret;
53
54 tegra_gpio_enable(CAM2_POWER_DWN_GPIO);
55 ret = gpio_request(CAM2_POWER_DWN_GPIO, "cam2_power_en");
56 if (ret < 0) {
57 pr_err("%s: gpio_request failed for gpio %s\n",
58 __func__, "CAM2_POWER_DWN_GPIO");
59 }
60
61 gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
62 mdelay(10);
63
64 tegra_gpio_enable(CAM2_RST_GPIO);
65 ret = gpio_request(CAM2_RST_GPIO, "cam2_reset");
66 if (ret < 0) {
67 pr_err("%s: gpio_request failed for gpio %s\n",
68 __func__, "CAM2_RST_GPIO");
69 }
70
71 gpio_direction_output(CAM2_RST_GPIO, 0);
72 mdelay(5);
73
74 return 0;
75}
76
77static int kai_ov2710_power_on(void)
78{
79 gpio_direction_output(CAM2_POWER_DWN_GPIO, 0);
80 mdelay(10);
81
82 if (kai_vdd_cam3 == NULL) {
83 kai_vdd_cam3 = regulator_get(NULL, "vdd_cam3");
84 if (WARN_ON(IS_ERR(kai_vdd_cam3))) {
85 pr_err("%s: couldn't get regulator vdd_cam3: %d\n",
86 __func__, PTR_ERR(kai_vdd_cam3));
87 goto reg_get_vdd_cam3_fail;
88 }
89 }
90 regulator_enable(kai_vdd_cam3);
91
92 if (kai_1v8_cam3 == NULL) {
93 kai_1v8_cam3 = regulator_get(NULL, "vdd_1v8_cam3");
94 if (WARN_ON(IS_ERR(kai_1v8_cam3))) {
95 pr_err("%s: couldn't get regulator vdd_1v8_cam3: %d\n",
96 __func__, PTR_ERR(kai_1v8_cam3));
97 goto reg_get_vdd_1v8_cam3_fail;
98 }
99 }
100 regulator_enable(kai_1v8_cam3);
101 mdelay(5);
102
103 gpio_direction_output(CAM2_RST_GPIO, 1);
104 mdelay(10);
105
106 return 0;
107
108reg_get_vdd_1v8_cam3_fail:
109 kai_1v8_cam3 = NULL;
110 regulator_put(kai_vdd_cam3);
111
112reg_get_vdd_cam3_fail:
113 kai_vdd_cam3 = NULL;
114
115 return -ENODEV;
116}
117
118static int kai_ov2710_power_off(void)
119{
120 gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
121
122 gpio_direction_output(CAM2_RST_GPIO, 0);
123
124 if (kai_1v8_cam3)
125 regulator_disable(kai_1v8_cam3);
126 if (kai_vdd_cam3)
127 regulator_disable(kai_vdd_cam3);
128
129 return 0;
130}
131
132struct ov2710_platform_data kai_ov2710_data = {
133 .power_on = kai_ov2710_power_on,
134 .power_off = kai_ov2710_power_off,
135};
136
137static struct i2c_board_info kai_i2c2_board_info[] = {
138 {
139 I2C_BOARD_INFO("ov2710", 0x36),
140 .platform_data = &kai_ov2710_data,
141 },
142};
143
144/* MPU board file definition */
145
146#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
147#define MPU_GYRO_NAME "mpu3050"
148#endif
149#if (MPU_GYRO_TYPE == MPU_TYPE_MPU6050)
150#define MPU_GYRO_NAME "mpu6050"
151#endif
152
153static struct mpu_platform_data mpu_gyro_data = {
154 .int_config = 0x10,
155 .level_shifter = 0,
156 .orientation = MPU_GYRO_ORIENTATION,
157};
158
159#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
160static struct ext_slave_platform_data mpu_accel_data = {
161 .address = MPU_ACCEL_ADDR,
162 .irq = 0,
163 .adapt_num = MPU_ACCEL_BUS_NUM,
164 .bus = EXT_SLAVE_BUS_SECONDARY,
165 .orientation = MPU_ACCEL_ORIENTATION,
166};
167#endif
168
169static struct ext_slave_platform_data mpu_compass_data = {
170 .address = MPU_COMPASS_ADDR,
171 .irq = 0,
172 .adapt_num = MPU_COMPASS_BUS_NUM,
173 .bus = EXT_SLAVE_BUS_PRIMARY,
174 .orientation = MPU_COMPASS_ORIENTATION,
175};
176
177static struct i2c_board_info __initdata inv_mpu_i2c0_board_info[] = {
178 {
179 I2C_BOARD_INFO(MPU_GYRO_NAME, MPU_GYRO_ADDR),
180 .irq = TEGRA_GPIO_TO_IRQ(MPU_GYRO_IRQ_GPIO),
181 .platform_data = &mpu_gyro_data,
182 },
183#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
184 {
185 I2C_BOARD_INFO(MPU_ACCEL_NAME, MPU_ACCEL_ADDR),
186#if MPU_ACCEL_IRQ_GPIO
187 .irq = TEGRA_GPIO_TO_IRQ(MPU_ACCEL_IRQ_GPIO),
188#endif
189 .platform_data = &mpu_accel_data,
190 },
191#endif
192 {
193 I2C_BOARD_INFO(MPU_COMPASS_NAME, MPU_COMPASS_ADDR),
194#if MPU_COMPASS_IRQ_GPIO
195 .irq = TEGRA_GPIO_TO_IRQ(MPU_COMPASS_IRQ_GPIO),
196#endif
197 .platform_data = &mpu_compass_data,
198 },
199};
200
201static void mpuirq_init(void)
202{
203 int ret = 0;
204
205 pr_info("*** MPU START *** mpuirq_init...\n");
206
207#if (MPU_GYRO_TYPE == MPU_TYPE_MPU3050)
208#if MPU_ACCEL_IRQ_GPIO
209 /* ACCEL-IRQ assignment */
210 tegra_gpio_enable(MPU_ACCEL_IRQ_GPIO);
211 ret = gpio_request(MPU_ACCEL_IRQ_GPIO, MPU_ACCEL_NAME);
212 if (ret < 0) {
213 pr_err("%s: gpio_request failed %d\n", __func__, ret);
214 return;
215 }
216
217 ret = gpio_direction_input(MPU_ACCEL_IRQ_GPIO);
218 if (ret < 0) {
219 pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
220 gpio_free(MPU_ACCEL_IRQ_GPIO);
221 return;
222 }
223#endif
224#endif
225
226 /* MPU-IRQ assignment */
227 tegra_gpio_enable(MPU_GYRO_IRQ_GPIO);
228 ret = gpio_request(MPU_GYRO_IRQ_GPIO, MPU_GYRO_NAME);
229 if (ret < 0) {
230 pr_err("%s: gpio_request failed %d\n", __func__, ret);
231 return;
232 }
233
234 ret = gpio_direction_input(MPU_GYRO_IRQ_GPIO);
235 if (ret < 0) {
236 pr_err("%s: gpio_direction_input failed %d\n", __func__, ret);
237 gpio_free(MPU_GYRO_IRQ_GPIO);
238 return;
239 }
240 pr_info("*** MPU END *** mpuirq_init...\n");
241
242 i2c_register_board_info(MPU_GYRO_BUS_NUM, inv_mpu_i2c0_board_info,
243 ARRAY_SIZE(inv_mpu_i2c0_board_info));
244}
245
246int __init kai_sensors_init(void)
247{
248 kai_camera_init();
249
250 i2c_register_board_info(2, kai_i2c2_board_info,
251 ARRAY_SIZE(kai_i2c2_board_info));
252
253 i2c_register_board_info(0, kai_i2c0_cm3217_board_info,
254 ARRAY_SIZE(kai_i2c0_cm3217_board_info));
255
256 mpuirq_init();
257
258 return 0;
259}