summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/arm/as3525/sd-as3525.c15
-rw-r--r--firmware/target/arm/as3525/sd-as3525v2.c8
-rw-r--r--firmware/target/arm/as3525/system-as3525.c2
-rw-r--r--firmware/target/arm/ata-nand-telechips.c92
-rw-r--r--firmware/target/arm/imx233/clkctrl-imx233.c28
-rw-r--r--firmware/target/arm/imx233/clkctrl-imx233.h2
-rw-r--r--firmware/target/arm/imx233/nand-imx233.c4
-rw-r--r--firmware/target/arm/imx233/partitions-imx233.c8
-rw-r--r--firmware/target/arm/imx233/partitions-imx233.h6
-rw-r--r--firmware/target/arm/imx233/sdmmc-imx233.c20
-rw-r--r--firmware/target/arm/ipod/button-clickwheel.c8
-rw-r--r--firmware/target/arm/pp/ata-pp5020.c24
-rw-r--r--firmware/target/arm/pp/ata-sd-pp.c40
-rw-r--r--firmware/target/arm/rk27xx/ata-nand-rk27xx.c8
-rw-r--r--firmware/target/arm/rk27xx/sd-rk27xx.c9
-rw-r--r--firmware/target/arm/s3c2440/sd-s3c2440.c171
-rw-r--r--firmware/target/arm/s5l8700/ata-nand-s5l8700.c8
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c15
-rw-r--r--firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c585
-rw-r--r--firmware/target/arm/tcc780x/sd-tcc780x.c94
-rw-r--r--firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c22
-rw-r--r--firmware/target/arm/tms320dm320/creative-zvm/ata-target.h4
-rw-r--r--firmware/target/arm/tms320dm320/sdmmc-dm320.c23
-rw-r--r--firmware/target/arm/tms320dm320/system-dm320.c2
-rw-r--r--firmware/target/coldfire/system-coldfire.c5
-rw-r--r--firmware/target/hosted/agptek/debug-agptek.c6
-rw-r--r--firmware/target/hosted/aigo/power-erosq.c55
-rw-r--r--firmware/target/hosted/alsa-controls.h2
-rw-r--r--firmware/target/hosted/filesystem-hosted.h3
-rw-r--r--firmware/target/hosted/filesystem-unix.c6
-rw-r--r--firmware/target/hosted/filesystem-win32.c5
-rw-r--r--firmware/target/hosted/lcd-linuxfb.c24
-rw-r--r--firmware/target/hosted/power-linux.c5
-rw-r--r--firmware/target/hosted/sdl/app/button-application.c26
-rw-r--r--firmware/target/hosted/sdl/button-sdl.c88
-rw-r--r--firmware/target/hosted/sdl/kernel-sdl.c12
-rw-r--r--firmware/target/hosted/sdl/key_to_touch-sdl.c19
-rw-r--r--firmware/target/hosted/sdl/lcd-bitmap.c9
-rw-r--r--firmware/target/hosted/sdl/lcd-sdl.c13
-rw-r--r--firmware/target/hosted/sdl/lcd-sdl.h4
-rw-r--r--firmware/target/hosted/sdl/pcm-sdl.c88
-rw-r--r--firmware/target/hosted/sdl/system-sdl.c116
-rw-r--r--firmware/target/hosted/sdl/thread-sdl.c4
-rw-r--r--firmware/target/mips/ingenic_jz47xx/app.lds8
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c24
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c26
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c30
-rw-r--r--firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c17
-rw-r--r--firmware/target/mips/ingenic_jz47xx/crt0.S2
-rw-r--r--firmware/target/mips/ingenic_jz47xx/xduoo_x3/power-xduoo_x3.c12
-rw-r--r--firmware/target/mips/ingenic_x1000/crt0.S7
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c40
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c26
-rw-r--r--firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c146
-rw-r--r--firmware/target/mips/ingenic_x1000/msc-x1000.c2
-rw-r--r--firmware/target/mips/ingenic_x1000/sd-x1000.c14
-rw-r--r--firmware/target/mips/ingenic_x1000/system-x1000.c19
-rw-r--r--firmware/target/mips/ingenic_x1000/x1000boot.make2
58 files changed, 1252 insertions, 811 deletions
diff --git a/firmware/target/arm/as3525/sd-as3525.c b/firmware/target/arm/as3525/sd-as3525.c
index 70e0778d2b..df39cba495 100644
--- a/firmware/target/arm/as3525/sd-as3525.c
+++ b/firmware/target/arm/as3525/sd-as3525.c
@@ -446,7 +446,7 @@ static int sd_init_card(const int drive)
446 sd_parse_csd(&card_info[drive]); 446 sd_parse_csd(&card_info[drive]);
447 447
448#if defined(HAVE_MULTIDRIVE) 448#if defined(HAVE_MULTIDRIVE)
449 hs_card = (card_info[drive].speed == 50000000); 449 hs_card = (card_info[drive].speed >= 50000000);
450#endif 450#endif
451 451
452 /* Boost MCICLK to operating speed */ 452 /* Boost MCICLK to operating speed */
@@ -455,7 +455,7 @@ static int sd_init_card(const int drive)
455#if defined(HAVE_MULTIDRIVE) 455#if defined(HAVE_MULTIDRIVE)
456 else 456 else
457 /* MCICLK = PCLK/2 = 31MHz(HS) or PCLK/4 = 15.5 Mhz (STD)*/ 457 /* MCICLK = PCLK/2 = 31MHz(HS) or PCLK/4 = 15.5 Mhz (STD)*/
458 MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED) | 458 MCI_CLOCK(drive) = (hs_card ? MCI_HALFSPEED : MCI_QUARTERSPEED) |
459 MCI_CLOCK_POWERSAVE; /* SD supports powersave */ 459 MCI_CLOCK_POWERSAVE; /* SD supports powersave */
460#endif 460#endif
461 461
@@ -680,7 +680,7 @@ static int sd_select_bank(signed char bank)
680 return 0; 680 return 0;
681} 681}
682 682
683static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start, 683static int sd_transfer_sectors(IF_MD(int drive,) sector_t start,
684 int count, void* buf, const bool write) 684 int count, void* buf, const bool write)
685{ 685{
686#ifndef HAVE_MULTIDRIVE 686#ifndef HAVE_MULTIDRIVE
@@ -735,7 +735,8 @@ static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start,
735 unsigned int transfer = (count >= 128) ? 127 : count; /* sectors */ 735 unsigned int transfer = (count >= 128) ? 127 : count; /* sectors */
736 void *dma_buf; 736 void *dma_buf;
737 737
738 unsigned long bank_start = start; 738 sector_t bank_start = start;
739 // XXX 64-bit sectors?
739 740
740 /* Only switch banks for internal storage */ 741 /* Only switch banks for internal storage */
741 if(drive == INTERNAL_AS3525) 742 if(drive == INTERNAL_AS3525)
@@ -869,7 +870,7 @@ sd_transfer_error_nodma:
869 return ret; 870 return ret;
870} 871}
871 872
872int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, 873int sd_read_sectors(IF_MD(int drive,) sector_t start, int count,
873 void* buf) 874 void* buf)
874{ 875{
875 int ret; 876 int ret;
@@ -881,11 +882,11 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
881 return ret; 882 return ret;
882} 883}
883 884
884int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, 885int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
885 const void* buf) 886 const void* buf)
886{ 887{
887#ifdef VERIFY_WRITE 888#ifdef VERIFY_WRITE
888 unsigned long saved_start = start; 889 sector_t saved_start = start;
889 int saved_count = count; 890 int saved_count = count;
890 void *saved_buf = (void*)buf; 891 void *saved_buf = (void*)buf;
891#endif 892#endif
diff --git a/firmware/target/arm/as3525/sd-as3525v2.c b/firmware/target/arm/as3525/sd-as3525v2.c
index b512cc2ea4..f9ef7d9c97 100644
--- a/firmware/target/arm/as3525/sd-as3525v2.c
+++ b/firmware/target/arm/as3525/sd-as3525v2.c
@@ -677,7 +677,7 @@ int sd_init(void)
677 return 0; 677 return 0;
678} 678}
679 679
680static int sd_transfer_sectors(IF_MD(int drive,) unsigned long start, 680static int sd_transfer_sectors(IF_MD(int drive,) sector_t start,
681 int count, void* buf, bool write) 681 int count, void* buf, bool write)
682{ 682{
683 unsigned long response; 683 unsigned long response;
@@ -776,7 +776,7 @@ retry_with_reinit:
776 776
777 MCI_BYTCNT = transfer * SD_BLOCK_SIZE; 777 MCI_BYTCNT = transfer * SD_BLOCK_SIZE;
778 778
779 int arg = start; 779 sector_t arg = start; // XXX 64-bit
780 if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */ 780 if(!(card_info[drive].ocr & (1<<30))) /* not SDHC */
781 arg *= SD_BLOCK_SIZE; 781 arg *= SD_BLOCK_SIZE;
782 782
@@ -858,13 +858,13 @@ exit:
858 return ret; 858 return ret;
859} 859}
860 860
861int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, 861int sd_read_sectors(IF_MD(int drive,) sector_t start, int count,
862 void* buf) 862 void* buf)
863{ 863{
864 return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false); 864 return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false);
865} 865}
866 866
867int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, 867int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
868 const void* buf) 868 const void* buf)
869{ 869{
870 return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true); 870 return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true);
diff --git a/firmware/target/arm/as3525/system-as3525.c b/firmware/target/arm/as3525/system-as3525.c
index 0450c8b410..26a228cddf 100644
--- a/firmware/target/arm/as3525/system-as3525.c
+++ b/firmware/target/arm/as3525/system-as3525.c
@@ -92,7 +92,7 @@ void INT_GPIOA(void);
92default_interrupt(INT_GPIOB); 92default_interrupt(INT_GPIOB);
93default_interrupt(INT_GPIOC); 93default_interrupt(INT_GPIOC);
94 94
95static const char const irqname[][9] = 95static const char irqname[][9] =
96{ 96{
97 "WATCHDOG", "TIMER1", "TIMER2", "USB", "DMAC", "NAND", 97 "WATCHDOG", "TIMER1", "TIMER2", "USB", "DMAC", "NAND",
98 "IDE", "MCI0", "MCI1", "AUDIO", "SSP", "I2C_MS", 98 "IDE", "MCI0", "MCI1", "AUDIO", "SSP", "I2C_MS",
diff --git a/firmware/target/arm/ata-nand-telechips.c b/firmware/target/arm/ata-nand-telechips.c
index d61c223219..453a51ed1b 100644
--- a/firmware/target/arm/ata-nand-telechips.c
+++ b/firmware/target/arm/ata-nand-telechips.c
@@ -179,7 +179,7 @@ static int phys_segment_to_page_addr(int phys_segment, int page_in_seg)
179 break; 179 break;
180 } 180 }
181 } 181 }
182 182
183 page_addr += (page_in_seg / nand_data->planes); 183 page_addr += (page_in_seg / nand_data->planes);
184 184
185 return page_addr; 185 return page_addr;
@@ -222,7 +222,7 @@ static void nand_chip_select(int bank)
222static void nand_read_id(int bank, unsigned char* id_buf) 222static void nand_read_id(int bank, unsigned char* id_buf)
223{ 223{
224 int i; 224 int i;
225 225
226 /* Enable NFC bus clock */ 226 /* Enable NFC bus clock */
227 BCLKCTR |= DEV_NAND; 227 BCLKCTR |= DEV_NAND;
228 228
@@ -358,7 +358,7 @@ static void nand_setup_read(int bank, int row, int column)
358static void nand_end_read(void) 358static void nand_end_read(void)
359{ 359{
360 nand_chip_select(-1); 360 nand_chip_select(-1);
361 361
362 /* Disable NFC bus clock */ 362 /* Disable NFC bus clock */
363 BCLKCTR &= ~DEV_NAND; 363 BCLKCTR &= ~DEV_NAND;
364} 364}
@@ -367,7 +367,7 @@ static void nand_end_read(void)
367static void nand_read_raw(int bank, int row, int column, int size, void* buf) 367static void nand_read_raw(int bank, int row, int column, int size, void* buf)
368{ 368{
369 int i; 369 int i;
370 370
371 nand_setup_read(bank, row, column); 371 nand_setup_read(bank, row, column);
372 372
373 /* Read data into page buffer */ 373 /* Read data into page buffer */
@@ -388,7 +388,7 @@ static void nand_read_raw(int bank, int row, int column, int size, void* buf)
388 ((unsigned int*)buf)[i] = NFC_WDATA; 388 ((unsigned int*)buf)[i] = NFC_WDATA;
389 } 389 }
390 } 390 }
391 391
392 nand_end_read(); 392 nand_end_read();
393} 393}
394 394
@@ -422,7 +422,7 @@ static void nand_get_chip_info(void)
422 sectors_per_page = nand_data->page_size / SECTOR_SIZE; 422 sectors_per_page = nand_data->page_size / SECTOR_SIZE;
423 423
424 sectors_per_segment = bytes_per_segment / SECTOR_SIZE; 424 sectors_per_segment = bytes_per_segment / SECTOR_SIZE;
425 425
426 pages_per_segment = sectors_per_segment / sectors_per_page; 426 pages_per_segment = sectors_per_segment / sectors_per_page;
427 427
428 /* Establish how many banks are present */ 428 /* Establish how many banks are present */
@@ -494,7 +494,7 @@ static bool nand_read_sector_of_phys_page(int bank, int page,
494 494
495#ifdef USE_ECC_CORRECTION 495#ifdef USE_ECC_CORRECTION
496 unsigned long spare_buf[4]; 496 unsigned long spare_buf[4];
497 497
498 /* Set up the ECC controller to monitor reads from NFC_WDATA */ 498 /* Set up the ECC controller to monitor reads from NFC_WDATA */
499 BCLKCTR |= DEV_ECC; 499 BCLKCTR |= DEV_ECC;
500 ECC_BASE = (unsigned long)&NFC_WDATA; 500 ECC_BASE = (unsigned long)&NFC_WDATA;
@@ -514,27 +514,27 @@ static bool nand_read_sector_of_phys_page(int bank, int page,
514 This way, reads are always done through NFC_WDATA - otherwise they 514 This way, reads are always done through NFC_WDATA - otherwise they
515 would not be 'seen' by the ECC controller. */ 515 would not be 'seen' by the ECC controller. */
516 static char temp_buf[SECTOR_SIZE]; 516 static char temp_buf[SECTOR_SIZE];
517 517
518 unsigned int* ptr = (unsigned int*) temp_buf; 518 unsigned int* ptr = (unsigned int*) temp_buf;
519 519
520 for (i = 0; i < (SECTOR_SIZE/4); i++) 520 for (i = 0; i < (SECTOR_SIZE/4); i++)
521 { 521 {
522 *ptr++ = NFC_WDATA; 522 *ptr++ = NFC_WDATA;
523 } 523 }
524 524
525 memcpy(buf, temp_buf, SECTOR_SIZE); 525 memcpy(buf, temp_buf, SECTOR_SIZE);
526 } 526 }
527 else 527 else
528 { 528 {
529 /* Use straight word copy as buffer and size are both word-aligned */ 529 /* Use straight word copy as buffer and size are both word-aligned */
530 unsigned int* ptr = (unsigned int*) buf; 530 unsigned int* ptr = (unsigned int*) buf;
531 531
532 for (i = 0; i < (SECTOR_SIZE/4); i++) 532 for (i = 0; i < (SECTOR_SIZE/4); i++)
533 { 533 {
534 *ptr++ = NFC_WDATA; 534 *ptr++ = NFC_WDATA;
535 } 535 }
536 } 536 }
537 537
538#ifdef USE_ECC_CORRECTION 538#ifdef USE_ECC_CORRECTION
539 /* Stop monitoring before we read the OOB data */ 539 /* Stop monitoring before we read the OOB data */
540 ECC_CTRL &= ~ECC_M4EN; 540 ECC_CTRL &= ~ECC_M4EN;
@@ -549,29 +549,29 @@ static bool nand_read_sector_of_phys_page(int bank, int page,
549 /* Calculate MLC4 ECC using bytes 0,1,8-15 */ 549 /* Calculate MLC4 ECC using bytes 0,1,8-15 */
550 BCLKCTR |= DEV_ECC; 550 BCLKCTR |= DEV_ECC;
551 ECC_CTRL |= ECC_M4EN; 551 ECC_CTRL |= ECC_M4EN;
552 552
553 MLC_ECC0W = *(unsigned short*)spare_buf; 553 MLC_ECC0W = *(unsigned short*)spare_buf;
554 MLC_ECC1W = spare_buf[2]; 554 MLC_ECC1W = spare_buf[2];
555 MLC_ECC2W = spare_buf[3]; 555 MLC_ECC2W = spare_buf[3];
556 556
557 while (!(ECC_CTRL & ECC_READY)) {}; 557 while (!(ECC_CTRL & ECC_READY)) {};
558 558
559 int errors = ECC_ERR_NUM & 7; 559 int errors = ECC_ERR_NUM & 7;
560 560
561 switch (errors) 561 switch (errors)
562 { 562 {
563 case 4: /* nothing to correct */ 563 case 4: /* nothing to correct */
564 break; 564 break;
565 565
566 case 7: /* fail, can't correct */ 566 case 7: /* fail, can't correct */
567 ret = false; 567 ret = false;
568 break; 568 break;
569 569
570 default: /* between 1 and 4 errors */ 570 default: /* between 1 and 4 errors */
571 { 571 {
572 int i; 572 int i;
573 unsigned char* char_buf = (unsigned char*)buf; 573 unsigned char* char_buf = (unsigned char*)buf;
574 574
575 for (i = 0; i < errors + 1; i++) 575 for (i = 0; i < errors + 1; i++)
576 { 576 {
577 int offset = 0x207 - ECC_ERRADDR(i); 577 int offset = 0x207 - ECC_ERRADDR(i);
@@ -584,7 +584,7 @@ static bool nand_read_sector_of_phys_page(int bank, int page,
584 ECC_CTRL &= ~ECC_M4EN; 584 ECC_CTRL &= ~ECC_M4EN;
585 BCLKCTR &= ~DEV_ECC; 585 BCLKCTR &= ~DEV_ECC;
586#endif 586#endif
587 587
588 nand_end_read(); 588 nand_end_read();
589 589
590 return ret; 590 return ret;
@@ -619,7 +619,7 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector,
619 619
620 int cache_num = 0; 620 int cache_num = 0;
621 bool found = false; 621 bool found = false;
622 622
623 while (!found && cache_num < write_caches_in_use) 623 while (!found && cache_num < write_caches_in_use)
624 { 624 {
625 if (write_caches[cache_num].log_segment == log_segment) 625 if (write_caches[cache_num].log_segment == log_segment)
@@ -628,10 +628,10 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector,
628 { 628 {
629 /* data is located in random pages cache */ 629 /* data is located in random pages cache */
630 found = true; 630 found = true;
631 631
632 bank = write_caches[cache_num].random_bank; 632 bank = write_caches[cache_num].random_bank;
633 phys_segment = write_caches[cache_num].random_phys_segment; 633 phys_segment = write_caches[cache_num].random_phys_segment;
634 634
635 page_in_segment = 635 page_in_segment =
636 write_caches[cache_num].page_map[page_in_segment]; 636 write_caches[cache_num].page_map[page_in_segment];
637 } 637 }
@@ -640,7 +640,7 @@ static bool nand_read_sector_of_logical_segment(int log_segment, int sector,
640 { 640 {
641 /* data is located in in-place pages cache */ 641 /* data is located in in-place pages cache */
642 found = true; 642 found = true;
643 643
644 bank = write_caches[cache_num].inplace_bank; 644 bank = write_caches[cache_num].inplace_bank;
645 phys_segment = write_caches[cache_num].inplace_phys_segment; 645 phys_segment = write_caches[cache_num].inplace_phys_segment;
646 } 646 }
@@ -664,7 +664,7 @@ static inline unsigned char get_sector_type(char* spare_buf)
664static inline unsigned short get_log_segment_id(int phys_seg, char* spare_buf) 664static inline unsigned short get_log_segment_id(int phys_seg, char* spare_buf)
665{ 665{
666 (void)phys_seg; 666 (void)phys_seg;
667 667
668 return ((spare_buf[OFF_LOG_SEG_HIBYTE] << 8) | 668 return ((spare_buf[OFF_LOG_SEG_HIBYTE] << 8) |
669 spare_buf[OFF_LOG_SEG_LOBYTE]) 669 spare_buf[OFF_LOG_SEG_LOBYTE])
670#if defined(FTL_V1) 670#if defined(FTL_V1)
@@ -702,7 +702,7 @@ static void read_random_writes_cache(int bank, int phys_segment)
702 16, spare_buf); 702 16, spare_buf);
703 703
704 log_segment = get_log_segment_id(phys_segment, spare_buf); 704 log_segment = get_log_segment_id(phys_segment, spare_buf);
705 705
706 if (log_segment == -1) 706 if (log_segment == -1)
707 return; 707 return;
708 708
@@ -734,13 +734,13 @@ static void read_random_writes_cache(int bank, int phys_segment)
734 page++) 734 page++)
735 { 735 {
736 unsigned short cached_page; 736 unsigned short cached_page;
737 737
738 nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, page), 738 nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, page),
739 SECTOR_SIZE, /* offset to first sector's spare */ 739 SECTOR_SIZE, /* offset to first sector's spare */
740 16, spare_buf); 740 16, spare_buf);
741 741
742 cached_page = get_cached_page_id(spare_buf); 742 cached_page = get_cached_page_id(spare_buf);
743 743
744 if (cached_page != 0xFFFF) 744 if (cached_page != 0xFFFF)
745 write_caches[cache_no].page_map[cached_page] = page; 745 write_caches[cache_no].page_map[cached_page] = page;
746 } 746 }
@@ -759,10 +759,10 @@ static void read_inplace_writes_cache(int bank, int phys_segment)
759 16, spare_buf); 759 16, spare_buf);
760 760
761 log_segment = get_log_segment_id(phys_segment, spare_buf); 761 log_segment = get_log_segment_id(phys_segment, spare_buf);
762 762
763 if (log_segment == -1) 763 if (log_segment == -1)
764 return; 764 return;
765 765
766 /* Find which cache this is related to */ 766 /* Find which cache this is related to */
767 int cache_no = find_write_cache(log_segment); 767 int cache_no = find_write_cache(log_segment);
768 768
@@ -780,7 +780,7 @@ static void read_inplace_writes_cache(int bank, int phys_segment)
780 } 780 }
781 781
782 write_caches[cache_no].log_segment = log_segment; 782 write_caches[cache_no].log_segment = log_segment;
783 783
784 /* Find how many pages have been written to the new segment */ 784 /* Find how many pages have been written to the new segment */
785 while (log_segment != -1 && 785 while (log_segment != -1 &&
786 page < (nand_data->pages_per_block * nand_data->planes) - 1) 786 page < (nand_data->pages_per_block * nand_data->planes) - 1)
@@ -791,7 +791,7 @@ static void read_inplace_writes_cache(int bank, int phys_segment)
791 791
792 log_segment = get_log_segment_id(phys_segment, spare_buf); 792 log_segment = get_log_segment_id(phys_segment, spare_buf);
793 } 793 }
794 794
795 if (page != 0) 795 if (page != 0)
796 { 796 {
797 write_caches[cache_no].inplace_bank = bank; 797 write_caches[cache_no].inplace_bank = bank;
@@ -801,7 +801,7 @@ static void read_inplace_writes_cache(int bank, int phys_segment)
801} 801}
802 802
803 803
804int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount, 804int nand_read_sectors(IF_MD(int drive,) sector_t start, int incount,
805 void* inbuf) 805 void* inbuf)
806{ 806{
807#ifdef HAVE_MULTIDRIVE 807#ifdef HAVE_MULTIDRIVE
@@ -809,15 +809,15 @@ int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
809#endif 809#endif
810 810
811 int ret = 0; 811 int ret = 0;
812 812
813 mutex_lock(&ata_mtx); 813 mutex_lock(&ata_mtx);
814 814
815 led(true); 815 led(true);
816 816
817 while (incount > 0) 817 while (incount > 0)
818 { 818 {
819 int done = 0; 819 int done = 0;
820 int segment = start / sectors_per_segment; 820 sector_t segment = start / sectors_per_segment;
821 int secmod = start % sectors_per_segment; 821 int secmod = start % sectors_per_segment;
822 822
823 while (incount > 0 && secmod < sectors_per_segment) 823 while (incount > 0 && secmod < sectors_per_segment)
@@ -839,7 +839,7 @@ int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
839 secmod++; 839 secmod++;
840 done++; 840 done++;
841 } 841 }
842 842
843 if (done < 0) 843 if (done < 0)
844 { 844 {
845 ret = -1; 845 ret = -1;
@@ -852,11 +852,11 @@ nand_read_error:
852 852
853 mutex_unlock(&ata_mtx); 853 mutex_unlock(&ata_mtx);
854 led(false); 854 led(false);
855 855
856 return ret; 856 return ret;
857} 857}
858 858
859int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, 859int nand_write_sectors(IF_MD(int drive,) sector_t start, int count,
860 const void* outbuf) 860 const void* outbuf)
861{ 861{
862#ifdef HAVE_MULTIDRIVE 862#ifdef HAVE_MULTIDRIVE
@@ -903,7 +903,7 @@ int nand_init(void)
903 unsigned char spare_buf[16]; 903 unsigned char spare_buf[16];
904 904
905 if (initialized) return 0; 905 if (initialized) return 0;
906 906
907 mutex_init(&ata_mtx); 907 mutex_init(&ata_mtx);
908 908
909 /* Set GPIO direction for chip select & write protect */ 909 /* Set GPIO direction for chip select & write protect */
@@ -924,7 +924,7 @@ int nand_init(void)
924 924
925 memset(lpt_lookup, 0xff, lptbuf_size); 925 memset(lpt_lookup, 0xff, lptbuf_size);
926 memset(write_caches, 0xff, sizeof(write_caches)); 926 memset(write_caches, 0xff, sizeof(write_caches));
927 927
928 write_caches_in_use = 0; 928 write_caches_in_use = 0;
929 929
930 /* Scan banks to build up block translation table */ 930 /* Scan banks to build up block translation table */
@@ -936,7 +936,7 @@ int nand_init(void)
936 nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, 0), 936 nand_read_raw(bank, phys_segment_to_page_addr(phys_segment, 0),
937 SECTOR_SIZE, /* offset */ 937 SECTOR_SIZE, /* offset */
938 16, spare_buf); 938 16, spare_buf);
939 939
940 int type = get_sector_type(spare_buf); 940 int type = get_sector_type(spare_buf);
941 941
942#ifdef FTL_V2 942#ifdef FTL_V2
@@ -948,7 +948,7 @@ int nand_init(void)
948 nand_read_raw(bank, phys_segment_to_page_addr 948 nand_read_raw(bank, phys_segment_to_page_addr
949 (phys_segment, pages_per_segment - 1), 949 (phys_segment, pages_per_segment - 1),
950 SECTOR_SIZE, 16, spare_buf); 950 SECTOR_SIZE, 16, spare_buf);
951 951
952 if (get_sector_type(spare_buf) != 0xff) 952 if (get_sector_type(spare_buf) != 0xff)
953 { 953 {
954 type = SECTYPE_MAIN_DATA; 954 type = SECTYPE_MAIN_DATA;
@@ -982,14 +982,14 @@ int nand_init(void)
982 } 982 }
983 break; 983 break;
984 } 984 }
985 985
986 case SECTYPE_MAIN_RANDOM_CACHE: 986 case SECTYPE_MAIN_RANDOM_CACHE:
987 { 987 {
988 /* Newly-written random page data (Main data area) */ 988 /* Newly-written random page data (Main data area) */
989 read_random_writes_cache(bank, phys_segment); 989 read_random_writes_cache(bank, phys_segment);
990 break; 990 break;
991 } 991 }
992 992
993 case SECTYPE_MAIN_INPLACE_CACHE: 993 case SECTYPE_MAIN_INPLACE_CACHE:
994 { 994 {
995 /* Newly-written sequential page data (Main data area) */ 995 /* Newly-written sequential page data (Main data area) */
@@ -999,7 +999,7 @@ int nand_init(void)
999 } 999 }
1000 } 1000 }
1001 } 1001 }
1002 1002
1003 initialized = true; 1003 initialized = true;
1004 1004
1005 return 0; 1005 return 0;
@@ -1029,7 +1029,7 @@ int nand_num_drives(int first_drive)
1029{ 1029{
1030 /* We don't care which logical drive number we have been assigned */ 1030 /* We don't care which logical drive number we have been assigned */
1031 (void)first_drive; 1031 (void)first_drive;
1032 1032
1033 return 1; 1033 return 1;
1034} 1034}
1035 1035
diff --git a/firmware/target/arm/imx233/clkctrl-imx233.c b/firmware/target/arm/imx233/clkctrl-imx233.c
index 59c23c1a76..1a8f523d5a 100644
--- a/firmware/target/arm/imx233/clkctrl-imx233.c
+++ b/firmware/target/arm/imx233/clkctrl-imx233.c
@@ -87,7 +87,9 @@ void imx233_clkctrl_set_div(enum imx233_clock_t clk, int div)
87 case CLK_EMI: BF_WR(CLKCTRL_EMI, DIV(div)); break; 87 case CLK_EMI: BF_WR(CLKCTRL_EMI, DIV(div)); break;
88#endif 88#endif
89 case CLK_SSP: BF_WR(CLKCTRL_SSP, DIV(div)); break; 89 case CLK_SSP: BF_WR(CLKCTRL_SSP, DIV(div)); break;
90 case CLK_HBUS: BF_WR(CLKCTRL_HBUS, DIV(div)); break; 90 case CLK_HBUS:
91 /* make sure to switch to integer divide mode simulteanously */
92 BF_WR(CLKCTRL_HBUS, DIV_FRAC_EN(0), DIV(div)); break;
91 case CLK_XBUS: BF_WR(CLKCTRL_XBUS, DIV(div)); break; 93 case CLK_XBUS: BF_WR(CLKCTRL_XBUS, DIV(div)); break;
92 default: return; 94 default: return;
93 } 95 }
@@ -107,7 +109,12 @@ int imx233_clkctrl_get_div(enum imx233_clock_t clk)
107 case CLK_EMI: return BF_RD(CLKCTRL_EMI, DIV); 109 case CLK_EMI: return BF_RD(CLKCTRL_EMI, DIV);
108#endif 110#endif
109 case CLK_SSP: return BF_RD(CLKCTRL_SSP, DIV); 111 case CLK_SSP: return BF_RD(CLKCTRL_SSP, DIV);
110 case CLK_HBUS: return BF_RD(CLKCTRL_HBUS, DIV); 112 case CLK_HBUS:
113 /* since fractional and integer divider share the same field, clain it is disabled in frac mode */
114 if(BF_RD(CLKCTRL_HBUS, DIV_FRAC_EN))
115 return 0;
116 else
117 return BF_RD(CLKCTRL_HBUS, DIV);
111 case CLK_XBUS: return BF_RD(CLKCTRL_XBUS, DIV); 118 case CLK_XBUS: return BF_RD(CLKCTRL_XBUS, DIV);
112 default: return 0; 119 default: return 0;
113 } 120 }
@@ -130,6 +137,14 @@ void imx233_clkctrl_set_frac_div(enum imx233_clock_t clk, int fracdiv)
130 handle_frac(IO) 137 handle_frac(IO)
131 handle_frac(CPU) 138 handle_frac(CPU)
132 handle_frac(EMI) 139 handle_frac(EMI)
140 case CLK_HBUS:
141 if(fracdiv == 0)
142 panicf("Don't set hbus fracdiv to 0!");
143 /* value 0 is forbidden because we can't simply disabble the divider, it's always
144 * active but either in integer or fractional mode
145 * make sure we write both the value and frac_en bit at the same time */
146 BF_WR(CLKCTRL_HBUS, DIV_FRAC_EN(1), DIV(fracdiv));
147 break;
133 default: break; 148 default: break;
134 } 149 }
135#undef handle_frac 150#undef handle_frac
@@ -151,6 +166,11 @@ int imx233_clkctrl_get_frac_div(enum imx233_clock_t clk)
151 handle_frac(IO) 166 handle_frac(IO)
152 handle_frac(CPU) 167 handle_frac(CPU)
153 handle_frac(EMI) 168 handle_frac(EMI)
169 case CLK_HBUS:
170 if(BF_RD(CLKCTRL_HBUS, DIV_FRAC_EN))
171 return BF_RD(CLKCTRL_HBUS, DIV);
172 else
173 return 0;
154 default: return 0; 174 default: return 0;
155 } 175 }
156#undef handle_frac 176#undef handle_frac
@@ -303,8 +323,12 @@ unsigned imx233_clkctrl_get_freq(enum imx233_clock_t clk)
303 /* Derived from clk_p via integer/fractional div */ 323 /* Derived from clk_p via integer/fractional div */
304 unsigned ref = imx233_clkctrl_get_freq(CLK_CPU); 324 unsigned ref = imx233_clkctrl_get_freq(CLK_CPU);
305#if IMX233_SUBTARGET >= 3700 325#if IMX233_SUBTARGET >= 3700
326 /* if divider is in fractional mode, integer divider does not take effect (in fact it's
327 * the same divider but in a different mode ). Also the fractiona value is encoded as
328 * a fraction, not a divider */
306 if(imx233_clkctrl_get_frac_div(CLK_HBUS) != 0) 329 if(imx233_clkctrl_get_frac_div(CLK_HBUS) != 0)
307 ref = (ref * imx233_clkctrl_get_frac_div(CLK_HBUS)) / 32; 330 ref = (ref * imx233_clkctrl_get_frac_div(CLK_HBUS)) / 32;
331 else
308#endif 332#endif
309 if(imx233_clkctrl_get_div(CLK_HBUS) != 0) 333 if(imx233_clkctrl_get_div(CLK_HBUS) != 0)
310 ref /= imx233_clkctrl_get_div(CLK_HBUS); 334 ref /= imx233_clkctrl_get_div(CLK_HBUS);
diff --git a/firmware/target/arm/imx233/clkctrl-imx233.h b/firmware/target/arm/imx233/clkctrl-imx233.h
index f12d181c50..d150912cfe 100644
--- a/firmware/target/arm/imx233/clkctrl-imx233.h
+++ b/firmware/target/arm/imx233/clkctrl-imx233.h
@@ -68,7 +68,7 @@ int imx233_clkctrl_get_div(enum imx233_clock_t clk);
68#if IMX233_SUBTARGET >= 3700 68#if IMX233_SUBTARGET >= 3700
69/* call with fracdiv=0 to disable it */ 69/* call with fracdiv=0 to disable it */
70void imx233_clkctrl_set_frac_div(enum imx233_clock_t clk, int fracdiv); 70void imx233_clkctrl_set_frac_div(enum imx233_clock_t clk, int fracdiv);
71/* 0 means fractional dividor disable */ 71/* 0 means fractional dividor disabled */
72int imx233_clkctrl_get_frac_div(enum imx233_clock_t clk); 72int imx233_clkctrl_get_frac_div(enum imx233_clock_t clk);
73void imx233_clkctrl_set_bypass(enum imx233_clock_t clk, bool bypass); 73void imx233_clkctrl_set_bypass(enum imx233_clock_t clk, bool bypass);
74bool imx233_clkctrl_get_bypass(enum imx233_clock_t clk); 74bool imx233_clkctrl_get_bypass(enum imx233_clock_t clk);
diff --git a/firmware/target/arm/imx233/nand-imx233.c b/firmware/target/arm/imx233/nand-imx233.c
index a7afba7d43..22da408e05 100644
--- a/firmware/target/arm/imx233/nand-imx233.c
+++ b/firmware/target/arm/imx233/nand-imx233.c
@@ -36,13 +36,13 @@ int nand_init(void)
36{ 36{
37 return -1; 37 return -1;
38} 38}
39int nand_read_sectors(IF_MD(int drive,) unsigned long start, int count, 39int nand_read_sectors(IF_MD(int drive,) sector_t start, int count,
40 void* buf) 40 void* buf)
41{ 41{
42 return -1; 42 return -1;
43} 43}
44 44
45int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, 45int nand_write_sectors(IF_MD(int drive,) sector_t start, int count,
46 const void* buf) 46 const void* buf)
47{ 47{
48 return -1; 48 return -1;
diff --git a/firmware/target/arm/imx233/partitions-imx233.c b/firmware/target/arm/imx233/partitions-imx233.c
index 83a0bf8b42..69d0ba4199 100644
--- a/firmware/target/arm/imx233/partitions-imx233.c
+++ b/firmware/target/arm/imx233/partitions-imx233.c
@@ -71,7 +71,7 @@ static const char *creative_part_name(enum imx233_part_t part)
71} 71}
72 72
73static int compute_window_creative(intptr_t user, part_read_fn_t read_fn, 73static int compute_window_creative(intptr_t user, part_read_fn_t read_fn,
74 enum imx233_part_t part, unsigned *start, unsigned *end) 74 enum imx233_part_t part, sector_t *start, sector_t *end)
75{ 75{
76 uint8_t mblk[512]; 76 uint8_t mblk[512];
77 int ret = read_fn(user, MBLK_ADDR / 512, 1, mblk); 77 int ret = read_fn(user, MBLK_ADDR / 512, 1, mblk);
@@ -99,7 +99,7 @@ static int compute_window_creative(intptr_t user, part_read_fn_t read_fn,
99 } 99 }
100 else 100 else
101 *end = *start + ent[i].size * hdr->block_size / 512; 101 *end = *start + ent[i].size * hdr->block_size / 512;
102 102
103 return 0; 103 return 0;
104 } 104 }
105 } 105 }
@@ -109,7 +109,7 @@ static int compute_window_creative(intptr_t user, part_read_fn_t read_fn,
109 109
110#if (IMX233_PARTITIONS & IMX233_FREESCALE) 110#if (IMX233_PARTITIONS & IMX233_FREESCALE)
111static int compute_window_freescale(intptr_t user, part_read_fn_t read_fn, 111static int compute_window_freescale(intptr_t user, part_read_fn_t read_fn,
112 enum imx233_part_t part, unsigned *start, unsigned *end) 112 enum imx233_part_t part, sector_t *start, sector_t *end)
113{ 113{
114 uint8_t mbr[512]; 114 uint8_t mbr[512];
115 int ret = read_fn(user, 0, 1, mbr); 115 int ret = read_fn(user, 0, 1, mbr);
@@ -179,7 +179,7 @@ static int compute_window_freescale(intptr_t user, part_read_fn_t read_fn,
179#endif /* (IMX233_PARTITIONS & IMX233_FREESCALE) */ 179#endif /* (IMX233_PARTITIONS & IMX233_FREESCALE) */
180 180
181int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn, 181int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn,
182 enum imx233_part_t part, unsigned *start, unsigned *end) 182 enum imx233_part_t part, sector_t *start, sector_t *end)
183{ 183{
184 int ret = -1; 184 int ret = -1;
185#if (IMX233_PARTITIONS & IMX233_CREATIVE) 185#if (IMX233_PARTITIONS & IMX233_CREATIVE)
diff --git a/firmware/target/arm/imx233/partitions-imx233.h b/firmware/target/arm/imx233/partitions-imx233.h
index e5378dadbb..edc6c1b2f4 100644
--- a/firmware/target/arm/imx233/partitions-imx233.h
+++ b/firmware/target/arm/imx233/partitions-imx233.h
@@ -45,7 +45,7 @@ enum imx233_part_t
45/** The computation function can be called very early in the boot, at which point 45/** The computation function can be called very early in the boot, at which point
46 * usual storage read/write function may not be available. To workaround this 46 * usual storage read/write function may not be available. To workaround this
47 * issue, one must provide a read function. */ 47 * issue, one must provide a read function. */
48typedef int (*part_read_fn_t)(intptr_t user, unsigned long start, int count, void* buf); 48typedef int (*part_read_fn_t)(intptr_t user, sector_t start, int count, void* buf);
49/* Enable/Disable window computations for internal storage following the 49/* Enable/Disable window computations for internal storage following the
50 * Freescale/Creative convention */ 50 * Freescale/Creative convention */
51void imx233_partitions_enable_window(bool enable); 51void imx233_partitions_enable_window(bool enable);
@@ -55,6 +55,6 @@ bool imx233_partitions_is_window_enabled(void);
55 * for a whole disk, *end should be the size of the disk when the function is 55 * for a whole disk, *end should be the size of the disk when the function is
56 * called */ 56 * called */
57int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn, 57int imx233_partitions_compute_window(intptr_t user, part_read_fn_t read_fn,
58 enum imx233_part_t part, unsigned *start, unsigned *end); 58 enum imx233_part_t part, sector_t *start, sector_t *end);
59 59
60#endif /* __PARTITIONS_IMX233__ */ \ No newline at end of file 60#endif /* __PARTITIONS_IMX233__ */
diff --git a/firmware/target/arm/imx233/sdmmc-imx233.c b/firmware/target/arm/imx233/sdmmc-imx233.c
index af090e8a07..02f59a50f4 100644
--- a/firmware/target/arm/imx233/sdmmc-imx233.c
+++ b/firmware/target/arm/imx233/sdmmc-imx233.c
@@ -203,8 +203,8 @@ struct sdmmc_status_t
203 * the RCA is the 16-bit msb. Be careful that this is not the actuall RCA ! */ 203 * the RCA is the 16-bit msb. Be careful that this is not the actuall RCA ! */
204 204
205/* common */ 205/* common */
206static unsigned window_start[SDMMC_NUM_DRIVES]; 206static sector_t window_start[SDMMC_NUM_DRIVES];
207static unsigned window_end[SDMMC_NUM_DRIVES]; 207static sector_t window_end[SDMMC_NUM_DRIVES];
208static uint8_t aligned_buffer[SDMMC_NUM_DRIVES][512] CACHEALIGN_ATTR; 208static uint8_t aligned_buffer[SDMMC_NUM_DRIVES][512] CACHEALIGN_ATTR;
209static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES]; 209static tCardInfo sdmmc_card_info[SDMMC_NUM_DRIVES];
210static struct mutex mutex[SDMMC_NUM_DRIVES]; 210static struct mutex mutex[SDMMC_NUM_DRIVES];
@@ -648,7 +648,7 @@ int mmc_event(long id, intptr_t data)
648#endif /* CONFIG_STORAGE & STORAGE_MMC */ 648#endif /* CONFIG_STORAGE & STORAGE_MMC */
649 649
650/* low-level function, don't call directly! */ 650/* low-level function, don't call directly! */
651static int __xfer_sectors(int drive, unsigned long start, int count, void *buf, bool read) 651static int __xfer_sectors(int drive, sector_t start, int count, void *buf, bool read)
652{ 652{
653 uint32_t resp; 653 uint32_t resp;
654 int ret = 0; 654 int ret = 0;
@@ -660,7 +660,7 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf,
660 need_stop = false; 660 need_stop = false;
661 /* Set bank_start to the correct unit (blocks or bytes). 661 /* Set bank_start to the correct unit (blocks or bytes).
662 * MMC drives use block addressing, SD cards bytes or blocks */ 662 * MMC drives use block addressing, SD cards bytes or blocks */
663 int bank_start = start; 663 sector_t bank_start = start;
664 if(SDMMC_MODE(drive) == SD_MODE && !(SDMMC_INFO(drive).ocr & (1<<30))) /* not SDHC */ 664 if(SDMMC_MODE(drive) == SD_MODE && !(SDMMC_INFO(drive).ocr & (1<<30))) /* not SDHC */
665 bank_start *= SD_BLOCK_SIZE; 665 bank_start *= SD_BLOCK_SIZE;
666 /* issue read/write 666 /* issue read/write
@@ -686,7 +686,7 @@ static int __xfer_sectors(int drive, unsigned long start, int count, void *buf,
686 return ret; 686 return ret;
687} 687}
688 688
689static int transfer_sectors(int drive, unsigned long start, int count, void *buf, bool read) 689static int transfer_sectors(int drive, sector_t start, int count, void *buf, bool read)
690{ 690{
691 int ret = 0; 691 int ret = 0;
692 /* the function doesn't work when count is 0 */ 692 /* the function doesn't work when count is 0 */
@@ -806,7 +806,7 @@ static int transfer_sectors(int drive, unsigned long start, int count, void *buf
806} 806}
807 807
808/* user specifies the sdmmc drive */ 808/* user specifies the sdmmc drive */
809static int part_read_fn(intptr_t user, unsigned long start, int count, void* buf) 809static int part_read_fn(intptr_t user, sector_t start, int count, void* buf)
810{ 810{
811 return transfer_sectors(user, start, count, buf, true); 811 return transfer_sectors(user, start, count, buf, true);
812} 812}
@@ -917,7 +917,7 @@ void sd_enable(bool on)
917 (void) on; 917 (void) on;
918} 918}
919 919
920int sd_read_sectors(IF_MD(int sd_drive,) unsigned long start, int count, void *buf) 920int sd_read_sectors(IF_MD(int sd_drive,) sector_t start, int count, void *buf)
921{ 921{
922#ifndef HAVE_MULTIDRIVE 922#ifndef HAVE_MULTIDRIVE
923 int sd_drive = 0; 923 int sd_drive = 0;
@@ -925,7 +925,7 @@ int sd_read_sectors(IF_MD(int sd_drive,) unsigned long start, int count, void *b
925 return transfer_sectors(sd_map[sd_drive], start, count, buf, true); 925 return transfer_sectors(sd_map[sd_drive], start, count, buf, true);
926} 926}
927 927
928int sd_write_sectors(IF_MD(int sd_drive,) unsigned long start, int count, const void* buf) 928int sd_write_sectors(IF_MD(int sd_drive,) sector_t start, int count, const void* buf)
929{ 929{
930#ifndef HAVE_MULTIDRIVE 930#ifndef HAVE_MULTIDRIVE
931 int sd_drive = 0; 931 int sd_drive = 0;
@@ -1039,7 +1039,7 @@ int mmc_spinup_time(void)
1039 return 0; 1039 return 0;
1040} 1040}
1041 1041
1042int mmc_read_sectors(IF_MD(int mmc_drive,) unsigned long start, int count, void *buf) 1042int mmc_read_sectors(IF_MD(int mmc_drive,) sector_t start, int count, void *buf)
1043{ 1043{
1044#ifndef HAVE_MULTIDRIVE 1044#ifndef HAVE_MULTIDRIVE
1045 int mmc_drive = 0; 1045 int mmc_drive = 0;
@@ -1047,7 +1047,7 @@ int mmc_read_sectors(IF_MD(int mmc_drive,) unsigned long start, int count, void
1047 return transfer_sectors(mmc_map[mmc_drive], start, count, buf, true); 1047 return transfer_sectors(mmc_map[mmc_drive], start, count, buf, true);
1048} 1048}
1049 1049
1050int mmc_write_sectors(IF_MD(int mmc_drive,) unsigned long start, int count, const void* buf) 1050int mmc_write_sectors(IF_MD(int mmc_drive,) sector_t start, int count, const void* buf)
1051{ 1051{
1052#ifndef HAVE_MULTIDRIVE 1052#ifndef HAVE_MULTIDRIVE
1053 int mmc_drive = 0; 1053 int mmc_drive = 0;
diff --git a/firmware/target/arm/ipod/button-clickwheel.c b/firmware/target/arm/ipod/button-clickwheel.c
index 8f238936e7..9308b7664e 100644
--- a/firmware/target/arm/ipod/button-clickwheel.c
+++ b/firmware/target/arm/ipod/button-clickwheel.c
@@ -327,7 +327,13 @@ void ipod_4g_button_int(void)
327void button_init_device(void) 327void button_init_device(void)
328{ 328{
329 opto_i2c_init(); 329 opto_i2c_init();
330 330
331 /* fixes first button press being ignored */
332#if defined(IPOD_4G) || defined(IPOD_COLOR)
333 outl(inl(0x7000c100) & ~0x60000000, 0x7000c100);
334 outl(inl(0x7000c104) | 0x04000000, 0x7000c104);
335 outl(inl(0x7000c100) | 0x60000000, 0x7000c100);
336#endif
331 /* hold button - enable as input */ 337 /* hold button - enable as input */
332 GPIOA_ENABLE |= 0x20; 338 GPIOA_ENABLE |= 0x20;
333 GPIOA_OUTPUT_EN &= ~0x20; 339 GPIOA_OUTPUT_EN &= ~0x20;
diff --git a/firmware/target/arm/pp/ata-pp5020.c b/firmware/target/arm/pp/ata-pp5020.c
index 176e74993c..7351215693 100644
--- a/firmware/target/arm/pp/ata-pp5020.c
+++ b/firmware/target/arm/pp/ata-pp5020.c
@@ -48,8 +48,8 @@ bool ata_is_coldstart()
48 rest are the same. They go in IDE0_PRI_TIMING0. 48 rest are the same. They go in IDE0_PRI_TIMING0.
49 49
50 Rockbox used to use 0x10, and test_disk shows that leads to faster PIO. 50 Rockbox used to use 0x10, and test_disk shows that leads to faster PIO.
51 However on some disks connected with mSATA adapters this causes corrupt data 51 However when used with mSATA and some SD adapters this causes corrupt data
52 so we now just use these timings from the OF. 52 so we now unconditionally use these timings from the OF.
53*/ 53*/
54static const unsigned long pio80mhz[] = { 54static const unsigned long pio80mhz[] = {
55 0xC293, 0x43A2, 0x11A1, 0x7232, 0x3131 55 0xC293, 0x43A2, 0x11A1, 0x7232, 0x3131
@@ -83,10 +83,7 @@ void ata_device_init()
83/* Setup the timing for PIO mode */ 83/* Setup the timing for PIO mode */
84void ata_set_pio_timings(int mode) 84void ata_set_pio_timings(int mode)
85{ 85{
86 if (ata_disk_isssd()) 86 IDE0_PRI_TIMING0 = pio80mhz[mode];
87 IDE0_PRI_TIMING0 = pio80mhz[mode];
88 else
89 IDE0_PRI_TIMING0 = 0x10;
90} 87}
91 88
92#ifdef HAVE_ATA_DMA 89#ifdef HAVE_ATA_DMA
@@ -109,6 +106,8 @@ static bool dma_boosted = false;
109static bool dma_needs_boost; 106static bool dma_needs_boost;
110#endif 107#endif
111 108
109static int ata_is_ssd = 0;
110
112/* This function sets up registers for 80 Mhz. 111/* This function sets up registers for 80 Mhz.
113 Ultra DMA mode 2 works at 30 Mhz. 112 Ultra DMA mode 2 works at 30 Mhz.
114 */ 113 */
@@ -136,6 +135,8 @@ void ata_dma_set_mode(unsigned char mode) {
136#if !defined(IPOD_NANO) 135#if !defined(IPOD_NANO)
137 IDE0_CFG |= 0x20000000; /* >= 50 Mhz */ 136 IDE0_CFG |= 0x20000000; /* >= 50 Mhz */
138#endif 137#endif
138
139 ata_is_ssd = ata_disk_isssd();
139} 140}
140 141
141#define IDE_CFG_INTRQ 8 142#define IDE_CFG_INTRQ 8
@@ -175,11 +176,12 @@ bool ata_dma_setup(void *addr, unsigned long bytes, bool write) {
175 /* Writes only need to be word-aligned, but by default DMA 176 /* Writes only need to be word-aligned, but by default DMA
176 * is not used for writing on non-SSDs as it appears to be slower. 177 * is not used for writing on non-SSDs as it appears to be slower.
177 */ 178 */
178 if (!ata_disk_isssd()) 179 if (write) {
179 return false; 180 if ((unsigned long)addr & 3)
180 181 return false;
181 if (write && ((unsigned long)addr & 3)) 182 if (!ata_is_ssd)
182 return false; 183 return false;
184 }
183 185
184#if ATA_MAX_UDMA > 2 186#if ATA_MAX_UDMA > 2
185 if (dma_needs_boost && !dma_boosted) { 187 if (dma_needs_boost && !dma_boosted) {
diff --git a/firmware/target/arm/pp/ata-sd-pp.c b/firmware/target/arm/pp/ata-sd-pp.c
index fb0a9e150e..b998afd21e 100644
--- a/firmware/target/arm/pp/ata-sd-pp.c
+++ b/firmware/target/arm/pp/ata-sd-pp.c
@@ -82,7 +82,7 @@
82#define STAT_TIME_OUT_RES (1 << 1) 82#define STAT_TIME_OUT_RES (1 << 1)
83#define STAT_TIME_OUT_READ (1) 83#define STAT_TIME_OUT_READ (1)
84#define STAT_ERROR_BITS (0x3f) 84#define STAT_ERROR_BITS (0x3f)
85 85
86/* MMC_CMDAT bits */ 86/* MMC_CMDAT bits */
87/* Some of the bits used by the OF don't make much sense with these */ 87/* Some of the bits used by the OF don't make much sense with these */
88/* definitions. So they're probably different between PXA and PP502x */ 88/* definitions. So they're probably different between PXA and PP502x */
@@ -101,7 +101,7 @@
101#define CMDAT_RES_TYPE3 (3) 101#define CMDAT_RES_TYPE3 (3)
102#define CMDAT_RES_TYPE2 (2) 102#define CMDAT_RES_TYPE2 (2)
103#define CMDAT_RES_TYPE1 (1) 103#define CMDAT_RES_TYPE1 (1)
104 104
105/* MMC_I_MASK bits */ 105/* MMC_I_MASK bits */
106/* PP502x apparently only has bits 0-3 */ 106/* PP502x apparently only has bits 0-3 */
107#define I_MASK_SDIO_SUSPEND_ACK (1 << 12) 107#define I_MASK_SDIO_SUSPEND_ACK (1 << 12)
@@ -499,18 +499,18 @@ static inline void copy_write_sectors(const unsigned char** buf)
499 { 499 {
500 asm volatile ( 500 asm volatile (
501 "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n" 501 "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n"
502 "mov r4, r3, lsr #16 \r\n" 502 "mov r4, r3, lsr #16 \r\n"
503 "mov r6, r5, lsr #16 \r\n" 503 "mov r6, r5, lsr #16 \r\n"
504 "mov r8, r7, lsr #16 \r\n" 504 "mov r8, r7, lsr #16 \r\n"
505 "mov r10, r9, lsr #16 \r\n" 505 "mov r10, r9, lsr #16 \r\n"
506 "stmia %[data], { r3-r10 } \r\n" 506 "stmia %[data], { r3-r10 } \r\n"
507 "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n" 507 "ldmia %[buf]!, { r3, r5, r7, r9 } \r\n"
508 "mov r4, r3, lsr #16 \r\n" 508 "mov r4, r3, lsr #16 \r\n"
509 "mov r6, r5, lsr #16 \r\n" 509 "mov r6, r5, lsr #16 \r\n"
510 "mov r8, r7, lsr #16 \r\n" 510 "mov r8, r7, lsr #16 \r\n"
511 "mov %[t], r9, lsr #16 \r\n" 511 "mov %[t], r9, lsr #16 \r\n"
512 "stmia %[data], { r3-r9 } \r\n" 512 "stmia %[data], { r3-r9 } \r\n"
513 : [buf]"+&r"(*buf), [t]"=&r"(t) 513 : [buf]"+&r"(*buf), [t]"=&r"(t)
514 : [data]"r"(&MMC_DATA_FIFO) 514 : [data]"r"(&MMC_DATA_FIFO)
515 : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" 515 : "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10"
516 ); 516 );
@@ -760,7 +760,7 @@ static void sd_init_device(int card_no)
760 currcard->csd[i] = temp_reg[3-i]; 760 currcard->csd[i] = temp_reg[3-i];
761 761
762 sd_parse_csd(currcard); 762 sd_parse_csd(currcard);
763 763
764 MMC_CLKRT = 0; /* switch to highest clock rate */ 764 MMC_CLKRT = 0; /* switch to highest clock rate */
765 765
766 ret = sd_command(SD_SELECT_CARD, currcard->rca, NULL, 766 ret = sd_command(SD_SELECT_CARD, currcard->rca, NULL,
@@ -849,7 +849,7 @@ static void sd_select_device(int card_no)
849 849
850/* API Functions */ 850/* API Functions */
851 851
852int sd_read_sectors(IF_MD(int drive,) unsigned long start, int incount, 852int sd_read_sectors(IF_MD(int drive,) sector_t start, int incount,
853 void* inbuf) 853 void* inbuf)
854{ 854{
855#ifndef HAVE_MULTIDRIVE 855#ifndef HAVE_MULTIDRIVE
@@ -857,8 +857,8 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int incount,
857#endif 857#endif
858 int ret; 858 int ret;
859 unsigned char *buf, *buf_end; 859 unsigned char *buf, *buf_end;
860 unsigned int bank; 860 sector_t bank;
861 861
862 /* TODO: Add DMA support. */ 862 /* TODO: Add DMA support. */
863 863
864 mutex_lock(&sd_mtx); 864 mutex_lock(&sd_mtx);
@@ -894,7 +894,7 @@ sd_read_retry:
894 if (ret < 0) 894 if (ret < 0)
895 goto sd_read_error; 895 goto sd_read_error;
896 } 896 }
897 897
898 start -= bank * BLOCKS_PER_BANK; 898 start -= bank * BLOCKS_PER_BANK;
899 } 899 }
900 900
@@ -904,6 +904,8 @@ sd_read_retry:
904 904
905 MMC_NUMBLK = incount; 905 MMC_NUMBLK = incount;
906 906
907 // XXX 64-bit addresses..
908
907#ifdef HAVE_HOTSWAP 909#ifdef HAVE_HOTSWAP
908 if(currcard->ocr & (1<<30) ) 910 if(currcard->ocr & (1<<30) )
909 { 911 {
@@ -966,7 +968,7 @@ sd_read_error:
966 } 968 }
967} 969}
968 970
969int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, 971int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
970 const void* outbuf) 972 const void* outbuf)
971{ 973{
972/* Write support is not finished yet */ 974/* Write support is not finished yet */
@@ -1010,7 +1012,7 @@ sd_write_retry:
1010 if (ret < 0) 1012 if (ret < 0)
1011 goto sd_write_error; 1013 goto sd_write_error;
1012 } 1014 }
1013 1015
1014 start -= bank * BLOCKS_PER_BANK; 1016 start -= bank * BLOCKS_PER_BANK;
1015 } 1017 }
1016 1018
@@ -1250,7 +1252,7 @@ int sd_num_drives(int first_drive)
1250#else 1252#else
1251 (void)first_drive; 1253 (void)first_drive;
1252#endif 1254#endif
1253 1255
1254#ifdef HAVE_MULTIDRIVE 1256#ifdef HAVE_MULTIDRIVE
1255 return 2; 1257 return 2;
1256#else 1258#else
diff --git a/firmware/target/arm/rk27xx/ata-nand-rk27xx.c b/firmware/target/arm/rk27xx/ata-nand-rk27xx.c
index e257416cd0..54a1223cfc 100644
--- a/firmware/target/arm/rk27xx/ata-nand-rk27xx.c
+++ b/firmware/target/arm/rk27xx/ata-nand-rk27xx.c
@@ -31,18 +31,18 @@
31 31
32/* This file provides only STUBS for now */ 32/* This file provides only STUBS for now */
33 33
34/** static, private data **/ 34/** static, private data **/
35static bool initialized = false; 35static bool initialized = false;
36 36
37/* API Functions */ 37/* API Functions */
38int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount, 38int nand_read_sectors(IF_MD(int drive,) sector_t start, int incount,
39 void* inbuf) 39 void* inbuf)
40{ 40{
41 (void)drive; 41 (void)drive;
42 return ftl_read(start, incount, inbuf); 42 return ftl_read(start, incount, inbuf);
43} 43}
44 44
45int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, 45int nand_write_sectors(IF_MD(int drive,) sector_t start, int count,
46 const void* outbuf) 46 const void* outbuf)
47{ 47{
48 (void)drive; 48 (void)drive;
@@ -112,7 +112,7 @@ int nand_num_drives(int first_drive)
112{ 112{
113 /* We don't care which logical drive number(s) we have been assigned */ 113 /* We don't care which logical drive number(s) we have been assigned */
114 (void)first_drive; 114 (void)first_drive;
115 115
116 return 1; 116 return 1;
117} 117}
118#endif 118#endif
diff --git a/firmware/target/arm/rk27xx/sd-rk27xx.c b/firmware/target/arm/rk27xx/sd-rk27xx.c
index 2ddf91a67e..e082a8bf2e 100644
--- a/firmware/target/arm/rk27xx/sd-rk27xx.c
+++ b/firmware/target/arm/rk27xx/sd-rk27xx.c
@@ -35,7 +35,7 @@
35#include "panic.h" 35#include "panic.h"
36#include "stdbool.h" 36#include "stdbool.h"
37#include "storage.h" 37#include "storage.h"
38 38#include "timeout.h"
39#include "lcd.h" 39#include "lcd.h"
40#include <stdarg.h> 40#include <stdarg.h>
41#include "sysfont.h" 41#include "sysfont.h"
@@ -453,7 +453,7 @@ static inline void write_sd_data(unsigned char **src)
453 *src += 512; 453 *src += 512;
454} 454}
455 455
456int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, 456int sd_read_sectors(IF_MD(int drive,) sector_t start, int count,
457 void* buf) 457 void* buf)
458{ 458{
459#ifdef HAVE_MULTIDRIVE 459#ifdef HAVE_MULTIDRIVE
@@ -498,6 +498,8 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
498 DATA_XFER_MULTI; 498 DATA_XFER_MULTI;
499 } 499 }
500 500
501 // XXX 64-bit
502
501 /* issue read command to the card */ 503 /* issue read command to the card */
502 if (!send_cmd(SD_READ_MULTIPLE_BLOCK, start, RES_R1, &response)) 504 if (!send_cmd(SD_READ_MULTIPLE_BLOCK, start, RES_R1, &response))
503 { 505 {
@@ -576,7 +578,7 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count,
576} 578}
577 579
578/* Not tested */ 580/* Not tested */
579int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, 581int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
580 const void* buf) 582 const void* buf)
581{ 583{
582#ifdef HAVE_MULTIDRIVE 584#ifdef HAVE_MULTIDRIVE
@@ -620,6 +622,7 @@ int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count,
620 622
621 write_sd_data(&src); /* put data into transfer buffer */ 623 write_sd_data(&src); /* put data into transfer buffer */
622 624
625 // XXX 64-bit
623 if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response)) 626 if (!send_cmd(SD_WRITE_MULTIPLE_BLOCK, start, RES_R1, &response))
624 { 627 {
625 ret = -3; 628 ret = -3;
diff --git a/firmware/target/arm/s3c2440/sd-s3c2440.c b/firmware/target/arm/s3c2440/sd-s3c2440.c
index 2ff68aa4ee..82fd60c711 100644
--- a/firmware/target/arm/s3c2440/sd-s3c2440.c
+++ b/firmware/target/arm/s3c2440/sd-s3c2440.c
@@ -18,7 +18,7 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22//#define SD_DEBUG 22//#define SD_DEBUG
23 23
24#include "system.h" 24#include "system.h"
@@ -33,7 +33,7 @@
33#include "sdmmc.h" 33#include "sdmmc.h"
34#endif 34#endif
35#include "storage.h" 35#include "storage.h"
36#include "dma-target.h" 36#include "dma-target.h"
37#include "system-target.h" 37#include "system-target.h"
38#include "led-mini2440.h" 38#include "led-mini2440.h"
39 39
@@ -83,7 +83,7 @@ struct sd_card_status
83 int retry_max; 83 int retry_max;
84}; 84};
85 85
86/** static, private data **/ 86/** static, private data **/
87 87
88/* for compatibility */ 88/* for compatibility */
89static long last_disk_activity = -1; 89static long last_disk_activity = -1;
@@ -117,13 +117,13 @@ static struct mutex sd_mtx SHAREDBSS_ATTR;
117static struct semaphore transfer_completion_signal; 117static struct semaphore transfer_completion_signal;
118static volatile unsigned int transfer_error[NUM_DRIVES]; 118static volatile unsigned int transfer_error[NUM_DRIVES];
119/* align on cache line size */ 119/* align on cache line size */
120static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] 120static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE]
121 __attribute__((aligned(32))); 121 __attribute__((aligned(32)));
122static unsigned char * uncached_buffer; 122static unsigned char * uncached_buffer;
123 123
124static inline void mci_delay(void) 124static inline void mci_delay(void)
125{ 125{
126 int i = 0xffff; 126 int i = 0xffff;
127 while (i--) 127 while (i--)
128 asm volatile ("nop\n"); 128 asm volatile ("nop\n");
129} 129}
@@ -146,7 +146,7 @@ static void get_regs (unsigned *regs)
146{ 146{
147 unsigned j; 147 unsigned j;
148 volatile unsigned long *sdi_reg = &SDICON; 148 volatile unsigned long *sdi_reg = &SDICON;
149 149
150 for (j=0; j < 16;j++) 150 for (j=0; j < 16;j++)
151 { 151 {
152 *regs++ = *sdi_reg++; 152 *regs++ = *sdi_reg++;
@@ -158,7 +158,7 @@ static void dump_regs (unsigned *regs1, unsigned *regs2)
158 unsigned j; 158 unsigned j;
159 volatile unsigned long*sdi_reg = &SDICON; 159 volatile unsigned long*sdi_reg = &SDICON;
160 unsigned long diff; 160 unsigned long diff;
161 161
162 for (j=0; j < 16;j++) 162 for (j=0; j < 16;j++)
163 { 163 {
164 diff = *regs1 ^ *regs2; 164 diff = *regs1 ^ *regs2;
@@ -174,23 +174,23 @@ static void dump_regs (unsigned *regs1, unsigned *regs2)
174static void debug_r1(int cmd) 174static void debug_r1(int cmd)
175{ 175{
176#if defined(SD_DEBUG) 176#if defined(SD_DEBUG)
177 dbgprintf("CMD%2.2d:SDICSTA=%04x [%c%c%c%c%c-%c%c%c%c%c%c%c] SDIRSP0=%08x [%d %s] \n", 177 dbgprintf("CMD%2.2d:SDICSTA=%04x [%c%c%c%c%c-%c%c%c%c%c%c%c] SDIRSP0=%08x [%d %s] \n",
178 cmd, 178 cmd,
179 SDICSTA, 179 SDICSTA,
180 (SDICSTA & S3C2410_SDICMDSTAT_CRCFAIL) ? 'C' : ' ', 180 (SDICSTA & S3C2410_SDICMDSTAT_CRCFAIL) ? 'C' : ' ',
181 (SDICSTA & S3C2410_SDICMDSTAT_CMDSENT) ? 'S' : ' ', 181 (SDICSTA & S3C2410_SDICMDSTAT_CMDSENT) ? 'S' : ' ',
182 (SDICSTA & S3C2410_SDICMDSTAT_CMDTIMEOUT) ? 'T' : ' ', 182 (SDICSTA & S3C2410_SDICMDSTAT_CMDTIMEOUT) ? 'T' : ' ',
183 (SDICSTA & S3C2410_SDICMDSTAT_RSPFIN) ? 'R' : ' ', 183 (SDICSTA & S3C2410_SDICMDSTAT_RSPFIN) ? 'R' : ' ',
184 (SDICSTA & S3C2410_SDICMDSTAT_XFERING) ? 'X' : ' ', 184 (SDICSTA & S3C2410_SDICMDSTAT_XFERING) ? 'X' : ' ',
185 185
186 (SDICSTA & 0x40) ? 'P' : ' ', 186 (SDICSTA & 0x40) ? 'P' : ' ',
187 (SDICSTA & 0x20) ? 'A' : ' ', 187 (SDICSTA & 0x20) ? 'A' : ' ',
188 (SDICSTA & 0x10) ? 'E' : ' ', 188 (SDICSTA & 0x10) ? 'E' : ' ',
189 (SDICSTA & 0x08) ? 'C' : ' ', 189 (SDICSTA & 0x08) ? 'C' : ' ',
190 (SDICSTA & 0x04) ? 'I' : ' ', 190 (SDICSTA & 0x04) ? 'I' : ' ',
191 (SDICSTA & 0x02) ? 'R' : ' ', 191 (SDICSTA & 0x02) ? 'R' : ' ',
192 (SDICSTA & 0x01) ? 'Z' : ' ', 192 (SDICSTA & 0x01) ? 'Z' : ' ',
193 193
194 SDIRSP0, 194 SDIRSP0,
195 SD_R1_CURRENT_STATE(SDIRSP0), 195 SD_R1_CURRENT_STATE(SDIRSP0),
196 (SDIRSP0 & SD_R1_READY_FOR_DATA) ? "RDY " : " " 196 (SDIRSP0 & SD_R1_READY_FOR_DATA) ? "RDY " : " "
@@ -205,8 +205,8 @@ void SDI (void)
205 int status = SDIDSTA; 205 int status = SDIDSTA;
206#ifndef HAVE_MULTIDRIVE 206#ifndef HAVE_MULTIDRIVE
207 const int curr_card = 0; 207 const int curr_card = 0;
208#endif 208#endif
209 209
210 transfer_error[curr_card] = status 210 transfer_error[curr_card] = status
211#if 0 211#if 0
212 & ( S3C2410_SDIDSTA_CRCFAIL | S3C2410_SDIDSTA_RXCRCFAIL | 212 & ( S3C2410_SDIDSTA_CRCFAIL | S3C2410_SDIDSTA_RXCRCFAIL |
@@ -217,7 +217,7 @@ void SDI (void)
217 SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */ 217 SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */
218 218
219 dbgprintf ("SDI %x\n", transfer_error[curr_card]); 219 dbgprintf ("SDI %x\n", transfer_error[curr_card]);
220 220
221 semaphore_release(&transfer_completion_signal); 221 semaphore_release(&transfer_completion_signal);
222 222
223 /* Ack the interrupt */ 223 /* Ack the interrupt */
@@ -229,13 +229,13 @@ void SDI (void)
229void dma_callback (void) 229void dma_callback (void)
230{ 230{
231 const int status = SDIDSTA; 231 const int status = SDIDSTA;
232 232
233 transfer_error[0] = status & (S3C2410_SDIDSTA_CRCFAIL | 233 transfer_error[0] = status & (S3C2410_SDIDSTA_CRCFAIL |
234 S3C2410_SDIDSTA_RXCRCFAIL | 234 S3C2410_SDIDSTA_RXCRCFAIL |
235 S3C2410_SDIDSTA_DATATIMEOUT ); 235 S3C2410_SDIDSTA_DATATIMEOUT );
236 236
237 SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */ 237 SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; /* needed to clear int */
238 238
239 dbgprintf ("dma_cb\n"); 239 dbgprintf ("dma_cb\n");
240 semaphore_release(&transfer_completion_signal); 240 semaphore_release(&transfer_completion_signal);
241} 241}
@@ -248,14 +248,14 @@ static void init_sdi_controller(const int card_no)
248/*****************************************************************************/ 248/*****************************************************************************/
249#ifdef MINI2440 249#ifdef MINI2440
250 /* Specific to Mini2440 */ 250 /* Specific to Mini2440 */
251 251
252 /* Enable pullups on SDCMD and SDDAT pins */ 252 /* Enable pullups on SDCMD and SDDAT pins */
253 S3C2440_GPIO_PULLUP (GPEUP, 6, GPIO_PULLUP_ENABLE); 253 S3C2440_GPIO_PULLUP (GPEUP, 6, GPIO_PULLUP_ENABLE);
254 S3C2440_GPIO_PULLUP (GPEUP, 7, GPIO_PULLUP_ENABLE); 254 S3C2440_GPIO_PULLUP (GPEUP, 7, GPIO_PULLUP_ENABLE);
255 S3C2440_GPIO_PULLUP (GPEUP, 8, GPIO_PULLUP_ENABLE); 255 S3C2440_GPIO_PULLUP (GPEUP, 8, GPIO_PULLUP_ENABLE);
256 S3C2440_GPIO_PULLUP (GPEUP, 9, GPIO_PULLUP_ENABLE); 256 S3C2440_GPIO_PULLUP (GPEUP, 9, GPIO_PULLUP_ENABLE);
257 S3C2440_GPIO_PULLUP (GPEUP, 10, GPIO_PULLUP_ENABLE); 257 S3C2440_GPIO_PULLUP (GPEUP, 10, GPIO_PULLUP_ENABLE);
258 258
259 /* Enable special function for SDCMD, SDCLK and SDDAT pins */ 259 /* Enable special function for SDCMD, SDCLK and SDDAT pins */
260 S3C2440_GPIO_CONFIG (GPECON, 5, GPIO_FUNCTION); 260 S3C2440_GPIO_CONFIG (GPECON, 5, GPIO_FUNCTION);
261 S3C2440_GPIO_CONFIG (GPECON, 6, GPIO_FUNCTION); 261 S3C2440_GPIO_CONFIG (GPECON, 6, GPIO_FUNCTION);
@@ -263,15 +263,15 @@ static void init_sdi_controller(const int card_no)
263 S3C2440_GPIO_CONFIG (GPECON, 8, GPIO_FUNCTION); 263 S3C2440_GPIO_CONFIG (GPECON, 8, GPIO_FUNCTION);
264 S3C2440_GPIO_CONFIG (GPECON, 9, GPIO_FUNCTION); 264 S3C2440_GPIO_CONFIG (GPECON, 9, GPIO_FUNCTION);
265 S3C2440_GPIO_CONFIG (GPECON, 10, GPIO_FUNCTION); 265 S3C2440_GPIO_CONFIG (GPECON, 10, GPIO_FUNCTION);
266 266
267 /* Card Detect input */ 267 /* Card Detect input */
268 S3C2440_GPIO_CONFIG (GPGCON, 8, GPIO_INPUT); 268 S3C2440_GPIO_CONFIG (GPGCON, 8, GPIO_INPUT);
269 /* enable external irq 8-23 on the internal interrupt controller */ 269 /* enable external irq 8-23 on the internal interrupt controller */
270 INTMSK &= ~1<<5; 270 INTMSK &= ~1<<5;
271 /* enable GPG8 IRQ on the external interrupt controller */ 271 /* enable GPG8 IRQ on the external interrupt controller */
272 EINTMASK &= ~(1<<16); 272 EINTMASK &= ~(1<<16);
273 273
274 274
275 /* Write Protect input */ 275 /* Write Protect input */
276 S3C2440_GPIO_CONFIG (GPHCON, 8, GPIO_INPUT); 276 S3C2440_GPIO_CONFIG (GPHCON, 8, GPIO_INPUT);
277/*****************************************************************************/ 277/*****************************************************************************/
@@ -279,11 +279,11 @@ static void init_sdi_controller(const int card_no)
279#error Unsupported target 279#error Unsupported target
280#endif 280#endif
281/*****************************************************************************/ 281/*****************************************************************************/
282 282
283 /* About 400KHz for initial comms with card */ 283 /* About 400KHz for initial comms with card */
284 SDIPRE = PCLK / INITIAL_CLK - 1; 284 SDIPRE = PCLK / INITIAL_CLK - 1;
285 /* Byte order=Type A (Little Endian), clock enable */ 285 /* Byte order=Type A (Little Endian), clock enable */
286 SDICON = S3C2410_SDICON_CLOCKTYPE; 286 SDICON = S3C2410_SDICON_CLOCKTYPE;
287 SDIFSTA |= S3C2440_SDIFSTA_FIFORESET; 287 SDIFSTA |= S3C2440_SDIFSTA_FIFORESET;
288 SDIBSIZE = SD_BLOCK_SIZE; 288 SDIBSIZE = SD_BLOCK_SIZE;
289 SDIDTIMER= 0x7fffff; /* Set timeout count - max value */ 289 SDIDTIMER= 0x7fffff; /* Set timeout count - max value */
@@ -297,11 +297,11 @@ static void init_sdi_controller(const int card_no)
297 /* Enable interrupt in controller */ 297 /* Enable interrupt in controller */
298 bitclr32(&INTMOD, SDI_MASK); 298 bitclr32(&INTMOD, SDI_MASK);
299 bitclr32(&INTMSK, SDI_MASK); 299 bitclr32(&INTMSK, SDI_MASK);
300 300
301 SDIIMSK |= S3C2410_SDIIMSK_DATAFINISH 301 SDIIMSK |= S3C2410_SDIIMSK_DATAFINISH
302 | S3C2410_SDIIMSK_DATATIMEOUT 302 | S3C2410_SDIIMSK_DATATIMEOUT
303 | S3C2410_SDIIMSK_DATACRC 303 | S3C2410_SDIIMSK_DATACRC
304 | S3C2410_SDIIMSK_CRCSTATUS 304 | S3C2410_SDIIMSK_CRCSTATUS
305 | S3C2410_SDIIMSK_FIFOFAIL 305 | S3C2410_SDIIMSK_FIFOFAIL
306 ; 306 ;
307#endif 307#endif
@@ -325,18 +325,18 @@ static bool send_cmd(const int card_no, const int cmd, const int arg,
325 get_regs (reg_copy2); 325 get_regs (reg_copy2);
326 dump_regs (reg_copy, reg_copy2); 326 dump_regs (reg_copy, reg_copy2);
327#endif 327#endif
328 328
329#if 0 329#if 0
330 while (SDICSTA & S3C2410_SDICMDSTAT_XFERING) 330 while (SDICSTA & S3C2410_SDICMDSTAT_XFERING)
331 ; /* wait ?? */ 331 ; /* wait ?? */
332#endif 332#endif
333 /* set up new command */ 333 /* set up new command */
334 334
335 if (flags & MCI_ARG) 335 if (flags & MCI_ARG)
336 SDICARG = arg; 336 SDICARG = arg;
337 else 337 else
338 SDICARG = 0; 338 SDICARG = 0;
339 339
340 val = cmd | S3C2410_SDICMDCON_CMDSTART | S3C2410_SDICMDCON_SENDERHOST; 340 val = cmd | S3C2410_SDICMDCON_CMDSTART | S3C2410_SDICMDCON_SENDERHOST;
341 if(flags & MCI_RESP) 341 if(flags & MCI_RESP)
342 { 342 {
@@ -344,27 +344,27 @@ static bool send_cmd(const int card_no, const int cmd, const int arg,
344 if(flags & MCI_LONG_RESP) 344 if(flags & MCI_LONG_RESP)
345 val |= S3C2410_SDICMDCON_LONGRSP; 345 val |= S3C2410_SDICMDCON_LONGRSP;
346 } 346 }
347 347
348 /* Clear command/data status flags */ 348 /* Clear command/data status flags */
349 SDICSTA |= 0x0f << 9; 349 SDICSTA |= 0x0f << 9;
350 SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS; 350 SDIDSTA |= S3C2410_SDIDSTA_CLEAR_BITS;
351 351
352 /* Initiate the command */ 352 /* Initiate the command */
353 SDICCON = val; 353 SDICCON = val;
354 354
355 if (flags & MCI_RESP) 355 if (flags & MCI_RESP)
356 { 356 {
357 /* wait for response or timeout */ 357 /* wait for response or timeout */
358 do 358 do
359 { 359 {
360 status = SDICSTA; 360 status = SDICSTA;
361 } while ( (status & (S3C2410_SDICMDSTAT_RSPFIN | 361 } while ( (status & (S3C2410_SDICMDSTAT_RSPFIN |
362 S3C2410_SDICMDSTAT_CMDTIMEOUT) ) == 0); 362 S3C2410_SDICMDSTAT_CMDTIMEOUT) ) == 0);
363 debug_r1(cmd); 363 debug_r1(cmd);
364 if (status & S3C2410_SDICMDSTAT_CMDTIMEOUT) 364 if (status & S3C2410_SDICMDSTAT_CMDTIMEOUT)
365 ret = false; 365 ret = false;
366 else if (status & (S3C2410_SDICMDSTAT_RSPFIN)) 366 else if (status & (S3C2410_SDICMDSTAT_RSPFIN))
367 { 367 {
368 /* resp received */ 368 /* resp received */
369 if(flags & MCI_LONG_RESP) 369 if(flags & MCI_LONG_RESP)
370 { 370 {
@@ -381,10 +381,10 @@ static bool send_cmd(const int card_no, const int cmd, const int arg,
381 else 381 else
382 ret = true; 382 ret = true;
383 } 383 }
384 else 384 else
385 { 385 {
386 /* wait for command completion or timeout */ 386 /* wait for command completion or timeout */
387 do 387 do
388 { 388 {
389 status = SDICSTA; 389 status = SDICSTA;
390 } while ( (status & (S3C2410_SDICMDSTAT_CMDSENT | 390 } while ( (status & (S3C2410_SDICMDSTAT_CMDSENT |
@@ -395,12 +395,12 @@ static bool send_cmd(const int card_no, const int cmd, const int arg,
395 else 395 else
396 ret = true; 396 ret = true;
397 } 397 }
398 398
399 /* Clear Command status flags */ 399 /* Clear Command status flags */
400 SDICSTA |= 0x0f << 9; 400 SDICSTA |= 0x0f << 9;
401 401
402 mci_delay(); 402 mci_delay();
403 403
404 return ret; 404 return ret;
405} 405}
406 406
@@ -558,7 +558,7 @@ bool sd_removable(IF_MD_NONVOID(int card_no))
558 const int card_no = 0; 558 const int card_no = 0;
559#endif 559#endif
560 (void)card_no; 560 (void)card_no;
561 561
562 /* not applicable */ 562 /* not applicable */
563 dbgprintf ("sd_remov"); 563 dbgprintf ("sd_remov");
564 return false; 564 return false;
@@ -596,7 +596,7 @@ static int sd_wait_for_state(const int card_no, unsigned int state)
596 } 596 }
597} 597}
598 598
599static int sd_transfer_sectors(int card_no, unsigned long start, 599static int sd_transfer_sectors(int card_no, sector_t start,
600 int count, void* buf, const bool write) 600 int count, void* buf, const bool write)
601{ 601{
602 int ret = EC_OK; 602 int ret = EC_OK;
@@ -636,7 +636,7 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
636 void *dma_buf; 636 void *dma_buf;
637 const int cmd = 637 const int cmd =
638 write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK; 638 write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK;
639 unsigned long start_addr = start; 639 sector_t start_addr = start;
640 640
641 dma_buf = aligned_buffer; 641 dma_buf = aligned_buffer;
642 if(transfer > UNALIGNED_NUM_SECTORS) 642 if(transfer > UNALIGNED_NUM_SECTORS)
@@ -650,10 +650,10 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
650 650
651 /* TODO? */ 651 /* TODO? */
652 SDIFSTA = SDIFSTA | S3C2440_SDIFSTA_FIFORESET; 652 SDIFSTA = SDIFSTA | S3C2440_SDIFSTA_FIFORESET;
653 SDIDCON = S3C2440_SDIDCON_DS_WORD | 653 SDIDCON = S3C2440_SDIDCON_DS_WORD |
654 S3C2410_SDIDCON_BLOCKMODE | S3C2410_SDIDCON_WIDEBUS | 654 S3C2410_SDIDCON_BLOCKMODE | S3C2410_SDIDCON_WIDEBUS |
655 S3C2410_SDIDCON_DMAEN | 655 S3C2410_SDIDCON_DMAEN |
656 S3C2440_SDIDCON_DATSTART | 656 S3C2440_SDIDCON_DATSTART |
657 ( transfer << 0); 657 ( transfer << 0);
658 if (write) 658 if (write)
659 SDIDCON |= S3C2410_SDIDCON_TXAFTERRESP | S3C2410_SDIDCON_XFER_TXSTART; 659 SDIDCON |= S3C2410_SDIDCON_TXAFTERRESP | S3C2410_SDIDCON_XFER_TXSTART;
@@ -665,6 +665,7 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
665 INTPND = SDI_MASK; 665 INTPND = SDI_MASK;
666 666
667 /* Initiate read/write command */ 667 /* Initiate read/write command */
668 // XXX 64-bit
668 if(!send_cmd(card_no, cmd, start_addr, MCI_ARG | MCI_RESP, NULL)) 669 if(!send_cmd(card_no, cmd, start_addr, MCI_ARG | MCI_RESP, NULL))
669 { 670 {
670 ret -= 3*20; 671 ret -= 3*20;
@@ -674,32 +675,32 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
674 if(write) 675 if(write)
675 { 676 {
676 request.source_addr = dma_buf; 677 request.source_addr = dma_buf;
677 request.source_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO; 678 request.source_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO;
678 request.dest_addr = &SDIDAT_LLE; 679 request.dest_addr = &SDIDAT_LLE;
679 request.dest_control = DISRCC_LOC_APB | DISRCC_INC_FIXED; 680 request.dest_control = DISRCC_LOC_APB | DISRCC_INC_FIXED;
680 request.count = transfer * SD_BLOCK_SIZE / sizeof(long); 681 request.count = transfer * SD_BLOCK_SIZE / sizeof(long);
681 request.source_map = DMA_SRC_MAP_SDI; 682 request.source_map = DMA_SRC_MAP_SDI;
682 request.control = DCON_DMD_HS | DCON_SYNC_APB | 683 request.control = DCON_DMD_HS | DCON_SYNC_APB |
683 DCON_HW_SEL | 684 DCON_HW_SEL |
684 DCON_NO_RELOAD | DCON_DSZ_WORD; 685 DCON_NO_RELOAD | DCON_DSZ_WORD;
685 request.callback = NULL; 686 request.callback = NULL;
686 687
687 dma_enable_channel(0, &request); 688 dma_enable_channel(0, &request);
688 } 689 }
689 else 690 else
690 { 691 {
691 request.source_addr = &SDIDAT_LLE; 692 request.source_addr = &SDIDAT_LLE;
692 request.source_control = DISRCC_LOC_APB | DISRCC_INC_FIXED; 693 request.source_control = DISRCC_LOC_APB | DISRCC_INC_FIXED;
693 request.dest_addr = dma_buf; 694 request.dest_addr = dma_buf;
694 request.dest_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO; 695 request.dest_control = DISRCC_LOC_AHB | DISRCC_INC_AUTO;
695 request.count = transfer * SD_BLOCK_SIZE / sizeof(long); 696 request.count = transfer * SD_BLOCK_SIZE / sizeof(long);
696 request.source_map = DMA_SRC_MAP_SDI; 697 request.source_map = DMA_SRC_MAP_SDI;
697 request.control = DCON_DMD_HS | DCON_SYNC_APB | 698 request.control = DCON_DMD_HS | DCON_SYNC_APB |
698 DCON_HW_SEL | 699 DCON_HW_SEL |
699 DCON_NO_RELOAD | DCON_DSZ_WORD; 700 DCON_NO_RELOAD | DCON_DSZ_WORD;
700 request.callback = NULL; 701 request.callback = NULL;
701 702
702 dma_enable_channel(0, &request); 703 dma_enable_channel(0, &request);
703 } 704 }
704 705
705#if 0 706#if 0
@@ -716,12 +717,12 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
716#endif 717#endif
717 718
718 semaphore_wait(&transfer_completion_signal, 100 /*TIMEOUT_BLOCK*/); 719 semaphore_wait(&transfer_completion_signal, 100 /*TIMEOUT_BLOCK*/);
719 720
720 /* wait for DMA to finish */ 721 /* wait for DMA to finish */
721 while (DSTAT0 & DSTAT_STAT_BUSY) 722 while (DSTAT0 & DSTAT_STAT_BUSY)
722 ; 723 ;
723 724
724#if 0 725#if 0
725 status = SDIDSTA; 726 status = SDIDSTA;
726 while ((status & (S3C2410_SDIDSTA_DATATIMEOUT|S3C2410_SDIDSTA_XFERFINISH)) == 0) 727 while ((status & (S3C2410_SDIDSTA_DATATIMEOUT|S3C2410_SDIDSTA_XFERFINISH)) == 0)
727 { 728 {
@@ -738,10 +739,10 @@ static int sd_transfer_sectors(int card_no, unsigned long start,
738 count -= transfer; 739 count -= transfer;
739 loops = 0; /* reset errors counter */ 740 loops = 0; /* reset errors counter */
740 } 741 }
741 else 742 else
742 { 743 {
743 dbgprintf ("SD transfer error : 0x%x\n", transfer_error[card_no]); 744 dbgprintf ("SD transfer error : 0x%x\n", transfer_error[card_no]);
744 745
745 if(loops++ > MAX_TRANSFER_ERRORS) 746 if(loops++ > MAX_TRANSFER_ERRORS)
746 { 747 {
747 led_flash(LED1|LED2, LED3|LED4); 748 led_flash(LED1|LED2, LED3|LED4);
@@ -783,11 +784,11 @@ sd_transfer_error:
783 return ret; 784 return ret;
784} 785}
785 786
786int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount, 787int sd_read_sectors(IF_MD(int card_no,) sector_t start, int incount,
787 void* inbuf) 788 void* inbuf)
788{ 789{
789 int ret; 790 int ret;
790 791
791#ifdef HAVE_MULTIDRIVE 792#ifdef HAVE_MULTIDRIVE
792 dbgprintf ("sd_read %d %x %d\n", card_no, start, incount); 793 dbgprintf ("sd_read %d %x %d\n", card_no, start, incount);
793#else 794#else
@@ -804,7 +805,7 @@ int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount,
804} 805}
805 806
806/*****************************************************************************/ 807/*****************************************************************************/
807int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, 808int sd_write_sectors(IF_MD(int drive,) sector_t start, int count,
808 const void* outbuf) 809 const void* outbuf)
809{ 810{
810#ifdef BOOTLOADER /* we don't need write support in bootloader */ 811#ifdef BOOTLOADER /* we don't need write support in bootloader */
@@ -835,7 +836,7 @@ void sd_enable(bool on)
835{ 836{
836 dbgprintf ("sd_enable %d\n", on); 837 dbgprintf ("sd_enable %d\n", on);
837 /* TODO: enable/disable SDI clock */ 838 /* TODO: enable/disable SDI clock */
838 839
839 if (sd_enabled == on) 840 if (sd_enabled == on)
840 return; /* nothing to do */ 841 return; /* nothing to do */
841 if (on) 842 if (on)
@@ -847,14 +848,14 @@ void sd_enable(bool on)
847 sd_enabled = false; 848 sd_enabled = false;
848 } 849 }
849} 850}
850 851
851int sd_init(void) 852int sd_init(void)
852{ 853{
853 int ret = EC_OK; 854 int ret = EC_OK;
854 dbgprintf ("\n==============================\n"); 855 dbgprintf ("\n==============================\n");
855 dbgprintf (" sd_init\n"); 856 dbgprintf (" sd_init\n");
856 dbgprintf ("==============================\n"); 857 dbgprintf ("==============================\n");
857 858
858 init_sdi_controller (0); 859 init_sdi_controller (0);
859#ifndef BOOTLOADER 860#ifndef BOOTLOADER
860 sd_enabled = true; 861 sd_enabled = true;
@@ -893,7 +894,7 @@ long sd_last_disk_activity(void)
893} 894}
894 895
895tCardInfo *card_get_info_target(int card_no) 896tCardInfo *card_get_info_target(int card_no)
896{ 897{
897 return &card_info[card_no]; 898 return &card_info[card_no];
898} 899}
899 900
diff --git a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
index 7f68b82a0d..34a1c46043 100644
--- a/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
+++ b/firmware/target/arm/s5l8700/ata-nand-s5l8700.c
@@ -29,17 +29,17 @@
29#include "ftl-target.h" 29#include "ftl-target.h"
30#include "nand-target.h" 30#include "nand-target.h"
31 31
32/** static, private data **/ 32/** static, private data **/
33static bool initialized = false; 33static bool initialized = false;
34 34
35/* API Functions */ 35/* API Functions */
36int nand_read_sectors(IF_MD(int drive,) unsigned long start, int incount, 36int nand_read_sectors(IF_MD(int drive,) sector_t start, int incount,
37 void* inbuf) 37 void* inbuf)
38{ 38{
39 return ftl_read(start, incount, inbuf); 39 return ftl_read(start, incount, inbuf);
40} 40}
41 41
42int nand_write_sectors(IF_MD(int drive,) unsigned long start, int count, 42int nand_write_sectors(IF_MD(int drive,) sector_t start, int count,
43 const void* outbuf) 43 const void* outbuf)
44{ 44{
45 return ftl_write(start, count, outbuf); 45 return ftl_write(start, count, outbuf);
@@ -106,7 +106,7 @@ int nand_num_drives(int first_drive)
106{ 106{
107 /* We don't care which logical drive number(s) we have been assigned */ 107 /* We don't care which logical drive number(s) we have been assigned */
108 (void)first_drive; 108 (void)first_drive;
109 109
110 return 1; 110 return 1;
111} 111}
112#endif 112#endif
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c
index 0d831a7167..7071d411b5 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c
+++ b/firmware/target/arm/s5l8700/ipodnano2g/ftl-nano2g.c
@@ -186,7 +186,6 @@ struct ftl_cxt_type
186 There is one of these per bank. */ 186 There is one of these per bank. */
187struct ftl_vfl_cxt_type 187struct ftl_vfl_cxt_type
188{ 188{
189
190 /* Cross-bank update sequence number, incremented on every VFL 189 /* Cross-bank update sequence number, incremented on every VFL
191 context commit on any bank. */ 190 context commit on any bank. */
192 uint32_t usn; 191 uint32_t usn;
@@ -525,18 +524,24 @@ static uint32_t ftl_vfl_verify_checksum(uint32_t bank)
525 return 1; 524 return 1;
526} 525}
527 526
528
529#ifndef FTL_READONLY 527#ifndef FTL_READONLY
528
529#if __GNUC__ >= 9
530#pragma GCC diagnostic push
531#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
532#endif
533
530/* Updates the checksums of the VFL context of the specified bank */ 534/* Updates the checksums of the VFL context of the specified bank */
531static void ftl_vfl_update_checksum(uint32_t bank) 535static void ftl_vfl_update_checksum(uint32_t bank)
532{ 536{
533 ftl_vfl_calculate_checksum(bank, &ftl_vfl_cxt[bank].checksum1, 537 ftl_vfl_calculate_checksum(bank, &ftl_vfl_cxt[bank].checksum1,
534 &ftl_vfl_cxt[bank].checksum2); 538 &ftl_vfl_cxt[bank].checksum2);
535} 539}
536#endif
537 540
541#if __GNUC__ >= 9
542#pragma GCC diagnostic pop
543#endif
538 544
539#ifndef FTL_READONLY
540/* Writes 8 copies of the VFL context of the specified bank to flash, 545/* Writes 8 copies of the VFL context of the specified bank to flash,
541 and succeeds if at least 4 can be read back properly. */ 546 and succeeds if at least 4 can be read back properly. */
542static uint32_t ftl_vfl_store_cxt(uint32_t bank) 547static uint32_t ftl_vfl_store_cxt(uint32_t bank)
@@ -2107,7 +2112,7 @@ uint32_t ftl_sync(void)
2107 if (ftl_cxt.clean_flag == 1) return 0; 2112 if (ftl_cxt.clean_flag == 1) return 0;
2108 2113
2109 mutex_lock(&ftl_mtx); 2114 mutex_lock(&ftl_mtx);
2110 2115
2111#ifdef FTL_TRACE 2116#ifdef FTL_TRACE
2112 DEBUGF("FTL: Syncing\n"); 2117 DEBUGF("FTL: Syncing\n");
2113#endif 2118#endif
diff --git a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
index 7a3be20577..8cc5b44aca 100644
--- a/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
+++ b/firmware/target/arm/s5l8702/ipod6g/storage_ata-6g.c
@@ -29,6 +29,9 @@
29#include "mmcdefs-target.h" 29#include "mmcdefs-target.h"
30#include "s5l8702.h" 30#include "s5l8702.h"
31#include "led.h" 31#include "led.h"
32#include "debug.h"
33#include "panic.h"
34#include "fs_defines.h"
32 35
33#ifndef ATA_RETRIES 36#ifndef ATA_RETRIES
34#define ATA_RETRIES 3 37#define ATA_RETRIES 3
@@ -58,10 +61,9 @@
58#define CEATA_DAT_NONBUSY_TIMEOUT 5000000 61#define CEATA_DAT_NONBUSY_TIMEOUT 5000000
59#define CEATA_MMC_RCA 1 62#define CEATA_MMC_RCA 1
60 63
61
62/** static, private data **/ 64/** static, private data **/
63static uint8_t ceata_taskfile[16] STORAGE_ALIGN_ATTR; 65static uint8_t ceata_taskfile[16] STORAGE_ALIGN_ATTR;
64static uint16_t ata_identify_data[0x100] STORAGE_ALIGN_ATTR; 66static uint16_t identify_info[ATA_IDENTIFY_WORDS] STORAGE_ALIGN_ATTR;
65static bool ceata; 67static bool ceata;
66static bool ata_lba48; 68static bool ata_lba48;
67static bool ata_dma; 69static bool ata_dma;
@@ -70,18 +72,18 @@ static struct mutex ata_mutex;
70static struct semaphore ata_wakeup; 72static struct semaphore ata_wakeup;
71static uint32_t ata_dma_flags; 73static uint32_t ata_dma_flags;
72static long ata_last_activity_value = -1; 74static long ata_last_activity_value = -1;
73static long ata_sleep_timeout = 20 * HZ; 75static long ata_sleep_timeout = 7 * HZ;
74static bool ata_powered; 76static bool ata_powered;
75static const int ata_retries = ATA_RETRIES; 77static bool canflush = true;
76static const bool ata_error_srst = true;
77static struct semaphore mmc_wakeup; 78static struct semaphore mmc_wakeup;
78static struct semaphore mmc_comp_wakeup; 79static struct semaphore mmc_comp_wakeup;
79static int spinup_time = 0; 80static int spinup_time = 0;
80static int dma_mode = 0; 81static int dma_mode = 0;
81static char aligned_buffer[SECTOR_SIZE] STORAGE_ALIGN_ATTR;
82 82
83static int ata_reset(void); 83static const int ata_retries = ATA_RETRIES;
84static const bool ata_error_srst = true;
84 85
86static int ata_reset(void);
85 87
86static uint16_t ata_read_cbr(uint32_t volatile* reg) 88static uint16_t ata_read_cbr(uint32_t volatile* reg)
87{ 89{
@@ -103,8 +105,10 @@ static int ata_wait_for_not_bsy(long timeout)
103 while (true) 105 while (true)
104 { 106 {
105 uint8_t csd = ata_read_cbr(&ATA_PIO_CSD); 107 uint8_t csd = ata_read_cbr(&ATA_PIO_CSD);
106 if (!(csd & BIT(7))) return 0; 108 if (!(csd & BIT(7)))
107 if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(0); 109 return 0;
110 if (TIMEOUT_EXPIRED(startusec, timeout))
111 RET_ERR(0);
108 yield(); 112 yield();
109 } 113 }
110} 114}
@@ -116,8 +120,10 @@ static int ata_wait_for_rdy(long timeout)
116 while (true) 120 while (true)
117 { 121 {
118 uint8_t dad = ata_read_cbr(&ATA_PIO_DAD); 122 uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
119 if (dad & BIT(6)) return 0; 123 if (dad & BIT(6))
120 if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(1); 124 return 0;
125 if (TIMEOUT_EXPIRED(startusec, timeout))
126 RET_ERR(1);
121 yield(); 127 yield();
122 } 128 }
123} 129}
@@ -129,9 +135,12 @@ static int ata_wait_for_start_of_transfer(long timeout)
129 while (true) 135 while (true)
130 { 136 {
131 uint8_t dad = ata_read_cbr(&ATA_PIO_DAD); 137 uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
132 if (dad & BIT(0)) RET_ERR(1); 138 if (dad & BIT(0))
133 if ((dad & (BIT(7) | BIT(3))) == BIT(3)) return 0; 139 RET_ERR(1);
134 if (TIMEOUT_EXPIRED(startusec, timeout)) RET_ERR(2); 140 if ((dad & (BIT(7) | BIT(3))) == BIT(3))
141 return 0;
142 if (TIMEOUT_EXPIRED(startusec, timeout))
143 RET_ERR(2);
135 yield(); 144 yield();
136 } 145 }
137} 146}
@@ -140,8 +149,10 @@ static int ata_wait_for_end_of_transfer(long timeout)
140{ 149{
141 PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0); 150 PASS_RC(ata_wait_for_not_bsy(timeout), 2, 0);
142 uint8_t dad = ata_read_cbr(&ATA_PIO_DAD); 151 uint8_t dad = ata_read_cbr(&ATA_PIO_DAD);
143 if (dad & BIT(0)) RET_ERR(1); 152 if (dad & BIT(0))
144 if ((dad & (BIT(3) | BITRANGE(5, 7))) == BIT(6)) return 0; 153 RET_ERR(1);
154 if ((dad & (BIT(3) | BITRANGE(5, 7))) == BIT(6))
155 return 0;
145 RET_ERR(2); 156 RET_ERR(2);
146} 157}
147 158
@@ -149,13 +160,17 @@ static int mmc_dsta_check_command_success(bool disable_crc)
149{ 160{
150 int rc = 0; 161 int rc = 0;
151 uint32_t dsta = SDCI_DSTA; 162 uint32_t dsta = SDCI_DSTA;
152 if (dsta & SDCI_DSTA_RESTOUTE) rc |= 1; 163 if (dsta & SDCI_DSTA_RESTOUTE)
153 if (dsta & SDCI_DSTA_RESENDE) rc |= 2; 164 rc |= 1;
154 if (dsta & SDCI_DSTA_RESINDE) rc |= 4; 165 if (dsta & SDCI_DSTA_RESENDE)
166 rc |= 2;
167 if (dsta & SDCI_DSTA_RESINDE)
168 rc |= 4;
155 if (!disable_crc) 169 if (!disable_crc)
156 if (dsta & SDCI_DSTA_RESCRCE) 170 if (dsta & SDCI_DSTA_RESCRCE)
157 rc |= 8; 171 rc |= 8;
158 if (rc) RET_ERR(rc); 172 if (rc)
173 RET_ERR(rc);
159 return 0; 174 return 0;
160} 175}
161 176
@@ -164,7 +179,8 @@ static bool mmc_send_command(uint32_t cmd, uint32_t arg, uint32_t* result, int t
164 long starttime = USEC_TIMER; 179 long starttime = USEC_TIMER;
165 while ((SDCI_STATE & SDCI_STATE_CMD_STATE_MASK) != SDCI_STATE_CMD_STATE_CMD_IDLE) 180 while ((SDCI_STATE & SDCI_STATE_CMD_STATE_MASK) != SDCI_STATE_CMD_STATE_CMD_IDLE)
166 { 181 {
167 if (TIMEOUT_EXPIRED(starttime, timeout)) RET_ERR(0); 182 if (TIMEOUT_EXPIRED(starttime, timeout))
183 RET_ERR(0);
168 yield(); 184 yield();
169 } 185 }
170 SDCI_STAC = SDCI_STAC_CLR_CMDEND | SDCI_STAC_CLR_BIT_3 186 SDCI_STAC = SDCI_STAC_CLR_CMDEND | SDCI_STAC_CLR_BIT_3
@@ -179,32 +195,38 @@ static bool mmc_send_command(uint32_t cmd, uint32_t arg, uint32_t* result, int t
179 | SDCI_STAC_CLR_RD_DATENDE6 | SDCI_STAC_CLR_RD_DATENDE7; 195 | SDCI_STAC_CLR_RD_DATENDE6 | SDCI_STAC_CLR_RD_DATENDE7;
180 SDCI_ARGU = arg; 196 SDCI_ARGU = arg;
181 SDCI_CMD = cmd; 197 SDCI_CMD = cmd;
182 if (!(SDCI_DSTA & SDCI_DSTA_CMDRDY)) RET_ERR(1); 198 if (!(SDCI_DSTA & SDCI_DSTA_CMDRDY))
199 RET_ERR(1);
183 SDCI_CMD = cmd | SDCI_CMD_CMDSTR; 200 SDCI_CMD = cmd | SDCI_CMD_CMDSTR;
184 long sleepbase = USEC_TIMER; 201 long sleepbase = USEC_TIMER;
185 while (TIMEOUT_EXPIRED(sleepbase, 1000)) yield(); 202 while (TIMEOUT_EXPIRED(sleepbase, 1000))
203 yield();
186 while (!(SDCI_DSTA & SDCI_DSTA_CMDEND)) 204 while (!(SDCI_DSTA & SDCI_DSTA_CMDEND))
187 { 205 {
188 if (TIMEOUT_EXPIRED(starttime, timeout)) RET_ERR(2); 206 if (TIMEOUT_EXPIRED(starttime, timeout))
207 RET_ERR(2);
189 yield(); 208 yield();
190 } 209 }
191 if ((cmd & SDCI_CMD_RES_TYPE_MASK) != SDCI_CMD_RES_TYPE_NONE) 210 if ((cmd & SDCI_CMD_RES_TYPE_MASK) != SDCI_CMD_RES_TYPE_NONE)
192 { 211 {
193 while (!(SDCI_DSTA & SDCI_DSTA_RESEND)) 212 while (!(SDCI_DSTA & SDCI_DSTA_RESEND))
194 { 213 {
195 if (TIMEOUT_EXPIRED(starttime, timeout)) RET_ERR(3); 214 if (TIMEOUT_EXPIRED(starttime, timeout))
215 RET_ERR(3);
196 yield(); 216 yield();
197 } 217 }
198 if (cmd & SDCI_CMD_RES_BUSY) 218 if (cmd & SDCI_CMD_RES_BUSY)
199 while (SDCI_DSTA & SDCI_DSTA_DAT_BUSY) 219 while (SDCI_DSTA & SDCI_DSTA_DAT_BUSY)
200 { 220 {
201 if (TIMEOUT_EXPIRED(starttime, CEATA_DAT_NONBUSY_TIMEOUT)) RET_ERR(4); 221 if (TIMEOUT_EXPIRED(starttime, CEATA_DAT_NONBUSY_TIMEOUT))
222 RET_ERR(4);
202 yield(); 223 yield();
203 } 224 }
204 } 225 }
205 bool nocrc = (cmd & SDCI_CMD_RES_SIZE_MASK) == SDCI_CMD_RES_SIZE_136; 226 bool nocrc = (cmd & SDCI_CMD_RES_SIZE_MASK) == SDCI_CMD_RES_SIZE_136;
206 PASS_RC(mmc_dsta_check_command_success(nocrc), 3, 5); 227 PASS_RC(mmc_dsta_check_command_success(nocrc), 3, 5);
207 if (result) *result = SDCI_RESP0; 228 if (result)
229 *result = SDCI_RESP0;
208 return 0; 230 return 0;
209} 231}
210 232
@@ -227,7 +249,8 @@ static int mmc_init(void)
227 uint32_t result; 249 uint32_t result;
228 do 250 do
229 { 251 {
230 if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT)) RET_ERR(1); 252 if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT))
253 RET_ERR(1);
231 sleep(HZ / 100); 254 sleep(HZ / 100);
232 PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SEND_OP_COND) 255 PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SEND_OP_COND)
233 | SDCI_CMD_CMD_TYPE_BCR | SDCI_CMD_RES_TYPE_R3 256 | SDCI_CMD_CMD_TYPE_BCR | SDCI_CMD_RES_TYPE_R3
@@ -252,7 +275,8 @@ static int mmc_init(void)
252 MMC_CMD_SELECT_CARD_RCA(CEATA_MMC_RCA), 275 MMC_CMD_SELECT_CARD_RCA(CEATA_MMC_RCA),
253 NULL, CEATA_COMMAND_TIMEOUT), 3, 5); 276 NULL, CEATA_COMMAND_TIMEOUT), 3, 5);
254 PASS_RC(mmc_get_card_status(&result), 3, 6); 277 PASS_RC(mmc_get_card_status(&result), 3, 6);
255 if ((result & MMC_STATUS_CURRENT_STATE_MASK) != MMC_STATUS_CURRENT_STATE_TRAN) RET_ERR(7); 278 if ((result & MMC_STATUS_CURRENT_STATE_MASK) != MMC_STATUS_CURRENT_STATE_TRAN)
279 RET_ERR(7);
256 return 0; 280 return 0;
257} 281}
258 282
@@ -286,7 +310,8 @@ static int ceata_soft_reset(void)
286 do 310 do
287 { 311 {
288 PASS_RC(mmc_fastio_read(0xf, &status), 2, 2); 312 PASS_RC(mmc_fastio_read(0xf, &status), 2, 2);
289 if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT)) RET_ERR(3); 313 if (TIMEOUT_EXPIRED(startusec, CEATA_POWERUP_TIMEOUT))
314 RET_ERR(3);
290 sleep(HZ / 100); 315 sleep(HZ / 100);
291 } 316 }
292 while (status & 0x80); 317 while (status & 0x80);
@@ -299,16 +324,21 @@ static int mmc_dsta_check_data_success(void)
299 uint32_t dsta = SDCI_DSTA; 324 uint32_t dsta = SDCI_DSTA;
300 if (dsta & (SDCI_DSTA_WR_DATCRCE | SDCI_DSTA_RD_DATCRCE)) 325 if (dsta & (SDCI_DSTA_WR_DATCRCE | SDCI_DSTA_RD_DATCRCE))
301 { 326 {
302 if (dsta & SDCI_DSTA_WR_DATCRCE) rc |= 1; 327 if (dsta & SDCI_DSTA_WR_DATCRCE)
303 if (dsta & SDCI_DSTA_RD_DATCRCE) rc |= 2; 328 rc |= 1;
304 if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_TXERR) rc |= 4; 329 if (dsta & SDCI_DSTA_RD_DATCRCE)
305 else if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_CARDERR) rc |= 8; 330 rc |= 2;
331 if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_TXERR)
332 rc |= 4;
333 else if ((dsta & SDCI_DSTA_WR_CRC_STATUS_MASK) == SDCI_DSTA_WR_CRC_STATUS_CARDERR)
334 rc |= 8;
306 } 335 }
307 if (dsta & (SDCI_DSTA_RD_DATENDE0 | SDCI_DSTA_RD_DATENDE1 | SDCI_DSTA_RD_DATENDE2 336 if (dsta & (SDCI_DSTA_RD_DATENDE0 | SDCI_DSTA_RD_DATENDE1 | SDCI_DSTA_RD_DATENDE2
308 | SDCI_DSTA_RD_DATENDE3 | SDCI_DSTA_RD_DATENDE4 | SDCI_DSTA_RD_DATENDE5 337 | SDCI_DSTA_RD_DATENDE3 | SDCI_DSTA_RD_DATENDE4 | SDCI_DSTA_RD_DATENDE5
309 | SDCI_DSTA_RD_DATENDE6 | SDCI_DSTA_RD_DATENDE7)) 338 | SDCI_DSTA_RD_DATENDE6 | SDCI_DSTA_RD_DATENDE7))
310 rc |= 16; 339 rc |= 16;
311 if (rc) RET_ERR(rc); 340 if (rc)
341 RET_ERR(rc);
312 return 0; 342 return 0;
313} 343}
314 344
@@ -321,7 +351,8 @@ static void mmc_discard_irq(void)
321 351
322static int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size) 352static int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size)
323{ 353{
324 if (size > 0x10) RET_ERR(0); 354 if (size > 0x10)
355 RET_ERR(0);
325 mmc_discard_irq(); 356 mmc_discard_irq();
326 SDCI_DMASIZE = size; 357 SDCI_DMASIZE = size;
327 SDCI_DMACOUNT = 1; 358 SDCI_DMACOUNT = 1;
@@ -335,8 +366,8 @@ static int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size
335 | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc) 366 | MMC_CMD_CEATA_RW_MULTIPLE_REG_ADDRESS(addr & 0xfc)
336 | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc), 367 | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc),
337 NULL, CEATA_COMMAND_TIMEOUT), 2, 1); 368 NULL, CEATA_COMMAND_TIMEOUT), 2, 1);
338 if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) 369 if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) == OBJ_WAIT_TIMEDOUT)
339 == OBJ_WAIT_TIMEDOUT) RET_ERR(2); 370 RET_ERR(2);
340 PASS_RC(mmc_dsta_check_data_success(), 2, 3); 371 PASS_RC(mmc_dsta_check_data_success(), 2, 3);
341 return 0; 372 return 0;
342} 373}
@@ -344,7 +375,8 @@ static int ceata_read_multiple_register(uint32_t addr, void* dest, uint32_t size
344static int ceata_write_multiple_register(uint32_t addr, void* dest, uint32_t size) 375static int ceata_write_multiple_register(uint32_t addr, void* dest, uint32_t size)
345{ 376{
346 uint32_t i; 377 uint32_t i;
347 if (size > 0x10) RET_ERR(0); 378 if (size > 0x10)
379 RET_ERR(0);
348 mmc_discard_irq(); 380 mmc_discard_irq();
349 SDCI_DMASIZE = size; 381 SDCI_DMASIZE = size;
350 SDCI_DMACOUNT = 0; 382 SDCI_DMACOUNT = 0;
@@ -358,13 +390,15 @@ static int ceata_write_multiple_register(uint32_t addr, void* dest, uint32_t siz
358 | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc), 390 | MMC_CMD_CEATA_RW_MULTIPLE_REG_COUNT(size & 0xfc),
359 NULL, CEATA_COMMAND_TIMEOUT), 3, 1); 391 NULL, CEATA_COMMAND_TIMEOUT), 3, 1);
360 SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX; 392 SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX;
361 for (i = 0; i < size / 4; i++) SDCI_DATA = ((uint32_t*)dest)[i]; 393 for (i = 0; i < size / 4; i++)
394 SDCI_DATA = ((uint32_t*)dest)[i];
362 long startusec = USEC_TIMER; 395 long startusec = USEC_TIMER;
363 if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) 396 if (semaphore_wait(&mmc_wakeup, CEATA_COMMAND_TIMEOUT * HZ / 1000000) == OBJ_WAIT_TIMEDOUT)
364 == OBJ_WAIT_TIMEDOUT) RET_ERR(2); 397 RET_ERR(2);
365 while ((SDCI_STATE & SDCI_STATE_DAT_STATE_MASK) != SDCI_STATE_DAT_STATE_IDLE) 398 while ((SDCI_STATE & SDCI_STATE_DAT_STATE_MASK) != SDCI_STATE_DAT_STATE_IDLE)
366 { 399 {
367 if (TIMEOUT_EXPIRED(startusec, CEATA_COMMAND_TIMEOUT)) RET_ERR(3); 400 if (TIMEOUT_EXPIRED(startusec, CEATA_COMMAND_TIMEOUT))
401 RET_ERR(3);
368 yield(); 402 yield();
369 } 403 }
370 PASS_RC(mmc_dsta_check_data_success(), 3, 4); 404 PASS_RC(mmc_dsta_check_data_success(), 3, 4);
@@ -381,13 +415,17 @@ static int ceata_init(int buswidth)
381 | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_HS_TIMING) 415 | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_HS_TIMING)
382 | MMC_CMD_SWITCH_VALUE(MMC_CMD_SWITCH_FIELD_HS_TIMING_HIGH_SPEED), 416 | MMC_CMD_SWITCH_VALUE(MMC_CMD_SWITCH_FIELD_HS_TIMING_HIGH_SPEED),
383 &result, CEATA_COMMAND_TIMEOUT), 3, 0); 417 &result, CEATA_COMMAND_TIMEOUT), 3, 0);
384 if (result & MMC_STATUS_SWITCH_ERROR) RET_ERR(1); 418 if (result & MMC_STATUS_SWITCH_ERROR)
419 RET_ERR(1);
385 if (buswidth > 1) 420 if (buswidth > 1)
386 { 421 {
387 int setting; 422 int setting;
388 if (buswidth == 4) setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_4BIT; 423 if (buswidth == 4)
389 else if (buswidth == 8) setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_8BIT; 424 setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_4BIT;
390 else setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_1BIT; 425 else if (buswidth == 8)
426 setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_8BIT;
427 else
428 setting = MMC_CMD_SWITCH_FIELD_BUS_WIDTH_1BIT;
391 PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SWITCH) | SDCI_CMD_RES_BUSY 429 PASS_RC(mmc_send_command(SDCI_CMD_CMD_NUM(MMC_CMD_SWITCH) | SDCI_CMD_RES_BUSY
392 | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1 430 | SDCI_CMD_CMD_TYPE_AC | SDCI_CMD_RES_TYPE_R1
393 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR, 431 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
@@ -395,7 +433,8 @@ static int ceata_init(int buswidth)
395 | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_BUS_WIDTH) 433 | MMC_CMD_SWITCH_INDEX(MMC_CMD_SWITCH_FIELD_BUS_WIDTH)
396 | MMC_CMD_SWITCH_VALUE(setting), 434 | MMC_CMD_SWITCH_VALUE(setting),
397 &result, CEATA_COMMAND_TIMEOUT), 3, 2); 435 &result, CEATA_COMMAND_TIMEOUT), 3, 2);
398 if (result & MMC_STATUS_SWITCH_ERROR) RET_ERR(3); 436 if (result & MMC_STATUS_SWITCH_ERROR)
437 RET_ERR(3);
399 if (buswidth == 4) 438 if (buswidth == 4)
400 SDCI_CTRL = (SDCI_CTRL & ~SDCI_CTRL_BUS_WIDTH_MASK) | SDCI_CTRL_BUS_WIDTH_4BIT; 439 SDCI_CTRL = (SDCI_CTRL & ~SDCI_CTRL_BUS_WIDTH_MASK) | SDCI_CTRL_BUS_WIDTH_4BIT;
401 else if (buswidth == 8) 440 else if (buswidth == 8)
@@ -403,7 +442,8 @@ static int ceata_init(int buswidth)
403 } 442 }
404 PASS_RC(ceata_soft_reset(), 3, 4); 443 PASS_RC(ceata_soft_reset(), 3, 4);
405 PASS_RC(ceata_read_multiple_register(0, ceata_taskfile, 0x10), 3, 5); 444 PASS_RC(ceata_read_multiple_register(0, ceata_taskfile, 0x10), 3, 5);
406 if (ceata_taskfile[0xc] != 0xce || ceata_taskfile[0xd] != 0xaa) RET_ERR(6); 445 if (ceata_taskfile[0xc] != 0xce || ceata_taskfile[0xd] != 0xaa)
446 RET_ERR(6);
407 PASS_RC(mmc_fastio_write(6, 0), 3, 7); 447 PASS_RC(mmc_fastio_write(6, 0), 3, 7);
408 return 0; 448 return 0;
409} 449}
@@ -427,8 +467,10 @@ static int ceata_wait_idle(void)
427 { 467 {
428 uint32_t status; 468 uint32_t status;
429 PASS_RC(mmc_fastio_read(0xf, &status), 1, 0); 469 PASS_RC(mmc_fastio_read(0xf, &status), 1, 0);
430 if (!(status & 0x88)) return 0; 470 if (!(status & 0x88))
431 if (TIMEOUT_EXPIRED(startusec, CEATA_DAT_NONBUSY_TIMEOUT)) RET_ERR(1); 471 return 0;
472 if (TIMEOUT_EXPIRED(startusec, CEATA_DAT_NONBUSY_TIMEOUT))
473 RET_ERR(1);
432 sleep(HZ / 20); 474 sleep(HZ / 20);
433 } 475 }
434} 476}
@@ -477,7 +519,8 @@ static int ceata_rw_multiple_block(bool write, void* buf, uint32_t count, long t
477 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR, 519 | SDCI_CMD_RES_SIZE_48 | SDCI_CMD_NCR_NID_NCR,
478 direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count), 520 direction | MMC_CMD_CEATA_RW_MULTIPLE_BLOCK_COUNT(count),
479 NULL, CEATA_COMMAND_TIMEOUT), 3, 0); 521 NULL, CEATA_COMMAND_TIMEOUT), 3, 0);
480 if (write) SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX; 522 if (write)
523 SDCI_DCTRL = SDCI_DCTRL_TRCONT_TX;
481 if (semaphore_wait(&mmc_wakeup, timeout) == OBJ_WAIT_TIMEDOUT) 524 if (semaphore_wait(&mmc_wakeup, timeout) == OBJ_WAIT_TIMEDOUT)
482 { 525 {
483 PASS_RC(ceata_cancel_command(), 3, 1); 526 PASS_RC(ceata_cancel_command(), 3, 1);
@@ -510,7 +553,8 @@ static int ata_identify(uint16_t* buf)
510 ata_write_cbr(&ATA_PIO_DVR, 0); 553 ata_write_cbr(&ATA_PIO_DVR, 0);
511 ata_write_cbr(&ATA_PIO_CSD, CMD_IDENTIFY); 554 ata_write_cbr(&ATA_PIO_CSD, CMD_IDENTIFY);
512 PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1); 555 PASS_RC(ata_wait_for_start_of_transfer(10000000), 1, 1);
513 for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR); 556 for (i = 0; i < ATA_IDENTIFY_WORDS; i++)
557 buf[i] = ata_read_cbr(&ATA_PIO_DTR);
514 } 558 }
515 return 0; 559 return 0;
516} 560}
@@ -549,6 +593,41 @@ static int ata_set_feature(uint32_t feature, uint32_t param)
549 return 0; 593 return 0;
550} 594}
551 595
596#ifdef HAVE_ATA_DMA
597static int udmatimes[ATA_MAX_UDMA + 1] = {
598 0x4071152,
599 0x2050d52,
600#if ATA_MAX_UDMA >= 2
601 0x2030a52,
602#endif
603#if ATA_MAX_UDMA >= 3
604 0x1020a52,
605#endif
606#if ATA_MAX_UDMA >= 4
607 0x1010a52,
608#endif
609};
610static int mwdmatimes[ATA_MAX_MWDMA + 1] = {
611 0x1c175,
612 0x7083,
613 0x5072,
614};
615
616static int ata_get_best_mode(unsigned short identword, int max, int modetype)
617{
618 unsigned short testbit = BIT_N(max);
619
620 while (1) {
621 if (identword & testbit)
622 return max | modetype;
623 testbit >>= 1;
624 if (!testbit)
625 return 0;
626 max--;
627 }
628}
629#endif
630
552/* 631/*
553 * ATA_UDMA_TIME register is documented on s3c6400 datasheet, information 632 * ATA_UDMA_TIME register is documented on s3c6400 datasheet, information
554 * included in s5l8700 datasheet is wrong or not valid for s5l8702. 633 * included in s5l8700 datasheet is wrong or not valid for s5l8702.
@@ -573,10 +652,10 @@ static int ata_power_up(void)
573 ata_set_active(); 652 ata_set_active();
574 ide_power_enable(true); 653 ide_power_enable(true);
575 long spinup_start = current_tick; 654 long spinup_start = current_tick;
576 if (ceata) 655 if (ceata) {
577 {
578 ata_lba48 = true; 656 ata_lba48 = true;
579 ata_dma = true; 657 ata_dma = true;
658 dma_mode = 0xff; /* Canary */
580 PCON(8) = 0x33333333; 659 PCON(8) = 0x33333333;
581 PCON(9) = 0x00000033; 660 PCON(9) = 0x00000033;
582 PCON(11) |= 0xf; 661 PCON(11) |= 0xf;
@@ -596,11 +675,8 @@ static int ata_power_up(void)
596 SDCI_CDIV = SDCI_CDIV_CLKDIV(4); 675 SDCI_CDIV = SDCI_CDIV_CLKDIV(4);
597 sleep(HZ / 100); 676 sleep(HZ / 100);
598 PASS_RC(ceata_init(8), 3, 1); 677 PASS_RC(ceata_init(8), 3, 1);
599 PASS_RC(ata_identify(ata_identify_data), 3, 2); 678 PASS_RC(ata_identify(identify_info), 3, 2);
600 dma_mode = 0x44; 679 } else {
601 }
602 else
603 {
604 PCON(7) = 0x44444444; 680 PCON(7) = 0x44444444;
605 PCON(8) = 0x44444444; 681 PCON(8) = 0x44444444;
606 PCON(9) = 0x44444444; 682 PCON(9) = 0x44444444;
@@ -620,88 +696,71 @@ static int ata_power_up(void)
620 ATA_PIO_LHR = 0; 696 ATA_PIO_LHR = 0;
621 ATA_CFG = BIT(6); 697 ATA_CFG = BIT(6);
622 while (!(ATA_PIO_READY & BIT(1))) yield(); 698 while (!(ATA_PIO_READY & BIT(1))) yield();
623 PASS_RC(ata_identify(ata_identify_data), 3, 3); 699
624 uint32_t piotime = 0x11f3; 700 PASS_RC(ata_identify(identify_info), 3, 3);
625 uint32_t mdmatime = 0x1c175; 701
626 uint32_t udmatime = 0x4071152; 702 uint32_t piotime = 0x11f3; /* PIO0-2? */
627 uint32_t param = 0; 703 if (identify_info[53] & BIT(1)) /* Word 64..70 valid */
628 ata_dma_flags = 0;
629 ata_lba48 = ata_identify_data[83] & BIT(10) ? true : false;
630 if (ata_identify_data[53] & BIT(1))
631 {
632 if (ata_identify_data[64] & BIT(1)) piotime = 0x2072;
633 else if (ata_identify_data[64] & BIT(0)) piotime = 0x7083;
634 }
635 if (ata_identify_data[63] & BIT(2))
636 { 704 {
637 mdmatime = 0x5072; 705 if (identify_info[64] & BIT(1))
638 param = 0x22; 706 piotime = 0x2072; /* PIO mode 4 */
707 else if (identify_info[64] & BIT(0))
708 piotime = 0x7083; /* PIO mode 3 */
639 } 709 }
640 else if (ata_identify_data[63] & BIT(1)) 710 ATA_PIO_TIME = piotime;
711
712 uint32_t param = 0;
713 ata_dma_flags = 0;
714#ifdef HAVE_ATA_DMA
715 if ((identify_info[53] & BIT(2)) && (identify_info[88] & BITRANGE(0, 4))) /* Any UDMA */
641 { 716 {
642 mdmatime = 0x7083; 717 int max_udma = ATA_MAX_UDMA;
643 param = 0x21; 718#if ATA_MAX_UDMA > 2
719 if (!(identify_info[93] & BIT(13)))
720 max_udma = 2;
721#endif
722 param = ata_get_best_mode(identify_info[88], max_udma, 0x40);
723 ATA_UDMA_TIME = udmatimes[param & 0xf];
724 ata_dma_flags = BIT(2) | BIT(3) | BIT(9) | BIT(10);
644 } 725 }
645 if (ata_identify_data[63] & BITRANGE(0, 2)) 726 if (!param && identify_info[63] & BITRANGE(0, 2)) /* Fall back to any MWDMA */
646 { 727 {
728 param = ata_get_best_mode(identify_info[63], ATA_MAX_MWDMA, 0x20);
729 ATA_MDMA_TIME = mwdmatimes[param & 0xf];
647 ata_dma_flags = BIT(3) | BIT(10); 730 ata_dma_flags = BIT(3) | BIT(10);
648 param |= 0x20;
649 }
650 if (ata_identify_data[53] & BIT(2))
651 {
652 if (ata_identify_data[88] & BIT(4))
653 {
654 udmatime = 0x1010a52;
655 param = 0x44;
656 }
657 else if (ata_identify_data[88] & BIT(3))
658 {
659 udmatime = 0x1020a52;
660 param = 0x43;
661 }
662 else if (ata_identify_data[88] & BIT(2))
663 {
664 udmatime = 0x2030a52;
665 param = 0x42;
666 }
667 else if (ata_identify_data[88] & BIT(1))
668 {
669 udmatime = 0x2050d52;
670 param = 0x41;
671 }
672 else if (ata_identify_data[88] & BIT(0))
673 {
674 param = 0x40;
675 }
676 if (ata_identify_data[88] & BITRANGE(0, 4))
677 {
678 ata_dma_flags = BIT(2) | BIT(3) | BIT(9) | BIT(10);
679 }
680 } 731 }
732#endif /* HAVE_ATA_DMA */
681 ata_dma = param ? true : false; 733 ata_dma = param ? true : false;
682 dma_mode = param; 734 dma_mode = param;
683 PASS_RC(ata_set_feature(0x03, param), 3, 4); /* Transfer mode */ 735 PASS_RC(ata_set_feature(0x03, param), 3, 4); /* Transfer mode */
684 if (ata_identify_data[82] & BIT(5)) 736
737 /* SET_FEATURE only supported on PATA, not CE-ATA */
738 if (identify_info[82] & BIT(5))
685 PASS_RC(ata_set_feature(0x02, 0), 3, 5); /* Enable volatile write cache */ 739 PASS_RC(ata_set_feature(0x02, 0), 3, 5); /* Enable volatile write cache */
686 if (ata_identify_data[82] & BIT(6)) 740 if (identify_info[82] & BIT(6))
687 PASS_RC(ata_set_feature(0xaa, 0), 3, 6); /* Enable read lookahead */ 741 PASS_RC(ata_set_feature(0xaa, 0), 3, 6); /* Enable read lookahead */
688 if (ata_identify_data[83] & BIT(3)) 742 if (identify_info[83] & BIT(3))
689 PASS_RC(ata_set_feature(0x05, 0x80), 3, 7); /* Enable lowest power mode w/o standby */ 743 PASS_RC(ata_set_feature(0x05, 0x80), 3, 7); /* Enable lowest power mode w/o standby */
690 if (ata_identify_data[83] & BIT(9)) 744 if (identify_info[83] & BIT(9))
691 PASS_RC(ata_set_feature(0x42, 0x80), 3, 8); /* Enable lowest noise mode */ 745 PASS_RC(ata_set_feature(0x42, 0x80), 3, 8); /* Enable lowest noise mode */
692 ATA_PIO_TIME = piotime; 746
693 ATA_MDMA_TIME = mdmatime; 747 PASS_RC(ata_identify(identify_info), 3, 9); /* Finally, re-read identify info */
694 ATA_UDMA_TIME = udmatime;
695 } 748 }
749
696 spinup_time = current_tick - spinup_start; 750 spinup_time = current_tick - spinup_start;
697 if (ata_lba48) 751
698 ata_total_sectors = ata_identify_data[100] 752 ata_total_sectors = (identify_info[61] << 16) | identify_info[60];
699 | (((uint64_t)ata_identify_data[101]) << 16) 753 if ( identify_info[83] & BIT(10) && ata_total_sectors == 0x0FFFFFFF)
700 | (((uint64_t)ata_identify_data[102]) << 32) 754 {
701 | (((uint64_t)ata_identify_data[103]) << 48); 755 ata_total_sectors = ((uint64_t)identify_info[103] << 48) |
702 else 756 ((uint64_t)identify_info[102] << 32) |
703 ata_total_sectors = ata_identify_data[60] | (((uint32_t)ata_identify_data[61]) << 16); 757 ((uint64_t)identify_info[101] << 16) |
704 ata_total_sectors >>= 3; 758 identify_info[100];
759 ata_lba48 = true;
760 } else {
761 ata_lba48 = false;
762 }
763
705 ata_powered = true; 764 ata_powered = true;
706 ata_set_active(); 765 ata_set_active();
707 return 0; 766 return 0;
@@ -709,28 +768,8 @@ static int ata_power_up(void)
709 768
710static void ata_power_down(void) 769static void ata_power_down(void)
711{ 770{
712 if (!ata_powered) return; 771 if (!ata_powered)
713 if (ceata) 772 return;
714 {
715 memset(ceata_taskfile, 0, 16);
716 ceata_taskfile[0xf] = CMD_STANDBY_IMMEDIATE;
717 ceata_wait_idle();
718 ceata_write_multiple_register(0, ceata_taskfile, 16);
719 ceata_wait_idle();
720 sleep(HZ);
721 PWRCON(0) |= (1 << 9);
722 }
723 else
724 {
725 ata_wait_for_rdy(1000000);
726 ata_write_cbr(&ATA_PIO_DVR, 0);
727 ata_write_cbr(&ATA_PIO_CSD, CMD_STANDBY_IMMEDIATE);
728 ata_wait_for_rdy(1000000);
729 sleep(HZ / 30);
730 ATA_CONTROL = 0;
731 while (!(ATA_CONTROL & BIT(1))) yield();
732 PWRCON(0) |= (1 << 5);
733 }
734 PCON(7) = 0; 773 PCON(7) = 0;
735 PCON(8) = 0; 774 PCON(8) = 0;
736 PCON(9) = 0; 775 PCON(9) = 0;
@@ -745,18 +784,18 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo
745 if (ceata) 784 if (ceata)
746 { 785 {
747 memset(ceata_taskfile, 0, 16); 786 memset(ceata_taskfile, 0, 16);
748 ceata_taskfile[0x2] = cnt >> 5; 787 ceata_taskfile[0x2] = cnt >> 8;
749 ceata_taskfile[0x3] = sector >> 21; 788 ceata_taskfile[0x3] = sector >> 24;
750 ceata_taskfile[0x4] = sector >> 29; 789 ceata_taskfile[0x4] = sector >> 32;
751 ceata_taskfile[0x5] = sector >> 37; 790 ceata_taskfile[0x5] = sector >> 40;
752 ceata_taskfile[0xa] = cnt << 3; 791 ceata_taskfile[0xa] = cnt;
753 ceata_taskfile[0xb] = sector << 3; 792 ceata_taskfile[0xb] = sector;
754 ceata_taskfile[0xc] = sector >> 5; 793 ceata_taskfile[0xc] = sector >> 8;
755 ceata_taskfile[0xd] = sector >> 13; 794 ceata_taskfile[0xd] = sector >> 16;
756 ceata_taskfile[0xf] = write ? CMD_WRITE_DMA_EXT : CMD_READ_DMA_EXT; 795 ceata_taskfile[0xf] = write ? CMD_WRITE_DMA_EXT : CMD_READ_DMA_EXT;
757 PASS_RC(ceata_wait_idle(), 2, 0); 796 PASS_RC(ceata_wait_idle(), 2, 0);
758 PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1); 797 PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 2, 1);
759 PASS_RC(ceata_rw_multiple_block(write, buffer, cnt << 3, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 2, 2); 798 PASS_RC(ceata_rw_multiple_block(write, buffer, cnt, CEATA_COMMAND_TIMEOUT * HZ / 1000000), 2, 2);
760 } 799 }
761 else 800 else
762 { 801 {
@@ -764,14 +803,14 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo
764 ata_write_cbr(&ATA_PIO_DVR, 0); 803 ata_write_cbr(&ATA_PIO_DVR, 0);
765 if (ata_lba48) 804 if (ata_lba48)
766 { 805 {
767 ata_write_cbr(&ATA_PIO_SCR, cnt >> 5); 806 ata_write_cbr(&ATA_PIO_SCR, (cnt >> 8) & 0xff);
768 ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff); 807 ata_write_cbr(&ATA_PIO_SCR, (cnt) & 0xff);
769 ata_write_cbr(&ATA_PIO_LHR, (sector >> 37) & 0xff); 808 ata_write_cbr(&ATA_PIO_LHR, (sector >> 40) & 0xff);
770 ata_write_cbr(&ATA_PIO_LMR, (sector >> 29) & 0xff); 809 ata_write_cbr(&ATA_PIO_LMR, (sector >> 32) & 0xff);
771 ata_write_cbr(&ATA_PIO_LLR, (sector >> 21) & 0xff); 810 ata_write_cbr(&ATA_PIO_LLR, (sector >> 24) & 0xff);
772 ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff); 811 ata_write_cbr(&ATA_PIO_LHR, (sector >> 16) & 0xff);
773 ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff); 812 ata_write_cbr(&ATA_PIO_LMR, (sector >> 8) & 0xff);
774 ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff); 813 ata_write_cbr(&ATA_PIO_LLR, (sector) & 0xff);
775 ata_write_cbr(&ATA_PIO_DVR, BIT(6)); 814 ata_write_cbr(&ATA_PIO_DVR, BIT(6));
776 if (write) 815 if (write)
777 ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA_EXT : CMD_WRITE_MULTIPLE_EXT); 816 ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA_EXT : CMD_WRITE_MULTIPLE_EXT);
@@ -780,16 +819,17 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo
780 } 819 }
781 else 820 else
782 { 821 {
783 ata_write_cbr(&ATA_PIO_SCR, (cnt << 3) & 0xff); 822 ata_write_cbr(&ATA_PIO_SCR, (cnt) & 0xff);
784 ata_write_cbr(&ATA_PIO_LHR, (sector >> 13) & 0xff); 823 ata_write_cbr(&ATA_PIO_LHR, (sector >> 16) & 0xff);
785 ata_write_cbr(&ATA_PIO_LMR, (sector >> 5) & 0xff); 824 ata_write_cbr(&ATA_PIO_LMR, (sector >> 8) & 0xff);
786 ata_write_cbr(&ATA_PIO_LLR, (sector << 3) & 0xff); 825 ata_write_cbr(&ATA_PIO_LLR, (sector) & 0xff);
787 ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 21) & 0xf)); 826 ata_write_cbr(&ATA_PIO_DVR, BIT(6) | ((sector >> 24) & 0xf)); /* LBA28, mask off upper 4 bits of 32-bit sector address */
788 if (write) 827 if (write)
789 ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA : CMD_WRITE_SECTORS); 828 ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_WRITE_DMA : CMD_WRITE_SECTORS);
790 else 829 else
791 ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_READ_DMA : CMD_READ_MULTIPLE); 830 ata_write_cbr(&ATA_PIO_CSD, ata_dma ? CMD_READ_DMA : CMD_READ_MULTIPLE);
792 } 831 }
832#ifdef HAVE_ATA_DMA
793 if (ata_dma) 833 if (ata_dma)
794 { 834 {
795 PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1); 835 PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1);
@@ -812,8 +852,7 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo
812 ATA_IRQ = BITRANGE(0, 4); 852 ATA_IRQ = BITRANGE(0, 4);
813 ATA_IRQ_MASK = BIT(0); 853 ATA_IRQ_MASK = BIT(0);
814 ATA_COMMAND = BIT(0); 854 ATA_COMMAND = BIT(0);
815 if (semaphore_wait(&ata_wakeup, 500000 * HZ / 1000000) 855 if (semaphore_wait(&ata_wakeup, 500000 * HZ / 1000000) == OBJ_WAIT_TIMEDOUT)
816 == OBJ_WAIT_TIMEDOUT)
817 { 856 {
818 ATA_COMMAND = BIT(1); 857 ATA_COMMAND = BIT(1);
819 ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12)); 858 ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
@@ -823,19 +862,19 @@ static int ata_rw_chunk_internal(uint64_t sector, uint32_t cnt, void* buffer, bo
823 ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12)); 862 ATA_CFG &= ~(BITRANGE(2, 3) | BIT(12));
824 } 863 }
825 else 864 else
865#endif // HAVE_ATA_DMA
826 { 866 {
827 cnt *= SECTOR_SIZE / 512;
828 while (cnt--) 867 while (cnt--)
829 { 868 {
830 int i; 869 int i;
831 PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1); 870 PASS_RC(ata_wait_for_start_of_transfer(500000), 2, 1);
832 if (write) 871 if (write)
833 for (i = 0; i < 256; i++) 872 for (i = 0; i < SECTOR_SIZE/2; i++)
834 ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]); 873 ata_write_cbr(&ATA_PIO_DTR, ((uint16_t*)buffer)[i]);
835 else 874 else
836 for (i = 0; i < 256; i++) 875 for (i = 0; i < SECTOR_SIZE/2; i++)
837 ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR); 876 ((uint16_t*)buffer)[i] = ata_read_cbr(&ATA_PIO_DTR);
838 buffer += 512; 877 buffer += SECTOR_SIZE;
839 } 878 }
840 } 879 }
841 PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3); 880 PASS_RC(ata_wait_for_end_of_transfer(100000), 2, 3);
@@ -851,40 +890,27 @@ static int ata_rw_chunk(uint64_t sector, uint32_t cnt, void* buffer, bool write)
851 return rc; 890 return rc;
852} 891}
853 892
854static int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool write) 893static int ata_transfer_sectors(uint64_t sector, uint32_t count, void* buffer, bool write)
855{ 894{
856 if (STORAGE_OVERLAP((uint32_t)buffer)) 895 if (!ata_powered)
857 { 896 ata_power_up();
858 while (count) 897 if (sector + count > ata_total_sectors)
859 { 898 RET_ERR(0);
860 if (write)
861 memcpy(aligned_buffer, buffer, SECTOR_SIZE);
862
863 PASS_RC(ata_rw_sectors(sector, 1, aligned_buffer, write), 0, 0);
864
865 if (!write)
866 memcpy(buffer, aligned_buffer, SECTOR_SIZE);
867
868 buffer += SECTOR_SIZE;
869 sector++;
870 count--;
871 }
872
873 return 0;
874 }
875
876 if (!ata_powered) ata_power_up();
877 if (sector + count > ata_total_sectors) RET_ERR(0);
878 ata_set_active(); 899 ata_set_active();
879 if (ata_dma && write) commit_dcache(); 900 if (ata_dma && write)
880 else if (ata_dma) commit_discard_dcache(); 901 commit_dcache();
881 if (!ceata) ATA_COMMAND = BIT(1); 902 else if (ata_dma)
903 commit_discard_dcache();
904 if (!ceata)
905 ATA_COMMAND = BIT(1);
906
882 while (count) 907 while (count)
883 { 908 {
884 uint32_t cnt = MIN(ata_lba48 ? 8192 : 32, count); 909 uint32_t cnt = MIN(ata_lba48 ? 65536 : 256, count);
885 int rc = -1; 910 int rc = -1;
886 rc = ata_rw_chunk(sector, cnt, buffer, write); 911 rc = ata_rw_chunk(sector, cnt, buffer, write);
887 if (rc && ata_error_srst) ata_reset(); 912 if (rc && ata_error_srst)
913 ata_reset();
888 if (rc && ata_retries) 914 if (rc && ata_retries)
889 { 915 {
890 void* buf = buffer; 916 void* buf = buffer;
@@ -896,9 +922,11 @@ static int ata_rw_sectors(uint64_t sector, uint32_t count, void* buffer, bool wr
896 while (tries-- && rc) 922 while (tries-- && rc)
897 { 923 {
898 rc = ata_rw_chunk(sect, 1, buf, write); 924 rc = ata_rw_chunk(sect, 1, buf, write);
899 if (rc && ata_error_srst) ata_reset(); 925 if (rc && ata_error_srst)
926 ata_reset();
900 } 927 }
901 if (rc) break; 928 if (rc)
929 break;
902 buf += SECTOR_SIZE; 930 buf += SECTOR_SIZE;
903 } 931 }
904 } 932 }
@@ -916,9 +944,13 @@ int ata_soft_reset(void)
916{ 944{
917 int rc; 945 int rc;
918 mutex_lock(&ata_mutex); 946 mutex_lock(&ata_mutex);
919 if (!ata_powered) PASS_RC(ata_power_up(), 1, 0); 947 if (!ata_powered)
948 PASS_RC(ata_power_up(), 1, 0);
920 ata_set_active(); 949 ata_set_active();
921 if (ceata) rc = ceata_soft_reset(); 950 if (ceata)
951 {
952 rc = ceata_soft_reset();
953 }
922 else 954 else
923 { 955 {
924 ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2)); 956 ata_write_cbr(&ATA_PIO_DAD, BIT(1) | BIT(2));
@@ -945,7 +977,8 @@ static int ata_reset(void)
945{ 977{
946 int rc; 978 int rc;
947 mutex_lock(&ata_mutex); 979 mutex_lock(&ata_mutex);
948 if (!ata_powered) PASS_RC(ata_power_up(), 2, 0); 980 if (!ata_powered)
981 PASS_RC(ata_power_up(), 2, 0);
949 ata_set_active(); 982 ata_set_active();
950 rc = ata_soft_reset(); 983 rc = ata_soft_reset();
951 if (IS_ERR(rc)) 984 if (IS_ERR(rc))
@@ -957,7 +990,8 @@ static int ata_reset(void)
957 ata_power_down(); 990 ata_power_down();
958 sleep(HZ * 3); 991 sleep(HZ * 3);
959 int rc2 = ata_power_up(); 992 int rc2 = ata_power_up();
960 if (IS_ERR(rc2)) rc = ERR_RC((rc << 2) | 2); 993 if (IS_ERR(rc2))
994 rc = ERR_RC((rc << 2) | 2);
961 } 995 }
962 else rc = 1; 996 else rc = 1;
963 } 997 }
@@ -966,23 +1000,35 @@ static int ata_reset(void)
966 return rc; 1000 return rc;
967} 1001}
968 1002
969int ata_read_sectors(IF_MD(int drive,) unsigned long start, int incount, 1003#include "ata-common.c"
1004
1005#ifndef MAX_PHYS_SECTOR_SIZE
1006int ata_read_sectors(IF_MD(int drive,) sector_t start, int incount,
970 void* inbuf) 1007 void* inbuf)
971{ 1008{
1009#ifdef HAVE_MULTIDRIVE
1010 (void)drive; /* unused for now */
1011#endif
1012
972 mutex_lock(&ata_mutex); 1013 mutex_lock(&ata_mutex);
973 int rc = ata_rw_sectors(start, incount, inbuf, false); 1014 int rc = ata_transfer_sectors(start, incount, inbuf, false);
974 mutex_unlock(&ata_mutex); 1015 mutex_unlock(&ata_mutex);
975 return rc; 1016 return rc;
976} 1017}
977 1018
978int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, 1019int ata_write_sectors(IF_MD(int drive,) sector_t start, int count,
979 const void* outbuf) 1020 const void* outbuf)
980{ 1021{
1022#ifdef HAVE_MULTIDRIVE
1023 (void)drive; /* unused for now */
1024#endif
1025
981 mutex_lock(&ata_mutex); 1026 mutex_lock(&ata_mutex);
982 int rc = ata_rw_sectors(start, count, (void*)((uint32_t)outbuf), true); 1027 int rc = ata_transfer_sectors(start, count, (void*)((uint32_t)outbuf), true);
983 mutex_unlock(&ata_mutex); 1028 mutex_unlock(&ata_mutex);
984 return rc; 1029 return rc;
985} 1030}
1031#endif /* ndef MAX_PHYS_SECTOR_SIZE */
986 1032
987void ata_spindown(int seconds) 1033void ata_spindown(int seconds)
988{ 1034{
@@ -993,26 +1039,27 @@ static void ata_flush_cache(void)
993{ 1039{
994 uint8_t cmd; 1040 uint8_t cmd;
995 1041
996 if (ata_identify_data[83] & BIT(13)) { 1042 if (ceata) {
997 cmd = CMD_FLUSH_CACHE_EXT;
998 } else if (ata_identify_data[83] & BIT(12)) {
999 cmd = CMD_FLUSH_CACHE;
1000 } else {
1001 /* If neither (mandatory!) command is supported
1002 then don't issue it. */
1003 return;
1004 }
1005
1006 if (ceata)
1007 {
1008 memset(ceata_taskfile, 0, 16); 1043 memset(ceata_taskfile, 0, 16);
1009 ceata_taskfile[0xf] = cmd; 1044 ceata_taskfile[0xf] = CMD_FLUSH_CACHE_EXT; /* CE-ATA only supports EXT */
1010 ceata_wait_idle(); 1045 ceata_wait_idle();
1011 ceata_write_multiple_register(0, ceata_taskfile, 16); 1046 ceata_write_multiple_register(0, ceata_taskfile, 16);
1012 ceata_wait_idle(); 1047 ceata_wait_idle();
1013 } 1048 } else {
1014 else 1049 if (!canflush) {
1015 { 1050 return;
1051 } else if (ata_lba48 && identify_info[83] & BIT(13)) {
1052 cmd = CMD_FLUSH_CACHE_EXT; /* Flag, optional, ATA-6 and up, for use with LBA48 devices. Mandatory for CE-ATA */
1053 } else if (identify_info[83] & BIT(12)) {
1054 cmd = CMD_FLUSH_CACHE; /* Flag, mandatory, ATA-6 and up */
1055 } else if (identify_info[80] >= BIT(5)) { /* Use >= instead of '&' because bits lower than the latest standard we support don't have to be set */
1056 cmd = CMD_FLUSH_CACHE; /* No flag, mandatory, ATA-5 (Optional for ATA-4) */
1057 } else {
1058 /* If neither command is supported then don't issue it. */
1059 canflush = 0;
1060 return;
1061 }
1062
1016 ata_wait_for_rdy(1000000); 1063 ata_wait_for_rdy(1000000);
1017 ata_write_cbr(&ATA_PIO_DVR, 0); 1064 ata_write_cbr(&ATA_PIO_DVR, 0);
1018 ata_write_cbr(&ATA_PIO_CSD, cmd); 1065 ata_write_cbr(&ATA_PIO_CSD, cmd);
@@ -1020,14 +1067,46 @@ static void ata_flush_cache(void)
1020 } 1067 }
1021} 1068}
1022 1069
1070int ata_flush(void)
1071{
1072 if (ata_powered) {
1073 mutex_lock(&ata_mutex);
1074 ata_flush_cache();
1075 mutex_unlock(&ata_mutex);
1076 }
1077 return 0;
1078}
1079
1023void ata_sleepnow(void) 1080void ata_sleepnow(void)
1024{ 1081{
1025 mutex_lock(&ata_mutex); 1082 mutex_lock(&ata_mutex);
1026 1083
1027 if (ata_disk_can_poweroff()) 1084 ata_flush_cache();
1028 ata_power_down(); 1085
1029 else 1086 if (ata_disk_can_sleep()) {
1030 ata_flush_cache(); 1087 if (ceata) {
1088 memset(ceata_taskfile, 0, 16);
1089 ceata_taskfile[0xf] = CMD_STANDBY_IMMEDIATE;
1090 ceata_wait_idle();
1091 ceata_write_multiple_register(0, ceata_taskfile, 16);
1092 ceata_wait_idle();
1093 sleep(HZ);
1094 PWRCON(0) |= (1 << 9);
1095 } else {
1096 ata_wait_for_rdy(1000000);
1097 ata_write_cbr(&ATA_PIO_DVR, 0);
1098 ata_write_cbr(&ATA_PIO_CSD, CMD_STANDBY_IMMEDIATE);
1099 ata_wait_for_rdy(1000000);
1100 sleep(HZ / 30);
1101 ATA_CONTROL = 0;
1102 while (!(ATA_CONTROL & BIT(1)))
1103 yield();
1104 PWRCON(0) |= (1 << 5);
1105 }
1106 }
1107
1108 if (ata_disk_can_sleep() || canflush)
1109 ata_power_down(); // XXX add a powerdown delay similar to main ATA driver?
1031 1110
1032 mutex_unlock(&ata_mutex); 1111 mutex_unlock(&ata_mutex);
1033} 1112}
@@ -1037,14 +1116,21 @@ void ata_spin(void)
1037 ata_set_active(); 1116 ata_set_active();
1038} 1117}
1039 1118
1119#ifdef STORAGE_GET_INFO
1040void ata_get_info(IF_MD(int drive,) struct storage_info *info) 1120void ata_get_info(IF_MD(int drive,) struct storage_info *info)
1041{ 1121{
1042 (*info).sector_size = SECTOR_SIZE; 1122 /* Logical sector size */
1123 if ((identify_info[106] & 0xd000) == 0x5000) /* B14, B12 */
1124 info->sector_size = (identify_info[117] | (identify_info[118] << 16)) * 2;
1125 else
1126 info->sector_size = SECTOR_SIZE;
1127
1043 (*info).num_sectors = ata_total_sectors; 1128 (*info).num_sectors = ata_total_sectors;
1044 (*info).vendor = "Apple"; 1129 (*info).vendor = "Apple";
1045 (*info).product = "iPod Classic"; 1130 (*info).product = "iPod Classic";
1046 (*info).revision = "1.0"; 1131 (*info).revision = "1.0";
1047} 1132}
1133#endif
1048 1134
1049long ata_last_disk_activity(void) 1135long ata_last_disk_activity(void)
1050{ 1136{
@@ -1061,11 +1147,18 @@ int ata_init(void)
1061 ata_powered = false; 1147 ata_powered = false;
1062 ata_total_sectors = 0; 1148 ata_total_sectors = 0;
1063 1149
1064 /* get ata_identify_data */ 1150 /* get identify_info */
1065 mutex_lock(&ata_mutex); 1151 mutex_lock(&ata_mutex);
1066 int rc = ata_power_up(); 1152 int rc = ata_power_up();
1067 mutex_unlock(&ata_mutex); 1153 mutex_unlock(&ata_mutex);
1068 if (IS_ERR(rc)) return rc; 1154 if (IS_ERR(rc))
1155 return rc;
1156
1157#ifdef MAX_PHYS_SECTOR_SIZE
1158 rc = ata_get_phys_sector_mult();
1159 if (IS_ERR(rc))
1160 return rc;
1161#endif
1069 1162
1070 return 0; 1163 return 0;
1071} 1164}
@@ -1082,7 +1175,7 @@ static int ata_smart(uint16_t* buf)
1082 ceata_taskfile[0xe] = BIT(6); 1175 ceata_taskfile[0xe] = BIT(6);
1083 ceata_taskfile[0xf] = CMD_SMART; 1176 ceata_taskfile[0xf] = CMD_SMART;
1084 PASS_RC(ceata_wait_idle(), 3, 1); 1177 PASS_RC(ceata_wait_idle(), 3, 1);
1085 if (((uint8_t*)ata_identify_data)[54] != 'A') /* Model != aAmsung */ 1178 if (((uint8_t*)identify_info)[54] != 'A') /* Model != aAmsung */
1086 { 1179 {
1087 ceata_taskfile[0x9] = 0xd8; /* SMART enable operations */ 1180 ceata_taskfile[0x9] = 0xd8; /* SMART enable operations */
1088 PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 3, 2); 1181 PASS_RC(ceata_write_multiple_register(0, ceata_taskfile, 16), 3, 2);
@@ -1102,7 +1195,8 @@ static int ata_smart(uint16_t* buf)
1102 ata_write_cbr(&ATA_PIO_DVR, BIT(6)); 1195 ata_write_cbr(&ATA_PIO_DVR, BIT(6));
1103 ata_write_cbr(&ATA_PIO_CSD, CMD_SMART); 1196 ata_write_cbr(&ATA_PIO_CSD, CMD_SMART);
1104 PASS_RC(ata_wait_for_start_of_transfer(10000000), 3, 7); 1197 PASS_RC(ata_wait_for_start_of_transfer(10000000), 3, 7);
1105 for (i = 0; i < 0x100; i++) buf[i] = ata_read_cbr(&ATA_PIO_DTR); 1198 for (i = 0; i < 0x100; i++)
1199 buf[i] = ata_read_cbr(&ATA_PIO_DTR);
1106 } 1200 }
1107 ata_set_active(); 1201 ata_set_active();
1108 return 0; 1202 return 0;
@@ -1129,7 +1223,7 @@ static int ata_num_drives(int first_drive)
1129 1223
1130unsigned short* ata_get_identify(void) 1224unsigned short* ata_get_identify(void)
1131{ 1225{
1132 return ata_identify_data; 1226 return identify_info;
1133} 1227}
1134 1228
1135int ata_spinup_time(void) 1229int ata_spinup_time(void)
@@ -1137,24 +1231,29 @@ int ata_spinup_time(void)
1137 return spinup_time; 1231 return spinup_time;
1138} 1232}
1139 1233
1234#ifdef HAVE_ATA_DMA
1140int ata_get_dma_mode(void) 1235int ata_get_dma_mode(void)
1141{ 1236{
1142 return dma_mode; 1237 return dma_mode;
1143} 1238}
1239#endif
1144 1240
1145void INT_ATA(void) 1241void INT_ATA(void)
1146{ 1242{
1147 uint32_t ata_irq = ATA_IRQ; 1243 uint32_t ata_irq = ATA_IRQ;
1148 ATA_IRQ = ata_irq; 1244 ATA_IRQ = ata_irq;
1149 if (ata_irq & ATA_IRQ_MASK) semaphore_release(&ata_wakeup); 1245 if (ata_irq & ATA_IRQ_MASK)
1246 semaphore_release(&ata_wakeup);
1150 ATA_IRQ_MASK = 0; 1247 ATA_IRQ_MASK = 0;
1151} 1248}
1152 1249
1153void INT_MMC(void) 1250void INT_MMC(void)
1154{ 1251{
1155 uint32_t irq = SDCI_IRQ; 1252 uint32_t irq = SDCI_IRQ;
1156 if (irq & SDCI_IRQ_DAT_DONE_INT) semaphore_release(&mmc_wakeup); 1253 if (irq & SDCI_IRQ_DAT_DONE_INT)
1157 if (irq & SDCI_IRQ_IOCARD_IRQ_INT) semaphore_release(&mmc_comp_wakeup); 1254 semaphore_release(&mmc_wakeup);
1255 if (irq & SDCI_IRQ_IOCARD_IRQ_INT)
1256 semaphore_release(&mmc_comp_wakeup);
1158 SDCI_IRQ = irq; 1257 SDCI_IRQ = irq;
1159} 1258}
1160 1259
diff --git a/firmware/target/arm/tcc780x/sd-tcc780x.c b/firmware/target/arm/tcc780x/sd-tcc780x.c
index c80c3b746f..3ef8972ee9 100644
--- a/firmware/target/arm/tcc780x/sd-tcc780x.c
+++ b/firmware/target/arm/tcc780x/sd-tcc780x.c
@@ -104,19 +104,19 @@ static bool sd_poll_status(unsigned int trigger, long timeout)
104 return true; 104 return true;
105} 105}
106 106
107static int sd_command(unsigned int cmd, unsigned int arg, 107static int sd_command(unsigned int cmd, unsigned int arg,
108 unsigned long* response, unsigned int resp_type) 108 unsigned long* response, unsigned int resp_type)
109{ 109{
110 int sdi_cmd = cmd; 110 int sdi_cmd = cmd;
111 111
112 sdi_cmd |= (127<<12) | (1<<11); /* max wait time | enable */ 112 sdi_cmd |= (127<<12) | (1<<11); /* max wait time | enable */
113 113
114 if (resp_type) 114 if (resp_type)
115 { 115 {
116 /* response type & response required flag */ 116 /* response type & response required flag */
117 sdi_cmd |= (resp_type<<7) | (1<<6); 117 sdi_cmd |= (resp_type<<7) | (1<<6);
118 } 118 }
119 119
120 if (cmd == SD_READ_SINGLE_BLOCK || 120 if (cmd == SD_READ_SINGLE_BLOCK ||
121 cmd == SD_READ_MULTIPLE_BLOCK || 121 cmd == SD_READ_MULTIPLE_BLOCK ||
122 cmd == SD_WRITE_BLOCK || 122 cmd == SD_WRITE_BLOCK ||
@@ -124,18 +124,18 @@ static int sd_command(unsigned int cmd, unsigned int arg,
124 { 124 {
125 sdi_cmd |= (1<<10); /* request data transfer */ 125 sdi_cmd |= (1<<10); /* request data transfer */
126 } 126 }
127 127
128 if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000)) 128 if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000))
129 return -EC_COMMAND; 129 return -EC_COMMAND;
130 130
131 SDIARGU = arg; 131 SDIARGU = arg;
132 SDICMD = sdi_cmd; 132 SDICMD = sdi_cmd;
133 133
134 udelay(10); 134 udelay(10);
135 135
136 if (response == NULL) 136 if (response == NULL)
137 return 0; 137 return 0;
138 138
139 if (!sd_poll_status(SDISTATUS_RESP_RCVD, 100000)) 139 if (!sd_poll_status(SDISTATUS_RESP_RCVD, 100000))
140 return -EC_COMMAND; 140 return -EC_COMMAND;
141 141
@@ -150,7 +150,7 @@ static int sd_command(unsigned int cmd, unsigned int arg,
150 { 150 {
151 response[0] = SDIRSPARGU0; 151 response[0] = SDIRSPARGU0;
152 } 152 }
153 153
154 return 0; 154 return 0;
155} 155}
156 156
@@ -220,7 +220,7 @@ static int sd1_oneshot_callback(struct timeout *tmo)
220void EXT0(void) 220void EXT0(void)
221{ 221{
222 static struct timeout sd1_oneshot; 222 static struct timeout sd1_oneshot;
223 223
224 timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0); 224 timeout_register(&sd1_oneshot, sd1_oneshot_callback, (3*HZ/10), 0);
225} 225}
226 226
@@ -248,7 +248,7 @@ bool sd_removable(IF_MD_NONVOID(int card_no))
248 const int card_no = 0; 248 const int card_no = 0;
249#endif 249#endif
250 (void)card_no; 250 (void)card_no;
251 251
252 return false; 252 return false;
253} 253}
254 254
@@ -259,7 +259,7 @@ static void sd_init_device(int card_no)
259{ 259{
260 int ret; 260 int ret;
261 unsigned long response; 261 unsigned long response;
262 262
263 /* Initialise card data as blank */ 263 /* Initialise card data as blank */
264 memset(currcard, 0, sizeof(*currcard)); 264 memset(currcard, 0, sizeof(*currcard));
265 265
@@ -282,7 +282,7 @@ static void sd_init_device(int card_no)
282#endif 282#endif
283 283
284 ret = sd_command(SD_GO_IDLE_STATE, 0, NULL, SDICMD_RES_TYPE1); 284 ret = sd_command(SD_GO_IDLE_STATE, 0, NULL, SDICMD_RES_TYPE1);
285 285
286 if (ret < 0) 286 if (ret < 0)
287 goto card_init_error; 287 goto card_init_error;
288 288
@@ -290,30 +290,30 @@ static void sd_init_device(int card_no)
290 SDICLK = (1<<12) | 59; 290 SDICLK = (1<<12) | 59;
291 291
292 sd_command(SD_SEND_IF_COND, 0x1aa, &response, SDICMD_RES_TYPE3); 292 sd_command(SD_SEND_IF_COND, 0x1aa, &response, SDICMD_RES_TYPE3);
293 293
294 if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000)) 294 if (!sd_poll_status(SDISTATUS_CMD_PATH_RDY, 100000))
295 goto card_init_error; 295 goto card_init_error;
296 296
297 currcard->ocr = 0; 297 currcard->ocr = 0;
298 298
299 long start_tick = current_tick; 299 long start_tick = current_tick;
300 300
301 while ((currcard->ocr & (1<<31)) == 0 301 while ((currcard->ocr & (1<<31)) == 0
302 && TIME_BEFORE(current_tick, start_tick + HZ)) 302 && TIME_BEFORE(current_tick, start_tick + HZ))
303 { 303 {
304 udelay(100); 304 udelay(100);
305 sd_command(SD_APP_CMD, 0, NULL, SDICMD_RES_TYPE1); 305 sd_command(SD_APP_CMD, 0, NULL, SDICMD_RES_TYPE1);
306 306
307 int arg = 0x100000 | ((response == 0x1aa) ? (1<<30):0); 307 int arg = 0x100000 | ((response == 0x1aa) ? (1<<30):0);
308 sd_command(SD_APP_OP_COND, arg, &currcard->ocr, SDICMD_RES_TYPE3); 308 sd_command(SD_APP_OP_COND, arg, &currcard->ocr, SDICMD_RES_TYPE3);
309 } 309 }
310 310
311 if ((currcard->ocr & (1<<31)) == 0) 311 if ((currcard->ocr & (1<<31)) == 0)
312 { 312 {
313 ret = -EC_POWER_UP; 313 ret = -EC_POWER_UP;
314 goto card_init_error; 314 goto card_init_error;
315 } 315 }
316 316
317 ret = sd_command 317 ret = sd_command
318 (SD_ALL_SEND_CID, 0, currcard->cid, SDICMD_RES_TYPE2); 318 (SD_ALL_SEND_CID, 0, currcard->cid, SDICMD_RES_TYPE2);
319 319
@@ -322,39 +322,39 @@ static void sd_init_device(int card_no)
322 322
323 ret = sd_command 323 ret = sd_command
324 (SD_SEND_RELATIVE_ADDR, 0, &currcard->rca, SDICMD_RES_TYPE1); 324 (SD_SEND_RELATIVE_ADDR, 0, &currcard->rca, SDICMD_RES_TYPE1);
325 325
326 if (ret < 0) 326 if (ret < 0)
327 goto card_init_error; 327 goto card_init_error;
328 328
329 ret = sd_command 329 ret = sd_command
330 (SD_SEND_CSD, currcard->rca, currcard->csd, SDICMD_RES_TYPE2); 330 (SD_SEND_CSD, currcard->rca, currcard->csd, SDICMD_RES_TYPE2);
331 331
332 if (ret < 0) 332 if (ret < 0)
333 goto card_init_error; 333 goto card_init_error;
334 334
335 sd_parse_csd(currcard); 335 sd_parse_csd(currcard);
336 336
337 ret = sd_command 337 ret = sd_command
338 (SD_SELECT_CARD, currcard->rca, NULL, SDICMD_RES_TYPE1); 338 (SD_SELECT_CARD, currcard->rca, NULL, SDICMD_RES_TYPE1);
339 339
340 if (ret < 0) 340 if (ret < 0)
341 goto card_init_error; 341 goto card_init_error;
342 342
343 ret = sd_command 343 ret = sd_command
344 (SD_APP_CMD, currcard->rca, NULL, SDICMD_RES_TYPE1); 344 (SD_APP_CMD, currcard->rca, NULL, SDICMD_RES_TYPE1);
345 345
346 if (ret < 0) 346 if (ret < 0)
347 goto card_init_error; 347 goto card_init_error;
348 348
349 ret = sd_command /* 4 bit */ 349 ret = sd_command /* 4 bit */
350 (SD_SET_BUS_WIDTH, currcard->rca | 2, NULL, SDICMD_RES_TYPE1); 350 (SD_SET_BUS_WIDTH, currcard->rca | 2, NULL, SDICMD_RES_TYPE1);
351 351
352 if (ret < 0) 352 if (ret < 0)
353 goto card_init_error; 353 goto card_init_error;
354 354
355 ret = sd_command 355 ret = sd_command
356 (SD_SET_BLOCKLEN, currcard->blocksize, NULL, SDICMD_RES_TYPE1); 356 (SD_SET_BLOCKLEN, currcard->blocksize, NULL, SDICMD_RES_TYPE1);
357 357
358 if (ret < 0) 358 if (ret < 0)
359 goto card_init_error; 359 goto card_init_error;
360 360
@@ -386,7 +386,7 @@ static void sd_select_device(int card_no)
386 } 386 }
387} 387}
388 388
389int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount, 389int sd_read_sectors(IF_MD(int card_no,) sector_t start, int incount,
390 void* inbuf) 390 void* inbuf)
391{ 391{
392#ifndef HAVE_MULTIDRIVE 392#ifndef HAVE_MULTIDRIVE
@@ -416,23 +416,24 @@ sd_read_retry:
416 ret = currcard->initialized; 416 ret = currcard->initialized;
417 goto sd_read_error; 417 goto sd_read_error;
418 } 418 }
419 419
420 last_disk_activity = current_tick; 420 last_disk_activity = current_tick;
421 421
422 ret = sd_wait_for_state(SD_TRAN, EC_TRAN_READ_ENTRY); 422 ret = sd_wait_for_state(SD_TRAN, EC_TRAN_READ_ENTRY);
423 423
424 if (ret < 0) 424 if (ret < 0)
425 goto sd_read_error; 425 goto sd_read_error;
426 426
427 /* Use full SD clock for data transfer (PCK_SDMMC) */ 427 /* Use full SD clock for data transfer (PCK_SDMMC) */
428 SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */ 428 SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */
429 429
430 /* Block count | FIFO count | Block size (2^9) | 4-bit bus */ 430 /* Block count | FIFO count | Block size (2^9) | 4-bit bus */
431 SDIDCTRL = (incount << 13) | (4<<8) | (9<<4) | (1<<2); 431 SDIDCTRL = (incount << 13) | (4<<8) | (9<<4) | (1<<2);
432 SDIDCTRL |= (1<<12); /* nReset */ 432 SDIDCTRL |= (1<<12); /* nReset */
433 433
434 SDIDCTRL2 = (1<<2); /* multi block, read */ 434 SDIDCTRL2 = (1<<2); /* multi block, read */
435 435
436 // XXX 64-bit
436 if (currcard->ocr & (1<<30)) 437 if (currcard->ocr & (1<<30))
437 ret = sd_command(SD_READ_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1); 438 ret = sd_command(SD_READ_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1);
438 else 439 else
@@ -500,7 +501,7 @@ sd_read_error:
500 } 501 }
501} 502}
502 503
503int sd_write_sectors(IF_MD(int card_no,) unsigned long start, int count, 504int sd_write_sectors(IF_MD(int card_no,) sector_t start, int count,
504 const void* outbuf) 505 const void* outbuf)
505{ 506{
506/* Write support is not finished yet */ 507/* Write support is not finished yet */
@@ -538,21 +539,22 @@ sd_write_retry:
538 ret = currcard->initialized; 539 ret = currcard->initialized;
539 goto sd_write_error; 540 goto sd_write_error;
540 } 541 }
541 542
542 ret = sd_wait_for_state(SD_TRAN, EC_TRAN_WRITE_ENTRY); 543 ret = sd_wait_for_state(SD_TRAN, EC_TRAN_WRITE_ENTRY);
543 544
544 if (ret < 0) 545 if (ret < 0)
545 goto sd_write_error; 546 goto sd_write_error;
546 547
547 /* Use full SD clock for data transfer (PCK_SDMMC) */ 548 /* Use full SD clock for data transfer (PCK_SDMMC) */
548 SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */ 549 SDICLK = (1<<13) | (1<<12); /* bypass divider | enable */
549 550
550 /* Block count | FIFO count | Block size (2^9) | 4-bit bus */ 551 /* Block count | FIFO count | Block size (2^9) | 4-bit bus */
551 SDIDCTRL = (count<<13) | (4<<8) | (9<<4) | (1<<2); 552 SDIDCTRL = (count<<13) | (4<<8) | (9<<4) | (1<<2);
552 SDIDCTRL |= (1<<12); /* nReset */ 553 SDIDCTRL |= (1<<12); /* nReset */
553 554
554 SDIDCTRL2 = (1<<2) | (1<<1); /* multi block, write */ 555 SDIDCTRL2 = (1<<2) | (1<<1); /* multi block, write */
555 556
557 // XXX 64-bit
556 if (currcard->ocr & (1<<30)) 558 if (currcard->ocr & (1<<30))
557 ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1); 559 ret = sd_command(SD_WRITE_MULTIPLE_BLOCK, start, NULL, SDICMD_RES_TYPE1);
558 else 560 else
@@ -578,7 +580,7 @@ sd_write_retry:
578 else 580 else
579 { 581 {
580 int tmp_buf[4]; 582 int tmp_buf[4];
581 583
582 memcpy(tmp_buf, outbuf, 16); 584 memcpy(tmp_buf, outbuf, 16);
583 585
584 SDIWDATA = tmp_buf[0]; 586 SDIWDATA = tmp_buf[0];
@@ -646,12 +648,12 @@ void sd_enable(bool on)
646 PCLK_SDMMC &= ~PCK_EN; 648 PCLK_SDMMC &= ~PCK_EN;
647 } 649 }
648} 650}
649 651
650int sd_init(void) 652int sd_init(void)
651{ 653{
652 static bool initialized = false; 654 static bool initialized = false;
653 int ret = 0; 655 int ret = 0;
654 656
655 if (!initialized) 657 if (!initialized)
656 mutex_init(&sd_mtx); 658 mutex_init(&sd_mtx);
657 659
@@ -678,7 +680,7 @@ int sd_init(void)
678 GPIOC_DIR |= (1<<24); 680 GPIOC_DIR |= (1<<24);
679 681
680 sleep(HZ/10); 682 sleep(HZ/10);
681 683
682#ifdef HAVE_HOTSWAP 684#ifdef HAVE_HOTSWAP
683 /* Configure interrupts for the card slot */ 685 /* Configure interrupts for the card slot */
684 TMODE &= ~EXT0_IRQ_MASK; /* edge-triggered */ 686 TMODE &= ~EXT0_IRQ_MASK; /* edge-triggered */
@@ -696,7 +698,7 @@ long sd_last_disk_activity(void)
696} 698}
697 699
698tCardInfo *card_get_info_target(int card_no) 700tCardInfo *card_get_info_target(int card_no)
699{ 701{
700 return &card_info[card_no]; 702 return &card_info[card_no];
701} 703}
702 704
@@ -706,7 +708,7 @@ int sd_num_drives(int first_drive)
706{ 708{
707 /* Store which logical drive number(s) we have been assigned */ 709 /* Store which logical drive number(s) we have been assigned */
708 sd_first_drive = first_drive; 710 sd_first_drive = first_drive;
709 711
710#if defined(HAVE_INTERNAL_SD) && defined(HAVE_HOTSWAP) 712#if defined(HAVE_INTERNAL_SD) && defined(HAVE_HOTSWAP)
711 return 2; 713 return 2;
712#else 714#else
diff --git a/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c b/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c
index a1985472a0..76929e603e 100644
--- a/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c
+++ b/firmware/target/arm/tms320dm320/creative-zvm/ata-creativezvm.c
@@ -126,8 +126,10 @@ void GIO2(void)
126 126
127#define VFAT_SECTOR_SIZE(x) ( (x)/0x8000 ) /* 1GB array requires 80kB of RAM */ 127#define VFAT_SECTOR_SIZE(x) ( (x)/0x8000 ) /* 1GB array requires 80kB of RAM */
128 128
129extern int ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); 129extern int ata_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
130extern int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); 130extern int ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
131
132// XXX 64-bit: Due to this it's not likely that this target will ever handle 64-bit storage.
131 133
132struct main_header 134struct main_header
133{ 135{
@@ -253,9 +255,9 @@ static void cfs_init(void)
253 /* Read root inode */ 255 /* Read root inode */
254 _ata_read_sectors(CFS_CLUSTER2CLUSTER(cfs->first_inode), 64, &sector2); 256 _ata_read_sectors(CFS_CLUSTER2CLUSTER(cfs->first_inode), 64, &sector2);
255 root_inode = (struct cfs_inode*)&sector2; 257 root_inode = (struct cfs_inode*)&sector2;
256 258
257 logf("Root inode = 0x%x", root_inode); 259 logf("Root inode = 0x%x", root_inode);
258 260
259 logf("0x%x 0x%x", CFS_CLUSTER2CLUSTER(root_inode->first_class_chain[0]), root_inode->first_class_chain[0]); 261 logf("0x%x 0x%x", CFS_CLUSTER2CLUSTER(root_inode->first_class_chain[0]), root_inode->first_class_chain[0]);
260 262
261 /* Read root inode's first sector */ 263 /* Read root inode's first sector */
@@ -277,9 +279,9 @@ static void cfs_init(void)
277 vfat_inode_nr = root_direntry_items[i].inode_number; 279 vfat_inode_nr = root_direntry_items[i].inode_number;
278 } 280 }
279 } 281 }
280 282
281 logf("VFAT inode = 0x%x", vfat_inode_nr); 283 logf("VFAT inode = 0x%x", vfat_inode_nr);
282 284
283 if(vfat_inode_nr != 0) 285 if(vfat_inode_nr != 0)
284 { 286 {
285 /* Read VFAT inode */ 287 /* Read VFAT inode */
@@ -384,19 +386,19 @@ static void cfs_init(void)
384 cfs_inited = true; 386 cfs_inited = true;
385} 387}
386 388
387static inline unsigned long map_sector(unsigned long sector) 389static inline sector_t map_sector(sector_t sector)
388{ 390{
389 /* 391 /*
390 * Sector mapping: start of CFS + FAT_SECTOR2CFS_SECTOR(sector) + missing part 392 * Sector mapping: start of CFS + FAT_SECTOR2CFS_SECTOR(sector) + missing part
391 * FAT works with sectors of 0x200 bytes, CFS with sectors of 0x8000 bytes. 393 * FAT works with sectors of 0x200 bytes, CFS with sectors of 0x8000 bytes.
392 */ 394 */
393#ifndef BOOTLOADER 395#ifndef BOOTLOADER
394 unsigned long *sectors = core_get_data(sectors_handle); 396 sector_t *sectors = core_get_data(sectors_handle);
395#endif 397#endif
396 return cfs_start+sectors[sector/64]*64+sector%64; 398 return cfs_start+sectors[sector/64]*64+sector%64;
397} 399}
398 400
399int ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) 401int ata_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf)
400{ 402{
401 if(!cfs_inited) 403 if(!cfs_inited)
402 cfs_init(); 404 cfs_init();
@@ -423,7 +425,7 @@ int ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf
423 } 425 }
424} 426}
425 427
426int ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf) 428int ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf)
427{ 429{
428 if(!cfs_inited) 430 if(!cfs_inited)
429 cfs_init(); 431 cfs_init();
diff --git a/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h b/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h
index d0aa12e040..41b8e73ad4 100644
--- a/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h
+++ b/firmware/target/arm/tms320dm320/creative-zvm/ata-target.h
@@ -36,8 +36,8 @@
36/* Nasty hack, but Creative is nasty... */ 36/* Nasty hack, but Creative is nasty... */
37#define ata_read_sectors _ata_read_sectors 37#define ata_read_sectors _ata_read_sectors
38#define ata_write_sectors _ata_write_sectors 38#define ata_write_sectors _ata_write_sectors
39extern int _ata_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf); 39extern int _ata_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf);
40extern int _ata_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf); 40extern int _ata_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf);
41 41
42/* General purpose memory region #1 */ 42/* General purpose memory region #1 */
43#define ATA_IOBASE 0x50FEE000 43#define ATA_IOBASE 0x50FEE000
diff --git a/firmware/target/arm/tms320dm320/sdmmc-dm320.c b/firmware/target/arm/tms320dm320/sdmmc-dm320.c
index e66a4cb3c7..17cb239374 100644
--- a/firmware/target/arm/tms320dm320/sdmmc-dm320.c
+++ b/firmware/target/arm/tms320dm320/sdmmc-dm320.c
@@ -18,7 +18,7 @@
18 * KIND, either express or implied. 18 * KIND, either express or implied.
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#include "system.h" 22#include "system.h"
23#include <string.h> 23#include <string.h>
24#include "gcc_extensions.h" 24#include "gcc_extensions.h"
@@ -97,7 +97,7 @@ struct sd_card_status
97 int retry_max; 97 int retry_max;
98}; 98};
99 99
100/** static, private data **/ 100/** static, private data **/
101 101
102/* for compatibility */ 102/* for compatibility */
103static long last_disk_activity = -1; 103static long last_disk_activity = -1;
@@ -123,7 +123,7 @@ static struct mutex sd_mtx SHAREDBSS_ATTR;
123static struct semaphore data_done SHAREDBSS_ATTR; 123static struct semaphore data_done SHAREDBSS_ATTR;
124static volatile unsigned int transfer_error[NUM_DRIVES]; 124static volatile unsigned int transfer_error[NUM_DRIVES];
125/* align on cache line size */ 125/* align on cache line size */
126static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE] 126static unsigned char aligned_buffer[UNALIGNED_NUM_SECTORS * SD_BLOCK_SIZE]
127 __attribute__((aligned(32))); 127 __attribute__((aligned(32)));
128 128
129static void sd_card_mux(int card_no) 129static void sd_card_mux(int card_no)
@@ -397,7 +397,7 @@ static int sd_init_card(const int card_no)
397 SDHC_RESP_FMT_1, &currcard->rca); 397 SDHC_RESP_FMT_1, &currcard->rca);
398 if (ret < 0) 398 if (ret < 0)
399 { 399 {
400 dbgprintf("SD_SEND_RELATIVE_ADDR failed"); 400 dbgprintf("SD_SEND_RELATIVE_ADDR failed");
401 return -1; 401 return -1;
402 } 402 }
403 403
@@ -559,7 +559,7 @@ bool sd_removable(IF_MD_NONVOID(int card_no))
559#ifdef HAVE_MULTIDRIVE 559#ifdef HAVE_MULTIDRIVE
560 (void)card_no; 560 (void)card_no;
561#endif 561#endif
562 562
563 /* not applicable */ 563 /* not applicable */
564 return false; 564 return false;
565} 565}
@@ -597,17 +597,17 @@ static int sd_wait_for_state(unsigned int state)
597 } 597 }
598} 598}
599 599
600static int sd_transfer_sectors(int card_no, unsigned long start, 600static int sd_transfer_sectors(int card_no, sector_t start,
601 int count, void *buffer, bool write) 601 int count, void *buffer, bool write)
602{ 602{
603 int ret; 603 int ret;
604 unsigned long start_addr; 604 sector_t start_addr;
605 int dma_channel = -1; 605 int dma_channel = -1;
606 bool use_direct_dma; 606 bool use_direct_dma;
607 int count_per_dma; 607 int count_per_dma;
608 unsigned long rel_addr; 608 unsigned long rel_addr;
609 609
610 dbgprintf("transfer %d %d %d", card_no, start, count); 610 dbgprintf("transfer %d %lu %d", card_no, start, count);
611 mutex_lock(&sd_mtx); 611 mutex_lock(&sd_mtx);
612 enable_controller(true); 612 enable_controller(true);
613 613
@@ -673,6 +673,7 @@ sd_transfer_retry:
673 if (!(card_info[card_no].ocr & SD_OCR_CARD_CAPACITY_STATUS)) 673 if (!(card_info[card_no].ocr & SD_OCR_CARD_CAPACITY_STATUS))
674 start_addr *= SD_BLOCK_SIZE; /* not SDHC */ 674 start_addr *= SD_BLOCK_SIZE; /* not SDHC */
675 675
676 // XXX 64-bit
676 ret = sd_command(write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK, 677 ret = sd_command(write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK,
677 start_addr, MMC_CMD_DCLR | MMC_CMD_DATA | 678 start_addr, MMC_CMD_DCLR | MMC_CMD_DATA |
678 SDHC_RESP_FMT_1 | (write ? MMC_CMD_WRITE : 0), 679 SDHC_RESP_FMT_1 | (write ? MMC_CMD_WRITE : 0),
@@ -765,7 +766,7 @@ sd_transfer_error:
765 } 766 }
766} 767}
767 768
768int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount, 769int sd_read_sectors(IF_MD(int card_no,) sector_t start, int incount,
769 void* inbuf) 770 void* inbuf)
770{ 771{
771#ifndef HAVE_MULTIDRIVE 772#ifndef HAVE_MULTIDRIVE
@@ -774,7 +775,7 @@ int sd_read_sectors(IF_MD(int card_no,) unsigned long start, int incount,
774 return sd_transfer_sectors(card_no, start, incount, inbuf, false); 775 return sd_transfer_sectors(card_no, start, incount, inbuf, false);
775} 776}
776 777
777int sd_write_sectors(IF_MD(int card_no,) unsigned long start, int count, 778int sd_write_sectors(IF_MD(int card_no,) sector_t start, int count,
778 const void* outbuf) 779 const void* outbuf)
779{ 780{
780#ifndef HAVE_MULTIDRIVE 781#ifndef HAVE_MULTIDRIVE
@@ -862,7 +863,7 @@ long sd_last_disk_activity(void)
862} 863}
863 864
864tCardInfo *card_get_info_target(int card_no) 865tCardInfo *card_get_info_target(int card_no)
865{ 866{
866 return &card_info[card_no]; 867 return &card_info[card_no];
867} 868}
868 869
diff --git a/firmware/target/arm/tms320dm320/system-dm320.c b/firmware/target/arm/tms320dm320/system-dm320.c
index 6cf616184d..62eaf1f8ce 100644
--- a/firmware/target/arm/tms320dm320/system-dm320.c
+++ b/firmware/target/arm/tms320dm320/system-dm320.c
@@ -100,7 +100,7 @@ default_interrupt(RESERVED);
100 * change the offset for the interrupt in the entry table. 100 * change the offset for the interrupt in the entry table.
101 */ 101 */
102 102
103static const unsigned short const irqpriority[] = 103static const unsigned short irqpriority[] =
104{ 104{
105 IRQ_TIMER0,IRQ_TIMER1,IRQ_TIMER2,IRQ_TIMER3,IRQ_CCD_VD0,IRQ_CCD_VD1, 105 IRQ_TIMER0,IRQ_TIMER1,IRQ_TIMER2,IRQ_TIMER3,IRQ_CCD_VD0,IRQ_CCD_VD1,
106 IRQ_CCD_WEN,IRQ_VENC,IRQ_SERIAL0,IRQ_SERIAL1,IRQ_EXT_HOST,IRQ_DSPHINT, 106 IRQ_CCD_WEN,IRQ_VENC,IRQ_SERIAL0,IRQ_SERIAL1,IRQ_EXT_HOST,IRQ_DSPHINT,
diff --git a/firmware/target/coldfire/system-coldfire.c b/firmware/target/coldfire/system-coldfire.c
index ed130fca1f..2f2f2cb45b 100644
--- a/firmware/target/coldfire/system-coldfire.c
+++ b/firmware/target/coldfire/system-coldfire.c
@@ -26,6 +26,11 @@
26#include "lcd.h" 26#include "lcd.h"
27#include "font.h" 27#include "font.h"
28 28
29#if __GNUC__ >= 9
30#pragma GCC diagnostic push
31#pragma GCC diagnostic ignored "-Wmissing-attributes"
32#endif
33
29#define default_interrupt(name) \ 34#define default_interrupt(name) \
30 extern __attribute__((weak,alias("UIE"))) void name (void) 35 extern __attribute__((weak,alias("UIE"))) void name (void)
31 36
diff --git a/firmware/target/hosted/agptek/debug-agptek.c b/firmware/target/hosted/agptek/debug-agptek.c
index a9b829f7ec..de4bc946bc 100644
--- a/firmware/target/hosted/agptek/debug-agptek.c
+++ b/firmware/target/hosted/agptek/debug-agptek.c
@@ -37,6 +37,8 @@
37 37
38static int line = 0; 38static int line = 0;
39 39
40extern int hwver;
41
40bool dbg_hw_info(void) 42bool dbg_hw_info(void)
41{ 43{
42 int btn = 0; 44 int btn = 0;
@@ -61,6 +63,10 @@ bool dbg_hw_info(void)
61 lcd_putsf(0, line++, "Boot ver: %s", verstr); 63 lcd_putsf(0, line++, "Boot ver: %s", verstr);
62 } 64 }
63 65
66#ifdef EROS_Q
67 lcd_putsf(0, line++, "hwver: %d", hwver);
68#endif
69
64 lcd_putsf(0, line++, "pcm srate: %d", pcm_alsa_get_rate()); 70 lcd_putsf(0, line++, "pcm srate: %d", pcm_alsa_get_rate());
65 lcd_putsf(0, line++, "pcm xruns: %d", pcm_alsa_get_xruns()); 71 lcd_putsf(0, line++, "pcm xruns: %d", pcm_alsa_get_xruns());
66#ifdef HAVE_HEADPHONE_DETECTION 72#ifdef HAVE_HEADPHONE_DETECTION
diff --git a/firmware/target/hosted/aigo/power-erosq.c b/firmware/target/hosted/aigo/power-erosq.c
index 73fa5fe972..7c4515f616 100644
--- a/firmware/target/hosted/aigo/power-erosq.c
+++ b/firmware/target/hosted/aigo/power-erosq.c
@@ -28,17 +28,34 @@
28#include "power.h" 28#include "power.h"
29#include "panic.h" 29#include "panic.h"
30#include "sysfs.h" 30#include "sysfs.h"
31#include "tick.h"
31 32
32const char * const sysfs_bat_voltage = 33const char * const sysfs_bat_voltage[2] = {
33 "/sys/class/power_supply/battery/voltage_now"; 34 "/sys/class/power_supply/battery/voltage_now",
35 "/sys/class/power_supply/axp_battery/voltage_now",
36};
34 37
35const char * const sysfs_bat_capacity = 38const char * const sysfs_bat_capacity[2] = {
36 "/sys/class/power_supply/battery/capacity"; 39 "/sys/class/power_supply/battery/capacity",
40 "/sys/class/power_supply/axp_battery/capacity",
41};
42
43const char * const sysfs_bat_status[2] = {
44 "/sys/class/power_supply/battery/status",
45 "/sys/class/power_supply/axp_battery/status",
46};
47
48int hwver = 1; /* Exported */
37 49
38unsigned int erosq_power_get_battery_voltage(void) 50unsigned int erosq_power_get_battery_voltage(void)
39{ 51{
40 int battery_voltage; 52 int battery_voltage;
41 sysfs_get_int(sysfs_bat_voltage, &battery_voltage); 53 int x = sysfs_get_int(sysfs_bat_voltage[hwver == 4], &battery_voltage);
54
55 if (!x && hwver != 4) {
56 hwver = 4;
57 sysfs_get_int(sysfs_bat_voltage[hwver == 4], &battery_voltage);
58 }
42 59
43 return battery_voltage/1000; 60 return battery_voltage/1000;
44} 61}
@@ -46,7 +63,33 @@ unsigned int erosq_power_get_battery_voltage(void)
46unsigned int erosq_power_get_battery_capacity(void) 63unsigned int erosq_power_get_battery_capacity(void)
47{ 64{
48 int battery_capacity; 65 int battery_capacity;
49 sysfs_get_int(sysfs_bat_capacity, &battery_capacity); 66 int x = sysfs_get_int(sysfs_bat_capacity[hwver == 4], &battery_capacity);
67
68 if (!x && hwver != 4) {
69 hwver = 4;
70 sysfs_get_int(sysfs_bat_capacity[hwver == 4], &battery_capacity);
71 }
50 72
51 return battery_capacity; 73 return battery_capacity;
52} 74}
75
76/* We get called multiple times per tick, let's cut that back! */
77static long last_tick = 0;
78static bool last_power = false;
79
80bool charging_state(void)
81{
82 if ((current_tick - last_tick) > HZ/2 ) {
83 char buf[12] = {0};
84 int x = sysfs_get_string(sysfs_bat_status[hwver == 4], buf, sizeof(buf));
85
86 if (!x && hwver != 4) {
87 hwver = 4;
88 sysfs_get_string(sysfs_bat_status[hwver == 4], buf, sizeof(buf));
89 }
90
91 last_tick = current_tick;
92 last_power = (strncmp(buf, "Charging", 8) == 0);
93 }
94 return last_power;
95}
diff --git a/firmware/target/hosted/alsa-controls.h b/firmware/target/hosted/alsa-controls.h
index af3e584cd9..b868ef52fb 100644
--- a/firmware/target/hosted/alsa-controls.h
+++ b/firmware/target/hosted/alsa-controls.h
@@ -36,6 +36,8 @@ void alsa_controls_close(void);
36 36
37/* check wether a control exists */ 37/* check wether a control exists */
38bool alsa_has_control(const char *name); 38bool alsa_has_control(const char *name);
39/* find a control element ID by name, return -1 of not found or index into array */
40int alsa_controls_find(const char *name);
39/* find a control element enum index by name, return -1 if not found */ 41/* find a control element enum index by name, return -1 if not found */
40int alsa_controls_find_enum(const char *name, const char *enum_name); 42int alsa_controls_find_enum(const char *name, const char *enum_name);
41/* set a control, potentially supports several values */ 43/* set a control, potentially supports several values */
diff --git a/firmware/target/hosted/filesystem-hosted.h b/firmware/target/hosted/filesystem-hosted.h
index b9c7ce648a..348a921f82 100644
--- a/firmware/target/hosted/filesystem-hosted.h
+++ b/firmware/target/hosted/filesystem-hosted.h
@@ -21,9 +21,6 @@
21#ifndef _FILESYSTEM_HOSTED_H_ 21#ifndef _FILESYSTEM_HOSTED_H_
22#define _FILESYSTEM_HOSTED_H_ 22#define _FILESYSTEM_HOSTED_H_
23 23
24#include "mv.h"
25
26int os_volume_path(IF_MV(int volume, ) char *buffer, size_t bufsize);
27void * os_lc_open(const char *ospath); 24void * os_lc_open(const char *ospath);
28 25
29#endif /* _FILESYSTEM_HOSTED_H_ */ 26#endif /* _FILESYSTEM_HOSTED_H_ */
diff --git a/firmware/target/hosted/filesystem-unix.c b/firmware/target/hosted/filesystem-unix.c
index f0d7de640d..4869d07263 100644
--- a/firmware/target/hosted/filesystem-unix.c
+++ b/firmware/target/hosted/filesystem-unix.c
@@ -33,6 +33,8 @@
33#include "pathfuncs.h" 33#include "pathfuncs.h"
34#include "string-extra.h" 34#include "string-extra.h"
35 35
36int os_volume_path(IF_MV(int volume, ) char *buffer, size_t bufsize);
37
36#define SAME_FILE_INFO(sb1p, sb2p) \ 38#define SAME_FILE_INFO(sb1p, sb2p) \
37 ((sb1p)->st_dev == (sb2p)->st_dev && (sb1p)->st_ino == (sb2p)->st_ino) 39 ((sb1p)->st_dev == (sb2p)->st_dev && (sb1p)->st_ino == (sb2p)->st_ino)
38 40
@@ -207,9 +209,9 @@ int os_opendir_and_fd(const char *osdirname, DIR **osdirpp, int *osfdp)
207} 209}
208 210
209/* do we really need this in the app? (in the sim, yes) */ 211/* do we really need this in the app? (in the sim, yes) */
210void volume_size(IF_MV(int volume,) unsigned long *sizep, unsigned long *freep) 212void volume_size(IF_MV(int volume,) sector_t *sizep, sector_t *freep)
211{ 213{
212 unsigned long size = 0, free = 0; 214 sector_t size = 0, free = 0;
213 char volpath[MAX_PATH]; 215 char volpath[MAX_PATH];
214 struct statfs fs; 216 struct statfs fs;
215 217
diff --git a/firmware/target/hosted/filesystem-win32.c b/firmware/target/hosted/filesystem-win32.c
index fac10d003b..ebb7f283ac 100644
--- a/firmware/target/hosted/filesystem-win32.c
+++ b/firmware/target/hosted/filesystem-win32.c
@@ -30,6 +30,7 @@
30#include "debug.h" 30#include "debug.h"
31#include "pathfuncs.h" 31#include "pathfuncs.h"
32#include "string-extra.h" 32#include "string-extra.h"
33#include "mv.h"
33 34
34#define SAME_FILE_INFO(lpInfo1, lpInfo2) \ 35#define SAME_FILE_INFO(lpInfo1, lpInfo2) \
35 ((lpInfo1)->dwVolumeSerialNumber == (lpInfo2)->dwVolumeSerialNumber && \ 36 ((lpInfo1)->dwVolumeSerialNumber == (lpInfo2)->dwVolumeSerialNumber && \
@@ -469,7 +470,9 @@ int os_modtime(const char *path, time_t modtime)
469 return 0; 470 return 0;
470} 471}
471 472
472void volume_size(IF_MV(int volume,) unsigned long *sizep, unsigned long *freep) 473int os_volume_path(IF_MV(int volume, ) char *buffer, size_t bufsize);
474
475void volume_size(IF_MV(int volume,) sector_t *sizep, sector_t *freep)
473{ 476{
474 ULARGE_INTEGER free = { .QuadPart = 0 }, 477 ULARGE_INTEGER free = { .QuadPart = 0 },
475 size = { .QuadPart = 0 }; 478 size = { .QuadPart = 0 };
diff --git a/firmware/target/hosted/lcd-linuxfb.c b/firmware/target/hosted/lcd-linuxfb.c
index 14c8c30f89..5dda5cf1cc 100644
--- a/firmware/target/hosted/lcd-linuxfb.c
+++ b/firmware/target/hosted/lcd-linuxfb.c
@@ -59,14 +59,21 @@ void lcd_init_device(void)
59 panicf("Cannot read framebuffer fixed information"); 59 panicf("Cannot read framebuffer fixed information");
60 } 60 }
61 61
62#if 0 62 if(ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0)
63 /* check resolution and framebuffer size */
64 if(vinfo.xres != LCD_WIDTH || vinfo.yres != LCD_HEIGHT || vinfo.bits_per_pixel != LCD_DEPTH)
65 { 63 {
66 panicf("Unexpected framebuffer resolution: %dx%dx%d\n", vinfo.xres, 64 panicf("Cannot read framebuffer variable information");
67 vinfo.yres, vinfo.bits_per_pixel); 65 }
66
67 /* Make sure we match our desired bitdepth */
68 if (vinfo.bits_per_pixel != LCD_DEPTH || vinfo.xres != LCD_WIDTH || vinfo.yres != LCD_HEIGHT) {
69 vinfo.bits_per_pixel = LCD_DEPTH;
70 vinfo.xres = LCD_WIDTH;
71 vinfo.yres = LCD_HEIGHT;
72 if (ioctl(fd, FBIOPUT_VSCREENINFO, &vinfo)) {
73 panicf("Cannot set framebuffer to %dx%dx%d",
74 vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
75 }
68 } 76 }
69#endif
70 /* Note: we use a framebuffer size of width*height*bbp. We cannot trust the 77 /* Note: we use a framebuffer size of width*height*bbp. We cannot trust the
71 * values returned by the driver for line_length */ 78 * values returned by the driver for line_length */
72 79
@@ -77,11 +84,6 @@ void lcd_init_device(void)
77 panicf("Cannot map framebuffer"); 84 panicf("Cannot map framebuffer");
78 } 85 }
79 86
80 if(ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0)
81 {
82 panicf("Cannot read framebuffer variable information");
83 }
84
85 memset(framebuffer, 0, finfo.smem_len); 87 memset(framebuffer, 0, finfo.smem_len);
86 88
87#ifdef HAVE_LCD_ENABLE 89#ifdef HAVE_LCD_ENABLE
diff --git a/firmware/target/hosted/power-linux.c b/firmware/target/hosted/power-linux.c
index ddd7ad63e3..8d263eebec 100644
--- a/firmware/target/hosted/power-linux.c
+++ b/firmware/target/hosted/power-linux.c
@@ -33,9 +33,13 @@
33#include "usb.h" 33#include "usb.h"
34#endif 34#endif
35 35
36#ifdef BATTERY_DEV_NAME
36#define BATTERY_STATUS_PATH "/sys/class/power_supply/" BATTERY_DEV_NAME "/status" 37#define BATTERY_STATUS_PATH "/sys/class/power_supply/" BATTERY_DEV_NAME "/status"
38#endif
39
37#define POWER_STATUS_PATH "/sys/class/power_supply/" POWER_DEV_NAME "/online" 40#define POWER_STATUS_PATH "/sys/class/power_supply/" POWER_DEV_NAME "/online"
38 41
42#ifdef BATTERY_DEV_NAME
39/* We get called multiple times per tick, let's cut that back! */ 43/* We get called multiple times per tick, let's cut that back! */
40static long last_tick = 0; 44static long last_tick = 0;
41static bool last_power = false; 45static bool last_power = false;
@@ -51,6 +55,7 @@ bool charging_state(void)
51 } 55 }
52 return last_power; 56 return last_power;
53} 57}
58#endif
54 59
55unsigned int power_input_status(void) 60unsigned int power_input_status(void)
56{ 61{
diff --git a/firmware/target/hosted/sdl/app/button-application.c b/firmware/target/hosted/sdl/app/button-application.c
index 9c313b76b1..8071df201a 100644
--- a/firmware/target/hosted/sdl/app/button-application.c
+++ b/firmware/target/hosted/sdl/app/button-application.c
@@ -40,23 +40,23 @@ int key_to_button(int keyboard_key)
40#if (CONFIG_PLATFORM & PLATFORM_MAEMO4) 40#if (CONFIG_PLATFORM & PLATFORM_MAEMO4)
41 case SDLK_ESCAPE: 41 case SDLK_ESCAPE:
42#endif 42#endif
43 case SDLK_KP7: 43 case SDLK_KP_7:
44 new_btn = BUTTON_TOPLEFT; 44 new_btn = BUTTON_TOPLEFT;
45 break; 45 break;
46 case SDLK_KP8: 46 case SDLK_KP_8:
47 case SDLK_UP: 47 case SDLK_UP:
48 new_btn = BUTTON_TOPMIDDLE; 48 new_btn = BUTTON_TOPMIDDLE;
49 break; 49 break;
50#if (CONFIG_PLATFORM & PLATFORM_MAEMO4) 50#if (CONFIG_PLATFORM & PLATFORM_MAEMO4)
51 case SDLK_F7: 51 case SDLK_F7:
52#endif 52#endif
53 case SDLK_KP9: 53 case SDLK_KP_9:
54 new_btn = BUTTON_TOPRIGHT; 54 new_btn = BUTTON_TOPRIGHT;
55 break; 55 break;
56#if (CONFIG_PLATFORM & PLATFORM_PANDORA) 56#if (CONFIG_PLATFORM & PLATFORM_PANDORA)
57 case SDLK_RSHIFT: 57 case SDLK_RSHIFT:
58#endif 58#endif
59 case SDLK_KP4: 59 case SDLK_KP_4:
60 case SDLK_LEFT: 60 case SDLK_LEFT:
61 new_btn = BUTTON_MIDLEFT; 61 new_btn = BUTTON_MIDLEFT;
62 break; 62 break;
@@ -64,40 +64,32 @@ int key_to_button(int keyboard_key)
64 case SDLK_RETURN: 64 case SDLK_RETURN:
65 case SDLK_KP_ENTER: 65 case SDLK_KP_ENTER:
66#endif 66#endif
67 case SDLK_KP5: 67 case SDLK_KP_5:
68 new_btn = BUTTON_CENTER; 68 new_btn = BUTTON_CENTER;
69 break; 69 break;
70#if (CONFIG_PLATFORM & PLATFORM_PANDORA) 70#if (CONFIG_PLATFORM & PLATFORM_PANDORA)
71 case SDLK_RCTRL: 71 case SDLK_RCTRL:
72#endif 72#endif
73 case SDLK_KP6: 73 case SDLK_KP_6:
74 case SDLK_RIGHT: 74 case SDLK_RIGHT:
75 new_btn = BUTTON_MIDRIGHT; 75 new_btn = BUTTON_MIDRIGHT;
76 break; 76 break;
77#if (CONFIG_PLATFORM & PLATFORM_MAEMO4) 77#if (CONFIG_PLATFORM & PLATFORM_MAEMO4)
78 case SDLK_F6: 78 case SDLK_F6:
79#endif 79#endif
80 case SDLK_KP1: 80 case SDLK_KP_1:
81 new_btn = BUTTON_BOTTOMLEFT; 81 new_btn = BUTTON_BOTTOMLEFT;
82 break; 82 break;
83 case SDLK_KP2: 83 case SDLK_KP_2:
84 case SDLK_DOWN: 84 case SDLK_DOWN:
85 new_btn = BUTTON_BOTTOMMIDDLE; 85 new_btn = BUTTON_BOTTOMMIDDLE;
86 break; 86 break;
87#if (CONFIG_PLATFORM & PLATFORM_MAEMO4) 87#if (CONFIG_PLATFORM & PLATFORM_MAEMO4)
88 case SDLK_F8: 88 case SDLK_F8:
89#endif 89#endif
90 case SDLK_KP3: 90 case SDLK_KP_3:
91 new_btn = BUTTON_BOTTOMRIGHT; 91 new_btn = BUTTON_BOTTOMRIGHT;
92 break; 92 break;
93#ifdef HAVE_SCROLLWHEEL
94 case SDL_BUTTON_WHEELUP:
95 new_btn = BUTTON_SCROLL_BACK;
96 break;
97 case SDL_BUTTON_WHEELDOWN:
98 new_btn = BUTTON_SCROLL_FWD;
99 break;
100#endif
101 case SDL_BUTTON_RIGHT: 93 case SDL_BUTTON_RIGHT:
102 new_btn = BUTTON_MIDLEFT; 94 new_btn = BUTTON_MIDLEFT;
103 break; 95 break;
diff --git a/firmware/target/hosted/sdl/button-sdl.c b/firmware/target/hosted/sdl/button-sdl.c
index 1055d7e0b9..8af6f3ffaf 100644
--- a/firmware/target/hosted/sdl/button-sdl.c
+++ b/firmware/target/hosted/sdl/button-sdl.c
@@ -107,6 +107,30 @@ static void touchscreen_event(int x, int y)
107} 107}
108#endif 108#endif
109 109
110#if defined(HAVE_SCROLLWHEEL) || ((defined(BUTTON_SCROLL_FWD) && defined(BUTTON_SCROLL_BACK)))
111static void scrollwheel_event(int x, int y)
112{
113 int new_btn = 0;
114 if (y > 0)
115 new_btn = BUTTON_SCROLL_BACK;
116 else if (y < 0)
117 new_btn = BUTTON_SCROLL_FWD;
118 else
119 return;
120
121#ifdef HAVE_BACKLIGHT
122 backlight_on();
123#endif
124#ifdef HAVE_BUTTON_LIGHT
125 buttonlight_on();
126#endif
127 reset_poweroff_timer();
128 if (new_btn && !queue_full(&button_queue))
129 queue_post(&button_queue, new_btn, 1<<24);
130
131 (void)x;
132}
133#endif
110static void mouse_event(SDL_MouseButtonEvent *event, bool button_up) 134static void mouse_event(SDL_MouseButtonEvent *event, bool button_up)
111{ 135{
112#define SQUARE(x) ((x)*(x)) 136#define SQUARE(x) ((x)*(x))
@@ -118,10 +142,6 @@ static void mouse_event(SDL_MouseButtonEvent *event, bool button_up)
118 if(button_up) { 142 if(button_up) {
119 switch ( event->button ) 143 switch ( event->button )
120 { 144 {
121#ifdef HAVE_SCROLLWHEEL
122 case SDL_BUTTON_WHEELUP:
123 case SDL_BUTTON_WHEELDOWN:
124#endif
125 case SDL_BUTTON_MIDDLE: 145 case SDL_BUTTON_MIDDLE:
126 case SDL_BUTTON_RIGHT: 146 case SDL_BUTTON_RIGHT:
127 button_event( event->button, false ); 147 button_event( event->button, false );
@@ -145,13 +165,9 @@ static void mouse_event(SDL_MouseButtonEvent *event, bool button_up)
145#endif 165#endif
146 break; 166 break;
147 } 167 }
148 } else { /* button down */ 168 } else { /* button down */
149 switch ( event->button ) 169 switch ( event->button )
150 { 170 {
151#ifdef HAVE_SCROLLWHEEL
152 case SDL_BUTTON_WHEELUP:
153 case SDL_BUTTON_WHEELDOWN:
154#endif
155 case SDL_BUTTON_MIDDLE: 171 case SDL_BUTTON_MIDDLE:
156 case SDL_BUTTON_RIGHT: 172 case SDL_BUTTON_RIGHT:
157 button_event( event->button, true ); 173 button_event( event->button, true );
@@ -215,18 +231,15 @@ static void mouse_event(SDL_MouseButtonEvent *event, bool button_up)
215 231
216static bool event_handler(SDL_Event *event) 232static bool event_handler(SDL_Event *event)
217{ 233{
218 SDLKey ev_key; 234 SDL_Keycode ev_key;
219 235
220 switch(event->type) 236 switch(event->type)
221 { 237 {
222 case SDL_ACTIVEEVENT: 238 case SDL_WINDOWEVENT:
223 if (event->active.state & SDL_APPINPUTFOCUS) 239 if (event->window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
224 { 240 sdl_app_has_input_focus = 1;
225 if (event->active.gain == 1) 241 else if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST)
226 sdl_app_has_input_focus = 1; 242 sdl_app_has_input_focus = 0;
227 else
228 sdl_app_has_input_focus = 0;
229 }
230 break; 243 break;
231 case SDL_KEYDOWN: 244 case SDL_KEYDOWN:
232 case SDL_KEYUP: 245 case SDL_KEYUP:
@@ -275,6 +288,13 @@ static bool event_handler(SDL_Event *event)
275 mouse_event(mev, event->type == SDL_MOUSEBUTTONUP); 288 mouse_event(mev, event->type == SDL_MOUSEBUTTONUP);
276 break; 289 break;
277 } 290 }
291#ifdef HAVE_SCROLLWHEEL
292 case SDL_MOUSEWHEEL:
293 {
294 scrollwheel_event(event->wheel.x, event->wheel.y);
295 break;
296 }
297#endif
278 case SDL_QUIT: 298 case SDL_QUIT:
279 /* Will post SDL_USEREVENT in shutdown_hw() if successful. */ 299 /* Will post SDL_USEREVENT in shutdown_hw() if successful. */
280 sdl_sys_quit(); 300 sdl_sys_quit();
@@ -340,7 +360,7 @@ static void button_event(int key, bool pressed)
340 } 360 }
341 return; 361 return;
342#endif 362#endif
343#ifdef HAVE_MULTIDRIVE 363#ifdef HAVE_HOTSWAP
344 case EXT_KEY: 364 case EXT_KEY:
345 if (!pressed) 365 if (!pressed)
346 sim_trigger_external(!storage_present(1)); 366 sim_trigger_external(!storage_present(1));
@@ -362,7 +382,7 @@ static void button_event(int key, bool pressed)
362 } 382 }
363 return; 383 return;
364#endif 384#endif
365 385
366#ifdef HAS_REMOTE_BUTTON_HOLD 386#ifdef HAS_REMOTE_BUTTON_HOLD
367 case SDLK_j: 387 case SDLK_j:
368 if(pressed) 388 if(pressed)
@@ -379,7 +399,7 @@ static void button_event(int key, bool pressed)
379 if(pressed) 399 if(pressed)
380 switch(_remote_type) 400 switch(_remote_type)
381 { 401 {
382 case REMOTETYPE_UNPLUGGED: 402 case REMOTETYPE_UNPLUGGED:
383 _remote_type=REMOTETYPE_H100_LCD; 403 _remote_type=REMOTETYPE_H100_LCD;
384 DEBUGF("Changed remote type to H100\n"); 404 DEBUGF("Changed remote type to H100\n");
385 break; 405 break;
@@ -399,7 +419,7 @@ static void button_event(int key, bool pressed)
399 break; 419 break;
400#endif 420#endif
401#ifndef APPLICATION 421#ifndef APPLICATION
402 case SDLK_KP0: 422 case SDLK_KP_0:
403 case SDLK_F5: 423 case SDLK_F5:
404 if(pressed) 424 if(pressed)
405 { 425 {
@@ -430,32 +450,17 @@ static void button_event(int key, bool pressed)
430#endif 450#endif
431 break; 451 break;
432 } 452 }
433 /* Call to make up for scrollwheel target implementation. This is 453
434 * not handled in the main button.c driver, but on the target
435 * implementation (look at button-e200.c for example if you are trying to
436 * figure out why using button_get_data needed a hack before).
437 */
438#if defined(BUTTON_SCROLL_FWD) && defined(BUTTON_SCROLL_BACK) 454#if defined(BUTTON_SCROLL_FWD) && defined(BUTTON_SCROLL_BACK)
439 if((new_btn == BUTTON_SCROLL_FWD || new_btn == BUTTON_SCROLL_BACK) && 455 if((new_btn == BUTTON_SCROLL_FWD || new_btn == BUTTON_SCROLL_BACK) &&
440 pressed) 456 pressed)
441 { 457 {
442 /* Clear these buttons from the data - adding them to the queue is 458 scrollwheel_event(0, new_btn == BUTTON_SCROLL_FWD ? -1 : 1);
443 * handled in the scrollwheel drivers for the targets. They do not
444 * store the scroll forward/back buttons in their button data for
445 * the button_read call.
446 */
447#ifdef HAVE_BACKLIGHT
448 backlight_on();
449#endif
450#ifdef HAVE_BUTTON_LIGHT
451 buttonlight_on();
452#endif
453 reset_poweroff_timer();
454 queue_post(&button_queue, new_btn, 1<<24);
455 new_btn &= ~(BUTTON_SCROLL_FWD | BUTTON_SCROLL_BACK); 459 new_btn &= ~(BUTTON_SCROLL_FWD | BUTTON_SCROLL_BACK);
456 } 460 }
457#endif 461#endif
458 462
463 /* Update global button press state */
459 if (pressed) 464 if (pressed)
460 btn |= new_btn; 465 btn |= new_btn;
461 else 466 else
@@ -496,5 +501,4 @@ int button_read_device(void)
496 501
497void button_init_device(void) 502void button_init_device(void)
498{ 503{
499 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
500} 504}
diff --git a/firmware/target/hosted/sdl/kernel-sdl.c b/firmware/target/hosted/sdl/kernel-sdl.c
index 5c16f86749..bcad39b4d8 100644
--- a/firmware/target/hosted/sdl/kernel-sdl.c
+++ b/firmware/target/hosted/sdl/kernel-sdl.c
@@ -153,7 +153,7 @@ void sim_kernel_shutdown(void)
153 SDL_Delay(10); 153 SDL_Delay(10);
154 154
155 SDL_DestroyMutex(sim_irq_mtx); 155 SDL_DestroyMutex(sim_irq_mtx);
156 SDL_DestroyCond(sim_thread_cond); 156 SDL_DestroyCond(sim_thread_cond);
157} 157}
158 158
159Uint32 tick_timer(Uint32 interval, void *param) 159Uint32 tick_timer(Uint32 interval, void *param)
@@ -162,9 +162,9 @@ Uint32 tick_timer(Uint32 interval, void *param)
162 162
163 (void) interval; 163 (void) interval;
164 (void) param; 164 (void) param;
165 165
166 new_tick = (SDL_GetTicks() - start_tick) / (1000/HZ); 166 new_tick = (SDL_GetTicks() - start_tick) / (1000/HZ);
167 167
168 while(new_tick != current_tick) 168 while(new_tick != current_tick)
169 { 169 {
170 sim_enter_irq_handler(); 170 sim_enter_irq_handler();
@@ -175,7 +175,7 @@ Uint32 tick_timer(Uint32 interval, void *param)
175 175
176 sim_exit_irq_handler(); 176 sim_exit_irq_handler();
177 } 177 }
178 178
179 return interval; 179 return interval;
180} 180}
181 181
@@ -187,10 +187,10 @@ void tick_start(unsigned int interval_in_ms)
187 exit(-1); 187 exit(-1);
188 } 188 }
189 189
190 if (tick_timer_id != NULL) 190 if (tick_timer_id != 0)
191 { 191 {
192 SDL_RemoveTimer(tick_timer_id); 192 SDL_RemoveTimer(tick_timer_id);
193 tick_timer_id = NULL; 193 tick_timer_id = 0;
194 } 194 }
195 else 195 else
196 { 196 {
diff --git a/firmware/target/hosted/sdl/key_to_touch-sdl.c b/firmware/target/hosted/sdl/key_to_touch-sdl.c
index d56d06ba74..b7052e043f 100644
--- a/firmware/target/hosted/sdl/key_to_touch-sdl.c
+++ b/firmware/target/hosted/sdl/key_to_touch-sdl.c
@@ -52,12 +52,12 @@ int key_to_touch(int keyboard_button, unsigned int mouse_coords)
52 } 52 }
53 break; 53 break;
54#ifndef APPLICATION 54#ifndef APPLICATION
55 case SDLK_KP7: 55 case SDLK_KP_7:
56 case SDLK_7: 56 case SDLK_7:
57 case SDLK_HOME: 57 case SDLK_HOME:
58 new_btn = BUTTON_TOPLEFT; 58 new_btn = BUTTON_TOPLEFT;
59 break; 59 break;
60 case SDLK_KP8: 60 case SDLK_KP_8:
61 case SDLK_8: 61 case SDLK_8:
62 case SDLK_UP: 62 case SDLK_UP:
63#ifdef HAVE_SCROLLWHEEL 63#ifdef HAVE_SCROLLWHEEL
@@ -65,32 +65,32 @@ int key_to_touch(int keyboard_button, unsigned int mouse_coords)
65#endif 65#endif
66 new_btn = BUTTON_TOPMIDDLE; 66 new_btn = BUTTON_TOPMIDDLE;
67 break; 67 break;
68 case SDLK_KP9: 68 case SDLK_KP_9:
69 case SDLK_9: 69 case SDLK_9:
70 case SDLK_PAGEUP: 70 case SDLK_PAGEUP:
71 new_btn = BUTTON_TOPRIGHT; 71 new_btn = BUTTON_TOPRIGHT;
72 break; 72 break;
73 case SDLK_KP4: 73 case SDLK_KP_4:
74 case SDLK_u: 74 case SDLK_u:
75 case SDLK_LEFT: 75 case SDLK_LEFT:
76 new_btn = BUTTON_MIDLEFT; 76 new_btn = BUTTON_MIDLEFT;
77 break; 77 break;
78 case SDLK_KP5: 78 case SDLK_KP_5:
79 case SDLK_i: 79 case SDLK_i:
80 case SDL_BUTTON_MIDDLE: 80 case SDL_BUTTON_MIDDLE:
81 new_btn = BUTTON_CENTER; 81 new_btn = BUTTON_CENTER;
82 break; 82 break;
83 case SDLK_KP6: 83 case SDLK_KP_6:
84 case SDLK_o: 84 case SDLK_o:
85 case SDLK_RIGHT: 85 case SDLK_RIGHT:
86 new_btn = BUTTON_MIDRIGHT; 86 new_btn = BUTTON_MIDRIGHT;
87 break; 87 break;
88 case SDLK_KP1: 88 case SDLK_KP_1:
89 case SDLK_j: 89 case SDLK_j:
90 case SDLK_END: 90 case SDLK_END:
91 new_btn = BUTTON_BOTTOMLEFT; 91 new_btn = BUTTON_BOTTOMLEFT;
92 break; 92 break;
93 case SDLK_KP2: 93 case SDLK_KP_2:
94 case SDLK_k: 94 case SDLK_k:
95#ifdef HAVE_SCROLLWHEEL 95#ifdef HAVE_SCROLLWHEEL
96 case SDL_BUTTON_WHEELDOWN: 96 case SDL_BUTTON_WHEELDOWN:
@@ -98,7 +98,7 @@ int key_to_touch(int keyboard_button, unsigned int mouse_coords)
98 case SDLK_DOWN: 98 case SDLK_DOWN:
99 new_btn = BUTTON_BOTTOMMIDDLE; 99 new_btn = BUTTON_BOTTOMMIDDLE;
100 break; 100 break;
101 case SDLK_KP3: 101 case SDLK_KP_3:
102 case SDLK_l: 102 case SDLK_l:
103 case SDLK_PAGEDOWN: 103 case SDLK_PAGEDOWN:
104 new_btn = BUTTON_BOTTOMRIGHT; 104 new_btn = BUTTON_BOTTOMRIGHT;
@@ -106,4 +106,5 @@ int key_to_touch(int keyboard_button, unsigned int mouse_coords)
106#endif 106#endif
107 } 107 }
108 return new_btn; 108 return new_btn;
109
109} 110}
diff --git a/firmware/target/hosted/sdl/lcd-bitmap.c b/firmware/target/hosted/sdl/lcd-bitmap.c
index ea30afea3b..ef284eeb48 100644
--- a/firmware/target/hosted/sdl/lcd-bitmap.c
+++ b/firmware/target/hosted/sdl/lcd-bitmap.c
@@ -164,12 +164,12 @@ void sim_backlight(int value)
164#else /* LCD_DEPTH > 8 */ 164#else /* LCD_DEPTH > 8 */
165#if defined(HAVE_TRANSFLECTIVE_LCD) && defined(HAVE_LCD_SLEEP) 165#if defined(HAVE_TRANSFLECTIVE_LCD) && defined(HAVE_LCD_SLEEP)
166 if (!lcd_active()) 166 if (!lcd_active())
167 SDL_SetAlpha(lcd_surface, SDL_SRCALPHA, 0); 167 SDL_SetSurfaceAlphaMod(lcd_surface, 0);
168 else 168 else
169 SDL_SetAlpha(lcd_surface, SDL_SRCALPHA, 169 SDL_SetSurfaceAlphaMod(lcd_surface,
170 MAX(BACKLIGHT_OFF_ALPHA, (value * 255) / 100)); 170 MAX(BACKLIGHT_OFF_ALPHA, (value * 255) / 100));
171#else 171#else
172 SDL_SetAlpha(lcd_surface, SDL_SRCALPHA, (value * 255) / 100); 172 SDL_SetSurfaceAlphaMod(lcd_surface, (value * 255) / 100);
173#endif 173#endif
174#endif /* LCD_DEPTH */ 174#endif /* LCD_DEPTH */
175 175
@@ -187,6 +187,7 @@ void lcd_init_device(void)
187 SIM_LCD_WIDTH * display_zoom, 187 SIM_LCD_WIDTH * display_zoom,
188 SIM_LCD_HEIGHT * display_zoom, 188 SIM_LCD_HEIGHT * display_zoom,
189 LCD_DEPTH, 0, 0, 0, 0); 189 LCD_DEPTH, 0, 0, 0, 0);
190 SDL_SetSurfaceBlendMode(lcd_surface, SDL_BLENDMODE_BLEND);
190#elif LCD_DEPTH <= 8 191#elif LCD_DEPTH <= 8
191 lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 192 lcd_surface = SDL_CreateRGBSurface(SDL_SWSURFACE,
192 SIM_LCD_WIDTH * display_zoom, 193 SIM_LCD_WIDTH * display_zoom,
@@ -222,7 +223,7 @@ void sim_lcd_ex_update_rect(int x_start, int y_start, int width, int height)
222 if (lcd_ex_getpixel) { 223 if (lcd_ex_getpixel) {
223 sdl_update_rect(lcd_surface, x_start, y_start, width, height, 224 sdl_update_rect(lcd_surface, x_start, y_start, width, height,
224 LCD_WIDTH, LCD_HEIGHT, lcd_ex_getpixel); 225 LCD_WIDTH, LCD_HEIGHT, lcd_ex_getpixel);
225 sdl_gui_update(lcd_surface, x_start, y_start, width, 226 sdl_gui_update(lcd_surface, x_start, y_start, width,
226 height + LCD_SPLIT_LINES, SIM_LCD_WIDTH, SIM_LCD_HEIGHT, 227 height + LCD_SPLIT_LINES, SIM_LCD_WIDTH, SIM_LCD_HEIGHT,
227 background ? UI_LCD_POSX : 0, 228 background ? UI_LCD_POSX : 0,
228 background ? UI_LCD_POSY : 0); 229 background ? UI_LCD_POSY : 0);
diff --git a/firmware/target/hosted/sdl/lcd-sdl.c b/firmware/target/hosted/sdl/lcd-sdl.c
index 8cbb6c5651..1e9daeffd3 100644
--- a/firmware/target/hosted/sdl/lcd-sdl.c
+++ b/firmware/target/hosted/sdl/lcd-sdl.c
@@ -115,12 +115,17 @@ void sdl_gui_update(SDL_Surface *surface, int x_start, int y_start, int width,
115 (ui_y + y_start) * display_zoom, 115 (ui_y + y_start) * display_zoom,
116 width * display_zoom, height * display_zoom}; 116 width * display_zoom, height * display_zoom};
117 117
118 if (surface->flags & SDL_SRCALPHA) /* alpha needs a black background */ 118 uint8_t alpha;
119 if (SDL_GetSurfaceAlphaMod(surface,&alpha) == 0 && alpha < 255)
119 SDL_FillRect(gui_surface, &dest, 0); 120 SDL_FillRect(gui_surface, &dest, 0);
120 121
121 SDL_BlitSurface(surface, &src, gui_surface, &dest); 122 SDL_BlitSurface(surface, &src, gui_surface, &dest); /* alpha needs a black background */
122 123
123 SDL_Flip(gui_surface); 124 SDL_Texture *sdlTexture = SDL_CreateTextureFromSurface(sdlRenderer, gui_surface);
125 SDL_RenderClear(sdlRenderer);
126 SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL);
127 SDL_RenderPresent(sdlRenderer);
128 SDL_DestroyTexture(sdlTexture);
124} 129}
125 130
126/* set a range of bitmap indices to a gradient from startcolour to endcolour */ 131/* set a range of bitmap indices to a gradient from startcolour to endcolour */
@@ -136,7 +141,7 @@ void sdl_set_gradient(SDL_Surface *surface, SDL_Color *start, SDL_Color *end,
136 palette[i].b = start->b + (end->b - start->b) * i / (steps - 1); 141 palette[i].b = start->b + (end->b - start->b) * i / (steps - 1);
137 } 142 }
138 143
139 SDL_SetPalette(surface, SDL_LOGPAL|SDL_PHYSPAL, palette, first, steps); 144 SDL_SetPaletteColors(surface->format->palette, palette, first , steps);
140} 145}
141 146
142int lcd_get_dpi(void) 147int lcd_get_dpi(void)
diff --git a/firmware/target/hosted/sdl/lcd-sdl.h b/firmware/target/hosted/sdl/lcd-sdl.h
index a964c9bc40..3f1334e4a2 100644
--- a/firmware/target/hosted/sdl/lcd-sdl.h
+++ b/firmware/target/hosted/sdl/lcd-sdl.h
@@ -3,7 +3,7 @@
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
@@ -27,6 +27,7 @@
27 27
28/* Default display zoom level */ 28/* Default display zoom level */
29extern SDL_Surface *gui_surface; 29extern SDL_Surface *gui_surface;
30extern SDL_Renderer *sdlRenderer;
30 31
31void sdl_update_rect(SDL_Surface *surface, int x_start, int y_start, int width, 32void sdl_update_rect(SDL_Surface *surface, int x_start, int y_start, int width,
32 int height, int max_x, int max_y, 33 int height, int max_x, int max_y,
@@ -39,4 +40,3 @@ void sdl_set_gradient(SDL_Surface *surface, SDL_Color *start, SDL_Color *end,
39 int first, int steps); 40 int first, int steps);
40 41
41#endif /* #ifndef __LCDSDL_H__ */ 42#endif /* #ifndef __LCDSDL_H__ */
42
diff --git a/firmware/target/hosted/sdl/pcm-sdl.c b/firmware/target/hosted/sdl/pcm-sdl.c
index 940403002f..dec12af2f1 100644
--- a/firmware/target/hosted/sdl/pcm-sdl.c
+++ b/firmware/target/hosted/sdl/pcm-sdl.c
@@ -1,10 +1,10 @@
1/*************************************************************************** 1/***************************************************************************
2 * __________ __ ___. 2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2005 by Nick Lanham 10 * Copyright (C) 2005 by Nick Lanham
@@ -85,8 +85,43 @@ void pcm_play_unlock(void)
85 SDL_UnlockMutex(audio_lock); 85 SDL_UnlockMutex(audio_lock);
86} 86}
87 87
88static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len);
88static void pcm_dma_apply_settings_nolock(void) 89static void pcm_dma_apply_settings_nolock(void)
89{ 90{
91 SDL_AudioSpec wanted_spec;
92 wanted_spec.freq = pcm_sampr;
93 wanted_spec.format = AUDIO_S16SYS;
94 wanted_spec.channels = 2;
95 wanted_spec.samples = 2048;
96 wanted_spec.callback =
97 (void (SDLCALL *)(void *userdata,
98 Uint8 *stream, int len))sdl_audio_callback;
99 wanted_spec.userdata = &udata;
100 SDL_CloseAudio();
101 /* Open the audio device and start playing sound! */
102 if(SDL_OpenAudio(&wanted_spec, &obtained) < 0) {
103 DEBUGF("Unable to open audio: %s\n", SDL_GetError());
104 return;
105 }
106 switch (obtained.format)
107 {
108 case AUDIO_U8:
109 case AUDIO_S8:
110 pcm_channel_bytes = 1;
111 break;
112 case AUDIO_U16LSB:
113 case AUDIO_S16LSB:
114 case AUDIO_U16MSB:
115 case AUDIO_S16MSB:
116 pcm_channel_bytes = 2;
117 break;
118 default:
119 DEBUGF("Unknown sample format obtained: %u\n",
120 (unsigned)obtained.format);
121 return;
122 }
123 pcm_sample_bytes = obtained.channels * pcm_channel_bytes;
124
90 cvt_status = SDL_BuildAudioCVT(&cvt, AUDIO_S16SYS, 2, pcm_sampr, 125 cvt_status = SDL_BuildAudioCVT(&cvt, AUDIO_S16SYS, 2, pcm_sampr,
91 obtained.format, obtained.channels, obtained.freq); 126 obtained.format, obtained.channels, obtained.freq);
92 127
@@ -104,7 +139,6 @@ void pcm_dma_apply_settings(void)
104 139
105void pcm_play_dma_start(const void *addr, size_t size) 140void pcm_play_dma_start(const void *addr, size_t size)
106{ 141{
107 pcm_dma_apply_settings_nolock();
108 142
109 pcm_data = addr; 143 pcm_data = addr;
110 pcm_data_size = size; 144 pcm_data_size = size;
@@ -257,9 +291,7 @@ static void sdl_audio_callback(struct pcm_udata *udata, Uint8 *stream, int len)
257 291
258 if (delay > 0) 292 if (delay > 0)
259 { 293 {
260 SDL_UnlockMutex(audio_lock);
261 SDL_Delay(delay); 294 SDL_Delay(delay);
262 SDL_LockMutex(audio_lock);
263 295
264 if (!pcm_is_playing()) 296 if (!pcm_is_playing())
265 break; 297 break;
@@ -340,7 +372,6 @@ void pcm_play_dma_init(void)
340 return; 372 return;
341 } 373 }
342 374
343 SDL_AudioSpec wanted_spec;
344#ifdef DEBUG 375#ifdef DEBUG
345 udata.debug = NULL; 376 udata.debug = NULL;
346 if (debug_audio) { 377 if (debug_audio) {
@@ -348,43 +379,6 @@ void pcm_play_dma_init(void)
348 DEBUGF("Audio debug file open\n"); 379 DEBUGF("Audio debug file open\n");
349 } 380 }
350#endif 381#endif
351 /* Set 16-bit stereo audio at 44Khz */
352 wanted_spec.freq = 44100;
353 wanted_spec.format = AUDIO_S16SYS;
354 wanted_spec.channels = 2;
355 wanted_spec.samples = 2048;
356 wanted_spec.callback =
357 (void (SDLCALL *)(void *userdata,
358 Uint8 *stream, int len))sdl_audio_callback;
359 wanted_spec.userdata = &udata;
360
361 /* Open the audio device and start playing sound! */
362 if(SDL_OpenAudio(&wanted_spec, &obtained) < 0) {
363 DEBUGF("Unable to open audio: %s\n", SDL_GetError());
364 return;
365 }
366
367 switch (obtained.format)
368 {
369 case AUDIO_U8:
370 case AUDIO_S8:
371 pcm_channel_bytes = 1;
372 break;
373 case AUDIO_U16LSB:
374 case AUDIO_S16LSB:
375 case AUDIO_U16MSB:
376 case AUDIO_S16MSB:
377 pcm_channel_bytes = 2;
378 break;
379 default:
380 DEBUGF("Unknown sample format obtained: %u\n",
381 (unsigned)obtained.format);
382 return;
383 }
384
385 pcm_sample_bytes = obtained.channels * pcm_channel_bytes;
386
387 pcm_dma_apply_settings_nolock();
388} 382}
389 383
390void pcm_play_dma_postinit(void) 384void pcm_play_dma_postinit(void)
diff --git a/firmware/target/hosted/sdl/system-sdl.c b/firmware/target/hosted/sdl/system-sdl.c
index e53643f449..56cff3f1be 100644
--- a/firmware/target/hosted/sdl/system-sdl.c
+++ b/firmware/target/hosted/sdl/system-sdl.c
@@ -1,10 +1,10 @@
1/*************************************************************************** 1/***************************************************************************
2 * __________ __ ___. 2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/ 7 * \/ \/ \/ \/ \/
8 * $Id$ 8 * $Id$
9 * 9 *
10 * Copyright (C) 2006 by Daniel Everton <dan@iocaine.org> 10 * Copyright (C) 2006 by Daniel Everton <dan@iocaine.org>
@@ -50,6 +50,8 @@
50#define SIMULATOR_DEFAULT_ROOT "simdisk" 50#define SIMULATOR_DEFAULT_ROOT "simdisk"
51 51
52SDL_Surface *gui_surface; 52SDL_Surface *gui_surface;
53SDL_Window *window;
54SDL_Renderer *sdlRenderer;
53 55
54bool background = true; /* use backgrounds by default */ 56bool background = true; /* use backgrounds by default */
55#ifdef HAVE_REMOTE_LCD 57#ifdef HAVE_REMOTE_LCD
@@ -72,26 +74,12 @@ bool debug_audio = false;
72bool debug_wps = false; 74bool debug_wps = false;
73int wps_verbose_level = 3; 75int wps_verbose_level = 3;
74 76
75/* 77static void sdl_window_setup(void)
76 * This thread will read the buttons in an interrupt like fashion, and
77 * also initializes SDL_INIT_VIDEO and the surfaces
78 *
79 * it must be done in the same thread (at least on windows) because events only
80 * work in the thread which called SDL_Init(SubSystem) with SDL_INIT_VIDEO
81 *
82 * This is an SDL thread and relies on preemptive behavoir of the host
83 **/
84static int sdl_event_thread(void * param)
85{ 78{
86 SDL_InitSubSystem(SDL_INIT_VIDEO);
87
88#if (CONFIG_PLATFORM & PLATFORM_MAEMO)
89 SDL_sem *wait_for_maemo_startup;
90#endif
91 SDL_Surface *picture_surface = NULL; 79 SDL_Surface *picture_surface = NULL;
92 int width, height; 80 int width, height;
93 int depth; 81 int depth;
94 Uint32 flags; 82 Uint32 flags = 0;
95 83
96 /* Try and load the background image. If it fails go without */ 84 /* Try and load the background image. If it fails go without */
97 if (background) { 85 if (background) {
@@ -101,14 +89,14 @@ static int sdl_event_thread(void * param)
101 DEBUGF("warn: %s\n", SDL_GetError()); 89 DEBUGF("warn: %s\n", SDL_GetError());
102 } 90 }
103 } 91 }
104 92
105 /* Set things up */ 93 /* Set things up */
106 if (background) 94 if (background)
107 { 95 {
108 width = UI_WIDTH; 96 width = UI_WIDTH;
109 height = UI_HEIGHT; 97 height = UI_HEIGHT;
110 } 98 }
111 else 99 else
112 { 100 {
113#ifdef HAVE_REMOTE_LCD 101#ifdef HAVE_REMOTE_LCD
114 if (showremote) 102 if (showremote)
@@ -128,17 +116,47 @@ static int sdl_event_thread(void * param)
128 if (depth < 8) 116 if (depth < 8)
129 depth = 16; 117 depth = 16;
130 118
131 flags = SDL_HWSURFACE|SDL_DOUBLEBUF;
132#if (CONFIG_PLATFORM & (PLATFORM_MAEMO|PLATFORM_PANDORA)) 119#if (CONFIG_PLATFORM & (PLATFORM_MAEMO|PLATFORM_PANDORA))
133 /* Fullscreen mode for maemo app */ 120 /* Fullscreen mode for maemo app */
134 flags |= SDL_FULLSCREEN; 121 flags |= SDL_WINDOW_FULLSCREEN;
135#endif 122#endif
136 123
137 SDL_WM_SetCaption(UI_TITLE, NULL); 124 if ((window = SDL_CreateWindow(UI_TITLE, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
138 125 width * display_zoom, height * display_zoom , flags)) == NULL)
139 if ((gui_surface = SDL_SetVideoMode(width * display_zoom, height * display_zoom, depth, flags)) == NULL) { 126 panicf("%s", SDL_GetError());
127 if ((sdlRenderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_PRESENTVSYNC)) == NULL)
140 panicf("%s", SDL_GetError()); 128 panicf("%s", SDL_GetError());
129 if ((gui_surface = SDL_CreateRGBSurface(0, width * display_zoom, height * display_zoom, depth,
130 0, 0, 0, 0)) == NULL)
131 panicf("%s", SDL_GetError());
132
133 /* If we have a background, blit it over to the display surface */
134 if (background && picture_surface)
135 {
136 SDL_BlitSurface(picture_surface, NULL, gui_surface, NULL);
137 SDL_FreeSurface(picture_surface);
141 } 138 }
139}
140
141/*
142 * This thread will read the buttons in an interrupt like fashion, and
143 * also initializes SDL_INIT_VIDEO and the surfaces
144 *
145 * it must be done in the same thread (at least on windows) because events only
146 * work in the thread that called SDL_InitSubSystem(SDL_INIT_VIDEO)
147 *
148 * This is an SDL thread and relies on preemptive behavoir of the host
149 **/
150static int sdl_event_thread(void * param)
151{
152#ifdef __WIN32 /* Fails on Linux and MacOS */
153 SDL_InitSubSystem(SDL_INIT_VIDEO);
154 sdl_window_setup();
155#endif
156
157#if (CONFIG_PLATFORM & PLATFORM_MAEMO)
158 SDL_sem *wait_for_maemo_startup;
159#endif
142 160
143#if (CONFIG_PLATFORM & (PLATFORM_MAEMO|PLATFORM_PANDORA)) 161#if (CONFIG_PLATFORM & (PLATFORM_MAEMO|PLATFORM_PANDORA))
144 /* SDL touch screen fix: Work around a SDL assumption that returns 162 /* SDL touch screen fix: Work around a SDL assumption that returns
@@ -152,14 +170,10 @@ static int sdl_event_thread(void * param)
152 SDL_SetCursor(hiddenCursor); 170 SDL_SetCursor(hiddenCursor);
153#endif 171#endif
154 172
155 if (background && picture_surface != NULL)
156 SDL_BlitSurface(picture_surface, NULL, gui_surface, NULL);
157
158#if (CONFIG_PLATFORM & PLATFORM_MAEMO) 173#if (CONFIG_PLATFORM & PLATFORM_MAEMO)
159 /* start maemo thread: Listen to display on/off events and battery monitoring */ 174 /* start maemo thread: Listen to display on/off events and battery monitoring */
160 wait_for_maemo_startup = SDL_CreateSemaphore(0); /* 0-count so it blocks */ 175 wait_for_maemo_startup = SDL_CreateSemaphore(0); /* 0-count so it blocks */
161 SDL_Thread *maemo_thread = SDL_CreateThread(maemo_thread_func, wait_for_maemo_startup); 176 SDL_Thread *maemo_thread = SDL_CreateThread(maemo_thread_func, NULL, wait_for_maemo_startup);
162
163 SDL_SemWait(wait_for_maemo_startup); 177 SDL_SemWait(wait_for_maemo_startup);
164 SDL_DestroySemaphore(wait_for_maemo_startup); 178 SDL_DestroySemaphore(wait_for_maemo_startup);
165#endif 179#endif
@@ -184,9 +198,6 @@ static int sdl_event_thread(void * param)
184 SDL_FreeCursor(hiddenCursor); 198 SDL_FreeCursor(hiddenCursor);
185#endif 199#endif
186 200
187 if(picture_surface)
188 SDL_FreeSurface(picture_surface);
189
190 /* Order here is relevent to prevent deadlocks and use of destroyed 201 /* Order here is relevent to prevent deadlocks and use of destroyed
191 sync primitives by kernel threads */ 202 sync primitives by kernel threads */
192#ifdef HAVE_SDL_THREADS 203#ifdef HAVE_SDL_THREADS
@@ -251,15 +262,16 @@ void system_init(void)
251 g_type_init(); 262 g_type_init();
252#endif 263#endif
253 264
254 if (SDL_Init(SDL_INIT_TIMER)) 265 if (SDL_InitSubSystem(SDL_INIT_TIMER))
255 panicf("%s", SDL_GetError()); 266 panicf("%s", SDL_GetError());
256 267
257 s = SDL_CreateSemaphore(0); /* 0-count so it blocks */ 268#ifndef __WIN32 /* Fails on Windows */
258 269 SDL_InitSubSystem(SDL_INIT_VIDEO);
259 evt_thread = SDL_CreateThread(sdl_event_thread, s); 270 sdl_window_setup();
271#endif
260 272
261 /* wait for sdl_event_thread to run so that it can initialize the surfaces 273 s = SDL_CreateSemaphore(0); /* 0-count so it blocks */
262 * and video subsystem needed for SDL events */ 274 evt_thread = SDL_CreateThread(sdl_event_thread, NULL, s);
263 SDL_SemWait(s); 275 SDL_SemWait(s);
264 /* cleanup */ 276 /* cleanup */
265 SDL_DestroySemaphore(s); 277 SDL_DestroySemaphore(s);
@@ -303,29 +315,29 @@ int hostfs_flush(void)
303 315
304void sys_handle_argv(int argc, char *argv[]) 316void sys_handle_argv(int argc, char *argv[])
305{ 317{
306 if (argc >= 1) 318 if (argc >= 1)
307 { 319 {
308 int x; 320 int x;
309 for (x = 1; x < argc; x++) 321 for (x = 1; x < argc; x++)
310 { 322 {
311#ifdef DEBUG 323#ifdef DEBUG
312 if (!strcmp("--debugaudio", argv[x])) 324 if (!strcmp("--debugaudio", argv[x]))
313 { 325 {
314 debug_audio = true; 326 debug_audio = true;
315 printf("Writing debug audio file.\n"); 327 printf("Writing debug audio file.\n");
316 } 328 }
317 else 329 else
318#endif 330#endif
319 if (!strcmp("--debugwps", argv[x])) 331 if (!strcmp("--debugwps", argv[x]))
320 { 332 {
321 debug_wps = true; 333 debug_wps = true;
322 printf("WPS debug mode enabled.\n"); 334 printf("WPS debug mode enabled.\n");
323 } 335 }
324 else if (!strcmp("--nobackground", argv[x])) 336 else if (!strcmp("--nobackground", argv[x]))
325 { 337 {
326 background = false; 338 background = false;
327 printf("Disabling background image.\n"); 339 printf("Disabling background image.\n");
328 } 340 }
329#ifdef HAVE_REMOTE_LCD 341#ifdef HAVE_REMOTE_LCD
330 else if (!strcmp("--noremote", argv[x])) 342 else if (!strcmp("--noremote", argv[x]))
331 { 343 {
@@ -346,7 +358,7 @@ void sys_handle_argv(int argc, char *argv[])
346 display_zoom=atof(argv[x]); 358 display_zoom=atof(argv[x]);
347 else 359 else
348 display_zoom = 2; 360 display_zoom = 2;
349 printf("Window zoom is %d\n", display_zoom); 361 printf("Window zoom is %f\n", display_zoom);
350 } 362 }
351 else if (!strcmp("--alarm", argv[x])) 363 else if (!strcmp("--alarm", argv[x]))
352 { 364 {
@@ -372,7 +384,7 @@ void sys_handle_argv(int argc, char *argv[])
372 debug_buttons = true; 384 debug_buttons = true;
373 printf("Printing background button clicks.\n"); 385 printf("Printing background button clicks.\n");
374 } 386 }
375 else 387 else
376 { 388 {
377 printf("rockboxui\n"); 389 printf("rockboxui\n");
378 printf("Arguments:\n"); 390 printf("Arguments:\n");
diff --git a/firmware/target/hosted/sdl/thread-sdl.c b/firmware/target/hosted/sdl/thread-sdl.c
index 17a0f847b5..abd6339cee 100644
--- a/firmware/target/hosted/sdl/thread-sdl.c
+++ b/firmware/target/hosted/sdl/thread-sdl.c
@@ -340,7 +340,7 @@ unsigned int create_thread(void (*function)(void),
340 return 0; 340 return 0;
341 } 341 }
342 342
343 SDL_Thread *t = SDL_CreateThread(runthread, thread); 343 SDL_Thread *t = SDL_CreateThread(runthread, NULL, thread);
344 if (t == NULL) 344 if (t == NULL)
345 { 345 {
346 DEBUGF("Failed to create SDL thread\n"); 346 DEBUGF("Failed to create SDL thread\n");
@@ -447,7 +447,7 @@ void init_threads(void)
447 thread->context.s = SDL_CreateSemaphore(0); 447 thread->context.s = SDL_CreateSemaphore(0);
448 thread->context.t = NULL; /* NULL for the implicit main thread */ 448 thread->context.t = NULL; /* NULL for the implicit main thread */
449 __running_self_entry() = thread; 449 __running_self_entry() = thread;
450 450
451 if (thread->context.s == NULL) 451 if (thread->context.s == NULL)
452 { 452 {
453 fprintf(stderr, "Failed to create main semaphore\n"); 453 fprintf(stderr, "Failed to create main semaphore\n");
diff --git a/firmware/target/mips/ingenic_jz47xx/app.lds b/firmware/target/mips/ingenic_jz47xx/app.lds
index 1d300fed82..29a973a0ca 100644
--- a/firmware/target/mips/ingenic_jz47xx/app.lds
+++ b/firmware/target/mips/ingenic_jz47xx/app.lds
@@ -37,15 +37,11 @@ SECTIONS
37{ 37{
38 . = DRAMORIG; 38 . = DRAMORIG;
39 39
40 .startup : 40 .text :
41 { 41 {
42 loadaddress = .; 42 loadaddress = .;
43 _loadaddress = .; 43 _loadaddress = .;
44 *(.startup.text); 44 *(.init.text);
45 } > DRAM
46
47 .text :
48 {
49 *(.text*); 45 *(.text*);
50#ifndef HAVE_INIT_ATTR 46#ifndef HAVE_INIT_ATTR
51 *(.init*); 47 *(.init*);
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
index 5f320f8e9b..77fd5c013b 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4740.c
@@ -84,7 +84,7 @@ struct nand_param
84 * 84 *
85 */ 85 */
86 86
87static volatile unsigned long nand_address; 87static volatile sector_t nand_address;
88#define NAND_DATAPORT (nand_address) 88#define NAND_DATAPORT (nand_address)
89#define NAND_ADDRPORT (nand_address+0x10000) 89#define NAND_ADDRPORT (nand_address+0x10000)
90#define NAND_COMMPORT (nand_address+0x08000) 90#define NAND_COMMPORT (nand_address+0x08000)
@@ -111,7 +111,7 @@ static volatile unsigned long nand_address;
111static struct nand_info* chip_info = NULL; 111static struct nand_info* chip_info = NULL;
112static struct nand_info* banks[4]; 112static struct nand_info* banks[4];
113static unsigned int nr_banks = 1; 113static unsigned int nr_banks = 1;
114static unsigned long bank_size; 114static sector_t bank_size;
115static struct nand_param internal_param; 115static struct nand_param internal_param;
116static struct mutex nand_mtx; 116static struct mutex nand_mtx;
117#ifdef USE_DMA 117#ifdef USE_DMA
@@ -282,7 +282,7 @@ static void jz_rs_correct(unsigned char *dat, int idx, int mask)
282/* 282/*
283 * Read oob 283 * Read oob
284 */ 284 */
285static int jz_nand_read_oob(unsigned long page_addr, unsigned char *buf, int size) 285static int jz_nand_read_oob(sector_t page_addr, unsigned char *buf, int size)
286{ 286{
287 struct nand_param *nandp = &internal_param; 287 struct nand_param *nandp = &internal_param;
288 int page_size, row_cycle, bus_width; 288 int page_size, row_cycle, bus_width;
@@ -338,7 +338,7 @@ static int jz_nand_read_oob(unsigned long page_addr, unsigned char *buf, int siz
338 * page - page number within a block: 0, 1, 2, ... 338 * page - page number within a block: 0, 1, 2, ...
339 * dst - pointer to target buffer 339 * dst - pointer to target buffer
340 */ 340 */
341static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst) 341static int jz_nand_read_page(sector_t page_addr, unsigned char *dst)
342{ 342{
343 struct nand_param *nandp = &internal_param; 343 struct nand_param *nandp = &internal_param;
344 int page_size, oob_size; 344 int page_size, oob_size;
@@ -611,7 +611,7 @@ int nand_init(void)
611 return res; 611 return res;
612} 612}
613 613
614static inline int read_sector(unsigned long start, unsigned int count, 614static inline int read_sector(sector_t start, unsigned int count,
615 void* buf, unsigned int chip_size) 615 void* buf, unsigned int chip_size)
616{ 616{
617 register int ret; 617 register int ret;
@@ -627,14 +627,14 @@ static inline int read_sector(unsigned long start, unsigned int count,
627 return ret; 627 return ret;
628} 628}
629 629
630int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* buf) 630int nand_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf)
631{ 631{
632#ifdef HAVE_MULTIVOLUME 632#ifdef HAVE_MULTIDRIVE
633 (void)drive; 633 (void)drive;
634#endif 634#endif
635 int ret = 0; 635 int ret = 0;
636 unsigned int i, _count, chip_size = chip_info->page_size; 636 unsigned int i, _count, chip_size = chip_info->page_size;
637 unsigned long _start; 637 sector_t _start;
638 638
639 logf("start"); 639 logf("start");
640 mutex_lock(&nand_mtx); 640 mutex_lock(&nand_mtx);
@@ -670,12 +670,12 @@ int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* bu
670} 670}
671 671
672/* TODO */ 672/* TODO */
673int nand_write_sectors(IF_MV(int drive,) unsigned long start, int count, const void* buf) 673int nand_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf)
674{ 674{
675 (void)start; 675 (void)start;
676 (void)count; 676 (void)count;
677 (void)buf; 677 (void)buf;
678#ifdef HAVE_MULTIVOLUME 678#ifdef HAVE_MULTIDRIVE
679 (void)drive; 679 (void)drive;
680#endif 680#endif
681 681
@@ -727,9 +727,9 @@ void nand_sleepnow(void)
727} 727}
728 728
729#ifdef STORAGE_GET_INFO 729#ifdef STORAGE_GET_INFO
730void nand_get_info(IF_MV(int drive,) struct storage_info *info) 730void nand_get_info(IF_MD(int drive,) struct storage_info *info)
731{ 731{
732#ifdef HAVE_MULTIVOLUME 732#ifdef HAVE_MULTIDRIVE
733 (void)drive; 733 (void)drive;
734#endif 734#endif
735 735
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c
index efce5742d0..ff9b7e419e 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-nand-jz4760.c
@@ -110,7 +110,7 @@ struct nand_param {
110 110
111static struct nand_info* chip_info = NULL; 111static struct nand_info* chip_info = NULL;
112static struct nand_info* bank; 112static struct nand_info* bank;
113static unsigned long nand_size; 113static sector_t nand_size;
114static struct nand_param internal_param; 114static struct nand_param internal_param;
115static struct mutex nand_mtx; 115static struct mutex nand_mtx;
116#ifdef USE_DMA 116#ifdef USE_DMA
@@ -281,7 +281,7 @@ static void jz_rs_correct(unsigned char *dat, int idx, int mask)
281/* 281/*
282 * Read oob 282 * Read oob
283 */ 283 */
284static int jz_nand_read_oob(unsigned long page_addr, unsigned char *buf, int size) 284static int jz_nand_read_oob(sector_t page_addr, unsigned char *buf, int size)
285{ 285{
286 struct nand_param *nandp = &internal_param; 286 struct nand_param *nandp = &internal_param;
287 int page_size, row_cycle, bus_width; 287 int page_size, row_cycle, bus_width;
@@ -337,7 +337,7 @@ static int jz_nand_read_oob(unsigned long page_addr, unsigned char *buf, int siz
337 * page - page number within a block: 0, 1, 2, ... 337 * page - page number within a block: 0, 1, 2, ...
338 * dst - pointer to target buffer 338 * dst - pointer to target buffer
339 */ 339 */
340static int jz_nand_read_page(unsigned long page_addr, unsigned char *dst) 340static int jz_nand_read_page(sector_t page_addr, unsigned char *dst)
341{ 341{
342 struct nand_param *nandp = &internal_param; 342 struct nand_param *nandp = &internal_param;
343 int page_size, oob_size; 343 int page_size, oob_size;
@@ -532,7 +532,7 @@ int nand_init(void)
532 return res; 532 return res;
533} 533}
534 534
535static inline int read_sector(unsigned long start, unsigned int count, 535static inline int read_sector(sector_t start, unsigned int count,
536 void* buf, unsigned int chip_size) 536 void* buf, unsigned int chip_size)
537{ 537{
538 register int ret; 538 register int ret;
@@ -548,7 +548,7 @@ static inline int read_sector(unsigned long start, unsigned int count,
548 return ret; 548 return ret;
549} 549}
550 550
551static inline int write_sector(unsigned long start, unsigned int count, 551static inline int write_sector(sector_t start, unsigned int count,
552 const void* buf, unsigned int chip_size) 552 const void* buf, unsigned int chip_size)
553{ 553{
554 int ret = 0; 554 int ret = 0;
@@ -563,14 +563,14 @@ static inline int write_sector(unsigned long start, unsigned int count,
563 return ret; 563 return ret;
564} 564}
565 565
566int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* buf) 566int nand_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf)
567{ 567{
568#ifdef HAVE_MULTIVOLUME 568#ifdef HAVE_MULTIDRIVE
569 (void)drive; 569 (void)drive;
570#endif 570#endif
571 int ret = 0; 571 int ret = 0;
572 unsigned int _count, chip_size = chip_info->page_size; 572 unsigned int _count, chip_size = chip_info->page_size;
573 unsigned long _start; 573 sector_t _start;
574 574
575 logf("start"); 575 logf("start");
576 mutex_lock(&nand_mtx); 576 mutex_lock(&nand_mtx);
@@ -590,14 +590,14 @@ int nand_read_sectors(IF_MV(int drive,) unsigned long start, int count, void* bu
590 return ret; 590 return ret;
591} 591}
592 592
593int nand_write_sectors(IF_MV(int drive,) unsigned long start, int count, const void* buf) 593int nand_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf)
594{ 594{
595#ifdef HAVE_MULTIVOLUME 595#ifdef HAVE_MULTIDRIVE
596 (void)drive; 596 (void)drive;
597#endif 597#endif
598 int ret = 0; 598 int ret = 0;
599 unsigned int _count, chip_size = chip_info->page_size; 599 unsigned int _count, chip_size = chip_info->page_size;
600 unsigned long _start; 600 sector_t _start;
601 601
602 logf("start"); 602 logf("start");
603 mutex_lock(&nand_mtx); 603 mutex_lock(&nand_mtx);
@@ -662,9 +662,9 @@ void nand_sleepnow(void)
662} 662}
663 663
664#ifdef STORAGE_GET_INFO 664#ifdef STORAGE_GET_INFO
665void nand_get_info(IF_MV(int drive,) struct storage_info *info) 665void nand_get_info(IF_MD(int drive,) struct storage_info *info)
666{ 666{
667#ifdef HAVE_MULTIVOLUME 667#ifdef HAVE_MULTIDRIVE
668 (void)drive; 668 (void)drive;
669#endif 669#endif
670 670
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
index 56dd50814a..066be4e987 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4740.c
@@ -42,7 +42,6 @@ static struct mutex sd_mtx;
42 42
43static int use_4bit; 43static int use_4bit;
44static int num_6; 44static int num_6;
45static int sd2_0;
46 45
47//#define SD_DMA_ENABLE 46//#define SD_DMA_ENABLE
48#define SD_DMA_INTERRUPT 0 47#define SD_DMA_INTERRUPT 0
@@ -598,7 +597,7 @@ static int jz_sd_transmit_data(struct sd_request *req)
598static inline unsigned int jz_sd_calc_clkrt(unsigned int rate) 597static inline unsigned int jz_sd_calc_clkrt(unsigned int rate)
599{ 598{
600 unsigned int clkrt; 599 unsigned int clkrt;
601 unsigned int clk_src = sd2_0 ? SD_CLOCK_HIGH : SD_CLOCK_FAST; 600 unsigned int clk_src = card.sd2plus ? SD_CLOCK_HIGH : SD_CLOCK_FAST;
602 601
603 clkrt = 0; 602 clkrt = 0;
604 while (rate < clk_src) 603 while (rate < clk_src)
@@ -716,7 +715,7 @@ static int jz_sd_exec_cmd(struct sd_request *request)
716 events = SD_EVENT_RX_DATA_DONE; 715 events = SD_EVENT_RX_DATA_DONE;
717 break; 716 break;
718 717
719 case 6: 718 case SD_SWITCH_FUNC:
720 if (num_6 < 2) 719 if (num_6 < 2)
721 { 720 {
722#if defined(SD_DMA_ENABLE) 721#if defined(SD_DMA_ENABLE)
@@ -1086,7 +1085,6 @@ static int sd_init_card_state(struct sd_request *request)
1086 (request->response[3+i*4]<< 8) | request->response[4+i*4]); 1085 (request->response[3+i*4]<< 8) | request->response[4+i*4]);
1087 1086
1088 sd_parse_csd(&card); 1087 sd_parse_csd(&card);
1089 sd2_0 = (card_extract_bits(card.csd, 127, 2) == 1);
1090 1088
1091 logf("CSD: %08lx%08lx%08lx%08lx", card.csd[0], card.csd[1], card.csd[2], card.csd[3]); 1089 logf("CSD: %08lx%08lx%08lx%08lx", card.csd[0], card.csd[1], card.csd[2], card.csd[3]);
1092 DEBUG("SD card is ready"); 1090 DEBUG("SD card is ready");
@@ -1155,7 +1153,7 @@ static int sd_select_card(void)
1155 if (retval) 1153 if (retval)
1156 return retval; 1154 return retval;
1157 1155
1158 if (sd2_0) 1156 if (card.sd2plus)
1159 { 1157 {
1160 retval = sd_read_switch(&request); 1158 retval = sd_read_switch(&request);
1161 if (!retval) 1159 if (!retval)
@@ -1188,7 +1186,6 @@ static int __sd_init_device(void)
1188 /* Initialise card data as blank */ 1186 /* Initialise card data as blank */
1189 memset(&card, 0, sizeof(tCardInfo)); 1187 memset(&card, 0, sizeof(tCardInfo));
1190 1188
1191 sd2_0 = 0;
1192 num_6 = 0; 1189 num_6 = 0;
1193 use_4bit = 0; 1190 use_4bit = 0;
1194 1191
@@ -1250,9 +1247,9 @@ static inline void sd_stop_transfer(void)
1250 mutex_unlock(&sd_mtx); 1247 mutex_unlock(&sd_mtx);
1251} 1248}
1252 1249
1253int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) 1250int sd_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf)
1254{ 1251{
1255#ifdef HAVE_MULTIVOLUME 1252#ifdef HAVE_MULTIDRIVE
1256 (void)drive; 1253 (void)drive;
1257#endif 1254#endif
1258 sd_start_transfer(); 1255 sd_start_transfer();
@@ -1276,7 +1273,8 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf)
1276 if ((retval = sd_unpack_r1(&request, &r1))) 1273 if ((retval = sd_unpack_r1(&request, &r1)))
1277 goto err; 1274 goto err;
1278 1275
1279 if (sd2_0) 1276 // XXX 64-bit
1277 if (card.sd2plus)
1280 { 1278 {
1281 sd_send_cmd(&request, SD_READ_MULTIPLE_BLOCK, start, 1279 sd_send_cmd(&request, SD_READ_MULTIPLE_BLOCK, start,
1282 count, SD_BLOCK_SIZE, RESPONSE_R1, buf); 1280 count, SD_BLOCK_SIZE, RESPONSE_R1, buf);
@@ -1292,21 +1290,20 @@ int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf)
1292 goto err; 1290 goto err;
1293 } 1291 }
1294 1292
1295 last_disk_activity = current_tick;
1296
1297 sd_simple_cmd(&request, SD_STOP_TRANSMISSION, 0, RESPONSE_R1B); 1293 sd_simple_cmd(&request, SD_STOP_TRANSMISSION, 0, RESPONSE_R1B);
1298 if ((retval = sd_unpack_r1(&request, &r1))) 1294 if ((retval = sd_unpack_r1(&request, &r1)))
1299 goto err; 1295 goto err;
1300 1296
1301err: 1297err:
1298 last_disk_activity = current_tick;
1302 sd_stop_transfer(); 1299 sd_stop_transfer();
1303 1300
1304 return retval; 1301 return retval;
1305} 1302}
1306 1303
1307int sd_write_sectors(IF_MV(int drive,) unsigned long start, int count, const void* buf) 1304int sd_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf)
1308{ 1305{
1309#ifdef HAVE_MULTIVOLUME 1306#ifdef HAVE_MULTIDRIVE
1310 (void)drive; 1307 (void)drive;
1311#endif 1308#endif
1312 sd_start_transfer(); 1309 sd_start_transfer();
@@ -1330,7 +1327,8 @@ int sd_write_sectors(IF_MV(int drive,) unsigned long start, int count, const voi
1330 if ((retval = sd_unpack_r1(&request, &r1))) 1327 if ((retval = sd_unpack_r1(&request, &r1)))
1331 goto err; 1328 goto err;
1332 1329
1333 if (sd2_0) 1330 // XXX 64-bit
1331 if (card.sd2plus)
1334 { 1332 {
1335 sd_send_cmd(&request, SD_WRITE_MULTIPLE_BLOCK, start, 1333 sd_send_cmd(&request, SD_WRITE_MULTIPLE_BLOCK, start,
1336 count, SD_BLOCK_SIZE, RESPONSE_R1, 1334 count, SD_BLOCK_SIZE, RESPONSE_R1,
@@ -1387,7 +1385,7 @@ int sd_soft_reset(void)
1387#ifdef HAVE_HOTSWAP 1385#ifdef HAVE_HOTSWAP
1388bool sd_removable(IF_MD_NONVOID(int drive)) 1386bool sd_removable(IF_MD_NONVOID(int drive))
1389{ 1387{
1390#ifdef HAVE_MULTIVOLUME 1388#ifdef HAVE_MULTIDRIVE
1391 (void)drive; 1389 (void)drive;
1392#endif 1390#endif
1393 return true; 1391 return true;
@@ -1415,7 +1413,7 @@ void MMC_CD_IRQ(void)
1415} 1413}
1416#endif 1414#endif
1417 1415
1418bool sd_present(IF_MV_NONVOID(int drive)) 1416bool sd_present(IF_MD_NONVOID(int drive))
1419{ 1417{
1420#ifdef HAVE_MULTIDRIVE 1418#ifdef HAVE_MULTIDRIVE
1421 (void)drive; 1419 (void)drive;
diff --git a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c
index 1960fcbd35..3810852686 100644
--- a/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c
+++ b/firmware/target/mips/ingenic_jz47xx/ata-sd-jz4760.c
@@ -57,8 +57,6 @@ static struct semaphore sd_wakeup[NUM_DRIVES];
57 57
58static int use_4bit[NUM_DRIVES]; 58static int use_4bit[NUM_DRIVES];
59static int num_6[NUM_DRIVES]; 59static int num_6[NUM_DRIVES];
60static int sd2_0[NUM_DRIVES];
61
62 60
63//#define DEBUG(x...) logf(x) 61//#define DEBUG(x...) logf(x)
64#define DEBUG(x, ...) 62#define DEBUG(x, ...)
@@ -698,7 +696,7 @@ static inline unsigned int jz_sd_calc_clkrt(const int drive, unsigned int rate)
698 unsigned int clkrt = 0; 696 unsigned int clkrt = 0;
699 unsigned int clk_src = cpu_frequency / __cpm_get_mscdiv(); /* MSC_CLK */ 697 unsigned int clk_src = cpu_frequency / __cpm_get_mscdiv(); /* MSC_CLK */
700 698
701 if (!sd2_0[drive] && rate > SD_CLOCK_FAST) 699 if (!card[drive].sd2plus && rate > SD_CLOCK_FAST)
702 rate = SD_CLOCK_FAST; 700 rate = SD_CLOCK_FAST;
703 701
704 while (rate < clk_src) 702 while (rate < clk_src)
@@ -1192,7 +1190,6 @@ static int sd_init_card_state(const int drive, struct sd_request *request)
1192 (request->response[3+i*4]<< 8) | request->response[4+i*4]); 1190 (request->response[3+i*4]<< 8) | request->response[4+i*4]);
1193 1191
1194 sd_parse_csd(&card[drive]); 1192 sd_parse_csd(&card[drive]);
1195 sd2_0[drive] = (card_extract_bits(card[drive].csd, 127, 2) == 1);
1196 1193
1197 logf("CSD: %08lx%08lx%08lx%08lx", card[drive].csd[0], card[drive].csd[1], card[drive].csd[2], card[drive].csd[3]); 1194 logf("CSD: %08lx%08lx%08lx%08lx", card[drive].csd[0], card[drive].csd[1], card[drive].csd[2], card[drive].csd[3]);
1198 DEBUG("SD card is ready"); 1195 DEBUG("SD card is ready");
@@ -1261,7 +1258,7 @@ static int sd_select_card(const int drive)
1261 if (retval) 1258 if (retval)
1262 return retval; 1259 return retval;
1263 1260
1264 if (sd2_0[drive]) 1261 if (card[drive].sd2plus)
1265 { 1262 {
1266 retval = sd_read_switch(drive, &request); 1263 retval = sd_read_switch(drive, &request);
1267 if (!retval) 1264 if (!retval)
@@ -1292,7 +1289,6 @@ static int __sd_init_device(const int drive)
1292 /* Initialise card data as blank */ 1289 /* Initialise card data as blank */
1293 memset(&card[drive], 0, sizeof(tCardInfo)); 1290 memset(&card[drive], 0, sizeof(tCardInfo));
1294 1291
1295 sd2_0[drive] = 0;
1296 num_6[drive] = 0; 1292 num_6[drive] = 0;
1297 use_4bit[drive] = 0; 1293 use_4bit[drive] = 0;
1298 active[drive] = 0; 1294 active[drive] = 0;
@@ -1402,7 +1398,7 @@ static inline void sd_stop_transfer(const int drive)
1402 mutex_unlock(&sd_mtx[drive]); 1398 mutex_unlock(&sd_mtx[drive]);
1403} 1399}
1404 1400
1405int sd_transfer_sectors(IF_MD(const int drive,) unsigned long start, int count, void* buf, bool write) 1401int sd_transfer_sectors(IF_MD(const int drive,) sector_t start, int count, void* buf, bool write)
1406{ 1402{
1407 struct sd_request request; 1403 struct sd_request request;
1408 struct sd_response_r1 r1; 1404 struct sd_response_r1 r1;
@@ -1427,11 +1423,12 @@ int sd_transfer_sectors(IF_MD(const int drive,) unsigned long start, int count,
1427 if ((retval = sd_unpack_r1(&request, &r1))) 1423 if ((retval = sd_unpack_r1(&request, &r1)))
1428 goto err; 1424 goto err;
1429 1425
1426 // XXX 64-bit
1430 sd_send_cmd(drive, &request, 1427 sd_send_cmd(drive, &request,
1431 (count > 1) ? 1428 (count > 1) ?
1432 (write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK) : 1429 (write ? SD_WRITE_MULTIPLE_BLOCK : SD_READ_MULTIPLE_BLOCK) :
1433 (write ? SD_WRITE_BLOCK : SD_READ_SINGLE_BLOCK), 1430 (write ? SD_WRITE_BLOCK : SD_READ_SINGLE_BLOCK),
1434 sd2_0[drive] ? start : (start * SD_BLOCK_SIZE), 1431 card[drive].sd2plus ? start : (start * SD_BLOCK_SIZE),
1435 count, SD_BLOCK_SIZE, RESPONSE_R1, buf); 1432 count, SD_BLOCK_SIZE, RESPONSE_R1, buf);
1436 if ((retval = sd_unpack_r1(&request, &r1))) 1433 if ((retval = sd_unpack_r1(&request, &r1)))
1437 goto err; 1434 goto err;
@@ -1451,12 +1448,12 @@ err:
1451 return retval; 1448 return retval;
1452} 1449}
1453 1450
1454int sd_read_sectors(IF_MD(int drive,) unsigned long start, int count, void* buf) 1451int sd_read_sectors(IF_MD(int drive,) sector_t start, int count, void* buf)
1455{ 1452{
1456 return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false); 1453 return sd_transfer_sectors(IF_MD(drive,) start, count, buf, false);
1457} 1454}
1458 1455
1459int sd_write_sectors(IF_MD(int drive,) unsigned long start, int count, const void* buf) 1456int sd_write_sectors(IF_MD(int drive,) sector_t start, int count, const void* buf)
1460{ 1457{
1461 return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true); 1458 return sd_transfer_sectors(IF_MD(drive,) start, count, (void*)buf, true);
1462} 1459}
diff --git a/firmware/target/mips/ingenic_jz47xx/crt0.S b/firmware/target/mips/ingenic_jz47xx/crt0.S
index b73a43d8f2..ee203b3b4d 100644
--- a/firmware/target/mips/ingenic_jz47xx/crt0.S
+++ b/firmware/target/mips/ingenic_jz47xx/crt0.S
@@ -44,7 +44,7 @@
44 .extern main 44 .extern main
45 .global _start 45 .global _start
46 46
47 .section .startup.text,"ax",%progbits 47 .section .init.text
48 .set push 48 .set push
49 .set mips32 49 .set mips32
50 .set noreorder 50 .set noreorder
diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/power-xduoo_x3.c b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/power-xduoo_x3.c
index 9ae602ba56..c9bcb47fcd 100644
--- a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/power-xduoo_x3.c
+++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/power-xduoo_x3.c
@@ -23,15 +23,19 @@
23#include "power.h" 23#include "power.h"
24#include "cpu.h" 24#include "cpu.h"
25 25
26#define CHARGE_STAT_GPIO (32*1+6) /* STAT port */ 26#define CHARGE_STAT_GPIO (32*1+6) /* STAT port */
27#define PIN_USB_DET (32*4+19) /* USB connected */
27 28
28/* Detect which power sources are present. */ 29/* Detect which power sources are present. */
29unsigned int power_input_status(void) 30unsigned int power_input_status(void)
30{ 31{
32 int rval = POWER_INPUT_NONE;
33 if(!__gpio_get_pin(PIN_USB_DET))
34 rval |= POWER_INPUT_USB;
31 if(!__gpio_get_pin(CHARGE_STAT_GPIO)) 35 if(!__gpio_get_pin(CHARGE_STAT_GPIO))
32 return POWER_INPUT_USB_CHARGER; 36 rval |= POWER_INPUT_USB_CHARGER;
33 37
34 return POWER_INPUT_NONE; 38 return rval;
35} 39}
36 40
37void power_init(void) 41void power_init(void)
@@ -42,5 +46,5 @@ void power_init(void)
42 46
43bool charging_state(void) 47bool charging_state(void)
44{ 48{
45 return (power_input_status() == POWER_INPUT_USB_CHARGER); 49 return (power_input_status() & POWER_INPUT_USB_CHARGER);
46} 50}
diff --git a/firmware/target/mips/ingenic_x1000/crt0.S b/firmware/target/mips/ingenic_x1000/crt0.S
index 6c0942b0db..23daaefb5e 100644
--- a/firmware/target/mips/ingenic_x1000/crt0.S
+++ b/firmware/target/mips/ingenic_x1000/crt0.S
@@ -23,6 +23,10 @@
23#include "mips.h" 23#include "mips.h"
24#include "bootdata.h" 24#include "bootdata.h"
25 25
26#if defined(HAVE_DEVICEDATA) && !defined(BOOTLOADER)
27#include "devicedata.h"
28#endif
29
26 .text 30 .text
27 .extern main 31 .extern main
28 .extern system_early_init 32 .extern system_early_init
@@ -52,6 +56,9 @@ _header:
52#ifndef BOOTLOADER 56#ifndef BOOTLOADER
53 /* Multiboot support header; this is not part of the above header. */ 57 /* Multiboot support header; this is not part of the above header. */
54 put_boot_data_here 58 put_boot_data_here
59#ifdef HAVE_DEVICEDATA
60 put_device_data_here
61#endif
55#endif 62#endif
56 63
57_realstart: 64_realstart:
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c
index df97aba0c8..6968a19a1c 100644
--- a/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c
+++ b/firmware/target/mips/ingenic_x1000/erosqnative/audiohw-erosqnative.c
@@ -104,6 +104,30 @@ void audiohw_postinit(void)
104 * for 24-bit data... */ 104 * for 24-bit data... */
105 // es9018k2m_write_reg(ES9018K2M_REG1_INPUT_CONFIG, 0b01001100); // 24-bit data 105 // es9018k2m_write_reg(ES9018K2M_REG1_INPUT_CONFIG, 0b01001100); // 24-bit data
106 106
107 /* Datasheet: Sets the number os FSR edges that must occur before *
108 * the DPLL and ASRC can lock on to the the incoming Signal. *
109 * When Samplerates >= 96khz could be used, STOP_DIV should be set *
110 * to 0 (= 16384 FSR Edges). *
111 * Reg #10 [3:0] (0x05 default, 2730 FSR Edges) */
112 es9018k2m_write_reg(ES9018K2M_REG10_MASTER_MODE_CTRL, 0x00);
113
114 /* Datasheet: The ES90x8Q2M/K2M contains a Jitter Eliminator block, *
115 * which employs the use of a digital phase locked loop (DPLL) to *
116 * lock to the incoming audio clock rate. When in I2S or SPDIF mode, *
117 * the DPLL will lock to the frame clock (1 x fs). However, when in *
118 * DSD mode, the DPLL has no frame clock information, and must in- *
119 * stead lock to the bit clock rate (BCK). For this reason, there are *
120 * two bandwidth settings for the DPLL. *
121 Reg #12 [7:4] (0x05 default) bandwidth for I2S / SPDIF mode.
122 Reg #12 [3:0] (0x0A default) bandwidth for DSD mode.
123 * The DPLL bandwidth sets how quickly the DPLL can adjust its intern *
124 * representation of the audio clock. The higher the jitter or *
125 * frequency drift on the audio clock, the higher the bandwidth must *
126 * be so that the DPLL can react. *
127 * ! If the bandwidth is “too low”, the DPLL will loose lock and you *
128 * ! will hear random dropouts. (Fixed my SurfansF20 v3.2 dropouts) */
129 es9018k2m_write_reg(ES9018K2M_REG12_DPLL_SETTINGS, 0xda);
130
107 } else { /* Default to SWVOL for PCM5102A DAC */ 131 } else { /* Default to SWVOL for PCM5102A DAC */
108 logf("Default to SWVOL: ret=%d", ret); 132 logf("Default to SWVOL: ret=%d", ret);
109 } 133 }
@@ -139,17 +163,19 @@ void audiohw_set_volume(int vol_l, int vol_r)
139 r = vol_r; 163 r = vol_r;
140 164
141#if (defined(HAVE_HEADPHONE_DETECTION) && defined(HAVE_LINEOUT_DETECTION)) 165#if (defined(HAVE_HEADPHONE_DETECTION) && defined(HAVE_LINEOUT_DETECTION))
142 /* make sure headphones aren't present - don't want to 166 /* Due to the hardware's detection method, make the Line-Out
143 * blow out our eardrums cranking it to full */ 167 * the default. The LO can only be detected if it is active
144 if (lineout_inserted() && !headphones_inserted()) 168 * (assuming a high-impedance device is attached). HP takes priority
169 * if both are present. */
170 if (headphones_inserted())
145 { 171 {
146 eros_qn_switch_output(1); 172 eros_qn_switch_output(0);
147
148 l = r = eros_qn_get_volume_limit();
149 } 173 }
150 else 174 else
151 { 175 {
152 eros_qn_switch_output(0); 176 eros_qn_switch_output(1);
177
178 l = r = eros_qn_get_volume_limit();
153 } 179 }
154#endif 180#endif
155 181
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c
index 0d2207af2a..707dc372a8 100644
--- a/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c
+++ b/firmware/target/mips/ingenic_x1000/erosqnative/button-erosqnative.c
@@ -75,12 +75,26 @@ volatile signed int enc_position = 0;
75/* Value of headphone detect register */ 75/* Value of headphone detect register */
76static uint8_t hp_detect_reg = 0x00; 76static uint8_t hp_detect_reg = 0x00;
77static uint8_t hp_detect_reg_old = 0x00; 77static uint8_t hp_detect_reg_old = 0x00;
78static uint8_t hp_detect_debounce1 = 0x00;
79static uint8_t hp_detect_debounce2 = 0x00;
80static uint8_t debounce_count = 0;
78 81
79/* Interval to poll the register */ 82/* Interval to poll the register */
80#define HPD_POLL_TIME (HZ/2) 83#define HPD_POLL_TIME (HZ/4)
81 84
82static int hp_detect_tmo_cb(struct timeout* tmo) 85static int hp_detect_tmo_cb(struct timeout* tmo)
83{ 86{
87 if (hp_detect_debounce1 == hp_detect_debounce2){
88 if (debounce_count >= 2){
89 debounce_count = 2;
90 } else {
91 debounce_count = debounce_count + 1;
92 }
93 } else {
94 debounce_count = 0;
95 hp_detect_debounce2 = hp_detect_debounce1;
96 }
97
84 i2c_descriptor* d = (i2c_descriptor*)tmo->data; 98 i2c_descriptor* d = (i2c_descriptor*)tmo->data;
85 i2c_async_queue(AXP_PMU_BUS, TIMEOUT_NOBLOCK, I2C_Q_ADD, 0, d); 99 i2c_async_queue(AXP_PMU_BUS, TIMEOUT_NOBLOCK, I2C_Q_ADD, 0, d);
86 return HPD_POLL_TIME; 100 return HPD_POLL_TIME;
@@ -96,7 +110,7 @@ static void hp_detect_init(void)
96 .tran_mode = I2C_READ, 110 .tran_mode = I2C_READ,
97 .buffer[0] = (void*)&gpio_reg, 111 .buffer[0] = (void*)&gpio_reg,
98 .count[0] = 1, 112 .count[0] = 1,
99 .buffer[1] = &hp_detect_reg, 113 .buffer[1] = &hp_detect_debounce1,
100 .count[1] = 1, 114 .count[1] = 1,
101 .callback = NULL, 115 .callback = NULL,
102 .arg = 0, 116 .arg = 0,
@@ -113,6 +127,8 @@ static void hp_detect_init(void)
113 if(r >= 0) 127 if(r >= 0)
114 { 128 {
115 hp_detect_reg = r; 129 hp_detect_reg = r;
130 hp_detect_debounce1 = r;
131 hp_detect_debounce2 = r;
116 hp_detect_reg_old = hp_detect_reg; 132 hp_detect_reg_old = hp_detect_reg;
117 } 133 }
118 134
@@ -122,6 +138,9 @@ static void hp_detect_init(void)
122 138
123bool headphones_inserted(void) 139bool headphones_inserted(void)
124{ 140{
141 if (debounce_count > 1){
142 hp_detect_reg = hp_detect_debounce2;
143 }
125 /* if the status has changed, set the output volume accordingly */ 144 /* if the status has changed, set the output volume accordingly */
126 if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30)) 145 if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30))
127 { 146 {
@@ -135,6 +154,9 @@ bool headphones_inserted(void)
135 154
136bool lineout_inserted(void) 155bool lineout_inserted(void)
137{ 156{
157 if (debounce_count > 1){
158 hp_detect_reg = hp_detect_debounce2;
159 }
138 /* if the status has changed, set the output volume accordingly */ 160 /* if the status has changed, set the output volume accordingly */
139 if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30)) 161 if ((hp_detect_reg & 0x30) != (hp_detect_reg_old & 0x30))
140 { 162 {
diff --git a/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c b/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c
index 0d43a3f010..bcc30a71bd 100644
--- a/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c
+++ b/firmware/target/mips/ingenic_x1000/erosqnative/lcd-erosqnative.c
@@ -25,11 +25,138 @@
25#include "lcd-x1000.h" 25#include "lcd-x1000.h"
26#include "gpio-x1000.h" 26#include "gpio-x1000.h"
27#include "system.h" 27#include "system.h"
28#include "devicedata.h"
28 29
29/* for reference on these command/data hex values, see the mipi dcs lcd spec. * 30/* for reference on these command/data hex values, see the mipi dcs lcd spec. *
30 * Not everything here is there, but all the standard stuff is. */ 31 * Not everything here is there, but all the standard stuff is. */
31 32
32static const uint32_t erosqnative_lcd_cmd_enable[] = { 33/* New Display Eroq 2.1 / Hifiwalker 1.7+ / Surfans v3.2, unknown Controller *
34 * (partially GC9A01 register compatible) *
35 * https://espruino.microcosm.app/api/v1/files/ \ *
36 * 9dc1b976d621a2ab3854312cce862c4a9a50dc1b.html#GC9A01 , *
37 * https://www.buydisplay.com/download/ic/GC9A01A.pdf , *
38 * https://lcddisplay.co/wp-content/uploads/2023/02/GC9A01.pdf *
39 * Init sequence From 'EROS Q (c口)_V2.1_20231209固件.zip' *
40 * update.upt/.iso -> In 'uboot.bin' at 0x52da0-0x5305f *
41 * http://www.eroshifi.com/download/firmware/122.html */
42static const uint32_t erosqnative_lcd_cmd_enable_v3[] = {
43
44 /* Unlock EXTC? */
45 LCD_INSTR_CMD, 0xfe, // Inter Register Enable1
46 LCD_INSTR_CMD, 0xef, // Inter Register Enable2
47
48 LCD_INSTR_CMD, 0x36, // Memory Access Control
49/* Bit7 1:vertical flip 0:no vertical flip
50 Bit6 1:horizontal flip 0:no horizontal flip
51 Bit3 1:BGR 0:RGB */
52 LCD_INSTR_DAT, 0x90,
53 /* Pixel Format Set */
54 LCD_INSTR_CMD, 0x3a,
55 LCD_INSTR_DAT, 0x55, /* Rockbox uses 16pp, OF specified 18 bpp */
56
57 LCD_INSTR_CMD, 0x84, // ?? (undocumented)
58 LCD_INSTR_DAT, 0x04,
59 LCD_INSTR_CMD, 0x86, // ??
60 LCD_INSTR_DAT, 0xfb,
61 LCD_INSTR_CMD, 0x87, // ??
62 LCD_INSTR_DAT, 0x79,
63 LCD_INSTR_CMD, 0x89, // ??
64 LCD_INSTR_DAT, 0x0b,
65 LCD_INSTR_CMD, 0x8a, // ??
66 LCD_INSTR_DAT, 0x20,
67 LCD_INSTR_CMD, 0x8b, // ??
68 LCD_INSTR_DAT, 0x80,
69 LCD_INSTR_CMD, 0x8d, // ??
70 LCD_INSTR_DAT, 0x3b,
71 LCD_INSTR_CMD, 0x8e, // ??
72 LCD_INSTR_DAT, 0xcf,
73
74 LCD_INSTR_CMD, 0xec, // Charge Pump Frequent Control
75 LCD_INSTR_DAT, 0x33,
76 LCD_INSTR_DAT, 0x02,
77 LCD_INSTR_DAT, 0x4c,
78
79 LCD_INSTR_CMD, 0x98, // ?? (undocumented)
80 LCD_INSTR_DAT, 0x3e,
81 LCD_INSTR_CMD, 0x9c, // ??
82 LCD_INSTR_DAT, 0x4b,
83 LCD_INSTR_CMD, 0x99, // ??
84 LCD_INSTR_DAT, 0x3e,
85 LCD_INSTR_CMD, 0x9d, // ??
86 LCD_INSTR_DAT, 0x4b,
87 LCD_INSTR_CMD, 0x9b, // ??
88 LCD_INSTR_DAT, 0x55,
89
90 LCD_INSTR_CMD, 0xe8, // Frame Rate
91 LCD_INSTR_DAT, 0x11,
92 LCD_INSTR_DAT, 0x00,
93
94 LCD_INSTR_CMD, 0xff, // ?? (Adafruit & Co lib. C:0xFF, D:0x60, D:0x01, D:0x04)
95 LCD_INSTR_DAT, 0x62, // LCD_INSTR_DAT, 0x01, LCD_INSTR_DAT, 0x04,
96 LCD_INSTR_CMD, 0xc3, // Vreg1a voltage Control
97 LCD_INSTR_DAT, 0x20,
98 LCD_INSTR_CMD, 0xc4, // Vreg1b voltage Control
99 LCD_INSTR_DAT, 0x03,
100 LCD_INSTR_CMD, 0xc9, // Vreg2a voltage Control
101 LCD_INSTR_DAT, 0x2a,
102
103 LCD_INSTR_CMD, 0xf0, // SET_GAMMA1
104 LCD_INSTR_DAT, 0x4a,
105 LCD_INSTR_DAT, 0x10,
106 LCD_INSTR_DAT, 0x0a,
107 LCD_INSTR_DAT, 0x0a,
108 LCD_INSTR_DAT, 0x26,
109 LCD_INSTR_DAT, 0x39,
110
111 LCD_INSTR_CMD, 0xf2, // SET_GAMMA3
112 LCD_INSTR_DAT, 0x4a,
113 LCD_INSTR_DAT, 0x10,
114 LCD_INSTR_DAT, 0x0a,
115 LCD_INSTR_DAT, 0x0a,
116 LCD_INSTR_DAT, 0x26,
117 LCD_INSTR_DAT, 0x39,
118
119 LCD_INSTR_CMD, 0xf1, // SET_GAMMA2
120 LCD_INSTR_DAT, 0x50,
121 LCD_INSTR_DAT, 0x8f,
122 LCD_INSTR_DAT, 0xaf,
123 LCD_INSTR_DAT, 0x3b,
124 LCD_INSTR_DAT, 0x3f,
125 LCD_INSTR_DAT, 0x7f,
126
127 LCD_INSTR_CMD, 0xf3, // SET_GAMMA4
128 LCD_INSTR_DAT, 0x50,
129 LCD_INSTR_DAT, 0x8f,
130 LCD_INSTR_DAT, 0xaf,
131 LCD_INSTR_DAT, 0x3b,
132 LCD_INSTR_DAT, 0x3f,
133 LCD_INSTR_DAT, 0x7f,
134
135 LCD_INSTR_CMD, 0xba, // TE Control
136 LCD_INSTR_DAT, 0x0a,
137
138#ifdef BOOTLOADER
139 LCD_INSTR_CMD, 0x35, // Tearing Effect Line ON
140 LCD_INSTR_DAT, 0x00,
141#endif
142
143 LCD_INSTR_CMD, 0x21, /* Invert */
144
145 /* Lock EXTC? */
146 LCD_INSTR_CMD, 0xfe, // Inter Register Enable1
147 LCD_INSTR_CMD, 0xee,
148
149 /* Exit Sleep */
150 LCD_INSTR_CMD, 0x11,
151 LCD_INSTR_UDELAY, 120000,
152 /* Display On */
153 LCD_INSTR_CMD, 0x29,
154 LCD_INSTR_UDELAY, 20000,
155 LCD_INSTR_END,
156};
157
158/* Original Display / Hifiwalker -1.5 / Surfans -2.7 */
159static const uint32_t erosqnative_lcd_cmd_enable_v1[] = {
33 /* Set EXTC? */ 160 /* Set EXTC? */
34 LCD_INSTR_CMD, 0xc8, 161 LCD_INSTR_CMD, 0xc8,
35 LCD_INSTR_DAT, 0xff, 162 LCD_INSTR_DAT, 0xff,
@@ -179,7 +306,22 @@ void lcd_tgt_enable(bool enable)
179 mdelay(5); 306 mdelay(5);
180 gpio_set_level(GPIO_LCD_CE, 0); 307 gpio_set_level(GPIO_LCD_CE, 0);
181 308
182 lcd_exec_commands(&erosqnative_lcd_cmd_enable[0]); 309#ifdef BOOTLOADER
310# if EROSQN_VER == 3
311 lcd_exec_commands(&erosqnative_lcd_cmd_enable_v3[0]);
312# else
313 lcd_exec_commands(&erosqnative_lcd_cmd_enable_v1[0]);
314# endif
315#else
316 if (device_data.lcd_version == 3)
317 {
318 lcd_exec_commands(&erosqnative_lcd_cmd_enable_v3[0]);
319 }
320 else
321 {
322 lcd_exec_commands(&erosqnative_lcd_cmd_enable_v1[0]);
323 }
324#endif
183 } else { 325 } else {
184 /* doesn't flash white if we don't do anything... */ 326 /* doesn't flash white if we don't do anything... */
185#if 0 327#if 0
diff --git a/firmware/target/mips/ingenic_x1000/msc-x1000.c b/firmware/target/mips/ingenic_x1000/msc-x1000.c
index 62172fa213..f0d417e4f7 100644
--- a/firmware/target/mips/ingenic_x1000/msc-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/msc-x1000.c
@@ -844,7 +844,7 @@ int msc_cmd_send_csd(msc_drv* d)
844 d->cardinfo.csd[i] = req.response[i]; 844 d->cardinfo.csd[i] = req.response[i];
845 sd_parse_csd(&d->cardinfo); 845 sd_parse_csd(&d->cardinfo);
846 846
847 if((req.response[0] >> 30) == 1) 847 if(d->cardinfo.sd2plus)
848 d->driver_flags |= MSC_DF_V2_CARD; 848 d->driver_flags |= MSC_DF_V2_CARD;
849 849
850 return 0; 850 return 0;
diff --git a/firmware/target/mips/ingenic_x1000/sd-x1000.c b/firmware/target/mips/ingenic_x1000/sd-x1000.c
index 679a25a222..c1aec59aa3 100644
--- a/firmware/target/mips/ingenic_x1000/sd-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/sd-x1000.c
@@ -51,7 +51,7 @@ static int sd_init_card(msc_drv* d)
51} 51}
52 52
53static int sd_transfer(msc_drv* d, bool write, 53static int sd_transfer(msc_drv* d, bool write,
54 unsigned long start, int count, void* buf) 54 sector_t start, int count, void* buf)
55{ 55{
56 int status = -1; 56 int status = -1;
57 57
@@ -114,6 +114,7 @@ static int sd_transfer(msc_drv* d, bool write,
114 : SD_READ_MULTIPLE_BLOCK; 114 : SD_READ_MULTIPLE_BLOCK;
115 } 115 }
116 116
117 // XXX 64-bit
117 if(d->driver_flags & MSC_DF_V2_CARD) 118 if(d->driver_flags & MSC_DF_V2_CARD)
118 req.argument = start; 119 req.argument = start;
119 else 120 else
@@ -142,14 +143,14 @@ static int sd_transfer(msc_drv* d, bool write,
142 return status; 143 return status;
143} 144}
144 145
145int sd_read_sectors(IF_MD(int drive,) unsigned long start, 146int sd_read_sectors(IF_MD(int drive,) sector_t start,
146 int count, void* buf) 147 int count, void* buf)
147{ 148{
148 return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], false, 149 return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], false,
149 start, count, buf); 150 start, count, buf);
150} 151}
151 152
152int sd_write_sectors(IF_MD(int drive,) unsigned long start, 153int sd_write_sectors(IF_MD(int drive,) sector_t start,
153 int count, const void* buf) 154 int count, const void* buf)
154{ 155{
155 return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], true, 156 return sd_transfer(sd_to_msc[IF_MD_DRV(drive)], true,
@@ -187,6 +188,9 @@ long sd_last_disk_activity(void)
187 188
188bool sd_present(IF_MD_NONVOID(int drive)) 189bool sd_present(IF_MD_NONVOID(int drive))
189{ 190{
191#ifndef HAVE_MULTIDRIVE
192 int drive = 0;
193#endif
190 /* Seems that volume_properties() in firmware/common/disk.c may pass 194 /* Seems that volume_properties() in firmware/common/disk.c may pass
191 * drive = -1 when the SD card is not inserted, so just return false. 195 * drive = -1 when the SD card is not inserted, so just return false.
192 */ 196 */
@@ -198,6 +202,10 @@ bool sd_present(IF_MD_NONVOID(int drive))
198 202
199bool sd_removable(IF_MD_NONVOID(int drive)) 203bool sd_removable(IF_MD_NONVOID(int drive))
200{ 204{
205#ifndef HAVE_MULTIDRIVE
206 int drive = 0;
207#endif
208
201 /* Same reason as sd_present() */ 209 /* Same reason as sd_present() */
202 if(drive < 0) 210 if(drive < 0)
203 return false; 211 return false;
diff --git a/firmware/target/mips/ingenic_x1000/system-x1000.c b/firmware/target/mips/ingenic_x1000/system-x1000.c
index 64890a6c3a..1c850736b6 100644
--- a/firmware/target/mips/ingenic_x1000/system-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/system-x1000.c
@@ -20,6 +20,7 @@
20 ****************************************************************************/ 20 ****************************************************************************/
21 21
22#include "system.h" 22#include "system.h"
23#include <string.h>
23#include "mips.h" 24#include "mips.h"
24#include "panic.h" 25#include "panic.h"
25#include "button.h" 26#include "button.h"
@@ -36,6 +37,10 @@
36#include "x1000/msc.h" 37#include "x1000/msc.h"
37#include "x1000/aic.h" 38#include "x1000/aic.h"
38 39
40#if defined(HAVE_DEVICEDATA)
41#include "devicedata.h"
42#endif
43
39#ifdef X1000_CPUIDLE_STATS 44#ifdef X1000_CPUIDLE_STATS
40int __cpu_idle_avg = 0; 45int __cpu_idle_avg = 0;
41int __cpu_idle_cur = 0; 46int __cpu_idle_cur = 0;
@@ -81,6 +86,20 @@ void system_early_init(void)
81 clk_init(); 86 clk_init();
82} 87}
83 88
89#if defined (HAVE_DEVICEDATA) && defined(EROS_QN)
90void fill_devicedata(struct device_data_t *data)
91{
92#ifdef BOOTLOADER
93 memset(data->payload, 0xff, data->length);
94 data->lcd_version = EROSQN_VER;
95#else
96 uint8_t lcd_version = device_data.lcd_version;
97 memset(data->payload, 0xff, data->length);
98 data->lcd_version = lcd_version;
99#endif
100}
101#endif
102
84/* First thing called from Rockbox main() */ 103/* First thing called from Rockbox main() */
85void system_init(void) 104void system_init(void)
86{ 105{
diff --git a/firmware/target/mips/ingenic_x1000/x1000boot.make b/firmware/target/mips/ingenic_x1000/x1000boot.make
index 0bdf5cf7b4..7a861b0a3d 100644
--- a/firmware/target/mips/ingenic_x1000/x1000boot.make
+++ b/firmware/target/mips/ingenic_x1000/x1000boot.make
@@ -12,7 +12,7 @@ include $(ROOTDIR)/lib/microtar/microtar.make
12INCLUDES += -I$(APPSDIR) 12INCLUDES += -I$(APPSDIR)
13SRC += $(call preprocess, $(APPSDIR)/SOURCES) 13SRC += $(call preprocess, $(APPSDIR)/SOURCES)
14 14
15LDSDEP := $(FIRMDIR)/export/cpu.h $(FIRMDIR)/export/config/$(MODELNAME).h 15LDSDEP := $(FIRMDIR)/export/cpu.h $(FIRMDIR)/export/config.h
16 16
17BOOTLDS := $(FIRMDIR)/target/$(CPU)/$(MANUFACTURER)/boot.lds 17BOOTLDS := $(FIRMDIR)/target/$(CPU)/$(MANUFACTURER)/boot.lds
18BOOTLINK := $(BUILDDIR)/boot.link 18BOOTLINK := $(BUILDDIR)/boot.link