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
;
27 static int rk_pwm_set_invert(struct udevice
*dev
, uint channel
, bool polarity
)
29 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
31 debug("%s: polarity=%u\n", __func__
, polarity
);
33 priv
->enable_conf
|= PWM_DUTY_NEGATIVE
| PWM_INACTIVE_POSTIVE
;
35 priv
->enable_conf
|= PWM_DUTY_POSTIVE
| PWM_INACTIVE_NEGATIVE
;
40 static int rk_pwm_set_config(struct udevice
*dev
, uint channel
, uint period_ns
,
43 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
44 struct rk3288_pwm
*regs
= priv
->regs
;
45 unsigned long period
, duty
;
47 debug("%s: period_ns=%u, duty_ns=%u\n", __func__
, period_ns
, duty_ns
);
48 writel(PWM_SEL_SRC_CLK
| PWM_OUTPUT_LEFT
| PWM_LP_DISABLE
|
49 PWM_CONTINUOUS
| priv
->enable_conf
|
53 period
= lldiv((uint64_t)(priv
->freq
/ 1000) * period_ns
, 1000000);
54 duty
= lldiv((uint64_t)(priv
->freq
/ 1000) * duty_ns
, 1000000);
56 writel(period
, ®s
->period_hpr
);
57 writel(duty
, ®s
->duty_lpr
);
58 debug("%s: period=%lu, duty=%lu\n", __func__
, period
, duty
);
63 static int rk_pwm_set_enable(struct udevice
*dev
, uint channel
, bool enable
)
65 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
66 struct rk3288_pwm
*regs
= priv
->regs
;
68 debug("%s: Enable '%s'\n", __func__
, dev
->name
);
69 clrsetbits_le32(®s
->ctrl
, RK_PWM_ENABLE
, enable
? RK_PWM_ENABLE
: 0);
74 static int rk_pwm_ofdata_to_platdata(struct udevice
*dev
)
76 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
78 priv
->regs
= (struct rk3288_pwm
*)devfdt_get_addr(dev
);
83 static int rk_pwm_probe(struct udevice
*dev
)
85 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
89 ret
= clk_get_by_index(dev
, 0, &clk
);
91 debug("%s get clock fail!\n", __func__
);
94 priv
->freq
= clk_get_rate(&clk
);
99 static const struct pwm_ops rk_pwm_ops
= {
100 .set_invert
= rk_pwm_set_invert
,
101 .set_config
= rk_pwm_set_config
,
102 .set_enable
= rk_pwm_set_enable
,
105 static const struct udevice_id rk_pwm_ids
[] = {
106 { .compatible
= "rockchip,rk3288-pwm" },
110 U_BOOT_DRIVER(rk_pwm
) = {
113 .of_match
= rk_pwm_ids
,
115 .ofdata_to_platdata
= rk_pwm_ofdata_to_platdata
,
116 .probe
= rk_pwm_probe
,
117 .priv_auto_alloc_size
= sizeof(struct rk_pwm_priv
),