Path: blob/master/arch/sh/boards/mach-ap325rxa/setup.c
15126 views
/*1* Renesas - AP-325RXA2* (Compatible with Algo System ., LTD. - AP-320A)3*4* Copyright (C) 2008 Renesas Solutions Corp.5* Author : Yusuke Goda <[email protected]>6*7* This file is subject to the terms and conditions of the GNU General Public8* License. See the file "COPYING" in the main directory of this archive9* for more details.10*/1112#include <linux/init.h>13#include <linux/device.h>14#include <linux/interrupt.h>15#include <linux/platform_device.h>16#include <linux/mmc/host.h>17#include <linux/mmc/sh_mobile_sdhi.h>18#include <linux/mtd/physmap.h>19#include <linux/mtd/sh_flctl.h>20#include <linux/delay.h>21#include <linux/i2c.h>22#include <linux/smsc911x.h>23#include <linux/gpio.h>24#include <media/ov772x.h>25#include <media/soc_camera.h>26#include <media/soc_camera_platform.h>27#include <media/sh_mobile_ceu.h>28#include <video/sh_mobile_lcdc.h>29#include <asm/io.h>30#include <asm/clock.h>31#include <asm/suspend.h>32#include <cpu/sh7723.h>3334static struct smsc911x_platform_config smsc911x_config = {35.phy_interface = PHY_INTERFACE_MODE_MII,36.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,37.irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,38.flags = SMSC911X_USE_32BIT,39};4041static struct resource smsc9118_resources[] = {42[0] = {43.start = 0xb6080000,44.end = 0xb60fffff,45.flags = IORESOURCE_MEM,46},47[1] = {48.start = 35,49.end = 35,50.flags = IORESOURCE_IRQ,51}52};5354static struct platform_device smsc9118_device = {55.name = "smsc911x",56.id = -1,57.num_resources = ARRAY_SIZE(smsc9118_resources),58.resource = smsc9118_resources,59.dev = {60.platform_data = &smsc911x_config,61},62};6364/*65* AP320 and AP325RXA has CPLD data in NOR Flash(0xA80000-0xABFFFF).66* If this area erased, this board can not boot.67*/68static struct mtd_partition ap325rxa_nor_flash_partitions[] = {69{70.name = "uboot",71.offset = 0,72.size = (1 * 1024 * 1024),73.mask_flags = MTD_WRITEABLE, /* Read-only */74}, {75.name = "kernel",76.offset = MTDPART_OFS_APPEND,77.size = (2 * 1024 * 1024),78}, {79.name = "free-area0",80.offset = MTDPART_OFS_APPEND,81.size = ((7 * 1024 * 1024) + (512 * 1024)),82}, {83.name = "CPLD-Data",84.offset = MTDPART_OFS_APPEND,85.mask_flags = MTD_WRITEABLE, /* Read-only */86.size = (1024 * 128 * 2),87}, {88.name = "free-area1",89.offset = MTDPART_OFS_APPEND,90.size = MTDPART_SIZ_FULL,91},92};9394static struct physmap_flash_data ap325rxa_nor_flash_data = {95.width = 2,96.parts = ap325rxa_nor_flash_partitions,97.nr_parts = ARRAY_SIZE(ap325rxa_nor_flash_partitions),98};99100static struct resource ap325rxa_nor_flash_resources[] = {101[0] = {102.name = "NOR Flash",103.start = 0x00000000,104.end = 0x00ffffff,105.flags = IORESOURCE_MEM,106}107};108109static struct platform_device ap325rxa_nor_flash_device = {110.name = "physmap-flash",111.resource = ap325rxa_nor_flash_resources,112.num_resources = ARRAY_SIZE(ap325rxa_nor_flash_resources),113.dev = {114.platform_data = &ap325rxa_nor_flash_data,115},116};117118static struct mtd_partition nand_partition_info[] = {119{120.name = "nand_data",121.offset = 0,122.size = MTDPART_SIZ_FULL,123},124};125126static struct resource nand_flash_resources[] = {127[0] = {128.start = 0xa4530000,129.end = 0xa45300ff,130.flags = IORESOURCE_MEM,131}132};133134static struct sh_flctl_platform_data nand_flash_data = {135.parts = nand_partition_info,136.nr_parts = ARRAY_SIZE(nand_partition_info),137.flcmncr_val = FCKSEL_E | TYPESEL_SET | NANWF_E,138.has_hwecc = 1,139};140141static struct platform_device nand_flash_device = {142.name = "sh_flctl",143.resource = nand_flash_resources,144.num_resources = ARRAY_SIZE(nand_flash_resources),145.dev = {146.platform_data = &nand_flash_data,147},148};149150#define FPGA_LCDREG 0xB4100180151#define FPGA_BKLREG 0xB4100212152#define FPGA_LCDREG_VAL 0x0018153#define PORT_MSELCRB 0xA4050182154#define PORT_HIZCRC 0xA405015C155#define PORT_DRVCRA 0xA405018A156#define PORT_DRVCRB 0xA405018C157158static int ap320_wvga_set_brightness(void *board_data, int brightness)159{160if (brightness) {161gpio_set_value(GPIO_PTS3, 0);162__raw_writew(0x100, FPGA_BKLREG);163} else {164__raw_writew(0, FPGA_BKLREG);165gpio_set_value(GPIO_PTS3, 1);166}167168return 0;169}170171static int ap320_wvga_get_brightness(void *board_data)172{173return gpio_get_value(GPIO_PTS3);174}175176static void ap320_wvga_power_on(void *board_data, struct fb_info *info)177{178msleep(100);179180/* ASD AP-320/325 LCD ON */181__raw_writew(FPGA_LCDREG_VAL, FPGA_LCDREG);182}183184static void ap320_wvga_power_off(void *board_data)185{186/* ASD AP-320/325 LCD OFF */187__raw_writew(0, FPGA_LCDREG);188}189190const static struct fb_videomode ap325rxa_lcdc_modes[] = {191{192.name = "LB070WV1",193.xres = 800,194.yres = 480,195.left_margin = 32,196.right_margin = 160,197.hsync_len = 8,198.upper_margin = 63,199.lower_margin = 80,200.vsync_len = 1,201.sync = 0, /* hsync and vsync are active low */202},203};204205static struct sh_mobile_lcdc_info lcdc_info = {206.clock_source = LCDC_CLK_EXTERNAL,207.ch[0] = {208.chan = LCDC_CHAN_MAINLCD,209.bpp = 16,210.interface_type = RGB18,211.clock_divider = 1,212.lcd_cfg = ap325rxa_lcdc_modes,213.num_cfg = ARRAY_SIZE(ap325rxa_lcdc_modes),214.lcd_size_cfg = { /* 7.0 inch */215.width = 152,216.height = 91,217},218.board_cfg = {219.display_on = ap320_wvga_power_on,220.display_off = ap320_wvga_power_off,221.set_brightness = ap320_wvga_set_brightness,222.get_brightness = ap320_wvga_get_brightness,223},224.bl_info = {225.name = "sh_mobile_lcdc_bl",226.max_brightness = 1,227},228}229};230231static struct resource lcdc_resources[] = {232[0] = {233.name = "LCDC",234.start = 0xfe940000, /* P4-only space */235.end = 0xfe942fff,236.flags = IORESOURCE_MEM,237},238[1] = {239.start = 28,240.flags = IORESOURCE_IRQ,241},242};243244static struct platform_device lcdc_device = {245.name = "sh_mobile_lcdc_fb",246.num_resources = ARRAY_SIZE(lcdc_resources),247.resource = lcdc_resources,248.dev = {249.platform_data = &lcdc_info,250},251.archdata = {252.hwblk_id = HWBLK_LCDC,253},254};255256static void camera_power(int val)257{258gpio_set_value(GPIO_PTZ5, val); /* RST_CAM/RSTB */259mdelay(10);260}261262#ifdef CONFIG_I2C263/* support for the old ncm03j camera */264static unsigned char camera_ncm03j_magic[] =265{2660x87, 0x00, 0x88, 0x08, 0x89, 0x01, 0x8A, 0xE8,2670x1D, 0x00, 0x1E, 0x8A, 0x21, 0x00, 0x33, 0x36,2680x36, 0x60, 0x37, 0x08, 0x3B, 0x31, 0x44, 0x0F,2690x46, 0xF0, 0x4B, 0x28, 0x4C, 0x21, 0x4D, 0x55,2700x4E, 0x1B, 0x4F, 0xC7, 0x50, 0xFC, 0x51, 0x12,2710x58, 0x02, 0x66, 0xC0, 0x67, 0x46, 0x6B, 0xA0,2720x6C, 0x34, 0x7E, 0x25, 0x7F, 0x25, 0x8D, 0x0F,2730x92, 0x40, 0x93, 0x04, 0x94, 0x26, 0x95, 0x0A,2740x99, 0x03, 0x9A, 0xF0, 0x9B, 0x14, 0x9D, 0x7A,2750xC5, 0x02, 0xD6, 0x07, 0x59, 0x00, 0x5A, 0x1A,2760x5B, 0x2A, 0x5C, 0x37, 0x5D, 0x42, 0x5E, 0x56,2770xC8, 0x00, 0xC9, 0x1A, 0xCA, 0x2A, 0xCB, 0x37,2780xCC, 0x42, 0xCD, 0x56, 0xCE, 0x00, 0xCF, 0x1A,2790xD0, 0x2A, 0xD1, 0x37, 0xD2, 0x42, 0xD3, 0x56,2800x5F, 0x68, 0x60, 0x87, 0x61, 0xA3, 0x62, 0xBC,2810x63, 0xD4, 0x64, 0xEA, 0xD6, 0x0F,282};283284static int camera_probe(void)285{286struct i2c_adapter *a = i2c_get_adapter(0);287struct i2c_msg msg;288int ret;289290if (!a)291return -ENODEV;292293camera_power(1);294msg.addr = 0x6e;295msg.buf = camera_ncm03j_magic;296msg.len = 2;297msg.flags = 0;298ret = i2c_transfer(a, &msg, 1);299camera_power(0);300301return ret;302}303304static int camera_set_capture(struct soc_camera_platform_info *info,305int enable)306{307struct i2c_adapter *a = i2c_get_adapter(0);308struct i2c_msg msg;309int ret = 0;310int i;311312camera_power(0);313if (!enable)314return 0; /* no disable for now */315316camera_power(1);317for (i = 0; i < ARRAY_SIZE(camera_ncm03j_magic); i += 2) {318u_int8_t buf[8];319320msg.addr = 0x6e;321msg.buf = buf;322msg.len = 2;323msg.flags = 0;324325buf[0] = camera_ncm03j_magic[i];326buf[1] = camera_ncm03j_magic[i + 1];327328ret = (ret < 0) ? ret : i2c_transfer(a, &msg, 1);329}330331return ret;332}333334static int ap325rxa_camera_add(struct soc_camera_link *icl, struct device *dev);335static void ap325rxa_camera_del(struct soc_camera_link *icl);336337static struct soc_camera_platform_info camera_info = {338.format_name = "UYVY",339.format_depth = 16,340.format = {341.code = V4L2_MBUS_FMT_UYVY8_2X8,342.colorspace = V4L2_COLORSPACE_SMPTE170M,343.field = V4L2_FIELD_NONE,344.width = 640,345.height = 480,346},347.bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |348SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8 |349SOCAM_DATA_ACTIVE_HIGH,350.set_capture = camera_set_capture,351};352353static struct soc_camera_link camera_link = {354.bus_id = 0,355.add_device = ap325rxa_camera_add,356.del_device = ap325rxa_camera_del,357.module_name = "soc_camera_platform",358.priv = &camera_info,359};360361static struct platform_device *camera_device;362363static void ap325rxa_camera_release(struct device *dev)364{365soc_camera_platform_release(&camera_device);366}367368static int ap325rxa_camera_add(struct soc_camera_link *icl,369struct device *dev)370{371int ret = soc_camera_platform_add(icl, dev, &camera_device, &camera_link,372ap325rxa_camera_release, 0);373if (ret < 0)374return ret;375376ret = camera_probe();377if (ret < 0)378soc_camera_platform_del(icl, camera_device, &camera_link);379380return ret;381}382383static void ap325rxa_camera_del(struct soc_camera_link *icl)384{385soc_camera_platform_del(icl, camera_device, &camera_link);386}387#endif /* CONFIG_I2C */388389static int ov7725_power(struct device *dev, int mode)390{391camera_power(0);392if (mode)393camera_power(1);394395return 0;396}397398static struct sh_mobile_ceu_info sh_mobile_ceu_info = {399.flags = SH_CEU_FLAG_USE_8BIT_BUS,400};401402static struct resource ceu_resources[] = {403[0] = {404.name = "CEU",405.start = 0xfe910000,406.end = 0xfe91009f,407.flags = IORESOURCE_MEM,408},409[1] = {410.start = 52,411.flags = IORESOURCE_IRQ,412},413[2] = {414/* place holder for contiguous memory */415},416};417418static struct platform_device ceu_device = {419.name = "sh_mobile_ceu",420.id = 0, /* "ceu0" clock */421.num_resources = ARRAY_SIZE(ceu_resources),422.resource = ceu_resources,423.dev = {424.platform_data = &sh_mobile_ceu_info,425},426.archdata = {427.hwblk_id = HWBLK_CEU,428},429};430431static struct resource sdhi0_cn3_resources[] = {432[0] = {433.name = "SDHI0",434.start = 0x04ce0000,435.end = 0x04ce00ff,436.flags = IORESOURCE_MEM,437},438[1] = {439.start = 100,440.flags = IORESOURCE_IRQ,441},442};443444static struct sh_mobile_sdhi_info sdhi0_cn3_data = {445.tmio_caps = MMC_CAP_SDIO_IRQ,446};447448static struct platform_device sdhi0_cn3_device = {449.name = "sh_mobile_sdhi",450.id = 0, /* "sdhi0" clock */451.num_resources = ARRAY_SIZE(sdhi0_cn3_resources),452.resource = sdhi0_cn3_resources,453.dev = {454.platform_data = &sdhi0_cn3_data,455},456.archdata = {457.hwblk_id = HWBLK_SDHI0,458},459};460461static struct resource sdhi1_cn7_resources[] = {462[0] = {463.name = "SDHI1",464.start = 0x04cf0000,465.end = 0x04cf00ff,466.flags = IORESOURCE_MEM,467},468[1] = {469.start = 23,470.flags = IORESOURCE_IRQ,471},472};473474static struct sh_mobile_sdhi_info sdhi1_cn7_data = {475.tmio_caps = MMC_CAP_SDIO_IRQ,476};477478static struct platform_device sdhi1_cn7_device = {479.name = "sh_mobile_sdhi",480.id = 1, /* "sdhi1" clock */481.num_resources = ARRAY_SIZE(sdhi1_cn7_resources),482.resource = sdhi1_cn7_resources,483.dev = {484.platform_data = &sdhi1_cn7_data,485},486.archdata = {487.hwblk_id = HWBLK_SDHI1,488},489};490491static struct i2c_board_info __initdata ap325rxa_i2c_devices[] = {492{493I2C_BOARD_INFO("pcf8563", 0x51),494},495};496497static struct i2c_board_info ap325rxa_i2c_camera[] = {498{499I2C_BOARD_INFO("ov772x", 0x21),500},501};502503static struct ov772x_camera_info ov7725_info = {504.flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP | \505OV772X_FLAG_8BIT,506.edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0),507};508509static struct soc_camera_link ov7725_link = {510.bus_id = 0,511.power = ov7725_power,512.board_info = &ap325rxa_i2c_camera[0],513.i2c_adapter_id = 0,514.priv = &ov7725_info,515};516517static struct platform_device ap325rxa_camera[] = {518{519.name = "soc-camera-pdrv",520.id = 0,521.dev = {522.platform_data = &ov7725_link,523},524}, {525.name = "soc-camera-pdrv",526.id = 1,527.dev = {528.platform_data = &camera_link,529},530},531};532533static struct platform_device *ap325rxa_devices[] __initdata = {534&smsc9118_device,535&ap325rxa_nor_flash_device,536&lcdc_device,537&ceu_device,538&nand_flash_device,539&sdhi0_cn3_device,540&sdhi1_cn7_device,541&ap325rxa_camera[0],542&ap325rxa_camera[1],543};544545extern char ap325rxa_sdram_enter_start;546extern char ap325rxa_sdram_enter_end;547extern char ap325rxa_sdram_leave_start;548extern char ap325rxa_sdram_leave_end;549550static int __init ap325rxa_devices_setup(void)551{552/* register board specific self-refresh code */553sh_mobile_register_self_refresh(SUSP_SH_STANDBY | SUSP_SH_SF,554&ap325rxa_sdram_enter_start,555&ap325rxa_sdram_enter_end,556&ap325rxa_sdram_leave_start,557&ap325rxa_sdram_leave_end);558559/* LD3 and LD4 LEDs */560gpio_request(GPIO_PTX5, NULL); /* RUN */561gpio_direction_output(GPIO_PTX5, 1);562gpio_export(GPIO_PTX5, 0);563564gpio_request(GPIO_PTX4, NULL); /* INDICATOR */565gpio_direction_output(GPIO_PTX4, 0);566gpio_export(GPIO_PTX4, 0);567568/* SW1 input */569gpio_request(GPIO_PTF7, NULL); /* MODE */570gpio_direction_input(GPIO_PTF7);571gpio_export(GPIO_PTF7, 0);572573/* LCDC */574gpio_request(GPIO_FN_LCDD15, NULL);575gpio_request(GPIO_FN_LCDD14, NULL);576gpio_request(GPIO_FN_LCDD13, NULL);577gpio_request(GPIO_FN_LCDD12, NULL);578gpio_request(GPIO_FN_LCDD11, NULL);579gpio_request(GPIO_FN_LCDD10, NULL);580gpio_request(GPIO_FN_LCDD9, NULL);581gpio_request(GPIO_FN_LCDD8, NULL);582gpio_request(GPIO_FN_LCDD7, NULL);583gpio_request(GPIO_FN_LCDD6, NULL);584gpio_request(GPIO_FN_LCDD5, NULL);585gpio_request(GPIO_FN_LCDD4, NULL);586gpio_request(GPIO_FN_LCDD3, NULL);587gpio_request(GPIO_FN_LCDD2, NULL);588gpio_request(GPIO_FN_LCDD1, NULL);589gpio_request(GPIO_FN_LCDD0, NULL);590gpio_request(GPIO_FN_LCDLCLK_PTR, NULL);591gpio_request(GPIO_FN_LCDDCK, NULL);592gpio_request(GPIO_FN_LCDVEPWC, NULL);593gpio_request(GPIO_FN_LCDVCPWC, NULL);594gpio_request(GPIO_FN_LCDVSYN, NULL);595gpio_request(GPIO_FN_LCDHSYN, NULL);596gpio_request(GPIO_FN_LCDDISP, NULL);597gpio_request(GPIO_FN_LCDDON, NULL);598599/* LCD backlight */600gpio_request(GPIO_PTS3, NULL);601gpio_direction_output(GPIO_PTS3, 1);602603/* CEU */604gpio_request(GPIO_FN_VIO_CLK2, NULL);605gpio_request(GPIO_FN_VIO_VD2, NULL);606gpio_request(GPIO_FN_VIO_HD2, NULL);607gpio_request(GPIO_FN_VIO_FLD, NULL);608gpio_request(GPIO_FN_VIO_CKO, NULL);609gpio_request(GPIO_FN_VIO_D15, NULL);610gpio_request(GPIO_FN_VIO_D14, NULL);611gpio_request(GPIO_FN_VIO_D13, NULL);612gpio_request(GPIO_FN_VIO_D12, NULL);613gpio_request(GPIO_FN_VIO_D11, NULL);614gpio_request(GPIO_FN_VIO_D10, NULL);615gpio_request(GPIO_FN_VIO_D9, NULL);616gpio_request(GPIO_FN_VIO_D8, NULL);617618gpio_request(GPIO_PTZ7, NULL);619gpio_direction_output(GPIO_PTZ7, 0); /* OE_CAM */620gpio_request(GPIO_PTZ6, NULL);621gpio_direction_output(GPIO_PTZ6, 0); /* STBY_CAM */622gpio_request(GPIO_PTZ5, NULL);623gpio_direction_output(GPIO_PTZ5, 0); /* RST_CAM */624gpio_request(GPIO_PTZ4, NULL);625gpio_direction_output(GPIO_PTZ4, 0); /* SADDR */626627__raw_writew(__raw_readw(PORT_MSELCRB) & ~0x0001, PORT_MSELCRB);628629/* FLCTL */630gpio_request(GPIO_FN_FCE, NULL);631gpio_request(GPIO_FN_NAF7, NULL);632gpio_request(GPIO_FN_NAF6, NULL);633gpio_request(GPIO_FN_NAF5, NULL);634gpio_request(GPIO_FN_NAF4, NULL);635gpio_request(GPIO_FN_NAF3, NULL);636gpio_request(GPIO_FN_NAF2, NULL);637gpio_request(GPIO_FN_NAF1, NULL);638gpio_request(GPIO_FN_NAF0, NULL);639gpio_request(GPIO_FN_FCDE, NULL);640gpio_request(GPIO_FN_FOE, NULL);641gpio_request(GPIO_FN_FSC, NULL);642gpio_request(GPIO_FN_FWE, NULL);643gpio_request(GPIO_FN_FRB, NULL);644645__raw_writew(0, PORT_HIZCRC);646__raw_writew(0xFFFF, PORT_DRVCRA);647__raw_writew(0xFFFF, PORT_DRVCRB);648649platform_resource_setup_memory(&ceu_device, "ceu", 4 << 20);650651/* SDHI0 - CN3 - SD CARD */652gpio_request(GPIO_FN_SDHI0CD_PTD, NULL);653gpio_request(GPIO_FN_SDHI0WP_PTD, NULL);654gpio_request(GPIO_FN_SDHI0D3_PTD, NULL);655gpio_request(GPIO_FN_SDHI0D2_PTD, NULL);656gpio_request(GPIO_FN_SDHI0D1_PTD, NULL);657gpio_request(GPIO_FN_SDHI0D0_PTD, NULL);658gpio_request(GPIO_FN_SDHI0CMD_PTD, NULL);659gpio_request(GPIO_FN_SDHI0CLK_PTD, NULL);660661/* SDHI1 - CN7 - MICRO SD CARD */662gpio_request(GPIO_FN_SDHI1CD, NULL);663gpio_request(GPIO_FN_SDHI1D3, NULL);664gpio_request(GPIO_FN_SDHI1D2, NULL);665gpio_request(GPIO_FN_SDHI1D1, NULL);666gpio_request(GPIO_FN_SDHI1D0, NULL);667gpio_request(GPIO_FN_SDHI1CMD, NULL);668gpio_request(GPIO_FN_SDHI1CLK, NULL);669670i2c_register_board_info(0, ap325rxa_i2c_devices,671ARRAY_SIZE(ap325rxa_i2c_devices));672673return platform_add_devices(ap325rxa_devices,674ARRAY_SIZE(ap325rxa_devices));675}676arch_initcall(ap325rxa_devices_setup);677678/* Return the board specific boot mode pin configuration */679static int ap325rxa_mode_pins(void)680{681/* MD0=0, MD1=0, MD2=0: Clock Mode 0682* MD3=0: 16-bit Area0 Bus Width683* MD5=1: Little Endian684* TSTMD=1, MD8=1: Test Mode Disabled685*/686return MODE_PIN5 | MODE_PIN8;687}688689static struct sh_machine_vector mv_ap325rxa __initmv = {690.mv_name = "AP-325RXA",691.mv_mode_pins = ap325rxa_mode_pins,692};693694695