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

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

Issue 6627032: CHROMIUM: Board file changes for Tegra camera (Closed)
Patch Set: Work in progress on aebl sensor. Fixed C99 comments, and file comment headers. 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
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 #ifdef DEBUG
78 static void tegra_camera_dump_port_expander_regs(struct nvhost_device *ndev)
79 {
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 }
92
93 static void tegra_camera_dump_port_switch_regs(struct nvhost_device *ndev)
94 {
95 u8 val;
96
97 val = i2c_smbus_read_byte(port_switch);
98 dev_info(&ndev->dev, "I2C switch reg = 0x%02x\n", val);
99 }
100 #endif
Olof Johansson 2011/03/28 22:41:44 If you provide empty stubs of these functions (or
101
102 static int tegra_camera_enable(struct nvhost_device *ndev)
103 {
104 struct i2c_adapter *adapter;
105 struct i2c_board_info port_expander_info = {
106 I2C_BOARD_INFO("tca6416",
107 TEGRA_CAMERA_I2C_ADDR_PORT_EXPANDER) };
108 struct i2c_board_info port_switch_info = {
109 I2C_BOARD_INFO("pca9546",
110 TEGRA_CAMERA_I2C_ADDR_PORT_SWITCH) };
111 int err;
112 u16 val;
113 u8 val2;
114
115 /* Turn on relevant clocks. */
116 clk_enable(clk_vi);
117 clk_enable(clk_vi_sensor);
118 clk_enable(clk_csi);
119 clk_enable(clk_isp);
120 clk_enable(clk_csus);
121
122 /* Turn on power to the camera board. */
123 regulator = regulator_get(&ndev->dev, "vddio_vi");
124 if (IS_ERR(regulator)) {
125 dev_info(&ndev->dev, "regulator_get() returned error %ld\n",
126 PTR_ERR(regulator));
127 err = PTR_ERR(regulator);
128 goto exit;
129 }
130
131 err = regulator_enable(regulator);
132 if (err != 0)
133 goto exit_regulator_put;
134
135 /* Get the I2C adapter and clients for the stuff on the camera board. */
136 adapter = i2c_get_adapter(TEGRA_CAMERA_I2C_ADAPTER_ID);
137 if (!adapter) {
138 err = -EINVAL;
139 goto exit_regulator_disable;
140 }
141
142 port_expander = i2c_new_device(adapter, &port_expander_info);
143 if (!port_expander) {
144 err = -EINVAL;
145 goto exit_adapter_put;
146 }
147
148 port_switch = i2c_new_device(adapter, &port_switch_info);
149 if (!port_switch) {
150 err = -EINVAL;
151 goto exit_port_expander_unregister;
152 }
153
154 /* Set up GPIOs. */
155 err = gpio_request(TEGRA_CAMERA_GPIO_CAM_PWR_EN, "cam_pwr_en");
156 if (err != 0)
157 goto exit_port_switch_unregister;
158 gpio_direction_output(TEGRA_CAMERA_GPIO_CAM_PWR_EN, 1);
159
160 err = gpio_request(TEGRA_CAMERA_GPIO_VI_GP3, "vi_gp3");
161 if (err != 0)
162 goto exit_gpio_free_cam_pwr_en;
163 gpio_direction_output(TEGRA_CAMERA_GPIO_VI_GP3, 1);
164
165 err = gpio_request(TEGRA_CAMERA_GPIO_PMU, "tegra_camera");
166 if (err != 0)
167 goto exit_gpio_free_vi_gp3;
168 gpio_direction_output(TEGRA_CAMERA_GPIO_PMU, 1);
169
170 /* All port pins on the port expander are inputs by default.
171 Set all to output. */
172 i2c_smbus_write_word_data(port_expander, TCA6416_REG_CNF, 0x0000);
173
174 /* Take port switch out of reset and turn on camera 3. */
175 val = TCA6416_PORT_CAM3_RST |
176 TCA6416_PORT_TP_CAM3_AF_PWDN |
177 TCA6416_PORT_CAM3_LDO_SHDN |
178 TCA6416_PORT_CAM_I2C_MUX_RST |
179 TCA6416_PORT_CAM_LED1;
180 i2c_smbus_write_word_data(port_expander, TCA6416_REG_OUTP, val);
181
182 #ifdef DEBUG
183 tegra_camera_dump_port_expander_regs(ndev);
184 #endif
185
186 /* Twiddle port switch to select our camera. */
187 val2 = i2c_smbus_read_byte(port_switch);
188 val2 |= (1 << 2); /* Enable port 2 (out of 0..3). */
189 i2c_smbus_write_byte(port_switch, val2);
190
191 #ifdef DEBUG
192 tegra_camera_dump_port_switch_regs(ndev);
193 #endif
194
195 /* Give the sensor time to come out of reset. The OV9740 needs
196 8192 clock cycles (from vi_sensor clock) before the first I2C
197 transaction. */
Olof Johansson 2011/03/28 22:41:44 /* Comment style * should be * like this. */
198 udelay(1000);
199
200 return 0;
201
202 /*exit_gpio_free_pmu: */
203 /* gpio_free(TEGRA_CAMERA_GPIO_PMU); */
Olof Johansson 2011/03/28 22:41:44 More commented out code.
204 exit_gpio_free_vi_gp3:
205 gpio_free(TEGRA_CAMERA_GPIO_VI_GP3);
206 exit_gpio_free_cam_pwr_en:
207 gpio_free(TEGRA_CAMERA_GPIO_CAM_PWR_EN);
208 exit_port_switch_unregister:
209 i2c_unregister_device(port_switch);
210 exit_port_expander_unregister:
211 i2c_unregister_device(port_expander);
212 exit_adapter_put:
213 i2c_put_adapter(adapter);
214 exit_regulator_disable:
215 regulator_disable(regulator);
216 exit_regulator_put:
217 regulator_put(regulator);
218 exit:
219 return err;
220 }
221
222 static void tegra_camera_disable(struct nvhost_device *ndev)
223 {
224 struct i2c_adapter *adapter;
225
226 gpio_free(TEGRA_CAMERA_GPIO_PMU);
227 gpio_free(TEGRA_CAMERA_GPIO_VI_GP3);
228 gpio_free(TEGRA_CAMERA_GPIO_CAM_PWR_EN);
229
230 adapter = i2c_get_adapter(TEGRA_CAMERA_I2C_ADAPTER_ID);
231 BUG_ON(!adapter);
232 i2c_unregister_device(port_switch);
233 i2c_unregister_device(port_expander);
234 i2c_put_adapter(adapter);
235
236 BUG_ON(!regulator);
237 regulator_disable(regulator);
238 regulator_put(regulator);
239 regulator = NULL;
240
241 /* Turn off relevant clocks. */
242 clk_disable(clk_vi);
243 clk_disable(clk_vi_sensor);
244 clk_disable(clk_csi);
245 clk_disable(clk_isp);
246 clk_disable(clk_csus);
247 }
248
249 static struct i2c_board_info seaboard_i2c_bus3_sensor_info = {
250 I2C_BOARD_INFO("ov9740", 0x10),
251 };
252
253 static struct soc_camera_link ov9740_iclink = {
254 .bus_id = 0,
255 .i2c_adapter_id = TEGRA_CAMERA_I2C_ADAPTER_ID,
256 .board_info = &seaboard_i2c_bus3_sensor_info,
257 .module_name = "ov9740",
258 };
259
260 static struct platform_device soc_camera = {
261 .name = "soc-camera-pdrv",
262 .id = 0,
263 .dev = {
264 .platform_data = &ov9740_iclink,
265 },
266 };
267
268 static struct tegra_camera_platform_data tegra_camera_platform_data = {
269 .enable_camera = tegra_camera_enable,
270 .disable_camera = tegra_camera_disable,
271 .flip_v = 1,
272 .flip_h = 0,
273 };
274
275 int __init seaboard_sensors_init(void)
276 {
277 tegra_camera_device.dev.platform_data = &tegra_camera_platform_data;
278
279 tegra_gpio_enable(TEGRA_CAMERA_GPIO_CAM_PWR_EN);
280 tegra_gpio_enable(TEGRA_CAMERA_GPIO_VI_GP3);
281
282 clk_vi = clk_get_sys("tegra_camera", "vi");
283 clk_vi_sensor = clk_get_sys("tegra_camera", "vi_sensor");
284 clk_csi = clk_get_sys("tegra_camera", "csi");
285 clk_isp = clk_get_sys("tegra_camera", "isp");
286 clk_csus = clk_get_sys("tegra_camera", "csus");
Olof Johansson 2011/03/28 22:41:44 Maybe print a warning if any of those clock gets f
287
288 nvhost_device_register(&tegra_camera_device);
289
290 platform_device_register(&soc_camera);
291
292 return 0;
293 }
294
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698