static void __pmz_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct uart_pmac_port *uap = to_pmz(port); unsigned long baud; pmz_debug("pmz: set_termios()\n"); if (ZS_IS_ASLEEP(uap)) return; memcpy(&uap->termios_cache, termios, sizeof(struct ktermios)); /* XXX Check which revs of machines actually allow 1 and 4Mb speeds * on the IR dongle. Note that the IRTTY driver currently doesn't know * about the FIR mode and high speed modes. So these are unused. For * implementing proper support for these, we should probably add some * DMA as well, at least on the Rx side, which isn't a simple thing * at this point. */ if (ZS_IS_IRDA(uap)) { /* Calc baud rate */ baud = uart_get_baud_rate(port, termios, old, 1200, 4000000); pmz_debug("pmz: switch IRDA to %ld bauds\n", baud); /* Cet the irda codec to the right rate */ pmz_irda_setup(uap, &baud); /* Set final baud rate */ pmz_convert_to_zs(uap, termios->c_cflag, termios->c_iflag, baud); pmz_load_zsregs(uap, uap->curregs); zssync(uap); } else { baud = uart_get_baud_rate(port, termios, old, 1200, 230400); pmz_convert_to_zs(uap, termios->c_cflag, termios->c_iflag, baud); /* Make sure modem status interrupts are correctly configured */ if (UART_ENABLE_MS(&uap->port, termios->c_cflag)) { uap->curregs[R15] |= DCDIE | SYNCIE | CTSIE; uap->flags |= PMACZILOG_FLAG_MODEM_STATUS; } else { uap->curregs[R15] &= ~(DCDIE | SYNCIE | CTSIE); uap->flags &= ~PMACZILOG_FLAG_MODEM_STATUS; } /* Load registers to the chip */ pmz_maybe_update_regs(uap); } uart_update_timeout(port, termios->c_cflag, baud); pmz_debug("pmz: set_termios() done.\n"); }
/* * Setup one port structure after probing, HW is down at this point, * Unlike sunzilog, we don't need to pre-init the spinlock as we don't * register our console before uart_add_one_port() is called */ static int __init pmz_init_port(struct uart_pmac_port *uap) { struct device_node *np = uap->node; const char *conn; const struct slot_names_prop { int count; char name[1]; } *slots; int len; struct resource r_ports, r_rxdma, r_txdma; /* * Request & map chip registers */ if (of_address_to_resource(np, 0, &r_ports)) return -ENODEV; uap->port.mapbase = r_ports.start; uap->port.membase = ioremap(uap->port.mapbase, 0x1000); uap->control_reg = uap->port.membase; uap->data_reg = uap->control_reg + 0x10; /* * Request & map DBDMA registers */ #ifdef HAS_DBDMA if (of_address_to_resource(np, 1, &r_txdma) == 0 && of_address_to_resource(np, 2, &r_rxdma) == 0) uap->flags |= PMACZILOG_FLAG_HAS_DMA; #else memset(&r_txdma, 0, sizeof(struct resource)); memset(&r_rxdma, 0, sizeof(struct resource)); #endif if (ZS_HAS_DMA(uap)) { uap->tx_dma_regs = ioremap(r_txdma.start, 0x100); if (uap->tx_dma_regs == NULL) { uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; goto no_dma; } uap->rx_dma_regs = ioremap(r_rxdma.start, 0x100); if (uap->rx_dma_regs == NULL) { iounmap(uap->tx_dma_regs); uap->tx_dma_regs = NULL; uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; goto no_dma; } uap->tx_dma_irq = irq_of_parse_and_map(np, 1); uap->rx_dma_irq = irq_of_parse_and_map(np, 2); } no_dma: /* * Detect port type */ if (of_device_is_compatible(np, "cobalt")) uap->flags |= PMACZILOG_FLAG_IS_INTMODEM; conn = of_get_property(np, "AAPL,connector", &len); if (conn && (strcmp(conn, "infrared") == 0)) uap->flags |= PMACZILOG_FLAG_IS_IRDA; uap->port_type = PMAC_SCC_ASYNC; /* 1999 Powerbook G3 has slot-names property instead */ slots = of_get_property(np, "slot-names", &len); if (slots && slots->count > 0) { if (strcmp(slots->name, "IrDA") == 0) uap->flags |= PMACZILOG_FLAG_IS_IRDA; else if (strcmp(slots->name, "Modem") == 0) uap->flags |= PMACZILOG_FLAG_IS_INTMODEM; } if (ZS_IS_IRDA(uap)) uap->port_type = PMAC_SCC_IRDA; if (ZS_IS_INTMODEM(uap)) { struct device_node* i2c_modem = of_find_node_by_name(NULL, "i2c-modem"); if (i2c_modem) { const char* mid = of_get_property(i2c_modem, "modem-id", NULL); if (mid) switch(*mid) { case 0x04 : case 0x05 : case 0x07 : case 0x08 : case 0x0b : case 0x0c : uap->port_type = PMAC_SCC_I2S1; } printk(KERN_INFO "pmac_zilog: i2c-modem detected, id: %d\n", mid ? (*mid) : 0); of_node_put(i2c_modem); } else { printk(KERN_INFO "pmac_zilog: serial modem detected\n"); } } /* * Init remaining bits of "port" structure */ uap->port.iotype = UPIO_MEM; uap->port.irq = irq_of_parse_and_map(np, 0); uap->port.uartclk = ZS_CLOCK; uap->port.fifosize = 1; uap->port.ops = &pmz_pops; uap->port.type = PORT_PMAC_ZILOG; uap->port.flags = 0; /* Setup some valid baud rate information in the register * shadows so we don't write crap there before baud rate is * first initialized. */ pmz_convert_to_zs(uap, CS8, 0, 9600); return 0; }
/* * Set the irda codec on the imac to the specified baud rate. */ static void pmz_irda_setup(struct uart_pmac_port *uap, unsigned long *baud) { u8 cmdbyte; int t, version; switch (*baud) { /* SIR modes */ case 2400: cmdbyte = 0x53; break; case 4800: cmdbyte = 0x52; break; case 9600: cmdbyte = 0x51; break; case 19200: cmdbyte = 0x50; break; case 38400: cmdbyte = 0x4f; break; case 57600: cmdbyte = 0x4e; break; case 115200: cmdbyte = 0x4d; break; /* The FIR modes aren't really supported at this point, how * do we select the speed ? via the FCR on KeyLargo ? */ case 1152000: cmdbyte = 0; break; case 4000000: cmdbyte = 0; break; default: /* 9600 */ cmdbyte = 0x51; *baud = 9600; break; } /* Wait for transmitter to drain */ t = 10000; while ((read_zsreg(uap, R0) & Tx_BUF_EMP) == 0 || (read_zsreg(uap, R1) & ALL_SNT) == 0) { if (--t <= 0) { dev_err(&uap->dev->ofdev.dev, "transmitter didn't drain\n"); return; } udelay(10); } /* Drain the receiver too */ t = 100; (void)read_zsdata(uap); (void)read_zsdata(uap); (void)read_zsdata(uap); mdelay(10); while (read_zsreg(uap, R0) & Rx_CH_AV) { read_zsdata(uap); mdelay(10); if (--t <= 0) { dev_err(&uap->dev->ofdev.dev, "receiver didn't drain\n"); return; } } /* Switch to command mode */ uap->curregs[R5] |= DTR; write_zsreg(uap, R5, uap->curregs[R5]); zssync(uap); mdelay(1); /* Switch SCC to 19200 */ pmz_convert_to_zs(uap, CS8, 0, 19200); pmz_load_zsregs(uap, uap->curregs); mdelay(1); /* Write get_version command byte */ write_zsdata(uap, 1); t = 5000; while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) { if (--t <= 0) { dev_err(&uap->dev->ofdev.dev, "irda_setup timed out on get_version byte\n"); goto out; } udelay(10); } version = read_zsdata(uap); if (version < 4) { dev_info(&uap->dev->ofdev.dev, "IrDA: dongle version %d not supported\n", version); goto out; } /* Send speed mode */ write_zsdata(uap, cmdbyte); t = 5000; while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) { if (--t <= 0) { dev_err(&uap->dev->ofdev.dev, "irda_setup timed out on speed mode byte\n"); goto out; } udelay(10); } t = read_zsdata(uap); if (t != cmdbyte) dev_err(&uap->dev->ofdev.dev, "irda_setup speed mode byte = %x (%x)\n", t, cmdbyte); dev_info(&uap->dev->ofdev.dev, "IrDA setup for %ld bps, dongle version: %d\n", *baud, version); (void)read_zsdata(uap); (void)read_zsdata(uap); (void)read_zsdata(uap); out: /* Switch back to data mode */ uap->curregs[R5] &= ~DTR; write_zsreg(uap, R5, uap->curregs[R5]); zssync(uap); (void)read_zsdata(uap); (void)read_zsdata(uap); (void)read_zsdata(uap); }
/* * Setup one port structure after probing, HW is down at this point, * Unlike sunzilog, we don't need to pre-init the spinlock as we don't * register our console before uart_add_one_port() is called */ static int __init pmz_init_port(struct uart_pmac_port *uap) { struct device_node *np = uap->node; char *conn; struct slot_names_prop { int count; char name[1]; } *slots; int len; /* * Request & map chip registers */ uap->port.mapbase = np->addrs[0].address; uap->port.membase = ioremap(uap->port.mapbase, 0x1000); uap->control_reg = (volatile u8 *)uap->port.membase; uap->data_reg = uap->control_reg + 0x10; /* * Request & map DBDMA registers */ #ifdef HAS_DBDMA if (np->n_addrs >= 3 && np->n_intrs >= 3) uap->flags |= PMACZILOG_FLAG_HAS_DMA; #endif if (ZS_HAS_DMA(uap)) { uap->tx_dma_regs = (volatile struct dbdma_regs *) ioremap(np->addrs[np->n_addrs - 2].address, 0x1000); if (uap->tx_dma_regs == NULL) { uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; goto no_dma; } uap->rx_dma_regs = (volatile struct dbdma_regs *) ioremap(np->addrs[np->n_addrs - 1].address, 0x1000); if (uap->rx_dma_regs == NULL) { iounmap((void *)uap->tx_dma_regs); uap->tx_dma_regs = NULL; uap->flags &= ~PMACZILOG_FLAG_HAS_DMA; goto no_dma; } uap->tx_dma_irq = np->intrs[1].line; uap->rx_dma_irq = np->intrs[2].line; } no_dma: /* * Detect port type */ if (device_is_compatible(np, "cobalt")) uap->flags |= PMACZILOG_FLAG_IS_INTMODEM; conn = get_property(np, "AAPL,connector", &len); if (conn && (strcmp(conn, "infrared") == 0)) uap->flags |= PMACZILOG_FLAG_IS_IRDA; uap->port_type = PMAC_SCC_ASYNC; /* 1999 Powerbook G3 has slot-names property instead */ slots = (struct slot_names_prop *)get_property(np, "slot-names", &len); if (slots && slots->count > 0) { if (strcmp(slots->name, "IrDA") == 0) uap->flags |= PMACZILOG_FLAG_IS_IRDA; else if (strcmp(slots->name, "Modem") == 0) uap->flags |= PMACZILOG_FLAG_IS_INTMODEM; } if (ZS_IS_IRDA(uap)) uap->port_type = PMAC_SCC_IRDA; if (ZS_IS_INTMODEM(uap)) { struct device_node* i2c_modem = find_devices("i2c-modem"); if (i2c_modem) { char* mid = get_property(i2c_modem, "modem-id", NULL); if (mid) switch(*mid) { case 0x04 : case 0x05 : case 0x07 : case 0x08 : case 0x0b : case 0x0c : uap->port_type = PMAC_SCC_I2S1; } printk(KERN_INFO "pmac_zilog: i2c-modem detected, id: %d\n", mid ? (*mid) : 0); } else { printk(KERN_INFO "pmac_zilog: serial modem detected\n"); } } /* * Init remaining bits of "port" structure */ uap->port.iotype = SERIAL_IO_MEM; uap->port.irq = np->intrs[0].line; uap->port.uartclk = ZS_CLOCK; uap->port.fifosize = 1; uap->port.ops = &pmz_pops; uap->port.type = PORT_PMAC_ZILOG; uap->port.flags = 0; /* Setup some valid baud rate information in the register * shadows so we don't write crap there before baud rate is * first initialized. */ pmz_convert_to_zs(uap, CS8, 0, 9600); return 0; }