diff options
-rw-r--r-- | firmware/target/mips/ingenic_x1000/pwm-x1000.c | 39 |
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 | ||
35 | struct pwm_state { | 35 | struct 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 | ||
43 | static 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 | |||
44 | static struct pwm_state pwm_state[] = { | 51 | static 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 | ||
52 | void pwm_init(int chn) | 59 | void 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 | ||
161 | void pwm_disable(int chn) | 168 | void 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); |