Skip to content

Commit

Permalink
ASoC: wm0010: Split out the stage2 load from the boot function
Browse files Browse the repository at this point in the history
Signed-off-by: Scott Ling <sl@opensource.wolfsonmicro.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Scott Ling authored and Mark Brown committed Nov 9, 2012
1 parent 8f7d52a commit 3f5475d
Showing 1 changed file with 79 additions and 50 deletions.
129 changes: 79 additions & 50 deletions sound/soc/codecs/wm0010.c
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,82 @@ static int wm0010_firmware_load(char *name, struct snd_soc_codec *codec)
return ret;
}

static int wm0010_stage2_load(struct snd_soc_codec *codec)
{
struct spi_device *spi = to_spi_device(codec->dev);
struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
const struct firmware *fw;
struct spi_message m;
struct spi_transfer t;
u32 *img;
u8 *out;
int i;
int ret = 0;

ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev);
if (ret != 0) {
dev_err(codec->dev, "Failed to request stage2 loader: %d\n",
ret);
return ret;
}

dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size);

/* Copy to local buffer first as vmalloc causes problems for dma */
img = kzalloc(fw->size, GFP_KERNEL);
if (!img) {
dev_err(codec->dev, "Failed to allocate image buffer\n");
ret = -ENOMEM;
goto abort2;
}

out = kzalloc(fw->size, GFP_KERNEL);
if (!out) {
dev_err(codec->dev, "Failed to allocate output buffer\n");
ret = -ENOMEM;
goto abort1;
}

memcpy(img, &fw->data[0], fw->size);

spi_message_init(&m);
memset(&t, 0, sizeof(t));
t.rx_buf = out;
t.tx_buf = img;
t.len = fw->size;
t.bits_per_word = 8;
t.speed_hz = wm0010->sysclk / 10;
spi_message_add_tail(&t, &m);

dev_dbg(codec->dev, "Starting initial download at %dHz\n",
t.speed_hz);

ret = spi_sync(spi, &m);
if (ret != 0) {
dev_err(codec->dev, "Initial download failed: %d\n", ret);
goto abort;
}

/* Look for errors from the boot ROM */
for (i = 0; i < fw->size; i++) {
if (out[i] != 0x55) {
dev_err(codec->dev, "Boot ROM error: %x in %d\n",
out[i], i);
wm0010_mark_boot_failure(wm0010);
ret = -EBUSY;
goto abort;
}
}
abort:
kfree(out);
abort1:
kfree(img);
abort2:
release_firmware(fw);

return ret;
}

static int wm0010_boot(struct snd_soc_codec *codec)
{
struct spi_device *spi = to_spi_device(codec->dev);
Expand All @@ -487,10 +563,9 @@ static int wm0010_boot(struct snd_soc_codec *codec)
struct spi_message m;
struct spi_transfer t;
struct dfw_pllrec pll_rec;
u32 *img, *p;
u32 *p, len;
u64 *img_swap;
u8 *out;
u32 len;
int i;

spin_lock_irqsave(&wm0010->irq_lock, flags);
Expand Down Expand Up @@ -546,55 +621,9 @@ static int wm0010_boot(struct snd_soc_codec *codec)
wm0010->state = WM0010_BOOTROM;
spin_unlock_irqrestore(&wm0010->irq_lock, flags);

dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size);

/* Copy to local buffer first as vmalloc causes problems for dma */
img = kzalloc(fw->size, GFP_KERNEL);
if (!img) {
dev_err(codec->dev, "Failed to allocate image buffer\n");
goto abort;
}

out = kzalloc(fw->size, GFP_KERNEL);
if (!out) {
dev_err(codec->dev, "Failed to allocate output buffer\n");
goto abort;
}

memcpy(img, &fw->data[0], fw->size);

spi_message_init(&m);
memset(&t, 0, sizeof(t));
t.rx_buf = out;
t.tx_buf = img;
t.len = fw->size;
t.bits_per_word = 8;
t.speed_hz = wm0010->sysclk / 10;
spi_message_add_tail(&t, &m);

dev_dbg(codec->dev, "Starting initial download at %dHz\n",
t.speed_hz);

ret = spi_sync(spi, &m);
if (ret != 0) {
dev_err(codec->dev, "Initial download failed: %d\n", ret);
ret = wm0010_stage2_load(codec);
if (ret)
goto abort;
}

/* Look for errors from the boot ROM */
for (i = 0; i < fw->size; i++) {
if (out[i] != 0x55) {
ret = -EBUSY;
dev_err(codec->dev, "Boot ROM error: %x in %d\n",
out[i], i);
wm0010_mark_boot_failure(wm0010);
goto abort;
}
}

release_firmware(fw);
kfree(img);
kfree(out);

if (!wait_for_completion_timeout(&wm0010->boot_completion,
msecs_to_jiffies(10)))
Expand Down

0 comments on commit 3f5475d

Please sign in to comment.