Lines Matching +full:pwm +full:- +full:mode

4  * SPDX-License-Identifier: Apache-2.0
10 #include <zephyr/drivers/pwm.h>
12 #include <zephyr/dt-bindings/pwm/it8xxx2_pwm.h>
28 /* PWM channel duty cycle register */
30 /* PWM channel clock source selection register */
32 /* PWM channel clock source gating register */
34 /* PWM channel output polarity register */
36 /* PWM channel */
38 /* PWM prescaler control register base */
40 /* Select PWM prescaler that output to PWM channel */
42 /* PWM alternate configuration */
54 const struct pwm_it8xxx2_cfg *config = dev->config; in pwm_enable()
55 volatile uint8_t *reg_pcsgr = (uint8_t *)config->reg_pcsgr; in pwm_enable()
56 int ch = config->channel; in pwm_enable()
59 /* PWM channel clock source not gating */ in pwm_enable()
62 /* PWM channel clock source gating */ in pwm_enable()
73 * There are three ways to call pwm_it8xxx2_set_cycles() from pwm api: in pwm_it8xxx2_get_cycles_per_sec()
74 * 1) pwm_set_cycles_usec() -> pwm_set_cycles_cycles() -> pwm_it8xxx2_set_cycles() in pwm_it8xxx2_get_cycles_per_sec()
78 * 2) pwm_set_cycles_nsec() -> pwm_set_cycles_cycles() -> pwm_it8xxx2_set_cycles() in pwm_it8xxx2_get_cycles_per_sec()
82 * 3) pwm_set_cycles_cycles() -> pwm_it8xxx2_set_cycles() in pwm_it8xxx2_get_cycles_per_sec()
86 * If we need to pwm output in EC power saving mode, then we will switch in pwm_it8xxx2_get_cycles_per_sec()
99 const struct pwm_it8xxx2_cfg *config = dev->config; in pwm_it8xxx2_set_cycles()
100 struct pwm_it8xxx2_regs *const inst = config->base; in pwm_it8xxx2_set_cycles()
101 struct pwm_it8xxx2_data *data = dev->data; in pwm_it8xxx2_set_cycles()
102 volatile uint8_t *reg_dcr = (uint8_t *)config->reg_dcr; in pwm_it8xxx2_set_cycles()
103 volatile uint8_t *reg_pwmpol = (uint8_t *)config->reg_pwmpol; in pwm_it8xxx2_set_cycles()
104 int ch = config->channel; in pwm_it8xxx2_set_cycles()
105 int prs_sel = config->prs_sel; in pwm_it8xxx2_set_cycles()
109 /* Select PWM inverted polarity (ex. active-low pulse) */ in pwm_it8xxx2_set_cycles()
116 /* Enable PWM output open-drain */ in pwm_it8xxx2_set_cycles()
118 inst->PWMODENR |= BIT(ch); in pwm_it8xxx2_set_cycles()
121 /* If pulse cycles is 0, set duty cycle 0 and enable pwm channel */ in pwm_it8xxx2_set_cycles()
132 * Support PWM output frequency: in pwm_it8xxx2_set_cycles()
135 * NOTE: PWM output signal maximum supported frequency comes from in pwm_it8xxx2_set_cycles()
137 * PWM output signal minimum supported frequency comes from in pwm_it8xxx2_set_cycles()
141 LOG_ERR("PWM output frequency is < 1 !"); in pwm_it8xxx2_set_cycles()
142 return -EINVAL; in pwm_it8xxx2_set_cycles()
149 * saving mode, clock source 8MHz will be gated (32.768KHz won't). in pwm_it8xxx2_set_cycles()
150 * So if we still need pwm output in mode, then we should set frequency in pwm_it8xxx2_set_cycles()
152 * 32.768KHz to support pwm output in mode. in pwm_it8xxx2_set_cycles()
155 if (inst->PCFSR & BIT(prs_sel)) { in pwm_it8xxx2_set_cycles()
156 inst->PCFSR &= ~BIT(prs_sel); in pwm_it8xxx2_set_cycles()
163 * PWM output signal frequency is in pwm_it8xxx2_set_cycles()
172 if (target_freq != data->target_freq_prev) { in pwm_it8xxx2_set_cycles()
175 for (ctr = 0xFF; ctr >= PWM_CTRX_MIN; ctr--) { in pwm_it8xxx2_set_cycles()
179 * divide-by-zero on calculating actual_freq. in pwm_it8xxx2_set_cycles()
183 if (abs(actual_freq - target_freq) < deviation) { in pwm_it8xxx2_set_cycles()
184 /* CxCPRS[15:0] = cxcprs - 1 */ in pwm_it8xxx2_set_cycles()
185 cxcprs--; in pwm_it8xxx2_set_cycles()
192 LOG_ERR("PWM prescaler CxCPRS only support 2 bytes !"); in pwm_it8xxx2_set_cycles()
193 return -EINVAL; in pwm_it8xxx2_set_cycles()
197 data->ctr = ctr; in pwm_it8xxx2_set_cycles()
198 data->cxcprs = cxcprs; in pwm_it8xxx2_set_cycles()
201 /* Set PWM prescaler clock divide and cycle time register */ in pwm_it8xxx2_set_cycles()
203 inst->C4CPRS = data->cxcprs & 0xFF; in pwm_it8xxx2_set_cycles()
204 inst->C4MCPRS = (data->cxcprs >> 8) & 0xFF; in pwm_it8xxx2_set_cycles()
205 inst->CTR1 = data->ctr; in pwm_it8xxx2_set_cycles()
207 inst->C6CPRS = data->cxcprs & 0xFF; in pwm_it8xxx2_set_cycles()
208 inst->C6MCPRS = (data->cxcprs >> 8) & 0xFF; in pwm_it8xxx2_set_cycles()
209 inst->CTR2 = data->ctr; in pwm_it8xxx2_set_cycles()
211 inst->C7CPRS = data->cxcprs & 0xFF; in pwm_it8xxx2_set_cycles()
212 inst->C7MCPRS = (data->cxcprs >> 8) & 0xFF; in pwm_it8xxx2_set_cycles()
213 inst->CTR3 = data->ctr; in pwm_it8xxx2_set_cycles()
216 /* Set PWM channel duty cycle register */ in pwm_it8xxx2_set_cycles()
217 *reg_dcr = (data->ctr * pulse_cycles) / period_cycles; in pwm_it8xxx2_set_cycles()
219 /* PWM channel clock source not gating */ in pwm_it8xxx2_set_cycles()
223 data->target_freq_prev = target_freq; in pwm_it8xxx2_set_cycles()
233 const struct pwm_it8xxx2_cfg *config = dev->config; in pwm_it8xxx2_init()
234 struct pwm_it8xxx2_regs *const inst = config->base; in pwm_it8xxx2_init()
235 volatile uint8_t *reg_pcssg = (uint8_t *)config->reg_pcssg; in pwm_it8xxx2_init()
236 int ch = config->channel; in pwm_it8xxx2_init()
237 int prs_sel = config->prs_sel; in pwm_it8xxx2_init()
242 /* PWM channel clock source gating before configuring */ in pwm_it8xxx2_init()
246 inst->PCFSR |= BIT(prs_sel); in pwm_it8xxx2_init()
252 /* Select which prescaler output to PWM channel */ in pwm_it8xxx2_init()
260 * we clear cycle timer1 high byte at init and use it as 8-bit in pwm_it8xxx2_init()
263 inst->CTR1M = 0; in pwm_it8xxx2_init()
266 inst->ZTIER |= IT8XXX2_PWM_PCCE; in pwm_it8xxx2_init()
268 /* Set alternate mode of PWM pin */ in pwm_it8xxx2_init()
269 status = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); in pwm_it8xxx2_init()
271 LOG_ERR("Failed to configure PWM pins"); in pwm_it8xxx2_init()
278 static DEVICE_API(pwm, pwm_it8xxx2_api) = {