summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_x1000/pwm-x1000.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/pwm-x1000.c')
-rw-r--r--firmware/target/mips/ingenic_x1000/pwm-x1000.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/firmware/target/mips/ingenic_x1000/pwm-x1000.c b/firmware/target/mips/ingenic_x1000/pwm-x1000.c
index 37d2856c1a..8530a38af5 100644
--- a/firmware/target/mips/ingenic_x1000/pwm-x1000.c
+++ b/firmware/target/mips/ingenic_x1000/pwm-x1000.c
@@ -33,7 +33,6 @@ struct pwm_gpio_data {
33}; 33};
34 34
35struct pwm_state { 35struct pwm_state {
36 struct pwm_gpio_data gpio;
37 int period_ns; 36 int period_ns;
38 int duty_ns; 37 int duty_ns;
39 int full_ticks; 38 int full_ticks;
@@ -41,12 +40,20 @@ struct pwm_state {
41 int prescaler; 40 int prescaler;
42}; 41};
43 42
43static const struct pwm_gpio_data pwm_gpios[] = {
44 {GPIO_C, 1 << 25, GPIO_DEVICE(0)},
45 {GPIO_C, 1 << 26, GPIO_DEVICE(1)},
46 {GPIO_C, 1 << 27, GPIO_DEVICE(1)},
47 {GPIO_B, 1 << 6, GPIO_DEVICE(2)},
48 {GPIO_C, 1 << 24, GPIO_DEVICE(0)},
49};
50
44static struct pwm_state pwm_state[] = { 51static struct pwm_state pwm_state[] = {
45 {{GPIO_C, 1 << 25, GPIO_DEVICE(0)}, -1, -1, -1, -1, -1}, 52 {-1, -1, -1, -1, -1},
46 {{GPIO_C, 1 << 26, GPIO_DEVICE(1)}, -1, -1, -1, -1, -1}, 53 {-1, -1, -1, -1, -1},
47 {{GPIO_C, 1 << 27, GPIO_DEVICE(1)}, -1, -1, -1, -1, -1}, 54 {-1, -1, -1, -1, -1},
48 {{GPIO_B, 1 << 6, GPIO_DEVICE(2)}, -1, -1, -1, -1, -1}, 55 {-1, -1, -1, -1, -1},
49 {{GPIO_C, 1 << 24, GPIO_DEVICE(0)}, -1, -1, -1, -1, -1}, 56 {-1, -1, -1, -1, -1},
50}; 57};
51 58
52void pwm_init(int chn) 59void pwm_init(int chn)
@@ -60,7 +67,8 @@ void pwm_init(int chn)
60 st->prescaler = -1; 67 st->prescaler = -1;
61 68
62 /* clear GPIO and disable timer */ 69 /* clear GPIO and disable timer */
63 gpio_config(st->gpio.port, st->gpio.pin, GPIO_OUTPUT(0)); 70 const struct pwm_gpio_data* pg = &pwm_gpios[chn];
71 gpio_config(pg->port, pg->pin, GPIO_OUTPUT(0));
64 jz_clr(TCU_STOP, 1 << chn); 72 jz_clr(TCU_STOP, 1 << chn);
65 jz_clr(TCU_ENABLE, 1 << chn); 73 jz_clr(TCU_ENABLE, 1 << chn);
66 jz_set(TCU_STOP, 1 << chn); 74 jz_set(TCU_STOP, 1 << chn);
@@ -126,11 +134,10 @@ void pwm_set_period(int chn, int period_ns, int duty_ns)
126 134
127 if(full_ticks != st->full_ticks || half_ticks != st->half_ticks) { 135 if(full_ticks != st->full_ticks || half_ticks != st->half_ticks) {
128 if(enabled) { 136 if(enabled) {
129 /* avoid changing PWM settings in the middle of a cycle */ 137 /* avoid changing PWM settings in the middle of a cycle,
130 unsigned cmp = REG_TCU_CMP_FULL(chn) - 1; 138 * because for some reason, that is supposed to be "bad" */
131 long deadline = current_tick + 3; 139 jz_clr(TCU_FLAG, 1 << chn);
132 while(REG_TCU_COUNT(chn) < cmp 140 while((REG_TCU_FLAG & (1 << chn)) == 0);
133 && TIME_BEFORE(current_tick, deadline));
134 } 141 }
135 142
136 /* these can be changed while the timer is running */ 143 /* these can be changed while the timer is running */
@@ -154,15 +161,15 @@ void pwm_enable(int chn)
154 jz_set(TCU_ENABLE, 1 << chn); 161 jz_set(TCU_ENABLE, 1 << chn);
155 162
156 /* Configure GPIO function */ 163 /* Configure GPIO function */
157 struct pwm_state* st = &pwm_state[chn]; 164 const struct pwm_gpio_data* pg = &pwm_gpios[chn];
158 gpio_config(st->gpio.port, st->gpio.pin, st->gpio.func); 165 gpio_config(pg->port, pg->pin, pg->func);
159} 166}
160 167
161void pwm_disable(int chn) 168void pwm_disable(int chn)
162{ 169{
163 /* Set GPIO to output 0 */ 170 /* Set GPIO to output 0 */
164 struct pwm_state* st = &pwm_state[chn]; 171 const struct pwm_gpio_data* pg = &pwm_gpios[chn];
165 gpio_config(st->gpio.port, st->gpio.pin, GPIO_OUTPUT(0)); 172 gpio_config(pg->port, pg->pin, GPIO_OUTPUT(0));
166 173
167 /* Stop timer */ 174 /* Stop timer */
168 jz_clr(TCU_ENABLE, 1 << chn); 175 jz_clr(TCU_ENABLE, 1 << chn);