Beispiel #1
0
/*
 * 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;
}
Beispiel #2
0
static int pcan_add_channels(struct pcan_pccard *card)
{
	struct pcmcia_device *pdev = card->pdev;
	int i, err = 0;
	u8 ccr = PCC_CCR_INIT;

	/* init common registers (reset channels and leds off) */
	card->ccr = ~ccr;
	pcan_write_reg(card, PCC_CCR, ccr);

	/* wait 2ms before unresetting channels */
	mdelay(2);

	ccr &= ~PCC_CCR_RST_ALL;
	pcan_write_reg(card, PCC_CCR, ccr);

	/* create one network device per channel detected */
	for (i = 0; i < ARRAY_SIZE(card->channel); i++) {
		struct net_device *netdev;
		struct sja1000_priv *priv;

		netdev = alloc_sja1000dev(0);
		if (!netdev) {
			err = -ENOMEM;
			break;
		}

		/* update linkages */
		priv = netdev_priv(netdev);
		priv->priv = card;
		SET_NETDEV_DEV(netdev, &pdev->dev);
		netdev->dev_id = i;

		priv->irq_flags = IRQF_SHARED;
		netdev->irq = pdev->irq;
		priv->reg_base = card->ioport_addr + PCC_CHAN_OFF(i);

		/* check if channel is present */
		if (!pcan_channel_present(priv)) {
			dev_err(&pdev->dev, "channel %d not present\n", i);
			free_sja1000dev(netdev);
			continue;
		}

		priv->read_reg  = pcan_read_canreg;
		priv->write_reg = pcan_write_canreg;
		priv->can.clock.freq = PCC_CAN_CLOCK;
		priv->ocr = PCC_OCR;
		priv->cdr = PCC_CDR;

		/* Neither a slave device distributes the clock */
		if (i > 0)
			priv->cdr |= CDR_CLK_OFF;

		priv->flags |= SJA1000_CUSTOM_IRQ_HANDLER;

		/* register SJA1000 device */
		err = register_sja1000dev(netdev);
		if (err) {
			free_sja1000dev(netdev);
			continue;
		}

		card->channel[i].netdev = netdev;
		card->chan_count++;

		/* set corresponding led on in the new ccr */
		ccr &= ~PCC_CCR_LED_OFF_CHAN(i);

		dev_info(&pdev->dev,
			"%s on channel %d at 0x%p irq %d\n",
			netdev->name, i, priv->reg_base, pdev->irq);
	}

	/* write new ccr (change leds state) */
	pcan_write_reg(card, PCC_CCR, ccr);

	return err;
}