1 /*
2 // Copyright (C) 2022 Beken Corporation
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <common/bk_include.h>
16 #include "bk_gpio.h"
17 #include "pwm_hal.h"
18 #include "pwm_ll.h"
19
pwm_hal_init(pwm_hal_t * hal)20 bk_err_t pwm_hal_init(pwm_hal_t *hal)
21 {
22 hal->hw = (pwm_hw_t *)PWM_LL_REG_BASE(hal->id);
23 pwm_ll_init(hal->hw);
24 return BK_OK;
25 }
26
pwm_hal_init_pwm(pwm_hal_t * hal,pwm_chan_t chan,const pwm_hal_config_t * config)27 bk_err_t pwm_hal_init_pwm(pwm_hal_t *hal, pwm_chan_t chan, const pwm_hal_config_t *config)
28 {
29 /* Import notes:
30 * On BK7251, we found that, if we power up the channel and disable the PWM
31 * channel immediately, then the PWM interrupt will not happen.
32 *
33 * So don't disable the PWM channel in PWM channel init API.
34 **/
35 //pwm_ll_disable(hal->hw, chan);
36
37 pwm_ll_disable_interrupt(hal->hw, chan);
38 pwm_ll_clear_chan_interrupt_status(hal->hw, chan);
39 pwm_ll_set_mode_pwm(hal->hw, chan);
40
41 pwm_ll_set_t1(hal->hw, chan, config->t1);
42 pwm_ll_set_t2(hal->hw, chan, config->t2);
43 pwm_ll_set_t3(hal->hw, chan, config->t3);
44 pwm_ll_set_t4(hal->hw, chan, config->t4);
45 return BK_OK;
46 }
47
pwm_hal_start_common(pwm_hal_t * hal,pwm_chan_t chan)48 bk_err_t pwm_hal_start_common(pwm_hal_t *hal, pwm_chan_t chan)
49 {
50 pwm_ll_enable(hal->hw, chan);
51 return BK_OK;
52 }
53
pwm_hal_stop_common(pwm_hal_t * hal,pwm_chan_t chan)54 bk_err_t pwm_hal_stop_common(pwm_hal_t *hal, pwm_chan_t chan)
55 {
56 /* We should disable the PWM interrupt first before stopping
57 * PWM. Otherwise the interrupt will always be triggered and the
58 * interrupt status can't be cleared (Observed on BK7251).
59 **/
60 pwm_ll_disable_interrupt(hal->hw, chan);
61 pwm_ll_clear_chan_interrupt_status(hal->hw, chan);
62 pwm_ll_disable(hal->hw, chan);
63
64 //The original implementation for BK7231N will reset the hardware configuration here!
65 //Now we do it in deinit API.
66 return BK_OK;
67 }
68
pwm_hal_init_capture(pwm_hal_t * hal,pwm_chan_t chan,const pwm_hal_capture_config_t * config)69 bk_err_t pwm_hal_init_capture(pwm_hal_t *hal, pwm_chan_t chan, const pwm_hal_capture_config_t *config)
70 {
71 //pwm_ll_disable(hal->hw, chan);
72 pwm_ll_disable_interrupt(hal->hw, chan);
73
74 if (config->edge == PWM_CAPTURE_POS)
75 pwm_ll_set_mode_capture_pos(hal->hw, chan);
76 else if (config->edge == PWM_CAPTURE_NEG)
77 pwm_ll_set_mode_capture_neg(hal->hw, chan);
78 else if (config->edge == PWM_CAPTURE_EDGE)
79 pwm_ll_set_mode_capture_edge(hal->hw, chan);
80 else {
81 //Never be here, caller validate the parameter
82 }
83
84 pwm_ll_set_t1(hal->hw, chan, 0);
85 pwm_ll_set_t2(hal->hw, chan, 0);
86 pwm_ll_set_t3(hal->hw, chan, 0);
87 pwm_ll_set_t4(hal->hw, chan, 0);
88 return BK_OK;
89 }
90