diff options
author | Valentin Longchamp <valentin.longchamp@epfl.ch> | 2009-11-03 12:09:51 -0500 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2009-11-14 04:29:15 -0500 |
commit | 04ea3c801905a4562cc89af78eba40dec0f960a9 (patch) | |
tree | 51dd16f2bae5032e60720bb7b7d92f499e1a6651 /arch/arm/mach-mx3 | |
parent | 4dd7129345be71cb20da99a75ded01ea50615f66 (diff) |
mx31moboard: camera support
We have two mt9t031 cameras that have a muxed bus on the robot.
Only one is currently initialized because of limitations in
soc_camera that should be removed later.
Signed-off-by: Valentin Longchamp <valentin.longchamp@epfl.ch>
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-mx3')
-rw-r--r-- | arch/arm/mach-mx3/mx31moboard-marxbot.c | 86 | ||||
-rw-r--r-- | arch/arm/mach-mx3/mx31moboard.c | 36 |
2 files changed, 121 insertions, 1 deletions
diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c index 6b06faf0cf30..e4e344eceb7c 100644 --- a/arch/arm/mach-mx3/mx31moboard-marxbot.c +++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c | |||
@@ -16,9 +16,11 @@ | |||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/delay.h> | ||
19 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
21 | #include <linux/interrupt.h> | 22 | #include <linux/interrupt.h> |
23 | #include <linux/i2c.h> | ||
22 | #include <linux/platform_device.h> | 24 | #include <linux/platform_device.h> |
23 | #include <linux/types.h> | 25 | #include <linux/types.h> |
24 | 26 | ||
@@ -28,6 +30,8 @@ | |||
28 | #include <mach/iomux-mx3.h> | 30 | #include <mach/iomux-mx3.h> |
29 | #include <mach/mmc.h> | 31 | #include <mach/mmc.h> |
30 | 32 | ||
33 | #include <media/soc_camera.h> | ||
34 | |||
31 | #include "devices.h" | 35 | #include "devices.h" |
32 | 36 | ||
33 | static unsigned int marxbot_pins[] = { | 37 | static unsigned int marxbot_pins[] = { |
@@ -37,7 +41,6 @@ static unsigned int marxbot_pins[] = { | |||
37 | MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD, | 41 | MX31_PIN_PC_CD2_B__SD2_CLK, MX31_PIN_PC_CD1_B__SD2_CMD, |
38 | MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29, | 42 | MX31_PIN_ATA_DIOR__GPIO3_28, MX31_PIN_ATA_DIOW__GPIO3_29, |
39 | /* CSI */ | 43 | /* CSI */ |
40 | MX31_PIN_CSI_D4__CSI_D4, MX31_PIN_CSI_D5__CSI_D5, | ||
41 | MX31_PIN_CSI_D6__CSI_D6, MX31_PIN_CSI_D7__CSI_D7, | 44 | MX31_PIN_CSI_D6__CSI_D6, MX31_PIN_CSI_D7__CSI_D7, |
42 | MX31_PIN_CSI_D8__CSI_D8, MX31_PIN_CSI_D9__CSI_D9, | 45 | MX31_PIN_CSI_D8__CSI_D8, MX31_PIN_CSI_D9__CSI_D9, |
43 | MX31_PIN_CSI_D10__CSI_D10, MX31_PIN_CSI_D11__CSI_D11, | 46 | MX31_PIN_CSI_D10__CSI_D10, MX31_PIN_CSI_D11__CSI_D11, |
@@ -45,6 +48,7 @@ static unsigned int marxbot_pins[] = { | |||
45 | MX31_PIN_CSI_D14__CSI_D14, MX31_PIN_CSI_D15__CSI_D15, | 48 | MX31_PIN_CSI_D14__CSI_D14, MX31_PIN_CSI_D15__CSI_D15, |
46 | MX31_PIN_CSI_HSYNC__CSI_HSYNC, MX31_PIN_CSI_MCLK__CSI_MCLK, | 49 | MX31_PIN_CSI_HSYNC__CSI_HSYNC, MX31_PIN_CSI_MCLK__CSI_MCLK, |
47 | MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, MX31_PIN_CSI_VSYNC__CSI_VSYNC, | 50 | MX31_PIN_CSI_PIXCLK__CSI_PIXCLK, MX31_PIN_CSI_VSYNC__CSI_VSYNC, |
51 | MX31_PIN_CSI_D4__GPIO3_4, MX31_PIN_CSI_D5__GPIO3_5, | ||
48 | MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1, | 52 | MX31_PIN_GPIO3_0__GPIO3_0, MX31_PIN_GPIO3_1__GPIO3_1, |
49 | MX31_PIN_TXD2__GPIO1_28, | 53 | MX31_PIN_TXD2__GPIO1_28, |
50 | /* dsPIC resets */ | 54 | /* dsPIC resets */ |
@@ -122,6 +126,83 @@ static void dspics_resets_init(void) | |||
122 | } | 126 | } |
123 | } | 127 | } |
124 | 128 | ||
129 | #define TURRETCAM_POWER IOMUX_TO_GPIO(MX31_PIN_GPIO3_1) | ||
130 | #define BASECAM_POWER IOMUX_TO_GPIO(MX31_PIN_CSI_D5) | ||
131 | #define TURRETCAM_RST_B IOMUX_TO_GPIO(MX31_PIN_GPIO3_0) | ||
132 | #define BASECAM_RST_B IOMUX_TO_GPIO(MX31_PIN_CSI_D4) | ||
133 | #define CAM_CHOICE IOMUX_TO_GPIO(MX31_PIN_TXD2) | ||
134 | |||
135 | static int marxbot_basecam_power(struct device *dev, int on) | ||
136 | { | ||
137 | gpio_set_value(BASECAM_POWER, !on); | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | static int marxbot_basecam_reset(struct device *dev) | ||
142 | { | ||
143 | gpio_set_value(BASECAM_RST_B, 0); | ||
144 | udelay(100); | ||
145 | gpio_set_value(BASECAM_RST_B, 1); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static struct i2c_board_info marxbot_i2c_devices[] = { | ||
150 | { | ||
151 | I2C_BOARD_INFO("mt9t031", 0x5d), | ||
152 | }, | ||
153 | }; | ||
154 | |||
155 | static struct soc_camera_link base_iclink = { | ||
156 | .bus_id = 0, /* Must match with the camera ID */ | ||
157 | .power = marxbot_basecam_power, | ||
158 | .reset = marxbot_basecam_reset, | ||
159 | .board_info = &marxbot_i2c_devices[0], | ||
160 | .i2c_adapter_id = 0, | ||
161 | .module_name = "mt9t031", | ||
162 | }; | ||
163 | |||
164 | static struct platform_device marxbot_camera[] = { | ||
165 | { | ||
166 | .name = "soc-camera-pdrv", | ||
167 | .id = 0, | ||
168 | .dev = { | ||
169 | .platform_data = &base_iclink, | ||
170 | }, | ||
171 | }, | ||
172 | }; | ||
173 | |||
174 | static struct platform_device *marxbot_cameras[] __initdata = { | ||
175 | &marxbot_camera[0], | ||
176 | }; | ||
177 | |||
178 | static int __init marxbot_cam_init(void) | ||
179 | { | ||
180 | int ret = gpio_request(CAM_CHOICE, "cam-choice"); | ||
181 | if (ret) | ||
182 | return ret; | ||
183 | gpio_direction_output(CAM_CHOICE, 1); | ||
184 | |||
185 | ret = gpio_request(BASECAM_RST_B, "basecam-reset"); | ||
186 | if (ret) | ||
187 | return ret; | ||
188 | gpio_direction_output(BASECAM_RST_B, 1); | ||
189 | ret = gpio_request(BASECAM_POWER, "basecam-standby"); | ||
190 | if (ret) | ||
191 | return ret; | ||
192 | gpio_direction_output(BASECAM_POWER, 0); | ||
193 | |||
194 | ret = gpio_request(TURRETCAM_RST_B, "turretcam-reset"); | ||
195 | if (ret) | ||
196 | return ret; | ||
197 | gpio_direction_output(TURRETCAM_RST_B, 1); | ||
198 | ret = gpio_request(TURRETCAM_POWER, "turretcam-standby"); | ||
199 | if (ret) | ||
200 | return ret; | ||
201 | gpio_direction_output(TURRETCAM_POWER, 0); | ||
202 | |||
203 | return 0; | ||
204 | } | ||
205 | |||
125 | /* | 206 | /* |
126 | * system init for baseboard usage. Will be called by mx31moboard init. | 207 | * system init for baseboard usage. Will be called by mx31moboard init. |
127 | */ | 208 | */ |
@@ -136,6 +217,9 @@ void __init mx31moboard_marxbot_init(void) | |||
136 | 217 | ||
137 | mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata); | 218 | mxc_register_device(&mxcsdhc_device1, &sdhc2_pdata); |
138 | 219 | ||
220 | marxbot_cam_init(); | ||
221 | platform_add_devices(marxbot_cameras, ARRAY_SIZE(marxbot_cameras)); | ||
222 | |||
139 | /* battery present pin */ | 223 | /* battery present pin */ |
140 | gpio_request(IOMUX_TO_GPIO(MX31_PIN_LCS0), "bat-present"); | 224 | gpio_request(IOMUX_TO_GPIO(MX31_PIN_LCS0), "bat-present"); |
141 | gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_LCS0)); | 225 | gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_LCS0)); |
diff --git a/arch/arm/mach-mx3/mx31moboard.c b/arch/arm/mach-mx3/mx31moboard.c index 2f95dcd805cc..b167f131f7c0 100644 --- a/arch/arm/mach-mx3/mx31moboard.c +++ b/arch/arm/mach-mx3/mx31moboard.c | |||
@@ -17,6 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/dma-mapping.h> | ||
20 | #include <linux/fsl_devices.h> | 21 | #include <linux/fsl_devices.h> |
21 | #include <linux/gpio.h> | 22 | #include <linux/gpio.h> |
22 | #include <linux/init.h> | 23 | #include <linux/init.h> |
@@ -403,6 +404,39 @@ static struct platform_device *devices[] __initdata = { | |||
403 | &mx31moboard_leds_device, | 404 | &mx31moboard_leds_device, |
404 | }; | 405 | }; |
405 | 406 | ||
407 | static struct mx3_camera_pdata camera_pdata = { | ||
408 | .dma_dev = &mx3_ipu.dev, | ||
409 | .flags = MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10, | ||
410 | .mclk_10khz = 4800, | ||
411 | }; | ||
412 | |||
413 | #define CAMERA_BUF_SIZE (4*1024*1024) | ||
414 | |||
415 | static int __init mx31moboard_cam_alloc_dma(const size_t buf_size) | ||
416 | { | ||
417 | dma_addr_t dma_handle; | ||
418 | void *buf; | ||
419 | int dma; | ||
420 | |||
421 | if (buf_size < 2 * 1024 * 1024) | ||
422 | return -EINVAL; | ||
423 | |||
424 | buf = dma_alloc_coherent(NULL, buf_size, &dma_handle, GFP_KERNEL); | ||
425 | if (!buf) { | ||
426 | pr_err("%s: cannot allocate camera buffer-memory\n", __func__); | ||
427 | return -ENOMEM; | ||
428 | } | ||
429 | |||
430 | memset(buf, 0, buf_size); | ||
431 | |||
432 | dma = dma_declare_coherent_memory(&mx3_camera.dev, | ||
433 | dma_handle, dma_handle, buf_size, | ||
434 | DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE); | ||
435 | |||
436 | /* The way we call dma_declare_coherent_memory only a malloc can fail */ | ||
437 | return dma & DMA_MEMORY_MAP ? 0 : -ENOMEM; | ||
438 | } | ||
439 | |||
406 | static int mx31moboard_baseboard; | 440 | static int mx31moboard_baseboard; |
407 | core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444); | 441 | core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444); |
408 | 442 | ||
@@ -436,6 +470,8 @@ static void __init mxc_board_init(void) | |||
436 | mxc_register_device(&mxcsdhc_device0, &sdhc1_pdata); | 470 | mxc_register_device(&mxcsdhc_device0, &sdhc1_pdata); |
437 | 471 | ||
438 | mxc_register_device(&mx3_ipu, &mx3_ipu_data); | 472 | mxc_register_device(&mx3_ipu, &mx3_ipu_data); |
473 | if (!mx31moboard_cam_alloc_dma(CAMERA_BUF_SIZE)) | ||
474 | mxc_register_device(&mx3_camera, &camera_pdata); | ||
439 | 475 | ||
440 | usb_xcvr_reset(); | 476 | usb_xcvr_reset(); |
441 | 477 | ||