/*
 * 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;
}
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;
}