aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm0010.c
diff options
context:
space:
mode:
authorScott Ling <sl@opensource.wolfsonmicro.com>2012-11-07 11:53:18 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-11-09 06:44:31 -0500
commit3f5475df378cfcac51e9384153aef122555a60cb (patch)
tree442e5c1c19bd70cec8a93815804c3f3afe1563bd /sound/soc/codecs/wm0010.c
parent8f7d52affeb8341cbc602209b6f35eedb410d3ee (diff)
ASoC: wm0010: Split out the stage2 load from the boot function
Signed-off-by: Scott Ling <sl@opensource.wolfsonmicro.com> Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Diffstat (limited to 'sound/soc/codecs/wm0010.c')
-rw-r--r--sound/soc/codecs/wm0010.c129
1 files changed, 79 insertions, 50 deletions
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c
index 7576330044ba..4b68ea86d7cb 100644
--- a/sound/soc/codecs/wm0010.c
+++ b/sound/soc/codecs/wm0010.c
@@ -477,6 +477,82 @@ abort:
477 return ret; 477 return ret;
478} 478}
479 479
480static int wm0010_stage2_load(struct snd_soc_codec *codec)
481{
482 struct spi_device *spi = to_spi_device(codec->dev);
483 struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
484 const struct firmware *fw;
485 struct spi_message m;
486 struct spi_transfer t;
487 u32 *img;
488 u8 *out;
489 int i;
490 int ret = 0;
491
492 ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev);
493 if (ret != 0) {
494 dev_err(codec->dev, "Failed to request stage2 loader: %d\n",
495 ret);
496 return ret;
497 }
498
499 dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size);
500
501 /* Copy to local buffer first as vmalloc causes problems for dma */
502 img = kzalloc(fw->size, GFP_KERNEL);
503 if (!img) {
504 dev_err(codec->dev, "Failed to allocate image buffer\n");
505 ret = -ENOMEM;
506 goto abort2;
507 }
508
509 out = kzalloc(fw->size, GFP_KERNEL);
510 if (!out) {
511 dev_err(codec->dev, "Failed to allocate output buffer\n");
512 ret = -ENOMEM;
513 goto abort1;
514 }
515
516 memcpy(img, &fw->data[0], fw->size);
517
518 spi_message_init(&m);
519 memset(&t, 0, sizeof(t));
520 t.rx_buf = out;
521 t.tx_buf = img;
522 t.len = fw->size;
523 t.bits_per_word = 8;
524 t.speed_hz = wm0010->sysclk / 10;
525 spi_message_add_tail(&t, &m);
526
527 dev_dbg(codec->dev, "Starting initial download at %dHz\n",
528 t.speed_hz);
529
530 ret = spi_sync(spi, &m);
531 if (ret != 0) {
532 dev_err(codec->dev, "Initial download failed: %d\n", ret);
533 goto abort;
534 }
535
536 /* Look for errors from the boot ROM */
537 for (i = 0; i < fw->size; i++) {
538 if (out[i] != 0x55) {
539 dev_err(codec->dev, "Boot ROM error: %x in %d\n",
540 out[i], i);
541 wm0010_mark_boot_failure(wm0010);
542 ret = -EBUSY;
543 goto abort;
544 }
545 }
546abort:
547 kfree(out);
548abort1:
549 kfree(img);
550abort2:
551 release_firmware(fw);
552
553 return ret;
554}
555
480static int wm0010_boot(struct snd_soc_codec *codec) 556static int wm0010_boot(struct snd_soc_codec *codec)
481{ 557{
482 struct spi_device *spi = to_spi_device(codec->dev); 558 struct spi_device *spi = to_spi_device(codec->dev);
@@ -487,10 +563,9 @@ static int wm0010_boot(struct snd_soc_codec *codec)
487 struct spi_message m; 563 struct spi_message m;
488 struct spi_transfer t; 564 struct spi_transfer t;
489 struct dfw_pllrec pll_rec; 565 struct dfw_pllrec pll_rec;
490 u32 *img, *p; 566 u32 *p, len;
491 u64 *img_swap; 567 u64 *img_swap;
492 u8 *out; 568 u8 *out;
493 u32 len;
494 int i; 569 int i;
495 570
496 spin_lock_irqsave(&wm0010->irq_lock, flags); 571 spin_lock_irqsave(&wm0010->irq_lock, flags);
@@ -546,55 +621,9 @@ static int wm0010_boot(struct snd_soc_codec *codec)
546 wm0010->state = WM0010_BOOTROM; 621 wm0010->state = WM0010_BOOTROM;
547 spin_unlock_irqrestore(&wm0010->irq_lock, flags); 622 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
548 623
549 dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size); 624 ret = wm0010_stage2_load(codec);
550 625 if (ret)
551 /* Copy to local buffer first as vmalloc causes problems for dma */
552 img = kzalloc(fw->size, GFP_KERNEL);
553 if (!img) {
554 dev_err(codec->dev, "Failed to allocate image buffer\n");
555 goto abort;
556 }
557
558 out = kzalloc(fw->size, GFP_KERNEL);
559 if (!out) {
560 dev_err(codec->dev, "Failed to allocate output buffer\n");
561 goto abort;
562 }
563
564 memcpy(img, &fw->data[0], fw->size);
565
566 spi_message_init(&m);
567 memset(&t, 0, sizeof(t));
568 t.rx_buf = out;
569 t.tx_buf = img;
570 t.len = fw->size;
571 t.bits_per_word = 8;
572 t.speed_hz = wm0010->sysclk / 10;
573 spi_message_add_tail(&t, &m);
574
575 dev_dbg(codec->dev, "Starting initial download at %dHz\n",
576 t.speed_hz);
577
578 ret = spi_sync(spi, &m);
579 if (ret != 0) {
580 dev_err(codec->dev, "Initial download failed: %d\n", ret);
581 goto abort; 626 goto abort;
582 }
583
584 /* Look for errors from the boot ROM */
585 for (i = 0; i < fw->size; i++) {
586 if (out[i] != 0x55) {
587 ret = -EBUSY;
588 dev_err(codec->dev, "Boot ROM error: %x in %d\n",
589 out[i], i);
590 wm0010_mark_boot_failure(wm0010);
591 goto abort;
592 }
593 }
594
595 release_firmware(fw);
596 kfree(img);
597 kfree(out);
598 627
599 if (!wait_for_completion_timeout(&wm0010->boot_completion, 628 if (!wait_for_completion_timeout(&wm0010->boot_completion,
600 msecs_to_jiffies(10))) 629 msecs_to_jiffies(10)))