14 #define pr_fmt(fmt) "pwm-samsung: " fmt
16 #include <linux/export.h>
17 #include <linux/kernel.h>
19 #include <linux/slab.h>
44 #define to_s3c_chip(chip) container_of(chip, struct s3c_chip, chip)
46 #define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
48 static struct clk *clk_scaler[2];
55 #define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
56 #define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
57 #define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
58 #define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
92 static unsigned long pwm_calc_tin(
struct s3c_chip *s3c,
unsigned long freq)
94 unsigned long tin_parent_rate;
98 pwm_dbg(s3c,
"tin parent at %lu\n", tin_parent_rate);
100 for (div = 2; div <= 16; div *= 2) {
101 if ((tin_parent_rate / (div << 16)) < freq)
102 return tin_parent_rate /
div;
105 return tin_parent_rate / 16;
108 #define NS_IN_HZ (1000000000UL)
114 unsigned long tin_rate;
115 unsigned long tin_ns;
141 pwm_dbg(s3c,
"duty_ns=%d, period_ns=%d (%lu)\n",
142 duty_ns, period_ns, period);
147 if (pwm_is_tdiv(s3c)) {
148 tin_rate = pwm_calc_tin(s3c, period);
155 pwm_dbg(s3c,
"tin_rate=%lu\n", tin_rate);
158 tcnt = period_ns / tin_ns;
164 tcmp = duty_ns / tin_ns;
171 pwm_dbg(s3c,
"tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
196 static struct pwm_ops s3c_pwm_ops = {
197 .enable = s3c_pwm_enable,
198 .disable = s3c_pwm_disable,
199 .config = s3c_pwm_config,
209 unsigned int id = pdev->
id;
213 dev_err(dev,
"TIMER4 is currently not supported\n");
219 dev_err(dev,
"failed to allocate pwm_device\n");
224 s3c->
tcon_base =
id == 0 ? 0 : (
id * 4) + 4;
226 s3c->
chip.ops = &s3c_pwm_ops;
231 if (IS_ERR(s3c->
clk)) {
232 dev_err(dev,
"failed to get pwm tin clk\n");
233 return PTR_ERR(s3c->
clk);
238 dev_err(dev,
"failed to get pwm tdiv clk\n");
255 dev_err(dev,
"failed to register pwm\n");
259 pwm_dbg(s3c,
"config bits %02x\n",
262 dev_info(dev,
"tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
265 pwm_is_tdiv(s3c) ?
"div" :
"ext", s3c->
tcon_base);
267 platform_set_drvdata(pdev, s3c);
278 struct s3c_chip *s3c = platform_get_drvdata(pdev);
294 struct s3c_chip *s3c = platform_get_drvdata(pdev);
308 struct s3c_chip *s3c = platform_get_drvdata(pdev);
320 #define s3c_pwm_suspend NULL
321 #define s3c_pwm_resume NULL
326 .name =
"s3c24xx-pwm",
329 .probe = s3c_pwm_probe,
335 static int __init pwm_init(
void)
342 if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
343 pr_err(
"failed to get scaler clocks\n");
349 pr_err(
"failed to add pwm driver\n");