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
);
32 priv
->enable_conf
&= ~(PWM_DUTY_MASK
| PWM_INACTIVE_MASK
);
34 priv
->enable_conf
|= PWM_DUTY_NEGATIVE
| PWM_INACTIVE_POSTIVE
;
36 priv
->enable_conf
|= PWM_DUTY_POSTIVE
| PWM_INACTIVE_NEGATIVE
;
41 static int rk_pwm_set_config(struct udevice
*dev
, uint channel
, uint period_ns
,
44 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
45 struct rk3288_pwm
*regs
= priv
->regs
;
46 unsigned long period
, duty
;
48 debug("%s: period_ns=%u, duty_ns=%u\n", __func__
, period_ns
, duty_ns
);
49 writel(PWM_SEL_SRC_CLK
| PWM_OUTPUT_LEFT
| PWM_LP_DISABLE
|
50 PWM_CONTINUOUS
| priv
->enable_conf
|
54 period
= lldiv((uint64_t)(priv
->freq
/ 1000) * period_ns
, 1000000);
55 duty
= lldiv((uint64_t)(priv
->freq
/ 1000) * duty_ns
, 1000000);
57 writel(period
, ®s
->period_hpr
);
58 writel(duty
, ®s
->duty_lpr
);
59 debug("%s: period=%lu, duty=%lu\n", __func__
, period
, duty
);
64 static int rk_pwm_set_enable(struct udevice
*dev
, uint channel
, bool enable
)
66 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
67 struct rk3288_pwm
*regs
= priv
->regs
;
69 debug("%s: Enable '%s'\n", __func__
, dev
->name
);
70 clrsetbits_le32(®s
->ctrl
, RK_PWM_ENABLE
, enable
? RK_PWM_ENABLE
: 0);
75 static int rk_pwm_ofdata_to_platdata(struct udevice
*dev
)
77 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
79 priv
->regs
= (struct rk3288_pwm
*)devfdt_get_addr(dev
);
84 static int rk_pwm_probe(struct udevice
*dev
)
86 struct rk_pwm_priv
*priv
= dev_get_priv(dev
);
90 ret
= clk_get_by_index(dev
, 0, &clk
);
92 debug("%s get clock fail!\n", __func__
);
95 priv
->freq
= clk_get_rate(&clk
);
96 priv
->enable_conf
= PWM_DUTY_POSTIVE
| PWM_INACTIVE_POSTIVE
;
101 static const struct pwm_ops rk_pwm_ops
= {
102 .set_invert
= rk_pwm_set_invert
,
103 .set_config
= rk_pwm_set_config
,
104 .set_enable
= rk_pwm_set_enable
,
107 static const struct udevice_id rk_pwm_ids
[] = {
108 { .compatible
= "rockchip,rk3288-pwm" },
112 U_BOOT_DRIVER(rk_pwm
) = {
115 .of_match
= rk_pwm_ids
,
117 .ofdata_to_platdata
= rk_pwm_ofdata_to_platdata
,
118 .probe
= rk_pwm_probe
,
119 .priv_auto_alloc_size
= sizeof(struct rk_pwm_priv
),