diff options
Diffstat (limited to 'firmware')
4 files changed, 50 insertions, 12 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/ata-imx31.c b/firmware/target/arm/imx31/gigabeat-s/ata-imx31.c index 9c3c72e2c5..885e7e7521 100644 --- a/firmware/target/arm/imx31/gigabeat-s/ata-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/ata-imx31.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "ata.h" | 26 | #include "ata.h" |
27 | #include "ata-target.h" | 27 | #include "ata-target.h" |
28 | #include "clkctl-imx31.h" | 28 | #include "clkctl-imx31.h" |
29 | # | ||
29 | 30 | ||
30 | static const struct ata_pio_timings | 31 | static const struct ata_pio_timings |
31 | { | 32 | { |
@@ -81,10 +82,15 @@ static const struct ata_pio_timings | |||
81 | 82 | ||
82 | static int pio_mode = 0; /* Setup mode 0 by default */ | 83 | static int pio_mode = 0; /* Setup mode 0 by default */ |
83 | 84 | ||
85 | static void ata_wait_for_idle(void) | ||
86 | { | ||
87 | while (!(ATA_INTERRUPT_PENDING & ATA_CONTROLLER_IDLE)); | ||
88 | } | ||
89 | |||
84 | /* Setup the timing for PIO mode */ | 90 | /* Setup the timing for PIO mode */ |
85 | void ata_set_pio_timings(int mode) | 91 | void ata_set_pio_timings(int mode) |
86 | { | 92 | { |
87 | while (!(ATA_INTERRUPT_PENDING & ATA_CONTROLLER_IDLE)); | 93 | ata_wait_for_idle(); |
88 | 94 | ||
89 | const struct ata_pio_timings * const timings = &pio_timings[mode]; | 95 | const struct ata_pio_timings * const timings = &pio_timings[mode]; |
90 | /* T = period in nanoseconds */ | 96 | /* T = period in nanoseconds */ |
@@ -107,20 +113,34 @@ void ata_set_pio_timings(int mode) | |||
107 | void ata_reset(void) | 113 | void ata_reset(void) |
108 | { | 114 | { |
109 | /* Be sure we're not busy */ | 115 | /* Be sure we're not busy */ |
110 | while (!(ATA_INTERRUPT_PENDING & ATA_CONTROLLER_IDLE)); | 116 | ata_wait_for_idle(); |
111 | 117 | ||
112 | ATA_INTF_CONTROL &= ~ATA_ATA_RST; | 118 | ATA_INTF_CONTROL &= ~ATA_ATA_RST; |
113 | sleep(1); | 119 | sleep(1); |
114 | ATA_INTF_CONTROL |= ATA_ATA_RST; | 120 | ATA_INTF_CONTROL |= ATA_ATA_RST; |
115 | sleep(1); | 121 | sleep(1); |
116 | 122 | ||
117 | while (!(ATA_INTERRUPT_PENDING & ATA_CONTROLLER_IDLE)); | 123 | ata_wait_for_idle(); |
118 | } | 124 | } |
119 | 125 | ||
120 | /* This function is called before enabling the USB bus */ | ||
121 | void ata_enable(bool on) | 126 | void ata_enable(bool on) |
122 | { | 127 | { |
123 | (void)on; | 128 | /* Unconditionally clock module before writing regs */ |
129 | imx31_clkctl_module_clock_gating(CG_ATA, CGM_ON_ALL); | ||
130 | |||
131 | if (on) | ||
132 | { | ||
133 | ATA_INTF_CONTROL |= ATA_ATA_RST; | ||
134 | } | ||
135 | else | ||
136 | { | ||
137 | ata_wait_for_idle(); | ||
138 | |||
139 | ATA_INTF_CONTROL &= ~ATA_ATA_RST; | ||
140 | |||
141 | /* Disable off - unclock ATA module */ | ||
142 | imx31_clkctl_module_clock_gating(CG_ATA, CGM_OFF); | ||
143 | } | ||
124 | } | 144 | } |
125 | 145 | ||
126 | bool ata_is_coldstart(void) | 146 | bool ata_is_coldstart(void) |
@@ -130,7 +150,8 @@ bool ata_is_coldstart(void) | |||
130 | 150 | ||
131 | void ata_device_init(void) | 151 | void ata_device_init(void) |
132 | { | 152 | { |
133 | ATA_INTF_CONTROL |= ATA_ATA_RST; /* Make sure we're not in reset mode */ | 153 | /* Make sure we're not in reset mode */ |
154 | ata_enable(true); | ||
134 | 155 | ||
135 | /* mode may be switched later once identify info is ready in which | 156 | /* mode may be switched later once identify info is ready in which |
136 | * case the main driver calls back */ | 157 | * case the main driver calls back */ |
diff --git a/firmware/target/arm/imx31/gigabeat-s/power-imx31.c b/firmware/target/arm/imx31/gigabeat-s/power-imx31.c index e51318d16f..3e845d7d93 100644 --- a/firmware/target/arm/imx31/gigabeat-s/power-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/power-imx31.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include "config.h" | 19 | #include "config.h" |
20 | #include "system.h" | 20 | #include "system.h" |
21 | #include "power.h" | 21 | #include "power.h" |
22 | #include "ata.h" | ||
22 | #include "backlight.h" | 23 | #include "backlight.h" |
23 | #include "backlight-target.h" | 24 | #include "backlight-target.h" |
24 | #include "avic-imx31.h" | 25 | #include "avic-imx31.h" |
@@ -50,7 +51,21 @@ bool charging_state(void) { | |||
50 | 51 | ||
51 | void ide_power_enable(bool on) | 52 | void ide_power_enable(bool on) |
52 | { | 53 | { |
53 | (void)on; | 54 | if (!on) |
55 | { | ||
56 | /* Bus must be isolated before power off */ | ||
57 | imx31_regmod32(&GPIO2_DR, (1 << 16), (1 << 16)); | ||
58 | } | ||
59 | |||
60 | /* HD power switch */ | ||
61 | imx31_regmod32(&GPIO3_DR, on ? (1 << 5) : 0, (1 << 5)); | ||
62 | |||
63 | if (on) | ||
64 | { | ||
65 | /* Bus switch may be turned on after powerup */ | ||
66 | sleep(HZ/10); | ||
67 | imx31_regmod32(&GPIO2_DR, 0, (1 << 16)); | ||
68 | } | ||
54 | } | 69 | } |
55 | 70 | ||
56 | bool ide_powered(void) | 71 | bool ide_powered(void) |
diff --git a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c index ca82a18fbd..412bbcc4b0 100644 --- a/firmware/target/arm/imx31/gigabeat-s/system-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/system-imx31.c | |||
@@ -27,7 +27,7 @@ void system_init(void) | |||
27 | gpio_init(); | 27 | gpio_init(); |
28 | } | 28 | } |
29 | 29 | ||
30 | void imx31_regmod32(volatile uint32_t *reg_p, uint32_t mask, uint32_t value) | 30 | void imx31_regmod32(volatile uint32_t *reg_p, uint32_t value, uint32_t mask) |
31 | { | 31 | { |
32 | value &= mask; | 32 | value &= mask; |
33 | mask = ~mask; | 33 | mask = ~mask; |
diff --git a/firmware/target/arm/imx31/gigabeat-s/wmcodec-imx31.c b/firmware/target/arm/imx31/gigabeat-s/wmcodec-imx31.c index c8a04ce20e..a88571ee14 100644 --- a/firmware/target/arm/imx31/gigabeat-s/wmcodec-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/wmcodec-imx31.c | |||
@@ -39,10 +39,12 @@ static struct i2c_node wm8978_i2c_node = | |||
39 | void audiohw_init(void) | 39 | void audiohw_init(void) |
40 | { | 40 | { |
41 | /* USB PLL = 338.688MHz, /30 = 11.2896MHz = 256Fs */ | 41 | /* USB PLL = 338.688MHz, /30 = 11.2896MHz = 256Fs */ |
42 | imx31_regmod32(&CLKCTL_PDR1, PDR1_SSI1_PODF | PDR1_SSI2_PODF, | 42 | imx31_regmod32(&CLKCTL_PDR1, |
43 | PDR1_SSI1_PODFw(64-1) | PDR1_SSI2_PODFw(5-1)); | 43 | PDR1_SSI1_PODFw(64-1) | PDR1_SSI2_PODFw(5-1), |
44 | imx31_regmod32(&CLKCTL_PDR1, PDR1_SSI1_PRE_PODF | PDR1_SSI2_PRE_PODF, | 44 | PDR1_SSI1_PODF | PDR1_SSI2_PODF); |
45 | PDR1_SSI1_PRE_PODFw(4-1) | PDR1_SSI2_PRE_PODFw(1-1)); | 45 | imx31_regmod32(&CLKCTL_PDR1, |
46 | PDR1_SSI1_PRE_PODFw(4-1) | PDR1_SSI2_PRE_PODFw(1-1), | ||
47 | PDR1_SSI1_PRE_PODF | PDR1_SSI2_PRE_PODF); | ||
46 | i2c_enable_node(&wm8978_i2c_node, true); | 48 | i2c_enable_node(&wm8978_i2c_node, true); |
47 | 49 | ||
48 | audiohw_preinit(); | 50 | audiohw_preinit(); |