arm: tegra: pluto: add camera sensor support
[linux-3.10.git] / arch / arm / mach-tegra / board-pluto-sensors.c
1 /*
2  * arch/arm/mach-tegra/board-pluto-sensors.c
3  *
4  * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19 #include <linux/i2c.h>
20 #include <linux/delay.h>
21 #include <mach/gpio.h>
22 #include "gpio-names.h"
23 #include "board.h"
24 #include <mach/gpio.h>
25 #include <media/imx091.h>
26 #include "board-pluto.h"
27 #include "cpu-tegra.h"
28 #include <linux/i2c.h>
29 #include <linux/delay.h>
30 #include <linux/regulator/consumer.h>
31 #include <linux/gpio.h>
32 #include <mach/gpio-tegra.h>
33 #include <mach/fb.h>
34 #include <media/imx091.h>
35 #include <media/imx132.h>
36 #include <generated/mach-types.h>
37 #include <linux/mpu.h>
38
39 static struct board_info board_info;
40
41 /* isl29029 support is provided by isl29028*/
42 static struct i2c_board_info pluto_i2c1_isl_board_info[] = {
43         {
44                 I2C_BOARD_INFO("isl29028", 0x44),
45         }
46 };
47
48 struct pluto_cam_gpio {
49         int gpio;
50         const char *label;
51         int value;
52 };
53
54 static char *pluto_cam_reg_name[] = {
55         "avdd_cam1",            /* Analog VDD 2.7V */
56         "avdd_cam2",            /* Analog VDD 2.7V */
57         "vdd_1v2_cam",          /* Digital VDD 1.2V */
58         "vdd_1v8_cam12",        /* Digital VDDIO 1.8V */
59         "vddio_cam",            /* Tegra CAM_I2C, CAM_MCLK, VDD 1.8V */
60         "vddio_cam_mb",         /* CAM_I2C PULL-UP VDD 1.8V */
61         "vdd_af_cam1",          /* AF VDD */
62 };
63
64 static struct regulator *pluto_cam_reg[ARRAY_SIZE(pluto_cam_reg_name)];
65
66 static int pluto_imx091_power_on(void)
67 {
68         int i;
69
70         for (i = 0; i < ARRAY_SIZE(pluto_cam_reg_name); i++) {
71                 if (!pluto_cam_reg[i]) {
72                         pluto_cam_reg[i] = regulator_get(NULL,
73                                         pluto_cam_reg_name[i]);
74                         if (WARN_ON(IS_ERR(pluto_cam_reg[i]))) {
75                                 pr_err("%s: didn't get regulator #%d: %ld\n",
76                                 __func__, i, PTR_ERR(pluto_cam_reg[i]));
77                                 goto reg_alloc_fail;
78                         }
79                 }
80                 regulator_enable(pluto_cam_reg[i]);
81         }
82
83         gpio_direction_output(CAM_RSTN, 0);
84         gpio_direction_output(CAM_GPIO1, 1);
85         gpio_direction_output(CAM_RSTN, 1);
86
87         mdelay(1);
88
89         return 0;
90
91 reg_alloc_fail:
92
93         for (i = 0; i < ARRAY_SIZE(pluto_cam_reg_name); i++) {
94                 if (pluto_cam_reg[i]) {
95                         regulator_put(pluto_cam_reg[i]);
96                         pluto_cam_reg[i] = NULL;
97                 }
98         }
99
100         return -ENODEV;
101 }
102
103 static int pluto_imx091_power_off(void)
104 {
105         int i;
106
107         for (i = 0; i < ARRAY_SIZE(pluto_cam_reg_name); i++) {
108                 if (pluto_cam_reg[i]) {
109                         regulator_disable(pluto_cam_reg[i]);
110                         regulator_put(pluto_cam_reg[i]);
111                 }
112         }
113
114         return 0;
115 }
116
117 static int pluto_imx132_power_on(void)
118 {
119         int i;
120
121         for (i = 0; i < ARRAY_SIZE(pluto_cam_reg_name); i++) {
122                 if (!pluto_cam_reg[i]) {
123                         pluto_cam_reg[i] = regulator_get(NULL,
124                                         pluto_cam_reg_name[i]);
125                         if (WARN_ON(IS_ERR(pluto_cam_reg[i]))) {
126                                 pr_err("%s: didn't get regulator #%d: %ld\n",
127                                 __func__, i, PTR_ERR(pluto_cam_reg[i]));
128                                 goto reg_alloc_fail;
129                         }
130                 }
131                 regulator_enable(pluto_cam_reg[i]);
132         }
133
134         gpio_direction_output(CAM_RSTN, 0);
135         gpio_direction_output(CAM_GPIO2, 1);
136         gpio_direction_output(CAM_RSTN, 1);
137
138         mdelay(1);
139
140         return 0;
141
142 reg_alloc_fail:
143
144         for (i = 0; i < ARRAY_SIZE(pluto_cam_reg_name); i++) {
145                 if (pluto_cam_reg[i]) {
146                         regulator_put(pluto_cam_reg[i]);
147                         pluto_cam_reg[i] = NULL;
148                 }
149         }
150
151         return -ENODEV;
152 }
153
154
155 static int pluto_imx132_power_off(void)
156 {
157         int i;
158
159         for (i = 0; i < ARRAY_SIZE(pluto_cam_reg_name); i++) {
160                 if (pluto_cam_reg[i]) {
161                         regulator_disable(pluto_cam_reg[i]);
162                         regulator_put(pluto_cam_reg[i]);
163                 }
164         }
165
166         return 0;
167 }
168
169 struct imx091_platform_data pluto_imx091_data = {
170         .power_on = pluto_imx091_power_on,
171         .power_off = pluto_imx091_power_off,
172 };
173
174 struct imx132_platform_data pluto_imx132_data = {
175         .power_on = pluto_imx132_power_on,
176         .power_off = pluto_imx132_power_off,
177 };
178
179 static struct i2c_board_info pluto_i2c_board_info_e1625[] = {
180         {
181                 I2C_BOARD_INFO("imx091", 0x36),
182                 .platform_data = &pluto_imx091_data,
183         },
184         {
185                 I2C_BOARD_INFO("imx132", 0x36),
186                 .platform_data = &pluto_imx132_data,
187         },
188 };
189
190 #define TEGRA_CAMERA_GPIO(_gpio, _label, _value)                \
191         {                                                       \
192                 .gpio = _gpio,                                  \
193                 .label = _label,                                \
194                 .value = _value,                                \
195         }
196 static struct pluto_cam_gpio pluto_cam_gpio_data[] = {
197         [0] = TEGRA_CAMERA_GPIO(CAM1_POWER_DWN_GPIO, "camera_power_en", 1),
198         [1] = TEGRA_CAMERA_GPIO(CAM2_POWER_DWN_GPIO, "camera2_power_en", 1),
199         [2] = TEGRA_CAMERA_GPIO(CAM_GPIO1, "camera_gpio1", 0),
200         [3] = TEGRA_CAMERA_GPIO(CAM_GPIO2, "camera_gpio2", 0),
201         [4] = TEGRA_CAMERA_GPIO(CAM_RSTN, "camera_rstn", 1),
202         [5] = TEGRA_CAMERA_GPIO(CAM_AF_PWDN, "camera_af_pwdn", 1),
203 };
204
205 static int pluto_camera_init(void)
206 {
207         int ret;
208         int i;
209
210         pr_debug("%s: ++\n", __func__);
211
212         for (i = 0; i < ARRAY_SIZE(pluto_cam_gpio_data); i++) {
213                 ret = gpio_request(pluto_cam_gpio_data[i].gpio,
214                                 pluto_cam_gpio_data[i].label);
215                 if (ret < 0) {
216                         pr_err("%s: gpio_request failed for gpio #%d\n",
217                                 __func__, i);
218                         goto fail_free_gpio;
219                 }
220                 gpio_direction_output(pluto_cam_gpio_data[i].gpio,
221                                         pluto_cam_gpio_data[i].value);
222                 gpio_export(pluto_cam_gpio_data[i].gpio, false);
223         }
224
225         i2c_register_board_info(2, pluto_i2c_board_info_e1625,
226                 ARRAY_SIZE(pluto_i2c_board_info_e1625));
227
228         return 0;
229
230 fail_free_gpio:
231         while (i--)
232                 gpio_free(pluto_cam_gpio_data[i].gpio);
233         return ret;
234 }
235
236 int __init pluto_sensors_init(void)
237 {
238         pr_debug("%s: ++\n", __func__);
239         tegra_get_board_info(&board_info);
240         pluto_camera_init();
241
242         i2c_register_board_info(0, pluto_i2c1_isl_board_info,
243                                 ARRAY_SIZE(pluto_i2c1_isl_board_info));
244
245         return 0;
246 }