162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Renesas - AP-325RXA 462306a36Sopenharmony_ci * (Compatible with Algo System ., LTD. - AP-320A) 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Copyright (C) 2008 Renesas Solutions Corp. 762306a36Sopenharmony_ci * Author : Yusuke Goda <goda.yuske@renesas.com> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci#include <asm/clock.h> 1162306a36Sopenharmony_ci#include <asm/io.h> 1262306a36Sopenharmony_ci#include <asm/suspend.h> 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <cpu/sh7723.h> 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include <linux/dma-map-ops.h> 1762306a36Sopenharmony_ci#include <linux/clkdev.h> 1862306a36Sopenharmony_ci#include <linux/delay.h> 1962306a36Sopenharmony_ci#include <linux/device.h> 2062306a36Sopenharmony_ci#include <linux/gpio.h> 2162306a36Sopenharmony_ci#include <linux/gpio/consumer.h> 2262306a36Sopenharmony_ci#include <linux/gpio/machine.h> 2362306a36Sopenharmony_ci#include <linux/i2c.h> 2462306a36Sopenharmony_ci#include <linux/init.h> 2562306a36Sopenharmony_ci#include <linux/interrupt.h> 2662306a36Sopenharmony_ci#include <linux/memblock.h> 2762306a36Sopenharmony_ci#include <linux/mfd/tmio.h> 2862306a36Sopenharmony_ci#include <linux/mmc/host.h> 2962306a36Sopenharmony_ci#include <linux/mtd/physmap.h> 3062306a36Sopenharmony_ci#include <linux/mtd/sh_flctl.h> 3162306a36Sopenharmony_ci#include <linux/platform_device.h> 3262306a36Sopenharmony_ci#include <linux/regulator/fixed.h> 3362306a36Sopenharmony_ci#include <linux/regulator/machine.h> 3462306a36Sopenharmony_ci#include <linux/sh_intc.h> 3562306a36Sopenharmony_ci#include <linux/smsc911x.h> 3662306a36Sopenharmony_ci#include <linux/videodev2.h> 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci#include <media/drv-intf/renesas-ceu.h> 3962306a36Sopenharmony_ci#include <media/i2c/ov772x.h> 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci#include <video/sh_mobile_lcdc.h> 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#define CEU_BUFFER_MEMORY_SIZE (4 << 20) 4462306a36Sopenharmony_cistatic phys_addr_t ceu_dma_membase; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci/* Dummy supplies, where voltage doesn't matter */ 4762306a36Sopenharmony_cistatic struct regulator_consumer_supply dummy_supplies[] = { 4862306a36Sopenharmony_ci REGULATOR_SUPPLY("vddvario", "smsc911x"), 4962306a36Sopenharmony_ci REGULATOR_SUPPLY("vdd33a", "smsc911x"), 5062306a36Sopenharmony_ci}; 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_cistatic struct smsc911x_platform_config smsc911x_config = { 5362306a36Sopenharmony_ci .phy_interface = PHY_INTERFACE_MODE_MII, 5462306a36Sopenharmony_ci .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, 5562306a36Sopenharmony_ci .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, 5662306a36Sopenharmony_ci .flags = SMSC911X_USE_32BIT, 5762306a36Sopenharmony_ci}; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistatic struct resource smsc9118_resources[] = { 6062306a36Sopenharmony_ci [0] = { 6162306a36Sopenharmony_ci .start = 0xb6080000, 6262306a36Sopenharmony_ci .end = 0xb60fffff, 6362306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 6462306a36Sopenharmony_ci }, 6562306a36Sopenharmony_ci [1] = { 6662306a36Sopenharmony_ci .start = evt2irq(0x660), 6762306a36Sopenharmony_ci .end = evt2irq(0x660), 6862306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 6962306a36Sopenharmony_ci } 7062306a36Sopenharmony_ci}; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_cistatic struct platform_device smsc9118_device = { 7362306a36Sopenharmony_ci .name = "smsc911x", 7462306a36Sopenharmony_ci .id = -1, 7562306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(smsc9118_resources), 7662306a36Sopenharmony_ci .resource = smsc9118_resources, 7762306a36Sopenharmony_ci .dev = { 7862306a36Sopenharmony_ci .platform_data = &smsc911x_config, 7962306a36Sopenharmony_ci }, 8062306a36Sopenharmony_ci}; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci/* 8362306a36Sopenharmony_ci * AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF). 8462306a36Sopenharmony_ci * If this area erased, this board can not boot. 8562306a36Sopenharmony_ci */ 8662306a36Sopenharmony_cistatic struct mtd_partition ap325rxa_nor_flash_partitions[] = { 8762306a36Sopenharmony_ci { 8862306a36Sopenharmony_ci .name = "uboot", 8962306a36Sopenharmony_ci .offset = 0, 9062306a36Sopenharmony_ci .size = (1 * 1024 * 1024), 9162306a36Sopenharmony_ci .mask_flags = MTD_WRITEABLE, /* Read-only */ 9262306a36Sopenharmony_ci }, { 9362306a36Sopenharmony_ci .name = "kernel", 9462306a36Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 9562306a36Sopenharmony_ci .size = (2 * 1024 * 1024), 9662306a36Sopenharmony_ci }, { 9762306a36Sopenharmony_ci .name = "free-area0", 9862306a36Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 9962306a36Sopenharmony_ci .size = ((7 * 1024 * 1024) + (512 * 1024)), 10062306a36Sopenharmony_ci }, { 10162306a36Sopenharmony_ci .name = "CPLD-Data", 10262306a36Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 10362306a36Sopenharmony_ci .mask_flags = MTD_WRITEABLE, /* Read-only */ 10462306a36Sopenharmony_ci .size = (1024 * 128 * 2), 10562306a36Sopenharmony_ci }, { 10662306a36Sopenharmony_ci .name = "free-area1", 10762306a36Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 10862306a36Sopenharmony_ci .size = MTDPART_SIZ_FULL, 10962306a36Sopenharmony_ci }, 11062306a36Sopenharmony_ci}; 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_cistatic struct physmap_flash_data ap325rxa_nor_flash_data = { 11362306a36Sopenharmony_ci .width = 2, 11462306a36Sopenharmony_ci .parts = ap325rxa_nor_flash_partitions, 11562306a36Sopenharmony_ci .nr_parts = ARRAY_SIZE(ap325rxa_nor_flash_partitions), 11662306a36Sopenharmony_ci}; 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_cistatic struct resource ap325rxa_nor_flash_resources[] = { 11962306a36Sopenharmony_ci [0] = { 12062306a36Sopenharmony_ci .name = "NOR Flash", 12162306a36Sopenharmony_ci .start = 0x00000000, 12262306a36Sopenharmony_ci .end = 0x00ffffff, 12362306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 12462306a36Sopenharmony_ci } 12562306a36Sopenharmony_ci}; 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_cistatic struct platform_device ap325rxa_nor_flash_device = { 12862306a36Sopenharmony_ci .name = "physmap-flash", 12962306a36Sopenharmony_ci .resource = ap325rxa_nor_flash_resources, 13062306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(ap325rxa_nor_flash_resources), 13162306a36Sopenharmony_ci .dev = { 13262306a36Sopenharmony_ci .platform_data = &ap325rxa_nor_flash_data, 13362306a36Sopenharmony_ci }, 13462306a36Sopenharmony_ci}; 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_cistatic struct mtd_partition nand_partition_info[] = { 13762306a36Sopenharmony_ci { 13862306a36Sopenharmony_ci .name = "nand_data", 13962306a36Sopenharmony_ci .offset = 0, 14062306a36Sopenharmony_ci .size = MTDPART_SIZ_FULL, 14162306a36Sopenharmony_ci }, 14262306a36Sopenharmony_ci}; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_cistatic struct resource nand_flash_resources[] = { 14562306a36Sopenharmony_ci [0] = { 14662306a36Sopenharmony_ci .start = 0xa4530000, 14762306a36Sopenharmony_ci .end = 0xa45300ff, 14862306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 14962306a36Sopenharmony_ci } 15062306a36Sopenharmony_ci}; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_cistatic struct sh_flctl_platform_data nand_flash_data = { 15362306a36Sopenharmony_ci .parts = nand_partition_info, 15462306a36Sopenharmony_ci .nr_parts = ARRAY_SIZE(nand_partition_info), 15562306a36Sopenharmony_ci .flcmncr_val = FCKSEL_E | TYPESEL_SET | NANWF_E, 15662306a36Sopenharmony_ci .has_hwecc = 1, 15762306a36Sopenharmony_ci}; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_cistatic struct platform_device nand_flash_device = { 16062306a36Sopenharmony_ci .name = "sh_flctl", 16162306a36Sopenharmony_ci .resource = nand_flash_resources, 16262306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(nand_flash_resources), 16362306a36Sopenharmony_ci .dev = { 16462306a36Sopenharmony_ci .platform_data = &nand_flash_data, 16562306a36Sopenharmony_ci }, 16662306a36Sopenharmony_ci}; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci#define FPGA_LCDREG 0xB4100180 16962306a36Sopenharmony_ci#define FPGA_BKLREG 0xB4100212 17062306a36Sopenharmony_ci#define FPGA_LCDREG_VAL 0x0018 17162306a36Sopenharmony_ci#define PORT_MSELCRB 0xA4050182 17262306a36Sopenharmony_ci#define PORT_HIZCRC 0xA405015C 17362306a36Sopenharmony_ci#define PORT_DRVCRA 0xA405018A 17462306a36Sopenharmony_ci#define PORT_DRVCRB 0xA405018C 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_cistatic int ap320_wvga_set_brightness(int brightness) 17762306a36Sopenharmony_ci{ 17862306a36Sopenharmony_ci if (brightness) { 17962306a36Sopenharmony_ci gpio_set_value(GPIO_PTS3, 0); 18062306a36Sopenharmony_ci __raw_writew(0x100, FPGA_BKLREG); 18162306a36Sopenharmony_ci } else { 18262306a36Sopenharmony_ci __raw_writew(0, FPGA_BKLREG); 18362306a36Sopenharmony_ci gpio_set_value(GPIO_PTS3, 1); 18462306a36Sopenharmony_ci } 18562306a36Sopenharmony_ci 18662306a36Sopenharmony_ci return 0; 18762306a36Sopenharmony_ci} 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_cistatic void ap320_wvga_power_on(void) 19062306a36Sopenharmony_ci{ 19162306a36Sopenharmony_ci msleep(100); 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci /* ASD AP-320/325 LCD ON */ 19462306a36Sopenharmony_ci __raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG); 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic void ap320_wvga_power_off(void) 19862306a36Sopenharmony_ci{ 19962306a36Sopenharmony_ci /* ASD AP-320/325 LCD OFF */ 20062306a36Sopenharmony_ci __raw_writew(0, FPGA_LCDREG); 20162306a36Sopenharmony_ci} 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_cistatic const struct fb_videomode ap325rxa_lcdc_modes[] = { 20462306a36Sopenharmony_ci { 20562306a36Sopenharmony_ci .name = "LB070WV1", 20662306a36Sopenharmony_ci .xres = 800, 20762306a36Sopenharmony_ci .yres = 480, 20862306a36Sopenharmony_ci .left_margin = 32, 20962306a36Sopenharmony_ci .right_margin = 160, 21062306a36Sopenharmony_ci .hsync_len = 8, 21162306a36Sopenharmony_ci .upper_margin = 63, 21262306a36Sopenharmony_ci .lower_margin = 80, 21362306a36Sopenharmony_ci .vsync_len = 1, 21462306a36Sopenharmony_ci .sync = 0, /* hsync and vsync are active low */ 21562306a36Sopenharmony_ci }, 21662306a36Sopenharmony_ci}; 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_cistatic struct sh_mobile_lcdc_info lcdc_info = { 21962306a36Sopenharmony_ci .clock_source = LCDC_CLK_EXTERNAL, 22062306a36Sopenharmony_ci .ch[0] = { 22162306a36Sopenharmony_ci .chan = LCDC_CHAN_MAINLCD, 22262306a36Sopenharmony_ci .fourcc = V4L2_PIX_FMT_RGB565, 22362306a36Sopenharmony_ci .interface_type = RGB18, 22462306a36Sopenharmony_ci .clock_divider = 1, 22562306a36Sopenharmony_ci .lcd_modes = ap325rxa_lcdc_modes, 22662306a36Sopenharmony_ci .num_modes = ARRAY_SIZE(ap325rxa_lcdc_modes), 22762306a36Sopenharmony_ci .panel_cfg = { 22862306a36Sopenharmony_ci .width = 152, /* 7.0 inch */ 22962306a36Sopenharmony_ci .height = 91, 23062306a36Sopenharmony_ci .display_on = ap320_wvga_power_on, 23162306a36Sopenharmony_ci .display_off = ap320_wvga_power_off, 23262306a36Sopenharmony_ci }, 23362306a36Sopenharmony_ci .bl_info = { 23462306a36Sopenharmony_ci .name = "sh_mobile_lcdc_bl", 23562306a36Sopenharmony_ci .max_brightness = 1, 23662306a36Sopenharmony_ci .set_brightness = ap320_wvga_set_brightness, 23762306a36Sopenharmony_ci }, 23862306a36Sopenharmony_ci } 23962306a36Sopenharmony_ci}; 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_cistatic struct resource lcdc_resources[] = { 24262306a36Sopenharmony_ci [0] = { 24362306a36Sopenharmony_ci .name = "LCDC", 24462306a36Sopenharmony_ci .start = 0xfe940000, /* P4-only space */ 24562306a36Sopenharmony_ci .end = 0xfe942fff, 24662306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 24762306a36Sopenharmony_ci }, 24862306a36Sopenharmony_ci [1] = { 24962306a36Sopenharmony_ci .start = evt2irq(0x580), 25062306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 25162306a36Sopenharmony_ci }, 25262306a36Sopenharmony_ci}; 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_cistatic struct platform_device lcdc_device = { 25562306a36Sopenharmony_ci .name = "sh_mobile_lcdc_fb", 25662306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(lcdc_resources), 25762306a36Sopenharmony_ci .resource = lcdc_resources, 25862306a36Sopenharmony_ci .dev = { 25962306a36Sopenharmony_ci .platform_data = &lcdc_info, 26062306a36Sopenharmony_ci }, 26162306a36Sopenharmony_ci}; 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci/* Powerdown/reset gpios for CEU image sensors */ 26462306a36Sopenharmony_cistatic struct gpiod_lookup_table ov7725_gpios = { 26562306a36Sopenharmony_ci .dev_id = "0-0021", 26662306a36Sopenharmony_ci .table = { 26762306a36Sopenharmony_ci GPIO_LOOKUP("sh7723_pfc", GPIO_PTZ5, "reset", GPIO_ACTIVE_LOW), 26862306a36Sopenharmony_ci }, 26962306a36Sopenharmony_ci}; 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_cistatic struct ceu_platform_data ceu0_pdata = { 27262306a36Sopenharmony_ci .num_subdevs = 1, 27362306a36Sopenharmony_ci .subdevs = { 27462306a36Sopenharmony_ci { /* [0] = ov7725 */ 27562306a36Sopenharmony_ci .flags = 0, 27662306a36Sopenharmony_ci .bus_width = 8, 27762306a36Sopenharmony_ci .bus_shift = 0, 27862306a36Sopenharmony_ci .i2c_adapter_id = 0, 27962306a36Sopenharmony_ci .i2c_address = 0x21, 28062306a36Sopenharmony_ci }, 28162306a36Sopenharmony_ci }, 28262306a36Sopenharmony_ci}; 28362306a36Sopenharmony_ci 28462306a36Sopenharmony_cistatic struct resource ceu_resources[] = { 28562306a36Sopenharmony_ci [0] = { 28662306a36Sopenharmony_ci .name = "CEU", 28762306a36Sopenharmony_ci .start = 0xfe910000, 28862306a36Sopenharmony_ci .end = 0xfe91009f, 28962306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 29062306a36Sopenharmony_ci }, 29162306a36Sopenharmony_ci [1] = { 29262306a36Sopenharmony_ci .start = evt2irq(0x880), 29362306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 29462306a36Sopenharmony_ci }, 29562306a36Sopenharmony_ci}; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_cistatic struct platform_device ap325rxa_ceu_device = { 29862306a36Sopenharmony_ci .name = "renesas-ceu", 29962306a36Sopenharmony_ci .id = 0, /* "ceu.0" clock */ 30062306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(ceu_resources), 30162306a36Sopenharmony_ci .resource = ceu_resources, 30262306a36Sopenharmony_ci .dev = { 30362306a36Sopenharmony_ci .platform_data = &ceu0_pdata, 30462306a36Sopenharmony_ci }, 30562306a36Sopenharmony_ci}; 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci/* Fixed 3.3V regulators to be used by SDHI0, SDHI1 */ 30862306a36Sopenharmony_cistatic struct regulator_consumer_supply fixed3v3_power_consumers[] = 30962306a36Sopenharmony_ci{ 31062306a36Sopenharmony_ci REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), 31162306a36Sopenharmony_ci REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), 31262306a36Sopenharmony_ci REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), 31362306a36Sopenharmony_ci REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), 31462306a36Sopenharmony_ci}; 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_cistatic struct resource sdhi0_cn3_resources[] = { 31762306a36Sopenharmony_ci [0] = { 31862306a36Sopenharmony_ci .name = "SDHI0", 31962306a36Sopenharmony_ci .start = 0x04ce0000, 32062306a36Sopenharmony_ci .end = 0x04ce00ff, 32162306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 32262306a36Sopenharmony_ci }, 32362306a36Sopenharmony_ci [1] = { 32462306a36Sopenharmony_ci .start = evt2irq(0xe80), 32562306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 32662306a36Sopenharmony_ci }, 32762306a36Sopenharmony_ci}; 32862306a36Sopenharmony_ci 32962306a36Sopenharmony_cistatic struct tmio_mmc_data sdhi0_cn3_data = { 33062306a36Sopenharmony_ci .capabilities = MMC_CAP_SDIO_IRQ, 33162306a36Sopenharmony_ci}; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_cistatic struct platform_device sdhi0_cn3_device = { 33462306a36Sopenharmony_ci .name = "sh_mobile_sdhi", 33562306a36Sopenharmony_ci .id = 0, /* "sdhi0" clock */ 33662306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(sdhi0_cn3_resources), 33762306a36Sopenharmony_ci .resource = sdhi0_cn3_resources, 33862306a36Sopenharmony_ci .dev = { 33962306a36Sopenharmony_ci .platform_data = &sdhi0_cn3_data, 34062306a36Sopenharmony_ci }, 34162306a36Sopenharmony_ci}; 34262306a36Sopenharmony_ci 34362306a36Sopenharmony_cistatic struct resource sdhi1_cn7_resources[] = { 34462306a36Sopenharmony_ci [0] = { 34562306a36Sopenharmony_ci .name = "SDHI1", 34662306a36Sopenharmony_ci .start = 0x04cf0000, 34762306a36Sopenharmony_ci .end = 0x04cf00ff, 34862306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 34962306a36Sopenharmony_ci }, 35062306a36Sopenharmony_ci [1] = { 35162306a36Sopenharmony_ci .start = evt2irq(0x4e0), 35262306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 35362306a36Sopenharmony_ci }, 35462306a36Sopenharmony_ci}; 35562306a36Sopenharmony_ci 35662306a36Sopenharmony_cistatic struct tmio_mmc_data sdhi1_cn7_data = { 35762306a36Sopenharmony_ci .capabilities = MMC_CAP_SDIO_IRQ, 35862306a36Sopenharmony_ci}; 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_cistatic struct platform_device sdhi1_cn7_device = { 36162306a36Sopenharmony_ci .name = "sh_mobile_sdhi", 36262306a36Sopenharmony_ci .id = 1, /* "sdhi1" clock */ 36362306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(sdhi1_cn7_resources), 36462306a36Sopenharmony_ci .resource = sdhi1_cn7_resources, 36562306a36Sopenharmony_ci .dev = { 36662306a36Sopenharmony_ci .platform_data = &sdhi1_cn7_data, 36762306a36Sopenharmony_ci }, 36862306a36Sopenharmony_ci}; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_cistatic struct ov772x_camera_info ov7725_info = { 37162306a36Sopenharmony_ci .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP, 37262306a36Sopenharmony_ci .edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0), 37362306a36Sopenharmony_ci}; 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_cistatic struct i2c_board_info ap325rxa_i2c_devices[] __initdata = { 37662306a36Sopenharmony_ci { 37762306a36Sopenharmony_ci I2C_BOARD_INFO("pcf8563", 0x51), 37862306a36Sopenharmony_ci }, 37962306a36Sopenharmony_ci { 38062306a36Sopenharmony_ci I2C_BOARD_INFO("ov772x", 0x21), 38162306a36Sopenharmony_ci .platform_data = &ov7725_info, 38262306a36Sopenharmony_ci }, 38362306a36Sopenharmony_ci}; 38462306a36Sopenharmony_ci 38562306a36Sopenharmony_cistatic struct platform_device *ap325rxa_devices[] __initdata = { 38662306a36Sopenharmony_ci &smsc9118_device, 38762306a36Sopenharmony_ci &ap325rxa_nor_flash_device, 38862306a36Sopenharmony_ci &lcdc_device, 38962306a36Sopenharmony_ci &nand_flash_device, 39062306a36Sopenharmony_ci &sdhi0_cn3_device, 39162306a36Sopenharmony_ci &sdhi1_cn7_device, 39262306a36Sopenharmony_ci}; 39362306a36Sopenharmony_ci 39462306a36Sopenharmony_ciextern char ap325rxa_sdram_enter_start; 39562306a36Sopenharmony_ciextern char ap325rxa_sdram_enter_end; 39662306a36Sopenharmony_ciextern char ap325rxa_sdram_leave_start; 39762306a36Sopenharmony_ciextern char ap325rxa_sdram_leave_end; 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_cistatic int __init ap325rxa_devices_setup(void) 40062306a36Sopenharmony_ci{ 40162306a36Sopenharmony_ci /* register board specific self-refresh code */ 40262306a36Sopenharmony_ci sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF, 40362306a36Sopenharmony_ci &ap325rxa_sdram_enter_start, 40462306a36Sopenharmony_ci &ap325rxa_sdram_enter_end, 40562306a36Sopenharmony_ci &ap325rxa_sdram_leave_start, 40662306a36Sopenharmony_ci &ap325rxa_sdram_leave_end); 40762306a36Sopenharmony_ci 40862306a36Sopenharmony_ci regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, 40962306a36Sopenharmony_ci ARRAY_SIZE(fixed3v3_power_consumers), 3300000); 41062306a36Sopenharmony_ci regulator_register_fixed(1, dummy_supplies, ARRAY_SIZE(dummy_supplies)); 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci /* LD3 and LD4 LEDs */ 41362306a36Sopenharmony_ci gpio_request(GPIO_PTX5, NULL); /* RUN */ 41462306a36Sopenharmony_ci gpio_direction_output(GPIO_PTX5, 1); 41562306a36Sopenharmony_ci gpiod_export(gpio_to_desc(GPIO_PTX5), 0); 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci gpio_request(GPIO_PTX4, NULL); /* INDICATOR */ 41862306a36Sopenharmony_ci gpio_direction_output(GPIO_PTX4, 0); 41962306a36Sopenharmony_ci gpiod_export(gpio_to_desc(GPIO_PTX4), 0); 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci /* SW1 input */ 42262306a36Sopenharmony_ci gpio_request(GPIO_PTF7, NULL); /* MODE */ 42362306a36Sopenharmony_ci gpio_direction_input(GPIO_PTF7); 42462306a36Sopenharmony_ci gpiod_export(gpio_to_desc(GPIO_PTF7), 0); 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci /* LCDC */ 42762306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD15, NULL); 42862306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD14, NULL); 42962306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD13, NULL); 43062306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD12, NULL); 43162306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD11, NULL); 43262306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD10, NULL); 43362306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD9, NULL); 43462306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD8, NULL); 43562306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD7, NULL); 43662306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD6, NULL); 43762306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD5, NULL); 43862306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD4, NULL); 43962306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD3, NULL); 44062306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD2, NULL); 44162306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD1, NULL); 44262306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDD0, NULL); 44362306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDLCLK_PTR, NULL); 44462306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDDCK, NULL); 44562306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDVEPWC, NULL); 44662306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDVCPWC, NULL); 44762306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDVSYN, NULL); 44862306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDHSYN, NULL); 44962306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDDISP, NULL); 45062306a36Sopenharmony_ci gpio_request(GPIO_FN_LCDDON, NULL); 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci /* LCD backlight */ 45362306a36Sopenharmony_ci gpio_request(GPIO_PTS3, NULL); 45462306a36Sopenharmony_ci gpio_direction_output(GPIO_PTS3, 1); 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci /* CEU */ 45762306a36Sopenharmony_ci gpio_request(GPIO_FN_VIO_CLK2, NULL); 45862306a36Sopenharmony_ci gpio_request(GPIO_FN_VIO_VD2, NULL); 45962306a36Sopenharmony_ci gpio_request(GPIO_FN_VIO_HD2, NULL); 46062306a36Sopenharmony_ci gpio_request(GPIO_FN_VIO_FLD, NULL); 46162306a36Sopenharmony_ci gpio_request(GPIO_FN_VIO_CKO, NULL); 46262306a36Sopenharmony_ci gpio_request(GPIO_FN_VIO_D15, NULL); 46362306a36Sopenharmony_ci gpio_request(GPIO_FN_VIO_D14, NULL); 46462306a36Sopenharmony_ci gpio_request(GPIO_FN_VIO_D13, NULL); 46562306a36Sopenharmony_ci gpio_request(GPIO_FN_VIO_D12, NULL); 46662306a36Sopenharmony_ci gpio_request(GPIO_FN_VIO_D11, NULL); 46762306a36Sopenharmony_ci gpio_request(GPIO_FN_VIO_D10, NULL); 46862306a36Sopenharmony_ci gpio_request(GPIO_FN_VIO_D9, NULL); 46962306a36Sopenharmony_ci gpio_request(GPIO_FN_VIO_D8, NULL); 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_ci gpio_request(GPIO_PTZ7, NULL); 47262306a36Sopenharmony_ci gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */ 47362306a36Sopenharmony_ci gpio_request(GPIO_PTZ6, NULL); 47462306a36Sopenharmony_ci gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */ 47562306a36Sopenharmony_ci gpio_request(GPIO_PTZ5, NULL); 47662306a36Sopenharmony_ci gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */ 47762306a36Sopenharmony_ci gpio_request(GPIO_PTZ4, NULL); 47862306a36Sopenharmony_ci gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */ 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci __raw_writew(__raw_readw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB); 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_ci /* FLCTL */ 48362306a36Sopenharmony_ci gpio_request(GPIO_FN_FCE, NULL); 48462306a36Sopenharmony_ci gpio_request(GPIO_FN_NAF7, NULL); 48562306a36Sopenharmony_ci gpio_request(GPIO_FN_NAF6, NULL); 48662306a36Sopenharmony_ci gpio_request(GPIO_FN_NAF5, NULL); 48762306a36Sopenharmony_ci gpio_request(GPIO_FN_NAF4, NULL); 48862306a36Sopenharmony_ci gpio_request(GPIO_FN_NAF3, NULL); 48962306a36Sopenharmony_ci gpio_request(GPIO_FN_NAF2, NULL); 49062306a36Sopenharmony_ci gpio_request(GPIO_FN_NAF1, NULL); 49162306a36Sopenharmony_ci gpio_request(GPIO_FN_NAF0, NULL); 49262306a36Sopenharmony_ci gpio_request(GPIO_FN_FCDE, NULL); 49362306a36Sopenharmony_ci gpio_request(GPIO_FN_FOE, NULL); 49462306a36Sopenharmony_ci gpio_request(GPIO_FN_FSC, NULL); 49562306a36Sopenharmony_ci gpio_request(GPIO_FN_FWE, NULL); 49662306a36Sopenharmony_ci gpio_request(GPIO_FN_FRB, NULL); 49762306a36Sopenharmony_ci 49862306a36Sopenharmony_ci __raw_writew(0, PORT_HIZCRC); 49962306a36Sopenharmony_ci __raw_writew(0xFFFF, PORT_DRVCRA); 50062306a36Sopenharmony_ci __raw_writew(0xFFFF, PORT_DRVCRB); 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci /* SDHI0 - CN3 - SD CARD */ 50362306a36Sopenharmony_ci gpio_request(GPIO_FN_SDHI0CD_PTD, NULL); 50462306a36Sopenharmony_ci gpio_request(GPIO_FN_SDHI0WP_PTD, NULL); 50562306a36Sopenharmony_ci gpio_request(GPIO_FN_SDHI0D3_PTD, NULL); 50662306a36Sopenharmony_ci gpio_request(GPIO_FN_SDHI0D2_PTD, NULL); 50762306a36Sopenharmony_ci gpio_request(GPIO_FN_SDHI0D1_PTD, NULL); 50862306a36Sopenharmony_ci gpio_request(GPIO_FN_SDHI0D0_PTD, NULL); 50962306a36Sopenharmony_ci gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL); 51062306a36Sopenharmony_ci gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL); 51162306a36Sopenharmony_ci 51262306a36Sopenharmony_ci /* SDHI1 - CN7 - MICRO SD CARD */ 51362306a36Sopenharmony_ci gpio_request(GPIO_FN_SDHI1CD, NULL); 51462306a36Sopenharmony_ci gpio_request(GPIO_FN_SDHI1D3, NULL); 51562306a36Sopenharmony_ci gpio_request(GPIO_FN_SDHI1D2, NULL); 51662306a36Sopenharmony_ci gpio_request(GPIO_FN_SDHI1D1, NULL); 51762306a36Sopenharmony_ci gpio_request(GPIO_FN_SDHI1D0, NULL); 51862306a36Sopenharmony_ci gpio_request(GPIO_FN_SDHI1CMD, NULL); 51962306a36Sopenharmony_ci gpio_request(GPIO_FN_SDHI1CLK, NULL); 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci /* Add a clock alias for ov7725 xclk source. */ 52262306a36Sopenharmony_ci clk_add_alias(NULL, "0-0021", "video_clk", NULL); 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci /* Register RSTB gpio for ov7725 camera sensor. */ 52562306a36Sopenharmony_ci gpiod_add_lookup_table(&ov7725_gpios); 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci i2c_register_board_info(0, ap325rxa_i2c_devices, 52862306a36Sopenharmony_ci ARRAY_SIZE(ap325rxa_i2c_devices)); 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_ci /* Initialize CEU platform device separately to map memory first */ 53162306a36Sopenharmony_ci device_initialize(&ap325rxa_ceu_device.dev); 53262306a36Sopenharmony_ci dma_declare_coherent_memory(&ap325rxa_ceu_device.dev, 53362306a36Sopenharmony_ci ceu_dma_membase, ceu_dma_membase, 53462306a36Sopenharmony_ci CEU_BUFFER_MEMORY_SIZE); 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_ci platform_device_add(&ap325rxa_ceu_device); 53762306a36Sopenharmony_ci 53862306a36Sopenharmony_ci return platform_add_devices(ap325rxa_devices, 53962306a36Sopenharmony_ci ARRAY_SIZE(ap325rxa_devices)); 54062306a36Sopenharmony_ci} 54162306a36Sopenharmony_ciarch_initcall(ap325rxa_devices_setup); 54262306a36Sopenharmony_ci 54362306a36Sopenharmony_ci/* Return the board specific boot mode pin configuration */ 54462306a36Sopenharmony_cistatic int ap325rxa_mode_pins(void) 54562306a36Sopenharmony_ci{ 54662306a36Sopenharmony_ci /* MD0=0, MD1=0, MD2=0: Clock Mode 0 54762306a36Sopenharmony_ci * MD3=0: 16-bit Area0 Bus Width 54862306a36Sopenharmony_ci * MD5=1: Little Endian 54962306a36Sopenharmony_ci * TSTMD=1, MD8=1: Test Mode Disabled 55062306a36Sopenharmony_ci */ 55162306a36Sopenharmony_ci return MODE_PIN5 | MODE_PIN8; 55262306a36Sopenharmony_ci} 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_ci/* Reserve a portion of memory for CEU buffers */ 55562306a36Sopenharmony_cistatic void __init ap325rxa_mv_mem_reserve(void) 55662306a36Sopenharmony_ci{ 55762306a36Sopenharmony_ci phys_addr_t phys; 55862306a36Sopenharmony_ci phys_addr_t size = CEU_BUFFER_MEMORY_SIZE; 55962306a36Sopenharmony_ci 56062306a36Sopenharmony_ci phys = memblock_phys_alloc(size, PAGE_SIZE); 56162306a36Sopenharmony_ci if (!phys) 56262306a36Sopenharmony_ci panic("Failed to allocate CEU memory\n"); 56362306a36Sopenharmony_ci 56462306a36Sopenharmony_ci memblock_phys_free(phys, size); 56562306a36Sopenharmony_ci memblock_remove(phys, size); 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_ci ceu_dma_membase = phys; 56862306a36Sopenharmony_ci} 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_cistatic struct sh_machine_vector mv_ap325rxa __initmv = { 57162306a36Sopenharmony_ci .mv_name = "AP-325RXA", 57262306a36Sopenharmony_ci .mv_mode_pins = ap325rxa_mode_pins, 57362306a36Sopenharmony_ci .mv_mem_reserve = ap325rxa_mv_mem_reserve, 57462306a36Sopenharmony_ci}; 575