Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(113)

Side by Side Diff: arch/arm/mach-tegra/board-seaboard-sensors.c

Issue 6627032: CHROMIUM: Board file changes for Tegra camera (Closed)
Patch Set: Make sensor stub functions static inline. Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « arch/arm/mach-tegra/board-seaboard.c ('k') | arch/arm/mach-tegra/devices.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2011 NVIDIA Corporation.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 */
14
15 #include <linux/delay.h>
16 #include <linux/i2c.h>
17 #include <linux/clk.h>
18 #include <linux/regulator/consumer.h>
19 #include <linux/platform_device.h>
20 #include <linux/dma-mapping.h>
21
22 #include <media/soc_camera.h>
23 #include <media/tegra_v4l2_camera.h>
24
25 #include <mach/gpio.h>
26 #include <mach/iomap.h>
27 #include <mach/nvhost.h>
28
29 #include "gpio-names.h"
30 #include "devices.h"
31
32 /* I2C adapter ID for the camera board. */
33 #define TEGRA_CAMERA_I2C_ADAPTER_ID 3
34
35 /* I2C addresses. */
36 #define TEGRA_CAMERA_I2C_ADDR_PORT_EXPANDER 0x20
37 #define TEGRA_CAMERA_I2C_ADDR_PORT_SWITCH 0x70
38
39 /* GPIOs relevant to camera module. */
40 #define TEGRA_CAMERA_GPIO_CAM_PWR_EN TEGRA_GPIO_PV4
41 #define TEGRA_CAMERA_GPIO_VI_GP3 TEGRA_GPIO_PBB4
42 #define TEGRA_CAMERA_GPIO_PMU (TEGRA_NR_GPIOS + 1)
43
44 /* Port expander registers. */
45 #define TCA6416_REG_INP 0x00
46 #define TCA6416_REG_OUTP 0x02
47 #define TCA6416_REG_PINV 0x04
48 #define TCA6416_REG_CNF 0x06
49
50 /* Port expander ports. */
51 #define TCA6416_PORT_CAM1_PWDN (1 << 0)
52 #define TCA6416_PORT_CAM1_RST (1 << 1)
53 #define TCA6416_PORT_TP_CAM1_AF_PWDN (1 << 2)
54 #define TCA6416_PORT_CAM1_LDO_SHDN (1 << 3)
55 #define TCA6416_PORT_CAM2_PWDN (1 << 4)
56 #define TCA6416_PORT_CAM2_RST (1 << 5)
57 #define TCA6416_PORT_TP_CAM2_AF_PWDN (1 << 6)
58 #define TCA6416_PORT_CAM2_LDO_SHDN (1 << 7)
59 #define TCA6416_PORT_CAM3_PWDN (1 << 8)
60 #define TCA6416_PORT_CAM3_RST (1 << 9)
61 #define TCA6416_PORT_TP_CAM3_AF_PWDN (1 << 10)
62 #define TCA6416_PORT_CAM3_LDO_SHDN (1 << 11)
63 #define TCA6416_PORT_CAM_LED1 (1 << 12)
64 #define TCA6416_PORT_CAM_LED2 (1 << 13)
65 #define TCA6416_PORT_GPIO_PI6 (1 << 14)
66 #define TCA6416_PORT_CAM_I2C_MUX_RST (1 << 15)
67
68 static struct regulator *regulator;
69 static struct i2c_client *port_expander;
70 static struct i2c_client *port_switch;
71 static struct clk *clk_vi;
72 static struct clk *clk_vi_sensor;
73 static struct clk *clk_csi;
74 static struct clk *clk_isp;
75 static struct clk *clk_csus;
76
77 static void tegra_camera_dump_port_expander_regs(struct nvhost_device *ndev)
78 {
79 #ifdef DEBUG
80 u16 val;
81
82 dev_info(&ndev->dev, "Port expander regs:\n");
83 val = i2c_smbus_read_word_data(port_expander, TCA6416_REG_INP);
84 dev_info(&ndev->dev, "INP = 0x%04x\n", val);
85 val = i2c_smbus_read_word_data(port_expander, TCA6416_REG_OUTP);
86 dev_info(&ndev->dev, "OUTP = 0x%04x\n", val);
87 val = i2c_smbus_read_word_data(port_expander, TCA6416_REG_PINV);
88 dev_info(&ndev->dev, "PINV = 0x%04x\n", val);
89 val = i2c_smbus_read_word_data(port_expander, TCA6416_REG_CNF);
90 dev_info(&ndev->dev, "CNF = 0x%04x\n", val);
91 #endif
92 }
93
94 static void tegra_camera_dump_port_switch_regs(struct nvhost_device *ndev)
95 {
96 #ifdef DEBUG
97 u8 val;
98
99 val = i2c_smbus_read_byte(port_switch);
100 dev_info(&ndev->dev, "I2C switch reg = 0x%02x\n", val);
101 #endif
102 }
103
104 static int tegra_camera_enable(struct nvhost_device *ndev)
105 {
106 struct i2c_adapter *adapter;
107 struct i2c_board_info port_expander_info = {
108 I2C_BOARD_INFO("tca6416",
109 TEGRA_CAMERA_I2C_ADDR_PORT_EXPANDER) };
110 struct i2c_board_info port_switch_info = {
111 I2C_BOARD_INFO("pca9546",
112 TEGRA_CAMERA_I2C_ADDR_PORT_SWITCH) };
113 int err;
114 u16 val;
115 u8 val2;
116
117 /* Turn on relevant clocks. */
118 clk_enable(clk_vi);
119 clk_enable(clk_vi_sensor);
120 clk_enable(clk_csi);
121 clk_enable(clk_isp);
122 clk_enable(clk_csus);
123
124 /* Turn on power to the camera board. */
125 regulator = regulator_get(&ndev->dev, "vddio_vi");
126 if (IS_ERR(regulator)) {
127 dev_info(&ndev->dev, "regulator_get() returned error %ld\n",
128 PTR_ERR(regulator));
129 err = PTR_ERR(regulator);
130 goto exit;
131 }
132
133 err = regulator_enable(regulator);
134 if (err != 0)
135 goto exit_regulator_put;
136
137 /* Get the I2C adapter and clients for the stuff on the camera board. */
138 adapter = i2c_get_adapter(TEGRA_CAMERA_I2C_ADAPTER_ID);
139 if (!adapter) {
140 err = -EINVAL;
141 goto exit_regulator_disable;
142 }
143
144 port_expander = i2c_new_device(adapter, &port_expander_info);
145 if (!port_expander) {
146 err = -EINVAL;
147 goto exit_adapter_put;
148 }
149
150 port_switch = i2c_new_device(adapter, &port_switch_info);
151 if (!port_switch) {
152 err = -EINVAL;
153 goto exit_port_expander_unregister;
154 }
155
156 /* Set up GPIOs. */
157 err = gpio_request(TEGRA_CAMERA_GPIO_CAM_PWR_EN, "cam_pwr_en");
158 if (err != 0)
159 goto exit_port_switch_unregister;
160 gpio_direction_output(TEGRA_CAMERA_GPIO_CAM_PWR_EN, 1);
161
162 err = gpio_request(TEGRA_CAMERA_GPIO_VI_GP3, "vi_gp3");
163 if (err != 0)
164 goto exit_gpio_free_cam_pwr_en;
165 gpio_direction_output(TEGRA_CAMERA_GPIO_VI_GP3, 1);
166
167 err = gpio_request(TEGRA_CAMERA_GPIO_PMU, "tegra_camera");
168 if (err != 0)
169 goto exit_gpio_free_vi_gp3;
170 gpio_direction_output(TEGRA_CAMERA_GPIO_PMU, 1);
171
172 /* All port pins on the port expander are inputs by default.
173 * Set all to output.
174 */
175 i2c_smbus_write_word_data(port_expander, TCA6416_REG_CNF, 0x0000);
176
177 /* Take port switch out of reset and turn on camera 3. */
178 val = TCA6416_PORT_CAM3_RST |
179 TCA6416_PORT_TP_CAM3_AF_PWDN |
180 TCA6416_PORT_CAM3_LDO_SHDN |
181 TCA6416_PORT_CAM_I2C_MUX_RST |
182 TCA6416_PORT_CAM_LED1;
183 i2c_smbus_write_word_data(port_expander, TCA6416_REG_OUTP, val);
184
185 tegra_camera_dump_port_expander_regs(ndev);
186
187 /* Twiddle port switch to select our camera. */
188 val2 = i2c_smbus_read_byte(port_switch);
189 val2 |= (1 << 2); /* Enable port 2 (out of 0..3). */
190 i2c_smbus_write_byte(port_switch, val2);
191
192 tegra_camera_dump_port_switch_regs(ndev);
193
194 /* Give the sensor time to come out of reset. The OV9740 needs
195 * 8192 clock cycles (from vi_sensor clock) before the first I2C
196 * transaction.
197 */
198 udelay(1000);
199
200 return 0;
201
202 exit_gpio_free_vi_gp3:
203 gpio_free(TEGRA_CAMERA_GPIO_VI_GP3);
204 exit_gpio_free_cam_pwr_en:
205 gpio_free(TEGRA_CAMERA_GPIO_CAM_PWR_EN);
206 exit_port_switch_unregister:
207 i2c_unregister_device(port_switch);
208 exit_port_expander_unregister:
209 i2c_unregister_device(port_expander);
210 exit_adapter_put:
211 i2c_put_adapter(adapter);
212 exit_regulator_disable:
213 regulator_disable(regulator);
214 exit_regulator_put:
215 regulator_put(regulator);
216 exit:
217 return err;
218 }
219
220 static void tegra_camera_disable(struct nvhost_device *ndev)
221 {
222 struct i2c_adapter *adapter;
223
224 gpio_free(TEGRA_CAMERA_GPIO_PMU);
225 gpio_free(TEGRA_CAMERA_GPIO_VI_GP3);
226 gpio_free(TEGRA_CAMERA_GPIO_CAM_PWR_EN);
227
228 adapter = i2c_get_adapter(TEGRA_CAMERA_I2C_ADAPTER_ID);
229 BUG_ON(!adapter);
230 i2c_unregister_device(port_switch);
231 i2c_unregister_device(port_expander);
232 i2c_put_adapter(adapter);
233
234 BUG_ON(!regulator);
235 regulator_disable(regulator);
236 regulator_put(regulator);
237 regulator = NULL;
238
239 /* Turn off relevant clocks. */
240 clk_disable(clk_vi);
241 clk_disable(clk_vi_sensor);
242 clk_disable(clk_csi);
243 clk_disable(clk_isp);
244 clk_disable(clk_csus);
245 }
246
247 static struct i2c_board_info seaboard_i2c_bus3_sensor_info = {
248 I2C_BOARD_INFO("ov9740", 0x10),
249 };
250
251 static struct soc_camera_link ov9740_iclink = {
252 .bus_id = 0,
253 .i2c_adapter_id = TEGRA_CAMERA_I2C_ADAPTER_ID,
254 .board_info = &seaboard_i2c_bus3_sensor_info,
255 .module_name = "ov9740",
256 };
257
258 static struct platform_device soc_camera = {
259 .name = "soc-camera-pdrv",
260 .id = 0,
261 .dev = {
262 .platform_data = &ov9740_iclink,
263 },
264 };
265
266 static struct tegra_camera_platform_data tegra_camera_platform_data = {
267 .enable_camera = tegra_camera_enable,
268 .disable_camera = tegra_camera_disable,
269 .flip_v = 1,
270 .flip_h = 0,
271 };
272
273 int __init seaboard_sensors_init(void)
274 {
275 tegra_camera_device.dev.platform_data = &tegra_camera_platform_data;
276
277 tegra_gpio_enable(TEGRA_CAMERA_GPIO_CAM_PWR_EN);
278 tegra_gpio_enable(TEGRA_CAMERA_GPIO_VI_GP3);
279
280 clk_vi = clk_get_sys("tegra_camera", "vi");
281 if (!clk_vi)
282 pr_warn("Failed to get vi clock\n");
283
284 clk_vi_sensor = clk_get_sys("tegra_camera", "vi_sensor");
285 if (!clk_vi_sensor)
286 pr_warn("Failed to get vi_sensor clock\n");
287
288 clk_csi = clk_get_sys("tegra_camera", "csi");
289 if (!clk_csi)
290 pr_warn("Failed to get csi clock\n");
291
292 clk_isp = clk_get_sys("tegra_camera", "isp");
293 if (!clk_isp)
294 pr_warn("Failed to get isp clock\n");
295
296 clk_csus = clk_get_sys("tegra_camera", "csus");
297 if (!clk_csus)
298 pr_warn("Failed to get csus clock\n");
299
300 nvhost_device_register(&tegra_camera_device);
301
302 platform_device_register(&soc_camera);
303
304 return 0;
305 }
306
OLDNEW
« no previous file with comments | « arch/arm/mach-tegra/board-seaboard.c ('k') | arch/arm/mach-tegra/devices.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698