swconfig: Replace SPIN_LOCK_UNLOCKED with DEFINE_SPINLOCK
[openwrt.git] / target / linux / generic / files / Documentation / pwm.txt
1 Generic PWM Device API
2
3 February 1, 2010
4 Bill Gatliff
5 <bgat@billgatliff.com>
6
7
8
9 The code in drivers/pwm and include/linux/pwm/ implements an API for
10 applications involving pulse-width-modulation signals. This document
11 describes how the API implementation facilitates both PWM-generating
12 devices, and users of those devices.
13
14
15
16 Motivation
17
18 The primary goals for implementing the "generic PWM API" are to
19 consolidate the various PWM implementations within a consistent and
20 redundancy-reducing framework, and to facilitate the use of
21 hotpluggable PWM devices.
22
23 Previous PWM-related implementations within the Linux kernel achieved
24 their consistency via cut-and-paste, but did not need to (and didn't)
25 facilitate more than one PWM-generating device within the system---
26 hotplug or otherwise. The Generic PWM Device API might be most
27 appropriately viewed as an update to those implementations, rather
28 than a complete rewrite.
29
30
31
32 Challenges
33
34 One of the difficulties in implementing a generic PWM framework is the
35 fact that pulse-width-modulation applications involve real-world
36 signals, which often must be carefully managed to prevent destruction
37 of hardware that is linked to those signals. A DC motor that
38 experiences a brief interruption in the PWM signal controlling it
39 might destructively overheat; it could suddenly change speed, losing
40 synchronization with a sensor; it could even suddenly change direction
41 or torque, breaking the mechanical device connected to it.
42
43 (A generic PWM device framework is not directly responsible for
44 preventing the above scenarios: that responsibility lies with the
45 hardware designer, and the application and driver authors. But it
46 must to the greatest extent possible make it easy to avoid such
47 problems).
48
49 A generic PWM device framework must accommodate the substantial
50 differences between available PWM-generating hardware devices, without
51 becoming sub-optimal for any of them.
52
53 Finally, a generic PWM device framework must be relatively
54 lightweight, computationally speaking. Some PWM users demand
55 high-speed outputs, plus the ability to regulate those outputs
56 quickly. A device framework must be able to "keep up" with such
57 hardware, while still leaving time to do real work.
58
59 The Generic PWM Device API is an attempt to meet all of the above
60 requirements. At its initial publication, the API was already in use
61 managing small DC motors, sensors and solenoids through a
62 custom-designed, optically-isolated H-bridge driver.
63
64
65
66 Functional Overview
67
68 The Generic PWM Device API framework is implemented in
69 include/linux/pwm/pwm.h and drivers/pwm/pwm.c. The functions therein
70 use information from pwm_device, pwm_channel and pwm_channel_config
71 structures to invoke services in PWM peripheral device drivers.
72 Consult drivers/pwm/atmel-pwm.c for an example driver.
73
74 There are two classes of adopters of the PWM framework:
75
76 "Users" -- those wishing to employ the API merely to produce PWM
77 signals; once they have identified the appropriate physical output
78 on the platform in question, they don't care about the details of
79 the underlying hardware
80
81 "Driver authors" -- those wishing to bind devices that can generate
82 PWM signals to the Generic PWM Device API, so that the services of
83 those devices become available to users. Assuming the hardware can
84 support the needs of a user, driver authors don't care about the
85 details of the user's application
86
87 Generally speaking, users will first invoke pwm_request() to obtain a
88 handle to a PWM device. They will then pass that handle to functions
89 like pwm_duty_ns() and pwm_period_ns() to set the duty cycle and
90 period of the PWM signal, respectively. They will also invoke
91 pwm_start() and pwm_stop() to turn the signal on and off.
92
93 The Generic PWM API framework also provides a sysfs interface to PWM
94 devices, which is adequate for basic application needs and testing.
95
96 Driver authors fill out a pwm_device structure, which describes the
97 capabilities of the PWM hardware being constructed--- including the
98 number of distinct output "channels" the peripheral offers. They then
99 invoke pwm_register() (usually from within their device's probe()
100 handler) to make the PWM API aware of their device. The framework
101 will call back to the methods described in the pwm_device structure as
102 users begin to configure and utilize the hardware.
103
104 Note that PWM signals can be produced by a variety of peripherals,
105 beyond the true "PWM hardware" offered by many system-on-chip devices.
106 Other possibilities include timer/counters with compare-match
107 capabilities, carefully-programmed synchronous serial ports
108 (e.g. SPI), and GPIO pins driven by kernel interval timers. With a
109 proper pwm_device structure, these devices and pseudo-devices can all
110 be accommodated by the Generic PWM Device API framework.
111
112
113
114 Using the API to Generate PWM Signals -- Basic Functions for Users
115
116
117 pwm_request() -- Returns a pwm_channel pointer, which is subsequently
118 passed to the other user-related PWM functions. Once requested, a PWM
119 channel is marked as in-use and subsequent requests prior to
120 pwm_free() will fail.
121
122 The names used to refer to PWM devices are defined by driver authors.
123 Typically they are platform device bus identifiers, and this
124 convention is encouraged for consistency.
125
126
127 pwm_free() -- Marks a PWM channel as no longer in use. The PWM device
128 is stopped before it is released by the API.
129
130
131 pwm_period_ns() -- Specifies the PWM signal's period, in nanoseconds.
132
133
134 pwm_duty_ns() -- Specifies the PWM signal's active duration, in nanoseconds.
135
136
137 pwm_duty_percent() -- Specifies the PWM signal's active duration, as a
138 percentage of the current period of the signal. NOTE: this value is
139 not recalculated if the period of the signal is subsequently changed.
140
141
142 pwm_start(), pwm_stop() -- Turns the PWM signal on and off. Except
143 where stated otherwise by a driver author, signals are stopped at the
144 end of the current period, at which time the output is set to its
145 inactive state.
146
147
148 pwm_polarity() -- Defines whether the PWM signal output's active
149 region is "1" or "0". A 10% duty-cycle, polarity=1 signal will
150 conventionally be at 5V (or 3.3V, or 1000V, or whatever the platform
151 hardware does) for 10% of the period. The same configuration of a
152 polarity=0 signal will be at 5V (or 3.3V, or ...) for 90% of the
153 period.
154
155
156
157 Using the API to Generate PWM Signals -- Advanced Functions
158
159
160 pwm_config() -- Passes a pwm_channel_config structure to the
161 associated device driver. This function is invoked by pwm_start(),
162 pwm_duty_ns(), etc. and is one of two main entry points to the PWM
163 driver for the hardware being used. The configuration change is
164 guaranteed atomic if multiple configuration changes are specified.
165 This function might sleep, depending on what the device driver has to
166 do to satisfy the request. All PWM device drivers must support this
167 entry point.
168
169
170 pwm_config_nosleep() -- Passes a pwm_channel_config structure to the
171 associated device driver. If the driver must sleep in order to
172 implement the requested configuration change, -EWOULDBLOCK is
173 returned. Users may call this function from interrupt handlers, for
174 example. This is the other main entry point into the PWM hardware
175 driver, but not all device drivers support this entry point.
176
177
178 pwm_synchronize(), pwm_unsynchronize() -- "Synchronizes" two or more
179 PWM channels, if the underlying hardware permits. (If it doesn't, the
180 framework facilitates emulating this capability but it is not yet
181 implemented). Synchronized channels will start and stop
182 simultaneously when any single channel in the group is started or
183 stopped. Use pwm_unsynchronize(..., NULL) to completely detach a
184 channel from any other synchronized channels. By default, all PWM
185 channels are unsynchronized.
186
187
188 pwm_set_handler() -- Defines an end-of-period callback. The indicated
189 function will be invoked in a worker thread at the end of each PWM
190 period, and can subsequently invoke pwm_config(), etc. Must be used
191 with extreme care for high-speed PWM outputs. Set the handler
192 function to NULL to un-set the handler.
193
194
195
196 Implementing a PWM Device API Driver -- Functions for Driver Authors
197
198
199 Fill out the appropriate fields in a pwm_device structure, and submit
200 to pwm_register():
201
202
203 bus_id -- the plain-text name of the device. Users will bind to a
204 channel on the device using this name plus the channel number. For
205 example, the Atmel PWMC's bus_id is "atmel_pwmc", the same as used by
206 the platform device driver (recommended). The first device registered
207 thereby receives bus_id "atmel_pwmc.0", which is what you put in
208 pwm_device.bus_id. Channels are then named "atmel_pwmc.0:[0-3]".
209 (Hint: just use pdev->dev.bus_id in your probe() method).
210
211
212 nchan -- the number of distinct output channels provided by the device.
213
214
215 request -- (optional) Invoked each time a user requests a channel.
216 Use to turn on clocks, clean up register states, etc. The framework
217 takes care of device locking/unlocking; you will see only successful
218 requests.
219
220
221 free -- (optional) Callback for each time a user relinquishes a
222 channel. The framework will have already stopped, unsynchronized and
223 un-handled the channel. Use to turn off clocks, etc. as necessary.
224
225
226 synchronize, unsynchronize -- (optional) Callbacks to
227 synchronize/unsynchronize channels. Some devices provide this
228 capability in hardware; for others, it can be emulated (see
229 atmel_pwmc.c's sync_mask for an example).
230
231
232 set_callback -- (optional) Invoked when a user requests a handler. If
233 the hardware supports an end-of-period interrupt, invoke the function
234 indicated during your interrupt handler. The callback function itself
235 is always internal to the API, and does not map directly to the user's
236 callback function.
237
238
239 config -- Invoked to change the device configuration, always from a
240 sleep-capable context. All the changes indicated must be performed
241 atomically, ideally synchronized to an end-of-period event (so that
242 you avoid short or long output pulses). You may sleep, etc. as
243 necessary within this function.
244
245
246 config_nosleep -- (optional) Invoked to change device configuration
247 from within a context that is not allowed to sleep. If you cannot
248 perform the requested configuration changes without sleeping, return
249 -EWOULDBLOCK.
250
251
252
253 Acknowledgements
254
255
256 The author expresses his gratitude to the countless developers who
257 have reviewed and submitted feedback on the various versions of the
258 Generic PWM Device API code, and those who have submitted drivers and
259 applications that use the framework. You know who you are. ;)
260
This page took 0.056396 seconds and 5 git commands to generate.