board-ape6evm.c 8.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * 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.
 *
 * 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 St, Fifth Floor, Boston, MA  02110-1301  USA
 */

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

37 38 39
#include <asm/mach-types.h>
#include <asm/mach/arch.h>

M
Magnus Damm 已提交
40
#include "common.h"
41
#include "irqs.h"
42
#include "r8a73a4.h"
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 76 77
/* 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),
};

78 79 80 81 82 83 84 85 86 87 88 89 90
/* 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"),
};

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

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

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

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

117
/*
118 119 120 121
 * 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
122
 */
123
static struct regulator_consumer_supply vcc_mmc0_consumers[] =
124 125
{
	REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"),
126 127 128 129 130 131 132 133 134 135
};

/*
 * 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[] =
{
136
	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
};

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[] =
{
161
	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
162 163 164
};

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

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

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

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

/* SDHI1 */
189
static const struct sh_mobile_sdhi_info sdhi1_pdata __initconst = {
190 191 192 193 194
	.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,
};

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

200
static const struct pinctrl_map ape6evm_pinctrl_map[] __initconst = {
M
Magnus Damm 已提交
201 202 203
	/* SCIFA0 console */
	PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.0", "pfc-r8a73a4",
				  "scifa0_data", "scifa0"),
204 205 206
	/* SMSC */
	PIN_MAP_MUX_GROUP_DEFAULT("smsc911x", "pfc-r8a73a4",
				  "irqc_irq40", "irqc"),
207 208 209 210 211
	/* 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"),
212 213 214 215 216 217 218 219 220 221 222 223
	/* 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 已提交
224 225
};

226 227
static void __init ape6evm_add_standard_devices(void)
{
228 229 230 231

	struct clk *parent;
	struct clk *mp;

232
	r8a73a4_clock_init();
233 234 235 236 237 238 239 240 241 242

	/* 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 已提交
243 244 245
	pinctrl_register_mappings(ape6evm_pinctrl_map,
				  ARRAY_SIZE(ape6evm_pinctrl_map));
	r8a73a4_pinmux_init();
246
	r8a73a4_add_standard_devices();
247 248 249 250 251 252

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

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

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

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

static const char *ape6evm_boards_compat_dt[] __initdata = {
	"renesas,ape6evm",
	NULL,
};

DT_MACHINE_START(APE6EVM_DT, "ape6evm")
286
	.init_early	= r8a73a4_init_early,
287
	.init_machine	= ape6evm_add_standard_devices,
288
	.init_late	= shmobile_init_late,
289 290
	.dt_compat	= ape6evm_boards_compat_dt,
MACHINE_END