aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-tegra/board-whistler-sensors.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /arch/arm/mach-tegra/board-whistler-sensors.c
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'arch/arm/mach-tegra/board-whistler-sensors.c')
-rw-r--r--arch/arm/mach-tegra/board-whistler-sensors.c405
1 files changed, 405 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/board-whistler-sensors.c b/arch/arm/mach-tegra/board-whistler-sensors.c
new file mode 100644
index 00000000000..95bb2f1dd40
--- /dev/null
+++ b/arch/arm/mach-tegra/board-whistler-sensors.c
@@ -0,0 +1,405 @@
1/*
2 * arch/arm/mach-tegra/board-whistler-sensors.c
3 *
4 * Copyright (c) 2010-2011, NVIDIA CORPORATION, All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * Neither the name of NVIDIA CORPORATION nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
22 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include <linux/delay.h>
35#include <linux/i2c.h>
36#include <mach/gpio.h>
37#include <media/ov5650.h>
38#include <media/soc380.h>
39#include <linux/regulator/consumer.h>
40#include <linux/err.h>
41#include <linux/adt7461.h>
42#include <generated/mach-types.h>
43#include <linux/gpio.h>
44#include <linux/i2c/pca953x.h>
45
46#include <mach/tegra_odm_fuses.h>
47
48#include "gpio-names.h"
49#include "cpu-tegra.h"
50#include "board-whistler.h"
51
52#define CAMERA1_PWDN_GPIO TEGRA_GPIO_PT2
53#define CAMERA1_RESET_GPIO TEGRA_GPIO_PD2
54#define CAMERA2_PWDN_GPIO TEGRA_GPIO_PBB5
55#define CAMERA2_RESET_GPIO TEGRA_GPIO_PBB1
56#define CAMERA_AF_PD_GPIO TEGRA_GPIO_PT3
57#define CAMERA_FLASH_EN1_GPIO TEGRA_GPIO_PBB4
58#define CAMERA_FLASH_EN2_GPIO TEGRA_GPIO_PA0
59
60#define FUSE_POWER_EN_GPIO (TCA6416_GPIO_BASE + 2)
61
62#define ADXL34X_IRQ_GPIO TEGRA_GPIO_PAA1
63#define ISL29018_IRQ_GPIO TEGRA_GPIO_PK2
64#define ADT7461_IRQ_GPIO TEGRA_GPIO_PI2
65
66static struct regulator *reg_avdd_cam1; /* LDO9 */
67static struct regulator *reg_vdd_af; /* LDO13 */
68static struct regulator *reg_vdd_mipi; /* LDO17 */
69static struct regulator *reg_vddio_vi; /* LDO18 */
70
71static int whistler_camera_init(void)
72{
73 tegra_gpio_enable(CAMERA1_PWDN_GPIO);
74 gpio_request(CAMERA1_PWDN_GPIO, "camera1_powerdown");
75 gpio_direction_output(CAMERA1_PWDN_GPIO, 0);
76 gpio_export(CAMERA1_PWDN_GPIO, false);
77
78 tegra_gpio_enable(CAMERA1_RESET_GPIO);
79 gpio_request(CAMERA1_RESET_GPIO, "camera1_reset");
80 gpio_direction_output(CAMERA1_RESET_GPIO, 0);
81 gpio_export(CAMERA1_RESET_GPIO, false);
82
83 tegra_gpio_enable(CAMERA2_PWDN_GPIO);
84 gpio_request(CAMERA2_PWDN_GPIO, "camera2_powerdown");
85 gpio_direction_output(CAMERA2_PWDN_GPIO, 0);
86 gpio_export(CAMERA2_PWDN_GPIO, false);
87
88 tegra_gpio_enable(CAMERA2_RESET_GPIO);
89 gpio_request(CAMERA2_RESET_GPIO, "camera2_reset");
90 gpio_direction_output(CAMERA2_RESET_GPIO, 0);
91 gpio_export(CAMERA2_RESET_GPIO, false);
92
93 tegra_gpio_enable(CAMERA_AF_PD_GPIO);
94 gpio_request(CAMERA_AF_PD_GPIO, "camera_autofocus");
95 gpio_direction_output(CAMERA_AF_PD_GPIO, 0);
96 gpio_export(CAMERA_AF_PD_GPIO, false);
97
98 tegra_gpio_enable(CAMERA_FLASH_EN1_GPIO);
99 gpio_request(CAMERA_FLASH_EN1_GPIO, "camera_flash_en1");
100 gpio_direction_output(CAMERA_FLASH_EN1_GPIO, 0);
101 gpio_export(CAMERA_FLASH_EN1_GPIO, false);
102
103 tegra_gpio_enable(CAMERA_FLASH_EN2_GPIO);
104 gpio_request(CAMERA_FLASH_EN2_GPIO, "camera_flash_en2");
105 gpio_direction_output(CAMERA_FLASH_EN2_GPIO, 0);
106 gpio_export(CAMERA_FLASH_EN2_GPIO, false);
107
108 gpio_set_value(CAMERA1_PWDN_GPIO, 1);
109 mdelay(5);
110
111 return 0;
112}
113
114static int whistler_ov5650_power_on(void)
115{
116 gpio_set_value(CAMERA1_PWDN_GPIO, 0);
117
118 if (!reg_avdd_cam1) {
119 reg_avdd_cam1 = regulator_get(NULL, "vdd_cam1");
120 if (IS_ERR_OR_NULL(reg_avdd_cam1)) {
121 pr_err("whistler_ov5650_power_on: vdd_cam1 failed\n");
122 reg_avdd_cam1 = NULL;
123 return PTR_ERR(reg_avdd_cam1);
124 }
125 regulator_enable(reg_avdd_cam1);
126 }
127 mdelay(5);
128
129 if (!reg_vdd_mipi) {
130 reg_vdd_mipi = regulator_get(NULL, "vddio_mipi");
131 if (IS_ERR_OR_NULL(reg_vdd_mipi)) {
132 pr_err("whistler_ov5650_power_on: vddio_mipi failed\n");
133 reg_vdd_mipi = NULL;
134 return PTR_ERR(reg_vdd_mipi);
135 }
136 regulator_enable(reg_vdd_mipi);
137 }
138 mdelay(5);
139
140 if (!reg_vdd_af) {
141 reg_vdd_af = regulator_get(NULL, "vdd_vcore_af");
142 if (IS_ERR_OR_NULL(reg_vdd_af)) {
143 pr_err("whistler_ov5650_power_on: vdd_vcore_af failed\n");
144 reg_vdd_af = NULL;
145 return PTR_ERR(reg_vdd_af);
146 }
147 regulator_enable(reg_vdd_af);
148 }
149 mdelay(5);
150
151 gpio_set_value(CAMERA1_RESET_GPIO, 1);
152 mdelay(10);
153 gpio_set_value(CAMERA1_RESET_GPIO, 0);
154 mdelay(5);
155 gpio_set_value(CAMERA1_RESET_GPIO, 1);
156 mdelay(20);
157 gpio_set_value(CAMERA_AF_PD_GPIO, 1);
158
159 return 0;
160}
161
162static int whistler_ov5650_power_off(void)
163{
164 gpio_set_value(CAMERA_AF_PD_GPIO, 0);
165 gpio_set_value(CAMERA1_PWDN_GPIO, 1);
166 gpio_set_value(CAMERA1_RESET_GPIO, 0);
167
168 if (reg_avdd_cam1) {
169 regulator_disable(reg_avdd_cam1);
170 regulator_put(reg_avdd_cam1);
171 reg_avdd_cam1 = NULL;
172 }
173
174 if (reg_vdd_mipi) {
175 regulator_disable(reg_vdd_mipi);
176 regulator_put(reg_vdd_mipi);
177 reg_vdd_mipi = NULL;
178 }
179
180 if (reg_vdd_af) {
181 regulator_disable(reg_vdd_af);
182 regulator_put(reg_vdd_af);
183 reg_vdd_af = NULL;
184 }
185
186 return 0;
187}
188
189static int whistler_soc380_power_on(void)
190{
191 gpio_set_value(CAMERA2_PWDN_GPIO, 0);
192
193 if (!reg_vddio_vi) {
194 reg_vddio_vi = regulator_get(NULL, "vddio_vi");
195 if (IS_ERR_OR_NULL(reg_vddio_vi)) {
196 pr_err("whistler_soc380_power_on: vddio_vi failed\n");
197 reg_vddio_vi = NULL;
198 return PTR_ERR(reg_vddio_vi);
199 }
200 regulator_set_voltage(reg_vddio_vi, 1800*1000, 1800*1000);
201 mdelay(5);
202 regulator_enable(reg_vddio_vi);
203 }
204
205 if (!reg_avdd_cam1) {
206 reg_avdd_cam1 = regulator_get(NULL, "vdd_cam1");
207 if (IS_ERR_OR_NULL(reg_avdd_cam1)) {
208 pr_err("whistler_soc380_power_on: vdd_cam1 failed\n");
209 reg_avdd_cam1 = NULL;
210 return PTR_ERR(reg_avdd_cam1);
211 }
212 regulator_enable(reg_avdd_cam1);
213 }
214 mdelay(5);
215
216 gpio_set_value(CAMERA2_RESET_GPIO, 1);
217 mdelay(10);
218 gpio_set_value(CAMERA2_RESET_GPIO, 0);
219 mdelay(5);
220 gpio_set_value(CAMERA2_RESET_GPIO, 1);
221 mdelay(20);
222
223 return 0;
224
225}
226
227static int whistler_soc380_power_off(void)
228{
229 gpio_set_value(CAMERA2_PWDN_GPIO, 1);
230 gpio_set_value(CAMERA2_RESET_GPIO, 0);
231
232 if (reg_avdd_cam1) {
233 regulator_disable(reg_avdd_cam1);
234 regulator_put(reg_avdd_cam1);
235 reg_avdd_cam1 = NULL;
236 }
237 if (reg_vddio_vi) {
238 regulator_disable(reg_vddio_vi);
239 regulator_put(reg_vddio_vi);
240 reg_vddio_vi = NULL;
241 }
242
243 return 0;
244}
245
246struct ov5650_platform_data whistler_ov5650_data = {
247 .power_on = whistler_ov5650_power_on,
248 .power_off = whistler_ov5650_power_off,
249};
250
251struct soc380_platform_data whistler_soc380_data = {
252 .power_on = whistler_soc380_power_on,
253 .power_off = whistler_soc380_power_off,
254};
255
256static int whistler_fuse_power_en(int enb)
257{
258 int ret;
259
260 ret = gpio_request(FUSE_POWER_EN_GPIO, "fuse_power_en");
261 if (ret) {
262 pr_err("%s: gpio_request fail (%d)\n", __func__, ret);
263 return ret;
264 }
265
266 ret = gpio_direction_output(FUSE_POWER_EN_GPIO, enb);
267 if (ret) {
268 pr_err("%s: gpio_direction_output fail (%d)\n", __func__, ret);
269 return ret;
270 }
271
272 gpio_free(FUSE_POWER_EN_GPIO);
273 return 0;
274}
275
276static struct pca953x_platform_data whistler_tca6416_data = {
277 .gpio_base = TCA6416_GPIO_BASE,
278};
279
280static struct i2c_board_info whistler_i2c3_board_info[] = {
281 {
282 I2C_BOARD_INFO("ov5650", 0x36),
283 .platform_data = &whistler_ov5650_data,
284 },
285 {
286 I2C_BOARD_INFO("ad5820", 0x0c),
287 },
288 {
289 I2C_BOARD_INFO("soc380", 0x3C),
290 .platform_data = &whistler_soc380_data,
291 },
292};
293
294static void whistler_adxl34x_init(void)
295{
296 tegra_gpio_enable(ADXL34X_IRQ_GPIO);
297 gpio_request(ADXL34X_IRQ_GPIO, "adxl34x");
298 gpio_direction_input(ADXL34X_IRQ_GPIO);
299}
300
301static void whistler_isl29018_init(void)
302{
303 tegra_gpio_enable(ISL29018_IRQ_GPIO);
304 gpio_request(ISL29018_IRQ_GPIO, "isl29018");
305 gpio_direction_input(ISL29018_IRQ_GPIO);
306}
307
308static struct i2c_board_info whistler_i2c1_board_info[] = {
309 {
310 I2C_BOARD_INFO("adxl34x", 0x1D),
311 .irq = TEGRA_GPIO_TO_IRQ(ADXL34X_IRQ_GPIO),
312 },
313 {
314 I2C_BOARD_INFO("isl29018", 0x44),
315 .irq = TEGRA_GPIO_TO_IRQ(ISL29018_IRQ_GPIO),
316 },
317};
318
319static void whistler_adt7461_init(void)
320{
321 tegra_gpio_enable(ADT7461_IRQ_GPIO);
322}
323
324static struct adt7461_platform_data whistler_adt7461_pdata = {
325 .supported_hwrev = true,
326 .ext_range = false,
327 .therm2 = true,
328 .conv_rate = 0x05,
329 .offset = 0,
330 .hysteresis = 0,
331 .shutdown_ext_limit = 115,
332 .shutdown_local_limit = 120,
333 .throttling_ext_limit = 90,
334 .alarm_fn = tegra_throttling_enable,
335 .irq_gpio = ADT7461_IRQ_GPIO,
336};
337
338static struct i2c_board_info whistler_i2c4_board_info[] = {
339 {
340 I2C_BOARD_INFO("adt7461", 0x4C),
341 .irq = TEGRA_GPIO_TO_IRQ(ADT7461_IRQ_GPIO),
342 .platform_data = &whistler_adt7461_pdata,
343 },
344 {
345 I2C_BOARD_INFO("tca6416", 0x20),
346 .platform_data = &whistler_tca6416_data,
347 },
348};
349
350int __init whistler_sensors_init(void)
351{
352 whistler_camera_init();
353
354 whistler_adxl34x_init();
355
356 whistler_isl29018_init();
357
358 whistler_adt7461_init();
359
360 i2c_register_board_info(0, whistler_i2c1_board_info,
361 ARRAY_SIZE(whistler_i2c1_board_info));
362
363 i2c_register_board_info(4, whistler_i2c4_board_info,
364 ARRAY_SIZE(whistler_i2c4_board_info));
365
366 i2c_register_board_info(3, whistler_i2c3_board_info,
367 ARRAY_SIZE(whistler_i2c3_board_info));
368
369 tegra_fuse_regulator_en = whistler_fuse_power_en;
370
371 return 0;
372}
373
374int __init whistler_sensor_late_init(void)
375{
376 int ret;
377
378 if (!machine_is_whistler())
379 return 0;
380
381 reg_vddio_vi = regulator_get(NULL, "vddio_vi");
382 if (IS_ERR_OR_NULL(reg_vddio_vi)) {
383 pr_err("%s: Couldn't get regulator vddio_vi\n", __func__);
384 return PTR_ERR(reg_vddio_vi);
385 }
386
387 /* set vddio_vi voltage to 1.8v */
388 ret = regulator_set_voltage(reg_vddio_vi, 1800*1000, 1800*1000);
389 if (ret) {
390 pr_err("%s: Failed to set vddio_vi to 1.8v\n", __func__);
391 goto fail_put_regulator;
392 }
393
394 regulator_put(reg_vddio_vi);
395 reg_vddio_vi = NULL;
396 return 0;
397
398fail_put_regulator:
399 regulator_put(reg_vddio_vi);
400 reg_vddio_vi = NULL;
401 return ret;
402}
403
404late_initcall(whistler_sensor_late_init);
405