board-ape6evm.c 8.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * APE6EVM board support
 *
 * Copyright (C) 2013  Renesas Solutions Corp.
 * Copyright (C) 2013  Magnus Damm
 *
 * 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; version 2 of the License.
 *
 * 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.
 */

17
#include <linux/gpio.h>
18 19
#include <linux/gpio_keys.h>
#include <linux/input.h>
20
#include <linux/interrupt.h>
21 22
#include <linux/irqchip.h>
#include <linux/irqchip/arm-gic.h>
23
#include <linux/kernel.h>
24
#include <linux/mfd/tmio.h>
25 26
#include <linux/mmc/host.h>
#include <linux/mmc/sh_mmcif.h>
27
#include <linux/mmc/sh_mobile_sdhi.h>
M
Magnus Damm 已提交
28
#include <linux/pinctrl/machine.h>
29
#include <linux/platform_device.h>
30 31
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
32
#include <linux/sh_clk.h>
33
#include <linux/smsc911x.h>
34

35 36 37
#include <asm/mach-types.h>
#include <asm/mach/arch.h>

M
Magnus Damm 已提交
38
#include "common.h"
39
#include "irqs.h"
40
#include "r8a73a4.h"
41

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
/* LEDS */
static struct gpio_led ape6evm_leds[] = {
	{
		.name		= "gnss-en",
		.gpio		= 28,
		.default_state	= LEDS_GPIO_DEFSTATE_OFF,
	}, {
		.name		= "nfc-nrst",
		.gpio		= 126,
		.default_state	= LEDS_GPIO_DEFSTATE_OFF,
	}, {
		.name		= "gnss-nrst",
		.gpio		= 132,
		.default_state	= LEDS_GPIO_DEFSTATE_OFF,
	}, {
		.name		= "bt-wakeup",
		.gpio		= 232,
		.default_state	= LEDS_GPIO_DEFSTATE_OFF,
	}, {
		.name		= "strobe",
		.gpio		= 250,
		.default_state	= LEDS_GPIO_DEFSTATE_OFF,
	}, {
		.name		= "bbresetout",
		.gpio		= 288,
		.default_state	= LEDS_GPIO_DEFSTATE_OFF,
	},
};

static __initdata struct gpio_led_platform_data ape6evm_leds_pdata = {
	.leds		= ape6evm_leds,
	.num_leds	= ARRAY_SIZE(ape6evm_leds),
};

76 77 78 79 80 81 82 83 84 85 86 87 88
/* GPIO KEY */
#define GPIO_KEY(c, g, d, ...) \
	{ .code = c, .gpio = g, .desc = d, .active_low = 1 }

static struct gpio_keys_button gpio_buttons[] = {
	GPIO_KEY(KEY_0,			324,	"S16"),
	GPIO_KEY(KEY_MENU,		325,	"S17"),
	GPIO_KEY(KEY_HOME,		326,	"S18"),
	GPIO_KEY(KEY_BACK,		327,	"S19"),
	GPIO_KEY(KEY_VOLUMEUP,		328,	"S20"),
	GPIO_KEY(KEY_VOLUMEDOWN,	329,	"S21"),
};

89
static struct gpio_keys_platform_data ape6evm_keys_pdata __initdata = {
90 91 92 93
	.buttons	= gpio_buttons,
	.nbuttons	= ARRAY_SIZE(gpio_buttons),
};

94 95 96 97 98 99 100
/* Dummy supplies, where voltage doesn't matter */
static struct regulator_consumer_supply dummy_supplies[] = {
	REGULATOR_SUPPLY("vddvario", "smsc911x"),
	REGULATOR_SUPPLY("vdd33a", "smsc911x"),
};

/* SMSC LAN9220 */
101
static const struct resource lan9220_res[] __initconst = {
102 103 104 105 106 107 108
	DEFINE_RES_MEM(0x08000000, 0x1000),
	{
		.start	= irq_pin(40), /* IRQ40 */
		.flags	= IORESOURCE_IRQ | IRQF_TRIGGER_HIGH,
	},
};

109
static const struct smsc911x_platform_config lan9220_data __initconst = {
110 111 112 113 114
	.flags		= SMSC911X_USE_32BIT,
	.irq_type	= SMSC911X_IRQ_TYPE_PUSH_PULL,
	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_HIGH,
};

115
/*
116 117 118 119
 * MMC0 power supplies:
 * Both Vcc and VccQ to eMMC on APE6EVM are supplied by a tps80032 voltage
 * regulator. Until support for it is added to this file we simulate the
 * Vcc supply by a fixed always-on regulator
120
 */
121
static struct regulator_consumer_supply vcc_mmc0_consumers[] =
122 123
{
	REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"),
124 125 126 127 128 129 130 131 132 133
};

/*
 * SDHI0 power supplies:
 * Vcc to SDHI0 on APE6EVM is supplied by a GPIO-switchable regulator. VccQ is
 * provided by the same tps80032 regulator as both MMC0 voltages - see comment
 * above
 */
static struct regulator_consumer_supply vcc_sdhi0_consumers[] =
{
134
	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
};

static struct regulator_init_data vcc_sdhi0_init_data = {
	.constraints = {
		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
	},
	.num_consumer_supplies  = ARRAY_SIZE(vcc_sdhi0_consumers),
	.consumer_supplies      = vcc_sdhi0_consumers,
};

static const struct fixed_voltage_config vcc_sdhi0_info __initconst = {
	.supply_name = "SDHI0 Vcc",
	.microvolts = 3300000,
	.gpio = 76,
	.enable_high = 1,
	.init_data = &vcc_sdhi0_init_data,
};

/*
 * SDHI1 power supplies:
 * Vcc and VccQ to SDHI1 on APE6EVM are both fixed at 3.3V
 */
static struct regulator_consumer_supply vcc_sdhi1_consumers[] =
{
159
	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
160 161 162
};

/* MMCIF */
163
static const struct sh_mmcif_plat_data mmcif0_pdata __initconst = {
164
	.caps		= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
165 166
	.slave_id_tx	= SHDMA_SLAVE_MMCIF0_TX,
	.slave_id_rx	= SHDMA_SLAVE_MMCIF0_RX,
167
	.ccs_unsupported = true,
168 169
};

170
static const struct resource mmcif0_resources[] __initconst = {
171
	DEFINE_RES_MEM(0xee200000, 0x100),
172 173 174
	DEFINE_RES_IRQ(gic_spi(169)),
};

175
/* SDHI0 */
176
static const struct sh_mobile_sdhi_info sdhi0_pdata __initconst = {
177 178 179 180
	.tmio_flags	= TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE,
	.tmio_caps	= MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ,
};

181
static const struct resource sdhi0_resources[] __initconst = {
182
	DEFINE_RES_MEM(0xee100000, 0x100),
183 184 185 186
	DEFINE_RES_IRQ(gic_spi(165)),
};

/* SDHI1 */
187
static const struct sh_mobile_sdhi_info sdhi1_pdata __initconst = {
188 189 190 191 192
	.tmio_flags	= TMIO_MMC_HAS_IDLE_WAIT | TMIO_MMC_WRPROTECT_DISABLE,
	.tmio_caps	= MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
			  MMC_CAP_NEEDS_POLL,
};

193
static const struct resource sdhi1_resources[] __initconst = {
194
	DEFINE_RES_MEM(0xee120000, 0x100),
195 196 197
	DEFINE_RES_IRQ(gic_spi(166)),
};

198
static const struct pinctrl_map ape6evm_pinctrl_map[] __initconst = {
M
Magnus Damm 已提交
199 200 201
	/* SCIFA0 console */
	PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a73a4",
				  "scifa0_data", "scifa0"),
202 203 204
	/* SMSC */
	PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-r8a73a4",
				  "irqc_irq40", "irqc"),
205 206 207 208 209
	/* MMCIF0 */
	PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-r8a73a4",
				  "mmc0_data8", "mmc0"),
	PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.0", "pfc-r8a73a4",
				  "mmc0_ctrl", "mmc0"),
210 211 212 213 214 215 216 217 218 219 220 221
	/* SDHI0: uSD: no WP */
	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a73a4",
				  "sdhi0_data4", "sdhi0"),
	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a73a4",
				  "sdhi0_ctrl", "sdhi0"),
	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a73a4",
				  "sdhi0_cd", "sdhi0"),
	/* SDHI1 */
	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a73a4",
				  "sdhi1_data4", "sdhi1"),
	PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.1", "pfc-r8a73a4",
				  "sdhi1_ctrl", "sdhi1"),
M
Magnus Damm 已提交
222 223
};

224 225
static void __init ape6evm_add_standard_devices(void)
{
226 227 228 229

	struct clk *parent;
	struct clk *mp;

230
	r8a73a4_clock_init();
231 232 233 234 235 236 237 238 239 240

	/* MP clock parent = extal2 */
	parent      = clk_get(NULL, "extal2");
	mp          = clk_get(NULL, "mp");
	BUG_ON(IS_ERR(parent) || IS_ERR(mp));

	clk_set_parent(mp, parent);
	clk_put(parent);
	clk_put(mp);

M
Magnus Damm 已提交
241 242 243
	pinctrl_register_mappings(ape6evm_pinctrl_map,
				  ARRAY_SIZE(ape6evm_pinctrl_map));
	r8a73a4_pinmux_init();
244
	r8a73a4_add_standard_devices();
245 246 247 248 249 250

	/* LAN9220 ethernet */
	gpio_request_one(270, GPIOF_OUT_INIT_HIGH, NULL); /* smsc9220 RESET */

	regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));

251
	platform_device_register_resndata(NULL, "smsc911x", -1,
252 253
					  lan9220_res, ARRAY_SIZE(lan9220_res),
					  &lan9220_data, sizeof(lan9220_data));
254 255 256

	regulator_register_always_on(1, "MMC0 Vcc", vcc_mmc0_consumers,
				     ARRAY_SIZE(vcc_mmc0_consumers), 2800000);
257
	platform_device_register_resndata(NULL, "sh_mmcif", 0,
258 259
					  mmcif0_resources, ARRAY_SIZE(mmcif0_resources),
					  &mmcif0_pdata, sizeof(mmcif0_pdata));
260
	platform_device_register_data(NULL, "reg-fixed-voltage", 2,
261
				      &vcc_sdhi0_info, sizeof(vcc_sdhi0_info));
262
	platform_device_register_resndata(NULL, "sh_mobile_sdhi", 0,
263 264
					  sdhi0_resources, ARRAY_SIZE(sdhi0_resources),
					  &sdhi0_pdata, sizeof(sdhi0_pdata));
265 266
	regulator_register_always_on(3, "SDHI1 Vcc", vcc_sdhi1_consumers,
				     ARRAY_SIZE(vcc_sdhi1_consumers), 3300000);
267
	platform_device_register_resndata(NULL, "sh_mobile_sdhi", 1,
268 269
					  sdhi1_resources, ARRAY_SIZE(sdhi1_resources),
					  &sdhi1_pdata, sizeof(sdhi1_pdata));
270
	platform_device_register_data(NULL, "gpio-keys", -1,
271 272
				      &ape6evm_keys_pdata,
				      sizeof(ape6evm_keys_pdata));
273
	platform_device_register_data(NULL, "leds-gpio", -1,
274 275
				      &ape6evm_leds_pdata,
				      sizeof(ape6evm_leds_pdata));
276 277
}

278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
static void __init ape6evm_legacy_init_time(void)
{
	/* Do not invoke DT-based timers via clocksource_of_init() */
}

static void __init ape6evm_legacy_init_irq(void)
{
	void __iomem *gic_dist_base = ioremap_nocache(0xf1001000, 0x1000);
	void __iomem *gic_cpu_base = ioremap_nocache(0xf1002000, 0x1000);

	gic_init(0, 29, gic_dist_base, gic_cpu_base);

	/* Do not invoke DT-based interrupt code via irqchip_init() */
}


294 295 296 297 298 299
static const char *ape6evm_boards_compat_dt[] __initdata = {
	"renesas,ape6evm",
	NULL,
};

DT_MACHINE_START(APE6EVM_DT, "ape6evm")
300
	.init_early	= shmobile_init_delay,
301
	.init_irq       = ape6evm_legacy_init_irq,
302
	.init_machine	= ape6evm_add_standard_devices,
303
	.init_late	= shmobile_init_late,
304
	.dt_compat	= ape6evm_boards_compat_dt,
305
	.init_time	= ape6evm_legacy_init_time,
306
MACHINE_END