Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/arch/arm/mach-omap2/board-overo.c
10817 views
1
/*
2
* board-overo.c (Gumstix Overo)
3
*
4
* Initial code: Steve Sakoman <[email protected]>
5
*
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* version 2 as published by the Free Software Foundation.
9
*
10
* This program is distributed in the hope that it will be useful, but
11
* WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* General Public License for more details.
14
*
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18
* 02110-1301 USA
19
*
20
*/
21
22
#include <linux/clk.h>
23
#include <linux/delay.h>
24
#include <linux/err.h>
25
#include <linux/init.h>
26
#include <linux/io.h>
27
#include <linux/gpio.h>
28
#include <linux/kernel.h>
29
#include <linux/platform_device.h>
30
#include <linux/i2c/twl.h>
31
#include <linux/regulator/machine.h>
32
#include <linux/regulator/fixed.h>
33
#include <linux/spi/spi.h>
34
35
#include <linux/mtd/mtd.h>
36
#include <linux/mtd/nand.h>
37
#include <linux/mtd/partitions.h>
38
#include <linux/mmc/host.h>
39
40
#include <asm/mach-types.h>
41
#include <asm/mach/arch.h>
42
#include <asm/mach/flash.h>
43
#include <asm/mach/map.h>
44
45
#include <plat/board.h>
46
#include <plat/common.h>
47
#include <video/omapdss.h>
48
#include <video/omap-panel-generic-dpi.h>
49
#include <plat/gpmc.h>
50
#include <mach/hardware.h>
51
#include <plat/nand.h>
52
#include <plat/mcspi.h>
53
#include <plat/mux.h>
54
#include <plat/usb.h>
55
56
#include "mux.h"
57
#include "sdram-micron-mt46h32m32lf-6.h"
58
#include "hsmmc.h"
59
#include "common-board-devices.h"
60
61
#define OVERO_GPIO_BT_XGATE 15
62
#define OVERO_GPIO_W2W_NRESET 16
63
#define OVERO_GPIO_PENDOWN 114
64
#define OVERO_GPIO_BT_NRESET 164
65
#define OVERO_GPIO_USBH_CPEN 168
66
#define OVERO_GPIO_USBH_NRESET 183
67
68
#define OVERO_SMSC911X_CS 5
69
#define OVERO_SMSC911X_GPIO 176
70
#define OVERO_SMSC911X2_CS 4
71
#define OVERO_SMSC911X2_GPIO 65
72
73
#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \
74
defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE)
75
76
/* fixed regulator for ads7846 */
77
static struct regulator_consumer_supply ads7846_supply =
78
REGULATOR_SUPPLY("vcc", "spi1.0");
79
80
static struct regulator_init_data vads7846_regulator = {
81
.constraints = {
82
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
83
},
84
.num_consumer_supplies = 1,
85
.consumer_supplies = &ads7846_supply,
86
};
87
88
static struct fixed_voltage_config vads7846 = {
89
.supply_name = "vads7846",
90
.microvolts = 3300000, /* 3.3V */
91
.gpio = -EINVAL,
92
.startup_delay = 0,
93
.init_data = &vads7846_regulator,
94
};
95
96
static struct platform_device vads7846_device = {
97
.name = "reg-fixed-voltage",
98
.id = 1,
99
.dev = {
100
.platform_data = &vads7846,
101
},
102
};
103
104
static void __init overo_ads7846_init(void)
105
{
106
omap_ads7846_init(1, OVERO_GPIO_PENDOWN, 0, NULL);
107
platform_device_register(&vads7846_device);
108
}
109
110
#else
111
static inline void __init overo_ads7846_init(void) { return; }
112
#endif
113
114
#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
115
116
#include <linux/smsc911x.h>
117
#include <plat/gpmc-smsc911x.h>
118
119
static struct omap_smsc911x_platform_data smsc911x_cfg = {
120
.id = 0,
121
.cs = OVERO_SMSC911X_CS,
122
.gpio_irq = OVERO_SMSC911X_GPIO,
123
.gpio_reset = -EINVAL,
124
.flags = SMSC911X_USE_32BIT,
125
};
126
127
static struct omap_smsc911x_platform_data smsc911x2_cfg = {
128
.id = 1,
129
.cs = OVERO_SMSC911X2_CS,
130
.gpio_irq = OVERO_SMSC911X2_GPIO,
131
.gpio_reset = -EINVAL,
132
.flags = SMSC911X_USE_32BIT,
133
};
134
135
static void __init overo_init_smsc911x(void)
136
{
137
gpmc_smsc911x_init(&smsc911x_cfg);
138
gpmc_smsc911x_init(&smsc911x2_cfg);
139
}
140
141
#else
142
static inline void __init overo_init_smsc911x(void) { return; }
143
#endif
144
145
/* DSS */
146
static int lcd_enabled;
147
static int dvi_enabled;
148
149
#define OVERO_GPIO_LCD_EN 144
150
#define OVERO_GPIO_LCD_BL 145
151
152
static struct gpio overo_dss_gpios[] __initdata = {
153
{ OVERO_GPIO_LCD_EN, GPIOF_OUT_INIT_HIGH, "OVERO_GPIO_LCD_EN" },
154
{ OVERO_GPIO_LCD_BL, GPIOF_OUT_INIT_HIGH, "OVERO_GPIO_LCD_BL" },
155
};
156
157
static void __init overo_display_init(void)
158
{
159
if (gpio_request_array(overo_dss_gpios, ARRAY_SIZE(overo_dss_gpios))) {
160
printk(KERN_ERR "could not obtain DSS control GPIOs\n");
161
return;
162
}
163
164
gpio_export(OVERO_GPIO_LCD_EN, 0);
165
gpio_export(OVERO_GPIO_LCD_BL, 0);
166
}
167
168
static int overo_panel_enable_dvi(struct omap_dss_device *dssdev)
169
{
170
if (lcd_enabled) {
171
printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
172
return -EINVAL;
173
}
174
dvi_enabled = 1;
175
176
return 0;
177
}
178
179
static void overo_panel_disable_dvi(struct omap_dss_device *dssdev)
180
{
181
dvi_enabled = 0;
182
}
183
184
static struct panel_generic_dpi_data dvi_panel = {
185
.name = "generic",
186
.platform_enable = overo_panel_enable_dvi,
187
.platform_disable = overo_panel_disable_dvi,
188
};
189
190
static struct omap_dss_device overo_dvi_device = {
191
.name = "dvi",
192
.type = OMAP_DISPLAY_TYPE_DPI,
193
.driver_name = "generic_dpi_panel",
194
.data = &dvi_panel,
195
.phy.dpi.data_lines = 24,
196
};
197
198
static struct omap_dss_device overo_tv_device = {
199
.name = "tv",
200
.driver_name = "venc",
201
.type = OMAP_DISPLAY_TYPE_VENC,
202
.phy.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
203
};
204
205
static int overo_panel_enable_lcd(struct omap_dss_device *dssdev)
206
{
207
if (dvi_enabled) {
208
printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
209
return -EINVAL;
210
}
211
212
gpio_set_value(OVERO_GPIO_LCD_EN, 1);
213
gpio_set_value(OVERO_GPIO_LCD_BL, 1);
214
lcd_enabled = 1;
215
return 0;
216
}
217
218
static void overo_panel_disable_lcd(struct omap_dss_device *dssdev)
219
{
220
gpio_set_value(OVERO_GPIO_LCD_EN, 0);
221
gpio_set_value(OVERO_GPIO_LCD_BL, 0);
222
lcd_enabled = 0;
223
}
224
225
static struct panel_generic_dpi_data lcd43_panel = {
226
.name = "samsung_lte430wq_f0c",
227
.platform_enable = overo_panel_enable_lcd,
228
.platform_disable = overo_panel_disable_lcd,
229
};
230
231
static struct omap_dss_device overo_lcd43_device = {
232
.name = "lcd43",
233
.type = OMAP_DISPLAY_TYPE_DPI,
234
.driver_name = "generic_dpi_panel",
235
.data = &lcd43_panel,
236
.phy.dpi.data_lines = 24,
237
};
238
239
#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
240
defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
241
static struct omap_dss_device overo_lcd35_device = {
242
.type = OMAP_DISPLAY_TYPE_DPI,
243
.name = "lcd35",
244
.driver_name = "lgphilips_lb035q02_panel",
245
.phy.dpi.data_lines = 24,
246
.platform_enable = overo_panel_enable_lcd,
247
.platform_disable = overo_panel_disable_lcd,
248
};
249
#endif
250
251
static struct omap_dss_device *overo_dss_devices[] = {
252
&overo_dvi_device,
253
&overo_tv_device,
254
#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
255
defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
256
&overo_lcd35_device,
257
#endif
258
&overo_lcd43_device,
259
};
260
261
static struct omap_dss_board_info overo_dss_data = {
262
.num_devices = ARRAY_SIZE(overo_dss_devices),
263
.devices = overo_dss_devices,
264
.default_device = &overo_dvi_device,
265
};
266
267
static struct regulator_consumer_supply overo_vdda_dac_supply =
268
REGULATOR_SUPPLY("vdda_dac", "omapdss_venc");
269
270
static struct regulator_consumer_supply overo_vdds_dsi_supply[] = {
271
REGULATOR_SUPPLY("vdds_dsi", "omapdss"),
272
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
273
};
274
275
static struct mtd_partition overo_nand_partitions[] = {
276
{
277
.name = "xloader",
278
.offset = 0, /* Offset = 0x00000 */
279
.size = 4 * NAND_BLOCK_SIZE,
280
.mask_flags = MTD_WRITEABLE
281
},
282
{
283
.name = "uboot",
284
.offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
285
.size = 14 * NAND_BLOCK_SIZE,
286
},
287
{
288
.name = "uboot environment",
289
.offset = MTDPART_OFS_APPEND, /* Offset = 0x240000 */
290
.size = 2 * NAND_BLOCK_SIZE,
291
},
292
{
293
.name = "linux",
294
.offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */
295
.size = 32 * NAND_BLOCK_SIZE,
296
},
297
{
298
.name = "rootfs",
299
.offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */
300
.size = MTDPART_SIZ_FULL,
301
},
302
};
303
304
static struct omap2_hsmmc_info mmc[] = {
305
{
306
.mmc = 1,
307
.caps = MMC_CAP_4_BIT_DATA,
308
.gpio_cd = -EINVAL,
309
.gpio_wp = -EINVAL,
310
},
311
{
312
.mmc = 2,
313
.caps = MMC_CAP_4_BIT_DATA,
314
.gpio_cd = -EINVAL,
315
.gpio_wp = -EINVAL,
316
.transceiver = true,
317
.ocr_mask = 0x00100000, /* 3.3V */
318
},
319
{} /* Terminator */
320
};
321
322
static struct regulator_consumer_supply overo_vmmc1_supply = {
323
.supply = "vmmc",
324
};
325
326
#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
327
#include <linux/leds.h>
328
329
static struct gpio_led gpio_leds[] = {
330
{
331
.name = "overo:red:gpio21",
332
.default_trigger = "heartbeat",
333
.gpio = 21,
334
.active_low = true,
335
},
336
{
337
.name = "overo:blue:gpio22",
338
.default_trigger = "none",
339
.gpio = 22,
340
.active_low = true,
341
},
342
{
343
.name = "overo:blue:COM",
344
.default_trigger = "mmc0",
345
.gpio = -EINVAL, /* gets replaced */
346
.active_low = true,
347
},
348
};
349
350
static struct gpio_led_platform_data gpio_leds_pdata = {
351
.leds = gpio_leds,
352
.num_leds = ARRAY_SIZE(gpio_leds),
353
};
354
355
static struct platform_device gpio_leds_device = {
356
.name = "leds-gpio",
357
.id = -1,
358
.dev = {
359
.platform_data = &gpio_leds_pdata,
360
},
361
};
362
363
static void __init overo_init_led(void)
364
{
365
platform_device_register(&gpio_leds_device);
366
}
367
368
#else
369
static inline void __init overo_init_led(void) { return; }
370
#endif
371
372
#if defined(CONFIG_KEYBOARD_GPIO) || defined(CONFIG_KEYBOARD_GPIO_MODULE)
373
#include <linux/input.h>
374
#include <linux/gpio_keys.h>
375
376
static struct gpio_keys_button gpio_buttons[] = {
377
{
378
.code = BTN_0,
379
.gpio = 23,
380
.desc = "button0",
381
.wakeup = 1,
382
},
383
{
384
.code = BTN_1,
385
.gpio = 14,
386
.desc = "button1",
387
.wakeup = 1,
388
},
389
};
390
391
static struct gpio_keys_platform_data gpio_keys_pdata = {
392
.buttons = gpio_buttons,
393
.nbuttons = ARRAY_SIZE(gpio_buttons),
394
};
395
396
static struct platform_device gpio_keys_device = {
397
.name = "gpio-keys",
398
.id = -1,
399
.dev = {
400
.platform_data = &gpio_keys_pdata,
401
},
402
};
403
404
static void __init overo_init_keys(void)
405
{
406
platform_device_register(&gpio_keys_device);
407
}
408
409
#else
410
static inline void __init overo_init_keys(void) { return; }
411
#endif
412
413
static int overo_twl_gpio_setup(struct device *dev,
414
unsigned gpio, unsigned ngpio)
415
{
416
omap2_hsmmc_init(mmc);
417
418
overo_vmmc1_supply.dev = mmc[0].dev;
419
420
#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
421
/* TWL4030_GPIO_MAX + 1 == ledB, PMU_STAT (out, active low LED) */
422
gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
423
#endif
424
425
return 0;
426
}
427
428
static struct twl4030_gpio_platform_data overo_gpio_data = {
429
.gpio_base = OMAP_MAX_GPIO_LINES,
430
.irq_base = TWL4030_GPIO_IRQ_BASE,
431
.irq_end = TWL4030_GPIO_IRQ_END,
432
.use_leds = true,
433
.setup = overo_twl_gpio_setup,
434
};
435
436
static struct twl4030_usb_data overo_usb_data = {
437
.usb_mode = T2_USB_MODE_ULPI,
438
};
439
440
static struct regulator_init_data overo_vmmc1 = {
441
.constraints = {
442
.min_uV = 1850000,
443
.max_uV = 3150000,
444
.valid_modes_mask = REGULATOR_MODE_NORMAL
445
| REGULATOR_MODE_STANDBY,
446
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
447
| REGULATOR_CHANGE_MODE
448
| REGULATOR_CHANGE_STATUS,
449
},
450
.num_consumer_supplies = 1,
451
.consumer_supplies = &overo_vmmc1_supply,
452
};
453
454
/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
455
static struct regulator_init_data overo_vdac = {
456
.constraints = {
457
.min_uV = 1800000,
458
.max_uV = 1800000,
459
.valid_modes_mask = REGULATOR_MODE_NORMAL
460
| REGULATOR_MODE_STANDBY,
461
.valid_ops_mask = REGULATOR_CHANGE_MODE
462
| REGULATOR_CHANGE_STATUS,
463
},
464
.num_consumer_supplies = 1,
465
.consumer_supplies = &overo_vdda_dac_supply,
466
};
467
468
/* VPLL2 for digital video outputs */
469
static struct regulator_init_data overo_vpll2 = {
470
.constraints = {
471
.name = "VDVI",
472
.min_uV = 1800000,
473
.max_uV = 1800000,
474
.valid_modes_mask = REGULATOR_MODE_NORMAL
475
| REGULATOR_MODE_STANDBY,
476
.valid_ops_mask = REGULATOR_CHANGE_MODE
477
| REGULATOR_CHANGE_STATUS,
478
},
479
.num_consumer_supplies = ARRAY_SIZE(overo_vdds_dsi_supply),
480
.consumer_supplies = overo_vdds_dsi_supply,
481
};
482
483
static struct twl4030_codec_audio_data overo_audio_data;
484
485
static struct twl4030_codec_data overo_codec_data = {
486
.audio_mclk = 26000000,
487
.audio = &overo_audio_data,
488
};
489
490
static struct twl4030_platform_data overo_twldata = {
491
.irq_base = TWL4030_IRQ_BASE,
492
.irq_end = TWL4030_IRQ_END,
493
.gpio = &overo_gpio_data,
494
.usb = &overo_usb_data,
495
.codec = &overo_codec_data,
496
.vmmc1 = &overo_vmmc1,
497
.vdac = &overo_vdac,
498
.vpll2 = &overo_vpll2,
499
};
500
501
static int __init overo_i2c_init(void)
502
{
503
omap3_pmic_init("tps65950", &overo_twldata);
504
/* i2c2 pins are used for gpio */
505
omap_register_i2c_bus(3, 400, NULL, 0);
506
return 0;
507
}
508
509
static struct spi_board_info overo_spi_board_info[] __initdata = {
510
#if defined(CONFIG_PANEL_LGPHILIPS_LB035Q02) || \
511
defined(CONFIG_PANEL_LGPHILIPS_LB035Q02_MODULE)
512
{
513
.modalias = "lgphilips_lb035q02_panel-spi",
514
.bus_num = 1,
515
.chip_select = 1,
516
.max_speed_hz = 500000,
517
.mode = SPI_MODE_3,
518
},
519
#endif
520
};
521
522
static int __init overo_spi_init(void)
523
{
524
overo_ads7846_init();
525
spi_register_board_info(overo_spi_board_info,
526
ARRAY_SIZE(overo_spi_board_info));
527
return 0;
528
}
529
530
static void __init overo_init_early(void)
531
{
532
omap2_init_common_infrastructure();
533
omap2_init_common_devices(mt46h32m32lf6_sdrc_params,
534
mt46h32m32lf6_sdrc_params);
535
}
536
537
static const struct usbhs_omap_board_data usbhs_bdata __initconst = {
538
.port_mode[0] = OMAP_USBHS_PORT_MODE_UNUSED,
539
.port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
540
.port_mode[2] = OMAP_USBHS_PORT_MODE_UNUSED,
541
.phy_reset = true,
542
.reset_gpio_port[0] = -EINVAL,
543
.reset_gpio_port[1] = OVERO_GPIO_USBH_NRESET,
544
.reset_gpio_port[2] = -EINVAL
545
};
546
547
#ifdef CONFIG_OMAP_MUX
548
static struct omap_board_mux board_mux[] __initdata = {
549
{ .reg_offset = OMAP_MUX_TERMINATOR },
550
};
551
#endif
552
553
static struct gpio overo_bt_gpios[] __initdata = {
554
{ OVERO_GPIO_BT_XGATE, GPIOF_OUT_INIT_LOW, "lcd enable" },
555
{ OVERO_GPIO_BT_NRESET, GPIOF_OUT_INIT_HIGH, "lcd bl enable" },
556
};
557
558
static void __init overo_init(void)
559
{
560
int ret;
561
562
omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
563
overo_i2c_init();
564
omap_display_init(&overo_dss_data);
565
omap_serial_init();
566
omap_nand_flash_init(0, overo_nand_partitions,
567
ARRAY_SIZE(overo_nand_partitions));
568
usb_musb_init(NULL);
569
usbhs_init(&usbhs_bdata);
570
overo_spi_init();
571
overo_ads7846_init();
572
overo_init_smsc911x();
573
overo_display_init();
574
overo_init_led();
575
overo_init_keys();
576
577
/* Ensure SDRC pins are mux'd for self-refresh */
578
omap_mux_init_signal("sdrc_cke0", OMAP_PIN_OUTPUT);
579
omap_mux_init_signal("sdrc_cke1", OMAP_PIN_OUTPUT);
580
581
ret = gpio_request_one(OVERO_GPIO_W2W_NRESET, GPIOF_OUT_INIT_HIGH,
582
"OVERO_GPIO_W2W_NRESET");
583
if (ret == 0) {
584
gpio_export(OVERO_GPIO_W2W_NRESET, 0);
585
gpio_set_value(OVERO_GPIO_W2W_NRESET, 0);
586
udelay(10);
587
gpio_set_value(OVERO_GPIO_W2W_NRESET, 1);
588
} else {
589
printk(KERN_ERR "could not obtain gpio for "
590
"OVERO_GPIO_W2W_NRESET\n");
591
}
592
593
ret = gpio_request_array(overo_bt_gpios, ARRAY_SIZE(overo_bt_gpios));
594
if (ret) {
595
pr_err("%s: could not obtain BT gpios\n", __func__);
596
} else {
597
gpio_export(OVERO_GPIO_BT_XGATE, 0);
598
gpio_export(OVERO_GPIO_BT_NRESET, 0);
599
gpio_set_value(OVERO_GPIO_BT_NRESET, 0);
600
mdelay(6);
601
gpio_set_value(OVERO_GPIO_BT_NRESET, 1);
602
}
603
604
ret = gpio_request_one(OVERO_GPIO_USBH_CPEN, GPIOF_OUT_INIT_HIGH,
605
"OVERO_GPIO_USBH_CPEN");
606
if (ret == 0)
607
gpio_export(OVERO_GPIO_USBH_CPEN, 0);
608
else
609
printk(KERN_ERR "could not obtain gpio for "
610
"OVERO_GPIO_USBH_CPEN\n");
611
}
612
613
MACHINE_START(OVERO, "Gumstix Overo")
614
.boot_params = 0x80000100,
615
.reserve = omap_reserve,
616
.map_io = omap3_map_io,
617
.init_early = overo_init_early,
618
.init_irq = omap_init_irq,
619
.init_machine = overo_init,
620
.timer = &omap_timer,
621
MACHINE_END
622
623