summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXinyu Chen <b03824@freescale.com>2011-12-06 17:19:12 +0800
committerXinyu Chen <b03824@freescale.com>2011-12-06 17:19:12 +0800
commit4eb99c5e5be396410fa62178e94b8fca62abf7d5 (patch)
tree17670f1e0ffb20a1aaa48a72a7312c1ee4a036cb
parent73c089abb36b98866bbfbaec0f9a2dafbfe73ed5 (diff)
parentb92265a274f0fec27567e86b995424ef8823499f (diff)
Merge remote branch 'fsl-linux-sdk/imx_2.6.38' into imx_2.6.38_android
Conflicts: arch/arm/mach-mx6/system.c drivers/media/video/mxc/capture/mxc_v4l2_capture.c
-rw-r--r--arch/arm/configs/imx6_android_defconfig1
-rw-r--r--arch/arm/configs/imx6_defconfig8
-rw-r--r--arch/arm/configs/imx6_updater_defconfig1
-rw-r--r--arch/arm/mach-mx6/Kconfig38
-rw-r--r--arch/arm/mach-mx6/Makefile1
-rw-r--r--arch/arm/mach-mx6/board-mx6q_arm2.c154
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabreauto.c1560
-rwxr-xr-xarch/arm/mach-mx6/board-mx6q_sabrelite.c48
-rw-r--r--arch/arm/mach-mx6/clock.c90
-rw-r--r--arch/arm/mach-mx6/cpu.c18
-rw-r--r--arch/arm/mach-mx6/cpu_op-mx6.c70
-rw-r--r--arch/arm/mach-mx6/cpu_op-mx6.h3
-rw-r--r--arch/arm/mach-mx6/devices-imx6q.h5
-rw-r--r--arch/arm/mach-mx6/mx6_fec.c2
-rw-r--r--arch/arm/mach-mx6/pm.c6
-rw-r--r--arch/arm/mach-mx6/system.c5
-rw-r--r--arch/arm/mach-mx6/usb_dr.c14
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-perfmon.c88
-rw-r--r--arch/arm/plat-mxc/dvfs_core.c21
-rw-r--r--arch/arm/plat-mxc/include/mach/esdhc.h1
-rw-r--r--arch/arm/plat-mxc/include/mach/imx-uart.h3
-rw-r--r--arch/arm/plat-mxc/include/mach/ipu-v3.h16
-rw-r--r--arch/arm/plat-mxc/include/mach/mipi_csi2.h39
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/uncompress.h3
-rw-r--r--drivers/dma/imx-sdma.c11
-rw-r--r--drivers/media/video/mxc/capture/Kconfig8
-rw-r--r--drivers/media/video/mxc/capture/Makefile3
-rw-r--r--drivers/media/video/mxc/capture/ipu_csi_enc.c53
-rw-r--r--drivers/media/video/mxc/capture/ipu_prp_enc.c65
-rw-r--r--drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c62
-rw-r--r--drivers/media/video/mxc/capture/ipu_prp_vf_sdc_bg.c63
-rw-r--r--drivers/media/video/mxc/capture/ov3640.c3
-rw-r--r--drivers/media/video/mxc/capture/ov5640.c3
-rw-r--r--drivers/media/video/mxc/capture/ov5640_mipi.c874
-rw-r--r--drivers/media/video/mxc/capture/ov5642.c3
-rw-r--r--drivers/media/video/mxc/capture/ov8820_mipi.c1037
-rw-r--r--drivers/media/video/mxc/output/mxc_vout.c152
-rw-r--r--drivers/misc/Kconfig2
-rw-r--r--drivers/misc/mxs-perfmon.c27
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c4
-rw-r--r--drivers/mmc/host/sdhci.c2
-rw-r--r--drivers/mxc/gpu-viv/Kbuild9
-rw-r--r--drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c2
-rw-r--r--drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c44
-rw-r--r--drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c98
-rw-r--r--drivers/mxc/gpu-viv/config3
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c188
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c7
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c69
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c5
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h6
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h23
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h1
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h8
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h39
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h16
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h51
-rw-r--r--drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h4
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h2
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c7
-rw-r--r--drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c14
-rw-r--r--drivers/mxc/ipu3/ipu_calc_stripes_sizes.c11
-rw-r--r--drivers/mxc/ipu3/ipu_common.c31
-rw-r--r--drivers/mxc/mipi/mxc_mipi_csi2.c176
-rw-r--r--drivers/mxc/mipi/mxc_mipi_csi2.h13
-rw-r--r--drivers/net/fec.c12
-rw-r--r--drivers/tty/serial/imx.c347
-rw-r--r--drivers/usb/gadget/arcotg_udc.c119
-rw-r--r--drivers/usb/gadget/arcotg_udc.h6
-rw-r--r--drivers/usb/gadget/file_storage.c19
-rw-r--r--drivers/usb/otg/fsl_otg.c18
-rw-r--r--drivers/usb/otg/fsl_otg.h2
-rw-r--r--drivers/video/backlight/pwm_bl.c5
-rw-r--r--drivers/video/mxc/mxc_ipuv3_fb.c38
-rw-r--r--drivers/video/mxc_hdmi.c69
-rw-r--r--firmware/imx/sdma/sdma-imx6q-to1.bin.ihex197
-rw-r--r--fs/fs-writeback.c2
-rw-r--r--include/linux/fsl_devices.h4
-rw-r--r--sound/soc/imx/Kconfig2
80 files changed, 5481 insertions, 755 deletions
diff --git a/arch/arm/configs/imx6_android_defconfig b/arch/arm/configs/imx6_android_defconfig
index 8d353c494ddb..e2e8c5489b4d 100644
--- a/arch/arm/configs/imx6_android_defconfig
+++ b/arch/arm/configs/imx6_android_defconfig
@@ -1680,7 +1680,6 @@ CONFIG_VIDEO_MXC_IPU_CAMERA=y
# CONFIG_MXC_CAMERA_OV3640 is not set
CONFIG_MXC_CAMERA_OV5642=y
# CONFIG_MXC_CAMERA_OV5640_MIPI is not set
-# CONFIG_MXC_CAMERA_OV5642 is not set
CONFIG_MXC_IPU_PRP_VF_SDC=y
CONFIG_MXC_IPU_PRP_ENC=y
CONFIG_MXC_IPU_CSI_ENC=y
diff --git a/arch/arm/configs/imx6_defconfig b/arch/arm/configs/imx6_defconfig
index 06ee86f5e0b7..0f2c0e802856 100644
--- a/arch/arm/configs/imx6_defconfig
+++ b/arch/arm/configs/imx6_defconfig
@@ -304,6 +304,7 @@ CONFIG_ARCH_MX6Q=y
CONFIG_SOC_IMX6Q=y
CONFIG_MACH_MX6Q_ARM2=y
CONFIG_MACH_MX6Q_SABRELITE=y
+CONFIG_MACH_MX6Q_SABREAUTO=y
#
# MX6 Options:
@@ -768,7 +769,8 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_MG_DISK is not set
# CONFIG_BLK_DEV_RBD is not set
-# CONFIG_MISC_DEVICES is not set
+CONFIG_MISC_DEVICES=y
+CONFIG_MXS_PERFMON=m
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -815,7 +817,7 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_DH is not set
# CONFIG_SCSI_OSD_INITIATOR is not set
-CONFIG_ATA=m
+CONFIG_ATA=y
# CONFIG_ATA_NONSTANDARD is not set
CONFIG_ATA_VERBOSE_ERROR=y
# CONFIG_SATA_PMP is not set
@@ -823,7 +825,7 @@ CONFIG_ATA_VERBOSE_ERROR=y
#
# Controllers with non-SFF native interface
#
-CONFIG_SATA_AHCI_PLATFORM=m
+CONFIG_SATA_AHCI_PLATFORM=y
CONFIG_ATA_SFF=y
#
diff --git a/arch/arm/configs/imx6_updater_defconfig b/arch/arm/configs/imx6_updater_defconfig
index f9ab9462dacc..d8d9eae1b8b9 100644
--- a/arch/arm/configs/imx6_updater_defconfig
+++ b/arch/arm/configs/imx6_updater_defconfig
@@ -310,6 +310,7 @@ CONFIG_ARCH_MX6Q=y
CONFIG_SOC_IMX6Q=y
CONFIG_MACH_MX6Q_ARM2=y
CONFIG_MACH_MX6Q_SABRELITE=y
+CONFIG_MACH_MX6Q_SABREAUTO=y
#
# MX6 Options:
diff --git a/arch/arm/mach-mx6/Kconfig b/arch/arm/mach-mx6/Kconfig
index 6a1a99dd7d17..e28be210c654 100644
--- a/arch/arm/mach-mx6/Kconfig
+++ b/arch/arm/mach-mx6/Kconfig
@@ -54,6 +54,7 @@ config MACH_MX6Q_ARM2
select IMX_HAVE_PLATFORM_IMX_MIPI_DSI
select IMX_HAVE_PLATFORM_FLEXCAN
select IMX_HAVE_PLATFORM_IMX_MIPI_CSI2
+ select IMX_HAVE_PLATFORM_PERFMON
help
Include support for i.MX 6Quad Armadillo2 platform. This includes specific
configurations for the board and its peripherals.
@@ -85,10 +86,47 @@ config MACH_MX6Q_SABRELITE
select IMX_HAVE_PLATFORM_IMX_PM
select IMX_HAVE_PLATFORM_MXC_HDMI
select IMX_HAVE_PLATFORM_IMX_ASRC
+ select IMX_HAVE_PLATFORM_FLEXCAN
help
Include support for i.MX 6Quad SABRE Lite platform. This includes specific
configurations for the board and its peripherals.
+config MACH_MX6Q_SABREAUTO
+ bool "Support i.MX 6Quad SABRE Auto platform"
+ select ARCH_MX6Q
+ select SOC_IMX6Q
+ select IMX_HAVE_PLATFORM_IMX_UART
+ select IMX_HAVE_PLATFORM_DMA
+ select IMX_HAVE_PLATFORM_FEC
+ select IMX_HAVE_PLATFORM_GPMI_NFC
+ select IMX_HAVE_PLATFORM_SDHCI_ESDHC_IMX
+ select IMX_HAVE_PLATFORM_SPI_IMX
+ select IMX_HAVE_PLATFORM_IMX_I2C
+ select IMX_HAVE_PLATFORM_VIV_GPU
+ select IMX_HAVE_PLATFORM_IMX_VPU
+ select IMX_HAVE_PLATFORM_IMX_DVFS
+ select IMX_HAVE_PLATFORM_IMX_ESAI
+ select IMX_HAVE_PLATFORM_IMX_ANATOP_THERMAL
+ select IMX_HAVE_PLATFORM_FSL_USB2_UDC
+ select IMX_HAVE_PLATFORM_MXC_EHCI
+ select IMX_HAVE_PLATFORM_FSL_OTG
+ select IMX_HAVE_PLATFORM_FSL_USB_WAKEUP
+ select IMX_HAVE_PLATFORM_AHCI
+ select IMX_HAVE_PLATFORM_IMX_OCOTP
+ select IMX_HAVE_PLATFORM_IMX_VIIM
+ select IMX_HAVE_PLATFORM_IMX2_WDT
+ select IMX_HAVE_PLATFORM_IMX_SNVS_RTC
+ select IMX_HAVE_PLATFORM_IMX_PM
+ select IMX_HAVE_PLATFORM_MXC_HDMI
+ select IMX_HAVE_PLATFORM_IMX_ASRC
+ select IMX_HAVE_PLATFORM_IMX_SPDIF
+ select IMX_HAVE_PLATFORM_IMX_MIPI_DSI
+ select IMX_HAVE_PLATFORM_FLEXCAN
+ select IMX_HAVE_PLATFORM_IMX_MIPI_CSI2
+ help
+ Include support for i.MX 6Quad SABRE Auto platform. This includes specific
+ configurations for the board and its peripherals.
+
comment "MX6 Options:"
endif
diff --git a/arch/arm/mach-mx6/Makefile b/arch/arm/mach-mx6/Makefile
index d0fe1f4e3410..bd55b5ba9c3f 100644
--- a/arch/arm/mach-mx6/Makefile
+++ b/arch/arm/mach-mx6/Makefile
@@ -8,5 +8,6 @@ obj-y := cpu.o mm.o system.o devices.o dummy_gpio.o irq.o bus_freq.o usb_dr.o
obj-$(CONFIG_ARCH_MX6) += clock.o mx6q_suspend.o
obj-$(CONFIG_MACH_MX6Q_ARM2) += board-mx6q_arm2.o
obj-$(CONFIG_MACH_MX6Q_SABRELITE) += board-mx6q_sabrelite.o
+obj-$(CONFIG_MACH_MX6Q_SABREAUTO) += board-mx6q_sabreauto.o
obj-$(CONFIG_SMP) += plat_hotplug.o platsmp.o headsmp.o
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.c b/arch/arm/mach-mx6/board-mx6q_arm2.c
index 2b93fb95dd15..218a202bd75f 100644
--- a/arch/arm/mach-mx6/board-mx6q_arm2.c
+++ b/arch/arm/mach-mx6/board-mx6q_arm2.c
@@ -106,11 +106,13 @@
#define MX6Q_SMD_CSI0_RST IMX_GPIO_NR(4, 5)
#define MX6Q_SMD_CSI0_PWN IMX_GPIO_NR(5, 23)
+#define BMCR_PDOWN 0x0800 /* PHY Powerdown */
+
void __init early_console_setup(unsigned long base, struct clk *clk);
static struct clk *sata_clk;
static int esai_record;
static int spdif_en;
-static int mipi_sensor;
+static int flexcan_en;
extern struct regulator *(*get_cpu_regulator)(void);
extern void (*put_cpu_regulator)(void);
@@ -256,23 +258,6 @@ static iomux_v3_cfg_t mx6q_arm2_pads[] = {
MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
- /* ipu1 csi0 */
- MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
- MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
- MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
- MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
- MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
- MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
- MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
- MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
- MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
- MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
- MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
- /* camera reset */
- MX6Q_PAD_GPIO_19__GPIO_4_5,
- /* camera powerdown */
- MX6Q_PAD_CSI0_DAT5__GPIO_5_23,
-
MX6Q_PAD_EIM_D24__GPIO_3_24,
/* UART2 */
@@ -329,6 +314,26 @@ static iomux_v3_cfg_t mx6q_arm2_esai_record_pads[] = {
MX6Q_PAD_ENET_REF_CLK__ESAI1_FSR,
};
+static iomux_v3_cfg_t mx6q_arm2_csi0_sensor_pads[] = {
+ MX6Q_PAD_GPIO_0__CCM_CLKO,
+ /* ipu1 csi0 */
+ MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
+ MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
+ MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
+ MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
+ MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
+ MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
+ MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
+ MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
+ MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+ MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
+ MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
+ /* camera reset */
+ MX6Q_PAD_GPIO_19__GPIO_4_5,
+ /* camera powerdown */
+ MX6Q_PAD_CSI0_DAT5__GPIO_5_23,
+};
+
static iomux_v3_cfg_t mx6q_arm2_mipi_sensor_pads[] = {
MX6Q_PAD_CSI0_MCLK__CCM_CLKO,
};
@@ -421,6 +426,7 @@ static const struct esdhc_platform_data mx6q_arm2_sd3_data __initconst = {
.wp_gpio = MX6Q_ARM2_SD3_WP,
.support_18v = 1,
.support_8bit = 1,
+ .keep_power_at_suspend = 1,
.delay_line = 0,
.platform_pad_change = plt_sd3_pad_change,
};
@@ -429,6 +435,7 @@ static const struct esdhc_platform_data mx6q_arm2_sd3_data __initconst = {
static const struct esdhc_platform_data mx6q_arm2_sd4_data __initconst = {
.always_present = 1,
.support_8bit = 1,
+ .keep_power_at_suspend = 1,
.platform_pad_change = plt_sd4_pad_change,
};
@@ -475,14 +482,15 @@ static const struct anatop_thermal_platform_data
};
static const struct imxuart_platform_data mx6q_uart1_data __initconst = {
- .flags = IMXUART_HAVE_RTSCTS | IMXUART_USE_DCEDTE,
+ .flags = IMXUART_HAVE_RTSCTS | IMXUART_USE_DCEDTE | IMXUART_SDMA,
+ .dma_req_rx = MX6Q_DMA_REQ_UART2_RX,
+ .dma_req_tx = MX6Q_DMA_REQ_UART2_TX,
};
static inline void mx6q_arm2_init_uart(void)
{
imx6q_add_imx_uart(0, NULL);
imx6q_add_imx_uart(1, &mx6q_uart1_data);
- imx6q_add_imx_uart(3, NULL);
}
static int mx6q_arm2_fec_phy_init(struct phy_device *phydev)
@@ -505,6 +513,10 @@ static int mx6q_arm2_fec_phy_init(struct phy_device *phydev)
val |= 0x0100;
phy_write(phydev, 0x1e, val);
+ /*check phy power*/
+ val = phy_read(phydev, 0x0);
+ if (val & BMCR_PDOWN)
+ phy_write(phydev, 0x0, (val & ~BMCR_PDOWN));
return 0;
}
@@ -659,19 +671,58 @@ static struct fsl_mxc_dvi_platform_data sabr_ddc_dvi_data = {
.update = ddc_dvi_update,
};
+static void mx6q_csi0_io_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_csi0_sensor_pads,
+ ARRAY_SIZE(mx6q_arm2_csi0_sensor_pads));
+
+ /* Camera reset */
+ gpio_request(MX6Q_SMD_CSI0_RST, "cam-reset");
+ gpio_direction_output(MX6Q_SMD_CSI0_RST, 1);
+
+ /* Camera power down */
+ gpio_request(MX6Q_SMD_CSI0_PWN, "cam-pwdn");
+ gpio_direction_output(MX6Q_SMD_CSI0_PWN, 1);
+ msleep(1);
+ gpio_set_value(MX6Q_SMD_CSI0_PWN, 0);
+
+ /* For MX6Q GPR1 bit19 and bit20 meaning:
+ * Bit19: 0 - Enable mipi to IPU1 CSI0
+ * virtual channel is fixed to 0
+ * 1 - Enable parallel interface to IPU1 CSI0
+ * Bit20: 0 - Enable mipi to IPU2 CSI1
+ * virtual channel is fixed to 3
+ * 1 - Enable parallel interface to IPU2 CSI1
+ * IPU1 CSI1 directly connect to mipi csi2,
+ * virtual channel is fixed to 1
+ * IPU2 CSI0 directly connect to mipi csi2,
+ * virtual channel is fixed to 2
+ */
+ mxc_iomux_set_gpr_register(1, 19, 1, 1);
+}
+
static struct fsl_mxc_camera_platform_data camera_data = {
.analog_regulator = "DA9052_LDO7",
.core_regulator = "DA9052_LDO9",
.mclk = 24000000,
.csi = 0,
+ .io_init = mx6q_csi0_io_init,
};
+static void mx6q_mipi_sensor_io_init(void)
+{
+ mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_mipi_sensor_pads,
+ ARRAY_SIZE(mx6q_arm2_mipi_sensor_pads));
+
+ mxc_iomux_set_gpr_register(1, 19, 1, 0);
+}
+
static struct fsl_mxc_camera_platform_data ov5640_mipi_data = {
.mclk = 24000000,
.csi = 0,
+ .io_init = mx6q_mipi_sensor_io_init,
};
-
static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
{
I2C_BOARD_INFO("cs42888", 0x48),
@@ -768,7 +819,7 @@ static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = {
static int mx6q_arm2_sata_init(struct device *dev, void __iomem *addr)
{
u32 tmpdata;
- int ret = 0;
+ int ret = 0, iterations = 20;
struct clk *clk;
/* Enable SATA PWR CTRL_0 of MAX7310 */
@@ -819,12 +870,29 @@ static int mx6q_arm2_sata_init(struct device *dev, void __iomem *addr)
sata_init(addr, tmpdata);
+ /* Release resources when there is no device on the port */
+ do {
+ if ((readl(addr + PORT_SATA_SR) & 0xF) == 0)
+ msleep(25);
+ else
+ break;
+
+ if (iterations == 0) {
+ dev_info(dev, "NO sata disk.\n");
+ ret = -ENODEV;
+ goto release_sata_clk;
+ }
+ } while (iterations-- > 0);
+
return ret;
release_sata_clk:
clk_disable(sata_clk);
put_sata_clk:
clk_put(sata_clk);
+ /* Disable SATA PWR CTRL_0 of MAX7310 */
+ gpio_request(MX6Q_ARM2_MAX7310_1_BASE_ADDR, "SATA_PWR_EN");
+ gpio_direction_output(MX6Q_ARM2_MAX7310_1_BASE_ADDR, 0);
return ret;
}
@@ -1352,34 +1420,21 @@ static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
set_cpu_voltage = mx6_arm2_set_cpu_voltage;
}
-static int __init early_enable_mipi_sensor(char *p)
+static int __init early_enable_spdif(char *p)
{
- mipi_sensor = 1;
+ spdif_en = 1;
return 0;
}
-early_param("mipi_sensor", early_enable_mipi_sensor);
-static inline void __init mx6q_csi0_io_init(void)
-{
- /* Camera reset */
- gpio_request(MX6Q_SMD_CSI0_RST, "cam-reset");
- gpio_direction_output(MX6Q_SMD_CSI0_RST, 1);
-
- /* Camera power down */
- gpio_request(MX6Q_SMD_CSI0_PWN, "cam-pwdn");
- gpio_direction_output(MX6Q_SMD_CSI0_PWN, 1);
- msleep(1);
- gpio_set_value(MX6Q_SMD_CSI0_PWN, 0);
- mxc_iomux_set_gpr_register(1, 19, 1, 1);
-}
+early_param("spdif", early_enable_spdif);
-static int __init early_enable_spdif(char *p)
+static int __init early_enable_can(char *p)
{
- spdif_en = 1;
+ flexcan_en = 1;
return 0;
}
-early_param("spdif", early_enable_spdif);
+early_param("flexcan", early_enable_can);
static int spdif_clk_set_rate(struct clk *clk, unsigned long rate)
{
@@ -1436,14 +1491,11 @@ static void __init mx6_board_init(void)
} else {
mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_i2c3_pads,
ARRAY_SIZE(mx6q_arm2_i2c3_pads));
- mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_can_pads,
- ARRAY_SIZE(mx6q_arm2_can_pads));
+ if (flexcan_en)
+ mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_can_pads,
+ ARRAY_SIZE(mx6q_arm2_can_pads));
}
- if (mipi_sensor)
- mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_mipi_sensor_pads,
- ARRAY_SIZE(mx6q_arm2_mipi_sensor_pads));
-
gp_reg_id = arm2_dvfscore_data.reg_id;
mx6q_arm2_init_uart();
imx6q_add_mipi_csi2(&mipi_csi2_pdata);
@@ -1499,9 +1551,6 @@ static void __init mx6_board_init(void)
imx_asrc_data.asrc_audio_clk = clk_get(NULL, "asrc_serial_clk");
imx6q_add_asrc(&imx_asrc_data);
- if (!mipi_sensor)
- mx6q_csi0_io_init();
-
/* DISP0 Detect */
/* gpio_request(MX6Q_ARM2_DISP0_DET_INT, "disp0-detect"); */
/* gpio_direction_input(MX6Q_ARM2_DISP0_DET_INT); */
@@ -1541,7 +1590,7 @@ static void __init mx6_board_init(void)
imx6q_add_spdif(&mxc_spdif_data);
imx6q_add_spdif_dai();
imx6q_add_spdif_audio_device();
- } else {
+ } else if (flexcan_en) {
ret = gpio_request_array(mx6q_flexcan_gpios,
ARRAY_SIZE(mx6q_flexcan_gpios));
if (ret) {
@@ -1554,6 +1603,9 @@ static void __init mx6_board_init(void)
imx6q_add_hdmi_soc();
imx6q_add_hdmi_soc_dai();
+ imx6q_add_perfmon(0);
+ imx6q_add_perfmon(1);
+ imx6q_add_perfmon(2);
}
extern void __iomem *twd_base;
diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.c b/arch/arm/mach-mx6/board-mx6q_sabreauto.c
new file mode 100644
index 000000000000..063b8276605f
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.c
@@ -0,0 +1,1560 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/smsc911x.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/flash.h>
+#include <linux/i2c.h>
+#include <linux/i2c/pca953x.h>
+#include <linux/ata.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/regulator/consumer.h>
+#include <linux/pmic_external.h>
+#include <linux/pmic_status.h>
+#include <linux/ipu.h>
+#include <linux/mxcfb.h>
+#include <linux/pwm_backlight.h>
+#include <linux/fec.h>
+#include <linux/memblock.h>
+#include <linux/gpio.h>
+#include <linux/etherdevice.h>
+#include <linux/regulator/anatop-regulator.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/fixed.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/mxc_dvfs.h>
+#include <mach/memory.h>
+#include <mach/iomux-mx6q.h>
+#include <mach/imx-uart.h>
+#include <mach/viv_gpu.h>
+#include <mach/ahci_sata.h>
+#include <mach/ipu-v3.h>
+#include <mach/mxc_hdmi.h>
+#include <mach/mxc_asrc.h>
+#include <mach/mipi_dsi.h>
+#include <mach/mipi_csi2.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "usb.h"
+#include "devices-imx6q.h"
+#include "crm_regs.h"
+#include "cpu_op-mx6.h"
+
+#define MX6Q_SABREAUTO_LDB_BACKLIGHT IMX_GPIO_NR(1, 9)
+#define MX6Q_SABREAUTO_ECSPI1_CS0 IMX_GPIO_NR(2, 30)
+#define MX6Q_SABREAUTO_ECSPI1_CS1 IMX_GPIO_NR(3, 19)
+#define MX6Q_SABREAUTO_DISP0_PWR IMX_GPIO_NR(3, 24)
+#define MX6Q_SABREAUTO_DISP0_I2C_EN IMX_GPIO_NR(3, 28)
+#define MX6Q_SABREAUTO_DISP0_DET_INT IMX_GPIO_NR(3, 31)
+#define MX6Q_SABREAUTO_DISP0_RESET IMX_GPIO_NR(5, 0)
+#define MX6Q_SABREAUTO_SD3_CD IMX_GPIO_NR(6, 15)
+#define MX6Q_SABREAUTO_SD3_WP IMX_GPIO_NR(1, 13)
+#define MX6Q_SABREAUTO_USB_OTG_PWR IMX_GPIO_NR(3, 22)
+#define MX6Q_SABREAUTO_MAX7310_1_BASE_ADDR IMX_GPIO_NR(8, 0)
+#define MX6Q_SABREAUTO_MAX7310_2_BASE_ADDR IMX_GPIO_NR(8, 8)
+#define MX6Q_SABREAUTO_CAP_TCH_INT IMX_GPIO_NR(3, 31)
+
+#define MX6Q_SABREAUTO_IO_EXP_GPIO1(x) \
+ (MX6Q_SABREAUTO_MAX7310_1_BASE_ADDR + (x))
+#define MX6Q_SABREAUTO_IO_EXP_GPIO2(x) \
+ (MX6Q_SABREAUTO_MAX7310_2_BASE_ADDR + (x))
+
+#define MX6Q_SABREAUTO_CAN1_STBY IMX_GPIO_NR(7, 12)
+#define MX6Q_SABREAUTO_CAN1_EN IMX_GPIO_NR(7, 13)
+#define MX6Q_SABREAUTO_CAN2_STBY MX6Q_SABREAUTO_IO_EXP_GPIO2(1)
+#define MX6Q_SABREAUTO_CAN2_EN IMX_GPIO_NR(5, 24)
+
+#define MX6Q_SMD_CSI0_RST IMX_GPIO_NR(4, 5)
+#define MX6Q_SMD_CSI0_PWN IMX_GPIO_NR(5, 23)
+
+void __init early_console_setup(unsigned long base, struct clk *clk);
+static struct clk *sata_clk;
+static int esai_record;
+static int spdif_en;
+static int mipi_sensor;
+
+extern struct regulator *(*get_cpu_regulator)(void);
+extern void (*put_cpu_regulator)(void);
+extern int (*set_cpu_voltage)(u32 volt);
+extern int mx6_set_cpu_voltage(u32 cpu_volt);
+static struct regulator *cpu_regulator;
+static char *gp_reg_id;
+
+static iomux_v3_cfg_t mx6q_sabreauto_pads[] = {
+
+ /* UART4 for debug */
+ MX6Q_PAD_KEY_COL0__UART4_TXD,
+ MX6Q_PAD_KEY_ROW0__UART4_RXD,
+ /* USB HSIC ports use the same pin with ENET */
+#ifdef CONFIG_USB_EHCI_ARC_HSIC
+ /* USB H2 strobe/data pin */
+ MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE,
+ MX6Q_PAD_RGMII_TXC__USBOH3_H2_DATA,
+
+ /* USB H3 strobe/data pin */
+ MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE,
+ MX6Q_PAD_RGMII_RX_CTL__USBOH3_H3_DATA,
+ /* ENET */
+#else
+ MX6Q_PAD_KEY_COL1__ENET_MDIO,
+ MX6Q_PAD_KEY_COL2__ENET_MDC,
+ MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC,
+ MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0,
+ MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1,
+ MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2,
+ MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3,
+ MX6Q_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL,
+ MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK,
+ MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC,
+ MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0,
+ MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1,
+ MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2,
+ MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3,
+ MX6Q_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL,
+#endif
+ /* MCLK for csi0 */
+ MX6Q_PAD_GPIO_0__CCM_CLKO,
+ MX6Q_PAD_GPIO_3__CCM_CLKO2,
+
+ /* SD1 */
+ MX6Q_PAD_SD1_CLK__USDHC1_CLK,
+ MX6Q_PAD_SD1_CMD__USDHC1_CMD,
+ MX6Q_PAD_SD1_DAT0__USDHC1_DAT0,
+ MX6Q_PAD_SD1_DAT1__USDHC1_DAT1,
+ MX6Q_PAD_SD1_DAT2__USDHC1_DAT2,
+ MX6Q_PAD_SD1_DAT3__USDHC1_DAT3,
+ /* SD2 */
+ MX6Q_PAD_SD2_CLK__USDHC2_CLK,
+ MX6Q_PAD_SD2_CMD__USDHC2_CMD,
+ MX6Q_PAD_SD2_DAT0__USDHC2_DAT0,
+ MX6Q_PAD_SD2_DAT1__USDHC2_DAT1,
+ MX6Q_PAD_SD2_DAT2__USDHC2_DAT2,
+ MX6Q_PAD_SD2_DAT3__USDHC2_DAT3,
+ /* SD3 */
+ MX6Q_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6Q_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6Q_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6Q_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6Q_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6Q_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+ MX6Q_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ,
+ MX6Q_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ,
+ MX6Q_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ,
+ MX6Q_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ,
+ /* MX6Q_PAD_SD3_RST__USDHC3_RST, */
+ /* SD3 VSelect */
+ MX6Q_PAD_GPIO_18__USDHC3_VSELECT,
+ /* SD3_CD and SD3_WP */
+ MX6Q_PAD_NANDF_CS2__GPIO_6_15,
+ MX6Q_PAD_SD2_DAT2__GPIO_1_13,
+ /* SD4 */
+ MX6Q_PAD_SD4_CLK__USDHC4_CLK_50MHZ,
+ MX6Q_PAD_SD4_CMD__USDHC4_CMD_50MHZ,
+ MX6Q_PAD_SD4_DAT0__USDHC4_DAT0_50MHZ,
+ MX6Q_PAD_SD4_DAT1__USDHC4_DAT1_50MHZ,
+ MX6Q_PAD_SD4_DAT2__USDHC4_DAT2_50MHZ,
+ MX6Q_PAD_SD4_DAT3__USDHC4_DAT3_50MHZ,
+ MX6Q_PAD_SD4_DAT4__USDHC4_DAT4_50MHZ,
+ MX6Q_PAD_SD4_DAT5__USDHC4_DAT5_50MHZ,
+ MX6Q_PAD_SD4_DAT6__USDHC4_DAT6_50MHZ,
+ MX6Q_PAD_SD4_DAT7__USDHC4_DAT7_50MHZ,
+ MX6Q_PAD_NANDF_ALE__USDHC4_RST,
+ /* eCSPI1 */
+ MX6Q_PAD_EIM_EB2__ECSPI1_SS0,
+ MX6Q_PAD_EIM_D16__ECSPI1_SCLK,
+ MX6Q_PAD_EIM_D17__ECSPI1_MISO,
+ MX6Q_PAD_EIM_D18__ECSPI1_MOSI,
+ MX6Q_PAD_EIM_D19__ECSPI1_SS1,
+ MX6Q_PAD_EIM_EB2__GPIO_2_30, /*SS0*/
+ MX6Q_PAD_EIM_D19__GPIO_3_19, /*SS1*/
+
+ /* ESAI */
+ MX6Q_PAD_ENET_RXD0__ESAI1_HCKT,
+ MX6Q_PAD_ENET_CRS_DV__ESAI1_SCKT,
+ MX6Q_PAD_ENET_RXD1__ESAI1_FST,
+ MX6Q_PAD_ENET_TX_EN__ESAI1_TX3_RX2,
+ MX6Q_PAD_ENET_TXD1__ESAI1_TX2_RX3,
+ MX6Q_PAD_ENET_TXD0__ESAI1_TX4_RX1,
+ MX6Q_PAD_ENET_MDC__ESAI1_TX5_RX0,
+ MX6Q_PAD_NANDF_CS2__ESAI1_TX0,
+ MX6Q_PAD_NANDF_CS3__ESAI1_TX1,
+
+ /* I2C1 */
+ MX6Q_PAD_CSI0_DAT8__I2C1_SDA,
+ MX6Q_PAD_CSI0_DAT9__I2C1_SCL,
+
+ /* I2C2 */
+ MX6Q_PAD_KEY_COL3__I2C2_SCL,
+ MX6Q_PAD_KEY_ROW3__I2C2_SDA,
+
+ /* DISPLAY */
+ MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+ MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15,
+ MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2,
+ MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3,
+ MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
+ MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
+ MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
+ MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
+ MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
+ MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
+ MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
+ MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
+ MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
+ MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
+ MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
+ MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
+ MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
+ MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
+ MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
+ MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
+ MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
+ MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
+ MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
+ MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
+ MX6Q_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20,
+ MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
+ MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
+ MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
+
+ /* ipu1 csi0 */
+ MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
+ MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
+ MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
+ MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
+ MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
+ MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
+ MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
+ MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
+ MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+ MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
+ MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
+ /* camera reset */
+ MX6Q_PAD_GPIO_19__GPIO_4_5,
+ /* camera powerdown */
+ MX6Q_PAD_CSI0_DAT5__GPIO_5_23,
+
+ MX6Q_PAD_EIM_D24__GPIO_3_24,
+
+ /* PWM1 */
+ MX6Q_PAD_GPIO_9__PWM1_PWMO,
+
+ /* DISP0 I2C ENABLE*/
+ MX6Q_PAD_EIM_D28__GPIO_3_28,
+
+ /* DISP0 DET */
+ MX6Q_PAD_EIM_D31__GPIO_3_31,
+
+ /* DISP0 RESET */
+ MX6Q_PAD_EIM_WAIT__GPIO_5_0,
+
+ /* HDMI */
+ MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE,
+ MX6Q_PAD_SD1_DAT1__HDMI_TX_OPHYDTB_0,
+ MX6Q_PAD_SD1_DAT0__HDMI_TX_OPHYDTB_1,
+
+ /* USBOTG ID pin */
+ MX6Q_PAD_GPIO_1__USBOTG_ID,
+};
+
+static iomux_v3_cfg_t mx6q_sabreauto_i2c3_pads[] = {
+ MX6Q_PAD_GPIO_5__I2C3_SCL,
+ MX6Q_PAD_GPIO_16__I2C3_SDA,
+};
+
+static iomux_v3_cfg_t mx6q_sabreauto_spdif_pads[] = {
+ /* SPDIF */
+ MX6Q_PAD_GPIO_16__SPDIF_IN1,
+ MX6Q_PAD_GPIO_17__SPDIF_OUT1,
+};
+
+static iomux_v3_cfg_t mx6q_sabreauto_can_pads[] = {
+ /* CAN1 */
+ MX6Q_PAD_GPIO_7__CAN1_TXCAN,
+ MX6Q_PAD_KEY_ROW2__CAN1_RXCAN,
+ MX6Q_PAD_GPIO_17__GPIO_7_12, /* CAN1 STBY */
+ MX6Q_PAD_GPIO_18__GPIO_7_13, /* CAN1 EN */
+
+ /* CAN2 */
+ MX6Q_PAD_KEY_COL4__CAN2_TXCAN,
+ MX6Q_PAD_KEY_ROW4__CAN2_RXCAN,
+ MX6Q_PAD_CSI0_DAT6__GPIO_5_24, /* CAN2 EN */
+};
+
+static iomux_v3_cfg_t mx6q_sabreauto_esai_record_pads[] = {
+ MX6Q_PAD_ENET_RX_ER__ESAI1_HCKR,
+ MX6Q_PAD_ENET_MDIO__ESAI1_SCKR,
+ MX6Q_PAD_ENET_REF_CLK__ESAI1_FSR,
+};
+
+static iomux_v3_cfg_t mx6q_sabreauto_mipi_sensor_pads[] = {
+ MX6Q_PAD_CSI0_MCLK__CCM_CLKO,
+};
+
+#define MX6Q_USDHC_PAD_SETTING(id, speed) \
+mx6q_sd##id##_##speed##mhz[] = { \
+ MX6Q_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT4__USDHC##id##_DAT4_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT5__USDHC##id##_DAT5_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT6__USDHC##id##_DAT6_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT7__USDHC##id##_DAT7_##speed##MHZ, \
+}
+
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 50);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 100);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 200);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(4, 50);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(4, 100);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(4, 200);
+
+enum sd_pad_mode {
+ SD_PAD_MODE_LOW_SPEED,
+ SD_PAD_MODE_MED_SPEED,
+ SD_PAD_MODE_HIGH_SPEED,
+};
+
+static int plt_sd3_pad_change(int clock)
+{
+ static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
+
+ if (clock > 100000000) {
+ if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
+ return 0;
+
+ pad_mode = SD_PAD_MODE_HIGH_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(mx6q_sd3_200mhz,
+ ARRAY_SIZE(mx6q_sd3_200mhz));
+ } else if (clock > 52000000) {
+ if (pad_mode == SD_PAD_MODE_MED_SPEED)
+ return 0;
+
+ pad_mode = SD_PAD_MODE_MED_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(mx6q_sd3_100mhz,
+ ARRAY_SIZE(mx6q_sd3_100mhz));
+ } else {
+ if (pad_mode == SD_PAD_MODE_LOW_SPEED)
+ return 0;
+
+ pad_mode = SD_PAD_MODE_LOW_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(mx6q_sd3_50mhz,
+ ARRAY_SIZE(mx6q_sd3_50mhz));
+ }
+}
+
+static int plt_sd4_pad_change(int clock)
+{
+ static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
+
+ if (clock > 100000000) {
+ if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
+ return 0;
+
+ pad_mode = SD_PAD_MODE_HIGH_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(mx6q_sd4_200mhz,
+ ARRAY_SIZE(mx6q_sd4_200mhz));
+ } else if (clock > 52000000) {
+ if (pad_mode == SD_PAD_MODE_MED_SPEED)
+ return 0;
+
+ pad_mode = SD_PAD_MODE_MED_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(mx6q_sd4_100mhz,
+ ARRAY_SIZE(mx6q_sd4_100mhz));
+ } else {
+ if (pad_mode == SD_PAD_MODE_LOW_SPEED)
+ return 0;
+
+ pad_mode = SD_PAD_MODE_LOW_SPEED;
+ return mxc_iomux_v3_setup_multiple_pads(mx6q_sd4_50mhz,
+ ARRAY_SIZE(mx6q_sd4_50mhz));
+ }
+}
+
+static const struct esdhc_platform_data mx6q_sabreauto_sd3_data __initconst = {
+ .cd_gpio = MX6Q_SABREAUTO_SD3_CD,
+ .wp_gpio = MX6Q_SABREAUTO_SD3_WP,
+ .support_18v = 1,
+ .support_8bit = 1,
+ .delay_line = 0,
+ .platform_pad_change = plt_sd3_pad_change,
+};
+
+/* No card detect signal for SD4 */
+static const struct esdhc_platform_data mx6q_sabreauto_sd4_data __initconst = {
+ .always_present = 1,
+ .support_8bit = 1,
+ .platform_pad_change = plt_sd4_pad_change,
+};
+
+/* The GPMI is conflicted with SD3, so init this in the driver. */
+static iomux_v3_cfg_t mx6q_gpmi_nand[] __initdata = {
+ MX6Q_PAD_NANDF_CLE__RAWNAND_CLE,
+ MX6Q_PAD_NANDF_ALE__RAWNAND_ALE,
+ MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N,
+ MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N,
+ MX6Q_PAD_NANDF_CS2__RAWNAND_CE2N,
+ MX6Q_PAD_NANDF_CS3__RAWNAND_CE3N,
+ MX6Q_PAD_NANDF_RB0__RAWNAND_READY0,
+ MX6Q_PAD_SD4_DAT0__RAWNAND_DQS,
+ MX6Q_PAD_NANDF_D0__RAWNAND_D0,
+ MX6Q_PAD_NANDF_D1__RAWNAND_D1,
+ MX6Q_PAD_NANDF_D2__RAWNAND_D2,
+ MX6Q_PAD_NANDF_D3__RAWNAND_D3,
+ MX6Q_PAD_NANDF_D4__RAWNAND_D4,
+ MX6Q_PAD_NANDF_D5__RAWNAND_D5,
+ MX6Q_PAD_NANDF_D6__RAWNAND_D6,
+ MX6Q_PAD_NANDF_D7__RAWNAND_D7,
+ MX6Q_PAD_SD4_CMD__RAWNAND_RDN,
+ MX6Q_PAD_SD4_CLK__RAWNAND_WRN,
+ MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN,
+};
+
+static int gpmi_nfc_platform_init(void)
+{
+ return mxc_iomux_v3_setup_multiple_pads(mx6q_gpmi_nand,
+ ARRAY_SIZE(mx6q_gpmi_nand));
+}
+
+static const struct gpmi_nfc_platform_data
+mx6q_gpmi_nfc_platform_data __initconst = {
+ .platform_init = gpmi_nfc_platform_init,
+ .min_prop_delay_in_ns = 5,
+ .max_prop_delay_in_ns = 9,
+ .max_chip_count = 1,
+};
+
+static const struct anatop_thermal_platform_data
+ mx6q_sabreauto_anatop_thermal_data __initconst = {
+ .name = "anatop_thermal",
+};
+
+static inline void mx6q_sabreauto_init_uart(void)
+{
+ imx6q_add_imx_uart(0, NULL);
+ imx6q_add_imx_uart(1, NULL);
+ imx6q_add_imx_uart(3, NULL);
+}
+
+static int mx6q_sabreauto_fec_phy_init(struct phy_device *phydev)
+{
+ unsigned short val;
+
+ /* To enable AR8031 ouput a 125MHz clk from CLK_25M */
+ phy_write(phydev, 0xd, 0x7);
+ phy_write(phydev, 0xe, 0x8016);
+ phy_write(phydev, 0xd, 0x4007);
+ val = phy_read(phydev, 0xe);
+
+ val &= 0xffe3;
+ val |= 0x18;
+ phy_write(phydev, 0xe, val);
+
+ /* introduce tx clock delay */
+ phy_write(phydev, 0x1d, 0x5);
+ val = phy_read(phydev, 0x1e);
+ val |= 0x0100;
+ phy_write(phydev, 0x1e, val);
+
+ return 0;
+}
+
+static int mx6q_sabreauto_fec_power_hibernate(struct phy_device *phydev)
+{
+ unsigned short val;
+
+ /*set AR8031 debug reg 0xb to hibernate power*/
+ phy_write(phydev, 0x1d, 0xb);
+ val = phy_read(phydev, 0x1e);
+
+ val |= 0x8000;
+ phy_write(phydev, 0x1e, val);
+
+ return 0;
+}
+
+static struct fec_platform_data fec_data __initdata = {
+ .init = mx6q_sabreauto_fec_phy_init,
+ .power_hibernate = mx6q_sabreauto_fec_power_hibernate,
+ .phy = PHY_INTERFACE_MODE_RGMII,
+};
+
+static int mx6q_sabreauto_spi_cs[] = {
+ MX6Q_SABREAUTO_ECSPI1_CS0,
+ MX6Q_SABREAUTO_ECSPI1_CS1,
+};
+
+static const struct spi_imx_master mx6q_sabreauto_spi_data __initconst = {
+ .chipselect = mx6q_sabreauto_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx6q_sabreauto_spi_cs),
+};
+
+#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
+static struct mtd_partition m25p32_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x00040000,
+ },
+ {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+static struct flash_platform_data m25p32_spi_flash_data = {
+ .name = "m25p32",
+ .parts = m25p32_partitions,
+ .nr_parts = ARRAY_SIZE(m25p32_partitions),
+ .type = "m25p32",
+};
+#endif
+
+static struct spi_board_info m25p32_spi0_board_info[] __initdata = {
+#if defined(CONFIG_MTD_M25P80)
+ {
+ /* The modalias must be the same as spi device driver name */
+ .modalias = "m25p80",
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .platform_data = &m25p32_spi_flash_data,
+ },
+#endif
+};
+
+static void spi_device_init(void)
+{
+ spi_register_board_info(m25p32_spi0_board_info,
+ ARRAY_SIZE(m25p32_spi0_board_info));
+}
+
+static int max7310_1_setup(struct i2c_client *client,
+ unsigned gpio_base, unsigned ngpio,
+ void *context)
+{
+ int max7310_gpio_value[] = {
+ 0, 1, 0, 1, 0, 0, 0, 0,
+ };
+
+ int n;
+
+ for (n = 0; n < ARRAY_SIZE(max7310_gpio_value); ++n) {
+ gpio_request(gpio_base + n, "MAX7310 1 GPIO Expander");
+ if (max7310_gpio_value[n] < 0)
+ gpio_direction_input(gpio_base + n);
+ else
+ gpio_direction_output(gpio_base + n,
+ max7310_gpio_value[n]);
+ gpio_export(gpio_base + n, 0);
+ }
+
+ return 0;
+}
+
+static struct pca953x_platform_data max7310_platdata = {
+ .gpio_base = MX6Q_SABREAUTO_MAX7310_1_BASE_ADDR,
+ .invert = 0,
+ .setup = max7310_1_setup,
+};
+
+static int max7310_u48_setup(struct i2c_client *client,
+ unsigned gpio_base, unsigned ngpio,
+ void *context)
+{
+ int max7310_gpio_value[] = {
+ 1, 1, 1, 1, 0, 0, 0, 0,
+ };
+
+ int n;
+
+ for (n = 0; n < ARRAY_SIZE(max7310_gpio_value); ++n) {
+ gpio_request(gpio_base + n, "MAX7310 U48 GPIO Expander");
+ if (max7310_gpio_value[n] < 0)
+ gpio_direction_input(gpio_base + n);
+ else
+ gpio_direction_output(gpio_base + n,
+ max7310_gpio_value[n]);
+ gpio_export(gpio_base + n, 0);
+ }
+
+ return 0;
+}
+
+static struct pca953x_platform_data max7310_u48_platdata = {
+ .gpio_base = MX6Q_SABREAUTO_MAX7310_2_BASE_ADDR,
+ .invert = 0,
+ .setup = max7310_u48_setup,
+};
+
+static void ddc_dvi_init(void)
+{
+ /* enable DVI I2C */
+ gpio_set_value(MX6Q_SABREAUTO_DISP0_I2C_EN, 1);
+}
+
+static int ddc_dvi_update(void)
+{
+ /* DVI cable state */
+ if (gpio_get_value(MX6Q_SABREAUTO_DISP0_DET_INT) == 1)
+ return 1;
+ else
+ return 0;
+}
+
+static struct fsl_mxc_dvi_platform_data sabr_ddc_dvi_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .init = ddc_dvi_init,
+ .update = ddc_dvi_update,
+};
+
+static struct fsl_mxc_camera_platform_data camera_data = {
+ .analog_regulator = "DA9052_LDO7",
+ .core_regulator = "DA9052_LDO9",
+ .mclk = 24000000,
+ .csi = 0,
+};
+
+static struct fsl_mxc_camera_platform_data ov5640_mipi_data = {
+ .mclk = 24000000,
+ .csi = 0,
+};
+
+
+static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("cs42888", 0x48),
+ },
+ {
+ I2C_BOARD_INFO("ov3640", 0x3c),
+ .platform_data = (void *)&camera_data,
+ },
+};
+
+static struct imxi2c_platform_data mx6q_sabreauto_i2c_data = {
+ .bitrate = 400000,
+};
+
+static struct imxi2c_platform_data mx6q_sabreauto_i2c0_data = {
+ .bitrate = 100000,
+};
+
+static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("max7310", 0x1F),
+ .platform_data = &max7310_platdata,
+ },
+ {
+ I2C_BOARD_INFO("max7310", 0x1B),
+ .platform_data = &max7310_u48_platdata,
+ },
+ {
+ I2C_BOARD_INFO("mxc_dvi", 0x50),
+ .platform_data = &sabr_ddc_dvi_data,
+ .irq = gpio_to_irq(MX6Q_SABREAUTO_DISP0_DET_INT),
+ },
+ {
+ I2C_BOARD_INFO("egalax_ts", 0x4),
+ .irq = gpio_to_irq(MX6Q_SABREAUTO_CAP_TCH_INT),
+ },
+
+};
+
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("egalax_ts", 0x4),
+ .irq = gpio_to_irq(MX6Q_SABREAUTO_CAP_TCH_INT),
+ },
+ {
+ I2C_BOARD_INFO("mxc_hdmi_i2c", 0x50),
+ },
+ {
+ I2C_BOARD_INFO("ov5640_mipi", 0x3c),
+ .platform_data = (void *)&ov5640_mipi_data,
+ },
+};
+
+static void imx6q_sabreauto_usbotg_vbus(bool on)
+{
+ if (on)
+ gpio_set_value(MX6Q_SABREAUTO_USB_OTG_PWR, 1);
+ else
+ gpio_set_value(MX6Q_SABREAUTO_USB_OTG_PWR, 0);
+}
+
+static void __init imx6q_sabreauto_init_usb(void)
+{
+ int ret = 0;
+
+ imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR);
+ /* disable external charger detect,
+ * or it will affect signal quality at dp.
+ */
+
+ ret = gpio_request(MX6Q_SABREAUTO_USB_OTG_PWR, "usb-pwr");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO MX6Q_SABREAUTO_USB_OTG_PWR:"
+ " %d\n", ret);
+ return;
+ }
+ gpio_direction_output(MX6Q_SABREAUTO_USB_OTG_PWR, 0);
+ mxc_iomux_set_gpr_register(1, 13, 1, 1);
+
+ mx6_set_otghost_vbus_func(imx6q_sabreauto_usbotg_vbus);
+ mx6_usb_dr_init();
+ mx6_usb_h1_init();
+#ifdef CONFIG_USB_EHCI_ARC_HSIC
+ mx6_usb_h2_init();
+ mx6_usb_h3_init();
+#endif
+}
+
+static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = {
+ .reserved_mem_size = SZ_128M,
+};
+
+/* HW Initialization, if return 0, initialization is successful. */
+static int mx6q_sabreauto_sata_init(struct device *dev, void __iomem *addr)
+{
+ u32 tmpdata;
+ int ret = 0;
+ struct clk *clk;
+
+ /* Enable SATA PWR CTRL_0 of MAX7310 */
+ gpio_request(MX6Q_SABREAUTO_MAX7310_1_BASE_ADDR, "SATA_PWR_EN");
+ gpio_direction_output(MX6Q_SABREAUTO_MAX7310_1_BASE_ADDR, 1);
+
+ sata_clk = clk_get(dev, "imx_sata_clk");
+ if (IS_ERR(sata_clk)) {
+ dev_err(dev, "no sata clock.\n");
+ return PTR_ERR(sata_clk);
+ }
+ ret = clk_enable(sata_clk);
+ if (ret) {
+ dev_err(dev, "can't enable sata clock.\n");
+ goto put_sata_clk;
+ }
+
+ /* Set PHY Paremeters, two steps to configure the GPR13,
+ * one write for rest of parameters, mask of first write is 0x07FFFFFD,
+ * and the other one write for setting the mpll_clk_off_b
+ *.rx_eq_val_0(iomuxc_gpr13[26:24]),
+ *.los_lvl(iomuxc_gpr13[23:19]),
+ *.rx_dpll_mode_0(iomuxc_gpr13[18:16]),
+ *.sata_speed(iomuxc_gpr13[15]),
+ *.mpll_ss_en(iomuxc_gpr13[14]),
+ *.tx_atten_0(iomuxc_gpr13[13:11]),
+ *.tx_boost_0(iomuxc_gpr13[10:7]),
+ *.tx_lvl(iomuxc_gpr13[6:2]),
+ *.mpll_ck_off(iomuxc_gpr13[1]),
+ *.tx_edgerate_0(iomuxc_gpr13[0]),
+ */
+ tmpdata = readl(IOMUXC_GPR13);
+ writel(((tmpdata & ~0x07FFFFFD) | 0x0593A044), IOMUXC_GPR13);
+
+ /* enable SATA_PHY PLL */
+ tmpdata = readl(IOMUXC_GPR13);
+ writel(((tmpdata & ~0x2) | 0x2), IOMUXC_GPR13);
+
+ /* Get the AHB clock rate, and configure the TIMER1MS reg later */
+ clk = clk_get(NULL, "ahb");
+ if (IS_ERR(clk)) {
+ dev_err(dev, "no ahb clock.\n");
+ ret = PTR_ERR(clk);
+ goto release_sata_clk;
+ }
+ tmpdata = clk_get_rate(clk) / 1000;
+ clk_put(clk);
+
+ sata_init(addr, tmpdata);
+
+ return ret;
+
+release_sata_clk:
+ clk_disable(sata_clk);
+put_sata_clk:
+ clk_put(sata_clk);
+
+ return ret;
+}
+
+static void mx6q_sabreauto_sata_exit(struct device *dev)
+{
+ clk_disable(sata_clk);
+ clk_put(sata_clk);
+
+ /* Disable SATA PWR CTRL_0 of MAX7310 */
+ gpio_request(MX6Q_SABREAUTO_MAX7310_1_BASE_ADDR, "SATA_PWR_EN");
+ gpio_direction_output(MX6Q_SABREAUTO_MAX7310_1_BASE_ADDR, 0);
+
+}
+
+static struct ahci_platform_data mx6q_sabreauto_sata_data = {
+ .init = mx6q_sabreauto_sata_init,
+ .exit = mx6q_sabreauto_sata_exit,
+};
+
+static struct imx_asrc_platform_data imx_asrc_data = {
+ .channel_bits = 4,
+ .clk_map_ver = 2,
+};
+
+static void mx6q_sabreauto_reset_mipi_dsi(void)
+{
+ gpio_set_value(MX6Q_SABREAUTO_DISP0_PWR, 1);
+ gpio_set_value(MX6Q_SABREAUTO_DISP0_RESET, 1);
+ udelay(10);
+ gpio_set_value(MX6Q_SABREAUTO_DISP0_RESET, 0);
+ udelay(50);
+ gpio_set_value(MX6Q_SABREAUTO_DISP0_RESET, 1);
+
+ /*
+ * it needs to delay 120ms minimum for reset complete
+ */
+ msleep(120);
+}
+
+static struct mipi_dsi_platform_data mipi_dsi_pdata = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .lcd_panel = "TRULY-WVGA",
+ .reset = mx6q_sabreauto_reset_mipi_dsi,
+};
+
+static struct ipuv3_fb_platform_data sabr_fb_data[] = {
+ { /*fb0*/
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB666,
+ .mode_str = "LDB-XGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ }, {
+ .disp_dev = "lcd",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB565,
+ .mode_str = "CLAA-WVGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ }, {
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB666,
+ .mode_str = "LDB-XGA",
+ .default_bpp = 16,
+ .int_clk = false,
+ },
+};
+
+static void hdmi_init(int ipu_id, int disp_id)
+{
+ int hdmi_mux_setting;
+
+ if ((ipu_id > 1) || (ipu_id < 0)) {
+ printk(KERN_ERR"Invalid IPU select for HDMI: %d. Set to 0\n",
+ ipu_id);
+ ipu_id = 0;
+ }
+
+ if ((disp_id > 1) || (disp_id < 0)) {
+ printk(KERN_ERR"Invalid DI select for HDMI: %d. Set to 0\n",
+ disp_id);
+ disp_id = 0;
+ }
+
+ /* Configure the connection between IPU1/2 and HDMI */
+ hdmi_mux_setting = 2*ipu_id + disp_id;
+
+ /* GPR3, bits 2-3 = HDMI_MUX_CTL */
+ mxc_iomux_set_gpr_register(3, 2, 2, hdmi_mux_setting);
+}
+
+static struct fsl_mxc_hdmi_platform_data hdmi_data = {
+ .init = hdmi_init,
+};
+
+static struct fsl_mxc_hdmi_core_platform_data hdmi_core_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+};
+
+static struct fsl_mxc_lcd_platform_data lcdif_data = {
+ .ipu_id = 0,
+ .disp_id = 0,
+ .default_ifmt = IPU_PIX_FMT_RGB565,
+};
+
+static struct fsl_mxc_ldb_platform_data ldb_data = {
+ .ipu_id = 0,
+ .disp_id = 1,
+ .ext_ref = 1,
+ .mode = LDB_SEP0,
+ .sec_ipu_id = 1,
+ .sec_disp_id = 1,
+};
+
+static struct imx_ipuv3_platform_data ipu_data[] = {
+ {
+ .rev = 4,
+ .csi_clk[0] = "ccm_clk0",
+ }, {
+ .rev = 4,
+ .csi_clk[0] = "ccm_clk0",
+ },
+};
+
+static struct platform_pwm_backlight_data mx6_arm2_pwm_backlight_data = {
+ .pwm_id = 0,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
+};
+
+static struct gpio mx6q_flexcan_gpios[] = {
+ { MX6Q_SABREAUTO_CAN1_EN, GPIOF_OUT_INIT_LOW, "flexcan1-en" },
+ { MX6Q_SABREAUTO_CAN1_STBY, GPIOF_OUT_INIT_LOW, "flexcan1-stby" },
+ { MX6Q_SABREAUTO_CAN2_EN, GPIOF_OUT_INIT_LOW, "flexcan2-en" },
+};
+
+static void mx6q_flexcan0_switch(int enable)
+{
+ if (enable) {
+ gpio_set_value(MX6Q_SABREAUTO_CAN1_EN, 1);
+ gpio_set_value(MX6Q_SABREAUTO_CAN1_STBY, 1);
+ } else {
+ gpio_set_value(MX6Q_SABREAUTO_CAN1_EN, 0);
+ gpio_set_value(MX6Q_SABREAUTO_CAN1_STBY, 0);
+ }
+}
+
+static void mx6q_flexcan1_switch(int enable)
+{
+ if (enable) {
+ gpio_set_value(MX6Q_SABREAUTO_CAN2_EN, 1);
+ gpio_set_value(MX6Q_SABREAUTO_CAN2_STBY, 1);
+ } else {
+ gpio_set_value(MX6Q_SABREAUTO_CAN2_EN, 0);
+ gpio_set_value(MX6Q_SABREAUTO_CAN2_STBY, 0);
+ }
+}
+
+static const struct flexcan_platform_data
+ mx6q_sabreauto_flexcan_pdata[] __initconst = {
+ {
+ .transceiver_switch = mx6q_flexcan0_switch,
+ }, {
+ .transceiver_switch = mx6q_flexcan1_switch,
+ }
+};
+
+static struct mipi_csi2_platform_data mipi_csi2_pdata = {
+ .ipu_id = 0,
+ .csi_id = 0,
+ .v_channel = 0,
+ .lanes = 2,
+ .dphy_clk = "mipi_pllref_clk",
+ .pixel_clk = "emi_clk",
+};
+
+static void arm2_suspend_enter(void)
+{
+ /* suspend preparation */
+}
+
+static void arm2_suspend_exit(void)
+{
+ /* resmue resore */
+}
+static const struct pm_platform_data mx6q_sabreauto_pm_data __initconst = {
+ .name = "imx_pm",
+ .suspend_enter = arm2_suspend_enter,
+ .suspend_exit = arm2_suspend_exit,
+};
+
+static struct mxc_audio_platform_data sab_audio_data = {
+ .sysclk = 16934400,
+};
+
+static struct platform_device sab_audio_device = {
+ .name = "imx-cs42888",
+};
+
+static struct imx_esai_platform_data sab_esai_pdata = {
+ .flags = IMX_ESAI_NET,
+};
+
+static struct regulator_consumer_supply arm2_vmmc_consumers[] = {
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.1"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.2"),
+ REGULATOR_SUPPLY("vmmc", "sdhci-esdhc-imx.3"),
+};
+
+static struct regulator_init_data arm2_vmmc_init = {
+ .num_consumer_supplies = ARRAY_SIZE(arm2_vmmc_consumers),
+ .consumer_supplies = arm2_vmmc_consumers,
+};
+
+static struct fixed_voltage_config arm2_vmmc_reg_config = {
+ .supply_name = "vmmc",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &arm2_vmmc_init,
+};
+
+static struct platform_device arm2_vmmc_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
+ .platform_data = &arm2_vmmc_reg_config,
+ },
+};
+
+#ifdef CONFIG_SND_SOC_CS42888
+
+static struct regulator_consumer_supply cs42888_arm2_consumer_va = {
+ .supply = "VA",
+ .dev_name = "0-0048",
+};
+
+static struct regulator_consumer_supply cs42888_arm2_consumer_vd = {
+ .supply = "VD",
+ .dev_name = "0-0048",
+};
+
+static struct regulator_consumer_supply cs42888_arm2_consumer_vls = {
+ .supply = "VLS",
+ .dev_name = "0-0048",
+};
+
+static struct regulator_consumer_supply cs42888_arm2_consumer_vlc = {
+ .supply = "VLC",
+ .dev_name = "0-0048",
+};
+
+static struct regulator_init_data cs42888_arm2_va_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_arm2_consumer_va,
+};
+
+static struct regulator_init_data cs42888_arm2_vd_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_arm2_consumer_vd,
+};
+
+static struct regulator_init_data cs42888_arm2_vls_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_arm2_consumer_vls,
+};
+
+static struct regulator_init_data cs42888_arm2_vlc_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_arm2_consumer_vlc,
+};
+
+static struct fixed_voltage_config cs42888_arm2_va_reg_config = {
+ .supply_name = "VA",
+ .microvolts = 2800000,
+ .gpio = -1,
+ .init_data = &cs42888_arm2_va_reg_initdata,
+};
+
+static struct fixed_voltage_config cs42888_arm2_vd_reg_config = {
+ .supply_name = "VD",
+ .microvolts = 2800000,
+ .gpio = -1,
+ .init_data = &cs42888_arm2_vd_reg_initdata,
+};
+
+static struct fixed_voltage_config cs42888_arm2_vls_reg_config = {
+ .supply_name = "VLS",
+ .microvolts = 2800000,
+ .gpio = -1,
+ .init_data = &cs42888_arm2_vls_reg_initdata,
+};
+
+static struct fixed_voltage_config cs42888_arm2_vlc_reg_config = {
+ .supply_name = "VLC",
+ .microvolts = 2800000,
+ .gpio = -1,
+ .init_data = &cs42888_arm2_vlc_reg_initdata,
+};
+
+static struct platform_device cs42888_arm2_va_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 3,
+ .dev = {
+ .platform_data = &cs42888_arm2_va_reg_config,
+ },
+};
+
+static struct platform_device cs42888_arm2_vd_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 4,
+ .dev = {
+ .platform_data = &cs42888_arm2_vd_reg_config,
+ },
+};
+
+static struct platform_device cs42888_arm2_vls_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 5,
+ .dev = {
+ .platform_data = &cs42888_arm2_vls_reg_config,
+ },
+};
+
+static struct platform_device cs42888_arm2_vlc_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 6,
+ .dev = {
+ .platform_data = &cs42888_arm2_vlc_reg_config,
+ },
+};
+
+#endif /* CONFIG_SND_SOC_CS42888 */
+
+#ifdef CONFIG_SND_SOC_SGTL5000
+
+static struct regulator_consumer_supply sgtl5000_arm2_consumer_vdda = {
+ .supply = "VDDA",
+ .dev_name = "0-000a",
+};
+
+static struct regulator_consumer_supply sgtl5000_arm2_consumer_vddio = {
+ .supply = "VDDIO",
+ .dev_name = "0-000a",
+};
+
+static struct regulator_consumer_supply sgtl5000_arm2_consumer_vddd = {
+ .supply = "VDDD",
+ .dev_name = "0-000a",
+};
+
+static struct regulator_init_data sgtl5000_arm2_vdda_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sgtl5000_arm2_consumer_vdda,
+};
+
+static struct regulator_init_data sgtl5000_arm2_vddio_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sgtl5000_arm2_consumer_vddio,
+};
+
+static struct regulator_init_data sgtl5000_arm2_vddd_reg_initdata = {
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sgtl5000_arm2_consumer_vddd,
+};
+
+static struct fixed_voltage_config sgtl5000_arm2_vdda_reg_config = {
+ .supply_name = "VDDA",
+ .microvolts = 1800000,
+ .gpio = -1,
+ .init_data = &sgtl5000_arm2_vdda_reg_initdata,
+};
+
+static struct fixed_voltage_config sgtl5000_arm2_vddio_reg_config = {
+ .supply_name = "VDDIO",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &sgtl5000_arm2_vddio_reg_initdata,
+};
+
+static struct fixed_voltage_config sgtl5000_arm2_vddd_reg_config = {
+ .supply_name = "VDDD",
+ .microvolts = 0,
+ .gpio = -1,
+ .init_data = &sgtl5000_arm2_vddd_reg_initdata,
+};
+
+static struct platform_device sgtl5000_arm2_vdda_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 7,
+ .dev = {
+ .platform_data = &sgtl5000_arm2_vdda_reg_config,
+ },
+};
+
+static struct platform_device sgtl5000_arm2_vddio_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 8,
+ .dev = {
+ .platform_data = &sgtl5000_arm2_vddio_reg_config,
+ },
+};
+
+static struct platform_device sgtl5000_arm2_vddd_reg_devices = {
+ .name = "reg-fixed-voltage",
+ .id = 9,
+ .dev = {
+ .platform_data = &sgtl5000_arm2_vddd_reg_config,
+ },
+};
+
+#endif /* CONFIG_SND_SOC_SGTL5000 */
+
+static int __init imx6q_init_audio(void)
+{
+ struct clk *pll3_pfd, *esai_clk;
+ mxc_register_device(&sab_audio_device, &sab_audio_data);
+ imx6q_add_imx_esai(0, &sab_esai_pdata);
+
+ esai_clk = clk_get(NULL, "esai_clk");
+ if (IS_ERR(esai_clk))
+ return PTR_ERR(esai_clk);
+
+ pll3_pfd = clk_get(NULL, "pll3_pfd_508M");
+ if (IS_ERR(pll3_pfd))
+ return PTR_ERR(pll3_pfd);
+
+ clk_set_parent(esai_clk, pll3_pfd);
+ clk_set_rate(esai_clk, 101647058);
+
+#ifdef CONFIG_SND_SOC_SGTL5000
+ platform_device_register(&sgtl5000_arm2_vdda_reg_devices);
+ platform_device_register(&sgtl5000_arm2_vddio_reg_devices);
+ platform_device_register(&sgtl5000_arm2_vddd_reg_devices);
+#endif
+
+#ifdef CONFIG_SND_SOC_CS42888
+ platform_device_register(&cs42888_arm2_va_reg_devices);
+ platform_device_register(&cs42888_arm2_vd_reg_devices);
+ platform_device_register(&cs42888_arm2_vls_reg_devices);
+ platform_device_register(&cs42888_arm2_vlc_reg_devices);
+#endif
+ return 0;
+}
+
+static int __init early_use_esai_record(char *p)
+{
+ esai_record = 1;
+ return 0;
+}
+
+early_param("esai_record", early_use_esai_record);
+
+static struct mxc_dvfs_platform_data arm2_dvfscore_data = {
+ .reg_id = "cpu_vddgp",
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 80,
+};
+
+static int mx6_arm2_set_cpu_voltage(u32 cpu_volt)
+{
+ int ret = -EINVAL;
+
+ if (cpu_regulator == NULL)
+ cpu_regulator = regulator_get(NULL, gp_reg_id);
+
+ if (!IS_ERR(cpu_regulator))
+ ret = regulator_set_voltage(cpu_regulator,
+ cpu_volt, cpu_volt);
+ return ret;
+}
+
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ set_cpu_voltage = mx6_arm2_set_cpu_voltage;
+}
+
+static int __init early_enable_mipi_sensor(char *p)
+{
+ mipi_sensor = 1;
+ return 0;
+}
+early_param("mipi_sensor", early_enable_mipi_sensor);
+
+static inline void __init mx6q_csi0_io_init(void)
+{
+ /* Camera reset */
+ gpio_request(MX6Q_SMD_CSI0_RST, "cam-reset");
+ gpio_direction_output(MX6Q_SMD_CSI0_RST, 1);
+
+ /* Camera power down */
+ gpio_request(MX6Q_SMD_CSI0_PWN, "cam-pwdn");
+ gpio_direction_output(MX6Q_SMD_CSI0_PWN, 1);
+ msleep(1);
+ gpio_set_value(MX6Q_SMD_CSI0_PWN, 0);
+ mxc_iomux_set_gpr_register(1, 19, 1, 1);
+}
+
+static int __init early_enable_spdif(char *p)
+{
+ spdif_en = 1;
+ return 0;
+}
+
+early_param("spdif", early_enable_spdif);
+
+static int spdif_clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long rate_actual;
+ rate_actual = clk_round_rate(clk, rate);
+ clk_set_rate(clk, rate_actual);
+ return 0;
+}
+
+static struct mxc_spdif_platform_data mxc_spdif_data = {
+ .spdif_tx = 1, /* enable tx */
+ .spdif_rx = 1, /* enable rx */
+ /*
+ * spdif0_clk will be 454.7MHz divided by ccm dividers.
+ *
+ * 44.1KHz: 454.7MHz / 7 (ccm) / 23 (spdif) = 44,128 Hz ~ 0.06% error
+ * 48KHz: 454.7MHz / 4 (ccm) / 37 (spdif) = 48,004 Hz ~ 0.01% error
+ * 32KHz: 454.7MHz / 6 (ccm) / 37 (spdif) = 32,003 Hz ~ 0.01% error
+ */
+ .spdif_clk_44100 = 1, /* tx clk from spdif0_clk_root */
+ .spdif_clk_48000 = 1, /* tx clk from spdif0_clk_root */
+ .spdif_div_44100 = 23,
+ .spdif_div_48000 = 37,
+ .spdif_div_32000 = 37,
+ .spdif_rx_clk = 0, /* rx clk from spdif stream */
+ .spdif_clk_set_rate = spdif_clk_set_rate,
+ .spdif_clk = NULL, /* spdif bus clk */
+};
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mx6_board_init(void)
+{
+ int i;
+ int ret;
+
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabreauto_pads,
+ ARRAY_SIZE(mx6q_sabreauto_pads));
+
+ if (esai_record)
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabreauto_esai_record_pads,
+ ARRAY_SIZE(mx6q_sabreauto_esai_record_pads));
+
+ /*
+ * S/PDIF in and i2c3 are mutually exclusive because both
+ * use GPIO_16.
+ * S/PDIF out and can1 stby are mutually exclusive because both
+ * use GPIO_17.
+ */
+ if (spdif_en) {
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabreauto_spdif_pads,
+ ARRAY_SIZE(mx6q_sabreauto_spdif_pads));
+ } else {
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabreauto_i2c3_pads,
+ ARRAY_SIZE(mx6q_sabreauto_i2c3_pads));
+ mxc_iomux_v3_setup_multiple_pads(mx6q_sabreauto_can_pads,
+ ARRAY_SIZE(mx6q_sabreauto_can_pads));
+ }
+
+ if (mipi_sensor)
+ mxc_iomux_v3_setup_multiple_pads(
+ mx6q_sabreauto_mipi_sensor_pads,
+ ARRAY_SIZE(mx6q_sabreauto_mipi_sensor_pads));
+
+ gp_reg_id = arm2_dvfscore_data.reg_id;
+ mx6q_sabreauto_init_uart();
+ imx6q_add_mipi_csi2(&mipi_csi2_pdata);
+ imx6q_add_mxc_hdmi_core(&hdmi_core_data);
+
+ imx6q_add_ipuv3(0, &ipu_data[0]);
+ imx6q_add_ipuv3(1, &ipu_data[1]);
+
+ for (i = 0; i < ARRAY_SIZE(sabr_fb_data); i++)
+ imx6q_add_ipuv3fb(i, &sabr_fb_data[i]);
+
+ imx6q_add_mipi_dsi(&mipi_dsi_pdata);
+ imx6q_add_lcdif(&lcdif_data);
+ imx6q_add_ldb(&ldb_data);
+ imx6q_add_v4l2_output(0);
+ imx6q_add_v4l2_capture(0);
+
+ imx6q_add_imx_snvs_rtc();
+
+ imx6q_add_imx_i2c(0, &mx6q_sabreauto_i2c0_data);
+ imx6q_add_imx_i2c(1, &mx6q_sabreauto_i2c_data);
+ i2c_register_board_info(0, mxc_i2c0_board_info,
+ ARRAY_SIZE(mxc_i2c0_board_info));
+ i2c_register_board_info(1, mxc_i2c1_board_info,
+ ARRAY_SIZE(mxc_i2c1_board_info));
+ if (!spdif_en) {
+ imx6q_add_imx_i2c(2, &mx6q_sabreauto_i2c_data);
+ i2c_register_board_info(2, mxc_i2c2_board_info,
+ ARRAY_SIZE(mxc_i2c2_board_info));
+ }
+
+ /* SPI */
+ imx6q_add_ecspi(0, &mx6q_sabreauto_spi_data);
+ spi_device_init();
+
+ imx6q_add_mxc_hdmi(&hdmi_data);
+
+ imx6q_add_anatop_thermal_imx(1, &mx6q_sabreauto_anatop_thermal_data);
+
+ if (!esai_record)
+ imx6_init_fec(fec_data);
+
+ imx6q_add_pm_imx(0, &mx6q_sabreauto_pm_data);
+ /* imx6q_add_sdhci_usdhc_imx(3, &mx6q_sabreauto_sd4_data); */
+ imx6q_add_sdhci_usdhc_imx(2, &mx6q_sabreauto_sd3_data);
+ imx_add_viv_gpu(&imx6_gpu_data, &imx6q_gpu_pdata);
+ imx6q_sabreauto_init_usb();
+ imx6q_add_ahci(0, &mx6q_sabreauto_sata_data);
+ imx6q_add_vpu();
+ imx6q_init_audio();
+ platform_device_register(&arm2_vmmc_reg_devices);
+ imx_asrc_data.asrc_core_clk = clk_get(NULL, "asrc_clk");
+ imx_asrc_data.asrc_audio_clk = clk_get(NULL, "asrc_serial_clk");
+ imx6q_add_asrc(&imx_asrc_data);
+
+ if (!mipi_sensor)
+ mx6q_csi0_io_init();
+
+ /* DISP0 Detect */
+ gpio_request(MX6Q_SABREAUTO_DISP0_DET_INT, "disp0-detect");
+ gpio_direction_input(MX6Q_SABREAUTO_DISP0_DET_INT);
+
+ /* DISP0 Reset - Assert for i2c disabled mode */
+ gpio_request(MX6Q_SABREAUTO_DISP0_RESET, "disp0-reset");
+ gpio_direction_output(MX6Q_SABREAUTO_DISP0_RESET, 0);
+
+ /* DISP0 I2C enable */
+ gpio_request(MX6Q_SABREAUTO_DISP0_I2C_EN, "disp0-i2c");
+ gpio_direction_output(MX6Q_SABREAUTO_DISP0_I2C_EN, 0);
+
+ gpio_request(MX6Q_SABREAUTO_DISP0_PWR, "disp0-pwr");
+ gpio_direction_output(MX6Q_SABREAUTO_DISP0_PWR, 1);
+
+ gpio_request(MX6Q_SABREAUTO_LDB_BACKLIGHT, "ldb-backlight");
+ gpio_direction_output(MX6Q_SABREAUTO_LDB_BACKLIGHT, 1);
+ imx6q_add_otp();
+ imx6q_add_viim();
+ imx6q_add_imx2_wdt(0, NULL);
+ imx6q_add_dma();
+ imx6q_add_gpmi(&mx6q_gpmi_nfc_platform_data);
+
+ imx6q_add_dvfs_core(&arm2_dvfscore_data);
+
+ imx6q_add_mxc_pwm(0);
+ imx6q_add_mxc_pwm_backlight(0, &mx6_arm2_pwm_backlight_data);
+
+ if (spdif_en) {
+ mxc_spdif_data.spdif_core_clk = clk_get_sys("mxc_spdif.0",
+ NULL);
+ clk_put(mxc_spdif_data.spdif_core_clk);
+ imx6q_add_spdif(&mxc_spdif_data);
+ imx6q_add_spdif_dai();
+ imx6q_add_spdif_audio_device();
+ } else {
+ ret = gpio_request_array(mx6q_flexcan_gpios,
+ ARRAY_SIZE(mx6q_flexcan_gpios));
+ if (ret) {
+ pr_err("failed to request flexcan-gpios: %d\n", ret);
+ } else {
+ imx6q_add_flexcan0(&mx6q_sabreauto_flexcan_pdata[0]);
+ imx6q_add_flexcan1(&mx6q_sabreauto_flexcan_pdata[1]);
+ }
+ }
+
+ imx6q_add_hdmi_soc();
+ imx6q_add_hdmi_soc_dai();
+}
+
+extern void __iomem *twd_base;
+static void __init mx6_timer_init(void)
+{
+ struct clk *uart_clk;
+#ifdef CONFIG_LOCAL_TIMERS
+ twd_base = ioremap(LOCAL_TWD_ADDR, SZ_256);
+ BUG_ON(!twd_base);
+#endif
+ mx6_clocks_init(32768, 24000000, 0, 0);
+
+ uart_clk = clk_get_sys("imx-uart.0", NULL);
+ early_console_setup(UART4_BASE_ADDR, uart_clk);
+}
+
+static struct sys_timer mxc_timer = {
+ .init = mx6_timer_init,
+};
+
+static void __init mx6q_reserve(void)
+{
+ phys_addr_t phys;
+
+ if (imx6q_gpu_pdata.reserved_mem_size) {
+ phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
+ SZ_4K, SZ_2G);
+ memblock_free(phys, imx6q_gpu_pdata.reserved_mem_size);
+ memblock_remove(phys, imx6q_gpu_pdata.reserved_mem_size);
+ imx6q_gpu_pdata.reserved_mem_base = phys;
+ }
+}
+
+/*
+ * initialize __mach_desc_MX6Q_SABREAUTO data structure.
+ */
+MACHINE_START(MX6Q_SABREAUTO, "Freescale i.MX 6Quad Sabre Auto Board")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .boot_params = MX6_PHYS_OFFSET + 0x100,
+ .fixup = fixup_mxc_board,
+ .map_io = mx6_map_io,
+ .init_irq = mx6_init_irq,
+ .init_machine = mx6_board_init,
+ .timer = &mxc_timer,
+ .reserve = mx6q_reserve,
+MACHINE_END
diff --git a/arch/arm/mach-mx6/board-mx6q_sabrelite.c b/arch/arm/mach-mx6/board-mx6q_sabrelite.c
index c3b49eb9fc10..3918989ca166 100755
--- a/arch/arm/mach-mx6/board-mx6q_sabrelite.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabrelite.c
@@ -82,6 +82,8 @@
#define MX6Q_SABRELITE_USB_OTG_PWR IMX_GPIO_NR(3, 22)
#define MX6Q_SABRELITE_CAP_TCH_INT1 IMX_GPIO_NR(1, 9)
#define MX6Q_SABRELITE_USB_HUB_RESET IMX_GPIO_NR(7, 12)
+#define MX6Q_SABRELITE_CAN1_STBY IMX_GPIO_NR(1, 2)
+#define MX6Q_SABRELITE_CAN1_EN IMX_GPIO_NR(1, 4)
#define MX6Q_SABRELITE_SD3_WP_PADCFG (PAD_CTL_PKE | PAD_CTL_PUE | \
PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_MED | \
@@ -106,9 +108,9 @@ static iomux_v3_cfg_t mx6q_sabrelite_pads[] = {
/* CAN1 */
MX6Q_PAD_KEY_ROW2__CAN1_RXCAN,
MX6Q_PAD_KEY_COL2__CAN1_TXCAN,
- MX6Q_PAD_ENET_CRS_DV__GPIO_1_25, /* STNDBY */
- MX6Q_PAD_ENET_RXD1__GPIO_1_26, /* NERR */
- MX6Q_PAD_ENET_RXD0__GPIO_1_27, /* Enable */
+ MX6Q_PAD_GPIO_2__GPIO_1_2, /* STNDBY */
+ MX6Q_PAD_GPIO_7__GPIO_1_7, /* NERR */
+ MX6Q_PAD_GPIO_4__GPIO_1_4, /* Enable */
/* CCM */
MX6Q_PAD_GPIO_0__CCM_CLKO, /* SGTL500 sys_mclk */
@@ -582,10 +584,37 @@ static void __init imx6q_sabrelite_init_usb(void)
mx6_usb_dr_init();
mx6_usb_h1_init();
}
+
+static struct gpio mx6q_sabrelite_flexcan_gpios[] = {
+ { MX6Q_SABRELITE_CAN1_EN, GPIOF_OUT_INIT_LOW, "flexcan1-en" },
+ { MX6Q_SABRELITE_CAN1_STBY, GPIOF_OUT_INIT_LOW, "flexcan1-stby" },
+};
+
+static void mx6q_sabrelite_flexcan0_switch(int enable)
+{
+ if (enable) {
+ gpio_set_value(MX6Q_SABRELITE_CAN1_EN, 1);
+ gpio_set_value(MX6Q_SABRELITE_CAN1_STBY, 1);
+ } else {
+ gpio_set_value(MX6Q_SABRELITE_CAN1_EN, 0);
+ gpio_set_value(MX6Q_SABRELITE_CAN1_STBY, 0);
+ }
+}
+
+static const struct flexcan_platform_data
+ mx6q_sabrelite_flexcan0_pdata __initconst = {
+ .transceiver_switch = mx6q_sabrelite_flexcan0_switch,
+};
+
static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = {
.reserved_mem_size = SZ_128M,
};
+static struct imx_asrc_platform_data imx_asrc_data = {
+ .channel_bits = 4,
+ .clk_map_ver = 2,
+};
+
static struct ipuv3_fb_platform_data sabrelite_fb_data[] = {
{ /*fb0*/
.disp_dev = "ldb",
@@ -885,10 +914,12 @@ static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
static void __init mx6_sabrelite_board_init(void)
{
int i;
+ int ret;
mxc_iomux_v3_setup_multiple_pads(mx6q_sabrelite_pads,
ARRAY_SIZE(mx6q_sabrelite_pads));
+ gp_reg_id = sabrelite_dvfscore_data.reg_id;
mx6q_sabrelite_init_uart();
imx6q_add_mxc_hdmi_core(&hdmi_core_data);
@@ -930,6 +961,10 @@ static void __init mx6_sabrelite_board_init(void)
imx6q_add_vpu();
imx6q_init_audio();
platform_device_register(&sabrelite_vmmc_reg_devices);
+ imx_asrc_data.asrc_core_clk = clk_get(NULL, "asrc_clk");
+ imx_asrc_data.asrc_audio_clk = clk_get(NULL, "asrc_serial_clk");
+ imx6q_add_asrc(&imx_asrc_data);
+
/* release USB Hub reset */
gpio_set_value(MX6Q_SABRELITE_USB_HUB_RESET, 1);
@@ -953,6 +988,13 @@ static void __init mx6_sabrelite_board_init(void)
imx6q_add_hdmi_soc();
imx6q_add_hdmi_soc_dai();
+
+ ret = gpio_request_array(mx6q_sabrelite_flexcan_gpios,
+ ARRAY_SIZE(mx6q_sabrelite_flexcan_gpios));
+ if (ret)
+ pr_err("failed to request flexcan1-gpios: %d\n", ret);
+ else
+ imx6q_add_flexcan0(&mx6q_sabrelite_flexcan0_pdata);
}
extern void __iomem *twd_base;
diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c
index 01469475b8a9..12a8d3583921 100644
--- a/arch/arm/mach-mx6/clock.c
+++ b/arch/arm/mach-mx6/clock.c
@@ -37,8 +37,11 @@
#define __INIT_CLK_DEBUG(n)
#endif
+extern u32 arm_max_freq;
extern int mxc_jtag_enabled;
extern struct cpu_op *(*get_cpu_op)(int *op);
+extern int mx6_set_cpu_voltage(u32 cpu_volt);
+
extern int lp_high_freq;
extern int lp_med_freq;
@@ -67,6 +70,12 @@ static int cpu_op_nr;
#define AUDIO_VIDEO_MIN_CLK_FREQ 650000000
#define AUDIO_VIDEO_MAX_CLK_FREQ 1300000000
+/* We need to check the exp status again after timer expiration,
+ * as there might be interrupt coming between the first time exp
+ * and the time reading, then the time reading may be several ms
+ * after the exp checking due to the irq handle, so we need to
+ * check it to make sure the exp return the right value after
+ * timer expiration. */
#define WAIT(exp, timeout) \
({ \
struct timespec nstimeofday; \
@@ -76,7 +85,8 @@ static int cpu_op_nr;
while (!(exp)) { \
getnstimeofday(&curtime); \
if ((curtime.tv_nsec - nstimeofday.tv_nsec) > (timeout)) { \
- result = 0; \
+ if (!(exp)) \
+ result = 0; \
break; \
} \
} \
@@ -906,7 +916,7 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
int i;
u32 div;
u32 parent_rate;
- struct clk *old_parent = pll1_sw_clk.parent;
+
for (i = 0; i < cpu_op_nr; i++) {
if (rate == cpu_op_tbl[i].cpu_rate)
@@ -915,23 +925,14 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
if (i >= cpu_op_nr)
return -EINVAL;
- if (rate <= clk_get_rate(&pll2_pfd_400M)) {
- /*
- * Move pll1_sw_clk to PLL2_PFD_400M
- * so that we can disable PLL1.
- */
- if (pll2_pfd_400M.usecount == 0)
- pll2_pfd_400M.enable(&pll2_pfd_400M);
- pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd_400M);
- pll1_sw_clk.parent = &pll2_pfd_400M;
- } else {
- /* Rate is above 400MHz. We may need to relock PLL1. */
- pll1_sw_clk.set_parent(&pll1_sw_clk, &osc_clk);
- if (pll1_sys_main_clk.usecount == 0)
- pll1_sys_main_clk.enable(&pll1_sys_main_clk);
+ if (cpu_op_tbl[i].pll_rate != clk_get_rate(&pll1_sys_main_clk)) {
+ /* Change the PLL1 rate. */
+ if (pll2_pfd_400M.usecount != 0)
+ pll1_sw_clk.set_parent(&pll1_sw_clk, &pll2_pfd_400M);
+ else
+ pll1_sw_clk.set_parent(&pll1_sw_clk, &osc_clk);
pll1_sys_main_clk.set_rate(&pll1_sys_main_clk, cpu_op_tbl[i].pll_rate);
pll1_sw_clk.set_parent(&pll1_sw_clk, &pll1_sys_main_clk);
- pll1_sw_clk.parent = &pll1_sys_main_clk;
}
parent_rate = clk_get_rate(clk->parent);
@@ -948,15 +949,6 @@ static int _clk_arm_set_rate(struct clk *clk, unsigned long rate)
__raw_writel(div - 1, MXC_CCM_CACRR);
- /* Increment current parent's usecount. */
- pll1_sw_clk.parent->usecount++;
-
- /* Decrement the current parent's usecount */
- old_parent->usecount--;
-
- if (old_parent->usecount == 0)
- old_parent->disable(old_parent);
-
return 0;
}
@@ -4214,8 +4206,8 @@ static int _clk_gpu2d_core_set_rate(struct clk *clk, unsigned long rate)
return -EINVAL;
reg = __raw_readl(MXC_CCM_CBCMR);
- reg &= ~MXC_CCM_CBCMR_GPU3D_CORE_PODF_MASK;
- reg |= (div - 1) << MXC_CCM_CBCMR_GPU3D_CORE_PODF_OFFSET;
+ reg &= ~MXC_CCM_CBCMR_GPU2D_CORE_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCMR_GPU2D_CORE_PODF_OFFSET;
__raw_writel(reg, MXC_CCM_CBCMR);
return 0;
@@ -4645,6 +4637,33 @@ static struct clk clko_clk = {
.round_rate = _clk_clko_round_rate,
};
+static struct clk perfmon0_clk = {
+ __INIT_CLK_DEBUG(perfmon0_clk)
+ .parent = &mmdc_ch0_axi_clk[0],
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG1_OFFSET,
+ .disable = _clk_disable1,
+};
+
+static struct clk perfmon1_clk = {
+ __INIT_CLK_DEBUG(perfmon1_clk)
+ .parent = &ipu1_clk,
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG2_OFFSET,
+ .disable = _clk_disable1,
+};
+
+static struct clk perfmon2_clk = {
+ __INIT_CLK_DEBUG(perfmon2_clk)
+ .parent = &mmdc_ch0_axi_clk[0],
+ .enable = _clk_enable1,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGRx_CG3_OFFSET,
+ .disable = _clk_disable1,
+};
+
static struct clk dummy_clk = {
.id = 0,
};
@@ -4770,6 +4789,9 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, NULL, aips_tz2_clk),
_REGISTER_CLOCK(NULL, NULL, aips_tz1_clk),
_REGISTER_CLOCK(NULL, "clko_clk", clko_clk),
+ _REGISTER_CLOCK("mxs-perfmon.0", "perfmon", perfmon0_clk),
+ _REGISTER_CLOCK("mxs-perfmon.1", "perfmon", perfmon1_clk),
+ _REGISTER_CLOCK("mxs-perfmon.2", "perfmon", perfmon2_clk),
};
@@ -4857,12 +4879,12 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
clk_set_rate(&gpu3d_core_clk[0], 528000000);
/*
- * FIXME: asrc needs to use asrc_serial(spdif1) clock to do sample rate convertion,
- * however we found it only works when set to 1.5M clock and the
- * parent is pll3_sw_clk.
+ * FIXME: asrc needs to use asrc_serial(spdif1) clock to do sample
+ * rate convertion and this clock frequency can not be too high, set
+ * it to the minimum value 7.5Mhz to make asrc work properly.
*/
clk_set_parent(&asrc_clk[1], &pll3_sw_clk);
- clk_set_rate(&asrc_clk[1], 1500000);
+ clk_set_rate(&asrc_clk[1], 7500000);
/* set the NAND to 11MHz. Too fast will cause dma timeout. */
clk_set_rate(&enfc_clk, enfc_clk.round_rate(&enfc_clk, 11000000));
@@ -4909,6 +4931,10 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
base = ioremap(GPT_BASE_ADDR, SZ_4K);
mxc_timer_init(&gpt_clk[0], base, MXC_INT_GPT);
+ /* Set the core to max frequency requested. */
+ mx6_set_cpu_voltage(cpu_op_tbl[0].cpu_voltage);
+ clk_set_rate(&cpu_clk, cpu_op_tbl[0].pll_rate);
+
lp_high_freq = 0;
lp_med_freq = 0;
diff --git a/arch/arm/mach-mx6/cpu.c b/arch/arm/mach-mx6/cpu.c
index f2b934519cfe..e392a3cbef10 100644
--- a/arch/arm/mach-mx6/cpu.c
+++ b/arch/arm/mach-mx6/cpu.c
@@ -29,6 +29,8 @@
#include <asm/mach/map.h>
#include "crm_regs.h"
+#include "cpu_op-mx6.h"
+
void *mx6_wait_in_iram_base;
void (*mx6_wait_in_iram)(void *ccm_base);
@@ -37,6 +39,7 @@ extern void mx6_wait(void);
struct cpu_op *(*get_cpu_op)(int *op);
bool enable_wait_mode;
+u32 arm_max_freq = CPU_AT_1GHz;
void __iomem *gpc_base;
void __iomem *ccm_base;
@@ -128,3 +131,18 @@ static int __init enable_wait(char *p)
}
early_param("enable_wait_mode", enable_wait);
+static int __init arm_core_max(char *p)
+{
+ if (memcmp(p, "1000", 4) == 0) {
+ arm_max_freq = CPU_AT_1GHz;
+ p += 4;
+ } else if (memcmp(p, "800", 3) == 0) {
+ arm_max_freq = CPU_AT_800MHz;
+ p += 3;
+ }
+ return 0;
+}
+
+early_param("arm_freq", arm_core_max);
+
+
diff --git a/arch/arm/mach-mx6/cpu_op-mx6.c b/arch/arm/mach-mx6/cpu_op-mx6.c
index c0694fd71e3b..30a4346282ea 100644
--- a/arch/arm/mach-mx6/cpu_op-mx6.c
+++ b/arch/arm/mach-mx6/cpu_op-mx6.c
@@ -15,14 +15,16 @@
#include <linux/kernel.h>
#include <mach/hardware.h>
#include <mach/mxc_dvfs.h>
+#include "cpu_op-mx6.h"
extern struct cpu_op *(*get_cpu_op)(int *op);
extern struct dvfs_op *(*get_dvfs_core_op)(int *wp);
extern void (*set_num_cpu_op)(int num);
+extern u32 arm_max_freq;
static int num_cpu_op;
/* working point(wp): 0 - 1GHzMHz; 1 - 800MHz, 3 - 400MHz, 4 - 160MHz */
-static struct cpu_op mx6_cpu_op[] = {
+static struct cpu_op mx6_cpu_op_1G[] = {
{
.pll_rate = 996000000,
.cpu_rate = 996000000,
@@ -31,7 +33,7 @@ static struct cpu_op mx6_cpu_op[] = {
.mfd = 11,
.mfn = 5,
.cpu_podf = 0,
- .cpu_voltage = 1150000,},
+ .cpu_voltage = 1225000,},
{
.pll_rate = 792000000,
.cpu_rate = 792000000,
@@ -40,35 +42,72 @@ static struct cpu_op mx6_cpu_op[] = {
.mfd = 2,
.mfn = 1,
.cpu_podf = 0,
- .cpu_voltage = 1150000,},
+ .cpu_voltage = 1100000,},
{
- .pll_rate = 396000000,
+ .pll_rate = 792000000,
.cpu_rate = 396000000,
- .cpu_podf = 0,
- .cpu_voltage = 1050000,},
+ .cpu_podf = 1,
+ .cpu_voltage = 950000,},
{
- .pll_rate = 396000000,
+ .pll_rate = 792000000,
.cpu_rate = 198000000,
- .cpu_podf = 1,
- .cpu_voltage = 900000,},
+ .cpu_podf = 3,
+ .cpu_voltage = 850000,},
};
-static struct dvfs_op dvfs_core_setpoint[] = {
+static struct cpu_op mx6_cpu_op[] = {
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 792000000,
+ .pdf = 0,
+ .mfi = 8,
+ .mfd = 2,
+ .mfn = 1,
+ .cpu_podf = 0,
+ .cpu_voltage = 1100000,},
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 396000000,
+ .cpu_podf = 1,
+ .cpu_voltage = 950000,},
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 198000000,
+ .cpu_podf = 3,
+ .cpu_voltage = 850000,},
+};
+
+static struct dvfs_op dvfs_core_setpoint_1G[] = {
{33, 14, 33, 10, 10, 0x08}, /* 1GHz*/
{30, 12, 33, 10, 10, 0x08}, /* 800MHz */
{28, 8, 33, 10, 10, 0x08}, /* 400MHz */
- {20, 0, 33, 20, 10, 0x08} }; /* 167MHz*/
+ {20, 0, 33, 20, 10, 0x08} }; /* 200MHz*/
+
+static struct dvfs_op dvfs_core_setpoint[] = {
+ {33, 14, 33, 10, 10, 0x08}, /* 800MHz */
+ {26, 8, 33, 10, 10, 0x08}, /* 400MHz */
+ {20, 0, 33, 20, 10, 0x08} }; /* 200MHz*/
static struct dvfs_op *mx6_get_dvfs_core_table(int *wp)
{
- *wp = ARRAY_SIZE(dvfs_core_setpoint);
- return dvfs_core_setpoint;
+ if (arm_max_freq == CPU_AT_1GHz) {
+ *wp = ARRAY_SIZE(dvfs_core_setpoint_1G);
+ return dvfs_core_setpoint_1G;
+ } else {
+ *wp = ARRAY_SIZE(dvfs_core_setpoint);
+ return dvfs_core_setpoint;
+ }
}
struct cpu_op *mx6_get_cpu_op(int *op)
{
- *op = num_cpu_op;
- return mx6_cpu_op;
+ if (arm_max_freq == CPU_AT_1GHz) {
+ *op = num_cpu_op = ARRAY_SIZE(mx6_cpu_op_1G);
+ return mx6_cpu_op_1G;
+ } else {
+ *op = num_cpu_op = ARRAY_SIZE(mx6_cpu_op);
+ return mx6_cpu_op;
+ }
}
void mx6_set_num_cpu_op(int num)
@@ -82,7 +121,6 @@ void mx6_cpu_op_init(void)
get_cpu_op = mx6_get_cpu_op;
set_num_cpu_op = mx6_set_num_cpu_op;
- num_cpu_op = ARRAY_SIZE(mx6_cpu_op);
get_dvfs_core_op = mx6_get_dvfs_core_table;
}
diff --git a/arch/arm/mach-mx6/cpu_op-mx6.h b/arch/arm/mach-mx6/cpu_op-mx6.h
index f13b26962bde..77e8222c5d38 100644
--- a/arch/arm/mach-mx6/cpu_op-mx6.h
+++ b/arch/arm/mach-mx6/cpu_op-mx6.h
@@ -11,4 +11,7 @@
* http://www.gnu.org/copyleft/gpl.html
*/
+#define CPU_AT_800MHz 0
+#define CPU_AT_1GHz 1
+
void mx6_cpu_op_init(void);
diff --git a/arch/arm/mach-mx6/devices-imx6q.h b/arch/arm/mach-mx6/devices-imx6q.h
index e46c97ef927c..e87f9c0d7e7f 100644
--- a/arch/arm/mach-mx6/devices-imx6q.h
+++ b/arch/arm/mach-mx6/devices-imx6q.h
@@ -189,3 +189,8 @@ extern const struct imx_flexcan_data imx6q_flexcan_data[] __initconst;
extern const struct imx_mipi_csi2_data imx6q_mipi_csi2_data __initconst;
#define imx6q_add_mipi_csi2(pdata) \
imx_add_mipi_csi2(&imx6q_mipi_csi2_data, pdata)
+
+extern const struct imx_perfmon_data imx6q_perfmon_data[] __initconst;
+#define imx6q_add_perfmon(id) \
+ imx_add_perfmon(&imx6q_perfmon_data[id])
+
diff --git a/arch/arm/mach-mx6/mx6_fec.c b/arch/arm/mach-mx6/mx6_fec.c
index 32e858355390..b2aa45b3c510 100644
--- a/arch/arm/mach-mx6/mx6_fec.c
+++ b/arch/arm/mach-mx6/mx6_fec.c
@@ -25,7 +25,7 @@
#include <asm/mach/arch.h>
#include "devices-imx6q.h"
-#define HW_OCOTP_MACn(n) (0x00000250 + (n) * 0x10)
+#define HW_OCOTP_MACn(n) (0x00000620 + (n) * 0x10)
static int fec_get_mac_addr(unsigned char *mac)
{
diff --git a/arch/arm/mach-mx6/pm.c b/arch/arm/mach-mx6/pm.c
index 36e35cc062c5..bdf337144554 100644
--- a/arch/arm/mach-mx6/pm.c
+++ b/arch/arm/mach-mx6/pm.c
@@ -186,11 +186,11 @@ static int mx6_suspend_enter(suspend_state_t state)
wake_irq_isr[0] = __raw_readl(gpc_base +
GPC_ISR1_OFFSET) & gpc_wake_irq[0];
wake_irq_isr[1] = __raw_readl(gpc_base +
- GPC_ISR1_OFFSET) & gpc_wake_irq[1];
+ GPC_ISR2_OFFSET) & gpc_wake_irq[1];
wake_irq_isr[2] = __raw_readl(gpc_base +
- GPC_ISR1_OFFSET) & gpc_wake_irq[2];
+ GPC_ISR3_OFFSET) & gpc_wake_irq[2];
wake_irq_isr[3] = __raw_readl(gpc_base +
- GPC_ISR1_OFFSET) & gpc_wake_irq[3];
+ GPC_ISR4_OFFSET) & gpc_wake_irq[3];
if (wake_irq_isr[0] | wake_irq_isr[1] |
wake_irq_isr[2] | wake_irq_isr[3]) {
printk(KERN_INFO "There are wakeup irq pending,system resume!\n");
diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c
index 801826c0fecc..69e761c00402 100644
--- a/arch/arm/mach-mx6/system.c
+++ b/arch/arm/mach-mx6/system.c
@@ -124,7 +124,7 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
/* dormant mode, need to power off the arm core */
if (stop_mode == 2) {
- __raw_writel(0x1, gpc_base + GPC_PGC_CPU_PDN_OFFSET);
+ __raw_writel(0x1, gpc_base + GPC_PGC_CPU_PDN_OFFSET);
__raw_writel(0x1, gpc_base + GPC_PGC_GPU_PGCR_OFFSET);
__raw_writel(0x1, gpc_base + GPC_CNTR_OFFSET);
/* Enable weak 2P5 linear regulator */
@@ -134,7 +134,7 @@ void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
/* Make sure ARM and SOC domain has same voltage */
anatop_val = __raw_readl(anatop_base + ANATOP_REG_CORE_OFFSET);
anatop_val &= ~(0x1f << 18);
- anatop_val |= 0xc;
+ anatop_val |= (anatop_val & 0x1f) << 18;
__raw_writel(anatop_val, anatop_base + ANATOP_REG_CORE_OFFSET);
__raw_writel(__raw_readl(MXC_CCM_CCR) | MXC_CCM_CCR_RBC_EN, MXC_CCM_CCR);
ccm_clpcr |= MXC_CCM_CLPCR_WB_PER_AT_LPM;
@@ -243,3 +243,4 @@ int mxs_reset_block(void __iomem *hwreg, int just_enable)
}
return r;
}
+EXPORT_SYMBOL(mxs_reset_block);
diff --git a/arch/arm/mach-mx6/usb_dr.c b/arch/arm/mach-mx6/usb_dr.c
index de84a4ded23b..957b021e0a73 100644
--- a/arch/arm/mach-mx6/usb_dr.c
+++ b/arch/arm/mach-mx6/usb_dr.c
@@ -365,6 +365,19 @@ static void host_wakeup_handler(struct fsl_usb2_platform_data *pdata)
#ifdef CONFIG_USB_GADGET_ARC
/* Beginning of device related operation for DR port */
+static void _gadget_discharge_dp(bool enable)
+{
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
+ if (enable) {
+ __raw_writel(BF_USBPHY_DEBUG_ENHSTPULLDOWN(0x2), phy_reg + HW_USBPHY_DEBUG_SET);
+ __raw_writel(BF_USBPHY_DEBUG_HSTPULLDOWN(0x2), phy_reg + HW_USBPHY_DEBUG_SET);
+ } else {
+ __raw_writel(BF_USBPHY_DEBUG_ENHSTPULLDOWN(0x2), phy_reg + HW_USBPHY_DEBUG_CLR);
+ __raw_writel(BF_USBPHY_DEBUG_HSTPULLDOWN(0x2), phy_reg + HW_USBPHY_DEBUG_CLR);
+ }
+
+}
+
static void _device_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
{
__phy_lowpower_suspend(pdata, enable, ENABLED_BY_DEVICE);
@@ -450,6 +463,7 @@ void __init mx6_usb_dr_init(void)
dr_utmi_config.wake_up_enable = _device_wakeup_enable;
dr_utmi_config.phy_lowpower_suspend = _device_phy_lowpower_suspend;
dr_utmi_config.is_wakeup_event = _is_device_wakeup;
+ dr_utmi_config.gadget_discharge_dp = _gadget_discharge_dp;
dr_utmi_config.wakeup_pdata = &dr_wakeup_config;
dr_utmi_config.wakeup_handler = device_wakeup_handler;
pdev = imx6q_add_fsl_usb2_udc(&dr_utmi_config);
diff --git a/arch/arm/plat-mxc/devices/platform-imx-perfmon.c b/arch/arm/plat-mxc/devices/platform-imx-perfmon.c
index faec9b0e1111..25d1bf582de2 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-perfmon.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-perfmon.c
@@ -21,6 +21,7 @@
#include <mach/hardware.h>
#include <mach/devices-common.h>
#include <linux/fsl_devices.h>
+#include <mach/iomux-v3.h>
#ifdef CONFIG_SOC_IMX50
static struct mxs_perfmon_bit_config
@@ -51,10 +52,95 @@ const struct imx_perfmon_data imx50_perfmon_data = {
};
#endif
+#ifdef CONFIG_SOC_IMX6Q
+static struct mxs_perfmon_bit_config
+mx6q_perfmon1_bit_config[] = {
+ {.field = (1 << 0), .name = "MID0-GPU_3D" },
+ {.field = (1 << 1), .name = "MID1-GPU_2D" },
+ {.field = (1 << 2), .name = "MID2-VDOA" },
+ {.field = (1 << 3), .name = "MID3-Unused" },
+ {.field = (1 << 4), .name = "MID4-OPENVG" }
+};
+
+static struct mxs_perfmon_bit_config
+mx6q_perfmon2_bit_config[] = {
+ {.field = (1 << 0), .name = "MID0-IPU1.ld00" },
+ {.field = (1 << 1), .name = "MID1-IPU1.ld01" },
+ {.field = (1 << 2), .name = "MID2-IPU1.ld10" },
+ {.field = (1 << 3), .name = "MID3-IPU1.ld11" }
+};
+
+static struct mxs_perfmon_bit_config
+mx6q_perfmon3_bit_config[] = {
+ {.field = (1 << 0), .name = "MID0-CORES" },
+ {.field = (1 << 1), .name = "MID1-L2-BUF" },
+ {.field = (1 << 2), .name = "MID2-Unused" },
+ {.field = (1 << 3), .name = "MID3-L2-EVIC" },
+ {.field = (1 << 4), .name = "MID4-Unused" }
+};
+
+static int init;
+
+static void platform_perfmon_init(void)
+{
+ if (init)
+ return;
+
+ /* GPR11 bit[16] is the clock enable bit for perfmon */
+ mxc_iomux_set_gpr_register(11, 16, 1, 1);
+ init = true;
+}
+
+static void platform_perfmon_exit(void)
+{
+ if (!init)
+ return;
+
+ /* GPR11 bit[16] is the clock enable bit for perfmon */
+ mxc_iomux_set_gpr_register(11, 16, 1, 0);
+ init = false;
+}
+
+struct mxs_platform_perfmon_data mxc_perfmon_data1 = {
+ .bit_config_tab = mx6q_perfmon1_bit_config,
+ .bit_config_cnt = ARRAY_SIZE(mx6q_perfmon1_bit_config),
+ .plt_init = platform_perfmon_init,
+ .plt_exit = platform_perfmon_exit,
+};
+
+struct mxs_platform_perfmon_data mxc_perfmon_data2 = {
+ .bit_config_tab = mx6q_perfmon2_bit_config,
+ .bit_config_cnt = ARRAY_SIZE(mx6q_perfmon2_bit_config),
+ .plt_init = platform_perfmon_init,
+};
+
+struct mxs_platform_perfmon_data mxc_perfmon_data3 = {
+ .bit_config_tab = mx6q_perfmon3_bit_config,
+ .bit_config_cnt = ARRAY_SIZE(mx6q_perfmon3_bit_config),
+ .plt_init = platform_perfmon_init,
+};
+
+const struct imx_perfmon_data imx6q_perfmon_data[3] = {
+ {
+ .iobase = IP2APB_PERFMON1_BASE_ADDR,
+ .pdata = &mxc_perfmon_data1,
+ },
+ {
+ .iobase = IP2APB_PERFMON2_BASE_ADDR,
+ .pdata = &mxc_perfmon_data2,
+ },
+ {
+ .iobase = IP2APB_PERFMON3_BASE_ADDR,
+ .pdata = &mxc_perfmon_data3,
+ }
+};
+#endif
struct platform_device *__init imx_add_perfmon(
const struct imx_perfmon_data *data)
{
+ static int id;
+
struct resource res[] = {
{
.start = data->iobase,
@@ -63,7 +149,7 @@ struct platform_device *__init imx_add_perfmon(
}
};
- return imx_add_platform_device("mxs-perfmon", 0,
+ return imx_add_platform_device("mxs-perfmon", id++,
res, ARRAY_SIZE(res), data->pdata,
sizeof(struct mxs_platform_perfmon_data));
}
diff --git a/arch/arm/plat-mxc/dvfs_core.c b/arch/arm/plat-mxc/dvfs_core.c
index a8812d8ef612..006530416edd 100644
--- a/arch/arm/plat-mxc/dvfs_core.c
+++ b/arch/arm/plat-mxc/dvfs_core.c
@@ -820,7 +820,7 @@ void dump_dvfs_core_regs()
__raw_readl(dvfs_data->membase
+ MXC_DVFSCORE_THRS + 0x40));
}
-
+#if 0
static ssize_t downthreshold_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
@@ -856,7 +856,7 @@ static ssize_t downcount_store(struct device *dev,
return size;
}
-
+#endif
static ssize_t dvfs_enable_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -903,9 +903,6 @@ static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR,
dvfs_enable_show, dvfs_enable_store);
static DEVICE_ATTR(show_regs, S_IRUGO, dvfs_regs_show,
dvfs_regs_store);
-static DEVICE_ATTR(down_threshold, 0644, downthreshold_show,
- downthreshold_store);
-static DEVICE_ATTR(down_count, 0644, downcount_show, downcount_store);
/*!
* This is the probe routine for the DVFS driver.
@@ -996,20 +993,6 @@ static int __devinit mxc_dvfs_core_probe(struct platform_device *pdev)
goto err3;
}
- err = sysfs_create_file(&dvfs_dev->kobj, &dev_attr_down_threshold.attr);
- if (err) {
- printk(KERN_ERR
- "DVFS: Unable to register sysdev entry for DVFS");
- goto err3;
- }
-
- err = sysfs_create_file(&dvfs_dev->kobj, &dev_attr_down_count.attr);
- if (err) {
- printk(KERN_ERR
- "DVFS: Unable to register sysdev entry for DVFS");
- goto err3;
- }
-
/* Set the current working point. */
cpu_op_tbl = get_cpu_op(&cpu_op_nr);
old_op = 0;
diff --git a/arch/arm/plat-mxc/include/mach/esdhc.h b/arch/arm/plat-mxc/include/mach/esdhc.h
index 9ef53aba40f8..1862c70ac13d 100644
--- a/arch/arm/plat-mxc/include/mach/esdhc.h
+++ b/arch/arm/plat-mxc/include/mach/esdhc.h
@@ -25,6 +25,7 @@ struct esdhc_platform_data {
unsigned int always_present;
unsigned int support_18v;
unsigned int support_8bit;
+ unsigned int keep_power_at_suspend;
unsigned int delay_line;
int (*platform_pad_change)(int clock);
};
diff --git a/arch/arm/plat-mxc/include/mach/imx-uart.h b/arch/arm/plat-mxc/include/mach/imx-uart.h
index 15b1a6c03f94..21dcdaf29512 100644
--- a/arch/arm/plat-mxc/include/mach/imx-uart.h
+++ b/arch/arm/plat-mxc/include/mach/imx-uart.h
@@ -22,6 +22,7 @@
#define IMXUART_HAVE_RTSCTS (1<<0)
#define IMXUART_IRDA (1<<1)
#define IMXUART_USE_DCEDTE (1<<2)
+#define IMXUART_SDMA (1<<3)
struct imxuart_platform_data {
int (*init)(struct platform_device *pdev);
@@ -31,6 +32,8 @@ struct imxuart_platform_data {
unsigned int irda_inv_rx:1;
unsigned int irda_inv_tx:1;
unsigned short transceiver_delay;
+ unsigned int dma_req_rx;
+ unsigned int dma_req_tx;
};
#endif
diff --git a/arch/arm/plat-mxc/include/mach/ipu-v3.h b/arch/arm/plat-mxc/include/mach/ipu-v3.h
index 480b4ea338e7..dd18f36c3ff2 100644
--- a/arch/arm/plat-mxc/include/mach/ipu-v3.h
+++ b/arch/arm/plat-mxc/include/mach/ipu-v3.h
@@ -136,7 +136,12 @@ typedef union {
uint32_t out_width;
uint32_t out_height;
uint32_t out_pixel_fmt;
+ uint32_t outh_resize_ratio;
+ uint32_t outv_resize_ratio;
uint32_t csi;
+ uint32_t mipi_id;
+ uint32_t mipi_vc;
+ bool mipi_en;
} csi_prp_enc_mem;
struct {
uint32_t in_width;
@@ -163,10 +168,21 @@ typedef union {
uint32_t out_width;
uint32_t out_height;
uint32_t out_pixel_fmt;
+ uint32_t outh_resize_ratio;
+ uint32_t outv_resize_ratio;
bool graphics_combine_en;
bool global_alpha_en;
bool key_color_en;
+ uint32_t in_g_pixel_fmt;
+ uint8_t alpha;
+ uint32_t key_color;
+ bool alpha_chan_en;
+ ipu_motion_sel motion_sel;
+ enum v4l2_field field_fmt;
uint32_t csi;
+ uint32_t mipi_id;
+ uint32_t mipi_vc;
+ bool mipi_en;
} csi_prp_vf_mem;
struct {
uint32_t in_width;
diff --git a/arch/arm/plat-mxc/include/mach/mipi_csi2.h b/arch/arm/plat-mxc/include/mach/mipi_csi2.h
index b2660836c295..7679027a2770 100644
--- a/arch/arm/plat-mxc/include/mach/mipi_csi2.h
+++ b/arch/arm/plat-mxc/include/mach/mipi_csi2.h
@@ -24,32 +24,45 @@
#define CSI2_N_LANES (0x004/4)
#define CSI2_PHY_SHUTDOWNZ (0x008/4)
#define CSI2_DPHY_RSTZ (0x00c/4)
-#define CSI2_RESETN (0x010/4)
+#define CSI2_RESETN (0x010/4)
#define CSI2_PHY_STATE (0x014/4)
#define CSI2_DATA_IDS_1 (0x018/4)
#define CSI2_DATA_IDS_2 (0x01c/4)
-#define CSI2_ERR1 (0x020/4)
-#define CSI2_ERR2 (0x024/4)
-#define CSI2_MSK1 (0x028/4)
-#define CSI2_MSK2 (0x02c/4)
+#define CSI2_ERR1 (0x020/4)
+#define CSI2_ERR2 (0x024/4)
+#define CSI2_MSK1 (0x028/4)
+#define CSI2_MSK2 (0x02c/4)
#define CSI2_PHY_TST_CTRL0 (0x030/4)
#define CSI2_PHY_TST_CTRL1 (0x034/4)
#define CSI2_SFT_RESET (0xf00/4)
/* mipi data type */
-#define MIPI_DT_YUV422 0x1e
-#define MIPI_DT_RGB444 0x20
-#define MIPI_DT_RGB555 0x21
-#define MIPI_DT_RGB565 0x22
-#define MIPI_DT_RGB888 0x24
-#define MIPI_DT_RAW8 0x2a
-#define MIPI_DT_RAW10 0x2b
+#define MIPI_DT_YUV420 0x18 /* YYY.../UYVY.... */
+#define MIPI_DT_YUV420_LEGACY 0x1a /* UYY.../VYY... */
+#define MIPI_DT_YUV422 0x1e /* UYVY... */
+#define MIPI_DT_RGB444 0x20
+#define MIPI_DT_RGB555 0x21
+#define MIPI_DT_RGB565 0x22
+#define MIPI_DT_RGB666 0x23
+#define MIPI_DT_RGB888 0x24
+#define MIPI_DT_RAW6 0x28
+#define MIPI_DT_RAW7 0x29
+#define MIPI_DT_RAW8 0x2a
+#define MIPI_DT_RAW10 0x2b
+#define MIPI_DT_RAW12 0x2c
+#define MIPI_DT_RAW14 0x2d
struct mipi_csi2_info;
/* mipi csi2 API */
struct mipi_csi2_info *mipi_csi2_get_info(void);
+bool mipi_csi2_enable(struct mipi_csi2_info *info);
+
+bool mipi_csi2_disable(struct mipi_csi2_info *info);
+
+bool mipi_csi2_get_status(struct mipi_csi2_info *info);
+
int mipi_csi2_get_bind_ipu(struct mipi_csi2_info *info);
unsigned int mipi_csi2_get_bind_csi(struct mipi_csi2_info *info);
@@ -59,7 +72,7 @@ unsigned int mipi_csi2_get_virtual_channel(struct mipi_csi2_info *info);
unsigned int mipi_csi2_set_lanes(struct mipi_csi2_info *info);
unsigned int mipi_csi2_set_datatype(struct mipi_csi2_info *info,
- unsigned int datatype);
+ unsigned int datatype);
unsigned int mipi_csi2_get_datatype(struct mipi_csi2_info *info);
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index bc6515bb9494..b8ad52fac513 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -90,6 +90,8 @@ extern unsigned int system_rev;
board_is_rev(IMX_BOARD_REV_1))
#define board_is_mx6q_sabre_lite() (cpu_is_mx6q() && \
board_is_rev(IMX_BOARD_REV_2))
+#define board_is_mx6q_sabre_auto() (cpu_is_mx6q() && \
+ board_is_rev(IMX_BOARD_REV_3))
#endif
#ifndef __ASSEMBLY__
diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h
index 7859f113cd2c..2f9a7ad7a1aa 100644
--- a/arch/arm/plat-mxc/include/mach/uncompress.h
+++ b/arch/arm/plat-mxc/include/mach/uncompress.h
@@ -127,6 +127,9 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
case MACH_TYPE_MX6Q_SABRELITE:
uart_base = MX6Q_UART2_BASE_ADDR;
break;
+ case MACH_TYPE_MX6Q_SABREAUTO:
+ uart_base = MX6Q_UART4_BASE_ADDR;
+ break;
default:
break;
}
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index 7dd48b11ee4c..881969c36949 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -264,6 +264,8 @@ struct sdma_channel {
struct dma_async_tx_descriptor desc;
dma_cookie_t last_completed;
enum dma_status status;
+ unsigned int chn_count;
+ unsigned int chn_real_count;
};
#define IMX_DMA_SG_LOOP (1 << 0)
@@ -467,6 +469,7 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
struct sdma_buffer_descriptor *bd;
int i, error = 0;
+ sdmac->chn_real_count = 0;
/*
* non loop mode. Iterate over all descriptors, collect
* errors and call callback function
@@ -476,6 +479,7 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
if (bd->mode.status & (BD_DONE | BD_RROR))
error = -EIO;
+ sdmac->chn_real_count += bd->mode.count;
}
if (error)
@@ -483,9 +487,9 @@ static void mxc_sdma_handle_channel_normal(struct sdma_channel *sdmac)
else
sdmac->status = DMA_SUCCESS;
+ sdmac->last_completed = sdmac->desc.cookie;
if (sdmac->desc.callback)
sdmac->desc.callback(sdmac->desc.callback_param);
- sdmac->last_completed = sdmac->desc.cookie;
}
static void mxc_sdma_handle_channel(struct sdma_channel *sdmac)
@@ -903,6 +907,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
goto err_out;
}
+ sdmac->chn_count = 0;
for_each_sg(sgl, sg, sg_len, i) {
struct sdma_buffer_descriptor *bd = &sdmac->bd[i];
int param;
@@ -919,6 +924,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
}
bd->mode.count = count;
+ sdmac->chn_count += count;
if (sdmac->word_size > DMA_SLAVE_BUSWIDTH_4_BYTES) {
ret = -EINVAL;
@@ -1081,7 +1087,8 @@ static enum dma_status sdma_tx_status(struct dma_chan *chan,
last_used = chan->cookie;
- dma_set_tx_state(txstate, sdmac->last_completed, last_used, 0);
+ dma_set_tx_state(txstate, sdmac->last_completed, last_used,
+ sdmac->chn_count - sdmac->chn_real_count);
return sdmac->status;
}
diff --git a/drivers/media/video/mxc/capture/Kconfig b/drivers/media/video/mxc/capture/Kconfig
index 93d56057e31c..c9f3e3bcaec1 100644
--- a/drivers/media/video/mxc/capture/Kconfig
+++ b/drivers/media/video/mxc/capture/Kconfig
@@ -84,6 +84,14 @@ config MXC_CAMERA_OV5640_MIPI
---help---
If you plan to use the ov5640 Camera with mipi interface in your MXC system, say Y here.
+config MXC_CAMERA_OV8820_MIPI
+ tristate "OmniVision ov8820 camera support using mipi"
+ depends on !VIDEO_MXC_EMMA_CAMERA
+ depends on ARCH_MX6Q
+ select MXC_MIPI_CSI2 if ARCH_MX6Q
+ ---help---
+ If you plan to use the ov8820 Camera with mipi interface in your MXC system, say Y here.
+
config MXC_CAMERA_OV5642
tristate "OmniVision ov5642 camera support"
depends on !VIDEO_MXC_EMMA_CAMERA
diff --git a/drivers/media/video/mxc/capture/Makefile b/drivers/media/video/mxc/capture/Makefile
index d8633307a1dc..8dab021fa64f 100644
--- a/drivers/media/video/mxc/capture/Makefile
+++ b/drivers/media/video/mxc/capture/Makefile
@@ -40,6 +40,9 @@ obj-$(CONFIG_MXC_CAMERA_OV5640) += ov5640_camera.o
ov5640_camera_mipi-objs := ov5640_mipi.o sensor_clock.o
obj-$(CONFIG_MXC_CAMERA_OV5640_MIPI) += ov5640_camera_mipi.o
+ov8820_camera_mipi-objs := ov8820_mipi.o sensor_clock.o
+obj-$(CONFIG_MXC_CAMERA_OV8820_MIPI) += ov8820_camera_mipi.o
+
ov5642_camera-objs := ov5642.o sensor_clock.o
obj-$(CONFIG_MXC_CAMERA_OV5642) += ov5642_camera.o
diff --git a/drivers/media/video/mxc/capture/ipu_csi_enc.c b/drivers/media/video/mxc/capture/ipu_csi_enc.c
index 71fd113df9e9..0261a7ecd212 100644
--- a/drivers/media/video/mxc/capture/ipu_csi_enc.c
+++ b/drivers/media/video/mxc/capture/ipu_csi_enc.c
@@ -131,15 +131,34 @@ static int csi_enc_setup(cam_data *cam)
#ifdef CONFIG_MXC_MIPI_CSI2
mipi_csi2_info = mipi_csi2_get_info();
- ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
- csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
- if (cam->ipu == ipu_get_soc(ipu_id) && cam->csi == csi_id) {
- params.csi_mem.mipi_en = true;
- params.csi_mem.mipi_vc = mipi_csi2_get_virtual_channel(mipi_csi2_info);
- params.csi_mem.mipi_id = mipi_csi2_get_datatype(mipi_csi2_info);
-
- mipi_csi2_pixelclk_enable(mipi_csi2_info);
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id) {
+ params.csi_mem.mipi_en = true;
+ params.csi_mem.mipi_vc =
+ mipi_csi2_get_virtual_channel(mipi_csi2_info);
+ params.csi_mem.mipi_id =
+ mipi_csi2_get_datatype(mipi_csi2_info);
+
+ mipi_csi2_pixelclk_enable(mipi_csi2_info);
+ } else {
+ params.csi_mem.mipi_en = false;
+ params.csi_mem.mipi_vc = 0;
+ params.csi_mem.mipi_id = 0;
+ }
+ } else {
+ params.csi_mem.mipi_en = false;
+ params.csi_mem.mipi_vc = 0;
+ params.csi_mem.mipi_id = 0;
+ }
+ } else {
+ printk(KERN_ERR "Fail to get mipi_csi2_info!\n");
+ return -EPERM;
}
#endif
@@ -275,13 +294,23 @@ static int csi_enc_disabling_tasks(void *private)
cam->dummy_frame.paddress);
cam->dummy_frame.vaddress = 0;
}
+
#ifdef CONFIG_MXC_MIPI_CSI2
mipi_csi2_info = mipi_csi2_get_info();
- ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
- csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
- if (cam->ipu == ipu_get_soc(ipu_id) && cam->csi == csi_id)
- mipi_csi2_pixelclk_disable(mipi_csi2_info);
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id)
+ mipi_csi2_pixelclk_disable(mipi_csi2_info);
+ }
+ } else {
+ printk(KERN_ERR "Fail to get mipi_csi2_info!\n");
+ return -EPERM;
+ }
#endif
ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_ENC, cam->csi, false, false);
diff --git a/drivers/media/video/mxc/capture/ipu_prp_enc.c b/drivers/media/video/mxc/capture/ipu_prp_enc.c
index 3ead6f1900a2..6710cba5d817 100644
--- a/drivers/media/video/mxc/capture/ipu_prp_enc.c
+++ b/drivers/media/video/mxc/capture/ipu_prp_enc.c
@@ -20,7 +20,10 @@
*/
#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
#include <linux/ipu.h>
+#include <mach/devices-common.h>
+#include <mach/mipi_csi2.h>
#include "mxc_v4l2_capture.h"
#include "ipu_prp_sw.h"
@@ -68,6 +71,11 @@ static int prp_enc_setup(cam_data *cam)
ipu_channel_params_t enc;
int err = 0;
dma_addr_t dummy = 0xdeadbeaf;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
CAMERA_TRACE("In prp_enc_setup\n");
if (!cam) {
@@ -123,6 +131,39 @@ static int prp_enc_setup(cam_data *cam)
return -EINVAL;
}
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id) {
+ enc.csi_prp_enc_mem.mipi_en = true;
+ enc.csi_prp_enc_mem.mipi_vc =
+ mipi_csi2_get_virtual_channel(mipi_csi2_info);
+ enc.csi_prp_enc_mem.mipi_id =
+ mipi_csi2_get_datatype(mipi_csi2_info);
+
+ mipi_csi2_pixelclk_enable(mipi_csi2_info);
+ } else {
+ enc.csi_prp_enc_mem.mipi_en = false;
+ enc.csi_prp_enc_mem.mipi_vc = 0;
+ enc.csi_prp_enc_mem.mipi_id = 0;
+ }
+ } else {
+ enc.csi_prp_enc_mem.mipi_en = false;
+ enc.csi_prp_enc_mem.mipi_vc = 0;
+ enc.csi_prp_enc_mem.mipi_id = 0;
+ }
+ } else {
+ printk(KERN_ERR "Fail to get mipi_csi2_info!\n");
+ return -EPERM;
+ }
+#endif
+
err = ipu_init_channel(cam->ipu, CSI_PRP_ENC_MEM, &enc);
if (err != 0) {
printk(KERN_ERR "ipu_init_channel %d\n", err);
@@ -383,6 +424,11 @@ static int prp_enc_disabling_tasks(void *private)
{
cam_data *cam = (cam_data *) private;
int err = 0;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
if (cam->rotation >= IPU_ROTATE_90_RIGHT) {
ipu_free_irq(cam->ipu, IPU_IRQ_PRP_ENC_ROT_OUT_EOF, cam);
@@ -410,6 +456,25 @@ static int prp_enc_disabling_tasks(void *private)
cam->dummy_frame.paddress);
cam->dummy_frame.vaddress = 0;
}
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id)
+ mipi_csi2_pixelclk_disable(mipi_csi2_info);
+ }
+ } else {
+ printk(KERN_ERR "Fail to get mipi_csi2_info!\n");
+ return -EPERM;
+ }
+#endif
+
ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_ENC, cam->csi, false, false);
return err;
diff --git a/drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c b/drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c
index 6e101748c576..121b328ad18b 100644
--- a/drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c
+++ b/drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c
@@ -24,6 +24,7 @@
#include <linux/ipu.h>
#include <linux/mxcfb.h>
#include <mach/hardware.h>
+#include <mach/mipi_csi2.h>
#include "mxc_v4l2_capture.h"
#include "ipu_prp_sw.h"
@@ -49,6 +50,11 @@ static int prpvf_start(void *private)
u32 size = 2, temp = 0;
int err = 0, i = 0;
short *tmp, color;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
if (!cam) {
printk(KERN_ERR "private is NULL\n");
@@ -132,6 +138,39 @@ static int prpvf_start(void *private)
vf.csi_prp_vf_mem.out_pixel_fmt = vf_out_format;
size = cam->win.w.width * cam->win.w.height * size;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id) {
+ vf.csi_prp_vf_mem.mipi_en = true;
+ vf.csi_prp_vf_mem.mipi_vc =
+ mipi_csi2_get_virtual_channel(mipi_csi2_info);
+ vf.csi_prp_vf_mem.mipi_id =
+ mipi_csi2_get_datatype(mipi_csi2_info);
+
+ mipi_csi2_pixelclk_enable(mipi_csi2_info);
+ } else {
+ vf.csi_prp_vf_mem.mipi_en = false;
+ vf.csi_prp_vf_mem.mipi_vc = 0;
+ vf.csi_prp_vf_mem.mipi_id = 0;
+ }
+ } else {
+ vf.csi_prp_vf_mem.mipi_en = false;
+ vf.csi_prp_vf_mem.mipi_vc = 0;
+ vf.csi_prp_vf_mem.mipi_id = 0;
+ }
+ } else {
+ printk(KERN_ERR "Fail to get mipi_csi2_info!\n");
+ return -EPERM;
+ }
+#endif
+
err = ipu_init_channel(cam->ipu, CSI_PRP_VF_MEM, &vf);
if (err != 0)
goto out_5;
@@ -320,6 +359,11 @@ static int prpvf_stop(void *private)
int err = 0, i = 0;
struct fb_info *fbi = NULL;
struct fb_var_screeninfo fbvar;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
if (cam->overlay_active == false)
return 0;
@@ -363,6 +407,24 @@ static int prpvf_stop(void *private)
fbvar.activate |= FB_ACTIVATE_FORCE;
fb_set_var(fbi, &fbvar);
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id)
+ mipi_csi2_pixelclk_disable(mipi_csi2_info);
+ }
+ } else {
+ printk(KERN_ERR "Fail to get mipi_csi2_info!\n");
+ return -EPERM;
+ }
+#endif
+
ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_VF, cam->csi, false, false);
if (cam->vf_bufs_vaddr[0]) {
diff --git a/drivers/media/video/mxc/capture/ipu_prp_vf_sdc_bg.c b/drivers/media/video/mxc/capture/ipu_prp_vf_sdc_bg.c
index ef7f33c27a65..99fa4eaecfac 100644
--- a/drivers/media/video/mxc/capture/ipu_prp_vf_sdc_bg.c
+++ b/drivers/media/video/mxc/capture/ipu_prp_vf_sdc_bg.c
@@ -21,6 +21,7 @@
#include <linux/dma-mapping.h>
#include <linux/fb.h>
#include <linux/ipu.h>
+#include <mach/mipi_csi2.h>
#include "mxc_v4l2_capture.h"
#include "ipu_prp_sw.h"
@@ -87,6 +88,11 @@ static int prpvf_start(void *private)
u32 offset;
u32 bpp, size = 3;
int err = 0;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
if (!cam) {
printk(KERN_ERR "private is NULL\n");
@@ -137,6 +143,39 @@ static int prpvf_start(void *private)
vf.csi_prp_vf_mem.out_pixel_fmt = format;
size = cam->win.w.width * cam->win.w.height * size;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id) {
+ vf.csi_prp_vf_mem.mipi_en = true;
+ vf.csi_prp_vf_mem.mipi_vc =
+ mipi_csi2_get_virtual_channel(mipi_csi2_info);
+ vf.csi_prp_vf_mem.mipi_id =
+ mipi_csi2_get_datatype(mipi_csi2_info);
+
+ mipi_csi2_pixelclk_enable(mipi_csi2_info);
+ } else {
+ vf.csi_prp_vf_mem.mipi_en = false;
+ vf.csi_prp_vf_mem.mipi_vc = 0;
+ vf.csi_prp_vf_mem.mipi_id = 0;
+ }
+ } else {
+ vf.csi_prp_vf_mem.mipi_en = false;
+ vf.csi_prp_vf_mem.mipi_vc = 0;
+ vf.csi_prp_vf_mem.mipi_id = 0;
+ }
+ } else {
+ printk(KERN_ERR "Fail to get mipi_csi2_info!\n");
+ return -EPERM;
+ }
+#endif
+
err = ipu_init_channel(cam->ipu, CSI_PRP_VF_MEM, &vf);
if (err != 0)
goto out_4;
@@ -304,6 +343,11 @@ static int prpvf_start(void *private)
static int prpvf_stop(void *private)
{
cam_data *cam = (cam_data *) private;
+#ifdef CONFIG_MXC_MIPI_CSI2
+ void *mipi_csi2_info;
+ int ipu_id;
+ int csi_id;
+#endif
if (cam->overlay_active == false)
return 0;
@@ -316,6 +360,25 @@ static int prpvf_stop(void *private)
ipu_disable_channel(cam->ipu, MEM_ROT_VF_MEM, true);
ipu_uninit_channel(cam->ipu, CSI_PRP_VF_MEM);
ipu_uninit_channel(cam->ipu, MEM_ROT_VF_MEM);
+
+#ifdef CONFIG_MXC_MIPI_CSI2
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ if (mipi_csi2_info) {
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ ipu_id = mipi_csi2_get_bind_ipu(mipi_csi2_info);
+ csi_id = mipi_csi2_get_bind_csi(mipi_csi2_info);
+
+ if (cam->ipu == ipu_get_soc(ipu_id)
+ && cam->csi == csi_id)
+ mipi_csi2_pixelclk_disable(mipi_csi2_info);
+ }
+ } else {
+ printk(KERN_ERR "Fail to get mipi_csi2_info!\n");
+ return -EPERM;
+ }
+#endif
+
ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_VF, cam->csi, false, false);
if (cam->vf_bufs_vaddr[0]) {
diff --git a/drivers/media/video/mxc/capture/ov3640.c b/drivers/media/video/mxc/capture/ov3640.c
index 24e12d78b1aa..e10190687d80 100644
--- a/drivers/media/video/mxc/capture/ov3640.c
+++ b/drivers/media/video/mxc/capture/ov3640.c
@@ -1391,6 +1391,9 @@ static int ov3640_probe(struct i2c_client *client,
gpo_regulator = NULL;
}
+ if (plat_data->io_init)
+ plat_data->io_init();
+
if (plat_data->pwdn)
plat_data->pwdn(0);
diff --git a/drivers/media/video/mxc/capture/ov5640.c b/drivers/media/video/mxc/capture/ov5640.c
index 69bbd2a678d5..6ed73ca85645 100644
--- a/drivers/media/video/mxc/capture/ov5640.c
+++ b/drivers/media/video/mxc/capture/ov5640.c
@@ -1424,6 +1424,9 @@ static int ov5640_probe(struct i2c_client *client,
analog_regulator = NULL;
}
+ if (plat_data->io_init)
+ plat_data->io_init();
+
if (plat_data->pwdn)
plat_data->pwdn(0);
diff --git a/drivers/media/video/mxc/capture/ov5640_mipi.c b/drivers/media/video/mxc/capture/ov5640_mipi.c
index 7618ab93019d..53b841956c46 100644
--- a/drivers/media/video/mxc/capture/ov5640_mipi.c
+++ b/drivers/media/video/mxc/capture/ov5640_mipi.c
@@ -102,251 +102,619 @@ struct sensor {
} ov5640_data;
static struct reg_value ov5640_setting_30fps_VGA_640_480[] = {
- {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0}, {0x3103, 0x03, 0, 0},
- {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0}, {0x3630, 0x2e, 0, 0},
- {0x3632, 0xe2, 0, 0}, {0x3633, 0x23, 0, 0}, {0x3634, 0x44, 0, 0},
+ {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
+ {0x3034, 0x18, 0, 0}, {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0},
+ {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
+ {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
{0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
{0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
{0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
- {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x04, 0, 0},
- {0x3601, 0x22, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a18, 0x00, 0, 0},
- {0x3a19, 0xf8, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3500, 0x00, 0, 0},
- {0x3501, 0x01, 0, 0}, {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0},
- {0x350b, 0x3f, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
- {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x3612, 0x49, 0, 0},
- {0x3618, 0x00, 0, 0}, {0x3034, 0x18, 0, 0}, {0x3035, 0x41, 0, 0},
- {0x3036, 0xa8, 0, 0}, {0x3708, 0x66, 0, 0}, {0x3709, 0x52, 0, 0},
- {0x370c, 0x03, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
- {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
- {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 5}, {0x3807, 0x9f, 0, 0},
- {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
- {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x58, 0, 0},
- {0x380e, 0x01, 0, 0}, {0x380f, 0xf0, 0, 0}, {0x3810, 0x00, 0, 0},
- {0x3811, 0x04, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x02, 0, 0},
- {0x3814, 0x71, 0, 0}, {0x3815, 0x35, 0, 0}, {0x3820, 0x40, 0, 0},
- {0x3821, 0x01, 0, 0}, {0x3824, 0x01, 0, 0}, {0x3a02, 0x01, 0, 0},
- {0x3a03, 0xf0, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbe, 0, 0},
- {0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x74, 0, 0}, {0x3a0e, 0x01, 0, 0},
- {0x3a0d, 0x01, 0, 0}, {0x3a14, 0x01, 0, 0}, {0x3a15, 0xf0, 0, 0},
- {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4300, 0x3f, 0, 0},
- {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x4713, 0x02, 0, 0},
- {0x4750, 0x00, 0, 0}, {0x4751, 0x00, 0, 0}, {0x5000, 0x07, 0, 0},
- {0x5001, 0x23, 0, 0}, {0x501d, 0x00, 0, 0}, {0x501f, 0x00, 0, 0},
- {0x5684, 0x10, 0, 0}, {0x5685, 0xa0, 0, 0}, {0x5686, 0x0c, 0, 0},
- {0x5687, 0x78, 0, 0}, {0x5a00, 0x08, 0, 0}, {0x5a21, 0x00, 0, 0},
- {0x5a24, 0x00, 0, 0}, {0x4837, 0x0a, 0, 0}, {0x3037, 0x01, 0, 0},
- {0x4800, 0x14, 0, 5}, {0x483b, 0xff, 0, 0}, {0x3007, 0xf7, 0, 0},
- {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0}, {0x3a1b, 0x30, 0, 0},
- {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x14, 0, 0},
+ {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
+ {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
+ {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
+ {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
{0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
- {0x3c06, 0x1c, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
- {0x3c0a, 0x9c, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0b, 0x40, 0, 0},
- {0x5180, 0xff, 0, 0}, {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0},
- {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
- {0x5186, 0x09, 0, 0}, {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0},
- {0x5189, 0x75, 0, 0}, {0x518a, 0x54, 0, 0}, {0x518b, 0xe0, 0, 0},
- {0x518c, 0xb2, 0, 0}, {0x518d, 0x42, 0, 0}, {0x518e, 0x3d, 0, 0},
- {0x518f, 0x56, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
- {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
- {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
- {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
- {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
- {0x519e, 0x38, 0, 0}, {0x5381, 0x1c, 0, 0}, {0x5382, 0x5a, 0, 0},
- {0x5383, 0x06, 0, 5}, {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0},
- {0x5386, 0x88, 0, 0}, {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0},
- {0x5389, 0x10, 0, 0}, {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0},
- {0x5300, 0x08, 0, 0}, {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0},
- {0x5303, 0x00, 0, 0}, {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0},
- {0x5306, 0x08, 0, 0}, {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0},
- {0x530a, 0x30, 0, 0}, {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0},
- {0x4814, 0x00, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0x00, 0, 10},
- {0x483b, 0x33, 0, 0}, {0x3007, 0xff, 0, 10},
+ {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x4837, 0x0a, 0, 0}, {0x4800, 0x04, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
+ {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
+ {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
+ {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0}, {0x5189, 0x75, 0, 0},
+ {0x518a, 0x54, 0, 0}, {0x518b, 0xe0, 0, 0}, {0x518c, 0xb2, 0, 0},
+ {0x518d, 0x42, 0, 0}, {0x518e, 0x3d, 0, 0}, {0x518f, 0x56, 0, 0},
+ {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0},
+ {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0},
+ {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0},
+ {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0}, {0x519e, 0x38, 0, 0},
+ {0x5381, 0x1e, 0, 0}, {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0},
+ {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0},
+ {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0},
+ {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0},
+ {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0},
+ {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0},
+ {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0},
+ {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0},
+ {0x5481, 0x08, 0, 0}, {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0},
+ {0x5484, 0x51, 0, 0}, {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0},
+ {0x5487, 0x7d, 0, 0}, {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0},
+ {0x548a, 0x9a, 0, 0}, {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0},
+ {0x548d, 0xcd, 0, 0}, {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0},
+ {0x5490, 0x1d, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x10, 0, 0}, {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0},
+ {0x558b, 0xf8, 0, 0}, {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0},
+ {0x5802, 0x0f, 0, 0}, {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0},
+ {0x5805, 0x26, 0, 0}, {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0},
+ {0x5808, 0x05, 0, 0}, {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0},
+ {0x580b, 0x0d, 0, 0}, {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0},
+ {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0},
+ {0x5811, 0x09, 0, 0}, {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0},
+ {0x5814, 0x00, 0, 0}, {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0},
+ {0x5817, 0x08, 0, 0}, {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0},
+ {0x581a, 0x05, 0, 0}, {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0},
+ {0x581d, 0x0e, 0, 0}, {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0},
+ {0x5820, 0x11, 0, 0}, {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0},
+ {0x5823, 0x28, 0, 0}, {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0},
+ {0x5826, 0x08, 0, 0}, {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0},
+ {0x5829, 0x26, 0, 0}, {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0},
+ {0x582c, 0x24, 0, 0}, {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0},
+ {0x582f, 0x22, 0, 0}, {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0},
+ {0x5832, 0x24, 0, 0}, {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0},
+ {0x5835, 0x22, 0, 0}, {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0},
+ {0x5838, 0x44, 0, 0}, {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0},
+ {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0},
+ {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0},
+ {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0},
+ {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0},
};
static struct reg_value ov5640_setting_30fps_QVGA_320_240[] = {
- {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0}, {0x3103, 0x03, 0, 0},
- {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0}, {0x3630, 0x2e, 0, 0},
- {0x3632, 0xe2, 0, 0}, {0x3633, 0x23, 0, 0}, {0x3634, 0x44, 0, 0},
+ {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
+ {0x3034, 0x18, 0, 0}, {0x3035, 0x14, 0, 0}, {0x3036, 0x38, 0, 0},
+ {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
+ {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
{0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
{0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
{0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
- {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x04, 0, 0},
- {0x3601, 0x22, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a18, 0x00, 0, 0},
- {0x3a19, 0xf8, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3500, 0x00, 0, 0},
- {0x3501, 0x01, 0, 0}, {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0},
- {0x350b, 0x3f, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
- {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x3612, 0x49, 0, 0},
- {0x3618, 0x00, 0, 0}, {0x3034, 0x18, 0, 0}, {0x3035, 0x41, 0, 0},
- {0x3036, 0xa8, 0, 0}, {0x3708, 0x24, 0, 0}, {0x3709, 0x52, 0, 0},
- {0x370c, 0x03, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
- {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
- {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 5}, {0x3807, 0x9f, 0, 0},
+ {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
+ {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
+ {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
+ {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
+ {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
+ {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
{0x3808, 0x01, 0, 0}, {0x3809, 0x40, 0, 0}, {0x380a, 0x00, 0, 0},
- {0x380b, 0xf0, 0, 0}, {0x380c, 0x0a, 0, 0}, {0x380d, 0xda, 0, 0},
- {0x380e, 0x00, 0, 0}, {0x380f, 0xfc, 0, 0}, {0x3810, 0x00, 0, 0},
- {0x3811, 0x04, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x02, 0, 0},
- {0x3814, 0xf1, 0, 0}, {0x3815, 0xf1, 0, 0}, {0x3820, 0x41, 0, 0},
- {0x3821, 0x01, 0, 0}, {0x3824, 0x01, 0, 0}, {0x3a02, 0x01, 0, 0},
- {0x3a03, 0xf0, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x2e, 0, 0},
- {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xfc, 0, 0}, {0x3a0e, 0x01, 0, 0},
- {0x3a0d, 0x01, 0, 0}, {0x3a14, 0x01, 0, 0}, {0x3a15, 0xf0, 0, 0},
- {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4300, 0x3f, 0, 0},
- {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x4713, 0x02, 0, 0},
- {0x4750, 0x00, 0, 0}, {0x4751, 0x00, 0, 0}, {0x5000, 0x07, 0, 0},
- {0x5001, 0x23, 0, 0}, {0x501d, 0x00, 0, 0}, {0x501f, 0x00, 0, 0},
- {0x5684, 0x10, 0, 0}, {0x5685, 0xa0, 0, 0}, {0x5686, 0x0c, 0, 0},
- {0x5687, 0x78, 0, 0}, {0x5a00, 0x08, 0, 0}, {0x5a21, 0x00, 0, 0},
- {0x5a24, 0x00, 0, 0}, {0x4837, 0x0a, 0, 0}, {0x3037, 0x01, 0, 0},
- {0x4800, 0x14, 0, 5}, {0x483b, 0xff, 0, 0}, {0x3007, 0xf7, 0, 0},
- {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0}, {0x3a1b, 0x30, 0, 0},
- {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x14, 0, 0},
+ {0x380b, 0xf0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x4837, 0x0a, 0, 0}, {0x4800, 0x04, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
+ {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
+ {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
+ {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0}, {0x5189, 0x75, 0, 0},
+ {0x518a, 0x54, 0, 0}, {0x518b, 0xe0, 0, 0}, {0x518c, 0xb2, 0, 0},
+ {0x518d, 0x42, 0, 0}, {0x518e, 0x3d, 0, 0}, {0x518f, 0x56, 0, 0},
+ {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0},
+ {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0},
+ {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0},
+ {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0}, {0x519e, 0x38, 0, 0},
+ {0x5381, 0x1e, 0, 0}, {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0},
+ {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0},
+ {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0},
+ {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0},
+ {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0},
+ {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0},
+ {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0},
+ {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0},
+ {0x5481, 0x08, 0, 0}, {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0},
+ {0x5484, 0x51, 0, 0}, {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0},
+ {0x5487, 0x7d, 0, 0}, {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0},
+ {0x548a, 0x9a, 0, 0}, {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0},
+ {0x548d, 0xcd, 0, 0}, {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0},
+ {0x5490, 0x1d, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x10, 0, 0}, {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0},
+ {0x558b, 0xf8, 0, 0}, {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0},
+ {0x5802, 0x0f, 0, 0}, {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0},
+ {0x5805, 0x26, 0, 0}, {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0},
+ {0x5808, 0x05, 0, 0}, {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0},
+ {0x580b, 0x0d, 0, 0}, {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0},
+ {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0},
+ {0x5811, 0x09, 0, 0}, {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0},
+ {0x5814, 0x00, 0, 0}, {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0},
+ {0x5817, 0x08, 0, 0}, {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0},
+ {0x581a, 0x05, 0, 0}, {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0},
+ {0x581d, 0x0e, 0, 0}, {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0},
+ {0x5820, 0x11, 0, 0}, {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0},
+ {0x5823, 0x28, 0, 0}, {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0},
+ {0x5826, 0x08, 0, 0}, {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0},
+ {0x5829, 0x26, 0, 0}, {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0},
+ {0x582c, 0x24, 0, 0}, {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0},
+ {0x582f, 0x22, 0, 0}, {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0},
+ {0x5832, 0x24, 0, 0}, {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0},
+ {0x5835, 0x22, 0, 0}, {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0},
+ {0x5838, 0x44, 0, 0}, {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0},
+ {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0},
+ {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0},
+ {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0},
+ {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_NTSC_720_480[] = {
+ {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
+ {0x3034, 0x18, 0, 0}, {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0},
+ {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
+ {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
+ {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
+ {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
+ {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
+ {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
+ {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
+ {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
+ {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
{0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
- {0x3c06, 0x1c, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
- {0x3c0a, 0x9c, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0b, 0x40, 0, 0},
- {0x5180, 0xff, 0, 0}, {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0},
- {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
- {0x5186, 0x09, 0, 0}, {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0},
- {0x5189, 0x75, 0, 0}, {0x518a, 0x54, 0, 0}, {0x518b, 0xe0, 0, 0},
- {0x518c, 0xb2, 0, 0}, {0x518d, 0x42, 0, 0}, {0x518e, 0x3d, 0, 0},
- {0x518f, 0x56, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
- {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
- {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
- {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
- {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
- {0x519e, 0x38, 0, 0}, {0x5381, 0x1c, 0, 0}, {0x5382, 0x5a, 0, 0},
- {0x5383, 0x06, 0, 5}, {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0},
- {0x5386, 0x88, 0, 0}, {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0},
- {0x5389, 0x10, 0, 0}, {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0},
- {0x5300, 0x08, 0, 0}, {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0},
- {0x5303, 0x00, 0, 0}, {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0},
- {0x5306, 0x08, 0, 0}, {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0},
- {0x530a, 0x30, 0, 0}, {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0},
- {0x4814, 0x00, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0x00, 0, 10},
- {0x483b, 0x33, 0, 0}, {0x3007, 0xff, 0, 10},
+ {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x01, 0, 0},
+ {0x380b, 0xe0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x3c, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x4837, 0x0a, 0, 0}, {0x4800, 0x04, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
+ {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
+ {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
+ {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0}, {0x5189, 0x75, 0, 0},
+ {0x518a, 0x54, 0, 0}, {0x518b, 0xe0, 0, 0}, {0x518c, 0xb2, 0, 0},
+ {0x518d, 0x42, 0, 0}, {0x518e, 0x3d, 0, 0}, {0x518f, 0x56, 0, 0},
+ {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0},
+ {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0},
+ {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0},
+ {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0}, {0x519e, 0x38, 0, 0},
+ {0x5381, 0x1e, 0, 0}, {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0},
+ {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0},
+ {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0},
+ {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0},
+ {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0},
+ {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0},
+ {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0},
+ {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0},
+ {0x5481, 0x08, 0, 0}, {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0},
+ {0x5484, 0x51, 0, 0}, {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0},
+ {0x5487, 0x7d, 0, 0}, {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0},
+ {0x548a, 0x9a, 0, 0}, {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0},
+ {0x548d, 0xcd, 0, 0}, {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0},
+ {0x5490, 0x1d, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x10, 0, 0}, {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0},
+ {0x558b, 0xf8, 0, 0}, {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0},
+ {0x5802, 0x0f, 0, 0}, {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0},
+ {0x5805, 0x26, 0, 0}, {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0},
+ {0x5808, 0x05, 0, 0}, {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0},
+ {0x580b, 0x0d, 0, 0}, {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0},
+ {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0},
+ {0x5811, 0x09, 0, 0}, {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0},
+ {0x5814, 0x00, 0, 0}, {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0},
+ {0x5817, 0x08, 0, 0}, {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0},
+ {0x581a, 0x05, 0, 0}, {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0},
+ {0x581d, 0x0e, 0, 0}, {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0},
+ {0x5820, 0x11, 0, 0}, {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0},
+ {0x5823, 0x28, 0, 0}, {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0},
+ {0x5826, 0x08, 0, 0}, {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0},
+ {0x5829, 0x26, 0, 0}, {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0},
+ {0x582c, 0x24, 0, 0}, {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0},
+ {0x582f, 0x22, 0, 0}, {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0},
+ {0x5832, 0x24, 0, 0}, {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0},
+ {0x5835, 0x22, 0, 0}, {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0},
+ {0x5838, 0x44, 0, 0}, {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0},
+ {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0},
+ {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0},
+ {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0},
+ {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0},
+};
+
+static struct reg_value ov5640_setting_30fps_PAL_720_576[] = {
+ {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
+ {0x3034, 0x18, 0, 0}, {0x3035, 0x12, 0, 0}, {0x3036, 0x38, 0, 0},
+ {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
+ {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
+ {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
+ {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
+ {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
+ {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
+ {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
+ {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
+ {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
+ {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
+ {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x04, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9b, 0, 0},
+ {0x3808, 0x02, 0, 0}, {0x3809, 0xd0, 0, 0}, {0x380a, 0x02, 0, 0},
+ {0x380b, 0x40, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x68, 0, 0},
+ {0x380e, 0x03, 0, 0}, {0x380f, 0xd8, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x38, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x06, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x4837, 0x0a, 0, 0}, {0x4800, 0x04, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5000, 0xa7, 0, 0}, {0x5001, 0xa3, 0, 0}, {0x5180, 0xff, 0, 0},
+ {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
+ {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
+ {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0}, {0x5189, 0x75, 0, 0},
+ {0x518a, 0x54, 0, 0}, {0x518b, 0xe0, 0, 0}, {0x518c, 0xb2, 0, 0},
+ {0x518d, 0x42, 0, 0}, {0x518e, 0x3d, 0, 0}, {0x518f, 0x56, 0, 0},
+ {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0},
+ {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0},
+ {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0},
+ {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0}, {0x519e, 0x38, 0, 0},
+ {0x5381, 0x1e, 0, 0}, {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0},
+ {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0},
+ {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0},
+ {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0},
+ {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0},
+ {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0},
+ {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0},
+ {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0},
+ {0x5481, 0x08, 0, 0}, {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0},
+ {0x5484, 0x51, 0, 0}, {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0},
+ {0x5487, 0x7d, 0, 0}, {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0},
+ {0x548a, 0x9a, 0, 0}, {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0},
+ {0x548d, 0xcd, 0, 0}, {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0},
+ {0x5490, 0x1d, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x10, 0, 0}, {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0},
+ {0x558b, 0xf8, 0, 0}, {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0},
+ {0x5802, 0x0f, 0, 0}, {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0},
+ {0x5805, 0x26, 0, 0}, {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0},
+ {0x5808, 0x05, 0, 0}, {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0},
+ {0x580b, 0x0d, 0, 0}, {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0},
+ {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0},
+ {0x5811, 0x09, 0, 0}, {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0},
+ {0x5814, 0x00, 0, 0}, {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0},
+ {0x5817, 0x08, 0, 0}, {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0},
+ {0x581a, 0x05, 0, 0}, {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0},
+ {0x581d, 0x0e, 0, 0}, {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0},
+ {0x5820, 0x11, 0, 0}, {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0},
+ {0x5823, 0x28, 0, 0}, {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0},
+ {0x5826, 0x08, 0, 0}, {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0},
+ {0x5829, 0x26, 0, 0}, {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0},
+ {0x582c, 0x24, 0, 0}, {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0},
+ {0x582f, 0x22, 0, 0}, {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0},
+ {0x5832, 0x24, 0, 0}, {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0},
+ {0x5835, 0x22, 0, 0}, {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0},
+ {0x5838, 0x44, 0, 0}, {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0},
+ {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0},
+ {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0},
+ {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0},
+ {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0},
};
static struct reg_value ov5640_setting_30fps_720P_1280_720[] = {
- {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0}, {0x3103, 0x03, 0, 0},
- {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0}, {0x3630, 0x2e, 0, 0},
- {0x3632, 0xe2, 0, 0}, {0x3633, 0x23, 0, 0}, {0x3634, 0x44, 0, 0},
+ {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
+ {0x3034, 0x18, 0, 0}, {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0},
+ {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
+ {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
{0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
{0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
{0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
- {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x04, 0, 0},
- {0x3601, 0x22, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a18, 0x00, 0, 0},
- {0x3a19, 0xf8, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3500, 0x00, 0, 0},
- {0x3501, 0x01, 0, 0}, {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0},
- {0x350b, 0x3f, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
- {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x3612, 0x49, 0, 0},
- {0x3618, 0x00, 0, 0}, {0x3034, 0x18, 0, 0}, {0x3035, 0x41, 0, 0},
- {0x3036, 0xa8, 0, 0}, {0x3708, 0x62, 0, 0}, {0x3709, 0x52, 0, 0},
- {0x370c, 0x03, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
+ {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
+ {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
+ {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
+ {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
+ {0x3c06, 0x00, 0, 0}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x41, 0, 0}, {0x3821, 0x07, 0, 0}, {0x3814, 0x31, 0, 0},
+ {0x3815, 0x31, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
{0x3802, 0x00, 0, 0}, {0x3803, 0xfa, 0, 0}, {0x3804, 0x0a, 0, 0},
- {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 5}, {0x3807, 0xa9, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x06, 0, 0}, {0x3807, 0xa9, 0, 0},
{0x3808, 0x05, 0, 0}, {0x3809, 0x00, 0, 0}, {0x380a, 0x02, 0, 0},
{0x380b, 0xd0, 0, 0}, {0x380c, 0x07, 0, 0}, {0x380d, 0x64, 0, 0},
{0x380e, 0x02, 0, 0}, {0x380f, 0xe4, 0, 0}, {0x3810, 0x00, 0, 0},
{0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
- {0x3814, 0x31, 0, 0}, {0x3815, 0x31, 0, 0}, {0x3820, 0x41, 0, 0},
- {0x3821, 0x01, 0, 0}, {0x3824, 0x01, 0, 0}, {0x3a02, 0x01, 0, 0},
- {0x3a03, 0xf0, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x52, 0, 0}, {0x370c, 0x03, 0, 0}, {0x3a02, 0x02, 0, 0},
+ {0x3a03, 0xe4, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0xbc, 0, 0},
{0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x72, 0, 0}, {0x3a0e, 0x01, 0, 0},
- {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x01, 0, 0}, {0x3a15, 0xf0, 0, 0},
- {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x4300, 0x3f, 0, 0},
- {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x4713, 0x02, 0, 0},
- {0x4750, 0x00, 0, 0}, {0x4751, 0x00, 0, 0}, {0x5000, 0x07, 0, 0},
- {0x5001, 0x23, 0, 0}, {0x501d, 0x00, 0, 0}, {0x501f, 0x00, 0, 0},
- {0x5684, 0x10, 0, 0}, {0x5685, 0xa0, 0, 0}, {0x5686, 0x0c, 0, 0},
- {0x5687, 0x78, 0, 0}, {0x5a00, 0x08, 0, 0}, {0x5a21, 0x00, 0, 0},
- {0x5a24, 0x00, 0, 0}, {0x4837, 0x0a, 0, 0}, {0x3037, 0x01, 0, 0},
- {0x4800, 0x14, 0, 5}, {0x483b, 0xff, 0, 0}, {0x3007, 0xf7, 0, 0},
- {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0}, {0x3a1b, 0x30, 0, 0},
- {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x14, 0, 0},
- {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
- {0x3c06, 0x1c, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
- {0x3c0a, 0x9c, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0b, 0x40, 0, 0},
- {0x5180, 0xff, 0, 0}, {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0},
- {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
- {0x5186, 0x09, 0, 0}, {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0},
- {0x5189, 0x75, 0, 0}, {0x518a, 0x54, 0, 0}, {0x518b, 0xe0, 0, 0},
- {0x518c, 0xb2, 0, 0}, {0x518d, 0x42, 0, 0}, {0x518e, 0x3d, 0, 0},
- {0x518f, 0x56, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
- {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
- {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
- {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
- {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
- {0x519e, 0x38, 0, 0}, {0x5381, 0x1c, 0, 0}, {0x5382, 0x5a, 0, 0},
- {0x5383, 0x06, 0, 5}, {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0},
- {0x5386, 0x88, 0, 0}, {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0},
- {0x5389, 0x10, 0, 0}, {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0},
- {0x5300, 0x08, 0, 0}, {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0},
- {0x5303, 0x00, 0, 0}, {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0},
- {0x5306, 0x08, 0, 0}, {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0},
- {0x530a, 0x30, 0, 0}, {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0},
- {0x4814, 0x00, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0x00, 0, 10},
- {0x483b, 0x33, 0, 0}, {0x3007, 0xff, 0, 10},
+ {0x3a0d, 0x02, 0, 0}, {0x3a14, 0x02, 0, 0}, {0x3a15, 0xe4, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x02, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x4713, 0x02, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x440e, 0x00, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
+ {0x4827, 0x16, 0, 0}, {0x4837, 0x0a, 0, 0}, {0x3824, 0x04, 0, 0},
+ {0x5000, 0xa7, 0, 0}, {0x5001, 0x83, 0, 0}, {0x5180, 0xff, 0, 0},
+ {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
+ {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
+ {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0}, {0x5189, 0x75, 0, 0},
+ {0x518a, 0x54, 0, 0}, {0x518b, 0xe0, 0, 0}, {0x518c, 0xb2, 0, 0},
+ {0x518d, 0x42, 0, 0}, {0x518e, 0x3d, 0, 0}, {0x518f, 0x56, 0, 0},
+ {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0},
+ {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0},
+ {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0},
+ {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0}, {0x519e, 0x38, 0, 0},
+ {0x5381, 0x1e, 0, 0}, {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0},
+ {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0},
+ {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0},
+ {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0},
+ {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0},
+ {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0},
+ {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0},
+ {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0},
+ {0x5481, 0x08, 0, 0}, {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0},
+ {0x5484, 0x51, 0, 0}, {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0},
+ {0x5487, 0x7d, 0, 0}, {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0},
+ {0x548a, 0x9a, 0, 0}, {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0},
+ {0x548d, 0xcd, 0, 0}, {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0},
+ {0x5490, 0x1d, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x10, 0, 0}, {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0},
+ {0x558b, 0xf8, 0, 0}, {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0},
+ {0x5802, 0x0f, 0, 0}, {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0},
+ {0x5805, 0x26, 0, 0}, {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0},
+ {0x5808, 0x05, 0, 0}, {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0},
+ {0x580b, 0x0d, 0, 0}, {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0},
+ {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0},
+ {0x5811, 0x09, 0, 0}, {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0},
+ {0x5814, 0x00, 0, 0}, {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0},
+ {0x5817, 0x08, 0, 0}, {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0},
+ {0x581a, 0x05, 0, 0}, {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0},
+ {0x581d, 0x0e, 0, 0}, {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0},
+ {0x5820, 0x11, 0, 0}, {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0},
+ {0x5823, 0x28, 0, 0}, {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0},
+ {0x5826, 0x08, 0, 0}, {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0},
+ {0x5829, 0x26, 0, 0}, {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0},
+ {0x582c, 0x24, 0, 0}, {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0},
+ {0x582f, 0x22, 0, 0}, {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0},
+ {0x5832, 0x24, 0, 0}, {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0},
+ {0x5835, 0x22, 0, 0}, {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0},
+ {0x5838, 0x44, 0, 0}, {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0},
+ {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0},
+ {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0},
+ {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0},
+ {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0},
};
static struct reg_value ov5640_setting_30fps_1080P_1920_1080[] = {
- {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0}, {0x3103, 0x03, 0, 0},
- {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0}, {0x3630, 0x2e, 0, 0},
- {0x3632, 0xe2, 0, 0}, {0x3633, 0x23, 0, 0}, {0x3634, 0x44, 0, 0},
+ {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
+ {0x3034, 0x18, 0, 0}, {0x3035, 0x11, 0, 0}, {0x3036, 0x54, 0, 0},
+ {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
+ {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
{0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
{0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
{0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
- {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x04, 0, 0},
- {0x3601, 0x22, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a18, 0x00, 0, 0},
- {0x3a19, 0xf8, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3500, 0x00, 0, 0},
- {0x3501, 0x01, 0, 0}, {0x3502, 0x00, 0, 0}, {0x350a, 0x00, 0, 0},
- {0x350b, 0x3f, 0, 0}, {0x3002, 0x1c, 0, 0}, {0x3006, 0xc3, 0, 0},
- {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x3612, 0x4b, 0, 0},
- {0x3618, 0x04, 0, 0}, {0x3034, 0x18, 0, 0}, {0x3035, 0x41, 0, 0},
- {0x3036, 0xa8, 0, 0}, {0x3708, 0x61, 0, 0}, {0x3709, 0x12, 0, 0},
- {0x370c, 0x03, 0, 0}, {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0},
+ {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
+ {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
+ {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
+ {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
+ {0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
+ {0x3c06, 0x00, 0, 0}, {0x3c07, 0x07, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
+ {0x3815, 0x11, 0, 0}, {0x3800, 0x01, 0, 0}, {0x3801, 0x50, 0, 0},
{0x3802, 0x01, 0, 0}, {0x3803, 0xb2, 0, 0}, {0x3804, 0x08, 0, 0},
- {0x3805, 0xef, 0, 0}, {0x3806, 0x05, 0, 5}, {0x3807, 0xf2, 0, 0},
+ {0x3805, 0xef, 0, 0}, {0x3806, 0x05, 0, 0}, {0x3807, 0xf1, 0, 0},
{0x3808, 0x07, 0, 0}, {0x3809, 0x80, 0, 0}, {0x380a, 0x04, 0, 0},
{0x380b, 0x38, 0, 0}, {0x380c, 0x09, 0, 0}, {0x380d, 0xc4, 0, 0},
{0x380e, 0x04, 0, 0}, {0x380f, 0x60, 0, 0}, {0x3810, 0x00, 0, 0},
{0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
- {0x3814, 0x11, 0, 0}, {0x3815, 0x11, 0, 0}, {0x3820, 0x40, 0, 0},
- {0x3821, 0x00, 0, 0}, {0x3824, 0x01, 0, 0}, {0x3a02, 0x01, 0, 0},
- {0x3a03, 0xf0, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x50, 0, 0},
+ {0x3618, 0x04, 0, 0}, {0x3612, 0x2b, 0, 0}, {0x3708, 0x64, 0, 0},
+ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x04, 0, 0},
+ {0x3a03, 0x60, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x50, 0, 0},
{0x3a0a, 0x01, 0, 0}, {0x3a0b, 0x18, 0, 0}, {0x3a0e, 0x03, 0, 0},
- {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x01, 0, 0}, {0x3a15, 0xf0, 0, 0},
- {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x4300, 0x3f, 0, 0},
- {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0}, {0x4713, 0x02, 0, 0},
- {0x4750, 0x00, 0, 0}, {0x4751, 0x00, 0, 0}, {0x5000, 0x07, 0, 0},
- {0x5001, 0x23, 0, 0}, {0x501d, 0x00, 0, 0}, {0x501f, 0x00, 0, 0},
- {0x5684, 0x10, 0, 0}, {0x5685, 0xa0, 0, 0}, {0x5686, 0x0c, 0, 0},
- {0x5687, 0x78, 0, 0}, {0x5a00, 0x08, 0, 0}, {0x5a21, 0x00, 0, 0},
- {0x5a24, 0x00, 0, 0}, {0x4837, 0x0a, 0, 0}, {0x3037, 0x01, 0, 0},
- {0x4800, 0x14, 0, 5}, {0x483b, 0xff, 0, 0}, {0x3007, 0xf7, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x04, 0, 0}, {0x3a15, 0x60, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x4713, 0x02, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x440e, 0x00, 0, 0}, {0x460b, 0x37, 0, 0}, {0x460c, 0x20, 0, 0},
+ {0x4837, 0x0a, 0, 0}, {0x3824, 0x04, 0, 0}, {0x5000, 0xa7, 0, 0},
+ {0x5001, 0x83, 0, 0}, {0x5180, 0xff, 0, 0}, {0x5181, 0xf2, 0, 0},
+ {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0},
+ {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0}, {0x5187, 0x09, 0, 0},
+ {0x5188, 0x09, 0, 0}, {0x5189, 0x75, 0, 0}, {0x518a, 0x54, 0, 0},
+ {0x518b, 0xe0, 0, 0}, {0x518c, 0xb2, 0, 0}, {0x518d, 0x42, 0, 0},
+ {0x518e, 0x3d, 0, 0}, {0x518f, 0x56, 0, 0}, {0x5190, 0x46, 0, 0},
+ {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0},
+ {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0},
+ {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0},
+ {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0},
+ {0x519d, 0x82, 0, 0}, {0x519e, 0x38, 0, 0}, {0x5381, 0x1e, 0, 0},
+ {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0}, {0x5384, 0x0a, 0, 0},
+ {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0}, {0x5387, 0x7c, 0, 0},
+ {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0}, {0x538a, 0x01, 0, 0},
+ {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0}, {0x5301, 0x30, 0, 0},
+ {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0}, {0x5304, 0x08, 0, 0},
+ {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0}, {0x5307, 0x16, 0, 0},
+ {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0}, {0x530b, 0x04, 0, 0},
+ {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0}, {0x5481, 0x08, 0, 0},
+ {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0}, {0x5484, 0x51, 0, 0},
+ {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0}, {0x5487, 0x7d, 0, 0},
+ {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0}, {0x548a, 0x9a, 0, 0},
+ {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0}, {0x548d, 0xcd, 0, 0},
+ {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0}, {0x5490, 0x1d, 0, 0},
+ {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0}, {0x5584, 0x10, 0, 0},
+ {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0}, {0x558b, 0xf8, 0, 0},
+ {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0}, {0x5802, 0x0f, 0, 0},
+ {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0}, {0x5805, 0x26, 0, 0},
+ {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0}, {0x5808, 0x05, 0, 0},
+ {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0}, {0x580b, 0x0d, 0, 0},
+ {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0}, {0x580e, 0x00, 0, 0},
+ {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0}, {0x5811, 0x09, 0, 0},
+ {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0}, {0x5814, 0x00, 0, 0},
+ {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0}, {0x5817, 0x08, 0, 0},
+ {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0}, {0x581a, 0x05, 0, 0},
+ {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0}, {0x581d, 0x0e, 0, 0},
+ {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0}, {0x5820, 0x11, 0, 0},
+ {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0}, {0x5823, 0x28, 0, 0},
+ {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0}, {0x5826, 0x08, 0, 0},
+ {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0}, {0x5829, 0x26, 0, 0},
+ {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0}, {0x582c, 0x24, 0, 0},
+ {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0}, {0x582f, 0x22, 0, 0},
+ {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0}, {0x5832, 0x24, 0, 0},
+ {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0}, {0x5835, 0x22, 0, 0},
+ {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0}, {0x5838, 0x44, 0, 0},
+ {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0}, {0x583b, 0x28, 0, 0},
+ {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0}, {0x5025, 0x00, 0, 0},
{0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0}, {0x3a1b, 0x30, 0, 0},
{0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0}, {0x3a1f, 0x14, 0, 0},
+ {0x3008, 0x02, 0, 0},
+};
+
+static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
+ {0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
+ {0x3103, 0x03, 0, 0}, {0x3017, 0x00, 0, 0}, {0x3018, 0x00, 0, 0},
+ {0x3034, 0x18, 0, 0}, {0x3035, 0x21, 0, 0}, {0x3036, 0x54, 0, 0},
+ {0x3037, 0x13, 0, 0}, {0x3108, 0x01, 0, 0}, {0x3630, 0x36, 0, 0},
+ {0x3631, 0x0e, 0, 0}, {0x3632, 0xe2, 0, 0}, {0x3633, 0x12, 0, 0},
+ {0x3621, 0xe0, 0, 0}, {0x3704, 0xa0, 0, 0}, {0x3703, 0x5a, 0, 0},
+ {0x3715, 0x78, 0, 0}, {0x3717, 0x01, 0, 0}, {0x370b, 0x60, 0, 0},
+ {0x3705, 0x1a, 0, 0}, {0x3905, 0x02, 0, 0}, {0x3906, 0x10, 0, 0},
+ {0x3901, 0x0a, 0, 0}, {0x3731, 0x12, 0, 0}, {0x3600, 0x08, 0, 0},
+ {0x3601, 0x33, 0, 0}, {0x302d, 0x60, 0, 0}, {0x3620, 0x52, 0, 0},
+ {0x371b, 0x20, 0, 0}, {0x471c, 0x50, 0, 0}, {0x3a13, 0x43, 0, 0},
+ {0x3a18, 0x00, 0, 0}, {0x3a19, 0xf8, 0, 0}, {0x3635, 0x13, 0, 0},
+ {0x3636, 0x03, 0, 0}, {0x3634, 0x40, 0, 0}, {0x3622, 0x01, 0, 0},
{0x3c01, 0x34, 0, 0}, {0x3c04, 0x28, 0, 0}, {0x3c05, 0x98, 0, 0},
- {0x3c06, 0x1c, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
- {0x3c0a, 0x9c, 0, 0}, {0x3c09, 0x1c, 0, 0}, {0x3c0b, 0x40, 0, 0},
- {0x5180, 0xff, 0, 0}, {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0},
- {0x5183, 0x14, 0, 0}, {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0},
- {0x5186, 0x09, 0, 0}, {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0},
- {0x5189, 0x75, 0, 0}, {0x518a, 0x54, 0, 0}, {0x518b, 0xe0, 0, 0},
- {0x518c, 0xb2, 0, 0}, {0x518d, 0x42, 0, 0}, {0x518e, 0x3d, 0, 0},
- {0x518f, 0x56, 0, 0}, {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0},
- {0x5192, 0x04, 0, 0}, {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0},
- {0x5195, 0xf0, 0, 0}, {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0},
- {0x5198, 0x04, 0, 0}, {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0},
- {0x519b, 0x00, 0, 0}, {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0},
- {0x519e, 0x38, 0, 0}, {0x5381, 0x1c, 0, 0}, {0x5382, 0x5a, 0, 0},
- {0x5383, 0x06, 0, 5}, {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0},
- {0x5386, 0x88, 0, 0}, {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0},
- {0x5389, 0x10, 0, 0}, {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0},
- {0x5300, 0x08, 0, 0}, {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0},
- {0x5303, 0x00, 0, 0}, {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0},
- {0x5306, 0x08, 0, 0}, {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0},
- {0x530a, 0x30, 0, 0}, {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0},
- {0x4814, 0x00, 0, 0}, {0x3008, 0x02, 0, 0}, {0x3503, 0x00, 0, 10},
- {0x483b, 0x33, 0, 0}, {0x3007, 0xff, 0, 10},
+ {0x3c06, 0x00, 0, 0}, {0x3c07, 0x08, 0, 0}, {0x3c08, 0x00, 0, 0},
+ {0x3c09, 0x1c, 0, 0}, {0x3c0a, 0x9c, 0, 0}, {0x3c0b, 0x40, 0, 0},
+ {0x3820, 0x40, 0, 0}, {0x3821, 0x06, 0, 0}, {0x3814, 0x11, 0, 0},
+ {0x3815, 0x11, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3801, 0x00, 0, 0},
+ {0x3802, 0x00, 0, 0}, {0x3803, 0x00, 0, 0}, {0x3804, 0x0a, 0, 0},
+ {0x3805, 0x3f, 0, 0}, {0x3806, 0x07, 0, 0}, {0x3807, 0x9f, 0, 0},
+ {0x3808, 0x0a, 0, 0}, {0x3809, 0x20, 0, 0}, {0x380a, 0x07, 0, 0},
+ {0x380b, 0x98, 0, 0}, {0x380c, 0x0b, 0, 0}, {0x380d, 0x1c, 0, 0},
+ {0x380e, 0x07, 0, 0}, {0x380f, 0xb0, 0, 0}, {0x3810, 0x00, 0, 0},
+ {0x3811, 0x10, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3813, 0x04, 0, 0},
+ {0x3618, 0x04, 0, 0}, {0x3612, 0x29, 0, 0}, {0x3708, 0x21, 0, 0},
+ {0x3709, 0x12, 0, 0}, {0x370c, 0x00, 0, 0}, {0x3a02, 0x03, 0, 0},
+ {0x3a03, 0xd8, 0, 0}, {0x3a08, 0x01, 0, 0}, {0x3a09, 0x27, 0, 0},
+ {0x3a0a, 0x00, 0, 0}, {0x3a0b, 0xf6, 0, 0}, {0x3a0e, 0x03, 0, 0},
+ {0x3a0d, 0x04, 0, 0}, {0x3a14, 0x03, 0, 0}, {0x3a15, 0xd8, 0, 0},
+ {0x4001, 0x02, 0, 0}, {0x4004, 0x06, 0, 0}, {0x3000, 0x00, 0, 0},
+ {0x3002, 0x1c, 0, 0}, {0x3004, 0xff, 0, 0}, {0x3006, 0xc3, 0, 0},
+ {0x300e, 0x45, 0, 0}, {0x302e, 0x08, 0, 0}, {0x4300, 0x3f, 0, 0},
+ {0x501f, 0x00, 0, 0}, {0x4713, 0x03, 0, 0}, {0x4407, 0x04, 0, 0},
+ {0x440e, 0x00, 0, 0}, {0x460b, 0x35, 0, 0}, {0x460c, 0x22, 0, 0},
+ {0x4837, 0x0a, 0, 0}, {0x4800, 0x04, 0, 0}, {0x3824, 0x02, 0, 0},
+ {0x5000, 0xa7, 0, 0}, {0x5001, 0x83, 0, 0}, {0x5180, 0xff, 0, 0},
+ {0x5181, 0xf2, 0, 0}, {0x5182, 0x00, 0, 0}, {0x5183, 0x14, 0, 0},
+ {0x5184, 0x25, 0, 0}, {0x5185, 0x24, 0, 0}, {0x5186, 0x09, 0, 0},
+ {0x5187, 0x09, 0, 0}, {0x5188, 0x09, 0, 0}, {0x5189, 0x75, 0, 0},
+ {0x518a, 0x54, 0, 0}, {0x518b, 0xe0, 0, 0}, {0x518c, 0xb2, 0, 0},
+ {0x518d, 0x42, 0, 0}, {0x518e, 0x3d, 0, 0}, {0x518f, 0x56, 0, 0},
+ {0x5190, 0x46, 0, 0}, {0x5191, 0xf8, 0, 0}, {0x5192, 0x04, 0, 0},
+ {0x5193, 0x70, 0, 0}, {0x5194, 0xf0, 0, 0}, {0x5195, 0xf0, 0, 0},
+ {0x5196, 0x03, 0, 0}, {0x5197, 0x01, 0, 0}, {0x5198, 0x04, 0, 0},
+ {0x5199, 0x12, 0, 0}, {0x519a, 0x04, 0, 0}, {0x519b, 0x00, 0, 0},
+ {0x519c, 0x06, 0, 0}, {0x519d, 0x82, 0, 0}, {0x519e, 0x38, 0, 0},
+ {0x5381, 0x1e, 0, 0}, {0x5382, 0x5b, 0, 0}, {0x5383, 0x08, 0, 0},
+ {0x5384, 0x0a, 0, 0}, {0x5385, 0x7e, 0, 0}, {0x5386, 0x88, 0, 0},
+ {0x5387, 0x7c, 0, 0}, {0x5388, 0x6c, 0, 0}, {0x5389, 0x10, 0, 0},
+ {0x538a, 0x01, 0, 0}, {0x538b, 0x98, 0, 0}, {0x5300, 0x08, 0, 0},
+ {0x5301, 0x30, 0, 0}, {0x5302, 0x10, 0, 0}, {0x5303, 0x00, 0, 0},
+ {0x5304, 0x08, 0, 0}, {0x5305, 0x30, 0, 0}, {0x5306, 0x08, 0, 0},
+ {0x5307, 0x16, 0, 0}, {0x5309, 0x08, 0, 0}, {0x530a, 0x30, 0, 0},
+ {0x530b, 0x04, 0, 0}, {0x530c, 0x06, 0, 0}, {0x5480, 0x01, 0, 0},
+ {0x5481, 0x08, 0, 0}, {0x5482, 0x14, 0, 0}, {0x5483, 0x28, 0, 0},
+ {0x5484, 0x51, 0, 0}, {0x5485, 0x65, 0, 0}, {0x5486, 0x71, 0, 0},
+ {0x5487, 0x7d, 0, 0}, {0x5488, 0x87, 0, 0}, {0x5489, 0x91, 0, 0},
+ {0x548a, 0x9a, 0, 0}, {0x548b, 0xaa, 0, 0}, {0x548c, 0xb8, 0, 0},
+ {0x548d, 0xcd, 0, 0}, {0x548e, 0xdd, 0, 0}, {0x548f, 0xea, 0, 0},
+ {0x5490, 0x1d, 0, 0}, {0x5580, 0x02, 0, 0}, {0x5583, 0x40, 0, 0},
+ {0x5584, 0x10, 0, 0}, {0x5589, 0x10, 0, 0}, {0x558a, 0x00, 0, 0},
+ {0x558b, 0xf8, 0, 0}, {0x5800, 0x23, 0, 0}, {0x5801, 0x14, 0, 0},
+ {0x5802, 0x0f, 0, 0}, {0x5803, 0x0f, 0, 0}, {0x5804, 0x12, 0, 0},
+ {0x5805, 0x26, 0, 0}, {0x5806, 0x0c, 0, 0}, {0x5807, 0x08, 0, 0},
+ {0x5808, 0x05, 0, 0}, {0x5809, 0x05, 0, 0}, {0x580a, 0x08, 0, 0},
+ {0x580b, 0x0d, 0, 0}, {0x580c, 0x08, 0, 0}, {0x580d, 0x03, 0, 0},
+ {0x580e, 0x00, 0, 0}, {0x580f, 0x00, 0, 0}, {0x5810, 0x03, 0, 0},
+ {0x5811, 0x09, 0, 0}, {0x5812, 0x07, 0, 0}, {0x5813, 0x03, 0, 0},
+ {0x5814, 0x00, 0, 0}, {0x5815, 0x01, 0, 0}, {0x5816, 0x03, 0, 0},
+ {0x5817, 0x08, 0, 0}, {0x5818, 0x0d, 0, 0}, {0x5819, 0x08, 0, 0},
+ {0x581a, 0x05, 0, 0}, {0x581b, 0x06, 0, 0}, {0x581c, 0x08, 0, 0},
+ {0x581d, 0x0e, 0, 0}, {0x581e, 0x29, 0, 0}, {0x581f, 0x17, 0, 0},
+ {0x5820, 0x11, 0, 0}, {0x5821, 0x11, 0, 0}, {0x5822, 0x15, 0, 0},
+ {0x5823, 0x28, 0, 0}, {0x5824, 0x46, 0, 0}, {0x5825, 0x26, 0, 0},
+ {0x5826, 0x08, 0, 0}, {0x5827, 0x26, 0, 0}, {0x5828, 0x64, 0, 0},
+ {0x5829, 0x26, 0, 0}, {0x582a, 0x24, 0, 0}, {0x582b, 0x22, 0, 0},
+ {0x582c, 0x24, 0, 0}, {0x582d, 0x24, 0, 0}, {0x582e, 0x06, 0, 0},
+ {0x582f, 0x22, 0, 0}, {0x5830, 0x40, 0, 0}, {0x5831, 0x42, 0, 0},
+ {0x5832, 0x24, 0, 0}, {0x5833, 0x26, 0, 0}, {0x5834, 0x24, 0, 0},
+ {0x5835, 0x22, 0, 0}, {0x5836, 0x22, 0, 0}, {0x5837, 0x26, 0, 0},
+ {0x5838, 0x44, 0, 0}, {0x5839, 0x24, 0, 0}, {0x583a, 0x26, 0, 0},
+ {0x583b, 0x28, 0, 0}, {0x583c, 0x42, 0, 0}, {0x583d, 0xce, 0, 0},
+ {0x5025, 0x00, 0, 0}, {0x3a0f, 0x30, 0, 0}, {0x3a10, 0x28, 0, 0},
+ {0x3a1b, 0x30, 0, 0}, {0x3a1e, 0x26, 0, 0}, {0x3a11, 0x60, 0, 0},
+ {0x3a1f, 0x14, 0, 0}, {0x3008, 0x02, 0, 0},
};
static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
@@ -357,7 +725,9 @@ static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
{ov5640_mode_PAL_720_576, 0, 0, NULL, 0},
{ov5640_mode_720P_1280_720, 0, 0, NULL, 0},
{ov5640_mode_1080P_1920_1080, 0, 0, NULL, 0},
- {ov5640_mode_QSXGA_2592_1944, 0, 0, NULL, 0},
+ {ov5640_mode_QSXGA_2592_1944, 2592, 1944,
+ ov5640_setting_15fps_QSXGA_2592_1944,
+ ARRAY_SIZE(ov5640_setting_15fps_QSXGA_2592_1944)},
},
{
{ov5640_mode_VGA_640_480, 640, 480,
@@ -366,8 +736,12 @@ static struct ov5640_mode_info ov5640_mode_info_data[2][ov5640_mode_MAX + 1] = {
{ov5640_mode_QVGA_320_240, 320, 240,
ov5640_setting_30fps_QVGA_320_240,
ARRAY_SIZE(ov5640_setting_30fps_QVGA_320_240)},
- {ov5640_mode_NTSC_720_480, 0, 0, NULL, 0},
- {ov5640_mode_PAL_720_576, 0, 0, NULL, 0},
+ {ov5640_mode_NTSC_720_480, 720, 480,
+ ov5640_setting_30fps_NTSC_720_480,
+ ARRAY_SIZE(ov5640_setting_30fps_NTSC_720_480)},
+ {ov5640_mode_PAL_720_576, 720, 576,
+ ov5640_setting_30fps_PAL_720_576,
+ ARRAY_SIZE(ov5640_setting_30fps_PAL_720_576)},
{ov5640_mode_720P_1280_720, 1280, 720,
ov5640_setting_30fps_720P_1280_720,
ARRAY_SIZE(ov5640_setting_30fps_720P_1280_720)},
@@ -475,15 +849,26 @@ static int ov5640_init_mode(enum ov5640_frame_rate frame_rate,
/* initial mipi dphy */
if (mipi_csi2_info) {
- mipi_csi2_set_lanes(mipi_csi2_info);
- mipi_csi2_reset(mipi_csi2_info);
-
- if (ov5640_data.pix.pixelformat == V4L2_PIX_FMT_YUYV)
- mipi_csi2_set_datatype(mipi_csi2_info, MIPI_DT_YUV422);
- else if (ov5640_data.pix.pixelformat == V4L2_PIX_FMT_RGB565)
- mipi_csi2_set_datatype(mipi_csi2_info, MIPI_DT_RGB565);
- else
- pr_err("currently this sensor format can not be supported!\n");
+ if (!mipi_csi2_get_status(mipi_csi2_info))
+ mipi_csi2_enable(mipi_csi2_info);
+
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ mipi_csi2_set_lanes(mipi_csi2_info);
+ mipi_csi2_reset(mipi_csi2_info);
+
+ if (ov5640_data.pix.pixelformat == V4L2_PIX_FMT_UYVY)
+ mipi_csi2_set_datatype(mipi_csi2_info, MIPI_DT_YUV422);
+ else if (ov5640_data.pix.pixelformat == V4L2_PIX_FMT_RGB565)
+ mipi_csi2_set_datatype(mipi_csi2_info, MIPI_DT_RGB565);
+ else
+ pr_err("currently this sensor format can not be supported!\n");
+ } else {
+ pr_err("Can not enable mipi csi2 driver!\n");
+ return -1;
+ }
+ } else {
+ printk(KERN_ERR "Fail to get mipi_csi2_info!\n");
+ return -1;
}
pModeSetting = ov5640_mode_info_data[frame_rate][mode].init_data_ptr;
@@ -522,15 +907,37 @@ static int ov5640_init_mode(enum ov5640_frame_rate frame_rate,
}
if (mipi_csi2_info) {
+ unsigned int i;
+
+ i = 0;
+
/* wait for mipi sensor ready */
mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
- while (mipi_reg == 0x200)
+ while ((mipi_reg == 0x200) && (i < 10)) {
mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
+ i++;
+ msleep(10);
+ }
+
+ if (i >= 10) {
+ pr_err("mipi csi2 can not receive sensor clk!\n");
+ return -1;
+ }
+
+ i = 0;
/* wait for mipi stable */
mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
- while (mipi_reg != 0x0)
+ while ((mipi_reg != 0x0) && (i < 10)) {
mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
+ i++;
+ msleep(10);
+ }
+
+ if (i >= 10) {
+ pr_err("mipi csi2 can not reveive data correctly!\n");
+ return -1;
+ }
}
err:
return retval;
@@ -924,6 +1331,7 @@ static int ioctl_dev_init(struct v4l2_int_device *s)
u32 tgt_fps; /* target frames per secound */
int ret;
enum ov5640_frame_rate frame_rate;
+ void *mipi_csi2_info;
ov5640_data.on = true;
@@ -947,6 +1355,16 @@ static int ioctl_dev_init(struct v4l2_int_device *s)
else
return -EINVAL; /* Only support 15fps or 30fps now. */
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ /* enable mipi csi2 */
+ if (mipi_csi2_info)
+ mipi_csi2_enable(mipi_csi2_info);
+ else {
+ printk(KERN_ERR "Fail to get mipi_csi2_info!\n");
+ return -EPERM;
+ }
+
ret = ov5640_init_mode(frame_rate,
sensor->streamcap.capturemode);
@@ -961,6 +1379,15 @@ static int ioctl_dev_init(struct v4l2_int_device *s)
*/
static int ioctl_dev_exit(struct v4l2_int_device *s)
{
+ void *mipi_csi2_info;
+
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ /* disable mipi csi2 */
+ if (mipi_csi2_info)
+ if (mipi_csi2_get_status(mipi_csi2_info))
+ mipi_csi2_disable(mipi_csi2_info);
+
return 0;
}
@@ -1027,7 +1454,7 @@ static int ov5640_probe(struct i2c_client *client,
ov5640_data.csi = plat_data->csi;
ov5640_data.i2c_client = client;
- ov5640_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
+ ov5640_data.pix.pixelformat = V4L2_PIX_FMT_UYVY;
ov5640_data.pix.width = 640;
ov5640_data.pix.height = 480;
ov5640_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
@@ -1091,6 +1518,9 @@ static int ov5640_probe(struct i2c_client *client,
analog_regulator = NULL;
}
+ if (plat_data->io_init)
+ plat_data->io_init();
+
if (plat_data->pwdn)
plat_data->pwdn(0);
@@ -1181,7 +1611,7 @@ module_init(ov5640_init);
module_exit(ov5640_clean);
MODULE_AUTHOR("Freescale Semiconductor, Inc.");
-MODULE_DESCRIPTION("OV5640 Camera Driver");
+MODULE_DESCRIPTION("OV5640 MIPI Camera Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION("1.0");
MODULE_ALIAS("CSI");
diff --git a/drivers/media/video/mxc/capture/ov5642.c b/drivers/media/video/mxc/capture/ov5642.c
index 25749673caa2..f874635d201c 100644
--- a/drivers/media/video/mxc/capture/ov5642.c
+++ b/drivers/media/video/mxc/capture/ov5642.c
@@ -2762,6 +2762,9 @@ static int ov5642_probe(struct i2c_client *client,
analog_regulator = NULL;
}
+ if (plat_data->io_init)
+ plat_data->io_init();
+
if (plat_data->pwdn)
plat_data->pwdn(0);
diff --git a/drivers/media/video/mxc/capture/ov8820_mipi.c b/drivers/media/video/mxc/capture/ov8820_mipi.c
new file mode 100644
index 000000000000..4c2a49d8bef5
--- /dev/null
+++ b/drivers/media/video/mxc/capture/ov8820_mipi.c
@@ -0,0 +1,1037 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/regulator/consumer.h>
+#include <linux/fsl_devices.h>
+#include <mach/mipi_csi2.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-int-device.h>
+#include "mxc_v4l2_capture.h"
+
+#define OV8820_VOLTAGE_ANALOG 2800000
+#define OV8820_VOLTAGE_DIGITAL_CORE 1500000
+#define OV8820_VOLTAGE_DIGITAL_IO 1800000
+
+#define MIN_FPS 15
+#define MAX_FPS 30
+#define DEFAULT_FPS 30
+
+#define OV8820_XCLK_MIN 6000000
+#define OV8820_XCLK_MAX 24000000
+
+enum ov8820_mode {
+ ov8820_mode_MIN = 0,
+ ov8820_mode_480_480 = 0,
+ ov8820_mode_MAX = 0
+};
+
+enum ov8820_frame_rate {
+ ov8820_15_fps,
+ ov8820_30_fps
+};
+
+struct reg_value {
+ u16 u16RegAddr;
+ u8 u8Val;
+ u8 u8Mask;
+ u32 u32Delay_ms;
+};
+
+struct ov8820_mode_info {
+ enum ov8820_mode mode;
+ u32 width;
+ u32 height;
+ struct reg_value *init_data_ptr;
+ u32 init_data_size;
+};
+
+/*!
+ * Maintains the information on the current state of the sesor.
+ */
+struct sensor {
+ const struct ov8820_platform_data *platform_data;
+ struct v4l2_int_device *v4l2_int_device;
+ struct i2c_client *i2c_client;
+ struct v4l2_pix_format pix;
+ struct v4l2_captureparm streamcap;
+ bool on;
+
+ /* control settings */
+ int brightness;
+ int hue;
+ int contrast;
+ int saturation;
+ int red;
+ int green;
+ int blue;
+ int ae_mode;
+
+ u32 mclk;
+ int csi;
+} ov8820_data;
+
+static struct reg_value ov8820_setting_30fps_480_480[] = {
+ {0x0103, 0x01, 0, 5}, {0x3000, 0x02, 0, 0}, {0x3001, 0x00, 0, 0},
+ {0x3002, 0x6c, 0, 0}, {0x300d, 0x00, 0, 0}, {0x301f, 0x09, 0, 0},
+ {0x3010, 0x00, 0, 0}, {0x3018, 0x00, 0, 0}, {0x3300, 0x00, 0, 0},
+ {0x3500, 0x00, 0, 0}, {0x3503, 0x07, 0, 0}, {0x3509, 0x00, 0, 0},
+ {0x3600, 0x08, 0, 0}, {0x3601, 0x44, 0, 0}, {0x3602, 0x75, 0, 0},
+ {0x3603, 0x5c, 0, 0}, {0x3604, 0x98, 0, 0}, {0x3605, 0xe9, 0, 0},
+ {0x3609, 0xb8, 0, 0}, {0x360a, 0xbc, 0, 0}, {0x360b, 0xb4, 0, 0},
+ {0x360c, 0x0d, 0, 0}, {0x3613, 0x02, 0, 0}, {0x3614, 0x0f, 0, 0},
+ {0x3615, 0x00, 0, 0}, {0x3616, 0x03, 0, 0}, {0x3617, 0x01, 0, 0},
+ {0x3618, 0x00, 0, 0}, {0x3619, 0x00, 0, 0}, {0x361a, 0x00, 0, 0},
+ {0x361b, 0x00, 0, 0}, {0x3700, 0x20, 0, 0}, {0x3701, 0x44, 0, 0},
+ {0x3702, 0x50, 0, 0}, {0x3703, 0xcc, 0, 0}, {0x3704, 0x19, 0, 0},
+ {0x3706, 0x4b, 0, 0}, {0x3707, 0x63, 0, 0}, {0x3708, 0x84, 0, 0},
+ {0x3709, 0x40, 0, 0}, {0x370b, 0x01, 0, 0}, {0x370c, 0x50, 0, 0},
+ {0x370d, 0x0c, 0, 0}, {0x370e, 0x00, 0, 0}, {0x3711, 0x01, 0, 0},
+ {0x3712, 0x9c, 0, 0}, {0x3800, 0x00, 0, 0}, {0x3804, 0x0c, 0, 0},
+ {0x3810, 0x00, 0, 0}, {0x3812, 0x00, 0, 0}, {0x3816, 0x02, 0, 0},
+ {0x3817, 0x40, 0, 0}, {0x3818, 0x00, 0, 0}, {0x3819, 0x40, 0, 0},
+ {0x3d00, 0x00, 0, 0}, {0x3d01, 0x00, 0, 0}, {0x3d02, 0x00, 0, 0},
+ {0x3d03, 0x00, 0, 0}, {0x3d04, 0x00, 0, 0}, {0x3d05, 0x00, 0, 0},
+ {0x3d06, 0x00, 0, 0}, {0x3d07, 0x00, 0, 0}, {0x3d08, 0x00, 0, 0},
+ {0x3d09, 0x00, 0, 0}, {0x3d0a, 0x00, 0, 0}, {0x3d0b, 0x00, 0, 0},
+ {0x3d0c, 0x00, 0, 0}, {0x3d0d, 0x00, 0, 0}, {0x3d0e, 0x00, 0, 0},
+ {0x3d0f, 0x00, 0, 0}, {0x3d10, 0x00, 0, 0}, {0x3d11, 0x00, 0, 0},
+ {0x3d12, 0x00, 0, 0}, {0x3d13, 0x00, 0, 0}, {0x3d14, 0x00, 0, 0},
+ {0x3d15, 0x00, 0, 0}, {0x3d16, 0x00, 0, 0}, {0x3d17, 0x00, 0, 0},
+ {0x3d18, 0x00, 0, 0}, {0x3d19, 0x00, 0, 0}, {0x3d1a, 0x00, 0, 0},
+ {0x3d1b, 0x00, 0, 0}, {0x3d1c, 0x00, 0, 0}, {0x3d1d, 0x00, 0, 0},
+ {0x3d1e, 0x00, 0, 0}, {0x3d1f, 0x00, 0, 0}, {0x3d80, 0x00, 0, 0},
+ {0x3d81, 0x00, 0, 0}, {0x3d84, 0x00, 0, 0}, {0x3f01, 0xfc, 0, 0},
+ {0x3f05, 0x10, 0, 0}, {0x3f06, 0x00, 0, 0}, {0x3f07, 0x00, 0, 0},
+ {0x4000, 0x29, 0, 0}, {0x4001, 0x02, 0, 0}, {0x4002, 0x45, 0, 0},
+ {0x4003, 0x08, 0, 0}, {0x4004, 0x04, 0, 0}, {0x4005, 0x18, 0, 0},
+ {0x4300, 0xff, 0, 0}, {0x4303, 0x00, 0, 0}, {0x4304, 0x08, 0, 0},
+ {0x4307, 0x00, 0, 0}, {0x4800, 0x04, 0, 0}, {0x4801, 0x0f, 0, 0},
+ {0x4843, 0x02, 0, 0}, {0x5000, 0x00, 0, 0}, {0x5001, 0x00, 0, 0},
+ {0x5002, 0x00, 0, 0}, {0x501f, 0x00, 0, 0}, {0x5c00, 0x80, 0, 0},
+ {0x5c01, 0x00, 0, 0}, {0x5c02, 0x00, 0, 0}, {0x5c03, 0x00, 0, 0},
+ {0x5c04, 0x00, 0, 0}, {0x5c05, 0x00, 0, 0}, {0x5c06, 0x00, 0, 0},
+ {0x5c07, 0x80, 0, 0}, {0x5c08, 0x10, 0, 0}, {0x6700, 0x05, 0, 0},
+ {0x6701, 0x19, 0, 0}, {0x6702, 0xfd, 0, 0}, {0x6703, 0xd1, 0, 0},
+ {0x6704, 0xff, 0, 0}, {0x6705, 0xff, 0, 0}, {0x6800, 0x10, 0, 0},
+ {0x6801, 0x02, 0, 0}, {0x6802, 0x90, 0, 0}, {0x6803, 0x10, 0, 0},
+ {0x6804, 0x59, 0, 0}, {0x6900, 0x61, 0, 0}, {0x6901, 0x04, 0, 0},
+ {0x3612, 0x00, 0, 0}, {0x3617, 0xa1, 0, 0}, {0x3b1f, 0x00, 0, 0},
+ {0x3000, 0x12, 0, 0}, {0x3000, 0x16, 0, 0}, {0x3b1f, 0x00, 0, 0},
+ {0x3003, 0xce, 0, 0}, {0x3004, 0xd8, 0, 0}, {0x3005, 0x00, 0, 0},
+ {0x3006, 0x10, 0, 0}, {0x3007, 0x3b, 0, 0}, {0x3012, 0x80, 0, 0},
+ {0x3013, 0x39, 0, 0}, {0x3104, 0x20, 0, 0}, {0x3503, 0x07, 0, 0},
+ {0x3500, 0x00, 0, 0}, {0x3501, 0x14, 0, 0}, {0x3502, 0x80, 0, 0},
+ {0x350b, 0xff, 0, 0}, {0x3400, 0x04, 0, 0}, {0x3401, 0x00, 0, 0},
+ {0x3402, 0x04, 0, 0}, {0x3403, 0x00, 0, 0}, {0x3404, 0x04, 0, 0},
+ {0x3405, 0x00, 0, 0}, {0x3406, 0x01, 0, 0}, {0x5001, 0x01, 0, 0},
+ {0x5000, 0x06, 0, 0}, {0x0100, 0x00, 0, 0}, {0x3004, 0xbf, 0, 0},
+ {0x3005, 0x10, 0, 0}, {0x3006, 0x00, 0, 0}, {0x3011, 0x02, 0, 0},
+ {0x370a, 0x74, 0, 0}, {0x3801, 0x08, 0, 0}, {0x3802, 0x00, 0, 0},
+ {0x3803, 0x00, 0, 0}, {0x3805, 0xd7, 0, 0}, {0x3806, 0x09, 0, 0},
+ {0x3807, 0x97, 0, 0}, {0x3808, 0x01, 0, 0}, {0x3809, 0xe0, 0, 0},
+ {0x380a, 0x01, 0, 0}, {0x380b, 0xe0, 0, 0}, {0x380c, 0x0d, 0, 0},
+ {0x380d, 0xb0, 0, 0}, {0x380e, 0x02, 0, 0}, {0x380f, 0x7a, 0, 0},
+ {0x3811, 0x04, 0, 0}, {0x3813, 0x02, 0, 0}, {0x3814, 0x71, 0, 0},
+ {0x3815, 0x71, 0, 0}, {0x3820, 0x00, 0, 0}, {0x3821, 0x16, 0, 0},
+ {0x3f00, 0x00, 0, 0}, {0x4600, 0x14, 0, 0}, {0x4601, 0x14, 0, 0},
+ {0x4602, 0x00, 0, 0}, {0x4837, 0x1e, 0, 0}, {0x5068, 0x59, 0, 0},
+ {0x506a, 0x5a, 0, 0}, {0x0100, 0x01, 0, 0},
+};
+
+static struct ov8820_mode_info ov8820_mode_info_data[2][ov8820_mode_MAX + 1] = {
+ {
+ {ov8820_mode_480_480, 0, 0, NULL, 0},
+ },
+ {
+ {ov8820_mode_480_480, 480, 480,
+ ov8820_setting_30fps_480_480,
+ ARRAY_SIZE(ov8820_setting_30fps_480_480)},
+ },
+};
+
+static struct regulator *io_regulator;
+static struct regulator *core_regulator;
+static struct regulator *analog_regulator;
+static struct regulator *gpo_regulator;
+static struct fsl_mxc_camera_platform_data *camera_plat;
+
+static int ov8820_probe(struct i2c_client *adapter,
+ const struct i2c_device_id *device_id);
+static int ov8820_remove(struct i2c_client *client);
+
+static s32 ov8820_read_reg(u16 reg, u8 *val);
+static s32 ov8820_write_reg(u16 reg, u8 val);
+
+static const struct i2c_device_id ov8820_id[] = {
+ {"ov8820_mipi", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, ov8820_id);
+
+static struct i2c_driver ov8820_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ov8820_mipi",
+ },
+ .probe = ov8820_probe,
+ .remove = ov8820_remove,
+ .id_table = ov8820_id,
+};
+
+
+static s32 ov8820_write_reg(u16 reg, u8 val)
+{
+ u8 au8Buf[3] = {0};
+
+ au8Buf[0] = reg >> 8;
+ au8Buf[1] = reg & 0xff;
+ au8Buf[2] = val;
+
+ if (i2c_master_send(ov8820_data.i2c_client, au8Buf, 3) < 0) {
+ pr_err("%s:write reg error:reg=%x,val=%x\n",
+ __func__, reg, val);
+ return -1;
+ }
+
+ return 0;
+}
+
+static s32 ov8820_read_reg(u16 reg, u8 *val)
+{
+ u8 au8RegBuf[2] = {0};
+ u8 u8RdVal = 0;
+
+ au8RegBuf[0] = reg >> 8;
+ au8RegBuf[1] = reg & 0xff;
+
+ if (2 != i2c_master_send(ov8820_data.i2c_client, au8RegBuf, 2)) {
+ pr_err("%s:write reg error:reg=%x\n",
+ __func__, reg);
+ return -1;
+ }
+
+ if (1 != i2c_master_recv(ov8820_data.i2c_client, &u8RdVal, 1)) {
+ pr_err("%s:read reg error:reg=%x,val=%x\n",
+ __func__, reg, u8RdVal);
+ return -1;
+ }
+
+ *val = u8RdVal;
+
+ return u8RdVal;
+}
+
+static int ov8820_init_mode(enum ov8820_frame_rate frame_rate,
+ enum ov8820_mode mode)
+{
+ struct reg_value *pModeSetting = NULL;
+ s32 i = 0;
+ s32 iModeSettingArySize = 0;
+ register u32 Delay_ms = 0;
+ register u16 RegAddr = 0;
+ register u8 Mask = 0;
+ register u8 Val = 0;
+ u8 RegVal = 0;
+ int retval = 0;
+ void *mipi_csi2_info;
+ u32 mipi_reg;
+
+ if (mode > ov8820_mode_MAX || mode < ov8820_mode_MIN) {
+ pr_err("Wrong ov8820 mode detected!\n");
+ return -1;
+ }
+
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ /* initial mipi dphy */
+ if (mipi_csi2_info) {
+ if (!mipi_csi2_get_status(mipi_csi2_info))
+ mipi_csi2_enable(mipi_csi2_info);
+
+ if (mipi_csi2_get_status(mipi_csi2_info)) {
+ mipi_csi2_set_lanes(mipi_csi2_info);
+ mipi_csi2_reset(mipi_csi2_info);
+
+ if (ov8820_data.pix.pixelformat == V4L2_PIX_FMT_SBGGR10)
+ mipi_csi2_set_datatype(mipi_csi2_info, MIPI_DT_RAW10);
+ else
+ pr_err("currently this sensor format can not be supported!\n");
+ } else {
+ pr_err("Can not enable mipi csi2 driver!\n");
+ return -1;
+ }
+ } else {
+ printk(KERN_ERR "Fail to get mipi_csi2_info!\n");
+ return -1;
+ }
+
+ pModeSetting = ov8820_mode_info_data[frame_rate][mode].init_data_ptr;
+ iModeSettingArySize =
+ ov8820_mode_info_data[frame_rate][mode].init_data_size;
+
+ ov8820_data.pix.width = ov8820_mode_info_data[frame_rate][mode].width;
+ ov8820_data.pix.height = ov8820_mode_info_data[frame_rate][mode].height;
+
+ if (ov8820_data.pix.width == 0 || ov8820_data.pix.height == 0 ||
+ pModeSetting == NULL || iModeSettingArySize == 0)
+ return -EINVAL;
+
+ for (i = 0; i < iModeSettingArySize; ++i, ++pModeSetting) {
+ Delay_ms = pModeSetting->u32Delay_ms;
+ RegAddr = pModeSetting->u16RegAddr;
+ Val = pModeSetting->u8Val;
+ Mask = pModeSetting->u8Mask;
+
+ if (Mask) {
+ retval = ov8820_read_reg(RegAddr, &RegVal);
+ if (retval < 0)
+ goto err;
+
+ RegVal &= ~(u8)Mask;
+ Val &= Mask;
+ Val |= RegVal;
+ }
+
+ retval = ov8820_write_reg(RegAddr, Val);
+ if (retval < 0)
+ goto err;
+
+ if (Delay_ms)
+ msleep(Delay_ms);
+ }
+
+ if (mipi_csi2_info) {
+ unsigned int i;
+
+ i = 0;
+
+ /* wait for mipi sensor ready */
+ mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
+ while ((mipi_reg == 0x200) && (i < 10)) {
+ mipi_reg = mipi_csi2_dphy_status(mipi_csi2_info);
+ i++;
+ msleep(10);
+ }
+
+ if (i >= 10) {
+ pr_err("mipi csi2 can not receive sensor clk!\n");
+ return -1;
+ }
+
+ i = 0;
+
+ /* wait for mipi stable */
+ mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
+ while ((mipi_reg != 0x0) && (i < 10)) {
+ mipi_reg = mipi_csi2_get_error1(mipi_csi2_info);
+ i++;
+ msleep(10);
+ }
+
+ if (i >= 10) {
+ pr_err("mipi csi2 can not reveive data correctly!\n");
+ return -1;
+ }
+ }
+err:
+ return retval;
+}
+
+/* --------------- IOCTL functions from v4l2_int_ioctl_desc --------------- */
+
+static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
+{
+ if (s == NULL) {
+ pr_err(" ERROR!! no slave device set!\n");
+ return -1;
+ }
+
+ memset(p, 0, sizeof(*p));
+ p->u.bt656.clock_curr = ov8820_data.mclk;
+ pr_debug(" clock_curr=mclk=%d\n", ov8820_data.mclk);
+ p->if_type = V4L2_IF_TYPE_BT656;
+ p->u.bt656.mode = V4L2_IF_TYPE_BT656_MODE_NOBT_8BIT;
+ p->u.bt656.clock_min = OV8820_XCLK_MIN;
+ p->u.bt656.clock_max = OV8820_XCLK_MAX;
+ p->u.bt656.bt_sync_correct = 1; /* Indicate external vsync */
+
+ return 0;
+}
+
+/*!
+ * ioctl_s_power - V4L2 sensor interface handler for VIDIOC_S_POWER ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @on: indicates power mode (on or off)
+ *
+ * Turns the power on or off, depending on the value of on and returns the
+ * appropriate error code.
+ */
+static int ioctl_s_power(struct v4l2_int_device *s, int on)
+{
+ struct sensor *sensor = s->priv;
+
+ if (on && !sensor->on) {
+ if (io_regulator)
+ if (regulator_enable(io_regulator) != 0)
+ return -EIO;
+ if (core_regulator)
+ if (regulator_enable(core_regulator) != 0)
+ return -EIO;
+ if (gpo_regulator)
+ if (regulator_enable(gpo_regulator) != 0)
+ return -EIO;
+ if (analog_regulator)
+ if (regulator_enable(analog_regulator) != 0)
+ return -EIO;
+ /* Make sure power on */
+ if (camera_plat->pwdn)
+ camera_plat->pwdn(0);
+
+ } else if (!on && sensor->on) {
+ if (analog_regulator)
+ regulator_disable(analog_regulator);
+ if (core_regulator)
+ regulator_disable(core_regulator);
+ if (io_regulator)
+ regulator_disable(io_regulator);
+ if (gpo_regulator)
+ regulator_disable(gpo_regulator);
+ }
+
+ sensor->on = on;
+
+ return 0;
+}
+
+/*!
+ * ioctl_g_parm - V4L2 sensor interface handler for VIDIOC_G_PARM ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
+ *
+ * Returns the sensor's video CAPTURE parameters.
+ */
+static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ struct sensor *sensor = s->priv;
+ struct v4l2_captureparm *cparm = &a->parm.capture;
+ int ret = 0;
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ memset(a, 0, sizeof(*a));
+ a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
+ cparm->capability = sensor->streamcap.capability;
+ cparm->timeperframe = sensor->streamcap.timeperframe;
+ cparm->capturemode = sensor->streamcap.capturemode;
+ ret = 0;
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_s_parm - V4L2 sensor interface handler for VIDIOC_S_PARM ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
+ *
+ * Configures the sensor to use the input parameters, if possible. If
+ * not possible, reverts to the old parameters and returns the
+ * appropriate error code.
+ */
+static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
+{
+ struct sensor *sensor = s->priv;
+ struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
+ u32 tgt_fps; /* target frames per secound */
+ enum ov8820_frame_rate frame_rate;
+ int ret = 0;
+
+ /* Make sure power on */
+ if (camera_plat->pwdn)
+ camera_plat->pwdn(0);
+
+ switch (a->type) {
+ /* This is the only case currently handled. */
+ case V4L2_BUF_TYPE_VIDEO_CAPTURE:
+ /* Check that the new frame rate is allowed. */
+ if ((timeperframe->numerator == 0) ||
+ (timeperframe->denominator == 0)) {
+ timeperframe->denominator = DEFAULT_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps > MAX_FPS) {
+ timeperframe->denominator = MAX_FPS;
+ timeperframe->numerator = 1;
+ } else if (tgt_fps < MIN_FPS) {
+ timeperframe->denominator = MIN_FPS;
+ timeperframe->numerator = 1;
+ }
+
+ /* Actual frame rate we use */
+ tgt_fps = timeperframe->denominator /
+ timeperframe->numerator;
+
+ if (tgt_fps == 15)
+ frame_rate = ov8820_15_fps;
+ else if (tgt_fps == 30)
+ frame_rate = ov8820_30_fps;
+ else {
+ pr_err(" The camera frame rate is not supported!\n");
+ return -EINVAL;
+ }
+
+ sensor->streamcap.timeperframe = *timeperframe;
+ sensor->streamcap.capturemode =
+ (u32)a->parm.capture.capturemode;
+
+ ret = ov8820_init_mode(frame_rate,
+ sensor->streamcap.capturemode);
+ break;
+
+ /* These are all the possible cases. */
+ case V4L2_BUF_TYPE_VIDEO_OUTPUT:
+ case V4L2_BUF_TYPE_VIDEO_OVERLAY:
+ case V4L2_BUF_TYPE_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_VBI_OUTPUT:
+ case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
+ case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
+ pr_debug(" type is not " \
+ "V4L2_BUF_TYPE_VIDEO_CAPTURE but %d\n",
+ a->type);
+ ret = -EINVAL;
+ break;
+
+ default:
+ pr_debug(" type is unknown - %d\n", a->type);
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_g_fmt_cap - V4L2 sensor interface handler for ioctl_g_fmt_cap
+ * @s: pointer to standard V4L2 device structure
+ * @f: pointer to standard V4L2 v4l2_format structure
+ *
+ * Returns the sensor's current pixel format in the v4l2_format
+ * parameter.
+ */
+static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
+{
+ struct sensor *sensor = s->priv;
+
+ f->fmt.pix = sensor->pix;
+
+ return 0;
+}
+
+/*!
+ * ioctl_g_ctrl - V4L2 sensor interface handler for VIDIOC_G_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_G_CTRL ioctl structure
+ *
+ * If the requested control is supported, returns the control's current
+ * value from the video_control[] array. Otherwise, returns -EINVAL
+ * if the control is not supported.
+ */
+static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int ret = 0;
+
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ vc->value = ov8820_data.brightness;
+ break;
+ case V4L2_CID_HUE:
+ vc->value = ov8820_data.hue;
+ break;
+ case V4L2_CID_CONTRAST:
+ vc->value = ov8820_data.contrast;
+ break;
+ case V4L2_CID_SATURATION:
+ vc->value = ov8820_data.saturation;
+ break;
+ case V4L2_CID_RED_BALANCE:
+ vc->value = ov8820_data.red;
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ vc->value = ov8820_data.blue;
+ break;
+ case V4L2_CID_EXPOSURE:
+ vc->value = ov8820_data.ae_mode;
+ break;
+ default:
+ ret = -EINVAL;
+ }
+
+ return ret;
+}
+
+/*!
+ * ioctl_s_ctrl - V4L2 sensor interface handler for VIDIOC_S_CTRL ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @vc: standard V4L2 VIDIOC_S_CTRL ioctl structure
+ *
+ * If the requested control is supported, sets the control's current
+ * value in HW (and updates the video_control[] array). Otherwise,
+ * returns -EINVAL if the control is not supported.
+ */
+static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
+{
+ int retval = 0;
+
+ pr_debug("In ov8820:ioctl_s_ctrl %d\n",
+ vc->id);
+
+ switch (vc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ break;
+ case V4L2_CID_CONTRAST:
+ break;
+ case V4L2_CID_SATURATION:
+ break;
+ case V4L2_CID_HUE:
+ break;
+ case V4L2_CID_AUTO_WHITE_BALANCE:
+ break;
+ case V4L2_CID_DO_WHITE_BALANCE:
+ break;
+ case V4L2_CID_RED_BALANCE:
+ break;
+ case V4L2_CID_BLUE_BALANCE:
+ break;
+ case V4L2_CID_GAMMA:
+ break;
+ case V4L2_CID_EXPOSURE:
+ break;
+ case V4L2_CID_AUTOGAIN:
+ break;
+ case V4L2_CID_GAIN:
+ break;
+ case V4L2_CID_HFLIP:
+ break;
+ case V4L2_CID_VFLIP:
+ break;
+ default:
+ retval = -EPERM;
+ break;
+ }
+
+ return retval;
+}
+
+/*!
+ * ioctl_enum_framesizes - V4L2 sensor interface handler for
+ * VIDIOC_ENUM_FRAMESIZES ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @fsize: standard V4L2 VIDIOC_ENUM_FRAMESIZES ioctl structure
+ *
+ * Return 0 if successful, otherwise -EINVAL.
+ */
+static int ioctl_enum_framesizes(struct v4l2_int_device *s,
+ struct v4l2_frmsizeenum *fsize)
+{
+ if (fsize->index > ov8820_mode_MAX)
+ return -EINVAL;
+
+ fsize->pixel_format = ov8820_data.pix.pixelformat;
+ fsize->discrete.width =
+ max(ov8820_mode_info_data[0][fsize->index].width,
+ ov8820_mode_info_data[1][fsize->index].width);
+ fsize->discrete.height =
+ max(ov8820_mode_info_data[0][fsize->index].height,
+ ov8820_mode_info_data[1][fsize->index].height);
+ return 0;
+}
+
+/*!
+ * ioctl_g_chip_ident - V4L2 sensor interface handler for
+ * VIDIOC_DBG_G_CHIP_IDENT ioctl
+ * @s: pointer to standard V4L2 device structure
+ * @id: pointer to int
+ *
+ * Return 0.
+ */
+static int ioctl_g_chip_ident(struct v4l2_int_device *s, int *id)
+{
+ ((struct v4l2_dbg_chip_ident *)id)->match.type =
+ V4L2_CHIP_MATCH_I2C_DRIVER;
+ strcpy(((struct v4l2_dbg_chip_ident *)id)->match.name, "ov8820_camera");
+
+ return 0;
+}
+
+/*!
+ * ioctl_init - V4L2 sensor interface handler for VIDIOC_INT_INIT
+ * @s: pointer to standard V4L2 device structure
+ */
+static int ioctl_init(struct v4l2_int_device *s)
+{
+
+ return 0;
+}
+
+/*!
+ * ioctl_enum_fmt_cap - V4L2 sensor interface handler for VIDIOC_ENUM_FMT
+ * @s: pointer to standard V4L2 device structure
+ * @fmt: pointer to standard V4L2 fmt description structure
+ *
+ * Return 0.
+ */
+static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
+ struct v4l2_fmtdesc *fmt)
+{
+ if (fmt->index > ov8820_mode_MAX)
+ return -EINVAL;
+
+ fmt->pixelformat = ov8820_data.pix.pixelformat;
+
+ return 0;
+}
+
+/*!
+ * ioctl_dev_init - V4L2 sensor interface handler for vidioc_int_dev_init_num
+ * @s: pointer to standard V4L2 device structure
+ *
+ * Initialise the device when slave attaches to the master.
+ */
+static int ioctl_dev_init(struct v4l2_int_device *s)
+{
+ struct sensor *sensor = s->priv;
+ u32 tgt_xclk; /* target xclk */
+ u32 tgt_fps; /* target frames per secound */
+ int ret;
+ enum ov8820_frame_rate frame_rate;
+ void *mipi_csi2_info;
+
+ ov8820_data.on = true;
+
+ /* mclk */
+ tgt_xclk = ov8820_data.mclk;
+ tgt_xclk = min(tgt_xclk, (u32)OV8820_XCLK_MAX);
+ tgt_xclk = max(tgt_xclk, (u32)OV8820_XCLK_MIN);
+ ov8820_data.mclk = tgt_xclk;
+
+ pr_debug(" Setting mclk to %d MHz\n", tgt_xclk / 1000000);
+ set_mclk_rate(&ov8820_data.mclk, ov8820_data.csi);
+
+ /* Default camera frame rate is set in probe */
+ tgt_fps = sensor->streamcap.timeperframe.denominator /
+ sensor->streamcap.timeperframe.numerator;
+
+ if (tgt_fps == 15)
+ frame_rate = ov8820_15_fps;
+ else if (tgt_fps == 30)
+ frame_rate = ov8820_30_fps;
+ else
+ return -EINVAL; /* Only support 15fps or 30fps now. */
+
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ /* enable mipi csi2 */
+ if (mipi_csi2_info)
+ mipi_csi2_enable(mipi_csi2_info);
+ else {
+ printk(KERN_ERR "Fail to get mipi_csi2_info!\n");
+ return -EPERM;
+ }
+
+ ret = ov8820_init_mode(frame_rate,
+ sensor->streamcap.capturemode);
+
+ return ret;
+}
+
+/*!
+ * ioctl_dev_exit - V4L2 sensor interface handler for vidioc_int_dev_exit_num
+ * @s: pointer to standard V4L2 device structure
+ *
+ * Delinitialise the device when slave detaches to the master.
+ */
+static int ioctl_dev_exit(struct v4l2_int_device *s)
+{
+ void *mipi_csi2_info;
+
+ mipi_csi2_info = mipi_csi2_get_info();
+
+ /* disable mipi csi2 */
+ if (mipi_csi2_info)
+ if (mipi_csi2_get_status(mipi_csi2_info))
+ mipi_csi2_disable(mipi_csi2_info);
+
+ return 0;
+}
+
+/*!
+ * This structure defines all the ioctls for this module and links them to the
+ * enumeration.
+ */
+static struct v4l2_int_ioctl_desc ov8820_ioctl_desc[] = {
+ {vidioc_int_dev_init_num, (v4l2_int_ioctl_func*) ioctl_dev_init},
+ {vidioc_int_dev_exit_num, ioctl_dev_exit},
+ {vidioc_int_s_power_num, (v4l2_int_ioctl_func*) ioctl_s_power},
+ {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func*) ioctl_g_ifparm},
+/* {vidioc_int_g_needs_reset_num,
+ (v4l2_int_ioctl_func *)ioctl_g_needs_reset}, */
+/* {vidioc_int_reset_num, (v4l2_int_ioctl_func *)ioctl_reset}, */
+ {vidioc_int_init_num, (v4l2_int_ioctl_func*) ioctl_init},
+ {vidioc_int_enum_fmt_cap_num,
+ (v4l2_int_ioctl_func *) ioctl_enum_fmt_cap},
+/* {vidioc_int_try_fmt_cap_num,
+ (v4l2_int_ioctl_func *)ioctl_try_fmt_cap}, */
+ {vidioc_int_g_fmt_cap_num, (v4l2_int_ioctl_func *) ioctl_g_fmt_cap},
+/* {vidioc_int_s_fmt_cap_num, (v4l2_int_ioctl_func *) ioctl_s_fmt_cap}, */
+ {vidioc_int_g_parm_num, (v4l2_int_ioctl_func *) ioctl_g_parm},
+ {vidioc_int_s_parm_num, (v4l2_int_ioctl_func *) ioctl_s_parm},
+/* {vidioc_int_queryctrl_num, (v4l2_int_ioctl_func *)ioctl_queryctrl}, */
+ {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *) ioctl_g_ctrl},
+ {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *) ioctl_s_ctrl},
+ {vidioc_int_enum_framesizes_num,
+ (v4l2_int_ioctl_func *) ioctl_enum_framesizes},
+ {vidioc_int_g_chip_ident_num,
+ (v4l2_int_ioctl_func *) ioctl_g_chip_ident},
+};
+
+static struct v4l2_int_slave ov8820_slave = {
+ .ioctls = ov8820_ioctl_desc,
+ .num_ioctls = ARRAY_SIZE(ov8820_ioctl_desc),
+};
+
+static struct v4l2_int_device ov8820_int_device = {
+ .module = THIS_MODULE,
+ .name = "ov8820",
+ .type = v4l2_int_type_slave,
+ .u = {
+ .slave = &ov8820_slave,
+ },
+};
+
+/*!
+ * ov8820 I2C probe function
+ *
+ * @param adapter struct i2c_adapter *
+ * @return Error code indicating success or failure
+ */
+static int ov8820_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int retval;
+ struct fsl_mxc_camera_platform_data *plat_data = client->dev.platform_data;
+
+ /* Set initial values for the sensor struct. */
+ memset(&ov8820_data, 0, sizeof(ov8820_data));
+ ov8820_data.mclk = 24000000; /* 6 - 54 MHz, typical 24MHz */
+ ov8820_data.mclk = plat_data->mclk;
+ ov8820_data.csi = plat_data->csi;
+
+ ov8820_data.i2c_client = client;
+ ov8820_data.pix.pixelformat = V4L2_PIX_FMT_SBGGR10;
+ ov8820_data.pix.width = 480;
+ ov8820_data.pix.height = 480;
+ ov8820_data.streamcap.capability = V4L2_MODE_HIGHQUALITY |
+ V4L2_CAP_TIMEPERFRAME;
+ ov8820_data.streamcap.capturemode = 0;
+ ov8820_data.streamcap.timeperframe.denominator = DEFAULT_FPS;
+ ov8820_data.streamcap.timeperframe.numerator = 1;
+
+ if (plat_data->io_regulator) {
+ io_regulator = regulator_get(&client->dev,
+ plat_data->io_regulator);
+ if (!IS_ERR(io_regulator)) {
+ regulator_set_voltage(io_regulator,
+ OV8820_VOLTAGE_DIGITAL_IO,
+ OV8820_VOLTAGE_DIGITAL_IO);
+ if (regulator_enable(io_regulator) != 0) {
+ pr_err("%s:io set voltage error\n", __func__);
+ goto err1;
+ } else {
+ dev_dbg(&client->dev,
+ "%s:io set voltage ok\n", __func__);
+ }
+ } else
+ io_regulator = NULL;
+ }
+
+ if (plat_data->core_regulator) {
+ core_regulator = regulator_get(&client->dev,
+ plat_data->core_regulator);
+ if (!IS_ERR(core_regulator)) {
+ regulator_set_voltage(core_regulator,
+ OV8820_VOLTAGE_DIGITAL_CORE,
+ OV8820_VOLTAGE_DIGITAL_CORE);
+ if (regulator_enable(core_regulator) != 0) {
+ pr_err("%s:core set voltage error\n", __func__);
+ goto err2;
+ } else {
+ dev_dbg(&client->dev,
+ "%s:core set voltage ok\n", __func__);
+ }
+ } else
+ core_regulator = NULL;
+ }
+
+ if (plat_data->analog_regulator) {
+ analog_regulator = regulator_get(&client->dev,
+ plat_data->analog_regulator);
+ if (!IS_ERR(analog_regulator)) {
+ regulator_set_voltage(analog_regulator,
+ OV8820_VOLTAGE_ANALOG,
+ OV8820_VOLTAGE_ANALOG);
+ if (regulator_enable(analog_regulator) != 0) {
+ pr_err("%s:analog set voltage error\n",
+ __func__);
+ goto err3;
+ } else {
+ dev_dbg(&client->dev,
+ "%s:analog set voltage ok\n", __func__);
+ }
+ } else
+ analog_regulator = NULL;
+ }
+
+ if (plat_data->io_init)
+ plat_data->io_init();
+
+ if (plat_data->pwdn)
+ plat_data->pwdn(0);
+
+ camera_plat = plat_data;
+
+ ov8820_int_device.priv = &ov8820_data;
+ retval = v4l2_int_device_register(&ov8820_int_device);
+
+ return retval;
+
+err3:
+ if (core_regulator) {
+ regulator_disable(core_regulator);
+ regulator_put(core_regulator);
+ }
+err2:
+ if (io_regulator) {
+ regulator_disable(io_regulator);
+ regulator_put(io_regulator);
+ }
+err1:
+ return -1;
+}
+
+/*!
+ * ov8820 I2C detach function
+ *
+ * @param client struct i2c_client *
+ * @return Error code indicating success or failure
+ */
+static int ov8820_remove(struct i2c_client *client)
+{
+ v4l2_int_device_unregister(&ov8820_int_device);
+
+ if (gpo_regulator) {
+ regulator_disable(gpo_regulator);
+ regulator_put(gpo_regulator);
+ }
+
+ if (analog_regulator) {
+ regulator_disable(analog_regulator);
+ regulator_put(analog_regulator);
+ }
+
+ if (core_regulator) {
+ regulator_disable(core_regulator);
+ regulator_put(core_regulator);
+ }
+
+ if (io_regulator) {
+ regulator_disable(io_regulator);
+ regulator_put(io_regulator);
+ }
+
+ return 0;
+}
+
+/*!
+ * ov8820 init function
+ * Called by insmod ov8820_camera.ko.
+ *
+ * @return Error code indicating success or failure
+ */
+static __init int ov8820_init(void)
+{
+ u8 err;
+
+ err = i2c_add_driver(&ov8820_i2c_driver);
+ if (err != 0)
+ pr_err("%s:driver registration failed, error=%d\n",
+ __func__, err);
+
+ return err;
+}
+
+/*!
+ * OV8820 cleanup function
+ * Called on rmmod ov8820_camera.ko
+ *
+ * @return Error code indicating success or failure
+ */
+static void __exit ov8820_clean(void)
+{
+ i2c_del_driver(&ov8820_i2c_driver);
+}
+
+module_init(ov8820_init);
+module_exit(ov8820_clean);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("OV8820 MIPI Camera Driver");
+MODULE_LICENSE("GPL");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("CSI");
diff --git a/drivers/media/video/mxc/output/mxc_vout.c b/drivers/media/video/mxc/output/mxc_vout.c
index d7e6fa3e02c3..57e684f99308 100644
--- a/drivers/media/video/mxc/output/mxc_vout.c
+++ b/drivers/media/video/mxc/output/mxc_vout.c
@@ -61,6 +61,7 @@ struct mxc_vout_output {
bool disp_support_csc;
bool fmt_init;
+ bool bypass_pp;
struct ipu_task task;
bool timer_stop;
@@ -318,7 +319,7 @@ static bool is_pp_bypass(struct mxc_vout_output *vout)
(vout->task.input.height == vout->task.output.height) &&
(vout->task.input.crop.w == vout->task.output.crop.w) &&
(vout->task.input.crop.h == vout->task.output.crop.h) &&
- (vout->task.output.rotate < IPU_ROTATE_90_RIGHT) &&
+ (vout->task.output.rotate < IPU_ROTATE_HORIZ_FLIP) &&
!vout->task.input.deinterlace.enable) {
if (vout->disp_support_csc)
return true;
@@ -329,7 +330,7 @@ static bool is_pp_bypass(struct mxc_vout_output *vout)
(vout->task.output.crop.w == vout->task.output.width) &&
(vout->task.input.crop.h == vout->task.output.crop.h) &&
(vout->task.output.crop.h == vout->task.output.height) &&
- (vout->task.output.rotate < IPU_ROTATE_90_RIGHT) &&
+ (vout->task.output.rotate < IPU_ROTATE_HORIZ_FLIP) &&
!vout->task.input.deinterlace.enable) {
if (vout->disp_support_csc)
return true;
@@ -367,7 +368,8 @@ static void setup_buf_timer(struct mxc_vout_output *vout,
"timer handler next schedule: %lu\n", timeout);
}
-static int show_buf(struct mxc_vout_output *vout, int idx)
+static int show_buf(struct mxc_vout_output *vout, int idx,
+ struct ipu_pos *ipos)
{
struct fb_info *fbi = vout->fbi;
struct fb_var_screeninfo var;
@@ -375,16 +377,16 @@ static int show_buf(struct mxc_vout_output *vout, int idx)
memcpy(&var, &fbi->var, sizeof(var));
- if (is_pp_bypass(vout)) {
+ if (vout->bypass_pp) {
/*
* crack fb base
* NOTE: should not do other fb operation during v4l2
*/
console_lock();
fbi->fix.smem_start = vout->task.output.paddr;
- fbi->var.yoffset = vout->task.input.crop.pos.y + 1;
- var.xoffset = vout->task.input.crop.pos.x;
- var.yoffset = vout->task.input.crop.pos.y;
+ fbi->var.yoffset = ipos->y + 1;
+ var.xoffset = ipos->x;
+ var.yoffset = ipos->y;
ret = fb_pan_display(fbi, &var);
console_unlock();
} else {
@@ -404,8 +406,11 @@ static void disp_work_func(struct work_struct *work)
struct videobuf_queue *q = &vout->vbq;
struct videobuf_buffer *vb, *vb_next = NULL;
unsigned long flags = 0;
+ struct ipu_pos ipos;
int ret = 0;
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "disp work begin one frame\n");
+
spin_lock_irqsave(q->irqlock, flags);
if (deinterlace_3_field(vout)) {
@@ -439,9 +444,11 @@ static void disp_work_func(struct work_struct *work)
else
vout->task.input.paddr = videobuf_to_dma_contig(vb);
- if (is_pp_bypass(vout))
+ if (vout->bypass_pp) {
vout->task.output.paddr = vout->task.input.paddr;
- else {
+ ipos.x = vout->task.input.crop.pos.x;
+ ipos.y = vout->task.input.crop.pos.y;
+ } else {
if (deinterlace_3_field(vout)) {
if (vb->memory == V4L2_MEMORY_USERPTR)
vout->task.input.paddr_n = vb_next->baddr;
@@ -458,29 +465,35 @@ static void disp_work_func(struct work_struct *work)
}
}
- ret = show_buf(vout, vout->frame_count % FB_BUFS);
- if (ret < 0)
- v4l2_warn(vout->vfd->v4l2_dev, "show buf with ret %d\n", ret);
-
mutex_unlock(&vout->task_lock);
+ ret = show_buf(vout, vout->frame_count % FB_BUFS, &ipos);
+ if (ret < 0)
+ v4l2_dbg(1, debug, vout->vfd->v4l2_dev, "show buf with ret %d\n", ret);
+
spin_lock_irqsave(q->irqlock, flags);
list_del(&vb->queue);
/*
* previous videobuf finish show, set VIDEOBUF_DONE state here
- * to avoid tearing issue, which make sure showing buffer will
- * not be dequeue to write new data. It also bring side-effect
- * that the last buffer can not be dequeue correctly, app need
- * take care about it.
+ * to avoid tearing issue in pp bypass case, which make sure
+ * showing buffer will not be dequeue to write new data. It also
+ * bring side-effect that the last buffer can not be dequeue
+ * correctly, app need take care about it.
*/
if (vout->pre_vb) {
vout->pre_vb->state = VIDEOBUF_DONE;
wake_up_interruptible(&vout->pre_vb->done);
}
- vout->pre_vb = vb;
+ if (vout->bypass_pp)
+ vout->pre_vb = vb;
+ else {
+ vout->pre_vb = NULL;
+ vb->state = VIDEOBUF_DONE;
+ wake_up_interruptible(&vb->done);
+ }
vout->frame_count++;
@@ -651,8 +664,10 @@ static int mxc_vout_release(struct file *file)
q = &vout->vbq;
if (q->streaming)
mxc_vidioc_streamoff(file, vout, vout->type);
- else
+ else {
+ release_disp_output(vout);
videobuf_queue_cancel(q);
+ }
destroy_workqueue(vout->v4l_wq);
ret = videobuf_mmap_free(q);
}
@@ -757,9 +772,10 @@ static int mxc_vidioc_g_fmt_vid_out(struct file *file, void *fh,
return 0;
}
-static inline int ipu_try_task(struct ipu_task *task)
+static inline int ipu_try_task(struct mxc_vout_output *vout)
{
int ret;
+ struct ipu_task *task = &vout->task;
again:
ret = ipu_check_task(task);
@@ -774,11 +790,19 @@ again:
goto again;
}
if (ret == IPU_CHECK_ERR_SPLIT_OUTPUTW_OVER) {
- task->output.crop.w -= 8;
+ if (vout->disp_support_windows) {
+ task->output.width -= 8;
+ task->output.crop.w = task->output.width;
+ } else
+ task->output.crop.w -= 8;
goto again;
}
if (ret == IPU_CHECK_ERR_SPLIT_OUTPUTH_OVER) {
- task->output.crop.h -= 8;
+ if (vout->disp_support_windows) {
+ task->output.height -= 8;
+ task->output.crop.h = task->output.height;
+ } else
+ task->output.crop.h -= 8;
goto again;
}
ret = -EINVAL;
@@ -799,9 +823,11 @@ static int mxc_vout_try_task(struct mxc_vout_output *vout)
/* assume task.output already set by S_CROP */
if (is_pp_bypass(vout)) {
v4l2_info(vout->vfd->v4l2_dev, "Bypass IC.\n");
+ vout->bypass_pp = true;
vout->task.output.format = vout->task.input.format;
} else {
/* if need CSC, choose IPU-DP or IPU_IC do it */
+ vout->bypass_pp = false;
if (vout->disp_support_csc) {
if (colorspaceofpixel(vout->task.input.format) == YUV_CS)
vout->task.output.format = IPU_PIX_FMT_UYVY;
@@ -813,7 +839,7 @@ static int mxc_vout_try_task(struct mxc_vout_output *vout)
else
vout->task.output.format = IPU_PIX_FMT_RGB565;
}
- ret = ipu_try_task(&vout->task);
+ ret = ipu_try_task(vout);
}
return ret;
@@ -979,10 +1005,26 @@ static int mxc_vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop
crop->c.height -= crop->c.height % 8;
crop->c.width -= crop->c.width % 8;
- mutex_lock(&vout->task_lock);
+ /* the same setting, return */
+ if (vout->disp_support_windows) {
+ if ((vout->win_pos.x == crop->c.left) &&
+ (vout->win_pos.y == crop->c.top) &&
+ (vout->task.output.crop.w == crop->c.width) &&
+ (vout->task.output.crop.h == crop->c.height))
+ return 0;
+ } else {
+ if ((vout->task.output.crop.pos.x == crop->c.left) &&
+ (vout->task.output.crop.pos.y == crop->c.top) &&
+ (vout->task.output.crop.w == crop->c.width) &&
+ (vout->task.output.crop.h == crop->c.height))
+ return 0;
+ }
- if (vout->fmt_init && vout->vbq.streaming)
- release_disp_output(vout);
+ /* wait current work finish */
+ if (vout->vbq.streaming)
+ cancel_work_sync(&vout->disp_work);
+
+ mutex_lock(&vout->task_lock);
if (vout->disp_support_windows) {
vout->task.output.crop.pos.x = 0;
@@ -1005,6 +1047,9 @@ static int mxc_vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop
* check ipu task too.
*/
if (vout->fmt_init) {
+ if (vout->vbq.streaming)
+ release_disp_output(vout);
+
ret = mxc_vout_try_task(vout);
if (ret < 0) {
v4l2_err(vout->vfd->v4l2_dev,
@@ -1125,6 +1170,10 @@ static int mxc_vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c
int ret = 0;
struct mxc_vout_output *vout = fh;
+ /* wait current work finish */
+ if (vout->vbq.streaming)
+ cancel_work_sync(&vout->disp_work);
+
mutex_lock(&vout->task_lock);
switch (ctrl->id) {
case V4L2_CID_ROTATE:
@@ -1154,8 +1203,32 @@ static int mxc_vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c
}
default:
ret = -EINVAL;
+ goto done;
+ }
+
+ if (vout->fmt_init) {
+ if (vout->vbq.streaming)
+ release_disp_output(vout);
+
+ ret = mxc_vout_try_task(vout);
+ if (ret < 0) {
+ v4l2_err(vout->vfd->v4l2_dev,
+ "vout check task failed\n");
+ goto done;
+ }
+ if (vout->vbq.streaming) {
+ ret = config_disp_output(vout);
+ if (ret < 0) {
+ v4l2_err(vout->vfd->v4l2_dev,
+ "Config display output failed\n");
+ goto done;
+ }
+ }
}
+
+done:
mutex_unlock(&vout->task_lock);
+
return ret;
}
@@ -1216,7 +1289,7 @@ static int mxc_vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
return videobuf_dqbuf(&vout->vbq, (struct v4l2_buffer *)b, 0);
}
-static int set_window_position(struct mxc_vout_output *vout)
+static int set_window_position(struct mxc_vout_output *vout, struct mxcfb_pos *pos)
{
struct fb_info *fbi = vout->fbi;
mm_segment_t old_fs;
@@ -1226,7 +1299,7 @@ static int set_window_position(struct mxc_vout_output *vout)
old_fs = get_fs();
set_fs(KERNEL_DS);
ret = fbi->fbops->fb_ioctl(fbi, MXCFB_SET_OVERLAY_POS,
- (unsigned long)&vout->win_pos);
+ (unsigned long)pos);
set_fs(old_fs);
}
@@ -1243,7 +1316,7 @@ static int config_disp_output(struct mxc_vout_output *vout)
var.xres = vout->task.output.width;
var.yres = vout->task.output.height;
- if (is_pp_bypass(vout)) {
+ if (vout->bypass_pp) {
fb_num = 1;
/* input crop */
if (vout->task.input.width > vout->task.output.width)
@@ -1254,6 +1327,7 @@ static int config_disp_output(struct mxc_vout_output *vout)
var.yres_virtual = vout->task.input.height;
else
var.yres_virtual = var.yres;
+ var.rotate = vout->task.output.rotate;
} else {
fb_num = FB_BUFS;
var.xres_virtual = var.xres;
@@ -1266,7 +1340,7 @@ static int config_disp_output(struct mxc_vout_output *vout)
"set display fb to %d %d\n",
var.xres, var.yres);
- ret = set_window_position(vout);
+ ret = set_window_position(vout, &vout->win_pos);
if (ret < 0)
return ret;
@@ -1286,7 +1360,9 @@ static int config_disp_output(struct mxc_vout_output *vout)
vout->disp_bufs[i] = fbi->fix.smem_start + i * display_buf_size;
console_lock();
+ fbi->flags |= FBINFO_MISC_USEREVENT;
ret = fb_blank(fbi, FB_BLANK_UNBLANK);
+ fbi->flags &= ~FBINFO_MISC_USEREVENT;
console_unlock();
return ret;
@@ -1295,13 +1371,21 @@ static int config_disp_output(struct mxc_vout_output *vout)
static void release_disp_output(struct mxc_vout_output *vout)
{
struct fb_info *fbi = vout->fbi;
+ struct mxcfb_pos pos;
console_lock();
+ fbi->flags |= FBINFO_MISC_USEREVENT;
fb_blank(fbi, FB_BLANK_POWERDOWN);
+ fbi->flags &= ~FBINFO_MISC_USEREVENT;
console_unlock();
+ /* restore pos to 0,0 avoid fb pan display hang? */
+ pos.x = 0;
+ pos.y = 0;
+ set_window_position(vout, &pos);
+
/* fix if ic bypass crack smem_start */
- if (is_pp_bypass(vout)) {
+ if (vout->bypass_pp) {
console_lock();
fbi->fix.smem_start = vout->disp_bufs[0];
console_unlock();
@@ -1309,7 +1393,9 @@ static void release_disp_output(struct mxc_vout_output *vout)
if (get_ipu_channel(fbi) == MEM_BG_SYNC) {
console_lock();
+ fbi->flags |= FBINFO_MISC_USEREVENT;
fb_blank(fbi, FB_BLANK_UNBLANK);
+ fbi->flags &= ~FBINFO_MISC_USEREVENT;
console_unlock();
}
}
@@ -1362,11 +1448,11 @@ static int mxc_vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type
int ret = 0;
if (q->streaming) {
- del_timer(&vout->timer);
-
cancel_work_sync(&vout->disp_work);
flush_workqueue(vout->v4l_wq);
+ del_timer_sync(&vout->timer);
+
release_disp_output(vout);
ret = videobuf_streamoff(&vout->vbq);
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 7ae1ff64a48c..65bcce3c7fb3 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -499,7 +499,7 @@ config APANIC_PLABEL
crashdumps, enter it here.
config MXS_PERFMON
tristate "i.MX Performance Monitor"
- depends on ARCH_MX50
+ depends on ARCH_MX50 || ARCH_MX6
default y
source "drivers/misc/c2port/Kconfig"
diff --git a/drivers/misc/mxs-perfmon.c b/drivers/misc/mxs-perfmon.c
index 94916e000e84..5986e1ca9508 100644
--- a/drivers/misc/mxs-perfmon.c
+++ b/drivers/misc/mxs-perfmon.c
@@ -27,6 +27,7 @@
#include <linux/platform_device.h>
#include <linux/sysfs.h>
#include <linux/io.h>
+#include <linux/clk.h>
#include <linux/fsl_devices.h>
#include <mach/hardware.h>
#include <asm/irq.h>
@@ -104,6 +105,7 @@ struct mxs_perfmon_data {
struct attribute_group attr_group;
unsigned int base;
unsigned int initial;
+ struct clk *clk;
/* attribute ** follow */
/* device_attribute follow */
};
@@ -150,6 +152,7 @@ perfmon_show(struct device *dev, struct device_attribute *attr, char *buf)
int idx;
u32 val;
ssize_t result = 0;
+ struct mxs_platform_perfmon_data *pdata = pdev->dev.platform_data;
idx = attr - devattr;
if ((unsigned int)idx >= pd->count)
@@ -163,6 +166,11 @@ perfmon_show(struct device *dev, struct device_attribute *attr, char *buf)
[idx - pd->pdata->bit_config_cnt];
if (!pd->initial) {
+ if (pd->clk)
+ clk_enable(pd->clk);
+ if (pdata->plt_init)
+ pdata->plt_init();
+
mxs_reset_block((void *)pd->base, true);
pd->initial = true;
}
@@ -204,6 +212,7 @@ perfmon_store(struct device *dev, struct device_attribute *attr,
struct mxs_perfmon_bit_config *pb;
int idx, r;
unsigned long val, newval;
+ struct mxs_platform_perfmon_data *pdata = pdev->dev.platform_data;
idx = attr - devattr;
if ((unsigned int)idx >= pd->count)
@@ -220,6 +229,11 @@ perfmon_store(struct device *dev, struct device_attribute *attr,
[idx - pd->pdata->bit_config_cnt];
if (!pd->initial) {
+ if (pd->clk)
+ clk_enable(pd->clk);
+ if (pdata->plt_init)
+ pdata->plt_init();
+
mxs_reset_block((void *)pd->base, true);
pd->initial = true;
}
@@ -278,6 +292,7 @@ static int __devinit mxs_perfmon_probe(struct platform_device *pdev)
struct device_attribute *devattr;
int i, cnt, size;
int err;
+ struct device *dev = &pdev->dev;
pdata = pdev->dev.platform_data;
if (pdata == NULL)
@@ -301,6 +316,7 @@ static int __devinit mxs_perfmon_probe(struct platform_device *pdev)
pd->pdata_common = pdata_common;
pd->base = (unsigned int)ioremap(res->start, res->end - res->start);
pd->initial = false;
+ pd->clk = clk_get(dev, "perfmon");
platform_set_drvdata(pdev, pd);
pd->count = cnt;
@@ -341,10 +357,21 @@ static int __devinit mxs_perfmon_probe(struct platform_device *pdev)
static int __devexit mxs_perfmon_remove(struct platform_device *pdev)
{
struct mxs_perfmon_data *pd;
+ struct mxs_platform_perfmon_data *pdata = pdev->dev.platform_data;;
pd = platform_get_drvdata(pdev);
sysfs_remove_group(&pdev->dev.kobj, &pd->attr_group);
platform_set_drvdata(pdev, NULL);
+
+ if (pdata->plt_exit)
+ pdata->plt_exit();
+
+ if (pd->clk) {
+ if (pd->initial)
+ clk_disable(pd->clk);
+ clk_put(pd->clk);
+ }
+
kfree(pd);
return 0;
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index e68884c849e9..3f164e7ba7fa 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -104,7 +104,7 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
if (boarddata && gpio_is_valid(boarddata->cd_gpio)
&& gpio_get_value(boarddata->cd_gpio))
/* no card, if a valid gpio says so... */
- val &= SDHCI_CARD_PRESENT;
+ val &= ~SDHCI_CARD_PRESENT;
else
/* ... in all other cases assume card is present */
val |= SDHCI_CARD_PRESENT;
@@ -469,6 +469,8 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
host->ocr_avail_sd |= MMC_VDD_165_195;
if (boarddata->support_8bit)
host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+ if (boarddata->keep_power_at_suspend)
+ host->mmc->pm_caps |= MMC_PM_KEEP_POWER;
if (cpu_is_mx6q()) {
host->mmc->caps |= MMC_CAP_1_8V_DDR;
host->tuning_min = SDHCI_TUNE_CTRL_MIN;
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index dad820ad423f..c051ea791e95 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -1398,7 +1398,7 @@ static void sdhci_tasklet_card(unsigned long param)
out:
spin_unlock_irqrestore(&host->lock, flags);
- mmc_detect_change(host->mmc, msecs_to_jiffies(200));
+ mmc_detect_change(host->mmc, msecs_to_jiffies(500));
}
static void sdhci_tasklet_finish(unsigned long param)
diff --git a/drivers/mxc/gpu-viv/Kbuild b/drivers/mxc/gpu-viv/Kbuild
index fee9dfdc9d62..aa1ec7bf5eba 100644
--- a/drivers/mxc/gpu-viv/Kbuild
+++ b/drivers/mxc/gpu-viv/Kbuild
@@ -209,6 +209,15 @@ else
EXTRA_CFLAGS += -DgcdSMP=0
endif
+ifeq ($(VIVANTE_NO_3D),1)
+EXTRA_CFLAGS += -DVIVANTE_NO_3D
+endif
+
+ifeq ($(ENABLE_OUTER_CACHE_PATCH), 1)
+EXTRA_CFLAGS += -DgcdENABLE_OUTER_CACHE_PATCH=1
+else
+EXTRA_CFLAGS += -DgcdENABLE_OUTER_CACHE_PATCH=0
+endif
EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel/inc
EXTRA_CFLAGS += -I$(AQROOT)/hal/kernel
diff --git a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c
index 2b5e9ece7fc3..20c79b88806f 100644
--- a/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c
+++ b/drivers/mxc/gpu-viv/arch/GC350/hal/kernel/gc_hal_kernel_hardware_vg.c
@@ -1792,7 +1792,7 @@ gckVGHARDWARE_SetPowerManagementState(
gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->idleSemaphore));
}
/* Reset power off time */
- gcmkONERROR(gckOS_GetTicks(&currentTime));
+ gcmkVERIFY_OK(gckOS_GetTicks(&currentTime));
Hardware->powerOffTime = currentTime + Hardware->powerOffTimeout;
if (commitMutex)
diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
index dbf8680cf9d3..f1b4dd099cec 100644
--- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
+++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_context.c
@@ -67,6 +67,14 @@
gcvFALSE, gcvFALSE \
)
+#define _STATE_MIRROR(reg, mirror) \
+ _StateMirror(\
+ Context, \
+ reg ## _Address >> 2, \
+ reg ## _Count, \
+ mirror ## _Address >> 2 \
+ )
+
#define _STATE_HINT(reg) \
_State(\
Context, index, \
@@ -353,6 +361,32 @@ _State(
/* Return number of slots required. */
return Size;
}
+
+static gctSIZE_T
+_StateMirror(
+ IN gckCONTEXT Context,
+ IN gctUINT32 Address,
+ IN gctSIZE_T Size,
+ IN gctUINT32 AddressMirror
+ )
+{
+ gctSIZE_T i;
+
+ /* Process when buffer is set. */
+ if (Context->buffer != gcvNULL)
+ {
+ /* Walk all states. */
+ for (i = 0; i < Size; i++)
+ {
+ /* Copy the mapping address. */
+ Context->map[Address + i].index =
+ Context->map[AddressMirror + i].index;
+ }
+ }
+
+ /* Return the number of required maps. */
+ return Size;
+}
#endif
static gceSTATUS
@@ -565,7 +599,7 @@ _InitializeContextBuffer(
index += _State(Context, index, 0x0091C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
index += _CLOSE_RANGE();
- if (Context->hardware->identity.instructionCount >= 2048)
+ if (Context->hardware->identity.instructionCount > 1024)
{
/* New Shader instruction memory. */
index += _State(Context, index, 0x0085C >> 2, 0x00000000, 1, gcvFALSE, gcvFALSE);
@@ -579,7 +613,7 @@ _InitializeContextBuffer(
index += _CLOSE_RANGE();
}
}
- else if (Context->hardware->identity.instructionCount >= 1024)
+ else if (Context->hardware->identity.instructionCount > 256)
{
/* VX instruction memory. */
for (i = 0; i < 4096; i += 1024)
@@ -588,11 +622,7 @@ _InitializeContextBuffer(
index += _CLOSE_RANGE();
}
- for (i = 0; i < 4096; i += 1024)
- {
- index += _State(Context, index, (0x08000 >> 2) + i, 0x00000000, 1024, gcvFALSE, gcvFALSE);
- index += _CLOSE_RANGE();
- }
+ index += _StateMirror(Context, (0x08000 >> 2), 4096, 0x0C000 >> 2);
}
/* Store the index of the "XD" entry. */
diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
index fe6c1a93bfe6..0ceced9754bb 100644
--- a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
+++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
@@ -715,15 +715,15 @@ gckHARDWARE_InitializeHardware(
0x00418,
baseAddress));
-#ifndef VIVANTE_NO_3D
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
Hardware->core,
- 0x00420,
+ 0x00428,
baseAddress));
+#ifndef VIVANTE_NO_3D
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
Hardware->core,
- 0x00428,
+ 0x00420,
baseAddress));
gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os,
@@ -3684,6 +3684,22 @@ gckHARDWARE_SetPowerManagementState(
Hardware->powerMutex,
gcvINFINITE));
mutexAcquired = gcvTRUE;
+
+ /* chipPowerState may be changed by external world during the time
+ ** we give up powerMutex, so updating flag now is necessary. */
+ flag = flags[Hardware->chipPowerState][State];
+
+ if (flag == 0)
+ {
+ gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
+ globalAcquired = gcvFALSE;
+
+ gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex));
+ mutexAcquired = gcvFALSE;
+
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+ }
}
else
{
@@ -3695,6 +3711,40 @@ gckHARDWARE_SetPowerManagementState(
gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
globalAcquired = gcvFALSE;
}
+ else
+ {
+ if (State == gcvPOWER_OFF || State == gcvPOWER_SUSPEND || State == gcvPOWER_IDLE)
+ {
+ /* Acquire the global semaphore if it has not been acquired. */
+ status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
+ if (status == gcvSTATUS_OK)
+ {
+ globalAcquired = gcvTRUE;
+ }
+ else if (status != gcvSTATUS_TIMEOUT)
+ {
+ /* Other errors. */
+ gcmkONERROR(status);
+ }
+ /* Ignore gcvSTATUS_TIMEOUT and leave globalAcquired as gcvFALSE.
+ ** gcvSTATUS_TIMEOUT means global semaphore has already
+ ** been acquired before this operation, so even if we fail,
+ ** we should not release it in our error handling. It should be
+ ** released by the next successful global gcvPOWER_ON. */
+ }
+
+ /* Global power management can't be aborted, so sync with
+ ** proceeding last commit. */
+ if (flag & gcvPOWER_FLAG_ACQUIRE)
+ {
+ /* Acquire the power management semaphore. */
+ gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
+ acquired = gcvTRUE;
+
+ /* avoid acquiring again. */
+ flag &= ~gcvPOWER_FLAG_ACQUIRE;
+ }
+ }
if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON))
{
@@ -3714,15 +3764,20 @@ gckHARDWARE_SetPowerManagementState(
gctBOOL idle;
gctINT32 atomValue;
- /* Check commit atom. */
- gcmkONERROR(gckOS_AtomGet(os, command->atomCommit, &atomValue));
-
- if (atomValue > 0)
+ /* For global operation, all pending commits have already been
+ ** blocked by globalSemaphore or powerSemaphore.*/
+ if (!global)
{
- /* Commits are pending - abort power management. */
- status = broadcast ? gcvSTATUS_CHIP_NOT_READY
- : gcvSTATUS_MORE_DATA;
- goto OnError;
+ /* Check commit atom. */
+ gcmkONERROR(gckOS_AtomGet(os, command->atomCommit, &atomValue));
+
+ if (atomValue > 0)
+ {
+ /* Commits are pending - abort power management. */
+ status = broadcast ? gcvSTATUS_CHIP_NOT_READY
+ : gcvSTATUS_MORE_DATA;
+ goto OnError;
+ }
}
if (broadcast)
@@ -3780,13 +3835,6 @@ gckHARDWARE_SetPowerManagementState(
/* Acquire the power management semaphore. */
gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore));
acquired = gcvTRUE;
-
- if (global)
- {
- /* Acquire the global semaphore. */
- gcmkONERROR(gckOS_AcquireSemaphore(os, Hardware->globalSemaphore));
- globalAcquired = gcvTRUE;
- }
}
if (flag & gcvPOWER_FLAG_STOP)
@@ -3796,7 +3844,7 @@ gckHARDWARE_SetPowerManagementState(
/* Stop the Isr. */
gcmkONERROR(Hardware->stopIsr(Hardware->isrContext));
- }
+ }
/* Get time until stopped. */
gcmkPROFILE_QUERY(time, stopTime);
@@ -3883,6 +3931,18 @@ gckHARDWARE_SetPowerManagementState(
if (global)
{
+ /* Verify global semaphore has been acquired already before
+ ** we release it.
+ ** If it was acquired, gckOS_TryAcquireSemaphore will return
+ ** gcvSTATUS_TIMEOUT and we release it. Otherwise, global
+ ** semaphore will be acquried now, but it still is released
+ ** immediately. */
+ status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore);
+ if (status != gcvSTATUS_TIMEOUT)
+ {
+ gcmkONERROR(status);
+ }
+
/* Release the global semaphore. */
gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore));
globalAcquired = gcvFALSE;
diff --git a/drivers/mxc/gpu-viv/config b/drivers/mxc/gpu-viv/config
index 043a91b535f2..68a43adf1aae 100644
--- a/drivers/mxc/gpu-viv/config
+++ b/drivers/mxc/gpu-viv/config
@@ -29,4 +29,7 @@ NONPAGED_MEMORY_BUFFERABLE ?= 1
CACHE_FUNCTION_UNIMPLEMENTED ?= 0
VIVANTE_ENABLE_VG ?= 1
NO_USER_DIRECT_ACCESS_FROM_KERNEL ?= 1
+VIVANTE_NO_3D ?= 0
+ENABLE_OUTER_CACHE_PATCH ?= 1
ENABLE_GPU_CLOCK_BY_DRIVER = 1
+
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
index 8af629283ea2..4aeb53ce883a 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
@@ -681,13 +681,6 @@ gckKERNEL_Dispatch(
/* Get the current process ID. */
gcmkONERROR(gckOS_GetProcessID(&processID));
-#ifdef UNDER_CE
- if (!FromUser)
- {
- gcmkONERROR(gckOS_GetCurrentProcessID(&processID));
- }
-#endif
-
#if gcdSECURE_USER
gcmkONERROR(gckKERNEL_GetProcessDBCache(Kernel, processID, &cache));
#endif
@@ -1566,23 +1559,81 @@ gckKERNEL_Dispatch(
if ((node = Interface->u.GetSharedInfo.node) != gcvNULL)
{
- if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
- {
- data = &node->VidMem.sharedInfo;
- }
- else
- {
- data = &node->Virtual.sharedInfo;
- }
+ switch (Interface->u.GetSharedInfo.infoType)
+ {
+ case gcvVIDMEM_INFO_GENERIC:
+ { /* Generic data stored */
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ data = &node->VidMem.sharedInfo;
+
+ }
+ else
+ {
+ data = &node->Virtual.sharedInfo;
+ }
+
+ gcmkONERROR(gckOS_CopyToUserData(
+ Kernel->os,
+ data,
+ Interface->u.GetSharedInfo.nodeData,
+ sizeof(gcsVIDMEM_NODE_SHARED_INFO)
+ ));
+ }
+ break;
- gcmkONERROR(gckOS_CopyToUserData(
- Kernel->os,
- data,
- Interface->u.GetSharedInfo.nodeData,
- sizeof(gcsVIDMEM_NODE_SHARED_INFO)
- ));
+ case gcvVIDMEM_INFO_DIRTY_RECTANGLE:
+ { /* Dirty rectangle stored */
+ gcsVIDMEM_NODE_SHARED_INFO *storedSharedInfo;
+ gcsVIDMEM_NODE_SHARED_INFO alignedSharedInfo;
+
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ storedSharedInfo = &node->VidMem.sharedInfo;
+ }
+ else
+ {
+ storedSharedInfo = &node->Virtual.sharedInfo;
+ }
+
+ /* Stored shared info holds the unaligned dirty rectangle.
+ Align it first. */
+
+ /* Hardware requires 64-byte aligned address, and 16x4 pixel aligned rectsize.
+ We simply align to 32 pixels which covers both 16- and 32-bpp formats. */
+
+ /* Make sure we have a legit rectangle. */
+ gcmkASSERT((storedSharedInfo->RectSize.width != 0) && (storedSharedInfo->RectSize.height != 0));
+
+ alignedSharedInfo.SrcOrigin.x = gcmALIGN_BASE(storedSharedInfo->SrcOrigin.x, 32);
+ alignedSharedInfo.RectSize.width = gcmALIGN((storedSharedInfo->RectSize.width + (storedSharedInfo->SrcOrigin.x - alignedSharedInfo.SrcOrigin.x)), 16);
+
+ alignedSharedInfo.SrcOrigin.y = gcmALIGN_BASE(storedSharedInfo->SrcOrigin.y, 4);
+ alignedSharedInfo.RectSize.height = gcmALIGN((storedSharedInfo->RectSize.height + (storedSharedInfo->SrcOrigin.y - alignedSharedInfo.SrcOrigin.y)), 4);
+
+ gcmkONERROR(gckOS_CopyToUserData(
+ Kernel->os,
+ &alignedSharedInfo,
+ Interface->u.GetSharedInfo.nodeData,
+ sizeof(gcsVIDMEM_NODE_SHARED_INFO)
+ ));
+
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_KERNEL,
+ "Node = %p, unaligned rectangle (l=%d, t=%d, w=%d, h=%d) aligned to (l=%d, t=%d, w=%d, h=%d)", node,
+ storedSharedInfo->SrcOrigin.x, storedSharedInfo->SrcOrigin.y,
+ storedSharedInfo->RectSize.width, storedSharedInfo->RectSize.height,
+ alignedSharedInfo.SrcOrigin.x, alignedSharedInfo.SrcOrigin.y,
+ alignedSharedInfo.RectSize.width, alignedSharedInfo.RectSize.height);
+
+ /* Rectangle */
+ storedSharedInfo->SrcOrigin.x =
+ storedSharedInfo->SrcOrigin.y =
+ storedSharedInfo->RectSize.width =
+ storedSharedInfo->RectSize.height = 0;
+ }
+ break;
+ }
}
-
break;
case gcvHAL_SET_SHARED_INFO:
@@ -1637,21 +1688,86 @@ gckKERNEL_Dispatch(
if ((node = Interface->u.SetSharedInfo.node) != gcvNULL)
{
- if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
- {
- data = &node->VidMem.sharedInfo;
- }
- else
- {
- data = &node->Virtual.sharedInfo;
- }
+ switch (Interface->u.SetSharedInfo.infoType)
+ {
+ case gcvVIDMEM_INFO_GENERIC:
+ { /* Generic data stored */
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ data = &node->VidMem.sharedInfo;
+ }
+ else
+ {
+ data = &node->Virtual.sharedInfo;
+ }
+
+ gcmkONERROR(gckOS_CopyFromUserData(
+ Kernel->os,
+ data,
+ Interface->u.SetSharedInfo.nodeData,
+ sizeof(gcsVIDMEM_NODE_SHARED_INFO)
+ ));
+ }
+ break;
- gcmkONERROR(gckOS_CopyFromUserData(
- Kernel->os,
- data,
- Interface->u.SetSharedInfo.nodeData,
- sizeof(gcsVIDMEM_NODE_SHARED_INFO)
- ));
+ case gcvVIDMEM_INFO_DIRTY_RECTANGLE:
+ { /* Dirty rectangle stored */
+ gcsVIDMEM_NODE_SHARED_INFO newSharedInfo;
+ gcsVIDMEM_NODE_SHARED_INFO *currentSharedInfo;
+ gctINT dirtyX, dirtyY, right, bottom;
+
+ /* Expand the dirty rectangle stored in the node to include the rectangle passed in. */
+ gcmkONERROR(gckOS_CopyFromUserData(
+ Kernel->os,
+ &newSharedInfo,
+ Interface->u.SetSharedInfo.nodeData,
+ gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO)
+ ));
+
+ if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM)
+ {
+ currentSharedInfo = &node->VidMem.sharedInfo;
+ }
+ else
+ {
+ currentSharedInfo = &node->Virtual.sharedInfo;
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_KERNEL, "Node = %p Stored rectangle (l=%d, t=%d, w=%d, h=%d)", node,
+ currentSharedInfo->SrcOrigin.x, currentSharedInfo->SrcOrigin.y,
+ currentSharedInfo->RectSize.width, currentSharedInfo->RectSize.height);
+
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_KERNEL, "To combine with (l=%d, t=%d, w=%d, h=%d)",
+ newSharedInfo.SrcOrigin.x, newSharedInfo.SrcOrigin.y,
+ newSharedInfo.RectSize.width, newSharedInfo.RectSize.height);
+
+ if ((currentSharedInfo->RectSize.width == 0) || (currentSharedInfo->RectSize.height == 0))
+ { /* Setting it for the first time */
+ currentSharedInfo->SrcOrigin.x = newSharedInfo.SrcOrigin.x;
+ currentSharedInfo->SrcOrigin.y = newSharedInfo.SrcOrigin.y;
+ currentSharedInfo->RectSize.width = newSharedInfo.RectSize.width;
+ currentSharedInfo->RectSize.height = newSharedInfo.RectSize.height;
+ }
+ else
+ {
+ /* Expand the stored rectangle to include newly locked rectangle */
+ dirtyX = (newSharedInfo.SrcOrigin.x < currentSharedInfo->SrcOrigin.x) ? newSharedInfo.SrcOrigin.x : currentSharedInfo->SrcOrigin.x;
+ right = gcmMAX((currentSharedInfo->SrcOrigin.x + currentSharedInfo->RectSize.width), (newSharedInfo.SrcOrigin.x + newSharedInfo.RectSize.width));
+ currentSharedInfo->RectSize.width = right - dirtyX;
+ currentSharedInfo->SrcOrigin.x = dirtyX;
+
+ dirtyY = (newSharedInfo.SrcOrigin.y < currentSharedInfo->SrcOrigin.y) ? newSharedInfo.SrcOrigin.y : currentSharedInfo->SrcOrigin.y;
+ bottom = gcmMAX((currentSharedInfo->SrcOrigin.y + currentSharedInfo->RectSize.height), (newSharedInfo.SrcOrigin.y + newSharedInfo.RectSize.height));
+ currentSharedInfo->RectSize.height = bottom - dirtyY;
+ currentSharedInfo->SrcOrigin.y = dirtyY;
+ }
+
+ gcmkTRACE_ZONE(gcvLEVEL_VERBOSE, gcvZONE_KERNEL, "Combined rectangle (l=%d, t=%d, w=%d, h=%d)",
+ currentSharedInfo->SrcOrigin.x, currentSharedInfo->SrcOrigin.y,
+ currentSharedInfo->RectSize.width, currentSharedInfo->RectSize.height);
+ }
+ break;
+ }
}
break;
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
index a9489eaf20ad..ec9c8ee2ee56 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_command.c
@@ -1905,6 +1905,13 @@ gckCOMMAND_Commit(
EventQueue = nextEventRecord;
}
+ if (Command->kernel->eventObj->queueHead == gcvNULL)
+ {
+ /* Commit done event by which work thread knows all jobs done. */
+ gcmkVERIFY_OK(
+ gckEVENT_CommitDone(Command->kernel->eventObj, gcvKERNEL_PIXEL));
+ }
+
/* Submit events. */
gcmkONERROR(gckEVENT_Submit(Command->kernel->eventObj, gcvTRUE, gcvFALSE));
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
index 6c9a65b923db..1efdc5f10368 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
@@ -742,8 +742,13 @@ gckEVENT_AllocateRecord(
gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
gcmkVERIFY_ARGUMENT(Record != gcvNULL);
+ /* Acquire the mutex. */
+ gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->freeEventMutex, gcvINFINITE));
+ acquired = gcvTRUE;
+
/* Test if we are below the allocation threshold. */
- if (AllocateAllowed && (Event->freeEventCount < gcdEVENT_MIN_THRESHOLD))
+ if ( (AllocateAllowed && (Event->freeEventCount < gcdEVENT_MIN_THRESHOLD)) ||
+ (Event->freeEventCount == 0) )
{
/* Allocate a bunch of records. */
for (i = 0; i < gcdEVENT_ALLOCATION_COUNT; i += 1)
@@ -755,25 +760,13 @@ gckEVENT_AllocateRecord(
record = pointer;
- /* Acquire the mutex. */
- gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->freeEventMutex, gcvINFINITE));
- acquired = gcvTRUE;
-
/* Push it on the free list. */
record->next = Event->freeEventList;
Event->freeEventList = record;
Event->freeEventCount += 1;
-
- /* Release the mutex. */
- gcmkONERROR(gckOS_ReleaseMutex(Event->os, Event->freeEventMutex));
- acquired = gcvFALSE;
}
}
- /* Acquire the mutex. */
- gcmkONERROR(gckOS_AcquireMutex(Event->os, Event->freeEventMutex, gcvINFINITE));
- acquired = gcvTRUE;
-
*Record = Event->freeEventList;
Event->freeEventList = Event->freeEventList->next;
Event->freeEventCount -= 1;
@@ -852,6 +845,7 @@ gckEVENT_AddList(
|| (Interface->command == gcvHAL_SIGNAL)
|| (Interface->command == gcvHAL_UNMAP_USER_MEMORY)
|| (Interface->command == gcvHAL_TIMESTAMP)
+ || (Interface->command == gcvHAL_COMMIT_DONE)
);
/* Validate the source. */
@@ -1253,6 +1247,52 @@ OnError:
/*******************************************************************************
**
+** gckEVENT_CommitDone
+**
+** Schedule an event to wake up work thread when commit is done by GPU.
+**
+** INPUT:
+**
+** gckEVENT Event
+** Pointer to an gckEVENT object.
+**
+** gceKERNEL_WHERE FromWhere
+** Place in the pipe where the event needs to be generated.
+**
+** OUTPUT:
+**
+** Nothing.
+*/
+gceSTATUS
+gckEVENT_CommitDone(
+ IN gckEVENT Event,
+ IN gceKERNEL_WHERE FromWhere
+ )
+{
+ gceSTATUS status;
+ gcsHAL_INTERFACE iface;
+
+ gcmkHEADER_ARG("Event=0x%x FromWhere=%d", Event, FromWhere);
+
+ /* Verify the arguments. */
+ gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
+
+ iface.command = gcvHAL_COMMIT_DONE;
+
+ /* Append it to the queue. */
+ gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE));
+
+ /* Success. */
+ gcmkFOOTER_NO();
+ return gcvSTATUS_OK;
+
+OnError:
+ /* Return the status. */
+ gcmkFOOTER();
+ return status;
+}
+/*******************************************************************************
+**
** gckEVENT_Submit
**
** Submit the current event queue to the GPU.
@@ -2208,6 +2248,9 @@ gckEVENT_Notify(
}
break;
+ case gcvHAL_COMMIT_DONE:
+ break;
+
default:
/* Invalid argument. */
gcmkTRACE_ZONE_N(
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
index 2c282f861b18..f3fdc7530c42 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
+++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_video_memory.c
@@ -266,6 +266,9 @@ gckVIDMEM_ConstructVirtual(
#endif
node->Virtual.freed = gcvFALSE;
+
+ gcmkONERROR(gckOS_ZeroMemory(&node->Virtual.sharedInfo, gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO)));
+
/* Create the mutex. */
gcmkONERROR(
gckOS_CreateMutex(os, &node->Virtual.mutex));
@@ -514,6 +517,8 @@ gckVIDMEM_Construct(
node->VidMem.locked = 0;
+ gcmkONERROR(gckOS_ZeroMemory(&node->VidMem.sharedInfo, gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO)));
+
#ifdef __QNXNTO__
#if gcdUSE_VIDMEM_PER_PID
node->VidMem.processID = memory->pid;
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
index bc20a4331031..2dfa3e74f5de 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
@@ -2116,6 +2116,12 @@ gckEVENT_Unlock(
);
gceSTATUS
+gckEVENT_CommitDone(
+ IN gckEVENT Event,
+ IN gceKERNEL_WHERE FromWhere
+ );
+
+gceSTATUS
gckEVENT_Submit(
IN gckEVENT Event,
IN gctBOOL Wait,
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
index c1711fa6484d..03631fe1528f 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
@@ -118,6 +118,7 @@ typedef struct _gcsTLS
gcoHARDWARE hardware2D;
#if gcdENABLE_VG
gcoVGHARDWARE vg;
+ gcoVG engineVG;
#endif /* gcdENABLE_VG */
gctPOINTER context;
gctTLS_DESTRUCTOR destructor;
@@ -1620,6 +1621,20 @@ gcoSURF_QueryVidMemNode(
OUT gctUINT_PTR Bytes
);
+/* Set usage attribute of a surface. */
+gceSTATUS
+gcoSURF_SetUsage(
+ IN gcoSURF Surface,
+ IN gceSURF_USAGE Usage
+ );
+
+/* Return usage attribute of a surface. */
+gceSTATUS
+gcoSURF_QueryUsage(
+ IN gcoSURF Surface,
+ OUT gceSURF_USAGE *Usage
+ );
+
/* Set the color type of the surface. */
gceSTATUS
gcoSURF_SetColorType(
@@ -1832,6 +1847,14 @@ gcoSURF_SetOffset(
IN gctUINT Offset
);
+gceSTATUS
+gcoSURF_NODE_Cache(
+ IN gcsSURF_NODE_PTR Node,
+ IN gctPOINTER Logical,
+ IN gctSIZE_T Bytes,
+ IN gceCACHEOPERATION Operation
+ );
+
/******************************************************************************\
********************************* gcoDUMP Object ********************************
\******************************************************************************/
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h
index aaf50c42e9b8..37715ffdd504 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_compiler.h
@@ -428,6 +428,7 @@ gceUNIFORM_FLAGS;
#define gcdUNIFORM_KERNEL_ARG_MASK (gcvUNIFORM_KERNEL_ARG | \
gcvUNIFORM_KERNEL_ARG_LOCAL | \
gcvUNIFORM_KERNEL_ARG_SAMPLER | \
+ gcvUNIFORM_KERNEL_ARG_PRIVATE | \
gcvUNIFORM_KERNEL_ARG_CONSTANT)
/*******************************************************************************
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h
index a16a60d0bfb5..505a23d93b46 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_driver.h
@@ -147,7 +147,9 @@ typedef enum _gceHAL_COMMAND_CODES
/* Shared info for each process */
gcvHAL_GET_SHARED_INFO,
gcvHAL_SET_SHARED_INFO,
- gcvHAL_QUERY_COMMAND_BUFFER
+ gcvHAL_QUERY_COMMAND_BUFFER,
+
+ gcvHAL_COMMIT_DONE,
}
gceHAL_COMMAND_CODES;
@@ -859,7 +861,6 @@ typedef struct _gcsHAL_INTERFACE
#endif
-#if gcdENABLE_SHARED_INFO
struct _gcsHAL_GET_SHARED_INFO
{
IN gctUINT32 pid;
@@ -869,6 +870,7 @@ typedef struct _gcsHAL_INTERFACE
/* fix size */
OUT gctUINT8_PTR nodeData;
gctSIZE_T size;
+ IN gceVIDMEM_NODE_SHARED_INFO_TYPE infoType;
}
GetSharedInfo;
@@ -879,9 +881,9 @@ typedef struct _gcsHAL_INTERFACE
IN gctUINT8_PTR data;
IN gctUINT8_PTR nodeData;
IN gctSIZE_T size;
+ IN gceVIDMEM_NODE_SHARED_INFO_TYPE infoType;
}
SetSharedInfo;
-#endif
}
u;
}
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
index 5ae49e05dfab..165234a579fa 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
@@ -330,13 +330,6 @@ gcoSURF_ExportRenderTarget(
IN gcoSURF SrcSurface
);
-/* Export render target by given key. */
-gceSTATUS
-gcoSURF_ExportRenderTargetByKey(
- IN gcoSURF Key,
- IN gcoSURF SrcSurface
-);
-
/* Import the render target. */
gceSTATUS
gcoSURF_ImportRenderTarget(
@@ -344,14 +337,6 @@ gcoSURF_ImportRenderTarget(
IN gcoSURF SrcSurface
);
-/* Import the render target by given key. */
-gceSTATUS
-gcoSURF_ImportRenderTargetByKey(
- IN gctUINT32 Pid,
- IN gcoSURF Key,
- IN gcoSURF SrcSurface
-);
-
/* Save the Resolve info to kernel. */
gceSTATUS
gcoSURF_PrepareRemoteResolveRect(
@@ -361,6 +346,13 @@ gcoSURF_PrepareRemoteResolveRect(
IN gcsPOINT_PTR RectSize
);
+/* Resolve using the rectangle info previously saved in the vid mem node. */
+gceSTATUS
+gcoSURF_ResolveFromStoredRect(
+ IN gcoSURF SrcSurface,
+ IN gcoSURF DestSurface
+ );
+
/* Using the info that Process Pid saved to do resolve. */
gceSTATUS
gcoSURF_RemoteResolveRect(
@@ -369,8 +361,7 @@ gcoSURF_RemoteResolveRect(
IN gctBOOL *resolveDiscarded
);
-/*
- Return the "resolve submitted indicator" signal. */
+/* Return the "resolve submitted indicator" signal. */
gceSTATUS
gcoSURF_GetRTSignal(
IN gcoSURF RTSurface,
@@ -401,14 +392,6 @@ gcoSURF_CPUCacheOperation(
IN gceCACHEOPERATION Operation
);
-gceSTATUS
-gcoSURF_NODE_Cache(
- IN gcsSURF_NODE_PTR Node,
- IN gctPOINTER Logical,
- IN gctSIZE_T Bytes,
- IN gceCACHEOPERATION Operation
- );
-
/******************************************************************************\
******************************** gcoINDEX Object *******************************
\******************************************************************************/
@@ -1843,7 +1826,8 @@ gcoHAL_GetSharedInfo(
OUT gctUINT8_PTR Data,
IN gctSIZE_T Bytes,
IN gcuVIDMEM_NODE_PTR Node,
- OUT gctUINT8_PTR NodeData
+ OUT gctUINT8_PTR NodeData,
+ IN gceVIDMEM_NODE_SHARED_INFO_TYPE SharedInfoType
);
gceSTATUS
@@ -1852,7 +1836,8 @@ gcoHAL_SetSharedInfo(
IN gctUINT8_PTR Data,
IN gctSIZE_T Bytes,
IN gcuVIDMEM_NODE_PTR Node,
- IN gctUINT8_PTR NodeData
+ IN gctUINT8_PTR NodeData,
+ IN gceVIDMEM_NODE_SHARED_INFO_TYPE SharedInfoType
);
#ifdef __cplusplus
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
index 9ade98fa0b13..f28675448dae 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_enum.h
@@ -128,6 +128,7 @@ typedef enum _gceFEATURE
gcvFEATURE_TEXTURE_FLOAT_HALF_FLOAT,
gcvFEATURE_2D_ROTATION_STALL_FIX,
gcvFEATURE_2D_MULTI_SOURCE_BLT_EX,
+ gcvFEATURE_BUG_FIXES10,
}
gceFEATURE;
@@ -160,6 +161,13 @@ typedef enum _gceCACHEOPERATION
}
gceCACHEOPERATION;
+typedef enum _gceVIDMEM_NODE_SHARED_INFO_TYPE
+{
+ gcvVIDMEM_INFO_GENERIC,
+ gcvVIDMEM_INFO_DIRTY_RECTANGLE
+}
+gceVIDMEM_NODE_SHARED_INFO_TYPE;
+
/* Surface types. */
typedef enum _gceSURF_TYPE
{
@@ -205,6 +213,14 @@ typedef enum _gceSURF_TYPE
}
gceSURF_TYPE;
+typedef enum _gceSURF_USAGE
+{
+ gcvSURF_USAGE_UNKNOWN,
+ gcvSURF_USAGE_RESOLVE_AFTER_CPU,
+ gcvSURF_USAGE_RESOLVE_AFTER_3D
+}
+gceSURF_USAGE;
+
typedef enum _gceSURF_COLOR_TYPE
{
gcvSURF_COLOR_UNKNOWN = 0,
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
index fdfc07bf0e32..fc97c78d5d80 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_options.h
@@ -524,17 +524,6 @@
# define gcdENABLE_TS_DOUBLE_BUFFER 1
#endif
-
-/*
- gcdENABLE_SHARED_INFO
-
- When non-zero, enable process store some shared data in kernel
- which can be got by other processes
- */
-#ifndef gcdENABLE_SHARED_INFO
-# define gcdENABLE_SHARED_INFO 1
-#endif
-
/*
gcd6000_SUPPORT
@@ -624,16 +613,46 @@
#endif
/*
- gcdSYNC_CPU_APP_WITH_COMPOSITOR
+ gcdCOPYBLT_OPTIMIZATION
- Synchronize access to a linear buffer between CPU app and compositor (i.e. GPU - 2D, 3D or CE).
+ Combine dirty areas resulting from Android's copyBlt.
*/
-#ifndef gcdSYNC_CPU_APP_WITH_COMPOSITOR
-# define gcdSYNC_CPU_APP_WITH_COMPOSITOR 0
+#ifndef gcdCOPYBLT_OPTIMIZATION
+# define gcdCOPYBLT_OPTIMIZATION 0
#endif
+/*
+ gcdGPU_LINEAR_BUFFER_ENABLED
+
+ Use linear buffer for GPU apps so HWC can do 2D composition.
+*/
+#ifndef gcdGPU_LINEAR_BUFFER_ENABLED
+# define gcdGPU_LINEAR_BUFFER_ENABLED 0
+#endif
+
+/*
+ gcdSHARED_RESOLVE_BUFFER_ENABLED
+
+ Use shared resolve buffer for all app buffers.
+*/
+#ifndef gcdSHARED_RESOLVE_BUFFER_ENABLED
+# define gcdSHARED_RESOLVE_BUFFER_ENABLED 0
+#endif
+
+/*
+ gcdUSE_TRIANGLE_STRIP_PATCH
+ */
#ifndef gcdUSE_TRIANGLE_STRIP_PATCH
-# define gcdUSE_TRIANGLE_STRIP_PATCH 1
+# define gcdUSE_TRIANGLE_STRIP_PATCH 1
+#endif
+
+/*
+ gcdENABLE_OUTER_CACHE_PATCH
+
+ Enable the outer cache patch.
+*/
+#ifndef gcdENABLE_OUTER_CACHE_PATCH
+# define gcdENABLE_OUTER_CACHE_PATCH 0
#endif
#endif /* __gc_hal_options_h_ */
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
index 6605f4fccb5b..6213ffaaef8f 100644
--- a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
+++ b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_version.h
@@ -28,9 +28,9 @@
#define gcvVERSION_MINOR 6
-#define gcvVERSION_PATCH 2
+#define gcvVERSION_PATCH 3
-#define gcvVERSION_BUILD 1251
+#define gcvVERSION_BUILD 1280
#define gcvVERSION_DATE __DATE__
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h
index a9b633e5d858..d6ceba73e41e 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debug.h
@@ -46,7 +46,7 @@ typedef va_list gctARGUMENTS;
va_end(Arguments)
#define gcmkDECLARE_LOCK(__spinLock__) \
- static spinlock_t __spinLock__ = SPIN_LOCK_UNLOCKED;
+ static DEFINE_SPINLOCK(__spinLock__);
#define gcmkLOCKSECTION(__spinLock__) \
spin_lock(&__spinLock__)
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
index e7cc92f74e7b..e4ef19b8c654 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_driver.c
@@ -511,6 +511,13 @@ long drv_ioctl(
}
}
+ /* Redo system call after pending signal is handled. */
+ if (status == gcvSTATUS_INTERRUPTED)
+ {
+ gcmkFOOTER();
+ return -ERESTARTSYS;
+ }
+
if (gcmIS_SUCCESS(status) && (iface.command == gcvHAL_LOCK_VIDEO_MEMORY))
{
/* Special case for mapped memory. */
diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
index ba4f032039b8..c22aa460d2f4 100644
--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
+++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c
@@ -5468,6 +5468,7 @@ outer_func(
return gcvSTATUS_OK;
}
+#if gcdENABLE_OUTER_CACHE_PATCH
/*******************************************************************************
** _HandleOuterCache
**
@@ -5561,6 +5562,7 @@ OnError:
return status;
}
#endif
+#endif
/*******************************************************************************
** gckOS_CacheClean
@@ -5619,7 +5621,11 @@ gckOS_CacheClean(
#if defined(CONFIG_OUTER_CACHE)
/* Outer cache. */
+#if gcdENABLE_OUTER_CACHE_PATCH
_HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_CLEAN);
+#else
+ outer_clean_range((unsigned long) Handle, (unsigned long) Handle + Bytes);
+#endif
#endif
#elif defined(CONFIG_MIPS)
@@ -5694,7 +5700,11 @@ gckOS_CacheInvalidate(
#if defined(CONFIG_OUTER_CACHE)
/* Outer cache. */
+#if gcdENABLE_OUTER_CACHE_PATCH
_HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_INVALIDATE);
+#else
+ outer_inv_range((unsigned long) Handle, (unsigned long) Handle + Bytes);
+#endif
#endif
#elif defined(CONFIG_MIPS)
@@ -5762,7 +5772,11 @@ gckOS_CacheFlush(
#if defined(CONFIG_OUTER_CACHE)
/* Outer cache. */
+#if gcdENABLE_OUTER_CACHE_PATCH
_HandleOuterCache(Os, ProcessID, Handle, Physical, Logical, Bytes, gcvCACHE_FLUSH);
+#else
+ outer_flush_range((unsigned long) Handle, (unsigned long) Handle + Bytes);
+#endif
#endif
#elif defined(CONFIG_MIPS)
diff --git a/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c b/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c
index 1e05cc5808b5..aa9fdaf27cdc 100644
--- a/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c
+++ b/drivers/mxc/ipu3/ipu_calc_stripes_sizes.c
@@ -52,8 +52,8 @@ static u32 truncate(u32 up, /* 0: down; else: up */
return d;
}
-/*static unsigned int f_calc(unsigned int pfs, unsigned int bpp, unsigned int *write)
-{[> return input_f <]
+static unsigned int f_calc(unsigned int pfs, unsigned int bpp, unsigned int *write)
+{/* return input_f */
unsigned int f_calculated = 0;
switch (pfs) {
case IPU_PIX_FMT_YVU422P:
@@ -129,7 +129,7 @@ static unsigned int m_calc(unsigned int pfs)
}
return m_calculated;
-}*/
+}
/* Stripe parameters calculator */
@@ -214,14 +214,14 @@ int ipu_calc_stripes_sizes(const unsigned int input_frame_width,
/* M, F calculations */
/* read back pfs from params */
- input_f = 16;
+ input_f = f_calc(input_pixelformat, 0, NULL);
input_m = 16;
/* BPP should be used in the out_F calc */
/* Temporarily not used */
/* out_F = F_calc(idmac->pfs, idmac->bpp, NULL); */
output_f = 16;
- output_m = 16;
+ output_m = m_calc(output_pixelformat);
if ((input_frame_width < 4) || (output_frame_width < 4))
@@ -370,7 +370,6 @@ int ipu_calc_stripes_sizes(const unsigned int input_frame_width,
left->output_column = 0;
right->output_column = onw;
}
-
return status;
}
EXPORT_SYMBOL(ipu_calc_stripes_sizes);
diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c
index 133c2a65c48c..e7713199abcb 100644
--- a/drivers/mxc/ipu3/ipu_common.c
+++ b/drivers/mxc/ipu3/ipu_common.c
@@ -688,9 +688,16 @@ int32_t ipu_init_channel(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel
ipu->ic_use_count++;
ipu->csi_channel[params->csi_prp_enc_mem.csi] = channel;
- /*Without SMFC, CSI only support parallel data source*/
- ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
- params->csi_prp_enc_mem.csi));
+ if (params->csi_prp_enc_mem.mipi_en) {
+ ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
+ params->csi_prp_enc_mem.csi));
+ _ipu_csi_set_mipi_di(ipu,
+ params->csi_prp_enc_mem.mipi_vc,
+ params->csi_prp_enc_mem.mipi_id,
+ params->csi_prp_enc_mem.csi);
+ } else
+ ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
+ params->csi_prp_enc_mem.csi));
/*CSI0/1 feed into IC*/
ipu_conf &= ~IPU_CONF_IC_INPUT;
@@ -721,9 +728,16 @@ int32_t ipu_init_channel(struct ipu_soc *ipu, ipu_channel_t channel, ipu_channel
ipu->ic_use_count++;
ipu->csi_channel[params->csi_prp_vf_mem.csi] = channel;
- /*Without SMFC, CSI only support parallel data source*/
- ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
- params->csi_prp_vf_mem.csi));
+ if (params->csi_prp_vf_mem.mipi_en) {
+ ipu_conf |= (1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
+ params->csi_prp_vf_mem.csi));
+ _ipu_csi_set_mipi_di(ipu,
+ params->csi_prp_vf_mem.mipi_vc,
+ params->csi_prp_vf_mem.mipi_id,
+ params->csi_prp_vf_mem.csi);
+ } else
+ ipu_conf &= ~(1 << (IPU_CONF_CSI0_DATA_SOURCE_OFFSET +
+ params->csi_prp_vf_mem.csi));
/*CSI0/1 feed into IC*/
ipu_conf &= ~IPU_CONF_IC_INPUT;
@@ -2317,6 +2331,7 @@ int32_t ipu_enable_csi(struct ipu_soc *ipu, uint32_t csi)
return -EINVAL;
}
+ _ipu_get(ipu);
_ipu_lock(ipu);
ipu->csi_use_count[csi]++;
@@ -2328,6 +2343,7 @@ int32_t ipu_enable_csi(struct ipu_soc *ipu, uint32_t csi)
ipu_cm_write(ipu, reg | IPU_CONF_CSI1_EN, IPU_CONF);
}
_ipu_unlock(ipu);
+ _ipu_put(ipu);
return 0;
}
EXPORT_SYMBOL(ipu_enable_csi);
@@ -2349,7 +2365,7 @@ int32_t ipu_disable_csi(struct ipu_soc *ipu, uint32_t csi)
dev_err(ipu->dev, "Wrong csi num_%d\n", csi);
return -EINVAL;
}
-
+ _ipu_get(ipu);
_ipu_lock(ipu);
ipu->csi_use_count[csi]--;
if (ipu->csi_use_count[csi] == 0) {
@@ -2360,6 +2376,7 @@ int32_t ipu_disable_csi(struct ipu_soc *ipu, uint32_t csi)
ipu_cm_write(ipu, reg & ~IPU_CONF_CSI1_EN, IPU_CONF);
}
_ipu_unlock(ipu);
+ _ipu_put(ipu);
return 0;
}
EXPORT_SYMBOL(ipu_disable_csi);
diff --git a/drivers/mxc/mipi/mxc_mipi_csi2.c b/drivers/mxc/mipi/mxc_mipi_csi2.c
index 89592a84745c..1f051dff88bd 100644
--- a/drivers/mxc/mipi/mxc_mipi_csi2.c
+++ b/drivers/mxc/mipi/mxc_mipi_csi2.c
@@ -17,6 +17,9 @@
*/
#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/err.h>
@@ -24,14 +27,10 @@
#include <linux/console.h>
#include <linux/io.h>
#include <linux/bitops.h>
-#include <linux/ipu.h>
-#include <linux/mxcfb.h>
-#include <linux/regulator/consumer.h>
-#include <linux/backlight.h>
-#include <linux/spinlock.h>
#include <linux/delay.h>
#include <linux/fsl_devices.h>
+#include <mach/devices-common.h>
#include <mach/hardware.h>
#include <mach/clock.h>
#include <mach/mipi_csi2.h>
@@ -40,6 +39,18 @@
static struct mipi_csi2_info *gmipi_csi2;
+void _mipi_csi2_lock(struct mipi_csi2_info *info)
+{
+ if (!in_irq() && !in_softirq())
+ mutex_lock(&info->mutex_lock);
+}
+
+void _mipi_csi2_unlock(struct mipi_csi2_info *info)
+{
+ if (!in_irq() && !in_softirq())
+ mutex_unlock(&info->mutex_lock);
+}
+
static inline void mipi_csi2_write(struct mipi_csi2_info *info, unsigned value, unsigned offset)
{
writel(value, info->mipi_csi2_base + offset);
@@ -51,6 +62,76 @@ static inline unsigned int mipi_csi2_read(struct mipi_csi2_info *info, unsigned
}
/*!
+ * This function is called to enable the mipi csi2 interface.
+ *
+ * @param info mipi csi2 hander
+ * @return Returns setted value
+ */
+bool mipi_csi2_enable(struct mipi_csi2_info *info)
+{
+ bool status;
+
+ _mipi_csi2_lock(info);
+
+ if (!info->mipi_en) {
+ info->mipi_en = true;
+ clk_enable(info->dphy_clk);
+ } else
+ mipi_dbg("mipi csi2 already enabled!\n");
+
+ status = info->mipi_en;
+
+ _mipi_csi2_unlock(info);
+
+ return status;
+}
+EXPORT_SYMBOL(mipi_csi2_enable);
+
+/*!
+ * This function is called to disable the mipi csi2 interface.
+ *
+ * @param info mipi csi2 hander
+ * @return Returns setted value
+ */
+bool mipi_csi2_disable(struct mipi_csi2_info *info)
+{
+ bool status;
+
+ _mipi_csi2_lock(info);
+
+ if (info->mipi_en) {
+ info->mipi_en = false;
+ clk_disable(info->dphy_clk);
+ } else
+ mipi_dbg("mipi csi2 already disabled!\n");
+
+ status = info->mipi_en;
+
+ _mipi_csi2_unlock(info);
+
+ return status;
+}
+EXPORT_SYMBOL(mipi_csi2_disable);
+
+/*!
+ * This function is called to get mipi csi2 disable/enable status.
+ *
+ * @param info mipi csi2 hander
+ * @return Returns mipi csi2 status
+ */
+bool mipi_csi2_get_status(struct mipi_csi2_info *info)
+{
+ bool status;
+
+ _mipi_csi2_lock(info);
+ status = info->mipi_en;
+ _mipi_csi2_unlock(info);
+
+ return status;
+}
+EXPORT_SYMBOL(mipi_csi2_get_status);
+
+/*!
* This function is called to set mipi lanes.
*
* @param info mipi csi2 hander
@@ -58,9 +139,14 @@ static inline unsigned int mipi_csi2_read(struct mipi_csi2_info *info, unsigned
*/
unsigned int mipi_csi2_set_lanes(struct mipi_csi2_info *info)
{
+ unsigned int lanes;
+
+ _mipi_csi2_lock(info);
mipi_csi2_write(info, info->lanes - 1, CSI2_N_LANES);
+ lanes = mipi_csi2_read(info, CSI2_N_LANES);
+ _mipi_csi2_unlock(info);
- return mipi_csi2_read(info, CSI2_N_LANES);
+ return lanes;
}
EXPORT_SYMBOL(mipi_csi2_set_lanes);
@@ -71,11 +157,16 @@ EXPORT_SYMBOL(mipi_csi2_set_lanes);
* @return Returns setted value
*/
unsigned int mipi_csi2_set_datatype(struct mipi_csi2_info *info,
- unsigned int datatype)
+ unsigned int datatype)
{
+ unsigned int dtype;
+
+ _mipi_csi2_lock(info);
info->datatype = datatype;
+ dtype = info->datatype;
+ _mipi_csi2_unlock(info);
- return info->datatype;
+ return dtype;
}
EXPORT_SYMBOL(mipi_csi2_set_datatype);
@@ -87,7 +178,13 @@ EXPORT_SYMBOL(mipi_csi2_set_datatype);
*/
unsigned int mipi_csi2_get_datatype(struct mipi_csi2_info *info)
{
- return info->datatype;
+ unsigned int dtype;
+
+ _mipi_csi2_lock(info);
+ dtype = info->datatype;
+ _mipi_csi2_unlock(info);
+
+ return dtype;
}
EXPORT_SYMBOL(mipi_csi2_get_datatype);
@@ -99,7 +196,13 @@ EXPORT_SYMBOL(mipi_csi2_get_datatype);
*/
unsigned int mipi_csi2_dphy_status(struct mipi_csi2_info *info)
{
- return mipi_csi2_read(info, CSI2_PHY_STATE);
+ unsigned int status;
+
+ _mipi_csi2_lock(info);
+ status = mipi_csi2_read(info, CSI2_PHY_STATE);
+ _mipi_csi2_unlock(info);
+
+ return status;
}
EXPORT_SYMBOL(mipi_csi2_dphy_status);
@@ -111,7 +214,13 @@ EXPORT_SYMBOL(mipi_csi2_dphy_status);
*/
unsigned int mipi_csi2_get_error1(struct mipi_csi2_info *info)
{
- return mipi_csi2_read(info, CSI2_ERR1);
+ unsigned int err1;
+
+ _mipi_csi2_lock(info);
+ err1 = mipi_csi2_read(info, CSI2_ERR1);
+ _mipi_csi2_unlock(info);
+
+ return err1;
}
EXPORT_SYMBOL(mipi_csi2_get_error1);
@@ -123,7 +232,13 @@ EXPORT_SYMBOL(mipi_csi2_get_error1);
*/
unsigned int mipi_csi2_get_error2(struct mipi_csi2_info *info)
{
- return mipi_csi2_read(info, CSI2_ERR2);
+ unsigned int err2;
+
+ _mipi_csi2_lock(info);
+ err2 = mipi_csi2_read(info, CSI2_ERR2);
+ _mipi_csi2_unlock(info);
+
+ return err2;
}
EXPORT_SYMBOL(mipi_csi2_get_error2);
@@ -159,6 +274,8 @@ EXPORT_SYMBOL(mipi_csi2_pixelclk_disable);
*/
int mipi_csi2_reset(struct mipi_csi2_info *info)
{
+ _mipi_csi2_lock(info);
+
mipi_csi2_write(info, 0x0, CSI2_PHY_SHUTDOWNZ);
mipi_csi2_write(info, 0x0, CSI2_DPHY_RSTZ);
mipi_csi2_write(info, 0x0, CSI2_RESETN);
@@ -177,6 +294,8 @@ int mipi_csi2_reset(struct mipi_csi2_info *info)
mipi_csi2_write(info, 0xffffffff, CSI2_DPHY_RSTZ);
mipi_csi2_write(info, 0xffffffff, CSI2_RESETN);
+ _mipi_csi2_unlock(info);
+
return 0;
}
EXPORT_SYMBOL(mipi_csi2_reset);
@@ -199,7 +318,13 @@ EXPORT_SYMBOL(mipi_csi2_get_info);
*/
int mipi_csi2_get_bind_ipu(struct mipi_csi2_info *info)
{
- return info->ipu_id;
+ int ipu_id;
+
+ _mipi_csi2_lock(info);
+ ipu_id = info->ipu_id;
+ _mipi_csi2_unlock(info);
+
+ return ipu_id;
}
EXPORT_SYMBOL(mipi_csi2_get_bind_ipu);
@@ -210,7 +335,13 @@ EXPORT_SYMBOL(mipi_csi2_get_bind_ipu);
*/
unsigned int mipi_csi2_get_bind_csi(struct mipi_csi2_info *info)
{
- return info->csi_id;
+ unsigned int csi_id;
+
+ _mipi_csi2_lock(info);
+ csi_id = info->csi_id;
+ _mipi_csi2_unlock(info);
+
+ return csi_id;
}
EXPORT_SYMBOL(mipi_csi2_get_bind_csi);
@@ -221,7 +352,13 @@ EXPORT_SYMBOL(mipi_csi2_get_bind_csi);
*/
unsigned int mipi_csi2_get_virtual_channel(struct mipi_csi2_info *info)
{
- return info->v_channel;
+ unsigned int v_channel;
+
+ _mipi_csi2_lock(info);
+ v_channel = info->v_channel;
+ _mipi_csi2_unlock(info);
+
+ return v_channel;
}
EXPORT_SYMBOL(mipi_csi2_get_virtual_channel);
@@ -254,8 +391,12 @@ static int mipi_csi2_probe(struct platform_device *pdev)
goto alloc_failed;
}
+ /* initialize mutex */
+ mutex_init(&gmipi_csi2->mutex_lock);
+
/* get mipi csi2 informaiton */
gmipi_csi2->pdev = pdev;
+ gmipi_csi2->mipi_en = false;
gmipi_csi2->ipu_id = plat_data->ipu_id;
gmipi_csi2->csi_id = plat_data->csi_id;
gmipi_csi2->v_channel = plat_data->v_channel;
@@ -295,6 +436,8 @@ static int mipi_csi2_probe(struct platform_device *pdev)
/* get mipi csi2 dphy version */
mipi_csi2_dphy_ver = mipi_csi2_read(gmipi_csi2, CSI2_VERSION);
+ clk_disable(gmipi_csi2->dphy_clk);
+
platform_set_drvdata(pdev, gmipi_csi2);
dev_info(&pdev->dev, "i.MX MIPI CSI2 driver probed\n");
@@ -320,7 +463,6 @@ static int __devexit mipi_csi2_remove(struct platform_device *pdev)
iounmap(gmipi_csi2->mipi_csi2_base);
/* disable mipi dphy clk */
- clk_disable(gmipi_csi2->dphy_clk);
clk_put(gmipi_csi2->dphy_clk);
clk_put(gmipi_csi2->pixel_clk);
@@ -360,7 +502,7 @@ static void __exit mipi_csi2_cleanup(void)
platform_driver_unregister(&mipi_csi2_driver);
}
-module_init(mipi_csi2_init);
+subsys_initcall(mipi_csi2_init);
module_exit(mipi_csi2_cleanup);
MODULE_AUTHOR("Freescale Semiconductor, Inc.");
diff --git a/drivers/mxc/mipi/mxc_mipi_csi2.h b/drivers/mxc/mipi/mxc_mipi_csi2.h
index d7c4ba1e36da..9bccff7d6ce2 100644
--- a/drivers/mxc/mipi/mxc_mipi_csi2.h
+++ b/drivers/mxc/mipi/mxc_mipi_csi2.h
@@ -28,15 +28,18 @@
/* driver private data */
struct mipi_csi2_info {
- int ipu_id;
+ bool mipi_en;
+ int ipu_id;
unsigned int csi_id;
unsigned int v_channel;
unsigned int lanes;
unsigned int datatype;
- struct clk *dphy_clk;
- struct clk *pixel_clk;
- unsigned int *mipi_csi2_base;
- struct platform_device *pdev;
+ struct clk *dphy_clk;
+ struct clk *pixel_clk;
+ unsigned int *mipi_csi2_base;
+ struct platform_device *pdev;
+
+ struct mutex mutex_lock;
};
#endif
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 2022af73e194..3ca487da1272 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -246,7 +246,7 @@ static void fec_stop(struct net_device *dev);
#define FEC_MMFR_TA (2 << 16)
#define FEC_MMFR_DATA(v) (v & 0xffff)
-#define FEC_MII_TIMEOUT 1000 /* us */
+#define FEC_MII_TIMEOUT 2000 /* us */
/* Transmitter timeout */
#define TX_TIMEOUT (2 * HZ)
@@ -898,9 +898,13 @@ static int fec_enet_mii_init(struct platform_device *pdev)
*/
fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk), 5000000) << 1;
- if (cpu_is_mx6q())
- /* FIXME: hard code to 0x1a for clock issue */
- fep->phy_speed = 0x11a;
+ if (cpu_is_mx6q()) {
+ /* FIXME: non-1588 MII clk: 66MHz, 1588 mode : 40MHz */
+ if (fep->ptimer_present)
+ fep->phy_speed = 0xe;
+ else
+ fep->phy_speed = 0x11a;
+ }
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
index 70c1da61d2e8..094ce699f9eb 100644
--- a/drivers/tty/serial/imx.c
+++ b/drivers/tty/serial/imx.c
@@ -50,9 +50,11 @@
#include <asm/io.h>
#include <asm/irq.h>
+#include <mach/dma.h>
#include <mach/hardware.h>
#include <mach/imx-uart.h>
+
/* Register definitions */
#define URXD0 0x0 /* Receiver Register */
#define URTX0 0x40 /* Transmitter Register */
@@ -82,6 +84,7 @@
#define UCR1_ADBR (1<<14) /* Auto detect baud rate */
#define UCR1_TRDYEN (1<<13) /* Transmitter ready interrupt enable */
#define UCR1_IDEN (1<<12) /* Idle condition interrupt */
+#define UCR1_ICD_REG(x) (((x) & 3) << 10) /* idle condition detect */
#define UCR1_RRDYEN (1<<9) /* Recv ready interrupt enable */
#define UCR1_RDMAEN (1<<8) /* Recv ready DMA enable */
#define UCR1_IREN (1<<7) /* Infrared interface enable */
@@ -90,6 +93,7 @@
#define UCR1_SNDBRK (1<<4) /* Send break */
#define UCR1_TDMAEN (1<<3) /* Transmitter ready DMA enable */
#define MX1_UCR1_UARTCLKEN (1<<2) /* UART clock enabled, mx1 only */
+#define UCR1_ATDMAEN (1<<2) /* Aging DMA Timer Enable */
#define UCR1_DOZE (1<<1) /* Doze */
#define UCR1_UARTEN (1<<0) /* UART enabled */
#define UCR2_ESCI (1<<15) /* Escape seq interrupt enable */
@@ -102,6 +106,7 @@
#define UCR2_STPB (1<<6) /* Stop */
#define UCR2_WS (1<<5) /* Word size */
#define UCR2_RTSEN (1<<4) /* Request to send interrupt enable */
+#define UCR2_ATEN (1<<3) /* Aging Timer Enable */
#define UCR2_TXEN (1<<2) /* Transmitter enabled */
#define UCR2_RXEN (1<<1) /* Receiver enabled */
#define UCR2_SRST (1<<0) /* SW reset */
@@ -126,6 +131,7 @@
#define UCR4_ENIRI (1<<8) /* Serial infrared interrupt enable */
#define UCR4_WKEN (1<<7) /* Wake interrupt enable */
#define UCR4_REF16 (1<<6) /* Ref freq 16 MHz */
+#define UCR4_IDDMAEN (1<<6) /* DMA IDLE Condition Detected */
#define UCR4_IRSC (1<<5) /* IR special case */
#define UCR4_TCEN (1<<3) /* Transmit complete interrupt enable */
#define UCR4_BKEN (1<<2) /* Break condition interrupt enable */
@@ -196,6 +202,17 @@ struct imx_port {
unsigned int irda_inv_tx:1;
unsigned short trcv_delay; /* transceiver delay */
struct clk *clk;
+
+ /* DMA fields */
+ int enable_dma;
+ struct imx_dma_data dma_data;
+ struct dma_chan *dma_chan_rx, *dma_chan_tx;
+ struct scatterlist rx_sgl, tx_sgl[2];
+ void *rx_buf;
+ unsigned int rx_bytes, tx_bytes;
+ struct work_struct tsk_dma_rx, tsk_dma_tx;
+ unsigned int dma_tx_nents;
+ bool dma_is_rxing;
};
#ifdef CONFIG_IRDA
@@ -345,6 +362,79 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
imx_stop_tx(&sport->port);
}
+static void dma_tx_callback(void *data)
+{
+ struct imx_port *sport = data;
+ struct scatterlist *sgl = &sport->tx_sgl[0];
+ struct circ_buf *xmit = &sport->port.state->xmit;
+
+ dma_unmap_sg(sport->port.dev, sgl, sport->dma_tx_nents, DMA_TO_DEVICE);
+
+ /* update the stat */
+ spin_lock(&sport->port.lock);
+ xmit->tail = (xmit->tail + sport->tx_bytes) & (UART_XMIT_SIZE - 1);
+ sport->port.icount.tx += sport->tx_bytes;
+ spin_unlock(&sport->port.lock);
+
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+ uart_write_wakeup(&sport->port);
+ schedule_work(&sport->tsk_dma_tx);
+}
+
+static void dma_tx_work(struct work_struct *w)
+{
+ struct imx_port *sport = container_of(w, struct imx_port, tsk_dma_tx);
+ struct circ_buf *xmit = &sport->port.state->xmit;
+ struct scatterlist *sgl = &sport->tx_sgl[0];
+ struct dma_async_tx_descriptor *desc;
+ struct dma_chan *chan = sport->dma_chan_tx;
+ enum dma_status status;
+ unsigned long flags;
+ int ret;
+
+ status = chan->device->device_tx_status(chan, (dma_cookie_t)NULL, NULL);
+ if (DMA_IN_PROGRESS == status)
+ return;
+
+ spin_lock_irqsave(&sport->port.lock, flags);
+ sport->tx_bytes = uart_circ_chars_pending(xmit);
+ if (sport->tx_bytes > 0) {
+ if (xmit->tail > xmit->head) {
+ sport->dma_tx_nents = 2;
+ sg_init_table(sgl, 2);
+ sg_set_buf(sgl, xmit->buf + xmit->tail,
+ UART_XMIT_SIZE - xmit->tail);
+ sg_set_buf(&sgl[1], xmit->buf, xmit->head);
+ } else {
+ sport->dma_tx_nents = 1;
+ sg_init_one(sgl, xmit->buf + xmit->tail,
+ sport->tx_bytes);
+ }
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+
+ ret = dma_map_sg(sport->port.dev, sgl,
+ sport->dma_tx_nents, DMA_TO_DEVICE);
+ if (ret == 0) {
+ pr_err("DMA mapping error for TX.\n");
+ return;
+ }
+ desc = chan->device->device_prep_slave_sg(chan, sgl,
+ sport->dma_tx_nents, DMA_TO_DEVICE, 0);
+ if (!desc) {
+ pr_err("We cannot prepare for the TX slave dma!\n");
+ return;
+ }
+ desc->callback = dma_tx_callback;
+ desc->callback_param = sport;
+
+ /* fire it */
+ dmaengine_submit(desc);
+ return;
+ }
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+ return;
+}
+
/*
* interrupts disabled on entry
*/
@@ -364,8 +454,10 @@ static void imx_start_tx(struct uart_port *port)
writel(temp, sport->port.membase + UCR1);
}
- temp = readl(sport->port.membase + UCR1);
- writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1);
+ if (!sport->enable_dma) {
+ temp = readl(sport->port.membase + UCR1);
+ writel(temp | UCR1_TXMPTYEN, sport->port.membase + UCR1);
+ }
if (USE_IRDA(sport)) {
temp = readl(sport->port.membase + UCR1);
@@ -377,6 +469,11 @@ static void imx_start_tx(struct uart_port *port)
writel(temp, sport->port.membase + UCR4);
}
+ if (sport->enable_dma) {
+ schedule_work(&sport->tsk_dma_tx);
+ return;
+ }
+
if (readl(sport->port.membase + UTS) & UTS_TXEMPTY)
imx_transmit_buffer(sport);
}
@@ -489,6 +586,28 @@ out:
return IRQ_HANDLED;
}
+/*
+ * We wait for the RXFIFO is filled with some data, and then
+ * arise a DMA operation to receive the data.
+ */
+static void imx_dma_rxint(struct imx_port *sport)
+{
+ unsigned long temp;
+
+ temp = readl(sport->port.membase + USR2);
+ if ((temp & USR2_RDR) && !sport->dma_is_rxing) {
+ sport->dma_is_rxing = true;
+
+ /* disable the `Recerver Ready Interrrupt` */
+ temp = readl(sport->port.membase + UCR1);
+ temp &= ~(UCR1_RRDYEN);
+ writel(temp, sport->port.membase + UCR1);
+
+ /* tell the DMA to receive the data. */
+ schedule_work(&sport->tsk_dma_rx);
+ }
+}
+
static irqreturn_t imx_int(int irq, void *dev_id)
{
struct imx_port *sport = dev_id;
@@ -496,8 +615,12 @@ static irqreturn_t imx_int(int irq, void *dev_id)
sts = readl(sport->port.membase + USR1);
- if (sts & USR1_RRDY)
- imx_rxint(irq, dev_id);
+ if (sts & USR1_RRDY) {
+ if (sport->enable_dma)
+ imx_dma_rxint(sport);
+ else
+ imx_rxint(irq, dev_id);
+ }
if (sts & USR1_TRDY &&
readl(sport->port.membase + UCR1) & UCR1_TXMPTYEN)
@@ -597,6 +720,180 @@ static int imx_setup_ufcr(struct imx_port *sport, unsigned int mode)
return 0;
}
+static bool imx_uart_filter(struct dma_chan *chan, void *param)
+{
+ struct imx_port *sport = param;
+
+ if (!imx_dma_is_general_purpose(chan))
+ return false;
+ chan->private = &sport->dma_data;
+ return true;
+}
+
+#define RX_BUF_SIZE (PAGE_SIZE)
+static int start_rx_dma(struct imx_port *sport);
+
+static void dma_rx_work(struct work_struct *w)
+{
+ struct imx_port *sport = container_of(w, struct imx_port, tsk_dma_rx);
+ struct tty_struct *tty = sport->port.state->port.tty;
+
+ if (sport->rx_bytes) {
+ tty_insert_flip_string(tty, sport->rx_buf, sport->rx_bytes);
+ tty_flip_buffer_push(tty);
+ sport->rx_bytes = 0;
+ }
+
+ if (sport->dma_is_rxing)
+ start_rx_dma(sport);
+}
+
+/*
+ * There are two kinds RX DMA interrupts:
+ * [1] the RX DMA buffer is full.
+ * [2] the Aging timer reached its final value(enabled the UCR4_IDDMAEN).
+ */
+static void dma_rx_callback(void *data)
+{
+ struct imx_port *sport = data;
+ struct dma_chan *chan = sport->dma_chan_rx;
+ unsigned int count;
+ struct tty_struct *tty;
+ struct scatterlist *sgl;
+ struct dma_tx_state state;
+ enum dma_status status;
+
+ tty = sport->port.state->port.tty;
+ sgl = &sport->rx_sgl;
+
+ /* unmap it first */
+ dma_unmap_sg(sport->port.dev, sgl, 1, DMA_FROM_DEVICE);
+
+ status = chan->device->device_tx_status(chan,
+ (dma_cookie_t)NULL, &state);
+ count = RX_BUF_SIZE - state.residue;
+ if (count) {
+ sport->rx_bytes = count;
+ schedule_work(&sport->tsk_dma_rx);
+ } else {
+ unsigned long temp;
+
+ /* Enable the interrupt when the RXFIFO is not empty. */
+ temp = readl(sport->port.membase + UCR1);
+ temp |= UCR1_RRDYEN;
+ writel(temp, sport->port.membase + UCR1);
+ sport->dma_is_rxing = false;
+ }
+}
+
+static int start_rx_dma(struct imx_port *sport)
+{
+ struct scatterlist *sgl = &sport->rx_sgl;
+ struct dma_chan *chan = sport->dma_chan_rx;
+ struct dma_async_tx_descriptor *desc;
+ int ret;
+
+ sg_init_one(sgl, sport->rx_buf, RX_BUF_SIZE);
+ ret = dma_map_sg(sport->port.dev, sgl, 1, DMA_FROM_DEVICE);
+ if (ret == 0) {
+ pr_err("DMA mapping error for RX.\n");
+ return -EINVAL;
+ }
+ desc = chan->device->device_prep_slave_sg(chan,
+ sgl, 1, DMA_FROM_DEVICE, 0);
+ if (!desc) {
+ pr_err("We cannot prepare for the RX slave dma!\n");
+ return -EINVAL;
+ }
+ desc->callback = dma_rx_callback;
+ desc->callback_param = sport;
+
+ dmaengine_submit(desc);
+ return 0;
+}
+
+static void imx_uart_dma_exit(struct imx_port *sport)
+{
+ if (sport->dma_chan_rx) {
+ dma_release_channel(sport->dma_chan_rx);
+ sport->dma_chan_rx = NULL;
+
+ kfree(sport->rx_buf);
+ sport->rx_buf = NULL;
+ }
+
+ if (sport->dma_chan_tx) {
+ dma_release_channel(sport->dma_chan_tx);
+ sport->dma_chan_tx = NULL;
+ }
+}
+
+/* see the "i.MX61 SDMA Scripts User Manual.doc" for the parameters */
+static int imx_uart_dma_init(struct imx_port *sport)
+{
+ struct imxuart_platform_data *pdata = sport->port.dev->platform_data;
+ struct dma_slave_config slave_config;
+ dma_cap_mask_t mask;
+ int ret;
+
+ /* prepare for RX : */
+ dma_cap_zero(mask);
+ dma_cap_set(DMA_SLAVE, mask);
+
+ sport->dma_data.priority = DMA_PRIO_HIGH;
+ sport->dma_data.dma_request = pdata->dma_req_rx;
+ sport->dma_data.peripheral_type = IMX_DMATYPE_UART;
+
+ sport->dma_chan_rx = dma_request_channel(mask, imx_uart_filter, sport);
+ if (!sport->dma_chan_rx) {
+ pr_err("cannot get the DMA channel.\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ slave_config.direction = DMA_FROM_DEVICE;
+ slave_config.src_addr = sport->port.mapbase + URXD0;
+ slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ slave_config.src_maxburst = RXTL; /* fix me */
+ ret = dmaengine_slave_config(sport->dma_chan_rx, &slave_config);
+ if (ret) {
+ pr_err("error in RX dma configuration.\n");
+ goto err;
+ }
+
+ sport->rx_buf = kzalloc(PAGE_SIZE, GFP_DMA);
+ if (!sport->rx_buf) {
+ pr_err("cannot alloc DMA buffer.\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+ sport->rx_bytes = 0;
+
+ /* prepare for TX : */
+ sport->dma_data.dma_request = pdata->dma_req_tx;
+ sport->dma_chan_tx = dma_request_channel(mask, imx_uart_filter, sport);
+ if (!sport->dma_chan_tx) {
+ pr_err("cannot get the TX DMA channel!\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ slave_config.direction = DMA_TO_DEVICE;
+ slave_config.dst_addr = sport->port.mapbase + URTX0;
+ slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+ slave_config.dst_maxburst = TXTL; /* fix me */
+ ret = dmaengine_slave_config(sport->dma_chan_tx, &slave_config);
+ if (ret) {
+ pr_err("error in TX dma configuration.");
+ goto err;
+ }
+
+ return 0;
+err:
+ imx_uart_dma_exit(sport);
+ return ret;
+}
+
/* half the RX buffer size */
#define CTSTL 16
@@ -607,7 +904,9 @@ static int imx_startup(struct uart_port *port)
unsigned long flags, temp;
struct tty_struct *tty;
+#ifndef CONFIG_SERIAL_CORE_CONSOLE
imx_setup_ufcr(sport, 0);
+#endif
/* disable the DREN bit (Data Ready interrupt enable) before
* requesting IRQs
@@ -669,6 +968,19 @@ static int imx_startup(struct uart_port *port)
}
}
+ /* Enable the SDMA for uart. */
+ if (sport->enable_dma) {
+ int ret;
+ ret = imx_uart_dma_init(sport);
+ if (ret)
+ goto error_out3;
+
+ sport->port.flags |= UPF_LOW_LATENCY;
+ INIT_WORK(&sport->tsk_dma_tx, dma_tx_work);
+ INIT_WORK(&sport->tsk_dma_rx, dma_rx_work);
+ }
+
+ spin_lock_irqsave(&sport->port.lock, flags);
/*
* Finally, clear and enable interrupts
*/
@@ -676,6 +988,11 @@ static int imx_startup(struct uart_port *port)
temp = readl(sport->port.membase + UCR1);
temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN;
+ if (sport->enable_dma) {
+ temp |= UCR1_RDMAEN | UCR1_TDMAEN | UCR1_ATDMAEN;
+ /* ICD, wait for more than 32 frames, but it still to short. */
+ temp |= UCR1_ICD_REG(3);
+ }
if (USE_IRDA(sport)) {
temp |= UCR1_IREN;
@@ -719,10 +1036,15 @@ static int imx_startup(struct uart_port *port)
writel(temp, sport->port.membase + UCR3);
}
+ if (sport->enable_dma) {
+ temp = readl(sport->port.membase + UCR4);
+ temp |= UCR4_IDDMAEN;
+ writel(temp, sport->port.membase + UCR4);
+ }
+
/*
* Enable modem status interrupts
*/
- spin_lock_irqsave(&sport->port.lock,flags);
imx_enable_ms(&sport->port);
spin_unlock_irqrestore(&sport->port.lock,flags);
@@ -756,10 +1078,13 @@ static void imx_shutdown(struct uart_port *port)
{
struct imx_port *sport = (struct imx_port *)port;
unsigned long temp;
+ unsigned long flags;
+ spin_lock_irqsave(&sport->port.lock, flags);
temp = readl(sport->port.membase + UCR2);
temp &= ~(UCR2_TXEN);
writel(temp, sport->port.membase + UCR2);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
if (USE_IRDA(sport)) {
struct imxuart_platform_data *pdata;
@@ -788,12 +1113,17 @@ static void imx_shutdown(struct uart_port *port)
* Disable all interrupts, port and break condition.
*/
+ spin_lock_irqsave(&sport->port.lock, flags);
temp = readl(sport->port.membase + UCR1);
temp &= ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN);
if (USE_IRDA(sport))
temp &= ~(UCR1_IREN);
writel(temp, sport->port.membase + UCR1);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
+
+ if (sport->enable_dma)
+ imx_uart_dma_exit(sport);
}
static void
@@ -952,6 +1282,7 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
if (UART_ENABLE_MS(&sport->port, termios->c_cflag))
imx_enable_ms(&sport->port);
+
}
static const char *imx_type(struct uart_port *port)
@@ -1072,7 +1403,9 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
{
struct imx_port *sport = imx_ports[co->index];
unsigned int old_ucr1, old_ucr2, ucr1;
+ unsigned long flags;
+ spin_lock_irqsave(&sport->port.lock, flags);
/*
* First, save UCR1/2 and then disable interrupts
*/
@@ -1098,6 +1431,7 @@ imx_console_write(struct console *co, const char *s, unsigned int count)
writel(old_ucr1, sport->port.membase + UCR1);
writel(old_ucr2, sport->port.membase + UCR2);
+ spin_unlock_irqrestore(&sport->port.lock, flags);
}
/*
@@ -1319,6 +1653,9 @@ static int serial_imx_probe(struct platform_device *pdev)
sport->have_rtscts = 1;
if (pdata && (pdata->flags & IMXUART_USE_DCEDTE))
sport->use_dcedte = 1;
+ if (pdata && (pdata->flags & IMXUART_SDMA))
+ sport->enable_dma = 1;
+
#ifdef CONFIG_IRDA
if (pdata && (pdata->flags & IMXUART_IRDA))
sport->use_irda = 1;
diff --git a/drivers/usb/gadget/arcotg_udc.c b/drivers/usb/gadget/arcotg_udc.c
index cd649a416a96..e84ede66ad9c 100644
--- a/drivers/usb/gadget/arcotg_udc.c
+++ b/drivers/usb/gadget/arcotg_udc.c
@@ -865,8 +865,13 @@ static int fsl_queue_td(struct fsl_ep *ep, struct fsl_req *req)
? (1 << (ep_index(ep) + 16))
: (1 << (ep_index(ep)));
- /* check if the pipe is empty */
- if (!(list_empty(&ep->queue))) {
+ /*
+ * check if
+ * - the request is empty, and
+ * - the request is not the status request for ep0
+ */
+ if (!(list_empty(&ep->queue)) &&
+ !((ep_index(ep) == 0) && (req->req.length == 0))) {
/* Add td to the end */
struct fsl_req *lastreq;
lastreq = list_entry(ep->queue.prev, struct fsl_req, queue);
@@ -1128,10 +1133,6 @@ static int fsl_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req)
spin_lock_irqsave(&ep->udc->lock, flags);
stopped = ep->stopped;
udc = ep->udc;
- if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN) {
- spin_unlock_irqrestore(&ep->udc->lock, flags);
- return -ESHUTDOWN;
- }
/* Stop the ep before we deal with the queue */
ep->stopped = 1;
@@ -2053,8 +2054,10 @@ static int reset_queues(struct fsl_udc *udc)
for (pipe = 0; pipe < udc->max_pipes; pipe++)
udc_reset_ep_queue(udc, pipe);
+ spin_unlock(&udc->lock);
/* report disconnect; the driver is already quiesced */
udc->driver->disconnect(&udc->gadget);
+ spin_lock(&udc->lock);
return 0;
}
@@ -2097,22 +2100,79 @@ static void reset_irq(struct fsl_udc *udc)
udc->usb_state = USB_STATE_DEFAULT;
}
-static void fsl_gadget_event(struct work_struct *work)
+#define FSL_DP_CHANGE_TIMEOUT (msecs_to_jiffies(1000)) /* 1000 ms */
+static void gadget_wait_line_to_se0(void)
+{
+ unsigned long timeout;
+ timeout = jiffies + FSL_DP_CHANGE_TIMEOUT;
+ /* Wait for DP to SE0 */
+ while (!((fsl_readl(&dr_regs->portsc1) &
+ (u32)((1 << 10) | (1 << 11))) == PORTSCX_LINE_STATUS_SE0)) {
+ if (time_after(jiffies, timeout)) {
+ pr_warning(KERN_ERR "wait dp to SE0 timeout, please check"
+ " your hardware design!\n");
+ break;
+ }
+ msleep(10);
+ }
+}
+
+#define FSL_WAIT_CLASS_DRIVER_TIMEOUT (msecs_to_jiffies(3000)) /* 3s */
+static void gadget_wait_class_driver_finish(void)
+{
+ unsigned long timeout;
+ struct fsl_udc *udc = udc_controller;
+ struct fsl_ep *ep;
+ int i = 2;
+ timeout = jiffies + FSL_WAIT_CLASS_DRIVER_TIMEOUT;
+ /* for non-control endpoints */
+ while (i < (int)(udc_controller->max_ep)) {
+ ep = &udc->eps[i++];
+ if (ep->stopped == 0) {
+ if (time_after(timeout, jiffies)) {
+ i = 2;
+ msleep(10);
+ continue;
+ } else {
+ pr_warning(KERN_WARNING "We have waited 3s, but the class driver"
+ " has still not finishes!\n");
+ break;
+ }
+ }
+ }
+}
+
+static void fsl_gadget_disconnect_event(struct work_struct *work)
{
struct fsl_udc *udc = udc_controller;
unsigned long flags;
+ struct fsl_usb2_platform_data *pdata;
u32 tmp;
- if (udc->driver)
- udc->driver->disconnect(&udc->gadget);
+ pdata = udc->pdata;
+
+ /* enable pulldown dp */
+ if (pdata->gadget_discharge_dp)
+ pdata->gadget_discharge_dp(true);
+ /*
+ * Some boards are very slow change line state from J to SE0 for DP,
+ * So, we need to discharge DP, otherwise there is a wakeup interrupt
+ * after we enable the wakeup function.
+ */
+ gadget_wait_line_to_se0();
+
+ /* Disable pulldown dp */
+ if (pdata->gadget_discharge_dp)
+ pdata->gadget_discharge_dp(false);
+
+ /*
+ * Wait class drivers finish, an well-behaviour class driver should
+ * call ep_disable when it is notified to be disconnected.
+ */
+ gadget_wait_class_driver_finish();
+
spin_lock_irqsave(&udc->lock, flags);
- /* update port status */
- fsl_udc_speed_update(udc);
- spin_unlock_irqrestore(&udc->lock, flags);
- udc->stopped = 1;
- /* enable wake up */
- dr_wake_up_enable(udc, true);
/* here we need to enable the B_SESSION_IRQ
* to enable the following device attach
*/
@@ -2120,6 +2180,10 @@ static void fsl_gadget_event(struct work_struct *work)
if (!(tmp & (OTGSC_B_SESSION_VALID_IRQ_EN)))
fsl_writel(tmp | (OTGSC_B_SESSION_VALID_IRQ_EN),
&dr_regs->otgsc);
+ udc->stopped = 1;
+ /* enable wake up */
+ dr_wake_up_enable(udc, true);
+ spin_unlock_irqrestore(&udc->lock, flags);
/* close USB PHY clock */
dr_phy_low_power_mode(udc, true);
/* close dr controller clock */
@@ -2169,11 +2233,14 @@ bool try_wake_up_udc(struct fsl_udc *udc)
fsl_writel(tmp &
(~OTGSC_B_SESSION_VALID_IRQ_EN),
&dr_regs->otgsc);
- /*here we need delay 30 ms for avoid exception usb vbus falling interrupt
- Once we clear the RS bit, D+ D- need about 20 ms to SE0 modet ,during this period
- we can not enable device wake up
- */
- schedule_delayed_work(&udc->gadget_delay_work, msecs_to_jiffies(30));
+
+ /* update port status */
+ fsl_udc_speed_update(udc);
+ spin_unlock(&udc->lock);
+ if (udc->driver)
+ udc->driver->disconnect(&udc->gadget);
+ spin_lock(&udc->lock);
+ schedule_work(&udc->gadget_disconnect_schedule);
return false;
}
}
@@ -2782,7 +2849,15 @@ static int __init struct_ep_setup(struct fsl_udc *udc, unsigned char index,
ep->ep.name = ep->name;
ep->ep.ops = &fsl_ep_ops;
- ep->stopped = 0;
+ /*
+ * For ep0, the endpoint is enabled after controller initialization
+ * For non-ep0, the endpoint is stopped default, and will be enabled
+ * by class driver when needed.
+ */
+ if (index)
+ ep->stopped = 1;
+ else
+ ep->stopped = 0;
/* for ep0: maxP defined in desc
* for other eps, maxP is set by epautoconfig() called by gadget layer
@@ -2959,7 +3034,7 @@ static int __devinit fsl_udc_probe(struct platform_device *pdev)
}
}
- INIT_DELAYED_WORK(&udc_controller->gadget_delay_work, fsl_gadget_event);
+ INIT_WORK(&udc_controller->gadget_disconnect_schedule, fsl_gadget_disconnect_event);
#ifdef POSTPONE_FREE_LAST_DTD
last_free_td = NULL;
#endif
diff --git a/drivers/usb/gadget/arcotg_udc.h b/drivers/usb/gadget/arcotg_udc.h
index eb92e470a7f3..00c8e8a8cdd7 100644
--- a/drivers/usb/gadget/arcotg_udc.h
+++ b/drivers/usb/gadget/arcotg_udc.h
@@ -232,8 +232,8 @@ struct usb_sys_interface {
/* bit 11-10 are line status */
#define PORTSCX_LINE_STATUS_SE0 (0x00000000)
-#define PORTSCX_LINE_STATUS_JSTATE (0x00000400)
-#define PORTSCX_LINE_STATUS_KSTATE (0x00000800)
+#define PORTSCX_LINE_STATUS_KSTATE (0x00000400)
+#define PORTSCX_LINE_STATUS_JSTATE (0x00000800)
#define PORTSCX_LINE_STATUS_UNDEF (0x00000C00)
#define PORTSCX_LINE_STATUS_BIT_POS (10)
@@ -624,7 +624,7 @@ struct fsl_udc {
struct completion *done; /* to make sure release() is done */
u32 iram_buffer[IRAM_PPH_NTD];
void *iram_buffer_v[IRAM_PPH_NTD];
- struct delayed_work gadget_delay_work;
+ struct work_struct gadget_disconnect_schedule;
};
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index c23b2185ff8f..d843277d68ec 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -3163,7 +3163,6 @@ static int fsg_main_thread(void *fsg_)
complete_and_exit(&fsg->thread_notifier, 0);
}
-
/*-------------------------------------------------------------------------*/
@@ -3202,6 +3201,15 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
DBG(fsg, "unbind\n");
clear_bit(REGISTERED, &fsg->atomic_bitflags);
+ /* If the thread isn't already dead, tell it to exit now */
+ if (fsg->state != FSG_STATE_TERMINATED) {
+ raise_exception(fsg, FSG_STATE_EXIT);
+ wait_for_completion(&fsg->thread_notifier);
+
+ /* The cleanup routine waits for this completion also */
+ complete(&fsg->thread_notifier);
+ }
+
/* Unregister the sysfs attribute files and the LUNs */
for (i = 0; i < fsg->nluns; ++i) {
curlun = &fsg->luns[i];
@@ -3215,15 +3223,6 @@ static void /* __init_or_exit */ fsg_unbind(struct usb_gadget *gadget)
}
}
- /* If the thread isn't already dead, tell it to exit now */
- if (fsg->state != FSG_STATE_TERMINATED) {
- raise_exception(fsg, FSG_STATE_EXIT);
- wait_for_completion(&fsg->thread_notifier);
-
- /* The cleanup routine waits for this completion also */
- complete(&fsg->thread_notifier);
- }
-
/* Free the data buffers */
for (i = 0; i < FSG_NUM_BUFFERS; ++i)
kfree(fsg->buffhds[i].buf);
diff --git a/drivers/usb/otg/fsl_otg.c b/drivers/usb/otg/fsl_otg.c
index a30815cba3f1..be8e0160a197 100644
--- a/drivers/usb/otg/fsl_otg.c
+++ b/drivers/usb/otg/fsl_otg.c
@@ -168,11 +168,11 @@ static void fsl_otg_wait_stable_vbus(bool on)
fsl_otg_clk_gate(true);
/* Wait for vbus change to B_SESSION_VALID complete */
timeout = jiffies + FSL_VBUS_CHANGE_TIMEOUT;
- while ((le32_to_cpu(usb_dr_regs->otgsc)&OTGSC_INTSTS_B_SESSION_VALID) == !on) {
+ while ((le32_to_cpu(usb_dr_regs->otgsc)&OTGSC_STS_B_SESSION_VALID) != (on << 11)) {
if (time_after(jiffies, timeout)) {
printk(KERN_ERR"wait otg vbus change timeout! \n");
fsl_otg_clk_gate(false);
- break;
+ return;
}
msleep(10);
}
@@ -619,8 +619,11 @@ static int fsl_otg_set_host(struct otg_transceiver *otg_p, struct usb_bus *host)
* so suspend the host after a short delay.
*/
otg_dev->host_working = 1;
- if (otg_dev->fsm.id)
+
+ if (otg_dev->fsm.id) {
+ otg_dev->host_first_call = true;
schedule_otg_work(&otg_dev->otg_event, 100);
+ }
else {
/* if the device is already at the port */
otg_drv_vbus(&otg_dev->fsm, 1);
@@ -733,8 +736,12 @@ static void fsl_otg_event(struct work_struct *work)
if (fsm->id) { /* switch to gadget */
fsl_otg_start_host(fsm, 0);
otg_drv_vbus(fsm, 0);
- fsl_otg_wait_stable_vbus(false);
- fsl_otg_wait_dischrg_vbus();
+ if (og->host_first_call == false) {
+ fsl_otg_wait_dischrg_vbus();
+ fsl_otg_wait_stable_vbus(false);
+ } else {
+ og->host_first_call = false;
+ }
b_session_irq_enable(false);
fsl_otg_start_gadget(fsm, 1);
} else { /* switch to host */
@@ -943,6 +950,7 @@ static int fsl_otg_conf(struct platform_device *pdev)
fsl_otg_tc->otg.start_hnp = fsl_otg_start_hnp;
fsl_otg_tc->otg.start_srp = fsl_otg_start_srp;
fsl_otg_tc->otg.dev = &pdev->dev;
+ fsl_otg_tc->host_first_call = false;
fsl_otg_dev = fsl_otg_tc;
diff --git a/drivers/usb/otg/fsl_otg.h b/drivers/usb/otg/fsl_otg.h
index a8536815d0bf..d3d382bd8e32 100644
--- a/drivers/usb/otg/fsl_otg.h
+++ b/drivers/usb/otg/fsl_otg.h
@@ -385,6 +385,8 @@ struct fsl_otg {
/*used for usb host */
struct work_struct work_wq;
u8 host_working;
+ /*Used for host init call,we need to avoid discharge Vbus when usb cable connect to PC*/
+ bool host_first_call;
int irq;
};
diff --git a/drivers/video/backlight/pwm_bl.c b/drivers/video/backlight/pwm_bl.c
index 79bf1f40bca5..7642172ba844 100644
--- a/drivers/video/backlight/pwm_bl.c
+++ b/drivers/video/backlight/pwm_bl.c
@@ -66,7 +66,10 @@ static int pwm_backlight_check_fb(struct backlight_device *bl,
struct fb_info *info)
{
char *id = info->fix.id;
- if (!strcmp(id, "DISP3 BG"))
+ if (!strcmp(id, "DISP3 BG") ||
+ !strcmp(id, "DISP3 BG - DI1") ||
+ !strcmp(id, "DISP4 BG") ||
+ !strcmp(id, "DISP4 BG - DI1"))
return 1;
else
return 0;
diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c
index e68efb88abbb..0b5c2f06722b 100644
--- a/drivers/video/mxc/mxc_ipuv3_fb.c
+++ b/drivers/video/mxc/mxc_ipuv3_fb.c
@@ -85,7 +85,7 @@ struct mxcfb_info {
u32 pseudo_palette[16];
bool mode_found;
- bool wait4vsync;
+ volatile bool wait4vsync;
struct semaphore flip_sem;
struct semaphore alpha_flip_sem;
struct completion vsync_complete;
@@ -233,8 +233,7 @@ static int _setup_disp_channel2(struct fb_info *fbi)
}
fbi->var.xoffset = 0;
- base = (fbi->var.yoffset * fbi->var.xres_virtual + fbi->var.xoffset);
- base = (fbi->var.bits_per_pixel) * base / 8;
+ base = (fbi->var.yoffset * fb_stride + fbi->var.xoffset);
base += fbi->fix.smem_start;
retval = ipu_init_channel_buffer(mxc_fbi->ipu,
@@ -242,10 +241,11 @@ static int _setup_disp_channel2(struct fb_info *fbi)
bpp_to_pixfmt(fbi),
fbi->var.xres, fbi->var.yres,
fb_stride,
- IPU_ROTATE_NONE,
- base,
+ fbi->var.rotate,
base,
base,
+ fbi->var.accel_flags &
+ FB_ACCEL_DOUBLE_FLAG ? 0 : base,
0, 0);
if (retval) {
dev_err(fbi->device,
@@ -259,7 +259,7 @@ static int _setup_disp_channel2(struct fb_info *fbi)
IPU_PIX_FMT_GENERIC,
fbi->var.xres, fbi->var.yres,
fbi->var.xres,
- IPU_ROTATE_NONE,
+ fbi->var.rotate,
mxc_fbi->alpha_phy_addr1,
mxc_fbi->alpha_phy_addr0,
0,
@@ -574,6 +574,9 @@ static int mxcfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
var->yres = bg_yres - pos_y;
}
+ if (var->rotate > IPU_ROTATE_VERT_FLIP)
+ var->rotate = IPU_ROTATE_NONE;
+
if (var->xres_virtual < var->xres)
var->xres_virtual = var->xres;
@@ -928,7 +931,7 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
init_completion(&mxc_fbi->vsync_complete);
ipu_clear_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
- mxc_fbi->wait4vsync = 1;
+ mxc_fbi->wait4vsync = true;
ipu_enable_irq(mxc_fbi->ipu, mxc_fbi->ipu_ch_irq);
retval = wait_for_completion_interruptible_timeout(
&mxc_fbi->vsync_complete, 1 * HZ);
@@ -936,7 +939,7 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
dev_err(fbi->device,
"MXCFB_WAIT_FOR_VSYNC: timeout %d\n",
retval);
- mxc_fbi->wait4vsync = 0;
+ mxc_fbi->wait4vsync = false;
retval = -ETIME;
} else if (retval > 0) {
retval = 0;
@@ -1155,6 +1158,7 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
u_int y_bottom;
unsigned long base, active_alpha_phy_addr = 0;
bool loc_alpha_en = false;
+ int fb_stride;
int i;
if (info->var.yoffset == var->yoffset)
@@ -1184,8 +1188,20 @@ mxcfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
if (y_bottom > info->var.yres_virtual)
return -EINVAL;
- base = (var->yoffset * var->xres_virtual + var->xoffset);
- base = (var->bits_per_pixel) * base / 8;
+ switch (bpp_to_pixfmt(info)) {
+ case IPU_PIX_FMT_YUV420P2:
+ case IPU_PIX_FMT_YVU420P:
+ case IPU_PIX_FMT_NV12:
+ case IPU_PIX_FMT_YUV422P:
+ case IPU_PIX_FMT_YVU422P:
+ case IPU_PIX_FMT_YUV420P:
+ fb_stride = info->var.xres_virtual;
+ break;
+ default:
+ fb_stride = info->fix.line_length;
+ }
+
+ base = (var->yoffset * fb_stride + var->xoffset);
base += info->fix.smem_start;
/* Check if DP local alpha is enabled and find the graphic fb */
@@ -1361,7 +1377,7 @@ static irqreturn_t mxcfb_irq_handler(int irq, void *dev_id)
if (mxc_fbi->wait4vsync) {
complete(&mxc_fbi->vsync_complete);
ipu_disable_irq(mxc_fbi->ipu, irq);
- mxc_fbi->wait4vsync = 0;
+ mxc_fbi->wait4vsync = false;
} else {
up(&mxc_fbi->flip_sem);
ipu_disable_irq(mxc_fbi->ipu, irq);
diff --git a/drivers/video/mxc_hdmi.c b/drivers/video/mxc_hdmi.c
index 95083f2ebd3a..09930158fb0e 100644
--- a/drivers/video/mxc_hdmi.c
+++ b/drivers/video/mxc_hdmi.c
@@ -138,6 +138,8 @@ struct mxc_hdmi {
struct i2c_client *hdmi_i2c;
+extern const struct fb_videomode mxc_cea_mode[64];
+
/*!
* this submodule is responsible for the video data synchronization.
* for example, for RGB 4:4:4 input, the data map is defined as
@@ -1226,6 +1228,9 @@ static int mxc_hdmi_read_edid(struct mxc_hdmi *hdmi,
ret = mxc_edid_read(hdmi_i2c->adapter, hdmi_i2c->addr,
hdmi->edid, &hdmi->edid_cfg, fbi);
+ if (ret < 0)
+ return ret;
+
if (!memcmp(edid_old, hdmi->edid, HDMI_EDID_LEN))
ret = -2;
return ret;
@@ -1298,9 +1303,27 @@ static void mxc_hdmi_disable(struct mxc_hdmi *hdmi)
clk_disable(hdmi->hdmi_iahb_clk);
}
+static void mxc_hdmi_default_modelist(struct mxc_hdmi *hdmi)
+{
+ u32 i;
+ const struct fb_videomode *mode;
+
+ fb_destroy_modelist(&hdmi->fbi->modelist);
+
+ for (i = 0; i < ARRAY_SIZE(mxc_cea_mode); i++) {
+ mode = &mxc_cea_mode[i];
+ if ((mode->xres == hdmi->fbi->var.xres) &&
+ (mode->yres == hdmi->fbi->var.yres) &&
+ !(mode->vmode & FB_VMODE_INTERLACED))
+ fb_add_videomode(mode, &hdmi->fbi->modelist);
+ }
+}
+
static int mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi)
{
int ret;
+ struct fb_videomode m;
+ const struct fb_videomode *mode;
dev_dbg(&hdmi->pdev->dev, "cable connected\n");
@@ -1308,14 +1331,10 @@ static int mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi)
/* edid read */
ret = mxc_hdmi_read_edid(hdmi, hdmi->fbi);
- if (ret == -1)
- dev_err(&hdmi->pdev->dev, "read edid fail\n");
- else if (ret == -2)
+ if (ret == -2)
dev_info(&hdmi->pdev->dev, "same edid\n");
else if (hdmi->fbi->monspecs.modedb_len > 0) {
int i;
- const struct fb_videomode *mode;
- struct fb_videomode m;
fb_destroy_modelist(&hdmi->fbi->modelist);
@@ -1340,11 +1359,24 @@ static int mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi)
fb_var_to_videomode(&m, &hdmi->fbi->var);
mode = fb_find_nearest_mode(&m,
&hdmi->fbi->modelist);
+ if (mode)
+ fb_videomode_to_var(&hdmi->fbi->var, mode);
- fb_videomode_to_var(&hdmi->fbi->var, mode);
- hdmi->need_mode_change = true;
- } else
+ hdmi->need_mode_change = mode ? true : false;
+ } else {
+ /* If not EDID data readed, setup default modelist */
dev_info(&hdmi->pdev->dev, "No modes read from edid\n");
+ mxc_hdmi_default_modelist(hdmi);
+
+ fb_var_to_videomode(&m, &hdmi->fbi->var);
+ mode = fb_find_nearest_mode(&m,
+ &hdmi->fbi->modelist);
+ if (mode)
+ fb_videomode_to_var(&hdmi->fbi->var, mode);
+
+ hdmi->need_mode_change = mode ? true : false;
+ }
+
return 0;
}
@@ -1593,6 +1625,9 @@ static int mxc_hdmi_disp_init(struct mxc_dispdrv_entry *disp)
int irq = platform_get_irq(hdmi->pdev, 0);
bool found = false;
u8 val;
+ const struct fb_videomode *mode;
+ struct fb_videomode m;
+ struct fb_var_screeninfo var;
if (!plat || irq < 0)
return -ENODEV;
@@ -1658,13 +1693,19 @@ static int mxc_hdmi_disp_init(struct mxc_dispdrv_entry *disp)
/* try to read edid */
ret = mxc_hdmi_read_edid(hdmi, hdmi->fbi);
- if (ret < 0)
- dev_warn(&hdmi->pdev->dev, "Can not read edid\n");
- else if (hdmi->fbi->monspecs.modedb_len > 0) {
+ if (ret < 0) {
+ /* If not EDID data readed, setup default modelist */
+ dev_info(&hdmi->pdev->dev, "No modes read from edid\n");
+ mxc_hdmi_default_modelist(hdmi);
+
+ fb_var_to_videomode(&m, &hdmi->fbi->var);
+ mode = fb_find_nearest_mode(&m,
+ &hdmi->fbi->modelist);
+
+ fb_videomode_to_var(&hdmi->fbi->var, mode);
+ hdmi->need_mode_change = true;
+ } else if (hdmi->fbi->monspecs.modedb_len > 0) {
int i;
- const struct fb_videomode *mode;
- struct fb_videomode m;
- struct fb_var_screeninfo var;
for (i = 0; i < hdmi->fbi->monspecs.modedb_len; i++) {
/*
diff --git a/firmware/imx/sdma/sdma-imx6q-to1.bin.ihex b/firmware/imx/sdma/sdma-imx6q-to1.bin.ihex
index d180a30e6916..04ae9928afde 100644
--- a/firmware/imx/sdma/sdma-imx6q-to1.bin.ihex
+++ b/firmware/imx/sdma/sdma-imx6q-to1.bin.ihex
@@ -1,106 +1,99 @@
-:1000000053444D4101000000000000001C000000AE
-:1000100023000000A8000000DC05000082020000B0
+:1000000053444D4101000000010000001C000000AD
+:1000100023000000A80000006A0500008202000022
:10002000FFFFFFFF00000000FFFFFFFFFFFFFFFFDC
:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
-:10004000FFFFFFFFFFFFFFFF31030000FFFFFFFF88
-:10005000EB0200003F190000FFFFFFFF0804000053
-:10006000FFFFFFFFC0030000FFFFFFFFFFFFFFFFD9
-:10007000FFFFFFFFAB020000FFFFFFFF7B0300005D
+:10004000FFFFFFFFB61800006A1A00004B04000013
+:10005000EB0200004A190000FF180000080400002D
+:1000600095040000C0030000C105000070050000F9
+:1000700009040000AB020000E30400007B03000061
:10008000FFFFFFFFFFFFFFFF4C0400006E040000B6
-:10009000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
-:1000A0000000000000180000700D11051555CD5A14
-:1000B000FD5F010B6606017C17036706027C1703D0
-:1000C00017036806047C1703170317031703C55BA0
-:1000D0008D073CC1637D4EC1617C081DD75ADF5B33
-:1000E000E75CEF5DF75E8803700E1106FF0A1102F0
-:1000F000FF1ABC02800CD402017C8A04A4022E5593
-:10010000B905004D057CFE55BB05004D017C2B98C3
-:10011000FF55E7507800017C081D216DF755056DEE
-:10012000081DF75D7DD81F7F080818681C7C286DA6
-:100130001A7F0824027C004A1B7DFF55E750780097
-:10014000017D081D056DEF55016D081DEF5D080867
-:100150001868097C286D077F004CD17C0000269828
-:10016000DF5BE75C880307000C68E7545404E75C36
-:100170008B00D752DF53E75459C1107C4EC10E7C1F
-:10018000DF5BFF527803017D081A016D056A0808DC
-:100190001868E67C286AE47FD75219987DD8000059
-:1001A0001598CF55D26DC755C86DDE6D010206009A
-:1001B000E3C1DB57E35FE357F352016A8F00D500D9
-:1001C000017D8D00A005EB5D7804037D79042C7D15
-:1001D000367C79041F7CEE56000F6006057D0965AC
-:1001E000437E0A62417EA4980A623E7E09653C7E97
-:1001F00012051205AD026007037DFB55D36DAF9864
-:10020000FB55041DD36DC86A2F7F011F03200048D2
-:10021000E47CD798FB55D76D150005780962C86A4C
-:100220000962C86AD76DD698FB55D76D15001500C1
-:1002300005780A62C86A0A62C86AD76DD698FB5503
-:10024000D76D15001500150005780B62C86A0B62A2
-:10025000C86AD76D097CDF6D077F0000EB55004D44
-:10026000077DFAC1E3578A980700CC680C6813C26F
-:100270000AC28798D9C1E3C1DB57E35FE357F35262
-:10028000216A8F00D500017D8D00A005EB5DFB5636
-:100290007804037D79042A7D317C7904207C700BFD
-:1002A0001103EB53000F6003057D0965377E0A6279
-:1002B000357E0A990A62327E0965307E1205120582
-:1002C000AD026007027C065A1299265A277F011F49
-:1002D00003200048E87C700B110313533399150079
-:1002E00004780962065A0962265A329915001500E7
-:1002F00004780A62065A0A62265A329915001500D5
-:10030000150004780B62065A0B62265A077C00001F
-:10031000EB55004D067DFAC1E357ED9807000C68D8
-:1003200013C20AC2EA98700B110313536C07017CC5
-:10033000D9C1FB5E8A066B07017CD9C1F35EDB592C
-:10034000D3588F0110010F398B003CC12B7DC05A4F
-:10035000C85B4EC1277C88038906E35CFF0D11054D
-:10036000FF1DBC053E07004D187D700811007E077B
-:10037000097D7D07027D28526A99F852DB54BC0240
-:10038000CC02097C7C07027D28527399F852D35421
-:10039000BC02CC02097D000461998B00C052C85395
-:1003A00059C1D67D00025199FF08BF007F07157D16
-:1003B0008804D500017D8D00A005EB5D8F0212023F
-:1003C0001202FF3ADA05027C3E079C99A402DD0284
-:1003D000027D3E079C995E079C99EB559805EB5D65
-:1003E000F352FB546A07267D6C07017DD9996B0790
-:1003F000577C6907047D6807027D010EB399935805
-:10040000D600017D8E009355A005935DA00602786D
-:100410000255045D1D7C004E087C6907037D025572
-:10042000177EC099045D147F890693500048017DB2
-:10043000AB99249A150006780255045D4F070255C2
-:10044000245D2F07017C249A17006F07017C01208F
-:1004500093559D0007002BDA7999D36C6907047DC9
-:100460006807027D010EE8999358D600017D8E0041
-:100470009355A005935DA00602780255C86D0F7CC8
-:10048000004E087C6907037D0255097EF599C86D09
-:10049000067F890693500048017DE099249A1E9AB0
-:1004A000C36A6907047D6807027D010E0B9A9358A1
-:1004B000D600017D8E009355A005935DA0060278BD
-:1004C000C865045D0F7C004E087C6907037DC86524
-:1004D000097E189A045D067F890693500048017DC5
-:1004E000039A249A93559D000700FF6C2BDA7999A3
-:1004F0000000E354EB55004D017C79996199E35478
-:10050000EB55FF0A1102FF1A7F07027CA005389AFB
-:100510009D008C05BA05A0051002BA04AD04540470
-:100520000600E3C1DB57FB52C36AF352056A8F0032
-:10053000D500017D8D00A005EB5D7804037D790475
-:100540002B7D1E7C7904337CEE56000FFB55600733
-:10055000027DC36D599A041DC36DC8623B7E60065F
-:10056000027D10021202096A357F1202096A327F87
-:100570001202096A2F7F011F03200048E77C8D9A31
-:10058000FB55C76D1500150015000578C8620B6A8C
-:10059000C8620B6AC76D8C9AFB55C76D15001500B4
-:1005A0000578C8620A6AC8620A6AC76D8C9AFB55E8
-:1005B000C76D15000578C862096AC862096AC76D07
-:1005C000097C286A077F0000EB55004D057DFAC1C4
-:1005D000DB57439A77C254040AC23E9AD9C1E3C199
-:1005E000DB57F352056A8F00D500017D8D00A00511
-:1005F000FB567804037D7904297D1F7C79042E7CC9
-:10060000E35D700D1105ED55000F6007027D065288
-:10061000B69A2652337E6005027D10021202096AE4
-:100620002D7F1202096A2A7F1202096A277F011FA1
-:1006300003200048EA7CE355E19A150015001500F7
-:10064000047806520B6A26520B6AE09A15001500D0
-:10065000047806520A6A26520A6AE09A150004785B
-:100660000652096A2652096A097C286A077F000037
-:10067000DB57004D057DFAC1DB579F9A77C25404C2
-:040680000AC29C9A74
+:10009000FFFFFFFF00180000FFFFFFFFFFFFFFFF54
+:1000A0000000000000180000E3C1DB57E35FE357E6
+:1000B000F352016A8F00D500017D8D00A005EB5D34
+:1000C0007804037D79042C7D367C79041F7CEE5600
+:1000D000000F6006057D0965437E0A62417E209817
+:1000E0000A623E7E09653C7E12051205AD0260077C
+:1000F000037DFB55D36D2B98FB55041DD36DC86A4A
+:100100002F7F011F03200048E47C5398FB55D76DD7
+:10011000150005780962C86A0962C86AD76D5298E5
+:10012000FB55D76D1500150005780A62C86A0A628A
+:10013000C86AD76D5298FB55D76D1500150015008C
+:1001400005780B62C86A0B62C86AD76D097CDF6DDF
+:10015000077F0000EB55004D077DFAC1E357069875
+:100160000700CC680C6813C20AC20398D9C1E3C166
+:10017000DB57E35FE357F352216A8F00D500017D1F
+:100180008D00A005EB5DFB567804037D79042A7D84
+:10019000317C7904207C700B1103EB53000F60035A
+:1001A000057D0965377E0A62357E86980A62327E51
+:1001B0000965307E12051205AD026007027C065A01
+:1001C0008E98265A277F011F03200048E87C700B79
+:1001D00011031353AF98150004780962065A096297
+:1001E000265AAE981500150004780A62065A0A626B
+:1001F000265AAE9815001500150004780B62065AB1
+:100200000B62265A077C0000EB55004D067DFAC1B3
+:10021000E357699807000C6813C20AC26698700B0E
+:10022000110313536C07017CD9C1FB5E8A066B076F
+:10023000017CD9C1F35EDB59D3588F0110010F390E
+:100240008B003CC12B7DC05AC85B4EC1277C880304
+:100250008906E35CFF0D1105FF1DBC053E07004D3F
+:10026000187D700811007E07097D7D07027D2852E8
+:10027000E698F852DB54BC02CC02097C7C07027D74
+:100280002852EF98F852D354BC02CC02097D0004E6
+:10029000DD988B00C052C85359C1D67D0002CD985D
+:1002A000FF08BF007F07157D8804D500017D8D0004
+:1002B000A005EB5D8F0212021202FF3ADA05027C02
+:1002C0003E071899A402DD02027D3E0718995E07D9
+:1002D0001899EB559805EB5DF352FB546A07267DA0
+:1002E0006C07017D55996B07577C6907047D68078A
+:1002F000027D010E2F999358D600017D8E009355F3
+:10030000A005935DA00602780255045D1D7C004E99
+:10031000087C6907037D0255177E3C99045D147FB4
+:10032000890693500048017D2799A0991500067809
+:100330000255045D4F070255245D2F07017CA099EB
+:1003400017006F07017C012093559D000700A7D976
+:10035000F598D36C6907047D6807027D010E6499E6
+:100360009358D600017D8E009355A005935DA0069D
+:1003700002780255C86D0F7C004E087C6907037D2A
+:100380000255097E7199C86D067F89069350004811
+:10039000017D5C99A0999A99C36A6907047D6807F1
+:1003A000027D010E87999358D600017D8E009355EA
+:1003B000A005935DA0060278C865045D0F7C004E21
+:1003C000087C6907037DC865097E9499045D067FF2
+:1003D000890693500048017D7F99A09993559D000F
+:1003E0000700FF6CA7D9F5980000E354EB55004DCA
+:1003F000017CF598DD98E354EB55FF0A1102FF1AD2
+:100400007F07027CA005B4999D008C05BA05A00564
+:100410001002BA04AD0454040600E3C1DB57FB52DA
+:10042000C36AF352056A8F00D500017D8D00A005D7
+:10043000EB5D7804037D79042B7D1E7C7904337C8D
+:10044000EE56000FFB556007027DC36DD599041D64
+:10045000C36DC8623B7E6006027D10021202096A0B
+:10046000357F1202096A327F1202096A2F7F011F4B
+:1004700003200048E77C099AFB55C76D150015005D
+:1004800015000578C8620B6AC8620B6AC76D089AC6
+:10049000FB55C76D150015000578C8620A6AC86269
+:1004A0000A6AC76D089AFB55C76D15000578C862C2
+:1004B000096AC862096AC76D097C286A077F00005B
+:1004C000EB55004D057DFAC1DB57BF9977C2540447
+:1004D0000AC2BA99D9C1E3C1DB57F352056A8F004A
+:1004E000D500017D8D00A005FB567804037D7904BD
+:1004F000297D1F7C79042E7CE35D700D1105ED557F
+:10050000000F6007027D0652329A2652337E600544
+:10051000027D10021202096A2D7F1202096A2A7FE7
+:100520001202096A277F011F03200048EA7CE35575
+:100530005D9A150015001500047806520B6A2652C4
+:100540000B6A5C9A15001500047806520A6A265256
+:100550000A6A5C9A150004780652096A2652096AEA
+:10056000097C286A077F0000DB57004D057DFAC132
+:10057000DB571B9A77C254040AC2189AE3C1DB57AF
+:10058000F352056AFB568E02941AC36AC862690266
+:100590001D7D941EC36ED36EC8624802C86A94263D
+:1005A000C36E981EC36EC8629826C36E6002097C33
+:1005B000C8626E02247D096A1E7F0125004D257DDB
+:1005C0007D9A286A187F04627AC2B19AE36E8F001E
+:1005D000D805017D8D00A005C8626E02107D096AF4
+:1005E0000A7F0120F97C286A067F0000004D0D7DFE
+:1005F000FAC1DB576E9A070004620C6AAE9A286A49
+:10060000FA7F04627AC258045404286AF47F0AC24A
+:020610006B9AE3
:00000001FF
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 0fd119586716..f31ce0bf42c9 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -1047,6 +1047,8 @@ void __mark_inode_dirty(struct inode *inode, int flags)
*/
if (!was_dirty) {
bdi = inode_to_bdi(inode);
+ if (!bdi)
+ goto out;
if (bdi_cap_writeback_dirty(bdi)) {
WARN(!test_bit(BDI_registered, &bdi->state),
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index cb2bcc1a47c0..cc1d8574dc7f 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -119,6 +119,7 @@ struct fsl_usb2_platform_data {
enum usb_wakeup_event (*is_wakeup_event)(struct fsl_usb2_platform_data *);
void (*wakeup_handler)(struct fsl_usb2_platform_data *);
void (*hsic_post_ops)(void);
+ void (*gadget_discharge_dp) (bool);
struct fsl_usb2_wakeup_platform_data *wakeup_pdata;
struct platform_device *pdev;
@@ -253,6 +254,7 @@ struct fsl_mxc_camera_platform_data {
u32 mclk;
u32 csi;
void (*pwdn)(int pwdn);
+ void (*io_init)(void);
};
struct mpc8xx_pcmcia_ops {
@@ -363,6 +365,8 @@ struct mxs_perfmon_bit_config {
struct mxs_platform_perfmon_data {
struct mxs_perfmon_bit_config *bit_config_tab;
int bit_config_cnt;
+ void (*plt_init) (void);
+ void (*plt_exit) (void);
};
#endif /* _FSL_DEVICE_H_ */
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig
index f3788b5bc9fb..bff6b667a7b1 100644
--- a/sound/soc/imx/Kconfig
+++ b/sound/soc/imx/Kconfig
@@ -57,7 +57,7 @@ config SND_SOC_IMX_SGTL5000
config SND_SOC_IMX_CS42888
tristate "SoC Audio support for i.MX boards with cs42888"
- depends on I2C && (MACH_MX6Q_ARM2 || MACH_MX53_ARD)
+ depends on I2C && (MACH_MX6Q_ARM2 || MACH_MX6Q_SABREAUTO || MACH_MX53_ARD)
select SND_SOC_CS42888
select SND_MXC_SOC_MX2
help