2 * Blackfin Pulse Width Modulation (PWM) core
4 * Copyright (c) 2011 Analog Devices Inc.
6 * Licensed under the GPL-2 or later.
9 #include <linux/module.h>
10 #include <linux/pwm.h>
11 #include <linux/slab.h>
13 #include <asm/gptimers.h>
14 #include <asm/portmux.h>
21 static const unsigned short pwm_to_gptimer_per
[] = {
22 P_TMR0
, P_TMR1
, P_TMR2
, P_TMR3
, P_TMR4
, P_TMR5
,
23 P_TMR6
, P_TMR7
, P_TMR8
, P_TMR9
, P_TMR10
, P_TMR11
,
26 struct pwm_device
*pwm_request(int pwm_id
, const char *label
)
28 struct pwm_device
*pwm
;
31 /* XXX: pwm_id really should be unsigned */
35 pwm
= kzalloc(sizeof(*pwm
), GFP_KERNEL
);
40 if (pwm
->id
>= ARRAY_SIZE(pwm_to_gptimer_per
))
43 pwm
->pin
= pwm_to_gptimer_per
[pwm
->id
];
44 ret
= peripheral_request(pwm
->pin
, label
);
53 EXPORT_SYMBOL(pwm_request
);
55 void pwm_free(struct pwm_device
*pwm
)
57 peripheral_free(pwm
->pin
);
60 EXPORT_SYMBOL(pwm_free
);
62 int pwm_config(struct pwm_device
*pwm
, int duty_ns
, int period_ns
)
64 unsigned long period
, duty
;
65 unsigned long long val
;
67 if (duty_ns
< 0 || duty_ns
> period_ns
)
70 val
= (unsigned long long)get_sclk() * period_ns
;
71 do_div(val
, NSEC_PER_SEC
);
74 val
= (unsigned long long)period
* duty_ns
;
75 do_div(val
, period_ns
);
81 set_gptimer_config(pwm
->id
, TIMER_MODE_PWM
| TIMER_PERIOD_CNT
);
82 set_gptimer_pwidth(pwm
->id
, duty
);
83 set_gptimer_period(pwm
->id
, period
);
87 EXPORT_SYMBOL(pwm_config
);
89 int pwm_enable(struct pwm_device
*pwm
)
91 enable_gptimer(pwm
->id
);
94 EXPORT_SYMBOL(pwm_enable
);
96 void pwm_disable(struct pwm_device
*pwm
)
98 disable_gptimer(pwm
->id
);
100 EXPORT_SYMBOL(pwm_disable
);