2 * Copyright (c) 2016 Google, Inc
3 * Written by Simon Glass <sjg@chromium.org>
5 * SPDX-License-Identifier: GPL-2.0+
16 #include <asm/arch/pwm.h>
17 #include <power/regulator.h>
19 DECLARE_GLOBAL_DATA_PTR
;
22 struct rk3288_pwm
*regs
;
26 static int rk_pwm_set_config(struct udevice
*dev
, uint channel
, uint period_ns
,
29 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
30 struct rk3288_pwm
*regs
= priv
->regs
;
31 unsigned long period
, duty
;
33 debug("%s: period_ns=%u, duty_ns=%u\n", __func__
, period_ns
, duty_ns
);
34 writel(PWM_SEL_SRC_CLK
| PWM_OUTPUT_LEFT
| PWM_LP_DISABLE
|
35 PWM_CONTINUOUS
| PWM_DUTY_POSTIVE
| PWM_INACTIVE_POSTIVE
|
39 period
= lldiv((uint64_t)(priv
->freq
/ 1000) * period_ns
, 1000000);
40 duty
= lldiv((uint64_t)(priv
->freq
/ 1000) * duty_ns
, 1000000);
42 writel(period
, ®s
->period_hpr
);
43 writel(duty
, ®s
->duty_lpr
);
44 debug("%s: period=%lu, duty=%lu\n", __func__
, period
, duty
);
49 static int rk_pwm_set_enable(struct udevice
*dev
, uint channel
, bool enable
)
51 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
52 struct rk3288_pwm
*regs
= priv
->regs
;
54 debug("%s: Enable '%s'\n", __func__
, dev
->name
);
55 clrsetbits_le32(®s
->ctrl
, RK_PWM_ENABLE
, enable
? RK_PWM_ENABLE
: 0);
60 static int rk_pwm_ofdata_to_platdata(struct udevice
*dev
)
62 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
64 priv
->regs
= (struct rk3288_pwm
*)dev_get_addr(dev
);
69 static int rk_pwm_probe(struct udevice
*dev
)
71 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
75 ret
= clk_get_by_index(dev
, 0, &clk
);
77 debug("%s get clock fail!\n", __func__
);
80 priv
->freq
= clk_get_rate(&clk
);
85 static const struct pwm_ops rk_pwm_ops
= {
86 .set_config
= rk_pwm_set_config
,
87 .set_enable
= rk_pwm_set_enable
,
90 static const struct udevice_id rk_pwm_ids
[] = {
91 { .compatible
= "rockchip,rk3288-pwm" },
95 U_BOOT_DRIVER(rk_pwm
) = {
98 .of_match
= rk_pwm_ids
,
100 .ofdata_to_platdata
= rk_pwm_ofdata_to_platdata
,
101 .probe
= rk_pwm_probe
,
102 .priv_auto_alloc_size
= sizeof(struct rk_pwm_priv
),