/* Load a firmware file */
ret = request_firmware(&firmware, fw_path, priv->pdev); if (ret) {
pr_err("Can't load firmware file %s.\n", fw_path); gotoexit;
}
buf = kmalloc(DOWNLOAD_BLOCK_SIZE, GFP_KERNEL | GFP_DMA); if (!buf) {
pr_err("Can't allocate firmware load buffer.\n");
ret = -ENOMEM; goto firmware_release;
}
/* Check if the bootloader is ready */ for (i = 0; i < 100; i += 1 + i / 2) {
APB_READ(DOWNLOAD_IMAGE_SIZE_REG, val32); if (val32 == DOWNLOAD_I_AM_HERE) break;
mdelay(i);
} /* End of for loop */
if (val32 != DOWNLOAD_I_AM_HERE) {
pr_err("Bootloader is not ready.\n");
ret = -ETIMEDOUT; goto free_buffer;
}
/* Calculcate number of download blocks */
num_blocks = (firmware->size - 1) / DOWNLOAD_BLOCK_SIZE + 1;
/* Updating the length in Download Ctrl Area */
val32 = firmware->size; /* Explicit cast from size_t to u32 */
APB_WRITE2(DOWNLOAD_IMAGE_SIZE_REG, val32);
/* check the download status */
APB_READ(DOWNLOAD_STATUS_REG, val32); if (val32 != DOWNLOAD_PENDING) {
pr_err("Bootloader reported error %d.\n", val32);
ret = -EIO; goto free_buffer;
}
/* loop until put - get <= 24K */ for (i = 0; i < 100; i++) {
APB_READ(DOWNLOAD_GET_REG, get); if ((put - get) <=
(DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE)) break;
mdelay(i);
}
if ((put - get) > (DOWNLOAD_FIFO_SIZE - DOWNLOAD_BLOCK_SIZE)) {
pr_err("Timeout waiting for FIFO.\n");
ret = -ETIMEDOUT; goto free_buffer;
}
/* send the block to sram */
ret = cw1200_apb_write(priv,
CW1200_APB(DOWNLOAD_FIFO_OFFSET +
(put & (DOWNLOAD_FIFO_SIZE - 1))),
buf, tx_size); if (ret < 0) {
pr_err("Can't write firmware block @ %d!\n",
put & (DOWNLOAD_FIFO_SIZE - 1)); goto free_buffer;
}
/* update the put register */
put += block_size;
APB_WRITE2(DOWNLOAD_PUT_REG, put);
} /* End of firmware download loop */
/* Wait for the download completion */ for (i = 0; i < 300; i += 1 + i / 2) {
APB_READ(DOWNLOAD_STATUS_REG, val32); if (val32 != DOWNLOAD_PENDING) break;
mdelay(i);
} if (val32 != DOWNLOAD_SUCCESS) {
pr_err("Wait for download completion failed: 0x%.8X\n", val32);
ret = -ETIMEDOUT; goto free_buffer;
} else {
pr_info("Firmware download completed.\n");
ret = 0;
}
if (val32 == 0 || val32 == 0xffffffff) {
pr_err("Bad config register value (0x%08x)\n", val32);
ret = -EIO; goto out;
}
ret = cw1200_get_hw_type(val32, &major_revision); if (ret < 0) {
pr_err("Can't deduce hardware type.\n"); goto out;
}
priv->hw_type = ret;
/* Set DPLL Reg value, and read back to confirm writes work */
ret = cw1200_reg_write_32(priv, ST90TDS_TSET_GEN_R_W_REG_ID,
cw1200_dpll_from_clk(priv->hw_refclk)); if (ret < 0) {
pr_err("Can't write DPLL register.\n"); goto out;
}
msleep(20);
ret = cw1200_reg_read_32(priv,
ST90TDS_TSET_GEN_R_W_REG_ID, &val32); if (ret < 0) {
pr_err("Can't read DPLL register.\n"); goto out;
}
if (val32 != cw1200_dpll_from_clk(priv->hw_refclk)) {
pr_err("Unable to initialise DPLL register. Wrote 0x%.8X, Read 0x%.8X.\n",
cw1200_dpll_from_clk(priv->hw_refclk), val32);
ret = -EIO; goto out;
}
/* Set wakeup bit in device */
ret = cw1200_reg_read_16(priv, ST90TDS_CONTROL_REG_ID, &val16); if (ret < 0) {
pr_err("set_wakeup: can't read control register.\n"); goto out;
}
ret = cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID,
val16 | ST90TDS_CONT_WUP_BIT); if (ret < 0) {
pr_err("set_wakeup: can't write control register.\n"); goto out;
}
/* Wait for wakeup */ for (i = 0; i < 300; i += (1 + i / 2)) {
ret = cw1200_reg_read_16(priv,
ST90TDS_CONTROL_REG_ID, &val16); if (ret < 0) {
pr_err("wait_for_wakeup: can't read control register.\n"); goto out;
}
if (val16 & ST90TDS_CONT_RDY_BIT) break;
msleep(i);
}
if ((val16 & ST90TDS_CONT_RDY_BIT) == 0) {
pr_err("wait_for_wakeup: device is not responding.\n");
ret = -ETIMEDOUT; goto out;
}
switch (major_revision) { case 1: /* CW1200 Hardware detection logic : Check for CUT1.1 */
ret = cw1200_ahb_read_32(priv, CW1200_CUT_ID_ADDR, &val32); if (ret) {
pr_err("HW detection: can't read CUT ID.\n"); goto out;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.