1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright (c) 2016 Google, Inc
4 * Written by Simon Glass <sjg@chromium.org>
15 #include <asm/arch/pwm.h>
16 #include <power/regulator.h>
19 struct rk3288_pwm
*regs
;
24 static int rk_pwm_set_invert(struct udevice
*dev
, uint channel
, bool polarity
)
26 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
28 debug("%s: polarity=%u\n", __func__
, polarity
);
29 priv
->enable_conf
&= ~(PWM_DUTY_MASK
| PWM_INACTIVE_MASK
);
31 priv
->enable_conf
|= PWM_DUTY_NEGATIVE
| PWM_INACTIVE_POSTIVE
;
33 priv
->enable_conf
|= PWM_DUTY_POSTIVE
| PWM_INACTIVE_NEGATIVE
;
38 static int rk_pwm_set_config(struct udevice
*dev
, uint channel
, uint period_ns
,
41 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
42 struct rk3288_pwm
*regs
= priv
->regs
;
43 unsigned long period
, duty
;
45 debug("%s: period_ns=%u, duty_ns=%u\n", __func__
, period_ns
, duty_ns
);
46 writel(PWM_SEL_SRC_CLK
| PWM_OUTPUT_LEFT
| PWM_LP_DISABLE
|
47 PWM_CONTINUOUS
| priv
->enable_conf
|
51 period
= lldiv((uint64_t)(priv
->freq
/ 1000) * period_ns
, 1000000);
52 duty
= lldiv((uint64_t)(priv
->freq
/ 1000) * duty_ns
, 1000000);
54 writel(period
, ®s
->period_hpr
);
55 writel(duty
, ®s
->duty_lpr
);
56 debug("%s: period=%lu, duty=%lu\n", __func__
, period
, duty
);
61 static int rk_pwm_set_enable(struct udevice
*dev
, uint channel
, bool enable
)
63 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
64 struct rk3288_pwm
*regs
= priv
->regs
;
66 debug("%s: Enable '%s'\n", __func__
, dev
->name
);
67 clrsetbits_le32(®s
->ctrl
, RK_PWM_ENABLE
, enable
? RK_PWM_ENABLE
: 0);
72 static int rk_pwm_ofdata_to_platdata(struct udevice
*dev
)
74 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
76 priv
->regs
= (struct rk3288_pwm
*)dev_read_addr(dev
);
81 static int rk_pwm_probe(struct udevice
*dev
)
83 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
87 ret
= clk_get_by_index(dev
, 0, &clk
);
89 debug("%s get clock fail!\n", __func__
);
92 priv
->freq
= clk_get_rate(&clk
);
93 priv
->enable_conf
= PWM_DUTY_POSTIVE
| PWM_INACTIVE_POSTIVE
;
98 static const struct pwm_ops rk_pwm_ops
= {
99 .set_invert
= rk_pwm_set_invert
,
100 .set_config
= rk_pwm_set_config
,
101 .set_enable
= rk_pwm_set_enable
,
104 static const struct udevice_id rk_pwm_ids
[] = {
105 { .compatible
= "rockchip,rk3288-pwm" },
109 U_BOOT_DRIVER(rk_pwm
) = {
112 .of_match
= rk_pwm_ids
,
114 .ofdata_to_platdata
= rk_pwm_ofdata_to_platdata
,
115 .probe
= rk_pwm_probe
,
116 .priv_auto_alloc_size
= sizeof(struct rk_pwm_priv
),