ARM: tegra: dalmore: Add sensor board support
[linux-3.10.git] / arch / arm / mach-tegra / board-dalmore-sensors.c
1 /*
2  * arch/arm/mach-tegra/board-dalmore-sensors.c
3  *
4  * Copyright (c) 2012 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 licensed under the terms of the GNU General Public
22  * License version 2, as published by the Free Software Foundation, and
23  * may be copied, distributed, and modified under those terms.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28  * GNU General Public License for more details.
29  */
30
31 #include <linux/i2c.h>
32 #include <linux/delay.h>
33 #include <mach/gpio.h>
34 #include "gpio-names.h"
35 #include "board.h"
36 #include <mach/gpio.h>
37 #include <media/imx091.h>
38 #include <media/ov9772.h>
39 #include "board-dalmore.h"
40 #include "cpu-tegra.h"
41
42 #include <linux/i2c.h>
43 #include <linux/delay.h>
44 #include <linux/regulator/consumer.h>
45 #include <linux/i2c/pca954x.h>
46 #include <linux/i2c/pca953x.h>
47 #include <linux/nct1008.h>
48 #include <linux/gpio.h>
49
50 #include <mach/gpio-tegra.h>
51 #include <mach/fb.h>
52
53 #include <media/imx091.h>
54 #include <generated/mach-types.h>
55
56 #include <linux/mpu.h>
57 #include "board-dalmore.h"
58
59 static struct board_info board_info;
60
61 static char *dalmore_cam_reg_name[] = {
62         "vdd_sensor_2v85",      /* 2.85V */
63         "avddio_usb",           /* VDDIO USB CAM */
64         "dvdd_cam",             /* DVDD CAM */
65         "vddio_cam",            /* Tegra CAM_I2C, CAM_MCLK, VDD 1.8V */
66         "avdd_cam1",            /* Analog VDD 2.7V */
67         "avdd_cam2",            /* Analog VDD 2.7V */
68 };
69
70 static struct regulator *dalmore_cam_reg[ARRAY_SIZE(dalmore_cam_reg_name)];
71
72 static int dalmore_imx091_power_on(void)
73 {
74
75         int i;
76
77         for (i = 0; i < ARRAY_SIZE(dalmore_cam_reg_name); i++) {
78                 if (!dalmore_cam_reg[i]) {
79                         dalmore_cam_reg[i] = regulator_get(NULL,
80                                         dalmore_cam_reg_name[i]);
81                         if (WARN_ON(IS_ERR(dalmore_cam_reg[i]))) {
82                                 pr_err("%s: didn't get regulator #%d: %ld\n",
83                                 __func__, i, PTR_ERR(dalmore_cam_reg[i]));
84                                 goto reg_alloc_fail;
85                         }
86                 }
87                 regulator_enable(dalmore_cam_reg[i]);
88         }
89
90         gpio_direction_output(CAM_RSTN, 0);
91         mdelay(10);
92         gpio_direction_output(CAM_AF_PWDN, 1);
93         gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
94         gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
95         gpio_direction_output(CAM_RSTN, 1);
96
97         return 0;
98
99 reg_alloc_fail:
100
101         for (i = 0; i < ARRAY_SIZE(dalmore_cam_reg_name); i++) {
102                 if (dalmore_cam_reg[i]) {
103                         regulator_put(dalmore_cam_reg[i]);
104                         dalmore_cam_reg[i] = NULL;
105                 }
106         }
107
108         return -ENODEV;
109 }
110
111 static int dalmore_imx091_power_off(void)
112 {
113         int i;
114         gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
115
116         for (i = 0; i < ARRAY_SIZE(dalmore_cam_reg_name); i++) {
117                 if (dalmore_cam_reg[i]) {
118                         regulator_disable(dalmore_cam_reg[i]);
119                         regulator_put(dalmore_cam_reg[i]);
120                 }
121         }
122
123         return 0;
124 }
125
126 static int dalmore_ov9772_power_on(void)
127 {
128
129         int i;
130
131         for (i = 0; i < ARRAY_SIZE(dalmore_cam_reg_name); i++) {
132                 if (!dalmore_cam_reg[i]) {
133                         dalmore_cam_reg[i] = regulator_get(NULL,
134                                         dalmore_cam_reg_name[i]);
135                         if (WARN_ON(IS_ERR(dalmore_cam_reg[i]))) {
136                                 pr_err("%s: didn't get regulator #%d: %ld\n",
137                                 __func__, i, PTR_ERR(dalmore_cam_reg[i]));
138                                 goto reg_alloc_fail;
139                         }
140                 }
141                 regulator_enable(dalmore_cam_reg[i]);
142         }
143
144         gpio_direction_output(CAM_RSTN, 0);
145         mdelay(10);
146         gpio_direction_output(CAM_AF_PWDN, 1);
147         gpio_direction_output(CAM2_POWER_DWN_GPIO, 1);
148         gpio_direction_output(CAM1_POWER_DWN_GPIO, 1);
149         gpio_direction_output(CAM_RSTN, 1);
150
151         return 0;
152
153 reg_alloc_fail:
154
155         for (i = 0; i < ARRAY_SIZE(dalmore_cam_reg_name); i++) {
156                 if (dalmore_cam_reg[i]) {
157                         regulator_put(dalmore_cam_reg[i]);
158                         dalmore_cam_reg[i] = NULL;
159                 }
160         }
161
162         return -ENODEV;
163 }
164
165 static int dalmore_ov9772_power_off(void)
166 {
167         int i;
168         gpio_direction_output(CAM1_POWER_DWN_GPIO, 0);
169
170         for (i = 0; i < ARRAY_SIZE(dalmore_cam_reg_name); i++) {
171                 if (dalmore_cam_reg[i]) {
172                         regulator_disable(dalmore_cam_reg[i]);
173                         regulator_put(dalmore_cam_reg[i]);
174                 }
175         }
176
177         return 0;
178 }
179
180 struct imx091_platform_data dalmore_imx091_data = {
181         .power_on = dalmore_imx091_power_on,
182         .power_off = dalmore_imx091_power_off,
183 };
184
185 struct ov9772_platform_data dalmore_ov9772_data = {
186         .power_on = dalmore_ov9772_power_on,
187         .power_off = dalmore_ov9772_power_off,
188 };
189
190 static struct i2c_board_info dalmore_i2c_board_info_e1625[] = {
191         {
192                 I2C_BOARD_INFO("imx091", 0x36),
193                 .platform_data = &dalmore_imx091_data,
194         },
195         {
196                 I2C_BOARD_INFO("ov9772", 0x10),
197                 .platform_data = &dalmore_ov9772_data,
198         },
199 };
200
201 struct dalmore_cam_gpio {
202         int gpio;
203         const char *label;
204         int value;
205 };
206
207 #define TEGRA_CAMERA_GPIO(_gpio, _label, _value)                \
208         {                                                       \
209                 .gpio = _gpio,                                  \
210                 .label = _label,                                \
211                 .value = _value,                                \
212         }
213
214 static struct dalmore_cam_gpio dalmore_cam_gpio_data[] = {
215         [0] = TEGRA_CAMERA_GPIO(CAM1_POWER_DWN_GPIO, "camera_power_en", 0),
216         [1] = TEGRA_CAMERA_GPIO(CAM2_POWER_DWN_GPIO, "camera2_power_en", 0),
217         [2] = TEGRA_CAMERA_GPIO(CAM_GPIO1, "camera_gpio1", 0),
218         [3] = TEGRA_CAMERA_GPIO(CAM_GPIO2, "camera_gpio2", 0),
219         [4] = TEGRA_CAMERA_GPIO(CAM_RSTN, "camera_rstn", 1),
220         [5] = TEGRA_CAMERA_GPIO(CAM_AF_PWDN, "camera_af_pwdn", 1),
221 };
222
223 static int dalmore_camera_init(void)
224 {
225
226         int ret;
227         int i;
228
229         pr_debug("%s: ++\n", __func__);
230
231         for (i = 0; i < ARRAY_SIZE(dalmore_cam_gpio_data); i++) {
232                 ret = gpio_request(dalmore_cam_gpio_data[i].gpio,
233                                 dalmore_cam_gpio_data[i].label);
234                 if (ret < 0) {
235                         pr_err("%s: gpio_request failed for gpio #%d\n",
236                                 __func__, i);
237                         goto fail_free_gpio;
238                 }
239                 gpio_direction_output(dalmore_cam_gpio_data[i].gpio,
240                                         dalmore_cam_gpio_data[i].value);
241                 gpio_export(dalmore_cam_gpio_data[i].gpio, false);
242         }
243
244         i2c_register_board_info(2, dalmore_i2c_board_info_e1625,
245                 ARRAY_SIZE(dalmore_i2c_board_info_e1625));
246
247 fail_free_gpio:
248
249         while (i--)
250                 gpio_free(dalmore_cam_gpio_data[i].gpio);
251         return ret;
252
253 }
254
255
256 int __init dalmore_sensors_init(void)
257 {
258         tegra_get_board_info(&board_info);
259
260         dalmore_camera_init();
261
262         return 0;
263 }