arm: tegra: pluto: Add ad5816 focuser 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/err.h>
20 #include <linux/i2c.h>
21 #include <linux/delay.h>
22 #include <linux/regulator/consumer.h>
23 #include <linux/gpio.h>
24 #include <linux/mpu.h>
25 #include <media/imx091.h>
26 #include <media/imx132.h>
27 #include <media/ad5816.h>
28
29 #include "gpio-names.h"
30 #include "board-pluto.h"
31
32 /* isl29029 support is provided by isl29028*/
33 static struct i2c_board_info pluto_i2c1_isl_board_info[] = {
34         {
35                 I2C_BOARD_INFO("isl29028", 0x44),
36         }
37 };
38
39 struct pluto_cam_gpio {
40         int gpio;
41         const char *label;
42         int value;
43 };
44
45 static char *pluto_cam_reg_name[] = {
46         "avdd_cam1",            /* Analog VDD 2.7V */
47         "avdd_cam2",            /* Analog VDD 2.7V */
48         "vdd_1v2_cam",          /* Digital VDD 1.2V */
49         "vdd_1v8_cam12",        /* Digital VDDIO 1.8V */
50 };
51
52 static struct regulator *pluto_cam_reg[ARRAY_SIZE(pluto_cam_reg_name)];
53
54 static int pluto_imx091_power_on(struct device *dev)
55 {
56         int i;
57
58         for (i = 0; i < ARRAY_SIZE(pluto_cam_reg_name); i++) {
59                 if (!pluto_cam_reg[i]) {
60                         pluto_cam_reg[i] = regulator_get(dev,
61                                         pluto_cam_reg_name[i]);
62                         if (WARN_ON(IS_ERR(pluto_cam_reg[i]))) {
63                                 pr_err("%s: didn't get regulator #%d: %ld\n",
64                                 __func__, i, PTR_ERR(pluto_cam_reg[i]));
65                                 goto reg_alloc_fail;
66                         }
67                 }
68                 regulator_enable(pluto_cam_reg[i]);
69         }
70
71         gpio_direction_output(CAM_RSTN, 0);
72         gpio_direction_output(CAM_GPIO1, 1);
73         gpio_direction_output(CAM_RSTN, 1);
74
75         mdelay(1);
76
77         return 0;
78
79 reg_alloc_fail:
80
81         for (i = ARRAY_SIZE(pluto_cam_reg_name) - 1; i >= 0; i--) {
82                 if (pluto_cam_reg[i]) {
83                         regulator_put(pluto_cam_reg[i]);
84                         pluto_cam_reg[i] = NULL;
85                 }
86         }
87         pr_info("%s fail\n", __func__);
88
89         return -ENODEV;
90 }
91
92 static int pluto_imx091_power_off(struct device *dev)
93 {
94         int i;
95
96         for (i = ARRAY_SIZE(pluto_cam_reg_name) - 1; i >= 0; i--) {
97                 if (pluto_cam_reg[i]) {
98                         regulator_disable(pluto_cam_reg[i]);
99                         regulator_put(pluto_cam_reg[i]);
100                         pluto_cam_reg[i] = NULL;
101                 }
102         }
103
104         return 0;
105 }
106
107 static int pluto_imx132_power_on(struct device *dev)
108 {
109         int i;
110
111         for (i = 0; i < ARRAY_SIZE(pluto_cam_reg_name); i++) {
112                 if (!pluto_cam_reg[i]) {
113                         pluto_cam_reg[i] = regulator_get(dev,
114                                         pluto_cam_reg_name[i]);
115                         if (WARN_ON(IS_ERR(pluto_cam_reg[i]))) {
116                                 pr_err("%s: didn't get regulator #%d: %ld\n",
117                                 __func__, i, PTR_ERR(pluto_cam_reg[i]));
118                                 goto reg_alloc_fail;
119                         }
120                 }
121                 regulator_enable(pluto_cam_reg[i]);
122         }
123
124         gpio_direction_output(CAM_RSTN, 0);
125         gpio_direction_output(CAM_GPIO2, 1);
126         gpio_direction_output(CAM_RSTN, 1);
127
128         mdelay(1);
129
130         return 0;
131
132 reg_alloc_fail:
133         for (i = ARRAY_SIZE(pluto_cam_reg_name) - 1; i >= 0; i--) {
134                 if (pluto_cam_reg[i]) {
135                         regulator_put(pluto_cam_reg[i]);
136                         pluto_cam_reg[i] = NULL;
137                 }
138         }
139
140         return -ENODEV;
141 }
142
143
144 static int pluto_imx132_power_off(struct device *dev)
145 {
146         int i;
147
148         for (i = ARRAY_SIZE(pluto_cam_reg_name) - 1; i >= 0; i--) {
149                 if (pluto_cam_reg[i]) {
150                         regulator_disable(pluto_cam_reg[i]);
151                         regulator_put(pluto_cam_reg[i]);
152                         pluto_cam_reg[i] = NULL;
153                 }
154         }
155
156         return 0;
157 }
158
159 struct imx091_platform_data pluto_imx091_data = {
160         .power_on = pluto_imx091_power_on,
161         .power_off = pluto_imx091_power_off,
162 };
163
164 struct imx132_platform_data pluto_imx132_data = {
165         .power_on = pluto_imx132_power_on,
166         .power_off = pluto_imx132_power_off,
167 };
168
169 static struct ad5816_platform_data pluto_ad5816_pdata = {
170         .cfg            = 0,
171         .num            = 0,
172         .sync           = 0,
173         .dev_name       = "focuser",
174 };
175
176 static struct i2c_board_info pluto_i2c_board_info_e1625[] = {
177         {
178                 I2C_BOARD_INFO("imx091", 0x10),
179                 .platform_data = &pluto_imx091_data,
180         },
181         {
182                 I2C_BOARD_INFO("imx132", 0x36),
183                 .platform_data = &pluto_imx132_data,
184         },
185         {
186                 I2C_BOARD_INFO("ad5816", 0x0E),
187                 .platform_data = &pluto_ad5816_pdata,
188         },
189 };
190
191 #define TEGRA_CAMERA_GPIO(_gpio, _label, _value)                \
192         {                                                       \
193                 .gpio = _gpio,                                  \
194                 .label = _label,                                \
195                 .value = _value,                                \
196         }
197 static struct pluto_cam_gpio pluto_cam_gpio_data[] = {
198         [0] = TEGRA_CAMERA_GPIO(CAM1_POWER_DWN_GPIO, "camera_power_en", 1),
199         [1] = TEGRA_CAMERA_GPIO(CAM2_POWER_DWN_GPIO, "camera2_power_en", 1),
200         [2] = TEGRA_CAMERA_GPIO(CAM_GPIO1, "camera_gpio1", 0),
201         [3] = TEGRA_CAMERA_GPIO(CAM_GPIO2, "camera_gpio2", 0),
202         [4] = TEGRA_CAMERA_GPIO(CAM_RSTN, "camera_rstn", 1),
203         [5] = TEGRA_CAMERA_GPIO(CAM_AF_PWDN, "camera_af_pwdn", 1),
204 };
205
206 static int pluto_camera_init(void)
207 {
208         int ret;
209         int i;
210
211         pr_debug("%s: ++\n", __func__);
212
213         for (i = 0; i < ARRAY_SIZE(pluto_cam_gpio_data); i++) {
214                 ret = gpio_request(pluto_cam_gpio_data[i].gpio,
215                                 pluto_cam_gpio_data[i].label);
216                 if (ret < 0) {
217                         pr_err("%s: gpio_request failed for gpio #%d\n",
218                                 __func__, i);
219                         goto fail_free_gpio;
220                 }
221                 gpio_direction_output(pluto_cam_gpio_data[i].gpio,
222                                         pluto_cam_gpio_data[i].value);
223                 gpio_export(pluto_cam_gpio_data[i].gpio, false);
224         }
225
226         i2c_register_board_info(2, pluto_i2c_board_info_e1625,
227                 ARRAY_SIZE(pluto_i2c_board_info_e1625));
228
229         return 0;
230
231 fail_free_gpio:
232         while (i--)
233                 gpio_free(pluto_cam_gpio_data[i].gpio);
234         return ret;
235 }
236
237 int __init pluto_sensors_init(void)
238 {
239         pr_debug("%s: ++\n", __func__);
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 }