Esempio n. 1
0
void write_fuse(uint8_t efuse, uint16_t fuse_word)
{
	load_command(appc_write_fuse_bits);

	load_data_low_byte(fuse_word & 0xFF);
	set_byte_low();
	reset_bs2();
	wrb_pulse();
	while (poll_busy())
		;

	load_data_low_byte(fuse_word >> 8);
	set_byte_high();
	reset_bs2();
	wrb_pulse();
	while (poll_busy())
		;
	set_byte_low();

	load_data_low_byte(efuse);
	set_byte_low();
	set_bs2();
	wrb_pulse();
	while (poll_busy())
		;
	reset_bs2();
}
Esempio n. 2
0
void erase_chip(void)
{
	load_command(appc_chip_erase);
	wrb_pulse();
	while (poll_busy())
		;
}
Esempio n. 3
0
static void program_page(void) /* Datasheet code: H & L */
{
	set_byte_low();
	wrb_pulse();
	while (poll_busy())
		;
}
Esempio n. 4
0
static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
			      struct i2c_msg *msgs,
			      int num)
{
	struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter);
	struct i2c_msg	*msg;
	int err = 0;
	int i;
	long timeout;

	/* Wake up device and enable clock */
	pm_runtime_get_sync(pd->dev);

	/* Process all messages */
	for (i = 0; i < num; i++) {
		bool do_start = pd->send_stop || !i;
		msg = &msgs[i];
		pd->send_stop = i == num - 1 || msg->flags & I2C_M_STOP;
		pd->stop_after_dma = false;

		start_ch(pd, msg, do_start);

		if (do_start)
			i2c_op(pd, OP_START, 0);

		/* The interrupt handler takes care of the rest... */
		timeout = wait_event_timeout(pd->wait,
				       pd->sr & (ICSR_TACK | SW_DONE),
				       adapter->timeout);

		/* 'stop_after_dma' tells if DMA transfer was complete */
		i2c_put_dma_safe_msg_buf(pd->dma_buf, pd->msg, pd->stop_after_dma);

		if (!timeout) {
			dev_err(pd->dev, "Transfer request timed out\n");
			if (pd->dma_direction != DMA_NONE)
				sh_mobile_i2c_cleanup_dma(pd);

			err = -ETIMEDOUT;
			break;
		}

		if (pd->send_stop)
			err = poll_busy(pd);
		else
			err = poll_dte(pd);
		if (err < 0)
			break;
	}

	/* Disable channel */
	iic_wr(pd, ICCR, ICCR_SCP);

	/* Disable clock and mark device as idle */
	pm_runtime_put_sync(pd->dev);

	return err ?: num;
}
Esempio n. 5
0
void write_lock(uint8_t lock)
{
	load_command(appc_write_lock_bits);
	load_data_low_byte(lock);
	set_byte_low();
	reset_bs2();
	wrb_pulse();
	while (poll_busy())
		;
}
Esempio n. 6
0
static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
			      struct i2c_msg *msgs,
			      int num)
{
	struct sh_mobile_i2c_data *pd = i2c_get_adapdata(adapter);
	struct i2c_msg	*msg;
	int err = 0;
	int i, k;

	activate_ch(pd);

	/* Process all messages */
	for (i = 0; i < num; i++) {
		bool do_start = pd->send_stop || !i;
		msg = &msgs[i];
		pd->send_stop = i == num - 1 || msg->flags & I2C_M_STOP;

		err = start_ch(pd, msg, do_start);
		if (err)
			break;

		if (do_start)
			i2c_op(pd, OP_START, 0);

		/* The interrupt handler takes care of the rest... */
		k = wait_event_timeout(pd->wait,
				       pd->sr & (ICSR_TACK | SW_DONE),
				       5 * HZ);
		if (!k) {
			dev_err(pd->dev, "Transfer request timed out\n");
			err = -ETIMEDOUT;
			break;
		}

		if (pd->send_stop)
			err = poll_busy(pd);
		else
			err = poll_dte(pd);
		if (err < 0)
			break;
	}

	deactivate_ch(pd);

	if (!err)
		err = num;
	return err;
}
/* Send one block with DMA from the current write buffer, possibly preparing
 * the next block within the next write buffer in the background. */
static int send_block_send(unsigned char start_token, long timeout,
                           bool prepare_next)
{
    int rc = 0;
    unsigned char *curbuf = write_buffer[current_buffer];

    curbuf[1] = fliptable[(signed char)start_token];
    *(unsigned short *)(curbuf + BLOCK_SIZE + 2) = 0xFFFF;

    while (!(SSR1 & SCI_TEND));   /* wait for end of transfer */

    SCR1 = 0;                     /* disable serial */
    SSR1 = 0;                     /* clear all flags */

    /* setup DMA channel 0 */
    CHCR0 = 0;                    /* disable */
    SAR0 = (unsigned long)(curbuf + 1);
    DAR0 = TDR1_ADDR;
    DTCR0 = BLOCK_SIZE + 3;       /* start token + block + dummy crc */
    CHCR0 = 0x1701;               /* fixed dest. address, TXI1, enable */
    DMAOR = 0x0001;
    SCR1 = (SCI_TE|SCI_TIE);      /* kick off DMA */

    if (prepare_next)
        send_block_prepare();
    yield();                      /* be nice */

    while (!(CHCR0 & 0x0002));    /* wait for end of DMA */
    while (!(SSR1 & SCI_TEND));   /* wait for end of transfer */
    SCR1 = 0;
    serial_mode = SER_DISABLED;

    if ((poll_busy(timeout) & 0x1F) != 0x05) /* something went wrong */
        rc = -1;

    write_transfer(dummy, 1);
    last_disk_activity = current_tick;

    return rc;
}