aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-rw-r--r--sound/soc/codecs/wm0010.c419
1 files changed, 248 insertions, 171 deletions
diff --git a/sound/soc/codecs/wm0010.c b/sound/soc/codecs/wm0010.c
index 99afc003a084..40256b526259 100644
--- a/sound/soc/codecs/wm0010.c
+++ b/sound/soc/codecs/wm0010.c
@@ -31,6 +31,9 @@
31 31
32#define DEVICE_ID_WM0010 10 32#define DEVICE_ID_WM0010 10
33 33
34/* We only support v1 of the .dfw INFO record */
35#define INFO_VERSION 1
36
34enum dfw_cmd { 37enum dfw_cmd {
35 DFW_CMD_FUSE = 0x01, 38 DFW_CMD_FUSE = 0x01,
36 DFW_CMD_CODE_HDR, 39 DFW_CMD_CODE_HDR,
@@ -46,6 +49,13 @@ struct dfw_binrec {
46 uint8_t data[0]; 49 uint8_t data[0];
47} __packed; 50} __packed;
48 51
52struct dfw_inforec {
53 u8 info_version;
54 u8 tool_major_version;
55 u8 tool_minor_version;
56 u8 dsp_target;
57};
58
49struct dfw_pllrec { 59struct dfw_pllrec {
50 u8 command; 60 u8 command;
51 u32 length:24; 61 u32 length:24;
@@ -97,7 +107,6 @@ struct wm0010_priv {
97 107
98 enum wm0010_state state; 108 enum wm0010_state state;
99 bool boot_failed; 109 bool boot_failed;
100 int boot_done;
101 bool ready; 110 bool ready;
102 bool pll_running; 111 bool pll_running;
103 int max_spi_freq; 112 int max_spi_freq;
@@ -234,7 +243,7 @@ static void wm0010_boot_xfer_complete(void *data)
234 break; 243 break;
235 244
236 case 0x55555555: 245 case 0x55555555:
237 if (wm0010->boot_done == 0) 246 if (wm0010->state < WM0010_STAGE2)
238 break; 247 break;
239 dev_err(codec->dev, 248 dev_err(codec->dev,
240 "%d: ROM bootloader running in stage 2\n", i); 249 "%d: ROM bootloader running in stage 2\n", i);
@@ -321,7 +330,6 @@ static void wm0010_boot_xfer_complete(void *data)
321 break; 330 break;
322 } 331 }
323 332
324 wm0010->boot_done++;
325 if (xfer->done) 333 if (xfer->done)
326 complete(xfer->done); 334 complete(xfer->done);
327} 335}
@@ -334,94 +342,198 @@ static void byte_swap_64(u64 *data_in, u64 *data_out, u32 len)
334 data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i])); 342 data_out[i] = cpu_to_be64(le64_to_cpu(data_in[i]));
335} 343}
336 344
337static int wm0010_boot(struct snd_soc_codec *codec) 345static int wm0010_firmware_load(char *name, struct snd_soc_codec *codec)
338{ 346{
339 struct spi_device *spi = to_spi_device(codec->dev); 347 struct spi_device *spi = to_spi_device(codec->dev);
340 struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec); 348 struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
341 unsigned long flags;
342 struct list_head xfer_list; 349 struct list_head xfer_list;
343 struct wm0010_boot_xfer *xfer; 350 struct wm0010_boot_xfer *xfer;
344 int ret; 351 int ret;
345 struct completion done; 352 struct completion done;
346 const struct firmware *fw; 353 const struct firmware *fw;
347 const struct dfw_binrec *rec; 354 const struct dfw_binrec *rec;
348 struct spi_message m; 355 const struct dfw_inforec *inforec;
349 struct spi_transfer t; 356 u64 *img;
350 struct dfw_pllrec pll_rec; 357 u8 *out, dsp;
351 u32 *img, *p;
352 u64 *img_swap;
353 u8 *out;
354 u32 len, offset; 358 u32 len, offset;
355 int i;
356 359
357 spin_lock_irqsave(&wm0010->irq_lock, flags); 360 INIT_LIST_HEAD(&xfer_list);
358 if (wm0010->state != WM0010_POWER_OFF)
359 dev_warn(wm0010->dev, "DSP already powered up!\n");
360 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
361 361
362 if (wm0010->sysclk > 26000000) { 362 ret = request_firmware(&fw, name, codec->dev);
363 dev_err(codec->dev, "Max DSP clock frequency is 26MHz\n"); 363 if (ret != 0) {
364 ret = -ECANCELED; 364 dev_err(codec->dev, "Failed to request application: %d\n",
365 goto err; 365 ret);
366 return ret;
366 } 367 }
367 368
368 INIT_LIST_HEAD(&xfer_list); 369 rec = (const struct dfw_binrec *)fw->data;
370 inforec = (const struct dfw_inforec *)rec->data;
371 offset = 0;
372 dsp = inforec->dsp_target;
373 wm0010->boot_failed = false;
374 BUG_ON(!list_empty(&xfer_list));
375 init_completion(&done);
369 376
370 mutex_lock(&wm0010->lock); 377 /* First record should be INFO */
371 wm0010->pll_running = false; 378 if (rec->command != DFW_CMD_INFO) {
379 dev_err(codec->dev, "First record not INFO\r\n");
380 ret = -EINVAL;
381 goto abort;
382 }
372 383
373 dev_dbg(codec->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq); 384 if (inforec->info_version != INFO_VERSION) {
385 dev_err(codec->dev,
386 "Unsupported version (%02d) of INFO record\r\n",
387 inforec->info_version);
388 ret = -EINVAL;
389 goto abort;
390 }
374 391
375 ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies), 392 dev_dbg(codec->dev, "Version v%02d INFO record found\r\n",
376 wm0010->core_supplies); 393 inforec->info_version);
377 if (ret != 0) { 394
378 dev_err(&spi->dev, "Failed to enable core supplies: %d\n", 395 /* Check it's a DSP file */
379 ret); 396 if (dsp != DEVICE_ID_WM0010) {
380 mutex_unlock(&wm0010->lock); 397 dev_err(codec->dev, "Not a WM0010 firmware file.\r\n");
381 goto err; 398 ret = -EINVAL;
399 goto abort;
382 } 400 }
383 401
384 ret = regulator_enable(wm0010->dbvdd); 402 /* Skip the info record as we don't need to send it */
385 if (ret != 0) { 403 offset += ((rec->length) + 8);
386 dev_err(&spi->dev, "Failed to enable DBVDD: %d\n", ret); 404 rec = (void *)&rec->data[rec->length];
387 goto err_core; 405
406 while (offset < fw->size) {
407 dev_dbg(codec->dev,
408 "Packet: command %d, data length = 0x%x\r\n",
409 rec->command, rec->length);
410 len = rec->length + 8;
411
412 out = kzalloc(len, GFP_KERNEL);
413 if (!out) {
414 dev_err(codec->dev,
415 "Failed to allocate RX buffer\n");
416 ret = -ENOMEM;
417 goto abort1;
418 }
419
420 img = kzalloc(len, GFP_KERNEL);
421 if (!img) {
422 dev_err(codec->dev,
423 "Failed to allocate image buffer\n");
424 ret = -ENOMEM;
425 goto abort1;
426 }
427
428 byte_swap_64((u64 *)&rec->command, img, len);
429
430 xfer = kzalloc(sizeof(*xfer), GFP_KERNEL);
431 if (!xfer) {
432 dev_err(codec->dev, "Failed to allocate xfer\n");
433 ret = -ENOMEM;
434 goto abort1;
435 }
436
437 xfer->codec = codec;
438 list_add_tail(&xfer->list, &xfer_list);
439
440 spi_message_init(&xfer->m);
441 xfer->m.complete = wm0010_boot_xfer_complete;
442 xfer->m.context = xfer;
443 xfer->t.tx_buf = img;
444 xfer->t.rx_buf = out;
445 xfer->t.len = len;
446 xfer->t.bits_per_word = 8;
447
448 if (!wm0010->pll_running) {
449 xfer->t.speed_hz = wm0010->sysclk / 6;
450 } else {
451 xfer->t.speed_hz = wm0010->max_spi_freq;
452
453 if (wm0010->board_max_spi_speed &&
454 (wm0010->board_max_spi_speed < wm0010->max_spi_freq))
455 xfer->t.speed_hz = wm0010->board_max_spi_speed;
456 }
457
458 /* Store max usable spi frequency for later use */
459 wm0010->max_spi_freq = xfer->t.speed_hz;
460
461 spi_message_add_tail(&xfer->t, &xfer->m);
462
463 offset += ((rec->length) + 8);
464 rec = (void *)&rec->data[rec->length];
465
466 if (offset >= fw->size) {
467 dev_dbg(codec->dev, "All transfers scheduled\n");
468 xfer->done = &done;
469 }
470
471 ret = spi_async(spi, &xfer->m);
472 if (ret != 0) {
473 dev_err(codec->dev, "Write failed: %d\n", ret);
474 goto abort1;
475 }
476
477 if (wm0010->boot_failed) {
478 dev_dbg(codec->dev, "Boot fail!\n");
479 ret = -EINVAL;
480 goto abort1;
481 }
388 } 482 }
389 483
390 /* Release reset */ 484 wait_for_completion(&done);
391 gpio_set_value_cansleep(wm0010->gpio_reset, !wm0010->gpio_reset_value); 485
392 spin_lock_irqsave(&wm0010->irq_lock, flags); 486 ret = 0;
393 wm0010->state = WM0010_OUT_OF_RESET; 487
394 spin_unlock_irqrestore(&wm0010->irq_lock, flags); 488abort1:
489 while (!list_empty(&xfer_list)) {
490 xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer,
491 list);
492 kfree(xfer->t.rx_buf);
493 kfree(xfer->t.tx_buf);
494 list_del(&xfer->list);
495 kfree(xfer);
496 }
497
498abort:
499 release_firmware(fw);
500 return ret;
501}
502
503static int wm0010_stage2_load(struct snd_soc_codec *codec)
504{
505 struct spi_device *spi = to_spi_device(codec->dev);
506 struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
507 const struct firmware *fw;
508 struct spi_message m;
509 struct spi_transfer t;
510 u32 *img;
511 u8 *out;
512 int i;
513 int ret = 0;
395 514
396 /* First the bootloader */
397 ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev); 515 ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev);
398 if (ret != 0) { 516 if (ret != 0) {
399 dev_err(codec->dev, "Failed to request stage2 loader: %d\n", 517 dev_err(codec->dev, "Failed to request stage2 loader: %d\n",
400 ret); 518 ret);
401 goto abort; 519 return ret;
402 } 520 }
403 521
404 if (!wait_for_completion_timeout(&wm0010->boot_completion,
405 msecs_to_jiffies(10)))
406 dev_err(codec->dev, "Failed to get interrupt from DSP\n");
407
408 spin_lock_irqsave(&wm0010->irq_lock, flags);
409 wm0010->state = WM0010_BOOTROM;
410 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
411
412 dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size); 522 dev_dbg(codec->dev, "Downloading %zu byte stage 2 loader\n", fw->size);
413 523
414 /* Copy to local buffer first as vmalloc causes problems for dma */ 524 /* Copy to local buffer first as vmalloc causes problems for dma */
415 img = kzalloc(fw->size, GFP_KERNEL); 525 img = kzalloc(fw->size, GFP_KERNEL);
416 if (!img) { 526 if (!img) {
417 dev_err(codec->dev, "Failed to allocate image buffer\n"); 527 dev_err(codec->dev, "Failed to allocate image buffer\n");
418 goto abort; 528 ret = -ENOMEM;
529 goto abort2;
419 } 530 }
420 531
421 out = kzalloc(fw->size, GFP_KERNEL); 532 out = kzalloc(fw->size, GFP_KERNEL);
422 if (!out) { 533 if (!out) {
423 dev_err(codec->dev, "Failed to allocate output buffer\n"); 534 dev_err(codec->dev, "Failed to allocate output buffer\n");
424 goto abort; 535 ret = -ENOMEM;
536 goto abort1;
425 } 537 }
426 538
427 memcpy(img, &fw->data[0], fw->size); 539 memcpy(img, &fw->data[0], fw->size);
@@ -447,20 +559,97 @@ static int wm0010_boot(struct snd_soc_codec *codec)
447 /* Look for errors from the boot ROM */ 559 /* Look for errors from the boot ROM */
448 for (i = 0; i < fw->size; i++) { 560 for (i = 0; i < fw->size; i++) {
449 if (out[i] != 0x55) { 561 if (out[i] != 0x55) {
450 ret = -EBUSY;
451 dev_err(codec->dev, "Boot ROM error: %x in %d\n", 562 dev_err(codec->dev, "Boot ROM error: %x in %d\n",
452 out[i], i); 563 out[i], i);
453 wm0010_mark_boot_failure(wm0010); 564 wm0010_mark_boot_failure(wm0010);
565 ret = -EBUSY;
454 goto abort; 566 goto abort;
455 } 567 }
456 } 568 }
457 569abort:
458 release_firmware(fw);
459 kfree(img);
460 kfree(out); 570 kfree(out);
571abort1:
572 kfree(img);
573abort2:
574 release_firmware(fw);
575
576 return ret;
577}
578
579static int wm0010_boot(struct snd_soc_codec *codec)
580{
581 struct spi_device *spi = to_spi_device(codec->dev);
582 struct wm0010_priv *wm0010 = snd_soc_codec_get_drvdata(codec);
583 unsigned long flags;
584 int ret;
585 const struct firmware *fw;
586 struct spi_message m;
587 struct spi_transfer t;
588 struct dfw_pllrec pll_rec;
589 u32 *p, len;
590 u64 *img_swap;
591 u8 *out;
592 int i;
593
594 spin_lock_irqsave(&wm0010->irq_lock, flags);
595 if (wm0010->state != WM0010_POWER_OFF)
596 dev_warn(wm0010->dev, "DSP already powered up!\n");
597 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
598
599 if (wm0010->sysclk > 26000000) {
600 dev_err(codec->dev, "Max DSP clock frequency is 26MHz\n");
601 ret = -ECANCELED;
602 goto err;
603 }
604
605 mutex_lock(&wm0010->lock);
606 wm0010->pll_running = false;
607
608 dev_dbg(codec->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq);
609
610 ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies),
611 wm0010->core_supplies);
612 if (ret != 0) {
613 dev_err(&spi->dev, "Failed to enable core supplies: %d\n",
614 ret);
615 mutex_unlock(&wm0010->lock);
616 goto err;
617 }
618
619 ret = regulator_enable(wm0010->dbvdd);
620 if (ret != 0) {
621 dev_err(&spi->dev, "Failed to enable DBVDD: %d\n", ret);
622 goto err_core;
623 }
624
625 /* Release reset */
626 gpio_set_value_cansleep(wm0010->gpio_reset, !wm0010->gpio_reset_value);
627 spin_lock_irqsave(&wm0010->irq_lock, flags);
628 wm0010->state = WM0010_OUT_OF_RESET;
629 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
630
631 /* First the bootloader */
632 ret = request_firmware(&fw, "wm0010_stage2.bin", codec->dev);
633 if (ret != 0) {
634 dev_err(codec->dev, "Failed to request stage2 loader: %d\n",
635 ret);
636 goto abort;
637 }
638
639 if (!wait_for_completion_timeout(&wm0010->boot_completion,
640 msecs_to_jiffies(20)))
641 dev_err(codec->dev, "Failed to get interrupt from DSP\n");
642
643 spin_lock_irqsave(&wm0010->irq_lock, flags);
644 wm0010->state = WM0010_BOOTROM;
645 spin_unlock_irqrestore(&wm0010->irq_lock, flags);
646
647 ret = wm0010_stage2_load(codec);
648 if (ret)
649 goto abort;
461 650
462 if (!wait_for_completion_timeout(&wm0010->boot_completion, 651 if (!wait_for_completion_timeout(&wm0010->boot_completion,
463 msecs_to_jiffies(10))) 652 msecs_to_jiffies(20)))
464 dev_err(codec->dev, "Failed to get interrupt from DSP loader.\n"); 653 dev_err(codec->dev, "Failed to get interrupt from DSP loader.\n");
465 654
466 spin_lock_irqsave(&wm0010->irq_lock, flags); 655 spin_lock_irqsave(&wm0010->irq_lock, flags);
@@ -535,110 +724,10 @@ static int wm0010_boot(struct snd_soc_codec *codec)
535 } else 724 } else
536 dev_dbg(codec->dev, "Not enabling DSP PLL."); 725 dev_dbg(codec->dev, "Not enabling DSP PLL.");
537 726
538 ret = request_firmware(&fw, "wm0010.dfw", codec->dev); 727 ret = wm0010_firmware_load("wm0010.dfw", codec);
539 if (ret != 0) {
540 dev_err(codec->dev, "Failed to request application: %d\n",
541 ret);
542 goto abort;
543 }
544
545 rec = (const struct dfw_binrec *)fw->data;
546 offset = 0;
547 wm0010->boot_done = 0;
548 wm0010->boot_failed = false;
549 BUG_ON(!list_empty(&xfer_list));
550 init_completion(&done);
551 728
552 /* First record should be INFO */ 729 if (ret != 0)
553 if (rec->command != DFW_CMD_INFO) {
554 dev_err(codec->dev, "First record not INFO\r\n");
555 goto abort;
556 }
557
558 /* Check it's a 0010 file */
559 if (rec->data[0] != DEVICE_ID_WM0010) {
560 dev_err(codec->dev, "Not a WM0010 firmware file.\r\n");
561 goto abort; 730 goto abort;
562 }
563
564 /* Skip the info record as we don't need to send it */
565 offset += ((rec->length) + 8);
566 rec = (void *)&rec->data[rec->length];
567
568 while (offset < fw->size) {
569 dev_dbg(codec->dev,
570 "Packet: command %d, data length = 0x%x\r\n",
571 rec->command, rec->length);
572 len = rec->length + 8;
573
574 out = kzalloc(len, GFP_KERNEL);
575 if (!out) {
576 dev_err(codec->dev,
577 "Failed to allocate RX buffer\n");
578 goto abort;
579 }
580
581 img_swap = kzalloc(len, GFP_KERNEL);
582 if (!img_swap) {
583 dev_err(codec->dev,
584 "Failed to allocate image buffer\n");
585 goto abort;
586 }
587
588 /* We need to re-order for 0010 */
589 byte_swap_64((u64 *)&rec->command, img_swap, len);
590
591 xfer = kzalloc(sizeof(*xfer), GFP_KERNEL);
592 if (!xfer) {
593 dev_err(codec->dev, "Failed to allocate xfer\n");
594 goto abort;
595 }
596
597 xfer->codec = codec;
598 list_add_tail(&xfer->list, &xfer_list);
599
600 spi_message_init(&xfer->m);
601 xfer->m.complete = wm0010_boot_xfer_complete;
602 xfer->m.context = xfer;
603 xfer->t.tx_buf = img_swap;
604 xfer->t.rx_buf = out;
605 xfer->t.len = len;
606 xfer->t.bits_per_word = 8;
607
608 if (!wm0010->pll_running) {
609 xfer->t.speed_hz = wm0010->sysclk / 6;
610 } else {
611 xfer->t.speed_hz = wm0010->max_spi_freq;
612
613 if (wm0010->board_max_spi_speed &&
614 (wm0010->board_max_spi_speed < wm0010->max_spi_freq))
615 xfer->t.speed_hz = wm0010->board_max_spi_speed;
616 }
617
618 /* Store max usable spi frequency for later use */
619 wm0010->max_spi_freq = xfer->t.speed_hz;
620
621 spi_message_add_tail(&xfer->t, &xfer->m);
622
623 offset += ((rec->length) + 8);
624 rec = (void *)&rec->data[rec->length];
625
626 if (offset >= fw->size) {
627 dev_dbg(codec->dev, "All transfers scheduled\n");
628 xfer->done = &done;
629 }
630
631 ret = spi_async(spi, &xfer->m);
632 if (ret != 0) {
633 dev_err(codec->dev, "Write failed: %d\n", ret);
634 goto abort;
635 }
636
637 if (wm0010->boot_failed)
638 goto abort;
639 }
640
641 wait_for_completion(&done);
642 731
643 spin_lock_irqsave(&wm0010->irq_lock, flags); 732 spin_lock_irqsave(&wm0010->irq_lock, flags);
644 wm0010->state = WM0010_FIRMWARE; 733 wm0010->state = WM0010_FIRMWARE;
@@ -646,17 +735,6 @@ static int wm0010_boot(struct snd_soc_codec *codec)
646 735
647 mutex_unlock(&wm0010->lock); 736 mutex_unlock(&wm0010->lock);
648 737
649 release_firmware(fw);
650
651 while (!list_empty(&xfer_list)) {
652 xfer = list_first_entry(&xfer_list, struct wm0010_boot_xfer,
653 list);
654 kfree(xfer->t.rx_buf);
655 kfree(xfer->t.tx_buf);
656 list_del(&xfer->list);
657 kfree(xfer);
658 }
659
660 return 0; 738 return 0;
661 739
662abort: 740abort:
@@ -784,7 +862,6 @@ static irqreturn_t wm0010_irq(int irq, void *data)
784 struct wm0010_priv *wm0010 = data; 862 struct wm0010_priv *wm0010 = data;
785 863
786 switch (wm0010->state) { 864 switch (wm0010->state) {
787 case WM0010_POWER_OFF:
788 case WM0010_OUT_OF_RESET: 865 case WM0010_OUT_OF_RESET:
789 case WM0010_BOOTROM: 866 case WM0010_BOOTROM:
790 case WM0010_STAGE2: 867 case WM0010_STAGE2: