コード例 #1
0
int es705_uart_cmd(struct es705_priv *es705, u32 cmd, int sr, u32 *resp)
{
	int err;
	u32 rv;

	dev_dbg(es705->dev, "%s(): cmd=0x%08x  sr=%i\n", __func__, cmd, sr);

	cmd = cpu_to_be32(cmd);
	err = es705_uart_write(es705, &cmd, sizeof(cmd));
	if (err < 0 || sr)
		goto es705_uart_cmd_exit;

	/* Maximum response time is 10ms */
	usleep_range(10000, 10000);

	err = es705_uart_read(es705, &rv, sizeof(rv));
	if (err > 0) {
	dev_dbg(es705->dev, "%s(): response=0x%08x\n", __func__, rv);
		*resp = be32_to_cpu(rv);
	} else if (err == 0) {
		dev_dbg(es705->dev, "%s(): No response\n", __func__);
	} else {
		dev_err(es705->dev, "%s(): UART read fail\n", __func__);
	}
es705_uart_cmd_exit:
	return err;
}
コード例 #2
0
static int es705_uart_boot_finish(struct es705_priv *es705)
{
    u32 sync_cmd;
    u32 sync_resp;
    char msg[4];
    int rc;

    /*
     * Give the chip some time to become ready after firmware
     * download. (FW is still transferring)
     */
    msleep(50);

    /*
     * Read 4 bytes of VS FW download status
     * TODO To avoid possible problem in the future
     * if FW goes to send less or more then 4 bytes
     * Need modify code to read UART until read
     * buffer is empty
     */
    rc = es705_uart_read(es705, msg, 4);
    if (rc < 0)
        dev_err(es705->dev, "%s(): UART read fail\n",
                __func__);
    else
        dev_dbg(es705->dev, "%s(): read byte = 0x%02x%02x%02x%02x\n",
                __func__, msg[0], msg[1], msg[2], msg[3]);

    if (es705->es705_power_state == ES705_SET_POWER_STATE_VS_OVERLAY) {
        sync_cmd = (ES705_SYNC_CMD << 16) | ES705_SYNC_INTR_RISING_EDGE;
        dev_info(es705->dev, "%s(): FW type : VOICESENSE\n", __func__);
    } else {
        sync_cmd = (ES705_SYNC_CMD << 16) | ES705_SYNC_POLLING;
        dev_info(es705->dev, "%s(): FW type : STANDARD\n", __func__);
    }

    dev_dbg(es705->dev, "%s(): write ES705_SYNC_CMD = 0x%08x\n",
            __func__, sync_cmd);
    rc = es705_uart_cmd(es705, sync_cmd, 0, &sync_resp);
    if (rc < 0) {
        dev_err(es705->dev, "%s(): firmware load failed (no sync response)\n",
                __func__);
        goto es705_boot_finish_failed;
    }
    if (sync_cmd != sync_resp) {
        dev_err(es705->dev, "%s(): firmware load failed, invalid sync response 0x%08x\n",
                __func__, sync_resp);
        rc = -EIO;
        goto es705_boot_finish_failed;
    }

    dev_dbg(es705->dev, "%s(): firmware load success 0x%08x\n",
            __func__, sync_resp);

es705_boot_finish_failed:
    return rc;
}
コード例 #3
0
int es705_uart_write_then_read(struct es705_priv *es705, const void *buf,
			       int len, u32 *rspn, int match)
{
	int rc;
	u32 response = 0;

	rc = es705_uart_write(es705, buf, len);
	if (rc > 0) {
		rc = es705_uart_read(es705, &response, len);
		response = le32_to_cpu(response);
		if (rc < 0) {
			dev_err(es705->dev, "%s(): UART read fail\n",
				__func__);
		} else if (match && *rspn != response) {
			dev_err(es705->dev, "%s(): unexpected response 0x%08x\n",
				__func__, be32_to_cpu(response));
			rc = -EIO;
		} else {
			*rspn = response;
		}
	}
	return rc;
}
コード例 #4
0
int es705_uart_dev_wdb(struct es705_priv *es705, const void *buf, int len)
{
	/* At this point the command has been determined and is not part
	 * of the data in the buffer. Its just data. Note that we donot
	 * evaluate the contents of the data. It is up to the higher layers
	 * to insure the the codes mode of operation matchs what is being
	 * sent.
	 */
	int ret;
	u32 resp;
	u8 *dptr;

	u32 cmd = ES705_WDB_CMD << 16;

	dev_dbg(es705->dev, "%s(): len = 0x%08x\n", __func__, len);
	dptr = (char *)buf;

	cmd = cmd | (len & 0xFFFF);
	dev_dbg(es705->dev, "%s(): cmd = 0x%08x\n", __func__, cmd);
	cmd = cpu_to_be32(cmd);
	ret = es705_uart_write_then_read(es705, &cmd, sizeof(cmd), &resp, 0);
	if (ret < 0) {
		dev_err(es705->dev, "%s(): cmd write err=%hu\n", __func__, ret);
		goto wdb_err;
	}

	be32_to_cpus(&resp);
	dev_dbg(es705->dev, "%s(): resp = 0x%08x\n", __func__, resp);
	if ((resp & 0xffff0000) != (ES705_WDB_CMD << 16)) {
		dev_err(es705->dev, "%s(): invalid write data block 0x%08x\n",
			__func__, resp);
		goto wdb_err;
	}

	/* The API requires that the subsequent writes are to be
	 * a byte stream (one byte per transport transaction)
	 */
	ret = es705_uart_write(es705, dptr, len);
	if (ret < 0) {
		dev_err(es705->dev, "%s(): wdb error =%d\n", __func__, ret);
		goto wdb_err;
	}

	/* One last ACK read */
	ret = es705_uart_read(es705, &resp, 4);
	if (ret < 0) {
		dev_err(es705->dev, "%s(): last ack %d\n", __func__, ret);
		goto wdb_err;
	}

	if (resp & 0xff000000) {
		dev_err(es705->dev, "%s(): write data block error 0x%0x\n",
			__func__, resp);
		goto wdb_err;
	}

	dev_dbg(es705->dev, "%s(): len = %d\n", __func__, len);

	goto exit;

wdb_err:
	len = -EIO;
exit:
	return len;
}
コード例 #5
0
int es705_uart_dev_rdb(struct es705_priv *es705, void *buf, int id)
{
	u32 cmd;
	u32 resp;
	u8 *dptr;
	int ret;
	int size;
	int rdcnt = 0;

	dptr = (u8 *) buf;
	/* Read voice sense keyword data block request. */
	cmd = (ES705_RDB_CMD << 16) | (id & 0xFFFF);
	cmd = cpu_to_be32(cmd);

	ret = es705_uart_write(es705, (char *)&cmd, 4);
	if (ret < 0) {
		dev_err(es705->dev, "%s(): RDB cmd write err = %d\n", __func__,
			ret);
		goto rdb_err;
	}

	/* Refer to "ES705 Advanced API Guide" for details of interface */
	usleep_range(10000, 11000);

	ret = es705_uart_read(es705, (char *)&resp, 4);
	if (ret < 0) {
		dev_err(es705->dev, "%s(): error sending request = %d\n",
			__func__, ret);
		goto rdb_err;
	}

	be32_to_cpus(&resp);
	size = resp & 0xffff;

	dev_dbg(es705->dev, "%s(): resp=0x%08x size=%d\n", __func__, resp,
		size);

	if ((resp & 0xffff0000) != (ES705_RDB_CMD << 16)) {
		dev_err(es705->dev,
			"%s(): invalid read v-s data block response = 0x%08x\n",
			__func__, resp);
		goto rdb_err;
	}

	if (size == 0) {
		dev_err(es705->dev, "%s(): read request return size of 0\n",
			__func__);
		goto rdb_err;
	}
	if (size > PARSE_BUFFER_SIZE)
		size = PARSE_BUFFER_SIZE;

	for (rdcnt = 0; rdcnt < size; rdcnt++, dptr++) {
		ret = es705_uart_read(es705, dptr, 1);
		if (ret < 0) {
			dev_err(es705->dev,
				"%s(): data block ed error %d bytes ret = %d\n",
				__func__, rdcnt, ret);
			goto rdb_err;
		}
	}

	es705->rdb_read_count = size;

	ret = 0;
	goto exit;

rdb_err:
	es705->rdb_read_count = 0;
	ret = -EIO;
exit:
	return ret;
}
コード例 #6
0
ファイル: es705-uart.c プロジェクト: hallometa/Gear_S_Kernel
int es705_uart_dev_rdb(struct es705_priv *es705, void *buf, int id)
{
	u32 cmd;
	u32 resp;
	u8 *dptr;
	int ret;
	int size;
	int rdcnt = 0;
#if defined(CONFIG_MQ100_SENSOR_HUB)
	u8 pad;
	/* Take Mutex for the duration of this UART transaction. */
	mutex_lock(&es705_priv.uart_transaction_mutex);
#endif
	dptr = (u8 *)buf;
	/* Read voice sense keyword data block request. */
	cmd = (ES705_RDB_CMD << 16) | (id & 0xFFFF);
	cmd = cpu_to_be32(cmd);
	ret = es705_uart_write(es705, (char *)&cmd, 4);
	if (ret < 0) {
		dev_err(es705->dev, "%s(): RDB cmd write err = %d\n",
			__func__, ret);
		goto rdb_err;
	}

	/* Refer to "ES705 Advanced API Guide" for details of interface */
	usleep_range(10000, 10000);

	ret = es705_uart_read(es705, (char *)&resp, 4);
	if (ret < 0) {
		dev_err(es705->dev, "%s(): error sending request = %d\n",
			__func__, ret);
		goto rdb_err;
	}

	be32_to_cpus(&resp);
	size = resp & 0xffff;
	dev_dbg(es705->dev, "%s(): resp=0x%08x size=%d\n",
		__func__, resp, size);
	if ((resp & 0xffff0000) != (ES705_RDB_CMD << 16)) {
		dev_err(es705->dev,
			"%s(): invalid read v-s data block response = 0x%08x\n",
			__func__, resp);
		goto rdb_err;
	}

	if (size == 0) {
		dev_err(es705->dev, "%s(): read request return size of 0\n",
			__func__);
		goto rdb_err;
	}
	if (size > PARSE_BUFFER_SIZE)
		size = PARSE_BUFFER_SIZE;

	for (rdcnt = 0; rdcnt < size; rdcnt++, dptr++) {
		ret = es705_uart_read(es705, dptr, 1);
		if (ret < 0) {
			dev_err(es705->dev,
				"%s(): data block ed error %d bytes ret = %d\n",
				__func__, rdcnt, ret);
			goto rdb_err;
		}
	}

	es705->rdb_read_count = size;

#if defined(CONFIG_MQ100_SENSOR_HUB)
	size = PAD4(size);
	dev_dbg(es705->dev, "%s: Discarding %d pad bytes\n",
			__func__, size);
	ret = 0;
	while ((size > 0) && (ret >= 0)) {
		ret = es705_uart_read(es705, &pad, 1);
		size--;
	}
#endif
	ret = 0;
	goto exit;

rdb_err:
	es705->rdb_read_count = 0;
	ret = -EIO;
exit:
#if defined(CONFIG_MQ100_SENSOR_HUB)
	/* release UART transaction mutex */
	mutex_unlock(&es705_priv.uart_transaction_mutex);
#endif
	return ret;
}