1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include <linux/gpio.h>
22#include <linux/if_ether.h>
23#include <linux/irq.h>
24#include <linux/jiffies.h>
25#include <linux/timer.h>
26#include <linux/serial.h>
27#include <linux/serial_8250.h>
28#include <linux/leds.h>
29#include <linux/reboot.h>
30#include <linux/i2c.h>
31#include <linux/gpio/machine.h>
32#include <linux/io.h>
33#include <asm/mach-types.h>
34#include <asm/mach/arch.h>
35#include <asm/mach/flash.h>
36#include <mach/hardware.h>
37
38#include "irqs.h"
39
40#define NAS100D_SDA_PIN 5
41#define NAS100D_SCL_PIN 6
42
43
44#define NAS100D_PB_GPIO 14
45#define NAS100D_RB_GPIO 4
46
47
48#define NAS100D_PO_GPIO 12
49
50
51#define NAS100D_LED_WLAN_GPIO 0
52#define NAS100D_LED_DISK_GPIO 3
53#define NAS100D_LED_PWR_GPIO 15
54
55static struct flash_platform_data nas100d_flash_data = {
56 .map_name = "cfi_probe",
57 .width = 2,
58};
59
60static struct resource nas100d_flash_resource = {
61 .flags = IORESOURCE_MEM,
62};
63
64static struct platform_device nas100d_flash = {
65 .name = "IXP4XX-Flash",
66 .id = 0,
67 .dev.platform_data = &nas100d_flash_data,
68 .num_resources = 1,
69 .resource = &nas100d_flash_resource,
70};
71
72static struct i2c_board_info __initdata nas100d_i2c_board_info [] = {
73 {
74 I2C_BOARD_INFO("pcf8563", 0x51),
75 },
76};
77
78static struct gpio_led nas100d_led_pins[] = {
79 {
80 .name = "nas100d:green:wlan",
81 .gpio = NAS100D_LED_WLAN_GPIO,
82 .active_low = true,
83 },
84 {
85 .name = "nas100d:blue:power",
86 .gpio = NAS100D_LED_PWR_GPIO,
87 .active_low = true,
88 },
89 {
90 .name = "nas100d:yellow:disk",
91 .gpio = NAS100D_LED_DISK_GPIO,
92 .active_low = true,
93 },
94};
95
96static struct gpio_led_platform_data nas100d_led_data = {
97 .num_leds = ARRAY_SIZE(nas100d_led_pins),
98 .leds = nas100d_led_pins,
99};
100
101static struct platform_device nas100d_leds = {
102 .name = "leds-gpio",
103 .id = -1,
104 .dev.platform_data = &nas100d_led_data,
105};
106
107static struct gpiod_lookup_table nas100d_i2c_gpiod_table = {
108 .dev_id = "i2c-gpio.0",
109 .table = {
110 GPIO_LOOKUP_IDX("IXP4XX_GPIO_CHIP", NAS100D_SDA_PIN,
111 NULL, 0, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
112 GPIO_LOOKUP_IDX("IXP4XX_GPIO_CHIP", NAS100D_SCL_PIN,
113 NULL, 1, GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN),
114 },
115};
116
117static struct platform_device nas100d_i2c_gpio = {
118 .name = "i2c-gpio",
119 .id = 0,
120 .dev = {
121 .platform_data = NULL,
122 },
123};
124
125static struct resource nas100d_uart_resources[] = {
126 {
127 .start = IXP4XX_UART1_BASE_PHYS,
128 .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
129 .flags = IORESOURCE_MEM,
130 },
131 {
132 .start = IXP4XX_UART2_BASE_PHYS,
133 .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
134 .flags = IORESOURCE_MEM,
135 }
136};
137
138static struct plat_serial8250_port nas100d_uart_data[] = {
139 {
140 .mapbase = IXP4XX_UART1_BASE_PHYS,
141 .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
142 .irq = IRQ_IXP4XX_UART1,
143 .flags = UPF_BOOT_AUTOCONF,
144 .iotype = UPIO_MEM,
145 .regshift = 2,
146 .uartclk = IXP4XX_UART_XTAL,
147 },
148 {
149 .mapbase = IXP4XX_UART2_BASE_PHYS,
150 .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
151 .irq = IRQ_IXP4XX_UART2,
152 .flags = UPF_BOOT_AUTOCONF,
153 .iotype = UPIO_MEM,
154 .regshift = 2,
155 .uartclk = IXP4XX_UART_XTAL,
156 },
157 { }
158};
159
160static struct platform_device nas100d_uart = {
161 .name = "serial8250",
162 .id = PLAT8250_DEV_PLATFORM,
163 .dev.platform_data = nas100d_uart_data,
164 .num_resources = 2,
165 .resource = nas100d_uart_resources,
166};
167
168
169static struct resource nas100d_eth_resources[] = {
170 {
171 .start = IXP4XX_EthB_BASE_PHYS,
172 .end = IXP4XX_EthB_BASE_PHYS + 0x0fff,
173 .flags = IORESOURCE_MEM,
174 },
175};
176
177static struct eth_plat_info nas100d_plat_eth[] = {
178 {
179 .phy = 0,
180 .rxq = 3,
181 .txreadyq = 20,
182 }
183};
184
185static struct platform_device nas100d_eth[] = {
186 {
187 .name = "ixp4xx_eth",
188 .id = IXP4XX_ETH_NPEB,
189 .dev.platform_data = nas100d_plat_eth,
190 .num_resources = ARRAY_SIZE(nas100d_eth_resources),
191 .resource = nas100d_eth_resources,
192 }
193};
194
195static struct platform_device *nas100d_devices[] __initdata = {
196 &nas100d_i2c_gpio,
197 &nas100d_flash,
198 &nas100d_leds,
199 &nas100d_eth[0],
200};
201
202static void nas100d_power_off(void)
203{
204
205
206
207 gpio_direction_output(NAS100D_PO_GPIO, 1);
208}
209
210
211
212
213static int power_button_countdown;
214
215
216#define PBUTTON_HOLDDOWN_COUNT 4
217
218static void nas100d_power_handler(struct timer_list *unused);
219static DEFINE_TIMER(nas100d_power_timer, nas100d_power_handler);
220
221static void nas100d_power_handler(struct timer_list *unused)
222{
223
224
225
226
227 if (gpio_get_value(NAS100D_PB_GPIO)) {
228
229
230 if (power_button_countdown > 0)
231 power_button_countdown--;
232
233 } else {
234
235
236 if (power_button_countdown == 0) {
237
238
239
240
241 ctrl_alt_del();
242
243
244 gpio_set_value(NAS100D_LED_PWR_GPIO, 0);
245 } else {
246 power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
247 }
248 }
249
250 mod_timer(&nas100d_power_timer, jiffies + msecs_to_jiffies(500));
251}
252
253static irqreturn_t nas100d_reset_handler(int irq, void *dev_id)
254{
255
256 machine_power_off();
257
258 return IRQ_HANDLED;
259}
260
261static int __init nas100d_gpio_init(void)
262{
263 if (!machine_is_nas100d())
264 return 0;
265
266
267
268
269
270
271
272
273 gpio_request(NAS100D_PO_GPIO, "power off");
274
275
276 gpio_request(NAS100D_PB_GPIO, "power button");
277 gpio_direction_input(NAS100D_PB_GPIO);
278
279
280 power_button_countdown = PBUTTON_HOLDDOWN_COUNT;
281
282 mod_timer(&nas100d_power_timer, jiffies + msecs_to_jiffies(500));
283
284 return 0;
285}
286device_initcall(nas100d_gpio_init);
287
288static void __init nas100d_init(void)
289{
290 uint8_t __iomem *f;
291 int i;
292
293 ixp4xx_sys_init();
294
295 nas100d_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
296 nas100d_flash_resource.end =
297 IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
298
299 gpiod_add_lookup_table(&nas100d_i2c_gpiod_table);
300 i2c_register_board_info(0, nas100d_i2c_board_info,
301 ARRAY_SIZE(nas100d_i2c_board_info));
302
303
304
305
306
307
308 (void)platform_device_register(&nas100d_uart);
309
310 platform_add_devices(nas100d_devices, ARRAY_SIZE(nas100d_devices));
311
312 pm_power_off = nas100d_power_off;
313
314 if (request_irq(gpio_to_irq(NAS100D_RB_GPIO), &nas100d_reset_handler,
315 IRQF_TRIGGER_LOW, "NAS100D reset button", NULL) < 0) {
316
317 printk(KERN_DEBUG "Reset Button IRQ %d not available\n",
318 gpio_to_irq(NAS100D_RB_GPIO));
319 }
320
321
322
323
324
325
326 f = ioremap(IXP4XX_EXP_BUS_BASE(0), 0x1000000);
327 if (f) {
328 for (i = 0; i < 6; i++)
329#ifdef __ARMEB__
330 nas100d_plat_eth[0].hwaddr[i] = readb(f + 0xFC0FD8 + i);
331#else
332 nas100d_plat_eth[0].hwaddr[i] = readb(f + 0xFC0FD8 + (i^3));
333#endif
334 iounmap(f);
335 }
336 printk(KERN_INFO "NAS100D: Using MAC address %pM for port 0\n",
337 nas100d_plat_eth[0].hwaddr);
338
339}
340
341MACHINE_START(NAS100D, "Iomega NAS 100d")
342
343 .atag_offset = 0x100,
344 .map_io = ixp4xx_map_io,
345 .init_early = ixp4xx_init_early,
346 .init_irq = ixp4xx_init_irq,
347 .init_time = ixp4xx_timer_init,
348 .init_machine = nas100d_init,
349#if defined(CONFIG_PCI)
350 .dma_zone_size = SZ_64M,
351#endif
352 .restart = ixp4xx_restart,
353MACHINE_END
354