aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-mx3
diff options
context:
space:
mode:
authorAlberto Panizzo <alberto@amarulasolutions.com>2011-03-07 05:47:37 -0500
committerSascha Hauer <s.hauer@pengutronix.de>2011-03-08 07:24:22 -0500
commit164f7b5237cca2701dd2943928ec8d078877a28d (patch)
tree7f0330eef457ec7d2c90f6182f3214029a5d37aa /arch/arm/mach-mx3
parente42010e0e129cc31a83ce9d8d1c7e1d50ba155f3 (diff)
mach-mx31_3ds: Add support for the camera device on the personality board
Signed-off-by: Alberto Panizzo <alberto@amarulasolutions.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch/arm/mach-mx3')
-rw-r--r--arch/arm/mach-mx3/mach-mx31_3ds.c156
1 files changed, 156 insertions, 0 deletions
diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c
index d760a06c9e3c..544d3e414f58 100644
--- a/arch/arm/mach-mx3/mach-mx31_3ds.c
+++ b/arch/arm/mach-mx3/mach-mx31_3ds.c
@@ -25,6 +25,9 @@
25#include <linux/regulator/machine.h> 25#include <linux/regulator/machine.h>
26#include <linux/usb/otg.h> 26#include <linux/usb/otg.h>
27#include <linux/usb/ulpi.h> 27#include <linux/usb/ulpi.h>
28#include <linux/memblock.h>
29
30#include <media/soc_camera.h>
28 31
29#include <mach/hardware.h> 32#include <mach/hardware.h>
30#include <asm/mach-types.h> 33#include <asm/mach-types.h>
@@ -39,6 +42,7 @@
39#include <mach/mmc.h> 42#include <mach/mmc.h>
40#include <mach/ipu.h> 43#include <mach/ipu.h>
41#include <mach/mx3fb.h> 44#include <mach/mx3fb.h>
45#include <mach/mx3_camera.h>
42 46
43#include "devices-imx31.h" 47#include "devices-imx31.h"
44#include "devices.h" 48#include "devices.h"
@@ -141,6 +145,106 @@ static int mx31_3ds_pins[] = {
141 MX31_PIN_HSYNC__HSYNC, 145 MX31_PIN_HSYNC__HSYNC,
142 MX31_PIN_FPSHIFT__FPSHIFT, 146 MX31_PIN_FPSHIFT__FPSHIFT,
143 MX31_PIN_CONTRAST__CONTRAST, 147 MX31_PIN_CONTRAST__CONTRAST,
148 /* CSI */
149 MX31_PIN_CSI_D6__CSI_D6,
150 MX31_PIN_CSI_D7__CSI_D7,
151 MX31_PIN_CSI_D8__CSI_D8,
152 MX31_PIN_CSI_D9__CSI_D9,
153 MX31_PIN_CSI_D10__CSI_D10,
154 MX31_PIN_CSI_D11__CSI_D11,
155 MX31_PIN_CSI_D12__CSI_D12,
156 MX31_PIN_CSI_D13__CSI_D13,
157 MX31_PIN_CSI_D14__CSI_D14,
158 MX31_PIN_CSI_D15__CSI_D15,
159 MX31_PIN_CSI_HSYNC__CSI_HSYNC,
160 MX31_PIN_CSI_MCLK__CSI_MCLK,
161 MX31_PIN_CSI_PIXCLK__CSI_PIXCLK,
162 MX31_PIN_CSI_VSYNC__CSI_VSYNC,
163 MX31_PIN_CSI_D5__GPIO3_5, /* CMOS PWDN */
164 IOMUX_MODE(MX31_PIN_RI_DTE1, IOMUX_CONFIG_GPIO), /* CMOS reset */
165};
166
167/*
168 * Camera support
169 */
170static phys_addr_t mx3_camera_base __initdata;
171#define MX31_3DS_CAMERA_BUF_SIZE SZ_8M
172
173#define MX31_3DS_GPIO_CAMERA_PW IOMUX_TO_GPIO(MX31_PIN_CSI_D5)
174#define MX31_3DS_GPIO_CAMERA_RST IOMUX_TO_GPIO(MX31_PIN_RI_DTE1)
175
176static struct gpio mx31_3ds_camera_gpios[] = {
177 { MX31_3DS_GPIO_CAMERA_PW, GPIOF_OUT_INIT_HIGH, "camera-power" },
178 { MX31_3DS_GPIO_CAMERA_RST, GPIOF_OUT_INIT_HIGH, "camera-reset" },
179};
180
181static int __init mx31_3ds_camera_alloc_dma(void)
182{
183 int dma;
184
185 if (!mx3_camera_base)
186 return -ENOMEM;
187
188 dma = dma_declare_coherent_memory(&mx3_camera.dev,
189 mx3_camera_base, mx3_camera_base,
190 MX31_3DS_CAMERA_BUF_SIZE,
191 DMA_MEMORY_MAP | DMA_MEMORY_EXCLUSIVE);
192
193 if (!(dma & DMA_MEMORY_MAP))
194 return -ENOMEM;
195
196 return 0;
197}
198
199static int mx31_3ds_camera_power(struct device *dev, int on)
200{
201 /* enable or disable the camera */
202 pr_debug("%s: %s the camera\n", __func__, on ? "ENABLE" : "DISABLE");
203 gpio_set_value(MX31_3DS_GPIO_CAMERA_PW, on ? 0 : 1);
204
205 if (!on)
206 goto out;
207
208 /* If enabled, give a reset impulse */
209 gpio_set_value(MX31_3DS_GPIO_CAMERA_RST, 0);
210 msleep(20);
211 gpio_set_value(MX31_3DS_GPIO_CAMERA_RST, 1);
212 msleep(100);
213
214out:
215 return 0;
216}
217
218static struct i2c_board_info mx31_3ds_i2c_camera = {
219 I2C_BOARD_INFO("ov2640", 0x30),
220};
221
222static struct regulator_bulk_data mx31_3ds_camera_regs[] = {
223 { .supply = "cmos_vcore" },
224 { .supply = "cmos_2v8" },
225};
226
227static struct soc_camera_link iclink_ov2640 = {
228 .bus_id = 0,
229 .board_info = &mx31_3ds_i2c_camera,
230 .i2c_adapter_id = 0,
231 .power = mx31_3ds_camera_power,
232 .regulators = mx31_3ds_camera_regs,
233 .num_regulators = ARRAY_SIZE(mx31_3ds_camera_regs),
234};
235
236static struct platform_device mx31_3ds_ov2640 = {
237 .name = "soc-camera-pdrv",
238 .id = 0,
239 .dev = {
240 .platform_data = &iclink_ov2640,
241 },
242};
243
244struct mx3_camera_pdata mx31_3ds_camera_pdata = {
245 .dma_dev = &mx3_ipu.dev,
246 .flags = MX3_CAMERA_DATAWIDTH_10,
247 .mclk_10khz = 2600,
144}; 248};
145 249
146/* 250/*
@@ -307,6 +411,7 @@ static struct regulator_init_data vmmc2_init = {
307 411
308static struct regulator_consumer_supply vmmc1_consumers[] = { 412static struct regulator_consumer_supply vmmc1_consumers[] = {
309 REGULATOR_SUPPLY("lcd_2v8", NULL), 413 REGULATOR_SUPPLY("lcd_2v8", NULL),
414 REGULATOR_SUPPLY("cmos_2v8", "soc-camera-pdrv.0"),
310}; 415};
311 416
312static struct regulator_init_data vmmc1_init = { 417static struct regulator_init_data vmmc1_init = {
@@ -337,6 +442,22 @@ static struct regulator_init_data vgen_init = {
337 .consumer_supplies = vgen_consumers, 442 .consumer_supplies = vgen_consumers,
338}; 443};
339 444
445static struct regulator_consumer_supply vvib_consumers[] = {
446 REGULATOR_SUPPLY("cmos_vcore", "soc-camera-pdrv.0"),
447};
448
449static struct regulator_init_data vvib_init = {
450 .constraints = {
451 .min_uV = 1300000,
452 .max_uV = 1300000,
453 .apply_uV = 1,
454 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE |
455 REGULATOR_CHANGE_STATUS,
456 },
457 .num_consumer_supplies = ARRAY_SIZE(vvib_consumers),
458 .consumer_supplies = vvib_consumers,
459};
460
340static struct mc13xxx_regulator_init_data mx31_3ds_regulators[] = { 461static struct mc13xxx_regulator_init_data mx31_3ds_regulators[] = {
341 { 462 {
342 .id = MC13783_REG_PWGT1SPI, /* Power Gate for ARM core. */ 463 .id = MC13783_REG_PWGT1SPI, /* Power Gate for ARM core. */
@@ -360,6 +481,9 @@ static struct mc13xxx_regulator_init_data mx31_3ds_regulators[] = {
360 }, { 481 }, {
361 .id = MC13783_REG_VGEN, /* Power LCD */ 482 .id = MC13783_REG_VGEN, /* Power LCD */
362 .init_data = &vgen_init, 483 .init_data = &vgen_init,
484 }, {
485 .id = MC13783_REG_VVIB, /* Power CMOS */
486 .init_data = &vvib_init,
363 }, 487 },
364}; 488};
365 489
@@ -552,8 +676,14 @@ static const struct imxi2c_platform_data mx31_3ds_i2c0_data __initconst = {
552 .bitrate = 100000, 676 .bitrate = 100000,
553}; 677};
554 678
679static struct platform_device *devices[] __initdata = {
680 &mx31_3ds_ov2640,
681};
682
555static void __init mx31_3ds_init(void) 683static void __init mx31_3ds_init(void)
556{ 684{
685 int ret;
686
557 mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins), 687 mxc_iomux_setup_multiple_pins(mx31_3ds_pins, ARRAY_SIZE(mx31_3ds_pins),
558 "mx31_3ds"); 688 "mx31_3ds");
559 689
@@ -564,6 +694,8 @@ static void __init mx31_3ds_init(void)
564 spi_register_board_info(mx31_3ds_spi_devs, 694 spi_register_board_info(mx31_3ds_spi_devs,
565 ARRAY_SIZE(mx31_3ds_spi_devs)); 695 ARRAY_SIZE(mx31_3ds_spi_devs));
566 696
697 platform_add_devices(devices, ARRAY_SIZE(devices));
698
567 imx31_add_imx_keypad(&mx31_3ds_keymap_data); 699 imx31_add_imx_keypad(&mx31_3ds_keymap_data);
568 700
569 mx31_3ds_usbotg_init(); 701 mx31_3ds_usbotg_init();
@@ -591,6 +723,20 @@ static void __init mx31_3ds_init(void)
591 imx31_add_spi_imx0(&spi0_pdata); 723 imx31_add_spi_imx0(&spi0_pdata);
592 mxc_register_device(&mx3_ipu, &mx3_ipu_data); 724 mxc_register_device(&mx3_ipu, &mx3_ipu_data);
593 mxc_register_device(&mx3_fb, &mx3fb_pdata); 725 mxc_register_device(&mx3_fb, &mx3fb_pdata);
726
727 /* CSI */
728 /* Camera power: default - off */
729 ret = gpio_request_array(mx31_3ds_camera_gpios,
730 ARRAY_SIZE(mx31_3ds_camera_gpios));
731 if (ret) {
732 pr_err("Failed to request camera gpios");
733 iclink_ov2640.power = NULL;
734 }
735
736 if (!mx31_3ds_camera_alloc_dma())
737 mxc_register_device(&mx3_camera, &mx31_3ds_camera_pdata);
738 else
739 pr_err("Failed to allocate dma memory for camera");
594} 740}
595 741
596static void __init mx31_3ds_timer_init(void) 742static void __init mx31_3ds_timer_init(void)
@@ -602,6 +748,15 @@ static struct sys_timer mx31_3ds_timer = {
602 .init = mx31_3ds_timer_init, 748 .init = mx31_3ds_timer_init,
603}; 749};
604 750
751static void __init mx31_3ds_reserve(void)
752{
753 /* reserve MX31_3DS_CAMERA_BUF_SIZE bytes for mx3-camera */
754 mx3_camera_base = memblock_alloc(MX31_3DS_CAMERA_BUF_SIZE,
755 MX31_3DS_CAMERA_BUF_SIZE);
756 memblock_free(mx3_camera_base, MX31_3DS_CAMERA_BUF_SIZE);
757 memblock_remove(mx3_camera_base, MX31_3DS_CAMERA_BUF_SIZE);
758}
759
605MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)") 760MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
606 /* Maintainer: Freescale Semiconductor, Inc. */ 761 /* Maintainer: Freescale Semiconductor, Inc. */
607 .boot_params = MX3x_PHYS_OFFSET + 0x100, 762 .boot_params = MX3x_PHYS_OFFSET + 0x100,
@@ -610,4 +765,5 @@ MACHINE_START(MX31_3DS, "Freescale MX31PDK (3DS)")
610 .init_irq = mx31_init_irq, 765 .init_irq = mx31_init_irq,
611 .timer = &mx31_3ds_timer, 766 .timer = &mx31_3ds_timer,
612 .init_machine = mx31_3ds_init, 767 .init_machine = mx31_3ds_init,
768 .reserve = mx31_3ds_reserve,
613MACHINE_END 769MACHINE_END