示例#1
0
文件: escore-vs.c 项目: SelfImp/m75
int escore_vs_load(struct escore_priv *escore)
{
	struct escore_voice_sense *voice_sense =
			(struct escore_voice_sense *) escore->voice_sense;
	int rc = 0;
	int write_size = ES_VS_FW_CHUNK;
	int data_remaining = voice_sense->vs->size;
	u32 sync_cmd = (ES_EVENT_RESPONSE_CMD << 16) | ES_SYNC_INTR_RISING_EDGE;
	u32 resp;

	BUG_ON(voice_sense->vs->size == 0);

	if (!escore->boot_ops.setup || !escore->boot_ops.finish) {
		dev_err(escore->dev,
			"%s(): boot setup or finish function undefined\n",
			__func__);
		rc = -EIO;
		goto escore_vs_fw_download_failed;
	}

	rc = escore->boot_ops.setup(escore);
	if (rc) {
		dev_err(escore->dev, "%s(): fw download start error\n",
			__func__);
		goto escore_vs_fw_download_failed;
	}

	dev_dbg(escore->dev, "%s(): write vs firmware image\n", __func__);

	while (data_remaining) {
		rc = escore->bus.ops.high_bw_write(escore,
			((char *)voice_sense->vs->data)
			+ (voice_sense->vs->size - data_remaining), write_size);

		data_remaining -= write_size;

		dev_dbg(escore->dev,
			"data_remaining = %d, write_size = %d\n",
			data_remaining, write_size);

		if (rc) {
			dev_err(escore->dev,
				"%s(): vs firmware image write error\n",
				__func__);
			rc = -EIO;
			goto escore_vs_fw_download_failed;
		} else if (data_remaining < write_size) {
			write_size = data_remaining;
		}

		usleep_range(2000, 2000);
	}

	escore->mode = VOICESENSE;

	if (((struct escore_voice_sense *)escore->voice_sense)->vs_irq != true)
		escore_vs_init_intr(escore);

	rc = escore->boot_ops.finish(escore);
	if (rc) {
		dev_err(escore->dev, "%s() vs fw download finish error\n",
			__func__);
		goto escore_vs_fw_download_failed;
	} else {
		/* Enable Voice Sense Event INTR to Host */
		rc = escore_cmd(escore, sync_cmd, &resp);
		if (rc)
			dev_err(escore->dev, "%s(): escore_cmd fail %d\n",
								__func__, rc);

		if (resp != sync_cmd) {
			dev_err(escore->dev,
				"%s(): Enable VS Event INTR fail\n", __func__);
			goto escore_vs_fw_download_failed;
		}
	}

	dev_dbg(escore->dev, "%s(): fw download done\n", __func__);

escore_vs_fw_download_failed:
	return rc;
}
示例#2
0
文件: escore-vs.c 项目: qkdang/m462
int escore_vs_load(struct escore_priv *escore)
{
    struct escore_voice_sense *voice_sense =
        (struct escore_voice_sense *) escore->voice_sense;
    u32 cmd, resp;
    int rc = 0;

    BUG_ON(voice_sense->vs->size == 0);
    escore->mode = VOICESENSE_PENDING;

    if (!escore->boot_ops.setup || !escore->boot_ops.finish) {
        dev_err(escore->dev,
                "%s(): boot setup or finish function undefined\n",
                __func__);
        rc = -EIO;
        goto escore_vs_uart_open_failed;
    }

    if (escore->bus.ops.high_bw_open) {
        rc = escore->bus.ops.high_bw_open(escore);
        if (rc) {
            dev_err(escore->dev, "%s(): high_bw_open failed %d\n",
                    __func__, rc);
            goto escore_vs_uart_open_failed;
        }
    }

    rc = escore->boot_ops.setup(escore);
    if (rc) {
        dev_err(escore->dev, "%s(): fw download start error\n",
                __func__);
        goto escore_vs_fw_download_failed;
    }

    rc = escore_is_sleep_aborted(escore);
    if (rc == -EABORT) {
        /* after boot setup, firmware download is initiated and can be
         * aborted by sending abort keyword. This abort word is located
         * in the firmware binary image, comprised of the 4 bytes
         * starting at binary offset 0x000C. So host has to write
         * at least 16 byte so that abort code is known to chip.
         * Firmware abort sequence is mentioned in BUG #20899
         */
        rc = escore->bus.ops.high_bw_write(escore,
                                           ((char *)voice_sense->vs->data) , 20);
        if (rc) {
            dev_err(escore->dev,
                    "%s(): vs firmware data write error\n",
                    __func__);
            rc = -EIO;
            goto escore_vs_fw_download_failed;
        }

        /* Write abort keyword */
        cmd = *(u32 *)(voice_sense->vs->data + 0x000c);
        rc = escore->bus.ops.high_bw_write(escore, &cmd , 4);
        if (rc) {
            dev_err(escore->dev,
                    "%s(): abort word write error\n", __func__);
            rc = -EIO;
            goto escore_vs_fw_download_failed;
        }

        if (escore->high_bw_intf == ES_UART_INTF) {
            if (escore->boot_ops.escore_abort_config)
                escore->boot_ops.escore_abort_config(escore);
        }

        cmd = ES_SET_POWER_STATE_CMD << 16 | ES_SET_POWER_STATE_NORMAL;
        rc = escore->bus.ops.high_bw_cmd(escore, cmd , &resp);
        if (rc) {
            dev_err(escore->dev, "%s(): power state cmd error\n",
                    __func__);
            rc = -EIO;
            goto escore_vs_fw_download_failed;
        }
        rc = -EABORT;
        goto escore_sleep_aborted;
    }
    dev_dbg(escore->dev, "%s(): write vs firmware image\n", __func__);

    rc = escore->bus.ops.high_bw_write(escore,
                                       ((char *)voice_sense->vs->data) , voice_sense->vs->size);
    if (rc) {
        dev_err(escore->dev, "%s(): vs firmware image write error\n",
                __func__);
        rc = -EIO;
        goto escore_vs_fw_download_failed;
    }

    rc = escore_is_sleep_aborted(escore);
    if (rc == -EABORT)
        goto escore_sleep_aborted;

    escore->mode = VOICESENSE;

    if (((struct escore_voice_sense *)escore->voice_sense)->vs_irq != true)
        escore_vs_init_intr(escore);

    rc = escore->boot_ops.finish(escore);
    if (rc) {
        dev_err(escore->dev, "%s() vs fw download finish error\n",
                __func__);
        goto escore_vs_fw_download_failed;
    }
    /* Set smooth mute to 0 */
    cmd = ES_SET_SMOOTH_MUTE << 16 | ES_SMOOTH_MUTE_ZERO;
    rc = escore->bus.ops.cmd(escore, cmd, &resp);
    if (rc) {
        dev_err(escore->dev, "%s(): escore_cmd(%08x) fail %d\n",
                __func__, cmd, rc);
        goto escore_vs_fw_download_failed;
    }
#ifdef CONFIG_ARCH_EXYNOS
    cmd = 0x805200f3; // DHWPT: Port-A connected to Port-D
    rc = escore->bus.ops.cmd(escore, cmd, &resp);
    if (rc) {
        dev_err(escore->dev, "%s(): escore_cmd(%08x) fail %d\n",
                __func__, cmd, rc);
        goto escore_vs_fw_download_failed;
    }
#endif

    rc = escore_is_sleep_aborted(escore);
    if (rc == -EABORT)
        goto escore_sleep_aborted;

    rc = escore_reconfig_intr(escore);
    if (rc) {
        dev_err(escore->dev, "%s() config resume failed after VS load rc = %d\n",
                __func__, rc);
        goto escore_vs_fw_download_failed;
    }

    dev_dbg(escore->dev, "%s(): fw download done\n", __func__);

escore_sleep_aborted:
escore_vs_fw_download_failed:
    if (escore->bus.ops.high_bw_close) {
        rc = escore->bus.ops.high_bw_close(escore);
        if (rc) {
            dev_err(escore->dev, "%s(): high_bw_close failed %d\n",
                    __func__, rc);
        }
    }
escore_vs_uart_open_failed:

    return rc;
}