0001
0002
0003
0004
0005
0006
0007 #include <linux/init.h>
0008 #include <linux/types.h>
0009 #include <linux/delay.h>
0010 #include <linux/dma-mapping.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/mtd/physmap.h>
0013 #include <linux/serial.h>
0014 #include <linux/serial_8250.h>
0015 #include <linux/ioport.h>
0016 #include <linux/io.h>
0017 #include <linux/vlynq.h>
0018 #include <linux/leds.h>
0019 #include <linux/string.h>
0020 #include <linux/etherdevice.h>
0021 #include <linux/phy.h>
0022 #include <linux/phy_fixed.h>
0023 #include <linux/gpio.h>
0024 #include <linux/clk.h>
0025
0026 #include <asm/addrspace.h>
0027 #include <asm/mach-ar7/ar7.h>
0028 #include <asm/mach-ar7/prom.h>
0029
0030
0031
0032
0033 struct plat_vlynq_data {
0034 struct plat_vlynq_ops ops;
0035 int gpio_bit;
0036 int reset_bit;
0037 };
0038
0039 static int vlynq_on(struct vlynq_device *dev)
0040 {
0041 int ret;
0042 struct plat_vlynq_data *pdata = dev->dev.platform_data;
0043
0044 ret = gpio_request(pdata->gpio_bit, "vlynq");
0045 if (ret)
0046 goto out;
0047
0048 ar7_device_reset(pdata->reset_bit);
0049
0050 ret = ar7_gpio_disable(pdata->gpio_bit);
0051 if (ret)
0052 goto out_enabled;
0053
0054 ret = ar7_gpio_enable(pdata->gpio_bit);
0055 if (ret)
0056 goto out_enabled;
0057
0058 ret = gpio_direction_output(pdata->gpio_bit, 0);
0059 if (ret)
0060 goto out_gpio_enabled;
0061
0062 msleep(50);
0063
0064 gpio_set_value(pdata->gpio_bit, 1);
0065
0066 msleep(50);
0067
0068 return 0;
0069
0070 out_gpio_enabled:
0071 ar7_gpio_disable(pdata->gpio_bit);
0072 out_enabled:
0073 ar7_device_disable(pdata->reset_bit);
0074 gpio_free(pdata->gpio_bit);
0075 out:
0076 return ret;
0077 }
0078
0079 static void vlynq_off(struct vlynq_device *dev)
0080 {
0081 struct plat_vlynq_data *pdata = dev->dev.platform_data;
0082
0083 ar7_gpio_disable(pdata->gpio_bit);
0084 gpio_free(pdata->gpio_bit);
0085 ar7_device_disable(pdata->reset_bit);
0086 }
0087
0088 static struct resource vlynq_low_res[] = {
0089 {
0090 .name = "regs",
0091 .flags = IORESOURCE_MEM,
0092 .start = AR7_REGS_VLYNQ0,
0093 .end = AR7_REGS_VLYNQ0 + 0xff,
0094 },
0095 {
0096 .name = "irq",
0097 .flags = IORESOURCE_IRQ,
0098 .start = 29,
0099 .end = 29,
0100 },
0101 {
0102 .name = "mem",
0103 .flags = IORESOURCE_MEM,
0104 .start = 0x04000000,
0105 .end = 0x04ffffff,
0106 },
0107 {
0108 .name = "devirq",
0109 .flags = IORESOURCE_IRQ,
0110 .start = 80,
0111 .end = 111,
0112 },
0113 };
0114
0115 static struct resource vlynq_high_res[] = {
0116 {
0117 .name = "regs",
0118 .flags = IORESOURCE_MEM,
0119 .start = AR7_REGS_VLYNQ1,
0120 .end = AR7_REGS_VLYNQ1 + 0xff,
0121 },
0122 {
0123 .name = "irq",
0124 .flags = IORESOURCE_IRQ,
0125 .start = 33,
0126 .end = 33,
0127 },
0128 {
0129 .name = "mem",
0130 .flags = IORESOURCE_MEM,
0131 .start = 0x0c000000,
0132 .end = 0x0cffffff,
0133 },
0134 {
0135 .name = "devirq",
0136 .flags = IORESOURCE_IRQ,
0137 .start = 112,
0138 .end = 143,
0139 },
0140 };
0141
0142 static struct plat_vlynq_data vlynq_low_data = {
0143 .ops = {
0144 .on = vlynq_on,
0145 .off = vlynq_off,
0146 },
0147 .reset_bit = 20,
0148 .gpio_bit = 18,
0149 };
0150
0151 static struct plat_vlynq_data vlynq_high_data = {
0152 .ops = {
0153 .on = vlynq_on,
0154 .off = vlynq_off,
0155 },
0156 .reset_bit = 16,
0157 .gpio_bit = 19,
0158 };
0159
0160 static struct platform_device vlynq_low = {
0161 .id = 0,
0162 .name = "vlynq",
0163 .dev = {
0164 .platform_data = &vlynq_low_data,
0165 },
0166 .resource = vlynq_low_res,
0167 .num_resources = ARRAY_SIZE(vlynq_low_res),
0168 };
0169
0170 static struct platform_device vlynq_high = {
0171 .id = 1,
0172 .name = "vlynq",
0173 .dev = {
0174 .platform_data = &vlynq_high_data,
0175 },
0176 .resource = vlynq_high_res,
0177 .num_resources = ARRAY_SIZE(vlynq_high_res),
0178 };
0179
0180
0181
0182
0183 static struct resource physmap_flash_resource = {
0184 .name = "mem",
0185 .flags = IORESOURCE_MEM,
0186 .start = 0x10000000,
0187 .end = 0x107fffff,
0188 };
0189
0190 static const char *ar7_probe_types[] = { "ar7part", NULL };
0191
0192 static struct physmap_flash_data physmap_flash_data = {
0193 .width = 2,
0194 .part_probe_types = ar7_probe_types,
0195 };
0196
0197 static struct platform_device physmap_flash = {
0198 .name = "physmap-flash",
0199 .dev = {
0200 .platform_data = &physmap_flash_data,
0201 },
0202 .resource = &physmap_flash_resource,
0203 .num_resources = 1,
0204 };
0205
0206
0207
0208
0209 static struct resource cpmac_low_res[] = {
0210 {
0211 .name = "regs",
0212 .flags = IORESOURCE_MEM,
0213 .start = AR7_REGS_MAC0,
0214 .end = AR7_REGS_MAC0 + 0x7ff,
0215 },
0216 {
0217 .name = "irq",
0218 .flags = IORESOURCE_IRQ,
0219 .start = 27,
0220 .end = 27,
0221 },
0222 };
0223
0224 static struct resource cpmac_high_res[] = {
0225 {
0226 .name = "regs",
0227 .flags = IORESOURCE_MEM,
0228 .start = AR7_REGS_MAC1,
0229 .end = AR7_REGS_MAC1 + 0x7ff,
0230 },
0231 {
0232 .name = "irq",
0233 .flags = IORESOURCE_IRQ,
0234 .start = 41,
0235 .end = 41,
0236 },
0237 };
0238
0239 static struct fixed_phy_status fixed_phy_status __initdata = {
0240 .link = 1,
0241 .speed = 100,
0242 .duplex = 1,
0243 };
0244
0245 static struct plat_cpmac_data cpmac_low_data = {
0246 .reset_bit = 17,
0247 .power_bit = 20,
0248 .phy_mask = 0x80000000,
0249 };
0250
0251 static struct plat_cpmac_data cpmac_high_data = {
0252 .reset_bit = 21,
0253 .power_bit = 22,
0254 .phy_mask = 0x7fffffff,
0255 };
0256
0257 static u64 cpmac_dma_mask = DMA_BIT_MASK(32);
0258
0259 static struct platform_device cpmac_low = {
0260 .id = 0,
0261 .name = "cpmac",
0262 .dev = {
0263 .dma_mask = &cpmac_dma_mask,
0264 .coherent_dma_mask = DMA_BIT_MASK(32),
0265 .platform_data = &cpmac_low_data,
0266 },
0267 .resource = cpmac_low_res,
0268 .num_resources = ARRAY_SIZE(cpmac_low_res),
0269 };
0270
0271 static struct platform_device cpmac_high = {
0272 .id = 1,
0273 .name = "cpmac",
0274 .dev = {
0275 .dma_mask = &cpmac_dma_mask,
0276 .coherent_dma_mask = DMA_BIT_MASK(32),
0277 .platform_data = &cpmac_high_data,
0278 },
0279 .resource = cpmac_high_res,
0280 .num_resources = ARRAY_SIZE(cpmac_high_res),
0281 };
0282
0283 static void __init cpmac_get_mac(int instance, unsigned char *dev_addr)
0284 {
0285 char name[5], *mac;
0286
0287 sprintf(name, "mac%c", 'a' + instance);
0288 mac = prom_getenv(name);
0289 if (!mac && instance) {
0290 sprintf(name, "mac%c", 'a');
0291 mac = prom_getenv(name);
0292 }
0293
0294 if (mac) {
0295 if (!mac_pton(mac, dev_addr)) {
0296 pr_warn("cannot parse mac address, using random address\n");
0297 eth_random_addr(dev_addr);
0298 }
0299 } else
0300 eth_random_addr(dev_addr);
0301 }
0302
0303
0304
0305
0306 static struct resource usb_res[] = {
0307 {
0308 .name = "regs",
0309 .flags = IORESOURCE_MEM,
0310 .start = AR7_REGS_USB,
0311 .end = AR7_REGS_USB + 0xff,
0312 },
0313 {
0314 .name = "irq",
0315 .flags = IORESOURCE_IRQ,
0316 .start = 32,
0317 .end = 32,
0318 },
0319 {
0320 .name = "mem",
0321 .flags = IORESOURCE_MEM,
0322 .start = 0x03400000,
0323 .end = 0x03401fff,
0324 },
0325 };
0326
0327 static struct platform_device ar7_udc = {
0328 .name = "ar7_udc",
0329 .resource = usb_res,
0330 .num_resources = ARRAY_SIZE(usb_res),
0331 };
0332
0333
0334
0335
0336 static const struct gpio_led default_leds[] = {
0337 {
0338 .name = "status",
0339 .gpio = 8,
0340 .active_low = 1,
0341 },
0342 };
0343
0344 static const struct gpio_led titan_leds[] = {
0345 { .name = "status", .gpio = 8, .active_low = 1, },
0346 { .name = "wifi", .gpio = 13, .active_low = 1, },
0347 };
0348
0349 static const struct gpio_led dsl502t_leds[] = {
0350 {
0351 .name = "status",
0352 .gpio = 9,
0353 .active_low = 1,
0354 },
0355 {
0356 .name = "ethernet",
0357 .gpio = 7,
0358 .active_low = 1,
0359 },
0360 {
0361 .name = "usb",
0362 .gpio = 12,
0363 .active_low = 1,
0364 },
0365 };
0366
0367 static const struct gpio_led dg834g_leds[] = {
0368 {
0369 .name = "ppp",
0370 .gpio = 6,
0371 .active_low = 1,
0372 },
0373 {
0374 .name = "status",
0375 .gpio = 7,
0376 .active_low = 1,
0377 },
0378 {
0379 .name = "adsl",
0380 .gpio = 8,
0381 .active_low = 1,
0382 },
0383 {
0384 .name = "wifi",
0385 .gpio = 12,
0386 .active_low = 1,
0387 },
0388 {
0389 .name = "power",
0390 .gpio = 14,
0391 .active_low = 1,
0392 .default_trigger = "default-on",
0393 },
0394 };
0395
0396 static const struct gpio_led fb_sl_leds[] = {
0397 {
0398 .name = "1",
0399 .gpio = 7,
0400 },
0401 {
0402 .name = "2",
0403 .gpio = 13,
0404 .active_low = 1,
0405 },
0406 {
0407 .name = "3",
0408 .gpio = 10,
0409 .active_low = 1,
0410 },
0411 {
0412 .name = "4",
0413 .gpio = 12,
0414 .active_low = 1,
0415 },
0416 {
0417 .name = "5",
0418 .gpio = 9,
0419 .active_low = 1,
0420 },
0421 };
0422
0423 static const struct gpio_led fb_fon_leds[] = {
0424 {
0425 .name = "1",
0426 .gpio = 8,
0427 },
0428 {
0429 .name = "2",
0430 .gpio = 3,
0431 .active_low = 1,
0432 },
0433 {
0434 .name = "3",
0435 .gpio = 5,
0436 },
0437 {
0438 .name = "4",
0439 .gpio = 4,
0440 .active_low = 1,
0441 },
0442 {
0443 .name = "5",
0444 .gpio = 11,
0445 .active_low = 1,
0446 },
0447 };
0448
0449 static const struct gpio_led gt701_leds[] = {
0450 {
0451 .name = "inet:green",
0452 .gpio = 13,
0453 .active_low = 1,
0454 },
0455 {
0456 .name = "usb",
0457 .gpio = 12,
0458 .active_low = 1,
0459 },
0460 {
0461 .name = "inet:red",
0462 .gpio = 9,
0463 .active_low = 1,
0464 },
0465 {
0466 .name = "power:red",
0467 .gpio = 7,
0468 .active_low = 1,
0469 },
0470 {
0471 .name = "power:green",
0472 .gpio = 8,
0473 .active_low = 1,
0474 .default_trigger = "default-on",
0475 },
0476 {
0477 .name = "ethernet",
0478 .gpio = 10,
0479 .active_low = 1,
0480 },
0481 };
0482
0483 static struct gpio_led_platform_data ar7_led_data;
0484
0485 static struct platform_device ar7_gpio_leds = {
0486 .name = "leds-gpio",
0487 .dev = {
0488 .platform_data = &ar7_led_data,
0489 }
0490 };
0491
0492 static void __init detect_leds(void)
0493 {
0494 char *prid, *usb_prod;
0495
0496
0497 ar7_led_data.num_leds = ARRAY_SIZE(default_leds);
0498 ar7_led_data.leds = default_leds;
0499
0500
0501 prid = prom_getenv("ProductID");
0502 usb_prod = prom_getenv("usb_prod");
0503
0504
0505 if (!prid)
0506 return;
0507
0508 if (strstr(prid, "Fritz_Box_FON")) {
0509 ar7_led_data.num_leds = ARRAY_SIZE(fb_fon_leds);
0510 ar7_led_data.leds = fb_fon_leds;
0511 } else if (strstr(prid, "Fritz_Box_")) {
0512 ar7_led_data.num_leds = ARRAY_SIZE(fb_sl_leds);
0513 ar7_led_data.leds = fb_sl_leds;
0514 } else if ((!strcmp(prid, "AR7RD") || !strcmp(prid, "AR7DB"))
0515 && usb_prod != NULL && strstr(usb_prod, "DSL-502T")) {
0516 ar7_led_data.num_leds = ARRAY_SIZE(dsl502t_leds);
0517 ar7_led_data.leds = dsl502t_leds;
0518 } else if (strstr(prid, "DG834")) {
0519 ar7_led_data.num_leds = ARRAY_SIZE(dg834g_leds);
0520 ar7_led_data.leds = dg834g_leds;
0521 } else if (strstr(prid, "CYWM") || strstr(prid, "CYWL")) {
0522 ar7_led_data.num_leds = ARRAY_SIZE(titan_leds);
0523 ar7_led_data.leds = titan_leds;
0524 } else if (strstr(prid, "GT701")) {
0525 ar7_led_data.num_leds = ARRAY_SIZE(gt701_leds);
0526 ar7_led_data.leds = gt701_leds;
0527 }
0528 }
0529
0530
0531
0532
0533 static struct resource ar7_wdt_res = {
0534 .name = "regs",
0535 .flags = IORESOURCE_MEM,
0536 .start = -1,
0537 .end = -1,
0538 };
0539
0540 static struct platform_device ar7_wdt = {
0541 .name = "ar7_wdt",
0542 .resource = &ar7_wdt_res,
0543 .num_resources = 1,
0544 };
0545
0546
0547
0548
0549 static int __init ar7_register_uarts(void)
0550 {
0551 #ifdef CONFIG_SERIAL_8250
0552 static struct uart_port uart_port __initdata;
0553 struct clk *bus_clk;
0554 int res;
0555
0556 memset(&uart_port, 0, sizeof(struct uart_port));
0557
0558 bus_clk = clk_get(NULL, "bus");
0559 if (IS_ERR(bus_clk))
0560 panic("unable to get bus clk");
0561
0562 uart_port.type = PORT_AR7;
0563 uart_port.uartclk = clk_get_rate(bus_clk) / 2;
0564 uart_port.iotype = UPIO_MEM32;
0565 uart_port.flags = UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF;
0566 uart_port.regshift = 2;
0567
0568 uart_port.line = 0;
0569 uart_port.irq = AR7_IRQ_UART0;
0570 uart_port.mapbase = AR7_REGS_UART0;
0571 uart_port.membase = ioremap(uart_port.mapbase, 256);
0572
0573 res = early_serial_setup(&uart_port);
0574 if (res)
0575 return res;
0576
0577
0578 if (ar7_has_second_uart()) {
0579 uart_port.line = 1;
0580 uart_port.irq = AR7_IRQ_UART1;
0581 uart_port.mapbase = UR8_REGS_UART1;
0582 uart_port.membase = ioremap(uart_port.mapbase, 256);
0583
0584 res = early_serial_setup(&uart_port);
0585 if (res)
0586 return res;
0587 }
0588 #endif
0589
0590 return 0;
0591 }
0592
0593 static void __init titan_fixup_devices(void)
0594 {
0595
0596 vlynq_low_data.reset_bit = 15;
0597 vlynq_low_data.gpio_bit = 14;
0598
0599
0600 vlynq_high_data.reset_bit = 16;
0601 vlynq_high_data.gpio_bit = 7;
0602
0603
0604 vlynq_low_res[0].start = TITAN_REGS_VLYNQ0;
0605 vlynq_low_res[0].end = TITAN_REGS_VLYNQ0 + 0xff;
0606 vlynq_low_res[1].start = 33;
0607 vlynq_low_res[1].end = 33;
0608 vlynq_low_res[2].start = 0x0c000000;
0609 vlynq_low_res[2].end = 0x0fffffff;
0610 vlynq_low_res[3].start = 80;
0611 vlynq_low_res[3].end = 111;
0612
0613
0614 vlynq_high_res[0].start = TITAN_REGS_VLYNQ1;
0615 vlynq_high_res[0].end = TITAN_REGS_VLYNQ1 + 0xff;
0616 vlynq_high_res[1].start = 34;
0617 vlynq_high_res[1].end = 34;
0618 vlynq_high_res[2].start = 0x40000000;
0619 vlynq_high_res[2].end = 0x43ffffff;
0620 vlynq_high_res[3].start = 112;
0621 vlynq_high_res[3].end = 143;
0622
0623
0624 cpmac_low_data.phy_mask = 0x40000000;
0625
0626
0627 cpmac_high_data.phy_mask = 0x80000000;
0628
0629
0630 cpmac_low_res[0].start = TITAN_REGS_MAC0;
0631 cpmac_low_res[0].end = TITAN_REGS_MAC0 + 0x7ff;
0632
0633
0634 cpmac_high_res[0].start = TITAN_REGS_MAC1;
0635 cpmac_high_res[0].end = TITAN_REGS_MAC1 + 0x7ff;
0636 }
0637
0638 static int __init ar7_register_devices(void)
0639 {
0640 void __iomem *bootcr;
0641 u32 val;
0642 int res;
0643
0644 res = ar7_gpio_init();
0645 if (res)
0646 pr_warn("unable to register gpios: %d\n", res);
0647
0648 res = ar7_register_uarts();
0649 if (res)
0650 pr_err("unable to setup uart(s): %d\n", res);
0651
0652 res = platform_device_register(&physmap_flash);
0653 if (res)
0654 pr_warn("unable to register physmap-flash: %d\n", res);
0655
0656 if (ar7_is_titan())
0657 titan_fixup_devices();
0658
0659 ar7_device_disable(vlynq_low_data.reset_bit);
0660 res = platform_device_register(&vlynq_low);
0661 if (res)
0662 pr_warn("unable to register vlynq-low: %d\n", res);
0663
0664 if (ar7_has_high_vlynq()) {
0665 ar7_device_disable(vlynq_high_data.reset_bit);
0666 res = platform_device_register(&vlynq_high);
0667 if (res)
0668 pr_warn("unable to register vlynq-high: %d\n", res);
0669 }
0670
0671 if (ar7_has_high_cpmac()) {
0672 res = fixed_phy_add(PHY_POLL, cpmac_high.id,
0673 &fixed_phy_status);
0674 if (!res) {
0675 cpmac_get_mac(1, cpmac_high_data.dev_addr);
0676
0677 res = platform_device_register(&cpmac_high);
0678 if (res)
0679 pr_warn("unable to register cpmac-high: %d\n",
0680 res);
0681 } else
0682 pr_warn("unable to add cpmac-high phy: %d\n", res);
0683 } else
0684 cpmac_low_data.phy_mask = 0xffffffff;
0685
0686 res = fixed_phy_add(PHY_POLL, cpmac_low.id, &fixed_phy_status);
0687 if (!res) {
0688 cpmac_get_mac(0, cpmac_low_data.dev_addr);
0689 res = platform_device_register(&cpmac_low);
0690 if (res)
0691 pr_warn("unable to register cpmac-low: %d\n", res);
0692 } else
0693 pr_warn("unable to add cpmac-low phy: %d\n", res);
0694
0695 detect_leds();
0696 res = platform_device_register(&ar7_gpio_leds);
0697 if (res)
0698 pr_warn("unable to register leds: %d\n", res);
0699
0700 res = platform_device_register(&ar7_udc);
0701 if (res)
0702 pr_warn("unable to register usb slave: %d\n", res);
0703
0704
0705 bootcr = ioremap(AR7_REGS_DCL, 4);
0706 val = readl(bootcr);
0707 iounmap(bootcr);
0708 if (val & AR7_WDT_HW_ENA) {
0709 if (ar7_has_high_vlynq())
0710 ar7_wdt_res.start = UR8_REGS_WDT;
0711 else
0712 ar7_wdt_res.start = AR7_REGS_WDT;
0713
0714 ar7_wdt_res.end = ar7_wdt_res.start + 0x20;
0715 res = platform_device_register(&ar7_wdt);
0716 if (res)
0717 pr_warn("unable to register watchdog: %d\n", res);
0718 }
0719
0720 return 0;
0721 }
0722 device_initcall(ar7_register_devices);