/* * wait for SPI engine while it is busy */ static int pcan_wait_spi_busy(struct pcan_pccard *card) { unsigned long timeout = jiffies + msecs_to_jiffies(PCC_SPI_MAX_BUSY_WAIT_MS) + 1; /* be sure to read status at least once after sleeping */ while (pcan_read_reg(card, PCC_CSR) & PCC_CSR_SPI_BUSY) { if (time_after(jiffies, timeout)) return -EBUSY; schedule(); } return 0; }
/* * setup PCMCIA socket and probe for PEAK-System PC-CARD */ static int __devinit pcan_probe(struct pcmcia_device *pdev) { struct pcan_pccard *card; int err; pdev->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; err = pcmcia_loop_config(pdev, pcan_conf_check, NULL); if (err) { dev_err(&pdev->dev, "pcmcia_loop_config() error %d\n", err); goto probe_err_1; } if (!pdev->irq) { dev_err(&pdev->dev, "no irq assigned\n"); err = -ENODEV; goto probe_err_1; } err = pcmcia_enable_device(pdev); if (err) { dev_err(&pdev->dev, "pcmcia_enable_device failed err=%d\n", err); goto probe_err_1; } card = kzalloc(sizeof(struct pcan_pccard), GFP_KERNEL); if (!card) { dev_err(&pdev->dev, "couldn't allocate card memory\n"); err = -ENOMEM; goto probe_err_2; } card->pdev = pdev; pdev->priv = card; /* sja1000 api uses iomem */ card->ioport_addr = ioport_map(pdev->resource[0]->start, resource_size(pdev->resource[0])); if (!card->ioport_addr) { dev_err(&pdev->dev, "couldn't map io port into io memory\n"); err = -ENOMEM; goto probe_err_3; } card->fw_major = pcan_read_reg(card, PCC_FW_MAJOR); card->fw_minor = pcan_read_reg(card, PCC_FW_MINOR); /* display board name and firware version */ dev_info(&pdev->dev, "PEAK-System pcmcia card %s fw %d.%d\n", pdev->prod_id[1] ? pdev->prod_id[1] : "PCAN-PC Card", card->fw_major, card->fw_minor); /* detect available channels */ pcan_add_channels(card); if (!card->chan_count) goto probe_err_4; /* init the timer which controls the leds */ init_timer(&card->led_timer); card->led_timer.function = pcan_led_timer; card->led_timer.data = (unsigned long)card; /* request the given irq */ err = request_irq(pdev->irq, &pcan_isr, IRQF_SHARED, PCC_NAME, card); if (err) { dev_err(&pdev->dev, "couldn't request irq%d\n", pdev->irq); goto probe_err_5; } /* power on the connectors */ pcan_set_can_power(card, 1); return 0; probe_err_5: /* unregister can devices from network */ pcan_free_channels(card); probe_err_4: ioport_unmap(card->ioport_addr); probe_err_3: kfree(card); pdev->priv = NULL; probe_err_2: pcmcia_disable_device(pdev); probe_err_1: return err; }
/* * write data in device eeprom */ static int pcan_write_eeprom(struct pcan_pccard *card, u16 addr, u8 v) { u8 status; int err, i; /* write instruction enabling write */ pcan_write_reg(card, PCC_SPI_IR, PCC_EEP_WREN); err = pcan_wait_spi_busy(card); if (err) goto we_spi_err; /* wait until write enabled */ for (i = 0; i < PCC_WRITE_MAX_LOOP; i++) { /* write instruction reading the status register */ pcan_write_reg(card, PCC_SPI_IR, PCC_EEP_RDSR); err = pcan_wait_spi_busy(card); if (err) goto we_spi_err; /* get status register value and check write enable bit */ status = pcan_read_reg(card, PCC_SPI_DIR); if (status & PCC_EEP_SR_WEN) break; } if (i >= PCC_WRITE_MAX_LOOP) { dev_err(&card->pdev->dev, "stop waiting to be allowed to write in eeprom\n"); return -EIO; } /* set address and data */ pcan_write_reg(card, PCC_SPI_ADR, addr & 0xff); pcan_write_reg(card, PCC_SPI_DOR, v); /* * write instruction with bit[3] set according to address value: * if addr refers to upper half of the memory array: bit[3] = 1 */ pcan_write_reg(card, PCC_SPI_IR, PCC_EEP_WRITE(addr)); err = pcan_wait_spi_busy(card); if (err) goto we_spi_err; /* wait while write in progress */ for (i = 0; i < PCC_WRITE_MAX_LOOP; i++) { /* write instruction reading the status register */ pcan_write_reg(card, PCC_SPI_IR, PCC_EEP_RDSR); err = pcan_wait_spi_busy(card); if (err) goto we_spi_err; /* get status register value and check write in progress bit */ status = pcan_read_reg(card, PCC_SPI_DIR); if (!(status & PCC_EEP_SR_WIP)) break; } if (i >= PCC_WRITE_MAX_LOOP) { dev_err(&card->pdev->dev, "stop waiting for write in eeprom to complete\n"); return -EIO; } /* write instruction disabling write */ pcan_write_reg(card, PCC_SPI_IR, PCC_EEP_WRDI); err = pcan_wait_spi_busy(card); if (err) goto we_spi_err; return 0; we_spi_err: dev_err(&card->pdev->dev, "stop waiting (spi engine always busy) err %d\n", err); return err; }
/* * check whether the card is present by checking its fw version numbers * against values read at probing time. */ static inline int pcan_pccard_present(struct pcan_pccard *card) { return ((pcan_read_reg(card, PCC_FW_MAJOR) == card->fw_major) && (pcan_read_reg(card, PCC_FW_MINOR) == card->fw_minor)); }
static int pcan_write_eeprom(struct pcan_pccard *card, u16 addr, u8 v) { u8 status; int err, i; pcan_write_reg(card, PCC_SPI_IR, PCC_EEP_WREN); err = pcan_wait_spi_busy(card); if (err) goto we_spi_err; for (i = 0; i < PCC_WRITE_MAX_LOOP; i++) { pcan_write_reg(card, PCC_SPI_IR, PCC_EEP_RDSR); err = pcan_wait_spi_busy(card); if (err) goto we_spi_err; status = pcan_read_reg(card, PCC_SPI_DIR); if (status & PCC_EEP_SR_WEN) break; } if (i >= PCC_WRITE_MAX_LOOP) { dev_err(&card->pdev->dev, "stop waiting to be allowed to write in eeprom\n"); return -EIO; } pcan_write_reg(card, PCC_SPI_ADR, addr & 0xff); pcan_write_reg(card, PCC_SPI_DOR, v); pcan_write_reg(card, PCC_SPI_IR, PCC_EEP_WRITE(addr)); err = pcan_wait_spi_busy(card); if (err) goto we_spi_err; for (i = 0; i < PCC_WRITE_MAX_LOOP; i++) { pcan_write_reg(card, PCC_SPI_IR, PCC_EEP_RDSR); err = pcan_wait_spi_busy(card); if (err) goto we_spi_err; status = pcan_read_reg(card, PCC_SPI_DIR); if (!(status & PCC_EEP_SR_WIP)) break; } if (i >= PCC_WRITE_MAX_LOOP) { dev_err(&card->pdev->dev, "stop waiting for write in eeprom to complete\n"); return -EIO; } pcan_write_reg(card, PCC_SPI_IR, PCC_EEP_WRDI); err = pcan_wait_spi_busy(card); if (err) goto we_spi_err; return 0; we_spi_err: dev_err(&card->pdev->dev, "stop waiting (spi engine always busy) err %d\n", err); return err; }