diff options
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c b/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c index 3af4b48b66..ddf8d1360f 100644 --- a/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c | |||
@@ -29,6 +29,10 @@ | |||
29 | #include "adc-target.h" | 29 | #include "adc-target.h" |
30 | #include "usb-target.h" | 30 | #include "usb-target.h" |
31 | 31 | ||
32 | #ifdef BOOTLOADER | ||
33 | #define PMIC_DRIVER_CLOSE | ||
34 | #endif | ||
35 | |||
32 | /* This is all based on communicating with the MC13783 PMU which is on | 36 | /* This is all based on communicating with the MC13783 PMU which is on |
33 | * CSPI2 with the chip select at 0. The LCD controller resides on | 37 | * CSPI2 with the chip select at 0. The LCD controller resides on |
34 | * CSPI3 cs1, but we have no idea how to communicate to it */ | 38 | * CSPI3 cs1, but we have no idea how to communicate to it */ |
@@ -48,10 +52,14 @@ static struct spi_node mc13783_spi = | |||
48 | static int mc13783_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)]; | 52 | static int mc13783_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)]; |
49 | static const char *mc13783_thread_name = "pmic"; | 53 | static const char *mc13783_thread_name = "pmic"; |
50 | static struct wakeup mc13783_wake; | 54 | static struct wakeup mc13783_wake; |
55 | #ifdef PMIC_DRIVER_CLOSE | ||
56 | static bool pmic_close = false; | ||
57 | static struct thread_entry *mc13783_thread_p = NULL; | ||
58 | #endif | ||
51 | 59 | ||
52 | /* The next two functions are rather target-specific but they'll just be left | 60 | /* The next two functions are rather target-specific but they'll just be left |
53 | * here for the moment */ | 61 | * here for the moment */ |
54 | static __attribute__((noreturn)) void mc13783_interrupt_thread(void) | 62 | static void mc13783_interrupt_thread(void) |
55 | { | 63 | { |
56 | const unsigned char status_regs[2] = | 64 | const unsigned char status_regs[2] = |
57 | { | 65 | { |
@@ -76,7 +84,9 @@ static __attribute__((noreturn)) void mc13783_interrupt_thread(void) | |||
76 | 84 | ||
77 | value = mc13783_read(MC13783_INTERRUPT_SENSE1); | 85 | value = mc13783_read(MC13783_INTERRUPT_SENSE1); |
78 | button_power_set_state((value & MC13783_ONOFD1) == 0); | 86 | button_power_set_state((value & MC13783_ONOFD1) == 0); |
87 | #ifdef HAVE_HEADPHONE_DETECTION | ||
79 | set_headphones_inserted((value & MC13783_ONOFD2) == 0); | 88 | set_headphones_inserted((value & MC13783_ONOFD2) == 0); |
89 | #endif | ||
80 | 90 | ||
81 | pending[0] = pending[1] = 0xffffff; | 91 | pending[0] = pending[1] = 0xffffff; |
82 | mc13783_write_regset(status_regs, pending, 2); | 92 | mc13783_write_regset(status_regs, pending, 2); |
@@ -90,6 +100,14 @@ static __attribute__((noreturn)) void mc13783_interrupt_thread(void) | |||
90 | { | 100 | { |
91 | wakeup_wait(&mc13783_wake, TIMEOUT_BLOCK); | 101 | wakeup_wait(&mc13783_wake, TIMEOUT_BLOCK); |
92 | 102 | ||
103 | #ifdef PMIC_DRIVER_CLOSE | ||
104 | if (pmic_close) | ||
105 | { | ||
106 | gpio_disable_event(MC13783_GPIO_NUM, MC13783_EVENT_ID); | ||
107 | return; | ||
108 | } | ||
109 | #endif | ||
110 | |||
93 | mc13783_read_regset(status_regs, pending, 2); | 111 | mc13783_read_regset(status_regs, pending, 2); |
94 | mc13783_write_regset(status_regs, pending, 2); | 112 | mc13783_write_regset(status_regs, pending, 2); |
95 | 113 | ||
@@ -130,9 +148,10 @@ static __attribute__((noreturn)) void mc13783_interrupt_thread(void) | |||
130 | 148 | ||
131 | if (pending[1] & MC13783_ONOFD1) | 149 | if (pending[1] & MC13783_ONOFD1) |
132 | button_power_set_state((value & MC13783_ONOFD1) == 0); | 150 | button_power_set_state((value & MC13783_ONOFD1) == 0); |
133 | 151 | #ifdef HAVE_HEADPHONE_DETECTION | |
134 | if (pending[1] & MC13783_ONOFD2) | 152 | if (pending[1] & MC13783_ONOFD2) |
135 | set_headphones_inserted((value & MC13783_ONOFD2) == 0); | 153 | set_headphones_inserted((value & MC13783_ONOFD2) == 0); |
154 | #endif | ||
136 | } | 155 | } |
137 | } | 156 | } |
138 | } | 157 | } |
@@ -161,10 +180,29 @@ void mc13783_init(void) | |||
161 | 180 | ||
162 | MC13783_GPIO_ISR = (1ul << MC13783_GPIO_LINE); | 181 | MC13783_GPIO_ISR = (1ul << MC13783_GPIO_LINE); |
163 | 182 | ||
164 | create_thread(mc13783_interrupt_thread, mc13783_thread_stack, | 183 | #ifdef PMIC_DRIVER_CLOSE |
165 | sizeof(mc13783_thread_stack), 0, mc13783_thread_name | 184 | mc13783_thread_p = |
166 | IF_PRIO(, PRIORITY_REALTIME) IF_COP(, CPU)); | 185 | #endif |
186 | create_thread(mc13783_interrupt_thread, | ||
187 | mc13783_thread_stack, sizeof(mc13783_thread_stack), 0, | ||
188 | mc13783_thread_name IF_PRIO(, PRIORITY_REALTIME) IF_COP(, CPU)); | ||
189 | } | ||
190 | |||
191 | #ifdef PMIC_DRIVER_CLOSE | ||
192 | void mc13783_close(void) | ||
193 | { | ||
194 | struct thread_entry *thread = mc13783_thread_p; | ||
195 | |||
196 | if (thread == NULL) | ||
197 | return; | ||
198 | |||
199 | mc13783_thread_p = NULL; | ||
200 | |||
201 | pmic_close = true; | ||
202 | wakeup_signal(&mc13783_wake); | ||
203 | thread_wait(thread); | ||
167 | } | 204 | } |
205 | #endif | ||
168 | 206 | ||
169 | uint32_t mc13783_set(unsigned address, uint32_t bits) | 207 | uint32_t mc13783_set(unsigned address, uint32_t bits) |
170 | { | 208 | { |