Full support for Ginger Console
[linux-ginger.git] / arch / arm / mach-omap2 / board-omap3evm-camera.c
blob05d4837bc36a6464a326f9e2963daf2c1b1c3425
1 /*
2 * arch/arm/mach-omap2/board-omap3evm-dc-v4l.c
4 * Driver for OMAP3 EVM Mass Market Daughter Card
6 * Copyright (C) 2008 Texas Instruments Inc
7 * Author: Vaibhav Hiremath <hvaibhav@ti.com>
9 * Contributors:
10 * Anuj Aggarwal <anuj.aggarwal@ti.com>
11 * Sivaraj R <sivaraj@ti.com>
13 * This package is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include <linux/init.h>
29 #include <linux/i2c.h>
30 #include <linux/gpio.h>
31 #include <linux/mm.h>
32 #include <linux/videodev2.h>
33 #include <linux/i2c/twl4030.h>
34 #include <linux/delay.h>
36 #include <plat/mux.h>
37 #include <plat/board.h>
39 #include <media/v4l2-int-device.h>
40 #include <media/tvp514x-int.h>
42 /* Include V4L2 ISP-Camera driver related header file */
43 #include <../drivers/media/video/omap34xxcam.h>
44 #include <../drivers/media/video/isp/ispreg.h>
46 #include "board-omap3evm-camera.h"
48 #define MODULE_NAME "omap3evmdc"
50 #define TVP5146_I2C_BUSNUM 3
51 /* Is decoder present on-board or Daughter card */
52 static bool is_dec_onboard;
54 /* GPIO pins Daughter Card */
55 #define GPIO134_SEL_TVP_Y (134)
56 #define GPIO54_SEL_EXP_CAM (54)
57 #define GPIO136_SEL_CAM (136)
58 /* GPIO pins for GEN_2 EVM */
59 #define GPIO98_VID_DEC_RES (98)
60 #define nCAM_VD_SEL (157)
62 #ifndef TRUE
63 #define TRUE 1
64 #endif
65 #ifndef FALSE
66 #define FALSE 0
67 #endif
69 #if defined(CONFIG_VIDEO_TVP514X) || defined(CONFIG_VIDEO_TVP514X_MODULE)
70 #if defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
71 static struct omap34xxcam_hw_config decoder_hwc = {
72 .dev_index = 0,
73 .dev_minor = 0,
74 .dev_type = OMAP34XXCAM_SLAVE_SENSOR,
75 .u.sensor.sensor_isp = 1,
76 .u.sensor.capture_mem = PAGE_ALIGN(720*525*2*4),
79 static struct isp_interface_config tvp5146_if_config = {
80 .ccdc_par_ser = ISP_PARLL_YUV_BT,
81 .dataline_shift = 0x1,
82 .hsvs_syncdetect = ISPCTRL_SYNC_DETECT_VSRISE,
83 .strobe = 0x0,
84 .prestrobe = 0x0,
85 .shutter = 0x0,
86 .wait_hs_vs = 2,
87 .u.par.par_bridge = 0x0,
88 .u.par.par_clk_pol = 0x0,
90 #endif
92 static struct v4l2_ifparm ifparm = {
93 .if_type = V4L2_IF_TYPE_BT656,
94 .u = {
95 .bt656 = {
96 .frame_start_on_rising_vs = 1,
97 .bt_sync_correct = 0,
98 .swap = 0,
99 .latch_clk_inv = 0,
100 .nobt_hs_inv = 0, /* active high */
101 .nobt_vs_inv = 0, /* active high */
102 .mode = V4L2_IF_TYPE_BT656_MODE_BT_8BIT,
103 .clock_min = TVP514X_XCLK_BT656,
104 .clock_max = TVP514X_XCLK_BT656,
110 * @brief tvp5146_ifparm - Returns the TVP5146 decoder interface parameters
112 * @param p - pointer to v4l2_ifparm structure
114 * @return result of operation - 0 is success
116 static int tvp5146_ifparm(struct v4l2_ifparm *p)
118 if (p == NULL)
119 return -EINVAL;
121 *p = ifparm;
122 return 0;
126 * @brief tvp5146_set_prv_data - Returns tvp5146 omap34xx driver private data
128 * @param priv - pointer to omap34xxcam_hw_config structure
130 * @return result of operation - 0 is success
132 static int tvp5146_set_prv_data(struct v4l2_int_device *s, void *priv)
134 #if defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
135 struct omap34xxcam_hw_config *hwc = priv;
137 if (priv == NULL)
138 return -EINVAL;
140 hwc->u.sensor.sensor_isp = decoder_hwc.u.sensor.sensor_isp;
141 hwc->u.sensor.capture_mem = decoder_hwc.u.sensor.capture_mem;
142 hwc->dev_index = decoder_hwc.dev_index;
143 hwc->dev_minor = decoder_hwc.dev_minor;
144 hwc->dev_type = decoder_hwc.dev_type;
145 return 0;
146 #else
147 return -EINVAL;
148 #endif
152 * @brief omap3evmdc_set_mux - Sets mux to enable/disable signal routing to
153 * different peripherals present in board
154 * IMPORTANT - This function will take care of writing appropriate values for
155 * active low signals as well
157 * @param mux_id - enum, mux id to enable/disable
158 * @param value - enum, ENABLE_MUX for enabling and DISABLE_MUX for disabling
160 * @return result of operation - 0 is success
162 static int omap3evmdc_set_mux(enum omap3evmdc_mux mux_id, enum config_mux value)
164 int err = 0;
166 if (unlikely(mux_id >= NUM_MUX)) {
167 printk(KERN_ERR MODULE_NAME ": Invalid mux id\n");
168 return -EPERM;
171 switch (mux_id) {
172 case MUX_TVP5146:
173 if (ENABLE_MUX == value) {
174 /* Enable TVP5146 Video in (GPIO134 = 0) */
175 gpio_set_value(GPIO134_SEL_TVP_Y, 0);
176 /* Disable Expansion Camera Video in (GPIO54 = 1) */
177 gpio_set_value(GPIO54_SEL_EXP_CAM, 1);
178 /* Disable Camera Video in (GPIO136 = 1)*/
179 gpio_set_value(GPIO136_SEL_CAM, 1);
180 } else {
181 /* Disable TVP5146 Video in (GPIO134 = 0) */
182 gpio_set_value(GPIO134_SEL_TVP_Y, 1);
184 break;
186 case MUX_CAMERA_SENSOR:
187 if (ENABLE_MUX == value) {
188 /* Disable TVP5146 Video in (GPIO134 = 0) */
189 gpio_set_value(GPIO134_SEL_TVP_Y, 1);
190 /* Disable Exapansion Camera Video in (GPIO54 = 1) */
191 gpio_set_value(GPIO54_SEL_EXP_CAM, 1);
192 /* Enable Camera Video in (GPIO136 = 1) */
193 gpio_set_value(GPIO136_SEL_CAM, 0);
194 } else {
195 /* Disable Camera Video in (GPIO136 = 1) */
196 gpio_set_value(GPIO136_SEL_CAM, 1);
198 break;
200 case MUX_EXP_CAMERA_SENSOR:
201 if (ENABLE_MUX == value) {
202 /* Disable TVP5146 Video in (GPIO134 = 0) */
203 gpio_set_value(GPIO134_SEL_TVP_Y, 1);
204 /* Enable Expansion Camera Video in (GPIO54 = 1) */
205 gpio_set_value(GPIO54_SEL_EXP_CAM, 0);
206 /* Disable Camera Video in (GPIO136 = 1) */
207 gpio_set_value(GPIO136_SEL_CAM, 1);
208 } else {
209 /* Disable Expansion Camera Video in (GPIO54 = 1) */
210 gpio_set_value(GPIO54_SEL_EXP_CAM, 1);
212 break;
214 case NUM_MUX:
215 default:
216 printk(KERN_ERR "Invalid mux id\n");
217 err = -EPERM;
220 return err;
224 * @brief omap3evm_set_mux - Sets mux to enable/disable signal routing to
225 * different peripherals present on new EVM board
226 * IMPORTANT - This function will take care of writing appropriate values for
227 * active low signals as well
229 * @param mux_id - enum, mux id to enable/disable
230 * @param value - enum, ENABLE_MUX for enabling and DISABLE_MUX for disabling
232 * @return result of operation - 0 is success
234 static int omap3evm_set_mux(enum omap3evmdc_mux mux_id, enum config_mux value)
236 static int is_init_done = 0;
237 unsigned char val;
238 int err = 0;
240 if (unlikely(mux_id >= NUM_MUX)) {
241 printk(KERN_ERR MODULE_NAME ": Invalid mux id\n");
242 return -EPERM;
245 if (is_init_done == 0) {
246 /*FIXME: Need to follow standard GPIO API's to control
247 * TWL4030 GPIO.
249 /* Enable TWL GPIO Module */
250 twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0x04, REG_GPIO_CTRL);
252 /* First Level Enable GPIO */
253 /* Configure GPIO2 as output */
254 twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val, REG_GPIODATADIR1);
255 val |= 0x04;
256 twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val, REG_GPIODATADIR1);
257 /* Set GPIO-2 pull-up */
258 twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val, REG_GPIOPUPDCTR1);
259 val |= 0x20;
260 twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val, REG_GPIOPUPDCTR1);
261 /* Set GPIO-2 = 0 */
262 twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val, REG_GPIODATAOUT1);
263 val &= ~0x04;
264 twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val, REG_GPIODATAOUT1);
266 /* Configure GPIO8 as output*/
267 twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val, REG_GPIODATADIR2);
268 val |= 0x1;
269 twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val, REG_GPIODATADIR2);
270 /* GPIO-8 pull down */
271 twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val, REG_GPIOPUPDCTR3);
272 val |= 0x01;
273 twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val, REG_GPIOPUPDCTR3);
275 /* Assert the reset signal */
276 gpio_set_value(GPIO98_VID_DEC_RES, 0);
277 mdelay(5);
278 gpio_set_value(GPIO98_VID_DEC_RES, 1);
280 switch (mux_id) {
281 case MUX_TVP5146:
282 if (ENABLE_MUX == value) {
283 /* Set GPIO8 = 0 */
284 twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
285 REG_GPIODATAOUT2);
286 val &= ~0x1;
287 twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
288 REG_GPIODATAOUT2);
290 gpio_set_value(nCAM_VD_SEL, 1);
291 } else {
292 /* Set GPIO8 = 0 */
293 twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
294 REG_GPIODATAOUT2);
295 val |= 0x1;
296 twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
297 REG_GPIODATAOUT2);
299 break;
301 case MUX_CAMERA_SENSOR:
302 if (ENABLE_MUX == value) {
303 /* Set GPIO8 = 0 */
304 twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
305 REG_GPIODATAOUT2);
306 val &= ~0x1;
307 twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
308 REG_GPIODATAOUT2);
310 gpio_set_value(nCAM_VD_SEL, 0);
311 } else {
312 /* Set GPIO8 = 0 */
313 twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
314 REG_GPIODATAOUT2);
315 val |= 0x1;
316 twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
317 REG_GPIODATAOUT2);
319 break;
321 case MUX_EXP_CAMERA_SENSOR:
322 if (ENABLE_MUX == value) {
323 /* Set GPIO8 = 1 */
324 twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
325 REG_GPIODATAOUT2);
326 val |= 0x1;
327 twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
328 REG_GPIODATAOUT2);
330 } else {
331 /* Set GPIO8 = 0 */
332 twl4030_i2c_read_u8(TWL4030_MODULE_GPIO, &val,
333 REG_GPIODATAOUT2);
334 val &= ~0x1;
335 twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, val,
336 REG_GPIODATAOUT2);
338 break;
340 case NUM_MUX:
341 default:
342 printk(KERN_ERR "Invalid mux id\n");
343 err = -EPERM;
346 return err;
349 * @brief tvp5146_power_set - Power-on or power-off TVP5146 device
351 * @param power - enum, Power on/off, resume/standby
353 * @return result of operation - 0 is success
355 static int tvp5146_power_set(struct v4l2_int_device *s, enum v4l2_power power)
357 struct omap34xxcam_videodev *vdev = s->u.slave->master->priv;
359 switch (power) {
360 case V4L2_POWER_OFF:
361 /* Disable mux for TVP5146 decoder data path */
362 if (is_dec_onboard) {
363 if (omap3evm_set_mux(MUX_TVP5146, DISABLE_MUX))
364 return -ENODEV;
365 } else {
366 if (omap3evmdc_set_mux(MUX_TVP5146, DISABLE_MUX))
367 return -ENODEV;
369 break;
371 case V4L2_POWER_STANDBY:
372 break;
374 case V4L2_POWER_ON:
375 /* Enable mux for TVP5146 decoder data path */
376 if (is_dec_onboard) {
377 if (omap3evm_set_mux(MUX_TVP5146, ENABLE_MUX))
378 return -ENODEV;
379 } else {
380 if (omap3evmdc_set_mux(MUX_TVP5146, ENABLE_MUX))
381 return -ENODEV;
384 #if defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
385 isp_configure_interface(vdev->cam->isp, &tvp5146_if_config);
386 #endif
387 break;
389 default:
390 return -ENODEV;
391 break;
393 return 0;
396 static struct tvp514x_platform_data tvp5146_pdata = {
397 .master = "omap34xxcam",
398 .power_set = tvp5146_power_set,
399 .priv_data_set = tvp5146_set_prv_data,
400 .ifparm = tvp5146_ifparm,
401 /* Some interface dependent params */
402 .clk_polarity = 0, /* data clocked out on falling edge */
403 .hs_polarity = 1, /* 0 - Active low, 1- Active high */
404 .vs_polarity = 1, /* 0 - Active low, 1- Active high */
407 static struct i2c_board_info __initdata tvp5146_i2c_board_info = {
408 I2C_BOARD_INFO("tvp5146m2", 0),
409 .platform_data = &tvp5146_pdata,
412 #endif /* #ifdef CONFIG_VIDEO_TVP514X */
415 * @brief omap3evmdc_mdc_config - GPIO configuration for
416 * GPIO 134, 54 and 136
418 * @return result of operation - 0 is success
420 static int omap3evmdc_mdc_config(void)
422 if (is_dec_onboard) {
423 /* Enable Video Decoder */
424 omap_cfg_reg(AA21_34XX_GPIO157);
425 if (gpio_request(nCAM_VD_SEL, "Vid-Dec Sel") < 0) {
426 printk(KERN_ERR "Failed to get GPIO 157\n");
427 return -EINVAL;
429 gpio_direction_output(nCAM_VD_SEL, 1);
430 gpio_set_value(nCAM_VD_SEL, 1);
432 omap_cfg_reg(C23_34XX_GPIO98);
433 if (gpio_request(GPIO98_VID_DEC_RES, "vid-dec reset") < 0) {
434 printk(KERN_ERR "failed to get GPIO98_VID_DEC_RES\n");
435 return -EINVAL;
437 gpio_direction_output(GPIO98_VID_DEC_RES, 1);
438 } else {
440 /* Setting the MUX configuration */
441 omap_cfg_reg(AG4_34XX_GPIO134_OUT);
442 omap_cfg_reg(U8_34XX_GPIO54_OUT);
443 omap_cfg_reg(AE4_34XX_GPIO136_OUT);
445 if (gpio_request(GPIO134_SEL_TVP_Y, "TVP5146 Vid-in") < 0) {
446 printk(KERN_ERR MODULE_NAME ": Can't get GPIO 134\n");
447 return -EINVAL;
450 if (gpio_request(GPIO54_SEL_EXP_CAM, "EXP_CAM Vid-in") < 0) {
451 printk(KERN_ERR MODULE_NAME ": Can't get GPIO 54\n");
452 return -EINVAL;
455 if (gpio_request(GPIO136_SEL_CAM, "CAM Vid-in") < 0) {
456 printk(KERN_ERR MODULE_NAME ": Can't get GPIO 136\n");
457 return -EINVAL;
460 /* Make GPIO as output */
461 gpio_direction_output(GPIO134_SEL_TVP_Y, 0);
462 gpio_direction_output(GPIO54_SEL_EXP_CAM, 0);
463 gpio_direction_output(GPIO136_SEL_CAM, 0);
466 return 0;
470 * @brief omap3evmdc_init - module init function. Should be called before any
471 * client driver init call
473 * @return result of operation - 0 is success
475 int __init omap3evmdc_init(void)
477 int err;
479 /* Status of Video Decoder : On Board or DC */
480 if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2)
481 is_dec_onboard = TRUE;
482 else
483 is_dec_onboard = FALSE;
485 err = omap3evmdc_mdc_config();
486 if (err) {
487 printk(KERN_ERR MODULE_NAME ": MDC configuration failed \n");
488 return err;
492 * Register the I2C devices present in the board to the I2C
493 * framework.
494 * If more I2C devices are added, then each device information should
495 * be registered with I2C using i2c_register_board_info().
497 #if defined(CONFIG_VIDEO_TVP514X) || defined(CONFIG_VIDEO_TVP514X_MODULE)
498 if (get_omap3_evm_rev() >= OMAP3EVM_BOARD_GEN_2)
499 tvp5146_i2c_board_info.addr = 0x5C;
500 else
501 tvp5146_i2c_board_info.addr = 0x5D;
503 err = i2c_register_board_info(TVP5146_I2C_BUSNUM,
504 &tvp5146_i2c_board_info, 1);
505 if (err) {
506 printk(KERN_ERR MODULE_NAME \
507 ": TVP5146 I2C Board Registration failed \n");
508 return err;
510 #endif
511 printk(KERN_INFO MODULE_NAME ": Driver registration complete \n");
513 return 0;
515 arch_initcall(omap3evmdc_init);