1 /*
2  * linux/arch/arm/mach-omap2/board-omap3logic.c
3  *
4  * Copyright (C) 2010 Li-Pro.Net
5  * Stephan Linz <linz@li-pro.net>
6  *
7  * Copyright (C) 2010 Logic Product Development, Inc.
8  * Peter Barada <peter.barada@logicpd.com>
9  *
10  * Modified from Beagle, EVM, and RX51
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License version 2 as
14  * published by the Free Software Foundation.
15  */
16 
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/platform_device.h>
20 #include <linux/delay.h>
21 #include <linux/err.h>
22 #include <linux/clk.h>
23 #include <linux/io.h>
24 #include <linux/gpio.h>
25 
26 #include <linux/regulator/machine.h>
27 
28 #include <linux/i2c/twl.h>
29 #include <linux/mmc/host.h>
30 
31 #include <mach/hardware.h>
32 #include <asm/mach-types.h>
33 #include <asm/mach/arch.h>
34 #include <asm/mach/map.h>
35 
36 #include "mux.h"
37 #include "hsmmc.h"
38 #include "control.h"
39 #include "common-board-devices.h"
40 
41 #include <plat/mux.h>
42 #include <plat/board.h>
43 #include "common.h"
44 #include <plat/gpmc-smsc911x.h>
45 #include <plat/gpmc.h>
46 #include <plat/sdrc.h>
47 
48 #define OMAP3LOGIC_SMSC911X_CS			1
49 
50 #define OMAP3530_LV_SOM_MMC_GPIO_CD		110
51 #define OMAP3530_LV_SOM_MMC_GPIO_WP		126
52 #define OMAP3530_LV_SOM_SMSC911X_GPIO_IRQ	152
53 
54 #define OMAP3_TORPEDO_MMC_GPIO_CD		127
55 #define OMAP3_TORPEDO_SMSC911X_GPIO_IRQ		129
56 
57 static struct regulator_consumer_supply omap3logic_vmmc1_supply[] = {
58 	REGULATOR_SUPPLY("vmmc", "omap_hsmmc.0"),
59 };
60 
61 /* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
62 static struct regulator_init_data omap3logic_vmmc1 = {
63 	.constraints = {
64 		.name			= "VMMC1",
65 		.min_uV			= 1850000,
66 		.max_uV			= 3150000,
67 		.valid_modes_mask	= REGULATOR_MODE_NORMAL
68 					| REGULATOR_MODE_STANDBY,
69 		.valid_ops_mask		= REGULATOR_CHANGE_VOLTAGE
70 					| REGULATOR_CHANGE_MODE
71 					| REGULATOR_CHANGE_STATUS,
72 	},
73 	.num_consumer_supplies  = ARRAY_SIZE(omap3logic_vmmc1_supply),
74 	.consumer_supplies      = omap3logic_vmmc1_supply,
75 };
76 
77 static struct twl4030_gpio_platform_data omap3logic_gpio_data = {
78 	.gpio_base	= OMAP_MAX_GPIO_LINES,
79 	.irq_base	= TWL4030_GPIO_IRQ_BASE,
80 	.irq_end	= TWL4030_GPIO_IRQ_END,
81 	.use_leds	= true,
82 	.pullups	= BIT(1),
83 	.pulldowns	= BIT(2)  | BIT(6)  | BIT(7)  | BIT(8)
84 			| BIT(13) | BIT(15) | BIT(16) | BIT(17),
85 };
86 
87 static struct twl4030_platform_data omap3logic_twldata = {
88 	.irq_base	= TWL4030_IRQ_BASE,
89 	.irq_end	= TWL4030_IRQ_END,
90 
91 	/* platform_data for children goes here */
92 	.gpio		= &omap3logic_gpio_data,
93 	.vmmc1		= &omap3logic_vmmc1,
94 };
95 
omap3logic_i2c_init(void)96 static int __init omap3logic_i2c_init(void)
97 {
98 	omap3_pmic_init("twl4030", &omap3logic_twldata);
99 	return 0;
100 }
101 
102 static struct omap2_hsmmc_info __initdata board_mmc_info[] = {
103 	{
104 		.name		= "external",
105 		.mmc		= 1,
106 		.caps		= MMC_CAP_4_BIT_DATA,
107 		.gpio_cd	= -EINVAL,
108 		.gpio_wp	= -EINVAL,
109 	},
110 	{}      /* Terminator */
111 };
112 
board_mmc_init(void)113 static void __init board_mmc_init(void)
114 {
115 	if (machine_is_omap3530_lv_som()) {
116 		/* OMAP3530 LV SOM board */
117 		board_mmc_info[0].gpio_cd = OMAP3530_LV_SOM_MMC_GPIO_CD;
118 		board_mmc_info[0].gpio_wp = OMAP3530_LV_SOM_MMC_GPIO_WP;
119 		omap_mux_init_signal("gpio_110", OMAP_PIN_OUTPUT);
120 		omap_mux_init_signal("gpio_126", OMAP_PIN_OUTPUT);
121 	} else if (machine_is_omap3_torpedo()) {
122 		/* OMAP3 Torpedo board */
123 		board_mmc_info[0].gpio_cd = OMAP3_TORPEDO_MMC_GPIO_CD;
124 		omap_mux_init_signal("gpio_127", OMAP_PIN_OUTPUT);
125 	} else {
126 		/* unsupported board */
127 		printk(KERN_ERR "%s(): unknown machine type\n", __func__);
128 		return;
129 	}
130 
131 	omap2_hsmmc_init(board_mmc_info);
132 }
133 
134 static struct omap_smsc911x_platform_data __initdata board_smsc911x_data = {
135 	.cs             = OMAP3LOGIC_SMSC911X_CS,
136 	.gpio_irq       = -EINVAL,
137 	.gpio_reset     = -EINVAL,
138 };
139 
140 /* TODO/FIXME (comment by Peter Barada, LogicPD):
141  * Fix the PBIAS voltage for Torpedo MMC1 pins that
142  * are used for other needs (IRQs, etc).            */
omap3torpedo_fix_pbias_voltage(void)143 static void omap3torpedo_fix_pbias_voltage(void)
144 {
145 	u16 control_pbias_offset = OMAP343X_CONTROL_PBIAS_LITE;
146 	u32 reg;
147 
148 	if (machine_is_omap3_torpedo())
149 	{
150 		/* Set the bias for the pin */
151 		reg = omap_ctrl_readl(control_pbias_offset);
152 
153 		reg &= ~OMAP343X_PBIASLITEPWRDNZ1;
154 		omap_ctrl_writel(reg, control_pbias_offset);
155 
156 		/* 100ms delay required for PBIAS configuration */
157 		msleep(100);
158 
159 		reg |= OMAP343X_PBIASLITEVMODE1;
160 		reg |= OMAP343X_PBIASLITEPWRDNZ1;
161 		omap_ctrl_writel(reg | 0x300, control_pbias_offset);
162 	}
163 }
164 
board_smsc911x_init(void)165 static inline void __init board_smsc911x_init(void)
166 {
167 	if (machine_is_omap3530_lv_som()) {
168 		/* OMAP3530 LV SOM board */
169 		board_smsc911x_data.gpio_irq =
170 					OMAP3530_LV_SOM_SMSC911X_GPIO_IRQ;
171 		omap_mux_init_signal("gpio_152", OMAP_PIN_INPUT);
172 	} else if (machine_is_omap3_torpedo()) {
173 		/* OMAP3 Torpedo board */
174 		board_smsc911x_data.gpio_irq = OMAP3_TORPEDO_SMSC911X_GPIO_IRQ;
175 		omap_mux_init_signal("gpio_129", OMAP_PIN_INPUT);
176 	} else {
177 		/* unsupported board */
178 		printk(KERN_ERR "%s(): unknown machine type\n", __func__);
179 		return;
180 	}
181 
182 	gpmc_smsc911x_init(&board_smsc911x_data);
183 }
184 
185 #ifdef CONFIG_OMAP_MUX
186 static struct omap_board_mux board_mux[] __initdata = {
187 	{ .reg_offset = OMAP_MUX_TERMINATOR },
188 };
189 #endif
190 
omap3logic_init(void)191 static void __init omap3logic_init(void)
192 {
193 	omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
194 	omap3torpedo_fix_pbias_voltage();
195 	omap3logic_i2c_init();
196 	omap_serial_init();
197 	omap_sdrc_init(NULL, NULL);
198 	board_mmc_init();
199 	board_smsc911x_init();
200 
201 	/* Ensure SDRC pins are mux'd for self-refresh */
202 	omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
203 	omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
204 }
205 
206 MACHINE_START(OMAP3_TORPEDO, "Logic OMAP3 Torpedo board")
207 	.atag_offset	= 0x100,
208 	.map_io		= omap3_map_io,
209 	.init_early	= omap35xx_init_early,
210 	.init_irq	= omap3_init_irq,
211 	.handle_irq	= omap3_intc_handle_irq,
212 	.init_machine	= omap3logic_init,
213 	.timer		= &omap3_timer,
214 	.restart	= omap_prcm_restart,
215 MACHINE_END
216 
217 MACHINE_START(OMAP3530_LV_SOM, "OMAP Logic 3530 LV SOM board")
218 	.atag_offset	= 0x100,
219 	.map_io		= omap3_map_io,
220 	.init_early	= omap35xx_init_early,
221 	.init_irq	= omap3_init_irq,
222 	.handle_irq	= omap3_intc_handle_irq,
223 	.init_machine	= omap3logic_init,
224 	.timer		= &omap3_timer,
225 	.restart	= omap_prcm_restart,
226 MACHINE_END
227