linux/arch/mips/ar7/platform.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2006,2007 Felix Fietkau <nbd@openwrt.org>
   3 * Copyright (C) 2006,2007 Eugene Konev <ejka@openwrt.org>
   4 *
   5 * This program is free software; you can redistribute it and/or modify
   6 * it under the terms of the GNU General Public License as published by
   7 * the Free Software Foundation; either version 2 of the License, or
   8 * (at your option) any later version.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU 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  02110-1301  USA
  18 */
  19
  20#include <linux/init.h>
  21#include <linux/types.h>
  22#include <linux/module.h>
  23#include <linux/delay.h>
  24#include <linux/dma-mapping.h>
  25#include <linux/platform_device.h>
  26#include <linux/mtd/physmap.h>
  27#include <linux/serial.h>
  28#include <linux/serial_8250.h>
  29#include <linux/ioport.h>
  30#include <linux/io.h>
  31#include <linux/vlynq.h>
  32#include <linux/leds.h>
  33#include <linux/string.h>
  34#include <linux/etherdevice.h>
  35#include <linux/phy.h>
  36#include <linux/phy_fixed.h>
  37#include <linux/gpio.h>
  38#include <linux/clk.h>
  39
  40#include <asm/addrspace.h>
  41#include <asm/mach-ar7/ar7.h>
  42#include <asm/mach-ar7/gpio.h>
  43#include <asm/mach-ar7/prom.h>
  44
  45/*****************************************************************************
  46 * VLYNQ Bus
  47 ****************************************************************************/
  48struct plat_vlynq_data {
  49        struct plat_vlynq_ops ops;
  50        int gpio_bit;
  51        int reset_bit;
  52};
  53
  54static int vlynq_on(struct vlynq_device *dev)
  55{
  56        int ret;
  57        struct plat_vlynq_data *pdata = dev->dev.platform_data;
  58
  59        ret = gpio_request(pdata->gpio_bit, "vlynq");
  60        if (ret)
  61                goto out;
  62
  63        ar7_device_reset(pdata->reset_bit);
  64
  65        ret = ar7_gpio_disable(pdata->gpio_bit);
  66        if (ret)
  67                goto out_enabled;
  68
  69        ret = ar7_gpio_enable(pdata->gpio_bit);
  70        if (ret)
  71                goto out_enabled;
  72
  73        ret = gpio_direction_output(pdata->gpio_bit, 0);
  74        if (ret)
  75                goto out_gpio_enabled;
  76
  77        msleep(50);
  78
  79        gpio_set_value(pdata->gpio_bit, 1);
  80
  81        msleep(50);
  82
  83        return 0;
  84
  85out_gpio_enabled:
  86        ar7_gpio_disable(pdata->gpio_bit);
  87out_enabled:
  88        ar7_device_disable(pdata->reset_bit);
  89        gpio_free(pdata->gpio_bit);
  90out:
  91        return ret;
  92}
  93
  94static void vlynq_off(struct vlynq_device *dev)
  95{
  96        struct plat_vlynq_data *pdata = dev->dev.platform_data;
  97
  98        ar7_gpio_disable(pdata->gpio_bit);
  99        gpio_free(pdata->gpio_bit);
 100        ar7_device_disable(pdata->reset_bit);
 101}
 102
 103static struct resource vlynq_low_res[] = {
 104        {
 105                .name   = "regs",
 106                .flags  = IORESOURCE_MEM,
 107                .start  = AR7_REGS_VLYNQ0,
 108                .end    = AR7_REGS_VLYNQ0 + 0xff,
 109        },
 110        {
 111                .name   = "irq",
 112                .flags  = IORESOURCE_IRQ,
 113                .start  = 29,
 114                .end    = 29,
 115        },
 116        {
 117                .name   = "mem",
 118                .flags  = IORESOURCE_MEM,
 119                .start  = 0x04000000,
 120                .end    = 0x04ffffff,
 121        },
 122        {
 123                .name   = "devirq",
 124                .flags  = IORESOURCE_IRQ,
 125                .start  = 80,
 126                .end    = 111,
 127        },
 128};
 129
 130static struct resource vlynq_high_res[] = {
 131        {
 132                .name   = "regs",
 133                .flags  = IORESOURCE_MEM,
 134                .start  = AR7_REGS_VLYNQ1,
 135                .end    = AR7_REGS_VLYNQ1 + 0xff,
 136        },
 137        {
 138                .name   = "irq",
 139                .flags  = IORESOURCE_IRQ,
 140                .start  = 33,
 141                .end    = 33,
 142        },
 143        {
 144                .name   = "mem",
 145                .flags  = IORESOURCE_MEM,
 146                .start  = 0x0c000000,
 147                .end    = 0x0cffffff,
 148        },
 149        {
 150                .name   = "devirq",
 151                .flags  = IORESOURCE_IRQ,
 152                .start  = 112,
 153                .end    = 143,
 154        },
 155};
 156
 157static struct plat_vlynq_data vlynq_low_data = {
 158        .ops = {
 159                .on     = vlynq_on,
 160                .off    = vlynq_off,
 161        },
 162        .reset_bit      = 20,
 163        .gpio_bit       = 18,
 164};
 165
 166static struct plat_vlynq_data vlynq_high_data = {
 167        .ops = {
 168                .on     = vlynq_on,
 169                .off    = vlynq_off,
 170        },
 171        .reset_bit      = 16,
 172        .gpio_bit       = 19,
 173};
 174
 175static struct platform_device vlynq_low = {
 176        .id             = 0,
 177        .name           = "vlynq",
 178        .dev = {
 179                .platform_data  = &vlynq_low_data,
 180        },
 181        .resource       = vlynq_low_res,
 182        .num_resources  = ARRAY_SIZE(vlynq_low_res),
 183};
 184
 185static struct platform_device vlynq_high = {
 186        .id             = 1,
 187        .name           = "vlynq",
 188        .dev = {
 189                .platform_data  = &vlynq_high_data,
 190        },
 191        .resource       = vlynq_high_res,
 192        .num_resources  = ARRAY_SIZE(vlynq_high_res),
 193};
 194
 195/*****************************************************************************
 196 * Flash
 197 ****************************************************************************/
 198static struct resource physmap_flash_resource = {
 199        .name   = "mem",
 200        .flags  = IORESOURCE_MEM,
 201        .start  = 0x10000000,
 202        .end    = 0x107fffff,
 203};
 204
 205static const char *ar7_probe_types[] = { "ar7part", NULL };
 206
 207static struct physmap_flash_data physmap_flash_data = {
 208        .width  = 2,
 209        .part_probe_types = ar7_probe_types,
 210};
 211
 212static struct platform_device physmap_flash = {
 213        .name           = "physmap-flash",
 214        .dev = {
 215                .platform_data  = &physmap_flash_data,
 216        },
 217        .resource       = &physmap_flash_resource,
 218        .num_resources  = 1,
 219};
 220
 221/*****************************************************************************
 222 * Ethernet
 223 ****************************************************************************/
 224static struct resource cpmac_low_res[] = {
 225        {
 226                .name   = "regs",
 227                .flags  = IORESOURCE_MEM,
 228                .start  = AR7_REGS_MAC0,
 229                .end    = AR7_REGS_MAC0 + 0x7ff,
 230        },
 231        {
 232                .name   = "irq",
 233                .flags  = IORESOURCE_IRQ,
 234                .start  = 27,
 235                .end    = 27,
 236        },
 237};
 238
 239static struct resource cpmac_high_res[] = {
 240        {
 241                .name   = "regs",
 242                .flags  = IORESOURCE_MEM,
 243                .start  = AR7_REGS_MAC1,
 244                .end    = AR7_REGS_MAC1 + 0x7ff,
 245        },
 246        {
 247                .name   = "irq",
 248                .flags  = IORESOURCE_IRQ,
 249                .start  = 41,
 250                .end    = 41,
 251        },
 252};
 253
 254static struct fixed_phy_status fixed_phy_status __initdata = {
 255        .link           = 1,
 256        .speed          = 100,
 257        .duplex         = 1,
 258};
 259
 260static struct plat_cpmac_data cpmac_low_data = {
 261        .reset_bit      = 17,
 262        .power_bit      = 20,
 263        .phy_mask       = 0x80000000,
 264};
 265
 266static struct plat_cpmac_data cpmac_high_data = {
 267        .reset_bit      = 21,
 268        .power_bit      = 22,
 269        .phy_mask       = 0x7fffffff,
 270};
 271
 272static u64 cpmac_dma_mask = DMA_BIT_MASK(32);
 273
 274static struct platform_device cpmac_low = {
 275        .id             = 0,
 276        .name           = "cpmac",
 277        .dev = {
 278                .dma_mask               = &cpmac_dma_mask,
 279                .coherent_dma_mask      = DMA_BIT_MASK(32),
 280                .platform_data          = &cpmac_low_data,
 281        },
 282        .resource       = cpmac_low_res,
 283        .num_resources  = ARRAY_SIZE(cpmac_low_res),
 284};
 285
 286static struct platform_device cpmac_high = {
 287        .id             = 1,
 288        .name           = "cpmac",
 289        .dev = {
 290                .dma_mask               = &cpmac_dma_mask,
 291                .coherent_dma_mask      = DMA_BIT_MASK(32),
 292                .platform_data          = &cpmac_high_data,
 293        },
 294        .resource       = cpmac_high_res,
 295        .num_resources  = ARRAY_SIZE(cpmac_high_res),
 296};
 297
 298static void __init cpmac_get_mac(int instance, unsigned char *dev_addr)
 299{
 300        char name[5], *mac;
 301
 302        sprintf(name, "mac%c", 'a' + instance);
 303        mac = prom_getenv(name);
 304        if (!mac && instance) {
 305                sprintf(name, "mac%c", 'a');
 306                mac = prom_getenv(name);
 307        }
 308
 309        if (mac) {
 310                if (sscanf(mac, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
 311                                        &dev_addr[0], &dev_addr[1],
 312                                        &dev_addr[2], &dev_addr[3],
 313                                        &dev_addr[4], &dev_addr[5]) != 6) {
 314                        pr_warning("cannot parse mac address, "
 315                                        "using random address\n");
 316                        eth_random_addr(dev_addr);
 317                }
 318        } else
 319                eth_random_addr(dev_addr);
 320}
 321
 322/*****************************************************************************
 323 * USB
 324 ****************************************************************************/
 325static struct resource usb_res[] = {
 326        {
 327                .name   = "regs",
 328                .flags  = IORESOURCE_MEM,
 329                .start  = AR7_REGS_USB,
 330                .end    = AR7_REGS_USB + 0xff,
 331        },
 332        {
 333                .name   = "irq",
 334                .flags  = IORESOURCE_IRQ,
 335                .start  = 32,
 336                .end    = 32,
 337        },
 338        {
 339                .name   = "mem",
 340                .flags  = IORESOURCE_MEM,
 341                .start  = 0x03400000,
 342                .end    = 0x03401fff,
 343        },
 344};
 345
 346static struct platform_device ar7_udc = {
 347        .name           = "ar7_udc",
 348        .resource       = usb_res,
 349        .num_resources  = ARRAY_SIZE(usb_res),
 350};
 351
 352/*****************************************************************************
 353 * LEDs
 354 ****************************************************************************/
 355static struct gpio_led default_leds[] = {
 356        {
 357                .name                   = "status",
 358                .gpio                   = 8,
 359                .active_low             = 1,
 360        },
 361};
 362
 363static struct gpio_led titan_leds[] = {
 364        { .name = "status", .gpio = 8, .active_low = 1, },
 365        { .name = "wifi", .gpio = 13, .active_low = 1, },
 366};
 367
 368static struct gpio_led dsl502t_leds[] = {
 369        {
 370                .name                   = "status",
 371                .gpio                   = 9,
 372                .active_low             = 1,
 373        },
 374        {
 375                .name                   = "ethernet",
 376                .gpio                   = 7,
 377                .active_low             = 1,
 378        },
 379        {
 380                .name                   = "usb",
 381                .gpio                   = 12,
 382                .active_low             = 1,
 383        },
 384};
 385
 386static struct gpio_led dg834g_leds[] = {
 387        {
 388                .name                   = "ppp",
 389                .gpio                   = 6,
 390                .active_low             = 1,
 391        },
 392        {
 393                .name                   = "status",
 394                .gpio                   = 7,
 395                .active_low             = 1,
 396        },
 397        {
 398                .name                   = "adsl",
 399                .gpio                   = 8,
 400                .active_low             = 1,
 401        },
 402        {
 403                .name                   = "wifi",
 404                .gpio                   = 12,
 405                .active_low             = 1,
 406        },
 407        {
 408                .name                   = "power",
 409                .gpio                   = 14,
 410                .active_low             = 1,
 411                .default_trigger        = "default-on",
 412        },
 413};
 414
 415static struct gpio_led fb_sl_leds[] = {
 416        {
 417                .name                   = "1",
 418                .gpio                   = 7,
 419        },
 420        {
 421                .name                   = "2",
 422                .gpio                   = 13,
 423                .active_low             = 1,
 424        },
 425        {
 426                .name                   = "3",
 427                .gpio                   = 10,
 428                .active_low             = 1,
 429        },
 430        {
 431                .name                   = "4",
 432                .gpio                   = 12,
 433                .active_low             = 1,
 434        },
 435        {
 436                .name                   = "5",
 437                .gpio                   = 9,
 438                .active_low             = 1,
 439        },
 440};
 441
 442static struct gpio_led fb_fon_leds[] = {
 443        {
 444                .name                   = "1",
 445                .gpio                   = 8,
 446        },
 447        {
 448                .name                   = "2",
 449                .gpio                   = 3,
 450                .active_low             = 1,
 451        },
 452        {
 453                .name                   = "3",
 454                .gpio                   = 5,
 455        },
 456        {
 457                .name                   = "4",
 458                .gpio                   = 4,
 459                .active_low             = 1,
 460        },
 461        {
 462                .name                   = "5",
 463                .gpio                   = 11,
 464                .active_low             = 1,
 465        },
 466};
 467
 468static struct gpio_led gt701_leds[] = {
 469        {
 470                .name                   = "inet:green",
 471                .gpio                   = 13,
 472                .active_low             = 1,
 473        },
 474        {
 475                .name                   = "usb",
 476                .gpio                   = 12,
 477                .active_low             = 1,
 478        },
 479        {
 480                .name                   = "inet:red",
 481                .gpio                   = 9,
 482                .active_low             = 1,
 483        },
 484        {
 485                .name                   = "power:red",
 486                .gpio                   = 7,
 487                .active_low             = 1,
 488        },
 489        {
 490                .name                   = "power:green",
 491                .gpio                   = 8,
 492                .active_low             = 1,
 493                .default_trigger        = "default-on",
 494        },
 495        {
 496                .name                   = "ethernet",
 497                .gpio                   = 10,
 498                .active_low             = 1,
 499        },
 500};
 501
 502static struct gpio_led_platform_data ar7_led_data;
 503
 504static struct platform_device ar7_gpio_leds = {
 505        .name = "leds-gpio",
 506        .dev = {
 507                .platform_data = &ar7_led_data,
 508        }
 509};
 510
 511static void __init detect_leds(void)
 512{
 513        char *prid, *usb_prod;
 514
 515        /* Default LEDs */
 516        ar7_led_data.num_leds = ARRAY_SIZE(default_leds);
 517        ar7_led_data.leds = default_leds;
 518
 519        /* FIXME: the whole thing is unreliable */
 520        prid = prom_getenv("ProductID");
 521        usb_prod = prom_getenv("usb_prod");
 522
 523        /* If we can't get the product id from PROM, use the default LEDs */
 524        if (!prid)
 525                return;
 526
 527        if (strstr(prid, "Fritz_Box_FON")) {
 528                ar7_led_data.num_leds = ARRAY_SIZE(fb_fon_leds);
 529                ar7_led_data.leds = fb_fon_leds;
 530        } else if (strstr(prid, "Fritz_Box_")) {
 531                ar7_led_data.num_leds = ARRAY_SIZE(fb_sl_leds);
 532                ar7_led_data.leds = fb_sl_leds;
 533        } else if ((!strcmp(prid, "AR7RD") || !strcmp(prid, "AR7DB"))
 534                && usb_prod != NULL && strstr(usb_prod, "DSL-502T")) {
 535                ar7_led_data.num_leds = ARRAY_SIZE(dsl502t_leds);
 536                ar7_led_data.leds = dsl502t_leds;
 537        } else if (strstr(prid, "DG834")) {
 538                ar7_led_data.num_leds = ARRAY_SIZE(dg834g_leds);
 539                ar7_led_data.leds = dg834g_leds;
 540        } else if (strstr(prid, "CYWM") || strstr(prid, "CYWL")) {
 541                ar7_led_data.num_leds = ARRAY_SIZE(titan_leds);
 542                ar7_led_data.leds = titan_leds;
 543        } else if (strstr(prid, "GT701")) {
 544                ar7_led_data.num_leds = ARRAY_SIZE(gt701_leds);
 545                ar7_led_data.leds = gt701_leds;
 546        }
 547}
 548
 549/*****************************************************************************
 550 * Watchdog
 551 ****************************************************************************/
 552static struct resource ar7_wdt_res = {
 553        .name           = "regs",
 554        .flags          = IORESOURCE_MEM,
 555        .start          = -1,   /* Filled at runtime */
 556        .end            = -1,   /* Filled at runtime */
 557};
 558
 559static struct platform_device ar7_wdt = {
 560        .name           = "ar7_wdt",
 561        .resource       = &ar7_wdt_res,
 562        .num_resources  = 1,
 563};
 564
 565/*****************************************************************************
 566 * Init
 567 ****************************************************************************/
 568static int __init ar7_register_uarts(void)
 569{
 570#ifdef CONFIG_SERIAL_8250
 571        static struct uart_port uart_port __initdata;
 572        struct clk *bus_clk;
 573        int res;
 574
 575        memset(&uart_port, 0, sizeof(struct uart_port));
 576
 577        bus_clk = clk_get(NULL, "bus");
 578        if (IS_ERR(bus_clk))
 579                panic("unable to get bus clk");
 580
 581        uart_port.type          = PORT_AR7;
 582        uart_port.uartclk       = clk_get_rate(bus_clk) / 2;
 583        uart_port.iotype        = UPIO_MEM32;
 584        uart_port.regshift      = 2;
 585
 586        uart_port.line          = 0;
 587        uart_port.irq           = AR7_IRQ_UART0;
 588        uart_port.mapbase       = AR7_REGS_UART0;
 589        uart_port.membase       = ioremap(uart_port.mapbase, 256);
 590
 591        res = early_serial_setup(&uart_port);
 592        if (res)
 593                return res;
 594
 595        /* Only TNETD73xx have a second serial port */
 596        if (ar7_has_second_uart()) {
 597                uart_port.line          = 1;
 598                uart_port.irq           = AR7_IRQ_UART1;
 599                uart_port.mapbase       = UR8_REGS_UART1;
 600                uart_port.membase       = ioremap(uart_port.mapbase, 256);
 601
 602                res = early_serial_setup(&uart_port);
 603                if (res)
 604                        return res;
 605        }
 606#endif
 607
 608        return 0;
 609}
 610
 611static void __init titan_fixup_devices(void)
 612{
 613        /* Set vlynq0 data */
 614        vlynq_low_data.reset_bit = 15;
 615        vlynq_low_data.gpio_bit = 14;
 616
 617        /* Set vlynq1 data */
 618        vlynq_high_data.reset_bit = 16;
 619        vlynq_high_data.gpio_bit = 7;
 620
 621        /* Set vlynq0 resources */
 622        vlynq_low_res[0].start = TITAN_REGS_VLYNQ0;
 623        vlynq_low_res[0].end = TITAN_REGS_VLYNQ0 + 0xff;
 624        vlynq_low_res[1].start = 33;
 625        vlynq_low_res[1].end = 33;
 626        vlynq_low_res[2].start = 0x0c000000;
 627        vlynq_low_res[2].end = 0x0fffffff;
 628        vlynq_low_res[3].start = 80;
 629        vlynq_low_res[3].end = 111;
 630
 631        /* Set vlynq1 resources */
 632        vlynq_high_res[0].start = TITAN_REGS_VLYNQ1;
 633        vlynq_high_res[0].end = TITAN_REGS_VLYNQ1 + 0xff;
 634        vlynq_high_res[1].start = 34;
 635        vlynq_high_res[1].end = 34;
 636        vlynq_high_res[2].start = 0x40000000;
 637        vlynq_high_res[2].end = 0x43ffffff;
 638        vlynq_high_res[3].start = 112;
 639        vlynq_high_res[3].end = 143;
 640
 641        /* Set cpmac0 data */
 642        cpmac_low_data.phy_mask = 0x40000000;
 643
 644        /* Set cpmac1 data */
 645        cpmac_high_data.phy_mask = 0x80000000;
 646
 647        /* Set cpmac0 resources */
 648        cpmac_low_res[0].start = TITAN_REGS_MAC0;
 649        cpmac_low_res[0].end = TITAN_REGS_MAC0 + 0x7ff;
 650
 651        /* Set cpmac1 resources */
 652        cpmac_high_res[0].start = TITAN_REGS_MAC1;
 653        cpmac_high_res[0].end = TITAN_REGS_MAC1 + 0x7ff;
 654}
 655
 656static int __init ar7_register_devices(void)
 657{
 658        void __iomem *bootcr;
 659        u32 val;
 660        int res;
 661
 662        res = ar7_register_uarts();
 663        if (res)
 664                pr_err("unable to setup uart(s): %d\n", res);
 665
 666        res = platform_device_register(&physmap_flash);
 667        if (res)
 668                pr_warning("unable to register physmap-flash: %d\n", res);
 669
 670        if (ar7_is_titan())
 671                titan_fixup_devices();
 672
 673        ar7_device_disable(vlynq_low_data.reset_bit);
 674        res = platform_device_register(&vlynq_low);
 675        if (res)
 676                pr_warning("unable to register vlynq-low: %d\n", res);
 677
 678        if (ar7_has_high_vlynq()) {
 679                ar7_device_disable(vlynq_high_data.reset_bit);
 680                res = platform_device_register(&vlynq_high);
 681                if (res)
 682                        pr_warning("unable to register vlynq-high: %d\n", res);
 683        }
 684
 685        if (ar7_has_high_cpmac()) {
 686                res = fixed_phy_add(PHY_POLL, cpmac_high.id, &fixed_phy_status);
 687                if (!res) {
 688                        cpmac_get_mac(1, cpmac_high_data.dev_addr);
 689
 690                        res = platform_device_register(&cpmac_high);
 691                        if (res)
 692                                pr_warning("unable to register cpmac-high: %d\n", res);
 693                } else
 694                        pr_warning("unable to add cpmac-high phy: %d\n", res);
 695        } else
 696                cpmac_low_data.phy_mask = 0xffffffff;
 697
 698        res = fixed_phy_add(PHY_POLL, cpmac_low.id, &fixed_phy_status);
 699        if (!res) {
 700                cpmac_get_mac(0, cpmac_low_data.dev_addr);
 701                res = platform_device_register(&cpmac_low);
 702                if (res)
 703                        pr_warning("unable to register cpmac-low: %d\n", res);
 704        } else
 705                pr_warning("unable to add cpmac-low phy: %d\n", res);
 706
 707        detect_leds();
 708        res = platform_device_register(&ar7_gpio_leds);
 709        if (res)
 710                pr_warning("unable to register leds: %d\n", res);
 711
 712        res = platform_device_register(&ar7_udc);
 713        if (res)
 714                pr_warning("unable to register usb slave: %d\n", res);
 715
 716        /* Register watchdog only if enabled in hardware */
 717        bootcr = ioremap_nocache(AR7_REGS_DCL, 4);
 718        val = readl(bootcr);
 719        iounmap(bootcr);
 720        if (val & AR7_WDT_HW_ENA) {
 721                if (ar7_has_high_vlynq())
 722                        ar7_wdt_res.start = UR8_REGS_WDT;
 723                else
 724                        ar7_wdt_res.start = AR7_REGS_WDT;
 725
 726                ar7_wdt_res.end = ar7_wdt_res.start + 0x20;
 727                res = platform_device_register(&ar7_wdt);
 728                if (res)
 729                        pr_warning("unable to register watchdog: %d\n", res);
 730        }
 731
 732        return 0;
 733}
 734device_initcall(ar7_register_devices);
 735