Commit | Line | Data |
---|---|---|
cdd280b9 TN |
1 | /* |
2 | * linux/arch/arm/mach-omap2/gpmc-smsc911x.c | |
3 | * | |
4 | * Copyright (C) 2009 Li-Pro.Net | |
5 | * Stephan Linz <linz@li-pro.net> | |
6 | * | |
7 | * Modified from linux/arch/arm/mach-omap2/gpmc-smc91x.c | |
8 | * | |
9 | * This program is free software; you can redistribute it and/or modify | |
10 | * it under the terms of the GNU General Public License version 2 as | |
11 | * published by the Free Software Foundation. | |
12 | */ | |
13 | ||
14 | #include <linux/kernel.h> | |
15 | #include <linux/platform_device.h> | |
16 | #include <linux/gpio.h> | |
17 | #include <linux/delay.h> | |
18 | #include <linux/interrupt.h> | |
19 | #include <linux/io.h> | |
20 | #include <linux/smsc911x.h> | |
21 | ||
22 | #include <plat/board.h> | |
23 | #include <plat/gpmc.h> | |
24 | #include <plat/gpmc-smsc911x.h> | |
25 | ||
26 | static struct omap_smsc911x_platform_data *gpmc_cfg; | |
27 | ||
28 | static struct resource gpmc_smsc911x_resources[] = { | |
29 | [0] = { | |
30 | .flags = IORESOURCE_MEM, | |
31 | }, | |
32 | [1] = { | |
33 | .flags = IORESOURCE_IRQ, | |
34 | }, | |
35 | }; | |
36 | ||
37 | static struct smsc911x_platform_config gpmc_smsc911x_config = { | |
38 | .phy_interface = PHY_INTERFACE_MODE_MII, | |
39 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | |
40 | .irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN, | |
41 | .flags = SMSC911X_USE_16BIT, | |
42 | }; | |
43 | ||
44 | static struct platform_device gpmc_smsc911x_device = { | |
45 | .name = "smsc911x", | |
46 | .id = -1, | |
47 | .num_resources = ARRAY_SIZE(gpmc_smsc911x_resources), | |
48 | .resource = gpmc_smsc911x_resources, | |
49 | .dev = { | |
50 | .platform_data = &gpmc_smsc911x_config, | |
51 | }, | |
52 | }; | |
53 | ||
54 | /* | |
55 | * Initialize smsc911x device connected to the GPMC. Note that we | |
56 | * assume that pin multiplexing is done in the board-*.c file, | |
57 | * or in the bootloader. | |
58 | */ | |
59 | void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *board_data) | |
60 | { | |
61 | unsigned long cs_mem_base; | |
62 | int ret; | |
63 | ||
64 | gpmc_cfg = board_data; | |
65 | ||
66 | if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) { | |
67 | printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n"); | |
68 | return; | |
69 | } | |
70 | ||
71 | gpmc_smsc911x_resources[0].start = cs_mem_base + 0x0; | |
72 | gpmc_smsc911x_resources[0].end = cs_mem_base + 0xff; | |
73 | ||
74 | if (gpio_request(gpmc_cfg->gpio_irq, "smsc911x irq") < 0) { | |
75 | printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n", | |
76 | gpmc_cfg->gpio_irq); | |
77 | goto free1; | |
78 | } | |
79 | ||
80 | gpio_direction_input(gpmc_cfg->gpio_irq); | |
81 | gpmc_smsc911x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq); | |
82 | gpmc_smsc911x_resources[1].flags |= | |
83 | (gpmc_cfg->flags & IRQF_TRIGGER_MASK); | |
84 | ||
85 | if (gpio_is_valid(gpmc_cfg->gpio_reset)) { | |
86 | ret = gpio_request(gpmc_cfg->gpio_reset, "smsc911x reset"); | |
87 | if (ret) { | |
88 | printk(KERN_ERR "Failed to request GPIO%d for smsc911x reset\n", | |
89 | gpmc_cfg->gpio_reset); | |
90 | goto free2; | |
91 | } | |
92 | ||
93 | gpio_direction_output(gpmc_cfg->gpio_reset, 1); | |
94 | gpio_set_value(gpmc_cfg->gpio_reset, 0); | |
95 | msleep(100); | |
96 | gpio_set_value(gpmc_cfg->gpio_reset, 1); | |
97 | } | |
98 | ||
99 | if (platform_device_register(&gpmc_smsc911x_device) < 0) { | |
100 | printk(KERN_ERR "Unable to register smsc911x device\n"); | |
101 | gpio_free(gpmc_cfg->gpio_reset); | |
102 | goto free2; | |
103 | } | |
104 | ||
105 | return; | |
106 | ||
107 | free2: | |
108 | gpio_free(gpmc_cfg->gpio_irq); | |
109 | free1: | |
110 | gpmc_cs_free(gpmc_cfg->cs); | |
111 | ||
112 | printk(KERN_ERR "Could not initialize smsc911x\n"); | |
113 | } |