summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c48
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 =
48static int mc13783_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)]; 52static int mc13783_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)];
49static const char *mc13783_thread_name = "pmic"; 53static const char *mc13783_thread_name = "pmic";
50static struct wakeup mc13783_wake; 54static struct wakeup mc13783_wake;
55#ifdef PMIC_DRIVER_CLOSE
56static bool pmic_close = false;
57static 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 */
54static __attribute__((noreturn)) void mc13783_interrupt_thread(void) 62static 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
192void 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
169uint32_t mc13783_set(unsigned address, uint32_t bits) 207uint32_t mc13783_set(unsigned address, uint32_t bits)
170{ 208{