summaryrefslogtreecommitdiff
path: root/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c')
-rw-r--r--firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c76
1 files changed, 41 insertions, 35 deletions
diff --git a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
index 1698dc2b9b..4b74405c1c 100644
--- a/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
+++ b/firmware/target/arm/s5l8700/ipodnano2g/nand-nano2g.c
@@ -31,8 +31,7 @@
31#include <mmu-arm.h> 31#include <mmu-arm.h>
32#include <string.h> 32#include <string.h>
33#include "led.h" 33#include "led.h"
34#include "ata_idle_notify.h" 34#include "storage.h"
35
36 35
37#define NAND_CMD_READ 0x00 36#define NAND_CMD_READ 0x00
38#define NAND_CMD_PROGCNFRM 0x10 37#define NAND_CMD_PROGCNFRM 0x10
@@ -91,7 +90,6 @@ static int nand_powered = 0;
91static int nand_interleaved = 0; 90static int nand_interleaved = 0;
92static int nand_cached = 0; 91static int nand_cached = 0;
93static long nand_last_activity_value = -1; 92static long nand_last_activity_value = -1;
94static long nand_stack[DEFAULT_STACK_SIZE];
95 93
96static struct mutex nand_mtx; 94static struct mutex nand_mtx;
97static struct semaphore nand_complete; 95static struct semaphore nand_complete;
@@ -359,20 +357,22 @@ void nand_power_up(void)
359 357
360void nand_power_down(void) 358void nand_power_down(void)
361{ 359{
362 if (!nand_powered) return;
363 mutex_lock(&nand_mtx); 360 mutex_lock(&nand_mtx);
364 pmu_ldo_power_off(4); 361 if (nand_powered)
365 PCON2 = 0x11111111; 362 {
366 PDAT2 = 0; 363 pmu_ldo_power_off(4);
367 PCON3 = 0x11111111; 364 PCON2 = 0x11111111;
368 PDAT3 = 0; 365 PDAT2 = 0;
369 PCON4 = 0x11111111; 366 PCON3 = 0x11111111;
370 PDAT4 = 0; 367 PDAT3 = 0;
371 PCON5 = (PCON5 & ~0xF) | 1; 368 PCON4 = 0x11111111;
372 PUNK5 = 1; 369 PDAT4 = 0;
373 PWRCONEXT |= 0x40; 370 PCON5 = (PCON5 & ~0xF) | 1;
374 PWRCON |= 0x100000; 371 PUNK5 = 1;
375 nand_powered = 0; 372 PWRCONEXT |= 0x40;
373 PWRCON |= 0x100000;
374 nand_powered = 0;
375 }
376 mutex_unlock(&nand_mtx); 376 mutex_unlock(&nand_mtx);
377} 377}
378 378
@@ -714,20 +714,6 @@ const struct nand_device_info_type* nand_get_device_type(uint32_t bank)
714 return &nand_deviceinfotable[nand_type[bank]]; 714 return &nand_deviceinfotable[nand_type[bank]];
715} 715}
716 716
717static void nand_thread(void)
718{
719 while (1)
720 {
721 if (TIME_AFTER(current_tick, nand_last_activity_value + HZ / 5)
722 && nand_powered)
723 {
724 call_storage_idle_notifys(false);
725 nand_power_down();
726 }
727 sleep(HZ / 10);
728 }
729}
730
731int nand_device_init(void) 717int nand_device_init(void)
732{ 718{
733 mutex_init(&nand_mtx); 719 mutex_init(&nand_mtx);
@@ -776,10 +762,30 @@ int nand_device_init(void)
776 nand_cached = ((nand_deviceinfotable[nand_type[0]].id >> 23) & 1); 762 nand_cached = ((nand_deviceinfotable[nand_type[0]].id >> 23) & 1);
777 763
778 nand_last_activity_value = current_tick; 764 nand_last_activity_value = current_tick;
779 create_thread(nand_thread, nand_stack,
780 sizeof(nand_stack), 0, "nand"
781 IF_PRIO(, PRIORITY_USER_INTERFACE)
782 IF_COP(, CPU));
783
784 return 0; 765 return 0;
785} 766}
767
768int nand_event(long id, intptr_t data)
769{
770 int rc = 0;
771
772 if (LIKELY(id == Q_STORAGE_TICK))
773 {
774 if (!nand_powered ||
775 TIME_BEFORE(current_tick, nand_last_activity_value + HZ / 5))
776 {
777 STG_EVENT_ASSERT_ACTIVE(STORAGE_NAND);
778 }
779 }
780 else if (id == Q_STORAGE_SLEEPNOW)
781 {
782 nand_power_down();
783 }
784 else
785 {
786 rc = storage_event_default_handler(id, data, nand_last_activity_value,
787 STORAGE_NAND);
788 }
789
790 return rc;
791}